diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2f3046cb9a1..5b04d623b52 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,14 +2,17 @@ # below ones takes precedence over the upper ones # Global owners -* @nazar-pc @rg3l3dr +* @nazar-pc @rg3l3dr -/crates @liuchengxu @nazar-pc @rg3l3dr -/crates/pallet-* @liuchengxu @nazar-pc @rg3l3dr @vedhavyas -/crates/sp-* @liuchengxu @nazar-pc @rg3l3dr @vedhavyas -/crates/subspace-archiving @liuchengxu @i1i1 @nazar-pc @rg3l3dr -/crates/subspace-farmer @i1i1 @nazar-pc @rg3l3dr -/crates/subspace-networking @nazar-pc @rg3l3dr @shamil-gadelshin -/crates/subspace-runtime* @liuchengxu @nazar-pc @rg3l3dr @vedhavyas -/crates/subspace-solving @i1i1 @liuchengxu @nazar-pc @rg3l3dr -/crates/substrate @nazar-pc @rg3l3dr +/crates @nazar-pc @rg3l3dr +/crates/pallet-* @nazar-pc @rg3l3dr @vedhavyas @NingLin-P +/crates/sp-* @nazar-pc @rg3l3dr @vedhavyas @NingLin-P +/crates/subspace-archiving @shamil-gadelshin @nazar-pc @rg3l3dr +/crates/subspace-farmer @nazar-pc @shamil-gadelshin @rg3l3dr +/crates/subspace-networking @shamil-gadelshin @nazar-pc @rg3l3dr +/crates/subspace-runtime* @vedhavyas @nazar-pc @rg3l3dr +/crates/subspace-node @NingLin-P @nazar-pc @rg3l3dr +/crates/subspace-fraud-proof @NingLin-P @nazar-pc @rg3l3dr +/crates/subspace-transaction-pool @NingLin-P @nazar-pc @rg3l3dr +/crates/substrate @nazar-pc @rg3l3dr +/domains @vedhavyas @NingLin-P @nazar-pc @rg3l3dr diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8bb2fddb733..90659546d14 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -29,7 +29,9 @@ env: CARGO_TERM_COLOR: always # Build smaller artifacts to avoid running out of space in CI # TODO: Try to remove once https://github.com/paritytech/substrate/issues/11538 is resolved - RUSTFLAGS: -C strip=symbols -C opt-level=s + # TODO: AES flag is such that we have decent performance on ARMv8, remove once `aes` crate bumps MSRV to at least + # 1.61: https://github.com/RustCrypto/block-ciphers/issues/373 + RUSTFLAGS: -C strip=symbols -C opt-level=s --cfg aes_armv8 # Remove unnecessary WASM build artefacts WASM_BUILD_CLEAN_TARGET: 1 diff --git a/.github/workflows/snapshot-build.yml b/.github/workflows/snapshot-build.yml index 01e3bd5401d..0b242d8ad15 100644 --- a/.github/workflows/snapshot-build.yml +++ b/.github/workflows/snapshot-build.yml @@ -62,6 +62,8 @@ jobs: ghcr.io/${{ github.repository_owner }}/${{ matrix.image }} tags: | type=ref,event=tag + type=ref,event=branch + type=sha,format=long flavor: | latest=false suffix=${{ matrix.platform.image-suffix }} @@ -71,8 +73,7 @@ jobs: with: file: Dockerfile-${{ matrix.image }}${{ matrix.platform.dockerfile-suffix }} platforms: ${{ matrix.platform.arch }} - # Only push for releases - push: ${{ github.event_name == 'push' && github.ref_type == 'tag' }} + push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: | @@ -94,7 +95,9 @@ jobs: - os: ${{ fromJson(github.repository_owner == 'subspace' && '["self-hosted", "ubuntu-20.04-x86-64"]' || 'ubuntu-20.04') }} target: aarch64-unknown-linux-gnu suffix: ubuntu-aarch64-${{ github.ref_name }} - rustflags: "-C linker=aarch64-linux-gnu-gcc" + # TODO: AES flag is such that we have decent performance on ARMv8, remove once `aes` crate bumps MSRV to + # at least 1.61: https://github.com/RustCrypto/block-ciphers/issues/373 + rustflags: "-C linker=aarch64-linux-gnu-gcc --cfg aes_armv8" - os: ${{ fromJson(github.repository_owner == 'subspace' && '["self-hosted", "macos-12-arm64"]' || 'macos-12') }} target: x86_64-apple-darwin suffix: macos-x86_64-${{ github.ref_name }} @@ -102,7 +105,9 @@ jobs: - os: ${{ fromJson(github.repository_owner == 'subspace' && '["self-hosted", "macos-12-arm64"]' || 'macos-12') }} target: aarch64-apple-darwin suffix: macos-aarch64-${{ github.ref_name }} - rustflags: "" + # TODO: AES flag is such that we have decent performance on ARMv8, remove once `aes` crate bumps MSRV to + # at least 1.61: https://github.com/RustCrypto/block-ciphers/issues/373 + rustflags: "--cfg aes_armv8" - os: ${{ fromJson(github.repository_owner == 'subspace' && '["self-hosted", "windows-server-2022-x86-64"]' || 'windows-2022') }} target: x86_64-pc-windows-msvc suffix: windows-x86_64-v2-${{ github.ref_name }} diff --git a/Cargo.lock b/Cargo.lock index fa972560864..0c4b2a2b61f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,9 +262,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if", "cipher 0.4.4", @@ -292,7 +292,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" dependencies = [ "aead 0.5.2", - "aes 0.8.2", + "aes 0.8.3", "cipher 0.4.4", "ctr 0.9.2", "ghash 0.5.0", @@ -375,12 +375,6 @@ dependencies = [ "alloc-no-stdlib", ] -[[package]] -name = "allocator-api2" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9" - [[package]] name = "android-tzdata" version = "0.1.1" @@ -507,9 +501,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "arrayvec" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "asn1-rs" @@ -618,6 +612,15 @@ dependencies = [ "event-listener", ] +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + [[package]] name = "async-oneshot" version = "0.5.0" @@ -635,7 +638,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -652,13 +655,10 @@ dependencies = [ ] [[package]] -name = "atoi" -version = "2.0.0" +name = "atomic" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" -dependencies = [ - "num-traits", -] +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" [[package]] name = "atomic-polyfill" @@ -787,7 +787,7 @@ dependencies = [ [[package]] name = "binary-merkle-tree" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "hash-db 0.16.0", "log", @@ -836,8 +836,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" dependencies = [ "arrayref", - "arrayvec 0.7.3", - "constant_time_eq", + "arrayvec 0.7.4", + "constant_time_eq 0.2.6", ] [[package]] @@ -847,21 +847,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" dependencies = [ "arrayref", - "arrayvec 0.7.3", - "constant_time_eq", + "arrayvec 0.7.4", + "constant_time_eq 0.2.6", ] [[package]] name = "blake3" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b71f35bd3fa1a4c86b85d32c8b9069ea7fe14f7a53cfabb65f62d4265b888" +checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" dependencies = [ "arrayref", - "arrayvec 0.7.3", + "arrayvec 0.7.4", "cc", "cfg-if", - "constant_time_eq", + "constant_time_eq 0.3.0", "digest 0.10.7", ] @@ -994,6 +994,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + [[package]] name = "bstr" version = "1.5.0" @@ -1192,7 +1201,6 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", - "serde", "time 0.1.45", "wasm-bindgen", "winapi", @@ -1308,7 +1316,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -1365,6 +1373,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "convert_case" version = "0.4.0" @@ -1382,57 +1396,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "core-evm-runtime" -version = "0.1.0" -dependencies = [ - "domain-pallet-executive", - "domain-runtime-primitives", - "fp-account", - "fp-evm", - "fp-rpc", - "fp-self-contained", - "frame-benchmarking", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "hex-literal", - "log", - "pallet-balances", - "pallet-base-fee", - "pallet-ethereum", - "pallet-evm", - "pallet-evm-chain-id", - "pallet-evm-precompile-modexp", - "pallet-evm-precompile-sha3fips", - "pallet-evm-precompile-simple", - "pallet-messenger", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-transporter", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-block-builder", - "sp-core", - "sp-domains", - "sp-inherents", - "sp-io", - "sp-messenger", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-std", - "sp-transaction-pool", - "sp-version", - "subspace-runtime-primitives", - "subspace-wasm-tools", - "substrate-wasm-builder", -] - [[package]] name = "core-foundation" version = "0.9.3" @@ -1804,6 +1767,20 @@ dependencies = [ "cipher 0.4.4", ] +[[package]] +name = "cuckoofilter" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18" +dependencies = [ + "byteorder", + "fnv", + "rand 0.7.3", + "serde", + "serde_bytes", + "serde_derive", +] + [[package]] name = "curve25519-dalek" version = "2.1.3" @@ -1868,7 +1845,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -1885,7 +1862,7 @@ checksum = "a26acccf6f445af85ea056362561a24ef56cdc15fcc685f03aec50b9c702cb6d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -2159,7 +2136,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -2197,12 +2174,9 @@ dependencies = [ "sp-keyring", "sp-messenger", "sp-runtime", - "sp-settlement", "sp-state-machine", "subspace-core-primitives", "subspace-runtime-primitives", - "subspace-wasm-tools", - "system-runtime-primitives", "tracing", ] @@ -2223,18 +2197,43 @@ dependencies = [ ] [[package]] -name = "domain-client-executor" +name = "domain-client-message-relayer" +version = "0.1.0" +dependencies = [ + "async-channel", + "cross-domain-message-gossip", + "domain-runtime-primitives", + "futures", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-api", + "sc-consensus", + "sc-network", + "sc-network-gossip", + "sc-utils", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-domains", + "sp-messenger", + "sp-runtime", + "tracing", +] + +[[package]] +name = "domain-client-operator" version = "0.1.0" dependencies = [ "crossbeam", "domain-block-builder", "domain-block-preprocessor", "domain-client-consensus-relay-chain", - "domain-client-executor-gossip", "domain-client-message-relayer", "domain-runtime-primitives", "domain-test-primitives", "domain-test-service", + "evm-domain-test-runtime", "futures", "futures-timer", "num-traits", @@ -2265,19 +2264,17 @@ dependencies = [ "sp-keystore", "sp-messenger", "sp-runtime", - "sp-settlement", "sp-state-machine", "sp-trie", + "sp-weights", "subspace-core-primitives", "subspace-fraud-proof", + "subspace-node", "subspace-runtime-primitives", "subspace-test-runtime", "subspace-test-service", - "subspace-wasm-tools", "substrate-test-runtime-client", "substrate-test-utils", - "system-domain-test-runtime", - "system-runtime-primitives", "tempfile", "thiserror", "tokio", @@ -2285,7 +2282,7 @@ dependencies = [ ] [[package]] -name = "domain-client-executor-gossip" +name = "domain-client-subnet-gossip" version = "0.1.0" dependencies = [ "futures", @@ -2298,33 +2295,7 @@ dependencies = [ "sp-core", "sp-domains", "sp-runtime", - "tracing", -] - -[[package]] -name = "domain-client-message-relayer" -version = "0.1.0" -dependencies = [ - "async-channel", - "cross-domain-message-gossip", - "domain-runtime-primitives", - "futures", - "parity-scale-codec", - "parking_lot 0.12.1", - "sc-client-api", - "sc-consensus", - "sc-network", - "sc-network-gossip", - "sc-utils", - "sp-api", - "sp-blockchain", - "sp-consensus", - "sp-core", - "sp-domains", - "sp-messenger", - "sp-runtime", - "sp-settlement", - "system-runtime-primitives", + "subspace-runtime-primitives", "tracing", ] @@ -2341,7 +2312,7 @@ dependencies = [ "fc-rpc", "fc-rpc-core", "fc-storage", - "fp-rpc", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "futures", "jsonrpsee", "pallet-transaction-payment-rpc", @@ -2392,6 +2363,8 @@ dependencies = [ "sp-core", "sp-runtime", "sp-std", + "sp-weights", + "subspace-core-primitives", "subspace-runtime-primitives", ] @@ -2404,9 +2377,9 @@ dependencies = [ "cross-domain-message-gossip", "domain-block-preprocessor", "domain-client-consensus-relay-chain", - "domain-client-executor", - "domain-client-executor-gossip", "domain-client-message-relayer", + "domain-client-operator", + "domain-client-subnet-gossip", "domain-runtime-primitives", "frame-benchmarking", "frame-benchmarking-cli", @@ -2445,7 +2418,6 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-settlement", "sp-transaction-pool", "subspace-core-primitives", "subspace-fraud-proof", @@ -2454,7 +2426,6 @@ dependencies = [ "substrate-build-script-utils", "substrate-frame-rpc-system", "substrate-prometheus-endpoint", - "system-runtime-primitives", "tracing", ] @@ -2475,14 +2446,20 @@ version = "0.1.0" dependencies = [ "async-trait", "domain-client-consensus-relay-chain", - "domain-client-executor", + "domain-client-operator", + "domain-eth-service", "domain-runtime-primitives", "domain-service", "domain-test-primitives", + "evm-domain-test-runtime", + "fp-account 1.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", "frame-support", "frame-system", "frame-system-rpc-runtime-api", "futures", + "once_cell", "pallet-transaction-payment", "pallet-transaction-payment-rpc", "rand 0.8.5", @@ -2497,6 +2474,8 @@ dependencies = [ "sc-tracing", "sc-transaction-pool", "sc-utils", + "serde", + "serde_json", "sp-api", "sp-application-crypto", "sp-arithmetic", @@ -2521,17 +2500,10 @@ dependencies = [ "subspace-test-service", "substrate-frame-rpc-system", "substrate-test-client", - "system-domain-test-runtime", "tokio", "tracing", ] -[[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - [[package]] name = "downcast" version = "0.11.0" @@ -2636,12 +2608,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" -dependencies = [ - "serde", -] +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" @@ -2844,6 +2813,111 @@ dependencies = [ "serde", ] +[[package]] +name = "evm-domain-runtime" +version = "0.1.0" +dependencies = [ + "domain-pallet-executive", + "domain-runtime-primitives", + "fp-account 1.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-self-contained 1.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "frame-benchmarking", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "hex-literal", + "log", + "pallet-balances", + "pallet-base-fee 1.0.0 (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "pallet-domain-id", + "pallet-ethereum 4.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "pallet-evm 6.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "pallet-evm-chain-id 1.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "pallet-evm-precompile-modexp 2.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "pallet-evm-precompile-sha3fips 2.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "pallet-evm-precompile-simple 2.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "pallet-messenger", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-transporter", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-block-builder", + "sp-core", + "sp-domains", + "sp-inherents", + "sp-io", + "sp-messenger", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std", + "sp-transaction-pool", + "sp-version", + "subspace-core-primitives", + "subspace-runtime-primitives", + "substrate-wasm-builder", +] + +[[package]] +name = "evm-domain-test-runtime" +version = "0.1.0" +dependencies = [ + "domain-pallet-executive", + "domain-runtime-primitives", + "domain-test-primitives", + "fp-account 1.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-self-contained 1.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "frame-benchmarking", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "hex-literal", + "log", + "pallet-balances", + "pallet-base-fee 1.0.0 (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "pallet-domain-id", + "pallet-ethereum 4.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "pallet-evm 6.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "pallet-evm-chain-id 1.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "pallet-evm-precompile-modexp 2.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "pallet-evm-precompile-sha3fips 2.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "pallet-evm-precompile-simple 2.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "pallet-messenger", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-transporter", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-block-builder", + "sp-core", + "sp-domains", + "sp-inherents", + "sp-io", + "sp-messenger", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std", + "sp-transaction-pool", + "sp-version", + "subspace-core-primitives", + "subspace-runtime-primitives", + "substrate-wasm-builder", +] + [[package]] name = "evm-gasometer" version = "0.39.0" @@ -2888,7 +2962,7 @@ dependencies = [ "fs-err", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -2915,11 +2989,11 @@ dependencies = [ [[package]] name = "fc-consensus" version = "2.0.0-dev" -source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" dependencies = [ "async-trait", - "fp-consensus", - "fp-rpc", + "fp-consensus 2.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "sc-consensus", "sp-api", "sp-block-builder", @@ -2931,41 +3005,30 @@ dependencies = [ [[package]] name = "fc-db" version = "2.0.0-dev" -source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" dependencies = [ "async-trait", - "ethereum", - "fc-storage", - "fp-consensus", - "fp-rpc", - "fp-storage", - "futures", + "fp-storage 2.0.0 (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "log", "parity-db", "parity-scale-codec", "parking_lot 0.12.1", - "sc-client-api", "sc-client-db", - "smallvec", - "sp-api", "sp-blockchain", "sp-core", "sp-database", "sp-runtime", - "sp-storage", - "sqlx", - "tokio", ] [[package]] name = "fc-mapping-sync" version = "2.0.0-dev" -source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" dependencies = [ "fc-db", "fc-storage", - "fp-consensus", - "fp-rpc", + "fp-consensus 2.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "futures", "futures-timer", "log", @@ -2975,15 +3038,13 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", "sp-runtime", - "tokio", ] [[package]] name = "fc-rpc" version = "2.0.0-dev" -source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" dependencies = [ "ethereum", "ethereum-types", @@ -2992,17 +3053,17 @@ dependencies = [ "fc-mapping-sync", "fc-rpc-core", "fc-storage", - "fp-ethereum", - "fp-evm", - "fp-rpc", - "fp-storage", + "fp-ethereum 1.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-storage 2.0.0 (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "futures", "hex", "jsonrpsee", "libsecp256k1", "log", "lru 0.8.1", - "pallet-evm", + "pallet-evm 6.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "parity-scale-codec", "prometheus", "rand 0.8.5", @@ -3032,7 +3093,7 @@ dependencies = [ [[package]] name = "fc-rpc-core" version = "1.1.0-dev" -source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" dependencies = [ "ethereum", "ethereum-types", @@ -3045,12 +3106,12 @@ dependencies = [ [[package]] name = "fc-storage" version = "1.0.0-dev" -source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" dependencies = [ "ethereum", "ethereum-types", - "fp-rpc", - "fp-storage", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-storage 2.0.0 (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "parity-scale-codec", "sc-client-api", "sp-api", @@ -3171,43 +3232,16 @@ dependencies = [ "num-traits", ] -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "pin-project", - "spin 0.9.8", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", ] @@ -3221,6 +3255,24 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fp-account" +version = "1.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "hex", + "impl-serde", + "libsecp256k1", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "fp-account" version = "1.0.0-dev" @@ -3239,6 +3291,18 @@ dependencies = [ "sp-std", ] +[[package]] +name = "fp-consensus" +version = "2.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "ethereum", + "parity-scale-codec", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "fp-consensus" version = "2.0.0-dev" @@ -3251,6 +3315,20 @@ dependencies = [ "sp-std", ] +[[package]] +name = "fp-ethereum" +version = "1.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "ethereum", + "ethereum-types", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "frame-support", + "num_enum", + "parity-scale-codec", + "sp-std", +] + [[package]] name = "fp-ethereum" version = "1.0.0-dev" @@ -3258,13 +3336,28 @@ source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f35 dependencies = [ "ethereum", "ethereum-types", - "fp-evm", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", "frame-support", "num_enum", "parity-scale-codec", "sp-std", ] +[[package]] +name = "fp-evm" +version = "3.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "evm", + "frame-support", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "fp-evm" version = "3.0.0-dev" @@ -3280,6 +3373,23 @@ dependencies = [ "sp-std", ] +[[package]] +name = "fp-rpc" +version = "3.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "ethereum", + "ethereum-types", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-std", +] + [[package]] name = "fp-rpc" version = "3.0.0-dev" @@ -3287,7 +3397,7 @@ source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f35 dependencies = [ "ethereum", "ethereum-types", - "fp-evm", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", "parity-scale-codec", "scale-info", "sp-api", @@ -3297,6 +3407,18 @@ dependencies = [ "sp-std", ] +[[package]] +name = "fp-self-contained" +version = "1.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "frame-support", + "parity-scale-codec", + "scale-info", + "serde", + "sp-runtime", +] + [[package]] name = "fp-self-contained" version = "1.0.0-dev" @@ -3309,6 +3431,15 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "fp-storage" +version = "2.0.0" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "parity-scale-codec", + "serde", +] + [[package]] name = "fp-storage" version = "2.0.0" @@ -3327,7 +3458,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-support", "frame-support-procedural", @@ -3352,7 +3483,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "Inflector", "array-bytes 4.2.0", @@ -3399,7 +3530,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-support", "frame-system", @@ -3428,7 +3559,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "bitflags", "environmental", @@ -3463,7 +3594,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "Inflector", "cfg-expr", @@ -3474,35 +3605,35 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "cfg-if", "frame-support", @@ -3521,7 +3652,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-benchmarking", "frame-support", @@ -3536,7 +3667,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "sp-api", @@ -3545,7 +3676,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-support", "parity-scale-codec", @@ -3629,17 +3760,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "futures-intrusive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot 0.12.1", -] - [[package]] name = "futures-io" version = "0.3.28" @@ -3669,7 +3789,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -3692,6 +3812,16 @@ dependencies = [ "webpki 0.22.0", ] +[[package]] +name = "futures-rustls" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" +dependencies = [ + "futures-io", + "rustls 0.21.2", +] + [[package]] name = "futures-sink" version = "0.3.28" @@ -3704,6 +3834,17 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +[[package]] +name = "futures-ticker" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9763058047f713632a52e916cc7f6a4b3fc6e9fc1ff8c5b1dc49e5a89041682e" +dependencies = [ + "futures", + "futures-timer", + "instant", +] + [[package]] name = "futures-timer" version = "3.0.2" @@ -3988,33 +4129,11 @@ dependencies = [ "ahash 0.8.3", ] -[[package]] -name = "hashbrown" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" -dependencies = [ - "ahash 0.8.3", - "allocator-api2", -] - -[[package]] -name = "hashlink" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" -dependencies = [ - "hashbrown 0.14.0", -] - [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] [[package]] name = "hermit-abi" @@ -4204,7 +4323,7 @@ dependencies = [ "rustls-native-certs", "tokio", "tokio-rustls 0.23.4", - "webpki-roots", + "webpki-roots 0.22.6", ] [[package]] @@ -4536,7 +4655,7 @@ dependencies = [ "tokio-rustls 0.23.4", "tokio-util", "tracing", - "webpki-roots", + "webpki-roots 0.22.6", ] [[package]] @@ -4546,7 +4665,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e70b4439a751a5de7dd5ed55eacff78ebf4ffe0fc009cb1ebb11417f5b536b" dependencies = [ "anyhow", - "arrayvec 0.7.3", + "arrayvec 0.7.4", "async-lock", "async-trait", "beef", @@ -4744,27 +4863,58 @@ dependencies = [ "futures-timer", "getrandom 0.2.10", "instant", - "libp2p-allow-block-list", - "libp2p-connection-limits", - "libp2p-core", - "libp2p-dns", - "libp2p-gossipsub", - "libp2p-identify", - "libp2p-identity", - "libp2p-kad", - "libp2p-mdns", - "libp2p-metrics", - "libp2p-noise", - "libp2p-ping", - "libp2p-quic", - "libp2p-request-response", - "libp2p-swarm", - "libp2p-tcp", + "libp2p-allow-block-list 0.1.1", + "libp2p-connection-limits 0.1.0", + "libp2p-core 0.39.2", + "libp2p-dns 0.39.0", + "libp2p-identify 0.42.2", + "libp2p-identity 0.1.2", + "libp2p-kad 0.43.3", + "libp2p-mdns 0.43.1", + "libp2p-metrics 0.12.0", + "libp2p-noise 0.42.2", + "libp2p-ping 0.42.0", + "libp2p-quic 0.7.0-alpha.3", + "libp2p-request-response 0.24.1", + "libp2p-swarm 0.42.2", + "libp2p-tcp 0.39.0", "libp2p-wasm-ext", "libp2p-webrtc", - "libp2p-websocket", - "libp2p-yamux", - "multiaddr", + "libp2p-websocket 0.41.0", + "libp2p-yamux 0.43.1", + "multiaddr 0.17.1", + "pin-project", +] + +[[package]] +name = "libp2p" +version = "0.52.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38039ba2df4f3255842050845daef4a004cc1f26da03dbc645535088b51910ef" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "getrandom 0.2.10", + "instant", + "libp2p-allow-block-list 0.2.0", + "libp2p-connection-limits 0.2.1", + "libp2p-core 0.40.0", + "libp2p-dns 0.40.0", + "libp2p-gossipsub", + "libp2p-identify 0.43.0", + "libp2p-identity 0.2.2", + "libp2p-kad 0.44.3", + "libp2p-mdns 0.44.0", + "libp2p-metrics 0.13.0", + "libp2p-noise 0.43.0", + "libp2p-ping 0.43.0", + "libp2p-request-response 0.25.0", + "libp2p-swarm 0.43.2", + "libp2p-tcp 0.40.0", + "libp2p-websocket 0.42.0", + "libp2p-yamux 0.44.0", + "multiaddr 0.18.0", "pin-project", ] @@ -4774,9 +4924,21 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "510daa05efbc25184458db837f6f9a5143888f1caa742426d92e1833ddd38a50" dependencies = [ - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "libp2p-swarm 0.42.2", + "void", +] + +[[package]] +name = "libp2p-allow-block-list" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55b46558c5c0bf99d3e2a1a38fd54ff5476ca66dd1737b12466a1824dd219311" +dependencies = [ + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-swarm 0.43.2", "void", ] @@ -4786,9 +4948,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4caa33f1d26ed664c4fe2cca81a08c8e07d4c1c04f2f4ac7655c2dd85467fda0" dependencies = [ - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "libp2p-swarm 0.42.2", + "void", +] + +[[package]] +name = "libp2p-connection-limits" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f5107ad45cb20b2f6c3628c7b6014b996fcb13a88053f4569c872c6e30abf58" +dependencies = [ + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-swarm 0.43.2", "void", ] @@ -4803,17 +4977,45 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-identity", + "libp2p-identity 0.1.2", "log", - "multiaddr", + "multiaddr 0.17.1", "multihash 0.17.0", - "multistream-select", + "multistream-select 0.12.1", + "once_cell", + "parking_lot 0.12.1", + "pin-project", + "quick-protobuf", + "rand 0.8.5", + "rw-stream-sink 0.3.0", + "smallvec", + "thiserror", + "unsigned-varint", + "void", +] + +[[package]] +name = "libp2p-core" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef7dd7b09e71aac9271c60031d0e558966cdb3253ba0308ab369bb2de80630d0" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-identity 0.2.2", + "log", + "multiaddr 0.18.0", + "multihash 0.19.0", + "multistream-select 0.13.0", "once_cell", "parking_lot 0.12.1", "pin-project", "quick-protobuf", "rand 0.8.5", - "rw-stream-sink", + "rw-stream-sink 0.4.0", "serde", "smallvec", "thiserror", @@ -4828,7 +5030,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146ff7034daae62077c415c2376b8057368042df6ab95f5432ad5e88568b1554" dependencies = [ "futures", - "libp2p-core", + "libp2p-core 0.39.2", + "log", + "parking_lot 0.12.1", + "smallvec", + "trust-dns-resolver", +] + +[[package]] +name = "libp2p-dns" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd4394c81c0c06d7b4a60f3face7e8e8a9b246840f98d2c80508d0721b032147" +dependencies = [ + "futures", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", "log", "parking_lot 0.12.1", "smallvec", @@ -4837,9 +5054,9 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.44.4" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b34b6da8165c0bde35c82db8efda39b824776537e73973549e76cadb3a77c5" +checksum = "8e378da62e8c9251f6e885ed173a561663f29b251e745586cf6ae6150b295c37" dependencies = [ "asynchronous-codec", "base64 0.21.2", @@ -4848,24 +5065,24 @@ dependencies = [ "either", "fnv", "futures", + "futures-ticker", + "getrandom 0.2.10", "hex_fmt", "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-swarm 0.43.2", "log", - "prometheus-client", + "prometheus-client 0.21.2", "quick-protobuf", - "quick-protobuf-codec", + "quick-protobuf-codec 0.2.0", "rand 0.8.5", "regex", "serde", "sha2 0.10.7", "smallvec", - "thiserror", "unsigned-varint", "void", - "wasm-timer", ] [[package]] @@ -4878,13 +5095,35 @@ dependencies = [ "either", "futures", "futures-timer", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "libp2p-swarm 0.42.2", + "log", + "lru 0.10.0", + "quick-protobuf", + "quick-protobuf-codec 0.1.0", + "smallvec", + "thiserror", + "void", +] + +[[package]] +name = "libp2p-identify" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a29675a32dbcc87790db6cf599709e64308f1ae9d5ecea2d259155889982db8" +dependencies = [ + "asynchronous-codec", + "either", + "futures", + "futures-timer", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-swarm 0.43.2", "log", "lru 0.10.0", "quick-protobuf", - "quick-protobuf-codec", + "quick-protobuf-codec 0.2.0", "smallvec", "thiserror", "void", @@ -4896,13 +5135,30 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e2d584751cecb2aabaa56106be6be91338a60a0f4e420cf2af639204f596fc1" dependencies = [ - "bs58", + "bs58 0.4.0", "ed25519-dalek", "log", - "multiaddr", + "multiaddr 0.17.1", "multihash 0.17.0", "quick-protobuf", "rand 0.8.5", + "sha2 0.10.7", + "thiserror", + "zeroize", +] + +[[package]] +name = "libp2p-identity" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38d6012784fe4cc14e6d443eb415b11fc7c456dc15d9f0d90d9b70bc7ac3ec1" +dependencies = [ + "bs58 0.5.0", + "ed25519-dalek", + "log", + "multihash 0.19.0", + "quick-protobuf", + "rand 0.8.5", "serde", "sha2 0.10.7", "thiserror", @@ -4915,7 +5171,7 @@ version = "0.43.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39d5ef876a2b2323d63c258e63c2f8e36f205fe5a11f0b3095d59635650790ff" dependencies = [ - "arrayvec 0.7.3", + "arrayvec 0.7.4", "asynchronous-codec", "bytes", "either", @@ -4923,9 +5179,37 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "libp2p-swarm 0.42.2", + "log", + "quick-protobuf", + "rand 0.8.5", + "sha2 0.10.7", + "smallvec", + "thiserror", + "uint", + "unsigned-varint", + "void", +] + +[[package]] +name = "libp2p-kad" +version = "0.44.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2584b0c27f879a1cca4b753fd96874109e5a2f46bd6e30924096456c2ba9b2" +dependencies = [ + "arrayvec 0.7.4", + "asynchronous-codec", + "bytes", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-swarm 0.43.2", "log", "quick-protobuf", "rand 0.8.5", @@ -4947,9 +5231,9 @@ dependencies = [ "data-encoding", "futures", "if-watch", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "libp2p-swarm 0.42.2", "log", "rand 0.8.5", "smallvec", @@ -4959,19 +5243,57 @@ dependencies = [ "void", ] +[[package]] +name = "libp2p-mdns" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a2567c305232f5ef54185e9604579a894fd0674819402bb0ac0246da82f52a" +dependencies = [ + "data-encoding", + "futures", + "if-watch", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-swarm 0.43.2", + "log", + "rand 0.8.5", + "smallvec", + "socket2 0.5.3", + "tokio", + "trust-dns-proto", + "void", +] + [[package]] name = "libp2p-metrics" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a42ec91e227d7d0dafa4ce88b333cdf5f277253873ab087555c92798db2ddd46" dependencies = [ - "libp2p-core", + "libp2p-core 0.39.2", + "libp2p-identify 0.42.2", + "libp2p-kad 0.43.3", + "libp2p-ping 0.42.0", + "libp2p-swarm 0.42.2", + "prometheus-client 0.19.0", +] + +[[package]] +name = "libp2p-metrics" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3787ea81798dcc5bf1d8b40a8e8245cf894b168d04dd70aa48cb3ff2fff141d2" +dependencies = [ + "instant", + "libp2p-core 0.40.0", "libp2p-gossipsub", - "libp2p-identify", - "libp2p-kad", - "libp2p-ping", - "libp2p-swarm", - "prometheus-client", + "libp2p-identify 0.43.0", + "libp2p-identity 0.2.2", + "libp2p-kad 0.44.3", + "libp2p-ping 0.43.0", + "libp2p-swarm 0.43.2", + "once_cell", + "prometheus-client 0.21.2", ] [[package]] @@ -4983,9 +5305,34 @@ dependencies = [ "bytes", "curve25519-dalek 3.2.0", "futures", - "libp2p-core", - "libp2p-identity", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "log", + "once_cell", + "quick-protobuf", + "rand 0.8.5", + "sha2 0.10.7", + "snow", + "static_assertions", + "thiserror", + "x25519-dalek 1.1.1", + "zeroize", +] + +[[package]] +name = "libp2p-noise" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87945db2b3f977af09b62b9aa0a5f3e4870995a577ecd845cdeba94cdf6bbca7" +dependencies = [ + "bytes", + "curve25519-dalek 3.2.0", + "futures", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", "log", + "multiaddr 0.18.0", + "multihash 0.19.0", "once_cell", "quick-protobuf", "rand 0.8.5", @@ -5007,8 +5354,26 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core", - "libp2p-swarm", + "libp2p-core 0.39.2", + "libp2p-swarm 0.42.2", + "log", + "rand 0.8.5", + "void", +] + +[[package]] +name = "libp2p-ping" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd5ee3270229443a2b34b27ed0cb7470ef6b4a6e45e54e89a8771fa683bab48" +dependencies = [ + "either", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-swarm 0.43.2", "log", "rand 0.8.5", "void", @@ -5024,18 +5389,40 @@ dependencies = [ "futures", "futures-timer", "if-watch", - "libp2p-core", - "libp2p-identity", - "libp2p-tls", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "libp2p-tls 0.1.0", "log", "parking_lot 0.12.1", - "quinn-proto", + "quinn-proto 0.9.3", "rand 0.8.5", "rustls 0.20.8", "thiserror", "tokio", ] +[[package]] +name = "libp2p-quic" +version = "0.8.0-alpha" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7f1b4fb39b4136b29458735d8c82907d4851e611dbacbe919dd4ab2f02a69a8" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "if-watch", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-tls 0.2.0", + "log", + "parking_lot 0.12.1", + "quinn-proto 0.10.1", + "rand 0.8.5", + "rustls 0.21.2", + "thiserror", + "tokio", +] + [[package]] name = "libp2p-request-response" version = "0.24.1" @@ -5045,11 +5432,29 @@ dependencies = [ "async-trait", "futures", "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "libp2p-swarm 0.42.2", + "rand 0.8.5", + "smallvec", +] + +[[package]] +name = "libp2p-request-response" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20bd837798cdcce4283d2675f08bcd3756a650d56eab4d4367e1b3f27eed6887" +dependencies = [ + "async-trait", + "futures", + "instant", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-swarm 0.43.2", + "log", "rand 0.8.5", "smallvec", + "void", ] [[package]] @@ -5063,10 +5468,33 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm-derive", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "libp2p-swarm-derive 0.32.0", + "log", + "rand 0.8.5", + "smallvec", + "tokio", + "void", +] + +[[package]] +name = "libp2p-swarm" +version = "0.43.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43106820057e0f65c77b01a3873593f66e676da4e40c70c3a809b239109f1d30" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "libp2p-swarm-derive 0.33.0", "log", + "multistream-select 0.13.0", + "once_cell", "rand 0.8.5", "smallvec", "tokio", @@ -5084,6 +5512,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "libp2p-swarm-derive" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4d5ec2a3df00c7836d7696c136274c9c59705bac69133253696a6c932cd1d74" +dependencies = [ + "heck", + "proc-macro-warning", + "proc-macro2", + "quote", + "syn 2.0.27", +] + [[package]] name = "libp2p-tcp" version = "0.39.0" @@ -5094,12 +5535,29 @@ dependencies = [ "futures-timer", "if-watch", "libc", - "libp2p-core", + "libp2p-core 0.39.2", "log", "socket2 0.4.9", "tokio", ] +[[package]] +name = "libp2p-tcp" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09bfdfb6f945c5c014b87872a0bdb6e0aef90e92f380ef57cd9013f118f9289d" +dependencies = [ + "futures", + "futures-timer", + "if-watch", + "libc", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "log", + "socket2 0.5.3", + "tokio", +] + [[package]] name = "libp2p-tls" version = "0.1.0" @@ -5107,9 +5565,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff08d13d0dc66e5e9ba6279c1de417b84fa0d0adc3b03e5732928c180ec02781" dependencies = [ "futures", - "futures-rustls", - "libp2p-core", - "libp2p-identity", + "futures-rustls 0.22.2", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", "rcgen 0.10.0", "ring", "rustls 0.20.8", @@ -5119,6 +5577,25 @@ dependencies = [ "yasna", ] +[[package]] +name = "libp2p-tls" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec63209ec17ffb354a5fdfde7c36f14d168367c5f115fdb5a177a342414d5a55" +dependencies = [ + "futures", + "futures-rustls 0.24.0", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", + "rcgen 0.10.0", + "ring", + "rustls 0.21.2", + "thiserror", + "webpki 0.22.0", + "x509-parser 0.15.0", + "yasna", +] + [[package]] name = "libp2p-wasm-ext" version = "0.39.0" @@ -5127,7 +5604,7 @@ checksum = "77dff9d32353a5887adb86c8afc1de1a94d9e8c3bc6df8b2201d7cdf5c848f43" dependencies = [ "futures", "js-sys", - "libp2p-core", + "libp2p-core 0.39.2", "parity-send-wrapper", "wasm-bindgen", "wasm-bindgen-futures", @@ -5146,13 +5623,13 @@ dependencies = [ "futures-timer", "hex", "if-watch", - "libp2p-core", - "libp2p-identity", - "libp2p-noise", + "libp2p-core 0.39.2", + "libp2p-identity 0.1.2", + "libp2p-noise 0.42.2", "log", "multihash 0.17.0", "quick-protobuf", - "quick-protobuf-codec", + "quick-protobuf-codec 0.1.0", "rand 0.8.5", "rcgen 0.9.3", "serde", @@ -5172,15 +5649,35 @@ checksum = "111273f7b3d3510524c752e8b7a5314b7f7a1fee7e68161c01a7d72cbb06db9f" dependencies = [ "either", "futures", - "futures-rustls", - "libp2p-core", + "futures-rustls 0.22.2", + "libp2p-core 0.39.2", + "log", + "parking_lot 0.12.1", + "quicksink", + "rw-stream-sink 0.3.0", + "soketto", + "url", + "webpki-roots 0.22.6", +] + +[[package]] +name = "libp2p-websocket" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956d981ebc84abc3377e5875483c06d94ff57bc6b25f725047f9fd52592f72d4" +dependencies = [ + "either", + "futures", + "futures-rustls 0.22.2", + "libp2p-core 0.40.0", + "libp2p-identity 0.2.2", "log", "parking_lot 0.12.1", "quicksink", - "rw-stream-sink", + "rw-stream-sink 0.4.0", "soketto", "url", - "webpki-roots", + "webpki-roots 0.23.1", ] [[package]] @@ -5190,7 +5687,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd21d950662700a385d4c6d68e2f5f54d778e97068cdd718522222ef513bda" dependencies = [ "futures", - "libp2p-core", + "libp2p-core 0.39.2", + "log", + "thiserror", + "yamux", +] + +[[package]] +name = "libp2p-yamux" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0a9b42ab6de15c6f076d8fb11dc5f48d899a10b55a2e16b12be9012a05287b0" +dependencies = [ + "futures", + "libp2p-core 0.40.0", "log", "thiserror", "yamux", @@ -5244,17 +5754,6 @@ dependencies = [ "libsecp256k1-core", ] -[[package]] -name = "libsqlite3-sys" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - [[package]] name = "libz-sys" version = "1.1.9" @@ -5410,7 +5909,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -5423,7 +5922,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -5434,7 +5933,7 @@ checksum = "de6267819c9042df1a9e62ca279e5a34254ad5dfdcb13ff988f560d75576e8b4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -5445,7 +5944,7 @@ checksum = "dc7176ac15ab2ed7f335e2398f729b9562dae0c233705bc1e1e3acd8452d403d" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -5523,9 +6022,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180d4b35be83d33392d1d1bfbd2ae1eca7ff5de1a94d3fc87faaa99a069e7cbd" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" dependencies = [ "libc", ] @@ -5666,6 +6165,25 @@ dependencies = [ "url", ] +[[package]] +name = "multiaddr" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92a651988b3ed3ad1bc8c87d016bb92f6f395b84ed1db9b926b32b1fc5a2c8b5" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "libp2p-identity 0.2.2", + "multibase", + "multihash 0.19.0", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + [[package]] name = "multibase" version = "0.9.1" @@ -5703,12 +6221,21 @@ dependencies = [ "core2", "digest 0.10.7", "multihash-derive", - "serde", - "serde-big-array", "sha2 0.10.7", "unsigned-varint", ] +[[package]] +name = "multihash" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd59dcc2bbe70baabeac52cd22ae52c55eefe6c38ff11a9439f16a350a939f2" +dependencies = [ + "core2", + "serde", + "unsigned-varint", +] + [[package]] name = "multihash-derive" version = "0.8.1" @@ -5743,6 +6270,20 @@ dependencies = [ "unsigned-varint", ] +[[package]] +name = "multistream-select" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19" +dependencies = [ + "bytes", + "futures", + "log", + "pin-project", + "smallvec", + "unsigned-varint", +] + [[package]] name = "nalgebra" version = "0.32.2" @@ -5771,30 +6312,12 @@ dependencies = [ ] [[package]] -name = "names" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d66043b25d4a6cccb23619d10c19c25304b355a7dccd4a8e11423dd2382146" -dependencies = [ - "rand 0.8.5", -] - -[[package]] -name = "native-tls" -version = "0.2.11" +name = "names" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "e7d66043b25d4a6cccb23619d10c19c25304b355a7dccd4a8e11423dd2382146" dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "rand 0.8.5", ] [[package]] @@ -5947,7 +6470,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" dependencies = [ - "arrayvec 0.7.3", + "arrayvec 0.7.4", "itoa", ] @@ -6021,7 +6544,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -6082,50 +6605,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "openssl" -version = "0.10.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-sys" -version = "0.9.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "option-ext" version = "0.2.0" @@ -6189,7 +6674,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-support", "frame-system", @@ -6203,7 +6688,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-benchmarking", "frame-support", @@ -6227,7 +6712,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-benchmarking", "frame-support", @@ -6239,12 +6724,26 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-base-fee" +version = "1.0.0" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", +] + [[package]] name = "pallet-base-fee" version = "1.0.0" source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" dependencies = [ - "fp-evm", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", "frame-support", "frame-system", "parity-scale-codec", @@ -6256,7 +6755,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-support", "frame-system", @@ -6275,7 +6774,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "binary-merkle-tree", @@ -6297,7 +6796,18 @@ dependencies = [ ] [[package]] -name = "pallet-domain-registry" +name = "pallet-domain-id" +version = "0.1.0" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-domains", +] + +[[package]] +name = "pallet-domains" version = "0.1.0" dependencies = [ "frame-benchmarking", @@ -6305,38 +6815,41 @@ dependencies = [ "frame-system", "log", "pallet-balances", - "pallet-executor-registry", - "pallet-settlement", "parity-scale-codec", "scale-info", - "serde", "sp-core", - "sp-domain-digests", "sp-domains", - "sp-executor-registry", + "sp-externalities", "sp-io", "sp-runtime", "sp-std", "sp-trie", + "sp-version", + "subspace-core-primitives", + "subspace-runtime-primitives", ] [[package]] -name = "pallet-domains" -version = "0.1.0" +name = "pallet-ethereum" +version = "4.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" dependencies = [ - "frame-benchmarking", + "ethereum", + "ethereum-types", + "evm", + "fp-consensus 2.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-ethereum 1.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-storage 2.0.0 (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "frame-support", "frame-system", - "log", - "pallet-settlement", + "pallet-evm 6.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "parity-scale-codec", "scale-info", - "sp-core", - "sp-domains", "sp-io", "sp-runtime", "sp-std", - "sp-trie", ] [[package]] @@ -6347,16 +6860,41 @@ dependencies = [ "ethereum", "ethereum-types", "evm", - "fp-consensus", - "fp-ethereum", - "fp-evm", - "fp-rpc", - "fp-storage", + "fp-consensus 2.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-ethereum 1.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-rpc 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-storage 2.0.0 (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "frame-support", + "frame-system", + "pallet-evm 6.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-evm" +version = "6.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "environmental", + "evm", + "fp-account 1.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "frame-benchmarking", "frame-support", "frame-system", - "pallet-evm", + "hex", + "hex-literal", + "impl-trait-for-tuples", + "log", "parity-scale-codec", + "rlp", "scale-info", + "sp-core", "sp-io", "sp-runtime", "sp-std", @@ -6369,8 +6907,8 @@ source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f35 dependencies = [ "environmental", "evm", - "fp-account", - "fp-evm", + "fp-account 1.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", "frame-benchmarking", "frame-support", "frame-system", @@ -6387,6 +6925,17 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-evm-chain-id" +version = "1.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", +] + [[package]] name = "pallet-evm-chain-id" version = "1.0.0-dev" @@ -6398,52 +6947,60 @@ dependencies = [ "scale-info", ] +[[package]] +name = "pallet-evm-precompile-modexp" +version = "2.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "num", +] + [[package]] name = "pallet-evm-precompile-modexp" version = "2.0.0-dev" source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" dependencies = [ - "fp-evm", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", "num", ] +[[package]] +name = "pallet-evm-precompile-sha3fips" +version = "2.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" +dependencies = [ + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", + "tiny-keccak", +] + [[package]] name = "pallet-evm-precompile-sha3fips" version = "2.0.0-dev" source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" dependencies = [ - "fp-evm", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", "tiny-keccak", ] [[package]] name = "pallet-evm-precompile-simple" version = "2.0.0-dev" -source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" +source = "git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3#74483666645e121c0c5e6616f43fdfd8664ea0d3" dependencies = [ - "fp-evm", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "ripemd", "sp-io", ] [[package]] -name = "pallet-executor-registry" -version = "0.1.0" +name = "pallet-evm-precompile-simple" +version = "2.0.0-dev" +source = "git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4#c13d670b25b5506c1c5243f352941dc46c82ffe4" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "pallet-balances", - "parity-scale-codec", - "scale-info", - "sp-arithmetic", - "sp-core", - "sp-domains", - "sp-executor-registry", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", + "ripemd", "sp-io", - "sp-runtime", - "sp-std", - "subspace-core-primitives", ] [[package]] @@ -6510,7 +7067,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-benchmarking", "frame-support", @@ -6574,7 +7131,7 @@ dependencies = [ [[package]] name = "pallet-root-testing" version = "1.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-support", "frame-system", @@ -6600,7 +7157,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-support", "frame-system", @@ -6618,21 +7175,6 @@ dependencies = [ "sp-trie", ] -[[package]] -name = "pallet-settlement" -version = "0.1.0" -dependencies = [ - "frame-support", - "frame-system", - "log", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-domains", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-subspace" version = "0.1.0" @@ -6670,7 +7212,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-benchmarking", "frame-support", @@ -6685,7 +7227,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-benchmarking", "frame-support", @@ -6714,7 +7256,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-support", "frame-system", @@ -6730,7 +7272,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -6746,7 +7288,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -6777,7 +7319,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-benchmarking", "frame-support", @@ -6812,11 +7354,11 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.5.0" +version = "3.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28" +checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" dependencies = [ - "arrayvec 0.7.3", + "arrayvec 0.7.4", "bitvec", "byte-slice-cast", "bytes", @@ -6827,9 +7369,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.4" +version = "3.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" +checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6987,7 +7529,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -7028,7 +7570,7 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -7262,14 +7804,14 @@ checksum = "70550716265d1ec349c41f70dd4f964b4fd88394efe4405f0c1da679c4799a07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -7300,6 +7842,18 @@ dependencies = [ "prometheus-client-derive-encode", ] +[[package]] +name = "prometheus-client" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c99afa9a01501019ac3a14d71d9f94050346f55ca471ce90c799a15c58f61e2" +dependencies = [ + "dtoa", + "itoa", + "parking_lot 0.12.1", + "prometheus-client-derive-encode", +] + [[package]] name = "prometheus-client-derive-encode" version = "0.4.1" @@ -7402,6 +7956,19 @@ dependencies = [ "unsigned-varint", ] +[[package]] +name = "quick-protobuf-codec" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ededb1cd78531627244d51dd0c7139fbe736c7d57af0092a76f0ffb2f56e98" +dependencies = [ + "asynchronous-codec", + "bytes", + "quick-protobuf", + "thiserror", + "unsigned-varint", +] + [[package]] name = "quicksink" version = "0.1.2" @@ -7431,11 +7998,28 @@ dependencies = [ "webpki 0.22.0", ] +[[package]] +name = "quinn-proto" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85af4ed6ee5a89f26a26086e9089a6643650544c025158449a3626ebf72884b3" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls 0.21.2", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + [[package]] name = "quote" -version = "1.0.28" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -7625,7 +8209,7 @@ checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -7968,6 +8552,17 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "rw-stream-sink" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c9026ff5d2f23da5e45bbc283f156383001bfb09c4e44256d02c1a685fe9a1" +dependencies = [ + "futures", + "pin-project", + "static_assertions", +] + [[package]] name = "ryu" version = "1.0.13" @@ -7995,7 +8590,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "log", "sp-core", @@ -8006,7 +8601,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "futures", "futures-timer", @@ -8029,7 +8624,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -8044,7 +8639,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "memmap2 0.5.10", "sc-chain-spec-derive", @@ -8063,25 +8658,26 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", + "atomic", "chrono", "clap", "fdlimit", "futures", - "libp2p-identity", + "libp2p-identity 0.1.2", "log", "names", "parity-scale-codec", @@ -8114,7 +8710,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "fnv", "futures", @@ -8141,7 +8737,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "hash-db 0.16.0", "kvdb", @@ -8166,12 +8762,12 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "futures", "futures-timer", - "libp2p-identity", + "libp2p-identity 0.1.2", "log", "mockall", "parking_lot 0.12.1", @@ -8199,14 +8795,13 @@ dependencies = [ "sp-consensus", "sp-domains", "sp-runtime", - "sp-settlement", "subspace-fraud-proof", ] [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "futures", @@ -8239,9 +8834,11 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.12.1", "rand 0.8.5", + "rand_chacha 0.3.1", "sc-client-api", "sc-consensus", "sc-consensus-slots", + "sc-proof-of-time", "sc-telemetry", "sc-utils", "schnorrkel", @@ -8283,6 +8880,7 @@ dependencies = [ "sc-utils", "sp-api", "sp-blockchain", + "sp-consensus", "sp-consensus-slots", "sp-consensus-subspace", "sp-core", @@ -8298,7 +8896,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "lru 0.10.0", "parity-scale-codec", @@ -8320,7 +8918,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", @@ -8332,7 +8930,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "anyhow", "cfg-if", @@ -8350,7 +8948,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "ansi_term", "futures", @@ -8366,7 +8964,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "parking_lot 0.12.1", @@ -8380,19 +8978,20 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "async-channel", "async-trait", "asynchronous-codec", + "atomic", "bytes", "either", "fnv", "futures", "futures-timer", "ip_network", - "libp2p", + "libp2p 0.51.3", "linked_hash_set", "log", "lru 0.10.0", @@ -8426,12 +9025,12 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-channel", "cid", "futures", - "libp2p-identity", + "libp2p-identity 0.1.2", "log", "prost", "prost-build", @@ -8447,7 +9046,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -8455,7 +9054,7 @@ dependencies = [ "bytes", "futures", "futures-timer", - "libp2p-identity", + "libp2p-identity 0.1.2", "parity-scale-codec", "prost-build", "sc-consensus", @@ -8474,12 +9073,12 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "ahash 0.8.3", "futures", "futures-timer", - "libp2p", + "libp2p 0.51.3", "log", "lru 0.10.0", "sc-network", @@ -8492,12 +9091,12 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "async-channel", "futures", - "libp2p-identity", + "libp2p-identity 0.1.2", "log", "parity-scale-codec", "prost", @@ -8514,15 +9113,16 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "async-channel", "async-trait", + "atomic", "fork-tree", "futures", "futures-timer", - "libp2p", + "libp2p 0.51.3", "log", "lru 0.10.0", "mockall", @@ -8548,11 +9148,11 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "futures", - "libp2p", + "libp2p 0.51.3", "log", "parity-scale-codec", "sc-network", @@ -8566,7 +9166,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "bytes", @@ -8575,7 +9175,7 @@ dependencies = [ "futures-timer", "hyper", "hyper-rustls 0.24.0", - "libp2p", + "libp2p 0.51.3", "num_cpus", "once_cell", "parity-scale-codec", @@ -8593,10 +9193,31 @@ dependencies = [ "tracing", ] +[[package]] +name = "sc-proof-of-time" +version = "0.1.0" +dependencies = [ + "futures", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-network", + "sc-network-gossip", + "sp-blockchain", + "sp-consensus", + "sp-consensus-subspace", + "sp-core", + "sp-runtime", + "subspace-core-primitives", + "subspace-proof-of-time", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -8605,7 +9226,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "futures", "jsonrpsee", @@ -8636,7 +9257,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -8655,7 +9276,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "http", "jsonrpsee", @@ -8670,7 +9291,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "futures", @@ -8696,7 +9317,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "directories", @@ -8762,7 +9383,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "log", "parity-scale-codec", @@ -8773,7 +9394,7 @@ dependencies = [ [[package]] name = "sc-storage-monitor" version = "0.1.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "clap", "fs4", @@ -8822,7 +9443,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "futures", "libc", @@ -8841,11 +9462,11 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "chrono", "futures", - "libp2p", + "libp2p 0.51.3", "log", "parking_lot 0.12.1", "pin-project", @@ -8860,7 +9481,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "ansi_term", "atty", @@ -8891,18 +9512,18 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "futures", @@ -8928,7 +9549,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "futures", @@ -8944,7 +9565,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-channel", "futures", @@ -9172,42 +9793,48 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" +[[package]] +name = "seq-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" + [[package]] name = "serde" -version = "1.0.164" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" dependencies = [ "serde_derive", ] [[package]] -name = "serde-big-array" -version = "0.3.3" +name = "serde_arrays" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd31f59f6fe2b0c055371bb2f16d7f0aa7d8881676c04a55b1596d1a17cd10a4" +checksum = "38636132857f68ec3d5f3eb121166d2af33cb55174c4d5ff645db6165cbef0fd" dependencies = [ "serde", ] [[package]] -name = "serde_arrays" -version = "0.1.0" +name = "serde_bytes" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38636132857f68ec3d5f3eb121166d2af33cb55174c4d5ff645db6165cbef0fd" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -9386,9 +10013,9 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "snap" @@ -9453,7 +10080,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "hash-db 0.16.0", "log", @@ -9473,7 +10100,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "Inflector", "blake2", @@ -9481,13 +10108,13 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "sp-application-crypto" version = "23.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "scale-info", @@ -9500,7 +10127,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "16.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "integer-sqrt", "num-traits", @@ -9514,7 +10141,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "sp-api", @@ -9526,7 +10153,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "futures", "log", @@ -9544,7 +10171,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "futures", @@ -9559,7 +10186,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "parity-scale-codec", @@ -9577,7 +10204,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "parity-scale-codec", @@ -9598,7 +10225,7 @@ dependencies = [ [[package]] name = "sp-consensus-beefy" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "lazy_static", "parity-scale-codec", @@ -9617,7 +10244,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "finality-grandpa", "log", @@ -9635,7 +10262,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "scale-info", @@ -9675,13 +10302,13 @@ dependencies = [ [[package]] name = "sp-core" version = "21.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "bitflags", "blake2", "bounded-collections", - "bs58", + "bs58 0.4.0", "dyn-clonable", "ed25519-zebra", "futures", @@ -9719,7 +10346,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "9.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "blake2b_simd", "byteorder", @@ -9733,18 +10360,18 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "9.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "proc-macro2", "quote", "sp-core-hashing", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -9753,11 +10380,11 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "8.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -9776,6 +10403,7 @@ name = "sp-domains" version = "0.1.0" dependencies = [ "blake2", + "num-traits", "parity-scale-codec", "rs_merkle", "scale-info", @@ -9785,29 +10413,23 @@ dependencies = [ "sp-blockchain", "sp-consensus-slots", "sp-core", + "sp-externalities", "sp-keystore", "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", - "subspace-core-primitives", - "subspace-runtime-primitives", - "thiserror", -] - -[[package]] -name = "sp-executor-registry" -version = "0.1.0" -dependencies = [ - "parity-scale-codec", - "sp-domains", + "sp-runtime-interface", + "sp-state-machine", "sp-std", + "sp-trie", + "sp-weights", + "subspace-core-primitives", + "subspace-runtime-primitives", + "thiserror", ] [[package]] name = "sp-externalities" version = "0.19.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "environmental", "parity-scale-codec", @@ -9818,7 +10440,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -9833,7 +10455,7 @@ dependencies = [ [[package]] name = "sp-io" version = "23.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "bytes", "ed25519", @@ -9859,7 +10481,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "24.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "lazy_static", "sp-core", @@ -9870,7 +10492,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.27.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "futures", "parity-scale-codec", @@ -9908,7 +10530,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "thiserror", "zstd 0.12.3+zstd.1.5.2", @@ -9933,7 +10555,7 @@ dependencies = [ [[package]] name = "sp-metadata-ir" version = "0.1.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-metadata", "parity-scale-codec", @@ -9944,7 +10566,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "ckb-merkle-mountain-range", "log", @@ -9972,7 +10594,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "sp-api", "sp-core", @@ -9982,7 +10604,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "8.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "backtrace", "lazy_static", @@ -9992,7 +10614,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "rustc-hash", "serde", @@ -10002,7 +10624,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "24.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "either", "hash256-std-hasher", @@ -10024,7 +10646,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "17.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -10042,19 +10664,19 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "11.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "Inflector", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "scale-info", @@ -10065,22 +10687,10 @@ dependencies = [ "sp-std", ] -[[package]] -name = "sp-settlement" -version = "0.1.0" -dependencies = [ - "parity-scale-codec", - "sp-api", - "sp-core", - "sp-domains", - "sp-runtime", - "sp-std", -] - [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "scale-info", @@ -10093,7 +10703,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.28.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "hash-db 0.16.0", "log", @@ -10113,7 +10723,7 @@ dependencies = [ [[package]] name = "sp-statement-store" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "log", "parity-scale-codec", @@ -10131,12 +10741,12 @@ dependencies = [ [[package]] name = "sp-std" version = "8.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" [[package]] name = "sp-storage" version = "13.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "impl-serde", "parity-scale-codec", @@ -10149,7 +10759,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "futures-timer", @@ -10164,7 +10774,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "10.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "sp-std", @@ -10176,7 +10786,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "sp-api", "sp-runtime", @@ -10185,7 +10795,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "async-trait", "log", @@ -10201,7 +10811,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "22.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "ahash 0.8.3", "hash-db 0.16.0", @@ -10224,7 +10834,7 @@ dependencies = [ [[package]] name = "sp-version" version = "22.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "impl-serde", "parity-scale-codec", @@ -10241,18 +10851,18 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "8.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "sp-wasm-interface" version = "14.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -10265,7 +10875,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "20.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "parity-scale-codec", "scale-info", @@ -10312,128 +10922,6 @@ dependencies = [ "der 0.7.6", ] -[[package]] -name = "sqlformat" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" -dependencies = [ - "itertools", - "nom", - "unicode_categories", -] - -[[package]] -name = "sqlx" -version = "0.7.0-alpha.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afd8985c8822235a9ebeedf0bff971462470162759663d3184593c807ab6e898" -dependencies = [ - "sqlx-core", - "sqlx-macros", - "sqlx-sqlite", -] - -[[package]] -name = "sqlx-core" -version = "0.7.0-alpha.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c12403de02d88e6808de30eb2153c6997d39cc9511a446b510d5944a3ea6727" -dependencies = [ - "ahash 0.7.6", - "atoi", - "bitflags", - "byteorder", - "bytes", - "crc", - "crossbeam-queue", - "dotenvy", - "either", - "event-listener", - "futures-channel", - "futures-core", - "futures-intrusive", - "futures-io", - "futures-util", - "hashlink", - "hex", - "indexmap", - "log", - "memchr", - "native-tls", - "once_cell", - "paste", - "percent-encoding", - "serde", - "sha2 0.10.7", - "smallvec", - "sqlformat", - "thiserror", - "tokio", - "tokio-stream", - "tracing", - "url", -] - -[[package]] -name = "sqlx-macros" -version = "0.7.0-alpha.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2be74801a0852ace9d86bc8cc8ac36241e7dc712fea26b8f32bd80ce29c98a10" -dependencies = [ - "proc-macro2", - "quote", - "sqlx-core", - "sqlx-macros-core", - "syn 1.0.109", -] - -[[package]] -name = "sqlx-macros-core" -version = "0.7.0-alpha.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ce71dd8afc7ad2aeff001bb6affa7128c9087bbdcab07fa97a7952e8ee3d1da" -dependencies = [ - "dotenvy", - "either", - "heck", - "hex", - "once_cell", - "proc-macro2", - "quote", - "serde", - "serde_json", - "sha2 0.10.7", - "sqlx-core", - "sqlx-sqlite", - "syn 1.0.109", - "tempfile", - "tokio", - "url", -] - -[[package]] -name = "sqlx-sqlite" -version = "0.7.0-alpha.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f446c04b2d2d06b49b905e33c877b282e0f70b1b60a22513eacee8bf56d8afbe" -dependencies = [ - "atoi", - "flume", - "futures-channel", - "futures-core", - "futures-executor", - "futures-intrusive", - "futures-util", - "libsqlite3-sys", - "log", - "percent-encoding", - "serde", - "sqlx-core", - "tracing", - "url", -] - [[package]] name = "ss58-registry" version = "1.40.0" @@ -10570,6 +11058,7 @@ name = "subspace-core-primitives" version = "0.1.0" dependencies = [ "blake2", + "blake3", "blst_rust", "criterion", "derive_more", @@ -10609,13 +11098,14 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", + "atomic", "backoff", "base58", "blake2", "bytesize", "clap", + "cuckoofilter", "derive_more", - "dirs", "event-listener-primitives", "fdlimit", "futures", @@ -10623,8 +11113,7 @@ dependencies = [ "jemallocator", "jsonrpsee", "lru 0.10.0", - "memmap2 0.7.0", - "num-traits", + "memmap2 0.7.1", "parity-db", "parity-scale-codec", "parking_lot 0.12.1", @@ -10666,7 +11155,7 @@ dependencies = [ "futures", "libc", "lru 0.10.0", - "memmap2 0.7.0", + "memmap2 0.7.1", "parity-scale-codec", "parking_lot 0.12.1", "rand 0.8.5", @@ -10709,16 +11198,13 @@ dependencies = [ "sp-keyring", "sp-messenger", "sp-runtime", - "sp-settlement", "sp-state-machine", "sp-trie", "subspace-runtime-primitives", "subspace-test-client", "subspace-test-runtime", "subspace-test-service", - "subspace-wasm-tools", "substrate-test-utils", - "system-runtime-primitives", "tempfile", "tokio", "tracing", @@ -10729,26 +11215,29 @@ name = "subspace-networking" version = "0.1.0" dependencies = [ "actix-web", - "anyhow", + "async-mutex", "async-trait", "backoff", "bytes", - "bytesize", - "chrono", "clap", "derive_more", "either", "event-listener-primitives", + "fs2", "futures", + "futures-timer", "hex", - "libp2p", + "libp2p 0.52.1", + "libp2p-connection-limits 0.2.1", + "libp2p-kad 0.44.3", + "libp2p-quic 0.8.0-alpha", "lru 0.10.0", + "memmap2 0.7.1", "nohash-hasher", - "parity-db", "parity-scale-codec", "parking_lot 0.12.1", "pin-project", - "prometheus-client", + "prometheus-client 0.19.0", "rand 0.8.5", "serde", "serde_json", @@ -10768,14 +11257,14 @@ version = "0.1.0" dependencies = [ "bytesize", "clap", - "core-evm-runtime", "cross-domain-message-gossip", "dirs", - "domain-client-executor", + "domain-client-operator", "domain-eth-service", "domain-runtime-primitives", "domain-service", - "fp-evm", + "evm-domain-runtime", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=74483666645e121c0c5e6616f43fdfd8664ea0d3)", "frame-benchmarking", "frame-benchmarking-cli", "frame-support", @@ -10784,12 +11273,16 @@ dependencies = [ "log", "once_cell", "parity-scale-codec", + "sc-chain-spec", "sc-cli", "sc-client-api", "sc-consensus", "sc-consensus-slots", "sc-consensus-subspace", "sc-executor", + "sc-network", + "sc-network-sync", + "sc-proof-of-time", "sc-service", "sc-storage-monitor", "sc-subspace-chain-specs", @@ -10798,6 +11291,7 @@ dependencies = [ "sc-utils", "serde", "serde_json", + "sp-blockchain", "sp-consensus", "sp-consensus-subspace", "sp-core", @@ -10811,7 +11305,6 @@ dependencies = [ "subspace-runtime-primitives", "subspace-service", "substrate-build-script-utils", - "system-domain-runtime", "thiserror", "tokio", ] @@ -10821,16 +11314,28 @@ name = "subspace-proof-of-space" version = "0.1.0" dependencies = [ "bitvec", - "blake3", "chacha20 0.9.1", "criterion", + "derive_more", "rand 0.8.5", "rayon", + "seq-macro", "sha2 0.10.7", "subspace-chiapos", "subspace-core-primitives", ] +[[package]] +name = "subspace-proof-of-time" +version = "0.1.0" +dependencies = [ + "aes 0.8.3", + "criterion", + "rand 0.8.5", + "subspace-core-primitives", + "thiserror", +] + [[package]] name = "subspace-rpc-primitives" version = "0.1.0" @@ -10863,7 +11368,6 @@ dependencies = [ "pallet-offences-subspace", "pallet-rewards", "pallet-runtime-configs", - "pallet-settlement", "pallet-subspace", "pallet-sudo", "pallet-timestamp", @@ -10884,16 +11388,14 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-settlement", "sp-std", "sp-transaction-pool", "sp-version", + "static_assertions", "subspace-core-primitives", "subspace-runtime-primitives", "subspace-verification", - "subspace-wasm-tools", "substrate-wasm-builder", - "system-domain-runtime", ] [[package]] @@ -10913,6 +11415,7 @@ name = "subspace-service" version = "0.1.0" dependencies = [ "async-trait", + "atomic", "cross-domain-message-gossip", "derive_more", "domain-block-preprocessor", @@ -10938,6 +11441,7 @@ dependencies = [ "sc-executor", "sc-network", "sc-network-sync", + "sc-proof-of-time", "sc-rpc", "sc-rpc-api", "sc-rpc-spec-v2", @@ -10960,10 +11464,10 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-settlement", "sp-timestamp", "sp-transaction-pool", "sp-trie", + "static_assertions", "subspace-archiving", "subspace-core-primitives", "subspace-fraud-proof", @@ -10986,6 +11490,8 @@ version = "0.1.0" name = "subspace-test-client" version = "0.1.0" dependencies = [ + "evm-domain-test-runtime", + "fp-evm 3.0.0-dev (git+https://github.com/subspace/frontier?rev=c13d670b25b5506c1c5243f352941dc46c82ffe4)", "futures", "sc-chain-spec", "sc-client-api", @@ -10993,9 +11499,11 @@ dependencies = [ "sc-executor", "sc-service", "schnorrkel", + "serde_json", "sp-api", "sp-consensus-subspace", "sp-core", + "sp-domains", "sp-runtime", "subspace-archiving", "subspace-core-primitives", @@ -11006,7 +11514,6 @@ dependencies = [ "subspace-service", "subspace-solving", "subspace-test-runtime", - "subspace-transaction-pool", "zeroize", ] @@ -11028,7 +11535,6 @@ dependencies = [ "pallet-object-store", "pallet-offences-subspace", "pallet-rewards", - "pallet-settlement", "pallet-subspace", "pallet-sudo", "pallet-timestamp", @@ -11049,16 +11555,13 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-settlement", "sp-std", "sp-transaction-pool", "sp-version", "subspace-core-primitives", "subspace-runtime-primitives", "subspace-verification", - "subspace-wasm-tools", "substrate-wasm-builder", - "system-domain-test-runtime", ] [[package]] @@ -11067,6 +11570,7 @@ version = "0.1.0" dependencies = [ "async-trait", "cross-domain-message-gossip", + "domain-runtime-primitives", "futures", "futures-timer", "jsonrpsee", @@ -11094,12 +11598,14 @@ dependencies = [ "sp-consensus-subspace", "sp-core", "sp-domains", + "sp-externalities", "sp-inherents", "sp-keyring", "sp-runtime", "sp-timestamp", "subspace-core-primitives", "subspace-fraud-proof", + "subspace-node", "subspace-runtime-primitives", "subspace-service", "subspace-test-client", @@ -11131,6 +11637,7 @@ dependencies = [ "sp-domains", "sp-runtime", "sp-transaction-pool", + "subspace-runtime-primitives", "substrate-prometheus-endpoint", "tracing", ] @@ -11151,10 +11658,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "subspace-wasm-tools" -version = "0.1.0" - [[package]] name = "substrate-bip39" version = "0.4.4" @@ -11171,7 +11674,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "platforms", ] @@ -11179,7 +11682,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "frame-system-rpc-runtime-api", "futures", @@ -11198,7 +11701,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "hyper", "log", @@ -11210,7 +11713,7 @@ dependencies = [ [[package]] name = "substrate-test-client" version = "2.0.1" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -11236,7 +11739,7 @@ dependencies = [ [[package]] name = "substrate-test-runtime" version = "2.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "array-bytes 6.1.0", "frame-executive", @@ -11284,7 +11787,7 @@ dependencies = [ [[package]] name = "substrate-test-runtime-client" version = "2.0.0" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "futures", "parity-scale-codec", @@ -11304,7 +11807,7 @@ dependencies = [ [[package]] name = "substrate-test-utils" version = "4.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "futures", "substrate-test-utils-derive", @@ -11314,18 +11817,18 @@ dependencies = [ [[package]] name = "substrate-test-utils-derive" version = "0.10.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/subspace/substrate?rev=28e33f78a3aa8ac4c6753108bc0471273ff6bf6f#28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" +source = "git+https://github.com/subspace/substrate?rev=55c157cff49b638a59d81a9f971f0f9a66829c71#55c157cff49b638a59d81a9f971f0f9a66829c71" dependencies = [ "ansi_term", "build-helper", @@ -11368,9 +11871,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -11410,105 +11913,6 @@ dependencies = [ "libc", ] -[[package]] -name = "system-domain-runtime" -version = "0.1.0" -dependencies = [ - "domain-pallet-executive", - "domain-runtime-primitives", - "frame-benchmarking", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "pallet-balances", - "pallet-domain-registry", - "pallet-executor-registry", - "pallet-messenger", - "pallet-settlement", - "pallet-sudo", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-transporter", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-block-builder", - "sp-core", - "sp-domains", - "sp-inherents", - "sp-io", - "sp-messenger", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-settlement", - "sp-std", - "sp-transaction-pool", - "sp-version", - "subspace-runtime-primitives", - "subspace-wasm-tools", - "substrate-wasm-builder", - "system-runtime-primitives", -] - -[[package]] -name = "system-domain-test-runtime" -version = "0.1.0" -dependencies = [ - "domain-pallet-executive", - "domain-runtime-primitives", - "domain-test-primitives", - "frame-benchmarking", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "hex-literal", - "log", - "pallet-balances", - "pallet-domain-registry", - "pallet-executor-registry", - "pallet-messenger", - "pallet-settlement", - "pallet-sudo", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-transporter", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-block-builder", - "sp-core", - "sp-domains", - "sp-inherents", - "sp-io", - "sp-messenger", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-settlement", - "sp-std", - "sp-transaction-pool", - "sp-version", - "subspace-runtime-primitives", - "subspace-wasm-tools", - "substrate-wasm-builder", - "system-runtime-primitives", -] - -[[package]] -name = "system-runtime-primitives" -version = "0.1.0" -dependencies = [ - "parity-scale-codec", - "sp-api", - "sp-core", - "sp-domains", - "sp-runtime", - "sp-std", -] - [[package]] name = "tap" version = "1.0.1" @@ -11567,7 +11971,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -11688,11 +12092,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -11713,7 +12118,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -11869,7 +12274,7 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] @@ -12130,12 +12535,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - [[package]] name = "unicode-width" version = "0.1.10" @@ -12148,12 +12547,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - [[package]] name = "universal-hash" version = "0.4.1" @@ -12315,7 +12708,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", "wasm-bindgen-shared", ] @@ -12349,7 +12742,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -12668,6 +13061,15 @@ dependencies = [ "webpki 0.22.0", ] +[[package]] +name = "webpki-roots" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +dependencies = [ + "rustls-webpki", +] + [[package]] name = "webrtc" version = "0.6.0" @@ -13221,6 +13623,23 @@ dependencies = [ "time 0.3.22", ] +[[package]] +name = "x509-parser" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab0c2f54ae1d92f4fcb99c0b7ccf0b1e3451cbd395e5f115ccbdbcb18d4f634" +dependencies = [ + "asn1-rs 0.5.2", + "data-encoding", + "der-parser 8.2.0", + "lazy_static", + "nom", + "oid-registry 0.6.1", + "rusticata-macros", + "thiserror", + "time 0.3.22", +] + [[package]] name = "yamux" version = "0.10.2" @@ -13261,7 +13680,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.27", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index be484c9189b..16ac35c337e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,32 +88,32 @@ codegen-units = 1 # Reason: We need to patch substrate dependency of snowfork and frontier libraries to our fork # TODO: Remove when we are using upstream substrate instead of fork [patch."https://github.com/paritytech/substrate.git"] -frame-benchmarking = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-client-db = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-database = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-externalities = { version = "0.19.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-storage = { version = "13.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -substrate-prometheus-endpoint = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-benchmarking = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-client-db = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-database = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-externalities = { version = "0.19.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-storage = { version = "13.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +substrate-prometheus-endpoint = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } diff --git a/Dockerfile-bootstrap-node b/Dockerfile-bootstrap-node index 3b8f7146133..34cdc93cc29 100644 --- a/Dockerfile-bootstrap-node +++ b/Dockerfile-bootstrap-node @@ -1,6 +1,6 @@ FROM ubuntu:20.04 -ARG RUSTC_VERSION=nightly-2023-05-16 +ARG RUSTC_VERSION=nightly-2023-07-21 ARG PROFILE=production ARG RUSTFLAGS # Workaround for https://github.com/rust-lang/cargo/issues/10583 diff --git a/Dockerfile-bootstrap-node.aarch64 b/Dockerfile-bootstrap-node.aarch64 index b38a949363c..c10e74c417f 100644 --- a/Dockerfile-bootstrap-node.aarch64 +++ b/Dockerfile-bootstrap-node.aarch64 @@ -1,6 +1,6 @@ FROM ubuntu:20.04 -ARG RUSTC_VERSION=nightly-2023-05-16 +ARG RUSTC_VERSION=nightly-2023-07-21 ARG PROFILE=production ARG RUSTFLAGS # Workaround for https://github.com/rust-lang/cargo/issues/10583 diff --git a/Dockerfile-farmer b/Dockerfile-farmer index b45e54a5491..f49574a7247 100644 --- a/Dockerfile-farmer +++ b/Dockerfile-farmer @@ -1,6 +1,6 @@ FROM ubuntu:20.04 -ARG RUSTC_VERSION=nightly-2023-05-16 +ARG RUSTC_VERSION=nightly-2023-07-21 ARG PROFILE=production ARG RUSTFLAGS # Workaround for https://github.com/rust-lang/cargo/issues/10583 diff --git a/Dockerfile-farmer.aarch64 b/Dockerfile-farmer.aarch64 index 1391eebb690..193e9a1074b 100644 --- a/Dockerfile-farmer.aarch64 +++ b/Dockerfile-farmer.aarch64 @@ -1,6 +1,6 @@ FROM ubuntu:20.04 -ARG RUSTC_VERSION=nightly-2023-05-16 +ARG RUSTC_VERSION=nightly-2023-07-21 ARG PROFILE=production ARG RUSTFLAGS # Workaround for https://github.com/rust-lang/cargo/issues/10583 diff --git a/Dockerfile-node b/Dockerfile-node index f791bbf954b..76f014f74fd 100644 --- a/Dockerfile-node +++ b/Dockerfile-node @@ -1,6 +1,6 @@ FROM ubuntu:20.04 -ARG RUSTC_VERSION=nightly-2023-05-16 +ARG RUSTC_VERSION=nightly-2023-07-21 ARG PROFILE=production ARG RUSTFLAGS # Workaround for https://github.com/rust-lang/cargo/issues/10583 @@ -59,7 +59,7 @@ RUN \ HEALTHCHECK CMD curl \ -H "Content-Type: application/json" \ -d '{ "id": 1, "jsonrpc": "2.0", "method": "system_health", "params": [] }' \ - -f "http://localhost:9933" + -f "http://localhost:9944" COPY --from=0 /code/subspace-node /subspace-node diff --git a/Dockerfile-node.aarch64 b/Dockerfile-node.aarch64 index e9e51702cc8..4c9983bff38 100644 --- a/Dockerfile-node.aarch64 +++ b/Dockerfile-node.aarch64 @@ -1,6 +1,6 @@ FROM ubuntu:20.04 -ARG RUSTC_VERSION=nightly-2023-05-16 +ARG RUSTC_VERSION=nightly-2023-07-21 ARG PROFILE=production ARG RUSTFLAGS # Workaround for https://github.com/rust-lang/cargo/issues/10583 @@ -68,7 +68,7 @@ RUN \ HEALTHCHECK CMD curl \ -H "Content-Type: application/json" \ -d '{ "id": 1, "jsonrpc": "2.0", "method": "system_health", "params": [] }' \ - -f "http://localhost:9933" + -f "http://localhost:9944" COPY --from=0 /code/subspace-node /subspace-node diff --git a/Dockerfile-runtime b/Dockerfile-runtime index 17ae5bb7d89..ea182df6ba3 100644 --- a/Dockerfile-runtime +++ b/Dockerfile-runtime @@ -1,6 +1,6 @@ FROM ubuntu:20.04 -ARG RUSTC_VERSION=nightly-2023-05-16 +ARG RUSTC_VERSION=nightly-2023-07-21 ARG PROFILE=production ARG RUSTFLAGS # Workaround for https://github.com/rust-lang/cargo/issues/10583 diff --git a/crates/pallet-domains/Cargo.toml b/crates/pallet-domains/Cargo.toml index 4157224d708..ed74c70e00b 100644 --- a/crates/pallet-domains/Cargo.toml +++ b/crates/pallet-domains/Cargo.toml @@ -12,21 +12,25 @@ description = "Subspace domains pallet" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } log = { version = "0.4.19", default-features = false } -pallet-settlement = { version = "0.1.0", default-features = false, path = "../pallet-settlement" } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", features = ["serde"] } +subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } [dev-dependencies] -sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-externalities = { version = "0.19.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +subspace-runtime-primitives = { version = "0.1.0", path = "../subspace-runtime-primitives" } [features] default = ["std"] @@ -39,9 +43,11 @@ std = [ "scale-info/std", "sp-core/std", "sp-domains/std", - "pallet-settlement/std", + "sp-io/std", "sp-runtime/std", "sp-std/std", + "sp-version/std", + "subspace-core-primitives/std", ] try-runtime = ["frame-support/try-runtime"] runtime-benchmarks = [ diff --git a/crates/pallet-domains/src/benchmarking.rs b/crates/pallet-domains/src/benchmarking.rs index 18005a334f3..8ed971bc453 100644 --- a/crates/pallet-domains/src/benchmarking.rs +++ b/crates/pallet-domains/src/benchmarking.rs @@ -14,19 +14,22 @@ use sp_runtime::traits::SaturatedConversion; mod benchmarks { use super::*; + // TODO: Remove when DomainRegistry is usable. + const DOMAIN_ID: DomainId = DomainId::new(0); + /// Benchmark `submit_bundle` extrinsic with the worst possible conditions: /// - Submit a system domain bundle /// - The receipts will prune a expired receipt #[benchmark] fn submit_system_bundle() { - let receipts_pruning_depth = T::ReceiptsPruningDepth::get().saturated_into::(); + let block_tree_pruning_depth = T::BlockTreePruningDepth::get().saturated_into::(); - // Import `ReceiptsPruningDepth` number of receipts which will be pruned later - run_to_block::(1, receipts_pruning_depth); - for i in 0..receipts_pruning_depth { + // Import `BlockTreePruningDepth` number of receipts which will be pruned later + run_to_block::(1, block_tree_pruning_depth); + for i in 0..block_tree_pruning_depth { let receipt = ExecutionReceipt::dummy(i.into(), block_hash_n::(i)); let bundle = create_dummy_bundle_with_receipts_generic( - DomainId::SYSTEM, + DOMAIN_ID, (i + 1).into(), Default::default(), receipt, @@ -35,18 +38,18 @@ mod benchmarks { } assert_eq!( Domains::::head_receipt_number(), - (receipts_pruning_depth - 1).into() + (block_tree_pruning_depth - 1).into() ); // Construct a bundle that contains a new receipt - run_to_block::(receipts_pruning_depth + 1, receipts_pruning_depth + 2); + run_to_block::(block_tree_pruning_depth + 1, block_tree_pruning_depth + 2); let receipt = ExecutionReceipt::dummy( - receipts_pruning_depth.into(), - block_hash_n::(receipts_pruning_depth), + block_tree_pruning_depth.into(), + block_hash_n::(block_tree_pruning_depth), ); let bundle = create_dummy_bundle_with_receipts_generic( - DomainId::SYSTEM, - (receipts_pruning_depth + 1).into(), + DOMAIN_ID, + (block_tree_pruning_depth + 1).into(), Default::default(), receipt, ); @@ -56,7 +59,7 @@ mod benchmarks { assert_eq!( Domains::::head_receipt_number(), - receipts_pruning_depth.into() + block_tree_pruning_depth.into() ); assert_eq!(Domains::::oldest_receipt_number(), 1u32.into()); } @@ -64,7 +67,7 @@ mod benchmarks { #[benchmark] fn submit_core_bundle() { let bundle = create_dummy_bundle_with_receipts_generic( - DomainId::CORE_PAYMENTS, + DomainId::from(1u32), 2u32.into(), Default::default(), ExecutionReceipt::dummy(1u32.into(), block_hash_n::(1)), @@ -79,14 +82,14 @@ mod benchmarks { /// - The fraud proof will revert the maximal possible number of receipts #[benchmark] fn submit_system_domain_invalid_state_transition_proof() { - let receipts_pruning_depth = T::ReceiptsPruningDepth::get().saturated_into::(); + let block_tree_pruning_depth = T::BlockTreePruningDepth::get().saturated_into::(); - // Import `ReceiptsPruningDepth` number of receipts which will be revert later - run_to_block::(1, receipts_pruning_depth); - for i in 0..receipts_pruning_depth { + // Import `BlockTreePruningDepth` number of receipts which will be revert later + run_to_block::(1, block_tree_pruning_depth); + for i in 0..block_tree_pruning_depth { let receipt = ExecutionReceipt::dummy(i.into(), block_hash_n::(i)); let bundle = create_dummy_bundle_with_receipts_generic( - DomainId::SYSTEM, + DOMAIN_ID, (i + 1).into(), Default::default(), receipt, @@ -95,13 +98,12 @@ mod benchmarks { } assert_eq!( Domains::::head_receipt_number(), - (receipts_pruning_depth - 1).into() + (block_tree_pruning_depth - 1).into() ); - // Construct a fraud proof that will revert `ReceiptsPruningDepth` number of receipts - let proof: FraudProof = FraudProof::InvalidStateTransition( - dummy_invalid_state_transition_proof(DomainId::SYSTEM, 0), - ); + // Construct a fraud proof that will revert `BlockTreePruningDepth` number of receipts + let proof: FraudProof = + FraudProof::InvalidStateTransition(dummy_invalid_state_transition_proof(DOMAIN_ID, 0)); #[extrinsic_call] submit_fraud_proof(RawOrigin::None, proof); diff --git a/crates/pallet-domains/src/block_tree.rs b/crates/pallet-domains/src/block_tree.rs new file mode 100644 index 00000000000..c67f323f473 --- /dev/null +++ b/crates/pallet-domains/src/block_tree.rs @@ -0,0 +1,878 @@ +//! Domain block tree + +use crate::{ + BalanceOf, BlockTree, Config, DomainBlocks, ExecutionInbox, ExecutionReceiptOf, + HeadReceiptNumber, InboxedBundle, +}; +use codec::{Decode, Encode}; +use frame_support::{ensure, PalletError}; +use scale_info::TypeInfo; +use sp_core::Get; +use sp_domains::merkle_tree::MerkleTree; +use sp_domains::{DomainId, ExecutionReceipt, OperatorId}; +use sp_runtime::traits::{CheckedSub, One, Saturating, Zero}; +use sp_std::cmp::Ordering; +use sp_std::vec::Vec; + +/// Block tree specific errors +#[derive(TypeInfo, Encode, Decode, PalletError, Debug, PartialEq)] +pub enum Error { + InvalidExtrinsicsRoots, + UnknownParentBlockReceipt, + BuiltOnUnknownConsensusBlock, + InFutureReceipt, + PrunedReceipt, + BadGenesisReceipt, + UnexpectedReceiptType, + MaxHeadDomainNumber, + MultipleERsAfterChallengePeriod, + MissingDomainBlock, + InvalidTraceRoot, +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct DomainBlock { + /// The full ER for this block. + pub execution_receipt: ExecutionReceipt, + /// A set of all operators who have committed to this ER within a bundle. Used to determine who to + /// slash if a fraudulent branch of the `block_tree` is pruned. + /// + /// NOTE: there may be duplicated operator id as an operator can submit multiple bundles with the + /// same head receipt to a consensus block. + pub operator_ids: Vec, +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) enum AcceptedReceiptType { + // New head receipt that extend the longest branch + NewHead, + // Receipt that creates a new branch of the block tree + NewBranch, + // Receipt that comfirms the current head receipt + CurrentHead, +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) enum RejectedReceiptType { + // Receipt that is newer than the head receipt but does not extend the head receipt + InFuture, + // Receipt that already been pruned + Pruned, +} + +impl From for Error { + fn from(rejected_receipt: RejectedReceiptType) -> Error { + match rejected_receipt { + RejectedReceiptType::InFuture => Error::InFutureReceipt, + RejectedReceiptType::Pruned => Error::PrunedReceipt, + } + } +} + +/// The type of receipt regarding to its freshness +#[derive(Debug, PartialEq, Eq)] +pub(crate) enum ReceiptType { + Accepted(AcceptedReceiptType), + Rejected(RejectedReceiptType), + // Receipt that comfirm a non-head receipt + Stale, +} + +/// Get the receipt type of the given receipt based on the current block tree state +pub(crate) fn execution_receipt_type( + domain_id: DomainId, + execution_receipt: &ExecutionReceiptOf, +) -> ReceiptType { + let receipt_number = execution_receipt.domain_block_number; + let head_receipt_number = HeadReceiptNumber::::get(domain_id); + + match receipt_number.cmp(&head_receipt_number.saturating_add(One::one())) { + Ordering::Greater => ReceiptType::Rejected(RejectedReceiptType::InFuture), + Ordering::Equal => ReceiptType::Accepted(AcceptedReceiptType::NewHead), + Ordering::Less => { + let oldest_receipt_number = + head_receipt_number.saturating_sub(T::BlockTreePruningDepth::get()); + let already_exist = + BlockTree::::get(domain_id, receipt_number).contains(&execution_receipt.hash()); + + if receipt_number < oldest_receipt_number { + // Receipt already pruned + ReceiptType::Rejected(RejectedReceiptType::Pruned) + } else if !already_exist { + // Create new branch + ReceiptType::Accepted(AcceptedReceiptType::NewBranch) + } else if receipt_number == head_receipt_number { + // Add comfirm to the current head receipt + ReceiptType::Accepted(AcceptedReceiptType::CurrentHead) + } else { + // Add comfirm to a non-head receipt + ReceiptType::Stale + } + } + } +} + +/// Verify the execution receipt +pub(crate) fn verify_execution_receipt( + domain_id: DomainId, + execution_receipt: &ExecutionReceiptOf, +) -> Result<(), Error> { + let ExecutionReceipt { + consensus_block_number, + consensus_block_hash, + domain_block_number, + block_extrinsics_roots, + parent_domain_block_receipt_hash, + execution_trace, + execution_trace_root, + .. + } = execution_receipt; + + if domain_block_number.is_zero() { + // The genesis receipt is generated and added to the block tree by the runtime upon domain + // instantiation, thus it is unchallengeable and must always be the same. + ensure!( + BlockTree::::get(domain_id, domain_block_number).contains(&execution_receipt.hash()), + Error::BadGenesisReceipt + ); + } else { + let execution_inbox = + ExecutionInbox::::get((domain_id, domain_block_number, consensus_block_number)); + let expected_extrinsics_roots: Vec<_> = execution_inbox + .into_iter() + .map(|b| b.extrinsics_root) + .collect(); + ensure!( + !block_extrinsics_roots.is_empty() + && *block_extrinsics_roots == expected_extrinsics_roots, + Error::InvalidExtrinsicsRoots + ); + + let mut trace = Vec::with_capacity(execution_trace.len()); + for root in execution_trace { + trace.push( + root.encode() + .try_into() + .map_err(|_| Error::InvalidTraceRoot)?, + ); + } + let expected_execution_trace_root: sp_core::H256 = + MerkleTree::from_leaves(trace.as_slice()) + .root() + .ok_or(Error::InvalidTraceRoot)? + .into(); + ensure!( + expected_execution_trace_root == *execution_trace_root, + Error::InvalidTraceRoot + ); + } + + let excepted_consensus_block_hash = + frame_system::Pallet::::block_hash(consensus_block_number); + ensure!( + *consensus_block_hash == excepted_consensus_block_hash, + Error::BuiltOnUnknownConsensusBlock + ); + + if let Some(parent_block_number) = domain_block_number.checked_sub(&One::one()) { + let parent_block_exist = BlockTree::::get(domain_id, parent_block_number) + .contains(parent_domain_block_receipt_hash); + ensure!(parent_block_exist, Error::UnknownParentBlockReceipt); + } + + match execution_receipt_type::(domain_id, execution_receipt) { + ReceiptType::Rejected(RejectedReceiptType::InFuture) => { + log::error!( + target: "runtime::domains", + "Unexpected in future receipt {execution_receipt:?}, which should result in \ + `UnknownParentBlockReceipt` error as it parent receipt is missing" + ); + Err(Error::InFutureReceipt) + } + ReceiptType::Rejected(RejectedReceiptType::Pruned) => { + log::error!( + target: "runtime::domains", + "Unexpected pruned receipt {execution_receipt:?}, which should result in \ + `InvalidExtrinsicsRoots` error as its `ExecutionInbox` is pruned at the same time" + ); + Err(Error::PrunedReceipt) + } + ReceiptType::Accepted(_) | ReceiptType::Stale => Ok(()), + } +} + +/// Details of the pruned domain block such as operators, rewards they would receive. +pub(crate) struct PrunedDomainBlockInfo { + pub domain_block_number: DomainNumber, + pub operator_ids: Vec, + #[allow(dead_code)] + // TODO: use once actual rewards are set + pub rewards: Balance, +} + +pub(crate) type ProcessExecutionReceiptResult = + Result::DomainNumber, BalanceOf>>, Error>; + +/// Process the execution receipt to add it to the block tree +/// Returns the domain block number that was pruned, if any +pub(crate) fn process_execution_receipt( + domain_id: DomainId, + submitter: OperatorId, + execution_receipt: ExecutionReceiptOf, + receipt_type: AcceptedReceiptType, +) -> ProcessExecutionReceiptResult { + let mut pruned_domain_block_info = None; + match receipt_type { + AcceptedReceiptType::NewBranch => { + add_new_receipt_to_block_tree::(domain_id, submitter, execution_receipt); + } + AcceptedReceiptType::NewHead => { + let domain_block_number = execution_receipt.domain_block_number; + + add_new_receipt_to_block_tree::(domain_id, submitter, execution_receipt); + + // Update the head receipt number + HeadReceiptNumber::::insert(domain_id, domain_block_number); + + // Prune expired domain block + if let Some(to_prune) = + domain_block_number.checked_sub(&T::BlockTreePruningDepth::get()) + { + let receipts_at_number = BlockTree::::take(domain_id, to_prune); + if receipts_at_number.len() != 1 { + return Err(Error::MultipleERsAfterChallengePeriod); + } + + let receipt = receipts_at_number + .first() + .cloned() + .expect("should always have a value due to check above"); + + let domain_block = + DomainBlocks::::take(receipt).ok_or(Error::MissingDomainBlock)?; + + // Remove the block's `ExecutionInbox` and `InboxedBundle` as the block is pruned and + // does not need to verify its receipt's `extrinsics_root` anymore. + for bundle_digests in ExecutionInbox::::iter_prefix_values((domain_id, to_prune)) + { + for bd in bundle_digests { + InboxedBundle::::remove(bd.header_hash); + } + } + let _ = ExecutionInbox::::clear_prefix((domain_id, to_prune), u32::MAX, None); + + pruned_domain_block_info = Some(PrunedDomainBlockInfo { + domain_block_number: to_prune, + operator_ids: domain_block.operator_ids, + rewards: domain_block.execution_receipt.total_rewards, + }) + } + } + AcceptedReceiptType::CurrentHead => { + // Add confirmation to the current head receipt + let er_hash = execution_receipt.hash(); + DomainBlocks::::mutate(er_hash, |maybe_domain_block| { + let domain_block = maybe_domain_block.as_mut().expect( + "The domain block of `CurrentHead` receipt is checked to be exist in `execution_receipt_type`; qed" + ); + domain_block.operator_ids.push(submitter); + }); + } + } + Ok(pruned_domain_block_info) +} + +fn add_new_receipt_to_block_tree( + domain_id: DomainId, + submitter: OperatorId, + execution_receipt: ExecutionReceiptOf, +) { + // Construct and add a new domain block to the block tree + let er_hash = execution_receipt.hash(); + let domain_block_number = execution_receipt.domain_block_number; + let domain_block = DomainBlock { + execution_receipt, + operator_ids: sp_std::vec![submitter], + }; + BlockTree::::mutate(domain_id, domain_block_number, |er_hashes| { + er_hashes.insert(er_hash); + }); + DomainBlocks::::insert(er_hash, domain_block); +} + +/// Import the genesis receipt to the block tree +pub(crate) fn import_genesis_receipt( + domain_id: DomainId, + genesis_receipt: ExecutionReceiptOf, +) { + let er_hash = genesis_receipt.hash(); + let domain_block_number = genesis_receipt.domain_block_number; + let domain_block = DomainBlock { + execution_receipt: genesis_receipt, + operator_ids: sp_std::vec![], + }; + // NOTE: no need to update the head receipt number as we are using `ValueQuery` + BlockTree::::mutate(domain_id, domain_block_number, |er_hashes| { + er_hashes.insert(er_hash); + }); + DomainBlocks::::insert(er_hash, domain_block); +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::domain_registry::DomainConfig; + use crate::pallet::Operators; + use crate::staking::{Operator, OperatorStatus}; + use crate::tests::{ + create_dummy_bundle_with_receipts, create_dummy_receipt, GenesisStateRootGenerater, + ReadRuntimeVersion, Test, + }; + use crate::{BalanceOf, NextDomainId}; + use frame_support::dispatch::RawOrigin; + use frame_support::traits::{Currency, Hooks}; + use frame_support::weights::Weight; + use frame_support::{assert_err, assert_ok}; + use frame_system::Pallet as System; + use sp_core::{Pair, H256, U256}; + use sp_domains::{BundleDigest, GenesisReceiptExtension, OperatorPair, RuntimeType}; + use sp_version::RuntimeVersion; + use std::sync::Arc; + use subspace_runtime_primitives::SSC; + + fn run_to_block(block_number: T::BlockNumber, parent_hash: T::Hash) { + System::::set_block_number(block_number); + System::::initialize(&block_number, &parent_hash, &Default::default()); + as Hooks>::on_initialize(block_number); + System::::finalize(); + } + + fn register_genesis_domain(creator: u64, operator_ids: Vec) -> DomainId { + assert_ok!(crate::Pallet::::register_domain_runtime( + RawOrigin::Root.into(), + b"evm".to_vec(), + RuntimeType::Evm, + vec![1, 2, 3, 4], + )); + + let domain_id = NextDomainId::::get(); + ::Currency::make_free_balance_be( + &creator, + ::DomainInstantiationDeposit::get() + + ::ExistentialDeposit::get(), + ); + crate::Pallet::::instantiate_domain( + RawOrigin::Signed(creator).into(), + DomainConfig { + domain_name: b"evm-domain".to_vec(), + runtime_id: 0, + max_block_size: 1u32, + max_block_weight: Weight::from_parts(1, 0), + bundle_slot_probability: (1, 1), + target_bundles_per_block: 1, + }, + ) + .unwrap(); + + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + for operator_id in operator_ids { + Operators::::insert( + operator_id, + Operator { + signing_key: pair.public(), + current_domain_id: domain_id, + next_domain_id: domain_id, + minimum_nominator_stake: SSC, + nomination_tax: Default::default(), + current_total_stake: Zero::zero(), + current_epoch_rewards: Zero::zero(), + total_shares: Zero::zero(), + status: OperatorStatus::Registered, + }, + ); + } + + domain_id + } + + // Submit new head receipt to extend the block tree + fn extend_block_tree(domain_id: DomainId, operator_id: u64, to: u64) { + let head_receipt_number = HeadReceiptNumber::::get(domain_id); + assert!(head_receipt_number < to); + + let head_node = get_block_tree_node_at::(domain_id, head_receipt_number).unwrap(); + let mut receipt = head_node.execution_receipt; + for block_number in (head_receipt_number + 1)..=to { + // Run to `block_number` + run_to_block::( + block_number, + frame_system::Pallet::::block_hash(block_number - 1), + ); + + // Submit a bundle with the receipt of the last block + let bundle_extrinsics_root = H256::random(); + let bundle = create_dummy_bundle_with_receipts( + domain_id, + operator_id, + bundle_extrinsics_root, + receipt, + ); + assert_ok!(crate::Pallet::::submit_bundle( + RawOrigin::None.into(), + bundle, + )); + + // Construct a `NewHead` receipt of the just submitted bundle, which will be included in the next bundle + let head_receipt_number = HeadReceiptNumber::::get(domain_id); + let parent_block_tree_node = + get_block_tree_node_at::(domain_id, head_receipt_number).unwrap(); + receipt = create_dummy_receipt( + block_number, + frame_system::Pallet::::block_hash(block_number), + parent_block_tree_node.execution_receipt.hash(), + vec![bundle_extrinsics_root], + ); + } + } + + #[allow(clippy::type_complexity)] + fn get_block_tree_node_at( + domain_id: DomainId, + block_number: T::DomainNumber, + ) -> Option>> + { + BlockTree::::get(domain_id, block_number) + .first() + .and_then(DomainBlocks::::get) + } + + fn new_test_ext() -> sp_io::TestExternalities { + let version = RuntimeVersion { + spec_name: "test".into(), + impl_name: Default::default(), + authoring_version: 0, + spec_version: 1, + impl_version: 1, + apis: Default::default(), + transaction_version: 1, + state_version: 0, + }; + + let mut ext = crate::tests::new_test_ext(); + ext.register_extension(sp_core::traits::ReadRuntimeVersionExt::new( + ReadRuntimeVersion(version.encode()), + )); + ext.register_extension(GenesisReceiptExtension::new(Arc::new( + GenesisStateRootGenerater, + ))); + + ext + } + + #[test] + fn test_genesis_receipt() { + let mut ext = new_test_ext(); + ext.execute_with(|| { + let domain_id = register_genesis_domain(0u64, vec![0u64]); + + // The genesis receipt should be added to the block tree + let block_tree_node_at_0 = BlockTree::::get(domain_id, 0); + assert_eq!(block_tree_node_at_0.len(), 1); + + let genesis_node = + DomainBlocks::::get(block_tree_node_at_0.first().unwrap()).unwrap(); + assert!(genesis_node.operator_ids.is_empty()); + assert_eq!(HeadReceiptNumber::::get(domain_id), 0); + + // The genesis receipt should be able pass the verification and is unchallengeable + let genesis_receipt = genesis_node.execution_receipt; + let invalid_genesis_receipt = { + let mut receipt = genesis_receipt.clone(); + receipt.final_state_root = H256::random(); + receipt + }; + assert_ok!(verify_execution_receipt::( + domain_id, + &genesis_receipt + )); + assert_err!( + verify_execution_receipt::(domain_id, &invalid_genesis_receipt), + Error::BadGenesisReceipt + ); + }); + } + + #[test] + fn test_new_head_receipt() { + let creator = 0u64; + let operator_id = 1u64; + let block_tree_pruning_depth = ::BlockTreePruningDepth::get() as u64; + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let domain_id = register_genesis_domain(creator, vec![operator_id]); + + // The genesis node of the block tree + let genesis_node = get_block_tree_node_at::(domain_id, 0).unwrap(); + let mut receipt = genesis_node.execution_receipt; + let mut receipt_of_block_1 = None; + let mut bundle_header_hash_of_block_1 = None; + for block_number in 1..=(block_tree_pruning_depth + 3) { + // Run to `block_number` + run_to_block::( + block_number, + frame_system::Pallet::::block_hash(block_number - 1), + ); + + // Submit a bundle with the receipt of the last block + let bundle_extrinsics_root = H256::random(); + let bundle = create_dummy_bundle_with_receipts( + domain_id, + operator_id, + bundle_extrinsics_root, + receipt, + ); + let bundle_header_hash = bundle.sealed_header.pre_hash(); + assert_ok!(crate::Pallet::::submit_bundle( + RawOrigin::None.into(), + bundle, + )); + // `bundle_extrinsics_root` should be tracked in `ExecutionInbox` + assert_eq!( + ExecutionInbox::::get((domain_id, block_number, block_number)), + vec![BundleDigest { + header_hash: bundle_header_hash, + extrinsics_root: bundle_extrinsics_root, + }] + ); + assert!(InboxedBundle::::contains_key(bundle_header_hash)); + + // Head receipt number should be updated + let head_receipt_number = HeadReceiptNumber::::get(domain_id); + assert_eq!(head_receipt_number, block_number - 1); + + // As we only extending the block tree there should be no fork + let parent_block_tree_nodes = + BlockTree::::get(domain_id, head_receipt_number); + assert_eq!(parent_block_tree_nodes.len(), 1); + + // The submitter should be added to `operator_ids` + let parent_domain_block_receipt = parent_block_tree_nodes.first().unwrap(); + let parent_node = DomainBlocks::::get(parent_domain_block_receipt).unwrap(); + assert_eq!(parent_node.operator_ids.len(), 1); + assert_eq!(parent_node.operator_ids[0], operator_id); + + // Construct a `NewHead` receipt of the just submitted bundle, which will be included + // in the next bundle + receipt = create_dummy_receipt( + block_number, + frame_system::Pallet::::block_hash(block_number), + *parent_domain_block_receipt, + vec![bundle_extrinsics_root], + ); + assert_eq!( + execution_receipt_type::(domain_id, &receipt), + ReceiptType::Accepted(AcceptedReceiptType::NewHead) + ); + assert_ok!(verify_execution_receipt::(domain_id, &receipt)); + + // Record receipt of block #1 for later use + if block_number == 1 { + receipt_of_block_1.replace(receipt.clone()); + bundle_header_hash_of_block_1.replace(bundle_header_hash); + } + } + + // The receipt of the block 1 is pruned at the last iteration, verify it will result in + // `InvalidExtrinsicsRoots` error as `ExecutionInbox` of block 1 is pruned + let pruned_receipt = receipt_of_block_1.unwrap(); + let pruned_bundle = bundle_header_hash_of_block_1.unwrap(); + assert!(BlockTree::::get(domain_id, 1).is_empty()); + assert!(ExecutionInbox::::get((domain_id, 1, 1)).is_empty()); + assert!(!InboxedBundle::::contains_key(pruned_bundle)); + assert_eq!( + execution_receipt_type::(domain_id, &pruned_receipt), + ReceiptType::Rejected(RejectedReceiptType::Pruned) + ); + assert_err!( + verify_execution_receipt::(domain_id, &pruned_receipt), + Error::InvalidExtrinsicsRoots + ); + }); + } + + #[test] + fn test_confirm_head_receipt() { + let creator = 0u64; + let operator_id1 = 1u64; + let operator_id2 = 2u64; + let mut ext = new_test_ext(); + ext.execute_with(|| { + let domain_id = register_genesis_domain(creator, vec![operator_id1, operator_id2]); + extend_block_tree(domain_id, operator_id1, 3); + + let head_receipt_number = HeadReceiptNumber::::get(domain_id); + + // Get the head receipt + let current_head_receipt = + get_block_tree_node_at::(domain_id, head_receipt_number) + .unwrap() + .execution_receipt; + + // Receipt should be valid + assert_eq!( + execution_receipt_type::(domain_id, ¤t_head_receipt), + ReceiptType::Accepted(AcceptedReceiptType::CurrentHead) + ); + assert_ok!(verify_execution_receipt::( + domain_id, + ¤t_head_receipt + )); + + // Re-submit the receipt will add confirm to the head receipt + let bundle = create_dummy_bundle_with_receipts( + domain_id, + operator_id2, + H256::random(), + current_head_receipt, + ); + assert_ok!(crate::Pallet::::submit_bundle( + RawOrigin::None.into(), + bundle, + )); + let head_node = get_block_tree_node_at::(domain_id, head_receipt_number).unwrap(); + assert_eq!(head_node.operator_ids, vec![operator_id1, operator_id2]); + }); + } + + #[test] + fn test_stale_receipt() { + let creator = 0u64; + let operator_id1 = 1u64; + let operator_id2 = 2u64; + let mut ext = new_test_ext(); + ext.execute_with(|| { + let domain_id = register_genesis_domain(creator, vec![operator_id1, operator_id2]); + extend_block_tree(domain_id, operator_id1, 3); + + // Receipt that comfirm a non-head receipt is stale receipt + let head_receipt_number = HeadReceiptNumber::::get(domain_id); + let stale_receipt = get_block_tree_node_at::(domain_id, head_receipt_number - 1) + .unwrap() + .execution_receipt; + let stale_receipt_hash = stale_receipt.hash(); + + // Stale receipt can pass the verification + assert_eq!( + execution_receipt_type::(domain_id, &stale_receipt), + ReceiptType::Stale + ); + assert_ok!(verify_execution_receipt::(domain_id, &stale_receipt)); + + // Stale receipt can be submitted but won't be added to the block tree + let bundle = create_dummy_bundle_with_receipts( + domain_id, + operator_id2, + H256::random(), + stale_receipt, + ); + assert_ok!(crate::Pallet::::submit_bundle( + RawOrigin::None.into(), + bundle, + )); + + assert_eq!( + DomainBlocks::::get(stale_receipt_hash) + .unwrap() + .operator_ids, + vec![operator_id1] + ); + }); + } + + #[test] + fn test_new_branch_receipt() { + let creator = 0u64; + let operator_id1 = 1u64; + let operator_id2 = 2u64; + let mut ext = new_test_ext(); + ext.execute_with(|| { + let domain_id = register_genesis_domain(creator, vec![operator_id1, operator_id2]); + extend_block_tree(domain_id, operator_id1, 3); + + let head_receipt_number = HeadReceiptNumber::::get(domain_id); + assert_eq!( + BlockTree::::get(domain_id, head_receipt_number).len(), + 1 + ); + + // Construct new branch receipt that fork away from an existing node of + // the block tree + let new_branch_receipt = { + let mut head_receipt = + get_block_tree_node_at::(domain_id, head_receipt_number) + .unwrap() + .execution_receipt; + head_receipt.final_state_root = H256::random(); + head_receipt + }; + let new_branch_receipt_hash = new_branch_receipt.hash(); + + // New branch receipt can pass the verification + assert_eq!( + execution_receipt_type::(domain_id, &new_branch_receipt), + ReceiptType::Accepted(AcceptedReceiptType::NewBranch) + ); + assert_ok!(verify_execution_receipt::( + domain_id, + &new_branch_receipt + )); + + // Submit the new branch receipt will create fork in the block tree + let bundle = create_dummy_bundle_with_receipts( + domain_id, + operator_id2, + H256::random(), + new_branch_receipt, + ); + assert_ok!(crate::Pallet::::submit_bundle( + RawOrigin::None.into(), + bundle, + )); + + let nodes = BlockTree::::get(domain_id, head_receipt_number); + assert_eq!(nodes.len(), 2); + for n in nodes.iter() { + let block = DomainBlocks::::get(n).unwrap(); + if *n == new_branch_receipt_hash { + assert_eq!(block.operator_ids, vec![operator_id2]); + } else { + assert_eq!(block.operator_ids, vec![operator_id1]); + } + } + }); + } + + #[test] + fn test_invalid_receipt() { + let creator = 0u64; + let operator_id = 1u64; + let mut ext = new_test_ext(); + ext.execute_with(|| { + let domain_id = register_genesis_domain(creator, vec![operator_id]); + extend_block_tree(domain_id, operator_id, 3); + + let head_receipt_number = HeadReceiptNumber::::get(domain_id); + let current_head_receipt = + get_block_tree_node_at::(domain_id, head_receipt_number) + .unwrap() + .execution_receipt; + + // In future receipt will result in `UnknownParentBlockReceipt` error as its parent + // receipt is missing from the block tree + let mut future_receipt = current_head_receipt.clone(); + future_receipt.domain_block_number = head_receipt_number + 2; + future_receipt.consensus_block_number = head_receipt_number + 2; + ExecutionInbox::::insert( + ( + domain_id, + future_receipt.domain_block_number, + future_receipt.consensus_block_number, + ), + future_receipt + .block_extrinsics_roots + .clone() + .into_iter() + .map(|er| BundleDigest { + header_hash: H256::random(), + extrinsics_root: er, + }) + .collect::>(), + ); + assert_eq!( + execution_receipt_type::(domain_id, &future_receipt), + ReceiptType::Rejected(RejectedReceiptType::InFuture) + ); + assert_err!( + verify_execution_receipt::(domain_id, &future_receipt), + Error::UnknownParentBlockReceipt + ); + + // Receipt with unknown extrinsics roots + let mut unknown_extrinsics_roots_receipt = current_head_receipt.clone(); + unknown_extrinsics_roots_receipt.block_extrinsics_roots = vec![H256::random()]; + assert_err!( + verify_execution_receipt::(domain_id, &unknown_extrinsics_roots_receipt), + Error::InvalidExtrinsicsRoots + ); + + // Receipt with unknown consensus block hash + let mut unknown_consensus_block_receipt = current_head_receipt.clone(); + unknown_consensus_block_receipt.consensus_block_hash = H256::random(); + assert_err!( + verify_execution_receipt::(domain_id, &unknown_consensus_block_receipt), + Error::BuiltOnUnknownConsensusBlock + ); + + // Receipt with unknown parent receipt + let mut unknown_parent_receipt = current_head_receipt; + unknown_parent_receipt.parent_domain_block_receipt_hash = H256::random(); + assert_err!( + verify_execution_receipt::(domain_id, &unknown_parent_receipt), + Error::UnknownParentBlockReceipt + ); + }); + } + + #[test] + fn test_invalid_trace_root_receipt() { + let creator = 0u64; + let operator_id1 = 1u64; + let operator_id2 = 2u64; + let mut ext = new_test_ext(); + ext.execute_with(|| { + let domain_id = register_genesis_domain(creator, vec![operator_id1, operator_id2]); + extend_block_tree(domain_id, operator_id1, 3); + + let head_receipt_number = HeadReceiptNumber::::get(domain_id); + + // Get the head receipt + let current_head_receipt = + get_block_tree_node_at::(domain_id, head_receipt_number) + .unwrap() + .execution_receipt; + + // Receipt with wrong value of `execution_trace_root` + let mut invalid_receipt = current_head_receipt.clone(); + invalid_receipt.execution_trace_root = H256::random(); + assert_err!( + verify_execution_receipt::(domain_id, &invalid_receipt), + Error::InvalidTraceRoot + ); + + // Receipt with wrong value of trace + let mut invalid_receipt = current_head_receipt.clone(); + invalid_receipt.execution_trace[0] = H256::random(); + assert_err!( + verify_execution_receipt::(domain_id, &invalid_receipt), + Error::InvalidTraceRoot + ); + + // Receipt with addtional trace + let mut invalid_receipt = current_head_receipt.clone(); + invalid_receipt.execution_trace.push(H256::random()); + assert_err!( + verify_execution_receipt::(domain_id, &invalid_receipt), + Error::InvalidTraceRoot + ); + + // Receipt with missing trace + let mut invalid_receipt = current_head_receipt; + invalid_receipt.execution_trace.pop(); + assert_err!( + verify_execution_receipt::(domain_id, &invalid_receipt), + Error::InvalidTraceRoot + ); + }); + } +} diff --git a/crates/pallet-domains/src/domain_registry.rs b/crates/pallet-domains/src/domain_registry.rs new file mode 100644 index 00000000000..9b33db67b44 --- /dev/null +++ b/crates/pallet-domains/src/domain_registry.rs @@ -0,0 +1,353 @@ +//! Domain registry for domains + +use crate::block_tree::import_genesis_receipt; +use crate::pallet::DomainStakingSummary; +use crate::staking::StakingSummary; +use crate::{ + Config, DomainRegistry, ExecutionReceiptOf, HoldIdentifier, NextDomainId, RuntimeRegistry, +}; +use codec::{Decode, Encode}; +use frame_support::traits::fungible::{Inspect, MutateHold}; +use frame_support::traits::tokens::{Fortitude, Preservation}; +use frame_support::weights::Weight; +use frame_support::{ensure, PalletError}; +use scale_info::TypeInfo; +use sp_core::Get; +use sp_domains::domain::generate_genesis_state_root; +use sp_domains::{ + DomainId, DomainInstanceData, DomainsDigestItem, ReceiptHash, RuntimeId, RuntimeType, +}; +use sp_runtime::traits::{CheckedAdd, Zero}; +use sp_runtime::DigestItem; +use sp_std::collections::btree_map::BTreeMap; +use sp_std::collections::btree_set::BTreeSet; +use sp_std::vec::Vec; + +/// Domain registry specific errors +#[derive(TypeInfo, Encode, Decode, PalletError, Debug, PartialEq)] +pub enum Error { + InvalidBundlesPerBlock, + ExceedMaxDomainBlockWeight, + ExceedMaxDomainBlockSize, + MaxDomainId, + InvalidSlotProbability, + RuntimeNotFound, + InsufficientFund, + DomainNameTooLong, + BalanceFreeze, + FailedToGenerateGenesisStateRoot, +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct DomainConfig { + /// A user defined name for this domain, should be a human-readable UTF-8 encoded string. + pub domain_name: Vec, + /// A pointer to the `RuntimeRegistry` entry for this domain. + pub runtime_id: RuntimeId, + /// The max block size for this domain, may not exceed the system-wide `MaxDomainBlockSize` limit. + pub max_block_size: u32, + /// The max block weight for this domain, may not exceed the system-wide `MaxDomainBlockWeight` limit. + pub max_block_weight: Weight, + /// The probability of successful bundle in a slot (active slots coefficient). This defines the + /// expected bundle production rate, must be `> 0` and `≤ 1`. + pub bundle_slot_probability: (u64, u64), + /// The expected number of bundles for a domain block, must be `≥ 1` and `≤ MaxBundlesPerBlock`. + pub target_bundles_per_block: u32, +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct DomainObject { + /// The address of the domain creator, used to validate updating the domain config. + pub owner_account_id: AccountId, + /// The consensus chain block number when the domain first instantiated. + pub created_at: Number, + /// The hash of the genesis execution receipt for this domain. + pub genesis_receipt_hash: ReceiptHash, + /// The domain config. + pub domain_config: DomainConfig, + /// The genesis config of the domain, encoded in json format. + // + /// NOTE: the WASM code in the `system-pallet` genesis config should be empty to avoid + /// redundancy with the `RuntimeRegistry`. Currently, this value only set to `Some` for + /// the genesis domain instance. + pub raw_genesis_config: Option>, +} + +pub(crate) fn can_instantiate_domain( + owner_account_id: &T::AccountId, + domain_config: &DomainConfig, +) -> Result<(), Error> { + ensure!( + domain_config.domain_name.len() as u32 <= T::MaxDomainNameLength::get(), + Error::DomainNameTooLong, + ); + ensure!( + RuntimeRegistry::::contains_key(domain_config.runtime_id), + Error::RuntimeNotFound + ); + ensure!( + domain_config.max_block_size <= T::MaxDomainBlockSize::get(), + Error::ExceedMaxDomainBlockSize + ); + ensure!( + domain_config.max_block_weight.ref_time() <= T::MaxDomainBlockWeight::get().ref_time(), + Error::ExceedMaxDomainBlockWeight + ); + ensure!( + domain_config.target_bundles_per_block != 0 + && domain_config.target_bundles_per_block <= T::MaxBundlesPerBlock::get(), + Error::InvalidBundlesPerBlock + ); + + // `bundle_slot_probability` must be `> 0` and `≤ 1` + let (numerator, denominator) = domain_config.bundle_slot_probability; + ensure!( + numerator != 0 && denominator != 0 && numerator <= denominator, + Error::InvalidSlotProbability + ); + + ensure!( + T::Currency::reducible_balance(owner_account_id, Preservation::Protect, Fortitude::Polite) + >= T::DomainInstantiationDeposit::get(), + Error::InsufficientFund + ); + + Ok(()) +} + +pub(crate) fn do_instantiate_domain( + domain_config: DomainConfig, + owner_account_id: T::AccountId, + created_at: T::BlockNumber, + raw_genesis_config: Option>, +) -> Result { + can_instantiate_domain::(&owner_account_id, &domain_config)?; + + let domain_id = NextDomainId::::get(); + + let genesis_receipt = { + let runtime_obj = RuntimeRegistry::::get(domain_config.runtime_id) + .expect("Runtime object must exist as checked in `can_instantiate_domain`; qed"); + initialize_genesis_receipt::( + domain_id, + runtime_obj.runtime_type, + runtime_obj.code, + raw_genesis_config.clone(), + )? + }; + let genesis_receipt_hash = genesis_receipt.hash(); + + let domain_obj = DomainObject { + owner_account_id: owner_account_id.clone(), + created_at, + genesis_receipt_hash, + domain_config, + raw_genesis_config, + }; + DomainRegistry::::insert(domain_id, domain_obj); + + let next_domain_id = domain_id.checked_add(&1.into()).ok_or(Error::MaxDomainId)?; + NextDomainId::::set(next_domain_id); + + // Lock up fund of the domain instance creator + T::Currency::hold( + &T::HoldIdentifier::domain_instantiation_id(domain_id), + &owner_account_id, + T::DomainInstantiationDeposit::get(), + ) + .map_err(|_| Error::BalanceFreeze)?; + + DomainStakingSummary::::insert( + domain_id, + StakingSummary { + current_epoch_index: 0, + current_total_stake: Zero::zero(), + current_operators: BTreeMap::new(), + next_operators: BTreeSet::new(), + current_epoch_rewards: BTreeMap::new(), + }, + ); + + import_genesis_receipt::(domain_id, genesis_receipt); + + frame_system::Pallet::::deposit_log(DigestItem::domain_instantiation(domain_id)); + + Ok(domain_id) +} + +fn initialize_genesis_receipt( + domain_id: DomainId, + runtime_type: RuntimeType, + runtime_code: Vec, + raw_genesis_config: Option>, +) -> Result, Error> { + let consensus_genesis_hash = frame_system::Pallet::::block_hash(T::BlockNumber::zero()); + let genesis_state_root = generate_genesis_state_root( + domain_id, + DomainInstanceData { + runtime_type, + runtime_code, + raw_genesis_config, + }, + ) + .ok_or(Error::FailedToGenerateGenesisStateRoot)?; + Ok(ExecutionReceiptOf::::genesis( + consensus_genesis_hash, + genesis_state_root.into(), + )) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::pallet::{DomainRegistry, NextDomainId, RuntimeRegistry}; + use crate::runtime_registry::RuntimeObject; + use crate::tests::{new_test_ext, GenesisStateRootGenerater, Test}; + use frame_support::traits::Currency; + use sp_domains::GenesisReceiptExtension; + use sp_std::vec; + use sp_version::RuntimeVersion; + use std::sync::Arc; + + type Balances = pallet_balances::Pallet; + + #[test] + fn test_domain_instantiation() { + let creator = 1u64; + let created_at = 0u64; + // Construct an invalid domain config initially + let mut domain_config = DomainConfig { + domain_name: vec![0; 1024], + runtime_id: 0, + max_block_size: u32::MAX, + max_block_weight: Weight::MAX, + bundle_slot_probability: (0, 0), + target_bundles_per_block: 0, + }; + + let mut ext = new_test_ext(); + ext.register_extension(GenesisReceiptExtension::new(Arc::new( + GenesisStateRootGenerater, + ))); + ext.execute_with(|| { + assert_eq!(NextDomainId::::get(), 0.into()); + + // Failed to instantiate domain due to `domain_name` too long + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::DomainNameTooLong) + ); + // Recorrect `domain_name` + domain_config.domain_name = b"evm-domain".to_vec(); + + // Failed to instantiate domain due to using unregistered runtime id + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::RuntimeNotFound) + ); + // Register runtime id + RuntimeRegistry::::insert( + domain_config.runtime_id, + RuntimeObject { + runtime_name: b"evm".to_vec(), + runtime_type: Default::default(), + runtime_upgrades: 0, + hash: Default::default(), + code: vec![1, 2, 3, 4], + version: RuntimeVersion { + spec_name: "test".into(), + spec_version: 1, + impl_version: 1, + transaction_version: 1, + ..Default::default() + }, + created_at: Default::default(), + updated_at: Default::default(), + }, + ); + + // Failed to instantiate domain due to exceed max domain block size limit + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::ExceedMaxDomainBlockSize) + ); + // Recorrect `max_block_size` + domain_config.max_block_size = 1; + + // Failed to instantiate domain due to exceed max domain block weight limit + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::ExceedMaxDomainBlockWeight) + ); + // Recorrect `max_block_weight` + domain_config.max_block_weight = Weight::from_parts(1, 0); + + // Failed to instantiate domain due to invalid `target_bundles_per_block` + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::InvalidBundlesPerBlock) + ); + domain_config.target_bundles_per_block = u32::MAX; + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::InvalidBundlesPerBlock) + ); + // Recorrect `target_bundles_per_block` + domain_config.target_bundles_per_block = 1; + + // Failed to instantiate domain due to invalid `bundle_slot_probability` + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::InvalidSlotProbability) + ); + domain_config.bundle_slot_probability = (1, 0); + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::InvalidSlotProbability) + ); + domain_config.bundle_slot_probability = (0, 1); + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::InvalidSlotProbability) + ); + domain_config.bundle_slot_probability = (2, 1); + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::InvalidSlotProbability) + ); + // Recorrect `bundle_slot_probability` + domain_config.bundle_slot_probability = (1, 1); + + // Failed to instantiate domain due to creator don't have enough fund + assert_eq!( + do_instantiate_domain::(domain_config.clone(), creator, created_at, None), + Err(Error::InsufficientFund) + ); + // Set enough fund to creator + Balances::make_free_balance_be( + &creator, + ::DomainInstantiationDeposit::get() + + ::ExistentialDeposit::get(), + ); + + // `instantiate_domain` must success now + let domain_id = + do_instantiate_domain::(domain_config.clone(), creator, created_at, None) + .unwrap(); + let domain_obj = DomainRegistry::::get(domain_id).unwrap(); + + assert_eq!(domain_obj.owner_account_id, creator); + assert_eq!(domain_obj.created_at, created_at); + assert_eq!(domain_obj.domain_config, domain_config); + assert_eq!(NextDomainId::::get(), 1.into()); + // Fund locked up thus can't withdraw, and usable balance is zero since ED is 1 + assert_eq!(Balances::usable_balance(creator), Zero::zero()); + + // cannot use the locked funds to create a new domain instance + assert!( + do_instantiate_domain::(domain_config, creator, created_at, None) + == Err(Error::InsufficientFund) + ) + }); + } +} diff --git a/crates/pallet-domains/src/lib.rs b/crates/pallet-domains/src/lib.rs index 1f174fde8f6..0d32a33beb5 100644 --- a/crates/pallet-domains/src/lib.rs +++ b/crates/pallet-domains/src/lib.rs @@ -24,48 +24,257 @@ mod benchmarking; #[cfg(test)] mod tests; +pub mod block_tree; +pub mod domain_registry; +pub mod runtime_registry; +mod staking; +mod staking_epoch; pub mod weights; +use crate::block_tree::verify_execution_receipt; +use crate::staking::{do_nominate_operator, Operator, OperatorStatus}; use codec::{Decode, Encode}; +use frame_support::ensure; +use frame_support::traits::fungible::{Inspect, InspectHold}; use frame_support::traits::Get; use frame_system::offchain::SubmitTransaction; pub use pallet::*; +use scale_info::TypeInfo; use sp_core::H256; -use sp_domains::bundle_election::verify_system_bundle_solution; +use sp_domains::bundle_producer_election::{is_below_threshold, BundleProducerElectionParams}; use sp_domains::fraud_proof::FraudProof; -use sp_domains::merkle_tree::Witness; -use sp_domains::transaction::InvalidTransactionCode; -use sp_domains::{BundleSolution, DomainId, ExecutionReceipt, OpaqueBundle, ProofOfElection}; -use sp_runtime::traits::{BlockNumberProvider, CheckedSub, One, Zero}; -use sp_runtime::transaction_validity::TransactionValidityError; -use sp_std::cmp::Ordering; +use sp_domains::{ + DomainBlockLimit, DomainId, DomainInstanceData, ExecutionReceipt, OpaqueBundle, OperatorId, + OperatorPublicKey, ProofOfElection, RuntimeId, +}; +use sp_runtime::traits::{BlakeTwo256, Hash, Zero}; +use sp_runtime::{RuntimeAppPublic, SaturatedConversion, Saturating}; +use sp_std::boxed::Box; +use sp_std::collections::btree_map::BTreeMap; use sp_std::vec::Vec; +use subspace_core_primitives::U256; + +pub(crate) type BalanceOf = + <::Currency as Inspect<::AccountId>>::Balance; + +pub(crate) type FungibleHoldId = + <::Currency as InspectHold<::AccountId>>::Reason; + +pub(crate) type NominatorId = ::AccountId; + +pub trait HoldIdentifier { + fn staking_pending_deposit(operator_id: OperatorId) -> FungibleHoldId; + fn staking_staked(operator_id: OperatorId) -> FungibleHoldId; + fn staking_pending_unlock(operator_id: OperatorId) -> FungibleHoldId; + fn domain_instantiation_id(domain_id: DomainId) -> FungibleHoldId; +} + +pub type ExecutionReceiptOf = ExecutionReceipt< + ::BlockNumber, + ::Hash, + ::DomainNumber, + ::DomainHash, + BalanceOf, +>; + +pub type OpaqueBundleOf = OpaqueBundle< + ::BlockNumber, + ::Hash, + ::DomainNumber, + ::DomainHash, + BalanceOf, +>; + +/// Parameters used to verify proof of election. +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub(crate) struct ElectionVerificationParams { + operators: BTreeMap, + total_domain_stake: Balance, +} #[frame_support::pallet] mod pallet { + #![allow(clippy::large_enum_variant)] + + use crate::block_tree::{ + execution_receipt_type, process_execution_receipt, DomainBlock, Error as BlockTreeError, + ReceiptType, + }; + use crate::domain_registry::{ + do_instantiate_domain, DomainConfig, DomainObject, Error as DomainRegistryError, + }; + use crate::runtime_registry::{ + do_register_runtime, do_schedule_runtime_upgrade, do_upgrade_runtimes, + register_runtime_at_genesis, Error as RuntimeRegistryError, RuntimeObject, + ScheduledRuntimeUpgrade, + }; + use crate::staking::{ + do_auto_stake_block_rewards, do_deregister_operator, do_nominate_operator, + do_register_operator, do_reward_operators, do_switch_operator_domain, do_withdraw_stake, + Error as StakingError, Nominator, Operator, OperatorConfig, StakingSummary, Withdraw, + }; + use crate::staking_epoch::{ + do_finalize_domain_current_epoch, do_unlock_pending_withdrawals, + Error as StakingEpochError, PendingNominatorUnlock, PendingOperatorSlashInfo, + }; use crate::weights::WeightInfo; - use frame_support::pallet_prelude::*; + use crate::{ + BalanceOf, ElectionVerificationParams, HoldIdentifier, NominatorId, OpaqueBundleOf, + }; + use codec::FullCodec; + use frame_support::pallet_prelude::{StorageMap, *}; + use frame_support::traits::fungible::{InspectHold, Mutate, MutateHold}; use frame_support::weights::Weight; - use frame_support::PalletError; + use frame_support::{Identity, PalletError}; use frame_system::pallet_prelude::*; - use pallet_settlement::{Error as SettlementError, FraudProofError}; use sp_core::H256; use sp_domains::fraud_proof::FraudProof; use sp_domains::transaction::InvalidTransactionCode; - use sp_domains::{DomainId, ExecutorPublicKey, OpaqueBundle}; - use sp_runtime::traits::{One, Zero}; + use sp_domains::{ + BundleDigest, DomainId, EpochIndex, GenesisDomain, OperatorId, ReceiptHash, RuntimeId, + RuntimeType, + }; + use sp_runtime::traits::{ + AtLeast32BitUnsigned, BlockNumberProvider, Bounded, CheckEqual, CheckedAdd, MaybeDisplay, + One, SimpleBitOps, Zero, + }; + use sp_runtime::SaturatedConversion; + use sp_std::boxed::Box; + use sp_std::collections::btree_map::BTreeMap; + use sp_std::collections::btree_set::BTreeSet; use sp_std::fmt::Debug; + use sp_std::vec; use sp_std::vec::Vec; + use subspace_core_primitives::U256; #[pallet::config] - pub trait Config: frame_system::Config + pallet_settlement::Config { + pub trait Config: frame_system::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// Domain block number type. + type DomainNumber: Parameter + + Member + + MaybeSerializeDeserialize + + Debug + + MaybeDisplay + + AtLeast32BitUnsigned + + Default + + Bounded + + Copy + + sp_std::hash::Hash + + sp_std::str::FromStr + + MaxEncodedLen + + TypeInfo; + + /// Domain block hash type. + type DomainHash: Parameter + + Member + + MaybeSerializeDeserialize + + Debug + + MaybeDisplay + + SimpleBitOps + + Ord + + Default + + Copy + + CheckEqual + + sp_std::hash::Hash + + AsRef<[u8]> + + AsMut<[u8]> + + MaxEncodedLen + + Into + + From; + /// Same with `pallet_subspace::Config::ConfirmationDepthK`. + #[pallet::constant] type ConfirmationDepthK: Get; + /// Delay before a domain runtime is upgraded. + #[pallet::constant] + type DomainRuntimeUpgradeDelay: Get; + + /// Currency type used by the domains for staking and other currency related stuff. + type Currency: Mutate + + InspectHold + + MutateHold; + + /// Type representing the shares in the staking protocol. + type Share: Parameter + + Member + + MaybeSerializeDeserialize + + Debug + + AtLeast32BitUnsigned + + FullCodec + + Copy + + Default + + TypeInfo + + MaxEncodedLen + + IsType>; + + /// A variation of the Identifier used for holding the funds used for staking and domains. + type HoldIdentifier: HoldIdentifier; + + /// The block tree pruning depth, its value should <= `BlockHashCount` because we + /// need the consensus block hash to verify execution receipt, which is used to + /// construct the node of the block tree. + /// + /// TODO: `BlockTreePruningDepth` <= `BlockHashCount` is not enough to guarantee the consensus block + /// hash must exists while verifying receipt because the domain block is not mapping to the consensus + /// block one by one, we need to either store the consensus block hash in runtime manually or store + /// the consensus block hash in the client side and use host function to get them in runtime. + #[pallet::constant] + type BlockTreePruningDepth: Get; + + /// The maximum block size limit for all domain. + #[pallet::constant] + type MaxDomainBlockSize: Get; + + /// The maximum block weight limit for all domain. + #[pallet::constant] + type MaxDomainBlockWeight: Get; + + /// The maximum bundle per block limit for all domain. + #[pallet::constant] + type MaxBundlesPerBlock: Get; + + /// The maximum domain name length limit for all domain. + #[pallet::constant] + type MaxDomainNameLength: Get; + + /// The amount of fund to be locked up for the domain instance creator. + #[pallet::constant] + type DomainInstantiationDeposit: Get>; + /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; + + /// Initial domain tx range value. + #[pallet::constant] + type InitialDomainTxRange: Get; + + /// Domain tx range is adjusted after every DomainTxRangeAdjustmentInterval blocks. + #[pallet::constant] + type DomainTxRangeAdjustmentInterval: Get; + + /// Minimum operator stake required to become operator of a domain. + #[pallet::constant] + type MinOperatorStake: Get>; + + /// Minimum number of blocks after which any finalized withdrawals are released to nominators. + #[pallet::constant] + type StakeWithdrawalLockingPeriod: Get; + + /// Domain epoch transition interval + #[pallet::constant] + type StakeEpochDuration: Get; + + /// Treasury account. + #[pallet::constant] + type TreasuryAccount: Get; + + /// A fixed domain block reward. + // TODO: remove once we have operator rewards on client side is available + #[pallet::constant] + type DomainBlockReward: Get>; } #[pallet::pallet] @@ -74,76 +283,292 @@ mod pallet { /// Bundles submitted successfully in current block. #[pallet::storage] - pub(super) type SuccessfulBundles = StorageValue<_, Vec, ValueQuery>; + pub(super) type SuccessfulBundles = StorageMap<_, Identity, DomainId, Vec, ValueQuery>; + + /// Stores the next runtime id. + #[pallet::storage] + pub(super) type NextRuntimeId = StorageValue<_, RuntimeId, ValueQuery>; + + #[pallet::storage] + pub(super) type RuntimeRegistry = + StorageMap<_, Identity, RuntimeId, RuntimeObject, OptionQuery>; + + #[pallet::storage] + pub(super) type ScheduledRuntimeUpgrades = StorageDoubleMap< + _, + Identity, + T::BlockNumber, + Identity, + RuntimeId, + ScheduledRuntimeUpgrade, + OptionQuery, + >; + + #[pallet::storage] + pub(super) type NextOperatorId = StorageValue<_, OperatorId, ValueQuery>; + + #[pallet::storage] + pub(super) type OperatorIdOwner = + StorageMap<_, Identity, OperatorId, T::AccountId, OptionQuery>; + + #[pallet::storage] + pub(super) type DomainStakingSummary = + StorageMap<_, Identity, DomainId, StakingSummary>, OptionQuery>; + + /// List of all registered operators and their configuration. + #[pallet::storage] + pub(super) type Operators = + StorageMap<_, Identity, OperatorId, Operator, T::Share>, OptionQuery>; + + /// Temporary hold of all the operators who decided to switch to another domain. + /// Once epoch is complete, these operators are added to new domains under next_operators. + #[pallet::storage] + pub(super) type PendingOperatorSwitches = + StorageMap<_, Identity, DomainId, BTreeSet, OptionQuery>; + + /// List of all current epoch's nominators and their shares under a given operator, + #[pallet::storage] + pub(super) type Nominators = StorageDoubleMap< + _, + Identity, + OperatorId, + Identity, + NominatorId, + Nominator, + OptionQuery, + >; + + /// Deposits initiated a nominator under this operator. + /// Will be stored temporarily until the current epoch is complete. + /// Once, epoch is complete, these deposits are staked beginning next epoch. + #[pallet::storage] + pub(super) type PendingDeposits = StorageDoubleMap< + _, + Identity, + OperatorId, + Identity, + NominatorId, + BalanceOf, + OptionQuery, + >; + + /// Withdrawals initiated a nominator under this operator. + /// Will be stored temporarily until the current epoch is complete. + /// Once, epoch is complete, these will be moved to PendingNominatorUnlocks. + #[pallet::storage] + pub(super) type PendingWithdrawals = StorageDoubleMap< + _, + Identity, + OperatorId, + Identity, + NominatorId, + Withdraw>, + OptionQuery, + >; + + /// Operators who chose to deregister from a domain. + /// Stored here temporarily until domain epoch is complete. + #[pallet::storage] + pub(super) type PendingOperatorDeregistrations = + StorageMap<_, Identity, DomainId, BTreeSet, OptionQuery>; + + /// Stores a list of operators who are unlocking in the coming blocks. + /// The operator will be removed when the wait period is over + /// or when the operator is slashed. + #[pallet::storage] + pub(super) type PendingOperatorUnlocks = + StorageValue<_, BTreeSet, ValueQuery>; + + /// All the pending unlocks for the nominators. + /// We use this storage to fetch all the pending unlocks under a operator pool at the time of slashing. + #[pallet::storage] + pub(super) type PendingNominatorUnlocks = StorageDoubleMap< + _, + Identity, + OperatorId, + Identity, + T::DomainNumber, + Vec, BalanceOf>>, + OptionQuery, + >; + + /// A list of operators that are either unregistering or one more of the nominators + /// are withdrawing some staked funds. + #[pallet::storage] + pub(super) type PendingUnlocks = + StorageMap<_, Identity, (DomainId, T::DomainNumber), BTreeSet, OptionQuery>; + + /// A list operators who were slashed during the current epoch associated with the domain. + /// When the epoch for a given domain is complete, operator total stake is moved to treasury and + /// then deleted. + #[pallet::storage] + pub(super) type PendingSlashes = StorageMap< + _, + Identity, + DomainId, + BTreeMap, BalanceOf>>, + OptionQuery, + >; + + /// Stores the next domain id. + #[pallet::storage] + pub(super) type NextDomainId = StorageValue<_, DomainId, ValueQuery>; + + /// The domain registry + #[pallet::storage] + pub(super) type DomainRegistry = + StorageMap<_, Identity, DomainId, DomainObject, OptionQuery>; + + /// The domain block tree, map (`domain_id`, `domain_block_number`) to the hash of a domain blocks, + /// which can be used get the domain block in `DomainBlocks` + #[pallet::storage] + pub(super) type BlockTree = StorageDoubleMap< + _, + Identity, + DomainId, + Identity, + T::DomainNumber, + BTreeSet, + ValueQuery, + >; + + /// Mapping of domain block hash to domain block + #[pallet::storage] + pub(super) type DomainBlocks = StorageMap< + _, + Identity, + ReceiptHash, + DomainBlock>, + OptionQuery, + >; + + /// The head receipt number of each domain + #[pallet::storage] + pub(super) type HeadReceiptNumber = + StorageMap<_, Identity, DomainId, T::DomainNumber, ValueQuery>; + + /// A set of `BundleDigest` from all bundles that successfully submitted to the consensus block, + /// these bundles will be used to construct the domain block and `ExecutionInbox` is used to: + /// + /// 1. Ensure subsequent ERs of that domain block include all pre-validated extrinsic bundles + /// 2. Index the `InboxedBundle` and pruned its value when the corresponding `ExecutionInbox` is pruned + #[pallet::storage] + pub type ExecutionInbox = StorageNMap< + _, + ( + NMapKey, + NMapKey, + NMapKey, + ), + Vec, + ValueQuery, + >; + + /// A mapping of `bundle_header_hash` -> `bundle_author` for all the successfully submitted bundles of + /// the last `BlockTreePruningDepth` domain blocks. Used to verify the invalid bundle fraud proof and + /// slash malicious operator who have submitted invalid bundle. + #[pallet::storage] + pub(super) type InboxedBundle = + StorageMap<_, Identity, H256, OperatorId, OptionQuery>; + + /// The block number of the best domain block, increase by one when the first bundle of the domain is + /// successfully submitted to current consensus block, which mean a new domain block with this block + /// number will be produce. Used as a pointer in `ExecutionInbox` to identify the current under building + /// domain block, also used as a mapping of consensus block number to domain block number. + #[pallet::storage] + pub(super) type HeadDomainNumber = + StorageMap<_, Identity, DomainId, T::DomainNumber, ValueQuery>; + + /// The genesis domian that scheduled to register at block #1, should be removed once + /// https://github.com/paritytech/substrate/issues/14541 is resolved. + #[pallet::storage] + type PendingGenesisDomain = + StorageValue<_, GenesisDomain, OptionQuery>; + + /// A temporary storage to hold any previous epoch details for a given domain + /// if the epoch transitioned in this block so that all the submitted bundles + /// within this block are verified. + /// The storage is cleared on block finalization. + #[pallet::storage] + pub(super) type LastEpochStakingDistribution = + StorageMap<_, Identity, DomainId, ElectionVerificationParams>, OptionQuery>; + + /// A preferred Operator for a given Farmer, enabling automatic staking of block rewards. + /// For the auto-staking to succeed, the Farmer must also be a Nominator of the preferred Operator. + #[pallet::storage] + pub(super) type PreferredOperator = + StorageMap<_, Identity, NominatorId, OperatorId, OptionQuery>; #[derive(TypeInfo, Encode, Decode, PalletError, Debug, PartialEq)] pub enum BundleError { - /// The signer of bundle is unexpected. - UnexpectedSigner, - /// Invalid bundle signature. - BadSignature, - /// Invalid vrf proof. - BadVrfProof, - /// State of a system domain block is missing. - StateRootNotFound, - /// Invalid state root in the proof of election. - BadStateRoot, - /// The type of state root is not H256. - StateRootNotH256, - /// Invalid system bundle election solution. - BadElectionSolution, - /// An invalid execution receipt found in the bundle. - Receipt(ExecutionReceiptError), + /// Can not find the operator for given operator id. + InvalidOperatorId, + /// Invalid signature on the bundle header. + BadBundleSignature, + /// Invalid vrf signature in the proof of election. + BadVrfSignature, + /// Can not find the domain for given domain id. + InvalidDomainId, + /// Operator is not allowed to produce bundles in current epoch. + BadOperator, + /// Failed to pass the threshold check. + ThresholdUnsatisfied, /// The Bundle is created too long ago. StaleBundle, - /// Bundle was created on an unknown primary block (probably a fork block). - UnknownBlock, + /// An invalid execution receipt found in the bundle. + Receipt(BlockTreeError), + /// Bundle size exceed the max bundle size limit in the domain config + BundleTooLarge, + // Bundle with an invalid extrinsic root + InvalidExtrinsicRoot, + /// This bundle duplicated with an already submitted bundle + DuplicatedBundle, } - impl From for Error { - #[inline] - fn from(e: BundleError) -> Self { - Self::Bundle(e) + impl From for Error { + fn from(err: RuntimeRegistryError) -> Self { + Error::RuntimeRegistry(err) } } - #[derive(TypeInfo, Encode, Decode, PalletError, Debug, PartialEq)] - pub enum ExecutionReceiptError { - /// The parent execution receipt is unknown. - MissingParent, - /// The execution receipt has been pruned. - Pruned, - /// The execution receipt points to a block unknown to the history. - UnknownBlock, - /// The execution receipt is too far in the future. - TooFarInFuture, - /// Receipts are not consecutive. - Inconsecutive, - /// Receipts in a bundle can not be empty. - Empty, - } - - impl From for Error { - #[inline] - fn from(error: SettlementError) -> Self { - match error { - SettlementError::MissingParent => { - Self::Bundle(BundleError::Receipt(ExecutionReceiptError::MissingParent)) - } - SettlementError::FraudProof(err) => Self::FraudProof(err), - SettlementError::UnavailablePrimaryBlockHash => Self::UnavailablePrimaryBlockHash, - } + impl From for Error { + fn from(err: StakingError) -> Self { + Error::Staking(err) + } + } + + impl From for Error { + fn from(err: StakingEpochError) -> Self { + Error::StakingEpoch(err) + } + } + + impl From for Error { + fn from(err: DomainRegistryError) -> Self { + Error::DomainRegistry(err) + } + } + + impl From for Error { + fn from(err: BlockTreeError) -> Self { + Error::BlockTree(err) } } #[pallet::error] pub enum Error { - /// Can not find the block hash of given primary block number. - UnavailablePrimaryBlockHash, - /// Invalid bundle. - Bundle(BundleError), /// Invalid fraud proof. - FraudProof(FraudProofError), + FraudProof, + /// Runtime registry specific errors + RuntimeRegistry(RuntimeRegistryError), + /// Staking related errors. + Staking(StakingError), + /// Staking epoch specific errors. + StakingEpoch(StakingEpochError), + /// Domain registry specific errors + DomainRegistry(DomainRegistryError), + /// Block tree specific errors + BlockTree(BlockTreeError), } #[pallet::event] @@ -153,44 +578,184 @@ mod pallet { BundleStored { domain_id: DomainId, bundle_hash: H256, - bundle_author: ExecutorPublicKey, + bundle_author: OperatorId, + }, + DomainRuntimeCreated { + runtime_id: RuntimeId, + runtime_type: RuntimeType, + }, + DomainRuntimeUpgradeScheduled { + runtime_id: RuntimeId, + scheduled_at: T::BlockNumber, + }, + DomainRuntimeUpgraded { + runtime_id: RuntimeId, + }, + OperatorRegistered { + operator_id: OperatorId, + domain_id: DomainId, + }, + OperatorNominated { + operator_id: OperatorId, + nominator_id: NominatorId, + }, + DomainInstantiated { + domain_id: DomainId, + }, + OperatorSwitchedDomain { + old_domain_id: DomainId, + new_domain_id: DomainId, + }, + OperatorDeregistered { + operator_id: OperatorId, + }, + WithdrewStake { + operator_id: OperatorId, + nominator_id: NominatorId, + }, + PreferredOperator { + operator_id: OperatorId, + nominator_id: NominatorId, + }, + OperatorRewarded { + operator_id: OperatorId, + reward: BalanceOf, + }, + DomainEpochCompleted { + domain_id: DomainId, + completed_epoch_index: EpochIndex, }, } + /// Per-domain state for tx range calculation. + #[derive(Debug, Default, Decode, Encode, TypeInfo, PartialEq, Eq)] + pub struct TxRangeState { + /// Current tx range. + pub tx_range: U256, + + /// Blocks in the current adjustment interval. + pub interval_blocks: u64, + + /// Bundles in the current adjustment interval. + pub interval_bundles: u64, + } + + impl TxRangeState { + /// Called when a bundle is added to the current block. + pub fn on_bundle(&mut self) { + self.interval_bundles += 1; + } + } + + #[pallet::storage] + pub(super) type DomainTxRangeState = + StorageMap<_, Identity, DomainId, TxRangeState, OptionQuery>; + #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight( - if opaque_bundle.domain_id().is_system() { - T::WeightInfo::submit_system_bundle() - } else { - T::WeightInfo::submit_core_bundle() - } - )] + #[pallet::weight(Weight::from_all(10_000))] + // TODO: proper benchmark pub fn submit_bundle( origin: OriginFor, - opaque_bundle: OpaqueBundle, + opaque_bundle: OpaqueBundleOf, ) -> DispatchResult { ensure_none(origin)?; log::trace!(target: "runtime::domains", "Processing bundle: {opaque_bundle:?}"); let domain_id = opaque_bundle.domain_id(); - - // Only process the system domain receipts. - if domain_id.is_system() { - pallet_settlement::Pallet::::track_receipt(domain_id, &opaque_bundle.receipt) + let bundle_hash = opaque_bundle.hash(); + let bundle_header_hash = opaque_bundle.sealed_header.pre_hash(); + let extrinsics_root = opaque_bundle.extrinsics_root(); + let operator_id = opaque_bundle.operator_id(); + let receipt = opaque_bundle.into_receipt(); + + match execution_receipt_type::(domain_id, &receipt) { + // The stale receipt should not be further processed, but we still track them for purposes + // of measuring the bundle production rate. + ReceiptType::Stale => { + Self::note_domain_bundle(domain_id); + return Ok(()); + } + ReceiptType::Rejected(rejected_receipt_type) => { + return Err(Error::::BlockTree(rejected_receipt_type.into()).into()); + } + // Add the exeuctione receipt to the block tree + ReceiptType::Accepted(accepted_receipt_type) => { + let maybe_pruned_domain_block_info = process_execution_receipt::( + domain_id, + operator_id, + receipt, + accepted_receipt_type, + ) .map_err(Error::::from)?; + + // if any domain block is pruned, then we have a new head added + // so distribute the operator rewards and, if required, do epoch transition as well. + if let Some(pruned_block_info) = maybe_pruned_domain_block_info { + do_reward_operators::( + domain_id, + pruned_block_info.operator_ids.into_iter(), + T::DomainBlockReward::get(), + ) + .map_err(Error::::from)?; + + if pruned_block_info.domain_block_number % T::StakeEpochDuration::get() + == Zero::zero() + { + let completed_epoch_index = do_finalize_domain_current_epoch::( + domain_id, + pruned_block_info.domain_block_number, + ) + .map_err(Error::::from)?; + + Self::deposit_event(Event::DomainEpochCompleted { + domain_id, + completed_epoch_index, + }); + } + + do_unlock_pending_withdrawals::( + domain_id, + pruned_block_info.domain_block_number, + ) + .map_err(Error::::from)?; + } + } } - let bundle_hash = opaque_bundle.hash(); + // `SuccessfulBundles` is empty means this is the first accepted bundle for this domain in this + // consensus block, which also mean a domain block will be produced thus update `HeadDomainNumber` + // to this domain block's block number. + if SuccessfulBundles::::get(domain_id).is_empty() { + let next_number = HeadDomainNumber::::get(domain_id) + .checked_add(&One::one()) + .ok_or::>(BlockTreeError::MaxHeadDomainNumber.into())?; + HeadDomainNumber::::set(domain_id, next_number); + } + + // Put the `extrinsics_root` to the inbox of the current under building domain block + let head_domain_number = HeadDomainNumber::::get(domain_id); + let consensus_block_number = frame_system::Pallet::::current_block_number(); + ExecutionInbox::::append( + (domain_id, head_domain_number, consensus_block_number), + BundleDigest { + header_hash: bundle_header_hash, + extrinsics_root, + }, + ); + + InboxedBundle::::insert(bundle_header_hash, operator_id); - SuccessfulBundles::::append(bundle_hash); + SuccessfulBundles::::append(domain_id, bundle_hash); + + Self::note_domain_bundle(domain_id); Self::deposit_event(Event::BundleStored { domain_id, bundle_hash, - bundle_author: opaque_bundle.into_executor_public_key(), + bundle_author: operator_id, }); Ok(()) @@ -198,7 +763,7 @@ mod pallet { #[pallet::call_index(1)] #[pallet::weight( - match fraud_proof { + match fraud_proof.as_ref() { FraudProof::InvalidStateTransition(..) => ( T::WeightInfo::submit_system_domain_invalid_state_transition_proof(), Pays::No @@ -209,45 +774,291 @@ mod pallet { )] pub fn submit_fraud_proof( origin: OriginFor, - fraud_proof: FraudProof, + fraud_proof: Box>, ) -> DispatchResult { ensure_none(origin)?; log::trace!(target: "runtime::domains", "Processing fraud proof: {fraud_proof:?}"); - if fraud_proof.domain_id().is_system() { - pallet_settlement::Pallet::::process_fraud_proof(fraud_proof) + // TODO: Implement fraud proof processing. + + Ok(()) + } + + #[pallet::call_index(2)] + #[pallet::weight((Weight::from_all(10_000), Pays::Yes))] + // TODO: proper benchmark + pub fn register_domain_runtime( + origin: OriginFor, + runtime_name: Vec, + runtime_type: RuntimeType, + code: Vec, + ) -> DispatchResult { + ensure_root(origin)?; + + let block_number = frame_system::Pallet::::current_block_number(); + let runtime_id = + do_register_runtime::(runtime_name, runtime_type.clone(), code, block_number) .map_err(Error::::from)?; - } + + Self::deposit_event(Event::DomainRuntimeCreated { + runtime_id, + runtime_type, + }); + + Ok(()) + } + + #[pallet::call_index(3)] + #[pallet::weight((Weight::from_all(10_000), Pays::Yes))] + // TODO: proper benchmark + pub fn upgrade_domain_runtime( + origin: OriginFor, + runtime_id: RuntimeId, + code: Vec, + ) -> DispatchResult { + ensure_root(origin)?; + + let block_number = frame_system::Pallet::::current_block_number(); + let scheduled_at = do_schedule_runtime_upgrade::(runtime_id, code, block_number) + .map_err(Error::::from)?; + + Self::deposit_event(Event::DomainRuntimeUpgradeScheduled { + runtime_id, + scheduled_at, + }); + + Ok(()) + } + + #[pallet::call_index(4)] + #[pallet::weight((Weight::from_all(10_000), Pays::Yes))] + // TODO: proper benchmark + pub fn register_operator( + origin: OriginFor, + domain_id: DomainId, + amount: BalanceOf, + config: OperatorConfig>, + ) -> DispatchResult { + let owner = ensure_signed(origin)?; + + let operator_id = do_register_operator::(owner, domain_id, amount, config) + .map_err(Error::::from)?; + Self::deposit_event(Event::OperatorRegistered { + operator_id, + domain_id, + }); + + Ok(()) + } + + #[pallet::call_index(5)] + #[pallet::weight((Weight::from_all(10_000), Pays::Yes))] + // TODO: proper benchmark + pub fn nominate_operator( + origin: OriginFor, + operator_id: OperatorId, + amount: BalanceOf, + ) -> DispatchResult { + let nominator_id = ensure_signed(origin)?; + + do_nominate_operator::(operator_id, nominator_id.clone(), amount) + .map_err(Error::::from)?; + + Self::deposit_event(Event::OperatorNominated { + operator_id, + nominator_id, + }); + + Ok(()) + } + + #[pallet::call_index(6)] + #[pallet::weight((Weight::from_all(10_000), Pays::Yes))] + // TODO: proper benchmark + pub fn instantiate_domain( + origin: OriginFor, + domain_config: DomainConfig, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + let created_at = frame_system::Pallet::::current_block_number(); + + let domain_id = do_instantiate_domain::(domain_config, who, created_at, None) + .map_err(Error::::from)?; + + Self::deposit_event(Event::DomainInstantiated { domain_id }); + + Ok(()) + } + + #[pallet::call_index(7)] + #[pallet::weight((Weight::from_all(10_000), Pays::Yes))] + // TODO: proper benchmark + pub fn switch_domain( + origin: OriginFor, + operator_id: OperatorId, + new_domain_id: DomainId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + let old_domain_id = do_switch_operator_domain::(who, operator_id, new_domain_id) + .map_err(Error::::from)?; + + Self::deposit_event(Event::OperatorSwitchedDomain { + old_domain_id, + new_domain_id, + }); Ok(()) } + + #[pallet::call_index(8)] + #[pallet::weight((Weight::from_all(10_000), Pays::Yes))] + // TODO: proper benchmark + pub fn deregister_operator( + origin: OriginFor, + operator_id: OperatorId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + do_deregister_operator::(who, operator_id).map_err(Error::::from)?; + + Self::deposit_event(Event::OperatorDeregistered { operator_id }); + + Ok(()) + } + + #[pallet::call_index(9)] + #[pallet::weight((Weight::from_all(10_000), Pays::Yes))] + // TODO: proper benchmark + pub fn withdraw_stake( + origin: OriginFor, + operator_id: OperatorId, + withdraw: Withdraw>, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + do_withdraw_stake::(operator_id, who.clone(), withdraw).map_err(Error::::from)?; + + Self::deposit_event(Event::WithdrewStake { + operator_id, + nominator_id: who, + }); + + Ok(()) + } + + #[pallet::call_index(10)] + #[pallet::weight((Weight::from_all(10_000), Pays::Yes))] + // TODO: proper benchmark + pub fn auto_stake_block_rewards( + origin: OriginFor, + operator_id: OperatorId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + do_auto_stake_block_rewards::(who.clone(), operator_id).map_err(Error::::from)?; + + Self::deposit_event(Event::PreferredOperator { + operator_id, + nominator_id: who, + }); + + Ok(()) + } + } + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub genesis_domain: Option>, + } + + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + genesis_domain: None, + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + // Delay the genesis domain register to block #1 due to the required `GenesisReceiptExtension` is not + // registered during genesis storage build, remove once https://github.com/paritytech/substrate/issues/14541 + // is resolved. + if let Some(genesis_domain) = &self.genesis_domain { + PendingGenesisDomain::::set(Some(genesis_domain.clone())); + } + } } #[pallet::hooks] + // TODO: proper benchmark impl Hooks for Pallet { fn on_initialize(block_number: T::BlockNumber) -> Weight { - let parent_number = block_number - One::one(); - let parent_hash = frame_system::Pallet::::block_hash(parent_number); - - pallet_settlement::PrimaryBlockHash::::insert( - DomainId::SYSTEM, - parent_number, - parent_hash, - ); + if block_number.is_one() { + if let Some(genesis_domain) = PendingGenesisDomain::::take() { + // Register the genesis domain runtime + let runtime_id = register_runtime_at_genesis::( + genesis_domain.runtime_name, + genesis_domain.runtime_type, + genesis_domain.runtime_version, + genesis_domain.code, + One::one(), + ) + .expect("Genesis runtime registration must always succeed"); + + // Instantiate the genesis domain + let domain_config = DomainConfig { + domain_name: genesis_domain.domain_name, + runtime_id, + max_block_size: genesis_domain.max_block_size, + max_block_weight: genesis_domain.max_block_weight, + bundle_slot_probability: genesis_domain.bundle_slot_probability, + target_bundles_per_block: genesis_domain.target_bundles_per_block, + }; + let domain_owner = genesis_domain.owner_account_id; + let domain_id = do_instantiate_domain::( + domain_config, + domain_owner.clone(), + One::one(), + Some(genesis_domain.raw_genesis_config), + ) + .expect("Genesis domain instantiation must always succeed"); + + // Register domain_owner as the genesis operator. + let operator_config = OperatorConfig { + signing_key: genesis_domain.signing_key.clone(), + minimum_nominator_stake: genesis_domain + .minimum_nominator_stake + .saturated_into(), + nomination_tax: genesis_domain.nomination_tax, + }; + let operator_stake = T::MinOperatorStake::get(); + do_register_operator::( + domain_owner, + domain_id, + operator_stake, + operator_config, + ) + .expect("Genesis operator registration must succeed"); - // The genesis block hash is not finalized until the genesis block building is done, - // hence the genesis receipt is initialized after the genesis building. - if parent_number.is_zero() { - pallet_settlement::Pallet::::initialize_genesis_receipt( - DomainId::SYSTEM, - parent_hash, - ); + do_finalize_domain_current_epoch::(domain_id, One::one()) + .expect("Genesis epoch must succeed"); + } } - SuccessfulBundles::::kill(); + do_upgrade_runtimes::(block_number); + + let _ = SuccessfulBundles::::clear(u32::MAX, None); + + Weight::zero() + } - T::DbWeight::get().writes(2) + fn on_finalize(_: T::BlockNumber) { + let _ = LastEpochStakingDistribution::::clear(u32::MAX, None); + Self::update_domain_tx_range(); } } @@ -267,22 +1078,9 @@ mod pallet { type Call = Call; fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { match call { - Call::submit_bundle { opaque_bundle } => { - Self::pre_dispatch_submit_bundle(opaque_bundle) - } - Call::submit_fraud_proof { fraud_proof } => { - if !fraud_proof.domain_id().is_system() { - log::debug!( - target: "runtime::domains", - "Wrong fraud proof, expected system domain fraud proof but got: {fraud_proof:?}", - ); - Err(TransactionValidityError::Invalid( - InvalidTransactionCode::FraudProof.into(), - )) - } else { - Ok(()) - } - } + Call::submit_bundle { opaque_bundle } => Self::validate_bundle(opaque_bundle) + .map_err(|_| InvalidTransaction::Call.into()), + Call::submit_fraud_proof { fraud_proof: _ } => Ok(()), _ => Err(InvalidTransaction::Call.into()), } } @@ -312,22 +1110,7 @@ mod pallet { .build() } Call::submit_fraud_proof { fraud_proof } => { - if !fraud_proof.domain_id().is_system() { - log::debug!( - target: "runtime::domains", - "Wrong fraud proof, expected system domain fraud proof but got: {fraud_proof:?}", - ); - return InvalidTransactionCode::FraudProof.into(); - } - if let Err(e) = - pallet_settlement::Pallet::::validate_fraud_proof(fraud_proof) - { - log::debug!( - target: "runtime::domains", - "Bad fraud proof: {fraud_proof:?}, error: {e:?}", - ); - return InvalidTransactionCode::FraudProof.into(); - } + // TODO: Validate fraud proof // TODO: proper tag value. unsigned_validity("SubspaceSubmitFraudProof", fraud_proof) @@ -340,279 +1123,329 @@ mod pallet { } impl Pallet { - pub fn successful_bundles() -> Vec { - SuccessfulBundles::::get() + pub fn successful_bundles(domain_id: DomainId) -> Vec { + SuccessfulBundles::::get(domain_id) } - /// Returns the block number of the latest receipt. - pub fn head_receipt_number() -> T::BlockNumber { - pallet_settlement::Pallet::::head_receipt_number(DomainId::SYSTEM) + pub fn domain_runtime_code(domain_id: DomainId) -> Option> { + RuntimeRegistry::::get(Self::runtime_id(domain_id)?) + .map(|runtime_object| runtime_object.code) } - /// Returns the block number of the oldest receipt still being tracked in the state. - pub fn oldest_receipt_number() -> T::BlockNumber { - pallet_settlement::Pallet::::oldest_receipt_number(DomainId::SYSTEM) + pub fn runtime_id(domain_id: DomainId) -> Option { + DomainRegistry::::get(domain_id) + .map(|domain_object| domain_object.domain_config.runtime_id) } - fn pre_dispatch_submit_bundle( - opaque_bundle: &OpaqueBundle, - ) -> Result<(), TransactionValidityError> { - if !opaque_bundle.domain_id().is_system() { - return Ok(()); - } + pub fn domain_instance_data( + domain_id: DomainId, + ) -> Option<(DomainInstanceData, T::BlockNumber)> { + let domain_obj = DomainRegistry::::get(domain_id)?; + let (runtime_type, runtime_code) = + RuntimeRegistry::::get(domain_obj.domain_config.runtime_id) + .map(|runtime_object| (runtime_object.runtime_type, runtime_object.code))?; + Some(( + DomainInstanceData { + runtime_type, + runtime_code, + raw_genesis_config: domain_obj.raw_genesis_config, + }, + domain_obj.created_at, + )) + } - let receipt = &opaque_bundle.receipt; - let oldest_receipt_number = Self::oldest_receipt_number(); - let next_head_receipt_number = Self::head_receipt_number() + One::one(); - let primary_number = receipt.primary_number; + pub fn genesis_state_root(domain_id: DomainId) -> Option { + BlockTree::::get(domain_id, T::DomainNumber::zero()) + .first() + .and_then(DomainBlocks::::get) + .map(|block| block.execution_receipt.final_state_root.into()) + } - // Ignore the receipt if it has already been pruned. - if primary_number < oldest_receipt_number { - return Ok(()); - } + /// Returns the tx range for the domain. + pub fn domain_tx_range(domain_id: DomainId) -> U256 { + DomainTxRangeState::::try_get(domain_id) + .map(|state| state.tx_range) + .ok() + .unwrap_or_else(Self::initial_tx_range) + } - // TODO: check if the receipt extend the receipt chain or add confirmations to the head receipt. - match primary_number.cmp(&next_head_receipt_number) { - // Missing receipt. - Ordering::Greater => { - return Err(TransactionValidityError::Invalid( - InvalidTransactionCode::ExecutionReceipt.into(), - )); - } - // Non-best receipt or new best receipt. - Ordering::Less | Ordering::Equal => { - if !pallet_settlement::Pallet::::point_to_valid_primary_block( - DomainId::SYSTEM, - receipt, - ) { - log::debug!( - target: "runtime::domains", - "Invalid primary hash for #{primary_number:?} in receipt, \ - expected: {:?}, got: {:?}", - pallet_settlement::PrimaryBlockHash::::get(DomainId::SYSTEM, primary_number), - receipt.primary_hash, - ); - return Err(TransactionValidityError::Invalid( - InvalidTransactionCode::ExecutionReceipt.into(), - )); - } - } + pub fn bundle_producer_election_params( + domain_id: DomainId, + ) -> Option>> { + match ( + DomainRegistry::::get(domain_id), + DomainStakingSummary::::get(domain_id), + ) { + (Some(domain_object), Some(stake_summary)) => Some(BundleProducerElectionParams { + current_operators: stake_summary + .current_operators + .keys() + .cloned() + .collect::>(), + total_domain_stake: stake_summary.current_total_stake, + bundle_slot_probability: domain_object.domain_config.bundle_slot_probability, + }), + _ => None, } + } + pub fn operator(operator_id: OperatorId) -> Option<(OperatorPublicKey, BalanceOf)> { + Operators::::get(operator_id) + .map(|operator| (operator.signing_key, operator.current_total_stake)) + } + + fn check_bundle_duplication(opaque_bundle: &OpaqueBundleOf) -> Result<(), BundleError> { + // NOTE: it is important to use the hash that not incliude the signature, otherwise + // the malicious operator may update its `signing_key` (this may support in the future) + // and sign an existing bundle thus creating a duplicated bundle and pass the check. + let bundle_header_hash = opaque_bundle.sealed_header.pre_hash(); + ensure!( + !InboxedBundle::::contains_key(bundle_header_hash), + BundleError::DuplicatedBundle + ); Ok(()) } - fn validate_system_bundle_solution( - receipt: &ExecutionReceipt, - authority_stake_weight: sp_domains::StakeWeight, - authority_witness: &Witness, - proof_of_election: &ProofOfElection, + fn check_bundle_size( + opaque_bundle: &OpaqueBundleOf, + max_size: u32, ) -> Result<(), BundleError> { - let ProofOfElection { - system_state_root, - system_block_number, - system_block_hash, - .. - } = proof_of_election; - - let state_root = *system_state_root; - let block_number = T::BlockNumber::from(*system_block_number); - let block_hash = *system_block_hash; - - let new_best_receipt_number = receipt.primary_number.max(Self::head_receipt_number()); - - let state_root_verifiable = block_number <= new_best_receipt_number; - - if !block_number.is_zero() && state_root_verifiable { - let maybe_state_root = receipt.trace.last().and_then(|state_root| { - if (receipt.primary_number, receipt.domain_hash) == (block_number, block_hash) { - Some(*state_root) - } else { - None - } - }); + let bundle_size = opaque_bundle + .extrinsics + .iter() + .fold(0, |acc, xt| acc + xt.encoded_size() as u32); + ensure!(max_size >= bundle_size, BundleError::BundleTooLarge); + Ok(()) + } - let expected_state_root = match maybe_state_root { - Some(v) => v, - None => pallet_settlement::Pallet::::state_root(( - DomainId::SYSTEM, - block_number, - block_hash, - )) - .ok_or(BundleError::StateRootNotFound) - .map_err(|err| { - log::debug!( - target: "runtime::domains", - "State root for #{block_number:?},{block_hash:?} not found, \ - current head receipt: {:?}", - pallet_settlement::Pallet::::receipt_head(DomainId::SYSTEM), - ); - err - })?, - }; + fn check_extrinsics_root(opaque_bundle: &OpaqueBundleOf) -> Result<(), BundleError> { + let expected_extrinsics_root = BlakeTwo256::ordered_trie_root( + opaque_bundle + .extrinsics + .iter() + .map(|xt| xt.encode()) + .collect(), + sp_core::storage::StateVersion::V1, + ); + ensure!( + expected_extrinsics_root == opaque_bundle.extrinsics_root(), + BundleError::InvalidExtrinsicRoot + ); + Ok(()) + } - if expected_state_root != state_root { - log::debug!( - target: "runtime::domains", - "Bad state root for #{block_number:?},{block_hash:?}, \ - expected: {expected_state_root:?}, got: {state_root:?}", - ); - return Err(BundleError::BadStateRoot); - } - } + fn check_proof_of_election( + domain_id: DomainId, + operator_id: OperatorId, + operator: Operator, T::Share>, + bundle_slot_probability: (u64, u64), + proof_of_election: &ProofOfElection, + ) -> Result<(), BundleError> { + proof_of_election + .verify_vrf_signature(&operator.signing_key) + .map_err(|_| BundleError::BadVrfSignature)?; - let state_root = H256::decode(&mut state_root.encode().as_slice()) - .map_err(|_| BundleError::StateRootNotH256)?; + let (operator_stake, total_domain_stake) = + Self::fetch_operator_stake_info(domain_id, &operator_id)?; - verify_system_bundle_solution( - proof_of_election, - state_root, - authority_stake_weight, - authority_witness, - ) - .map_err(|_| BundleError::BadElectionSolution)?; + let threshold = sp_domains::bundle_producer_election::calculate_threshold( + operator_stake.saturated_into(), + total_domain_stake.saturated_into(), + bundle_slot_probability, + ); + + if !is_below_threshold(&proof_of_election.vrf_signature.output, threshold) { + return Err(BundleError::ThresholdUnsatisfied); + } Ok(()) } - fn validate_bundle( - OpaqueBundle { - sealed_header, - receipt, - extrinsics: _, - }: &OpaqueBundle, - ) -> Result<(), BundleError> { - if !sealed_header.verify_signature() { - return Err(BundleError::BadSignature); + fn validate_bundle(opaque_bundle: &OpaqueBundleOf) -> Result<(), BundleError> { + let domain_id = opaque_bundle.domain_id(); + let operator_id = opaque_bundle.operator_id(); + let sealed_header = &opaque_bundle.sealed_header; + + let operator = Operators::::get(operator_id).ok_or(BundleError::InvalidOperatorId)?; + + ensure!( + operator.status != OperatorStatus::Slashed, + BundleError::BadOperator + ); + + if !operator + .signing_key + .verify(&sealed_header.pre_hash(), &sealed_header.signature) + { + return Err(BundleError::BadBundleSignature); } - let header = &sealed_header.header; + Self::check_bundle_duplication(opaque_bundle)?; - let current_block_number = frame_system::Pallet::::current_block_number(); + let domain_config = DomainRegistry::::get(domain_id) + .ok_or(BundleError::InvalidDomainId)? + .domain_config; - // Reject the stale bundles so that they can't be used by attacker to occupy the block space without cost. - let confirmation_depth_k = T::ConfirmationDepthK::get(); - if let Some(finalized) = current_block_number.checked_sub(&confirmation_depth_k) { - { - // Ideally, `bundle.header.primary_number` is `current_block_number - 1`, we need - // to handle the edge case that `T::ConfirmationDepthK` happens to be 1. - let is_stale_bundle = if confirmation_depth_k.is_zero() { - unreachable!( - "ConfirmationDepthK is guaranteed to be non-zero at genesis config" - ) - } else if confirmation_depth_k == One::one() { - header.primary_number < finalized - } else { - header.primary_number <= finalized - }; - - if is_stale_bundle { - log::debug!( - target: "runtime::domains", - "Bundle created on an ancient consensus block, current_block_number: {current_block_number:?}, \ - ConfirmationDepthK: {confirmation_depth_k:?}, `bundle.header.primary_number`: {:?}, `finalized`: {finalized:?}", - header.primary_number, - ); - return Err(BundleError::StaleBundle); - } + // TODO: check bundle weight with `domain_config.max_block_weight` + + Self::check_bundle_size(opaque_bundle, domain_config.max_block_size)?; + + Self::check_extrinsics_root(opaque_bundle)?; + + let proof_of_election = &sealed_header.header.proof_of_election; + Self::check_proof_of_election( + domain_id, + operator_id, + operator, + domain_config.bundle_slot_probability, + proof_of_election, + )?; + + let receipt = &sealed_header.header.receipt; + verify_execution_receipt::(domain_id, receipt).map_err(BundleError::Receipt)?; + + Ok(()) + } + + /// Return operators specific election verification params for Proof of Election verification. + /// If there was an epoch transition in this block for this domain, + /// then return the parameters from previous epoch stored in LastEpochStakingDistribution + /// Else, return those details from the Domain's stake summary for this epoch. + fn fetch_operator_stake_info( + domain_id: DomainId, + operator_id: &OperatorId, + ) -> Result<(BalanceOf, BalanceOf), BundleError> { + match LastEpochStakingDistribution::::get(domain_id) { + None => { + let domain_stake_summary = DomainStakingSummary::::get(domain_id) + .ok_or(BundleError::InvalidDomainId)?; + + let operator_stake = domain_stake_summary + .current_operators + .get(operator_id) + .ok_or(BundleError::BadOperator)?; + + Ok((*operator_stake, domain_stake_summary.current_total_stake)) + } + Some(pending_election_params) => { + let operator_stake = pending_election_params + .operators + .get(operator_id) + .ok_or(BundleError::BadOperator)?; + Ok((*operator_stake, pending_election_params.total_domain_stake)) } } + } - let proof_of_election = header.bundle_solution.proof_of_election(); - proof_of_election - .verify_vrf_proof() - .map_err(|_| BundleError::BadVrfProof)?; - - if proof_of_election.domain_id.is_system() { - let BundleSolution::System { - authority_stake_weight, - authority_witness, - proof_of_election - } = &header.bundle_solution else { - unreachable!("Must be system domain bundle solution as we just checked; qed ") - }; - - // TODO: currently, only the system bundles created on the primary fork can be - // prevented beforehand, the core bundles will be rejected by the system domain but - // they are still included on the primary chain as it's not feasible to check core bundles - // within this pallet, which may be solved if the `submit_bundle` extrinsic is no longer - // free in the future. - let bundle_created_on_valid_primary_block = - match pallet_settlement::PrimaryBlockHash::::get( - DomainId::SYSTEM, - header.primary_number, - ) { - Some(block_hash) => block_hash == header.primary_hash, - // The `initialize_block` of non-system pallets is skipped in the `validate_transaction`, - // thus the hash of best block, which is recorded in the this pallet's `on_initialize` hook, - // is unavailable in pallet-receipts at this point. - None => frame_system::Pallet::::parent_hash() == header.primary_hash, - }; - - if !bundle_created_on_valid_primary_block { - log::debug!( - target: "runtime::domains", - "Bundle is probably created on a primary fork #{:?}, expected: {:?}, got: {:?}", - header.primary_number, - pallet_settlement::PrimaryBlockHash::::get(DomainId::SYSTEM, header.primary_number), - header.primary_hash, - ); - return Err(BundleError::UnknownBlock); + /// Called when a bundle is added to update the bundle state for tx range + /// calculation. + fn note_domain_bundle(domain_id: DomainId) { + DomainTxRangeState::::mutate(domain_id, |maybe_state| match maybe_state { + Some(state) => { + state.interval_bundles += 1; } - - Self::validate_system_bundle_solution( - receipt, - *authority_stake_weight, - authority_witness, - proof_of_election, - )?; - - let best_number = Self::head_receipt_number(); - let max_allowed = best_number + T::MaximumReceiptDrift::get(); - let oldest_receipt_number = Self::oldest_receipt_number(); - let primary_number = receipt.primary_number; - - // The corresponding block info has been pruned, such expired receipts - // will be skipped too while applying the bundle. - if primary_number < oldest_receipt_number { - return Ok(()); + None => { + maybe_state.replace(TxRangeState { + tx_range: Self::initial_tx_range(), + interval_blocks: 0, + interval_bundles: 1, + }); } + }); + } - // Due to `initialize_block` is skipped while calling the runtime api, the block - // hash mapping for last block is unknown to the transaction pool, but this info - // is already available in System. - let point_to_parent_block = primary_number == current_block_number - One::one() - && receipt.primary_hash == frame_system::Pallet::::parent_hash(); + /// Called when the block is finalized to update the tx range for all the + /// domains with bundles in the block. + fn update_domain_tx_range() { + for domain_id in DomainTxRangeState::::iter_keys() { + if let Some(domain_config) = + DomainRegistry::::get(domain_id).map(|obj| obj.domain_config) + { + DomainTxRangeState::::mutate(domain_id, |maybe_tx_range_state| { + if let Some(tx_range_state) = maybe_tx_range_state { + let tx_range_adjustment_interval = + T::DomainTxRangeAdjustmentInterval::get(); - let point_to_valid_primary_block = - pallet_settlement::Pallet::::point_to_valid_primary_block( - DomainId::SYSTEM, - receipt, - ); + tx_range_state.interval_blocks += 1; - if !point_to_parent_block && !point_to_valid_primary_block { - log::debug!( - target: "runtime::domains", - "Receipt of #{primary_number:?},{:?} points to an unknown primary block, \ - expected: #{primary_number:?},{:?}", - receipt.primary_hash, - pallet_settlement::PrimaryBlockHash::::get(DomainId::SYSTEM, primary_number), - ); - return Err(BundleError::Receipt(ExecutionReceiptError::UnknownBlock)); - } + if tx_range_state.interval_blocks < tx_range_adjustment_interval { + return; + } - // Ensure the receipt is not too new. - if primary_number == current_block_number || primary_number > max_allowed { - log::debug!( - target: "runtime::domains", - "Receipt for #{primary_number:?} is too far in future, \ - current_block_number: {current_block_number:?}, max_allowed: {max_allowed:?}", - ); - return Err(BundleError::Receipt(ExecutionReceiptError::TooFarInFuture)); + // End of interval, calculate the new tx range. + let TxRangeState { + tx_range, + interval_blocks, + interval_bundles, + } = tx_range_state; + + let actual_bundle_count = *interval_bundles; + let expected_bundle_count = tx_range_adjustment_interval + * u64::from(domain_config.target_bundles_per_block); + + let new_tx_range = calculate_tx_range( + *tx_range, + actual_bundle_count, + expected_bundle_count, + ); + + log::trace!( + target: "runtime::domains", + "tx range update: blocks = {interval_blocks}, bundles = {actual_bundle_count}, prev = {tx_range}, new = {new_tx_range}" + ); + + // Reset the tx range and start over. + tx_range_state.tx_range = new_tx_range; + tx_range_state.interval_blocks = 0; + tx_range_state.interval_bundles = 0; + } + }) } } + } - Ok(()) + /// Calculates the initial tx range. + fn initial_tx_range() -> U256 { + U256::MAX / T::InitialDomainTxRange::get() + } + + /// Returns the best execution chain number. + pub fn head_receipt_number(domain_id: DomainId) -> T::DomainNumber { + HeadReceiptNumber::::get(domain_id) + } + + /// Returns the block number of oldest execution receipt. + pub fn oldest_receipt_number(domain_id: DomainId) -> T::DomainNumber { + Self::head_receipt_number(domain_id).saturating_sub(Self::block_tree_pruning_depth()) + } + + /// Returns the block tree pruning depth. + pub fn block_tree_pruning_depth() -> T::DomainNumber { + T::BlockTreePruningDepth::get() + } + + /// Returns the domain block limit of the given domain. + pub fn domain_block_limit(domain_id: DomainId) -> Option { + DomainRegistry::::get(domain_id).map(|domain_obj| DomainBlockLimit { + max_block_size: domain_obj.domain_config.max_block_size, + max_block_weight: domain_obj.domain_config.max_block_weight, + }) + } + + /// Increase the nomination stake by `reward` to the preferred operator of `who`. + /// Preference is removed if the nomination fails. + pub fn on_block_reward(who: NominatorId, reward: BalanceOf) { + PreferredOperator::::mutate_exists(who.clone(), |maybe_preferred_operator_id| { + if let Some(operator_id) = maybe_preferred_operator_id { + if let Err(err) = do_nominate_operator::(*operator_id, who, reward) { + log::trace!( + target: "runtime::domains", + "Failed to stake the reward amount to preferred operator: {err:?}. Removing preference." + ); + maybe_preferred_operator_id.take(); + } + } + }); } } @@ -621,10 +1454,8 @@ where T: Config + frame_system::offchain::SendTransactionTypes>, { /// Submits an unsigned extrinsic [`Call::submit_bundle`]. - pub fn submit_bundle_unsigned( - opaque_bundle: OpaqueBundle, - ) { - let slot = opaque_bundle.sealed_header.header.slot_number; + pub fn submit_bundle_unsigned(opaque_bundle: OpaqueBundleOf) { + let slot = opaque_bundle.sealed_header.slot_number(); let extrincis_count = opaque_bundle.extrinsics.len(); let call = Call::submit_bundle { opaque_bundle }; @@ -644,7 +1475,9 @@ where /// Submits an unsigned extrinsic [`Call::submit_fraud_proof`]. pub fn submit_fraud_proof_unsigned(fraud_proof: FraudProof) { - let call = Call::submit_fraud_proof { fraud_proof }; + let call = Call::submit_fraud_proof { + fraud_proof: Box::new(fraud_proof), + }; match SubmitTransaction::>::submit_unsigned_transaction(call.into()) { Ok(()) => { @@ -656,3 +1489,27 @@ where } } } + +/// Calculates the new tx range based on the bundles produced during the interval. +pub fn calculate_tx_range( + cur_tx_range: U256, + actual_bundle_count: u64, + expected_bundle_count: u64, +) -> U256 { + if actual_bundle_count == 0 || expected_bundle_count == 0 { + return cur_tx_range; + } + + let Some(new_tx_range) = U256::from(actual_bundle_count) + .saturating_mul(&cur_tx_range) + .checked_div(&U256::from(expected_bundle_count)) + else { + return cur_tx_range; + }; + + let upper_bound = cur_tx_range.saturating_mul(&U256::from(4_u64)); + let Some(lower_bound) = cur_tx_range.checked_div(&U256::from(4_u64)) else { + return cur_tx_range; + }; + new_tx_range.clamp(lower_bound, upper_bound) +} diff --git a/crates/pallet-domains/src/runtime_registry.rs b/crates/pallet-domains/src/runtime_registry.rs new file mode 100644 index 00000000000..99eda3a4fc5 --- /dev/null +++ b/crates/pallet-domains/src/runtime_registry.rs @@ -0,0 +1,424 @@ +//! Runtime registry for domains + +use crate::pallet::{NextRuntimeId, RuntimeRegistry, ScheduledRuntimeUpgrades}; +use crate::{Config, Event}; +use codec::{Decode, Encode}; +use frame_support::PalletError; +use scale_info::TypeInfo; +use sp_core::Hasher; +use sp_domains::{DomainsDigestItem, RuntimeId, RuntimeType}; +use sp_runtime::traits::{CheckedAdd, Get}; +use sp_runtime::DigestItem; +use sp_std::vec::Vec; +use sp_version::RuntimeVersion; + +/// Runtime specific errors +#[derive(TypeInfo, Encode, Decode, PalletError, Debug, PartialEq)] +pub enum Error { + FailedToExtractRuntimeVersion, + InvalidSpecName, + SpecVersionNeedsToIncrease, + MaxRuntimeId, + MissingRuntimeObject, + RuntimeUpgradeAlreadyScheduled, + MaxScheduledBlockNumber, +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct RuntimeObject { + pub runtime_name: Vec, + pub runtime_type: RuntimeType, + pub runtime_upgrades: u32, + pub hash: Hash, + pub code: Vec, + pub version: RuntimeVersion, + pub created_at: Number, + pub updated_at: Number, +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct ScheduledRuntimeUpgrade { + pub code: Vec, + pub version: RuntimeVersion, +} + +/// Extracts the runtime version of the provided code. +pub(crate) fn runtime_version(code: &[u8]) -> Result { + sp_io::misc::runtime_version(code) + .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) + .ok_or(Error::FailedToExtractRuntimeVersion) +} + +/// Upgrades current runtime with new runtime. +// TODO: we can use upstream's `can_set_code` after some adjustments +pub(crate) fn can_upgrade_code( + current_version: &RuntimeVersion, + update_code: &[u8], +) -> Result { + let new_version = runtime_version(update_code)?; + + if new_version.spec_name != current_version.spec_name { + return Err(Error::InvalidSpecName); + } + + if new_version.spec_version <= current_version.spec_version { + return Err(Error::SpecVersionNeedsToIncrease); + } + + Ok(new_version) +} + +/// Registers a new domain runtime.. +pub(crate) fn do_register_runtime( + runtime_name: Vec, + runtime_type: RuntimeType, + code: Vec, + at: T::BlockNumber, +) -> Result { + let runtime_version = runtime_version(&code)?; + let runtime_hash = T::Hashing::hash(&code); + let runtime_id = NextRuntimeId::::get(); + + RuntimeRegistry::::insert( + runtime_id, + RuntimeObject { + runtime_name, + runtime_type, + hash: runtime_hash, + code, + version: runtime_version, + created_at: at, + updated_at: at, + runtime_upgrades: 0u32, + }, + ); + + let next_runtime_id = runtime_id.checked_add(1).ok_or(Error::MaxRuntimeId)?; + NextRuntimeId::::set(next_runtime_id); + + Ok(runtime_id) +} + +// TODO: Remove once `do_register_runtime` works at genesis. +/// Registers a new domain runtime at genesis. +pub(crate) fn register_runtime_at_genesis( + runtime_name: Vec, + runtime_type: RuntimeType, + runtime_version: RuntimeVersion, + code: Vec, + at: T::BlockNumber, +) -> Result { + let runtime_hash = T::Hashing::hash(&code); + let runtime_id = NextRuntimeId::::get(); + + RuntimeRegistry::::insert( + runtime_id, + RuntimeObject { + runtime_name, + runtime_type, + hash: runtime_hash, + code, + version: runtime_version, + created_at: at, + updated_at: at, + runtime_upgrades: 0u32, + }, + ); + + let next_runtime_id = runtime_id.checked_add(1).ok_or(Error::MaxRuntimeId)?; + NextRuntimeId::::set(next_runtime_id); + + Ok(runtime_id) +} + +/// Schedules a runtime upgrade after `DomainRuntimeUpgradeDelay` from current block number. +pub(crate) fn do_schedule_runtime_upgrade( + runtime_id: RuntimeId, + code: Vec, + current_block_number: T::BlockNumber, +) -> Result { + let runtime_obj = RuntimeRegistry::::get(runtime_id).ok_or(Error::MissingRuntimeObject)?; + let new_runtime_version = can_upgrade_code(&runtime_obj.version, &code)?; + let scheduled_at = current_block_number + .checked_add(&T::DomainRuntimeUpgradeDelay::get()) + .ok_or(Error::MaxScheduledBlockNumber)?; + let scheduled_upgrade = ScheduledRuntimeUpgrade { + code, + version: new_runtime_version, + }; + ScheduledRuntimeUpgrades::::insert(scheduled_at, runtime_id, scheduled_upgrade); + Ok(scheduled_at) +} + +pub(crate) fn do_upgrade_runtimes(at: T::BlockNumber) { + for (runtime_id, scheduled_update) in ScheduledRuntimeUpgrades::::drain_prefix(at) { + RuntimeRegistry::::mutate(runtime_id, |maybe_runtime_object| { + let runtime_obj = maybe_runtime_object + .as_mut() + .expect("Runtime object exists since an upgrade is scheduled after verification"); + + let runtime_hash = T::Hashing::hash(&scheduled_update.code); + runtime_obj.code = scheduled_update.code; + runtime_obj.version = scheduled_update.version; + runtime_obj.hash = runtime_hash; + runtime_obj.runtime_upgrades = runtime_obj.runtime_upgrades.saturating_add(1); + runtime_obj.updated_at = at; + }); + + // deposit digest log for light clients + frame_system::Pallet::::deposit_log(DigestItem::domain_runtime_upgrade(runtime_id)); + + // deposit event to signal runtime upgrade is complete + frame_system::Pallet::::deposit_event(::RuntimeEvent::from( + Event::DomainRuntimeUpgraded { runtime_id }, + )); + } +} + +#[cfg(test)] +mod tests { + use crate::pallet::{NextRuntimeId, RuntimeRegistry, ScheduledRuntimeUpgrades}; + use crate::runtime_registry::{Error as RuntimeRegistryError, RuntimeObject}; + use crate::tests::{ + new_test_ext, DomainRuntimeUpgradeDelay, Domains, ReadRuntimeVersion, System, Test, + }; + use crate::Error; + use codec::Encode; + use frame_support::assert_ok; + use frame_support::dispatch::RawOrigin; + use frame_support::traits::OnInitialize; + use sp_domains::{DomainsDigestItem, RuntimeId, RuntimeType}; + use sp_runtime::traits::BlockNumberProvider; + use sp_runtime::{Digest, DispatchError}; + use sp_version::RuntimeVersion; + + #[test] + fn create_domain_runtime() { + let version = RuntimeVersion { + spec_name: "test".into(), + impl_name: Default::default(), + authoring_version: 0, + spec_version: 1, + impl_version: 1, + apis: Default::default(), + transaction_version: 1, + state_version: 0, + }; + let read_runtime_version = ReadRuntimeVersion(version.encode()); + + let mut ext = new_test_ext(); + ext.register_extension(sp_core::traits::ReadRuntimeVersionExt::new( + read_runtime_version, + )); + ext.execute_with(|| { + let res = crate::Pallet::::register_domain_runtime( + RawOrigin::Root.into(), + b"evm".to_vec(), + RuntimeType::Evm, + vec![1, 2, 3, 4], + ); + + assert_ok!(res); + let runtime_obj = RuntimeRegistry::::get(0).unwrap(); + assert_eq!(runtime_obj.version, version); + assert_eq!(NextRuntimeId::::get(), 1) + }) + } + + #[test] + fn schedule_domain_runtime_upgrade() { + let mut ext = new_test_ext(); + ext.execute_with(|| { + RuntimeRegistry::::insert( + 0, + RuntimeObject { + runtime_name: b"evm".to_vec(), + runtime_type: Default::default(), + runtime_upgrades: 0, + hash: Default::default(), + code: vec![1, 2, 3, 4], + version: RuntimeVersion { + spec_name: "test".into(), + spec_version: 1, + impl_version: 1, + transaction_version: 1, + ..Default::default() + }, + created_at: Default::default(), + updated_at: Default::default(), + }, + ); + + NextRuntimeId::::set(1); + }); + + let test_data = vec![ + ( + "test1", + 1, + Err(Error::::RuntimeRegistry( + RuntimeRegistryError::InvalidSpecName, + )), + ), + ( + "test", + 1, + Err(Error::::RuntimeRegistry( + RuntimeRegistryError::SpecVersionNeedsToIncrease, + )), + ), + ("test", 2, Ok(())), + ]; + + for (spec_name, spec_version, expected) in test_data.into_iter() { + let version = RuntimeVersion { + spec_name: spec_name.into(), + spec_version, + impl_version: 1, + transaction_version: 1, + ..Default::default() + }; + let read_runtime_version = ReadRuntimeVersion(version.encode()); + ext.register_extension(sp_core::traits::ReadRuntimeVersionExt::new( + read_runtime_version, + )); + + ext.execute_with(|| { + frame_system::Pallet::::set_block_number(100u64); + let res = crate::Pallet::::upgrade_domain_runtime( + RawOrigin::Root.into(), + 0, + vec![6, 7, 8, 9], + ); + + assert_eq!(res, expected.map_err(DispatchError::from)) + }) + } + + // verify upgrade + ext.execute_with(|| { + let runtime_obj = RuntimeRegistry::::get(0).unwrap(); + assert_eq!( + runtime_obj.version, + RuntimeVersion { + spec_name: "test".into(), + spec_version: 1, + impl_version: 1, + transaction_version: 1, + ..Default::default() + } + ); + assert_eq!(runtime_obj.runtime_upgrades, 0); + assert_eq!(runtime_obj.code, vec![1, 2, 3, 4]); + + let block_number = frame_system::Pallet::::current_block_number(); + let scheduled_block_number = block_number + .checked_add(DomainRuntimeUpgradeDelay::get()) + .unwrap(); + let scheduled_upgrade = + ScheduledRuntimeUpgrades::::get(scheduled_block_number, 0).unwrap(); + assert_eq!( + scheduled_upgrade.version, + RuntimeVersion { + spec_name: "test".into(), + spec_version: 2, + impl_version: 1, + transaction_version: 1, + ..Default::default() + } + ) + }) + } + + fn go_to_block(block: u64) { + for i in System::block_number() + 1..=block { + let parent_hash = if System::block_number() > 1 { + let hdr = System::finalize(); + hdr.hash() + } else { + System::parent_hash() + }; + + System::reset_events(); + let digest = sp_runtime::testing::Digest { logs: vec![] }; + System::initialize(&i, &parent_hash, &digest); + Domains::on_initialize(i); + } + } + + fn fetch_upgraded_runtime_from_digest(digest: Digest) -> Option { + for log in digest.logs { + match log.as_domain_runtime_upgrade() { + None => continue, + Some(runtime_id) => return Some(runtime_id), + } + } + + None + } + + #[test] + fn upgrade_scheduled_domain_runtime() { + let mut ext = new_test_ext(); + let mut version = RuntimeVersion { + spec_name: "test".into(), + impl_name: Default::default(), + authoring_version: 0, + spec_version: 1, + impl_version: 1, + apis: Default::default(), + transaction_version: 1, + state_version: 0, + }; + + ext.execute_with(|| { + RuntimeRegistry::::insert( + 0, + RuntimeObject { + runtime_name: b"evm".to_vec(), + runtime_type: Default::default(), + runtime_upgrades: 0, + hash: Default::default(), + code: vec![1, 2, 3, 4], + version: version.clone(), + created_at: Default::default(), + updated_at: Default::default(), + }, + ); + + NextRuntimeId::::set(1); + }); + + version.spec_version = 2; + let read_runtime_version = ReadRuntimeVersion(version.encode()); + ext.register_extension(sp_core::traits::ReadRuntimeVersionExt::new( + read_runtime_version, + )); + + ext.execute_with(|| { + let res = crate::Pallet::::upgrade_domain_runtime( + RawOrigin::Root.into(), + 0, + vec![6, 7, 8, 9], + ); + assert_ok!(res); + + let current_block = frame_system::Pallet::::current_block_number(); + let scheduled_block_number = current_block + .checked_add(DomainRuntimeUpgradeDelay::get()) + .unwrap(); + + go_to_block(scheduled_block_number); + assert_eq!( + ScheduledRuntimeUpgrades::::get(scheduled_block_number, 0), + None + ); + + let runtime_obj = RuntimeRegistry::::get(0).unwrap(); + assert_eq!(runtime_obj.version, version); + + let digest = System::digest(); + assert_eq!(Some(0), fetch_upgraded_runtime_from_digest(digest)) + }); + } +} diff --git a/crates/pallet-domains/src/staking.rs b/crates/pallet-domains/src/staking.rs new file mode 100644 index 00000000000..35212ce7b5d --- /dev/null +++ b/crates/pallet-domains/src/staking.rs @@ -0,0 +1,1487 @@ +//! Staking for domains + +use crate::pallet::{ + DomainStakingSummary, NextOperatorId, Nominators, OperatorIdOwner, Operators, PendingDeposits, + PendingNominatorUnlocks, PendingOperatorDeregistrations, PendingOperatorSwitches, + PendingOperatorUnlocks, PendingSlashes, PendingWithdrawals, PreferredOperator, +}; +use crate::staking_epoch::{mint_funds, PendingNominatorUnlock, PendingOperatorSlashInfo}; +use crate::{BalanceOf, Config, Event, HoldIdentifier, NominatorId, Pallet}; +use codec::{Decode, Encode}; +use frame_support::traits::fungible::{Inspect, MutateHold}; +use frame_support::traits::tokens::{Fortitude, Preservation}; +use frame_support::{ensure, PalletError}; +use scale_info::TypeInfo; +use sp_core::Get; +use sp_domains::{DomainId, EpochIndex, OperatorId, OperatorPublicKey}; +use sp_runtime::traits::{CheckedAdd, CheckedSub, One, Zero}; +use sp_runtime::{Perbill, Percent}; +use sp_std::collections::btree_map::BTreeMap; +use sp_std::collections::btree_set::BTreeSet; +use sp_std::vec::{IntoIter, Vec}; + +/// Type that represents an operator status. +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub enum OperatorStatus { + Registered, + Deregistered, + Slashed, +} + +/// Type that represents an operator details. +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct Operator { + pub signing_key: OperatorPublicKey, + pub current_domain_id: DomainId, + pub next_domain_id: DomainId, + pub minimum_nominator_stake: Balance, + pub nomination_tax: Percent, + /// Total active stake of combined nominators under this operator. + pub current_total_stake: Balance, + /// Total rewards this operator received this current epoch. + pub current_epoch_rewards: Balance, + /// Total shares of all the nominators under this operator. + pub total_shares: Share, + pub status: OperatorStatus, +} + +/// Type that represents a nominator's details under a specific operator. +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct Nominator { + pub shares: Share, +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub enum Withdraw { + All, + Some(Balance), +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct StakingSummary { + /// Current epoch index for the domain. + pub current_epoch_index: EpochIndex, + /// Total active stake for the current epoch. + pub current_total_stake: Balance, + /// Current operators for this epoch + pub current_operators: BTreeMap, + /// Operators for the next epoch. + pub next_operators: BTreeSet, + /// Operator's current Epoch rewards + pub current_epoch_rewards: BTreeMap, +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct OperatorConfig { + pub signing_key: OperatorPublicKey, + pub minimum_nominator_stake: Balance, + pub nomination_tax: Percent, +} + +#[derive(TypeInfo, Encode, Decode, PalletError, Debug, PartialEq)] +pub enum Error { + MaximumOperatorId, + DomainNotInitialized, + PendingOperatorSwitch, + InsufficientBalance, + BalanceFreeze, + MinimumOperatorStake, + UnknownOperator, + MinimumNominatorStake, + BalanceOverflow, + BalanceUnderflow, + NotOperatorOwner, + OperatorNotRegistered, + UnknownNominator, + ExistingFullWithdraw, + MissingOperatorOwner, + MintBalance, + BlockNumberOverflow, + RemoveLock, + UpdateLock, + EpochOverflow, + ShareUnderflow, + ShareOverflow, + TryDepositWithPendingWithdraw, + TryWithdrawWithPendingDeposit, +} + +pub(crate) fn do_register_operator( + operator_owner: T::AccountId, + domain_id: DomainId, + amount: BalanceOf, + config: OperatorConfig>, +) -> Result { + DomainStakingSummary::::try_mutate(domain_id, |maybe_domain_stake_summary| { + let operator_id = NextOperatorId::::get(); + let next_operator_id = operator_id.checked_add(1).ok_or(Error::MaximumOperatorId)?; + NextOperatorId::::set(next_operator_id); + + OperatorIdOwner::::insert(operator_id, operator_owner.clone()); + + // reserve stake balance + ensure!( + amount >= T::MinOperatorStake::get(), + Error::MinimumOperatorStake + ); + + hold_pending_deposit::(&operator_owner, operator_id, amount)?; + + let domain_stake_summary = maybe_domain_stake_summary + .as_mut() + .ok_or(Error::DomainNotInitialized)?; + + let OperatorConfig { + signing_key, + minimum_nominator_stake, + nomination_tax, + } = config; + + let operator = Operator { + signing_key, + current_domain_id: domain_id, + next_domain_id: domain_id, + minimum_nominator_stake, + nomination_tax, + current_total_stake: Zero::zero(), + current_epoch_rewards: Zero::zero(), + total_shares: Zero::zero(), + status: OperatorStatus::Registered, + }; + Operators::::insert(operator_id, operator); + // update stake summary to include new operator for next epoch + domain_stake_summary.next_operators.insert(operator_id); + // update pending transfers + PendingDeposits::::insert(operator_id, operator_owner, amount); + + Ok(operator_id) + }) +} + +pub(crate) fn do_nominate_operator( + operator_id: OperatorId, + nominator_id: T::AccountId, + amount: BalanceOf, +) -> Result<(), Error> { + let operator = Operators::::get(operator_id).ok_or(Error::UnknownOperator)?; + + ensure!( + operator.status == OperatorStatus::Registered, + Error::OperatorNotRegistered + ); + + ensure!( + !PendingWithdrawals::::contains_key(operator_id, nominator_id.clone()), + Error::TryDepositWithPendingWithdraw, + ); + + let updated_total_deposit = match PendingDeposits::::get(operator_id, nominator_id.clone()) { + None => amount, + Some(existing_deposit) => existing_deposit + .checked_add(&amount) + .ok_or(Error::BalanceOverflow)?, + }; + + // if not a nominator, then ensure amount >= operator's minimum nominator stake amount + if !Nominators::::contains_key(operator_id, nominator_id.clone()) { + ensure!( + updated_total_deposit >= operator.minimum_nominator_stake, + Error::MinimumNominatorStake + ); + } + + hold_pending_deposit::(&nominator_id, operator_id, amount)?; + PendingDeposits::::insert(operator_id, nominator_id, updated_total_deposit); + + Ok(()) +} + +pub(crate) fn hold_pending_deposit( + who: &T::AccountId, + operator_id: OperatorId, + amount: BalanceOf, +) -> Result<(), Error> { + // ensure there is enough free balance to lock + ensure!( + T::Currency::reducible_balance(who, Preservation::Preserve, Fortitude::Polite) >= amount, + Error::InsufficientBalance + ); + + let pending_deposit_hold_id = T::HoldIdentifier::staking_pending_deposit(operator_id); + T::Currency::hold(&pending_deposit_hold_id, who, amount).map_err(|_| Error::BalanceFreeze)?; + + Ok(()) +} + +pub(crate) fn do_switch_operator_domain( + operator_owner: T::AccountId, + operator_id: OperatorId, + new_domain_id: DomainId, +) -> Result { + ensure!( + OperatorIdOwner::::get(operator_id) == Some(operator_owner), + Error::NotOperatorOwner + ); + + ensure!( + DomainStakingSummary::::contains_key(new_domain_id), + Error::DomainNotInitialized + ); + + Operators::::try_mutate(operator_id, |maybe_operator| { + let operator = maybe_operator.as_mut().ok_or(Error::UnknownOperator)?; + + ensure!( + operator.status == OperatorStatus::Registered, + Error::OperatorNotRegistered + ); + + // noop when switch is for same domain + if operator.current_domain_id == new_domain_id { + return Ok(operator.current_domain_id); + } + + // check if there is any ongoing pending switch, if so reject + ensure!( + operator.current_domain_id == operator.next_domain_id, + Error::PendingOperatorSwitch + ); + + operator.next_domain_id = new_domain_id; + + // remove operator from next_operators from current domains. + // operator is added to the next_operators of the new domain once the + // current domain epoch is finished. + DomainStakingSummary::::try_mutate( + operator.current_domain_id, + |maybe_domain_stake_summary| { + let stake_summary = maybe_domain_stake_summary + .as_mut() + .ok_or(Error::DomainNotInitialized)?; + stake_summary.next_operators.remove(&operator_id); + Ok(()) + }, + )?; + + PendingOperatorSwitches::::append(operator.current_domain_id, operator_id); + + Ok(operator.current_domain_id) + }) +} + +pub(crate) fn do_deregister_operator( + operator_owner: T::AccountId, + operator_id: OperatorId, +) -> Result<(), Error> { + ensure!( + OperatorIdOwner::::get(operator_id) == Some(operator_owner), + Error::NotOperatorOwner + ); + + Operators::::try_mutate(operator_id, |maybe_operator| { + let operator = maybe_operator.as_mut().ok_or(Error::UnknownOperator)?; + + ensure!( + operator.status == OperatorStatus::Registered, + Error::OperatorNotRegistered + ); + operator.status = OperatorStatus::Deregistered; + + PendingOperatorDeregistrations::::append(operator.current_domain_id, operator_id); + DomainStakingSummary::::try_mutate( + operator.current_domain_id, + |maybe_domain_stake_summary| { + let stake_summary = maybe_domain_stake_summary + .as_mut() + .ok_or(Error::DomainNotInitialized)?; + + stake_summary.next_operators.remove(&operator_id); + Ok(()) + }, + ) + }) +} + +pub(crate) fn do_withdraw_stake( + operator_id: OperatorId, + nominator_id: NominatorId, + withdraw: Withdraw>, +) -> Result<(), Error> { + ensure!( + !PendingDeposits::::contains_key(operator_id, nominator_id.clone()), + Error::TryWithdrawWithPendingDeposit, + ); + Operators::::try_mutate(operator_id, |maybe_operator| { + let operator = maybe_operator.as_mut().ok_or(Error::UnknownOperator)?; + ensure!( + operator.status == OperatorStatus::Registered, + Error::OperatorNotRegistered + ); + + let nominator = Nominators::::get(operator_id, nominator_id.clone()) + .ok_or(Error::UnknownNominator)?; + + let operator_owner = + OperatorIdOwner::::get(operator_id).ok_or(Error::UnknownOperator)?; + + let withdraw = match PendingWithdrawals::::get(operator_id, nominator_id.clone()) { + None => withdraw, + Some(existing_withdraw) => match (existing_withdraw, withdraw) { + (Withdraw::All, _) => { + // there is an existing full withdraw, error out + return Err(Error::ExistingFullWithdraw); + } + (_, Withdraw::All) => { + // there is exisiting withdrawal with specific amount, + // since the new intent is complete withdrawl, use this instead + Withdraw::All + } + (Withdraw::Some(previous_withdraw), Withdraw::Some(new_withdraw)) => { + // combine both withdrawls into single one + Withdraw::Some( + previous_withdraw + .checked_add(&new_withdraw) + .ok_or(Error::BalanceOverflow)?, + ) + } + }, + }; + + match withdraw { + Withdraw::All => { + // if nominator is the operator owner and trying to withdraw all, then error out + if operator_owner == nominator_id { + return Err(Error::MinimumOperatorStake); + } + + PendingWithdrawals::::insert(operator_id, nominator_id, withdraw); + } + Withdraw::Some(withdraw_amount) => { + if withdraw_amount.is_zero() { + return Ok(()); + } + + let domain_stake_summary = + DomainStakingSummary::::get(operator.current_domain_id) + .ok_or(Error::DomainNotInitialized)?; + + let total_stake = match domain_stake_summary.current_epoch_rewards.get(&operator_id) + { + None => operator.current_total_stake, + Some(rewards) => { + let operator_tax = operator.nomination_tax.mul_floor(*rewards); + operator + .current_total_stake + .checked_add(rewards) + .ok_or(Error::BalanceOverflow)? + // deduct operator tax + .checked_sub(&operator_tax) + .ok_or(Error::BalanceUnderflow)? + } + }; + + let nominator_share = + Perbill::from_rational(nominator.shares, operator.total_shares); + + let nominator_staked_amount = nominator_share.mul_floor(total_stake); + + let nominator_remaining_amount = nominator_staked_amount + .checked_sub(&withdraw_amount) + .ok_or(Error::BalanceUnderflow)?; + + if operator_owner == nominator_id { + // for operator owner, the remaining amount should not be less than MinimumOperatorStake, + if nominator_remaining_amount < T::MinOperatorStake::get() { + return Err(Error::MinimumOperatorStake); + } + + PendingWithdrawals::::insert(operator_id, nominator_id, withdraw); + + // for just a nominator, if remaining amount falls below MinimumNominator stake, then withdraw all + // else withdraw the asked amount only + } else if nominator_remaining_amount < operator.minimum_nominator_stake { + PendingWithdrawals::::insert(operator_id, nominator_id, Withdraw::All); + } else { + PendingWithdrawals::::insert(operator_id, nominator_id, withdraw); + } + } + } + + Ok(()) + }) +} + +/// Distribute the reward to the operators equally and drop any dust to treasury. +pub(crate) fn do_reward_operators( + domain_id: DomainId, + operators: IntoIter, + mut rewards: BalanceOf, +) -> Result<(), Error> { + DomainStakingSummary::::mutate(domain_id, |maybe_stake_summary| { + let stake_summary = maybe_stake_summary + .as_mut() + .ok_or(Error::DomainNotInitialized)?; + + let distribution = Perbill::from_rational(One::one(), operators.len() as u32); + let reward_per_operator = distribution.mul_floor(rewards); + for operator_id in operators { + let total_reward = match stake_summary.current_epoch_rewards.get(&operator_id) { + None => reward_per_operator, + Some(rewards) => rewards + .checked_add(&reward_per_operator) + .ok_or(Error::BalanceOverflow)?, + }; + + stake_summary + .current_epoch_rewards + .insert(operator_id, total_reward); + + Pallet::::deposit_event(Event::OperatorRewarded { + operator_id, + reward: reward_per_operator, + }); + + rewards = rewards + .checked_sub(&reward_per_operator) + .ok_or(Error::BalanceUnderflow)?; + } + + mint_funds::(&T::TreasuryAccount::get(), rewards) + }) +} + +/// Sets Operator as the preferred one to auto stake the block rewards. +/// Caller must be nominator of the Operator. +pub(crate) fn do_auto_stake_block_rewards( + nominator_id: NominatorId, + operator_id: OperatorId, +) -> Result<(), Error> { + // must be a nominator of this operator + ensure!( + Nominators::::contains_key(operator_id, nominator_id.clone()), + Error::UnknownNominator + ); + + let operator = Operators::::get(operator_id).ok_or(Error::UnknownOperator)?; + ensure!( + operator.status == OperatorStatus::Registered, + Error::OperatorNotRegistered + ); + + PreferredOperator::::insert(nominator_id, operator_id); + Ok(()) +} + +#[allow(dead_code)] +// TODO: remove once fraud proof is done +/// Freezes the slashed operators and moves the operator to be removed once the domain they are +/// operating finishes the epoch. +pub(crate) fn do_slash_operators( + operator_ids: IntoIter, +) -> Result<(), Error> { + for operator_id in operator_ids { + Operators::::try_mutate(operator_id, |maybe_operator| { + let operator = maybe_operator.as_mut().ok_or(Error::UnknownOperator)?; + let mut pending_slashes = + PendingSlashes::::get(operator.current_domain_id).unwrap_or_default(); + + if pending_slashes.contains_key(&operator_id) { + return Ok(()); + } + + DomainStakingSummary::::try_mutate( + operator.current_domain_id, + |maybe_domain_stake_summary| { + let stake_summary = maybe_domain_stake_summary + .as_mut() + .ok_or(Error::DomainNotInitialized)?; + + // slash and remove operator from next epoch set + operator.status = OperatorStatus::Slashed; + stake_summary.next_operators.remove(&operator_id); + + // remove any current operator switches + PendingOperatorSwitches::::mutate( + operator.current_domain_id, + |maybe_switching_operators| { + if let Some(switching_operators) = maybe_switching_operators.as_mut() { + switching_operators.remove(&operator_id); + } + }, + ); + + // remove any current operator de-registrations + PendingOperatorDeregistrations::::mutate( + operator.current_domain_id, + |maybe_deregistering_operators| { + if let Some(deregistering_operators) = + maybe_deregistering_operators.as_mut() + { + deregistering_operators.remove(&operator_id); + } + }, + ); + + // remove from operator unlocks + PendingOperatorUnlocks::::mutate(|unlocking_operators| { + unlocking_operators.remove(&operator_id) + }); + + // remove from nominator unlocks + let unlocking_nominators = + PendingNominatorUnlocks::::drain_prefix(operator_id) + .flat_map(|(_, nominator_unlocks)| nominator_unlocks) + .collect::, BalanceOf>>>(); + + // update pending slashed + pending_slashes.insert( + operator_id, + PendingOperatorSlashInfo { + unlocking_nominators, + }, + ); + + PendingSlashes::::insert(operator.current_domain_id, pending_slashes); + Ok(()) + }, + ) + })? + } + + Ok(()) +} + +#[cfg(test)] +pub(crate) mod tests { + use crate::pallet::{ + DomainStakingSummary, NextOperatorId, OperatorIdOwner, Operators, PendingDeposits, + PendingNominatorUnlocks, PendingOperatorDeregistrations, PendingOperatorSwitches, + PendingSlashes, PendingUnlocks, PendingWithdrawals, PreferredOperator, + }; + use crate::staking::{ + do_nominate_operator, do_reward_operators, do_slash_operators, do_withdraw_stake, + Error as StakingError, Operator, OperatorConfig, OperatorStatus, StakingSummary, Withdraw, + }; + use crate::staking_epoch::{ + do_finalize_domain_current_epoch, do_finalize_slashed_operators, + do_unlock_pending_withdrawals, PendingNominatorUnlock, + }; + use crate::tests::{new_test_ext, ExistentialDeposit, RuntimeOrigin, Test}; + use crate::{BalanceOf, Error, NominatorId}; + use frame_support::traits::fungible::Mutate; + use frame_support::traits::Currency; + use frame_support::{assert_err, assert_ok}; + use sp_core::{Pair, U256}; + use sp_domains::{DomainId, OperatorId, OperatorPair, OperatorPublicKey}; + use sp_runtime::traits::Zero; + use std::collections::{BTreeMap, BTreeSet}; + use std::vec; + use subspace_runtime_primitives::SSC; + + type Balances = pallet_balances::Pallet; + type Domains = crate::Pallet; + + pub(crate) fn register_operator( + domain_id: DomainId, + operator_account: ::AccountId, + operator_free_balance: BalanceOf, + operator_stake: BalanceOf, + minimum_nominator_stake: BalanceOf, + signing_key: OperatorPublicKey, + mut nominators: BTreeMap, (BalanceOf, BalanceOf)>, + ) -> (OperatorId, OperatorConfig>) { + nominators.insert(operator_account, (operator_free_balance, operator_stake)); + for nominator in &nominators { + Balances::set_balance(nominator.0, nominator.1 .0); + assert_eq!(Balances::usable_balance(nominator.0), nominator.1 .0); + } + nominators.remove(&operator_account); + + DomainStakingSummary::::insert( + domain_id, + StakingSummary { + current_epoch_index: 0, + current_total_stake: 0, + current_operators: BTreeMap::new(), + next_operators: BTreeSet::new(), + current_epoch_rewards: BTreeMap::new(), + }, + ); + + let operator_config = OperatorConfig { + signing_key, + minimum_nominator_stake, + nomination_tax: Default::default(), + }; + + let res = Domains::register_operator( + RuntimeOrigin::signed(operator_account), + domain_id, + operator_stake, + operator_config.clone(), + ); + assert_ok!(res); + + let operator_id = 0; + for nominator in nominators { + if nominator.1 .1.is_zero() { + continue; + } + + let res = Domains::nominate_operator( + RuntimeOrigin::signed(nominator.0), + operator_id, + nominator.1 .1, + ); + assert_ok!(res); + } + + (operator_id, operator_config) + } + + #[test] + fn test_register_operator() { + let domain_id = DomainId::new(0); + let operator_account = 1; + let operator_free_balance = 1500 * SSC; + let operator_stake = 1000 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, operator_config) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 0, + pair.public(), + BTreeMap::new(), + ); + + assert_eq!(NextOperatorId::::get(), 1); + // operator_id should be 0 and be registered + assert_eq!( + OperatorIdOwner::::get(operator_id).unwrap(), + operator_account + ); + assert_eq!( + Operators::::get(operator_id).unwrap(), + Operator { + signing_key: pair.public(), + current_domain_id: domain_id, + next_domain_id: domain_id, + minimum_nominator_stake: 0, + nomination_tax: Default::default(), + current_total_stake: 0, + current_epoch_rewards: 0, + total_shares: 0, + status: OperatorStatus::Registered, + } + ); + let pending_deposit = + PendingDeposits::::get(operator_id, operator_account).unwrap(); + assert_eq!(pending_deposit, operator_stake); + + let stake_summary = DomainStakingSummary::::get(domain_id).unwrap(); + assert!(stake_summary.next_operators.contains(&operator_id)); + + assert_eq!( + Balances::usable_balance(operator_account), + operator_free_balance - operator_stake - ExistentialDeposit::get() + ); + + // cannot use the locked funds to register a new operator + let res = Domains::register_operator( + RuntimeOrigin::signed(operator_account), + domain_id, + operator_stake, + operator_config, + ); + assert_err!( + res, + Error::::Staking(crate::staking::Error::InsufficientBalance) + ) + }); + } + + #[test] + fn nominate_operator() { + let domain_id = DomainId::new(0); + let operator_account = 1; + let operator_free_balance = 1500 * SSC; + let operator_stake = 1000 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let nominator_account = 2; + let nominator_free_balance = 150 * SSC; + let nominator_stake = 100 * SSC; + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 10 * SSC, + pair.public(), + BTreeMap::from_iter(vec![( + nominator_account, + (nominator_free_balance, nominator_stake), + )]), + ); + + let pending_deposit = PendingDeposits::::get(0, operator_account).unwrap(); + assert_eq!(pending_deposit, operator_stake); + let pending_deposit = PendingDeposits::::get(0, nominator_account).unwrap(); + assert_eq!(pending_deposit, nominator_stake); + + assert_eq!( + Balances::usable_balance(nominator_account), + nominator_free_balance - nominator_stake - ExistentialDeposit::get() + ); + + // another transfer with an existing transfer in place should lead to single + let res = Domains::nominate_operator( + RuntimeOrigin::signed(nominator_account), + operator_id, + 40 * SSC, + ); + assert_ok!(res); + let pending_deposit = PendingDeposits::::get(0, nominator_account).unwrap(); + assert_eq!(pending_deposit, nominator_stake + 40 * SSC); + }); + } + + #[test] + fn switch_domain_operator() { + let old_domain_id = DomainId::new(0); + let new_domain_id = DomainId::new(1); + let operator_account = 1; + let operator_free_balance = 250 * SSC; + let operator_stake = 200 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, _) = register_operator( + old_domain_id, + operator_account, + operator_free_balance, + operator_stake, + 0, + pair.public(), + BTreeMap::new(), + ); + + DomainStakingSummary::::insert( + new_domain_id, + StakingSummary { + current_epoch_index: 0, + current_total_stake: 0, + current_operators: BTreeMap::new(), + next_operators: BTreeSet::new(), + current_epoch_rewards: BTreeMap::new(), + }, + ); + + let res = Domains::switch_domain( + RuntimeOrigin::signed(operator_account), + operator_id, + new_domain_id, + ); + assert_ok!(res); + + let old_domain_stake_summary = + DomainStakingSummary::::get(old_domain_id).unwrap(); + assert!(!old_domain_stake_summary + .next_operators + .contains(&operator_id)); + + let new_domain_stake_summary = + DomainStakingSummary::::get(new_domain_id).unwrap(); + assert!(!new_domain_stake_summary + .next_operators + .contains(&operator_id)); + + let operator = Operators::::get(operator_id).unwrap(); + assert_eq!(operator.current_domain_id, old_domain_id); + assert_eq!(operator.next_domain_id, new_domain_id); + assert_eq!( + PendingOperatorSwitches::::get(old_domain_id).unwrap(), + BTreeSet::from_iter(vec![operator_id]) + ); + + let res = Domains::switch_domain( + RuntimeOrigin::signed(operator_account), + operator_id, + new_domain_id, + ); + assert_err!( + res, + Error::::Staking(crate::staking::Error::PendingOperatorSwitch) + ) + }); + } + + #[test] + fn operator_deregistration() { + let domain_id = DomainId::new(0); + let operator_account = 1; + let operator_stake = 200 * SSC; + let operator_free_balance = 250 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 0, + pair.public(), + BTreeMap::new(), + ); + + let res = + Domains::deregister_operator(RuntimeOrigin::signed(operator_account), operator_id); + assert_ok!(res); + + let domain_stake_summary = DomainStakingSummary::::get(domain_id).unwrap(); + assert!(!domain_stake_summary.next_operators.contains(&operator_id)); + + let operator = Operators::::get(operator_id).unwrap(); + assert_eq!(operator.status, OperatorStatus::Deregistered); + + assert!(PendingOperatorDeregistrations::::get(domain_id) + .unwrap() + .contains(&operator_id)); + + // domain switch will not work since the operator is frozen + let new_domain_id = DomainId::new(1); + DomainStakingSummary::::insert( + new_domain_id, + StakingSummary { + current_epoch_index: 0, + current_total_stake: 0, + current_operators: BTreeMap::new(), + next_operators: BTreeSet::new(), + current_epoch_rewards: BTreeMap::new(), + }, + ); + let res = Domains::switch_domain( + RuntimeOrigin::signed(operator_account), + operator_id, + new_domain_id, + ); + assert_err!( + res, + Error::::Staking(crate::staking::Error::OperatorNotRegistered) + ); + + // nominations will not work since the is frozen + let nominator_account = 100; + let nominator_stake = 100 * SSC; + let res = Domains::nominate_operator( + RuntimeOrigin::signed(nominator_account), + operator_id, + nominator_stake, + ); + assert_err!( + res, + Error::::Staking(crate::staking::Error::OperatorNotRegistered) + ); + }); + } + + type WithdrawWithResult = Vec<(Withdraw>, Result<(), StakingError>)>; + + struct WithdrawParams { + minimum_nominator_stake: BalanceOf, + nominators: Vec<(NominatorId, BalanceOf)>, + operator_reward: BalanceOf, + nominator_id: NominatorId, + withdraws: WithdrawWithResult, + expected_withdraw: Option>>, + } + + fn withdraw_stake(params: WithdrawParams) { + let WithdrawParams { + minimum_nominator_stake, + nominators, + operator_reward, + nominator_id, + withdraws, + expected_withdraw, + } = params; + let domain_id = DomainId::new(0); + let operator_account = 0; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let mut nominators = BTreeMap::from_iter( + nominators + .into_iter() + .map(|(id, bal)| (id, (bal + ExistentialDeposit::get(), bal))) + .collect::, (BalanceOf, BalanceOf))>>(), + ); + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_free_balance, operator_stake) = + nominators.remove(&operator_account).unwrap(); + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + minimum_nominator_stake, + pair.public(), + nominators, + ); + + do_finalize_domain_current_epoch::(domain_id, Zero::zero()).unwrap(); + + if !operator_reward.is_zero() { + do_reward_operators::( + domain_id, + vec![operator_id].into_iter(), + operator_reward, + ) + .unwrap(); + } + + for (withdraw, expected_result) in withdraws { + let res = Domains::withdraw_stake( + RuntimeOrigin::signed(nominator_id), + operator_id, + withdraw, + ); + assert_eq!( + res, + expected_result.map_err(|err| Error::::Staking(err).into()) + ); + } + + assert_eq!( + PendingWithdrawals::::get(operator_id, nominator_id), + expected_withdraw + ); + + if let Some(withdraw) = expected_withdraw { + // finalize pending withdrawals + let domain_block = 100; + let expected_unlock_at = + domain_block + crate::tests::StakeWithdrawalLockingPeriod::get(); + do_finalize_domain_current_epoch::(domain_id, domain_block).unwrap(); + assert_eq!( + PendingWithdrawals::::get(operator_id, nominator_id), + None + ); + + let pending_unlocks_at = + PendingNominatorUnlocks::::get(operator_id, expected_unlock_at).unwrap(); + assert_eq!(pending_unlocks_at.len(), 1); + assert_eq!(pending_unlocks_at[0].nominator_id, nominator_id); + + assert_eq!( + PendingUnlocks::::get((domain_id, expected_unlock_at)), + Some(BTreeSet::from_iter(vec![operator_id])) + ); + + let previous_usable_balance = Balances::usable_balance(nominator_id); + + do_unlock_pending_withdrawals::(domain_id, expected_unlock_at).unwrap(); + + let mut withdrew_amount = pending_unlocks_at[0].balance; + if withdraw == Withdraw::All { + // since there are no holds, ED is not considered untouchable + withdrew_amount += ExistentialDeposit::get(); + } + assert_eq!( + Balances::usable_balance(nominator_id), + previous_usable_balance + withdrew_amount + ) + } + }); + } + + #[test] + fn withdraw_stake_operator_all() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 0, + withdraws: vec![(Withdraw::All, Err(StakingError::MinimumOperatorStake))], + expected_withdraw: None, + }) + } + + #[test] + fn withdraw_stake_operator_below_minimum() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 0, + withdraws: vec![( + Withdraw::Some(65 * SSC), + Err(StakingError::MinimumOperatorStake), + )], + expected_withdraw: None, + }) + } + + #[test] + fn withdraw_stake_operator_below_minimum_no_rewards() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: Zero::zero(), + nominator_id: 0, + withdraws: vec![( + Withdraw::Some(51 * SSC), + Err(StakingError::MinimumOperatorStake), + )], + expected_withdraw: None, + }) + } + + #[test] + fn withdraw_stake_operator_above_minimum() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 0, + withdraws: vec![(Withdraw::Some(64 * SSC), Ok(()))], + expected_withdraw: Some(Withdraw::Some(64 * SSC)), + }) + } + + #[test] + fn withdraw_stake_operator_above_minimum_multiple_withdraws_error() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 0, + withdraws: vec![ + (Withdraw::Some(60 * SSC), Ok(())), + ( + Withdraw::Some(5 * SSC), + Err(StakingError::MinimumOperatorStake), + ), + ], + expected_withdraw: Some(Withdraw::Some(60 * SSC)), + }) + } + + #[test] + fn withdraw_stake_operator_above_minimum_multiple_withdraws() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 0, + withdraws: vec![ + (Withdraw::Some(60 * SSC), Ok(())), + (Withdraw::Some(4 * SSC), Ok(())), + ], + expected_withdraw: Some(Withdraw::Some(64 * SSC)), + }) + } + + #[test] + fn withdraw_stake_operator_above_minimum_no_rewards() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: Zero::zero(), + nominator_id: 0, + withdraws: vec![(Withdraw::Some(49 * SSC), Ok(()))], + expected_withdraw: Some(Withdraw::Some(49 * SSC)), + }) + } + + #[test] + fn withdraw_stake_nominator_below_minimum() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 1, + withdraws: vec![(Withdraw::Some(45 * SSC), Ok(()))], + expected_withdraw: Some(Withdraw::All), + }) + } + + #[test] + fn withdraw_stake_nominator_below_minimum_no_reward() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: Zero::zero(), + nominator_id: 1, + withdraws: vec![(Withdraw::Some(45 * SSC), Ok(()))], + expected_withdraw: Some(Withdraw::All), + }) + } + + #[test] + fn withdraw_stake_nominator_above_minimum() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 1, + withdraws: vec![(Withdraw::Some(44 * SSC), Ok(()))], + expected_withdraw: Some(Withdraw::Some(44 * SSC)), + }) + } + + #[test] + fn withdraw_stake_nominator_above_minimum_multiple_withdraw_all() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 1, + withdraws: vec![ + (Withdraw::Some(40 * SSC), Ok(())), + (Withdraw::Some(5 * SSC), Ok(())), + ], + expected_withdraw: Some(Withdraw::All), + }) + } + + #[test] + fn withdraw_stake_nominator_withdraw_all() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 1, + withdraws: vec![(Withdraw::All, Ok(()))], + expected_withdraw: Some(Withdraw::All), + }) + } + + #[test] + fn withdraw_stake_nominator_withdraw_all_multiple_withdraws_error() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: 20 * SSC, + nominator_id: 1, + withdraws: vec![ + (Withdraw::All, Ok(())), + ( + Withdraw::Some(10 * SSC), + Err(StakingError::ExistingFullWithdraw), + ), + ], + expected_withdraw: Some(Withdraw::All), + }) + } + + #[test] + fn withdraw_stake_nominator_above_minimum_no_rewards() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: Zero::zero(), + nominator_id: 1, + withdraws: vec![(Withdraw::Some(39 * SSC), Ok(()))], + expected_withdraw: Some(Withdraw::Some(39 * SSC)), + }) + } + + #[test] + fn withdraw_stake_nominator_zero_amount() { + withdraw_stake(WithdrawParams { + minimum_nominator_stake: 10 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + operator_reward: Zero::zero(), + nominator_id: 1, + withdraws: vec![(Withdraw::Some(0), Ok(()))], + expected_withdraw: None, + }) + } + + #[test] + fn slash_operator() { + let domain_id = DomainId::new(0); + let operator_account = 1; + let operator_free_balance = 250 * SSC; + let operator_stake = 200 * SSC; + let operator_extra_deposit = 40 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let nominator_account = 2; + let nominator_free_balance = 150 * SSC; + let nominator_stake = 100 * SSC; + let nominator_extra_deposit = 40 * SSC; + + let nominators = vec![ + (operator_account, (operator_free_balance, operator_stake)), + (nominator_account, (nominator_free_balance, nominator_stake)), + ]; + + let unlocking = vec![(operator_account, 10 * SSC), (nominator_account, 10 * SSC)]; + + let deposits = vec![ + (operator_account, operator_extra_deposit), + (nominator_account, nominator_extra_deposit), + ]; + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 10 * SSC, + pair.public(), + BTreeMap::from_iter(nominators), + ); + + do_finalize_domain_current_epoch::(domain_id, Zero::zero()).unwrap(); + + for unlock in &unlocking { + do_withdraw_stake::(operator_id, unlock.0, Withdraw::Some(unlock.1)).unwrap(); + } + do_finalize_domain_current_epoch::(domain_id, Zero::zero()).unwrap(); + + for deposit in deposits { + do_nominate_operator::(operator_id, deposit.0, deposit.1).unwrap(); + } + + do_slash_operators::(vec![operator_id].into_iter()).unwrap(); + + let domain_stake_summary = DomainStakingSummary::::get(domain_id).unwrap(); + assert!(!domain_stake_summary.next_operators.contains(&operator_id)); + + let operator = Operators::::get(operator_id).unwrap(); + assert_eq!(operator.status, OperatorStatus::Slashed); + + let pending_slashes = PendingSlashes::::get(domain_id).unwrap(); + assert!(pending_slashes.contains_key(&operator_id)); + let slash_info = pending_slashes.get(&operator_id).cloned().unwrap(); + for unlock in &unlocking { + assert!(slash_info + .unlocking_nominators + .contains(&PendingNominatorUnlock { + nominator_id: unlock.0, + balance: unlock.1, + })) + } + + do_finalize_slashed_operators::(domain_id).unwrap(); + assert_eq!(PendingSlashes::::get(domain_id), None); + assert_eq!(Operators::::get(operator_id), None); + assert_eq!(OperatorIdOwner::::get(operator_id), None); + + assert_eq!( + Balances::total_balance(&operator_account), + operator_free_balance - operator_stake + ); + assert_eq!( + Balances::total_balance(&nominator_account), + nominator_free_balance - nominator_stake + ); + }); + } + + #[test] + fn nominator_withdraw_while_pending_deposit_exist() { + let domain_id = DomainId::new(0); + let operator_account = 1; + let operator_free_balance = 1500 * SSC; + let operator_stake = 1000 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let nominator_account = 2; + let nominator_free_balance = 150 * SSC; + let nominator_stake = 100 * SSC; + let nominators = BTreeMap::from_iter(vec![( + nominator_account, + (nominator_free_balance, nominator_stake), + )]); + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 100 * SSC, + pair.public(), + nominators, + ); + + let pending_deposit = + PendingDeposits::::get(operator_id, nominator_account).unwrap(); + assert_eq!(pending_deposit, nominator_stake); + + // It is okay to deposit more while there is pending deposit + let additional_deposit = 10 * SSC; + let res = Domains::nominate_operator( + RuntimeOrigin::signed(nominator_account), + operator_id, + additional_deposit, + ); + assert_ok!(res); + let pending_deposit = + PendingDeposits::::get(operator_id, nominator_account).unwrap(); + assert_eq!(pending_deposit, nominator_stake + additional_deposit); + + // Withdraw will be rejected while there is pending deposit + let res = Domains::withdraw_stake( + RuntimeOrigin::signed(nominator_account), + operator_id, + Withdraw::All, + ); + assert_err!( + res, + Error::::Staking(crate::staking::Error::TryWithdrawWithPendingDeposit) + ) + }); + } + + #[test] + fn nominator_deposit_while_pending_withdraw_exist() { + let domain_id = DomainId::new(0); + let operator_account = 1; + let operator_free_balance = 1500 * SSC; + let operator_stake = 1000 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let nominator_account = 2; + let nominator_free_balance = 150 * SSC; + let nominator_stake = 100 * SSC; + let nominators = BTreeMap::from_iter(vec![( + nominator_account, + (nominator_free_balance, nominator_stake), + )]); + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 10 * SSC, + pair.public(), + nominators, + ); + + // Finalize pending deposit + do_finalize_domain_current_epoch::(domain_id, 0).unwrap(); + assert!(!PendingDeposits::::contains_key( + operator_id, + nominator_account, + )); + + // Issue a withdraw + let res = Domains::withdraw_stake( + RuntimeOrigin::signed(nominator_account), + operator_id, + Withdraw::Some(nominator_stake / 3), + ); + assert_ok!(res); + let pending_withdrawal = + PendingWithdrawals::::get(operator_id, nominator_account).unwrap(); + assert_eq!(pending_withdrawal, Withdraw::Some(nominator_stake / 3)); + + // It is okay to withdraw more while there is pending withdraw + let res = Domains::withdraw_stake( + RuntimeOrigin::signed(nominator_account), + operator_id, + Withdraw::Some(nominator_stake / 3), + ); + assert_ok!(res); + let pending_withdrawal = + PendingWithdrawals::::get(operator_id, nominator_account).unwrap(); + assert_eq!(pending_withdrawal, Withdraw::Some(nominator_stake * 2 / 3)); + + // Deposit will be rejected while there is pending withdraw + let res = Domains::nominate_operator( + RuntimeOrigin::signed(nominator_account), + operator_id, + 10 * SSC, + ); + assert_err!( + res, + Error::::Staking(crate::staking::Error::TryDepositWithPendingWithdraw) + ) + }); + } + + #[test] + fn auto_stake_block_rewards() { + let domain_id = DomainId::new(0); + let operator_account = 1; + let operator_free_balance = 1500 * SSC; + let operator_stake = 1000 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let nominator_account = 2; + let nominator_free_balance = 150 * SSC; + let nominator_stake = 100 * SSC; + let nominators = BTreeMap::from_iter(vec![( + nominator_account, + (nominator_free_balance, nominator_stake), + )]); + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 10 * SSC, + pair.public(), + nominators, + ); + + // Finalize pending deposit + do_finalize_domain_current_epoch::(domain_id, 0).unwrap(); + assert!(!PreferredOperator::::contains_key(nominator_account)); + + let res = Domains::auto_stake_block_rewards( + RuntimeOrigin::signed(nominator_account), + operator_id, + ); + assert_ok!(res); + + assert_eq!( + operator_id, + PreferredOperator::::get(nominator_account).unwrap() + ); + + // should auto deposit + Domains::on_block_reward(nominator_account, 10 * SSC); + let deposit = PendingDeposits::::get(operator_id, nominator_account).unwrap(); + assert_eq!(deposit, 10 * SSC); + + // an issues with nominator will lead to removal of preference + Operators::::mutate(operator_id, |maybe_operator| { + let operator = maybe_operator.as_mut().unwrap(); + operator.status = OperatorStatus::Deregistered; + }); + Domains::on_block_reward(nominator_account, 10 * SSC); + + // deposit is still 10 SSC + let deposit = PendingDeposits::::get(operator_id, nominator_account).unwrap(); + assert_eq!(deposit, 10 * SSC); + // no preference + assert!(!PreferredOperator::::contains_key(nominator_account)); + }); + } +} diff --git a/crates/pallet-domains/src/staking_epoch.rs b/crates/pallet-domains/src/staking_epoch.rs new file mode 100644 index 00000000000..d2093548bcb --- /dev/null +++ b/crates/pallet-domains/src/staking_epoch.rs @@ -0,0 +1,1139 @@ +//! Staking epoch transition for domain + +use crate::pallet::{ + DomainStakingSummary, LastEpochStakingDistribution, Nominators, OperatorIdOwner, Operators, + PendingDeposits, PendingNominatorUnlocks, PendingOperatorDeregistrations, + PendingOperatorSwitches, PendingOperatorUnlocks, PendingSlashes, PendingUnlocks, + PendingWithdrawals, PreferredOperator, +}; +use crate::staking::{Error as TransitionError, Nominator, OperatorStatus, Withdraw}; +use crate::{ + BalanceOf, Config, ElectionVerificationParams, FungibleHoldId, HoldIdentifier, NominatorId, +}; +use codec::{Decode, Encode}; +use frame_support::dispatch::TypeInfo; +use frame_support::traits::fungible::{InspectHold, Mutate, MutateHold}; +use frame_support::traits::tokens::{Fortitude, Precision, Restriction}; +use frame_support::PalletError; +use sp_core::Get; +use sp_domains::{DomainId, EpochIndex, OperatorId}; +use sp_runtime::traits::{CheckedAdd, CheckedSub, One, Zero}; +use sp_runtime::Perbill; +use sp_std::collections::btree_map::BTreeMap; +use sp_std::vec::Vec; + +#[derive(TypeInfo, Encode, Decode, PalletError, Debug, PartialEq)] +pub enum Error { + FinalizeSwitchOperatorDomain(TransitionError), + FinalizeOperatorDeregistration(TransitionError), + UnlockOperator(TransitionError), + FinalizeDomainPendingTransfers(TransitionError), + UnlockNominator(TransitionError), + OperatorRewardStaking(TransitionError), + SlashOperator(TransitionError), +} + +/// Finalizes the domain's current epoch and begins the next epoch. +/// Returns true of the epoch indeed was finished. +pub(crate) fn do_finalize_domain_current_epoch( + domain_id: DomainId, + domain_block_number: T::DomainNumber, +) -> Result { + // slash the operators + do_finalize_slashed_operators::(domain_id).map_err(Error::SlashOperator)?; + + // re stake operator's tax from the rewards + operator_take_reward_tax_and_stake::(domain_id)?; + + // finalize any operator switches + do_finalize_switch_operator_domain::(domain_id)?; + + // finalize operator de-registrations + do_finalize_operator_deregistrations::(domain_id, domain_block_number)?; + + // finalize any withdrawals and then deposits + do_finalize_domain_staking::(domain_id, domain_block_number) +} + +/// Unlocks any operators who are de-registering or nominators who are withdrawing staked funds. +pub(crate) fn do_unlock_pending_withdrawals( + domain_id: DomainId, + domain_block_number: T::DomainNumber, +) -> Result<(), Error> { + if let Some(operator_ids) = PendingUnlocks::::take((domain_id, domain_block_number)) { + PendingOperatorUnlocks::::try_mutate(|unlocking_operator_ids| { + for operator_id in operator_ids { + if unlocking_operator_ids.contains(&operator_id) { + unlock_operator::(operator_id)?; + unlocking_operator_ids.remove(&operator_id); + } else { + unlock_nominator_withdrawals::(operator_id, domain_block_number)?; + } + } + + Ok(()) + })?; + } + Ok(()) +} + +/// Operator takes `NominationTax` of the current epoch rewards and stake them. +pub(crate) fn operator_take_reward_tax_and_stake( + domain_id: DomainId, +) -> Result<(), Error> { + DomainStakingSummary::::try_mutate(domain_id, |maybe_domain_stake_summary| { + let stake_summary = maybe_domain_stake_summary + .as_mut() + .ok_or(TransitionError::DomainNotInitialized)?; + + while let Some((operator_id, reward)) = stake_summary.current_epoch_rewards.pop_first() { + Operators::::try_mutate(operator_id, |maybe_operator| { + let operator = match maybe_operator.as_mut() { + // it is possible that operator may have de registered by the time they got rewards + // if not available, skip the operator + None => return Ok(()), + Some(operator) => operator, + }; + + // calculate operator tax, mint the balance, and stake them + let operator_tax = operator.nomination_tax.mul_floor(reward); + if !operator_tax.is_zero() { + let nominator_id = OperatorIdOwner::::get(operator_id) + .ok_or(TransitionError::MissingOperatorOwner)?; + T::Currency::mint_into(&nominator_id, operator_tax) + .map_err(|_| TransitionError::MintBalance)?; + + // add an pending deposit for the operator tax + let updated_total_deposit = + match PendingDeposits::::get(operator_id, nominator_id.clone()) { + None => operator_tax, + Some(existing_deposit) => existing_deposit + .checked_add(&operator_tax) + .ok_or(TransitionError::BalanceOverflow)?, + }; + + crate::staking::hold_pending_deposit::( + &nominator_id, + operator_id, + operator_tax, + )?; + PendingDeposits::::insert(operator_id, nominator_id, updated_total_deposit); + } + + // add remaining rewards to nominators to be distributed during the epoch transition + let rewards = reward + .checked_sub(&operator_tax) + .ok_or(TransitionError::BalanceUnderflow)?; + + operator.current_epoch_rewards = operator + .current_epoch_rewards + .checked_add(&rewards) + .ok_or(TransitionError::BalanceOverflow)?; + + Ok(()) + })?; + } + + Ok(()) + }) + .map_err(Error::OperatorRewardStaking) +} + +/// Add all the switched operators to new domain as next operators. +/// Once the new domain's epoch is complete, operators are included in the next epoch. +fn do_finalize_switch_operator_domain(domain_id: DomainId) -> Result<(), Error> { + if let Some(operators) = PendingOperatorSwitches::::take(domain_id) { + operators.into_iter().try_for_each(|operator_id| { + switch_operator::(operator_id).map_err(Error::FinalizeSwitchOperatorDomain) + })?; + } + + Ok(()) +} + +fn switch_operator(operator_id: OperatorId) -> Result<(), TransitionError> { + Operators::::try_mutate(operator_id, |maybe_operator| { + let operator = maybe_operator + .as_mut() + .ok_or(TransitionError::UnknownOperator)?; + + // operator is not registered, just no-op + if operator.status != OperatorStatus::Registered { + return Ok(()); + } + + operator.current_domain_id = operator.next_domain_id; + DomainStakingSummary::::try_mutate(operator.current_domain_id, |maybe_stake_summary| { + let stake_summary = maybe_stake_summary + .as_mut() + .ok_or(TransitionError::DomainNotInitialized)?; + + stake_summary.next_operators.insert(operator_id); + + Ok(()) + }) + }) +} + +fn do_finalize_operator_deregistrations( + domain_id: DomainId, + domain_block_number: T::DomainNumber, +) -> Result<(), Error> { + let stake_withdrawal_locking_period = T::StakeWithdrawalLockingPeriod::get(); + let unlock_block_number = domain_block_number + .checked_add(&stake_withdrawal_locking_period) + .ok_or(Error::FinalizeOperatorDeregistration( + TransitionError::BlockNumberOverflow, + ))?; + + if let Some(operator_ids) = PendingOperatorDeregistrations::::take(domain_id) { + PendingUnlocks::::mutate( + (domain_id, unlock_block_number), + |maybe_stored_operator_ids| { + let mut stored_operator_ids = maybe_stored_operator_ids.take().unwrap_or_default(); + operator_ids.into_iter().for_each(|operator_id| { + PendingOperatorUnlocks::::append(operator_id); + stored_operator_ids.insert(operator_id); + }); + *maybe_stored_operator_ids = Some(stored_operator_ids) + }, + ) + } + + Ok(()) +} + +fn unlock_operator(operator_id: OperatorId) -> Result<(), Error> { + Operators::::try_mutate_exists(operator_id, |maybe_operator| { + // take the operator so this operator info is removed once we unlock the operator. + let operator = maybe_operator + .take() + .ok_or(TransitionError::UnknownOperator)?; + + let mut total_shares = operator.total_shares; + let mut total_stake = operator + .current_total_stake + .checked_add(&operator.current_epoch_rewards) + .ok_or(TransitionError::BalanceOverflow)?; + + let staked_hold_id = T::HoldIdentifier::staking_staked(operator_id); + Nominators::::drain_prefix(operator_id).try_for_each(|(nominator_id, nominator)| { + let nominator_share = Perbill::from_rational(nominator.shares, total_shares); + let current_locked_amount = + T::Currency::balance_on_hold(&staked_hold_id, &nominator_id); + let nominator_staked_amount = nominator_share + .mul_floor(total_stake) + .max(current_locked_amount); + + let amount_to_mint = nominator_staked_amount + .checked_sub(¤t_locked_amount) + .unwrap_or(Zero::zero()); + + // remove the lock and mint any gains + mint_funds::(&nominator_id, amount_to_mint)?; + T::Currency::release( + &staked_hold_id, + &nominator_id, + current_locked_amount, + Precision::Exact, + ) + .map_err(|_| TransitionError::RemoveLock)?; + + remove_preferred_operator::(nominator_id, &operator_id); + + // update pool's remaining shares and stake + total_shares = total_shares + .checked_sub(&nominator.shares) + .ok_or(TransitionError::ShareUnderflow)?; + total_stake = total_stake + .checked_sub(&nominator_staked_amount) + .ok_or(TransitionError::BalanceUnderflow)?; + + Ok(()) + })?; + + // transfer any remaining amount to treasury + mint_funds::(&T::TreasuryAccount::get(), total_stake)?; + + // remove all of the pending deposits since we initiated withdrawal for all nominators. + let _ = PendingWithdrawals::::clear_prefix(operator_id, u32::MAX, None); + + // remove lock on any remaining deposits, all these deposits are recorded after start + // of new epoch and before operator de-registered + release_pending_deposits::(operator_id)?; + + // remove OperatorOwner Details + OperatorIdOwner::::remove(operator_id); + + Ok(()) + }) + .map_err(Error::UnlockOperator) +} + +fn release_pending_deposits(operator_id: OperatorId) -> Result<(), TransitionError> { + let pending_deposit_hold_id = T::HoldIdentifier::staking_pending_deposit(operator_id); + for (nominator_id, deposit) in PendingDeposits::::drain_prefix(operator_id) { + T::Currency::release( + &pending_deposit_hold_id, + &nominator_id, + deposit, + Precision::Exact, + ) + .map_err(|_| TransitionError::RemoveLock)?; + } + + Ok(()) +} + +fn unlock_nominator_withdrawals( + operator_id: OperatorId, + domain_block_number: T::DomainNumber, +) -> Result<(), Error> { + let pending_unlock_hold_id = T::HoldIdentifier::staking_pending_unlock(operator_id); + match PendingNominatorUnlocks::::take(operator_id, domain_block_number) { + None => Ok(()), + Some(withdrawals) => withdrawals.into_iter().try_for_each(|withdrawal| { + let total_unlocking_balance = + T::Currency::balance_on_hold(&pending_unlock_hold_id, &withdrawal.nominator_id); + T::Currency::release( + &pending_unlock_hold_id, + &withdrawal.nominator_id, + total_unlocking_balance, + Precision::Exact, + ) + .map_err(|_| TransitionError::RemoveLock)?; + + let remaining_unlocking_balance = total_unlocking_balance + .checked_sub(&withdrawal.balance) + .ok_or(TransitionError::BalanceUnderflow)?; + + T::Currency::hold( + &pending_unlock_hold_id, + &withdrawal.nominator_id, + remaining_unlocking_balance, + ) + .map_err(|_| TransitionError::UpdateLock)?; + + Ok(()) + }), + } + .map_err(Error::UnlockNominator) +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct PendingNominatorUnlock { + pub nominator_id: NominatorId, + pub balance: Balance, +} + +pub(crate) fn do_finalize_domain_staking( + domain_id: DomainId, + domain_block_number: T::DomainNumber, +) -> Result { + DomainStakingSummary::::try_mutate(domain_id, |maybe_stake_summary| { + let stake_summary = maybe_stake_summary + .as_mut() + .ok_or(TransitionError::DomainNotInitialized)?; + + let next_epoch = stake_summary + .current_epoch_index + .checked_add(One::one()) + .ok_or(TransitionError::EpochOverflow)?; + + let mut total_domain_stake = BalanceOf::::zero(); + let mut current_operators = BTreeMap::new(); + for next_operator_id in &stake_summary.next_operators { + let operator_stake = + finalize_operator_pending_transfers::(*next_operator_id, domain_block_number)?; + + total_domain_stake = total_domain_stake + .checked_add(&operator_stake) + .ok_or(TransitionError::BalanceOverflow)?; + current_operators.insert(*next_operator_id, operator_stake); + } + + let election_verification_params = ElectionVerificationParams { + operators: stake_summary.current_operators.clone(), + total_domain_stake: stake_summary.current_total_stake, + }; + + LastEpochStakingDistribution::::insert(domain_id, election_verification_params); + + let previous_epoch = stake_summary.current_epoch_index; + stake_summary.current_epoch_index = next_epoch; + stake_summary.current_total_stake = total_domain_stake; + stake_summary.current_operators = current_operators; + + Ok(previous_epoch) + }) + .map_err(Error::FinalizeDomainPendingTransfers) +} + +fn finalize_operator_pending_transfers( + operator_id: OperatorId, + domain_block_number: T::DomainNumber, +) -> Result, TransitionError> { + Operators::::try_mutate(operator_id, |maybe_operator| { + let operator = maybe_operator + .as_mut() + .ok_or(TransitionError::UnknownOperator)?; + + if operator.status != OperatorStatus::Registered { + return Err(TransitionError::OperatorNotRegistered); + } + + let mut total_stake = operator + .current_total_stake + .checked_add(&operator.current_epoch_rewards) + .ok_or(TransitionError::BalanceOverflow)?; + + let mut total_shares = operator.total_shares; + finalize_pending_withdrawals::( + operator.current_domain_id, + operator_id, + &mut total_stake, + &mut total_shares, + domain_block_number, + )?; + + finalize_pending_deposits::(operator_id, &mut total_stake, &mut total_shares)?; + + // update operator state + operator.total_shares = total_shares; + operator.current_total_stake = total_stake; + operator.current_epoch_rewards = Zero::zero(); + + Ok(total_stake) + }) +} + +fn finalize_pending_withdrawals( + domain_id: DomainId, + operator_id: OperatorId, + total_stake: &mut BalanceOf, + total_shares: &mut T::Share, + domain_block_number: T::DomainNumber, +) -> Result<(), TransitionError> { + let staked_hold_id = T::HoldIdentifier::staking_staked(operator_id); + let pending_unlock_hold_id = T::HoldIdentifier::staking_pending_unlock(operator_id); + let unlock_block_number = domain_block_number + .checked_add(&T::StakeWithdrawalLockingPeriod::get()) + .ok_or(TransitionError::BlockNumberOverflow)?; + PendingWithdrawals::::drain_prefix(operator_id).try_for_each(|(nominator_id, withdraw)| { + finalize_nominator_withdrawal::( + domain_id, + operator_id, + &staked_hold_id, + &pending_unlock_hold_id, + nominator_id, + withdraw, + total_stake, + total_shares, + unlock_block_number, + ) + }) +} + +pub(crate) fn mint_funds( + account_id: &T::AccountId, + amount_to_mint: BalanceOf, +) -> Result<(), TransitionError> { + if !amount_to_mint.is_zero() { + T::Currency::mint_into(account_id, amount_to_mint) + .map_err(|_| TransitionError::MintBalance)?; + } + + Ok(()) +} + +/// Remove the preference if the operator id matches +fn remove_preferred_operator(nominator_id: NominatorId, operator_id: &OperatorId) { + PreferredOperator::::mutate_exists(nominator_id, |maybe_preferred_operator| { + if let Some(preferred_operator_id) = maybe_preferred_operator { + if preferred_operator_id == operator_id { + maybe_preferred_operator.take(); + } + } + }); +} + +#[allow(clippy::too_many_arguments)] +fn finalize_nominator_withdrawal( + domain_id: DomainId, + operator_id: OperatorId, + staked_hold_id: &FungibleHoldId, + pending_unlock_hold_id: &FungibleHoldId, + nominator_id: NominatorId, + withdraw: Withdraw>, + total_stake: &mut BalanceOf, + total_shares: &mut T::Share, + unlock_at: T::DomainNumber, +) -> Result<(), TransitionError> { + let (withdrew_stake, withdrew_shares) = match withdraw { + Withdraw::All => { + let nominator = Nominators::::take(operator_id, nominator_id.clone()) + .ok_or(TransitionError::UnknownNominator)?; + + let nominator_share = Perbill::from_rational(nominator.shares, *total_shares); + let locked_amount = T::Currency::balance_on_hold(staked_hold_id, &nominator_id); + let nominator_staked_amount = + nominator_share.mul_floor(*total_stake).max(locked_amount); + + let amount_to_mint = nominator_staked_amount + .checked_sub(&locked_amount) + .unwrap_or(Zero::zero()); + + // mint any gains and then remove staked freeze lock + mint_funds::(&nominator_id, amount_to_mint)?; + T::Currency::release( + staked_hold_id, + &nominator_id, + locked_amount, + Precision::Exact, + ) + .map_err(|_| TransitionError::RemoveLock)?; + + remove_preferred_operator::(nominator_id.clone(), &operator_id); + (nominator_staked_amount, nominator.shares) + } + Withdraw::Some(withdraw_amount) => { + Nominators::::try_mutate(operator_id, nominator_id.clone(), |maybe_nominator| { + let nominator = maybe_nominator + .as_mut() + .ok_or(TransitionError::UnknownNominator)?; + + // calculate nominator total staked value + let nominator_share = Perbill::from_rational(nominator.shares, *total_shares); + let old_locked_amount = T::Currency::balance_on_hold(staked_hold_id, &nominator_id); + let nominator_staked_amount = nominator_share + .mul_floor(*total_stake) + .max(old_locked_amount); + + // mint any gains + let amount_to_mint = nominator_staked_amount + .checked_sub(&old_locked_amount) + .unwrap_or(Zero::zero()); + mint_funds::(&nominator_id, amount_to_mint)?; + + // calculate the shares to be deducted from the withdraw amount and adjust + let share_per_ssc = + Perbill::from_rational(*total_shares, T::Share::from(*total_stake)); + let shares_to_withdraw = T::Share::from(share_per_ssc.mul_ceil(withdraw_amount)); + nominator.shares = nominator + .shares + .checked_sub(&shares_to_withdraw) + .ok_or(TransitionError::ShareUnderflow)?; + + // and update the staked lock to hold remaining staked amount + let remaining_staked_amount = nominator_staked_amount + .checked_sub(&withdraw_amount) + .ok_or(TransitionError::BalanceUnderflow)?; + T::Currency::release( + staked_hold_id, + &nominator_id, + old_locked_amount, + Precision::Exact, + ) + .map_err(|_| TransitionError::UpdateLock)?; + T::Currency::hold(staked_hold_id, &nominator_id, remaining_staked_amount) + .map_err(|_| TransitionError::UpdateLock)?; + + Ok((withdraw_amount, shares_to_withdraw)) + })? + } + }; + + // lock the pending withdrawal under withdrawal lock id + T::Currency::hold(pending_unlock_hold_id, &nominator_id, withdrew_stake) + .map_err(|_| TransitionError::BalanceFreeze)?; + + PendingNominatorUnlocks::::append( + operator_id, + unlock_at, + PendingNominatorUnlock { + nominator_id, + balance: withdrew_stake, + }, + ); + + let mut operator_ids = PendingUnlocks::::get((domain_id, unlock_at)).unwrap_or_default(); + operator_ids.insert(operator_id); + PendingUnlocks::::insert((domain_id, unlock_at), operator_ids); + + // update pool's remaining shares and stake + *total_shares = total_shares + .checked_sub(&withdrew_shares) + .ok_or(TransitionError::ShareUnderflow)?; + *total_stake = total_stake + .checked_sub(&withdrew_stake) + .ok_or(TransitionError::BalanceUnderflow)?; + + Ok(()) +} + +fn finalize_pending_deposits( + operator_id: OperatorId, + total_stake: &mut BalanceOf, + total_shares: &mut T::Share, +) -> Result<(), TransitionError> { + let staked_hold_id = T::HoldIdentifier::staking_staked(operator_id); + let pending_deposits_hold_id = T::HoldIdentifier::staking_pending_deposit(operator_id); + PendingDeposits::::drain_prefix(operator_id).try_for_each(|(nominator_id, deposit)| { + finalize_nominator_deposit::( + operator_id, + nominator_id, + deposit, + total_stake, + total_shares, + &pending_deposits_hold_id, + &staked_hold_id, + ) + }) +} + +fn finalize_nominator_deposit( + operator_id: OperatorId, + nominator_id: NominatorId, + deposit: BalanceOf, + total_stake: &mut BalanceOf, + total_shares: &mut T::Share, + pending_deposit_hold_id: &FungibleHoldId, + staked_hold_id: &FungibleHoldId, +) -> Result<(), TransitionError> { + // calculate the shares to be added to nominator + let share_per_ssc = if total_shares.is_zero() { + // share price is 1 for first nominator + Perbill::one() + } else { + Perbill::from_rational(*total_shares, T::Share::from(*total_stake)) + }; + + let shares_to_deposit = T::Share::from(share_per_ssc.mul_floor(deposit)); + let mut nominator = + Nominators::::get(operator_id, nominator_id.clone()).unwrap_or(Nominator { + shares: Zero::zero(), + }); + + nominator.shares = nominator + .shares + .checked_add(&shares_to_deposit) + .ok_or(TransitionError::ShareOverflow)?; + + // move lock from pending deposit to staked + T::Currency::release( + pending_deposit_hold_id, + &nominator_id, + deposit, + Precision::Exact, + ) + .map_err(|_| TransitionError::RemoveLock)?; + T::Currency::hold(staked_hold_id, &nominator_id, deposit) + .map_err(|_| crate::staking::Error::BalanceFreeze)?; + + // Update nominator + Nominators::::insert(operator_id, nominator_id, nominator); + + // update operator's remaining shares and stake + *total_shares = total_shares + .checked_add(&shares_to_deposit) + .ok_or(TransitionError::ShareOverflow)?; + *total_stake = total_stake + .checked_add(&deposit) + .ok_or(TransitionError::BalanceOverflow)?; + + Ok(()) +} + +pub(crate) fn do_finalize_slashed_operators( + domain_id: DomainId, +) -> Result<(), TransitionError> { + for (operator_id, slash_info) in PendingSlashes::::take(domain_id).unwrap_or_default() { + Operators::::try_mutate_exists(operator_id, |maybe_operator| { + // take the operator so this operator info is removed once we slash the operator. + let operator = maybe_operator + .take() + .ok_or(TransitionError::UnknownOperator)?; + + // remove OperatorOwner Details + OperatorIdOwner::::remove(operator_id); + + let staked_hold_id = T::HoldIdentifier::staking_staked(operator_id); + let mut total_stake = operator + .current_total_stake + .checked_add(&operator.current_epoch_rewards) + .ok_or(TransitionError::BalanceOverflow)?; + + // transfer all the staked funds to the treasury account + // any gains will be minted to treasury account + Nominators::::drain_prefix(operator_id).try_for_each(|(nominator_id, _)| { + let locked_amount = T::Currency::balance_on_hold(&staked_hold_id, &nominator_id); + T::Currency::transfer_on_hold( + &staked_hold_id, + &nominator_id, + &T::TreasuryAccount::get(), + locked_amount, + Precision::Exact, + Restriction::Free, + Fortitude::Force, + ) + .map_err(|_| TransitionError::RemoveLock)?; + + total_stake = total_stake + .checked_sub(&locked_amount) + .ok_or(TransitionError::BalanceUnderflow)?; + + remove_preferred_operator::(nominator_id, &operator_id); + + Ok(()) + })?; + + // mint any gains to treasury account + mint_funds::(&T::TreasuryAccount::get(), total_stake)?; + + // remove all of the pending withdrawals as the operator and all its nominators are slashed. + let _ = PendingWithdrawals::::clear_prefix(operator_id, u32::MAX, None); + + // transfer all the unlocking withdrawals to treasury account + let unlocking_nominators = slash_info + .unlocking_nominators + .into_iter() + .map(|pending_unlock| pending_unlock.nominator_id); + + let pending_withdrawal_freeze_id = + T::HoldIdentifier::staking_pending_unlock(operator_id); + for unlocking_nominator in unlocking_nominators { + let unlocking_balance = T::Currency::balance_on_hold( + &pending_withdrawal_freeze_id, + &unlocking_nominator, + ); + T::Currency::transfer_on_hold( + &pending_withdrawal_freeze_id, + &unlocking_nominator, + &T::TreasuryAccount::get(), + unlocking_balance, + Precision::Exact, + Restriction::Free, + Fortitude::Force, + ) + .map_err(|_| TransitionError::RemoveLock)?; + } + + // remove any nominator deposits + // all these are new deposits recorded after start of new epoch and before operator was slashed + release_pending_deposits::(operator_id) + })?; + } + + Ok(()) +} + +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)] +pub struct PendingOperatorSlashInfo { + pub unlocking_nominators: Vec>, +} + +#[cfg(test)] +mod tests { + use crate::pallet::{ + DomainStakingSummary, LastEpochStakingDistribution, Nominators, OperatorIdOwner, Operators, + PendingDeposits, PendingOperatorSwitches, PendingOperatorUnlocks, PendingUnlocks, + PendingWithdrawals, PreferredOperator, + }; + use crate::staking::tests::register_operator; + use crate::staking::{ + do_auto_stake_block_rewards, do_deregister_operator, do_nominate_operator, + do_reward_operators, StakingSummary, + }; + use crate::staking_epoch::{ + do_finalize_domain_current_epoch, do_finalize_operator_deregistrations, + do_finalize_switch_operator_domain, do_unlock_pending_withdrawals, + operator_take_reward_tax_and_stake, + }; + use crate::tests::{new_test_ext, RuntimeOrigin, Test}; + use crate::{BalanceOf, Config, HoldIdentifier as FreezeIdentifierT, NominatorId}; + use frame_support::assert_ok; + use frame_support::traits::fungible::InspectHold; + use sp_core::{Pair, U256}; + use sp_domains::{DomainId, OperatorPair}; + use sp_runtime::traits::Zero; + use sp_runtime::Percent; + use std::collections::{BTreeMap, BTreeSet}; + use subspace_runtime_primitives::SSC; + + type Balances = pallet_balances::Pallet; + type Domains = crate::Pallet; + + #[test] + fn finalize_operator_domain_switch() { + let old_domain_id = DomainId::new(0); + let new_domain_id = DomainId::new(1); + let operator_account = 1; + let operator_free_balance = 200 * SSC; + let operator_stake = 100 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, _) = register_operator( + old_domain_id, + operator_account, + operator_free_balance, + operator_stake, + 100 * SSC, + pair.public(), + BTreeMap::new(), + ); + + DomainStakingSummary::::insert( + new_domain_id, + StakingSummary { + current_epoch_index: 0, + current_total_stake: 0, + current_operators: BTreeMap::new(), + next_operators: BTreeSet::new(), + current_epoch_rewards: BTreeMap::new(), + }, + ); + let res = Domains::switch_domain( + RuntimeOrigin::signed(operator_account), + operator_id, + new_domain_id, + ); + assert_ok!(res); + + assert!(do_finalize_switch_operator_domain::(old_domain_id).is_ok()); + + let operator = Operators::::get(operator_id).unwrap(); + assert_eq!(operator.current_domain_id, new_domain_id); + assert_eq!(operator.next_domain_id, new_domain_id); + assert_eq!(PendingOperatorSwitches::::get(old_domain_id), None); + + let domain_stake_summary = DomainStakingSummary::::get(new_domain_id).unwrap(); + assert!(domain_stake_summary.next_operators.contains(&operator_id)); + }); + } + + fn unlock_operator( + nominators: Vec<(NominatorId, BalanceOf)>, + pending_deposits: Vec<(NominatorId, BalanceOf)>, + rewards: BalanceOf, + ) { + let domain_id = DomainId::new(0); + let operator_account = 1; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + let minimum_free_balance = 10 * SSC; + let mut nominators = BTreeMap::from_iter( + nominators + .into_iter() + .map(|(id, balance)| (id, (balance + minimum_free_balance, balance))) + .collect::, (BalanceOf, BalanceOf))>>(), + ); + + for pending_deposit in &pending_deposits { + let staked_deposit = nominators + .get(&pending_deposit.0) + .cloned() + .unwrap_or((minimum_free_balance, 0)); + let total_balance = staked_deposit.0 + pending_deposit.1; + nominators.insert(pending_deposit.0, (total_balance, staked_deposit.1)); + } + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_free_balance, operator_stake) = + nominators.remove(&operator_account).unwrap(); + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 10 * SSC, + pair.public(), + BTreeMap::from_iter(nominators.clone()), + ); + + do_finalize_domain_current_epoch::(domain_id, Zero::zero()).unwrap(); + + // add pending deposits + for pending_deposit in &pending_deposits { + do_nominate_operator::(operator_id, pending_deposit.0, pending_deposit.1) + .unwrap(); + } + + if !rewards.is_zero() { + do_reward_operators::(domain_id, vec![operator_id].into_iter(), rewards) + .unwrap() + } + + for nominator in &nominators { + if !nominator.1 .1.is_zero() { + do_auto_stake_block_rewards::(*nominator.0, operator_id).unwrap(); + assert_eq!( + operator_id, + PreferredOperator::::get(nominator.0).unwrap() + ) + } + } + + // de-register operator + do_deregister_operator::(operator_account, operator_id).unwrap(); + + // finalize and add to pending operator unlocks + let domain_block_number = 100; + do_finalize_domain_current_epoch::(domain_id, domain_block_number).unwrap(); + + // unlock operator + let unlock_at = 100 + crate::tests::StakeWithdrawalLockingPeriod::get(); + assert!(do_unlock_pending_withdrawals::(domain_id, unlock_at).is_ok()); + + let hold_id = crate::tests::HoldIdentifier::staking_pending_unlock(operator_id); + for nominator in &nominators { + let required_minimum_free_balance = nominator.1 .0; + assert_eq!(Nominators::::get(operator_id, nominator.0), None); + assert!(Balances::usable_balance(nominator.0) >= required_minimum_free_balance); + assert_eq!( + Balances::balance_on_hold(&hold_id, nominator.0), + Zero::zero() + ); + assert_eq!( + PendingDeposits::::get(operator_id, *nominator.0), + None + ); + assert_eq!( + PendingWithdrawals::::get(operator_id, *nominator.0), + None + ); + + if !nominator.1 .0.is_zero() { + assert!(!PreferredOperator::::contains_key(nominator.0)) + } + } + + assert_eq!(Operators::::get(operator_id), None); + assert_eq!(OperatorIdOwner::::get(operator_id), None); + assert!(PendingOperatorUnlocks::::get().is_empty()) + }); + } + + #[test] + fn unlock_operator_with_no_rewards() { + unlock_operator( + vec![(1, 150 * SSC), (2, 50 * SSC), (3, 10 * SSC)], + vec![(2, 10 * SSC), (4, 10 * SSC)], + 0, + ); + } + + #[test] + fn unlock_operator_with_rewards() { + unlock_operator( + vec![(1, 150 * SSC), (2, 50 * SSC), (3, 10 * SSC)], + vec![(2, 10 * SSC), (4, 10 * SSC)], + 20 * SSC, + ); + } + + #[test] + fn finalize_operator_deregistration() { + let domain_id = DomainId::new(0); + let operator_account = 1; + let operator_free_balance = 200 * SSC; + let operator_stake = 100 * SSC; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 10 * SSC, + pair.public(), + BTreeMap::new(), + ); + + do_finalize_domain_current_epoch::(domain_id, Zero::zero()).unwrap(); + + do_deregister_operator::(operator_account, operator_id).unwrap(); + + let current_consensus_block_number = 100; + assert!(do_finalize_operator_deregistrations::( + domain_id, + current_consensus_block_number, + ) + .is_ok()); + + let expected_unlock = 100 + crate::tests::StakeWithdrawalLockingPeriod::get(); + assert_eq!( + PendingOperatorUnlocks::::get(), + BTreeSet::from_iter(vec![operator_id]) + ); + assert_eq!( + PendingUnlocks::::get((domain_id, expected_unlock)), + Some(BTreeSet::from_iter(vec![operator_id])) + ) + }); + } + + struct FinalizeDomainParams { + total_stake: BalanceOf, + rewards: BalanceOf, + nominators: Vec<(NominatorId, ::Share)>, + deposits: Vec<(NominatorId, BalanceOf)>, + } + + fn finalize_domain_epoch(params: FinalizeDomainParams) { + let domain_id = DomainId::new(0); + let operator_account = 0; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + + let FinalizeDomainParams { + total_stake, + rewards, + nominators, + deposits, + } = params; + + let minimum_free_balance = 10 * SSC; + let mut nominators = BTreeMap::from_iter( + nominators + .into_iter() + .map(|(id, balance)| (id, (balance + minimum_free_balance, balance))) + .collect::, (BalanceOf, BalanceOf))>>(), + ); + + for deposit in &deposits { + let values = nominators + .remove(&deposit.0) + .unwrap_or((minimum_free_balance, 0)); + nominators.insert(deposit.0, (deposit.1 + values.0, values.1)); + } + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_free_balance, operator_stake) = + nominators.remove(&operator_account).unwrap(); + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 10 * SSC, + pair.public(), + BTreeMap::from_iter(nominators), + ); + + do_finalize_domain_current_epoch::(domain_id, Zero::zero()).unwrap(); + + let mut total_deposit = BalanceOf::::zero(); + for deposit in &deposits { + do_nominate_operator::(operator_id, deposit.0, deposit.1).unwrap(); + total_deposit += deposit.1; + } + + if !rewards.is_zero() { + do_reward_operators::(domain_id, vec![operator_id].into_iter(), rewards) + .unwrap(); + } + + let current_block = 100; + do_finalize_domain_current_epoch::(domain_id, current_block).unwrap(); + for deposit in deposits { + assert_eq!(PendingDeposits::::get(operator_id, deposit.0), None); + Nominators::::contains_key(operator_id, deposit.0); + } + + // should also store the previous epoch details in-block + let election_params = LastEpochStakingDistribution::::get(domain_id).unwrap(); + assert_eq!( + election_params.operators, + BTreeMap::from_iter(vec![(operator_id, total_stake)]) + ); + assert_eq!(election_params.total_domain_stake, total_stake); + + let total_updated_stake = total_stake + total_deposit + rewards; + let operator = Operators::::get(operator_id).unwrap(); + assert_eq!(operator.current_total_stake, total_updated_stake); + assert_eq!(operator.current_epoch_rewards, Zero::zero()); + + let domain_stake_summary = DomainStakingSummary::::get(domain_id).unwrap(); + assert_eq!( + domain_stake_summary.current_total_stake, + total_updated_stake + ); + // epoch should be 2 since we did 3 epoch transitions + assert_eq!(domain_stake_summary.current_epoch_index, 2); + }); + } + + #[test] + fn finalize_domain_epoch_no_rewards() { + finalize_domain_epoch(FinalizeDomainParams { + total_stake: 210 * SSC, + rewards: 0, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + deposits: vec![(1, 50 * SSC), (3, 10 * SSC)], + }) + } + + #[test] + fn finalize_domain_epoch_with_rewards() { + finalize_domain_epoch(FinalizeDomainParams { + total_stake: 210 * SSC, + rewards: 20 * SSC, + nominators: vec![(0, 150 * SSC), (1, 50 * SSC), (2, 10 * SSC)], + deposits: vec![(1, 50 * SSC), (3, 10 * SSC)], + }) + } + + #[test] + fn operator_tax_and_staking() { + let domain_id = DomainId::new(0); + let operator_account = 1; + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); + let operator_rewards = 10 * SSC; + let mut nominators = + BTreeMap::from_iter(vec![(1, (110 * SSC, 100 * SSC)), (2, (60 * SSC, 50 * SSC))]); + + let mut ext = new_test_ext(); + ext.execute_with(|| { + let (operator_free_balance, operator_stake) = + nominators.remove(&operator_account).unwrap(); + let (operator_id, _) = register_operator( + domain_id, + operator_account, + operator_free_balance, + operator_stake, + 10 * SSC, + pair.public(), + BTreeMap::from_iter(nominators), + ); + + do_finalize_domain_current_epoch::(domain_id, Zero::zero()).unwrap(); + + // 10% tax + let nomination_tax = Percent::from_parts(10); + let mut operator = Operators::::get(operator_id).unwrap(); + operator.nomination_tax = nomination_tax; + Operators::::insert(operator_id, operator); + let expected_operator_tax = nomination_tax.mul_ceil(operator_rewards); + + do_reward_operators::(domain_id, vec![operator_id].into_iter(), operator_rewards) + .unwrap(); + + operator_take_reward_tax_and_stake::(domain_id).unwrap(); + let operator = Operators::::get(operator_id).unwrap(); + assert_eq!( + operator.current_epoch_rewards, + (10 * SSC - expected_operator_tax) + ); + + let deposit = PendingDeposits::::get(operator_id, operator_account).unwrap(); + assert_eq!(deposit, expected_operator_tax); + + let domain_stake_summary = DomainStakingSummary::::get(domain_id).unwrap(); + assert!(domain_stake_summary.current_epoch_rewards.is_empty()) + }); + } +} diff --git a/crates/pallet-domains/src/tests.rs b/crates/pallet-domains/src/tests.rs index fc633538c08..c6c017a7402 100644 --- a/crates/pallet-domains/src/tests.rs +++ b/crates/pallet-domains/src/tests.rs @@ -1,23 +1,34 @@ -use crate::{self as pallet_domains}; +use crate::domain_registry::{DomainConfig, DomainObject}; +use crate::{self as pallet_domains, BundleError, DomainRegistry, FungibleHoldId}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::traits::{ConstU16, ConstU32, ConstU64, Hooks}; -use frame_support::{assert_noop, assert_ok, parameter_types}; -use pallet_settlement::{PrimaryBlockHash, ReceiptVotes}; +use frame_support::weights::Weight; +use frame_support::{assert_err, assert_ok, parameter_types, PalletId}; +use scale_info::TypeInfo; use sp_core::crypto::Pair; use sp_core::{Get, H256, U256}; -use sp_domains::fraud_proof::{ExecutionPhase, FraudProof, InvalidStateTransitionProof}; -use sp_domains::transaction::InvalidTransactionCode; +use sp_domains::merkle_tree::MerkleTree; use sp_domains::{ - create_dummy_bundle_with_receipts_generic, BundleHeader, BundleSolution, DomainId, - ExecutionReceipt, ExecutorPair, OpaqueBundle, SealedBundleHeader, + BundleHeader, DomainId, DomainInstanceData, DomainsHoldIdentifier, ExecutionReceipt, + GenerateGenesisStateRoot, OpaqueBundle, OperatorId, OperatorPair, ProofOfElection, + SealedBundleHeader, StakingHoldIdentifier, }; use sp_runtime::testing::Header; -use sp_runtime::traits::{BlakeTwo256, IdentityLookup, ValidateUnsigned}; -use sp_runtime::transaction_validity::TransactionValidityError; -use sp_trie::StorageProof; +use sp_runtime::traits::{AccountIdConversion, BlakeTwo256, Hash as HashT, IdentityLookup}; +use sp_runtime::OpaqueExtrinsic; use std::sync::atomic::{AtomicU64, Ordering}; +use subspace_core_primitives::U256 as P256; +use subspace_runtime_primitives::SSC; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; +type Balance = u128; + +// TODO: Remove when DomainRegistry is usable. +const DOMAIN_ID: DomainId = DomainId::new(0); + +// Operator id used for testing +const OPERATOR_ID: OperatorId = 0u64; frame_support::construct_runtime!( pub struct Test @@ -27,7 +38,7 @@ frame_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system, - Settlement: pallet_settlement, + Balances: pallet_balances, Domains: pallet_domains, } ); @@ -53,7 +64,7 @@ impl frame_system::Config for Test { type BlockHashCount = ConstU64<2>; type Version = (); type PalletInfo = PalletInfo; - type AccountData = (); + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); type SystemWeightInfo = (); @@ -63,8 +74,16 @@ impl frame_system::Config for Test { } parameter_types! { - pub const ReceiptsPruningDepth: BlockNumber = 256; pub const MaximumReceiptDrift: BlockNumber = 128; + pub const InitialDomainTxRange: u64 = 10; + pub const DomainTxRangeAdjustmentInterval: u64 = 100; + pub const DomainRuntimeUpgradeDelay: BlockNumber = 100; + pub const MaxBundlesPerBlock: u32 = 10; + pub const MaxDomainBlockSize: u32 = 1024 * 1024; + pub const MaxDomainBlockWeight: Weight = Weight::from_parts(1024 * 1024, 0); + pub const DomainInstantiationDeposit: Balance = 100; + pub const MaxDomainNameLength: u32 = 16; + pub const BlockTreePruningDepth: u32 = 256; } static CONFIRMATION_DEPTH_K: AtomicU64 = AtomicU64::new(10); @@ -87,17 +106,89 @@ impl Get for ConfirmationDepthK { } } -impl pallet_domains::Config for Test { +#[derive( + PartialEq, Eq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, Ord, PartialOrd, Copy, Debug, +)] +pub enum HoldIdentifier { + Domains(DomainsHoldIdentifier), +} + +impl pallet_domains::HoldIdentifier for HoldIdentifier { + fn staking_pending_deposit(operator_id: OperatorId) -> FungibleHoldId { + Self::Domains(DomainsHoldIdentifier::Staking( + StakingHoldIdentifier::PendingDeposit(operator_id), + )) + } + + fn staking_staked(operator_id: OperatorId) -> FungibleHoldId { + Self::Domains(DomainsHoldIdentifier::Staking( + StakingHoldIdentifier::Staked(operator_id), + )) + } + + fn staking_pending_unlock(operator_id: OperatorId) -> FungibleHoldId { + Self::Domains(DomainsHoldIdentifier::Staking( + StakingHoldIdentifier::PendingUnlock(operator_id), + )) + } + + fn domain_instantiation_id(domain_id: DomainId) -> FungibleHoldId { + Self::Domains(DomainsHoldIdentifier::DomainInstantiation(domain_id)) + } +} + +parameter_types! { + pub const MaxHolds: u32 = 10; + pub const ExistentialDeposit: Balance = 1; +} + +impl pallet_balances::Config for Test { + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = Balance; + type DustRemoval = (); type RuntimeEvent = RuntimeEvent; - type ConfirmationDepthK = ConfirmationDepthK; - type WeightInfo = pallet_domains::weights::SubstrateWeight; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type FreezeIdentifier = (); + type MaxFreezes = (); + type RuntimeHoldReason = HoldIdentifier; + type MaxHolds = MaxHolds; } -impl pallet_settlement::Config for Test { +parameter_types! { + pub const MinOperatorStake: Balance = 100 * SSC; + pub const StakeWithdrawalLockingPeriod: BlockNumber = 5; + pub const StakeEpochDuration: BlockNumber = 5; + pub TreasuryAccount: u64 = PalletId(*b"treasury").into_account_truncating(); + pub const BlockReward: Balance = 10 * SSC; +} + +impl pallet_domains::Config for Test { type RuntimeEvent = RuntimeEvent; - type DomainHash = H256; - type MaximumReceiptDrift = MaximumReceiptDrift; - type ReceiptsPruningDepth = ReceiptsPruningDepth; + type DomainNumber = BlockNumber; + type DomainHash = sp_core::H256; + type ConfirmationDepthK = ConfirmationDepthK; + type DomainRuntimeUpgradeDelay = DomainRuntimeUpgradeDelay; + type Currency = Balances; + type HoldIdentifier = HoldIdentifier; + type WeightInfo = pallet_domains::weights::SubstrateWeight; + type InitialDomainTxRange = InitialDomainTxRange; + type DomainTxRangeAdjustmentInterval = DomainTxRangeAdjustmentInterval; + type MinOperatorStake = MinOperatorStake; + type MaxDomainBlockSize = MaxDomainBlockSize; + type MaxDomainBlockWeight = MaxDomainBlockWeight; + type MaxBundlesPerBlock = MaxBundlesPerBlock; + type DomainInstantiationDeposit = DomainInstantiationDeposit; + type MaxDomainNameLength = MaxDomainNameLength; + type Share = Balance; + type BlockTreePruningDepth = BlockTreePruningDepth; + type StakeWithdrawalLockingPeriod = StakeWithdrawalLockingPeriod; + type StakeEpochDuration = StakeEpochDuration; + type TreasuryAccount = TreasuryAccount; + type DomainBlockReward = BlockReward; } pub(crate) fn new_test_ext() -> sp_io::TestExternalities { @@ -108,300 +199,111 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { t.into() } -fn create_dummy_receipt( - primary_number: BlockNumber, - primary_hash: Hash, -) -> ExecutionReceipt { +pub(crate) fn create_dummy_receipt( + block_number: BlockNumber, + consensus_block_hash: Hash, + parent_domain_block_receipt_hash: H256, + block_extrinsics_roots: Vec, +) -> ExecutionReceipt { + let (execution_trace, execution_trace_root) = if block_number == 0 { + (Vec::new(), Default::default()) + } else { + let execution_trace = vec![H256::random(), H256::random()]; + let trace: Vec<[u8; 32]> = execution_trace + .iter() + .map(|r| r.encode().try_into().expect("H256 must fit into [u8; 32]")) + .collect(); + let execution_trace_root = MerkleTree::from_leaves(trace.as_slice()) + .root() + .expect("Compute merkle root of trace should success") + .into(); + (execution_trace, execution_trace_root) + }; ExecutionReceipt { - primary_number, - primary_hash, - domain_hash: H256::random(), - trace: if primary_number == 0 { - Vec::new() - } else { - vec![H256::random(), H256::random()] - }, - trace_root: Default::default(), + domain_block_number: block_number, + domain_block_hash: H256::random(), + parent_domain_block_receipt_hash, + consensus_block_number: block_number, + consensus_block_hash, + invalid_bundles: Vec::new(), + block_extrinsics_roots, + final_state_root: Default::default(), + execution_trace, + execution_trace_root, + total_rewards: 0, } } fn create_dummy_bundle( domain_id: DomainId, - primary_number: BlockNumber, - primary_hash: Hash, -) -> OpaqueBundle { - let pair = ExecutorPair::from_seed(&U256::from(0u32).into()); + block_number: BlockNumber, + consensus_block_hash: Hash, +) -> OpaqueBundle { + let execution_receipt = create_dummy_receipt( + block_number, + consensus_block_hash, + Default::default(), + vec![], + ); + create_dummy_bundle_with_receipts( + domain_id, + OPERATOR_ID, + Default::default(), + execution_receipt, + ) +} - let execution_receipt = create_dummy_receipt(primary_number, primary_hash); +pub(crate) fn create_dummy_bundle_with_receipts( + domain_id: DomainId, + operator_id: OperatorId, + bundle_extrinsics_root: H256, + receipt: ExecutionReceipt, +) -> OpaqueBundle { + let pair = OperatorPair::from_seed(&U256::from(0u32).into()); let header = BundleHeader { - primary_number, - primary_hash, - slot_number: 0u64, - extrinsics_root: Default::default(), - bundle_solution: BundleSolution::dummy(domain_id, pair.public()), + proof_of_election: ProofOfElection::dummy(domain_id, operator_id), + receipt, + bundle_size: 0u32, + estimated_bundle_weight: Default::default(), + bundle_extrinsics_root, }; let signature = pair.sign(header.hash().as_ref()); OpaqueBundle { sealed_header: SealedBundleHeader::new(header, signature), - receipt: execution_receipt, extrinsics: Vec::new(), } } -fn create_dummy_bundle_with_receipts( - domain_id: DomainId, - primary_number: BlockNumber, - primary_hash: Hash, - receipt: ExecutionReceipt, -) -> OpaqueBundle { - create_dummy_bundle_with_receipts_generic::( - domain_id, - primary_number, - primary_hash, - receipt, - ) -} - -#[test] -fn submit_execution_receipt_incrementally_should_work() { - let (dummy_bundles, block_hashes): (Vec<_>, Vec<_>) = (1u64..=256u64 + 3u64) - .map(|n| { - let primary_hash = Hash::random(); - ( - create_dummy_bundle(DomainId::SYSTEM, n, primary_hash), - primary_hash, - ) - }) - .unzip(); - - let receipt_hash = |block_number| { - dummy_bundles[block_number as usize - 1] - .clone() - .receipt - .hash() - }; - - new_test_ext().execute_with(|| { - let genesis_hash = frame_system::Pallet::::block_hash(0); - PrimaryBlockHash::::insert(DomainId::SYSTEM, 0, genesis_hash); - Settlement::initialize_genesis_receipt(DomainId::SYSTEM, genesis_hash); - - (0..256).for_each(|index| { - let block_hash = block_hashes[index]; - PrimaryBlockHash::::insert(DomainId::SYSTEM, (index + 1) as u64, block_hash); - - assert_ok!(pallet_domains::Pallet::::pre_dispatch( - &pallet_domains::Call::submit_bundle { - opaque_bundle: dummy_bundles[index].clone() - } - )); - assert_ok!(Domains::submit_bundle( - RuntimeOrigin::none(), - dummy_bundles[index].clone(), - )); - - assert_eq!(Settlement::finalized_receipt_number(DomainId::SYSTEM), 0); - }); - - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash(257)).is_none()); - assert_ok!(Domains::submit_bundle( - RuntimeOrigin::none(), - dummy_bundles[256].clone(), - )); - // The oldest ER should be deleted. - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash(1)).is_none()); - assert_eq!(Settlement::finalized_receipt_number(DomainId::SYSTEM), 1); - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash(257)).is_some()); - - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash(2)).is_some()); - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash(258)).is_none()); - - assert_noop!( - pallet_domains::Pallet::::pre_dispatch(&pallet_domains::Call::submit_bundle { - opaque_bundle: dummy_bundles[258].clone() - }), - TransactionValidityError::Invalid(InvalidTransactionCode::ExecutionReceipt.into()) - ); - - assert_ok!(Domains::submit_bundle( - RuntimeOrigin::none(), - dummy_bundles[257].clone(), - )); - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash(2)).is_none()); - assert_eq!(Settlement::finalized_receipt_number(DomainId::SYSTEM), 2); - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash(258)).is_some()); - }); -} - -#[test] -fn submit_execution_receipt_with_huge_gap_should_work() { - let (dummy_bundles, block_hashes): (Vec<_>, Vec<_>) = (1u64..=256u64 + 2) - .map(|n| { - let primary_hash = Hash::random(); - ( - create_dummy_bundle(DomainId::SYSTEM, n, primary_hash), - primary_hash, - ) - }) - .unzip(); - - let run_to_block = |n: BlockNumber, block_hashes: Vec| { - System::initialize(&1, &System::parent_hash(), &Default::default()); - >::on_initialize(1); - System::finalize(); - - for b in 2..=n { - System::set_block_number(b); - System::initialize(&b, &block_hashes[b as usize - 2], &Default::default()); - >::on_initialize(b); - System::finalize(); - } - }; - - new_test_ext().execute_with(|| { - run_to_block(256 + 2, block_hashes); - - // Submit ancient receipts still works even the block hash mapping for [1, 256) - // in System has been removed. - assert!(!frame_system::BlockHash::::contains_key(1)); - assert!(!frame_system::BlockHash::::contains_key(255)); - (0..255).for_each(|index| { - assert_ok!(Domains::submit_bundle( - RuntimeOrigin::none(), - dummy_bundles[index].clone(), - )); - }); - - // Reaching the receipts pruning depth, block hash mapping will be pruned as well. - assert!(PrimaryBlockHash::::contains_key(DomainId::SYSTEM, 0)); - assert_ok!(Domains::submit_bundle( - RuntimeOrigin::none(), - dummy_bundles[255].clone(), - )); - assert!(!PrimaryBlockHash::::contains_key(DomainId::SYSTEM, 0)); - - assert!(PrimaryBlockHash::::contains_key(DomainId::SYSTEM, 1)); - assert_ok!(Domains::submit_bundle( - RuntimeOrigin::none(), - dummy_bundles[256].clone(), - )); - assert!(!PrimaryBlockHash::::contains_key(DomainId::SYSTEM, 1)); - - assert!(PrimaryBlockHash::::contains_key(DomainId::SYSTEM, 2)); - assert_ok!(Domains::submit_bundle( - RuntimeOrigin::none(), - dummy_bundles[257].clone(), - )); - assert!(!PrimaryBlockHash::::contains_key(DomainId::SYSTEM, 2)); - assert_eq!(Settlement::finalized_receipt_number(DomainId::SYSTEM), 2); - }); -} - -#[test] -fn only_system_domain_receipts_are_maintained_on_primary_chain() { - let primary_hash = Hash::random(); - - let system_receipt = create_dummy_receipt(1, primary_hash); - let system_bundle = create_dummy_bundle_with_receipts( - DomainId::SYSTEM, - 1, - primary_hash, - system_receipt.clone(), - ); - let core_receipt = create_dummy_receipt(1, primary_hash); - let core_bundle = - create_dummy_bundle_with_receipts(DomainId::new(1), 1, primary_hash, core_receipt.clone()); +pub(crate) struct GenesisStateRootGenerater; - new_test_ext().execute_with(|| { - assert_ok!(Domains::submit_bundle(RuntimeOrigin::none(), system_bundle)); - assert_ok!(Domains::submit_bundle(RuntimeOrigin::none(), core_bundle)); - // Only system domain receipt is tracked, core domain receipt is ignored. - assert!(Settlement::receipts(DomainId::SYSTEM, system_receipt.hash()).is_some()); - assert!(Settlement::receipts(DomainId::SYSTEM, core_receipt.hash()).is_none()); - }); +impl GenerateGenesisStateRoot for GenesisStateRootGenerater { + fn generate_genesis_state_root( + &self, + _domain_id: DomainId, + _domain_instance_data: DomainInstanceData, + ) -> Option { + Some(Default::default()) + } } -#[test] -fn submit_fraud_proof_should_work() { - let (dummy_bundles, block_hashes): (Vec<_>, Vec<_>) = (1u64..=256u64) - .map(|n| { - let primary_hash = Hash::random(); - ( - create_dummy_bundle(DomainId::SYSTEM, n, primary_hash), - primary_hash, - ) - }) - .unzip(); - - let dummy_proof = |domain_id| { - FraudProof::InvalidStateTransition(InvalidStateTransitionProof { - domain_id, - bad_receipt_hash: Hash::random(), - parent_number: 99, - primary_parent_hash: block_hashes[98], - pre_state_root: H256::random(), - post_state_root: H256::random(), - proof: StorageProof::empty(), - execution_phase: ExecutionPhase::FinalizeBlock { - total_extrinsics: 0, - }, - }) - }; - - new_test_ext().execute_with(|| { - (0usize..256usize).for_each(|index| { - let block_hash = block_hashes[index]; - PrimaryBlockHash::::insert(DomainId::SYSTEM, (index + 1) as u64, block_hash); - - assert_ok!(Domains::submit_bundle( - RuntimeOrigin::none(), - dummy_bundles[index].clone(), - )); - - let receipt_hash = dummy_bundles[index].clone().receipt.hash(); - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash).is_some()); - let mut votes = ReceiptVotes::::iter_prefix((DomainId::SYSTEM, block_hash)); - assert_eq!(votes.next(), Some((receipt_hash, 1))); - assert_eq!(votes.next(), None); - }); - - // non-system domain fraud proof should be ignored - assert_ok!(Domains::submit_fraud_proof( - RuntimeOrigin::none(), - dummy_proof(DomainId::new(100)) - )); - assert_eq!(Domains::head_receipt_number(), 256); - let receipt_hash = dummy_bundles[255].clone().receipt.hash(); - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash).is_some()); +pub(crate) struct ReadRuntimeVersion(pub Vec); - assert_ok!(Domains::submit_fraud_proof( - RuntimeOrigin::none(), - dummy_proof(DomainId::SYSTEM) - )); - assert_eq!(Settlement::head_receipt_number(DomainId::SYSTEM), 99); - let receipt_hash = dummy_bundles[98].clone().receipt.hash(); - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash).is_some()); - // Receipts for block [100, 256] should be removed as being invalid. - (100..=256).for_each(|block_number| { - let receipt_hash = dummy_bundles[block_number as usize - 1] - .clone() - .receipt - .hash(); - assert!(Settlement::receipts(DomainId::SYSTEM, receipt_hash).is_none()); - let block_hash = block_hashes[block_number as usize - 1]; - assert!( - ReceiptVotes::::iter_prefix((DomainId::SYSTEM, block_hash)) - .next() - .is_none() - ); - }); - }); +impl sp_core::traits::ReadRuntimeVersion for ReadRuntimeVersion { + fn read_runtime_version( + &self, + _wasm_code: &[u8], + _ext: &mut dyn sp_externalities::Externalities, + ) -> Result, String> { + Ok(self.0.clone()) + } } +// TODO: Unblock once bundle producer election v2 is finished. #[test] +#[ignore] fn test_stale_bundle_should_be_rejected() { // Small macro in order to be more readable. // @@ -427,14 +329,14 @@ fn test_stale_bundle_should_be_rejected() { ConfirmationDepthK::set(1); new_test_ext().execute_with(|| { // Create a bundle at genesis block -> #1 - let bundle0 = create_dummy_bundle(DomainId::SYSTEM, 0, System::parent_hash()); + let bundle0 = create_dummy_bundle(DOMAIN_ID, 0, System::parent_hash()); System::initialize(&1, &System::parent_hash(), &Default::default()); >::on_initialize(1); assert_not_stale!(pallet_domains::Pallet::::validate_bundle(&bundle0)); // Create a bundle at block #1 -> #2 let block_hash1 = Hash::random(); - let bundle1 = create_dummy_bundle(DomainId::SYSTEM, 1, block_hash1); + let bundle1 = create_dummy_bundle(DOMAIN_ID, 1, block_hash1); System::initialize(&2, &block_hash1, &Default::default()); >::on_initialize(2); assert_stale!(pallet_domains::Pallet::::validate_bundle(&bundle0)); @@ -444,14 +346,14 @@ fn test_stale_bundle_should_be_rejected() { ConfirmationDepthK::set(2); new_test_ext().execute_with(|| { // Create a bundle at genesis block -> #1 - let bundle0 = create_dummy_bundle(DomainId::SYSTEM, 0, System::parent_hash()); + let bundle0 = create_dummy_bundle(DOMAIN_ID, 0, System::parent_hash()); System::initialize(&1, &System::parent_hash(), &Default::default()); >::on_initialize(1); assert_not_stale!(pallet_domains::Pallet::::validate_bundle(&bundle0)); // Create a bundle at block #1 -> #2 let block_hash1 = Hash::random(); - let bundle1 = create_dummy_bundle(DomainId::SYSTEM, 1, block_hash1); + let bundle1 = create_dummy_bundle(DOMAIN_ID, 1, block_hash1); System::initialize(&2, &block_hash1, &Default::default()); >::on_initialize(2); assert_stale!(pallet_domains::Pallet::::validate_bundle(&bundle0)); @@ -459,7 +361,7 @@ fn test_stale_bundle_should_be_rejected() { // Create a bundle at block #2 -> #3 let block_hash2 = Hash::random(); - let bundle2 = create_dummy_bundle(DomainId::SYSTEM, 2, block_hash2); + let bundle2 = create_dummy_bundle(DOMAIN_ID, 2, block_hash2); System::initialize(&3, &block_hash2, &Default::default()); >::on_initialize(3); assert_stale!(pallet_domains::Pallet::::validate_bundle(&bundle0)); @@ -471,10 +373,10 @@ fn test_stale_bundle_should_be_rejected() { let confirmation_depth_k = ConfirmationDepthK::get(); let (dummy_bundles, block_hashes): (Vec<_>, Vec<_>) = (1..=confirmation_depth_k + 2) .map(|n| { - let primary_hash = Hash::random(); + let consensus_block_hash = Hash::random(); ( - create_dummy_bundle(DomainId::SYSTEM, n, primary_hash), - primary_hash, + create_dummy_bundle(DOMAIN_ID, n, consensus_block_hash), + consensus_block_hash, ) }) .unzip(); @@ -502,3 +404,156 @@ fn test_stale_bundle_should_be_rejected() { } }); } + +#[test] +fn test_calculate_tx_range() { + let cur_tx_range = P256::from(400_u64); + + assert_eq!( + cur_tx_range, + pallet_domains::calculate_tx_range(cur_tx_range, 0, 1000) + ); + assert_eq!( + cur_tx_range, + pallet_domains::calculate_tx_range(cur_tx_range, 1000, 0) + ); + + // Lower bound of 1/4 * current range + assert_eq!( + cur_tx_range.checked_div(&P256::from(4_u64)).unwrap(), + pallet_domains::calculate_tx_range(cur_tx_range, 10, 1000) + ); + + // Upper bound of 4 * current range + assert_eq!( + cur_tx_range.checked_mul(&P256::from(4_u64)).unwrap(), + pallet_domains::calculate_tx_range(cur_tx_range, 8000, 1000) + ); + + // For anything else in the [0.25, 4.0] range, the change ratio should be same as + // actual / expected + assert_eq!( + cur_tx_range.checked_div(&P256::from(4_u64)).unwrap(), + pallet_domains::calculate_tx_range(cur_tx_range, 250, 1000) + ); + assert_eq!( + cur_tx_range.checked_div(&P256::from(2_u64)).unwrap(), + pallet_domains::calculate_tx_range(cur_tx_range, 500, 1000) + ); + assert_eq!( + cur_tx_range.checked_mul(&P256::from(1_u64)).unwrap(), + pallet_domains::calculate_tx_range(cur_tx_range, 1000, 1000) + ); + assert_eq!( + cur_tx_range.checked_mul(&P256::from(2_u64)).unwrap(), + pallet_domains::calculate_tx_range(cur_tx_range, 2000, 1000) + ); + assert_eq!( + cur_tx_range.checked_mul(&P256::from(3_u64)).unwrap(), + pallet_domains::calculate_tx_range(cur_tx_range, 3000, 1000) + ); + assert_eq!( + cur_tx_range.checked_mul(&P256::from(4_u64)).unwrap(), + pallet_domains::calculate_tx_range(cur_tx_range, 4000, 1000) + ); +} + +#[test] +fn test_bundle_fromat_verification() { + let opaque_extrinsic = |dest: u64, value: u128| -> OpaqueExtrinsic { + UncheckedExtrinsic { + signature: None, + function: RuntimeCall::Balances(pallet_balances::Call::transfer { dest, value }), + } + .into() + }; + new_test_ext().execute_with(|| { + let domain_id = DomainId::new(0); + let max_extrincis_count = 10; + let max_block_size = opaque_extrinsic(0, 0).encoded_size() as u32 * max_extrincis_count; + let domain_config = DomainConfig { + domain_name: b"test-domain".to_vec(), + runtime_id: 0u32, + max_block_size, + max_block_weight: Weight::MAX, + bundle_slot_probability: (1, 1), + target_bundles_per_block: 1, + }; + let domain_obj = DomainObject { + owner_account_id: Default::default(), + created_at: Default::default(), + genesis_receipt_hash: Default::default(), + domain_config, + raw_genesis_config: None, + }; + DomainRegistry::::insert(domain_id, domain_obj); + + let mut valid_bundle = create_dummy_bundle(DOMAIN_ID, 0, System::parent_hash()); + valid_bundle.extrinsics.push(opaque_extrinsic(1, 1)); + valid_bundle.extrinsics.push(opaque_extrinsic(2, 2)); + valid_bundle.sealed_header.header.bundle_extrinsics_root = BlakeTwo256::ordered_trie_root( + valid_bundle + .extrinsics + .iter() + .map(|xt| xt.encode()) + .collect(), + sp_core::storage::StateVersion::V1, + ); + assert_ok!(pallet_domains::Pallet::::check_bundle_size( + &valid_bundle, + max_block_size + )); + assert_ok!(pallet_domains::Pallet::::check_extrinsics_root( + &valid_bundle + )); + + // Bundle exceed max size + let mut too_large_bundle = valid_bundle.clone(); + for i in 0..max_extrincis_count { + too_large_bundle + .extrinsics + .push(opaque_extrinsic(i as u64, i as u128)); + } + assert_err!( + pallet_domains::Pallet::::check_bundle_size(&too_large_bundle, max_block_size), + BundleError::BundleTooLarge + ); + + // Bundle with wrong value of `bundle_extrinsics_root` + let mut invalid_extrinsic_root_bundle = valid_bundle.clone(); + invalid_extrinsic_root_bundle + .sealed_header + .header + .bundle_extrinsics_root = H256::random(); + assert_err!( + pallet_domains::Pallet::::check_extrinsics_root(&invalid_extrinsic_root_bundle), + BundleError::InvalidExtrinsicRoot + ); + + // Bundle with wrong value of `extrinsics` + let mut invalid_extrinsic_root_bundle = valid_bundle.clone(); + invalid_extrinsic_root_bundle.extrinsics[0] = opaque_extrinsic(3, 3); + assert_err!( + pallet_domains::Pallet::::check_extrinsics_root(&invalid_extrinsic_root_bundle), + BundleError::InvalidExtrinsicRoot + ); + + // Bundle with addtional extrinsic + let mut invalid_extrinsic_root_bundle = valid_bundle.clone(); + invalid_extrinsic_root_bundle + .extrinsics + .push(opaque_extrinsic(4, 4)); + assert_err!( + pallet_domains::Pallet::::check_extrinsics_root(&invalid_extrinsic_root_bundle), + BundleError::InvalidExtrinsicRoot + ); + + // Bundle with missing extrinsic + let mut invalid_extrinsic_root_bundle = valid_bundle; + invalid_extrinsic_root_bundle.extrinsics.pop(); + assert_err!( + pallet_domains::Pallet::::check_extrinsics_root(&invalid_extrinsic_root_bundle), + BundleError::InvalidExtrinsicRoot + ); + }); +} diff --git a/crates/pallet-feeds/Cargo.toml b/crates/pallet-feeds/Cargo.toml index ea7a806970f..572b2c03f47 100644 --- a/crates/pallet-feeds/Cargo.toml +++ b/crates/pallet-feeds/Cargo.toml @@ -13,19 +13,19 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } log = { version = "0.4.19", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } [dev-dependencies] serde = "1.0.159" -sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/crates/pallet-grandpa-finality-verifier/Cargo.toml b/crates/pallet-grandpa-finality-verifier/Cargo.toml index eaddd42cb40..563eac125db 100644 --- a/crates/pallet-grandpa-finality-verifier/Cargo.toml +++ b/crates/pallet-grandpa-finality-verifier/Cargo.toml @@ -10,7 +10,7 @@ description = "Pallet to verify GRANDPA finality proofs for Substrate based chai readme = "README.md" [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false } finality-grandpa = { version = "0.16.1", default-features = false } log = { version = "0.4.19", default-features = false } num-traits = { version = "0.2.15", default-features = false } @@ -19,18 +19,18 @@ serde = { version = "1.0.159", optional = true } # Substrate Dependencies -frame-support = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -frame-system = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-consensus-grandpa = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-core = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-runtime = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-std = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-trie = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } +frame-support = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +frame-system = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-consensus-grandpa = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-core = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-runtime = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-std = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-trie = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } [dev-dependencies] ed25519-dalek = { version = "1.0", default-features = false, features = ["u64_backend"] } -sp-io = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-application-crypto = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-io = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-application-crypto = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/crates/pallet-object-store/Cargo.toml b/crates/pallet-object-store/Cargo.toml index 69976f2b34c..e61233796f7 100644 --- a/crates/pallet-object-store/Cargo.toml +++ b/crates/pallet-object-store/Cargo.toml @@ -13,20 +13,20 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } hex = { version = "0.4.3", default-features = false, features = ["alloc"] } log = { version = "0.4.19", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } [dev-dependencies] serde = "1.0.159" -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/crates/pallet-offences-subspace/Cargo.toml b/crates/pallet-offences-subspace/Cargo.toml index 4a32d8f67a5..dcda0633edf 100644 --- a/crates/pallet-offences-subspace/Cargo.toml +++ b/crates/pallet-offences-subspace/Cargo.toml @@ -13,18 +13,18 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } log = { version = "0.4.19", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } sp-consensus-subspace = { version = "0.1.0", default-features = false, path = "../sp-consensus-subspace" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [dev-dependencies] -sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } schnorrkel = "0.9.1" [features] diff --git a/crates/pallet-rewards/Cargo.toml b/crates/pallet-rewards/Cargo.toml index 87c3ed88382..4b7ac382383 100644 --- a/crates/pallet-rewards/Cargo.toml +++ b/crates/pallet-rewards/Cargo.toml @@ -18,11 +18,11 @@ include = [ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } [features] diff --git a/crates/pallet-rewards/src/lib.rs b/crates/pallet-rewards/src/lib.rs index 0b45ee60dfb..2cc87fd4a57 100644 --- a/crates/pallet-rewards/src/lib.rs +++ b/crates/pallet-rewards/src/lib.rs @@ -30,9 +30,18 @@ pub trait WeightInfo { fn on_initialize() -> Weight; } +/// Hooks to notify when there are any rewards for specific account. +pub trait OnReward { + fn on_reward(account: AccountId, reward: Balance); +} + +impl OnReward for () { + fn on_reward(_account: AccountId, _reward: Balance) {} +} + #[frame_support::pallet] mod pallet { - use super::WeightInfo; + use super::{OnReward, WeightInfo}; use frame_support::pallet_prelude::*; use frame_support::traits::Currency; use frame_system::pallet_prelude::*; @@ -65,6 +74,8 @@ mod pallet { type FindVotingRewardAddresses: FindVotingRewardAddresses; type WeightInfo: WeightInfo; + + type OnReward: OnReward>; } /// `pallet-rewards` events @@ -102,6 +113,7 @@ impl Pallet { if let Some(block_author) = T::FindBlockRewardAddress::find_block_reward_address() { let reward = T::BlockReward::get(); T::Currency::deposit_creating(&block_author, reward); + T::OnReward::on_reward(block_author.clone(), reward); Self::deposit_event(Event::BlockReward { block_author, @@ -115,6 +127,7 @@ impl Pallet { for voter in T::FindVotingRewardAddresses::find_voting_reward_addresses() { T::Currency::deposit_creating(&voter, reward); + T::OnReward::on_reward(voter.clone(), reward); Self::deposit_event(Event::VoteReward { voter, reward }); } diff --git a/crates/pallet-runtime-configs/Cargo.toml b/crates/pallet-runtime-configs/Cargo.toml index f828e800fb1..89c30533192 100644 --- a/crates/pallet-runtime-configs/Cargo.toml +++ b/crates/pallet-runtime-configs/Cargo.toml @@ -16,11 +16,11 @@ include = [ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/crates/pallet-runtime-configs/src/lib.rs b/crates/pallet-runtime-configs/src/lib.rs index 03657d4eaf7..fde39c664b1 100644 --- a/crates/pallet-runtime-configs/src/lib.rs +++ b/crates/pallet-runtime-configs/src/lib.rs @@ -27,10 +27,10 @@ mod pallet { #[pallet::pallet] pub struct Pallet(_); - /// Whether to disable the executor calls. + /// Whether to disable the calls in pallet-domains. #[pallet::storage] - #[pallet::getter(fn enable_executor)] - pub type EnableExecutor = StorageValue<_, bool, ValueQuery>; + #[pallet::getter(fn enable_domains)] + pub type EnableDomains = StorageValue<_, bool, ValueQuery>; /// Whether to disable the normal balances transfer calls. #[pallet::storage] @@ -45,7 +45,7 @@ mod pallet { #[pallet::genesis_config] pub struct GenesisConfig { - pub enable_executor: bool, + pub enable_domains: bool, pub enable_transfer: bool, pub confirmation_depth_k: T::BlockNumber, } @@ -54,7 +54,7 @@ mod pallet { #[inline] fn default() -> Self { Self { - enable_executor: false, + enable_domains: false, enable_transfer: false, confirmation_depth_k: T::BlockNumber::from(100u32), } @@ -65,7 +65,7 @@ mod pallet { impl GenesisBuild for GenesisConfig { fn build(&self) { let Self { - enable_executor, + enable_domains, enable_transfer, confirmation_depth_k, } = self; @@ -75,7 +75,7 @@ mod pallet { "ConfirmationDepthK can not be zero" ); - >::put(enable_executor); + >::put(enable_domains); >::put(enable_transfer); >::put(confirmation_depth_k); } diff --git a/crates/pallet-settlement/Cargo.toml b/crates/pallet-settlement/Cargo.toml deleted file mode 100644 index 389850abe1a..00000000000 --- a/crates/pallet-settlement/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "pallet-settlement" -version = "0.1.0" -authors = ["Subspace Labs "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://subspace.network" -repository = "https://github.com/subspace/subspace" -description = "Subspace receipts pallet" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -log = { version = "0.4.19", default-features = false } -scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } - -[features] -default = ["std"] -std = [ - "frame-support/std", - "frame-system/std", - "log/std", - "sp-core/std", - "sp-domains/std", - "sp-runtime/std", - "sp-std/std", -] -try-runtime = ["frame-support/try-runtime"] diff --git a/crates/pallet-settlement/src/lib.rs b/crates/pallet-settlement/src/lib.rs deleted file mode 100644 index 21b14b4f77d..00000000000 --- a/crates/pallet-settlement/src/lib.rs +++ /dev/null @@ -1,488 +0,0 @@ -// Copyright (C) 2022 Subspace Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! # Settlement Pallet -//! -//! This pallet provides the general common settlement functions needed by the consensus chain -//! and system domain, which mainly includes tracking the receipts and handling the fraud proofs -//! from the chain they secure. - -#![cfg_attr(not(feature = "std"), no_std)] - -use codec::{Decode, Encode}; -use frame_support::ensure; -use frame_support::traits::Get; -pub use pallet::*; -use sp_core::H256; -use sp_domains::fraud_proof::{FraudProof, InvalidStateTransitionProof, InvalidTransactionProof}; -use sp_domains::{DomainId, ExecutionReceipt}; -use sp_runtime::traits::{CheckedSub, One, Saturating, Zero}; -use sp_std::vec::Vec; - -#[frame_support::pallet] -mod pallet { - use frame_support::pallet_prelude::{StorageMap, StorageNMap, StorageValue, ValueQuery, *}; - use frame_support::PalletError; - use frame_system::pallet_prelude::*; - use sp_core::H256; - use sp_domains::{DomainId, ExecutionReceipt}; - use sp_runtime::traits::{CheckEqual, MaybeDisplay, SimpleBitOps}; - use sp_std::fmt::Debug; - use sp_std::vec::Vec; - - #[pallet::config] - pub trait Config: frame_system::Config { - /// Domain block hash type. - type DomainHash: Parameter - + Member - + MaybeSerializeDeserialize - + Debug - + MaybeDisplay - + SimpleBitOps - + Ord - + Default - + Copy - + CheckEqual - + sp_std::hash::Hash - + AsRef<[u8]> - + AsMut<[u8]> - + MaxEncodedLen - + Into; - - type RuntimeEvent: From> + IsType<::RuntimeEvent>; - - /// Maximum execution receipt drift. - /// - /// If the primary number of an execution receipt plus the maximum drift is bigger than the - /// best execution chain number, this receipt will be rejected as being too far in the - /// future. - #[pallet::constant] - type MaximumReceiptDrift: Get; - - /// Number of execution receipts kept in the state. - /// - /// This parameter specifies the fraud proof period. The challenge window is closed once - /// the receipts are pruned. - #[pallet::constant] - type ReceiptsPruningDepth: Get; - } - - #[pallet::pallet] - #[pallet::without_storage_info] - pub struct Pallet(_); - - /// Map of primary block number to primary block hash for tracking bounded receipts per domain. - /// - /// The oldest block hash will be pruned once the oldest receipt is pruned. However, if a - /// domain stalls, i.e., no receipts are included in the domain's parent chain for a long time, - /// the corresponding entry will grow indefinitely. - /// - /// TODO: there is a pitfall that any stalled domain can lead to an ubounded runtime storage - /// growth. - #[pallet::storage] - #[pallet::getter(fn primary_hash)] - pub type PrimaryBlockHash = StorageDoubleMap< - _, - Twox64Concat, - DomainId, - Twox64Concat, - T::BlockNumber, - T::Hash, - OptionQuery, - >; - - /// Stores the latest block number for which Execution receipt(s) are available for a given Domain. - #[pallet::storage] - #[pallet::getter(fn receipt_head)] - pub(super) type HeadReceiptNumber = - StorageMap<_, Twox64Concat, DomainId, T::BlockNumber, ValueQuery>; - - /// Block number of the oldest receipt stored in the state. - #[pallet::storage] - pub(super) type OldestReceiptNumber = - StorageMap<_, Twox64Concat, DomainId, T::BlockNumber, ValueQuery>; - - /// Mapping from the receipt hash to the corresponding verified execution receipt. - /// - /// The capacity of receipts stored in the state is [`Config::ReceiptsPruningDepth`], the older - /// ones will be pruned once the size of receipts exceeds this number. - #[pallet::storage] - #[pallet::getter(fn receipts)] - pub(super) type Receipts = StorageDoubleMap< - _, - Twox64Concat, - DomainId, - Twox64Concat, - H256, - ExecutionReceipt, - OptionQuery, - >; - - /// Mapping for tracking the receipt votes. - /// - /// (domain_id, domain_block_hash, receipt_hash) -> receipt_count - #[pallet::storage] - pub type ReceiptVotes = StorageNMap< - _, - ( - NMapKey, - NMapKey, - NMapKey, - ), - u32, - ValueQuery, - >; - - /// Mapping for tracking the domain state roots. - /// - /// (domain_id, domain_block_number, domain_block_hash) -> domain_state_root - #[pallet::storage] - #[pallet::getter(fn state_root)] - pub(super) type StateRoots = StorageNMap< - _, - ( - NMapKey, - NMapKey, - NMapKey, - ), - T::DomainHash, - OptionQuery, - >; - - /// Fraud proof processed successfully in current block. - #[pallet::storage] - pub(super) type SuccessfulFraudProofs = StorageValue<_, Vec, ValueQuery>; - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(_now: BlockNumberFor) -> Weight { - SuccessfulFraudProofs::::kill(); - T::DbWeight::get().writes(1) - } - } - - #[pallet::event] - #[pallet::generate_deposit(pub (super) fn deposit_event)] - pub enum Event { - /// A new domain receipt. - NewDomainReceipt { - domain_id: DomainId, - primary_number: T::BlockNumber, - primary_hash: T::Hash, - }, - /// An invalid state transition proof was processed. - InvalidStateTransitionProofProcessed { - domain_id: DomainId, - new_best_number: T::BlockNumber, - new_best_hash: T::Hash, - }, - } - - #[derive(TypeInfo, Encode, Decode, PalletError, Debug)] - pub enum FraudProofError { - /// Fraud proof is expired as the execution receipt has been pruned. - ExecutionReceiptPruned, - /// Trying to prove an receipt from the future. - ExecutionReceiptInFuture, - /// Unexpected hash type. - WrongHashType, - /// The execution receipt points to a block unknown to the history. - UnknownBlock, - /// This kind of fraud proof is still unimplemented. - Unimplemented, - } -} - -#[derive(Debug)] -pub enum Error { - /// The parent execution receipt is missing. - MissingParent, - /// Can not find the block hash of given primary block number. - UnavailablePrimaryBlockHash, - /// Invalid fraud proof. - FraudProof(FraudProofError), -} - -impl From for Error { - #[inline] - fn from(e: FraudProofError) -> Self { - Self::FraudProof(e) - } -} - -impl Pallet { - pub fn successful_fraud_proofs() -> Vec { - SuccessfulFraudProofs::::get() - } - - /// Returns the block number of the latest receipt. - pub fn head_receipt_number(domain_id: DomainId) -> T::BlockNumber { - >::get(domain_id) - } - - /// Initialize the head receipt on the domain creation. - pub fn initialize_head_receipt_number(domain_id: DomainId, created_at: T::BlockNumber) { - >::insert(domain_id, created_at) - } - - /// Returns the block number of the oldest receipt still being tracked in the state. - pub fn oldest_receipt_number(domain_id: DomainId) -> T::BlockNumber { - Self::finalized_receipt_number(domain_id) + One::one() - } - - /// Returns the state root of a domain at specific number and hash. - pub fn domain_state_root_at( - domain_id: DomainId, - number: T::BlockNumber, - hash: T::DomainHash, - ) -> Option { - StateRoots::::get((domain_id, number, hash)) - } - - /// Returns the block number of latest _finalized_ receipt. - pub fn finalized_receipt_number(domain_id: DomainId) -> T::BlockNumber { - let best_number = >::get(domain_id); - best_number.saturating_sub(T::ReceiptsPruningDepth::get()) - } - - /// Returns `true` if the primary block the receipt points to is part of the history. - pub fn point_to_valid_primary_block( - domain_id: DomainId, - receipt: &ExecutionReceipt, - ) -> bool { - Self::primary_hash(domain_id, receipt.primary_number) - .map(|hash| hash == receipt.primary_hash) - .unwrap_or(false) - } - - /// Initialize the genesis execution receipt - pub fn initialize_genesis_receipt(domain_id: DomainId, genesis_hash: T::Hash) { - let genesis_receipt = ExecutionReceipt { - primary_number: Zero::zero(), - primary_hash: genesis_hash, - domain_hash: T::DomainHash::default(), - trace: Vec::new(), - trace_root: Default::default(), - }; - Self::import_head_receipt(domain_id, &genesis_receipt); - // Explicitly initialize the oldest receipt number even not necessary as ValueQuery is used. - >::insert::<_, T::BlockNumber>(domain_id, Zero::zero()); - } - - /// Track the execution receipts for the domain - pub fn track_receipt( - domain_id: DomainId, - receipt: &ExecutionReceipt, - ) -> Result<(), Error> { - let oldest_receipt_number = >::get(domain_id); - let mut best_number = >::get(domain_id); - - let primary_number = receipt.primary_number; - - // Ignore the receipt if it has already been pruned. - if primary_number < oldest_receipt_number { - return Ok(()); - } - - if primary_number <= best_number { - // Either increase the vote for a known receipt or add a fork receipt at this height. - Self::import_receipt(domain_id, receipt); - } else if primary_number == best_number + One::one() { - Self::import_head_receipt(domain_id, receipt); - Self::remove_expired_receipts(domain_id, primary_number); - best_number += One::one(); - } else { - // Reject the entire Bundle due to the missing receipt(s) between [best_number, .., receipt.primary_number]. - return Err(Error::MissingParent); - } - Ok(()) - } - - /// Process a verified fraud proof. - pub fn process_fraud_proof( - fraud_proof: FraudProof, - ) -> Result<(), Error> { - let proof_hash = fraud_proof.hash(); - match fraud_proof { - FraudProof::InvalidStateTransition(proof) => { - Self::process_invalid_state_transition_proof(proof)? - } - FraudProof::InvalidTransaction(_proof) => { - // TODO: slash the executor accordingly. - } - _ => return Err(FraudProofError::Unimplemented.into()), - } - SuccessfulFraudProofs::::append(proof_hash); - Ok(()) - } - - fn process_invalid_state_transition_proof( - fraud_proof: InvalidStateTransitionProof, - ) -> Result<(), Error> { - // Revert the execution chain. - let domain_id = fraud_proof.domain_id; - let mut to_remove = >::get(domain_id); - - let new_best_number: T::BlockNumber = fraud_proof.parent_number.into(); - let new_best_hash = PrimaryBlockHash::::get(domain_id, new_best_number) - .ok_or(Error::UnavailablePrimaryBlockHash)?; - - >::insert(domain_id, new_best_number); - - while to_remove > new_best_number { - let block_hash = PrimaryBlockHash::::get(domain_id, to_remove) - .ok_or(Error::UnavailablePrimaryBlockHash)?; - for (receipt_hash, _) in >::drain_prefix((domain_id, block_hash)) { - if let Some(receipt) = >::take(domain_id, receipt_hash) { - StateRoots::::remove((domain_id, to_remove, receipt.domain_hash)) - } - } - to_remove -= One::one(); - } - // TODO: slash the executor accordingly. - Self::deposit_event(Event::InvalidStateTransitionProofProcessed { - domain_id, - new_best_number, - new_best_hash, - }); - Ok(()) - } - - pub fn validate_fraud_proof( - fraud_proof: &FraudProof, - ) -> Result<(), Error> { - match fraud_proof { - FraudProof::InvalidStateTransition(proof) => { - Self::validate_invalid_state_transition_proof(proof) - } - FraudProof::InvalidTransaction(proof) => { - Self::validate_invalid_transaction_proof(proof) - } - _ => Err(FraudProofError::Unimplemented.into()), - } - } - - fn validate_invalid_state_transition_proof( - fraud_proof: &InvalidStateTransitionProof, - ) -> Result<(), Error> { - let best_number = Self::head_receipt_number(fraud_proof.domain_id); - let to_prove: T::BlockNumber = (fraud_proof.parent_number + 1u32).into(); - ensure!( - to_prove > best_number.saturating_sub(T::ReceiptsPruningDepth::get()), - FraudProofError::ExecutionReceiptPruned - ); - - ensure!( - to_prove <= best_number, - FraudProofError::ExecutionReceiptInFuture - ); - - let primary_parent_hash = - T::Hash::decode(&mut fraud_proof.primary_parent_hash.encode().as_slice()) - .map_err(|_| FraudProofError::WrongHashType)?; - let parent_number: T::BlockNumber = fraud_proof.parent_number.into(); - ensure!( - Self::primary_hash(fraud_proof.domain_id, parent_number) == Some(primary_parent_hash), - FraudProofError::UnknownBlock - ); - - // TODO: prevent the spamming of fraud proof transaction. - - Ok(()) - } - - fn validate_invalid_transaction_proof( - fraud_proof: &InvalidTransactionProof, - ) -> Result<(), Error> { - let best_number = Self::head_receipt_number(fraud_proof.domain_id); - let to_prove: T::BlockNumber = fraud_proof.block_number.into(); - ensure!( - to_prove > best_number.saturating_sub(T::ReceiptsPruningDepth::get()), - FraudProofError::ExecutionReceiptPruned - ); - - ensure!( - to_prove <= best_number, - FraudProofError::ExecutionReceiptInFuture - ); - - Ok(()) - } -} - -impl Pallet { - /// Remove the expired receipts once the receipts cache is full. - fn remove_expired_receipts(domain_id: DomainId, primary_number: T::BlockNumber) { - if let Some(to_prune) = primary_number.checked_sub(&T::ReceiptsPruningDepth::get()) { - PrimaryBlockHash::::mutate_exists(domain_id, to_prune, |maybe_block_hash| { - if let Some(block_hash) = maybe_block_hash.take() { - for (receipt_hash, _) in - >::drain_prefix((domain_id, block_hash)) - { - >::remove(domain_id, receipt_hash); - } - } - }); - >::insert(domain_id, to_prune + One::one()); - let _ = >::clear_prefix((domain_id, to_prune), u32::MAX, None); - } - } - - /// Imports the receipt of the latest head of the domain. - /// Updates the receipt head of the domain accordingly. - fn import_head_receipt( - domain_id: DomainId, - receipt: &ExecutionReceipt, - ) { - Self::import_receipt(domain_id, receipt); - HeadReceiptNumber::::insert(domain_id, receipt.primary_number) - } - - /// Imports a receipt of domain. - /// Increments the receipt votes. - /// Assumes the receipt number is not pruned yet and inserts the a new receipt if not present. - fn import_receipt( - domain_id: DomainId, - execution_receipt: &ExecutionReceipt, - ) { - let primary_hash = execution_receipt.primary_hash; - let primary_number = execution_receipt.primary_number; - let receipt_hash = execution_receipt.hash(); - - // Track the fork receipt if it's not seen before. - if !>::contains_key(domain_id, receipt_hash) { - >::insert(domain_id, receipt_hash, execution_receipt); - if !primary_number.is_zero() { - let state_root = execution_receipt - .trace - .last() - .expect("There are at least 2 elements in trace after the genesis block; qed"); - - >::insert( - (domain_id, primary_number, execution_receipt.domain_hash), - state_root, - ); - } - Self::deposit_event(Event::NewDomainReceipt { - domain_id, - primary_number, - primary_hash, - }); - } - >::mutate((domain_id, primary_hash, receipt_hash), |count| { - *count += 1; - }); - } -} diff --git a/crates/pallet-subspace/Cargo.toml b/crates/pallet-subspace/Cargo.toml index a0e30d39539..4aef1dad82f 100644 --- a/crates/pallet-subspace/Cargo.toml +++ b/crates/pallet-subspace/Cargo.toml @@ -13,21 +13,21 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } log = { version = "0.4.19", default-features = false } -pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } schnorrkel = { version = "0.9.1", default-features = false, features = ["u64_backend"] } serde = { version = "1.0.159", optional = true, default-features = false, features = ["derive"] } sp-consensus-subspace = { version = "0.1.0", default-features = false, path = "../sp-consensus-subspace" } -sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } +sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } subspace-solving = { version = "0.1.0", default-features = false, path = "../subspace-solving" } @@ -36,10 +36,10 @@ subspace-verification = { version = "0.1.0", path = "../subspace-verification", [dev-dependencies] env_logger = "0.10.0" futures = "0.3.28" -pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } pallet-offences-subspace = { version = "0.1.0", path = "../pallet-offences-subspace" } rand = { version = "0.8.5", features = ["min_const_gen"] } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } subspace-farmer-components = { version = "0.1.0", path = "../subspace-farmer-components" } diff --git a/crates/pallet-subspace/src/lib.rs b/crates/pallet-subspace/src/lib.rs index 9dbecb69290..710f2f06766 100644 --- a/crates/pallet-subspace/src/lib.rs +++ b/crates/pallet-subspace/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(assert_matches)] +#![feature(assert_matches, const_option)] // Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. // Copyright (C) 2021 Subspace Labs, Inc. // SPDX-License-Identifier: Apache-2.0 @@ -139,7 +139,7 @@ mod pallet { use sp_std::prelude::*; use subspace_core_primitives::crypto::Scalar; use subspace_core_primitives::{ - Randomness, SectorIndex, SegmentHeader, SegmentIndex, SolutionRange, + HistorySize, Randomness, SectorIndex, SegmentHeader, SegmentIndex, SolutionRange, }; pub(super) struct InitialSolutionRanges { @@ -216,6 +216,18 @@ mod pallet { #[pallet::constant] type ConfirmationDepthK: Get; + /// Number of latest archived segments that are considered "recent history". + #[pallet::constant] + type RecentSegments: Get; + + /// Fraction of pieces from the "recent history" (`recent_segments`) in each sector. + #[pallet::constant] + type RecentHistoryFraction: Get<(HistorySize, HistorySize)>; + + /// Minimum lifetime of a plotted sector, measured in archived segment. + #[pallet::constant] + type MinSectorLifetime: Get; + /// Number of votes expected per block. /// /// This impacts solution range for votes in consensus. @@ -1046,6 +1058,12 @@ impl Pallet { .try_into() .unwrap_or_else(|_| panic!("Block number always fits in BlockNumber; qed")), slot_probability: T::SlotProbability::get(), + recent_segments: T::RecentSegments::get(), + recent_history_fraction: ( + T::RecentHistoryFraction::get().0, + T::RecentHistoryFraction::get().1, + ), + min_sector_lifetime: T::MinSectorLifetime::get(), } } } @@ -1196,6 +1214,7 @@ enum CheckVoteError { SlotInThePast, BadRewardSignature(SignatureError), UnknownSegmentCommitment, + InvalidHistorySize, InvalidSolution(String), DuplicateVote, Equivocated(SubspaceEquivocationOffence), @@ -1214,6 +1233,7 @@ impl From for TransactionValidityError { CheckVoteError::SlotInThePast => InvalidTransaction::Stale, CheckVoteError::BadRewardSignature(_) => InvalidTransaction::BadProof, CheckVoteError::UnknownSegmentCommitment => InvalidTransaction::Call, + CheckVoteError::InvalidHistorySize => InvalidTransaction::Call, CheckVoteError::InvalidSolution(_) => InvalidTransaction::Call, CheckVoteError::DuplicateVote => InvalidTransaction::Call, CheckVoteError::Equivocated(_) => InvalidTransaction::BadSigner, @@ -1347,8 +1367,19 @@ fn check_vote( solution.sector_index, ); + let recent_segments = T::RecentSegments::get(); + let recent_history_fraction = ( + T::RecentHistoryFraction::get().0, + T::RecentHistoryFraction::get().1, + ); let segment_index = sector_id - .derive_piece_index(solution.piece_offset, solution.history_size) + .derive_piece_index( + solution.piece_offset, + solution.history_size, + T::MaxPiecesInSector::get(), + recent_segments, + recent_history_fraction, + ) .segment_index(); let segment_commitment = @@ -1362,6 +1393,14 @@ fn check_vote( return Err(CheckVoteError::UnknownSegmentCommitment); }; + let sector_expiration_check_segment_commitment = Pallet::::segment_commitment( + solution + .history_size + .sector_expiration_check(T::MinSectorLifetime::get()) + .ok_or(CheckVoteError::InvalidHistorySize)? + .segment_index(), + ); + if let Err(error) = verify_solution( solution.into(), slot.into(), @@ -1371,6 +1410,11 @@ fn check_vote( piece_check_params: Some(PieceCheckParams { max_pieces_in_sector: T::MaxPiecesInSector::get(), segment_commitment, + recent_segments, + recent_history_fraction, + min_sector_lifetime: T::MinSectorLifetime::get(), + current_history_size: Pallet::::history_size(), + sector_expiration_check_segment_commitment, }), }) .into(), diff --git a/crates/pallet-subspace/src/mock.rs b/crates/pallet-subspace/src/mock.rs index 5d1aa693e24..cf3886f8729 100644 --- a/crates/pallet-subspace/src/mock.rs +++ b/crates/pallet-subspace/src/mock.rs @@ -37,6 +37,7 @@ use sp_runtime::testing::{Digest, DigestItem, Header, TestXt}; use sp_runtime::traits::{Block as BlockT, Header as _, IdentityLookup}; use sp_runtime::Perbill; use std::iter; +use std::num::NonZeroU64; use std::sync::Once; use subspace_archiving::archiver::{Archiver, NewArchivedSegment}; use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; @@ -52,6 +53,7 @@ use subspace_farmer_components::plotting::{plot_sector, PieceGetterRetryPolicy}; use subspace_farmer_components::sector::{sector_size, SectorMetadata}; use subspace_farmer_components::FarmerProtocolInfo; use subspace_proof_of_space::shim::ShimTable; +use subspace_proof_of_space::Table; use subspace_solving::REWARD_SIGNING_CONTEXT; type PosTable = ShimTable; @@ -158,6 +160,12 @@ parameter_types! { pub const InitialSolutionRange: SolutionRange = INITIAL_SOLUTION_RANGE; pub const SlotProbability: (u64, u64) = SLOT_PROBABILITY; pub const ConfirmationDepthK: u32 = 10; + pub const RecentSegments: HistorySize = HistorySize::new(NonZeroU64::new(5).unwrap()); + pub const RecentHistoryFraction: (HistorySize, HistorySize) = ( + HistorySize::new(NonZeroU64::new(1).unwrap()), + HistorySize::new(NonZeroU64::new(10).unwrap()), + ); + pub const MinSectorLifetime: HistorySize = HistorySize::new(NonZeroU64::new(4).unwrap()); pub const RecordSize: u32 = 3840; pub const ExpectedVotesPerBlock: u32 = 9; pub const ReplicationFactor: u16 = 1; @@ -173,6 +181,9 @@ impl Config for Test { type SlotProbability = SlotProbability; type ExpectedBlockTime = ConstU64<1>; type ConfirmationDepthK = ConfirmationDepthK; + type RecentSegments = RecentSegments; + type RecentHistoryFraction = RecentHistoryFraction; + type MinSectorLifetime = MinSectorLifetime; type ExpectedVotesPerBlock = ExpectedVotesPerBlock; type MaxPiecesInSector = ConstU16<{ MAX_PIECES_IN_SECTOR }>; type ShouldAdjustSolutionRange = ShouldAdjustSolutionRange; @@ -243,7 +254,11 @@ pub fn make_pre_digest( slot: Slot, solution: Solution::AccountId>, ) -> Digest { - let log = DigestItem::subspace_pre_digest(&PreDigest { slot, solution }); + let log = DigestItem::subspace_pre_digest(&PreDigest { + slot, + solution, + proof_of_time: Default::default(), + }); Digest { logs: vec![log] } } @@ -367,7 +382,7 @@ pub fn create_archived_segment(kzg: Kzg) -> NewArchivedSegment { let mut block = vec![0u8; RecordedHistorySegment::SIZE]; rand::thread_rng().fill(block.as_mut_slice()); archiver - .add_block(block, Default::default()) + .add_block(block, Default::default(), true) .into_iter() .next() .unwrap() @@ -392,18 +407,24 @@ pub fn create_signed_vote( let farmer_protocol_info = FarmerProtocolInfo { history_size: HistorySize::from(SegmentIndex::ZERO), max_pieces_in_sector: MAX_PIECES_IN_SECTOR, - sector_expiration: SegmentIndex::ONE, + recent_segments: HistorySize::from(NonZeroU64::new(5).unwrap()), + recent_history_fraction: ( + HistorySize::from(NonZeroU64::new(1).unwrap()), + HistorySize::from(NonZeroU64::new(10).unwrap()), + ), + min_sector_lifetime: HistorySize::from(NonZeroU64::new(4).unwrap()), }; let pieces_in_sector = farmer_protocol_info.max_pieces_in_sector; let sector_size = sector_size(pieces_in_sector); - for (sector_offset, sector_index) in iter::from_fn(|| Some(rand::random())).enumerate() { + let mut table_generator = PosTable::generator(); + + for sector_index in iter::from_fn(|| Some(rand::random())) { let mut plotted_sector_bytes = vec![0; sector_size]; let mut plotted_sector_metadata_bytes = vec![0; SectorMetadata::encoded_size()]; let plotted_sector = block_on(plot_sector::<_, PosTable>( &public_key, - sector_offset, sector_index, archived_history_segment, PieceGetterRetryPolicy::default(), @@ -413,7 +434,7 @@ pub fn create_signed_vote( pieces_in_sector, &mut plotted_sector_bytes, &mut plotted_sector_metadata_bytes, - Default::default(), + &mut table_generator, )) .unwrap(); @@ -432,7 +453,7 @@ pub fn create_signed_vote( }; let solution = solution_candidates - .into_iter::<_, PosTable>(&reward_address, kzg, erasure_coding) + .into_iter::<_, PosTable>(&reward_address, kzg, erasure_coding, &mut table_generator) .unwrap() .next() .unwrap() diff --git a/crates/pallet-subspace/src/tests.rs b/crates/pallet-subspace/src/tests.rs index d2680faebd8..3bfc7511ac0 100644 --- a/crates/pallet-subspace/src/tests.rs +++ b/crates/pallet-subspace/src/tests.rs @@ -1482,6 +1482,8 @@ fn vote_equivocation_parent_voters_duplicate() { }); } +// TODO: Test for `CheckVoteError::InvalidHistorySize` + #[test] fn enabling_block_rewards_works() { fn set_block_rewards() { diff --git a/crates/pallet-transaction-fees/Cargo.toml b/crates/pallet-transaction-fees/Cargo.toml index bbfb21d3e3b..38be6db06d4 100644 --- a/crates/pallet-transaction-fees/Cargo.toml +++ b/crates/pallet-transaction-fees/Cargo.toml @@ -18,9 +18,9 @@ include = [ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } diff --git a/crates/sc-consensus-fraud-proof/Cargo.toml b/crates/sc-consensus-fraud-proof/Cargo.toml index dc731b94afa..63ed0401611 100644 --- a/crates/sc-consensus-fraud-proof/Cargo.toml +++ b/crates/sc-consensus-fraud-proof/Cargo.toml @@ -12,11 +12,10 @@ include = [ [dependencies] async-trait = "0.1.68" -codec = { package = "parity-scale-codec", version = "3.4.0", features = ["derive"] } -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", features = ["derive"] } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../sp-domains" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", path = "../sp-settlement" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-fraud-proof = { version = "0.1.0", path = "../subspace-fraud-proof" } diff --git a/crates/sc-consensus-fraud-proof/src/lib.rs b/crates/sc-consensus-fraud-proof/src/lib.rs index 9d6199cc2ce..184378030d1 100644 --- a/crates/sc-consensus-fraud-proof/src/lib.rs +++ b/crates/sc-consensus-fraud-proof/src/lib.rs @@ -20,9 +20,8 @@ use codec::{Decode, Encode}; use sc_consensus::block_import::{BlockCheckParams, BlockImport, BlockImportParams, ImportResult}; use sp_api::{ProvideRuntimeApi, TransactionFor}; use sp_consensus::Error as ConsensusError; -use sp_domains::DomainId; +use sp_domains::DomainsApi; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; -use sp_settlement::SettlementApi; use std::marker::PhantomData; use std::sync::Arc; use subspace_fraud_proof::VerifyFraudProof; @@ -34,15 +33,15 @@ use subspace_fraud_proof::VerifyFraudProof; /// /// This block import object should be used with the subspace consensus block import together until /// the fraud proof verification can be done in the runtime properly. -pub struct FraudProofBlockImport { +pub struct FraudProofBlockImport { inner: I, client: Arc, fraud_proof_verifier: Verifier, - _phantom: PhantomData<(Block, DomainHash)>, + _phantom: PhantomData<(Block, DomainNumber, DomainHash)>, } -impl Clone - for FraudProofBlockImport +impl Clone + for FraudProofBlockImport where I: Clone, Verifier: Clone, @@ -58,15 +57,16 @@ where } #[async_trait::async_trait] -impl BlockImport - for FraudProofBlockImport +impl BlockImport + for FraudProofBlockImport where Block: BlockT, Client: ProvideRuntimeApi + Send + Sync + 'static, - Client::Api: SettlementApi, + Client::Api: DomainsApi, Inner: BlockImport, Error = ConsensusError> + Send, Verifier: VerifyFraudProof + Send, + DomainNumber: Encode + Decode + Send, DomainHash: Encode + Decode + Send, { type Error = ConsensusError; @@ -83,21 +83,28 @@ where &mut self, block: BlockImportParams, ) -> Result { - let parent_hash = *block.header.parent_hash(); + let _parent_hash = *block.header.parent_hash(); if !block.state_action.skip_execution_checks() { - if let Some(extrinsics) = &block.body { - let fraud_proofs = self - .client - .runtime_api() - .extract_fraud_proofs(parent_hash, extrinsics.clone(), DomainId::SYSTEM) - .map_err(|e| ConsensusError::ClientImport(e.to_string()))?; + if let Some(_extrinsics) = &block.body { + // TODO: Fetch the registered domains properly + // We may change `extract_fraud_proofs` API to return the fraud proofs for all + // domains instead of specifying the domain_id each time for the efficiency. + // let registered_domains = vec![]; + // for domain_id in registered_domains { + // TODO: Implement `extract_fraud_proofs` when proceeding to fraud proof v2. + // let fraud_proofs = self + // .client + // .runtime_api() + // .extract_fraud_proofs(parent_hash, extrinsics.clone(), domain_id) + // .map_err(|e| ConsensusError::ClientImport(e.to_string()))?; - for fraud_proof in fraud_proofs { - self.fraud_proof_verifier - .verify_fraud_proof(&fraud_proof) - .map_err(|e| ConsensusError::Other(Box::new(e)))?; - } + // for fraud_proof in fraud_proofs { + // self.fraud_proof_verifier + // .verify_fraud_proof(&fraud_proof) + // .map_err(|e| ConsensusError::Other(Box::new(e)))?; + // } + // } } } @@ -105,15 +112,15 @@ where } } -pub fn block_import( +pub fn block_import( client: Arc, wrapped_block_import: I, fraud_proof_verifier: Verifier, -) -> FraudProofBlockImport { +) -> FraudProofBlockImport { FraudProofBlockImport { inner: wrapped_block_import, client, fraud_proof_verifier, - _phantom: PhantomData::<(Block, DomainHash)>, + _phantom: PhantomData::<(Block, DomainNumber, DomainHash)>, } } diff --git a/crates/sc-consensus-subspace-rpc/Cargo.toml b/crates/sc-consensus-subspace-rpc/Cargo.toml index 6c2bd9c4921..de1dca4c24d 100644 --- a/crates/sc-consensus-subspace-rpc/Cargo.toml +++ b/crates/sc-consensus-subspace-rpc/Cargo.toml @@ -17,18 +17,19 @@ async-oneshot = "0.5.0" futures = "0.3.28" futures-timer = "3.0.2" jsonrpsee = { version = "0.16.2", features = ["server", "macros"] } -parity-scale-codec = "3.4.0" +parity-scale-codec = "3.6.3" parking_lot = "0.12.1" -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sc-consensus-subspace = { version = "0.1.0", path = "../sc-consensus-subspace" } -sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace" } -sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } subspace-farmer-components = { version = "0.1.0", path = "../subspace-farmer-components" } diff --git a/crates/sc-consensus-subspace-rpc/src/lib.rs b/crates/sc-consensus-subspace-rpc/src/lib.rs index 3b6346e0989..8578f79ff81 100644 --- a/crates/sc-consensus-subspace-rpc/src/lib.rs +++ b/crates/sc-consensus-subspace-rpc/src/lib.rs @@ -26,39 +26,41 @@ use jsonrpsee::types::SubscriptionResult; use jsonrpsee::SubscriptionSink; use parity_scale_codec::{Decode, Encode}; use parking_lot::Mutex; -use sc_client_api::BlockBackend; +use sc_client_api::{AuxStore, BlockBackend}; use sc_consensus_subspace::notification::SubspaceNotificationStream; use sc_consensus_subspace::{ - ArchivedSegmentNotification, NewSlotNotification, RewardSigningNotification, SubspaceLink, + ArchivedSegmentNotification, NewSlotNotification, RewardSigningNotification, + SegmentHeadersStore, SubspaceSyncOracle, }; use sc_rpc::SubscriptionTaskExecutor; use sc_utils::mpsc::TracingUnboundedSender; use sp_api::{ApiError, ProvideRuntimeApi}; use sp_blockchain::HeaderBackend; +use sp_consensus::SyncOracle; use sp_consensus_slots::Slot; use sp_consensus_subspace::{FarmerPublicKey, FarmerSignature, SubspaceApi as SubspaceRuntimeApi}; use sp_core::crypto::ByteArray; use sp_core::H256; -use sp_runtime::traits::{Block as BlockT, Zero}; +use sp_runtime::traits::Block as BlockT; use std::collections::hash_map::Entry; use std::collections::HashMap; -use std::error::Error; +use std::marker::PhantomData; use std::sync::atomic::{AtomicU64, Ordering}; -use std::sync::Arc; +use std::sync::{Arc, Weak}; use std::time::Duration; -use subspace_core_primitives::{ - Piece, PieceIndex, SegmentCommitment, SegmentHeader, SegmentIndex, Solution, -}; +use subspace_archiving::archiver::NewArchivedSegment; +use subspace_core_primitives::{PieceIndex, SegmentHeader, SegmentIndex, Solution}; use subspace_farmer_components::FarmerProtocolInfo; use subspace_networking::libp2p::Multiaddr; use subspace_rpc_primitives::{ - FarmerAppInfo, RewardSignatureResponse, RewardSigningInfo, SlotInfo, SolutionResponse, - MAX_SEGMENT_INDEXES_PER_REQUEST, + FarmerAppInfo, NodeSyncStatus, RewardSignatureResponse, RewardSigningInfo, SlotInfo, + SolutionResponse, MAX_SEGMENT_HEADERS_PER_REQUEST, }; use tracing::{debug, error, warn}; const SOLUTION_TIMEOUT: Duration = Duration::from_secs(2); const REWARD_SIGNING_TIMEOUT: Duration = Duration::from_millis(500); +const NODE_SYNC_STATUS_CHECK_INTERVAL: Duration = Duration::from_secs(1); /// Provides rpc methods for interacting with Subspace. #[rpc(client, server)] @@ -97,11 +99,13 @@ pub trait SubspaceRpcApi { )] fn subscribe_archived_segment_header(&self); - #[method(name = "subspace_segmentCommitments")] - async fn segment_commitments( - &self, - segment_indexes: Vec, - ) -> RpcResult>>; + /// Archived segment header subscription + #[subscription( + name = "subspace_subscribeNodeSyncStatusChange" => "subspace_node_sync_status_change", + unsubscribe = "subspace_unsubscribeNodeSyncStatusChange", + item = NodeSyncStatus, + )] + fn subscribe_node_sync_status_change(&self); #[method(name = "subspace_segmentHeaders")] async fn segment_headers( @@ -137,22 +141,12 @@ struct BlockSignatureSenders { senders: Vec>, } -pub trait SegmentHeaderProvider { - fn get_segment_header( - &self, - segment_index: SegmentIndex, - ) -> Result, Box>; -} - -pub trait PieceProvider { - fn get_piece_by_index( - &self, - piece_index: PieceIndex, - ) -> Result, Box>; -} - /// Implements the [`SubspaceRpcApiServer`] trait for interacting with Subspace. -pub struct SubspaceRpc { +pub struct SubspaceRpc +where + Block: BlockT, + SO: SyncOracle + Send + Sync + Clone + 'static, +{ client: Arc, executor: SubscriptionTaskExecutor, new_slot_notification_stream: SubspaceNotificationStream, @@ -161,12 +155,18 @@ pub struct SubspaceRpc>, reward_signature_senders: Arc>, dsn_bootstrap_nodes: Vec, - subspace_link: SubspaceLink, - segment_header_provider: RBP, - piece_provider: Option, + segment_headers_store: SegmentHeadersStore, + /// In-memory piece cache of last archived segment, such that when request comes back right + /// after archived segment notification, RPC server is able to answer quickly. + /// + /// We store weak reference, such that archived segment is not persisted for longer than + /// necessary occupying RAM. + piece_cache: Arc>>>, archived_segment_acknowledgement_senders: Arc>, next_subscription_id: AtomicU64, + sync_oracle: SubspaceSyncOracle, + _block: PhantomData, } /// [`SubspaceRpc`] is used for notifying subscribers about arrival of new slots and for @@ -176,8 +176,11 @@ pub struct SubspaceRpc - SubspaceRpc +impl SubspaceRpc +where + Block: BlockT, + SO: SyncOracle + Send + Sync + Clone + 'static, + AS: AuxStore + Send + Sync + 'static, { #[allow(clippy::too_many_arguments)] /// Creates a new instance of the `SubspaceRpc` handler. @@ -190,9 +193,8 @@ impl ArchivedSegmentNotification, >, dsn_bootstrap_nodes: Vec, - subspace_link: SubspaceLink, - segment_header_provider: RBP, - piece_provider: Option, + segment_headers_store: SegmentHeadersStore, + sync_oracle: SubspaceSyncOracle, ) -> Self { Self { client, @@ -203,17 +205,18 @@ impl solution_response_senders: Arc::default(), reward_signature_senders: Arc::default(), dsn_bootstrap_nodes, - subspace_link, - segment_header_provider, - piece_provider, + segment_headers_store, + piece_cache: Arc::default(), archived_segment_acknowledgement_senders: Arc::default(), next_subscription_id: AtomicU64::default(), + sync_oracle, + _block: PhantomData, } } } #[async_trait] -impl SubspaceRpcApiServer for SubspaceRpc +impl SubspaceRpcApiServer for SubspaceRpc where Block: BlockT, Client: ProvideRuntimeApi @@ -223,8 +226,8 @@ where + Sync + 'static, Client::Api: SubspaceRuntimeApi, - RBP: SegmentHeaderProvider + Send + Sync + 'static, - PP: PieceProvider + Send + Sync + 'static, + SO: SyncOracle + Send + Sync + Clone + 'static, + AS: AuxStore + Send + Sync + 'static, { fn get_farmer_app_info(&self) -> RpcResult { let best_hash = self.client.info().best_hash; @@ -242,11 +245,13 @@ where })?; let farmer_app_info: Result = try { + let chain_constants = runtime_api.chain_constants(best_hash)?; let protocol_info = FarmerProtocolInfo { history_size: runtime_api.history_size(best_hash)?, max_pieces_in_sector: runtime_api.max_pieces_in_sector(best_hash)?, - // TODO: Fetch this from the runtime - sector_expiration: SegmentIndex::from(100), + recent_segments: chain_constants.recent_segments(), + recent_history_fraction: chain_constants.recent_history_fraction(), + min_sector_lifetime: chain_constants.min_sector_lifetime(), }; FarmerAppInfo { @@ -350,10 +355,16 @@ where .boxed(), ); + let slot_number = new_slot_info.slot.into(); + + let global_challenge = new_slot_info + .global_randomness + .derive_global_challenge(slot_number); + // This will be sent to the farmer SlotInfo { - slot_number: new_slot_info.slot.into(), - global_challenge: new_slot_info.global_challenge, + slot_number, + global_challenge, solution_range: new_slot_info.solution_range, voting_solution_range: new_slot_info.voting_solution_range, } @@ -473,6 +484,7 @@ where let archived_segment_acknowledgement_senders = self.archived_segment_acknowledgement_senders.clone(); + let piece_cache = Arc::clone(&self.piece_cache); let subscription_id = self.next_subscription_id.fetch_add(1, Ordering::Relaxed); let stream = self @@ -514,6 +526,10 @@ where } }; + piece_cache + .lock() + .replace(Arc::downgrade(&archived_segment)); + Box::pin(async move { maybe_archived_segment_header }) } }); @@ -540,6 +556,48 @@ where Ok(()) } + fn subscribe_node_sync_status_change(&self, mut sink: SubscriptionSink) -> SubscriptionResult { + let sync_oracle = self.sync_oracle.clone(); + let fut = async move { + let mut last_node_sync_status = None; + loop { + let node_sync_status = if sync_oracle.is_major_syncing() { + NodeSyncStatus::MajorSyncing + } else { + NodeSyncStatus::Synced + }; + + // Update subscriber if value has changed + if last_node_sync_status != Some(node_sync_status) { + last_node_sync_status.replace(node_sync_status); + + match sink.send(&node_sync_status) { + Ok(true) => { + // Success + } + Ok(false) => { + // Subscription closed + return; + } + Err(error) => { + error!("Failed to serialize node sync status: {}", error); + } + } + } + + futures_timer::Delay::new(NODE_SYNC_STATUS_CHECK_INTERVAL).await; + } + }; + + self.executor.spawn( + "subspace-node-sync-status-change-subscription", + Some("rpc"), + fut.boxed(), + ); + + Ok(()) + } + async fn acknowledge_archived_segment_header( &self, segment_index: SegmentIndex, @@ -578,112 +636,44 @@ where Ok(()) } - async fn segment_commitments( - &self, - segment_indexes: Vec, - ) -> RpcResult>> { - if segment_indexes.len() > MAX_SEGMENT_INDEXES_PER_REQUEST { - error!( - "segment_indexes length exceed the limit: {} ", - segment_indexes.len() - ); - - return Err(JsonRpseeError::Custom(format!( - "segment_indexes length exceed the limit {MAX_SEGMENT_INDEXES_PER_REQUEST}" - ))); - }; - - let runtime_api = self.client.runtime_api(); - let best_hash = self.client.info().best_hash; - let best_block_number = self.client.info().best_number; - - let segment_commitment_result: Result, JsonRpseeError> = segment_indexes - .into_iter() - .map(|segment_index| { - let api_result = runtime_api - .segment_commitment(best_hash, segment_index) - .map_err(|_| { - JsonRpseeError::Custom( - "Internal error during `segment_commitment` call".to_string(), - ) - }); - - api_result.map(|maybe_segment_commitment| { - // This is not a very nice hack due to the fact that at the time first block is - // produced extrinsics with segment headers are not yet in runtime. - if maybe_segment_commitment.is_none() && best_block_number.is_zero() { - self.subspace_link - .segment_commitment_by_segment_index(segment_index) - } else { - maybe_segment_commitment - } - }) - }) - .collect(); - - if let Err(ref err) = segment_commitment_result { - error!( - "Failed to get data from runtime API (segment_commitment): {}", - err - ); - } - - segment_commitment_result - } - async fn segment_headers( &self, segment_indexes: Vec, ) -> RpcResult>> { - if segment_indexes.len() > MAX_SEGMENT_INDEXES_PER_REQUEST { + if segment_indexes.len() > MAX_SEGMENT_HEADERS_PER_REQUEST { error!( "segment_indexes length exceed the limit: {} ", segment_indexes.len() ); return Err(JsonRpseeError::Custom(format!( - "segment_indexes length exceed the limit {MAX_SEGMENT_INDEXES_PER_REQUEST}" + "segment_indexes length exceed the limit {MAX_SEGMENT_HEADERS_PER_REQUEST}" ))); }; - let segment_commitment_result: Result, JsonRpseeError> = segment_indexes + Ok(segment_indexes .into_iter() - .map(|segment_index| { - let api_result = self - .segment_header_provider - .get_segment_header(segment_index) - .map_err(|_| { - JsonRpseeError::Custom( - "Internal error during `segment_headers` call".to_string(), - ) - }); - - api_result - }) - .collect(); - - if let Err(err) = &segment_commitment_result { - error!(?err, "Failed to get segment headers."); - } - - segment_commitment_result + .map(|segment_index| self.segment_headers_store.get_segment_header(segment_index)) + .collect()) } - fn piece(&self, piece_index: PieceIndex) -> RpcResult>> { - if let Some(piece_provider) = self.piece_provider.as_ref() { - let result = piece_provider.get_piece_by_index(piece_index).map_err(|_| { - JsonRpseeError::Custom("Internal error during `piece` call".to_string()) - }); + fn piece(&self, requested_piece_index: PieceIndex) -> RpcResult>> { + let Some(archived_segment) = self.piece_cache.lock().as_ref().and_then(Weak::upgrade) + else { + return Ok(None); + }; - if let Err(err) = &result { - error!(?err, %piece_index, "Failed to get a piece."); + let indices = archived_segment + .segment_header + .segment_index() + .segment_piece_indexes(); + let pieces = &archived_segment.pieces; + for (piece_index, piece) in indices.into_iter().zip(pieces.iter()) { + if requested_piece_index == piece_index { + return Ok(Some(piece.to_vec())); } - - result.map(|piece| piece.map(|piece| piece.to_vec())) - } else { - Err(JsonRpseeError::Custom( - "Piece provider is not set.".to_string(), - )) } + + Ok(None) } } diff --git a/crates/sc-consensus-subspace/Cargo.toml b/crates/sc-consensus-subspace/Cargo.toml index f91485cd144..234bf9a34ff 100644 --- a/crates/sc-consensus-subspace/Cargo.toml +++ b/crates/sc-consensus-subspace/Cargo.toml @@ -15,34 +15,36 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] async-trait = "0.1.68" -codec = { package = "parity-scale-codec", version = "3.4.0", features = ["derive"] } -fork-tree = { version = "3.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", features = ["derive"] } +fork-tree = { version = "3.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } futures = "0.3.28" futures-timer = "3.0.2" log = "0.4.19" lru = "0.10.0" parking_lot = "0.12.1" -prometheus-endpoint = { package = "substrate-prometheus-endpoint", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", version = "0.10.0-dev" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", version = "0.10.0-dev" } rand = "0.8.5" +rand_chacha = "0.3.1" schnorrkel = "0.9.1" -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-proof-of-time = { version = "0.1.0", path = "../sc-proof-of-time" } +sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } serde = { version = "1.0.159", features = ["derive"] } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace" } -sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-objects = { version = "0.1.0", path = "../sp-objects" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-version = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-version = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-space" } diff --git a/crates/sc-consensus-subspace/src/archiver.rs b/crates/sc-consensus-subspace/src/archiver.rs index c1d2ada6bc6..5378e251540 100644 --- a/crates/sc-consensus-subspace/src/archiver.rs +++ b/crates/sc-consensus-subspace/src/archiver.rs @@ -16,26 +16,173 @@ use crate::{ get_chain_constants, ArchivedSegmentNotification, BlockImportingNotification, SubspaceLink, - SubspaceNotificationSender, + SubspaceNotificationSender, SubspaceSyncOracle, }; -use codec::Encode; +use codec::{Decode, Encode}; use futures::StreamExt; use log::{debug, error, info, warn}; +use parking_lot::Mutex; +use rand::prelude::*; +use rand_chacha::ChaCha8Rng; use sc_client_api::{AuxStore, Backend as BackendT, BlockBackend, Finalizer, LockImportRun}; use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_INFO}; use sc_utils::mpsc::tracing_unbounded; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; +use sp_consensus::SyncOracle; use sp_consensus_subspace::{FarmerPublicKey, SubspaceApi}; use sp_objects::ObjectsApi; use sp_runtime::generic::SignedBlock; use sp_runtime::traits::{Block as BlockT, CheckedSub, Header, NumberFor, One, Zero}; use std::future::Future; +use std::slice; +use std::sync::atomic::{AtomicU16, Ordering}; use std::sync::Arc; use subspace_archiving::archiver::{Archiver, NewArchivedSegment}; use subspace_core_primitives::crypto::kzg::Kzg; use subspace_core_primitives::objects::BlockObjectMapping; -use subspace_core_primitives::{BlockNumber, SegmentHeader}; +use subspace_core_primitives::{BlockNumber, RecordedHistorySegment, SegmentHeader, SegmentIndex}; + +#[derive(Debug)] +struct SegmentHeadersStoreInner { + aux_store: Arc, + next_key_index: AtomicU16, + /// In-memory cache of segment headers + cache: Mutex>, +} + +/// Persistent storage of segment headers +#[derive(Debug)] +pub struct SegmentHeadersStore { + inner: Arc>, +} + +impl Clone for SegmentHeadersStore { + fn clone(&self) -> Self { + Self { + inner: Arc::clone(&self.inner), + } + } +} + +impl SegmentHeadersStore +where + AS: AuxStore, +{ + const KEY_PREFIX: &[u8] = b"segment-headers"; + const INITIAL_CACHE_CAPACITY: usize = 1_000; + + /// Create new instance + pub fn new(aux_store: Arc) -> Result { + let mut cache = Vec::with_capacity(Self::INITIAL_CACHE_CAPACITY); + let mut next_key_index = 0; + + debug!( + target: "subspace", + "Started loading segment headers into cache" + ); + while let Some(segment_headers) = + aux_store + .get_aux(&Self::key(next_key_index))? + .map(|segment_header| { + Vec::::decode(&mut segment_header.as_slice()) + .expect("Always correct segment header unless DB is corrupted; qed") + }) + { + cache.extend(segment_headers); + next_key_index += 1; + } + debug!( + target: "subspace", + "Finished loading segment headers into cache" + ); + + Ok(Self { + inner: Arc::new(SegmentHeadersStoreInner { + aux_store, + next_key_index: AtomicU16::new(next_key_index), + cache: Mutex::new(cache), + }), + }) + } + + /// Returns last observed segment index + pub fn max_segment_index(&self) -> Option { + let segment_index = self.inner.cache.lock().len().checked_sub(1)? as u64; + Some(SegmentIndex::from(segment_index)) + } + + /// Add segment headers + pub fn add_segment_headers( + &self, + segment_headers: &[SegmentHeader], + ) -> Result<(), sp_blockchain::Error> { + let mut maybe_last_segment_index = self.max_segment_index(); + let mut segment_headers_to_store = Vec::with_capacity(segment_headers.len()); + for segment_header in segment_headers { + let segment_index = segment_header.segment_index(); + match maybe_last_segment_index { + Some(last_segment_index) => { + if segment_index <= last_segment_index { + // Skip already stored segment headers + continue; + } + + if segment_index != last_segment_index + SegmentIndex::ONE { + let error = format!( + "Segment index {} must strictly follow {}, can't store segment header", + segment_index, last_segment_index + ); + return Err(sp_blockchain::Error::Application(error.into())); + } + + segment_headers_to_store.push(segment_header); + maybe_last_segment_index.replace(segment_index); + } + None => { + if segment_index != SegmentIndex::ZERO { + let error = format!( + "First segment header index must be zero, found index {segment_index}" + ); + return Err(sp_blockchain::Error::Application(error.into())); + } + + segment_headers_to_store.push(segment_header); + maybe_last_segment_index.replace(segment_index); + } + } + } + + if segment_headers_to_store.is_empty() { + return Ok(()); + } + + // TODO: Do compaction when we have too many keys: combine multiple segment headers into a + // single entry for faster retrievals and more compact storage + let key_index = self.inner.next_key_index.fetch_add(1, Ordering::SeqCst); + let key = Self::key(key_index); + let value = segment_headers_to_store.encode(); + let insert_data = vec![(key.as_slice(), value.as_slice())]; + + self.inner.aux_store.insert_aux(&insert_data, &[])?; + self.inner.cache.lock().extend(segment_headers_to_store); + + Ok(()) + } + + /// Get a single segment header + pub fn get_segment_header(&self, segment_index: SegmentIndex) -> Option { + self.inner + .cache + .lock() + .get(u64::from(segment_index) as usize) + .copied() + } + + fn key(key_index: u16) -> Vec { + (Self::KEY_PREFIX, key_index.to_le_bytes()).encode() + } +} /// How deep (in segments) should block be in order to be finalized. /// @@ -191,9 +338,39 @@ where best_archived_block: (Block::Hash, NumberFor), } -fn initialize_archiver( +fn encode_genesis_block(block: &SignedBlock) -> Vec +where + Block: BlockT, +{ + let mut encoded_block = block.encode(); + let encoded_block_length = encoded_block.len(); + + // We extend encoding of genesis block with extra data such that the very first + // archived segment can be produced right away, bootstrapping the farming + // process. + // + // Note: we add it to the end of the encoded block, so during decoding it'll + // actually be ignored (unless `DecodeAll::decode_all()` is used) even though it + // is technically present in encoded form. + encoded_block.resize(RecordedHistorySegment::SIZE, 0); + let mut rng = ChaCha8Rng::from_seed( + block + .block + .header() + .state_root() + .as_ref() + .try_into() + .expect("State root in Subspace must be 32 bytes, panic otherwise; qed"), + ); + rng.fill(&mut encoded_block[encoded_block_length..]); + + encoded_block +} + +fn initialize_archiver( best_block_hash: Block::Hash, best_block_number: NumberFor, + segment_headers_store: &SegmentHeadersStore, subspace_link: &SubspaceLink, client: &Client, kzg: Kzg, @@ -202,6 +379,7 @@ where Block: BlockT, Client: ProvideRuntimeApi + BlockBackend + HeaderBackend + AuxStore, Client::Api: SubspaceApi + ObjectsApi, + AS: AuxStore, { let confirmation_depth_k = get_chain_constants(client) .expect("Must always be able to get chain constants") @@ -230,10 +408,17 @@ where *last_archived_block.block.header().number(), )); + let last_archived_block_encoded = + if last_archived_block.block.header().number().is_zero() { + encode_genesis_block(&last_archived_block) + } else { + last_archived_block.encode() + }; + Archiver::with_initial_state( kzg, last_segment_header, - &last_archived_block.encode(), + &last_archived_block_encoded, block_object_mappings, ) .expect("Incorrect parameters for archiver") @@ -304,7 +489,11 @@ where }) .unwrap_or_default(); - let encoded_block = block.encode(); + let encoded_block = if block_number_to_archive.is_zero() { + encode_genesis_block(&block) + } else { + block.encode() + }; debug!( target: "subspace", "Encoded block {} has size of {:.2} kiB", @@ -312,7 +501,8 @@ where encoded_block.len() as f32 / 1024.0 ); - let archived_segments = archiver.add_block(encoded_block, block_object_mappings); + let archived_segments = + archiver.add_block(encoded_block, block_object_mappings, false); let new_segment_headers: Vec = archived_segments .iter() .map(|archived_segment| archived_segment.segment_header) @@ -321,6 +511,11 @@ where older_archived_segments.extend(archived_segments); if !new_segment_headers.is_empty() { + if let Err(error) = + segment_headers_store.add_segment_headers(&new_segment_headers) + { + panic!("Failed to store segment headers: {error}"); + } // Set list of expected segment headers for the block where we expect segment // header extrinsic to be included subspace_link.segment_headers.lock().put( @@ -357,6 +552,10 @@ fn finalize_block( Backend: BackendT, Client: LockImportRun + Finalizer, { + if number.is_zero() { + // Block zero is finalized already and generates unnecessary warning if called again + return; + } // We don't have anything useful to do with this result yet, the only source of errors was // logged already inside let _result: Result<_, sp_blockchain::Error> = client.lock_import_and_run(|import_op| { @@ -387,9 +586,11 @@ fn finalize_block( /// `store_segment_header` extrinsic). /// /// NOTE: Archiver is doing blocking operations and must run in a dedicated task. -pub fn create_subspace_archiver( +pub fn create_subspace_archiver( + segment_headers_store: SegmentHeadersStore, subspace_link: &SubspaceLink, client: Arc, + sync_oracle: SubspaceSyncOracle, telemetry: Option, ) -> impl Future + Send + 'static where @@ -405,6 +606,8 @@ where + Sync + 'static, Client::Api: SubspaceApi + ObjectsApi, + AS: AuxStore + Send + Sync + 'static, + SO: SyncOracle + Send + Sync + 'static, { let client_info = client.info(); let best_block_hash = client_info.best_hash; @@ -418,6 +621,7 @@ where } = initialize_archiver( best_block_hash, best_block_number, + &segment_headers_store, subspace_link, client.as_ref(), subspace_link.kzg.clone(), @@ -525,9 +729,23 @@ where ); let mut new_segment_headers = Vec::new(); - for archived_segment in archiver.add_block(encoded_block, block_object_mappings) { + for archived_segment in archiver.add_block( + encoded_block, + block_object_mappings, + !sync_oracle.is_major_syncing(), + ) { let segment_header = archived_segment.segment_header; + if let Err(error) = + segment_headers_store.add_segment_headers(slice::from_ref(&segment_header)) + { + error!( + target: "subspace", + "Failed to store segment headers: {error}" + ); + return; + } + send_archived_segment_notification( &archived_segment_notification_sender, archived_segment, @@ -542,7 +760,7 @@ where let mut segment_headers = segment_headers.lock(); segment_headers.put(block_number + One::one(), new_segment_headers); - // Skip last 5 archived segments + // Skip last `FINALIZATION_DEPTH_IN_SEGMENTS` archived segments segment_headers .iter() .flat_map(|(_k, v)| v.iter().rev()) @@ -574,8 +792,11 @@ async fn send_archived_segment_notification( let segment_index = archived_segment.segment_header.segment_index(); let (acknowledgement_sender, mut acknowledgement_receiver) = tracing_unbounded::<()>("subspace_acknowledgement", 100); + // Keep `archived_segment` around until all acknowledgements are received since some receivers + // might use weak references + let archived_segment = Arc::new(archived_segment); let archived_segment_notification = ArchivedSegmentNotification { - archived_segment: Arc::new(archived_segment), + archived_segment: Arc::clone(&archived_segment), acknowledgement_sender, }; diff --git a/crates/sc-consensus-subspace/src/aux_schema.rs b/crates/sc-consensus-subspace/src/aux_schema.rs index 98d34b8e646..2485ee29969 100644 --- a/crates/sc-consensus-subspace/src/aux_schema.rs +++ b/crates/sc-consensus-subspace/src/aux_schema.rs @@ -21,7 +21,7 @@ use codec::{Decode, Encode}; use sc_client_api::backend::AuxStore; use sp_blockchain::{Error as ClientError, Result as ClientResult}; use sp_consensus_subspace::ChainConstants; -use subspace_core_primitives::{BlockWeight, SegmentCommitment, SegmentIndex}; +use subspace_core_primitives::BlockWeight; fn load_decode(backend: &B, key: &[u8]) -> ClientResult> where @@ -63,32 +63,6 @@ pub(crate) fn load_block_weight( load_decode(backend, block_weight_key(block_hash).as_slice()) } -/// The aux storage key used to store the segment commitment of the given segment. -fn segment_commitment_key(segment_index: SegmentIndex) -> Vec { - (b"segment_commitment", segment_index).encode() -} - -/// Write the cumulative segment commitment of a segment to aux storage. -pub(crate) fn write_segment_commitment( - segment_index: SegmentIndex, - segment_commitment: &SegmentCommitment, - write_aux: F, -) -> R -where - F: FnOnce(&[(Vec, &[u8])]) -> R, -{ - let key = segment_commitment_key(segment_index); - segment_commitment.using_encoded(|s| write_aux(&[(key, s)])) -} - -/// Load the cumulative chain-weight associated with a block. -pub(crate) fn load_segment_commitment( - backend: &B, - segment_index: SegmentIndex, -) -> ClientResult> { - load_decode(backend, segment_commitment_key(segment_index).as_slice()) -} - /// The aux storage key used to store the chain constants. fn chain_constants_key() -> Vec { b"chain_constants".encode() diff --git a/crates/sc-consensus-subspace/src/lib.rs b/crates/sc-consensus-subspace/src/lib.rs index 8f2d5dcca40..91538c0060a 100644 --- a/crates/sc-consensus-subspace/src/lib.rs +++ b/crates/sc-consensus-subspace/src/lib.rs @@ -16,7 +16,7 @@ // along with this program. If not, see . #![doc = include_str!("../README.md")] -#![feature(drain_filter, try_blocks)] +#![feature(try_blocks)] #![forbid(unsafe_code)] #![warn(missing_docs)] @@ -29,9 +29,9 @@ mod tests; use crate::archiver::FINALIZATION_DEPTH_IN_SEGMENTS; use crate::notification::{SubspaceNotificationSender, SubspaceNotificationStream}; -use crate::slot_worker::{SlotWorkerSyncOracle, SubspaceSlotWorker}; -pub use archiver::create_subspace_archiver; -use codec::Encode; +use crate::slot_worker::SubspaceSlotWorker; +pub use crate::slot_worker::SubspaceSyncOracle; +pub use archiver::{create_subspace_archiver, SegmentHeadersStore}; use futures::channel::mpsc; use futures::StreamExt; use log::{debug, info, trace, warn}; @@ -50,6 +50,7 @@ use sc_consensus::JustificationSyncLink; use sc_consensus_slots::{ check_equivocation, BackoffAuthoringBlocksStrategy, InherentDataProviderExt, SlotProportion, }; +use sc_proof_of_time::{PotConsensusState, PotVerifyBlockProofsError}; use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_TRACE}; use sc_utils::mpsc::TracingUnboundedSender; use schnorrkel::context::SigningContext; @@ -61,7 +62,8 @@ use sp_consensus::{ }; use sp_consensus_slots::{Slot, SlotDuration}; use sp_consensus_subspace::digests::{ - extract_pre_digest, extract_subspace_digest_items, Error as DigestError, SubspaceDigestItems, + extract_pre_digest, extract_subspace_digest_items, Error as DigestError, PreDigest, + SubspaceDigestItems, }; use sp_consensus_subspace::{ check_header, ChainConstants, CheckedHeader, FarmerPublicKey, FarmerSignature, SubspaceApi, @@ -69,18 +71,17 @@ use sp_consensus_subspace::{ }; use sp_core::H256; use sp_inherents::{CreateInherentDataProviders, InherentDataProvider}; -use sp_runtime::traits::One; +use sp_runtime::traits::{NumberFor as BlockNumberFor, One}; use std::future::Future; use std::marker::PhantomData; use std::num::NonZeroUsize; use std::pin::Pin; use std::sync::Arc; -use subspace_archiving::archiver::{Archiver, NewArchivedSegment}; +use subspace_archiving::archiver::NewArchivedSegment; use subspace_core_primitives::crypto::kzg::Kzg; -use subspace_core_primitives::objects::BlockObjectMapping; use subspace_core_primitives::{ - Blake2b256Hash, PublicKey, SectorId, SegmentCommitment, SegmentHeader, SegmentIndex, Solution, - SolutionRange, + BlockNumber, HistorySize, PublicKey, Randomness, SectorId, SegmentHeader, SegmentIndex, + SlotNumber, Solution, SolutionRange, }; use subspace_proof_of_space::Table; use subspace_solving::REWARD_SIGNING_CONTEXT; @@ -89,13 +90,40 @@ use subspace_verification::{ VerifySolutionParams, }; +/// Errors while verifying the block proof of time. +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum PotVerifyError { + /// Parent block has no proof of time digest. + #[error( + "Parent block missing proof of time : {block_number}/{parent_slot_number}/{slot_number}" + )] + ParentMissingPotDigest { + block_number: BlockNumberFor, + parent_slot_number: SlotNumber, + slot_number: SlotNumber, + }, + + /// Block has no proof of time digest. + #[error("Block missing proof of time : {block_number}/{parent_slot_number}/{slot_number}")] + MissingPotDigest { + block_number: BlockNumberFor, + parent_slot_number: SlotNumber, + slot_number: SlotNumber, + }, + + /// Verification failed. + #[error("Proof of time error: {0}")] + PotVerifyBlockProofsError(#[from] PotVerifyBlockProofsError), +} + /// Information about new slot that just arrived #[derive(Debug, Copy, Clone)] pub struct NewSlotInfo { /// Slot pub slot: Slot, - /// Global slot challenge - pub global_challenge: Blake2b256Hash, + /// Global randomness + pub global_randomness: Randomness, /// Acceptable solution range for block authoring pub solution_range: SolutionRange, /// Acceptable solution range for voting @@ -144,8 +172,8 @@ where { /// Block number pub block_number: NumberFor, - /// Sender for pausing the block import when executor is not fast enough to process - /// the primary block. + /// Sender for pausing the block import when operator is not fast enough to process + /// the consensus block. pub acknowledgement_sender: mpsc::Sender<()>, } @@ -229,7 +257,7 @@ pub enum Error { /// Stored segment header extrinsic was not found #[error("Stored segment header extrinsic was not found: {0:?}")] SegmentHeadersExtrinsicNotFound(Vec), - /// Duplicated segment commitment + /// Different segment commitment found #[error( "Different segment commitment for segment index {0} was found in storage, likely fork \ below archiving point" @@ -238,9 +266,20 @@ pub enum Error { /// Farmer in block list #[error("Farmer {0} is in block list")] FarmerInBlockList(FarmerPublicKey), - /// Merkle Root not found + /// Segment commitment not found #[error("Segment commitment for segment index {0} not found")] SegmentCommitmentNotFound(SegmentIndex), + /// Sector expired + #[error("Sector expired")] + SectorExpired { + /// Expiration history size + expiration_history_size: HistorySize, + /// Current history size + current_history_size: HistorySize, + }, + /// Invalid history size + #[error("Invalid history size")] + InvalidHistorySize, /// Only root plot public key is allowed #[error("Only root plot public key is allowed")] OnlyRootPlotPublicKeyAllowed, @@ -297,6 +336,14 @@ where Error::InvalidAuditChunkOffset } VerificationPrimitiveError::InvalidChunkWitness => Error::InvalidChunkWitness, + VerificationPrimitiveError::SectorExpired { + expiration_history_size, + current_history_size, + } => Error::SectorExpired { + expiration_history_size, + current_history_size, + }, + VerificationPrimitiveError::InvalidHistorySize => Error::InvalidHistorySize, }, } } @@ -330,7 +377,10 @@ where } /// Parameters for Subspace. -pub struct SubspaceParams { +pub struct SubspaceParams +where + SO: SyncOracle + Send + Sync, +{ /// The client to use pub client: Arc, @@ -346,7 +396,7 @@ pub struct SubspaceParams { pub block_import: I, /// A sync oracle - pub sync_oracle: SO, + pub sync_oracle: SubspaceSyncOracle, /// Hook into the sync module to control the justification sync process. pub justification_sync_link: L, @@ -363,6 +413,9 @@ pub struct SubspaceParams { /// The source of timestamps for relative slots pub subspace_link: SubspaceLink, + /// Persistent storage of segment headers + pub segment_headers_store: SegmentHeadersStore, + /// The proportion of the slot dedicated to proposing. /// /// The block proposing will be limited to this proportion of the slot from the starting of the @@ -376,10 +429,13 @@ pub struct SubspaceParams { /// Handle use to report telemetries. pub telemetry: Option, + + /// Proof of time interface. + pub proof_of_time: Option>, } /// Start the Subspace worker. -pub fn start_subspace( +pub fn start_subspace( SubspaceParams { client, select_chain, @@ -391,10 +447,12 @@ pub fn start_subspace force_authoring, backoff_authoring_blocks, subspace_link, + segment_headers_store, block_proposal_slot_portion, max_block_proposal_slot_portion, telemetry, - }: SubspaceParams, + proof_of_time, + }: SubspaceParams, ) -> Result where PosTable: Table, @@ -404,6 +462,7 @@ where + BlockchainEvents + HeaderBackend + HeaderMetadata + + AuxStore + Send + Sync + 'static, @@ -420,7 +479,9 @@ where CIDP: CreateInherentDataProviders + Send + Sync + 'static, CIDP::InherentDataProviders: InherentDataProviderExt + Send, BS: BackoffAuthoringBlocksStrategy> + Send + Sync + 'static, + AS: AuxStore + Send + Sync + 'static, Error: std::error::Error + Send + From + From + 'static, + BlockNumber: From<<::Header as HeaderT>::Number>, { let worker = SubspaceSlotWorker { client, @@ -435,6 +496,8 @@ where block_proposal_slot_portion, max_block_proposal_slot_portion, telemetry, + segment_headers_store, + proof_of_time, _pos_table: PhantomData::, }; @@ -443,10 +506,7 @@ where subspace_link.slot_duration(), select_chain, sc_consensus_slots::SimpleSlotWorkerToSlotWorker(worker), - SlotWorkerSyncOracle { - force_authoring, - inner: sync_oracle, - }, + sync_oracle, create_inherent_data_providers, ); @@ -533,25 +593,6 @@ impl SubspaceLink { .cloned() .unwrap_or_default() } - - /// Get the first found segment commitment by segment index. - pub fn segment_commitment_by_segment_index( - &self, - segment_index: SegmentIndex, - ) -> Option { - self.segment_headers - .lock() - .iter() - .find_map(|(_block_number, segment_headers)| { - segment_headers.iter().find_map(|segment_header| { - if segment_header.segment_index() == segment_index { - Some(segment_header.segment_commitment()) - } else { - None - } - }) - }) - } } /// A verifier for Subspace blocks. @@ -779,18 +820,23 @@ where } /// A block-import handler for Subspace. -pub struct SubspaceBlockImport { +pub struct SubspaceBlockImport +where + Block: BlockT, +{ inner: I, client: Arc, block_importing_notification_sender: SubspaceNotificationSender>, subspace_link: SubspaceLink, create_inherent_data_providers: CIDP, + segment_headers_store: SegmentHeadersStore, + proof_of_time: Option>, _pos_table: PhantomData, } -impl Clone - for SubspaceBlockImport +impl Clone + for SubspaceBlockImport where Block: BlockT, I: Clone, @@ -803,18 +849,22 @@ where block_importing_notification_sender: self.block_importing_notification_sender.clone(), subspace_link: self.subspace_link.clone(), create_inherent_data_providers: self.create_inherent_data_providers.clone(), + segment_headers_store: self.segment_headers_store.clone(), + proof_of_time: self.proof_of_time.clone(), _pos_table: PhantomData, } } } -impl SubspaceBlockImport +impl SubspaceBlockImport where PosTable: Table, Block: BlockT, Client: ProvideRuntimeApi + BlockBackend + HeaderBackend + AuxStore, Client::Api: BlockBuilderApi + SubspaceApi + ApiExt, CIDP: CreateInherentDataProviders> + Send + Sync + 'static, + AS: AuxStore + Send + Sync + 'static, + BlockNumber: From<<::Header as HeaderT>::Number>, { fn new( client: Arc, @@ -824,6 +874,8 @@ where >, subspace_link: SubspaceLink, create_inherent_data_providers: CIDP, + segment_headers_store: SegmentHeadersStore, + proof_of_time: Option>, ) -> Self { SubspaceBlockImport { client, @@ -831,6 +883,8 @@ where block_importing_notification_sender, subspace_link, create_inherent_data_providers, + segment_headers_store, + proof_of_time, _pos_table: PhantomData, } } @@ -854,7 +908,6 @@ where let parent_hash = *header.parent_hash(); let pre_digest = &subspace_digest_items.pre_digest; - if let Some(root_plot_public_key) = root_plot_public_key { if &pre_digest.solution.public_key != root_plot_public_key { // Only root plot public key is allowed. @@ -922,6 +975,20 @@ where None => parent_subspace_digest_items.solution_range, }; + if let Some(proof_of_time) = self.proof_of_time.as_ref() { + let ret = self.proof_of_time_verification( + proof_of_time.as_ref(), + block_number, + pre_digest, + &parent_subspace_digest_items.pre_digest, + ); + debug!( + target: "subspace", + "block_import_verification: {block_number}/{}/{}/{origin:?}, ret={ret:?}", + pre_digest.slot, parent_subspace_digest_items.pre_digest.slot + ); + } + (correct_global_randomness, correct_solution_range) }; @@ -938,40 +1005,41 @@ where pre_digest.solution.sector_index, ); - // TODO: Derive `pre_digest.solution.piece_offset` from local challenge instead - + let chain_constants = get_chain_constants(self.client.as_ref())?; + // TODO: Below `skip_runtime_access` has no impact on this, but ideally it + // should (though we don't support fast sync yet, so doesn't matter in + // practice) + let max_pieces_in_sector = self + .client + .runtime_api() + .max_pieces_in_sector(parent_hash)?; let piece_index = sector_id.derive_piece_index( pre_digest.solution.piece_offset, pre_digest.solution.history_size, + max_pieces_in_sector, + chain_constants.recent_segments(), + chain_constants.recent_history_fraction(), ); let segment_index = piece_index.segment_index(); - // This is not a very nice hack due to the fact that at the time first block is produced - // extrinsics with segment headers are not yet in runtime. - let maybe_segment_commitment = if block_number.is_one() { - let genesis_block_hash = self.client.info().genesis_hash; - let archived_segments = Archiver::new(self.subspace_link.kzg.clone()) - .expect("Incorrect parameters for archiver") - .add_block( - self.client - .block(genesis_block_hash)? - .ok_or(Error::GenesisUnavailable)? - .encode(), - BlockObjectMapping::default(), - ); - archived_segments.into_iter().find_map(|archived_segment| { - if archived_segment.segment_header.segment_index() == segment_index { - Some(archived_segment.segment_header.segment_commitment()) - } else { - None - } - }) - } else { - aux_schema::load_segment_commitment(self.client.as_ref(), segment_index)? - }; - - let segment_commitment = - maybe_segment_commitment.ok_or(Error::SegmentCommitmentNotFound(segment_index))?; + let segment_commitment = self + .segment_headers_store + .get_segment_header(segment_index) + .map(|segment_header| segment_header.segment_commitment()) + .ok_or(Error::SegmentCommitmentNotFound(segment_index))?; + + let sector_expiration_check_segment_commitment = self + .segment_headers_store + .get_segment_header( + subspace_digest_items + .pre_digest + .solution + .history_size + .sector_expiration_check(chain_constants.min_sector_lifetime()) + .ok_or(Error::InvalidHistorySize)? + .segment_index(), + ) + .map(|segment_header| segment_header.segment_commitment()); // Piece is not checked during initial block verification because it requires access to // segment header and runtime, check it now. @@ -983,14 +1051,16 @@ where global_randomness: subspace_digest_items.global_randomness, solution_range: subspace_digest_items.solution_range, piece_check_params: Some(PieceCheckParams { + max_pieces_in_sector, + segment_commitment, + recent_segments: chain_constants.recent_segments(), + recent_history_fraction: chain_constants.recent_history_fraction(), + min_sector_lifetime: chain_constants.min_sector_lifetime(), // TODO: Below `skip_runtime_access` has no impact on this, but ideally it // should (though we don't support fast sync yet, so doesn't matter in // practice) - max_pieces_in_sector: self - .client - .runtime_api() - .max_pieces_in_sector(parent_hash)?, - segment_commitment, + current_history_size: self.client.runtime_api().history_size(parent_hash)?, + sector_expiration_check_segment_commitment, }), }, &self.subspace_link.kzg, @@ -1043,11 +1113,48 @@ where Ok(()) } + + /// Verifies the proof of time in the received block. + #[allow(clippy::too_many_arguments)] + fn proof_of_time_verification( + &self, + proof_of_time: &dyn PotConsensusState, + block_number: NumberFor, + pre_digest: &PreDigest, + parent_pre_digest: &PreDigest, + ) -> Result<(), PotVerifyError> { + let parent_pot_digest = parent_pre_digest.proof_of_time.as_ref().ok_or_else(|| { + PotVerifyError::ParentMissingPotDigest { + block_number, + parent_slot_number: parent_pre_digest.slot.into(), + slot_number: pre_digest.slot.into(), + } + })?; + let pot_digest = + pre_digest + .proof_of_time + .as_ref() + .ok_or_else(|| PotVerifyError::MissingPotDigest { + block_number, + parent_slot_number: parent_pre_digest.slot.into(), + slot_number: pre_digest.slot.into(), + })?; + + proof_of_time + .verify_block_proofs( + block_number.into(), + pre_digest.slot.into(), + pot_digest, + parent_pre_digest.slot.into(), + parent_pot_digest, + ) + .map_err(PotVerifyError::PotVerifyBlockProofsError) + } } #[async_trait::async_trait] -impl BlockImport - for SubspaceBlockImport +impl BlockImport + for SubspaceBlockImport where PosTable: Table, Block: BlockT, @@ -1063,6 +1170,8 @@ where + Sync, Client::Api: BlockBuilderApi + SubspaceApi + ApiExt, CIDP: CreateInherentDataProviders> + Send + Sync + 'static, + AS: AuxStore + Send + Sync + 'static, + BlockNumber: From<<::Header as HeaderT>::Number>, { type Error = ConsensusError; type Transaction = TransactionFor; @@ -1132,23 +1241,29 @@ where }); for (&segment_index, segment_commitment) in &subspace_digest_items.segment_commitments { - if let Some(found_segment_commitment) = - aux_schema::load_segment_commitment(self.client.as_ref(), segment_index) - .map_err(|e| ConsensusError::ClientImport(e.to_string()))? - { - if &found_segment_commitment != segment_commitment { - return Err(ConsensusError::ClientImport( - Error::::DifferentSegmentCommitment(segment_index) - .to_string(), - )); - } + let found_segment_commitment = self + .segment_headers_store + .get_segment_header(segment_index) + .ok_or_else(|| { + ConsensusError::ClientImport(format!( + "Segment header for index {segment_index} not found" + )) + })? + .segment_commitment(); + + if &found_segment_commitment != segment_commitment { + warn!( + target: "subspace", + "Different segment commitment for segment index {} was found in storage, \ + likely fork below archiving point. expected {:?}, found {:?}", + segment_index, + segment_commitment, + found_segment_commitment + ); + return Err(ConsensusError::ClientImport( + Error::::DifferentSegmentCommitment(segment_index).to_string(), + )); } - - aux_schema::write_segment_commitment(segment_index, segment_commitment, |values| { - block - .auxiliary - .extend(values.iter().map(|(k, v)| (k.to_vec(), Some(v.to_vec())))) - }); } // The fork choice rule is that we pick the heaviest chain (i.e. smallest solution @@ -1235,14 +1350,16 @@ where /// /// Also returns a link object used to correctly instantiate the import queue and background worker. #[allow(clippy::type_complexity)] -pub fn block_import( +pub fn block_import( slot_duration: SlotDuration, wrapped_block_import: I, client: Arc, kzg: Kzg, create_inherent_data_providers: CIDP, + segment_headers_store: SegmentHeadersStore, + proof_of_time: Option>, ) -> ClientResult<( - SubspaceBlockImport, + SubspaceBlockImport, SubspaceLink, )> where @@ -1251,6 +1368,8 @@ where Client: ProvideRuntimeApi + BlockBackend + HeaderBackend + AuxStore, Client::Api: BlockBuilderApi + SubspaceApi, CIDP: CreateInherentDataProviders> + Send + Sync + 'static, + AS: AuxStore + Send + Sync + 'static, + BlockNumber: From<<::Header as HeaderT>::Number>, { let (new_slot_notification_sender, new_slot_notification_stream) = notification::channel("subspace_new_slot_notification_stream"); @@ -1291,6 +1410,8 @@ where block_importing_notification_sender, link.clone(), create_inherent_data_providers, + segment_headers_store, + proof_of_time, ); Ok((import, link)) diff --git a/crates/sc-consensus-subspace/src/slot_worker.rs b/crates/sc-consensus-subspace/src/slot_worker.rs index 7c5ac577784..2f4d9a33429 100644 --- a/crates/sc-consensus-subspace/src/slot_worker.rs +++ b/crates/sc-consensus-subspace/src/slot_worker.rs @@ -16,17 +16,19 @@ // along with this program. If not, see . use crate::{ - BlockImportingNotification, NewSlotInfo, NewSlotNotification, RewardSigningNotification, - SubspaceLink, + get_chain_constants, BlockImportingNotification, NewSlotInfo, NewSlotNotification, + RewardSigningNotification, SegmentHeadersStore, SubspaceLink, }; use futures::channel::mpsc; use futures::{StreamExt, TryFutureExt}; use log::{debug, error, info, warn}; +use sc_client_api::AuxStore; use sc_consensus::block_import::{BlockImport, BlockImportParams, StateAction}; use sc_consensus::{JustificationSyncLink, StorageChanges}; use sc_consensus_slots::{ BackoffAuthoringBlocksStrategy, SimpleSlotWorker, SlotInfo, SlotLenienceType, SlotProportion, }; +use sc_proof_of_time::{PotConsensusState, PotGetBlockProofsError}; use sc_telemetry::TelemetryHandle; use sc_utils::mpsc::tracing_unbounded; use schnorrkel::context::SigningContext; @@ -34,34 +36,59 @@ use sp_api::{ApiError, NumberFor, ProvideRuntimeApi, TransactionFor}; use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata}; use sp_consensus::{BlockOrigin, Environment, Error as ConsensusError, Proposer, SyncOracle}; use sp_consensus_slots::Slot; -use sp_consensus_subspace::digests::{extract_pre_digest, CompatibleDigestItem, PreDigest}; +use sp_consensus_subspace::digests::{ + extract_pre_digest, CompatibleDigestItem, PotPreDigest, PreDigest, +}; use sp_consensus_subspace::{FarmerPublicKey, FarmerSignature, SignedVote, SubspaceApi, Vote}; use sp_core::crypto::ByteArray; use sp_core::H256; -use sp_runtime::traits::{Block as BlockT, Header, One, Saturating, Zero}; +use sp_runtime::traits::{ + Block as BlockT, Header, NumberFor as BlockNumberFor, One, Saturating, Zero, +}; use sp_runtime::DigestItem; use std::future::Future; use std::marker::PhantomData; use std::pin::Pin; use std::sync::Arc; -use subspace_core_primitives::{PublicKey, Randomness, RewardSignature, SectorId, Solution}; +use subspace_core_primitives::{ + BlockNumber, PublicKey, Randomness, RewardSignature, SectorId, SlotNumber, Solution, +}; use subspace_proof_of_space::Table; use subspace_verification::{ check_reward_signature, verify_solution, PieceCheckParams, VerifySolutionParams, }; -#[derive(Clone)] -pub(super) struct SlotWorkerSyncOracle +/// Errors while building the block proof of time. +#[derive(Debug, thiserror::Error)] +pub enum PotCreateError { + /// Parent block has no proof of time digest. + #[error("Parent block missing proof of time : {parent_block_number}/{parent_slot_number}/{slot_number}")] + ParentMissingPotDigest { + parent_block_number: BlockNumberFor, + parent_slot_number: SlotNumber, + slot_number: SlotNumber, + }, + + /// Proof creation failed. + #[error("Proof of time error: {0}")] + PotGetBlockProofsError(#[from] PotGetBlockProofsError), +} + +/// Subspace sync oracle that takes into account force authoring flag, allowing to bootstrap +/// Subspace network from scratch due to our fork of Substrate where sync state of nodes depends on +/// connected nodes (none of which will be synced initially). +#[derive(Debug, Clone)] +pub struct SubspaceSyncOracle where - SO: SyncOracle + Send + Sync + Clone, + SO: SyncOracle + Send + Sync, { - pub(super) force_authoring: bool, - pub(super) inner: SO, + force_authoring: bool, + inner: SO, } -impl SyncOracle for SlotWorkerSyncOracle +impl SyncOracle for SubspaceSyncOracle where - SO: SyncOracle + Send + Sync + Clone, + SO: SyncOracle + Send + Sync, { fn is_major_syncing(&self) -> bool { // This allows slot worker to produce blocks even when it is offline, which according to @@ -75,7 +102,23 @@ where } } -pub(super) struct SubspaceSlotWorker { +impl SubspaceSyncOracle +where + SO: SyncOracle + Send + Sync, +{ + /// Create new instance + pub fn new(force_authoring: bool, substrate_sync_oracle: SO) -> Self { + Self { + force_authoring, + inner: substrate_sync_oracle, + } + } +} + +pub(super) struct SubspaceSlotWorker +where + Block: BlockT, +{ pub(super) client: Arc, pub(super) block_import: I, pub(super) env: E, @@ -88,27 +131,32 @@ pub(super) struct SubspaceSlotWorker, pub(super) telemetry: Option, + pub(super) segment_headers_store: SegmentHeadersStore, + pub(super) proof_of_time: Option>, pub(super) _pos_table: PhantomData, } #[async_trait::async_trait] -impl SimpleSlotWorker - for SubspaceSlotWorker +impl SimpleSlotWorker + for SubspaceSlotWorker where PosTable: Table, Block: BlockT, Client: ProvideRuntimeApi + HeaderBackend + HeaderMetadata + + AuxStore + 'static, Client::Api: SubspaceApi, E: Environment + Send + Sync, E::Proposer: Proposer>, I: BlockImport> + Send + Sync + 'static, - SO: SyncOracle + Send + Sync + Clone, + SO: SyncOracle + Send + Sync, L: JustificationSyncLink, BS: BackoffAuthoringBlocksStrategy> + Send + Sync, Error: std::error::Error + Send + From + From + 'static, + AS: AuxStore + Send + Sync + 'static, + BlockNumber: From<<::Header as Header>::Number>, { type BlockImport = I; type SyncOracle = SO; @@ -148,8 +196,8 @@ where slot: Slot, _epoch_data: &Self::AuxData, ) -> Option { - let parent_slot = match extract_pre_digest(parent_header) { - Ok(pre_digest) => pre_digest.slot, + let parent_pre_digest = match extract_pre_digest(parent_header) { + Ok(pre_digest) => pre_digest, Err(error) => { error!( target: "subspace", @@ -159,6 +207,7 @@ where return None; } }; + let parent_slot = parent_pre_digest.slot; if slot <= parent_slot { debug!( @@ -178,7 +227,6 @@ where extract_global_randomness_for_block(self.client.as_ref(), parent_hash).ok()?; let (solution_range, voting_solution_range) = extract_solution_ranges_for_block(self.client.as_ref(), parent_hash).ok()?; - let global_challenge = global_randomness.derive_global_challenge(slot.into()); let maybe_root_plot_public_key = self .client @@ -188,7 +236,7 @@ where let new_slot_info = NewSlotInfo { slot, - global_challenge, + global_randomness, solution_range, voting_solution_range, }; @@ -234,23 +282,23 @@ where solution.sector_index, ); - let segment_index = sector_id - .derive_piece_index(solution.piece_offset, solution.history_size) - .segment_index(); - let mut maybe_segment_commitment = runtime_api - .segment_commitment(parent_hash, segment_index) - .ok()?; - // TODO: This will be necessary for verifying sector expiration in the future - let _history_size = runtime_api.history_size(parent_hash).ok()?; + let history_size = runtime_api.history_size(parent_hash).ok()?; let max_pieces_in_sector = runtime_api.max_pieces_in_sector(parent_hash).ok()?; + let chain_constants = get_chain_constants(self.client.as_ref()).ok()?; - // This is not a very nice hack due to the fact that at the time first block is produced - // extrinsics with segment headers are not yet in runtime. - if maybe_segment_commitment.is_none() && parent_header.number().is_zero() { - maybe_segment_commitment = self - .subspace_link - .segment_commitment_by_segment_index(segment_index); - } + let segment_index = sector_id + .derive_piece_index( + solution.piece_offset, + solution.history_size, + max_pieces_in_sector, + chain_constants.recent_segments(), + chain_constants.recent_history_fraction(), + ) + .segment_index(); + let maybe_segment_commitment = self + .segment_headers_store + .get_segment_header(segment_index) + .map(|segment_header| segment_header.segment_commitment()); let segment_commitment = match maybe_segment_commitment { Some(segment_commitment) => segment_commitment, @@ -264,6 +312,18 @@ where continue; } }; + let sector_expiration_check_segment_index = match solution + .history_size + .sector_expiration_check(chain_constants.min_sector_lifetime()) + { + Some(sector_expiration_check) => sector_expiration_check.segment_index(), + None => { + continue; + } + }; + let sector_expiration_check_segment_commitment = runtime_api + .segment_commitment(parent_hash, sector_expiration_check_segment_index) + .ok()?; let solution_verification_result = verify_solution::( &solution, @@ -274,6 +334,11 @@ where piece_check_params: Some(PieceCheckParams { max_pieces_in_sector, segment_commitment, + recent_segments: chain_constants.recent_segments(), + recent_history_fraction: chain_constants.recent_history_fraction(), + min_sector_lifetime: chain_constants.min_sector_lifetime(), + current_history_size: history_size, + sector_expiration_check_segment_commitment, }), }, &self.subspace_link.kzg, @@ -285,8 +350,14 @@ where // block reward is claimed if maybe_pre_digest.is_none() && solution_distance <= solution_range / 2 { info!(target: "subspace", "🚜 Claimed block at slot {slot}"); - - maybe_pre_digest.replace(PreDigest { solution, slot }); + let proof_of_time = self + .build_block_pot(parent_header, &parent_pre_digest, slot.into()) + .ok()?; + maybe_pre_digest.replace(PreDigest { + solution, + slot, + proof_of_time, + }); } else if !parent_header.number().is_zero() { // Not sending vote on top of genesis block since segment headers since piece // verification wouldn't be possible due to missing (for now) segment commitment @@ -410,23 +481,26 @@ where } } -impl - SubspaceSlotWorker +impl + SubspaceSlotWorker where PosTable: Table, Block: BlockT, Client: ProvideRuntimeApi + HeaderBackend + HeaderMetadata + + AuxStore + 'static, Client::Api: SubspaceApi, E: Environment + Send + Sync, E::Proposer: Proposer>, I: BlockImport> + Send + Sync + 'static, - SO: SyncOracle + Send + Sync + Clone, + SO: SyncOracle + Send + Sync, L: JustificationSyncLink, BS: BackoffAuthoringBlocksStrategy> + Send + Sync, Error: std::error::Error + Send + From + From + 'static, + AS: AuxStore + Send + Sync + 'static, + BlockNumber: From<<::Header as Header>::Number>, { async fn create_vote( &self, @@ -510,6 +584,59 @@ where public_key.to_raw_vec() ))) } + + /// Builds the proof of time for the block being proposed. + fn build_block_pot( + &self, + parent_header: &Block::Header, + parent_pre_digest: &PreDigest, + slot_number: SlotNumber, + ) -> Result, PotCreateError> { + let proof_of_time = match &self.proof_of_time { + Some(proof_of_time) => proof_of_time.clone(), + _ => { + // PoT feature disabled. + return Ok(None); + } + }; + let block_number = *parent_header.number() + One::one(); + + // Block 1 does not have proofs + if block_number.is_one() { + return Ok(Some(PotPreDigest::FirstBlock(slot_number))); + } + + // Block 2 onwards. + // Get the start slot number for the proofs in the new block. + let parent_pot_digest = parent_pre_digest.proof_of_time.as_ref().ok_or_else(|| { + // PoT needs to be present in the block if feature is enabled. + PotCreateError::ParentMissingPotDigest { + parent_block_number: *parent_header.number(), + parent_slot_number: parent_pre_digest.slot.into(), + slot_number, + } + })?; + + proof_of_time + .get_block_proofs(block_number.into(), slot_number, parent_pot_digest) + .map(|proofs| { + let proof_of_time = PotPreDigest::new(proofs); + debug!( + target: "subspace", + "build_block_pot: {block_number}/{}/{slot_number}, PoT=[{proof_of_time:?}]", + parent_pre_digest.slot + ); + Some(proof_of_time) + }) + .map_err(|err| { + debug!( + target: "subspace", + "build_block_pot: {block_number}/{}/{slot_number}, err={err:?}", + parent_pre_digest.slot + ); + PotCreateError::PotGetBlockProofsError(err) + }) + } } // TODO: Replace with querying parent block header when breaking protocol diff --git a/crates/sc-proof-of-time/Cargo.toml b/crates/sc-proof-of-time/Cargo.toml new file mode 100644 index 00000000000..b14bac05b9c --- /dev/null +++ b/crates/sc-proof-of-time/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "sc-proof-of-time" +description = "Subspace proof of time implementation" +license = "MIT OR Apache-2.0" +version = "0.1.0" +authors = ["Rahul Subramaniyam "] +edition = "2021" +include = [ + "/src", + "/Cargo.toml", +] + +[dependencies] +futures = "0.3.28" +parity-scale-codec = { version = "3.6.1", features = ["derive"] } +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } +subspace-proof-of-time = { version = "0.1.0", path = "../subspace-proof-of-time" } +parking_lot = "0.12.1" +thiserror = "1.0.38" +tokio = { version = "1.28.2", features = ["time"] } +tracing = "0.1.37" diff --git a/crates/sc-proof-of-time/src/gossip.rs b/crates/sc-proof-of-time/src/gossip.rs new file mode 100644 index 00000000000..874a7706c09 --- /dev/null +++ b/crates/sc-proof-of-time/src/gossip.rs @@ -0,0 +1,185 @@ +//! PoT gossip functionality. + +use crate::state_manager::PotProtocolState; +use futures::{FutureExt, StreamExt}; +use parity_scale_codec::Decode; +use parking_lot::{Mutex, RwLock}; +use sc_network::config::NonDefaultSetConfig; +use sc_network::PeerId; +use sc_network_gossip::{ + GossipEngine, MessageIntent, Syncing as GossipSyncing, ValidationResult, Validator, + ValidatorContext, +}; +use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT}; +use std::collections::HashSet; +use std::sync::Arc; +use subspace_core_primitives::crypto::blake2b_256_hash; +use subspace_core_primitives::PotProof; +use subspace_proof_of_time::ProofOfTime; +use tracing::{error, trace}; + +pub(crate) const GOSSIP_PROTOCOL: &str = "/subspace/subspace-proof-of-time"; + +type MessageHash = [u8; 32]; + +/// PoT gossip components. +#[derive(Clone)] +pub(crate) struct PotGossip { + engine: Arc>>, + validator: Arc, +} + +impl PotGossip { + /// Creates the gossip components. + pub(crate) fn new( + network: Network, + sync: Arc, + pot_state: Arc, + proof_of_time: ProofOfTime, + ) -> Self + where + Network: sc_network_gossip::Network + Send + Sync + Clone + 'static, + GossipSync: GossipSyncing + 'static, + { + let validator = Arc::new(PotGossipValidator::new(pot_state, proof_of_time)); + let engine = Arc::new(Mutex::new(GossipEngine::new( + network, + sync, + GOSSIP_PROTOCOL, + validator.clone(), + None, + ))); + Self { engine, validator } + } + + /// Gossips the message to the network. + pub(crate) fn gossip_message(&self, message: Vec) { + self.validator.on_broadcast(&message); + self.engine + .lock() + .gossip_message(topic::(), message, false); + } + + /// Runs the loop to process incoming messages. + /// Returns when the gossip engine terminates. + pub(crate) async fn process_incoming_messages<'a>( + &self, + process_fn: Arc, + ) { + let message_receiver = self.engine.lock().messages_for(topic::()); + let mut incoming_messages = Box::pin(message_receiver.filter_map( + // Filter out messages without sender or fail to decode. + // TODO: penalize nodes that send garbled messages. + |notification| async move { + let mut ret = None; + if let Some(sender) = notification.sender { + if let Ok(msg) = PotProof::decode(&mut ¬ification.message[..]) { + ret = Some((sender, msg)) + } + } + ret + }, + )); + + loop { + let gossip_engine_poll = + futures::future::poll_fn(|cx| self.engine.lock().poll_unpin(cx)); + futures::select! { + gossiped = incoming_messages.next().fuse() => { + if let Some((sender, proof)) = gossiped { + (process_fn)(sender, proof); + } + }, + _ = gossip_engine_poll.fuse() => { + error!("Gossip engine has terminated."); + return; + } + } + } + } +} + +/// Validator for gossiped messages +struct PotGossipValidator { + pot_state: Arc, + proof_of_time: ProofOfTime, + pending: RwLock>, +} + +impl PotGossipValidator { + /// Creates the validator. + fn new(pot_state: Arc, proof_of_time: ProofOfTime) -> Self { + Self { + pot_state, + proof_of_time, + pending: RwLock::new(HashSet::new()), + } + } + + /// Called when the message is broadcast. + fn on_broadcast(&self, msg: &[u8]) { + let hash = blake2b_256_hash(msg); + let mut pending = self.pending.write(); + pending.insert(hash); + } +} + +impl Validator for PotGossipValidator { + fn validate( + &self, + _context: &mut dyn ValidatorContext, + sender: &PeerId, + mut data: &[u8], + ) -> ValidationResult { + match PotProof::decode(&mut data) { + Ok(proof) => { + // Perform AES verification only if the proof is a candidate. + if let Err(err) = self.pot_state.is_candidate(*sender, &proof) { + trace!("gossip::validate: not a candidate: {err:?}"); + ValidationResult::Discard + } else if let Err(err) = self.proof_of_time.verify(&proof) { + trace!("gossip::validate: verification failed: {err:?}"); + ValidationResult::Discard + } else { + ValidationResult::ProcessAndKeep(topic::()) + } + } + Err(_) => ValidationResult::Discard, + } + } + + fn message_expired<'a>(&'a self) -> Box bool + 'a> { + Box::new(move |_topic, data| { + let hash = blake2b_256_hash(data); + let pending = self.pending.read(); + !pending.contains(&hash) + }) + } + + fn message_allowed<'a>( + &'a self, + ) -> Box bool + 'a> { + Box::new(move |_who, _intent, _topic, data| { + let hash = blake2b_256_hash(data); + let mut pending = self.pending.write(); + if pending.contains(&hash) { + pending.remove(&hash); + true + } else { + false + } + }) + } +} + +/// PoT message topic. +fn topic() -> Block::Hash { + <::Hashing as HashT>::hash(b"subspace-proof-of-time-gossip") +} + +/// Returns the network configuration for PoT gossip. +pub fn pot_gossip_peers_set_config() -> NonDefaultSetConfig { + let mut cfg = NonDefaultSetConfig::new(GOSSIP_PROTOCOL.into(), 5 * 1024 * 1024); + cfg.allow_non_reserved(25, 25); + cfg +} diff --git a/crates/sc-proof-of-time/src/lib.rs b/crates/sc-proof-of-time/src/lib.rs new file mode 100644 index 00000000000..5fc46745e33 --- /dev/null +++ b/crates/sc-proof-of-time/src/lib.rs @@ -0,0 +1,110 @@ +//! Subspace proof of time implementation. + +#![feature(const_option)] + +mod gossip; +mod node_client; +mod state_manager; +mod time_keeper; +mod utils; + +use crate::state_manager::{init_pot_state, PotProtocolState}; +use core::num::{NonZeroU32, NonZeroU8}; +use std::sync::Arc; +use subspace_core_primitives::{BlockNumber, SlotNumber}; +use subspace_proof_of_time::ProofOfTime; + +pub use gossip::pot_gossip_peers_set_config; +pub use node_client::PotClient; +pub use state_manager::{ + PotConsensusState, PotGetBlockProofsError, PotStateSummary, PotVerifyBlockProofsError, +}; +pub use time_keeper::TimeKeeper; + +// TODO: change the fields that can't be zero to NonZero types. +#[derive(Debug, Clone)] +pub struct PotConfig { + /// Frequency of entropy injection from consensus. + pub randomness_update_interval_blocks: BlockNumber, + + /// Starting point for entropy injection from consensus. + pub injection_depth_blocks: BlockNumber, + + /// Number of slots it takes for updated global randomness to + /// take effect. + pub global_randomness_reveal_lag_slots: SlotNumber, + + /// Number of slots it takes for injected randomness to + /// take effect. + pub pot_injection_lag_slots: SlotNumber, + + /// If the received proof is more than max_future_slots into the + /// future from the current tip's slot, reject it. + pub max_future_slots: SlotNumber, + + /// Total iterations per proof. + pub pot_iterations: NonZeroU32, + + /// Number of checkpoints per proof. + pub num_checkpoints: NonZeroU8, +} + +impl Default for PotConfig { + fn default() -> Self { + // TODO: fill proper values. These are set to use less + // CPU and take less than 1 sec to produce per proof + // during the initial testing. + Self { + randomness_update_interval_blocks: 18, + injection_depth_blocks: 90, + global_randomness_reveal_lag_slots: 6, + pot_injection_lag_slots: 6, + max_future_slots: 10, + pot_iterations: NonZeroU32::new(4 * 1_000).expect("Not zero; qed"), + num_checkpoints: NonZeroU8::new(4).expect("Not zero; qed"), + } + } +} + +/// Components initialized during the new_partial() phase of set up. +pub struct PotComponents { + /// If the role is time keeper or node client. + is_time_keeper: bool, + + /// Proof of time implementation. + proof_of_time: ProofOfTime, + + /// Protocol state. + protocol_state: Arc, + + /// Consensus state. + consensus_state: Arc, +} + +impl PotComponents { + /// Sets up the partial components. + pub fn new(is_time_keeper: bool) -> Self { + let config = PotConfig::default(); + let proof_of_time = ProofOfTime::new(config.pot_iterations, config.num_checkpoints) + // TODO: Proper error handling or proof + .expect("Failed to initialize proof of time"); + let (protocol_state, consensus_state) = init_pot_state(config); + + Self { + is_time_keeper, + proof_of_time, + protocol_state, + consensus_state, + } + } + + /// Checks if the role is time keeper or node client. + pub fn is_time_keeper(&self) -> bool { + self.is_time_keeper + } + + /// Returns the consensus interface. + pub fn consensus_state(&self) -> Arc { + self.consensus_state.clone() + } +} diff --git a/crates/sc-proof-of-time/src/node_client.rs b/crates/sc-proof-of-time/src/node_client.rs new file mode 100644 index 00000000000..5117528f584 --- /dev/null +++ b/crates/sc-proof-of-time/src/node_client.rs @@ -0,0 +1,115 @@ +//! Consensus node interface to the time keeper network. + +use crate::gossip::PotGossip; +use crate::state_manager::PotProtocolState; +use crate::utils::get_consensus_tip; +use crate::PotComponents; +use sc_network::PeerId; +use sc_network_gossip::{Network as GossipNetwork, Syncing as GossipSyncing}; +use sp_blockchain::{HeaderBackend, Info}; +use sp_consensus::SyncOracle; +use sp_core::H256; +use sp_runtime::traits::Block as BlockT; +use std::sync::Arc; +use std::time::Instant; +use subspace_core_primitives::PotProof; +use tracing::{error, info, trace}; + +/// The PoT client implementation +pub struct PotClient, Client, SO> { + pot_state: Arc, + gossip: PotGossip, + client: Arc, + sync_oracle: Arc, + chain_info_fn: Arc Info + Send + Sync>, +} + +impl PotClient +where + Block: BlockT, + Client: HeaderBackend, + SO: SyncOracle + Send + Sync + Clone + 'static, +{ + /// Creates the PoT client instance. + pub fn new( + components: PotComponents, + client: Arc, + sync_oracle: Arc, + network: Network, + sync: Arc, + chain_info_fn: Arc Info + Send + Sync>, + ) -> Self + where + Network: GossipNetwork + Send + Sync + Clone + 'static, + GossipSync: GossipSyncing + 'static, + { + Self { + pot_state: components.protocol_state.clone(), + gossip: PotGossip::new( + network, + sync, + components.protocol_state, + components.proof_of_time, + ), + client, + sync_oracle, + chain_info_fn, + } + } + + /// Runs the node client processing loop. + pub async fn run(self) { + self.initialize().await; + let handle_gossip_message: Arc = + Arc::new(|sender, proof| { + self.handle_gossip_message(sender, proof); + }); + self.gossip + .process_incoming_messages(handle_gossip_message) + .await; + error!("pot_client: gossip engine has terminated."); + } + + /// Initializes the chain state from the consensus tip info. + async fn initialize(&self) { + // Wait for a block with proofs. + info!("pot_client::initialize: waiting for initialization ..."); + let delay = tokio::time::Duration::from_secs(1); + let proofs = loop { + // TODO: Proper error handling or proof + let tip = get_consensus_tip( + self.client.clone(), + self.sync_oracle.clone(), + self.chain_info_fn.clone(), + ) + .await + .expect("Consensus tip info should be available"); + + if let Some(proofs) = tip.pot_pre_digest.proofs().cloned() { + info!( + "pot_client::initialization done: block_hash={:?}, block_number={}, slot_number={}, {:?}", + tip.block_hash, tip.block_number, tip.slot_number, tip.pot_pre_digest + ); + break proofs; + } + + trace!("pot_client::initialize: {tip:?}, no proofs yet, to wait ...",); + tokio::time::sleep(delay).await; + }; + + self.pot_state.reset(proofs); + } + + /// Handles the incoming gossip message. + fn handle_gossip_message(&self, sender: PeerId, proof: PotProof) { + let start_ts = Instant::now(); + let ret = self.pot_state.on_proof_from_peer(sender, &proof); + let elapsed = start_ts.elapsed(); + + if let Err(err) = ret { + trace!("pot_client::on gossip: {err:?}, {sender}"); + } else { + trace!("pot_client::on gossip: {proof}, time=[{elapsed:?}], {sender}"); + } + } +} diff --git a/crates/sc-proof-of-time/src/state_manager.rs b/crates/sc-proof-of-time/src/state_manager.rs new file mode 100644 index 00000000000..c4fa73623bf --- /dev/null +++ b/crates/sc-proof-of-time/src/state_manager.rs @@ -0,0 +1,673 @@ +//! PoT state management. + +use crate::PotConfig; +use core::num::NonZeroUsize; +use parking_lot::Mutex; +use sc_network::PeerId; +use sp_consensus_subspace::digests::PotPreDigest; +use std::collections::btree_map::Entry; +use std::collections::{BTreeMap, VecDeque}; +use std::sync::Arc; +use subspace_core_primitives::{BlockNumber, NonEmptyVec, PotKey, PotProof, PotSeed, SlotNumber}; + +/// The maximum size of the PoT chain to keep (about 5 min worth of proofs for now). +/// TODO: remove this when purging is implemented. +const POT_CHAIN_MAX_SIZE: NonZeroUsize = NonZeroUsize::new(300).expect("Not zero; qed"); + +/// Error codes for PotProtocolState APIs. +#[derive(Debug, thiserror::Error)] +pub(crate) enum PotProtocolStateError { + #[error("Failed to extend chain: {expected}/{actual}")] + TipMismatch { + expected: SlotNumber, + actual: SlotNumber, + }, + + #[error("Proof for an older slot number: {tip_slot}/{proof_slot}")] + StaleProof { + tip_slot: SlotNumber, + proof_slot: SlotNumber, + }, + + #[error("Proof had an unexpected seed: {expected:?}/{actual:?}")] + InvalidSeed { expected: PotSeed, actual: PotSeed }, + + #[error("Proof had an unexpected key: {expected:?}/{actual:?}")] + InvalidKey { expected: PotKey, actual: PotKey }, + + #[error("Proof is too much into future: {tip_slot}/{proof_slot}")] + TooFuturistic { + tip_slot: SlotNumber, + proof_slot: SlotNumber, + }, + + #[error("Duplicate proof from peer: {0:?}")] + DuplicateProofFromPeer(PeerId), +} + +/// Error codes for PotConsensusState::get_block_proofs(). +#[derive(Debug, thiserror::Error)] +pub enum PotGetBlockProofsError { + #[error("Failed to get start slot: {summary:?}/{block_number}/{proof_slot}/{current_slot}")] + StartSlotMissing { + summary: PotStateSummary, + block_number: BlockNumber, + proof_slot: SlotNumber, + current_slot: SlotNumber, + }, + + #[error( + "Invalid slot range: {summary:?}/{block_number}/{start_slot}/{proof_slot}/{current_slot}" + )] + InvalidRange { + summary: PotStateSummary, + block_number: BlockNumber, + start_slot: SlotNumber, + proof_slot: SlotNumber, + current_slot: SlotNumber, + }, + + #[error("Proof unavailable to send: {summary:?}/{block_number}/{missing_slot}/{current_slot}")] + ProofUnavailable { + summary: PotStateSummary, + block_number: BlockNumber, + missing_slot: SlotNumber, + current_slot: SlotNumber, + }, +} + +/// Error codes for PotConsensusState::verify_block_proofs(). +#[derive(Debug, thiserror::Error)] +pub enum PotVerifyBlockProofsError { + #[error("Block has no proofs: {summary:?}/{block_number}/{slot}/{parent_slot}")] + NoProofs { + summary: PotStateSummary, + block_number: BlockNumber, + slot: SlotNumber, + parent_slot: SlotNumber, + }, + + #[error("Failed to get start slot: {summary:?}/{block_number}/{slot}/{parent_slot}")] + StartSlotMissing { + summary: PotStateSummary, + block_number: BlockNumber, + slot: SlotNumber, + parent_slot: SlotNumber, + }, + + #[error("Unexpected slot number: {summary:?}/{block_number}/{slot}/{parent_slot}/{expected_slot}/{actual_slot}")] + UnexpectedSlot { + summary: PotStateSummary, + block_number: BlockNumber, + slot: SlotNumber, + parent_slot: SlotNumber, + expected_slot: SlotNumber, + actual_slot: SlotNumber, + }, + + #[error( + "Local chain missing proof: {summary:?}/{block_number}/{slot}/{parent_slot}/{missing_slot}" + )] + LocalChainMissingProof { + summary: PotStateSummary, + block_number: BlockNumber, + slot: SlotNumber, + parent_slot: SlotNumber, + missing_slot: SlotNumber, + }, + + #[error("Mismatch with local proof: {summary:?}/{block_number}/{slot}/{parent_slot}/{mismatch_slot}")] + ProofMismatch { + summary: PotStateSummary, + block_number: BlockNumber, + slot: SlotNumber, + parent_slot: SlotNumber, + mismatch_slot: SlotNumber, + }, +} + +/// Summary of the current state. +#[derive(Debug, Clone)] +pub struct PotStateSummary { + /// Current tip. + pub tip: Option, + + /// Length of chain. + pub chain_length: usize, +} + +/// Wrapper around the PoT chain. +struct PotChain { + entries: VecDeque, + max_entries: usize, +} + +impl PotChain { + /// Creates the chain. + fn new(max_entries: NonZeroUsize) -> Self { + Self { + entries: VecDeque::new(), + max_entries: max_entries.get(), + } + } + + /// Resets the chain to the given entries. + fn reset(&mut self, proofs: NonEmptyVec) { + self.entries.clear(); + for proof in proofs.to_vec() { + self.extend(proof); + } + } + + /// Helper to extend the chain. + fn extend(&mut self, proof: PotProof) { + if let Some(tip) = self.entries.back() { + // This is a debug assert for now, as this should not happen. + // Change to return error if needed. + debug_assert!((tip.slot_number + 1) == proof.slot_number); + } + if self.entries.len() == self.max_entries { + // Evict the oldest entry if full + self.entries.pop_front(); + } + self.entries.push_back(proof); + } + + /// Returns the last entry in the chain. + fn tip(&self) -> Option { + self.entries.back().cloned() + } + + /// Returns the length of the chain. + fn len(&self) -> usize { + self.entries.len() + } + + /// Returns an iterator to the entries. + fn iter(&self) -> Box + '_> { + Box::new(self.entries.iter()) + } +} + +/// The shared PoT state. +struct InternalState { + /// Config. + config: PotConfig, + + /// Last N entries of the PotChain, sorted by height. + /// TODO: purging to be implemented. + chain: PotChain, + + /// Proofs for future slot numbers, indexed by slot number. + /// Each entry holds the proofs indexed by sender. The proofs + /// are already verified before being added to the future list. + /// TODO: limit the number of proofs per future slot. + future_proofs: BTreeMap>, +} + +impl InternalState { + /// Creates the state. + fn new(config: PotConfig) -> Self { + Self { + config, + chain: PotChain::new(POT_CHAIN_MAX_SIZE), + future_proofs: BTreeMap::new(), + } + } + + /// Re-initializes the state with the given chain. + fn reset(&mut self, proofs: NonEmptyVec) { + self.chain.reset(proofs); + self.future_proofs.clear(); + } + + /// Adds the proof to the current tip and merged possible future proofs. + fn extend_and_merge(&mut self, proof: PotProof) { + self.future_proofs.remove(&proof.slot_number); + self.chain.extend(proof); + self.merge_future_proofs(); + } + + /// Tries to extend the chain with the locally produced proof. + fn handle_local_proof(&mut self, proof: &PotProof) -> Result<(), PotProtocolStateError> { + let tip = match self.chain.tip() { + Some(tip) => tip, + None => { + self.extend_and_merge(proof.clone()); + return Ok(()); + } + }; + + if (tip.slot_number + 1) == proof.slot_number { + self.extend_and_merge(proof.clone()); + Ok(()) + } else { + // The tip moved by the time the proof was computed. + Err(PotProtocolStateError::TipMismatch { + expected: tip.slot_number + 1, + actual: proof.slot_number, + }) + } + } + + /// Tries to extend the chain with the proof received from a peer. + /// The proof is assumed to have passed the AES verification. + fn handle_peer_proof( + &mut self, + sender: PeerId, + proof: &PotProof, + ) -> Result<(), PotProtocolStateError> { + let tip = match self.chain.tip() { + Some(tip) => tip.clone(), + None => { + self.extend_and_merge(proof.clone()); + return Ok(()); + } + }; + + // Case 1: the proof is for an older slot + if proof.slot_number <= tip.slot_number { + return Err(PotProtocolStateError::StaleProof { + tip_slot: tip.slot_number, + proof_slot: proof.slot_number, + }); + } + + // Case 2: the proof extends the tip + if (tip.slot_number + 1) == proof.slot_number { + let expected_seed = tip.next_seed(None); + if proof.seed != expected_seed { + return Err(PotProtocolStateError::InvalidSeed { + expected: expected_seed, + actual: proof.seed, + }); + } + + let expected_key = tip.next_key(); + if proof.key != expected_key { + return Err(PotProtocolStateError::InvalidKey { + expected: expected_key, + actual: proof.key, + }); + } + + // All checks passed, advance the tip with the new proof + self.extend_and_merge(proof.clone()); + return Ok(()); + } + + // Case 3: proof for a future slot + self.handle_future_proof(&tip, sender, proof) + } + + /// Checks if the proof is a possible candidate. + fn is_candidate(&self, _sender: PeerId, proof: &PotProof) -> Result<(), PotProtocolStateError> { + let tip = match self.chain.tip() { + Some(tip) => tip.clone(), + None => { + // Chain is empty, possible first proof. + return Ok(()); + } + }; + + // Case 1: the proof is for an older slot. + // When same proof is gossiped by multiple peers, this check + // could help early discard of the duplicates. + if proof.slot_number <= tip.slot_number { + return Err(PotProtocolStateError::StaleProof { + tip_slot: tip.slot_number, + proof_slot: proof.slot_number, + }); + } + + // Case 2: the proof extends the tip + if (tip.slot_number + 1) == proof.slot_number { + let expected_seed = tip.next_seed(None); + if proof.seed != expected_seed { + return Err(PotProtocolStateError::InvalidSeed { + expected: expected_seed, + actual: proof.seed, + }); + } + + let expected_key = tip.next_key(); + if proof.key != expected_key { + return Err(PotProtocolStateError::InvalidKey { + expected: expected_key, + actual: proof.key, + }); + } + } + + // Case 3: future proof + // TODO: add more filtering for future proofs + Ok(()) + } + + /// Handles the received proof for a future slot. + fn handle_future_proof( + &mut self, + tip: &PotProof, + sender: PeerId, + proof: &PotProof, + ) -> Result<(), PotProtocolStateError> { + // Reject if too much into future + if (proof.slot_number - tip.slot_number) > self.config.max_future_slots { + return Err(PotProtocolStateError::TooFuturistic { + tip_slot: tip.slot_number, + proof_slot: proof.slot_number, + }); + } + + match self.future_proofs.entry(proof.slot_number) { + Entry::Vacant(entry) => { + let mut proofs = BTreeMap::new(); + proofs.insert(sender, proof.clone()); + entry.insert(proofs); + Ok(()) + } + Entry::Occupied(mut entry) => { + let proofs_for_slot = entry.get_mut(); + // Reject if the sender already sent a proof for same slot number. + if proofs_for_slot.contains_key(&sender) { + return Err(PotProtocolStateError::DuplicateProofFromPeer(sender)); + } + + // TODO: put a max limit on future proofs per slot number. + proofs_for_slot.insert(sender, proof.clone()); + Ok(()) + } + } + } + + /// Called when the chain is extended with a new proof. + /// Tries to advance the tip as much as possible, by merging with + /// the pending future proofs. + fn merge_future_proofs(&mut self) { + let mut cur_tip = self.chain.tip(); + while let Some(tip) = cur_tip.as_ref() { + // At this point, we know the expected seed/key for the next proof + // in the sequence. If there is at least an entry with the expected + // key/seed(there could be several from different peers), extend the + // chain. + let next_slot = tip.slot_number + 1; + let proofs_for_slot = match self.future_proofs.remove(&next_slot) { + Some(proofs) => proofs, + None => return, + }; + + let next_seed = tip.next_seed(None); + let next_key = tip.next_key(); + match proofs_for_slot + .values() + .find(|proof| proof.seed == next_seed && proof.key == next_key) + .cloned() + { + Some(next_proof) => { + // Extend the tip with the next proof, continue merging. + self.chain.extend(next_proof.clone()); + cur_tip = Some(next_proof); + } + None => { + // TODO: penalize peers that sent invalid key/seed + return; + } + } + } + } + + /// Returns the proofs for the block. + fn get_block_proofs( + &self, + block_number: BlockNumber, + current_slot: SlotNumber, + parent_pre_digest: &PotPreDigest, + ) -> Result, PotGetBlockProofsError> { + let summary = self.summary(); + let proof_slot = current_slot - self.config.global_randomness_reveal_lag_slots; + let start_slot = parent_pre_digest.next_block_initial_slot().ok_or_else(|| { + PotGetBlockProofsError::StartSlotMissing { + summary: summary.clone(), + block_number, + proof_slot, + current_slot, + } + })?; + + if start_slot > proof_slot { + return Err(PotGetBlockProofsError::InvalidRange { + summary: summary.clone(), + block_number, + start_slot, + proof_slot, + current_slot, + }); + } + + // Collect the proofs in the requested range. + let mut proofs = Vec::with_capacity((proof_slot - start_slot + 1) as usize); + let mut iter = self.chain.iter().skip_while(|p| p.slot_number < start_slot); + for slot in start_slot..=proof_slot { + if let Some(proof) = iter.next() { + debug_assert!(proof.slot_number == slot); + proofs.push(proof.clone()); + } else { + return Err(PotGetBlockProofsError::ProofUnavailable { + summary: summary.clone(), + block_number, + missing_slot: slot, + current_slot, + }); + } + } + + Ok(NonEmptyVec::new(proofs).expect("NonEmptyVec cannot fail with non-empty inputs")) + } + + /// Verifies the block proofs. + fn verify_block_proofs( + &self, + block_number: BlockNumber, + slot_number: SlotNumber, + pre_digest: &PotPreDigest, + parent_slot_number: SlotNumber, + parent_pre_digest: &PotPreDigest, + ) -> Result<(), PotVerifyBlockProofsError> { + let summary = self.summary(); + let block_proofs = pre_digest + .proofs() + .ok_or(PotVerifyBlockProofsError::NoProofs { + summary: summary.clone(), + block_number, + slot: slot_number, + parent_slot: parent_slot_number, + })?; + + // Get the expected slot of the first proof in this block. + let start_slot = parent_pre_digest.next_block_initial_slot().ok_or_else(|| { + PotVerifyBlockProofsError::StartSlotMissing { + summary: summary.clone(), + block_number, + slot: slot_number, + parent_slot: parent_slot_number, + } + })?; + + // Since we check the first proof starts with the parent.last_proof.slot + 1, + // and we already verified the seed/key of the proofs in the chain were was + // correctly derived from the previous proof, this implies correct chain continuity + // from parent. + let mut local_proofs_iter = self.chain.iter().skip_while(|p| p.slot_number < start_slot); + for received in block_proofs.iter() { + if let Some(local_proof) = local_proofs_iter.next() { + // The received proof should match the proof in the local chain. No need to + // perform AES verification, as local proof is already verified. + if *local_proof != *received { + return Err(PotVerifyBlockProofsError::ProofMismatch { + summary: summary.clone(), + block_number, + slot: slot_number, + parent_slot: parent_slot_number, + mismatch_slot: received.slot_number, + }); + } + } else { + // TODO: extend local chain with proofs in the block. + return Err(PotVerifyBlockProofsError::LocalChainMissingProof { + summary: summary.clone(), + block_number, + slot: slot_number, + parent_slot: parent_slot_number, + missing_slot: received.slot_number, + }); + } + } + + Ok(()) + } + + /// Returns the current tip of the chain. + fn tip(&self) -> Option { + self.chain.tip() + } + + /// Returns the summary of the current state. + fn summary(&self) -> PotStateSummary { + PotStateSummary { + tip: self.chain.tip().map(|proof| proof.slot_number), + chain_length: self.chain.len(), + } + } +} + +/// Wrapper to manage the state. +struct StateManager { + /// The PoT state + state: Mutex, +} + +impl StateManager { + /// Creates the state. + pub fn new(config: PotConfig) -> Self { + Self { + state: Mutex::new(InternalState::new(config)), + } + } +} + +/// Interface to the internal protocol components (time keeper, PoT client). +pub(crate) trait PotProtocolState: Send + Sync { + /// Re(initializes) the chain with the given set of proofs. + /// TODO: the proofs are assumed to have been validated, validate + /// if needed. + fn reset(&self, proofs: NonEmptyVec); + + /// Returns the current tip. + fn tip(&self) -> Option; + + /// Called when a proof is produced locally. It tries to extend the + /// chain without verifying the proof. + fn on_proof(&self, proof: &PotProof) -> Result<(), PotProtocolStateError>; + + /// Called when a proof is received via gossip from a peer. The AES + /// verification is already done by the gossip validator. + fn on_proof_from_peer( + &self, + sender: PeerId, + proof: &PotProof, + ) -> Result<(), PotProtocolStateError>; + + /// Called by gossip validator to filter out the received proofs + /// early on. This performs only simple/inexpensive checks, the + /// actual AES verification happens later when the proof is delivered + /// by gossip. This acts like a Bloom filter: false positives with an + /// error probability, no false negatives. + fn is_candidate(&self, sender: PeerId, proof: &PotProof) -> Result<(), PotProtocolStateError>; +} + +impl PotProtocolState for StateManager { + fn reset(&self, proofs: NonEmptyVec) { + self.state.lock().reset(proofs); + } + + fn tip(&self) -> Option { + self.state.lock().tip() + } + + fn on_proof(&self, proof: &PotProof) -> Result<(), PotProtocolStateError> { + self.state.lock().handle_local_proof(proof) + } + + fn on_proof_from_peer( + &self, + sender: PeerId, + proof: &PotProof, + ) -> Result<(), PotProtocolStateError> { + self.state.lock().handle_peer_proof(sender, proof) + } + + fn is_candidate(&self, sender: PeerId, proof: &PotProof) -> Result<(), PotProtocolStateError> { + self.state.lock().is_candidate(sender, proof) + } +} + +/// Interface to consensus. +pub trait PotConsensusState: Send + Sync { + /// Called by consensus when trying to claim the slot. + /// Returns the proofs in the slot range + /// [start_slot, current_slot - global_randomness_reveal_lag_slots]. + fn get_block_proofs( + &self, + block_number: BlockNumber, + current_slot: SlotNumber, + parent_pre_digest: &PotPreDigest, + ) -> Result, PotGetBlockProofsError>; + + /// Called during block import validation. + /// Verifies the sequence of proofs in the block being validated. + fn verify_block_proofs( + &self, + block_number: BlockNumber, + slot_number: SlotNumber, + pre_digest: &PotPreDigest, + parent_slot_number: SlotNumber, + parent_pre_digest: &PotPreDigest, + ) -> Result<(), PotVerifyBlockProofsError>; +} + +impl PotConsensusState for StateManager { + fn get_block_proofs( + &self, + block_number: BlockNumber, + current_slot: SlotNumber, + parent_pre_digest: &PotPreDigest, + ) -> Result, PotGetBlockProofsError> { + self.state + .lock() + .get_block_proofs(block_number, current_slot, parent_pre_digest) + } + + fn verify_block_proofs( + &self, + block_number: BlockNumber, + slot_number: SlotNumber, + pre_digest: &PotPreDigest, + parent_slot_number: SlotNumber, + parent_pre_digest: &PotPreDigest, + ) -> Result<(), PotVerifyBlockProofsError> { + self.state.lock().verify_block_proofs( + block_number, + slot_number, + pre_digest, + parent_slot_number, + parent_pre_digest, + ) + } +} + +pub(crate) fn init_pot_state( + config: PotConfig, +) -> (Arc, Arc) { + let state = Arc::new(StateManager::new(config)); + (state.clone(), state) +} diff --git a/crates/sc-proof-of-time/src/time_keeper.rs b/crates/sc-proof-of-time/src/time_keeper.rs new file mode 100644 index 00000000000..c05c5b68738 --- /dev/null +++ b/crates/sc-proof-of-time/src/time_keeper.rs @@ -0,0 +1,230 @@ +//! Time keeper implementation. + +use crate::gossip::PotGossip; +use crate::state_manager::PotProtocolState; +use crate::utils::get_consensus_tip; +use crate::PotComponents; +use futures::FutureExt; +use parity_scale_codec::Encode; +use sc_network::PeerId; +use sc_network_gossip::{Network as GossipNetwork, Syncing as GossipSyncing}; +use sp_blockchain::{HeaderBackend, Info}; +use sp_consensus::SyncOracle; +use sp_core::H256; +use sp_runtime::traits::{Block as BlockT, Zero}; +use std::sync::Arc; +use std::thread; +use std::time::{Duration, Instant}; +use subspace_core_primitives::{NonEmptyVec, PotProof, PotSeed}; +use subspace_proof_of_time::ProofOfTime; +use tokio::sync::mpsc::{channel, Receiver, Sender}; +use tracing::{error, info, trace, warn}; + +/// Channel size to send the produced proofs. +/// The proof producer thread will block if the receiver is behind and +/// the channel fills up. +const PROOFS_CHANNEL_SIZE: usize = 12; // 2 * reveal lag. + +/// Expected time to produce a proof. +const TARGET_PROOF_TIME_MSEC: u128 = 1000; + +/// The time keeper manages the protocol: periodic proof generation/verification, gossip. +pub struct TimeKeeper, Client, SO> { + proof_of_time: ProofOfTime, + pot_state: Arc, + gossip: PotGossip, + client: Arc, + sync_oracle: Arc, + chain_info_fn: Arc Info + Send + Sync>, +} + +impl TimeKeeper +where + Block: BlockT, + Client: HeaderBackend, + SO: SyncOracle + Send + Sync + Clone + 'static, +{ + /// Creates the time keeper instance. + /// TODO: chain_info() is not a trait method, but part of the + /// client::Client struct itself. Passing it in brings in lot + /// of unnecessary generics/dependencies. chain_info_fn() tries + /// to avoid that by using a Fn instead. Follow up with upstream + /// to include this in the trait. + pub fn new( + components: PotComponents, + client: Arc, + sync_oracle: Arc, + network: Network, + sync: Arc, + chain_info_fn: Arc Info + Send + Sync>, + ) -> Self + where + Network: GossipNetwork + Send + Sync + Clone + 'static, + GossipSync: GossipSyncing + 'static, + { + let PotComponents { + proof_of_time, + protocol_state: pot_state, + .. + } = components; + + Self { + proof_of_time: proof_of_time.clone(), + pot_state: pot_state.clone(), + gossip: PotGossip::new(network, sync, pot_state, proof_of_time), + client, + sync_oracle, + chain_info_fn, + } + } + + /// Runs the time keeper processing loop. + pub async fn run(self) { + self.initialize().await; + + let mut local_proof_receiver = self.spawn_producer_thread(); + let handle_gossip_message: Arc = + Arc::new(|sender, proof| { + self.handle_gossip_message(sender, proof); + }); + loop { + futures::select! { + local_proof = local_proof_receiver.recv().fuse() => { + if let Some(proof) = local_proof { + trace!("time_keeper: got local proof: {proof}"); + self.handle_local_proof(proof); + } + }, + _ = self.gossip.process_incoming_messages( + handle_gossip_message.clone() + ).fuse() => { + error!("time_keeper: gossip engine has terminated."); + return; + } + } + } + } + + /// Initializes the chain state from the consensus tip info. + async fn initialize(&self) { + info!("time_keeper::initialize: waiting for initialization ..."); + let delay = tokio::time::Duration::from_secs(1); + let proofs = loop { + // TODO: Proper error handling or proof + let tip = get_consensus_tip( + self.client.clone(), + self.sync_oracle.clone(), + self.chain_info_fn.clone(), + ) + .await + .expect("Consensus tip info should be available"); + + if tip.block_number.is_zero() { + trace!("time_keeper::initialize: {tip:?}, to wait ...",); + tokio::time::sleep(delay).await; + continue; + } + + info!( + "time_keeper::initialization done: block_hash={:?}, block_number={}, slot_number={}, {:?}", + tip.block_hash, tip.block_number, tip.slot_number, tip.pot_pre_digest + ); + + let proofs = tip.pot_pre_digest.proofs().cloned().unwrap_or_else(|| { + // Producing proofs starting from (genesis_slot + 1). + // TODO: Proper error handling or proof + let proof = self.proof_of_time.create( + PotSeed::from_block_hash(tip.block_hash), + Default::default(), // TODO: key from cmd line or BTC + tip.pot_pre_digest + .next_block_initial_slot() + .expect("Initial slot number should be available for block_number >= 1"), + tip.block_hash, + ); + info!("time_keeper::initialize: creating first proof: {proof}"); + NonEmptyVec::new_with_entry(proof) + }); + break proofs; + }; + self.pot_state.reset(proofs); + } + + /// Starts the thread to produce the proofs. + fn spawn_producer_thread(&self) -> Receiver { + let (sender, receiver) = channel(PROOFS_CHANNEL_SIZE); + let proof_of_time = self.proof_of_time.clone(); + let pot_state = self.pot_state.clone(); + thread::Builder::new() + .name("pot-proof-producer".to_string()) + .spawn(move || { + Self::produce_proofs(proof_of_time, pot_state, sender); + }) + // TODO: Proper error handling or proof + .expect("Failed to spawn PoT proof producer thread"); + receiver + } + + /// Long running loop to produce the proofs. + fn produce_proofs( + proof_of_time: ProofOfTime, + state: Arc, + proof_sender: Sender, + ) { + loop { + // Build the next proof on top of the latest tip. + // TODO: Proper error handling or proof + let last_proof = state.tip().expect("Time keeper chain cannot be empty"); + + // TODO: injected block hash from consensus + let start_ts = Instant::now(); + let next_slot_number = last_proof.slot_number + 1; + let next_seed = last_proof.next_seed(None); + let next_key = last_proof.next_key(); + let next_proof = proof_of_time.create( + next_seed, + next_key, + next_slot_number, + last_proof.injected_block_hash, + ); + let elapsed = start_ts.elapsed(); + trace!("time_keeper::produce proofs: {next_proof}, time=[{elapsed:?}]"); + + // Store the new proof back into the chain and gossip to other time keepers. + if let Err(e) = state.on_proof(&next_proof) { + info!("time_keeper::produce proofs: failed to extend chain: {e:?}"); + continue; + } else if let Err(e) = proof_sender.blocking_send(next_proof.clone()) { + warn!("time_keeper::produce proofs: send failed: {e:?}"); + return; + } + + // TODO: temporary hack for initial testing. + // The pot_iterations is set to take less than 1 sec. Pad the + // remaining time so that we produce approximately 1 proof/sec. + if elapsed.as_millis() < TARGET_PROOF_TIME_MSEC { + let pad = TARGET_PROOF_TIME_MSEC - elapsed.as_millis(); + // Cast should be fine if TARGET_PROOF_TIME_MSEC is small + thread::sleep(Duration::from_millis(pad as u64)) + } + } + } + + /// Gossips the locally generated proof. + fn handle_local_proof(&self, proof: PotProof) { + self.gossip.gossip_message(proof.encode()); + } + + /// Handles the incoming gossip message. + fn handle_gossip_message(&self, sender: PeerId, proof: PotProof) { + let start_ts = Instant::now(); + let ret = self.pot_state.on_proof_from_peer(sender, &proof); + let elapsed = start_ts.elapsed(); + + if let Err(err) = ret { + trace!("time_keeper::on gossip: {err:?}, {sender}"); + } else { + trace!("time_keeper::on gossip: {proof}, time=[{elapsed:?}], {sender}"); + self.gossip.gossip_message(proof.encode()); + } + } +} diff --git a/crates/sc-proof-of-time/src/utils.rs b/crates/sc-proof-of-time/src/utils.rs new file mode 100644 index 00000000000..7d8d4ed285d --- /dev/null +++ b/crates/sc-proof-of-time/src/utils.rs @@ -0,0 +1,62 @@ +//! Common utils. + +use sp_blockchain::{HeaderBackend, Info}; +use sp_consensus::SyncOracle; +use sp_consensus_subspace::digests::{extract_pre_digest, PotPreDigest}; +use sp_core::H256; +use sp_runtime::traits::{Block as BlockT, NumberFor}; +use std::sync::Arc; +use subspace_core_primitives::{BlockHash, SlotNumber}; +use tracing::trace; + +/// Info extracted from the consensus tip. +#[derive(Debug)] +pub(crate) struct ConsensusTipInfo> { + /// Block hash. + pub(crate) block_hash: BlockHash, + + /// Block number. + pub(crate) block_number: NumberFor, + + /// Slot number for the block. + pub(crate) slot_number: SlotNumber, + + /// The PoT from the pre digest + pub(crate) pot_pre_digest: PotPreDigest, +} + +/// Helper to retrieve the PoT state from latest tip. +pub(crate) async fn get_consensus_tip( + client: Arc, + sync_oracle: Arc, + chain_info_fn: Arc Info + Send + Sync>, +) -> Result, String> +where + Block: BlockT, + Client: HeaderBackend, + SO: SyncOracle + Send + Sync + Clone + 'static, +{ + let delay = tokio::time::Duration::from_secs(1); + trace!("get_consensus_tip(): waiting for sync to complete ..."); + while sync_oracle.is_major_syncing() { + tokio::time::sleep(delay).await; + } + + let info = (chain_info_fn)(); + trace!("get_consensus_tip(): sync complete. chain_info = {info:?}"); + let header = client + .header(info.best_hash) + .map_err(|err| format!("get_consensus_tip(): failed to get hdr: {err:?}, {info:?}"))? + .ok_or(format!("get_consensus_tip(): missing hdr: {info:?}"))?; + + let pre_digest = extract_pre_digest(&header).map_err(|err| { + format!("get_consensus_tip_proofs(): failed to get pre digest: {err:?}, {info:?}") + })?; + + Ok(ConsensusTipInfo { + block_hash: info.best_hash.to_fixed_bytes(), + block_number: info.best_number, + slot_number: pre_digest.slot.into(), + pot_pre_digest: pre_digest.proof_of_time.unwrap_or_default(), + }) +} diff --git a/crates/sc-subspace-block-relay/Cargo.toml b/crates/sc-subspace-block-relay/Cargo.toml index dc31ec4047b..38e852b5093 100644 --- a/crates/sc-subspace-block-relay/Cargo.toml +++ b/crates/sc-subspace-block-relay/Cargo.toml @@ -13,17 +13,17 @@ include = [ [dependencies] async-channel = "1.8.0" async-trait = "0.1.68" -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } futures = "0.3.28" lru = "0.10.0" parking_lot = "0.12.1" -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } thiserror = "1.0.38" tracing = "0.1.37" diff --git a/crates/sc-subspace-block-relay/src/consensus.rs b/crates/sc-subspace-block-relay/src/consensus.rs index cbd85daa208..50df8dd509c 100644 --- a/crates/sc-subspace-block-relay/src/consensus.rs +++ b/crates/sc-subspace-block-relay/src/consensus.rs @@ -27,7 +27,7 @@ use sp_runtime::Justifications; use std::num::NonZeroUsize; use std::sync::Arc; use std::time::{Duration, Instant}; -use tracing::{info, trace, warn}; +use tracing::{debug, info, trace, warn}; type BlockHash = ::Hash; type BlockHeader = ::Header; @@ -226,7 +226,7 @@ where who: PeerId, request: BlockRequest, ) -> Result, RequestFailure>, oneshot::Canceled> { - let ret = self.download(who, request).await; + let ret = self.download(who, request.clone()).await; match ret { Ok(result) => { let downloaded = result.downloaded.encode(); @@ -241,9 +241,9 @@ where Ok(Ok(downloaded)) } Err(error) => { - warn!( + debug!( target: LOG_TARGET, - "relay::download_block: peer = {who:?}, err = {error:?}" + "relay::download_block: error: {who:?}/{request:?}/{error:?}" ); match error { RelayError::RequestResponse(error) => match error { @@ -332,10 +332,10 @@ where "relay::consensus server: request processed from: {peer}" ); } - Err(err) => { - warn!( + Err(error) => { + debug!( target: LOG_TARGET, - "relay::consensus server: request processing error: {peer}: {err:?}" + "relay::consensus server: error: {peer}/{error:?}" ); } } diff --git a/crates/sc-subspace-chain-specs/Cargo.toml b/crates/sc-subspace-chain-specs/Cargo.toml index 167cdbb454f..f4eb6356a53 100644 --- a/crates/sc-subspace-chain-specs/Cargo.toml +++ b/crates/sc-subspace-chain-specs/Cargo.toml @@ -12,9 +12,9 @@ include = [ ] [dependencies] -sc-chain-spec = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-chain-spec = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } serde = "1.0.159" -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } diff --git a/crates/sc-subspace-chain-specs/src/lib.rs b/crates/sc-subspace-chain-specs/src/lib.rs index 0b31b1fd5ff..8eb6948dbc1 100644 --- a/crates/sc-subspace-chain-specs/src/lib.rs +++ b/crates/sc-subspace-chain-specs/src/lib.rs @@ -20,40 +20,10 @@ mod utils; pub use utils::SerializableChainSpec; -use sc_chain_spec::{ChainSpecExtension, NoExtension, RuntimeGenesis}; -use sc_service::ChainSpecExtension; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; - -/// The extensions for the [`ConsensusChainSpec`]. -#[derive(Serialize, Deserialize, ChainSpecExtension)] -#[serde(deny_unknown_fields, rename_all = "camelCase")] -#[serde(bound = "")] -pub struct ChainSpecExtensions -where - ExecutionGenesisConfig: RuntimeGenesis + 'static, - Extensions: ChainSpecExtension + DeserializeOwned + Clone + Send + Sync + 'static, -{ - /// Chain spec of execution chain. - pub execution_chain_spec: ExecutionChainSpec, -} - -impl Clone - for ChainSpecExtensions -where - ExecutionGenesisConfig: RuntimeGenesis + 'static, - Extensions: ChainSpecExtension + DeserializeOwned + Clone + Send + Sync + 'static, -{ - fn clone(&self) -> Self { - Self { - execution_chain_spec: self.execution_chain_spec.clone(), - } - } -} +use sc_chain_spec::NoExtension; /// Specialized `ChainSpec` for the consensus runtime. -pub type ConsensusChainSpec = - SerializableChainSpec>; +pub type ConsensusChainSpec = SerializableChainSpec; /// Specialized `ChainSpec` for the execution runtime. pub type ExecutionChainSpec = diff --git a/crates/sp-consensus-subspace/Cargo.toml b/crates/sp-consensus-subspace/Cargo.toml index 74021443ee4..9cc0fa7bf5d 100644 --- a/crates/sp-consensus-subspace/Cargo.toml +++ b/crates/sp-consensus-subspace/Cargo.toml @@ -14,21 +14,21 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] async-trait = { version = "0.1.68", optional = true } -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false } log = { version = "0.4.19", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } schnorrkel = { version = "0.9.1", default-features = false, features = ["u64_backend"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-application-crypto = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-externalities = { version = "0.19.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime-interface = { version = "17.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-application-crypto = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-externalities = { version = "0.19.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime-interface = { version = "17.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } subspace-archiving = { version = "0.1.0", path = "../subspace-archiving", default-features = false } subspace-solving = { version = "0.1.0", path = "../subspace-solving", default-features = false } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } diff --git a/crates/sp-consensus-subspace/src/digests.rs b/crates/sp-consensus-subspace/src/digests.rs index 5ff5c77d89c..c48714196d8 100644 --- a/crates/sp-consensus-subspace/src/digests.rs +++ b/crates/sp-consensus-subspace/src/digests.rs @@ -27,7 +27,8 @@ use sp_runtime::DigestItem; use sp_std::collections::btree_map::{BTreeMap, Entry}; use sp_std::fmt; use subspace_core_primitives::{ - Randomness, SegmentCommitment, SegmentIndex, Solution, SolutionRange, + NonEmptyVec, PotProof, Randomness, SegmentCommitment, SegmentIndex, SlotNumber, Solution, + SolutionRange, }; use subspace_verification::derive_randomness; @@ -39,6 +40,83 @@ pub struct PreDigest { pub slot: Slot, /// Solution (includes PoR) pub solution: Solution, + /// Proof of time included in the block + /// TODO: It is Option<> for now for testing, to be removed + /// when PoT feature is permanently enabled. + pub proof_of_time: Option, +} + +/// The proof of time included in the pre digest. +/// TODO: versioning needs to match PotProof version, +/// versioning added on the proof side +#[derive(Clone, Encode, Decode)] +pub enum PotPreDigest { + /// The block was produced in the bootstrapping phase, where + /// the genesis slot has not yet been determined and the proof + /// production has not started. + Bootstrapping, + + /// Genesis slot determined by the bootstrap node. + FirstBlock(SlotNumber), + + /// V0 proof. + V0(NonEmptyVec), +} + +impl PotPreDigest { + /// Constructs the PoT for the pre digest. + pub fn new(proofs: NonEmptyVec) -> Self { + Self::V0(proofs) + } + + /// Returns a reference to the proofs. + pub fn proofs(&self) -> Option<&NonEmptyVec> { + match self { + Self::Bootstrapping | Self::FirstBlock(_) => None, + Self::V0(proofs) => Some(proofs), + } + } + + /// Returns the starting slot number for the proofs in the next + /// block. + pub fn next_block_initial_slot(&self) -> Option { + match self { + Self::Bootstrapping => None, + Self::FirstBlock(slot_number) => Some(slot_number + 1), + Self::V0(proofs) => Some(proofs.last().slot_number + 1), + } + } +} + +impl Default for PotPreDigest { + fn default() -> Self { + Self::Bootstrapping + } +} + +impl fmt::Debug for PotPreDigest { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Bootstrapping => { + write!(f, "PotPreDigest::Bootstrapping") + } + Self::FirstBlock(slot_number) => { + write!( + f, + "PotPreDigest::FirstBlock => genesis_slot = {slot_number}" + ) + } + Self::V0(proofs) => { + write!( + f, + "PotPreDigest::V0 => num_proofs: {}, proofs: [{} - {}]", + proofs.len(), + proofs.first(), + proofs.last(), + ) + } + } + } } /// A digest item which is usable with Subspace consensus. @@ -570,6 +648,7 @@ where FarmerPublicKey::unchecked_from([0u8; 32]), FarmerPublicKey::unchecked_from([0u8; 32]), ), + proof_of_time: Default::default(), }); } diff --git a/crates/sp-consensus-subspace/src/lib.rs b/crates/sp-consensus-subspace/src/lib.rs index 7f2e2e8cfc6..6e8fd87a6a3 100644 --- a/crates/sp-consensus-subspace/src/lib.rs +++ b/crates/sp-consensus-subspace/src/lib.rs @@ -317,6 +317,12 @@ pub enum ChainConstants { era_duration: BlockNumber, /// Slot probability. slot_probability: (u64, u64), + /// Number of latest archived segments that are considered "recent history". + recent_segments: HistorySize, + /// Fraction of pieces from the "recent history" (`recent_segments`) in each sector. + recent_history_fraction: (HistorySize, HistorySize), + /// Minimum lifetime of a plotted sector, measured in archived segment. + min_sector_lifetime: HistorySize, }, } @@ -352,6 +358,32 @@ impl ChainConstants { } = self; *slot_probability } + + /// Number of latest archived segments that are considered "recent history". + pub fn recent_segments(&self) -> HistorySize { + let Self::V0 { + recent_segments, .. + } = self; + *recent_segments + } + + /// Fraction of pieces from the "recent history" (`recent_segments`) in each sector. + pub fn recent_history_fraction(&self) -> (HistorySize, HistorySize) { + let Self::V0 { + recent_history_fraction, + .. + } = self; + *recent_history_fraction + } + + /// Minimum lifetime of a plotted sector, measured in archived segment. + pub fn min_sector_lifetime(&self) -> HistorySize { + let Self::V0 { + min_sector_lifetime, + .. + } = self; + *min_sector_lifetime + } } /// Wrapped solution for the purposes of runtime interface. diff --git a/crates/sp-consensus-subspace/src/tests.rs b/crates/sp-consensus-subspace/src/tests.rs index 93f320c611e..0f92b22d760 100644 --- a/crates/sp-consensus-subspace/src/tests.rs +++ b/crates/sp-consensus-subspace/src/tests.rs @@ -42,6 +42,7 @@ fn test_is_equivocation_proof_valid() { logs: vec![DigestItem::subspace_pre_digest(&PreDigest { slot, solution: solution.clone(), + proof_of_time: Default::default(), })], }, }; @@ -66,6 +67,7 @@ fn test_is_equivocation_proof_valid() { logs: vec![DigestItem::subspace_pre_digest(&PreDigest { slot, solution, + proof_of_time: Default::default(), })], }, }; diff --git a/crates/sp-domains/Cargo.toml b/crates/sp-domains/Cargo.toml index a6461ef9e8f..c9337daefc8 100644 --- a/crates/sp-domains/Cargo.toml +++ b/crates/sp-domains/Cargo.toml @@ -13,24 +13,30 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] blake2 = { version = "0.10.6", default-features = false } -parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } +parity-scale-codec = { version = "3.6.3", default-features = false, features = ["derive"] } rs_merkle = { version = "1.4.1", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } serde = { version = "1.0.159", default-features = false, features = ["alloc", "derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-application-crypto = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-state-machine = { version = "0.28.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-application-crypto = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } +sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-externalities = { version = "0.19.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime-interface = { version = "17.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-state-machine = { version = "0.28.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-weights = { version = "20.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } thiserror = { version = "1.0.38", optional = true } +[dev-dependencies] +num-traits = "0.2.15" + [features] default = ["std"] std = [ @@ -44,11 +50,14 @@ std = [ "sp-application-crypto/std", "sp-consensus-slots/std", "sp-core/std", + "sp-externalities/std", "sp-keystore", "sp-runtime/std", + "sp-runtime-interface/std", "sp-state-machine/std", "sp-std/std", "sp-trie/std", + "sp-weights/std", "subspace-core-primitives/std", "subspace-runtime-primitives/std", "thiserror", diff --git a/crates/sp-domains/src/bundle_election.rs b/crates/sp-domains/src/bundle_election.rs deleted file mode 100644 index 5d9ae8235b3..00000000000 --- a/crates/sp-domains/src/bundle_election.rs +++ /dev/null @@ -1,309 +0,0 @@ -use crate::merkle_tree::{MerkleProof, Witness}; -use crate::{DomainId, ExecutorPublicKey, ProofOfElection, StakeWeight}; -use parity_scale_codec::{Decode, Encode}; -use scale_info::TypeInfo; -use sp_core::crypto::{VrfPublic, Wraps}; -use sp_core::sr25519::vrf::{VrfInput, VrfOutput, VrfSignature}; -use sp_core::H256; -use sp_runtime::traits::{BlakeTwo256, Hash}; -use sp_std::vec::Vec; -use sp_trie::{read_trie_value, LayoutV1, StorageProof}; -use subspace_core_primitives::crypto::blake2b_256_hash_list; -use subspace_core_primitives::Blake2b256Hash; -use well_known_keys::{AUTHORITIES_ROOT, SLOT_PROBABILITY, TOTAL_STAKE_WEIGHT}; - -const VRF_TRANSCRIPT_LABEL: &[u8] = b"executor"; - -const LOCAL_RANDOMNESS_CONTEXT: &[u8] = b"bundle_election_local_randomness_context"; - -type LocalRandomness = [u8; core::mem::size_of::()]; - -fn derive_local_randomness( - vrf_output: &VrfOutput, - public_key: &ExecutorPublicKey, - global_challenge: &Blake2b256Hash, -) -> Result { - vrf_output.make_bytes( - LOCAL_RANDOMNESS_CONTEXT, - &make_local_randomness_input(global_challenge), - public_key.as_ref(), - ) -} - -/// Returns the domain-specific solution for the challenge of producing a bundle. -pub fn derive_bundle_election_solution( - domain_id: DomainId, - vrf_output: &VrfOutput, - public_key: &ExecutorPublicKey, - global_challenge: &Blake2b256Hash, -) -> Result { - let local_randomness = derive_local_randomness(vrf_output, public_key, global_challenge)?; - let local_domain_randomness = - blake2b_256_hash_list(&[&domain_id.to_le_bytes(), &local_randomness]); - - let election_solution = u128::from_le_bytes( - local_domain_randomness - .split_at(core::mem::size_of::()) - .0 - .try_into() - .expect("Local domain randomness must fit into u128; qed"), - ); - - Ok(election_solution) -} - -/// Returns the election threshold based on the stake weight proportion and slot probability. -pub fn calculate_bundle_election_threshold( - stake_weight: StakeWeight, - total_stake_weight: StakeWeight, - slot_probability: (u64, u64), -) -> u128 { - // The calculation is written for not causing the overflow, which might be harder to - // understand, the formula in a readable form is as followes: - // - // slot_probability.0 stake_weight - // threshold = ------------------ * --------------------- * u128::MAX - // slot_probability.1 total_stake_weight - // - // TODO: better to have more audits on this calculation. - u128::MAX / u128::from(slot_probability.1) * u128::from(slot_probability.0) / total_stake_weight - * stake_weight -} - -pub fn is_election_solution_within_threshold(election_solution: u128, threshold: u128) -> bool { - election_solution <= threshold -} - -/// Make a VRF inout. -pub fn make_local_randomness_input(global_challenge: &Blake2b256Hash) -> VrfInput { - VrfInput::new( - VRF_TRANSCRIPT_LABEL, - &[(b"global challenge", global_challenge)], - ) -} - -pub mod well_known_keys { - use sp_std::vec; - use sp_std::vec::Vec; - - /// Storage key of `pallet_executor_registry::AuthoritiesRoot`. - /// - /// AuthoritiesRoot::::hashed_key(). - pub(crate) const AUTHORITIES_ROOT: [u8; 32] = [ - 185, 61, 20, 0, 90, 16, 106, 134, 14, 150, 35, 100, 152, 229, 203, 187, 229, 73, 72, 152, - 132, 52, 185, 74, 34, 205, 232, 65, 110, 2, 255, 36, - ]; - - /// Storage key of `pallet_executor_registry::TotalStakeWeight`. - /// - /// TotalStakeWeight::::hashed_key(). - pub(crate) const TOTAL_STAKE_WEIGHT: [u8; 32] = [ - 185, 61, 20, 0, 90, 16, 106, 134, 14, 150, 35, 100, 152, 229, 203, 187, 173, 245, 4, 89, - 128, 92, 85, 189, 74, 160, 138, 209, 188, 18, 62, 94, - ]; - - /// Storage key of `pallet_executor_registry::SlotProbability`. - /// - /// SlotProbability::::hashed_key(). - pub(crate) const SLOT_PROBABILITY: [u8; 32] = [ - 185, 61, 20, 0, 90, 16, 106, 134, 14, 150, 35, 100, 152, 229, 203, 187, 60, 16, 174, 72, - 214, 175, 220, 254, 34, 167, 168, 222, 147, 18, 4, 168, - ]; - - /// Returns the storage keys for verifying the system domain bundle election. - pub fn system_bundle_election_storage_keys() -> Vec<[u8; 32]> { - vec![AUTHORITIES_ROOT, TOTAL_STAKE_WEIGHT, SLOT_PROBABILITY] - } -} - -/// Parameters for solving the bundle election. -#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] -pub struct BundleElectionSolverParams { - pub authorities: Vec<(ExecutorPublicKey, StakeWeight)>, - pub total_stake_weight: StakeWeight, - pub slot_probability: (u64, u64), -} - -impl BundleElectionSolverParams { - pub fn empty() -> Self { - Self { - authorities: Vec::new(), - total_stake_weight: 0, - slot_probability: (0, 0), - } - } -} - -/// Parameters for verifying the system bundle election. -#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] -struct SystemBundleElectionVerifierParams { - pub authorities_root: Blake2b256Hash, - pub total_stake_weight: StakeWeight, - pub slot_probability: (u64, u64), -} - -#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] -pub enum VrfProofError { - /// Invalid vrf proof. - BadProof, -} - -/// Verify the vrf proof generated in the bundle election. -pub(crate) fn verify_vrf_proof( - public_key: &ExecutorPublicKey, - vrf_signature: &VrfSignature, - global_challenge: &Blake2b256Hash, -) -> Result<(), VrfProofError> { - if !public_key.as_inner_ref().vrf_verify( - &make_local_randomness_input(global_challenge).into(), - vrf_signature, - ) { - return Err(VrfProofError::BadProof); - } - - Ok(()) -} - -#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] -pub enum ReadBundleElectionParamsError { - /// Trie error. - TrieError, - /// The value does not exist in the trie. - MissingValue, - /// Failed to decode the value read from the trie. - DecodeError, -} - -/// Returns the system bundle election verification parameters read from the given storage proof. -fn read_system_bundle_election_verifier_params( - storage_proof: StorageProof, - state_root: &H256, -) -> Result { - let db = storage_proof.into_memory_db::(); - - let read_value = |storage_key| { - read_trie_value::, _>(&db, state_root, storage_key, None, None) - .map_err(|_| ReadBundleElectionParamsError::TrieError) - }; - - let authorities_root_value = - read_value(&AUTHORITIES_ROOT)?.ok_or(ReadBundleElectionParamsError::MissingValue)?; - let authorities_root: Blake2b256Hash = - Decode::decode(&mut authorities_root_value.as_slice()) - .map_err(|_| ReadBundleElectionParamsError::DecodeError)?; - - let total_stake_weight_value = - read_value(&TOTAL_STAKE_WEIGHT)?.ok_or(ReadBundleElectionParamsError::MissingValue)?; - let total_stake_weight: StakeWeight = Decode::decode(&mut total_stake_weight_value.as_slice()) - .map_err(|_| ReadBundleElectionParamsError::DecodeError)?; - - let slot_probability_value = - read_value(&SLOT_PROBABILITY)?.ok_or(ReadBundleElectionParamsError::MissingValue)?; - let slot_probability: (u64, u64) = Decode::decode(&mut slot_probability_value.as_slice()) - .map_err(|_| ReadBundleElectionParamsError::DecodeError)?; - - Ok(SystemBundleElectionVerifierParams { - authorities_root, - total_stake_weight, - slot_probability, - }) -} - -#[derive(Debug)] -pub enum BundleSolutionError { - /// Can not retrieve the state needed from the storage proof. - BadStorageProof(ReadBundleElectionParamsError), - /// Can not construct merkle proof. - CannotConstructMerkleProof(rs_merkle::Error), - /// Invalid merkle proof. - BadMerkleProof, - /// Failed to derive the bundle election solution. - FailedToDeriveBundleElectionSolution(parity_scale_codec::Error), - /// Election solution does not satisfy the threshold. - InvalidElectionSolution, -} - -pub fn verify_system_bundle_solution( - proof_of_election: &ProofOfElection, - verified_state_root: H256, - authority_stake_weight: StakeWeight, - authority_witness: &Witness, -) -> Result<(), BundleSolutionError> { - let ProofOfElection { - domain_id, - vrf_output, - executor_public_key, - global_challenge, - storage_proof, - .. - } = proof_of_election; - - let SystemBundleElectionVerifierParams { - authorities_root, - total_stake_weight, - slot_probability, - } = read_system_bundle_election_verifier_params(storage_proof.clone(), &verified_state_root) - .map_err(BundleSolutionError::BadStorageProof)?; - - let stake_weight = authority_stake_weight; - - let Witness { - leaf_index, - number_of_leaves, - proof, - } = authority_witness; - - let merkle_proof = - MerkleProof::from_bytes(proof).map_err(BundleSolutionError::CannotConstructMerkleProof)?; - - let leaf_to_prove = - BlakeTwo256::hash_of(&(executor_public_key, stake_weight).encode()).to_fixed_bytes(); - - if !merkle_proof.verify( - authorities_root, - &[*leaf_index as usize], - &[leaf_to_prove], - *number_of_leaves as usize, - ) { - return Err(BundleSolutionError::BadMerkleProof); - } - - verify_bundle_solution_threshold( - *domain_id, - vrf_output, - stake_weight, - total_stake_weight, - slot_probability, - executor_public_key, - global_challenge, - )?; - - Ok(()) -} - -pub fn verify_bundle_solution_threshold( - domain_id: DomainId, - vrf_output: &VrfOutput, - stake_weight: StakeWeight, - total_stake_weight: StakeWeight, - slot_probability: (u64, u64), - executor_public_key: &ExecutorPublicKey, - global_challenge: &Blake2b256Hash, -) -> Result<(), BundleSolutionError> { - let election_solution = derive_bundle_election_solution( - domain_id, - vrf_output, - executor_public_key, - global_challenge, - ) - .map_err(BundleSolutionError::FailedToDeriveBundleElectionSolution)?; - - let threshold = - calculate_bundle_election_threshold(stake_weight, total_stake_weight, slot_probability); - - if !is_election_solution_within_threshold(election_solution, threshold) { - return Err(BundleSolutionError::InvalidElectionSolution); - } - - Ok(()) -} diff --git a/crates/sp-domains/src/bundle_producer_election.rs b/crates/sp-domains/src/bundle_producer_election.rs new file mode 100644 index 00000000000..e732c2100aa --- /dev/null +++ b/crates/sp-domains/src/bundle_producer_election.rs @@ -0,0 +1,83 @@ +use crate::{DomainId, OperatorId, OperatorPublicKey, StakeWeight}; +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_core::crypto::{VrfPublic, Wraps}; +use sp_core::sr25519::vrf::{VrfOutput, VrfSignature, VrfTranscript}; +use sp_std::vec::Vec; +use subspace_core_primitives::Blake2b256Hash; + +const VRF_TRANSCRIPT_LABEL: &[u8] = b"bundle_producer_election"; + +/// Generates a domain-specific vrf transcript from given global_challenge. +pub fn make_transcript(domain_id: DomainId, global_challenge: &Blake2b256Hash) -> VrfTranscript { + VrfTranscript::new( + VRF_TRANSCRIPT_LABEL, + &[ + (b"domain", &domain_id.to_le_bytes()), + (b"global_challenge", global_challenge.as_ref()), + ], + ) +} + +/// Returns the election threshold based on the operator stake proportion and slot probability. +pub fn calculate_threshold( + operator_stake: StakeWeight, + total_domain_stake: StakeWeight, + bundle_slot_probability: (u64, u64), +) -> u128 { + // The calculation is written for not causing the overflow, which might be harder to + // understand, the formula in a readable form is as followes: + // + // bundle_slot_probability.0 operator_stake + // threshold = ------------------------- * --------------------- * u128::MAX + // bundle_slot_probability.1 total_domain_stake + // + // TODO: better to have more audits on this calculation. + u128::MAX / u128::from(bundle_slot_probability.1) * u128::from(bundle_slot_probability.0) + / total_domain_stake + * operator_stake +} + +pub fn is_below_threshold(vrf_output: &VrfOutput, threshold: u128) -> bool { + let vrf_output = u128::from_le_bytes( + vrf_output + .0 + .to_bytes() + .split_at(core::mem::size_of::()) + .0 + .try_into() + .expect("Slice splitted from VrfOutput must fit into u128; qed"), + ); + + vrf_output < threshold +} + +#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] +pub struct BundleProducerElectionParams { + pub current_operators: Vec, + pub total_domain_stake: Balance, + pub bundle_slot_probability: (u64, u64), +} + +#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] +pub enum VrfProofError { + /// Invalid vrf proof. + BadProof, +} + +/// Verify the vrf proof generated in the bundle election. +pub(crate) fn verify_vrf_signature( + domain_id: DomainId, + public_key: &OperatorPublicKey, + vrf_signature: &VrfSignature, + global_challenge: &Blake2b256Hash, +) -> Result<(), VrfProofError> { + if !public_key.as_inner_ref().vrf_verify( + &make_transcript(domain_id, global_challenge).into(), + vrf_signature, + ) { + return Err(VrfProofError::BadProof); + } + + Ok(()) +} diff --git a/crates/sp-domains/src/fraud_proof.rs b/crates/sp-domains/src/fraud_proof.rs index fe3b95f4ba4..94888f273d0 100644 --- a/crates/sp-domains/src/fraud_proof.rs +++ b/crates/sp-domains/src/fraud_proof.rs @@ -1,5 +1,3 @@ -#[cfg(any(feature = "std", feature = "runtime-benchmarks"))] -use crate::BundleHeader; use crate::{DomainId, SealedBundleHeader}; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; @@ -9,7 +7,7 @@ use sp_runtime::traits::{BlakeTwo256, Hash as HashT, Header as HeaderT}; use sp_std::vec::Vec; use sp_trie::StorageProof; use subspace_core_primitives::BlockNumber; -use subspace_runtime_primitives::AccountId; +use subspace_runtime_primitives::{AccountId, Balance}; /// A phase of a block's execution, carrying necessary information needed for verifying the /// invalid state transition proof. @@ -69,16 +67,16 @@ impl ExecutionPhase { } } -/// Error type of fraud proof verification on primary node. +/// Error type of fraud proof verification on consensus node. #[derive(Debug)] #[cfg_attr(feature = "thiserror", derive(thiserror::Error))] pub enum VerificationError { /// `pre_state_root` in the invalid state transition proof is invalid. #[cfg_attr(feature = "thiserror", error("invalid `pre_state_root`"))] InvalidPreStateRoot, - /// Hash of the primary block being challenged not found. - #[cfg_attr(feature = "thiserror", error("primary hash not found"))] - PrimaryHashNotFound, + /// Hash of the consensus block being challenged not found. + #[cfg_attr(feature = "thiserror", error("consensus block hash not found"))] + ConsensusBlockHashNotFound, /// `post_state_root` not found in the state. #[cfg_attr(feature = "thiserror", error("`post_state_root` not found"))] PostStateRootNotFound, @@ -184,6 +182,8 @@ pub enum VerificationError { } /// Fraud proof. +// TODO: Revisit when fraud proof v2 is implemented. +#[allow(clippy::large_enum_variant)] #[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] pub enum FraudProof { InvalidStateTransition(InvalidStateTransitionProof), @@ -222,11 +222,11 @@ pub struct InvalidStateTransitionProof { pub bad_receipt_hash: H256, /// Parent number. pub parent_number: BlockNumber, - /// Hash of the primary block corresponding to `parent_number`. + /// Hash of the consensus block corresponding to `parent_number`. /// /// Runtime code for the execution of the domain block that is being challenged - /// is retrieved on top of the primary parent block from the primary chain. - pub primary_parent_hash: H256, + /// is retrieved on top of the consensus parent block from the consensus chain. + pub consensus_parent_hash: H256, /// State root before the fraudulent transaction. pub pre_state_root: H256, /// State root after the fraudulent transaction. @@ -245,7 +245,7 @@ pub fn dummy_invalid_state_transition_proof( domain_id, bad_receipt_hash: H256::default(), parent_number, - primary_parent_hash: H256::default(), + consensus_parent_hash: H256::default(), pre_state_root: H256::default(), post_state_root: H256::default(), proof: StorageProof::empty(), @@ -265,11 +265,13 @@ pub struct BundleEquivocationProof { pub offender: AccountId, /// The slot at which the equivocation happened. pub slot: Slot, - // TODO: Make H256 a generic when bundle equivocation is implemented properly. + // TODO: The generic type should be `` + // TODO: `SealedBundleHeader` contains `ExecutionReceipt` which make the size of the proof + // large, revisit when proceeding to fraud proof v2. /// The first header involved in the equivocation. - pub first_header: SealedBundleHeader, + pub first_header: SealedBundleHeader, /// The second header involved in the equivocation. - pub second_header: SealedBundleHeader, + pub second_header: SealedBundleHeader, } impl + Encode, Hash: Clone + Default + Encode> @@ -279,36 +281,6 @@ impl + Encode, Hash: Clone + Default + Encode> pub fn hash(&self) -> H256 { BlakeTwo256::hash_of(self) } - - // TODO: remove this later. - /// Constructs a dummy bundle equivocation proof. - #[cfg(any(feature = "std", feature = "runtime-benchmarks"))] - pub fn dummy_at(slot_number: u64) -> Self { - use sp_application_crypto::UncheckedFrom; - - let dummy_header = SealedBundleHeader { - header: BundleHeader { - primary_number: Number::from(0u32), - primary_hash: Hash::default(), - slot_number, - extrinsics_root: H256::default(), - bundle_solution: crate::BundleSolution::dummy( - DomainId::SYSTEM, - crate::ExecutorPublicKey::unchecked_from([0u8; 32]), - ), - }, - signature: crate::ExecutorSignature::unchecked_from([0u8; 64]), - }; - - Self { - domain_id: DomainId::SYSTEM, - offender: AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) - .expect("Failed to create zero account"), - slot: slot_number.into(), - first_header: dummy_header.clone(), - second_header: dummy_header, - } - } } /// Represents an invalid transaction proof. diff --git a/crates/sp-domains/src/lib.rs b/crates/sp-domains/src/lib.rs index dbc6bbe1e3d..7c7290d7432 100644 --- a/crates/sp-domains/src/lib.rs +++ b/crates/sp-domains/src/lib.rs @@ -13,36 +13,40 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Primitives for executor pallet. +//! Primitives for domains pallet. #![cfg_attr(not(feature = "std"), no_std)] -pub mod bundle_election; +pub mod bundle_producer_election; pub mod fraud_proof; pub mod merkle_tree; +#[cfg(test)] +mod tests; pub mod transaction; -use bundle_election::VrfProofError; -use merkle_tree::Witness; -#[cfg(any(feature = "std", feature = "runtime-benchmarks"))] -use parity_scale_codec::MaxEncodedLen; -use parity_scale_codec::{Decode, Encode}; +use bundle_producer_election::{BundleProducerElectionParams, VrfProofError}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; +use sp_api::RuntimeVersion; use sp_core::crypto::KeyTypeId; use sp_core::sr25519::vrf::{VrfOutput, VrfProof, VrfSignature}; use sp_core::H256; -use sp_runtime::traits::{BlakeTwo256, Block as BlockT, Hash as HashT, NumberFor, Zero}; -use sp_runtime::{OpaqueExtrinsic, RuntimeAppPublic}; -use sp_std::borrow::Cow; +use sp_runtime::generic::OpaqueDigestItemId; +use sp_runtime::traits::{ + BlakeTwo256, Block as BlockT, CheckedAdd, Hash as HashT, NumberFor, Zero, +}; +use sp_runtime::{DigestItem, OpaqueExtrinsic, Percent}; +use sp_runtime_interface::pass_by::PassBy; +use sp_runtime_interface::{pass_by, runtime_interface}; use sp_std::vec::Vec; -use sp_trie::StorageProof; +use sp_weights::Weight; use subspace_core_primitives::crypto::blake2b_256_hash; -use subspace_core_primitives::{Blake2b256Hash, BlockNumber, Randomness}; -use subspace_runtime_primitives::Moment; +use subspace_core_primitives::{bidirectional_distance, Blake2b256Hash, Randomness, U256}; +use subspace_runtime_primitives::{Balance, Moment}; -/// Key type for Executor. -const KEY_TYPE: KeyTypeId = KeyTypeId(*b"exec"); +/// Key type for Operator. +const KEY_TYPE: KeyTypeId = KeyTypeId(*b"oper"); mod app { use super::KEY_TYPE; @@ -51,22 +55,22 @@ mod app { app_crypto!(sr25519, KEY_TYPE); } -/// An executor authority signature. -pub type ExecutorSignature = app::Signature; +/// An operator authority signature. +pub type OperatorSignature = app::Signature; -/// An executor authority keypair. Necessarily equivalent to the schnorrkel public key used in +/// An operator authority keypair. Necessarily equivalent to the schnorrkel public key used in /// the main executor module. If that ever changes, then this must, too. #[cfg(feature = "std")] -pub type ExecutorPair = app::Pair; +pub type OperatorPair = app::Pair; -/// An executor authority identifier. -pub type ExecutorPublicKey = app::Public; +/// An operator authority identifier. +pub type OperatorPublicKey = app::Public; -/// A type that implements `BoundToRuntimeAppPublic`, used for executor signing key. -pub struct ExecutorKey; +/// A type that implements `BoundToRuntimeAppPublic`, used for operator signing key. +pub struct OperatorKey; -impl sp_runtime::BoundToRuntimeAppPublic for ExecutorKey { - type Public = ExecutorPublicKey; +impl sp_runtime::BoundToRuntimeAppPublic for OperatorKey { + type Public = OperatorPublicKey; } /// Stake weight in the domain bundle election. @@ -74,6 +78,12 @@ impl sp_runtime::BoundToRuntimeAppPublic for ExecutorKey { /// Derived from the Balance and can't be smaller than u128. pub type StakeWeight = u128; +/// The hash of a execution receipt. +pub type ReceiptHash = H256; + +/// The Merkle root of all extrinsics included in a bundle. +pub type ExtrinsicsRoot = H256; + /// Unique identifier of a domain. #[derive( Clone, @@ -90,9 +100,14 @@ pub type StakeWeight = u128; TypeInfo, Serialize, Deserialize, + MaxEncodedLen, )] pub struct DomainId(u32); +impl PassBy for DomainId { + type PassBy = pass_by::Codec; +} + impl From for DomainId { #[inline] fn from(x: u32) -> Self { @@ -107,107 +122,62 @@ impl From for u32 { } } -impl core::ops::Add for DomainId { +impl core::ops::Add for DomainId { type Output = Self; - fn add(self, other: u32) -> Self { - Self(self.0 + other) + fn add(self, other: DomainId) -> Self { + Self(self.0 + other.0) } } -impl core::ops::Sub for DomainId { +impl core::ops::Sub for DomainId { type Output = Self; - fn sub(self, other: u32) -> Self { - Self(self.0 - other) + fn sub(self, other: DomainId) -> Self { + Self(self.0 - other.0) } } -const OPEN_DOMAIN_ID_START: u32 = 100; +impl CheckedAdd for DomainId { + fn checked_add(&self, rhs: &Self) -> Option { + self.0.checked_add(rhs.0).map(Self) + } +} impl DomainId { - pub const SYSTEM: Self = Self::new(0); - - pub const CORE_DOMAIN_ID_START: Self = Self::new(1); - - pub const CORE_PAYMENTS: Self = Self::new(1); - - pub const CORE_EVM: Self = Self::new(3); - /// Creates a [`DomainId`]. pub const fn new(id: u32) -> Self { Self(id) } - /// Returns `true` if a domain is a system domain. - pub fn is_system(&self) -> bool { - self.0 == Self::SYSTEM.0 - } - - /// Returns `true` if a domain is a core domain. - pub fn is_core(&self) -> bool { - self.0 >= Self::CORE_DOMAIN_ID_START.0 && self.0 < OPEN_DOMAIN_ID_START - } - - /// Returns `true` if a domain is an open domain. - pub fn is_open(&self) -> bool { - self.0 >= OPEN_DOMAIN_ID_START - } - /// Converts the inner integer to little-endian bytes. pub fn to_le_bytes(&self) -> [u8; 4] { self.0.to_le_bytes() } - - /// Returns the section name when a core domain wasm blob is embedded into the system domain - /// runtime via the `link_section` attribute. - #[cfg(feature = "std")] - pub fn link_section_name(&self) -> String { - format!("runtime_blob_{}", self.0) - } -} - -/// Domain configuration. -#[derive(Debug, Encode, Decode, TypeInfo, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct DomainConfig { - /// Hash of the domain wasm runtime blob. - pub wasm_runtime_hash: Hash, - - // May be supported later. - //pub upgrade_keys: Vec, - /// Slot probability - pub bundle_slot_probability: (u64, u64), - - /// Maximum domain bundle size in bytes. - pub max_bundle_size: u32, - - /// Maximum domain bundle weight. - pub max_bundle_weight: Weight, - - /// Minimum executor stake value to be an operator on this domain. - pub min_operator_stake: Balance, } -/// Unsealed header of bundle. -/// -/// Domain operator needs to sign the hash of [`BundleHeader`] and uses the signature to -/// assemble the final [`SealedBundleHeader`]. #[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] -pub struct BundleHeader { - /// The block number of primary block at which the bundle was created. - pub primary_number: Number, - /// The hash of primary block at which the bundle was created. - pub primary_hash: Hash, - /// The slot number. - pub slot_number: u64, - /// The merkle root of the extrinsics. - pub extrinsics_root: H256, - /// Solution of the bundle election. - pub bundle_solution: BundleSolution, +pub struct BundleHeader { + /// Proof of bundle producer election. + pub proof_of_election: ProofOfElection, + /// Execution receipt that should extend the receipt chain or add confirmations + /// to the head receipt. + pub receipt: ExecutionReceipt, + /// The size of the bundle body in bytes. + /// + /// Used to calculate the storage cost. + pub bundle_size: u32, + /// The total (estimated) weight of all extrinsics in the bundle. + /// + /// Used to prevent overloading the bundle with compute. + pub estimated_bundle_weight: Weight, + /// The Merkle root of all new extrinsics included in this bundle. + pub bundle_extrinsics_root: ExtrinsicsRoot, } -impl BundleHeader { +impl + BundleHeader +{ /// Returns the hash of this header. pub fn hash(&self) -> H256 { BlakeTwo256::hash_of(self) @@ -216,20 +186,20 @@ impl BundleHeader { +pub struct SealedBundleHeader { /// Unsealed header. - pub header: BundleHeader, + pub header: BundleHeader, /// Signature of the bundle. - pub signature: ExecutorSignature, + pub signature: OperatorSignature, } -impl - SealedBundleHeader +impl + SealedBundleHeader { /// Constructs a new instance of [`SealedBundleHeader`]. pub fn new( - header: BundleHeader, - signature: ExecutorSignature, + header: BundleHeader, + signature: OperatorSignature, ) -> Self { Self { header, signature } } @@ -244,167 +214,28 @@ impl BlakeTwo256::hash_of(self) } - /// Returns whether the signature is valid. - pub fn verify_signature(&self) -> bool { - self.header - .bundle_solution - .proof_of_election() - .executor_public_key - .verify(&self.pre_hash(), &self.signature) - } -} - -#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] -pub struct ProofOfElection { - /// Domain id. - pub domain_id: DomainId, - /// VRF output. - pub vrf_output: VrfOutput, - /// VRF proof. - pub vrf_proof: VrfProof, - /// VRF public key. - pub executor_public_key: ExecutorPublicKey, - /// Global challenge. - pub global_challenge: Blake2b256Hash, - /// Storage proof containing the partial state for verifying the bundle election. - pub storage_proof: StorageProof, - /// State root corresponding to the storage proof above. - pub system_state_root: DomainHash, - /// Number of the system domain block at which the proof of election was created. - pub system_block_number: BlockNumber, - /// Block hash corresponding to the `block_number` above. - pub system_block_hash: DomainHash, -} - -impl ProofOfElection { - pub fn verify_vrf_proof(&self) -> Result<(), VrfProofError> { - bundle_election::verify_vrf_proof( - &self.executor_public_key, - // TODO: Maybe we want to store signature in the struct rather than separate fields, - // such that we don't need to clone here? - &VrfSignature { - output: self.vrf_output.clone(), - proof: self.vrf_proof.clone(), - }, - &self.global_challenge, - ) - } - - /// Computes the VRF hash. - pub fn vrf_hash(&self) -> Blake2b256Hash { - let mut bytes = self.vrf_output.encode(); - bytes.append(&mut self.vrf_proof.encode()); - blake2b_256_hash(&bytes) - } -} - -impl ProofOfElection { - #[cfg(any(feature = "std", feature = "runtime-benchmarks"))] - pub fn dummy(domain_id: DomainId, executor_public_key: ExecutorPublicKey) -> Self { - let output_bytes = vec![0u8; VrfOutput::max_encoded_len()]; - let proof_bytes = vec![0u8; VrfProof::max_encoded_len()]; - Self { - domain_id, - vrf_output: VrfOutput::decode(&mut output_bytes.as_slice()).unwrap(), - vrf_proof: VrfProof::decode(&mut proof_bytes.as_slice()).unwrap(), - executor_public_key, - global_challenge: Blake2b256Hash::default(), - storage_proof: StorageProof::empty(), - system_state_root: Default::default(), - system_block_number: Default::default(), - system_block_hash: Default::default(), - } - } -} - -/// Domain bundle election solution. -#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] -pub enum BundleSolution { - /// System domain bundle election. - System { - /// Authority's stake weight. - authority_stake_weight: StakeWeight, - /// Authority membership witness. - authority_witness: Witness, - /// Proof of election - proof_of_election: ProofOfElection, - }, - /// Core domain bundle election. - Core { - /// Proof of election. - proof_of_election: ProofOfElection, - /// Number of the core domain block at which the proof of election was created. - core_block_number: BlockNumber, - /// Block hash corresponding to the `core_block_number` above. - core_block_hash: DomainHash, - /// Core domain state root corresponding to the `core_block_hash` above. - core_state_root: DomainHash, - }, -} - -impl BundleSolution { - pub fn proof_of_election(&self) -> &ProofOfElection { - match self { - Self::System { - proof_of_election, .. - } - | Self::Core { - proof_of_election, .. - } => proof_of_election, - } - } - - /// Returns the hash of the block on top of which the solution was created. - pub fn creation_block_hash(&self) -> &DomainHash { - match self { - Self::System { - proof_of_election, .. - } => &proof_of_election.system_block_hash, - Self::Core { - core_block_hash, .. - } => core_block_hash, - } - } -} - -impl BundleSolution { - #[cfg(any(feature = "std", feature = "runtime-benchmarks"))] - pub fn dummy(domain_id: DomainId, executor_public_key: ExecutorPublicKey) -> Self { - let proof_of_election = ProofOfElection::dummy(domain_id, executor_public_key); - - if domain_id.is_system() { - Self::System { - authority_stake_weight: Default::default(), - authority_witness: Default::default(), - proof_of_election, - } - } else if domain_id.is_core() { - Self::Core { - proof_of_election, - core_block_number: Default::default(), - core_block_hash: Default::default(), - core_state_root: Default::default(), - } - } else { - panic!("Open domain unsupported"); - } + pub fn slot_number(&self) -> u64 { + self.header.proof_of_election.slot_number } } /// Domain bundle. #[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] -pub struct Bundle { +pub struct Bundle { /// Sealed bundle header. - pub sealed_header: SealedBundleHeader, - /// Execution receipt that should extend the receipt chain or add confirmations - /// to the head receipt. - pub receipt: ExecutionReceipt, + pub sealed_header: SealedBundleHeader, /// The accompanying extrinsics. pub extrinsics: Vec, } -impl - Bundle +impl< + Extrinsic: Encode, + Number: Encode, + Hash: Encode, + DomainNumber: Encode, + DomainHash: Encode, + Balance: Encode, + > Bundle { /// Returns the hash of this bundle. pub fn hash(&self) -> H256 { @@ -413,35 +244,47 @@ impl /// Returns the domain_id of this bundle. pub fn domain_id(&self) -> DomainId { - self.sealed_header - .header - .bundle_solution - .proof_of_election() - .domain_id - } - - /// Consumes [`Bundle`] to extract the inner executor public key. - pub fn into_executor_public_key(self) -> ExecutorPublicKey { - match self.sealed_header.header.bundle_solution { - BundleSolution::System { - proof_of_election, .. - } - | BundleSolution::Core { - proof_of_election, .. - } => proof_of_election.executor_public_key, - } + self.sealed_header.header.proof_of_election.domain_id + } + + /// Return the `bundle_extrinsics_root` + pub fn extrinsics_root(&self) -> ExtrinsicsRoot { + self.sealed_header.header.bundle_extrinsics_root + } + + /// Return the `operator_id` + pub fn operator_id(&self) -> OperatorId { + self.sealed_header.header.proof_of_election.operator_id + } + + /// Return a reference of the execution receipt. + pub fn receipt(&self) -> &ExecutionReceipt { + &self.sealed_header.header.receipt + } + + /// Consumes [`Bundle`] to extract the execution receipt. + pub fn into_receipt(self) -> ExecutionReceipt { + self.sealed_header.header.receipt } } /// Bundle with opaque extrinsics. -pub type OpaqueBundle = Bundle; +pub type OpaqueBundle = + Bundle; + +/// List of [`OpaqueBundle`]. +pub type OpaqueBundles = + Vec, ::Hash, DomainNumber, DomainHash, Balance>>; -impl Bundle { +impl + Bundle +{ /// Convert a bundle with generic extrinsic to a bundle with opaque extrinsic. - pub fn into_opaque_bundle(self) -> OpaqueBundle { + pub fn into_opaque_bundle( + self, + ) -> OpaqueBundle { let Bundle { sealed_header, - receipt, extrinsics, } = self; let opaque_extrinsics = extrinsics @@ -453,121 +296,411 @@ impl Bundle { - /// Primary block number. - pub primary_number: Number, - /// Hash of the origin primary block this receipt corresponds to. - pub primary_hash: Hash, - /// Hash of the domain block this receipt points to. - pub domain_hash: DomainHash, +pub struct ExecutionReceipt { + /// The index of the current domain block that forms the basis of this ER. + pub domain_block_number: DomainNumber, + /// The block hash corresponding to `domain_block_number`. + pub domain_block_hash: DomainHash, + /// The hash of the ER for the last domain block. + pub parent_domain_block_receipt_hash: ReceiptHash, + /// A pointer to the consensus block index which contains all of the bundles that were used to derive and + /// order all extrinsics executed by the current domain block for this ER. + pub consensus_block_number: Number, + /// The block hash corresponding to `consensus_block_number`. + pub consensus_block_hash: Hash, + /// Potential bundles that are excluded from the domain block building. + pub invalid_bundles: Vec, + /// All `extrinsics_roots` for all bundles being executed by this block. + /// + /// Used to ensure these are contained within the state of the `execution_inbox`. + pub block_extrinsics_roots: Vec, + /// The final state root for the current domain block reflected by this ER. + /// + /// Used for verifying storage proofs for domains. + pub final_state_root: DomainHash, /// List of storage roots collected during the domain block execution. - pub trace: Vec, - /// The merkle root of `trace`. - pub trace_root: Blake2b256Hash, + pub execution_trace: Vec, + /// The Merkle root of the execution trace for the current domain block. + /// + /// Used for verifying fraud proofs. + pub execution_trace_root: H256, + /// All SSC rewards for this ER to be shared across operators. + pub total_rewards: Balance, } -impl ExecutionReceipt { +impl< + Number: Encode + Zero, + Hash: Encode + Default, + DomainNumber: Encode + Zero, + DomainHash: Clone + Encode + Default, + Balance: Encode + Zero, + > ExecutionReceipt +{ /// Returns the hash of this execution receipt. - pub fn hash(&self) -> H256 { + pub fn hash(&self) -> ReceiptHash { BlakeTwo256::hash_of(self) } + + pub fn genesis(consensus_genesis_hash: Hash, genesis_state_root: DomainHash) -> Self { + ExecutionReceipt { + domain_block_number: Zero::zero(), + domain_block_hash: Default::default(), + parent_domain_block_receipt_hash: Default::default(), + consensus_block_hash: consensus_genesis_hash, + consensus_block_number: Zero::zero(), + invalid_bundles: Vec::new(), + block_extrinsics_roots: sp_std::vec![], + final_state_root: genesis_state_root.clone(), + execution_trace: sp_std::vec![genesis_state_root], + execution_trace_root: Default::default(), + total_rewards: Zero::zero(), + } + } +} + +#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] +pub struct ProofOfElection { + /// Domain id. + pub domain_id: DomainId, + /// The slot number. + pub slot_number: u64, + /// Global randomness. + pub global_randomness: Randomness, + /// VRF signature. + pub vrf_signature: VrfSignature, + /// Operator index in the OperatorRegistry. + pub operator_id: OperatorId, +} + +impl ProofOfElection { + pub fn verify_vrf_signature( + &self, + operator_signing_key: &OperatorPublicKey, + ) -> Result<(), VrfProofError> { + let global_challenge = self + .global_randomness + .derive_global_challenge(self.slot_number); + bundle_producer_election::verify_vrf_signature( + self.domain_id, + operator_signing_key, + &self.vrf_signature, + &global_challenge, + ) + } + + /// Computes the VRF hash. + pub fn vrf_hash(&self) -> Blake2b256Hash { + let mut bytes = self.vrf_signature.output.encode(); + bytes.append(&mut self.vrf_signature.proof.encode()); + blake2b_256_hash(&bytes) + } } -impl ExecutionReceipt { +impl ProofOfElection { #[cfg(any(feature = "std", feature = "runtime-benchmarks"))] - pub fn dummy( - primary_number: Number, - primary_hash: Hash, - ) -> ExecutionReceipt { - let trace = if primary_number.is_zero() { - Vec::new() - } else { - sp_std::vec![Default::default(), Default::default()] + pub fn dummy(domain_id: DomainId, operator_id: OperatorId) -> Self { + let output_bytes = vec![0u8; VrfOutput::max_encoded_len()]; + let proof_bytes = vec![0u8; VrfProof::max_encoded_len()]; + let vrf_signature = VrfSignature { + output: VrfOutput::decode(&mut output_bytes.as_slice()).unwrap(), + proof: VrfProof::decode(&mut proof_bytes.as_slice()).unwrap(), }; - ExecutionReceipt { - primary_number, - primary_hash, - domain_hash: Default::default(), - trace, - trace_root: Default::default(), + Self { + domain_id, + slot_number: 0u64, + global_randomness: Randomness::default(), + vrf_signature, + operator_id, } } } -/// List of [`OpaqueBundle`]. -pub type OpaqueBundles = - Vec, ::Hash, DomainHash>>; - -#[cfg(any(feature = "std", feature = "runtime-benchmarks"))] -pub fn create_dummy_bundle_with_receipts_generic( - domain_id: DomainId, - primary_number: BlockNumber, - primary_hash: Hash, - receipt: ExecutionReceipt, -) -> OpaqueBundle -where - BlockNumber: Encode + Default, - Hash: Encode + Default, - DomainHash: Encode + Default, -{ - use sp_core::crypto::UncheckedFrom; +#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct GenesisDomain { + // Domain runtime items + pub runtime_name: Vec, + pub runtime_type: RuntimeType, + pub runtime_version: RuntimeVersion, + pub code: Vec, + + // Domain config items + pub owner_account_id: AccountId, + pub domain_name: Vec, + pub max_block_size: u32, + pub max_block_weight: Weight, + pub bundle_slot_probability: (u64, u64), + pub target_bundles_per_block: u32, + pub raw_genesis_config: Vec, - let sealed_header = SealedBundleHeader { - header: BundleHeader { - primary_number, - primary_hash, - slot_number: 0u64, - extrinsics_root: Default::default(), - bundle_solution: BundleSolution::dummy( - domain_id, - ExecutorPublicKey::unchecked_from([0u8; 32]), - ), - }, - signature: ExecutorSignature::unchecked_from([0u8; 64]), - }; + // Genesis operator + pub signing_key: OperatorPublicKey, + pub minimum_nominator_stake: Balance, + pub nomination_tax: Percent, +} + +/// Types of runtime pallet domains currently supports +#[derive( + TypeInfo, Debug, Default, Encode, Decode, Clone, PartialEq, Eq, Serialize, Deserialize, +)] +pub enum RuntimeType { + #[default] + Evm, +} + +impl PassBy for RuntimeType { + type PassBy = pass_by::Codec; +} + +/// Type representing the runtime ID. +pub type RuntimeId = u32; + +/// Type representing domain epoch. +pub type EpochIndex = u32; + +/// Type representing operator ID +pub type OperatorId = u64; + +/// Staking specific hold identifier +#[derive( + PartialEq, Eq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, Ord, PartialOrd, Copy, Debug, +)] +pub enum StakingHoldIdentifier { + /// Holds all the pending deposits to an Operator. + PendingDeposit(OperatorId), + /// Holds all the currently staked funds to an Operator. + Staked(OperatorId), + /// Holds all the currently unlocking funds. + PendingUnlock(OperatorId), +} + +/// Domains specific Identifier for Balances holds. +#[derive( + PartialEq, Eq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, Ord, PartialOrd, Copy, Debug, +)] +pub enum DomainsHoldIdentifier { + Staking(StakingHoldIdentifier), + DomainInstantiation(DomainId), +} + +/// Domains specific digest item. +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)] +pub enum DomainDigestItem { + DomainRuntimeUpgraded(RuntimeId), + DomainInstantiated(DomainId), +} + +/// Domains specific digest items. +pub trait DomainsDigestItem { + fn domain_runtime_upgrade(runtime_id: RuntimeId) -> Self; + fn as_domain_runtime_upgrade(&self) -> Option; + + fn domain_instantiation(domain_id: DomainId) -> Self; + fn as_domain_instantiation(&self) -> Option; +} + +impl DomainsDigestItem for DigestItem { + fn domain_runtime_upgrade(runtime_id: RuntimeId) -> Self { + Self::Other(DomainDigestItem::DomainRuntimeUpgraded(runtime_id).encode()) + } + + fn as_domain_runtime_upgrade(&self) -> Option { + match self.try_to::(OpaqueDigestItemId::Other) { + Some(DomainDigestItem::DomainRuntimeUpgraded(runtime_id)) => Some(runtime_id), + _ => None, + } + } + + fn domain_instantiation(domain_id: DomainId) -> Self { + Self::Other(DomainDigestItem::DomainInstantiated(domain_id).encode()) + } - OpaqueBundle { - sealed_header, - receipt, - extrinsics: Vec::new(), + fn as_domain_instantiation(&self) -> Option { + match self.try_to::(OpaqueDigestItemId::Other) { + Some(DomainDigestItem::DomainInstantiated(domain_id)) => Some(domain_id), + _ => None, + } + } +} + +/// `DomainInstanceData` is used to construct `RuntimeGenesisConfig` which will be further used +/// to construct the genesis block +#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)] +pub struct DomainInstanceData { + pub runtime_type: RuntimeType, + pub runtime_code: Vec, + // The genesis config of the domain, encoded in json format. + // + // NOTE: the WASM code in the `system-pallet` genesis config should be empty to avoid + // redundancy with the `runtime_code` field. + pub raw_genesis_config: Option>, +} + +impl PassBy for DomainInstanceData { + type PassBy = pass_by::Codec; +} + +#[cfg(feature = "std")] +pub trait GenerateGenesisStateRoot: Send + Sync { + /// Returns the state root of genesis block built from the runtime genesis config on success. + fn generate_genesis_state_root( + &self, + domain_id: DomainId, + domain_instance_data: DomainInstanceData, + ) -> Option; +} + +#[cfg(feature = "std")] +sp_externalities::decl_extension! { + /// A domain genesis receipt extension. + pub struct GenesisReceiptExtension(std::sync::Arc); +} + +#[cfg(feature = "std")] +impl GenesisReceiptExtension { + /// Create a new instance of [`GenesisReceiptExtension`]. + pub fn new(inner: std::sync::Arc) -> Self { + Self(inner) + } +} + +/// Domain-related runtime interface +#[runtime_interface] +pub trait Domain { + fn generate_genesis_state_root( + &mut self, + domain_id: DomainId, + domain_instance_data: DomainInstanceData, + ) -> Option { + use sp_externalities::ExternalitiesExt; + + self.extension::() + .expect("No `GenesisReceiptExtension` associated for the current context!") + .generate_genesis_state_root(domain_id, domain_instance_data) } } +#[derive(Debug, Decode, Encode, TypeInfo, Clone)] +pub struct DomainBlockLimit { + /// The max block size for the domain. + pub max_block_size: u32, + /// The max block weight for the domain. + pub max_block_weight: Weight, +} + +/// Checks if the signer Id hash is within the tx range +pub fn signer_in_tx_range(bundle_vrf_hash: &U256, signer_id_hash: &U256, tx_range: &U256) -> bool { + let distance_from_vrf_hash = bidirectional_distance(bundle_vrf_hash, signer_id_hash); + distance_from_vrf_hash <= (*tx_range / 2) +} + +/// Receipt invalidity type. +#[derive(Debug, Decode, Encode, TypeInfo, Clone, PartialEq, Eq)] +pub enum InvalidReceipt { + /// The field `invalid_bundles` in [`ExecutionReceipt`] is invalid. + InvalidBundles, +} + +#[derive(Debug, Decode, Encode, TypeInfo, Clone, PartialEq, Eq)] +pub enum ReceiptValidity { + Valid, + Invalid(InvalidReceipt), +} + +/// Bundle invalidity type. +#[derive(Debug, Decode, Encode, TypeInfo, Clone, PartialEq, Eq)] +pub enum InvalidBundleType { + /// Failed to decode the opaque extrinsic. + UndecodableTx, + /// Transaction is out of the tx range. + OutOfRangeTx, + /// Transaction is illegal (unable to pay the fee, etc). + IllegalTx, + /// Receipt is invalid. + InvalidReceipt(InvalidReceipt), +} + +/// [`InvalidBundle`] represents a bundle that was originally included in the consensus +/// block but subsequently excluded from the corresponding domain block by operator due +/// to being flagged as invalid. +#[derive(Debug, Decode, Encode, TypeInfo, Clone, PartialEq, Eq)] +pub struct InvalidBundle { + /// Index of this bundle in the original list of bundles in the consensus block. + pub bundle_index: u32, + /// Specific type of invalidity. + pub invalid_bundle_type: InvalidBundleType, +} + +#[derive(Debug, Decode, Encode, TypeInfo, Clone, PartialEq, Eq)] +pub enum BundleValidity { + Valid(Vec), + Invalid(InvalidBundleType), +} + sp_api::decl_runtime_apis! { - /// API necessary for executor pallet. - pub trait ExecutorApi { + /// API necessary for domains pallet. + pub trait DomainsApi { /// Submits the transaction bundle via an unsigned extrinsic. - fn submit_bundle_unsigned(opaque_bundle: OpaqueBundle, Block::Hash, DomainHash>); - - /// Extract the system bundles from the given extrinsics. - fn extract_system_bundles( - extrinsics: Vec, - ) -> (OpaqueBundles, OpaqueBundles); + fn submit_bundle_unsigned(opaque_bundle: OpaqueBundle, Block::Hash, DomainNumber, DomainHash, Balance>); - /// Extract the core bundles from the given extrinsics. - fn extract_core_bundles( - extrinsics: Vec, + /// Extract the bundles stored successfully from the given extrinsics. + fn extract_successful_bundles( domain_id: DomainId, - ) -> OpaqueBundles; - - /// Returns the hash of successfully submitted bundles. - fn successful_bundle_hashes() -> Vec; + extrinsics: Vec, + ) -> OpaqueBundles; /// Generates a randomness seed for extrinsics shuffling. fn extrinsics_shuffling_seed(header: Block::Header) -> Randomness; - /// WASM bundle for system domain runtime. - fn system_domain_wasm_bundle() -> Cow<'static, [u8]>; + /// Returns the WASM bundle for given `domain_id`. + fn domain_runtime_code(domain_id: DomainId) -> Option>; + + /// Returns the runtime id for given `domain_id`. + fn runtime_id(domain_id: DomainId) -> Option; + + /// Returns the domain instance data for given `domain_id`. + fn domain_instance_data(domain_id: DomainId) -> Option<(DomainInstanceData, NumberFor)>; - // Returns the current timestamp at given height + /// Returns the current timestamp at given height. fn timestamp() -> Moment; + + /// Returns the current Tx range for the given domain Id. + fn domain_tx_range(domain_id: DomainId) -> U256; + + /// Return the genesis state root if not pruned + fn genesis_state_root(domain_id: DomainId) -> Option; + + /// Returns the best execution chain number. + fn head_receipt_number(domain_id: DomainId) -> NumberFor; + + /// Returns the block number of oldest execution receipt. + fn oldest_receipt_number(domain_id: DomainId) -> NumberFor; + + /// Returns the block tree pruning depth. + fn block_tree_pruning_depth() -> NumberFor; + + /// Returns the domain block limit of the given domain. + fn domain_block_limit(domain_id: DomainId) -> Option; + } + + pub trait BundleProducerElectionApi { + fn bundle_producer_election_params(domain_id: DomainId) -> Option>; + + fn operator(operator_id: OperatorId) -> Option<(OperatorPublicKey, Balance)>; } } diff --git a/crates/sp-domains/src/merkle_tree.rs b/crates/sp-domains/src/merkle_tree.rs index 83b6b519193..9f80c670b1f 100644 --- a/crates/sp-domains/src/merkle_tree.rs +++ b/crates/sp-domains/src/merkle_tree.rs @@ -1,4 +1,4 @@ -use crate::ExecutorPublicKey; +use crate::OperatorPublicKey; use blake2::digest::typenum::U32; use blake2::digest::FixedOutput; use blake2::{Blake2b, Digest}; @@ -48,7 +48,7 @@ impl Hasher for Blake2b256Algorithm { /// Constructs a merkle tree from given authorities. pub fn authorities_merkle_tree( - authorities: &[(ExecutorPublicKey, StakeWeight)], + authorities: &[(OperatorPublicKey, StakeWeight)], ) -> MerkleTree { let leaves = authorities .iter() diff --git a/crates/sp-domains/src/tests.rs b/crates/sp-domains/src/tests.rs new file mode 100644 index 00000000000..5a087d890af --- /dev/null +++ b/crates/sp-domains/src/tests.rs @@ -0,0 +1,209 @@ +use crate::signer_in_tx_range; +use num_traits::ops::wrapping::{WrappingAdd, WrappingSub}; +use subspace_core_primitives::U256; + +#[test] +fn test_tx_range() { + let tx_range = U256::MAX / 4; + let bundle_vrf_hash = U256::MAX / 2; + + let signer_id_hash = bundle_vrf_hash + U256::from(10_u64); + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash - U256::from(10_u64); + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash + U256::MAX / 8; + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash - U256::MAX / 8; + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash + U256::MAX / 8 + U256::from(1_u64); + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash - U256::MAX / 8 - U256::from(1_u64); + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash + U256::MAX / 4; + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash - U256::MAX / 4; + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); +} + +#[test] +fn test_tx_range_wrap_under_flow() { + let tx_range = U256::MAX / 4; + let bundle_vrf_hash = U256::from(100_u64); + + let signer_id_hash = bundle_vrf_hash + U256::from(1000_u64); + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash.wrapping_sub(&U256::from(1000_u64)); + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash + U256::MAX / 8; + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let v = U256::MAX / 8; + let signer_id_hash = bundle_vrf_hash.wrapping_sub(&v); + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash + U256::MAX / 8 + U256::from(1_u64); + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let v = U256::MAX / 8 + U256::from(1_u64); + let signer_id_hash = bundle_vrf_hash.wrapping_sub(&v); + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash + U256::MAX / 4; + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let v = U256::MAX / 4; + let signer_id_hash = bundle_vrf_hash.wrapping_sub(&v); + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); +} + +#[test] +fn test_tx_range_wrap_over_flow() { + let tx_range = U256::MAX / 4; + let v = U256::MAX; + let bundle_vrf_hash = v.wrapping_sub(&U256::from(100_u64)); + + let signer_id_hash = bundle_vrf_hash.wrapping_add(&U256::from(1000_u64)); + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash - U256::from(1000_u64); + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let v = U256::MAX / 8; + let signer_id_hash = bundle_vrf_hash.wrapping_add(&v); + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash - U256::MAX / 8; + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let v = U256::MAX / 8 + U256::from(1_u64); + let signer_id_hash = bundle_vrf_hash.wrapping_add(&v); + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash - U256::MAX / 8 - U256::from(1_u64); + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let v = U256::MAX / 4; + let signer_id_hash = bundle_vrf_hash.wrapping_add(&v); + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); + + let signer_id_hash = bundle_vrf_hash - U256::MAX / 4; + assert!(!signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); +} + +#[test] +fn test_tx_range_max() { + let tx_range = U256::MAX; + let bundle_vrf_hash = U256::MAX / 2; + + let signer_id_hash = bundle_vrf_hash + U256::from(10_u64); + assert!(signer_in_tx_range( + &bundle_vrf_hash, + &signer_id_hash, + &tx_range + )); +} diff --git a/crates/sp-domains/src/transaction.rs b/crates/sp-domains/src/transaction.rs index bab6193ef9a..434d2974fab 100644 --- a/crates/sp-domains/src/transaction.rs +++ b/crates/sp-domains/src/transaction.rs @@ -4,6 +4,7 @@ use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::traits::{Block as BlockT, NumberFor}; use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidity}; +use subspace_runtime_primitives::Balance; /// Custom invalid validity code for the extrinsics in pallet-domains. #[repr(u8)] @@ -31,20 +32,24 @@ impl From for TransactionValidity { /// Object for performing the pre-validation in the transaction pool /// before calling into the regular `validate_transaction` runtime api. +// TODO: Revisit +#[allow(clippy::large_enum_variant)] #[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)] -pub enum PreValidationObject +pub enum PreValidationObject where Block: BlockT, { Null, FraudProof(FraudProof, Block::Hash>), - Bundle(OpaqueBundle, Block::Hash, DomainHash>), + Bundle(OpaqueBundle, Block::Hash, DomainNumber, DomainHash, Balance>), } sp_api::decl_runtime_apis! { /// API for extracting the pre-validation objects in the primary chain transaction pool wrapper. - pub trait PreValidationObjectApi { + pub trait PreValidationObjectApi { /// Extract the pre-validation object from the given extrinsic. - fn extract_pre_validation_object(extrinsics: Block::Extrinsic) -> PreValidationObject; + fn extract_pre_validation_object( + extrinsics: Block::Extrinsic, + ) -> PreValidationObject; } } diff --git a/crates/sp-lightclient/Cargo.toml b/crates/sp-lightclient/Cargo.toml index 34c30f78c85..49d2e3a1a20 100644 --- a/crates/sp-lightclient/Cargo.toml +++ b/crates/sp-lightclient/Cargo.toml @@ -19,18 +19,18 @@ include = [ codec = { package = "parity-scale-codec", version = "3.1.2", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } schnorrkel = { version = "0.9.1", default-features = false, features = ["u64_backend"] } -sp-arithmetic = { version = "16.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-arithmetic = { version = "16.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace", default-features = false } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } subspace-erasure-coding = { version = "0.1.0", path = "../subspace-erasure-coding", default-features = false } subspace-solving = { version = "0.1.0", path = "../subspace-solving", default-features = false } subspace-verification = { version = "0.1.0", path = "../subspace-verification", default-features = false } [dev-dependencies] -frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } futures = "0.3.28" rand = { version = "0.8.5", features = ["min_const_gen"] } subspace-archiving = { version = "0.1.0", path = "../subspace-archiving"} diff --git a/crates/sp-lightclient/src/lib.rs b/crates/sp-lightclient/src/lib.rs index d668e1079ee..027957c5186 100644 --- a/crates/sp-lightclient/src/lib.rs +++ b/crates/sp-lightclient/src/lib.rs @@ -35,9 +35,10 @@ use sp_runtime::ArithmeticError; use sp_std::cmp::Ordering; use sp_std::collections::btree_map::BTreeMap; use sp_std::marker::PhantomData; +use sp_std::num::NonZeroU64; use subspace_core_primitives::{ - ArchivedHistorySegment, BlockWeight, PublicKey, Randomness, RewardSignature, SectorId, - SegmentCommitment, SegmentIndex, SolutionRange, + ArchivedHistorySegment, BlockWeight, HistorySize, PublicKey, Randomness, RewardSignature, + SectorId, SegmentCommitment, SegmentIndex, SolutionRange, }; use subspace_solving::REWARD_SIGNING_CONTEXT; use subspace_verification::{ @@ -55,28 +56,28 @@ mod mock; pub struct ChainConstants { /// K Depth at which we finalize the heads. pub k_depth: NumberOf
, - /// Genesis digest items at the start of the chain since the genesis block will not have any /// digests to verify the Block #1 digests. pub genesis_digest_items: NextDigestItems, - /// Genesis block segment commitments to verify the Block #1 and other block solutions until /// Block #1 is finalized. /// When Block #1 is finalized, these segment commitments are present in Block #1 are stored in /// the storage. pub genesis_segment_commitments: BTreeMap, - /// Defines interval at which randomness is updated. pub global_randomness_interval: NumberOf
, - /// Era duration at which solution range is updated. pub era_duration: NumberOf
, - /// Slot probability. pub slot_probability: (u64, u64), - /// Storage bound for the light client store. pub storage_bound: StorageBound>, + /// Number of latest archived segments that are considered "recent history". + pub recent_segments: HistorySize, + /// Fraction of pieces from the "recent history" (`recent_segments`) in each sector. + pub recent_history_fraction: (HistorySize, HistorySize), + /// Minimum lifetime of a plotted sector, measured in archived segment. + pub min_sector_lifetime: HistorySize, } /// Defines the storage bound for the light client store. @@ -214,6 +215,7 @@ pub trait Storage { fn segment_commitment(&self, segment_index: SegmentIndex) -> Option; /// Returns the stored segment count. + // TODO: Ideally should use `HistorySize` instead of `u64` fn number_of_segments(&self) -> u64; /// How many pieces one sector is supposed to contain (max) @@ -258,6 +260,10 @@ pub enum ImportError { MissingSegmentCommitment(SegmentIndex), /// Incorrect block author. IncorrectBlockAuthor(FarmerPublicKey), + /// Segment commitment history is empty + EmptySegmentCommitmentHistory, + /// Invalid history size + InvalidHistorySize, } impl From for ImportError
{ @@ -349,17 +355,36 @@ impl> HeaderImporter { header_digests.pre_digest.solution.sector_index, ); + let max_pieces_in_sector = self.store.max_pieces_in_sector(); + let segment_index = sector_id .derive_piece_index( header_digests.pre_digest.solution.piece_offset, header_digests.pre_digest.solution.history_size, + max_pieces_in_sector, + constants.recent_segments, + constants.recent_history_fraction, ) .segment_index(); - let segment_commitment = self.find_segment_commitment_for_segment_index( - segment_index, - parent_header.header.hash(), - )?; + let segment_commitment = self + .find_segment_commitment_for_segment_index(segment_index, parent_header.header.hash())? + .ok_or(ImportError::MissingSegmentCommitment(segment_index))?; + let current_history_size = HistorySize::new( + NonZeroU64::try_from(self.store.number_of_segments()) + .map_err(|_error| ImportError::EmptySegmentCommitmentHistory)?, + ); + let sector_expiration_check_segment_commitment = self + .find_segment_commitment_for_segment_index( + header_digests + .pre_digest + .solution + .history_size + .sector_expiration_check(constants.min_sector_lifetime) + .ok_or(ImportError::InvalidHistorySize)? + .segment_index(), + parent_header.header.hash(), + )?; verify_solution( (&header_digests.pre_digest.solution).into(), @@ -368,8 +393,13 @@ impl> HeaderImporter { global_randomness: header_digests.global_randomness, solution_range: header_digests.solution_range, piece_check_params: Some(PieceCheckParams { - max_pieces_in_sector: self.store.max_pieces_in_sector(), + max_pieces_in_sector, segment_commitment, + recent_segments: constants.recent_segments, + recent_history_fraction: constants.recent_history_fraction, + min_sector_lifetime: constants.min_sector_lifetime, + current_history_size, + sector_expiration_check_segment_commitment, }), }) .into(), @@ -654,10 +684,10 @@ impl> HeaderImporter { &self, segment_index: SegmentIndex, chain_tip: HashOf
, - ) -> Result> { + ) -> Result, ImportError
> { // check if the segment commitment is already in the store if let Some(segment_commitment) = self.store.segment_commitment(segment_index) { - return Ok(segment_commitment); + return Ok(Some(segment_commitment)); }; // special case: check the genesis segment commitments if the Block #1 is not finalized yet @@ -667,7 +697,7 @@ impl> HeaderImporter { .genesis_segment_commitments .get(&segment_index) { - return Ok(*segment_commitment); + return Ok(Some(*segment_commitment)); } // find the segment commitment from the headers which are not finalized yet. @@ -686,7 +716,7 @@ impl> HeaderImporter { >(&header.header)?; if let Some(segment_commitment) = digest_items.segment_commitments.get(&segment_index) { - return Ok(*segment_commitment); + return Ok(Some(*segment_commitment)); } header = self @@ -695,7 +725,7 @@ impl> HeaderImporter { .ok_or_else(|| ImportError::MissingParent(header.header.hash()))?; } - Err(ImportError::MissingSegmentCommitment(segment_index)) + Ok(None) } /// Stores finalized header and segment commitments present in the header. diff --git a/crates/sp-lightclient/src/tests.rs b/crates/sp-lightclient/src/tests.rs index db18c864458..32e2a09e286 100644 --- a/crates/sp-lightclient/src/tests.rs +++ b/crates/sp-lightclient/src/tests.rs @@ -20,7 +20,7 @@ use sp_runtime::testing::H256; use sp_runtime::traits::Header as HeaderT; use sp_runtime::{Digest, DigestItem}; use std::iter; -use std::num::NonZeroUsize; +use std::num::{NonZeroU64, NonZeroUsize}; use subspace_archiving::archiver::{Archiver, NewArchivedSegment}; use subspace_core_primitives::crypto::kzg; use subspace_core_primitives::crypto::kzg::Kzg; @@ -33,6 +33,7 @@ use subspace_farmer_components::auditing::audit_sector; use subspace_farmer_components::plotting::{plot_sector, PieceGetterRetryPolicy}; use subspace_farmer_components::sector::{sector_size, SectorMetadata}; use subspace_farmer_components::FarmerProtocolInfo; +use subspace_proof_of_space::Table; use subspace_solving::REWARD_SIGNING_CONTEXT; use subspace_verification::{ calculate_block_weight, derive_randomness, verify_solution, VerifySolutionParams, @@ -55,6 +56,12 @@ fn default_test_constants() -> ChainConstants
{ era_duration: 20, slot_probability: (1, 6), storage_bound: Default::default(), + recent_segments: HistorySize::from(NonZeroU64::new(5).unwrap()), + recent_history_fraction: ( + HistorySize::from(NonZeroU64::new(1).unwrap()), + HistorySize::from(NonZeroU64::new(10).unwrap()), + ), + min_sector_lifetime: HistorySize::from(NonZeroU64::new(4).unwrap()), } } @@ -67,7 +74,7 @@ fn archived_segment(kzg: Kzg) -> NewArchivedSegment { let mut archiver = Archiver::new(kzg).unwrap(); archiver - .add_block(block, Default::default()) + .add_block(block, Default::default(), true) .into_iter() .next() .unwrap() @@ -91,7 +98,12 @@ impl FarmerParameters { let farmer_protocol_info = FarmerProtocolInfo { history_size: HistorySize::from(SegmentIndex::ZERO), max_pieces_in_sector: 1, - sector_expiration: SegmentIndex::ONE, + recent_segments: HistorySize::from(NonZeroU64::new(5).unwrap()), + recent_history_fraction: ( + HistorySize::from(NonZeroU64::new(1).unwrap()), + HistorySize::from(NonZeroU64::new(10).unwrap()), + ), + min_sector_lifetime: HistorySize::from(NonZeroU64::new(4).unwrap()), }; Self { @@ -143,13 +155,14 @@ fn valid_header( let pieces_in_sector = farmer_parameters.farmer_protocol_info.max_pieces_in_sector; let sector_size = sector_size(pieces_in_sector); - for (sector_offset, sector_index) in iter::from_fn(|| Some(rand::random())).enumerate() { + let mut table_generator = PosTable::generator(); + + for sector_index in iter::from_fn(|| Some(rand::random())) { let mut plotted_sector_bytes = vec![0; sector_size]; let mut plotted_sector_metadata_bytes = vec![0; SectorMetadata::encoded_size()]; let plotted_sector = block_on(plot_sector::<_, PosTable>( &public_key, - sector_offset, sector_index, &farmer_parameters.archived_segment.pieces, PieceGetterRetryPolicy::default(), @@ -159,7 +172,7 @@ fn valid_header( pieces_in_sector, &mut plotted_sector_bytes, &mut plotted_sector_metadata_bytes, - Default::default(), + &mut table_generator, )) .unwrap(); @@ -184,6 +197,7 @@ fn valid_header( &public_key, &farmer_parameters.kzg, &farmer_parameters.erasure_coding, + &mut table_generator, ) .unwrap() .next() @@ -221,6 +235,7 @@ fn valid_header( let pre_digest = PreDigest { slot: slot.into(), solution, + proof_of_time: Default::default(), }; let digests = vec![ DigestItem::global_randomness(global_randomness), @@ -1445,3 +1460,5 @@ fn test_disallow_root_plot_public_key_override() { ); }); } + +// TODO: Test for expired sector diff --git a/crates/sp-objects/Cargo.toml b/crates/sp-objects/Cargo.toml index 9e140a43394..d223b042f46 100644 --- a/crates/sp-objects/Cargo.toml +++ b/crates/sp-objects/Cargo.toml @@ -13,8 +13,8 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } diff --git a/crates/sp-settlement/Cargo.toml b/crates/sp-settlement/Cargo.toml deleted file mode 100644 index 09300b5d9a1..00000000000 --- a/crates/sp-settlement/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "sp-settlement" -version = "0.1.0" -authors = ["Liu-Cheng Xu "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://subspace.network" -repository = "https://github.com/subspace/subspace" -description = "Primitives for Receipts" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.1.2", default-features = false } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } - -[features] -default = ["std"] -std = [ - "codec/std", - "sp-api/std", - "sp-core/std", - "sp-domains/std", - "sp-runtime/std", - "sp-std/std", -] diff --git a/crates/sp-settlement/src/lib.rs b/crates/sp-settlement/src/lib.rs deleted file mode 100644 index 729f1e59c82..00000000000 --- a/crates/sp-settlement/src/lib.rs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2023 Subspace Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Primitives for Receipts. - -#![cfg_attr(not(feature = "std"), no_std)] - -use codec::{Decode, Encode}; -use sp_core::H256; -use sp_domains::fraud_proof::FraudProof; -use sp_domains::{DomainId, ExecutionReceipt}; -use sp_runtime::traits::NumberFor; -use sp_std::vec::Vec; - -sp_api::decl_runtime_apis! { - pub trait SettlementApi { - /// Returns the trace of given domain receipt hash. - fn execution_trace(domain_id: DomainId, receipt_hash: H256) -> Vec; - - /// Returns the state root of given domain block. - fn state_root( - domain_id: DomainId, - domain_block_number: NumberFor, - domain_block_hash: Block::Hash, - ) -> Option; - - /// Returns the primary block hash for given domain block number. - fn primary_hash( - domain_id: DomainId, - domain_block_number: NumberFor, - ) -> Option; - - /// Returns the receipts pruning depth. - fn receipts_pruning_depth() -> NumberFor; - - /// Returns the best execution chain number. - fn head_receipt_number(domain_id: DomainId) -> NumberFor; - - /// Returns the block number of oldest execution receipt. - fn oldest_receipt_number(domain_id: DomainId) -> NumberFor; - - /// Returns the maximum receipt drift. - fn maximum_receipt_drift() -> NumberFor; - - /// Extract the receipts from the given extrinsics. - fn extract_receipts( - extrinsics: Vec, - domain_id: DomainId, - ) -> Vec, Block::Hash, DomainHash>>; - - /// Extract the fraud proofs from the given extrinsics. - fn extract_fraud_proofs( - extrinsics: Vec, - domain_id: DomainId, - ) -> Vec, Block::Hash>>; - - /// Submits the fraud proof via an unsigned extrinsic. - fn submit_fraud_proof_unsigned(fraud_proof: FraudProof, Block::Hash>); - } -} diff --git a/crates/subspace-archiving/Cargo.toml b/crates/subspace-archiving/Cargo.toml index d6876134b16..a94cd936532 100644 --- a/crates/subspace-archiving/Cargo.toml +++ b/crates/subspace-archiving/Cargo.toml @@ -17,7 +17,7 @@ include = [ bench = false [dependencies] -parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } +parity-scale-codec = { version = "3.6.3", default-features = false, features = ["derive"] } rayon = { version = "1.7.0", optional = true } serde = { version = "1.0.159", optional = true, features = ["derive"] } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } diff --git a/crates/subspace-archiving/benches/archiving.rs b/crates/subspace-archiving/benches/archiving.rs index b2bf99e884b..0cd77d8c7de 100644 --- a/crates/subspace-archiving/benches/archiving.rs +++ b/crates/subspace-archiving/benches/archiving.rs @@ -1,24 +1,53 @@ -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; use rand::{thread_rng, Rng}; use subspace_archiving::archiver::Archiver; use subspace_core_primitives::crypto::kzg; use subspace_core_primitives::crypto::kzg::Kzg; -use subspace_core_primitives::RecordedHistorySegment; + +const AMOUNT_OF_DATA: usize = 5 * 1024 * 1024; +const SMALL_BLOCK_SIZE: usize = 500; fn criterion_benchmark(c: &mut Criterion) { - let mut input = RecordedHistorySegment::new_boxed(); - thread_rng().fill(AsMut::<[u8]>::as_mut(input.as_mut())); + let mut input = vec![0u8; AMOUNT_OF_DATA]; + thread_rng().fill(input.as_mut_slice()); let kzg = Kzg::new(kzg::embedded_kzg_settings()); - let mut archiver = Archiver::new(kzg).unwrap(); + let archiver = Archiver::new(kzg).unwrap(); - c.bench_function("segment-archiving", |b| { + c.bench_function("segment-archiving-large-block", |b| { b.iter(|| { - archiver.add_block( - AsRef::<[u8]>::as_ref(input.as_ref()).to_vec(), - Default::default(), + archiver.clone().add_block( + black_box(input.clone()), + black_box(Default::default()), + black_box(true), ); }) }); + + c.bench_function("segment-archiving-small-blocks/incremental", |b| { + b.iter(|| { + let mut archiver = archiver.clone(); + for chunk in input.chunks(SMALL_BLOCK_SIZE) { + archiver.add_block( + black_box(chunk.to_vec()), + black_box(Default::default()), + black_box(true), + ); + } + }) + }); + + c.bench_function("segment-archiving-small-blocks/non-incremental", |b| { + b.iter(|| { + let mut archiver = archiver.clone(); + for chunk in input.chunks(SMALL_BLOCK_SIZE) { + archiver.add_block( + black_box(chunk.to_vec()), + black_box(Default::default()), + black_box(false), + ); + } + }) + }); } criterion_group!(benches, criterion_benchmark); diff --git a/crates/subspace-archiving/src/archiver.rs b/crates/subspace-archiving/src/archiver.rs index 8d5cd033302..b09f0f9baee 100644 --- a/crates/subspace-archiving/src/archiver.rs +++ b/crates/subspace-archiving/src/archiver.rs @@ -124,11 +124,6 @@ impl Segment { let Self::V0 { items } = self; items.push(segment_item); } - - fn pop_item(&mut self) -> Option { - let Self::V0 { items } = self; - items.pop() - } } /// Kinds of items that are contained within a segment @@ -248,6 +243,7 @@ pub struct Archiver { } impl Archiver { + // TODO: Make erasure coding an explicit argument /// Create a new instance with specified record size and recorded history segment size. /// /// Note: this is the only way to instantiate object archiver, while block archiver can be @@ -316,13 +312,13 @@ impl Archiver { // buffer and block continuation object_mapping .objects - .drain_filter(|block_object: &mut BlockObject| { + .retain_mut(|block_object: &mut BlockObject| { let current_offset = block_object.offset(); if current_offset >= archived_block_bytes { block_object.set_offset(current_offset - archived_block_bytes); - false - } else { true + } else { + false } }); archiver.buffer.push_back(SegmentItem::BlockContinuation { @@ -345,11 +341,15 @@ impl Archiver { } } - /// Adds new block to internal buffer, potentially producing pieces and segment header headers + /// Adds new block to internal buffer, potentially producing pieces and segment header headers. + /// + /// Incremental archiving can be enabled if amortized block addition cost is preferred over + /// throughput. pub fn add_block( &mut self, bytes: Vec, object_mapping: BlockObjectMapping, + incremental: bool, ) -> Vec { // Append new block to the buffer self.buffer.push_back(SegmentItem::Block { @@ -359,7 +359,7 @@ impl Archiver { let mut archived_segments = Vec::new(); - while let Some(segment) = self.produce_segment() { + while let Some(segment) = self.produce_segment(incremental) { archived_segments.push(self.produce_archived_segment(segment)); } @@ -368,24 +368,32 @@ impl Archiver { /// Try to slice buffer contents into segments if there is enough data, producing one segment at /// a time - fn produce_segment(&mut self) -> Option { + fn produce_segment(&mut self, incremental: bool) -> Option { let mut segment = Segment::V0 { items: Vec::with_capacity(self.buffer.len()), }; let mut last_archived_block = self.last_archived_block; + let mut segment_size = segment.encoded_size(); + // `-2` because even the smallest segment item will take 2 bytes to encode, so it makes // sense to stop earlier here - while segment.encoded_size() < (RecordedHistorySegment::SIZE - 2) { + while segment_size < (RecordedHistorySegment::SIZE - 2) { let segment_item = match self.buffer.pop_front() { Some(segment_item) => segment_item, None => { - update_record_commitments( - &mut self.incremental_record_commitments, - &segment, - &self.kzg, - ); + let existing_commitments = self.incremental_record_commitments.len(); + let bytes_committed_to = existing_commitments * RawRecord::SIZE; + // Run incremental archiver only when there is at least two records to archive, + // otherwise we're wasting CPU cycles encoding segment over and over again + if incremental && segment_size - bytes_committed_to >= RawRecord::SIZE * 2 { + update_record_commitments( + &mut self.incremental_record_commitments, + &segment, + &self.kzg, + ); + } let Segment::V0 { items } = segment; // Push all of the items back into the buffer, we don't have enough data yet @@ -397,18 +405,14 @@ impl Archiver { } }; - // Push segment item into the segment temporarily to measure encoded size of resulting - // segment - segment.push_item(segment_item); - let encoded_segment_length = segment.encoded_size(); - // Pop segment item back from segment - let segment_item = segment.pop_item().unwrap(); + let segment_item_encoded_size = segment_item.encoded_size(); + segment_size += segment_item_encoded_size; // Check if there would be enough data collected with above segment item inserted - if encoded_segment_length >= RecordedHistorySegment::SIZE { + if segment_size >= RecordedHistorySegment::SIZE { // Check if there is an excess of data that should be spilled over into the next // segment - let spill_over = encoded_segment_length - RecordedHistorySegment::SIZE; + let spill_over = segment_size - RecordedHistorySegment::SIZE; // Due to compact vector length encoding in scale codec, spill over might happen to // be the same or even bigger than the inserted segment item bytes, in which case @@ -433,6 +437,7 @@ impl Archiver { if spill_over > inner_bytes_size { self.buffer.push_front(segment_item); + segment_size -= segment_item_encoded_size; break; } } @@ -476,8 +481,7 @@ impl Archiver { } // Check if there is an excess of data that should be spilled over into the next segment - let segment_encoded_length = segment.encoded_size(); - let spill_over = segment_encoded_length + let spill_over = segment_size .checked_sub(RecordedHistorySegment::SIZE) .unwrap_or_default(); @@ -503,7 +507,7 @@ impl Archiver { let continuation_object_mapping = BlockObjectMapping { objects: object_mapping .objects - .drain_filter(|block_object: &mut BlockObject| { + .extract_if(|block_object: &mut BlockObject| { let current_offset = block_object.offset(); if current_offset >= split_point as u32 { block_object.set_offset(current_offset - split_point as u32); @@ -547,7 +551,7 @@ impl Archiver { let continuation_object_mapping = BlockObjectMapping { objects: object_mapping .objects - .drain_filter(|block_object: &mut BlockObject| { + .extract_if(|block_object: &mut BlockObject| { let current_offset = block_object.offset(); if current_offset >= split_point as u32 { block_object.set_offset(current_offset - split_point as u32); diff --git a/crates/subspace-archiving/src/lib.rs b/crates/subspace-archiving/src/lib.rs index e0eb8770d09..9ceae191f4e 100644 --- a/crates/subspace-archiving/src/lib.rs +++ b/crates/subspace-archiving/src/lib.rs @@ -15,7 +15,7 @@ //! Collection of modules used for dealing with archived state of Subspace Network. #![cfg_attr(not(feature = "std"), no_std)] -#![feature(array_chunks, drain_filter, iter_collect_into, slice_flatten)] +#![feature(array_chunks, extract_if, iter_collect_into, slice_flatten)] pub mod archiver; pub mod piece_reconstructor; diff --git a/crates/subspace-archiving/src/piece_reconstructor.rs b/crates/subspace-archiving/src/piece_reconstructor.rs index 0b61254bccb..1849e9dbe5a 100644 --- a/crates/subspace-archiving/src/piece_reconstructor.rs +++ b/crates/subspace-archiving/src/piece_reconstructor.rs @@ -52,6 +52,7 @@ pub struct PiecesReconstructor { } impl PiecesReconstructor { + // TODO: Make erasure coding an explicit argument pub fn new(kzg: Kzg) -> Result { // TODO: Check if KZG can process number configured number of elements and update proof // message in `.expect()` diff --git a/crates/subspace-archiving/src/reconstructor.rs b/crates/subspace-archiving/src/reconstructor.rs index 905e79037c0..6151a67ae52 100644 --- a/crates/subspace-archiving/src/reconstructor.rs +++ b/crates/subspace-archiving/src/reconstructor.rs @@ -71,6 +71,7 @@ pub struct Reconstructor { } impl Reconstructor { + // TODO: Make erasure coding an explicit argument pub fn new() -> Result { // TODO: Check if KZG can process number configured number of elements and update proof // message in `.expect()` diff --git a/crates/subspace-archiving/tests/integration/archiver.rs b/crates/subspace-archiving/tests/integration/archiver.rs index f67bd8c4e57..025f789dbf7 100644 --- a/crates/subspace-archiving/tests/integration/archiver.rs +++ b/crates/subspace-archiving/tests/integration/archiver.rs @@ -95,7 +95,7 @@ fn archiver() { }; // There is not enough data to produce archived segment yet assert!(archiver - .add_block(block_0.clone(), block_0_object_mapping.clone()) + .add_block(block_0.clone(), block_0_object_mapping.clone(), true) .is_empty()); let (block_1, block_1_object_mapping) = { @@ -133,7 +133,8 @@ fn archiver() { (block, object_mapping) }; // This should produce 1 archived segment - let archived_segments = archiver.add_block(block_1.clone(), block_1_object_mapping.clone()); + let archived_segments = + archiver.add_block(block_1.clone(), block_1_object_mapping.clone(), true); assert_eq!(archived_segments.len(), 1); let first_archived_segment = archived_segments.into_iter().next().unwrap(); @@ -210,7 +211,8 @@ fn archiver() { block }; // This should be big enough to produce two archived segments in one go - let archived_segments = archiver.add_block(block_2.clone(), BlockObjectMapping::default()); + let archived_segments = + archiver.add_block(block_2.clone(), BlockObjectMapping::default(), true); assert_eq!(archived_segments.len(), 2); // Check that initializing archiver with initial state before last block results in the same @@ -225,7 +227,11 @@ fn archiver() { .unwrap(); assert_eq!( - archiver_with_initial_state.add_block(block_2.clone(), BlockObjectMapping::default()), + archiver_with_initial_state.add_block( + block_2.clone(), + BlockObjectMapping::default(), + true + ), archived_segments, ); } @@ -331,7 +337,8 @@ fn archiver() { thread_rng().fill(block.as_mut_slice()); block }; - let archived_segments = archiver.add_block(block_3.clone(), BlockObjectMapping::default()); + let archived_segments = + archiver.add_block(block_3.clone(), BlockObjectMapping::default(), true); assert_eq!(archived_segments.len(), 1); // Check that initializing archiver with initial state before last block results in the same @@ -346,7 +353,7 @@ fn archiver() { .unwrap(); assert_eq!( - archiver_with_initial_state.add_block(block_3, BlockObjectMapping::default()), + archiver_with_initial_state.add_block(block_3, BlockObjectMapping::default(), true), archived_segments, ); } @@ -466,7 +473,7 @@ fn one_byte_smaller_segment() { assert_eq!( Archiver::new(kzg.clone()) .unwrap() - .add_block(vec![0u8; block_size], BlockObjectMapping::default()) + .add_block(vec![0u8; block_size], BlockObjectMapping::default(), true) .len(), 1 ); @@ -474,7 +481,11 @@ fn one_byte_smaller_segment() { // against code regressions assert!(Archiver::new(kzg) .unwrap() - .add_block(vec![0u8; block_size - 1], BlockObjectMapping::default()) + .add_block( + vec![0u8; block_size - 1], + BlockObjectMapping::default(), + true + ) .is_empty()); } @@ -498,7 +509,7 @@ fn spill_over_edge_case() { // We leave three bytes at the end intentionally - 3; assert!(archiver - .add_block(vec![0u8; block_size], BlockObjectMapping::default()) + .add_block(vec![0u8; block_size], BlockObjectMapping::default(), true) .is_empty()); // Here we add one more block with internal length that takes 4 bytes in compact length @@ -513,6 +524,7 @@ fn spill_over_edge_case() { offset: 0, }], }, + true, ); assert_eq!(archived_segments.len(), 2); // If spill over actually happened, we'll not find object mapping in the first segment @@ -539,7 +551,8 @@ fn object_on_the_edge_of_segment() { let kzg = Kzg::new(embedded_kzg_settings()); let mut archiver = Archiver::new(kzg).unwrap(); let first_block = vec![0u8; RecordedHistorySegment::SIZE]; - let archived_segments = archiver.add_block(first_block.clone(), BlockObjectMapping::default()); + let archived_segments = + archiver.add_block(first_block.clone(), BlockObjectMapping::default(), true); assert_eq!(archived_segments.len(), 1); let archived_segment = archived_segments.into_iter().next().unwrap(); let left_unarchived_from_first_block = first_block.len() as u32 @@ -600,6 +613,7 @@ fn object_on_the_edge_of_segment() { offset: object_mapping.offset() - 1, }], }, + true, ); assert_eq!(archived_segments.len(), 2); @@ -618,6 +632,7 @@ fn object_on_the_edge_of_segment() { BlockObjectMapping { objects: vec![object_mapping], }, + true, ); assert_eq!(archived_segments.len(), 2); diff --git a/crates/subspace-archiving/tests/integration/piece_reconstruction.rs b/crates/subspace-archiving/tests/integration/piece_reconstruction.rs index 07dd21de780..c1426f035b8 100644 --- a/crates/subspace-archiving/tests/integration/piece_reconstruction.rs +++ b/crates/subspace-archiving/tests/integration/piece_reconstruction.rs @@ -25,7 +25,7 @@ fn segment_reconstruction_works() { let block = get_random_block(); - let archived_segments = archiver.add_block(block, BlockObjectMapping::default()); + let archived_segments = archiver.add_block(block, BlockObjectMapping::default(), true); assert_eq!(archived_segments.len(), 1); @@ -66,7 +66,7 @@ fn piece_reconstruction_works() { // Block that fits into the segment fully let block = get_random_block(); - let archived_segments = archiver.add_block(block, BlockObjectMapping::default()); + let archived_segments = archiver.add_block(block, BlockObjectMapping::default(), true); assert_eq!(archived_segments.len(), 1); @@ -126,7 +126,7 @@ fn segment_reconstruction_fails() { // Block that fits into the segment fully let block = get_random_block(); - let archived_segments = archiver.add_block(block, BlockObjectMapping::default()); + let archived_segments = archiver.add_block(block, BlockObjectMapping::default(), true); assert_eq!(archived_segments.len(), 1); @@ -163,7 +163,7 @@ fn piece_reconstruction_fails() { // Block that fits into the segment fully let block = get_random_block(); - let archived_segments = archiver.add_block(block, BlockObjectMapping::default()); + let archived_segments = archiver.add_block(block, BlockObjectMapping::default(), true); assert_eq!(archived_segments.len(), 1); diff --git a/crates/subspace-archiving/tests/integration/reconstructor.rs b/crates/subspace-archiving/tests/integration/reconstructor.rs index 06b551a4a4d..bd4e9860fde 100644 --- a/crates/subspace-archiving/tests/integration/reconstructor.rs +++ b/crates/subspace-archiving/tests/integration/reconstructor.rs @@ -49,12 +49,12 @@ fn basic() { block }; let archived_segments = archiver - .add_block(block_0.clone(), BlockObjectMapping::default()) + .add_block(block_0.clone(), BlockObjectMapping::default(), true) .into_iter() - .chain(archiver.add_block(block_1.clone(), BlockObjectMapping::default())) - .chain(archiver.add_block(block_2.clone(), BlockObjectMapping::default())) - .chain(archiver.add_block(block_3.clone(), BlockObjectMapping::default())) - .chain(archiver.add_block(block_4, BlockObjectMapping::default())) + .chain(archiver.add_block(block_1.clone(), BlockObjectMapping::default(), true)) + .chain(archiver.add_block(block_2.clone(), BlockObjectMapping::default(), true)) + .chain(archiver.add_block(block_3.clone(), BlockObjectMapping::default(), true)) + .chain(archiver.add_block(block_4, BlockObjectMapping::default(), true)) .collect::>(); assert_eq!(archived_segments.len(), 5); @@ -257,9 +257,9 @@ fn partial_data() { block }; let archived_segments = archiver - .add_block(block_0.clone(), BlockObjectMapping::default()) + .add_block(block_0.clone(), BlockObjectMapping::default(), true) .into_iter() - .chain(archiver.add_block(block_1, BlockObjectMapping::default())) + .chain(archiver.add_block(block_1, BlockObjectMapping::default(), true)) .collect::>(); assert_eq!(archived_segments.len(), 1); @@ -332,7 +332,7 @@ fn invalid_usage() { block }; - let archived_segments = archiver.add_block(block_0, BlockObjectMapping::default()); + let archived_segments = archiver.add_block(block_0, BlockObjectMapping::default(), true); assert_eq!(archived_segments.len(), 4); diff --git a/crates/subspace-core-primitives/Cargo.toml b/crates/subspace-core-primitives/Cargo.toml index dcb1aab25f1..a0456e4126b 100644 --- a/crates/subspace-core-primitives/Cargo.toml +++ b/crates/subspace-core-primitives/Cargo.toml @@ -17,6 +17,7 @@ bench = false [dependencies] blake2 = { version = "0.10.6", default-features = false } +blake3 = { version = "1.4.1", default-features = false } # TODO: Switch to upstream `main` once https://github.com/sifraitech/rust-kzg/pull/204 is merged and blst has upstream no_std support blst_rust = { git = "https://github.com/subspace/rust-kzg", rev = "1058cc8c8af8461b490dc212c41d7d506a746577", default-features = false } derive_more = "0.99.17" @@ -24,7 +25,7 @@ hex = { version = "0.4.3", default-features = false, features = ["alloc"] } # TODO: Switch to upstream `main` once https://github.com/sifraitech/rust-kzg/pull/204 is merged and blst has upstream no_std support kzg = { git = "https://github.com/subspace/rust-kzg", rev = "1058cc8c8af8461b490dc212c41d7d506a746577", default-features = false } num-traits = { version = "0.2.15", default-features = false } -parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive", "max-encoded-len"] } +parity-scale-codec = { version = "3.6.3", default-features = false, features = ["derive", "max-encoded-len"] } parking_lot = { version = "0.12.1", optional = true } rayon = { version = "1.7.0", optional = true } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } @@ -64,6 +65,7 @@ serde = [ ] std = [ "blake2/std", + "blake3/std", "blst_rust/std", "hex/std", "kzg/std", diff --git a/crates/subspace-core-primitives/src/crypto.rs b/crates/subspace-core-primitives/src/crypto.rs index 5a279c2566d..8df4e4d0c5d 100644 --- a/crates/subspace-core-primitives/src/crypto.rs +++ b/crates/subspace-core-primitives/src/crypto.rs @@ -19,7 +19,7 @@ extern crate alloc; pub mod kzg; -use crate::Blake2b256Hash; +use crate::{Blake2b256Hash, Blake3Hash}; use alloc::format; use alloc::string::String; use alloc::vec::Vec; @@ -65,7 +65,7 @@ pub fn blake2b_256_254_hash_to_scalar(data: &[u8]) -> Scalar { /// BLAKE2b-256 keyed hashing of a single value. /// /// PANIC: Panics if key is longer than 64 bytes. -pub fn blake2b_256_hash_with_key(data: &[u8], key: &[u8]) -> Blake2b256Hash { +pub fn blake2b_256_hash_with_key(key: &[u8], data: &[u8]) -> Blake2b256Hash { let mut state = Blake2bMac::::new_with_salt_and_personal(key, &[], &[]) .expect("Only panics when key is over 64 bytes as specified in function description"); Update::update(&mut state, data); @@ -84,6 +84,20 @@ pub fn blake2b_256_hash_list(data: &[&[u8]]) -> Blake2b256Hash { .expect("Initialized with correct length; qed") } +/// BLAKE3 hashing of a single value. +pub fn blake3_hash(data: &[u8]) -> Blake3Hash { + *blake3::hash(data).as_bytes() +} + +/// BLAKE3 hashing of a list of values. +pub fn blake3_hash_list(data: &[&[u8]]) -> Blake3Hash { + let mut state = blake3::Hasher::new(); + for d in data { + state.update(d); + } + *state.finalize().as_bytes() +} + /// Representation of a single BLS12-381 scalar value. #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, From, Into, AsRef, AsMut, Deref, DerefMut)] #[repr(transparent)] @@ -97,7 +111,7 @@ impl Hash for Scalar { impl PartialOrd for Scalar { fn partial_cmp(&self, other: &Self) -> Option { - self.to_bytes().partial_cmp(&other.to_bytes()) + Some(self.cmp(other)) } } diff --git a/crates/subspace-core-primitives/src/lib.rs b/crates/subspace-core-primitives/src/lib.rs index f9ea461d996..fd41bf70b2f 100644 --- a/crates/subspace-core-primitives/src/lib.rs +++ b/crates/subspace-core-primitives/src/lib.rs @@ -41,13 +41,17 @@ mod tests; extern crate alloc; use crate::crypto::kzg::{Commitment, Witness}; -use crate::crypto::{blake2b_256_hash, blake2b_256_hash_with_key, Scalar}; +use crate::crypto::{blake2b_256_hash, blake2b_256_hash_list, blake2b_256_hash_with_key, Scalar}; #[cfg(feature = "serde")] use ::serde::{Deserialize, Serialize}; +use alloc::boxed::Box; +use alloc::vec::Vec; use core::convert::AsRef; use core::fmt; +use core::iter::Iterator; +use core::num::NonZeroU64; use core::simd::Simd; -use derive_more::{Add, Deref, DerefMut, Display, Div, From, Into, Mul, Rem, Sub}; +use derive_more::{Add, AsMut, AsRef, Deref, DerefMut, Display, Div, From, Into, Mul, Rem, Sub}; use num_traits::{WrappingAdd, WrappingSub}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; pub use pieces::{ @@ -61,15 +65,24 @@ use uint::static_assertions::const_assert; // Refuse to compile on lower than 32-bit platforms const_assert!(core::mem::size_of::() >= core::mem::size_of::()); -/// Size of BLAKE2b-256 hash output (in bytes). -pub const BLAKE2B_256_HASH_SIZE: usize = 32; - /// Byte length of a randomness type. pub const RANDOMNESS_LENGTH: usize = 32; +/// Size of BLAKE2b-256 hash output (in bytes). +pub const BLAKE2B_256_HASH_SIZE: usize = 32; + /// BLAKE2b-256 hash output pub type Blake2b256Hash = [u8; BLAKE2B_256_HASH_SIZE]; +/// Size of BLAKE3 hash output (in bytes). +pub const BLAKE3_HASH_SIZE: usize = 32; + +/// BLAKE3 hash output +pub type Blake3Hash = [u8; BLAKE3_HASH_SIZE]; + +/// 128 bits for the proof of time data types. +pub type PotBytes = [u8; 16]; + /// Type of randomness. #[derive( Debug, @@ -127,6 +140,9 @@ pub type SolutionRange = u64; /// The closer solution's tag is to the target, the heavier it is. pub type BlockWeight = u128; +/// Block hash (the bytes from H256) +pub type BlockHash = [u8; 32]; + // TODO: New type /// Segment commitment type. pub type SegmentCommitment = Commitment; @@ -213,6 +229,167 @@ impl Default for PosProof { impl PosProof { /// Size of proof of space proof in bytes. pub const SIZE: usize = 17 * 8; + + /// Proof hash. + pub fn hash(&self) -> Blake2b256Hash { + blake2b_256_hash(&self.0) + } +} + +/// Proof of time key(input to the encryption). +#[derive( + Debug, + Default, + Copy, + Clone, + Eq, + PartialEq, + From, + Into, + AsRef, + AsMut, + Encode, + Decode, + TypeInfo, + MaxEncodedLen, +)] +pub struct PotKey(PotBytes); + +/// Proof of time seed (input to the encryption). +#[derive( + Debug, + Default, + Copy, + Clone, + Eq, + PartialEq, + From, + Into, + AsRef, + AsMut, + Encode, + Decode, + TypeInfo, + MaxEncodedLen, +)] +pub struct PotSeed(PotBytes); + +impl PotSeed { + /// Builds the seed from block hash (e.g) used to create initial seed from + /// genesis block hash. + #[inline] + pub fn from_block_hash(block_hash: BlockHash) -> Self { + Self(truncate_32_bytes(block_hash)) + } +} + +/// Proof of time ciphertext (output from the encryption). +#[derive( + Debug, + Default, + Copy, + Clone, + Eq, + PartialEq, + From, + Into, + AsRef, + AsMut, + Encode, + Decode, + TypeInfo, + MaxEncodedLen, +)] +pub struct PotCheckpoint(PotBytes); + +/// Proof of time. +/// TODO: versioning. +#[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] +pub struct PotProof { + /// Slot the proof was evaluated for. + pub slot_number: SlotNumber, + + /// The seed used for evaluation. + pub seed: PotSeed, + + /// The key used for evaluation. + pub key: PotKey, + + /// The encrypted outputs from each stage. + pub checkpoints: NonEmptyVec, + + /// Hash of last block at injection point. + pub injected_block_hash: BlockHash, +} + +impl PotProof { + /// Create the proof. + pub fn new( + slot_number: SlotNumber, + seed: PotSeed, + key: PotKey, + checkpoints: NonEmptyVec, + injected_block_hash: BlockHash, + ) -> Self { + Self { + slot_number, + seed, + key, + checkpoints, + injected_block_hash, + } + } + + /// Returns the last check point. + pub fn output(&self) -> PotCheckpoint { + self.checkpoints.last() + } + + /// Derives the global randomness from the output. + pub fn derive_global_randomness(&self) -> Blake2b256Hash { + blake2b_256_hash(&PotBytes::from(self.output())) + } + + /// Derives the next seed based on the injected randomness. + pub fn next_seed(&self, injected_hash: Option) -> PotSeed { + match injected_hash { + Some(injected_hash) => { + // Next seed = Hash(last checkpoint + injected hash). + let hash = blake2b_256_hash_list(&[&self.output().0, &injected_hash]); + PotSeed::from(truncate_32_bytes(hash)) + } + None => { + // No injected randomness, next seed = last checkpoint. + PotSeed::from(self.output().0) + } + } + } + + /// Derives the next key from the hash of the current seed. + pub fn next_key(&self) -> PotKey { + PotKey::from(truncate_32_bytes(blake2b_256_hash(&self.seed.0))) + } +} + +impl fmt::Display for PotProof { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "PotProof: [slot={}, seed={}, key={}, injected={}, checkpoints={}]", + self.slot_number, + hex::encode(self.seed.0), + hex::encode(self.key.0), + hex::encode(self.injected_block_hash), + self.checkpoints.len() + ) + } +} + +/// Helper to truncate the 32 bytes to 16 bytes. +fn truncate_32_bytes(bytes: [u8; 32]) -> PotBytes { + bytes[..core::mem::size_of::()] + .try_into() + .expect("Hash is longer than seed; qed") } /// A Ristretto Schnorr public key as bytes produced by `schnorrkel` crate. @@ -389,7 +566,7 @@ impl SegmentHeader { } } - /// Merkle root of the records in a segment. + /// Segment commitment of the records in a segment. pub fn segment_commitment(&self) -> SegmentCommitment { match self { Self::V0 { @@ -420,7 +597,7 @@ impl SegmentHeader { } /// Sector index in consensus -pub type SectorIndex = u64; +pub type SectorIndex = u16; // TODO: Versioned solution enum /// Farmer solution for slot challenge. @@ -521,15 +698,34 @@ pub fn bidirectional_distance(a: &T, b: &T) -> T { #[allow(clippy::assign_op_pattern, clippy::ptr_offset_with_cast)] mod private_u256 { //! This module is needed to scope clippy allows + use parity_scale_codec::{Decode, Encode}; + use scale_info::TypeInfo; uint::construct_uint! { + #[derive(Encode, Decode, TypeInfo)] pub struct U256(4); } } /// 256-bit unsigned integer #[derive( - Debug, Display, Add, Sub, Mul, Div, Rem, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, + Debug, + Display, + Add, + Sub, + Mul, + Div, + Rem, + Copy, + Clone, + Ord, + PartialOrd, + Eq, + PartialEq, + Hash, + Encode, + Decode, + TypeInfo, )] pub struct U256(private_u256::U256); @@ -734,6 +930,12 @@ impl TryFrom for u64 { } } +impl Default for U256 { + fn default() -> Self { + Self::zero() + } +} + /// Challenge used for a particular sector for particular slot #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deref)] pub struct SectorSlotChallenge(Blake2b256Hash); @@ -782,10 +984,36 @@ impl SectorId { &self, piece_offset: PieceOffset, history_size: HistorySize, + max_pieces_in_sector: u16, + recent_segments: HistorySize, + recent_history_fraction: (HistorySize, HistorySize), ) -> PieceIndex { - let piece_index = - U256::from_le_bytes(blake2b_256_hash_with_key(&self.0, &piece_offset.to_bytes())) - % U256::from(history_size.in_pieces().get()); + let recent_segments_in_pieces = recent_segments.in_pieces().get(); + // Recent history must be at most `recent_history_fraction` of all history to use separate + // policy for recent pieces + let min_history_size_in_pieces = recent_segments_in_pieces + * recent_history_fraction.1.in_pieces().get() + / recent_history_fraction.0.in_pieces().get(); + let input_hash = + U256::from_le_bytes(blake2b_256_hash_with_key(&piece_offset.to_bytes(), &self.0)); + let history_size_in_pieces = history_size.in_pieces().get(); + let num_interleaved_pieces = 1.max( + u64::from(max_pieces_in_sector) * recent_history_fraction.0.in_pieces().get() + / recent_history_fraction.1.in_pieces().get() + * 2, + ); + + let piece_index = if history_size_in_pieces > min_history_size_in_pieces + && u64::from(piece_offset) < num_interleaved_pieces + && u16::from(piece_offset) % 2 == 1 + { + // For odd piece offsets at the beginning of the sector pick pieces at random from + // recent history only + input_hash % U256::from(recent_segments_in_pieces) + + U256::from(history_size_in_pieces - recent_segments_in_pieces) + } else { + input_hash % U256::from(history_size_in_pieces) + }; PieceIndex::from(u64::try_from(piece_index).expect( "Remainder of division by PieceIndex is guaranteed to fit into PieceIndex; qed", @@ -802,19 +1030,125 @@ impl SectorId { } /// Derive evaluation seed - pub fn evaluation_seed(&self, piece_offset: PieceOffset, history_size: HistorySize) -> PosSeed { - let mut evaluation_seed = self.0; + pub fn derive_evaluation_seed( + &self, + piece_offset: PieceOffset, + history_size: HistorySize, + ) -> PosSeed { + let evaluation_seed = blake2b_256_hash_list(&[ + &self.0, + &piece_offset.to_bytes(), + &history_size.get().to_le_bytes(), + ]); - for (output, input) in evaluation_seed.iter_mut().zip(piece_offset.to_bytes()) { - *output ^= input; - } - for (output, input) in evaluation_seed - .iter_mut() - .zip(history_size.get().to_le_bytes()) - { - *output ^= input; + PosSeed::from(evaluation_seed) + } + + /// Derive history size when sector created at `history_size` expires. + /// + /// Returns `None` on overflow. + pub fn derive_expiration_history_size( + &self, + history_size: HistorySize, + sector_expiration_check_segment_commitment: &SegmentCommitment, + min_sector_lifetime: HistorySize, + ) -> Option { + let sector_expiration_check_history_size = + history_size.sector_expiration_check(min_sector_lifetime)?; + + let input_hash = U256::from_le_bytes(blake2b_256_hash_list(&[ + &self.0, + §or_expiration_check_segment_commitment.to_bytes(), + ])); + + let last_possible_expiration = + min_sector_lifetime.checked_add(history_size.get().checked_mul(4u64)?)?; + let expires_in = input_hash + % U256::from( + last_possible_expiration + .get() + .checked_sub(sector_expiration_check_history_size.get())?, + ); + let expires_in = u64::try_from(expires_in).expect("Number modulo u64 fits into u64; qed"); + + let expiration_history_size = sector_expiration_check_history_size.get() + expires_in; + let expiration_history_size = NonZeroU64::try_from(expiration_history_size).expect( + "History size is not zero, so result is not zero even if expires immediately; qed", + ); + Some(HistorySize::from(expiration_history_size)) + } +} + +/// A Vec<> that enforces the invariant that it cannot be empty. +#[derive(Debug, Clone, Encode, Decode, Eq, PartialEq)] +pub struct NonEmptyVec(Vec); + +/// Error codes for `NonEmptyVec`. +#[derive(Debug)] +pub enum NonEmptyVecErr { + /// Tried to create with an empty Vec + EmptyVec, +} + +#[allow(clippy::len_without_is_empty)] +impl NonEmptyVec { + /// Creates the Vec. + pub fn new(vec: Vec) -> Result { + if vec.is_empty() { + return Err(NonEmptyVecErr::EmptyVec); } - PosSeed::from(evaluation_seed) + Ok(Self(vec)) + } + + /// Creates the Vec with the entry. + pub fn new_with_entry(entry: T) -> Self { + Self(alloc::vec![entry]) + } + + /// Returns the number of entries. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Returns the slice of the entries. + pub fn as_slice(&self) -> &[T] { + self.0.as_slice() + } + + /// Returns an iterator for the entries. + pub fn iter(&self) -> Box + '_> { + Box::new(self.0.iter()) + } + + /// Returns a mutable iterator for the entries. + pub fn iter_mut(&mut self) -> Box + '_> { + Box::new(self.0.iter_mut()) + } + + /// Returns the first entry. + pub fn first(&self) -> T { + self.0 + .first() + .expect("NonEmptyVec::first(): collection cannot be empty") + .clone() + } + + /// Returns the last entry. + pub fn last(&self) -> T { + self.0 + .last() + .expect("NonEmptyVec::last(): collection cannot be empty") + .clone() + } + + /// Adds an entry to the end. + pub fn push(&mut self, entry: T) { + self.0.push(entry); + } + + /// Returns the entries in the collection. + pub fn to_vec(self) -> Vec { + self.0 } } diff --git a/crates/subspace-core-primitives/src/pieces.rs b/crates/subspace-core-primitives/src/pieces.rs index a81ad2b43d4..72dcf6ffcc1 100644 --- a/crates/subspace-core-primitives/src/pieces.rs +++ b/crates/subspace-core-primitives/src/pieces.rs @@ -20,7 +20,7 @@ use derive_more::{ Add, AddAssign, AsMut, AsRef, Deref, DerefMut, Display, Div, DivAssign, From, Into, Mul, MulAssign, Sub, SubAssign, }; -use parity_scale_codec::{Decode, Encode, Input, MaxEncodedLen}; +use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; #[cfg(feature = "parallel")] use rayon::prelude::*; use scale_info::TypeInfo; @@ -176,6 +176,8 @@ impl From for u64 { } impl PieceIndex { + /// Size in bytes. + pub const SIZE: usize = mem::size_of::(); /// Piece index 0. pub const ZERO: PieceIndex = PieceIndex(0); /// Piece index 1. @@ -186,9 +188,15 @@ impl PieceIndex { PieceIndexHash::from(blake2b_256_hash(&self.to_bytes())) } + /// Create piece index from bytes. + #[inline] + pub const fn from_bytes(bytes: [u8; Self::SIZE]) -> Self { + Self(u64::from_le_bytes(bytes)) + } + /// Convert piece index to bytes. #[inline] - pub const fn to_bytes(self) -> [u8; mem::size_of::()] { + pub const fn to_bytes(self) -> [u8; Self::SIZE] { self.0.to_le_bytes() } @@ -266,6 +274,20 @@ impl From for u16 { } } +impl From for u32 { + #[inline] + fn from(original: PieceOffset) -> Self { + Self::from(original.0) + } +} + +impl From for u64 { + #[inline] + fn from(original: PieceOffset) -> Self { + Self::from(original.0) + } +} + impl From for usize { #[inline] fn from(original: PieceOffset) -> Self { @@ -390,6 +412,35 @@ impl Record { unsafe { Box::new_zeroed().assume_init() } } + /// Create vector filled with zeroe records without hitting stack overflow + #[inline] + pub fn new_zero_vec(length: usize) -> Vec { + // TODO: Should have been just `::new()`, but https://github.com/rust-lang/rust/issues/53827 + let mut records = Vec::with_capacity(length); + { + let slice = records.spare_capacity_mut(); + // SAFETY: Same memory layout due to `#[repr(transparent)]` on `Record` and + // `MaybeUninit<[[T; M]; N]>` is guaranteed to have the same layout as + // `[[MaybeUninit; M]; N]` + let slice = unsafe { + slice::from_raw_parts_mut( + slice.as_mut_ptr() + as *mut [[mem::MaybeUninit; Scalar::FULL_BYTES]; Self::NUM_CHUNKS], + length, + ) + }; + for byte in slice.flatten_mut().flatten_mut() { + byte.write(0); + } + } + // SAFETY: All values are initialized above. + unsafe { + records.set_len(records.capacity()); + } + + records + } + /// Convenient conversion from slice of record to underlying representation for efficiency /// purposes. #[inline] @@ -538,7 +589,7 @@ impl RecordWitness { /// Internally piece contains a record and corresponding witness that together with segment /// commitment of the segment this piece belongs to can be used to verify that a piece belongs to /// the actual archival history of the blockchain. -#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Encode, TypeInfo)] +#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Encode, Decode, TypeInfo)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Piece(Box); @@ -549,19 +600,6 @@ impl Default for Piece { } } -// TODO: Manual implementation due to https://github.com/paritytech/parity-scale-codec/issues/419, -// can be replaced with derive once fixed upstream version is released -impl Decode for Piece { - fn decode(input: &mut I) -> Result { - let piece = parity_scale_codec::decode_vec_with_len::(input, Self::SIZE) - .map_err(|error| error.chain("Could not decode `Piece.0`"))?; - let mut piece = mem::ManuallyDrop::new(piece); - // SAFETY: Original memory is not dropped and guaranteed to be allocated - let piece = unsafe { Box::from_raw(piece.as_mut_ptr() as *mut PieceArray) }; - Ok(Piece(piece)) - } -} - impl From for Vec { #[inline] fn from(piece: Piece) -> Self { diff --git a/crates/subspace-core-primitives/src/segments.rs b/crates/subspace-core-primitives/src/segments.rs index 5aa105a8f15..e5b5beda229 100644 --- a/crates/subspace-core-primitives/src/segments.rs +++ b/crates/subspace-core-primitives/src/segments.rs @@ -24,6 +24,8 @@ use serde::{Deserialize, Serialize}; Eq, PartialEq, Hash, + From, + Into, Encode, Decode, Add, @@ -58,17 +60,51 @@ impl Step for SegmentIndex { } } -impl From for SegmentIndex { - #[inline] - fn from(original: u64) -> Self { - Self(original) +impl SegmentIndex { + /// Segment index 0. + pub const ZERO: SegmentIndex = SegmentIndex(0); + /// Segment index 1. + pub const ONE: SegmentIndex = SegmentIndex(1); + + /// Get the first piece index in this segment. + pub fn first_piece_index(&self) -> PieceIndex { + PieceIndex::from(self.0 * ArchivedHistorySegment::NUM_PIECES as u64) } -} -impl From for u64 { - #[inline] - fn from(original: SegmentIndex) -> Self { - original.0 + /// Get the last piece index in this segment. + pub fn last_piece_index(&self) -> PieceIndex { + PieceIndex::from((self.0 + 1) * ArchivedHistorySegment::NUM_PIECES as u64 - 1) + } + + /// List of piece indexes that belong to this segment. + pub fn segment_piece_indexes(&self) -> [PieceIndex; ArchivedHistorySegment::NUM_PIECES] { + let mut piece_indices = [PieceIndex::ZERO; ArchivedHistorySegment::NUM_PIECES]; + (self.first_piece_index()..=self.last_piece_index()) + .zip(&mut piece_indices) + .for_each(|(input, output)| { + *output = input; + }); + + piece_indices + } + + /// List of piece indexes that belong to this segment with source pieces first. + pub fn segment_piece_indexes_source_first( + &self, + ) -> [PieceIndex; ArchivedHistorySegment::NUM_PIECES] { + let mut source_first_piece_indices = [PieceIndex::ZERO; ArchivedHistorySegment::NUM_PIECES]; + + let piece_indices = self.segment_piece_indexes(); + piece_indices + .into_iter() + .step_by(2) + .chain(piece_indices.into_iter().skip(1).step_by(2)) + .zip(&mut source_first_piece_indices) + .for_each(|(input, output)| { + *output = input; + }); + + source_first_piece_indices } } @@ -104,6 +140,11 @@ impl From for HistorySize { } impl HistorySize { + /// Create new instance. + pub const fn new(value: NonZeroU64) -> Self { + Self(value) + } + /// Size of blockchain history in pieces. pub const fn in_pieces(&self) -> NonZeroU64 { self.0.saturating_mul( @@ -115,29 +156,12 @@ impl HistorySize { pub fn segment_index(&self) -> SegmentIndex { SegmentIndex::from(self.0.get() - 1) } -} - -impl SegmentIndex { - /// Segment index 0. - pub const ZERO: SegmentIndex = SegmentIndex(0); - /// Segment index 1. - pub const ONE: SegmentIndex = SegmentIndex(1); - - /// Get the first piece index in this segment. - pub fn first_piece_index(&self) -> PieceIndex { - PieceIndex::from(self.0 * ArchivedHistorySegment::NUM_PIECES as u64) - } - - /// Iterator over piece indexes that belong to this segment. - pub fn segment_piece_indexes(&self) -> impl Iterator { - (self.first_piece_index()..).take(ArchivedHistorySegment::NUM_PIECES) - } - /// Iterator over piece indexes that belong to this segment with source pieces first. - pub fn segment_piece_indexes_source_first(&self) -> impl Iterator { - self.segment_piece_indexes() - .step_by(2) - .chain(self.segment_piece_indexes().skip(1).step_by(2)) + /// History size at which expiration check for sector happens. + /// + /// Returns `None` on overflow. + pub fn sector_expiration_check(&self, min_sector_lifetime: Self) -> Option { + self.0.checked_add(min_sector_lifetime.0.get()).map(Self) } } diff --git a/crates/subspace-farmer-components/Cargo.toml b/crates/subspace-farmer-components/Cargo.toml index f2cb71eff1a..2ed14d801c2 100644 --- a/crates/subspace-farmer-components/Cargo.toml +++ b/crates/subspace-farmer-components/Cargo.toml @@ -23,7 +23,7 @@ fs2 = "0.4.3" futures = "0.3.28" libc = "0.2.146" lru = "0.10.0" -parity-scale-codec = "3.4.0" +parity-scale-codec = "3.6.3" parking_lot = "0.12.1" rand = "0.8.5" rayon = "1.7.0" @@ -42,7 +42,7 @@ tracing = "0.1.37" [dev-dependencies] criterion = "0.5.1" futures = "0.3.28" -memmap2 = "0.7.0" +memmap2 = "0.7.1" subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-space", features = ["chia"] } diff --git a/crates/subspace-farmer-components/benches/auditing.rs b/crates/subspace-farmer-components/benches/auditing.rs index 07dc44c95ad..9e98eaff011 100644 --- a/crates/subspace-farmer-components/benches/auditing.rs +++ b/crates/subspace-farmer-components/benches/auditing.rs @@ -11,7 +11,7 @@ use subspace_archiving::archiver::Archiver; use subspace_core_primitives::crypto::kzg; use subspace_core_primitives::crypto::kzg::Kzg; use subspace_core_primitives::{ - Blake2b256Hash, HistorySize, PublicKey, Record, RecordedHistorySegment, SectorId, SegmentIndex, + Blake2b256Hash, HistorySize, PublicKey, Record, RecordedHistorySegment, SectorId, SectorIndex, SolutionRange, }; use subspace_erasure_coding::ErasureCoding; @@ -21,6 +21,7 @@ use subspace_farmer_components::plotting::{plot_sector, PieceGetterRetryPolicy, use subspace_farmer_components::sector::{sector_size, SectorContentsMap, SectorMetadata}; use subspace_farmer_components::FarmerProtocolInfo; use subspace_proof_of_space::chia::ChiaTable; +use subspace_proof_of_space::Table; type PosTable = ChiaTable; @@ -42,7 +43,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { .unwrap_or(10); let public_key = PublicKey::default(); - let sector_offset = 0; let sector_index = 0; let mut input = RecordedHistorySegment::new_boxed(); StdRng::seed_from_u64(42).fill(AsMut::<[u8]>::as_mut(input.as_mut())); @@ -52,10 +52,12 @@ pub fn criterion_benchmark(c: &mut Criterion) { NonZeroUsize::new(Record::NUM_S_BUCKETS.next_power_of_two().ilog2() as usize).unwrap(), ) .unwrap(); + let mut table_generator = PosTable::generator(); let archived_history_segment = archiver .add_block( AsRef::<[u8]>::as_ref(input.as_ref()).to_vec(), Default::default(), + true, ) .into_iter() .next() @@ -65,7 +67,12 @@ pub fn criterion_benchmark(c: &mut Criterion) { let farmer_protocol_info = FarmerProtocolInfo { history_size: HistorySize::from(NonZeroU64::new(1).unwrap()), max_pieces_in_sector: pieces_in_sector, - sector_expiration: SegmentIndex::ONE, + recent_segments: HistorySize::from(NonZeroU64::new(5).unwrap()), + recent_history_fraction: ( + HistorySize::from(NonZeroU64::new(1).unwrap()), + HistorySize::from(NonZeroU64::new(10).unwrap()), + ), + min_sector_lifetime: HistorySize::from(NonZeroU64::new(4).unwrap()), }; let global_challenge = Blake2b256Hash::default(); let solution_range = SolutionRange::MAX; @@ -91,7 +98,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { pieces_in_sector, s_bucket_sizes: sector_contents_map.s_bucket_sizes(), history_size: farmer_protocol_info.history_size, - expires_at: Default::default(), }; ( @@ -111,7 +117,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { let plotted_sector = block_on(plot_sector::<_, PosTable>( &public_key, - sector_offset, sector_index, &archived_history_segment, PieceGetterRetryPolicy::default(), @@ -121,7 +126,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { pieces_in_sector, &mut plotted_sector_bytes, &mut plotted_sector_metadata_bytes, - Default::default(), + &mut table_generator, )) .unwrap(); @@ -191,7 +196,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { for (sector_index, sector) in plot_mmap .chunks_exact(sector_size) .enumerate() - .map(|(sector_index, sector)| (sector_index as u64, sector)) + .map(|(sector_index, sector)| (sector_index as SectorIndex, sector)) { audit_sector( black_box(&public_key), diff --git a/crates/subspace-farmer-components/benches/plotting.rs b/crates/subspace-farmer-components/benches/plotting.rs index a1d1f54afbe..c442206ebee 100644 --- a/crates/subspace-farmer-components/benches/plotting.rs +++ b/crates/subspace-farmer-components/benches/plotting.rs @@ -6,14 +6,13 @@ use std::num::{NonZeroU64, NonZeroUsize}; use subspace_archiving::archiver::Archiver; use subspace_core_primitives::crypto::kzg; use subspace_core_primitives::crypto::kzg::Kzg; -use subspace_core_primitives::{ - HistorySize, PublicKey, Record, RecordedHistorySegment, SegmentIndex, -}; +use subspace_core_primitives::{HistorySize, PublicKey, Record, RecordedHistorySegment}; use subspace_erasure_coding::ErasureCoding; use subspace_farmer_components::plotting::{plot_sector, PieceGetterRetryPolicy}; use subspace_farmer_components::sector::{sector_size, SectorMetadata}; use subspace_farmer_components::FarmerProtocolInfo; use subspace_proof_of_space::chia::ChiaTable; +use subspace_proof_of_space::Table; type PosTable = ChiaTable; @@ -26,7 +25,6 @@ fn criterion_benchmark(c: &mut Criterion) { .unwrap_or_else(|_error| MAX_PIECES_IN_SECTOR); let public_key = PublicKey::default(); - let sector_offset = 0; let sector_index = 0; let mut input = RecordedHistorySegment::new_boxed(); StdRng::seed_from_u64(42).fill(AsMut::<[u8]>::as_mut(input.as_mut())); @@ -36,10 +34,12 @@ fn criterion_benchmark(c: &mut Criterion) { NonZeroUsize::new(Record::NUM_S_BUCKETS.next_power_of_two().ilog2() as usize).unwrap(), ) .unwrap(); + let mut table_generator = PosTable::generator(); let archived_history_segment = archiver .add_block( AsRef::<[u8]>::as_ref(input.as_ref()).to_vec(), Default::default(), + true, ) .into_iter() .next() @@ -49,7 +49,12 @@ fn criterion_benchmark(c: &mut Criterion) { let farmer_protocol_info = FarmerProtocolInfo { history_size: HistorySize::from(NonZeroU64::new(1).unwrap()), max_pieces_in_sector: pieces_in_sector, - sector_expiration: SegmentIndex::ONE, + recent_segments: HistorySize::from(NonZeroU64::new(5).unwrap()), + recent_history_fraction: ( + HistorySize::from(NonZeroU64::new(1).unwrap()), + HistorySize::from(NonZeroU64::new(10).unwrap()), + ), + min_sector_lifetime: HistorySize::from(NonZeroU64::new(4).unwrap()), }; let sector_size = sector_size(pieces_in_sector); @@ -62,7 +67,6 @@ fn criterion_benchmark(c: &mut Criterion) { b.iter(|| { block_on(plot_sector::<_, PosTable>( black_box(&public_key), - black_box(sector_offset), black_box(sector_index), black_box(&archived_history_segment), black_box(PieceGetterRetryPolicy::default()), @@ -72,7 +76,7 @@ fn criterion_benchmark(c: &mut Criterion) { black_box(pieces_in_sector), black_box(&mut sector_bytes), black_box(&mut sector_metadata_bytes), - Default::default(), + black_box(&mut table_generator), )) .unwrap(); }) diff --git a/crates/subspace-farmer-components/benches/proving.rs b/crates/subspace-farmer-components/benches/proving.rs index 95ba211d81a..d844152061d 100644 --- a/crates/subspace-farmer-components/benches/proving.rs +++ b/crates/subspace-farmer-components/benches/proving.rs @@ -12,8 +12,7 @@ use subspace_archiving::archiver::Archiver; use subspace_core_primitives::crypto::kzg; use subspace_core_primitives::crypto::kzg::Kzg; use subspace_core_primitives::{ - Blake2b256Hash, HistorySize, PublicKey, Record, RecordedHistorySegment, SectorId, SegmentIndex, - SolutionRange, + Blake2b256Hash, HistorySize, PublicKey, Record, RecordedHistorySegment, SectorId, SolutionRange, }; use subspace_erasure_coding::ErasureCoding; use subspace_farmer_components::auditing::audit_sector; @@ -22,6 +21,7 @@ use subspace_farmer_components::plotting::{plot_sector, PieceGetterRetryPolicy, use subspace_farmer_components::sector::{sector_size, SectorContentsMap, SectorMetadata}; use subspace_farmer_components::FarmerProtocolInfo; use subspace_proof_of_space::chia::ChiaTable; +use subspace_proof_of_space::Table; type PosTable = ChiaTable; @@ -44,7 +44,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { let keypair = Keypair::from_bytes(&[0; 96]).unwrap(); let public_key = PublicKey::from(keypair.public.to_bytes()); - let sector_offset = 0; let sector_index = 0; let mut input = RecordedHistorySegment::new_boxed(); let mut rng = StdRng::seed_from_u64(42); @@ -55,10 +54,12 @@ pub fn criterion_benchmark(c: &mut Criterion) { NonZeroUsize::new(Record::NUM_S_BUCKETS.next_power_of_two().ilog2() as usize).unwrap(), ) .unwrap(); + let mut table_generator = PosTable::generator(); let archived_history_segment = archiver .add_block( AsRef::<[u8]>::as_ref(input.as_ref()).to_vec(), Default::default(), + true, ) .into_iter() .next() @@ -68,7 +69,12 @@ pub fn criterion_benchmark(c: &mut Criterion) { let farmer_protocol_info = FarmerProtocolInfo { history_size: HistorySize::from(NonZeroU64::new(1).unwrap()), max_pieces_in_sector: pieces_in_sector, - sector_expiration: SegmentIndex::ONE, + recent_segments: HistorySize::from(NonZeroU64::new(5).unwrap()), + recent_history_fraction: ( + HistorySize::from(NonZeroU64::new(1).unwrap()), + HistorySize::from(NonZeroU64::new(10).unwrap()), + ), + min_sector_lifetime: HistorySize::from(NonZeroU64::new(4).unwrap()), }; let solution_range = SolutionRange::MAX; let reward_address = PublicKey::default(); @@ -94,7 +100,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { pieces_in_sector, s_bucket_sizes: sector_contents_map.s_bucket_sizes(), history_size: farmer_protocol_info.history_size, - expires_at: Default::default(), }; ( @@ -114,7 +119,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { let plotted_sector = block_on(plot_sector::<_, PosTable>( &public_key, - sector_offset, sector_index, &archived_history_segment, PieceGetterRetryPolicy::default(), @@ -124,7 +128,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { pieces_in_sector, &mut plotted_sector_bytes, &mut plotted_sector_metadata_bytes, - Default::default(), + &mut table_generator, )) .unwrap(); @@ -164,7 +168,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { let num_actual_solutions = solution_candidates .clone() - .into_iter::<_, PosTable>(&reward_address, &kzg, &erasure_coding) + .into_iter::<_, PosTable>(&reward_address, &kzg, &erasure_coding, &mut table_generator) .unwrap() .len(); @@ -194,6 +198,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { black_box(&reward_address), black_box(&kzg), black_box(&erasure_coding), + black_box(&mut table_generator), ) .unwrap() // Process just one solution @@ -260,6 +265,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { black_box(&reward_address), black_box(&kzg), black_box(&erasure_coding), + black_box(&mut table_generator), ) .unwrap() // Process just one solution diff --git a/crates/subspace-farmer-components/benches/reading.rs b/crates/subspace-farmer-components/benches/reading.rs index da38b1178e4..774f5bcf502 100644 --- a/crates/subspace-farmer-components/benches/reading.rs +++ b/crates/subspace-farmer-components/benches/reading.rs @@ -11,7 +11,7 @@ use subspace_archiving::archiver::Archiver; use subspace_core_primitives::crypto::kzg; use subspace_core_primitives::crypto::kzg::Kzg; use subspace_core_primitives::{ - HistorySize, PieceOffset, PublicKey, Record, RecordedHistorySegment, SectorId, SegmentIndex, + HistorySize, PieceOffset, PublicKey, Record, RecordedHistorySegment, SectorId, }; use subspace_erasure_coding::ErasureCoding; use subspace_farmer_components::file_ext::FileExt; @@ -20,6 +20,7 @@ use subspace_farmer_components::reading::read_piece; use subspace_farmer_components::sector::{sector_size, SectorContentsMap, SectorMetadata}; use subspace_farmer_components::FarmerProtocolInfo; use subspace_proof_of_space::chia::ChiaTable; +use subspace_proof_of_space::Table; type PosTable = ChiaTable; @@ -41,7 +42,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { .unwrap_or(10); let public_key = PublicKey::default(); - let sector_offset = 0; let sector_index = 0; let mut input = RecordedHistorySegment::new_boxed(); StdRng::seed_from_u64(42).fill(AsMut::<[u8]>::as_mut(input.as_mut())); @@ -51,10 +51,12 @@ pub fn criterion_benchmark(c: &mut Criterion) { NonZeroUsize::new(Record::NUM_S_BUCKETS.next_power_of_two().ilog2() as usize).unwrap(), ) .unwrap(); + let mut table_generator = PosTable::generator(); let archived_history_segment = archiver .add_block( AsRef::<[u8]>::as_ref(input.as_ref()).to_vec(), Default::default(), + true, ) .into_iter() .next() @@ -64,7 +66,12 @@ pub fn criterion_benchmark(c: &mut Criterion) { let farmer_protocol_info = FarmerProtocolInfo { history_size: HistorySize::from(NonZeroU64::new(1).unwrap()), max_pieces_in_sector: pieces_in_sector, - sector_expiration: SegmentIndex::ONE, + recent_segments: HistorySize::from(NonZeroU64::new(5).unwrap()), + recent_history_fraction: ( + HistorySize::from(NonZeroU64::new(1).unwrap()), + HistorySize::from(NonZeroU64::new(10).unwrap()), + ), + min_sector_lifetime: HistorySize::from(NonZeroU64::new(4).unwrap()), }; let sector_size = sector_size(pieces_in_sector); @@ -88,7 +95,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { pieces_in_sector, s_bucket_sizes: sector_contents_map.s_bucket_sizes(), history_size: farmer_protocol_info.history_size, - expires_at: Default::default(), }; ( @@ -108,7 +114,6 @@ pub fn criterion_benchmark(c: &mut Criterion) { let plotted_sector = block_on(plot_sector::<_, PosTable>( &public_key, - sector_offset, sector_index, &archived_history_segment, PieceGetterRetryPolicy::default(), @@ -118,7 +123,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { pieces_in_sector, &mut plotted_sector_bytes, &mut plotted_sector_metadata_bytes, - Default::default(), + &mut table_generator, )) .unwrap(); @@ -147,6 +152,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { black_box(&plotted_sector.sector_metadata), black_box(&plotted_sector_bytes), black_box(&erasure_coding), + black_box(&mut table_generator), ) .unwrap(); }) @@ -194,6 +200,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { black_box(&plotted_sector.sector_metadata), black_box(sector), black_box(&erasure_coding), + black_box(&mut table_generator), ) .unwrap(); } diff --git a/crates/subspace-farmer-components/src/auditing.rs b/crates/subspace-farmer-components/src/auditing.rs index d70199504c7..a1a3913bebb 100644 --- a/crates/subspace-farmer-components/src/auditing.rs +++ b/crates/subspace-farmer-components/src/auditing.rs @@ -3,7 +3,7 @@ use crate::sector::{SectorContentsMap, SectorMetadata}; use std::collections::VecDeque; use std::mem; use subspace_core_primitives::crypto::Scalar; -use subspace_core_primitives::{Blake2b256Hash, PublicKey, SectorId, SolutionRange}; +use subspace_core_primitives::{Blake2b256Hash, PublicKey, SectorId, SectorIndex, SolutionRange}; use subspace_verification::is_within_solution_range; #[derive(Debug, Clone)] @@ -19,7 +19,7 @@ pub(crate) struct ChunkCandidate { /// and seek back afterwards if necessary). pub fn audit_sector<'a>( public_key: &'a PublicKey, - sector_index: u64, + sector_index: SectorIndex, global_challenge: &Blake2b256Hash, solution_range: SolutionRange, sector: &'a [u8], diff --git a/crates/subspace-farmer-components/src/lib.rs b/crates/subspace-farmer-components/src/lib.rs index 2a5ca42e414..931190ceec6 100644 --- a/crates/subspace-farmer-components/src/lib.rs +++ b/crates/subspace-farmer-components/src/lib.rs @@ -16,7 +16,6 @@ pub mod auditing; pub mod file_ext; -pub mod piece_caching; pub mod plotting; pub mod proving; pub mod reading; @@ -25,7 +24,7 @@ mod segment_reconstruction; use serde::{Deserialize, Serialize}; use static_assertions::const_assert; -use subspace_core_primitives::{HistorySize, SegmentIndex}; +use subspace_core_primitives::HistorySize; // Refuse to compile on non-64-bit platforms, offsets may fail on those when converting from u64 to // usize depending on chain parameters @@ -39,6 +38,10 @@ pub struct FarmerProtocolInfo { pub history_size: HistorySize, /// How many pieces one sector is supposed to contain (max) pub max_pieces_in_sector: u16, - /// Number of segments after which sector expires - pub sector_expiration: SegmentIndex, + /// Number of latest archived segments that are considered "recent history". + pub recent_segments: HistorySize, + /// Fraction of pieces from the "recent history" (`recent_segments`) in each sector. + pub recent_history_fraction: (HistorySize, HistorySize), + /// Minimum lifetime of a plotted sector, measured in archived segment + pub min_sector_lifetime: HistorySize, } diff --git a/crates/subspace-farmer-components/src/piece_caching.rs b/crates/subspace-farmer-components/src/piece_caching.rs deleted file mode 100644 index e18284acc2d..00000000000 --- a/crates/subspace-farmer-components/src/piece_caching.rs +++ /dev/null @@ -1,51 +0,0 @@ -use lru::LruCache; -use parking_lot::Mutex; -use std::num::NonZeroUsize; -use std::sync::Arc; -use subspace_core_primitives::{Piece, PieceIndexHash}; -use tracing::trace; - -// TODO: Re-think this number -const CACHE_ITEMS_LIMIT: NonZeroUsize = - NonZeroUsize::new(100).expect("Archived history segment contains at very least one piece; qed"); - -#[derive(Clone)] -pub struct PieceMemoryCache { - cache: Arc>>, -} -impl Default for PieceMemoryCache { - #[inline] - fn default() -> Self { - Self::new(CACHE_ITEMS_LIMIT) - } -} - -impl PieceMemoryCache { - pub fn new(items_limit: NonZeroUsize) -> Self { - Self { - cache: Arc::new(Mutex::new(LruCache::new(items_limit))), - } - } - - pub fn add_piece(&self, piece_index_hash: PieceIndexHash, piece: Piece) { - self.cache.lock().put(piece_index_hash, piece); - } - - pub fn add_pieces(&self, pieces: Vec<(PieceIndexHash, Piece)>) { - let mut cache = self.cache.lock(); - - for (piece_index_hash, piece) in pieces { - cache.put(piece_index_hash, piece); - } - } - - pub fn get_piece(&self, piece_index_hash: &PieceIndexHash) -> Option { - let piece = self.cache.lock().get(piece_index_hash).cloned(); - - if piece.is_some() { - trace!(?piece_index_hash, "Piece memory cache hit."); - } - - piece - } -} diff --git a/crates/subspace-farmer-components/src/plotting.rs b/crates/subspace-farmer-components/src/plotting.rs index 6d9229b2208..5577b52837d 100644 --- a/crates/subspace-farmer-components/src/plotting.rs +++ b/crates/subspace-farmer-components/src/plotting.rs @@ -1,4 +1,3 @@ -use crate::piece_caching::PieceMemoryCache; use crate::sector::{ sector_record_chunks_size, sector_size, RawSector, RecordMetadata, SectorContentsMap, SectorMetadata, @@ -8,11 +7,10 @@ use crate::FarmerProtocolInfo; use async_trait::async_trait; use backoff::future::retry; use backoff::{Error as BackoffError, ExponentialBackoff}; -use futures::stream::FuturesOrdered; +use futures::stream::FuturesUnordered; use futures::StreamExt; use parity_scale_codec::Encode; use parking_lot::Mutex; -use rayon::prelude::*; use std::error::Error; use std::simd::Simd; use std::sync::Arc; @@ -24,9 +22,12 @@ use subspace_core_primitives::{ RecordWitness, SBucket, SectorId, SectorIndex, }; use subspace_erasure_coding::ErasureCoding; -use subspace_proof_of_space::{Quality, Table}; +use subspace_proof_of_space::{Quality, Table, TableGenerator}; use thiserror::Error; -use tracing::{debug, warn}; +use tokio::sync::Semaphore; +use tracing::{debug, trace, warn}; + +const RECONSTRUCTION_CONCURRENCY_LIMIT: usize = 1; fn default_backoff() -> ExponentialBackoff { ExponentialBackoff { @@ -158,8 +159,7 @@ pub enum PlottingError { #[allow(clippy::too_many_arguments)] pub async fn plot_sector( public_key: &PublicKey, - sector_offset: usize, - sector_index: u64, + sector_index: SectorIndex, piece_getter: &PG, piece_getter_retry_policy: PieceGetterRetryPolicy, farmer_protocol_info: &FarmerProtocolInfo, @@ -168,7 +168,7 @@ pub async fn plot_sector( pieces_in_sector: u16, sector_output: &mut [u8], sector_metadata_output: &mut [u8], - piece_memory_cache: PieceMemoryCache, + table_generator: &mut PosTable::Generator, ) -> Result where PG: PieceGetter, @@ -193,13 +193,17 @@ where } let sector_id = SectorId::new(public_key.hash(), sector_index); - let current_segment_index = farmer_protocol_info.history_size.segment_index(); - let expires_at = current_segment_index + farmer_protocol_info.sector_expiration; let piece_indexes: Vec = (PieceOffset::ZERO..) .take(pieces_in_sector.into()) .map(|piece_offset| { - sector_id.derive_piece_index(piece_offset, farmer_protocol_info.history_size) + sector_id.derive_piece_index( + piece_offset, + farmer_protocol_info.history_size, + farmer_protocol_info.max_pieces_in_sector, + farmer_protocol_info.recent_segments, + farmer_protocol_info.recent_history_fraction, + ) }) .collect(); @@ -208,36 +212,45 @@ where let raw_sector = Mutex::new(RawSector::new(pieces_in_sector)); - retry(default_backoff(), || async { - let mut raw_sector = raw_sector.lock(); - raw_sector.records.clear(); - raw_sector.metadata.clear(); - - if let Err(error) = download_sector( - &mut raw_sector, - sector_offset, - sector_index, - piece_getter, - piece_getter_retry_policy, - kzg, - &piece_indexes, - piece_memory_cache.clone(), - ) - .await - { - warn!( - %sector_offset, - %sector_index, - %error, - "Sector plotting attempt failed, will retry later" - ); + { + // This list will be mutated, replacing pieces we have already processed with `None` + let incremental_piece_indices = + Mutex::new(piece_indexes.iter().copied().map(Some).collect::>()); + + retry(default_backoff(), || async { + let mut raw_sector = raw_sector.lock(); + let mut incremental_piece_indices = incremental_piece_indices.lock(); + + if let Err(error) = download_sector( + &mut raw_sector, + piece_getter, + piece_getter_retry_policy, + kzg, + &mut incremental_piece_indices, + ) + .await + { + let retrieved_pieces = incremental_piece_indices + .iter() + .filter(|maybe_piece_index| maybe_piece_index.is_some()) + .count(); + warn!( + %sector_index, + %error, + %pieces_in_sector, + %retrieved_pieces, + "Sector plotting attempt failed, will retry later" + ); + + return Err(BackoffError::transient(error)); + } - return Err(BackoffError::transient(error)); - } + debug!(%sector_index, "Sector downloaded successfully"); - Ok(()) - }) - .await?; + Ok(()) + }) + .await?; + } let mut raw_sector = raw_sector.into_inner(); @@ -246,12 +259,14 @@ where (PieceOffset::ZERO..) .zip(raw_sector.records.iter_mut()) .zip(sector_contents_map.iter_record_bitfields_mut()) - // TODO: Doesn't work without a bridge: https://github.com/ferrilab/bitvec/issues/143 - .par_bridge() + // TODO: Ideally, we'd use parallelism here, but using `.par_bridge()` causes Chia table + // derivation to only use a single thread, which slows everything to essentially + // single-threaded .for_each(|((piece_offset, record), mut encoded_chunks_used)| { - // Derive PoSpace table - let pos_table = PosTable::generate( - §or_id.evaluation_seed(piece_offset, farmer_protocol_info.history_size), + // Derive PoSpace table (use parallel mode because multiple tables concurrently will use + // too much RAM) + let pos_table = table_generator.generate_parallel( + §or_id.derive_evaluation_seed(piece_offset, farmer_protocol_info.history_size), ); let source_record_chunks = record @@ -259,7 +274,7 @@ where .map(|scalar_bytes| { Scalar::try_from(scalar_bytes).expect( "Piece getter must returns valid pieces of history that contain \ - proper scalar bytes; qed", + proper scalar bytes; qed", ) }) .collect::>(); @@ -283,8 +298,10 @@ where *encoded_chunk_used = true; - // NOTE: Quality is already hashed in the `subspace-chiapos` library - Some(Simd::from(record_chunk.to_bytes()) ^ Simd::from(*quality.to_bytes())) + Some( + Simd::from(record_chunk.to_bytes()) + ^ Simd::from(quality.create_proof().hash()), + ) }) // Make sure above filter function (and corresponding `encoded_chunk_used` update) // happen at most as many times as there is number of chunks in the record, @@ -378,7 +395,6 @@ where pieces_in_sector, s_bucket_sizes: sector_contents_map.s_bucket_sizes(), history_size: farmer_protocol_info.history_size, - expires_at, }; sector_metadata_output.copy_from_slice(§or_metadata.encode()); @@ -391,27 +407,27 @@ where }) } -#[allow(clippy::too_many_arguments)] async fn download_sector( raw_sector: &mut RawSector, - sector_offset: usize, - sector_index: u64, piece_getter: &PG, piece_getter_retry_policy: PieceGetterRetryPolicy, kzg: &Kzg, - piece_indexes: &[PieceIndex], - piece_memory_cache: PieceMemoryCache, + piece_indexes: &mut [Option], ) -> Result<(), PlottingError> { - let mut pieces_receiving_futures = piece_indexes - .iter() - .map(|piece_index| async { - let piece_index = *piece_index; + // TODO: Make configurable, likely allowing user to specify RAM usage expectations and inferring + // concurrency from there + let recovery_semaphore = Semaphore::new(RECONSTRUCTION_CONCURRENCY_LIMIT); - if let Some(piece) = piece_memory_cache.get_piece(&piece_index.hash()) { - return (piece_index, Ok(Some(piece))); - } - - let piece_result = piece_getter + let mut pieces_receiving_futures = piece_indexes + .iter_mut() + .zip(raw_sector.records.iter_mut().zip(&mut raw_sector.metadata)) + .map(|(maybe_piece_index, (record, metadata))| async { + // We skip pieces that we have already processed previously + let Some(piece_index) = *maybe_piece_index else { + return Ok(()); + }; + + let mut piece_result = piece_getter .get_piece(piece_index, piece_getter_retry_policy) .await; @@ -420,38 +436,53 @@ async fn download_sector( .map(|piece| piece.is_some()) .unwrap_or_default(); - // all retries failed + // All retries failed if !succeeded { + let _permit = match recovery_semaphore.acquire().await { + Ok(permit) => permit, + Err(error) => { + let error = format!("Recovery semaphore was closed: {error}").into(); + return Err(PlottingError::FailedToRetrievePiece { piece_index, error }); + } + }; let recovered_piece = recover_missing_piece(piece_getter, kzg.clone(), piece_index).await; - return (piece_index, recovered_piece.map(Some).map_err(Into::into)); + piece_result = recovered_piece.map(Some).map_err(Into::into); } - (piece_index, piece_result) + let piece = piece_result + .map_err(|error| PlottingError::FailedToRetrievePiece { piece_index, error })? + .ok_or(PlottingError::PieceNotFound { piece_index })?; + + // Fancy way to insert value in order to avoid going through stack (if naive de-referencing + // is used) and potentially causing stack overflow as the result + record + .flatten_mut() + .copy_from_slice(piece.record().flatten()); + *metadata = RecordMetadata { + commitment: *piece.commitment(), + witness: *piece.witness(), + }; + + // We have processed this piece index, clear it + maybe_piece_index.take(); + + Ok(()) }) - .collect::>(); - - while let Some((piece_index, piece_result)) = pieces_receiving_futures.next().await { - let piece = piece_result - .map_err(|error| PlottingError::FailedToRetrievePiece { piece_index, error })? - .ok_or(PlottingError::PieceNotFound { piece_index })?; - - let (record, commitment, witness) = piece.split(); - // Fancy way to insert value in order to avoid going through stack (if naive de-referencing - // is used) and potentially causing stack overflow as the result - raw_sector - .records - .extend_from_slice(std::slice::from_ref(record)); - raw_sector.metadata.push(RecordMetadata { - commitment: *commitment, - witness: *witness, - }); + .collect::>(); - piece_memory_cache.add_piece(piece_index.hash(), piece); - } + let mut final_result = Ok(()); + + while let Some(result) = pieces_receiving_futures.next().await { + if let Err(error) = result { + trace!(%error, "Failed to download piece"); - debug!(%sector_offset, %sector_index, "Sector downloaded successfully"); + if final_result.is_ok() { + final_result = Err(error); + } + } + } - Ok(()) + final_result } diff --git a/crates/subspace-farmer-components/src/proving.rs b/crates/subspace-farmer-components/src/proving.rs index db782f04fd7..a7f60e22688 100644 --- a/crates/subspace-farmer-components/src/proving.rs +++ b/crates/subspace-farmer-components/src/proving.rs @@ -2,14 +2,13 @@ use crate::auditing::ChunkCandidate; use crate::reading::{read_record_metadata, read_sector_record_chunks, ReadingError}; use crate::sector::{SectorContentsMap, SectorContentsMapFromBytesError, SectorMetadata}; use std::collections::VecDeque; -use std::marker::PhantomData; use subspace_core_primitives::crypto::kzg::{Commitment, Kzg, Witness}; use subspace_core_primitives::crypto::Scalar; use subspace_core_primitives::{ PieceOffset, PosProof, PublicKey, Record, SBucket, SectorId, SectorIndex, Solution, }; use subspace_erasure_coding::ErasureCoding; -use subspace_proof_of_space::{Quality, Table}; +use subspace_proof_of_space::{Quality, Table, TableGenerator}; use thiserror::Error; /// Errors that happen during proving @@ -116,6 +115,7 @@ impl<'a> SolutionCandidates<'a> { reward_address: &'a RewardAddress, kzg: &'a Kzg, erasure_coding: &'a ErasureCoding, + table_generator: &'a mut PosTable::Generator, ) -> Result< impl ExactSizeIterator, ProvingError>> + 'a, ProvingError, @@ -135,6 +135,7 @@ impl<'a> SolutionCandidates<'a> { kzg, erasure_coding, self.chunk_candidates, + table_generator, ) } } @@ -148,7 +149,10 @@ struct ChunkCache { proof_of_space: PosProof, } -struct SolutionCandidatesIterator<'a, RewardAddress, PosTable> { +struct SolutionCandidatesIterator<'a, RewardAddress, PosTable> +where + PosTable: Table, +{ public_key: &'a PublicKey, reward_address: &'a RewardAddress, sector_index: SectorIndex, @@ -163,7 +167,7 @@ struct SolutionCandidatesIterator<'a, RewardAddress, PosTable> { winning_chunks: VecDeque, count: usize, chunk_cache: Option, - _pos_table: PhantomData, + table_generator: &'a mut PosTable::Generator, } // TODO: This can be potentially parallelized with rayon @@ -200,10 +204,10 @@ where } // Derive PoSpace table - let pos_table = PosTable::generate_parallel( + let pos_table = self.table_generator.generate_parallel( &self .sector_id - .evaluation_seed(piece_offset, self.sector_metadata.history_size), + .derive_evaluation_seed(piece_offset, self.sector_metadata.history_size), ); let maybe_chunk_cache: Result<_, ProvingError> = try { @@ -351,6 +355,7 @@ where kzg: &'a Kzg, erasure_coding: &'a ErasureCoding, chunk_candidates: VecDeque, + table_generator: &'a mut PosTable::Generator, ) -> Result { if erasure_coding.max_shards() < Record::NUM_S_BUCKETS { return Err(ProvingError::InvalidErasureCodingInstance); @@ -411,7 +416,7 @@ where winning_chunks, count, chunk_cache: None, - _pos_table: PhantomData, + table_generator, }) } } diff --git a/crates/subspace-farmer-components/src/reading.rs b/crates/subspace-farmer-components/src/reading.rs index 90437231084..67711117819 100644 --- a/crates/subspace-farmer-components/src/reading.rs +++ b/crates/subspace-farmer-components/src/reading.rs @@ -10,7 +10,7 @@ use subspace_core_primitives::{ Piece, PieceOffset, Record, RecordCommitment, RecordWitness, SBucket, SectorId, }; use subspace_erasure_coding::ErasureCoding; -use subspace_proof_of_space::{Quality, Table}; +use subspace_proof_of_space::{Quality, Table, TableGenerator}; use thiserror::Error; /// Errors that happen during reading @@ -133,9 +133,9 @@ where .find_quality(s_bucket.into()) .expect("encoded_chunk_used implies quality exists for this chunk; qed"); - // NOTE: Quality is already hashed in the `subspace-chiapos` library - record_chunk = - Simd::to_array(Simd::from(record_chunk) ^ Simd::from(*quality.to_bytes())); + record_chunk = Simd::to_array( + Simd::from(record_chunk) ^ Simd::from(quality.create_proof().hash()), + ); } maybe_record_chunk.replace(Scalar::try_from(record_chunk).map_err(|error| { @@ -257,6 +257,7 @@ pub fn read_piece( sector_metadata: &SectorMetadata, sector: &[u8], erasure_coding: &ErasureCoding, + table_generator: &mut PosTable::Generator, ) -> Result where PosTable: Table, @@ -284,8 +285,8 @@ where pieces_in_sector, §or_metadata.s_bucket_offsets(), §or_contents_map, - &PosTable::generate( - §or_id.evaluation_seed(piece_offset, sector_metadata.history_size), + &table_generator.generate( + §or_id.derive_evaluation_seed(piece_offset, sector_metadata.history_size), ), sector, )?, diff --git a/crates/subspace-farmer-components/src/sector.rs b/crates/subspace-farmer-components/src/sector.rs index af152ff3e81..34152225b4a 100644 --- a/crates/subspace-farmer-components/src/sector.rs +++ b/crates/subspace-farmer-components/src/sector.rs @@ -6,7 +6,6 @@ use std::ops::{Deref, DerefMut}; use std::{mem, slice}; use subspace_core_primitives::{ HistorySize, PieceOffset, Record, RecordCommitment, RecordWitness, SBucket, SectorIndex, - SegmentIndex, }; use thiserror::Error; @@ -48,8 +47,6 @@ pub struct SectorMetadata { pub s_bucket_sizes: Box<[u16; Record::NUM_S_BUCKETS]>, /// Size of the blockchain history at time of sector creation pub history_size: HistorySize, - /// Sector expiration, defined as sector of the archived history of the blockchain - pub expires_at: SegmentIndex, } impl SectorMetadata { @@ -87,7 +84,6 @@ impl SectorMetadata { // SAFETY: Data structure filled with zeroes is a valid invariant s_bucket_sizes: unsafe { Box::new_zeroed().assume_init() }, history_size: HistorySize::from(NonZeroU64::new(1).expect("1 is not 0; qed")), - expires_at: SegmentIndex::default(), }; default.encoded_size() @@ -95,7 +91,7 @@ impl SectorMetadata { } /// Commitment and witness corresponding to the same record -#[derive(Debug, Clone, Encode, Decode)] +#[derive(Debug, Default, Clone, Encode, Decode)] pub struct RecordMetadata { /// Record commitment pub commitment: RecordCommitment, @@ -113,12 +109,11 @@ pub struct RawSector { } impl RawSector { - /// Create new raw sector with internal vectors being allocated (but not filled) to be able to - /// store data for specified number of pieces in sector + /// Create new raw sector with internal vectors being allocated and filled with default values pub fn new(pieces_in_sector: u16) -> Self { Self { - records: Vec::with_capacity(usize::from(pieces_in_sector)), - metadata: Vec::with_capacity(usize::from(pieces_in_sector)), + records: Record::new_zero_vec(usize::from(pieces_in_sector)), + metadata: vec![RecordMetadata::default(); usize::from(pieces_in_sector)], } } } diff --git a/crates/subspace-farmer-components/src/segment_reconstruction.rs b/crates/subspace-farmer-components/src/segment_reconstruction.rs index 37a2fb54f54..11b525554fe 100644 --- a/crates/subspace-farmer-components/src/segment_reconstruction.rs +++ b/crates/subspace-farmer-components/src/segment_reconstruction.rs @@ -9,6 +9,7 @@ use thiserror::Error; use tokio::sync::Semaphore; use tracing::{debug, error, info, trace, warn}; +// TODO: Probably should be made configurable const PARALLELISM_LEVEL: usize = 20; #[derive(Debug, Error)] @@ -80,6 +81,7 @@ pub(crate) async fn recover_missing_piece( } } }) + .into_iter() .collect::>(); let mut segment_pieces = vec![None::; ArchivedHistorySegment::NUM_PIECES]; @@ -92,8 +94,14 @@ pub(crate) async fn recover_missing_piece( } } - if acquired_pieces_counter.load(Ordering::SeqCst) < required_pieces_number { - error!(%missing_piece_index, "Recovering missing piece failed."); + let received_pieces = acquired_pieces_counter.load(Ordering::SeqCst); + if received_pieces < required_pieces_number { + error!( + %missing_piece_index, + %received_pieces, + %required_pieces_number, + "Recovering missing piece failed." + ); return Err(SegmentReconstructionError::NotEnoughPiecesAcquired); } diff --git a/crates/subspace-farmer/Cargo.toml b/crates/subspace-farmer/Cargo.toml index a5af5f5a352..25652a130f1 100644 --- a/crates/subspace-farmer/Cargo.toml +++ b/crates/subspace-farmer/Cargo.toml @@ -14,25 +14,26 @@ include = [ [dependencies] anyhow = "1.0.71" async-trait = "0.1.68" +atomic = "0.5.3" backoff = { version = "0.4.0", features = ["futures", "tokio"] } base58 = "0.2.0" blake2 = "0.10.6" bytesize = "1.2.0" clap = { version = "4.2.1", features = ["color", "derive"] } +cuckoofilter = { version = "0.5.0", features = ["serde_support"] } derive_more = "0.99.17" -dirs = "5.0.1" event-listener-primitives = "2.0.1" fdlimit = "0.2" futures = "0.3.28" hex = { version = "0.4.3", features = ["serde"] } -jsonrpsee = { version = "0.16.2", features = ["client", "macros", "server"] } +jsonrpsee = { version = "0.16.2", features = ["client"] } lru = "0.10.0" -memmap2 = "0.7.0" -num-traits = "0.2.15" +memmap2 = "0.7.1" parity-db = "0.4.6" -parity-scale-codec = "3.4.0" +parity-scale-codec = "3.6.3" parking_lot = "0.12.1" rand = "0.8.5" +rayon = "1.7.0" schnorrkel = "0.9.1" serde = { version = "1.0.159", features = ["derive"] } serde_json = "1.0.95" @@ -59,6 +60,3 @@ zeroize = "1.6.0" # The only triple tested and confirmed as working in `jemallocator` crate is `x86_64-unknown-linux-gnu` [target.'cfg(all(target_arch = "x86_64", target_vendor = "unknown", target_os = "linux", target_env = "gnu"))'.dependencies] jemallocator = "0.5.0" - -[dev-dependencies] -rayon = "1.7.0" diff --git a/crates/subspace-farmer/README.md b/crates/subspace-farmer/README.md index bcedf3097e2..312c1994955 100644 --- a/crates/subspace-farmer/README.md +++ b/crates/subspace-farmer/README.md @@ -32,9 +32,9 @@ It is recommended to follow general farming instructions that explain how to run Rust toolchain is expected to be installed for anything in this repository to compile, but there are some extra dependencies for farmer specifically. -RocksDB on Linux needs LLVM/Clang: +Prost library from libp2p dependency needs CMake, also LLVM/Clang is necessary: ```bash -sudo apt-get install llvm clang +sudo apt-get install llvm clang cmake ``` Then build the farmer using Cargo: @@ -53,32 +53,18 @@ target/production/subspace-farmer --help ### Start the farmer ``` -target/production/subspace-farmer farm --reward-address st... --plot-size 100G +target/production/subspace-farmer --farm path=/path/to/disk,size=100G farm --reward-address st... ``` -`st...` should be replaced with the reward address taken from Polkadot.js wallet (or similar) and `100G` replaced with desired plot size. +`st...` should be replaced with the reward address taken from Polkadot.js wallet (or similar), `/path/to/disk` with location where you want to store plot and `100G` replaced with desired plot size. This will connect to local node and will try to solve on every slot notification, while also plotting all existing and new history of the blockchain in parallel. *NOTE: You need to have a `subspace-node` running before starting farmer, otherwise it will not be able to start* -By default, farmer data are written to `subspace-farmer` subdirectory of the OS-specific users local data directory. - -``` -Linux -$XDG_DATA_HOME or /home/alice/.local/share -$HOME/.local/share - -macOS -$HOME/Library/Application Support /Users/Alice/Library/Application Support - -Windows -{FOLDERID_LocalAppData} C:\Users\Alice\AppData\Local -``` - -### Wipe the plot +### Wipe the plot (same that was created previously) ``` -target/production/subspace-farmer wipe +target/production/subspace-farmer --farm path=/path/to/disk,size=100G wipe ``` This would wipe plots in the OS-specific users local data directory. diff --git a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm.rs b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm.rs index 9ec873d53b2..f1c7a7c9b15 100644 --- a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm.rs +++ b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm.rs @@ -4,53 +4,39 @@ use crate::commands::farm::dsn::configure_dsn; use crate::commands::shared::print_disk_farm_info; use crate::utils::{get_required_plot_space_with_overhead, shutdown_signal}; use crate::{DiskFarm, FarmingArgs}; -use anyhow::{anyhow, Context, Result}; -use futures::future::{select, Either}; +use anyhow::{anyhow, Result}; use futures::stream::FuturesUnordered; use futures::{FutureExt, StreamExt}; use lru::LruCache; use parking_lot::Mutex; -use std::collections::HashMap; use std::num::NonZeroUsize; -use std::path::PathBuf; use std::sync::Arc; -use std::time::Duration; use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; -use subspace_core_primitives::{ - ArchivedHistorySegment, PieceIndex, PieceIndexHash, PieceOffset, Record, SegmentIndex, -}; +use subspace_core_primitives::{Piece, Record, SectorIndex}; use subspace_erasure_coding::ErasureCoding; +use subspace_farmer::piece_cache::PieceCache; use subspace_farmer::single_disk_plot::{ SingleDiskPlot, SingleDiskPlotError, SingleDiskPlotOptions, }; -use subspace_farmer::utils::farmer_piece_cache::FarmerPieceCache; +use subspace_farmer::utils::archival_storage_info::ArchivalStorageInfo; +use subspace_farmer::utils::archival_storage_pieces::ArchivalStoragePieces; use subspace_farmer::utils::farmer_piece_getter::FarmerPieceGetter; -use subspace_farmer::utils::node_piece_getter::NodePieceGetter; -use subspace_farmer::utils::piece_cache::PieceCache; use subspace_farmer::utils::piece_validator::SegmentCommitmentPieceValidator; -use subspace_farmer::utils::readers_and_pieces::{PieceDetails, ReadersAndPieces}; +use subspace_farmer::utils::readers_and_pieces::ReadersAndPieces; use subspace_farmer::utils::run_future_in_dedicated_thread; use subspace_farmer::{Identity, NodeClient, NodeRpcClient}; -use subspace_farmer_components::piece_caching::PieceMemoryCache; -use subspace_farmer_components::plotting::{PieceGetter, PieceGetterRetryPolicy}; +use subspace_farmer_components::plotting::PlottedSector; use subspace_networking::libp2p::identity::{ed25519, Keypair}; -use subspace_networking::utils::multihash::ToMultihash; -use subspace_networking::utils::piece_announcement::announce_single_piece_index_hash_with_backoff; use subspace_networking::utils::piece_provider::PieceProvider; use subspace_proof_of_space::Table; -use tokio::sync::broadcast; -use tokio::time::sleep; -use tracing::{debug, error, info, info_span, trace, warn, Instrument}; +use tracing::{debug, error, info, info_span, warn}; use zeroize::Zeroizing; const RECORDS_ROOTS_CACHE_SIZE: NonZeroUsize = NonZeroUsize::new(1_000_000).expect("Not zero; qed"); -const GET_PIECE_MAX_RETRIES_COUNT: u16 = 3; -const GET_PIECE_DELAY_IN_SECS: u64 = 3; /// Start farming by using multiple replica plot in specified path and connecting to WebSocket /// server at specified address. pub(crate) async fn farm_multi_disk( - base_path: PathBuf, disk_farms: Vec, farming_args: FarmingArgs, ) -> Result<(), anyhow::Error> @@ -68,12 +54,12 @@ where let FarmingArgs { node_rpc_url, reward_address, - plot_size: _, max_pieces_in_sector, disk_concurrency, disable_farming, mut dsn, max_concurrent_plots, + cache_percentage, no_info: _, } = farming_args; @@ -82,45 +68,50 @@ where info!(url = %node_rpc_url, "Connecting to node RPC"); let node_client = NodeRpcClient::new(&node_rpc_url).await?; - let concurrent_plotting_semaphore = Arc::new(tokio::sync::Semaphore::new( - farming_args.max_concurrent_plots.get(), - )); - - let piece_memory_cache = PieceMemoryCache::default(); - let farmer_app_info = node_client .farmer_app_info() .await .map_err(|error| anyhow::anyhow!(error))?; - let (node, mut node_runner, piece_cache) = { - // TODO: Temporary networking identity derivation from the first disk farm identity. - let directory = disk_farms - .first() - .expect("Disk farm collection should not be empty at this point.") - .directory - .clone(); - // TODO: Update `Identity` to use more specific error type and remove this `.unwrap()` - let identity = Identity::open_or_create(&directory).unwrap(); - let keypair = derive_libp2p_keypair(identity.secret_key()); - + let cuckoo_filter_capacity = disk_farms + .iter() + .map(|df| df.allocated_plotting_space as usize) + .sum::() + / Piece::SIZE + + 1usize; + let archival_storage_pieces = ArchivalStoragePieces::new(cuckoo_filter_capacity); + let archival_storage_info = ArchivalStorageInfo::default(); + + let first_farm_directory = disk_farms + .first() + .expect("Disk farm collection is not be empty as checked above; qed") + .directory + .clone(); + // TODO: Update `Identity` to use more specific error type and remove this `.unwrap()` + let identity = Identity::open_or_create(&first_farm_directory).unwrap(); + let keypair = derive_libp2p_keypair(identity.secret_key()); + let peer_id = keypair.public().to_peer_id(); + + let (piece_cache, piece_cache_worker) = PieceCache::new(node_client.clone(), peer_id); + + let (node, mut node_runner) = { if dsn.bootstrap_nodes.is_empty() { dsn.bootstrap_nodes = farmer_app_info.dsn_bootstrap_nodes.clone(); } configure_dsn( hex::encode(farmer_app_info.genesis_hash), - base_path, + first_farm_directory, keypair, dsn, - &readers_and_pieces, + Arc::downgrade(&readers_and_pieces), node_client.clone(), - piece_memory_cache.clone(), + archival_storage_pieces.clone(), + archival_storage_info.clone(), + piece_cache.clone(), )? }; - let piece_cache = Arc::new(tokio::sync::Mutex::new(piece_cache)); - let kzg = Kzg::new(embedded_kzg_settings()); let erasure_coding = ErasureCoding::new( NonZeroUsize::new(Record::NUM_S_BUCKETS.next_power_of_two().ilog2() as usize).unwrap(), @@ -138,32 +129,19 @@ where segment_commitments_cache, )), ); + let piece_getter = Arc::new(FarmerPieceGetter::new( - NodePieceGetter::new(piece_provider), + node.clone(), + piece_provider, piece_cache.clone(), + archival_storage_info, + Arc::clone(&readers_and_pieces), )); - let last_segment_index = farmer_app_info.protocol_info.history_size.segment_index(); - - let _piece_cache_population = run_future_in_dedicated_thread( - Box::pin({ - let piece_cache = piece_cache.clone(); - let piece_getter = piece_getter.clone(); - - populate_pieces_cache(last_segment_index, piece_getter, piece_cache) - }), - "pieces-cache-population".to_string(), - )?; - - let _piece_cache_maintainer = run_future_in_dedicated_thread( - Box::pin({ - let piece_cache = piece_cache.clone(); - let node_client = node_client.clone(); - - fill_piece_cache_from_archived_segments(node_client, piece_cache) - }), - "pieces-cache-maintainer".to_string(), - )?; + let _piece_cache_worker = run_future_in_dedicated_thread( + Box::pin(piece_cache_worker.run(piece_getter.clone())), + "cache-worker".to_string(), + ); let mut single_disk_plots = Vec::with_capacity(disk_farms.len()); let max_pieces_in_sector = match max_pieces_in_sector { @@ -201,8 +179,7 @@ where kzg: kzg.clone(), erasure_coding: erasure_coding.clone(), piece_getter: piece_getter.clone(), - concurrent_plotting_semaphore: Arc::clone(&concurrent_plotting_semaphore), - piece_memory_cache: piece_memory_cache.clone(), + cache_percentage, }, disk_farm_index, ); @@ -235,6 +212,16 @@ where single_disk_plots.push(single_disk_plot); } + piece_cache + .replace_backing_caches( + single_disk_plots + .iter() + .map(|single_disk_plot| single_disk_plot.piece_cache()) + .collect(), + ) + .await; + drop(piece_cache); + // Store piece readers so we can reference them later let piece_readers = single_disk_plots .iter() @@ -244,153 +231,80 @@ where info!("Collecting already plotted pieces (this will take some time)..."); // Collect already plotted pieces - let plotted_pieces: HashMap = single_disk_plots - .iter() - .enumerate() - .flat_map(|(disk_farm_index, single_disk_plot)| { - single_disk_plot - .plotted_sectors() - .enumerate() - .filter_map(move |(sector_offset, plotted_sector_result)| { - match plotted_sector_result { - Ok(plotted_sector) => Some(plotted_sector), - Err(error) => { - error!( - %error, - %disk_farm_index, - %sector_offset, - "Failed reading plotted sector on startup, skipping" - ); - None - } - } - }) - .flat_map(move |plotted_sector| { - (PieceOffset::ZERO..).zip(plotted_sector.piece_indexes).map( - move |(piece_offset, piece_index)| { - ( - piece_index.hash(), - PieceDetails { - disk_farm_index, - sector_index: plotted_sector.sector_index, - piece_offset, - }, - ) - }, + { + let mut readers_and_pieces = readers_and_pieces.lock(); + let readers_and_pieces = readers_and_pieces.insert(ReadersAndPieces::new( + piece_readers, + archival_storage_pieces, + )); + + single_disk_plots.iter().enumerate().try_for_each( + |(disk_farm_index, single_disk_plot)| { + let disk_farm_index = disk_farm_index.try_into().map_err(|_error| { + anyhow!( + "More than 256 plots are not supported, consider running multiple farmer \ + instances" ) - }) - }) - // We implicitly ignore duplicates here, reading just from one of the plots - .collect(); + })?; + + (0 as SectorIndex..) + .zip(single_disk_plot.plotted_sectors()) + .for_each( + |(sector_index, plotted_sector_result)| match plotted_sector_result { + Ok(plotted_sector) => { + readers_and_pieces.add_sector(disk_farm_index, &plotted_sector); + } + Err(error) => { + error!( + %error, + %disk_farm_index, + %sector_index, + "Failed reading plotted sector on startup, skipping" + ); + } + }, + ); - info!("Finished collecting already plotted pieces successfully"); + Ok::<_, anyhow::Error>(()) + }, + )?; + } - readers_and_pieces - .lock() - .replace(ReadersAndPieces::new(piece_readers, plotted_pieces)); + info!("Finished collecting already plotted pieces successfully"); let mut single_disk_plots_stream = single_disk_plots .into_iter() .enumerate() .map(|(disk_farm_index, single_disk_plot)| { + let disk_farm_index = disk_farm_index.try_into().expect( + "More than 256 plots are not supported, this is checked above already; qed", + ); let readers_and_pieces = Arc::clone(&readers_and_pieces); - let node = node.clone(); let span = info_span!("farm", %disk_farm_index); - // We are not going to send anything here, but dropping of sender on dropping of - // corresponding `SingleDiskPlot` will allow us to stop background tasks. - let (dropped_sender, _dropped_receiver) = broadcast::channel::<()>(1); - // Collect newly plotted pieces - // TODO: Once we have replotting, this will have to be updated - single_disk_plot - .on_sector_plotted(Arc::new( - move |(sector_offset, plotted_sector, plotting_permit)| { - let _span_guard = span.enter(); - let plotting_permit = Arc::clone(plotting_permit); - let node = node.clone(); - let sector_offset = *sector_offset; - let sector_index = plotted_sector.sector_index; - - let mut dropped_receiver = dropped_sender.subscribe(); - - let new_pieces = { - let mut readers_and_pieces = readers_and_pieces.lock(); - let readers_and_pieces = readers_and_pieces - .as_mut() - .expect("Initial value was populated above; qed"); - - let new_pieces = plotted_sector - .piece_indexes - .iter() - .filter(|&&piece_index| { - // Skip pieces that are already plotted and thus were announced - // before - !readers_and_pieces.contains_piece(&piece_index.hash()) - }) - .copied() - .collect::>(); - - readers_and_pieces.add_pieces( - (PieceOffset::ZERO..) - .zip(plotted_sector.piece_indexes.iter().copied()) - .map(|(piece_offset, piece_index)| { - ( - piece_index.hash(), - PieceDetails { - disk_farm_index, - sector_index, - piece_offset, - }, - ) - }), - ); - - new_pieces - }; - - if new_pieces.is_empty() { - // None of the pieces are new, nothing left to do here - return; - } - - // TODO: Skip those that were already announced (because they cached) - let publish_fut = async move { - let mut pieces_publishing_futures = new_pieces - .into_iter() - .map(|piece_index| { - announce_single_piece_index_hash_with_backoff( - piece_index.hash(), - &node, - ) - }) - .collect::>(); - - while pieces_publishing_futures.next().await.is_some() { - // Nothing is needed here, just driving all futures to completion - } + let on_plotted_sector_callback = + move |(plotted_sector, maybe_old_plotted_sector): &( + PlottedSector, + Option, + )| { + let _span_guard = span.enter(); - info!( - %sector_offset, - ?sector_index, - "Sector publishing was successful." - ); + { + let mut readers_and_pieces = readers_and_pieces.lock(); + let readers_and_pieces = readers_and_pieces + .as_mut() + .expect("Initial value was populated above; qed"); - // Release only after publishing is finished - drop(plotting_permit); + if let Some(old_plotted_sector) = maybe_old_plotted_sector { + readers_and_pieces.delete_sector(disk_farm_index, old_plotted_sector); } - .in_current_span(); - - tokio::spawn(async move { - let result = - select(Box::pin(publish_fut), Box::pin(dropped_receiver.recv())) - .await; - if matches!(result, Either::Right(_)) { - debug!("Piece publishing was cancelled due to shutdown."); - } - }); - }, - )) + readers_and_pieces.add_sector(disk_farm_index, plotted_sector); + } + }; + + single_disk_plot + .on_sector_plotted(Arc::new(on_plotted_sector_callback)) .detach(); single_disk_plot.run() @@ -448,151 +362,3 @@ fn derive_libp2p_keypair(schnorrkel_sk: &schnorrkel::SecretKey) -> Keypair { Keypair::from(keypair) } - -/// Populates piece cache on startup. It waits for the new segment index and check all pieces from -/// previous segments to see if they are already in the cache. If they are not, they are added -/// from DSN. -async fn populate_pieces_cache( - segment_index: SegmentIndex, - piece_getter: Arc>, - piece_cache: Arc>, -) where - PG: PieceGetter + Send + Sync, - PC: PieceCache + Send + 'static, -{ - debug!(%segment_index, "Started syncing piece cache..."); - let final_piece_index = - u64::from(segment_index.first_piece_index()) + ArchivedHistorySegment::NUM_PIECES as u64; - - // TODO: consider optimizing starting point of this loop - let mut piece_index = 0; - 'outer: while piece_index < final_piece_index { - // Scroll to the next piece index to cache. - { - let piece_cache = piece_cache.lock().await; - while !piece_cache - .should_cache(&PieceIndex::from(piece_index).hash().to_multihash().into()) - { - piece_index += 1; - - if piece_index >= final_piece_index { - break 'outer; - } - } - } - - let key = PieceIndex::from(piece_index).hash().to_multihash().into(); - - let result = piece_getter - .get_piece(piece_index.into(), PieceGetterRetryPolicy::Limited(1)) - .await; - - match result { - Ok(Some(piece)) => { - debug!(%piece_index, "Added piece to cache."); - piece_cache.lock().await.add_piece(key, piece); - } - Ok(None) => { - debug!(%piece_index, "Couldn't find piece."); - } - Err(err) => { - debug!(error=%err, %piece_index, "Failed to get piece for piece cache."); - } - } - - piece_index += 1; - } - - debug!("Finished syncing piece cache."); -} - -/// Subscribes to a new segment index and adds pieces from the segment to the cache if required. -async fn fill_piece_cache_from_archived_segments( - node_client: NodeRpcClient, - piece_cache: Arc>, -) { - let segment_headers_notifications = node_client - .subscribe_archived_segment_headers() - .await - .map_err(|err| anyhow::anyhow!(err.to_string())) - .context("Failed to subscribe to archived segments"); - - match segment_headers_notifications { - Ok(mut segment_headers_notifications) => { - while let Some(segment_header) = segment_headers_notifications.next().await { - let segment_index = segment_header.segment_index(); - - debug!(%segment_index, "Starting to process archived segment...."); - - for piece_index in segment_index.segment_piece_indexes() { - let key = piece_index.hash().to_multihash().into(); - { - if !piece_cache.lock().await.should_cache(&key) { - trace!(%piece_index, ?key, "Piece key will not be included in the cache."); - - continue; - } - } - - trace!(%piece_index, ?key, "Piece key will be included in the cache."); - - // Segment notification will come earlier than node's local cache finishes its - // initialization, so we need to wait for it. - let mut retries_count = 0u16; - 'retry: loop { - if retries_count >= GET_PIECE_MAX_RETRIES_COUNT { - debug!(%piece_index, "Max retries number exceeded."); - - break 'retry; - } - - retries_count += 1; - - let piece = node_client.piece(piece_index).await; - - match piece { - Ok(Some(piece)) => { - { - piece_cache.lock().await.add_piece(key, piece); - } - - trace!(%piece_index, "Got piece for archived segment."); - - break 'retry; - } - Ok(None) => { - debug!(%piece_index, "Can't get piece. Retrying..."); - - sleep(Duration::from_secs(GET_PIECE_DELAY_IN_SECS)).await; - } - Err(err) => { - warn!( - piece_index = ?piece_index, - err = ?err, - "Failed to get piece" - ); - } - } - } - } - - match node_client - .acknowledge_archived_segment_header(segment_index) - .await - { - Ok(()) => { - debug!(%segment_index, "Acknowledged archived segment."); - } - Err(err) => { - error!(%segment_index, ?err, "Failed to acknowledge archived segment."); - } - }; - - debug!(%segment_index, "Finished processing archived segment."); - } - } - Err(err) => { - error!(?err, "Failed to get archived segments notifications.") - } - } -} diff --git a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/dsn.rs b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/dsn.rs index 153e19b529c..29b1b1e5bb3 100644 --- a/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/dsn.rs +++ b/crates/subspace-farmer/src/bin/subspace-farmer/commands/farm/dsn.rs @@ -1,32 +1,33 @@ use crate::DsnArgs; -use anyhow::Context; use futures::StreamExt; use parking_lot::Mutex; +use std::collections::HashSet; use std::path::PathBuf; use std::sync::atomic::{AtomicU64, Ordering}; -use std::sync::Arc; -use std::time::Instant; +use std::sync::{Arc, Weak}; use subspace_core_primitives::SegmentIndex; -use subspace_farmer::utils::farmer_piece_cache::FarmerPieceCache; -use subspace_farmer::utils::farmer_provider_storage::FarmerProviderStorage; -use subspace_farmer::utils::parity_db_store::ParityDbStore; +use subspace_farmer::piece_cache::PieceCache; +use subspace_farmer::utils::archival_storage_info::ArchivalStorageInfo; +use subspace_farmer::utils::archival_storage_pieces::ArchivalStoragePieces; use subspace_farmer::utils::readers_and_pieces::ReadersAndPieces; use subspace_farmer::{NodeClient, NodeRpcClient}; -use subspace_farmer_components::piece_caching::PieceMemoryCache; use subspace_networking::libp2p::identity::Keypair; -use subspace_networking::libp2p::kad::ProviderRecord; +use subspace_networking::libp2p::kad::RecordKey; use subspace_networking::libp2p::multiaddr::Protocol; use subspace_networking::utils::multihash::ToMultihash; +use subspace_networking::utils::strip_peer_id; use subspace_networking::{ - create, peer_id, Config, NetworkingParametersManager, Node, NodeRunner, - ParityDbProviderStorage, PieceAnnouncementRequestHandler, PieceAnnouncementResponse, - PieceByHashRequest, PieceByHashRequestHandler, PieceByHashResponse, ProviderStorage, + create, Config, NetworkingParametersManager, Node, NodeRunner, PeerInfo, PeerInfoProvider, + PieceByHashRequest, PieceByHashRequestHandler, PieceByHashResponse, SegmentHeaderBySegmentIndexesRequestHandler, SegmentHeaderRequest, SegmentHeaderResponse, - KADEMLIA_PROVIDER_TTL_IN_SECS, }; -use tracing::{debug, error, info, trace, Instrument}; +use subspace_rpc_primitives::MAX_SEGMENT_HEADERS_PER_REQUEST; +use tracing::{debug, error, info, Instrument}; -const ROOT_BLOCK_NUMBER_LIMIT: u64 = 1000; +/// How many segment headers can be requested at a time. +/// +/// Must be the same as RPC limit since all requests go to the node anyway. +const SEGMENT_HEADER_NUMBER_LIMIT: u64 = MAX_SEGMENT_HEADERS_PER_REQUEST as u64; #[allow(clippy::type_complexity, clippy::too_many_arguments)] pub(super) fn configure_dsn( @@ -36,73 +37,29 @@ pub(super) fn configure_dsn( DsnArgs { listen_on, bootstrap_nodes, - piece_cache_size, - provided_keys_limit, - disable_private_ips, + enable_private_ips, reserved_peers, in_connections, out_connections, pending_in_connections, pending_out_connections, target_connections, + external_addresses, }: DsnArgs, - readers_and_pieces: &Arc>>, + weak_readers_and_pieces: Weak>>, node_client: NodeRpcClient, - piece_memory_cache: PieceMemoryCache, -) -> Result< - ( - Node, - NodeRunner>, - FarmerPieceCache, - ), - anyhow::Error, -> { - let peer_id = peer_id(&keypair); - - let networking_parameters_registry = { - let known_addresses_db_path = base_path.join("known_addresses_db"); - - NetworkingParametersManager::new(&known_addresses_db_path, bootstrap_nodes) - .map(|manager| manager.boxed())? - }; - - let weak_readers_and_pieces = Arc::downgrade(readers_and_pieces); - - let piece_cache_db_path = base_path.join("piece_cache_db"); - let provider_db_path = base_path.join("providers_db"); - - info!( - db_path = ?provider_db_path, - keys_limit = ?provided_keys_limit, - "Initializing provider storage..." - ); - let persistent_provider_storage = - ParityDbProviderStorage::new(&provider_db_path, provided_keys_limit, peer_id) - .map_err(|err| anyhow::anyhow!(err.to_string()))?; - info!( - current_size = ?persistent_provider_storage.size(), - "Provider storage initialized successfully" - ); - - info!( - db_path = ?piece_cache_db_path, - size = ?piece_cache_size, - "Initializing piece cache..." - ); - let piece_store = - ParityDbStore::new(&piece_cache_db_path).map_err(|err| anyhow::anyhow!(err.to_string()))?; - let piece_cache = FarmerPieceCache::new(piece_store.clone(), piece_cache_size, peer_id); - info!( - current_size = ?piece_cache.size(), - "Piece cache initialized successfully" - ); - - let farmer_provider_storage = FarmerProviderStorage::new( - peer_id, - readers_and_pieces.clone(), - persistent_provider_storage, - piece_cache.clone(), - ); + archival_storage_pieces: ArchivalStoragePieces, + archival_storage_info: ArchivalStorageInfo, + piece_cache: PieceCache, +) -> Result<(Node, NodeRunner), anyhow::Error> { + let networking_parameters_registry = NetworkingParametersManager::new( + &base_path.join("known_addresses.bin"), + strip_peer_id(bootstrap_nodes.clone()) + .into_iter() + .map(|(peer_id, _)| peer_id) + .collect::>(), + ) + .map(Box::new)?; // TODO: Consider introducing and using global in-memory segment header cache (this comment is // in multiple files) @@ -112,11 +69,8 @@ pub(super) fn configure_dsn( let node_client = node_client.clone(); async move { - let segment_headers_notifications = node_client - .subscribe_archived_segment_headers() - .await - .map_err(|err| anyhow::anyhow!(err.to_string())) - .context("Failed to subscribe to archived segments"); + let segment_headers_notifications = + node_client.subscribe_archived_segment_headers().await; match segment_headers_notifications { Ok(mut segment_headers_notifications) => { @@ -126,67 +80,45 @@ pub(super) fn configure_dsn( last_archived_segment_index .store(u64::from(segment_index), Ordering::Relaxed); - if let Err(err) = node_client + if let Err(error) = node_client .acknowledge_archived_segment_header(segment_index) .await { - error!(?err, %segment_index, "Failed to acknowledge archived segments notifications") + error!(?error, %segment_index, "Failed to acknowledge archived segments notifications") } } } - Err(err) => { - error!(?err, "Failed to get archived segments notifications.") + Err(error) => { + error!(?error, "Failed to get archived segments notifications.") } } } }); - let default_config = Config::new(protocol_prefix, keypair, farmer_provider_storage.clone()); + let default_config = Config::new( + protocol_prefix, + keypair, + piece_cache.clone(), + Some(PeerInfoProvider::new_farmer(Box::new( + archival_storage_pieces, + ))), + ); let config = Config { reserved_peers, listen_on, - allow_non_global_addresses_in_dht: !disable_private_ips, - networking_parameters_registry, + allow_non_global_addresses_in_dht: enable_private_ips, + networking_parameters_registry: Some(networking_parameters_registry), request_response_protocols: vec![ - PieceAnnouncementRequestHandler::create({ - move |peer_id, req| { - trace!(?req, %peer_id, "Piece announcement request received."); - - let provider_record = ProviderRecord { - provider: peer_id, - key: req.piece_index_hash.into(), - addresses: req.addresses.clone(), - expires: KADEMLIA_PROVIDER_TTL_IN_SECS.map(|ttl| Instant::now() + ttl), - }; - - let result = farmer_provider_storage.add_provider(provider_record); - if let Err(error) = &result { - error!( - %error, - %peer_id, - ?req, - "Failed to add provider for received key." - ); - }; - - async move { result.map(|_| PieceAnnouncementResponse::Success).ok() } - } - }), PieceByHashRequestHandler::create( move |_, &PieceByHashRequest { piece_index_hash }| { debug!(?piece_index_hash, "Piece request received. Trying cache..."); - let multihash = piece_index_hash.to_multihash(); let weak_readers_and_pieces = weak_readers_and_pieces.clone(); - let piece_store = piece_store.clone(); - let piece_memory_cache = piece_memory_cache.clone(); + let piece_cache = piece_cache.clone(); async move { - if let Some(piece) = piece_memory_cache.get_piece(&piece_index_hash) { - return Some(PieceByHashResponse { piece: Some(piece) }); - } - - let piece_from_store = piece_store.get(&multihash.into()); + let key = RecordKey::from(piece_index_hash.to_multihash()); + let piece_from_store = piece_cache.get_piece(key).await; if let Some(piece) = piece_from_store { Some(PieceByHashResponse { piece: Some(piece) }) @@ -242,14 +174,15 @@ pub(super) fn configure_dsn( segment_indexes.clone() } SegmentHeaderRequest::LastSegmentHeaders { - segment_header_number, + mut segment_header_number, } => { - if segment_header_number > ROOT_BLOCK_NUMBER_LIMIT { + if segment_header_number > SEGMENT_HEADER_NUMBER_LIMIT { debug!( %segment_header_number, "Segment header number exceeded the limit." ); - return None; + + segment_header_number = SEGMENT_HEADER_NUMBER_LIMIT; } let last_segment_index = SegmentIndex::from( @@ -296,7 +229,15 @@ pub(super) fn configure_dsn( max_pending_outgoing_connections: pending_out_connections, max_established_incoming_connections: in_connections, max_pending_incoming_connections: pending_in_connections, - target_connections, + general_target_connections: target_connections, + // maintain permanent connections between farmers + special_connected_peers_handler: Some(Arc::new(PeerInfo::is_farmer)), + // other (non-farmer) connections + general_connected_peers_handler: Some(Arc::new(|peer_info| { + !PeerInfo::is_farmer(peer_info) + })), + bootstrap_addresses: bootstrap_nodes, + external_addresses, ..default_config }; @@ -308,13 +249,41 @@ pub(super) fn configure_dsn( move |address| { info!( "DSN listening on {}", - address.clone().with(Protocol::P2p(node.id().into())) + address.clone().with(Protocol::P2p(node.id())) ); } })) .detach(); - (node, node_runner, piece_cache) + node.on_peer_info(Arc::new({ + let archival_storage_info = archival_storage_info.clone(); + + move |new_peer_info| { + let peer_id = new_peer_info.peer_id; + let peer_info = &new_peer_info.peer_info; + + if let PeerInfo::Farmer { cuckoo_filter } = peer_info { + archival_storage_info.update_cuckoo_filter(peer_id, cuckoo_filter.clone()); + + debug!(%peer_id, ?peer_info, "Peer info cached",); + } + } + })) + .detach(); + + node.on_disconnected_peer(Arc::new({ + let archival_storage_info = archival_storage_info.clone(); + + move |peer_id| { + if archival_storage_info.remove_peer_filter(peer_id) { + debug!(%peer_id, "Peer filter removed.",); + } + } + })) + .detach(); + + // Consider returning HandlerId instead of each `detach()` calls for other usages. + (node, node_runner) }) .map_err(Into::into) } diff --git a/crates/subspace-farmer/src/bin/subspace-farmer/commands/shared.rs b/crates/subspace-farmer/src/bin/subspace-farmer/commands/shared.rs index a4c4bb8adbe..484e454a5fb 100644 --- a/crates/subspace-farmer/src/bin/subspace-farmer/commands/shared.rs +++ b/crates/subspace-farmer/src/bin/subspace-farmer/commands/shared.rs @@ -8,7 +8,6 @@ pub(crate) fn print_disk_farm_info(directory: PathBuf, disk_farm_index: usize) { println!(" ID: {}", info.id()); println!(" Genesis hash: 0x{}", hex::encode(info.genesis_hash())); println!(" Public key: 0x{}", hex::encode(info.public_key())); - println!(" First sector index: {}", info.first_sector_index()); println!( " Allocated space: {} ({})", bytesize::to_string(info.allocated_space(), true), diff --git a/crates/subspace-farmer/src/bin/subspace-farmer/main.rs b/crates/subspace-farmer/src/bin/subspace-farmer/main.rs index fa7295bebc7..39d8cbd4ac4 100644 --- a/crates/subspace-farmer/src/bin/subspace-farmer/main.rs +++ b/crates/subspace-farmer/src/bin/subspace-farmer/main.rs @@ -4,13 +4,11 @@ mod commands; mod ss58; mod utils; -use crate::utils::get_usable_plot_space; -use anyhow::Result; use bytesize::ByteSize; use clap::{Parser, ValueEnum, ValueHint}; use ss58::parse_ss58_reward_address; use std::fs; -use std::num::{NonZeroU16, NonZeroUsize}; +use std::num::{NonZeroU16, NonZeroU8, NonZeroUsize}; use std::path::PathBuf; use std::str::FromStr; use subspace_core_primitives::PublicKey; @@ -43,9 +41,6 @@ struct FarmingArgs { /// Address for farming rewards #[arg(long, value_parser = parse_ss58_reward_address)] reward_address: PublicKey, - /// Maximum plot size in human readable format (e.g. 10GB, 2TiB) or just bytes (e.g. 4096). - #[arg(long, default_value_t)] - plot_size: ByteSize, /// Maximum number of pieces in sector (can override protocol value to something lower). #[arg(long)] max_pieces_in_sector: Option, @@ -61,11 +56,24 @@ struct FarmingArgs { /// Number of plots that can be plotted concurrently, impacts RAM usage. #[arg(long, default_value = "10")] max_concurrent_plots: NonZeroUsize, + /// Percentage of plot dedicated for caching purposes, 99% max. + #[arg(long, default_value = "1", value_parser = cache_percentage_parser)] + cache_percentage: NonZeroU8, /// Do not print info about configured farms on startup. #[arg(long)] no_info: bool, } +fn cache_percentage_parser(s: &str) -> anyhow::Result { + let cache_percentage = NonZeroU8::from_str(s)?; + + if cache_percentage.get() > 99 { + return Err(anyhow::anyhow!("Cache percentage can't exceed 100")); + } + + Ok(cache_percentage) +} + /// Arguments for DSN #[derive(Debug, Parser)] struct DsnArgs { @@ -76,15 +84,9 @@ struct DsnArgs { /// multiple are supported. #[arg(long, default_value = "/ip4/0.0.0.0/tcp/30533")] listen_on: Vec, - /// Piece cache size in pieces. - #[arg(long, default_value = "1000")] - piece_cache_size: NonZeroUsize, - /// Number of provided keys (by other peers) that will be stored. - #[arg(long, default_value = "655360")] - provided_keys_limit: NonZeroUsize, /// Determines whether we allow keeping non-global (private, shared, loopback..) addresses in Kademlia DHT. #[arg(long, default_value_t = false)] - disable_private_ips: bool, + enable_private_ips: bool, /// Multiaddrs of reserved nodes to maintain a connection to, multiple are supported #[arg(long)] reserved_peers: Vec, @@ -103,6 +105,9 @@ struct DsnArgs { /// Defines target total (in and out) connection number that should be maintained. #[arg(long, default_value_t = 50)] target_connections: u32, + /// Known external addresses + #[arg(long, alias = "external-address")] + external_addresses: Vec, } #[derive(Debug, Clone, Copy, ValueEnum)] @@ -118,6 +123,7 @@ impl Default for WriteToDisk { } } +#[allow(clippy::large_enum_variant)] // we allow large function parameter list and enums #[derive(Debug, clap::Subcommand)] enum Subcommand { /// Wipes plot and identity @@ -139,7 +145,7 @@ struct DiskFarm { impl FromStr for DiskFarm { type Err = String; - fn from_str(s: &str) -> Result { + fn from_str(s: &str) -> anyhow::Result { let parts = s.split(',').collect::>(); if parts.len() != 2 { return Err("Must contain 2 coma-separated components".to_string()); @@ -199,13 +205,6 @@ impl FromStr for DiskFarm { struct Command { #[clap(subcommand)] subcommand: Subcommand, - /// Base path for data storage. - #[arg( - long, - default_value_os_t = utils::default_base_path(), - value_hint = ValueHint::FilePath, - )] - base_path: PathBuf, /// Specify single plot located at specified path, can be specified multiple times to use /// multiple disks. /// @@ -219,14 +218,18 @@ struct Command { /// which right now occupies up to 8% of the disk space. #[arg(long)] farm: Vec, - /// Run temporary farmer, this will create a temporary directory for storing farmer data that - /// will be delete at the end of the process - #[arg(long, conflicts_with = "base_path", conflicts_with = "farm")] - tmp: bool, + /// Run temporary farmer with specified plot size in human readable format (e.g. 10GB, 2TiB) or + /// just bytes (e.g. 4096), this will create a temporary directory for storing farmer data that + /// will be deleted at the end of the process. + #[arg(long, conflicts_with = "farm")] + tmp: Option, + /// Enables the "development mode". Toggles flags like `--enable-private-ips` + #[arg(long)] + dev: bool, } #[tokio::main] -async fn main() -> Result<()> { +async fn main() -> anyhow::Result<()> { tracing_subscriber::registry() .with( fmt::layer().with_filter( @@ -240,80 +243,54 @@ async fn main() -> Result<()> { let command = Command::parse(); - let (base_path, _tmp_directory) = if command.tmp { + let (disk_farms, _tmp_directory) = if let Some(plot_size) = command.tmp { let tmp_directory = TempDir::new()?; - (tmp_directory.as_ref().to_path_buf(), Some(tmp_directory)) + ( + vec![DiskFarm { + directory: tmp_directory.as_ref().to_path_buf(), + allocated_plotting_space: plot_size.as_u64(), + }], + Some(tmp_directory), + ) } else { - (command.base_path, None) + (command.farm, None) }; match command.subcommand { Subcommand::Wipe => { - let disk_farms = if command.farm.is_empty() { - if !base_path.exists() { - info!("Done"); - - return Ok(()); - } - - // TODO: Support wiping of old disk plots for backwards compatibility - - vec![DiskFarm { - directory: base_path, - allocated_plotting_space: get_usable_plot_space(0), - }] - } else { - for farm in &command.farm { - if !farm.directory.exists() { - panic!("Directory {} doesn't exist", farm.directory.display()); - } + for farm in &disk_farms { + if !farm.directory.exists() { + panic!("Directory {} doesn't exist", farm.directory.display()); } - - command.farm - }; + } for farm in &disk_farms { + // TODO: Delete this section once we don't have shared data anymore + info!("Wiping shared data"); + let _ = fs::remove_file(farm.directory.join("known_addresses_db")); + let _ = fs::remove_file(farm.directory.join("known_addresses.bin")); + let _ = fs::remove_file(farm.directory.join("piece_cache_db")); + let _ = fs::remove_file(farm.directory.join("providers_db")); + SingleDiskPlot::wipe(&farm.directory)?; } info!("Done"); } - Subcommand::Farm(farming_args) => { - let disk_farms = if command.farm.is_empty() { - if !base_path.exists() { - fs::create_dir_all(&base_path).unwrap_or_else(|error| { - panic!("Failed to create data directory {base_path:?}: {error:?}") - }); - } - - vec![DiskFarm { - directory: base_path.clone(), - allocated_plotting_space: get_usable_plot_space( - farming_args.plot_size.as_u64(), - ), - }] - } else { - for farm in &command.farm { - if !farm.directory.exists() { - panic!("Directory {} doesn't exist", farm.directory.display()); - } + Subcommand::Farm(mut farming_args) => { + for farm in &disk_farms { + if !farm.directory.exists() { + panic!("Directory {} doesn't exist", farm.directory.display()); } + } - command.farm - }; + // Override the `--enable_private_ips` flag with `--dev` + farming_args.dsn.enable_private_ips = + farming_args.dsn.enable_private_ips || command.dev; - commands::farm_multi_disk::(base_path, disk_farms, farming_args).await?; + commands::farm_multi_disk::(disk_farms, farming_args).await?; } Subcommand::Info => { - let disk_farms = if command.farm.is_empty() { - vec![DiskFarm { - directory: base_path, - allocated_plotting_space: get_usable_plot_space(0), - }] - } else { - command.farm - }; - commands::info(disk_farms); } } diff --git a/crates/subspace-farmer/src/bin/subspace-farmer/utils.rs b/crates/subspace-farmer/src/bin/subspace-farmer/utils.rs index a65f6d6a0aa..0199e540054 100644 --- a/crates/subspace-farmer/src/bin/subspace-farmer/utils.rs +++ b/crates/subspace-farmer/src/bin/subspace-farmer/utils.rs @@ -1,12 +1,5 @@ -use std::path::PathBuf; use tokio::signal; -pub(crate) fn default_base_path() -> PathBuf { - dirs::data_local_dir() - .expect("Can't find local data directory, needs to be specified explicitly") - .join("subspace-farmer") -} - pub(crate) fn raise_fd_limit() { match std::panic::catch_unwind(fdlimit::raise_fd_limit) { Ok(Some(limit)) => { @@ -28,12 +21,6 @@ pub(crate) fn raise_fd_limit() { pub(crate) const DB_OVERHEAD_PERCENT: u64 = 92; -pub(crate) fn get_usable_plot_space(allocated_space: u64) -> u64 { - // TODO: Should account for database overhead of various additional databases. - // For now assume 92% will go for plot itself - allocated_space * DB_OVERHEAD_PERCENT / 100 -} - pub(crate) fn get_required_plot_space_with_overhead(allocated_space: u64) -> u64 { // TODO: Should account for database overhead of various additional databases. // For now assume 92% will go for plot itself diff --git a/crates/subspace-farmer/src/lib.rs b/crates/subspace-farmer/src/lib.rs index 3c50106aac1..96f761db75b 100644 --- a/crates/subspace-farmer/src/lib.rs +++ b/crates/subspace-farmer/src/lib.rs @@ -1,7 +1,7 @@ #![feature( + array_chunks, const_option, - drain_filter, - hash_drain_filter, + hash_extract_if, impl_trait_in_assoc_type, io_error_other, iter_collect_into, @@ -35,14 +35,12 @@ pub(crate) mod identity; pub mod node_client; -pub(crate) mod object_mappings; +pub mod piece_cache; pub mod reward_signing; pub mod single_disk_plot; pub mod utils; -pub mod ws_rpc_server; pub use identity::Identity; pub use jsonrpsee; pub use node_client::node_rpc_client::NodeRpcClient; pub use node_client::{Error as RpcClientError, NodeClient}; -pub use object_mappings::{ObjectMappingError, ObjectMappings}; diff --git a/crates/subspace-farmer/src/node_client.rs b/crates/subspace-farmer/src/node_client.rs index e6cefa36ccc..00aa85ea424 100644 --- a/crates/subspace-farmer/src/node_client.rs +++ b/crates/subspace-farmer/src/node_client.rs @@ -3,9 +3,10 @@ pub(crate) mod node_rpc_client; use async_trait::async_trait; use futures::Stream; use std::pin::Pin; -use subspace_core_primitives::{Piece, PieceIndex, SegmentCommitment, SegmentHeader, SegmentIndex}; +use subspace_core_primitives::{Piece, PieceIndex, SegmentHeader, SegmentIndex}; use subspace_rpc_primitives::{ - FarmerAppInfo, RewardSignatureResponse, RewardSigningInfo, SlotInfo, SolutionResponse, + FarmerAppInfo, NodeSyncStatus, RewardSignatureResponse, RewardSigningInfo, SlotInfo, + SolutionResponse, }; /// To become error type agnostic @@ -44,11 +45,10 @@ pub trait NodeClient: Clone + Send + Sync + 'static { &self, ) -> Result + Send + 'static>>, Error>; - /// Get segment commitments for the segments - async fn segment_commitments( + /// Subscribe to node sync status change + async fn subscribe_node_sync_status_change( &self, - segment_indexes: Vec, - ) -> Result>, Error>; + ) -> Result + Send + 'static>>, Error>; /// Get segment headers for the segments async fn segment_headers( diff --git a/crates/subspace-farmer/src/node_client/node_rpc_client.rs b/crates/subspace-farmer/src/node_client/node_rpc_client.rs index 9825377f695..a9db6e4e644 100644 --- a/crates/subspace-farmer/src/node_client/node_rpc_client.rs +++ b/crates/subspace-farmer/src/node_client/node_rpc_client.rs @@ -7,9 +7,10 @@ use jsonrpsee::rpc_params; use jsonrpsee::ws_client::{WsClient, WsClientBuilder}; use std::pin::Pin; use std::sync::Arc; -use subspace_core_primitives::{Piece, PieceIndex, SegmentCommitment, SegmentHeader, SegmentIndex}; +use subspace_core_primitives::{Piece, PieceIndex, SegmentHeader, SegmentIndex}; use subspace_rpc_primitives::{ - FarmerAppInfo, RewardSignatureResponse, RewardSigningInfo, SlotInfo, SolutionResponse, + FarmerAppInfo, NodeSyncStatus, RewardSignatureResponse, RewardSigningInfo, SlotInfo, + SolutionResponse, }; // Defines max_concurrent_requests constant in the node rpc client. @@ -123,14 +124,21 @@ impl NodeClient for NodeRpcClient { ))) } - async fn segment_commitments( + async fn subscribe_node_sync_status_change( &self, - segment_indexes: Vec, - ) -> Result>, RpcError> { - Ok(self + ) -> Result + Send + 'static>>, RpcError> { + let subscription = self .client - .request("subspace_segmentCommitments", rpc_params![&segment_indexes]) - .await?) + .subscribe( + "subspace_subscribeNodeSyncStatusChange", + rpc_params![], + "subspace_unsubscribeNodeSyncStatusChange", + ) + .await?; + + Ok(Box::pin(subscription.filter_map( + |node_sync_status_result| async move { node_sync_status_result.ok() }, + ))) } async fn segment_headers( diff --git a/crates/subspace-farmer/src/object_mappings.rs b/crates/subspace-farmer/src/object_mappings.rs deleted file mode 100644 index 3d3d08daf85..00000000000 --- a/crates/subspace-farmer/src/object_mappings.rs +++ /dev/null @@ -1,307 +0,0 @@ -#[cfg(test)] -mod tests; - -use num_traits::{WrappingAdd, WrappingSub}; -use parity_db::{Db, Options}; -use parity_scale_codec::{Decode, Encode}; -use parking_lot::Mutex; -use std::cell::RefCell; -use std::collections::BTreeMap; -use std::path::Path; -use std::sync::Arc; -use std::{fmt, iter}; -use subspace_core_primitives::objects::GlobalObject; -use subspace_core_primitives::{bidirectional_distance, Blake2b256Hash, PublicKey, U256}; -use thiserror::Error; - -/// How full should object mappings database be before we try to prune some values -const PRUNE_FILL_RATIO: (u64, u64) = (95, 100); -/// Target fill ratio after pruning -const RESET_FILL_RATIO: (u64, u64) = (80, 100); - -#[repr(u8)] -enum Columns { - Mappings = 0, - Metadata = 1, -} - -struct FurthestKey { - key: Blake2b256Hash, - /// Size of key + value together - size: u16, -} - -struct PruningState { - public_key_as_number: U256, - furthest_keys: BTreeMap, - /// Combined size of everything in `furthest_keys` - total_size: u64, - /// Amount of data we want to remove - remove_size: u64, -} - -impl PruningState { - fn new(public_key_as_number: U256, remove_size: u64) -> Self { - Self { - public_key_as_number, - furthest_keys: BTreeMap::new(), - total_size: 0, - remove_size, - } - } - - fn process(&mut self, furthest_key: FurthestKey) { - let distance_from_public_key = bidirectional_distance( - &self.public_key_as_number, - &U256::from_be_bytes(furthest_key.key), - ); - - loop { - if self.total_size < self.remove_size { - self.total_size += u64::from(furthest_key.size); - self.furthest_keys - .insert(distance_from_public_key, furthest_key); - break; - } else { - let (closest_distance, closest_furthest_key) = self - .furthest_keys - .first_key_value() - .expect("Total size isn't zero, meaning at least one key is in; qed"); - let closest_furthest_size = closest_furthest_key.size; - - // Check if the key is further than the closest know distance - if &distance_from_public_key > closest_distance { - // Remove existing key and loop to try inserting again - self.furthest_keys.pop_first(); - self.total_size -= u64::from(closest_furthest_size); - } else { - break; - } - } - } - } - - fn furthest_distance(&self) -> Option { - self.furthest_keys - .last_key_value() - .map(|(distance_from_public_key, _furthest_key)| *distance_from_public_key) - } - - fn keys_to_delete(&self) -> impl Iterator { - self.furthest_keys.values() - } -} - -#[derive(Debug, Error)] -pub enum ObjectMappingError { - #[error("DB error: {0}")] - Db(#[from] parity_db::Error), -} - -struct Inner { - db: Db, - public_key_as_number: U256, - size: Mutex, - /// Max distance from public key beyond which to not store anything - max_distance: Mutex>, - prune_fill_size: u64, - reset_fill_size: u64, -} - -/// `ObjectMappings` is a mapping from arbitrary object hash to its location in archived history. -#[derive(Clone)] -pub struct ObjectMappings { - inner: Arc, -} - -impl fmt::Debug for ObjectMappings { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ObjectMappings").finish() - } -} - -impl ObjectMappings { - const SIZE_KEY: &'static [u8] = b"size"; - const MAX_DISTANCE_KEY: &'static [u8] = b"max_distance"; - - /// Opens or creates a new object mappings database - pub fn open_or_create( - path: &Path, - public_key: PublicKey, - max_size: u64, - ) -> Result { - let mut options = Options::with_columns(path, 2); - { - let mappings_column_options = options - .columns - .get_mut(Columns::Mappings as usize) - .expect("Number of columns defined above; qed"); - mappings_column_options.uniform = true; - // Using b-tree so we can iterate over keys - mappings_column_options.btree_index = true; - } - // We don't use stats - options.stats = false; - // Remove salt to avoid mangling of keys - options.salt = Some([0u8; 32]); - let db = Db::open_or_create(&options)?; - - let size = - db.get(Columns::Metadata as u8, Self::SIZE_KEY)? - .map(|bytes| { - u64::from_le_bytes( - bytes.as_slice().try_into().expect( - "Values written into size key are always of correct length; qed", - ), - ) - }) - .unwrap_or_default(); - let max_distance = db - .get(Columns::Metadata as u8, Self::MAX_DISTANCE_KEY)? - .map(|bytes| { - U256::from_le_bytes(bytes.as_slice().try_into().expect( - "Values written into max distance key are always of correct length; qed", - )) - }); - - Ok(Self { - inner: Arc::new(Inner { - db, - public_key_as_number: U256::from_be_bytes(public_key.into()), - size: Mutex::new(size), - max_distance: Mutex::new(max_distance), - prune_fill_size: max_size.saturating_mul(PRUNE_FILL_RATIO.0) / PRUNE_FILL_RATIO.1, - reset_fill_size: max_size.saturating_mul(RESET_FILL_RATIO.0) / RESET_FILL_RATIO.1, - }), - }) - } - - /// Retrieve mapping for object - pub fn retrieve( - &self, - object_id: &Blake2b256Hash, - ) -> Result, ObjectMappingError> { - Ok(self - .inner - .db - .get(Columns::Mappings as u8, object_id)? - .and_then(|global_object| GlobalObject::decode(&mut global_object.as_ref()).ok())) - } - - /// Store object mappings in database, might run pruning if total size of mappings exceeds - /// configured size - pub fn store( - &self, - object_mapping: &[(Blake2b256Hash, GlobalObject)], - ) -> Result<(), ObjectMappingError> { - let bytes_to_write = RefCell::new(0u64); - let store = self.inner.max_distance.lock().as_ref().map(|max_distance| { - ( - self.inner.public_key_as_number.wrapping_sub(max_distance), - self.inner.public_key_as_number.wrapping_add(max_distance), - ) - }); - let tx = object_mapping - .iter() - .filter(|(object_id, _global_object)| match store { - Some((store_from, store_to)) => { - let object_id = U256::from_be_bytes(*object_id); - store_from < object_id && object_id < store_to - } - None => true, - }) - .map(|(object_id, global_object)| { - let encoded_global_object = global_object.encode(); - *bytes_to_write.borrow_mut() += - object_id.len() as u64 + encoded_global_object.len() as u64; - ( - Columns::Mappings as u8, - object_id.as_ref(), - Some(encoded_global_object), - ) - }); - - let mut size = self.inner.size.lock(); - - let mut new_size = *size; - - let tx = tx.chain( - iter::from_fn(|| { - let bytes_to_write = *bytes_to_write.borrow(); - if bytes_to_write == 0 { - // Nothing to store - return None; - } - - new_size += bytes_to_write; - - Some(( - Columns::Metadata as u8, - Self::SIZE_KEY, - Some(new_size.to_le_bytes().to_vec()), - )) - }) - .take(1), - ); - self.inner.db.commit(tx)?; - - *size = new_size; - - if new_size >= self.inner.prune_fill_size { - self.prune(new_size - self.inner.reset_fill_size, &mut size)?; - } - - Ok(()) - } - - fn prune(&self, remove_size: u64, size: &mut u64) -> Result<(), parity_db::Error> { - let mut pruning_state = PruningState::new(self.inner.public_key_as_number, remove_size); - let mut iter = self.inner.db.iter(Columns::Mappings as u8)?; - while let Some((key, value)) = iter.next()? { - pruning_state.process(FurthestKey { - key: key - .as_slice() - .try_into() - .expect("Key read from database is always of correct size"), - size: u16::try_from(key.len()).expect("Key always fits in u16; qed") - + u16::try_from(value.len()).expect("Value always fits in u16; qed"), - }); - } - - // Update furthest distance, so unnecessary keys are not stored - let max_distance = pruning_state - .furthest_distance() - .expect("Reaching this place implies there was at least one element stored; qed"); - self.inner.max_distance.lock().replace(max_distance); - - let bytes_to_delete = RefCell::new(0u64); - let tx = pruning_state.keys_to_delete().map(|furthest_key| { - *bytes_to_delete.borrow_mut() += u64::from(furthest_key.size); - - (Columns::Mappings as u8, furthest_key.key.as_ref(), None) - }); - - let mut new_size = *size; - - let tx = tx - .chain(iter::once_with(|| { - new_size -= *bytes_to_delete.borrow(); - - ( - Columns::Metadata as u8, - Self::SIZE_KEY, - Some(new_size.to_le_bytes().to_vec()), - ) - })) - .chain(iter::once(( - Columns::Metadata as u8, - Self::MAX_DISTANCE_KEY, - Some(max_distance.to_le_bytes().to_vec()), - ))); - self.inner.db.commit(tx)?; - - *size = new_size; - - Ok(()) - } -} diff --git a/crates/subspace-farmer/src/object_mappings/tests.rs b/crates/subspace-farmer/src/object_mappings/tests.rs deleted file mode 100644 index ada42f8c5ac..00000000000 --- a/crates/subspace-farmer/src/object_mappings/tests.rs +++ /dev/null @@ -1,174 +0,0 @@ -use crate::object_mappings::ObjectMappings; -use num_traits::{WrappingAdd, WrappingSub}; -use parity_scale_codec::Encode; -use rand::random; -use subspace_core_primitives::objects::GlobalObject; -use subspace_core_primitives::{PieceIndex, PublicKey, U256}; -use tempfile::TempDir; - -fn init() { - let _ = tracing_subscriber::fmt::try_init(); -} - -#[test] -fn basic() { - init(); - let public_key = PublicKey::from(random::<[u8; 32]>()); - let public_key_as_number = U256::from_be_bytes(public_key.into()); - let global_mappings = vec![ - ( - public_key_as_number - .wrapping_sub(&U256::from(5u64)) - .to_be_bytes(), - GlobalObject::V0 { - piece_index: PieceIndex::default(), - offset: 0, - }, - ), - ( - public_key_as_number - .wrapping_sub(&U256::from(2u64)) - .to_be_bytes(), - GlobalObject::V0 { - piece_index: PieceIndex::default(), - offset: 0, - }, - ), - ( - (public_key_as_number).to_be_bytes(), - GlobalObject::V0 { - piece_index: PieceIndex::default(), - offset: 0, - }, - ), - ( - public_key_as_number - .wrapping_add(&U256::from(1u64)) - .to_be_bytes(), - GlobalObject::V0 { - piece_index: PieceIndex::default(), - offset: 0, - }, - ), - ( - public_key_as_number - .wrapping_add(&U256::from(20u64)) - .to_be_bytes(), - GlobalObject::V0 { - piece_index: PieceIndex::default(), - offset: 0, - }, - ), - ]; - - // Test basic retrievability - { - let base_directory = TempDir::new().unwrap(); - let object_mappings = - ObjectMappings::open_or_create(base_directory.path(), public_key, u64::MAX).unwrap(); - object_mappings.store(&global_mappings).unwrap(); - - for (hash, global_mapping) in &global_mappings { - assert_eq!( - object_mappings.retrieve(hash).unwrap().as_ref(), - Some(global_mapping) - ); - } - } - - // Test pruning - { - let base_directory = TempDir::new().unwrap(); - let object_mappings = ObjectMappings::open_or_create( - base_directory.path(), - public_key, - // Store up to 4 elements, prune down to 3 - global_mappings[0].encoded_size() as u64 * 5 - 1, - ) - .unwrap(); - object_mappings.store(&global_mappings).unwrap(); - - assert!(object_mappings - .retrieve(&global_mappings[0].0) - .unwrap() - .is_none()); - for (hash, global_mapping) in global_mappings.iter().skip(1).take(3) { - assert_eq!( - object_mappings.retrieve(hash).unwrap().as_ref(), - Some(global_mapping) - ); - } - assert!(object_mappings - .retrieve(&global_mappings[4].0) - .unwrap() - .is_none()); - - // This key is further that keys pruned before and shouldn't be stored once attempted - let key_very_far = ( - public_key_as_number - .wrapping_add(&U256::from(21u64)) - .to_be_bytes(), - GlobalObject::V0 { - piece_index: PieceIndex::default(), - offset: 0, - }, - ); - - object_mappings.store(&[key_very_far]).unwrap(); - - // Not stored because too far - assert!(object_mappings.retrieve(&key_very_far.0).unwrap().is_none()); - - // This key is close enough to be stored - let key_close_enough = ( - public_key_as_number - .wrapping_add(&U256::from(2u64)) - .to_be_bytes(), - GlobalObject::V0 { - piece_index: PieceIndex::default(), - offset: 0, - }, - ); - - object_mappings.store(&[key_close_enough]).unwrap(); - - // Stored because close enough - assert_eq!( - object_mappings.retrieve(&key_close_enough.0).unwrap(), - Some(key_close_enough.1) - ); - // Keys previously stored are still there, so no pruning took effect yet - for (hash, global_mapping) in global_mappings.iter().skip(1).take(3) { - assert_eq!( - object_mappings.retrieve(hash).unwrap().as_ref(), - Some(global_mapping) - ); - } - - // Close and re-open database to check reading of parameters on restart - drop(object_mappings); - let object_mappings = ObjectMappings::open_or_create( - base_directory.path(), - public_key, - // Store up to 4 elements, prune down to 3 - global_mappings[0].encoded_size() as u64 * 5 - 1, - ) - .unwrap(); - - // Make sure old key is still not stored because too far - object_mappings.store(&[key_very_far]).unwrap(); - assert!(object_mappings.retrieve(&key_very_far.0).unwrap().is_none()); - - // And no pruning too place because nothing was inserted - assert_eq!( - object_mappings.retrieve(&key_close_enough.0).unwrap(), - Some(key_close_enough.1) - ); - for (hash, global_mapping) in global_mappings.iter().skip(1).take(3) { - assert_eq!( - object_mappings.retrieve(hash).unwrap().as_ref(), - Some(global_mapping) - ); - } - } -} diff --git a/crates/subspace-farmer/src/piece_cache.rs b/crates/subspace-farmer/src/piece_cache.rs new file mode 100644 index 00000000000..199951d0598 --- /dev/null +++ b/crates/subspace-farmer/src/piece_cache.rs @@ -0,0 +1,676 @@ +use crate::single_disk_plot::piece_cache::{DiskPieceCache, Offset}; +use crate::utils::AsyncJoinOnDrop; +use crate::NodeClient; +use futures::lock::Mutex; +use futures::{select, FutureExt, StreamExt}; +use parking_lot::RwLock; +use rayon::prelude::*; +use std::collections::HashMap; +use std::mem; +use std::sync::Arc; +use subspace_core_primitives::{Piece, PieceIndex, SegmentIndex}; +use subspace_farmer_components::plotting::{PieceGetter, PieceGetterRetryPolicy}; +use subspace_networking::libp2p::kad::{ProviderRecord, RecordKey}; +use subspace_networking::libp2p::PeerId; +use subspace_networking::utils::multihash::ToMultihash; +use subspace_networking::{KeyWrapper, LocalRecordProvider, UniqueRecordBinaryHeap}; +use tokio::sync::mpsc; +use tracing::{debug, error, info, trace, warn}; + +const WORKER_CHANNEL_CAPACITY: usize = 100; +/// Make caches available as they are building without waiting for the initialization to finish, +/// this number defines an interval in pieces after which cache is updated +const INTERMEDIATE_CACHE_UPDATE_INTERVAL: usize = 100; + +#[derive(Debug, Clone)] +struct DiskPieceCacheState { + stored_pieces: HashMap, + free_offsets: Vec, + backend: DiskPieceCache, +} + +#[derive(Debug)] +enum WorkerCommand { + ReplaceBackingCaches { new_caches: Vec }, + ForgetKey { key: RecordKey }, +} + +#[derive(Debug)] +struct CacheWorkerState { + heap: UniqueRecordBinaryHeap>, + last_segment_index: SegmentIndex, +} + +/// Cache worker used to drive the cache +#[must_use = "Cache will not work unless its worker is running"] +pub struct CacheWorker { + peer_id: PeerId, + node_client: NC, + /// It is important to always lock caches AFTER worker state in order to avoid deadlock! + caches: Arc>>, + worker_receiver: Option>, +} + +impl CacheWorker +where + NC: NodeClient, +{ + /// Run the cache worker with provided piece getter + pub async fn run(mut self, piece_getter: PG) + where + PG: PieceGetter, + { + // Limit is dynamically set later + // It is important to always lock worker state BEFORE caches in order to avoid deadlock! + let worker_state = Mutex::new(CacheWorkerState { + heap: UniqueRecordBinaryHeap::new(self.peer_id, 0), + last_segment_index: SegmentIndex::ZERO, + }); + + let mut worker_receiver = self + .worker_receiver + .take() + .expect("Always set during worker instantiation"); + + if let Some(WorkerCommand::ReplaceBackingCaches { new_caches }) = + worker_receiver.recv().await + { + self.initialize(&piece_getter, &worker_state, new_caches) + .await; + } else { + // Piece cache is dropped before backing caches were sent + return; + } + + loop { + select! { + maybe_command = worker_receiver.recv().fuse() => { + let Some(command) = maybe_command else { + // Nothing else left to do + return; + }; + + self.handle_command(command, &piece_getter, &worker_state).await; + } + _ = self.keep_up_sync(&piece_getter, &worker_state).fuse() => { + // Keep-up sync only ends with subscription, which lasts for duration of an + // instance + return; + } + } + } + } + + async fn handle_command( + &self, + command: WorkerCommand, + piece_getter: &PG, + worker_state: &Mutex, + ) where + PG: PieceGetter, + { + match command { + WorkerCommand::ReplaceBackingCaches { new_caches } => { + self.initialize(piece_getter, worker_state, new_caches) + .await; + } + // TODO: Consider implementing optional re-sync of the piece instead of just forgetting + WorkerCommand::ForgetKey { key } => { + let mut worker_state = worker_state.lock().await; + let mut caches = self.caches.write(); + + for (disk_farm_index, cache) in caches.iter_mut().enumerate() { + let Some(offset) = cache.stored_pieces.remove(&key) else { + // Not this disk farm + continue; + }; + + // Making offset as unoccupied and remove corresponding key from heap + cache.free_offsets.push(offset); + match cache.backend.read_piece_index(offset) { + Some(piece_index) => { + worker_state.heap.remove(KeyWrapper(piece_index)); + } + None => { + warn!( + %disk_farm_index, + %offset, + "Piece index out of range, this is likely an implementation bug, \ + not freeing heap element" + ); + } + } + return; + } + } + } + } + + async fn initialize( + &self, + piece_getter: &PG, + worker_state: &Mutex, + new_caches: Vec, + ) where + PG: PieceGetter, + { + info!("Initializing piece cache"); + let mut worker_state = worker_state.lock().await; + // Pull old cache state since it will be replaced with a new one and reuse its allocations + let cache_state = mem::take(&mut *self.caches.write()); + let mut stored_pieces = Vec::with_capacity(new_caches.len()); + let mut free_offsets = Vec::with_capacity(new_caches.len()); + for state in cache_state { + stored_pieces.push(state.stored_pieces); + free_offsets.push(state.free_offsets); + } + stored_pieces.resize(new_caches.len(), HashMap::default()); + free_offsets.resize(new_caches.len(), Vec::default()); + + debug!("Collecting pieces that were in the cache before"); + + // Build cache state of all backends + let mut caches = stored_pieces + .into_par_iter() + .zip(free_offsets) + .zip(new_caches) + .map(|((mut stored_pieces, mut free_offsets), new_cache)| { + let contents = new_cache.contents(); + stored_pieces.clear(); + stored_pieces.reserve(contents.len()); + free_offsets.clear(); + + for (offset, maybe_piece_index) in contents { + match maybe_piece_index { + Some(piece_index) => { + stored_pieces + .insert(RecordKey::from(piece_index.hash().to_multihash()), offset); + } + None => { + free_offsets.push(offset); + } + } + } + + DiskPieceCacheState { + stored_pieces, + free_offsets, + backend: new_cache, + } + }) + .collect::>(); + + info!("Synchronizing cache"); + + let last_segment_index = match self.node_client.farmer_app_info().await { + Ok(farmer_app_info) => farmer_app_info.protocol_info.history_size.segment_index(), + Err(error) => { + error!( + %error, + "Failed to get farmer app info from node, keeping old cache state without \ + updates" + ); + + // Not the latest, but at least something + *self.caches.write() = caches; + return; + } + }; + + worker_state.heap.clear(); + // Change limit to number of pieces + worker_state.heap.set_limit( + caches + .iter() + .map(|state| state.stored_pieces.len() + state.free_offsets.len()) + .sum::(), + ); + + for segment_index in SegmentIndex::ZERO..=last_segment_index { + for piece_index in segment_index.segment_piece_indexes() { + worker_state.heap.insert(KeyWrapper(piece_index)); + } + } + + // This hashset is faster than `heap` + // Clippy complains about `RecordKey`, but it is not changing here, so it is fine + #[allow(clippy::mutable_key_type)] + let mut inserted_piece_indices = worker_state + .heap + .keys() + .map(|KeyWrapper(piece_index)| { + ( + RecordKey::from(piece_index.hash().to_multihash()), + *piece_index, + ) + }) + .collect::>(); + + caches.iter_mut().for_each(|state| { + // Filter-out piece indices that are stored, but should not be as well as clean + // `inserted_piece_indices` from already stored piece indices, leaving just those that are + // still missing in cache + state + .stored_pieces + .extract_if(|key, _offset| inserted_piece_indices.remove(key).is_none()) + .for_each(|(_piece_index, offset)| { + state.free_offsets.push(offset); + }); + }); + + // TODO: Can probably do concurrency here + for (index, piece_index) in inserted_piece_indices.into_values().enumerate() { + let result = piece_getter + .get_piece(piece_index, PieceGetterRetryPolicy::Limited(1)) + .await; + + let piece = match result { + Ok(Some(piece)) => piece, + Ok(None) => { + debug!(%piece_index, "Couldn't find piece"); + continue; + } + Err(error) => { + debug!(%error, %piece_index, "Failed to get piece for piece cache"); + continue; + } + }; + + // Find plot in which there is a place for new piece to be stored + for (disk_farm_index, cache) in caches.iter_mut().enumerate() { + let Some(offset) = cache.free_offsets.pop() else { + continue; + }; + + if let Err(error) = cache.backend.write_piece(offset, piece_index, &piece) { + error!( + %error, + %disk_farm_index, + %piece_index, + %offset, + "Failed to write piece into cache" + ); + continue; + } + cache + .stored_pieces + .insert(RecordKey::from(piece_index.hash().to_multihash()), offset); + } + + if (index + 1) % INTERMEDIATE_CACHE_UPDATE_INTERVAL == 0 { + *self.caches.write() = caches.clone(); + } + } + + *self.caches.write() = caches; + worker_state.last_segment_index = last_segment_index; + + info!("Finished cache initialization"); + } + + async fn keep_up_sync(&self, piece_getter: &PG, worker_state: &Mutex) + where + PG: PieceGetter, + { + let mut segment_headers_notifications = + match self.node_client.subscribe_archived_segment_headers().await { + Ok(segment_headers_notifications) => segment_headers_notifications, + Err(error) => { + error!(%error, "Failed to subscribe to archived segments notifications"); + return; + } + }; + + // Keep up with segment indices that were potentially created since reinitialization, + // depending on the size of the diff this may pause block production for a while (due to + // subscription we have created above) + self.keep_up_after_initial_sync(piece_getter, worker_state) + .await; + + while let Some(segment_header) = segment_headers_notifications.next().await { + let segment_index = segment_header.segment_index(); + debug!(%segment_index, "Starting to process newly archived segment"); + + let mut worker_state = worker_state.lock().await; + + if worker_state.last_segment_index >= segment_index { + continue; + } + + // TODO: Can probably do concurrency here + for piece_index in segment_index.segment_piece_indexes() { + if !worker_state + .heap + .should_include_key(KeyWrapper(piece_index)) + { + trace!(%piece_index, "Piece doesn't need to be cached #1"); + + continue; + } + + trace!(%piece_index, "Piece needs to be cached #1"); + + let maybe_piece = match self.node_client.piece(piece_index).await { + Ok(maybe_piece) => maybe_piece, + Err(error) => { + error!( + %error, + %segment_index, + %piece_index, + "Failed to retrieve piece from node right after archiving, this \ + should never happen and is an implementation bug" + ); + continue; + } + }; + + let Some(piece) = maybe_piece else { + error!( + %segment_index, + %piece_index, + "Failed to retrieve piece from node right after archiving, this should \ + never happen and is an implementation bug" + ); + continue; + }; + + self.persist_piece_in_cache(piece_index, piece, &mut worker_state); + } + + worker_state.last_segment_index = segment_index; + + match self + .node_client + .acknowledge_archived_segment_header(segment_index) + .await + { + Ok(()) => { + debug!(%segment_index, "Acknowledged archived segment"); + } + Err(error) => { + error!(%segment_index, ?error, "Failed to acknowledge archived segment"); + } + }; + + debug!(%segment_index, "Finished processing newly archived segment"); + } + } + + async fn keep_up_after_initial_sync( + &self, + piece_getter: &PG, + worker_state: &Mutex, + ) where + PG: PieceGetter, + { + let mut worker_state = worker_state.lock().await; + let last_segment_index = match self.node_client.farmer_app_info().await { + Ok(farmer_app_info) => farmer_app_info.protocol_info.history_size.segment_index(), + Err(error) => { + error!( + %error, + "Failed to get farmer app info from node, keeping old cache state without \ + updates" + ); + return; + } + }; + + if last_segment_index <= worker_state.last_segment_index { + return; + } + + info!( + "Syncing piece cache to the latest history size, this may pause block production if \ + takes too long" + ); + + // Keep up with segment indices that were potentially created since reinitialization + let piece_indices = (worker_state.last_segment_index..=last_segment_index) + .flat_map(|segment_index| segment_index.segment_piece_indexes()); + + // TODO: Can probably do concurrency here + for piece_index in piece_indices { + let key = KeyWrapper(piece_index); + if !worker_state.heap.should_include_key(key) { + trace!(%piece_index, "Piece doesn't need to be cached #1"); + + continue; + } + + trace!(%piece_index, "Piece needs to be cached #1"); + + let result = piece_getter + .get_piece(piece_index, PieceGetterRetryPolicy::Limited(1)) + .await; + + let piece = match result { + Ok(Some(piece)) => piece, + Ok(None) => { + debug!(%piece_index, "Couldn't find piece"); + continue; + } + Err(error) => { + debug!( + %error, + %piece_index, + "Failed to get piece for piece cache" + ); + continue; + } + }; + + self.persist_piece_in_cache(piece_index, piece, &mut worker_state); + } + + info!("Finished syncing piece cache to the latest history size"); + + worker_state.last_segment_index = last_segment_index; + } + + /// This assumes it was already checked that piece needs to be stored, no verification for this + /// is done internally and invariants will break if this assumption doesn't hold true + fn persist_piece_in_cache( + &self, + piece_index: PieceIndex, + piece: Piece, + worker_state: &mut CacheWorkerState, + ) { + let record_key = RecordKey::from(piece_index.hash().to_multihash()); + let heap_key = KeyWrapper(piece_index); + + let mut caches = self.caches.write(); + match worker_state.heap.insert(heap_key) { + // Entry is already occupied, we need to find and replace old piece with new one + Some(KeyWrapper(old_piece_index)) => { + for (disk_farm_index, cache) in caches.iter_mut().enumerate() { + let old_record_key = RecordKey::from(old_piece_index.hash().to_multihash()); + let Some(offset) = cache.stored_pieces.remove(&old_record_key) else { + // Not this disk farm + continue; + }; + + if let Err(error) = cache.backend.write_piece(offset, piece_index, &piece) { + error!( + %error, + %disk_farm_index, + %piece_index, + %offset, + "Failed to write piece into cache" + ); + } else { + trace!( + %disk_farm_index, + %old_piece_index, + %piece_index, + %offset, + "Successfully replaced old cached piece" + ); + cache.stored_pieces.insert(record_key, offset); + } + return; + } + + warn!( + %old_piece_index, + %piece_index, + "Should have replaced cached piece, but it didn't happen, this is an \ + implementation bug" + ); + } + // There is free space in cache, need to find a free spot and place piece there + None => { + for (disk_farm_index, cache) in caches.iter_mut().enumerate() { + let Some(offset) = cache.free_offsets.pop() else { + // Not this disk farm + continue; + }; + + if let Err(error) = cache.backend.write_piece(offset, piece_index, &piece) { + error!( + %error, + %disk_farm_index, + %piece_index, + %offset, + "Failed to write piece into cache" + ); + } else { + trace!( + %disk_farm_index, + %piece_index, + %offset, + "Successfully stored piece in cache" + ); + cache.stored_pieces.insert(record_key, offset); + } + return; + } + + warn!( + %piece_index, + "Should have inserted piece into cache, but it didn't happen, this is an \ + implementation bug" + ); + } + }; + } +} + +/// Piece cache that aggregates caches of multiple disks +#[derive(Debug, Clone)] +pub struct PieceCache { + peer_id: PeerId, + /// Individual disk caches where pieces are stored + caches: Arc>>, + // We do not want to increase capacity unnecessarily on clone + worker_sender: mpsc::Sender, +} + +impl PieceCache { + /// Create new piece cache instance and corresponding worker. + /// + /// NOTE: Returned future is async, but does blocking operations and should be running in + /// dedicated thread. + pub fn new(node_client: NC, peer_id: PeerId) -> (Self, CacheWorker) + where + NC: NodeClient, + { + let caches = Arc::default(); + let (worker_sender, worker_receiver) = mpsc::channel(WORKER_CHANNEL_CAPACITY); + + let instance = Self { + peer_id, + caches: Arc::clone(&caches), + worker_sender, + }; + let worker = CacheWorker { + peer_id, + node_client, + caches, + worker_receiver: Some(worker_receiver), + }; + + (instance, worker) + } + + /// Get piece from cache + pub async fn get_piece(&self, key: RecordKey) -> Option { + let caches = Arc::clone(&self.caches); + + let maybe_piece_fut = tokio::task::spawn_blocking({ + let key = key.clone(); + let worker_sender = self.worker_sender.clone(); + + move || { + for (disk_farm_index, cache) in caches.read().iter().enumerate() { + let Some(&offset) = cache.stored_pieces.get(&key) else { + continue; + }; + match cache.backend.read_piece(offset) { + Ok(maybe_piece) => { + return maybe_piece; + } + Err(error) => { + error!( + %error, + %disk_farm_index, + ?key, + %offset, + "Error while reading piece from cache, might be a disk corruption" + ); + + if let Err(error) = + worker_sender.blocking_send(WorkerCommand::ForgetKey { key }) + { + trace!(%error, "Failed to send ForgetKey command to worker"); + } + + return None; + } + } + } + + None + } + }); + + match AsyncJoinOnDrop::new(maybe_piece_fut).await { + Ok(maybe_piece) => maybe_piece, + Err(error) => { + error!(%error, ?key, "Piece reading task failed"); + None + } + } + } + + pub async fn replace_backing_caches(&self, new_caches: Vec) { + if let Err(error) = self + .worker_sender + .send(WorkerCommand::ReplaceBackingCaches { new_caches }) + .await + { + warn!(%error, "Failed to replace backing caches, worker exited"); + } + } +} + +impl LocalRecordProvider for PieceCache { + fn record(&self, key: &RecordKey) -> Option { + // It is okay to take read lock here, writes locks are very infrequent and very short + for cache in self.caches.read().iter() { + if cache.stored_pieces.contains_key(key) { + // Note: We store our own provider records locally without local addresses + // to avoid redundant storage and outdated addresses. Instead these are + // acquired on demand when returning a `ProviderRecord` for the local node. + return Some(ProviderRecord { + key: key.clone(), + provider: self.peer_id, + expires: None, + addresses: Vec::new(), + }); + }; + } + + None + } +} diff --git a/crates/subspace-farmer/src/single_disk_plot.rs b/crates/subspace-farmer/src/single_disk_plot.rs index a60bb5cdb99..1d2bcc9bdd3 100644 --- a/crates/subspace-farmer/src/single_disk_plot.rs +++ b/crates/subspace-farmer/src/single_disk_plot.rs @@ -1,12 +1,17 @@ +mod farming; +pub mod piece_cache; pub mod piece_reader; +mod plotting; use crate::identity::Identity; -use crate::node_client; use crate::node_client::NodeClient; use crate::reward_signing::reward_signing; -use crate::single_disk_plot::auditing::audit_sector; -use crate::single_disk_plot::piece_reader::{read_piece, PieceReader, ReadPieceRequest}; -use crate::single_disk_plot::plotting::{plot_sector, PlottedSector}; +use crate::single_disk_plot::farming::farming; +pub use crate::single_disk_plot::farming::FarmingError; +use crate::single_disk_plot::piece_cache::{DiskPieceCache, DiskPieceCacheError}; +use crate::single_disk_plot::piece_reader::PieceReader; +pub use crate::single_disk_plot::plotting::PlottingError; +use crate::single_disk_plot::plotting::{plotting, plotting_scheduler}; use crate::utils::JoinOnDrop; use bytesize::ByteSize; use derive_more::{Display, From}; @@ -23,32 +28,27 @@ use static_assertions::const_assert; use std::fs::OpenOptions; use std::future::Future; use std::io::{Seek, SeekFrom}; -use std::num::NonZeroU16; +use std::num::{NonZeroU16, NonZeroU8}; use std::path::{Path, PathBuf}; use std::pin::Pin; use std::sync::Arc; -use std::time::SystemTime; use std::{fmt, fs, io, thread}; use std_semaphore::{Semaphore, SemaphoreGuard}; use subspace_core_primitives::crypto::kzg::Kzg; -use subspace_core_primitives::{PieceOffset, PublicKey, SectorId, SectorIndex, Solution}; +use subspace_core_primitives::{PieceOffset, PublicKey, SectorId, SectorIndex}; use subspace_erasure_coding::ErasureCoding; use subspace_farmer_components::file_ext::FileExt; -use subspace_farmer_components::piece_caching::PieceMemoryCache; -use subspace_farmer_components::plotting::{PieceGetter, PieceGetterRetryPolicy}; +use subspace_farmer_components::plotting::{PieceGetter, PlottedSector}; use subspace_farmer_components::sector::{sector_size, SectorMetadata}; -use subspace_farmer_components::{auditing, plotting, proving}; +use subspace_farmer_components::FarmerProtocolInfo; use subspace_proof_of_space::Table; -use subspace_rpc_primitives::{FarmerAppInfo, SlotInfo, SolutionResponse}; +use subspace_rpc_primitives::{FarmerAppInfo, SolutionResponse}; use thiserror::Error; use tokio::runtime::Handle; -use tokio::sync::{broadcast, OwnedSemaphorePermit}; -use tracing::{debug, error, info, info_span, trace, warn, Instrument, Span}; +use tokio::sync::broadcast; +use tracing::{debug, error, info, info_span, warn, Instrument, Span}; use ulid::Ulid; -/// Get piece retry attempts number. -const PIECE_GETTER_RETRY_NUMBER: NonZeroU16 = NonZeroU16::new(3).expect("Not zero; qed"); - // Refuse to compile on non-64-bit platforms, offsets may fail on those when converting from u64 to // usize depending on chain parameters const_assert!(std::mem::size_of::() >= std::mem::size_of::()); @@ -56,12 +56,6 @@ const_assert!(std::mem::size_of::() >= std::mem::size_of::()); /// Reserve 1M of space for plot metadata (for potential future expansion) const RESERVED_PLOT_METADATA: u64 = 1024 * 1024; -/// Self-imposed limit for number of solutions that farmer will not go over per challenge. -/// -/// Only useful for initial network bootstrapping where due to initial plot size there might be too -/// many solutions. -const SOLUTIONS_LIMIT: usize = 1; - /// Semaphore that limits disk access concurrency in strategic places to the number specified during /// initialization #[derive(Clone)] @@ -123,12 +117,6 @@ pub enum SingleDiskPlotInfo { genesis_hash: [u8; 32], /// Public key of identity used for plot creation public_key: PublicKey, - /// First sector index in this plot - /// - /// Multiple plots can reuse the same identity, but they have to use different ranges for - /// sector indexes or else they'll essentially plot the same data and will not result in - /// increased probability of winning the reward. - first_sector_index: SectorIndex, /// How many pieces does one sector contain. pieces_in_sector: u16, /// How much space in bytes is allocated for this plot @@ -143,7 +131,6 @@ impl SingleDiskPlotInfo { id: SingleDiskPlotId, genesis_hash: [u8; 32], public_key: PublicKey, - first_sector_index: SectorIndex, pieces_in_sector: u16, allocated_space: u64, ) -> Self { @@ -151,7 +138,6 @@ impl SingleDiskPlotInfo { id, genesis_hash, public_key, - first_sector_index, pieces_in_sector, allocated_space, } @@ -202,18 +188,6 @@ impl SingleDiskPlotInfo { public_key } - /// First sector index in this plot - /// - /// Multiple plots can reuse the same identity, but they have to use different ranges for - /// sector indexes or else they'll essentially plot the same data and will not result in - /// increased probability of winning the reward. - pub fn first_sector_index(&self) -> SectorIndex { - let Self::V0 { - first_sector_index, .. - } = self; - *first_sector_index - } - /// How many pieces does one sector contain. pub fn pieces_in_sector(&self) -> u16 { let Self::V0 { @@ -257,7 +231,7 @@ pub enum SingleDiskPlotSummary { #[derive(Debug, Encode, Decode)] struct PlotMetadataHeader { version: u8, - sector_count: u64, + sector_count: SectorIndex, } impl PlotMetadataHeader { @@ -274,7 +248,7 @@ impl PlotMetadataHeader { /// Options used to open single dis plot pub struct SingleDiskPlotOptions { - /// Path to directory where plot are stored. + /// Path to directory where plot is stored. pub directory: PathBuf, /// Information necessary for farmer application pub farmer_app_info: FarmerAppInfo, @@ -292,10 +266,8 @@ pub struct SingleDiskPlotOptions { pub kzg: Kzg, /// Erasure coding instance to use. pub erasure_coding: ErasureCoding, - /// Semaphore to limit concurrency of plotting process. - pub concurrent_plotting_semaphore: Arc, - /// Additional memory cache for pieces from archival storage - pub piece_memory_cache: PieceMemoryCache, + /// Percentage of disk plot dedicated for caching purposes + pub cache_percentage: NonZeroU8, } /// Errors happening when trying to create/open single disk plot @@ -305,6 +277,12 @@ pub enum SingleDiskPlotError { /// I/O error occurred #[error("I/O error: {0}")] Io(#[from] io::Error), + /// Piece cache error + #[error("Piece cache error: {0}")] + PieceCacheError(#[from] DiskPieceCacheError), + /// Can't preallocate plot file, probably not enough space on disk + #[error("Can't preallocate plot file, probably not enough space on disk: {0}")] + CantPreallocatePlotFile(io::Error), /// Can't resize plot after creation #[error( "Usable plotting space of plot {id} {new_space} is different from {old_space} when plot \ @@ -379,58 +357,18 @@ pub enum SingleDiskPlotError { /// Current allocated space allocated_space: u64, }, -} - -/// Errors that happen during plotting -#[derive(Debug, Error)] -pub enum PlottingError { - /// Failed to retrieve farmer info - #[error("Failed to retrieve farmer info: {error}")] - FailedToGetFarmerInfo { - /// Lower-level error - error: node_client::Error, - }, - /// I/O error occurred - #[error("I/O error: {0}")] - Io(#[from] io::Error), - /// Low-level plotting error - #[error("Low-level plotting error: {0}")] - LowLevel(#[from] plotting::PlottingError), -} - -/// Errors that happen during farming -#[derive(Debug, Error)] -pub enum FarmingError { - /// Failed to substribe to slot info notifications - #[error("Failed to substribe to slot info notifications: {error}")] - FailedToSubscribeSlotInfo { - /// Lower-level error - error: node_client::Error, - }, - /// Failed to retrieve farmer info - #[error("Failed to retrieve farmer info: {error}")] - FailedToGetFarmerInfo { - /// Lower-level error - error: node_client::Error, - }, - /// Failed to create memory mapping for metadata - #[error("Failed to create memory mapping for metadata: {error}")] - FailedToMapMetadata { - /// Lower-level error - error: io::Error, - }, - /// Failed to submit solutions response - #[error("Failed to submit solutions response: {error}")] - FailedToSubmitSolutionsResponse { - /// Lower-level error - error: node_client::Error, + /// Plot is too large + #[error( + "Plot is too large: allocated {allocated_sectors} sectors ({allocated_space} bytes), max \ + supported is {max_sectors} ({max_space} bytes). Consider creating multiple smaller plots \ + instead." + )] + PlotTooLarge { + allocated_space: u64, + allocated_sectors: u64, + max_space: u64, + max_sectors: u16, }, - /// Low-level proving error - #[error("Low-level proving error: {0}")] - LowLevelProving(#[from] proving::ProvingError), - /// I/O error occurred - #[error("I/O error: {0}")] - Io(#[from] io::Error), } /// Errors that happen in background tasks @@ -451,7 +389,7 @@ type Handler = Bag, A>; #[derive(Default, Debug)] struct Handlers { - sector_plotted: Handler<(usize, PlottedSector, Arc)>, + sector_plotted: Handler<(PlottedSector, Option)>, solution: Handler, } @@ -461,6 +399,7 @@ struct Handlers { /// Plot starts operating during creation and doesn't stop until dropped (or error happens). #[must_use = "Plot does not function properly unless run() method is called"] pub struct SingleDiskPlot { + farmer_protocol_info: FarmerProtocolInfo, single_disk_plot_info: SingleDiskPlotInfo, /// Metadata of all sectors plotted so far sectors_metadata: Arc>>, @@ -468,6 +407,7 @@ pub struct SingleDiskPlot { span: Span, tasks: FuturesUnordered, handlers: Arc, + piece_cache: DiskPieceCache, piece_reader: PieceReader, _plotting_join_handle: JoinOnDrop, _farming_join_handle: JoinOnDrop, @@ -517,8 +457,7 @@ impl SingleDiskPlot { piece_getter, kzg, erasure_coding, - concurrent_plotting_semaphore, - piece_memory_cache, + cache_percentage, } = options; fs::create_dir_all(&directory)?; @@ -590,19 +529,10 @@ impl SingleDiskPlot { }); } - // TODO: Global generator that makes sure to avoid returning the same sector index - // for multiple disks - let first_sector_index = SystemTime::UNIX_EPOCH - .elapsed() - .expect("Unix epoch is always in the past; qed") - .as_secs() - .wrapping_mul(u64::from(u32::MAX)); - let single_disk_plot_info = SingleDiskPlotInfo::new( SingleDiskPlotId::new(), farmer_app_info.genesis_hash, public_key, - first_sector_index, max_pieces_in_sector, allocated_space, ); @@ -616,20 +546,46 @@ impl SingleDiskPlot { let pieces_in_sector = single_disk_plot_info.pieces_in_sector(); let sector_size = sector_size(max_pieces_in_sector); let sector_metadata_size = SectorMetadata::encoded_size(); - let target_sector_count = - (single_disk_plot_info.allocated_space() / sector_size as u64) as usize; - let first_sector_index = single_disk_plot_info.first_sector_index(); + // TODO: Split allocated space into more components once all components are deterministic + // to correctly size everything: + // * plot info + // * identity + // * metadata + // * plot + // * known_addresses + let cache_size = allocated_space / 100 * u64::from(cache_percentage.get()); + // We have a hardcoded value decreasing allocated space to account for things like cache, + // don't change plot size (yet) if cache is under 5% that is assumed to be accounted for, + // this will be removed once we have proper static allocation as described in TODO above + let cache_size_exceeding_5_percents = + allocated_space / 100 * u64::from(cache_percentage.get()).saturating_sub(5); + let plot_space = (allocated_space - cache_size_exceeding_5_percents) / sector_size as u64; + let target_sector_count = plot_space; + let target_sector_count = match SectorIndex::try_from(target_sector_count) { + Ok(target_sector_count) if target_sector_count < SectorIndex::MAX => { + target_sector_count + } + _ => { + // We use this for both count and index, hence index must not reach actual `MAX` + // (consensus doesn't care about this, just farmer implementation detail) + let max_sectors = SectorIndex::MAX - 1; + return Err(SingleDiskPlotError::PlotTooLarge { + allocated_space: target_sector_count * sector_size as u64, + allocated_sectors: target_sector_count, + max_space: max_sectors as u64 * sector_size as u64, + max_sectors, + }); + } + }; - // TODO: Consider file locking to prevent other apps from modifying it + // TODO: Consider file locking to prevent other apps from modifying itS let mut metadata_file = OpenOptions::new() .read(true) .write(true) .create(true) .open(directory.join(Self::METADATA_FILE))?; - let (mut metadata_header, mut metadata_header_mmap) = if metadata_file - .seek(SeekFrom::End(0))? - == 0 + let (metadata_header, metadata_header_mmap) = if metadata_file.seek(SeekFrom::End(0))? == 0 { let metadata_header = PlotMetadataHeader { version: 0, @@ -637,7 +593,8 @@ impl SingleDiskPlot { }; metadata_file.preallocate( - RESERVED_PLOT_METADATA + sector_metadata_size as u64 * target_sector_count as u64, + RESERVED_PLOT_METADATA + + sector_metadata_size as u64 * u64::from(target_sector_count), )?; metadata_file.write_all_at(metadata_header.encode().as_slice(), 0)?; @@ -671,11 +628,12 @@ impl SingleDiskPlot { let metadata_mmap = unsafe { MmapOptions::new() .offset(RESERVED_PLOT_METADATA) - .len(sector_metadata_size * target_sector_count) + .len(sector_metadata_size * usize::from(target_sector_count)) .map(&metadata_file)? }; - let mut sectors_metadata = Vec::::with_capacity(target_sector_count); + let mut sectors_metadata = + Vec::::with_capacity(usize::from(target_sector_count)); for mut sector_metadata_bytes in metadata_mmap .chunks_exact(sector_metadata_size) @@ -698,7 +656,14 @@ impl SingleDiskPlot { .open(directory.join(Self::PLOT_FILE))?, ); - plot_file.preallocate(sector_size as u64 * target_sector_count as u64)?; + plot_file + .preallocate(sector_size as u64 * u64::from(target_sector_count)) + .map_err(SingleDiskPlotError::CantPreallocatePlotFile)?; + + let piece_cache = DiskPieceCache::open( + &directory, + cache_size as usize / DiskPieceCache::element_size(), + )?; let (error_sender, error_receiver) = oneshot::channel(); let error_sender = Arc::new(Mutex::new(Some(error_sender))); @@ -716,6 +681,10 @@ impl SingleDiskPlot { let handlers = Arc::::default(); let (start_sender, mut start_receiver) = broadcast::channel::<()>(1); let (stop_sender, mut stop_receiver) = broadcast::channel::<()>(1); + let modifying_sector_index = Arc::>>::default(); + let (sectors_to_plot_sender, sectors_to_plot_receiver) = mpsc::channel(0); + // Some sectors may already be plotted, skip them + let sectors_indices_left_to_plot = metadata_header.sector_count..target_sector_count; let span = info_span!("single_disk_plot", %disk_farm_index); @@ -727,6 +696,7 @@ impl SingleDiskPlot { let kzg = kzg.clone(); let erasure_coding = erasure_coding.clone(); let handlers = Arc::clone(&handlers); + let modifying_sector_index = Arc::clone(&modifying_sector_index); let node_client = node_client.clone(); let plot_file = Arc::clone(&plot_file); let error_sender = Arc::clone(&error_sender); @@ -743,86 +713,25 @@ impl SingleDiskPlot { return Ok(()); } - // Some sectors may already be plotted, skip them - let sectors_offsets_left_to_plot = - metadata_header.sector_count as usize..target_sector_count; - - // TODO: Concurrency - for sector_offset in sectors_offsets_left_to_plot { - let sector_index = sector_offset as u64 + first_sector_index; - trace!(%sector_offset, %sector_index, "Preparing to plot sector"); - - let mut sector = unsafe { - MmapOptions::new() - .offset((sector_offset * sector_size) as u64) - .len(sector_size) - .map_mut(&*plot_file)? - }; - let mut sector_metadata = unsafe { - MmapOptions::new() - .offset( - RESERVED_PLOT_METADATA - + (sector_offset * sector_metadata_size) as u64, - ) - .len(sector_metadata_size) - .map_mut(&metadata_file)? - }; - let plotting_permit = - match concurrent_plotting_semaphore.clone().acquire_owned().await { - Ok(plotting_permit) => plotting_permit, - Err(error) => { - warn!( - %sector_offset, - %sector_index, - %error, - "Semaphore was closed, interrupting plotting" - ); - return Ok(()); - } - }; - - debug!(%sector_offset, %sector_index, "Plotting sector"); - - let farmer_app_info = node_client - .farmer_app_info() - .await - .map_err(|error| PlottingError::FailedToGetFarmerInfo { error })?; - - let plot_sector_fut = plot_sector::<_, PosTable>( - &public_key, - sector_offset, - sector_index, - &piece_getter, - PieceGetterRetryPolicy::Limited(PIECE_GETTER_RETRY_NUMBER.get()), - &farmer_app_info.protocol_info, - &kzg, - &erasure_coding, - pieces_in_sector, - &mut sector, - &mut sector_metadata, - piece_memory_cache.clone(), - ); - let plotted_sector = plot_sector_fut.await?; - sector.flush()?; - sector_metadata.flush()?; - - metadata_header.sector_count += 1; - metadata_header_mmap - .copy_from_slice(metadata_header.encode().as_slice()); - sectors_metadata - .write() - .push(plotted_sector.sector_metadata.clone()); - - info!(%sector_offset, %sector_index, "Sector plotted successfully"); - - handlers.sector_plotted.call_simple(&( - sector_offset, - plotted_sector, - Arc::new(plotting_permit), - )); - } - - Ok::<_, PlottingError>(()) + plotting::<_, _, PosTable>( + public_key, + node_client, + pieces_in_sector, + sector_size, + sector_metadata_size, + metadata_header, + metadata_header_mmap, + plot_file, + metadata_file, + sectors_metadata, + piece_getter, + kzg, + erasure_coding, + handlers, + modifying_sector_index, + sectors_to_plot_receiver, + ) + .await }; let initial_plotting_result = handle.block_on(select( @@ -840,8 +749,18 @@ impl SingleDiskPlot { } })?; - let (mut slot_info_forwarder_sender, mut slot_info_forwarder_receiver) = - mpsc::channel::(0); + tasks.push(Box::pin(plotting_scheduler( + public_key.hash(), + sectors_indices_left_to_plot, + target_sector_count, + farmer_app_info.protocol_info.history_size.segment_index(), + farmer_app_info.protocol_info.min_sector_lifetime, + node_client.clone(), + Arc::clone(§ors_metadata), + sectors_to_plot_sender, + ))); + + let (mut slot_info_forwarder_sender, slot_info_forwarder_receiver) = mpsc::channel(0); tasks.push(Box::pin({ let node_client = node_client.clone(); @@ -882,6 +801,7 @@ impl SingleDiskPlot { let handle = handle.clone(); let erasure_coding = erasure_coding.clone(); let handlers = Arc::clone(&handlers); + let modifying_sector_index = Arc::clone(&modifying_sector_index); let sectors_metadata = Arc::clone(§ors_metadata); let mut start_receiver = start_sender.subscribe(); let mut stop_receiver = stop_sender.subscribe(); @@ -898,88 +818,20 @@ impl SingleDiskPlot { return Ok(()); } - while let Some(slot_info) = slot_info_forwarder_receiver.next().await { - let slot = slot_info.slot_number; - let sectors_metadata = sectors_metadata.read(); - let sector_count = sectors_metadata.len(); - - debug!(%slot, %sector_count, "Reading sectors"); - - let mut solutions = Vec::>::new(); - - for (sector_index, sector_metadata, sector) in sectors_metadata - .iter() - .zip(plot_mmap.chunks_exact(sector_size)) - .enumerate() - .map(|(sector_index, (sector, metadata))| { - (sector_index as u64 + first_sector_index, sector, metadata) - }) - { - trace!(%slot, %sector_index, "Auditing sector"); - - let maybe_solution_candidates = audit_sector( - &public_key, - sector_index, - &slot_info.global_challenge, - slot_info.voting_solution_range, - sector, - sector_metadata, - ); - let Some(solution_candidates) = maybe_solution_candidates else { - continue; - }; - - for maybe_solution in solution_candidates.into_iter::<_, PosTable>( - &reward_address, - &kzg, - &erasure_coding, - )? { - let solution = match maybe_solution { - Ok(solution) => solution, - Err(error) => { - error!(%slot, %sector_index, %error, "Failed to prove"); - // Do not error completely on disk corruption or other - // reasons why proving might fail - continue; - } - }; - - debug!(%slot, %sector_index, "Solution found"); - trace!(?solution, "Solution found"); - - solutions.push(solution); - - if solutions.len() >= SOLUTIONS_LIMIT { - break; - } - } - - if solutions.len() >= SOLUTIONS_LIMIT { - break; - } - // TODO: It is known that decoding is slow now and we'll only be - // able to decode a single sector within time slot reliably, in the - // future we may want allow more than one sector to be valid within - // the same disk plot. - if !solutions.is_empty() { - break; - } - } - - let response = SolutionResponse { - slot_number: slot_info.slot_number, - solutions, - }; - handlers.solution.call_simple(&response); - node_client - .submit_solution_response(response) - .await - .map_err(|error| FarmingError::FailedToSubmitSolutionsResponse { - error, - })?; - } - - Ok::<_, FarmingError>(()) + farming::<_, PosTable>( + public_key, + reward_address, + node_client, + sector_size, + plot_mmap, + sectors_metadata, + kzg, + erasure_coding, + handlers, + modifying_sector_index, + slot_info_forwarder_receiver, + ) + .await }; let farming_result = handle.block_on(select( @@ -997,75 +849,23 @@ impl SingleDiskPlot { } })?; - let (piece_reader, mut read_piece_receiver) = PieceReader::new(); + let (piece_reader, reading_fut) = PieceReader::new::( + public_key, + pieces_in_sector, + unsafe { Mmap::map(&*plot_file)? }, + Arc::clone(§ors_metadata), + erasure_coding, + modifying_sector_index, + ); let reading_join_handle = thread::Builder::new() .name(format!("reading-{disk_farm_index}")) .spawn({ - let global_plot_mmap = unsafe { Mmap::map(&*plot_file)? }; - #[cfg(unix)] - { - global_plot_mmap.advise(memmap2::Advice::Random)?; - } - - let sectors_metadata = Arc::clone(§ors_metadata); let mut stop_receiver = stop_sender.subscribe(); - let span = span.clone(); + let reading_fut = reading_fut.instrument(span.clone()); move || { let _tokio_handle_guard = handle.enter(); - let _span_guard = span.enter(); - - let reading_fut = async move { - while let Some(read_piece_request) = read_piece_receiver.next().await { - let ReadPieceRequest { - sector_index, - piece_offset, - response_sender, - } = read_piece_request; - - if response_sender.is_canceled() { - continue; - } - - let (sector_metadata, sector_count) = { - let sectors_metadata = sectors_metadata.read(); - - let sector_offset = (sector_index - first_sector_index) as usize; - let sector_count = sectors_metadata.len(); - - let sector_metadata = match sectors_metadata.get(sector_offset) { - Some(sector_metadata) => sector_metadata.clone(), - None => { - error!( - %sector_index, - %first_sector_index, - %sector_count, - "Tried to read piece from sector that is not yet \ - plotted" - ); - continue; - } - }; - - (sector_metadata, sector_count) - }; - - let maybe_piece = read_piece::( - &public_key, - piece_offset, - pieces_in_sector, - sector_count, - first_sector_index, - §or_metadata, - &global_plot_mmap, - &erasure_coding, - ); - - // Doesn't matter if receiver still cares about it - let _ = response_sender.send(maybe_piece); - } - }; handle.block_on(select( Box::pin(reading_fut), @@ -1082,12 +882,14 @@ impl SingleDiskPlot { })); let farm = Self { + farmer_protocol_info: farmer_app_info.protocol_info, single_disk_plot_info, sectors_metadata, pieces_in_sector, span, tasks, handlers, + piece_cache, piece_reader, _plotting_join_handle: JoinOnDrop::new(plotting_join_handle), _farming_join_handle: JoinOnDrop::new(farming_join_handle), @@ -1132,18 +934,22 @@ impl SingleDiskPlot { &self, ) -> impl Iterator> + '_ { let public_key = self.single_disk_plot_info.public_key(); - let first_sector_index = self.single_disk_plot_info.first_sector_index(); - (first_sector_index..) - .zip(self.sectors_metadata.read().clone()) - .map(move |(sector_index, sector_metadata)| { + (0..).zip(self.sectors_metadata.read().clone()).map( + move |(sector_index, sector_metadata)| { let sector_id = SectorId::new(public_key.hash(), sector_index); - let mut piece_indexes = Vec::with_capacity(self.pieces_in_sector.into()); + let mut piece_indexes = Vec::with_capacity(usize::from(self.pieces_in_sector)); (PieceOffset::ZERO..) - .take(self.pieces_in_sector.into()) + .take(usize::from(self.pieces_in_sector)) .map(|piece_offset| { - sector_id.derive_piece_index(piece_offset, sector_metadata.history_size) + sector_id.derive_piece_index( + piece_offset, + sector_metadata.history_size, + self.farmer_protocol_info.max_pieces_in_sector, + self.farmer_protocol_info.recent_segments, + self.farmer_protocol_info.recent_history_fraction, + ) }) .collect_into(&mut piece_indexes); @@ -1153,7 +959,13 @@ impl SingleDiskPlot { sector_metadata, piece_indexes, }) - }) + }, + ) + } + + /// Get piece cache instance + pub fn piece_cache(&self) -> DiskPieceCache { + self.piece_cache.clone() } /// Get piece reader to read plot pieces later @@ -1167,7 +979,7 @@ impl SingleDiskPlot { /// throttling of the plotting process is desired. pub fn on_sector_plotted( &self, - callback: HandlerFn<(usize, PlottedSector, Arc)>, + callback: HandlerFn<(PlottedSector, Option)>, ) -> HandlerId { self.handlers.sector_plotted.add(callback) } @@ -1194,17 +1006,23 @@ impl SingleDiskPlot { /// Wipe everything that belongs to this single disk plot pub fn wipe(directory: &Path) -> io::Result<()> { let single_disk_plot_info_path = directory.join(SingleDiskPlotInfo::FILE_NAME); - let single_disk_plot_info = SingleDiskPlotInfo::load_from(directory)?.ok_or_else(|| { - io::Error::new( - io::ErrorKind::NotFound, - format!( - "Single disk plot info not found at {}", - single_disk_plot_info_path.display() - ), - ) - })?; - - info!("Found single disk plot {}", single_disk_plot_info.id()); + match SingleDiskPlotInfo::load_from(directory) { + Ok(Some(single_disk_plot_info)) => { + info!("Found single disk plot {}", single_disk_plot_info.id()); + } + Ok(None) => { + return Err(io::Error::new( + io::ErrorKind::NotFound, + format!( + "Single disk plot info not found at {}", + single_disk_plot_info_path.display() + ), + )); + } + Err(error) => { + warn!("Found unknown single disk plot: {}", error); + } + } { let plot = directory.join(Self::PLOT_FILE); @@ -1224,6 +1042,8 @@ impl SingleDiskPlot { fs::remove_file(identity)?; } + DiskPieceCache::wipe(directory)?; + info!( "Deleting info file at {}", single_disk_plot_info_path.display() diff --git a/crates/subspace-farmer/src/single_disk_plot/farming.rs b/crates/subspace-farmer/src/single_disk_plot/farming.rs new file mode 100644 index 00000000000..decbd3ba0dc --- /dev/null +++ b/crates/subspace-farmer/src/single_disk_plot/farming.rs @@ -0,0 +1,174 @@ +use crate::node_client; +use crate::node_client::NodeClient; +use crate::single_disk_plot::Handlers; +use futures::channel::mpsc; +use futures::StreamExt; +use memmap2::Mmap; +use parking_lot::RwLock; +use std::io; +use std::sync::Arc; +use subspace_core_primitives::crypto::kzg::Kzg; +use subspace_core_primitives::{PublicKey, SectorIndex, Solution}; +use subspace_erasure_coding::ErasureCoding; +use subspace_farmer_components::auditing::audit_sector; +use subspace_farmer_components::proving; +use subspace_farmer_components::sector::SectorMetadata; +use subspace_proof_of_space::Table; +use subspace_rpc_primitives::{SlotInfo, SolutionResponse}; +use thiserror::Error; +use tracing::{debug, error, trace}; + +/// Self-imposed limit for number of solutions that farmer will not go over per challenge. +/// +/// Only useful for initial network bootstrapping where due to initial plot size there might be too +/// many solutions. +const SOLUTIONS_LIMIT: usize = 1; + +/// Errors that happen during farming +#[derive(Debug, Error)] +pub enum FarmingError { + /// Failed to subscribe to slot info notifications + #[error("Failed to substribe to slot info notifications: {error}")] + FailedToSubscribeSlotInfo { + /// Lower-level error + error: node_client::Error, + }, + /// Failed to retrieve farmer info + #[error("Failed to retrieve farmer info: {error}")] + FailedToGetFarmerInfo { + /// Lower-level error + error: node_client::Error, + }, + /// Failed to create memory mapping for metadata + #[error("Failed to create memory mapping for metadata: {error}")] + FailedToMapMetadata { + /// Lower-level error + error: io::Error, + }, + /// Failed to submit solutions response + #[error("Failed to submit solutions response: {error}")] + FailedToSubmitSolutionsResponse { + /// Lower-level error + error: node_client::Error, + }, + /// Low-level proving error + #[error("Low-level proving error: {0}")] + LowLevelProving(#[from] proving::ProvingError), + /// I/O error occurred + #[error("I/O error: {0}")] + Io(#[from] io::Error), +} + +/// Starts farming process. +/// +/// NOTE: Returned future is async, but does blocking operations and should be running in dedicated +/// thread. +// False-positive, we do drop lock before .await +#[allow(clippy::await_holding_lock)] +#[allow(clippy::too_many_arguments)] +pub(super) async fn farming( + public_key: PublicKey, + reward_address: PublicKey, + node_client: NC, + sector_size: usize, + plot_mmap: Mmap, + sectors_metadata: Arc>>, + kzg: Kzg, + erasure_coding: ErasureCoding, + handlers: Arc, + modifying_sector_index: Arc>>, + mut slot_info_notifications: mpsc::Receiver, +) -> Result<(), FarmingError> +where + NC: NodeClient, + PosTable: Table, +{ + let mut table_generator = PosTable::generator(); + + while let Some(slot_info) = slot_info_notifications.next().await { + let slot = slot_info.slot_number; + let sectors_metadata = sectors_metadata.read(); + let sector_count = sectors_metadata.len(); + + debug!(%slot, %sector_count, "Reading sectors"); + + let modifying_sector_guard = modifying_sector_index.read(); + let maybe_sector_being_modified = modifying_sector_guard.as_ref().copied(); + let mut solutions = Vec::>::new(); + + for ((sector_index, sector_metadata), sector) in (0..) + .zip(&*sectors_metadata) + .zip(plot_mmap.chunks_exact(sector_size)) + { + if maybe_sector_being_modified == Some(sector_index) { + // Skip sector that is being modified right now + continue; + } + trace!(%slot, %sector_index, "Auditing sector"); + + let maybe_solution_candidates = audit_sector( + &public_key, + sector_index, + &slot_info.global_challenge, + slot_info.voting_solution_range, + sector, + sector_metadata, + ); + let Some(solution_candidates) = maybe_solution_candidates else { + continue; + }; + + for maybe_solution in solution_candidates.into_iter::<_, PosTable>( + &reward_address, + &kzg, + &erasure_coding, + &mut table_generator, + )? { + let solution = match maybe_solution { + Ok(solution) => solution, + Err(error) => { + error!(%slot, %sector_index, %error, "Failed to prove"); + // Do not error completely on disk corruption or other + // reasons why proving might fail + continue; + } + }; + + debug!(%slot, %sector_index, "Solution found"); + trace!(?solution, "Solution found"); + + solutions.push(solution); + + if solutions.len() >= SOLUTIONS_LIMIT { + break; + } + } + + if solutions.len() >= SOLUTIONS_LIMIT { + break; + } + // TODO: It is known that decoding is slow now and we'll only be + // able to decode a single sector within time slot reliably, in the + // future we may want allow more than one sector to be valid within + // the same disk plot. + if !solutions.is_empty() { + break; + } + } + + drop(sectors_metadata); + drop(modifying_sector_guard); + + let response = SolutionResponse { + slot_number: slot_info.slot_number, + solutions, + }; + handlers.solution.call_simple(&response); + node_client + .submit_solution_response(response) + .await + .map_err(|error| FarmingError::FailedToSubmitSolutionsResponse { error })?; + } + + Ok(()) +} diff --git a/crates/subspace-farmer/src/single_disk_plot/piece_cache.rs b/crates/subspace-farmer/src/single_disk_plot/piece_cache.rs new file mode 100644 index 00000000000..e1c98f94a86 --- /dev/null +++ b/crates/subspace-farmer/src/single_disk_plot/piece_cache.rs @@ -0,0 +1,214 @@ +use derive_more::Display; +use memmap2::{Mmap, MmapOptions}; +use std::fs::{File, OpenOptions}; +use std::io::{Seek, SeekFrom}; +use std::path::Path; +use std::sync::Arc; +use std::{fs, io, mem}; +use subspace_core_primitives::{Piece, PieceIndex}; +use subspace_farmer_components::file_ext::FileExt; +use thiserror::Error; +use tracing::{info, warn}; + +/// Disk piece cache open error +#[derive(Debug, Error)] +pub enum DiskPieceCacheError { + /// I/O error occurred + #[error("I/O error: {0}")] + Io(#[from] io::Error), + /// Can't preallocate cache file, probably not enough space on disk + #[error("Can't preallocate cache file, probably not enough space on disk: {0}")] + CantPreallocateCacheFile(io::Error), + /// Offset outsize of range + #[error("Offset outsize of range: provided {provided}, max {max}")] + OffsetOutsideOfRange { + /// Provided offset + provided: usize, + /// Max offset + max: usize, + }, + /// Cache size has zero capacity, this is not supported + #[error("Cache size has zero capacity, this is not supported")] + ZeroCapacity, +} + +/// Offset wrapper for pieces in [`DiskPieceCache`] +#[derive(Debug, Display, Copy, Clone)] +#[repr(transparent)] +pub struct Offset(usize); + +#[derive(Debug)] +struct Inner { + file: File, + read_mmap: Mmap, + file_size: usize, +} + +/// Piece cache stored on one disk +#[derive(Debug, Clone)] +pub struct DiskPieceCache { + inner: Arc, +} + +impl DiskPieceCache { + const PIECE_CACHE_FILE: &'static str = "piece_cache.bin"; + + pub(super) fn open(directory: &Path, capacity: usize) -> Result { + if capacity == 0 { + return Err(DiskPieceCacheError::ZeroCapacity); + } + + let mut file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(directory.join(Self::PIECE_CACHE_FILE))?; + + let current_file_size = file.seek(SeekFrom::End(0))?; + let expected_size = Self::element_size() * capacity; + if current_file_size == 0 { + // Empty file + file.preallocate(expected_size as u64) + .map_err(DiskPieceCacheError::CantPreallocateCacheFile)?; + } else if current_file_size == expected_size as u64 { + // Already correct size + } else { + panic!( + "Resizing not supported, single disk plot must have checked this before getting \ + here" + ); + } + + let read_mmap = unsafe { MmapOptions::new().len(expected_size).map(&file)? }; + #[cfg(unix)] + { + read_mmap.advise(memmap2::Advice::Random)?; + } + + Ok(Self { + inner: Arc::new(Inner { + file, + read_mmap, + file_size: expected_size, + }), + }) + } + + pub(super) const fn element_size() -> usize { + mem::size_of::() + Piece::SIZE + } + + /// Contents of this disk cache + /// + /// NOTE: it is possible to do concurrent reads and writes, higher level logic must ensure this + /// doesn't happen for the same piece being accessed! + pub(crate) fn contents( + &self, + ) -> impl ExactSizeIterator)> + '_ { + self.inner + .read_mmap + .array_chunks::<{ Self::element_size() }>() + .enumerate() + .map(|(offset, chunk)| { + let (piece_index_bytes, piece_bytes) = chunk.split_at(PieceIndex::SIZE); + let piece_index = PieceIndex::from_bytes( + piece_index_bytes + .try_into() + .expect("Statically known to have correct size; qed"), + ); + // Piece index zero might mean we have piece index zero or just an empty space + let piece_index = if piece_index != PieceIndex::ZERO + || piece_bytes.iter().any(|&byte| byte != 0) + { + Some(piece_index) + } else { + None + }; + + (Offset(offset), piece_index) + }) + } + + /// Store piece in cache at specified offset, replacing existing piece if there is any + /// + /// NOTE: it is possible to do concurrent reads and writes, higher level logic must ensure this + /// doesn't happen for the same piece being accessed! + pub(crate) fn write_piece( + &self, + offset: Offset, + piece_index: PieceIndex, + piece: &Piece, + ) -> Result<(), DiskPieceCacheError> { + let Offset(offset) = offset; + if offset >= self.inner.file_size / Self::element_size() { + return Err(DiskPieceCacheError::OffsetOutsideOfRange { + provided: offset, + max: self.inner.file_size / Self::element_size() - 1, + }); + } + + let mut write_mmap = unsafe { + MmapOptions::new() + .offset((offset * Self::element_size()) as u64) + .len(Self::element_size()) + .map_mut(&self.inner.file)? + }; + + let piece_index_bytes = piece_index.to_bytes(); + write_mmap[..piece_index_bytes.len()].copy_from_slice(&piece_index_bytes); + write_mmap[piece_index_bytes.len()..].copy_from_slice(piece.as_ref()); + + write_mmap.flush()?; + + Ok(()) + } + + /// Read piece index from cache at specified offset. + /// + /// Returns `None` if offset is out of range. + /// + /// NOTE: it is possible to do concurrent reads and writes, higher level logic must ensure this + /// doesn't happen for the same piece being accessed! + pub(crate) fn read_piece_index(&self, offset: Offset) -> Option { + let Offset(offset) = offset; + if offset >= self.inner.file_size / Self::element_size() { + warn!(%offset, "Trying to read piece out of range, this must be an implementation bug"); + return None; + } + + Some(PieceIndex::from_bytes( + self.inner.read_mmap[Self::element_size() * offset..][..PieceIndex::SIZE] + .try_into() + .expect("Statically guaranteed to be correct size; qed"), + )) + } + + /// Read piece from cache at specified offset. + /// + /// Returns `None` if offset is out of range. + /// + /// NOTE: it is possible to do concurrent reads and writes, higher level logic must ensure this + /// doesn't happen for the same piece being accessed! + pub(crate) fn read_piece(&self, offset: Offset) -> Result, DiskPieceCacheError> { + let Offset(offset) = offset; + if offset >= self.inner.file_size / Self::element_size() { + warn!(%offset, "Trying to read piece out of range, this must be an implementation bug"); + return Ok(None); + } + + let mut piece = Piece::default(); + piece.copy_from_slice( + &self.inner.read_mmap[offset * Self::element_size() + PieceIndex::SIZE..] + [..Piece::SIZE], + ); + + // TODO: Verify checksum (when we have them) and return `None` in case it doesn't match + Ok(Some(piece)) + } + + pub(crate) fn wipe(directory: &Path) -> io::Result<()> { + let piece_cache = directory.join(Self::PIECE_CACHE_FILE); + info!("Deleting piece cache file at {}", piece_cache.display()); + fs::remove_file(piece_cache) + } +} diff --git a/crates/subspace-farmer/src/single_disk_plot/piece_reader.rs b/crates/subspace-farmer/src/single_disk_plot/piece_reader.rs index 3c8e67c9828..48ab9cc78bc 100644 --- a/crates/subspace-farmer/src/single_disk_plot/piece_reader.rs +++ b/crates/subspace-farmer/src/single_disk_plot/piece_reader.rs @@ -1,5 +1,9 @@ use futures::channel::{mpsc, oneshot}; -use futures::SinkExt; +use futures::{SinkExt, StreamExt}; +use memmap2::Mmap; +use parking_lot::RwLock; +use std::future::Future; +use std::sync::Arc; use subspace_core_primitives::{Piece, PieceOffset, PublicKey, SectorId, SectorIndex}; use subspace_erasure_coding::ErasureCoding; use subspace_farmer_components::reading; @@ -8,10 +12,10 @@ use subspace_proof_of_space::Table; use tracing::{error, warn}; #[derive(Debug)] -pub(super) struct ReadPieceRequest { - pub(super) sector_index: SectorIndex, - pub(super) piece_offset: PieceOffset, - pub(super) response_sender: oneshot::Sender>, +struct ReadPieceRequest { + sector_index: SectorIndex, + piece_offset: PieceOffset, + response_sender: oneshot::Sender>, } /// Wrapper data structure that can be used to read pieces from single disk plot @@ -21,10 +25,34 @@ pub struct PieceReader { } impl PieceReader { - pub(super) fn new() -> (Self, mpsc::Receiver) { - let (read_piece_sender, read_piece_receiver) = mpsc::channel::(10); + /// Creates new piece reader instance and background future that handles reads internally. + /// + /// NOTE: Background future is async, but does blocking operations and should be running in + /// dedicated thread. + pub(super) fn new( + public_key: PublicKey, + pieces_in_sector: u16, + global_plot_mmap: Mmap, + sectors_metadata: Arc>>, + erasure_coding: ErasureCoding, + modifying_sector_index: Arc>>, + ) -> (Self, impl Future) + where + PosTable: Table, + { + let (read_piece_sender, read_piece_receiver) = mpsc::channel(10); + + let reading_fut = read_pieces::( + public_key, + pieces_in_sector, + global_plot_mmap, + sectors_metadata, + erasure_coding, + modifying_sector_index, + read_piece_receiver, + ); - (Self { read_piece_sender }, read_piece_receiver) + (Self { read_piece_sender }, reading_fut) } pub(super) fn close_all_readers(&mut self) { @@ -52,38 +80,102 @@ impl PieceReader { } #[allow(clippy::too_many_arguments)] -pub(super) fn read_piece( +async fn read_pieces( + public_key: PublicKey, + pieces_in_sector: u16, + global_plot_mmap: Mmap, + sectors_metadata: Arc>>, + erasure_coding: ErasureCoding, + modifying_sector_index: Arc>>, + mut read_piece_receiver: mpsc::Receiver, +) where + PosTable: Table, +{ + #[cfg(unix)] + { + if let Err(error) = global_plot_mmap.advise(memmap2::Advice::Random) { + error!(%error, "Failed to set random access on global plot mmap"); + } + } + + let mut table_generator = PosTable::generator(); + + while let Some(read_piece_request) = read_piece_receiver.next().await { + let ReadPieceRequest { + sector_index, + piece_offset, + response_sender, + } = read_piece_request; + + if response_sender.is_canceled() { + continue; + } + + let modifying_sector_guard = modifying_sector_index.read(); + + if *modifying_sector_guard == Some(sector_index) { + // Skip sector that is being modified right now + continue; + } + + let (sector_metadata, sector_count) = { + let sectors_metadata = sectors_metadata.read(); + + let sector_count = sectors_metadata.len() as SectorIndex; + + let sector_metadata = match sectors_metadata.get(sector_index as usize) { + Some(sector_metadata) => sector_metadata.clone(), + None => { + error!( + %sector_index, + %sector_count, + "Tried to read piece from sector that is not yet \ + plotted" + ); + continue; + } + }; + + (sector_metadata, sector_count) + }; + + let maybe_piece = read_piece::( + &public_key, + piece_offset, + pieces_in_sector, + sector_count, + §or_metadata, + &global_plot_mmap, + &erasure_coding, + &mut table_generator, + ); + + // Doesn't matter if receiver still cares about it + let _ = response_sender.send(maybe_piece); + } +} + +#[allow(clippy::too_many_arguments)] +fn read_piece( public_key: &PublicKey, piece_offset: PieceOffset, pieces_in_sector: u16, - sector_count: usize, - first_sector_index: SectorIndex, + sector_count: SectorIndex, sector_metadata: &SectorMetadata, global_plot: &[u8], erasure_coding: &ErasureCoding, + table_generator: &mut PosTable::Generator, ) -> Option where PosTable: Table, { let sector_index = sector_metadata.sector_index; - if sector_index < first_sector_index { - warn!( - %sector_index, - %piece_offset, - %sector_count, - %first_sector_index, - "Incorrect first sector index" - ); - return None; - } - let sector_offset = (sector_index - first_sector_index) as usize; // Sector must be plotted - if sector_offset >= sector_count { + if sector_index >= sector_count { warn!( %sector_index, %piece_offset, %sector_count, - %first_sector_index, "Incorrect sector offset" ); return None; @@ -94,7 +186,6 @@ where %sector_index, %piece_offset, %sector_count, - %first_sector_index, "Incorrect piece offset" ); return None; @@ -103,7 +194,7 @@ where let sector_id = SectorId::new(public_key.hash(), sector_index); let sector_size = sector_size(pieces_in_sector); // TODO: Would be nicer to have list of plots here and just index it - let sector = &global_plot[sector_size * sector_offset..][..sector_size]; + let sector = &global_plot[sector_index as usize * sector_size..][..sector_size]; let piece = match reading::read_piece::( piece_offset, @@ -111,6 +202,7 @@ where sector_metadata, sector, erasure_coding, + table_generator, ) { Ok(piece) => piece, Err(error) => { @@ -118,7 +210,6 @@ where %sector_index, %piece_offset, %sector_count, - %first_sector_index, %error, "Failed to read piece from sector" ); diff --git a/crates/subspace-farmer/src/single_disk_plot/plotting.rs b/crates/subspace-farmer/src/single_disk_plot/plotting.rs new file mode 100644 index 00000000000..dfbe2fa97cb --- /dev/null +++ b/crates/subspace-farmer/src/single_disk_plot/plotting.rs @@ -0,0 +1,597 @@ +use crate::single_disk_plot::{ + BackgroundTaskError, Handlers, PlotMetadataHeader, RESERVED_PLOT_METADATA, +}; +use crate::{node_client, NodeClient}; +use atomic::Atomic; +use futures::channel::{mpsc, oneshot}; +use futures::{select, FutureExt, SinkExt, StreamExt}; +use lru::LruCache; +use memmap2::{MmapMut, MmapOptions}; +use parity_scale_codec::Encode; +use parking_lot::RwLock; +use std::collections::HashMap; +use std::fs::File; +use std::io; +use std::num::{NonZeroU16, NonZeroUsize}; +use std::ops::Range; +use std::sync::atomic::Ordering; +use std::sync::Arc; +use std::time::Duration; +use subspace_core_primitives::crypto::kzg::Kzg; +use subspace_core_primitives::{ + Blake2b256Hash, HistorySize, PieceOffset, PublicKey, SectorId, SectorIndex, SegmentHeader, + SegmentIndex, +}; +use subspace_erasure_coding::ErasureCoding; +use subspace_farmer_components::plotting; +use subspace_farmer_components::plotting::{ + plot_sector, PieceGetter, PieceGetterRetryPolicy, PlottedSector, +}; +use subspace_farmer_components::sector::SectorMetadata; +use subspace_proof_of_space::Table; +use thiserror::Error; +use tracing::{debug, info, trace, warn}; + +const FARMER_APP_INFO_RETRY_INTERVAL: Duration = Duration::from_millis(500); +/// Get piece retry attempts number. +const PIECE_GETTER_RETRY_NUMBER: NonZeroU16 = NonZeroU16::new(3).expect("Not zero; qed"); +/// Size of the cache of archived segments for the purposes of faster sector expiration checks. +const ARCHIVED_SEGMENTS_CACHE_SIZE: NonZeroUsize = NonZeroUsize::new(1000).expect("Not zero; qed"); + +/// Errors that happen during plotting +#[derive(Debug, Error)] +pub enum PlottingError { + /// Failed to retrieve farmer info + #[error("Failed to retrieve farmer info: {error}")] + FailedToGetFarmerInfo { + /// Lower-level error + error: node_client::Error, + }, + /// Failed to get segment header + #[error("Failed to get segment header: {error}")] + FailedToGetSegmentHeader { + /// Lower-level error + error: node_client::Error, + }, + /// Missing archived segment header + #[error("Missing archived segment header: {segment_index}")] + MissingArchivedSegmentHeader { + /// Segment index that was missing + segment_index: SegmentIndex, + }, + /// Failed to subscribe to archived segments + #[error("Failed to subscribe to archived segments: {error}")] + FailedToSubscribeArchivedSegments { + /// Lower-level error + error: node_client::Error, + }, + /// I/O error occurred + #[error("I/O error: {0}")] + Io(#[from] io::Error), + /// Low-level plotting error + #[error("Low-level plotting error: {0}")] + LowLevel(#[from] plotting::PlottingError), +} + +/// Starts plotting process. +/// +/// NOTE: Returned future is async, but does blocking operations and should be running in dedicated +/// thread. +#[allow(clippy::too_many_arguments)] +pub(super) async fn plotting( + public_key: PublicKey, + node_client: NC, + pieces_in_sector: u16, + sector_size: usize, + sector_metadata_size: usize, + mut metadata_header: PlotMetadataHeader, + mut metadata_header_mmap: MmapMut, + plot_file: Arc, + metadata_file: File, + sectors_metadata: Arc>>, + piece_getter: PG, + kzg: Kzg, + erasure_coding: ErasureCoding, + handlers: Arc, + modifying_sector_index: Arc>>, + mut sectors_to_plot: mpsc::Receiver<(SectorIndex, oneshot::Sender<()>)>, +) -> Result<(), PlottingError> +where + NC: NodeClient, + PG: PieceGetter + Send + 'static, + PosTable: Table, +{ + let mut table_generator = PosTable::generator(); + // TODO: Concurrency + while let Some((sector_index, _acknowledgement_sender)) = sectors_to_plot.next().await { + trace!(%sector_index, "Preparing to plot sector"); + + let mut sector = unsafe { + MmapOptions::new() + .offset((sector_index as usize * sector_size) as u64) + .len(sector_size) + .map_mut(&*plot_file)? + }; + let mut sector_metadata = unsafe { + MmapOptions::new() + .offset( + RESERVED_PLOT_METADATA + + (u64::from(sector_index) * sector_metadata_size as u64), + ) + .len(sector_metadata_size) + .map_mut(&metadata_file)? + }; + + let maybe_old_sector_metadata = sectors_metadata.read().get(sector_index as usize).cloned(); + + if maybe_old_sector_metadata.is_some() { + debug!(%sector_index, "Replotting sector"); + } else { + debug!(%sector_index, "Plotting sector"); + } + + // This `loop` is a workaround for edge-case in local setup if expiration is configured to + // 1. In that scenario we get replotting notification essentially straight from block import + // pipeline of the node, before block is imported. This can result in subsequent request for + // farmer app info to return old data, meaning we're replotting exactly the same sector that + // just expired. + let farmer_app_info = loop { + let farmer_app_info = node_client + .farmer_app_info() + .await + .map_err(|error| PlottingError::FailedToGetFarmerInfo { error })?; + + if let Some(old_sector_metadata) = &maybe_old_sector_metadata { + if farmer_app_info.protocol_info.history_size <= old_sector_metadata.history_size { + debug!( + current_history_size = %farmer_app_info.protocol_info.history_size, + old_sector_history_size = %old_sector_metadata.history_size, + "Latest protocol history size is not yet newer than old sector history \ + size, wait for a bit and try again" + ); + tokio::time::sleep(FARMER_APP_INFO_RETRY_INTERVAL).await; + continue; + } + } + + break farmer_app_info; + }; + + let plot_sector_fut = plot_sector::<_, PosTable>( + &public_key, + sector_index, + &piece_getter, + PieceGetterRetryPolicy::Limited(PIECE_GETTER_RETRY_NUMBER.get()), + &farmer_app_info.protocol_info, + &kzg, + &erasure_coding, + pieces_in_sector, + &mut sector, + &mut sector_metadata, + &mut table_generator, + ); + + // Inform others that this sector is being modified + modifying_sector_index.write().replace(sector_index); + + let plotted_sector = plot_sector_fut.await?; + sector.flush()?; + sector_metadata.flush()?; + + if sector_index + 1 > metadata_header.sector_count { + metadata_header.sector_count = sector_index + 1; + metadata_header_mmap.copy_from_slice(metadata_header.encode().as_slice()); + } + { + let mut sectors_metadata = sectors_metadata.write(); + // If exists then we're replotting, otherwise we create sector for the first time + if let Some(existing_sector_metadata) = sectors_metadata.get_mut(sector_index as usize) + { + *existing_sector_metadata = plotted_sector.sector_metadata.clone(); + } else { + sectors_metadata.push(plotted_sector.sector_metadata.clone()); + } + } + + let maybe_old_plotted_sector = maybe_old_sector_metadata.map(|old_sector_metadata| { + let old_history_size = old_sector_metadata.history_size; + + PlottedSector { + sector_id: plotted_sector.sector_id, + sector_index: plotted_sector.sector_index, + sector_metadata: old_sector_metadata, + piece_indexes: { + let mut piece_indexes = Vec::with_capacity(usize::from(pieces_in_sector)); + (PieceOffset::ZERO..) + .take(usize::from(pieces_in_sector)) + .map(|piece_offset| { + plotted_sector.sector_id.derive_piece_index( + piece_offset, + old_history_size, + farmer_app_info.protocol_info.max_pieces_in_sector, + farmer_app_info.protocol_info.recent_segments, + farmer_app_info.protocol_info.recent_history_fraction, + ) + }) + .collect_into(&mut piece_indexes); + piece_indexes + }, + } + }); + + // Inform others that this sector is no longer being modified + modifying_sector_index.write().take(); + + if maybe_old_plotted_sector.is_some() { + info!(%sector_index, "Sector replotted successfully"); + } else { + info!(%sector_index, "Sector plotted successfully"); + } + + handlers + .sector_plotted + .call_simple(&(plotted_sector, maybe_old_plotted_sector)); + } + + Ok(()) +} + +#[allow(clippy::too_many_arguments)] +pub(super) async fn plotting_scheduler( + public_key_hash: Blake2b256Hash, + sectors_indices_left_to_plot: Range, + target_sector_count: SectorIndex, + last_archived_segment_index: SegmentIndex, + min_sector_lifetime: HistorySize, + node_client: NC, + sectors_metadata: Arc>>, + sectors_to_plot_sender: mpsc::Sender<(SectorIndex, oneshot::Sender<()>)>, +) -> Result<(), BackgroundTaskError> +where + NC: NodeClient, +{ + // Create a proxy channel with atomically updatable last archived segment that + // allows to not buffer messages from RPC subscription, but also access the most + // recent value at any time + let last_archived_segment = Atomic::new( + node_client + .segment_headers(vec![last_archived_segment_index]) + .await + .map_err(|error| PlottingError::FailedToGetSegmentHeader { error })? + .into_iter() + .next() + .flatten() + .ok_or(PlottingError::MissingArchivedSegmentHeader { + segment_index: last_archived_segment_index, + })?, + ); + let (mut archived_segments_sender, archived_segments_receiver) = mpsc::channel(0); + archived_segments_sender + .try_send(()) + .expect("No messages were sent yet, there is capacity for one message; qed"); + + let read_archived_segments_notifications_fut = read_archived_segments_notifications( + &node_client, + &last_archived_segment, + archived_segments_sender, + ); + + let (sectors_to_plot_proxy_sender, sectors_to_plot_proxy_receiver) = mpsc::channel(0); + + let pause_plotting_if_node_not_synced_fut = pause_plotting_if_node_not_synced( + &node_client, + sectors_to_plot_proxy_receiver, + sectors_to_plot_sender, + ); + + let send_plotting_notifications_fut = send_plotting_notifications( + public_key_hash, + sectors_indices_left_to_plot, + target_sector_count, + min_sector_lifetime, + &node_client, + sectors_metadata, + &last_archived_segment, + archived_segments_receiver, + sectors_to_plot_proxy_sender, + ); + + select! { + result = pause_plotting_if_node_not_synced_fut.fuse() => { + result + } + result = read_archived_segments_notifications_fut.fuse() => { + result + } + result = send_plotting_notifications_fut.fuse() => { + result + } + } +} + +async fn read_archived_segments_notifications( + node_client: &NC, + last_archived_segment: &Atomic, + mut archived_segments_sender: mpsc::Sender<()>, +) -> Result<(), BackgroundTaskError> +where + NC: NodeClient, +{ + info!("Subscribing to archived segments"); + + let mut archived_segments_notifications = node_client + .subscribe_archived_segment_headers() + .await + .map_err(|error| PlottingError::FailedToSubscribeArchivedSegments { error })?; + + while let Some(segment_header) = archived_segments_notifications.next().await { + debug!(?segment_header, "New archived segment"); + if let Err(error) = node_client + .acknowledge_archived_segment_header(segment_header.segment_index()) + .await + { + debug!(%error, "Failed to acknowledge segment header"); + } + + last_archived_segment.store(segment_header, Ordering::SeqCst); + // Just a notification such that receiving side can read updated + // `last_archived_segment` (whatever it happens to be right now) + if let Err(error) = archived_segments_sender.try_send(()) { + if error.is_disconnected() { + return Ok(()); + } + } + } + + Ok(()) +} + +async fn pause_plotting_if_node_not_synced( + node_client: &NC, + sectors_to_plot_proxy_receiver: mpsc::Receiver<(SectorIndex, oneshot::Sender<()>)>, + mut sectors_to_plot_sender: mpsc::Sender<(SectorIndex, oneshot::Sender<()>)>, +) -> Result<(), BackgroundTaskError> +where + NC: NodeClient, +{ + let mut node_sync_status_change_notifications = node_client + .subscribe_node_sync_status_change() + .await + .map_err(|error| PlottingError::FailedToSubscribeArchivedSegments { error })?; + + let Some(mut node_sync_status) = node_sync_status_change_notifications.next().await else { + return Ok(()); + }; + + let mut sectors_to_plot_proxy_receiver = sectors_to_plot_proxy_receiver.fuse(); + let mut node_sync_status_change_notifications = node_sync_status_change_notifications.fuse(); + + 'outer: loop { + // Pause proxying of sectors to plot until we get notification that node is synced + if !node_sync_status.is_synced() { + info!("Node is not synced yet, pausing plotting until sync status changes"); + + loop { + if node_sync_status.is_synced() { + info!("Node is synced, resuming plotting"); + continue 'outer; + } + + match node_sync_status_change_notifications.next().await { + Some(new_node_sync_status) => { + node_sync_status = new_node_sync_status; + } + None => { + // Subscription ended, nothing left to do + return Ok(()); + } + } + } + } + + select! { + maybe_sector_to_plot = sectors_to_plot_proxy_receiver.next() => { + let Some(sector_to_plot) = maybe_sector_to_plot else { + // Subscription ended, nothing left to do + return Ok(()); + }; + + if let Err(_error) = sectors_to_plot_sender.send(sector_to_plot).await { + // Receiver disconnected, nothing left to do + return Ok(()); + } + }, + + maybe_node_sync_status = node_sync_status_change_notifications.next() => { + match maybe_node_sync_status { + Some(new_node_sync_status) => { + node_sync_status = new_node_sync_status; + } + None => { + // Subscription ended, nothing left to do + return Ok(()); + } + } + }, + } + } +} + +#[allow(clippy::too_many_arguments)] +async fn send_plotting_notifications( + public_key_hash: Blake2b256Hash, + sectors_indices_left_to_plot: Range, + target_sector_count: SectorIndex, + min_sector_lifetime: HistorySize, + node_client: &NC, + sectors_metadata: Arc>>, + last_archived_segment: &Atomic, + mut archived_segments_receiver: mpsc::Receiver<()>, + mut sectors_to_plot_sender: mpsc::Sender<(SectorIndex, oneshot::Sender<()>)>, +) -> Result<(), BackgroundTaskError> +where + NC: NodeClient, +{ + // Finish initial plotting if some sectors were not plotted fully yet + for sector_index in sectors_indices_left_to_plot { + let (acknowledgement_sender, acknowledgement_receiver) = oneshot::channel(); + if let Err(error) = sectors_to_plot_sender + .send((sector_index, acknowledgement_sender)) + .await + { + warn!(%error, "Failed to send sector index for initial plotting"); + return Ok(()); + } + + // We do not care if message was sent back or sender was just dropped + let _ = acknowledgement_receiver.await; + } + + let mut sectors_expire_at = HashMap::with_capacity(usize::from(target_sector_count)); + + let mut sector_indices_to_replot = Vec::new(); + let mut sectors_to_check = Vec::with_capacity(usize::from(target_sector_count)); + let mut archived_segment_commitments_cache = LruCache::new(ARCHIVED_SEGMENTS_CACHE_SIZE); + + while let Some(()) = archived_segments_receiver.next().await { + let archived_segment_header = last_archived_segment.load(Ordering::SeqCst); + trace!( + segment_index = %archived_segment_header.segment_index(), + "New archived segment received", + ); + + // It is fine to take a synchronous read lock here because the only time + // write lock is taken is during plotting, which we know doesn't happen + // right now. We copy data here because `.read()`'s guard is not `Send`. + sectors_metadata + .read() + .iter() + .map(|sector_metadata| (sector_metadata.sector_index, sector_metadata.history_size)) + .collect_into(&mut sectors_to_check); + for (sector_index, history_size) in sectors_to_check.drain(..) { + if let Some(sector_expire_at) = sectors_expire_at.get(§or_index) { + trace!( + %sector_index, + %history_size, + %sector_expire_at, + "Checking sector for expiration" + ); + // +1 means we will start replotting a bit before it actually expires to avoid + // storing expired sectors + if *sector_expire_at + <= (archived_segment_header.segment_index() + SegmentIndex::ONE) + { + debug!( + %sector_index, + %history_size, + %sector_expire_at, + "Sector expires soon #1, scheduling replotting" + ); + // Time to replot + sector_indices_to_replot.push(sector_index); + } + continue; + } + + if let Some(expiration_check_segment_index) = history_size + .sector_expiration_check(min_sector_lifetime) + .map(|expiration_check_history_size| expiration_check_history_size.segment_index()) + { + trace!( + %sector_index, + %history_size, + %expiration_check_segment_index, + "Determined sector expiration check segment index" + ); + let maybe_sector_expiration_check_segment_commitment = + if let Some(segment_commitment) = + archived_segment_commitments_cache.get(&expiration_check_segment_index) + { + Some(*segment_commitment) + } else { + node_client + .segment_headers(vec![expiration_check_segment_index]) + .await + .map_err(|error| PlottingError::FailedToGetSegmentHeader { error })? + .into_iter() + .next() + .flatten() + .map(|segment_header| { + let segment_commitment = segment_header.segment_commitment(); + + archived_segment_commitments_cache + .push(expiration_check_segment_index, segment_commitment); + segment_commitment + }) + }; + + if let Some(sector_expiration_check_segment_commitment) = + maybe_sector_expiration_check_segment_commitment + { + let sector_id = SectorId::new(public_key_hash, sector_index); + let expiration_history_size = sector_id + .derive_expiration_history_size( + history_size, + §or_expiration_check_segment_commitment, + min_sector_lifetime, + ) + .expect( + "Farmers internally stores correct history size in sector \ + metadata; qed", + ); + + trace!( + %sector_index, + %history_size, + sector_expire_at = %expiration_history_size.segment_index(), + "Determined sector expiration segment index" + ); + // +1 means we will start replotting a bit before it actually expires to avoid + // storing expired sectors + if expiration_history_size.segment_index() + <= (archived_segment_header.segment_index() + SegmentIndex::ONE) + { + debug!( + %sector_index, + %history_size, + sector_expire_at = %expiration_history_size.segment_index(), + "Sector expires soon #2, scheduling replotting" + ); + // Time to replot + sector_indices_to_replot.push(sector_index); + } else { + trace!( + %sector_index, + %history_size, + sector_expire_at = %expiration_history_size.segment_index(), + "Sector expires later, remembering sector expiration" + ); + // Store expiration so we don't have to recalculate it later + sectors_expire_at + .insert(sector_index, expiration_history_size.segment_index()); + } + } + } + } + + for sector_index in sector_indices_to_replot.iter() { + let (acknowledgement_sender, acknowledgement_receiver) = oneshot::channel(); + if let Err(error) = sectors_to_plot_sender + .send((*sector_index, acknowledgement_sender)) + .await + { + warn!(%error, "Failed to send sector index for replotting"); + return Ok(()); + } + + // We do not care if message was sent back or sender was just dropped + let _ = acknowledgement_receiver.await; + + sectors_expire_at.remove(sector_index); + } + + sector_indices_to_replot.clear(); + } + + Ok(()) +} diff --git a/crates/subspace-farmer/src/utils.rs b/crates/subspace-farmer/src/utils.rs index 370bccf1e64..cbf4d5b07c5 100644 --- a/crates/subspace-farmer/src/utils.rs +++ b/crates/subspace-farmer/src/utils.rs @@ -1,9 +1,6 @@ -pub mod farmer_piece_cache; +pub mod archival_storage_info; +pub mod archival_storage_pieces; pub mod farmer_piece_getter; -pub mod farmer_provider_storage; -pub mod node_piece_getter; -pub mod parity_db_store; -pub mod piece_cache; pub mod piece_validator; pub mod readers_and_pieces; #[cfg(test)] @@ -11,13 +8,46 @@ mod tests; use futures::channel::oneshot; use futures::channel::oneshot::Canceled; -use futures::future::Either; +use futures::future::{Either, Fuse, FusedFuture}; +use futures::FutureExt; use std::future::Future; use std::ops::Deref; +use std::pin::Pin; +use std::task::{Context, Poll}; use std::{io, thread}; use tokio::runtime::Handle; +use tokio::task; use tracing::debug; +/// Joins async join handle on drop +pub(crate) struct AsyncJoinOnDrop(Option>>); + +impl Drop for AsyncJoinOnDrop { + fn drop(&mut self) { + let handle = self.0.take().expect("Always called exactly once; qed"); + if !handle.is_terminated() { + task::block_in_place(move || { + let _ = Handle::current().block_on(handle); + }); + } + } +} + +impl AsyncJoinOnDrop { + // Create new instance + pub(crate) fn new(handle: task::JoinHandle) -> Self { + Self(Some(handle.fuse())) + } +} + +impl Future for AsyncJoinOnDrop { + type Output = Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(self.0.as_mut().expect("Only dropped in Drop impl; qed")).poll(cx) + } +} + /// Joins synchronous join handle on drop pub(crate) struct JoinOnDrop(Option>); diff --git a/crates/subspace-farmer/src/utils/archival_storage_info.rs b/crates/subspace-farmer/src/utils/archival_storage_info.rs new file mode 100644 index 00000000000..24353129ec7 --- /dev/null +++ b/crates/subspace-farmer/src/utils/archival_storage_info.rs @@ -0,0 +1,51 @@ +use cuckoofilter::{CuckooFilter, ExportedCuckooFilter}; +use parking_lot::Mutex; +use std::collections::hash_map::DefaultHasher; +use std::collections::HashMap; +use std::fmt; +use std::fmt::Debug; +use std::sync::Arc; +use subspace_core_primitives::PieceIndex; +use subspace_networking::libp2p::PeerId; +use subspace_networking::CuckooFilterDTO; + +#[derive(Clone, Default)] +pub struct ArchivalStorageInfo { + peers: Arc>>>, +} + +impl Debug for ArchivalStorageInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ArchivalStorageInfo") + .field("peers (len)", &self.peers.lock().len()) + .finish() + } +} + +impl ArchivalStorageInfo { + pub fn update_cuckoo_filter(&self, peer_id: PeerId, cuckoo_filter_dto: Arc) { + let exported_filter = ExportedCuckooFilter { + values: cuckoo_filter_dto.values.clone(), + length: cuckoo_filter_dto.length as usize, + }; + + let cuckoo_filter = CuckooFilter::from(exported_filter); + + self.peers.lock().insert(peer_id, cuckoo_filter); + } + + pub fn remove_peer_filter(&self, peer_id: &PeerId) -> bool { + self.peers.lock().remove(peer_id).is_some() + } + + pub fn peers_contain_piece(&self, piece_index: &PieceIndex) -> Vec { + let mut result = Vec::new(); + for (peer_id, cuckoo_filter) in self.peers.lock().iter() { + if cuckoo_filter.contains(piece_index) { + result.push(*peer_id) + } + } + + result + } +} diff --git a/crates/subspace-farmer/src/utils/archival_storage_pieces.rs b/crates/subspace-farmer/src/utils/archival_storage_pieces.rs new file mode 100644 index 00000000000..cdaee990b0c --- /dev/null +++ b/crates/subspace-farmer/src/utils/archival_storage_pieces.rs @@ -0,0 +1,87 @@ +use cuckoofilter::CuckooFilter; +use event_listener_primitives::{Bag, HandlerId}; +use parking_lot::Mutex; +use std::collections::hash_map::DefaultHasher; +use std::fmt; +use std::fmt::Debug; +use std::sync::Arc; +use subspace_core_primitives::PieceIndex; +use subspace_networking::{ + CuckooFilterDTO, CuckooFilterProvider, Notification, NotificationHandler, +}; +use tracing::warn; + +type NotificationEventHandler = Bag; + +// TODO: Consider renaming this type. +#[derive(Clone)] +pub struct ArchivalStoragePieces { + cuckoo_filter: Arc>>, + listeners: NotificationEventHandler, +} + +impl Debug for ArchivalStoragePieces { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ArchivalStoragePieces") + .field("cuckoo_filter (len)", &self.cuckoo_filter.lock().len()) + .finish() + } +} + +impl ArchivalStoragePieces { + pub fn new(capacity: usize) -> Self { + Self { + cuckoo_filter: Arc::new(Mutex::new(CuckooFilter::with_capacity(capacity))), + listeners: Bag::default(), + } + } + + pub fn add_pieces(&self, piece_indexes: &[PieceIndex]) { + let mut cuckoo_filter = self.cuckoo_filter.lock(); + let mut last_error = None; + + for piece_index in piece_indexes { + if let Err(err) = cuckoo_filter.add(piece_index) { + last_error.replace(err); + } + } + drop(cuckoo_filter); + + self.listeners.call_simple(&Notification); + + if let Some(err) = last_error { + warn!( + ?err, + "Cuckoo-filter returned an error during piece insertion." + ); + } + } + + pub fn delete_pieces(&self, piece_indexes: &[PieceIndex]) { + let mut cuckoo_filter = self.cuckoo_filter.lock(); + + for piece_index in piece_indexes { + cuckoo_filter.delete(piece_index); + } + drop(cuckoo_filter); + + self.listeners.call_simple(&Notification); + } +} + +impl CuckooFilterProvider for ArchivalStoragePieces { + fn cuckoo_filter(&self) -> CuckooFilterDTO { + let exported_filter = self.cuckoo_filter.lock().export(); + + CuckooFilterDTO { + values: exported_filter.values, + length: exported_filter.length as u64, + } + } + + fn on_notification(&self, handler: NotificationHandler) -> Option { + let handler_id = self.listeners.add(handler); + + Some(handler_id) + } +} diff --git a/crates/subspace-farmer/src/utils/farmer_piece_cache.rs b/crates/subspace-farmer/src/utils/farmer_piece_cache.rs deleted file mode 100644 index c837db36889..00000000000 --- a/crates/subspace-farmer/src/utils/farmer_piece_cache.rs +++ /dev/null @@ -1,85 +0,0 @@ -use crate::utils::parity_db_store::ParityDbStore; -use crate::utils::piece_cache::PieceCache; -use parking_lot::Mutex; -use std::num::NonZeroUsize; -use std::sync::Arc; -use subspace_core_primitives::Piece; -use subspace_networking::libp2p::kad::record::Key; -use subspace_networking::libp2p::PeerId; -use subspace_networking::UniqueRecordBinaryHeap; -use tracing::{debug, trace, warn}; - -/// Piece cache with limited size where pieces closer to provided peer ID are retained. -#[derive(Clone)] -pub struct FarmerPieceCache { - // Underlying unbounded store. - store: ParityDbStore, - // Maintains a heap to limit total number of entries. - heap: Arc>, -} - -impl FarmerPieceCache { - pub fn new( - store: ParityDbStore, - max_items_limit: NonZeroUsize, - peer_id: PeerId, - ) -> Self { - let mut heap = UniqueRecordBinaryHeap::new(peer_id, max_items_limit.get()); - - match store.iter() { - Ok(pieces_iter) => { - for (key, _) in pieces_iter { - let _ = heap.insert(key); - } - - if heap.size() > 0 { - debug!(size = heap.size(), "Local piece cache loaded."); - } else { - debug!("New local piece cache initialized."); - } - } - Err(err) => { - warn!(?err, "Local pieces from Parity DB iterator failed."); - } - } - - Self { - store, - heap: Arc::new(Mutex::new(heap)), - } - } - - pub fn size(&self) -> usize { - self.heap.lock().size() - } -} - -impl PieceCache for FarmerPieceCache { - type KeysIterator = impl IntoIterator; - - fn should_cache(&self, key: &Key) -> bool { - self.heap.lock().should_include_key(key) - } - - fn add_piece(&mut self, key: Key, piece: Piece) { - self.store.update([(&key, Some(piece.into()))]); - - let evicted_key = self.heap.lock().insert(key); - - if let Some(key) = evicted_key { - trace!(?key, "Record evicted from cache."); - - self.store.update([(&key, None)]); - } - } - - fn get_piece(&self, key: &Key) -> Option { - self.store.get(key) - } - - fn keys(&self) -> Self::KeysIterator { - // It is not great that we're cloning it, but at the same time dealing with self-referential - // lifetimes originating from the fact that mutex is used here proven to be challenging - self.heap.lock().keys().cloned().collect::>() - } -} diff --git a/crates/subspace-farmer/src/utils/farmer_piece_getter.rs b/crates/subspace-farmer/src/utils/farmer_piece_getter.rs index 6e8c6868bea..6dadf1f414e 100644 --- a/crates/subspace-farmer/src/utils/farmer_piece_getter.rs +++ b/crates/subspace-farmer/src/utils/farmer_piece_getter.rs @@ -1,30 +1,56 @@ -use crate::utils::piece_cache::PieceCache; +use crate::piece_cache::PieceCache; +use crate::utils::archival_storage_info::ArchivalStorageInfo; +use crate::utils::readers_and_pieces::ReadersAndPieces; use async_trait::async_trait; +use parking_lot::Mutex; +use std::collections::HashSet; use std::error::Error; use std::sync::Arc; use subspace_core_primitives::{Piece, PieceIndex}; use subspace_farmer_components::plotting::{PieceGetter, PieceGetterRetryPolicy}; +use subspace_networking::libp2p::kad::RecordKey; +use subspace_networking::libp2p::PeerId; use subspace_networking::utils::multihash::ToMultihash; +use subspace_networking::utils::piece_provider::{PieceProvider, PieceValidator, RetryPolicy}; +use subspace_networking::Node; -pub struct FarmerPieceGetter { - base_piece_getter: PG, - piece_cache: Arc>, +pub struct FarmerPieceGetter { + node: Node, + piece_provider: PieceProvider, + piece_cache: PieceCache, + archival_storage_info: ArchivalStorageInfo, + readers_and_pieces: Arc>>, } -impl FarmerPieceGetter { - pub fn new(base_piece_getter: PG, piece_cache: Arc>) -> Self { +impl FarmerPieceGetter { + pub fn new( + node: Node, + piece_provider: PieceProvider, + piece_cache: PieceCache, + archival_storage_info: ArchivalStorageInfo, + readers_and_pieces: Arc>>, + ) -> Self { Self { - base_piece_getter, + node, + piece_provider, piece_cache, + archival_storage_info, + readers_and_pieces, + } + } + + fn convert_retry_policy(retry_policy: PieceGetterRetryPolicy) -> RetryPolicy { + match retry_policy { + PieceGetterRetryPolicy::Limited(retries) => RetryPolicy::Limited(retries), + PieceGetterRetryPolicy::Unlimited => RetryPolicy::Unlimited, } } } #[async_trait] -impl PieceGetter for FarmerPieceGetter +impl PieceGetter for FarmerPieceGetter where - PG: PieceGetter + Send + Sync, - PC: PieceCache + Send + 'static, + PV: PieceValidator + Send + 'static, { async fn get_piece( &self, @@ -32,17 +58,55 @@ where retry_policy: PieceGetterRetryPolicy, ) -> Result, Box> { let piece_index_hash = piece_index.hash(); - let key = piece_index_hash.to_multihash().into(); + let key = RecordKey::from(piece_index_hash.to_multihash()); - if let Some(piece) = self.piece_cache.lock().await.get_piece(&key) { + if let Some(piece) = self.piece_cache.get_piece(key).await { return Ok(Some(piece)); } + // L2 piece acquisition let maybe_piece = self - .base_piece_getter - .get_piece(piece_index, retry_policy) + .piece_provider + .get_piece(piece_index, Self::convert_retry_policy(retry_policy)) .await?; - Ok(maybe_piece) + if maybe_piece.is_some() { + return Ok(maybe_piece); + } + + let maybe_read_piece_fut = self + .readers_and_pieces + .lock() + .as_ref() + .and_then(|readers_and_pieces| readers_and_pieces.read_piece(&piece_index_hash)); + + if let Some(read_piece_fut) = maybe_read_piece_fut { + if let Some(piece) = read_piece_fut.await { + return Ok(Some(piece)); + } + } + + // L1 piece acquisition + // TODO: consider using retry policy for L1 lookups as well. + let connected_peers = HashSet::::from_iter(self.node.connected_peers().await?); + + for peer_id in self + .archival_storage_info + .peers_contain_piece(&piece_index) + .iter() + { + if connected_peers.contains(peer_id) { + let maybe_piece = self + .piece_provider + .get_piece_from_peer(*peer_id, piece_index) + .await; + + if maybe_piece.is_some() { + return Ok(maybe_piece); + } + } + } + + Ok(None) } } diff --git a/crates/subspace-farmer/src/utils/farmer_provider_storage.rs b/crates/subspace-farmer/src/utils/farmer_provider_storage.rs deleted file mode 100644 index 9507ba770a5..00000000000 --- a/crates/subspace-farmer/src/utils/farmer_provider_storage.rs +++ /dev/null @@ -1,166 +0,0 @@ -use crate::utils::piece_cache::PieceCache; -use crate::utils::readers_and_pieces::ReadersAndPieces; -use parking_lot::Mutex; -use std::borrow::Cow; -use std::collections::HashSet; -use std::sync::Arc; -use subspace_core_primitives::{Blake2b256Hash, BLAKE2B_256_HASH_SIZE}; -use subspace_networking::libp2p::kad::record::Key; -use subspace_networking::libp2p::kad::ProviderRecord; -use subspace_networking::libp2p::multihash::Multihash; -use subspace_networking::libp2p::PeerId; -use subspace_networking::utils::multihash::{MultihashCode, ToMultihash}; -use subspace_networking::ProviderStorage; -use tracing::trace; - -#[derive(Clone)] -pub struct FarmerProviderStorage { - local_peer_id: PeerId, - readers_and_pieces: Arc>>, - persistent_provider_storage: PersistentProviderStorage, - piece_cache: LocalPieceCache, -} - -impl - FarmerProviderStorage -where - PersistentProviderStorage: ProviderStorage, - LocalPieceCache: PieceCache + Clone, -{ - pub fn new( - local_peer_id: PeerId, - readers_and_pieces: Arc>>, - persistent_provider_storage: PersistentProviderStorage, - piece_cache: LocalPieceCache, - ) -> Self { - Self { - local_peer_id, - readers_and_pieces, - persistent_provider_storage, - piece_cache, - } - } -} - -impl ProviderStorage - for FarmerProviderStorage -where - PersistentProviderStorage: ProviderStorage, - LocalPieceCache: PieceCache + Clone, -{ - type ProvidedIter<'a> = impl Iterator> - where - Self:'a; - - fn add_provider( - &self, - record: ProviderRecord, - ) -> subspace_networking::libp2p::kad::store::Result<()> { - // Local providers are implicit and should not be put into persistent storage - if record.provider != self.local_peer_id { - self.persistent_provider_storage.add_provider(record) - } else { - Ok(()) - } - } - - fn providers(&self, key: &Key) -> Vec { - let multihash = match Multihash::from_bytes(key.as_ref()) { - Ok(multihash) => multihash, - Err(error) => { - trace!( - ?key, - %error, - "Record is not a correct multihash, ignoring" - ); - return Vec::new(); - } - }; - - if multihash.code() != u64::from(MultihashCode::PieceIndexHash) { - trace!( - ?key, - code = %multihash.code(), - "Record is not a piece, ignoring" - ); - return Vec::new(); - } - - let piece_index_hash = - Blake2b256Hash::try_from(&multihash.digest()[..BLAKE2B_256_HASH_SIZE]) - .expect( - "Multihash has 64-byte digest, which is sufficient for 32-byte Blake2b \ - hash; qed", - ) - .into(); - - let mut provider_records = self.persistent_provider_storage.providers(key); - - // `ReadersAndPieces` is much cheaper than getting from piece cache, so try it first - if self - .readers_and_pieces - .lock() - .as_ref() - .expect("Should be populated at this point.") - .contains_piece(&piece_index_hash) - || self.piece_cache.get_piece(key).is_some() - { - // Note: We store our own provider records locally without local addresses - // to avoid redundant storage and outdated addresses. Instead these are - // acquired on demand when returning a `ProviderRecord` for the local node. - provider_records.push(ProviderRecord { - key: piece_index_hash.to_multihash().into(), - provider: self.local_peer_id, - expires: None, - addresses: Vec::new(), - }); - } - - provider_records - } - - fn provided(&self) -> Self::ProvidedIter<'_> { - // We are not using interior mutability in this context, so this is fine - #[allow(clippy::mutable_key_type)] - let provided_by_cache = self.piece_cache.keys().into_iter().collect::>(); - let provided_by_plots = self - .readers_and_pieces - .lock() - .as_ref() - .map(|readers_and_pieces| { - readers_and_pieces - .piece_index_hashes() - .filter_map(|hash| { - let key = hash.to_multihash().into(); - - if provided_by_cache.contains(&key) { - None - } else { - Some(key) - } - }) - .collect::>() - }) - .unwrap_or_default(); - - // Note: We store our own provider records locally without local addresses - // to avoid redundant storage and outdated addresses. Instead these are - // acquired on demand when returning a `ProviderRecord` for the local node. - provided_by_cache - .into_iter() - .chain(provided_by_plots) - .map(|key| ProviderRecord { - key, - provider: self.local_peer_id, - expires: None, - addresses: Vec::new(), - }) - .map(Cow::Owned) - .chain(self.persistent_provider_storage.provided()) - } - - fn remove_provider(&self, key: &Key, peer_id: &PeerId) { - self.persistent_provider_storage - .remove_provider(key, peer_id); - } -} diff --git a/crates/subspace-farmer/src/utils/node_piece_getter.rs b/crates/subspace-farmer/src/utils/node_piece_getter.rs deleted file mode 100644 index d70abc989a0..00000000000 --- a/crates/subspace-farmer/src/utils/node_piece_getter.rs +++ /dev/null @@ -1,38 +0,0 @@ -use async_trait::async_trait; -use std::error::Error; -use subspace_core_primitives::{Piece, PieceIndex}; -use subspace_farmer_components::plotting::{PieceGetter, PieceGetterRetryPolicy}; -use subspace_networking::utils::piece_provider::{PieceProvider, PieceValidator, RetryPolicy}; - -pub struct NodePieceGetter { - piece_provider: PieceProvider, -} - -impl NodePieceGetter { - pub fn new(piece_provider: PieceProvider) -> Self { - Self { piece_provider } - } -} - -fn convert_retry_policies(retry_policy: PieceGetterRetryPolicy) -> RetryPolicy { - match retry_policy { - PieceGetterRetryPolicy::Limited(retries) => RetryPolicy::Limited(retries), - PieceGetterRetryPolicy::Unlimited => RetryPolicy::Unlimited, - } -} - -#[async_trait] -impl PieceGetter for NodePieceGetter -where - PV: PieceValidator, -{ - async fn get_piece( - &self, - piece_index: PieceIndex, - retry_policy: PieceGetterRetryPolicy, - ) -> Result, Box> { - self.piece_provider - .get_piece(piece_index, convert_retry_policies(retry_policy)) - .await - } -} diff --git a/crates/subspace-farmer/src/utils/parity_db_store.rs b/crates/subspace-farmer/src/utils/parity_db_store.rs deleted file mode 100644 index 9bd4aca75b4..00000000000 --- a/crates/subspace-farmer/src/utils/parity_db_store.rs +++ /dev/null @@ -1,161 +0,0 @@ -use parity_db::{ColumnOptions, Db, Options}; -use std::error::Error; -use std::fmt::Debug; -use std::marker::PhantomData; -use std::path::Path; -use std::sync::Arc; -use tracing::{debug, trace, warn}; - -/// Generic key value store with ParityDB backend and iteration support -#[derive(Clone)] -pub struct ParityDbStore { - // Parity DB instance - db: Arc, - - // Type marker - marker: PhantomData<(StoreKey, StoreValue)>, -} - -impl ParityDbStore -where - StoreKey: AsRef<[u8]> + From> + Debug, - StoreValue: TryFrom>, - StoreValue::Error: Debug, -{ - const COLUMN_ID: u8 = 0; - - pub fn new(path: &Path) -> Result { - let mut options = Options::with_columns(path, 1); - options.columns = vec![ColumnOptions { - btree_index: true, - ..Default::default() - }]; - // We don't use stats - options.stats = false; - - let db = Db::open_or_create(&options)?; - - Ok(Self { - db: Arc::new(db), - marker: PhantomData, - }) - } - - pub fn get(&self, key: &StoreKey) -> Option { - let result = self.db.get(Self::COLUMN_ID, key.as_ref()); - - match result { - Ok(Some(data)) => { - trace!(?key, "Record loaded successfully from DB"); - - match data.try_into() { - Ok(piece) => Some(piece), - Err(err) => { - debug!(?key, ?err, "Parity DB record conversion error"); - - None - } - } - } - Ok(None) => { - trace!(?key, "No Parity DB record for given key"); - - None - } - Err(err) => { - debug!(?key, ?err, "Parity DB record storage error"); - - None - } - } - } - - pub fn update<'a, I>(&'a self, values: I) -> bool - where - I: IntoIterator>)> + Debug, - { - trace!(?values, "Updating records in DB"); - - let tx = values - .into_iter() - .map(|(key, value)| (Self::COLUMN_ID, key, value)); - - let result = self.db.commit(tx); - if let Err(error) = &result { - debug!(%error, "DB saving error."); - } - - result.is_ok() - } - - pub fn iter( - &self, - ) -> Result + '_, Box> { - let btree_iter = self.db.iter(Self::COLUMN_ID)?; - - Ok(ParityDbStoreIterator::new(btree_iter)?) - } -} - -/// Parity DB BTree iterator wrapper. -struct ParityDbStoreIterator<'a, StoreKey, StoreValue> { - iter: parity_db::BTreeIterator<'a>, - _value: PhantomData<(StoreKey, StoreValue)>, -} - -impl<'a, StoreKey, StoreValue> ParityDbStoreIterator<'a, StoreKey, StoreValue> { - /// Fallible iterator constructor. It requires inner DB BTreeIterator as a parameter. - fn new(mut iter: parity_db::BTreeIterator<'a>) -> parity_db::Result { - iter.seek_to_first()?; - - Ok(Self { - iter, - _value: PhantomData, - }) - } - - fn next_entry(&mut self) -> Option<(Vec, Vec)> { - match self.iter.next() { - Ok(value) => { - trace!("Parity DB store iterator succeeded"); - - value - } - Err(err) => { - warn!(?err, "Parity DB store iterator error"); - - None - } - } - } -} - -impl<'a, StoreKey, StoreValue> Iterator for ParityDbStoreIterator<'a, StoreKey, StoreValue> -where - StoreKey: TryFrom>, - StoreKey::Error: Debug, - StoreValue: TryFrom>, - StoreValue::Error: Debug, -{ - type Item = (StoreKey, StoreValue); - - fn next(&mut self) -> Option { - let (key, value) = self.next_entry()?; - - match StoreValue::try_from(value) { - Ok(piece) => match key.clone().try_into() { - Ok(key) => Some((key, piece)), - Err(err) => { - debug!(?key, ?err, "Parity DB store key conversion error"); - - None - } - }, - Err(err) => { - warn!(?key, ?err, "Parity DB store value conversion error"); - - None - } - } - } -} diff --git a/crates/subspace-farmer/src/utils/piece_cache.rs b/crates/subspace-farmer/src/utils/piece_cache.rs deleted file mode 100644 index 2daa8adc4db..00000000000 --- a/crates/subspace-farmer/src/utils/piece_cache.rs +++ /dev/null @@ -1,20 +0,0 @@ -use subspace_core_primitives::Piece; -use subspace_networking::libp2p::kad::record::Key; - -/// Defines persistent piece cache interface. -// TODO: This should be elsewhere, like in `subspace-dsn` -pub trait PieceCache: Sync + Send + 'static { - type KeysIterator: IntoIterator; - - /// Check whether key should be cached based on current cache size and key-to-peer-id distance. - fn should_cache(&self, key: &Key) -> bool; - - /// Add piece to the cache. - fn add_piece(&mut self, key: Key, piece: Piece); - - /// Get piece from the cache. - fn get_piece(&self, key: &Key) -> Option; - - /// Iterator over pieces in cache - fn keys(&self) -> Self::KeysIterator; -} diff --git a/crates/subspace-farmer/src/utils/piece_validator.rs b/crates/subspace-farmer/src/utils/piece_validator.rs index 0ed0c7ca4a6..089ac16a183 100644 --- a/crates/subspace-farmer/src/utils/piece_validator.rs +++ b/crates/subspace-farmer/src/utils/piece_validator.rs @@ -55,25 +55,21 @@ where let segment_commitment = match maybe_segment_commitment { Some(segment_commitment) => segment_commitment, None => { - let segment_commitments = match self - .node_client - .segment_commitments(vec![segment_index]) - .await - { - Ok(segment_commitments) => segment_commitments, - Err(error) => { - error!( - %piece_index, - ?error, - "Failed tor retrieve segment commitment from node" - ); - return None; - } - }; + let segment_headers = + match self.node_client.segment_headers(vec![segment_index]).await { + Ok(segment_headers) => segment_headers, + Err(error) => { + error!( + %piece_index, + ?error, + "Failed tor retrieve segment headers from node" + ); + return None; + } + }; - let segment_commitment = match segment_commitments.into_iter().next().flatten() - { - Some(segment_commitment) => segment_commitment, + let segment_commitment = match segment_headers.into_iter().next().flatten() { + Some(segment_header) => segment_header.segment_commitment(), None => { error!( %piece_index, diff --git a/crates/subspace-farmer/src/utils/readers_and_pieces.rs b/crates/subspace-farmer/src/utils/readers_and_pieces.rs index 987a5bd6823..81b7e00608e 100644 --- a/crates/subspace-farmer/src/utils/readers_and_pieces.rs +++ b/crates/subspace-farmer/src/utils/readers_and_pieces.rs @@ -1,27 +1,35 @@ use crate::single_disk_plot::piece_reader::PieceReader; +use crate::utils::archival_storage_pieces::ArchivalStoragePieces; +use std::collections::hash_map::Entry; use std::collections::HashMap; use std::future::Future; use subspace_core_primitives::{Piece, PieceIndexHash, PieceOffset, SectorIndex}; +use subspace_farmer_components::plotting::PlottedSector; use tracing::{trace, warn}; -#[derive(Debug, Copy, Clone)] -pub struct PieceDetails { - pub disk_farm_index: usize, - pub sector_index: SectorIndex, - pub piece_offset: PieceOffset, +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +struct PieceDetails { + disk_farm_index: u8, + sector_index: SectorIndex, + piece_offset: PieceOffset, } -/// Wrapper data structure for pieces plotted under multiple plots and corresponding piece readers. +/// Wrapper data structure for pieces plotted under multiple plots and corresponding piece readers, +/// it also maintains filter in given [`ArchivalStoragePieces`]. #[derive(Debug)] pub struct ReadersAndPieces { readers: Vec, - pieces: HashMap, + pieces: HashMap>, + archival_storage_pieces: ArchivalStoragePieces, } impl ReadersAndPieces { - pub fn new(readers: Vec, pieces: HashMap) -> Self { - // TODO: Verify that plot offset and piece offset are correct - Self { readers, pieces } + pub fn new(readers: Vec, archival_storage_pieces: ArchivalStoragePieces) -> Self { + Self { + readers, + pieces: HashMap::new(), + archival_storage_pieces, + } } /// Check if piece is known and can be retrieved @@ -37,8 +45,11 @@ impl ReadersAndPieces { &self, piece_index_hash: &PieceIndexHash, ) -> Option> + 'static> { - let piece_details = match self.pieces.get(piece_index_hash).copied() { - Some(piece_details) => piece_details, + let piece_details = match self.pieces.get(piece_index_hash) { + Some(piece_details) => piece_details + .first() + .copied() + .expect("Empty lists are not stored in the map; qed"), None => { trace!( ?piece_index_hash, @@ -47,8 +58,8 @@ impl ReadersAndPieces { return None; } }; - let mut reader = match self.readers.get(piece_details.disk_farm_index).cloned() { - Some(reader) => reader, + let mut reader = match self.readers.get(usize::from(piece_details.disk_farm_index)) { + Some(reader) => reader.clone(), None => { warn!(?piece_index_hash, ?piece_details, "Plot offset is invalid"); return None; @@ -62,15 +73,71 @@ impl ReadersAndPieces { }) } - /// Add more pieces from iterator. - /// - /// [`PieceDetails`] containing plot offset or piece offset will be silently ignored. - pub fn add_pieces(&mut self, pieces: I) - where - I: Iterator, - { - // TODO: Verify that plot offset and piece offset are correct - self.pieces.extend(pieces) + pub fn add_sector(&mut self, disk_farm_index: u8, plotted_sector: &PlottedSector) { + let mut new_piece_indices = Vec::new(); + + for (piece_offset, &piece_index) in + (PieceOffset::ZERO..).zip(plotted_sector.piece_indexes.iter()) + { + let piece_details = PieceDetails { + disk_farm_index, + sector_index: plotted_sector.sector_index, + piece_offset, + }; + + match self.pieces.entry(piece_index.hash()) { + Entry::Occupied(mut entry) => { + entry.get_mut().push(piece_details); + } + Entry::Vacant(entry) => { + entry.insert(vec![piece_details]); + new_piece_indices.push(piece_index); + } + } + } + + if !new_piece_indices.is_empty() { + self.archival_storage_pieces.add_pieces(&new_piece_indices); + } + } + + pub fn delete_sector(&mut self, disk_farm_index: u8, plotted_sector: &PlottedSector) { + let mut deleted_piece_indices = Vec::new(); + + for (piece_offset, &piece_index) in + (PieceOffset::ZERO..).zip(plotted_sector.piece_indexes.iter()) + { + let searching_piece_details = PieceDetails { + disk_farm_index, + sector_index: plotted_sector.sector_index, + piece_offset, + }; + + if let Entry::Occupied(mut entry) = self.pieces.entry(piece_index.hash()) { + let piece_details = entry.get_mut(); + if let Some(index) = + piece_details + .iter() + .enumerate() + .find_map(|(index, piece_details)| { + (piece_details == &searching_piece_details).then_some(index) + }) + { + piece_details.swap_remove(index); + } + + // We do not store empty lists + if piece_details.is_empty() { + entry.remove_entry(); + deleted_piece_indices.push(piece_index); + } + } + } + + if !deleted_piece_indices.is_empty() { + self.archival_storage_pieces + .delete_pieces(&deleted_piece_indices); + } } pub fn piece_index_hashes(&self) -> impl Iterator { diff --git a/crates/subspace-farmer/src/ws_rpc_server.rs b/crates/subspace-farmer/src/ws_rpc_server.rs deleted file mode 100644 index 5d5bd9bf208..00000000000 --- a/crates/subspace-farmer/src/ws_rpc_server.rs +++ /dev/null @@ -1,503 +0,0 @@ -use crate::object_mappings::{ObjectMappingError, ObjectMappings}; -use jsonrpsee::core::error::Error; -use jsonrpsee::proc_macros::rpc; -use parity_scale_codec::{Compact, CompactLen, Decode, Encode}; -use serde::{Deserialize, Serialize}; -use std::ops::{Deref, DerefMut}; -use std::sync::Arc; -use subspace_archiving::archiver::{Segment, SegmentItem}; -use subspace_core_primitives::objects::GlobalObject; -use subspace_core_primitives::{ - Blake2b256Hash, Piece, PieceIndex, PieceIndexHash, Record, RecordedHistorySegment, SegmentIndex, -}; -use tracing::{debug, error}; - -/// Maximum expected size of one object in bytes -const MAX_OBJECT_SIZE: usize = 5 * 1024 * 1024; - -/// Something that can be used to get decoded pieces by index -pub trait PieceGetter { - /// Get piece - fn get_piece(&self, piece_index: PieceIndex, piece_index_hash: PieceIndexHash) - -> Option; -} - -impl PieceGetter for Vec -where - PG: PieceGetter, -{ - fn get_piece( - &self, - piece_index: PieceIndex, - piece_index_hash: PieceIndexHash, - ) -> Option { - self.iter() - .find_map(|piece_getter| piece_getter.get_piece(piece_index, piece_index_hash)) - } -} - -/// Same as [`Piece`], but serializes/deserialized to/from hex string -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct HexPiece(#[serde(with = "hex::serde")] Vec); - -impl From for HexPiece { - #[inline] - fn from(piece: Piece) -> Self { - HexPiece(piece.into()) - } -} - -impl From for Piece { - #[inline] - fn from(piece: HexPiece) -> Self { - piece - .0 - .as_slice() - .try_into() - .expect("Internal piece is always has correct length; qed") - } -} - -impl Deref for HexPiece { - type Target = [u8]; - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for HexPiece { - #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl AsRef<[u8]> for HexPiece { - #[inline] - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -impl AsMut<[u8]> for HexPiece { - #[inline] - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } -} - -/// Similar to [`Blake2b256Hash`], but serializes/deserialized to/from hex string -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub struct HexBlake2b256Hash(#[serde(with = "hex::serde")] Blake2b256Hash); - -impl From for HexBlake2b256Hash { - #[inline] - fn from(hash: Blake2b256Hash) -> Self { - HexBlake2b256Hash(hash) - } -} - -impl From for Blake2b256Hash { - #[inline] - fn from(piece: HexBlake2b256Hash) -> Self { - piece.0 - } -} - -impl Deref for HexBlake2b256Hash { - type Target = [u8]; - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for HexBlake2b256Hash { - #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl AsRef<[u8]> for HexBlake2b256Hash { - #[inline] - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -impl AsMut<[u8]> for HexBlake2b256Hash { - #[inline] - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } -} - -/// Object stored inside in the history of the blockchain -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Object { - /// Piece index where object is contained (at least its beginning, might not fit fully) - piece_index: PieceIndex, - /// Offset of the object - offset: u32, - /// The data object contains for convenience - #[serde(with = "hex::serde")] - data: Vec, -} - -#[rpc(server, client)] -pub trait Rpc { - /// Get single piece by its index - #[method(name = "getPiece", blocking)] - fn get_piece(&self, piece_index: PieceIndex) -> Result, Error>; - - /// Find object by its ID - #[method(name = "findObject", blocking)] - fn find_object(&self, object_id: HexBlake2b256Hash) -> Result, Error>; -} - -/// Farmer RPC server implementation. -pub struct RpcServerImpl { - record_size: u32, - pieces_in_segment: u32, - piece_getter: Arc, - object_mappings: Arc>, -} - -// TODO: Reconstruction here is a bit incorrect: it doesn't account for source/parity interleaving -// and raw records -impl RpcServerImpl { - pub fn new( - record_size: u32, - recorded_history_segment_size: u32, - piece_getter: Arc, - object_mappings: Arc>, - ) -> Self { - Self { - record_size, - pieces_in_segment: recorded_history_segment_size / record_size * 2, - piece_getter, - object_mappings, - } - } - - /// Assemble object that starts at `piece_index` at `offset` by reading necessary pieces from - /// plot and putting necessary bytes together. - fn assemble_object( - &self, - piece_index: PieceIndex, - offset: u32, - object_id: &str, - ) -> Result, Error> { - // Try fast object assembling - if let Some(data) = self.assemble_object_fast(piece_index, offset)? { - return Ok(data); - } - - self.assemble_object_regular(piece_index, offset, object_id) - } - - /// Fast object assembling in case object doesn't cross piece (super fast) or segment (just - /// fast) boundary, returns `Ok(None)` if fast retrieval possibility is not guaranteed. - fn assemble_object_fast( - &self, - piece_index: PieceIndex, - offset: u32, - ) -> Result>, Error> { - // We care if the offset is before the last 2 bytes of a piece because if not we might be - // able to do very fast object retrieval without assembling and processing the whole - // segment. `-2` is because last 2 bytes might contain padding if a piece is the last piece - // in the segment. - let before_last_two_bytes = offset <= self.record_size - 1 - 2; - - // We care about whether piece index points to the last data piece in the segment because - // if not we might be able to do very fast object retrieval without assembling and - // processing the whole segment. - let last_data_piece_in_segment = { - let piece_position_in_segment = piece_index.position(); - let last_piece_position_in_segment = self.pieces_in_segment / 2 - 1; - - piece_position_in_segment >= last_piece_position_in_segment - }; - - // How much bytes are definitely available starting at `piece_index` and `offset` without - // crossing segment boundary - let bytes_available_in_segment = { - let data_shards = RecordedHistorySegment::NUM_RAW_RECORDS as u32; - let piece_position = piece_index.position(); - - // `-2` is because last 2 bytes might contain padding if a piece is the last piece in - // the segment. - u64::from(data_shards - piece_position) * Record::SIZE as u64 - u64::from(offset) - 2 - }; - - if last_data_piece_in_segment && !before_last_two_bytes { - // Fast retrieval possibility is not guaranteed - return Ok(None); - } - - // Cache of read pieces that were already read, starting with piece at index `piece_index` - let mut read_records_data = Vec::::with_capacity(self.record_size as usize * 2); - let mut next_piece_index = piece_index; - - let piece = self.read_and_decode_piece(next_piece_index)?; - next_piece_index += PieceIndex::ONE; - read_records_data.extend_from_slice(piece.record().as_ref()); - - // Let's see how many bytes encode compact length encoding of the data, see - // https://docs.substrate.io/v3/advanced/scale-codec/#compactgeneral-integers for - // details. - let data_length_bytes_length: u32 = match read_records_data[offset as usize] % 4 { - 0 => 1, - 1 => 2, - 2 => 4, - _ => { - let error_string = format!( - "Invalid data length prefix found: 0x{:02x}", - read_records_data[offset as usize] - ); - error!(error = %error_string); - - return Err(Error::Custom(error_string)); - } - }; - - // Same as `before_last_two_bytes`, but accounts for compact encoding of data length - let length_before_last_two_bytes = - offset + data_length_bytes_length < self.record_size - 1 - 2; - // Similar to `length_before_last_two_bytes`, but uses the whole recordif needed - let length_before_record_end = offset + data_length_bytes_length < self.record_size - 1; - - let data_length_result = if length_before_last_two_bytes { - Compact::::decode(&mut &read_records_data[offset as usize..]) - } else if !last_data_piece_in_segment { - if !length_before_record_end { - // Need the next piece to read the length of data - let piece = self.read_and_decode_piece(next_piece_index)?; - next_piece_index += PieceIndex::ONE; - read_records_data.extend_from_slice(piece.record().as_ref()); - } - - Compact::::decode(&mut &read_records_data[offset as usize..]) - } else { - // Super fast read is not possible - return Ok(None); - }; - - let Compact(data_length) = data_length_result.map_err(|error| { - let error_string = format!("Failed to read object data length: {error}"); - error!(error = %error_string); - - Error::Custom(error_string) - })?; - - if u64::from(data_length_bytes_length + data_length) > bytes_available_in_segment { - // Not enough data without crossing segment boundary - return Ok(None); - } - - let mut data = - read_records_data[offset as usize + data_length_bytes_length as usize..].to_vec(); - drop(read_records_data); - - // Read more pieces until we have enough data - while data.len() <= data_length as usize { - let piece = self.read_and_decode_piece(next_piece_index)?; - next_piece_index += PieceIndex::ONE; - data.extend_from_slice(&piece[..self.record_size as usize]); - } - - // Trim the excess - data.truncate(data_length as usize); - - Ok(Some(data)) - } - - /// Assemble object that can cross segment boundary, which requires assembling and iterating - /// over full segments. - fn assemble_object_regular( - &self, - piece_index: PieceIndex, - offset: u32, - object_id: &str, - ) -> Result, Error> { - let segment_index = piece_index.segment_index(); - let piece_position_in_segment = piece_index.position(); - let offset_in_segment = - u64::from(piece_position_in_segment) * Record::SIZE as u64 + u64::from(offset); - - let mut data = { - let Segment::V0 { items } = self.read_segment(segment_index)?; - // Unconditional progress is enum variant + compact encoding of number of elements - let mut progress = 1 + Compact::compact_len(&(items.len() as u64)); - let segment_item = items - .into_iter() - .find(|item| { - // Add number of bytes in encoded version of segment item - progress += item.encoded_size(); - - // Our data is within another segment item, which will have wrapping data - // structure, hence strictly `>` here - progress > offset_in_segment as usize - }) - .ok_or_else(|| { - let error_string = format!( - "Failed to find item at offset {offset_in_segment} in segment \ - {segment_index} for object {object_id}" - ); - error!(error = %error_string); - - Error::Custom(error_string) - })?; - - match segment_item { - SegmentItem::Block { bytes, .. } - | SegmentItem::BlockStart { bytes, .. } - | SegmentItem::BlockContinuation { bytes, .. } => { - // Rewind back progress to the beginning of the number of bytes - progress -= bytes.len(); - // Get a chunk of the bytes starting at the position we care about - Vec::from(&bytes[offset_in_segment as usize - progress..]) - } - segment_item => { - error!( - ?segment_item, - offset_in_segment, - %segment_index, - object_id, - "Unexpected segment item", - ); - - return Err(Error::Custom(format!( - "Unexpected segment item at offset {offset_in_segment} in segment \ - {segment_index} for object {object_id}" - ))); - } - } - }; - - if let Ok(data) = Vec::::decode(&mut data.as_slice()) { - return Ok(data); - } - - for segment_index in segment_index + SegmentIndex::ONE.. { - let Segment::V0 { items } = self.read_segment(segment_index)?; - for segment_item in items { - if let SegmentItem::BlockContinuation { bytes, .. } = segment_item { - data.extend_from_slice(&bytes); - - if let Ok(data) = Vec::::decode(&mut data.as_slice()) { - return Ok(data); - } - } - } - - if data.len() >= MAX_OBJECT_SIZE { - break; - } - } - - error!(object_id, "Read max object size for object without success"); - - Err(Error::Custom( - "Read max object size for object without success".to_string(), - )) - } - - /// Read the whole segment by its index (just records, skipping witnesses) - fn read_segment(&self, segment_index: SegmentIndex) -> Result { - let mut segment_bytes = - Vec::::with_capacity((self.pieces_in_segment * self.record_size) as usize); - - for piece_index in - (segment_index.first_piece_index()..).take(RecordedHistorySegment::NUM_RAW_RECORDS) - { - let piece = self.read_and_decode_piece(piece_index)?; - segment_bytes.extend_from_slice(piece.record().as_ref()); - } - - let segment = Segment::decode(&mut segment_bytes.as_slice()).map_err(|error| { - error!( - index = %segment_index, - %error, - "Failed to decode segment of archival history on retrieval", - ); - - Error::Custom(format!( - "Failed to decode segment {segment_index} of archival history on retrieval" - )) - })?; - - Ok(segment) - } - - /// Read and decode the whole piece - fn read_and_decode_piece(&self, piece_index: PieceIndex) -> Result { - let piece_getter = self.piece_getter.clone(); - piece_getter - .get_piece(piece_index, piece_index.hash()) - .ok_or_else(|| { - Error::Custom("Object mapping found, but reading piece failed".to_string()) - }) - } -} - -impl RpcServer for RpcServerImpl { - fn get_piece(&self, piece_index: PieceIndex) -> Result, Error> { - let piece_getter = self.piece_getter.clone(); - piece_getter - .get_piece(piece_index, piece_index.hash()) - .map(HexPiece::from) - .map(Some) - .ok_or_else(|| Error::Custom("Piece not found".to_string())) - } - - /// Find object by its ID - fn find_object(&self, object_id: HexBlake2b256Hash) -> Result, Error> { - let global_object_handle = || -> Result, ObjectMappingError> { - for object_mappings in self.object_mappings.iter() { - let maybe_global_object = object_mappings.retrieve(&object_id.into())?; - - if let Some(global_object) = maybe_global_object { - return Ok(Some(global_object)); - } - } - - Ok(None) - }; - - let object_id_string = hex::encode(object_id); - - let global_object = global_object_handle().map_err(|error| { - error!( - object_id = %object_id_string, - %error, - "Object mapping retrieving failed", - ); - - Error::Custom("Failed to find an object due to internal error".to_string()) - })?; - - let global_object = match global_object { - Some(global_object) => global_object, - None => { - debug!(object_id = %object_id_string, "Object not found"); - - return Ok(None); - } - }; - - let piece_index = global_object.piece_index(); - let offset = global_object.offset(); - - let data = self.assemble_object(piece_index, offset, &object_id_string)?; - - Ok(Some(Object { - piece_index, - offset, - data, - })) - } -} diff --git a/crates/subspace-fraud-proof/Cargo.toml b/crates/subspace-fraud-proof/Cargo.toml index 951ad38ead4..af92e88d8fe 100644 --- a/crates/subspace-fraud-proof/Cargo.toml +++ b/crates/subspace-fraud-proof/Cargo.toml @@ -12,39 +12,36 @@ description = "Subspace fraud proof utilities" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.6.3", features = ["derive"] } domain-runtime-primitives = { version = "0.1.0", path = "../../domains/primitives/runtime" } domain-block-preprocessor = { version = "0.1.0", path = "../../domains/client/block-preprocessor" } -frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } futures = "0.3.28" hash-db = "0.16.0" -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../sp-domains" } sp-domain-digests = { version = "0.1.0", path = "../../domains/primitives/digests" } sp-messenger = { version = "0.1.0", path = "../../domains/primitives/messenger" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", path = "../sp-settlement" } -sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -subspace-wasm-tools = { version = "0.1.0", path = "../subspace-wasm-tools" } -system-runtime-primitives = { version = "0.1.0", path = "../../domains/primitives/system-runtime" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } tracing = "0.1.37" [dev-dependencies] domain-block-builder = { version = "0.1.0", path = "../../domains/client/block-builder" } domain-test-service = { version = "0.1.0", path = "../../domains/test/service" } -pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } pallet-domains = { version = "0.1.0", path = "../../crates/pallet-domains" } -sc-cli = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-keyring = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-cli = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-keyring = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-test-client = { version = "0.1.0", path = "../../test/subspace-test-client" } subspace-test-runtime = { version = "0.1.0", path = "../../test/subspace-test-runtime" } subspace-test-service = { version = "0.1.0", path = "../../test/subspace-test-service" } subspace-runtime-primitives = { version = "0.1.0", path = "../../crates/subspace-runtime-primitives" } -substrate-test-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +substrate-test-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } tempfile = "3.4.0" tokio = "1.28.2" diff --git a/crates/subspace-fraud-proof/src/domain_extrinsics_builder.rs b/crates/subspace-fraud-proof/src/domain_extrinsics_builder.rs deleted file mode 100644 index 1155665fead..00000000000 --- a/crates/subspace-fraud-proof/src/domain_extrinsics_builder.rs +++ /dev/null @@ -1,107 +0,0 @@ -//! This module defines a trait for building the domain extrinsics from the original -//! primary block and provides the implementation for both system domain and core domain. - -use domain_block_preprocessor::runtime_api_light::RuntimeApiLight; -use domain_block_preprocessor::SystemDomainBlockPreprocessor; -use domain_runtime_primitives::opaque::Block; -use sc_client_api::{BlockBackend, HeaderBackend}; -use sp_api::ProvideRuntimeApi; -use sp_core::traits::CodeExecutor; -use sp_core::H256; -use sp_domains::{DomainId, ExecutorApi}; -use sp_runtime::traits::Block as BlockT; -use sp_settlement::SettlementApi; -use std::marker::PhantomData; -use std::sync::Arc; - -/// Trait to build the extrinsics of domain block derived from the original primary block. -pub trait BuildDomainExtrinsics { - /// Returns the final list of encoded domain-specific extrinsics. - fn build_domain_extrinsics( - &self, - domain_id: DomainId, - primary_hash: PBlock::Hash, - domain_runtime: Vec, - ) -> sp_blockchain::Result>>; -} - -/// Utility to build the system domain extrinsics. -pub struct SystemDomainExtrinsicsBuilder { - primary_chain_client: Arc, - executor: Arc, - _phantom: PhantomData, -} - -impl Clone for SystemDomainExtrinsicsBuilder { - fn clone(&self) -> Self { - Self { - primary_chain_client: self.primary_chain_client.clone(), - executor: self.executor.clone(), - _phantom: self._phantom, - } - } -} - -impl SystemDomainExtrinsicsBuilder -where - PBlock: BlockT, - PBlock::Hash: From, - PClient: HeaderBackend - + BlockBackend - + ProvideRuntimeApi - + Send - + Sync - + 'static, - PClient::Api: ExecutorApi - + SettlementApi, - Executor: CodeExecutor, -{ - /// Constructs a new instance of [`SystemDomainExtrinsicsBuilder`]. - pub fn new(primary_chain_client: Arc, executor: Arc) -> Self { - Self { - primary_chain_client, - executor, - _phantom: Default::default(), - } - } - - fn build_system_domain_extrinsics( - &self, - primary_hash: PBlock::Hash, - runtime_code: Vec, - ) -> sp_blockchain::Result>> { - let system_runtime_api_light = - RuntimeApiLight::new(self.executor.clone(), runtime_code.into()); - let domain_extrinsics = SystemDomainBlockPreprocessor::::new( - self.primary_chain_client.clone(), - system_runtime_api_light, - ) - .preprocess_primary_block_for_verifier(primary_hash)?; - Ok(domain_extrinsics) - } -} - -impl BuildDomainExtrinsics - for SystemDomainExtrinsicsBuilder -where - PBlock: BlockT, - PBlock::Hash: From, - PClient: HeaderBackend - + BlockBackend - + ProvideRuntimeApi - + Send - + Sync - + 'static, - PClient::Api: ExecutorApi - + SettlementApi, - Executor: CodeExecutor, -{ - fn build_domain_extrinsics( - &self, - _domain_id: DomainId, - primary_hash: ::Hash, - domain_runtime: Vec, - ) -> sp_blockchain::Result>> { - self.build_system_domain_extrinsics(primary_hash, domain_runtime) - } -} diff --git a/crates/subspace-fraud-proof/src/domain_runtime_code.rs b/crates/subspace-fraud-proof/src/domain_runtime_code.rs index aa0084b3ee2..53b4ef19313 100644 --- a/crates/subspace-fraud-proof/src/domain_runtime_code.rs +++ b/crates/subspace-fraud-proof/src/domain_runtime_code.rs @@ -2,7 +2,7 @@ use codec::{Decode, Encode}; use sp_api::ProvideRuntimeApi; use sp_core::traits::FetchRuntimeCode; use sp_domains::fraud_proof::VerificationError; -use sp_domains::{DomainId, ExecutorApi}; +use sp_domains::{DomainId, DomainsApi}; use sp_runtime::traits::Block as BlockT; use std::borrow::Cow; use std::sync::Arc; @@ -18,7 +18,7 @@ impl<'a> FetchRuntimeCode for RuntimeCodeFetcher<'a> { } pub(crate) struct DomainRuntimeCode { - pub(crate) wasm_bundle: Cow<'static, [u8]>, + pub(crate) wasm_bundle: Vec, } impl DomainRuntimeCode { @@ -29,31 +29,25 @@ impl DomainRuntimeCode { } } -pub(crate) fn retrieve_domain_runtime_code( +pub(crate) fn retrieve_domain_runtime_code( domain_id: DomainId, - at: PBlock::Hash, - primary_chain_client: &Arc, + at: CBlock::Hash, + consensus_client: &Arc, ) -> Result where - PBlock: BlockT, + CBlock: BlockT, + Number: Encode + Decode, Hash: Encode + Decode, - PClient: ProvideRuntimeApi, - PClient::Api: ExecutorApi, + CClient: ProvideRuntimeApi, + CClient::Api: DomainsApi, { - let system_wasm_bundle = primary_chain_client + let wasm_bundle = consensus_client .runtime_api() - .system_domain_wasm_bundle(at) - .map_err(VerificationError::RuntimeApi)?; - - let wasm_bundle = { - if domain_id.is_system() { - system_wasm_bundle - } else { - return Err(VerificationError::RuntimeCode(format!( - "No runtime code for {domain_id:?}" - ))); - } - }; + .domain_runtime_code(at, domain_id) + .map_err(VerificationError::RuntimeApi)? + .ok_or_else(|| { + VerificationError::RuntimeCode(format!("No runtime code for {domain_id:?}")) + })?; Ok(DomainRuntimeCode { wasm_bundle }) } diff --git a/crates/subspace-fraud-proof/src/invalid_state_transition_proof.rs b/crates/subspace-fraud-proof/src/invalid_state_transition_proof.rs index d713c8dc355..d193b5f355f 100644 --- a/crates/subspace-fraud-proof/src/invalid_state_transition_proof.rs +++ b/crates/subspace-fraud-proof/src/invalid_state_transition_proof.rs @@ -5,7 +5,6 @@ //! block execution, block execution hooks (`initialize_block` and `finalize_block`) and any //! specific extrinsic execution are supported. -use crate::domain_extrinsics_builder::BuildDomainExtrinsics; use crate::verifier_api::VerifierApi; use codec::{Codec, Decode, Encode}; use domain_runtime_primitives::opaque::Block; @@ -14,11 +13,10 @@ use sc_client_api::backend; use sp_api::{ProvideRuntimeApi, StorageProof}; use sp_core::traits::{CodeExecutor, RuntimeCode}; use sp_core::H256; -use sp_domain_digests::AsPredigest; use sp_domains::fraud_proof::{ExecutionPhase, InvalidStateTransitionProof, VerificationError}; -use sp_domains::ExecutorApi; +use sp_domains::DomainsApi; use sp_runtime::traits::{BlakeTwo256, Block as BlockT, HashFor, Header as HeaderT, NumberFor}; -use sp_runtime::{Digest, DigestItem}; +use sp_runtime::Digest; use sp_state_machine::backend::AsTrieBackend; use sp_state_machine::{TrieBackend, TrieBackendBuilder, TrieBackendStorage}; use sp_trie::DBValue; @@ -182,78 +180,51 @@ where } /// Invalid state transition proof verifier. -pub struct InvalidStateTransitionProofVerifier< - PBlock, - PClient, - Exec, - Hash, - VerifierClient, - DomainExtrinsicsBuilder, -> { - primary_chain_client: Arc, +pub struct InvalidStateTransitionProofVerifier { + consensus_client: Arc, executor: Exec, verifier_client: VerifierClient, - domain_extrinsics_builder: DomainExtrinsicsBuilder, - _phantom: PhantomData<(PBlock, Hash)>, + _phantom: PhantomData<(CBlock, Hash)>, } -impl Clone - for InvalidStateTransitionProofVerifier< - PBlock, - PClient, - Exec, - Hash, - VerifierClient, - DomainExtrinsicsBuilder, - > +impl Clone + for InvalidStateTransitionProofVerifier where Exec: Clone, VerifierClient: Clone, - DomainExtrinsicsBuilder: Clone, { fn clone(&self) -> Self { Self { - primary_chain_client: self.primary_chain_client.clone(), + consensus_client: self.consensus_client.clone(), executor: self.executor.clone(), verifier_client: self.verifier_client.clone(), - domain_extrinsics_builder: self.domain_extrinsics_builder.clone(), _phantom: self._phantom, } } } -impl - InvalidStateTransitionProofVerifier< - PBlock, - PClient, - Exec, - Hash, - VerifierClient, - DomainExtrinsicsBuilder, - > +impl + InvalidStateTransitionProofVerifier where - PBlock: BlockT, - H256: Into, - PClient: ProvideRuntimeApi + Send + Sync, - PClient::Api: ExecutorApi, + CBlock: BlockT, + H256: Into, + CClient: ProvideRuntimeApi + Send + Sync, + CClient::Api: DomainsApi, Exec: CodeExecutor + Clone + 'static, Hash: Encode + Decode, VerifierClient: VerifierApi, - DomainExtrinsicsBuilder: BuildDomainExtrinsics, { /// Constructs a new instance of [`InvalidStateTransitionProofVerifier`]. pub fn new( - primary_chain_client: Arc, + consensus_client: Arc, executor: Exec, verifier_client: VerifierClient, - domain_extrinsics_builder: DomainExtrinsicsBuilder, ) -> Self { Self { - primary_chain_client, + consensus_client, executor, verifier_client, - domain_extrinsics_builder, - _phantom: PhantomData::<(PBlock, Hash)>, + _phantom: PhantomData::<(CBlock, Hash)>, } } @@ -271,7 +242,7 @@ where let InvalidStateTransitionProof { domain_id, parent_number, - primary_parent_hash, + consensus_parent_hash, pre_state_root, post_state_root, proof, @@ -281,8 +252,8 @@ where let domain_runtime_code = crate::domain_runtime_code::retrieve_domain_runtime_code( *domain_id, - (*primary_parent_hash).into(), - &self.primary_chain_client, + (*consensus_parent_hash).into(), + &self.consensus_client, )?; let runtime_code = RuntimeCode { @@ -299,45 +270,19 @@ where let parent_number = >::decode(&mut parent_number.encode().as_slice())?; - let primary_number = parent_number + 1; - let digest = if domain_id.is_system() { - let primary_hash = self - .verifier_client - .primary_hash(*domain_id, primary_number)?; - Digest { - logs: vec![DigestItem::primary_block_info::, _>(( - primary_number, - primary_hash, - ))], - } - } else { - Default::default() - }; + let consensus_block_number = parent_number + 1; let new_header = ::Header::new( - primary_number, + consensus_block_number, Default::default(), Default::default(), parent_hash, - digest, + Digest::default(), ); new_header.encode() } - ExecutionPhase::ApplyExtrinsic(extrinsic_index) => { - let primary_hash = self - .verifier_client - .primary_hash(*domain_id, parent_number + 1)?; - let domain_extrinsics = self - .domain_extrinsics_builder - .build_domain_extrinsics( - *domain_id, - primary_hash.into(), - domain_runtime_code.wasm_bundle.to_vec(), - ) - .map_err(|_| VerificationError::FailedToBuildDomainExtrinsics)?; - domain_extrinsics - .into_iter() - .nth(*extrinsic_index as usize) - .ok_or(VerificationError::DomainExtrinsicNotFound(*extrinsic_index))? + ExecutionPhase::ApplyExtrinsic(_extrinsic_index) => { + // TODO: Provide the tx Merkle proof and get data from there + Vec::new() } ExecutionPhase::FinalizeBlock { .. } => Vec::new(), }; @@ -354,7 +299,7 @@ where .map_err(VerificationError::BadProof)?; let new_post_state_root = - execution_phase.decode_execution_result::(execution_result)?; + execution_phase.decode_execution_result::(execution_result)?; let new_post_state_root = H256::decode(&mut new_post_state_root.encode().as_slice())?; if new_post_state_root == *post_state_root { @@ -377,25 +322,16 @@ pub trait VerifyInvalidStateTransitionProof { ) -> Result<(), VerificationError>; } -impl - VerifyInvalidStateTransitionProof - for InvalidStateTransitionProofVerifier< - PBlock, - C, - Exec, - Hash, - VerifierClient, - DomainExtrinsicsBuilder, - > +impl VerifyInvalidStateTransitionProof + for InvalidStateTransitionProofVerifier where - PBlock: BlockT, - H256: Into, - C: ProvideRuntimeApi + Send + Sync, - C::Api: ExecutorApi, + CBlock: BlockT, + H256: Into, + C: ProvideRuntimeApi + Send + Sync, + C::Api: DomainsApi, Exec: CodeExecutor + Clone + 'static, Hash: Encode + Decode, VerifierClient: VerifierApi, - DomainExtrinsicsBuilder: BuildDomainExtrinsics, { fn verify_invalid_state_transition_proof( &self, diff --git a/crates/subspace-fraud-proof/src/invalid_transaction_proof.rs b/crates/subspace-fraud-proof/src/invalid_transaction_proof.rs index c3c39e7bef5..eabb542249a 100644 --- a/crates/subspace-fraud-proof/src/invalid_transaction_proof.rs +++ b/crates/subspace-fraud-proof/src/invalid_transaction_proof.rs @@ -1,6 +1,5 @@ //! Invalid transaction proof. -use crate::domain_extrinsics_builder::BuildDomainExtrinsics; use crate::domain_runtime_code::retrieve_domain_runtime_code; use crate::verifier_api::VerifierApi; use codec::{Decode, Encode}; @@ -13,7 +12,7 @@ use sp_blockchain::HeaderBackend; use sp_core::traits::CodeExecutor; use sp_core::H256; use sp_domains::fraud_proof::{InvalidTransactionProof, VerificationError}; -use sp_domains::{DomainId, ExecutorApi}; +use sp_domains::{DomainId, DomainsApi}; use sp_runtime::traits::{BlakeTwo256, Block as BlockT, Header as HeaderT}; use sp_runtime::{OpaqueExtrinsic, Storage}; use sp_trie::{read_trie_value, LayoutV1}; @@ -23,40 +22,23 @@ use std::marker::PhantomData; use std::sync::Arc; /// Invalid transaction proof verifier. -pub struct InvalidTransactionProofVerifier< - PBlock, - PClient, - Hash, - Exec, - VerifierClient, - DomainExtrinsicsBuilder, -> { - primary_chain_client: Arc, +pub struct InvalidTransactionProofVerifier { + consensus_client: Arc, executor: Arc, verifier_client: VerifierClient, - domain_extrinsics_builder: DomainExtrinsicsBuilder, - _phantom: PhantomData<(PBlock, Hash)>, + _phantom: PhantomData<(CBlock, Hash)>, } -impl Clone - for InvalidTransactionProofVerifier< - PBlock, - PClient, - Hash, - Exec, - VerifierClient, - DomainExtrinsicsBuilder, - > +impl Clone + for InvalidTransactionProofVerifier where VerifierClient: Clone, - DomainExtrinsicsBuilder: Clone, { fn clone(&self) -> Self { Self { - primary_chain_client: self.primary_chain_client.clone(), + consensus_client: self.consensus_client.clone(), executor: self.executor.clone(), verifier_client: self.verifier_client.clone(), - domain_extrinsics_builder: self.domain_extrinsics_builder.clone(), _phantom: self._phantom, } } @@ -116,56 +98,48 @@ where Ok(runtime_api_light) } -impl - InvalidTransactionProofVerifier< - PBlock, - PClient, - Hash, - Exec, - VerifierClient, - DomainExtrinsicsBuilder, - > +impl + InvalidTransactionProofVerifier where - PBlock: BlockT, + CBlock: BlockT, Hash: Encode + Decode, - H256: Into, - PClient: HeaderBackend + ProvideRuntimeApi + Send + Sync, - PClient::Api: ExecutorApi, + H256: Into, + CClient: HeaderBackend + ProvideRuntimeApi + Send + Sync, + CClient::Api: DomainsApi, VerifierClient: VerifierApi, - DomainExtrinsicsBuilder: BuildDomainExtrinsics, Exec: CodeExecutor + 'static, { /// Constructs a new instance of [`InvalidTransactionProofVerifier`]. pub fn new( - primary_chain_client: Arc, + consensus_client: Arc, executor: Arc, verifier_client: VerifierClient, - domain_extrinsics_builder: DomainExtrinsicsBuilder, ) -> Self { Self { - primary_chain_client, + consensus_client, executor, verifier_client, - domain_extrinsics_builder, _phantom: Default::default(), } } - fn fetch_primary_header( + fn fetch_consensus_block_header( &self, domain_id: DomainId, block_number: u32, - ) -> Result { - let primary_hash: PBlock::Hash = self + ) -> Result { + let consensus_block_hash: CBlock::Hash = self .verifier_client .primary_hash(domain_id, block_number)? .into(); let header = self - .primary_chain_client - .header(primary_hash)? + .consensus_client + .header(consensus_block_hash)? .ok_or_else(|| { - sp_blockchain::Error::Backend(format!("Header for {primary_hash} not found")) + sp_blockchain::Error::Backend(format!( + "Header for {consensus_block_hash} not found" + )) })?; Ok(header) @@ -188,13 +162,13 @@ where // - Bundle is valid and is produced by a legit executor. // - Bundle author, who will be slashed, can be extracted in runtime. - let header = self.fetch_primary_header(*domain_id, *block_number)?; - let primary_parent_hash = *header.parent_hash(); + let header = self.fetch_consensus_block_header(*domain_id, *block_number)?; + let consensus_parent_hash = *header.parent_hash(); let domain_runtime_code = retrieve_domain_runtime_code( *domain_id, - primary_parent_hash, - &self.primary_chain_client, + consensus_parent_hash, + &self.consensus_client, )?; // TODO: Verifiable invalid extrinsic. @@ -211,7 +185,7 @@ where storage_proof.clone(), &state_root, self.executor.clone(), - domain_runtime_code.wasm_bundle, + domain_runtime_code.wasm_bundle.into(), extrinsic.clone(), )?; @@ -219,7 +193,7 @@ where as DomainCoreApi>::check_transaction_validity( &runtime_api_light, Default::default(), // Unused for stateless runtime api. - extrinsic, + &extrinsic, *domain_block_hash, )?; @@ -240,24 +214,15 @@ pub trait VerifyInvalidTransactionProof { ) -> Result<(), VerificationError>; } -impl - VerifyInvalidTransactionProof - for InvalidTransactionProofVerifier< - PBlock, - Client, - Hash, - Exec, - VerifierClient, - DomainExtrinsicsBuilder, - > +impl VerifyInvalidTransactionProof + for InvalidTransactionProofVerifier where - PBlock: BlockT, + CBlock: BlockT, Hash: Encode + Decode, - H256: Into, - Client: HeaderBackend + ProvideRuntimeApi + Send + Sync, - Client::Api: ExecutorApi, + H256: Into, + Client: HeaderBackend + ProvideRuntimeApi + Send + Sync, + Client::Api: DomainsApi, VerifierClient: VerifierApi, - DomainExtrinsicsBuilder: BuildDomainExtrinsics, Exec: CodeExecutor + 'static, { fn verify_invalid_transaction_proof( diff --git a/crates/subspace-fraud-proof/src/lib.rs b/crates/subspace-fraud-proof/src/lib.rs index 740355effe4..41245aea53d 100644 --- a/crates/subspace-fraud-proof/src/lib.rs +++ b/crates/subspace-fraud-proof/src/lib.rs @@ -2,7 +2,6 @@ #![warn(missing_docs)] -pub mod domain_extrinsics_builder; mod domain_runtime_code; pub mod invalid_state_transition_proof; pub mod invalid_transaction_proof; diff --git a/crates/subspace-fraud-proof/src/tests.rs b/crates/subspace-fraud-proof/src/tests.rs index 422d4f6d07e..7165664d238 100644 --- a/crates/subspace-fraud-proof/src/tests.rs +++ b/crates/subspace-fraud-proof/src/tests.rs @@ -1,18 +1,19 @@ -use crate::domain_extrinsics_builder::SystemDomainExtrinsicsBuilder; use crate::invalid_state_transition_proof::{ExecutionProver, InvalidStateTransitionProofVerifier}; use crate::invalid_transaction_proof::InvalidTransactionProofVerifier; use crate::verifier_api::VerifierApi; use crate::ProofVerifier; -use codec::{Decode, Encode}; +use codec::Encode; use domain_block_builder::{BlockBuilder, RecordProof}; use domain_runtime_primitives::{DomainCoreApi, Hash}; -use domain_test_service::system_domain::SClient as DomainClient; -use domain_test_service::system_domain_test_runtime::{Address, Header}; -use domain_test_service::Keyring::{Alice, Bob, Charlie, Dave, Ferdie, One}; +use domain_test_service::domain::EvmDomainClient as DomainClient; +use domain_test_service::evm_domain_test_runtime::Header; +use domain_test_service::EcdsaKeyring::{Alice, Bob, Charlie, Dave}; +use domain_test_service::Sr25519Keyring::Ferdie; +use domain_test_service::GENESIS_DOMAIN_ID; use sc_client_api::{HeaderBackend, StorageProof}; use sc_service::{BasePath, Role}; use sp_api::ProvideRuntimeApi; -use sp_core::{Pair, H256}; +use sp_core::H256; use sp_domain_digests::AsPredigest; use sp_domains::fraud_proof::{ ExecutionPhase, FraudProof, InvalidStateTransitionProof, VerificationError, @@ -20,23 +21,22 @@ use sp_domains::fraud_proof::{ use sp_domains::DomainId; use sp_runtime::generic::{Digest, DigestItem}; use sp_runtime::traits::{BlakeTwo256, Header as HeaderT}; -use sp_runtime::OpaqueExtrinsic; use std::sync::Arc; use subspace_runtime_primitives::opaque::Block; use subspace_test_client::Client; -use subspace_test_service::{produce_block_with, produce_blocks, MockPrimaryNode}; +use subspace_test_service::{produce_block_with, produce_blocks, MockConsensusNode}; use tempfile::TempDir; struct TestVerifierClient { - primary_chain_client: Arc, - system_domain_client: Arc, + consensus_client: Arc, + domain_client: Arc, } impl TestVerifierClient { - fn new(primary_chain_client: Arc, system_domain_client: Arc) -> Self { + fn new(consensus_client: Arc, domain_client: Arc) -> Self { Self { - primary_chain_client, - system_domain_client, + consensus_client, + domain_client, } } } @@ -67,7 +67,7 @@ impl VerifierApi for TestVerifierClient { // This is retrieved from the `PrimaryBlockHash` state on the parent chain in // production, we retrieve it from the primary chain client in test for simplicity. Ok(self - .primary_chain_client + .consensus_client .hash(domain_block_number) .unwrap() .unwrap()) @@ -80,7 +80,7 @@ impl VerifierApi for TestVerifierClient { domain_block_hash: H256, ) -> Result { Ok(*self - .system_domain_client + .domain_client .header(domain_block_hash) .unwrap() .unwrap() @@ -89,9 +89,10 @@ impl VerifierApi for TestVerifierClient { } // Use the system domain id for testing -const TEST_DOMAIN_ID: DomainId = DomainId::SYSTEM; +const TEST_DOMAIN_ID: DomainId = DomainId::new(3u32); #[substrate_test_utils::test(flavor = "multi_thread")] +#[ignore] async fn execution_proof_creation_and_verification_should_work() { let directory = TempDir::new().expect("Must be able to create temporary directory"); @@ -102,28 +103,28 @@ async fn execution_proof_creation_and_verification_should_work() { let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); - // Run Alice (a system domain authority node) - let mut alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let mut alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; - // Run Bob (a system domain full node) - let bob = domain_test_service::SystemDomainNodeBuilder::new( + // Run Bob (a evm domain full node) + let bob = domain_test_service::DomainNodeBuilder::new( tokio_handle, Bob, BasePath::new(directory.path().join("bob")), ) - .build_with_mock_primary_node(Role::Full, &mut ferdie) + .build_evm_node(Role::Full, GENESIS_DOMAIN_ID, &mut ferdie) .await; // Bob is able to sync blocks. @@ -133,21 +134,21 @@ async fn execution_proof_creation_and_verification_should_work() { let transfer_to_charlie = alice.construct_extrinsic( alice_nonce, pallet_balances::Call::transfer { - dest: Address::Id(Charlie.public().into()), + dest: Charlie.to_account_id(), value: 8, }, ); let transfer_to_dave = alice.construct_extrinsic( alice_nonce + 1, pallet_balances::Call::transfer { - dest: Address::Id(Dave.public().into()), + dest: Dave.to_account_id(), value: 8, }, ); let transfer_to_charlie_again = alice.construct_extrinsic( alice_nonce + 2, pallet_balances::Call::transfer { - dest: Address::Id(Charlie.public().into()), + dest: Charlie.to_account_id(), value: 88, }, ); @@ -255,26 +256,16 @@ async fn execution_proof_creation_and_verification_should_work() { .unwrap(); assert_eq!(post_execution_root, intermediate_roots[0].into()); - let domain_extrinsics_builder = SystemDomainExtrinsicsBuilder::new( - ferdie.client.clone(), - Arc::new(ferdie.executor.clone()), - ); - let invalid_state_transition_proof_verifier = InvalidStateTransitionProofVerifier::new( ferdie.client.clone(), ferdie.executor.clone(), TestVerifierClient::new(ferdie.client.clone(), alice.client.clone()), - SystemDomainExtrinsicsBuilder::new( - ferdie.client.clone(), - Arc::new(ferdie.executor.clone()), - ), ); let invalid_transaction_proof_verifier = InvalidTransactionProofVerifier::new( ferdie.client.clone(), Arc::new(ferdie.executor.clone()), TestVerifierClient::new(ferdie.client.clone(), alice.client.clone()), - domain_extrinsics_builder, ); let proof_verifier = ProofVerifier::::new( @@ -283,13 +274,13 @@ async fn execution_proof_creation_and_verification_should_work() { ); let parent_number_alice = *parent_header.number(); - let primary_parent_hash = ferdie.client.hash(parent_number_alice).unwrap().unwrap(); + let consensus_parent_hash = ferdie.client.hash(parent_number_alice).unwrap().unwrap(); let invalid_state_transition_proof = InvalidStateTransitionProof { domain_id: TEST_DOMAIN_ID, bad_receipt_hash: Hash::random(), parent_number: parent_number_alice, - primary_parent_hash, + consensus_parent_hash, pre_state_root: *parent_header.state_root(), post_state_root: intermediate_roots[0].into(), proof: storage_proof, @@ -346,7 +337,7 @@ async fn execution_proof_creation_and_verification_should_work() { domain_id: TEST_DOMAIN_ID, bad_receipt_hash: Hash::random(), parent_number: parent_number_alice, - primary_parent_hash, + consensus_parent_hash, pre_state_root: intermediate_roots[target_extrinsic_index].into(), post_state_root: intermediate_roots[target_extrinsic_index + 1].into(), proof: storage_proof, @@ -399,7 +390,7 @@ async fn execution_proof_creation_and_verification_should_work() { domain_id: TEST_DOMAIN_ID, bad_receipt_hash: Hash::random(), parent_number: parent_number_alice, - primary_parent_hash, + consensus_parent_hash, pre_state_root: intermediate_roots.last().unwrap().into(), post_state_root: post_execution_root, proof: storage_proof, @@ -410,6 +401,7 @@ async fn execution_proof_creation_and_verification_should_work() { } #[substrate_test_utils::test(flavor = "multi_thread")] +#[ignore] async fn invalid_execution_proof_should_not_work() { let directory = TempDir::new().expect("Must be able to create temporary directory"); @@ -420,28 +412,28 @@ async fn invalid_execution_proof_should_not_work() { let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); - // Run Alice (a system domain authority node) - let mut alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let mut alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; - // Run Bob (a system domain full node) - let bob = domain_test_service::SystemDomainNodeBuilder::new( + // Run Bob (a evm domain full node) + let bob = domain_test_service::DomainNodeBuilder::new( tokio_handle, Bob, BasePath::new(directory.path().join("bob")), ) - .build_with_mock_primary_node(Role::Full, &mut ferdie) + .build_evm_node(Role::Full, GENESIS_DOMAIN_ID, &mut ferdie) .await; // Bob is able to sync blocks. @@ -451,14 +443,14 @@ async fn invalid_execution_proof_should_not_work() { let transfer_to_charlie = alice.construct_extrinsic( alice_nonce, pallet_balances::Call::transfer { - dest: Address::Id(Charlie.public().into()), + dest: Charlie.to_account_id(), value: 8, }, ); let transfer_to_charlie_again = alice.construct_extrinsic( alice_nonce + 1, pallet_balances::Call::transfer { - dest: Address::Id(Charlie.public().into()), + dest: Charlie.to_account_id(), value: 8, }, ); @@ -555,22 +547,12 @@ async fn invalid_execution_proof_should_not_work() { ferdie.client.clone(), ferdie.executor.clone(), TestVerifierClient::new(ferdie.client.clone(), alice.client.clone()), - SystemDomainExtrinsicsBuilder::new( - ferdie.client.clone(), - Arc::new(ferdie.executor.clone()), - ), - ); - - let domain_extrinsics_builder = SystemDomainExtrinsicsBuilder::new( - ferdie.client.clone(), - Arc::new(ferdie.executor.clone()), ); let invalid_transaction_proof_verifier = InvalidTransactionProofVerifier::new( ferdie.client.clone(), Arc::new(ferdie.executor.clone()), TestVerifierClient::new(ferdie.client.clone(), alice.client.clone()), - domain_extrinsics_builder, ); let proof_verifier = ProofVerifier::::new( @@ -579,13 +561,13 @@ async fn invalid_execution_proof_should_not_work() { ); let parent_number_alice = *parent_header.number(); - let primary_parent_hash = ferdie.client.hash(parent_number_alice).unwrap().unwrap(); + let consensus_parent_hash = ferdie.client.hash(parent_number_alice).unwrap().unwrap(); let invalid_state_transition_proof = InvalidStateTransitionProof { domain_id: TEST_DOMAIN_ID, bad_receipt_hash: Hash::random(), parent_number: parent_number_alice, - primary_parent_hash, + consensus_parent_hash, pre_state_root: post_delta_root0, post_state_root: post_delta_root1, proof: proof1, @@ -598,7 +580,7 @@ async fn invalid_execution_proof_should_not_work() { domain_id: TEST_DOMAIN_ID, bad_receipt_hash: Hash::random(), parent_number: parent_number_alice, - primary_parent_hash, + consensus_parent_hash, pre_state_root: post_delta_root0, post_state_root: post_delta_root1, proof: proof0.clone(), @@ -611,7 +593,7 @@ async fn invalid_execution_proof_should_not_work() { domain_id: TEST_DOMAIN_ID, bad_receipt_hash: Hash::random(), parent_number: parent_number_alice, - primary_parent_hash, + consensus_parent_hash, pre_state_root: post_delta_root0, post_state_root: post_delta_root1, proof: proof0, @@ -621,133 +603,127 @@ async fn invalid_execution_proof_should_not_work() { assert!(proof_verifier.verify(&fraud_proof).is_ok()); } -#[substrate_test_utils::test(flavor = "multi_thread")] -async fn test_invalid_transaction_proof_creation_and_verification() { - let directory = TempDir::new().expect("Must be able to create temporary directory"); - - let mut builder = sc_cli::LoggerBuilder::new("runtime=debug"); - builder.with_colors(false); - let _ = builder.init(); - - let tokio_handle = tokio::runtime::Handle::current(); - - // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( - tokio_handle.clone(), - Ferdie, - BasePath::new(directory.path().join("ferdie")), - ); - - // Run Alice (a system domain authority node) - let mut alice = domain_test_service::SystemDomainNodeBuilder::new( - tokio_handle.clone(), - Alice, - BasePath::new(directory.path().join("alice")), - ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) - .await; - - produce_blocks!(ferdie, alice, 3).await.unwrap(); - - alice - .construct_and_send_extrinsic(pallet_balances::Call::transfer { - dest: domain_test_service::system_domain_test_runtime::Address::Id(One.public().into()), - value: 500 + 1, - }) - .await - .expect("Send an extrinsic to transfer some balance from Alice to One"); - - ferdie.produce_slot_and_wait_for_bundle_submission().await; - - produce_blocks!(ferdie, alice, 1).await.unwrap(); - - let (_slot, maybe_bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; - - produce_blocks!(ferdie, alice, 3).await.unwrap(); - - // This is an invalid transaction. - let transfer_from_one_to_bob = alice.construct_extrinsic_with_caller( - One, - pallet_balances::Call::transfer { - dest: domain_test_service::system_domain_test_runtime::Address::Id(Bob.public().into()), - value: 1000, - }, - ); - - let mut bundle_with_bad_extrinsics = maybe_bundle.unwrap(); - bundle_with_bad_extrinsics.extrinsics = - vec![OpaqueExtrinsic::from_bytes(&transfer_from_one_to_bob.encode()).unwrap()]; - bundle_with_bad_extrinsics.sealed_header.signature = alice - .key - .pair() - .sign(bundle_with_bad_extrinsics.sealed_header.pre_hash().as_ref()) - .into(); - - alice - .gossip_message_validator - .validate_gossiped_bundle(&bundle_with_bad_extrinsics) - .expect("Create an invalid transaction proof and submit to tx pool"); - - let extract_fraud_proof_from_tx_pool = || { - let ready_txs = ferdie - .transaction_pool - .pool() - .validated_pool() - .ready() - .collect::>(); - - ready_txs - .into_iter() - .find_map(|ready_tx| { - let uxt = subspace_test_runtime::UncheckedExtrinsic::decode( - &mut ready_tx.data.encode().as_slice(), - ) - .unwrap(); - match uxt.function { - subspace_test_runtime::RuntimeCall::Domains( - pallet_domains::Call::submit_fraud_proof { fraud_proof }, - ) => Some(fraud_proof), - _ => None, - } - }) - .expect("Can not find submit_fraud_proof extrinsic") - }; - - let good_invalid_transaction_proof = extract_fraud_proof_from_tx_pool(); - - let domain_extrinsics_builder = SystemDomainExtrinsicsBuilder::new( - ferdie.client.clone(), - Arc::new(ferdie.executor.clone()), - ); - - let invalid_state_transition_proof_verifier = InvalidStateTransitionProofVerifier::new( - ferdie.client.clone(), - ferdie.executor.clone(), - TestVerifierClient::new(ferdie.client.clone(), alice.client.clone()), - domain_extrinsics_builder.clone(), - ); - - let invalid_transaction_proof_verifier = InvalidTransactionProofVerifier::new( - ferdie.client.clone(), - Arc::new(ferdie.executor.clone()), - TestVerifierClient::new(ferdie.client.clone(), alice.client.clone()), - domain_extrinsics_builder, - ); - - let proof_verifier = ProofVerifier::::new( - Arc::new(invalid_transaction_proof_verifier), - Arc::new(invalid_state_transition_proof_verifier), - ); - - assert!( - proof_verifier - .verify(&good_invalid_transaction_proof) - .is_ok(), - "Valid proof must be accepeted" - ); - - ferdie - .produce_blocks(1) - .await - .expect("FraudProof verification in the block import pipeline is fine too"); -} +// TODO: Unlock test when gossip message validator are supported in DecEx v2. +// #[substrate_test_utils::test(flavor = "multi_thread")] +// async fn test_invalid_transaction_proof_creation_and_verification() { +// let directory = TempDir::new().expect("Must be able to create temporary directory"); + +// let mut builder = sc_cli::LoggerBuilder::new("runtime=debug"); +// builder.with_colors(false); +// let _ = builder.init(); + +// let tokio_handle = tokio::runtime::Handle::current(); + +// // Start Ferdie +// let mut ferdie = MockConsensusNode::run( +// tokio_handle.clone(), +// Ferdie, +// BasePath::new(directory.path().join("ferdie")), +// ); + +// // Run Alice (a system domain authority node) +// let mut alice = domain_test_service::DomainNodeBuilder::new( +// tokio_handle.clone(), +// Alice, +// BasePath::new(directory.path().join("alice")), +// ) +// .build_evm_node(Role::Authority, &mut ferdie) +// .await; + +// produce_blocks!(ferdie, alice, 3).await.unwrap(); + +// alice +// .construct_and_send_extrinsic(pallet_balances::Call::transfer { +// dest: domain_test_service::evm_domain_test_runtime::Address::Id(One.public().into()), +// value: 500 + 1, +// }) +// .await +// .expect("Send an extrinsic to transfer some balance from Alice to One"); + +// ferdie.produce_slot_and_wait_for_bundle_submission().await; + +// produce_blocks!(ferdie, alice, 1).await.unwrap(); + +// let (_slot, maybe_bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; + +// produce_blocks!(ferdie, alice, 3).await.unwrap(); + +// // This is an invalid transaction. +// let transfer_from_one_to_bob = alice.construct_extrinsic_with_caller( +// One, +// pallet_balances::Call::transfer { +// dest: domain_test_service::evm_domain_test_runtime::Address::Id(Bob.public().into()), +// value: 1000, +// }, +// ); + +// let mut bundle_with_bad_extrinsics = maybe_bundle.unwrap(); +// bundle_with_bad_extrinsics.extrinsics = +// vec![OpaqueExtrinsic::from_bytes(&transfer_from_one_to_bob.encode()).unwrap()]; +// bundle_with_bad_extrinsics.sealed_header.signature = alice +// .key +// .pair() +// .sign(bundle_with_bad_extrinsics.sealed_header.pre_hash().as_ref()) +// .into(); + +// alice +// .gossip_message_validator +// .validate_gossiped_bundle(&bundle_with_bad_extrinsics) +// .expect("Create an invalid transaction proof and submit to tx pool"); + +// let extract_fraud_proof_from_tx_pool = || { +// let ready_txs = ferdie +// .transaction_pool +// .pool() +// .validated_pool() +// .ready() +// .collect::>(); + +// ready_txs +// .into_iter() +// .find_map(|ready_tx| { +// let uxt = subspace_test_runtime::UncheckedExtrinsic::decode( +// &mut ready_tx.data.encode().as_slice(), +// ) +// .unwrap(); +// match uxt.function { +// subspace_test_runtime::RuntimeCall::Domains( +// pallet_domains::Call::submit_fraud_proof { fraud_proof }, +// ) => Some(fraud_proof), +// _ => None, +// } +// }) +// .expect("Can not find submit_fraud_proof extrinsic") +// }; + +// let good_invalid_transaction_proof = extract_fraud_proof_from_tx_pool(); + +// let invalid_state_transition_proof_verifier = InvalidStateTransitionProofVerifier::new( +// ferdie.client.clone(), +// ferdie.executor.clone(), +// TestVerifierClient::new(ferdie.client.clone(), alice.client.clone()), +// ); + +// let invalid_transaction_proof_verifier = InvalidTransactionProofVerifier::new( +// ferdie.client.clone(), +// Arc::new(ferdie.executor.clone()), +// TestVerifierClient::new(ferdie.client.clone(), alice.client.clone()), +// ); + +// let proof_verifier = ProofVerifier::::new( +// Arc::new(invalid_transaction_proof_verifier), +// Arc::new(invalid_state_transition_proof_verifier), +// ); + +// assert!( +// proof_verifier +// .verify(&good_invalid_transaction_proof) +// .is_ok(), +// "Valid proof must be accepeted" +// ); + +// ferdie +// .produce_blocks(1) +// .await +// .expect("FraudProof verification in the block import pipeline is fine too"); +// } diff --git a/crates/subspace-fraud-proof/src/verifier_api.rs b/crates/subspace-fraud-proof/src/verifier_api.rs index 2749f8ee8f2..b1b46807b0a 100644 --- a/crates/subspace-fraud-proof/src/verifier_api.rs +++ b/crates/subspace-fraud-proof/src/verifier_api.rs @@ -2,15 +2,17 @@ //! as well as the implementation to provide convenient interfaces used in the fraud //! proof verification. +// TODO: Remove once fraud proof v2 is implemented. +#![allow(unused)] + use codec::{Decode, Encode}; use domain_runtime_primitives::Hash; use sc_client_api::HeaderBackend; use sp_api::ProvideRuntimeApi; use sp_core::H256; use sp_domains::fraud_proof::{ExecutionPhase, InvalidStateTransitionProof, VerificationError}; -use sp_domains::DomainId; +use sp_domains::{DomainId, DomainsApi}; use sp_runtime::traits::{Block as BlockT, NumberFor}; -use sp_settlement::SettlementApi; use std::marker::PhantomData; use std::sync::Arc; @@ -45,8 +47,6 @@ pub trait VerifierApi { } /// A wrapper of primary chain client/system domain client in common. -/// -/// Both primary chain client and system domain client maintains the state of receipts, i.e., implements `SettlementApi`. pub struct VerifierClient { client: Arc, _phantom: PhantomData, @@ -75,7 +75,8 @@ impl VerifierApi for VerifierClient where Block: BlockT, Client: ProvideRuntimeApi + HeaderBackend, - Client::Api: SettlementApi, + Client::Api: + DomainsApi, { // TODO: It's not necessary to require `pre_state_root` in the proof and then verify, it can // be just retrieved by the verifier itself according the execution phase, which requires some @@ -85,118 +86,36 @@ where // Related: https://github.com/subspace/subspace/pull/1240#issuecomment-1476212007 fn verify_pre_state_root( &self, - invalid_state_transition_proof: &InvalidStateTransitionProof, + _invalid_state_transition_proof: &InvalidStateTransitionProof, ) -> Result<(), VerificationError> { - let InvalidStateTransitionProof { - domain_id, - parent_number, - bad_receipt_hash, - pre_state_root, - execution_phase, - .. - } = invalid_state_transition_proof; - - let pre_state_root_onchain = match execution_phase { - ExecutionPhase::InitializeBlock { domain_parent_hash } => { - self.client.runtime_api().state_root( - self.client.info().best_hash, - *domain_id, - NumberFor::::from(*parent_number), - Block::Hash::decode(&mut domain_parent_hash.encode().as_slice())?, - )? - } - ExecutionPhase::ApplyExtrinsic(trace_index_of_pre_state_root) - | ExecutionPhase::FinalizeBlock { - total_extrinsics: trace_index_of_pre_state_root, - } => { - let trace = self.client.runtime_api().execution_trace( - self.client.info().best_hash, - *domain_id, - *bad_receipt_hash, - )?; - - trace.get(*trace_index_of_pre_state_root as usize).copied() - } - }; - - match pre_state_root_onchain { - Some(expected_pre_state_root) if expected_pre_state_root == *pre_state_root => Ok(()), - res => { - tracing::debug!( - "Invalid `pre_state_root` in InvalidStateTransitionProof for {domain_id:?}, expected: {res:?}, got: {pre_state_root:?}", - ); - Err(VerificationError::InvalidPreStateRoot) - } - } + // TODO: Implement or remove entirely. + Ok(()) } fn verify_post_state_root( &self, - invalid_state_transition_proof: &InvalidStateTransitionProof, + _invalid_state_transition_proof: &InvalidStateTransitionProof, ) -> Result<(), VerificationError> { - let InvalidStateTransitionProof { - domain_id, - bad_receipt_hash, - execution_phase, - post_state_root, - .. - } = invalid_state_transition_proof; - - let trace = self.client.runtime_api().execution_trace( - self.client.info().best_hash, - *domain_id, - *bad_receipt_hash, - )?; - - let post_state_root_onchain = match execution_phase { - ExecutionPhase::InitializeBlock { .. } => trace - .get(0) - .ok_or(VerificationError::PostStateRootNotFound)?, - ExecutionPhase::ApplyExtrinsic(trace_index_of_post_state_root) - | ExecutionPhase::FinalizeBlock { - total_extrinsics: trace_index_of_post_state_root, - } => trace - .get(*trace_index_of_post_state_root as usize + 1) - .ok_or(VerificationError::PostStateRootNotFound)?, - }; - - if post_state_root_onchain == post_state_root { - Err(VerificationError::SamePostStateRoot) - } else { - Ok(()) - } + // TODO: Implement or remove entirely. + Ok(()) } fn primary_hash( &self, - domain_id: DomainId, - domain_block_number: u32, + _domain_id: DomainId, + _domain_block_number: u32, ) -> Result { - self.client - .runtime_api() - .primary_hash( - self.client.info().best_hash, - domain_id, - domain_block_number.into(), - )? - .and_then(|primary_hash| Decode::decode(&mut primary_hash.encode().as_slice()).ok()) - .ok_or(VerificationError::PrimaryHashNotFound) + // TODO: Remove entirely. + Err(VerificationError::ConsensusBlockHashNotFound) } fn state_root( &self, - domain_id: DomainId, - domain_block_number: u32, - domain_block_hash: H256, + _domain_id: DomainId, + _domain_block_number: u32, + _domain_block_hash: H256, ) -> Result { - self.client - .runtime_api() - .state_root( - self.client.info().best_hash, - domain_id, - NumberFor::::from(domain_block_number), - Block::Hash::decode(&mut domain_block_hash.encode().as_slice())?, - )? - .ok_or(VerificationError::DomainStateRootNotFound) + // TODO: Implement or remove entirely. + Err(VerificationError::DomainStateRootNotFound) } } diff --git a/crates/subspace-networking/Cargo.toml b/crates/subspace-networking/Cargo.toml index 4e4acbca639..ac01e5f1606 100644 --- a/crates/subspace-networking/Cargo.toml +++ b/crates/subspace-networking/Cargo.toml @@ -16,26 +16,27 @@ include = [ ] [dependencies] +async-mutex = "1.4.0" actix-web = "4.3.1" -anyhow = "1.0.71" async-trait = "0.1.68" backoff = { version = "0.4.0", features = ["futures", "tokio"] } bytes = "1.4.0" -bytesize = "1.2.0" -chrono = {version = "0.4.26", features = ["clock", "serde", "std",]} clap = { version = "4.2.1", features = ["color", "derive"] } derive_more = "0.99.17" either = "1.8.1" event-listener-primitives = "2.0.1" +fs2 = "0.4.3" futures = "0.3.28" +futures-timer = "3.0.2" hex = "0.4.3" lru = "0.10.0" +memmap2 = "0.7.1" nohash-hasher = "0.2.0" -parity-db = "0.4.6" -parity-scale-codec = "3.4.0" +parity-scale-codec = "3.6.3" parking_lot = "0.12.1" pin-project = "1.1.0" prometheus-client = "0.19.0" +rand = "0.8.5" serde = { version = "1.0.159", features = ["derive"] } serde_json = "1.0.97" subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } @@ -48,7 +49,7 @@ unsigned-varint = { version = "0.7.1", features = ["futures", "asynchronous_code void = "1.0.2" [dependencies.libp2p] -version = "0.51.3" +version = "0.52.1" default-features = false features = [ "dns", @@ -59,7 +60,6 @@ features = [ "metrics", "noise", "ping", - "quic", "request-response", "serde", "tcp", @@ -67,6 +67,17 @@ features = [ "websocket", "yamux", ] +[dependencies.libp2p-quic] +version = "0.8.0-alpha" +features = ["tokio"] + +# Remove after this patch goes to the release branch +[dependencies.libp2p-kad] +version = "0.44.3" + +# Remove after this patch goes to the release branch +[dependencies.libp2p-connection-limits] +version = "0.2.1" [dev-dependencies] rand = "0.8.5" diff --git a/crates/subspace-networking/examples/announce-piece-complex.rs b/crates/subspace-networking/examples/announce-piece-complex.rs deleted file mode 100644 index 50e510577b7..00000000000 --- a/crates/subspace-networking/examples/announce-piece-complex.rs +++ /dev/null @@ -1,113 +0,0 @@ -use futures::channel::oneshot; -use futures::StreamExt; -use libp2p::multiaddr::Protocol; -use parking_lot::Mutex; -use std::sync::Arc; -use std::time::Duration; -use subspace_core_primitives::PieceIndex; -use subspace_networking::utils::multihash::ToMultihash; -use subspace_networking::utils::piece_announcement::announce_single_piece_index_hash_with_backoff; -use subspace_networking::{BootstrappedNetworkingParameters, Config}; - -#[tokio::main] -async fn main() { - tracing_subscriber::fmt::init(); - - let mut bootstrap_nodes = Vec::new(); - - const TOTAL_NODE_COUNT: usize = 30; - - let mut nodes = Vec::with_capacity(TOTAL_NODE_COUNT); - for i in 0..TOTAL_NODE_COUNT { - let config = Config { - networking_parameters_registry: BootstrappedNetworkingParameters::new( - bootstrap_nodes.clone(), - ) - .boxed(), - listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], - allow_non_global_addresses_in_dht: true, - ..Config::default() - }; - - let (node, mut node_runner) = subspace_networking::create(config).unwrap(); - - println!("Node {} ID is {}", i, node.id()); - - let (node_address_sender, node_address_receiver) = oneshot::channel(); - let _handler = node.on_new_listener(Arc::new({ - let node_address_sender = Mutex::new(Some(node_address_sender)); - - move |address| { - if matches!(address.iter().next(), Some(Protocol::Ip4(_))) { - if let Some(node_address_sender) = node_address_sender.lock().take() { - node_address_sender.send(address.clone()).unwrap(); - } - } - } - })); - - tokio::spawn(async move { - node_runner.run().await; - }); - - // Wait for node to know its address - let node_addr = node_address_receiver.await.unwrap(); - - tokio::time::sleep(Duration::from_millis(40)).await; - - let address = node_addr.with(Protocol::P2p(node.id().into())); - - bootstrap_nodes.push(address); - - nodes.push(node); - } - - let config = Config { - listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], - allow_non_global_addresses_in_dht: true, - networking_parameters_registry: BootstrappedNetworkingParameters::new( - bootstrap_nodes.clone(), - ) - .boxed(), - ..Config::default() - }; - - let (node, mut node_runner) = subspace_networking::create(config).unwrap(); - - tokio::spawn(async move { - node_runner.run().await; - }); - - node.wait_for_connected_peers().await.unwrap(); - - let piece_index = PieceIndex::ONE; - let piece_index_hash = piece_index.hash(); - let key = piece_index_hash.to_multihash(); - - announce_single_piece_index_hash_with_backoff(piece_index_hash, &node) - .await - .unwrap(); - - println!("Node announced key: {key:?}"); - - tokio::time::sleep(Duration::from_secs(15)).await; - - let some_node = nodes.first().unwrap(); - let providers_result = match some_node.get_providers(key).await { - Ok(stream) => Ok(stream.collect::>().await), - Err(error) => Err(error), - }; - - println!("Some Node get_piece_providers result: {providers_result:?}"); - - tokio::time::sleep(Duration::from_secs(20)).await; - - let providers_result = match some_node.get_providers(key).await { - Ok(stream) => Ok(stream.collect::>().await), - Err(error) => Err(error), - }; - - println!("Some Node get_piece_providers result: {providers_result:?}"); - - println!("Exiting.."); -} diff --git a/crates/subspace-networking/examples/announce-piece.rs b/crates/subspace-networking/examples/announce-piece.rs deleted file mode 100644 index d632dd90b29..00000000000 --- a/crates/subspace-networking/examples/announce-piece.rs +++ /dev/null @@ -1,96 +0,0 @@ -use futures::channel::oneshot; -use futures::StreamExt; -use libp2p::multiaddr::Protocol; -use parking_lot::Mutex; -use std::sync::Arc; -use std::time::Duration; -use subspace_core_primitives::PieceIndex; -use subspace_networking::utils::multihash::ToMultihash; -use subspace_networking::utils::piece_announcement::announce_single_piece_index_hash_with_backoff; -use subspace_networking::{BootstrappedNetworkingParameters, Config}; - -#[tokio::main] -async fn main() { - tracing_subscriber::fmt::init(); - - let config_1 = Config { - listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], - allow_non_global_addresses_in_dht: true, - ..Config::default() - }; - let (node_1, mut node_runner_1) = subspace_networking::create(config_1).unwrap(); - - println!("Node 1 ID is {}", node_1.id()); - - let (node_1_address_sender, node_1_address_receiver) = oneshot::channel(); - let on_new_listener_handler = node_1.on_new_listener(Arc::new({ - let node_1_address_sender = Mutex::new(Some(node_1_address_sender)); - - move |address| { - if matches!(address.iter().next(), Some(Protocol::Ip4(_))) { - if let Some(node_1_address_sender) = node_1_address_sender.lock().take() { - node_1_address_sender.send(address.clone()).unwrap(); - } - } - } - })); - - tokio::spawn(async move { - node_runner_1.run().await; - }); - - // Wait for first node to know its address - let node_1_addr = node_1_address_receiver.await.unwrap(); - drop(on_new_listener_handler); - - let config_2 = Config { - networking_parameters_registry: BootstrappedNetworkingParameters::new(vec![ - node_1_addr.with(Protocol::P2p(node_1.id().into())) - ]) - .boxed(), - listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], - allow_non_global_addresses_in_dht: true, - ..Config::default() - }; - - let (node_2, mut node_runner_2) = subspace_networking::create(config_2).unwrap(); - - println!("Node 2 ID is {}", node_2.id()); - - tokio::spawn(async move { - node_runner_2.run().await; - }); - - tokio::time::sleep(Duration::from_secs(1)).await; - - let piece_index = PieceIndex::ONE; - let piece_index_hash = piece_index.hash(); - let key = piece_index_hash.to_multihash(); - - announce_single_piece_index_hash_with_backoff(piece_index_hash, &node_2) - .await - .unwrap(); - println!("Node 2 announced key: {key:?}"); - - tokio::time::sleep(Duration::from_secs(2)).await; - - let providers_result = match node_1.get_providers(key).await { - Ok(stream) => Ok(stream.collect::>().await), - Err(error) => Err(error), - }; - - println!("Node 1 get_providers result: {providers_result:?}"); - - node_2.stop_local_announcing(key).await.unwrap(); - - tokio::time::sleep(Duration::from_secs(3)).await; - - let providers_result = match node_1.get_providers(key).await { - Ok(stream) => Ok(stream.collect::>().await), - Err(error) => Err(error), - }; - - println!("Node 1 get_providers result: {providers_result:?}"); - - println!("Exiting.."); -} diff --git a/crates/subspace-networking/examples/custom-store.rs b/crates/subspace-networking/examples/custom-store.rs deleted file mode 100644 index e28f87b8653..00000000000 --- a/crates/subspace-networking/examples/custom-store.rs +++ /dev/null @@ -1,87 +0,0 @@ -use libp2p::identity::ed25519::Keypair; -use libp2p::kad::record::Key; -use libp2p::kad::ProviderRecord; -use libp2p::PeerId; -use std::collections::HashSet; -use std::num::NonZeroUsize; -use subspace_networking::{peer_id, ParityDbProviderStorage, ProviderStorage}; -use tempfile::TempDir; - -#[allow(clippy::mutable_key_type)] // we use hash set for sorting to compare collections -fn main() -> anyhow::Result<()> { - tracing_subscriber::fmt::init(); - - let db_path = TempDir::new() - .expect("We should be able to crate temp directory.") - .path() - .join("subspace_example_custom_provider_storage_db") - .into_boxed_path(); - - let keypair = Keypair::generate(); - let local_peer_id = peer_id(&libp2p::identity::Keypair::from(keypair)); - - let provider_storage = - ParityDbProviderStorage::new(&db_path, NonZeroUsize::new(1000).unwrap(), local_peer_id) - .expect("Provider storage DB path should be valid."); - - let key1: Key = b"key1".to_vec().into(); - let provider1 = PeerId::random(); - let rec1 = ProviderRecord { - provider: provider1, - key: key1, - expires: None, - addresses: Vec::new(), - }; - - let key2: Key = b"key2".to_vec().into(); - let provider2 = local_peer_id; - let rec2 = ProviderRecord { - provider: provider2, - key: key2.clone(), - expires: None, - addresses: Vec::new(), - }; - - let provider3 = PeerId::random(); - let rec3 = ProviderRecord { - provider: provider3, - key: key2.clone(), - expires: None, - addresses: Vec::new(), - }; - - // Check adding - provider_storage.add_provider(rec1).unwrap(); - provider_storage.add_provider(rec2.clone()).unwrap(); - provider_storage.add_provider(rec3.clone()).unwrap(); - - // Check local providers retrieval - let provided_collection: HashSet = - HashSet::from_iter(provider_storage.provided().map(|i| i.into_owned())); - - assert_eq!( - HashSet::from_iter(vec![rec2.clone()].into_iter()), - provided_collection - ); - - // Check single provider retrieval - let provided_collection: HashSet = - HashSet::from_iter(provider_storage.providers(&key2).into_iter()); - - assert_eq!( - HashSet::from_iter(vec![rec2.clone(), rec3].into_iter()), - provided_collection - ); - - // Remove provider - provider_storage.remove_provider(&key2, &provider3); - let provided_collection: HashSet = - HashSet::from_iter(provider_storage.providers(&key2).into_iter()); - - assert_eq!( - HashSet::from_iter(vec![rec2].into_iter()), - provided_collection - ); - - Ok(()) -} diff --git a/crates/subspace-networking/examples/get-peers-complex.rs b/crates/subspace-networking/examples/get-peers-complex.rs index 219d823fe13..278b4d6d9db 100644 --- a/crates/subspace-networking/examples/get-peers-complex.rs +++ b/crates/subspace-networking/examples/get-peers-complex.rs @@ -1,13 +1,12 @@ use futures::channel::oneshot; use futures::StreamExt; -use libp2p::identity::ed25519::Keypair; use libp2p::multiaddr::Protocol; -use libp2p::multihash::{Code, MultihashDigest}; use libp2p::PeerId; use parking_lot::Mutex; use std::sync::Arc; use std::time::Duration; -use subspace_networking::{BootstrappedNetworkingParameters, Config, NetworkingParametersManager}; +use subspace_networking::utils::multihash::Multihash; +use subspace_networking::{Config, NetworkingParametersManager}; #[tokio::main] async fn main() { @@ -15,7 +14,6 @@ async fn main() { let mut bootstrap_nodes = Vec::new(); let mut expected_node_id = PeerId::random(); - let mut expected_kaypair = Keypair::generate(); const TOTAL_NODE_COUNT: usize = 100; const EXPECTED_NODE_INDEX: usize = 75; @@ -23,15 +21,11 @@ async fn main() { let mut nodes = Vec::with_capacity(TOTAL_NODE_COUNT); for i in 0..TOTAL_NODE_COUNT { let config = Config { - networking_parameters_registry: BootstrappedNetworkingParameters::new( - bootstrap_nodes.clone(), - ) - .boxed(), listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], allow_non_global_addresses_in_dht: true, + bootstrap_addresses: bootstrap_nodes.clone(), ..Config::default() }; - let keypair = config.keypair.clone().try_into_ed25519().unwrap(); let (node, mut node_runner) = subspace_networking::create(config).unwrap(); @@ -39,7 +33,6 @@ async fn main() { if i == EXPECTED_NODE_INDEX { expected_node_id = node.id(); - expected_kaypair = keypair; } let (node_address_sender, node_address_receiver) = oneshot::channel(); @@ -64,31 +57,31 @@ async fn main() { tokio::time::sleep(Duration::from_millis(40)).await; - let address = node_addr.with(Protocol::P2p(node.id().into())); + let address = node_addr.with(Protocol::P2p(node.id())); bootstrap_nodes.push(address); nodes.push(node); } - let db_path = std::env::temp_dir() - .join("subspace_example_networking_params_db") + let file_path = std::env::temp_dir() + .join("subspace_example_networking_params.bin") .into_boxed_path(); println!( - "Networking parameters database path used (the app creates DB on the first run): \ - {db_path:?}" + "Networking parameters database path used (the app creates file on the first run): \ + {file_path:?}" ); let config = Config { listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], allow_non_global_addresses_in_dht: true, - networking_parameters_registry: NetworkingParametersManager::new( - db_path.as_ref(), - bootstrap_nodes, - ) - .unwrap() - .boxed(), + networking_parameters_registry: Some( + NetworkingParametersManager::new(file_path.as_ref(), Default::default()) + .unwrap() + .boxed(), + ), + bootstrap_addresses: bootstrap_nodes, ..Config::default() }; @@ -101,10 +94,8 @@ async fn main() { node_runner.run().await; }); - node.wait_for_connected_peers().await.unwrap(); - // Prepare multihash to look for in Kademlia - let key = Code::Identity.digest(&expected_kaypair.public().to_bytes()); + let key = Multihash::from(node.id()); let peers = node .get_closest_peers(key) diff --git a/crates/subspace-networking/examples/get-peers.rs b/crates/subspace-networking/examples/get-peers.rs index 953cfcc2b5a..8371c45847c 100644 --- a/crates/subspace-networking/examples/get-peers.rs +++ b/crates/subspace-networking/examples/get-peers.rs @@ -1,12 +1,10 @@ use futures::channel::oneshot; use futures::StreamExt; use libp2p::multiaddr::Protocol; -use libp2p::multihash::Code; use parking_lot::Mutex; use std::sync::Arc; use std::time::Duration; -use subspace_core_primitives::{crypto, PieceIndexHash, U256}; -use subspace_networking::{BootstrappedNetworkingParameters, Config}; +use subspace_networking::Config; #[tokio::main] async fn main() { @@ -42,13 +40,11 @@ async fn main() { let node_1_addr = node_1_address_receiver.await.unwrap(); drop(on_new_listener_handler); + let bootstrap_addresses = vec![node_1_addr.with(Protocol::P2p(node_1.id()))]; let config_2 = Config { - networking_parameters_registry: BootstrappedNetworkingParameters::new(vec![ - node_1_addr.with(Protocol::P2p(node_1.id().into())) - ]) - .boxed(), listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], allow_non_global_addresses_in_dht: true, + bootstrap_addresses, ..Config::default() }; @@ -62,13 +58,8 @@ async fn main() { tokio::time::sleep(Duration::from_secs(1)).await; - let hashed_peer_id = PieceIndexHash::from(crypto::blake2b_256_hash(&node_1.id().to_bytes())); - let key = libp2p::multihash::MultihashDigest::digest( - &Code::Identity, - &U256::from(hashed_peer_id).to_be_bytes(), - ); let peer_id = node_2 - .get_closest_peers(key) + .get_closest_peers(node_1.id().into()) .await .unwrap() .next() diff --git a/crates/subspace-networking/examples/networking.rs b/crates/subspace-networking/examples/networking.rs index 98b66edc4c4..ccd4b3bd0a9 100644 --- a/crates/subspace-networking/examples/networking.rs +++ b/crates/subspace-networking/examples/networking.rs @@ -7,7 +7,7 @@ use libp2p::multiaddr::Protocol; use parking_lot::Mutex; use std::sync::Arc; use std::time::Duration; -use subspace_networking::{BootstrappedNetworkingParameters, Config}; +use subspace_networking::Config; const TOPIC: &str = "Foo"; @@ -47,13 +47,11 @@ async fn main() { let mut subscription = node_1.subscribe(Sha256Topic::new(TOPIC)).await.unwrap(); + let bootstrap_addresses = vec![node_1_addr.with(Protocol::P2p(node_1.id()))]; let config_2 = Config { - networking_parameters_registry: BootstrappedNetworkingParameters::new(vec![ - node_1_addr.with(Protocol::P2p(node_1.id().into())) - ]) - .boxed(), listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], allow_non_global_addresses_in_dht: true, + bootstrap_addresses, ..Config::default() }; diff --git a/crates/subspace-networking/examples/requests.rs b/crates/subspace-networking/examples/requests.rs index 5e44f454ca9..4dedce1b114 100644 --- a/crates/subspace-networking/examples/requests.rs +++ b/crates/subspace-networking/examples/requests.rs @@ -1,17 +1,11 @@ use futures::channel::oneshot; -use libp2p::metrics::Metrics; use libp2p::multiaddr::Protocol; use parity_scale_codec::{Decode, Encode}; use parking_lot::Mutex; -use prometheus_client::registry::Registry; use std::sync::Arc; use std::time::Duration; -use subspace_networking::{ - start_prometheus_metrics_server, BootstrappedNetworkingParameters, Config, GenericRequest, - GenericRequestHandler, -}; +use subspace_networking::{Config, GenericRequest, GenericRequestHandler}; use tokio::time::sleep; -use tracing::error; #[derive(Encode, Decode)] struct ExampleRequest; @@ -29,9 +23,6 @@ struct ExampleResponse; async fn main() { tracing_subscriber::fmt::init(); - let mut metric_registry = Registry::default(); - let metrics = Metrics::new(&mut metric_registry); - let config_1 = Config { listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], allow_non_global_addresses_in_dht: true, @@ -43,26 +34,10 @@ async fn main() { Some(ExampleResponse) }, )], - metrics: Some(metrics), ..Config::default() }; let (node_1, mut node_runner_1) = subspace_networking::create(config_1).unwrap(); - // Init prometheus - let prometheus_metrics_server_address = "127.0.0.1:63000".parse().unwrap(); - tokio::task::spawn(async move { - if let Err(err) = - start_prometheus_metrics_server(prometheus_metrics_server_address, metric_registry) - .await - { - error!( - ?prometheus_metrics_server_address, - ?err, - "Prometheus metrics server failed to start." - ) - } - }); - println!("Node 1 ID is {}", node_1.id()); let (node_1_address_sender, node_1_address_receiver) = oneshot::channel(); @@ -86,16 +61,14 @@ async fn main() { let node_1_addr = node_1_address_receiver.await.unwrap(); drop(on_new_listener_handler); + let bootstrap_addresses = vec![node_1_addr.with(Protocol::P2p(node_1.id()))]; let config_2 = Config { - networking_parameters_registry: BootstrappedNetworkingParameters::new(vec![ - node_1_addr.with(Protocol::P2p(node_1.id().into())) - ]) - .boxed(), listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], allow_non_global_addresses_in_dht: true, request_response_protocols: vec![GenericRequestHandler::::create( |_, _| async { None }, )], + bootstrap_addresses, ..Config::default() }; diff --git a/crates/subspace-networking/src/behavior.rs b/crates/subspace-networking/src/behavior.rs index a28e1598b8d..8f05b6813e9 100644 --- a/crates/subspace-networking/src/behavior.rs +++ b/crates/subspace-networking/src/behavior.rs @@ -1,14 +1,21 @@ pub(crate) mod persistent_parameters; -pub(crate) mod provider_storage; #[cfg(test)] mod tests; +use crate::connected_peers::{ + Behaviour as ConnectedPeersBehaviour, Config as ConnectedPeersConfig, + Event as ConnectedPeersEvent, +}; +use crate::peer_info::{ + Behaviour as PeerInfoBehaviour, Config as PeerInfoConfig, Event as PeerInfoEvent, +}; use crate::request_responses::{ Event as RequestResponseEvent, RequestHandler, RequestResponsesBehaviour, }; use crate::reserved_peers::{ Behaviour as ReservedPeersBehaviour, Config as ReservedPeersConfig, Event as ReservedPeersEvent, }; +use crate::PeerInfoProvider; use derive_more::From; use libp2p::allow_block_list::{Behaviour as AllowBlockListBehaviour, BlockedPeers}; use libp2p::connection_limits::{Behaviour as ConnectionLimitsBehaviour, ConnectionLimits}; @@ -42,10 +49,23 @@ pub(crate) struct BehaviorConfig { pub(crate) connection_limits: ConnectionLimits, /// The configuration for the [`ReservedPeersBehaviour`]. pub(crate) reserved_peers: ReservedPeersConfig, + /// The configuration for the [`PeerInfo`] protocol. + pub(crate) peer_info_config: PeerInfoConfig, + /// Provides peer-info for local peer. + pub(crate) peer_info_provider: Option, + /// The configuration for the [`ConnectedPeers`] protocol (general instance). + pub(crate) general_connected_peers_config: Option, + /// The configuration for the [`ConnectedPeers`] protocol (special instance). + pub(crate) special_connected_peers_config: Option, } +#[derive(Debug, Clone, Copy)] +pub(crate) struct GeneralConnectedPeersInstance; +#[derive(Debug, Clone, Copy)] +pub(crate) struct SpecialConnectedPeersInstance; + #[derive(NetworkBehaviour)] -#[behaviour(out_event = "Event")] +#[behaviour(to_swarm = "Event")] #[behaviour(event_process = false)] pub(crate) struct Behavior { pub(crate) identify: Identify, @@ -56,6 +76,11 @@ pub(crate) struct Behavior { pub(crate) connection_limits: ConnectionLimitsBehaviour, pub(crate) block_list: BlockListBehaviour, pub(crate) reserved_peers: ReservedPeersBehaviour, + pub(crate) peer_info: Toggle, + pub(crate) general_connected_peers: + Toggle>, + pub(crate) special_connected_peers: + Toggle>, } impl Behavior @@ -81,19 +106,30 @@ where }) .into(); + let peer_info = config + .peer_info_provider + .map(|provider| PeerInfoBehaviour::new(config.peer_info_config, provider)); + Self { identify: Identify::new(config.identify), kademlia, gossipsub, ping: Ping::default(), - request_response: RequestResponsesBehaviour::new( - config.request_response_protocols.into_iter(), - ) - //TODO: Convert to an error. - .expect("RequestResponse protocols registration failed."), + request_response: RequestResponsesBehaviour::new(config.request_response_protocols) + //TODO: Convert to an error. + .expect("RequestResponse protocols registration failed."), connection_limits: ConnectionLimitsBehaviour::new(config.connection_limits), block_list: BlockListBehaviour::default(), reserved_peers: ReservedPeersBehaviour::new(config.reserved_peers), + peer_info: peer_info.into(), + general_connected_peers: config + .general_connected_peers_config + .map(ConnectedPeersBehaviour::new) + .into(), + special_connected_peers: config + .special_connected_peers_config + .map(ConnectedPeersBehaviour::new) + .into(), } } } @@ -108,4 +144,7 @@ pub(crate) enum Event { /// Event stub for connection limits and block list behaviours. We won't receive such events. VoidEventStub(VoidEvent), ReservedPeers(ReservedPeersEvent), + PeerInfo(PeerInfoEvent), + GeneralConnectedPeers(ConnectedPeersEvent), + SpecialConnectedPeers(ConnectedPeersEvent), } diff --git a/crates/subspace-networking/src/behavior/persistent_parameters.rs b/crates/subspace-networking/src/behavior/persistent_parameters.rs index 167b972112a..46e6fb89e2c 100644 --- a/crates/subspace-networking/src/behavior/persistent_parameters.rs +++ b/crates/subspace-networking/src/behavior/persistent_parameters.rs @@ -1,41 +1,182 @@ -use crate::utils::{convert_multiaddresses, CollectionBatcher, PeerAddress}; +use crate::utils::{AsyncJoinOnDrop, CollectionBatcher, Handler, HandlerFn, PeerAddress}; use async_trait::async_trait; -use chrono::{DateTime, Utc}; +use event_listener_primitives::HandlerId; +use fs2::FileExt; use futures::future::Fuse; use futures::FutureExt; use libp2p::multiaddr::Protocol; use libp2p::{Multiaddr, PeerId}; use lru::LruCache; -use parity_db::{Db, Options}; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -use std::hash::Hash; +use memmap2::{MmapMut, MmapOptions}; +use parity_scale_codec::{Compact, CompactLen, Decode, Encode}; +use parking_lot::Mutex; +use std::collections::HashSet; +use std::fs::OpenOptions; +use std::io::{Read, Seek, SeekFrom}; use std::num::NonZeroUsize; -use std::ops::Add; use std::path::Path; use std::pin::Pin; +use std::str::FromStr; use std::sync::Arc; -use std::time::Duration; +use std::time::{Duration, SystemTime}; +use std::{io, mem}; +use subspace_core_primitives::crypto::blake3_hash; +use subspace_core_primitives::Blake3Hash; use thiserror::Error; use tokio::time::{sleep, Sleep}; -use tracing::{debug, trace}; +use tracing::{debug, error, trace, warn}; -/// Parity DB error type alias. -pub type ParityDbError = parity_db::Error; +/// Defines optional time for address dial failure +type FailureTime = Option; -// Defines optional time for address dial failure -type FailureTime = Option>; - -// Size of the LRU cache for peers. +/// Size of the LRU cache for peers. const PEER_CACHE_SIZE: NonZeroUsize = NonZeroUsize::new(100).expect("Not zero; qed"); -// Size of the LRU cache for addresses. +/// Size of the LRU cache for addresses of a single peer ID. const ADDRESSES_CACHE_SIZE: NonZeroUsize = NonZeroUsize::new(30).expect("Not zero; qed"); -// Pause duration between network parameters save. +/// Pause duration between network parameters save. const DATA_FLUSH_DURATION_SECS: u64 = 5; -// Defines a batch size for a combined collection for known peers addresses and boostrap addresses. -const PEERS_ADDRESSES_BATCH_SIZE: usize = 30; -// Defines an expiration period for the peer marked for the removal. -const REMOVE_KNOWN_PEERS_GRACE_PERIOD_SECS: i64 = 86400; // 1 DAY +/// Defines a batch size for a combined collection for known peers addresses and boostrap addresses. +pub(crate) const PEERS_ADDRESSES_BATCH_SIZE: usize = 30; +/// Defines an expiration period for the peer marked for the removal. +const REMOVE_KNOWN_PEERS_GRACE_PERIOD_SECS: Duration = Duration::from_secs(3600 * 24); +/// Defines an expiration period for the peer marked for the removal for Kademlia DHT. +const REMOVE_KNOWN_PEERS_GRACE_PERIOD_FOR_KADEMLIA_SECS: Duration = Duration::from_secs(3600); + +/// Defines the event triggered when the peer address is removed from the permanent storage. +#[derive(Debug, Clone)] +pub struct PeerAddressRemovedEvent { + /// Peer ID + pub peer_id: PeerId, + /// Peer address + pub address: Multiaddr, + /// No address left in the permanent storage. + pub last_address: bool, +} + +#[derive(Debug, Encode, Decode)] +struct EncodableKnownPeerAddress { + multiaddr: Vec, + /// Failure time as Unix timestamp in seconds + failure_time: Option, +} + +#[derive(Debug, Encode, Decode)] +struct EncodableKnownPeers { + timestamp: u64, + // Each entry is a tuple of peer ID + list of multiaddresses with corresponding failure time + known_peers: Vec<(Vec, Vec)>, +} + +impl EncodableKnownPeers { + fn into_cache(self) -> LruCache> { + let mut peers_cache = LruCache::new(PEER_CACHE_SIZE); + + 'peers: for (peer_id, addresses) in self.known_peers { + let mut peer_cache = LruCache::::new(ADDRESSES_CACHE_SIZE); + + let peer_id = match PeerId::from_bytes(&peer_id) { + Ok(peer_id) => peer_id, + Err(error) => { + debug!(%error, "Failed to decode known peer ID, skipping peer entry"); + continue; + } + }; + for address in addresses { + let multiaddr = match Multiaddr::try_from(address.multiaddr) { + Ok(multiaddr) => multiaddr, + Err(error) => { + debug!( + %error, + "Failed to decode known peer multiaddress, skipping peer entry" + ); + continue 'peers; + } + }; + + peer_cache.push( + multiaddr, + address.failure_time.map(|failure_time| { + SystemTime::UNIX_EPOCH + Duration::from_secs(failure_time) + }), + ); + } + + peers_cache.push(peer_id, peer_cache); + } + + peers_cache + } + + fn from_cache(cache: &LruCache>) -> Self { + let single_peer_encoded_address_size = + NetworkingParametersManager::single_peer_encoded_address_size(); + Self { + timestamp: SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("Never before Unix epoch; qed") + .as_secs(), + known_peers: cache + .iter() + .map(|(peer_id, addresses)| { + ( + peer_id.to_bytes(), + addresses + .iter() + .filter_map(|(multiaddr, failure_time)| { + let multiaddr_bytes = multiaddr.to_vec(); + + if multiaddr_bytes.encoded_size() > single_peer_encoded_address_size + { + // Skip unexpectedly large multiaddresses + debug!( + encoded_multiaddress_size = %multiaddr_bytes.encoded_size(), + limit = %single_peer_encoded_address_size, + ?multiaddr, + "Unexpectedly large multiaddress" + ); + return None; + } + + Some(EncodableKnownPeerAddress { + multiaddr: multiaddr_bytes, + failure_time: failure_time.map(|failure_time| { + failure_time + .duration_since(SystemTime::UNIX_EPOCH) + .expect("Never before Unix epoch; qed") + .as_secs() + }), + }) + }) + .collect(), + ) + }) + .collect(), + } + } +} + +/// A/b slots with known peers where we write serialized known peers in one after another +struct KnownPeersSlots { + a: MmapMut, + b: MmapMut, +} + +impl KnownPeersSlots { + fn write_to_inactive_slot(&mut self, encodable_known_peers: &EncodableKnownPeers) { + let known_peers_bytes = encodable_known_peers.encode(); + let (encoded_bytes, remaining_bytes) = self.a.split_at_mut(known_peers_bytes.len()); + encoded_bytes.copy_from_slice(&known_peers_bytes); + // Write checksum + remaining_bytes[..mem::size_of::()] + .copy_from_slice(&blake3_hash(&known_peers_bytes)); + if let Err(error) = self.a.flush() { + warn!(%error, "Failed to flush known peers to disk"); + } + + // Swap slots such that we write into the opposite each time + mem::swap(&mut self.a, &mut self.b); + } +} /// Defines operations with the networking parameters. #[async_trait] @@ -47,7 +188,7 @@ pub trait NetworkingParametersRegistry: Send + Sync { async fn remove_known_peer_addresses(&mut self, peer_id: PeerId, addresses: Vec); /// Unregisters associated addresses for peer ID. - async fn remove_all_known_peer_addresses(&mut self, peer_id: PeerId); + fn remove_all_known_peer_addresses(&mut self, peer_id: PeerId); /// Returns a batch of the combined collection of known addresses from networking parameters DB /// and boostrap addresses from networking parameters initialization. @@ -60,71 +201,61 @@ pub trait NetworkingParametersRegistry: Send + Sync { /// Drive async work in the persistence provider async fn run(&mut self); - /// Enables Clone implementation for `Box` - fn clone_box(&self) -> Box; + /// Triggers when we removed the peer address from the permanent storage. Returns optional + /// event HandlerId. Option enables stub implementation. One of the usages is to notify + /// Kademlia about the expired(unreachable) address when it check for how long address was + /// unreachable. + fn on_unreachable_address( + &mut self, + handler: HandlerFn, + ) -> Option; } -impl Clone for Box { - fn clone(&self) -> Self { - self.clone_box() - } -} - -/// Networking manager implementation with bootstrapped addresses. All other operations muted. +/// Networking manager implementation with NOOP implementation. #[derive(Clone, Default)] -pub struct BootstrappedNetworkingParameters { - bootstrap_addresses: Vec, -} +pub(crate) struct StubNetworkingParametersManager; -impl BootstrappedNetworkingParameters { - /// Creates a new instance of `BootstrappedNetworkingParameters`. - pub fn new(bootstrap_addresses: Vec) -> Self { - Self { - bootstrap_addresses, - } - } - - fn bootstrap_addresses(&self) -> Vec { - convert_multiaddresses(self.bootstrap_addresses.clone()) - } - - /// Returns an instance of `BootstrappedNetworkingParameters` as the `Box` reference. +impl StubNetworkingParametersManager { + /// Returns an instance of `StubNetworkingParametersManager` as the `Box` reference. pub fn boxed(self) -> Box { Box::new(self) } } #[async_trait] -impl NetworkingParametersRegistry for BootstrappedNetworkingParameters { +impl NetworkingParametersRegistry for StubNetworkingParametersManager { async fn add_known_peer(&mut self, _: PeerId, _: Vec) {} async fn remove_known_peer_addresses(&mut self, _peer_id: PeerId, _addresses: Vec) {} - async fn remove_all_known_peer_addresses(&mut self, _peer_id: PeerId) {} + fn remove_all_known_peer_addresses(&mut self, _peer_id: PeerId) {} async fn next_known_addresses_batch(&mut self) -> Vec { - self.bootstrap_addresses() + Vec::new() } async fn run(&mut self) { - futures::future::pending().await // never resolves + // Never resolves + futures::future::pending().await } - fn clone_box(&self) -> Box { - Box::new(self.clone()) + fn on_unreachable_address( + &mut self, + _handler: HandlerFn, + ) -> Option { + None } } /// Networking parameters persistence errors. #[derive(Debug, Error)] pub enum NetworkParametersPersistenceError { - /// Parity DB error. - #[error("DB error: {0}")] - Db(#[from] parity_db::Error), - - /// Serialization error. - #[error("JSON serialization error: {0}")] - JsonSerialization(#[from] serde_json::Error), + /// I/O error. + #[error("I/O error: {0}")] + Io(#[from] io::Error), + /// Can't preallocate known peers file, probably not enough space on disk + #[error("Can't preallocate known peers file, probably not enough space on disk: {0}")] + CantPreallocateKnownPeersFile(io::Error), } /// Handles networking parameters. It manages network parameters set and its persistence. @@ -135,16 +266,24 @@ pub struct NetworkingParametersManager { known_peers: LruCache>, // Period between networking parameters saves. networking_parameters_save_delay: Pin>>, - // Parity DB instance - db: Arc, - // Column ID to persist parameters - column_id: u8, - // Key to persistent parameters - object_id: &'static [u8], - // Bootstrap addresses provided on creation - bootstrap_addresses: Vec, + /// Slots backed by file that store known peers + known_peers_slots: Arc>, // Provides batching capabilities for the address collection (it stores the last batch index) collection_batcher: CollectionBatcher, + // Event handler triggered when we decide to remove address from the storage. + address_removed: Handler, + // Peer ID list to filter on address adding. + ignore_peer_list: HashSet, +} + +impl Drop for NetworkingParametersManager { + fn drop(&mut self) { + if self.cache_need_saving { + self.known_peers_slots + .lock() + .write_to_inactive_slot(&EncodableKnownPeers::from_cache(&self.known_peers)); + } + } } impl NetworkingParametersManager { @@ -152,43 +291,125 @@ impl NetworkingParametersManager { /// On object creation it starts a job for networking parameters cache handling. pub fn new( path: &Path, - bootstrap_addresses: Vec, + ignore_peer_list: HashSet, ) -> Result { - let mut options = Options::with_columns(path, 1); - // We don't use stats - options.stats = false; - - let db = Db::open_or_create(&options)?; - let column_id = 0u8; - let object_id = b"global_networking_parameters_key"; - - // load known peers cache. - let cache = db - .get(column_id, object_id)? - .map(|data| { - let result = serde_json::from_slice::(&data) - .map(|data| data.to_cache()); - - if result.is_ok() { - debug!("Networking parameters loaded from DB"); + let mut file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(path)?; + + let known_addresses_size = Self::known_addresses_size(); + let file_size = Self::file_size(); + // Try reading existing encoded known peers from file + let mut maybe_newest_known_addresses = None::; + + { + let mut file_contents = Vec::with_capacity(file_size); + file.read_to_end(&mut file_contents)?; + if !file_contents.is_empty() { + for known_addresses_bytes in file_contents.chunks_exact(file_contents.len() / 2) { + let known_addresses = + match EncodableKnownPeers::decode(&mut &*known_addresses_bytes) { + Ok(known_addresses) => known_addresses, + Err(error) => { + debug!(%error, "Failed to decode encodable known peers"); + continue; + } + }; + + let (encoded_bytes, remaining_bytes) = + known_addresses_bytes.split_at(known_addresses.encoded_size()); + if remaining_bytes.len() < mem::size_of::() { + debug!( + remaining_bytes = %remaining_bytes.len(), + "Not enough bytes to decode checksum, file was likely corrupted" + ); + continue; + } + + // Verify checksum + let actual_hash = blake3_hash(encoded_bytes); + let expected_hash = &remaining_bytes[..mem::size_of::()]; + if actual_hash != expected_hash { + debug!( + encoded_bytes_len = %encoded_bytes.len(), + ?actual_hash, + ?expected_hash, + "Hash doesn't match, possible disk corruption or file was just \ + created, ignoring" + ); + continue; + } + + match &mut maybe_newest_known_addresses { + Some(newest_known_addresses) => { + if newest_known_addresses.timestamp < known_addresses.timestamp { + *newest_known_addresses = known_addresses; + } + } + None => { + maybe_newest_known_addresses.replace(known_addresses); + } + } } + } + } - result - }) - .unwrap_or_else(|| Ok(LruCache::new(PEER_CACHE_SIZE)))?; + // *2 because we have a/b parts of the file + let file_resized = if file.seek(SeekFrom::End(0))? != file_size as u64 { + // Allocating the whole file (`set_len` below can create a sparse file, which will cause + // writes to fail later) + file.allocate(file_size as u64) + .map_err(NetworkParametersPersistenceError::CantPreallocateKnownPeersFile)?; + // Truncating file (if necessary) + file.set_len(file_size as u64)?; + true + } else { + false + }; + + let mut a_mmap = unsafe { + MmapOptions::new() + .len(known_addresses_size) + .map_mut(&file)? + }; + let mut b_mmap = unsafe { + MmapOptions::new() + .offset(known_addresses_size as u64) + .len(known_addresses_size) + .map_mut(&file)? + }; + + if file_resized { + // File might have been resized, write current known addresses into it + if let Some(newest_known_addresses) = &maybe_newest_known_addresses { + let bytes = newest_known_addresses.encode(); + a_mmap[..bytes.len()].copy_from_slice(&bytes); + a_mmap.flush()?; + b_mmap[..bytes.len()].copy_from_slice(&bytes); + b_mmap.flush()?; + } + } + + let known_peers = maybe_newest_known_addresses + .map(EncodableKnownPeers::into_cache) + .unwrap_or_else(|| LruCache::new(PEER_CACHE_SIZE)); Ok(Self { cache_need_saving: false, - db: Arc::new(db), - column_id, - object_id, - known_peers: cache, + known_peers, networking_parameters_save_delay: Self::default_delay(), - bootstrap_addresses, + known_peers_slots: Arc::new(Mutex::new(KnownPeersSlots { + a: a_mmap, + b: b_mmap, + })), collection_batcher: CollectionBatcher::new( NonZeroUsize::new(PEERS_ADDRESSES_BATCH_SIZE) .expect("Manual non-zero initialization failed."), ), + address_removed: Default::default(), + ignore_peer_list, }) } @@ -202,21 +423,10 @@ impl NetworkingParametersManager { .collect() } - // Returns boostrap addresses from networking parameters initialization. - // It removes p2p-protocol suffix. - fn bootstrap_addresses(&self) -> Vec { - convert_multiaddresses(self.bootstrap_addresses.clone()) - } - - // Helps create a copy of the internal LruCache - fn clone_known_peers(&self) -> LruCache> { - let mut known_peers = LruCache::new(self.known_peers.cap()); - - for (peer_id, addresses) in self.known_peers.iter() { - known_peers.push(*peer_id, clone_lru_cache(addresses, ADDRESSES_CACHE_SIZE)); - } - - known_peers + /// Size of the backing file on disk + pub fn file_size() -> usize { + // *2 because we have a/b parts of the file + Self::known_addresses_size() * 2 } /// Creates a reference to the `NetworkingParametersRegistry` trait implementation. @@ -228,25 +438,56 @@ impl NetworkingParametersManager { fn default_delay() -> Pin>> { Box::pin(sleep(Duration::from_secs(DATA_FLUSH_DURATION_SECS)).fuse()) } -} -// Generic LRU-cache cloning function. -fn clone_lru_cache( - cache: &LruCache, - cap: NonZeroUsize, -) -> LruCache { - let mut cloned_cache = LruCache::new(cap); + fn single_peer_encoded_address_size() -> usize { + let multiaddr = Multiaddr::from_str( + "/ip4/127.0.0.1/udp/1234/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp", + ) + .expect("Valid multiaddr; qed"); + // Use multiaddr size that is 3x larger than typical, should be enough for most practical + // cases + multiaddr.to_vec().encoded_size() * 3 + } - for (key, value) in cache.iter() { - cloned_cache.push(key.clone(), value.clone()); + /// Size of single peer known addresses, this is an estimate and in some pathological cases peer + /// will have to be rejected if encoding exceeds this length. + fn single_peer_encoded_size() -> usize { + // Peer ID encoding + compact encoding of the length of list of addresses + (length of a + // single peer address entry + optional failure time) * number of entries + PeerId::random().to_bytes().encoded_size() + + Compact::compact_len(&(ADDRESSES_CACHE_SIZE.get() as u32)) + + (Self::single_peer_encoded_address_size() + Some(0u64).encoded_size()) + * ADDRESSES_CACHE_SIZE.get() } - cloned_cache + /// Size of known addresses and accompanying metadata. + /// + /// NOTE: This is max size that needs to be allocated on disk for successful write of a single + /// `known_addresses` copy, the actual written data can occupy only a part of this size + fn known_addresses_size() -> usize { + // Timestamp (when was written) + compact encoding of the length of peer records + peer + // records + checksum + mem::size_of::() + + Compact::compact_len(&(PEER_CACHE_SIZE.get() as u32)) + + Self::single_peer_encoded_size() * PEER_CACHE_SIZE.get() + + mem::size_of::() + } } #[async_trait] impl NetworkingParametersRegistry for NetworkingParametersManager { async fn add_known_peer(&mut self, peer_id: PeerId, addresses: Vec) { + if self.ignore_peer_list.contains(&peer_id) { + debug!( + %peer_id, + addr_num=addresses.len(), + "Adding new peer addresses canceled (ignore list): {:?}", + addresses + ); + + return; + } + debug!( %peer_id, addr_num=addresses.len(), @@ -284,17 +525,22 @@ impl NetworkingParametersRegistry for NetworkingParametersManager { async fn remove_known_peer_addresses(&mut self, peer_id: PeerId, addresses: Vec) { trace!(%peer_id, "Remove peer addresses from the networking parameters registry: {:?}", addresses); - remove_known_peer_addresses_internal( + let removed_addresses = remove_known_peer_addresses_internal( &mut self.known_peers, peer_id, addresses, - chrono::Duration::seconds(REMOVE_KNOWN_PEERS_GRACE_PERIOD_SECS), + REMOVE_KNOWN_PEERS_GRACE_PERIOD_SECS, + REMOVE_KNOWN_PEERS_GRACE_PERIOD_FOR_KADEMLIA_SECS, ); + for event in removed_addresses { + self.address_removed.call_simple(&event); + } + self.cache_need_saving = true; } - async fn remove_all_known_peer_addresses(&mut self, peer_id: PeerId) { + fn remove_all_known_peer_addresses(&mut self, peer_id: PeerId) { trace!(%peer_id, "Remove all peer addresses from the networking parameters registry"); self.known_peers.pop(&peer_id); @@ -304,12 +550,7 @@ impl NetworkingParametersRegistry for NetworkingParametersManager { async fn next_known_addresses_batch(&mut self) -> Vec { // We take cached known addresses and combine them with manually provided bootstrap addresses. - let combined_addresses = self - .known_addresses() - .await - .into_iter() - .chain(self.bootstrap_addresses().into_iter()) - .collect::>(); + let combined_addresses = self.known_addresses().await.into_iter().collect::>(); trace!( "Peer addresses batch requested. Total list size: {}", @@ -328,20 +569,17 @@ impl NetworkingParametersRegistry for NetworkingParametersManager { (&mut self.networking_parameters_save_delay).await; if self.cache_need_saving { - // save accumulated cache to DB - let dto = NetworkingParameters::from_cache(self.clone_known_peers()); - let save_result = serde_json::to_vec(&dto) - .map_err(NetworkParametersPersistenceError::from) - .and_then(|data| { - let tx = vec![(self.column_id, self.object_id, Some(data))]; - - self.db.commit(tx).map_err(|err| err.into()) - }); - - if let Err(err) = save_result { - debug!(error=%err, "Error on saving network parameters"); - } else { - trace!("Networking parameters saved to DB"); + let known_peers = EncodableKnownPeers::from_cache(&self.known_peers); + let known_peers_slots = Arc::clone(&self.known_peers_slots); + let write_known_peers_fut = + AsyncJoinOnDrop::new(tokio::task::spawn_blocking(move || { + known_peers_slots + .lock() + .write_to_inactive_slot(&known_peers); + })); + + if let Err(error) = write_known_peers_fut.await { + error!(%error, "Failed to write known peers"); } self.cache_need_saving = false; @@ -351,65 +589,43 @@ impl NetworkingParametersRegistry for NetworkingParametersManager { } } - fn clone_box(&self) -> Box { - Self { - cache_need_saving: self.cache_need_saving, - known_peers: self.clone_known_peers(), - networking_parameters_save_delay: Self::default_delay(), - db: self.db.clone(), - column_id: self.column_id, - object_id: self.object_id, - bootstrap_addresses: self.bootstrap_addresses.clone(), - collection_batcher: self.collection_batcher.clone(), - } - .boxed() + fn on_unreachable_address( + &mut self, + handler: HandlerFn, + ) -> Option { + let handler_id = self.address_removed.add(handler); + + Some(handler_id) } } -// Helper struct for NetworkingPersistence implementations (data transfer object). -#[derive(Default, Debug, Serialize, Deserialize)] -struct NetworkingParameters { - pub known_peers: HashMap>, -} +/// Removes a P2p protocol suffix from the multiaddress if any. +pub(crate) fn remove_p2p_suffix(mut address: Multiaddr) -> Multiaddr { + let last_protocol = address.pop(); -impl NetworkingParameters { - fn from_cache(cache: LruCache>) -> Self { - Self { - known_peers: cache - .into_iter() - .map(|(peer_id, addresses)| { - (peer_id, addresses.into_iter().collect::>()) - }) - .collect::>(), - } + if let Some(Protocol::P2p(_)) = &last_protocol { + return address; } - fn to_cache(&self) -> LruCache> { - let mut peers_cache = - LruCache::>::new(PEER_CACHE_SIZE); - - for (peer_id, address_map) in self.known_peers.iter() { - let mut address_cache = LruCache::::new(ADDRESSES_CACHE_SIZE); - - for (address, last_failed) in address_map.iter() { - address_cache.push(address.clone(), *last_failed); - } - peers_cache.push(*peer_id, address_cache); - } - - peers_cache + if let Some(protocol) = last_protocol { + address.push(protocol) } + + address } -// Removes a P2p protocol suffix from the multiaddress if any. -fn remove_p2p_suffix(address: Multiaddr) -> Multiaddr { - let mut modified_address = address.clone(); +/// Appends a P2p protocol suffix to the multiaddress if require3d. +pub(crate) fn append_p2p_suffix(peer_id: PeerId, mut address: Multiaddr) -> Multiaddr { + let last_protocol = address.pop(); - if let Some(Protocol::P2p(_)) = modified_address.pop() { - modified_address - } else { - address + if let Some(protocol) = last_protocol { + if !matches!(protocol, Protocol::P2p(..)) { + address.push(protocol) + } } + address.push(Protocol::P2p(peer_id)); + + address } // Testable implementation of the `remove_known_peer_addresses` @@ -417,42 +633,65 @@ pub(super) fn remove_known_peer_addresses_internal( known_peers: &mut LruCache>, peer_id: PeerId, addresses: Vec, - expired_address_duration: chrono::Duration, -) { + expired_address_duration_persistent_storage: Duration, + expired_address_duration_kademlia: Duration, +) -> Vec { + let mut address_removed_events = Vec::new(); + let now = SystemTime::now(); + addresses .into_iter() .map(remove_p2p_suffix) .for_each(|addr| { // if peer_id is present in the cache if let Some(addresses) = known_peers.peek_mut(&peer_id) { + let last_address = addresses.contains(&addr) && addresses.len() == 1; // Get mutable reference to first_failed_time for the address without updating // the item's position in the cache if let Some(first_failed_time) = addresses.peek_mut(&addr) { // if we failed previously with this address if let Some(time) = first_failed_time { - // if we failed first time more than a day ago - if time.add(expired_address_duration) < Utc::now() { + // if we failed first time more than an hour ago (for Kademlia) + if *time + expired_address_duration_kademlia < now { + let address_removed = PeerAddressRemovedEvent{ + peer_id, + address: addr.clone(), + last_address + }; + + address_removed_events.push(address_removed); + + trace!(%peer_id, "Address was marked for removal from Kademlia: {:?}", addr); + } + + // if we failed first time more than a day ago (for persistent cache) + if *time + expired_address_duration_persistent_storage < now { // Remove a failed address addresses.pop(&addr); // If the last address for peer - if addresses.is_empty() { + if last_address { known_peers.pop(&peer_id); trace!(%peer_id, "Peer removed from the cache"); } - trace!(%peer_id, "Address removed from the cache: {:?}", addr); + trace!(%peer_id, "Address removed from the persistent cache: {:?}", addr); } else { - trace!(%peer_id, "Saving failed connection attempt to a peer: {:?}", addr); + trace!( + %peer_id, "Saving failed connection attempt to a peer: {:?}", + addr + ); } } else { // Set failure time - first_failed_time.replace(Utc::now()); + first_failed_time.replace(now); trace!(%peer_id, "Address marked for removal from the cache: {:?}", addr); } } } }); + + address_removed_events } diff --git a/crates/subspace-networking/src/behavior/provider_storage.rs b/crates/subspace-networking/src/behavior/provider_storage.rs deleted file mode 100644 index 6296074446a..00000000000 --- a/crates/subspace-networking/src/behavior/provider_storage.rs +++ /dev/null @@ -1,34 +0,0 @@ -mod providers; - -use libp2p::kad::record::Key; -use libp2p::kad::{store, ProviderRecord}; -use libp2p::PeerId; -#[cfg(test)] -pub(crate) use providers::{instant_to_micros, micros_to_instant}; -pub use providers::{MemoryProviderStorage, ParityDbProviderStorage, VoidProviderStorage}; -use std::borrow::Cow; - -/// A trait for providers storages - wrapper around `provider` functions of the libp2p RecordStore. -pub trait ProviderStorage { - /// Provider record iterator. - type ProvidedIter<'a>: Iterator> - where - Self: 'a; - - /// Adds a provider record to the store. - /// - /// A record store only needs to store a number of provider records - /// for a key corresponding to the replication factor and should - /// store those records whose providers are closest to the key. - fn add_provider(&self, record: ProviderRecord) -> store::Result<()>; - - /// Gets a copy of the stored provider records for the given key. - fn providers(&self, key: &Key) -> Vec; - - /// Gets an iterator over all stored provider records for which the - /// node owning the store is itself the provider. - fn provided(&self) -> Self::ProvidedIter<'_>; - - /// Removes a provider record from the store. - fn remove_provider(&self, k: &Key, p: &PeerId); -} diff --git a/crates/subspace-networking/src/behavior/provider_storage/providers.rs b/crates/subspace-networking/src/behavior/provider_storage/providers.rs deleted file mode 100644 index 1521b8ef87c..00000000000 --- a/crates/subspace-networking/src/behavior/provider_storage/providers.rs +++ /dev/null @@ -1,712 +0,0 @@ -#[cfg(test)] -mod tests; - -use super::ProviderStorage; -use crate::utils::unique_record_binary_heap::UniqueRecordBinaryHeap; -use either::Either; -use libp2p::kad::record::Key; -use libp2p::kad::store::{MemoryStoreConfig, RecordStore}; -use libp2p::kad::{store, ProviderRecord, K_VALUE}; -use libp2p::{Multiaddr, PeerId}; -use parity_db::{ColumnOptions, Db, Options}; -use parity_scale_codec::{Decode, Encode}; -use parking_lot::Mutex; -use std::borrow::{Borrow, Cow}; -use std::collections::BTreeMap; -use std::iter; -use std::num::NonZeroUsize; -use std::path::Path; -use std::sync::Arc; -use std::time::{Duration, Instant, SystemTime}; -use std::vec::IntoIter; -use tracing::{debug, error, trace, warn}; - -// Defines max provider records number. Each provider record is expected to be less than 1KB. -const MEMORY_STORE_PROVIDED_KEY_LIMIT: usize = 100000; // ~100 MB - -const PARITY_DB_ALL_PROVIDERS_COLUMN_NAME: u8 = 0; -const PARITY_DB_LOCAL_PROVIDER_COLUMN_NAME: u8 = 1; - -/// Stub provider storage implementation. -/// All operations have no effect or return empty collections/iterators. -pub struct VoidProviderStorage; - -impl ProviderStorage for VoidProviderStorage { - type ProvidedIter<'a> = iter::Empty>; - - fn add_provider(&self, _: ProviderRecord) -> store::Result<()> { - Ok(()) - } - - fn providers(&self, _: &Key) -> Vec { - Default::default() - } - - fn provided(&self) -> Self::ProvidedIter<'_> { - iter::empty() - } - - fn remove_provider(&self, _: &Key, _: &PeerId) {} -} - -/// Memory based provider records storage. -#[derive(Clone)] -pub struct MemoryProviderStorage { - inner: Arc>, -} - -impl MemoryProviderStorage { - /// Create new memory based provider records storage. - pub fn new(peer_id: PeerId) -> Self { - Self { - inner: Arc::new(Mutex::new(store::MemoryStore::with_config( - peer_id, - MemoryStoreConfig { - max_records: 0, - max_value_bytes: 0, - max_providers_per_key: K_VALUE.get(), - max_provided_keys: MEMORY_STORE_PROVIDED_KEY_LIMIT, - }, - ))), - } - } -} - -impl ProviderStorage for MemoryProviderStorage { - type ProvidedIter<'a> = iter::Map< - IntoIter, - fn(ProviderRecord) -> Cow<'a, ProviderRecord>, - > where Self:'a; - - fn add_provider(&self, record: ProviderRecord) -> store::Result<()> { - trace!("New provider record added: {:?}", record); - - self.inner.lock().add_provider(record) - } - - fn providers(&self, key: &Key) -> Vec { - self.inner.lock().providers(key) - } - - fn provided(&self) -> Self::ProvidedIter<'_> { - // We copy records here. The downstream usage of this method is a relatively rare periodic job. - let records = { - self.inner - .lock() - .provided() - .map(|item| item.into_owned()) - .collect::>() - }; - - records.into_iter().map(Cow::Owned) - } - - fn remove_provider(&self, key: &Key, provider: &PeerId) { - trace!(?key, ?provider, "Provider record removed."); - - self.inner.lock().remove_provider(key, provider) - } -} - -#[derive(Clone, Debug, Decode, Encode, Default)] -struct ParityDbProviderCollection { - // Provider PeerID -> ProviderRecord - map: BTreeMap, ParityDbProviderRecord>, -} - -impl From for Vec { - #[inline] - fn from(value: ParityDbProviderCollection) -> Self { - value.encode() - } -} - -impl TryFrom> for ParityDbProviderCollection { - type Error = parity_scale_codec::Error; - - #[inline] - fn try_from(data: Vec) -> Result { - ParityDbProviderCollection::decode(&mut data.as_slice()).map(Into::into) - } -} - -impl ParityDbProviderCollection { - fn to_vec(&self) -> Vec { - self.clone().into() - } - - fn add_provider(&mut self, rec: ParityDbProviderRecord) { - self.map.insert(rec.provider.clone(), rec); - } - - fn remove_provider(&mut self, provider: Vec) { - self.map.remove(&provider); - } - - fn providers(&self) -> impl Iterator + '_ { - self.map.values().cloned() - } - - fn len(&self) -> usize { - self.map.len() - } -} - -#[derive(Clone, Debug, Decode, Encode)] -struct ParityDbProviderRecord { - // Key of the record. - key: Vec, - // Provider peer ID. - provider: Vec, - // The expiration time as measured by a local, monotonic clock. - expires: Option, - // Provider addresses. - addresses: Vec>, -} - -impl From for Vec { - #[inline] - fn from(rec: ParityDbProviderRecord) -> Self { - rec.encode() - } -} - -impl TryFrom> for ParityDbProviderRecord { - type Error = parity_scale_codec::Error; - - #[inline] - fn try_from(data: Vec) -> Result { - ParityDbProviderRecord::decode(&mut data.as_slice()).map(Into::into) - } -} - -impl From for ParityDbProviderRecord { - #[inline] - fn from(rec: ProviderRecord) -> Self { - Self { - key: rec.key.to_vec(), - provider: rec.provider.to_bytes(), - addresses: rec.addresses.iter().map(|a| a.to_vec()).collect(), - expires: rec.expires.map(instant_to_micros), - } - } -} - -impl From for ProviderRecord { - // We don't expect an error here because ParityDbRecord contains valid bytes - // representations. - #[inline] - fn from(rec: ParityDbProviderRecord) -> Self { - Self { - key: rec.key.into(), - provider: rec - .provider - .try_into() - .expect("Peer ID should be valid in bytes representation."), - addresses: rec - .addresses - .into_iter() - // We don't expect an error here because ParityDbRecord contains a bytes - // representation of the valid PeerId. - .map(|addr| { - Multiaddr::try_from(addr) - .expect("Multiaddr should be valid in bytes representation.") - }) - .collect::>(), - expires: rec.expires.map(micros_to_instant).unwrap_or_default(), - } - } -} - -/// Defines provider record storage with DB persistence -#[derive(Clone)] -pub struct ParityDbProviderStorage { - /// Parity DB instance - db: Arc, - /// Maintains a heap to limit total item number. - heap: Arc>, - /// Local provider PeerID - local_peer_id: PeerId, -} - -impl ParityDbProviderStorage { - /// Create new Parity DB based provider records storage. - pub fn new( - path: &Path, - max_items_limit: NonZeroUsize, - local_peer_id: PeerId, - ) -> Result { - let mut options = Options::with_columns(path, 2); - options.columns = vec![ - ColumnOptions { - // all providers - btree_index: true, - ..Default::default() - }, - ColumnOptions { - // local providers - btree_index: true, - ..Default::default() - }, - ]; - - // We don't use stats - options.stats = false; - - let db = Db::open_or_create(&options)?; - - let mut heap = UniqueRecordBinaryHeap::new(local_peer_id, max_items_limit.get()); - - let known_providers = { - let rec_iter_result: Result< - ParityDbProviderRecordCollectionIterator, - parity_db::Error, - > = try { - let btree_iter = db.iter(PARITY_DB_ALL_PROVIDERS_COLUMN_NAME)?; - ParityDbProviderRecordCollectionIterator::new(btree_iter)? - }; - - match rec_iter_result { - Ok(rec_iter) => rec_iter, - Err(err) => { - error!(?err, "Can't create Parity DB record storage iterator."); - - ParityDbProviderRecordCollectionIterator::empty() - } - } - }; - - // Initial cache loading. - for rec in known_providers { - let _ = heap.insert(rec.key.clone()); - } - - if heap.size() > 0 { - debug!(size = heap.size(), ?path, "Record cache loaded."); - } else { - debug!(?path, "New record cache initialized."); - } - - Ok(Self { - db: Arc::new(db), - heap: Arc::new(Mutex::new(heap)), - local_peer_id, - }) - } - - /// Gets records number in the storage. - pub fn size(&self) -> usize { - self.heap.lock().size() - } - - fn add_provider_to_db(&self, key: &Key, rec: ParityDbProviderRecord) { - let mut providers = self.load_providers(key).unwrap_or_default(); - - providers.add_provider(rec); - - self.save_providers(key, providers); - } - - fn remove_provider_from_db(&self, key: &Key, provider: Vec) { - let mut providers = self.load_providers(key).unwrap_or_default(); - - providers.remove_provider(provider); - - self.save_providers(key, providers); - } - - fn remove_providers_from_db(&self, key: &Key) { - let tx = [(PARITY_DB_ALL_PROVIDERS_COLUMN_NAME, key, None)]; - - let result = self.db.commit(tx); - if let Err(err) = &result { - error!(?key, ?err, "Failed to delete providers from Parity DB."); - } - } - - fn add_local_provider_to_db(&self, key: &Key, rec: ParityDbProviderRecord) { - let key: &[u8] = key.borrow(); - - let tx = [(PARITY_DB_LOCAL_PROVIDER_COLUMN_NAME, key, Some(rec.into()))]; - - let result = self.db.commit(tx); - if let Err(err) = &result { - error!(?key, ?err, "Local provider DB adding error."); - } - } - - fn remove_local_provider_to_db(&self, key: &Key) { - let key: &[u8] = key.borrow(); - - let tx = [(PARITY_DB_LOCAL_PROVIDER_COLUMN_NAME, key, None)]; - - let result = self.db.commit(tx); - if let Err(err) = &result { - error!(?key, ?err, "Local provider DB removing error."); - } - } - - fn save_providers(&self, key: &Key, providers: ParityDbProviderCollection) -> bool { - let key: &[u8] = key.borrow(); - let data = if providers.len() > 0 { - Some(providers.to_vec()) - } else { - None - }; - - let tx = [(PARITY_DB_ALL_PROVIDERS_COLUMN_NAME, key, data)]; - - let result = self.db.commit(tx); - if let Err(err) = &result { - error!(?key, ?err, "DB saving error."); - } - - result.is_ok() - } - - fn load_providers(&self, key: &Key) -> Option { - let result = self - .db - .get(PARITY_DB_ALL_PROVIDERS_COLUMN_NAME, key.borrow()); - - match result { - Ok(Some(data)) => { - let db_rec_result: Result = data.try_into(); - - match db_rec_result { - Ok(db_rec) => { - trace!(?key, "Provider record loaded successfully from DB"); - - Some(db_rec) - } - Err(err) => { - debug!( - ?key, - ?err, - "Parity DB provider record deserialization error" - ); - - None - } - } - } - Ok(None) => { - trace!(?key, "No Parity DB record for given key"); - - None - } - Err(err) => { - debug!(?key, ?err, "Parity DB record storage error"); - - None - } - } - } -} - -impl ProviderStorage for ParityDbProviderStorage { - type ProvidedIter<'a> = ParityDbProviderRecordIterator<'a> where Self:'a; - - fn add_provider(&self, record: ProviderRecord) -> store::Result<()> { - let record_key = record.key.clone(); - let provider_peer_id = record.provider; - - trace!(?record_key, provider=%record.provider, "Saving a provider to DB"); - - let db_rec = ParityDbProviderRecord::from(record); - - if provider_peer_id == self.local_peer_id { - self.add_local_provider_to_db(&record_key, db_rec.clone()); - } - - self.add_provider_to_db(&record_key, db_rec); - - let evicted_key = { self.heap.lock().insert(record_key) }; - - if let Some(key) = evicted_key { - trace!(?key, "Record evicted from cache."); - - self.remove_local_provider_to_db(&key); - self.remove_providers_from_db(&key); - } - - Ok(()) - } - - fn remove_provider(&self, key: &Key, provider: &PeerId) { - debug!(?key, %provider, "Removing a provider from DB"); - - if *provider == self.local_peer_id { - self.remove_local_provider_to_db(key); - } - - self.remove_provider_from_db(key, provider.to_bytes()); - - self.heap.lock().remove(key); - } - - fn provided(&self) -> Self::ProvidedIter<'_> { - let rec_iter_result: Result = try { - let btree_iter = self.db.iter(PARITY_DB_LOCAL_PROVIDER_COLUMN_NAME)?; - ParityDbProviderRecordIterator::new(btree_iter)? - }; - - match rec_iter_result { - Ok(rec_iter) => rec_iter, - Err(err) => { - error!(?err, "Can't create Parity DB record storage iterator."); - - // TODO: The error handling can be changed: - // https://github.com/libp2p/rust-libp2p/issues/3035 - ParityDbProviderRecordIterator::empty() - } - } - } - - fn providers(&self, key: &Key) -> Vec { - self.load_providers(key) - .unwrap_or_default() - .providers() - .map(Into::into) - .collect() - } -} - -/// Parity DB BTree iterator wrapper. -pub struct ParityDbProviderRecordIterator<'a> { - iter: Option>, -} - -impl<'a> ParityDbProviderRecordIterator<'a> { - /// Defines empty iterator, a stub when new() fails. - pub fn empty() -> Self { - Self { iter: None } - } - /// Fallible iterator constructor. It requires inner DB BTreeIterator as a parameter. - pub fn new(mut iter: parity_db::BTreeIterator<'a>) -> parity_db::Result { - iter.seek_to_first()?; - - Ok(Self { iter: Some(iter) }) - } - - fn next_entry(&mut self) -> Option<(Vec, Vec)> { - if let Some(ref mut iter) = self.iter { - match iter.next() { - Ok(value) => value, - Err(err) => { - warn!(?err, "Parity DB provider record iterator error"); - - None - } - } - } else { - None - } - } -} - -impl<'a> Iterator for ParityDbProviderRecordIterator<'a> { - type Item = Cow<'a, ProviderRecord>; - - fn next(&mut self) -> Option { - self.next_entry().and_then(|(key, value)| { - let db_rec_result: Result = value.try_into(); - - match db_rec_result { - Ok(db_rec) => Some(Cow::Owned(db_rec.into())), - Err(err) => { - warn!( - ?key, - ?err, - "Parity DB provider record deserialization error" - ); - - None - } - } - }) - } -} - -impl ProviderStorage for Either -where - L: ProviderStorage, - R: ProviderStorage, -{ - type ProvidedIter<'a> = impl Iterator> where Self:'a; - - fn add_provider(&self, record: ProviderRecord) -> store::Result<()> { - match self { - Either::Left(inner) => inner.add_provider(record), - Either::Right(inner) => inner.add_provider(record), - } - } - - fn providers(&self, key: &Key) -> Vec { - match self { - Either::Left(inner) => inner.providers(key), - Either::Right(inner) => inner.providers(key), - } - } - - fn provided(&self) -> Self::ProvidedIter<'_> { - let iterator = match self { - Either::Left(inner) => Either::Left(inner.provided()), - Either::Right(inner) => Either::Right(inner.provided()), - }; - - EitherProviderStorageIterator::new(iterator) - } - - fn remove_provider(&self, key: &Key, peer_id: &PeerId) { - match self { - Either::Left(inner) => inner.remove_provider(key, peer_id), - Either::Right(inner) => inner.remove_provider(key, peer_id), - } - } -} - -struct EitherProviderStorageIterator<'a, L, R> -where - L: Iterator>, - R: Iterator>, -{ - either_provider_iterator: Either, -} - -impl<'a, L, R> EitherProviderStorageIterator<'a, L, R> -where - L: Iterator>, - R: Iterator>, -{ - fn new(either_provider_iterator: Either) -> Self { - Self { - either_provider_iterator, - } - } -} - -impl<'a, L, R> Iterator for EitherProviderStorageIterator<'a, L, R> -where - L: Iterator>, - R: Iterator>, -{ - type Item = Cow<'a, ProviderRecord>; - - fn next(&mut self) -> Option { - match self.either_provider_iterator { - Either::Left(ref mut inner) => inner.next(), - Either::Right(ref mut inner) => inner.next(), - } - } -} - -// Instant to microseconds conversion function. -pub(crate) fn instant_to_micros(instant: Instant) -> u64 { - let system_now = SystemTime::now(); - let instant_now = Instant::now(); - - let system_time = system_now - (instant_now - instant); - let duration = system_time - .duration_since(SystemTime::UNIX_EPOCH) - .expect("Cannot be earlier than the beginning of unix time; qed"); - - duration.as_micros() as u64 -} - -// Microseconds to Instant conversion function. -pub(crate) fn micros_to_instant(micros: u64) -> Option { - let system_time = SystemTime::UNIX_EPOCH.checked_add(Duration::from_micros(micros))?; - - let system_now = SystemTime::now(); - let instant_now = Instant::now(); - let duration = system_now.duration_since(system_time).ok()?; - - instant_now.checked_sub(duration) -} - -/// Parity DB BTree ProviderRecordCollection iterator wrapper. -pub struct ParityDbProviderRecordCollectionIterator<'a> { - iter: Option>, - current_collection: Option>, -} - -impl<'a> ParityDbProviderRecordCollectionIterator<'a> { - /// Defines empty iterator, a stub when new() fails. - pub fn empty() -> Self { - Self { - iter: None, - current_collection: None, - } - } - - /// Fallible iterator constructor. It requires inner DB BTreeIterator as a parameter. - pub fn new(mut iter: parity_db::BTreeIterator<'a>) -> parity_db::Result { - iter.seek_to_first()?; - - Ok(Self { - iter: Some(iter), - current_collection: None, - }) - } - - fn next_entry(&mut self) -> Option<(Vec, Vec)> { - if let Some(ref mut iter) = self.iter { - match iter.next() { - Ok(value) => value, - Err(err) => { - warn!(?err, "Parity DB provider iterator error"); - - None - } - } - } else { - None - } - } -} - -impl<'a> Iterator for ParityDbProviderRecordCollectionIterator<'a> { - type Item = Cow<'a, ProviderRecord>; - - fn next(&mut self) -> Option { - if self.current_collection.is_none() { - let loaded_collection = self.next_entry().and_then(|(key, value)| { - let db_rec_result: Result = value.try_into(); - - match db_rec_result { - Ok(collection) => Some(collection.providers().collect::>()), - Err(err) => { - warn!( - ?key, - ?err, - "Parity DB provider collection deserialization error" - ); - - None - } - } - }); - - self.current_collection = loaded_collection; - } - - let result = if let Some(ref mut collection) = self.current_collection { - collection.pop().map(Into::into).map(Cow::Owned) - } else { - None - }; - - // Remove empty collection from the local cache. - let is_empty_collection = self - .current_collection - .as_ref() - .map(|collection| collection.is_empty()) - .unwrap_or(true); - if is_empty_collection { - self.current_collection = None; - } - - result - } -} diff --git a/crates/subspace-networking/src/behavior/provider_storage/providers/tests.rs b/crates/subspace-networking/src/behavior/provider_storage/providers/tests.rs deleted file mode 100644 index b24ce49cc95..00000000000 --- a/crates/subspace-networking/src/behavior/provider_storage/providers/tests.rs +++ /dev/null @@ -1,74 +0,0 @@ -use super::MemoryProviderStorage; -use crate::ProviderStorage; -use libp2p::kad::record::Key; -use libp2p::kad::ProviderRecord; -use libp2p::PeerId; -use std::collections::HashSet; - -#[allow(clippy::mutable_key_type)] // we use hash set for sorting to compare collections -#[test] -fn memory_storage_provider() { - let local_peer_id = PeerId::random(); - let store = MemoryProviderStorage::new(local_peer_id); - - let key1: Key = b"key1".to_vec().into(); - let provider1 = PeerId::random(); - let rec1 = ProviderRecord { - provider: provider1, - key: key1, - expires: None, - addresses: Vec::new(), - }; - - let key2: Key = b"key2".to_vec().into(); - let provider2 = local_peer_id; - let rec2 = ProviderRecord { - provider: provider2, - key: key2.clone(), - expires: None, - addresses: Vec::new(), - }; - - let provider3 = PeerId::random(); - let rec3 = ProviderRecord { - provider: provider3, - key: key2.clone(), - expires: None, - addresses: Vec::new(), - }; - - // Check adding - store.add_provider(rec1).unwrap(); - store.add_provider(rec2.clone()).unwrap(); - store.add_provider(rec3.clone()).unwrap(); - - // Check local providers retrieval - let provided_collection: HashSet = - HashSet::from_iter(store.provided().map(|i| i.into_owned())); - - println!("{:?}", store.provided()); - - assert_eq!( - HashSet::from_iter(vec![rec2.clone()].into_iter()), - provided_collection - ); - - // Check single provider retrieval - let provided_collection: HashSet = - HashSet::from_iter(store.providers(&key2).into_iter()); - - assert_eq!( - HashSet::from_iter(vec![rec2.clone(), rec3].into_iter()), - provided_collection - ); - - // Remove provider - store.remove_provider(&key2, &provider3); - let provided_collection: HashSet = - HashSet::from_iter(store.providers(&key2).into_iter()); - - assert_eq!( - HashSet::from_iter(vec![rec2].into_iter()), - provided_collection - ); -} diff --git a/crates/subspace-networking/src/behavior/tests.rs b/crates/subspace-networking/src/behavior/tests.rs index 4a318772791..78c63ebbd9d 100644 --- a/crates/subspace-networking/src/behavior/tests.rs +++ b/crates/subspace-networking/src/behavior/tests.rs @@ -1,7 +1,8 @@ use super::persistent_parameters::remove_known_peer_addresses_internal; -use crate::behavior::provider_storage::{instant_to_micros, micros_to_instant}; -use crate::{BootstrappedNetworkingParameters, Config, GenericRequest, GenericRequestHandler}; +use crate::behavior::persistent_parameters::{append_p2p_suffix, remove_p2p_suffix}; +use crate::{Config, GenericRequest, GenericRequestHandler}; use futures::channel::oneshot; +use futures::future::pending; use libp2p::multiaddr::Protocol; use libp2p::{Multiaddr, PeerId}; use lru::LruCache; @@ -10,9 +11,11 @@ use parking_lot::Mutex; use std::future::Future; use std::num::NonZeroUsize; use std::pin::Pin; +use std::str::FromStr; use std::sync::Arc; use std::task::{Context, Poll}; -use std::time::{Duration, Instant, SystemTime}; +use std::time::Duration; +use tokio::time::sleep; #[tokio::test()] async fn test_address_timed_removal_from_known_peers_cache() { @@ -21,7 +24,8 @@ async fn test_address_timed_removal_from_known_peers_cache() { let addr1 = Multiaddr::empty().with(Protocol::Memory(0)); let addr2 = Multiaddr::empty().with(Protocol::Memory(1)); let addresses = vec![addr1.clone(), addr2.clone()]; - let expiration = chrono::Duration::nanoseconds(1); + let expiration = Duration::from_nanos(1); + let expiration_kademlia = Duration::from_nanos(1); let mut peers_cache = LruCache::new(NonZeroUsize::new(100).unwrap()); let mut addresses_cache = LruCache::new(NonZeroUsize::new(100).unwrap()); @@ -45,10 +49,17 @@ async fn test_address_timed_removal_from_known_peers_cache() { .expect("Address present") .is_none()); - remove_known_peer_addresses_internal(&mut peers_cache, peer_id, addresses.clone(), expiration); + let removed_addresses = remove_known_peer_addresses_internal( + &mut peers_cache, + peer_id, + addresses.clone(), + expiration, + expiration_kademlia, + ); // Check after the first run (set the first failure time) assert_eq!(peers_cache.len(), 1); + assert_eq!(removed_addresses.len(), 0); let addresses_from_cache = peers_cache.get(&peer_id).expect("PeerId present"); assert_eq!(addresses_from_cache.len(), 2); assert!(addresses_from_cache @@ -60,33 +71,77 @@ async fn test_address_timed_removal_from_known_peers_cache() { .expect("Address present") .is_some()); - remove_known_peer_addresses_internal(&mut peers_cache, peer_id, addresses, expiration); + let removed_addresses = remove_known_peer_addresses_internal( + &mut peers_cache, + peer_id, + addresses, + expiration, + expiration_kademlia, + ); // Check after the second run (clean cache) assert_eq!(peers_cache.len(), 0); + assert_eq!(removed_addresses.len(), 2); } -#[test] -fn instant_conversion() { - let inst1 = Instant::now(); - let ms = instant_to_micros(inst1); - let inst2 = micros_to_instant(ms).unwrap(); +#[tokio::test()] +async fn test_different_removal_timing_from_known_peers_cache() { + // Cache initialization + let peer_id = PeerId::random(); + let addr = Multiaddr::empty().with(Protocol::Memory(0)); - assert!(inst1.saturating_duration_since(inst2) < Duration::from_millis(1)); - assert!(inst2.saturating_duration_since(inst1) < Duration::from_millis(1)); -} + let expiration = Duration::from_secs(3); + let expiration_kademlia = Duration::from_secs(1); + + let mut peers_cache = LruCache::new(NonZeroUsize::new(100).unwrap()); + let mut addresses_cache = LruCache::new(NonZeroUsize::new(100).unwrap()); + + let addresses = vec![addr.clone()]; + addresses_cache.push(addr, None); + peers_cache.push(peer_id, addresses_cache); + + //Precondition-check + assert_eq!(peers_cache.len(), 1); + + let removed_addresses = remove_known_peer_addresses_internal( + &mut peers_cache, + peer_id, + addresses.clone(), + expiration, + expiration_kademlia, + ); + + // Check after the first run (set the first failure time) + assert_eq!(peers_cache.len(), 1); + assert_eq!(removed_addresses.len(), 0); + + sleep(expiration_kademlia).await; + + let removed_addresses = remove_known_peer_addresses_internal( + &mut peers_cache, + peer_id, + addresses.clone(), + expiration, + expiration_kademlia, + ); + + // Check after the second run (Kademlia event only) + assert_eq!(peers_cache.len(), 1); + assert_eq!(removed_addresses.len(), 1); -#[test] -fn instant_conversion_edge_cases() { - assert!(micros_to_instant(u64::MAX).is_none()); - assert!(micros_to_instant( - SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() - .as_micros() as u64 - * 2 - ) - .is_none()); + sleep(expiration).await; + + let removed_addresses = remove_known_peer_addresses_internal( + &mut peers_cache, + peer_id, + addresses, + expiration, + expiration_kademlia, + ); + + // Check after the third run (Kademlia event and clean cache) + assert_eq!(peers_cache.len(), 0); + assert_eq!(removed_addresses.len(), 1); } #[derive(Default)] @@ -159,26 +214,36 @@ async fn test_async_handler_works_with_pending_internal_future() { let node_1_addr = node_1_address_receiver.await.unwrap(); drop(on_new_listener_handler); + let bootstrap_addresses = vec![node_1_addr.with(Protocol::P2p(node_1.id()))]; let config_2 = Config { - networking_parameters_registry: BootstrappedNetworkingParameters::new(vec![ - node_1_addr.with(Protocol::P2p(node_1.id().into())) - ]) - .boxed(), listen_on: vec!["/ip4/0.0.0.0/tcp/0".parse().unwrap()], allow_non_global_addresses_in_dht: true, request_response_protocols: vec![GenericRequestHandler::::create( |_, _| async { None }, )], + bootstrap_addresses, ..Config::default() }; let (node_2, mut node_runner_2) = crate::create(config_2).unwrap(); + let bootstrap_fut = Box::pin({ + let node = node_2.clone(); + + async move { + let _ = node.bootstrap().await; + + pending::<()>().await; + } + }); + tokio::spawn(async move { - node_runner_2.run().await; + bootstrap_fut.await; }); - node_2.wait_for_connected_peers().await.unwrap(); + tokio::spawn(async move { + node_runner_2.run().await; + }); let resp = node_2 .send_generic_request(node_1.id(), ExampleRequest) @@ -187,3 +252,28 @@ async fn test_async_handler_works_with_pending_internal_future() { assert_eq!(resp.counter, 1); } + +#[tokio::test] +async fn test_address_p2p_prefix_removal() { + let short_addr: Multiaddr = "/ip4/127.0.0.1/tcp/50000".parse().unwrap(); + let long_addr: Multiaddr = + "/ip4/127.0.0.1/tcp/50000/p2p/12D3KooWGAjyJAZNNsHu8sV6MP6mXHzNXFQbadjVBFUr5deTiom2" + .parse() + .unwrap(); + + assert_eq!(remove_p2p_suffix(long_addr.clone()), short_addr); + assert_eq!(remove_p2p_suffix(short_addr.clone()), short_addr); +} + +#[tokio::test] +async fn test_address_p2p_prefix_addition() { + let peer_id = PeerId::from_str("12D3KooWGAjyJAZNNsHu8sV6MP6mXHzNXFQbadjVBFUr5deTiom2").unwrap(); + let short_addr: Multiaddr = "/ip4/127.0.0.1/tcp/50000".parse().unwrap(); + let long_addr: Multiaddr = + "/ip4/127.0.0.1/tcp/50000/p2p/12D3KooWGAjyJAZNNsHu8sV6MP6mXHzNXFQbadjVBFUr5deTiom2" + .parse() + .unwrap(); + + assert_eq!(append_p2p_suffix(peer_id, long_addr.clone()), long_addr); + assert_eq!(append_p2p_suffix(peer_id, short_addr.clone()), long_addr); +} diff --git a/crates/subspace-networking/src/bin/subspace-bootstrap-node/main.rs b/crates/subspace-networking/src/bin/subspace-bootstrap-node/main.rs index 3c7d4eb1097..1f163a0b876 100644 --- a/crates/subspace-networking/src/bin/subspace-bootstrap-node/main.rs +++ b/crates/subspace-networking/src/bin/subspace-bootstrap-node/main.rs @@ -2,22 +2,15 @@ #![feature(type_changing_struct_update)] -use anyhow::anyhow; -use bytesize::ByteSize; -use clap::{Parser, ValueHint}; -use either::Either; +use clap::Parser; use libp2p::identity::ed25519::Keypair; use libp2p::{identity, Multiaddr, PeerId}; use serde::{Deserialize, Serialize}; +use std::error::Error; use std::fmt::{Display, Formatter}; -use std::num::NonZeroUsize; -use std::path::PathBuf; use std::sync::Arc; use subspace_networking::libp2p::multiaddr::Protocol; -use subspace_networking::{ - peer_id, BootstrappedNetworkingParameters, Config, NetworkingParametersManager, - ParityDbProviderStorage, VoidProviderStorage, -}; +use subspace_networking::{peer_id, Config}; use tracing::{debug, info, Level}; use tracing_subscriber::fmt::Subscriber; use tracing_subscriber::util::SubscriberInitExt; @@ -53,17 +46,14 @@ enum Command { pending_out_peers: u32, /// Determines whether we allow keeping non-global (private, shared, loopback..) addresses in Kademlia DHT. #[arg(long, default_value_t = false)] - disable_private_ips: bool, - /// Defines path for the provider record storage DB (optional). - #[arg(long, value_hint = ValueHint::FilePath)] - db_path: Option, - /// Piece providers cache size in human readable format (e.g. 10GB, 2TiB) or just bytes (e.g. 4096). - #[arg(long, default_value = "100MiB")] - piece_providers_cache_size: ByteSize, + enable_private_ips: bool, /// Protocol version for libp2p stack, should be set as genesis hash of the blockchain for /// production use. #[arg(long)] protocol_version: String, + /// Known external addresses + #[arg(long, alias = "external-address")] + external_addresses: Vec, }, /// Generate a new keypair GenerateKeypair { @@ -108,7 +98,7 @@ fn init_logging() { } #[tokio::main] -async fn main() -> anyhow::Result<()> { +async fn main() -> Result<(), Box> { init_logging(); let command: Command = Command::parse(); @@ -123,64 +113,33 @@ async fn main() -> anyhow::Result<()> { out_peers, pending_in_peers, pending_out_peers, - disable_private_ips, - db_path, - piece_providers_cache_size, + enable_private_ips, protocol_version, + external_addresses, } => { debug!( "Libp2p protocol stack instantiated with version: {} ", protocol_version ); - const APPROX_PROVIDER_RECORD_SIZE: u64 = 1000; // ~ 1KB - let recs = piece_providers_cache_size.as_u64() / APPROX_PROVIDER_RECORD_SIZE; - let converted_cache_size = - NonZeroUsize::new(recs as usize).ok_or_else(|| anyhow!("Incorrect cache size."))?; - let decoded_keypair = Keypair::try_from_bytes(hex::decode(keypair)?.as_mut_slice())?; - let local_peer_id = peer_id_from_keypair(decoded_keypair.clone()); let keypair = identity::Keypair::from(decoded_keypair); - let provider_storage = if let Some(path) = &db_path { - let db_path = path.join("subspace_storage_providers_db"); - - Either::Left(ParityDbProviderStorage::new( - &db_path, - converted_cache_size, - local_peer_id, - )?) - } else { - Either::Right(VoidProviderStorage) - }; - - let networking_parameters_registry = { - db_path - .map(|path| { - let known_addresses_db = path.join("known_addresses_db"); - - NetworkingParametersManager::new( - &known_addresses_db, - bootstrap_nodes.clone(), - ) - .map(|manager| manager.boxed()) - }) - .unwrap_or(Ok( - BootstrappedNetworkingParameters::new(bootstrap_nodes).boxed() - )) - .map_err(|err| anyhow!(err))? - }; - let config = Config { - networking_parameters_registry, listen_on, - allow_non_global_addresses_in_dht: !disable_private_ips, + allow_non_global_addresses_in_dht: enable_private_ips, reserved_peers, max_established_incoming_connections: in_peers, max_established_outgoing_connections: out_peers, max_pending_incoming_connections: pending_in_peers, max_pending_outgoing_connections: pending_out_peers, - ..Config::new(protocol_version.to_string(), keypair, provider_storage) + // we don't maintain permanent connections with any peer + general_connected_peers_handler: None, + special_connected_peers_handler: None, + bootstrap_addresses: bootstrap_nodes, + external_addresses, + + ..Config::new(protocol_version.to_string(), keypair, (), None) }; let (node, mut node_runner) = subspace_networking::create(config).expect("Networking stack creation failed."); @@ -191,7 +150,7 @@ async fn main() -> anyhow::Result<()> { move |multiaddr| { info!( "Listening on {}", - multiaddr.clone().with(Protocol::P2p(node_id.into())) + multiaddr.clone().with(Protocol::P2p(node_id)) ); } })) diff --git a/crates/subspace-networking/src/connected_peers.rs b/crates/subspace-networking/src/connected_peers.rs new file mode 100644 index 00000000000..8f98c8e8ed7 --- /dev/null +++ b/crates/subspace-networking/src/connected_peers.rs @@ -0,0 +1,441 @@ +//! # 'Connected peers' protocol +//! +//! This module contains a `connected peers` protocol. The main +//! purpose of the protocol is to manage and maintain connections with peers in a +//! distributed network, with a focus on managing permanent connections. +//! +//! The heart of the module is the [`PeerDecision`] enum, which represents different states +//! of a peer's permanent connection decision. These states include: +//! +//! * `PendingConnection` - Indicates that a connection attempt to a peer is in progress. +//! * `PendingDecision` - A state when we're waiting for a decision for a certain period of time. +//! If no decision is made within this period, we consider the decision to be `NotInterested`. +//! * `PermanentConnection` - Indicates that the decision has been made to maintain a permanent +//! connection with the peer. No further decision-making is required for this state. +//! * `NotInterested` - Shows that the system has decided not to connect with the peer. +//! No further decision-making is required for this state. +//! +//! The module includes configuration, event handling, and connection management. It provides +//! capabilities for dialing peers, sending signals about changes in connection states. +//! +//! The protocol strives to maintain a certain target number of peers, handles delay between dialing +//! attempts, and manages a cache for candidates for permanent connections. +//! Multiple protocol instances could be instantiated. + +mod handler; + +use crate::utils::PeerAddress; +use futures::FutureExt; +use futures_timer::Delay; +use handler::Handler; +use libp2p::core::{Endpoint, Multiaddr}; +use libp2p::swarm::behaviour::{ConnectionEstablished, FromSwarm}; +use libp2p::swarm::dial_opts::DialOpts; +use libp2p::swarm::{ + ConnectionClosed, ConnectionDenied, ConnectionId, DialFailure, KeepAlive, NetworkBehaviour, + NotifyHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, ToSwarm, +}; +use libp2p::PeerId; +use std::collections::hash_map::Entry; +use std::collections::HashMap; +use std::marker::PhantomData; +use std::ops::Add; +use std::task::{Context, Poll, Waker}; +use std::time::{Duration, Instant}; +use tracing::{debug, trace}; + +/// Peer connections number and statuses. +#[derive(Debug, Clone, PartialEq, Eq)] +struct PeerState { + connection_state: ConnectionState, + connection_counter: usize, +} + +impl PeerState { + fn new(connection_state: ConnectionState) -> Self { + Self { + connection_state, + connection_counter: 0, + } + } +} + +/// Represents different states of a peer permanent connection. +#[derive(Debug, Clone, PartialEq, Eq)] +enum ConnectionState { + /// Indicates that a connection attempt to a peer is in progress. + Connecting { peer_address: Multiaddr }, + + /// We're waiting for a decision for some time. The decision time is limited by the + /// connection timeout. + Deciding, + + /// Indicates that the decision has been made to maintain a permanent + /// connection with the peer. No further decision-making is required for this state. + Permanent, + + /// Shows that the system has decided not to connect with the peer. + /// No further decision-making is required for this state. + NotInterested, +} + +/// Connected peers protocol configuration. +#[derive(Debug, Clone)] +pub struct Config { + /// Defines a target for logging. + pub log_target: &'static str, + /// Interval between new dialing attempts. + pub dialing_interval: Duration, + /// Number of connected peers that protocol will maintain. + pub target_connected_peers: u32, + /// We dial peers using this batch size. + pub dialing_peer_batch_size: u32, + /// Time interval reserved for a decision about connections. + /// It also affects keep-alive interval. + pub decision_timeout: Duration, +} + +const DEFAULT_CONNECTED_PEERS_LOG_TARGET: &str = "connected-peers"; +impl Default for Config { + fn default() -> Self { + Self { + log_target: DEFAULT_CONNECTED_PEERS_LOG_TARGET, + dialing_interval: Duration::from_secs(3), + target_connected_peers: 30, + dialing_peer_batch_size: 5, + decision_timeout: Duration::from_secs(10), + } + } +} + +/// Connected-peers protocol event. +#[derive(Debug, Clone)] +pub enum Event { + /// We need a new batch of peer addresses from the swarm. + NewDialingCandidatesRequested(PhantomData), +} + +/// Defines a possible change for the connection status. +#[derive(Debug, Clone, PartialEq, Eq)] +struct PeerConnectionDecisionUpdate { + peer_id: PeerId, + keep_alive: KeepAlive, +} + +/// `Behaviour` for `connected peers` protocol. +#[derive(Debug)] +pub struct Behaviour { + /// Protocol configuration. + config: Config, + + /// Represents current permanent connection decisions for known peers. + known_peers: HashMap, + + /// Pending 'signals' to connection handlers about recent changes. + peer_decision_changes: Vec, + + /// Delay between dialing attempts. + dialing_delay: Delay, + + /// Cache for candidates for permanent connections. + peer_cache: Vec, + + /// Future waker. + waker: Option, + + /// Instance type marker. + phantom_data: PhantomData, +} + +impl Behaviour { + /// Creates a new `Behaviour`. + pub fn new(config: Config) -> Self { + let dialing_delay = Delay::new(config.dialing_interval); + Self { + config, + known_peers: HashMap::new(), + peer_decision_changes: Vec::new(), + dialing_delay, + peer_cache: Vec::new(), + waker: None, + phantom_data: PhantomData, + } + } + + /// Create a connection handler for the protocol. + fn new_connection_handler(&mut self, peer_id: &PeerId) -> Handler { + let default_until = Instant::now().add(self.config.decision_timeout); + let default_keep_alive_until = KeepAlive::Until(default_until); + let keep_alive = if let Some(state) = self.known_peers.get_mut(peer_id) { + match state.connection_state { + ConnectionState::Connecting { .. } => { + // Connection attempt was successful. + state.connection_state = ConnectionState::Deciding; + + default_keep_alive_until + } + ConnectionState::Deciding => KeepAlive::Until(default_until), + ConnectionState::Permanent => KeepAlive::Yes, + ConnectionState::NotInterested => KeepAlive::No, + } + } else { + // Connection from other protocols. + self.known_peers + .insert(*peer_id, PeerState::new(ConnectionState::Deciding)); + + default_keep_alive_until + }; + + self.wake(); + Handler::new(keep_alive) + } + + /// Specifies the whether we should keep connections to the peer alive. The decision could + /// depend on another protocol (e.g.: PeerInfo protocol event handling). + /// In case when we had decision timeout it sets up proper keep connection alive anyway. + pub fn update_keep_alive_status(&mut self, peer_id: PeerId, keep_alive: bool) { + let (connection_state, keep_alive) = if keep_alive { + if self.permanently_connected_peers() < self.config.target_connected_peers { + trace!(%peer_id, %keep_alive, "Insufficient number of connected peers."); + + (ConnectionState::Permanent, KeepAlive::Yes) + } else { + trace!(%peer_id, %keep_alive, "Target number of connected peers reached."); + + (ConnectionState::NotInterested, KeepAlive::No) + } + } else { + (ConnectionState::NotInterested, KeepAlive::No) + }; + + self.known_peers + .entry(peer_id) + .and_modify(|state| { + state.connection_state = connection_state.clone(); + }) + .or_insert(PeerState::new(connection_state)); + self.peer_decision_changes + .push(PeerConnectionDecisionUpdate { + peer_id, + keep_alive, + }); + self.wake(); + } + + /// Calculates the current number of permanently connected peers. + fn permanently_connected_peers(&self) -> u32 { + self.known_peers + .iter() + .filter(|(_, state)| state.connection_state == ConnectionState::Permanent) + .count() as u32 + } + + /// Calculates the current number of peers with all connections except connections with + /// decision PeerDecision::NotInterested. + fn active_peers(&self) -> u32 { + self.known_peers + .iter() + .filter(|(_, state)| state.connection_state != ConnectionState::NotInterested) + .count() as u32 + } + + /// Adds peer addresses for internal cache. We use these addresses to dial peers for maintaining + /// target connection number. + pub fn add_peers_to_dial(&mut self, peers: &[PeerAddress]) { + self.peer_cache.extend_from_slice(peers); + self.wake(); + } + + fn wake(&self) { + if let Some(waker) = &self.waker { + waker.wake_by_ref() + } + } +} + +impl NetworkBehaviour for Behaviour { + type ConnectionHandler = Handler; + type ToSwarm = Event; + + fn handle_established_inbound_connection( + &mut self, + _: ConnectionId, + peer_id: PeerId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, ConnectionDenied> { + Ok(self.new_connection_handler(&peer_id)) + } + + fn handle_established_outbound_connection( + &mut self, + _: ConnectionId, + peer_id: PeerId, + _: &Multiaddr, + _: Endpoint, + ) -> Result, ConnectionDenied> { + Ok(self.new_connection_handler(&peer_id)) + } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(ConnectionEstablished { peer_id, .. }) => { + match self.known_peers.entry(peer_id) { + // Connection was established without dialing from this protocol + Entry::Vacant(entry) => { + entry.insert(PeerState { + connection_state: ConnectionState::Deciding, + connection_counter: 1, + }); + + trace!(%peer_id, "Pending peer decision..."); + self.wake(); + } + Entry::Occupied(mut entry) => { + entry.get_mut().connection_counter += 1; + } + } + } + FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + remaining_established, + .. + }) => { + // No established connections left, one of the reasons - the other side chose to not + // keep the connection alive. We remove information from the local state and + // possibly will try to reconnect later. + if remaining_established == 0 { + let old_peer_decision = self.known_peers.remove(&peer_id); + + if old_peer_decision.is_some() { + trace!(%peer_id, ?old_peer_decision, "Known peer disconnected."); + self.wake(); + } + } else { + self.known_peers + .entry(peer_id) + .and_modify(|state| state.connection_counter -= 1); + }; + } + FromSwarm::DialFailure(DialFailure { peer_id, .. }) => { + if let Some(peer_id) = peer_id { + let other_connections = self + .known_peers + .get(&peer_id) + .map(|state| state.connection_counter > 0) + .unwrap_or(false); + if !other_connections { + let old_peer_decision = self.known_peers.remove(&peer_id); + + if old_peer_decision.is_some() { + debug!(%peer_id, ?old_peer_decision, "Dialing error to known peer."); + } + } + + self.wake(); + } + } + FromSwarm::AddressChange(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddrCandidate(_) + | FromSwarm::ExternalAddrConfirmed(_) + | FromSwarm::ExternalAddrExpired(_) => {} + } + } + + fn on_connection_handler_event( + &mut self, + _: PeerId, + _: ConnectionId, + _: THandlerOutEvent, + ) { + } + + fn poll( + &mut self, + cx: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll>> { + // Notify handlers about received connection decision. + if let Some(change) = self.peer_decision_changes.pop() { + return Poll::Ready(ToSwarm::NotifyHandler { + peer_id: change.peer_id, + handler: NotifyHandler::Any, + event: change.keep_alive, + }); + } + + // Check decision statuses. + for (peer_id, state) in self.known_peers.iter_mut() { + trace!( + %peer_id, + ?state, + target=%self.config.log_target, + "Peer decisions for connected peers protocol." + ); + match state.connection_state.clone() { + ConnectionState::Connecting { + peer_address: address, + .. + } => { + state.connection_state = ConnectionState::Deciding; + + debug!(%peer_id, "Dialing a new peer."); + + let dial_opts = DialOpts::peer_id(*peer_id).addresses(vec![address]); + + return Poll::Ready(ToSwarm::Dial { + opts: dial_opts.build(), + }); + } + ConnectionState::Deciding => { + // The decision time is limited by the connection timeout. + } + ConnectionState::Permanent | ConnectionState::NotInterested => { + // Decision is made - no action necessary. + } + } + } + + // Schedule new peer dialing. + match self.dialing_delay.poll_unpin(cx) { + Poll::Pending => {} + Poll::Ready(()) => { + self.dialing_delay.reset(self.config.dialing_interval); + + // Request new peer addresses. + if self.peer_cache.is_empty() { + trace!("Requesting new peers for connected-peers protocol...."); + + return Poll::Ready(ToSwarm::GenerateEvent( + Event::NewDialingCandidatesRequested(PhantomData), + )); + } + + // New dial candidates. + if self.active_peers() < self.config.target_connected_peers { + let range = 0..(self.config.dialing_peer_batch_size as usize) + .min(self.peer_cache.len()); + + let peer_addresses = self.peer_cache.drain(range); + + for (peer_id, address) in peer_addresses { + self.known_peers.entry(peer_id).or_insert_with(|| { + PeerState::new(ConnectionState::Connecting { + peer_address: address, + }) + }); + } + } + } + } + + self.waker.replace(cx.waker().clone()); + Poll::Pending + } +} diff --git a/crates/subspace-networking/src/connected_peers/handler.rs b/crates/subspace-networking/src/connected_peers/handler.rs new file mode 100644 index 00000000000..9799d227887 --- /dev/null +++ b/crates/subspace-networking/src/connected_peers/handler.rs @@ -0,0 +1,83 @@ +use libp2p::core::upgrade::DeniedUpgrade; +use libp2p::swarm::handler::ConnectionEvent; +use libp2p::swarm::{ConnectionHandler, ConnectionHandlerEvent, KeepAlive, SubstreamProtocol}; +use std::error::Error; +use std::fmt; +use std::task::{Context, Poll}; +use tracing::trace; + +/// Connection handler for managing connections within our `connected peers` protocol. +/// +/// This `Handler` is part of our custom protocol designed to maintain a target number of persistent +/// connections. The decision about the connection is specified by handler events from the +/// protocol [`Behaviour`] +/// +/// ## Connection Handling +/// +/// The `Handler` manages the lifecycle of a connection to each peer. If it's connected to a +/// peer with positive keep-alive decision (we are interested in this connection), it maintains the +/// connection alive (`KeepAlive::Yes`). If not, it allows the connection to close (`KeepAlive::No`). +pub struct Handler { + /// Specifies whether we should keep the connection alive. + keep_alive: KeepAlive, +} + +impl Handler { + /// Builds a new [`Handler`]. + pub fn new(keep_alive: KeepAlive) -> Self { + Handler { keep_alive } + } +} + +#[derive(Debug)] +pub struct ConnectedPeersError; + +impl fmt::Display for ConnectedPeersError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Connected peers protocol error.") + } +} + +impl Error for ConnectedPeersError {} + +impl ConnectionHandler for Handler { + type FromBehaviour = KeepAlive; + type ToBehaviour = (); + type Error = ConnectedPeersError; + type InboundProtocol = DeniedUpgrade; + type OutboundProtocol = DeniedUpgrade; + type OutboundOpenInfo = (); + type InboundOpenInfo = (); + + fn listen_protocol(&self) -> SubstreamProtocol { + SubstreamProtocol::new(DeniedUpgrade, ()) + } + + fn on_behaviour_event(&mut self, keep_alive: KeepAlive) { + trace!(?keep_alive, "Behaviour event arrived."); + + self.keep_alive = keep_alive; + } + + fn connection_keep_alive(&self) -> KeepAlive { + self.keep_alive + } + + fn poll( + &mut self, + _: &mut Context<'_>, + ) -> Poll> { + Poll::Pending + } + + fn on_connection_event( + &mut self, + _: ConnectionEvent< + Self::InboundProtocol, + Self::OutboundProtocol, + Self::InboundOpenInfo, + Self::OutboundOpenInfo, + >, + ) { + } +} diff --git a/crates/subspace-networking/src/create.rs b/crates/subspace-networking/src/create.rs index 3634a29b8a5..985f2d77aba 100644 --- a/crates/subspace-networking/src/create.rs +++ b/crates/subspace-networking/src/create.rs @@ -2,18 +2,20 @@ pub(crate) mod temporary_bans; mod transport; use crate::behavior::persistent_parameters::{ - BootstrappedNetworkingParameters, NetworkingParametersRegistry, + NetworkingParametersRegistry, StubNetworkingParametersManager, }; -use crate::behavior::provider_storage::MemoryProviderStorage; -use crate::behavior::{provider_storage, Behavior, BehaviorConfig}; +use crate::behavior::{Behavior, BehaviorConfig}; +use crate::connected_peers::Config as ConnectedPeersConfig; use crate::create::temporary_bans::TemporaryBans; use crate::create::transport::build_transport; use crate::node::Node; use crate::node_runner::{NodeRunner, NodeRunnerConfig}; +use crate::peer_info::PeerInfoProvider; use crate::request_responses::RequestHandler; use crate::reserved_peers::Config as ReservedPeersConfig; use crate::shared::Shared; -use crate::utils::{convert_multiaddresses, ResizableSemaphore}; +use crate::utils::{strip_peer_id, ResizableSemaphore}; +use crate::{PeerInfo, PeerInfoConfig}; use backoff::{ExponentialBackoff, SystemClock}; use futures::channel::mpsc; use libp2p::connection_limits::ConnectionLimits; @@ -22,7 +24,6 @@ use libp2p::gossipsub::{ Message as GossipsubMessage, MessageId, ValidationMode, }; use libp2p::identify::Config as IdentifyConfig; -use libp2p::kad::record::Key; use libp2p::kad::store::RecordStore; use libp2p::kad::{ store, KademliaBucketInserts, KademliaConfig, KademliaStoreInserts, ProviderRecord, Record, @@ -31,7 +32,8 @@ use libp2p::metrics::Metrics; use libp2p::multiaddr::Protocol; use libp2p::swarm::SwarmBuilder; use libp2p::yamux::Config as YamuxConfig; -use libp2p::{identity, Multiaddr, PeerId, TransportError}; +use libp2p::{identity, Multiaddr, PeerId, StreamProtocol, TransportError}; +use libp2p_kad::{Mode, RecordKey}; use parking_lot::Mutex; use std::borrow::Cow; use std::iter::Empty; @@ -44,29 +46,30 @@ use subspace_core_primitives::{crypto, Piece}; use thiserror::Error; use tracing::{debug, error, info}; +/// Defines whether connection should be maintained permanently. +pub type ConnectedPeersHandler = Arc bool + Send + Sync + 'static>; + const DEFAULT_NETWORK_PROTOCOL_VERSION: &str = "dev"; -const KADEMLIA_PROTOCOL: &[u8] = b"/subspace/kad/0.1.0"; +const KADEMLIA_PROTOCOL: &str = "/subspace/kad/0.1.0"; const GOSSIPSUB_PROTOCOL_PREFIX: &str = "subspace/gossipsub"; -const RESERVED_PEERS_PROTOCOL_NAME: &[u8] = b"/subspace/reserved-peers/1.0.0"; +const RESERVED_PEERS_PROTOCOL_NAME: &str = "/subspace/reserved-peers/1.0.0"; +const PEER_INFO_PROTOCOL_NAME: &str = "/subspace/peer-info/1.0.0"; +const GENERAL_CONNECTED_PEERS_PROTOCOL_LOG_TARGET: &str = "general-connected-peers"; +const SPECIAL_CONNECTED_PEERS_PROTOCOL_LOG_TARGET: &str = "special-connected-peers"; // Defines max_negotiating_inbound_streams constant for the swarm. // It must be set for large plots. const SWARM_MAX_NEGOTIATING_INBOUND_STREAMS: usize = 100000; /// The default maximum established incoming connection number for the swarm. -const SWARM_MAX_ESTABLISHED_INCOMING_CONNECTIONS: u32 = 50; +const SWARM_MAX_ESTABLISHED_INCOMING_CONNECTIONS: u32 = 80; /// The default maximum established incoming connection number for the swarm. -const SWARM_MAX_ESTABLISHED_OUTGOING_CONNECTIONS: u32 = 50; +const SWARM_MAX_ESTABLISHED_OUTGOING_CONNECTIONS: u32 = 80; /// The default maximum pending incoming connection number for the swarm. -const SWARM_MAX_PENDING_INCOMING_CONNECTIONS: u32 = 50; +const SWARM_MAX_PENDING_INCOMING_CONNECTIONS: u32 = 80; /// The default maximum pending incoming connection number for the swarm. -const SWARM_MAX_PENDING_OUTGOING_CONNECTIONS: u32 = 50; +const SWARM_MAX_PENDING_OUTGOING_CONNECTIONS: u32 = 80; // The default maximum connection number to be maintained for the swarm. -const SWARM_TARGET_CONNECTION_NUMBER: u32 = 50; -// Defines an expiration interval for item providers in Kademlia network. -const KADEMLIA_PROVIDER_TTL_IN_SECS: Option = Some(Duration::from_secs(86400)); /* 1 day */ -// Defines a republication interval for item providers in Kademlia network. -const KADEMLIA_PROVIDER_REPUBLICATION_INTERVAL_IN_SECS: Option = - Some(Duration::from_secs(3600)); /* 1 hour */ +const SWARM_TARGET_CONNECTION_NUMBER: u32 = 30; // Defines a replication factor for Kademlia on get_record operation. // "Good citizen" supports the network health. const YAMUX_MAX_STREAMS: usize = 256; @@ -105,25 +108,39 @@ const TEMPORARY_BANS_DEFAULT_BACKOFF_RANDOMIZATION_FACTOR: f64 = 0.1; const TEMPORARY_BANS_DEFAULT_BACKOFF_MULTIPLIER: f64 = 1.5; const TEMPORARY_BANS_DEFAULT_MAX_INTERVAL: Duration = Duration::from_secs(30 * 60); +/// Trait to be implemented on providers of local records +pub trait LocalRecordProvider { + /// Gets a provider record for key that is stored locally + fn record(&self, key: &RecordKey) -> Option; +} + +impl LocalRecordProvider for () { + fn record(&self, _key: &RecordKey) -> Option { + None + } +} + /// Record store that can't be created, only -pub(crate) struct ProviderOnlyRecordStore { - provider_storage: ProviderStorage, +pub(crate) struct LocalOnlyRecordStore { + local_records_provider: LocalRecordProvider, } -impl ProviderOnlyRecordStore { - fn new(provider_storage: ProviderStorage) -> Self { - Self { provider_storage } +impl LocalOnlyRecordStore { + fn new(local_records_provider: LocalRecordProvider) -> Self { + Self { + local_records_provider, + } } } -impl RecordStore for ProviderOnlyRecordStore +impl RecordStore for LocalOnlyRecordStore where - ProviderStorage: provider_storage::ProviderStorage, + LocalRecordProvider: self::LocalRecordProvider, { type RecordsIter<'a> = Empty> where Self: 'a; - type ProvidedIter<'a> = ProviderStorage::ProvidedIter<'a> where Self: 'a; + type ProvidedIter<'a> = Empty> where Self: 'a; - fn get(&self, _key: &Key) -> Option> { + fn get(&self, _key: &RecordKey) -> Option> { // Not supported None } @@ -133,7 +150,7 @@ where Ok(()) } - fn remove(&mut self, _key: &Key) { + fn remove(&mut self, _key: &RecordKey) { // Not supported } @@ -142,46 +159,30 @@ where iter::empty() } - fn add_provider(&mut self, record: ProviderRecord) -> store::Result<()> { - self.provider_storage.add_provider(record) + fn add_provider(&mut self, _record: ProviderRecord) -> store::Result<()> { + // Not supported + Ok(()) } - fn providers(&self, key: &Key) -> Vec { - self.provider_storage.providers(key) + fn providers(&self, key: &RecordKey) -> Vec { + self.local_records_provider + .record(key) + .into_iter() + .collect() } fn provided(&self) -> Self::ProvidedIter<'_> { - self.provider_storage.provided() - } - - fn remove_provider(&mut self, key: &Key, provider: &PeerId) { - self.provider_storage.remove_provider(key, provider) + // We don't use Kademlia's periodic replication + iter::empty() } -} - -/// Defines relay configuration for the Node -#[derive(Clone, Debug)] -pub enum RelayMode { - /// No relay configured. - NoRelay, - /// The node enables the relay behaviour. - Server, - /// Client relay configuration (enables relay client behavior). - /// It uses a circuit relay server address as a parameter. - /// - /// Example: /memory/\/p2p/\/p2p-circuit - Client(Multiaddr), -} -impl RelayMode { - /// Defines whether the node has its relay behavior enabled. - pub fn is_relay_server(&self) -> bool { - matches!(self, RelayMode::Server) + fn remove_provider(&mut self, _key: &RecordKey, _provider: &PeerId) { + // Not supported } } /// [`Node`] configuration. -pub struct Config { +pub struct Config { /// Identity keypair of a node used for authenticated connections. pub keypair: identity::Keypair, /// List of [`Multiaddr`] on which to listen for incoming connections. @@ -197,16 +198,16 @@ pub struct Config { pub kademlia: KademliaConfig, /// The configuration for the Gossip behaviour. pub gossipsub: Option, - /// Externally provided implementation of the custom provider storage for Kademlia DHT, - pub provider_storage: ProviderStorage, + /// Externally provided implementation of the local records provider + pub local_records_provider: LocalRecordProvider, /// Yamux multiplexing configuration. pub yamux_config: YamuxConfig, /// Should non-global addresses be added to the DHT? pub allow_non_global_addresses_in_dht: bool, /// How frequently should random queries be done using Kademlia DHT to populate routing table. pub initial_random_query_interval: Duration, - /// A reference to the `NetworkingParametersRegistry` implementation. - pub networking_parameters_registry: Box, + /// A reference to the `NetworkingParametersRegistry` implementation (optional). + pub networking_parameters_registry: Option>, /// The configuration for the `RequestResponsesBehaviour` protocol. pub request_response_protocols: Vec>, /// Defines set of peers with a permanent connection (and reconnection if necessary). @@ -219,8 +220,6 @@ pub struct Config { pub max_pending_incoming_connections: u32, /// Pending outgoing swarm connection limit. pub max_pending_outgoing_connections: u32, - /// Defines target total (in and out) connection number that should be maintained. - pub target_connections: u32, /// How many temporarily banned unreachable peers to keep in memory. pub temporary_bans_cache_size: NonZeroUsize, /// Backoff policy for temporary banning of unreachable peers. @@ -229,51 +228,73 @@ pub struct Config { pub metrics: Option, /// Defines protocol version for the network peers. Affects network partition. pub protocol_version: String, + /// Specifies a source for peer information. None disables the protocol. + pub peer_info_provider: Option, + /// Defines whether we maintain a persistent connection for common peers. + /// None disables the protocol. + pub general_connected_peers_handler: Option, + /// Defines whether we maintain a persistent connection for special peers. + /// None disables the protocol. + pub special_connected_peers_handler: Option, + /// Defines target total (in and out) connection number that should be maintained for general peers. + pub general_target_connections: u32, + /// Defines target total (in and out) connection number that should be maintained for special peers. + pub special_target_connections: u32, + /// Addresses to bootstrap Kademlia network + pub bootstrap_addresses: Vec, + /// Kademlia mode. None means "automatic mode". + pub kademlia_mode: Option, + /// Known external addresses to the local peer. The addresses will be added on the swarm start + /// and enable peer to notify others about its reachable address. + pub external_addresses: Vec, } -impl fmt::Debug for Config { +impl fmt::Debug for Config { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Config").finish() } } -impl Default for Config { +impl Default for Config<()> { #[inline] fn default() -> Self { let ed25519_keypair = identity::ed25519::Keypair::generate(); let keypair = identity::Keypair::from(ed25519_keypair); - let peer_id = keypair.public().to_peer_id(); Self::new( DEFAULT_NETWORK_PROTOCOL_VERSION.to_string(), keypair, - MemoryProviderStorage::new(peer_id), + (), + Some(PeerInfoProvider::new_client()), ) } } -impl Config +impl Config where - ProviderStorage: provider_storage::ProviderStorage, + LocalRecordProvider: self::LocalRecordProvider, { /// Creates a new [`Config`]. pub fn new( protocol_version: String, keypair: identity::Keypair, - provider_storage: ProviderStorage, + local_records_provider: LocalRecordProvider, + peer_info_provider: Option, ) -> Self { let mut kademlia = KademliaConfig::default(); kademlia .set_query_timeout(KADEMLIA_QUERY_TIMEOUT) - .set_protocol_names(vec![Cow::Owned(KADEMLIA_PROTOCOL.into())]) + .set_protocol_names(vec![StreamProtocol::try_from_owned( + KADEMLIA_PROTOCOL.to_owned(), + ) + .expect("Manual protocol name creation.")]) + .disjoint_query_paths(true) .set_max_packet_size(2 * Piece::SIZE) .set_kbucket_inserts(KademliaBucketInserts::Manual) .set_record_filtering(KademliaStoreInserts::FilterBoth) - // Providers' settings - .set_provider_record_ttl(KADEMLIA_PROVIDER_TTL_IN_SECS) - // TODO: remove republication after removing all pieces` announcements - .set_provider_publication_interval(KADEMLIA_PROVIDER_REPUBLICATION_INTERVAL_IN_SECS) - // Our records don't expire. + // We don't use records and providers publication. + .set_provider_record_ttl(None) + .set_provider_publication_interval(None) .set_record_ttl(None) .set_replication_interval(None); @@ -316,10 +337,10 @@ where identify, kademlia, gossipsub, - provider_storage, + local_records_provider, allow_non_global_addresses_in_dht: false, initial_random_query_interval: Duration::from_secs(1), - networking_parameters_registry: BootstrappedNetworkingParameters::default().boxed(), + networking_parameters_registry: None, request_response_protocols: Vec::new(), yamux_config, reserved_peers: Vec::new(), @@ -327,11 +348,19 @@ where max_established_outgoing_connections: SWARM_MAX_ESTABLISHED_OUTGOING_CONNECTIONS, max_pending_incoming_connections: SWARM_MAX_PENDING_INCOMING_CONNECTIONS, max_pending_outgoing_connections: SWARM_MAX_PENDING_OUTGOING_CONNECTIONS, - target_connections: SWARM_TARGET_CONNECTION_NUMBER, temporary_bans_cache_size: TEMPORARY_BANS_CACHE_SIZE, temporary_ban_backoff, metrics: None, protocol_version, + peer_info_provider, + // we don't need to keep additional connections by default + general_connected_peers_handler: None, + special_connected_peers_handler: None, + general_target_connections: SWARM_TARGET_CONNECTION_NUMBER, + special_target_connections: SWARM_TARGET_CONNECTION_NUMBER, + bootstrap_addresses: Vec::new(), + kademlia_mode: Some(Mode::Server), + external_addresses: Vec::new(), } } } @@ -348,9 +377,6 @@ pub enum CreationError { /// Transport error when attempting to listen on multiaddr. #[error("Transport error when attempting to listen on multiaddr: {0}")] TransportError(#[from] TransportError), - /// ParityDb storage error - #[error("ParityDb storage error: {0}")] - ParityDbStorageError(#[from] parity_db::Error), } /// Converts public key from keypair to PeerId. @@ -360,11 +386,11 @@ pub fn peer_id(keypair: &identity::Keypair) -> PeerId { } /// Create a new network node and node runner instances. -pub fn create( - config: Config, -) -> Result<(Node, NodeRunner), CreationError> +pub fn create( + config: Config, +) -> Result<(Node, NodeRunner), CreationError> where - ProviderStorage: Send + Sync + provider_storage::ProviderStorage + 'static, + LocalRecordProvider: self::LocalRecordProvider + Send + Sync + 'static, { let Config { keypair, @@ -374,7 +400,7 @@ where identify, kademlia, gossipsub, - provider_storage, + local_records_provider, yamux_config, allow_non_global_addresses_in_dht, initial_random_query_interval, @@ -385,11 +411,18 @@ where max_established_outgoing_connections, max_pending_incoming_connections, max_pending_outgoing_connections, - target_connections, temporary_bans_cache_size, temporary_ban_backoff, metrics, protocol_version, + peer_info_provider, + general_connected_peers_handler: general_connection_decision_handler, + special_connected_peers_handler: special_connection_decision_handler, + general_target_connections, + special_target_connections, + bootstrap_addresses, + kademlia_mode, + external_addresses, } = config; let local_peer_id = peer_id(&keypair); @@ -426,13 +459,29 @@ where identify, kademlia, gossipsub, - record_store: ProviderOnlyRecordStore::new(provider_storage), + record_store: LocalOnlyRecordStore::new(local_records_provider), request_response_protocols, connection_limits, reserved_peers: ReservedPeersConfig { reserved_peers: reserved_peers.clone(), protocol_name: RESERVED_PEERS_PROTOCOL_NAME, }, + peer_info_config: PeerInfoConfig::new(PEER_INFO_PROTOCOL_NAME), + peer_info_provider, + general_connected_peers_config: general_connection_decision_handler.as_ref().map(|_| { + ConnectedPeersConfig { + log_target: GENERAL_CONNECTED_PEERS_PROTOCOL_LOG_TARGET, + target_connected_peers: general_target_connections, + ..ConnectedPeersConfig::default() + } + }), + special_connected_peers_config: special_connection_decision_handler.as_ref().map(|_| { + ConnectedPeersConfig { + log_target: SPECIAL_CONNECTED_PEERS_PROTOCOL_LOG_TARGET, + target_connected_peers: special_target_connections, + ..ConnectedPeersConfig::default() + } + }), }); let mut swarm = SwarmBuilder::with_tokio_executor(transport, behaviour, local_peer_id) @@ -456,6 +505,12 @@ where } } + // Setup external addresses + for addr in external_addresses.iter().cloned() { + info!("DSN external address added: {addr}"); + swarm.add_external_address(addr); + } + // Create final structs let (command_sender, command_receiver) = mpsc::channel(1); @@ -471,19 +526,25 @@ where let shared_weak = Arc::downgrade(&shared); let node = Node::new(shared); - let node_runner = NodeRunner::::new(NodeRunnerConfig:: { - allow_non_global_addresses_in_dht, - command_receiver, - swarm, - shared_weak, - next_random_query_interval: initial_random_query_interval, - networking_parameters_registry, - reserved_peers: convert_multiaddresses(reserved_peers).into_iter().collect(), - target_connections, - temporary_bans, - metrics, - protocol_version, - }); + let node_runner = + NodeRunner::::new(NodeRunnerConfig:: { + allow_non_global_addresses_in_dht, + command_receiver, + swarm, + shared_weak, + next_random_query_interval: initial_random_query_interval, + networking_parameters_registry: networking_parameters_registry + .unwrap_or(StubNetworkingParametersManager.boxed()), + reserved_peers: strip_peer_id(reserved_peers).into_iter().collect(), + temporary_bans, + metrics, + protocol_version, + general_connection_decision_handler, + special_connection_decision_handler, + bootstrap_addresses, + kademlia_mode, + external_addresses, + }); Ok((node, node_runner)) } diff --git a/crates/subspace-networking/src/create/tests.rs b/crates/subspace-networking/src/create/tests.rs deleted file mode 100644 index 0a81239cdf8..00000000000 --- a/crates/subspace-networking/src/create/tests.rs +++ /dev/null @@ -1,122 +0,0 @@ -use futures::future::{select, Either}; -use std::num::NonZeroUsize; -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Arc; -use std::time::Duration; -use tokio::sync::Semaphore; -use tokio::time::sleep; - -#[tokio::test] -async fn maintain_semaphore_permits_capacity() { - let base_tasks = 2; - let boost_per_peer = 1; - let boost_peers_threshold = NonZeroUsize::new(1).unwrap(); - let interval = Duration::from_micros(1); - let connected_peers_count = Arc::new(AtomicUsize::new(0)); - let tasks_semaphore = Arc::new(Semaphore::new(base_tasks)); - - tokio::spawn({ - let tasks_semaphore = Arc::clone(&tasks_semaphore); - let connected_peers_count_weak = Arc::downgrade(&connected_peers_count); - - async move { - super::maintain_semaphore_permits_capacity( - &tasks_semaphore, - interval, - connected_peers_count_weak, - boost_per_peer, - boost_peers_threshold, - ) - .await; - } - }); - - let timeout = Duration::from_millis(100); - - // Let above function time to run at least one loop - sleep(timeout).await; - - let permit_1_result = select( - Box::pin(tasks_semaphore.acquire()), - Box::pin(sleep(timeout)), - ) - .await; - if !matches!(permit_1_result, Either::Left(_)) { - panic!("Must be able to acquire the permit"); - } - - let permit_2_result = select( - Box::pin(tasks_semaphore.acquire()), - Box::pin(sleep(timeout)), - ) - .await; - if !matches!(permit_2_result, Either::Left(_)) { - panic!("Must be able to acquire the second permit"); - } - - { - let permit_3_result = select( - Box::pin(tasks_semaphore.acquire()), - Box::pin(sleep(timeout)), - ) - .await; - if !matches!(permit_3_result, Either::Right(_)) { - panic!("Must not be able to acquire the third permit due to capacity"); - } - } - - // Increase capacity - connected_peers_count.fetch_add(1, Ordering::SeqCst); - - { - let permit_3_result = select( - Box::pin(tasks_semaphore.acquire()), - Box::pin(sleep(timeout)), - ) - .await; - if !matches!(permit_3_result, Either::Right(_)) { - panic!("Must not be able to acquire the third permit due to capacity"); - } - } - - // Increase capacity more - connected_peers_count.fetch_add(1, Ordering::SeqCst); - - let permit_3_result = select( - Box::pin(tasks_semaphore.acquire()), - Box::pin(sleep(timeout)), - ) - .await; - if !matches!(permit_3_result, Either::Left(_)) { - panic!("Must be able to acquire the third permit due to increased capacity"); - } - - { - let permit_4_result = select( - Box::pin(tasks_semaphore.acquire()), - Box::pin(sleep(timeout)), - ) - .await; - if !matches!(permit_4_result, Either::Right(_)) { - panic!("Must not be able to acquire the fourth permit due to capacity"); - } - } - - // Decrease capacity capacity - connected_peers_count.fetch_sub(1, Ordering::SeqCst); - - drop(permit_3_result); - - sleep(timeout).await; - - { - let permit_3_result = select( - Box::pin(tasks_semaphore.acquire()), - Box::pin(sleep(timeout)), - ) - .await; - if !matches!(permit_3_result, Either::Right(_)) { - panic!("Must not be able to acquire the third permit again due to capacity anymore"); - } - } -} diff --git a/crates/subspace-networking/src/create/transport.rs b/crates/subspace-networking/src/create/transport.rs index dbfefcb84ae..69a4444cab1 100644 --- a/crates/subspace-networking/src/create/transport.rs +++ b/crates/subspace-networking/src/create/transport.rs @@ -6,13 +6,13 @@ use libp2p::core::muxing::StreamMuxerBox; use libp2p::core::transport::{Boxed, ListenerId, TransportError, TransportEvent}; use libp2p::core::Transport; use libp2p::dns::TokioDnsConfig; -use libp2p::quic::tokio::Transport as QuicTransport; -use libp2p::quic::Config as QuicConfig; use libp2p::tcp::tokio::Transport as TokioTcpTransport; use libp2p::tcp::Config as GenTcpConfig; use libp2p::websocket::WsConfig; use libp2p::yamux::Config as YamuxConfig; use libp2p::{core, identity, noise, PeerId}; +use libp2p_quic::tokio::Transport as QuicTransport; +use libp2p_quic::Config as QuicConfig; use parking_lot::Mutex; use std::io; use std::pin::Pin; @@ -106,8 +106,12 @@ where type ListenerUpgrade = T::ListenerUpgrade; type Dial = T::Dial; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { - self.base_transport.listen_on(addr) + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { + self.base_transport.listen_on(id, addr) } fn remove_listener(&mut self, id: ListenerId) -> bool { @@ -138,13 +142,11 @@ where { let temporary_bans = self.temporary_bans.lock(); for protocol in addr_iter { - if let Protocol::P2p(multihash) = protocol { - if let Ok(peer_id) = PeerId::try_from(multihash) { - if temporary_bans.is_banned(&peer_id) { - let error = - io::Error::new(io::ErrorKind::Other, "Peer is temporarily banned"); - return Err(TransportError::Other(error.into())); - } + if let Protocol::P2p(peer_id) = protocol { + if temporary_bans.is_banned(&peer_id) { + let error = + io::Error::new(io::ErrorKind::Other, "Peer is temporarily banned"); + return Err(TransportError::Other(error.into())); } } } diff --git a/crates/subspace-networking/src/lib.rs b/crates/subspace-networking/src/lib.rs index 9f47d48b001..aff8b5fe042 100644 --- a/crates/subspace-networking/src/lib.rs +++ b/crates/subspace-networking/src/lib.rs @@ -19,9 +19,11 @@ #![warn(missing_docs)] mod behavior; +mod connected_peers; mod create; mod node; mod node_runner; +mod peer_info; mod request_handlers; mod request_responses; mod reserved_peers; @@ -29,25 +31,22 @@ mod shared; pub mod utils; pub use crate::behavior::persistent_parameters::{ - BootstrappedNetworkingParameters, NetworkParametersPersistenceError, - NetworkingParametersManager, ParityDbError, + NetworkParametersPersistenceError, NetworkingParametersManager, }; pub use crate::node::{ GetClosestPeersError, Node, SendRequestError, SubscribeError, TopicSubscription, }; pub use crate::node_runner::{NodeRunner, KADEMLIA_PROVIDER_TTL_IN_SECS}; -pub use behavior::provider_storage::{ - MemoryProviderStorage, ParityDbProviderStorage, ProviderStorage, VoidProviderStorage, +pub use crate::peer_info::{ + Config as PeerInfoConfig, CuckooFilterDTO, CuckooFilterProvider, Notification, + NotificationHandler, PeerInfo, PeerInfoProvider, }; -pub use create::{create, peer_id, Config, CreationError, RelayMode}; +pub use create::{create, peer_id, Config, CreationError, LocalRecordProvider}; pub use libp2p; pub use request_handlers::generic_request_handler::{GenericRequest, GenericRequestHandler}; pub use request_handlers::object_mappings::{ ObjectMappingsRequest, ObjectMappingsRequestHandler, ObjectMappingsResponse, }; -pub use request_handlers::peer_info::{ - PeerInfo, PeerInfoRequest, PeerInfoRequestHandler, PeerInfoResponse, PeerSyncStatus, -}; pub use request_handlers::piece_announcement::{ PieceAnnouncementRequest, PieceAnnouncementRequestHandler, PieceAnnouncementResponse, }; @@ -60,5 +59,7 @@ pub use request_handlers::pieces_by_range::{ pub use request_handlers::segment_header::{ SegmentHeaderBySegmentIndexesRequestHandler, SegmentHeaderRequest, SegmentHeaderResponse, }; +pub use shared::NewPeerInfo; +pub use utils::multihash::Multihash; pub use utils::prometheus::start_prometheus_metrics_server; -pub use utils::unique_record_binary_heap::UniqueRecordBinaryHeap; +pub use utils::unique_record_binary_heap::{KeyWrapper, UniqueRecordBinaryHeap}; diff --git a/crates/subspace-networking/src/node.rs b/crates/subspace-networking/src/node.rs index 31a3c297efa..b2908943077 100644 --- a/crates/subspace-networking/src/node.rs +++ b/crates/subspace-networking/src/node.rs @@ -1,13 +1,13 @@ use crate::request_handlers::generic_request_handler::GenericRequest; -use crate::request_responses; -use crate::shared::{Command, CreatedSubscription, HandlerFn, Shared}; -use crate::utils::ResizableSemaphorePermit; +use crate::shared::{Command, CreatedSubscription, Shared}; +use crate::utils::multihash::Multihash; +use crate::utils::{HandlerFn, ResizableSemaphorePermit}; +use crate::{request_responses, NewPeerInfo}; use bytes::Bytes; use event_listener_primitives::HandlerId; use futures::channel::mpsc::SendError; use futures::channel::{mpsc, oneshot}; -use futures::{SinkExt, Stream}; -use libp2p::core::multihash::Multihash; +use futures::{SinkExt, Stream, StreamExt}; use libp2p::gossipsub::{Sha256Topic, SubscriptionError}; use libp2p::kad::record::Key; use libp2p::kad::PeerRecord; @@ -16,10 +16,8 @@ use parity_scale_codec::Decode; use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; -use std::time::Duration; use thiserror::Error; -use tokio::time::sleep; -use tracing::{error, trace}; +use tracing::{debug, error, trace}; /// Topic subscription, will unsubscribe when last instance is dropped for a particular topic. #[derive(Debug)] @@ -120,13 +118,6 @@ impl From for GetClosestPeersError { } } -#[derive(Debug, Error)] -pub enum CheckConnectedPeersError { - /// Node runner was dropped, impossible to check connected peers. - #[error("Node runner was dropped, impossible to check connected peers")] - NodeRunnerDropped, -} - /// Defines errors for `subscribe` operation. #[derive(Debug, Error)] pub enum SubscribeError { @@ -252,6 +243,46 @@ impl From for SendRequestError { } } +#[derive(Debug, Error)] +pub enum ConnectedPeersError { + /// Failed to send command to the node runner + #[error("Failed to send command to the node runner: {0}")] + SendCommand(#[from] SendError), + /// Node runner was dropped + #[error("Node runner was dropped")] + NodeRunnerDropped, + /// Failed to get connected peers. + #[error("Failed to get connected peers.")] + ConnectedPeers, +} + +impl From for ConnectedPeersError { + #[inline] + fn from(oneshot::Canceled: oneshot::Canceled) -> Self { + Self::NodeRunnerDropped + } +} + +#[derive(Debug, Error)] +pub enum BootstrapError { + /// Failed to send command to the node runner + #[error("Failed to send command to the node runner: {0}")] + SendCommand(#[from] SendError), + /// Node runner was dropped + #[error("Node runner was dropped")] + NodeRunnerDropped, + /// Failed to bootstrap a peer. + #[error("Failed to bootstrap a peer.")] + Bootstrap, +} + +impl From for BootstrapError { + #[inline] + fn from(oneshot::Canceled: oneshot::Canceled) -> Self { + Self::NodeRunnerDropped + } +} + /// Implementation of a network node on Subspace Network. #[derive(Debug, Clone)] #[must_use = "Node doesn't do anything if dropped"] @@ -410,35 +441,6 @@ impl Node { Ok(result_receiver) } - // TODO: add timeout - /// Waits for peers connection to the swarm and for Kademlia address registration. - pub async fn wait_for_connected_peers(&self) -> Result<(), CheckConnectedPeersError> { - loop { - trace!("Starting 'CheckConnectedPeers' request."); - - let (result_sender, result_receiver) = oneshot::channel(); - - self.shared - .command_sender - .clone() - .send(Command::CheckConnectedPeers { result_sender }) - .await - .map_err(|_| CheckConnectedPeersError::NodeRunnerDropped)?; - - let connected_peers_present = result_receiver - .await - .map_err(|_| CheckConnectedPeersError::NodeRunnerDropped)?; - - trace!("'CheckConnectedPeers' request returned {connected_peers_present}"); - - if connected_peers_present { - return Ok(()); - } - - sleep(Duration::from_millis(50)).await; - } - } - /// Start local announcing item by its key. Saves key to the local storage. /// It doesn't affect Kademlia operations. pub async fn start_local_announcing( @@ -539,4 +541,72 @@ impl Node { pub fn on_new_listener(&self, callback: HandlerFn) -> HandlerId { self.shared.handlers.new_listener.add(callback) } + + /// Callback is called when number of established peer connections changes. + pub fn on_num_established_peer_connections_change( + &self, + callback: HandlerFn, + ) -> HandlerId { + self.shared + .handlers + .num_established_peer_connections_change + .add(callback) + } + + /// Returns a collection of currently connected peers. + pub async fn connected_peers(&self) -> Result, ConnectedPeersError> { + let (result_sender, result_receiver) = oneshot::channel(); + + trace!("Starting 'connected_peers' request."); + + self.shared + .command_sender + .clone() + .send(Command::ConnectedPeers { result_sender }) + .await?; + + result_receiver + .await + .map_err(|_| ConnectedPeersError::ConnectedPeers) + } + + /// Bootstraps Kademlia network + pub async fn bootstrap(&self) -> Result<(), BootstrapError> { + let (result_sender, mut result_receiver) = mpsc::unbounded(); + + debug!("Starting 'bootstrap' request."); + + self.shared + .command_sender + .clone() + .send(Command::Bootstrap { result_sender }) + .await?; + + for step in 0.. { + let result = result_receiver.next().await; + + if result.is_some() { + debug!(%step, "Kademlia bootstrapping..."); + } else { + break; + } + } + + Ok(()) + } + + /// Callback is called when we receive new [`crate::peer_info::PeerInfo`] + pub fn on_peer_info(&self, callback: HandlerFn) -> HandlerId { + self.shared.handlers.new_peer_info.add(callback) + } + + /// Callback is called when a peer is disconnected. + pub fn on_disconnected_peer(&self, callback: HandlerFn) -> HandlerId { + self.shared.handlers.disconnected_peer.add(callback) + } + + /// Callback is called when a peer is connected. + pub fn on_connected_peer(&self, callback: HandlerFn) -> HandlerId { + self.shared.handlers.connected_peer.add(callback) + } } diff --git a/crates/subspace-networking/src/node_runner.rs b/crates/subspace-networking/src/node_runner.rs index 862658e9940..bcc9ee9eb04 100644 --- a/crates/subspace-networking/src/node_runner.rs +++ b/crates/subspace-networking/src/node_runner.rs @@ -1,14 +1,26 @@ -use crate::behavior::persistent_parameters::NetworkingParametersRegistry; -use crate::behavior::{provider_storage, Behavior, Event}; +use crate::behavior::persistent_parameters::{ + append_p2p_suffix, remove_p2p_suffix, NetworkingParametersRegistry, PeerAddressRemovedEvent, + PEERS_ADDRESSES_BATCH_SIZE, +}; +use crate::behavior::{ + Behavior, Event, GeneralConnectedPeersInstance, SpecialConnectedPeersInstance, +}; +use crate::connected_peers::Event as ConnectedPeersEvent; +use crate::create; use crate::create::temporary_bans::TemporaryBans; use crate::create::{ - ProviderOnlyRecordStore, KADEMLIA_CONCURRENT_TASKS_BOOST_PER_PEER, + ConnectedPeersHandler, LocalOnlyRecordStore, KADEMLIA_CONCURRENT_TASKS_BOOST_PER_PEER, REGULAR_CONCURRENT_TASKS_BOOST_PER_PEER, }; +use crate::peer_info::{Event as PeerInfoEvent, PeerInfoSuccess}; use crate::request_responses::{Event as RequestResponseEvent, IfDisconnected}; -use crate::shared::{Command, CreatedSubscription, Shared}; -use crate::utils::{is_global_address_or_dns, ResizableSemaphorePermit}; +use crate::shared::{Command, CreatedSubscription, NewPeerInfo, Shared}; +use crate::utils::{ + is_global_address_or_dns, strip_peer_id, PeerAddress, ResizableSemaphorePermit, +}; +use async_mutex::Mutex as AsyncMutex; use bytes::Bytes; +use event_listener_primitives::HandlerId; use futures::channel::mpsc; use futures::future::Fuse; use futures::{FutureExt, StreamExt}; @@ -17,18 +29,20 @@ use libp2p::gossipsub::{Event as GossipsubEvent, TopicHash}; use libp2p::identify::Event as IdentifyEvent; use libp2p::kad::store::RecordStore; use libp2p::kad::{ - GetClosestPeersError, GetClosestPeersOk, GetProvidersError, GetProvidersOk, GetRecordError, - GetRecordOk, InboundRequest, Kademlia, KademliaEvent, PeerRecord, ProgressStep, ProviderRecord, - PutRecordOk, QueryId, QueryResult, Quorum, Record, + BootstrapOk, GetClosestPeersError, GetClosestPeersOk, GetProvidersError, GetProvidersOk, + GetRecordError, GetRecordOk, InboundRequest, Kademlia, KademliaEvent, Mode, PeerRecord, + ProgressStep, ProviderRecord, PutRecordOk, QueryId, QueryResult, Quorum, Record, }; use libp2p::metrics::{Metrics, Recorder}; -use libp2p::swarm::dial_opts::DialOpts; +use libp2p::multiaddr::Protocol; use libp2p::swarm::{DialError, SwarmEvent}; use libp2p::{futures, Multiaddr, PeerId, Swarm, TransportError}; use nohash_hasher::IntMap; use parking_lot::Mutex; +use rand::rngs::StdRng; +use rand::{Rng, SeedableRng}; use std::collections::hash_map::Entry; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::fmt::Debug; use std::num::NonZeroUsize; use std::pin::Pin; @@ -38,6 +52,9 @@ use std::time::{Duration, Instant}; use tokio::time::Sleep; use tracing::{debug, error, trace, warn}; +// Defines a batch size for peer addresses from Kademlia buckets. +const KADEMLIA_PEERS_ADDRESSES_BATCH_SIZE: usize = 20; + /// How many peers should node be connected to before boosting turns on. /// /// 1 means boosting starts with second peer. @@ -68,18 +85,29 @@ enum QueryResultSender { // Just holding onto permit while data structure is not dropped _permit: ResizableSemaphorePermit, }, + Bootstrap { + sender: mpsc::UnboundedSender<()>, + }, +} + +#[derive(Debug, Default)] +enum BootstrapCommandState { + #[default] + NotStarted, + InProgress(mpsc::UnboundedReceiver<()>), + Finished, } /// Runner for the Node. #[must_use = "Node does not function properly unless its runner is driven forward"] -pub struct NodeRunner +pub struct NodeRunner where - ProviderStorage: provider_storage::ProviderStorage + Send + Sync + 'static, + LocalRecordProvider: create::LocalRecordProvider + Send + Sync + 'static, { /// Should non-global addresses be added to the DHT? allow_non_global_addresses_in_dht: bool, command_receiver: mpsc::Receiver, - swarm: Swarm>>, + swarm: Swarm>>, shared_weak: Weak, /// How frequently should random queries be done using Kademlia DHT to populate routing table. next_random_query_interval: Duration, @@ -91,14 +119,12 @@ where /// present for the same physical subscription). topic_subscription_senders: HashMap>>, random_query_timeout: Pin>>, - /// Defines a timeout between swarm attempts to dial known addresses - peer_dialing_timeout: Pin>>, + /// Defines an interval between periodical tasks. + periodical_tasks_interval: Pin>>, /// Manages the networking parameters like known peers and addresses networking_parameters_registry: Box, /// Defines set of peers with a permanent connection (and reconnection if necessary). reserved_peers: HashMap, - /// Defines target total (in and out) connection number that should be maintained. - target_connections: u32, /// Temporarily banned peers. temporary_bans: Arc>, /// Prometheus metrics. @@ -107,29 +133,53 @@ where established_connections: HashMap<(PeerId, ConnectedPoint), usize>, /// Defines protocol version for the network peers. Affects network partition. protocol_version: String, + /// Defines whether we maintain a persistent connection for common peers. + general_connection_decision_handler: Option, + /// Defines whether we maintain a persistent connection for special peers. + special_connection_decision_handler: Option, + /// Randomness generator used for choosing Kademlia addresses. + rng: StdRng, + /// Addresses to bootstrap Kademlia network + bootstrap_addresses: Vec, + /// Ensures a single bootstrap on run() invocation. + bootstrap_command_state: Arc>, + /// Kademlia mode. None means "automatic mode". + kademlia_mode: Option, + /// Known external addresses to the local peer. The addresses are added on the swarm start + /// and enable peer to notify others about its reachable address. + external_addresses: Vec, + /// Receives an event on peer address removal from the persistent storage. + removed_addresses_rx: mpsc::UnboundedReceiver, + /// Optional storage for the [`HandlerId`] of the address removal task. + /// We keep to stop the task along with the rest of the networking. + _address_removal_task_handler_id: Option, } // Helper struct for NodeRunner configuration (clippy requirement). -pub(crate) struct NodeRunnerConfig +pub(crate) struct NodeRunnerConfig where - ProviderStorage: provider_storage::ProviderStorage + Send + Sync + 'static, + LocalRecordProvider: create::LocalRecordProvider + Send + Sync + 'static, { pub(crate) allow_non_global_addresses_in_dht: bool, pub(crate) command_receiver: mpsc::Receiver, - pub(crate) swarm: Swarm>>, + pub(crate) swarm: Swarm>>, pub(crate) shared_weak: Weak, pub(crate) next_random_query_interval: Duration, pub(crate) networking_parameters_registry: Box, pub(crate) reserved_peers: HashMap, - pub(crate) target_connections: u32, pub(crate) temporary_bans: Arc>, pub(crate) metrics: Option, pub(crate) protocol_version: String, + pub(crate) general_connection_decision_handler: Option, + pub(crate) special_connection_decision_handler: Option, + pub(crate) bootstrap_addresses: Vec, + pub(crate) kademlia_mode: Option, + pub(crate) external_addresses: Vec, } -impl NodeRunner +impl NodeRunner where - ProviderStorage: provider_storage::ProviderStorage + Send + Sync + 'static, + LocalRecordProvider: create::LocalRecordProvider + Send + Sync + 'static, { pub(crate) fn new( NodeRunnerConfig { @@ -138,14 +188,31 @@ where swarm, shared_weak, next_random_query_interval, - networking_parameters_registry, + mut networking_parameters_registry, reserved_peers, - target_connections, temporary_bans, metrics, protocol_version, - }: NodeRunnerConfig, + general_connection_decision_handler, + special_connection_decision_handler, + bootstrap_addresses, + kademlia_mode, + external_addresses, + }: NodeRunnerConfig, ) -> Self { + // Setup the address removal events exchange between persistent params storage and Kademlia. + let (removed_addresses_tx, removed_addresses_rx) = mpsc::unbounded(); + let mut address_removal_task_handler_id = None; + if let Some(handler_id) = networking_parameters_registry.on_unreachable_address({ + Arc::new(move |event| { + if let Err(error) = removed_addresses_tx.unbounded_send(event.clone()) { + debug!(?error, ?event, "Cannot send PeerAddressRemovedEvent") + }; + }) + }) { + address_removal_task_handler_id.replace(handler_id); + } + Self { allow_non_global_addresses_in_dht, command_receiver, @@ -158,19 +225,29 @@ where // We'll make the first query right away and continue at the interval. random_query_timeout: Box::pin(tokio::time::sleep(Duration::from_secs(0)).fuse()), // We'll make the first dial right away and continue at the interval. - peer_dialing_timeout: Box::pin(tokio::time::sleep(Duration::from_secs(0)).fuse()), + periodical_tasks_interval: Box::pin(tokio::time::sleep(Duration::from_secs(0)).fuse()), networking_parameters_registry, reserved_peers, - target_connections, temporary_bans, metrics, established_connections: HashMap::new(), protocol_version, + general_connection_decision_handler, + special_connection_decision_handler, + rng: StdRng::seed_from_u64(KADEMLIA_PEERS_ADDRESSES_BATCH_SIZE as u64), // any seed + bootstrap_addresses, + bootstrap_command_state: Arc::new(AsyncMutex::new(BootstrapCommandState::default())), + kademlia_mode, + external_addresses, + removed_addresses_rx, + _address_removal_task_handler_id: address_removal_task_handler_id, } } /// Drives the main networking future forward. pub async fn run(&mut self) { + self.bootstrap().await; + loop { futures::select! { _ = &mut self.random_query_timeout => { @@ -191,7 +268,7 @@ where }, command = self.command_receiver.next() => { if let Some(command) = command { - self.handle_command(command).await; + self.handle_command(command); } else { break; } @@ -199,93 +276,96 @@ where _ = self.networking_parameters_registry.run().fuse() => { trace!("Network parameters registry runner exited.") }, - //TODO: consider changing this worker to the reactive approach (using the connection - // closing events to maintain established connections set). - _ = &mut self.peer_dialing_timeout => { - self.handle_peer_dialing().await; + _ = &mut self.periodical_tasks_interval => { + self.handle_periodical_tasks().await; - self.peer_dialing_timeout = + self.periodical_tasks_interval = Box::pin(tokio::time::sleep(Duration::from_secs(5)).fuse()); }, + event = self.removed_addresses_rx.select_next_some() => { + self.handle_removed_address_event(event); + }, } } } - async fn handle_peer_dialing(&mut self) { - let local_peer_id = *self.swarm.local_peer_id(); - let connected_peers = self.swarm.connected_peers().cloned().collect::>(); + /// Bootstraps Kademlia network + async fn bootstrap(&mut self) { + let bootstrap_command_state = self.bootstrap_command_state.clone(); + let mut bootstrap_command_state = bootstrap_command_state.lock().await; + let bootstrap_command_receiver = match &mut *bootstrap_command_state { + BootstrapCommandState::NotStarted => { + debug!("Bootstrap started."); - // Maintain target connection number. - let (total_current_connections, established_connections) = { - let network_info = self.swarm.network_info(); - let connections = network_info.connection_counters(); + let (bootstrap_command_sender, bootstrap_command_receiver) = mpsc::unbounded(); - debug!( - ?connections, - target_connections = self.target_connections, - "Current connections and limits." - ); + self.handle_command(Command::Bootstrap { + result_sender: bootstrap_command_sender, + }); - ( - connections.num_pending_outgoing() - + connections.num_established_outgoing() - + connections.num_pending_incoming() - + connections.num_established_incoming(), - connections.num_established_outgoing() + connections.num_established_incoming(), - ) + *bootstrap_command_state = + BootstrapCommandState::InProgress(bootstrap_command_receiver); + match &mut *bootstrap_command_state { + BootstrapCommandState::InProgress(bootstrap_command_receiver) => { + bootstrap_command_receiver + } + _ => { + unreachable!("Was just set to that exact value"); + } + } + } + BootstrapCommandState::InProgress(bootstrap_command_receiver) => { + bootstrap_command_receiver + } + BootstrapCommandState::Finished => { + return; + } }; - if total_current_connections < self.target_connections { - debug!( - %local_peer_id, - total_current_connections, - target_connections=self.target_connections, - connected_peers=connected_peers.len(), - "Initiate connection to known peers", - ); + debug!("Bootstrap started."); - let allow_non_global_addresses_in_dht = self.allow_non_global_addresses_in_dht; + self.swarm + .behaviour_mut() + .kademlia + .set_mode(self.kademlia_mode); + debug!("Kademlia mode set: {:?}.", self.kademlia_mode); - let addresses = self - .networking_parameters_registry - .next_known_addresses_batch() - .await - .into_iter() - .filter(|(peer_id, address)| { - if !allow_non_global_addresses_in_dht && !is_global_address_or_dns(address) { - trace!( - %local_peer_id, - %peer_id, - %address, - "Ignoring non-global address read from parameters registry.", - ); - false + let mut bootstrap_step = 0; + loop { + futures::select! { + swarm_event = self.swarm.next() => { + if let Some(swarm_event) = swarm_event { + self.register_event_metrics(&swarm_event); + self.handle_swarm_event(swarm_event).await; } else { - true + break; + } + }, + result = bootstrap_command_receiver.next() => { + if result.is_some() { + debug!(%bootstrap_step, "Kademlia bootstrapping..."); + bootstrap_step += 1; + } else { + break; } - }); - - trace!(%local_peer_id, "Processing addresses batch: {:?}", addresses); - - for (peer_id, addr) in addresses { - if connected_peers.contains(&peer_id) { - continue; } - - self.dial_peer(peer_id, addr) } - } else if established_connections < self.target_connections { - self.networking_parameters_registry - .start_over_address_batching() } + debug!("Bootstrap finished."); + *bootstrap_command_state = BootstrapCommandState::Finished; + } + + /// Handles periodical tasks. + async fn handle_periodical_tasks(&mut self) { + // Log current connections. + let network_info = self.swarm.network_info(); + let connections = network_info.connection_counters(); + + debug!(?connections, "Current connections and limits."); + // Renew known external addresses. - let mut external_addresses = self - .swarm - .external_addresses() - .cloned() - .map(|item| item.addr) - .collect::>(); + let mut external_addresses = self.swarm.external_addresses().cloned().collect::>(); if let Some(shared) = self.shared_weak.upgrade() { debug!(?external_addresses, "Renew external addresses.",); @@ -295,25 +375,6 @@ where } } - fn dial_peer(&mut self, peer_id: PeerId, addr: Multiaddr) { - let local_peer_id = *self.swarm.local_peer_id(); - trace!(%local_peer_id, remote_peer_id=%peer_id, %addr, "Dialing address ..."); - - let dial_opts = DialOpts::peer_id(peer_id) - .addresses(vec![addr.clone()]) - .build(); - - if let Err(err) = self.swarm.dial(dial_opts) { - debug!( - %err, - %local_peer_id, - remote_peer_id = %peer_id, - %addr, - "Dialing error: failed to dial an address." - ); - } - } - fn handle_random_query_interval(&mut self) { let random_peer_id = PeerId::random(); @@ -325,6 +386,21 @@ where .get_closest_peers(random_peer_id); } + fn handle_removed_address_event(&mut self, event: PeerAddressRemovedEvent) { + trace!(?event, "Peer addressed removed event.",); + + // Remove both versions of the address + self.swarm.behaviour_mut().kademlia.remove_address( + &event.peer_id, + &append_p2p_suffix(event.peer_id, event.address.clone()), + ); + + self.swarm + .behaviour_mut() + .kademlia + .remove_address(&event.peer_id, &remove_p2p_suffix(event.address)); + } + async fn handle_swarm_event(&mut self, swarm_event: SwarmEvent) { match swarm_event { SwarmEvent::Behaviour(Event::Identify(event)) => { @@ -339,6 +415,15 @@ where SwarmEvent::Behaviour(Event::RequestResponse(event)) => { self.handle_request_response_event(event).await; } + SwarmEvent::Behaviour(Event::PeerInfo(event)) => { + self.handle_peer_info_event(event).await; + } + SwarmEvent::Behaviour(Event::GeneralConnectedPeers(event)) => { + self.handle_general_connected_peers_event(event).await; + } + SwarmEvent::Behaviour(Event::SpecialConnectedPeers(event)) => { + self.handle_special_connected_peers_event(event).await; + } SwarmEvent::NewListenAddr { address, .. } => { let shared = match self.shared_weak.upgrade() { Some(shared) => shared, @@ -390,9 +475,11 @@ where *entry += 1; }) .or_insert(1); - if shared.connected_peers_count.fetch_add(1, Ordering::SeqCst) - >= CONCURRENT_TASKS_BOOST_PEERS_THRESHOLD.get() - { + let num_established_peer_connections = shared + .num_established_peer_connections + .fetch_add(1, Ordering::SeqCst) + + 1; + if num_established_peer_connections > CONCURRENT_TASKS_BOOST_PEERS_THRESHOLD.get() { // The peer count exceeded the threshold, bump up the quota. if let Err(error) = shared .kademlia_tasks_semaphore @@ -407,6 +494,15 @@ where warn!(%error, "Failed to expand regular concurrent tasks"); } } + shared + .handlers + .num_established_peer_connections_change + .call_simple(&num_established_peer_connections); + + // A new connection + if num_established.get() == 1 { + shared.handlers.connected_peer.call_simple(&peer_id); + } } SwarmEvent::ConnectionClosed { peer_id, @@ -445,8 +541,11 @@ where } }; } - if shared.connected_peers_count.fetch_sub(1, Ordering::SeqCst) - > CONCURRENT_TASKS_BOOST_PEERS_THRESHOLD.get() + let num_established_peer_connections = shared + .num_established_peer_connections + .fetch_sub(1, Ordering::SeqCst) + - 1; + if num_established_peer_connections == CONCURRENT_TASKS_BOOST_PEERS_THRESHOLD.get() { // The previous peer count was over the threshold, reclaim the quota. if let Err(error) = shared @@ -462,14 +561,27 @@ where warn!(%error, "Failed to shrink regular concurrent tasks"); } } + shared + .handlers + .num_established_peer_connections_change + .call_simple(&num_established_peer_connections); + + // No more connections + if num_established == 0 { + shared.handlers.disconnected_peer.call_simple(&peer_id); + } } - SwarmEvent::OutgoingConnectionError { peer_id, error } => { + SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => { if let Some(peer_id) = &peer_id { // Create or extend temporary ban, but only if we are not offline if let Some(shared) = self.shared_weak.upgrade() { // One peer is possibly a node peer is connected to, hence expecting more // than one for online status - if shared.connected_peers_count.load(Ordering::Relaxed) > 1 { + if shared + .num_established_peer_connections + .load(Ordering::Relaxed) + > 1 + { let should_temporary_ban = match &error { DialError::Transport(addresses) => { // Ignoring other errors, those are likely temporary ban errors @@ -487,10 +599,12 @@ where }; } + debug!(?peer_id, "SwarmEvent::OutgoingConnectionError for peer."); + match error { DialError::Transport(ref addresses) => { for (addr, _) in addresses { - debug!(?error, ?peer_id, %addr, "SwarmEvent::OutgoingConnectionError (DialError::Transport) for peer."); + trace!(?error, ?peer_id, %addr, "SwarmEvent::OutgoingConnectionError (DialError::Transport) for peer."); if let Some(peer_id) = peer_id { self.networking_parameters_registry .remove_known_peer_addresses(peer_id, vec![addr.clone()]) @@ -499,7 +613,7 @@ where } } DialError::WrongPeerId { obtained, .. } => { - debug!(?error, ?peer_id, obtained_peer_id=?obtained, "SwarmEvent::WrongPeerId (DialError::WrongPeerId) for peer."); + trace!(?error, ?peer_id, obtained_peer_id=?obtained, "SwarmEvent::WrongPeerId (DialError::WrongPeerId) for peer."); if let Some(ref peer_id) = peer_id { let kademlia = &mut self.swarm.behaviour_mut().kademlia; @@ -507,7 +621,7 @@ where } } _ => { - debug!(?error, ?peer_id, "SwarmEvent::OutgoingConnectionError"); + trace!(?error, ?peer_id, "SwarmEvent::OutgoingConnectionError"); } } } @@ -533,7 +647,7 @@ where "Peer has different protocol version. Peer was banned.", ); - self.ban_peer(peer_id).await; + self.ban_peer(peer_id); } if info.listen_addrs.len() > 30 { @@ -550,7 +664,7 @@ where let full_kademlia_support = kademlia.protocol_names().iter().all(|local_protocol| { info.protocols .iter() - .any(|remote_protocol| remote_protocol.as_bytes() == local_protocol.as_ref()) + .any(|remote_protocol| *remote_protocol == *local_protocol) }); if full_kademlia_support { @@ -575,7 +689,6 @@ where kademlia .protocol_names() .iter() - .map(|p| String::from_utf8_lossy(p.as_ref())) .collect::>(), ); kademlia.add_address(&peer_id, address); @@ -589,15 +702,54 @@ where kademlia .protocol_names() .iter() - .map(|p| String::from_utf8_lossy(p.as_ref())) .collect::>(), ); kademlia.remove_peer(&peer_id); } + + self.add_observed_external_address(info.observed_addr); } } + fn add_observed_external_address(&mut self, observed_addr: Multiaddr) { + if !self.external_addresses.is_empty() { + debug!( + "Observed address wasn't added as external (manual external addresses set): {}", + observed_addr + ); + return; + } + + // TODO: replace with Autonat + // TODO: won't work with QUIC + let mut listen_ports = HashSet::new(); + for mut listen_address in self.swarm.listeners().cloned() { + while let Some(protocol) = listen_address.pop() { + if let Protocol::Tcp(port) = protocol { + listen_ports.insert(port); + } + } + } + + let mut observed_addr_candidate = observed_addr.clone(); + while let Some(protocol) = observed_addr_candidate.pop() { + if let Protocol::Tcp(port) = protocol { + if listen_ports.contains(&port) { + debug!("Added observed address as external: {}", observed_addr); + self.swarm.add_external_address(observed_addr); + + return; + } + } + } + + debug!( + "Observed address wasn't added as external (different port): {}", + observed_addr + ); + } + async fn handle_kademlia_event(&mut self, event: KademliaEvent) { trace!("Kademlia event: {:?}", event); @@ -607,6 +759,11 @@ where } => { debug!("Unexpected AddProvider request received: {:?}", record); } + KademliaEvent::UnroutablePeer { peer } => { + debug!("Unroutable peer detected: {:?}", peer); + + self.swarm.behaviour_mut().kademlia.remove_peer(&peer); + } KademliaEvent::OutboundQueryProgressed { step: ProgressStep { last, .. }, id, @@ -615,7 +772,7 @@ where } => { let mut cancelled = false; if let Some(QueryResultSender::ClosestPeers { sender, .. }) = - self.query_id_receivers.get_mut(&id) + self.query_id_receivers.get(&id) { match result { Ok(GetClosestPeersOk { key, peers }) => { @@ -675,7 +832,7 @@ where } => { let mut cancelled = false; if let Some(QueryResultSender::Value { sender, .. }) = - self.query_id_receivers.get_mut(&id) + self.query_id_receivers.get(&id) { match result { Ok(GetRecordOk::FoundRecord(rec)) => { @@ -729,7 +886,7 @@ where } => { let mut cancelled = false; if let Some(QueryResultSender::Providers { sender, .. }) = - self.query_id_receivers.get_mut(&id) + self.query_id_receivers.get(&id) { match result { Ok(GetProvidersOk::FoundProviders { key, providers }) => { @@ -776,7 +933,7 @@ where } => { let mut cancelled = false; if let Some(QueryResultSender::PutValue { sender, .. }) = - self.query_id_receivers.get_mut(&id) + self.query_id_receivers.get(&id) { match result { Ok(PutRecordOk { key, .. }) => { @@ -801,14 +958,50 @@ where self.query_id_receivers.remove(&id); } } + KademliaEvent::OutboundQueryProgressed { + step: ProgressStep { last, .. }, + id, + result: QueryResult::Bootstrap(result), + .. + } => { + let mut cancelled = false; + if let Some(QueryResultSender::Bootstrap { sender }) = + self.query_id_receivers.get_mut(&id) + { + match result { + Ok(BootstrapOk { + peer, + num_remaining, + }) => { + trace!(%peer, %num_remaining, %last, "Bootstrap query step succeeded"); + + cancelled = Self::unbounded_send_and_cancel_on_error( + &mut self.swarm.behaviour_mut().kademlia, + sender, + (), + "Bootstrap", + &id, + ) || cancelled; + } + Err(error) => { + debug!(?error, "Bootstrap query failed."); + } + } + } + + if last || cancelled { + // There will be no more progress + self.query_id_receivers.remove(&id); + } + } _ => {} } } // Returns `true` if query was cancelled fn unbounded_send_and_cancel_on_error( - kademlia: &mut Kademlia>, - sender: &mut mpsc::UnboundedSender, + kademlia: &mut Kademlia>, + sender: &mpsc::UnboundedSender, value: T, channel: &'static str, id: &QueryId, @@ -844,7 +1037,77 @@ where trace!("Request response event: {:?}", event); } - async fn handle_command(&mut self, command: Command) { + async fn handle_peer_info_event(&mut self, event: PeerInfoEvent) { + trace!(?event, "Peer info event."); + + if let Ok(PeerInfoSuccess::Received(peer_info)) = event.result { + if let Some(shared) = self.shared_weak.upgrade() { + let connected_peers = self.swarm.connected_peers().cloned().collect::>(); + + shared.handlers.new_peer_info.call_simple(&NewPeerInfo { + peer_id: event.peer_id, + peer_info: peer_info.clone(), + connected_peers, + }); + } + + if let Some(general_connected_peers) = + self.swarm.behaviour_mut().general_connected_peers.as_mut() + { + let keep_alive = self + .general_connection_decision_handler + .as_ref() + .map(|handler| handler(&peer_info)) + .unwrap_or(false); + + general_connected_peers.update_keep_alive_status(event.peer_id, keep_alive); + } + + if let Some(special_connected_peers) = + self.swarm.behaviour_mut().special_connected_peers.as_mut() + { + let special_keep_alive = self + .special_connection_decision_handler + .as_ref() + .map(|handler| handler(&peer_info)) + .unwrap_or(false); + + special_connected_peers.update_keep_alive_status(event.peer_id, special_keep_alive); + } + } + } + + async fn handle_general_connected_peers_event( + &mut self, + event: ConnectedPeersEvent, + ) { + trace!(?event, "General connected peers event."); + + let peers = self.get_peers_to_dial().await; + + if let Some(general_connected_peers) = + self.swarm.behaviour_mut().general_connected_peers.as_mut() + { + general_connected_peers.add_peers_to_dial(&peers); + } + } + + async fn handle_special_connected_peers_event( + &mut self, + event: ConnectedPeersEvent, + ) { + trace!(?event, "Special connected peers event."); + + let peers = self.get_peers_to_dial().await; + + if let Some(special_connected_peers) = + self.swarm.behaviour_mut().special_connected_peers.as_mut() + { + special_connected_peers.add_peers_to_dial(&peers); + } + } + + fn handle_command(&mut self, command: Command) { match command { Command::GetValue { key, @@ -1026,24 +1289,9 @@ where IfDisconnected::TryConnect, ); } - Command::CheckConnectedPeers { result_sender } => { - let connected_peers_present = self.swarm.connected_peers().next().is_some(); - - let kademlia_connection_initiated = if connected_peers_present { - self.swarm.behaviour_mut().kademlia.bootstrap().is_ok() - } else { - false - }; - - let _ = result_sender.send(kademlia_connection_initiated); - } Command::StartLocalAnnouncing { key, result_sender } => { let local_peer_id = *self.swarm.local_peer_id(); - let addresses = self - .swarm - .external_addresses() - .map(|rec| rec.addr.clone()) - .collect::>(); + let addresses = self.swarm.external_addresses().cloned().collect::>(); let provider_record = ProviderRecord { provider: local_peer_id, @@ -1096,15 +1344,41 @@ where ); } Command::BanPeer { peer_id } => { - self.ban_peer(peer_id).await; + self.ban_peer(peer_id); } Command::Dial { address } => { let _ = self.swarm.dial(address); } + Command::ConnectedPeers { result_sender } => { + let connected_peers = self.swarm.connected_peers().cloned().collect(); + + let _ = result_sender.send(connected_peers); + } + Command::Bootstrap { result_sender } => { + let kademlia = &mut self.swarm.behaviour_mut().kademlia; + + for (peer_id, address) in strip_peer_id(self.bootstrap_addresses.clone()) { + kademlia.add_address(&peer_id, address); + } + + match kademlia.bootstrap() { + Ok(query_id) => { + self.query_id_receivers.insert( + query_id, + QueryResultSender::Bootstrap { + sender: result_sender, + }, + ); + } + Err(err) => { + debug!(?err, "Bootstrap error."); + } + } + } } } - async fn ban_peer(&mut self, peer_id: PeerId) { + fn ban_peer(&mut self, peer_id: PeerId) { // Remove temporary ban if there is any before creating a permanent one self.temporary_bans.lock().remove(&peer_id); @@ -1113,8 +1387,7 @@ where self.swarm.behaviour_mut().block_list.block_peer(peer_id); self.swarm.behaviour_mut().kademlia.remove_peer(&peer_id); self.networking_parameters_registry - .remove_all_known_peer_addresses(peer_id) - .await; + .remove_all_known_peer_addresses(peer_id); } fn register_event_metrics(&mut self, swarm_event: &SwarmEvent) { @@ -1142,4 +1415,77 @@ where } } } + + async fn get_peers_to_dial(&mut self) -> Vec { + let mut result_peers = + Vec::with_capacity(KADEMLIA_PEERS_ADDRESSES_BATCH_SIZE + PEERS_ADDRESSES_BATCH_SIZE); + + // Get addresses from Kademlia buckets + let mut kademlia_addresses = Vec::new(); + let mut kademlia_peers = HashSet::new(); + for kbucket in self.swarm.behaviour_mut().kademlia.kbuckets() { + for entry in kbucket.iter() { + let peer_id = *entry.node.key.preimage(); + let addresses = entry.node.value.clone().into_vec(); + + for address in addresses { + kademlia_addresses.push((peer_id, address)); + } + } + } + + // Take random batch from kademlia addresses. + for _ in 0..KADEMLIA_PEERS_ADDRESSES_BATCH_SIZE { + if kademlia_addresses.is_empty() { + break; + } + let random_index = self.rng.gen_range(0..kademlia_addresses.len()); + + let (peer_id, peer_address) = kademlia_addresses.swap_remove(random_index); + result_peers.push((peer_id, peer_address)); + kademlia_peers.insert(peer_id); + } + + // Get peer batch from the known peers registry + let connected_peers = self.swarm.connected_peers().cloned().collect::>(); + let local_peer_id = *self.swarm.local_peer_id(); + let allow_non_global_addresses_in_dht = self.allow_non_global_addresses_in_dht; + + let addresses = self + .networking_parameters_registry + .next_known_addresses_batch() + .await + .into_iter() + .filter(|(peer_id, address)| { + if !allow_non_global_addresses_in_dht && !is_global_address_or_dns(address) { + trace!( + %local_peer_id, + %peer_id, + %address, + "Ignoring non-global address read from parameters registry.", + ); + false + } else { + true + } + }); + + trace!(%local_peer_id, "Processing addresses batch: {:?}", addresses); + + for (peer_id, addr) in addresses { + if connected_peers.contains(&peer_id) || kademlia_peers.contains(&peer_id) { + continue; + } + + result_peers.push((peer_id, addr)) + } + + let bootstrap_nodes = strip_peer_id(self.bootstrap_addresses.clone()) + .into_iter() + .map(|(peer_id, _)| peer_id) + .collect::>(); + + result_peers.retain(|(peer_id, _)| !bootstrap_nodes.contains(peer_id)); + result_peers + } } diff --git a/crates/subspace-networking/src/peer_info.rs b/crates/subspace-networking/src/peer_info.rs new file mode 100644 index 00000000000..2b415c283d3 --- /dev/null +++ b/crates/subspace-networking/src/peer_info.rs @@ -0,0 +1,331 @@ +mod handler; +mod protocol; + +use crate::peer_info::handler::HandlerInEvent; +use event_listener_primitives::HandlerId; +use handler::Handler; +pub use handler::{Config, PeerInfoError, PeerInfoSuccess}; +use libp2p::core::{Endpoint, Multiaddr}; +use libp2p::swarm::behaviour::{ConnectionEstablished, FromSwarm}; +use libp2p::swarm::{ + ConnectionClosed, ConnectionDenied, ConnectionId, NetworkBehaviour, NotifyHandler, + PollParameters, THandler, THandlerInEvent, THandlerOutEvent, ToSwarm, +}; +use libp2p::PeerId; +use parity_scale_codec::{Decode, Encode}; +use parking_lot::Mutex; +use std::collections::{HashSet, VecDeque}; +use std::fmt; +use std::fmt::Debug; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use std::task::{Context, Poll, Waker}; +use tracing::debug; + +#[derive(Debug, Clone, Copy)] +/// Peer info notification stub. +pub struct Notification; +/// Defines a subscription to a peer-info notification. +pub type NotificationHandler = Arc; + +/// Cuckoo filter data transfer object. +#[derive(Clone, Encode, Decode, Default)] +pub struct CuckooFilterDTO { + /// Exported cuckoo filter values. + pub values: Vec, + /// Cuckoo filter items. + pub length: u64, +} + +impl fmt::Debug for CuckooFilterDTO { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("CuckooFilterDTO") + .field("values", &self.length) + .field("length", &self.values.len()) + .finish() + } +} + +#[derive(Clone, Encode, Decode, Default, Debug)] +/// Peer info data +pub enum PeerInfo { + /// DSN farmer. + Farmer { + /// Peer info data. + cuckoo_filter: Arc, + }, + /// DSN node. + Node, + /// DSN bootstrap node. + BootstrapNode, + /// Unspecified client (testing, custom utilities, etc). + #[default] + Client, +} + +impl PeerInfo { + /// Returns whether [`PeerInfo`] is a Farmer. + pub fn is_farmer(peer_info: &PeerInfo) -> bool { + matches!(peer_info, Self::Farmer { .. }) + } +} + +/// A [`NetworkBehaviour`] that handles inbound peer info requests and +/// sends outbound peer info requests on the first established connection. +pub struct Behaviour { + /// Peer info protocol configuration. + config: Config, + /// Queue of events to yield to the swarm. + events: VecDeque, + /// Outbound peer info pushes. + requests: Vec, + /// Provides up-to-date peer info. + peer_info_provider: PeerInfoProvider, + /// Whether the behaviour should notify connected peers. + should_notify_handlers: Arc, + /// We just save the handler ID. + _notify_handler_id: Option, + /// Known connected peers. + connected_peers: HashSet, + /// Future waker. + waker: Arc>>, +} + +#[derive(Debug)] +/// Peer info push request. Handlers wait for these requests to send data. +struct Request { + peer_id: PeerId, + peer_info: Arc, +} + +/// Handles constant peer info data. +#[derive(Debug)] +pub enum PeerInfoProvider { + /// Provides peer-info for Node peer type. + Node, + /// Provides peer-info for Boostrap Node peer type. + BootstrapNode, + /// Provides peer-info for Client peer type. + Client, + /// Provides peer-info for Farmer peer type. + Farmer(Box), +} + +/// Provides the current cuckoo-filter data. +pub trait CuckooFilterProvider: Debug + 'static { + /// Returns the current cuckoo filter data. + fn cuckoo_filter(&self) -> CuckooFilterDTO; + /// Subscribe to cuckoo filter updates and invoke provided callback. + fn on_notification(&self, callback: NotificationHandler) -> Option; +} + +impl PeerInfoProvider { + /// Creates a new Node peer-info provider. + pub fn new_node() -> Self { + Self::Node + } + /// Creates a new Bootstrap Node peer-info provider. + pub fn new_bootstrap_node() -> Self { + Self::BootstrapNode + } + /// Creates a new Client peer-info provider. + pub fn new_client() -> Self { + Self::Client + } + /// Creates a new Farmer peer-info provider. + pub fn new_farmer(provider: Box) -> Self { + Self::Farmer(provider) + } + + /// Returns the peer info data. + pub fn peer_info(&self) -> PeerInfo { + match self { + PeerInfoProvider::Node => PeerInfo::Node, + PeerInfoProvider::BootstrapNode => PeerInfo::BootstrapNode, + PeerInfoProvider::Client => PeerInfo::Client, + PeerInfoProvider::Farmer(provider) => PeerInfo::Farmer { + cuckoo_filter: Arc::new(provider.cuckoo_filter()), + }, + } + } + /// Subscribe to peer info updates and invoke provided callback. + pub fn on_notification(&self, handler: NotificationHandler) -> Option { + match self { + PeerInfoProvider::Node | PeerInfoProvider::BootstrapNode | PeerInfoProvider::Client => { + None + } + PeerInfoProvider::Farmer(provider) => provider.on_notification(handler), + } + } +} + +/// Event generated by the `Peer Info` network behaviour. +#[derive(Debug)] +pub struct Event { + /// The peer ID of the remote. + pub peer_id: PeerId, + /// The result of an inbound or outbound peer info request. + pub result: Result, +} + +impl Behaviour { + /// Creates a new `Peer Info` network behaviour with the given configuration. + pub fn new(config: Config, peer_info_provider: PeerInfoProvider) -> Self { + let waker = Arc::new(Mutex::new(None::)); + let should_notify_handlers = Arc::new(AtomicBool::new(false)); + let _notify_handler_id = peer_info_provider.on_notification({ + let should_notify_handlers = should_notify_handlers.clone(); + let waker = waker.clone(); + + Arc::new(move |_| { + should_notify_handlers.store(true, Ordering::SeqCst); + if let Some(waker) = waker.lock().as_mut() { + waker.wake_by_ref(); + } + }) + }); + + Self { + _notify_handler_id, + config, + peer_info_provider, + events: VecDeque::new(), + requests: Vec::new(), + should_notify_handlers, + connected_peers: HashSet::new(), + waker, + } + } + + fn wake(&self) { + if let Some(waker) = &self.waker.lock().as_mut() { + waker.wake_by_ref() + } + } +} + +impl NetworkBehaviour for Behaviour { + type ConnectionHandler = Handler; + type ToSwarm = Event; + + fn handle_established_inbound_connection( + &mut self, + _: ConnectionId, + _: PeerId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, ConnectionDenied> { + Ok(Handler::new(self.config.clone())) + } + + fn handle_established_outbound_connection( + &mut self, + _: ConnectionId, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + ) -> Result, ConnectionDenied> { + Ok(Handler::new(self.config.clone())) + } + + fn on_connection_handler_event( + &mut self, + peer: PeerId, + _: ConnectionId, + result: THandlerOutEvent, + ) { + self.events.push_front(Event { + peer_id: peer, + result, + }); + self.wake(); + } + + fn poll( + &mut self, + cx: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll>> { + if self.should_notify_handlers.swap(false, Ordering::SeqCst) { + debug!("Notify peer-info handlers."); + + self.requests.clear(); + let peer_info = Arc::new(self.peer_info_provider.peer_info()); + for peer_id in self.connected_peers.iter().cloned() { + self.requests.push(Request { + peer_id, + peer_info: peer_info.clone(), + }); + } + } + + if let Some(e) = self.events.pop_back() { + let Event { result, peer_id } = &e; + + match result { + Ok(PeerInfoSuccess::Sent) => { + debug!(%peer_id, "Peer info sent.") + } + Ok(PeerInfoSuccess::Received(_)) => { + debug!(%peer_id, "Peer info received") + } + Err(err) => { + debug!(%peer_id, ?err, "Peer info error"); + } + } + + return Poll::Ready(ToSwarm::GenerateEvent(e)); + } + + // Check for pending requests. + if let Some(Request { peer_id, peer_info }) = self.requests.pop() { + return Poll::Ready(ToSwarm::NotifyHandler { + peer_id, + handler: NotifyHandler::Any, + event: HandlerInEvent { peer_info }, + }); + } + + self.waker.lock().replace(cx.waker().clone()); + Poll::Pending + } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id, + other_established, + .. + }) => { + self.connected_peers.insert(peer_id); + + // Push the peer-info request on the first connection. + if other_established == 0 { + let peer_info = Arc::new(self.peer_info_provider.peer_info()); + self.requests.push(Request { peer_id, peer_info }); + self.wake(); + } + } + FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + remaining_established, + .. + }) => { + if remaining_established == 0 { + self.connected_peers.remove(&peer_id); + } + } + FromSwarm::AddressChange(_) + | FromSwarm::DialFailure(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddrCandidate(_) + | FromSwarm::ExternalAddrConfirmed(_) + | FromSwarm::ExternalAddrExpired(_) => {} + } + } +} diff --git a/crates/subspace-networking/src/peer_info/handler.rs b/crates/subspace-networking/src/peer_info/handler.rs new file mode 100644 index 00000000000..8bcc819ba32 --- /dev/null +++ b/crates/subspace-networking/src/peer_info/handler.rs @@ -0,0 +1,290 @@ +use crate::peer_info::{protocol, PeerInfo}; +use futures::future::BoxFuture; +use futures::prelude::*; +use libp2p::core::upgrade::ReadyUpgrade; +use libp2p::swarm::handler::{ + ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, + ListenUpgradeError, StreamUpgradeError as ConnectionHandlerUpgrErr, +}; +use libp2p::swarm::{ + ConnectionHandler, ConnectionHandlerEvent, KeepAlive, Stream as NegotiatedSubstream, + SubstreamProtocol, +}; +use libp2p::StreamProtocol; +use std::error::Error; +use std::io; +use std::sync::Arc; +use std::task::{Context, Poll, Waker}; +use std::time::Duration; +use tracing::debug; + +/// The configuration for peer-info protocol. +#[derive(Debug, Clone)] +pub struct Config { + /// Protocol timeout. + timeout: Duration, + + /// Protocol name. + protocol_name: &'static str, +} + +impl Config { + /// Creates a new [`Config`] with the following default settings: + /// + /// * [`Config::with_timeout`] 20s + pub fn new(protocol_name: &'static str) -> Self { + Self { + timeout: Duration::from_secs(20), + protocol_name, + } + } + + /// Sets the protocol timeout. + pub fn with_timeout(mut self, d: Duration) -> Self { + self.timeout = d; + self + } +} + +/// The successful result of processing an inbound or outbound peer info requests. +#[derive(Debug)] +pub enum PeerInfoSuccess { + /// Local peer received peer info from a remote peer. + Received(PeerInfo), + /// Local peer sent its peer info to a remote peer. + Sent, +} + +/// A peer info protocol failure. +#[derive(Debug, thiserror::Error)] +pub enum PeerInfoError { + /// The peer does not support the peer info protocol. + #[error("Peer info protocol is not supported.")] + #[allow(dead_code)] // We preserve errors on dial upgrades for future use. + Unsupported, + /// The peer info request failed. + #[error("Peer info error: {error}")] + Other { + #[source] + error: Box, + }, +} + +/// Struct for outbound peer-info requests. +#[derive(Debug, Clone)] +pub struct HandlerInEvent { + pub peer_info: Arc, +} + +/// Protocol handler that handles peer-info requests. +/// +/// Any protocol failure produces an error that closes the connection. +pub struct Handler { + /// Configuration options. + config: Config, + /// The outbound request state. + outbound: Option, + /// The inbound request future. + inbound: Option, + /// Last peer-info error. + error: Option, + /// Future waker. + waker: Option, +} + +impl Handler { + /// Builds a new [`Handler`] with the given configuration. + pub fn new(config: Config) -> Self { + Handler { + config, + outbound: None, + inbound: None, + error: None, + waker: None, + } + } + + fn wake(&self) { + if let Some(waker) = &self.waker { + waker.wake_by_ref() + } + } +} + +impl ConnectionHandler for Handler { + type FromBehaviour = HandlerInEvent; + type ToBehaviour = Result; + type Error = PeerInfoError; + type InboundProtocol = ReadyUpgrade; + type OutboundProtocol = ReadyUpgrade; + type OutboundOpenInfo = Arc; + type InboundOpenInfo = (); + + fn listen_protocol(&self) -> SubstreamProtocol, ()> { + SubstreamProtocol::new( + ReadyUpgrade::new(StreamProtocol::new(self.config.protocol_name)), + (), + ) + } + + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { + if let Some(OutboundState::Idle(stream)) = self.outbound.take() { + self.outbound = Some(OutboundState::SendingData( + protocol::send(stream, event.peer_info).boxed(), + )); + } else { + self.outbound = Some(OutboundState::RequestNewStream(event.peer_info)); + } + self.wake(); + } + + fn connection_keep_alive(&self) -> KeepAlive { + KeepAlive::No + } + + fn poll( + &mut self, + cx: &mut Context<'_>, + ) -> Poll< + ConnectionHandlerEvent< + ReadyUpgrade, + Self::OutboundOpenInfo, + Result, + Self::Error, + >, + > { + if let Some(error) = self.error.take() { + return Poll::Ready(ConnectionHandlerEvent::Close(error)); + } + + // Respond to inbound requests. + if let Some(fut) = self.inbound.as_mut() { + match fut.poll_unpin(cx) { + Poll::Pending => {} + Poll::Ready(Err(err)) => { + debug!(?err, "Peer info handler: inbound peer info error."); + + return Poll::Ready(ConnectionHandlerEvent::Close(PeerInfoError::Other { + error: Box::new(err), + })); + } + Poll::Ready(Ok((stream, peer_info))) => { + debug!(?peer_info, "Inbound peer info"); + + self.inbound = Some(protocol::recv(stream).boxed()); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Ok( + PeerInfoSuccess::Received(peer_info), + ))); + } + } + } + + // Outbound requests. + match self.outbound.take() { + Some(OutboundState::SendingData(mut peer_info_fut)) => { + match peer_info_fut.poll_unpin(cx) { + Poll::Pending => { + self.outbound = Some(OutboundState::SendingData(peer_info_fut)); + } + Poll::Ready(Ok(stream)) => { + self.outbound = Some(OutboundState::Idle(stream)); + + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Ok( + PeerInfoSuccess::Sent, + ))); + } + Poll::Ready(Err(error)) => { + debug!(?error, "Outbound peer info error.",); + + self.error = Some(PeerInfoError::Other { + error: Box::new(error), + }); + } + } + } + Some(OutboundState::Idle(stream)) => { + // Nothing to do but we have a negotiated stream. + self.outbound = Some(OutboundState::Idle(stream)); + } + Some(OutboundState::NegotiatingStream) => { + self.outbound = Some(OutboundState::NegotiatingStream); + } + Some(OutboundState::RequestNewStream(peer_info)) => { + self.outbound = Some(OutboundState::NegotiatingStream); + let protocol = SubstreamProtocol::new( + ReadyUpgrade::new(StreamProtocol::new(self.config.protocol_name)), + peer_info, + ) + .with_timeout(self.config.timeout); + return Poll::Ready(ConnectionHandlerEvent::OutboundSubstreamRequest { protocol }); + } + None => { + // Not initialized yet. + } + } + + self.waker = Some(cx.waker().clone()); + Poll::Pending + } + + fn on_connection_event( + &mut self, + event: ConnectionEvent< + Self::InboundProtocol, + Self::OutboundProtocol, + Self::InboundOpenInfo, + Self::OutboundOpenInfo, + >, + ) { + match event { + ConnectionEvent::FullyNegotiatedInbound(FullyNegotiatedInbound { + protocol: stream, + .. + }) => { + self.inbound = Some(protocol::recv(stream).boxed()); + } + ConnectionEvent::FullyNegotiatedOutbound(FullyNegotiatedOutbound { + protocol: stream, + info, + }) => { + self.outbound = Some(OutboundState::SendingData( + protocol::send(stream, info).boxed(), + )); + } + ConnectionEvent::DialUpgradeError(DialUpgradeError { error, .. }) => { + match error { + ConnectionHandlerUpgrErr::NegotiationFailed + | ConnectionHandlerUpgrErr::Apply(..) => { + debug!("Peer-info protocol dial upgrade failed."); + } + e => { + self.error = Some(PeerInfoError::Other { error: Box::new(e) }); + } + }; + } + ConnectionEvent::ListenUpgradeError(ListenUpgradeError { error, .. }) => { + self.error = Some(PeerInfoError::Other { + error: Box::new(error), + }); + } + ConnectionEvent::AddressChange(_) => {} + ConnectionEvent::LocalProtocolsChange(_) => {} + ConnectionEvent::RemoteProtocolsChange(_) => {} + } + self.wake(); + } +} + +type InPeerInfoFuture = BoxFuture<'static, Result<(NegotiatedSubstream, PeerInfo), io::Error>>; +type OutPeerInfoFuture = BoxFuture<'static, Result>; + +/// The current state w.r.t. outbound peer info requests. +enum OutboundState { + RequestNewStream(Arc), + /// A new substream is being negotiated for the protocol. + NegotiatingStream, + /// A peer info request is being sent and the response awaited. + SendingData(OutPeerInfoFuture), + /// The substream is idle, waiting to send the next peer info request. + Idle(NegotiatedSubstream), +} diff --git a/crates/subspace-networking/src/peer_info/protocol.rs b/crates/subspace-networking/src/peer_info/protocol.rs new file mode 100644 index 00000000000..0d1991eab13 --- /dev/null +++ b/crates/subspace-networking/src/peer_info/protocol.rs @@ -0,0 +1,40 @@ +//! This module defines low-level functions for working with inbound and outbound streams. + +use crate::peer_info::PeerInfo; +use futures::prelude::*; +use parity_scale_codec::{Decode, Encode}; +use std::io; +use std::io::ErrorKind; +use std::sync::Arc; + +/// Send peer-info data to a remote peer. +pub async fn send(mut stream: S, pi: Arc) -> io::Result +where + S: AsyncRead + AsyncWrite + Unpin, +{ + let send_data = pi.encode(); + let send_len_bytes = (send_data.len() as u32).to_le_bytes(); + + stream.write_all(&send_len_bytes).await?; + stream.write_all(&send_data).await?; + stream.flush().await?; + + Ok(stream) +} + +/// Receive peer-info data from a remote peer. +pub async fn recv(mut stream: S) -> io::Result<(S, PeerInfo)> +where + S: AsyncRead + AsyncWrite + Unpin, +{ + let mut rec_len_bytes = 0u32.to_le_bytes(); + stream.read_exact(&mut rec_len_bytes).await?; + let rec_len = u32::from_le_bytes(rec_len_bytes) as usize; + let mut rec_data = vec![0; rec_len]; + + stream.read_exact(&mut rec_data).await?; + let received_peer_info = + PeerInfo::decode(&mut &*rec_data).map_err(|err| io::Error::new(ErrorKind::Other, err))?; + + Ok((stream, received_peer_info)) +} diff --git a/crates/subspace-networking/src/request_handlers.rs b/crates/subspace-networking/src/request_handlers.rs index 0f01ad50a3a..d7ec532d9ec 100644 --- a/crates/subspace-networking/src/request_handlers.rs +++ b/crates/subspace-networking/src/request_handlers.rs @@ -1,6 +1,5 @@ pub mod generic_request_handler; pub mod object_mappings; -pub mod peer_info; pub mod piece_announcement; pub mod piece_by_key; pub mod pieces_by_range; diff --git a/crates/subspace-networking/src/request_handlers/peer_info.rs b/crates/subspace-networking/src/request_handlers/peer_info.rs deleted file mode 100644 index 678a68cd36d..00000000000 --- a/crates/subspace-networking/src/request_handlers/peer_info.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::{GenericRequest, GenericRequestHandler}; -use parity_scale_codec::{Decode, Encode}; - -/// Peer-info protocol request. -#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode)] -pub struct PeerInfoRequest; - -/// Defines peer synchronization status. -#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] -pub enum PeerSyncStatus { - /// Special status for starting peer. Receiving it in the running mode means an error. - Unknown, - /// Synchronization is not supported for this peer. - NotSupported, - /// Peer is ready to provide data for synchronization. - Ready, - /// Peer is synchronizing. - Syncing, -} - -/// Defines peer current state. -#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] -pub struct PeerInfo { - /// Synchronization status. - pub status: PeerSyncStatus, -} - -impl GenericRequest for PeerInfoRequest { - const PROTOCOL_NAME: &'static str = "/subspace/sync/peer-info/0.1.0"; - const LOG_TARGET: &'static str = "peer-info-request-response-handler"; - type Response = PeerInfoResponse; -} - -/// Peer-info protocol response. -#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] -pub struct PeerInfoResponse { - /// Returned data. - pub peer_info: PeerInfo, -} - -/// Create a new peer-info request handler. -pub type PeerInfoRequestHandler = GenericRequestHandler; diff --git a/crates/subspace-networking/src/request_handlers/piece_announcement.rs b/crates/subspace-networking/src/request_handlers/piece_announcement.rs index ee872d6ad81..fd851faab30 100644 --- a/crates/subspace-networking/src/request_handlers/piece_announcement.rs +++ b/crates/subspace-networking/src/request_handlers/piece_announcement.rs @@ -4,7 +4,7 @@ //! `RequestResponsesBehaviour` with generic [`GenericRequestHandler`]. use crate::request_handlers::generic_request_handler::{GenericRequest, GenericRequestHandler}; -use libp2p::multihash::Multihash; +use crate::utils::multihash::Multihash; use libp2p::Multiaddr; use parity_scale_codec::{Decode, Encode, Error, Input, Output}; @@ -100,8 +100,6 @@ pub enum PieceAnnouncementResponse { Success, } -//TODO: remove attribute on the first usage -#[allow(dead_code)] /// Create a new piece announcement request handler. pub type PieceAnnouncementRequestHandler = GenericRequestHandler; diff --git a/crates/subspace-networking/src/request_handlers/piece_by_key.rs b/crates/subspace-networking/src/request_handlers/piece_by_key.rs index c9eabfc81d9..7ceebb2e5cc 100644 --- a/crates/subspace-networking/src/request_handlers/piece_by_key.rs +++ b/crates/subspace-networking/src/request_handlers/piece_by_key.rs @@ -27,7 +27,5 @@ pub struct PieceByHashResponse { pub piece: Option, } -//TODO: remove attribute on the first usage -#[allow(dead_code)] /// Create a new piece-by-hash request handler. pub type PieceByHashRequestHandler = GenericRequestHandler; diff --git a/crates/subspace-networking/src/request_handlers/segment_header.rs b/crates/subspace-networking/src/request_handlers/segment_header.rs index b1eff47f73f..dd46841f4a3 100644 --- a/crates/subspace-networking/src/request_handlers/segment_header.rs +++ b/crates/subspace-networking/src/request_handlers/segment_header.rs @@ -35,7 +35,5 @@ pub struct SegmentHeaderResponse { pub segment_headers: Vec, } -//TODO: remove attribute on the first usage -#[allow(dead_code)] /// Create a new segment-header-by-segment-indexes request handler. pub type SegmentHeaderBySegmentIndexesRequestHandler = GenericRequestHandler; diff --git a/crates/subspace-networking/src/request_responses.rs b/crates/subspace-networking/src/request_responses.rs index 72000c995e5..8053e33f75a 100644 --- a/crates/subspace-networking/src/request_responses.rs +++ b/crates/subspace-networking/src/request_responses.rs @@ -51,9 +51,10 @@ pub use libp2p::request_response::{InboundFailure, OutboundFailure, RequestId}; use libp2p::swarm::behaviour::{ConnectionClosed, DialFailure, FromSwarm, ListenFailure}; use libp2p::swarm::handler::multi::MultiHandler; use libp2p::swarm::{ - ConnectionDenied, ConnectionHandler, ConnectionId, NetworkBehaviour, PollParameters, - THandlerInEvent, ToSwarm, + ConnectionDenied, ConnectionId, NetworkBehaviour, PollParameters, THandlerInEvent, + THandlerOutEvent, ToSwarm, }; +use libp2p::StreamProtocol; use std::borrow::Cow; use std::collections::hash_map::Entry; use std::collections::HashMap; @@ -334,12 +335,12 @@ impl RequestResponsesBehaviour { ProtocolSupport::Outbound }; - let rq_rp = RequestResponse::new( + let rq_rp = RequestResponse::with_codec( GenericCodec { max_request_size: config.max_request_size, max_response_size: config.max_response_size, }, - iter::once((config.name.as_bytes().to_vec(), protocol_support)), + iter::once(StreamProtocol::new(config.name)).zip(iter::repeat(protocol_support)), cfg, ); @@ -417,7 +418,7 @@ impl NetworkBehaviour for RequestResponsesBehaviour { String, as NetworkBehaviour>::ConnectionHandler, >; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -555,31 +556,33 @@ impl NetworkBehaviour for RequestResponsesBehaviour { protocol.on_swarm_event(FromSwarm::ListenerClosed(inner)); } } - FromSwarm::NewExternalAddr(inner) => { + FromSwarm::NewExternalAddrCandidate(inner) => { for (protocol, _) in self.protocols.values_mut() { - protocol.on_swarm_event(FromSwarm::NewExternalAddr(inner)); + protocol.on_swarm_event(FromSwarm::NewExternalAddrCandidate(inner)); } } - FromSwarm::ExpiredExternalAddr(inner) => { + FromSwarm::ExternalAddrConfirmed(inner) => { for (protocol, _) in self.protocols.values_mut() { - protocol.on_swarm_event(FromSwarm::ExpiredExternalAddr(inner)); + protocol.on_swarm_event(FromSwarm::ExternalAddrConfirmed(inner)); + } + } + FromSwarm::ExternalAddrExpired(inner) => { + for (protocol, _) in self.protocols.values_mut() { + protocol.on_swarm_event(FromSwarm::ExternalAddrExpired(inner)); } } }; } - fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { - Vec::new() - } - fn on_connection_handler_event( &mut self, peer_id: PeerId, connection: ConnectionId, - (p_name, event): ::OutEvent, + event: THandlerOutEvent, ) { + let p_name = event.0; if let Some((proto, _)) = self.protocols.get_mut(&*p_name) { - return proto.on_connection_handler_event(peer_id, connection, event); + return proto.on_connection_handler_event(peer_id, connection, event.1); } warn!( @@ -592,7 +595,7 @@ impl NetworkBehaviour for RequestResponsesBehaviour { &mut self, cx: &mut Context, params: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { 'poll_all: loop { if let Some(message_request) = self.message_request.take() { let MessageRequest { @@ -707,9 +710,6 @@ impl NetworkBehaviour for RequestResponsesBehaviour { event: ((*protocol).to_string(), event), }) } - ToSwarm::ReportObservedAddr { address, score } => { - return Poll::Ready(ToSwarm::ReportObservedAddr { address, score }) - } ToSwarm::CloseConnection { peer_id, connection, @@ -719,6 +719,21 @@ impl NetworkBehaviour for RequestResponsesBehaviour { connection, }) } + ToSwarm::NewExternalAddrCandidate(observed) => { + return Poll::Ready(ToSwarm::NewExternalAddrCandidate(observed)) + } + ToSwarm::ExternalAddrConfirmed(addr) => { + return Poll::Ready(ToSwarm::ExternalAddrConfirmed(addr)) + } + ToSwarm::ExternalAddrExpired(addr) => { + return Poll::Ready(ToSwarm::ExternalAddrExpired(addr)) + } + ToSwarm::ListenOn { opts } => { + return Poll::Ready(ToSwarm::ListenOn { opts }) + } + ToSwarm::RemoveListener { id } => { + return Poll::Ready(ToSwarm::RemoveListener { id }) + } }; match ev { @@ -909,7 +924,7 @@ pub struct GenericCodec { #[async_trait::async_trait] impl RequestResponseCodec for GenericCodec { - type Protocol = Vec; + type Protocol = StreamProtocol; type Request = Vec; type Response = Result, ()>; diff --git a/crates/subspace-networking/src/reserved_peers.rs b/crates/subspace-networking/src/reserved_peers.rs index 33a2c429461..b5f95bba0e3 100644 --- a/crates/subspace-networking/src/reserved_peers.rs +++ b/crates/subspace-networking/src/reserved_peers.rs @@ -15,7 +15,7 @@ use std::task::{Context, Poll}; use std::time::{Duration, Instant}; use tracing::{debug, trace}; -use crate::utils::convert_multiaddresses; +use crate::utils::strip_peer_id; /// `Behaviour` controls and maintains the state of connections to a predefined set of peers. /// @@ -50,7 +50,7 @@ use crate::utils::convert_multiaddresses; #[derive(Debug)] pub struct Behaviour { /// Protocol name. - protocol_name: &'static [u8], + protocol_name: &'static str, /// A mapping from `PeerId` to `ReservedPeerState`, where each `ReservedPeerState` /// represents the current state of the connection to a reserved peer. reserved_peers_state: HashMap, @@ -60,7 +60,7 @@ pub struct Behaviour { #[derive(Debug, Clone)] pub struct Config { /// Protocol name. - pub protocol_name: &'static [u8], + pub protocol_name: &'static str, /// Predefined set of reserved peers with addresses. pub reserved_peers: Vec, } @@ -108,7 +108,7 @@ impl Behaviour { "Reserved peers protocol initialization...." ); - let peer_addresses = convert_multiaddresses(config.reserved_peers); + let peer_addresses = strip_peer_id(config.reserved_peers); let reserved_peers_state = peer_addresses .into_iter() @@ -144,7 +144,7 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -210,8 +210,9 @@ impl NetworkBehaviour for Behaviour { | FromSwarm::ExpiredListenAddr(_) | FromSwarm::ListenerError(_) | FromSwarm::ListenerClosed(_) - | FromSwarm::NewExternalAddr(_) - | FromSwarm::ExpiredExternalAddr(_) => {} + | FromSwarm::NewExternalAddrCandidate(_) + | FromSwarm::ExternalAddrConfirmed(_) + | FromSwarm::ExternalAddrExpired(_) => {} } } @@ -227,7 +228,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { for (_, state) in self.reserved_peers_state.iter_mut() { trace!(?state, "Reserved peer state."); diff --git a/crates/subspace-networking/src/reserved_peers/handler.rs b/crates/subspace-networking/src/reserved_peers/handler.rs index d34ab8fa463..5493dc9c412 100644 --- a/crates/subspace-networking/src/reserved_peers/handler.rs +++ b/crates/subspace-networking/src/reserved_peers/handler.rs @@ -1,6 +1,7 @@ use libp2p::core::upgrade::ReadyUpgrade; use libp2p::swarm::handler::ConnectionEvent; use libp2p::swarm::{ConnectionHandler, ConnectionHandlerEvent, KeepAlive, SubstreamProtocol}; +use libp2p::StreamProtocol; use std::error::Error; use std::fmt; use std::task::{Context, Poll}; @@ -21,14 +22,14 @@ use void::Void; /// while connections to non-reserved peers are allowed to close. pub struct Handler { /// Protocol name. - protocol_name: &'static [u8], + protocol_name: &'static str, /// A boolean flag indicating whether the handler is currently connected to a reserved peer. connected_to_reserved_peer: bool, } impl Handler { /// Builds a new [`Handler`]. - pub fn new(protocol_name: &'static [u8], connected_to_reserved_peer: bool) -> Self { + pub fn new(protocol_name: &'static str, connected_to_reserved_peer: bool) -> Self { Handler { protocol_name, connected_to_reserved_peer, @@ -48,16 +49,19 @@ impl fmt::Display for ReservedPeersError { impl Error for ReservedPeersError {} impl ConnectionHandler for Handler { - type InEvent = Void; - type OutEvent = (); + type FromBehaviour = Void; + type ToBehaviour = (); type Error = ReservedPeersError; - type InboundProtocol = ReadyUpgrade<&'static [u8]>; - type OutboundProtocol = ReadyUpgrade<&'static [u8]>; + type InboundProtocol = ReadyUpgrade; + type OutboundProtocol = ReadyUpgrade; type OutboundOpenInfo = (); type InboundOpenInfo = (); - fn listen_protocol(&self) -> SubstreamProtocol, ()> { - SubstreamProtocol::new(ReadyUpgrade::new(self.protocol_name), ()) + fn listen_protocol(&self) -> SubstreamProtocol, ()> { + SubstreamProtocol::new( + ReadyUpgrade::new(StreamProtocol::new(self.protocol_name)), + (), + ) } fn on_behaviour_event(&mut self, _: Void) {} @@ -73,7 +77,7 @@ impl ConnectionHandler for Handler { fn poll( &mut self, _: &mut Context<'_>, - ) -> Poll, (), (), Self::Error>> { + ) -> Poll, (), (), Self::Error>> { Poll::Pending } diff --git a/crates/subspace-networking/src/shared.rs b/crates/subspace-networking/src/shared.rs index acb07905146..88266cb2f88 100644 --- a/crates/subspace-networking/src/shared.rs +++ b/crates/subspace-networking/src/shared.rs @@ -1,12 +1,12 @@ //! Data structures shared between node and node runner, facilitating exchange and creation of //! queries, subscriptions, various events and shared information. +use crate::peer_info::PeerInfo; use crate::request_responses::RequestFailure; -use crate::utils::{ResizableSemaphore, ResizableSemaphorePermit}; +use crate::utils::multihash::Multihash; +use crate::utils::{Handler, ResizableSemaphore, ResizableSemaphorePermit}; use bytes::Bytes; -use event_listener_primitives::Bag; use futures::channel::{mpsc, oneshot}; -use libp2p::core::multihash::Multihash; use libp2p::gossipsub::{PublishError, Sha256Topic, SubscriptionError}; use libp2p::kad::record::Key; use libp2p::kad::PeerRecord; @@ -60,9 +60,6 @@ pub(crate) enum Command { request: Vec, result_sender: oneshot::Sender, RequestFailure>>, }, - CheckConnectedPeers { - result_sender: oneshot::Sender, - }, StartLocalAnnouncing { key: Key, result_sender: oneshot::Sender, @@ -82,14 +79,32 @@ pub(crate) enum Command { Dial { address: Multiaddr, }, + ConnectedPeers { + result_sender: oneshot::Sender>, + }, + Bootstrap { + result_sender: mpsc::UnboundedSender<()>, + }, } -pub(crate) type HandlerFn = Arc; -type Handler = Bag, A>; +/// [`PeerInfo`] update and related data container. +#[derive(Debug)] +pub struct NewPeerInfo { + /// Peer ID for this [`PeerInfo`] update. + pub peer_id: PeerId, + /// [`PeerInfo`] update. + pub peer_info: PeerInfo, + /// Currently connected peers. + pub connected_peers: Vec, +} #[derive(Default, Debug)] pub(crate) struct Handlers { pub(crate) new_listener: Handler, + pub(crate) num_established_peer_connections_change: Handler, + pub(crate) new_peer_info: Handler, + pub(crate) disconnected_peer: Handler, + pub(crate) connected_peer: Handler, } #[derive(Debug)] @@ -99,7 +114,7 @@ pub(crate) struct Shared { /// Addresses on which node is listening for incoming requests. pub(crate) listeners: Mutex>, pub(crate) external_addresses: Mutex>, - pub(crate) connected_peers_count: Arc, + pub(crate) num_established_peer_connections: Arc, /// Sender end of the channel for sending commands to the swarm. pub(crate) command_sender: mpsc::Sender, pub(crate) kademlia_tasks_semaphore: ResizableSemaphore, @@ -118,7 +133,7 @@ impl Shared { id, listeners: Mutex::default(), external_addresses: Mutex::default(), - connected_peers_count: Arc::new(AtomicUsize::new(0)), + num_established_peer_connections: Arc::new(AtomicUsize::new(0)), command_sender, kademlia_tasks_semaphore, regular_tasks_semaphore, diff --git a/crates/subspace-networking/src/utils.rs b/crates/subspace-networking/src/utils.rs index 162ae15dd7a..587183a0311 100644 --- a/crates/subspace-networking/src/utils.rs +++ b/crates/subspace-networking/src/utils.rs @@ -1,23 +1,58 @@ //! Miscellaneous utilities for networking. pub mod multihash; -pub mod piece_announcement; pub mod piece_provider; pub(crate) mod prometheus; #[cfg(test)] mod tests; pub(crate) mod unique_record_binary_heap; +use event_listener_primitives::Bag; +use futures::future::{Fuse, FusedFuture, FutureExt}; use libp2p::multiaddr::Protocol; use libp2p::{Multiaddr, PeerId}; use parking_lot::Mutex; +use std::future::Future; use std::marker::PhantomData; use std::num::NonZeroUsize; +use std::pin::Pin; use std::sync::Arc; +use std::task::{Context, Poll}; use thiserror::Error; +use tokio::runtime::Handle; use tokio::sync::Notify; +use tokio::task; use tracing::warn; +/// Joins async join handle on drop +pub(crate) struct AsyncJoinOnDrop(Option>>); + +impl Drop for AsyncJoinOnDrop { + fn drop(&mut self) { + let handle = self.0.take().expect("Always called exactly once; qed"); + if !handle.is_terminated() { + task::block_in_place(move || { + let _ = Handle::current().block_on(handle); + }); + } + } +} + +impl AsyncJoinOnDrop { + // Create new instance + pub(crate) fn new(handle: task::JoinHandle) -> Self { + Self(Some(handle.fuse())) + } +} + +impl Future for AsyncJoinOnDrop { + type Output = Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(self.0.as_mut().expect("Only dropped in Drop impl; qed")).poll(cx) + } +} + /// This test is successful only for global IP addresses and DNS names. pub(crate) fn is_global_address_or_dns(addr: &Multiaddr) -> bool { match addr.iter().next() { @@ -84,9 +119,9 @@ impl CollectionBatcher { // Convenience alias for peer ID and its multiaddresses. pub(crate) type PeerAddress = (PeerId, Multiaddr); -// Helper function. Converts multiaddresses to a tuple with peer ID removing the peer Id suffix. -// It logs incorrect multiaddresses. -pub(crate) fn convert_multiaddresses(addresses: Vec) -> Vec { +/// Helper function. Converts multiaddresses to a tuple with peer ID removing the peer Id suffix. +/// It logs incorrect multiaddresses. +pub fn strip_peer_id(addresses: Vec) -> Vec { addresses .into_iter() .filter_map(|multiaddr| { @@ -94,7 +129,7 @@ pub(crate) fn convert_multiaddresses(addresses: Vec) -> Vec = modified_multiaddr.pop().and_then(|protocol| { if let Protocol::P2p(peer_id) = protocol { - peer_id.try_into().ok() + Some(peer_id) } else { None } @@ -287,3 +322,6 @@ impl Drop for ResizableSemaphorePermit { } } } + +pub(crate) type HandlerFn = Arc; +pub(crate) type Handler = Bag, A>; diff --git a/crates/subspace-networking/src/utils/multihash.rs b/crates/subspace-networking/src/utils/multihash.rs index 20a5cc97927..95dbc3dfa36 100644 --- a/crates/subspace-networking/src/utils/multihash.rs +++ b/crates/subspace-networking/src/utils/multihash.rs @@ -1,9 +1,11 @@ //! Defines multihash codes for Subspace DSN. -use libp2p::multihash::Multihash; use std::error::Error; use subspace_core_primitives::PieceIndexHash; +/// Type alias for libp2p Multihash. Constant 64 was copied from libp2p protocols. +pub type Multihash = libp2p::multihash::Multihash<64>; + /// Start of Subspace Network multicodec namespace (+1000 to distinguish from future stable values): /// https://github.com/multiformats/multicodec/blob/master/table.csv const SUBSPACE_MULTICODEC_NAMESPACE_START: u64 = 0xb39910 + 1000; diff --git a/crates/subspace-networking/src/utils/piece_announcement.rs b/crates/subspace-networking/src/utils/piece_announcement.rs deleted file mode 100644 index 78d00e61926..00000000000 --- a/crates/subspace-networking/src/utils/piece_announcement.rs +++ /dev/null @@ -1,175 +0,0 @@ -//! Provides methods for piece publishing on DSN. - -use crate::node::Node; -use crate::utils::multihash::ToMultihash; -use crate::{PieceAnnouncementRequest, PieceAnnouncementResponse}; -use backoff::future::retry; -use backoff::ExponentialBackoff; -use futures::StreamExt; -use libp2p::multihash::Multihash; -use std::collections::HashSet; -use std::error::Error; -use std::time::Duration; -use subspace_core_primitives::PieceIndexHash; -use tracing::{debug, trace, warn}; - -const MAX_PEERS_TO_ACKNOWLEDGE: usize = 20; // Similar to Kademlia - -/// Defines initial duration between put_piece calls. -const PUT_PIECE_INITIAL_INTERVAL: Duration = Duration::from_secs(1); -/// Defines max duration between put_piece calls. -const PUT_PIECE_MAX_INTERVAL: Duration = Duration::from_secs(30); - -fn default_backoff() -> ExponentialBackoff { - ExponentialBackoff { - initial_interval: PUT_PIECE_INITIAL_INTERVAL, - max_interval: PUT_PIECE_MAX_INTERVAL, - // Try until we get a valid piece - max_elapsed_time: None, - ..ExponentialBackoff::default() - } -} - -/// Announce piece to the DSN with backoff policy. -pub async fn announce_single_piece_index_hash_with_backoff( - piece_index_hash: PieceIndexHash, - node: &Node, -) -> Result<(), Box> { - retry(default_backoff(), || { - announce_single_piece_index_hash(piece_index_hash, node) - }) - .await -} - -/// Announce piece to the DSN by its hash. -pub async fn announce_single_piece_index_hash( - piece_index_hash: PieceIndexHash, - node: &Node, -) -> Result<(), backoff::Error>> { - let key = piece_index_hash.to_multihash(); - - let local_announcing_result = node.start_local_announcing(key.into()).await; - match local_announcing_result { - Err(error) => { - debug!( - ?error, - ?piece_index_hash, - ?key, - "Local piece publishing returned an error" - ); - - return Err(backoff::Error::transient( - "Local piece publishing failed".into(), - )); - } - Ok(false) => { - debug!(?piece_index_hash, ?key, "Local piece publishing failed"); - - return Err(backoff::Error::transient( - "Local piece publishing was unsuccessful".into(), - )); - } - Ok(true) => { - trace!(?piece_index_hash, ?key, "Local piece publishing succeeded"); - } - }; - - let public_announce_result = announce_key(node, key).await; - match public_announce_result { - Err(error) => { - debug!( - ?error, - ?piece_index_hash, - ?key, - "Public piece publishing returned an error" - ); - - Err(backoff::Error::transient( - "Public piece publishing failed".into(), - )) - } - Ok(false) => { - debug!( - ?piece_index_hash, - ?key, - "Public piece publishing for a sector failed" - ); - - Err(backoff::Error::transient( - "Public piece publishing was unsuccessful".into(), - )) - } - Ok(true) => { - trace!( - ?piece_index_hash, - ?key, - "Public piece publishing for a sector succeeded" - ); - - Ok(()) - } - } -} - -/// Announce key using Kademlia `get_closest_peers` and custom requests. -async fn announce_key( - node: &Node, - key: Multihash, -) -> Result> { - let get_peers_result = node.get_closest_peers(key).await; - - let mut get_peers_stream = match get_peers_result { - Ok(get_peers_stream) => get_peers_stream, - Err(err) => { - warn!(?err, "get_closest_peers returned an error"); - - return Err(err.into()); - } - }; - - let mut contacted_peers = HashSet::new(); - let mut acknowledged_peers = HashSet::new(); - let external_addresses = node.external_addresses(); - while let Some(peer_id) = get_peers_stream.next().await { - trace!(?key, %peer_id, "get_closest_peers returned an item"); - - if contacted_peers.contains(&peer_id) { - continue; // skip duplicated PeerId - } - - contacted_peers.insert(peer_id); - - let request_result = node - .send_generic_request( - peer_id, - PieceAnnouncementRequest { - piece_index_hash: key, - addresses: external_addresses.clone(), - }, - ) - .await; - - match request_result { - Ok(PieceAnnouncementResponse::Success) => { - trace!( - %peer_id, - ?key, - "Piece announcement request succeeded." - ); - } - Err(error) => { - debug!(%peer_id, ?key, ?error, "Piece announcement request failed."); - } - } - - acknowledged_peers.insert(peer_id); - - // we hit the target peer number - if acknowledged_peers.len() >= MAX_PEERS_TO_ACKNOWLEDGE { - return Ok(true); - } - } - - // we publish the key to at least one peer - Ok(!acknowledged_peers.is_empty()) -} diff --git a/crates/subspace-networking/src/utils/piece_provider.rs b/crates/subspace-networking/src/utils/piece_provider.rs index 12d6c7554d6..df5ed96f10c 100644 --- a/crates/subspace-networking/src/utils/piece_provider.rs +++ b/crates/subspace-networking/src/utils/piece_provider.rs @@ -173,4 +173,38 @@ where }) .await } + + /// Get piece from a particular peer. + pub async fn get_piece_from_peer( + &self, + peer_id: PeerId, + piece_index: PieceIndex, + ) -> Option { + let piece_index_hash = piece_index.hash(); + + let request_result = self + .node + .send_generic_request(peer_id, PieceByHashRequest { piece_index_hash }) + .await; + + match request_result { + Ok(PieceByHashResponse { piece: Some(piece) }) => { + trace!(%peer_id, %piece_index, "Piece request succeeded."); + + if let Some(validator) = &self.piece_validator { + return validator.validate_piece(peer_id, piece_index, piece).await; + } else { + return Some(piece); + } + } + Ok(PieceByHashResponse { piece: None }) => { + debug!(%peer_id, %piece_index, "Piece request returned empty piece."); + } + Err(error) => { + debug!(%peer_id, %piece_index, ?error, "Piece request failed."); + } + } + + None + } } diff --git a/crates/subspace-networking/src/utils/unique_record_binary_heap.rs b/crates/subspace-networking/src/utils/unique_record_binary_heap.rs index 0d80f2b3001..45366df2e37 100644 --- a/crates/subspace-networking/src/utils/unique_record_binary_heap.rs +++ b/crates/subspace-networking/src/utils/unique_record_binary_heap.rs @@ -1,65 +1,103 @@ #[cfg(test)] mod tests; -use libp2p::kad::kbucket::Distance; +use crate::utils::multihash::ToMultihash; pub use libp2p::kad::record::Key; +use libp2p::kad::KBucketDistance; pub use libp2p::PeerId; use std::cmp::Ordering; use std::collections::BTreeSet; +use subspace_core_primitives::PieceIndex; -type KademliaBucketKey = libp2p::kad::kbucket::Key; +type KademliaBucketKey = libp2p::kad::KBucketKey; // Helper structure. It wraps Kademlia distance to a given peer for heap-metrics. #[derive(Debug, Clone)] -struct RecordHeapKey { - peer_distance: Distance, - key: KademliaBucketKey, +struct RecordHeapKey { + peer_distance: KBucketDistance, + key: K, } -impl RecordHeapKey { - fn peer_distance(&self) -> Distance { +impl RecordHeapKey +where + Key: From, + K: Clone, +{ + fn peer_distance(&self) -> KBucketDistance { self.peer_distance } - fn new(peer_key: &KademliaBucketKey, key: KademliaBucketKey) -> Self { - let peer_distance = key.distance(peer_key); + fn new(peer_key: &KademliaBucketKey, key: K) -> Self { + let peer_distance = KademliaBucketKey::new(Key::from(key.clone())).distance(peer_key); Self { peer_distance, key } } } -impl Eq for RecordHeapKey {} +impl Eq for RecordHeapKey +where + Key: From, + K: Clone, +{ +} -impl PartialEq for RecordHeapKey { +impl PartialEq for RecordHeapKey +where + Key: From, + K: Clone, +{ fn eq(&self, other: &Self) -> bool { self.peer_distance().eq(&other.peer_distance()) } } -impl PartialOrd for RecordHeapKey { +impl PartialOrd for RecordHeapKey +where + Key: From, + K: Clone, +{ fn partial_cmp(&self, other: &Self) -> Option { - self.peer_distance().partial_cmp(&other.peer_distance()) + Some(self.cmp(other)) } } -impl Ord for RecordHeapKey { +impl Ord for RecordHeapKey +where + Key: From, + K: Clone, +{ fn cmp(&self, other: &Self) -> Ordering { self.peer_distance().cmp(&other.peer_distance()) } } +/// Wrapper data structure that allows to work with keys as Kademlia keys, while not storing 32 +/// bytes if the key itself is smaller, while potentially trading a bit of runtime performance. +#[derive(Debug, Copy, Clone)] +pub struct KeyWrapper(pub T); + +impl From> for Key { + fn from(value: KeyWrapper) -> Self { + value.0.hash().to_multihash().into() + } +} + /// Limited-size max binary heap for Kademlia records' keys. /// /// The heap metrics depends on the Kademlia distance to the provided PeerId. /// It maintains limited size and evicts (pops) items when this limited is exceeded. /// Unique keys are only inserted once. #[derive(Clone, Debug)] -pub struct UniqueRecordBinaryHeap { +pub struct UniqueRecordBinaryHeap { peer_key: KademliaBucketKey, - set: BTreeSet, + set: BTreeSet>, limit: usize, } -impl UniqueRecordBinaryHeap { +impl UniqueRecordBinaryHeap +where + Key: From, + K: Clone, +{ /// Constructs a heap with given PeerId and size limit. pub fn new(peer_id: PeerId, limit: usize) -> Self { Self { @@ -69,24 +107,35 @@ impl UniqueRecordBinaryHeap { } } + /// Set limit to new value, decreasing to value lower than current size is not supported and + /// will be set to current size instead + pub fn set_limit(&mut self, limit: usize) { + self.limit = self.size().max(limit); + } + /// Returns heap-size pub fn size(&self) -> usize { self.set.len() } + /// Remove all contents, while keeping allocated capacity + pub fn clear(&mut self) { + self.set.clear(); + } + /// Insert a key in the heap evicting (popping) if the size limit is exceeded. /// /// If key doesn't pass [`UniqueRecordBinaryHeap::should_include_key`] check, it will be /// silently ignored. - pub fn insert(&mut self, key: Key) -> Option { - let key = RecordHeapKey::new(&self.peer_key, KademliaBucketKey::new(key)); + pub fn insert(&mut self, key: K) -> Option { + let key = RecordHeapKey::new(&self.peer_key, key); if !self.should_include_key_internal(&key) { return None; } let evicted = if self.is_limit_reached() { - self.set.pop_last().map(|key| key.key.into_preimage()) + self.set.pop_last().map(|key| key.key) } else { None }; @@ -97,19 +146,24 @@ impl UniqueRecordBinaryHeap { } /// Removes a key from the heap. - pub fn remove(&mut self, key: &Key) { - let key = RecordHeapKey::new(&self.peer_key, KademliaBucketKey::new(key.clone())); + pub fn remove(&mut self, key: K) { + let key = RecordHeapKey::new(&self.peer_key, key); self.set.remove(&key); } - /// Checks whether we include the key - pub fn should_include_key(&self, key: &Key) -> bool { - let new_key = RecordHeapKey::new(&self.peer_key, KademliaBucketKey::new(key.clone())); + /// Checks whether we include the key. + pub fn should_include_key(&self, key: K) -> bool { + let key = RecordHeapKey::new(&self.peer_key, key); + self.should_include_key_internal(&key) + } - self.should_include_key_internal(&new_key) + /// Checks whether the heap contains the given key. + pub fn contains_key(&self, key: K) -> bool { + let key = RecordHeapKey::new(&self.peer_key, key); + self.set.contains(&key) } - fn should_include_key_internal(&self, new_key: &RecordHeapKey) -> bool { + fn should_include_key_internal(&self, new_key: &RecordHeapKey) -> bool { if self.set.contains(new_key) { return false; } @@ -128,8 +182,8 @@ impl UniqueRecordBinaryHeap { } /// Iterator over all keys in arbitrary order - pub fn keys(&self) -> impl Iterator { - self.set.iter().map(|key| key.key.preimage()) + pub fn keys(&self) -> impl ExactSizeIterator + '_ { + self.set.iter().map(|key| &key.key) } fn is_limit_reached(&self) -> bool { diff --git a/crates/subspace-networking/src/utils/unique_record_binary_heap/tests.rs b/crates/subspace-networking/src/utils/unique_record_binary_heap/tests.rs index 3339aaffc19..7da88e956e3 100644 --- a/crates/subspace-networking/src/utils/unique_record_binary_heap/tests.rs +++ b/crates/subspace-networking/src/utils/unique_record_binary_heap/tests.rs @@ -1,13 +1,11 @@ +use crate::utils::multihash::Multihash; use crate::utils::unique_record_binary_heap::UniqueRecordBinaryHeap; use libp2p::kad::record::Key; -use libp2p::multihash::{Code, Multihash}; use libp2p::PeerId; #[test] fn binary_heap_insert_works() { - let peer_id = - PeerId::from_multihash(Multihash::wrap(Code::Identity.into(), [0u8].as_slice()).unwrap()) - .unwrap(); + let peer_id = PeerId::random(); let mut heap = UniqueRecordBinaryHeap::new(peer_id, 10); assert_eq!(heap.size(), 0); @@ -28,9 +26,7 @@ fn binary_heap_insert_works() { #[test] fn binary_heap_remove_works() { - let peer_id = - PeerId::from_multihash(Multihash::wrap(Code::Identity.into(), [0u8].as_slice()).unwrap()) - .unwrap(); + let peer_id = PeerId::random(); let mut heap = UniqueRecordBinaryHeap::new(peer_id, 10); let key1 = Key::from(vec![1]); @@ -39,18 +35,16 @@ fn binary_heap_remove_works() { heap.insert(key1.clone()); assert_eq!(heap.size(), 1); - heap.remove(&key2); + heap.remove(key2); assert_eq!(heap.size(), 1); - heap.remove(&key1); + heap.remove(key1); assert_eq!(heap.size(), 0); } #[test] fn binary_heap_limit_works() { - let peer_id = - PeerId::from_multihash(Multihash::wrap(Code::Identity.into(), [0u8].as_slice()).unwrap()) - .unwrap(); + let peer_id = PeerId::from_multihash(Multihash::wrap(0, [0u8].as_slice()).unwrap()).unwrap(); let mut heap = UniqueRecordBinaryHeap::new(peer_id, 1); let key1 = Key::from(vec![1]); @@ -67,18 +61,16 @@ fn binary_heap_limit_works() { #[test] fn binary_heap_eviction_works() { - type KademliaBucketKey = libp2p::kad::kbucket::Key; + type KademliaBucketKey = libp2p::kad::KBucketKey; - let peer_id = - PeerId::from_multihash(Multihash::wrap(Code::Identity.into(), [0u8].as_slice()).unwrap()) - .unwrap(); + let peer_id = PeerId::from_multihash(Multihash::wrap(0, [0u8].as_slice()).unwrap()).unwrap(); let mut heap = UniqueRecordBinaryHeap::new(peer_id, 1); let key1 = Key::from(vec![1]); let key2 = Key::from(vec![2]); heap.insert(key1.clone()); - let should_be_evicted = heap.should_include_key(&key2); + let should_be_evicted = heap.should_include_key(key2.clone()); let evicted = heap.insert(key2.clone()); assert!(evicted.is_some()); @@ -99,20 +91,18 @@ fn binary_heap_eviction_works() { #[test] fn binary_heap_should_include_key_works() { - let peer_id = - PeerId::from_multihash(Multihash::wrap(Code::Identity.into(), [2u8].as_slice()).unwrap()) - .unwrap(); + let peer_id = PeerId::from_multihash(Multihash::wrap(0, [2u8].as_slice()).unwrap()).unwrap(); let mut heap = UniqueRecordBinaryHeap::new(peer_id, 1); // Limit not reached let key1 = Key::from(vec![1]); - assert!(heap.should_include_key(&key1)); + assert!(heap.should_include_key(key1.clone())); // Limit reached and key is not "less" than top key heap.insert(key1.clone()); - assert!(!heap.should_include_key(&key1)); + assert!(!heap.should_include_key(key1)); // Limit reached and key is "less" than top key let key2 = Key::from(vec![2]); - assert!(heap.should_include_key(&key2)); + assert!(heap.should_include_key(key2)); } diff --git a/crates/subspace-node/Cargo.toml b/crates/subspace-node/Cargo.toml index e1bb79320b7..06100b7053e 100644 --- a/crates/subspace-node/Cargo.toml +++ b/crates/subspace-node/Cargo.toml @@ -23,40 +23,45 @@ targets = ["x86_64-unknown-linux-gnu"] bytesize = "1.2.0" clap = { version = "4.2.1", features = ["derive"] } cross-domain-message-gossip = { version = "0.1.0", path = "../../domains/client/cross-domain-message-gossip" } -core-evm-runtime = { version = "0.1.0", path = "../../domains/runtime/core-evm" } dirs = "5.0.1" -domain-client-executor = { version = "0.1.0", path = "../../domains/client/domain-executor" } +domain-client-operator = { version = "0.1.0", path = "../../domains/client/domain-operator" } domain-eth-service = { version = "0.1.0", path = "../../domains/client/eth-service" } domain-service = { version = "0.1.0", path = "../../domains/service" } domain-runtime-primitives = { version = "0.1.0", path = "../../domains/primitives/runtime" } -fp-evm = { version = "3.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } -frame-benchmarking = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -frame-benchmarking-cli = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +evm-domain-runtime = { version = "0.1.0", path = "../../domains/runtime/evm" } +fp-evm = { version = "3.0.0-dev", git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +frame-benchmarking = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +frame-benchmarking-cli = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } futures = "0.3.28" hex-literal = "0.4.0" log = "0.4.19" once_cell = "1.18.0" -parity-scale-codec = "3.4.0" -sc-cli = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +parity-scale-codec = "3.6.3" +sc-chain-spec = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-cli = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sc-consensus-subspace = { version = "0.1.0", path = "../sc-consensus-subspace" } sc-subspace-chain-specs = { version = "0.1.0", path = "../sc-subspace-chain-specs" } -sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-storage-monitor = { version = "0.1.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-tracing = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-proof-of-time = { version = "0.1.0", path = "../sc-proof-of-time" } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-storage-monitor = { version = "0.1.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-tracing = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } serde = "1.0.159" serde_json = "1.0.95" -sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../sp-domains" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } subspace-networking = { version = "0.1.0", path = "../subspace-networking" } @@ -64,12 +69,11 @@ subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-spac subspace-runtime = { version = "0.1.0", path = "../subspace-runtime" } subspace-runtime-primitives = { version = "0.1.0", path = "../subspace-runtime-primitives" } subspace-service = { version = "0.1.0", path = "../subspace-service" } -system-domain-runtime = { version = "0.1.0", path = "../../domains/runtime/system" } thiserror = "1.0.38" tokio = "1.28.2" [build-dependencies] -substrate-build-script-utils = { version = "3.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +substrate-build-script-utils = { version = "3.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["do-not-enforce-cost-of-storage"] @@ -80,6 +84,5 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-benchmarking-cli/runtime-benchmarks", "subspace-runtime/runtime-benchmarks", - "system-domain-runtime/runtime-benchmarks", - "core-evm-runtime/runtime-benchmarks", + "evm-domain-runtime/runtime-benchmarks", ] diff --git a/crates/subspace-node/README.md b/crates/subspace-node/README.md index f8a60877bc3..d053454dd1e 100644 --- a/crates/subspace-node/README.md +++ b/crates/subspace-node/README.md @@ -14,9 +14,9 @@ It is recommended to follow general farming instructions that explain how to run Rust toolchain is expected to be installed for anything in this repository to compile, but there are some extra dependencies for farmer specifically. -Prost library from libp2p dependency needs CMake: +Prost library from libp2p dependency needs CMake, also LLVM/Clang, `make` and `perl` (last for OpenSSL for `fc-db`) are necessary: ```bash -sudo apt-get install cmake +sudo apt-get install llvm clang cmake make perl ``` Then build the farmer using Cargo: diff --git a/crates/subspace-node/res/chain-spec-raw-devnet.json b/crates/subspace-node/res/chain-spec-raw-devnet.json index 08ecde26374..2eff41f1cf7 100644 --- a/crates/subspace-node/res/chain-spec-raw-devnet.json +++ b/crates/subspace-node/res/chain-spec-raw-devnet.json @@ -19,14 +19,14 @@ "tokenDecimals": 18, "tokenSymbol": "tSSC", "dsnBootstrapNodes": [ - "/dns/bootstrap-0.devnet.subspace.network/tcp/50000/p2p/12D3KooWJgLU8DmkXwBpQtHgSURFfJ4f2SyuNVBgVY96aDJsDWFK" + "/dns/bootstrap-0.devnet.subspace.network/tcp/30533/p2p/12D3KooWJgLU8DmkXwBpQtHgSURFfJ4f2SyuNVBgVY96aDJsDWFK" ] }, - "executionChainSpec": "{\n \"name\": \"Subspace Devnet System domain\",\n \"id\": \"subspace_devnet_system_domain\",\n \"chainType\": {\n \"Custom\": \"Testnet\"\n },\n \"bootNodes\": [],\n \"telemetryEndpoints\": null,\n \"protocolId\": \"subspace-devnet-execution\",\n \"properties\": {\n \"ss58Format\": 2254,\n \"tokenDecimals\": 18,\n \"tokenSymbol\": \"tSSC\"\n },\n \"codeSubstitutes\": {},\n \"genesis\": {\n \"raw\": {\n \"top\": {\n \"0x19bc6099459d33e46fffbc8449a0e701460b36981d9878fca7b4ad2657cdca112e8f7cee2531b6753849f0b9147bbda8ce0d0fb83c81a82d5d4c4bf64470e353\": \"0x14682f9dea76a4dd47172a118eb29b9cf9976df7ade12f95709a7cd2e3d81d6c000010632d5ec76b0500000000000000\",\n \"0x19bc6099459d33e46fffbc8449a0e7014e7b9012096b41c4eb3aaf947f6ea429\": \"0x0000\",\n \"0x19bc6099459d33e46fffbc8449a0e701661db2f443da00b5230d2fadadbedc44\": \"0x042e8f7cee2531b6753849f0b9147bbda8ce0d0fb83c81a82d5d4c4bf64470e353\",\n \"0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429\": \"0x0000\",\n \"0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710\": \"0x01\",\n \"0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc\": \"0x4545454545454545454545454545454545454545454545454545454545454545\",\n \"0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000\": \"0x4545454545454545454545454545454545454545454545454545454545454545\",\n \"0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439\": \"0x01\",\n \"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da924f740896a79c5c05c809396d4c7c6a1467842bfea753463beb37e055778761d6850093fc885a7422febafc39e429607\": \"0x00000000020000000100000000000000000000a1edccce1bc2d3000000000000000000000000000000000000000000000000a0dec5adc935360000000000000000000000000000000000000000000080\",\n \"0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da93ab039f243151a36f024ad1a14816d2e14682f9dea76a4dd47172a118eb29b9cf9976df7ade12f95709a7cd2e3d81d6c\": \"0x000000000100000001000000000000000000f03dc06e07b0bcd3000000000000000010632d5ec76b05000000000000000000000000000000000000000000000000000000000000000000000000000080\",\n \"0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8\": \"0x085873756273706163652d73797374656d2d646f6d61696e\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b0b41d0c7f7b4485bd7be1d66066b00ad5153cb1f00942ff401000000\": \"0x1f9c20fa76574c415987bbcb17533190ce87ae7afee33090243a048182ac02b0010000000000000001000000000000000000400013ffffffffffffffff13ffffffffffffffff000010632d5ec76b0500000000000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b0b41d0c7f7b4485bd7be1d66066b00ad9eb2dcce60f37a2702000000\": \"0x1f9c20fa76574c415987bbcb17533190ce87ae7afee33090243a048182ac02b0010000000000000001000000000000000000400013ffffffffffffffff13ffffffffffffffff000010632d5ec76b0500000000000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b0ccfc72cb4234bb4e1669a2f081868520e5ba0594e52062b467842bfea753463beb37e055778761d6850093fc885a7422febafc39e4296075153cb1f00942ff401000000\": \"0x0a\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b0ccfc72cb4234bb4e1669a2f081868520e5ba0594e52062b467842bfea753463beb37e055778761d6850093fc885a7422febafc39e4296079eb2dcce60f37a2702000000\": \"0x0a\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b33768ddd5596b1a2a00138ba04f73db05153cb1f00942ff4010000000e5ba0594e52062b467842bfea753463beb37e055778761d6850093fc885a7422febafc39e429607\": \"0x0000a0dec5adc9353600000000000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b33768ddd5596b1a2a00138ba04f73db09eb2dcce60f37a27020000000e5ba0594e52062b467842bfea753463beb37e055778761d6850093fc885a7422febafc39e429607\": \"0x0000a0dec5adc9353600000000000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b4b1c668a973afd8ca7a91ca62ce42f465153cb1f00942ff401000000\": \"0x00000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b4b1c668a973afd8ca7a91ca62ce42f469eb2dcce60f37a2702000000\": \"0x00000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b4e7b9012096b41c4eb3aaf947f6ea429\": \"0x0000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b4fa095bfdb06dcee7ffb6bcd5d73615b5153cb1f00942ff401000000\": \"0x000010632d5ec76b0500000000000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1b4fa095bfdb06dcee7ffb6bcd5d73615b9eb2dcce60f37a2702000000\": \"0x000010632d5ec76b0500000000000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1bb08109d3cf5cbd6f8beb07172cc16877\": \"0x03000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1bb4af397218de7539c859a76de55a689f5153cb1f00942ff4010000000e5ba0594e52062b467842bfea753463beb37e055778761d6850093fc885a7422febafc39e429607\": \"0x000010632d5ec76b0500000000000000\",\n \"0x32214eaa0b8523eaebb7f83e73660c1bb4af397218de7539c859a76de55a689f9eb2dcce60f37a27020000000e5ba0594e52062b467842bfea753463beb37e055778761d6850093fc885a7422febafc39e429607\": \"0x000010632d5ec76b0500000000000000\",\n \"0x3a636f6465\": \"0x52bc537646db8e0528b52ffd0058543305aecfc65b1553106868947468c8b20bf1ab3c8d64d008009a82307dccd1967581ec7845b6c950d08e4065109e090ffc1a96214d8045f810da5df3dcad93a829019592b739886da28501adf6c07f445a2384904608d97bcb2d0324169d141815b0b7cde13151a5b7b7b7d3e654b6d2d74b741e7e151e357cfcea3b42246c0c4fbbcd8e170fdf05295d7e76414ae7f7c492cfbcf6ad977dbdedeb9dbe6d376925eaf9d2574ff4248915083e808493239a1831241404c4648992229220a947881842889f2080f080919aa34fcf60e06567d6dc4324ded97e1d46c13bbc73fad5e9a0d10a5bbb77f8d537cca2ce7598eff2bc441dee5d0e1c37706e6c6cc0d08aaaa1999189817979a1d53b993a6ed34a1dad19764d19b9c22ed10a7f3ae4228b3c31bf0e81f0832db4f0410ff6c7ca9ca3359b39539a9bb2d2694a873cd8411658e8200738307dc67478851555dcc00654d460f7c7365fe6dba8c38753d0408a2866200328f6c7ee8fedeb311f448a3ad7b32a5e858f87489167554c6b66a2d5539568457585487d3deb826897ef89dab7de773304f63cecf98c8a375f2195bebe1d52814ef0cef675ee7cd843318bcb163492cad092a58554c5ca1596d111a4c2650b1a496568c9b2ad1c7ca49e7915d5a5eff2acea04fbf4ed7c4e147a253a346db66d3b8d56a2d65efaea26f5763e9a8956276d7ae9ab176b22c95652643152976e5361ab4bb72995de134bdf76d307e4a4b9d2b56fcc95beedb0eb01eb8ed6273daf7d405873b4126ddbf641aff4ed7c4aefe1edd3e8506c21da12a860020f445da24936a9e76337445b02154be8f9cd26b3c2c3be9d7d763e19851e76d9f140d4d837c8651feced309ab5c09befe1ace7d94aaf8e2792a863982f7ce09d7a33786776dd31e4e52ff9bee4abd7dbde9b47f5f04ecd76e09dea15e19deb402eb0465fdf00efc8bee296d1570e7d2d11fa92efe11612525fd7755dd737e7a248760ba7b12d0e5e7ccde4b71582355af2254b967b29bf3952082c7a5b18036f5b517c7192971fedf985903b1e88b8e8ce1f7cf721611df890e3f7f0c69cfc606f1b73b0d321bbf6edabda9170dfbef157b7efc674d9b1b77bc0a94b9bce1ff7764220ab4def61fe606fdcf1e7bd38b33cab8ae74f8653f1dbf278dbcaa28cd6fae5db3639d8f92cbf60dfed71fa3c7fdd4f5fe597be5d10fecb7bf8667f74b4c2e6c7731784efbd277adfcd107e777e4771b647fccb7733446bbed64c6f8060979e02c68b3c3074a34e7c8c3a3583d791f0b757fe7e7ecb3a1e88b8d82057ea7480dfb6ed3dbc65dd0e3dbdcba39638d80581e7f37b18eb84f0b76f17043610ecd248b6ed11cf6d8ff8ed767b4408034fb29468d3e337edabb2b9731764bf60b1da448380760b8bd54330ed7db7871634c4b5f7d3b7eb8189f6d5d8dc4f5f10d0029ab707f7a1ab4fdf20a77d959bbbe90b3a7de86aefdb0d21d2dd7bd8fb807274f7d307b48086db83fb0639d30704bb7477edabb0b98eeef2e0a8f69ed8c37bfeb64b5f10ececabf07bee965f30ea71eaa27cda93cac07e02894e7c7db111c083f7b66dbdce676bb6cda9704bf363e53e0fa7616ffb79361af6c642404213767a5630854de174fc707a8b9c95d5d92b194fcf0a5aabb3bdfba3670559b6c736b4d1f1b3d1dbe48eba6e12ec7cb0333c2c8bc7af9b841dc183679bcc0a0f1ef576dda4669a59e16d526f33dcb2c5b691a728a3f9cbe77bfc91a7e8f41c5fef4553e06b2e80f8a2efdd037054e4297aa12b1b3fbd7ce645a69fbedfc853f4d115cc3d9b17fddbf759e42962bae2135d4979a62b7e26e914f8953c8e7b2f9aa12b1a9adba0ab99bf7ca7c939cd5736cefde5a8efbdc853a4d195f618bfd1d0157da6e3353c66a7f92a9e86ae30ec4c57daf92b9a6f2fba6e4357323287a1abd34b7455fab77df57da3abd3e9abed378f613e475718768dae4e7475e3daf974fe8a3bd31516f315769deff88abf83ae64643e435733cfb2e3a02b191c9fc966bee3abec3be80a47e984e3ab520e9d928aa1ab98cfccfc266666865e87a61dc70d4ddbb4d2374363c33b71164b9a8d93dc66b0970fe3a2a4f15ea2fc323eb196cd6c186783c686fc5e3c4c2b954e1b67331ec7364a1c8d974519b5970f9b396133342759830dbcc5976ffb0dde0ead861a6268b6534947e7ab781d9d920d1bf429964f7136d8f095761b6cf8b2ece5f43a9c761d2c95faea7baa86947c99e1d3db40e3dd86dff0958ddfa0a3f3d5769d1d3abfe1ab1256430ddb77fa1436f354aca1861a6cf82abb0d7455430ddee937ecd871e32bee374aa7d7c1f11b3a6cdc709daf68ae934a01e03be82a751d3baef395761d5f31cd794c4ca4397d0d376e5c070e1cbff90d1dbff195f71bf2359cc7572fe7017de0fc86af5e7e03ccb98e1bcee32b1bd7f195bc4e0a07871e47e7385f7dc7815f6dc7f98e9b9bebc0415737e8eac675fc06c76fbee27e03bfc2bee3a9aff82908801abeca5e035d01a08653ba02c071e078eaabd3e957a5f3a02b1b6c780e5dddd0d5cd63628e43573636bfa12b9cc7c4fce6ab99dfd095cdcd6dbeca39477b74d0293ee80a06e637e8ca86ae6c7ee31c77fa15a52b181da75fc17ca34c56075efb0d5f69d4c9eac0df405736d0295067fb0ebad2b4cbd095ccb71ddfbe2ad10b6c74a56dc7a12bed5ce9dc5738ffa80f337487d5814fd1550d3307005d51baa2dff13d87ae74e438a5abd542943210a10b0cc2800223d58784259a388219bce0822224a88abef7449dfdeaa32b1b744f37eaec73d0479d3d0dcd56071ec70d1bc7a1ab9b9adbd01591163ad882963268408511b450d9207a41089c70822e9a5086329e50d9f8ca065dbd500f45b3a8b3afa11b7504406baaf71e457d75a244ac0e3c0d5dcdd0295055f47219baf21e43a7f850159d0e43572fdd3dba2292620a344c21051735b8f005d5699fb045073338c10bb8745106d5e9ab135d65d48789a2a2cebea31b7502406b0ebd679a0347571b9d925215cd6b740584075b74e10a3594b0c506aa129d7255510e2c63c8820b274831c3165445fcecab8cae30fad5815f5dd48b3afb4937eaf4a0d547ef254dad0e7ca44556077e4f149fd8c03dd6d8e0e1a7e3d54c365f66190fb16d6fce06e12bd70c2177ab9b5c1dfc6277dcfe088249dd84336dccc14f36b7a581b06e02d371a626d7697f044156032da0a110c9623514e2b138c8edfea8b0e36bf0749034db6ec876f1580adb76c63b951fbf7cf89ae3f1630f7c2491669cda4b4e2d15b2ed3d791fbc53b31c78a77ae79d791c7847f6c48202a49ec7e11deed995ebeaa3e797795855b9aea89ef778873f2fc33bf1f319efece739de819fdf9c49916c0b46d9e037a7fae024a7a0e41ea40e17adefeb1977cb2f9253b40ec586d7eef1ce866d58a9446be9da4b58c63bd8e339de293d7ec33ed85be95b4e2da7b8c34e076ec9298e56eedab16f9bfb866297be415e184dd8b7bd7ddb5ae9cb4135fc6e8f7854f51ad27a7d3e7e8b105edff602e0b36f6836fc763e32cddf7663ce495fdfaf66b15b7e81df64b7f285e3d439158f1d8753580ff7c4fde45761efaf6f28f61e7e19a7f8b0f359ca4dea718a330f8777f6f139bcb38de29d777c6a7fc48edf9ca8c139836d73aa8fe6d9a8b337bc6983b72d25d6e86d293146d754f30bd0db5202a9b9f3d1f15a2c5657aef91e7c966de459d6a95ec357afabc7e72feff0ce3c3fe3ce2752e8cdc38e07a29edf2037bfedf8c1de6037bfcd6f0802f9484ec90bf17a1e763b6ccf6fe7b39caa5c6fdb5db412f5f5f8d56cc6afcabedec35bfc6a033a8c56278d3d7e755b1d3fbf3a77f0e102458860d2f1cba9eaa4e3e3fcb6b10f2876e9d2854bcfc7af026979f9f96d6fd703d6f1fa80b09eb4c28e140876e9d2a54b57a28e97df720a52c92978be60f402738c30f27b38321f5e9e99399e2384cf1ad29b21f0f230d20a2384626c358bdf4bdee1efb7f8cded0d72f1bb9a3fd8f0ab4834fcb690d95441d0307ef0db09990ddfc3f193cddf36114322dbf20e3ced6ef0831e7f3b2defc0de6f59ef23b75ebc4d7685271f0f1f3b1f48a1c78f1f773e926ecc49ded9de6f9283dd763c1035f7301184b007dbe6d477fcb639bc6d6f78cba99a35ec823861b1584a34fcc6dcf20ebfca1df8fd76cba9f81e869fe454fc0eaf7a1dcf978fdf6478673b7e839cc73bcba97dbc0cefc08e47f10e7cfc763ef26b92a38588b2e667cdf466085f9e2fe9106c48975355f67e3b21f04c2b1fbe877b787322434884a386db10c2cbf4563df86503ec77dbf68607bfd8b64378356bbec73bf07cd4fe80cdcf7867b1a0c089e673bcb3ad2788d07c19ded9f337872992f7ea20825001dbdedb160b8bae59ef3dde592c2870a2f719ef6c0b4b94de73bc037bbfccb3aa2ad3fbcd598ae4bd3a88205cc0b63abcea357c8a772ad7f0f028dea9a98687e7c13bb0e13dded99612ac8697e11d6ef8651ea8aa380dcff1ce1e7e732045e2a35707118412d81687b75f6c5b6fbf5786b4801b68a1c52844332214ae29970864168904a9457a21bb98698049d7082e125c45b3cb5c63a2415e91439044e024cec260c8227014a411a4185208d70b2e16cc315c4b5c50ae105c4d5c5a2e15c82c2e262e1f5c47b8b6b88c008d20147499e03ac17574a5e042c1b502f9853c02f7e08a722971195d5264106418128c5845a4419c22ce20ca20b220ae20a620aa201e4513c4a218253611a744a3b8048b81c3c05b7e820082b7c05ab019dc0476028f11a5603138081c067f81750075c058b0156c02c80592018e015a019e01a7009f00a9c048802c8055a0129045f42409101c21d2010e402b1e3052640319b000acc1007c5c5a5caca11e3c6e20e28a02ab00d2e0e28111970e2e225c5f5c517009b80cf30c930c9c84b9855b30b9c04c9869300ce615588d698579c6ac02ff6042613e6196c1529864f0142613a613a619b309ec831985298549853985b98439468c62a231b1309360979985a985a984990486c244023f81c9985a60173008f308d3081106b105b3083106930811ca1cc2140233c1669841e0238632b1cc16acc2ecc114635e81516014cc2e669619c604834730bd985c4c20cc1fcc2da616d307cc9a3c983b98594c2ca60e660e980c1307d30a17615e31ad9855cc1b4c1b4c2a660d669539c5a4c194624631673065109d98504ca4f904a33163c0429830984ecc174c17cc164c2a930573055305b38999827902c6c13c9a2698259824984ccc114c11cc29d3682e31a5cca21965429921984a4c96ec22d320d120d7906790669065905c2419e418388a14835443864182417e416e915e601ec82e482ec82d482dc82c48342416e415e419ac4556814fc03b905490539049520a320a6c25d6205e01b100bb00b7c02fc8274827c413c826f016920c0984c804b98564228e118510a1883a88378836885430178c85bb441444293c06e6c255e02b180b7c05b6029fc15fc42aac042e839f602fe6177c04360277c12d06023bc131e017401f4424be12a9c4279804ec0216018381a7b0112fc152b8884300a980618060805a805e805c805b80598068442ba019100a500abc04480664427c417401fc027a01b1c016e402fe0062016500a140c209a7c16489122168d4c1067be1358412c71f21231e20c2c4c80f1144886c3006a1e48708116de14f120f181952628410448680f8093a128492234488d8c0b8d82544942c3912c46408889fea811e942c3952819f201f70c0809003fbc10a151184932194fc0809fd3cc0066c8b0d00a6c50691c4882544080100f3c18f9092254c847e82883859e20125476cc0ae3859e281212396506c072bf433841121a19f228808192112f493836581836121f4e3811b980e8c1411744408254b8020828491243f413ab01c6c10478804818491243f1290c170b003c0acac501146828c302112f4d324c912a19f243d302b562849104a8cf000919fa0254014f1332484c40478b02a3608254610d1c16eb0424118612448088a51b138b01aec901047828228c288228e383152449521a19f20922cd1814db1413f1e28c20825448230f243c487d160891862f213049121941c51624410132242434c8efc00f113948349b148041929e24810131b2c0a143683fd01c248d01011254b8efc24191afa99c00d4c0648087124688910448490f84192000c8a4562e8480a43da21208c081a1252b204081bb0270880c5608784880c092d61428488a12347102900068315fa19327224889f22827e86941c39e6c406fd2819e288109121208c040d39f9095ac20025478c14b1a40138d80b88181a42c94f1217eccf8f1044960c1119226288233f47e8602d58a124478c0cfd0441e4e747881a3016ec1221941c218244d08f1140448e30e921253f452061c487632bd81f20942c5142c40891234cfa0708254b2030a4c488254000d137301504b104889f207260295821247e9010111242e2678892254784847e26f06128d8238e30e9a01f24414b2cd0c3879d607f868c047124899126447e8cf83122023f04f133c410467eb8013b5a212440fc100104132b34a4e427e8870825478e8d40c911216eb0290bc41121254782869cfc104122091326468804fd0491e488112a24402c49a2c2c18c56c8065b628d10c1c1a46c11448c0c1909c2c8d0cf035eb0281f3892c4c891a1234a8ecc5c5e58244000f1e3e407e6eac2062d6100578117092c11400c19f100919b08ccf8e0f50003811562c99220264486f80012223f43463029620910340e5826460cfd081109e26748c888a02122411859920486013ba4e4a788213e8084c89221221e5892c403340a789102fb620ba45ea26d5b2c5643a268e38a58442c201388490923a594373012e606464af9825dd7b5c52b0059841033f10b06b378cd5c10c22d5e598c3042b8d77531b3cc3218e172bcaeeb8a57646628f9baae0b6e98372384f382704e38e79c70423867841916638418841884d00421e49863e4dd129b7ac0dd0b2e84d286e10577315e182f181942e66ce12e0fb8bb716106318841e6608437401b208c11d240b8104678c518e315218c3242a81321a4b952702164c8104619c8712184116610466c2307e115e12e738c1032b364c85b03840b17eef22ebc20330600668e3b767979774bcc70771972dc08215c8e31b28c8b61f1827121c7dd65e665e6dd5dc6ae12739c8130466ee315e1c208172ec416c618217306f992cc3518161942ede25893a3837e355796652ccf59263399314b664d323347969a86f276395e5769bbb408e18bf6b2a698036a304208a1d462bce0865dd06413e3b65d9217e260969884105e7119c2d2ee6648990c22cc3212414b8af829e23a79c00821224a8e18210208218458a2b303183212f4a3e467881d3f44e0c408316404912125478298dc1840103f3a6c2c01843812f4d384c80106600003102048c75c02fc0809fd04312962091044827e9a2c01e227888811a12080f8213200243b06200013207e84882c1962824410103ca8207e827e82085a4264c70004f83912346483b70458b224c8e684c40f1222434e7e94e0101a123ae2e40767c7000428e2c89012238288002174a4088a0408231e48926449900d478a28620910a99292254786803022a4c448d01091a1202343423510e0078991241ef869081b324128f961c2c4080ecd104b92d89849f2d3e427091127468a2032849223430cb124498e1c0830001c384b00274784f809624265867e846cc40419f9490204919f218c042d1912bae970d821e264c91143448650728408212344dcc88ac0d144c94fdc1d0011254b8e0805fd3421f2f313240491a025434680589224891122434e7e709a28f989373234784bd913a2389fc8274f8820514d11224814538408129d8a1041a2adc812113d894596282bb24f889e1071912790e8c9132259649f301156649f3cd922fbe40917d9274f88661122f80412c1224fe01358840812c127b0c83e794244248b2cd15584086e112248048926912cf284082e1111512c420489b8c812c122028851e0eec222848c6c06f0b6dff0effc977b38df6ef836492b84a9863e1a5e493435cfa4f0e0d571f2fb06b91b3ed85f00be0fd5df6395c823002aaf0480663d28ad7225c92b1da75d68449e55d5d0c06f73d2dce10721841042082184104208218410420821841042f89d831fdc4e5221dcdb7b187edf653a9fefdbf76d8f89d96ef8b6af2e571ad0b0c619cc50868b0cd7182e315c6a5c61b8c0707de1f2c2d5858b0b571ad7162e2d5c59b8b070052b9c51052a4c617fecfed88c0aaf42a3a4ec4afabeac7bbc9ae3bc422323359ae82aaf5c66f04e17a4e6f01bfc36a4ee4ee9bfafbebfffabef3f478eef6a5e45a5aea4a8e343dfd0fdfa4c37a4e6ddaf24ed4ada7125e55c493aae247925510de6e8383353b1d2373cc607a6c254980a53f964ba2034c79179286874c35fba2135af4456babb24031a451e1ebf2e99b0843194900424d4406bd600a04602f80e5a51bd02f88e608422106108620821009f0c4382218320bf905ec82e2416ee3d3ec905107eb085163ed81f3dd81fbb3f565ef9c569305d109adff86506efd8f04be7354bbd7a3500e0f52d77bca624ad4f92fa065abbe3dceb86d4dc065a898ebafba91bd243d72749dd3d56b9ae436b96a2d5ab815654ce0140eb757c07ad29cc085e8e577925f35039b4beabbca283d654d37cdbf47bf9f7c9fc1fcc737ca7771f6c358eefc65761473378e77d1d7e6fa326708c9cc08147ed0f1bfba34966b33f9a7837fba309aab7e31c6777b6710ebfcc0a2fc86b789c6b9d0f0e855ecd613a1e88bae65719bc53439340a49513deb9f975c8e21dadf3b9494204efd8bcd4f9d87cb3b1f9b4ed3131db37c8dd7c59db7c5913117932d57526bcb39b8d0ff5b1139c3ab69e9ca115f6fcc5e335ebf1ea05e04a9a977900503d3c1edfc748321f539999f9764166626abe91475e893ad7b978986bdf163f78c4a9eb301f34e2d4f5215ecc2b34ea2b26e657224fac1275ae6735b4661e0d9d34011e0f9c5a80d7fdace65e6395ed92bb3cd6f9c84bfe4ae21d49af7333a7c32fbb0c23c9ce47061af10eccaf43267807fb7578c43bdbb1f381f90603f369d8616030ec3dfcc1cefaf2985f5e9827b7decb67e7c34e70f4f8e5b0f379919c8ca68f9de068f5a1b96b5f6524ded96885bdfdaada4ff0dbe9632a9cbafe83b7bd32151dd8897a25313bd1e29400b60fb6f6c1a3ee3eeeab3e74121f3e9a61331576027ea747d9ea2a7dfab64d1fdc825357ab2f0178fc2aaf64b0b7c8bd7c597bdff6f6967dd247cbde24977d25aeb75f68f00e462b6cecdcebaabb2ff3f07847ebf62cfb26e061af57525fdf2e6e3ded57e7b3bdf441a2c60ebfca35e414849f46af244e5ddfbe2ec87506a7ae63ef899fd7da579db0583df4926d932b7db2b7d301621fec2b8977b25fbfcec09e5d320f8f53e8f9e81ee6f1c92d58e7a2f20aa7aecb2bd81600f00e960d5e730b4ecdd9ea39ad706a4e2c7ace28383567959e930aa7e674a2e7648253731ef55479f1d7f73e9eacb18c9e56b872969e55a2e14d382f544f2c383583228556282ace794d56d462c38e7a7b5b4fb6ac601145152a4ef47531c1a9eb3aeaeb3dbcfb831f85533a6c6351b6c7f5ed22c5589cbab8ca32ae2fe8b505a7ae578cd5d77dbcf932e01679850057ae5cc1c1282d8304e8ebf1924ae4995d80138dc8c3419debfc8aca689d69e84b52c1689d63e84b52813898561c288d56540669cda04ef5ba727d3dd2ea495a65d789465fd744833770c9ed74800d14aff177014e5d971fdcc2a9eb02f0640edbda2cab25c60ce36d83dc113090076e6962c49050101093254a8a4882a41e216208217e8200c203468a10e9000736a0810c60e002fb636d685f5f68435fcfa6c86ae0f5301f6eb93c0c6ee9eb17b8b0238f8a6dbd6c3de9659ce23805a103b68bd5f21bb769a50ce356e4e1a8d41275e465a6791906a115a925f352338a2a549c60e248b23825659496510d4ec9c8a525b4d2f240bc1ab558598027adb4bc8f9696975d25b75a36d141b2abd4d2f2fc799c929f1ca724f7c1ded6c3e194fcf630ec7c509c921780c719a71ae0c15facc87309a334faba08cc6878f86d1fe06d4b0444e878f9113021823564abb3d2576197b06b9f5f46ba822b3686571929cbb2ef78f34c2bf77df6abebe17a84ef8971683676593aecd279f0b623918faf49f8484a87af5c49887c3c0fde46876063bf3eafd121d8b2449bc086dfd8f9c073e713bfdd10d8f01945225b310b131287869d6a981d1ed5109e2e2b7d427dbd1a9af7f0f20e8c9155cc7c3b3cc73bdcb1c363a8de50afd951471d3bd6f96035af19ad39f7ab166924d72bfcf5ebdb67e7b351e8412abb1eb02febedcb9ae3cb0f7ebd4d3e3ee0e5db975d9184911a52258cd43589a44672fae9f27c09691246ea9797980f494df2644b2b8147ddc5c31efeb65e09e6c864b2b1c9b4f0e051cb6fa68dd624f0a8b7c79bb8c8999e6c89493bdeb36719873d5b81571969ca4dc22cf254613a0fde767ecd619b5ebae9f136442d0fe5b7eaa4c4ba92a69668c586c278f901396998d7276dfa80b086f97642187ef1b3f389cf4e4dd9d7f4ed5362fa4c911367443436284e408902ca0da060b1c5ea6caae197ea0d7250be8042042863403103ca1950d280a2c6a6341c1a7e38f4089c889de9b0d301f611d3b71362facc378de38fe5c7f0e3ed509c1369347f5b6363cee63837706c3736be3862fefddba8738356af7168d7434cbaa135ebed363668f57abb0caab7eda863db03e037da243e6808f6a46209542ca19b40eeed40b10544b8820eba09f7468386646f075a2e5bc4c004dd44f646e5873a04cad115f6107ceeab44cda86cdbbeace137349be1b703d9d1705b9df51a5cba66fb797c58a44696459e7806c7347abe7a3d8bced8ce3d0a1a5d6352951bc7753ef0db6db412f5461ff38d3cdfb1733086d68c6618addee7b5a415d51faaa57c8eaf27caafe6f0ab45bad67cd36abeebf2a5ce477e931ff4a0fc36caa7f9ba8e07a286b4eb86e4e8d2a54bf3b71a4e7e40fa06abb358645b785fa088f03156674960868f66129cb1a9ed1290861f905e0152dfd08b650647e86d83dd7555e19db991278b3af390d6a1b9f17755e1d4fcf55d489c9a1fe2f1eb85a4430cad199749e1a9000da985c56249a19adfd6bba250019715b0566074b43a2a581dfeb6a3b77bc0ccb9f32172893a3e6cd4d954db4900aa604fe48f1b5e485714cc73168b1502d5fc230f23a5625e7df4b597d757d633f35033df101f76d6f95c147adb6a468a3c3169cad09ac5d0ea3523c12419b71863d2901ccd42ae0f758b04591ae6ab4444bd5d9fdc4e5224f0f22f1f7f95913ac7a9f4f61c5f4c8a3af3d816bc1a9320bd818f4df4b6a28c7143af174ca8d131299ec13cf188c562b54035ef022aec0224764115768195edb12d254a6fab688cae1752cf03a0b7557403d831773e1817bc78d89a9bd432be9cbe7d35ebedea7c4edf4e1ff418c6304a0083f67e629a8491dafba91b12c3288113ed79d87bf8f465bd41eee5dbf6b69348b6f34d5f96bdebb297b8d7ac377ab3dd47179338352f000fbec6a48d0af161fab6bbefc996e6be1ad1e859fa56faa0b7719407a2deb49bba2158099cb8e2a3d1aac336131fcda52febecdb9e9d1022a4ae1068b5a44a36a9254db249db09f1a1ab50172dcde79debf30dd8a209deb9a8121fcd34495f566c584717c829661adca03936f3230a85132f23a7c3d03c8bc51a9a4dd85688b7ad2967f4fc76da1ca8ca208f0fa8c38750472ef1017998441d7ea435878592665328a1925fa2a4882448ea11228610e22708203c60a408910e7060031ac800062e60810a50e087094820023eec8fcd6ae0d5d59251e131995b20df87c8b3aa6c5559dcb87175789d8f145ef20e92496f84ccc74f1ae5c741eefa56b51d3c928c9160db2fc29c9e65cffab439bca37d9fc33bdef729dee9bee7c13b2fdffbe09dd3f738f04ee9fb1c78c7f43d909e06f04ef6fd0ebc33bfe78177b0ef7df8e102cc931db1582c2caadd739f9d0f47a1075180d4708b1fccb318b3d7f8ecd9e5678479f67930302618185a8b3412d32bcc4d37fd7409438726c7a9acb49ccadec32f5f85dd64f6e90d54a44fb41639798f9d8f47a177a2b0ebe12c16abbbedac4bdff6e9cbdad4bdf454975e331f5d3a47ab97439768c6a9ec1bd5bee55446afafc2ce6e935d91041e754695c0a3ae4fb63492d24b9fe7973ec929d8a54b17253aa349e051636fc0164d706a7b7b7ed90bbc78c03bf2d7f7dbf56dcb2f6b08b7e5e657df17adb0af43382fbfed0edeb6a030d1367a5b2148ea2de3d693cf3a1ff9abf3891f8a537c1dbceb15e583070edce980c329fef514ecf9bd630ecd4f459e8ce5f938cce3b158ac282a96b2a25a5249a10759ddc31bec7c3c4e719c62194ef99043d4e1205ecda19979248b65c462a9b88926945d78bc73da6f4e8d47f2fb6deff298debd66dcabb7bda2b4d7f77e97a7f49aea35516669f45d215289d6546346f05811a3d57baa2bb33ca806a722174ec38c242d6374f4e0179c8a30cb7af33671fe3a9f3f88c69679ee7c26ec74386b3edec7e3578894712a7eb2015e3cba882e9662981245d7cf7fb5c06febf1b7f36900a7e4a7c37603b6c7ece1d4fc760e5e7d4f36a3e5c768f90478f36735fc023cfe59bd9f875f76c5b5a021451546eaf86566fe5e42083f84caa4941f427173ce0fa1bcebba3e8492c1300cfb1e9565d9878eb33b41414d505d7a93ac4b0f1aca1a28a681d5a50fa1ba442113cf3e68f4c1289c8abf3ec8e254fcfc569f134ec5c36fe86352611253893cdae361524cea1823ab638c1783071bbeee16ed156ae978a11cb66bf3526801cd51a248c954504e5c5852502aed51a4a4541a8d2225aab86b9782001547abe06f5f94284639a8342aa5a4d20e25a681a532caa1d21e050ab6068ba5323aa9b443397161b1582a2950a55178147520ab25ad4c777b545846c7435a21958ebba5633c11fb833fa6400b687e05ea69be18bc79f8f8479e2a266d7235bf1bb2802b51673bb6b22c51a7a7085aa2ceb6fc322bbcc5d2db35c548bd3a9e44228c2f316cdbdeb68ca274c6d2d2192ba9b7fd764bcbaf37bf4449114990d4235bda6c7708217e8200c20346887480031bd0400630b0db2d50010afc30010944209bc2cba8f0e42f4b3ef4cccb471d8954aac2b292b1aef4ac19abd5336365e979cc085e2c65d7b67ab330ad44cdbfbefabeb6d74c2b7d97c787a8239fd17a1d7bec82642ca4bebe001f220f777905240008027e1c40a3d53bfdf4f1ec18008702106000260104a0078f1b6cd091dd57030076e4e8a0dff7c7b63cf73deac8ebf0cf24aa7be2b5841a73893556677e17b557aba796dd92712905dbe614e9496b919e326af3f01c4d2ffd7fe431d18e72b47abd5154675278fc12adf3cbb127ce0feb9224a3c6024f46ad44ebbbf4d2e165cdb057ef7a45b5a6d15afa469e9ea8c318a5990d3c9e2c39f21f79a08a9f62fe26957826e1fa7ad8125ff4193d3f9d88d267b536c6c5ed6e4acba4d032eeb2283c26119ab48c514ca2cef5d89de4b6418ebf26b0f9f0089a4ecf68e05578b449b145763e40b0f9ac864791e782a67878a578609e180a8f608a2786ee19151e99986cbb656ee9b6f4f58c059ecce433a96567a9ae432a2793e9f4d5f7e9f2ab6ff96733f052cfa4f02e2de3b22deb32293cf9d30e9796cd2e88e9f4956efab65391473b0cadd90bad9e97eaeb990dbcba59b48cb3230578d84b59cd3aab5e67afa8cee051e4a1a13b449debb49339c5d0ed59149ef7f8ba59be655c96795e45f5d23abb1ece6aad48950b449debd937ea74df4e023b441d9deb1ead7cf91db213ad9e29cb5177c41d6d477d3d7641b4cff7442dcbb252961d7b4fcc300ae111c4914201bc6d4939a3b715e58ce69dedd9449fd5315874769a283a3b7f89282d458dce6efa7e596fa7f9f5aeaf57fa7a1a3c9acfa8783db9c22acdf406f0ceeab3ba743e3cfc76e0943c7f5a5a7ea3a11536cdb1afbeb1735f7d7387f9ea1be6dbcbcbcbcb0ce419782fdc33293cecf533fcaceb213b4d4da432b4a2606620d370df7698ef3a0dad70e3388e4399bc675278f1f530dfc82353e1b147981eb2730c9f5eb39a57af5f645e51fdf28d3c8f3af32fb40ecd8e79e95837e4acee1ef355a2eefec803f313ada13214a607454d5ef71edeb6d32163b11ad2fa86ef79792685577adda4170578dab76fdb764272746998775f850dc3ccfc9a55afa2babee7331b783d9107aa26c76d5be460575f6885fd72effcd5374308a1165fb39107e730af59c3bc7a0df38a6a18da1379706891a8337f436de8461d9acb7c238f0dba5167e631cfa2f0e62bff7adda4639d4f2dc26a986fb08b80930b30893af33e449df9ed24b051077e3b0914893af337f06a68e563cf6ee0c517893cab82b4663449333d9393a1d58ba11505f3d597779f9d4f7df9e93df1a5761722ea9b2139ba2031d19b21d9bb67efde9dbfa1d9dd7b620f7735ebbaad9edfb6f744f86dc3ce67c3ba2435a435223564191d452a49686ce1d2caa2a50ca42a56ae50393262163333bcf69e88753e1a85a52fb362b74b09f0b2fda2e531ba9c8a3fab2f9a5de1652c1653e8652c56f7700f773a9cb5c3708b0cdf98c1b67d19a1c7de9c8ff3db193ff8d8f161c79d0f114398e58b08909f28de49028f647827f399df506c2158099ce841c3cb2f093c920d2f0f9fb0ede7c50365dd04a785889a7fe26f4e3525b5fcb6de7e3b9845f13223afcea496adce4ce0edab86d472d1884625f0f61909bcd8759ad1f2db1bbf3e4ba117230572d20ca990ac99664c783d9cf5340322605b4621be46232d78f01566e163617858171eec7d95598c5ac216ccd272d168694acac20ba8341f6a478d5dee0ffe9ebf037852b61a3b368617bbd8f1ae6f6b0568b44dc5bee055466af82b78b0ebd46283bd13c2d30b5de0421a5bd04216b070052b9c51052a4c614a210a5030e3094e68c26a9f643061096328210948d81fbb3fb6319a5de13112764c0c1eb37a5b2ce09255f1e6ebd4d2d8a796c8b32a8dd659466333a9b18cd68946638cd4db15dbd2d83707a348b4a35e1d4412ca276c7b2fca14efc4c77bbc139f931d75ec58b9187d0459e9f8edd813bc1ac40f6a12049be910ec21b1f94c9bccf3271de21e726a7e0e1c37706e6c6ca06a68666462605ebc93a9e336ad9461d79491e1ee0f9bec0a6fcf9d0eb0f9f2837d1b58e29768437e53e71a0076800c4b49081a12b6267053e8b260fac269cbe029f13205e604312d908162a6063438a8e9010a8b0d21d820e1a6093853b891051cdb235e7ef00bbd1dd31cdb2396a1b32a1e3fdb08ad64605ca1d2f2f246cd67ec011abd1275e22f2e45a543c96812ab2a2a41a61563750ebca0eb7cc8038fab64a9b22d2054e9ebd202ab54893c195d6556224fb768d07225f270592bf26cdee36196c8a395681228283189056c8139f0e499560824f91066e1c12cbc8a215d5c2a865406acc25db12c5896c803ab449df82cf33c1496a5e3591812960543da33ba5e5a2e2e97160274bd5857958b35ad9431adc8749549d328499347b36b6ca111a9c4166f8954b270d9c2482cce52a5b95481908b0fc8aa596f193e6ad611f2c0db81079b2396114d3631b1ada0c402a8a4261f5bacc9da5f9e8bdb57ad677415592d669de82a3bf655fc25bfcaced1156f893ea044afb4a6cdd362c779ac65c54751276a592d3cf261c548db0b275d93aee096432ba76d7191d56a713e4a5bac6cb1523ac6494967a4eeabca8ee4995ed73bd19b68a6a5e3286aa31e1f95a89751949627312a8c66aa8b3eea40ba2a792282ac1561cbb0eb7b54e4893cf27b28f1f38312e5278f7dab9967dfaae64f6254d825765d0a545d47527eca56964dadb4f352a06ac66b333149daa54095f6d59619ba8a22a553d544315a806ae652a06aa6269e864a81aa19baea893af13214b2a24e7c0c5dc1a4a8130f43573ea24efc0b651275e24b745524eac47b540a54cdf8137dd48997f1262a05aa32baf2a24e7c4721d28aa352a0ea8adfb45c9f48a557787d937c605f55a6bdc2248d3e8951cd6fab449fc4a8e457853d3bb4d2f1bb3e2feac0cf0ff5e5441922c89896cd8600545062520e28710d96cd023192370cc448e6c60231c2c1b1408c72b0980512c588002a282c05aa2210236c6681189d681688514dcd0231ca815a204635a8225d5d372a800a4814a31e2a28910b8bc56249b9ba0562c4a60562a49d1688118c8a8118d9bc2c10230ab3408c6c50315dcd1b15e05a2051a0602a231f2abe94a85a20465315811875a5056234a32d10a31baa08c468872ad255bc5101e00231ca788118799181305dc93f895161185f174651735ed48b74655400553c9448b3a8036f5400d52a4625e90a4a8cf4498ccaa8002aa68f4f2e285bde125e0e1c37706e6c6ca06a68666462605ebc93a9e336ad9461d794918bbc6dfd200a1778f01e1665db11789047f3d89a7f90a5994fdb031ece6c9b53676b7fb451e96552697eb5313707de76470a3f207898032f0852f3777bd478d8538b2d7e00042e7c801d8a348a516174b53a7fea008b2c76c0832b3df06e8483155758c1410eaa5820d8fc0d3c7fd260814481725219f950619732c502319255168811578305622443c50231c2b1c10231ca51dd608118f1504dba32c24185fd069e3fa1582046990c16889137830562848a6281185d8a05629452212d108cae6e209d80645d39ae7d6524a3da6e8483eafa120b507974b5c40254195d11dda08b2554ab2fb100d5a42b248a7c60840331b0e8a25a2db1001546574fb0e08413a854292305aa2bbb7e0e7a998d4f9adbf88a267bcd57df6518ce9c63a7afaaf841c773beba711dadee37beeaa6cd7190e86dbe62f11176da7100a070cc1c05b5ccb49a4b3795be622423191576738f75b400a0abd377d0223974e543d4e1eba02bd8ba41573ebaee387405916ce82a52ca4736e8aa8786e63574f58fc2a3181b56d4e19f7a39a8141e2aedaded7537ed8403e737647eb2712dcddc63628b831a5ba9f97684046fd0d5e9381426a1e80a6a99a12b6ead4a7405ad3092141eaa12eb86c6a3bd6c4e3650b701f36be6e530d1fbcb575b9a4ff75aa69f90acb00dbaba8ea29cb4e218ba8aada803b7acd8ca4657f2a886462498d15c337455c50f3197f96afbca08071597fdd2d2fc55153f68cfac343f4619bada1e436352d4e1c3d055d44257bc65255b5187914c345ae1a9841f94a135bb8daea248e1541c5d55f1c3f6f9954c6abe110eaa49571b9549bfe84a6a893afc8caea49518932e3304810c46c862084a688154aa200516c898022bd1271c061638400112d678816a52b9452679acb37cb060175515f251a60ba00138067bbdc2a3d88575d1284638aa28504e2c168ba5ba9a6003f0a5e4a8261558007e85d92b231d65aa28462955142939a8a60948e043354bb003e04b41a9ae579eafd10ad6a54b1a9a4086182f409a348a110eaa28d9a5e4a09a4b70aa79293c549389b8057681094ea8c213599ca05a15f62aad60496001137ab04411b8a05a1546a1605dba74c96814293e5453ca0e8067d10e801f05caa94b972e5d54d8a55c35a3ec00f8556e69fe7c627fc8f3272bf26074f7a29e575333e9ee64354b9a6379c0d9ead5f1841245be09e3072ce0e1997262c94bf9edb7ede6faf67cf64531ca54d94bc73ea34c857dbffae40766a9b2973e2939a8b026b2e76f8440a49e34d2fae4e6a23e60dffec15365efe1eba240a79e748a4c4256671ff64de611f0b4205e7e4652251fbf0a9c54f2bb3152a0534f21bf64b098a10b56000517088160c797608370773fd85ddac6f6e04fa6dbfd50db830f3f08c5db561668b46743be702fbdad2cb8b40ca7c8b015e171af173b48c292d182dd7663a415b27a879c5a3e7e4d64cbf8dd789edddd1e54b68a435720bdcf98c7f4bd2783c261ae04e347d4d9879dfb887a7e15f6cd9079ec4bab4a259160e7de9602f2f38ce696a7811acd93337d514c97b23b0079a8babe79d3b7aa6d72db4dd37c0f733743b66bdfae9dbbd443dcba6dc8d66df3d9b7d257afdf70df2e5d7e371c0d42a768a2b9b929a23477e95be490682f6d92d3beebd9075b56c809e1687c8902c12ea5c71eb8398aa46a97875da2951b89bc10515f43606fb424617397e9c0c35ee7e3106ef9ae18bd19725d4e7a237f23e990f98b0a995452b83de21348a4f17584ad080f5ef36a6878b9109bdfedb197875ffc85fd8894b39b2191eef6c0e0b58674db1efceb0b82cdfc1e6625faa5060cc2336c401ebcd4f16a16832dcde7bc4fe603f2e0111b106caec1193dcf9f106c3e773b6c9738086e8ff9a1ac81b64b6fe72e08776deeb0bd5123503d846a48352eb53cf7319a7be9db36b952e9835f2d0d91e7be9d90d2b9f7b00ed8b7c36f7be9e31ebb215990ec90eef680ef61eeab4c4bdfbeca0df74df6d8578720d105790bf23570a2af471f2e300511a23423de5c7f4eaa081165f4d44a69cc09210cb25f5c8f3b7017e09d8ada2c3cf00eec791fbcb3ad2a517ab398d1b3eb9ed1f3ea8149f3177ee86afe60e7f0cefc82f643d71022cdbff80b99eef2809d0f9292c6c12e488c351efb867d15047d7d9504674f9856a2b8255af948325ae3f7f5ba1edfc3572724c6475a93b8f8e71dfee237c843e2f943e04587c0639fc7e19deb531ea2617f7d0b39ecdbd61451f4f5cdf66436ee7840031ad29086deaecbf2d85f1fecd2dbb19607b39468788e5b4a4bd8163e91533db8597cd1d7f9063dc968b93f62e703913cbea2b775832a343fd1dba2e28b4ef5b66aa0464388e4c52e7a5b38b0a2e117bdad2bb4d03c7a5b57a0a06727e4ea6ac409c0284252031569b825060df4c4d475880a51403dd175a8ca1354e83a34022accae424dc8e2061f68e92a74454bc3cf4ec8b6c651571dd6381292b158dba5a19037dc1fdcfed07aa1007a0f97e7823af19b051318013d598cb102d8be68e5732784697dd2fc8b36e11e2208367c4946f3368ecbba26d2b43fb2a0d240a7d3fe583474fc0511b01debd5f1c386b478d08a5d908b2bd124a3af4f32ba0a11f505b45dba7461a2e663ad1d38d15f7fbd31c75f8ec6be49469319498778c8f9fafc9070a703ecd218bd11228f5d07798c0e6ddddac1163dc43d69e537813d4fd45fcfef6b1eda1a422a59ac1a80986586ecc204c3b56aec2240b2ba6e08805758bde7fde1a3f7717956b5df304e7641d68c2bcbb20c8b592639cb60ca04cf4db115e1c9de5614558af0666f2b8a1b34d4218421d4a0650cc0b0e3c930db1ef3fb4128f35b9acff6c7195b697ff84488c306e4c1af695b1cbc6d4561d4356bed80898ecc47b6852bf06a867d3bc5c718638c71639c53662b6f5b5150e9f99e785ddf7b18fb398a9a9a1a9acf5ce631afa9a9a9a919434c4c0ccc5feefdf49898989898344ea793e9ddb96f3f9d4ea71315b66dd3be6ddbb695b12df66d771772b73d306e7b6087dfcabb3e2f8f61e7f6071f7bc7981166f4b135990d74d9405ee36c8f26dc329cba8dedc49797f3db0db9e431aae4a2f57a9288832d3de9b56a79f8ebf15b2398a02f3a45b6d527bdcd0f53b24638eaf9fa81beb0f9baea8b56f8a82401515a272d5580200032baa0d5c90c921aa7b735832e7a636e7ea72e5dba38a12a4dc1ba4102299a400ada81744516d610933da3a76009808c2e584d1210a5e5e4033d43b067a84a94b5674c3a058b260a38809205164bb574b57fa224065034418935582c55465951582cd5beca1d492b93bdfce2b9dbae022f5388020dd200a54b17d5ca74e4274c34f9aa625f43d7a590094e41267827c8474f214fb45778fc4a3a6914293d54f346312a267847a6b92669c804a7f83ebaca745d2bf810657e8a5721135668fe4ade8b3a627082074ff0c04a128ba59a8f9fdfaae2c7923628c10c4220831fa8a248e9a18a378a51c928525875dd4801aaf8f9192940b5aae287f8950f51871fb5acaaf8e1faa4ab9e55153fcc47ba7ad4e14fea4327beae961dc3124298820b4ea0620a49f081b72a221510e1073188019632721006d5aae4ab8f1fce62a92213bc5343dc4396578801bfc12582d00051ca6f1e426cceebf1d89c937f80c3a9f9d8cd2c2dc3a9b9450eca5f14875393363f6183cff607a4584c2083f86c7fc4fb74d10532b4cc071b6e0f4e6511422ce2777fccefb719e3b783e711b3c7ebf17a3c0ed9151fafc7183f713875f95c41681986ddf51b79d8dc37328ceb13a3389cbaa8842dbf6c7becb795c6c61b7fdb82a28b9639c1cbfd01a9177d9ced01e149876d20d8656e8f256208a70c81860d041e7733d8d2194386453c1078f0cbed0f788e700cdb7e73e4feb8be9ffb03b60f4e4d28b4681eb18280072af2689fcf617f7c7b649f4ff18ec7a9ec73ea647fe4c96a7a5e8675b2cf43e144d7ec0f1c4e658fbd2d28ae34767d284e65cba91becb1b96f300a04bb40c1456f0b8a1fb40ca7b25f1f2c511c4e65737becb793db63dfc3d7073b56b15d3edabfeebb3fb6cf6fdb47d4950b827d8f04fb9efb2ad6db82028b96db639ef7e3771fc6cfb2775ff6920e30a3759f7d632efb783bccb8ec638e6ee7be9d0edc35eedb033aae74d8013989120225580d548f38031abab4d06aa9d284087a2f44d44b97dbb8eaa4b70774b43ae9eddc06d17ab747dd6b6f245a10edbb5124d96b7638849fbd2b7dfbed273728bde8e1fd200be8cca6e32da768b6d86a2246cec9609749a09190831410018d3290018b6abd97e9a3e3d594f4b6f5c416cde7c13bdc7c1c9807aa789e3948b9ded613376849653805bbc55fc86a8a07efc88ef7e265224ec7679c067600fbdd662f162ca6ded61350b6de560cb8340e64354381464356ef37e6d9ae90c5bdad258cd10354a29756c8eaf826b2f7f21b726aa2aef23742b49614e8d4fb25a37d74dd2e5de37993dc7ed583af620f3ba0b7d791e2b038079b8eb79789d98af0e4f20bc729c92999ed24043b766c9b3bbebca4bc364c4a66b82c4ddf1e9b51240fd02e0f8493d14ad4d9a5f669ef899bfc36ad94659db5c4aeb93ce0e5f280d7aa6cd89202ad9adfc35a5c1ef0f0f0f09a6cfe07149bb38c665c25a7b2c32e086ceef29392ae8ff6265e27912c25ba6607c2d650a24be9abdde3b10fc93cf64bfad55a6b2681b2282150a2839a5c5d7a13ac8588ba44e5b3216ed3a38902c1357a76df10f73cf701c59ef446086c35f6d8f9608f5fa9cacf635f13eef88db93a80888b86cb23fbd43e3fa055c7679ffc2ee1b74d46ce687d4fbc625721a2eeeca54fa0d89122c92812f812055a758d5ef327136fe47723cfc7be41ec908f5d0a6120d8256888db4e081321453a7b467779e8b05f605fcd8e441efb967db1943dc6ec9a263f74b5f6ca415a567a0f67a56bf203825dbaf4ecdb5d1eb20b322f0f3b1ff965b0f26190a41911073b2fb6952ff2717e9bf11bece00cb25fa836eddb69dbe37c74b6df1fb097fb3cdef1d1fb29645efba67dda373faf6141b213ec6d3d4e959e1d3bec7cb2cfe3d41efb4adffc9ac0d6be26b0b34c4286519a34faedb19f5f469160df2e3ba0ec01d8377a2a65875d92eb25ba9ccae8724abbb97e436fd857b167dfb6ed4ab41275e9da977dd501da33f8ecdbae448162671048f67c95bf2810ec497138b527cae094b2c56f4efc907848e26b682c2870627f541f2d89a410ade525f61a697dd2f1b5f480ad424b3a05f61efe7ed8e55701019081a58b6a1fbfbaea58e7931039d1d7eb1304ec0aa06e0b0a33f410ec8b2ad9331a2876e9d2934eb1da3f8938d8a2c228abae5ad21a5f4bcd35f47ebb0cac118e545b436f0e53243e26b3966d89194c30c5054e1859b1866ab96d795bd68287e214bcc72978ac174b0aac346cee82e414642e78f539a478071e08ef5c0dbd20c1190d79343c0765db96238a36bb2d4729bb48812b64f9bed82016b07300150610f9024a9ad118c4a601efb461c0dbce01442d25cd2811840df8028b183da6db958f6429d093de7b3380c117bd2d184401e576cdef93deec7820ea8ba82f9af1975de1c54d763e335eefe19b8b06817dfdda869f1feccd911489c765d38017e16bbc167083c4a0d5b3b70583a4de976d31c0b5ecedb4de75c8349e7bbc09c28fd7e1259278f9ebbb5c5bd91603de765aded9160cc6e88ccb4e17f0e2f9404fe057420f48a48eadef668bb109b6cf730948c0c408443025c32ed3b74b48298a022504acc4ecbe2e6940c31a67304319c8300631a81106307c617fecfed032bd93a9e3b6d88a3c1e855be2896e66a2b47a17ad280edbaed892a8a7bad4041569c4c41a92b5458d9ef18c1e865a224f64459d79a3ecc88b547a422d3d8178daf9b1d5f31129f2c03140b825f2d84048e3991aa9278ebeb06b25229f9f261a1c5d6d7a3e9b62f224d2010e6c400319c0c0052c50010afc30010944c0871e20f0001e863840c80e3a04f169000354dd330f5b54cc6c62f3ea992d668964b2620627b985ec12a858820d92704ed8b02d7d7d835d908f7778ec83bd7999f6ed4aef612cbb06dbfbe0cbb7634cf9a2b7178bbee1374889624a94aef9183df399331a8b8e79cc1756bae695e88802deb68ca2e89ac39e82456fdf2eaf5c49da371b1caacbae7ddb7be873fa86c3dd74a5bf7cd9b3f7b0e96503493e8cd180cd9203101e3e3e9557b3d3693a1ffe4ce723658c86875f74cc63601e3b1f1bdfd693f9763e289b2437dfce67c5a9efdbf91cc0abf24add160bb86c8053d761f7803da3a9c0db68bfb9d27df5dd691a4d8ef69b6fda076f3e27daeb725971eabaf61ea6c9d1311f5fe5951a1a0e0681ff6dba20f0379c09ef5cb7a9496cbe719fcd47c40f8f7b5d349270ea3a479970ea3a3686277f25d950d9f1badbe882c0e7d0601ebfef52e6cf3103176a125b46e647d86819cff392a822063208e3af398e636363f3cabdd2989898d3bae2018b0561c87120a11c2fc779c5f11b140af5bae3f5a3f447d8688a432b08cc60852e61e03890108ee7f88d9bd71bb799999979cd79fdf77d37b48280c5c411b2e4c891e355e8c681846e1cc773d8bce21c050303f3aae335c77f1b5a3f80250c26b88003078e57219c0309e1fcc671a05e6f3e733a9d5e6dbce2c89123078a5624b094410649b871e3c6abd0cd81846e8ef31b33af3687e138ee95e6f5060e1c386668c57870851338010707e755c8e6404236bf390ecc2beaa71d3b76bcd6bce2dcb8710386d669852e9460c6cdcdcdab10ea4042a8dbfce6f43a732e2727e755e6f5060707e744ab544212a650616363f32a347320a199a36ec3bdc27c870e1d3a5e635e6d6e6e6e385ad90b5194e105140af52a0473202198cf1c45ebf61dafa7e7d8b061e395bea26c6c7e848db6d9412b23e5c00b22ccccccbc0a9d0e24743acc6768f59ef3ca5d070d0dcdebf73a8342fd081b8dcaa175d320450b3060607e844dc3bc0a710712e2eacb75bceeb88d9a9a9ad7bfc2ccccfc081b3da383d62768288309a49c4ea757a11d0712da71eea79cd3c8c8c8bce6783dc1c0fc081b0d6332999e44c1052560e1b81f61d3dcab50ce818472bee31cada6d3bcea780dad424db48eb9d0115dc7fc8853c7bce278e52ed424f6e9424798faf4236cf469c58417a8a0c68e1d3b5e85741c4848c773bea3e6d5c6656464646428901a5a9188c216124c919393f32a64e3404236aee339b47a348fc96153d089143354210d3a74e87815a2399010cd6d5c07ad2f9779ad39c56153105341197ca0860d1b36686e83d6ee8b898989a13eaae0e00c5ed0d0d0d0d06a3a0f86028c110061cb91f23c0f3641821d28e1e1c8d9144ca21583255079b9f14dc1aeeb3e50c6177eb084aee63838deb7ed2693c984c409d2501445cd81846a4c32bf41bddc3b90d0cbbd6fdbb6cd237c31832fc81c4848e6358fa175bb8dd798dbd0d0d07c08d534546653b0fbcb8184babfdcf33c8f561bb446319e10e50935353fc2a66b5e85620e24147399d3bca26a6a6a6aa8e799de1d48c8f4ee2f2f2f2fb4d2d0faa40864f0400a1919995721ef4042de632e43ab7699d79997979717ca61db4d0712da6e7ad7751dad32b482c00a286438424c4cccab10e63d86d6d25f5e61baaeeb68766ddb4d26d38fc0d1265a5f68c5a64061ca09daf37e844d7baf42d78184b05ff768cddebd9e4c26d387506da272531088af1d4888b7ed47e0e88dd68e56d944152950e9cad16ddb3e84ea8deea6e0abd03c1076a1ebf355e808acb10b1d31d3d88fb0a9424768cd173a22a6f947e068be1090f6d281f8429a56fab28ffb50389c1aba7440051461c3f97e072691874ae4c1f1855f9ed2f744449e1ddfc3a3c863f3bdf9de8b3ca7ef73884522cfbf87469187fbeaf87eef23f2c47c7f81c803f33d64451e007cbda3bef721f2d0ef9d441e9ac8f30580d6ac03f09a8fd2a21b6c788fcf7c1f2da2df73fef201a08603e0a977df69510f1e9ff9f6e9a04539bf8e67df0e5ac463e6371cfb6c681100765ce7d77743759cfe9f1f0e2db2c1397f3868d10e9da76ee32bba79d1469dbaad225ce900e0b80c0fd50d1cc7f9e92bc241a7dca02aea8ee336d76ce814932ac76f68918d9f8e43a7cca88ab0db1cf51569379779cc577423739c9b706eba0c9d125545353fbdf415e1d0293d54452fc7315dbbfc8a4c744a025445db7168740a8eaa48bbcd6fe8141955d1cde561be221b7ad029365445d96dce834ec9544537e7c7af084a1191ea068a731be8944b55643a8ecfd02930aaa2999f4ef315e9d02937aaa29bcf149d92a32a42fdf41ace7d4535d0299aaa08e63800a0534eaa22ee38be834ec9415574dde6de57f4e5d02935a88a6e1e7f3a45475544f353e93ffc8a74d029ac2af28e732845442a4aa7284055743a0e5a549279cca740158e7f740a8faaa8741b5a64f32950f5f91c5fd10d2d9a025537c7a1fdc6577463e3a8d79ce6339f025536b4a8a8a8e8f4007c4f5a6de3437da99acf87cf49d4d9cfec65be98cf47d4d9c37c17883afb970fb2a2cedefb6095a8b33f7da62f87af48d4d9731f348a3afbed8356a2ce5efb4a5ff611018fa2ce95f9c96f07265167cf1fa412755a51674f049ff4e06c0ab9cf7022202f25646942921780108531dc80462935a1057223031727100312ba5cc18aaf04537060a4c0c716194d6f6b0856a2902598c9204a29af6b082be82b8bdfb20fc5a92c4baa62ca680ac78a2b4041518f5325ae174b1857e8d98b25cb0e32966bfc1fc235e735a577a22c98d841185c508485144d78e1daf88133d220832bc028021acec821461a2531c400c57555a124a5099a19535491f1f3171011cd87decb0fd20f7693068997f1dbae8f0b9b4af444af147ae96e8f851722ea7939df9336805344ddc3293e57e1f19b90a5e1b74be28994b4ceaf907949e5b78749ebaae125bd09b29747b2977bd93dccbb1b99d0842bf0f0927770346c35a14ac39c86c7f1f899c6a36d20b512104a547e389c4ad1a33875889a220a8aa2228f44d5c433ec7c601aded5cb3bd7725381d410ce2766bcb0942108590922eda25482eb43c974a10a2140d122043838c30d31b2e8c41842095a624c619a728becd4db1283caa4425b79f148d576519ad825766117c683edc2a8dce29a383db90ca1e73c6ace79cfcb244e57af230d1a2ae0092c380216130c410864a8e2179579bd58b81c75f55a6e61974b1a5be0820b5a78228d21a866cf7bad9eb1674b0864f454816afad82293e96d09c18bde7ab19871826d23cf8a917260a45a3de1af9e6c62d8d252f19f6c10b660a1e2ef9641f564c15031ad0242046cd009afb4412886514b086b08218dee2e568003a330ca88a2a3b71546165d45eb95b7584c700616132001de832df0b6d5051a366828024ff662a1628a867b8110782b6f5b60a0d1bdf2b6150695de77bdad308cda049ed7db02834bc3ff20af26683eb6182a3a42195fe4400d339650459b8e584c80848ef10a2c1d639471a6178b09b6e8ab178b1557c419ac155568428b1352d07044041b60402103838b28d7e3755dbb5bd8410cc2108228b0800b585056a0607a61050b48e0638bb542d1962708c10b3eb8420e6ab0b4d0705971858f2d32ae17cb165835b8e218535452ca78490986105a8e4025a59c73ce098617524ed9f57a61050b64d1b12b76c1a5638c3fbde4945e8cb10b337484a28a314a4fa6a6170b17a496bd2d30b8e8ea5d1c4b10c5e36f908a97f5b6c0b0828a57ea6d81b18386e71db609d76354cf280f69f5983f975e179541cfc3de4e9287fb9ef36436ee7be26db7913196bceb5836e1760f903d5f9a9d9009974d9a4cdf6852a3415072bc13e914dce56526e5b14f3e4af939393abd28555cefce7dabe5707788faf2582c164bb5fb63e346abe0496fe261cfcba26d73ea6a89f0379106e18eef120b87232d32a6a320fca0eb7b8340a52b8f1d5d7d44865e946dc1e845612b1b5c6613a4700c6f2992d5e20547fad96059c3059e0745e0c1af090b4df4b6b0102500bdad2b8cd1fc71de29662fd918ac8e8f4b848ecf81079a8e2d2534d1f139bcc33b343974fcb06fccf1f7f1f872b8ebbab7d7cb722ae347c64a9f0ca74adf76363fd85db11b027f2161483d1cde618ae24e8864b124ef407eec1e00bb34d31ca000e263c74d78dc393c67c7fe901c773d48168bc5ea8bf2a6ae8e979d10d9f5c990d8d7b7c85d5f138691579a80625f1472c7856cc22ed3db03064cf4b66040a5e36582984ea15de60a593a9ee3cf43413a85d1551ad5b460268047f125e3d439b5e7015f643875737d5b4538a3e5fee6a241b0a0c0099ed8daeff0439124adba6a4491ac31a0b1ad285d158b850c465db78cde3194d175cff0965575b9f4fefa1ab005154e6dcfaf015a6ce1d4b6fc1aa0851a9cdaf6c13bd0a877a665ba015b38c1a9dd94ec48a7c8e19457b3f696e0c574f57abf78a2f71cefc4f47e7316e3a80388802e2e2c692c6fab8b32fa283ece769a59d4e12a5bc6c85ca1a4d706bfc508143bbb1051c7f89d5f957dc5c85c616f90d6ebf21badd735edbb20c4de13814ab57421a296df0ffba012bcd90999f3a52389cfe47b585ee77bf3ba0e5bc8fc452b927824f1dcf5cdf9219197f3dbce601773f8ba0293e055af238e272f297b51aa8097725515fc780e305fe1f13972e4e1c7ef0ffcecbbf9217e3ed21b79781f36ead008b06aa30e7c0289206f605b5e94875d74f7a53ddc238119c3cf6f1a849fd4a8e414cb1d089711a0edc24fba7b5dd7c6c541c9f4d6ebbaaeebbaae0b4a4e315787269751d94cdfcfe4c3f46d0ce316b955632f954adb562a6d5b69887db60dca6892dde4ae0dd3b25229d3b0ede266274df1c41e7ce132de5953c76d5a293b99e0f6d8cf2bdbb06d378cdb4e87ceb41d6ecf1e5f82252ec5cb948e2a69dae1b5433a04bba4d1ba753d6c47025f2a95b66ddbb2edd8b70dceadc472db20bd4adbb6659ce2efdb833b87954aa552e975dbb6ad0421d641f80f42088be0f1b51ce5bc30b899894997bedbb745884186670cc3300cc2b9415ae1b1ec15c3300cc3300cc3300cc3300cc3300cc3300cc3300cc3300cc3b06d4836ccd9bec5bebd8464db0d6e93e50e6404f07686db57616fdb77e3ed1b5d0dc252068fcd0f9eef1171f0862e6cbb3b523e2e33ff933b52464600336fa7dd1ffbcacccb1c615462dbd6db628a5392478c506a1b6a3d8ef336eda552c6ddb65ec436c952c29da6dd1ef23d2ca5a41cc55879ddf46598949aa671526a9aa669da36d4956bec9beca494dd2933994c973761a6aed3b45312ae35e9652579d5a1297300d22ba594dab1ee15c3b4638758f7c54dbbd43429a5d44cbf3ed3d69d4ea7d3294a8961180e188fbebe5afae2617b5cdfa494524a39a349bbd4a49c2529a57cd652fe74997542e44fb46a3d684722df514d4aa969524a29a5a64929a5949aa6494d939ad434a9691aa6699aa6699aa6699aa669334aa9699aa669334aa9699aa669334a894929a59452ce08a59452ce88d19a35a6494dd3344dd3344d8b9aa6699a16a5d4344dd3b428a5a6699aa64529310cbba6699aa6699a9498a6699aa6699a16354dd3342d4aa9699aa669514a4dd3344d8b52629aa6699a949a866d526aaf524aa949a969dc524aa9699aa6699894988c988c988c988c988c988c988c9826a594524a296594127b95524ac92d3fb15729a5c4a49452ca28a5c4a4945193524a2935edf39ba6699aa6699aa6cda8699aa669334aa9699aa669334aa9699aa669334a89c96f12ca6b18cd81535726af1d62af9a26afc923d124764909bbcaaf94718bb47a5c47a9bd4a29b1af0ec99e8f93eeb747e5d17b288607b7cf5f5fcff6b83ebfba5ff425e379e768cd69ce14e7b7738adf5deb7cba6ff70d72dde15712c1ab5e335fa6fb60c3ae3b651d9f75a437434e8f3f3dd221d8dd4b9d90f813adf31d8db1ebba39638c31c66ececd34e39cb1eb66ecba3963d7cd39392e6a1c774e711df79ee87d5c8afbae73d93cac32c6b8db66faf699be69b33b9d4ea7d34f5af72da7ba6b9f73ce39e79c1367337d3587dee69c7376734e2fe3d4f6e59d39b539a7367972c739e79c734eca83535bf5d15b472b515fbd0db54f36c78e93d33e6e7971da077b629cf66d5f5d906d319346777bcc6f5de4cea77bc63bda8798e58e8cdc433ca43bee784c7b8d3146adeb5addc9b835a7b76ed2736a1e87edb1c54f5ae58e8c1cbb74610474dcf3f048826077e9d8bdce39b1c748b7ed3d91fb6a1220dbe703eea74679cc6f3955a25a49fb64fc750c0ec18337d12a9bbbc8c96d6a5769c3b88c77aa8d7c9d337ef6108f6442313c182927bf2c665de3c3f06047ba99a93ae9138428e02242221c81610e0f1e5f40e618a59cf3ba38ecc338ac5b4e551c1abef429c329899a339399ac59cbebfa96533e2a4e3ffb9c594e4ec7af98f410aa97533225bfad545a1abf9a43c7cb3ad4d149a4325da2255a73e89903a726ad49564b67c7322804af4aec9a3232c44cd549330fcce2f1e5eec8d749370c4ff6f6700aaad8cba006c593579c73ce09464f16a8e6a4d9cef4b65a50f096306525a330b0ebca642c61910364388116b640022a90204b8c111414c469d4c2082046152a7811852528c105181478efc522a50c8deac562546504d9945262a1628d96302daf4b2937cb3e4923cd30242c3198c20f6430062d5af0d204e70326e2afb9c5f422cf134760a2ca145c4082149ea0925e4b2fbeb841cbcbf0ce6c6954a52515957c0ef3acca07dd7829650ba9e525f340168bc592a29252fef232bdad160d260dae22201c2520938373e50b67e440968f1ce216c18a189ca08b259c808c27a84ebd47f1ce7bdf938a3c52b55f0c24f13143c5126c90c447195c7a5b65446902f4b6c8484243168cc23bf19996ceb24b988627b3c7a1d8a5672fc58c7af243c9dcc093f7de327e4e7847d2b9ead24bb4c65f9d0e1795f1220f93c8c4069e7cdd2d3a0c3d5b4ecdcff871ad659ec9d0bce49d770fcb8f9b910aaf3e08de919f270222200a6f5b646869792d5836ed9547ab02d92f7abf324be1c03c996abf6d136fb15071d42fbd586ae0446fc71976254e8e2f512f7e28994e8798c3a90a5b6e108a9ce042184e8064050ba6222c21e7561c2eb6f048d5b5d79771ea3acc72842006155c90c1850c57746354aeafeb0951e86bebebba0cad4972faba77651402c1dbc6be1c4e114531a5cb175acc9024850f545c5ff7b230a3afe330cfb6582c9691ea7a0e27f1d193a6e8b7f056051bde8b3c5205bf730a5efb7258071e6ae1d9e86d71718636f5b69290d4f55d62acc84a33120fbc792eab25cb45eb4634e4914c8a3c2b98c4461929ea301a90408543325559654b427b9556b88a95a8c357b834736bb23a4b57c865b5344b0a546de759bd9c67e59d6775fa469dab3be4c24a02b28c8c8c8e8e8ea28e0e1f4a17a64225eae8701210a90a17485d394bc6594c9a89ae16808623a84c87c271302c18984389395dc99c9ff2e13174079417798a62972e5d5450b417d11ca20e43d1d25099ce87556062fe2446c59d3b0c85558a6064baeedd61a82c829991a1499c4e3f1d86ae478b640e657b511114ed452ba302a8603e4393f0bc7bc75e68d1cba16ca5afaaa8088af65515c5d0243898eddb5f68f6d20773e0451aef7d30e9f441343eb8e583657c50cb2744d45978f01cbd8c56680515d19034a271c5ab9055a7116429a10750b8c00a5f9881cab45a2d144129630950f881aa5b7119d4a0016b09560d54dc2a1ae1ca1560c02a8316aa6dc559a4a441061170a18b4a3b7f1a451eef7494050d5b50d1825446e45925c1495ea049301a5e7841c53f28a32b6769e6d2fc8846e459419589fad812793a9a43e4127938dac38a3c1bdd411a451e8d321a40a802f91c51c62f516c39f082e6afef35d363a9f45512dd76d6b48d2651e2ced124b4d3210773e001c1c6b2a88ab8af8c0aa03ad12436134d82c32e2e1797c8d3d1a2aea31797a8135fc471146679d1b6c1d6c5a5483b94ec4501a730a8d4e898a973999a249d620acdd048838004231600404024168c46e3384f14f5011480118ec4624ca6cb9420c851c8186308210081210000323232220909791e36a6dd54fbfd17d483a2bf9ad83305cf68367ac7a263a4d9130bb6fbc9ed30dfc8d3c5daab839361c7a01b12ed15c41573db60c3d8aac663aa15c5a6aaf0304432c480823a656e93ac3036ddf058b582daa4541e0c5106185890a6cdcd9205c6b6161eaf96509bd0920b0c518d14315059a95d26cc7789aa332361dc93567b52981f892a320452cd3f56334f2c924524f7f3c3ec8ec7d60ee32fcf0a82f9e5d716b4b57d70885298b601fd3fdae08a0a20d559f583ed7a5bea78011e9233b2dbc887c196231d00ba67a3350baa6e9761d722417b164f983c7c07f5e03455dd385b87c1b91654d8e896651a8b38e15e0ba06adf681723bb13a85aa3e62d96c1c71192356b562dea3bcd48038dec6077f1936b1a3af4a50a9ca06d2f4734d7627b5a124e643bad07dd936bf04265b394ec513fce1ca3f70d5f8e49b58a973d9bd30160156c8faeba155f5b05f9a9fe7dee6584e96e6086b976317e882c9a8442d3920bc613e0e9f7aa56b47bf6c6d351500983b302dd1c7463c67509128a72d497ae33433b961d9220a29d0d60068b8f95bb3ac4bbd320fd13d511a848388b73dbae50e9c8c606b16f063a2b2c0809fa7368bb32d2899393557f4f190a1b6423336744658d58f26403cc77970fdfe5004b463555fc9f8f4c39a2e7c3a11f2abf591df9667a6a4ac1dc4815faaf7adbf402b901046ec2d04d427e23923db97a885cc611a5ce52cba25b414774c04d579475449b5c7d3d6793c4ec01f76c0d0a3bcbfac4addaed1779cbb7e660d6f32078b9434797afa5abacb6cdecea486a52dc5639f0acf5e53a0bd7bd83bb434813a2856ce98e35132dee3262a53560177555f462ba75b054c107b178810feea8b5e9e836a8195fb9303c36829d1881f89571c0bc2a9b0ba4408ec8097d53c3731258325d9991b19773f7f67349cdee19d3b5869aa3521564989654ac5255750e9ea7cee066a820a9fc0161527b7487085c04c585ef3a8d644b6a7bb1b4604b20173eb165715eec183ec41c04cf96ba469c07f908cac0e693bb783eb4f0d0f39068eae52ee508a29e614b4418089a1e84d089b11ec87544ff41ef910c0b194fb36bc8cd98661011051504060d7447e6fe9295615eb729e8d0b5d06271147a40c1f4720bc32b9dddac51ce1a4b69f2af48a0829267cee4a2478d7c1f8f1cdca17a068600af91f5b4c2035c36e3850472175aee2cca8a7ba9e7c1ce882ff7dd6a6555df2fc6d9b186d477d9ab18a4bfa14f23edf561fa6a719e4c99fdbce298e536b44ebef0d2a59371bc2c3b0edb243944a676bc2a4dc966775c72157c9b8dec3ec18c7e817391c43223851eabef2a9b85195e8af6fa83b8a7bf70bb7c3a60b6ffdf9dbf18e886cffb563785ff7974035684581027eee7d5e56eaae32a1cb592ce20d5c68ba05ab5597576f1d55266c5391ccf55f7c31265e19794bc5d45da2245c06390af80c6752c717fe74da0af39a0fc956caf307c37edf250c70fb6468d5cf1ca5a94cdef2e1ca337612670b0f8fe65b0dc535323251bf0abe841812e398812a22035a7f1f35331c5b5b87068ee039777959f747d1357d33d6346760185c623e6bef4748a2029c7c43d518320c3e0ed76d53938ca530de6753743bf52c05dac49e9134a738fa460794264014718f1abc8e3c60a16706f86593f108520a4085c1ea8c86a43d3603e2212c770871beca6d999874436bd9e851b0542873b6e88602108a1782069acc6ea23d4aa853cf29c494c497c24581c44a766765a113ba5ec416c8505a2cb66d58b29b9072eaab8eb03063f691e5e255a2810a690b487922f19e507b852721cdb1062dc054e9f739469af6c488b4a7671de7e0d18703bb197c11c94d0b03a20d732c418b37e96cafddce2978549a47be0f362cffce0ad18ebfc302bee20fad312e880c112262b7810fe81dc87a191f8f21afb2dd1af40ccb102b4226045a5c3c6d175f29bb75cbdf3f81076a63053477cc1d1c1e25f23430794c13d6e127fff8e6737a834e1b8c185ea83b5b7b7a5e58274f238e866e91245dcc704e0a29d89a5ffe877313291fa52333b58e8d4efe2d3fea55e1a5f5c1d3b120ca9cfce98162ae88d9a98e0d2086aaa7e1f3917c5f840a00e305471900f15b7d5e2f7d23ce8a789d3ca72d13318ec7690a89c228b0ef070587adb19503cb6c208367836a528f40934a2626959f6aa2fc08b903a9bb78fd8872c456705c450877c91ed2ea6856d6c16dfb60c3f631132aa1ec61906ba88386394e40d477e183cbd2766b087a10a3e410b79233fda08a251416026d48d4d6a04dcc1f241ed9eea10de570538690e9ccbd51ae0cb106ac95541d70a76c44ce2f5f01cc07ed03c19594d5542306f1b910fd22d609debcc829b5cb4c7465f1767161ee473813e4619967d2e104df5b72e94b2e77e3cc8cdecb6f6e40825aab9bec3d25488e4aced5be16040d733fe288a048014566afca40d3e924e866dc2f9cf07594aeab2165774162469d6ba94850534c4b2e5f3dcf738195e419b97b9771a80af5aadcc596adab315ac926a7292f6652eb3929c8adeeb4748f3d9d7a3ced2d56994fae9cca3a30ada66f521d622d44d2e2902ef759e73b677d6333344eaff3e6dce6b1dc347f4955f8e46e6ea42082fa88a853e8d886928885aeccd410bf9164ae01fe1dd47721636fb313aacd1263ac5b2e9a8090e14265a1c65d1ba66a96a04252b85b85285ba5b85681f6e1dafec14ea7e8a579ea19b4b22e59a997d972f62b2bb2cf7f61af7cea8d95f7102a28a77683afde5c6b432b06ee15958435d19f818e0e34289da5ec099f1bd385d45f7ba0c126e51eb8e6c807dc6a33ed1fe3390924a23544b7bd1b496e0c83af1e71aa4bd5da30a952fe137a402b4f9594450028aaa6e1035e1aa168aa86397c289f6481695a2a448e256695624f2a48607e71d56e829f34384b563f1dd3623101e1744290058a1db60c6a7e7c8e2ebb22a1ac21b5ac2d98e1cc9b929a0d2cb448b42f5523387f657a5c21ba383b34af737e86072a346d17a3fcb3c99f2430ce8b7df370ed061c075e96f0b1d21f58c9a77a6ed90b6367251785737468658a84317da981ac8fbd4eff9c792dd61df294bab1b5f2902a2c66cd0f18101b91a7134f8e22cf6a8222c404acbd3e54b8e6f87b982ee071ea5b62374a4d2864c18979beb505bf04adacb0b562251b74b5e80fd7cc743aae42d845bd4c60422031ab0eca64f49a636afdf6d74f94410a4ccc7396aa157d469c0358cd5a4c50eb894bb72ed07fc00417cb9553ab2230b315176f73e78762101e9b0627cdb19671b86894558d0f5a1bfd0026b563974e8a3088e932c7d236fd9047621eff8ff82efdee6849800f45b7c21d51ed476a5acfe99470017c0c80fda3d93d78499ae73a2d39d73f195d4501c29a1ea7a6c3f83b95ccabebdbcb82036805c08e89ae0ec40512aed72845d9c4f0053faa872d5b6238f2ae56a8dac5252fd69d8bc3ec3996f5cdf233d36c4c32a19b184e3962e43d616611c05f910ccbf4bb838ed9a759cdec257114738c27805892b2ab978198759019425f9243b9594adb6a6125649f5d8d3b58790bfb49704228246723c27e58870b5dc4471589a5ac3f12088f5d71d39db4a9d448b214400da536c48699943b01a949e9d6dc7906903457a2e23ad593da20ca52d6bc50bbd44af6b4aa49a718e92d2668644c1ad02d9f5600847cb8e78b947999e03f2abd63e9e5986d577942d66c9457a1f25017b6856c079479b839b88455aa5172affea48f4c0732112d606ee9e7c6622256a94da9eb93fd94fab71c5ddf4c3d659e7dc01f109cebc6255dca78d69eeb5e5469d22eda00414991e5b3e1bee8d9ffd3b3c7aa83ad182362090cccd044f7bd4a33cac77eb38d4badd1c17dfa0cd3ef154709ba8bbd8dfad97bba4b598d7e08d139d9eeb0fd6c584e725f6555c40198d7d04ec386527b48f0d9c799277186822ccc0860ec7b2941d9afa62eecbde7c7878f52d72282663075d4763214b2ff8f0dca467d374291a1b39f859141c45ba5180e1675d7661c125e238ea9d2a32cc2147accf0a0b5005893fd2c237a3c32716f51de361c561fa5c8760489319b4114c8d9f5537ff4de557f1cafb3ded6b177ba984b50cfbeb0f0ccf0c674e87b1dbff163944d9142b33c8bb80e96f1dcdbf22e134b8048358ded7e78745668d1adbbcdc74cf9f545fcdd3c0d51e7415812c7faba948b5c9e35844af118a156f20521cde78e8104937dcce69394ba6f0cd4d2ed654b39f3bb9dd479ce4b2782651ead007a496425eff02d54450097319a091215a7b904c2e355ddc7cc39ecfc1f578bd2caa20c6840dfb872cee19151d96c1a23064a980fd75436cd113dc10c9d8529ce09a819672848bcc2dc5058e19b42057b8c8dc529ce098418b72858b8cd5d268fc5e30fcea55ef03ea8f8668b7bf480666deef0ba9ebf24b99b88b086596999c106b53c093a9d69fb350aafe98568cf17f7d14d85bb7a3510a05a025ae9ffcb0e974d4d1a864ea471d29ee4cc7c6f21e05fb2de764b2bd31ef688a976845a61657c544ad2ce9e8d245a5926fee2d7b008982320650e922dbcd5a1956c86d8c8325046ff067d9223d42a3ee364d9b55deca5d50d44e42e6ff68b1263178fd59eaf4ce01717699ad5a6f1f552ba77126159960fab3b06d04d0c855575302550d735c622866b863b56270c5afae4bcab51b19228d3e9f6b1463469b3b286e208386e12fe203a5547a7d69267cc502e7aa99524365f1cb9989b0eb5f59fd11f14c4efb9518f224b994da891234c733a420b8fd48a6c126dd6acb47f075215cb6d7127fee9c3ee7b23e4808fa2e4e9d0bee23a680e4ed6601abde10b2ce5154852f01c8d71e8f495111008b3d9d110ebf82b6b05d52a6e9ec050f8c900816d3fde1652db3784db50b5fc47ed26501ce3224be5aa972bbaef6ebf0ef3e5c66248b6967fc69ec88ae155431edfcd4e213f8560af7529baaf93b46a1817e9d3e4a6c9292670182b784ad14dd1aa1e9e203c5f6e97c824b209921a227fb7d490116eda374bf6f1370858cc0b7c29785420740708c0603095ea18d6d15027a2383abee39be7ba8789c4baf3301ce85c42cbfa604d6bb7782d9deeaa860621d69a29fac058ea6d49bced8d203a16c14fb33017e28abc96294c5c5103b97d60f5b32a3a8046a33ecbfa65e9517f39b0957f04f92582994f7cf0df6396579b5a70bc27803237f5fce39ec578d58c60e173739a0112e61501c06f91d5c5d1f0bfc545c73ea4e232fb4c5a9929708e5a415d2ee455a2c565f5000ef9055f3247f46774289d30f5c8b23ec607f3f7812ec0fc5c96bde076face626b4b602310adc6406b7a91b85a165b2e7299e6368cb5fa39211362ecfa9c021baeb2c60845936d38867abf06201106d1302a703e5a47ccf04b2d59194222be45ef1c8db17ce721efc8db8282eccad61a7ed43e882aea92d86339e1ddb79072dd4f23a6aef93fd33e8a3b775030974174a6af08803f2a1132d58f508751ac246674763ea23d927d3d1cfc2098ecc0ad01cc62211592b0c6cf421cfd48ce84606f65293378cdbe414937cd49448b01240c589ea8b35249502fa9e5c19de801f9918f7e16ad7843186a0348617925d59590149a04ca4f7afd763d4623937f48db86ee4271534c92e2c54e32e0f0c7a323af11b43f294244586ea35da69a98973f93638cdc524c48f98e0db6bf70e79a149e71e158a1417d53bd2f1faa2832143c67a1c61968b9e77f9efa2f27ae3d004b6064ef7074c8b075dc6d73a85611b8081e13b7593c294fcf1ae299c98db484e8462ebdc9d792b09981ca993a6acff3ba5eb38297c59fdcd97c7abf45e294e34b14b3f9e312c20c6a3bacdc7f048a393cc8e8cce07efe8324f4f4b5868e518f43d26199948c860c4548926e042fa45b8bd63369a2f081ee392c685fb40a440f36ee8d66cdc8a36fa06723b5cb04e40792fd202bc0a5ea5daf8f2a6ea21979d0444826d3e701a993e92bc9d3d38b4d1681a5bb975a5697993dd0602441d219d035448eb5f2833028bebf2a13a0b5fb1d632611950f63a5a8bd592065668a3bd0a88a364fa4809e589ea4fc391c9a7d3da0ac706df81d67295d11603864805f71dc4cd2e48c92fa06e50a7a3f6a2f744ae980e0a2b2f4183d13703f58fcf6c143201e4d712662438ccea8c56b33d3d6ca536aa672aeaa8e6e34a966e2da39ff8d17547df7272931a452049a31f909a21148d9b0a9c45805a6432b218b751bdc526edf8663d6c073e6bea9a6c1d0ccdc8514a9ab735ff6044d4db00c91ed527c8b1be2fafba71008928f4c8b036622c49c2418603c604b995590139c8a58d06834d0dbb1afb62a36ec0b461b4f3b86be25195a8f54e19d856656989b51a9fb2d1240636b894ea2a11b132a2d7361bd56e1ddbdab217833c2233e4b35156174da0ce346da485cde594e4dfcd216966ed08c50f18858acea1965c92882185053383d14974f3419146c4fb8eb4e967749457822e2243f2917b5dd7ef144105d06dd4c024b5ed7eee1561f6e44a119daf4cee8e0a3e820583bc24b6d111f5bd834b8153cc4653ed121a06bd41771f650dafdf6f9c0bda946493dcc30b4789fba2565d76916f75c4289304016c103c154155c96bc0e8c45ba66cf4cdce5739f12d69d5d6e8431b1e45a3344158957bd7a960e243423a8b78e96e63c2dab46e7999020627edd74217ced48230f15e23c928a158c597d86d1545a3af37023e3c699176345afa861022782eec8455ea521cd046f4308de63fbfd9b26ea46a0eb9654d3b105a8209fbc51474dd41d5ac8e6ec0599191674ac0636b0aad9e47c89a706b5a5d48560ab61adf4df44eeef59de2074b80b2ce0090c1bac3fa3727d9190c9571dda596e303b103ae18cf00f28ce7a02454276685a7c0079e3fa21998d9604b2eac04bc35979d3d606edd74ee1fc31e2fe7b31b5bb85220fbe62f929f124a4acc77a38b5c90c5dcbaa09d9a1578abe71bf9559ede3300e57223bc81fcd0cbf355ed6ba01f0fbbcdd983d3e8d2de496bcdb36999a0e40b2623b0ac081ffbb499b20fd3a9220c28cf92d73c9c1bb9b0e0188d1e87a32c84eb8556dc42616bc3a8060f2388e4e9669b34eca59d584d6fee58ed6b5764ade8460b25310090cc86cd183205e8115a14a71962c89904123e3ac40fd254faab4a4702343061b2c4182a5cac25e5ded10b3f001363a92eb570aaee60d84b5d8b856add02d77606dded8112004c7af8dc6a74077cdea908f9a0aedd0b576a55f470611386e8d8fef90f9c6ca9ae68b3d92443f47fddfbfae5762cae3729debecddd0d580aef686768a80ee0b8d8f40d50dd386144fb66c949f3fa775a01ee2d9950d7389b6d83af34a44478ec2325720a503d77140b9f3bdca0f2463345d07410840dc1a1892ce0891cfb62e72b92a866f0ebf4430333273e42224f7081f73efb9c2fac103a8755c2a95233f702ddfc64f727e85a0ddb577717fbd17f7d8373afc013a9dd25d75cd30c0c477071fe776350a965dfae3522d6c11bbd344368e2018a6888ad85be35bd8ca129a630b4e17c3ce880d1ef25223032d56e0486bebf345674029c7abf3d53ba1caf4a095e9280946b9d2eb8cb4b5f8807c851a30ef976607b288a116d05d50297fae6f13fa579eb713b5430bae504c2cc057b14c95985a38f1e0d224c79c553bc661755f76bc8b2e7bd407fa3cd56c538d18f3853e8ee016a7a8f839a2e45a3e8c9cfb8cb76ab21c8c43bf6de1591153884bb167c840163213c5ec22c2895ab6d21ef4b589739f33e003b9a67413beae79aa6b24ff7d1c7c58a1f1d5b874010eeff3d2306c4ddeb65056fdeb2c7e447a3678bdde8ad585b7a2356ab7788dd426f21d3ff0a147207eac335d8c4507e3621f785e4f501000dd47b58b12ee878ba35bab4adf96cf74da6f0dd41bdb804cd7e791c372c565f9ecbddcc6d88a1de0cba0fc6e07ac9d41fe5237a1366a1feb46eb46a6d6ce81192e8464d4894da9bf68877e245b5beda78b3efcf458c3a326a6b34f05769d746cd89983b6abc5703b8953a66d5ff2de5eb5bf624d9bcd969975bc6835efc065e64599173b4ada7db4a377ed98f02edb10218c5ba17452211ffc9cecac4e0415dd36175d61469a62195badbf11508327cbedb20de4a76f011b8379f439eb1dc42662a6db13a8e31cc663407e7001abbe2cabd1af4389588247abebea7dc4adc456b3ea7b6c0d963e669c21c330d204dfe4da78bad28c96a6d0381f21b35b346c6a47b76d53414e0cc5f7086ace77042a97308779bd4dfc136ddbe54e61980064abfd214c9f6646d12354ca8940de59adba9309c8660e1e5d9ee1f42c6465a6edfa4d1e33f898edccabb84562a3b9b39e52a0c7ff3e2bfd489bccfd580a54000baa24c6ef764dd764aadf5cb962b7813e480def4187ac903d4296048b40a81f4fc0a91f3b3325143d9b313b4fa9d3e721111280cb7f9906821da975d6f2336ca8d36b92a56901b3e431fff9e1b1c2c8ac3a063cf10faced62ebb45f81635bbaed1502ed4d1a4f70e05d1b52e033540e3d8ecbfcc00b24443006354d594b8417028f6b00a58631df406e8251da2fa668d1895f0110af1e1a6aee0a100ce42ae417dda4291b95042d410fce718392de4a96f1addb555434950b1b81a4ba6f1bcd9b851f5ce01821ea0288ed25f1dff1688513676e3e29d730b1754f595c9c3882bf551437a630195ef79cb59d8e8be826fd6f8af57ae10c36ae9a8fe4ccff7fb6fbf6414232be69a0e1e57358f70af2fb7766e157a5aa7cfc41f27d46e2d0f8b63cc726544aa32dc7205cea928c6f0613927e5d488b83b8e03fffd3554d8cb1ed13e8ae43a16dff47f8cee49588b74b1bac276139d9a15ad3cf04a9f3aef7ac8cf10b75ba5afcee38c904b99d0a5d1779e2710a30911fc9e18cc681c080cd645a83e89061795db4c89b9ed9e2d7146571afaccf0bc46b78337b320ac5dfdc8dcf2061b3b11ccf081f6a6b0f89f73c21192304520dcba956178418d4acfa50219339fd05e68dd5a7974e162a9add00a696b376c8d869dd9cc1d497d438fbf7277c61cd9e1f9bbd4b728403082606b908c3ebcef5d49091dca8798c2b3e1278200ad44d9d29db1050bff95c96cff50e73b680060b6e40d69be5fde7545aeb9dc53ab42b00310401d185be0509f3ca5242c68e868eb3790e144ac62e0f4432c3e75b752fc4d89e2bf538d96b9201622b4f938d8479c876746ec69abe8f2905cb3bfa7a0e0b8d887e45a95edb2cd5899f1f06ae16acafac429d011a1e1549485e473df0269b8104fd802c5e26720b7d13d0d1415b6009b26401205449fea52f8305c5c23a83311bd096989e1c8b3ef2f1e20559ecbd95b01b8a5a89b2012545a724d38b0f588375de55d138280122ce04a4b1c3fdc182c2f02808ebcfc1c6e0fc90ccf7e4337eb455251de7138be30f481831af31a33718025a5cf3ad7d5fc75dd7b26a41c53493a1cd9523b21ce2829fb1fef4ce17112b8058a12f2e928b57c0782317a30318c3332ed193df6df2f1605e4e98396ebff831c366d92fbe0fcf906cebf27ecc022a071bd8e6e3939899ce6a523284644bfafaf2baf0a0c446ee368192041f52ea8899210bd2281427848a48dc574f4b9ae8e50384979b52422b7317ccd1204ce25d3a11f7390c1edd9a31fb05db226cc635feaf81f04ae9f9f46f0f243197696bab03b2067d82f12588726e67874a85d603018f75b34c53e2635cf73d80ac18302ce28b237534c53d953bfbae53dde355c0b0d99102f2060b520952a43452ff57e969517d7f533c2d831e7b2dc7e0ba2160846a619799db538791b6f3e5f5bc7cf73a83a2029d57d93af8fb4943154ba60b33b15d175fc7f258535b9245402181526f54025c4e0d123ad567344e403cacf38e8fdc6c45beda791071130883db4e111be5f51264308f9afab02f7f84fc3fa1c92ce783162183d14f1265e952fb7b7d47e9fa16466492f809be2a1c7356d42f1d86748486b0031825fcb8e5d6c9f2cf355eaf7c4acbe5c03ded8130533076aded8851dd0c2039c9cd3e772c33f9b65dff66932234699dec048e13c23a0b5dfae2b3ea197a61bfdd6a50366767b07c6b4604ac372178f88ec82e1a502a2e68341113b65eafdaa4f82c7bb7cc8f35db5329a1b977fd0a750a3c4cd01b09aff273e67668ddf3af947048b1d70f8c6fa3e00d0e0fa044e8f478a9303d3ae76474d167ffa0a330de609f5ba31fd91554f7749f2629d5f388f579c514277f9ecd39a001d750b6545fcd785521be3bc2efa7e32a2c4ba24635f4f198ca9d6c652d52c7f8f6ef07200a76d1a0a8f188f8f9b32fa7c1b7267a796ed21697aa9d9165b0e125390955210395ae7ab552485fa5d836cd0aa93e7bbb82a72700f55ed282eff942b87f47d56fc0f080f76284571a660fbfbe646d666511d353a576361b2432c95ecde871b15280db6cfeba886169a7d54c709bd4e2c8abacdf5313e9a1787a06f8db5d15274b2f5491b47d7c594933549943ab5b09a5c2b8a058d2599c090169606dcff1191730c9b4082aef059863ec517b9e41a68000eb102e1db97b47ec9f72c591a8b4575b54fef2d58c4de8dc1c0cd8315d4c429ffb1fef19d44d61b24814e18ff8f014fad128c978a1fe8f602396b420cc1541c678a7bd835500a71128c4471b3f8c9ad881c81cb0223ae0c1c096dbdb4f81bdf208b5065c2e8ee107550b5a9975755a16480760f108477324cbba37426f3ab60f6bd16b8b3e27bec7fcd06f8dd6c08aadae3de2b9e536f884d5509b7214e25a10696123ac90001db28513fffe2c11aa571217582db519a816ed77473404756309a43943576ec84d75813da7891e73d7f22d4967fb3cc247f49e89beb1d0c7625b507a133880e4674b8e3012234d3cd2f9b513103222627340d324be4a2981c1cf4ca54ef39dd55cc1ff0a49f302a501a9967b0a6151e756ad7fd7364471a246562fee470fcfd03cefc2c0fa969b621954c56d4dc355008340fbcbf16c10a3d06db7f41a5c6919887e8944b82c46f242ddc99bc276e37a7d40314c7ec1c24c8d076687708a928533bbea2860ef11eef14ab152696e02a01fdc94b92fbfcfb79a57c316f5d4064122fa057fdb6c4fcf8e6ac0d2553da29834bbdcfcf703752034dcad322e329a3528ea85fb251ce7e520ba944904f74580678a9b1381a192f3576353daf7f6e8732c5ac409f2458c8f905b93ecae5a88aac1c02b9198a894c83b8be92612c01431b86ae4fc4fe0e9f33f1cc3d448b342a9f18d1d2eb56eafd4c0d64cddb06519d5b9bf9337984c5ed7a4ab59acef3f7aa552e03b07d2bc5d931c78cb63e1ef0db3b1b5051ef3c6baff497ce76a141c3a3baba49dc1a86652d7bf7e7563406708f85d05ccb1f8739ac1dc82e4fae39b84095fac931c223624940f19ecce2024c80e6cfb71665b0022db1908c0b84af7b02e9c3de81f4b57fa07cec1f181ff70cccd7bd02f3758f407db82fb0beed0bb4f8e8bc5485ded197d784e96428f7645cd9b419e0a69259015d464019b2325160697d1b9bed8670ffe8a0ebb071203bb4c1b59b099a1b870e028c7694ed50842e4156c45d496daecb727e2b1e55dce629f7a8dccaebb23ab442647168c270afc887031aa2ed4800751c12f4e1dd3ca5d9987fab9be5d38309c08c7d8859d0a0392dd42ef7c8066bee75a9b5c610595613d8281c8aff330910cd2d581df1720242b29e2d4793491587d31a62971d8d8ef201b624ad7ce4413f78ade33a8f92e29cb9ff41b2e7e533f064f204298a3a30701252b041b57130a120d4b96d9df34d047ed2f79d7aa2b70b50a67281ec9c7c8092a580e93f41b23cbc169f666883397de29d6870498a069b076c26223a88611fbbcd367e9de9b328f8a7e22b355495c975b32a2c7781a95bbdfa6c55c6e2d218b50a342be4db59bf0a6d2bfcb20cc2e820113f1270becbea321d912f81085c1f529e13927acdad4dcee8497114606bfd70ea85e3c4c3a590fc5f7ad9dde5b1d228a268eb92cdec06389dcec97324d80896b53194409b0058d5945d402f514df1f5540c373d2e6507378602d90d5d870c821fc1b804a04f5def7cfcce434d26ce968464a3011b8711bcbe312a18da73e65da55d0a4119fa93f99c89eb5814a1e90bd5c07791e97cc53457270d3bc3ef0986941c183d2a559da3dfed3b3fb13ca5fae32bad7953598eda35b3d75824188cae606be6b4a0cffb674bf834ef6419a4629d81ec3e93880c37a53869a4286384fa919e822a29e7cba6e348e7123433c261aa37a7491d189a94e1040c010de3e0f709579b4668d29818de8196be73826a8eae42e313c00433eb63ed164a9f5226dbc706434dfab216b3d4a611bb01c6fd500fb17f32f7a0fffe7f91b78e24bf53c790234d4fae63c81c9c1452b4928cdfa10d7b50b2f187c3f4c2c3419f20f67e675285fb0af592c3021509754613063000bcf4ff664d0616e796484a47aaeecc3277bc1641d58cebcc3b8d0f8dd2cb781859ec7aad4cc1fcd28869a0cf517734cfe8d5e78fb9209d62d67fc3ac9c2d402297bad8b082aaae58f5206138067de39bda875caafac6eb271d8cfa6baec2200e1a7f56b9a53848054eca1a7a150260a66169a876ea829a6da1104bd0be85e42b3951e4fd1cf1f9af685c5c27788559f03a497f3b14afa6b74c6280258fee36367723495b7413ea578e77ca6f144aa71a3d52dfbfcdcee5974d273d44cf6369eafd1839b9863a75c469717411dba32333fdbaa863c5f5a7b1de9d47f2ecd83dda1706f6026be06fa66ac844112eb42c2ed8920b5a24c5a9872b46aec17d01b27dd7258013f4a93819322ee19772c98082e6bc309f39c97247a32d7aa0e64df9dca8145b96e880d2683c53d4123d91b6e64fd08658e3debe41bcfce3c208d56bb639fab8cbcc256490fb72f125b44dbb323509156aaac646e9e612e4d5dc71f20a4f87dcf8bef373acef5af3effc4be2df749acf6506291dd0047105ebfbb696fe4dd3a144e2f15f6384e905d8dab982952807be9054bb6cd1cc47b3f6a32390b6a70358ccec96a6126cee62f38bdabec76c15055a45a5a0971130e8da4023577b626bab68fa00451bc8bb79782e9b7bb59ed8c790341059fbb579fbe40dc8ab4e252db74a6901df40c031cd1634013bdf9c32e290f721862a951b3fe4b21936ea87c1e473e8c7c826c52ec44d42491fd9b73a9e0f267d96a8e8ec7217c1946dc42488439ce1889228b6c7c6dbee3feb02b39dad7d9dd1ca09ce11a3171d19ffecbd272f6134fe603359d7ab56ec0f8925b18523023042ee883cef1df276f61d3329309780103582cd2655d235e6d5ae8f0f0345de0f856c05c18ab9c57aafae569b4b2dd5171b30838706f36358b4b04db70cf683dbdfcacb70cfc564e9bb3a04521b59967b5e4551b88a39cb5eba4a8a78acf9dcf504fcacb4250d785f3164f905c073add38c891ae1b3af89ed67e89e29e1903e2c9f8dfb3554be6c29366a1b1efffd728424edddc063ce043dd6ff312cbf54251a44c2bdb189d65d8ae507602690a88d6e84ee5c12e929a19a6012d5cfacac7f868a156ae4bcb12b8de2da5aba2844b4f9e50525bfc81504e7485b0122a56ca3f2f8b328eb9237f2e210d8cc4c82b98ac493ee1a7727314d46794c7ebd581aece23831dfe376bdae36e7a5a7c69e80bfff0b80853eee44a0a616091d12c38704c351518bd327a90c9b9db44d599b7a0c4cdba3b3d6afe38f1092d2f9fc7540dab8dfc86cd0f622ff2171652aa0be63b22a49ecdf04f5a2775111d93d23249d4e6f4e9a79ae5ad5274b139ff6b08f5bbb2119b3528091f764dff7c23ca36c75fbe57f906464c5323156da6464fa521aba93c8154f8203566ae3e05dccb98986818836a58a8379f17ad310d3a77299b55a17b031432e4b6406775bfe92ec9a48fa6127046889348a95471b81452bd78f1786263034facdf63c74dd3946c29cfe11ca363210f20def17d51b045e46a644a749c20d10ed0c8ecaaea56af8667100e711a8e5238425c056b11f1c38392d7c40e852393f7e8409c3e0a7041fc76b514349224c8a2149e0658cfc89bc49f1fbfaefaf7de257278b9b90451cd99dfe9f476f731cc6ad8e7b63388cc3a874ddbe086ac915e6378e4443666ef477367c36835d9d1e755c658f5ae73ab0beece54ebbfa1dede51a5a7b539fe879179fe9e58a489282089f0e34431013f15c537287ae2d44b200f4639ae43a15da30b614c6edc2dd2c3a3a7bb12d9656155e61087cb29ee46bb70869b9cc6dbd35780e8f2c12de32d18b4fca8e7232179c14505bcc4b6a2f9111280befe35a84c9975e672f7b41b4b9b78c51c5b7570d2d0951aff8faf4d70ed6341db63a92d7520a92fb72ef48c9499734d05a175262f5d25b5fb68a4de9ab3596b0b707932d0023de8251e91817bf07022c43bcbc8e506a9279d603e14fd09d1f8eaa1a8dba12b5ae4de0069f4268cafbad760f515fb0bc06f2d5b6c95f8ea27c80dde2b350206c024138c084034ee4f419ef9ed7754d649f365e042b2ce4a039b0246d82d15fd8e63f74e2a06d46915a858315dd833e91d9f3bca104ebb60d57545b08ea8ce635075838f62f500673ec8575bfa76f69a548a87fd07f5ef58e798c8c51fd40700a580f2278b1b07a7ba333bbe30460ef3c189b975368a1bce5a2961fe57834d4b30ea08ff8144022b9a65a2c22b04ff0a6afff23fd7f32a93a3c24a5952d021e864ce86dfae82c3a5846c239b779b049224f1bb3815c403f1727d39bc378cd6dccaa9696a079d2104327385f5637000a83ff0bfd0c318fb6a8331279f9c44748975393fabe542f0a17c471be4380efd4c0b58cf28fb5fc2acc1775833920703158ca1e76319f6cfdf6bc1f874ae180540339bfb9ebcdb4b29ad903b4a98705585aaae10a3672193e9498035a8badbff7e363d081ee1a289fdf76ac4c23e3777de56d8c13f49b9829b996e2809a6a227a8789d8942615f413feab4ce9cfe0089f3b86a9804000da4b8d76bb97329ce0dfee71ab3672b02c05639c08b41f5bdf45a421a0b5a97bcb807cd41f0649f4c3299be0bd83470a1250a53278598e2d2df78437624f05cad1eeac14a9dd5039ee0374ac9fb22342dc77281fa4261d929882464e5957ea1cd6ef585554540ff6474234ba89e21f776524f355c3653547ba1e93409c18dea41ac39caf507ec801a83bf991e56113b59b02e4183ccd6995c66daac675a0b6403edf4b4c4ce5254b400594ab1c35d11b9ec41b552c2723a080805af7572859d459e940c334a56939286086d2197118479529e198298abcf2861f32369190f13b3ea457b71d6dd8455072039c8c379e2ec23e000dc8311f23c7b5af479e30a88db2cd1cf2436e35bfc9a0847af39bd01003deae5902135108cc18c2dcf7d6fe2e36810d2b5589c42f329a3ea01b8515a95914c9dd76ab202da26e0287ef3dbdb1ecdc281726fd44bb6e5728530a3e4bc39ebfc1aa1a1f86807400b2195ec591f16912f0344eb027a39b3cea34e22df95d014512485804c74e922857af57cee857ca7f4620a47df50ea301a2dce18653d73b98653bcd83d976c31c35746756b40aac3588b8f4efbd11c89c810cedecaf337a75e7f2b1d4da635dd93a1fdf516aac3e9d16cf1f90a1ed6ded548763e8e5b6765a0d0318bffd2e39feeea17034850da3f84de449803be8a7460286498982551f3b1dacfc6b0c26abf2e8cb4533e570ffa6e64a9999fc3d586a8d2482c05d8ee8c4d337b72a1cadc4d74bdbe2e8c380a2570c19a970b67bfd0034633a3caafcf11259ae6567da2479016b94bbd8d558d646e6b6186a4e3a392a16c44d742dbf5dd8f77711e65d709ac3cce16ef71e05e93691e4d52cbb543585531a396c5fce17cae016c6a595d7c0668a75480057bd0bd86b6d506e1b70d9e270c3d6fb5a0cc934fa01eb5c5745b8a01d8dac0f8ba2d0116f37e1e34f0e03a7d368b0231a7c3aa8ae46e446e148ada84e28090bf59626375cd9770d1580b9e2edc27f680319e648abcce3d0324e424363ade950451675ace09025acdc62f0e102055af895959497a505db89a3075f1889006c9636e6e38ee34f27bc13d69df8e00165120f8ed7873a25e5bab52376b14eb2019c2b0437576cd4377c5a487aedb2389a66abcb2122b745f2f59a022dc6d9c76b061c99c67e754932ec7c0a6e7471c31966e878978c49717fcf83a5867f6e02f0b7d26bb3304bd002f1947c41f54be6d5ae1b5e135e1e586c917fa63e8b7c0ca6a7738c0c097b67049a582ce2c0de634c1339e966b520c1421f8a0b68d57806766fad840cb69959e3705ba40ab3cce395292dc76c843c80d403ea9b0c8a9a69572ee6303f0f8fca11fb62a416945f767f530b05e9365f5f10460f9e9ae3b27c5e3e1dd7f06029b26bdd8e8a640ed1cd60a9d199b7d8d0316800c6b42d2d441437c15276fedc0e3f9f07c90ffd8523080fbef4020aee9b99f17972e220557c6f8121227e42be2c8163413b50e969e53104e6ae8cb7e449bbc5e01b7ef1e864cf36aa66943f188a549e2e538282fbe707289cfde11225ec7c6fd080980c757c2cf1e0ddac7eb0804c753ffdd41df424dc132ef516e41a8201c2912967ea7a840a189b07748c06bff88172328b1b841f6cb0bf5efca8ebd3c941df189c0e62f1d336911ef34c85f44fe31550632819fa9c4d31ae7713cb9898456f4bfb7a1a632e4863aacde555a194ca8f2346dd2e0af45f14c7a57e04a628840564738f421f7cb2526dc7d329533bd4f2646d838699b3e1dcc2338150641e70a392a7f5c47f392ba431993b9ad68927ee9306e5ee77b0c512a32b16305ec2e1c37b218607c00b3eaec9c4dbe1a44ae1d2b2d4210df5506a0e54b32aa1967456e7a305d35788b5a849ad006313ad0b6c9a41c83c20fb33a43eec89b5d87f9338960a167085347e723821e7145e494d1a051f0dc78f4add5c2c8ed4db263486bb821b37c32ba48812c6748ef74abf7108624e88e9b87e7dee8f0c0294790000de4a63bbba3a9eee71cf0ca494397410e7317f78a9030b4777af522cb51286041b0231df81362f21c66545554c7789f950f3f570c0edb5f559e6683209de222c0fe75b66c52b6c7811cc5bba1a440d6a0af03078137668140217765dc13e4a0905047fb0ea4500665003da0aa06f0f12bb01587123c49d81ae31394e379433ccc1f9953df03260b08153776ef03207ae6b55369da5ebdefe868e29dd79a16ecec556984ea9d1f28e29cdac00b5e67eb7c0ac04b7eaade3b0340f4d00ff446054d2143cd5a1428c156c946c1f440a48e836cb2d141e6e1d2e8261840ca9fb469207471c07dbf8aef3344930dbe7797705ec7c047ecd16c4bfc0c4bf0e69da2cf878d640fb178b2525341fcddec31427580694dd1e64a77cce02158da67c67e6f6e5e64e746234d4aa2ecb2c4180f89e0d2e620365428b2375969996248281dbeb0fa86878516199dfbbabfc5ba858b210386831f45f63330bb8cf527422a4e4154fab2fda9abd689b9050fa47bcce18d6a17e6e7e131bce1663d4c4d8fcf666fad8626e94b41874800e4ec71c6cf2c5481a17dbd515a8977e01ba160edfff6b34a1ed6630b737bc3667f5b9c8915e663ec7dbaced5b6b9bbec456a18f6339fa68108d5009fd407480c0178deada348fd0836c2115a14f66c9e1cc7a2fa5c810efc9c2020754dfce5751866d6b90b2e258f438f2646a8ade879a2a9523a7c89231ee57d3978d28920f9bddb9e5461d8ff1f892a5989e46048299f2e5172c983521f635b5471101cf83947e26c7771f11ed5fb9da08b363976c142851a041dfb609a1cba4231aee07591b053080743bbec1fef44df71bae45dc758d065ba1a58d5229998023690463b7d5414cf4e20bd76121aca2d98cb60538467d3ea0c855876f39b4b4c24c4ea0f3b87728002e0da2ab492f2ac7afe7e578ad9597fa863376881872795c6283b68662490347b5a4c00673037d44067602afc0021c974094df879da7faeff69421b2dd99bdedf8338da13863e509cdd9b8f3834ad7d4c5bc6bc29827a12be18b2a7ab4fbb5f5327ad4eaaae98f9ac28e9f1bcbf903cd5e7060dd3fc37698ac33ca84d3ca48914563ea93b03aa252ff74d49813f88a6c98966a01962f188421c5646963f21c65915af102aa1835dff9f464d6609e2a241b23ae18f8b84c7914c264045ca76aebf31659d73eb58b66b56023007122cd4750c6e7bbdb3d43e525acd1b7fad3990cb3964cac01d49733dda6cdccb1c2a732afb205992b6c871df434caa822a0135f80ce479f376813f338201550f4f0e54944e8a70b4eb717ff6612da267730e824f57b1b25ab8eaf7eadce4d73e1d59aa6dc95c595f5610e78c5465bd6a30d4c87265430a7638409e0791346d86a980bfa9eb5cbc0a00dd451e7fa9751ca6cfca80a505e06821ec440c2e10fbc91bae77e84723ec80e8c4cc70faf0ee674b64c83eaa5929cec9480f0c4564d0d73b4b08b81ffe61da3545a8f0ef1a4d5e09205b2f7767ec861edcc6f99c35285d2ee30249ebbcd85dd1c74ba2329fff05ac7d74cbe7cd0278e1e31053963873d5ec00d975b73978593601b4bc266f4181520fae4f066a5aad231a6cce0764520b5250e3925765c8ce1a47b688857a5bcc6a86f95b08d8f363b388ebbdac4f48dd94ac8564cecedd830023dc15643649e913c3052ee8122dbda119baf1f08dc030a1258672125c900591d6d567ff63468725de9649c9b676c1d9e1566d97e8c2ba540defe8c6f2a63a63bca915361f0845a3c12906ad40cfa97cb23d4f8ca4e820edf6341af00041c17b290585170b2850570346fc0e92e83d9c1b21ba74570089e0695113a104228373e923fa864939dc555fb8605ef9a3f7878c5050d1e58d00dccca62c53aa594ac8d3ec4508e3dd0a4701997e4169608c3f072e4be6cfac817647ed4e149ea081dc13e32284324b6dbe8b47692d9604a0a0efdc6ddfe7012d598ec9e8c40aede3cd58e1c1a7b991ea15e46374b94b7043a80c23b18ad1a4dcc81519d3ec2cc147e840eafff6d67e40204a10dbad50a1bf43db478355249246256318f6676162c436f5c7fbfe6348493f7cbd80b1e9f213458c24dd751f7e53329e2cef76b965202111cfaa19e83e812de8d499a75435dc5c3cc549a2bc6d762090405f9c78c8fc56beaa86dc1893baa0ac764055f4ada239ad9efa264722c5b3509c709a36847e973e7dc608c41a07f64567ece54004f759e8ca06b6effa89a46c7c4f2071034a8d0392919b63f1f2a6a55b312be26a1f4566f669654fe12c4423d5e66535c4a84ee3ef2d7cdafce540e2b31b821dddd5af300ba8804caafa9b7c280b4dc12be033042139700f9460290ff97efd8a8a312056689d1395d715631875e4e9969635a9e4b563d9c2ba860bd9e1f0283a3fb8f802c40aa9197b00f56cac54355f1eaec7dbff85110ccc92ebce60a8714760ac8f3d512a080a26de2633f6dab4daba8011bf66c5a3d945f099abed4170bc5567ead822e603ec0999486b4df47074f7ce337c050f62223c43cc4a2fded18ae3c94aef5a13cb115b45239120cc5ca929e1659888c6e6550a99ba4c167c9a658276b28627c712fe98a4e6886a67c99572c68e5718c3ab697b2cbd5a357b1f767b2052b65868095db2d534142d65df120b1f3a9bbd6d68a7da1688916b6db90716c769caf63fa8824148ee43d798146f0d4ccdea230ea2e8629623504e096a96cdacb4ccb4e27685bffb0ea45cd3092f3baa2cc02348eb836e5412f4a836e9cdf538070ad3243432792392ece4815a136de75738b94d87dde636de98b172ba69073f5ccee6d50bdbc3a650f8f7eae2b98ad2af8f8321ff60f394d4768225f13ccc013929ac076ad5582837609fc434b61913f1dacc486172a1a1760428f1a51b19a3ab763e71350b4242cf2eed8f938783d96db1809dc02577c986ef5a497ae636fc4f1f09803b6a66eae85d8c766839cba2d244d6b580ac138c240d441f3cdc1c8688f0b544731cdab54a7338a33bb43d1d0f32e4f0b3f027bd6c00d27bbd0c9d4ecb7f99c1e55b26a66b171f44a7bd60b5a823a57ab066cdd98c43480c6d5e03d6ab005946741306c3a86a202750b39ce4ecad8630d7081a3429ed4c5d911d1f46430be6873bc403b6c477912ea7ad659d1fb0137648e279b39635261e7550dc607cd989063bec953a63240582dd5b3d70024af6a33529b0e1a3f7340153e44168e0701458685330388cb8b5cf3b529c84b3191b1dc7361c559726a1bce1e72d241d28807952250aa2e089811943f094fcdcdbdec46ba7d7a6a3d9db4d7f19da5f905cbaf49935772862322735da5349ee61dae59f9fd99e754038c6b4530e82a812c5a82c9a810a2a5b61295d3a151860519b8f344343f56a2ebc38023747e9790127ecc16cfb4111a4b8b9e1f62d3c6659858c66fc929c20ac8c34a890674431344912f1a8156e1e68a0310df8265344dd79a548d418f20c05373e2ce83f687456d3ef1465171605ad40adc564e54fc2e17ac6c176dc9cb58c4e1049f28fe4c0361ccd914b10f74bd1c251b1bc27b02d7d4ef8fac8fc461419a0a6e21c624edea456b55049e9d10f960955b6de2a875f5269585a6748a7e5854a7ba1ac9a63882e8b0fd4bfba9a36113647918c39c1ee14d44bd31602a43d78b1617b72e9b6e64749258230c088bbd8f510a9355d3388a9904dc117c4207c74ec512e55c2a4a3b8fe9a0201d10d74906e003c1fc81f405a740da3c0a3d1908527fbfd7ab01abd9a51960a111d6fb654fb22f539b55c4a5b643405ccc62b6acdd50105fee94ca02b9d1578119246964880d2c1b428a52b9f102fb6385d59c1ae49a3fde0263741724185cd10f43381123297f4017b10d8c929bd10f49fcaddf6e9a0c33fc5a779d7a11736e86a93b2cb0f5dec09200f96c26365ca03a57304595b9a14d930df44e3ec3195151919cc3a51cbfcdbce6d3ac4a5bff072e9890f8ae0140d54a029d88a49850a437cd671bac8bd3502ffbac2fb09741d9ea7fdcd7da36f3d77dd11b3736372222fbce6ee5db80bc9dff0d43d1d7924522c50b1215805b46b8aa77c93052bb19aecafa2ad65fd06cadaadb726d7e1afa901494b84e8e2428dd004273e88d7bb89198c3eb5fcec4d7a576f82f4f49b37cf231263dfe4c82a5e14d192709b4421a8cf1b20a9fcdd60fc1972737cdb6cebf09296210793b2d62da98b722f0aa000f58f2676c8c1915c226a9952c902cdd824a7bb455f7ec4c6a6f7e63fe0483efbe8894bddbd51f0c6baa99561bc766610e660cdc667f5c4febd2c2332dff4ddd71c0f745be98bff3ab631ebfc28cb8d86309b6437c6e0941c8eec69370c56a809ae4c8cd042f1420d478be02d277e9029e8980ad974b09122cb3eb5520013d840cea57a4097c5cb746c788bd6728c98b7719729fd41ea00418dd62bd2af152b5a7518b560414b5cd65529a8c19d9d8c95c8855c2e113016e34238660efcce573a5b413c22d0c4f0d89bace2d4fc6b44135e838ea371406233362e940a25c046e87dd59bba7dacac9cb56b41c4b4e1a0b9e85dd9c586cdd17b875c1e1f8869423b31cfb12c3378ada89dcdcd0fdbc6a6ef531647ebc718525d135cb3d500491c1b8dde0a15cdefe4fb9bbe345604b0abef53e89857443bb1575294c4194047bbae09d582c60fa51d0f338fa23deccb09f0ea02bf45cdd4d9e02bd2bb0f73f1256d64868c1d07a494625742ecc43a87f2b4e4598913b82f0e4de66a1299683cd89990bb75c17bc0d780d09e2f774704ce552862061cff64bad9c87fee865387d0f742c13029f4dca406775854849f620ccea754f086b03ee78cecee3996ff2dc1b8f1f6aa2ac74bec40fa31fdafcadb94e2e50faee7d1911cb284f251040ec3191094b64fca6ff837487beb44c82e80fbe27f24f66c7f8ff1d8f3c6f819fb13ae7d34fc8cad48cc3e8e14d9c3f89918f6dd62d844f1a2a83a2a2c62659dcedf9c041820849e686844ad73d67f8e929a960970c08ac21c4f21de06352274006e94d256e0ce2dd9d48166daa7ab410c27dedc12e6dcd57392c4bdd28343c3228126e2dfbcfb78c8f688a6f51cf4080877e81c67b364a755af51da0b92fc321d082fef34c584447a7477da032998969550a62e6518272472804caca1da81d0e1fa82368a4a029c1ed57599a3b66ed9b388cc2f6beb54e291a95dd8fe09628b4b2dceabc31539d401b0f52dcd814ce8b33f0aa191d6e38f7c5f154e79db3b53357c8bc76fbd04d285dc4d085d3e64db154f42a5aba225002bad9f506086f762a1f10ce2ac136030e718f2be72a7df0a90098fa6c4c54a9051ce8ea4b2ed97e2b8e8e2312c1e7cdfe8da93b6e12b480fda169b6e497d90fb69241143a0061aa0cc3d053005b83088d0516ac46d73a09c347fcd2f3baf173ac1dd83df36d743fa62ec9b0e3c1c41913bd0f8ac046ee9f561369ac10d75dc411fcb5694c16cd27f5a8499386df343a33c91b4ec0377cac5227924b522c4e8cc20b23d6cca66d3f118f659ec5f088c5db2b598860dc6e2760d239b108b0972be0dc30e599e6c2413021fa8b3db85cea8771ea7c80e79aa4ffc9a30bab6aa0bc35b989c3357d50bba75cda978ba74177ff0a686f66c4a330464e178de33ca17d879e16a11a2ff99a2364a69be442ce3f62c9348d57641571b6c51e221f86bf6ce46b8df823d97fdca6fe738959b586c22c72340063b3f512e73eca5f7690fe1fb91ac5b0ef4e8c79910fb4f174879bc489c04a10b31a7351a85c7a85bf8a5d50160e2e80112c75545005016c9cb87d1a8003a66d837df78452177aa6c7261d6bb35d553c70ca7907d58b1d0bb2e438dbbbf3ab86acc781e3881bd684067d42c5141d279ba72463b2337855273ae13722480b38b600d31d706246e59a4d73792b660be00efde0b94696a9aed6a2909ec6b1b17c7d967d459e697f0755d605af281ab76bd594ab86d80f24c96f49471c69aef15b47a6075328fc1ac438a937bccca1aaf60441a6684a61370f0c7014d56665621ccb0cc8c74919d64d647043276a21e3ef36f7ba1418d6d04fe20244e908f5771d2a70d87419262bbbaf6149f20b38444f34196c49316696fc53485f27cfd18e0e966f9994cb2becda7118a78962346a0ecb5bd4b72b54759da84a4c1548123d3266b06683fe61e024ba07589064dc214266376913ebf9db582887d242099c19e6448adaa0bff650d8e16a8bcd0958f9e6ebe546e8dcb6881b4acf402d37c42b2883b825535c6ed3ae00dc268ded92a9e7bbed1637411d537fef33258d651691837f9e93f3032176c83d947422920832ee1b9efe7082a8144e747134418b40417c73bc3c7f336ad4924b48281909e144b87c5984f4360321ff833d8f2f862ac2f9257f1bcb237602d0e3f2fc8f72a8f0d6f99093fe57bc1b48e167a80d1ab3a8f2610d9a37401e01c47d3bd98676dc7aa150a1ddd2251f2dd6aa962cec09d6295470e91c795cf907e0e9f859ceff762743f3bfe2ce204a1a59f1ef525ee442c0116782bc468ea4ae0c02d32be9ae5925f4645a103552ec6750b9a3818d45ace727f89d9bd7f903066d11c04898309e67afb964c23df522f9ad78b65145b86057cfe30a98889c9d2a078b776db8858b7a786992b603064c0e0910e9146109d976b76a99122893889807c971b8c43ca06fbe94f487d2daf35884050c8891f0d714293d9645974ff666e84895391761c1b69c6b2d5e0ee6c9ccf607994cf50a1c6896cd0060c9d03e0f88f06dc8f22f035823f8de6512bc57c91bfb18fc9805cc7b6e7cf8b663597bc3f75f8b174079eda835f3da7d36127dc00cbe3c4a4c9965cc5e690f8615dfeeadd48716442449838748ed83468a691429afc185c41ce1fbc81d3d26a3e5c3d5b622dd9801a682c67ad806034a289a5c106692ce43777a872058d6511d99aa3cf049410d9f501ea83851ef1ce5f4ed0f62e93e01522828a77133301865b77ce57bd19628f3f53d232ac32448b12d038ef65b4193991fd7c5bbbc33b7cb88dbe51511718995427c2f6768cee0cc48d1cf7aa86d0258b91d96207b64276f4d0e436b5b201389d393c675e05a134b4bc719be2b82ef892a66df1b6f983c16a1598e4cd2163af8bcbba820809ff28eff256e7d077dcb6a2b2970af4618e74254087eaa2c5c3990416dc728c44c18ec01ad69f93c6fd361211fc8f6c9cb2091fa9ace737cd2cddcfd062714da79a9420ff1cece1ef91f1e01d3221af525d4661c66ee6b66ca6c8932ab7532e23539eff44ec37d87f14c17aadedc4c784af390c6e176c2b02a0b5214a7647f2095e7a6b9e0a521a975bb504555d51d93a21c121cfe96bd40f81b6abe0861f1a8c130ffc17635e93f8f3f4f801e90f49b932d47c27a3054824bc24521ca023039354e33e702f58a916f139eceb4c1c6ec73ba71aeda0050c1fb7a82e3a070d43033807dc587bfe0f10e28b31a92b94185163a7598a368ca6fcec91b73532fdf331a919d32095f83f79094436c1abb88eb23fed5037fbc23bb172c0f7cbe7434a051929e9d6c4cae438aea55674c334f7015e72f3becc3eeb9e8f0b10ccad55168fccb0f2c6cc3b3e92286c3f36b130ec3cbc5c98368cbc49cb043b3ff8a187e6200c7ec91e36f09fbaf49e2a24c8a822a9ffbf8c89c5ea84c2b893738a927aaccf7ac39c300675c59d022d5a7e7c6d31043d84a70fde4ce11ec285a5a1edf2a14644bb0494ca91946af35a5c6f494b32100404a6d9114cf938310a958a6ce6b60db07a7c9289048e0ea11bedc808f1ee94d570d7c11bc98e4dd35a03e07d8168e61e74617e5e67ddb94d7b8dcd0308e3f04fc0d5f979e6828a73d9e7f3b7800a7483eb1c36a5f880208e49c7df8b6abf702d6eaea0db5567729984060208784a85c00347e60477815055efc0639165b3f0a2957930cae2d46e8c6b0dedf3b982a7ea523faf54181ec4ddbabc1af74440118ef13b02f71672e815f867bd8b99a3d38e2fd8e1d4827f96dae6bac2096458c96852523a23fb0c838444c98c1c3010181a244bf0c939c1d513a215ed33e21567936876aac6792129c0c351ffafdf88e0123f6a8ae3874019551a83a06763324c025ed8e5a0f6b31d59af55572bd53551af8e3b317cc103934175e20f19a91f630f21087d7e5a031b439874c25c76322756024fd2519c9b03d833a14e9c585ae7ed541907f4edad9dda12b4cb8a58150b90ff79102126594c4dbd6fe3d555aeb181fe886b96e8c2fa780defecddf2d7cfc0af0ae24e14f04765101bd42b08a8ef817e2a974c2be0866a122f645012deba1eb025dce6f57c9494e7bffbdb24433c0f031c93e6b17f1d70ccd7b327160c2a9252a390664828351182d58c7c9af7323276456ef9c4fb2c858d59ccc3a70f109f87f3b2917b5dc3814e88cd649394f8149ca39c765c16b955dac263f5550ded9dd3bf9a644aceb56260b9c6875859491d10d0761ecc2ad238feec13deb9b79b9734b8acfa3c8f984e157a023be3c22807298bd1929c6b256ed2019b1515b3d69f497e210b1b3133fd031d98a2634ea3a2d31b791c8b0c05262418289ce7e79d3d3623cd095811947be3e47a266c8e9bacab119e05566c5c6aad19f08e468763353eb6cd29d9e2fd15913b56181751efa2c5e8659bf68ce115d001616b115982470e6ad8c167d45d54458a80db75983221427960b571f91caf2c6af4da4668c4a2fa78cd0b2bd33a645b616dbbe3fed9f5073b5fda7b44d452e4e499b6cec2a627828f30b714cb3453450b3e74dc295bf2b574bdd9db6867ae4429c587aaeb4f273d9dcc256af3495b603743414993a4fecb7a0456c6027d0885c49684836492c2cd41a379c1c4918c16e8e7e390787830b3851b28d5200df02a598f2c81d658d9c9f5507af1783e80e350dce07f7e961702ef847c51c84c715d24ba5d2693ae6671ed99b4604e60362379bddc213e6222e43c632fb108aa5888be298e56f48a805c21e053b3704b368637ec9977b61a7bbfdb9039bbaea65e02cdceb1ce8c83628d0097660d2d30c70a2a75a8112b3926002a6a833252296c9fa374603f5b6b333f666eb9b83825f2b0721b4baf8a4933c2b63df4e51f9d1070fa8c52b748cd57fe2e1fa2a7739933ca4993095dc0c6d7717a2a95e9ed379e99a2a71e91508a14aad92469d86e1d2ca2ace11bd4281131a5d095a5314c7b466fa150ee92a1f12e28daf8acd506faeb4a1cfc7c1d5e0c24a082df4e777ba5d97462d62ff061f9f29e69c6e902fa784d87fcc97669448dbaf1c1e3f8a6b3c258a3715da06572e46fbfdf97ed8339ca4be2f211190db86ee67f656e82b46087e0604385d624203ed59018cc41de225d139a35700cf0f9e5696199bc573ee784dc786c7fdb04bdbf96ed60d70b9b5f7a514eadafd2bd11add27f96ea3c9c62ad3b318025f86bb6531f6d2cb759d580b0152287dd7f4be5cbd96b246a267acd51941223b982f4f5d2dcc825bdbfbd4fb1ebfb9ed799da47468a9c1fc19dbff119f10efb1c94b0064d4ba48eff0936b1fbf0138bd3223be7a857e5c6b908f499b576def1742d40183014800754f9518ff7d692be5f3168ee05d7505d22b5b280f0003098f4fccba14df3b7054d614d9dd450418ada521be26f4944ab51943a1ff8717025ce6248edeb3467496a998ed35e380db8c013d6c818250b07b996b0c3a07f18e33321972ec5c3771044d4d95b58a6d04b893bfd0931ff85ce577a147a184e399089f4c083fba8c2db532b2bad1b27f4e9a8fc0ec870a295175a9cd8bed39038b6ca47615131265b93af25d5326f64078521a58d6f439f44fba0f4e29ee5d43c4c9d079a99440342a503302bb21e8ef39aa3f93b6f7d2c48dab9c028bfbeb0091b02042b62eb4dfab9f918540d98c107be205c53eaba17c4060ae90bac431cd22344f63e9d6272cbbca49689fc6d28d4f587695b3d03e8da45b8f70ec2e67a13b1aa51b3ee1d85dce427b344a377dc2b1ab9c85f6689c6efa8461773909ddd338ddf20863977216ea0205c515e84b2cd62c8dce3612bd42bfa523bb93b381988bbc345ed667c0433f2c048a838bb7996b728dd10c916a2a7bb20b07a6ff037565bdcfd1c2f6f77bbd8b3bf7c9fe8f75c5bd4fc8aaf2a525f9e7d67fa608868e6a2757ce61e2333ead63a9df69c44eb95396bf8b38721f2e9a06528fec3daa8d86b037ad2ae669d584ee66fe26928c645dc7487841963f8523727af3c2182db73b486cb5f66c0d0c91f27d5797c12af4d3d7b8db9ddf40abd68f6669d8d89dac05628b92418880c69ffcd905fa4f49558cc9da32bf8b01b84faf0ceab8bb8b8a1db1bbca8122173d511de1a090cb1c088e369ed4647cd021db7b3d493f8748e05f63c529a2079ef488ace7e21914400f2bd1cbdb3c707893e81d63bba3e8b5c35e0b45af12c4e65e7a263ff030a7df7e592fa90c18f7bb0c009a1a23a700a854342a94ca7105f8cc3659f091ff44727cc9a3235f71d69ea62f5b9016b94d62e32195bb74eaa109a53fe2415835ed8a94443053914ee6bbac4a258fdecd69b4c8d47a00b5eb0e99f28cb1ea5843f81a13a5f62c984ca69284d244507a51553f907e7f7d125c5c3bbcd5735d1582ee4310c6560b6d7de76a4f3d403b3508d08f06ad998920ad89aea96ced158fda0a8cc750ba29c1e72c4f17198071867eb7089a133f989345a5eb70402e86317f693c02737d54b69a55243e18524b32b0460a75750e116dcfcca8d8ba109872078d2a635c4041b5063b3a2c9f79ec1b8e8e4f1ea33f3024ce3fe466f1b8a5a176bb1d7fa5f86504a353e6472d016dcc7df6fb9ae9456cfed3f0ba71d4e67341f9385f9ae5bc43c20bf55ecb02f744d29d0ec424d8fc3f44ee07577f85172b2416e4c4f7c834102a97120113072f8fbaee52de61c8baa05fa5b65748391f94ed7f8b32bd2b3cb551e7232bf0911e58ca9380fa7dd6041e04e3e26cb41cd288ef58bffe3f9fd888969df7f3ec4bb33d034296cbb972a75b6bc9957e11a40b8bde4b4efa0e817b1155da59b7d75b6b56d65d6d676c9124cb308789a8e17878971a60993e8e2892da4ee52696487e62d0984360c6a62d35418e100d6101ada80de15eb3df113929622d89ed3c6e2d38c1aafd3215da426c6bf76af19845484886d359633cc75c4c9bf5521820755dafeeaa405e50537141e5578b9526d7477a24e9bb32058cd730e98a954ce31611171c651dd7035c0cd47136e890c383bcb80ea9c329f74f09e9311c91033cb178b84f8157e913521fb3e8d87ed2b1cb17124554783800bd53a834a2afddc382cb1edec94d069ac2b70efab2c3ae9450cb63712692a10363e25ee6b1b9a521e9ff7084f8a343eea6933661aa128dcd8fc8226e5c88d6cc7cc32a05a383fa3e3588526b1a045f9b5c6b7e960ad1711155561e8da9a331d0147e342d791face173230e3b61bca7873062ec3c3facb6d4e45d3a6d0a8b6c03fd6bb85fd1d36c9446f3cd8e9c52e6b99e6cfd843e337a643e03a9bd0b08be3b2914c0ba1e4c643665557e4326989f3f885cabc3c9b0e9bcc8bbe270938180e7f504877264e666e55962bddd7529d9377347d4b325063eb48924c6b0f1db1ea0d9dc7a2e12d5d2df242ff117fd7af93f2fb0898b0f8521315d2d66015de1d687a70e18f29b685064ecf8622462c317fcf3cb7c60284855152a58d66b7d00a6ebf36f4a900fb9589992d3c1025f2adaa7797c3e98d69cb238cfc465671eaeff2f12184bd1d69fb314408f45603a517b38002cfe0f33a5d6e5563a2718c6153e0ce0236556116eb4b3b1aac0d8027161c96f28f70e993e61d463428349a544d515272b86582be6ad6dc63986c29a9136e9f05c6cec920d335b3c86040e939a9279271713590bc96429f3c06614818397dd28a631b32d6fe1e8c7d3cd4a0d9d89e7bd5073c852946fddb1476c8827262707c4e1d160b4f1463e7fed11cbd81a8a3c598ea74b0fdf36a4b732ca3b011525fbc6e779169aac82073864ecd11c565c3add1bad029ac4a2286ae6264c0103ca1383a05c3050b29a74aa9a8499a47d85aec37902cedf8908355356bd95f87eae9a0dfebaa192cb4a139e013f33a3bf4c3d66a78fa7014041a958030068e1cd1fec5170c238dee7b95319af379ebd3cdea636d97dfd641b2144da2684ecbdf70e250a0e09c4098f3e5286501fcfbb3f4a807cb4db7ff7474a03b4db4b19a2fdbb5286dc23daed2338a4c3271bb2ea0d55e8a4e4e2452aaba7dfeea69dbeddde1f29f35286d06bf8c79ecedb21dab56fa7cbb2f7474a77292654fc237daa94ee111cb29dc33f5bd8dd2116034915b8395ff0a24ea6414d81a86c12d11d7a6bc3906561612cf75c6d8910da5308a5addddaad8b44049f09a6d564c3f412ba77b9b06c7ae13064e567296a6f7ea7b2980931c8e6adc7f8baeb2ffc1c4ef9ebf937f8f51c9b82f39be7383302079bc0e6addfe03026bdae051b107d6c70f4e267465234fdac3279e45ce28b31c658fbbb07a48bb9597608fa348932507752b447ba2373194fbb52b45a53b14abb290cc1f9eb4300f0d6630bff4879dd7500e0d89e3f2efca3fd85e55b5a8d0a3ccdc1477004f035075fe30a025e75f02a067c40edd58f82158c40ebae5770c8eb2d179678c5ba97e7bcad2ba5e21486b47ef321386f49496188ebade3dce0232dfcd3ba0bbf703c19b56ef4615d14240a2284091347bb82d0dc3b8d951d865a6bdde8a3ddd812bb8278afb9f71a8c7af8d5cd3334170519730b027105f1aeba7715fe006d223318d65389ca96922c804465afd68bbef04f4be6788e4b3acfb14987cda3cf066fddd7e58d40eb2ffc737f807c6c2e4157035e6f1d02afd623208bf0a38fcd7fd0d6b5b92e236ea784d1e76fdd06cba659d36fa090da1267154ad07ae2bc45e097c1f9c7b4b9403e112c416b8933f80ecb7f8fb921fe00ed0cebd40db2f5f70daed471a512dda1d7b939ae64a23bf41787a07396497d4f371391d8083542e924a2f4b2c9757a0986ca6c4e3f83a8ec75fa29446537a79f4354d63a3d78bd187d3cf9dddc9f9b2fb9b44fb7b93f365f72ffbfeecfeb4bee715a57a8f5487726ceb4e7eb0ab57e6c7f73855ac7c191eee03c7bdee60ab5b0948a511061c74efc81ad2b26c23dce3acfa569447796a8cc756bbf4b64bbbc8744049fd76f1e31edee36c7f9e9858fe43cfab4fe7bf7031b952db97f3d1ba146b52dceb4250a2234f77b9188e093f38a97e4fce61ec629cc964b726ef36c3f8d70f0929cb77ec2d96223b425fec0d61c8692834580f369d4f438d708ed0d7f60eb0cd45a92ec064fca4465619859ae3bc120f1a8b51381e23a11ed71d6121c018a0822dd992702450436d7e4ecf51766dd19d45ebd71d6ae2b824877a4086cee49d0041b6c83da068772d611046242ebb6f00ceaa0d56cc9e0759c656912bb1e8b373a15dbd3aa0483681d2f274fd65e4f4fc12033c83c110d87d8d2e823f65cc1934e208003218e50423ae20925dc20c0152e5774562cbd0080231d4e47411809c974b4a265a96d472b5adae8c204566461c1a6e395205868db7166c514e7662e54239a50282e5801039165a3069faaa3443d8252c3951594d8f0640be1938ed7c1a82336323bc61d302c5b3a7ff1e887245c1dada09105d87186c58c292345b982cca69f24e8181e899d5e7801649203938f0994163c2644b0d0598e09120d9eaaca7291065d5c80428c252e28c1a18316de70a251a4cec65aeb4669035a5005053880d12403153e35d6b52e99a22b0c3eb5524d09174de3b2ad75a3740645599430cae1882771f8541e5deb922b5d5bf0a9956a4ade18da36dca46a5d376ddbb6ed045d63f0a9bfa669358cd275eb5a6bad5aadb572944ee0084c130d33378248f2a903e85a95c0d0b5d20bf10db6e91c2d69419350d36aad5d98ba2af1a9b56a95851a34d8f1a80b0f3267bc6e94d21f8c9ad253adb5aab8c845164c3069e10430208ab2a30b0f2eb0341c86ac2328ad78a6a39524bce81cbe3ac1e2c4122c5360c1c242d8d1ca0e50faeb68e5c99210480962852a8cc27002030eb208a53aceb22c653943009d590240c30a9228508810e349d3ef24764a520fd3b9ce84c953596839a624c28d86bfca72b56ef4391c834bd354d31931a59aeced0a1a9864c124d4860f3e34004d69131a4d29dd98b6cc50355c2b53930caff43a5d96f01283ce8f59269aa621e93a1e099182b61d8f82305ab203eb0cabb10020a14614327063873880f00100d00b597a50c1185b9ea071021ff953d905a6a4110311537608a3838fbced08ca1fe60396da88e30c256ca0a2c9065cdcb4295241742888620634b078011c4e74ccc87062c382431056ae80d1a98e56c48861078ddb6ac5b242d7197c6aa55d356dd336cd0a239ae86c6cbc80c50c17703a1ee110d45fc72b2b8cf1064a67463aa79452ca792927a5f4b5e9944c9020072a9cfc40050c627ce1a3e9b4b6c59724b30461d7f1888d249224a98124098d2449672059753c62a3a8b98e476c84a153e48d7107926c23e4bcfa49240982ec78f944f421e7e7944a344aebecc80ae5076cd76d0be25afbec791fed0a983c95b67613aa686a6d46a522ad6ad18ccc459c25141daf5d67f2e4e81c9d396829b78d9220d3128ab8235ea6b57bdbb66d31ee90db379cb76d934871c78c760b5ad4f4367084f3b324a6a6d80e11caa48e0da00335ee850c33d0902484e1d5b9c65c23eea0f7d1016a43dc413fd5883be8a7f6a8d513451f44718aae38d7675931258a3bda08652811bd0149a611d26f52f6838a34e28ee4f941c51b11468fe8d859e607155e224c82f0830a34228fd845df145404d14b2843412d919ade8bd28d30ce9294fa488d289db99e4949f4caa0ee1224520b914e004141a76592eea15190612492042176946984f1124af4d10199a42594b823de47077aa8a2a82552a320c3800c904e74ed4122451f1da8a74e34fd8ff944f42191e28ef81877c44b28a20ff9187d508c826df9594de04dd7ecd1f2368470eec4e7b84453d5dca13fdd70eeccdb6be7ce3c77595a9559bcd8b1da4da2c0db9bedbd6f376f8ff9e9e6d355cfdcc399cf9b5538ff5061820668c4c41c04361df3dc0114ce316f3de7b88e8e8eea7966e620c0e999e7f9d5ea332458430c27d6004110751067f0df73eb3a74e89859ad56ab11ace0488b2e28140a8533ea34cfabebe8e8e8cccccc789e2702256e8469c33bcd738eeb78bd5e611886408c1c9208853a2e972b262626043de8d034430c4b464686656363c33141431367d0a452291a168b8542a1b8274a28f18292f9be8f8686c6f3bcedc8055e7cf1646464c230d4b67c99a18af037cf3952a9544c4c4c55e30b2ca088f9cd732b2727e7fb3e1004919a6ca0b25aad563883bf795ee1e0e0e8d0a1e30667ca8315365880fa7dbe79ce7f1d1d1dcff326123a7891c2fb7dce394e8e1c39c230a401174a42abd56a8573f8fb8cf35f9ce5143298a00689e48759534d4d0d50915117252a95ea88115c9a3c79358922c906d7ebf58a8989f94982881d7688b171b95c2008fe3811a28626906563638342a1463023438a2850342c16cbf3bc11d010068b0e9e0c0d0d4d1886229001490b25614c4c4c085e60e24488982f954a8120c85189424312a08eeffb5028d416c50731b040bd9e7574e8d0e1799e66c3d20d3278aee71c3a3a3a6118563288d0f24668f3dcca9123c76c32c38a510ceb79d56a1d04ad6e8120385fb085062520cd73cd6ab542a150528727568c81c2b9eaf57a3dcb3cab6a6a0e8256d7789ec7e3431358bcfff9e6332e97eb39f53c13e1847546b4de2e935aeb6eed53a4df40ac354ca4628abf5838eb1323d45223b4d38aba7a6feadadef7c5100602993c84f373ce0f1cc17654a1bbeed19e428e05c2bafbe41189f34f7711e76abf9005e2fcf270d6f970e6a03b9c639f07be9a2141e00e72ddbfeffbbea50fe7b9be9e63fde15ca407ce12f470f5f28124c8dcf597ebf1d1e6d50c9bb39a268fcdbbcee3eef6998b7315cdea91be86d5bdf56971b6279c430e679687f33f9c611dce3c3acba113c7719c8de1b8d3f753ce3d2e061339ddcec49c6e6f66709e6d7f83f3ecd36b537b2d9c792cb17086695183f3b1ac70663d418371d779e7b8cf9be13091d356dfe8bc9daa195c4d633bc56cdcb7fa2c6b536c07cc8d51022f419c8bf400718ef5496223b33db9c2920cd2020c96a6278e1acc05909dd04183dd372e5b3c6371f59283399c6b7bd855f3ede023ebf529ed31e7a83f8cd50cce7e032f930249e8ee6122de698eeac21f671e3938c36e707e0bb3b0f7ede3beb2b8abbd811cb6ff3e2fde2d06439496aa2b2c3d10088865a81535cdf56a4eaafb7acc052f7363cf5c9c8737f3c8b0d4ad56269e4065320c9f594a37cfb0ce51a9739e79f40b2907671eb00cfb597248caa113fec2d3bb587f212672baf72ebc37bfea4582c0bdf51cf3c17aeea0bbc74c80c8c5c344bc87dd75f754de7789b30c71aefd6157289178f080c17e168b7ee78af468efb9488f96bf798e35a87aae0d1ee7c60953fd7563dcd1dd82247827225fe7c012bef6e24ef7196139c6630776df62c5f4a9bbef3738c79abb7cf52241f070ee00507f7f81e0371008f885b77ae1515f8f2e8750f31c67abe7b804cd73449222d5452cbaebbab36a2cfa68bd7b07d107ebdd63f54200090204248ff9eeb3364979af0aa1074f023d8881fabbb9f6e8ee9ef77937aced5da02ed2a3435cbd481edc5537d7b6b9bc2e6c83212041904892c7fcfccc8db9d7bb76ebededdebd0af53b5e49a24a15301deb78a50a522ff5d7de676dfb05b38675bcf202a2f66287f1ca0b92daebeff1b6177e9e1676965c7a3e4a1919108876afbb1c58fb8312e98efd77b97bd94895e9b091d9b5beb6473f4d69c2a6c4a2fb7cccaaaef92248823c08825c2c8240683761dcc781e08dbd024738fd7bb5ef2eef06749ac8e91fce363a5eeb8b20091eb6799c327c80fbd3e37d7e773343dde527f35df54f75e384753138bc37ce9d13ceafee8e71567577090201ed6d6e119dae9268c26690433e845922492c268f459262f2685269f2c44d63b5708c3be6a1dc77f7bba165dd7aa108dde77e38b3c2ee6a0776dd3deeca3edd0925ccf27e5e264d1eeef3f7dab9f37d40e4bb8bfa96bfcba34020282cc3aec3466aa70e82424810264c18a6fe701156a7eecd7cd43b577b4bc1266c7e75e7696e8c31f676d746a1f73aec59dba13c9c65080ae9fa4b812484d71e76afb16becaebeeb3ccff34e20088246e6e912497d8fdfe77d33259cfe1dfc886c4fc594907a0cceb3f36266b097da3e2fc7f6d4bb7b24d0ce1dcef5bb39ec8f03fa51e1f3f291eeeee1fe640e9db95f22df5568efd5bbdc4fde4f59ce8051a09d65054bc8b3bf7bb20509c2697bb607419ce510b86123d382ddbf8331e02328a4fb77ba5976391890f2fee1ee6623d8953a779001df3b9c837cefde5d82257ce0bd4b210942770f9fec10a1eadcc39b6587970149f0de6122dd4f8ff140159e01bd99d0039f0251b33eddeec6d4ed3edc7197b9f6392e7ecc45fd070dc313268cebb66723f3eb3e225ed78204211b993636893077cf9d8d4d2234421bc444bedb77c7ffbe4b9001e0d761d7e9dc53ddb9bc3dc72d9dc27688d008edeff6983beace1cb734770f24e13b11707b0796f0f5f7e1dc016b7f0281d8ee9e6ebd1b845f10afed948561779fc0e4a1efbabb6c418220879a9b1a38826c10bb20708fef807b0cd4ddf5ee77c19bbb73dfb5a7ef02b577a3521ba16db16c41f2e0eab7abe1786fb4332867fa98e1c51b86aff5dae4ae663f0ff5acea6a8708c383993bd5c25ac31aded8290dbcb1bbdce73959e9d5b09139ebfc9c284963f0648c1bb76db64e8ed3b41a23a5945239a395d30aa59416e9d1f2c7cbe8c3033fee1c9caeeaeedcb54384dcc3d37b93db2ee5563b82f7a3e16eb87d9e87ba1cea6ea8abb5773defb3f7dbce1dbc07cea02070f677101422bfda1beaa22efd2eeace066f8d1eea8b6088335087b737ebb4cdaae6b897eaf9cd3d87cd651bf35c5be61c9e09bd3b739ddeee819e47431fe3d1c778aa3bb3c9c4dc3861dcad8d0247b04f7db71d08040c39f052fc7dbb295c44a7bfa740212f231a80d1dfbdd4f761d9e0adeda5beefdacbea218c71470e73986ddbd58d7367bbd77d9bb4bb73161422821c22e4c24d6ab71614126b6fb5a76a763c70397ab2a5768ef5b6d9cd6e939e9680a3e4b17de66a46cf0a02a1f3f3b54e9e39b739e9362d9d409cac4bc8ed524a69ada76f97d2c94348df5d4ae912b1ae3817e9d1f5f474dbb6ad36517ab7ea45f2d85e4fef465fab19bd552f92077da5b7364d18a5b76edb56af5dfaba6d7fc9fa7ab7ed9ee0d5badd0c74fa1525b07885dbb6ddab5cade7384e85d64e439d8dcc3e7dfbf6086ade76ebbd0896205b903ceab96f37dccedd28796429d4db4f902d481edbb9ed06b17dba379481ba6a1805ae4fdcb76de7eee9e3cedddcd3dc7f3cf3806d320e00f586eb576f083d13363f9f8419c83d214cd8bcd6291e5d8f023faf3bd5299bbb05e87a53500095591be6b07b268ffde491289c79c4409c613bbf6dadc5f632ca38707b65a871d8c8ec20324f9e90a1b7475ca44788cc93279cf4865d426a6fafbd61d776a08e4dd8aced492ca3c41df31ca032e943dc994a2ae879b965f26cc742f4c4d091900b7a4a227a7eee106edb5c4198c3b8d5cfebc03888f5763559296649949469f2b24822b36822b39841669183cce2c97f641144dc115ba60d050505f9e013ffedb4dc59413b1ac20b251e95ddea7cd0334a26618e754fec0d1ed921f46c124a245e4c0a5973ce39678f179127a184f2fb38d872839314000106193cf878d0b14f88490dd44c6ccca2d4f355768e5598407762062cd00d4d996234431a8292a9905845e75845d3cf1ac2e875a72854663b9fed710b7bc3f1da1dcab18a8e491d1b34c19eba684316dd49da26ad81a67947bed723f647ba9f1c70440a0a43ec293e42bfdd01d1c7e21f29280cf95ef1917aee0e883edfa50ca9e7025e64c183abe3cc8b24daa6e3ac8b34a24eaeb3a6362ca2320fd359474fd4f6f4c462b00c6ba24bac89332bc4b3a6dba994dfe424ea1f29121335fd1ca248dc83f200c2e8234fff83ca7e6490cf0fd7bc0cea0d1be15ac344804c8c420cd3f31fe07a5e46a4a6f4963ea467d19f1e461fa3efa1af15489b9a105ed4c93653669c07b03ef9eb38eb020b2ea6b437bf48b734da0bfaa28f13e86a80ea3387800a4320fec7b44884f534a43bdeb76b6f2f46773c7b201f209f1cdb96e88e0949b66b1f4008e463a37836568890487719d4b173f7535077998b22fb91d261a4ce1bd2e4a14b13e66121fb21850fc9c28c86359c44f1f11e0a5199f77088cabc874454e63d2ca232efe1142af31e1a519977ba3479e43d26eb3d266d4b27262a0b83f289290c83bc3048ce3819be759c71e142e76d09d671c685151d3b1e39c92149db21421a44e9520e3d239ac27c4419ad82e6954584a7a370ba2c221ca17bb611922d591006cdcce6bf6794d1290c9a388751c228615244ead839546aefdd8d1d4e0983c2a0597b464344dde11c0aa192a060183461de6711e144ea13eebaaecb61506ccfa83d9ad310ad584443acd510ddf194a8ce12a23b9e12d50786ee78f888ea180cf250464b334a6666befa5f4833aceb9c75d795ac56a7a979ce6b6e73253447a2ba129a1b7c64b53afeea1ee7f888eae2233434bfa7393ed2c24a90cc5c89eabfea3757f21c6fdd5b15a5c2af88c2d5508c0e1d7825f3d66d2dad826c886c8a6ca2d80ce95c1ba1a29aa2252fe8a402f35d494bd54477bc83ad2399c147ba471f252d15eadd0726eef02e5910b68c923ab398906a8a5a4b54d6b2610cce212b6c2da5707ee7d610ca8845d434438533d68c356b4fb5f481f10e06796056414d2ca21aa49a221611caa83563fdf542aab9cb95b4ba8d4d0b1fa1394eeb88ea37aa2197528d1095fdd82cb5986866b08a856798e88ef79a940ccd2ce691caf26b8aa86cc6a270b661c83ad5149d9e3f30df734cfa708e49279c61f90303b6eefd034365413342aea1d58d779008e73adfe03aee1d44a2b29f834533f71e6b68729e4130abd5ff8c0a6aefb1e61e090d13268c0feb1925d4de238b75dccaf18c1afabf7a8e4af7bee6392e61bc44fae0b39e23530ebc44fae478eb3936d9dcf51c7bfde6b907e73acf71b601b609d2815b1f98f6ae735b38b775735b4874a7d5d49ab59872dc99259b28f8ce28d914dd3b936443f43b8364339473676634d746755b46b7b5447750464933b3eeaa251ba1106758b7865a106616537bcf2da3f6de1a52cd10b9fe2ab2895273d65b5368be9a391395fdbc308d10562d3551d98f0d6e6115130543653f2c5c83554d4154f6b39ad1601598961095fda8f00ca609a2a8252ac3b9b977941195fdd49c75efa81995fdccbc75ef28242afb51dde6de514954f6b3faebde514a54f64373d759af89b53ed3637315ce739ce1bcbefa8deb419d2398ceaba008e675574474c7bbebae8ae88e779bbb1aa23bde5b77254477bcb3ee2ae8aea2d01defab19cd4552ddbcba29212a5b25d11def4d4d4c4c4b1965b40a6a2fa38c66ab20243592de506221992d355199cacbb6a9a9bd4b178499a55a6aefac222aaba14246a1b21a2ce6142aabd112594454e69d65446533f75e8344652a3c134477bc7b299c6d185383d4de651c619cc1d1390ca2b2e8e3d9c3623d9d67824e4c61d0a9e38c8b27da9b22412822fa38ddcb27a6f67ebaf386b8c37b772791e4e1ddc60e11ca5967db29d4ce61507bcfb5335d6aef79166d4b13e6bd88f0741bef128ef0dd3dec38eb828b7c23b41daf0c1575de96dab399d231870a2a203b09408417efe5a5523ec65ae7eb95f4b5c8d7353699b0c86d4d3a1b9953de185f2f6f94af5186605e3689b75ebbf21588d5825053acc0759c6d51a399948c60c286a1242dfff56c413a753ca212470c619c6d31abd271b645105b44d9a2e8ed801e21c223921cd15bc719184f28997de0050b44a4808b174758e911224c019d11c871050b123598410c508e90d52084ea38db22d4a78e476c38a9718d2e5de2d0927402222a78665b4ab0c2098c1632daeb38d3d2850748665aa4682d558230e2032d432f68498190961eb40cd1a98e474ba648c1500213ccb658a3b98e56e2c041678b24b32d92fad471b645193a09a892c3e4918fedc9abd5a6edd14fded9b2c530ea380bc388eed1711646507bdb27e386424186692e9c4d4c1d3b0149a43179e22c0e293ab637659ca80454219a3c2e79d91227a00a51479d28b3d0228d986daad18794511ac92834c618dd91392675d2ca648a5119cd6785366663744ae74943cfd3a1d0861acee164a23388cab817b188c2a19e42d686218b53b249748ad2524fa69e40e8144e88ca9420f9ae24441d15251513a52826554474253f314354a6043c920f8539f020e68638214ea8e739a5eff3dc521562aa434d54f6837a25e2c0d4a2a16d898968c8a8e7b7212ae3c28d88530a837a7e1be294b82932fa9c956d94d6661a93c62413d3a4cda66860908c82926674676e424a311a97c4294599d24d360a95cd209ae8228c1b5e80c267de4ea1324a431b6f40f96105567ce6ad1195c9254cb40803264c163ef37646651d3861c31761962ce1336f91a84cb6800d19846ae02448235ad1a8a86c86ca623e5f9b6ac050d9cf9115ae48aba0153e42836bd21115ae4a2a7c6406d7a5185c99e8ce9c07a21477cc73f2b406f50ca9cf96da7c3e94f49929a23250e8f361c51df9612434eec8dba66eaaaa0862351086c238cb624a779c69a1a5633aceb480a2e53f2dbe98400c6635f59a3c2e21f49adc52ae20b5366d2f858a3e64cb4f21a930b36bada7dd69f76ddb7a4b61bb914d4805ba7ed3be80c881562f91f97aaf820b88137bdba7ddf9383fedd64b9084f94aafdd7afaef9ecc9d93ded36bf29cea5daa0399f9bcb1517187f679b3a437cf126a3de5be0d0432737a539f37fc6bf2a4b8594f71064bb03a9327fe981a78edba662e3355a7b92e21f6aadbabb06b068f00d43177099139789983075727817edb2e736356e125426f9fba793b0dbd3b71b6dbb91bd3c011eae6711f054798f3f5150432718d35edb823a32c169a7b121c61759a4750017187fc8f497313306141a20f79b54b6475fb1fabfbc3d6ef35794e97f73c2de66a97f72418fe3579ec509fee12a2fd74999feecdcfdefcad1ee30e1a9abbba59bbea122ce1f4acddc6604a9f6250d4db3520e1b58bfa0bbcbd8c71475ebdbe84d35738db12b67ba94f67f2c411803af5d7767b49e39de6bac2c75cfb8c7665aebad9be7ee6ba846c97f97619ec0aef121273ef31f74c40227d8462eca0e63137f5f08e00d4295c73519708c822e2e1ee6ecf84490d678bb92a2745691a8ef253824082c41d21cdd49aa89ba6c5e837106b22f5d27b59c3a803c83cdb99e7af6556c9587467a2de3d7527949919c65ce65fb6e067aecc8d7427e68637c752386b58f36e5b68c1b205921630503a220652b2789205072c9c5ce1060b56b81184658d242f558441c59629ae90028a288ea0307a6208a41e9c4041133330d1069325da30c11536ac341d8d31eb0206599490e20557aa20910411484471810a8c6a68011b2e1cc1461216b861041a54c828628988184ca162082684a822854a103f00a1c30f443e8081210a982550e0e8210d1eba3cf962072d5690a48313454aa88005290802053be470030e6bc470c31a4236842152e30433a8810b0d5a66b04286279ccc6268c1901030f0f0420e2ec8d0448d1698a8518216c0b0708690182b70b1040b255124b182c4052698224b004506a5200c0d71d4a0091c3540f2461b6ed0a00d2636bc0093c51a53a8b1440d9248a3882f3ea05144831334a5f1c2196928f1f2c60cbe985146171994a14446154c4d8cf102318c08038813971dc0c0e10b1964f085c9d217245eb8d1c5172eba6c01438b962daed0220aa52b3148220b2a5980c062872b70b042062c683049420349156e50f1658a2e528011851628ae78220aa42b4e24d1041526805862872b385891e188064c6c9cd10089086e1ce08b01ba840006085a7c5c5180287aaec892e0a1f201103d76f0000702c8d04113935813121e6e0ce0cb8e2e1c8021002d01b862270ad8150024b101151d40e8ec9003072cc33d83c9cf4092e306ce979b2e2f305c5a6cae6845c1ba5293c48a0a0d10aa1d6670909121c60b93d00b92941ba82f60970f0c4f8bedb0384d619be060b0196944d4f0ac50f5037d08bbce0e333c2b5485539b39f49c0fa7ceec31599f876975ce19cc301f9b38e26c95a81367fb258d1924e912d45eea8809e6e57f247641401ef1f999a718346102f9441088092a4ce900a9c518351c638d51caf92c6394723ec748829c55ce1ac896768bd54e8dd64c272d4148b5ad4ed8c416c7d8f3daad96c64aa7dd94f0368e6a5a9719b4a6e9c47a7a2811eb11b39c1683e968b5c7b6c2867b6213267bb8544d0b2bd6542c8e524d4b6baf56d33425384a35ad0b96d6bad6ec356d6b4d43ad60f127ec2d633c333396b416838fa6c51eabb1d3edd1e588ee3aceba04d1391667e00d45541ed820c51845545e0c1380d413c29c73ce19653c61c2e29c73ce39e79c4ad184292711f654bb76d1eb110422552ad68793936de7e06c44eb9bbf0e44855f1700e106cfaaeff1f9d551e79e83a943187b967a967a967a2c2c07f66e7186b53dce4f37877df3536d15a89279dd7ce6bc3ae7b1957393a375f33b07e3dcd832e05dca4560ade3392c36525b476d9c9be33a134ae8dd3c27849b9b65df586b611d272cf7e42c60c272925a8ace7904819c70ce7fcc9c9bd39b11e861c7b91b884b4d841e063bbdbdf41bdc2c7b83ef3cc72b3d789e7bbaf51c42db7704c10291c7ece0f6d57e370188cd7439ab0f6eff23fa10c02ddee000b8f1b1e373c77f4c0e4ea7d329d63234bfa1f9cdedbd79cecdb2737e92517960ead64e99ec383a9df319d9c4134a68f3dc8381099bb7c0e4c1f97c08509faacf4ba1c9e3cd1dfbd7e4b1cf61bf0e5e0e2e4c87457770709cb0589fea656e36a1ed6966380e1432822c3f64196a8b8bc86fa6f35857b6ab670003f88fc9bab1736e6caf832bbba6003ccee33fa6b7ba04b817c31e8f20100ffe639e4ea7d3e9743a9d5431cf8979ceedcd79eb66d9ad9f4eaaaf6d0aa57a4d1e19eff63a93e7e6f6b0c983737b0e268f2bbc7d8fe803ece9d0258764aecfcb2139c39c775dd8e78ebdbd894b16a0b224526e703e9f81c9137aac9abbba3f686e083d37d7e2dc2f8ca16e8f05981077582fe7e6a8d4e3ada2ee71d5cd4051da3ea6c73910c86d4ff3dc82427e9e70f2644a5b9e7bf2fbadcd83877cd0e32e60c2ec3db8264c180170025637760737768cc7007cecb8b17a7b38b82174f78700ee0901a037c725ee3b37cfce71e97553a89de392cdcdb661379fce7d824000b0841012f06005d312006eeda132ebb380b9c18d3d61f3b27b2a937dea441ff7136f00d644725ce7f99de3f8f9d5f39ececdb97742dbebdc0c6b9d4b9dffa03a37c7736eb6b808aced73e8dc1c587623bef71577483ae108bd0d44a611c077efc06ff7bbe7bdac8dbd45f1b06e6fa9ac00b70f274fcded5954d673fb4f9ed5ed615426bb7d6cf2d0dcbe67f2a86e1fc2e49939dd3e0193a7757b054c1ed7ed4f883e52b73817894bbd3de6a43ace3d9c7bcac119a8c3d0da9cbb8158df3c8223e03ce73f26ce737eba39b737c7dade5c8240726e8ef5e97455bfb9d9843e5d759c9b4fb848ac652ef31f13e7aaee4d37c2bf9e63adb5d65a6badc5f98f79b2c7b905a8ccfacc6780ca64508e4a9d83f39cebe5a8d4f6378f938784d8a7e79c709cb01c9ced5f39f7757b5fc7b9f90617894a7dc2169830fb173e61c2ec5d77c884d9dbdc094c58ebc68e600b9b3061f6b700d7ce1dfb9adb735973c77e753f61f6b20b9b3bf634373661f6aadb3361f633378409b397b93f26cc3ee62660c2ecc3ab8009b34f5d0cc41df6120482c220fd06441499faf42a2404597ec822d41617894c96de982cfa60e64ca91368ce3981aafc682023b981a8d444a6c4d20732e078a10c26659ca049193b0c9541a5633a5a4182498a2d3a3a58e28b2f8240a3e989273ef189ba6953a474a82f409125861a9480d2030a7c2812195b74b8e93823e30728da0693a18bc1101948bc1504c082e6c50a250208d3791983053484ea9530c87881336a8a81630a0206a621a13ac617a131b88cf14403b727c9695f6b39d45e2de7c1185bb450699d8db144131a9dc3d3249e0c424a0f3dc630a23b1eb1808896a7308994383f78fc604a58482ff0f9d8f5d60903a272021e083c8b820cd3d7e3e4ebb77bf22691588a7de89dae7d3ebdbebb770a0639ddebae1522b48fcdd120a796a00583d813399d01d46e5bdb3b23ac5e0383540d144237900133f2a837c2aa5d35ad3715260a34cc1b6dcf814166505b9c82bd11dbdcc3c943697377c61df51c38c26c6aedbd48a70c4f77b6bd121c41463951f63fa6bd31eea82eebb21805d9f529c8aeaf9f188afcccdfbc76aba5545ee381c8961e8eb2205afa4283135cdad8b8dcd0e40c2f09109537da38a204529640220e9fda04972ed54a0c3a24e112032050f2563e94010889155e08238b0e2798018c4f64e2013606931c84aa57acdbe6e5cb144826c0524549053edb1230add27c54671817a29814031359a870c10b1529f0a15c6ce81897216b875a626962060d70b4b1420b5c30c20ad20aea8c4b113cf4d05fc719971b9c44db5286b57fcc1224f0c413a634b844a1c1171fad85274e56f06492108ca4260a3f584188445b010ca20e8956abd89a22a0380163051d675f3075bcd671f6c593ce1f184445c041014dd334a1dbf1088837867aa868019bc4aaa0665f60b1c21531c2c424a9f5c88c295dbfae486a3a1e0581828d0a1739d82317aa74533e11506c207d29638a1636c2f009a7742e7c11830b52f4d7f1880a0cdae6c1116c7041540396a12c44485989a20ced014fbac0c10b2852a6887180a3255ed0a830353922150525031a6692c4aabc64200452396212ab4b6092c4aa68b5d62a14ab625d1d8f8090c1e9c81a0131022c0540d460c799176ed42522542f29c974aae56b8c3b7ef0c20d902e09f58604b521593a22c56389cb1858d470b282377c3603f4b6c4446f437891e407261ad5d14a1465747e8c3b010e9e84227908a50742295f08a57421941e6c3c84c16245156b745143083330ce80018ca5251e48f97068c6b44085ca1a3e4cd16409848d02bd608d38b6049185114d7cf101448743388955d1f1c2069922ac603246144da04029290c20ba14c08b17bc599963a8446a98ea5339cb39868806180000005316003030140c8845c3599485a1be071400108da0484e4293c982498c82208661180460180e0700400000430c2084ccd40767876659b5b374f8d9596d16c832eb07977d3565712bb30af26373606299ffb314f8ec4c2d0bf422eb879f7d9bb3382a5965f26c0e34cbf493a5c465676b59a016637de1c5be99b3b8955905f96c0e9c65fecf52e26467f459a08bac2f5cf6c59cc5a9ce2ac86573a06399fec352e0b2b3f52c908bac1f5ef6659ac5a96615c9b2f9a02cf37f96129f9da165815e667d70c7beccc2e2566615e4b2395096e92f4b019f9dd167812c657d70d97773165725ab249fcd81b2ccfec252e0889dd1b3402eb2fe70d9977916a73aab24cfe683b24c7f594a9cecac96057291f581cfbeccb338556395e4c5e6c0b2ccbf2c655c76969605b29cf5c3cbbecc59dc95ac825c3657bc2c624c64dd4cb31d6ab0147361f140b2677f16c52e2b9b960d51cef2e567ddccd96e4a96622e8b07923dfbb228765919f4b1a11461f9e5b26e26d92e6596629ec503ca9efab228bb5919fa6c88d28b8f5bd501b329b168b21d4a96f22c8b0f0cf6cc0716c53e2b4b9b0d55cef2e7b3ee4cd90e559672268b07ca9efab228f45919fa6c8852962f977567ce7651c0529a81c505ce9e7db328fb59597a36b422cb97977533c97629598ab32c0e70f6e49f45d1cbcad0f6750f7a37f60be2b548afcc0efb8bbec0f42bcc28ac5aeae8b1d1deb32de059687859e293b26fc35939fd6cb192d93783ac9cfe6c31c9d9f76156ee5eb698a4ecfb40566e8fd8e292c6be0db372f4b3c54864df87b272fab3c524b36f8759397ad96292b36fc359b9fd6cf112d9b7a1acdc9e6c710962df87c6cae9678b91ccbe1964e5f6658b49cebe0db372f6b3c54864df86b372fab3c525b3ef0759397dd9e212b2ef0362e5f68d2d26997d33cccad1cb1697f47a636b35afec518f341bcd5db6252e2bad972d5622fb2684affadc662ed8d81edecd9e7b6d7af136ea45e78c0fcd83ee17194dc824b2c11b3ea4b9f2c551bea645bef156226a18236eed9125403bc2e88b927dd0081b905caf2ff77c85627cd2811a3e0544326e05d3c3b67cab1f5f19768abf17fd3cb74a7add5e2b84e8abad012cffbc64d1b837c7a2d062d887bd63f8fa90f103b8461a51a683b74ea80ec4072bfc43e24764fc4262a14212c82c92c9183848373ddb7d98eaa945454fbd799de26d0979d6c507add641ae84bb1f30d6e2c74c306eaa28c67daa51f5373a328f8ac59df0ee25e429944b9d7448ad7eb10973a2bdc5ea2574a7c0f1c2e8f38f00e3dd75a1dc5e7342ebf13a65c4a7d96c2abdf87aa88f3e0d1b4e73dfd646d779d7a88b6abc7668028c4249aa6789d09d14c0d939d0f3d4014c5ce49604b7acbd4174c2bfb2c0059fcbdc236a4e576697859433602ec8d232b1943213764bf2f7af89ecd87c431cc5188c5b2cc157a229a04335264d9031c89ac911940fb8c58f2502c06381099b588852635d734ebfc26ca79098337d199335707656bf8e6b97160b727eb4d38381c7384744c1f504b1a783c363e2aece830c236721ec46baa40155d647eddfbb9ddebef4fa43399ed2e07f4539a6e6ae0ddac3773c864de87214419ff73b24e5582b6fbe0c3011defe9d1ded02de6dc49583c6bb7807729905149e5b512ad858c78f03589ce7e060407bbb319003b998b62eda2ad23220216cdc13a3f97dcf9ebb3c69131cd79fd7b4e38732d74b3c1f6a6bc8dedc6444d08165c71e9b9d123dfa4567333ff8d30a8fc8cc91aacc430cca381b74ef9082e966cccb8e61c9408c5dbbed809b15644e585ca4fde835df8d4a8e00224711654b7f0f1700868de0a3397cd7288f862f82b7a59e12223c8ad647e3c73b1491a704fd44f8babed27db92be5669f4da4612c4e8d3dcd019e19768e7612dbfd244729b88d0a2527a11686f142e111ae8dc3ef4938db4ee06568580e9220df54cf1061ed7f836983dfae879b64dbf544bb4eb72dd4573f34a0246a7a5cdeb53942756d95fda2148669839d6626815158d9d7e3ce4dd8d242828d85dbd8e21dbc56d1613e32949a98127fb8634da2f2911de8f8382f9d0beeaf4daf3370648a95b75c8fec6ca06240b233d9c1fda0194185cdb82ebdc586ae0ad31509a8ec7636bc202f462d83de0d802dfde33b0d9f4f4155f65d5014d3f0166aed5f0b305048e5ddcf3e3879d9274bf863d8a128b682eb983cf9674561856809f6fa85a26ac7a8498b829a4cff942482ba11abe22499f102608452bfe56105ee7393450dc14e49d7591103cd46529499c861de79796347c3a11233895364d7c03e0c63ee3b1aff489b7ffbdcc1769ea20fde0ff1f35085a7dfb1b7a5a79a20de362d69cde2245dbad1fcb28ae22524e3b097658a0dd7b1da8fc46085e8d9ee625d0653e95466940e473c320a5690915c9732ce2478abfde4592b51737cfb4cc7a32f20ea1f70d7b04192ca0e9e06eba8c71cfe4d7b68e69041a26a1e2a91fed6e84603446c599c4dcc7d7b1c90b27ff60ec0f492f91f783014f4d9bcff987c0f82fab39f69c86195eea5204762872cce9583fe75f1c4911249da469fb8326a7ca4a51ebcea4bc6b70e423412531e3a0722adf0d97efe22382f0ec1bed2b7a9835d7e91b8bf22a8472a81866c035c40f78228fc4ff6ee374720528ac448c0b84920a8079643d03494ac4085dd631fb694d8524467271ccf454ac8eeae943f20eb76e66a76d592be14283f4993d7092c2740bb3e0db057c42eaa585aa0b8809e4a63c87f2a9bda7ff93a31545a693ec659d52c3bb259db9200d9f5a37c679f424dcafd8c6089ae747b1d036a2b5a83c614ce09ef5a85f1af47ff64db3f191fcd4f68cce8ebb21cf4cbd07b119f676b8131fe84dd80026f7da0c66d11b152126158b48e74bf187eec6e7df9b3df1967e9988945ec3afe2289e397c222cb32c507824fe60dc824fea310d785141178fefef82d24e23462f82b7963d8c3230746fda8ad6422ece3ea3e54b50510f548eaf87c1cb8cc5719bcbeb99d0b2a8a1f3ee0cf96cf48e97a290974fe2192c1c0c135075bc9238abd5c626511f882618116dd08d72d66de2cf86b333c726db714cc87079d67b2428843e6600b130be4e146c67abe2f7a004f19ae1308746f131c8b5188bbf7423f719928a1fbeb1cf51e956206159d69d1fb3a0eba9d088494409397e3c39f662b950587da433d025ec05535b447b8181bebffed52914273452669877a4c724052f2a415de1372116a7019dd812b9fe6af00e863c1fb846476f12d626001883738a2729280b0e727e219055d610b0e535d196a06798082635c5a7a421263acd72b420a9190434a1088c04da68c886fbba8ad93fc1a6bd0948026b40ed0cb3704cf08fdb9b20f9f8eda6d9ce118e2f1ebe7a137c8c00c06e4b70e2ba508608eed35ef145000dc70b7e796e6255a433b8fa35e76c8e124a4f00488643314dc3cdac1c1dc0ddd007e1a52680ddba93f2f614b25e39c5987d1679025d2e6bff57daedad3b3fcbf2b1f660844e232813f64c56dfa41677999438322855f0c228539bf63b80dbfbfe77fc1f78ef61f608634090399edbf540ce1e78694faa997fe31e2203b7fcd82e44a5904068d4d55dad0987ac3e7861c399c6335042867029a1f96fab35a4ea5ca28f6f3877c6cf82b2caef8ad09151e2b84c000545c07f791074d09cbaa8eb1ba68d430edda0933b21df7aa2c2c6a3b2114bf34098a17645324a3e84e9a08ef8ddff1d2d9d94702818e2d8237ccecc04afa96d2c9a1d71f7604ba84307116000d9ffd89b810621a33a109370f0edb70c40fc61a13d319f2d60d49c704829ce700ba45ef0a64bfe8600bb1954f9ae44374e17a90a61a280e481050d0ae30f24560cebe08aeebe9206d739abd2fc49d11e9d24f431e9ea65a49c2e8dd525e9382e4006788792f07ad1989519ebca4cad5154bd4ab89b54a5aa2844693354f0ef9bd804da3f61f28c85700311b92d20e3c078f6d11abc1495977041fbbc81308e225f9813938977f768b4d17173498ee5d40205c4d0e8805fc1290f402e4b5fef7ec01b1d668cc8b23f79221d494ccd83e75d280e7494dd2c8b01484b7483afc4533d07cc4d07a14f9b75ed605b9619c9135883a0e12655d5caa88a4d52883fa1f765dee436a59aca1d3eb16ef06d7da949513484d4d23dd72410adf73305a217b019d4fafcb919a6721310fe2c65a8cc203f48ce3c1a0949a35642d9f2e1b687af3f847c157a0493634e0a9a09b64e2e7d634b43592b17bcd505d1501b12c938af60280c782d0437448a40b967c605a69b10d74e54885105356411483984102e0897db23bf5a87d0b8b614a7b42dc330a6f81d8c1d7c14902c531a388d5319cf6401007014a5b46e545a293e11d2c5e087d854f0667188806fa8a1331b621e5d9258e9b090f562949301e4903f2c8417d6496f24a6fe9300a4d3f924512db324b03eb785d0ec4acf32a7a20883a205daaf92bea9f60dff1e468cd0570d3653c40a54350cbe279cad8fdef3fd85e4c21cebce7ccc801224501d33bd032a054250bbe172981ad436aacad5994dca12c34ab7e70c4e8d7b0ad69f2932d3e4b6ac6acc29ef59c4e0d489fbe86f31d686537cdb7174af935114895032b291ba334f77924e9db17a1cfd93409abc1fdade4ce63784e5ae5a9c7f8e98e1f554534dc99eb8901c06f2b878e7fb5865445b1027013fff19478a99a5902d58f984cd2517f915cfb468d896b95f4f240ed86c007bdde187ca24199d0a0d0856060f4c6c48b787f3e374c029f2902c96d2156776c5c9506f0a413537d80ae8495742a23876987cd07bd120670231e1f3dac5d15d67614984529d949050e37b50ea123cd54f64fc1be2d5272f9f898705fd0c068e420f8c3474809cfc273247da244be52ac9b636c5114051f6582e12d4112f71d33e2cd9e0932725d0d4a1dd2464acc4a0c8ae5c18ed4750a718431228c0b87f887e9a423e625cf43a79dad4aed041d958042226a947b23978d7adebbea234474377589be4d51d908d225874453308723eb8ca6120722076e7643483f70017d50504642394d725f9c83d322dc3201119eb081460efc777afba37977b4c40312e2cde7426b3a608325324172a70a32a6ce620afcfc8df7b908c1433cc7749bc8bb6a44bb828e685b33f9d4c5dc0c813bbb2da4ac5f35ec9a2a216e3bb3013724402ec8af0a88ee191e64ca8f1f15e22ac03304cbf0cdd1607a3489cf4691b26c3bc46fc23ab4e310c609d3cfb2b00fac0a75c16292f25dd04d5ac2bfb961b959d1eac7ae4a52505a3d366a802fdd5f4cfb487c12289960e1da05fd7f73d7f0ec10b916559aee02bcde6c1dfbd1e9e876770b8d10f474ccd6c5be1bf71ec28f83079bb1d68ec381b4e17f7d60aa29544203418367ccc1f5040821a04bd950f703451531e8e072007d1e60af47ca42ccc6b0808c16f7d73127bf67f1f290ae6e5c24676af9461fded3278edbf05fc478f1661f17df234674451c90bb7bfe3f73e3a5ca32089a44c5acf84e82998123cfbee97490d28baa0b1d6d64babf9a61d49b1c5bf49b983645474d5f258ab494a3da1a50bf445131e14e32f51f9a74c5260f02a75dd0e9b5e7891e856c267ee1aed68bc2880e7ca7fc24c918a0774a15b09b1eb488e585a7d36572a309c723694d8e4e4f5c8c26a12e3db09c3644b789e7aba4130d3b62a13a802cbb360e5a21c2a2f00d5ed45c32f2986ac1b29821c4d2030cc978f8c984e05d390e747380d01a9c3453e175819c373c18ba4009837192159709bbaff6e59c8a960a2588e6492699fe425ef5bc721864b405685d224ad1ba7541a8755d2fa57531d0b3ae0c06664168ad8e54d35a763c476b3153c62b493c1a8abe2868a4106ca8f3f7997e6e3f49ecfc5b5ac28fc31a216a97c5bd09776beab5f35a8aa1c15fbfe1d3d64810aa395390bcc3a5c0cf11f6ef49890a5b7089e8d0a92d147d1600362c64d0f32884075214415c71ab81106327b67c0f0737b1335228077dc5a673b347eaf6df27cc1d099e63441eeb80d56c40254ac38245aa7f9d5fc46640916c804e18c0e9d735bac5413dee3efd4d3687c3f13a49880828b2f016f636fab185593e81b8ff3eb2b9867a452e2a23ffca5a39aee2cb257044f5230d9806caca1171ff494082629ae25c515f7e548636d06381abf54ea0ab02e086b9db2852d1903ceb00024cb39a78ed38da498a49502ec94c18bdc855a50e24cce68a0c131045934ca59c5de54bb5e84d94eb57f421950ae2427d622c3e91a1c2ca9303c1866a8c9bc80bec88054cb80a70b2b1a3c310ba6a0f7f1dbdbc43f6363cee2a1c8207db38d148938343f2e4f63638d6a2109e2ac0e465cf7ed026a51c6fc6b2a8949b9b1b7c40d519d4466b3d5addedf1e8683cf61724ab0f988615833c31dec7ced13575ee57c17d7b1d7b8569fab74b0146a701cd57002c1de86dc5670386f65480c5731dd67fb00eeefab5769da552118e949532b0bcf6a0f5fc91b092236b7b5443039001e6782b5a90bee24c839e1fa4c30fb29ce6d9ce8cd17c478c94618d1fa356740534ecd22934d2858025dee7b8265ce81891a215515e4cd816adeb4be9acaa33b868086d098f05178d066205ba6452001a8f3cbf338b6918d13a126f1b054c304555f165ecac2395eeea6a47e6aa4b388931693792c6d953f6c9e5839ccde763d67463073a1f3b54259e6e553ffaf95e3df6c4d79206911b0b7931d6b5175fda3c0a34e1e5e60c618cc03c6c725bcf11b19e1e44b3557a7af3eebbf506ac48170a733ee289b51cd6b1eead48ffbe0b6de5c98c94387702fbf4371b591f3dae5b7dedbe132aff2c455ddb19a55b83d04dbb14eeaf62c6a2c002f60e0c7b1368055bfce5b08c4dcf6a489112f12054fc4f07d72c86ce710f1ba2942b2fd4447b3e3c456c643f94743d5bfd1c2daff9e6b122b998d517cca1f608faf59006cc397a0839843bd0967613d88ce4fabfb92c14ebf5b1518c0e30bd8b53f103c452596217c4ed7ed1f634554138f5231fc4892a7d7bbcd3048317d6f68a46d696df7325ae9854411b2bd3a32e4fb4635d85e148fe8e74b8053aae0af7ccd48a3cee442b9963d012a9b13239affef1a047c66a38290d181776982e49bbcc5450114b518c6b89a58e432965a88b24e455e92a021e1704ca026a552e5db43ec921a254c3c28d1912410fe45d93d7b70ff26138d2e517ca61896175fb2961f8b525813134304339b00ed277aec8e654849c5cc28b2158dc481c4fef4682864734be8b0e08443cb2e6efbd74c484205921f523a4a3e9292f48272caea1abd15bedc8fb47fa126330651a87c1d8c9acabfbbcfc458df25b1035dc986e9fc8d9a500658938358cc64d21b4d08687d90e228f6be5dcc1ba19d7d61d72099304c082522c670e367abc466612139ff6de8800f42f580a55a9fccc5e91b13039a25362a7051c8355464192c0e1d3c26b512e005aaa7120ed95187132155bb580f7169b204341b873975195b6622e355824d4ec2def3eac13e323cf468056edf0759a56a8c597b2db8280925e04ff53fccb912f293bc660e9be80e624b627ff46f77a15612a96e8e54ab614c98fcac2e9931515fc61260e8e567f02e071292752a068cfdc6211b0dad1fdd178b214e619bdf4b600d903038db8151738f4d4ced7071becdc5666b8dc60238e15f7fc81c567969d61e5b668b3f5b2e2de559b84186a932183302b2ecbcd33263eb507e30e62f30f5f8ffb5762414282d413692e6f9b29b3b6910b0216c4e3640274273f58b5027175fd0a8c1b56c305f713ba8e63942b0f9db77aad3ae808cf0f90dc00fac3a1c8107665c3a79533e0b94272ce3e0a986371ab79567ad45838439241967ce6e5166ae06775594be2ad735c595fbd7c28f630a6fe35cf3788b2c099397958c2b454af7364b296d641e26bcc522e6928b2a519b4f03bb67d168f91b12c073637324628323940b28defd8e57a2043da9a2eae1da11e13332dbc61858863e8312d7d759fa0d691c22d356aafaad1758e1af21fe2d59b8b49f4d16671b535506fdc2600de25cf8fc57a5c0163729baeb49917d619be24065ce3233061111eadbff88deac2a466f9802330cec4fcf22e43ab94ba789f3fc1360922a40b9b8e57032d4adf35dee8b677a6a57d7e4afb80ba98ff92559fb91749d37c21f87d34b412832b3b523a1a1770e82af9a63d7fb6df78aef7e8ecc5df76f794a72869145823c6bf70fffad5f1fb0b5f8feebdf83eeeeef59be39b17be8edc7afd72c4fdf55747b7afbe1ebb7bf9e5c8edcb6f476f5e7c39bef3faeb98db972ffe88db7932c51f869cda9438b398d9af2cf94fd191bba323dd6545af91282da07b5c82e5e213b8c54bf5c6f2fab65e1d339fbd6f697c52e0f5d2ed8cfe71c4f88984df4bac027769b5dda2e0c7f23737c6199580381cf65e1e7b694de379fe9210872b093397447c264d916d6c334ba20b0e18cd047443cde10feff998522b3fab01008445a5f1d6273cebe97b0a6e4c6d89084744a25e24a9e06a25cf1e577553cb2f7fdbd0fd78b65e3a41dada1a59c67539aa0ca6e0f70db631f87de30f4a4c200e065f989c0a9908cd4b7dcc540b36442b684e651be7330f0e3cd59abd6d1be5b24b24d0e71457d34c33e69646ba86de3a61ec8d6344fb4ac5b26ea8125dd6a0895b09ae37d2e96ef07104944da0cc8f6183356e0695c96476a21bc553a04190e5e595363bf0718043b0a62b6d71bc5c95a3ef1cfb31aec82cbfd098c16c394545c62fcf042f389478df7a1e86132e195b21924d9da6ad25b4125cc9bb892e1b8cedd2d23b32187ac710f8b4246aa77ddbd4bd04377980a74f6b52c3c6fabd8d6d5d80ba8d693508eef109b9d7184704a0c807448c2edd6799d5bfe5d14202b1c16f092a614aafc31aea7b10324728f5ace9c7617aa3e7f773679dab40c24ce16d0c8dde045edd2dd8870d90418cb99d333512758969f7bd2662703c80273162c7656c4e9e09a4c210d6b8813bcc3ad51989829f71f402bd6a637fe3517f905e8e4234ca4fdfc04fe1f6a5630b26f5d42cc2d91fda43fe4a7e87c12a1a2236ccb44ea6325fbe71a779bd052c33365cb16cbd853ad9b864608c2ffc2b547831b1105e54b263ab2f7c89eefe1215f008234a645831b97554ddf004ac061777a6bd29d7d565127f50478d8e45fa8493bac233aca378680299575eb80c5b895c6ad7999b6718ff5667b10becba21903dbfa6e1255dc295150243654c98be6dc68c94bcf7f202cbb3815e2f72d77f5304fab59895b442de779d93982cfa53adf152cfb394f69138a100837963b6ccc20473193ae680c708d537d4c40def59ad2f4cb195c9f3e8fc5d0d2241d9d3f95130cbd19ee57eda72be1410c8ffc06c055af7fca95b96ce09d6d3b585235f46157e280e96a562e7a52724356c03d5bf775b42419b84808af85fb44452a02ffe764bd742ddb0dd3512e76fde53053c074502ee3071b526648215dc291d6bb47ec28a3bb75923077bf368cb23e6eb8f75b75d07a317bb8aeb72d73705f84bf03205ec8d22182628b3967cca988756ddd21f30d7c4801c65ecd40706bc30c82486adb88021dee2420ccd8b5b3b227eac78e48bc5b08c1d8bc977c8c3c25c91a73e8ac2b1b46ae6d196799c620c21be889b857e49283999910f524b290f6778f8ed4832a4a3711399e507aa1c4b74f223772a5c6b62db132325087577873981655d978110b00a8f8af81e2ba665218a47ad6253c242087be587d6ca3e24f8c362df0a6dc132f753a0bae0dc39e660f69b8bec03613667393a547a2ffce37a49ea0f030b2eb0103a304761b1a63773c507ca5f76f5fff703f731cd4207ef190e63d17bd1714c1dd1686142bcd65c2707a505bf97c57aa777b581c32ccec21ac8754be37e9c6ada90101b4290e76e79e614b5b487c97bd896304fb685b25f9b597515e390681b5dbf1e5fef101076318101198cbf86d45368e812132af580ccb60008d496f9ee14dd84beb8e847049dc40ad342c770763f03a233faea0f00d5cb789623b7d662135d0d75c8058cd6e44ff6ef01d95ba2e7a625e548584fc7f63f7a3a7e86e2078913ff1a2be99b3ffbff5512b618b8b7121dc882cc8a33b245906b4ce0f786d7c9e342351ba70e76f8aab7708d5dae16f3bd8e208db17fd7db6b5ea24bdb49c9efe9757167057ac396a318656cb414029c157e58c66384616e5d5402f32e5bd6fabb68893e4109b840999f116446d92b834709168d4997f36d3a3ccff5f7ebf0e809e7ea385be9869e9f9a4bf2d068516e3b2e35221f423713dcb7a6d9c0a2ac94220be2234c557ecdcc5b8831dc22bd66d673764173277d57a761b0836674649653e5db1a1ce06b2071ddf48cdee09f2af8b92431d22506386c58296a4747fb1acc520196fb1b903fc0f31fcc13d81dff8f58b302e9c09a65fe913eb29f23699d937eb7ed543a65e577a685743e324deceac26e34f45939255bb38484394825f786da02289cd87ca4456111fd3875a5bc7aac242781ac5fce91a209d22b528367a5aa8e9ef493351c7bc6401a452470b70e8fdad3d9177024dbde48773bd1c0402b80360e27e827eb4319d8631486f463f09189b036e03f4727240972c67d045cba192ca0446d5fbdd73a89ee9ec831bfa34e8fe1baf2c22f56fb8eefde10715dc772f498424d7bc0b531aedfadaa05b271c25314e8925607e615c94767835029822a96a07f4b49e0945939df36808801bd9c04818522c95250a143d8d58f1d7706c725ea00968728c2e4b5f0c928cecdd9bfe5a4dd699ae3b94fd162a73ae4803efadee69bfbde9aa907ed4ca5c9613b81280a915291a967004b9ab65ad32c96ed51e381264dfb71d9ac71589812834e60711675d3d874397223e0560fc79057448174557548e4d05266bfd06cd64c68ec3221f2dec908ac9124eb184b759d2386ba440b97b7232d4533d903bf400bc06488a4a3d36f99fbfab38904c0481f55cdcf06785a586a442d7b87558c23af5d7c7c04a254d2432b0a5587871ceb2f7d59a1f602e73a6d4d9688f1f9f540caa1516cc2d4a3637761a6ddd1139fc245c4f22528081b007257564016894eb974b070f7fa0b173ca9070fe2665814d46a8e9db3c663a00b33eb1f2ff9c6fa0301b3f9096c1b56fc0e23aa5cd994a3d4b1f55191ab17b1c8e390286572fb18757949f10f53223c65f952f15f95a8ecdb20a8ac5cd75a65302e861893de023d6c05d0b95840f2b53019ee188b78d8f000d0fbdddc690330522546613cd43a89553237a653a62be3b964f6cc8f043ce884766c7bd038a4e485643805c8c4901a9ce358c27fe85992546afab1ba88ee58fe2bfce7ed712229981b7a9839f8ab5f84fb84a88e9a6546a7a309ff3960225155235f5cc7a8009f26ea9e71f76de2fddd506f0bbbdc8bb81cc33b0781c2da0624e395f1f380e8baf82637013cea005ca15ad6bce1c6fdc3f12754127e5113cfad4b89e5e2a64e62b0313559ad7b07c0057e4aa2f4d86a5191801d700b716551938bd0e5ef82cea3f2eff96355b916661de99b09025f8d5c3fdc14a8eb0b02063f30ac3487d8c956addf03d48767171c0a231fb13527a4af2ced70c9252f032a3d1d5c3964103adbcc5f8eea8bdb03d7eb5f63df2903b859667803336de9eff11f1262e554ea8850eb81595c8d740ec9b3542d5b692264e6d43dc7628367697f0fa65dfed050ecd793bbee7f58024e255d5e55b5b2ebcf399cdb3bcb87d58326e9aec10ef835d4d7bad70d40b55db6861d5906f5090113961a3a3a0604068405c8e7afb30cbb70356c5078f0bd6f56e2376f33c38a3ad2d19ab9eca3cbdb7c8bf36443cc2462d0f953c77807f5a7217ddc32ca4d0a04e02fcea51bb7a96dc55a41f45ab26cab5983304a55b464bee9154363c059c21ba473e163a37e90db55e979e4be692f87630a498c4d1458d640808e22dde53f159369ebdca8311fba5b7f9e7b3215ccfa9bd81a5fa64c511cad2f59d7f7f0094069b36ba75e1c51e3423c4f8038d38d10db6253779e2bfa33028e1d7f5abdff0a90ba472ec846b5d4b160dce3f1814d20016cbb298ba05b43e7ec1573ff9174a0b221e7384d0778470bd3920bdca1369490b6a6e861961bb6f878251f41e711bc6558b004672336872b836b618783310bd3872a0939d6458e7cea01c542237bb912823924cd19080adc0805581f88b59b935739097e3bd3a3688a34290ba3ca4e3447760aee4b4374665e48ba89d5071cc82d079843aabede7a4747804498545c4669bc3410ad910388df5ca2bdba8c670e95162613e85dab6e3db12a6e204265991c9a0552576108d5e90d86bfe3df7e6e875455c8eb8765a9fc58812e10c03adb011efa1c07e28d944eb474c79f1d9d9f9347e6b1b7c75a5a607b019f3027f5b7ef9cd61fbc1dfd980412d692a1e3c9523c5a2604459e6783450096501c36a534397d3293d8388f4529d7510a0ab5d496bc4573f06c2a11e0cf0b9420a43f913d6a529f692e1da2c200fa2c0801593d01ae63015b69064b13b15564764ebd64d9de380aaf9fab7f976c06db311e7a81fb0e3b0c535a78667515069dbd2b5ebbaee48f9c69696be70ceed792b1ec98686cf1a0eaa7090b21fae1e800fa3b860f22218025e220a5425073a4f61a341798c057e5276cdd542488941babc2585f8d2d3309b526a8ab394e90206b66d73d22d744e913b247110f1f67e4a8049279a4e56f4a90b1928099e49327e913a09abe045959cb99332ad1a54d3239a19774bd4c8f0b4b8286b70a6902d4de4471d8033d72d47574dd59be0c283db4c546e0db9220cb793b028492deeda66163d4bfa4fffdf381a61c221b183aa99c860c342592c431e506aa19803f76687898c376d4bd7c1e2587b09d28acbcc0afbd52b21564fd09052f24186e618e96200ea64cdebc4689db978cae37104ca9d973bb8f8684710e43a6d5674d782ad80718b7604d9a65aa778898ae66051600a0bf20486877145ca757c4aa43d83b1fb846ed726faf8384f073017f25e8e3d302bc50eb98873f5b1b25ae72cb69df60662e3b0d4b1634a5734bf90e10543464054bd897fa10ff5b6c3802bd3622d139fbc7fb0161c30b5feba6eb652535ef0bdd220747c0e8b6c0836399ae89cb67fd1cfc93e274ad1e65d8e0725063ba5c62386e3964ecb7545fc08026035faccdd01cd14c780ac9b0523382b7da54be63f1b61923c4703ace2fe39d22fe8dce88b9509731fae412c653cc35e8ac8932f059bde4f7edfe051aa505bc44c3f23b42cd79bee3d5ab3baa8e332fce9b2b41c1be82aea7ecc3e07a450d17aa96a06d96fedd7989ef89d670f1321189c947c12fb270baab9916701a20bb470e6aa42ac8df73455733c319fdca023ac3984f73731bf71c6c50c3cc3a5dbb9d05b8ec9639c66aa655d14e6a2284591b3e1d6951da53cd045b3c14179a70f8556651b0205348d11c6829d0074d52986b7c677b19b13dfdac8624db0124316cb32c14774ee17daf44e33e4c5dde7ce33bb3ba5c96805e44ec131c0f2aa4df109de27d4688322e1b99dc3bf7352244f3b9c448d7fb9aa42c959ae2e30741dd2a0c40c0ea7d5604defb2fd639938ef815081c0d8d12c0720cbcf5c5eadad6dd1c7f8049202d61a80aab167f2d4ca42c656c31168d3162b748f0754ef842de40f35d7c0a3ae249cb6080bcde5a350c11db14bbf3572b2e9447cd423711ec28f4f519c2cddcc027910b40a6430492c93a9d96e92f51380631ae2fe804aaf42a17764718dab442d19ce38b8042bf3baf04bf008387a47b360c1f0e292c9059fb94205b2a3fa2921870609da31301e2434250dd3ffbd1207011ba2f11b6476968bac31a20724a7371ddabb0a13592a0a88fa532bc3f1f2d819330849afbfb8bfb4e23735af600a90d3dad1bc388307d21b84bb134eeb3ba24d44cec76e61c39921a003904f6815661c8a24e5b41225950857f68cac6d365b2e7c2633786d673d6f6c8165717d46457818ccbe5ba96aa213c8af53b00d0cbb188ccba127f4b4d3913933ad5385e48d17a22fc3caabfbfa3bdf38464ca517dae2052df434f860a94f443a3389efc61bbcbd4c405da089f9311b057c8fe19e914cb93495b158d215850b0619955adfd369794f642d9081277a3e8a1397c2896371ab2a168d69e94e58cdebe328d5f1b566c8f50652d59994997892075153e04691b264d5da604647d5050637910971a12c2e1bf2b631e0c2a4256badfd6435710facf44c368c91fef9ab1ed1051c0d28357aaf836d1ef3462f4baa296dae6005c90e2db87da2a4db18f17d16fe2c86ce4b7bc2fcb14150f298fa8d7dac2b7e0e6c9ae76110e62dc84f111e813fc149abe45a4f05d1922be3459f88bf3876b425c6d062fa9704987f3317508efada1377a1ae1fbb87354a087016d41514b2d388081cf59dce454b8346ce19d8036471d91049a983730ace7b4f65e91ebfe393747607bfec0f8953901262a253ff10cd67cceeace07de6ed780447bbee806c3287e2046ce9c6f98716fc7ae9baf206d36ae46b8fe331c23456468b1ab6152811b56f1ca15db43e9d6bc8514d577c43d5d55d1a2274ce15fa809626cf5876130552fe706de3353476c59eecb16e039c70ed72c44ec1fff590735b2079159f0308e1035febc2c17fdb7095b901a7f0f19340c93792253dbcd6fbe9ed3b4b54e3904ad0632f54c234e2534504a81ccf52fed37c3fadd8f1c250ef46bc8138faeba0b19f306271a73646cd00c90c1d3d31034741ee03ce00fefd267d8d9419004f5da702fa6d052c62914103789a2b01ee0fb3e2fecbb13aa453034e196f06d25298a12de4f15720a4a1740e2e42a17b80e6da07cc8a2009dd8940a465446225eb6957096367b67226107847727fad0e31495f28fe6a4a30c3b8c914f9aca3d152f3e69b516ed1bc49fdf99ff640ffa894215f6546013299fb6567c4dce50673647523f259eff73ec5c7c2b6502a04dacd7217c963e375cc8b2b38ef48d482455e98dc38bed34b5875548c2ef01f7ab0a59171c93e076c45f6a68cb4d5461ff1278c2a83fc2b852e5614c9fc46363168c94c09e45d7133e88cfcb87c3e046aae3a0ce12ecfac14c5a18671df76bf7ce81400db9ca096c3816b53775f2d9ede2cd71480f0037336212a12f5cbc9e5741b4afc83afaacf83ed2dbc831c63cd92dc925139d6799b5f03be954d0eae16861ea44bda29385b630cd13b8c74213be39698241df8def31a655420865248b2c7b236cd0cbaa11a13df89b6be0213b0a5f6b73baec24c82bb02b5de29370510ef4ed6c0c8a204ec1324ab59b297511b1191cfdd59acd1587d039fa40e0b4831a42f2b183ddaee95a3f59f22870383b08e5a35982a786ee69f076ed61358cbf3ba20b49836f3b79d8db2e768c3c24a944c3deca47d693f1825695bfab02d783ee91399aa04da8440f2623862fc3b147bb3fbf84ab1f1c42a44a395aa4154f1cbbfd0a4b4ff5ee44d5f0ba94668b57b50218511134c7d01a16b42aae4f4d6d4489d0436441c57b234527c7fe988f67158aaf546028eb54f86ff7dd18665b53b44b45f267c29732477b9b9d4e4546f37ed2165b1a05fa6c1dfe447e4972ad9223b133f8dc7ae8890b5a6e8b5eab25163d66debfe9dbeaa5804215ceaa612ce9cd8b3f5fbb66dc5f9f54bda0842f986d3f744a6b3cbf8f929474c33228649c92af5dbfc2f2b84413d1c5fcb66975e7ff48cb70c24dbc6e40a9d95835f4c8bd131899e43071d6df646367161e1d28908824901179ac68591026b3022df821fbbf94b151c8dd2ac1178655ce90c2aaa4445bd2be3b8dd3d8a01d4cef5bd1a89c2dd699e95e49638173e25269d42d6372fe50b24886cdf12cb4835f9544163cfcaf3eabfad4528c8d41d47a776c7693dc070999a5c9d7ceb882a8310c2c9a50938e97c245686f86680e1571adccb6356efe20729462f63ffa7d44a91a8cd19c36fb07d73b53b05edd627c2db21360dd111865c3e952bb086fadd27ae2043ef4cf0e79d9189fc9be964da308993ffd97a594700229cfa0097d1a5f3ce57f6df23bcb31a06ae40c20c1e53f520109f7514c83edf097003cb12e429f08406c6e86c0e7abd2822f4d1ca9b95cdcf416326cb94a998b6707ea5c6298ac8cb0c316153d7570839a97ec7d9de0fb89c7f87b09000bf89bfb371a4e5cba785a7246debf07c313342f4664214cc2a457454b9cf8a3880287ca8853ff3bda473c34c489a78dcae4f124aa89e080faa55a4103d1b4bdcc491477b7805c638528a05ac864bac0370790fb641b12b9c52490f500b848f6eae0f340e44409893deb4cf6ffb12878ebcec39eaf4c9661c2e407dc69c0265775173500dde8bac2e830308e0e0dd6f18f2ad121857161896f0e8bfb5404b88f8895ddd9ddad59d637306877dd5592e1bfd9fa35cba21e3b0b433b22e6af14796cb2c13886d99087d3a1e0e1228c51445291ab82f13b92df382046d0e77734af6703228d376a47fce33fda21fd829c5e6a2f180de53747644f7c98a208342b141554af0a62f1b70165931116860bd1826fac813c9ed350b957683636f89d2c0e407f61fa3b5212ab5b9b40711939e80c2e072d0239917573fb651c619991d41c9634cd96e6b91417bbd329e24aaedaa581c0e55424b548be2733f12e4b86e401a216cc8d4b411e9c80f7036f0ede4b8c6d2e63728c28b0cc31b61ba832665a3a5c9e4d6a75489a5e59e6f0082e0a167a15824caa8308656b2030600f7885d92e4cd60b640a3a4249e8b28d7de380c2b64a8c040480fb6d575a94368cc1af4f968f0f5576d99795005d24f9f4b98f5bb14f63dabe06fade2d1beaa1d5837fc7ea00c2d3e844d984960e196c2270dff0788db7561ec5067d200300b7453de103a5f403d08b240952d475cda3fbdd411b592c9f7e90cb135ff5d6b592391b26c7ea2fa33cf51fc2d7bbb47c3aa9feb7ee1dd85ef10001854d79c0c70d6a88f421e8eba3e96a01ab9d8a003dff78fd659579221476666ea12f1199e53b6926629510471d40ce3ae7f7156fef0220a6c10a4a36cef9186efd2a86e62fa45ec59d4716a5583f05e65934b2e6890b674e5cbe3d272e74e689579518fd4e53fce82d3620b70d1207ad1c6a17dbc44ec1387e02970966dc610448ec29861830e5721f71b6f9627646f76d539163242e0d3fc1a2252dde7f562a5f495c3c8a57ba31509cd62b1c2a70a30b64186c520876950a8c4f4b18b22dd404a9f3f2d7aec6eabee0342c23de1e792625c8ab0aff817d3b83592e992535d4788026704e42f64675a8b96b35cfc5a0be0ecc76d822358cb440981cde43d26522c29466eccfd7c93052c3fdf35ba8a5dcae4b1c3d696da160083be3ccdd7120fdb010ce0697ceda81fecdf74023f92000a603b015864d4bc768b8981eff0f957f11da8092cd5ec64bfb9662b52c4b55dfebdb8405453100bda7c1df88fda6d01505d4157ec9ed2635dff3df8284a5fb78b6b27d07088bd600a13bcf38e796e5a8a81486518d6e108f10953b77fbc76cf43a7482dae70cfb620c80ae5bd2c4563ad58391f4cc9a6143274d41db93925121613c0ff5142e31f3654baf64caff8046232422b6ff4995f385663f4f4bb2d4d99a9645395531fe8ebe314f1dc14c85a241010aa5f59a33b53ba52afdcba6866fb98b6f58e9a32b13b2355fbce54eeb1a09b034b825593d33a055c3b43869a41f9b55a40f9b8855f0f1b8c941a426ab3300c82a451e706c08e3d59c494d9b553407001d821d2f6737c6662c262ae2752aef2d2bf7b55cac504d5d4c680ea6895230380797d942211afd05a2e6ce76f50d5cc8dff8d802e8a4db36d6f0e51847ca6b8e7894246614e0b8fd68d76e1b2fabb4b5b191266ca4d69138e5f02ca48a37904157aaa2711f3c189f938b574e09acf9c06f20003538e059ea3887c20130c38b784a0f7b328bf6f8b4c901524fdf058eac096685bc4a6477f9078db6a2bc0ff4384ec9e2ae42e8b01d28ef598f5f1f38d445ce611f969e5978adac4cc1da1e0aa6ccef4ec0c5a66444aff7011681c60677bbf174d2603c01fbc303bd6c74340162ce5985ff9433c234f4a829e212b37f674407cd305fdc0a90604d7e46c30d887d05a090b1b66cabcbe81173bfcb5de704de611d7c9395936804a5012e1b8d1f3eaddb700be2fa7a2f08e63b0c8d4129b47ce50f2b03443edd2a903183f0eb1e4ffcba36a1b0a4f13f582b5eb0d9ada504859f3f8b18a0cdf666ee73dd140a4a3b138b90f4a8f910ebabcbc9c70faed8219d6cbd4e757ef20369c727b8b0e86f10001a5defa7605d3fe88b5954f7fc6f4b963d0ee5ae07b0fbe899e276b438707361a51038c144597787a46dc8b0d0757d9e7ad10841ec7076c9bbef4071e5da05ec731fb292cbc79c1d1d9e022fe63c0067ba6a229d441da8f8c2cb828535862c4800db38db45f771432b41ee206b1e9c3e41fdcafcb320cbe2b479f670c332dac6790403f6514e8f1784f8ae17313207cd65780f0d6a4b02f462cd546e34f3f69e9d96422cf3656b0ab9da0ce4318ca2873dd96da306747d869e915532fb940e88ef358fe10d4e47e817a8197e130071f5d3c2736f29cfd003a768bf4d5992b6fe5e74278c8777daf13fd603ffb9a12d53d461bbd1b96f85c0db82874750fd38a9f93948ff4b9a5eee00379c90f4b6b786e05cde0aea0a64d5948af799ffa80eb14edf2f957071dab729a679ea3708d2e6f273319861cb75d51efc824a6df487c8d28e4077cfd744dc5d17bfc8375481728b8d7996814e9c8a5fa4d744e72282ca5becc3b5b72beaca295e6282e1067fd8a70db25952302edc5000218e0922280dd37feaab7a9b1e7a258b6300a167d58039f79cf4ee9cb647c9d1317e27d202245a00f2242f7811d1bf9ad83bb14e703ed221ed0b32eeee840efc43dea1ff90cf070be281681754dcb0f40670491c622f943cb54900ed1bd7a3886dc0c39fbc3a30e324060045ead54b92438b64f47900ef337c5cb5bd34628641a9a6cbaefb153890f3f8331aaf464e7e8aa4ae70c193895dcfbb764c94443bfcb59bc93ac1308570d3a8bdfd35733c689df32503fa09efbb72bbe8dc8dbde931097a59fe073414e1d952845fe8501c6900a57b218b3cd70cf1385a27277973b961f08f192c7cc79eb83cea0e1c8769b3535031528b7381880fc5002a404f19c4999ebbf6a3f9795d39622bd80d7d92e76339535a810cb11b6b1a2d4a11c92bae8c0ce96acc4d5bde09e4a3ce64049231ab82a029338791d9bbe9c103b2dcdab7448850fa88df92fa2637985f3b92940f2a2ce4f4e46bc47b27f8a404566a9a6ff6642510e98562937cfaae9070237fd3985c8ca81d9562ba1ef0e8ed606506f4ffc3e3a5c06c6ffa0c902381047635904d15a74f19d1d49d7ac503c28a1acd3201e7062d4c1f0c09f08464ff81d85e40166c1a6236272bd93a5cb0a544abb4270d4462b7b1b5af588dd954a6d5ceab5fea2e2bbeef689cfdb3fb6daaa9edf2233f174e749492d9dd95889a9abd8a01ee140659d0812b67f777d254d4144fa01fa093ae69ab60ed1815e900537041775bcd47f71b52ed24f83e16ce962b4d33a0a7bb3a4a97485ef7a9831ad5a4900695d20d41b3d720c9b91adbaeb83017e8fa35b35798fc291a951c09943f972a22512ae83ac515989df8eb578d86d351767ef95d038a20c1b29cedec2394acdd174dd13f7c04a9b1f4ec0150e9319ad4073de55b70b7e2e4a61d21a666f76ed2d4a2e9a5f860bf09c1f014199a944c50f45923c60fd118359a3dc389b36ad7ad0bd94b7f3417e0bc466bfcb81c1fba7af3762d3b64eb87ab11ed3ecd03245d12949db7e03356c35d916620285d12283bf3e167a0865a29d22050ba244876eec1cfa8869552ac015074495076dec3cf500d7565028320e99220d951829462775f8111199e8128ba2320fbfb41cda0a65012dc019d74495076de82cf580d77459a81a074492065473cf8bcd47053e41b0c4297045376ccc3cf2b0d576586c12074493065c73cfc3cb13434569c1b2e95fd0f9bfc6eb4cff3156186e673dc27652f1c485e376756c08fc173875d05d565f8f7e97d3eceab4ceb2da34ce7a4c8b6a3a913c445048ad64bc35a3092aa9a0e7a0904f8fe55640b205640ece6cf1dad697dd9223577b9906743c31d6e54aaae5e1ca4a08a7d31bfbb771e7d2606603cd0945931d38035733a667e235b22974bd7ff662fe2d323790462486b7b77db7b4b29654a291a0cf40be90b9208255be7942fa1ab2628eb8ffeefa194f7471c5efe2ff3e9c432cbc0f1e5d2d9eeeef25f60567e58eb4f59253de38a5bc1d1beec11ba1364d815b14b9fab9fbdf1706a31902ebb7622c99d1daef1789c70553f7d72c77e913d74e4af8d615b4e69bcdcb163614f99c9713f72294afb1e5f44ae501a88aac1e5797c1097e7f14c3430088fef01e2f000bfc7e3b88028d27311f1d97a0c56fb9f3d5bcf7bea81d5babcf624f0fbbe98c681e008fc0c1cad1dbddc91740456eba27d8fef2453f4797c320acbe35d3ec6359d18bc62c1535bb00d00ba6095f7f43d0c56919c8c4bf967f4ee28775aae067a7133835f20248d24235fd65dbeecdc9e633be236ee475fff878f3eb993491c58c9e3f2a3d778c5e347e05841c9b35385b53b34e41aede9a7b8a67bfa1d902b97a740e4aa5b324557dd0380b6698ff49487e83464a3587e72e9f3e8c2d3ffe1dd922bb9d3d359b4cd7fabb5d3baa753f7cc96368749cdde63269615eb45a7139e9fdbf1f4bd48ae668f4c25d1363bc09945fbf0985cc91d99e21e058e275047d1a5600e2fd24ce0a8591670b42770fc5bf298c33ca4bffde8478f7229497b14899449c9d344c25c15857acc8b4be5eb520974a98c5d4aca348f05b96a9c3dee05f5d8a59e46fa248f87f4bd4f2af1907ef749265886feec912be984cf2cda46aaa07d3cb9f439703cf958d9e4d2a71a28775886beb401736af43c3ee694d419d14dc75523d09f78489fbe4ce2aa0d5ce2f2d47b648a3e95973deff190665f7ff49e4bdf79dc095765a0ef784875a6b04dbf639a66ede9f4e10c4d2c76f253165c73d19d72b9732e778f87ddc4c3d6f130492b6199fb2cd32c416fb9cb5be8cf99437e248a3db96b48aebc356acc73356f3193be57c0abfe8153fcfddd23572df6f7ab75b8efef9d56c235dbf71f71e2f612eeb87dff0e5765dfdf3f4fb7bd754b6fdf82d5aefc7cb6f64ff6db7ae71e0d7ddfbd18b63bf6456957d3c0d1ae8039bde3c48a35a4f7755f073e9c66750ecbf07b573fbf1ccba0326e3fa7a134eda402cd0bedc26d20d77ac85563c38878d2e81ebacd37fb9a4329274b525da23246905c3550d06da086b9aabf9fb8ea85ce68f1b0e513f65b72e52d178c712738da06abcd61a1279ab80e7a8f8746f65bf6b15867adb4d2296e1f73834b32cfc4e9f20b4dae763ce9f9b91d1f8ba41d1f8b34fd5e83a81ae4fb07711087498341fc3d1007f5ee3dce8e9720aa3e8b4efa58b49af69906562b9f3e5b4dab96f4fdd5731a1a4953b30a562b2da514ac96d420ea3989856511a5bd5c434405594374e90b845d78643302d3e630a9e00d38780bf3739864f5e51536a89de7f76b6cd8ffd82ed38fad93e37f6c1e1ddc7f2cba8946ae80eeac6098812f6d0e930c6c9687b3e52dcc974ebcb8f36bf6ec01213d101ccf8addf91fe9fdf3e4c7c406167378bccbe7e478d373deb9ec9a0dcb3f487c6e77c055f333e02afe4182e7cee7c155ecc5f43bbbb86377258d5cdd2053f3a70603e9dec04195741f68fcfb1f8ff7cfe5db1bbddc6104a2b4ad0adb30902e14bb43f643b2df409903dbdf4fecbc43e610940602e1e1f2f4331d9fe3734e6f7a8ec7f7eff2f5f81d9f7cd4e73bb2c535d99dfe1a8fed99a4ff0f42fa077198648f239ff41918c4fb1e208ebf477a97cffb1d1f8ba88f45aee5ebfe848fe5757c2b7ffa543ec767dff495be7e36b09893b3f2f67354bef4f4430121bd0d2c925e885c43f44ef8586431c7c7a27b2820f2f9069152447f1b58c401e6e4fcd03dcbe7e4ac7c8e7dd2e7a87c4ee9bdffe1a68fc596af088bc5b175c1c3399fe4baf34b3a77beddb9f35578eefc159617ec4e16573e16553e16edc762e96391f4b1e87d2c765f111615f6078d87d289ed13e48fed670f488e7c7f5311cd579ce0a4f6fc2f9c71ca5935aa301386ed1f6738d451812bbfe566ec630a978e10b8de0c530327cbd0e74b33700441fd9843ca14e4965b700c00cb4ec6c8b9fc7383a18bc5e59f1ba0e0da96d37c72e58f71e5d801168b757938ddd1bbfe238b8dc73e3a035caebd18e6a5141c2598837c79d9af7cfa3307f9f3e620df4aaea13d5d4a9f2dc153258d45ee699ac1f1cbe8ae3b5fbeacdf6ef9b2d5929ebd9b92ad3fa58bec63dbd52caef1ee94777e1f71556ff64fe1cf8ccd6ad8b4398eea9ee58b8813d581a81a547ee5bb5f0171987460909567017156703ccbe3a880a8d2b368fa952f223e5b12586dcbdb674bfa66c94902ab55f9ee4b9fe6e17c1c9f95a9f9a64f4a611f0779b2a50d1c4f25b0da1630a76358e45cfb6cb76f969c1b58ad0a98d3ac284bdcee59be954f4661557ee569b8c6fbf909e055b36401d8460236ac22fd7c04b0aaf473fbc958dc39f2eed8acd173d2c6922bd34f96b7e068af04daa6fbf92592f7b50f2c331f07b932817dc4556dd3811d82f631bf25c99dcf81a3f5d4d848eefc11385f96ba7793c9bb754eb73c9cef1e0cf252b0592c335fdac08e34774e4e718aa6fecc40fdac77f265e7650658f76c6851932977d5229e6f578c9afcab7df697e58985409968ddd4e59f25886e73a3ee9778ffc3c739e79cb5d62abd97d203779c3c6cfa99f6a394ddd43e4dd3e6a8fbd1a803ada7bad19f307f1c8119a8d1e71df3d36260273dcd84db92d68bdc6fefcf967e4841b7394cb63792010e9c9eea77b6f3d9cad73e2d0696bedcc9691ffde969605bfad49381aff6f575d5e8fb79b477fee8995db57dff6cf9db76fde566df0c0b3450d8e9610fb2c8e65b1a33265f667a86a67f9cc9a17fbe87929d9dbdc171868519fa332cd0c83967682638fea5200d6ccf8801c6cc4c12a8808268f6cba73f392eeb47655995524a29a594524af9596dc95c5c297f78cf2935295dfabfb7ebc7268bf6a7992feb8ff2693cfc315fca6f95045dd3ac1de9f783a63f176460fff21d69ee0c38dcf9342efc904d237fb88a2738e3a137173664e1fa0baef21b5860c155fd5273971333a4b8141cad9d4f03569bd33b5440e1c595601823a046567015718d88408a08dca82b34132764761ce182173ec8f169c28811a12d623118222974408421236dbce4e59f22d69045ac2199c8e434028c10ccf850c162e40b26a630e2053d30e305244e2d8cc0c134820941cc60496724091523451431a7116a14610419452801cac987ea3e58d2e9e78819662cf153040b641d7e8e108d526eb287db35fb0a3e57993f96b204846d8f01daaddf2d65cb8fbf7efaf5f4e88c81510d5ecd43d94ac8b9840b765696411c09e3e787d7cf0f3d977ff8e7871d3e013801ae87b028feee6617d5cf2870fca4cb3f4418d1442421620911322002c8bbfc434414d48bfeaefefc90c6cf0f6574662ffffc30853bb2a99460f4434450bdfc03040fb7dd7eaeeb6e3fe7759761680c31492ad14408e2658a21885ee6105366957208284d7cf5993f9ce0ca104ce9a3fd2082150c5104050307314802832652f09a41164340e10222ab740af106133f607c518508802081c83a18e2884aa7255dfe1162085910ac64cb99f1594189ad0b243e48ccf8a810019b594108239a104c9098f1d15a6b4051291aad97295a66fcd0fa4110ad2c6668ad3e45366508666d91008923bf6244045a104c106264831802121bd720c4d06c4b105fd49a3d6d9921389d82783282198c208817b48260c10f41ec00e14198e0e5678a2673d2b972f9c70553ba1d702d79fe003184cb5dfe01628c2368cb3af43205114628429be2ca8e10519d94800910b404475e9a78abc5408a9f23550041c528484a13495430860a867a054b36a0024700131a491e407b508336a44001174d88891cc5062b8e14210b1f2986a63842a45818199a46d210410d92b410670c4929a5ec97b2bb31b80ce58138dc775f444405f148cf2f97a5875cb33dbf8d816fc83221c9fb5eb21d2f2f2fef3fe7dfece4aaeeaef6f4471dba5bdf08ab7d658006e650bb8ffbe40fc73ff21326d2b8fee4a21adca16feb3c5141ec3ac883df0d9c2e0f767eadb5beacb53eed2b69f7554aef86826d6b65af6af332ab863847bbae9ff6cd21edb7b986f2ec39619c3fe7df8d36032b1fc53f41946b323cc1f1f50cb8cdd15eb4de823f7b6a2c724f48d9313c2376c796eba77eb93eaa70fbfd8a3b6a9aede1faf2945b6b139cf1500a7bba0c7363c995977fa07471c7999bd514d037ae7ff8f232ab52523748e0860ddd38d204378c4c61421b4760c2101b3f280263093a50c293244821e589355a80849d239480a8094618a1093f14618a1a6ba471061a40382388085a0c4119c20dcc6822841794a102324c1084292e204c0942c88d1f24c10769f4808c316e9f8ba7cb1a0dedc6ed9f734e1c9f8b1d643ddb59f796abc68b6301edc63dcd9e165f2108de2d57f9abf8f9b2277fbee0d37ae7971f0f3e1944d1c02f9f8f78c8dc6324a1880a1ca42125a6049dcb3f6b8c71bafcb3c6cf55420b8d5800d08801000626058e75cc192c040382df0f2106ea6ead1d0522b80be4c1c365e88eda8cec3194155d1e279ca0230bca84aecd8632a29b155d99c5b4891a02eb041c384c4134871938565654ac9da9426011c20a89e469337f3a499a326c112e09accb3f5288ee685b57bebdfc2345e872debde09373b9f9d971ba97bc177c72c8b0a3c6d258f235cddad3e93f0c6766b4177c725ce593e3baec2afff1059fd62783605ff03902165df924efc65ff0c9f17c723ce43b5e6ef4f7059f23ad9be32b8de529f97c5ff061b9aaef0b3ead23fe8d9316b9febde0d37ac1c7c5decd0b524c715591cb77f35e90620aabbc204591877c478df5820f6bc6a3217be38d37dcb80ebe20c5140ff9968a5cc572957ceb4a40171c27c60f4b05273440f2e2d410bd527e5b9f3e057156ca280326568ac3a921d22f2232fd4e32e5dd58e4a2669077fed458465a01042196d850a010f96ddb38eb32f3ad9ffbe0031b30917e5c861191ebae7eed048a13507a706408b17edccc818b8c2574604786109b07094742041398e84ac8c0a27eee851445b0442ecb5aa003b17ede851b2d5827a185583f8e6af185165324c11251fd9d8416623f1124d60fd5600d2d662f592e78014b94230801104ce4b2ae7e12c683216022a75152373942ac9f84a10008969839142440b044fab59116885cadd5938006104ba41fb38144e4a494010ac8c0c1194880623e2983082cb17e32c912d622660498583f1b29ac061844b0c4faf1129e88dc6442e79e4600bbfe2d3bbc6bbde307aefcec2239230d96122472b352274d1c81871022d72c15440113eb87003344cea530821aacf671e20830b17e2e282176ac070630b17e3ca50a91a31dfdf80d2140c112eb27c302d108182ca10825442eebe8c759b8c4fab1c869b28a1e2b6062fd1a0889c85128602c6148c4c97c20f6d0f2029cad8a224abf875ab4061491823980e20990d8051a4b8089dceceac731286ab4c423c4280326d26fa689c8555aebc632fd1c0483141489f4db2184c8d58eb5ee67197f29644f94cb3a4daee85b15aee1cbb77e3893491176c41eb420886d8655020830104a8f5841b17e384d823678eaf720734608c40a760f82b0a20a1e11a793180a127bf03444f616c696db9db1461a8b5c4d0d2428e911e9c7e940e458bbf379b812944e6a62467329861db551057ff11d2e65d195cf9e9c3982b5923d54610fbbd0d943f795d5a8c042e8dadb19eb365bd1731956c5187714ba0c03d2c1d5b8c6df0617eb2f71c7ed8e9a0dae4cb10cf738a3cf7ef3fe86edbbbf596257544a4f7a124884fbd2b3b8421a3de95954e146cff25269209515538ebf598283fbd2e849a52795485dd0882b594fa888487e43fc4b249088ca8f9ec5d2df8012c23dcbb38044569e8b81ef6c7916956f79f66e587996c781f4b57ca8f92d5f44e4fc1b225f080e49084ee9b3df7ec80e3768dffd0ddbdbbf59e23dd7de0d2a37ac3c072467f4dc8f9e0351f47380ac95af5fa57b2808040768025b2d1fcb14cb879a20109629df91a9fe213b68a0ef0e3bd8c022f736b0b8f23bdc80124284f4dab3c8fd0d28215be9b76771e563e0db2a9e10d2ab3c7b37947ea4ad7c56e543c9e7be8838bfd1796e20dd50ea5cfbeddd13526fc84077c954ff06a2fc6df8c37f38109ddb4f0a423908c4031fe4501204422353fd45449e965c69d5d5a216d35e03896c3c4175e7766dc954f7c8d5e8e9eb76d18d551690487b642a484e21b91a92abec5bac1fdd91a9d18f4022dbd7ece34109a99f7d0612d1be8aa349e4610399413255b39abdf6e13011d245a0c1152c3104dae3f490030d20b04416ab45d4c010c831d040c2126be5a93d7587c6822ed02592abecbb3e4a48a681b30825a43e65dd1f9e7d9548a67c12cda2223878034848ae7a8848ae1826f6d3985c15118b88230dbadd1a35da0a92ab214d6806f1487718463383826e7fc78658de6a297cf00126f6bb4ef3b0aa045288c47e8d46ae7af41e8d6134375b2942bd85042757f1d0dfcfc384c2f5ec7719efe1fa372727d81c520a82ebdf0c93c5e280df0687d4661f545e3a71a63703b34c4f574dda0e83c9ab9c2cfb98cc99030ceca4de0d9d744eb0f3340f3da8b1d05a4a295ba2e617b92dcfe2715ba6f2a4d3db1c26706c27eecae96b17bd1c09f4c0d172e078024f151cff8eb65b35c8c6e173c9cf123d77d4980a1b4cd184aeebf0938228d7fea4e0494b17f667099ef682384b6c69e2f6fee3fcecb9c94b3650fb1fb2039782ace5c0835f0a7240def92c973d1a62ee0497784035a774f9c61b36f2c739e71cd297df7843d49e07bf4bb4674f0802440dfc890389436b9af6acb9f6ae696dfbd4b2b607d10d8e3cda68589535100fd9477fed3977ffaa75d56e96dd1cb2af3388d39ddaec6639993f03ebb77d2c533f248f3a9c2eff1c6da38d46207be68ce9d7a6df3d989927f83773eae24666e6ee9c93a3d994598637eab5b954e29a2d2391b846d33c8f6bb2ad1b71d76b28371a71cdecb68d6ba4a7695ce3a42ce39aae5cc3a32cab1add466666a9eaa494a36499d15e29a59492f3ae99bd8ef999b97b719aabbaa5abb00cbf77bbb76519c90517b6bf07720bdbcfb5932e7f3bb7378f56762c53c69c9252e92e69adcd1246291b406500da6c61c928f56ee6cb395968ea5cf16ea48a77236768285bf95245ce39a7e4b7944a497359ca6df3d188e3c27ff1ff9712cb0fbd1bb920a96f97df63b69fdf87e6f5e7228d3e00664f69b31f3599853399e6aa96b61ef277323523e9dce4c8399a965a78a819b21e2eb34c682f4ff91aafb497e0387f7ecf193ec9d14a696ad158b695910a67bb920a89e4953acba98c563616ad25f4e74c5db38a071160a5e2a039e649ea683f01d53912d65efff6d77a470bcb8a8a2d914c2d5a27b3e8b1bbdcb1958e84ed9f03b8fc3ea22347c2fe1d552e7f735de79ecca285d4491dd87e47c2f6f59265197efe3942cd30baf54a7004c1a5a0c632fc73ce39f9ab23200c8e5fb819947cbe41ae501244d5c07df742fa1924c2dfdf81449804e16fd213e9e740d4f660b5dd4f20cebdfc8df4fd27574034da4d100827c17e7edf7cc2bac1199a0fadd7d778957d056da9a902687d9760fd64f0295ff0b05f9b3f344b95e0ba0915d8956db3227f1c5d7eef55f7744a3e4f4aba76760fd7d02bbf5f5c334f5b582baefcb1c195f3235dfa359554cacf61d26e238083abc6221470d5a73d47878c46a3ad889ed86863dab92bd62fee31ae705dd93e57caf6e24ad9655c299d72d2db491a987d11c081021e4aeab06c899e4a3cec09f68e87cdd3e2a91be8f43a4f5f06b9ea141001898005788035ac0a33eec85e704226d8c11d59c80aa03b721aa5cb53b24a67bf26fb472c2032d56fdb9e6ec8a22cc2124fddcd32c854b368410da8270a4c07d76f987439b6dda4c1ee79f9df8043505050502bb9de4eb44bc789ebafd95b95d44b419eeb3804050505b5e8bd21a86141700ff216fce51556b3f6747a7bc76eb50bc975cffa4a1fcb35f4facbc040b8ce3be02dfc51fd456ef3d3afadebcf48b2cf9e2cc34e0c0bf9d293bbff9054d8096a42348b1f26382145c9910cb4543aa5770ffe5d67adb4d2d9854f739bd97e2857339cea1f9ceae7492da7ba638d27871c326ce6ed9de00e19e8ee0e389a834bb4d658d2255e66666866685c25a9649a1916666658a0997286e63d7c8e8d1c9b40e40ae4ecfc51d3b4396798680829989999a128e01c50449cef6307c02b0eb926bbfd335c43bafd63016e37c85658f6c24307ed89097b18cec8d5f65df422eafe7fe4a0577f17c15e0e7650c76239b3bd1b153c6c06c3196f21ec97ed75ffc365e79245feba8f4570a763b2a7062111125c20d1937950cc8b962b7b2dcb7c613bfba1808c1e65038b23941029e2f63207969f390842332ec8e02abffd41dcf079dd6e277aa97147163a56096053cab8ddd2f9e5aab1f371157f713dfa3f5cfbac012cce771f0f7bf4b14c65b07e1a932971f4b1b87d2c6a1f8bd9c76215672853dd30b05f1ef64b27967fec570b5d46a187ad88f4ce8db7cecde09871964d59c1f16fb39596d60cac95ba74490437f24ffaedee746ca193b9e532cbcd819be7f8776a9ab5cc141ce7fcee717398f42b4b707e05032ce343e69d3daeea97f2258376c4249094630ca08c02a42125474b67c241295014a0ce83c16bdf3b465090a7c3bbf4eb6e3e4ef793243424d479b2254b52f627ec4075db8e1dde4d967dd9930c08f55ccd90b8fa08d7502377acaf31834da938b82ebf43c92f729578b8e3a1ff8eb3eaabc2e48a0893f944ba27f1e8a8ab6d244ffb98a2576e46a7dc2f47433f7d0aa2e873eb7898c4437f770f068f81bae80e1d014fdb5026d887194d8f687a846be8fb37e177944db0f2474abaf4065543d7f104f19aa77ba4e0e19e78f8f2e32e7b370d6bb9ece40aa149348b9aa5246519488f7cf5ca36ac063aec357be44bbeb80f85afcb5cd993ec8757f4c52abf6530aed99853768b9bedc05753abc26a711d6499a2617838a41e0b9c7438ddacfb788a8466703810a77b9d1eed7768ed19d03c3b64170340ae0ea72b59e4de5b40f6fdde4db746b765fb55ba8ffbb2ac1665acebdfc35b40f6b28707835f0a664858467e992b6bb56137d08362a900c074315e0c5caaa3ded397ab50f4060fddbf63e0accc603993e54f5d7225875012b44006487448d37195f6b57e05471d4eb75f7379e83a5a922996efa8b92e928b6a1611ec8e4c04bb9da3a35df984fd7af9c70563dc7a47ad850242028930a94f847bd2f30de262b1c41248a4fb12f7a40fd27d09d458d9e57a61191296f1972ed9f270f60060f6f4f44829e5003a2a80cef36aadb37ed5470b3bd6d7adaf0a7395c692abd26b2df9aa2ffbaef23e5454401c269a060621bd0571ba2781a80afe1065f0ae94c27ef3c08a9664c3d297003caff402f03e08e93d1087497d1cee49a0d60ae27d09c4e9de0335964c5d6ea6ebaf5e504bc232ee57b66133d07526e8aed78c87aa817bef83744faa24afd6d70a1e901ceebba7af6efa6afaea17a594caeea3a1a9516450ea2b8349f96d975d35a5e7c130e79cf4455f734a4ed5d1f4b75d4ed5792a9ebb988cfdf3dde5a1ebf4cfe93aae9a9ae6b38753fe53c75d8ec45d3d5592e4b94b47babf3cf42dacebb8cb43243d6a1ed8edb213337666cf5db1d45c5a12aec99e7b4d476b3141b2613b0e0935e8811160284102222188d9e75158c63f13929e11652d7ff9923e6a9a7cc90cd6b52cea2558098e7588bebae73e48077e10d9fafea8a43e19d0876a100885d19787fe1c8d47c3e8ba302f7b37344f64301a96cb4e8082aebd4c45141b5c185a664fe4a76273983498c13c74206fc15f2ac18ed405bbfe2b0f55834ae45e480b65a0f1ea411256de0d0a08f7423c22266044218508a44b6a9a4b824328755dffa975f56119efcf5a57dc7e2e5c3cd0b9411072d5285b65b86af428750800d7c757d3ebcb55f2d949c6aa2922c0ed1f2bd1f5971d3b5a5ac6ee8ef5753d8365b039654baeb8efdedfa3700d47a4654536ef161459350d64c0551d30d25a515129324303d340063c031a60150840c0aa36c221cb0811d77b89f7dbb7a4d3c4eeebb7a465c54ed2483cd581de721d0f7dc5aaa8586b555464f8804ce97da8fe50fdf6aba6558dc7093a7a78dd0e97133c1d9b566bad2d5a4bd580b43c10d4f787d29e6fb7d48febf1919ec757faee33bdb77d7db97befbb66885e358f5c1d71fd5f27b80e04833d81699f33c132ee2ae8f6275eee0206faecf3f854be3dfa54c55b5c2304af7c8bed8e1e6bed507fabbf813759e752dc1787feb66a2d0720fda8c2e5c00ada569f7f866bb255e9bbe34ea4348662592c96c5481b29fb86d0209920b1c51b7709e98594584ce4f7c06447c7f977cf355b66c3aafaa703947e9cb9a4a7e2057789f78ec403fd88a772986c9f038415bb074213b3f79cd68cd83d105624a1f05d7813d1ad2682554d0587deb0e6e1900a9ea0acf445481fc43ee9fb49a42f8138444aef11614284f45d11d66cab7cc7563ec87ee985907e0524b2f2a42f81449804590189785f7a12886a1c1c22a4ef9e4910ef4b6fedb3f8ad7cff350fac77b58bea0f42faee8394de036b207df7424aefbd8f1d3de6414e24573de43d911729f130739f0cf497c3aac75c5eba50ef43a31349d6c7222a8bf9c7dc797cc73dc85b7025d7bf7af6ede73bd7bfa24aec65e010d4d781a876f93c10d55ccb8ef4e9b8aa5dd7e5df48fc3de6ef5e78bbbf5ece448f0a3ae55ffa5cb003b433247b09a2baabc2b7f85cc8b9e814f70a23a95b189d07d7bf3d06c5b6579f43b5f73f3cfb34d0e36391e2781e1f8bdc0e2e2b713c3a9983a16e29a576fa1c9fe9717c2ddfe35b791e9ffdfaf5ddf1b548b34dc7095fe6dd00c94cdff29545ce7f38e94b0fa47bbbd262b29453010089e33ccf2b7555e392556195ecf34b62e9d8f6b3d4cae2ad74ec5570c4e15694fc41695fe46ae0d8d9479f63e9b2acbbbbd6ce24a742c75c74113ad643dddddb4c122ce94b3f7ab66959d61b95524a29e9562205c9e8e870e0d8b6aba3eb8f6ff6b10eef86be8ecc2f87ea4adf92d68ba4ef6f492b14499ba6edd06f644ffa5295b4fee843559334fbfc963e5446fabc27bd90ee4b2091d2774f0289300952025140488f42097929452c81a8ec559ec5ee8990405406a26a28bd7d21a4570189a83ce92d4884491095273d11fba5acf35486aebf259554b2d287839462f972a66ddbb66ddba6493a5302e08142b9b8b8f4f01efff1170bf281c23f0882b77e0a92b718f1181e4b61f41c4c17c331b56a2c77eca1edebdbdc2e4975e3221cc7711cc76d55ebb8d4cb0b0c0c4caaf396abba20ae3f97ea46decd102056c5e5bbcfd9f1def30fddf7f81f3caec7677a1e397ec787e3757c2c7fc277fa2cc79b3e07c7b77c97441e1f8b2e1f8b3b3e161bc5f2a7cfc9c9f139a6277d0e8ecf69f9d2f7e74132e54f1232e1f0a2eb9f8375fd4fadebcff2e1f85834b14862f1984c7950c73c36f619bd460f351a6d841eea36421558851550c57a1d37006e005de963510002c8b6cb36ebeee66666bc1bf9335e0c7ee993fc7204e8b46f49f7a5aff562e9b3af7e1cb07703db8b1c205e2cd9d81a96afc7869c0b31d8636dc3eca3c151e6f6fb7b17ec61b04abe67e04873db9f23809dcfadd0915860165a92a8b8893d2487469b8123bded5a96699a967d2ca66919cbb08cf43ad636d258e4ca962223a7c00cb41e7185035cff01f8f383db55c3ce39e7e4afde91668557349cf2672b5ffa581a170cc02badc539b8fedcd45a3325b8eea45b3f172510eca8b55a0d8e9ab5a79314c3f64fe977877ec329a5948665fae547a3f5542bbae7d5e0c8837cbda068d23d50bc5e29e0f8850359f5bd3c71cde4033018f24ad529efea8f3016e40fc5a1ffb84395e36750aca281437f193cf4cf0102691b16da47cbcc88561c3d2cc333a275fcdb3c2d035eb5159c72eea0ebbe04c78c5ce1507f245d195cd5011a5805020efd65c032fe2070a203aeea1670e8df4f748a05234571fda5d7c9b51703e9b63f27d3b0927bf76e56641ab6dfa3c16fe9fb460e61990a2c78aeb7fc88bb1c89ebb86af4fe9ec4775c89ab4aefef3cee84f734f197ab58dedf7db846e5fdfd066cd33d601ffede3dc041a779b22f97e339ad93dfe9f6708d773f6bd77d7dfb72b6562aeb7cefeeaf5d29b5c18f15d6e630a12e037613b033c1de82ebe0e83282be954a154a29f5231ebab77a07964776c5762cdd486f7fb3aa5dff5d96f7c793b738f46f1b5cc4f1a38ecbf5743bc872f27392e5bcf3d1c8bdd14b578d3c7bba39ec2de870baf347a3d168346ae1396badb5b2ed1c2ee0f8f17475f0015a9a88c300ad50c4f1a38b0b2d1a11c78f3d727c73e7e3414b1f17d7780ec7b05072d99b73ce96b5a59b7c716cdddda4ae5b92e339958f59a65b0a73b8f24db4f22d65e5d97691873dc5c3f6689077056c2933c8db8ddddb5044891e1fd648020a932f7e2032a756baeeb9971e0cdd9b9ee5ebfb43761f5f151dbadb9203ec299ee29e5301c72257a503733ccbb380a30e5df739cbc32224d8eec72e8aa1a7fc0f5f61615979ff1c1f738a056c220f06edee807357debd19b4bb02aa144d71d5cafb0d07b6ed7ef31450e476a00edd5df9cda381bf70c1172eb82bdc0a889a41a50331d0dd96e2a17b5a901d9bc87e1a87dd375137f270b9e7b07bd2c71c76601379dd771e0cf376e00e3897fbce9b615e0e6c293dc5f36e684ff190e5dd6860178d4d5474fd9ba8a5b8aa873cfcba0c0ffd4bde4d832d44045bb238401c3fb65037a5a0e621a53d5bc0d15dbf1d644996ebaefbdbae8e8e5f1ec17acbf6e7f44e16b0cbbcc2f1fd9b76dbebeea681cbd17ddce97104a3213ac435f4291178b50d71ca7fa36cdc37aeff0652225a5459d73f143e0efcf80dcadf6c325fb3870e69da9046648b361db99a9ab6e96c3a1baca96bf67813aea7c7c7f17c9c126e87d3e192b40d8702f6c12dd1445850c1c361fe720074a9a9c332de1da74cc736cbb2ed963ebe6c478f8277c33d0a5e0ca49b7d5cbfbed9ab341a8da48cee388ae9ecd7998bf5db863c5c6d696c52b82376e858203b3ea62b7dddcd12584e001ddbee05e0dd783f4b605902d0657dfb7e9f14b357f6ba590dec96c64654b44d19b1e40a7cffd110d792abd38ed5193997a659ebb2e37ff8f73fdc3ded399e4958765285923b8eb21f2990abd8099427d77f94c6886824c5572c3a69090aef9e90165100717a10ffd9cbc0b1f65cff21b942e1fd29511577dcee381aa22322af061751d07c3c2481d5602f0f2712fbba952427e521f1f000699a468180ee904cf94623c17186048ee11de9d0e9642d1dea21ca71c7497477bcee58323524579ccec965bb96f602d26236e824341412dd993b52ae8806fcb817d784fb3e8e47a6fcb98f53c2ed70493e4ee7e3e837226299d1113e07e7c3f50d3662e33acc6e4335b8d8031c0dc91412f6474332e5341b0d71ec0a27b782a321571897822a504a29e50152eaf2cd7c6115babde9641b940d46379db6e98636985ccd9e0d4aaf2614bde974436de3b5da87f692296d8ad6f5e7b28f1651224c41d9601f67b491c140ba14f45ada14b4086f5cffd11be2fa6fdbb651900e1d61c711386aa3a1191f00a594523ad3d18fa6c1326ab08c7fa553ae7f07d4b4095048b9fe4e8b007433023b8e86464372c5e29604b6e986b6255cff4dca36b415d1ba0dd1292ce3df0db50d6d02fb88a2573b404a44dfe88654142c7242875c761c0dd121a0dbe0381abafe03f0e8e794523a1a1a0d5115aad77382370cb248c15ada68297af1c14b904b3963746094004314a3d33630b198178c127a1533458c4e5f79f26294b8fee3cb65259c6274608834afbb7bb3394cda25bbe84ed0e4b2420476fcce58e3fc51bec7f2b0e5b1bc96ab6495527a391e4be6b4a8c7f25a4b4e4b74fc0fe77a9c2f7fe472c4439ff33330cb9e3e37f26e28cd7480d6531eabbe4b477f9ca08b6b04bab4e4b397c369decd68b6d7f2d0eb2dec92d68b27b07a371b1dc9b72d5a0ceacb4a3d19b87ffbb6adf6951fa54768cb6b79391ecbc331a5c37939d3bb690f8295dfa3cb4ec40043c7d8830f57c704229b92a974fcdce973d133e2b14c49985c3bd43bdf8d60614c979d5811e58eee18f392ab972022a29817d78c7c604f6280b8a6f4fe3156f00ae6b5c58581ede03a4c15a78f45e9b1ea94d23e66914c4d37a4d4cfd46a61c30dd695d2362621d887b730c14484125a8a5a8aec95df1fcbadefb7ca95cbc922d8d1a5c5c35d60475c5cd7b9fd12d91146c9f5ebd2f25012d991853bc6bc625e72e572c453fe4860498094c49c086a22c442ccd075791243c48dbebd9b1c9b169691d2492519fbb76d4be96c5f43210f5bde9f79635e85455ccb97da49e9a492a474523aaecaeadf642d35a593daa9e19087fe452cdab3ed9e299d6a75fce62acf47cdc6e8c89487516274e42a059ac0d116a3f3d9dbe7727c38fe8631aff1345b65f428d3b77c4c1aae6af110650261f06b1a7dcceb897f4c94985850cc18fe3142aeb2d73fa68c98a11822b972d1dfd4324ae9b86a0c83765249524a5cd582e38652523a46d83124e227371b8bf8dcfa26703c3d6d6901c708bcfc1d7d28052724725548e4aa0c8c49e2a114575570c9e9fd638474ae5018148ee1aa0d0c631e7a08e461587443a0eb1f16b1801c18166961d1fc5c5a34909e2dcc181e3a8c104c0cc60b182298184c4cae60340d8608260643147324c6876bfa55567ed4aecaca8ff6aaacfc98e3aa7c7f30476019182296f18f89897979afe35bf9860ca1778c81211a639468778c7965de0248ef7de6ddd4862182217215290616f3f2f0c798570c4c4fcc16555c018b7172fd4798d785298221228129c05e9e76c4c0625e1e76600a493c7cdd21933afb045d5a1efabcd5f6bf04bd04bd04d998570ccc5bf097a01be353841d635e37e615037315bbb4988cdb3b827ce7fa379a5ea81966a3260883dff90080b9b892b8f0b83471153b2962b9f85c9742a30b92eb2e2552704f3074471727eee98e2e3d2eafeba38bec9722062308ee04983560885edc782942659d2c821d4dae5904db12f3d061a03bcab82e777477417295c564aa9f88686848e8f648b3a0a0db22d9f9a5d07a61638a5e9992e854dbc8b691600a42b08f1458f785099df2ffd84d81084fe5a588efca0e6904cb299dd48eb7e03f89b0237ddaa2a3cdba206171d171713962720d614797d690a9846b84b0ae92bff27ce094bf104946a0e47a26b8fea3c989ebafe2ddecd0d76315590d4cb1c2220f7db62c078e3db056bc199c75679f4026a3c7ba1ecb55a7fe4c2e0f83b0fd63df05541035922c1e0df3ab9cd2c9695b4c3aa60984959e735bc6eea8c1104d378a640a86a86d523aed43ae5c5a2f6ef4cac588940eccb7757777531d2a04cbf8a7745227f060205db97d8c8fad3a72fb1f4d3d7504ce1f6c05636031af1cbbfde8b15e19e8b1b23b4db5d65aab9c5e0c3d3ee9127c298a79b9b45c8c8879bdb818415d31afb6a1267069c9151d822a1113051582eabcd0d63422c119821ffee2dd782c8fe5b1f88b29a594b25639a786824bcb9484c9e5d26a9b97228f654aa2571e102f452e1e10269deb6d6362c27484a9891726984660da19995cd9881e69da72790bdb8f544a29a5cc625ee0f0525b8a5e7cf012d452d436a1d04b905cc1c45e7cd02b183042a1eb5f5b8a60c0888185426d136305fb88c9554c149d722c8270fd398fb1410c504ccccb879897f4b12eae611391a9e8fad3d7f19d3e1c2cb97269b9b45a3aaeeb824347f6d87e1392930e70bebf8ecfa46372b16cbfc975027318f652f452a4e384f737e9a49278c864c2487999e2e1f672fbec47f92f451ea6c0da5e7e0ea14bd75e8a5260d597a29a026b6472995ca3d19702eba5c8c397221a7a5cf973c4e3a52805d6b8813045a91d0f3da5034334650aac972218a23be565ca1676de31a5d34fbaece40c9f6a7299744e3f3f1392981d4d2e13a7c0fa5e8adeb0fd5c2aa5e4fa734b9072fb8e2f443d4529b05c35c2104971157371fd5f8afc5fa6c04c70c9e97fb8fc52291db90a8b523ad743535874fd617a5c359a5c304d5cf5dd6527582cb9a4cb5444b1e28e26970bd8bc460d4ee0441268dc00e80722fd468f07b50355c3e95d3ec809cfe3fb932f537898745c4c2ed34e0aac972293cba55574fd770c5d7f94773a9d80027202831419820c2021202d76582c51822497965c9934cd5a93cba5e5e5b08cbfc975fabc1f3885821309ae9b5c5e112496abc6189debdff258d7df63755607c86434b94cae181db9d2f1fe313b7275f2e2f68fa19561b3345a379372fb47ca73631ef6ebf84e9fc975fd4d3aae1a532657cef537213125b9fe29180ebfc00fc088b16026498103c1895cc8bb9df4b1d910d7f47f06a3a7305cd4a5e580b52ac42082df096a493414b00f6d09312ec7bdbb5a2c93d15ddd07e1be037198c8c7e99e0383784f0271b83ffd69f6ccd7379bcc1ed7f1165c5412215b660855d972335c48b6da66ee5017dd91adf9bafe3e7fd8c77ca2533ea950c194c184b1ccec914e5f613812cda521e1a427e1aee9426e861912c685e749b8abbd1864ed6aad1e57b52aaed5e23a58c39047322a2db7f29a2c983baf28af282d52bc260be6ce4ce2c5110f79da46beda470685db404ab38fd2177d51d8f66a1b6751174da253fe922f9601923660199756b08f245a46d1128bebdf7f3ae1ee709674303ce6acb6f1267367b2a089b3644ba6a411ed469ce56078acdfa324a92c0f3dc7c399a46da8cb55a7e09874a5e5beb9238d90adb9d3361e739734a2579e84c7e6cefc9c886580c032fe9e44afb8fd08ecc33d086b7071398efeb842fbf0f919944ec9fa6a9b9ee22c9941e99503d13ea56dbc090b885ef914dda4a75c77b14a515f19cc9bb48d47691f53f4cac1e89437b9fed2090fdd8f78e81ea56d664f7d4907a357758aeef128b7da1c26d9f61cdf4e8b41eb699b9964b260eecc9efa547a30789d48b258f693a46db22dd8070b3a03ba9e39e994675d5c7f6d26b9198c65aa967d96c5bc887912070a087dc7367b4e85b0f3d923e513f667384f4a2965d769413f52223a4429385a4b87c83bba50e7dd6833b07f87ccebc1e0570809cbc81ec9235f2d24be723238e58f46923594781b4e5c7fd99252b6a46c49d97257a7fc35cd5aef7147ef71ddd53629b08f8eb9ed4830bb12ec4d5c7fc16ce2fa8e3442b638655d88655c88a593524a99dd20b9e21391a443d7a7acf2e9973d41e2490673157dfb577ef5f555981b317c5552e952d6098e33e8ce1e29a56c12a4e7a8348c3487590e3ba5684402002008c314003030140e8a04c3f180a4a791f60314000d87a650664c1a49b328865110848c31c620830831046040646066b6028d4e00e498c68c26b49ffea2aee8c067be305821ce2cd1ccb0a6f50975c10f0f91b379ba543aec99a3e0d596391cedf3421a2df3ac3e4eeb3d74b8eee294dd614764e6222475509ea42691eb8089d8a46d58ad5b2128d852be0d289dda67c89388f081c90701d2b21c7597cb222ba35545c52d7a20683f5fdf316ff6427773b819b96b3bed3f76ab8e618886dbdea55971c1cd099bfcae25b348c9f097ea8ddd92d4da5628ab00e03f264af67849f32038065c5cc2d12a4a5257acbee747ae429ab20733ddb876b99e335a4532f640f58ae3eca03695a3cd1a63fa18187d38af8c9fa6ec23b73eb8067dfc342456ca79359a160a6b9593905bfd94ab9d81704be9b32def25c5ea48af481d3f38cb32071bf18ced49561116c03a88ec56f92e08bb5b95fde1e217299463c58da0b50667a938635dd550a6ab7c0f11574cde359e1451d77187c78951c088977c10c12cc51be42405dd5b50bfef58c1e411919a9431af74296101e40154a5b83ad14170310842513488a088b8a78752a9611ec52517c4f36552960e1ee2b14ab640e05a836fb35248d941ede17e5bcb37397e27de0c2eead8d82255f520724303b009aadfdc3c8b497c47974593c528d613f95cad2bf2aa6036ad3d8ff3f50fb39b95388f896b9dd6e6b23fbb45d8892e30bcee2a42cceba2ea5b40c34973f7f72a6fc12ba6c6bbae921e49ab823a99b9403f4a45ed900f91b8e625eafe480725a5dfee86169ff471c53f6ca8972242c257ad166d6f29303948e4008b4c69680698c11ebaf3a76a0dfc66cdb4e2d0e04243bac68baac28f605ac01afbbcae4910bb1c00f93ee51de4aa1e4d699f60c33a3269b8b802ea06e6300bccfef53b23dd0a2a292dd832ff376be48c4ee0f86709c8257cf7048eb769f6b7494f8f5009ab7057e3c3c6a1efaf30ba61cd2a6bf4d76a2170b2c4b05743f7dd450288137eb808b4d650e6984e94361af65aec85dbed8371a3801ebcebf82d23419ebb6be9f8d8e38b48eed9bca61b5018177683666b5becc23f4e72b1528197201bea2ac7bdfa1f108fba6dba4a0352eaa5554d96a530b81049df85e31b555b47929c9714ec826586cb102dae809ba611d7bfe03a43bcae3d4c0e4875bc26bd8a61c112a8f797c2f906021bc0ed7b7b1e1625dbe6deac5972a0ca46029192caa6b2bf21475f8cdad3790f84ca1cda3a18820cf7612f5d95cd6762e2cce4afb7beb429b0693d0bcfe469bcfcb933324264cd3786986c483c4510e959d4b9dd743a39d5475ea33e07bc53f344ca4db0ddcc4a4fdc28c5398a4e5f149dfe7651d93897a650258416d80e9987557ce2bd82f2cb35a943d73f611d69c0145a84d53c0d81cb321127409a1574afad15311da7ee97c8b6c9965193cbe17e68de4b5f5e92ccb86bd23a2fd391dd483c59f635cedcab10bb7edc5519f808252b5b7a7357285fce072d850b94b280d74392e0b7d4b2b357f4af456b0c66fa5a333f311baae50a7d8df3cc52fe9957922830c025d5a8f626fe3cea7ebebb0faafd0334374272f40d6bc9cf4a34cfe067ad20f2834a5b721a386106db111a048f08ed18a0a0437e84acc83d44f30183afeec5131f5816a0e1520f440b242b34e0148f7d7eb84b1c56586b93b855daf0ba81f343063ef9a02914ee71a9b96bd0d95a5f52e43edf039a56091eb5586d2ef46a10140e20486cfd04e12030951263b563de7b1abc35c7b8c2f5df4a1d9e39e512c6545e093b4ad3a66104a06b6f592d9cd794235f8311b64370dabf697fd94ab36eaee56abbbe67e87a328dd22ab5782c4d3df80c91b8fffaf390cf238859c2970c2b6e95714c65b4e1b070c38e3a4855005a38b94b0ebe97be3fb44bac525be40d7743d5fd6c244a07ca1e058e61016ed58320fdc449b597764035d39bbec30e4a3404691fd0a383ae9cf596fbdb446c9b003a242a930a8d644854a212370133dc6adec469aa9af1af013cf6dfa5b2541f313a2dac8f5c01a1d9f3cbd6b4c08425c35377867a176d70972f8d9f3af1d7bf64ecc55c42ea8c70ec59f454133b290ce8ba0f8a2c2c90385cd63274f26053930e55708e7d8f79880a1ab0b2ed4e3f25fae9cc8afd743455356500a2f88a8dd030f53f0efa129ebf4980e931e840ee0856d856197dd57fa0b525836278006fab80cdfa6268af1ccd747daa28fc1139dee28d5e762ca7359054af723cce637d529b983779a6a702a05270d9200d0c06d11221320a79ce86768bdf6152444fc1eab3c6825e26560acf13eb9d110240370207a0de6a74a142ada09af3cf831d013e6a32e4ed68221576385104c33fe748b733a01474fd5ced9cc4ca0e8ee1441538e3247f84f9fde483948173188abc82db577195901a1973c0c70202b5749e947df42ad667ddcc6da1544510c9b14574928ca0311e1254fbe29000dad0e2827e78628f35cbbb42bb1aae641bb0d7d943a9c844fd5fcf3552e183dce093129ccf0b516607f8608362d8d7c7ba925dc3b664bac8e99e8bd38e0d7a610b679a4b0d05d1fcfcea40ea6ee0f0d57fb30e5417d431f078ae3cac63819cc3e11d156a932aa9cd15bd6c99f768862ef7140c5fbdc4db49c38ad9448d94e3584ec3711fe795a1b09905dced946bade7b1f5bf9d143b1b2fc2f9aba4fd08c34b82700f0f4b93d350c4f0dcee205d1ba2cf3a19602abc51412d4513361371aa7b9f8a052aa71e29ea206e2d13b8e121b09e85dc10a6f2801dbe5f7c72f9bd8352597730d3c73d3f34945afea2d7bc60c3271b0cba775c5232fa36a20d73c5c10806d74280ad7e977e1e6fee746f890895c7e4789fe3144be2cb3ba9e8c24cb349b3537e04262135a786a2a9882a315d950449223fa4f4c5008e5e37099b0472253f2cc4659050ae625dca4c351f1d3d471b7a17917945c2cec4e81810175e7bfb29ebaf69529283b7d46fefe16b21de42e95114f8472ad2608715739c911fa9f88525afddbd0a1ac518656cfcd5ce825bf70c2ee595945b2accc3da5fd2ad8bccad3ab4ffa081a54ace1f789f4aefe9d05dfcc918477033943d33199f8e873951bbc28a1ffb0a48e1fbc0c225e3434007d769442ab58349420b1951225b8393166d71ba375f78a8d2de4ad1c6c7ff75934ba731c2c71db9c557cecbac8873d0bf617236cb3c382e25849b2f52a1ffaad763870d66d4c1b91a3ad6bf27793a8a1d5b8437a548775883441218645b2a98f58422af84e38286dc29883f436e78356350fbc79e8b0c9033c2b2b4ecce52677461ead10a1797ffb5c826950b4bda73aa2748c0be6679196e1a94416666e19459c54a62e5a91a10c1988544a6fa23756ad5c433302b9da6bdc40a4908a2c1ae4be3d93a947fba34cd2ef5359cbc7a103db58a025f029ef32b9dbe925a9d5e32db7db0db4972aa4ee1326b0a597a82ff1c9c129fa6fa6b90acf4e87395f22f879395e0e2bfac94fb085740fc55b3086f73adf040187c61915e8f22b3ae015d9db95f6542d5e2bb2e5e2a016dfec4ede629c445ad0f09526430151b925dbba3c6fb2f0ac1d682c278a605a603c3a2c30aad4ecd90ba2b9bd35e356d603458bcba885a0335d7699456eef7d6bdb0c09056a5cdd49a7d25c5247606dbd530da30102beda4f387b98dd28b975230b52d70bdcb623452c7f502714500f97c6de841c0209043a863ca3a2a320a3a1eaf440f14b9fef9a4b664e1c833f3d86c9c21d10df675e55e26ff3e192428fe4ca277fdefc735135920d8a493b7b7b416ec48210201adfb4127a7214f587cce5f79076db8622c12f555a78ea203682751d9913d0abcda917e10a5c5ce5f477743845fd0085217b0db15ac604d32694ac8e84033926a2efbdbf38e7e8e514adaaad46ed1c3b87eee61185cdd618160582ef5eb9b4809d472917d40542f1c5ef4d7aa324ec146cfafad3f3b3181c892893981c631b88cf2e27468e635f6dfd8e2a875355027dd8e872780905f42ba55c9919024a81c12a536b7291d89eab143a3a0d348b568059ae3a7cc106a1374b02a1f45f0cf91445809f428d8164c043d945aee00c3e4ec670a85209d888b3ecf14aba859da9bf9029cd8037d29475859bf882d90798d486b60cfbad35fe3c81ecdee63a35eda7f1c008e637e05e1e184aa89e916936ffe4547f59fbf7ca0db3de059ccd26cb52c44873bdd4c03c6ff4be42908a41ac089d26e5af6e7bad7e8b510c7910cd079eec6fce88972b157e761fd985eea12e2c2df830ccd4dd8d4911cb1ac1e403d8971d11fb28686539ad205b1b0a660649482887896db81e2fdef503134799ca090f024c8fc0a65fc92d515f2470ba9187e7f7c6c982fafabae3fee6962c21002023a6bf6a464487c006213fb8a4374332625e71fae354542d10006f30e5024d85abde450f02aa88bd0f502375b5c2f94d637eb4778487e912789886a6082e19f8c6a465c99885391ac9297bc4bddcac9af75b99e99843057da5f75fbc2311c2257269b77c0fb829e6295dad344c71a04bad5dfd966c1d636dd10643c1b511d77d023cf680ab342ed3930dcc35b62d416372257f8079f3aecf3a86fc937462b12f0e72fe629e9b22993446a188a16c280cd87bebc4c90f4f0c573fb30922559cb21d4798738bfa4a384c6dc2c9db884d1e22d164f791a738a006f876275438ca5f15694029bb6b0383437eba6b7402ed0ed46621dda9a0471c4e7f8230fcf61aceb4351670cfeca9e5a8a022197aa013a30ec352502a36048b40ec4720d00a7774e080883579a3e839d0336fcda92387265b527eb6f931b4eb478b976b313b5ef7fce3220fff944575aaf06c415a70e5e8f125f0e1de5bc63db6cd40262841cf8476fdd1aa5706f40226923b45607b2307fa214a21fff27eb4df6622bdd60e1866315a8818274ed2856bc5b1305c464b4ff125b01fee184a9bbdb7e5974a0dcc37ffc471008a20d2892d01b0813a93d0420e1f90924368f3c3969729055cf4db4a79b3fb84353446687681d06c612bfbc08ff45762a4b4b2a2e0597f6d65ed972aa50b74d5e1e0e677adcb96804f27116deb6ddc2666e6b052807a3b035981981d8956c7c9e79cce85cceb5e67789d273a5c8bbc3f1a76770770628b5f05182c3a7b34c5e4fc513ad25d5c2c1c39d1ac63bd442c4258d10e1f69621ac0bc9f52f16eb5847355a3cc251d89de0118ec3d4f5b457e634ee9504978c0465f1880e22283b35974870a51fdb39ac33c289ff2e50c76c25a37a426a5f4239d8b108206ba3839e11fd0d32c0839ad5888bc1864664427a10793c01b348d2b88c456939a00dc05b01c2632fa3cb88dbf5c09924f538b8ebb3f654ef461a55ef0c8951743820fc224ad3d8f1db19da00d0a85990264d9e7b4cf4cf17c19e392da301f9e6b51b47bd97375bc0ab4403de3b66dc18d5bb2cc2f017367d62a8bee61aea393c24938ee1c53b5b36286b5d530aeece91cd81f7431a604332844fea611711810cd05fd04c996fdb03a2e36e58de03b98cc006eaa89427f177087235e8be390d0e81dcce47cae7f241cd832919742342080483eaa765dfb967e4835b1cbda32e221c98eff0d02d3afd821de7f257dd74bc934ad32bc3a8a7f7e3963162b7e0ef18a910801272c142f8f75cedb59e500b59926a2c126b0f7d7003b473ce1c0e6f36307a53e2cfc4a203fb35dda83c346919002239abc7140e32a345fa5f52f5c852c18b9b9dea195606b42e988b25224bbd70fb65700f1a6fddcd097e3af692a8bf4cf92ef6dc32b53da148be3b16abe10a97613dd747608e2323615dcd98a6ba65648cd6f863f1968b589a3164c217173b9c70d8253597436fcc9bb1507b1363efc8baf68b0a88c58a18e3a6cde33012bc876e6bf8bbc5ae9b8b702bf9b0434913203cc223314428422a35a6a37caf004202a8a5513c5f269fe09bbd4102a766cc0fae1d7a3ae3ee9cf2064d55279c64ecf75175aa43cf0a4524c7c26c458f218e36711fed02c42d12d92fc69ce0479f4be903a942f166064f75284ad3a0d0283e9f4c8434cc95e08412405bd09d69190245fdd29ef0c665c6ba2d16e3dda50c7c0e653d2fc2182bc44a6ce07387cd52c22ea3662d05574caa234d56b82f4c3a164916f0800a1b59c5ead3688d1d47e4e1df434d613e70f00ccbfd95ff945f44583ee5008e1b227beabdf0398c504c412f21a985575d2884e339c616161451e17bf411f0c47bea27ba5bfb06cac25d72d4a14709d8650d626e0ee93d53b31a0a52cdaa0b944541252a23ebefb1f5ed1cfdfc8a632b4cc2b5546d218ee7a77824d6236fdf78a7aa35ee6acbe7a42a405872d19cdea0ea2218389dd4a82c2078141be8708d4dc6a2caa5178b151cb7a840712542635808ff4af9ee2d591ab85e2936b933aa4cd7bd8d50722ca431243682f184ec958a15cf8ad5860d50b1eb62e852f451ae2d9860a5a2f719c9e88bb3f5a329970bdc2fbb3b3bdc906307c33da983120c4d8db644b7ce08b362e23451f09774e52c07ed2e630b688d00570eda13b5a3ae0d4636f7324f05eee3b441a30982a3a8749e4e6bed18661e443cf6005e5842ab71c9fd99f29348cbdeafce139f9b52ba3bfd6ec2658537b4818c3869b2397ca4f6f2f554ee638c491fb774bbdb889af3bfd1b3e988cceb9c3fd5340d8e5a57c136d01d54b0540d4dfd432514ce03b044ae72734b0d4950eeb2de0f07b03f5386f5d9a2f9e71c8f5339d619e95604a9ea3037f409137214fef1c16a06b09dc864cc535a4a565cc851b54f9110325bdd0761231d95c6ce514492f4c36945072eb9cf1f1410afa4037da4e2e2dce5e2c59a28a9974252e8ab64787453710de06221c3cf6c3014e5aaa22fdda4ad799f8a525ec5b8b42c1af21a76e9894c0c30e75179a0d26c648ee4b87ece4d74373bb77aafd145e2bdfeb960cd58e121ffd55c95b8024b84c0361963a3b9b551c6278d0f3c9b47982f16f24d02cdce2c77461c79f81e9c41ca4765d5eb8a61c8224016ce06919f17f232df6350393bd22015d061cf4ef91a42ec5b77666dd3d744285739e1f18d6dadb001104053e1284f79e421dd9a247aa17f2acda96c4cb153e9dfe697996221a044f97a0c2e7ecfd245ca695cf39b762ee4e6787fb515a61e4dfa63fe73a9324feeea52a47fdf65591f65575e543ac280840ae6c9c3c85d212140e84dda8d4ca4c68100550e0386a47ce38f79b14eef64568b144a4833c45895a16c3d041be38b837dffc17c582619eeb8a112a99e0c3719643508c27aaf2dce26e69f0b6a91d0540b015e5f99df82fc329dcbed75c1125fba324326d770c63553a1a48ae6617d5aa2a3431898659b3e3f6d020853c4796732f210bc5b72f3907fdf2c7cd30859b545e96791faaef0e0f689e62f75e07d5846843055a0d48cd912f60cb84343dbe33b74a1c08a94a77bc03bcc944b0f032378a71f19f4accf9160d250eb8be924e0e246342beaa079889a2964dd708fda5435c06410b8ee48651bdc72d568bc8d18ae3add11a8c85aac379d71b2f0b0a0927f27f0f3da0e993c5cf9a353f3d065de7888ac2576e6416277e020ca3fafdfde63f5142190c86d0cc866bc4d832f8e9e191500cb320da6cc730ae9386f62b1295eff0f6ead6a035f9285cad101d6404c23333938ba6eb9a6806be8534ee7e15dedf2a1a164d6d8350dda135dd48dd22117dc670ff7546fc0d59aece4d4c60417f62c931c8cbf34a299cc720e7604de23187570b9087ca15a58dee8c239981af45942c4f422387d6684703604accb74143947908716a6ba01201d631ace4fde10b2ceec90cab5580082bb3eb3ecf8a8abf64f27d1b2cd36d1f52c9e1d79b9a5df04818ad60bdce9e1c0fe7f08b37733b5560560e0f310848bee94c26f25da8862d2b95291f6243d4ca04d48dfae642f504f13164ddc20ef5aa1ef093c453850eff21325e35b73f1901396ae4dd341b159f35f7240dbacb713d8fb1c698cb68fc4fa671960281e6dca67cb2340557728979d4ea95193c1bb0d9b9b888d7670262c19f55a7c3e12911c7a77b442369db81f555b23816f8f6da8715984fa8f9f2b55d018bab12b63c70b2238400496d0ac536ad6978c2bc86043019d99d2d1edc5da937983654d45996c40d5c36c5bc5b55f007b06d561f32cae4101ffb942620bb910a30cfc018a0e78caf00c8d35f0cbb5d5a3ce40b15615251cf4627c703f0e6ad4892d301d72d8f7d7100a841287fd2c592239f7a22b64cf50053054e2cc4f5970d99a9c9c45764ba3dec8a6d01d1da002abd94442c9b6853b10439af85dec667b05181a501f4a1ecec72f041d5645ec71aabc88191d4798c84df73895e55fd9ac420ae2009143ae25ac07cc43bfe6ea5aa48b7a0fc36c1ccac546daf897d84e3b18a6a4428a1892bad0113216049aa2982ba1277495b6350bed10a729286a6029d376cc042842653d94e2c58106da0a008ae1dad786b08222a65e36f44d0f5063b78c2c1c2d25d2528792a1d061063da3f2a81e7d21e5c2cb244f892098bc13987254697ac27434db4ed4cdc79812c4a0163bc91c6d5c324e0286c027e5489df1ae52fc6ee3764522b757a04eddc8315fa83c637f9c87be6f65ee9fe83d1d418c2edd9410b947867e0338b71a705ac010856c6927ce55c14a2631e88342a853d1faf21ae5f8553ea0dfac41cc828ba085cc749d441f49416f6eb643c3d213010f61ea52d488fc35e15f9785b0259992332af9a87c58a738ae6d4dbf428473aadb95578ccf93d428340803d8919f9b48a820b376e3b060a77b9ff6d56a3ab4c1e1478ac5cd68461d42a29c43c38d8d17f705274f1def7f2544191038aa08c5843c087c7a6caa5feead829fd1d3f5e1d3dc213d31cd4f848d7a16de68f8e263f822a77b9319642c1cf90417f388f7db0914956249e23bda749f2a113ebc1580ed51923fd2457ae6a877c996c8d4b0bea02f1642b2654689b12ee0d5337ccbb14d3f1fcebac1a95e979cf8fc2ad89dd514d2e6cfe85fb637f5fca51b2d986a157a6c723d7a60138d2d65c566ff3a4c081e41c3921077b3d313c481279c57e0e3ff5b4b930baf0c4b1dd74a5487c9249604cb56a22aeb5938f282980c3aa1084e86c4ac112201123de5a3fb1264c85b964c0736bf376f66678cbccc46eaf5dde90735147d77fbe822105042d78c1464cf5d64e25d23b8a919df441ff58b8e3ffc961b6cd0b506b7a9bfc5fb08a9014b517239524925a76df3c0ef032c0fc75a2e2f4fca466eba7a3f4c37a64c879d4cc9a2c6d146c33aeaf3cf682be3f754eba910792d63845dea1643da6d29174f3b4cef93680317ee522ba5c5bf9b3e58fe8b1520662748f9b22e944c1f474e86959a9c0da5354689243306388b9d284d5dac99884615683bc07b03e4cecccfbd284d522e76a903703453d0291da99ff18834c316720c16b06a809653f9941782603e14221793ac175eaf4fcf7a18a869d4cc5eb94a8a4ba4af254f3b2c1a0d04782b5852f5f96db5e192fc35b17f4b4716106bae5f80ff1cfdd5d47eb8e8e27a8d422249a7620e497b7302c2f661133bb6c1b8d96a9d36540288e57a339bc279476d5de00c49338a4dc3d246e37b70dc94ffda4e178b8b8395f7cb2002b691c0b556208662753a60e6b4f9075a133814d1da6b78945f2a6c1c38136a34a43caf681154df396ed62a7a3561db853616ca0ab6f3d3e8c6b3d6775e73f38b062761b9c1307119e5203195dbe0b0e143e7d69875311422b7dc8074ce0d485f2d60e93679c72911e686a4689946b9bb37ae552d144a14d31533c35601b034cffe593a09fce03fb57b77ea21fa7a3dbdbf4822db65176050524c9a3596e02fc22222b516e929fc49a3c7f4194a1dff06d480bb9f84897b661efa793ca28dc1d4a50a7da34880465a8721d18e3648b1643862f3b6d55e17a8b0a53a0a178df79e6aab855335b374f5647000e7fa983b39afa30ea577a1bdb20abe838fe7f647a91bae1ac49e18cfc5c27ce11041107186f03ec5c1c318e2aacd4c40531847c481a5758e4a77cf822eccdc746f784f8c6bf57a422a2c1ae21ceec4ba62de0e27bf93e12fb1fb36b2aee190e948d396a05e3f0389859e1ca011252760b5f27f62e1e89d8546837fa643bb86d64233ac67a288def8d79a8c7a2d44dd05ed3c2afc4ed97cb5c12c3ebd547944dc1e9989f8891aad70aac9894f7a3d05508e0bf5b0ce7ae92c581780ddd456469d797050aae378ec0f991be68c0fd604825f258fa6ae8a24e80874a179ba2cdef0c96e1693bc639e036f656d106a35b69796c55a512679a358060606d0a06f734ba2d093a415455f21ca914acdd09d54c957fe5d8d301bde0a9668b3e6e377496e4f2ea3fc108b93b773d36fc7befbfe87ac2710bde8333489666f4ac3f0754a67f8e3607b2fb43995231a833b9f9f8db18a18329153783584eb98fb0b8efdcd419aa3137cc363b2438350b44b96d3c501cbe3c1cc0714cf6bfc1d40e1e4d65c7f7ea12d16aa3d7b06284c0d257a59448001a3c474fbd96ee43654dd1048ded151003b3d3cf37c8a05e429406869744c0f1c4fe02e0f9757cff87d3f6e6c14f636930a59f19573c7f2515b9d84c77a29cfee420eefee4983f9cea493d05137bdb262ff7e55df9a49ac20cea23b1948feeea03d8fc8a655380cd67d29fb220565b522ba05770be398e8a3c48e579fed2546240287c2b5c26d1267915fb3ba08d2fd77133f085746a9b573cca86e936a4f2292d5bd382a611ca6041c337a3f998a95e022cebb16ec5ae78c839e735ec9c4261d106b0bdd08d93b90372faca3084467e91c31dd308de9e2fcdc2438817a5095555252a7bf7b5d09d099a04ae64585ed546c6760547bb2521904c30a676ed20e62bc8a181386984f01a28058bf229730ac00f3873a897b58b30eef259c399076fa0d55b82e42638cf324cccb4dc65cea97589cd2387c88c6f7418758a895b79c8424347b07d86c5b50440bff5bb3e0c5885ff7178cc8fe274741fac211bce816bd10b7e89803404843b2bc27b5370cef64547f8c1e4a5c78935228ef262c8ec166dc94c1b325b7a3685c6058afe86b059be1c806a8c3c346a850552b245cdce74e5c0131013f82d57694c6b5704e78fedb8afe0bd208a4527f1c15e72b95fad003261d52a11f993ed70073c03ac0cf9c98c6d77b68cc9fd5fcec0ae3aeeb6c630360b4d2f2a50c623d028221f0719fd7fd75b2bf224aef4c268b10c133086aa44f66a7f9bcb81d86ab5172cb303fb440ee7ae9877e034f90f90fde6e5f2c4c0a9bf74da442f868fb87ba005d9822b98a1219d35d198c97c3ed87688769e401b432902363f713c412782b25a101811b4aefeab2942c3bc9dfdc8f834c9983b20161244e856d8b302a846e74950f2034e68e17a03aed2b76da10d113b4147985184122e163c82640a7fb5c2b3226291cc606d484bfeb7adbf4cbe69d3c55f05bab8a3335511cc4e7725e7856d3e39033e1b1ace25f55aa23fac6a444edaabeda4449a3adf0420237a17793c5476c89775ada6503a761c32569233d94549d5bdc78d716eaf211b711eec941e46cac7c8d5c2fa9c509880e9563d5b35af2f61fa88808b7f268ad2f4043b03d6193dcf60c376ad6f4f33f0576cce764df0d99d455e3538ac5ebd35a2f97b3311df22bdf83f29ec563295528d928a693f23bb79c98dea97b53cd2229150ed91ed8b0a4c419f53f0bc9876756d294080107c54aaeba7296ae67867c2db4e66c1df7e5c6d99bd530c7a5d0a15915ef264aa9b84f0ad3dc556f740ce0f788af02b57a5b2233cc2b0e06cbb52b2e515fd271df4af29abc44f74203215d72f38936cad09a3bc79a06fcdbaab40dfcf41d1b8da6d79d3d34b955e576a9a98ac13d54c54abd2f113f18bbf5fe35692ef0119a3a605af1bef0b520d746a7d5e7a987ac808416388a6f81d90a1b5ba30a5ada24e2ee98c468ffdb928810e43074f6f7a94bac7647ce2792f8d4b1e62d4bd7c468246f5f2ca040203c08fd39569ce07ef155b7d3a4e02b702ea0ee908cfa08e7f0ce8e98286add6d26588a57a95940e6e620aecdab2ef8793a6de2b5cd84a5a5cb11a9273a2ea5727660e7b69f565e95062ac01ea547387710d919d6ca40c8cc67ba2679bc4ce19e24b5e16a90315e8b39dd6ace0f49a943d6584b02045eccb4d443b3446a654948fb015711cfbc070e186107893b4b094202ba4cf5c33799e748691b4c1de2531adc8cc2e7ddcab943596b5977bb5b1dc106331b9982dd152651f9d16a17ed76f3d31666fe23707610ae5b742a01efcba0093f1d35a3ccc7a79644967969271b87ca857c72fa4495ce7209c41d5629fdd257803757da9a633a3aacb14837050077fc57e228dc17cc311367df046962d7598afec5b77f9064d6f06693e0d31f89930f1e727e004992c4d8baa1617599a0ea56654539d15e1d474d5bdeebc543cc9339d78a1c2c5c9f90397d55372a018326c720ab549006a105aea6631cb40577170bb69a4c388679bcc2f0f2a10c3be82b0de7f0de8e9862a5aebf6e11289ef93a648c574770dd394038d4d17ac29df4d80738334b5aa722ba2db4189b13621c9c95a65edcac079a5b673bf34a24f6e35e0effc32460e01faf39c2a70a1f22cbe05be6391a117b60a66382f0c0b18108479fc9a520e2c0d5b5687c7d3bf93db9aacf20871171ab565fc491c67de0f1b095f7be835b573c0395237c83332f07660d3cfc873bd938d6438a0dc9361db9791520b86f0c132037e89f5962a6d24c61db0f3b8c5fa49fa9dc59ce8c4cfd5dfaf3455372803da00fbc014787c76d404b6bcdacac1d85bc651a5b1cc4208fdb4e1facd59332cac8194bce94adb6d81529b18b99ca5f90d314146732fe74a6e1520f20ec7eca88820801c448fc128fbef8f60a62d3973afdcd44f5e1089f074454684f1c122a1e9af542485103e782664d7c49974a3b5129e4a59179630e4986d8005f833c0154870743da1e92c4ef7aff93fd68645cb1cd61bc9ebeebbaa5c114814416a4a01fffaedc6ad46cc8e436638096e80ec77582ddef506489befa3ecc266ebc64a88437cb169464329a503bb3283259f561e17b7043fdd5dfed23fcdddf8abcd37ae98e0865a8db26474ced73816a84c2219d91a23da6c972381ed5b11286ae73d918126d3a310cbf84d137b020e28685ddea32016e72697b3831811cb89aa4351cbb46546de09c016929e0d48e6200148615b66aa66f95d2ef66bca9d76752064871cfa0c8805f4e0d2828e93c20abb693efa355687e9d12522c0ec5337f3e663a4ae5cda4ee4be74de5b183b3e268cce358813502806f02f78089d811eb0e030e1284150fb91b1183bb9c8ee062981def4143d89644ff8627740fb0aafbad0c91ddf685799a8d13c24a9866183883bbf1a3f5bdd66e87a293f0eb81a72f8b0e7bcd0667f44ed0c5f6d2bb4c49ad623bfc7a0646daabf2eefc96efa0d15f803d04543e1001df08b214108cb9dcd698436ae8f059483bf0f9510f2cbd0ec72c1366fc1d6e2c9e5584b3df5fcb4783f676a8dabbde44779bc38750cb44fb7f946671f8147ac208931d097bb14fcad602a78849a7d1d06e9fd5152baa719e1c7cea9630c3cad77526116df0a9baf3c005379a9897bef4dec79c55549d7c7913369c5e40df5751fbeeaef7b2a917db703eaa94fa73fc11b43948feae2d2604b40dfa2d867364efc15c7e5333036f46a70640204c10aa318695eae4e32f4844768f040d0c9849bcbe58bc132de1854c2f1472d4868d8154e3ea0857089df131a729e947d514263923a31f3c6f2b28ae6f8a3bdc4caf5a31d1f4a444b59eb89b95fbecac9f521555d5e8a706a50ac1fde0e600aa9167cae1acc8dd21bf81798838c73a650b21c759235114c0bcbbadc9dcd818866cc84532cbb51bdcce354c4cb2d7826fa1a5c08a46f2b82bdacba57703c40c062479f537e5435c0e64440a38610227cdec4268453efcc0931f44ba209dc460861a5a54a7a206833c33d33768e320367f5ec7c4d401098cab81f16b2d72e80fc7768357e0737f3589a491fcd058812b60b9850ff50fed49084e299b7309194a493f2142c4b5200ea6269c9f8af392425885714186e84f853bc20a6315cd597b3877da7a181e0981f166d841a02d3df8a939457cb769c0aec9029a6b0d38a81b30940a683287077d255bfe5e3f13276ebca16a69cc46fcb9838eb653769d1c15ef4f29e21f582d734b18debfbf1cb148108ce80efe573d1c279174ffc529799bef0735201d7365203e715758a93e7e7b72a2719ef94ddf5d799e6669e486c4ff70da7b33b3688fa353f8c9b309b6b82378c4abdac897ff484899d0cd00bc24a45e36de988160c4fbbb704d055f12dd9446719ba8907685dd373c6e24afcfdff38e7250c33b7b77438a717ca0fbb1e72a874c6e050d8c8faccb778dd6eeb16ab04ec92b036c4c4de1ee828d0baf0956e8e06d0ce9e3275ad6e400f355ff4227e2b750a8c6ea9d6d0509a0cac3daae0daefc2101fca8ca48d256023c9ec4ab82ef0a8f84f0f6422581d0a3d0f047271e1a30bd4a52a35642d6297c63494ee2cd9e63e773208f0943bd1ad036b96990fc6ee13f5228d104399eb331e7f47bb6db5d2146abad928f1d72ca64cbf05c8794a4c4697f451220349b312a63ac3ae13ad067395d749ec67b2b6c7115012a065d52dfbb8968fe1d160511c71421808038c60a5b73b4c257d4a70c44cecb9a055df6be22e27263fcda4a2b3b5992c8613868ac6bd35889a38913e8046f6f2620453020bbdce37b7f87faa8a33a28471e12e8ef2820a8a57a935c0505014b6c8b21b85501637274c786d9579343feaf0f3b609ea6a6f8683c0c37dca55e17c54795db43f6bb9ac3b8b54884ad5b1a40dc5fbfeb54aaf91a05a20453102e1045787cc95d263ca8087739e2fa2a36e7c9a0b9106d600b2f49cbdca5f0646c545f8c66cfd611abe12a9a168f21588667dbc4ee4e29012fa1dc04278e67ddb799fbe1fb857ed75b411203ee2d6172db179749d32bab421935d34b2d8cd304867a307ed91456dd045841c3656c60e407e971e70dbea8d0a4c73be8cca9ba32e53248d6c0623c1015f59544f9aaed7898a47ad3ca6ec925d33e9a9e013314c048f84b7f73332720a4c54c79426885890fd25d58cd577a83c5f808e9534b1dcfc951e0af859ebba96df3ff419734e5a741d50b140719684caa35b7ca75ea878e2ba4df693e3e2c0583a221aadb19b690a0e79de339543fbf0a1b12374d462e11e4e43dc1516e54abe65a5dd7c75551c363e6e4f18d61d9e08e51dbf6695c6789411b3403b87a6e0d0c1b9626db028e6d2486fe003054fecb43e708a839eded3fa7eac7a27b93df5aec23dd1331c8e9c4a544fafa4d6fe1a7d201c491bbd9c23cdb6ac91c6c8a1d8af8ca6545960ea05892556734f1d9704456a51fc385ea49af0ac0c413ccaa6a21ec0be5d9e1f276e01305bf6b82a50f0477d2dd6697eb8ecf9c39606188fc04c066031e1f67c3bcc9b101eb9c574352cc1aa067d7864f7f1558c6eab4f0546415c06581acb1ca92274bb77a9eb59f9cf188494bc0005cf593a7e3720168abc8bc7897faf886291df3c7d83239daf6a9b87da85c7dd49a54ad0937cd703271e444946c0797ab822b8bdc638918e22c5b0f509e34dd5680b7bd5dde0e12cc97b3cce2a59f6e6af52f5703a7b2f117373900dccbf48a62d52081ad49b4ddbb4a9d9b406a18bd7863f4a1528cc302da6e71caf8597652e1064fee42abb8d3c669d53c843f588a8528453988e09e1b1d188ea5e85718e3b4c2f502ba3014588a872c21c9092a9319597f8b2dc4c0b14c3dc9cfabd072929bf717a46bc89bf7802abe21ff9e7bc859872e41734043cf6d0f28ae25bd8e94c68ea660bdd8e1d33dd504e801fd8b05075fb14fec702c53cfcf11b8660534ac5542994bfe85599603abdbabc2d88830bc8e4eaed56a72df1013ce253d2429a520cc02cef28d0ecd6a6e62faa91203c87380051be95d5e89c275ef0ba266a7a5d1ae54d3be361f8ed5458d316043e7fb1157ed144023534a72df4ec2f4910049ebe165e3dd7d4c3319e17d2cba8e9090a4ed7527546fd775a1bb9b054577426b8b370497cae4fa8750129d2809a06a94d30c903744f15aef3cac23852a31bb53cd109d73b30306744853943d13a66981914ccc64045fa2e22fea4df87293578169413ddd49423b882f951f461f7f00f7155fc9007e4ffd11b3ff432f317e9b66f7298d9cfc6c8f0c58319427facbb877003c1419713f2e39feba4171920fbc3cccf4aa83c2754b0d10bd770bfb6196fbbd867880c1e79fd3086c4748fe9737e2f278a106837265a957cecebd53e51298963588951d51722d25e2a4688e94be4b51f8d9e1f4f356dfcdf8418cb1716b8a48a41110932bb41543e63af4b117b7acc5d758760f0b4577f9b489418961926fa5a8718fa2326ec68ad594511281d1a55f2b398853add659836c84b30b6d40b9cc8fc3c7156fa7c4fe4ec11e0583573f77f17508b578b82952b11245b33691929a3749afd84692cbf771ceb103694dc2205537d1eb76ea62c671e1d93124fb1bf954dee74838a7a204f56a0d642b5fb70ea3cdded414e94be8a5e01fc048892236ccb3aa6071ba7989c1129541ba2f649145ebae04e77c1783185d532b651e90489b527889999f71d2d3e8117a139abfb6d483294a62bbf50e418cfb0382fcd82d40d1b6a9d9ce5b0afc0ac1bb2a8468f51e7b4cc042dbed23cb7bfc0755658e4d3fe567fd23289d69e771147884c9214046d4882f9a39929150ca2284166e7c3aca0574dd72cbcbba66200b14e25e09aa73c8e822780e383b2bd01a61ffe1a7389b70dc664d36e3d5117c0d1ffd64a3bb4e623f4402a7ae314940b153c8a4f799541ff711cbc8f906d7573c9fb6475905b8688364f885c1065d951194cc18942f6714ca05012061b51c46518f741a4694153b77909017a092869f536ac4cf2f49e37d75a65f3c30125f870359668547d38058e72e290b140c5168fab8c4fe4d44b80429a012c249558081c667bff22d6f8577267e05dc45d37fb918dcefb054ed3937d3b4243f844692bc81b94c6f8b6b1dea32900f4e3768aa2a6340b8264373ed4f50ffa0e5b6e52fdde4ac5a8e68c32a55db0675c4eb4ba09b99824a746d564d371e720aa54fac77dfef5f478258505c794c4f95e55615d10a08c90918f1130c414b8bcd82cfbb6db3d2d80e35a8804d802fe31ef8b2fb834e2b37f08b57c5f8d6038efefd984f68dab1b93aa93641991447e5ae29db0b223bd4433c485caddbd7c2c1aa5ad80c79c6574decc9d54d920d670ea78ace7cfa6031af265a870dd11117d14e50ba1ada441204eda44cebe89e8ac41fae61fe97e30dbd46b6b402d2cefac3ca7c466d5d6f8d13e030e068a82c9bd74cc20601ad646b1503e721f85dd841fca634a74846a299770092cbaa70517ec9045b962bca927b321628b122f1192e5c71749a8c6f770c0dfc67f0c3575ef5aaa36a49c49d2b48d6cd4e0208b31739c82d417055da43e55efb3fdab2fac4443bcf8923de492b47823a339925a09b6fd6f57442eb5adc491b6da076d9ba438457736da83a71d3b108d5a7c76124c1cfcb66b7233ae631bff10b5df3a753db417c176308f6d88f6f2e686dbe109d1b62ad3541eae49ea041cc5d93fa6cda4c12e8235380ce9d6f7de83f53a8b5771440a2d7364494ade30a11c687bfaee1ad62fdd2b5851cf43a62f00d3fb0d09f9130ed07482fc7eaad7433ac733686f4249ea00454029a0b44943bac2ddec9b2f63f51f958a5810d4d08a4144ccaf30ff8642914b5044621028bb3b49cc0b2048ec4957546831de917c10e928b520084ebe826948fef814beb62ee65566c82e06ca180026a41b0c2f343698b703a6aea59a610f4ef29f08147a3d7bed14abaa95d0b2c4c2b70d089e64b6ea1eb1c43560776bc4693048082c73f107b2a9e7d0f5cc3502238e9ec84f2d714dbda1edf51159afdfc140590ff22b0350c95185aff288a3dcec22b3f3aa35ed27edb8b0cb7ded17d2d7d4e95f00fbf55b8a7b89ae319309e6555481cfd0164ea6123ca69e2d8d5ca42f8054db8cb8d7953658d9028df68d31e5e3c67201fd4feccc05e5047d504493bbd0ed882a355fc43ddd3899584d326699bce331d4e74d4ceb8fe2d58dd52a5b07d4100227beb753a37b0155580e9ea41972129407b527271e1102aea1df2f3b607a32c14b69c6bb03b64426057bd1bc4bcd319da183f4eb8447527dc3beb757983a56e67c39809c82dc34022b1f7f458139241548cf73ba44f0b88111d659e2e0e37de826acd80953458d57da892c62dddae0c8d2f72b375562b58837ced3b89f88e8d08fabed262076275f1590dbaf843cfc0889aafd2a1e0a3c2c77ef4b2f051d490fbdc837bbe714e5d4bf8f2b947083fc48808234fecd05bb0146e9b9ae153bfd32fcee9caa640a1613224a1e157a933ae95f411422bf68e4fa613e44c6966710df4e90b6d5477ee78a94c93c501fcba8466eecfc93e707b80c5b55d909440638832230b53b5d446fe70db7afc4991121766c713d00b64792f68326e5651c807e104f843de0e2bfe8dce696da511661bb4b8c2db67d2c00af1930a4dba6601d943870d3f21d950a6de18ab174d711907c8688431d46428c725425a937296342fe24d734cf0afe4f0deb3e3a7f3937c707d3614fa156d92887f2762a3886e094a888446ef818434f980694c226e34b3a03eaf0b9b49972551fd4a61ee524e286364e550efa2d88350e51b04f803f022eccfd151ab780eff6b85c11fb76b74d04bed91f270f5c580d3fb241d235c1f474172bf0901b7bd282a9f3e154796bed1a61d898741faa464a033e3a09521854afffc6280197aca5e1d61d5b614c346265928f46edfbd649b2f05e223524523fc7a3afe0afb2208cfb850a14404bdb49d3447cee75042ceffe752c011b4682b2944dec15f7c1da2a1c51320b2b54ad58d648f00a43055b26325e509807f95b27a842652eefeb9d51496db1b888e741ac92f117704f8a292d651c03cfda36c89e49f949462604ae00c6c0795320710b9b42acc15bc5a474d09104e310da164f9ca626682685231f8d110bb4cf499eaf779584f519693105f2474fb2a66ca71c975972044e130370910fbc6625b8bc7f7cf58f5b4f7396865106f7d1c5360502dc13cc32589e28c5c807911ad55b4d7fa91552f2b056049bebaacde62fb8ec3cee7bd05346d451845daef4c6de822f58cd24acb32a6067efe17dd03e82e6d57aa3399ac08fbe61c5890b8a78bd62944e7f65b59ac41ad3245132138ec8d3c1742d1d825501ff95a7104d32d72d60cfebd3e870fb0340947f05cb92987ac9164a494c0259413aa7cbfb79f80df81b916b3faef3247cdfb545c86f1e6b02fb9e31ded5f055c5250305ee1d7d8e54cd0281087519f9838661fdd6191cc76a437cf8f64e5aec1141cdcabc369fa59358929272b8b498537983f9617262f142ddc962317a6d0ee5e9435aabc5747d6581b5ad087f4998ca79d7f9da8621aa37a378ab93f0d51c2753d56d4656eb173d7096b62f3f1deba94994cfbfc37b983aaae7f7d21b567c0ac560092875d869b217e28293033d0ca2dfcdbe035bab12e14b1dffe22d16d046457387eaaa20c8d837e1c9ed1a41e617370b7bf13c220c450282b7e80be48cfe52bcac8019aa5e6aa58c1585c2363fc22848fd43e70bf247941fec6c48160a7e38bcf082c9f16493184415f353fd8263955b16dfb2ad9edb71f3edcf99db6fdbd7b8e271142e1edfaa3b580a53a6a187305f1f5ea9d10d0851d183983380e090c740822a1bbc7fe1afa11cc3c1e9dfe328cada19e76e9ec596e90e89013141a0349b8073324757aadcc0b0db93011871cd3cfe0f49c2da2894471e240408cde5514802d68060cc8b68a111d5d23309e51d7cc93a08335dbd47498e468697ae6cfa4008c4c06b7a7435725832ce341d86eca0826685c083badb607ff3024206844cc6a3baf1f40ebb1d2cf192a4bb1fdf0a46d82a61bc326d76a8b4997889928cf54f9cf3103b1110628d6aa00af6fe1baa60b588d488a1ab7420c654b0acc0de1b0ccba43987d3c238b3f444a20cbb6e329a9630d4afd82ca9484342acfd5da964369bfb70742154067cfb7c53c071f809e1961809fe09fb7d14f121c130dc76f1a6357df634f36631c929bc6de1805e74243bebcf11d6073cbbc4f72f768809237aad1372c762bb81ee0af1db2d86b6a26d0b00b4809364f8b921e9dfe74f04696757f198236745f0c9f5cc39b7b949e672efdb392e67659da575cd4d92509a7b8a06a23e800c1e024fb513519280bef0312a2d8f8f59d4890d1548502ae70dac1413db65840d6b04bd097bba872145d8d5177324a91da2c320d3b9eabf263d712d268a65f61fea4516d4ea7ad9dc12d6b52bcc8070fc23b8627d3a2144227c2be69d19c5b589ad5c11dff66edcb1c8f5810464087901b2650a6a646891335cf018848a5aa9d48534ccb14e49f00f353d80ecab8a1c1a59735ecfe7b5abef394874abec1997043bb35454247a128920d60e57a99495c0600d87e9eb7a727f5e3a93ecd530f95fae64cf983a76f90fea1c250160e3ae63717a608425910fa5bcab840587aeee9732a91f68434de789c696ff0148a4a7475a67dc1539c9b1545174b857c9094cc5425653546bd2c242b52b8df387844151a8f242c984d61df6e95db052af57eb0c7e9b3ead554f89646c8a2e9b7cbb37751336ee63d95658371a7dfda475dfb73a9ae95ff5b1a4d1e7aa595948ff8aa6d490857c9796e82cdac9d40a8724e5ab23426d24160d81c445fd765afa06a948431443c088a2d6665dd5ab77764108f5e5509db70ded792c03c8c3364e74fb0f3390829842aef47f2d049012e588e46246a5786bd5cfb804e4309037a8ef5d9fc12b60c3e8bdc628150bf5d1d5a57cac5f3136d56f86849a3ac6f85c13551dda676457acdc97040cd7fb434c9b7f21108a64797851aaaf8fbe3cb0be8942d71b786d16828843438c0b6f848d0d2644acada0c0c61855dcfb602c1ef3fceb4308388d42bf1431433944ceebfc96034fe20e933edd931cdbaea0241c34e6c08caa93409f515c52c316038b6df55a73da17cda35f552154788dce7478538db6d8caf3492541326d5e01be2798f50c0f3a901b0629d7f651dd84db617229475008416775e18b32d3301e1ddad223d8da0a875eaa6687569f0cdbeac90ed36ae06aed14b2490da52945d844cb0a702b5baabd364c498ca7bb9e96ced2c492f58d2589352a744f8245d1414a88e2c11fc264de9203924903a01f7d767c3ea4e06870de6f3118821751d019dd7269c45de39c542f7bd1083d2877cf972a5efbdaf91a1e1299f4e3c7fd9b81e868a4963f91c4db6d712a1f169c1bd100246e10c15c327c18308e128694862348191c8eed34d6f0f5033389c49823f23fece6a193e2c772cf0246ba00c73187b861bcb80736d464f93bd3a08636fd7fab7b735d36af72b51806c0d5ca4ac1338ff2125daf4d8f2a67e57a15e6a85ad5a156af084fa70abbe86f8df68c16ad3f8614988a1cadf34c11832836bf456c7336cde006f8a868bc5e38eeffba4f3892763e153de76078f5f579d362f249f4d95917c9284e62380ee327ec5f85f9833dd2d08f5bfd71eef89ef63cf6c2a0c48cbf67bf7b85fd05284fcc81fcc158e4dd606f30c410382a902fd70e6aa77c5d1560341184826b3b322279a15304164dfd166482666744a842ef95a460199338106c26ec1dd4c8acc369148f44915b8f6ede7c562d0bbc3c5bdcec7e670e107bf4cfa0a69a7fe3b2e7b50db42387adb069939e0ef7b71ca3c3e3b45fd56b127a4f46bfaf932d11436c1e71fdfc62e418b0dca5ac3faa9f023627b54e4d218a74645d0f52a5ded4b96747285117db62b5aed1d3e3f6e2ae8dc7c2cd9844708e6ddddf0de4649269ee2b3e6e605561ea5fda745db56911ba9d0a1e9191eb0be5e0d52ccc0fb1a07336410a0c399139707331237bcbad596f056e3e1f4d10e01d9d7caaf7ea711d58bdc968c4bd331fdfe32433cc488f885957508a07944ebcf20ca09238a69b439f12838c42c0c19cc93546cf8f85cabd337740479d46a4654f6b520ed81201608fc6d5acbb4d681b75aac28c5fcd0be1fe8646a5d9d67f569914c2b4a2d1aa206643b007180862d95ac29d642e83cefffc1f14547bd439debff9896f0f725088f8de07262f2042424d39343c2b2e1d8c25931819ec6ca2ad303e5c2ee7ba66bbbace65e566340d2f76002578f397c28376182924b6ac93b88022b209069dbd3c8c22440742ededc5c85ab852177d1922f42b2f771dda15e1eb7213d08b0e2ccc619a65433e048ccfa91d41e38d3057da9da495af803b77b24c1e429c2511d4584675706684b1d8afd6596cba16146538efdf236c0008d0061e1136510240ac80c517aa5326b8d2221294eaaf00b48ad5ec7dff529af20ad11edc134f225f09ddb30f063d38d0cacc01458811958dd9f849419a212b1cb5ce53f2447890b8c90b944425a3662d033c4b68b004e2ca5ccd7b7d57927b9a41438d1fe72607c26a7cc377b5b575d4b41b891c9e4207851c7dc0c841d753345f140a08f408721cf82c36ba88c55b212f051968c7032959e00c734700b4fbfc1346c411f31f917cb39320a54762e58ca22074c8ce0714c1c692de82a4cd888bc2e2e60f95483b78bac52bac469573a84f5d20531bdfb655044394494c9a299c999995d7f335f65e6a605dd4679da981d406cd8c2242ff302ec39f4f0d4c8693bf8fcee8633229f976a58ef4ef8e90210292d043af76ec222cd01fa1627bc0088a913db1290da6bd87786006a04b0894b75f5c76939ed8c73819cd49a0b37a46c2cea51dd5640384fd5d97c458c6b838d23c1e52bf2faa597b573f6f637a4a8cf59c24e1a89dc4d89629b736c6704c3fadb2b50f1601fe0399bc92c883c520e3491b02885033cafa1f4be86ed3e96e73e567efa76c74f247b9d35f4f2a0d19d04ce51ec4103a9c11c918bcb2354897e1aeb2dbad27ac4c2f4cdcdd9db0f4c0a451d532c72e0c8fbfca4dc914d135ef793790c62de8bb238b21223824292132d24f1cdd012a471d501aea67e7b7c8cf0c8f12d3d6e19da133dec941f68a8ed639e69d8c08a5a1083ca1daff58d4ca3bc7c7fef01cea07b228801b34430a22e9135bffae49020f19a5d20c54c6488bdaf52ccf63b50a7feb7a2a7d98844dd0ea265a3d524d23a4a903838451d990644a4d0779940296bad006a0f3c83aa9d689c6a4724d98fa877ddff8825d88eb236be24fa6ad049726684cd4e433b89a20b5099ddd2beba5415c8ffb49d34053b7d8764426c4cde5d6e27c691a9b7373bb5cb71e77dddf197afac909718bf300d03731f78cc0e6e5dc4e0a9af8d98907fe483dbafd978d6f9e00905b0d20c7c6092b35def80082413d157535ec74ca23439f665df539845992e3f8e9e3d2aac8d07d46784b4980d129684074a29274343cf35f31c4093a141fe9d1b6cfe6cae1a23d5a392d36ace55e09810f5aad66b12fa0355bef7399569e8c7089d257d0e2ebc9af114d83ac912a14fedecee2d86062582da594e26d41d4c2dd63187980d0fb6a33ed360ed01f18e5d19a54f6cf3f47d46ea79f723b9f0205f7ed6ba312648a1640300475b1eb2c006c81b2e800bf49c199b053a4acc1d323c2db48567bc810ad8f3b01343dfb252a58935422b00dd74d23683a480e55d80c54ce82790f52a9cb56fbd1dce2195d28a38e7ee9570d75c8d547e5c29b3d627be90a4dfbc52eb35125cffc51d782fb3368858ef162641d29d327ec97904425a558a7c2ebb567121af8ebc449104fd7f6e21f7083ad0b1abe34092a995b28a13521f530b595cc7b3def975f96ce1469ac7fb336c3c0331fc634f57c2fb0b98aaea11d084fcb9b1e827c2fd09b8fb1cb58eee59c0b1224f63c2307a6fb08557970baefc8eeda885bf3e106e52e127f59c4a606df15088f463549a575b65b10c807e3c0790903700a2c5a59b468385eb927254bbdf2076f337d61da15007ee12b115a33d6f0185f8a4b3ff6395bc026802d1e790d62e316bf5368a1ecc81ea09e21b85c38cf8768946314310350d6efe8c3fde2c27acd71eacecb4672a8aa1a507ba977815324a542dd2f6d19a2592771170f608fc451a88a200cfd3f7b23cd6273adfcf2db88c9e70e10abee5f06c9649153e305060ebe198a20f4fb5e4eaa087ad004652dbc4c67e270b7b8e4a45caf34ad7c22ae3e414f90359d1cded342579b30a11b034c9cc688896943db27968b08bc9d04ed0fea5cec04aff01b85720be97bc403c3c86347840b65346ae35e24c760ec01fb14c841b6b90f2bac0dfb765c402518755d853a3a301b03a891dea65dc5fb1fb7b46e1a89092734ced491324c35f3d4e44547486f8faf4eeda8b0a2757a752dd8977a7cd4e25d83d2e71eae449b72c390780bed40e7ebf53848b6ed53046a5b02195b07b0842b91c97fa45562994d64b2f947fff8010af236ea4c1a026c3950701c612a6918a0e48464c2d0a31e74094c5954136dbd205dc91a7ff4d03ef5e01dfd269cf5de21b9073c78c43fef7a14258071ca838ad42d7f173b876e21a585e953638f5e51f939a5ac5b1a8e0e347e6e9d78195e89adb652bb1c03e9c574a7d1336b836ecb35cdc054adbb576d217938f934c9c7857dd312845359c159ee61955adfc520052c4d736ca02ec1ef28ce15e6192ca795898edd5c7046df3acdac66a2fb9c811be8a2217da9f7025e02f5e1fa94d65fd316e91e7fd6d7ff262de736c3784eab3ca4639d7bf46e7d79985a35f8ed8fa5791d2edcc1b60469b9fe73b95713e1348b659504daf1c0c8cd14831bf25b94bbece855ab1b229905928a0c1cbd7855774277c874b553ed77c22c2d115b85936e06926e7055d4cff7933ef084fb764afbca6c5cb09bf152c4c14babdeff21abc3b7e75bf4f9ce2b35d7800783394fb0cf63b97fec477d6fa10767e58075a365f8d4ccaf0c34811d78ba605f26d7334b6a00eba6c312d9ce8d6e60576da57a0c3dc01074d1978bcb39e7bdf1a5ad50c7c6aa4d8c7272ab379f082dc520bb9c1e6f9c22b17c4da702aa9db8d8cccb6e6d625fbc2e6b8766eb31b8eb3f76eaf4e50bfa72373af5b61fcaacdc00e0a399ffb6d5d66a798d440821b420a21d7792e409aad70e660ab030ad7f4c580db0e66721a8aa6cdbbc71484b98f094221c7b606563877faeb9be602372b52b01bf0426c3e73ac7501c7098a7efa84b59933c297dd3546494c3b61b0b30443f78d204cfb134ec341a880daafe7abfebc0f0e539d77b8dbcba29a62a2066c742813907a008b3e97f0854a48025e61b71efbc81643f0c94cdd9d2b916d04f600587a1a7659a55904e9c27d3e50eb53360575c9a01f46c4f986fd782b0d771fcc3e1c1b47dac6aaa32f96156fff8dfed286bae5f82e2e0cf9e92cedc2b324ddac20c633c4e18d800dbc5125da7c2a8a3a522073ee761bac4be3ae6d72514a7d889b0dfa1c333d09594244f50b4781be27724bc042b67e56192517f10a83a7e4ea89ddbea092cbfec8175359c9855ccc084767bcb28d254ff22d96e9f90d60924bc6dd4af3be2d8d7932c807ba10c5678813efa0a523c25c2e0dd292368240bdcf3b92fbbcd850d712c3f662c895155d915ce0e6649e1df1697f8cb038926b1a53bbbcf726530cb0e5acd257b34aece986d5c44b76ed03ba5e96c13940a7119fe3625c9f09c4397c7a7d7993d20aab2c17fec10c1d7100000afc7c0fb4357879858ede831a43f49f401c53da2f8129d150e18c585f4fda6d585a506893e15f1e232e4f86877ea2a9b869bcd6a4c8d067d204705d4bfe8367b170621a30ec61ab598484f696860b2656e733ab2becac97125c24f2ff837ac76db132980e65dd7a10b7a608e245643f40b1f421e760cdf968cdfbffd399b6f81cd5989ae75b927e1c16433fcf16fb6c3561fe823b6bc9640ec3b5ee76ca7f1d53b865b9501f57ccfb577bd0f234e4fe2ba0e76ba5e6b8aef66aaa00fa768b49871cd89b00aa6222bd2bc6050b5023ab9c4f64c7bcbd22c4e2d671134e0e856ff971dea0a2cfb4311cadbb4a18bbbcb2666584b24b1e88184b07cc3e146ada3db1c3ea0a9a3c329f843ba5db10c12facf71f228009e121d41e5125f86b151e1bc256668cfc6265560c1e19a4cd9a3b8ffd6e19d00579b154a8095409f9172533b3a36a62e9fd5504f07c55e8edbb5a50894b80df8cdb12fc7d9b8455e89be93c8974e579c7a5a8cc94d8a105fc33f00ee247ad319b4619175f80211a731fa517795e581521eb7b5dda564544a58dd64058db5f895d5c62673363ace7e7789b7a9b00fe73161cc52394ab54d6f191550859736b4d2ad83b1078ad4e75e6b2a0a33162b454fd702d1a1be12459850154206acb185fa64d0638ded8d73a2a05e0bc8c6d4855a0496891bc79b45d7df674edba625d3c9b2e6377199274c9d46a70c490642aef1c569e2f6a096a5ef98fcbabc035ac00aad330a2c7b7562e0cfdb4ecd154882fa46c3ba0cdf1a5c0ca21941fd8c8a306e7a64b1f46b380a3b36139ff66ab96ebf0f11380e40057dec1a0b99848126a098871a157dd2b6491dd2ad3d48942634c712616bc5ee5d6ffe5d913178edcfc4d4ed362db9126e7064032dceff6be837f45b11c43bb458293b1006c60e5c20d81bc15b81e0441924f2d5a10a85a7315fbe67bda444c71115538096981e0874d0555b598315cc347ec0e765e693f647f6415e36688ce6bf1eb2b717c34bbc664dfb9bec6b8039e472296273aef5c66762c55c3e619b9a5914b531b59b29f259c29efd8b008691d9b2006609081dee9ae028096978121b64d729ff12ac93d2b733cfe9a17e08c1baa3c65c74047bd396385d3bb38a8b92295e1e1faa261121b7c9193d5e4f258931a0984f5b2cb89b58816112f6440c1915351312029472688a1019e041bf060b231f8a8e0ea245d9fe4f79fc207d28f88abc156a6b669d8a2d9d822cc17613c384db1ccfabee3c5e5c2527eafd8f917dce5febe808b73945b939001281c31f83cb0a30b04a4ce0efb73e9fd55f9ed1572d56e460e78c25b1f51539de330eeb6b6606a7b438e15b6ba0363b22d45daefaffb50ad641e97a06772e8cc85f6c3ea34cfab8129fbb05283eb03274124d9b30fe1800ee4202700a1364201ebe3e2276f7a726e794c2dfeef24536fb99bf63e0241fe1c29c0a251603909eaca08bfe834af363375c58b97db873c7732af42e9227fdb0e204172d499dc9e53ae3dbf6b3f3c9cecbe57b7783547711e96f305890ae35253414e014a6dd1bfde26e165896346b380b6247857756a7fd1c8eac64c2c12657509ef0a72a650ae2ae1f6a88c0c1a641ae2443f9f8bf3cf59d949786e86372c9bbae673b22c18fa9f5df9b60af5085108e8fc856cfdb86bb3c53c14bb0c209efc1e70b9be5ffcddbf37113ce22c699f40975be4a64eb865f7931b0978d385dc953e1bfabe404e130c53efdc19725dab52b778cfe4abcc2d9b039823a7003a87f8dd65dd13928c00a5d1f83c906ffa8f8a17e071c8e1cb1755f837f63120cc57d72e34db81b74221b6c99a402e827ae9fe10d2d8402e51a869f18b801457a92ae069005613f60eb24632d3d6d2c08a9dd395f304a0183acc25fe337c5a4c54808d523a3a345814e26d072fc0edbd02f0255db37129628082bde4d38cfcb6434a501555164181e33b6730bdd5f8e341e06f7cfa82ba3dd3857ab07d7d39049591ae7b3c380c47f7296f0eeb34ac2334c33c8224d544f9727b4013b1b7530fda19f398ea33787305814c0b4a074a5b64b1b7be184a19a5602e2decf60a62b515d1bb5973fcb39b8dc2190ff6bb8bf0b1a780e0220b17e75c322badfb9994fe973fad070ed0850998acf9faf14fb0e1f67e78c5780f1f7db7099b2d35c499e5727c75fe722708be039c34a23edeb21be49a09fd75ffd47eaa3203b445b6b7e7e143916a7bdb17702e853dc43b9a77cda63557881eaeaffa6ac3262da60d158ae92ac57a885cc91bfe1acadeae991b95cacd31615bc650ed636fe86fe7f0d360985503de923c6cf124a183eac693c60079a8a19351ff41a61cbf33d965baee298a78c3b768923de5990220f6ac3a4a841f207c47cd9ee00a81db9614ec7847ea6d4befb002a49454a03429a820591b808de0020aa78c2e2a044fee0fd32687159850a51dfaadd42d7e8e47abd428d54103811126e7f07e6868ccb433d409278384137429059390245255a902b56a08b18468d8ac13354475a9ca986941c06f8159733113c6a0ead4ff2a7ddb32a54cc87b7a069b4d0368bd050a337190d77ad14cc00f685118a3dc350b0906bf2e9e89bd16e162a57d27a4f6d188dc45273a3477cca86ca7820e4e7f0a8161d6a23ed52b36399ba8552868d10cddbc7b39c3535a6e9263881edd270cb6845af75db6c53be0e5e2019f7bf0c32d4d9d1b5a6750f1dbe5b15d57afa94ee22c36a1dee363b8629fc71ab86a84cd25b6541206806b67c1483c1a3e8c23349c9e7fde6a7e54529939ff5cbff3a459a2741098db54ef462410b85ffab36cb6a22307351d71accbb29dfb2000a67c29c1bbef3e138dec99799e3c041d7ec8ce046227d9fe82ec0f39d2f687ccfcd1b6fa762447e66e0dcb5d9a7c81c2ff461666c385ea13a6743a0b5ca636e7c188869b0a8ea84f80f8548dedcd41070cb888bf78d0125f8f544ab7d21305d662db9ad92405f6752cf2463a447d4bc84dbdd10aa636f28a0a7ccec7d2158c86b7b369613366ad98975b93ee4f47f8c3a62d796b3683893cb819ca65bec7084a8dc218f7890b1ddb17efa8f93a9bd037198eceefbc0e7b1551b6f7b85c162a5e083b140710f2ca6e7a3c0a9f502936fe9fbae971c2d1f84d6b6542f179bb327a7f15e83feac2a0d51cacf56d07b10831e120fe1bcba81cc8222f83fb376c8008c974391ce5b0f5f5299263f3b99e15d2aa76af7908eb90d6eba477c673bc4489358a9cc622345a45bfe021c63289c2f3a1804e2b075194eaefa41ae3df14c33a5efbcd7994004e25078dfcec5268129fb2d75170a9f656b88fa2b7c568dde3bfc7f9a9a481aa83babbc81f06aba72c8294ef9b4e34f608711f05abe0c181b6eca096ecf81231ce15a84174044a27ac265369fcd7853e0a28204766936cba3ccd608d86f558007a20bb66391a37b0b0627969979702c331e4458f6a35749b7c57f99036958f67c9870961e68006bbb460c6c8544288dad2fe8f409f37cbbf64b2dbb5d4b0d0897f242ca67dd82f5944251ceca6a71e2c51ec646ab854c232d5a5d817afa8fae2d6ee29b389361ab262666c5bd083a31517d30d91b675f70a5a3ef05d0664dbad813382b593d1f0ae0e9ad6cc016259d72fc49c0ac02a56b59900ae20d76d09721295b2cd781df84a0fd2e188ca4c8115861cccda68d6ff498a405e0fbf954a47f33cd8ca39e4cf2c4914e1a5452724f41a5d757639f7377cab1b614b4a786543999756d09ca515b75712f6c7565e150dacd2e4d66e07f8f93269c3576133fe009d1c843500bae8b92c61584d123254bf0c3471f911b81807557ecf04949d8e9485c0be2906ab24e91cbcd2bd4a9cd2529909612d3d1da8307086bf838a074e12cf95dc3268aea23eaa96a1648c553949b529fb43f007b44a5bc00310b9b8f403e6a27a9c7bd47bef009c7280c6e8f8786f8912cf79eacbe8f97ca6071e1b563840673e2ff6c811e157800f9be4398c4178ccf4f9b4b7aa9d5935f284bdc07d24ffcb0c8a0000a3963a8fd1b61c099eed7c605a6084c42bf697c103fa0d2386829e7f7ae018a69aef3ce1da1aae1c905bc07fc56c4977e27408c279bf7825dc7f486df7947a0a4101e775091d870b152144b7ad44718792dc6ed40917b8858de382a8a75cb3cfdf3a512874bbae51ba90bf976d221aaf6dff1f052eff24f1a447910364907aa866ff79d50065fb3ca6ca2b008db0c09abed9c30d2a5a3a0481713ac794833698be9bd6cddb68db9f5d01f8f52b52ab509ca69617ed6f2f23d237b664df85172c0d00b80f04e0db9ec82874db7dd2a3e51a5fc974c1e31cac190487fd8a364e39c772786428ff51e115ed885823b505319001a4807824040bd41500a051577a5f602726116d9c8abd6dc717bc897f3160143c1ba968a95783821581d04551f58da7c0f5c0049cf107125109471ba13afdd826316706b2d512c55173f165cd4e0a2c2ec0b0db4b832a032a5ebd66e8b0508b5d278a2af0f2cb388b939037122521c88a05af2ca5ed6dd37375d910b33db1bfcf903bbb960c9cf022b29328219a0fa44570eca2bfa9a22efda4a978071ff607c289c63d9de7942a4d0a74fcef3347ef1108c69d09008483e11e8cd363eb1cecf268f95ea0d6834033842b16bb97281a123e2190824ddfbd446bee3e83419647ad1fb817a0fc526fe94f4d42fc1d09ad7dcba42eb97d05eed9c4dd7b5f3121f9b87ffadc0c86134cfaaf2dcc49c98254e64db67943efde224449a25a26322cf6f4dfea603b1b16eb2086336d64bfc72126e2f0d18d178c1448601fa4562529efc637ba1b505b5d50bdd6e679532ec1651566a06ce1beeea75e3cb956f143c7ec6c0498754fa2418030405aa10f0aef9063153f187db03a23099d7a9f8473c74c7ef60887cd423c6e1c31ad00009084d8e411a613104ae5a243aae87db8dedec6ade96f4687c95a8173a3d250138df9715a650f053fa17b7d86c7639ea0233957d3590f22ab31f7fa51c61b64d56d1596a6588e967e90ffba67fcd3122e3517bb62f9b3e4ec50e269e6452ba7916d1b77c81b721f60e0c2767c68ee4249bb98c63980d73a08f5875ca23cfa6a0fd0bd01b8811b4e871bc426f4ea89eac85f3a1c284db3108ca5cd4b53d332d07d1a2938e37fdccd7c197f66ce24806523fa6e1980e79d835d03ffdf0410634e82c4ca90581f301808c7a093d2badb395d78239bdc75fd9d5547d7c879b1a2a0023900c2f5f3905669d8fcfb6e000a6ca0f2ed34a3f483f4e3a5375afced67981d8d117ac858cebf6d893fa2945529f59e4da85765dd161b8a9a2d9c7549a854c0a0490f008dca7d00d06901b0541428057449f78f333fcdb29261cbac0468a234b0189f090e5d6c26e0ae7426c071480c483ab999005f02f4dd04b5e0e9eb2d7d028e8f63dd9b89383ac089f883f7d436115907077624955b7a5f9c32685c88a1896c1ba780debb1142e9168cc451ded56c0485a534cbc9531ecfc029fa4e014a3e441cbc50f8234ad74e7113fc63eecd4d13ade7a31c6114dc39b77473982cf303e1a41b7966d29ef5294de8819c2ffd74f64c92a1a5b419cc1bfe871b4be8bc1a336d5fd75d3dbf8145af58b27af696554f5966f5fa3e9b1eb166f5f25d36bdb1ceeae95b363d63c9eae9db6c7a639dd5c3f76c7ac50a566fdfc1a6472c59bd7d9f4d6f2cb37a7c9b4dcf58b27afa269bde5866f5f62d9b5eb1c8eaf57d36bdb1ceeaed5b363d6215ab876f63d33bd6ac9ebecfa62756593d7ccfa677acbd1b8cef0184dd046aed4fc753106867351de04216bdf823a0f8d685bdf171f840888ffeac410fa67013351cf041bb2005fb47b78eeda0135e768fa10b3c03efe12522b994cbf2a7e645128ab7e8c8559acb23ffffdfdff6de7b4b29a54c49ca840ca30bf40b58befdcdc5dda3b4566be3df1bb34cd3b6ed44bb9ddaddddf1669acbd6ed70d246cfdba9dd0d9d9f8bde1570882347ef96954e8b129265cbbb8526384992c40910914e6f198b644a1eb72ba7a753801900e9940adbcb2b1b9630ea4852565986d72aa903d47266397af4fd0a1ebda1efcfee8606d2a24959865cf27a4996215f9e0e90f7a22da5f42978a17cbdeed3281d17b24aeba092aff5d7e99a6935d3b40ccb57c544444444b9d65a6bcdec9452cafab6dba16fbb1b3a296edcc76fb0553d1ab49139fa7dd5237f7e68ea11553d44b0bf079a2ac8544b2e22d81f5948626cf8a50443ea1dfdf2cba864302abd7a997fa039944b9e670e33980e8030897610554aa28a7647618e14b99778a14c92499b8cd2dd74a568d92b977c8908cf8b432f83cd69716bced66ccd969cf7de7befb48ea3238bb17bb983fdd32ad7697fc7512ec59b2fb4c020412131c81cdd3f9778319b648ecc69d5cfc71972fffcd18960ff9438c61ce19c39f45c2ec92dadc84388b8ca605b24c51b2a286d916518f2e554f0c20cf67a5dcf3b9d42f99252ac14f20b42e4fe0983dc4f1b09d9edc8a5cf6106cb60be92af99c16806cb60385e2891a97cc5d718794a49248924910db2d65ae5925caa95e24c29eb1d496cf13798af59328a7ccd2f6612cc94aff9c54c922fd94388ccd10fc4177215449cf2255df1260821b2876c22e6f09594910c29146f228f2ecf2cad723fcafd3a810e26d1226a244b2a8425967b26b9963b5d9308e6ef37913438935c44be8a39cad4c845f4f9922b35d81d73a349ed95f2e546beea249deae77ec3261c9e4c2fd9776ef42e6e9457306fc2614b692ab20a0efb4a6e0e87dc8643190d8734396ca28a43f0764c762cc3a11725591c7ecc8cf0f6aa0696f1b81376a53c8369f2ccd25b5a8b1ccad2ab89a463e174b966d2cbf582f90a695af1158df7160d6a95fd1adfe1d0574a29bb9df9b4c3a1a550e4d142d9d36ec7dafcc3cc59ae8005d9c3ff34b3dd147829b859fe95786289797ffa1bffc3868dbf61e3c613b1f1a753bc9ef26cccfc09a503ea67de07f533348f7a897d6afe34bd7f1b37bec8cbd38d1f328351f2f445be191c4fb911bcd3dff8e93dc69849e84a32ef4a33be64e3bffff13f8389ccfcff878930f199f9c72849e4df0646c9d7f93e1e1baf9934f3a7bf81d261e64fef33f3273c8489fc21367ee625f639fd0d3ce4c69f80e085d345973e3af3295521af2e144c5d3293a414d87ccda40933031361727fc6f7cf225fc56022a78f791a98c8ccd3789f99a7c144621f7c4e9889fc9897d8879e197fb10e455830afe35f5887c24ae44bb3f54d986f4811962bfdc0f3a406678d6fc67ac74c8af9fb37ae60fee250e2194b6ab065ab62e481a55531c73ccc871d8b3c9ec49524f220b985d392c7c8fdf1e250869125b7a42294577091fb659266cc188d3ffd8f999f8189cc20c2c467c6cfd87822334f03a3ba8fac1a1f591fbd97e73ee2ea9d5e7e26bd7cbfe0ead1f8edbb6f0720dff4b0974db8eb4ef7a3c7fd4ce2385c3d1a33be19f3d44d4af2812733ccc7bc246a49a400227befbd5706330967d24c9234d87c607d29e2f507a533ea8ce884321c642ed909d52cc3815c6553600a933d3818cc06d31412923d3a49d11342d4082129952411100df62c9a4df413d3079368d6a0934c20cc26e28a22315d2e3a146fb4eda50f37c4dcbdf7b1b316c90a6d620add8ecbd3a1c80389b8d2c2181aeab69fb3dbb93f5d5e0767fdd3217be42bce458b36a4d7c9e87a42b106edbbe9a37fccb7cb8b3ce89c73b2babbc19461300ebc9abf21f3a70f65a39bf9d8d5f0e97d2fc35f98a7f134705824c360148d8f19e6238dcf93d1bcadc92683b2518346c2c0d0f8a9844703c3684399264423d7d0abd94bc75fbef06a48fc20c3ecfbbe233be4baf1af1b83c3ebd1b048beca5c8e3491ea5d92b97c95bd5c664592b9649d592cd460d0b9acc89d5027747327247b74271479984cf92ef94a6b09e5a1ac558375909b090f16cb618cc5eed1c4d7a8888b715e91cbcee5e990b6852853d7d6ddedd898177c8fee4be663beeba4c80bef5196adaa6f352d9ab6a5552f17765f4e8e1a8cf92d7af3e50b65b6a80f736c8460ae9f6b0d2f8faff0d7eff1554db492ed9bf095d22095dc3f9548c9adc54e281ce678367088530387e009d3c03038bc2f38fc7b749df44ba639ee1ebd8eb274aabfedd78f798b43ae079ea6d460c7b42d5a964f9bf9b4a5c9034f06674499abc12436df1fde2fb3c15a1871067cfa300cdf4e8bcd1d781b51ee240db6cd5eb0ded1af032fcc5e1951ef7039e1bd8ae47aa2399d7284520516d6b9ae2f34a61793b0fe3465af0c96bd3258dfeb79192c7b6552b257fdecd5aaf9b6adc559e66a502279190c67af063329449215bf0023db867cf57d3f47c42541d22bdbda9296849c2b37379439a12d9637a56b25e90587a7a5dcde55ca18768fb0c5f843d947d59f2c674dd62639fc11d12c2637985a767493129ad769fc4dd6e67d316f2e5fcc9b67bb48fe74d12e2a7a01824d17c98903395daee485b3a5e4856e94e967ca5dcce4c9aa6141a66e91ec21bf25a65cc41c74ca2da254c415470507a35472d51e592658f12348969c60f7888b7154258df48ac63ad5465568c929898724f7917cf4da60a71ae4d12d7db9ccc5e24d872e39b4742ad9a9b4d43bfae737b5e4c00ba752569a4bd46a311a9b465acc4f4238f488404db9e693ac6944f3aca21c6e43349ad29c4b78165b2b16a91382451e54c42c6ab17883030fff0ca6f66ec7df7ea6f779bf27139e3cd1216b93608fea90ec6191a6924d825c4d32e89045923da64be6a04564c8157d62ba2c1267857b427248b9650f8e8b98a3b9295c1735a022f648c1cd55441e2938658a950411e1b1689e88cbeae7aaf48ad3d2547a1544040eabe6853c16cdf7734a344f84c7aaf97e6e898ab8ca5cdc1599b352a3c4904d823dba59dea3eb92c37be492c3cc3591d89b2314d8185d2cdeb4b6f492432da685e131410bb93fca6ee8061efdb013ea8ce410bdc81477435c16da7543bd83e6e99711f98ab2fa5b89a156454ea97770b1a9554d5a77f7b90d61ca92d8b9c09ae10bf03a6d376dc957333c2c778664d31969b06be6ca88a84b53f2558e8fe16644800f3722017cb815e17ca82de1f84d08fc701b1ac0879beb8b2c9c2fb2727c91758f36a3ede8beeed17d69b16ea813dad1b250acc534a5dee1a4f6d07c3da9a7f9703e9acff1d57c016c7e86bf791c5f80ec55b99a2fa8e665d0905a15521885512a5a8cde235f65aeccd5c1a073753190a14b22f7d774429d502784f3d97c8e6f8602609463ca042d8c78b3a48951a3c5b42d68311fe6cb7f89779690bd6c66f8d80de06f3e087c1cbfdde0a2af689a45c7a0310d0b5a4c4322aeb89892a685b8e24e3ef09c886d4d5ced0b9e10918301cd175996c6aa86052d26694cf6b845d3a56141ae260e2c8ddd22d9a38786260ee48ad2a0a9154a45bce9a7fd940b3aa50b8731e1bd70f2eb32ac0846f493098fe2e0321b64ae6c8aec95e23898e46292e3a894524e263c971c52581693efd24540e28ec2fb294da4575f7e5a96063b04927b902f84425902522e408e50964094b76d272625d5620db6a664832e70b04ec853ed9dd0e3e82932725769b03ba157cdf731455f868f7ef63a9d3c8f4ea52dd9ab5b15764519ac55212da24b3229d9abbbe1b30f40d97ec44a6a5e4b83f6e8c81e85b6a8626bc522d5c0b34899ebb998afee1162aaa3e0f056e1f709b9631c8c8371306badbd4752ca2379348dee11cd34923d001073c828e23c429c51e2ac42cee062389829871ccc7e1746f35d23d4dc292e94dc4590b94752bc0ea583cd17e07798e173fc0c6e080b583648c02f47013c8a9711652e9b0f0f2972044991117c0006cd6fcdd19bff6fdee7ff060fa1ac214ce4ff4bec73e371e021375ea7ff717c375e001f009e005f007e001f7ef0fb3e763b281d288be67de2185e6cb1042d5caf568b5593f1ff077d7f83e67f6c92bbf9220bc71759361fcdcff0d510e08bac0178ae2916003e001f14843fe89fe683be0fbaf135afd3e0175902d86a3e4d495bcafd375ab9ff8572ff37945d9e02405100bec8c25f647d3400d062327bd1bfd1a3385982f128be72f4e4bd9e57e967f7ca7b8fe4eb0b28c688a97e2ed032ea0b7267afccbeb5594ca6faef8dc5b298b5b466b14c8cdc9f8d9171212b437b410d8551d87f1fcd5b0de7489852249183107bf490ccd1641e39e9d58dc863d22c94520050aa0db96a6aba9dee371964e876625e8697c98417f35c4c8b451e26d3f7ff5c0ce36ea7e3603ab8cd0d3257d949c059ffdb73dcd5b898049af5bd0ecefa5e06540ed96fbfa1b6f8bd8d167b57ce72a801c026e6db926c441b9278e31aea74689616f354b6fd54c2db70d68457855a253fbb49b1ebf288fa6fe6a2a89eef6ff6dfa7c598f0c2691406f1667e4fccd3781b3f5f1ac9d7cca37ea2b63f3dcdfb9c9e060f61b2fde937ec83cfcca366de714f900d3c44b268b06a4cd9714ea406a715ff669506e744724d2b36be79d43be6fb378d1a9c2dd844f2978fd9fbdf686bda78ff97cfeb30f797c3d543e1cd06766fc7ff6f83bee57072b6dbb99f7df66d7783e972b2d33e765402ce8a798fb58a096ffb1f667783cc7eb727e25936dec6c724f4e7b8a72deea3420dce0f81d020da6ad5f6f3a9d07c0e69db9066b7b375e7e3b76e7b8e738e0add8f061179743e159a4848dc173ec8d7ddb729145f391e8b71ed7a476a55ccf3bd4aabe4dfeb79a7d37713ba9fdf585aa5fdfcaed2aafbb3b585ad9467c7f26c2bb2f9caf1a1fa33e6670d2c8d642b4f2c5f797a388c4a39f4231c9ea6d761bb70e66f336250f49b35595bc76e939299c98add0fc99ac1438260c53c8afb30c2ba6ffb4270a8c1f9a82cd3e0fcedcb3ce62b1a5e8fbd0b0e4f9b09879eb73d6d6d3fb78eb638ac43b3783cf5d13c97c86970fe29e7649fcc77fa643c2edef8d32fe6def975482be2d2379230ca2e7bb4508e92096fe6705eeaaf137970d99f27f2f0553cb9778c7185eab9fd5e5ca1e66fcfadeae7f2f1f40effc9c4934dd445fd443ccbe5ebd7491af4266aa22e72f16fff166a239147c7d8caeeee8ef43a322a227a89af9cfc2fabf7c1a77b53874fee83cff6dc863def09d2f010c9caf010c98a3f90df4639ce10c45684b6e5c1666b8c117b5fbf299b738beba5537e4bf913095ecb9f4af0fa9db0b5aabd53ab227df7bcfbb3bf2fbf3b1c3e53ec32a7eaf4bdfaa7806667c2f4a9042ffe54c2bdf6e529a796c8c2dcdd33a5817e73ce797a10e74a6f29a594b49ba9d166bc895b9c734e1caf567932f886985b35511d5f4ef1a41c922ea222abb4d49242d54a528caaa6cf39e7c491e3bb0ea7c1a5787c77a731832dfe12b2d0e4f804084472095b8070441b991e650a2479468e4f7ef045761c0621a998b3657777d7eeaeddb5a78cf5ff74a491464a69962e32abdd4dc3b91bb6a1f306b469978676b11c2713de185eae53ddb52fa7cfbe87fb5a83176b58c62f17e58bbd42401f1f68557761879ffe20fd4040dcccde56394dbcd1c9b2ac3325dceb34b67fbf3ef7325e1c341c314f835d4383cdf50e99de213ff4c2a8f575818c5ce438b9f93454d2393f1fb5bb769dddddeeddf37d47569e9eaedaebf426ebcbbf386a05eb671847666de62eddebd4c4d9dc3ac601230df5efa55287c7878ff6f47f24d5f0ecd4f4ea94f1779e9865b733efc7e3a307a75531f3d449314fbcbd2961e79cddddb556ef89751ae35829b19c9fd6183cb05646546cb01b892b9c1fe3b7abc1268a7dafe7f17813b5ab91b42bcaacdb89379aa84b666d1624abb876fd2ccb2a75796aa90ba540adb20f647f7e4f1b63f67b981f24cb661663fc170099b00714edc73062a01ffb710ea1f329b554b680c0c20bfb2877d8afdceff6fbc87a976da756d9cfbedac959cbdd8f9ffdd845dbf1c46c659ed23f8bdfccf77e407c431a6cb91a894df6213cfd6957f7fb6b4a76dc2e8bc39b8b96f4e9dedbc473924329c549e4a1e5e8b7dd094d728c9223942628e5c964c6082487f4855049d4c40ba5902be3744a46ff1cef9565bf8f6e3bbf46d2ae7635514fefe8b71f4f831126040ad9ef976e09b690671fbcd7934243bda39f82d90812bc500a49a121ae4119c17e6d4d63076df44595c691bbbbbbbbbbbbbb5be210ad9063bc51626dba873c8aeb34ac783ce51feb534a297d1f0d3ac57e791af49e065df6b44ada1e1e1f0d3a7d1f3c563a4f4fc53a604e839e13636194127fe24b4af67e8985c7e3a3553ef43d87be534a29e5a13c94ce0853aa49db9c9e97e97bed4ebc93f71279f44b9f437814df0683885ac936ffa359e6274770e54ab54a3f99067fbc6074042acdf2d72a45b22293fd65f6c50f7372228f88c3eceb3b75f2c957bc396ad0bed0af1fd297491a745ab15cd2a07f942ff151747e905685129629b6a133ada157419da4a4a5a4956317747cf0600a32cfc8f18913a1ecff03446784b58a4aab5c368937fe390d5e28e6bc316225dbeb748eaf240c363f463a7f7e281c72885862ce724ee4d143f609883c9214756db0621d9ad36178305e904cd23b7c49eff0fbb98892c822b9a45546ad8a5b647fd924f288314629a934e834cccfd1894f5f45b1df4b5d3ad39dce6f1f45743c6289e48f8507cbfe39add2a9a1557e14fd9ea674f92ac7ba14a38c5cdd29f6e97ef3313d87873009e2831cc3f594f7e7dbe414b1b0b6cee61c4f1dc193420dba91061d084ff96f9f3c126fbc0c4f12495783fe4e8617933c2d6c2189fbcbb8f3a04aee1e10e5761f40b777e31ebabf2330710ffdb3b739e984c9e194deed1ecef6dc659a685739bb5d2dcbb4bb59ae76d4345ddceb1709c39d5a15bac7c8ed0a4b80c1e4882843453dc8a22409d849ae37d766466fb5b6669a6fcdc92e86452c11a7eb19870164f1032d4eb2b930aaa85a71726ae8e1c13d56f1bcd2e90a655146e22e1e32107b4819c41cfe314e21873853c8115f28bc78258738591a8937fe5878a11c72896de491563556629f87c8a38d6611f1a71734678c3146bf5ef0e2eb608b365bec41fb2c88bcbdfdc2f8caf63730df10275fce3ae79ce5700f42a804ecd783b5c16edad7f95e6fdb361c02c9da471f32cd0699bdf6c94e87f8d1531a7dab65d3089eddb4f89af61a0e85d06cbf9b83577f764e019d1fb7ece39c26db1a5115ed9f228feced5f5fb9bc7dcf5f7cd3e7eff2f5739fe74d725ff6cefdfcd8aab086cb77bfe8b1d341eb6cf0bce153bcd15ec75ffba87d3a8be0c99f9e7d12638c58896deb596881c183e93a35ecd039435f10e5e47411726cb0d19a974166af7bff98e4fe40220f9bfd7f228f98fd817c15c47d507d223c96cb7b7479223cd68d0f4ffeeeee533c203fbe82891e4aa2970fe50926c6dddd2df6ae7f0048833fbdc3dfa134919d9c46f6e5f31ee6eb7ee633bdcc279fc647f3333ed4c77c35fef4d9f8646e4f73d926372997f3d3e303c4ff034eff337d7ae30dcc8befdbb792ee6bf7373e218fe5bdcb1744040ecb7b21cf870da32e11263e356f7a2232bccbcb8f48cd9b3e028937fe3e8517ff07d4c5f307094456100deafe8f7e97ff21dff45bf7a1ecff1761791fca76eff3f2dd5b8b7d60fef1909a87b11fc62420be3a29fd0831228f648f59b2cba0ec5a6673fc6970940e2f2f37f0101930ca7ebfcbbf7c867d60bec3436a30ea621dfa5d1e65b14fbf0bca473ecccc9b683caace0fd5f3f21288ac1798df242a661b3b14f7bcc06c302f323333689cfc633c0688a73c0675eff241a6f71ea6e765faf7e32937b9ffccc9de2f5f2ac11cd9ea6f6fff87f61513a9afbdc54498f8d4d79e88fdedeb87eab1f6513f5c0babfe804367f9ddb8654b1bba9e3ba57794def5afbffdec7fd4bf98c8fdfa192642247bfb9115b5cffbeeac73de1f200dcea4a8d43d95d8a24dd873c6ca3fac34470c24278e32257b348e32c7763f9be5d7bd9afea127a4be7f1be5ae071479d85c5f1ad50722f2e85cfd61afa3ebaaf56713af7bee7b88edbb1fc27baec328fadd1761711845314a876da394b268a780f0546d0135d8c423c2843e11ef3769bddfdec7c3a8fbddcfdf9e621f1346e9d0fd7cd4c53e1df6de1fe5e3bdbf87af735abc98296767abee7711f966d9ed78dc4796c53edb0fe96687eaf162377f7b8b7dbceff0900f70de87ba0f84a7eac53f40fac398d4ddcf2b422b220be58d72f7bbdf2d226f96567b4df6f366bffb9bec503a74bffd05ba0b708fca304a87edbdf7d9dec34398643fc4c57b93f7455877c7871c64ceee2773cfcbdbaf5a2027af5cdf1261923d91f99b8789f87b36bfbccffc177cf254fdfbd1fc19f6f1f7ea03e1a9fadb57df54dfa53e572390a72a4f83f52fd669b0fefced7de66f18757dfc5117830dd68f2c1c4f1dc1fb10ccf575e2ab6640d5cef7ef166d9313e227afecf66e87bafc06416f79389b8e56cd0663eb68308634388ef271e2132220c1c1c18948435bf4e6abc12825c722af1cf174a406bd4a96bf4919846d73252fd2a3f854325283b17ffb4219cbf1b7b825c7e7a2349ab9bf73e330882c71746225c7df84b6b8630a89e4cdc5b3e0853763c1869abbe60e954a1c62678316c444939fc43d2ea5bc213c65d9e3d9dfb8a2f98cc773a1f99c7ec53c0df664f433eca341ef69308c3069251442b315bf9e7d9f5948d3fff0f4ecb0245bf28a159924bd0fe5906c0945a5386386babcf7997ebbbef21c188ef4c1d30343e27df5072de66b6864cdc7d14c8e763798328f0ff277ae94a8b7f141dcd708bf56fca326bc596edb908ffb9462288ccabe86433d2ac33f6a30ea699e7bd40f9ae79e0673afe3754bce7cf05c71f7cbd7f8bc3f7d314fe383f999affb199f4cccbf681faac7c5c5947b643e282826b2664c5f8fa7fc5d3c87899171992fb2783ce55e83b0fb1b6ce3e9e1e147c8d5648cf306fd5517cb2b0d7ac54ab8771c1c1cd67d64f6c3ec791aecc96876b32cfbecb79b559e5665f5d65a711ae4b162c537ef63cdee8d601491b39a65198fafe21892ae64f717f758335496cd18e241888f2187b14af65896ec4b19b5f2a48c2bd99f6bd54cf69757fae917fe29de50ea5986c3fad37eb78785b8a4fdb26f060095dbf3d2d0e0566bfd89d90a92dc46720ff90e3c58993f0d0669286160c99d7b769842eee7a15535f7fb4428b12bb93f48d492bb3b1c109095083debe2209dea9740b2befc0b9483e73704c9a173c5a778236b8422c8f5634a7ef6f1b4aadfc74faedf9ecaf254ec230890ed7666cde1867c8ab914d0eca369e8d4dc799b939785275f1ad5b65dd8e40d268f3fb6187974266e8b9fc9db26cb437e962596f166369d2e5c547504e7c71ab2c0553107e12e2617d36c6dd157ace82bed6b08ea8829edaffd6c1a870e1ff93ea5b1e1616aef32590ba265f762c92a3283a8dd566cdd442bcfb80a22e2b25e828472582f4fc465f589d5945b051191c3ea5ee8b24c1fd21c76b9fbf0a5fb3066b6d7dca0c4247ba2d2d07c20228fd89a73ea6870e2e45020207c25c347295ddb89068faf7826529e409e9a7f1202d42010bd43494a9e7fe9ebf4bcdb8def65abe1fa0beaf75ece8b89e69c48e69c4a184d3b7bce2b7f5a15c60732abf0f80ac7e7c4913838b7066843a6e67b5f943b427c3addf8fc65f8ba46ebcd8778339fbe7c3fc8d4fcfe822218f2e43050bc99f7b7fb1bded130d0fc6be3693ea8c6a37ef3ef25fb64e461caf363cdffe8be06a3583f4c8fba35ffe3e56bbc27e2fff23fbcaff91a4ca4dffbb8d17c318ffa60dec637f3353e99a7f1b9fce99bf176e663a867a327286808979ff14141331f14f32f1f24f34130efd1f88ab4e684991f233333c3a5480ba887a7c1f9d3f45dd7d2ad982259bf5c91ed93a3dc3cf2c2f88a2f8f5ae5a455173cb50b088f43d7f35ac853dd27592d743a799e7f1bc8fef2cb1ee30d8dacc8d3aa1f84dc9c7d7fdb55f7fd3c00f940af4cdf1fa45772e801b1876c2273f41b29da32042b9c259b745f913de4d195eeb3436ee448f66818186104b732a935ee25969649adda700b6d418198a21f851df8c41b9a0510bacf474cd12a4b70b8d9beeda85c5c4408f4a889ec218f868e868e868e866493af59f28aec2193648e7e99d47d7dc4481b116ffa1b06b247cb6006f1a63f9455c8fdb785889045698f7c25935c5e91ffa793e7755fc9bda4bb284923e954bf3df2fd20c4cb4ae4fe4622e6e86ed2a92bb2472f117354a12225c90913b93f6c29e4fe4ce88bac39044f7ed84232b6290716954c9bdccc015508a15a19db84c39421dc502a88f00f2b72743a8199ee907d46907eff0562e6f9495ac3249138d5e7d71b78f3dd3d9fb74ed98f73838db258dd92764ccd8f330597b2ba93f1667eec9793b5cd28db6974ef16dafcfd431b3d564c2f96ddad24fe5cc237d836ff607ba707b3e7e4ed05e6fd6b7ca78fc637e39bf9643e1cb0c1066de3f80ac853fd9a871fe4708883e3753a50d60bbe41907910c4e9b01287c39c17a59bb56325197cc2de38cba4c8ca7db4c91a87431ef27d096ad9c799b521f9beccf7f3b78afa773bd47110a74e538268e57472e9fb82a61ea77b37ed9b63e4215d62912a9b8acc1f5573be5aad561256bcf7748a5185d4854ec213242c4919295db2941fbee498c33bb14ca12ce746bf70e290ce772c7dca286da40f213dcafa315b7fc243e570a387fecf31a370f84cff33c55b90a20b2a5bd8a00953aec00a1b839f6dde0b24a47085dcdd4dd8240e0db9bf6748bf827277a5aaf0c4e3aa61e27c83edd2b177997844439079f602fc4dd4f4d1748afec9578e719e7e4a849ee5afa357b10fe0e8a990864c751aa4949abefb1ffe8d89f4fb779808139f7ef730ca7e64b97c64cd5abb9f2f6a3d9797863d5b71f53a8f4e5fc52a73cdebf4166950935249d43be80731b1f446a42f916afccc175932c800f155c780602ba541fa6a90c27a077d87728fdcaf67c6074cf61bfa0122c367fa1b5ff74c86f037fd106de36b7ccd175996477dfa0790f4e9873cb21c8292e9cb98144a69445f36a12f5f520a9540e853e99a38c41bea0099a24f23148632c542c8942de68179f265f8507fe3a3a9a9389147f6f40d1057f249265ff23585273fcbf0ce7d291ecd3b3fa02aee41d1bc7d77e29ddec607d1f81a2f935cbe220f9be9530953ca548ae7f98799b7cb7d20f2984f1f0471259b8829fad4892b644ae94f2c5d52bccea174a174407dcdef40f332bcec7a6e50196a3c8ad733310f9d28148d89487ff7a8cfdfa483bfe97dfc4d5fb14fdbf8bcaff1b9fce983791adfcbcb7cdccf7c317fedb5adda7d12e629eaf2d1f73efa2f1f7d982f7a2ae6a3cf51f9f214c5401aa494ca46b23da30a5b51a6efdf34f2e423a5269d6d8568255af12dd2f933274f4fa741397148bd1cf04f36d0afafe3f6eba7413ce3b05d6104978f225672d8ae300213b9ffe6d875105a11da2ec44966752fd6f194bf534a699db2ab81a74187c20b41900687ffc957f7de53775d4e284a480ce59b1ca148f122cbf8ca3a3f755c524a6963a07eede3eb6452caa42975a4f46072385b26693d7b309ff0a4133cf933ba8e1c5b1586eef2da1c4fe148d912c7a36b56b2bb6931de8f17839e8a93a8c8c825ff06104ee63caafd924482e1b676a4735aafde0ee63b1b6fd7d6fed09fe2d8df5be956dcd88dc318b9feeae1d9a02c32cae26b6fb3b7dcf6f776735a161b87564a7cb1843d11bd6bedfd89a9bed55a8be49827a6ae94d65a4b25dec4c7c979811dc42c623b8321796eca5ed638e34abefa3bda2a0ebb45354aefcfd7be493b2c9d34687a9707e22bee5d2625ad388c718c8de95f544f7fcc3fe46f320d7a4268eeefbe08cb7bee7de47b78c81023ac8ea35ff7a1eaff78ca2beee1a158e72710bcf037cc64fec9cb48b7e914934a2ab5d8a24d189168d4d16003c97e3add8be5eb68b07384509c9c1027374e0e8e1fe17ebc3c0dca4d09088820392491c88f525a0aa45521cecf07a4904ec9078ac2f3c7921d7361dca15513fbe0a155f2797c952373705a255f47ab1ec893de9a12c8bdb1d28b52213fde56abd57ab172e6cf795f39523ce79c73bea020a2ce7ef073f821109bff7c3addebb2b6c4e0f70d7e7ef0f6e9937cf0df4e8092e448922a3c380284061769eaceb9b951ad66d7d68deb4c2e2e26cf140e8112a50859a412a5b422d18a64540509d62afbf12515cdb4bdcbc70e470e5d1751c6617ca223a6e8bb7c363145dff4c9c414fdeea340ee3594ad2fcb1953f4332e5390f21024d77048aed2c8536e8414062186dc2ec8f2a591e3f0b93e076e580407b10a990a459490c30de49ef8e38dfcae12ed0c0852dea657f7d56ab5a4b0fc63a441078e4cdfe6a32ac6934bc9d1a3b26d53d93da717435b3cd1434b4b610b6d71b9643f5a8ce32929bc502a2969e921bfc2166dc23994230da33e8a3c9cb491b795ecdd444cf9bb13d98bb27f48c3944db9d5a00bf50efbcda0d6f4496f0d7d0c16b72bdef84f263cfb61bbc2107bf890398c7c75df7d4be4d1f769ae9f6f8937fe3e640f0f43cce1ef6370429692c39befd7464b7814f3b451feee9fb4ca166dc23a94e7bcd7f34ea798a7e6c749650edadbd55f8e4e8333c2949eb6220f2ecfa7424f8db46a681ad5f849e3e7d397af667e3e85f9eaf4f314f392ace49965becc34488673ef76e86f56b39956e4b1ec9b4a73c9955a657fbe6bf125dfd22a5f722d9e45a334bad7787fd0573466fef4fe3a3cbe9a21f3ee9b12affe0d152b89f90d67e955ccb492e76f3329cff7d87c579a1e73ecb1063d4ba7e6fb963c1f87ae25cf9f3df05cc93fdfd2e0f4589606e7679ff6390fbcb9a4d4e04c3295f27c3a9f065321626a3eaa89930d24f27c18e4f9b415433368329a708023383096c86440460f0490b59746ba1dedde4e8b9c059838a2075b8002931c8461090c26b69346743b3406b20c02c0808b4b682286d190169715605eb011c389298b87e3713cf752a8b50040119c26802a946cf74a22a074218aac692f87b8dc57b1c46d32484b17f2bd2f5f30e42b7f5dfbd1c36885caeaa76d40cbc518b295b1d6ca5871424cb67fed7b49a14c0e69f2fd48857cefe502897cb9f822df972ef8ab752bdf9742743b37e95aa1365a8021d32d6cb00517ac4c91e9cb56d24d2a12444cb254a394c62c6e50852064218621807103162523534a354a048a164bc8f7fe906b230f8050042d471c01062966c0a25dc854015a682da0220b2b6eb664fb2c90dd12900c09b1052b4811038b6ae9620af779d29caa15cc06c2171046b6d642c902896c5f05dd8ebd3616990111b4704118ba9085296060512e64fa85184855689084135a84606d418c2e8278ec5ecaa5407b14743bda152ccac8d60a284f9802a54a0fb27d21b74acc097ee87636285844c9f7be0fddceb59672b4861efaf4bdd3d3644a358d7218687b13743bdb155ee4fbf37e09ba9d6badadc15a6bdff3159024b8702485201855810596d542b6d63ece18d9be0e6c85c8230e91ef93a0dbb99406277291431d99427182944c7f526a0551a65690912912162ec8f48a2e32fd20dd0e75245ff5681fb69486e5fadda43ac995d6fa8d84089d24d72ecab57e07d5dad5fa52e906b9c2d42559a556f932225753adf5555fd5c5845cb95aab5135aa5c65228c5cb95a6b0d36addabe3e581fa70a2fccb1c94375a853f269408417c4f49a4cd66c0045d634cd0658b2f63d743b1a9266c256b2f661b7a3218532364d349169164d6021d33f45a9c1944c7f04dd0e45a256945e99fe0f16cfe27a42ee7eb62a27772f826ea7a35a08ba1daadd1d3994c997892ee47baf2b897c1f04da072e163994c9f6460e69b2a54117d9d6646bdf5bca968929d9be07fe76c0932ca1010d32b72373cf816e8753b1e803f12348b2fc2885bc6dbf816e67a396d2d7400690728fbc94c7942b3ca9418fdd1b79501d21e3004b1465fa18b03653b4789e7701ef093364fb16e06054b8fc9f762042b6f62b40af0d8ca822f6a409d70c5855a90a249b7644099b6cff878d5b16bae0c1a5800fd204ba1d4be966a396032d44a862440c2c43604216c038c26e12d05e07258870b2fd1e3a252957995c6f04c490ad7d08743b96da970d15429eb5567b0095e9010e0f8b4cdf47b7439d6a166625a6fa520e62b4b22540b6ef806ec7d24d8b0e283ada0213423822126261e10ba26cd370b0cfd3edd8284904654aff8657f6a0af1aa9d56a2dc1cab297c93e12e52c677f3dcb3ec846a3801cdae0882ede0c398c58a4e4306631400ea396b8252894476492284f40a1c5104351a0f082288a1117a2601125085518a20651a290c20ca248e14594264688228424727d1b8a72fd9d1aba9dcc5f2aa082174c306206599278c2159eb015ff542a76355932491447325882c1172ec83265072ff4da06e0f89c2fabcc39e56b0a794a814da5a934e718f29c3369264d204fe4b9cd395ff36bb001e7e37891a78e3c73f2349a2f53c691393f88f661d422832272f6337b56b793655af6b9dbc99cc8b7182942be3fefeb743b97e8660ce8762e962c63d85f80b5af806ec74ab1af158d4116325540a6462cc9f469e87628b5aa0364fa3dba1dea4656b49881861cd200a508274846a0085501064688c1500ca4c8f579789e9604e428651f9a748c22ee563f8f7952add6aeba1dba24cf9faa6e67566c8b308935d13262a98b25ca18038c26f4624f8ad9dfd1ed5822904065fa3a6ab8d1ca912458166300c3166e20c61754ee9c73222096caf40f306f048cb4ba70c4149610c201ab8601860b28a5d9eb75df00ddce0db9202d40192207797aac863967f673ce0720093a02194e58210649583396e79c9ed4a08c514dc3a17da09f20d6fec5f6463bbdec7348191a1b1c92881cea9012c358e54aae114bccd2e5306ac1516b954724129924944ba6d48f6368926bfdeb9d1e6c15618a5c7f87319091ebffb4aa95eb03d19241cb054608292157284240c9f5a58ba828d79745ad8a505cb02557282fd822d79747ad8a50829cc8f50b205f745e2a8567639e9484a5417971e84b3762d842a6f471c46caa08ea2ef698476f248027062a79ce1fc0b431832cccc0084a7881123e60553060472f19bf5e3515e588579e793ed8edcca498233552d841bdfa6923d92516a97483ec39945ab2b7604568210c4b8ab0052b944b5fe4b05b79e54afeb2c9d16b08524a762d7821450c889880011456286156904bb207492129c8e0e6501ec9fe0516900085154f18e20a2c58a17461c9a1245af92b56018284684465e546577e4893fd657ae5449d92ef3851c8ae430260d8c248d00b0a4c8c8115e67891af28e18430410a2e1c21450f849002cbab90fd83f4ca878642192a39a4a1c9a18d149030002980310521240991eb0b00cc3e34805c3f009d5d4bbb921496c8d9cf567d397b00743bd98c0296e6a25045bef76dba9d9badc2faf75e7baf945eb952e854b2fc2bb16cedcfd0edd80b9394eb636fd2eee48a14990e20d3ffba1dfad3a0ecd707f41304a85555a9d5ca61c540f8a741c9920fe4497ae549bea40b2ee8c8f33fc957aee49a57c218f3966ca50a05ef065176245ff9ebee60082f30424b1525b4a0042a5421860cdd4eede28a9a3bc514234e343039e4a010cbfeb30b25647f9427a780cd4869030a4b64ffe95fa3c6224561249114832b14112528890a30f2d4ed542efc6948a256ab150377774f01aa1904a1091e3ca1882428583e052b286d7606fd996e870220879c4cae1f439ad0260139c4a183865c6ba492c511b9feac7fb3d822d7f74e596cc9f55f0ba45c1fdcc2895c1f27a755f1c91650c8f5891526b93ee1a295ebcb44242e68be14532529bb3f8c52abd52ac26bf0224eb290858c329e08110581e552c8ee4efd8563420e6574e490c626d78f210e06e45007165280b9562cba78820e72fd6fd593276851c5895cdfcb5192c0165214018a25102da185283c210292fa72213c972bbc4043f63729297950a63041bba20b9aecdfcd30be7e70a5668ab92b9ac8fed37fb3a622744abefab1724ad24f90d6728634e5d6f76814f0e40a50c88680942400d9bf4ea7c2896745153a9392309426428481240921ba60d52b5520b1cd39b1c392324fcab2527be73b169e2b65f867c6a52c65abcab7220a9cfd270ccff873bd56d150110653ae0d3acca54c2b316645502ec084b5ca710df5737ce54a9e925f6b2da34a13aae004a22b46788255bb88e1e28b234280210a4f944021572860e020d7d7d12a9b2bc50e7b29f1620efd95e5fb142ff4a21fe99272a9c55ac9ec84299947767fb91ccab34580ee242220b920fa8ac9fcf877dbdabd99a4a0b3fc3987ccdc9f0f5541363f9f99611977d016d0dcbf8310131f72720f423cdb07731156763f9441d913c1c4879c2cc40de02f6d6743912ce6206897434caebf496ab238059da39c425bb4a93522fdcbd8608893638e951c81f2fc9eb163a7a44a04a90f70e2f44cc9fad95e838d8796430d1e69b0a75577c57d7c1ee2cdd1c5d4bde0e4e4183d5fc9c49c72603c9c1725d0bbd7c5f3803cd52f8fb8fcaf475d47bc08fa470f922bf775878303e57ae9dd2477edd3b74f71094ed9624ee698a2af7d54647a45a6507811e83cb14ebca14f9490fd65bf4ef6f93da7d30379a2db36e9e630bea850257e83b098c5c8921c5f864647132942bcaab0244517f19514cba14c942fc6e0c557158ee4905b72832c9f1b02029b84e209a1256ec8504383b251e34463c68c4c0ccc8be762eab84dcbaead74d6306caee4c58f76092f8bf204490a2a59be0e959792e704922b875c510e658e724803cba14d142856728843070d510a521fb129e1c5284a088a220a5130914b46394679d2cae1cc71e6f8240a1f4479f2922228c7284f8ce2bfe4f8248a2c3946794214a37022ff6a11650a272e5ec477c9f10914483946996249fc2dc727500c21c72745b01cf62bc79792639427433974a11cdf94e313288aa040121453f2a26a8b114b8b86274b2c2d9125c7274b5cc9f16b8e4f96c86289284313d88e78f1890e8e745094e3131db8727c2ec7273a3092e31327b6442796727ce2442c879628472792727ce204520e2d2c471a393e71c2e8e58590134cf8a7944a98447a45d5d45cd3dce511516f718b94524ae77c79adf2491ddf10f37cfaa8892596ecf1fb5ea75a9cf4351cc6a4fc2198e9e764ead77a279ae349cf73aca7e110cc1f537f3acdf06a5aad318b375a9d988a490d66b24b4229a576d229bd9fbefc843c668fdffdf266fa45727ff4fbba9d9eadfaa9042ce78573041ae5f85ee444ae1c7de8c6577606e41edc56eaeef634c34692a7bbd31864a48fc82d9ee1cc7d3e9999d0ec567c9f137b2e3d145d66d9d32ccbb2f8bd94e35b6fe5f8b56352769237b32c73d86ca469e5e5425d93a791e1429b7c634a4e20e69c724a2df460196fdbaedd309c983a3de871138bad3fbc11941f1bc79d9b2bd7a6212fd307752491c9b41545095196e4644ae9fbecfe884445f3d060bf6ccd0fa591c8b2499c489143454d8e6ca5b79b35349f3034b10cbadf403f4180ecd060cb0928452cc9310a394221c2097973e1509808f7341ec53d8d2782fa937cc9fe11f534ff83fb1a4c840611263e349e7b22a747fd8fd3a3fe078de7507ffa1fdcd3a8b2562a8394c28025abf7a8f48cf585514d999a19010000007314003028100c088582d188441345d50f14800c7eac4e7a5e9cc74912c428859031c61064004000400040643008002312f66162fa13b090b119525fd40baf28e1ba09c96bfcec145df1102f116465ca7892e1fa6fe2026c06e166409df9931c7a486ab151074979ffd63a71bae1411d89e4d8d65d88cf5241c5ea8bcbe4f4806824aa322cfcb37ab5c78924d3257b2885ce842af310ed9f86956ed427d50fe264d4db368e8c5546dfde99d8b296236b2188fafcd776cf9f1a82087ea10fa61c0485212e585408ddc0e6cebe93d08a6928be780e8436877a2e4d83e6610e9aa889bcfb8b3f96f710ba4e0d5b5fadc695cbb8fe381ac8f35d2bc86c597fe5e0f98016d03a3d386ecef3fba06d46d11bbfb155c13c4b6b85f69cbdd81894d08407f843214656ed759e4bd1301f6ed2f667f37022ad8d618396503e7592f954048547cdce48da5ee32ab743e529d9a49e5e8920ac3054d1b87c055b6e5b1d9f8fef5fa35b12113190bcc681d77b6d993865370153d34096a6dc1c5920c1a50b350b28ed46fb572b5fe407b64ae53c86e36f3d70a3b02d25b26d6ff98c107ea1eee065e1f835c8ce95ac589f5a7dfe84064b63c23944273ae5ff9553406a6683924a491626f74c534629902b5be7952b8b32eba5bc89cae11288490b39edfa2da36632e70ef55317fd4ccf6d24740ed657d8bd4ba6aa48716f1cc4cde4748da446641c9d080f56c5d1534f2d7a1629b60d63dee12e9869b64721c9e4475cca718319771e821e9b3fa670640ab83b34d25bec598b43c03175abb77f4c0f105d97e801758e1056ecbe70ce83391016c858d3feca76927083d217132a17329f8db1721c3bc5ec130dfa1825a53b53aa218c8747fa79c050e07334ce0419833d44c8aa12a85aedcc632c2011715733101a0eb9950999b0d032a6d4823d9bde2eb1a58a50d655523ef882bb3511ea77ed42db137bf2e51db6120bd1032809a11c021b1085d42c383363ba7113c3fb251cdda7491b7b1b9b63bbfc1a757285a86d6444faaf9e0613da15e35531669f187854d6be4c8e3c8ca8fb909ad736cc18cbbfed1899687093846542d6fed24ca7a03f754054269ab5394f2e7a88431b98d29029c057452753c96dccc119747d41f79933a33f85770fb56215a27508097b6b9ec76893ff1e6463a5192fa6b95c3afe9ec86234000485c89069fdfc453b0171ad8d3284f8ce9656a63ea7fb3fc35a81743f28c2b5d8f567453e02172d4f2858d0b496b24fd90ffff1200d9fecdfe68878d0bd3d7c264398a113872f0ff4c48f6a10e0e49f5146537bed06295bbd3634e01f4c9785cb073c696a30a1fbddd99fb4c30105003d33e820f379775e0849a8f22879720a5872b16471023cc4152c592cd603ffac0cbe5613f58bb5c620a076a42bcff09c0e81274f41ede66948ccd9bf2fb0e8fc0ad3ac37006c29c18ab478471b9f8592c8e74b89c44ab25b35441863f4897bf41115149d4ca3bad546613462db50570f592274e9e09e985d67ee37c1ac38aa7a9b31816b8cbd75d9db568c0f9d5383dbfe8d8a1d0df735e6a552e8ae3cfd649cfb04a9b03360eab76f43f3460649300109ce5ddfb021faf8f231113eea8418c5c60ff2d654d69c96cbb27ff2820677177e40e8f6dc36861abfdea2587f9e93aadd2087447b6ed2dcee6381d87110c0d07a64a8b8cd9c3c78b8d2ed44269c82483cf3739ea55a43a3da4eb633b3535b2e8480ea5d6e978ea87c4cee9f7e09f448aa84165517a55037c82af403a6327db84131606d2c365c2efbd545d40b5f3eb932aed80315f716554e4b7a53eed305040d087568449c065c0f3147bfc612596cf4d34bc60096d7adf1f47cafb1f1d641e8385016b37c9ea6f16bc003b3fbeb27b1c1531fa867f94f2ac31f97a12d2bc713f1b6ebef4c2072cf00cee9d2261bb88372439804b0a7b51e93e42f5d1fb1aab5ce3832bfbc0d7da7d98c61701281aad0f315cbdcee3a3c07e3a4dd8cf45353869cda463cd4306d3919707d1c6b2f4003006e5497a611858974595d6fcdf513ac80be38becfb460342c557134183e06294f42f4895a0efb83fe4b050360233f071ef64af488e3877b87b2f8fa47ca0c39874392044307a0626363fe6be01fa81f0e71f05a0999c6f6771ba016374850fb981c793ccc01010247086203cce476aea945d5806e1d0dee8360d635435eb3adab646534b7fd3050bdfe295512a78de00e88e662b095306193c0942ffc1be5e01183508fc04a5810eb9a0187e0176d6bdb75cdf8bb46356fc9b76b9d333af7b2df7e486e564a16ae2e6316398411a6f764605ecc091043977b41333a39c70be443c95c2a46539adc6d9200599807b9875e080a98770c810335e1f0bdcf37d9f557fcf2a281eb2d084e5989fccdd282e37c7d07348588ea16b2ba3436cfb0a1ac0e521a9affb01cfe434c3de8762f447687f60c0c830b71f425a2490c05a4920add6019e290a539332f985c5bce8ae093ce558d2e43fe97f17621e3f200204f6484f3d6038822b0a10d04b591078a5ac25647896d68f2b485284f45c9cbb528f4c679859b1f66a346e4c0cd89a8314f67ead8de5dee6f0656e29c714ad3e14dcb2616617152c43af161fae4726eeac14438a675e0b858880c43f8af5419c4f0666a53ae1f52461a00564a051c9e53569bf2359f15a89cc38b81985c93a5db80d512854036158ecc7031aa8cb6480082365a5fabcea1c9b570c855b029693298a5bb7563ae3ed0f75cbb8996da2bfab1a49544a3b00c7d4dddd08b0585763d310a7ab02c6ec02f22b7939b272111f5afd192a68ccc994051e69599173b61c0dd16f3de5944940e49b183c49d169dd6d79f065272ea26a69e5b329ca52ae1df8488064062bedf73980dc1ef1e75130e450d42f78dbec550018865ceac4a54cc4c57b9fd1c0a89aaf6b51216212f718996ad9150520ce4915dc8891dd6a0647855f0e9457702ee5d9b638f85882ecf370c1ccde204756a09c8a8fbcdf0d9fe4bf8f9805da403a219d69c699e3118cb170bcabf90faa1894bf44d43dac4bb3102e855e8717ca8ea1016682f6ee08465f779ce69671106284b4505dedc68552d9803d2bd477a405c7f25f38a62048d4a740f11dd32b36597c36080ce1b80511a047416af218a5c430edb0552ae6bd9d12359ed8859598b49ba57652832a04d2d2c0593bfcd0e4bc5519c280a3fccd790ecb88cc3ee731af426f1ff4b90543813abb68d31c7bf8885ca7e483e8a9d777fdffdb5e6ce18a1518b20e82e9bebf5928d5418eca976a8a96c89dbebba5790ce0991297368d2dcc72a0815acda1b68c4d2b0db4fdbd291a62d6ff587180324c0dbc5fa97da47b945166fa97f0d19b02573ec9fb555e7c2cf1f06daf1f1521e03fd214b47d0bfa6402e80cc98ecfbe5f3c6c1da07b969349cac77732965383bdc3a7c0949484471c3f1872a2e46c4b4c41c6d4acafa5cadb3a46e706526a4cc84c3584396a8312c9d1a645167326187fec385210f58999139a34fffe6da6a243554692b19be4619059afc9513e4f2b4780813273e110130a0cb6c8b939e39d190c1151e62d7bb32fcf4e38e4d8e8982ce3b0ccb013bba816e5664a2f05d29ee2217d83ffda555180bd954a8638b5867fd6c39c02f46731e114231c259dcfb50aafaaacd43e982f1021b0f89a2614cab6305c7d6f52d1d985e3176d458ceb6c99550ed82f268c5b132fff38581a4b6056e695b6d820c0347e2a18435e521be84ee81f97ec08fd71925ae9e83890bb9c2b0e6b3cb82a0761cbcf83202e913cf5c41fdbda8cd9dd93294ba5498ea1948ab57407b7d8ba0b2a15e66cdad09af162d4b9de1cd7c448133aa49ee81acf920950cbf387e22dd8fcbbd4232c3b1411381b4c5ad2b8fde1589cd465216a1404d4f6c1a56a06267d3160c1d4158a2b9c85143990c890d0bf17c12c59144a3ac733b8c33c80eae1ef160c60b7adf773d6b036902ec8e9e3222ad93558f82d23a5987a54a9875e416af66e9275bbb8571e823c6163f58a64588ac8832c4dd32d0445b9565b00cef0136f07323fa61cfe81d19291b50168d13864262262634ba4e8a3ce7de5554a4641f3d6ed249f9cac21689352a475003af63f88ade83204621204019566f40b0971e326f0a416055c96cf80bf65ca1b6590ceb84787aff5402b4a389f8012c362e685d69c33a0683466761597f99e8cfd942c15febb08009eb4e9ec1c3c5662d65f88b460fd5b1d7354192dd8fa1ca1d62939b989daa012a2d60c325df79e07806b2730ff26c8e62513003319cf2353137679da61f59ab3f9f43891e577e44a47818a9ff5f4f5940696bbe379860465e66e2ff7922b61bac310a33d314d48b8ed174b924155b0cd0f2421cc29857de3c5a60534c11eabff2b897430189010a419d6031a0736f005b6bb73c4faa8061ed1600723da649ac3fb963859ebbbe6083b6e6925fa7457c145743b148b76358714a0271c7ae73f4ba0c051db5f3eb6557b373edb7006fb26b21626de82220e98d514c5519e1609f64873239c749acd737e2a3fd16fe5b44af656d5939b3a9852328d98d52642da009b04f41d2c711169b52ce267914877afc48ae2aeb1196d2ab7a35d3a861aa5c044315d94ed1fd6a18c8112c11a09f93e57bbdcf74ea126ada981c1fa1ffdefd9d28f1bd09e2b44754139a7f8f89685fd40a2afa1458b01b7b3dc26537b23e54754613aee9e09f022302b6b6c00c57561e97b5b40944b7da7bd585aad41627f6c1bf7f45ef507100a266a9895df44b01f944187fb84aadd8d83bab2ecc0629f2d56ac46f32e241b6320e554c8ebff1ae87c981637a0c51ce973b6481d6433fdae07961ab2ecc03454417dd83133666ef1b2f0838522fa3fb1741e6a0b8e33a56096029a6d5340eca3dbd14a047d6244d09931c1cac38b4b472e3d7e5585a032ab058914ecaeeccf0e2c8ced40a2f5c538239cc7761b6bf6448ca27bd09bd99987e21d5e3ec7c08ebcb3f7ea2eb8785c72388e2263b96b07036849d87a272b132ce2ad4d42977d0fea2c51507627bcae4f3fe633a59d350e981541d8af639ba91cb8804ba0279e63e37dd7fdef794da37322c3349cac42f641257f19b2691a740a23d38f8db1925c9b08619aabdaf3daf070e6062e83e02e34e17b7d67813e7a2dfe7af090edf0a28c4e28b822e514fa90d9d69b409a25577c1c108b75740892b67fff6af0cbd85ccb3bad6af7260ad4785d3f593d0093d06fe77fa95185249e849093e684397d89c719274178e0f98f4e0ba3da365e71d2f0020c8712a5ecb8248d76b394ca9279222eff9e460781621fba60997e3e7e3a5e6724de9d28b372f02cbe86242888882af19ba3afee568db853942dbe433564a7709fce94b0ec40e173c7d3d6458ba88ba9e7e03668bad8bdeec3b31cfd99795305e9530e1e54f3f377924057f71e2cae8abf58af79c289c95e142106ebe3207ffe907c3273425900152afa4a8d8c4c6476268c89070f260a71c84447e7c290ec6c96fff676a5b94083d52769f90a646819595d2bc7c4c3daf3ca24c9e1bb917a2aa573b20b05cacab44c325f5cf4437ace17fa79081f3cfc0a5291f9a3809890588a8a9f680c1934aea9cb7918a8451f14f58608458017d1da45818d99b51524cf54e631caf060fb379d662916840a2adbb564f620bf2298c3654c2e407fb36088ff9e3a75a233a022074e343e9d5bc2326a726401a4c8caee74639eb4625e2d3980453767812f0350c1192de2e57403819ab42f001cdd81b46cc9d7c332def4390bad391d497082b9fa3c94610ea78befbff28d52e92d74ab383eb86c0fa8a74eb8e8f5be3b6d577a720c7eaea6f993f2638f65f98783383c3953f6de849a0d2bd0e3e58449f95965244ea40d22eeab2da1965a72541ac8b906f8815680763d7f3d4cf3349b41742553650f6f1acc657d73f2016b909cb4e9b96577145e841afabb584103973d522bdbbb5cedd377dd9762290065f2664e08b98028559c8771ad4783900c3f669e28690926b5826a4cf18ef6653cfee312feb965bd5030ee4f99879c9ddef37eab485475e6d4d0a772326d986bbbe5ab3df0d6e74e53e05a5676b358da8f5be41eab6c33c3a36daf3e805aec729c86d37e09ed8ccbd66c7e71d86c2c0ebe6d6237228e7656e5ad1a8ded2ab50be655dca5da572b320d6ed2d708a5a0501c0dd5c3ab59a64802c7fa83fd8db8a533987fd6996ae4aba0d9b1d405d0063d1a8f0d03f66ff1c2d55579050be7c36b1d0cf63f564ba72508c3c019185ca4c1dd4d47cea632a70499c092103ae1d8db120eaa35dd134b143119b3a6d5d92e54c196d48801e2694597a9e9526cac5833bdc589519ab709179eb7193d956719fd9d67121d356e39ee9d6e22693ade23af356e346e6adc4293db9300ef0b1dc929b930c08db6232f4df4fcfa78525ea47f65e4c0850d3e5ad0c60b76bea12b4ce1bbe9c8e224bbef6fe5d51e7dd6f332aba5e6cb4fbd65954bda9a5c2174deb9876f5823e28e8d4c9a910b074f8839939df59cada1b6e33064c471ebde1a3b843fbfa8a0324faf93f3c93b70b896833bb498f9fd001615a420c1939857083c0984f68e615e083b7379b53bf47c865da45ef472b1345275167d3f791e150e1f992e2ff28f8d5f467bf1d4a5f9be8342b4b7991b8af46245a4d84dbb6ea12654bfc51ce058fe2a1ad1e8f6d9c78468ad8c62e50e2cb1c4e5704ef0d091e29a44275aa2c6d068973f2a2cfc2ff0b4ed1f92b3da177da2b8ce91b227a4deb29fa4f1573f167e37ace946affa74ae6dcc478e063b622251f6072e690a66834bcbec79823f6dbc01800e51a1ea285f936059f3d47b7fb53464dd8e03878afd501c77397eed317a2e270371959a838052396196ea52501a38a62db432bb74b54a6719332c4cba889e44ba0bf0166ae723eb9418d9bd7c5a328e662052b70787e7cf2168026b0e99cfed7e48e81a60acb2245b83d5e841e5b3cdc22c5c650c7b098057b0eefd2e6ef1c06e5c0f89fb137a0e357cb3c0141f3f220461d7a6b2f3091b719ab4ffaaecbd929a09270903090b0afcca5aab36229cac638d9724daaab3634b639794eb52ec41e43a3bb4382f5375e0717531a53c088cdf5f154195dacda6964bb3183549f3c8f165b855167a0122eb751090d9a7ab46897c17a575ad7592a0147b6c68fb6255c4367a71aeca44257a5e1ec8b0bb2e733a103f52acc49b7f62fa559086d50c8f91a596f14fd53405adf9c50c0d0459b95faba6ea822f93ffa6661168bf920e2e4294e3239ebc5fb9acea39c48dd9e89a88c18780ac013e60ccd0918980b50fd68ffba0c1f273ef1fe214967fc3349a4e34f15fe030068e0ee924fc035478af2e445849fe9b7f6f09e5b809e8451cea1e0cf9eb0a45a4b95c80afe54aa883fc7ac5b237526b478c9c0ed8d8fc4c0509dae052a27e29fe167181c1568e934e979e86a8bdecf6fdf9a225af12fa5d0cfcb3b375e078f48df60ae4d70a6b089fcd4284342e59125b727bea4d3bdf47392364be523e6e5ee74bf4bc77a7cfac10690037a6c78828a8e4a0fc3998bdd630114e5085aed20cc4e60178368934d4849e13afadc1aa558fb8208a017090a8f0949a0cfdf9b08fd28b5f06dc3e13006645ccb4b7d36c2493c977873b7051a7ad1d669daf0e15c25842504bb50046f1928fb9fa1ecafbe55cfe1ca782453c00c286c7ea4b6be15a975949b54751c2f1dd03428b9af5650807409d27ce5a4fd8162a89d8db7620cc26c03cd80540b2f3b19f5c12232f011cdadcdb5907a8779506ec5d171f08ab53b3d077c1c734b71c2abb3e98c605a824f31de658dde1b42e263f3b3d267d3c66bfb322b529cfc2c676a536d87cbe9931d183e13deb15315cef03b3f552e12eb20830b26aadc98ba0b5a76732b2afc035d3a3a61e1a65553a809bef118f69f8ac720242003a36af11a0c9de82fdba21b4d5dc15a995416f2341709ea8c9d22432662842c1542887a01cee9ffd9c5b3ab796a087317e18f6c5d662a1f7136a65d90a46642e4048daa9639c653c462fc256c239fdc62eb20cbe72f9d3de09488ca242b0021c5d65417bcb2743b8a27ff7203a39c94ec8253a37867656800443974b89581bdce6253778b37d6c740cfac1b70f25a07721c4952f38411cdf6755883b85061154963e3e7fc5201fd9e4484ad10311a559c154d0fee52ba49bbecaddbee9d012c86736b7bfa405db025d7559edf63c294fb0945565d285b9cf8f2dc755c93099fe3719e9e358e7637b19243b1df69832924045e078aaf2285dbaba23c703d6dce74cae210e9e2d68348eab0471dd648e7c53dea48d71ebc45bd4f1109d0c02bd9633dbb64e5e8d2e845b72d48731d8c2e3e3bdb14cebb8071dce59d839536020fd4ec604f1257c887898623da56f407ed64d43b55b375c0aee6a1d36e7451422a537124e3ea5594edf5a21e5827478950a83fb822c27acd84395ecc9a75e862399aa0ca5aa0e7aa3871a280238958f2e9ec451429fd1cbd4982afea7cc3c08d242e47a9a2588d895dbb92351b18e96f4d31f1d08f086fd11a24ee221d17810ecb6607cc63e08020ebfa64c245121c17690fdea26095a56688d9fc4f894f7274a3a7130eec26c8d2204dea4abaca36aa9fc49ae9271b07d6eb4ba0afb708e2a1e82414a32a665d8ae3d8ead0fcdbd472273fc383b697998b27d1a027df9c0acc64b2ba38a818b2938e003d163b243740b136960f52024018a9c0372820406ec096660cf21b1241c1ed6e34f59623b6602f78672483e9e43eea20b471a86786c0badea4265d25bd95c9573b14f965344250054e879965076b69d946155cbfa9a54b2519fc85e967ed51157615090501c07438eb7ca13f9935f0184fdbe4695e312a66817f977c130339381e84a12eefda956bd609ae389b9c47a4b249582d62e804a8990c621cdecae1db31a3f1df12380fb2defd8de6d001ef037529a8ee95b517c323224fb6f43b01ff60b1bbbdc587f3801ad64a4922409641816db4fb3a10967d274249a86fb3eb87dbb23daad72e7f63e2b8481b6827d2486d745e72106108e8db0418ecb638d186089b87a6a417a1762b0f73dd96a282b2ac87721bf015b914d603443df621d4aa172ce1a14140b828ae118dfd8870d7e13f6d428ff6ccf6684c63c7e20077047da6b3460e0e2a913688f7b7500c96b1c160a69ba239394cf9e3f3f8310219618649caabf6f1e51cb3ceb62d72ad16fe98245a2d400441b65b86d17e898f4cc6a54cb91f5f489108ec26dbc49b3bd40d58df68905b25d9ae1632600b6b06802660d01612072308414a251facea9684901d3956432007a9f81d94e2a5187eb9c138cf6e23ab6c4980a9454d62fb8c6b4301c74677df6faced0b31ee5c27e2a14e14b3efea0e17c066c583c810838253329425ac0ca22aee261ee59531634a4ffdf1ddf177a8bd94efe027b6740b7af05b1fb12d2f7c2784ee5eaa3b10f9e8805019c2413aa30e4fcff0056833619477cbe55840d9eb3442fc4a429d6e778c9f7ca1e14d2fb74f7c67fee4e52b85bfdd3d17e44db734743a8fb666c97896d6802003042aea136a93c9efc2fecf371b9abec1305ea987e18376ba5677b5e4855be0d115ef18692641a865102813dac9a52320887cef3693781a7792d7080e5733179be5841477e7819d4655853076c8496c5d53b5a4e6fc01ea3c30382b1f816c5ddce5d280dc253e0502a49eba0813472e1ff73ce2cb8fbaad5c78e6dfb69e1dcf6bd6f9e4275177d66024a4fa12b8b06ba06960126f8565684d64c79114e38feb792d11d9563193ce7b169b7f9596022763b1b02207e7a63953d1810b205c2c5ebc03e0ca62c0391b00378ff9832743474f95750cbd1039326b349407ee3bbb1eb272b144af991b8e83e08113e97aa8ab83bbe6d1ec35242e0014c66d44850657b6565cec88c3540e81d3e81c246135a43a908953043cd81a7fe9a681dc6a5650adf351637c6f58e7a4bdba3edc2eb5c4c324f4de29a78ac04079d59b88ce9e995d23f0976beb4e0e014cb85cc3c55a8155e2615119497e9d6ff07f064839186610ae56585b95aa852948f16458018fbfd703b99175c96e3c196c503b244c71a225323b965f38d1c89292117453d238903996df148235fa4585a9ccdc2038e0aada80c7d46c5c5e4b52661c803cea2de1ca161cc6b2a2b8503aa71c43a5a68f7263466bbb14f0c3222aceb85b2fe30c449eae6679b252b140cf496b7a37389e86a6653654c0bb8bcfe18e1fd481daf92ffc508029dc8b72df456e74d08f0052b4d1d726d24d10552144157122d606c794a5942c570ea9ac760fc0544f305ddda099446be67a599f84f8dcae5048c103dba2069523540e024900068c9a782122fbd71074f338598d4768dfe0d1993fef737767e98631c6419cc6d92d3ce2dcda47a8a8e9f67ccc2fad10e4dc7a92cd3700d3adc4e6e72ca1997448b08ce59a8d70b781ef020498c801cae43a98002716aca7f9ac555a650a103d5893fd6aeb755bcb4af610ecafcd28f055267e1d063e8f3aaa83074e6d2447925f4da58282d166f5e134e9990d9480ba3b0a082783eb0a5c8ba824c75429bb350ddaa6e80ac4ed1b2222e41510107cc8308dbd149d32256e62454c81482a27740e83e2a31d52ae2757c0f842e2a7643829950e0522e46de911b58c9f1d52daa6e094dd4ff03a5c550cc70b548637967b32cfd5a21fc72a72866ff5b86f9f933bec6d908574f16eceb0ec4a8c2dbaa274a9a91a2451397dc4cabec1f7f6ec0a121250ed9e066918c5c59808c440489411d029a7f50785eae74514a85b9d93227c9b639432934ccf8d6aec8d1cb56dfb59a9b2578ea5f5a944c2d57219858735660bfc41b60672b590d89e0ba9fc75f61c368f846253f9f59d92e3801c3b4fed54404a8b1e78bb4626d0a116d6d8097592882d1fbaf95b3adc2b4753f1d85a9e7cec730d35f5037c23955125968bc1b4c5233c859602fd27f373ed6aa18529784e1febc019626436ead44bc4974ad8bd57e8434e4cd179f25924cb57e210ee22a2f2d57447cb1d229707de8a366c7e13bfb4efa22ed21d446727b23c119e1af17e210a14e7cd343db71eda8aa63bc91d3f0c6a00ea5bdb1c4320ea43c97e17c304c37ec4f63b192c6e84e5f04f665ae5ea35508b1a6dfa870fdc67b62cfa5976f2549de1685d6c080531f872c3a321fcaf30037925840a4feb754e0270d8dfbaf9b47504f98c060d4029611d87db9796d20002a446b455af049440ba7e2be2739c7b53b09b9f13013c1ceb8624009e3c7c9f1b38cc39c4bb0e31d6edeb9cb48ea9b9546795838f5339142a53d428440208be9bd4454c1124e43c1ace79dba1f2c079c3eccc98d47f4532bc33e4439d852f1b2045b8d55b1191ef1a885f584cc91164fd9d211220f99e3881b2025c0a37a4cd6307adccbab8c9aa68871cb6a2cbba81f66a0c64d2e7cccaa16355dc962352ca5111e70daf3bfaee3b1daace269c6a6b414919f5e6e4cf59eb532c0ff41eccb4943610ac45a8bada5fab97109cf15d0349016a9fc117091bd3d3b45dbc09f3f275f4aac1c237755a7f01e86c6216a799220187420e51e1ef3074af7c410ccd1f1507ea6de6c73d73ab04b4ad5bd613a83030eca6b1ba2c57b0bf17ccf1a8629191ebca61a572a9ac5faffb7b3e31048055d03e472cebf7a94d89f946adc57522bdd666f97072155b9f9ecc91b60270bf2b331588d53c46f3f248c202cc827d1fad77bf21f2a838799c09e23b76b8f746f74fdd8b4910f8bad02c12d561f939c81c30a9b2c9d855296037b49172ffe4227686f8440fdb1ab84bb6794cddaca6e661653d6da17576e66e8985f719f38a07d4e075f2cf04412d47f0fbf9d646a98a5ad8bc51b18c548b9168944d9943d48e56e39696fbfa030910ffc310413b30d4386ff43c97aaad3b3f5b2c45c51ef142a66aa312a59c4b707a9b23f369dfc6736e42eec449696c8d574fd71e871d894fe58c27296a14a92bce54e5ee8c561319ff0b157bd28f4941019f14a6432b8571f5d6a188dbcdb1fed6de5a9b580c6bfc1c5c5386db42177023218d00af77072b1685911181ddeedc3015db4f9f4c813e2da4fff839f9aab6c399ed825edb12c7f532e9c2ee7d01b903b5c4af1aca3f9daaf83904eda8bfef08a067b033552ea1a297c7694033ef66b9f16cf2d974800cb040160532b16f21901d332927c6956d007d8fc07364b43ff18c24a589e528a6baf7bab14d28c12cfac645a44822088b9f42437079339bf396ac99d243132c51636d1af2a32c8880ea44396b985c22d4598aae6c04fb15778cee4ddb3bf7912cc50061608184266386125d3c24eca62f65c100b03ee4689f91e8f2d00b13ef8b846d90d2aa816d53a7d68618a6e81bd12c15ff2c11e73e910c34019b186b501c5a626b6f6820d4edf2df18d47f5c9e285b6422368f127b260f521d382c072aae3f8fde297a1e4675b4dbe13fa22103d1700035090758b1b846cd542dd084b29eae199d7b7cee8f0b89463db6f2ca55ab73734a4caf4427686e0c9d4261e83518936057074a58c0a0164f8183e3b6f0a15c71813548444a734417b3c1fab3c3d81f6b999b2ca17bd0cbaad00a3d5439e310197b5413612db3a480795c18f37c6efe446d4467c2df93e009cac42d016a7299e9a44984c4554baf7a5c8c28e8e548dda168f11926ca0a006dd2a03559b1125b1b5ae8530282a9546157a585b774c903a1c571deecd21c7bbd0944d038ed5cf501270b075fd5c5704f8c21c3b1bd035886fa5ce114498904255a1c7fa71009fce71968e41aa5c855f76e15656e48cf344fc0cef36c63b2b4a3c6ecbf5c0b512bbd2112e59af6645f3e2e8d12bbdc06e2f84cd175e9725336ad5dbed0be83335db7ecae1c3f0ff8af97083ac3af87782b8a9ae51ec7e5f92f3ba391cd3c370ab8f6dcc45d5a3d11826ee0ad57ebc7f987e74581096ac478502551ed6bd938c3cdb9bd4fdbfc63060310129ba2279feff68aa03d5f1e5095b474efbc4ce865aa5c4de56e52a958bccf414b3012108e6f0b5828e8962bdd0a0e3500b606efb66405132ada575c3c83a99f414da04132080d7ec7bc1b76b1d986bd10f933885262d4db8abbb2a1a83e6f3bdf8da501170e48b04f044129d48aad20059f4fc0c8482e180223e5d8f8207c3c0a3f9c3430f8c5e34dad24289b78d255b175b6db6dcd0a488b5ad2ef20f031a75eccf367c69b55d1ef43383d4b42b0cdd31ec63005553d6dab10e020f11297d0107f5f959d710caa3ee413199a26f27d32ac62278d686ab2136522683883c16f2cb486083a483277a78e57145a4a457ad401d229fe07b6a7a9f8dbaffdcc0d8da506c683e259709b20a904fac8d4d157140e4fec78e0d0dcc73110afd91ede0896b1aed0b9de3b39e1f02d38d6446cf5aad21c906d8fad38da1e2d5d108bb68043941938eae3f880a3a579d2d03586b26bb07fc7e36f66788f9a1b0c9aab47b36f9f1670751a6b83ce5108ec6ff5057615a1dd71398a94cd911d75105b54625a5bdf7e61f85497ab74cadb36bfa7117ec92fa4a1369b6dacd54a6c3e3984569cc78883d0034e2d5f414474202661bdd69e32d05a4494f9d840d66bf93d955859c7afb573f7c76dbaba7e24f635fa7688778a8aac614440708bee0687491e09edf4c84d39ab2d9d499a6e99e51448f3b984d55e04d6e7995fb3b4780928939988d0558034e07c7948ed3ad5a9d0e6697c187900f6d5ca31938d3e43e3703730caf6581643379523bcafa46eb769ace6220c0850d4ceb92c59f7a6e5698843d44abe3e7cec15a87b04e1dea88effb5b622a781e5b6bab9b41899368a32a0d70e8ff1c4b111124082a83eee899cce1573ce77c68c53023ce0f778514a157c57fabdb14fb4029cf7a51004aab11fbbda64d43490186b6a7a39a13092f0c7164c07dc62d7c6b2042a72a2f76ed0f4232f85882c924030f52922d1e098d675e0784920c2c2a17109f15eca7a3399155c144514149ec073ec5050f7da54fa60c693f86733d22052c1c53b3ce1acb19722969253b30884b8062c9f3101864efc1b867ac65aa695bb0243f12797e47fdee8c3f9397fb9e087b3bb1cd5c961bd1eb3ee5cfb9825a3a369933e19301a302e9d00d2be323d1aafc48eac0e2ddaf2f3fcebb63a14981621639df134f294c41b6dd929f2a75dae22d93030c8c9bbc077196635c655e51dd62fe0e3c9cbee4607d4de2bf9675c00398b98c41894a316f5a01ccb7b616f68259a8c6a4b81491ce76f39c60445703342a3a5be2af253c9da5420995c0596ac43178a9d678c3392e9e9ea9440e36ee179a4722ccc5937760d5dcb4f1a6a61a0a4c8bee4906ca1a672614ef5c97f052b2b5f103aa449560029ad49f71ee16f685853d2d0b4f0287e8986b6b3bcfa8cd2902b020dd86933ba2c6a40a8fcb08758dba3c6acc881efa9aae21860ec700b0b7b51ca51df167a5fddabc6154bd7c877f4d2277ce854701476fb7dce8410660ecc772a626f93d22e40612c5152251e532fe909c15095e34530a4a2f84386a625c232241b100662f813714c1120fa9ee8c569c43197ce76086a4d0e1b238fe3521ed788178091f939f8b57ff0fd83e86da8f8941011d7e7897d1c17fcf0066ac8180200e7c7a9c7b4838a847e527b3c86c01bb2d1888c2e504749521097d514e830b614a69576220f19464d388e0342b2540a753bf29245363fbe0020a0a4d053d805ef0efd42b7cbb00712c23921d9db88bd7f5388520fa6b960094cc775cbd9271a2d47c5e312c8f99ca1f894c42a2862cce10f59a2b1b6277d99688c488409321e915ac333f2d5cf80eee5e115d06b8cae9ca349af67e0967acbcd21ee27192363f77a868642fdbf2bf6748060104ab0530e0fdc4fb0ee362a471ab2f42c6008dde08e2151b4582ae24e15b416bc310b8b8b8c25fa96aaca0d6d2bb8a03da47d594ed8b91c8c647fd3b3499230b415a2551222936c1ec8ef08d034e23e092b70e732930957661d7eda88c103f6c25963f08dbea0984246966bbedd523bbc297bcba701f79f977536cfc44bac58cc289997295c31ae76c5ce2b9b628bd18c0daa241f7cb881a9dc2e331128ef27a2e63814a924589a7ef256b357250221bb62fac84f877ad58c29a2a1d14dba7bf031f849d2cc8e19bb81398482fb4a9d980d8e62e51f33eb490b9a42ebe99494e07bafaa782744adadafc5345ca849c02bf125a8e5c2cd64d49db632f90da29e46bbadc598abc800b4ca89fedaa9620cf1aa7da29b50836db8e78fdca81d3cde3bbca6ceed84b671b58032216feb351c8516a2161a92db4e321a098af5965812c1876a1c9981dff58ffe85d29f9a99409964c88f28492718127f67143b11cdfb2b24a3e0cef4d6f71d8f622fdb7d5ed84893340f4746b267d5456c7189b4852389f492249a34400bcd4109d87ebba25aa4cc88c439097e61a20d98a4a9a2651973f741cfe8f1b96d80a615a953d53b73c3806ff1b64cc041315f537721afa27dd80525beef775d398dc498e3ed6be9466f2d882752da844e7fdb2d4b298dcbaae8f06a199d9bfb03ac0bc2d2d1478b62ca2f639f3ec3036c9f3f3a2ce2e42c24ae468a721e9cf1219b6652ac9dcddb4a5d49236d42d27f91e8c5b8428a644aeb817ceb62fb81d536bc36a211b67fcb2d87b0c106bde763ffdda632cbe663807583ba76aed092d122fb53aa9f4057591641ffe86a9ec77a398333d11830c9b031aeb32a6524a8630829238de6f876f669bcaa53f6226dead0785fb72443cf60d4291ca11bbce29e3b8f8a63e136668046a3f64091c99da7859569c14e92723cf41a3d660b83986a4717ff152042f647178396649adf63e388888588f03d5ae4fc12019b28ee3f457632c0484dfe2af780413524920d9910dec9c8cb038f93ab3930c4e3840349a312e9114bccfd461839f3786cdf9778914246c7f0cd9670f4c3b3c55799090ff0828b374114ea67cde9b30b456d67c7135b18102f6a02763a2e67bb04c889f4efcd68c24af8ffb10b2c9c75fb7b2be2cb1fe677ae97bba20a81b794ec6742298f99f447cb7e6ed9254d968d5c6cc3449f15eb285e09f828a7331dd1ab03f21552e30789d2770be566ec9d09322872d535d808197948d24d450001cc65c7fc10c81a5f30a432097e97d02398c59d6964bbd4a405497c853ff2b6be4708a3a0d455bcd72ed83c1ec26eee0077cc26f5c134ad90347b73e224eb034d4c8330f4b21dff0561aca719f204615e595458c35c057e52c4b44cbab61e0c4533d3b812a860cde7928aedaa943526c8d33782934f5ca8f60ab712464317df8af039b80d56859b9dcb06b1a808464c0e1863fee1c85be8736a0dbf5b6027bce141e4a5f17778bb29954f488508452f32a964b502a94dd45e3c3faa5c842830c7655b91eee8f9ec328ac2a532ea0f5f4a71172b3be24bb9a66fcfb0039dd1fa2dce471152227b825c24fed010cf819d10ebdc2c63540ba6e4849205790b0678c26781bd3e58f01b98028f9145a5998b58e1953113c5d4a69f4787d6b7f43233f7996074f7909251535696548aa4d677509ea4a4af1ca33044d00e1c8ac5d7316c97fa17ea0767d85cafd92a192e5f4606b02f18184b987531dc119302112f32f1612efe87c89bb61011cd0e7687ba5ac05ecb2aa00d681500f7bce7df99d64a9739441e1d15821b6140ff236d117dabef50fb26dc97c2a54a781d22d95edfda141650b21b88cec0b43a643ac20fce497323959e6b1503f43a8223311a5c1904fb1d2cab39563ec876056513ad473484435ccb5ec7f9e050affb3663688075b61aadb7d95e531808506f4216c13f4d61023b07f8f9485b7723d4641e4e603ac76da68f9b5561f80c988d15ef82e48542cae22a0e29a09c320df9e72dc365a2bc974ab6fda8988fcb9051a2603ebf7696b1621bbabbb401158eb47d3daecf323f67dfbcaec7c12166ae5bfa01903880242e0edf37e314efe5263a76acecb9f10d1a1758e47f375078fa30581e2247405f4b59676ba6469df95be6a46736be96a05f8323c28d2538489d3e1d3dae9be744c3f04e42d2d73d9d6c42652a704440b165c23a5f1d6e1dba1a2614619ac723746f28637dcec5ae65ba8131a1ed17a9ed299a7edda244689d16176c1728b3c12b74fdad76e184ebd9a92c21c74d870982cbd024219e6905094348859393050a4e8ded7cc076038b9273db38c89f4c6b10d06ad1aca7e3c9b5450b9915b4840dab39ecb46a56358ea00d68b4a91a539942eafc6048d580c558be15dd0f4f32e71c165e1b65eb379eb54048a2474453d6b209fab25dcad54a81c4ce09b8b6305e057f85948cc61e675269c41b11b6c7297fe0bab783b3a6f39099c6a326862396b4769574b01f39c1261ac492ead7ba83dae8309fceb810d4239bb856d0f5bc348224584799cc683cc8d1115097f6cea2ed3afd7bba107de437274f6ec91fbe6b81188c8ace06ed150fd2a077970c1939f595ad2d08313b889466a11256490c2f374a65d1744e52d326c88807819f0f391301b0a1ad319cb50ba0373571f8cc199a6d6e660d07c91eb700932a0cd5c6da53ac510a81485b82aeb592ab93d7f25e1e310d4b12e6e85173567a402034f93468a4efb69bd5470d02cd7f08b5cb8257952a4b8ab9cb73256d38c2ea03d8dff1196f87c3f38134b2cebad23d550899588a53258a25b5bf5c263f212c2522fc902c92741235e1d869a669dc0b131943a23c02ec3884091a4d6d4b9d77b10ba16179b0291fb6b46082269140f8502bfd898c5137149f637c4695a846ca1fe81a13de887349b41c23bdbfaf1c5534c8455db5f4efe2281248f31bab3bcda0cd1636bbc7e348e9797aeed6637e401207139d602d1f2b456b67f1322b4fd6210187895c0dc36c9a8825c9e0a627d2d82dbc4fb9dfaebc75ac4f98f2cf6954559ff0f6d5361fe1893084e62bf4216d009f56224e03f66d42b2d14700127e6ce7b1f59f2d3cdbee0f5b40f4e50dc93feba7e2372bff9cecfe5d2afc953ff0bffc4f7413f7c562d127f6e8d031e29a8acd6b59950a8f55a28783b61b5c7a04a3e6a26837cba575ec91d9422aead864a5082e3c50ab2b03ac1300f84a691b2bba58a028ac676b6532dadf75328f05da8e1f14861be9f019e882ddcfe6aff4d0363f58412f9ff08a6f2d61b1817125307a5d6a960dd99fb582fbc43abb7a199442439b58491d184d91b34552557914eb7ca80e70dfcc58780caf097f868b687fbf66adea1c1a7db1c40b02565ba5ce45f17010fa2476110414afea5f5d98d521b98a863f154cdf79a4c29b0aa016ada3115053e11563a6e5c22bfb994e829fbfd0c1b85ca67ba70634fb372fb5b11804351a05e3d2d70621c5d835c707e0ea72f79afcef8001dce083ff950a835272a1481349a002ced76a89ad23436974cd7a5519dcfb0504054832c2e76f2270ff30a5524970ccfeb54d39fea0c7ad36d3a867fa7002554f6d5c6b53d538ac5206ca094554dd2950660630899a01978781b61988d69f8f9425e300f924ab81bb7516c23f67b9ba42bd237684e1036825eccda605a886665183dfb9949b6d816aebcf05e1233e69995c741db66a8f4eb0f97a388eb302d06e69c7747d0248d7cbfa4d6aefad97be69c842a809ef971d4095a5e3418bdaac021496860db0e6b844594d09165c602e485a2c7a3ee6dabfb1401f5c318aadc74a476a91d78449a6ce5f292b39eeebbdd9b6523440f6dfa4ac5305280e0916bd4323130508d499bb10e6dc4db95d4bc78ea752983a9ba91a52eac104edb073e487bae891ded23a1622e6eac3935b561fd2a84351dce2de4fe02d0f4ded59f09ee7ed967e5070158ed88c0771f8e9584ab82b11c5563d044d1cfeb37b0726996e26900a185edd68f3375070423fa7b839293de50b91b8b3be873e0592916fe65512bb6f5c38707e38e60dcd9dd0c5bd0e8d9f675c2ef5e5120a2cbfd9d70be7cfa18085371ee5d48d5e4f6c0d332fa68f14d168b19bf0b7cc5792688b87f16d50a18306a11762cb0c4a7884329472b4ad1683f6b154e3e912be036862680c2454938dc7504a9f75a96dd37f4f6d8de83f7047ba888fd0ed4c7b67d3a8ec69944399842e35eb57b476f2e0d6493ea4845bb238310f1b7c5bd749c8443b3e37135a76cae8736468f4789584892528afd8f58bf86b187060e345e894fd5ce85fa372c50a164ffceef5f1b0d292c83a146b66a5853f5858ee73cb53d9d395d2c3ab12731d5db8e5893a3ceb05afec32fbb4907692036a41b51b1b631b85c6cfd63c1ff386b15352b7d2922cdfe8515ba99d2977c8994ffb6363cb183c54cbbb259e8212eef339f6c0a11feacf31d0f3140dcae3a8e50f210dda7674d423bce97443af64d8d6e6f987cf5b872e6039609ec4a0327120330c3d7816ff322f4d7c7c3930f15c82ce76998424d02f2a9208a2ac3a51b875c423d6d0c0feafd945d18597091b80e676221743aae7a01c96c56996dd5549820593514dfb56c5f6b962cf9226ebd27861ecfd10884155f11754517c385d3793aa70741bd1806d3debd435858896363106137b152bc8768d4d8340664ccfb599052088ecc71f7a8ba75c7e76e55b9d22d8124c922f6eaf7d0dcfe40d1d1fcf48f31c897bdddc89d2cfbd5557b169443ca94cb3de7f9f23398fedcf470f5b69f851e04e84d84275fed0d0d388006b11cd459b41a68a0c4d81cee46bce8751fa1aae85673ede22662dfeccea0af182884c9490ec9610f263c45438eb16d20c7310da2518230bedb5a8f4840dd0f2e2ca7c02115689e579f658c992859454ba0cf4006796032ad7167374a72b999eb8b9b60050b36c32968c70ae5746519a7f32836171906e0be27e084880d0cd7feee9b802cfdeb046e06f8f233c63aca844f5abc07efc38de6d2044975116fa6a7b2693456ce9c543fac1618369b0c897cc3ade03cb0945c388c310de17336d4ff387069a60353fe90ab78f76880226e4784526a2eb17549d645e01f1648775df1e219eed16bb1c4aad36a974a472e0e3235f36476e455dcc2643f09b40341c9045349ad04b63c987ec690b242a30248f0c383bc4f1750e383f4c5b6c18390f0587ec0243dc66184f129942e109ce447ea6464aeef2295b6d30fde5c82781f988212e980460af4b5d70c8ebd3a994ce27211fa2c28ba58559e0e8b5aae9b8f11a708d6e384f5204e1b32e5e606633207deb6a3af91ed0e4c23fca8e170c4950aa3dc84bf0b3156144faec7fb4669d1810da8e98498dab79d1484cdf0db5d6db23b2138354972302905624a0af09ca5bbf265055db2ed8aa7184ea93d998a019087520f7a1101186cc492d0bb06ecefb0373af3e7e09a5c72d141911cc7f3d41d8b7666a70da26c8aae9a7db9dd43184b827372923038276943d20978006c0012c136ca53704e21f70bbaef9c7254b83112abb04b5f6a066da4aa3fa832d7c5c5fd80141a7ba44f52341ca643cd15f171a4dc0c88eb8b17bf97a2ac54081cbd1d149cdc2b60debab6cea48c6e1cfae5ab376f202fb0219d52dfd1c4bb5f1b748c44c48d1f5422712661a2d175e5b73d6d9921d09d1087429cb23184b013289552b3d580194e3cc34c019e854deb60b9fe402a424fb05fc174648d40130eff9811dd2d066bc5f09a6a502d70c550ba7162ec165caca60ae6b071758b944b7703765d0c3064d738af0ebe1b91e8161a578f4a46874cfa7e2f178b5ac2433a045c0925853120c3ccc597047ecca01f34bb721290131bc7566fbcf6d250a2abfe1b66beb85d7650adf70ee4735ce2e639b33629a02cea4990a279d880966dce8690ce1a455f1ea715e3c02a8c3faec3dd2c20d89b015bfbafc9059073d4c8111ab1f8ffa331d65ddb388125b61e5b60c57cb04bd0ded30b3d9e06676ddf36a39ee5ad0c1874316b79bd6b5ad9ab41ffd2a2fef38c592c8d1b27ee37ec6f9f82e16604426a1acadc4aef9d51c0b036f27b13f07d6de17002c71b44bd3abb78946d2ef552824280534aca65ba80d9d61ce090e4bff59c39f6c82d9df855ca1377023e0762d4ccaa58a6df7fc235c24a050d084ad3c025c775b36657b031696a06f78cadc00acde4ab14e036ad4263e10df4a550d30b42049eb28db209f942defd55c172818af85eb8005313ac2e9504c1a72460f8dd687123cafee86ec8f914cd6b3c1a83a8a5b006ca520bff37064f5229d530c59c5992db318e5af65b4ebb10178ee28256b740a30aaaf14bac5af5de7f2f5976a712556bb55384c59e2342bf1197e95ae35cd73e2b53f49e3534dda1f0156a2316f0e228f57f8104ff9a3c3c6d1e9f70d6268e49640b31e94f2d1f20ad15852bd1080387eac7056e7362818a5c0740fc71f3b6fd395532485a8d4094e63d604ac80226233e710c4079268df199f10bb672a816b692d028335a4ff4bd90cc1c045d378adaa0238739814762276cb389b3bb385662c355424d40996f228a580808d775f2ab33365caf4e8d4d90898310cec3215f2d2eb540914eb278d95afccdf16e440466a618e50f21fd08e8806c596baedba96b56c81d6c2c5315e9ad99e36491b7089930be876cd5e81c8718bf8f36fc70a548bf58a95078f3f79e4ef156698101a21bad016cdf8c50f445a9b3862b325e9c1156b9e60a1bb1b96118f9e1858511492bd18083713b47b502e42095397c60b25d96cc8b8bebd70ba425d63ebf4ff47788f4a82c03640ba87f2b85a58e67b8bfa09a39182a37ebbf48408e79f011a0882091b0e04b46ca1bc06e7071a9d5b09dce4b8aa6108ea975c6d2fb69f43f0fc05266d94e964d503765993819d8538e484da13b759afbe82388ace5f78a712c2c2c6f94040fe4258cdf754d71901cef4eac75d7540030de52790bac19c108340d77fa96e2efe0d933b1092406200e57db607feede7f3b6b8c8f9453ea93fa96ea891158fb2da811ace6387399816082f290505c3c09c45edae6ef9e227eeb1a77a5b1dd79233cfa7885618ba03ded3db2fec495e77d332d7ff2aeeaf62da28e8ea5ad36a45c4bffe7ea94fb4677b36fd0a1120a05764210d1cb0b9c33c4592af13d9088555541309100060e6ce7949cf2b357508956122bdebf7fc31c6120a448739e3f066372d5df01352ed3b2dd22a8badc45982a26ad59e9f40d3ea4057bf2ade48e929a77a608244ddc42837c548f7e4fd0c0b789d597c86bade766fe93d00cbb6fb8e2aaa01ecebe4df52d46576e1a2166a80153d78ef5437b4ae8ee906566fb3f7dd016eb68114c3234bc199e0ebac70eb815aa38a462be3048cc0336c954360da2ec8fece716a2b878450e31df582116079b112507e2c757baf8a9c9a8aee61905222010baa6e5ded02ed6077928992b0e8a92ea34109f1e82e2920726af74a986e5ce148b3d3ae67be5dd90d81594cbf3674dd71bb5166a441a2a442864a11525212b08ea31e3d04db05ae2a175c7887b5843226874d3c32d03dce5b88f67ee1c235b3b1391e47da184194426fb95f9637df1da6e23b35d14c8dc3d618cd1a86868afb1b915b69445148cb33eb85c758d93abad282405ebecbdfd7160ff690f8fa7ba50d420fe42a02334a35afd074e0ab3b470b8f2316c2612859ce29de21846f22e511a08021f7257ccbc89a566807438785ee416fd486422ed0e9ad23cbf79000202546c090a00d6c01d0866bda0180317675df6687c3a84250a8caba48f92869ee85d5ebaa31537ea9c320bef9d34c2e3d7695d52a799ece9c8443db62a8798dee00940846f39a64448b01d51b3c7718cb9d71e1ddb52b0091ae122801349e3f2bc0415b44b6821de1e93a1b773d658e5c40c4fc538eed22cc472174a320a4fa99b9e5e360e3f3bcd9f0d606f820e784d6ef2c3e6198b6219aa77e4176c2637e2e3248fa08d3a3a690930922bee860652f919489d669c1006f2559275a6642ac5cc1844f993a6a54af6417389ccd957f1541b688f6970735abcab44e7c12e76a0d22c530675a2b45f6f15666dd35d6f038ae07d253c2f7634de81be78468e363cc5e3f8b25abbda6130d13758381bc717aca623385e2f9eddc4236ffcfb4dc4d94cce2470b815181691348e846d226957769e84f2ed5fe062ed0fc08e082c59efdd86e91fbc365ca9e0ca8b54cf0c9287fac55ca93c693743c8927922cda51e7a2c357471b3ad3bffc6222c8083d8b197a0ae5b62443e92db898f2c66a416fd41b1135d88bc93a1344a8e8f6ba394c2834ed152eed97756aac39e4674e6e0ae75f44c885be9ee75bded3ee3aff2386e1c02846ac17b53b43ff6fc8737ed1c7b9b006be171d5f7219d3b2816b21b15c314c32b7084139e937daf6f6e276802c4ca338d31ccc758ae5b399305840b198ea48bf272887c0d2f6cda910933e76d438047a1ab3b9683d50c76389d4a0913bdaa183241785be7f1c9b0d0651a87501a99bee453e783d54c44cf15a0901e3af0c03c3e298624f35d0670cbde25bf1744a3a0764a55e6c1b4c6c4f6c2d431941c215797588265a287e063ea6b2be72b931851b6b37d9ecd4ed0e3458001e85edc8c9b250a423e14e1648387818c707c30f667aa57c20215023742cac00f622bfe5ea95d77a6730d1e93f3736d5a5e923d16b8cde9c5268306edff3e1be1b93911bf458062949dd5a95dcd0019760a169b6c2df882a4a0c5288bc0e5b24705c29a70913e5fa138c1580429de548182a3b83a1ce0cc7a428b1f1f7797df3f332d0bce48b96a75c25964c451123424bb007464f080ba60d7a303b964389504e24ac38c692714986a3dda2d8cc6a8470811b76809ebe926e47ae7f801b3954e10c716596b8b04363f570b84a3893eb2244fd3201592d30124befc6ff9306c5afad9ca1ef50d50e5dc9ccef573dc1876884e20d17013b4886ba7deb4fc68429c47b7c9f92a80d7e0aed3c666809bbe928c3b2a7771656e30aa573a4e3c3e1832090cf604220940903fc3f27cadf00b8b652360942920fdc01d3e03cffdd7801e956e3217f02880ae50a9e0752f8c2b6ab4e8ccb8786c6f005d0114620187ffe4bd902b01da72cb5db35ba96a381758cae58e0ec39163e042114bc51ee0147705216c49933be3844c7dea47c8cfeafe35b16b96918231b76ffa3a9d13cead6845ac04502eaf31d0d9454a8bcf60dcefa481a39367d3ca14dfa2c037adb061a49f3984489361a7b2f10aed0930d6702740481f416194ab0fb4b1080646605691fb20a9fa30081a178e23636266769cb3e57ed87bc7e589cdd81357a38dc371f71b4cde60039a721108a213e9b02b263addffd48d2c4fe269eb8f9dd6431de6fb9279f7a005217c3e66b2baf81271a8ffc756cf08482be174520bbbed792f1a61c3dc2682003382504a105efeab3418ef258a026ae97278d4fa566e61af97898a8136c644e3d3685537aa11c532f412b55734a4cf5a7a3d2b0daa06824498112c9d978fbe3d2c9cc084cb2fd27d0a4dd45143c944b8f823a42163f710007c312b405fa7cae985e11e6f7a02b030c355eb8503b96d150842b7402c08ad874e7357c31ec848ea114b346565c44f2e514722f063a318b32bcd3e4713863a83611c2776e8e6346a47c4a0573071403a331e3fa79026fc28730ccdaaf1c96f25a06453f7294ce6a03b5edee41cf63015db2090bc7fc19290aa518507c5b2404e3f2426a8f30ccc8ad61a644e47c72dd27bf6990b5cb632ff5b9372a89e48489c19a03f16d1c85078a0b2a6d9ca0a02ce0b81e7fd8c561b68013aa64961f48ff4ee6609cd8f062f5ac54f33a75b64d0dfc55383be214cd03f786bafb639ce791ad200908a5cf4b9a8c9d8d9dc4bd42dfa0376e955c77d0ab2d74f1ad07b8ab348aeedebf090a1b25ba51d0cfd2216ec21435b10e30f15863228a19d287287917ee4345b93e30bd6dba52199838e5ea1f1416960103d304fac5f54ff0fa814ccc23961141830c8278264acae8e0906b30f69c58deff3d8395113566b9a3df14e7d3c00ac037872654eafdb825c0c1898aa618273b2d0214016eeb4a92218d9fc44d336f0e9ae08a6748d2518628c44e1bb30d8a7a9fae153239dece4955d073a02173363d975c9a15416034531020f87f8da4475fecc36198e3a5c75c505af522a4414fd4ebdd26150a4cf1e60bd575252340d24d7c7e27c2fb889c10580330c1c1ca8cfb0c17ea460277a1a160bccc8043eeb5d66b097e685bcea43d6503cb9cec84dd874e578a0b548eae066efb62a0cfcb44020c5dffae2e233e58fd0a8347b30035930e5a43ac268f453d546a343e3aa040cf284cf6b5dfc71be8df2268a26308223f929bc8b95ddfb1719e383893cfab3ece556194c072a0b7c6a39581301e3f502f7a5978fe71edfdc89093c738902dc891c4572099edf2c13898a830cbc4f61916d2edb8772a073fbd3bb0e39d8123cd2f71de1748d9a1c42603661a2b4109a429bf74946545ccb2d2b6213251aad0f821aefd293276726880c739bfe372524721671d97cb70c43a25edfffbc30afc9fec2fc7386fe1d44f35a50d9986254dcc31580c039f2f86cfc3f23da483275a8249694918294e4618b0960c47da61a1976f3b09ea4ae3d127137763016f8527f3429c502e9e011ab2dc3c4173c0d32be0335c9dafa6e0ed1dc0960ae15d09d0ca2cb476e4070a300c0655452b3ad3a587bfcf71c66a6e8a025ff40b6cb6311f6a1a08edb5c4318efc0f7f0eb05436658899c12f159bb32254ce84c8f614a8d28bbe40271e3b28e06b31227bace692f565d2baa8692014534fa37defbda923bc13d98363fb27787b3a52ac810e76bcbcb7e521e63cc7cb866edc1756c4742d82553cc3863e040d4393d74d4740f89fc0ab30794b4ecaa1c66c53280302e741d24d86895800e205cc2d78ef5bb590e828178ddebb5e96c35885129c1a5ec6a946c15068901d0836b4998f2bf6b9a23f55c4e70afaaef0af2af075853e56fcb38af85c519f15fcad42beaed0d70a7f942a66f7b3131a94d425621b1c51fa54d444eee12f25571af2be41a0be3d3e70203cf57d56bbf57ee6fcfade2adf77e5d20d9f63be0675c12728daecae96041d39b31992d71bd094d195ec9a22e4c5f7a929bd34a760485f01a4bedac6dbb65e5bfed9cab7adbe602bf9a5fcec5736d9250b2f5b78d8eadf563fda5679d1867fa41ccec1c03ffb2235d68d5fbcbd2a1110fcb23953b290bd1a68dda6c9225f41895ce7c709bbd2d091581e06dea096ae1d95507dd8ac8b976e73c04c43d38f5ee6b5e09ad01430a716813783439f680aad8e21161d188cb2cea91843ba8e4d559f06f8e0da2126e015918966f1df0d1404a7553aaa75f10fc55132208bfa0b418f7f99952368cc67cebcce080421e118eace05fceff19606e6b9052c477959493b04c3439ed678ad3ccc74efb7da7a14bd8f9cbb09d32afddd4ad7a2bd8849c84cf76f8e86ae1e7d3e72e6e54fc42bcc6cb63e71da6ab525490326d8b9edd4349f562b602ab29c642cdce4a0fdfd6bc271ab82f2dc2a04f87119d6bc11b2bd81460704d1456439f4db8a85d3037c206b2fdbc68d59ec782edf4ce73827c76d63801388c103c7807391f6c0a334cb72fd30350ec3b73deae156ec640d6eb61dada28841d2a80ff44145b526a80d8880ed3c4ab9c947f12bb95e18a6ed8f9c2aa90a48ebe28e9027dc666c71220885f35f7b91a563a0965b50ccc3bf9bff9d8efc83dd366f2713833a0d1d023871014e82767bc14c464676131526f34cde1d0b6b1a4838291857e35381a1c1cc68f9a1d64e2e851c97237b07cfb251a20ccf5b658c9518e3da220eb2b90dec9c84a284b4771e7ae6249c9dd4cbffdfdab8c7cc3d346653466d0d8cc5713e75ec8ab4af3a0e569f7584bb5916204e946191011843482626212c7136cf9c51eac94045447a571885adbb0867eaca223b3d50d617f4953c8c276e8e186847b612ec4288ebc90a8a6fbdf8d050bd69d1a33e217119913797a17f01e2e2324cce2ec3e0093b2e7e23f9c4a45f3c8a8e85f17983a632d2ef8daa16ca58e4ac4a0f3e13115ce58b0f1efbd562acb04a46df2b44fd460853a01045842e53d3ebacdf4a10d0e4decee8a5323648f82ab156d2599dad3ad5964865539eabc7e7feeefdaada130877fc55ff33addb98699bc7f0630bcb830b6ffede3027053072ba37fc1d91ca4b7d714eb42a710c03e8dce35825333738154800ea2aab2a8a61ff851028dc4e4db9305cfdaa9ed60478bad35eaf1acfd905a0103daebb1d719b5fefe0769abbab589bb42e9575479982429d95425b9ee1764987a7466632c509cf918647529997e1699afaeb01e8d1a41a4c7c5970f461907e299b1a4849e0e85862b2254081a05733232683839c52a5a6db578a6fa2c685f9f2ec4f824000312ddb5e0e4699a888e47847df4f09cca2c02ce06afffa1ea902eef4480e98fa26b58c06c2876372717ba5d0796c7d63ef418da47d97ff652a956a451ccf20c78d2e5ae3288e5dcb526888168ccdc96be1f3649a9363b4e89d41dc751381db9ed0286d90843ebb8b3c208501c39809a4e0f3009e74813f140c1d629bac965a78e00da4a4f0c417027acface87d0cc29616911db6282934aae0cdeda116d423a47f5d63886fccc1fb0b1f6190fbe9b479825c19720f3d8f8eceeadb2531275f96d6c744b145b99f4d35ebc86500170ce2d8b8682b896904c67682445950314593fc12a84d0922bc1ff04fdd9876a27123097cd63cd0340d4aa04eb0a78b9552e7cab58bfe7307c0d7016513f90718727956ae23139d40f10a2b829e271c2c8c7599311955fc509df5291cea8c8fa5a790f14148b7b3f0282bfe8e08c7aa4b34e2184a0730281b44856c8216322fd384a9969b723b3bee313df670c89622b2f23668a0fc4cb4e2b4567e86db0694b76bd8e02d0df992c408a16a2ed893f8bb7a84327b1641b831fea15a5f07b983163a45e9f4d3d9ecd5829611e68bd403b2d46cdf5457ff03abae288c662f488bdb300457598815f11721e127a0957011613d8e3900d8da184d6fb0d641f2ce681fbc0861e702dc96d050cc5b76194392457451046de246892cd20bc9e330cbfe975006d534d6a7ae9220d868ceea8fca1d3de94a7839497026bc34c419517330ab2b80f11b3ff57e4f7cff2b753b2efa52f56045fbcbd7f2de91f91e54f699801e480a405562ce870e5ccb71818f7175130d0b6994606f1328551f1d8dae8fde731514558d770e930aadafd61e1c5a2285ead4a91ca7bc1beaeea12d34334301cef20a2a7ab2721ede80dfb68f6620cb89463b2433cdbb20b84db177b960747b6df600d1b2884314f8d10dc6dd2bf12c1612bf218c298020554c98a91404d99d31bb6b94ce878c545332d82a927ff18d7a20dee17a66b3d3e3504dfb167e3c766eac11401d6c886ae2273da0bdac5eb4baa8d621111eb611a9f8053703436c287889468deb0d90e0c980e7d653828489f90fe07ff84aa5fd822944716016a2a0304370131e34cb8b2c1f0dd992c825abe1d9c87399979c76d02583a9aa2b45ce2c44e3d1e06f6588b4d96de79a0fcb3c99917e2c48c05868119612361e3c0a72bc90176e275e912d0f74417fc3dd965aab22db0c51aea2dd5076263a9b6bcdda766c52af994fa4da1a4dfad62139979ae32cf8950cbcaf80fef51857a1209c9649b13f235abb4b1adadf6e1dcdcba4b1308a10eda3cf7b1cc03978e12d0a40f75087103ee8e074636e82008b6e617e8dfb18384440ed656f351607cbed01483e6b10a064ac7748778302f3051257f1a05bbc52f158cb64d136f461377ca56a8623aa9325f5032cc50e35e191b9342e679c6c43357906ff30b296cadaabbb9e703201e94f739fd0970836f7bb35f7fee95d2f72be99dc590a827436496fc9a55a7e14419070569b930b071a58656609d5ef09f7832a431ca03b1196fd82e980738b31a01fbaa66e58fbf352a9614be6c4f614da975bcdb3fea2391bce01dac20de497483b7a4e25b1233a18faf5cb792d95903fa2638ca90fd383b536b7258fe3d4d7c64b2ae40551ce837be389507fd630a353c305008c51a37cdafbae2e508971d3695028f0b3b066b22f0644812d3df205ca11203035014b6e0d4f00286c08068086e555ec3229e262b43231aa8d45a459547d6eac3d7dd91c20164731965ce0570f3573f1a368ddff5cd8522ab0d33b3baea1fad51346ce844050693e274594ba01386b561d545d2f1946cf8e7a9c8a7236b972fd54f846e3961f33b586da18d270608891d1b0c3c122cdf16e606932a6257c6731fcf2fe5ebb06da55d383dbbc007cdf5933a48df0181e3782fe8fcb177d71a4fa0285f8e62476461d5fe7ca1581ca858a6d51d744dc222976064200299a1562c587913fabc748e169c2ba72176476cdac1a9d6a1bfc037c245af0d1737f8909b1c5d83c4b45720dc4e249ffc7f55d56194062a43b7a3e5834d6782eb8a92d002f1df5adc1ae6086044f758f5fd257d90000fde0bc58f7e501ecdb847efc9bbff80b7fe74ff39380398f8944171a544f28fb194faa4238c03535060d5162b09f2923a1930de6f31fc6f354a8ea4d6ef633a3276d54eaa70e16370b42a5f4b2fe122886e51f052829ded023a87d38e113d34abdad4411d58d794c98248888460b899b11341d74074a5ec041499393e42859a880782e27e1ebcbccdef0e5e7b03bc17f925addad6fa967ff8f087299caab4cd6cd30fd63d02b17298aeec78b8027609bd41434f51b7c8e90c0c64240b1307c67b0114278211bd73fd34c532850e3f434da201f7f0ae2c6551f820db082cc69c71424884715c4bfd9e04a30f25c68f913c4b3d794052421de0628735920eb7357191bff481d30836e495a52b37e0ea72b9b01ac4c33c7d06441981053982c9283edc3649371368050b4a1dbb5e777bdec2c2f3dd67279dfcb9617bdfc5090eb8c2879c26190333bf240b35c376713cb89203b97c40a6125d58677628a55a03279269cb5d01253da3c561cf73a5e9095c83293c4a30ef3c01f7c381eaad89b4762ca75f32eba5f1a49f2759ca52cf4b9aca7e431d798c30e002bd228c1204cb47921c03642471d0e05cfcfd0cb0dad37e0d394143e4a001a7a4b46a91bec6a36de52e26049808e68386556a20f481a352dccfb5a4bd07845a8f391ae99529521d2503cc4532d40b5966957bf020a0cdcbd9c8d76d579bcbde0ffed5a7619c27803745b6d93f6b2ab354461871981f9fba7425c9de8db7e992cdbdbc51906d090c2f7a76af62f0f389ed17df2d344f66e3ae74096c08aeae839aa6932fa9e9fdf3b7cd8c309a48b8a613ed88ea35de6354b1e9ed068d96954448e17319cea85e638a25be99eadc92513bca4218787bf68c53e6019c6f69a616f02110ff2ab6efe4453fd3d5ee2a617ce91eda7333aaeeeee0a202a1a8569c5824c8df5a30d47a9bb4c41e6bf2f12c5f827cb8fa554905f98a6231b303fbe3952bcb3985dc6b908c4a65c535d2159737c8ccbb076cc8ffb47ab0033122391ecdb046e64b628d3d484e345f219db56b4f313e246854009375f0742faf50fc5f13d9745f261c2ebf47361bf03cbe9b359d5631673dcc4807d4fef551775f529a4693c90834c54a0e7a8d3b1543a2e390c0c11222d954ffc913a54199e8595851e2fc139f62a98340ea3915f468151b62ba54a498b5c3c8b28e2112e19d71fe35f3e840de82929b16ee0d91eed69e18ad94fc2d9aff32551897f168c762ba5679310a55443fddc518d55e614083b32dfac849ac2fc8fc5e53636fd6359ab62f2773dd8ad084c2ae95084ba35c1f4dea01063e52c8a2b084d43fd5374f8affcf855ad8e008b1c4eec114f44b0fd305cb53e0cc40b9922c9900cf1e10d55e0b44c27d6fe51d8aecf1856cc220f2d4fd730546900b2ac667e7d19c6995448725fef0acb3b52cce9d0b576b05a43039b83e06a00e3d0647443c7ccc330112ae4831c1ce40b2178a2add531e87e50b0553ee61fa6e24db04000ab34d89f9e641063943626fa505372089b82c4d8fc8015554c8bbdacb323c064343fd04f22de66b3cf6a29ef6a1b79fe169f117efa1bcdc43be2b6042773422abcd43691ca30e8b791a1e071edb97f2d21e1beb5b7bce49bd03de42f1c21db96ab97755034b718727a73ca5637aef8d9833aac4c994fa0d8d8cb5530858116bec091d43dca13b7c77ee5475cbe830a6bac538167dc8cb635b1e5e2ec2ef33686d6c02a2eef1e7ba2f843ddf1f73b398cc428a8b1d8ad0151d95bbd2e812b402858f66b2ed76e3f34e960c35229df6c9eb24213f2c1f12dbc81949b4dacc4d430f4c4017a2958ab7d6e1e2631d311e1de5fdaa85ffe547ed9510ddac2c40362403570a123d7b2cf7f2717e4962a2e7599b322ca08ad8f65e20f05a942cda486903313e215df6ad7696915e7a1f77e43885aaf693883c209202d582ee0d1ed7dc59568ab34c8502efdad1a5aac97a75e9ec17e1e1632bf2469bceffce2f5141de5a6782c526694da7b873b0edcd8473bcd059f3f66bb631b676ce1d02260e753ae04391304148da089c5db252202e52672d862f7298f16721f4a3941c3f60aff089ea5688ea8e9651c04a412d64b3b71fd828d9a2b29706b0ca2c8f77800a382f55e7b7a6e0e565152c2e857b19c5779ee115738624c79d24a685370494e50fa9fad17313f6c6f3adebdfb534966d5a162d53a391f8b3daee4a038167bfa02da73bea2abdc477cba90021b470209aaaebfbfc752d6d167228914272a80b20f97ecd030de8b6cdba38f3adf15fa74ea039d1224da97f041f619b7faa7c95f5c10cdfede1697101e535483b938d24f78212d505e00b81871923bc2b65c19c9200986692d7e22ef52415397ae606dfc86fced63bf6a65607f6d0df4ee27dd1a11bf19addd362d306c8a5badb21b67226fe738dbbc16c12b23dbe66639fdbb0a9920ef5839e6225c46a0cf58c9692170481cff4defc46e661103a7d98c2d94344878025e1034fd6de401257d64714f853212543d2a61289ef9a4c8b43c5f8125502bc5b976047c9bd8485f0656b829d5798687b7aca09ccd2a4d16a7101ca5ea91bf72ba32e25b2c4cf9bcc83dc366d6db832864112a06fb86a3901cf46cfe7288c0f085646a96225d4e277ac6939cf57d81983fce08fb51c5615d2f386a70f39e22e04cf13b1393485602fe6cee3368e9c0bec459fbf4920fc645be22a13ce96a80bc59b7f11002f01928ddf83fb78566e4670e47b8215891e5701576208133cb9c0d649076c6e3ce761a697bb3257150cd73f4527350ecb466ca7eab043681efd1defaa3402009398f1a6381061bc1002e80db69fa211272171421ed760cb10572b4de6da6f2dc2c01de81cef224b33eb821e8410afae0f27b80a40f26919398cb11324b8904fa5688e28dd46dc33968656a803556b86ac64960924a269dc70cba8b22157cafc8bd142b585861aa46d26c8ae08a84e87410f0226dffb749ba61dec55ecedbb24ea9ca83b76a82c021a93a2d113a64d8a5b2f0a65529fabd465cbb9b78a4dbc0d22b6d9852d24175fa9f7472583c5bda6c931082ef1bad99c3a8b0d6daaed0995b73f8467a58f5da79a02eccfe80172addede0a521a00e54f77834d606f1d03b4a5da88d80ae4a259198ee51ba016ddd696b88538e1231a7aeab19c5906686d5a6a6bac6bfe1643c56f73249dd6fb1dda166e51dea08f50ea04cb3114213c56bc3a7071069440bc5530bc65299e15786fac2de54270b5cd1e71fdddc465017f952c56f8f72f4d1287d7d24ae9018111e4990c4e9fc68a3cffe6d3652f42beece7f55d086158ce3ab427b5e252b42fc86b466367935b048fcfc35f1877dbd640bb2f5446333b6810f24b7b3d7b3b94798f4a9a1e721fb07ea681dcef1ff501017fe497cfacba81f9a357b3037463beb92b2a02ebc8dbda7d0794632fb7146bdbafb1d8d6b7e06f58032387c9c4c3629e950e17de00b35103fd942dd0b381499891c2d8bd4e61c2389a1c72320db4b63195b1703acca84476e00f00344520a5f92f6cfdc339ddc9ae1b4249d3acf74ed95faf3b3fcfa18856911bc77bc7891f49d1a6b6b235517da4b3431fc7dcee403d2645299cec994b0cc1b34d87863a53db940473aa88684d45d3fb09dddefc924d8a0ac5fc97d293d20dabbc7cb0cc7efbb525950cafccaa9a744923e6c3d38d59b343542fa4625b3b74c58ad824122420043a69fbe3414330a397a6d91efc065f719f6b80af712a0099888e463eccbbf46b5f3bb411554276e0ac6b4a8c1c43f09b5782d7310c2629a07bc3a85c70db637a9421347cc4437e544102d3f03bd09f58c2cbfb238501e262af6ba4073bcf99deb49bae04b0778a46689afbc6501e1a607e3e21d8955d6675988e5b67890276ab7b615f050d7f1872723ad05e7e924aaa69f027d677274a2664fd5df3423ece986d4a23b254b061e26d8761d858ceef04afc2cb42c86a420a958bea17273cf899b3b84796b8d3ef86a0af815dc42b24ead068864a844a2d5fb3398115d712fd9f61a3d45d0792d88832f804ed7823d8d10f2f85ecd3d854dccf251d925730a4af0cd44306083467ce647476a45f2627c5aad77ca2d3ec4179c913ac1f0760b3920ff71916cce76b7f4d8d82fb20c193f18e5ab01fda13c23091992bc3700bf7e02a6b67e145bc8f1baa03ecb4b15a16e8e822c089cbd38d1969fd948acda79551dabe6694ff1d74a32a87a60dd1aa8ffd4cdf975f54fbbae299e06501f29f66c7613b71da636ab441f6c24388318baf7213aff2f5f888a2fa7e522915bc7337df8d76dbcfd0a04ade66783f5a2031b6523a2c780fd3668b89bd6d1ada8fe1d6d62b58fbae725198e92831235f6e036602d335888a74273eabf81c7b7299db8ee3ece7c7dbcec5a489d9ff9716dfa474f34ec9f873759426da3165f55e99c9ced755ee90882cbf0269b8b58a66efc8117cb8a0c9ce51ae5ad0b462401f735de69868c908b61c39780142b74ae908bd01eb7a629aab37ff612af0f174d562e9a4a388d25d418dad13cd71a6cdd6a1c14d952bf8f69e7d85b34c37fda9e50d33f83e7c9ba87016af693acd4b5042cff225f4f499e76e52dccc8d3d777189531aae3841ab38273e0d358b7191d161fa85a4c5643bc1598e0ce5ce159431fcf4e287592851f5203dc2dee1f0cc501c9906795f10081c3a452249af3869ff30b15fb7296644bb3f58163ff3461be5db8a9e828226943c1c37dd60ee595ed3e06d09208456401665bfda409a72be85c958ae5405c4fe35ec5e4a17037446c12779cc613fb26854520db27aeafee17bb739192b5ea415af81c01925f8c8d06efde3cdc6e60ef3138b101438befba03cc04bf019225dccf9fb3869e1162555d55a5e7ba25b5182fa1a646b40c1a74f6799fa4e8fdeb56aee1957588d09947a4b1c8753a8d1f69a5ddc24a7da3ad996f47ab958c6b02b2857e5423435c714c942c4e1095be8fe67a28909ed6ca05103bd0b6bc28003812f83b7be092738e1c9445f1887a891c27bb78ce914686afeca14dd822bdb0070662c0b6b70f14eef3941286dae9c9ef41e2cf79364881fb7b0ada9204fa6a64a28bbd4cd0b0a579712b6cb8f48e5315bbca5a8e822eae932c4fc91ca48cc14802f16d68207014e69912f2c832c71677e3a81d1e390e4cc24d879caacd048fc91b418def17e80100f638986ab8008f2c19f498a3704e9b3ab598e839acde211f66ea6ed33002aa4ed91cd039a1fae45234d1744c61b41013df8f633f6258ee477283183a30728027c95b5af3f7a151b0aa2655cb3527f1e68800f618180d09961062f7d6f478abf5c2d8dc5d66fa3dd7ea8d0625e83e7880efbb79ffa4892048809ff3cd25ff8ffa0553ba29b139b60e687290030435de0ab30349b8623694ad11877543397c1d79770f96a0e4ff6a0c50cc805c0aaada3f34136bceea84350fd107a4106b4a1aebd14b17fe440a6041249813f34b6a22976492c46418b0d61f96a736ac0ee106792ce77dc0fb211ab6aa5b10ee580877c9b4d6da50e8df2afb642717fe25eb8c943933de384138cea58f4bf3a6907aedb6fbe4007e31e91475fa3501e755f95491cea3b1f9815e35cf61f8d2b6403a0e9d44678f3306c659177394edda78dda287d1457b78bc78376dec43485959e82d1b254cfa2c0cbe239ffdef86ab45c03e6b173a29cfc34a925a94b16d6c2cb97884c4405318031bed2688719d86bb91c3cdbcbb4f3011970a02be5c1c09e7ef04a57aa3e3ef1ede0e672941d98043f941f6a543b96d862e143c7fd84f29962fdd357c29c25ef0e1e4045e9c8cd800b06b12196e8fbfcf1f3db1928db7fd12dfaee069090574c0301533880aba8ae897bfe8c0ebe787202d3a55fb9452ffad5077d6f31ed407c48359d5ab008aae24d7bd91ab4053fc2945f895ff363c4874f609efd0ff002e5803fabc18e9a6a183b3fa088af64c8a87e3782e7d65dde9ca98927fca9573208fa88e3d03c138af4d52250815da500712471e5c53bd967bcd697efcedddfeda5476fdb3a66d278cd8bb2710bc11956ceb2e3613ee96816f2ccf520b40337ed88e0896df2f2d7374e1b59618b454f7c963f5abd83e12da9be0083f51c3004afacfe126f6398fd364bb366f8d3ef58a0accb67b6e8c1cdcaf3374b2ce799277a50121479d87d22fdd0f4beefbd6ca759dab8b33e40097f653449efa336c1fcaaba61495d03eacbe0f934e5424589637e499abb60cfd6cb768c1ce08a2d43ed7e483410d2348aab4dc04a914d85c9328a27074c44a207a4d7f9130294eeb6097f0d58e98f4604bbdf213c4240fd60ab2ccc21069e27f8f01ef65f5c9e7fde110f0414958177aaf20659f52e28d2e831bb4ebe613b86ed0b08a94dac9aa8ce6a16654220e98d55574d292b4317b9acaf084025e60c0c404de5009540eb14f627142188afa76053b6248a1031c051534814c971cc6b0c15317c550b85523d6d2e137cf3f6acd702cfe31bc7cc4eee6090fed45ec9a112b40cf33004677c3a634bf4a242336fbcc2d5c5461ffa3f4d5cc2f6cc8a06ed4e833ee047f8fc408557027918fb6df27369262e01b209ee52f11973cd77f9d0251ae33c75f0af8b6bb65a4ac00c319deb32cc80a91e41ca67311feb2735cc7cfe6fe4b566506b3d271860577de3dfbbf10f1e9e621b0a7f40fa755a62e220847b6b5045b14e4e9e40088126a30d36aa896ee0eb31462eacf76912aaad9eefaebf38996be156ba0edb6352fa6c3ed1a7232cf087f3464d24e1c2b6a1778ade35c78d8b580bba91ab496ab0308cb61648f7ae9166cced829e7787cd0d13bd8a357121f9669a603ab03ce9a3e11214e52da422ef06c75802b947aa3cd95ced376cbd9077d29a2a678fb8adbda9b6393b868ac3416c3dd4eae233fa48a2b99a4de35e82a2630844e511c45fd80d2834129057944e10b3c52b832eaef3dd2807417c2bb73ae2cde31b295e2e8b68a949f537bbee3eaaae4e9ed780e4fc407fbe47774b72901c844a727f502f2c73d813b36f8dfd804dd8ce415127bb07d56419f8dc799966454e66532820026300b47065b6842cf461c1c6b7f6a60977467046219e200aabb17bdbd03d289d3956df9bea3e2c0cd8498fe9720a8bac8f2fc5fa54f57a7e6da93900a16b5e7c31b2aeb865fffe30b0bd444831b24276ffab0668267ee67fc4887fbc475bad7509e6210a5ff556d4314f42b3c03b86d6686cdac3ea0d006a039857d057ce2b774be0b6cab8cadb1f303b410d5cce8480d3335c7a35325b59e82e823de74ed496a20bb6f190817dee555437134582279cdaedbb10b4b9f89ac6d634d772e02b4cfdbee06b1869271a43fc1892c3eaa26312f0707d0665069a2880fbfadf4b181a4189334a52d01dd969616dd75e34d76b94c408dddf890620c6be395983046a369dbaac1b0907c3863f305c40e6eecc4811f3eee4010669027134af50aa395e989e1eb5d4c3f361381876db42ecd03539bfcd865cce638b194395695a46a877b18c3ed3f190cd63e782ba88426e7726aa70d78035d1084a10ebc8529231f98c028e70cad83b50e9a4f43b68778c4e52271009a02562617b0172197c2a6614d8ea671966506b8e1b350201d6b7818cbde6cd76bed62d0e1d789aab3dafb98eb0bd2ab98092849e95abc36ed858b1d8e6b6fb6d5288ec252b6618272df8da64df4478d39bb787dea45e680f5f62d2d93e0def12a707891dbdd5decbd22e29ab45d94d590515f2fc1eacad183b5ec755bde95ef3216d35fbb6475d8bc81d23a3d0f4567e65d8cfcf65843a8e7c042ced6e428dde232efe29e57dd93df2aa15104b3b3bd2842834cbf5bb31d434157a92ed337426fb7e795896f67e84659a85865056231ca1e822350b5b1c0e8c1ec9f6ab37cb3881e5b09e0bae5474ca02d69a17c6b803464fb2ee5e59daf09532d98e827234bb4ad4a11a93438328be32695f89718120e19c3840c514fb6c484fa1881b0623b0427e018c4512a2638ad6cf13004204cc6d20c131a147ddbc402a687719b35b4861c69c8ac905d4fce23a2ba540abb2ea4cb33376201ef6fc5714acc3da3835b31e7105f2d435aea3129e69317dd80bd236875d81fcd468d5f2d9bc8fa0b24d2f6e3e60df7529fbfdaf088cbde356948c4f017f205eb9f0b9928829e37e8a614b605046944f144a2405ec1d2985861e1442feada3f89e621926a02d019803744d140d1b969cb6b6506b4b349b2bda0ce2f27010d4af444a4dde57b736f9cc5dda7bb5a06347945c5fb09d02b34676f4014e94c0b412f0ff30fa43ba69132d1de86e86ab0944e79692d6362401407b3fca6a19e1208dc31ec387606cfc85664228f7939609e6c9ca075b752d0fb6feb2c6e98408df36a3b739bd8196375a394f25e0150a0b987079ed6d1f2ac373fbd03c2c707002aaf3b0208cc45d5860774bbf7c1c560eebc7ce6fa0777c781cb9d9ccdc64d7e95fc6b5dbc43b9547465004a25c48a9342b6d2adb4e5b0c1b5ba1e220b22516284dab422a4e15f1f9966baa560b45c1fec110cfadecc2bf7e923b3ac744e699947e6f90e6b4e5008df2ecf935d92d406b14c7f30f828e527e5420617ed912bb6561f41460db4720d15cc1dab9ed4ac023a373a7c5a40cc289d0e6a095051c39834338684851c459be1ee77528d702d0a2a1a24d74901b3228e0ea8e121334d6077a3867097b923e48b198d898397ba7faf0ec9d51169d82298a8bc128e4123057f2eb48eabdbeeb6b794524a29f70ed1077807a5076e54683e60879ed6481f04bb817ffa0c48d394c3122b193049f164c994cef9f39c59160c00480d6265fd3ebecf97fa1d8bd2ef985bbfcfeb2d4972d28149cf8f7b24916d1da5c4707c689491a5bf54cc46a740e14b63faa320a6d463629ec7bc1af3abdd703fe6656c4c8c92b68e09d0f1974dd21fbe8ff912937249fa8b51c2d32b785cc19763e9af822458baaaeb6ada114af0c51526125d7c2a5457d59751d5e75d0e25908d8dcd089ffa496e91eb7567ee4540bfa4d6110b8e18fbfd15098e7eff79fa7dde927ebf570cebd26f1221fd7e2996feae05f24e0f59415b139c10b13803c22448940f133b3ea2d5f1f75e74fca592f487776592f4a7828df5098f277c1996fe26ec4a957b2181e91b478dc64d1b0fb32cdf9ed1f7af32d72607ec200384cb81fbf63b00dd5f4ffa96b06d0fa9b6226a4584e4eca7fd2640c14ef72e8209e91b66b769d5c0f202b341e26a3b756039ec1bfffed269e7f67eb79e03ebb92f91a4bf1c8931c6bf1ee99de869fa2558fa4bbf7c3a7ffc9cbfcabffc4a7fdcebcc02af21128c88593082c54bcb88112366064876dc88301916c9f0e5a69ebf2c5276a5bf6d84a7eb1eebbe2492fe7444ac3a0ea74482cd0a4c2b6b840f57c6e8381c6e3f0e57a4a7e324e034000348ed8550c6d80e1c0c1cee1980bb385c112d1d17833b010c3523a4a1d00909c7847b135c0edc87eb388cc3e122c38e71111f1d7f3964253b496ef57b2f91b57ebb84e4fc5c2d83a4bf4c44450924fded1fe90f477a75095c5dc2973ed29f0428fdece7f3f3d5d377fe9fcfbbbd21c27e6ae8703e080c20bf3250eca77a3e799e6f02149cfc3c8b435074cebfe43281418a23549a55089f241f5eeaf8cb1ee90fb755e8fbcb2d2afddeb232a79da619553c5cbefba2df2f790829f65c16cbac7bd5716686fb15e075f3836b0279405ebf65877952d5791721c30722ec8aab099e8c2772c664f84c51c2929ac2816851e246141e3113655249575166a79227328a386959551591bafe55afd8e1b3c594e693248b0fb2251756465d8f60c4081db72e1e22552d3ce8b0e9fa711224266b23945c74e10cabf0d5c0c70ff3389c21039614139af443c8d2161a11894f1f75fdab0ca9ea0fc1bdf703bc6eee60762194c8479c98a91129d118f3f11d90b3e87b0754030024c984931f351639bebc2b5774ac282a11f891f7f09f6eb9b0db27399313e9e4440e161a6b4213453ee0261a75e09e82f272f365448d33a20fb8af5474e03e62c24398648b8947cd07dc29fa36a21dbbdd6ebbcb356ea5bdd4edbebad25a246874f138561539bef9801a4507eaae0e4059b2220517256e457c401d56d481dab8c15a92284d38824e593ea04623ea407d74db363b08dc40ddee2107681dba8aa88961790c090aaf2442aedabc84f001b3f10488291f371d16686734b6f880d94407e60710b560229606c384970fa8873a500775d15033991da89d3890c19e20e9367f0d33573e622b18c039c1e2498a1f6e2b7c40ec26d481d906c44d0db5226049c48e573e600e96100b9b21c2ebc61a918b0f988b823a300f73b691abf255b7594b0353cad66a3a10ab0161230e0a8b4870146be1d503870c1f100f813a10334d612d1c047f497d753cd6002c8214b2d32dceb95d6e5dc3240e46382a62243da9a2e5035ea61f284ca84ca192a264f6c507bc533e1d78af345024c593afe058942e3ee0e5eae937cc6e18bb666a38ba150f7785877b34a103afd10717c8be9db2555cdda2c032e4e98a0e22477c40db25ec401b76b41bac74b9394bfd0a3bb0511ddce8166899baed75591f3c387a8c4f4fc07cc0328c440796c62243521c977258dcf8e10396683c1d580211b3d1c4a8e385c5131fb0741bd1b17dd272c03ea01dead6e888db0ba5907e8148b7659010aced116e51d3222a6af195c10e24dd14103546c40719501513df4e079641b21c9257c420401cb050bafd0d901e90dddaafc0e5a0de1a9c428b87120e8e331c9f7dd5fe7a39905cd67c641152250546129f886ea1a4aaa48a788a30f96c4ebf1c48a37d0984c0c5b09c085d148723fd712ba10c53290f81c951ca448cafb46289439675794ae2e266e8892c44da8f9874475a1e7a436a4c8b0751fc04a1228817954f0bb02553ca9b2098d3468debd64b7ed1ce93e368f01d27e25c8968a204d5c4c76d3ae7b93f539e629cd815baa214749c9ab1e44be767333ae7e779cdcedceee450e98f6b62799ea40aa408833623fd710c31d4a8342991812b7d14a94f4e27ca398a36c5d08261e4480c26183ce5e8730ec4c87ae2ce13e39229fd7174899f280964684dc7879113149497ceff7967503ae7289ae1a2a1282fcbe30ba5f49772604a92054345928ae278caf90f96b13720576a9838f3bdfdc8ca381cbf6e48e98f4f588ad24f31262d172a2e4702e5700204cc06cf1317be2e0c4862e1248717a424133ecea5f334279d731c8ac3f15cd922fd7154a7a75f0ed35fcae38596a5a47e7e7994fecedc979cf35700e73c7dcef93f079d739e4355bec2c43c8adb016376a4e5a13b20e7bc64917eb9a27cc1d5cf01f4f34ba3f4770e2f874b240eb3082c8710322ee7ac2d443d57909fcc34f9988f34bccb41ed59e939675d9652afd01e1868c9d1404b9316361557e81599e2ea76d9ea38dc9728d21fee8aa3571b8a70596ec17e9e5f12a5bf93e3be3c91fe786922fde54be4e7132e3d57d0338acb19cdb91cca42a3f30d9d7f2994fe78c635c5a0b82f4b582c5f0a108426ada9bd406223e546f46d41c04f112e9bae1023b86849e302f3015dfddcd24bdbeb878d4af0a9060d1f06d231d7968e6a793c0f6a30c151f49283d4c2777f1c31e86416942f50aad82f7a97e0688c04122435ba08f1651f5aa4b2162a9ebd13a27778f01d1a2d5e4c3b345d06d3cab6467a901f8835901da09c678ddfe2d7bb0f58b89f5f5bab77f6f3cd704b6bafbd3b2c636da977abe5d94b4255f5678cf5efd67e49e829dc35a2762049922479bfe2d40bc29657ca05d8b674d4905a1254820b0230a4acc0a08c3b78ceca1e6b96794381821b107d4301afddce4b7283fdfc2489f92ef75b067b68247abce1f4d65a6b1479ebbd371790c9150ce6fc6bce39eb8c39901755e3f660ebf7c90fec0796e33a89d543ec05eff11e57d795b802ad3de3da5b7b6b07ccd539e7f8af3ae616f312f3d2aa65f9bcb4bcb4f879c6ceefeda5fd9297dcae3cbe62cc6d57e7ab5a6275c59c33f5548c31568f9dabe595cab3d80e3be72a2ebb78075ef28e3950e71ddbf432ad970f9ce9e45f200f10022980f24ba38d8d8d8f0f015bfd2f87978244a44884098e103ef265480f70277fb51b40c0eb1e807933c2934f3e279fb44f6ad0e7eb47f5eb5fedffe03c0074fd400d5debffe0c814a915648255b2a46b4da2a9756da5b41112530685141e580e15f9b8eaba4c622a9dd6266d30255790aecb2ffda591089a5ad756baee6273369403b4429a07da212940ac53d736ec9511ab65b96c90aebff45b639b35ebdaa201ad5ad716f415265da3fa06afb0eb3b748bbafe3bcc32ecfa26cd3cf03239757d6d74adbfd8778f776fa1d2df0ecb8b3e3303f5240716af2bb162906f86c7ee675ec6ce3c6fe6d3fa850b6f89e9efc26ef77646fadbc9b8e2d46564de3ea53f192b6f3d97dbc017ce902f24a823355f4e6be6732f93cbe5aea4e8b908b95c2ef70ec8e5deb44ee96fa689d82d3cb6f03646fab3f0191e53ad1863b076d3316976865676e248158d2b663e208956c48f820c78c460fca59306513af6c2022b8d5863cb07b1ccc2328fbf1cbb70ac0284420796563006e1d0b046c736a96329264a96b8de96dcd0c258f81fbfadaac1b8ad45c71630c61b606ca5a7e30bf09398dcc2187380dbaa3a071cbc8591fe38d8ed76bbdd8e892dac6fb0c1dba5f4b781ae29b2a54536237de6ed8bf43753a5acd73cae79ab94fe6afe3f692d5609d1798f796f91d21f8f78d63160787e39d48471a5b9f0b2e50a8e0fc355c7f0d645fac3d08168bff047fa85c7178e2f5aa859c4ae2e2323335c13ea1a68f0f628fd69a073b91ccee5a67aee7bc29e7bcb22fde5a878f50c3278bb22fd656094fe2c5021d1533185ac67c8f036854541ec2454bfe082b745e9ef02b5a18e3ee6311dfdd56ec83dfa3276f728aad6d6d10ba800b488bcd8a4281e05d11de8cca3a805149d02d4d10c68028e4655b4bc96a4bca15628fa284051f4810fe4d9d8e9f82d911a55b760e1ed89f46761666666e6ad0929677db77b3b94fe7652c27221d0720364cb4b91a2a38e9e7b2b644ba43ff46cc9bde85f0c375c68e870f533b45010308834f181d3e5e3495b59d54d6037e4fe3e0a6e9973d186fd56704ba60b9a48b832770c03a66b2363876e1463bf13eee5befbf64a837bdf7629d9af7e9f6ce1dc78f1e16383c807b45416cd6e98f9fb568df7406be5feb589d2afee4e6009141643ac1c25e5f0016fb0df1cf76f91ddb0fbfbd7a8e68137896837904529c47e3bf0dae8f7c97b2ffcfd1be46ef0c0fbd5ef0debf7d3defa061bbc0d4a7f1b64bd05fb850bc42413319aacc88020f92ee0e817de02a5bf0bbb525dd3a27a8d865ef3f627fdd5ec76bbdd6eb7dbbdf5497fbb5da9f6a25ce93cdedb9ef4c793e9334f02bfcf3c693768d081bc3ef333333333bfcebc15a6bf995da9f6a2e8e81a68f09644fad3008dad6790c15b9ef497818c8c8cccdb11e94f064daa6380c1db60fac3c082050b16deeea43f0b50baf40b2e78ab03c52a013dc35b111272b95c2e97cbe5dee6f4a000f5ffb738e9ef77a5ca25c8c4608ccfd46c88b3a78e01c3db9bf4870145511e8aa2e8598b8ebeb5497fe8976bec2459a7a1f9d24bfaa32103ea399fed50a2d382cd87c72a632149844c42c939cbe45ce6a2670c48b48c7ece17b2979e878a72ce09435eebb9cc339fbf1cb3ffc0d2ec6886c3820e2cad5c2b422c372a555292f880a5db8d6e8376c3fdfc5698e18176283fa1d1b30072064d5a78de8855682065a93e6537ec3ebfadb217e46cb6a45f70c1976fe9ef02afbedbed765f76497f3b33123d43862fb9a4bf0c1ed4b6a4bfebc445ffc7ffa596f4f75865c73e83fbcccccc976ee96fa6ac47c780e1cb2ce90fc3ae54792e97cb7d8925fde5c8a4f40b1cfa852fafa4bf0b288a5a2163d1650ed065be6c4b7f3246b36ec1c2976ce9cfc2ae543916d456c7f8397e157f59a53ca6bf4c063be706b8395ad1319b7223e8e3519df397a10180ed194b74aea1f3235eb23451e2246558c357dae8fc19c0f96700a973099cf33781dd909f3f0a38c9bf04325675ce79392c9d7869833f29d5511445bf5c4b7fa8a64005638c31c6f8cb29e90fdfe719435ca3887ebf544b7fb79492fe7813aa6e81055fa6a53f0b8a4d64f40a152a54a850a1428567e2a5e3281c2bcdd8efbd6850d25f0526667d5dbf3c4b7f6b584f27f4344dd397499f775326457a9a2a29e171aa116417b3c4fcc308ad25abe03b6da6b9796cf6767bcb927ac9f93139cff2e2620b7bc11e0d3a37354fd031a822a05d1974e96f9f05f821840b14ac2714539a8475adb3a96dc470a2041384924f508a89a926a9162593e20e94aeb5e651a950431c23b01d510173d315c35605288733a5de08a51f4400c10c09d19c606e1884f37931a650284e1d2eb4edc7d0fc908386cb6a4b23e261e78d89adfeaaea56a379e247fbbe1471251259fd55d5ad37c1cd49601ca3a632ba3a401f748af20bd9e73d0dcf0608c98fd67aa7e8d690fccffe3f84183e4f46b8b18944c34b2b2d56746bc89bfeb88ef4344db1218ccff320e77c672911524dadc4ee6cbef9e7c466f86c33b866612d9d38a5e0ce9c09e6e6c6bdcf2bd4268a988d390b9307c5e8591f1973fc64e2567de4b6c6ea11511b7190e4b6be1cf36130f354537d92db7655752b0b1b53f392d756d2f03e0cc33e63e178db24b92b8f82d9ac32739ef739e1fe3368c7d354b0c6f97a82e9765318ce74726ecd839b24c7dcedd690c3230f125aedacaeaa6ebdda531ac3d04c4a12ee630e948b4e366691e986c6ead6185c58d8962b498ef98726a6ab85c2e2121aee038c30924a9311a6d8b41694570b529cf37c9a6afab35342e987a4214cfadb404aa02d8a724b7a702f52a034132752102d027d11d21af32563facb254ef00f2f88275389ed66e608d2bab5cad6905a4a41d4d50a91c407a5e30ba10f2db8800019c57e3e204da5f57c70510ccad2f36189a8ae127ca87c474d4530b5d494ad21bb96bab23564b74f495768eedef268aa685429ae53a85ee1d3ec3a895505f43d0dc5398e2b86fbe04e7eb660e25bb7fe7099190f2551f5abbca7e1fd0c399852de661498fc40c33d84e5c20dc5ba15884b139d2d72a470ce3a4782797d406e590a13e57c8e590a0f6de9a1bd952ad0a5cfa748eb1ca80de7b9435848543adf8f1b974011a15459ce10b52e4b824a641e2032a08440b94aaa6235162485afce8676ec885cede914e514d29fada1eb596bad5374e12a38899e2410854d20528aa0e2a8233ad231baf5e828a14cdf7cc2545fe53d0d6fc8150148c3a8bfaaba954530266f936fa2a099eb39d3f0806e0dd9f5ef0cc0f2a76fde26910d4fdf880b268b8972e5aa68dcd02d95a2cf166ea899b982881be35cb716319d65fae60cb6b70a2eb31841ebd623ada3203cfd991b825560c39da9638e5889082e92747a405edf786f1c1905714361dd5a84a6cbf4d2797d2c8878cb358fb45575ab11daad214bad73af83869e86b7b1c20f813349c4cb144ca62f0551d539e7ac73ce59278076ced9a72298e542070d66adb7de3a67616f013a9cf31ebaa5cac764c2a5bffd43c84b0ccf233f5bc8686e7942429f08f22d47a26c222c73d9e9711b2a31c4c4e58590d5ad25b86e0dc9b9e030e13351746b48ce65888f6f28ecd690dc1774e4f544999a92dbeae5bc732efedc60c8b94bebe8742930738145f44428c28a2f2be9f9eaaa67ac2bada3dff134dfcb461c879e7b670533eefcf0730401eaa789b08c8a4c2a49910957ace1c3b36cd0994e62e5101186b3589f27d08918bead78646e66facbe78ec9496d2ee178d624df9b8ccbe4db890e0e77d22384034403cd655c3bc6c9092729825638fc2aef6978462e5d84ed8ad7d713d5f02bcc4a2ed3d2e383c2557f55752bd9301bb97d95f7343ce3116315082d57aabfaabab5ec16c0898b3c030b47ef32b41c10961dde0e9bd5cac684239c733345715af8b9cd474d93a785e1f61662a09db3a7856a29561fc85755b71ab5cecfcbcefb2aef697851863a43decff7ab7bf7361a92be4ddbfb0e3d0d1d6c70cfe482e1b9e4f5f6de51aecc0c779ba636b5d98114a29c520fafdced3ff7f3bdb1d0a6f6fffedf69c45b4376f32dcfa0c1f24a135f58b67444d008f26d247da7b5f5bd7fb5e97b6f9d9f8746eca5193484a13626c8d735935aa5c937a43fab8504e95abfee73b6e2bb6cbc3564df613f58b74299d25c0814a17b36bc99bc1c54215b565855b776d91a328c9b196d0dd9b17a39904429ac9e0479f275f5daf510a8aef5ebc81c5b43f68c26b43564b7eae5803974275cb786ecf84b953c759dc442c1a39b506afe83761663e3c1ad8537348a3372345972531e9142438b6dc159671a2d651dbf0e638c335e4f1c5d399273c5c7662705988e12ec45796df2c65d7676c659c51718639cf1a6713a337bb84e6615c35070f0bd5e93de5018f480309463c84bab4812175f3def221479045b508327a9d354707712ebc8f325e8022c98a4b8392579d3f1ea71d5d682d48a4cc0013114553c1223478b2548a511b10c8e477a7ec48840bad1f3eb44d82e1e1a588694f5682b7293b39274845ae79cf388ddc92ca4a1c98303f634284bd044e939ef6cbdf5ce5b3a3290f40cd3338e0732b850985182c7838ca898b29c4da329dc7b65cc9051622da1714ce766d7cfa124757640f931bdc4273cf407c87880e1616b94483c89397cb018115bfc782072e1783cccd0427bce9199c1941bd3b9d7c33def1dd331cafa7d62d1ef9344a112190d9eb438ebbdb3e5ebf2f30e58a1978f4bd2966407a5b525d2dd7adbda024288442982a3870bb62e2323b8255c34459e60ce5ab2439875f49c73c4947269508479adb8a2c6692345108995234bcf75b268a4a5d748b045a46232b6d41424926348aaeccd06152ea22120a2480879a40009d24326040d5295c5c492565757900f36840d11e58799910e2c4b389e40c4d86af2660496a48dc9de44c0e458df8b2fbed748cbc62a0ace469c071d8a2f438e484c04e0135e8c547ce436d009bd4d69c3a1f248fce3762563ae5377ba5b92287621312563982017222b196b52eb14b73849a1c175b2b8a545077e4f7d8341ed0612e0ee810ddc0421082103157080daed0556f4cc38b103cbd910dfdd7d706bca5e27812b90d7a2033b00492e2019960424ddcae7e5abe57ff9bdf23f28df01e567a0fc109425766ad1c18a0e56e48dd5ce8236c618e34ce824965a9579965c4d8435f9fe604b96362616338490ac8dda4ed75a672ce5cafd9177152fa689fcd556a58ac60b1223707cf80b9bd189c5b663a20a16350ed417bf39e622a890ca6c8082465ff6d273ce3e241b716c139dc4f0d26ac2e9d98a12d47983ea49a1523869194c0621bbc29276b270ede4a852a54bbfbff640303e39691d9ab51eb7014a0bba212931e3a2a30227ca0a486bc8888d2d6404c80744699918eb781af515d45154e6e6181d0b4e5ddddec99a7785480589e29611535a84766f1e4f7d334a29aa27ea069765480476b2ce3aaf0861b90e51109d31c6af5b31c638e34db30545ccdde2f3030220460c6fb68094748ce5946e5adcb6962f3b7a27a3592d693e5a906421206680f5e841b6b68645954546e637273116aeab120bd50d191754e69212a1aa655411b1339ba628396eacf82e967eb95ee461d10790be3b59cc22d5cbb8f2d426e6d829679d75cef839c64f621ddff061ac37df27c65887337e8e9f68748cb1e63d31bd15fef309c553882ea193584e6b7bc4952b1da822f90483945d9d70124446a6a949ef9c7306c25505b0d1e1590bc236a4e1cb567c8e4ceace39671123d8824f82a6899be284870d5f82d5a3d2a8ae20d97044a08771e599cda6a1cc894d9eb7c0d82211f5028799585b5397165937f958558741201ddba00c81382931c5d654a5a4f3d67b472849bc4d1add55d40306d7d60d1d1a559c5610f1ce2a5081442cac381177a27e1cfb6e2253a1337e9a18542696081c69a37186c34593256b5456aca5028a2c582c25fd7ce95059b1a7ac25082aa38b1a4c3b22d0a6a65c2134493b39e7a20ca21e1d99e7dddb93d0c9e2d317156bde778702575f508a509a8c44b58e5f5deaf8c9c68a3543278b4f38fdec64d149cb8d22450a1809a20eb0b720a126b95c1a066b267eca84b07d094a5b57191e0034f4f26554fba599f1b9f7d51cb08fab28474b95eb755bbce2be0260efdde3019f9724aaf766d8195d03d9382fb971421be9cce88211921e5c08334c691d0f37ac70379c8498d4c2a902db31522389c807fc324a07f27a58525cbaee2496d495bd441ad59dc36826121e2588425ea47ce594508218a046952f3d5dbe9c8ebef2ac03c9302d24c6ee83a0458571f33a89e5e6c4ad88ca24062e63b490c9c35ede4f275497cfe6f8558c71c666d924754506d1abf7a4c49e5068e1da492ca9a28e0c3a89c56349c74d6d126b9da16b1e603a63be62f120f6d3cc567900e6a24ac60fa1215f4fb6bc706a62f8786980d351a30d3a89b575a4e76c00d049ac1e36524cbc0a41ce6cf056159302e824560fa7282aeab5e50f3345b966caa6699a3bd070f9e81cdb72cf86f6ef68b1b7baf73ac5f7de7b48676dee104ee019f3aba2bdf7d65975aaeee87704b1baf7de473b52a89c45745a75d5a9262e2761c2d5f03139df593de7de7befbd7b71a8637a9142050ea92e6066582790a1bcf7b6527b1617cdd6b9875a5ea66e5373ce397f1ddf1aabcbf28ec524a193584547549b5ece9be7fca333dffbcb234b6a0461c8aa587051d334c3e572673a4586c402ab5b9d00e54e930cab825d967569fde4aa6b9df63a68e8e527683b6bad732663aae084abc6ac28cbcc452ee79ccdb8ee139b5be3231b4a70c1391f023a2605e1291d758dc70ce484f53199c2643ea5af09da1d5beb3a1b89b786e4be2547ac29af266e34a66675d5a9ba9538344fa1e6466aea8c63d7a94468d4a582abfeaaead6ab4cd5e1f95e512235edf39e86370368eff28a18856ac551fa44ae9c731eb1c249958106c3b6e5ea280aed89ad740295a4a1622055057b1184784e51d382f4677147e94675187115ce62d18a52a82ac1752b5651052816da84f4b77b5aa3c52eddf6a2cbbbea9825a4bfacf7de3aeb08319b0dcdda8a29e7bd7793ac62bea3cbc3db4fd61b8f1246b5b2ac38d4544d847e4cc0baf52a2c27a2d741432f67adb1886907bb81d4717568a21261ee69adb5d63a6fad79596badb5d63a6bcea79cc059dd7a05749abc0331dd25a9b5dec1b4f5e7cf1d7416d550d55a5b61adb5367786d9f9b2d0aed65af3aeff697abddcce9775a5ae544517046a7b5cd47d9a3c42fab349494130cfa3b1faa35b8c9a14552287c3a826f5104a6970c1242909a25cb9a4321e9c549aa4e673464da1495b7c4c1c403852292881931c73a093ec4156856aca530d242db2ac1c685d6bada2eb5dc3c654b26142fba6b8920f9eecb361b395bc80b04fca463be9b9eaafaa6e1dde1a9267291d7d398c2f707c6e045f04f5f86e84f17c50684f83a5d4e37b1492ccd347046e6aaba9134710f72684a4b95884acfeaaea562e686a3754acd0b0caf106561adfa4d2b762cf367c396ff3c6140b70171ddc91701ff32d6119869962f5bdd968f122c455ec0469e87c5c823fc18d35b59572d3d785cb34f9de3b98f055e3f8b68f4308f3bdc9f3c80273df0ec1e3b98326e7c19e08ba350cc330837a4bce39ebcc799c29a8546bdd6962a714180d023a93180000c3402049b22c0dc3d42a0714800c3dc684a0a0643e0e4a239118457110c4500805310cc30000218308648e4944363aa00b60a1b679857834f1b4b86632baf29c2faaaeeb4d45edeec31ea658d12b82ad28e298286bf6a9df04dc973bc7e3a955dff9499acf00afc811586e60eef04d81c38fdff6228050760a2c173077f0eec8f1c76f7bf71fdeb99c60eecdf6d7d60461652db3e8817436c02b5c590f62207ecbe1b0766fd91ef01a7562e4bb7b039c8fdf95af54aaccb2e85c010c52c97f7958507a9758ea4d6a4d29edee9be5d0b38cedb2526f8e57ee4dc95ac7a5c4fb430fbd90be7b2a72b700d75c8123c46d460785a9ef13a3487a2b4ad2dbd3924d9b63514a1cc4e9e71e017be2ab7c265dfa996823fd0dd7778adc2ef245e5ae20017b24fbb16ccea13294aa5d42ae53b8b9e38d6b2133acb9fea98c6b445b3983954d35fb9da39d1cfec9bf9a474a336cdc369a282c4bdae9ff192233863c57cc7bf99656d665cd8410d3d2c5852d8d65ae21bdaf75a24bf45ad0f8a0def31601d3b988b26dc67e3573d608d3cfa5f7b8058e8a535845ef4919b69024ac81c673bb11e528d07d3e00d93e59aa3ae1c005c633b494ae0f17f0bb8f7cf818d1ce1276d11484b363f7606a333cc40a8f6419fed3c2afcd9aa6db155bedcccbb5229362ab888a9c5b9fd1bf63d7186a8ea8c6c131c3cd0b5354c18176577ca764a1af4abb57db19941c85448331709fe5962eb7255188ec405c0f3a84ef2e2e64fced7838f90ae1e9dac6a7f94b4120acd40c83cf85e46224938b925880d40e6f0229367cda60339c9d4d8013b8e3dab7ffe79b4a2467b2fe67c93699b79072130f0ae105eeb8150d7533bc6e113bf35abd4a594c334803fb941c682f0e74896855500c76363f0e0e7cebd326a33fba543c9fbfb65fa5d70ac6d5351c42afc56c04a48298c1ff267b4df8df1fda4fd72ecc708a78ed80794abbdd0936ffd3c4814e3d5530c112605dcb52063faaccee0b7f4f210212f328fe2e124621138e58c269b1e64223a25ebc4d18793bf31c3f07fc080b0e189d932e35f241f410f21c15bdf225b6f8ac55cf0799e8a22703ef76d57164a49c95c6683ffaf6aba8a79f7682b1e958511322df3cdf7440524f271bf25835c315d1e6595fdd9d344ea01b66ba8dd170e67f6de055364698bcec18c5a4a6cd48f962ecea4d2d1bb8cfaf4f97eaa4a6c9a6bd3c15ea396531dc52845de0c596f9a25a9e321455b35daa26c44736a914b35b2a24b2c7e62c4943d4d0e7f057a3ce7dc019bfa96aa0bbad05bd79d1e657978b1ac3b904cd0bb7b3e4cf4e11a3d5118564333570a01792aded4384f839f9c5d081fefaa669d66e9ca98ff2eba9372a5ba41657f18ef6349a80556221db8b36ba33f83c2d217a12f572a5b8c23cde52d7c1fae4dee9ec63edaf86708a803258a2d14201049af62035a56439e64081c07846f794583d365122154db63c4680d04042649f28e0569088f1b271639127c398166ed0436ec7e98f7d71b874a365f76cf996f8089eb2b0f8d44afcd9c571088d9c4d58b95a33428dda9011ab1d2bd9e3409cf141bb8a0a622802f4a43f7c3191f687c10cf15bbd6c1eac8a9712cc347f9ba7600963487d1c2956f720826e2058089e7d94e3de86b6463c6039cbd6e660c3fcd24b3e39ccceaccc469802cc4df7065f586be506040af059039854bfda8c27249115776e6517f9a855a401192cc6a0bac8ef61469e7eba2b12a00c76ed67d60199dc9cf3c8a2a7c993ce57f2b68da941d8902043c0c001ed6723a82e2bf081251c2a3762ece925b737e253367086d74919b2921380035c98a92204a1e109d744726a573c04b7af8a621f1eb528c2d4cd3b5a6bc794d60d004a183a89f295c99475b222bc9069276afe99de1c5b2a9e9264c44b726e3bae1d3d94471c64b4343670c53e18668c7d8a7ab234030e1cb8079034ed6888cae4696e22b48981fc0097ae1ed8447c6da20e95323106a6cc2d6b589a7f8a25d047008c81936f28556678f4c92fede79221442d91796966a2a56c87b419dfc60923b0df18584f2bd36dfce7eea77480961753ad05b5c8982c907a6ec0a34af7d506a3d650d8394c74471b7c7a390c1f1f96d25075b03eeb1d5074d6915644e7dedff99a8552c0cc82d9d3ec70f2af2f7a67497b44625df14bc21e921e264096fb9f5eefe418c493c364a9dd754636012ceff07a36720a38d9c371c888a8cfdc7b28a9407367948b49072c1cd44df3e18a0b8baa338259927521b024f36f3a72a67b0584f86df554f4893807b15df54480c703267fb9faca6bdf543ee9863343fff27cba654b80bf41c94231e0c27556be09fc4e7417d322ec89a45dc0ca92d54d570c2d0f9d631e419a848c6c58f75b0d1e8845aebe658d02eaf4b006cfb99680bdac9315271d1786a72aec4a61169550636d795c1475b82d15b094dd1ddc29ac45e6fa99ed9d6bd00fd7776d1240a3b66e672cefe2416a73655ae0fc4461ba06a35776c1b44092fc36caa039540d9c2fad28add0fb1505e09d051689ce4e835784c32543cef02432a8ed27ca88983e5abf142f4b729d4ea3c4bc35ecbed24c6a0293c8ad848a1d6859cad1ad838e6e3a5f66cc06774709b78110e105eeffdfc3214dcc1502d48a5cb19183f11b862f53a350aa4f4a02adaa2f5c56948792d15deec542a2d9215d6d76ec8c6e405ee1e4fe4d5dec0d99ec0cfd3f3737dd3cee70f30d82069f1b13a7effa0bcfcb9d2a0ca84b03c850fbdcfd7ddbea3ff468eac1adf68284d7259c20f9c45437060f0eda18ec801f9bb815c0999a9e37a1c35bb385d2afb9d32f27bb939fd8e59af036c673beee05c7508cfccbd69f073a85eceaedd678fe9833bffadd2c8afd780fae36547dc092fab435db95761fc02024b00e9bdadae0ae2f57c16d4d190d449369e172b7a1ac1a29cb7055a9764740a296d3d6d06c33446db9132c3e3cc19c4fb8d14a06d85a830f39a147f096324789271ab89ff26a86f83fc5f1c1ee229071fcb613dfdd388e046e4fec3f665c2996f4eca1025751861bb3cd19dfc6c4a3c4bb306685ec0c09b4d6fb44d6d3eb3cc830ec6b09780e395a16f56d14114e08cd24f48412269b18560849d27a53c007501ccf10f3f0c0d9444fb54feddd98c5265d78b8977e0f853c98eeb59df164391c84e28b5fa736ed45a57e7438f017be51488ba83c4cbe1e7abb6ee298a82861cc85f0f7731d3d3e30e59eb36fc0089601638bf75aa54b33a65313fb5cfe00c85b2d07f93f7f2d4591f2be4228f2a12a42fc612189f111fd9fe91357a4abda0909bf9328fbea0304f363549010652fb618cddb1964d7af0cc7fee69abdfd28c8cf02dd3b94fd87a784a929772e668167007f96d7f78abf4a809e06f085ee2aa7203348b3dba674838ba173a5da49f37ddaac95d6fe7e1350695509ef5791c1f65225f8478cde87c1397f14609c86d420c181e412020b096c2562c37c0e504ac3e07d4815e008093044c0019737776cfbbe5dcadc8015b99cd297a14187722a5df35d20ec5657cf0317e3029603ca22ea31a394a2211892127a58d7d5bee03ca1a13e495b3dba13e31cde81f512077b04b86e63c00c0f61d83a5645916a805bc2102ec13d9567ff1e4f783d90db29c4c840b27c82dceb3cd748878fc4a94b71d505bcf7297c322be2af8dfb4b6c3caa4622319c8ff4f6b1e343239cd6459b7adeb8b2769f2ba611d524b5caa107a7fa02e5e92f9110531f553af887bccb6c258daff50a5757177a9c29120b18d1b8356437b9eb8638cb153ae9af943da912e688d67461fde85a7feddc02dc7e14ccda60dd1fe9d08e3d3ccbbfd685026440b087efd7116a0d72ec547b7cae51aa8ff24e314c42ae9194e71e6e81ecf0eb0beef16c93d71d59291536aaa99deaa847cc77c4249656e69d43254117d72f649aebc79e458e43699c37e85342ade806141332cdd4ce082567c280dbc51535a8d3e2286169a8f79d81dcf6ed3f1a0fc1493b12bc65477a654225eb25ab59fc650dec8dad9388350a9875a8b269ff8e80caea77aaec3dfb44ea400a7f5ca998cc360f5a77468b51f89d04e0403e0a2aaa508276218aac2b7b94c5d90d3f272d96724f61806a664036345c39a9da3a6ac06ccd6ef7df1dac966530160be568db88b14479744426d59d6326244f93f315c65a43a7cb895e89d201e9b52a8d2cbd179c9e9091905f40ca4daba8a7d9231852a410c4e96b069c07c883b838282bd98472c44819783f23a7320a1b6f96c5f800d9a2bcb741a091b3f9096ed8e7b7324d64ab1533762c1d14780dd4db346b4ef49ac18347bee9d14e0cf4c193e84a3f435d5292ca3db75c204d0a3e18664903a5582a571f8de733e2adf3a50ad0748d912a5d8d64ed91c974f45ea851570bf17545a5471304df78453c26b9206f258f94da50a2855d96fdbca1457f83546b3980c0a459f122cb9d8634dbbd986867783c5b81fb7a5167e07b41e73f4ad855c3045450e9fc7c9e92ce643e2e1c96e23036580c7488aa9952ef0d89487905697470d2723bb42c4859b5674dacb21ed21d050d245b3718d917ca315d6909792cf2f385cc61f7eb0a4be829e200d3528c0adc15e07df940101798e212286bb20e5d2341a6114ab619d2951dd7f77d9b1192f984296753ba56b8c9dd4acbe60b988e6001642e5743958d3c605e77d6ab196004c6e84da8808b4bca55caec1a6a726dd9e6d1330960aea31c9c79869b99c3bb82bf15756409510cc278a1c87312fe00aeea9be04a045513c220fa86fbd261db6abe7be44b5f1d66bf8360652f0cc8a5ed332fd84350d0bee45116fabf1a1db26ec66f483510d5cc6a1c9ec58bd17f897f16979d64fd76ee88bae8840f32b682c617069bf541324b77f1f169584668e388ea819e6391e6820449035c985520670ddf0602e255db755a1f212078afb9c341d42eb7fb833e38a9dc93fae710ed4eaf89e698d97779054799c8e7eff7392a727503ca87560e4e3d76843e9eed504f7d1e1095a24862f94abbae38760853c9ed6608fb643286223a3e51151a86163fd5bc29d38d82c34fb03f90c9b6e2578b3fa380b31866c9431228ed066370c3607ae5c4d41793352c083526dc10fb932e61c87b6d84fbde8db71c05a277a9926888131cead7aca72c1f15ec7bff92c2d1877de72049a2f80d5bbd4f1a06545017475c522e178e838410bef6f0c33bca373b058b4c365d3d46893f174225a878f7ec622fc8ac4706047c96db83e3a5271157bf205d58cba096418d724485466958dfddd7286da7b6ef229c17206aa4a69254f80c6a223f6600d1d16b4f94511691588e383e1a903672842495df970984cfa55184ed394d032550d59360c7a55884e20bc588102276e8a0d587587728eb641574b9c63a8e5979301c0cae04be7bc152dd669d5022a096018b78d607e20e919bf8ebecd79f028343ac05de71e8b95c0adaaa3446cbc0bd29f291ccaf1d0017a78d2ea09d64ab65d75be3da516fd29837b85bfbd5060010b9b244520479d154e16920cc6e05c9a33bc4250617d432ca89c64c9eaef1791e8609f35e6ca8b3880e92b49adbbac64de18a10c8423a74a5c8abe2471d7c02b13e588dbf740cf455f7dbeebe63431f79af321e443da487ee7ee0cf2b00fbd3baaace6ee80e6f138e8f4f38753643f12c2670b97036a6eeeb2b173055cd651b2e791cefe198958e33e478bd4ce83144ca50ab46cfd6d767f5a79b4494a54b9074093a6192032d1914efea312680bef24b733b2e188742b28d28e59e9049bdb0271729e7950e55ba6ebb77ada92214570d96f346aea632a98d64f7cf74cce990048042eb1c66f4c470c24d20ffc4a60b661852a1eb05200e0972018b28673c551c01a32447f98acd7c656e38468b94435fbc2c936288cac73ff05241b71f434ddb74d041322a8e380b6c90ffd896dec536a7367be0a26f9d888a05f51f1ed6a2295b96c8204013e2d1747f4377485b352ddf116062baf7cfdd54d7cfdbc78454c8b527017863e21496b1e633022afe73de8cb95f7d7ae542338c7ba644d6caa003b110cfe8a908123a0b65ef982159a222b12b4da468c5968a5ba3c3b523200efed8b8e26ca9d1771927b2376b49a1815f827b8e752a37c7c50b7998091bdab8c734cc75f41d8b1dcbddb6f734fbd4c36c134936fab790797a398382c648caa7aaa571c6b454c37d72fee85bb2abcd33f4699a8e8682598445926c0fbfc8b9edbd46f982ac754a6de5067163d5da36fc48e5bccf87846507e728eaec248c75ac37587def7f5d1671a42402ce3121471da6cceeaca0d24d06fe01a93f66dcb3d7a0b052c300b66d013cf23165539537c4220a076f7d450b2b86da960b92638daa34e4c2e40d21e9773104e3581473bd6e0827a6e1d67be94aae4742876a044eeeaad08e6d64732113a0e45fbd67234691d3e70a9877069990fb2db037d8131caa6365290f9c328770fa0880a95db21681070de8bb58621f603e197b256188fbcd8bab408507441882e90cfff29a5a119f256606769964f589d114020310e0bd384db99e31a25e80859c1475ca1986507a96f1dce146f033ceca513e7013955ad2de5c4cb8a8eea148127132e858e85440f93214f0564fd06f3e4eb1f5a6df29c92ab486439401f89e90514a2309a802542192055180548a44a812744149862a412b45325409f52092210a204a9320a802d2c1447d8fed7deea02e8155d3f4852d96591d06f0a1180f73684716e223d9ce6091937485f3ca33a462b07bb8baccfed036074b5c257981b9403c125788e041558f21402596ced6e817e9e430f5956f84f544833ca764fb36bb2567d81247c37e02b8b3204234a5a4db72e79d801d1f1ee6c1228448d43470855e8601a614f1bec747834cd11822ab32ede387c3f586c57b85d1602ae1509adf70f1a896962f0d598335b7bb888817aae086ccf12b3c3d92f05992cfc2c3acf0f7a835682633735aa48925d87f14a010ec8956f87f6329dd700dc8ac1d23f742316b931f3c769271ac1a5cdc522d723116eaba1c4f960b0fe43aa0b10327c1cc55c46315e06f5ddef90e57d89fa2fe7f128cee0d0a92a4c4ac399b11a87f604c41b0e1393f8a6ee2b30dee10edf3621f552cce78a1dcf00f65e8d7b669471ac9500cc174c489986d26978518661d2d39c51773e34967f144950f7b7f3339f111c6d6b8d815a3787c5a68bd3adcbabe061146e948460d45917f2c2771f3366503ab4d5de7f8f38365445c46b01a185b85b1e6ccffb208ff3864fc6284288912c16318be1417d342aa6cefb0c351d73f13fed9bbb087b5c429511fe08fb831046de60bba8eb84fd5b7d6b205c0d793521eaa64b9aedec1c59fbd9a175e875373ec9b77ec3750fcebd00297241f452b30d322fbd2ed4f47284eca45697796f7ed79dd6059fa8064e4e3a5acb477b83487a1a02c3dd48b69bffb26b25e77028d0ae19e65943d8231242f4a925fa15ac7eb6844c6448e62fdebaca944be18120f44ae163d018cfd48676fcb7c17dae6518c648cab4f2d4664e9e0301196ac0f2068739d37d74cddc2565f7e2357c3c0b2dbc406cc323d69eac5c03d1bdc56673b718a69f68fd91a1092d07d84c7bea7f5d1681d73717d288f3c207b838061bf1bc37047b0eadac4f100bd56b826e81ac180810502d1c556563fca8c12a95f2bc2e87d50898f34b72428e9a32518fa6c25824a0465c298bfc22923199aac53436217c2db39abb439c5d90671d12fdc2e137dc341a208436b3ad0d966428895b2d8d0c7686e45c364549c13d56fef6dec6185ca3c2cc64291d6cf3b44276bb6d1f2aaf755070bd782760799f6d8125b315e3947b4e650b7c916a6ff902228759f328bff3993487707011450a8ed41fdbf5dfccfd07e36cda23270d9ac2e5569cce6b76260d5bfeab9dbe6004cfe6df23f98680bdf7350639472c3c9cc7f3909a9cdba98e868139f5b1cb3200a4c6b48171764cdfc5dfcababa96686329fb7cf6d9c32a823b68f3f049e7a1d3849e3d55cbf6c0e1780ac6f5390edeb40307636ed5a581fff1f4b81b2406699c788a294992736dce06523973af3c418879ad8cd249de50d2f0cbbe6fd9704e339bf044320a04032e4c507dcee74f883bb2bf7938cf7965436e004691996808f1d0525a60f580f772af8050246ba568a89f8e3178a0c2659f7885f6687a4aeaeaa9c8fe50f1ea03ae86c1b771390cca24089a440bce3c3deec6851f6c768a3406b0111a34186d82aaca626a80ec67e57a28399edec2a87ca90ee797c903b8d190382ea6fbf94ab49236dd23dac4421e967583171048a910ddadcce270150dec4533dde8c0a96f6c39286d14f6d06fde317212cf328829f786d94dc3c1f6eb67d26e5af17cc5ac00d5d6e817421bb1c269a1f3878b539d68cd003c560e861748c38751b44a2b9c6add01f37d474157e18291f0a110bdd0a107c307c05d5683a0fa82a24b8d68b2c86865050502fe11894e5fbf709215ac166babf8d35932a1ac4378ae549376250d9b15f8840c465cb66fa24628b1f46467811848dc48eca29c7542761ac9492223ba0609044c8d690f2744ad50ecdc34c3a5d295983474e044beb9a2eccea5c892dac8bf7d60bef8add1c50496dd303b3f2cb73c5111ae45e265c84c552a5a3035d73a26e87ed4dba6d249dd5decd93a01d016146ff2231af4abdb3f79af1b6f7889c12ff35a4fdb6aede5b65823ebd33e43b5cc30051cbff46b3e024cef5e9688434d73a500fb827cdca6582b1f3d7e9b48bdde4dc8939802923fcc09899c7d96e4c0a0b44390ea9190512b49d04f320af06fee2627a4c71843c9986f2ec48af94db8563a69746d9ccca4c026223aeb36e2988f82b94d1210634d58aa9f531daa04a135ff0c61d9b6810b1f0025387820606d90e6f18442dbcec2a0182f6b8eb550298e8e13192dd8eb42b02e84c0a3692ee8ccc2f132aa82ef03867d5097aed7123c24348b109e7dd4391dd8be2a52616566867eda80aafa590671b87f535a3cf223d83825cfaa8a40e0b8bea2d5a5a57ec1e5f4519e86bd2a75c846774b59c2d9a64d2bec202d6ba371610fb9aa22d03b25f2de8739eb9811e07e24981220315cfbb258da42123b0e560994b87f926f3c8ef76bcbbbd83ce561ba4962448a3c49a2020372af754fc0c4b8050322088afeb70c801520fc5075d9c809cc3b801c5b0dc8d10ecc83d80c23d0366218713be1b33cc0215e6cd684e96f9064cccaf81b85653175f7ecfcacce93bb4f6de0c865930a2c90905252a64a5486dcc1635f9a468831c143cebd4087a7e173f98609edb3a73223d3420fd8eac50b20f8f72e4d2dbe64dea213d8244d5a169e78a2b616f515159790d486af3061ac4bf6282bf3556af04ce248f254edebbd5049f63bb846d118f263d803f1972b688434e5fa070c309be62b71d0c2c731f32dd19a9fa31981e0ea6c33f0d659e94cba12285703fefc74542bf6ca0e60f2dd77df46a2e5d27c88b0b1124dc753a175a9d20970acf85ab2d2dbc54766666d28e13ba3330eae6cdc6d53483d8d591009ce1af163094539b7d4edd0c7d822c02572d5dd24058a1e309f5a019fd0e13f145c1e567b4a0fd5cc4462328db0dba583c59e09c68d19edffc17013e73a66c242c54ca31a00db4ca50550bdcabad2ab2bd69defec83117b983c4fef502212a8ba6b46377454d0cc28151b0962e5158b357fa2654aa70d46287e4f9855c69bb10b558a4ce680761c4d58b9c93d4e336b82b866daa055e960b0a60bc61877380ba4aad6c4b8c32eb96b499859695614ee52996bdf2c0dbf49630060079bb47f3f3bbd43c1f90c244b0392042a0948e0772c2df94964db75f575b053736f124ac6ebc2cf2dc4cffeb8c8b852cc12262c379436ae940922d157a6be83ef3834418e5ab534d0d75767687481b61c5e1c785951a9b56dada2a86ce9f20f5cea377558343cd7d29d43a4c185ce92eb448b0b7268905a61c87d58d426dc21ce21a6d06c58c04fa367a84691160f7222a489e5ff9fdc99add7406dcbc291d248fff2525a33f5b4bac288d161842861749464bf225125f256ef472c4f2848abdbe313047a209a50cb1b01ed10c7356970b6e65ca329198794dcdf0d11c7b454361db34074e91076cd984cfee32ec5596c9b862cb8a200eb23d62cb54281b31f5d6ea2053dc628c1826f1c8e74662d514c06540d87c52a484f06c25b34fdca772e0fc3a420bd1128f58b6dd6a994a539e9d9d530754229763baf3918a2a92e0b551602347b2a7f4ea204952bb171ac764688264d496da35e772ab088e2aceff3799ab2737f171b02d744e1a1554370bbefccdf1359f52eb562c51a86d9691fcaaaa0bbc527297051da6103b7eb51c67ad351a8086b2f86d61623c6189b1b3ddeed58144c34af202db7ba0b08bb14757e00ba0a611a258f4d22c276a8d527de00cc5092a94cfabdfee62de3271e8d744f889e0b9a2d4be757e90c4e1b408dc157bedd4c3eb96fd7e0989aefe19a7ce392ccd427eba253ff1aedd27e0e968510773433a42d5baee828bf85b05c456bd540d25602fefce6f3675f90449d576f8ed74e9f7e4c838f45a19bd15396cdb76549a9d2d9ac38e8b6cfad923469b371d0ee9e8edc30faadb61ae9ff6c7c7b021aa61b3178f73ae22efc39d9c29530984d939133d542f26863b66f4148034f2b0da9d859417578b796e647373c89b79419bfc4586a577bd282055f558afc9176df2eb425a1b1418bbeaff7b72822a12c58896caad11ec0d28c986d34ff9fe367d8d198b15878c820974b9f9c722d2eb1c2062755c5f066dbaa5e1dcb3e8d5cc23e1c04786d54ea89bf26eda8b83cad3c7b4b24193503aaad869e48efca79627475b60f5df60a78b2cdf5f65f2700f024e6da852604ddba1d0c0a526da1e6a827e99c5ebaccf414c84a6857e6c9f033e3a9195330baccdf6a7826e385665099658408c9e7e7ef3e18b09f3bb378134491813a83bf757546b427445171bb9bb6b1d2dc1fbf8bedad61f44685f208074408f17be39b9b432c941e77867b00e28c9580b74221cacd5a2870abe5e45b51a49790d3e79f82f725a9d526a8750e3204fd013ad90801409a13528cd04bfe420b110a86de074278eb74ad180ca92e86774171ad12e29347bbf3f2c37004aaa0cd422e831e7516dc266816736cc137e61823387ea48033ae02941e5d30a6ce61247ce4db83948f4c138039a7dc9eeffa0fbc2d0f020e1bed8b0990f4cbb3389267e5440f27a41117f0723016b2241cadf86c1b5cf24133cfc3c2188cebe181629b2441bec2f5158329600b954ce8d311f7fd94c66b90471746d75900133a2fd3784d1a15b64c6054468c8dde9aac5981f340e8eabff0f7011c0ab3bb598b11b280769a8e8b6516f43e8f90d2fddc285c83ce0ef6eed6b69b9a6208bd057c0868abe51fa3b1db0c2046e78a438a662e98b7129183a15561c6d64b20b6d8e7ba13f8d893a89328b09a9e4eae9d3e141876c91cc842d47211090cefdc194d345fb12285922187cd49e894c4ec68b8cb6a8ef4e4ff93f81a4be4dd3a614bf4fed88cd293427c52b41666edc0b39561ceb42ff0767fd47ed2adf78066eedd4e4e1e178ec34ba9f387a484fee029dc87db17d8667c1d4c7a24e9feaf2f74ab40cb08a6ecd5559d211760c9d74dbe006575c730e2296aa5989a88278f2ad923b6a3f7659494aba8c71e77c4537c05a849efdcbdf54e8e2846776540bd85fcb25320e60254a417562e15222c835d9d98790b35b06117010c435e7139cbfaa4e8ac124bb55bc6d5420b9ab4e2eff2c622f5b2d718478c4f27bf4bdc05ba924e1d41bc2f3236a648e51050da383c1e08670a0c2cf27300213a5f40fd21531d101a38598140812edcb9b886f331273c35692504e27d773bc759ef45902ce40765a10166401934bc1a94f2ec8e2aaf152fee357730e8703dec024c8017cdbe2198305207a2291cce81f33a3fb761d98dabf88dd8e415655619449d258680dae23ae82b733fb1fe702935668222eb6ec6eecc853b6303334d79ae8f8e253ddb22f1792245c55f0da6ba48d72a3ae013aff6a3c076ff1e894f74f61c779d9ebd4e5ffb2f8309ce2e765cea32905240c2df87a7922942384278836dc21f9c3113b1e60fc820a8c05465c0fd66ddab2a25bcc73e88a8375be2b658e819d5f3c1e65cea099fedf7f02856df59e1bb097dcd4eb83e798ab15f30001810a90aa9bc56d6cc941c10296cfe1420761c3b678f9ae15a8a3f04eac8710b5e551370be90918255fd691d290ff475cab5730e17437c10f2205df82220c32b111e9509931fcbda28a5c24e197df0f4d4815528f1ed406a4560d2517636c1628ae47759ac6522b15542ecdc483799e598d7ad443375dd13ec680f3c5d560ef6faff5a48888abbd2d3af05058815baae1e857b56122235731f7c4731556c1a0a02f544498c315d9e3fe3b867944de0aac27690b27e6227ae6e34cb77d66a6228f9c1b10fc2f882a6e9c92debb7732449285b2c05a02b65484ab1c9556e6019dd0a48d4cfe89125d472a89939d2107fbb6d32490119a511449408b9a1e79c7f4189399047b90813a8e6a143bd324600e5221e3518f0919914a1a109a3804436b5f2721d48a2ba8023512876ccd71607dc200b171a80393e1890c121d6d4c48dde38257c71e246827519288d0a6a96f1001221a26fd396ca157d8a4f9105a6baec7408543e828b55d3ad29f97bf953399fff9fda2756cfa2f212761caa503e244001ca71fbf436bdfcc87e09e20ffe6699d1895a330ddf63d069e6b41fb6602aab08a98a434902dacf4226e3b46808ef389aaeb316cae790357d1edbfd20022ac7cd123cb30ab8a7f30fbfc6329bfda1f5509c7e3b89fa96a970faf11a5e718599b3b9f42598f5a072b42d85a17131ef8617bdee634dbd2a2657ee6589f9d81eefae4db9f46c5fc51a043fad3e17cf07bcf970c747c6e878188e73b1fa31f2bb93e0d559c79c83cb97ebec69f54120d59a40cb5ca8faf71796b0ab4a49a28213c8308498d39a6b494eb8b81f96aff7ceca0c6a238fd573095d071c04dabb91ddb7a2318d5811e39b0f4fffe405982cf7eea25741d0e1cab0b0d128a7ecc54c9440a3588c420400c0b76071c42b3aac4bb84f6a235dc776380e83bdfbc7421e5aa144257b96f509bc2be4a5ede2c02d8497551b823f111ee9f0d20a3499fdf63a742e299b3557d093384d865b951799ec1695be7aa7f1a8b408e961fa256e12e016fbd6d9d7c00d7b49df73b18383fdc5b82e32585457c0e11386a6fec974e780be83a21abca1d5100b7192048d3605bf104529a51806674854a360d0d9bb9744cb3153b480c9337b83dbd60477803a8db31fa054a11a4227199ef633fe47ce4f89420df3c28ef569a8f51daddfc4d9ae76d8b89b673967069cf2aa39b1935b4638113281df0518c71e7471026dc01ad00ce600a1d5ef17ac8144830a13ed31bce20f6b0d961ee4e994f9b8cd753c671b6431afc368611502c46db24976eb232136493d08d1ca4e19554247d099cd313e9c0ee62bef9c3e0c5c982b3778374163ce24cab09ecd63bcd39f71617431f0c18563993190bbda2ea56e383ad78e719f5b7e6addf4dcba09271fb7a8fc3d6cf8409414fc89490e768bbbc176479dee09c576466dd0c2077d65f644f08ca8069a6de9949359e2894829f659f24898d4f492eca40488a669db2149ce4a40835d8b5fa8c1b7ba401e62ef0f932cfde877c44d8473533a03db6003f68091ac9d6ed6b9f6daaf97de7cf915b7aaab47a1f8b1c251653f594cd4637ab1588b63e7f45e07848a8d9bf6c92fcc3f7ceee4b4aa45e4c78b211dc685d1de220080db6f8d9ad57a0f0f9699c9f85e40a77239e9dcc2873d014ec3ed50f2cba4a0d43a871ec9e4e41468baae77fd444b4680106cc29a5a5365006ddfb575df729a95770868579750b0ea86c1fdc2dd83fed023932a0a8174ccccc79a66c4e0938d410d77a9c9bcfc6deb857c50b0b25ad494566152041138c1181e5641fe9728a4ab2f1256eaea8cc90963653e473a7e143d02f10dd2e64bd1024f44abf148ef89238582d42286e15482bd235f67b6157e85e926ea287dc6b3cec136a2bbd99ba9e0ac428c9f2ff7fe03a1dc4060a9dd1417cac4e67913de06d0ea50b08a81e9ca7c1e90046d13782d1cff2f008bffa15f96024b7cbd5d09b7161077dd1c08289c4b125d141de5fc47bd64656f2c5530cadc379cbe4d300a1a2ede17af0c11a3c94b6a7a5fd3e49ae3a7e1c99a2d25882fda30a3149291fd7d3dda3478ed6de6aef3b21b6b6c37dc0a88dbfaabf8cda2e0aed6779cc219576542e2c14b65ee254861cf791a63e9157064c3b1b2417acdbbd3476bca962ef989bc60c08fd248a07daaf6cbef455bca0c9aabf84dacb40c9ca6bb60bf8597fdb56fc26f3f2663a8245cd4f287b0d914e40b74469ff9261c586cf202c6d6e08b9af8c3a26a996e66bb34a927f7b305cfb7c11e016a08db190a45c66a7e6e4304877e8999cc132f3bce7f2152f476c44fb1b972ff938da4b465f862baeb2c0d40218029131b6cad57aeb9f253e6852f07896ee627cf4e05fe4fd89f1202a90e37387336c21547248cd2ba0b1e5a4f9173179b95f0a4b81b20a2457df0294f3970ff3c20ae2f6096f5f8b203f06e0129b9df0b979e2f0ef87146f01244c0937dcb4b7d04b648b8c5658a82464fd018a085d40edd8147027681686deefa72fb5b27c5ab2a14b8a2cb7c2223078f75dfaaecf2a8d6e5a037547b62e9f563a3389811626e743ba807d7075ff7c8d159121959c42c0e93cd67442f5fcee6d78cb66d597141833429b8ff5ea79c3a2270670b9d7c0080c59f3482604121ea4ee641a306930699bf440518291969ea15b1acce0b74cf0e7b135a990ddd9a63bcc55b9aa57202866be2d9fb7cb580254528541650d39e04a8e96c8969c97476b0dd3daadb65b77bbd072f9ba5d98f51f2e2380c22c65f280596cdcc860ae87b7d7be9336f89a2a40a4b219df4b259d0674c811950613973016dcaea135cba988126bac77c3c2e32ea48cc74bd24c2542e2553ac18cd80dc023a202f252ee8f2f69f17adc6bef175929c58839e0f8c9fe02b1bb959228e3b64cd5177bd586eb510a8f83e431cef7a69fafaadde1a03f3b6b0b29a98c4a5fb73f55188b11b99fa4de8bd77a894f0dabc0e80bdb135f4157a6b1914b4497c949dbd149e12939a8604b244f5b75aae716a6307724f3570cf54b0632de7c5bd49901f0945a5133428a67a845632a0df591b6fb6086d574392f6320485ec62ef901c56e11fca91158ecf83e33291fe27ca041365790c937e6eff99b9fed982832be920372b76578d83ec3dee24f113151909957b16ac94550f0f23216d23c0902e8ee6ac6e8f1f0e399645b03ec277516bb75a6e33cc35574f4635f6311b0b8a5a74b5910a75f4b054dcd4c99ccc8d0b0d89f53ad849a5686caa6b00052a0402869b9695374baa95e5623857dc4248659bceccd4b4cd3174b4ab44217dba22f69a9ece67b6bbffec4729ce53aad2cdd5e284bb38da7bc9fa4322254634fa9801159ab7bad967bd21380ca0d96403b79431c150418180a0900cef7cdacbbe4179615e629f3d18c364f16bc0c44d6244d0dbccc85587ffbed6325aca500d8bc7288a026e4f11b4f6e01a41ae598aaf0561055d6f99bfb51757cd5268959a7a70db8b13a32c53a880e8f319f276b21cd942c046d4b7252eb2f29990727252a884093633184d5a0d0e8a59813026e82a6296beee37426baafe43649c233a94b47b880fe9abb2b2857e6e3c9e80157542ac8aa9e0659daa04b4efef11c10a410a1f0c718a7d03b9e03b0b82e5edc8f5d937a6bef200228cad5816bee1025a33f53fb6fd69a8bfe2a8e57b9b2cdab6dd641e10ddca2536bccf46ca5c5fb09a7cf1d695c00c1d3ab3237e0c9949e5bb16b6588c5cf4936a78aab3c4c14f640ce8b358d1a66d5d5e6642939bbbd0ce0fc7ec8aa27aacafbd3cc26c41a46fb38ca3426d32008097ed2a168bf141c2a4c2dd1004a98ee93c517a21c9f86fdef5ac430e5a1fd69dd836c708bd562d71a04d2dfa3bf3bb43364b74bc44b33ffe05d2860b1056b49a1e204e9a9fc14a4e9aaa3966852ae278d8c563075a5074d3d06426068fd4355e5d2f4b83b1015b05ff2ccdba43ab7839096dcf0f13ec67938b427bc8db887efda60ba5777737a7ad71c3de31975eee49feea54b019ac9fe4fb61162b3e1d37fdbe337f947c50060232a1f89a9aede3411564bd5691a61e49955e8bebd740a97028c7140067adbae377634060f991f13de64319e08ce658d91710f7f20dcfc1bb73038d785438f0b9a05c417ec66a179ed3afeadd3b5a220ae59003af824a39e581299c82cdd17cd4270b8a8e26af596722262aed46fba15a9b360e92545d2b65d5fc03c0ec76518ea3576d9d4cfc0615ed6e7d1bec6c92198b152236e1a4552c76d6b39dcba2646f265cafa545decb80f56d8b57143e303858a7e1b242f45815ee3a9f6b1ee4dd528618e285cd9e5bc29531b5b21f4b5aa5f47559dcd53abbd2a82798c994ddd249ba59ab6d417549192111623143713095fccfc74544392321e818434497666846508e14e8aff075dd1dbe53eaa5a971c4c00cdaec8bfdf95435134c3e09f3e341ed36c027d1b72e3a46e934ea24cb2f271fc80b18a998022508b8adf514c3d75aad9956d58a3205f3d19849f41b41fd98177e153f43bd7776a94eecb9c44f8efca39a6ac00aac874a115441884a4b08a49192c720bf68c2754c62d240b78d3a9d951fe573f12a30f909db3ecf908040115741ffb8df11487cf35b6220c16127ca59e49d008ce592e6d242a80ff4e1181db47ede5eabade004ca02c584d96fb1cf77a9639928f00082ce69dab521bed78dba728c1f44d26b3339d017034f395e83c9ea93cf08fa3fc1917dfd9b918615d9c70c5bb894bfce7ac940be4631224fe73a02b1ef191b2a2458d0f69d109b56b0f917507288c33a27f1081b4ee28596d744e78b6b68ec9b5188bac2bc3800339abe2cfc74d15245f1504f77342b2d2ebdf355287319bc85ce1e3dc7ac7073f82b6fa6883dc38b22b30bac111de1a0c5759e2648eb6738d7e4a6fc380eb9f5d4fdf7dd13538a06dc85a4a264e3079fdd8e368d1d5733b730bfae6d98d9fc78ed7d23549e9dc3a96dcacbebad124319c5a559e9f5123c8b7172b707e529c9874c58c517c3285ae40045ca0a7600d40c23a97806842e5b5293afb29ca821f0ada2933ef8333334e9197a1918a7a5cddf472d7dc80f815c7dbab102a606b3b489d8b0dc89c0a6faa1381bf3db414aa83bdb8e0cdc8fd6ac459b7a0c1db2b477877e95f0ea706102d6990acb4ab77bf1a244f15f01aa7d53db243f1fbf0b316aacc9ee53ef1851e2c31bd629535c88450cc85e861e6edabf9e45202c6d25d25669fb1119c1bf493bd4081a7cbef15cd7883ff3997f932d7260ae77e803a04ebf4478c23e4c0f95712be8c781ed0a7078c77cf07ab7497818d5202173c5f16db974e799770968cd41db46a06ebd9ce6715374bded27ce22082e04f81b00eeaf6090c7b6ddc0f71800e97cdb7e8787a0d678ff129bb449d874d3a240eff2391ef3b1b40316d8aa09b33f7021536b64509ddb3400a3f8905b6ebfb143f6e9b25f2ca046e389c303b7c0bfc875be4e9e56277d0c930e10867196cd2e000108678855773212859b2cbc198bd02efaee1a91502a8f2f7575b9e2cc8e5d0822974b8cc3f177163bf448c0dab0229b72e269ec46482aad7ff88d8ffb1bc69fb787492c282eb3a1ffbb10ddf02f43a1372c17339610b517b881a04d84e687ee09ed6708decc80ae989c6f7e4640f58107b6278cf697d640656139b612bc4576932ab70c4c3477e7acbf2ef4530f0f5ebc636b3ba42f695196b3a34f47d6941310f99f2f9c928378de7d16d2c6e0c75d726fd2c3e2db7387e94e3491b5c109f10660bf8eb39d78865bc8cf6deb0b89f28f57f23171045bf95af6c1b156a68c101810134d33aa72e39dcf312a02549e5999c12507d8c2bb20553b3986b8d46eae9e32775c6d24720efe731cc6b252ca64b8246f338be4258cebcc42d734edb4a275349a82743f8dca20fb6dc6b1a09d52b37f46084508aaf351ea4bf621c68adee85aa007ff7ddce84a3afda33874fab1d3970d213ac58a618f8b23c632cf081e0101d34e4707e8809d2f1b981072fb0edc06f555510a1c6e95553dcf103d61b43b572c523f6c3f47cb69314c822c3f0b752dbbfa9456c2719d4100d3c707cf7e07758a06573d0023c2ff0dd62b6d3fc0a94c9689e4d600df9967e37643c2da10c4c464347ba55f949d2f9e9b6f13171e7317d6884edee676c0d08661327555e7d47a78089bd5bd9eb49003075060c0f7af02b0d29ce627ef380346ece4f53a44c4f0b6051fcca389e4fed849b05375c48bb3087fb153c4718acd58f698387310db38538fd93d3821f0be358aac2856bd14210371e977907e38e19b34c34b11e5d5ff0d9c70913c942983050e3826c1c15a6cd71b6ce1c90d584e38a3f6aba3defce0ccdc4cb20e9862c727a41e5e779df468409a5a8de58bf2f4cc7d3f393479b209e01b0d7f3135d01db2339e6bbb6decee1857d68245810c6e5ea3303debf00d5c2172bdb7445db9a25505d05758617197935d09ddb969cd0e3fe73cde939ff6d4085f4057afc91ad92e312c10574a564a4d83a6a2972d108b13eae1ad13566205107c37f5c1c93f41000d0bf33724f90e1c89f7884cdd171218d4ee9d1c83d85ffc63aa40209cefc49af792222efea2583dc0f9d98437a8932ce5c4d910ed5a5543bc4bea659f821e9818d46a6bd31ff9b8b8cb49b5afd9a5bedce28ce2b270f00b47b38389e215a8b87c7101011389eeb9edfa1bb13411466a58fc97f0164b5ad2d223a503856b6fb21a439b291ce896bd9815734b6017d407f244528b4ec619a7aa7503bff90f19e85da8756f8b190df8873876666a05c05e7356cf5a3db81245d1cd7994b18cac55186b9285a4e9dee6497fe97b772eeee6ed55a48b9160c2329a71958069c9683af724b0a4de50641271c6eb43c42a6ee5405ea0f070f869bcceac2f0c68e77f24461562ae9497276c8a52050515e40cf3196030c86b87067be9c547c9dd23f0d334d440326520a82d518e67495a2b401c73fb34ce5057b0cfb084f3929fd2e3416855eeed352583183d093bd8593b51a9f0a1dff231c0de8078cc25f196f4acc17225e4a6e2488f003b122a539e7662da6b6250d7d205486902e45ed450c3fc728210754be298f171200b83860554e127845a8ec70d9bb132de37da50339de1d809423b4878d07378d3366a149414b02e128d99970924d2601a66573b792073090af6d161ec8bb945d25e60a15ff0472ec784b819feae80aabacdc35562f3627c96e8edd7043b994a10759b707b81bae73673afb2068f9b82d507cd24f82fd52f5daccdd00a7bc066539c3152b685dcb1146200cb1a651966c09722d495e1f8406ff228aeb2f105d0e363652d19186efdb1ff6b25b07dea3062e0d810991c80a382723c31ab3c0cb0b41b47c6b7269f417058e5344710d58205c19271dc9b84ca6f57070191e2c87b31f47f2278d70019a9e5d5c545901a6e3e0533e26039a56946050350b0aa40c1430702a914a16cc8a054113c29c228ee97953fea837a38976b3bfac90adb584a8354208d95bca1dcb0d3d0df10ca94f47b6246ca9ab96d7ea712b3b7756ea6ba95c90ed2482985a3bf8199e910c6a60eccc074ad014a20c0b589158929e27405286b42a9d0a8c2d03641dd9126ea1b29ef554e0b60c104709673da94f476d96af86ead030e3617d86637c86552037cb5703d6186b842c5f7dbf1d4a34cba7636b96cff0596af89ac4b60df5d361ea186142d457e76fc796aa41b635179ec66d0c707bb60469c6616aad0631359fb58d02b7591f0eda415c7c3fbc83ac102bdc1fda5bde751b67588b313d1618637036748c1f0ed05a0d72806690bb06864a78a0b52cbaa5ae4efa7ee06fffa763e36e181f8e033457831ca039cae559c2007784597d35dbead9b3253372a5fa0b30751720cb5b80a8af80324a46faf83b5509a4a9804aeedbf1e998e73f7941919e9fe724b6e967646c930722b181212b3b8f1e44b06b06888c8545ea1997eaed15835fa45b26e8ce4ec72391d2318799c3ad9965736653289be0d4d994686df789ad01ce3de764d7c0d4e1a933a736b367204b8f5bf15914425a48830d66b73c594676d919e8648e57ca99c98e1186ebe4d6fc2ca21cb7e6a3cbac028424dee7e74f4fa0ee9a749d9edd75bb2ebabb78c842b3ee4da54f07a9e7f7e128ddc4c5ded8fba9d37d35dc3976a29a8c77ddbb6e56efa4f9ae23edbbf98ee4813f56ae44cfc832e7ce65a9331c67783eb137baef0fd457e68b7b35e45ef98b1a72a33e7566dd77ddc33977ce39bbfa03f595cf8742c090f68d8d1293140ee99ef34807fe9857a29784ea667ff748f7a6910ebf6e9ee4fd43bdeb6a3875fabb10eeed8e7ad7a1ea8ffd7c47d2ba472d1432bbaeebc00db990aeec49a84fd4b7e3580b568cd720e6b78639e677c7fc16d91b7b527bfbee25d0f4e1f0bef5c77ee525af3bc7e8769a2fba49fa3e1ce17a938834bdee458cc822b5e87e7a0544edacf345fa3b0be822d699c3adef33bc3e526661b0aefa0abc565327915c5ed84072a93f5e3c65c3499f4fb8f8b7bb7336ebe1ae90ac59f507e92ebe6fb141b8788b5048d6b1c7721a6576e5fb195d2897e7ea8248916e430db75f7c5f9c5457a97fb7e14b246564d4b0d595c11a3e460d5367d590768b1a7237d4ed51beac4e5f19281432bbc563d850391cd0edc341fa8f169575eddbe135e90cd4e23c7b1fa3862cd4df5b6a8b33a98618b8e93dcb458bafaa8faa86b4450dbfc3a8d3c5b3afc6c5821ce323bc93a36b17dc398e4a7367217695ce7d3eb137b6b9739f39ec6aee93f3566705e4181fd9e124dc9ab1fd2c35e466d4c82f5b4bb3939e4d1769f4422109881dae80e14daf5c7e352befd67be7d51510b1bde388edd52147dafb0df5c070efa2c5519f6117356429fd9d04def482b151a090ac5bd4f9c4d6f8be029adeb1f7719f618e71dc466b98ea54a54f494443ae592645e3b73d92475a703efb4a4a48354c511c4b7ae9bbfbfa523e3ed2bb4afa7ee8ee79608c303072495f8e75fa5019daa83862ef6a1f9b728bfbaef975cd9ada142dc34e8a931792c13446c0b1ebbb3c939e7e47274060f265d273a7f362775503438f4422917e3ae9dbd135a9442269b14f6038bb0ebfd3776038bb2369a76ba78f5e2a954af74e3a485daacbc4d698dfde69daf6d568dd7a25ca2d99ba895fbaa665ac913e233f90e396fccce93d8948cf775fcd32b135f6935de1c2f6466c7e9cb19708bbf84c7a0367e496566526069ad5f0a65b4ba467ef47a4e3c7971a141fad43cec914433e3093a2d569750c51ac27401dbae8748883939d0e7728023f721111268c4442b8c5a36f212796a4e70994234c7c7ee4425123eb568e6d0dfe0ac51e2e8328a7985b916654793020666f6cd1d6e08fce68d881cea221f6a053b4373816592743832c924550b00feb304b992338c5bcc96dd32eb1c0335f915dd3c8ce24b2681a99b1b9a3edf216ad342dbb820f3d9200c9a228c5e314733665d17cb1ab28081d524e89307c287caef2469158cc972ce256abf9b215d39a3ea51e745b14ad10e217916d8e53dca0672849331b698ef1ce944b855dfc4892756fc45e9ffd59a00de2f6c60e6d0dbe17220c3f2475ecbaebf8f542ec818e2a8706ba0f3728d3be9d3b17237d6cb0cc3e3ae91bd89d0357f35b901edbb96aa3647eab2d19a487f64eab92a6db1957969064e7c0ec1b985d03b3c76f08a6c9aa5c2a4b54b7a88b8a64146eade46d4a37896c6c40874490cda239ba845cac17e8b546727667c682deac07263931424f2682ac0c34cc86baee22c5b11d9f23eb58394984a982864ba4e3b7b738ea2ba6f81a1e2e5c802830ca7d0bb00994bffd6c4fb825b3185d93a7959126990c94925a52707bb21921c2ec3722c41a9bcf1868c8b1ac0a0d270c88d8c30822ef34d13ba1e87d0f624dea6ebf1d6f4d08d7128c1166e30b2f4f2f3fd60c887b8219944c09488835b29f6c0cd40c74ab61a4d2f19be48a1503add2b1cef04a26061d293e44424be4d7fcd5703af8669ce7636ff00b628dfd3e022bc331882feb83221dc42bd6065eb80226c5877badf8b1a318867a360bbb78053182330302825bdf9763b6d7f19be1797e06e527fbc90ec4aeac721ca59b0dc597ed195006ce0c68cf0cc4a6d32718ce671b156e2da99248e738d2a9b2f885df3dcc7e3ade6db3a1de8d4ad77d351cd7d14ab78d885bfc0986195737a26d885bbb0d6550b8b519d034d5c92ffcd1c8fb0c973ec3ac3ee9d95d3acf879459f972f4422b9563f4d1e1762159cb2fab0bc4f4267338d8b6acf4d58cf8ab61eec52d1c0e96fd645032201efc64401994ec875bcb19e93d67647e9f41619949b3736823da2a83b815853a2281c4fc1196e13c8eb13458c7e7783a1d1fa2e2435687d910114f10516cbbcccbc0950e0350cfed4768038a538461a7338ff9341b99c41ea40f0bbdd8c5ece21f0a14248587ce445cc458c072748cc81d2913134a1e26bdf761840626f028c4a11cea7859c4dcddf4f8cbb13dbce1ca2f6ec54f07e9da570eadf65116dbe1c97a485ecd7cd24d2613a86646993dbd6780a4993c1e832c57461887b359c7298e30458c63b1071e197bd07acf49d8052465b258f6fa993cc4d3af5ef14f1c4ccaacb89e6b0ffa53b5a12b3fddc654574c7f43b360eabb31f20794fef469033abf95102613df26ca9770793ae418d71ea69faa8dfc914142300d0eb716c6bd8a70af3dec67339d5d9d35b2457667936ccec2c0553cb7ec6e3f2168dd22f9f2235ff605040b922fe010f4a6c74f085a737a6faa99907cd9afe46560125c73ad41ef3b0e004fd1844d22eccac98cf4e6b33d611743d14a8a2c275152d4bb0d71b0ecc5bdd815a75022d47b0e875db2977bf51321c786a4ccf6c423eadd675fcde69343438e85b367f2c81730f30932615b2403202123a2d07c459830685e96650ce3b34e7e7a38cacb08249e267e646004e6e8e33aad9d3c06590ab796a34498e5a15efe912ffbb89bcf0460407da48c8f6ce7c69591e7fa90cb4ca88fd883377b0f44f61c2165a48e7cd903edfcc47c7462a91dc9b33019c42d9fac86592cfb91325b0be2cb5e069c92de6d073f3be8b0eb70c2a48ce9fb99b33798d4e184f53aa1c3ae438e0df1ced6d847b0438e09c134a6ca3130d090c66d929781cb041174c73129137f8096b02b4e76c5262b105a4ed2cbcbd984b10a7a1f633318ceeda7e567d8cbc052771c18807a76360485a5fb4e01069f5e96619a1c13942d3f1ddcb5673fecd23c2ba4f46c8efdec44e1e19e20223ec23eeceae214562cc964321a8e2dcbb2ecbd95eeb4b83cba761ca36b554ee9f89b7ef560d7a82ef3e6318f02d8c57ddf7554a0b42bcc8686b22276851cd35eec0a994a92de4f805d54d8c54ff43e236297769a6c28051d6658f416e950c3e9fdf664fbd97c369fde775f8e9981a7ee3c2f034dbd1f4b2928ef706cbee88cfcd3915f105ff63420ca41efc3aca8d707bdb108b34c855bfb8ca86643dcda09a35b8d59682096ca0c0e02f848c76fe440771bb914da743c37172bb18e2758808625583033a1ae00289d334c81c1c8879982333c89515102000acee08219f0200ae965e6a8e105d9f4016d99a0c8093b48565c4c2236a84136a3e05028c9441191284460062d20098119a830628620a0d25042430b8048a0cd99cd8e15d38222c8d16a99152fe86dce6e6e74dbac50e2028ea563132b5e4960275030977ca0053c4c90e084103bb183254bf04c910230c8800c28a042146053dbb80911705178a2e8075564e10643578882031cd0c8269ea08215556820189188aee0763449dcbcc1c11086402004313001059c238627524c8dc80b5c11136120838f15518c40043e01111a8e30b39035c10b9d083229cc396736533d72486b8109f6a705370092420b33100215a96d4e1101153633709bd7d1899225186051508212dc80800b5358020b344c118314304e01f68f89b1011122352f8802095650062028418a986c9b014e366736271515cc146c5c9c1a1298602d01438b26245862032674308548b9b9a40ad4042268d1848d254c464b8800d34115920ed600eb9cd0ba25cd6c495a1d51810929943011d3da789a904063414c4ca6655b961a81177e74a270220c4a20810e704e3a48010ba6a6ad5e6040410a92b033050a1352503949a10611dc450a262c5230810473a6a80b4852a4a0c318156cd30a28c27084230421044f780438c882090757ac0047071e800027cbb42c0a31db9a58c112373043d193276a60580aa88caad044116048c20ec4c0851bf0600a8b200761e839e7cca616f3530506a420c50b528274e0040b7889302ca1617852842661d0c99290653b58749611697162062128610d50a8811321d8093a594165083ca911dca4c0270a8c0a1f9c600a2ce0ec2c9102830d90ec7860093bdf0c6040c44be23383349020075848c116be50851918042f289a4996e0088d6004a35c926ea570a20b2c39f3d6a754e5964cf29c73a295521c25a52f711aeabd54398775b888e755d6e122dcda73cefab04bd61297bc779bc3bd735126e61eeb702b878b7c958be410034659574a5959a7720ee7e41461194ab3333282a3cfee716e9f8e0ec858112849237d03f788fc931ff608b79607138114d3137c4730e488902f7b8ea334068d2897a239a39cd168c4f506c68ed408204570cb07e7c81722d09088ef7d4823800861970698659c318b9cc36d96ca89e544e69cde03c1e38819d451a8062f4fd14aca5345139af66512f46104f330afedd0f0a6e3b529b36d8b1dc1089df99852822e5d88eaeca3a9d5791bdc9affa155176ecdbf68cc04a611ec5a368203c22e178f4020a8832d6ebde7b34d6e40502d39ee3eb4df7be5321f93a74a7791464a3f016ea5465cb7c5f5318149854e89fd2325bec4d6341c7efd40691fda8633a34f9855cd871133f3734e4dc80bbd4d1f93635a85ecc979522e4f96bc93a7dce8923b37cebe912bb1981d048d4d66f0d3dae5bb1f4c973574b1b98104297c6854db8ba9640b591e6747295d60c12dd4b21cf5307eabdcc32d7e01321396c7b3fc47fc8bca4cb8b52feee2e1a9e7c54f957d5efcc5431fecc3aebf5bac9c368671867118dfc0148cef9909bb52ff817123f5ed52e05b03b7513d2b1defd4dfa92a647bdb5e1b7a3b33e9e11ac61abe5f54c952658e8b3d0a94306e49580fe5ef977f2453568b957aaa517b798f54d3b4383a0527b7f6a41d0133acfd0e1fc869d96017cb0c887a696252875d5c900bd5fb8df2c44492a7ec97436a55a6ac7617e6edddb66ddbb66d2110948684b636031a725287a3573d6c451f95eaaa6aa3aaabab7e43d3f21b9a185ff58871d659d5264665fd8646ab61ab3519d016907558545b29e1c23cec55e0aa87eaabafaa4d0d284ce1011ad56f683c2e46adb3515d526f8b524aa94d19e2206ed504712b5616923c8579582accc3aac048c38125309c6d0247678138d1474e99af3d13b18ba3883dc45e4d4a19a3a6d558b91ab54e6a9aa6790c861cb7f1cf0632104be12079166299b6771dc84131a0a4878c43d2d1e8a6d14bdee8ddf78d6b8de3b6111841e6c00cb4b609093d52f8b0856a19026920a8ee323432abbb10e575f7c9ddbbafd4913233be945e3a09d525ae8692a75ba52681b147e0ecaef31ec110f5e9b0a1c38882259880091d23a9e47157228d6af42a10546fe7f807063464aad264dc22109496346ad75e40b94baaaa1d691463fce9a152ab5a8c9eab38702b9a7878749ee0a3d3056d06713cb2a70924a02760425d470485d1464569c6640e92274831243820653eaf1f98a13b42c50794c66bc698e47c3c4ca440b20203881505a7e548a290f58323a64ddb3609e335757a7c88d021ab57c78765939a91e5207669972043e1d6a242796de31f06da21eb0fad3210144a028ac4ec908358dbe86a4c1372cdb2da08031a58c3e980b2f46afbe8dba3132abad0f1c3c1d2a4e652dcfae1d6863cda5c627cd856ef0e367c46dcc645423f52360963284454dff38f94e11e15f7706b37943a58b0ebbd7c85d89d470b44df3626e95ebba4acbaaa4aa48ee42857979394aaaa5681342ab65b0d81a09a4119933a6ba046b8b58f429bcd40502d272775a48c7574d9fa4302653730180152c8688c516666666619eb8ee146e9c5524efefe81dde787a3d45fe9f11b7d0c90342b314689233d1053b285c5a680e6ac82c5e4ef81a44c2a9572710e168bb1213d105dfcc3434c855dd9a9eb743e17b10b0b4ddef41b1aae22e2743665dbc56bc51e78b9e32513b18759b77e6bb07abb1bed0df6c0b64551e2a2681358cac240e52bc2607102b90ab7a8706b885b51b80554c50f9f87b8c54492a954266a010d53cd12667343e36287bb121e2e8e7a18f382d9903afc0a6df410161fe981e677dad7838585070eea2e2e5fb10720581476bd60211e62a248b360ec3925189d50016b13f8a2377076f6c3f6ba7011844209b538cb19d0626835c48bb39c012feafed49b5e1e707bd687e3908f1efc1108c40c1355c2f6c6b7c62704d3a4e40b737c6b3b283946a08429e69c970b3af46e68f625ba72c4164c9eceaabd6a4500b7f83ec40e7d68099b55c29ca0a98e4d8ce848188c5d538645c3ac66b12bd5fc181b40a4749a7faee2751c6c206005422e392c70810fd127fec409639724c22eef0b4276c9e34fc7d6ab1cf2dab7dede6f87bc122f8e4a5036f76e8729d8caf04bc2883dc833ab20070034d7a28c25e7f93555301f72ce8c403a8258e990d7ae494e9362d614cbef5c306cf5cabacad113885d9f8eace53b9642945b55e832b95d8e46a3df34074630f411d2ce4620a783dd40edf18b1b78d35193cfe467e494dbf1db8542cc41a3131fa2e6ce6d5c9665307a4fbda3deb87df7db7771b3db28e2db091065b8189b442ac2b88428b4df70e0d6f60563b8b5b5b8b5b5386e1be178731cf7d15772cb715bfd1189e64f27dfc520a6041125ccfe637b0eda18e08f46e70813b76e7a120cb3f84909cebaca213fbaaca3fa63f45e309cbf64ed5bf6f8e4496c4967e28e63b49df45512b3e383983ad6779fdf0eed5b4d42eec81e6b12db5b23b7b42f88a931f01861e40e5977f0471f81496c12db733f4e7eab3fe6e70fbe90ed20db41b6b9927622e922bbf8d9e53b16c2f5356e8bb1c65e486a5e6bc96f87cdcc5a7e41c81c43b24fc76c52829c96bf69f9e1b869f96ddb6a8c30f20b22ab935bdbf2665bce42ae9680d89d6994ed2e272589443a8ed8a4dff4080cdfa32f18fae8bd068ec0d1cdc6527a7e46665e0a8a204833f871e88280d5fc05018d4e7e60a4c3148b5da14ba4b163131418b910aa4c174d68402436d9a1d271272806c5263bb10e77e8f854c7263b4bc4a220b1a815a3db1d02021434fa0c41e1e490946582b6e8e83344d47bcac323dfc9a12129e31293445840913dd30887b20acf155be89ce64ddb1e768592a799308f462535854a89b2edcba4001f9a358e711ae72980651608280a509cd2f12d1c620fa533cf11cc310f1d0b00a3713cdce21861b645d2bc6d0fa5ce0ccb1ceca007a7f3254ff461b7cddbddddddedb2b7addbb533d0a698708b0fe5875bdab7edf267032550953edb35d9c32d2e9d392e47bef0b71a964009b481f247032594953f120abbb46fdaa7809bd67ea40462ae4a3994c3c92774a986f447d3a48c1c9254d8653a878383094553a8165c0d19875ba94ca49985b8484aab211b11c2a161f1d311b1d0e14d6f0d125c4572fad6a23ed5d16ed116310ff3fc7b9802caf9bee4100ef321f713237fb8940b65f9f041be88dbf16ab87581a4ccd6306a5bc4aec83b2453298da3fc481939c45a11bf6295e6c1adfdbc3171ea8a20babd010e76f081942f78219e4a813a198a4e9c04753ca963932b8c9c014e8c3085ca165c746c4265094b054ff7de5bf2e389a197cf9011a226426e28a7a3cfd0abe3bd31d40a74f205453af462931af41ce93dc7394f50613651416cebd8e489a20bf474e85db14e7e565e400a9510f0e0032a5c8ddc7a409327b1281d4463843ac481a8c31da074d125cc6291dfd157c7772c57ccf10c2f2944a508c7c73525d115513a9458cc57cf39737a9e33a9c3aec92de829a7e446e242b8ceca402590cc420b45982bc41af3ab3248becc673aec32c206807d09d10030ce09b100b01614e62550f4e1ab31e32aa5d02ccbb22c93cd35b4a9524ac6935d41b925832407a5e5b3c8ad20211e3979f264700649995d427c998f82d015e6048a30f3737bb8352f975019242465368706653193a5950eadb373efd8871be8acaeb4c7cea4146ecdc729059542dc9a9f94ab4878474208d7dd9110429bf450ea4899236618a1cc231e28a54498f90e94548830558830568830f347489989c39b333f9f14e9f96d4e223dafd5a2544a06f5dee05e3248334150cf18f9126d703edb5946e50b97a24fad8628fd3b03be7af9327fd335a01b855b328bd1253a6629e7941d4b5074a6ec9165845aece2058c779c3d91d94fe693f98459087ef5033cebd9e5d016b1ab24a9c82a533a7b2735286818817eb43c8812cd1dc6ae9667dfd7e27092deae692c1608f264b10e869a8eedacb3fee51891b6b36ac75f10ac1a4e6e65076bd6f345596b12bbbafc766c6fa941b6b97039de20d0f1c361437335880dcd67719d5704239e9a8756a6cfce36c6aaf43cbf00a7b4a48b0d58d2f5603d78a4598e7ad7c24bb5ceb33b7dbf9a954760f5ec12882e195bab67f7b17a6643af560f697ba68e325b7c59dd636d757ec7e0f6c6a44f0137bdfdf0deb81538418e5bda2918d263601b89eda913c1ae517d12454fbf487938dc82e12d2cbe56b0f7c97cb2272c73c3b367419950e9f2523a7b0cb3299d65314bf187839b03e2f52a89d9da83985ad32eb59ac436d7707421db1f8e1fa96f3588126dc3b96a5064cf70647c33b21ed47f19a056245fb26ba056855bd94ef61960e6235fb27737804364dce5ddf6e5d827bdbd7ebf1df5dbb91ce0ebe32785b89571f397037596772c5e6c5282586f32343a210293de8e7ab7f23490e58408509acff22e86a781486c0751e2d52ddec5dede82d38096732f7d3fac4f730dbd190f677333401c2521f7d50fee2defb24fc7baa0486f6ff97e416c6fb996837b0b8b03b9b780f1fb813b728b5543567335e41939c3208844c62b88c4a5c24e23e332329e5d02a19eb13cbb94c2aed433d5331cb4c1d0abdc71bc5bce0134de61299aefe12948464ccab438cb88a97ca44c8baa1292b4aa847c7c7c96e6047244923f6ed280c65ec9977e43b392d5e6f4eeb2f6b0a137fd86265409f5c6af86070e4ef753c5319dd651cc047660ce0d8dce6aeb4a88eea6f7e84c2fce0656d44c631aa2d17240552f0f4418bef7ef308a88426e080715193bcc43c70dd54ac43cd4a1e68f7692b08c8c958e7ce9c2d1128ea374686814ebed2be308b738b6d37c1939a325cd271a31693ee552f497912365228d8c9ce62f187b87a7a7573edc50276347466c0a19b1e6c72f7e3cba958e94e186e44a475be9702b1d6eb51ad2e686766d70cb8724b85ea691203750cb872b9dec0b54d613ac7968c80d71445cd1e835828d7292e03ac896c51a5ebd1a0ee89420d78558833fbf1fb8b7724359f6d58c2e25a769d9e8c52de68ab885c508875bfc1138828d888c6658bb010d5542279e934ff3bf9f3e01355f25246580902f7c8e5309852aa1ae9e76e40b173b0985110651b3c65199dd7eab27d8e944a49eb87a22b2d269fe4ae70463d7b6f1bcdb72431c11f3c0d794d0554cefc02dbe9482d20e637c4840ec218903618494e9de6ae988325cd7b568d1d511e785a1adc1d7929c6036a05a0d68783ac1d8001d9153ce0976ca41023b4d575bd0d83280465c43494e132ba4305bb24babb6ea57c80b4e683d45ffcb9795f2ff79085d74891f91dedd7bbc0772f225f5960eb73a2d8a1095e5a9b23e41537668af6593875dfbd5208994b67e1b31f2651f03840f111f121ef2250a0d772702b18bebeec2603a51685f8be3436672ae4fcec6822ebaf03b2eb636e33229a594524ac9d95cbe818b4bb4819ab68edb14c0ad9d724e9e2c6b624f805f8c203d9c2e8f3b7fe38dec6c840ff9300a4d407607e2688079d883e0881128845b916e9f5fcd9ccc59c659c659c69ccd6fdb7d7ca4cd38eb4021fc9244aab30751e2d5a4cbaf66548f88ad79228ad0266f9c73ca51294698399b08761151848f091821bf9a6ddb3e1d3a4001650bcdde05505dc42a805f76a7808458c729909053848e5340f9e9eda4efe56499ce4f26abfec0cd32030f10a034cd9e659a0c6371c579d669aee5879a6b53e9abd92a39ec707e316c07708b98873d834b5485b658f5d8e13cdc46071eaa4dcc77a8b1864774c89d0a641a3476e0e1b28642260a347d3a482d4b1f0e98a354b15558d82176a9cedc75b2b67cca9be44d936f9237b5803f665c8996919392bb73cbe74d67ee336a7cc66bd4909b93b29a4cdcac61aa3fb8cfb87cc895b61cddd82821673864abf40f79259a278d77dd4d9be6e82df32d4ba543ee23138dfa83bf1ddba8e5a3770f67dc64aae10ef5e8dc69dc34635421dc34aae9e10c1a97b9e99c9471ddb4215769d49801865d35cdf8e82679ae610e793e9f4d9f9fb585c3ee23d361c0701be6a70fc73cd71ffc96d36932cdae9abace344d2f99beaf86465dca3add02cee058562944e335c018970177b80be4e13312068c2d472c65e51e72cb59725572add6170b343e7a945c3b150784293fbae934ceafe12e8d9b8230f15baa9ce7b8ae5a3e3a7f742964d29841e33c8051c600677c078e3ffae8c321ffc354c3e5be1d5ecb2f16f686ac210668d0f8f6d5d06050879a4ee33a5cd5e2aa2f8f6ab1b037b6556f81dbaacf1dda219e3a5a7c1e478b738b0467d47097b490d934ea62616ba8ce81281b253d74784c90cda267fc35ca198ff285724b1ea3438df2a56564fae81c48bf1aee73ce9b9660f8f6d1fc1630a4dd32414e07f46d02693c7e3cba09bc69a6317a0b1832508f3e2339d0fb088c2f7d35912567803b1461f62dc02582447a0b29b53edb697b4c0fe73709b77687273f6157b83e3c279f8df09248866d16c93eec62f97e9f2c930873ba9c8b24e633ec1353a37c61d5950fef127649976f5f4d9521e7fcd7301ebf9a1b9e6530c099c3ecddfb0cb30e0378cc73f87e00a00fe62123038d41313c23183b7ef1cca6a93367a844377b5ef744e418b9f6a60eb76290adbd19c14fd0aba19f1fd7f5d190a00388c3ece2223aa8571cb155aaa356aac76e7d932ccfc6f6084fd3f91be396a9ee0eeb24d925cc830a8cdd0263b36c0c89d0cb01947c7e41ec213633ef349df854d7c49cc3cc7cce617db2582c169f823c140002c1adbd12ced141caace2234d0e9f5e95969cb3313a8036e4cb3e0790e5647a51018ba9fc0872915875a4e41c6a625e1d2ec27c8f73621089a70a23a4264d3a80aa24d2682242be10fd504184949931d2a0e85524f0f4013a4e016504ddedb7ca1ec238100fc60d60113e648046802ee01142b805132306cc635e8d1abd97a246c59cdc9a21d735f47cb02bd6fa997d4e1f4145706b839801765905f9c5b09595956d3b86c1646558e517bf188799b9e34e1ee6f1db11e33318567a0c2b8c5fa5c729bd582a9dbbddc938bef418151b3b52caa6e49a65d963c0ae8bddf4bc67a0274f8f20fd043d70469e400a0271e9c8ad5529e49af5c3f7cc640aa9e9d1a4c3633e6bc8e5400770ae3a80030023bfe4007a5dc7a5d915cc5c8aa09e0904e2d287f97e2c3588198ff10f0c81b834df0b4b1588d733cedf113fa3cac82f86d588f1188fd507b74c31624c000412a71801a454c39b2e85b3bdef7cd35793d1e9c5735ccc228579098c71e6afc6f4ce648a4ea881136cd031625cfb744427d4c00935e818efd633c58079a42e3e24c0d7bcf80c77303002f062f426810137f6b24936266536c6ad677ec712f52c668ceaf97e08c005f0af86365bc42e148a858a8f35aca52a2c961a5279aa38dc5a8642c377ebf1616af590b678c835cb596ad8aa0cdbef5b9c5627d669b57aecd3e757735a8f7324eb308ff231bef2f8ad6a0e797ee130ab861cc752434a4f9529d8913cefab79f9324ba22a00983103008f5fcd8c9b66b8e533aca2e14dcf12989d410f25843bceac749aa5d3f97d35cce69c4af477064f5f3c7ddf67d333fb478570d3cff4cd39a729fba667a26010d9497073a6fa0cab50aaba3efba405dc5843978edf282b21857914922d141c80a2fcb05605659efc12bf30311e572e41b09ec18dafef342350d4f9b3bbcd8bb3e587230017c051e00fae1b0508f508027169d467787de802a1ce0200c36d01e8e414d1a95da9847ac71e8abd0a2ed116d5a84103a45d8394c3456f513cea0bc4a543815bc125a282c6a31e2e51fc81fa569951c39b9e7100bc5b6fc68c5770b60062c3c40057401cc0d00b00f88302f18f355c798cf8337801af5948730d8584db331ec1d09b957f007c4628a4e3e80c1d2b10cf86cf006303009c5dc1d94b5494d32fe036ea1525c19e9c8391ca78a42cd46fc0a26f384b0f8f8edd0e3170d32c6f79cbe92dbe6afd980ca22e7b5e2daf2272d20321d6d9e96d36d29a173f1da667976058c4a6239eebea3bdffb0c67e0ea7be9d994534e39ebeaab394a352c222ca2f9f2de5dc0683ae7f85e3a83f1f1cb01c4c545d69557777cb5146f0243eff5d9a780d34bcf3e20b64fe77020e3ddb6df02386f82a6c76f01dba759779c2eeb8fd34bf587ea12884bcb0ac4a55bae7a7d0b0c67af2e3f1da8abeae4564b3debb2862d6ae4d6ea935bab18044b102ca757a269049b7e3a42799e3b66d3cff07e4184f152364b0d87749c4769bc3ca2670d5917227f403d8451c39ba615c65987710ac2a891e54c1f29eb0cd2b3cea7010ad9a6173271d038d58e40573ab6e56bcbb7ae72a01e8f7aac21a9597aa8340e1d9df4f8fc60f90deff8cb416af9f8ed404596dfd0a8dfe0a407407dc359dec54e7a1918ba74115cc337ab23abd964aaa57f60ca553af1a97e5f0d69734c0d559f2f3d068cfc52aae1eaf51374b90a4c625bea40fd06f91b6ac87219bf1f3864b97c27c1f90e74697e0686abcfb88cd5855b2d9ff507cbc35505e2d22cf586d7cf481a20bd018c3da3de050c8be8faefab6145202e9dc436ea332cbf1c2e1af50a72a9ff5d04352ae88bc7ff47fc17c62e1bbe8f9fd186ff9d0de01edc970d0ff765038e6db02251f3ba3536d485c58801c68e1faaf3c0f92ed2d53b09e3df59c07815c8720f9cffae92a16c9addf443a986f342785b2ad1f2dc5130c8dc8ef361f6d24b8f6017ce2edd74cfe3b824b686f1defc8c0cb299d8334d30ee4ef4e1f89d2b62477628ebfcd5b4ccbfdb97427ae29cf5d99f7dc24cb9140271697d3b386e7d8f95f565bd059cf2ab29bd05e4222c907316077d56aae1768995f343b74b0f39a7c84b94c5fa7e98e1b4f98cf41e41d32798d56c750aca18e557256670d6be69d03b83abcb205ba94ed0bb8c35888ca67f3b9865c56202d7e7a7c555e0360cd45bbca4ccc65031e9e29e072e8dbc59f6e958f92e461deee2d1f3fe99bcfa09865c167d6cc4b474005b31363ac63c64e5f0103580875ecbe8c035cc9eba0ee000c01c400f8c3d41178fe0f72c488c378141b663c7baca51faca4b5eea5d0a5c1a5320bfb806c4a55f5cfb74b07ac490857ef1a2ae72ac9ce52b67617904599e3d7e46463014c2cd72171dcb4d87927664e9e21ef8a3f4183fbb638f058c1d3fc120b24b35c801b2c8228b8e2b6f517db40089e0d646cad700bb56ceaf1aa8471881cec7edceef36ce6f25c2c7fe8858b4129ce04e64aea1fc889ef3b814dcb32e9508939da334e512e303abd53bb4909cc92832c6b869ac2d33d1240aa10e393e2f6f144040346da10069d96a9bb669d9a66999567bdb23502d469959c6835b516edb68fb1c7192352774e336659665da7d6a4c7c89d7b84d6e73cbb66de3e4d4be6533885b71ce6c4689215921808e3e5b88d29d691f5dc27df1c3360bdde6b8cf739cecbd06d8c51b61c09aa591a395529c99d351e6fbfc4cec61f419a3d073462abe3a339fca3e0257cab0aae3b9b9d2f19b566bd79625cd0876715db11076adb822519190e4abb4cf167ea2cf167e1ac8111a205517743edc967373b6222971f078a6e87a9aa6459829dc1603ca21d07d2cc09c339b5a13ba74ce18234dbdb536b6d108e4c08da4cd39e72c01dd6fdf0f078a9f41089a9ce4c912c807b75602d1a5e10d00346ed3b2393be9a5286f69db11003a7e4d2d4d08a4af46aba18fd6629c358c9731066143fc48236d1b18b3cef33421c82f2808ac0981ae26042d08744fb94dcb505c944cd08640f7915b919b736ef2f32b5354fb62c4a1490dccbeaf26ce928c9f9fd4632728d7cc6ddc4af3557e055d93287c5cf0246a53d030d5248a1d1e5cb7a48ab3840d1aee308ea63b737122e92ae91c38fa8c241da143c74f47e442cf8a64256f137d6836c07d0323d79c92eb10328b2cb2c88286bbc18bc4f6e557b3f2185dd62863321574d125a43b63b692635798655916639c71c6396536a756038e761cb0c100ba088234ec3cc5983e912e3a36c199d27bc6a14b7a4140b771ced07be6119020a743ce07509c3001d421179dfc8048cb7392e32a10737a9726273822030d24c1a1631324bc3c9fe67e62a24c17f47a795146be78449911174485ba20ae0b42422fbb20a69a114d478b310f6b81287a050b9d3d7e526e67b0233df64843d1d89a116eada7317719a75dab9a0eb7b267558b19f100e5d99d03c3eefcd56c971ea0db438d5d922387f3db19a40f67f308876e5370b4845f3656fab7328da6b02bd4744cf5076ed38867d4c3643f7a32fad98f80d815653f0a6217edfd48ca48683464d2341d7685198f1603d28c6847d885d2ea88070ab4ee116e7115097d579465df5947306eede8a584ca87a3d797d1ed5c198837f92ca406c9fdbca4cc2807f165ef03ae49efa9e8bd7cad7c8d78224cd1888724e98993f45471e64be3ae2b9232cb93e3bd88783ade1176c5265074c21d3aec8aba222fa7b709156157d4ebc57abd1d8f26f4787a9f498eb12b649c1d26d244ef9751d0fb65277abf2117095909619624e302c765d159c41ed8c5b24b98b840d9a1c38d499942e5c8c680d2d3938aba7b8d7846b1d1138e0b3133313e915be1066b4d272b4a922981760f7ed1d0ca43beece92fdc0f220d3d8f535dc91b9a57ef29c840320899759c384208110ab217fbb08f066c268f78567213b107fe4e41727afc1c20855eaf170dfd097c2dd1eb4543ab12710a8d12a2d7abb9aef685f33a1118115876aa72c4b3b09c22abd5e9eb489911cf4e4d67ce11cfd23ae269e9f99878c6922eba84cbb36d60a4e1b699304289423e84bc880015118a4538b09c6cf26057d82262a70790a9b9220111c0b57060d77d701c278f10031f4884783228ba38af813b702b561b31dc8a31594ccc64c599afe56a48e3ac219571c6d0f8e1d80824adf8005dd2e19d3c31d2f1a38e4e9e3401a3a313274548b07cf5fcaa8de95e5d6536a81b1aed914a49344b36663e1b363612cdcede12cd9218a2ccfec497f9b9f2f99ddb33500ff41c41cfd3e32a217250a056e8f918b9d0f35da489ddbbba8aa5bad286ac627ca954ba0dca54538f342f4c7701b652ff0b13c5619cb9d256da230dbd8c94f4252291e2b58e128d2a577f2491a9f25ca259aab1865cd3a3ea102543bca38e3a4ee95d1d52aa2b21bca3be8ab5877754a4318191a68b72a32cade285f4a0ef55fc90eea6a3c055ac2b59852895862889b587e9dd87944e3f4409d721f4a57774d2fd79f11b9a893a7d0fd4e9e329fd8b6aa33a7d711b7a545dc51b1a9a172011f2654a20d04f150fd67b6c6af51873f29c443b5b7eb887f9c53096879cf3e221eb308c96fd91323dfd93035312eb12716b16310f444fcee012f9f43c776f0151974a6270373d69041ac66c7b9609d15699d9fe48998dcd5816cb1810695a16065b7d63744b5484d5e3b7e2caa3fb10720c34a82522da2223549f8fb125e2d1527170526739ce8bbb78fc56427467bd477716adabd89d6b0f54e9f443acdcf421a7973e8469e5a6471ad41318a9bf60b98bee2828b017600a84c1d32e5040757f368c437425c4e9a513b172d3bb9513c83bf265fe74e6e9790257f12b3aab68334feb2ad69510f4a7f7f8a9da2889b5c7e92bf554b748beccdbcc534aa4e580d208b3c7111b89538459fa13513cad7a985e2a551b46c4a7b8a1d6e7b57c6d0c36d145973003ca6ea353b2ef1ed3914120348e7b35f70e5c69bfa119dd04aeb4ca032704fcef21e03a84dfc374bef648e3fd8686ab8d12adf6287d546d4ab7319d5b4223cd47a4e4093f00420ee9dc7f02bd8f1854a2d59510fc8e2b47aa36a473a5a037bae93d46379d3eba567bd097aa4de9f4df6d9428590961fae93d4c3f69b587e9a56a73f9c2dd5467a48d921ea773b539fdcba0e841185430839cd78baed0c4afd0441a7e1813afb841951f1c69c10d9a708126d2709f91df088c341447498fd1b907bfab363ceaa8723ee4cb230dc7fd80461aaeab1ea333f76b3ba0234eee70f54706b4ac9da0eb22659de542a9141d12deabb3337ff408ae146ec55627459940c30d5a9ad8bb41a4c707cdadcacd985463a5df6f08aee3d18094a11c72fb90a65a4d596671f0bed5d045ab21ab5f595e8df225ec2a0e1d08821011e58b56c3d64ef310217fb6a7ee8e7c196288c8e3fb0caf7a78ef7a98eeddd0ecbd6ae3dd54b91ea6fdd91e8953aa3135d56374ef5eb5893d4836dd49bfa1e93a50c2823ae691afe620f912776783aab4105ecdba8a935bfc9b9652500e9aacf1c619930dcab288c37c6dfc89215253dc1ba8d78236c46861ad5430522f585ca05aac9ca8a9f4791d69c46d5a362547249259d6185f76599ec0860d1f54a1e6ffa457c750f5eab2c9bd80e24f8ada88e138d826748e8349198ee3601c8c6894235f84e46e427237a1514ef32694bd43d58b237a65af4ab397e643b32fbf3aab2a18b778b4af669763ac6196812a5816a38c5cdd534e86f3d5ec74cd28e1744d0924049e56bd76607b237bb857bd54306eb14a8593755f9aaec23c9aeea3d5ee4dbd5d1de9ace8c41ee22867083454bd542f76e1b00c47c33927a0159ca468fe89676f64e79f7410654e41f285a5cca9e8f473727202c249273cc54e3b2b3a52a683312465ba0a86a3289a3f62413440e9a39e110f086308c65073b8a2d3fc5391940187e42948cad422b0882b6a3e059d822492ee251096a2e9de65d50611865f69106b24e1176e0193ba24a739a7ea34d71648f9b07e38b29a24ab75a7f2300fb22259f5283dac3b36a50ff940f752fd5eaa4ae4c7a37bb75ec9fb0c57d84e2667ddd9ea4edd0187a44c4d515a2b38d4fc281526652a0de20b3f079c0f9a5f9b34bf7215165658dda941156887c60e2b10e7f3d37b1008a8f74214046abeead57cee8a3444994d4a7c211a4374cdf3393344977c1788b61108a415943bd274945374b855d9d980c02d0ab7b6a0f6b86637234e6541f6e4a5dc4a6de56a6a6619d7709f63be5e59cf8e5f8e7dbdb8e39723e3b835844e130265e61bf359f6898490d9485eab219686fbd27015e6d1705fcd6faf72987aded44838c0d56fd108f922c3d8a4b3263d37f6e91fd9ccb26cd7868d989856eb4fa5b25935d6cedaa7c6335a32bb44181904ca971c8eacdc503337d4617062029e1c3a3a2901163d133fa231eea5cccc9fcd991879269b1cb7e4189c9420d6b1890a783a94f1d32c03a8792517733272da392d6157744284ca898993121ca1c35391662725e0e9f094a4f9c473eac9b80d087685dc502b8087b40fec4024dd972768ea5350af74a4cc09265f58b5b32a1b345f458358837f82491955127ee150b54405d3909c60ecdabae298d0132cf69035ff941397a034f4e1d00968c582a1938ff7909e78fad4d3fcf0e403d74ae7d48401ba87a71f343f6e0160a7e91e9e8480a47413e8f1cbbc074e7e99df4aa7208cd294be6241f896113b038d4daa8075d644ec0a55421d63572823a61262d78ac62647a0c22e6efeca08bb589a61d0a1778285aa9dce5a468c5da10ad620d74d706f02bf7b208ed848c408b39a550593ab1edf0d4d095cf5b00142bec89770ba9b567ac293d08227584abef03ff0aa259abf4aa0dfbb872a98ea03cb035f03b9de195e50f582a972544dc41baa2ec41aac1a7222caa86262021000193284561daa602a2115acf9f287d2553e5c17e28deca7f3b92f449916f7c90182a97e7c0839338c760c607ac88da15147d521a85317a7a77508bd0bdec8b244c121f4dd51e010d47e42a0e8bbaf7a504a5152d0f950466ca4b334f51657bae9a63ac4f452e586a0434aa7ab9e5eedf4ae746c5fc90bae744ae090d2bb9bc02efb8430bdf4ee3dbe9bfedd5465f0ac7a742fbd7ba9cad8e12123265fb8ab3088be0a23fb18c034a5cb88ad84601aef326256502955425226d2a88aa850adc3d5cb03554257a0a18c980c1944993a242326e348ec81db1ebab4742823568b9a1fba08bf0e65c4f884e2d67254220cd72129c359115ff8433244d01c5fa76045949111a3127b904fb9e8901b8a5f87dcd0d691ba6e949940588ac67b0b10678956ab57a8c40cb4a6518f3aa66846020000e313003030140c0985a2b1783c2008d1ec0714800a96ac5878549867418ea31432c818024004000000400006d22000716651d58a991ba5c783815edf55694248a5a1ef832b609817dd0715fbf7619e5b16df8949bd39b4fb46bc21677532c977f063e6d180368bbe36e25f641d7afbf6604b3b922d239d393152313a2a78649bb20e6ab1e2166e86378cdda61800b7e10d3ce7c2d7ed9d84b48c7184544d70ba96848dd874417642910c3881169c0c82fd88b92e1fd3a44d455e7af5dd03a513641cf108751dc80d5122eee07881b3a781403a1e2f24e33845421701a6f0b1f90ce17f59565ca81d4d0d704f9e6fca18d8fe56e1e727bdf31dc3a8bb5bbc37fdcad7218b37a08768eccbe4a5350d8981c8c9d9052be246609740c403ef94f787a293ae677d2ce4143241535326622d6ec996dd2cfa68f69f3146b682272a7e6e5a11e0d647cd60d5a855560d84efa282cb6b0bfed9e600dbaa04aa2f421fe876a965fe7abb2a5987d689471a01a1b08327a1ee5ba811c164a6c78d1a6909143c059add74a7190c79ab015bf63cc8d81dea56548a3cc1a55151c07d2b05f4724bb1d991071291eed73a410be372420a2aaf68b82aa78de1b96adfea0d05bcde30ac942d0fd2c42015cf42a9dbbf11d907ca507375b113ae49c4eaa3f582decf9008ae7f5cb449ff0521ff581cfcfd4194c828ae1407e5aa9666cf570b84f93bc433befd79af579e031a77b4ffdcd3ea6df87475866396daf264ede708e23b942db221328aa958961111ef82048be1943b3c2ca416224dd56bac163763861cba7f30ea74202e85472861f7c3308b6ce4083185eb50370a9408b82c29e8ef82b7c34851d83bd1451b429283da51ba43f539940d77b86aa81e85ef01bc65aec1e8443a69a9ed3bd836d4f4a0c53a963b060b228f58c4ad85043cd20b598a9509baaf69e3d892a1332b7ba56d7c4ea712452dd15af2ae746a8ecfca8800efe7dfe19149a1e69cdd409e632a0e670446990d6c1874f118f5536d355956679a4f0462dd4b53d1ca4a32c713c5323509bcea94f834895742c2da0c01a37cc5d74111e0ca13cedf0ca49e0cb182391b26b2105604e501c7435a0e30f6f544df0ff17667c0ce3daa556f1880b6940876873ccf90f24ca7814e494c0c7e4ca887eeac60e6e81531d0aa30a5d65a245b03b5adf5ccbfcd5c93bb26831f19f1666fc8645ddde181041c74f14c0bf9250aeca130d81623c093e69cec714a5132e909e31615abc8f441f2634dbe0336ad280065ee2f552b31acfbfda9d6bd7e42c97bdd2005cd56fcd1843881a29272113dee3a31663f3d7af12be8d2c5c245c9b0be24b32f37563cdbacf878d3f78ad9d6649b8588b746edb958c7d4508cc5a729ad0b79cf8c16dbae8b26d2e85600bbca4add2146e2548cfd60d3000ac02f94e7231b80e8196cf71904616e1212478c8bc614f946ac0148c2aba1398678829aee43a3b85931f366a95f7b9e9be6179d590a9db541bad337ebcc465b621cf84a81c9e8875a54f78c365526b7b4c26f2f324b475b656e80e829812aef47abc36c1276ea40b4716b47e9a83c791db43755af7e74407fe8a94a2132b45d17b961d8fe30526c016c83049367250fdbc070d359a7f21758567e58a500ecc42211c07c6c01b402cec6a9464709a094ce4e6bc29d033bde52f37acdc2c238d8709cd6fd2eab322d7702edf2dcb162646141d8c2646785035880463e659492aa5434c3e5ec6adada3917655c008abdd6ed5a6bdf7e0bd3c83877482ecf3d6e1fefe4c8016f4d1d25a39ea25d37afe456f2172af2ecf3ea3ac1210c50dd470320ce42c2dbc50630ce09446f7065374fcad3af877e0b91b154ab8941328dd95910c9eff2bfc32ef0681aa0615663603f4c283926207c06fd179008391f643fce79ea987a3040947eb02ab364e32b13f231353638ab1774cbbc379f8e64118b999b2b3882c862f72451745dc044edd640b14e885449179d538b1f924280c15963903bb8d57a0118e257fa280a53183e71d243f64cc330e495fde95cd32cd6702c4e8bdf72bb795c46dcf16c396cb9e8813dd7ee22ab8bd892049e42ba89364fc89326462c83970e0c3ef18302fb799204d74b02490e2a4e544c564e6c87e35994f6572965005a9535c40e6e70534d399c8338ed38009f28f8b78911acb9722ef3e72ce5182eeaae9867dc7fd379f372662fd0764382df6944aab1b32627989350b2aafa2fda1cf3dd86621e93988e62318b4866e433b2c045d0b2999800c8dac1e44b3df053ecb8a66561c87fd59db25163a7bef7af02c17dc41aba17c3c05cfd00ed397c1375a3f653c20aa92a95f13287487dd362823e9bdf81134ee8a8975f8aceee61800aa6cdb6e997ee6698c1d64b14b319f04719a06fef496e1566f45ee63e055af9e351b97ce9e0f0706e60e6d1108b89220f48760cf7cec228c08ae94d2dceb2ce5f38b48965384b3154e14fdd36537f47af895deff596ff3cab986d13cbe58452473e283f2627e51b8af1be8c42d2f009c328f35c667cf240a4090888c0722dc7118da0ef7bd766c1d62d09a9c8a1e778111ddbb4c8c465fdd01fb623c9f0df28c9af1d3b7abbdf2bc3b4da9637f47be76ef560a39c5eb80d1244b2096dcd23874dfbd86131fc4db9422d62ae90a1ae0fccf7ead9cca6c431aecac29d6143a8e248606ff6cfd43a12dcec33b598d445fb502c1030edad7e71aff5466ce2c1737f281bed987da4c14f90381a432184342c24c08bfedf18cc8a928fdf473529cf26cf417cd51255c7d610a38c240cd67d2ac6d4d970e73d1568cef119437a97054e268210c907a860fbfe5594f91c50c14220f05671651ff8cb91b469fa3ce9f713063091e5a84c71a9e307bcbd4d0b3ca823307f93b1a2cc8a4a91cca256c8e5051a8248c2aac4c74cfc0f6994a30a0520df5755b08009ac48dbb6a1bd4e58da58dc29a4b42d5a733db9527f78e8cf7edcc2dc05754cdfc815b9d43248a097f615f00974060f2b7dfe215c23816648c69348565ce7b3bdbd22dab95f522c33436792c6652a3144936bead165af82b3624934adffccbc49211e7dfa8989e7792f90603ff794cb0065e164b556b5d0ece8982a880815cad8ca7d8e8da1e911db383e5a2e5202e8892583e73676d66a17584c2cc7d964fb896a17ac16ffed2a17d1430d3dbab1fb0ed29aa76fb0362becc4d09d3c07d6d4682ac4b576ab7fc1a007a5d2418e15769dbe022b9df32fb70bc47f5c4983f4d3af9d36ca908d29f5801245c3602bd387be2e68a6b45a2415460aec3e785c144e4d79ce7ae6c63f68a705e6b3a007ae01e63858c391d031d4ae178519208e9de37a9981fbb8bc92d32bbfa85358fcb2c331b88ce7e3389a1ea08cea0c689118b7f20a8f8fc81739bcd4aa43857a9613be93ecd6892acec018461561577f7d3321b836e63b4f572a1464480f61a373f44a8722a6fb51297d2a459e36cb6cf923247d540ed9f14baed70ee7663dcb4418876eece3f1013e40b21a7da18e367c9e8d4731e8493d5cfce3a485f49edba9dc1488f463a75cb257c19b4dc1f647beeea1a7e39888054cee070369aef067e9cd64aa8af8e664caacd47c70606ce1e027a20bde12f5ffeff7a076dd03d5f1ea0c51e3e991a29278c54a252d570f11e1085d780875e5a3f62ba61670d12d455626e1cebe42d8ecf5d70895cde0c8c724829dbad701cfd79b527f1f5d062e14dac0c0fac95e49bb651b77376446b83396dc60bc3088ba09dd2e08707b5ee72cfcda6e8a72ed33efc4073a4502f7bf8c481aae5fbb0dce3c6505d8ecc49d63e210298fef425c59fead41569aec476e8952bdecb9b8ada8d0ea6f29f16da03906fb6f7501ce6ddd23c6e4b6d9539513d089e375d974822eba67d4812622993959e2b7783002434c96b99564c7dfe77b9a2681462a16054fea73b6aa9461d45ac699874dbfd348f12be0d9b7ef9d3d0940f78b6b7aa9784ed80a8de0dac0c8474f68f568e43c1015caca031f8bfdc36192a637509669a9a80317dbef6cf11af50593df6b0e26c671df73d4bf7d2fd796cd34b61955f1b1550d160a5f1e2aa1db50695782775964a0badf407571948f8c0f33339b43f900d9f736dd55714866ccee45af54163ee4650c730ee23efd6fb9f527ecec22f0105d8362b14f54932a9fcb1387b602869dbde55986c4491d086136ee80756972269070e8dbe34396b29c15226a5bf70888709d55ab991025ee2f4f87ac7d4c37c837f060f7e51f6ca019c58585113282c407f4034ea2a98d7826e773d8c287552f5d3430c6d66d07540466d408ada5182c571165fc945a884654854ae96e4f5756088d40dc2bd3660aacff0b9a9732e87c41e71021759ebbe1625621b02cec506922e53a78266a17dd2e702e87fb19905dda499ea410085869b0ba0232a1664bf9258c2157f3b0a1de132793b421fcb7c66c4a75e878a84f4f57a443933b0c75ca928375b051519f50f891b34ade29bf468b8f583bfb3f6e161ce6844986059c31d95550420954241b04c7c8badad349e6374e5af5775b3f721db9c8a7d576ceffd12182c9f74ef5c75f9b51c3fb92425d16576b4f87770fd2490f57c5d8220826d940882735c12ec47a84eb09cbca57041b072c63bd3ab5d04c446bf2fbf01e2ff6011962214c942821809cbb4a5ead8d58cd8c771730567780392305b7dda878d2cb8c3730616a54d62b76262000da8c9a4b9a2297f4f387e6cde3f90c8cf10b2be6f5859004dcb42297388aaf788b068caaabd5b4dfa1575b4a25a675885a1ba67899d3a4307d8f5cfb0f3de0d47eb343523da9ab7b161d279f52c1354b448a43fbe9eeaea620dd2519ffd2a9c4a680fba412be20a137865f7c20dc502ad18b71cc6344f127d1f9e05256c6898329a877e941cc7c9eb070390f74b0d4846891162ee8b2d42438f2afccb862807fea190ea78ceacefb29cbec9d9aece3201953a0a65b090f83da2de304c4a27bba56a845e83a7b5f64594b65a1f79d403aa30e778fb00e8cbc28eb6df59972d86379bb91af3ff6f253201ea5fc4957ee0651ace53eb00638d0e7d3ddcc3ea6f68538d00bbe6b691d994c3707aca61c82ebf8a3b760a1f5da639cf2283446b8c566936430949f4bd11cc125367840c2d1556676b1a38d4b009c4034fff4b82c82bfcdeaa689ea7212e367d1bce1cc122c180bed3ef488251dca961a832ba4c7cbf970bd57b6e23251f6ac750e0062358bbba57625964f5cdcb5e6b12ccc74f022b64b2a4b1607c711ed64f065991ab73a165a0605d3667db0609d480b9c3561068c88f44049d71045046b8922c9850a02b8210b40d3b15f2b1e50063f8ffe7142cdadf1ddc7e1f31ff352a6adc99ada0c9f4ca29f63a8abc62fe73dcb2ba4e860fbcbdc85d4b3dffab115f959fa805cc1bc852cac7877e089310d479c56086066b3205590155c56f121f6070346c75f51ec831628a833c21e400ed1fb36bbc27c28a2d7dae60d92052b5ef1e149b10f82c0b7a77f10d1bd727f466897b79b2d6ba2b0c43e5e8c8a2fbaf0eec54080e7dd8ab0d9f28166c8096681ff211af772fd3b5e4199f61a3e420583d2b821d71726a4c5f97305847f74817a6ba0ac79e8154b3db7490e1a2815017cbe6449f4907ece8717289882355bca8dad95f768fd826e021915ea6b47796ca5bfd8317a55bc749bbbac1b3e74ce6b26e85e81a6ddce16b7fb528962b27bd3a8b3c22ab69b05ac6f0be5ece70e7b6766ee47b32ea6f8296bd5d79f07987e78c45928cdb63a30d343897f50aab1142c556298509c66ea3b740913674a1c47d400179c5296985db6b66d273731915f28416710bdfcaac46f04c667512b842989d3f4329c86291515e4af067ee52ce0dcdeb90a269eba5550c2f3a10da60c428262c0288efd6ef513918420e7524bdd0e479d2a9a34ef1bb81ad96bdf915e76e878a94b1bfb827d3cedd732e51fbbb20aeb16c9d09e6b1c957af6a37d19669d60d10cd23817a8f8c5801044fdbc13f8744c0ea6e4834b85cb4716ff14f8f23c0a50761a40d78b5b2267238a633dee7f79ee98f0f981ae8b1a4f85a1da7bee43e3cc61690eb97621a8d20bb49a750a46d28b1cb816bf1cfb60000b4eacf7c558df4b4a26b3caa8a7892b815439dc8e18d503a85c00d9064d3b0b53454a2146564111528f73c7f18ee253537eff10e7df68e9924bcb8199583f2a18a69e06cc171d0eb5f2e8d9578dc529295740a2877da3970190c9c0914fe438ff322674f934ca02a3cef83af7c82129e8fe29b7b84b35f765c47dbdf03d4679628c267a0e9aa44e5b1c87ec8fb29073a3474274575e1673339cfb4d0b81a1de2acc07561088d053a47a60bb18f22dfe838204683aaff34490efc08d917a2fe9f44310c13a349179f2af6c58bcfaa826433937634b745de383e367fbe4715727926b9619bd34ee87c2a77c009ea04f0a8bd5764b07b0aad723380461339820e68513daf0b53543563747942f03911648202f7430909be4934914195760c9428aa9143b53c178f2b68fe7111a32349c65686cd56508694e7b3d897b9595e8364ea49271cd46f729ac728db598f8ac8f18ffae8081225cd5047e2730d123f2c485df1ed0b8e5a4bf817a125a03725d5e1a2dfd043aeb75eb3803b59a3a67ac01e5b8924f889b42123ae4bc3caaf05c693ceee05b8f3487882c6e6cb624220d328b35af748f09c1201273211175a09a74345a3309989e502c044c2838677ec00d901638ed3ae05c0ebb63c8e59d8c65d435ebd129121504be08009dc7d08960e8b36ce6ed8dbcbfcd86eaab5444b07d6d986e2b3548d83632dce8556af43321520ede504dcc823906274a93652bb78b04606303b9553b2e74559ce54994a859b6c9c52806521819c34d38fe67fd11f539ab518a0a86853eeb621a1c87911641b9b91111a5ddbf0aad9b31db326fdc49626c9c9fc63db90b954be723d74f83049d2b3fc3a1f07d1b9c32b567ce9b7a294107051405e8f5d0359291c8e3f76b60c5652e158bad6a878e5d70e3b28a1804b6af5fae2cf822b0d44f223bc471ce0154d2d1bb166abbe0a2038fb0799ad35a7802d6ec32070674c45af2b46afa74198351b628c158f663c7c9a21e9a22a15edd794b95a624e90312290875f649a02f5a03212fff74046fa11095da167a501f305a9c91e60115ffc73cf956d4dc49c0cdbf62ce4993d0ffd739eeeef57daee376dcfe7310e97e604919e97ebb4b0b5e803828181b7c04a15590ca64466967924eefa4a3af028f471cbbfe937751402ce5cf825b358f73d6bfa96e723e31d111b6e300e7d08404192813280cc7065d8705958495a2bf9ce7391e9ac88b891748f25e40dbc0b4dae6ebac7b8867d8a8c9ea96c75bfe4594e04dbe0c4200a8805212ff4cdbbc1c71fbd79269d48e9b9ca4a1dc60e6bcc47ae85c1c52c2c45616a9bbb50dca357e3cccaca398b3599e4ad078f71752ff1422cf2c2db87ca6935051bfb6264e6ef901aa75e3ff3c897076cf4cb0684ddca8a0c5d473318003c1cd3b12a743b7ae6be4d4b674d968a9b53e3c1578aa32669de694514fba140ac67bd3331a202488c74556fe59b049dfaecb2c2745d4d6cdf930366742900a05c852a04e57d0014e4931c8fff244ea49cd3bbe71b7075381cda92a5846d599ebbe9500468bc9d992e2f13a0e77b8c91e2254dae2624d14eb58e837c5bc93d712d4c896832ec3668008a9a45b8138c10cfb4440f31c1e3910ba4307d3afc8f0207e2768205c20411d035ff8d293e07827935e4dcf7224c2390a72fb243201b023e9d4b0d970c7e487c33d468876c69738ad53146b9c3e80f4e3b9540fc389f226192712a1f93a705e64e26c8d45a924f5c70a258570b1f9b16a2bb69ff2432cacea72bcfb9b68ac128182eb1bd44e85ffc486eef12dc1f271add8a2f56bce422762a8c6b075a94baee21f0e6de6e860516ea560f94e06cc7e161b77e3d81296462558ff10390c7ba1144f86e96b9b525cf3c655336a20027c4f0e09a081862c21dce2849835e4a0bc6d3a7d1593424b4d34cf55f1c95564079ca24c58e95bb80b47c7b7f74cfe751509fb93c835275926ed38897d4a9503a84cd3d1095547c42020d31dd3b0108396961e8d78460e28c312b9aba40aae9f3e6b69e484c75420eeed0537476ce693aca8d87026c435421be1c074ec236ebc42a105d656fc5777f75df83d24255b850b1513c87ca34001c48efc726a043dfc4cc3de2cfce5259a66230a33bb70725304e87d963b27498a3a38a314cab1a990c7daef6876e5e094306218c02b45d1720af91e722180400b77493f6234ba4c413ff5f00f19200ed7bf52419e1bdea6481c47b1ce09a1dc423c58531eee05c6496a664cdc5c20f67b1094f599d60feb85153390c7cca70889172077ffe5ef109d10487f57f44a7b887e82100f03afd04d9a281c6428e5639a1716ef4e0061615e38f838321b5c216d30b01f94b31f93d7b774ab779b39431a8191aa9237be31c88484ccb0d438c1b226ca8998b0a568b2b499f012aff48ca1145b08198ab3c62d66fceb2ba780b8e03625fac45f523d033990e29881ac91bc9ad41e531dfab1d3a05c2df39c7fc808522b7d2cf488dc39dca2ad61d3676204bbd8cd3a99c8c7aece83ad4fdbd35cec47c8a7a5a8e189c9726347871cb316de8c26dbcd73880c756c3b19ceb383dd327fd7a9f85fefdda04c20f588c3efe6eddbd90f6f8f831e7d15f223e5536880adad0374c747bf8abb3e64027e994d08b0debf9c3da03b6cfa0f2478ec2ee38f5bc476dc8b3102dfc06302a0ff83f199cfe0e7b1ba1f4d92fb3111cfc280b53d9c2cae7f3ba51cb1a783cbc0d8885173fc3fe8727b0a17fd4232c11ee2ba7283c1220d0549268fe26490af6ce616624f868a97d0467d39b904cdee5b6454d34c7e1d4821cd12ce400d3c775924267235395106d04e04c457e0beb727cea9fc50fe4866579cea85772b3f915f9727c2d935993367fb4b9256fcebc958d230b7b1f98546ae82a1de1221976be2e898460297c68a44de72c2f0823a58b4e41cb4fe958275200beb8e9be1927476e0b9c1fa879fc4497ab2aa7bdec905864b48a725094081cc0b5200534b21a8acd4579be1645586e554841a659da75a0fd7849335adb87c61eb368e76b7582b8bbccddcbf2a2918c567d26e4616aed0662fcac2dd61e7508555e2c2d9ea1013fac28255497366a15a30696f105759329a584a5680500b85d485cdade8e2d68355946f2ff386fc85670809c1b35e06af95f291c2c07153a7c35c0c4e6477aa79ae74220a316aa024c02d828a64d4f65b1c38637a21f1715a4ac029f8fe17134d61a2bed031c69472965721534a01052450b9dc007ab9a8b8b88770b4341088277dd2e2fb2ac326c52a8e06649317ddd64640a6e3c280b30b1a0afc8220f4a39e69abe16076776790d5275b72651d7d1a5510e64af4c710745201c627b946d00cb106c4642f165d3d783c43abca9402370573c86221a5f98490c473a5dade32e4c0c786f7cb7729e7ee56ae4993e8181459a93fd73d76632f657e6e6dfe0ae506a4443808d61c6f94d48fc42d310377a618772d4856846d674e505729ea04b21d0c5c302a8009cd4611049eb0f8ac77967224df592262e721bd9cdb32b2241638303133812db4e6430478a916175ea30d4ae4417df02ed69af387690c19f8f03e92df38fe0693e46b0a3bcca5e9bc57e35bdc9dfbabb0a1c00b14b833a5226431add38ac34301362ef9a908d69b4444ef916b05931501dd9624aaeb1e45f41324111e95d64ef430592a39453063bccae233d7fe2af1f592336a46c4897bbc9bac54c4fdb30faec6c9abf6a6865ed0ce3e792a2ddf811396d75f20c5d9a1e4cc2c764a08ed533bed3d771df9b80ff341fc9060a59e8ec67ad8447375686652ef7a96ba9e1ac209cd21caac3dedfe8868149bd9255f52d17ea51444805f0dd6c064394312d5f512648dca17c0e99890e2df3b89f3b8b600fe5152e3f401254d2de3e05a10a3681989184606a560f1b55385902f7d96bfa566a2865ee2109ee2480eefb6d988489a2e36dca33c641e32389dbdd57d483a1d349e2e308944a0a4410740668c79ecd6dc6fd42f31e2253f4373aca26b55d89fdb8ac8066115f068df2f52b32c4a359047261341a381e6c7089c3a9079fbf32cf526082fb1e4e519202405437ecd8cc8889845f077db080fcfcfcf2dea417277ccabbf39a2a76ef6a40f67d8ec84a196c89e3f10be7773dcd0d2a28512f448a2d5461a3dff4e267fa2ec35bbdec73ce70e4eaec46418f8fc4f085de08d78c6ed2c19ac43f500a453f2a4539fbb7a0d7ea068473c0f878011c5d01e741e7e4417a8d969a09cbd954d15eff2006d023e0b602502e9a0dc10f3c09251920189ba496bb6251abd1e9742563293135ffc70e71196b36929ac7a62813b86ad998b5323881d45c1aaa822a6288dfe0f10b153cc2909c3ac6131d0dfd3da84dd5fbb5bb06ca81e20601a820674f84059ca276a2ae8e8a4d5335527e4d23c45fd241a93f8cbdaa8dddb24d6ab61eb50d9a92b28308ab7b50105e19deb6092b0e49a7eb3ed8aff0897ab9ef77d5b5a8148c81f39d6733b0334d6c4f9475008f1637cba441c0106ec2ff359d7fb07fee9cd1e09059b637fb85601fa4cced8f491cca459d08568ca8d464d2d3c066735d6715af888c00bd5798b6af6980f821c6fd09b168be8f3640620df406f7faed61f963cf66e8bcb420f2bef028fd5942d7b572183fb178d5a29d8af0694d6a6f6f378aec7a364bc1039315df10b320941d97c3106f782409971d2068acb6817434ddbadc14ed875f7f3dc3653eb55ccff0221dc7253f02d99f0af87074b8b944de1d8293b0a48cef52aebf8c593653538a54114cc9be2a1ca791e4db526f844cb289476068fdf4ee04791dc872bb9df07314cd4bcfe3d9f429de042202ac6f867e375dc0921df4e54308bafdebecf9a7bafb56bed1fbf7c3e7a44db2864f7ea2b6a7c60831c2b9015d142e3372f0073db7f64d6cef6380361d9e8a5c7d3a61b346db1231144790ec90b2056133b9a8569e9f73ee561e87de6748406c9ac9876b0434ef8e90ac3ae5a21897f995f7fb5de518205ce81576fd3fe19aa22a0af04c0b437964479a1ae34ba3adbde200bf1e2517eff908f23471c2b7d92314ceb0054cb35531b20a43def940ba8938545dcda7eb83ee7b2020180eb0299592e130536fd0faebd20f8117eec44093952620935fa00fbe00a80c425ec13f95845fdc2c00c5f3c0a9581e7a7c5cd81e002e8f91130efc33e662f81f7c09fae827a78a5763536685de448eda93bd42106726d3f3be2c79638ca7aec8bbcb035fb3caaa32309f685246ed6cdf51f8946bed1bb2cbeee7f86869a676e676d611c5e0bfacc3889d0ad17e67ce6e66191472f7ed03baf15cc9a33a2418f248e0d59eea066a45cd8725599d80f90b7a22ea7761781d1977c6e397045c6d7feb75938e4b9708eba1edbdcc5610c237e223ed7b68c55a5a23f2555518a40524e9b07070adc399314d2a58ae435eba0c00292a26110bbb9f973e1ac9d36efe92c5480233ecfdc25e0d1ec1c16b00011f8f8715d50ae16e37fca8cf682abfa0aea7cc5ac252311c191883337757835a9cb095db3f36546de2650cae42b38a491fbfc6fa088e22240140d670b8a4f3dc163e2bebfa9bd4ea5b00603460023fe52858f431de2ef8a1cacf6b742dd74098a6e2253e0c4234d8d167a0d5870b945bd86636e87b4d68464c14fe11814320ff8ace0d6732625d1c3c1028f9bedce183d34892cbb1f5775297d8528e69ff9fb916bf3d9568ac46205410b455c6b396ece00efd607e4e22e9781118226559c878c10008b1e2993045a7ebbf86c7ef7cf1da46bb5572b93da070661bdefff3fef277cf2e5efccf46102f09e8801cb6979a663fc67229383f03e8bcea971ad8af4f8f15ee551c3dc751d4b48a1c9eaacf4cb02fb40751920938c66a3af13962c9a3e662969f9e028b47a67029b44bc41819745ed91167cdbd8e737262c030da3b21e731ba95e6a7dadb6fa65e76a8b0622b4e786ca7ad946665d84404573db81d2919f4984bd29faf1a029375825c2b06c1071874b784e86532285ba28450ada0438c6550999b399e565500ec230d8dea52582132fce62693c7410fdf5c1bfaa836c7df7bb34ad0d4917f354bd9cad7de66934e954f6f9db919009b7351b860d38c88ebb8939511dd4b2739f062233577422da71d5a264f7344a05ed2f0a614cfbc3cfe5eb9891c515c02ef27bb3f8d1320823365780d15c96062caecf4e2dc65994155cd9db4d5fc0a53438ca4ea36f4f53f069eefda3f626b68d73007e6d2ddf8368893d2bf443c061edb3427e0cf044cf7aef3ac715ed2636833c2b3a924b8575447d3e6862e1e57dae9874514ea019c8d20889a7df06dc353925224a83c1805f8371db395b3749d13daa8f89d2dbbe94e9496883658906fa9c409ffe29a52806a0675fdbcff1d6d0a36e5a55cf7a68a712fe5d52c6bf842ad9931a78223ad9bc3f480f7f506421a154af3654e4888472fdd00a738db0033a5c3b46accc775ba34632cf56a049e6e9885eeb174cb5c5f02fd99b3416863a5b84aa48173d89b8edf24ed32c21ace360b1f7c819cf3b393c4e74ac2d925c67d83707a009b51492fa2e2e6a89ecc759ac285232f14448f73dd02dcfc21d42593b04318bb9a4d2d65bb23984410c1b836e9fc2d4f0c89ee5f1a9dd341860f603a9c308000c3db1a5273e252a61230d7ab2980a5600a768b486ad9d546123c064fde5b1d20502ceabfb27d7282aac908cfaea0fed52d9b48a03f87598a7c63e7b95fe2097cdcd1cbeaae91c32fc41506582a0a7eea8aa1e7134319005ff46152aeafe044e7efe81b8e4b26efcc58d2c707c2350fc92d6c7b4e6b1dba2e97778bc128dd2deb46138ae7a0921c438fc2fb3d90c29d21b6cabe4c58a597fad6316e5d7166bc969e6200e5ac8285a0cc1338d4095edb9a1a7d2a5b8f17c03bf430e9906560a7041c02a4de8c2cbc6c16646a4ea7398b43c5c109558a460bf40264c4a37fb4f3eb389fa05152ec789baab1a81287408d7cb147c2e80e4b19f85be3cc7d0ebc026691d9ae1c3476ba257c1fdafa2621ec0bb8dc8694a1c4dec6954cc1ae259c4bbd0a67877aa7abc2de6e9bfd222563554788a45d4933ec56e8da5b1c9986355da863c6b02d6105eeb88b8cde14c8eabe2cdad61586fd190ee152daa467c5864e16b8ea4c757a3c0c7d6272b2605bce2f9cc6ae8b8653f69ccbf7a2a8978230d8847d0fa81678f105b05ce8100ab6103f24dec7b65f6238e6700cb88aa20f3d800edce895936c0b5ab9d33109f9ae01fc55a2df7a46d4cb663c14d4b419c1df5b1eecd950e18015c3b31926144890857c7d02acb36a84b92a6c82e4001fb524e6ca1b30d4b28b2b49baccc49d3aafd44b7ffca7c4314b33ce7cd3932cebf42d2ae19eed96e04d9d7d043ff95fe7f490c32102a259de82069714f2730f851267947c744b8d63c888bdf021d3204d5762e2a6c58200ec71689e4bb0c1596666a230c169a46898e6cc2d563e0bff5576914682cf955856bb50199e94ec19de9f5f09bcb83deb0885ec4cfda8708ff7ea1d6d72ca9eb2eb6bbd114d209662fee89644b01dcf7539cdf6dcc82d60815f033cf6f63f690dd82f92838648f0b45f6c144f63f827e1a59a60b8c485154f190013128d8b5eccfeea002defb0e1e051b5abba9f3ee7f9c05735061f9d455b0ddfbf1a4cb0c5960df1b172e4fbc177b82fa0f5824ead1a17dd37e867c84df8b1e09953c1dd89216f15efbf0f9d14409dde5f2e6550321ac4965d513e4e9d9776465f990c6c39c46ed631802d00b336de1db69faeff26c71f52056c115b4b905d173d5a1f5bf592912351bdb0c459741416f26e7035a542c5093a96d296cc2bb7dcc410f32b921854d5cc49a8778faccf845b820d8d7e6a36a12a409bc7e7893d276dad05ce9700dfe1c4fa27d33c48ccd9909c9dc404aa94240fecedcec810fd0b160cb6a8e1d65b43326fc37c27c8a3768b61e4b03c9a90297d0a4fb8f6db3669651fe43c82680bbe5a4da92f344b46e8b34934390609b49803fe7ed84dc008f1be3e5cb674581214ed1b352034d3af371ca98a84ac9a7b90b2967a005ad0f8e5f09c998a24ac95fec9445da59bd5b4d27af7817905b074685f3e9517810c642b9ed9d415038dacfba6409e705ca7cfa9e8f0b311ddc07186ec9117b5c24ec8a474fb6404044c3b7f8ce7e78560c03bcc9f54ccfbce95a02a3cd920f3fb2a80a822b788e20b72b47a4cc72b62039a1a64011062c68c715dda8d3f3fee3078b88ed986c44d9179f9110c1310ac4120a037975c9b2d812bc7c13e9e2ee684f7f075c45d71ab8eb7186133aebdf098f9c428e700d1596e723e62c2677f72237dcb5db54ab8141750fda13e30bd6a9b394c0a8c39b0fbb81db04209831fa6ab245dd25b9afbf03bac9666e6e70fd23194fa541ed6b3768af2018caaf678e5d6013f6a26ee0a6f9ce3b88618b322798e23a01b00e8a035e41a488426642e2ff9851fe5819af854035179b0b477877183cd4e34be682bf5ff88b81f4afde2e0afd87bb54ac8bdc3df2abf43eef63f098b53b7828333faf9f673e11d26d2b12cf33396ccd49312a7100b63c8a0bf5c0dea3ba3c6368017d3548a140e78eba558ad2dee41e521206c7ac4b28d3353bc1d6876c3197ce4887f668d885baad49e633b26ea465e006dfe14ca2fc4b2d7b40b41cdef72c5f22242833855d464b827eaec30b0c1b706d18a50be04505185070b06f9f1b6a5f02e468e439b1b807d72fe48ec6a43b100dbf53046fc388482d0eacb9b859a5c139b15ebcc281844d2fd5bb66fd2b9c68824012eabd0fee4ccc57b76c0e66b87bfa22a546e99f6618ac0ad1dd827c3d9075cead4450abaa9b8f75e778ecdea43c9c5d39cee154cf1dc0f43730332479365c1817b016a17b30ad5ac80354d47f0a4e58fbd044e04792d551241c6a8080650445591ce7466ab86d3ed36504dc73a60a34616c58d80c1b4e1ea7132c806e3d07811c0c320320621d05972c3c6c1ba041c6bad5069722f22e3f20abfc56425fa1d7b82422e8b11c9e6ef215571d7157476f9438f52d52ea2b10d0a5cd491a0b9b931be8ad032710dc31cabd965020124ea1c32574502984f30b7a630c6ab0701a1426831546d5ba6c87496fd83693ce5a24b7d61589b1edc78fa1136549c60617c4880501a7deadd3e7f4c40701c17af2d7586a5573f8395bf298c425c44f0029c035444a7db627481784a5bea1cb67dd6c4c906e1722ef1b55130873936c195132ec7ce75233ec562f5424ec5061a81b76873297ababd39ae3c9304f86e4d6a431013678af75b11b656f6dffa7e40f11f5dc2d7013f144c702fde7d50ab60dead830fc4fcc06c06cf775ba33793f88b2fd058ff68c8ddc1d054883315f0ade411e366e348bdf958ca936e73a3aecc3baa00588c430d3d0115e2b50885869ab0bf2906cf2ffb10f80eca6d203884451b326638b8f220ac518b0b7fb6f52b496507dc5658ca5bd485503341932ae24e18bdc65e7329c1450285a7ce98cb9df41f0ef6ae68b44574c5e77cfbe3821ce909c52eacd72427b0aec0381e12a9c3ac895b45a064cf24d972a685eb4376acb2d64e3c4ffdff17aa6cd33c76aa9ae4b81ed65fbc1f3efcd11050807e83b4ec90a20a3e42132ad20f1429136e504e0b8982c4e58d609fd2860df5d59fa92523c111ada3e135ff7a82a9ca156e364f2606df24e86b7ddd005dc8e73e8728faf6582a595ea95e00bcb5d9c8484d69a7fe509d72b6c9044481402824c683ce8eaacc23f5490166c04dc2047516036d010cd4fea9bd6670f158d8c4d1494de2dd2ead2c6132053d76cf464d12ab7a031f7f888785da5ddd79040dbf8736581d01cbcb1b9f59a8601f0167711c834ffea685c5cf30750cbbb427f4c4b4df70cf53d3cb78b4aec4d371667885bbc48ad492ad32961094c98f407cdee8b8433080365b3c84d028a22de69cf1e57efcc48f529121820a5932b0419d206ff9079abc1a09bee5e8270c65737e238fec4130c6a924d7b2acc790321860dd3435bcfbca205ea92b138650f17a1af1d3bb18231f600d7f36c011750612605e90d1779ae3ce93f6c5d06e6167defecd55b6306579f473b0f1653c3083049d1395343d501c8bc53443b37d8b4388466506e61cedddb426c2146f5498cfed02d2005c331308e015852403dac2fe7eda70d81aec286d2918c2b99cd9adf4fd8995e6741194efce7c7f54f33dbced27c15a812c226ec0c505c6c82b5a2c7baf7373ad0fed3e6ddd1fbd6a66fb6a057970a79ef5838ee7ed0416a61e58e7e86dcdad1dbfabfe2f4dfbc2d04fe06ace2ad9f4e39175ff33ad7e22578f216d430fbb8f50019b897fde9dd389b56eda3f0049a236d00513c4ae9a1b03569feea83e3df40369a8235696d9bda080680b103ec9b6989fed401e65c5a577ed4254fe8875172b1ae3a2bd9dfc1cc293fe795bd7cc3b86ede7744cc40f1f6c101e747b7c3b32ed3926de84aa5405085448d9a69acb0cce88c09664cb80f90704a6760c2440ae7712301cf068b8946424fec89c1a703b6109a82d29ce180e74a59bf637e98702b460a0e306039e8987b8adedc349992882f325276a47b6a1e222245ce972ac8d0cbdf2ed962425a208cc730aa5a7ee6595ef4c48b6cbe1477969f85c864cef537a1556c1d874d081d027e6db8b4f34a07f988d56230f320b5688f6fe3fb559d9ee82158ba6e27bb118c87d51498a8091a01324184043dcfe2014416ed4ac1174b04dd25fc3044e3e07fd99ecfc0856076f95d555ddb9700baebc346ed219b45000b2693b944adc43e0b12cd5f57a8e41cddf97abd5b20a14671874027f1d6c9c5d56315a2f4474c5c51dd99a2dfb63e13d0163bad86f9f531ecc2b719d656a926811f47812dfc81e87220b9fc43f31e8add317591e463b0814fbec4435d50d04975818a13d48324bf133bbf39a018b2f31070594cd0a95ed9ef54dcb430d606a118f8dfc6530259967265d561f215334e4e303fcb5331f0306769808e7292bd82f328514e3297a37e9f7c079d13183ba049dd0a51301f49828b01016e3da4366c259e476a76501569516db328e24d87a8454706eba1f802cede3ffbcccb2adb089987c223cbbf5b38e3e3a655d97ce13bb0cef8d28146fdf7827f8c89acd92ab63b88ed4bb6416bbff818b6d4f4dbaf51c57b8c820db1f12543b755a414c28e0722fbce9fc1e017ee19d33588679229f0f2210afbdd36fea1ae0784eb219e58e32c1c3a62ee04716aed213bdb2a85ef28eda7fa466059fe7bed81cc3f937540e7140d967b715845c8144d75b2b5172a2841875cc9d3a203946b13c99fd828b8b1b283076912959eaab52eabaacff93a180099f99d4e84f58a50802c7917a1a8ab04382d824a019012d245a79635a1920991a9adbaa7c1baee7d3d1dffe7f8c44ccaed5a71d5fd97236ba82e89a98728a9221911055d89cca1b66212ea8c86faccaa23a0a2acf4bc876d48ce4b7c746a656db866a6071c84ee20a7eeaca89656a204fa3acda50805037432c5ac93ad3da7aef4f59422a818bd37549bd0a60c5191734072447c784a86c876f7233c1991435275dbc757a5a611149f57bcd116702253d65d940bdf5986a911224e686b741e2130981476fb397062c9e962c33ae5b2404d1f8927a294ba25e2f8c5ccf159f2421c065687e9069ec1d8f6587d70829d5010a429f40bdfd9f4fa774244280a68a94c80f7668a6bcb97cf09c2ccc45d20f36c702348a567945c28e6a13b98a0e648c368a5dbc32b8d5cb38e26bffc8d35b4b5a7277e0ca9bfd31a5d1564fc60886d2a2b1c16930c1fd632b3d1f738e752fbaaccfd0178766a301d3a80ccf63ab72be51763e3cd69d15d2d85b6413869c70e1115ea0ff5c4600f6e80bd28a2b44e11295e7eef37aac0c3e2a60a3b9803ec48ff50a13969c47adc96b048523246e59a5790e0c1fd38e1d0b160ac9dc7d46bc84ff05a0445b2512c8ba22e526ceb22242ab842f868a8dca158a6559e63a14a91c57deb771fbc9d83a5ec205120ca64835820d1fffade1bbc0145121d1bab3893fa53655234799bd51dd2b64a9afe430d9870710b8ecde3d8bd9a00b20327ec205a646e1824e2cea0344a9a7af4a366fbf78924b06e00d83e0ccca70994cffbc862257a90b6938279c3c309951ae4050bde6e5eb83099d054942096b4b38a95068811739ae2a9d6ea10d36f784beda1495fdd47df4e25096cbe69f6a1f345d14ec08e3207ec0e1c41c49fb3fb48ffe28dcef43a3bc17d48026e3fcf7a121848a64a316b22dd891f99ed9041bd9a33c3848a906b93467fa28efa7d6754598ab9b6ddc8c2040dca9e81364bade3255e940ecfd6430662e9b6572cb890e6953531223a852678f89043cfbee4be02dd3d43273f4c8464e5c69b4fbceaf76789275ada9626b13a124e2de4d9ff36b2f345c26eb19b09ae48df7726f97543a8032d8594b0f0b98ec1570e0c253c454d59ed10f97f602e248f5a953c38792db9af44a95878a65836f7cd934e14804135e2b41f50461d0ed14acf3f68eb733090f3314cd90a8013f7be822acaf52c5729db5dcd164644629b1b30616f4bd8fb5f2f3075bdd5f2f5aed88d4f056ceff76879031668a9d7bea225c3eb661ccf97269cf43969da5dd230582a0e4fe4c4d69d455c715d29d2e675b5bba23a4aaca45f1c13c3ee6a9d6cfb0350600cf99f4af6a56183351c2b0df3883cb6ba6b30b8b25dcfe3ca893e0e6a85d7c4031d87273fa36314ee171d160781e2a2314eca5005609560c69eb082f07abd2b9d3918edc93d4d01d5744e556b17bf2bcfd74982b3793fbfaad4d8dc1530a19790b117d3b6c9fd6d2114749c22464078870b71ab5e5868c7de675c1cd52b6eeb2444e3773c27320b0c7ab261260272f15911004c179d61079d2c0b989789e2fe209f72d6014c18a95c38dc1a9ef416a4ec60d33a7276313111d771bf6b5dd1558859d08953a4bd0d3711b428f17addfdfa401a7ec59eb3115ca9062093c8a4ce9885bc44c053f1b1665a9dbf98816d9df5982f115478b1278a731d4c501b2059cee74a494d3c267cf8c8c49676094c94fd90356b49c15a74ec5bfc8712ba8933cb3868d9cd5f19838172d6a885bb9e9c2d21e7b4c9918e1a6547a5cbfb73951124eb6e201cba3114e9e7052bef2a9acef15215c35e823e23d27b6fff020f610049b3227e5e984998e31fbe101e15b14c9148a584a2f007a778893e1d7884e5a05988b687dccd411cbce94c1771e686efaaaa88d39ef694d8f25c13db98c07baacfd5b8e12fdc92deaa5bd4cd934d5b422fbc4803bb317f0e68f891a207d5e67cf63aa0554a7ad1bfb4cc04cf931d8637a516e603905fa594bc2880d33949ae07dd0036f0828d898a720e6fbcf248a33ca60d838dbd1a12e3a19c835c996fdc37af0de22cdd2c09d4c543969f8d2a7b5a1fbc439a9e7f929f04c5f14a2eacca8633be1ce44c3cb9e4d1c22c41ef27b617106dee98280368d82a2384295e0f16c11153cd03fb9b1d22189f2d4c2b74414a4e82b409abe23d2a6028b2a4ee368807cd043d52ac3e17bf36c4654acd19b63b28fd956e7669d60f4b8fd6257dfa49b4d339935f4125adc34b710dc588e915e6b71d21009ad447f87e2c85709b6712b0cc0227d99cd88988414ebe99496c85e16ff2f9b8631ed7fe8f1cbc9bce459eb38bd70b1c61840d63020d4ee3f42c82117770bf415019e17b3e37fd42d2f6c5dd6cb5da06b4fda29fe86b60fcc535775e6bee3a5f1a10b51746bd90d604087e5f82fe9d6cb63c412f45d14c800a7bb042ef7cc1b7707c0d612841b8cee78abfcfa0594439375f3965e01b58f6b3998b7a52d0d234fc72c8a6fd031b9285eb76c375506ed97f459c245f9b0c923241abb20be2491c47c35c12152de9feef01986979e3d55555b67513ba8d3c217b4bbac454ee6fe5358d0f13d24847904745932ad67657eebe25a58f0ec30eb567b04298287f380a701ea2368e803c1cd733173387c575b882f1ff5a8b56b507612d0257f32bdf6fc38f377df17452bbd207ae715158eae69fa7f9a2959464575bf585a794a8293badc6d9dad7fbc1c01a1161550430f839bbc653f35224235f0f179cf53a1583adfc5d3ae869db971362b7cac38950465e914cc9efd3c9020b32fb5e6f957daa2728f742bced7b8673433e3c30a50a45bc701a5280cbff4462071a8e842282850eb8ccaf4b9330a05b38031376b51bc0ea758d849db58b21f1bf5ffa1409a6b6a7019c01f95f9c55ec1d877e946da12815d751b71303c4c6c1c38961fe47dfb1775fd8721803fd330973d7b1fb679068d169fac9cf942f93117e2ec9f283341cc8c835ab2210a40f19098496299fc9c0017a167ce1832494cec29527bb7d04e1e9304cb2dc45bbc1a03fcaf434b39d556a5cb779799b83a56d79bb8bb3d6c582de81fd1b38862f88af1d9b356f05d6ac81ccda3f05599c3d0a90336a50ff4fb933da50b0499f1c59a207804d1f2b03fc62c29146a036a5d13629a1a2217ff8e82a2707d384cbff45353ad0eca1f90159d0294b9f928b71ca5ef003258f0d60c4762c45c139720a1aa76a6417b7978626bf17a9518c4858089a7b397499b19fe0d6e0710a27e0ab0a73d12f4048302f15ea496f8c6d28a47f898e6c2a7aff25a46b8e45888ef17c3fdfd38adad18510d19a325faec9d5c2435316527f3276c7d515acd940c6ff9165e3652ccd717b7e75fc87dcf0503ad59ed799723402184229401c54ef6683af5e83bfab833fda6f51cf65625133157ac1af55217a3759c6dcb93c019f7fd37d2cb1f1e82c36695da5d5a1a4c14c965fec984daf04ea7081908dff96929c75870baa5f226fdeb90a811fce795e6cb6de4b0927760d2b4145704b5c1152e9a5fcd11a6e01de2d0f808147c0ffce9e4c9fd88bcbf4b39ebc75c106c37480c187ba08f8194357ecdeccdd5383e6138559b18abad7f1bd47c6d3d4ae2506725be076f3b25a2c86f2b3c2a654ac754b24dc8634b8ceb8029902d696bd0f032a801cd6ad60607e927fe7ce7c0ee48c75cc837844d160471a9785d5dc0cdfcd88454f3df1b24388342151efcf6fd94fc248fee28ffa4d113d67e70d8ebb8d3bb0fc22a057a0bfd950a4dd61c6ef42f17da8f4034ff1cbf7a4065ce141e93a0c120e9c2d309cca5c14fe2c56360337a2b4b671823db471875cacfd8b0fe9c04c8fd6c0c0ef2f0a04b5c7703212af39e51c9af5e1143b7756c16a0209f60a12837f5ac378aaa002f830bd38b9a6f455927633104b1bc2c85715de50c1fcc5192d6d7ba695cbbc18121b80efbcb4a73d7fdcba3b1322c1a381a636d04233a33b1b62e4e7cc1bc2844a0fef2d0d82a596322f5b173f8888b2d7a63de2328cac0c16416fad6bfe071a9405816632f83c6814aaa3687a2ca00c14427db10ec464a306d28ba4138d084402e95b79c8a02b8fc1e60ae665965d67c0bb6ca0e4eb0b0223e7e0388171a183e59c7d3cfe9c9ee2b0ef4185d7e7c29cc4181e18321311c66f12900bac5b6c67e16de9c0761f16c3b079694ca26dd0f4ed32a40b6aeeb29150dd3d00786dea28eb29d911f703f549cb081fad3155634d0a91b14153d1da7e2f857045d3ed887d4451b5a3003e05287ee1a5b9f175476d352f03ad540d73b64b1edc3ad06d6ccf918752f901e3aaf0cfea73059019a5064abb43b82c466972c5c01dc0f36015c7449b1ed206ae06b4dfa4543929bf994e7a0e28cb0a70a7ac6aa93fd3b65061e464f12ca342f306c4a1a9d29b2fe45091593e68b06442b97b94e53b01e3307ba6b39ddfa7f375be34a256b78397b0a12e32c84a269db2bf30fe427982964dc036135e91a8e2d286bf3883a5ba4b7f9a9276af17b5dc187023804ad96c6aa429ecffb27344b62d40f6919151b1a0e6faa486b75986ae1053f9b1c020a8d31b8e0cf61989b00140e8f96437fef7852061fa37cf42ab38ba78fc2d7faf0ca8fbccc28d5f7106e1d38a0827fd3fe8e0f15652ac52fa0bd81b47778a51a9e0e1f3b8920fdb327f10d6fb0bc46e6462460c034f24066552e92ec86ed231734e347fca5c61ba5b81c00dfbd091e1290ea7505e7314c42bffc1c3c10ba1de2e3876131f387c6c8ad4db056237fffc4d9c6b25c4ac750b8e722366f80cd8371f884e831df6a283dbb6eb9e185076485e74f66c953787ee920340bf40a360384b1fd947243ce74ccf1c43f3507ad6bb405e096e151c8870e8465f208d502489bd6566a60fb72554cfb02231e4f0e0681bf030e299bc86f644a72aaa668d70a33dee05fc82cc5c1197ea3de5a3676cf81bc3d9676f0a17886a9a0a5ad328e0682ab979339b1ff858ab05c2ece4dcf3a25b0e3bbfb138d3cc1bf6030666a489a216d9c48e7d5684d954689d915a594c296e9258e51f320bf499baec9723fa969c38a6001e7fa9e8afd1fe23485cfb4158ee769340be229f70e59c6298d4e7d964417d4faee02f26c0590d66e9e985c82c03c7c481496f67003c193db4772f6be378b7dc5f0baaaea78bbc7af6509018fb6e373acdb687569774e903ede92bd7a7490f94f1c10212cdc1b60cdcd3af5bff41b123e07aba2c22afaff3cd6b2233df53c411cbf986fb82dda7fb2e5207d927a18040a40e08fec761d7c5f70f174855471006fe89c2f71d6245cf86c045344bdaecf0ce400fd7bce803102938ed3a60dc60946ec4365b6502e452099d5564dbd4af7a41dfe8177c4ae1a3c35066e0f066e7993b8645f8458e8bef2c4b11f87b21e0faf13b9ef75092f421c1730be047200b90b875b49199a1dc491a15e3494b210a8d423a56e3392691158607cb5c0a662359f1e88c8a2b92fc88b837877de7beaef5d451c6df8b644738218406b286cc603fcfa76206cc832707ec1df06488f7ed0cfc5a615aa093d1542ac9dd8d2fd4376eaa089a74d4724b35fb2835f71cd56efe98b606811242c3269d5d3289265286cf915be94edc2ebb72b2a89138c4e71708c0b9a76e405ca9ae7ba9160b6a0518d4ac6af71cdea4860c09bcf1b6109a5a03d60f3f127e27038115e29dab6ae35af237ae450da8398658a0011543600ea0899b398dd941fd181074ccab56e6edffce08d09a15d7c3ba12ebe75eea4017a621989135d16045c2bb8d1244942699d655641ae409f62b58a7d2ff47efc49cdf6313e42d68225fa63ffbe79d37f132340b12b650b27149f50679e6b89860e410bf7505679f5bdfc34aabb47c2e9591a0d8b669a020459a8c249a689e25d3249b433a4b860c507d42ad9f5def77d482ce05adbc5aaee8f965548f46317175504b94038d2dae3092362b820d9041a069d7bac0c427b2ec7f043a78f22e501fb1face8d2a5186af889c7bc8a740ac0b365a063b55314d495e1db7d8bb8b2f3981ed4c5508b5b1435ce0909419b1c5b5cc5a8940ab0e1951aed4762adb90d5d34fe4a3c8ea41148820cd14d69f90bf03a5dc94d14a571949e9f0d47334380c3e392e4c9f2767ce3f513275621b4bd5a5220001562758718e020633dd8fa02a5be5540b5ff01c7cc74bde89a0878e21e45880b1efc8c25d6aaf0b8edf274ced621eb75ed408085d6b2b5b1184ce74c5d5aa3cd44cc25a835d262cc53f9d4bde0b5977dd56dfa459441c27642a74bd5a9224649bdbdd6cc77bfc28394e622ea6bbffc583a8dc91807b820451885dc6171fa05bbc2bc8b537d90bda81245a19144420ca6204352d62d403477fdee37a6d9c6df3c964ae9aa7fc72dd6bd254f4fb2e0e163a7730c83ee8c4e4983feb3c97e673044abc455324ae510d0b72b24266e3e0ee74aaec91bd25d5399f12f79b40facac708f8851d3071b9942fefb48804e840b751ac6335994f18f88fbc84e2beab427f265a357bd3f3c7deb330537463abf9e660a2b38709dff40c7dd017848fa88d16901a3d19f290abc6c062a5480a317be43c4978269e0b740e4521dbecf249ca5192a7ba15aace6c4be1324c907cf712292a3c55f2d43c97223190a8768f944471b629f60ba58592e4883b634ce00e38b86bfc43db0ca9ad689d4b7ba2c931736d42dfb2c45a5fdc6ec841ce154e67d01052ed4f10c005737264f22856ada9dfabd1f41dd5d70d500fa47fb4cb12f59a0944a905df1856d690e2f3b9d0a6735ec0e912fff14d195f95116643cd4ce0c57e9ca35f9a742efeff557f38cf7775c2a2c9d4871ceef51c97fdb7e5addaf93e2f6e600c9e57d7df72a3fe794ea1acb7883321da6d713e20c2bf6a0f931e225986598ccff970308df706d349800428412c0e827b0f2c6afbac4d69c724397779a3deeb4c5b54d7233405eddc6c214a43ed629004232d702ce0c8cca62d370628a734701e5119421c57353dd9c73bfbbc9df19665758498face29f83b777a781a45361b6fc1e6144708b0341fd69a96dc1928ff2f7564c328fc749be0602802b542c88ce64130038745aec6b1b3df8496d53c069146c01f11e2d4095e88ab402425c180f4230c798b488206d1d3ca71f1e8369341ebf8e069c2fbb08db699548e14881243d6672d3d8d5a34e1a7f5c7bc76505650e446f0916374ebd2178acb23182ede1e1a4eb484b32b57c871019aaa6124ea262df539213fa5077e7e670f4ecdfc13b6ecc01bd05e858f08f98431064fea3c708fe336a5a01a56310da1b3666d163351a6b509ca16fc00359b160000e45904df2f0cdb6ac5a3bc281dad6af717d4520e6c7136ab145dba9bad8ec5925c335d88c7fbd69ceb57999141f9c577451031c180ce042946b7690424f985a83cedcac20075cbc75483a606c9828b62a6861e66739c679848024ca2c7d23fb505a8b390d028a5b9a177e1696e47dd6419746c98e44c90eff79408f2dc33a0615dd35ecf212a8f526040bc455de25b493c57b3c2fe8477001f1812545d1574cebe410fb293a809d224b289fb0f2a5b24d9da651662ae2950766f2a06b3aceafa6891780087c7d167c85d3186880f0edddbe294e6ac6570122399967d5034bc8c8c8ce55e7d3975714f47c32bf9095a749e224bce0193fb853204cdd4b2456864fdbbc64375ea85e6a28444b5d609b0865aa5aa799e267c53cc8f6b7e1d4a4f0f3a84c125adbe7e37d5172be2e520f1e8695cf901fbf10e650455675303dadd3c73a5a00cb717df7ca3f3b676a1544ee8a9e218942f1ef429c0bf3d53d5701030bbd59e31cd00282cf3d8677ebe5bb60db6b212da3b6e9a81776ec9c952114f18fb306db1e0f15c61cba28718f57980f768b79ac05be172cfe1a74d2998c136e4ba257188c6127022c0f656ac2492fcdf9d8be3ba5a7afe9f1469aee0b3e00c035f540f30b399f7246553d4fcad31b7c541765269a4da2956582c40564fc6db867c53b5609f83a3fe3dbdcc3cb1625fdbcd11f02726b7d02b18e9ad30e72652dabfd064ea1b8dd8ee953fd8bea7ef8e436a65a5a6fb43bc39cf0c97429dc3f966e2236d45b5ff71b2d146b024fd7418145ef9f30c1696119dcbbdd70a164b1ba1c7761a395c795af9323b2331951644e750000e335c7eca83eabf9c8c942845d17d94364753785735802d87939eac29854739caec21b637e55d014af63359b4b690ed470880cbc46bd7d1f6c32984b93e7450aedb639781195342a1a97f91253f7349a165ee557db39c481fcba064f523ebbb6803fc141ba44bf8760a292883222ae0fd84634bf0a6de752af68e9ffb91e0434f2f065367a6705cb105228afbdc736dc7726afcfe0ddcc0cd73576076050020803838724dc094f9b01cf1342f9c3ea4b9a4c718720a91e6d62c3f333a6a9a7445c5d4c634e93437c2c18981a854df2953ee32dda1d2ce404f51aaa695a7300ee7a9ba50415430c319239a2818c36b9d13a0ca66a54412e355ceb223170743e9957acf1369c3d537b8750fed81edf795191fec25484d9f1b9519c0f4782c192f164747e58d30e433f633bb27c34ff8424ce00578e41415c37fe4ec3e4810388d50ff82a28fe6e55ac233a27100ed9cc7f145c6719753d1d831fd7166aec3398ff3d85f597bb45afe4772423f33474bfb37833b30bcfbe55f566b86f74fbfec884464dea838cc1720e7f2452fc8e21c9712826214134699914ec323dac5a27a0158b859d803c4ca555fc5e980d82017e7142d5c574abcb207837dc78582d0c07aeea9592ca13b6158743dd69db0cc5a008bbfcc99f0c07290609ab48dec442a9af7b811eec45cf7a493afad0387d74eccd5f7dd2a9a7d2f614bc707ab48582c5b985fbb24ee1c4fc43d0fd38470999923030f6a240c71de430ad1fe252197d73d059bf3366d6970a4294cbd9eebe3d009d85129035dba068f47f083b09ff9e0a295013e61534f9ee72a8ca7803414104aee17112c532ff1d361389378b79244d30d3c8a914a83b37edc682fa5022ea4ee28c857c7e0593c6f8e46da383004087ac1b17a487198fc7b0cc55462786a906c1ed30ff60e187b2a161b037440ccd4500c8f80dff6e0a36322a2e2ff854053631291aa79828283744c365b790fee78e0cdc5db4cd82076cc0d7b0db977c727b02c22152ecb02ff5f39e1dc6f9a4469cee1e24b09f73b9dc2882501d9d73114ade0474257e695994d6d9e9287f8d4bed5acf006fb618ee21f9cefa07ba3daaa99dcef2c6ed80ce83863b3643540ebc8c44fde71fb560b8f536978600621757c0c5a1da94fdad94befdbb680a0c91e794abb668df404b607626b8e9f376484d11692833ad7723c4924df128c6fe754fb1b95331a9595c42b7109d6f19eaf36081d4dd14e0fc3239bf603d2b486ee377d190d114bbe1504fee55e59be77a8856a1162949991f048ca095e99db4b1c9bf320733650503194f83ac827c95264f9a87a53de11e6d3bf9c7a28196f01712e9dc6c3b5a3dc6878e9cfe1c190a26d362759f5903d070d43b801c0b74d150a62ff72ac54f2d915c472ba0beb106764fb046221903910898a3c3f43cd277ee6ef486b3c50fe4d2de6ad648bff06e15f2521484e50069fc00b3f4ac63c2a92dadbe19d5e2173352bc5093b866ddd324cbebe96502976764e8e9e02825927ca173aec574e17947d898e04a62f1bd9c4105d4e6a3b313612ae7792dff1a337411cf472aa951e6e2cf6881531cc416e0d462b8bda0871ee88f4745797bb8807b8501adfc732aec7b0e429737eb39c274c93f37dd47c89a17a6b023402797800bce60d9431f07155eabc5af8f76f9f4fb9d8dc638fbca5f1643f6117c22e9bbff1b9d8e57017ccb089ff12fc239ab8a24e91d134b835fb03fef08dfc88667393049aa3d033730ffcc9387e8f75ae3d9152706396d6a49f79761ec3c109ad365e9056c99efb407c90a346a86b0464c00654a9906c47c7811d5ac52ec387c9c1e448026a1db711fb889ac407d461cb287e093c30e2c5763e347d7e01ecbf0e2336ececf355e86604c6c4730cb3de7e6231630cdd37e71925261db3f34cdbb3ce0b9e0527a17f74b2ce958f11d3b0b3b4d6f07e44f40c12bc71ce0adf1347a109cf144961efe361d2a36059acb36d0882b433234e0e94ae4074c04c29a955dac3af75a7c7337a74b7566468d37b32aa1c3a51ccfe3539ebeac5fdf727e891cf3e2fd9c76ac061c6066b8ed41c14e57544e7126012de8a63d40e0c680a1d5164f8a6887620d830d09828992c3886f419784a5045640fccd65279cdcfd6bb893f3a8b07920616f3c0f0a8bf094a0435dac9712117a3b722fd070f1ba96b2f11d7fec0b1745ac66b59b1f9a8fdd13411230058b5bc55aa6b841fc1a330b5f87ba1ad1af3931b0b9fee4026789feb0bf9f20462c882851d383cf53e06193c032f783736ec4f108149761a352e1c6b2f71323428a19d8dd73e884a6bc14c2fa06f00648176895e5fd1e6873752df42f6479b666ee158a08dd7876a937b5f656894500c1e75a5a70e727c764f0574ef92547a3ce89506347be984442ca277432fcae494d85fbe84964ac2fe6e2e58a3ebe6a4877e9452bc5f26acdc253f13e0a64e0205cfa7ed4d8dd408616eebaaea484b66e89c22d57544e0ffaae61638b5a452b1274e19b58ab7edf76444e5040a899a99eb771a13b42b824fa6df0da4c00bba14c7b05a2bed6f61c6b857b470cd48e0333314a2a96fe5d9bb9fee6c217191fc9674d2542f1ce864a561f25dc120bf2a961a68dd84d4cc5d971009b57737f7b3d3f4819a4f701fb49f3aa4e11ea320f975e262da92a398950be6be3c328d70c30671a39f1c0a5d99a86f8c7f6443fc72473370d83f970a283e32f6a16f3e7f035a1b64bd4b93656844e51897505864127ecaa061784a859093c4c471ada9993756800d8f7f5376e1b6d1480df0e7b0a548a746e95755ccc26588827e9903976da88ee1e544b7199413139928daf04939cca4fd50b10acad814a16183449086ae66bd22da0e823c210ab1e70e3b63399b3a27f1331f7dde0933283b384f4498cc9fc6020745084fa520c8a536065c3309591d974d3ad1990ef6180e9da04742678db7f672d6d6227d2392d09a459e608346ecba93ddb41d25becd90429ee2bc33bcbbaca2a68b25b4100bb9e5415c7cfe589508df97cca7a9bfe490a87cb963d4975b3aa2f5ba979fd675ecc50aff6e6196dc91b76d59bca3f68642181cf1c6b1f13339a7eb8fb40755f84b964488fcb9dfdfae1a5457e04b4bc6b1992715ffbe914efbb8ab983b687c5a700f292ebc76b651c000a7f63ec7efc83b4bd19905b9016ba35f41191fca9d3fdfeec9c2d65ab23b019335765c300d8eb85774bb53ec8458e9e39fa6ca3f9a3266012a385358c4654509a85bf912fdfd4b1c451922269e89f846b886e25f0f4b913e299ce9020df5c519d41cdb1cb3c122bdea84c5ee2270a6d6e74eec4ad3bf6cf45db1891c87111be416a207b986b08ce708dd5e6b776572404f6e51f02a1e3ac1399aa6e3ea1684185ffbeeb698e2c7d6fefc99cdcb5611e321efbd47e9a743061ad9cae631c3982e4062a664bbb457734795865b88430a5842274874854e148253398bab68bb46e8722de6add60699059e0e34d6cc4d0e8df8fcae0ae443e98e8161318340fa61ec044d52a8c219fdedc3d4274b91e283a368a74520e14e5de29bd7a13f423d9af82130b87308fa1f1aced058606e376e5efb09699f71dc5e2192b83a3d3f7e26de926b676e04b003c7a611592d3bf080f0a9b9c142aa11095d411ba81668c32fa53fe6ab8b6a55e5d658308ac8adffbe2e67ba101bd76cae33a9206d6de1bb5475844c0eb216a198e4f4c62a09c0036ac90279f3dd5a6773107a8e7c3cda4e3ab622f89cf09200bd4e0953476232d75b60dad805e1f5f5ca43efd85b239fb0997c75a313df766ff0c84ff3ec0742c7d445dd8fcdcfb3efe9e7f51a64a7a0e3b0fa49c9a0ba3885e41f9423cebc5f31fb6a33d047173a8bece7f5b28d67aed3ec976a577c59d9e6de0756bc4ac253557e55f6413eb05e08a0affcddd9781883312d4514927dd7c64bbbd251db2affa5d3783c7c0a21d98906854274bd06ee9ba57a38d631d331b081121986c805212875025563d7d97582fb0f701b6f2f0c04ac6cd50fa6f2ad7ebe04928a34b006c97d74715758f5dff516944107e35f67d084113fe52f3d41b7f5099dd7b7499b4288db02d4449c44d4bebc3bf1f919c956cd5590a0a9a7c7b5c1b627f820cfe03f14f637c78e2a3a04d5b92918f12b3582b5de621346d2484496af9876abf37e3907f0f121e804439d4931d0fd494befbea2824e28c5fd03357d36a1c1fc915cd8a6e29c8e829e9205cae8cdf02f055137001395a2dd83fb322cfcf40bba5343ef7f46d59e07f4fce867dce1b79840b1126f0aa30baba38011815ceb77d55185abdb84deb7d228e0795d528a504d1e7f68f5e931a501936e59e13ac556183c565599f9d57b72ce7f2bbf8343c9486c6d3a8ee31b83bd38ff3dd1beb326a4cbe4109673482761d60e4a0084295cb738d21378a39dde9e7509537d316cf6ca0e620943f89363424d2a74f0b20c5ed02ea28a4dc4a0b530e22e48c05318981de2d6362ad96e81e4ce220caa82bf6f0fa1e87bf77133a1dc0131a9bd7718ec318b41032a67900625f74758a4b048e26c744683bcb8e004f9c13f902712f6640f1ad0eb257629c0dcbd8fd141a9f022845065afd800736770e53f285d2a7a44e3d7f259e51baf67b189f0e377fccdd9e0a814d86c9e924a193c82466b714393e649644528b4061a2c497a06c0ee9f9392347a80210c1df70c6b5eecfe1721458a2d2f8ad433c7abe01506719d8a523bce3bc3239a3cddb53e72be21870a961db0f4e7649181e1467400fd53cbc9b58c236c3b1dd9e8a0aa917c14cdfb77e0496c493c0f4c25e4da524a8565a0862121b23a7319bdf6f4e7be8e30827efb7eacdbb102cdaf4b308a1568735ebe059dbd255e78b3ecdbb5be1e232cef705db078eb028b8a6014398058b68bc196e6b554baf3b06e4b47392f38c10f23d9e3e580bf54c12ad3f06932bb056b07201cc8083d4d4414bc6a16928af4d54089a07f057ac4ffc264e15ee4faf5ee48a475318f95d6c1940db80dc9cc4c015a069211c0d2bc53efabfdf200f176eac602b879429f88fce26202dd60136413189fa2180d6f1e2fffa437bbaf68122031ce857745dc1c444f7d8c534420f2dfb4c688f410b84a00d6d38d391d02a4f1ea02511b0b14931fd73598c6839598400460e954063dc90c1202ff3aff5fc917163f27a740bea57cdb8241c1261fa95669d893ad81bda02c8e2d8a1388e5df992ce9ea406901e522a83dc6c4c6254236561682853e181de36a06ea1001a6134415a1b0012c28388df39c70e3fc27cffa6fd856c4f38f7b1507e5c0334c955c968f48a38891e2ba78770583bada94487dbfb18904f0d411437af9201309a0ca65bc117688137258588b554ba0ba6d40f8f00bc59155ecbd47f7997ba75e2af04e8d5d1cd1cb997f41651c7a84ff23724478a1ee1f56da389231054138c8810dc35e6b2f31e0790f8b5a8904fe3245e8f63197d3d7129724b9d4910f5b2736d8f1cf87ab337944dd035c3ff6c784a2e62b708ceb7e533ec87bca783fd0bf79dcbdc7653af5f32c2491121134705c1eba9e721a985aaa4feb31d968891c7b8105efa149f1009b5dcbbf1b5feeba05fa6942724e4b71006a9a004ce1521bb897c011624ab70bb903f0fdb9edf84b19ceb5f3a2bc64d536aba926f29c927842ade8fd110e26280b2af143a7be41b78d61105b3cd3fc82be7d027ab7a9611730b89a13c3f8aa210bc989f22430d68fea8c5f4868fe380f785c9527a61fbbfb6506a81dc4e058d627b798e87ab26480b44a5fe99eea6ca187ac2109ac58288f36860d81747cc249336ab2a7707b45ccf550824464934f4685290d964031c660d5d5521cc127547f195a0de89d5b92f609005e7175070d0cf04655c7587d0a69306755291c5ca19110567730eddb20a52a377bf1e32e7ed02499bbed2d1b562cc22a1d03ba8c08251e09e5867b47396cbeeb1e80ec773393ef346c2e96433a9a020e12aca8299f5048410d9f3360a6561803cbab37b208ed2162d5b2a866235fa343b715e3f0a5cd6873408e2ae0cb46985fb5c7ad1c4a3113d0c6355384029ecedf65f86d1e786b747cae2fa71bfa7c404f5399e23e280fd9101f01ccc639c921984f3866a3660db253009e200513799c0c1b264ff2ec96b63a89ee36658baf70b5a3973942f2480971e60d83427d77c60fd0f7434b403bf17ee6f95c5c47304cb2963600ec2ccc60e233da5cfc2f7a8886c70420184e404bb18e8956ea7655f68eb3ceace496a33b1ddee0e88017e778b78fdaa00c25ee518bb62b05e52be35d3dffa20a98ad42f0670e20338c892dcdc118c8c56cf7fd5cfc6858c4f94c71d0ae4b17a9cf1f7cb86ccc2166f750e3ade629b6eb2d20bb80515ae45383e67d4f27b0f23bae645047566472887312023b3fe3e185bc1c73d0e7d6bb8c6862e1c1e603cd4014049a1e6e9920f3ca180b5b5d41c8464c25480f4d045a3a40609911c1e5892b91a38c769348eb1d0f6ce3d5b9e6f730e37a326cc9626453c09f01965a77c09f1c0f6c6a6be0211a78dc82ad692a958ff3b2901aeaaac0a8353dcab33118cabb878cfc941954eccf832b1861098b0e5a7c533a2e50506fb695c6c0c496a6f1f1be176d26ceeb6c3ed9e26d015ffa4861807065280fbc75ab3ef770252892c210c0b57c22df771cea30f7a382a7c68e7ae23319f4ba36ae5225e700bbe465cf29bb0e381dfccd2282bccd73b0402f5dea2a7067dbf6de41a8ea8dbdf2e2a43bfe2aa3ac16463652b37690056be3c3b4ff5ae6d0ad808e019a72353571e6be0b642a03d9249665a0aa615886836c983085684e0680a3c03f317321a86ba613d808f4fe3e7fdb721a134a9a00cbe7d8f8df9b946bd45aa665ef99fd59b47cd6e748752874d6f06d8d71207c1200a50eb77b252cee8f14336ff55a565d2d6e038b7737a25dfabe2746c5fa5b59f0530fc0ec5e437fb4d3025e236397ca64e62dd8c1ac3f78e2820b8ab040bae09412ce6d9e366707a8565950aefe24991a44966b74966c1fba8b673b32e4c6d8f72e6f6d4849a0f05a916874b6da538c2a5ba460f93c056d824b6d673bfcc7475828a98d5b8127aecfb9e6e6acdd934512da3716e3235f0abba22fe6d631db2368f101dbb0aad7da5ab4e6ca53d57c9045448946fd6443d82aceeb7152f129326cecda1e5663d51e398809a07dab5ca7f223b73bc37bda431517d2214877065fb5143c54c9b15584953333717a86528ebbafb75048e4aae88118b73e308725e5ef598cc6c4aac8926df1edb3aa75132b139fd5ebb7a8e7cd3a82091bec99a2717689237eb8d16a456c9913d0c787964f94381cb40cc632b431b7fd995e7ed86dbb4b5bcb1a7dc59d984b91d8e06b6b40620b56f6016f09b997e8c7e452468867d7026d3244d21b8e941a15b40b0028de0a251210adf83cc52f0852492d50c1bf8f183885f4f541d3ade41607241c558504b9ad0bdc74a4b20edab1cf119f4d22bdf3ea5a51adef5fa8dd243084788c6dc03b5442a2ad7c87014b4699a05d75b6f53f1a16283f5a20ba20fa7bf6dd5da8ec8e0af443ec74e2a4182428186280ab4379deb4b2df67850738d3f33d6bc7fc2868853ee331157ae80a12923664d386771de8d7e0ad3b12c42a66ee77631dfcd7a5c63a9854ac0b3b48f16057c7eec480634bcda6fff4280acd4f269328499ef17c82373119eebab4584ef074c6cf5b9aeea24f7737430048f4cdf0fb4e3f2158824ce8613c85ff820778937190158eaaa0acee9800098606e18705aa33318040c45b77de8f32f979323d043e15f02287500a987986515964e23fbfc686b9768cd1daf16da45b7195d7ee91e9cac95c0ea831cf311e8822c4ff744a242fc547f7037adc36acc995f1c8ce4168080c952ab35a2ba1619c4fd0a866c879be4d2041f5544cd6cae88e0c409d36c775de6fa5ebe39fc49156d410c2c54b162e991ab9dd7ae9f54154ed4c0b654602e817688f5e4067d1dfc481be70078325d2acdd3986c4b7e5e0611224d03ee7095d1e58611aecb120b00b2f57b529a1cf3a704c2385c143c74bc45f41a4bd21131522402a2436d8735f7a312070ac360b7e5f367e5c4fbe07a97958b7cb8bebcdb87f61583c68f31b6f1a15c841639588cc7b1fcd87e1409d99064a6f66914c73cf0d1747c2f17e376a76e05195bf1e45819fc4e90bca52de458e3e90d055fb9597f470db263cae359401d94a06687f3ed2479e7924ee817e8d63da934a13a65ee7afbdde16f8bcdf1015192b087a890ad4e2aa5b98173788c60b1c58f8d867586e6fd492445860d8c1baaec68c11364f23f81030884c1b3994a76d2ded687f6d6b8ec4cfc5d65db1ecfa53a5119ca9a408c327144120514b5f6fd704bfa2d860b0612441957f9e5af33a9f90a225d44aa64c8099e55b1b5508d947e9e64ddeba52f04768abba9ab7b43d06738b3adfa0acc4c98fa9131c52f9f2994c24f3a8fc2e587791351b7b05d603c6fd694c44c82b4a98ef2d18a3d188a7a97317b3ac27e27ab381b2a704926713bb53f82adb567fe28f4f6bcdb2194210591a1af2d442eaf7253e7c83f7d89d4f80401c6437b854a6a72b48f3b197d3f11b1c412bbfeed01de6cc233d029a15b51d07f3687ababcf18cb7a02c2d4eb1fb4adf4c5029911ba4f6314e6dd67864ce0616aadde0a5a906690fae683dff5344759085da3abc8a30196a9dea8ea7219331a6163c506468ad2df036f1264ebeb05d55849a08160e7053f2e19a0c800a7ec76b0ff223d5acf9308cce3edc8345617f1a84c695f1f61fdde4414711c6c71a219fa6eebbd4ae637ac6d1477a4a11625b91786496659d940293f88996c1abe9d3e2e88ec8a502ff17dcf27971a9edb9a96c3f93d8657e7465d17f11625457d68a06c66647a83622f24057f72027c7a7e8e5d87512d344883ca12c9cd3d1fcde7ed69c55a1c5100dc04fbbf27fc0641ff59ad58751b16893eddd9a10e992fc64404a64a80b60c36da826ac1e65b95bb67c67798d446de75f6e0590c3d6e99351447d50a9f4fdc20012ca6bf2993d70560e3a873baa9b6678c3ae6c947a960ba83fa758578646bccbd8188940d2b40cafb7eeee681026aa2f12f7f590512c332a0af41bb1050976833f28ed99a3e3326684f0b781da93afa9ec77657796f28efcd73ccf10c6ce9b16d2750681e7efee3141fba40ef5c48d33489be146c56cc5edd3ef046eb15f7a771383a11a56a3ed176618e8154090a04e766240662093eed210867b39235018a3c77b14c148046ec9ba9b24fcdf108f36788d5947a8b62ad3f6744a552c1f56932f65ac667a526666f83d835208cb07d018129e171733515fc0fe1e4ad52c35fef93e2a32a67400c5564d1112e2b2aded9a4fd3efa4552ed9778a3f1a216354de9aff890277c59ca8ecd2bf2d777c535fdd52ad97328496458c11bbcf069503cba6657be84b29041ac84b097411cf5328db63732f78fa24bd9f96edb1b5329f033dee74f956e24a46a30ae3295b176df8eb3f2fdd327e6d7255486e31fc23013764de0ab2121babbba53be185b0bcdb8c72eac968b15b7197c284b7ed0ee4ad114e85d17045e215ad48f242ae3cc9114f66044132d520c924c342725c409c8e5fe198801359578ad1ec32cb2a7ee900281a318fd3ebd8461fe079ce23f374131494a744f99c344555d4fafb53dbebd3fd311b067096e919d137617c490d1e8e7b7e4dc5dffa930cb619162c6ef054f7637dc03dff2a9f811a1df45a75881405e43831b828ccb4e1014e8c25e086b82dcbf642b7ab81345439eb221d58c4d15668a4998aeac20dfbce4800de6334284ac1299cfb4145a4f7aa46c3f5f6ae2798fde7fb607bb7043f015aa969db97c482f2ff89f940dee5d11506444d2388d9c771b7eada8d4bc84aec04e1f4e3187da98499f120d81dfcd844fe48e23dc94a8a6d86514ca25b80087ca427d961129777faea7065022589efa205aae26709a69c4c1c43f2376890c4557e12ac66dbc383289cb17a1cbb4f14312f1eaaed8e97d4b482e71b0b194fc11f29c3559787adae90f5165120d89271a3259874f054d1c79f9ffb2ec00f04cdac6f94702fcd83d3bc3721f457265511638c0dec5a5414805129921950b4f60d35b987017a7e6a7b888e25da3289fc49688898a29f52b03f174d562acd3bc76af5c2d984c30bf8c68ab753ca06a1a6f5139e5b81d21041e98527446935159a45e963333b27b6d4c00ee656dac4c6478f340abfb00abf410853dd991839732af2bb0e7a615d985b6b2a2e1ae0c93485860191977fea8b809df6a688bd5a7665dc6aec6307df3cd95f987907e4a15fd1845af84a84c8235ec81c7a9206ea58f05d00b946f98a1d27df1846bd36eb1614881f40ad10d517e1022b58d1a6b26af055438c79abb224f1a10e93958165290ef2ae0187654072f678f4ba01dc74b9f4b0a450a17ae4069c5b316308990cb5b38dea54ae609a9f0d8a3d29096095ca73b10d69af035662a50f0dc75452061c68dc313f2dcfc7705314ac3ecb46b06b40711be2c11251e0d59492485ca048c679d56053e79837088e735005877dcfd2a7a0844db53cd4202678b585183654a77aec52dba875393314494c8388a6ce1f9a49184d593d829e019336322a1541cf92b51a16a83a19c8202703259e5a2fba13ceeba611e38263738aeaf97a251d239bf3b81a084483e597278f1953bf1c9356b1a6123add5e36a249fae1690a3c30c70bc82e24ce9e946b0a8785d75a212933159beefe6410986b5ae5955ee92c9df7be7c8cc630fb24f321f36d78c157e938196626ec3815c1517683ebfd86e6af5469125e94b0c1c37dc6c3f3e6397b0c66158229c11e57a3bb8009876dc68d4e20a25ce15953952a8993fc30da60931f99d98669560292227668fe204239aa721a57a298ae340ad026a46cdd5db4ae3d1dd390462dd04bfb98f877efe68ff1073425fb2683953692e1c0ce0f3d557d9f784d112362cc0d13f3f6004088316991cae5b1693db9e870b92232071d3e2d454d8651eb3d09ffb9f007820cf9d3482e00bff88e1ef1abcf6c8a78b81b31ddabc2d7a830078158f8349e564d50b863f3ac7e652f7cd9ac38ede5dd65286e4d1ca282f6f20c182e9b2cc6ba0221ca854cd58427ec3160706cc4d18e311141229307193cbd267effb92206887e33956fcbedbf8077f2b7f6c8a9853d20e915b4c15cf4ed4dadfb1aed2081c98b7662b82034929f15b92cad862f05830bdd878d2debfe254f76efbe5a3282d3b97101111ee2b0632271b533832dbd4bed0fbe1d106dae78134c98431f5b68d008e5b4076161ca5cdfad5beb50da669003fdca0e15f0f36a3f5591948edd2b7542d246c3f2b8870934bacef4c3047fe88e7bed58bca5d014c93a074957034b9923965d4f4db8b7c36df6443f7724489d25d89b9c68af218731c66b1a44229228b655799270aaa60217690b4c229b7109c580cc4c54b2b8defe9597c8cc64a09610e67f787a484235cdc4344d39aeef1d2e3951b3de037b3dbd18c10c8bc4e19ecdfd4667011569ea0b24a2553cc31f87a4585c47aa21392821663f21ac1fe10495eb85d468acf46e6471704bdc8505ceebeb81e63b93d348fdf67a61c045bb253adc41745d07df483d864a8901fe29ab006214b2d8f99a5f9537a0d5e9f396a093a50ed7c855df08e8fc7f54d60010cd9648001d021b1806013d1998d0a8f2965aa25d2bd0cfe6d7be49d02d273c649db867093ace2e704219905989c62241f35ce09721a39ee6c8125ab534f56c838b0b2d4105161db2860ddc60ac6189432945fbab3eb6d7f4cadf0635eaee5c7de19dae8f164ad36b89c556f46c9767e9dc2686954a0caf2e82d105ec99445d3673ad289faec21258af58e483f6be804fadb9cbd0fa72ab64cf7b4542040509b6dc2f3fe4154fcc851d09b5d262332341ef896b9f6852dc1592002a3062917bd363cc40ba107fb5d3d27948f86ee6262556cf0f88f7bcb134ecb142803e0a083dbfda7e8714762aee92fbd9c8fc9ac60d46d49bcb0fb22a1ac0221e53f245c5cc5101291fb0fa2ba4bbea23bab4904d71fbc3d3199d4b0989e384211d6f164a534b094f1400e1c999f779aae2b782a97ca22d66c8d89abfea7122151f1a14894e3870063d42202f470f12d4b43d2607633fbebe33d809fd6dc24acae102a014458b44c9a52c2ad68f5709117aab7fc4e2cda66b9f857d59a9139962d82a72a5a23ea0d80520774bec095bec1cbdefc358f7f77b57d77adf01aac82860243d1f805cbaa61b78f37711b78411a3043c5a67b27a608644331397986ab292d17b1e56c124ade1e3797e7de6a43c5090e91c1e677a7a7dbe1836c3006bb219847eb923acb05d85feb5258e34c72d3a90eac07824f423c84a567f496da374bd08c7492c1a1d67240a21d696aa1ec2be05e38ea3d6e071c2bb8b61c5d0160dfabd23817c1237d468cf68ebbd9e90bf8525d4310f9c0da9e4137fb74a5899d7697db59a72ecbb7ca4747591ff3b031f60980acec44f8258708394fc1f07d7dee04d4bd77ff5c7aaa3b735adef19be3eb66067191c580098a03b317e8b197cb122814e3e0d0f3b6ed941ec948206b05f5076f98d2af16bbe15597bf777b5f364eec66016aeeda8b274b1184dd9b6d14d6b47f4231a9588ed9f84c80c0a7d26844535c20cacfb95f94bf0f7452b66567f1fff02b885036e51bc25288394985dfa8a42f4708bbc8b0fe8a50bd945a2400f74ec47775ea31f5ec02b91b4d73fa80be6aafe57a29f07a4774ad66350c9bbd6457c233d098ba6f1089b9797d10377bd42c62ad73e1c3023f186cca786d30807d079cb2ec51b8ae4372862a1db7537cbece963e1af7432571f24cfc4a4847f85287d2eb43ab2fbadb1399fc14cfed962ae486e960099b456e2f62c41fcd95aa7418935240329e457104f1cb8f4ccd2bbee9df536397b5b109a339b77e11621163f7a408b448c87f841f9cfe111012541f3dd8b12b26ae8ce575d60160d323924fad7090170b9280db1bb08b654b4a93f4ec2b6667e111fb4a076885011a6055764b23d283ad96705636d789634989b47cb252ba3ff1aa21afff9d4c15a03f5326d3470249315a574a6812353ece2f8d2287fffd175fc27189ef1f640d7e28c7ba98f4158b1acc68bef933b316060693bb5877377a82f8313a7525ed077a70cfbd4f4e56180a57149daae9222b708d08f92a29770be495fb99dda24128f94f7b8720bcfc1b2947563881eb3cbbdfbe59edddd7bcaa4d788de5c964975482904b0a96fab2aa906053b5a9e3a6e955c4291168ad27a0ed4d683f244b6d4675eaee2d33866822356cf67f0ec693a68cc08c86f8c9d6d0746ce50792d061e9b8b7d185697527b0a1d9347db6e056ed50198c4ad3210fbbdc02c8e2f2dca6ab9c4367bf82f48f026d22ad0effb541f9f4930c6b8339bc18c3a3f170fd205841a2930226af2fcc8089e96702bb5cf2fec8024c8c8671ccfe520f98d446a5b421a88036573653b3ebee2d4329da6b028c389657b490feb2079d7781ab5f41e051490e77f33e8c781d05b6e00494fedf17bd4554041eaf09fc5d17f841bc5cdbf8175b54c035564c3e369c44b2f75a459580686611c817a6b32aec6f9cee1987fe153d6cb3bbce26ac62ec1a76ea512badffadf997502a073f317c6d879d0f2de7f9ac1dc8a051e6d84b40d51202015a9035977fc33dd2f7a1f49c7ea99235c8a4511a7e709619de130c33f43d1abc1fa03a96341121e00545734ce56d739870617d306fff2cb2ded7d34a4524fb66fc01b8809217b37d9726f29654a32c30d9f0d7c0d795e014ce0a40b01e86e23c8f24fe2c89313943fbf33f1e89d523ee8bb4ef0b0f23bbe907f87204951255fceab494dce944baeee45f92e8eccf6a7e0c0600f597e9b66a69969669a453adc404604e7a680a89a9e853c3f72214f26d08f029880778730d9986c4c36435800651bc1e7ca14fad2042ef2fa7659c6d198ba9e9ce221c9fea01eb94ae148154bae4c54403dac30c4cafe211cb9329149d50acb64235517a786a593108e2d35455d216aa4ca83e4102bc9fe291cb9c23269b2d393fd5552382f98090bc504df601a995c6128708dc445b2ff89898c64222b0dc9fe23135914d95f844d6496755d0ec68aec5c23367275792e8e5c2d2929c99ec464932f4eaa3331f9645245be546aa7d6d44eca9572a58af49157ca952a92dae93e9a864f47d037d23b3b99db304cbe32e915876ee4f5fd9c98787d3914140d85e4f5adf9bb31a77c4ac43764fadb08b4e8627eca27435fa3584b39f1fa6ede75286619a350b861ac5ee239411c48f7946aa943e9ae10d4d7eb38f3bb1f38012b532c24f5211c1f82938138e8a157289624b36e5e4e535a625b49f6580462cc14430aa5f21d61a26f724289291ebd1e5dccd7aea4dc54b979e22e752a9d492341961fc1993f93a250d7e7a809ed3bc2e6cf77298f5b4054cd5f716354f5197a65270f760eb5db90c59027914f09cfb40a29c44417f3b74f86fb95962c95ac90e78f2964e9f14504e7a36e8daaf9a9ab95a22a7cac8195c881ea74970fae254fe59391af72f2b8cb654ea7d56a712a264fe5936f42791507d5377dd337b5660d9bb8bb65d3ccf4079989af6b09b6db06d63628eff4c947ad78dcd5f2e7ce086e5f6f8de0f6ddf522b8c5086e95dbbeb7caa1509ffcd40a8fbb346fdf2e381c91b852a94ffe0a7767b37acc56525eb49f4f7d32f553df0c67e23f21b15bc5e7de22ddbd46ee45ddfb922a0f2f2cfba7342e05d97f45bd42565656acf08cba2fa916212d52e5bf626587461bc2159dff4ffefd66789edfb1a8dd27f57d9fa8293872b5d292aa59cbe058d5f425a96a83bd2b2db9ba465cc56a19b70af1853f92ecf7485e69e55b4574713f23689ef8bad8802ba792fa6ab40607dbafbdc1f6c78fbad7ca61bfbcecd9d7fad6159f8ca4ff9fccdc32d72087e3ddd9f0bc45eefd64e6d4565a2b53a06eea5774dc654e5fa17ec3a10e6f4567a525f3b0d25a99e2441ff5297c8bb8caf14a6b658a151dd1a42f2279f7b396664cafbd21a5e04815c5f6c6daf0d8f9a1b5c936c8c3780a8e5c5dd74d1142884fc60671d05f5a1b07bdbf952956741cf495d64a2bfb5b1b1bc4de843e19392a2111803118610c994a3a5fc31ebe9385641182fa7985d47c0ceaf3044a88cdbb45eece2723f1755d177d77313ff5c968ee42da348e7293939c770240b435216c4cde811610a1b923125d785f1b59e4812c45f4a369f2082ecbef34afb3313bc2d0b42368963fe3e1ee673e5f95908387ccf5a32cff88f911e3dfe1b0693e6f69ba8f525599603f106739c6c44880f047d68cf81196b27bd65e226180bc7d17e507aaf809cfdb7b1fdf34cde777d4fb5c225a4f7799f8ab5326cc7c92e384ba9471dbb0fdc61e6394544471de4c33a5730751c62511b204191aa2aca1e81b8fc3b133736309b0c53f335124baa83866a2ac7bdad1f8bc5a5ae3a5ca490eb647aa3228dc257c1e7b60d5d804b9c1f9d467a92826e6f730fe32ff1e2926d61d3a989075cef521da986e8f71406caf66c110dcb0bd6c4ff6d09ba3ef6f8696e977b20e77b0b5cb26348724c8261b2ca37cfc9420416848a815ca39bdc9a3dc988d64ef43aff429295f4a297d17adc9256b35611bb33287e1b23c0eda58761bb3327789a55b1df4ba8e72a6bce7141c9e209b3c173f244640af96516ee713d223b165120e796413bcc1ac8d5c9d3e910d814e23d1b537b4b994bf07ddf0f38743bbdd308493fd3f1756599a96e337c3f6a8b846841eae06516ca1872504c518fa4cbe9377b075b076b0466859bec4d67ee79efc6446300ee3958aea9aa133ba3177d1828238784222bd94528e40370e9e3c8c8f2ec8c6c193973d76db71f0c48883271f3feee5e0892c73ef1fce178583fe9d3ce9869f497f72492f6f8843ce19bcb23f7dd28d0e7efc6674269d45d7092366968f048f6c311338f2411fe57ff2bd980e04644c0aae3a5215c2610dab77bb1b7efee090cb09bf9cb0fa6f57b3464c0cc21943c7a2d1167718191819d8109418e5a03716b2bd7f6973efcf3cd16a727aeea2d518632cc7088ba5186b481be7a5c100071d4606b67fce398b5051df596e6c73c6a1c707a45c5f2385397a3e4bbbbbb4e8c6617d5a49b91bc7586b8d75adf3a9f7b7c8fd936a9bbf26254b6e4f6e67e8224be832b41c1ff458fe51c04a95f614a852d51a98651158f97484f6aee1d38f0ce320ddaab6e1d08272f64b7aa15d68cba7b25f6a53c352c64c8ba48b2ce10a56963da44856c9b18a21b1dc392bcfdc51cf64a24d31d7eacd1bb1726cd99597e8b51206511838ef23fd13eb94734ac1c9085acb86a99911620cda32bc6538e65afdc2083106c5dc12a28bee452fb93299a6e9d5e2ccb0c2e1156fa55bf9ac3885c2348b31a8c90fd1e5048613eb9433b1c9b1e9657a7db57ad676a5d2e9f48a2e44af538e08268a8964a21ed16ce5358b31e8cb5f79adf821ba706658c9e15a2b2faeb5f25ac959c959c959c9c9f229e660a99d9d172c2693ab98c291ab1f39b215513f6252b315965cfd88e9d94a8d5ccd98d8b2ceca310636e45af154e3239fd3e1609c19a28be8c5b9b81dee25573146240624597ee7517aa20f76efe3fb0ffb28fd8f987ff11ef411883116fbf0c212e9c3171a13633c3fd19f912af93f629cb0f1f91a347ec4fc0796e5874f1d3ed508fd77cc8789341173d2f0e902df7fde86e8ed6b6fbfff5ef43fe4573fd858451676726777094d2f11cc5de4a7765246e48b5ea223eee259bacb4a0ebd10a6b1ff7918370d1142966f3ae22e2b4ef4fbb23edffde84097656b587c0ac9b7a1ef98d0c3f8e79e6c60931e0a748cfd8eb1af23263ef9bb3a9ac97a9d66f7264f81d17fb0093e3f7a136c0222363e3f3279138c62e6656287544919052b7af5377a9acf9b78f734f1cff73e4fc23e4cf0a8e67d8c44dd8f98ee734ff3bd50343bcdf746ac2cff834f139f20f0f9ee6d4cdc61114caae4fbf8f89bb4105dc817352c5b6c729974a44af44acd56705233b9ea5efe0a10ba2e35f352b32f3503a566a919a87ed6e23a064b3f34e9a46e52377215634c0a27c75db421ad94fc944eca753b6b476cf8237f32dad4fe889dbffdf4b29632e2a03cd518ddc82a6cea95da71b06d76643d7275a2c0e7bbcfcb681c48ca06354bb1640a6c8789c89597ce8a48c7b5f382c55035a215540dca067583c241e5b460597eb8f23ac14eb193ec749aa1583206f6f48a31e6cb3fe5c8d5e7e59fc0105d447e88a6975c7db0e85bb4c8e129e7abd5b3b62b954c2f233c4f2c9a4517f23524d8d44bae7ec4c84ff5a476523099dac9f2f330eed8b4135dc46ce3b04d3a59aebcde4a30afbca4fc6a2d87575e597e3037c4be1c141d7150c21c94a2978d7966ff93e82555f2a514bda4e8b582b539f882ae8b768783b1d6c1ceedc8dc5e79cee973ce39a7c4d1c11fb4dd0b317a8c71461e9e36c466dac0c34353d0c55844154f4032e46bb4c47274333ec7719bcb342850e17f44b7a15f502abf0d2fe5fba51fbbe5b765f2a5e76095b1034b6e89604f1c5b5c33c00ce352ca29275d814b295bbabbbbcb3ec313a8c803c8b18a2700b95a17398f8bbf6d9ce536256e64ee2bfdef76fef9a5d2b67538b4796effc16189fbed4177ba6afbf82971236f5fb10e1618bf91c3f83a58b2124af4bfec8294524a29dbd1309ffa7424930725f5ccfeb38fe887b59cbef688608e2d3de44a7efe577ce3f0f3df77947bfaa91559dddee4a7c97fa09841a06eca4a2827154bae3ec7715c7d8eabcfe508fd097235715cad524ece8473cc0f49eebb9e9408fd09c378ad15873c2617d65ab95aab56b5aa554d56ed79788e3a394e6adcacd5a4c9d726c769cf711ff298218f8973f4d7e7aecb38aeca9a6b0d85f814ea2157b3c6be68546be5a4d4b81927f9a1d3ac21a5a89c38ca7127d087fb8f1be1b024c21f8be74e96b76f0f1facaae1aabde9d2bf37f5a8bb12f3b4993518a3e0132cfa5a376e54a9e8fb431cb40c8f610df4218fc97d83708efaf49bc36177d56c684a51fd113e6daf3de9674da946aba21f91aa68e5923e75a3549146da73df8cfa3944985445614924d27e5449b4c788be844924322679fe9b3868192b29932a9fd5fbefd7ea3bc771dce7c369f552f9237faebf32c51307fd427b18a95dd0cf6b82a7835fcdfdb576254c22b93226791cc451ae1c0683c160b06eca4a32b964c21c7424b1bc22472b74c1e53dc7fdece1a0b31c863f0d910f777d7cc18671967bb0ba89447dee6bae1fb9ea122661ee72e2fe47e638aebf195e79a20baf75caeac73865532665ace293119e6b8e2e7834fc917cb0a1c3665247ae7ce6339d99ce94c9558f999d953eb5c7ec23535263134e20fe3da48685a41ec63f772691c99584c164f5af1c962e41d8d0613eabb39eddb8409f550b9b9d09f761775e58e2ba8e7bcff199bbe378142d8f7b77096909c562f2c99c9c7c32def75765deed240d8b52b5e15682fa7c0eeebd0f39ece1928336f52bdfc3e4df7b931e5f08c708c2618d1cd6ec631a6fedc0f2ece12bb0f7b28ab8ef21ee12f68ce39aa6a1887bb0b941a9021535d95b9f2afae8a27b3cf7f43f9f4fc542563c8cf790ab9ec915384ad58767b5679faf1ff687f3be7acde2ae0f6c1d46c961f4871dcb3e0b2dcd64c599c961e8a18b2c9d8f18c3b30f1f49b07149a9444d1065741de20bfab1ef90e98771104872d83601393924d2479feb1b908dcd87cb2712579e944f467b77e99ed298b9d93d539b3de8f9740fd753791c54e2f334991aed449f8c66a7a5bfe106f204cd285fd7748a87f2d14fa91cb87d6a4aca47bf44f30756b54f89becae6d53b7bece85129953e19ee4bda7542abbfc14c2e8ed1f7decce7297170d64b3c749d55da4c9ae9a37ffa66f8272304b420984d3b9d3cd427433f5ebd9db9ee73854c2c24f4da7582876d985cd55849ceac1ef0105ff8778dd51aeb434a94f2d5e0720061a383adfd41a35b89cb9153a39dbc55e5939926d32743a5ac38f6ac957c321a3ed558e501ddd0571948e6a1c62acf49b61257a1bcf851faa71a73b0546395a7caa4d684974fa84f66fe743958845209f3703877782c85f5a4baa7f2dc8afa64345c6335464fae22eea2b9cb74171992da2ca166eaca15cfda15027a0aa22fa74715fd15df11356fdf6dda6d25b39eabbdbfa49fa2a251cf69c060dbb6a86d736e9c085473eb08636e1aa573d28f31decf39354ae99c53a35550aa691aa554d3348d6a4a28d5344da3f4a3f4418d4a74d0842a0343175942112bfb6bdbf78a318e6cb04d498cd1bdfcaa635f7edd912bd0cbafaf0a93abd04bbcdac39664e3c93810438ebf21f1558f0d0c514607e9173e83fe098999633a18255733839425e66afc60fb5bc7bf4790961e24fb875ccd4d4fe13dcf8d879de81c5a9815d54f7b1752677f01fb207c8213053a06f41d03c2355e8cfd9a1943037a16d498fe6ccc188b59a082500ce83de6f332743b12a06bef03bd8709f0f13ee46a3e2fb923a215dadde36afee5a5a50504ff3daec6e36ab273359f9754c85cac42e63af9dd075b2436e6e0862d4ceb03cc634250ca3c4a79cb1f8883c89bd4706c2163a283fe2256e79d924ed667c1c71091f237fa5a4582959a9431f38f90d576ac8bee2233e551f336a30bed88c9624d8d6a74ce493fbad6de0491a59aa6699aa63ded2abbcdd658d62a2c6bafacd59dac7d75c915c7f25ec39c8e2ab37cb0f2c3ea712cb9da3e2cc9d71e6c7f58aab0ecd5b3da566551890e985065793a285dd3839538be28c6848e3ce69cb3d659ebac75ce4ae90e39b7ca79abd0c72fc95e31588c918462c935a217439787abfc6bf723cf1ea0ffbc3c73f7f33bcaf07ee2500729f7d8e1a0f7f0b832872e4dd7380cffef36cd2703fa7cba2e749bc655fe200ff4de27f3e16629b1f36909bcdb11dcdefb8ea0b97ef7cdcf3b7edf2739d0e767fef1b931baa872fb90a83b78f47070ca9f937bf91c9e4d90f2ac5fac516b7cd19773ce49353d58f9184f0725fedcb3e9aeed2ea7fc19e38eb6b1631d8be581a76334e6a03f1e621e0418bc60b00324875d0c084d0c754c64093d9becdded22e5585f7e32b7c31eb96b74d751b1a516ed09393830a8d1b161176be5ece4ceab1813832461979387b84b3ce2dff17449b27f87639de06173278512e20bff1004e2caa1ebe8c4d851afa3946adab66df293a9f39bd11fdb658c3e1fc6b74ec5d210d970d7e9388c2ed6e58ea7934d4ff3645d928e67f336e7a2369d82b687f192f5befb74f7f65de76db7f39c73467bde763d6f9bb5336204c3087adf0ccfdb95f9f35529ecf60e7ebe199bccdb77a0d82e2768cba9ff79ff0ec75dba771a7709820fb9ea70cf7dd772971c77e170bb9a60bb985c45574cae5ca78bf5865da723aeb98be974311dcf754e5e173bd9007d0fea62379c271b5ee97fc4d8b71e3dd1c988f8f14f14007d276ff2f01cfbe688f874c427f77f72c71c159ffa73c48f55d8e0e4eeed7e72bcb18a19cc72df1d9f1305bcfffec32608bd4781effb1813bf99930dd0dbb7ad4ee79bb099d0cb47e792aacec3d375b429ac66041bba8e8e27800ad771577bddddddf13651653947ff8643f9da77118722b8a9b250ee5a45b0a1eb785dd5f170d5911f6fe56ec5e167961d778e83431cd4516539bec4221d8f8e5cf913a2cabf0a2e2d647730b85ca793e12ee660d8c57c60c317d7a1c28b84c186edb3aca3a3f5d8976775742658efe32b86d0d1b0e063e4cf87918622290092fd6b9114d064cfee4cb03bba6ebedfa9fdf7dbd76ebbf19d76ec5ca737e0473e799fa37bee3d0ef388de64c2fbd1b567a16fcc75fac0a190c51f9039e46da1063dc85a1c76201c76b64a74d9627bfbad7d2bd330d2de0e5d0e876df2dbf62626bfbdc9f72763d2695e38737bb971a8c3e46e5df64fa68bb97f5efb5d7bf27347f693df15612129defc64408f724bdf296fefc4a0fb19d127de8fb01094ff6021255cf3312938bacabb20eb95fa45f7fbf8cdf07ef4a42a851d7dbf47baa3ff60212818c6bf2be4044f57d92791aef7a22be4e4472727dd9dc24d1e22c72aa4d0338529e4e44e7a146742216f3c48e70edb741d6e20261ffa2e9cb9fb70621e9d411d0ebd972ffaee4977f424ec1fbddc89befb8f3773e873d89fd9c3394cb0a7c3cbf6e5873abc49738f708ef91f125e48e4fdc439ecd32c3f2568b61e0e1b48eeba075deebbbb7138fc31fb36e1e51cf3df3f0fc71b7a46c83fb934443e2f7777b7ef0dc64d1c14d3ead0b2d6ff983c474af914d3a3fc89ca87beb3d77ee88aec977aae90e37df79f1bf2c89fef3624441fc2a7ef435d371ae1d38769c47c3a7d8ed17f7f1afdf7a30f047afb9f07dd9047eede86a02e7e478c3ef4c48afc7de8bbea85aee8ade8a3e3130837e047fef0e9fb1c9f07fdf779d07f6c7430f4211869435012a6ff3cfd687436bdc5a2fe1ed0d97aa6efdec33509b6c3a6b73887e93f3847e92de8ea30a5bc08873abc5cfaf82a27fdb69442faf91687282727a19f1ce93912177afb9dbd9ce86dc771a117bd25713f392ef4a20e87936bfb216bc261939f26cf5d93b76f7168b99f6f7fbb3c3a73b8b93ad813129d45df59f421ec7de3d311fdc9f1f92afafaf95aff13ba218f1c1a8d30e8ad7dd48daeb2de876e287ad1b7e82b0e3f2feaaf013f44d7f3e745df89ee27c2df83eee843b77b7b432fdb077d8ed0770f0a7df721fba01f59cff686dd6bdf8b68c47c127d0efba117e12a853d1d613ff4164707431884bd0fe7f87c871dd6e1e50fae1fa376c3e7317578f989ee373988a6277bbb9c54ebf8e1966338448e3c51d4213d0515397eac40703a084e43c15393b0628b02aa7801fda5255cd5e8171e81e8c26756e490058e1ac318cbf167cbe84102ad84c41e315242628fb4912e92a3f611d45ed36e3840c3d1458cb4abbb71a240c2a2592267dcc5590ee2f018ca9504fe3d44efff1281b0e5a53df798cb7c4874e1ef2c110ebd482612fdb3755608874e45f6efbc860935d98f4084ec394ab0a1bf72e27c100e5f3e1cb6783804bdba220f14d65aeb3da1367491259ced9e6663eb9186b94ba5c9617cbd4aee9fd3186ff64e0d7789a261f1f5eeeede30304bdc30b9f29d23aef22fb976765aa59d86852fa1a4b2d794385295c457b225558ee314cb70e44a2a7195cbd792ecdeca3dfef2355ff225b17c2921d32f64d931e8a6c109ee9025377103c93138811e7c67dbd97c67f31d202750e239393934088d2dc278cbb6b56c2d3b3a9cb5767e43e2632d0911a10e2f6b4f07ab3d0c033a2df4f2e6236b1a0eb7a712b0dacf600011dda2d91cf38644c330c0b97f50e2397451f4d8fece3f99ce6d6e5e5e2d3ba0eb75b26c599953258e0b46c2e88b1e7117181277a9ef4f63eef2797fcaa3e9683177d93ef4fe9a4baeb6ba635f250d965d93d1995c6d3952e55f6ad91c9ccab2355b4ef6df8c48588e59d2849ccb5e960843fe96235760544997eb4527dc5a920aae7ebc4b8aa0fcd02dc50823fc2ce58dac7d4707acc8f4a58fc65d67a9243b3173b819e974e61023283b97835f4745a7d3e96420b221d31f38600c99be4c83106c470725115dd08f5dc8548a2cbfb79aad66abd96ab21b9922cb6f6123cbdff27c4da6c9349926cb337eadce3d79634c95ab19338f58166f5fa2f38f2caf5c73d79ebb1333778e9a1b6cfcde5e797b85d3cd20840da93599b5912a7f225e8a70970e66c6572bfec318036d31c6b4b136a63fe4f85f94619af50b97ede0eaba7cb5b2e2c3080b7131e8c7ffb40c6d4bbd5eb684ffbafaba58e4749c07268143be244c22d931e29b4b6e3bee127a1a224e7c443a10c79a47728c1e122a22a827546f2c8e64754e4d629594e292d00e10f982d922584bf82a845343ae422fa9f255c8b2a4ea7bf919e1591b9609cb4486c242b1090df1154aab5462d9b0ea14968a305404e5851243e949b189954ad67aeed74aebba5c29383636a6d9ac851263c54c283d3638a0d16cf155ea512d72dc48beba2ed4fd7cbe25ca125ff5116f5d570a4d962e9b39f2a2bb7ca9146ae6eea4860a4228697d855aa57eae563e7e5c59c24a6ba5d532aeab5ff8afdc4e2273f0ba8ca059e22dd38bc4553c4d73bfb48cba0deb5804620ceda4276568b7a1c412b5f9836723f19556cb6830c4172c17d6afeb6a9e16c3c4fd7a828ac98b754fb636d134b3a218c334339943762eca3091f50bd728c7922bce44b6a970365ccdf6a1e7d0448635e053ca9b1cc61dd675d198eb92c3e4581c8b63712c005c80468dde1dedba9a40b5ef8849dffbd2bc6926d6fbee13356b5a0a8e8d09cb44966d6ce42a8583d292ab94ebc42ad9a8d898506c5a28ad9356f64779c9552a1693ab144a8f5cadb0526ce46a0587f4ca2628b1124a8f45e9c929364972b8d25a92b2912bfc4ab9e40ab7e4296563c2618d59590a4727e5dac9fe2729170e10594cae7014aeea912b6c236f12522c9bf4d064675dd79197110d47ae2eec97f8ea5e9c52100b048726bb114f5d37e22a9b7e49158cbb8de484454e66a1e3a0b3a0227b1c5e4060e50e41ba3817e7e2903e07acd04224ed75e4e414c1b9e2ba86080fe3af3c732712bd66fa515833ea51a73f59c941bf3e7df9f2cecf53faa916228a786921a2087ab5f76ea8237bf3253e955e3e3d951ee5abca8755e554c23462467994a7ef3d4a96a1f7a1ef344f1ea1f2f28915b9f4f2d6a7289e874f28b8013f720957296ca5af7243ef39d2a3909ed69fffd1ab517a35527d0dd724d88a75903ed2539c83f4283847ea29a9621da44cc2d14154eab95ff93c4da1521ef4148727e900e980941f3d8ca7dcf00479f4dd88feaca351cae841a3917c8a2b0e41cf43e65138a769844d0f32fde89a70d87984c30e04fa397a108fcea3efd13683131299bec427dff874c4e7e57f5e6a39b4177de7df111f25a2e8f322d16b28d8bb21297bb94aece09c2fa58a0a4ef9faa55f71a3ab4a98f41ef7f5863ee5863a4828f789ce1489cf8b5e8443ed69a83dad4fcad2b3bc21e92dad52d89a4f3e24e5132d24611da4ac61d1730f234d621685a4cc817490f2139d3f2734927070fef6f48624e791eb7fc521a52103fbf9194938e8fff1aa57e9fd2c3bd34882e3def3d5c75786f1aef6c8f465a538e5af87ea301c466d59cd186f0d0c36acf9bdb61011cbfe1e090cd3eb16031bb6b41011a74b41b2f20c0b72b2ff0d1e16bfd1751cd779dd9ed79ed79ed7ed71fff9990ee3902c5943061b46182b475884b1628c99f2352658ff4e2382952bc982813522d1c98628f422c992acaee36ce89e6c844a21ee3951c8721cc7719ec775f793b9d08d31df079fb88f1f36811585442f025b2c3ed9f85e4010f69e0803bf2f8b9c912aff8ac3ba61c9a20d9be98e339e80effd6fe09891383e6c6263ee972d1e74ee5ebd3fb9939e733577d49bfe54cbdde6693477d5db66ee38afcadc7d3caef33e9f11b9f3bcee33c2ffd365f943f65c43a461c1c768bf7d6409453d79e630baed0536ac332fb0dc25c6881cab1a11ca13dbdc19c6b52258910e9df26d9d85a25866b94b6849754645f6af4b381a1e075d96b798f630fe922bd14e68737de5d056182c8716d75968eb4cc66858d4da8315c544a2e9f4099d8baca02614d62c4329bde4c578f4d50e168b258398fe8e5f3f1cbac6195084068ad89bf68dbb467b0db74dc75e758c7fcd9d8cab7f29d2e2eea11ce5aa5bc09a007ccb872f2f3e6c2af267c335a0c4e117e0c31e42808f382c81ded8df816043cf61b172ba1797c5cf59ffc58bceebb3b87500cfe2abbbb03c8b67f1d65df0b37892bbbc3c8b2fb94b8c67f1287731c0b3f82eda211ec649241289d42f84107ff27d4f327ed20d5b32e9ff8635f2a3dc94ed945af9fe37c1cf6252e959a7a669a68f77c56f37667a431da59cf2a60f7d322b74783965c59d794b4179d3aba49c522ba552e9576e0b90e51d34dd92832827433cbe319386f8176288ef3e19168fe5ce8c3d6c1d6431803b1d64f12eaee7208b7fb92407597c8c5b7290c51be0a21c64f143dcea208bef4f06068e0eb2f8cae27ebee4c43479f104cd393eaffa8fea61fcc5fd7c4b8f0dd19e2ec4a23e74d6246da4dcee9242804fb9a2b0a403cce0dbd73e1902cc0c7ed71e01eecca26b7f8802bc465da7bd7c29a2bbbb5b4629e577777777778c6559c3418935234c5e00bfdd26a22ce730790108e04dbeaf8903a28cae892f5a7c18bf903b46dc81b1b2e2ff5b7341848a1092002d2f52df5f84bb1ce0fb93883106105f19f401c81a8c01de0d508087f118638c31e5f4dae9b5efaba53ca9840a6d4640b77c952855f81d6394eb42ecfdd0590d04017ff2fe3d04f54eea6ef125a9ba29a7aaf28942fc470815217ec5edfc09b059716386713baf28c026755dbe8bf6e5e327b37a188f31c618638c11c6f2f259e49b6ed8d9f4f17ab9554a7f5af18df2fdbda57c7f0b1131c6c9370e75bc64d3b3f88e24c42220e59de4291701f77da25c8875d2ffa5b162e5c21471f2acca6d295d22504e6e8de8a251388611f6f2a61b737c79dacf72c3fe97af9f0c8b2ec6f8ae637cd71e8b3bb32906c671806bc3c1fe97d5bd21e3826b38d819c68d9988ee1775bf77ff82aeea37c06d71b0bf00b7081807fb097019e0607fcba5e160ff8b9bc412d1850b1c47dfe2860eaab902b8a18e28cb00f8d1cb6eac23be32007efb902081143a309293ffbbf6023063f4262f57b5467a109c98bb47ae64bc7befdfa9aee9b7d21334e728bdaaf42ad597524ff21502de64fae92e2bdef4d55d50def49ebbacbce92dcae3377d942b04e0aec157bea6699ad614e39f5a13a59ce359dc25e549a83ff98e891cb73fb961c43a4a39fe6fb8e4a0fc94cbe2a07c12eab668c912cf79519ef66b288f5b723f8a75d0f4308e2f0aae0e9a7ec59d0e9a7ee57a0e9a48ae32a57088caa657f9fe644e383a68fad20d3f9b70a9743faf725557753fefdfb04e12637c206e02cc39ec0f61dfc3e6b97126f70f7143300ff13dc4473083de0e71ed03e0718ed19b7c6772e37b202ca98928cb27296f62f2292724cce2e3cfdc701716213efe1231c6fda8f20cf015cc4705b8ac90ab04ac3c025c52a8934b132d3907aa6be40a06a37c58b3a6b56c53db2eeab78bc23a5ab2e951a8ef1c1036ec9a2622acbbbbbbbbfb67f508cbdacf885952fa7da9c4381c8c4f31cbbde1607c16d7868318e31af72e115dc4ffab805b5d157fc54dc02db92afe0a022ee8aaf8a9dbe2607cd43ddd221c8c6fba300ec68f510587d1488e8ff2fdc99470cac5292977f42837ace18f9bdc4fba6194e5d19bdcb0b18e510f074778c785a1e1a08d991bd185bf8c8be332c1e3d32c50f62596e46077370f07b7b066a935cdbc3e6c0d1bd263206cbfef886d41930c368cae08c6d67e1cc089a8a273f11dfa4938e894d2d76ad0e0c9fe49c423d9e58704bd3568d0a8a1511acedcb8461234b060351880610b75f0f7254e90c1da4c1a744f9d0e368f1e3b787c0d36ec598f92222a60657f128a459a33767777bf0f6c68f30a6cf5bc476e26dc874344e1ea2964adb58bd82355fb08d66f57378e5a6b95f3e5d6755d57e5365f7e449bc7d591e53e50c86424b21eb7d5ad72deb67d687bd0b7791bb7d5adfbcc975cadd5f6a6d1386a5b456b9bdce86f54ced7e46b1afd88438d52aa519be9b66d9bf6717a750a91d5ebee6ed99239d94389d3f3e5ecba751fadbbbbbbbbfe4f7787f36ba5dd9b0a646f2ae83e75cadae9b0e107198820adb2ce975bed821449441774abb5d629620b1b79bedc6aad758b73079a4be932d729a5e444a092dab51153658421b5fa1d4d955272528b3192ce39351a5d683e6b207b5c1fc8f59252bed4d2cf984e7adf9573ce39fb3ba2d2975bbfa49a77949482bedcb35bc7650be2da71edececececc076744a362c98e77297ed39965c491b8963533371603649765772238f2b890dcec4a13831e9a2aee9ca2eb154c2179a0677888177023d00711d8ed3e174381d25ddfbcdcdcd4d4cf2230827a7c8f325c73df7dceb6ce00c577b4cd903d2431759c21456f6f62c692dc55565b11ecc37262db96280d33c694b4d76928a2c4331281c36c52b3424b4138534227bacfc6e4704132109c54c5a262d07fd4d5c642a813c8588aaea8015f3938161000d98e8aaacca52655a014e04346a55d36c10f755f4e80226b1b271052355fef5c6e2b8729a65b223ae4c62511663b1c2427115aa4444170b8ae4d128a388a62598112ce2fbe5cd93366d2b572c9f02db0f135d2ee88349ab56935635695593961c7290e7cb502c168b5af8e10455058488200db964a914720981813c5f465a020ae3dda651e93d41da770a6b94871a933db6c6410792ddceed6b954724cc5d5cee52c457a1964eabd5cac9fd13c7575bab74f39a362f8ff96aab32dbd3d3b84ee1aa5a5b55c73def561d07bdb6a6903cd5db3e19f9f5d61687656cb6dc650a77d1a9b82df792932fa747b7975cd5d6abf56a6dadad47aeaa8d54f9d6da5a5bab6e3d75ebc95bf5b8ed488571de276352c58366587dd5573d22631f96310fcb1857eb919a91a8f5e52edb117799b00e87dd5b9d2fe79c9deb57f5505bb5555bb595bd0815d5a6da549b6a436fd4e943c6240a623506dad1b6ca4d152d3dad1c8d25a972db124130aa68a433ff943e7dfa383ebaa6cb9e8db5b1425266e97e881f12fe36e822b2f2cca65a57259d5cf7886ced50b513875c4e4f08d6588b9697518d7151865dd2816ef71f2cb195ed85423a5286a49c20fadd884e50488a6aac65744f8dfdc1f68b2e57c4e5a08e54b5e6e586744fcbe08ac01da17b28def2bc5c0e37c45553b88a0a075ddc0e97c3e5681944ffa03ddd6c37dab84f099b678e542d6919edea172e737a5c76c9167310f6b9a008d2af771441fa1d97e32e28111c72da409ea4bce5c8154a6c17003275d1971698b47f8b5a9b906aac42250be6931f99744f6d438df50bd7bceb0e5d4e4544801aabeff9e79c0d450eb924322e87d3e176381848e4328941800e6286ae8602caf4452b995e20cf97ad8d6e0c132b6c21d3269cdc00900a10c3087b4d221c000ae4f9a1260e7c9ed022487feb493af1b667418d01d5bcc4c43a2d490e3f406a1c74ed72431cd4c182e8a4921c7e683e2c075d272787cbf9644d7279ce5933ed6d045a74415f6bacd18d73712da9e2685f21a2df2e37aba931a19798d0d7d41811b78426fbd71a8b408c5962e58bbaaabd76f269e0733dbaa0af5d4939aa125594d69057ad57455ea52fe74b3af2ea9d26a0eb94be9c2f4922fa963eb7845ed558c3ea8cdb0267050e0a5c0e7d395fd6a62f6b4c74417ffb64ead7584cd6f992fe06a21fa20da34d5fce97279103719543e172a6e4406f49275fb50e894c7e748249b5c25cf5bab5bfbdd662f2d1277d339c6b053b8082868853928cee5db247b09da58d808cfdd33b0cdd277604f66a6f0709991f3f0a74ccc43e4e105375a46a7b82f5ec5f3d06f679d51e253a807d74b2733297fc86e5b04a1c0761c3cfebf53922ab493eb1241f65b365fd55fdf9ae56893f978bd55b5e38ee232d17e3e7f3f994eac708721cf79fafdcd7c871bfc55cb40feb7f709c5d9df52bae0ee2907e8c996b1a73cd7ce8e8808a2244529e051f53a2ddb1a6dcd26d97c3f0cd09366c9dfaadf32c600beaa5a43ce82ea010fcd23be860d5c104cd39ebb6d591c882b6934a3219892c48fefc80404f448dc771a3749dc56a916de5eaa5c192caf7fc10112d6276fed732816075e8d75a6b8f991667b397978882f10926e1b064825f70f882c3961c5f5ea84a7f10a031254c43aa66cd61ebe8f86ed822fb834d85ab8bec1871500ec136ab47eba0b8d5b941c2526fa2c8fe1ea9a55a983dc5ce618d2d5b7a0b3948b2e1601641d07d68de61b8ff4e123808424384fbcf7fbcdcf22506e9a4017e2ed85187d61ff10ecc84cc619431a1c3e34c0e82eec1b6121b46964c4375809d8f2ea28f66f5907db025169b8dd5f96667667fdff4c6c48dc316ef3b79676c48c65a4b253ce3e08dc737b696dcfffe3372d59dbd31a6db6ecd9f1b634220bb75e8d6e866146ebc54815f0b0e4cf7606d8c91534a2ae98cd5fc811e39462ca4ebb00cf4df3d856e8ce931d86fd9e739251866bcab52e5320a33964e1a67bceb13fd9ae9c798ee7bc65a4233236cce9948f30204d61397b06ae68b0e4c112ff4d65c84ab9c4a97df75d3eb1a593e4cecfee987ee8c54852f4578f7a3aabfbb3338b2fc18ed8875b4d46fdc444b96b87990f8640da34a0e7ac75af66959ebb83e3beb09f90646e87556add6964af47b8685591be9250ed69891aacef4b6bcbcb85e5c4b6c2dd92fe508db704c066cdea4e1a0d73cb3061bbe64a771b60bc9fe36628c48bb881b717e9cb8568b63e6066c4699795fc23083631676929ec9da71ba4df5155398af4e83147a98af8fe605c661f84fdaf553180ebfc0bc4c0cf38283537f6e417e9c9f4c94314713f395c312b4728ef9dcc7ac85256865ee71385f1c0e87f302c441b771b0d6d42ebbd099b5fa79d1315f79dbe44b0872382f37a8c9fe4514e9e62bf7cb3bd8283b520b57f96d09391c6dbe720b9804db2d1cf46904477e322de61d6c6cf02510362c393151e0cb9eaf4e831479c8b39e8ec05e13f39549a1b5a4af879bb1249228e51693ab2886168bc542c1a6c45da2bb00719768053ae4c4e8d0cae196247ba5a93548f6d82deb60c32d169a22a4136ad91b6b448a6abff61b3ed113c54e74eeef772ca4beb4a4925cc5186b617c8bedb45c798cfcb8c52c6c936d31778945825091fd379e2d891d228e35de6282b0a1ddc9fe76a7baaa4bdac1c6efd1caf263b0bd96acb872dd5e693042cb48b6d74acd48aa2b0c9de4be35adbbbb4925fb345dc7e8a5d9e130fca3fcfad26d62cf7cff6476f0e8d149fc905847ecc9fd2507bd27d623091bb85abae265a29b1a1a968831c618a38cb88508077d8776869e1b7b32886389be3dd195290d073d898c6b38b8433b830de30e29873a50bee2e12acfa81d66b021088271d376c41e221cf4160e62f00836ac3596061bd4740d6ec2ce27246278025656c3a40112192318b94083285ce2f73cc0da22dab4b2fff464b76899118c750baf398325f4c1795bde106dccd470700a1b822d7255ad8de08c60ecfc011fb9dfdd891093550f8791ecbf4412ee234bc5c184c30863acf1297ee7d9dfb2768de9df9db64d7377777777df3ad6481ab6040e989dd8c6911a72055361e277c42d0e820ecec8927bb420843656c6313371d010a1bf7db4ed59167ccc46248c3f49330ee2c0017bc111e3cf9f32fdf3a6f29cb7730bd9846cdd605e81ab17a9fa9797176dd29939dbc6dce2eca5882233b8c9cd13b71b33cdaa4572455d1ace7350e64b847ebd2cf8984a8462d2c7f8a3988323d92836928d78b899bb7876a2473277a121d25fbfab78241bc53a167f24ab3f8ab94bcb6e14334d61d201638c9a0401a8a28cc6608cd1225bc4d0668962a15852db503652e5328db2912b1065635136ad81a7182bfb6bf4724a882f72d7986b451731ceb849c9ed5cce8883af230ec2a20b31b8e1448778ba435c71ef7f8ab50c9312e28b3648913d46781a44f60f4f7d3051613aedc815877168f10e5824fb872dc097fc24bea6294c54480a32b53e38dc8c9b7133b9e2661ff95172b3ec600c8ccd5a623c3228022ea9ac599db575ca39b54e3a2757f618078b21d7e25a21d79a1979ed8c5a281bee84b289657f948dbba082a0466ee0ec6f4ab6d9d67304fb657ff025e2eee76ac02232a0c9eefe42502caef20f4b251487874e7e64e98f58880c62639656d61dfb12e98862a109267397b0cef29218b8b2bf884794a4ceac11fbb23b52eeecbc5e3098c426d38e69c764c4149b5400a2a46e41acfc49d2b4d8dddd7d631652ab4402d73ddc45ca77f91cdec1c341d776f470b063cf94dc77e678d0fcd108e391799a53babbbbbbbbbbcb8e61e8b103088f25d97f0957f977727ad1de9861c25da4f43a1c4bece83e389660a2fb358a6f38e81e4658c549dc70970d0bf9de773a7fde428474efe9d9d1e3fa00a28b2b2cea230bead210213daa7bb4bc4714b97be0902eeaf60db758d6426f22d51b77e1fa391b5c65a42358130e6d8c64fa90f41c267dd83624d29348240eb74ddff44d10138e0e6a1fbaa146d3367de330dc66fb8e59479de5ad0b45709373c4a731fe2c73fdb298cab7a0209b6c33a9f2cd0d321ac8c686dc1b4fff91d938e45eabdfa5ae3de22a7f0b7397cffef688af3e26e5c315d9f431a66493e9437165755e4617d09b7e8b2edf9bbe8b2ede9b3e4619d648bff037bdf6c998ac0ee9fdad914fc13a293fc23af9db48f606b8476f0a0a3d8c9b6ecc55ae5ca5d47db290c30d0f3d504e70683309875b2cf79b884638f42cc2e10686dc6f1b0892dc281c7e985dc37820831c9e90e9d33a4362c30319e4a093e956739c0fe3f36d623c3549f63f7577f7c9260fd6a78da9b895e2592a0c68b2bf476a211263efa0c5612f2d5e60c463271b2f63cfeb3b67b0610bcbc6b2e13f4bacf3209a65fffa8220d9df23b1b27339b493f206076b3fe94f5b659d5ddbb9b1adb56e48b6d806538215f588f02092c57a72b896ab8a622258edc999234d09a69e2ce51107a57c4517727b18d791abeda566ca912af93b3baf174c8a642c7bc4c2ec4b89597b44b20d9b70443d4a4caf258c6ab2cf1624d99f88188e70b2bf8cdc8dede7a0e070ba390e87e3a070d03fbaf090bb09836da9340e7a4d952baac5e75e72bbf57fc4ec9c1a9f20b0fd7c1bdbcfafd8478bc3d936ee46aa3ce2d14807d1856b786483473531a39a91cd4d74210b5b6a46dc4d8be82555373604c116231cf76d48b35c30249e6ac8ef8f79661ab00adb355a196aedff41d7753776978688f6dd77b78b355a77899c373fac13db184a90c6769fe4777682661e33d316f3bd895b4033d810b4d35e207c9975aeaa5a1c62f77b537a4b9f027cb578a02bfbb720a2bd8f2cdedd82d8cf2de7d38ffde92a57a01332fdf561bc03a59b2c0d918ff6dd7f700d07fd15f18c8dfe99aeabe1e09df9c45cc3c68c7f49fc9089f854bf7348737f057ec46c9d5b521aeea2f1e0063d6fc8fedbd7dfd5fac9cc6f0fb77095c4a07f08e2d81664b9c681d4d044774919bb39e79c73eac0566edbb66ddb26eb0ce3cb625c591fe2a0fba01f6edf63fb30ceb6676935a5ad46d36eb37af898c5efe12edbf794ee39b31e3e858fa67197d075b27f747d0fdc3d36eb432693f556b38663493d5ce51f5ffb81edd7e4b70e2cbd7dda1e9fee5511ea3eb2842756f64f4bf6bea3747ebc4b247e7759f031dd77d17244e47bb347371ff1e8c6c11114a39b97780485835e922a9ad18dc318e1bc608433636bac699fdfeee72911d95b443cc219dd8c704637239c1114a31b8e8bda7c8e6bb94be3d1e82687a31b8be32edd15bf4417fe37eed2ab8e118335bdb8566cc59609f6f92857dcc71ab7d18dbb84dce86604c5ababb318439a609fd10d0e6b1ddd6ca39bd14df543a441761c5a1764c71c0a627fe45a3435d945ace8c245b2fcb93187138e6e62874de1e84672385c1427d6c79a02cf74f59d1fca6f492cbf73ba71b786f090794e29e794536edba6e1d82fe6f78db1d8af6d52c66dd35ebb1ba973bae520ee1c7ae5e31ed22d77691c25181cc755fea896d1d9df755eb6e687b2655b1024fb9350fe5a186ce7d8d59cc2553ea9f09c8c5b5a18bc6f5ab2d537ad86a27a9c20485147ae1d923e5bfdedbd1b5db5551ceac8db936648ce07d28a15bd3da8f178101f18465e1839afe77dfca87772491f3ff9b3fe9ca1a494d297158714d3393f990923e99de18f993674defd607949a43ff98e9148274ffaf620293316469eb8c21ff290276de8179dbd196f3e8c777ff177ed42567cea0a416171970fbd92cea612d9e349e88cbbcca7df318a9bc7c159fab0796858c23c3c979ee2b0798ce88cf2f443d0a77c8cab151fa65c48df422909e35087a7d2f2dea350a4a74f03f5fe289547bd09ef80300a871149f63e258579c80cfad0ab3f3308e718a9fcac9ff229b8be2c3dcd5205e728f987c4f448de97708e2a9b27d347b99fa7f7849b9334ab1128aff2f33641ca39505ee5bbe9a5ee080bb9a8fb1d0e4979d25b12b22202fff8e727539a7f616447bd944b7f7453b3441f02fff8617c520ce3a92b64c53f0acf4ef34a2a9f724bbfe2de8fdf0c954711527a5274150acadfebb90ae5fb3342e551feefa5219242cd3f41b9dca36ecc1fd24ccc27cd933b7f9e53c2f327b1d2a864acf5a64d2d95a201000000080314000028140c888462c16844a82c6bf80114000e8bae4e7a5a9b0842905248194408880000000000000004000000eedd8ae8d25b7d08b265f9041d9ca52dabbcab2d392ad319d42850d442ec441d8579fb3b06f4cb73de34385e1abc9838671c205ae91496cf1e8e2bd157ef841e53011215e3b32a1b11ae8606d7c5c6b04672d48298c11e44be26c662ae17c0ab845941a25c06573f926847e811853d3243c905a36796074e60103aaa40033ef81c74e65a7d340b1ffe89cb4cbe0551a05592c9d6d872ec84b84e162b165dd50c2551c1ba871017864feefd6a15d2de6de47f69ddda2aecedbbcbe407c5260fca840c66b33a3f20bf4f92b7f383e810d8c8434d35c9a6071cf403c28e63db5dfc682eadd982206c68b468d23274b154934ddb693ce8a2c37e33622d792390ea44c03045952b151f189cb95a3c7d7be004da89be1d99c1d345fe94981679a25e1a44f5041d2bb61bbd2d88633b9ad79a458a8a11cd361108623b74fa52ef921ab32ab11d4b7c1e1017ff5b5f7f201303d6ea0e99b3160c5a8a669fa562e9f41cf610a611907d18d6a9bc6ccccc3df4f8fcd018906dc525bd2e03812efd380020784a97dfef9f59d41223c176c32543ee6616e098aa380c871a10d72211dd541804011154c229b708d782772cd1d6089268962b0ba86f34af63f79b045495dd67ff4affa18fa2592f4c585fa0695dd4220397546ab6976ca3da34614d5b176fc774c861ac327c6badf81a91785cce799d18aaa122b3c8446316096611fb63a2d69cd3c736fda8e741035b027f3ce64c50abc96860cd58f6bb9cc97095f585006e601e10e4deaae7be41f777247ba26078e1cd09a1db0e947f81eb662da2889dadbcaeb1e857d7cab9cf9555be1817708a5a145a669e4914fc7e2ca5b2aae0ff4a977938a9a1fe0ea6c593a7ef57508122882368f5ee348c1e615aca9609e7919a0bf97ebb73a9d78f615488e2a900ef4ea2dcc402fca0d0be9343d7c632aabd4bf6d223596ae966c0a0f98c725c7f8a5f6474e14f8541fa47fc3d32e5e0e7bc7d553afab2fbdaac3d96a51b5aab134884b7bcc0eed46d6ea429347d38eb37188ac73fce56da279724cce18b32d58ef3ecc32d384dedeb6b0b918c05f635d9fafed6fb61b1cda224297c3f6bd104602c66c82154533cc79c0d6aec6d8783389bc629b834cc3bc2cf4c56dd80798cc1b5270a689708df602b4b1f7bdae23d84727a175152aa80533a59c8e5e3ba53e53a1957fb20cbc28c1a0a83d6340bd052b0ef976b3c3def46adc178f35bf6c50348d6ef9f34f0c8922b3db592d1b74a78ea61528c7f419ae4f9e5f1d9bff15b9cc98f8393cf472116265f14e3b35b3b59372c159ffbacc1f7f57d7878ac6d2b6b6d92306dc3131e8be7ebc9a18866095d80a361f8b3b18282d3d1b71f557cefeb3fda4fcb8af80643c27aff8a369a57dccb4a467661a2375277a3f8b678e8ff0cc94b9d7bbed3f35c02f8187a26451a545219108e1a9c94db30bd2370b190c7e5b9e2d7e530e629e5d5762e096f1980e13a84b8c18af36663387c1ff714a729dd24fd17cea17104258363e482d1360616106afed147b8f7b808c90531cd45a0726f01f1828978e18021241015900049bf27e3fecca2a1e35be1d2d15fca78d92915d36a873e3f70500a00a405322c8f48a64f7039106f328e16532e5a476002d994bfc1f8eca273d6eb988408fe2190f4dbf8e0eb0f1cb0732f5aa174c555672ed0bf8d17fb01d0ff12925d44da85b284fbc0fd5959a779ffcf166d33011a8ad0891cc7ec95be5199c1584686cae2ffddd07a2a4acbf6e10ed766c1cef840e2f2d0815ce3fa4e99cb3cd82782d820b7ef3bc46b8cbe16cf7a3e1145301e4f8ffcfc41f4f1a3c0afef86b07a9a0c4c9548754147156942a8c05ef1cfffe26161875c2a382dd1057d4cb9fb822f9eeb7a113b2d855230064a46cf11b71e8112a53cc393773b268793a9207c50cff562ad51dcd56f09fb74b1852c418789d87dcf271fcec5f45b3e2c5161101cf42f5740b631b8483a674edc37ef5a2fd36417a8519e705095e631e49d6abda7ffb3d4a038611c29cba9e057bfd6d14e08e7533ae2a4a34851a0d8f3fb792fb846ec1821f543530352ad202098d2635878ce00a521cf1ec3b5be22a400a2848809bc8d1e8f67ff00589e37cba50e9856994bb99e0200f34d1813873e1835900cacbd6934091ba2678401a147b2d6634cb7fc812c2aec41d280149691083de0548ac2cbfa36100db361d79a5eccbf2ebdbcfa4d6246e719fd096080306273cd0e029c49becb6e5596d76b064adae2a7e13ff7fc8a684a4b771fee372543d136aa208d1ecbbe11a4779021f4fd74846346c626a382fb4104eecd06b198c724d6b3447c73a20b1bc60db8de5c041da8b7f40d367cd008beb250863782ded1926ec6a26a44895dafb5415866427c5081328d6dc05134beae4cbecf04d24e91df834f840d211cff88dcfb8e31265d1324b98d40f843a2bae78537e4a8f066061fd7cee85deb198db781048b8106c41b8e39426293eca0a0b517302b27bb9f2614a68c94b43a2c8612daeff9d1cfd800f7013c16667f77746ac6575bb436f70bbcd557d6a90176591cd9ae5b739c234a370c99aab71f024e4273f290220cddb5a846a0e4e4b635b4a5f425a37464e5d4c8f8d5b3b00707f93220904b5bf57aae5a31bfe134bad68518c34d0be2029cb5c94a223033a5618a7c8be0d091227849f62ca132bc5ff36f76994aab0ee39df48517ca9560cd3263c991e533820b6ae96438345e26ce8e8fe43613d3673aad8dd5ff7260be168fba0552d2a4d3f5aa461ff68817051ad1115007a6eee03e167de1779ace96018269762b8014f97e370db7d0631b3d9a8660a6b7f908ffa80e4c4ccd9009f6c24ae43a9290b6ec9c7d122ec0b63e06a439c17b1edb5d6420cf323ab785615818ced1623e2f68ae0d6da45c211a402231e34e14347ef02201d3a7e47018245126f930c96a1ae4044e28368edc82b4b6b3f26ff03b89d593826bc1fff5cb59f9668e3f556e4307b804a2a34fee6cd9a0086837ac800e602f75fbd3e598b4e46139d6bebbe226feaf30d2fbe53ca320e15ca8d306e103c0071a8f4b841857a61f1cb57691000682a2ca43596625cffe7eb374a3c0f478dd4b5c9cfadc1ee88f4e0b3959b6e342adbe2d40b5cd0a57922bfdafb8cd3fa1beb5333f5929caf04cdb0a382a015e9881f0a1fc4a460f99ebc726c240383cd57bdad6179d105da901a03c04f7fd080d139a80ac4b7d19196b94bdba7db936f7db39b3aa30a3cdcdcfad6094f36d7d6ea33ebb19a0f649908a02fbc3262a46ab9a61ac4605f6da067149a381501886734539113028a9005dbb05ea770c7acdc03dc3d6b0eb33ac5e449eb80eda8ca50474caccf8355c64f8a6017f7ada5ce14aaaf032e916a9767699b5842275c5995b4f95a30383ec33f1bca69262c25b41200da323a9a8671d1b2a3a9e85fc63e835069716672d0452e291f42f0ef4f25adb5bddfc47fd13b0864d55a6869903f210bb82578853ec001697fa7089909efbc40a6f999fcf0462b119c59a98aeed84553da24f355deb472043dc55b11320fe04be1c0dce2a1f4f31986ce8edb399829832bd63d0d6fa974e66c2ef8daf539dc8f9f1e6d1bd4563d9e729b66fb8321f425468d1790023685ed9232eb4c0ff642a09819867878f701c995dfaf172110c96f6755c40cf56c9603bb028ddaecbbe7b177ca28674a1367581aa4d4c77879eda70190a9d29abca70dfd185dc6ad446d205d576988aec1f8c532ab8cb3900e1feddc57f61eabc36496a2af4c7165274d9f2bad3901f91560f2eee868e23675b8b6fd69784105f3b41cbc79693870e2c6bce13994b9b2217c248c28e1544d861f35b6d5b9cf3f2f37612cc703aad1d322eba370e4b884bce894184db01d1a11d90e77cdb93bca089a861ab91fe6bac8d749b784de1f1e6a20cac60fde8bdb7c6b45dec0b3240eede19dd8286b23580015e29c33333323fcc1a3fc7ae041e3aec7dafe19fc5409adfacae15b10de81cb6a3b21b5606e98ba2d97fad0d870191e04e1b2eaa9044175a63c38dc2d960d5087adf26d320447add80cb74bc6e9cf9c9619cb6cba7911ddb053510ba92911be4c1c0b4911e277c100550e806bb258106967782f5b9853b179865c2c9b0c28a75f2778db871a45d56af647a26b77976fd7f8487edb7eebf2a015d84203a8bb1f7d3e6abb5c2ca0a03685b69e0d2f9d79a0eb1bbdbc8e619eb435aebc6567f4e59034ba181265f144384cde0c13d091cbdb2117a4a46da8eb23f4c6bee8cb11405b7e37949de7b2302e9e99bd398ba41d656392a8d8d6a597fb5e8216bb566b11a87632b9880461fbd6ff8beb460c45bae8f233c52f5c1ff4fb973cfe9b8e5231607049314f421448d1f99aa6423b51047693e818025eae9a19d693efe0442bc61c770f33dbfe10a2217d69cb113cbb781f51a5595e507719ea1bcf72e2731d4b1c4ff932dc5b70c3a341feecbb30b34921a912c576859067c803a9797051b119ed2f14eaa58c5b088f1c23baebc801bf16a78b970ff726e2376453791093863703a75ebd6d56031980487fe31826b3ff561529d7640ed3f20843442a7942f35c384eed5e1a0831226eb2f5debda2b088006fd3720337ca5f4316f950285fedefe91657fee8c4e2096455009e6d5716294a15028c20fcd9404d2be1570a7b3f692d9d47520410066e880be30b85902ee1d605edabe715bcfac43d03adad2b17c880314896f7f3a77e0a9943c6ad8c5601d808b1fd9ac2c29db341f710d748b833986e7a58dbf6df147469ab8c7c969665bc11f9963c8c29736c532056eb4b71d2283837ba8fb0a350489a5a12d34e89d51f6b0e8328a21d98f8b9f12d23f432f85f1d4eee3008294f83c23c5d9a1b6229983576a07468f63aa28dab701abc91b319f4efe6c2d37b06f8e73e9e56de41980b41b5c137c862e3b08b9a33ff181ac8c706de070c366b51670370ed385ffaac99d097cdd8030f090ee2272250f6686a9667546b3173b80aaffa91c679e95a4bc51d09d23828f34f78a13bf530ca8199ced67292fc76f3f8984b102f46a13a72cb6f76251f6bcbee111f8bbdd4eebfde07844ca4124482edb6ab5a73d48b1a5013dca1453295c40557d492e2d1ac6851885d4870d138a945bf00f7cf636a22f86f77bcacab8f077b2b9d119325e1f2138d98ed0ee9a766d5eef2a27a5aef0a13d842629d542f7a8bf2aed6868cf1dbff3716d1f13077bbf4801043f8d2141c55308389bf0e7b1bcffcc018622fdee9900ab00525e5067dd22eb163a6232de5c8282ea45ba11e72f7c39df5bae6793515acacce2d09992aa9ad568ad8403907aa34c74e2edab42dd7017ef775efc00b28641807462f633c66887a8c506e3bc7d8053657a018f3cc09ce1347e7fbe235c96828a894439aea927060ac512d9c60191c91b67f1752aadc8fe84e1a7de2df01049181ac367423cedd663eccfec79da390810797f6e072cab3bacf5f3bff731be09b296ad0a565eb51ad35005e2ec3be279265d9ddcc98b46ce6b4362f8d6312a2f1e56976cc68b449119cf3da8aa1acae25c33392f188cc49d012be0a4ffbc1e9be08b5fedf9a4f762804c8ea526cd579893db0310836404fc3a5439564d931cf808e8553e878e039fa78b740d85613ae3cde08bf40a6f1664f4a92e604cf07cd890e9c4498a4c852cdd95787da84ee445d2cc0f95e6bbcf5c97f2d004e3a3e80febeee3d4c23280c5e2f4104154f391397a0b31229827d00a1fb9e82da686e096ef4ac132e5b3bb2f62c8db7be0b51b4a56e8442c2447f78e04ca13b5551d51088fddd66f8eae84f2d12f2e6b723dc575b36519f8132ba0c50243bd08226ba2258160b2a4304ab467b519bbd365fcb534c3438bfe6014356bde4ff4d2cad9fb6f80d6eb1d71eadb606993d1d151ef37e8cd4fa734c90ebc4ac494d0acf713f2109b2bd937f5d57befdb731893843fb2fd86f7571cb44c35d47b8ad9a8fa0e88e7a6fc4ea8afe98ca9f0937d54f10afde0a1c24d3fb91bf0416a16d6d8a609f073991ece9ceb4a406c4cb29bd4b186f62cb9b5ca3c961a2491494174ce75ad312367cc186d0bbabfe84d372a5dd36bbe8dd4c57c0f79169860f56aac5e62304954a9fde23bb1fa29070764a3c3e8a4ba770018de1f9c6f3c8a864a6203725a7ac029e5c71578bf879ebf571e53b8a411ce19441aecd481b137edaad06a6918813ecefe26a9ea04c8ae27de45253a0e862c71502562c442d3eac770661c379c5b8e5df255d7d210b6daf3e6b1433a8ecfbe0a307fc2c618db4a91f1a45391f804dde7d86ee9816fa8bc85850736375fd8d0a0abad3adb6d3c593c4fc6a89be59278e1f2b212fdd92df73d2d96c34e19d95d8fe7c2e460a5954e58de7b1cc6fd17542cdec02ce4adc9674dac26d762f4ae8ab3e03eada15421724c4403affedcb6e22da05609f71e4ae7d746ebadacf9f320e4d7aeaca24accb7318937fe0de94140cc8c06217f4c2050f014351fce2089c4a32d8eae171eb6f0d42de9c06acf1ecd0f4c6b15b21f596d5ba5cee5bf47fde103401e75ef0ed2bc044387287938ab3c1b68fc6149f47cdff890d0eb9945f647945ee689ec6b9b7ad11ed5507a71cc92fe7e6474305b97328d83a1e161aa4b339ba057f428f7d4163b3810c0599d375a8e1af6b53be827cee52743d26e5153433baaf568d773dece30705fd1a96d24fd3390c8d9d895c2faa61a3b62b9ea8446bc81bf7045cd204eb2e8ae2432ddb5876ac5350c739b6390719098acd6b0beea0147c2a6067566d7a1ba63c985ec2bd771b0810a68b207db8c1b4b6087af98116d8e0047180b60c77aca651aa6fbd13391ec4c178284203b3f3e0810911281993c2ba833814237312642cda2d2b4c98d10c85963998470282ea76432623914e02451dad0a486670a4893281e1fcddd45c9bad864b68d6962e8aa55d535a651bb8cd412d0d6a8494484653bd523c655771576c52453aa61f44c75804406f938107e8126075a8de4e3d79751a15941cebec28260bdf8c68f2e69cc6901858c9008d8a186d324ce38a0228648fa52862e77ad81ad7855703843a7b1ef4279309062b678a3fe2ee1d6cb009391c85f90c84030be96f6f31e32b67e1fdbe0026b2a472f519629076b1d1ba3f882ee3f32966a32dfe436d1840bfcb9c2ba1319d21424a71618c9a4a3514963143015a617ffd08ac083bff7d15b6d0950c3004e8832f9187a25f70e94dbafb085afc7a18fddd6d6b761943d8772ac21657871bbf0a87bdb74417a8db6a828724a55a4c3255d0f80e6c5e6a4550f79db173d9b1d734f4c994e684ceacabbd329f16f9011b4300d8e37985701c8cf72c6ff3c4c44d4199c60e679130a4d3b585967c3e419fb3fac2e05448910250a74c78a8e170a1f4c642d94e549726c4bd4e44828ef44ec588b344069f10a7595dba202f82438394d896270c62ae53db17c78247f199b4b45d3825abacc6f1ac45f08a98d815680028847cf6bb18fef4da2761e01d13eebd747899a024469fedb60aa955b9ab1e5099d077d3bd268158ce7813266d593046fd996277f02c1fe1c7f059fd4a4af6fb31804b7fc888a85e4ccf7255bc22735695d444b4e2214b890979c980c0a944d23354d2a18f57d7ea307f4b95060b2133ad2d98fb29b7e4b35803183ab608cce25d22198980301c281cfb2198e4286138c0426dacc7525268e623fa9c049643f4a5f96cf1e66a6c5466bc7994ecc7602ca9bcba2f178101ccb86e183858d5f28f22fb4199c78cab389e2f52a559d67d79bb67a51a72ec66152d02f78f7966ca5d8cf838ad9974ee6bc09b295340affbd19db3e5047651515daa6bd85445687dd8f713d0a7ced5d7d3bd3904090eb40da2bb9ba21c7ace17e02a6832a70cad0579874c35d5613415cd571b1c07b92a2c02dd7a58f1f944bb31ebf1abe3757e0e237c70f9568ff6945a4e78fa2b6c820cacf0c55942400a01c9fb0984d69924f5ca965909145ba09bf3834f0dbda77e9009af1a13439818924aa3838334e5a320f9fa166e1961d3226373471366d4ba376883eb00e9442d4019600f311f88a2a5eb3527feb33b74a6d14aa2ccac45074f948d325ed69cb796c988cc4a46ec5a632d7e96a9bd821352d093438567c54d7ad697830a9eb8a3b5daf019a63ac65ed3f062d72ae25301356b439b03790aad32eb09a49ebb38bebffbdd603c2cb6eb18f5af599e86d21239a0a8ef6a39062ea426f1c5912a0939e3800f11c2ec3e582cce05a7e5508c673dc14610ce1d5b7fba0180cc4f4d31bb4a264aeee6a51338090ce5ba2397ca82f1134e5306c130a25edf2ae61d11bba35138109e16997ead490472a39f5b2822bad499a83f29e50228087ee6a0eb302bafa433c3be5c287cd5c99653c1b5f18a9b1dc0c2c9f15c01acf050835dd5ecee66fb2226cc70101e7b2456c9d86727d1fd28d997a57dbc62f28ff6f8619b3a1240a06653111764c4081dcb61b35998af0b9013fc46eb1503597a3a232bf352374ac41b0123a7a51562ac9334adbe06fc9a3b221ded6f68fad593f061fd309cd94adafae2e2f0a1c25fe02d676936084019d0f2dd0f3c7ee8113eb42e5817828af4d72ace8ea782b2edd4e66fd742a77790f64456c07c24701dacf41329b6aa5ba480e418fb8f32bcea70a254211a3f13958840a2c02b9c227e2cad152cd6a2b2e290c13fae66affc2544390038eb7e32cc6a347afe55c19ddc1a342f8d43be119c05f1df80ac83d63bdc1a1b95b6a58dfc36d42f5f8f1fb74ef90370da33c81f7c73791002ea0b345bcbd9ab292be43550873a1471186b76296b6dd6088c76ab1b9d12db19e0cac9ca02a56c0f4dad3155456a77b619664f75576a79ba43298d138c58bddc83ec1242cd94ea18037ab594df534228ee168cb48c907150c56ba12a3340294c6154095cdf7bf6ff4c70309c464c238d7ef232cbd5b8b0a3fa5156a5046582770d53a040060f8c5b5558a128410da607b93a0f4063ff49f937e31a65d6f5a7a3afa5cfa45f38763854236ef03d3f78b44dee13e4f954b0090998d922530a3572de9c6f70f093b3bc61d1f04b537b2e5a840851ac83d838a2d3c32105f704c0d936ef707c97c09a90220342bcb924e3c6a48e1d61372cdca9676159960d8ddd0ce219a21caae491a1681e28f26d5ab13857c36d8045d640c9cefed87bd5790f482e68a35138d52e9fadbbb2f3af49ceedab31cc4e84cb5edc9042477ccda74a997e1af412efb5491e0861cb13728265424ec3ab0f09c8cc0224c001ec2cce59b7c2d192336d753f0fd7d708e33964be0292c0df02a9e361d07c0374e23a92d86f91c80278e7d44a2537d97e5221744f341bc7e568baceff4e4e53e66fdc7ed055d42c1d6802cd90cbadf6dafffd0ceff4ed762a79db9446c4745fa530b9aaf229f9b1b91491419d423081eebdc98c7e04dc03141e80c096347dd1bfc991bc8afbda694001b775b9d33a607db209b2806951c1a955b26982d0b1cc2d330f45241a3c8d8b76ce9b20df80ac50271c6702de907c49d151d6eb293e52939602e719324b8acaedc94e5c4742c27cef063b864bedc0c972c955e0cb4b62c4bf66fc44020154818df1277a61ba68cfa1b15fc2781f4ac8eead8679816169d4abb9694fab8b33d98549c0de95e29ea13d432300d30be91c87918ff9b60a248a1fe4f82609d004f1e608c84538ddec63b864c150a5fbef4859eea825f43145ea6100a53d20ff2870b1edddaf58eec07fe6fbe9b4ac17ef50c7053310af918bd0c38530e78c0ec14251daf0a3e6178bd245a66f9fc01a4498c111ccaa2b4450ebc59570343a254e93e3f15841225a849a690d9824f4faffdbba0ffe6940a93294efb52b605503d918b4151b6415bdcb78937a712624f5441e9149690d839e15b56e5618a0241687c2822af26e5b9d958b64bc446671ab2081fe3f6643ed593891cf1a5c336c5aff52dc67afef820a2e08247918f6905a18c04c444b59c60c70a47956b9b193182a9fafba3c02885d92848985ac4e84d3d316c1bafb67face6a13793478a5e6c73ae4a7ef54d5f49746661c7ed173aca6b6dcbd149d15a23cc34c0c4ada532cb26f357c83c2560b19b667bbed15be7e13a53e4e28d3738342387e12c68d0cd61e51370604cf1bd9ecd75cc89589b2d14c62ad0941605ecda8012f6874599ab2499a367e3c3b47f6d98fd4d74ac295411b3f54823c063e39832de3118dac3f4d4cc49acd10061cc9607935588ea4968e47ba4dbfe97813907d9aff6b4ef466e092b9a12bda7b1d5cdf761da86ea07f5eb71c485e6874520e074fd654690d7655c10735ea54f85ab1b6ea66032a0388b76eab2f684e8321c5e703707e5a83046319786de6a509682e2255cdd4001bf6fd4030f9494bc88ffa92e42cf95f0a8c748c8c6eaac94c1afc186b681cb49b5ea155d4d6a81fa2219b79e1623f70d3aed9734216c903e1f0660ba88c530e710456a3e4eeaf5dcd6ebf9a5cf2502a613dabad831eeba7e099780d81676c101e6762f3d358f47499192d633534745c2b7f7125e68a72d7d210b7e0c9a0dfa4beaa0bceb50faf0354ec69c1dc9f17eed1c515ff84ee4bc48bda36286185327dbcb71b5287d8cd211862f4c5ce2757599f3c9a8a5d9d61aeb0f95f9db99447407f9f805a35d7b1e70598926b40799a3be93413ec4751b403767faa1663fe1d1f818712eee6e01bcb9237c695d3f2e0b03d48976225b3dae01be04316e5c7c8fbc340f3425fe1dbe11550a66e4e6b27bab57d3419c3a6b8435f22d675a57bbf631008c5fcbddae178aeaede98f8f1e4b3aa14c5e9579e34e27c2b1e281e80edeca044208d9014c22391adb006304be605524bde683a53d22469ba9b6b04bb7557b21ef537af005b8d8ad3cb921da4ac5ccd3fb00728f9cfc1cd60b5ebd24e77ccac540e55399abaf437ea633d1275af02aa540a817e7712e2d5ccea96521a490863d07492a759c354995584e4787198d7568617408de613a21cd4b3251767fbaa68889605071937e4a7bece0596713607a79d7c975a04724fe15b847cd86ffa9ecfff7481751d32dbe387faef86b6c60350e541bf64d19bf6b5806e23cc920f1fcd101129bd7b54ccbfbb80f52f7fd4ea9abedfd9a782a912f387a798150c76de14be6ecff583a113cb28ae1d105c5622483a8934dc81dc96f311cd218df88bd820a8660bb7d0cd29a06a0000cb70e0e09a0fe6538e707e2e782991037a6cd372041c1ec11e7242f3ec93e54aee06f3ec19b07054721d9c1329efee692ad2fdd65cf7067d28577d3de0cc64917d25c28a4d015305ac28b40b17ec87629412122d0d5f56cc92b140deffe4011cd953039593b39152ec33ee471a175255c4e0e7ec60ade64ff856e6c8ee29bc58c3b1961adb6d13a45106d41c5c30eaeb30885e9a26ceea8a004d7e1a031cb8ef7a7be269ea685ca924f68a29856bde9e1912e05d0b15f6ca69e8ebf8cb0c5af04c57fcc305bd5c07e2574504199ce09e18248479fdade5c564717cf9d44d6d54b26c44deccb8955714cc1ecc4dcaba75b4fb7901de64247444392159fbdfa6fae1625fa16daa92a55fb1c58edabe18808d9d9f53a7fee3ac3025001b9e4a2d36913f135ce35f2fc4782bc1998221c82cd9888b1a16fab5573abd21b940aa9a34da9a073b945021368f6f0f7aa2bdd2119923706004ca9fcc758976259552c5eab5ac657b6ed529edbb4ded8aae7b42ab9b471b27d97929f88b8bb06213135c474f540175d977300a9d1ba152fbaf871cf90777d03d4916578a2351ce8ee93552b2ac8dcafd0850061cad39915d0baaff78195ff8b02bd3dc02b5088564c1b5c623817e57e472f161d0e175aaf455b74beb4706e22e25407f046b45e516853834378dd7c8de961fd491497057a26bbe8dcccbae0cb5726509b01964db502b3de16e6206a2980aa306291a2f6ffd0a16baabbbe06797210785dbf51a732ca8ef6e75e001574d90450e2c11927dcc1f414c502a89ea46edc49b7a1084463814708f1e06352a08ef1a90f57a6aee6270a15c1be7554e60894e920a195c3172bca0a7f65fd2d8286ed8ca608a3229dc39e21445a6571adf105a9c29d02b060678d65d97f263edc462445c431b3be1af17f122189d71d33ee53c071165673bd349b155854658a6211e7eecb1f7e8f6ff570fa9a1f853bd0821453ddf889ddc49582e7b21cc31a3a1f61a9631646f2b2e4e26bdae7c59ba21f4f22f614537edeecfb8309a6790b9deb8937f55d9a2794bb717254456b01824ed8d44d11b9c4cb0bdf40cde8556542394ddd2a5a3abccc9833931bb8910044ffd3a8732848d6065c31ce8653b73e4754cba683f937fedb1e2e03eac15ade42206b5e09447ed2aea6e82464e8b62bc03ed603095d4279da6ac0677dc1c796d6e7f86c70aed563fa62625b955f63af295b630431d3acbcaa68dff226b810933174cb59e5761dcaebc4119ca0803fc1b15b4972ec1fc9041d38dfc2e2563673f361ad0fdc0b2502d8fccedcb0ce6e5a9211bdfdc9089b5aa102084f1b432a24d8a04c9e89ca7d3a8053ba18fefa694f8fa2d3729f689a4a120e389bfd2ba50b07b934e36ff8133d17563ee2bed105e0d6a38475dda641f53b188dd0f2ab7aa348ea625339b8f28cb125902a0dedb43e66d6d7529aa58a079978d127944a8c468434e0031d1d326bef82142d025b0d12ef8c709ae83b065b022ede9a7d7d3ad2a21408db31385d217977a530c180fa4563abbd168df9f08da17ad733e048eec04533654407ce2f3202fcfcdb2fc78dabfa9a81a1347fc70a946ff6dbfb5206406200fc00b3c0948d83dd218a9f3834701608d0d2853c8d0623878a0a2198d0cfda3e5c79595e0fe76de176feb5a48ee5d8fcf113354c10e01ef73afeab04c63db530b9dff4331c727ea81f8a8d92ef884a90d256a480a3df2bb4b3f0773bc4cd47f5e99210430785412e1abcc24941d0a5eea0dbaf1b8254feac424ce74002823583b25e78d395db6992a3d4e4ced59d0729b2dbb772b37445e0a41c22f1bbc041f031959387d6e484f3a7567c74e6e714ef499925fc959b3af771d3a8867bc8f9a47a885b05e145ad9d90ba26d3196506102869d204e6c340a7c9e697acb0e58b37052131842087f5c23c9e7c4ef1633a0b04a89f12e870e245ef42893b24860a8717b45bb70891d1fac6580fdaba293be0140156aa97b7ef7908268ff363ff4896b114f015afe35bb7ef03eec0a1cf2d004c8c0499b20b22e441749889fe3c5ab5b59c41ad95abc4879fd88df6f3101899593d9892b43cd8b3b079c7c86cdd72ff4d2177d45610348efb4858b66eb91bedb4de440eaa442c097721dbe98f02a5554f643353a55d97543d55dd7aa85abe70976e20707b6655ea82219e113f0f4145cd04b62b4d708d448a607152cfc64489b0f9cdaa3d804476aa1a20262eef9719d115ee79b80e3e76345862135728f487bce50d880a20aeae056ec68412528900732b201175deab7f81ceb6a25a401e69774eaf05e67424299e9808d60d27bf47109ced1e44121199f2db2dcc47443445aae42492ccbd3f426eb8ede187cdde2b30c4cc1bbf997dd3cef5c43415252c234795bd575bb8d121a079811f76b6dc4751ae9877a9305c99542c8ef67f7a0ce2a864b898a25b1b3d90c63d905212776eb15b6d27fee1d3f18fffc48eefd8d9916af43a7793d550196aad1ab77bd0689bc7134e025466e2ec813b8d6758bbc46c73004459642bc220b82f0028877681647b3180d44f5d802538e0f4ae91cfae3e37c5f6c45d4092ad3d55a12d015324b9a91380dc319ee7cf71b07072df3c01b0bbdea51ca770e5b024dab5c0640737056ffa964f500e41d7c25c0388eb621087ea1dd5411fa61a068108b759f55b12d2f189420c5f44aa3c500de267adc765e08fd90a2c5e3123798d807f51fd64e279c221f453ed0a77a21a1c63c96a4e256bed07184fc984644066495605b839f315389d7b7dfa5d6e0cfd1f2cb0e436c36e355cd248461be5c252e8e902d31ffc58aeb870e17845c4de14ac69e98d4a58dcbea279049586ccbc16cf1c5d54277ae27c79358fcccce2b8dae9f5cccd01e65f65485c13595feba1ea910f9541d07da96334a3f3912770f9a8533dcaffe299c9609183fd8cc3db4f753a624e5a2d8c7546614987d6ec1e6766218cbae119a70b9c04546371c003631f353774014a1ed70cce38982a04123914d0c049cf70317ed6d22bfb19e71142061cbf6e2d6b37a08353c541300e37dc6aca808ca3f6bfb1d2138ce3c42e3f51776f203c8871ce65d4e5f24bab9ce2003bae32ce4159cd2be657752a19cf40e6edf1133b2690ac31445a619d4211aca848d904bcc810a7e2ded17a881f43d9cca8ffac38154132aad5a631d4c10dc86a7203ebc224b5dd6bb7dc7cb72d2210362f86cc5ded0ad2147489a42ad0de5f901e5e94eb5b2ba124cab9c69033a5e5e7775b45df0b446c78f25a84281d5cd62c2429af111c5f6108f5fac95e481d9de7a6a8a34e336a04288af667d3175cc6313b807c71f8a589b0f61ce4dfceebf13f3b965f23e1181bc1cf6e21b08ca011348260917d8e18c59281dc696e8a1d9e1e58587c124257f4f109ae9ddd83859695effb78ccae163891a8e9d921e28ebd38b1c7aa06ae851efb692f382437585ebc0c6b43a120662ebadd481c1ac7204de98689d62812785df8ae332f16786329a2525d9e0771c0c29e2ee88aa83a175bd2ed5109babbaa33f6c413b058f67dd9a7de20d7ec429b9a9c706ad9a4ae7b97e57175050df71ebcfb94249cc3980fbfc25c14ebd80650dffd0e1040a1a4beb0036ce63421eaea85ebd64a1dac900cb806e4f576bb802e207957678d5ebec03120543980f5276c032509653680cbbb0e7ed494a78e92de82653d80a53a6eead500755878c000605d9e575eaa4dbaf8751b3106383f33454386a7a1eb96777aa1ce5095ec6305cce3da1224ed32c07f09499e71e586488527f8bffc8a49176cb438ff44e1ef83316e8a76739613beabdf2bda93d0cbe97a8f168f4bef3c3614a857034be91e8fea54d63bdce0761832fda2565879d1b60736387273e0a73a726b04fca3c270adf5b45f7eb4d6371083712e94de08c33faab57f41e9dd427500c47200e6b6052cc7b81e8be5e669bbbd3d423c84449e945a581c184ba7f9701ad1e31cece1513daf51b26e9b5e3cabeebb361de53bae4a87f77b1150bb2ff65463c7f969e5f4859d552d73a58c39248a5bf0f07cc9122a33188bc4751a499023cc03420195f516b26f88389eb4500117e716fdfc80f7467840e0598130906c53c30cb5b540f5cb0068fea85a54a33e425008c0e69be429775c79aa208955f19930c7a6f37d009f3b2271471f7b4bdf957d96323a4df82c7255caf1a13409655c65fc4f781693f83aad401992cfcbbc93792dd654d95ea53fab93c7a82055fe16852244d62d34e3481f6807d2f71801a14bfa983b44c3ffc9434a12ae858b1e001abb5452b90306caf0910f28afcd0796a6d52945525ab524ab522cf93287762d9a55c5b3356652c9048af8c752fac48e0c714f31b24d52fa0474ffcb948f8e984ce7d386632a3ffd5866506e7093006baea0a2ff0d9b455049cbefe071dda7a418ba154ff5ceb0cb43132ab1047318de074b2d52232862f88a288eaf726cd2ec1c28dffa1231914d016560d10e1f78842922066dbe7463d16d928d1b94d85c3ab850e44418ffd732401854e79722f83a4109236d0538a870006c3c57357cb8c9379f41bca79927b628f089a1188394a8758c2050d617db9632d89c2af4c24f133078fe0eb43414e2a353099ee92c0125311ce2fe0fe1c9bdefb5c80985dae998091be528dc4d1d8e0d1f33d2daa19f3d1ba3fd69eb2a7d77637a528c16d6ba0bc68c22e875c0434b0a1c22085782541833a2f2208f6aaf7f1bd6fba8c11098cb61f664feccd5b1e34ccc984ce420b4f2a9a196bbd79da5b4c90edeb0dd5409518fc8486faa296a3122d4a9a78ee9de33d5ca77fe0c377023473a34dacdd3ff3ce98ab7fa93ccbd4cc1aa5ae5d4181f36bb8d65cda8669e4b979c92086bdc0d939461aecbe41eb5077c0a072fe63acf99e459a9d47ab62d96eb8d07ecd0bdcc088b357a8a3bbdeb9fac68fe8ae3e712516a9631961f7cfd0c7790866e44d22590a7398b95c6625ab4cfe45eb773828f09e2225d1f8e6995d63d38ae2f8f9338c2d43c7676131905d6cc4d3c83e62c4a3e4bed87f5a11b1da489f0b3f956d2bcbd5fcc4aa21f27223127b73471a59f78053c4a944d0d4ac87d9df9ad25312d5d43d7c129208d4a244fd94e9f9a59bff21778b6843c081a11a54b6eeb931a414d4404064ac67d46505c02a881514796f5a784d6391b97290de8b2d0419f5551faf9e805a0886c80471e300b5344bcc9664dd12364cade87736725fa91ee5d2d5d006dd6ed1d4749888b4b180779afff500e051426362c69cad72608a856c8551415575c6199dbd2f545036b03fccd1889b037209f2f8499f0d6e80ec00361e32ee5b9919e61f5b1d946de9f37b3b6f88b8aae067ef1cde9250f5e93d2386eb1c0d2210dae36993e87afc082ee0e1a1134784e00c0012fcc854c39b93b3dfc1d53ddcaca10b57dd160390753dec66e71e39ee86abec18b976b6e573d0670765343bfebe8f48e5b80cb88e38a9c41dcd83d4d8097dba7eec6f77a8abd1ee993a738cbbd5dbc92027d32f62f569581d30148de09f5cf9f8e2570c0c78b263f9ead6b32374693fe59d6a47fb4f5c3295e1383b76267eaac997652ffdf052cbee14c0f203d788817a11dd2e4ad46e23e6eb4b4adb6a0da848be239135d28adc53eca0c1256c55d85bb0427dbc57dc07c2a578c186d0db88a8a50fbf819ea7de0ee1448cbf18a119423a9536222398706d024319583d0b6a621bea05ce2b897493fc6c979f94220762f332066bfda8cce175d52ec989b0d90c50ca95ea5c1333508181ffc47f13ac6ed371b1b761d129e674e623b2c5d905022426cc3842e1f88806af78900a75ebfd8e2c2e89baf45eeabc8c77ad6aae838f3820b990b1021c10f6c56faafc35c0ec884b893721fa466e2519dc2d7ac2814245b9d5a5774c12e222acab87c2e2cdeb17784b28d2882742bf5000bf1b84ec32d71a051fd9b2194837e2d0cfae9ca98c9ea2e4b7fbd4c7e7c3dd62f940f894c76028396138dd45bfc15878cbb673ec991e5412cb6c8852c7b90c9d491b155c671d3a7387a5d1cb4526a8784fec13de70991f59dfeeece56fc6338ac9b3240a52ce4dbd9e4d3de6f29171df776d6c67e0944ddd87d8ab653ec784b821e7a5b79f6ca5ef521c2e99891f34c4faef0815c6020a0af3dff6bef701db988a14b74327cddd91cc48779cd0ae22b12c6df71882cc916ee9ff7b6a01eafdd2293d043cb75619909a1a5111990c3db5e87ab471d30533d79ec79ec068e97ec074857b7d82cf5ae06f329a46144f626409af5fe5ce37ac9cf36e5ce07611ed26cb6fcb4b208e7c9d3ef7d8599bae89f7f31b4cc2f9000f1dd18cd3aac4132fdff2dbbfcf741fbc489db0e4805d30d5d098e61a26abd5f56921bb18fb129963e66cfcd79664ef1600e47f619ce0efdf8d8b5329e72a4e63693f2158bdc9516c1db015b3e0bc249cb3446272f5eba9919b615d774c126d222745bf19616025d9c7338a84722f9290c0c6d1a6827575c2072a745744b7c23d6395949c62684f878cc8f6736d9a4b9c8b5261cb98254ff68e3865c171b4bb1fed84a5f2fce584162595833020908818778ec68d5bddbf90a89641baca062ccfa260f26adb6a6693072ac1aa5b8db976986fb28da1dffd63dc28d6b27a5ce0994b0496b8d4d149f00bb8b1503b5c7d5e5498f5e1006bc71f235aa0e611f7d8d15958b7e73b56eae9d0b214ca7646266ac0186d6e1857eee5b0b2b8a7352e2588454565bd77c4512d13396ac37799dc62bf0629863edc1b260602221a6ed026732887127749a8f3ab35bc3fe1051e2db23dfe2e5043859857f09b4357e225c536eef811b1827fc5cf34cf9d78e4501238e7681eebff34da4722b076afa89ffeb7bceafbe042e248f4f4b54366c0237ee08d51e498224c23dd16f022a4e2c1bca81c237b1a4a0ea0ec788005a34691fdd8e962f75a7917523d3d5f0dc7f346f67735c7024728993b7e132ee245774d82f8949cce4c9a466ea56aab2546360a1c93e545fe146a30cfdee2ddca39e888bd326b3822f2a3faa2d957a64d6118f28e8d4429506599a09124b26e7593de9d091e9eb8bd7d179f56af7b744927b09b9e9fd5f222c30b14cf45c6d4a6a89e4c780506b9ee0ea62352e01891d00f12f40be24b2a614a5ea3d8b8413dfd602fe4fc259e0898f8a204979ff479125e388842ff01e3f749af3dbdaffc1a048480811b7f6c147be8cffe33945be79ff1195e0c80ec4716ee790cfd9615cbb960bbcfdc788b8c7123734be9331b4bc0a167c7343e53520a31c8b1a264e3b7ad7c6149a151435be7aa9472ce2d0f6a32133ce3c864bb54ab4276ec69bdc72c278744b4cf75aadfeb9af05e79109442662d651443c84ed47493183251f8f6f017434c207663178fbd1992dbbb42ad76de815566c55fc3119b5669f9c75441a8a4c6767fd687140b1c6f017b215eb729cc18c7e743d7cc40d8e7b96109a2a62b79109088670f4430d080d264c5387239dbba12fcf3d1331f9463f00cf96802a6e31e2a9fe5bd7e695eed2cd0f34ba9c36d4d4a10c17a3eb63a005ac45a5a5dcfc48bd090e42d938c47cf988af6212f9315b0e4c0d98764fdec46314f0a4ca90becaac917ab9e98c469a450133d81bd76bdf8c812001a1c9e8e838b01ab98098fa09ee6dec6fbecae2c0e2943a9a9a5da368aa4481c381417e2f02154e1ed789aee1c016abc4d318328c0343402fe00f07d63df366d3bed31eb006682313f787038bff9c411b05ec38cff49864a904078a9dc1e5486a352c83a735bf284947fcd33130a7b7f261b8baadaca283c81e40760d808b5f101d8231347e530178c179192e0247204928a74269379054c8c2889cd131f30a500167d4e8e4b5700866d02e492f91f57f5747d2da745e19d2236defff5d43d63f1f41ecb764c9ed6aaec762166331277afcdb86c05e1af8f0ee55ef3c4c01b56d0354b79bbdb87be653a460b6280914ad73ddcf3cc65a047c0904a339c63316e0a4fdadddd97c8215b7af065d54130dc9973dc07aba2a52513a069f12b10679e5df84546fb05681e4cfeb37d89ac1d613f84d2f364d19c5069dfbcbe5f195830452a8d2a13292bf300371d277718c820254ec85082d858ae1248b37675992857081e31cb6c45443335540b22b804ad0ad3fd8d6f01527bfb75f3b6ec6b953f52e8c71bb0ee98091ffde59eca5ac5307bd280678df45eed2acfa81630f70677ba3f8932af11f39cd7169e84f193fe71546be0a5f70e6bc20de4bb269ed9f3380bf4bed3f0208ae78fe6a9940d6bd180db88d70f0ce20615618b6acfc010f5f8e2c42082a66d91614728bdf8239924d12307ea5ffbda6647b281ac0885bf16844aa47834a0da226561e622e2700e21356ddc3881f50e965dbc13db142ede8b2311652ddfed75d3dc7021172f9815ade1dffd49deb51dc2ae109811ca9210ffdba69975820ddea4a310bdbfea0398d88ea6ad429aac9d0a3baaf14e137a8f15312640e930bb70e88c658ed900a93b16f420fbbef3f12e6c30fde3d84b8ccaa6979757c180d97a418506420455236de44c459f27b8de4fe31c002c424f630b6b6556e5024f2d163934fe0a4de6bfafdd7f16f10b228dd537295186f1829539f1a6f3fad4e61e3b7ff4ff6c11bcd8e508a85ca93ce277f3065f1c818a49455709fcd762905f9addea4b73416dbf97eb2dc49962cfd867b661d3ccd6b81a2be8d0116b49aec2668154a6a0d307abbfcde66d07205f485a0a4b58d77c992f00a8116dd699cdc0bfd76190f61a28c64a5e5eab143047835a3e8b0506e7238410e126442efbc602916f1d6e12af4597b433977271233eea4453b33828d799f4cc7dfac8659f6c3a9cf9f75ff2003bd467494d98c31f3f88a7c60585c54ea8b09d320865aa5294b87b4de82311f72469f7b4e665e283e6fe480b6258c9a8f75d4f4dd66290929922ed22540165e5f174c9be9f6fe39508bf5103af4a46c813f602e49c9ba6e060d7cae2778c59068fb151af6667a4f250af3630d0d5e78d0922b57dd4ddd48e928a588f9c05a31f6164d147a4931d2bbaf51484f21de1ceb267514699059d77fa474c6b53bd8c4c89e8d950f9efb7457810648dea37db77057280c6dc5838ba6fd2219c27227e81050beac1511b0c23635d0fa3c77441c038a62a090a5c58c9c7d356cd3e2279159a55252392f0f26b75a00b5f9d354deede4963da252d4f38b64c5d0cff2757c2f8be87cd27b9d4a473f31ef66ff9990ad900965ea0da7dfefcfdd58f16593694e1ac8b926e14387064b02bc13a89187cc2c2013b4f7af55b4e2bec62a0cc99b2178882e7d7924bb5000926b397004867988bb417b5910b22a82b22c666a652e3af08e601227ba0c34daf1809d826ae7144e2296ee2bca6ec144d1aa01f1c089c7e8714106cf72386fbd3d0ff0e025d6d2dcfb3dcfaa2a327426d133a34b0d6db9d8a098bb0272cb016e6e698d063c21999084f5707a5e5e276e20a040520830cb5bf625e81c45188f7f592eda12ee6af203294d98b919f3df9f6309134047de850eb5ac3b00ff91cb3fb5ed85af2e531a347e08e8baa5930d4ec13bf0907469b8cc1bff3d3f6bd325d0271fd0d07a0b71afce00f2b2c6d26fe8c01074e902492ddc8edc3b80defabc000bec3c5e7696ce236261394f9795d147b153bfce728a9a939c798b5c8014450d568ec1449af09b5953769051e9b9337283bd09f8a969cc371197037173c4b2fc696aa57f2b6248cb6c85216150a814d3cafa6682deeec3455b2fd6f68a9a6250452e00de8c9ff6e7e15cdc2463844264767537f402a409717f8940a737d1d073d82dd61ac1315f071cb906a65340fa2553607f84ee405955ad8bf7829a71b222fb721a4d0b2425210e1b666562b13cad9870a5c6870f82c051fb011a1d85f1f61969f0d7eb519fe78608d7db274dc3eb6c9be7c4f88f7113e52e8606d74b8be5ad2fe74adfa10d1a3d9b78135e09c750c54baac0b49a34423b126753cce8997ed05202b3359a5d09604012cabd72af141f71530cb1cb89092e84c1057c897f8fb3bf3567d40a6709e44ccd9627791a2af68019aa8fabff9cf73dab7a06e75afebbd56b452020b08f51d2089c6f36e7aeee7622277e8068979d8b0e8e544587dfadb463fa1398f2932d0a98b7675fd2dd824019d54a66b52a06429c96f65065320045518b2aad9c1f49335165d69a96a943906c23523667a04f0109ce0c789ec845dafde885f7516552e23e72a2b6fcc4e95bb6a6ad280dbe3e2aa66c73d38446ee8067116e83fd6594d1a22578fc48ff0245cdfe56a32442848d396931de33eaf76d37d7ee83949649c31a03b67418cc27594b4874176fc98a42b318da3f4a5f78d0fb0f3fcf222ab82a57be8d009382454d5675db7ddf847ff53aa676687fe87a5050f7357714e7de1a421ada3f3cb41b8696ede47a05900f9a45ae6481917468379f13036fd6a6f8263635f9f3d03e28a3a862d692000a902a00eda24293fa591c8f056ede05403b55ff5b883df820d767265fa018458fc46985cc71c13325bbebe09e4fb87ec72b57f20726051863232ebe258777e94801e5bb12cdf52235c1f8d05aff434eaf66966b8b1e1bcf44effdc6a6eaf7ddf2280aa273bcfc4116b1063346266a0cda63b2f4f0aa295b7e1eff15502142e9b00e97ec3162643421f19b1e5d972a0ee644f33841b1943b51e91af7dcd7d4f12868a3a6167c681eb537fb59861a41b51c77c3351add448e1a10cbba547fb5823fbb34ae668cee0d90eb6cae27595842b7c8db0042b5adda61e44be24db3fc66a1e7e664b411278e8d23e86b012732eec70a1912018865b23d946709d3a01fccd9bfed84d6c87279c2863c57f6b54147239ab7a7716432aa42e64a98780bc8f2aa86094ec14cb6240dad757d6875d32a1aba33918b0a564264819f7ffc33b2efe33afa927bb00a5e9b7233f49c31bab6555a758f8f5fa2f268c6c763f07cb9802dd959b7b41f93b334f3640a069cbfe9950f99f78d23f7988f60dd3010e66776a3aacc2183cd565646afde041601a088d11f37b0c99b70372f094f28a2ab727c248e4ede0336df78e96e09a785f38a381f460e4ca148c7a399872993f049f29deebbf7dbeefbd76549a5c76c5b8f07b52dcd2543917e3e40141854398053fb80b79ce5a88269030af0127633ae2b215c7567acd1411021d53d7096137647d5d222bbe14cfaeb8b317db2a321b1c7170bf26cf3979c6aab3961a2aa6b8f32187aaba70e0cb00a596a3ab04399a75227d8db4d0e98df5b65c235b42d9c59c2bd4c292b9280a0c35d121a5998eaaa728861824530e257ec0a2255a1dbd36232a1eb0f252986383c6c66091ed8b1bfbc24511dc0c5b24418110c9add884a6653b00605b1240b104a9a144c9a6d6de0231420d4e7c80391a087fdee62991d5c2dde90822fac48d3213fbc91d79beb9534f56901a2ab8937d4258d17686292b221329f0101101880f5df7f281b7432b5fcdfa1004136414d0aa5e377e242ba62c437975f329ee89a101914201e34795839fa0fc794f8ade9680129118327ca6f39b259dd2a97f0b388046b078a352f907df9b00733224bf835595d17dbe5352f067801e3b53d675d225aa584bb2d19a04bd4ce6ba46c4ec35aac9b802a7ec1638e6b8ab1693e7761d56623c1e7e166fd3c2c2eb3c96ae845667bcaa980115d861f9b92ddc60637094cb4b7329de0717cafa148f3fd2402efc5cb7701d68ea0b886b5dcc746d6e9e45d0e6d4afae488fa4f16d14a17a14fdaa5e72a9c6974d360a16b21bfea5916a7dacf5ac40d9fa6caccfe45be17d2da228be59bdb271a58847a90ce8a070b040197c761c42b2e2efd52299313d2292719a8031131d2ab38f761ca64e73b58751cd455b522dbe6d99629923b49598d52504c5b4b818657121c5ae1f92b2bc30e05c5d74c5b400ffe0199282211bc2d107fea0a07c3c24159a1600252dd7cf07d01e17a0a7cf923880956a0b0230e9acc0206739fd096b2c7a0a27319d0da70af79af1e4009dc8ff85cd62e741b7aae536687d0eef95b5f2a56d84394d4d0eee49ed4840bfdbd787d700daf5ae51a26945dba8943f2ac9cb22569c713a9b97db4d269f9cd606d11ace0842c3af43684e6693e6f404a7a79dd7764196bd790981108932dc91d88e6d8703818c94c37a196e4317390ab3bfdcdf7a7facd5720841e2940f54840700b4880ce1e06a28ce71ebc610318400d0c7e506584a8374ecce3872e06ed098c0495d73d1ee14192f29082186f4db0dc2cafd21057cc4c3bd7ba90731534ec3a2d1db716de27232f7937316bace0efeefe0d003d9b0ac0a9315d4d10b4051e0cb22e9979a096ffe5a4d4bb45787889624796d6d1987994ad51d9fdcc21f0270c522b5aa400e3a71d8ef180a741d8cf0f02918cd0ec086ade0b8695e6702655114fc36d439c40be711a097a1a88010222d8225fef19ac0fe98760a36e91abd12ffba794358998a26884695a5051ca70bbeb7a89fe4f21aa84b3b822dd4bec23c5297911a87503838e41173770a610e304a5e84029a70cc9077e9c2514465519d1ba945da63f430b33b792be053626e786c4972c7cf3a119509c239e34a0ca4cbb789f47e0ea32d720281137830a4d9f7bdcab4825352d226f17cde64a444a3d98ae1388d3480977425f168d3a2405cb2bc570a6780cbeea81d96a534fff0111ed0b16519223be701ce101f3f68abe18d63222d44347a05d6a000b210a28e6ef021571d6361d07d200dd32a805b2ae17396ea63b1917c2ca1a1ce25378b0170864601ec72db1d7838855e8f09502bf70109e6006baf30206afb50603d78c06de8d84113840520126449cb44e6a105173aca3d6905f48dd096f8e0ca0785e851a440fe4e7d51acca9f4ec0ec886e6aee1d497a5d4d62e8bf8438063779bbb6b9a08ac480c5e43b42f731fe7d70140ba6d60f657b70b886b40fb33801890f9adad6d5bc3a96e601f3f88c1de75849c768803f3d21ac4ad9222dcca789e129d060810d6400717e9ca28090e78ab70ff4967a52351e9b086e7f57580b25f9777c2743f38e8d6d9e1c2d09957ebd366f53611be840115cd275f6484ff5bec756634abfa7c91a1f193ab01c4f7e4646f5dc27abc4c8a3fc2be33a36a70b9616d06b7ca643d482563351d9087833b05b75fc2b422c06af8f70d83b16e5f0c856260b7e84fa7c3c440e52fc56c0f0b445f7e10e2f64896957948e10b576635eb26be7f5402e90630bbf0f3da16c0b1b803b7b2537132870e6b6ea6824a68bc41c26c2902b244dced12442aa88a0853fb77ed8ab264069876c2f6d7bb7b582f0c317e46619d932f2f3f29c16a3ca836068e231eca6ea2a0f97a7fc9cc1cd282d1cd5cbf8133167b3c17157d5916e54acb283db163372abb793af739fcb41ef6332a78cd7a581d7d43c4f4a8ee52c63b35b4dafd70b74a36341a4b45476e73833b7eab2f52aac76b60d1dc9a271ffe91af168848be507cb95b619785ad7e2390e49460638b12856df8b6b937b917b5e4f77b65acabfe9f9df164a0dba797e0a892d8709904c238ad68bdc00e1d22295c89582a34559aaa5ab3cb104d0324f4beed1ae73aa52b17fb481ef64166c43ba8b394b04820fb3e0bbad0d512dcba80f30f7df6079a46c7d524b7bcc51d15e30d79e060b76a63bef210778959b0065cfcfb32d778917551212f86e323a78fb506b143057c8d8a1b4f3837d62afd72eda951c19cf84db44a7fdc4cb24c6c3ed73dde74856e9934e2aa40560d8f6023fc74e6dcb3a64cd4c0798feefae6dbfad3e1fb40373c469ea69092b48c9bbc19e8c89d18fba2f843277724d0705dec24547e8967dca003a99a3b76dea4883a16008da360438abf812fc2f65bf4fecbc0949f0c3fb66e3d85ec0a96c585d2527ebdad9c688cf0cade429558ff3cbe298eca551c6e42a42887484e9b03c25f124741a653fc94a381417f00d31a84df776a73b7eac0e4b48ff633952f8a581f9e820cf98074ddcde1b23cd94c615ced86ec0cbc22d6e94eb88234e8a1bff8f50e04cc2d9ec2a6aa9cef0a3247a640a37290162841afdcfd5ae0c8fac3a56c6b8093f9e979a3cbe6b5bd8ef362bcfab7f319079b5b51e212b21d876f986fdbebc48595117bc1d57755d198633ca6bc0428c1a017bb7fd30c7685e41ab75ab347fba5ae5ccabd5ac0fbe64e2ac603c131940fcf854c84a2670b49315a0ae69f6230add0bed0002229ada9a96fc4462f8fdafa40bce217f84a68b56c1a272d995f5dc54b47c2069ca53428f7391d9389d44a0ee9e74b48d5d9a36ef1625dbb3957633a47bff3187a1e5f3e286a23ef46653a1813a55c38d87f7eb572130ee9161078306b030755c2357381597afd2fe00544050eb472480aa1cdf0cd4647fd8b1d4c6b316203c0e3e92adbd4ff93c164634621fe5f4fac30d5842923ea46fb5d3aff1b94f6e0d14af028c41d8373ee5152c0f22d83b8d41473fbc6654d24257c51657d1fe3104513f4db6f03ca19c544869e6aac9bfe4e8760fd0cd8df2cf8078cb6369807a3c51a13c53f6efcd8450b15b32f9237afe06a206fdef831999f03334200db0d11d018344cca90ae0e4ac8a420c1dfdcfadef82b8ef545f8050094b38312180fa1f25ea245a280f70fd2fe60d462dae277fe9fdde983425fc9f5bb32a7e4ec235b2d19481d90f7a0a2c551cb1c8293be5fe6c389070117686ac7f68155f31aac6921b3494ca3b45fa7c7ab40e95979613d76b44f64ce639331535732332e1d22dac3de818578f1b078d96a91653944a57bc900704200f7e1300c70919edd5655cbb3619fc27515ff20330ee67395137033ce7af7b52ca21a0bb9cf032c582100b39425b71039b93c0a8dddd36e36b273baa545d2e21b9bd535133ca0429f14b4c3a62567099b5646495aa8ae5aa6841b1bbf95c06ae7e5d5ec3305ee11a4ba69e5c6a343090db7dc3c426270c1861f3f507932c0316f1e38e9970dcdf6856546798f5e4637d0d6e38a2ed5e64049a252c633b40093f413abfe72e0b6280f9ba4f6d5dd4e21c503fe6192b4325d8ea056f3431db56235ee0a48c1d9f0ada9d62cf98fc50f12220504f734edb3f160113a99cb0ad3e800337594f0a4c848a7800ef29ebf5ef86a9bd66e82f8295665378f8116496f463d36ed06b596c9c1330e4fe34cccb268b1d8965fd590bd039869cb1bfc27cf86d0bc90064117fa5450466048f7432f6cfe6d9d001d87cec9c0e803625c5ba4a7f1152e201add6a289b1f29e8940089ddbeb5e07aca8ff3d20005a16151f2d59628c37af47feb9786dfe1a93b1dea148cf3270e017519840c10d7e4aeccf05dc0a008026d378288ff677b73fea75e7c9aa144576d8409ed0be3e6dcf4833d991fd85f1eccb790c90162e734675b718e7e45d36c227e976d3ad11c6a408622c48402da6ab00306c82ea07af7871e249c86117ff6b84fb8b7f75c8566d32ce3abd3b93bcd8dba22c6a6a0b5b02fc5cdfe63549d59733c70bac2d7759dc05e636b71394a6ba25fbd3885b2046af2548068da23e6f8ffa7599e9314179360804be57a7b5469903873a4657f868497dccfcded8184cf52bc8292d61dd71e0252c6685cce740a804cfe088080440dd49502c82ad6525818e5f7489f1325a94995ebe6c5655e26e0ca8588d0797af91df48bf684a4ad3ee12f914894d8c89a5941ab22acb7c8266291c6ecad21bb040a236524166cb4899aaec6940d58b76dc273b43ad194e5632e027412b55544de5771e9da92a3779fc04e1db002401edf18e4318a9a1df6a1463ec3be0ec1bd8f769d9d15bec8e8922bd515486348132808992f266b0ef5b6d5a41195bfb022ac2c1a2b9b5ddb66857f3c21e10e42f8dda3ee6d6acc339a07108476f6a03d614895490d7a5023e5f3e42054c42dbc04ac89813a2e1eedae3fc3503cc3a585fa143e1e2550df911511dd8d9a7553ce20ed29fc933e6982c74d37ac9c74dceed581e0f6abb4a8a9e73aea05d9e64b167c08dc5d54ada03b8434be6fa6e8c088c3d4ad32f480b8a92985c83bf3fe29c5d77d742d5a191879bcee3450caa1081b27c4fbe8a20e547dda3c21eab86e62197007cefb6b9b663163f1980b39a1db528033bb6a8b965de40a07350f19ead6fabcab835af0ddec526e2489a56a865195b588c81654736a474ea161cbd08ed8b35b09160ba9961cecf324f089d2e951d2e3fbb424617f253cb817723d873850025a2aa2f3f8905ad9206f823e24ac67eb4dd80cee485b62b762b840edb39b61f76dc47423e6ed66a9e4343b9aee71d91328387caa67774385b5a84b6df24110fef6226f4ea8b55f9263d15c82b5c0375b54d93c855691f6b7c1c96a3a6c9ccc05c03dd2a4678f55f4858b8d7d7813851797615fb867037424ded6e0e476581e5034a93544203fa8e1b80c3eab70918577e07492cf25c44f186cc69dcd377964c642274fb04aa1b39f1719a2d1413950c5f22d16a1857303548d2735c5d7b7ab85e4395a75c16738eda1762e83c17490d042383d947b3a94edaad8b44de2f9d19e14404f3845da04bc6b68cb7c8f13f8e15ecd2c13e65e9bda7249a5eba3c82087cc1e337223f1908524e6904e4a3e7ac26b40affa82f53c175291c4965094fb55bfece09c2fbddae564d67efed130e3f4cba17cb4a79516d733509bc9c5a22d6f76ffa201d9fcb0e8ca9b3d98c9165964e2ea40ede476f9c48a9df1f85165ac37b2fc42e44349dab86cc0542bc6cc52d0bfe44d13cee117fd73cf0af31da2df43b0a78b158f2e656484433c7ec5ca22a2a9b2f09b71f1484f61805614d25703a95b012d3995a62a3d26410b2871c70bac4e3e30738a7e5d8b4bf96617bd212e50bc0a6efc72ec1c7710e805a5087f08eb94e858b94256a93b02f8efbcb0bef52fbe6369c2c1f30866395968760020d350c1c1c8cc3296fa83cad257421cfc96444207078e8743481edd81ac698dd831b29364e64a6c51907fd574894d1e35608a26e44b2823adaca41a4f6e5bc2d774cfb7347a0e9d4b05a0592e67d6059f852e47e71a31da9ed0992658d7ada3f0233ce9c168ddead92315d39914d6f40c04c5ac30b44a9064c54a6882f5240e6e25940ebe0441307b2966217cfecb3ef1cb6311d5709730205f18a500b6e9a66ada7937185ca0d97eec95cbadfb730751cd769885978cc3c6175541ac43833fd0ceb6c824bb45504e9456389fc04840bdcdb629271f755195f61bd453dfb4c87a44232d327ca419d9389899e009c8259ccb0604edb9bcf7cee585713459a8769aa2c430b06d47e304989f33d7fd1bc8c5a87cb6bc270827632ab9fa9cf1d07fed680f995c557cf8009f6fe8b91f3df23276a94ed9f4d8ec8017ee5eb211b27b7581539c6ad8e3cd63dcc3b9dfbf165a0ba1abadec43756ab634642caa507f1863acc020fe308e9ed9e46685d6b698fb75741f863176ead2db17668cb2d633298d152daf90b0c658c299ba613950316b8c241375c0d5916b8e7717fdad0da3f2b79d691f7ebae549a5d6e7c2d9ee657e40ad2a7282ef302f3d3a062c6b641bf120eaed687463e1f3f220b32e091931d1c048f5349d006f59acd824e1aa99e831193749a184f5901d3b592381778c025d078bfb23b1cdff29d11bff12311d7ee8515648675e4c524d9add31cad37df8094ed3adaa148d778c19fbe15058e50c55905f446f1e319500c1eed52619b181778c464e490a06b3bbf4c659157d25470e9b4639bf63743c1f7204db502d3251ce71c768cf6bca5e6a0498ab2553cdb82ac03e463fd6a4a690f249619223393de77d8cd960a1488a35d0c18c0ccdc262587158317143de39c1cb4580108017a545ce4b1e22f4b21cc2204a16d3eb1cc8b975b2765d9094fc918d7d63fdaeb11d3b94a8eb919b103688ad3ea747892265fd2501245853f416bfb9dc9d2e216f85e059ca1760a481b1901eeec92dbc3a25ca2cd692c222be76fdaf95160010212ebe780393655c6dde4ac8c1f02c8f5c8a9cc0915f4addcfdac29ddae9f616024c00185f0f328dd80b1b7b5af925fe9e97a3061d99a5b1711266f877760428f0b3b384e06e85b17c38089600c9dc57af6560ace050adeb790d535e24fd69053049c319b74891da23c3a03482068ca88eaf93eccae07a9313179a79e26a5a61234d6075be81894565fe8aebd26163924276f6a1b15bd1955b3c8a75e244ce0598d983ef1a15934eea227cf452ac5b1734285057019ddd2514347fa40a3c5fb6d0999b5fb568064bb8a332a2431a1d12e9f71f04e3794bceb6f3e5a6cc7d43c6ff5b8588809ba735d6f75bbb2cb4f81117fb24d0124b27c0ef94da58229a6cb54b4a19ce29d010157130021e5eacadd433ea3db158ac8d836103d05c2eb88694b8780cb90e32a0e925f1252163feda859f17327e645d00d0dd69e20195ba504221d1edd40336b2c8459538cb09b7edb20ef8ed3e07b09ce9e457f12c9435332654cd4432de5ec0fc11f6890c8477aed992ec0f5424a7204d9644e755827846e9fd7794036fbd50dafe311abe6ad0bf09700143ec9a5cab8d01091c9d146dcb1fb562272745954199933183ee51685b1b6d4841b340a6aedb8b2ee7d4921bd3360a2a3ba246eef6ff030eb7f193e5836c592c4c3b9184a667247402086ef80823c267e3423082cc41dabf682aab45d3d0dd4473739e72c21ae66bae9555b4688de7dc2110525106f6cd96d804eed3fbe1db7dd95e46f926ace5b3c4fd6112dfaa4dace5bd95b5ecfbab5928fd0085ba2222aa9cac6cb9a39da897961b378a8738f31e3c531d672c20e948bfef408b996513ec9e3be1e3cfcc20906d63aeaf9b665f2d526b8b2df462f33287d282a480d273c33ac75a37518500ce4828d740aab4fcceb95addc24adb6d03d4bed0a01e9ee55c1b08a68e8a3788103ce6433fca1da3e55b6be9bdefbee8613260a8b6f587fa61f6ef56737845edfa88270ad46667be172f6d0d08376d8e4fc571f3564e3c6c34bc4121f7be2c463c8ed76741c67a74b268cfd5604e99296b54aad274284a396a752587d4b130448eb65598c2e3e3a419a5ebb49d338ee995d3081764e5a834db9e79087ec3bac75057192af66fc7828d018c09b7618782fc0df3ef28cecef5cb3138b0318e26c9199bc9b9cf32b4638ba7f9d95b0557d601b934c604b839f0dda7266b5b872a1ad42dadea3d4a36cd1a59691e468773748f6bd86c290944032c48c973d78f52ece03152f61c558d39f6241b788823517b62332134647a600eba91c41d81b41ea2a48298f25a9d47024480c6ae2f0b8f836d1f84a6045e2279cbc1ee94f95200866feb974d4bd17284b4e25002114ef8272c1113eea8adff36df12ecc3ef7ba3aba770718c75a6ce3f9667753e910fc6d6252dbe22f24e374d8ac4587157743c31a054e3239e33baf812552f417b1c0ffebb9b3ee746063f837b1dfa006e10db3dcb82c6975d6e534c1bfc29468846c921a16acba0e8c6e279b868a756e9797d3c42f0c08085b15e93d6621141efd7e62417c11e7d466444e811b8003e1a16c7bc936512b4413aaf668484bf36a4751b6b291dab6fabf0f7a8f3d474ebd384aaecd0241b3098b60ff421eea6a092fc792817c28b0d7df805375a9828a4acf0820ec4e1b93d713a688cd93b8dd95d0aef5807e6d9f68c804f55660740f9da4180bbdc8cf31f48fedf118ac0a7972253aa1df27963d4004eabcf8f792f819114114038645247db4567a2ea9a7c326447d040dd3be85d0753d3e56d5c77900c27cd2926a540c17be5931580ddfa732a591d3a346b65456d20922c59835ee223771f7f5c541e95e57f3500320add656495a8cc165ac31467d89a9f68331f02606e0869c62b0a469adc89936d286c2c54186851a5773bbe5642201a66fd4be1a1cc12a59efa5bb7cdd3d01ab4ebfdb70763c02f55fbd6e7ca7562b69ff6462757857fb52d5b1e29e7d290b6e01bfc5fdf824318a3686c5f786d828f559a91d45a0f1f45459427c3a4b775165727ea0471859be36509810f57263395a7521a2bc4b3ef53634952b300ddd10ec73f90a1b6d22cca16f76bcff1c8aaae8ee7c8950de63714cc2ee2fc567e485a5838f17016b1ca9d3c21df2604fbc437f78f79b05d73e1a8d0b71ef7597d33ef9053e28c5abfa8b54e3725c6fd0412eecdb6d614f44119d4b3d6e3c642ef53b7e4921b2cae0af9221a05cabfa626988f8cb0961ecd8808015d9193154e0c94890546b41ba5586dcb39d99477e316e825603482ae2c724dec7a16777a1c86e001b4d5384968d805873e7f39489e83288f9d2387e7df2162e10c5bdc168c05760ac8670c287e52984b882dcf626c0cf99c9b867cf884fc231577a30961c4354a8054f6df62d340838266d1aa6d1bb9912547672a37b1913be618ee6bb52ae2e8c018747039af9705d7c3ca1dde15953fd247f99d1c094052034f7da593bd4895d41e8e8dde2daf3a6d5befa51e66745b33de79334973a180414d5b2ee3548f87d5fbc24756d87f88049aee7f2ca84c2fd37fb74315ca2521a2137a671bb99182b666d94a348f2fc03a98a2217a11239b608aec5025e103a369b540f418f5b205f1b288b1a97c9c081a6d16bdde66a531a6190335669d9a286cbdd69a4b69d4cfd535e2b436071b15355f37afb912a02752d5748421c4f5243c99b4d7fe48e47e27333ed4480127c1a2bd5826462d35a1ce84384677a89e639d691c74c621065071c5225f02a975341fb6c86735b0bcc935f0408cd786c590dd096421fee11107b0a98ded6d6655f37d54012b30cd0d51f4043854e71f571b9a6b7f8752352aaa7da22089a4a63857263abd0dd9dc1a104663c3b1742808c5d0d7de69387087150f3590c92585112545de4b826efa30360a5d9cab3685c33b04166fc7ba08375443459b6bd7aee458893ada98265e1ab0938767275670949e1c8193fe4f1c2008395b88e2e5fd67a7084e4c93395ec27f6b0ba7c9895676f192dc19b4473f4d4887d3e8b649e49b4ef1e0b8c44937c9c8a93e62a551407ca59acb523441fc409f883e160391be2832f97b019b5796cf5ff8b4d2234827d0546f5f27407c56e7682dfd456bf0c86f535cda83a0541e272cc81d2eebd7aee0db997cfc4f010d5abfb2691bf9000962e481a5d9ccbaa50a38ac33b32a25ab35d1b030c2290b67e158ae5b6b4eb4e651d7f7079e2f3fe4f3b9aa7b108eeadd28c417d26629577a85c20c18c6028e4c2e438a296f78cdfdf64607e819a073e0b03108b097ee703d5aaaf9d27e7866eaf0fba9b25ead6285d3df3f4dbc727eccc155f70142b5d1f478009a4e3900d7f32004a6cbab7866abfea2e1376a1b1dc407bd9407f9d720b12930fa396d7d2165311f6fc43bd0c944a79021fa350938619d7b5cfed66b847eabbc442ad7291659e1287e72a01aa38eb0f5f1cbc929961b20d333e5f6b13b6aad24d62cdee692dc36fe6bef156ff06e520dbf15f4b17000adce0062163a8fc7bb8398df26672d727d466228f013d8451ec48cd5338adec5cbf1de73bcc22e5eb6d7b4858f02c5403fa7a86eefca49d2789138f6c22a83d9d7f2428711d4c29ffa828ed2562535f3455bce39e730579f0d9832979502424623f6374ac4fd817757e3d230705b4b44c9d2502cef02a31568f604036eaa9cd8ece0e04305b6177959dc3c137ef6c72f2c3cbd890ca16ee3e0aadab81fc63c5b290b0a71b00318d9e27cac222b0a970cf5610f1e42e53748cc49d14b9d3c85184a3661029c9a88bde287525025bd481068e2fc70e81653dc7d7404b2949ba800714296f9c88cb5aa09d67b18d6c9dda22d78db8463f3871bb17b12346b48df2bc014c83afb265f33528afc47edf2307289d49f44e0c397261b0128038d7c2e614a3f2ed069951916edc1b27ca25d81fff3fff0ca25be283ed47c93bf8876151b25a454006d9433faa19bc66391204c9a1190a04039eac014e0207fcd2643d2e8878ca8a047bb393908d15de2209d18d25219afd6962263632472d201269141f348d4b463d43b99b412746f44ddbc693a52bc9a9e0001bfe4332ae7e524c6b696cbde08f1dea5649821148e1f57bbad4189507edd3b6af56d2842cb6aac6a1747b2b0a45a3793ce4c9857f7320d860b7ec758726567b9875000a01358331d014cd5ecee4150aa433c1702542b4014f756be41e0c72d1e0d404dcbb235bf4cf4620364949dfa3dfe199e1e3c9d72c3b72c4d57f30f9a55061f083b361b482ac36fff7cedf28d16b5db1e55b92a2c0aebe7ad4b909e870ebc8c94e194c9564251e7af836b9df2d0c88916548ad2545d068de324a704d68646b296bd6993c90cabbc0c5411bc31efcd4d52f154ac071c26b3b66e394d86c582b002cbe6b48c1aca7786a99656551fe9974816399eb29b7b643154f764aeeec679938baf810d7adf10a863996ef0e63e56a7cb378aa156e2331473dc53dfe5bf19d6d58232adcfcd5f6782a086f0e3d990500440894d361ad33d9e93fff76a4023ddc03e6e0e2df89d4d85443cefb18677c635b667069de9fd215d885321aa047a024220c351bedc48165dcb3718f721dd7001a3baab5b888cb3d6dcc1ed7fc8dd5179948ca374fd6b8c34153132ce076c6eea16f0b7dbdd070d19c3385bb4702e24b1f78d0256fb442060d95e771e5928491dbd67fa4f22818ba380b0ac40f26d734d9f8e7b0995e8ced4482c17ac460363e54ff0c871874e1cad16f1b00907752150e5203a0b40249bd46ad6aeba5eff4499bac6da16a35d26fcf55d0b96c387f671f185cace97c67d8eb89c2f2b36213714d2fa77cdba89bd97723d055cf4bdd78d0146c95da2ffef4aa42bfd11f70187b0566e517837bfe2d4c5f5251c34ba363721af40fa932909413ba4d58d533f894fbd38ee26144efb2e90dec6703a12e3a902bd87f80869ea85497b1aff8cff7c220e721059560a287044128483c03482d41f1dfac10c4b0e0990843fd815bbf4149d8fb068078387340b42424946a9108c3b7f7a4e4a57905de425d99a34328dbe8b3ecbb865ac444612bf4dff64d73e364540c069eec3b4854571cc1611a27d0dd9ac792ace9bcfc3fbafe003358b4bcd3fae214903db55f15edc857be051ed38bc3650af5f7113d010897b11f7f083db2af9d525a137517285b5d3ac2b1861e3f3a6d8ac1491c9243832de425e888787efd0ddafe413a137545a6f8b8542b41e25c76a0057adb837218c1e738be904094c4822e75eb608623ab25d9115adda15e7a4098e93645d04816a52f3700433b8b23e8e942c96c2ec8f2702635634ba28eced0468dc9fa857c48cf8338c5f53acab12ada6a0355482a84d1c7881111a5f3a0ea2b582f9904ed10360982b0d069d6476d983cee142f5793faa9ad9e20932b811cb2428704e93eafb428e4a21c19e58fe7fb0ae45e32960a9601ab0dc03115c7cc7e884727adcdecb5a2aad056f9ac3de957795af981f2584da8629de50ffef9bdb0d956410e3acdff83086b3fabb2285d6a4edd2265e226b623f6888a6ab279ceb5a36aff54ed1c4c053ccb12ca566daf335f44e6a9d810d3c8aaec09db551329b3bd94a281de872d8cd20f84c0a8438b2aaa5bcc27079fd1ec1c9bb9c03187a61e1fe700bc3de873e928835efa3bb30919a88f53cdc3f2da597f2a5b5a57a9602c98b55d291c10058fbdc71210dc9420f30e7001c35d7cb14dc706765c6e4160ef4c116942587629c5f02abf25448b11b511a1800641b285382888eb58c80d84bf42cfa7393ee694841aaa55cd6f957554cbc04fee6dce5d4105aa3db41fb3e0464296a25045ef43cad0c3956d34ed9c048f0e6811887714a041fec5668e04ca1b46200b32724f85fe25691d695dda9a2ad8692d8f7462a383b8d08040b29eecaf1fe62052728650ee535777f3da798580aaf84f867f7d2eb55bbf400acdbcbb0dfbe91e1c712610176c85ff300dabe09fb0923a77f463474530bc2fe0322f69f730aa4845b2b11d32593350dd8fcef7faacaa4ff57291c1853b88323abd72c59b1ca8e41b02cc9f15253e2778847dc18de2fae262ae15857b7480a24b039ed11971abb1c02fc9a69cac12755d92356f8a99fdde5666909ce890f3320a8cee27409d82c0ee8a6abd0a9c46a4f4b102fa3e9fc33113b733dab974b264bf5f34139967d3a52acd73bf817bc5f676ca683c9158c60ae3069dec3854d2eca1362949d5d652ea1c9d2e2af7155125564846134e897d890aacdfc3a010cb205c4661b5e0b320406d07d8f110823aa8b42260bd9649901733a032f5aaf5a3bc607ef994fd776fc07a945ecafb22682d63c6d6431540a0fe171487ca54922a0439d6cec801044300ca41e337b38ad724736cc2e1f4a6db05b52a8a3eba018b97734bb6a86d88bbdbd3da580e2877f894c7841f6acb48b50694e5181babef48040bc3b0ceb1d4e55fd7fb7477b8c52a1ec7a9a3e4366f61af069b198ebdc32606e1262b98d8a434d9cc6b5397f7149fc48047d6cd9ca09931b08caa7eec16a2ee79f6cf8569c3a9c46971d456c8676966242de393d51d15224257d34b5860bea186dde3201a1261690ed543bbcbc4dcf5a73f35e3ad3341c693c493e94c09a9ca0a57032e3f1dd87ec6207a3a66b0dc983498b182955b827509d08df5c590d450dcc1a99b3eca0b06d87db11f3dc51a28d2de00fefbb656a0954884172cbbaa210e20ccd40a9169abf48e2847ef6cb0a6f34ee77b65492f3663c8507189389f000c4abd1417caf97ced699c78647ac509f591d038d91d43439c9efe2dea55061ab1fd4584ccc86da8aa0e113f377029258636b02ffbf2491dc5a833f621304b6518d28cdd9f66301726f643c22a34af5f3c76d5d6d81ac7ba2f4dc3a97c6b4e332213f90404049467c22fe6ebbc9312ba1ddf0b6ba2fbe2fc138b00c17c1a05e3a1fe85a2fb689095467a8174fe2f211604a9de996cb1fbe094f8d78f5b96c9c9bc1b5f3e4ed9cc6fa3af7b184b08e4f430975d4fec1c7c0988b400428d6503bac0f2ed0383c51cd14997f2e12812d299f82b6d49079f38c347fa6694e8bd17da654844ca867ca5dd7e598d40eb1bfeb9d78306205dde035f8f31b94c6b8bb58133750b7aa36bbd951c23b903d900536b400946c043c6e5c860ccd1ea9c646a0151ced5ff02b9ac62e0a12c0f07bbcf50feb987cb1ee6916f475c23e440df432d2bc92ef5e20608d06c26ec7b0455ddd3653e52a060d6aecf47b84e21698f5c49d8188787d7fc6437db1e4f046cbfe5b8d6d6b219dff9602b0fdf8d850f583d1f95c55e6fcb799c8552228272e2be82af93944eab3abfa33d5f1ca67c67213bc4f0b43f7816a891c761f40f1bc855b8c52438442d9b5faf648e85afe9fff193788ff08a19853ac91d0b9dedad53ffcfcba052637e45fcaa642a8355b9f97cc980ba2d22545e3e37b5d3dc6068daf24dc903c92bb45e10c1a55f16196525cbf9412796ea0f9b2863ff5ec896c41cf1a72065f52d18c53f685039409a32e40eab67228aadc2c81948b4bb18eea7173b5ae3a6dd795f5cb255cf12ba1b644d92696eaaa9db5c25ecc5bdeb5b52b21f9d2769a5dde5f2477d7fccac65d515922e573059887479976a1f65c37ee14f6d2ab094e99a8577229d7defcd8edd5812950a3e45e6da48c09ebccbb544a4cd3972b7d097ba43a51a57609b36a0020cde0d4d034914c2c8fc77782b0a94e9829c8c121cf5641938eed67140dcd07b8801910ef763801268666a3e0dda7923e8b298bfd965351718e5ad9212cd435ad51b358e5ca5e292250ecf52db7fbbe5c0402f1a1d93e7fb5afc84eb6b9a1333d67626e0f095a661208378273d5512d814080937bf830fff7bd71c302148d40108a0004023b15d16163fa1e8b6b8277f526c6771abc805d689f58089106674e957fcc44bcf8bdba3324055825e813501a14d7bfc4663782c471f4be301f453894916fd07d5e659fcbe037bcad705cc7df73d3323cefd8836ba8f2b44345f92cd9c6f6bef0daa916e96a4e9dbbf718af663fc7a08ef051db84ac0f243a38d44153afe53d385831315f419b8990685cbe514e3d6dc75d46aad14e5acad0cacdbbb9fceb4454b501fc766e7d64cb97b0221db735663ff3d9c738c24d8822b970b6c029f3a89a68fd963c158386b30a7394a9a28dceef81e990fb362660ee641e77029c2fcf14ae7c8401a3b595e8851bd80343b06ccc233cffce8a85c8b631576508f2da6da46bf3e154aac0adc89d3f59db590f0710d6897f6850d95e32f48f5525e8990a39f2ae2178ee6263001f8e5448fe32d986048e43de9dec787419cc0b4ff01a6528933f265974ecaf060928882e9c6016c697a2966a5a98a86934299d065f26a0ba285c80148e13ebd748a03bfa70a2d0729e0ce6e58a38cb9b2822d5a289f6132a0f649bd12387d2312e1dd8e8055046a44cbae36ce17f8853b323c04de320c93894e26ada95d85a0af9b21ee2578e645b6ab5f771d2e21baf6b5d61ced3e9ea2e87595d1b91d7745116b92309f2b89c8e546d3dca22c8842f9c06778d64303975ffbf75aaf0e2badb36726b90ec9b5749cc72c8009785091a24e3ed24581aba301f4e69218bb5943966ae7a593306db0ae22d633634f5c7e2fb143d0aee0dbd0f53899b9917ebb41053b8f6af6958e02df0140727ea030ee2cf579b5ec8c655c7eebaeac9cb690bd05b56ac001d27bc0ae6eb241364058f9d9e03826d856184ca94b617f7290c1bb666afaa820346a8d0b8c4b8ed61d8dc454546a74b210a7098d0cd8fee9c5d53f0a4ab68d5d4bcbe719903ce2dd930271cabbf3dd44c8bb209eec0a7f1db53ea9e88c530da337122a49e25ea4a93c00a3e11f53f0f8e8f1854221451c47b644067ea77275a364e2e6c45d0a660f9c82bc86f901c45003f66ae6d349420e2f0b6351c412226752515bfa73d580a623f51d7a95a5dd48a7ed557b9b2c59bde6c3876ed84dda1adc5281b0e3855fc77da176b49544de710d2242212fb16d9fa3bf344e0fcbbb2a1634fd6fdae50a1f069d50b94a1dcf302a577ec167aaa85409380311cf920c005c088d7468f4f80b9e05866878e8409883c52d549ffebc637324711de9924fd804b14780d78ef29d36f91484094142d71e0c00a9a5fa48e9b5a4e05434cb488fd050c7fc94ebec1e242095977bf77eefa06a736eeb0f57f4590078bccd5824cbdd43723885a3ee6244e6c378feb4304b20297c2c660b66ab328f220aa35a8fadd29b810f4a142b658203816710d9a6d077b09d5847bce664550ee8aac58b69d9d66917169b34760bf4ba2dd606e69243dc830a7619dc655554688a49fed97972e53913fdbcd7b722675e08415eb15268ef7526a736bedae9946baa5869a38a9e732e60d73b83f28d66235cf65ffae92ff43dce8714a5a460f31d22577f1090997b442944c8202ce03531bc04b28161e6931a2ed30ca643335c2852d28e954cc69ad148ae9192bdf5c314edaf0e17ef0e2c36320d081a15fb1e51c0b4bb0462d671f306f9d18983207b1e8d5d2776c02dac54ace6d26cdc0e4c6100bdcfa828e15fbf9369d3985a60f86cac212f53d4131f1905c510fe9f481e4b7c1c288d1247fbc4c2643ae00e797fb51d1377ac83939d25eb4479e666f27db3db8085845c200f0f55d9e07b574b80c2bba80168d2f358f3fbdb06f1e3dc347df85163645757b04a8bb9a59ed44132678ef1d8ce4c257c7b33aa62fb212b3facbe395125d045888ace4bb9b12a9249462103164b550e7c08aba2c2022e00338b25d0034beff25d4892eca8e161e75d616341467b8761521b72558765a484d7782e683a72cd5ccbd77c6c6f57355051295946c39683c4ead1393e394576549f00ff0286a03416907a84495fa5fe11cf72603f94d58e8c1a9f5429a051e7f68584f7e392bdb81ee3ff8610e75a620b60fd31c71e68d9c1652ba43df1dd741d91cd1692fe46ced4ac8550cd53b51ff87576883135e70a7d04b2ccd8dc08210390e81ff2e35abd19aff02ce098341c964232e60662b4d6c2d35e2509f302ff95f26dc2121a3e964c1fb638e87be253965d1c2ddbdd2863b0d2c7291b6eb4c340801e9193553a8803beaecf9399a9a51379eb543ab8e715f9654476202c57e1b40423a9137b0660ee3c358c87524a38bddff46d30b760b17eb2f2ab8e3656ff41e8858ab579176cca4aebdb5f1457f404cade70e81986f4d958d57b21a3305f7b6cffab807adc815f735351df6f46494d65869dc9a874ef1e2dde90c21b28487bdeb5ba20b177964804e9ad30b48e08aa8e37aed76d72f57ac29bef11b3701d6425b81887ec976cbdb1e762f4ce9574714004b7d35cb1cff54f885313a7166f2bfb1b2bba145a57aa4563679f0f7de1b958c369ebb44d611e2e8a3e61fc04a90a9af201117c4a7d009bcf9e8a98507aeec478409ba788d69c466c66313f5771e0363812936f57f79625ee8e69010f409e57071c026ef2240184d9fc4b24fd6aae952d8dd725f562216a627d51eca8da1df9422671f1c2331200c093c6287ea1301f2e447532c56b744a677b627d2d92af749654e87f0b4b5ed1a6684e644229d27cbf558ecb3c622f6cb01c433607a333958367a71f3ddeb7c757386b6248b99796cd7b58fe99ae6a7c7d57d91cb76a937ec3c424ed723fd72bcade0abc3768721900d877d7f29a6d8e2d72a273b65ae9e04a9d6a38bb5311722f3518333425e40b234729fc4ab6d2eac52e94e0b5fb65bdd5e4fb38259aa008c36d91d27c0cfbf769c27c9dab54522b3718cde72b36c21485bcb317641097ec7f81714b3b0e55647e8422e6305cd75f54e1b72d2dac1ac54a2bd1337d5bef43d88f92187a61c0b44db59d2600e65f30d13c447281dc12f17d0f7e45e7629006c72bbf455b60ad2a784ac44516245d02e383bc83ab46c8466715e29c6d6d623b94e35704b6c10024912f6c9090703997c4af5690ef5150f55eaf125a2e785fc0770adb495fb6d1445a0c3520068918a8a222664f071c7fdabd6196c3363952b956d5a536bbe4490886f8c5f1607b82dd5b554444c6182b2a2bd95101e979dec092d81822701b5c25e2feb82a87e7d4f3073113b7df15ecc3cafa65cf008c5f845641334000accc87f0d45defe8bc7c6c3cbfeeb7b6ac47e62e5613c96241e5926514d8be42e0aa66feb5ed92412ebaf3d1cfa0630dc4ff41a5c93f98bd7be9774dfaec91102cbf49734c9597b113aa32f1e4daeba9adcf82bfc3aa6c9f9c22da81434cf8ccaffe7eac6a1e0bff06033b67b334d34a14510e7faa5867e6e5a83dde96ba50286135200418fa6dc4115446bcfc748632dadcdabf0ab2ee9a13be5f3846df66fb56ec4096a5117a5a84b06127817f1c6b6a0c6584b5cffdf5d756413ba84d63fee57f522f9c532532486ff7f7fd0bfc1588b13be54f80131cf0bb417ff29e4266d2ebb5b4d823d325b4bb91450479d8412237c4c8ee1f14847612f76cbedf93bb137f0c58649a07963e69c7d49c3f4cc4bad937cc4908ccaa83d459e620199da7f6d40740803d2c8dab92bc4a4b64a99583961cc990e0539bd642b40e76bcc502f85cc3eb3dc4499b5bfe2a3df60b7598c102572c26aced42398c4dbc28456fe8d0fa71582f2f5bed9c3f410a825d28701f4ec729c154184bcef56bf1bb807485cf1bee9948581d4f26bdc0596e9dd1c9814d86649110dfb391d9857aa31999bf8d0677689b92266bf7957fca64dbc7a5eb79b553456e81a2c6026194cb715e628a371c91f008d16517a477528c9137ce5a3dcb81bf1c2e305edbff114e065d5443c94109ebf241bcfb2f82926d9e0d23165392a87729117571c5b88749c43e1da68592ee5ccdba3b6d4d21b336eebd9042869e54151d309875b52212fe733363fd7112ffe04a7aa44db7b76c0308b6317271829147f4a4abd936e8bb1bc388e1fbe70eaf8eb09c0a0e8df26307627a73686cd98f8d188581665fb5a4190072e47ad8173d64bec544abb368105778b54c747ddcc048af37e761ace10bcb4563981f3fbf58fb0d11794e95f4d1eba784170520e98b5e5147574095155aa2163441d36dca26bba521266411764a8d3023f47021edc6c088c675a894bd6b24125db1aef4f9e90c64a225a301fab66937a7464ddcd8f0bf5b6d6a6089d39658efffd26af60e7dea3dcfed96a113ec58d8dc7c8c0f898e36ddcf5bd975500fcca4c788dce32f236ac01c66bad879128674902138c3e2820f5ccf102a3a1004d489dd45fac7c27b02317d372f16b1a4269efb15db2702426fb19873ead6796fe938c2ee3ca613d23fab352efd886c0c06d9acfaeb860f5f3aa6d61cbae37ce97bcfb48eecceea222fa21549e81f06be2fc247a5177078a94b4d6ad4c187741c8aa4e7f014ea08a06db8e0578d3dc38e52162445ffb946205b98f02ceb330ab9734706362d6874a975b537750067a78b33db09445c44fe91c6d1831415f4dd0030d422ea28751f8f9423f6a0f24e8059b8acdc2488cd226d0c3f50457f121b5abd6ec3b2c5903100cf7dcb95f37d7b277452142bc96d357f7e7cb79faa451d1d01b8f354246d66cc120d4d5ccf580378bb49d193b5241ce9ad6031a5ce91232ae98fc614c54483c98c373de2eea162e7b2936321ac299393da76f899edf835b7c61ef44d120a5008911cc91c2129a0859a89151867242d1828d4762d4648b400a5bd3858928325bbfac4635325a631865510c4edebc1e01b9a2d3811404c674988e6500f56b1e0feeefc3849c72394a55dc634ef765bdbedf14320cfdb315c0b18578e86fff46ee3c04efd9329ef01815600b60fe7c034d55079da823f1c18067eff0613c636ad67c98085413a6300c3c46be1a4e445c7c427636a50ebac39ddf985c02c7ab5c8be719fdccd3c8b809ec7809d4c838ea7308228f466e47cb6fd6d03a17d0df6874b7ad4553148c74de328adce6f8f98237fd53bd95f3343994fbcb245013ab8ca0ce9bb07edfe6d4f646487b8ab7202c06f8be2b208d62d7da89ba73798656906414db2b9c1b30e7a2040681614e91745eaa30519e84cfbb0c51bb4464b9e18ae42f237f8cae112139a008bcc6f2d405f190802ad6b95efa4261b41d3d2e3e06a1f0e2d621b4a9e664261ab865d46d587f5a2848c58c66bb2a5b6d2c86fc42932ce226da959b975da08cf25bff06e21fbfff3b19d94bf7c31c80783272cd4b4ad662b8c4682b97539ddb174eb96f55262ef9017d92897a6d30307513cd08527f56af33ea7815edd09d5b14c291ff6643fe8a6011240433428359bcf8d854d94a35aa82085934f2c0bf8cd90e3469c4b9de2434caf8f77dd8c4056178c41320e638497611ff1bac2b5cc746f2bd7d360ec4fda84ffb44f19b5110a9998bcbf26b12dbd9063a8402b5e50476f98702fe341c721a631851e831d7fbfd94a611810a3149f9b2638c6dc35c09b3668d8194f667cdbdc18da65f621214375a8db51b454d0455dcf8864d397339a31b3709f7d077dc9f57fd16675d1351ca23a02d6ab09455ed501ca812920b8eb83df2edeb2d1fbf34759dac7266a9d06179cc711037b949cd68bd24ca6ac1462e2bcb200d07e916a3ed9c0a02c5df3944382afde3e9d7bb164aa9a527d1ab8b9b1ac9ea51c5b5fbf3b061651bed06ba2651b4fb4ba0542a6157dd6b3941573f4de31dd7ef8e10e4a2adf496e607da7975c5d7bd4fdd7e9b85bb2acb41dae53493e00abc19e0afb47063874deb062c8146c8f88b4d768207e1537e029fc02adcf35b041855e9025955a20ed0cc59ee124458ce4b7cd1e7d0422f51dacb7b711917579a02be09bbcb9e65736d91e51cbc860436dcbc60bb098f8099b6d72ec7b2ee3c1cbe22dc63a5811c5550995776af769772d16fd21e7529487bc3b2fa2661cae679684b7473564180066c77f6b50b1ebcd5832e878fd303d716e5394d530641a38e134aab59233682873f7f5721c8f3df709178bbafa773268025ccc3b04d3e25b5c522c9df0553466bc24cf7c2edf5d4c545684efab69c7ce050759ec1489b80a33d4541457fd2b8d2afb1df7d06db19591a1788fd68104b7f3040a93405a093fc945d6a99a947af1053d2159c28690e897a7ee11f99a84652cd426432b5a45bdc5212901aa794cf6220e5523cc50e15ac5893e62b4c82be0be43641295286b95f148928fa2291aaf551279cd7baf4fb20b417007c1e96dc4c3ab54fffeb55bf1f3135582bed21eb4f331c1fc4f65c059888ebc6801d21943cdad64be0c9f24f44dc00ec6c19b17136ed976fb3fc300d4c3c4ffc0c0a422beb5c69ba72199e33fd0706e3ac37662fcdb1ca840c2d0b4f209c3256eb5654692da941d5845b81f29fb82f13562f7ac2e21593545338acd2e6450958a12d391b25c25ef485d2b5476442cd9cdca65a477234359a71e0c335a7ab0195d1558f557b8108cee3b289de9ff5b0efc6e2d6d12c258655b95dbb19c93f32a6da3247f2686e996b14815a96f118b8912928462d495eba1acefb175481c4256a093844ef925af20956b57526b2cbeeecb85a505c091d02573eb1bf77bf2d5a686a24880805c9ec71ca25158cf2b91609e9f39fd35d2a50cc89b64c35100dd9a85cd5841d201a305625ec146fbf129c12243418656d695eb7e1208bb7ae984fe546ce53431e61b88016a1d8c5c684bbf4314f246c1a26e7e506167d24f2cdd3ab17f9bdc31d7777c33e132f29b3bcc1c999d67b2ebf3aebcf99a6841ce2cc307530e281e5a6d978b318bd1f51fb1c6c7fa9e77bb6c6968f58a455becd258dc5f6443e329f1732326ce40d6cc701a344a3bfc84bed27d11fa1523664311ab4b74e4c72c166251455eddd7d4f9674cbba553acad6b2cc4bf721c2ac64047e1644ac0d581048e88a738a6644d320a9112042e26cf1b07ed573f23089a4a870f63c450622468810bdb76085d7a043edcaba234bb7b1c764da375880914c40c875098cea626d50345a567d33c94e34c8a3d1fe6f371111111122a59429a60c510d430df9063efe3467b77bce35ba853bff9a8df0bee99276ee86432950f0d570ca3ef82ad853bf28a8fca056b10c501d4a81dacf9f168f78f20339e79c73c6410dd09b93d2db7440f4ae888067d3f1ce23248c40c0149b8e67ea7cc00445179b8e57268da00b1459d8743c5288291250822d6c3a1e58849503d874bcf1888e27be92b7e9926cbcf0d5a4fde9f5d43153c34afd22350a6a73d4a2ce9f562f129b50ab7787486cf66864b347f553ad0ab7f0ff139336980e19e1ad861bbfef4fc7dd6dfc5950fc4b94763a207247888a0c09828f0077fb623103e8fdce3b5ad45e90b4f6bc378fd6da93bc37bc99bc378fe43def784d5415defb5d309b5735a2f786e828aac67bf18a1cc79bc3f166ab023fb2cc007a6fd356bfa67ddf84b24bea17a555bcd3e0d4be36ca3e0a05b3f2e0cabae044e932f5064ab61405ca9326274c4d64f8fbfe5bca59df7e76ce6e5993e7e0f73dc40695f26e618752a0fefee5fdbe187cef7006a86f55f6b4bf57bd4ad4daedf169c8e8db2a7db36f74ea5bb8bf5fb551524e2cb511de59d790afa237f0dd365d6d30752d76988653a043dfe38c8c327e7fd9119ed3da6d50ab766983bdde962dfb9bda5fabcb6ee752dadf874ca076abb4a7fd3dd4fe5e6dedf6a75510942dd9f8c31da04b2e8f2a5b529235f550a4fd691569cddd7460ceb2a58d5fdc408531286f38bb71dfe7579336e8bded5a45d7755d418cc338adfa9bf6dac73863eceeeeeeeeeefef98b7d01baef5f9ca5509a148af5bdf849e9abf29aaaf243332dc795af52def8e5398ea37fe8b4faf2c315788eaa55ba5aadcc50b52acff2663ea84395f87da3f9a7be8d7f333f5495ab9cfa1e52fdf8e5dfe7a9fec1f3c3bbcf1755abd5b7e2a944df6739a646365983afd53ba646367b1cf538be7943dad837bed98d69423df43da8873e4d93f5a845993f04ff46821a67ff463e2efcfbd6874c319442cf3f55afcae7f7e5f1c7cf76097ddf61a8557387a458ea922cff063e2e7cfba50e87c8f71da28fdaa5264c4e9a9e4089f224650a15a82a569a888a024b969e962d7796df7291bab2d2aaf7ce57bd4aabb4f3cff30a5afef7df979f69e4936f962569c32b286dd30035f3d3c9a40c678096389747bdddc7b933fcea6c3693c964ff1f8bc56030d8ebf54251d4344d5114b3d2dbb28e77bbefb7e64e3838b3d94c2693fd7f2c1683c160afd70b4551d3acd99c6dce36eb23246bbf06942e53716fe3cfa20e1fe743dfd2cea1a8c3f16fe2e3c61f12df6fd31514fc1c7ef861a8dea8287cc57b175bfc590ab54bd97b6178efbdf7de7befbdb987c107f59733ee8d2628edd368b48be2dc731645d344d1d70b068bc5fe65321cce9d5d7189d6c382f7cd6ea36fe737b2df107edfa50d9d40ada66da4ed671803d48a60695bbde2ece3cc80c87e3c8fd80e588e170ef4866963c5f99ddddf49dae11534cad3566956dfac0eba8df5b5b4d53dc7e28d718aa303901f3c76e4c071c386cf0e0d6726fb18ec859a7e03f3ce30e0ecef73baae6bf61c6b64b3d5a47d6b617f0ef5e9bc432cca300a1dcb5295ae49bbbdde7ee7f256a9d2d089a3add2ead1567dc6a2b55b45d57b836d7cd32d657f9cde2d5b95e6ec1006a8ea6fdc755dd7755dd7b5b4a62ab5507b64cda4dbad0a6a57fabbccd3b08997111fbf0c163efed9ccdffcc1c78fe344f337ff8f476c070c96e3f5c281a2374cd38628fae4cf3b59dffc697746a38f743833fa4837d34732bc50ff00799fd6e1ceb08c95c1325606cb58192c6365b08c9579fca2e8736bf84746ef38edd6f06307e2325f3efe1fb35b7399371f3f8ffbe342eb64b7e6327f3efe5b7399577d59e6578f3f99471f8336c2d6e3f7e189aec7bf737f605a27de9abf0e49e65f8f9f767f604e3e52cccb3c928ce611dd27b58fa9b96352bf350b9366576ada551afb5b2bbd17811277f77abb5b75c299c93e067ba1a6688f7839bbddb567d1445fb0d8cb78ebeccefc7376df37b2d957e3dcd935428983339bbd4cf61f8bc56030d8ebf54251d4344d51fc3e7f1a67df6dea8483236a9cd92cd433998c076ad99dfd8bf78fc55cbc3f0c167bffd7abe6fd5114766133ef2f8ae2ad6558beb50cd347f93d699333dca3c34182c9ee8f8dd6cd90607ffebcd03a19122c76793eede442eb1e09f6abcf0f8b691def7b1d12ecd10fb5538dd6f1c047823debb376a2d13a5ed8fafce68cd6f144d7e71779e3ebf3671109f6303f335aa72b1f49e6618f042bb57f36b74cea261abbb38ca631552a33539c219a78450be0d0f07cb39977192c7c99f758cc0883e1215faf12759966eb4f91c5a3d2e84ae7f7fc567532b2d9f97170687e369b013f67653258f8b9ff9711df3f168b193f67613018727cffd7eb557eee51d4657eee4db3758a2cd5e7ec3e6b78a85e8d6cf6ea7376ab7856e7ec5ebda7699aa6699aa6696a93642e1881120727cf66a04c26fe93b1980983a95e2f14455ba6f912c598bff633ecafd5b8a47d9d68fee677527adbf738f7e7d3473a9c3083ff7dfe09f5916e36823fa33ed2c94a51eb74e38b3fa53ed2fd49fe9cfa48175b993f2b7da483b154e8af5e2f17aa753af4c7a58f74284c4beb744aad1f187da433655e5aa7537afdc8e8239d3813a3753aa5989f197da4cbb7866b9e88954ea704fba9d14744ac745eb3ef3f93e65bb30f4bf3addd9afd1898d4bc35fbafd4bcb5fbae14bd35fbad9495be6ecd3e9abe5429ecd6ee9f69ecd6ec9b692cfd5bb34fa6632aa63230fd529c5bb3b5fb48301b32292fce9dd93bbb337b657766efdf99bdb13bb3177667f6beeecc5ef4ceec35efcc5ef1ceecbd7ae8fa5593f6d50e9bd9dfb933fb3e7766dfc6cc3e8e3bb3bf43877c81f27ec802d4e25fd7755dd7755d572d4b574919da00b5a288a230d8ccd7d5e3c7afaeaa3fdffcf2c1ff56ab5793f64aafabea3475a92fa9fdce420ddeac559a5779828282006a6eafa24493fdabb2188bd21e51031430b17dc90f22ae3ca0e7240909ec244238e00658aa4881099ea4b6ea5ec2035c09010b92a0812729b65ff15dc0022238c1f629241d44ed14b0b9e89a9e7607d837fbb8f0e9c96eb755d772b37a48f5be71e5172d7690fba10a5073e3be68b1692d4055efa954af266d955ed735c89d59fbce65dbf72bb6d5b350dbddb66f93e4d37e0a28fdddff55e2e0a84e4aef3f9bb5f411ef737debfd6532973ee281af77bdffff4b1ff142987fbd7f2c06a38f7862ccc3bc3f0c16a38f78a3ccc7bcffeb25a38f7824ec65de1f4561fa8857ce3cecfd4d73461ff14c9a9f797f51a4d147bcb3e669de3f7f7ea71a7dc453bd4ec9db625ff38e6a3569a37fc37a08d5b7fbb8ed14d347bcd5c7de3f96d6a4f9d6f0d3a4e2ade19f49cd5bc30f93495fb7863f2685dd1a7e9834766bf85fe9df1a7e572abb35fcad74766bf859298abe9ab451bdaeb44a67b1d4e89dd951c362fa35ce9dd9472a935437cba00c9940bd0a08a236ce6eadd28c6cf66d76966fda07bf5773d76de5eafb6e604982efb8a40d0e216df3c91493bcf2417f33fdbefc9cbe1bd7a5733d4babe1eb54dd26b50aeadc2dc154ab77971f925a153709be49fe0d4caabe5cb1fcd6c44742358f283ff82d19f0fefed6f0ab5255acd171bf3fb51abef825993ab15e44dae48320125ab21e09d52af8e08bdf83b66fcd3bd4b9a7013579c12194e5aa443afff6fda9d79bf9b7ef1d97b4bfa1f3578fb4557fcff466b793d2db5844589b9af777749f77bedf9a69a6e07ff9cfd4f72a753ab58ab4cf577a1b4bf5e6abbed7f9ad99cffa0ffc33cdcf02df593f2cadf35bfb74ce0c5babd729bd4ddcaa57f34f4beb565afdbe7c5deb9158efb7a6e6add2eaf7dfdffd02a9f4361def7b24f4599a4784bfb44fa6a3df9a2ed43577671a500fdd8e6c75b57397e6d35f054acf0bb0434071be2af06d2a76f9c69d38eec42e5eb2b55d7a1b0b0af212a24dc79dd8a58bfd1cab405d2303deaa10bb0beeb13617bb609cdf4f1a8428d1cb03667d73bdc290b77d1de1b62f8310db8a5d420b3809c37084e2044b0b750c8e51ecfb59442dfb3ec865dfc7d8dd07a764943b239fac0d1bd606feec0d1b2593dfc09a847267d7deb84e320055ddcabd2af568dff01cd6567215be0797a2b80ae39be36e541a97708f0a25a188bc7d5f6c727bc604f80a64122be37e17f1c938e5445400940bf6b836938482bf46877ff8a11eda79df2494cb133e0925d43e7776551a094509c3486257209f5819f77da0ecfba412eef14b3eb9a492565ba4925eed269f6c149fd9c9a740551a6cf5e7f9d676ae4e7375feb55d1549955ad711df9eda5d47247518feb5d74714c390f421491fd2271c9f6677683b29cb4b6bc7eaa2d2ba5c9b7f4fbbb4177e949e464221a190512ab005c786cf6cbcae0e54e0490680f0c8b2effff02c280c8ebad5d2db726b401cf1a1f188ba5197c9648ac9b62ae2cc76b62a32d9d8aab87dbccaf6a89ef147bd7ad5c68e8aa3c65ee4abe6abb2ad7ad4ca868f4af76ccf61e451cb1c86bbaabb4d600e320e3dd8cabe38aabc60f861a9e2277be5c34be2dd677ba202a2f6cd4bbd27bcc30f6a54fd9aee17857b44145dc1547f9a17eced7662d36e27365d70a78442c1c01ed893eaa960af047b526208f55d1f14ec7d4d18ec7d4d4dbbf24b35849222a7a4bc27753f2b1806ba8329bd7800344a85809d987752daef0d5204c3c0186325acc444d33c578b85aec0dc949f4070fc91e66a917669dca14be4d395310adf288cc1a9dec65a05bb6cd958637dbbe02b34b0378a60deb16c288325d3cb57ed92ea3d95d6c33098a69ac02e50761b63a5291867a8124b79cf5e7df53735b574250bf4d3365c028d104a8956b4a1d47b971d949295257bc5be0d400b95972c544f7c52f1ce412b8e4c514d58a0f4beff32146d4a1c412bbef8a11668f8592d502cda300956691b5fb962df4ad91b83615e5cf29ef7a4be5d8ed118468b1f5e4133ce5150198b951666612928540a955269d54edd51d44df965c52ba5cbc20fc1ecef4f038b71bd9aa1a4d00fb56aa7c02c154ae5b7be5adaeef25dcb3fbc82aa370b340bf40aeb57ae0faf944b9ffebe651f4ae798566d971aade6a88c25f7eed286d12fad5e26a95fbd9aa15a9aa5553ba5da29adbaf64bf26a9bf3d4f612926a6ce88032b422ed4dd94059e1a269aa4685f5f2df5763a0f2abaf26bc3acba6fbe36e0abdfaa6f8bdfc5ba975bc5bdeedf62d3fbcba22505bf85e94505b696aa4732909cfea75e88aeb10bc88b716e2242352dfec26df96b8f16fa476c28ddac9bca5158f9692ec763b4cf36e9773f7de2eafa6fd852e2a54a64c9122e5e9c915c515c505c505c5f5c4f5c4d5e46a723971397131b9985c4d5c4d5c4bae252a53a43cb9a2b8a0b89eb89a5c4e5c4cae2557933bfbdeb544c995c4e5da79e9125e31c5650bd6d2025b3df1fbdcd2ae252ced5242b52bc94abb762addf272ea569750b7ae28756b8ad42d2ea66e6d0175ab7767df63ddd272675ff8654e73ce43ec300cc3fc39e731670c6230679cbf157e30e79c73b6165b6b6d18662b56bda913ca8ab2696adc5901f6f6f7e114fa7d86dadf8756a02f96094d3b7f194ea1aa6cb76fa8509932458a94a7a79b2837516ea0dc40b97972f3e4a6e9a6e9c6c98d931ba61ba69b26374d6e966e96a84c91f27413e506cacd939ba61b27374c374b37374b6ceb9d949628b19492a0496e76ab9b9d1795972e67972b9c5c5ae7ba626a8a0bc9658bb9458bcbfe0dbf4c8bacf7f9bec97a375c6ee99b252c7da384ea9b242b7db35369999753cbbac8ae904dc9b8c8d64fcb7a322d7796c10ce2acca7621b6180bb1c1d1baf8d68aa636cdbf85df9bd8be2df38b7a28fcefadc518638c31c685f8438c4110092634a15c8e800588c515e12782200886e207822f7ea2f869f50bc50ffca41d82df07822008822008faa9c33620dba074996a1d10b5f17f51a03c6972c2d4e4f2f810dbfc16766805aad22f3e9aaab2dd463f2c02ea9b09172e5bb668d1d2eb65c982054b1451444535d184152b55aa404171d9a2a597054b14514d5881aa7267f82d132a99e69d94a84c9999220526e549e6294a4c142823942735e493a6b2c949e884c9323501f3dfbe67b274b3be59264b1a06e6f17f34da32a132a32d9329306d994891d196c9538cb64ca28cda3281426acbe449a92d93a6505b264eacb64c98aeb64c962c932677864952251ffff825fae5cd66c3e821f0e995c6e01b04576fc4fad69faebf815da911deaaf9dfb752237c0bb7b9db2a9badc2fb4c55bbb46463874c78d6e3973a4cc16c2d487e19a6f8c9f466b3473d043eee3e983f067ba1e6febefd7d20de764902b2dd0e43afa2b7bf5c05172ebbdefeaeb8152bbb9b29294b5bd6dbdfcdd2fe644ffbbb4db2f0b16a9790805aa525bbb4a4a98b5db20e88dab02b4b40e93297d2e0839f957229a82b6878bf7b691b6b958677a292106a6795558958d47e6756854abdfec57a562b94424df34329b0e7fad6abe112cc5381b2c271bc9287625422d6f86f2a1167a82fe663542a52ab54dff77ddfa755d25cbd6aa7aec0bc5cefd2aa5d6a7deb432ad016eb5962a9ba127e885528954acd50522b29b047be1aae56aa900a943c97cc37cda59dbf8fd4634f3f2865b3850aa15cd695a50c8b80ff43d5bc5196657db7697f1fba62fd0d5db1bea1f2a9404f32437d647e5275a940d147bf2694a555f009855aadbe2628359c42bf268c3e1a4aad1ebdb25b41e1dd8e24a7b6fa3551819e7f8e4d160a7f499255ac34111505962c3d2db37befbdf7de7b2f15a8fa35edaf09ea45da0ea5d0af69e307bf4f6c423f50da77592a36a12da99e2567c192b14491a38802735413196cc20a98ad54c960152890c5b2913fc76a692756d64ead9ab5ea0e6dd3880f588d6cb6d37d201fce7fff07f87d7f9f4708827f7f8718867f3fc7288a7f1f0739263969c28125c6bf7fa324c9bf6fc32c93926082cb937ddfe73451f3efefa83e67b34fed846a23a038ff1ad9ed847ece66abb4134beb74bc1bd20c40b0f1f356afe3dd8680220b9e6ae8b675b83c59e36ef89bfd07ca1e0cffcec4d88b3fbe9e2cd12f794c8dbbe137cfab7137fcb8fc2a9e95c6ddb0be8f31a6e91deda36de81b38748e1d9a87fe0144873b0b6380aaee7944894326be4f875cd0507f4340f1e3bf7147d074059ddaf8f1072585837138c817fefdb4aadbdf0762f00331f88118fc3e8cf187e017821f18821f183e4e71369529529ea24079d2e484c975b0bf30c4f90b4d2e652884f576f77a1b226f6ad2cdeef5f6fdfd9b6af7c599c93e067ba1a6e8a49ab449bdfaafe6afe7afe4afe3afab5fc35fc15fbf5ff3afe2abf47abbe59f7abddd13ebf576cd5f6fd73f1d4b5db91ac72038147322181e093ff0766f1e924b78de69bab64bee2c067bb1c218a83d86dfb5bab3f1d3dcd1165a82ab04add3a9764ab58e07c688a1cc28be8095dae985d6f146164fd64ee50c2fd320c9cc9ac79b95f2d0d4b368be60b197cdc6344c3d4aa56d275dfc8d2433f9dfef7440e48e10151942921fe4ceb0b5d6c6f4f3426ded92582c8dc53e16b389c55ec4622e6245623f24a68f825825b284478ad924f7a704523f52cceeee8fd63a19524c9792ff4831205eeb783996b3d13ade173bf222e6f113b99079fc45ee8f0bd8e31f727f5c90b120f7c70559f3b1478a691ed1a579ec5f43330393898179b95a2cd42e9db755831297ff861f97a4caced83d5b28d875ade2b73785faacedfd2043edaa24d95869e3c77d51966c4ce5c351cd4e99f9658c848d2f11cd662882f9ba9fe7bb69be97e53b49be8fe3bb28bee7fc1e86ef20f87e9f465ba2834aab9e4509c8ad3996243f6ecda3b03b1eb7e651ba1db7f63501448e5bfbace470885af52a476edcda074564e3d66c14f1b9b5ef413d64e7d6bebf9a1684666f6eeccd8dbdb9b13737f6e6c6dedcd89b1b7b73636f6eeccd8dbdb9b138384b663325992cc9bfddc5623a180c88d72b87a2474c9348148bdcda77a3bf27c2da86dcda77a38f82dcdaf79e3fc78e1a1eb11f2e80bcd0c1e66f4e2e1c386edcb061c3c767678746b3d1473a9c99ec63386ed8f0d9a1dd7befbdf7de7befbdf7de7befbd2b9d93ccaee66f4e3149627f73825172b1c4e9c5df9c5c400001cbe5668e1c691111b18a144187fc90d5833ceb2dd4419c6e3e559df4910ec7853ed2cd8e74b2984c0c8c0b46e65fe66d3ee65f3cccbbf8d7c7def540dc1f1a7da483d1a40ffbef73f787866646ffcc7f7fe4fed0d494f034ff3d518b25fb9affbec8fd69e9239d6802eb5bfffd90fb63823ed265135637bf7af4bf0f727f4cb8d13adaadd9ef6525e8f46d5eb888d5a47e6b34333099189817965b6bf9ec64d9074b22ef8b274adc021403a5cbf017fe774595fde5c741ed50abf80353eff99d0a940a14f7458bfd18436dc91843dd59152b4d444581254b4fcb162e535774b15e76499496d8cbb46d945dd238bbed7b2fc9da5dcebccbd49934c482da9ff91975c6d2bc6aa3926c00087b08f6322f8361f0c5090ad88e783135300f53a375198b10a02081ed88f772bdeb69334f73aa799ab7990221a88114b6235e8b056e00071248623be2a1ab5fad9c34e1c012b6239e0a3401131c68b21df1cc55124c7079623be291d608477cd9c276c4138d80027c257f9bf99c625a574291c5972fb6231e7e256fabd147bcfcab2f5bcc0004361aaddabd226d9abfcde8a19bdd343ff36ad29ed1ab8cfe55af2fbdb6f4bad2ab4aaf2ba95751afa05eb3c67a67ab7629e401da4473bf2acab0073340bd081fcb2694626ad5fb5e559daaf9b4dd5572097fc66fb5e3de1775fd3e76ffebd7b3b55094a59ff76daa3ae9547f1375bc1b68e500e78fa975bc9bdde263ac44c9db4e7d94640bdbe9b7f6693577c5376f0dff910e899c2202560c60331f09b472009ba97959af38bb57272416a0a2045f6cbcfc622aa64638bbd752dfec2e3faf4676879fb3d9e27f298efc5ba99d70a4763ab5ee88273eef7b256f3379f93f21a688801503ec3005ad1c6083e9ef2fcda999bbfb6af537124e2a2f26417944be923f2ac33f325fc91f9dafe44895ff68c5bb7f84be92b71db19e879f957a164df4756bb15bb3a3769fad6ba8dd67ebfa69f7d9ba627db5fb0c494c12afcda2bcdd6d6e501443127cfba31e021f875fa5dd56fb3e86816b69e7d66ee721fc535bbb21a3af858d31fe3e21a64087f0e3f0f7e08320c69fd547be1da0ae2529caefcb52b7ed873240d57137eef6f7391d32ca1bd4379b9d2d0c49db0eb16d980374283f2eda4b9d492d8eda14351aead7831af6c1d4ee275924d6059594b1986324ca0c8aa4a9425bb1180cf67aa1a8698a62ceac346751344d147dbd60b0580cb57907a5cb7e4cc3a1f049310dbf0c410aa0e28f4f82a41e1a3f8ffa48f8791cc7affc711cc7711cc7712ccb1fbf7097dae8eedc78ea98d9a3aed151eef16b74e03ddefd634aa63af01eef87575cfa9ab8770abbbbbbbbbbbbbbbbbbbbfbc557a61c376172d2f4044a94272953a8dcd9ad62a589a828b064e969d9c2456a09a47d76a9099393a62750a23c4999428526cf9a3039697a0225ca939429db6578f580d265a5cddb7896025fb888d5d0ccc06462605ed7d562a12bd56996e468f3e5356ddee64329d43ddb3c98419bfbff54a648798a02e5499313cb658b965e162c5144356185c82d151c9c77529a92420a525040e109068c28b3d9e7f576c2dbbf7def9473c22b79db8ca51cdd2446ca24a30427345993ce7f7fbbb14f6698f04adea64393bd92b7c98891a38f78fad3439fbee1924cf8fc38daa6a02d0adac2d076a6ed09da9aa0ed8db6326d4bd0566b9b6adbe4ce6cfe7717862b894b2813ace97144817261f80e99b0016daeb55436f8ab9db2c15fad14fb64a35828f6896d8ad12bd3067fb54d36f8ab5db24bac924d6277eec5bb9ce0af2bf8eb1ae4ce402da2d1093ea803901f3c76e4c071c386cfcecd3e2e69e7ee27ed2918973545f8416ecf8dc230c2c7b2a537b5c5bb84610945658a94a728509e3439616ab2b4442989dd79e972c514972d5a7a59b04411d584952a0e65c307049da02f3a41c10f3f3cdaed21226ca94c91f21405ca9326274c4d96401004411004411004411004411004411004411004411004411097b4adcee124b102680d0886187c1ca8d235e79f5a0455200882f6d59927df6a47daf7715a83d3a1f0cf172b809a2ffe10f8df87a7bec9fcaf35301ffe1a6a95f567786ab5f5a156574fea1ad5ab332a9ddfc587e99b8cc625ed5cd2ce956f14a36fe156fd5a03a3731cc15e78ad71e91c481b7cdf3994a58d6cb67a37a8555cd25e6fa4565b9aa5d5d59f8f6a24369bd443a036c27ba58df056c1c721edf27d9fa9df5236ea21bc3b7b50e62cd42e6d5aa3036fffbbd55347b95dab77dbf7d4c8eac047db93aebda174d950aa12792f54692eaa48537bd4c5308e224dfc78ec307f4992e187d6ea9af1f317d307758d0ce66edf3777fb7bab8ab0cf5fcf015ee5696a43a1e24e82002a6eafa244d4f62a1e58daf6ef0cb17488f5be4b2fb3e967ce639aa6e9287ee9a7f7def1a637bb453df4fdc7be4cc57b75ee6ef4310bd535a6686fdf8b8fff6a55bce976fe35f6dfc7d2a14fab4ee9b3de376ac5344d95de96a2aff4b6f4519da68fd3d46d5faae6ee6569177f3eebcdf79a188bc5aa61691caba6e6591f8bc53cdf19f9629ae63b1bff9b49875c4ff462bf1ea655bb61e5abde34450da0adcf7706fef9e6abbe54c13cf9313f3a00cd2ff3a4eac1075d9c335ab57be6bfd48626559d10f09fea88b0b6f411907e2ccdd99cdd2ed0c7897fff3ecdb3621a17633d8ef5b1af49876ef65d689c8b7ff1b89a7fa16fa8764ab5d2db5eeb8e7837fbf77934afe46d36fa8877b37ae8b67135efe26f60173576dff4756720f834690c7667e0cfa43c6c91099a9ffcf1065ef3063f06267da5dac88bed7a3f5f70e91cb8f3dfb8ad3467773e57e90be59f9f9a57d4560744eec8b668b8595a4dbae58d6aa3bbcb2fadb94aedbe3cf62c9fc6fea83af5d067963a875d26ea8fe6ae98942b383ef9f6bdcb1553e0835257a43049692265e9fc53fc4429fb7ee5e390b8e49357c0f1defcbab3fcb03bcb1fbbb3fc8f7367f96977967fc7c62c3f8e3bcb9fe3cef2efb8b3fc3fee2c3f903bcbafc39d6530e70cdedb44ea008a52fcd27472fdca14cde7f9971feb1d27ea21d0347ab14d5f7dee6ef3c5363f77f74a8b9ef76837e97736aa77663ef8a65645ddfa9528ea4aad6b916fba6d058237bb41ad3ab9be27495285494baab66f75f5e4834337f3cf075f5de9dcdd60eae402533583a98a2abdcd658aab5fe91f97d6b91ea9353e2bbde9f6e74addd64a79e78be90defef9d5a5f963ffe2a7572b15e1457a9934b2bbdad85335fe96d2ddeea7938531cbfbc21edef44b5ba4a6f769b1fa8828f33f51058d2907a48fc510f895ab5679232ffe5a143aa91dd3810fcf576f7b8def23e7fbd89dbfc1bbacbc721edf1f19957a68803ff56eaa1ef7de3c0374237f85faa037ff9b24110d46df0c9144792294e14411c2ec5e5bff9c6e5177fccff368bf9733bebdc4d1a2d3662c97bb877a396a09e9aa076796a2a77f9769fd2b7f4314da054d15de6fb2a085544e9b2d22fcffa3bdc02c50f8a084045fcdb3dc74522efedd6d4764b64a136a8339833f87d597f1f088220087a86c2262845153685420edc31f8b64e2b6153dbbf5b7ea93a79afbde79f54a0aa57a17faaacf768f6da9bcd2ca592eae52b2529857717ef34fe32d82349506e81daf782e61a9476fbabf984daf78940f16ea12a9314417c96e1d84255262982f82cc3fc6aa12a9314417ce6327cb55095498a203ecb1c53f36aa1a608e2b2a6a6269ff96b625e2d5465922288cf9206568227cddfca1a4c53f3252ce6d54255262982f8b4b098570b5599a488410b8b79b55095498a2056c79d17d4880c7543870c396280e1051c2ed8f6ef71bca143861c31c0f0020e176ce306c04e0b2caca0420d9f1e9edad7c210003b2db0b0820a357c7a78c2da8f8d190d1d19393829a000e361e4fc6363464347460e4e0a2864183368316227dc9490dabc70515333e3d71b7eb5e1d71fab0fbdd6f06b8f95c7af34fc3ac3af3bb4c5c1841b6436e81fefa386991e3c6898e13c4b1a137ebde1571b7efda1571fda6bd06b8f5f79e89506bdcea0d71ddae200bb21c686d797e58f960fb406550f1e240d338076c7af37ac36fcfae3571fbfd6a0d71ebff2d034e819f48e2d502a53a43ce528194a7e929bb293cc94977293bc242be52479e7a5cb15535cb6f4b464c11245541356aa405199f2240547c150f013dc849d6026dc042fe1255809ef709292871387c74108101050006e4e40ca1d3c68bf331c74972ba6b86cd1d2cb822500519c426ef81b8200d9f036ecf0e37ffc6dbae7df02f8781f04a8e16bd0a1c7f718008fe791030d4f830066f819809c7f2bdfef6cc7ef781f82c32b79db792b85dc707f0da2fdce6cd0eb0edaefec87566f957d7f2d80f63bf3a1d50b45801aeeaf3a68bfb31e7a1d80f63be3a1d71cb4df190d7a1580f63b9b41af40b4dfd90ead5e2817077bb578040aa58e3bd108543d432fa8bf7a1281deedafe62d5003a0250ee7e3f0376eb8e175d860c3cbf0e3c7e7d8f17b86b7d1f02ef0781c3dfe851a1e061f35f478256fe341c30c3bcabf9defe36338cf3100e5f9e39f38dcd06aa672830eade62936c8a0d52ce5470eade6271f31683547a90106ad66283d5ed06a7ec203875673130d2e68353b99c1a6d5cc14009d97766cade626a38ef2753c006490e17772e4f8166288e1598001865fe185175e051c38bec6f9b5fd3cb6ef71c1b6cff16fe5bbf03e6519de18c751af3a00a0d5bc44861dad66a51c2d683527898105ade61d0c2b68157b794105ade22e386a68155fe1828f56f194ad47ab98cbe6d12ade72e3ac69156b095b18bf85ff618185b7b1c20a3f534185a7513e8cf351a87d0a3c8fd3f3393e2fa3864fcf2b791b4fed2cc3bf8d5fe375c631ef84630b3f5ac55958b0a1558c6585995671142ad0d02a8eaaa1a355dc848f0cad622b3d395ac5557870b48aa16a296815533951d02a9eb2a31d3f9530b48aa5641ae1d3f8193a3a4f9321e363e4e47c0c07e74f48012885bf4101852f617c17e5bf38df06c6598ef96fe1c3f8340c6b6639fc9a0f69ccd02a8ea243d32a8622238656f1939c98567113ce095ac54e52b8d12a6642a104ade2263052ade2a5d346ab7849f942ab5869a6fdce6ad47187939c0074c29b7073f332a0124a780d94be92b709a5ff40e1af5841e5bb889c0fd3838b9729f2e267846c5ec9db8abc7071060d0102fa9abfe5b7f96fe8666f4eb1fc349f6b5e4dda357a3dc104ad5e2f3732adde2e2568adde2bd2d7ea9db2b95c5ee8bbc5c5d5727b370b9698f63ba351c71bc556c7ddcd09e86bfebed7cc0cf99b8cccc7c0c0fccbe5fa168bf5e86ac8ea553d9c6f0ec98f83887ccddf68be07225a17342403e923de5753f3371a3d74dbe5935f43f36ad2a6d1eb0c4cabb7099918ad5e2b30fa5671e90bc5ba5456fa4e39f595729f467da384eab8d365d39dddb7dfda09b956013528c50480e7799380ba69fe4dcb0fbfa0e187e28be38f0a402f98dff49e9d6ac220c0e24e7cf16e15efa4aefbb964cd37d5dba4525dc95a0a7d54eabc5aa5d1a4b04af7ce2bf99a52a56aa1462c5e2970676e51ba4c2d45f1fc53447fc4a212f4da0fbfa03c76168b40d5a4b0e99ee9286af108d466a87def35bf1fbf25b108147c3155c7bf6995283b2d1ef1a3ce198f29585a136a675114717cf2388a7a1c73ce3967ad8a6ff1bb2cd44344ded3a01e22ba4d1bff97e6d28a529437dcb3f95eabef7d9cb549d9da2e659524a236789bee962d53535df66eb7fd1d3f3ded9494969698989a3094db74ed4381f2f434c55ad9fe5539c1d226f22a2598daa026f2deb550b7c7425d18f6ad6c1b65a37abd2d5b7a825c18f6b76cf1a9dd2e64e266f70da5e85de9c14fb6098a9d425ec14f1743ed1b368eba70f867435d381cb7c630b206e572428ec85873b81834e0ee2938eab22d2e468472b8a0215f042827c487a0a2210f631604b42229c2b59e405b537c8891a09c90c7a18eb698861809d28eb688b47e1029fa5f8b88e4562139dc07f56044c83aae5eb88fa207e18884100942b2e6dc1d8bee76169e60c5c3dddadced76b7377a5043e77f7e5d9100a150a3864f8d9e1a3c356a35766ad0a831a3864e0d5a8d1a3e3e3e3d3e3c3e359f1d1f1a3e337c747c683e357a7c7a7a7a787a6a3d3b3d347a66f4e8f4d07a6af0f8f0f4f0f0f0d478767868f0cce0d1e1a1f1d4a8f9d47a6a3cb55a6da746a336a3a653a3d56aecf8ecf4ecf0ecd476767668ecccd8d1d9a1edd4a0e143a387060f8d1a8d1d1a3468cca0a1438346a3c60c9f193d337866d466eccca03163c60c9d19b41935747c747a7478746a3a3b3a347466e8e8e8d0746ad07c683d341e5a8db643a3419b41d3a1d1683cd0825014063e2031428021c819393bfaa31fe21f87c42187f8ff7f77db82bbfd71b72ccc86600115008a06005d0145f5ab1024c8ab40e20409f22ae4880411fd934160e48af420b4fee7880411cd82bc0a6b100e27840516d095177495c5fd714239243cfce384de4810910ab821469014f180a4e8ddad0d77ece8ca04531ee784133e27e487040d0109191172c43aba6282ca107357218724006bd1babef043d1ba16d9dcfd3aba1a72f71831706b8c21453ec8c8f940c471aa1e386e8dc18310112dc64e0c9d1c19447468b49a8e101e78983163488f0e119e9c22a118b8a09c901528061041438c0805b1e670423d04adb9b5880721ee760577ab82bbade1ee32b86796cf70cf18c61377eb637bdc2d8fbbadb9db1d774bc3ddce70f7197777c1e6ee3838aa7a396e8d812312ca21a939a1e0d6184110151db17177029c3aeede831043335258410680725053841fc800e1f1c4c60baa0842061d66b8c2c20654288217455d414b109a601f38814ce125240b0fca8b037430e489004e84160c40dad9a007a19407904c0de146034a0c21092a8c9c32ecf0031f2080e80324500e02d025c1a6003c4e72d88123bb0491610700580e4061c405a9c28a1590a00a5511601010430d0d099a40c046a287154480049ba20820c00f34b1c002549c08c204073c0085e4022560017e0660e20017785091a2a8871200c1807886989a4cc002343642404506a03c20891f147ab043c2085998a0444a04688c50840668e0362151182c0ac04412765a1ea0434823010ddcc0c5871f9e00e2e3480d38bcb0430e261c7cb800c80982708597554cbf46a3bbdf2f5a94547ebcf01035a0aa624b5ae0b900a07a44010283c78d1e4d7020801d5c3884374f2cd1403441c0b460c009a23c6006e60ff4ad657fd81728b34052c513469a486f70c58da910a84e5811f58318606880800b5e2b64400540c878e96102465f8ca003124a96b4f061c6b8fb1124456b0fafd3c31b11fa5c9191c7097dce8850d1910f2a92c305ad477c2802328264079d233be470443cb8fb8dbbebe0ee4545b95f8b8808e58890d4e0ee38b83b0aee3ec45130870e1f371904b024d4024f06e629060eae24a68e28e1531831c302d00f602003f8e54a0b383eccf0022b08e985ab0614181b28a04603aa500166030224c82c422e6c2cc42b38b8c12402083fe058a246080b7862be2882122f3025911ae2003cbc40d0821860e051b30003d29a1a70004301648cb61b2630855112b7a51c8e828050c1032ca20cb1a520811211240d9f80126a08f100ef82040570d902044d838e0c0860021a585604527460364594531118c0335590e40f1b10019379b2841459228b2a54e0e25a6125b9451c65f141c36a9281143d0e6031e083195acc505223ffc8f2228b900c6c00ea042d2558e8c00e0e3c31630849666071e0058c181634502ac1074a8c944e301182d109b4150a7507a30452507100140108c20f28f8c109ee865bc307401b46d0233d02dc40122f6cb440e7cb0880e4b0dee08618161cf5b85c2004640ad402e440e503338a20d500348b293150a2d7002eba227c2a208416fca0035f9e18400328062b4918e008ec081a5c708ab927211733c08004ba43be01101c4ed408a295f3d3a402de010b74c0a0c9911a07843012c2802907009021d4cb31a100630db67802495523010bd051830a88102b00846cd0010f05d845f186b0c46340cc161c332ee03133c3121eb820b1000be4d06ee0002d081a6c908c9b103b6042c7931212d8c012b4276e685164a339620016b92cb48d071a3946c0e08a18548831841f7068d0c089a414681075ab391285649f152558a1a90d3d1668c1cc0f28594101208810822480e8a1034121b07941162652b01a8000272230853783490da90740923873ec7c5b08330535acccc0082e90b0c28409641115c30e5a412861e4061e60d849c23340244b114fb13386a40e8400068d85076064351c0019454021871aec2007017a9cd023021bb080e3440e3420811809a8e23504848a0b3280518a70e04bb86049027ab86107c96a3a42bec2cb8f1150f4bac8762063b033444f039688c014a00d581c9002027dc036353ac860656724c20b8490221188d8008422ac1438e121070044288000027022881ecc2040124ce460891f32d08000f470563fa85600c185a40898e0452c808d190d88706005587e8c3d88d46083091df851630b2eb2735704033490408c112a04f12d5ed853bec4e8b930030d15b8c1340515448831c46380348a79058f1483a04c604b0ebec85043810c032409e928c2c47ab98028b195a0050a0840120e82443145bd208a1223dc6cf4a0ad400544ec4d0a5e3802e8052e5f0102f0cac014b72158b440414e0492744c81841e3618e046d48c290f08c1078fde920a3041289d400a952854da083f722c6144298b1d3e5918c1630699004e480733bc089e6072c3042190808318d965e709267064528044ab086591910f2008c1f2838dca133b3810c1022781c80f9680374e1c91423705120a4857a0c455025f675ad09040ae052116d0a389278c708ee282fd1a615c154e3e6058e028078d1a58c43103583e1f287872bf6c31802dbe7cf9f2c506092184fb1f8ad6074268cd09f1e183c8091941f2448a3e5754b4be11a1201ebe28f738a10f221202e403b7c6c005e170414782c8bddcfd851f13dc5d460747bf28b83506ae85518786e3b87bcbdd65ee0ec4d17c056e8da1d3c30e392244dcdde57e8dd06167f082bb450104962861b9db220e6080a313dcad0e881d76c8e1c28f6d8b21071d2ed4606bd841e7861d0400830c35bc70838d861d361f30581cfb76c6ede8aec5e8ee4790717720f0200ad2dd9d80e1ee4bb82f41c3dd9510b283cadd6d8871771f568748d17f0e28685d8b808c087d51ce88d00f091a3282a4880bee4338eeaeeaf0ed0070f71c1cb55ddc5177b734d3ddcad8d9f1d9d9e18850500e47c4830c1f20209f1a4d47068d1a0d201fda90193d3ab5209d1e1f22393d08319483cb21291a020a2a02242327d4838ca21e56214031640c11e2830f428a20f14146900f45456414c90d11fae18110e2c30711f1208448488891900f2a927b23428ae47e0deac14811d1e384860409111d3982c4c790a01c50d0112082be48ae072341445ff4432e874851ce1af443d1912f9213fae1733821a2dffe39e1ee33386a4d771b23c7dd8bd620213e081e3e68889091d0902fca7dee880f41b99c10dc1a630dca09c908021222c205ad45403268f0d4a0d50022c2530bd2d9e921e2c3e3a313544367864f0d1a0d9a4e0f0f9120202235746ad482806400e570485619eefeee9707778739ea5a706b8c9c0f4470dcedccd7a2750d7a23427e48909115492e68cd1909f22188e8880f429f1312b2e6be072342b99c101fd622222fc4ed04dc9dc651c7e1eea7a38e73771847bd00438288848410795c502e081efe8914bd9122a19c90c7ad31fc73bfa6bbc71c75186e8d011464b4c30f425619402b4e0650111191101941ac42561e8488dc6d0aee1605770bc3b3bb9d6525a64a87daedb6e34c4589b2144b807b743aa4fbf891ece7d7f17e840fbe2e89d2dbbe1fe37f8f243ef9ae7545bcedd33a24f049adf436fca34612b5d2dbec7f1f6a24507f1abf3f12688d94f8cbfcf77ce15eab1da7be93b0d5513a2ecbfb1f9198e40006b0f7afbee976d64336899c734eca49e990fd6cbf2c55fb0048ba39fcdfe34fb749bc433df4e99b6e8f7a48fc32e9be0dd32151dff0ce375dce18e38c73ce19637f7bea58ddb7efef81d2f1fd1fc32f4b197036ba9fd31b6c0f5d9dc31bfcbc497dd3e5b05b7cbc4755d437ddbed6b3bee13df47eea585d14d82e2e2227512a226bd14d709ed6761e21dd17f5eedef0bce74d93d2225ab0e12fd3244ad686bf88166c39fff93fb0f9aad46d657a9e4f96af646de4db17c73189f9e7dbf4887c3bda3f2adf2cc5fdfd590343f8e050a89d82b80f6aa720f0b7b0f36753d43bfca2792651896912f22da977da22e12ff50e27517adb9903badbed7636fc677a84845fa577f8cf1ee70ffcf7c954c9dac81f53256b1bbf4c9314d1828d7c256b2bbfbce989cf176a7ae43f3f07fce68b6992118724dbf9f68fc8bf476549a645f06e2d6cf0adedcb06f5905310f79d82c88ff2b8ff9d353df2dfff81dd56da9307fec717344129e29efb6e5325de55ca4994b2e6dd5a288277736b7148510ce37b7104a88d5224813805bd5f96abd1cd667f7fcb7f3f77b391c15eb1cb3384b33bac82be867edbc7bf2b65ca32ef8b37c61b0795abe7f85fcff1c79ee3ff798e3fe839fea1e7f88b9ee33f7a8e3fe939fea5e7f89b9ee3aff21cff95e7f8a39ee3cff21cff96e7f8bb3cc7ffe539fe309ee31fe339fe329ee30ff31cff19cff1a7f11cff1acff18f798ebf0bcff17fe139fe369ee36fd35007e86771ef81a1a2bbc3e0df842635a196773ff63233ceffe117db9a6e43158818102f807a150f2ca9f7d5f0876e43f6bd0cd3a1db50f81e7a980e857fbf24c11f9ff52ae837756a7d98de569fbf3c5929c8baac0fafff99de9058aa9b1d5abd6f92ccbfc2244aa2e9cdee9c9d5a610a6a53446285e383678b57be65fd2dd5508f4eadd5993ab5b4d2db5838f0f30e79e7f370e0bbfdd0f7ea667d9ba11e0adfc866dfa701f50f4abf3f60288ee44f69aa56acf7c7c99bf7e257aad32cc9510c55fc34b534c97224c53114c1f091be77f148dfd73cd2f7348ff4fd0c4c2606e6e5caef047e8b95b78b349666d1445fb0d8cb6638e84a759a25398aa1d648df7b164df4058bbdec913e9d6491666e488132167bc160aed7ab85a22cd3b4d8e2cf16dbf36d0c06f37fbdfc51d4df34fd45d13fe7cf7c7fb55cac16ca5aa13a24d3e9fcfcfba575b196d6c1585af74275a678c23c9219a715a844acb7c4391032844600000400000000b315003050200e8905234916a69262b30314800c81ac507e4a21e84992c310340600020c210410000001000040d80000df7505c7f5603e8196abc8bf0ad8e3427fbe04f8afddfaa31824f435fa1279de6954a1efabc6d41ef0626d38e18c4aa8504cc7599ce0e233c86e97a8d410885ef37ad9d6b1970e2749d487b13f7ec987adf11ee9bff960faa76bf1f668a4a71cd5e5acaa1bf78c4b4703aee7977e97bcd03d2268d4feec0b1b5ec1678adcbec416cd664734f9bdfe2fa5591f4827dbd8188a7ec25acb88465fbf91dbf7422b4725f6c576540a8d5bbccb0ee28571b0c29f21ad341c38b82eda13b36c2b1555387ed28ed9f27c383dd733789275a12db3b98439a1e0bdff81b81afb83edf1f67e76bf258cf8b195d747a6da3757b30f66b839e7133f6621c73b53343b8a1e5bc4862113fc47517faa68b8789f272588d6de4ed29403fcccfebf89ef9a20f8afca0a3f0b54300ef8e54a6890e78f87f2ae442be46314765a9c157d4fa3799327f0f95fb186527cc145961067504c8bee889ca9307aecd2a49f3f7cf8fe3cd7af01d4ebca05b41a6fff2e4e41eda34599954ce6b3b006319675571ea2632c46d1685d9de97e7296890354df5298cbc1418c789fc41927022fc4e4abe3bae7dce0daaf044dfb8f58f551f61309dd7c906ffa1773f8f7d77dff50f64d408a18fb4f6b3ef1a7587175ae9f0a7a3f0684a4ebbdf97565d9a681bd90e8f35ff0cf9d0bfe8800abde296db1adf5c97e451f9f6347e7575aade275ea9875a6b0d38f0e50f649db5dc773f15fef3e112d077eeebcf7585a16500109338f4bda9b2ebb1888efc464a6ea201f01b17a2bc8b154d9fe8588a9e139fb77856fe61ae997b3c520019985860431652726c0fbc9d32f9bed25ac1338f0c761f4008b8cf405af736b405b475c8f15a21b7a83811e231dee5ba727b66a75823351868ea3924c7087522dd771af9f739c2e8d701b250feef56d696dfe8c724a1700cf3b81192ac9b217fd2c7f404fe58676704fe9d12374fb1f24d4cbe9d42d6a02dadccb3c380d84dd29d06d93f460a693d6d30f2c623f3c82f836e9043f8b02653def702361c2d1fd9c00c59e93243f9a52c54bef4f2a804e64a6b7c93f9db4e0c7d437f90dc17e0d9b850c5ffc48e46bbc76b51a3e88bf3223e4f0f4206a78a8dc4e5058f19bc2da8ef08348927b7ef60fb11c572331418e48c19a8e3446980fa603b26ec1a1dabcf05a4e69e13ef1bb9afacc72d3f5c934b03695721154f52a3adb47b71ba842c0bca8efbc5b0e21f58bd97b0b3066c618d280e31820e83273906bcce2458df887d23e1eeea0305874e98122923e72e5610ccb3ad6865d6d21fc1503f3b771ae0b2e2d3830528715e7ff92da172b406949eb3fd700ea5a3784b103595608f1c49fc8a015e5cdbceb5faba9d1615564930e9766b2a2cf0c3afc546dc7854ad9361cf68e0cb8ca01e27c4b10a63117045d23948473b41dfc1e0ab54845d2cb12cb88542935f3f73a2fed3fea3ca931abbb0aa56513f07db498f9c5b90865f608d1bc3895fa653b477b685a4327336e4407afda2f29b12822503fc47ef2c1b5e5008b99be3e6fbcbb75cd21c24a847810fb4084f3c3420e5ace30e75b898f2b34cf390071c31a5458937c29b86b3308a021c6a829f0d4699ae272d74afaf9ceff32260271919adfcdaa02fc7b72fe5e06fdaee2f21a04a396eb3c3dc51f2ad7d5879a96371968251fb2d5df7e3300535a93e39adada02914a392273cdcd3129fa4d30e7c41072eeaa0f477391b7109875a28f0555b30098e3a67d6371f5890764465e15a16c34433ef1f371ab9eba14fcf2dc570878b78e79d0fb834120f7fa5f72c3f457e893064b95a1c0e86ec9de790af3f568b0ab05f66e9c814651a93b76b87d51a197c085093d1c8be7f789ce0cea052084af8c25d8a17da34c081285133d7e13ff465c55ccc9999870932ba7e9634e0e931493de8de126501bbb878801e7f4b12d2de2b4528316656bc02273ae9f1178ac0ac856d6681f65c0b855a04e27178ef63000aeff4bac86fc624d54a8355cd804444fc4b8f9110ae99a5180a5013bf3966d7269cb54647e4d31bed734c635e5019a96b43cf77c734b30a836bc8134ade3e6945dd620d3140955e517d4bbd45f7c07129e00e931b517dada55dd6312c90df88109ff91629d9270b0c02624194a2e4a162722c5e3d40ce3e642aebd9d740c38a1a5cd90227688b3c73243103b2a89b98866d538feb39c68f5f044fb7ad9ca3189b67f84ca81e9ad05cf4cc4df86d69d1af138391cc5d1e8dc9acda3440aa7e18dbb86e4b8123f632381f42723e5587bbec5c99392c5c5c6f2ca7b7fd9f7980df365d1b45eb7a9153bceedecceca9277814830a3a49a71441dba976a9c890e831d98077597c66848b65942b65ba415b0b1a1fdc58a3ac50a75c40a313bacb8b492df700e66098ee8156d77a60b96205a681942c5b84a0c9f012ae672206678a676d46ad2b1910480b3ea4ed11aab5eddff01a4b3ee8afc621b6b4b7809afcbb88f1ef3e8528053e3b36ef628ddbcf1ef1ad217f417436b8f9e9645ba196f8a6e89bc18375071bcfa5bb5085672eea6d6e693733642665a23679c4dc2740a8d83874c1b19b15c18d341eab05308ef388fad745c62c565a54396d68fccc7e20533c4b5f71334578e36762209cff0cc51d223508581aac0ec1b2903ebb619a5eb2c9d9b8c05fb753ff0033b015158fcc3e680bb51637884ba5c28e20733e929ea3d8fc64edd6af83ea54845a972aec25989c515dba8ee4cd36a21ffa90c4490dd00d5e792fba2d38d3fb0e5c0b44b0c51f55cd70982decabacb30665caab703b9b2641341fbad51d21c47166e8369c5efc6d22be892635d7254aad295a404a594463f986b60ec01d81b600f88bd00f6c06caffea909c9d80ce513456c8f60a1c4e851b12388539851bce1b8daa8663fb1a2e57c3d8ddd2984d394b303ae2df99eeb41989a02118ce4c69401f931ee891634fb8a36bf742fc5d6cc2ec3cac7f19d631dd3107978a4d249d768ba2c2a2a64386a9f1251443f897bf1a4ccf6974a093e79054995d83fcb42a412c05bccfbaa0341835a057fd280465967ea3b17720a637949d2ed9f04f2f966c9cea6bf22958dd7daf50273f80713b7569d7f78933f6b306bb62685196b5876a5a6f9a78a4b5b209b73584de498a3ee4a2a0267cfde1631901357156990481ca81feef4a934de55eb9850638740a83acd24d1d41e45ef34011cca8147f7abcc48746f9cb626cd823cc9c66c8b7400a7b151681810472d1e5f017c074abd42a550297a1aabcaf7e44522bf50adcfbad16c1c4b2e897894af7e24bed0290934783386b73e2af211924883c0231c0af5ad699f7a09b2213d783d8c75435c8cf2aae3530457d47ba4f39d59e012e23e1f5c91afef85fba2e39988fbe1127b1ae81275b7a1647946a88b29483b56f07e3d7fc45b73624136c9a914301422ed4451f06b003058dab28b988e272f2e1e96c3fdfc261a2f7786237d83e472464248203a55339b919c852e62408cc9542ad8ad8195461b6773cdb5c3c2925469100ba57571ae5844cfd4f0e43abf88c956be47c255d6bb028eca4571896621c48669dec3060b72e306ae4a8c08b6c1f1b11c527d42edb9b0c9b7a1f44d97740987ed05d2f1ae5e9b71c3f30b3434732480c31aa01d9fd636fd4021a284b2bd70af66f9a6833fc1619e1fd44f3f08248d90d5e94e4a6d9ee669c2a9c4aa284f3feda5635ad94303149d5597f00a6de60d80dd004b2c9c3a50be25914ff1cc14d49208e7309563ff033d0d36714fa98c23b983b77777ec8004ed9e67d974c0c6e4fdc2212a4e811d62406b41d05262908304ee1c9de39c486ff6ad3a62294d72da7a1bf75da8b9938b8e657724e97d13738c94a53587bb5654fce7e5decbc504bc97d9ca80ff483aa390a51b7b1585acadf1fcce14a43945ae31e4882ebac24bb9b37302fc8941a80ad99f52b28542e19255cf0ae69bac96e10fff649dc2ab8af051161fb4bf8a01231efa9405c2d7bca347528c3b59435921aa22d75d63d61d0b58863505c704916b838af52a2c082f88083a8815388b08a6b063688b6dfa2ff14ea1535f06e3b3d88932ae33e28ba4cfe3a2acd871e027e5419bba35b621b0331a1530e8abb334ed44fc4fb0a268affebd0cb5e973c0b1328415804e9685a8668f5337bc42844a70caf21db700c4e37a9d63d0f573c741ec5891530ef2105a5e162616c0d8213695adf490f8e272f3b5fadd7f09ee602d391b52b0bfbc84460e28190bc3ec124811de908941cc2559eaae0c780e9ce3c9655ce81153dd694b5b4268e16d569d3b75896a9a8b9bf8c7d7d6a122a5c9c0e043d259a8a44123132e98e8491075446f83129fa5e4c701fb94f6715978dbf5f1057be666cb8cf90c0206306bb12f8b26dd1d1c819e226ea7bd06287e372b6b694222fea86d90d7bae00449a37e9a9aa6a6b96136194d4693a94189d6abb42a27e3cfb9ba4ee374bc47dc7b2f4595ff3b7a68e7cfb5197167f2b343c90d01d05db18e852104555d3aaec132657c19eaa1fe111f0e56f2a6574a30a299389af9a5cd748056337b894a1ac8b31acdcada12f1044a6c413a157346e3782c9b8aa5ae03177f8b1e875c0bb577217e769bf0dba510ebff7b44469b9482404f609666befc40b818130fefd1a24e329e0dad7f914861d326c182187ed867cbee13887de41e7f32e8f1ee18f7020d19900262b5b191233e92d1e17ceee4e0e048ec31ba6771012ec0d804f741b1dc49981ecbd3b306dd005732e5da4e39b2de1413fc1d82556325e36723be39d8fff169bba7672240132dd9255f471184d367d5f14c88df53a687d11c0f87cb2fa0033d6fe1ad5c60ee89caff1653d1515e345dbe85433ee3742648de752907bf37fba489f00ab288270654d84d73d87dcaff49f9488ae067ee77605bfd8a5b6864a934b976d4628c4f92d6a1f3c31e4a092adde78553e88ab18d085feff5c2af801dc10ff6a79a7efb79023b99b1a076ca6fc09c15e04dc7528712d4c54e047b6424c1664c7572463f67a64fd4af8c7d081e569bd741b1b22fa2cd377a891ea39cc7a4909cb2694c02443cdd44ad9743dbd65bae06c84168f469638156c5682362f72904b297ae7595dab5ed9554660622192bbe66868b2034c6ee9b933383a4840b3c27d3a7d3f2f71b3753e48e19c3199d9c164308b74e7057012cb57414d5fb03b9326262c101a575d9f708699c08101e85273199397b1dcb893df12a246b15f885d4df2796c278829cf851f47bf23d898e40cc7ca8727b091105f3404272b06f9b7264b1f6a59c0fe5be267069a36cd35bea75ee8745d1f9bd60ee70feaa4375f488a3f126b3188d59aa67c1b9b5c85ccb05b52bce602cd2533d52b21c55a3ae476664ad30f0abf2d8e6af7b58dc76a53212a0b1fdd2eafe4dba9a68d796617a488ff974bc2c67bc9fed32929926a1416c8e0c5b9d11eeb408c8be85e70011241e138d9763f02f5c3d638852764cd490789398cb5885e26e9aeb8f45f472666e769602c363e61891a301b61daf4481a6603304de0a09e7f508bf4863da79080b418fc3a1582089d831ab2ff89a302fc10bb99acb51b5aaaa286c8361045cbf0bbaf7fb43d12265ea294808161d29dba2e2d59d1653ac1e7f7a6d889ece552584b20af38890235b1da8be5f3f1360804dc9de555c678a6b1fe4508f5f6b8e975e05233f8819886cc79bd74b8968934498c5ee06b21946700291be949618d9d86daeb6750d9c58d75daaa6c5685d6c5dcfddb37eab6d481940be330c375e983c9fa22f15a1c6dad02d0c1d6e26b0a8fed27a0e7cd4419e5a021d0f0d156abbbd8027b36b159592951b55e3980104a801f449f4a44864b2735c4b3d151950f3ee69abffe318d360e38af5ffea2f7ee197b9c5d16b138f7e965f98bf75326e321fa429cf7c24dc405284528d4a44e341bb8dfe60e2e848608c1b1b3ac3d26dc1294aabdb023d93cbb77874883b35c3b63942d17568b773a856c07f4064561c7953d570082a2e375270be431cac6e9e45145c1e16f7173fc4e96f2f115dfc784911e2dfe2d8c2e3fdb0df14bd53873df716004dbffc0eee993a44feb34b8703394f7f3435d959a0f0e9df50980a5d02406de4e8e905aa16c4074fc02f0377cd6e348aec5f06fc3f58ad90016695db6aebe5c5c423379dac4913dfe6f6242e36cd5d10fccca95ed2230e9392ab6c2e0a88423b924044fdd9b6b20dbb8f8e2a026f796656385bce1e1dedc15ce84435d9bbd3194b7919f8c09991210058451ebcee9e7c97ce1bc937e40a874e826c2fa0f286edf3a42e243df60974dd07fffa36aa28c11cad28116e9b1d54f2d4a911eaac6cabd17500a2fc2ad5ba5a88ae5001237ecacf4c1197212b5e7f662076c519d51e6e1b48c21d48f6108dfa0db88f928ac4218c50f1e7a50e17cb9da4551047e471bd111bcac85f50affa8b7a832467b072537b6566a0e27acfa76562b5cfc0b52886f1167f4d9cbf2ce83f6ee44fec1874ce422c949429971994d91390ea426eec6e6c3811c97d9d8b0ee80a3b6b8e5a120ab0f2184c7daf842747c665b21d4ec03ec16f163cdcb07dfe011c8c55a28870b77b83875aed51f06abfe1e65aa1988212d49ba1682b151482069e5f1221ee16f4903cf407ce6d8014f117058740906a029821681f45ee5889699e776a415235ad2fd1f02c81108bd3356adfd4667e47cd3b8c09a763260c667689deabd93a4e3ffa7b3064aac9b8a476de082c4b7737fd73cda423d67fe2b6e0ce714cb030b422a8d028f0313898f6216210c6a1b1a06220d8b59433686a81f3665ccf8809b8832e2803346a493e0d908e2e5a21ac63398820afc004b8c61cf341e2a122f8c7ac3503c8261fe6344176686ca7bfeebf9967a63293a933b30049f8e2777be617209819fed3ef741b5805c884c01933aa30752926da9d074aa20081560b9d69fc780565e66b9163aaac8430178cc127e0d09b1fe2efadbaf7a6068d342852e7bd754b5ac9b1845d1e59df7c1b8128b04d2f8219a252458250b477029fefbaebad45d5d29e0dd98750d4fdc9b6919c6ccb03ec84c6f71b5570ad614637141d24ba0c351069f92668e5cec5b9df77c147af044d0688d6b921270557b900fce6edd424016f1232be0ee34b7e9c07c30f15539e3b36989ee661591c0ad0ec0b010a43af14e8668ac6cf7fb786729a00773916fb97323e2f41a97c9639409e03eb5c59d7da552864e2365aec4fb55cfa62ece1d7b87f059b46dfcb206719ac79ff400fbe38c86e2db303198ec7ead6e21482de175b3d9b4c3472a8ceb1ffec7c9983f8bfb2720b8c907575f5f44f56e2ba168fb6e387eb5dbafeb0b2ef8612d092589193e9a84bc00422dd63f318132d2c10f3d0ae3a346286b38f609db5bd918921a577047e65d13ba4ebebb336488d8d59657340095d344ad9248749c4d258d3298de03f0444d14d8e7691fa0ad4d8a6c751c0783e5bb81b4cf14f928b429ecc6ba597b5c3b78c9f1aa01deb9f40d7c270593e715a260064824b72210fb51c0e029396c79d3b44b520ec55c42200d98b71b5c8171f7796ad8f5d838edee0a944b656603825c26c11ebddd8194d9d7613996f02873762ed7cf173754ad8e1eae94c35b9ec091ccc69a50349735f3124eba5ec3ebff373fbf3163f4727dbc14520244a07c5ef8dfde6f3f60280268e2bd6b49c04794f59397d02dd2db58889f6922f4e8f87ab6f0ea629ad622c068cfe6c18a4505da41c6990e29ce80852a49d299f1d364c08845ee30e6e24df0e5428b015854c518554a4262852908a28048a0aa2223549011860220b46c69ac26dec668b2e63f52487b0337a7495084514924205498142a4a046285090142848451402450551919aa4a0f0a866a91422e9b191593ad9a0cb50e720a68de890a620db7967449f9a225067c311656b29542c47541f2b2dbffc7831a2f64831fe644481e57b51043efe1851a3a478f4487844c73a857239dbf2739e2173011923ba17af7c1ebac367b714166d726a24964e66154c39efab11dde9ea6dd94447d487b4deb6f9c588165c1db7a1e68e68cab2e31625d988da60396eb35f47f4c3cc71db37ce88d6dc1db7840246d405bfe3f65a8549f9316f3dab46f4e4ae73441c248122e0cfa17e39924a8788ba4ee1fff0879b721337c84ddc2c377193dcc0cda24f562da4e90eb17626419bba2f46b4e661b47539e74b8fd80bb719b863d88b3379874d77fb34beb8b1cfbd073e6b83ff651d21f70c7d7e35bdcad0d01227a7d95c20c4d0fbf4db2921016ea78ff3572a334f3aed40284e02e292bcc836fb26fda51d55f60801fc653aefa14280274ef75d2894c2fbb4dd534334dc4e9ff3554ae6cf14ed42681c12e422bcc866f60dbd4b3b54f60801f0655adea142004f9cf6b150a8c2fb743b534369dc4e97f3af54e69e34c545d65c04ec20bc986df64dfa4b3b56ec1102e8cb349ea142004e9cf6bb5088c2f7693ba6866adc4e7723223407861597823ff22c217e2e2f28b8927b0760a0d12c66e947d0a54dc0699027d4c366dcab8504240ecab36049ea2fe1088ff720cc6bffda56e5a188352bcf9d8017d609213c166c3e5c3e42b1e10980dc7066500b17037e60ea9aba703ec0d9f0d324236c58536fc5192535834fb591179a806bcf66c611765aec75b770bd10187bb2e7ed09f4f2476b2bab21adad82349229826cfe3e3049a13d2f355aa5be58b85398089e3c37528283f4a0148d2cf3941787251bd43e24344a68cce8de1e8e757e0a46c26e960d6417810d55ed97695b224429b599add2817443d001c23af60773e507b3fa3d9db2bf56f5041d3704d86b47f3caa3b78730ab3f945c8dcee8d28388d0bd8929dd500b092f2454b85001ae47f7c69387775ede7979e4e1c9131381ee158ce9822e37d06c48ea1e47af1124d2d58c3c71703cb74da73610407d2247cb0de841ab4dd87350f686b70f8efae704138363fd08926293431ac1918e58c3c4a85c1ac7c87abc4bfd1f36740cf383719f473339bb8c91573d24ff060684aa88e67e91304d028076c628e33887a3dd92e6e80db6b6dcdcb86dabf6655608570d6ec080b63669dff1bc714acc7eaa1538220771113eefccdd656888227d75bea0a8569dcf27aa56e70b5cfd55fdbaa7028d1f65ba6a38563fab6bbb1dd723686499f8c977da56abeef2aba7354cc108db7c73a362991b480aa5d171fa9fac13bd53d62939fb3a443f9fccca75382a4fbc6e8a0f50a410a9000419581883ae749a4dcbdbf3d52bb81197c9060fd0f780e5332bebd0ae0a486d26151710c95ee888e69c686d2327fda44401499813eb2169db3202283563d1fd88b250f102c4a781408c7b0554610ddff5c2ec0568b3599436e38f7d99968b00dba2d10560939923b12a0fcf7a7fb859307a03c2a4c8ce0092f2883fec47e025bb593f9f0f1276fdf07a288a3ec1644c15d9084602ae5350f7f3fa18a79419d646ea417d6b6346843395fb8ccd2c08b04a4109c83e4c11a4bc78b620d604182ced2ee5ceac8f1e3607a4c2926a1110795e684f6642087d90983844468d0c9c21eef134d800812b19c3f1fd48112bba1342478248bc4b4035dc99233be480efb59558736094ed2f8a45f6698b28e5e5b705b96603e32023b11f7ce75df196fd803041b2b30049290b730434f6f56073f95307579b735545d43fc4aa89f06fa1c3a2e8aec341a020fcc8d254b125d843060119e6159086ad02f482ed05683353342de39e7d0d2d1619b6a5a70bc0a69ba550a3f2193045a5a0d201001ac9c9524476444b474bd2c5cc12c15a28282b2de921d3232a898e50887efc33ce5c787e02c3d84b114c451e063682d0c53c3c869d4d25b80377b01b96ea18d2271aa88a865e4479f7076ea114b89bc116d709d80ba2e3bf9bb85d42c69a2b2b681165aea06e5a5f3b3f9e31240108c490141384a108703ca01b8890971fd96905b10d7cd642246e5fd6657db0582de5e08807244806d6d3096ef9e5a1ae4d96d0c3800a99eaa1d8f469ed610273e3f7302e9b3009231f98fb0e17579dd33f81592f044bbb08d325c89927edf0118953e0e94e205685e0836b03424844147669f741b0de35d96de80140ac2743b34548685c60adde52f07855cc706ea7591574c749e1d5bc7c05553c9e6af8b1a00c5858532177331350b0bd6bdf31a89e50658d1ac7812481d61c1557d01942478aac63702860b09dbd1a97900f6318992471e937949645fc4524d07100b5ddc71582fe850a2ee0c3a843a231d50670f338969d2c49eb0ffc56c099a6464773531d385ea384a3ca81dc829fa3d511095cfa657983bbbb02969a3881dcdb7317642b511f3fa21d462e1401d4e71be1acd0cb7d0bf6a5accf6dba557d9d26beb7476e21539cea364b93f9198fd67164195440b25f94c24862d6497ee3158eadca8b445cee4fd3b5dcd9ca8530854b8097c60aa03970db35bd3ea1e165da0330e6017657a853e32c123423ab4d2810bc2151a9f24c22a7cc62f40dae86065ae2c71639a522b4955b26b5e97d9cb732a6eefc25dc4abfbf2baef2f68a3541ca046820e88a8097c2af989932b912baa553e2ce0bc131c2334474b8478a730d5352b3b7325a8c5bb7b91ea7d29ea6aca3c11be762274005162f3f58db461ac3ea523068af26193eceabceed4780a4610a256071fb0c1f40142e7fb9a867cabce1a5e860d1273e25f48a50e01765f34b57480e7023b1d4cc43a6d8b564d23ba6a66130418ea2e311bc9557c2a5fa9b0e211ae83058d9fedfa28adea97f5f407a7a307961f3d140a0e9fd5f0d317e937be788e21a7f76c56a862b6009ea0582b50ada0f9f44e633745f47c7a40380d8fc6769b65993502807af40dc537864c4189495badccfcbe85fa10640cba4e7af2835c018692389ab81d90cf4675faa869e038784b35dbab0036c76092939bcd7a972c402035776bcac72660a3200aba424647cc28fd6e7f2afecda29ba7c86def12efd10bbc7287de449a75e4d5492f3e5d2b09381d9a5dc6cf1417eab410c1368400932b79a5307be34c545c5ee25999e5348298208b769193c9e97ef1c43537fa40df47dfd737a6fc46594761262373c75f8a61d03b0a6f6be6e86f890b39fb1826231f1b082086d744904b90f2eb3b0ee80a75273a5a30c6d1da6ea7dc682080eb516b7a501718288b178e1771e99cf776feb62d0b1e5b27d5a8a56bd11a7f27b1aa36dd1cc0b94c5b8a19819b800821c3dc807dfdc5f1244b65c1baa968704492c84bb869eaf28f1b5a77b2fa8554fe965d7bc309037b9f09601c53feeba00111ba637626113b1a4422c492016cf87e5e261e1d4c0060e9baa6b6822c56da09aac47e458757d0766732ae8a54ad7564261c4e4e442b55e7d4f5adcc0f9e2ee2dc12f0443b964ad447cd1b0bb76385c7fa0466e21839135b64503f157010c1c8817a4dca256bbaf4209b5b10bc2e048cd88373e703cc35398e7887f8d432a36d4d924ac16df4c511d33d0cb5b98b7c6f45e7423877b115c46f9aaffefc14edd874d67470289a19a1a0d64294e8600abd03eaa45d555cba37408b0d0541bb6a2a442bea015479925ec6c59d1809d929c9b03fc71c98a5c3d5160f0d757fcfdaf5e1fd81e8c22e3f6c0de5b0d99ffac383d64f0b4f782ce4c54f877cfdd3ab9c2f7025ab54b20ab4f47ec4b694a2e52dcda5b4e3edb2d17a75684e287b806b8ae02639e592ea63a5f808aa4c1a3ab967939ee6cab181c179d6ffda1f0c9440d3a4acb712b9b38bb2645bf614546054900f0f081fe8948f015517a54e45bc000ec320911c3b4f6c4be9f7f8dec15fbc68468078c7d83fdb3d3c7be31dbd9999a6f7a308dc78d60464131d3894c999355c16642c5c8b90fdab88192826083a62281094eef6ae16ade2553a5eefee6d46b2b8136b0b9a099b308c06e412f452e8e8f243bce2a9b5a7e6a7abeb1cfec64859810ccd628390fda002d79f0884606bcd679f46cccb2608954d90bc44a5f2fb3b4bb9b23a75afffb94e1f57f376abe3f1a07faad07c8b135644a596569ed9185ba551feee47503b47173c53254aab6640f19daecb9333e05f01116ceadbcc98d831d76df585393405c6a3850517314e650ec96e0eb2b6107d2c17e055bb5130265fec3a88d93af2eca523b6180a1cf822332a63896817c37d725348681e3687df326322164dcf9cc31a434d28dc2a257f7c1a80475884de8a0645030a37c33201787a2c58f9ff01b289c1745703768171b941db84e69944f9cd30274c4081b1ebbfd6b0caf11db40e1dea3a46b29b91b89e9bc43598644a8914108eab77151d09f501689e69afb935b5d39983b56da94638d21594cdb46926101d8443c18eb9130600e624668045026ef36a9e10329220920baa9e5c40c0b50b73a751a5572d4bc2f16110cad7a932ce9a8acc7f829a521062078397705dc8b4d4fd53385c88ea8921b37d52fad051b7b90c692a900c2440d073652c917db38690cac8cdf062a4b07a32b9739b43905815a8e7dc519c440b5368cc5754ee92528d959d45f857e46a83a4b284bfba607202dd2969e040957804be89334ace073248bd51b0b3096497d3c9a75c494c13cd5edeea733cf04839129cc70e83e478d8b5e7a3ae2aeb38c9c80517a0624da7ebee87c7adacd458d0870672fb7ae8041929304d576e3d599c3279e9d44120dcf4c1d1087e317a8ff3cb1e152e33dd8dd345b0dc838049ae3bd22e783fa9064bcb5fdb83eac77379614584c032e2a6b3444c3a5a9c2cc32eb49b3b12886ec8ffd76f0ae801175abd134d20cee3d53bfee9334a690ff615a5c6d5954d1618343224802da878ec9068b732062bd7f095025f59d045c00a8e95afbfaf23b70e795314b50330988743bdc5259290e516dd28cbc600441442862b6fbb7617f0822b0b206ffbd1366307f031096f1d1853e1eeea681eb0b32d8ac073d620f50b92b3dbb136bbba9ab4ca3261329c677c97a48e7cb0f5152654c2feb8c9bdc0ba850063a98f19ad54361efbbe9571083f5e8bcfe38167be1757b58d79876544d731c441069e04110c8ec5fe6d282eb8cfffcc20b954adfd58ceccb8160cc00c7415274fe34237e4200a4f1c43f4150aa6b43b3d9e2c21cd91144a694985a4c18f773668a55b1cbebf127670f0132f105078ba89d5e8b3ca3440a2d231d3f5ea7156a9235ab053db97c633218fb2fbd6b32672b02f9808ed34445798089d564387886c1712197fe05ce49238d3401fe0b11e753813e7de3bf4db84b1c742f6463463dc40e50929d0c50ef4e56ed34b32fbda10b37c36115a411b27371a58cf052b4349f4f65cc631ecbd555bce7ccf2b55a8158217ba3b8181463609866cdfe3a9b001bf883dedc8296745097882477685df30539ce670a050baf5edfb6c435a4c8f22bfeacc3663df56e1f5d33e213cd520b06f06c63711a1aef78b326bd80469c0a6f6194adb458c789788f075a2303b5d152cd8e42e68352922ae42965640006256940036c52786e4f827bc6ac4a83728ce224121c2a3fb9bcf0643f2b961f80214fc000f94c719d0134d966ed056970f067a24f18e3bae91d0960f704851d5c523428ef7a795d59104230ba9a3189040f7314bd196625bebaa6084cbde3d64224570894f8e96b71acc663dd37e15f110622229f338e6ef14d1f2a22a6bc8fe30efffbc8fa9f26b2258b1bac08e181415cf4ef20162892f8c5a41c0afe0dae28cb182802decd6083ff43e7772f247664e704f9ae63111100aa86225418e2648209373e4853504c857aab504ad69207f7bcb89ae605dc662a773fe8fed26db885d15dfb7621f44316b0085de37d4293108c8cec33ea723116063fd4299a0f1a22be5e758b2a9a2d755e62797f4a16c5a3913d65464641c140cc43663fdd3086068edd4158e2c8d173294b11bf1243729c2146734817131f202d0cda988930c777e503b602f5598a9e618965184fef6ad2a77c1aad3de767bdb27701de2f5999e3bec664c5f624dc0ba1dc7f8acd8efc027dbe416b9ffee2781e4944f9f03e031a159b5d721772aa89c529741540fdc159f0d31b52dbc28f0b096c987e5fc06f59f4c5e4c729a64547af412fb493d330a84244a2d8a3cd5e9bcf3903809cbdd682b04e5d879e937aef28fe45b99f3df91c339c4693f02d3f0b862d664e2b5409098753dbf356a8b2470d678e7e581376e5be0c7b4a7e15970eff47a1a3515c1a68f405c4d0600212f884d6009c8359b3f4188a0bde38eee3c10c7dc3dc977a7d9cb938b7c2c13ef17d01ac1382e704731200ef035c94a9db3bbf98616efce3c17ba6bef57292f37b49334204f7b2990f9b6bdc1fb44e048dc20ec23350886b7d94c19b02f0b22fe02e2dfb85a185edefa51eda6deb61e4b762262aa95b8248eeb8803bd1db1e2baad7925769e8bd1f7a67a16178191589a6250051a0584cc04182ba1c3c9f08cefd4c2f46661dceea3dc1fc610066655826205ec3bc12321c0463426ac1ce49ff937456641d8cd025c35f2c50bac672e27eb044d9c10a03b916f14f2ebdb480af8a64619977e7119a12ca0e03f5b2533f9e7332a2c9aed9301fbb6f158066eb78a4b730fd96f7d734775278feeccdfaa33763e0f23f596801154dc0e1dfe691654d3a3077bf41288f97319b1d8d8e387f18c489b2e234d928dec060e43831789f68aeff52fa40a41e90d5cc4b7359cdefc979ba797cc20ae6a034e7417a0d40da9146b6e4b2241860c711d73cba919c9eae03e9e323133023c1c0925cabb50a09254a9a6ff9b6936b65456c6e8c45e6f2ee24180d6247188cba721c538d2f8020e17397d33245bfcdb89feac88e7abde00985ead20902861aeca46f1b3d9ebc4edbe66866fa958f87a3ee6015dc47a0e2bca6f028d57e2c028af1b86a194c15f38616bb6d2b6f466ad855caad4087dfa6d0af3645eb639caea73edfd1c8dcc24d0e6aa91bdaa5803e7ee300e05ddd3ebfe154033edac9788651a5fa8314b770fe0edb69478672b255f7b5ced39f6301c44215e838b6862ff7195199efd7feb4110e57b54159f36389e1bd51b5aed352b5ffdd97f23b49d640d6e386f6757627f41ff6418bd9fb21d7b879fecdec11547a4acdde1cdfec5d58ef10fc546ec9f543033f8418043353ffa24ae9fdec9f4ed6cb945d0c1977c323c9666f900e58e0ca85170f61980fc95027f32f14c6729be1408e6fcd0ffec10a1e96b8a0e5e37b394183bc25bc38c39e6ffd609c9418c656dfeb1184d1dfe4885f61374900cabe31967f203cfa7a913e3207f833b5107360eebe85940b7d86b9f8e0dbd1f7ebc08d8b018d00475fd396ed3b5ede1e47678d44ce556a7844f8281004e151f548ddf46f138335b10f9101e65c3021644f692162ea103d65889416a2a60f11528648d4213a5a3f81559b07566491a6296fe1f1d0912bfcfe7a4f83304ff26d217c06a5ba4ba50170f2d54814641c774b006390cf8441eda3e476e18861300dd91f2406f72c31ec6a100f31cefdc08aa2180d220a2c48b64dc8fca5754aa6f9d369a16c131604de87f743bb3e868905d4a912dde7e1b71e272650cb3890abcb4916d7a3acae90885393c05527c36f4d443722f9cc64f4b2c4e015b9f7aecf9539186233a1f704be0fde3a2d8bfb573a7a4d1aca9cf34b4463cbd042ad8d109e38ee3f07518d45f35ad9687f701ebdf04cb2898b00203e720e76003c671d2d2beb4733a9185886895ad50d738cc31251d83ded90c108cb7f8f9ecef84306d777dd21a80b629621b3c09c07538cec8d38444d1fa2240dd1a843f484214a52889a3cc443eb27b07af7c25a2c5359e72e2e06da155cfb3d2414ed44640af5334542c5ebbb1569fab73f5aa41f6ffeed4512c8f6688c244d27a6cda757f6a0c445f868e9e9feaf1a4980fe2737521dda7c72a481af94fcafc14d6a3d52830e697b467658c3e89016f64809464d49ea7b551351238786e6a661999b45d195a73a42a6d13329695e20d24a3da4ceec515ce274948373bbea34601fbbcd0dc1732919bc7c6c24296f32eaf33707ab7ec5e2ce54f571ab9c5f47864d1f0dabb6858f8fcddab6541dc2b0061f9d4a795bc64048a0f578a9c8242f843a18f66bbd1faabc2b004f5e86e3eddf83182099cc5bc5b98d9a76543009580797aaa8182f224b844f97d922c7bb8238f4026f188326f7571c7b0c208365de0f324d982cc0b07f98780dde3d419317ebb414db7a240c1d260eafa6b80040514d252293401bf4ce0e06d8b05e66bcc4ec3d807fcf2bbc8670e1977accf511c10ec6a06d71fc137aaab31c1b326f499fe68edcc2271bd28b79cf852678452336118a543ef6a28752983f336f0337e48552bf5093750d9c197ee266e31ca32763ed671a30b4971c77fa63ce34dfda3ce724b56e00f82c2d998d972f33588e6a6f33b071e153a352c92e40950609951f90ab4616203f7a666927aba8bca0619a1764273f11fb5d9b7550d386426ce958a11186a8a5b382361c628b4eed730e5637430291f7034522daecb1079f60be12f4ba12cf4a6acb5382aaa4b18e579725c1e20b12960c00abafae64f93aa38ede507ba06725412462fcf3cb57c945dbaa9f4a784806fc94c0b993afaa6c29a9a2f9e31b2910f3c891c4282667126cc47c67510e8e089c540200f5a867ea11e37967b69ac596cc8419d7791d539869cdf5236b4db37d4d4397ab20de06bf474412b30db2cebd2a2396555792ee2450f804d7f4cb426e103dbdee05f52f468aa224a7f79ca3700a0334378401913b7fc0f420986e82ab0af2863c4cf4098a57c9e1508b435ec5aabb3ac88965529409686f5cd88e895d3145a977628042deab2099e1ce63b56d68a9ec2b99cece43d4b9b382af3cc08f53d761f9dbe06e8e6078a28ae1f38b160f161857430c775ce42084c4971522697f04230d9952d8fcec50433d8f60b56eef9edfe246fed3011a3764aeeb9d397f4502122ce1bd003ea8c805024a656453d61d41272c98701f941bf9a56e00587f82d0481ff4830c16daf7264d14e0fa4b4103109edea0083ea01d48a5148903ae45d8de0f204dde0fed7a74077d3fd33ef21beeb2557c10b787453a61886b0ee6f3cba508a422752c505431ac17e3f0000187d76312bcaeffe50d0ff8e26cecbf1b9e2f2303eaa1b4e549eb9ec8a9de3a28c2cd975e23ebcc67221905c831ebb54b1c70cdbc9f2bb2e7d569d327c7f5d54bf4e01e816028d861e79c9192f11d6eaa736a8cff4bbdd20007d374aa0c384bc3017cbbf76b7d0e08e364a0577c4e68c66bb93995daa09d77d53c19c754064361cbffc9cb97b5afc0a921cc5305e02fb2af79c4fc7ead494aa17aa04f70190b6f8a11827b563540229f6ce551f3cbc687904c2c0cc639f2eeb494fef040dd427ba25ad29ebf327b1568b16ca1e1a022889051f1fa71327239c51cb4841cb38c09763b018a454655e714d82fb1479c334fb6ec513e4513d3ffc466ea01ba93a8db7a2604fe20a7236d0c2642a425295981900861a1c12d24e2cfaf8c06eb1676d153838e413a86ca559ce73d6e7206e87b74f01d8b5cef29bb6ca8c6d908a63f0e47c0bbe76c2cec94ee0fc6df0853b78e3f757d1300fbe7107a05e0ced187eb7ce7cff1732fa97e7b598f288bfe81ecd9932a33eebca4e594dd38b24bf65865a2d860f065caa22f7026210f64787ac2103ea33953d0110b5a94c6bad556cd01910a32726841db830c51bb2f5857e0f7d24a72bbb265509bd657884a2bb6ab8f169efbe5405de543362ce1acf2a448601ba85cd16dfb727a8a0eb75327bb1bb4315a46ca7de35120e3158419038d0f18cf9e9a60c3243a5b98c9ec37421cbe1ca4336054061142aca50843ab13da47dc46e3d0195e0a3a183fad0f3d4c7cb50a7e72131bfef22f7f3e516d99d61f867f4170b3396cd92d5f772b3777186d185db6ab6808687ef64e8b362b4daf5316b520371e3e4ec204a0de1e59697a02c130536eb70c294db7f2c98dbbc183a0001c4a4dbb230e5ff7f3ef0087c62d6ea65dfa1dc080eb65e8b63762f6b7674b5e4753ec1cfaa2fb567ff5175375c0f9790cb8ad6bb8f499613362335d98b0589e85676a10570d5074ca19007462cb0014e04e2cf7e9796b233c08f5e800344985db6a781ec1399f05407407c0eceecdaefd29fe9dce7f61451b877366067b827538a24e2cc61ac5e331340f47ed883423136530d655445f3f86ee2ad594cbc94f2938c562db58ca0818756b281567ec162c671b696056d89ba001da86001adfac6ce9803ac513f7b155e064a7533eb6ea1cf55248a9fa5f4331c94834e8a2b3f1c4a066e769d99a2e652b8465a483bcbc177d08b30e4fa54484a0b3ff3c5090edd1bf534075000b4b5922ab038dd75dd1fe7c48e84466ad19a9e57f4d696cf1fb7ca016e380106459ffdb6723ae8c3dd47066c26cfbbc6ae65224e2b44e185af683dfa992efb55f8eb5cb3b60d0790f044ed3619d53701c9a9a3a6b531434719d04573f3ba090f49317f04328508501a0753f6757e4f88ee6e237d5499be20b52d70402ea4ba5006ac1ebc8662dfadc95bcefbaf8be381ecd3b56ba9289b2b62095d41b4b8450df54ec2ff031e9a979d3d4b387019cdeeac10a922a18993eb2eaa0ea0949c63036d445c021d6b077fbe9716dc55a8b27b8136c939eba05fe6eb1031bc0f8a136d78c724f80aa8b3b3577020485d51fd0cb1321575adc89b903afb6c4eea991ba7dd0353e75341fca813a447455d066534e9a991838d454f0bb729bf3cefb1ba3334cc82db0548c99cd460dec66211192e3a7730d4de325da9274800e8473b3a4f772ea84f4e4e628ab81aa079750ade7c2c6d5b208951358ab290f500402578db2210a19b0d64816a248026a1a6443141630c1dbafc61a5c9fdbfd2c04357c425a28d8a2835b359dec9b030816e04d3ea73e01414abda2c0d50e029baf0e31a04a09b3589c6e4902965ff6b5077ec3164627db6edde9123610b184764171cb45f21604d4ea713f8c368046f79c3835004001ce9f99d808b4fdd926bcd90145f73d7f2e24635e8c1804b445d98e435ca16491098665d15f008d611357613433978fb9f20afda6e7af28db71252f6fdc61845847089db5f033b0b5bc1089776f8de2c3adc510e692e6516a3b44c27f07c1598b8a08cc69361aa27d414182a6e0457361d4e208d4dc4db359a5b63d31930468a4a076d2c1dcd869d4f22f6a6e4af10b50c5615b7a834d5667d6dadf55e9496f01a972af92628b4adcc0113a2c46cefc38903a75bfa918dd14af2f42d746186d5839f11b5ba46fb5bc0034c8a70595b6d8730e9d9f168e6af48e7a4531e21875413c36510e12ab168cb4f4176c5bb696581dd2e6121c3d5f22997431d11d8907a7df9b876084875ca20b14992aa8a2d6e098af169c12799a91a171b66dc8c62e679bd3f6ec7898b9a2f22a071c4f93433e501ce06d8ea0e011ecf7ff5c705007cc04ed270fe6c36b9eeb9aceee3fd97c1e669dc923aec0798ebda077ee2e944b74fff903e847cca5279b53c38c3202cb24cc4615e06bc1ac1bff720a9841b0df4cbf5cf9f775cd97014c5f897ad9b4f13d8a9735e95e6e52bbbc413bf7373f5dc6b20e2dd965c1dba8ad7583bdb92cc286a4e16ba3cb48bdc315fc1ad99d0dc45c5ef8a6d2a2b49191ec297676102159f42449d668ba6a3cd401701795491ea5abff4ff212a52af343953dc18716ef51dab3d05f04dc611da68b845bc1b76d446b0e6344caf06a8eb1b6861db0c77ccb7ab48bdc8ec93b8a492734f18c7fecb8ef185b782e1e6f1a5e14642cd6a8731dd29fa7ae8bed4f5158c85a20945d262363243e0d397667b00a78393f8b931cb8381f764dd6f135b36d4e4861f9613709a668513c5216ffc8f9cb9f18393250e558deed51c1d9e875418bd08ce7ce6b4f61b68e909231eef748d3b4b3a0af226436c83c1e16c07c591b019c2e43ba81c949991e2511c2eee93ecc13ca960028697ca4b1684de98ecf0441c49c5aee2a8182cfd068a03ef73866d5de82cd3fef3581352a4cf9932a26c32e66ea5231f09cd6ab653eb8bb08c9cefb6723740d1ca2ae65760bf30793e0e54119068e3178b68049cdfd278c8640fb60b0055fe814a5fc05312ce833670136d50bf5847364213fc5059ba8361c2ec0f559e26e0703da060586dc7495154ee42764c48fd95fd37d9ee61ce900407a17eeb1ce49eb86a475f0788140a41d08ebafb7ff3e6ad568a00257cb536c31da0b2cdd631cb75dbc48637095bcfca1b80cbd544ea16c2ed896ff2b679235f2755afe9f4da1ed266c50a426f1211f75e5bbb77c9dbd982ef2b7fc6263bbbf2a767ba2315392e11ee1169c4ff3ea8e920971824c73edbea3875fd565a617cca5bf1a0c57bbfeb72cf5c6a8dd866129f54e8422289e7e314bbdce31ed966034bd2b8da27f106818d32bdd29daea807e75bd32d518320f3848c9c432db4e4ebb4f0e2e828a39b13fb463a3835bc2aa0daf44e76a791c13b04110ea5e9e5db9687037207d495c3da0b6d94e36234521df055e548f4b17ce65e369a181c4be306b9150e9cb66b491d9b3c419e410ac0d580be68d8410a6ccf6f53482181fadc379797c565959a8eee30aee1738f107f0134a2e84f422cc26ad203a14b6a2794130e83a13b9349358a3be0d9eec0d24ac22f77d60e75928ba3e6580844d8efc10b36243cb2e9a8327d7ebe8c4133b1c6c239e97d7b9a7b044f4590c527ec400c5400d787c280828c0588e0e842a899989cd66b0e3b99dc79f0dbebceb56fa9327ba7c02f2ef8710ca7cb703299f5173e6a5913f3fa174220a616424cd456b83a5a24c2c2e850334a67f7b910f7c90bd2b5e32521bde202c039fec2951d5536571124381902347cf6021180e620dd58e121500fca430842b176b016f85daa04cbd8d48ba1f666784761d9828d3cfa4b215f878712e8028dfdf4ab117b878532ec020db9f91ba05a45a87097a389ea2a2d91b278733854bf820d99992ee22479853c60a42ed1a16862ba55f7e2ba05c8326f5933d7880c66c17817c76664ad91b5f25ea76b5453778a9ddef925283698fdffb8dbb7a50eef7e7dcf50374df2db14f6f3331a0b894ed74a3708725c616337bae7a53eb2595eb032f7fadb4b8a7aa0a5774a59159fda33eebcbfaa80fea3703198270853188c0c00132b0402812221390d5d331d0d2eafbb176c75a36aded65432b5546c34bc4e21caebba01c92e2139085262d3f43e7cbb3a68bed0dc11088472e7014d25a4a87288820c3d85ec3563b77762536ecdba90cd9f401b3c657320dc2202b7c538de059ab01a859dd939cac9d3943d2c4f5b735cf57a99b353e7d23722250e44a17f93addfad2085b71a4391645439c8297f05dbebfa1e4e62a4d51e78d795fd444bb94920e3547781710b9e11cc8f4e91e01aeea78b423be38c1f5683c28ddf343e168ca0eb5af73f239188ce168ec9bb31e3d7577ee01f5d2020dd9baf2005df819928581287514defdcd66551440ccc9a351a6aa242a7d5e7265aa8d660ea59b91264d5042762b9a5d88830e9b6b86a7e8aa89a9aa926b423dc689d2d65a81686c3e2b874067ca1481f8480d5ddce137cc73ce8ae03e2a442b4d09431056acb617db39bbe2e470d0cd270db06147420f31b8447a94c5558770f441bbac798ce87c6e07f9c4ce0793df0640c5764a8e6154a970ff125274d449daae10b519f713ec587b23d33b06a5c0a31822084843da6c729fcf5b62f186d73bffd79851030d7e02a3de2d36e603a305f6f310824a18906647b77c246180850ef6be977f3bf60ee32d20de226f83631d2a9fd2afe7e138b1c3a23d80f020e2698fa479a17a7224497bc29181d24d52a3c6010b60ccb788f1b6e276e7a9c0eb177112addc90c96febf2751db390954613709fdb3de0fbab0e1502da3bfe234ce5b93ed23c621325ca8b80177e736b2a287888dbae51718b80e67775d49824e58129a865b273cf8eff22024f870947320e08a406e673b9b83ba927f06375fa5d68d04baa9def56e76f09c9fe7cebc3341390e059eafb8fb667874692293ac15e6c60554e131ede3b33fb69b1d7693badad1ac2b5fc45c65d1cf49cda293ced6381839d697813a98a36dd581fd488033b13e5063dec09f01111c150f867e9a3d44303f48548159b91a06f82d22a64a9a1ae004957e5a52b5902cd180b51a6223abe5d95356e53b1100e0371c554835713a208263d746c2695a3478f526be97f8293629ae5f22b1702773ef5ddacf2da16df40b61d03f5cb6a815c138a566d6703fd1ab8724f317f8b609d66ec0ba53675e961f9e4a8253873f87176189d26a453ff757c3047ecd54a5075ceba72e2fc8dbff1bf5c33644008d1f2e95c3de28dea878cdc132211114cb763ff89cacdcb77f604bb246e8b7517ac976356f3c4fbbf042128a91a4ba1b6bcaf671a6021344d09539a33d8f1602540639b34ff42c766501786f9521a00a0f3de1f71b9d1754a22b87e02a3b25f76302e38e2de178e6ba302492a24fd54d911de4dd3a14217dd3791aa25a7c8fc4fb92e9a1d956d1778524d9954065ad085a504adcb6f2e93c751805c5ef9abb4529f11dd16757d79c760338bb4ca715389ed551bbc1f8606288cdb2628efcb1c7d51bf3e506e4a08f4cb7f1b1b0e3b14f54bf9177b511c90d201653eb425952130b7f16ffa0455ff46bb18cc08ba730284bab41b514aec2308620cddcffd60de1cfde3c890c20e60b93de643bba6275d54daeebf75db704a0482af7301b266a60387d97bde38413b16845ee94f09cf88cb5c86b1607248095695aa969a84c7f0c3e2f66ab96d104bba5272065d5bfc75fb8adceaea116a49344c53a11b7911fa9e07c32769e994bcaa73c1ea04537452e1fa72179d2c10d302ef5a97ee58f780b35e0d43b09501e3ff23ad1c11e5d2e90db878df81dbd87ba796b81056d3eb035e1be10dd0039e2b8acdb6399e43ad2e757c5316d30be8135ea4fdf2dc05b4b3bde8578dbcfdbca8ed1e58677d18a4026e9baf9136bda2ec2d39c66c3c20ea6daff5c91f0c9be69778bd50e8e1c5af137397ce308060aa9a1b76cd3caafbfc27ba447f931810edc5156c305420ca94c269db6f1ed93fb460ac63bb6f1bb1b5573fa1b5d7c7822522c4234d57eae61cf82aee5c9254532fb177e82a42f7b21cfb7dc7bbd73687bf574fe3bdf7aab0f6c2fc4ad2a6f87bef49d11e3579aef9d653f24385849b93d4dbdcdd1007fff07e6cd34b88dd15170610607a9ef89ef895b5175f42216ed0cb3bcfc9ec63881f143fc4214ce5944f3913abcf4285e60d1bf2fd77f489fed3b06925abc66b9a5bf3fb2e1e0ef8e620dd3cf60bf183e2860a44992a9c76fbaaa67047cd04389b6ff1da883507894d3ddcf86f0489fe0ab1720585aa77363dc56339f67c50df86efb480f7fe8ee85e0f48dea3a4f932e620d9d4871bff0d21515f212a22793789c5630634b9ba5e6270bea41bff9dde5cb6a98a8cdc30ef6f6745a36034dd3a6acc8e7d9b43072791c286dc1f17cefcae6130de74922dcf55bce866f15f7801da26e91d7d7066816bb18f9f521941cea8a23d62f603d669361131093c21e88831aae14b4fbc19b469641084331d16060104f48c8b4d6ca464794df3530830b1dc4461e69c71c3654b74741045ad7d303ffb3cc77ad623e4cf998fb65b0eb576ff5ab13565c7d91366cb8f5c84a63aa9e2c3cb2809fc13895fb4e9ca0614c616a9029a684b3000548b5572628d49c9042911e36dec15fb905d7b60b6ca3921e2b274e8de133df3a0bfaf78318c3fa9027b9fe0c098180eee16f9c58aa064dd3895d797b5d92162d8218599c8d8567b04771d2a2291fe402320d5a082507788ee5d800d845bd3c8f9a11414ffb2c1f1d307091445792c878539426b0cf1ecbc1f956e677de2fe18bd58b4ca0badfe607eaf23c925c373d928302c1c41c4aaa3aea1fd263b86e2aa6b8c806dccf996367ec5254483f3cadfb405941637c0e9442cfb3d218953e15683d3b7d3a48069196ad743a832762cf646838b54aefd88c29177036b40536886c69aaa47cbcec79a8a9bce5924bbd97a53c7905c00ec2e865efcd907ec4fdc1e14cbe457c422cd5efd7524bf36389cc2d5c52c781dd9548d8cf9f39902a8e5e4c625bb40958430caa8e2b7a3485cdc9dc5b519292d66a9d0c253a2ef8484e6ec6e466ff9e43c630f4159030ec853feca349e6328286cf99f0ad169a1035096d25d717e8a9d53c28f9df023f8fb397bbf2b9486e50a4dc612df2546e367325cb10dde32fa08017131a580ffd8a67c91b733268b0cd7ba5309202782149a542ee29373959b19e1d1389b0fe55ffb54fa2596e65963f590309e67efbc2c881290e1d14280d8040a39362c3e5da265ad6dff60f85bf9605304cd9a7896e2134bd33b89a897b2fab8a95b501d8abc14ea0293f0da6bfe664992f35270a6219b7eb3c8a8806afd921dbf51737b8451af0edfe560917811c304c0859f63abe74a2f23005858e4b0a3039a875aba16a96671ef366e0a1d8f55825130111a4f3b7bef7473b062ac30c6ed0c17f14514af8b51ec7431af775d3a7c346a2402ee73704720ab732a288b2dd4555d4f980af82a7e4de318abeb2ebf0fd7024a91dd104b4f8eb4d4913db94223bafade24cb5e20afb481f0b054c21a4d39ff1dcc7595d1c01a5fb757b6962b609ce7802073aab0c2e94d32f72061486185cb6a827b11d1d18c53e4740964d5ecdbd90647947781e001db681aa98b6473ed697672fb9bd6f3e3d29078f13ca212c43aebbd1ad68b9c4915e6671d2ddf7b477af64a9a0a86498ce943ed32431a50056dc41e1cd42a601d3db31d13cf83ed57b9f76f5d34a59414bb1727c60ca55d8a830c215aeb814b996f192c0f8f0d58303a7f96fab06b2e244d3f092b2cffdfe13e87047b7bd1e5fe70bb51ea5916f079f80ce24123a4daf215cd210696724d3e42dfa396e10954d56211f6333b410ddbb65e5309a58a2aaa8952420925ecea8955f3b9a3061cff95a653ff3f7301a9fb9ca95e2dde92699278aaf730a6dd50278b5645a7774eb6428e8e7d9b7bfb0ca95607d589c48705f6451528e53946ff13680d6f5621ea7f11e584c9708e58a7dec3a5f689dba50ca01b0addf3cc9cb6ee4c7017e4a8c1c152c87f55f0ac6d76d86a470d6741596b092ebdb987466b30fa32cbddcb207889b23d4aea0fa133678af94bb801a307a4996e1c7e5026013c39218c0b84d1362d22cdca1de3f84c046ae74dbd247307b005e852e9f263a21603ddc7fb0da4053c15ec4c4fb3b823c02941055eea58a6427155fd65512e27e5e9048599d447da16e3980aa7c714aa49ecd4740b0132c9d18a20f1b0f8d66f2cf596c22d75b10db43fa1e6de148415084470b2db48646c50114193bb82c08fa86d49d56aa55182006e5808dda82687c66c1746cc11c7dd5ddad65d54f0612a997cf47734bdefaa3b15bbcc20c5fe0a539d77d3cae2ff73c398e2b995302baa3c1be1ed4cab7031e399e113fc608df1d9dad0b68b5c2376adc8bc746c3845f601e52f573ba576035c1509b58a39582302bd8b32aa1c07a5eeeccd43c9036e3dfd0382cd556c5cc9002cabcbf500859ed5f9af8df0f323def4a96ecb81cd9116e7a2c129f444d7051d705b33b0667b9d4515db58f7178764d86daaadc8db320c1537a9d2551b343d8a7f4a300a72287f42304abfb1de05387347f8db16658ba9a51d2d66fb5e2cfefb75c4b8b64c564c60756c81fdf986d19d99d5cd566e849fbac5559fdcf8d66d97aff2d86ef1d466f9e4eea3e73cdb5cab25262048dd7bd21c87a3999d5d23e20a97ab7bbba01a71e036c11f97d3eb77bcd8051f141191993fab2cb4ed081bd7b7cebac2c0cc7b1b70f733c8dd95e0b3058a6a4c4788038a1134887e3821d46854e61789b420dce91aa62903da4e3fcf51d7ca2436d1a5d2f0299e67e6be388f50a10d7a2e4554eb2ce5dff5805e84d4dfb8d936594541a12f21b4c36430f35e831fc6c9af0689741fdcac3267daebe27952458fb2abff072b8fc5e3eb7bfbb8e8f8eaef3704b813dda65121983af41e42a4b22964e36ee2bee020e521cba2a0d596fa2ec91a5bc1dab43a76094e588ddabde9c0df07bbb25d1fa5a5951f09009f32a580c7e085938d11dd32e5ee0fe0888fc2535a3408ce3d6d00b93608844f5c7ca298bab0114dc23ead9be4f848395094a2eb496a100540bc50c5ed44b1ac5202e32b3f68a0e106c94e789747cbb3b6f472cff6f41cf74c1bf2454fdbb4d0e3aa98097440db863c0d42dd59ca3146f354a7a8d9a3ceb228fd30661abd75f2518240e3a12fe247c9705c45b7dc1f3f278da2aeb263f7daba93c8e15577e63d6df5e4d07b5520a3c730c5e7140c1fce3a1f0da3dd7c12cf08a7f48fae92c9508553db57c01f7c9ed9b1b41c6d11009190217afae76d9b20b0830306315188703b9e2710c76204efad04d1dc3c06139bb82eaa24ac39773458542397a6654662d4b0cab4405dc3f3dcc94135c067776af956bffcd94a15dff6773e7b29d9b7e0aacfbe8af876bcfdd95179e82bc32775b2ca9b48f690fcce3295d69f9e52e41aa8d7a947fc2f67b5d8efcc076d59fdb6ec586397b3db66aab68942b746c7a536184c66a6c1b7b6578dc3ebda3e6582723fc0c130004762f63a6aef5e46d7ba2d39e3bfff22e644484a0d83d899a44049cefd4da8950feab960027f30a210a327312836797c4b66301fda63fd0331c8a441e7466dc4047a4fcaa0516ffcbaabae313a5cd1c8980eae69621362f326fdbd9d931a4bc50666f35fbb65e41aa16e4179cc5d54745dce17b8cf73a427add2a4977f5cd9cbdd3e948b1cd9b43c5d418f030d2887f2d6a2962ba0e407647b6f6b31a99fdb66fc21588477f324a0b4ba84d4437000d5426c4823cdd8146f0b9e0eb96db5daf80cda3e5bc54f59befa6516669e0b066aa77798f41736a3ed87a9961c72daeff8bb65c01d88aa15494c66bba2f78c2a7913b2c64404089760aba1e6d0c35720fb796a0a654e5c634b5f4a513315d038f4c066ed39d7afcde1f90ded7c80d5af1d5ab55c2ac6251120b1f88929b34c1d51916aa4206b40a902b0a822ffcc4058b31acecf64713be26b0848e767bdbef1640801d4f02845dcdfb03d309ac8310e753dcec783f3b13e8e0908195b521ee1bdd0a400b6117f91a860a3bf858ae19051811424a5536e304c09d231e2bdb5f01bc4a9e2f0f043b0c554fb399e8a15a24ef73871d0549616ac792ad37012f3874fcb9dc62cb020a366ccf9eff8e9d9e4e00e7f2ee79b2033bc4820f98982014bf93c629f0c0addce1fe9c132c0390a9aa698c00123a7b58b8e184eb042124090639807b4a289f104a11edb8e759d1725dc8f696f11baee2a04c279e8a45d1c7adbb04842886b9be4076d9e8f0e4066853e281f4ad3884b92379cd938b98a1a7f560daf30de0ca2e59ae1eb9ee2ccf999de818456a753341e0629f776c34d965221a068deb4adf482faf1c3b031ed1964683ff7d05a37a7e2e753edc2349e1dd42464907697abd02ec19a0be8eab8b571df55bbe75b51503e6b12d21796b07aec778bd6f76c5e2795879b5d9623ac9c2c7cfd466b330760119be10aab232e35206d4a4041681d675b03d3a6d40a863ac8e6c3f1aac8927830b4610e75bb6cfb1985121cd6198b79926a1054f7548ade020fc14e1497ef34fad18f7b141110d42ab65b54bdc572dcdd6a01584b63b33d5a425d4b51476c26e3ede71a5677ffed600ffe99ca43b3ce073667dcbb9de081b71f24cefd9d13f44f86f2d199f03c2efc5ac559a3853d311789a644b0a58ea87f3cbe2455868b51606b07c27ec82adb917c11a427e65619be7a66cb7acfb4809f506a014a35da9e50bc415a7a5d84d2667dd19878a77d09e1316e284e85ad342cb7d0089a293f66bd24d51a351ce77103e47341e83c2a151be1798ad4e78447793d41b0c63d1d284b69b3509748b0f03874129c92c214886f42f79c7b91b3f9c88636783fde0c4fb9ea8301b3c66f8f1a7c4104c3204e25cdc495a4fa0ea46ef2c0a522b0e0bcbe42a2877a0c419755ebea043717bc3c5019c60e8fa6f58d26954dddf04fe99a67315e55f3880d6eec4edab842040575d1d26a9a88e16984a176e33e22e07d2519cdae5b155ea082c905aa2b147ec3c2503ca9f1a30833dd292ca9c5e8f5377e6a5b6f3d9e5730225791953e5d88b360cef98ad68adfbd7370d46e0a753e2295a3512bfc55df2e3bba8984addc07d831c9c21069a034e5f638860198b499cac9e3ff36f6b7b73997ce93b37046d3a81cff95308e9ff7e6aefa729eab2c29dab581f3a7d144cdeb6856c8a28040974563531844b990e33999a28e064db5e274e725d2148bd2199448bb54980e582aad4241ba69637b4114ea9d773e28c51b60f6e8feb278e4279fa8cba98c5da882e4c0f3dbd2ed1910dcac51852e4e2c55ebfba35183956191aa1166b89da03960f6801df86e2c5b9c4c1ce6214303c74f54e7b69dd19392f42e2f72bf9b5cd8b99d7d47fe7fb4abc7025254d8d21da46e5352eae74fa0a42a605256b221664da965883315429b40d3ec3e142bd4669de05a35b85a7b6858d33d5f986553c530252d7d031b0f6bafe0ac06b5b92a3e7c1524c11d0a98044d5c3848b1c2e4a228960ca32eb188d8fbde5e4acd410d740b4c14a8e0e630ef513778e8b46929e3023119a728e2506b98a610805d0876256de0371e0810269c305658e35639520aea780bd189547525c88a93a4ce90cd430c1332e273ba9233318a5b09848ebcaf6df24c730717af571a6ddaba67f6318ec3f5d0d923a05078849fccfadfd0eb8dd92b86916052c2c155100dc482b91ba3b58c5255f2ba77834bca30f5b46af2e020db4710004a189423d3e610a270854a61723cedcd17ce189dea43cece6c90edddf5a27da68ddee05b712469eed72784f22d29c1b05c5b736b7a2678195a8c60a8c494b5cd30a204e1628013356e609956ac6a692b7b550852ebb10b4929f2c97fcdb6b95acee020a869d5f2b90f02fea5c40f4b333d14ee5634c37b9550f22b67ef53b4fd463b6ae29e8089d21c09e733ca439985b1d8b879630bbf15ea3bce6519f6294c264c6086f75933ced1e4ffdb615ccf8840e0c9f97f23210a6d0d399908fa53a5d529c2dacd9f0dcec97d261f005466a4a7c0901db8e30cdc1577db57ed0b6741c6acf7ae15fdef224d74747aaebb9b3c2b64810158886654c794a993d3c4a73780d0cb9ebe1a4fd632c1cd2eceec2eeeb29de9640253948924d5cab5e7da8349fb10065c87e2eaf76fe48219521bfad9cff94e58eb2bd571126f9524f16e00e8fa758adad13c66a33b2329d9a7a1a8fddbad166769f5ee6fc665a7a0503ff7f697e41b419a0b84a028b29abee1a974f75647820d62e76e043460573ed66950835ed858d1427b28f45a635ee4e1bdf8a11b661017e0b4f1db9f01127330418f182d8a18c1fd03b18240855f6e533514e58b029912ef0680966e1402da4ceb4fa925992b106d95d9fc53819ec1020e9e284afe0ae9a8d00b50fb9ecb5cb293627e8add6e3a69e6b120cfe3c47c8507408b220a6efbb83092d82d888225c8ad02c7f80a3e2b4f5b573ca0ce76adaed7d8edb1b5c35f65ec26c4919823788079a6eee76d040294658f2fb43b5350356547e57a17da162bd73b20806e1145da5bcaff03d0ec5afe383e400ce677bf4f16c9d0b706d92154c01205b6107502b15f5ebc7a396d287acc2b8efbef6c580c49334cf1e9cd64ea4d4891cee0d0489f3aa7c4fc2c00f857514a07700676df8634bf72ca761449cb6799b173c9f6bc09e4b7d6015cd4469e09ded46077d30aa00006e9cccc66491bdddad6294ff0aaf09620fe928b27001bd5ca2353eec6c265006eacfc4453f9ecc1257fc6b53a473b25e92ab861f7e7ff8b5c09fa9abacee0557248acfbccd5637b1bfdd6584962fe95814ec216ebca3983a53b645948ef2cb684015cbe218723477a4abf8c37fdcb5b65f21829488189a0e6c3d1d96eac7733eed3fd895c8186e615d6eb20e5ab522020b0d642c98076c378a12f9ea97d4b8ccc90a18e905b19052fa0cd24251f95158379828cab2a2b47e09e832ffbe309c25c16344b8b7e871249967eca9a8c5856b04354e260cc9c702d2b443c9f4adf563e1ea73ad585896bf88457a2c65108af70dff36babbb640bfd3279c526c7b19e3dabee25870edb35dbdbb992455f9f26b17afdcec55d67a4eb5931aae69b14578f9bd0a7ec6adf8e70686c54217e748e3456b670d2bef769508f04203163f7723ed9777104459db4721ad2f8efd00a0447b1a76531168654acc814df064bffa0684105b872de18a4f5d589cd7494864545494cafaa8d5cffa6ff9f0bf5e1129afe095caf0dc1e765be0ca7e16b8672663115d2cd8bf103a2e7aeb1739489860f2dcab8b3411ef3305658aa38dc457be5cdb9c775b7865e516235be1cdfdb879063c0f659843da635087a3692f482e67e21f558298a8e49e8bdd4c48de94a240343a2a18aeddd44f4ef24e0940a96c09ab53fc0e1063eead68e6c1d2bc136da467d030e9975a910aeb365978c84edbd1b55b977d40ebaa2f07a3f9f1f3a13157b26c990063e9e48dc8fcfb9b61c16d0da46267a5e0628ca062a6066f09720fb2442ab0b18238c37adecbeff46792aab11565319c6be8ede7846e421507690886879e2cefede4b76f154a937da59c65c324225df33ecf4f66f971eea3b5f3dc37d3eaef877f80df46218c1b99a59a1e7a8a0b565dda54b3bdfb72a8a2672b2070e26e3705d925fd1050767e29e3efc52050ed3460d164e107058d33630cc43861966680f79c8431dcc4b76c8431eea8533c01dc38e436314296bcd0668439b2bbb5733f6d8d37d9e994fd7c3fe3cc46865777bd5e179ed605c3e071154c6ea1a41336bd676581884178e1473ac217f01425893bf6c6fdcc6b5ecf338d776e71d0181668c74cf455c8e8150b3f2f1372e76cdd3b8887be2e6e31fda9f66e3658145f71c2f795760113f349397c8028b2bb088d4ef2c22452a1cb70024bf714a3c241c2fc9b8dcbc145ce325992b4008210d4dfcd0ccb77d158c660da869b890cd9119231d8acd6f4744a2ec72247a39ce183162854b2212e54d13a92c6832393238a82c68bc9c656a6441c3f1920702c5d05c11ff65bcfcfcb752c6f192c7f192f7c930e5e550fc72e88bdd93e2b765addbb4fc6d9c8b48945da89ba712395ef23a1769380dc74b3251a68f130d4258c56fa17971541a69a16f0bcdfb2e7a5a244282100a819f2cac00218c5f8edc76f354e2cd53c93e2bbf6571068450c8909ba712a473838efb2ada57d9b4a7e2e5eff6739bdcf1d0a7d978a54cfaec4725efbb8c77d9e63b2fdbbbd4fdf3cc0381425e6e52d3e590cb7e928ca779bf3d939b4f93e1ba9ff27be360b2985616d5ace6b46c7214fe62e5f99641202459efa4f4aecacd53c94859efa47059efaa74289dcba8f0bcdf3ecde6e63bce45e68891fd52bc909743212f37b175eab95fcaefdc7d46644a22ced6d9c40b7939446d4908b5a53884da52908ee3b24d1b4dabf45b68dec8cb36355adf38972371080814871c31d2714b44a2124cc8cb4d8ed83a9bc4211f27923912f2729338c4c8d77132dd93b88e347ad1425e6e02d375181528d88f3899df389819e883191878f9cb31104e53b8a0df711bc22908082708b4707dd3b28c884c15f1cb91df3c15086111083d3fa26401c28e3bc1270173805faed1aae4adc87ff7e9229e88db34bf71303431c78d8b344282907267b39540209abc435f7e9ed9702251cef87f797f477a9e7d154d9433d23f159128675fa57befbbade495b2efbdec77c77508a707f08ddbef413839000e08a752f7dcebb40ee1d4808f1375cfb7ef9d837012826b1957452b698175df216ce3f38404d00110c211fcc414f1546e5e8ac87db1a64322c517b00b0540013f5042d0abd9b41bd1c6459e5f14b92f7a9fd67bc98bfcbfae853c2a3e08a8e203e5476529607ade8b6eb61cbd1f75d92b715a95ef623e303a80d4e8bf9711f76d3914a3edec3d4eb4378d5bc0f75ed6659f66e56190c05490e724a5dc2d9191f93c81031c123f27c9883cb910c208e2a5dcf518e33685d7519ae32010c74b5e46c4498410d668a3c86d710222e082c7802d6e209cac7c1d479a6c209caa8c01e15482a1ee79fe26fc3b0a009f9726bcdc0042c8023f2f6b78daa8c8f6b41184d00afcbc54de973c4f2b12daff8db84de952e8d36a8a140179a4ef0bc52fc78e237d1749f109feddd7d468dd17b77ffd5de9ab68def6fd79cc2f48445011ef7b912893206c008490bf578aafe377dc56f3926511f49cdba19dbfdb4a917ff7dff61124ca9bf735999491f287b2ef3d2ffb4adc736e7fef59d1fa77a44c24d2a87cdb57f92cf4693619952e8fbefb4feb6c78fe4e2b99be59250381481e930d30e9020a89a0df42f3b23824827ea47d59ff2e082eed97e2692424244f23e52a59cd26228db41fe56de334af7b29369ccb6bdde7716ecb5eeb3ec8041ef97041098413d6bd8cc7b7d2921bd10665541a699bf6c486137d92ef3d0fc9360517714dfecbdfb9bc4867be3dc90af67130fc219cb42095ba8e73d9a6e06fc38944483e0ee6e3b828a21cdaf9a37cda4873d2fd4d76c2c164814d7991c994604aa0b8c06059142851a26019e6640a25509e645520790202658f6f4c06937172a426cf18d92f25e6cb3599c475a49b4fabe2dd7c5ac7691d4994b7ee3f2b98286fcec98b8c94293898eeb71a4d86e7243c2771f13e8a8785be4e4b9293bc287f32dff6a39b1c73f36999ad93b399792a5994c465d36ab40e0acf49a2785d0c07e3753f2a791be772b3e5271cf754b81908a70d0984d36804e124129538f7840a847012e59701811670a48613fd973bada4c57771e3b44d8ba20f7d1dc77fabd1bcadb4693d7edce622c48613e9982355437d90e8fdf7f823ce8b379914b92f6e2f5d1389349bef4a5fce3a86be4ed331c72d472f87a257ca212b6f33e23eafb4a9b8e5d8e5c85f247a9d45d1cb365124ca3b22a1f87ff9f34aa3e8c52746d1d3228f339ef71de739d66cda56a379a25cd2e2435e6ea2413885e0e70051e4ee6badb5d64a29a594524aa965599665599665cd39e79c73ce29a594524a296535ab59cd6a56b39ad5ac6635ab795dd7755dd7755d18638c31c618df7befbdf7de6badb5d65a6b6dadb5d65a6bad94524a29a5945a966559966559d69c73ce39e79c524a29a5945555555555555525afebbaaeebbaae0b638c31c618e37befbdf7de7badb5d65a6badadb5d65a6bad95524a29a59452cbb22ccbb22ccb9a73ce39e79c534a29a5945256f2c2d7566a4df94494bf8e1b8d5eac80108ae0c70e01bd8ecadd17e12fbf69351bc6ffcb9c34c5b7fd68e33aadca86751ffaa088f2cbb87c17c341a0ad75bf7dcde8bf97cffb1a4d0984534d87707a0827ae75adfb2a1fc745f92f7f325f12652946f64bf1ac70fa2b719e1432a14fa3a2fb9b2cfa28db93a0887edb72c845c46deee3ba1808a7fddec691bccc896e720c8493fe3c0ee19421843c60b63beff3bea4c547e12f18df1e04eabe667bcffb11660008270883b811f1e7dcdefe4ba25c05c28906c229837052c01910c20e7e66106e74e679995464779d48112f0bfe5ac427be2d6fda48ebb6a7f1382a6def3dd7aa701d298ebc6ce3714dbc8eebbadc6f3215ce8b438c789a926ffbee43db8b142948f9c97f3793240a108844ca58fc775ff6222add8fbcaf925f94752ecb7a7e1184d31553ac801a845315544881100a21848ff60142f803fc5436a8cef8541ca8bca8ac7c6288f05e0e91b2ffbcec3bd24d97475a47ea5e8f4a5bc8cb219e358453109311212f87325286dd88482424104e94f742a8e44f260eb97929b626d2a5988e03813c9277f369224d67cd75a4ece344de53c99f9779af7d5ac785be52f646b9cb31dd571171325892afd95e24caa11d455973a21a8c9a83c78990bc22bf33c9a3d2713645bc6fff02b82ea648fe322ff26da3229f95ff366e679ef7db88e35bee3251de9c880a89c86823d2bb2a13f6953822bdabb269447a57e51395bc8fb2248a9490979b2c8922e5c997b4c82428104e53cc741ebd64ad93579b3dbe3f0b1a9fc0a52bf8cb936e666e5e0aee23dd741b04fa8edb19c99b96f771222ff34adef6dec66d9929a070dd4fb949a2c4abd9b4d097754fc25396f09453f0b7a22dc9f85bd13a08b4b5ef47a14feb7246f2209ca240382520eece715d4c4c89f495a02c892205c209f3645e08d0c1090cf1a20642b8e16748e8cba42237dfa52611ae6f1a14225ef75ad7beedb9163faf1425be8e5c54e2425ef4beed4735efc5d09749512442020279ee123a660075b0004208057e0c1005f5715cb74bdde76ddcfeee4335256efbf8719b1371c02c687c82dad215b6ce293227a0002b2b951338d838cdd3aa687c3fe75c2618400835f871e263298b089117e5ed11b9f9b42e933805f03a6a09f811b2c1088591184134359bb66979f41d4dfcbc4c8abfb75c85e7f871db96b7f6894a4fa6946f7b6d6f48a414efbdfca28fc27f9b82cae64449361b6ea3b24df1a49b9990979bd46c5c4705ffadd4c57c24edf747d938ed2bedb7827ddb7739a666d33c4f7b02e104c3ff7b1214fe1e27723922a426cf3c8943f84b1023fba57ce7a2e43bae7f92ef4a5f69c9f6d2e5251c37231221d99ef6e47f09e93d22238e67e013e40361fc9ad8bce7b8a785be18da5ac8260e99e1ef95bc68620a4db80123f745af268b7ae45fb3e5d02671f14b9bf66ddcd6ba2f96382b600360285340139f495594ac822581126546866682d31993d751afb9eef324555193c8a689ba1f61d313082727104e52c00f1352b8420b492842005d4c018d10e8085d20013e4481800aa0b8016464634397839a3426b0801e60a8b9c263ba72858b2b3eae4078e50ae45c819d2bd0025720186040e803f680107a01e11757608f2b57b8b872058c2b105eb9f205bc12010821acd9b4ee9301813292f7ed4c1a712e20d07ece6dae6f2fcf7357439a22cae76527daa76d2f5b68a2bc694b8e7859b4b3ee4956f288cae644fa88918dd33e121451feb8cf4a1e7959771fe35101e184002ff372c83b32ad9211cfcb2297ee6340202b7934d1e04300334008e3c76d5e8c5dfbd04c7c8226ebb88c8bb492a6e11ff2b44debb17b2ed24a49bc8ef23e6da48946ff7937d3cb7fb7647bda0804f2b6a7c27d2090e795befcc9fcdeb2282781706a028910e5d2b733d7b797d0fe32c9d3947c1e1703e1c464f26e32e9a6e3beccb7fc4494bb274111e551c7c1bc151c0c08e4dde418afa38a8832e83380092145514d7c2f1af2e5ef6ae2c7c144ca8ba2bc71dab7b3b76551698bf28e359bc6b752fc2ec7a70224fa2a2f02791d15f272a84891db2debf12c422dfc56ded6b57435b7be44fecbdde7e992e7e51008f4751c8954f2b21fe5ae2fe100f8755cc88b1cf785bc1c8aa0f7baaff25de49a2857d95ebcb7828381705ac28313104227f0b3c40fa800f8891780ff79bf65dd7f5a36e2ba9eed277945f657f9c40eda70a2de7d152ede7cdacea4bc6fbad6bd94e7dc7e25dccc92234770c9c87e2946f64bb9f9342b3354f6875c48252a1ce7c4fb2adaa78db48eb46979c4f16af2976f2b717b23819d2a1a38620d6c50e891c2428207f032204b1498bc810755309cbae07c78408d2640963798f1c200ea08a8a303605c35fa0fe01457b0691e6801e48c9e5003013741a08e0e7480603151a18e292e507286271142212c4e806180231052418211a6404316e00404088c21831d12802c45a0310413d4010af4f4f0c106321f54812c1478630c2ce63007dc91001e32146fcc01214be67c3aa80272cad084a2c20917847670c1952ca22003e4b0319b78ea9004649900075670c50909204b1a1420821dfca081f0092aa88318448c00ee38a20904f860c61a9013c568044218cd017778172042143736b0b304256e74ae44819d98982a4e5c610bb823041b6042066ab002ea8856095cb0c11c90e51ac236c3480ea08e309c80667243089cce08f24400b61dc0ce132300618515142811042568001de0634804f5f0c1802e8bf2968170c2b89bec04ca718506b28c58a0077aa098208b1913d7016462813f4c3a84987c98784ccf859d0d789460e1f0e0a1c3d39926380487821c3825c0738009b23ca103feb06382d334e9d041393c70e0344d1d4e9369629938d3d4d9b10567e24c2c1c21a24cd38e890572a61ea80e67c78e203ee2e4e1703c634c9e69e2f898dcc0997a401d9387d3f9695a00679a383ca6e01cc199383b3c9ca90c9c69dac19912300d314d1d0e0f20e8e8b0f83009314dd3c4b93801e0d199463071a61d9c69e274b289e3f1d183727e4c47784c3a5a3a504c2c1c8e47767c703893901fecc4008fe461492786033d90a382c9d309e2d1c1993a500707262e4c90033f9f0f9ce0e49938131a261e1c27a689a383c3e94c93351599784c3f381c0e6787cbd40487e3e14c5587e2a1081e4c4c3d00c0088e07261d9c2226cfd499202786137d4c1ec8d176c0483385d1814b006182510c81d399764c1e96a987a9530687c303d4997067e2703c91f3a3479049c734b1541e29806ae2f8d8c183334dd3c4324da089c3a94267c7d483e3e9549906c0294d5387c8d48307cec48365e244c15182a30427890eecc0e98769078733f5e0f9743c9c22381cceb463f2f4a947cbc4830ecea463f2e14ed3344d47705e5878e8c199348f1f2c9c2901138f69ea7026cfd4644a82737190e0f0c061e1e8983a1367e24ca029090e0f1c16cfd4d1d199a63b75a620538fe9c7344d4f4c4a707c7458261e9e89334da069da21042788c9c3997478a68bc3c3d4e12831753a1c8e87e3992e0e673282e363ea31f1f070a669024d49707cb074260f0fcf344d374e4438c1c348c7003aa6ced463f21031f5e801e2e18a23949808e099389c1d1c969f3e01a87868324d9c89334d1311c80249700a042639ac40038c5698400c7058b18417cc4045e6421a536c410b7066092a40191330e165f212601413e860045196e0a024c0040b902326d3289c9840093634c948549709882872651fd0b85be8a1e52ee163b25b98ec6069e620818d7780140d1d942042730667881656c00d899513063063481a0440137f08200e010068061059401a1d1980d1d305841d8805843110c220f0630409c249c96f4d2433e2ba2537dd0c84930b0120845330a084c51023ce20e5ed7d7fbe75bef0b5955a53565e47e52ff36c87047c14e00857587ab0f4f0f8c0c3b2f4e824f163860b9801f008b2c3070fecf9f1c3e4f9b123f3d8747ae800f148a10b105cd9e10387a58767480f49e034aef890f2837b86f8c005871ea1630acfb4c3c80fae40e14409902e381e1f1e2742e070050c1170020e2e261d20200288820b8ec7880e11d2b4c4111d0678c2951d3b0410238100fc9064021d265c54e04a113da8f811c48f20b6581200120fcfc71bae18f97a30a121e3c3d2a3d3830e2a1e0b5c800b1e1e1f762431fd6071118613f470020a12e011070ff8c0e141471440582e8f147fc51a11004247101f4b7c30b1030b8f132c57047060022611708118427c2a09f4b09d7c11842b3c947a08bae861fe304941a2f3044b11960b1f2cd70e1f3c7ce8dc17269d247c2c79c3151f2c2f3dc8f0687204b6c4478f263f64b8111c5c19c233c4fad80102a2871d3e78c006a080155cf1c1a389121a8c2b3a3a1f1dd38e04ecf0a1e3891d4e1c49c243a947133c9aecf0c152440f4a7ab478607a0c1104124c182184133c0c20451426b8f0c18362b17ab0ee4b0ccb0f0f8b113a401ddbe387a78918054b0f161f9e223aa4f0e028261d477496d02144d583c7ee5cd81344f0f021448fcb850b0c0f9447104f8ba765870bae38e18347890e03e850a2478b07891f642789085ca18a4c9dde21e2e9e860c00014a0011e709b1a69c0e1c61a6ab820055f40c001563c2afd378d02b0985285942964629c20a009085b4198280001a267084298230d6608c3018e1460004614c162461290c0821524003b00288900fce061471074d0060cce60410a5060023346304590268a502100c18ccc1c7568839e920634f420e380902186d68f3ce183e58c0c8c717b4c410a2d380374d92182e0c1070f16248eb8810db0780e0506012f4b301260c00215008016ea0ed448c30510a042cab54404e161021c6c9072040adb8365470c28d0860c4ed0010d80c1801290800462408139f244133f263a74e6c08983478e88068e183c61e06c418716262a70a2c081428f27fc8883c304ce12383ae0c4a0a306878a670153cb24001e49e840a287223843700230050104081d00e000993e1e1f383ce8f0c1e9c1830787854507c73375a66907ece187ce111d1e5cf18471c5e364871371627103179f155cd1a1e3070b1354e0c26302e919e2470ad0d8f1c5158f931e42f84082882eaef4b0c233a5a3040fdf8e1f3c96f0c03b7c749e20c2878e235ce1c1c69520b0e0a2c7ed8c600d3fb27045c71c5774fc30020a577e7c03e0c1951e44f8c061794247111d1bf022003c14e18108782e70e587257e58a2430448111e44009923023a0cc003b318e9fcd031c22305573a4f64911d3e76bce04a87871d467886f0203b93e78767888f253a0cc062c50e2376f8d8b1801f41fc08a207113d8460b1a2638708ec30a2b3460474bc71a5000bf08c625680243ca01f3fec00e2993a443a2e9e981f43ece0b050c172040b8c8e00f830ede0a1a3c3f3a3d3e9703a2c1d1e9d1e3e90f07458a66001c00f313e80b0ec60993a2c1eea29e2997814d139828b1e02d081c6151f5ec005901d9e2378288980270b11184016e11c7708c314a4c004388af046a94626036360490e00c5e5b634a0a148139f1f78b05c31050acc1c4a88a3090210a32ac3035180200b515802117a70033558508462a203a54f0caf73831ae4b0c213e210420d20f000056031a50a28304c960840892184d0410e20a0461a0f7040960412dc26001fb280052d4657e6b8031cde80c515430801240a4418820f7a70031bc4400c0c5820538015544081795982128690841d94d1a40a5458021184d0031eac2005604ca00b35c8118527f480073a908104ae3c7fc180f420c717bc9085220821076dd0a0051908e379a6002caea0e2057b022404480f4b5042114610820c48e0b90210f0b2047b02e4430f1ef8052f2c41094618420edaa0410c5a400606249005025ea0780274a9140200201e38c717bc80052314610842c8411b3168011919c0401812e042960516072842d5810e4ea4f8c1872b2031c605c0a8828aea046180716305063de6e8dc8163071d74e0cc81071a1e17705ac061c13439b2534d140f443a06e8442104c041623a82c5884e1113119e2126217a00010000743e9e1f7ef8f0e9c1881f45f080840f203d5878ec60e1ecd8a14347c742088d803e3e41bc00be48e76fd33a5291e7dcd6b65212104e2c415c813be02788289f2010f009a245480c12e373cddb342d3e71d3e52e8776cc40ace123448c0f105e809026d66cda876ca290205018899b56f31a081a400879801f205a00214dec5cf4b4f8dde82c288aba82efd8105610ea9002210c4fb0400f45f002054a1810889023feccae00928e1c1cb07501474c133060031f7830b571041254414aa2861326700407b24063004b049004153421099d227881025ac8a1450f28600980a20b2c3c000345f09ee88115348ac4c0090fe00118da6889021331c6b005151f572020830438eb40a10f17340121fc31071b589a4c610a25b0620e203a9c104407ba994b0c0388ce70840a908105018af081318cc18635886004a40c31be408611bae00210dc1c99400d8ae000919a3278d1020d8ca00b37c2f8021391130ed8e0093eaa8061053d98e051431bb220008a041d6289111310325c10000308a4388205367091e20551e0365248800d1300400f6aaa2698f18635ded0a2041a73dc21063273cc810317a0110381e8010800f0f0e9e10d0c3f6f48013f6f64013f6f2c007ede8000fcbc4106fcbc7106fcbcd106fcb451bd7104f879a30af0f30619e0e70d38b01c01049018001e90f8618a27e00707147e70f004fce0400afce0400bf8c10117f083830dc00f0ecc801f1cc4007e706004f8c10119e0a78d097eda10027eda2800fcb451c14f1b4fb44105fcb4d121844078f800040c00f4818c16f821a3c20f194ce0878c29f04386861f3244f043c616f0438617f0434608e0870c1ac00f1945801f329c003f6474017ec890037e34d0811f0d008110fe00021af1e948809f2e05f8e961809f3e07f8a919027e6a248490871e8070c0c38f0348f0e3800ac08f0336003f0e5801fc38000710c20f14c2873482809f345ae0278d0a3f6948013f6964f84983831f4c0cf083a5017eb03ac0cf921ff003060ce067c910f0b38400f0b3a408fc2c79027e96308110b27c20dc41640cf8214202f821b20208a10f3d902061023f483afc2061c112013031c475802fe0e70026809f0384017ea21800fc4481047ea2a0023f5164007ea258037ea22002fc448106f841d204fc503bc04fe5017eea10f053090021f4e1879028e04708851f214dc08f901fe02708ec41883640f186241f8063403180fcf086d7512f3fcc88b4d6ce8086890a70d2c1b403203ea400fa40d3831c10f6f002082308480f3c827a688920203fb41041407ea4208280fce01046d08f2110080f6d80110484872b10080f4800f11107841104c4c718104610101f4a2208880f4f04f578a3c7182108a447e4c1e30511a441203c30101e1e96386004b198114140589c441010961f30822e0864c71b4076340002d9514118414074b80144c7056004753311a403890802e2f1028411d40404e2a1018c20cf150823c8d3248280787e4018415288a00c4847049d500475aa0802c2090284700804c21923823804c2690132992182804c5e0099804c48401841709a811f307010c229100864018490eabda44125d2a6459e9370bc24138718e938517601817c3ccfb6e75c0b651a296724cf0381beedab68242454f72452ee6c5e629064d977a46fff02344784f244a2ec129f28a9226a2424de885bd14894d795fa7ba5a89190645996519ae71a6fe4123d8af2b42d53d1fb2c8ba2651a0909d5719ef7fb372ff332aa8a88f33c52eea8889e46424265ad4af4bc2ca3a82ca3222966944642f29d9793448a8626bec420e15a9651cfb9cd7d5a8e54a4461dd7b5ac8b3b6a2424ff3de3b6177d564a94904c2507f9921691fbe24b0c92f8a1198ad24859261a207a36b9cbb21acadbfecb7babd96870ff4a34af3f6a55227f8f2359f978f354fe3dafc4c59ba712bdf762e6ff9e46424205144a23e5e8e58f48ef3291fad297b4e8be775ccf2891d63c8f236d9a37eab8de3d29d37cdea6e59a1cf777252f3e953ce271ebf28b388ec485be1f498956be9b4f13e5c8bfd368a2476dda4d97ab74bf3d93b824521fb7c58e8b5f898b4f3c1a1a1a9a18bf12c77d310b1a9a2ba821fcb54843438d28febfc9c49beeabbc46ca34df712ef1a928d1eb385e9299b9e9a26033986630c5e0f3058e17c62000ce1343491b08000208e17445888d16ae20002f48004238f1e005d7210a53ac700008e1640139da40033b08218c87104e4b9e1003c91493051908e1448417621adc6044122680107ace38410b6280c8c11b1742381d808c2ba08c618111e80042388151060108e97418410342c871821de00b603401061c20849d008801071a3c50860e9a0021dc01020ec4618a0374872820841c2fb821030da88307ba7021849e10d0b07c2074840564011281705ae389179a4008bde04417da00e190386452030c931210caa10b4e487994c6c703062f40c3052d80700b2d201c41f69cdb3c1922104e677c1ef7795c4ce8d3a860c10a549002149c0042c8633281156905c8448519104e2520c1084400219c9e6c9f2906b0a20a53143085658a112bda00e114021004317de0038528a30d104e1e88420b1fafa3eea42a229a1379adfb3ae081d30620dc5908028410c249036464c08831384370acf82aea30021447e2f6a2eceb2fcab888b302f488800589cfe3110a28a29020db8ba8dd7966884046225df45e84028a10f535fcc5b8821538b75931f3e2822406894b3412ad706d225dc189d7514548790489308981014a268c0b80110226988855846289f8bdd73ba7a30850071bdb8b221446986022427124f2eda18e2750c701a08e223c4ff0c4e17182670855b8f2759cf7858c90205588104229f0430523408a860bd9d0689934e4bfc76c13dada109af8df91702dc7fc2fa13c8fa46922d228bf0d0d6954d2310fe16422f55ea421695f8edd6ba1df9be6fdc7c1c4278418203e119d88068841221491a47dd9f7a2278490b42fc816e59d4111e3f7a28e5b128b14d1867c5ea9a3a1a1891449fb6e741c2284a47d4122911b519745da682b7544be2d6f1a511e755fce3ff2364eabf96efb8d23695fcc39943fcd45ee8b349bd669e27b3434b1d33ec40d80a47d9d566500918626765c277d9aa8348aff3d2289f9fb7fcf5e74e4e57bb6719a47d23e9196bf57f2bf84730605ccedc88c9127ac01a9780542f88498271001e1568a430b30efd7916f71bc01e328230e2d22e15db6f928fc4725af94635cf886e495709b8771021b10f2ade4694e0841e8044cf1d748a5bdb926c4a10971504dd8a2094120a468866cd9c6a6094c7003c2ee49a4d297b4884c18436342a8478e9b6142843470c00187197058891b12518603c3f1a1b2a011c312d858c2184b08c125e025f0804ab08248fbb6529679da111f463c510e6d8e846d1cd7bd1795503fd24859f4ddc78964e27b538c4adda7e92e53f9b7792a9a280ed91ae96626525bc7d7dd9336cea3d27136df6ff14624ca259ebb9ae8d1448132e3826449261305cacc142e58155886497999714192c1bc3ca1d9b4dc7d9e2712d56c9a17b3769191d9b42754c7bd769191a1e2c789bc1c3947123b97e3a6e5b871375b1e451bae49e722e512a99ba7c2b74c853647fa1813298f866654928994e76df98967e5f9e8bb18cfe69770dccccd4bc145a4921225930588200548841264548947fed1fb38ae8b556c9d4d3027485c64968040104229209c2cd075184ddc861093c515490c01096a0d216881424308664c2710028d920e64d12284203a2e085a0842191042aee413042b105241700229fefc957020b0012184403003420a08311008f10760f84119105234363f207d1ccce7079f78c3f3e622121f8801523e70c3075672f441104809a112242e811f37a40021450302cdd0b83146e7b6ece2060d74830808374e7b2a4a7a2006d8033346b173a1991e8420a43824023f3d9890faeddb7e771fc37d47668c8040337148c61de1410c843c08b20339dcd8c1183ba0d901116efb4a7ab3191247daa659c99bf684eadc9398033144504c68e7f809e1485c47caf80fe15a90487d4822e51121e5514412850ce9b8ad79da8673c271335cc485bcef421f07c35f447924c371335fd365271c372342f251784ec2b712b7e4e3607212978f83e1301b142474a2b001043668903f34a4cb40d8c9820d2f3c369cc0d8713d2781b083c40de470033340083bae03b981951bd8dc404480d290d8b90e8fcf0d7eb0411c202440f79aa8cb1fb74c80f8e50821470e3660810dcab041151b7c21184156f2280e89a03884001142ce176ab046c80603b081103540430dbcc0d5c42111348400914ac775cdd56008f0bf1a7c0161c7c5781e298f22ef208431801096e08706a219cc812949554488d0a0090d5a20a4bcefe293b8edc54dcba8e4b7a1929f0a99fd5540a08cff7e2949f297957837ff21e1372fc567e561bccfcac340e1f99b707d7bf13c4f0640e85e065e4038e2ba2e8398ef32a8207fe12f318083ba11c5a00c9bdf6250450c78d8b8f802650d2b10c20b3f6b604851bf716ac8916d3851f472480d372034023f6a588110424f53230aaea551b3695e4ee30814919b4f1b7df4b2cfe3940de7a4fbbe022978704ebaafe279ff7152425e0e79af339bdf6010a23624306012f3d93c0c65c3f14db3899cd3ba27c5eebfff484f257e5deb94505dee91e3e202be7bada3a74511e925525fd73a1ea925f1e3b8ee0891286448362448a4bcffb82ad1dbb8d8fd902c68421fe995d46cda56ea62a280403457444f8b9dbf102f48e8b3e1ba9a52dcf2e67fb38944b97f1a098a12283391ba11fda76d5ab7e1ba9a9beedb9e2379436a364e147949b4372d7e97b92d0ea19ed2e2104f24ca9f17bb46f2b82f46014218057e64d488fff51c3fce190e1b7070e280105e013f5144104e5e449bdfe28bb4908db759c94f40a0998f347a221bb73df1a2fcf662e5615e623e4e2413f272132bfcc5cac3744ffe977c561ee64524ad9bf164b677221221f1be8af66d24d39a829bf13a6e49f7df56e25c3e8e8b82e46502e283021ac01a6ff4a1c089d75127d002e4af457c226e5a8c5e9ef120e4fa163b2773821f5f85d3397a25518973a3f83a7a37d94694bd2eeb9eebdb0b1a50c475219b6802d29ba009a49498e0b37fdbb8cdb52566c861061b99fba2196698416306111052504a2005084b202a958054826ad32209c400a9f73412acf15e2481158af31c3d2d9360c88ba7c5ccffd3ac60bf691c02b6974f547ac247703382205be65af6a208c400b308caf06eb248043110428adb9c801f1110a1454f8b06809f10680186608cedb7e8692188819052f2125db610f08094173d8e83c00d4ac94b8cdb57d16a4220b8e211f90e04548080078430f4e5fcc5263e1f800342083ded035e404875bfd9702f12e5ed69a3cf0762a84f197274dea6710b88d9fbb411564612220d111a6f94bb4c3a62a4c61b1d9931c25fb856469038bce18132209585074810525978200a0f040123a8d3a4091d60438b1076121085089f0ed074bf6dfdf336ad034a3a302482be9a4debc00f0ec401c2088a20ee8b14d5b9e8515ab6c9f1bb1ce387be292235e2f6a67931cbbe23d1c4c83bae73a4d17f1149f49af83a9ba87124cae36cb61aedb5a801253898ee457ccb4d381891a8b4048a1229483e0ea6fbcd06cac7c120e1663c0e26b4bffce4e36064d0e40d08ab7cde7f59f4df99f864c08929a98a0811aff4dff511d775ee8363f419e34af75f166941a237468cfe88110708f57331e210038c8f181842483de9e6fbf2d6f8a6956aba1c29ee8b2fc687e33a0f0906d8e0dfed388486267ad9a6e479da0703244a48e769230cc440b877c98b1820a20b230e5418a530c68061540121f55d1898fac260b9001b1e278a5f89abd9b421d18613bd8e5f497b5cc806043f172009e1be0b549410ce75fe55b851900886162025c426773cdb8081831127c3df2687669688b629f83fdfb45df2bc17cebfe33ebe3dc92bc924e1ff6dda13fe212f8b64a8e0ff65adfb32e9a3f029f87f1ee7e4f34a4af8db707cc33e5f6881c877a49b2e6b5bebbf7d92cf1766785eac12917cbea081a2dc7d51856ab49005c400b92f7e89470821053f165803428ac6025720a4682c10a35129d27dff58200884d497b6f7220e10d2d044febfad3c0c123aaeebbce747f88b88e3340834f3dff5cce6372f62a01741bc805416341580a3026754c00aac404c056213f0430132c0174f944b9b66253f89375b8e5f8e5cc485a258c94f362bf90935d23eef3baef3ede38d6889dfb8f879f945f1cbf1d3ba125725f7986317bdc72989a0df34511c71dfc7258914d7fd169aa7c5aec4695572e8bfafb9c923af7331be8854e26e5e2225c329891db7803c8a39924a717b1207a2e2695ddc6cb8d895b89bf8e5c87991e3dd57791bae49a468f867df95f67b9b46137ffbb8e53de4b5169db81189f2774ec4127713fb4b5c024a146c4a8441d2642646c16690605198442c499c9199e249a4b62771318e3a5a582236a001917f84e2486c4003a290209e46fd779d8afc47192652f9bb1ef93644cb6c9c28de6c4822e56937a2cdd36868bc124d97bb6fe376cdc68972a4a189de7b43bcdeb9e7b9fbbc1f25a168683aeef34a9c15918686263a20c623f9cb4ae2101e871c31d2452f6364a4856448f9091431c6181910637c91461a719bdb686868b048804875aee33e116994ad7ccc55b46fe7e7f9f3be12173b47450f0217422805fc3cc00c1042aa892622886bd910af7f1739f8794089fa9ebdf8fa2be9e875dc16bfbf8943a8ec12e7ba6fd31ca006febfc5d7f1268fe2b7fde8f34a0be01949a4a86c4e146ff6a87baf14914450cda66d5da6c2a3b23927317a5af7791fe5e6d3b856d242db5e9488b2f66dffa12df3526a36edf3342b587e251e17714dbcdfe2bf5b027fa0811f29dc80307f59491424fcc5f33a2a9b73c2b56f2b71a34c65734efebbbefd165cd7b95793454ba610650821120cf08201210654e175d4560281182004421a9af8e518f9c3200458628b31c89828800108a1869f1b33404829494922a2fc13d0f146a4f3571a791d556477de0d13df712ef1e6bf67fffd481c72c4471c62e44897f1efbe8a267a9e7d5e16918e08e12f5cdfb411d72df1f81fe12f42e2902346826c4f82227ace3df95f227ace8db2ffeed56c1a57f395b8cc4a1e717d7ba1b2395112239514fedfff7b26e23892f7bf84ebba0f7939c4f5eda58421843012d9b8b841f99478dc8844a5fe22d288db62a0a1f9de20e5efa2976d3624df1910c9c70584d1cb3648f847e12f126952c03ce75c3ceff72ec97c41504ae0c7736394b7f8047ebc504d57fabd7df7fdbbc875bf45ee3e34f3f18240b87d8fdc01e0a7b3c28e44366e8b5e0ef17fae6dad24f3e9d8f874a12d7f1f9af9743cc027e0470b382084144dc7459a8e73e93ef4691865f35bfcd0f74bb4600184476e9ecacd4be1dd3c155df28edcbc14a3ffb4e7dcfe681103a92c6892801f2d82402d48709c41b2426541438a8190739bd4048430065719194a8b1f953c8adc17bbe71d1737adc4e91c6db88d0ae7e58f12a9fd242f7e9745fb79bcf9e20096e0ea7903d85944fa2ee22a2313f93fa7bc2636ed7b26917a2a5c954d8b5bde5cfe32e762c8cb4d22297ede7311172492fea98ce2132714dfbcac2313918af14334df85be8fdb62d7a2101e24be27ca4b224533ad124df4b44843c3799197ba9948f1df9e44caa1183f2f8be287bece451a1a1a9aefb84f26529fc789e2eb51f44aa12f7edc16392bbf7d1bb7bbb67de88b349f4dec5a7caf94f7eb4823640808341384263ee9e6f3befbefbfef9d1b79da9643fb47b166d3a8ecdc7d5e4deebeca8b34d126f2856a3451f46c3c2d3413296efb18b7f679daa68dbaff9e8b44488c7ce762c77dfbabc42c6426dee8c8ffdbdefb8ef45d901873dcfe6dbed7b166d348a4fc24529fa78922cd911923de88eb7a1c7de88b9e48a47d5efc8d7b2fefb8699d23f295b8c8d5c48fdbac704922f55b681e914d8b5fd36551ccf1abe4508e9d8b52b81851dfb4f89e66d37de8e376fc5e22b56939b463175fc7eeabfc16bb0f7d7ccb712b454f8ba3ff34103603052652fc79f42215394f94e3904891289aa789373a7e2f13a9cd75a458b369afa3904f8bdce73541caa320317f99472f521e293f19d27de8fb1aee8b5f8924ca42368da2b23951d7957614e58f9b899492972e8b4a5bfbba4c8a39765c17894a9d943f04fa5186d94f7ae1663cfe0fb373f759c1fed33c8e34e25c3e5129f757b27130226d8948945d3848e8184268943daf548a9e169f73305d880ed9a086c7c233e18df03ef817bc0bbe05242e0a294090088a45a29002c42105882012178714206e4162040df162cce28ae7dc0641b8437332850d06fec6775f8590205f7e22208410c30f8f02e4f979bce1f93b518ebc0210c212ff2e6e5adc5a0de7e486c475dff659eebe4d03fd169a0804021d992171df7b3914f35e0e9178c7ed8f92bfcc49fbdb4a9c4bff281ed7372fe3badf22dbb8cdca973b6c540302cd6420d0f69f95d76440083d8feb5c209c24d085042622a206a2c72707f7628c35070458a5fb37ed96755d7d9f52ce07b07df7e6525e8ba935adabe49581c92caf65d54a795535b556e8ca9712c4f10086afbfd675593273a3ac8ac6afad730a5a391dc0aefcaff36bab5eacabaa391cc0aecacafadafcfca9ed947f475b66989448dbcbac246703d857574eba39ae5bf7cf17cc946ce36800abf3fa7eb79ed95a39eb4e5199c46460144bad71c5bae2aa777b95c1c900662d8cafaea6ec5a76ebb175c7c06ebd7a95efa5fb4e7eed8a230636e5d5b23ea75695afbbbb8599924de16000ebff137fd5fb6f6ed96b6f261dc00903c377cbbeb1b528ffb7b362313817c0ae296f85e57ebaebee7de24c7ac10103b370a6b4baeef5d2ba7d765be71414753399d50770bec0aeea75af76cf96a6b55ad4963816c026dd3c578ff7d6fbaa3245515726f1f400c70becaf5da7be594f9bbf579ca26e263d2b9c0a6052fe45b3cdfb921c4b6cb9b4b8b42469716941d212e3a4c5de702880d99778ca29ab97b4aab5df2b9c096017a5795716b52eb726d794a2ae4c5e2b3912c0ea65e56eefcf8aee5b2b4e51949d13059c2e308dab2af9b5309dd6ccb22a55112702d8bcac7be5677bf99d585b1c2eb0da7bdd57eefc2daeb0bc6a0638572c6eed63ebfa4a4f8c3359e7c0347d6b5ad62577b5af7c67bd03566d7d4b6f6565ffeba2d20e58efb3cfc7b2dfaca9bdfa4c253f92d66d099aea804d0b678bf9c5f3c69d524a07ccee896fcff8da15ad2ada4357d6bcc678cad75cf7c95cd6ce01ebf6ee3bfb9e365bdd5efb5faea275a42c83999251931cb02b6ffb95cc9c575357138b7ab5e280c9fd55d32931ef53e33a4357d670220b0e587d4cf5a5ebedf356577fe84a5ec339a9a9e19c9038188aaae1446fc0aeda67c5bdb2df35adb386aeb4754a69ebcc21cfce1cf228cc94ac9adc80edbc2dc937afd6923b579595bd52c97b3f150b33256b99da8059556bb9f5ccd655b5951cc34cc94a131b30d92b3e2bbf15ef9c33bdecb5062ccbb973a7595615d6b6f78b3339bf98d48059f492d7b4ff16e7ab3345dd4cde4c726055a5d796f3e229b7ce3ba701ab72ee353fafa8fc9aa7ac538c090d58ad24be55e71bcb5cab7dcf807dd5bbeb2a3f57f8d22e4357669e86a519307d6d8debcc96acaa9c562d03b6bfba14ffacfdda8f65c7938c890cd8be964fdb29d5fd4aab27ad63c0a8c5f352fbf76d7551a9294a0c98dd73637ef1a5a59c93579c493bc3806d79af4ae66b7ead3dbf0d5d29a51713a5a525c6c904c3bd2485e5fdf429c5f89f4ffe1901d317b08b5a76d739a9ae2ebdd64551540d4d5ec0aa7c8c29e5365b92528b531455c94c6e4f1b516b61307501c3f6f67a37eebd6bdce57301e3545e5c55ff96a5553529146a0bd8252dfa9ad38d73ad98a22ecc948ccaa4056c6b69593c3bc5bf7f6e8b0a8aa2a8cb0363ca02adfcbeaeb9e3ce3107262c6039df9b2f5abbcdd99a57e56591cb657560ba0256779dd2baaa8b729a35de38935318931530db29dd18db3b67af33eb9b1c4351d656019bf4ca356fdc736535cf96ca231315306a2dfffdb292d6ae7aa653e22960dcf28a7eb570affae2f222719d128a22711de75d2e31e9fe263b11e54b0a98ac369dd2de3a33d6d7ca2860af9fd37c6929eb75b5ae50c0be5f97acd9dabbf65b495b63715a46f22acc944cc8f404acb2baf7ff6a73acf9cb1dbab2464e51b6e49d99e2c0a4b6f7e2cdffd6fcd97a276055572e31e5d6dfdbad97ae5bb29f24435117cc946c9ac0d4044ccffe77cf796dc7d6572ed45ae16c663086999255999880d19e67e6f25eb8bad3d2f3435e6e2273f351148561a664dd040776edfa16d7754f6dcd7e59a12be5c44bc06e7f79c9ca2d7d596cb3b66959669d204902c509136ba52595805dd25ebbc2975e8979afba0a9829d994290958c5ab8ef135f5fcaae7ac1312307965cba254d789ab3d0296b3a5edac2ece7de6feb27f14178aaa2e301901bb66bf74f5faa21dbfa56fe8c65054c791aeda7da42ca6226096c593da59f1aff4672b67184565d9956d607a03abaab5dcc29a5a5aa5bdaa890858d53bff7dcb5e52d60ae7d09523aeebf4bb188a6a9971d232e2ba2514f5755f65e3b6a42d988680716e35d5d5adb756fc56be50300901bb5de2deab65f7bd6895755a6f0a024627adb435ad9cf6ab9e2f455154253359cd4ad6600202c6df529d5f72def7c597c427987e80fd45a5d52dae36cf16577b01930f30ebf68be7d9b3b5e69db6a2a8fd55ea746572039bd7dafb2b7e2bfea979d5038c576cd57ffd7d5a5a5d1e607362d9dfe2ce7b95b79a302ddaba9e8834d2ea03a61d60f9ab5d3def9df2da2dae261d6055a56b755dd6e39eaddb69e8cb3134f46512bdf966257380493a6bee96e59d72cbb23a7425d7378acaae4c4e2298dac026edf6f5654d59efcb8eab92453dcb359a48f4767e9bc6c544a192fbbeef3e4feb2e1c609ccf5d497d2bee3d5b5a967d9d16de942d334cee8481890dece24e2fddb673cbaad45a8aa2288aa2b644511455e1264c37c0b494fcfbb56d65f5a52f1dba92cab4e148b58ac90658bfd7acaa7b5179f1ce1b731f9615e3a2d796506a4b96e5db53d959df2ba61a60b7aa287e5da595675555160db03c2db72c5ae13de5adf4298aa26680f1eb92fa6be63dcffdf486aeb4c2e98ccace227dbde8d325cfc24cc9824c32c0eebce6953bedf7afb4ac2eca5bdbb82def29633d4be545997f95aeb4ad8499923d996280598bad2d3f5f79d53bffa228915d03cbf8addc39b6ec9e56d7ad06f6d7fcdee5a6179e783ea5696035576b5d92cade2b7d2b0cb06a37a596d5e7ade86b5d5f80556c299e15bffa29ed3ba381559cd22eed45ed75ed9d7197372d0916930bb0daab9458733af15bd6ba147593bb2e5f0b3325a3995a80693deff556bdaacab2bada6760d5d579d5785e6d71b9f56401a6f9b43a9638579d71de925a3dad00ab6abe6ec6b5e67d2b7a9f449a4201930a304d75bd3557f84e9badcd6f56f7a1dde597e93e19296ff77929c064eef8afdaf1ae56c569460126eff7aad2d9f7b52dae3e874e8059554ffdd8d279722b2fb6c25f6ab61c85a2be66cb1d4579244e5e9829199f4c805d9756d39215dddabad5d6eb9a81dd8b56b99a954a8b79ad3674e5d765570930b96bb55cdabfb2f22cb1ec3e6f220166a5e65ae6cdf5edf2ce9a599943d3bb5d0e6d2a338d009b559f5a6a5be5cfab9a93e334859992359944805dbcc2bd5e56ced5caeafb1060979d54eb5db7c477e78a6aa24ada0904d8ee966749abb7d2eed7b34e6cfa00a62b96bae679b775ed5756e8ca17914a9f94772a03bbd876abcf7b2f5e4d795d9307305ac9dffbb236cf6aad8debd401eca9a59772de35cfb253ed7100b3aeeaa5f59694577f7ce5ba014cf3a7365fd6e6346f4d39d50076df626ceb7c8b77bfecb4c8c0b4c5b6e6ebba96624b663c33805d54663d299d95fd6b539b65764e6360595b2df1fecef1de77f6d095530caccf4be995bfaa38af365b0c6055de55b72ed5bbdf4adb0f5d69e543595653d2cfab0c03d3d3e23dd35c37b5ae9d77e8caff44f902189697e67ceebb6fbebac66060d555a7d5f275af9b6779bfc072956d75d16a31e6965f19ba92fb362da3b694bdd7651295a3d266d1c902d82575a596df5d27deb3baa6b4b2c90bac56fcb26cb6b89a34cf5e799a930b345500eb78bf65f5fb55b556ddf39a2880556de94a5e56ae17bf78fd1ee3690258c5b5a4d29afbd215adf2ad260960f9ceadf9acae4afff9455f442acd54531798de395fbeabd571d525bd42575a28a60860d6579b5fbbda75665d5d7de202a356d6bc6afb3ff1adfe4e57b0291f6b6bf7eb72abef794100d3f3f3a5f79cd7b497b4f7019875afbdf25e4d359599ee3a1d806dfa56dd15c575f28aafe8b55e65a4c4461a805997a67fb7c6f4d2356b8984e7186c61a664350cc09ef76ddd5d5da931b626d5ac7c93ee6d3827d91698b5e6b5faa2f575b59df61bac6fab6fc76f3bd79d5bf7c50a666dee5c5b56d7775fbb3fd7b797ad6d3986a22ecc94acdb60d694754fb9b395fb757965493bab605762faf467d527aff91fcb5cc2aeb9f7f596ee945ff2e20a33258bf261d6ad94f749e9d4f6eaf6b22ccc940c0b0fc3d6c579d6f876ab5a79768a12897e5716664a6645472d0aa356729bf9e6db5a7b663b2a6d56a6056669e69555b7bebcaab2770fc95561a6645590b0eaad2daddcd39a3bdb3ae90b87f52ee5beb27e2ae5ec394f0a332563b26196c575b7d6bcfa9c3c672b7425cf248b1a61d6e7af2efd3927debacad095738908c37ccb2be3af24ff7a7b15ba5294bb9aff362de3993465f7df85a9609bd26dfdd5ab5dd9abbe15ba92da52f68dfaad16805db8527ae55c2d7e5d16e7a12bb9963de9e6bb1b128abad9f28cb560a6649886f5cbd299f7ab6eebf6af13975a669cb474ffbdb850dc5e12a5a592dd47b24219901a6c56cbaab4ac54e76b59f9a12b7f6f5c2612e57dfddea06c4b2cf6489cd5316bd3f977f33a6fbff9caea316a595725edce17679ce7b5e4e4d8d69d5e74e78b27ee57f55bfbf2e74d2937b6abe7d7e4baf7f915d5d58535d62da5f25e325b5877b973e84ace813276ed6b7aa96555fcfc6bc5b98b06a39a5ad765339df365952d59659894f3e2fabafeb22a39f50c5d694d0560f8ba945f95a5b7b6f6ba7a4a99055679357fbf55efc4f8250f5d49e23a5ecd0b0b8cde3cef674d2f9dda56a49196f1ef72c8c3f25e81d5cac216cd7c57b9e217f7cd27a660fdaa97ca6e61abba2426801558af649f9b56fd299795a5a19077a5ad02ebb857f22b8cabcd98da19baf2374eb4336ec47524392bcc940c4405102918bd145f9eb76559d2c2fa6714536016b76a75bf579a75fe4acf60baefbb9ff70a736b67be32510290801852e97baffb0000450818ac57f3725d657ffd7b726b953cc1a4be956afd5adf8b7f5eee9994b63ac1aacef1ae995697d6963e96020198c6d25e9d5acbbec67fb3ed4557de90b85d25afa59699165d4b2dd7fc178c5a8e2da6ba675bebbd72e8ca3aa409b6abd436577c5b2b577e2f2b986055be2c6d71be749eb257567ea32d334c5a5e28aae3beec4569716979699971d2f26da590ccd628caebfe23659e295b499829d9648125989dd65565ab77aeef2569e6beac9a516018df55a5f9ddda6aebabaa86aed4dd7bcfad34a2c405bb2e3e69d5fdea8b33bfd7ce2549b07e59d763cae5bc15e67c86aedc5e94f1ed333a6b4d8204cbfaf6ae2d59b1ac99eb9e43b4660b2a16cc944c4814d8ccd56b9aad4bf7edf4ded095574271008cde2adbabb155593acfab0a5d5965d3b2d0feb2ceba3e253e82f52bb3ed9262b9ab9fb21a755ca68db8ed46c491b2ffb245a98002d3b392d4d2fe9ddbd97b0f5d39274e6204e3f4fbbda8f59dcb7dd16a3e8149a9a9a4fcd2d6efa96d0761f2bbdd9d5e5ae94ded96a12b6fba56b3699d9649551eb9b0a71a6b4b25e5d8aa64bfa12bb1bc117131de126a66c9126f0935a78b0c932952784ba85a27cc948c03038c5df4e5b6acfdd2ba95757de8caccbb98ace65b1b573d73aef9d4a12b45a551cb0c93966e49d745a527920945d56c414532f1965094aca1288a9217cc94cc8ac5f296bd57d2ca169d57a555e84a3de276d6e5df3451266be4aca4928a3dbd64feae77c57cee2baf272866bdbd775f7cb19db85fd992d5c274af16eb7ceb9cdbbab8ea3e0f9b18afacabaa56ca6af53ba55553d2af044b4c67fdf85e2ef9a5e9aeaed0952d334c5a288a6a9971d2926d5a46e23a3e69f7912c27158677fdb77c6b2ce7bd3a0e5d5949c9c45b4265cdac9f57ea2e9829d91345303bb5ad6fe16babaa73fc1de7d26529545a9829d9a5b06be79d69b564be39e75b11c1a825fb75779d795f95f61cbab2cba15d492a866057febebbbcb69eaf79654357769f975d2d334c5afed33a2abc4cc5571ab52c89d252559829d91406c032bd16d573729de5df6943576696b4d309aca2bb63fd5c5b975a15dbd095950921d8b532dbb9afaae9c4b8ffb669d994f61b75cb06c16475c94b57ba9a154b59cdd09521af44ca3aae5be9a4092c775bf54e69b57fa7953874e5a789485e259f731bad52226102cb9fa5cdfb6a6bb7d575579375390b805d5ae66c655e69ee5a4b19ba926f39e3b89cb76586490b92169796999619272dfba5d8e42897152dd8acaea6795672526ca9ae7cd36cb612b76558820880c9af7d737ced7c7dc556b55a6698b44cabd471fd268b489ea684a2be51a7a8efb8dd52cd528b8834d25a669cb464b392469a352a6dd637ea961e0066e97b515ddd49279ffbeaa12bb1bc4b605dd6cbabb774e697d77943577ea39ed56c1a95eb3b6e5398295915316bdae7376389ef25659fa12bb32b6f85999261018c382e13f12ecb7a2891199144a9cb321f90c83e2b2fe4082364f621248a48820839c414e20620082380500200d203f291dbd3463f38e143901e9af81179a829c20747a287cc3851113cace491005894d831001d327baf084f975fb4332b7f44c7ca27c191d9488909f2d0c18e2aa460fa51de3c3baa40851f3cc020e86003482a003f4c78017e5e9068e10106210772208161a802cc0a64407318a37b6b7c807059c3070b18d044c71c75b8811de698638e3b40083970f010230147988336a18a2b40210323b2e83920401b58342182201ca0c345010eb0d4a00231886ec8e670c3172598c30e4b80c31c73cc618729aaf0f898011347e6e0ec484310612861461bdcd0cc70061b641733075bb08801f47282318c409b3798630d676032871d5cdc30c71c73d4c10569e838220568b41c9169acbd41a72121b1fd600145e2f0d981130221ce3002680801b081031bd8b8021a0f50c214272a35d8236ebee062f8a841025f4022b382c9009c60d2030660e179820f8c0c410d4660b2840f6e88a1060218800a18f001bc021b19a0c0942166a0833de2268c3640407c480315bc900004d4a0301047f8821958b0800f8e10411b519c21063896d084037114e0034ed8401549cca0528797069841066f58000c9c7c010a4b78ac61003fac41875e0624baa0013264e102253c41c11569184106561082060f88c108129830c400c41882969151031f5d00c1c28303516650441cef83011e70861cd8a1024d2072022b7a0794a0832498608458012a7c71b0a0088f30a4400586076ab0c21058f08113643ca0010c58020b4e3005053f50818727905107074440016f24710303e5050d90030764c0c0093b14f13942040ea2e40d30f49d4936b0041414f001175d1c295245162ac002044c08e20ba30304804f00148417e480c2852a8c113a410f475ce0015e7c5a62bce0d1ab103c6088136c1880cc9c800a02d7e6f66e7cdd3eb9f45001cbd5627cad6a4b5b2bcda5670ad8f3a9b7bd9594f9ed9cd7013c52c068af195f12f33eaddaefb7b8b4f42d049e2860d69c544b6de1ebebcc525e293c50c0ac4a5e53decae7b526d7fa09d8de6f69fd943edf55a615053c7160777ee557e3897f5f5c598f13b06e5593764b4a89e995b8da81a70998bc72fd6bd32b6ddd56ae4cc0f2bf9c2f1fe389afd92d1cd8beaa5d59927fc5f5cf399760a9a52c9f584f59f55959327b94805d4ba935bbed17ef4b563d09989c73f29975c695ffd5d783048ceb9eb39c7a5f925796e67a85e70818d7345757df5af7c4525b1e236094d68e69b5e6c52fe72902a6e9b49bbf9e7c4b7eeded7903fb7dadec12d3ebabd92911304bf7695dabd2b3767cebaee4103079bbd43a5bb6b2fade530818d51a5b5456fc7853da6910305955ddda1dcb6d39c5b60201bbbe5bfb5f5e99cb3c2dfd034ccf8db5be9bcefb7dea6ac6494b093c3ec02aae55b65be3ff8cefbf77f35278dcc02c8beeb77a5ab54beb738565e0e901462fd5145f4c6da5fbb53cc0beb27a9f777ea55b5f176d71c9d6f0ec00ab5472fb155717bd5745b3470718bff896f6d27dea6cedab7380c9f9b86fabb277ffc47787aecc666d039bf8a216ad78aed6ce9f150718d6d5b4aced57afae8ae31eb26ef7912c2a1e3630cba5aeb25617b672edf906f87afddf35bd57d369038f0d30f93fadfeb7aa6a69b52c4f0db0b9a7bcd7bdb6959b5f7d591bf0d000b3965ab8d33a3bbd55d5fb0ccf0c307be9dc59e79db19cf9b2a12bb7177d95ec5ae2910126ab997997dabad7e6d3aa4ee08901565917cff9bc6adb79ef96670d4ce7a9a9b6dcca16de575f6a5cdab3adaedd755b9e34b069fd5bf3ba7ef39cf9be60805deb6ebeab8cb1fda9afa55370dff612e3790156a77e4aab95b7ea3fe7dd5ba9fb325df2ee6c9961e2b938c0830666a5cdf956545a585f97c55d80d54a2babf36b626c5978e6d09598d385a7059835af2b7fbe159ef8ba77bac0730666ed6a569bad5aed7ef3631660fada54726ae569af6ae97b5680d90bd72a5f9def55597c4e1560fc67c6bbdaaaaad9baf3a600b3a47e6c6d9dab3c7bb7f2db940df0a000dbb5b2bac2995697bea55526d1f09c00e3cfe5c5bd7ec65ad66b020ce369595a539ce5e5947e0c0a3c6660bad63cedb5afdb679cb498e1290176e1cf58574fe5a6f2b715bad2e3be92d6bacfd3f835bf531260d7b692e38a5e6977b676f58c00cb95be68bff5d24bd3dd6d8924020cdf2b6b5e2f97bd534bca0c7842807dae68852b9a2d8aaf5e61106077db3cb96537ef1457d6fe00c6ab4b6f7a27a516b5b4656d4fe2cac0fe3eb592f6fcba4acaad19783c80e5bca9b597a6d2d22a5b4f07307b517a755ca9d617959303189f1b57ab71b6b35b59c90d605ff3f7feb6636a75c7520318afb0c655e574f6bcf7d3d09519c7ad8c870cccd2d5caaf66aff9aa55b7a12b6d7ec3b50b4f0630dafbae6ad6b94bab5f560d5dc9f12a6b14cf18d855d1abf9b52a8ead7afb15ba925b9289470cecb9edfaaafb2d5a559d6e0f06b04c699efc2bb77a5a8bdb296fe00903b3b8d472d7eaf3ed32d3eed2023325dbc27301ccbad64e4e25e6d2f2eb5e3030fb7a5f164f6b5a2b6f6545b90a37fa281b9416170e78bec02e6aeba5ad7969b7b2ebff4f93f2453a051e0b6095c527bef075ed6dfddfea055655f37f5e55959363dd71a491463d15c07697f3f1e5d6ac57afe45300d3bc72997bde57e27b69e59900f6cfafcfb8d6de2f7b79f74800eb734fda73aeaeae2be6f89c5f78bac072c6d755bb755f62eb372eefab029e086017e76b5fbce57d9c2d8b3d5c60d5e697f8ea5b534eb9e5b98255f9de5ea7b6fe2fbf2a390746b7d6f5a5ad3263ab767c076c5797dec7cfbbade4a69665076c666d61fa55adbb0e7dee3aa7b6d7ec980e58cffa5e7d7d25e794faf57b9b36078ceb59bbb633cbaf53571cba92ca7b98cae6441425a71cb0ad77afae6c5555aeb4cb1a070c5bfbb26ebd5d5b5badcbe180e9af72d7b55f8e39c512bf01db7fc97a67af15d756ef2b74e555a57b4f4e1074dc80d969d98ee5be3587ae14e999ed6572a0d306ec72cbee89af3e71b5317e622f6603a6f5acb4b21ad76ce9c7d51a30cd2bcd37af543f9d56d5ab1ab0e7b7d64eef9c99dbeabad29103ebb8ea7f693c2f6c6fbdae0b9e69c07475ad9438cfcb6e2bbf898bbc1cd04103c63be518d7fbddb295e44f6df7913a67c0b6ac2efdb5767969d6d90c58b7b4e3fb16c6d5daca2d8e97bc8a079d32609452fa5cef2af74beedcaf103a64c0acce587e754d8a2dcb3ead5202a133068c6a5c75dff7ead2da9daf2274c480e16d7997df65a658ef6c1da113068cfee5db52abea5afbad174b3060935a735a99cbaafad9b93442e70bd87fe557edd4cecbef6f37bc65c6498b152e0945f1b7c26997164eca236ba1d1f10256716c27963b6b5df3c45b947bd0e902d671b5e7cdb6a2544b2c3317b06ab77e5c494bee1b3de78b74e6bf4db105ac776addaee5f3aae9b657e8caecfb9a2bbf6722126517aa058c639e6dc69267bbfbd4d72647b12c2f3a59c028dedccaf6e59e55a56dffaee471a29de1e972ad2174b080e92b9feb7acdccf995960c5dd9c26fa965a4853caa4a8bbea5968a4ee95c01cb9d7fdf7fdfa2556fad43577ea5512612e58dbfd2936d49ed5801abeeb634d7555716ced4e2d095dd945aee6664153079edb715e38b5e3cb9bdae9c305332281d2a60b65b774acb71ae2e4cafaa3305accf7c559eb7b630dd96d6d544818e14b08b622aadf5dce2db726d6f14b08b5a5d4d5cb3a4bc4f3ca180d5d7384f6937bdac4b62fa044c4f5c5d3a5b8fbbc529b5716017b7e4ef7effdab7badf710276553ebb94944efdb2caef3401abace5bcda345b5c5a4a6b8709d8ae7abda6ac159515e698b7b8b4b4b8b484bcdc44caac051d38305de7fd6a79eed2a2fdb2536674bad15902b631de9d7fedb6637c735702665df3c29765594cf7cf5a51d0490246e9c557a5f8a5ceb36eebd282b5cc3869a1282460135f57eb5de9cabaf6655d2ef936054551d47c91d66ab65227a37304acda127fd6fd39aff2e2d30818bdb79a945af531bd565504ccb21c638b7bc75d537a69e8ca6b46e70dcc6e6e29ce534f9a6fc7940898d6fa92b7ead5bcaeb7d6ce6ebaaf921fe80c01fb9f5772bbefcd93cb2a7fa51113521e591be80801cb7adbfb5acfaa57366b3a6bd0090256aba4525b5e7dc61a6f0c042ccf99ffda5735ff0718eff5abba2fdd6b75d9c7a12b7956e53545c707d8acbeeb8af76d6d5dfdd72a4a8b4b4b95809618272d56ba81557be62bf75a4d8b4b6ef51e6036737b5597be5ceb9a25c593949f28b1929447d98b7489e395fc3a3cc0b695ad9c2dacaf496bed3b74a5955ee8ec00d37cd359ddca3ec6b6da4a4e1d60dbe2cbea8bef45edacb3e600c393bfe6f8e22fb1eef94357d66c9a95379ba2e4cdce44a4916649ce053a6d60725a6a696a2f8b63fe3f43575a323a38c0aaeecf7bcd5ffbc6b8b2f3061d36304c25ae77cbc7575ab9cf4b512d334c5aa4053325e350a173036cca6b6be6d9b2f4eed6acec013a36c07e3fa796ed4ff1bea4b44c6e5e0a8aba792a53bab454b35303ac7a6bfbd433577dd3ef759ba4fc04464a521e6d940658555d53e20b57abb7ac7506589df867cdfd2ba9af96fc898e0c30fb77f69fbdf36b6bff1c034c6eceabc9e975af4cefcd53c932521ec95949521e591df7e56b0d4c5a9a566d39b732df4da51ad8c6b5b2b4fd8b5b76573a3b69d46929ac762dafd56fadc7b9e7de810186b3bede5eba4eebaaeebe9d17605ae76bd7fef86acae9353b686094ef4bd6ae737e6d5d5ed9702e14d545c70518bff79fcbce2ba7b4ca2dc07afd4ada7ef7ddd5b4d6fe5ee67baf9220e89c8155fff74aabb26f652a7365017671fc17953ae3cd6b967c05d8bc7ae7fbba98dfa757df1d1560bfbf4fa97bde7d723b73270518ef5c5a57d6fd535f96a551805d3bd7eae255bd57be179f27c0feba3fed67bc75bf735ed13101565169596daf5c7f57eb7ec70c8c623bb5bd2cb778ef5d52ca804e09305e618e67d554cfca56977e4087045865359e335b6da5c56dbd240c3a23c0ecdcf7a5a5f5a4d45e76ce343a22b096df6df16c595b4380ed69adecfac2d656a303026c4aeba7aea4ee72575eef179d0f60d65f135b3a2d29adbf28cee4169d32b0f9dcd2b8f66bcd8acfa93d805d17c79fad2c33c51553ab03f6a214c6f35bccb9eed5d2ddef5f34eb7000db32ef6c3dc67fbdd5bb6f00bbf84f2ee79655a5f575591d0d6058de2af3c4797edd95953b6460d69d9b62ab9ab55fd75e8d33693bd0c90076a5c5ef57d7aaba95bb6a5b479d31b0da2f9babaa57585b2badee88814d8bf659af97b9e3ebb27607039894d677cbeeb9bbbdac29a5582b3a6160b8dad6fd3ceff36cc9cd974469993ae85c00c3af9fef8cbbb417cebbc24cc920d00103fb39f9b534b5b3eace2d1dba528b9f2d334c5ab4c062288a34da3a5f6015537de1aae69c2bdd15772c80f56efd957b65f5c496beaa8e17d8eccf714527fd8bebbfb25301ccc2ddba57d35d6dc597c4f4a543010c7fbff8e55a5e4ae5cbdf9d09605c575caf4aadbf95bf9d351d09603a530b5f385b18e70ea3a8dc3dcc944ceb7481cd5ad5abc2d55ed69575e8cbcf6bee302b776fddab1301ecb7fd7b599fb575ebf76b7b51967d3bcf8a25cc94ac49870bccbaaaeef95af935afb9e7fe51ae2b9d2bd8cfbaaf4d2f4be75e6d9f1445515ba3a839b07df7f75bf5aef9afb5d61db0792bb9655537d713577587aeac6cf7913876c024be24b6b2b5d4fa5ab1a5520a95552c4965158b72ea80d9a9f3dedbca5d71ca758ff272d37d1bd66919f76d2f14c57d9b562fc0a103f697ec95c4f3faea6dde369353ce01c3d93ea5bc632cf9b4fb5214c79103d6ad4bf2cd77de561cb08a56eb6dc7786e7a595c7a995401070e98addabebd7fbd9502ce1bb049e5553beeddee5b73afdc80e96ac96bf1a75acadde5ed00a70dd85f8c7bde5d56bcf1d4920d98e456a596de5a6a5df7f7356036eb2a37a6d4ea99e7acd4804d29e995af7da5b52efd49c981756bbfbd6fb565f54be30f5d698770d280e5feb96b6ced7add7c714ff459c765a43c92b222e1a0814a4a619b678b4fcb71d7d7b6b8e5657b7da36e71ce803ddefcb256ff8b7689b9e49801bb166f59e589b725ad9db20c98aefaed94d2a9f7a41deb90977d1e17caecacd9b49a1a4e8471c880e50b5b29ab8a6a6b6da6f59ec996192622d2e8e52689e7e518ceb95014958d019b7c5e3bcfea5ad7bcf4ec62c034df5356eb5a6b6f6ced19062c5f49bbc5adaff455fb953960c0aaa75797fcb2b2fc02762f7ad5cbb155ad5ce9ba49f90909385ec0fe37de56bebe70e5d5d54a286a7601ab72e68b2f95bf79e6af4357da9619265cc0b2a6d4a215adec63aeb57523c0d902663dc7b8f3bb79b566d515470b18dd17bfed545b4be35d5d389359c0e48567e7f2aa557eba3bc7026669bea8beae59e9ecb4caeb059c2b6095f64af76bd5ccf577adad80e5ab6fc5a7bd7a5ef3c2f23201a70a58eff3da7b5bf7efe5984b0570a880f55de5d5ebae2cbeb0fc6b0a58ee1795bb7a5c5df7c2d6b6e49502765955952b6cabb52ab9024e14b07cf9a55575fbffad50b015ad384fc0aafb9fafb697c66fffd638b0aaad5a9fdbdb37e757568aa2a82b93523a01c3b9ba976abab3bd70ef4dc078fddf5ae7fe78e66a320193fc62be65ce17c555ae308994298a44ca161c18c5957ed5f5bef32d6cd92560b7f2aaab8a5e5a2d0b63aa04ac5a5e59d575597cffec7553542661c049022665b5ad96f7e7a555cd99a2bae76a4448280a0958b57ada3cef57a12bbf6c5a550ae708d845fbfd69f14973bffa2be9d62b3846c0f4b5ead3bffab5b5b0753369c32902c6bbfe4a57f3e2b592d8566f606fd9aab2f6a59fcb7baf4904ec5af95ad3f2caba2ae59c5254efaa70868055dbba68b6f8ee9975adba10b0ae71be579e18eb8e73ed41c0de56eb4ece2f7d5ce5fe40c0b8d5d7c4785f2e79d7b9fe00bbe645f5fd7a5d754f7be9cde4f5017669de6597f8fa7c596bb91b58ad34eb3aafdc79e28c3945658fefaf10e0f400fb79715c51bd9f5e56b62a0fb059cd6a5babba72dd7fdd7ab9e0ec00cb926b5d2b6be96b635c75fe425194fdee76c1d1016677adfba5c49f2d69bba5288afa2e07d87d5cd1cf97e6af74256526b104386d60575e37cb0af37ae9acaffe7122198ac20126ed9db5da734bd9bf67ca0636e9be6455517b6d49a5b6beed77c501ce0db0eaeaf3e945e5acb275554c511425a5f5018e0db02a2b8db59e9652be69e7a12b45d9a76dda252d4e0d3049eff5385bcb2b2d7f561a60bdbab8e6aad2fcbfdad70cb02b6ffe74da8a56fc72ee2a431f97c4929e153d95aee3b6900cb06cbd95a955f12bf7b7f8ba489c18609765cd5a73e6fcaa58636be51a58adae96546f8b57d8aab2aa815d57b654e2bc6715fabe4cca9c34b0d9a975add4f6ca7a517e511806d857d5dfbc73c71ceb79d51760b8dad5efcd2d5eaba6954503b3d663abe349e75569bc658c2622c9749f77b9007b2b735d5db7da97d5b6328c6c01362d9659deadf5dc9de77b06d66945ed75ebbebb5eb6c2a12b2d89b1120e0bb04dedbef0d4d8d68d65be9ab3026c3ea67cca8bab8b5fbdabd095a38e5ba204771fc9fa382ac070c5f7e53ae3dceb55afe4a400d356575bb33565b55f525e374ee4425137dfe6a000b3d7bdaa9d15fe5c73b55c4a8b4b8b14a43ca2288ae29c0093d5d4bdf69a2f8aaf554d8a921ae09800cbd7cf6bd6b7bc5a55ef9e24fa50967ddc66cd5a33afe39881ed4c6baf96bdb69ed5d6daa40498dc95a5dc6e2cffbabb5a126015b5b0ad346b5d699d716e3202ecbaf4bf5a9b4e5bf3ddbb72448051fafae2b4efab5fd6c49d1302ac3fbe2aada9de019ff3a8643089859138ca71140519638812179100005311004038302291886462117d5c33820114800263986a8a469909a5b13049721085518618830c218418028c014446a5099da439b7ea5fa381cea1b014bb0d6e696a7e470e7115380439569c195cd10e77044b846f75102d8d554611b1099dc1e3798e9779a24a9a966ee1e8abc5b0f14f0609fdeb6d75cb3c5ab13825dca7fa4be28a2434f662bc6b9122f2e3e5090416e6cba03d68e14db3e4537449e8b0601fdb1a24f5d7c6a0477170a2019691a1ce993e3c755b45ead58e18f600a5c35273fe90695f644725ec1fa1ffcf9caa4d28fabf7fd8cfe8bc43110018f32a6af801fb9a55a97bcb3760409f35d1fb14de74fb7e92160f19010a6ea66d6bf72b916b2470bc476222dc309432f2a00e2bebefe92ecff4c47a7d5f7bd0a9403915dadf050acd3ad96adca18d58432b4de80305308a5de3f5e2c0d730dbc9318f898e0e0ac8003fec57a6ac2b0d5059cd2beda267a0073324c8e0297f738193ed137a0cade3e84f3dd8f09b1a021138dc02c335bc98a2ac9413d99d7a84376040fb8a8a7ff48095046180c54ba02a5fa679a406f3c201106859882c9c8bdc5966fafca26dce9d1926ac8323545e191fa8629cb614db8cc8d7838dd83dfefcd7b03de9aa0fb793a516de89c03ecafe284576482e693937190041338dcd8b798051cf4f999d80a2e3899809b6030c31c4849413dc6e5e99012e7241510440bfb70b4496803e2663317a46544b1e8a8cbb1fc0ba0041f3dd45d4cb03e28c136dc2bd9a8cb33cc2f250df5eb499020158adc416a9e990d0ab4f506d0f691d182563b8db392c543344ca8b7ce0551bc034b060d9410a1ad540efc1844b8de8277bacdf315c06bffbfc557a4de9d9b2b6560b13430bc4dca94b6b6604797c3b908742f735833a3a049011c5e79d9db8ee3007b346c094b8fe6f9eb15d8db3cfa727b13699049956d55bd33b947a05df5e5e509d5d5b9736407c7dce72dbb5f3a11f44ec465ffc680c0b63cf32f8edc73699764d929a6cb99f3f6a2133036e8ca445544e0280825f9a3d9fd04d314d6ffa880aac7940882cd6e0d36b0f9d996b5784ea4a0c887bb23e9d9f3179c59fa14a63a09906439431427a80edad6e75996eafd73067245b729133419e451702889c230b85f45717180eb83c5c0610373e80e8ee37707206c2ebb182f7f7049989ab46933b8de8271af2fe528e2f9f14a03534c3efec67288927317859542bbe8cc2a2e297d35216741e1086d677a3ffe8aebdd1c583644b6de0b72efd8f39614d135f1d3a8eac2dd9e10e49f8111c124dd9cff8eabd72983e6b91d8ad9e73dd1c8abe3cda9bc8b79f03e6ce8a7b7d4c95dca32911f95a65368e20e6bdfb5a1549621c61979996d6304337f4a53a2b5129a611a03754c4c9298a0a26724b3c29d3379fa7f0f034dadebb4da009b169283d309d5e7e90144e147ab36189f6023b2e227fa4122f20102ee73161f31c5948fec65e7b87fca5609ceec85bddcaed53847b833c746959df3e9d2eb953ee59495d424c6ad48db69019f495fd22ccf33eea7688d4bc46793ae38708cb92ce713283f8c6251fec9121a63b54dff417285baf549bed3ef1c12cfbd9198640dea7dd797eaef7d38ae74199e8fd7c4c9773b35bd2a1ff6b35230ac262ae2ea773b097c82ccda049b07d62726c54c3d7a5135550380295e342d3fa8ca80b1c7d9b48dce4d6f5882d1494584c9135fde3ccb262af05d4e26800edb67532ec80d8a80ba9905744ebcec664589f5d237e6897ff303d797796f0ce7fcf0022ed8b22b6780c9e42c53235ac86b3c20cb7cf871d97d586c539e475c7d7369744a2ad301c11e1f204253a8b7c1566b64117201f45540e14152450d55b0c068987ad2efd96dc81e7a8ddd327ee762f3bc47a20e76391860fcae583c42d4530d47cb5b2498814bed4890327924e1091823e28ad0e8271920bfac940a74a8a17a55312ce1a3ade0bcec50bc5fef688d8f3f735bca4e4be60081143bdcb8ac1310d004ab1ddd9c0ce9730d5e799487276805489d2fd5a0630f9b63e9364c23cebcdb426ebe8c50de8d1d81468b9da4589000c5564442fd4f4453e7a6d968c2bb9328b23272b9d7a7f75c735209b0248bd99b7e799e87e6dc2487208a941a4d864bf9da80fc6024c10c81d72ae79bd8fa32250478cd36444e6f42ca6c5dd62411e4d5d63bdff0a7657de12c6fa953cb4f8a04bf036caa7ce9513373d9795231b0f59f4decdc1715c74ac30f692c1b7d8409e19dd5d6b4aa11ab84b9960aa856527b61d9eb524d66c9bf221b75628e67c02fd204ffd923ced80611628b8b1246879aab26573c98dcedbd7ed13cd91ffcc4b04756199c8b57cd9e45ea37a0cf2c0bca00697beef34b4ef28b996bd9ebb9df1e3422428c0bde8c869e2a9d5f76fafb28a1142e6da577ed509301d573f6fb7891c8b4bfab31def70790d9930f6b550d1a1453202b4e7c7a6fa0e3043b106a51ed313b08cfa40f209ad9bfe4fb01a04fe904cc2d7c1751b7ba7a97d8c1d850dbe24416f207ac09e69bf26acb822d7a67d0cd7d10b7544eef29bd0fd70b741f3be1f8a3200a7323ba169fdd06e7d5e7ef45aad2ce444522e715cbedf5256033c6e9aff0d671ef3f72779a18dfdad66800a758b1fad92389b8779d07587c42937c686916754257e90b76987b5f9aa3b02b4a2553d34355b2e1cae098f04040850ea99b9072d792847fc93f1e48aa2e9cf7ece9ce36e9dead0ef19d2cfae43b16f825d8176b47d26e7643a60ebc6f521193d21e6708556f0cd7f320d81b4b0ddf80638dd07b404bed92a1b0baee71032f5729089d303c512c5362af417cf8438b707db2757c451258e9d53f9ea4c63dd58b14c86235a7257ca02a9999e7c2f5a469a901b35121422ac22d17a121cba14fa2879d06fd683ed2dc3886685388995fa4d912a2afc8f41ab137a75107e8483a2bb0253c17c304acb4109f59ecbb81c264d6b5c4fe083393b9760e5e04d028a5c083ee9a2d90c3fa359c4dc1f0e9b9e1b023019a98c5e49a7fcf0e0c146fa5b652045af2317a455def4040e1d4a2afd5485a81c1eb413324458d7893251df5e49197a58202220be988b56c7837bce05df09a3816342c9fb78bdb24be7bea647788e850d39e90e542159bf837b423863e71d4549f4276b9c729c82cad9bc44e586ebeec6e7bf1161d7404a9d0f8eca923c011b3f1cd7784bc8fd1e9a4e051d2c60c9fd9d4dd39a3778e342b503f3255abd546325bab8106ea84182fbf0d09deb72f33ce207aa7d4000350c0c3e6eeaebeed741689743961a3e2a73f08fd2471ab77820bd428e470b8e2185a210efc4d481ca717f2f8de28a23b802c837ef87a37c48c5b2e6797edfa14b824b987ee49e1a481684ad6d92382d893a29a58324a4b598548facad1338f8f2ed238b51b0cb86b3004c1fda037a6f3432b842108b3856443e8df5d8db5f09534d76ecc905458efe648cfc109b759395b04a2711f3db1f6847ede7df90e22c3df5118adf84e0cc7dab0d9c358afb9a7a428560a2a6b8d18be8ec03750c259c9d60257aaaf37e7b2ababa4beeb85cc62c99858ae47d5e5ea0bb01a9b632320ab6c356a86492d6c48293494d54fadd7b59eeb238b01b8d3c23c53ee93977c7621ba28d72894b6058522a5088e3ce954c2310f01380a14dfa51427a246e9e70642e2b376f79334086eff7d580f924e1f6a7bc54cd9d707d72db08d17ae5ded46d332b13adbeacef789fd888e6af6db9fb138afbebf35c596db5078eacda208a63db3bc7b64543b126a42debbdbb955796ef7faffe35e13fca03874618b47fed763d35423001e621e0de39449c1776767465e25a88aed560d27c7c04aa14cfb5798ba8afc03b247b44b1310d4b71e9db8027bf369a9cfc6c719f0e7070a790388c2c06451a81f700c0f4a98389614c00e6085a56c1b9d04f6ae8129fa101f91fd79de4f4fc7b78421fdaeb4ad02519fce7444524605e4108a5876f039fc2ca798e734b525d4c21cca9eb4096433aba115023979da6feba8cf1fb34233a3f00be73acc5711f043d9e4194cb656fe8078e66aeec21390164296a97fdbc0593f99f4bad424adaae525949b0e21b3d9a2e9d4b4cd4902d6b5451b0edd8fcf670f880ce23a8b78bccbd0ee9a126083daf2c804b087dc3ceffacca64f1964a893541f7b6d109c4f7f222cbf3e2121c09a745b7d09610c285f77aac5a974efbe9d41a801c12058e8e86a6a71ab103227e27b303215e8a121600ecf8bdc409578890ea41dfebd40ded28ec785491eea36451752db181dbd517e715f3693ca8f7a8756f2d1ecff8fd827d578f101e9ad118a390a70362654c84752f3fa79141f0bc43f2c903893cf9ee8aa8dc16da21e01122d0270f4a150aa9fb3c4eda02204ac13456c5b6530d011d61161c3069ec9c97ff463a09778f56586f59337e356b2d47fbf6a3c36597b341ac5f8cbcbe9452d67e318f0acd22e87eb2b5b7c3c7b59427ac9e99734584345c457b376b3ee8907742c10c85e6ed0619ff352da01e1ce9785f296f1d135a453bbabc911c88538fe3688c55da7164c95722080bc1781a5c87f4637da670dc7cd8f64b042d3c5c39afc9641ed01a22667ad6654b7bcc77e226431e22d3be3e74d2a2a7d6ec265770c6b5cd887eb8ea1d60650eb28dcf1344702bd91a3b5778fdb305eb3fb34a42193b80a1c200157fd1a1919cc3b41bd8986011648986347a763732306af0a05ee6bb611b42b7482042b0b9b54725a55f679f64c666968c4e909e84a2d9b14003a75d464090c135949cc365474f1a580409551374b7225d4f70052620f241d076b0c6fd488c06366bd9b2ecfc340c09a4b7227824d91aeb79b90fb00b50e3933ff2eb93294fa014f56ff31189c1b8131e5add30e27c4e26ab7b91eb51faf9b969466e296fc46a0af694fde1c7a206f3ee5d4121367218e3d772932ca5b5b6139cb9ea72b0f3b3ad2a0144f39cd37b78f2b58353c571e392174972271a4670f49495b2298b49c9bb916669c7267577858e9343d3414036f1c96732c1389a7e74b607a4801f0f01064d8f3b43f92cecf9880d35e2930a9451d83358a5616c223094d76e9ab9cc484d020544fa08134a79237bfbea3d7483785e35cfc8f2ea3d6ffd4b6ffeff47aff5740bd5b4133793759b45101571c999f60381e819364fc8794c707e2aab52531fe67fe9e1f6535a42ff348edcb632700972d8e840971654234ad555aa94811afb7e39f83a22c09a35f270f467b6acdc57fec4339a288f14f95bd772d40c9efee9714351c45d5b942865c16ddfc38e9c2456c0e615352ed3dae86f54f65654e5aeae877176a142cb4ace0593793dc165721429371f22921e2708d9356cb37caccb676f5626db9e84e9cd8554e32921680a8899e9387f78262df8c1ec366848340b7744af20b19dbd93641102977c0ce2a323e85bc68a0db53e0ad5516228bdf82bc9228e0298081ff0a16c79d2a8285d321b02bdd0572c33b6c8511f7497e2bc873a8204d4b61a1e71ad29ed8be03fa1e01e8e0eb7a27f63758179c67baec061121edf109a3d567c288e1a2bdb39739160f3c1d9473b90afcd82b0ba370ed46aac5e3abdca57670f5d087e882135ab1ca79daa302e3fcde5b99ceaaf0558d096f5bbfec6366e69c675701ff74bb9af3e741603fa799c5d9b780a2b30cee66001708d69a4e29f7b51668aa01581f337982bee119fc724d246e7930f48af949195431a94e8629c22955f7de1a23fa722638b9014cca2514e0302ae0f70e3dceda46f94a644a83f2fb12fae319095c3ab75524317b09c5856d5f5a337d1f858d48a5e014640a7ae30eca5145d230d145a45739d0bed8038e651bf771e5d088159c65e7c2b0985acc111a1947583b1be804087de193fd00e9bce1ee166259ae46628ca6940a6f822bc1429e52d89b7166675df2b79a80358ac6e339cd8bb88c6b8deb9a40f636ce87a81ffe26abe21041a9acdee0c5897786a1484918f9301c3d4b4ab635d6793768b210d802ea5b69b4fd447c0334b234d675c472eca596a2492e5711bd822d2b413c7d325a850ac9a7f2db36d4d9a1bbeafeb8d2ec3d6f68e880a9f32686d95c59acbf948a703e5e004a03ad4a3e92d55b1592074e19652897e80d5a11a34384a4e516cf5d03040892f4e7ff3015312fff5fd95bf06d8c58d8dadff55b12475d44a759095999cca86a385f1d75f6d16e886badcc383c6e1eaafa3dfeb69954e081735ae441a5ffda38d50c7a91169d09b32d8bc882b5af49eab0d78a37ea53076cc808f5b0a6edad821588261e52ab82a45b2629a02f2e0c094a889bfae57eab1038e0daca66370eec1010ebfa2d534f78a4805f93ece431a3d12d530a92210963e2d8f55f3e914c46ca245cbc75191795b29278b8f5e9bbd23a97e1d4eb29537d9077f7e7d0a22abb68dd01649c41cf4b801187967e5ed4d377c0c46f28ca0e1d17f579d3323b735a7c84011c6b27e980b3de580bbdf25fa935cf2c3782e2b9df8fa0908080a0cf09b723b91029b355a2673b8d9c96af44b970ef5868302462e09b20d676788b4b52f1d2b34550ebd543842bb9743d57c0ea19568d99c22909d94a6f24cfece37c31ba702cfd252bab45b5b85015c2bf42f98e9be70847ccac791e98361bef6ce22e956565607d9a613e95ca974dfaf18d659f66e18dc7a047199b3e112d38bf2e292ae10cc7cfb061f9a60469906a78995410723d7b5dcafc0fd19c0886525ddccd26fa882b78fddd14c506e93bb284b4125222e52886637855ec59d94025c83c9c6c85d6d3d1451b80305df0785ae5d7a5d712dc3cbe41e4f15c83ab7477db37c95078721277a8b12ecffdc14588ac6ec3789556e700d892e48bc4f50f03e120d1625c4a572fe1e213dc3162f3dac818fe085d212263577c36fd60cfe9884408b025c73f155f29933f1ab173841906d52133f781ae6c19020a11a7dfcc95dffa38605e2ac0fba8417ff8ea459b4743ebc6e4147561e2d08607bac97a3f32950ce660784113230adbadaf5ca27fc918a55d7646bb3cb26567ebfe8348c7a3cf94d84634cb0914a06db66f7d78ce018bab7b0109437cbfc2ce185a08545f6bc76642d777177b844ff1df62bd12d2ac1047ef850dec7cd9da243225c2eca06c02881614b2b98616ddc0a80ef2823db11dafbca39c8da2a470e50a71afa5303e77db62702b8aac5b1647192d55425aeb4370d20745239c5135125b5e282d8374f72fd462626b3dbbf0e8a3d40146d4c3aaec0708f74c124548d58f2bd72674b991b2f887f68a5013133c7cf6e710e28f6c6a416f38eeba72d54da82ea3f39b3e8b7e09ed8291b5b6786b9a7c1f528857548474b708b24494c54bce0d456aba5064c003c856a309ef89f30c611d6fe9792420669f14106ee2c8ed014d55d9eb264a316f727dd7bde5ffb9acd1eac0c1e43da9c987e6d02b2af9cb6915cd5a7f24edca21a0f6852d27b91ca4cd0c5977b039174335ba241f52dfe9482a35f41841feca2d957942cf70b4cfa984a1bba910f476bb874a6a696c8284ebc2017edb4b8626dea14eeab87b33d3267d0e1f7416f23093285c02f3283aa6fb470c11273974c828d4379c326b4c37d912de791d89ca7e979e78034773413f1254e076a5470651a251542be8b124acdb5dbc2489c00a6e37b3b335c682e14a64feaac905229d40d85fcbe6370f3181fa317a41dcdaabb264f04b2805adf5d22c24bb5acc3d8ffb0a0b27c6daa4a1d8f200836521707a1625fd7f2364d32a97f4be271ac5f0a49fe47321d9e8aab84c33cda6c31488dbe7110ae628fa09d3712f498f8411a9c0443acfda79d520466dad02335123ce0a40e222c63828b7310cb859b89d3afd073b0f73df323e9c3843c78cf79e25dae420706788997e1abd714533156251a13807b8fb0906feaaa1118015328676e70c2b7abd5f7b1656bf305134a881ec8beb551208620afc6d957d9a6d6382ce60c36f0559e2d657bd336cd5241947bc0e17b0b76c0243b84a7b074f3412495885f1efddf072e445f6e0e4790be949cb7a45a8129f13c7faea78db4c0ce6442194884521acba3e18ba0ca5d5cbe845184154a375356900eafd6c14529b2f84ec39c6d387a075a19ddaeff750a8c83655caf04fc0358636f14f98b4ff9a8902f9f157a1f588ea4df727e45d880a41dd20c7117f070e35c4bf7e1e92dc4ff9d5d3eb050c1a0d385d6271f6a21755320d2aa71ed85a210ea19d41ba8c7d5be02f106202f54fc36f68a0fd48c1485cdbadb992bd1895c617118d4084c7208de6f7622dbfed2ac77af283c863d21cc9cd7f35248479d699612a4e1e1d2dd1a2c47e014e3b1017b44e8b8f780535f9369d1053652845df6867449bb4e9065e32055fec8132a10b0640293893ff34c621097266d20a724e3bcd0da704a4030ee5bb06efbd78d02b7a99a0c314d7b20dcf38b8297233441e7c2cd5825122463ed658452cf0912072e81c27b18896e6f1228fa85640ed2f2cce26f5313fbc59400e2911729f5480ad986f192aa0c2725b883654d36c8d66a18279a78a17210b00ae338ecdd54a40439d4d4cbfb435e51770269854ecee8406840c7d255e72d904fbb48e065524b475967e90374a38dce05ffaac3ffc61a4ae52ac5b77c25e6824148ce08d1faa1515052885c68e5584a2c4e84c6e07a04ed02f72e6bc7a13a1f9683842e9c773dcdb2674cea7446c9f48c126f6689cef57997ce5f7157db6e2a7bb739c3cc04a6e9c058a80be8e7797a5e3091f800d96b93ce6f2800270000b9e60b600fffb4bee1aa7354721299b7b163073f530c43555993d82750637c9a5434be97c62c212413baf2050a17f45658b7c102ae8c42f203d91b882b38c599e4b862c2405a61ef2b036acd75b5eafb8c9b5c1945ccfe906dc1833083d3f9420b4f62e801869dc948454c7419e0f0577a003d60c25749170b5dc8c43e320abeacffd4488b36f2bde8f34bf8ba058983a9affea6b5a57fa1726308cfd94571d85bc8303d56220bf683c0a7d6508888ded2eaf151cd4e4e3f7af68e54fe43bedf15ca98ec697922e040148c38d847538f6820836f32498f3f1767b965964b060a9af62c58a5abf082e53ef3fae85a46e689ad4c6105e2caaabf0f9be6ec3933d099a74ec93b5963169f9bb8c41bf3fcd87b6a0805dcee7acdd00e1d4c7cf4ee6a1055b16a35c869794ab97fb86432ad125d4d36df36f84ba4a56cb574edce52fb26d29addff54012be4a96143b4cde726a9b96be774939374d31ed42153159e538892757f3ba09791248cbca3f0a44c5f76cbed19a786cdb45c734e8eebb92db786902e72d5b41f53a7bf267c36d52612dfb028ddea62724435ca7b55f80aaf7f5b0d1313854858633baecab8611c5d78e6bd5b235271f37644a806c85654bb3b223434c82602f7cc8d9f11d190a9a3ca27e4fc060ee28944e8ae84aa6ebcc8a1e2331e91f9458fed47b5222234dd10984af64bd5a4bcc115c9a74e3177c7a39722ce2d2c6a3d0fa3031750a77aafb2d8d190c0f60fa3a312a9f642b99846266bd77e435d19967d9cc812b550e8e5cf485092d581db0d36d385d13a8b683c84f24cd0f1318750f89858c2d5e20401877b902bc74db2f0dccb4576e97b3d9b7845f7c4d62e293d2ddbfaa18f23b729f12b756b622b992d9ae3aa43164b3681a0f2d494b01ac5515ca479bd8b7e6edd5526121821fd79f816e285a8de2385be684d1af4af66111cd73e7ff7292a82466ceb882aca50e2eb807fd49082b2f20b74bad25945681aedc6a9ac6a575a3b9cd7926cce0957b2d9161b76af42f586abefcedc1d945122d1cd542cae34221efda29f7c6253df5709fc47215dcad97a5ebcd1126bd3022a42f01d9c4edc33265ce0f06f80d6ddc22b5722dded1a20e0eb23ace994a8a96537fe122de52aff1c735c409e1715b47b5b069dd38341cac6811acee9d85861f4215d1c6755da988849ad4057f8572bf1893aaa880d36a250fc5ceecf74b2dd0071ef37c7e15c9a0368f68fb477ded503d961f46a6586abb875286646741369117e3613404c5c9dea34a1d0ff3c1636373eb7e913bc81b9918b828a94371604b89a77b5902ae7292540a3de780159e3fe5c1e4e9d287d75019b2fb1db67c11e7e7817859a8c7896a188dc60cf43a60e668eaca9583706cbfa68e229d11c5684d055f71d0b456311424b767cbdc2a6e354c52e42e866cce094fa7dd6706ac5cdfc9130493eb845de264274315146886ee8f883e81af88c10ad3f99f82842b44bbcf19881eea7413c0bf9d628f10839184788b62592d171d8862d5db0ea125a6c47080da2c93cc823445f67ec9ef708a15eef44c78f102a13115b37f1380c86c3294385140cdccb055b952192a304f4d1acd41142179721849ef24f318d84d019dbb2dfe5036060dae07efdc8e6225a5212a2c79b67645d9d6fd7796a005fa4389310dd9dfceb8a940a8d8dc04193b5a181ac4a554fccb07672638775af80e271ebc16c7af41efcf0add27b3fd8f3e91a6f4ae1213c2c2336364f0939ac51ecc0023d6d41d98b3ced28ec1ec487d2b18b70fb2d36ecc6e64cbcc0ffcf59938e300b520c8bce049b92f1bea6bb7e2c774fc03561f81fd5b06a646d5ab64ce61f17369b9ff4ffdede6947e33ec7f3fed9d5776eb5c87cc0416fedb4e77ef35ead7c5f1bbc4fc2668cf3b59d9ffdc4f1675c5fd06d2b44e80b97d6012194bfda290f61202272310da6f1ac62d619ddaadb8bfb77766b77f5b01fcbf0477014cd1df4a86cb93dc1327e0e80f54889dbcf39897dfc3866e1c3ca14c7dc0dae9f132121793376eac58967b904872e5769f5cd66b76e94d1cf06f716f25c7fea4c35b58e77f2d4cc89a917218e695d3589e13d094016283008fd0970a283e78133e4c4a5ab84d8d196209587b1a6e556613a8366711b5ae866a7f03ef6bf693acf7bde62417fccac75b3cd10e760a45943c7a31e749f757a657968ec73a613153e9c3f14e34e77b2f77de2eb0ca2a25b5a583194b4fd0bdfd4a1910477efa31be5f56bed593946f84ddc7574bf76fe26f7519745710d12b3458c22ed71b70fdfafecd0773f1f7d68e91627b2eb6fb83e10fd90d28b1c3d0a5fdcf1a3fbc867b7e1871039493a563920f7932d03adba135e74eadc463c60f65aa4ea6ceb58d6681f4300853ff86ca89e32fd20552b2afa4bdb5eb07487238b8d5505fd72441895a14cd15e1b3f641e0b70895f316cd5c35caeadbca2245d16016e02744f053b63bf8f03d6d5d9ea54f83e769e867041e95634b57a9c69b17893b60718b86f4189ee2931aea68c9f42138a62edf67b9b52a67a15eb45d1e36b4c8604dff004a2bc9f80cab476ea6c114df525d9a0bed1b415554cb358ace6d96cd328fb88c4cefbb73d1629aefeb4f829b623b692165bb2b9e8ece5c889495bc6a8610f22f19e97d8052d2b8e0e2eba05c144a46aef81168549ca8dcead1b9fa87493241c9dba1c6da9e172ac0e49cd163522682f76b74c20b257516f47625d94cee362a69178f2c17760add46bb8bc8f9b34b624453f11881a9318b320f6659b6e91183913c12cf217b32e73967811ab0227740a7b3a8104e402efd6894840c07d258409e2f6557ef932baced44628aed6b616ab4ab91f0514406d030b0fb84ac69d59ce621d23b23df3e86fe6d8cc9dcfc2ac7939a7e078c6c433934137a96c366522791325402c11ca9afd67b8bbe9e9e119fb7967c5cefbbbb8552d7b54cd513b5bad243ae9a673731548eff843534ab63b1c12b2009763dff71f4253e748a87d8fb3c963d104e962043633149c97fcf173d4ec58944914132b521ce8cb3e10a181fce8e2c3fd0e539314c6f55ff3642e6202f5b295b611e89844918920428750df6ed574e43870488681f6c488d26390f9affc7ac76d2dee133c8bd6645628b4ebdc26ca69f7bc99af6cd3f73d9a3079f77bd6c49c18c9b9bfaf66f972b869c4bbc86ace1b2b09b8da2b9d8c2a34dedab669e84e8f884a4991edb8f262c8ded8b706c4be729089e680b888038c44108d99fa3eca2eabcd2bb269d18cdd73d64236fb86afff2ed9210d70a37de77516b519d0cf596b709c06034295a1f15032b6a5c2c34371a8c46cabb9d56580ab099c27a805fcc1d0532b1de57ed9feb26cf798a89c4aa04ebb3bac405673a9a8f6cd74ae8c46990990ddcd694c491eafcdd618bbc25471e5784382d97ea3990b25894e31c56af28b632738b6e8ab516f343433f23c481922da64d9a918c9d0fc1466170ae6ccd0fa84feadb1383312a498a4b1e456f454fce23c4105aef9485ea2d0faf74660ed7ee2ecb6ac79fca741bb1f5c21828c89ddc6869a25fa1f5682ca80125665f23e5d81c4eb17a14652c59ca5204f36c4c9bcf3746c0345509fe0c4504f31e9e67fe4df7d1e4b21e3f6e7b7a7449145f3199a21282021871d8115fc4a8d5f544a8dc19b31d9710a32727d598263d268ad891d1adec6f13baa8d42584277c15d9471526859514db330ac987e0873c8344163f08ddcdde43b86598b51832377955a9a4ea14103da98feabe050523a7a7e7570f1962acf93e04033d05031f3ca1103fdb6e48624dad480f842d0ba44170d6adff2502fd78333c5caae8db0e59c9e53d697e6c6a37c1d9f7791b7acca7b02523d73bc64e34f3e297ccd2c04d665a432fc2fadab05f2f80cfcb49c9aa952da9ae45dd115b5a0fbc6ff709aa4ef56db12a187c10019b97e42c7670e88613972e6a6c5de695ae7bcae8847da8b674ba8e0b3198e2654f28fcfa0d34af71b3404de969fa1321b572f6645795102851c0039a9358c1cc2eb354264e0ddc4cef23fc00fc6e6b101304f24c5f6b0fe57fc8bc98fb4a622defc6b8a99581b74956fb9e1d67feaec58d5794a7ea222b937f6e2b19ce51cbba79fa959a0cbd84b4c62f38ece727f97b7df47912aec2bdc972f02aa36ebab6a8baec41f986b11c93ba144ca162dd0367873357e8ef0657582a8109bc6895e8333863cc7b255322b80cfa115397633e89c1a35e8ac23b455a98aa940aa830102f0b96d566be608d5ce19ccf5afac035a20f11d951bc266d089518e41da7b83247c5ecbe0ccd495014c3f001d1749a47eceef2c89da0e69a0fc544a727f6317f4d60a5e16bd4096fac8836ad773597751a1ae202616a24d016831302e83d9e467e152449655a7ef207d12ce49c09677b9ac028e7a0e6b12902e63fd6caea37c0e52a47bb8316a0b47d2e36ee3574ce2785c578aa25ecaf2ac6e67670a76124bc1d99b0fdfc4d040e005d4e16c9aedd1699c14c6cc216ca55a86de71559f112fb4df2da1712c10a27a145a91cbf0a7fea222ac3cfda7b766f1d22ee81a5c72d304c061f7150005facd92515686fe3de4996e512a8bd8828923432aa4820620c1c6b23324b67aabe7c0cf6325dcdf95e97376ffe9757bfbd76ed3987493fb1590b7cb809aa3ede838a35047452d1d1a745b8c4a7534911181c5b4cf2e9a3c7a6427a5fe4c3b09b67950014f23488472989b0c9d95922a6f9f4a26142cd1591bf181fc3df1db41794128cb93e9b8daf0b1d48d9d93b8e138c1937f93a06b1277c5fdbcb81d3939fb75707d94b1b982eb28ebc9b5cc96ae944fac19d094a884f0cee46677952d3db0e821d355720bd613fe2db21eebcede7811ce6d1339ce12ecb6fbced486b1ea3d6a523b2b66aaa052fd2c9a716480591c81964b2fb498513ca6ddd26480fd7787ede64a54f5db64ed0a116a828e7085d0725b259192330328a907c2dabbeb5f4fc3e756b8ef9d9d8117743f3eaef02320f9956460ca8ebd5344752da7f492f8e57a428adbc189a1274f8628baa1ab139fb598c976c91ca4b051bca1137b45c57a138969c2cc0b4605881cbb4b33d949702b405e3d6dcb516f8e33f573218ff098a1ebbd72683d09d7b046dd22b2e35415f191ed140c0b95a578fe3e57853f72fe51e7e155effd75f65aae3c551cc1f80478f5463e7010c70657bce364113c906807bd430b441d62aece1bc131d2ff1bda1603b82bfc47ae34979fa330618b7f604d08e01b1f6e1daf3da39b8341f5a78bdc67e9f7abcb3adf3d28310dcbb6f26a54ebb4ec6bc2d068447a5073b6d1555be8c5223ae489f3aa6ce4ff05d3cfdc708e6874533e1892fe32ba3d5834b660b863885c8fe017ee58927462eefada6aed5d77ddc393fd56e2d5a7935add5a265bc174e96b601bcbabddabeafcc1b0382ef2ecb0de00e12eddf524cb73cce152acfb2be94f0cb0e54e8dbca4714f585720b7293e08fa44e0ee092143835586e00152f8e163f61ddadb09fbd1f005955589c9d267dab98c4c8441704b5061c9a26a617a5f5e34aea01190b7ef2731e5ef4f65cd7b6b67ad95db7017410848983fbc1c0bcece767ef4cdfdcd76e2156652c37accfc0399256f240382b546275ebb5696c0ef9a5ce1bc62f90dfb214b721891ee7fa7857a0846fc4c4c64cfd18a7420c73e8fdfd2b543cbeeae9e1a5cef1fa3fa8e5893f620ff1236ced0184208b8343011bcea1d4aa506dbd4b95781de0b719940c4ba1a37bceb3ce26eda87345a0b2f6015a1a2a1128c2baf5506922628ec43712691eac14c4ee0acebda4a93c56b53b64e60c0d7c066af84e252c5660e80a5c79dc2b53e650e5b2cee16db4c97e87f96852e623a59ba15afa27b5a79533579ec23d2a21bb6385846f90984f3385bed72e0d8c4ab411191ccfa1dccd451e78224673f9bab8f47094e3193200a8312460687a557bf4017be2d1c16564ac211e35bab53c19fca8491632fd6af88ed38d3d8e688c59fe69c4ca939a9b1a045e8c1a4843f299be71aa5f2a4f5c24fa6adc4aa388c01d0a65f03a08414d673df750099720a2e8d294a0c8dd7a39445682c53317e8a716d8280dc74dbad717528ccb38fa3cbc467e9eeb5baa6c8610fafaed87c3e8a9243430be3b4570933d6f8497ba243fcfcf7f42ca8447aad5ccf3c8077b71a70a053009dc8641f467163731e20d3fb21e26cbd10196c4855ecdfc28e3b55cf16c7b7e80189004e8816afe0248d03ea0fb50d489083f04ab318c3110a0cb3b5d9fca25017ad5f8c0bd16676c2f9979c7f96e2b6a50c1dc9cb8b5a4801e2ffb3b1e9cb230710a789cef52a92dff181db32cf8609fa9400090512fae1893fb095e9bbd7642a0ce34cd96548b249b98637d7860750926fc291f6bf6422acb99b92aecb5f60e85c94112a55d2eff86297df0159e049f59b329df37729bc81725e5cbc5be1e018330736d361295e237245336bc0396fa20dcf27baa3dc81effcd446b1460aba305341b3807e7b7e32e226d716ba68db597edb0c9a15a4ee8a8392f2a07c46ff1c1c668af8eae07a38c739b503c0573f91371cd9397e17794eb14c80b564219e52aa4bd86481ef60496ad3ff92a183057eff948f8c63606fd617d82d0d1da61022cec4c701664e5746eb4bf9d00b76bad86ecf9f3d18e7d31b4c20aacfe6c3e7e8b671ff3e6cf8bedc12fd98a38933c46f784feac0f0c1a5f5574c9e5f7a2d5cc18ae59c62fdb82005039483b2f1ee520810e08f8900bf00d058063c8445a7c9dc42e6ab0e99bb1d2420df45b89b5fa5b80bdcacbd932fd7d4c9d49022563e511da6aec63a7bd242977d05579e13d406e9914ef7e8ad661176cf376a736f5a24bd175020d8b5d7a77adce509a8319137f7f0af1267791641cd6cbbee0ca3a084cb17f2151aa6dd8eab52a31c3ca5a52bfb0da8ce02da43c292f4cc662a40ad182a49cd7da719fe616ab4ad73510c840678d96551230b8501b4448ee53b4091f81473e8b5baadf609217d268f7baa90247ff3451bc060fb43261c58ed64451d77bc29c5976166feeda946286ff12cae9e7dd28a22c600d912f0e4e8fa32334f3d9f5b005b31df068ad5089afbe2aad25303341175da5b25156844fa5eea71ec9b6d6658c986ff227a87abeeaeea89c5a488843373440b1a438fe45bfe01f0a6b95fa427b094e6974286ac5f20794887b02a7bea4c0ac967a0df37244e873c2a080554424c1e38b890e83de85c450ba2a5bf9b17818cfafc7fbbc57141f4a4908da0c5739f5ca9f9f19b18552bb99031ccd270f83fc30cae9034b090e7bbf3493e8ce5ac2eefba44601fd0c5427d3a47d8e27c42b59008bef4b106223646fe7ef34168c7385e5733c716f9d414752764ee2ddc2d05e5bf143ae02fcc825dd435c95b040b2b069817b05e2a38307477fc13a41b4726207cca63d09c0a738cccc230be1b230707f8166f6c31c5044ebee183d6965332d51c8cde83cfd82315f1c8e9a5d874b319e358e6d3c7b48a6193981ca3d2497d071cd68ad32bfbd6a4a0f7cd6dd924644e9c5a1cdc7f79d880e0fb5f945fec4c0add302b67f5a8a98a60a0380899e52985d99bef5d0f2e9befc00fff0ef4e212d22ac2ad041bd719b3824cd3e2655ee419f42a3799ed2a68c29bff624a5b2d5eb45d5d6fba9d735b7008eb680e3201053363e2c4e43bf1217a9647b3db570d58c016cd698a45cd9f8995e915db93205c41c871649cf5a786da18ade9484298121a4afeb8c5e0220aa5513891a2a66f97f7a4759899c7968309b9219cd3d2613dfd330caf60c2991e6679668f15f32538b9b0772c9db3b73e0c12245ec0f327051c7b9144ef26fb0fec639eb05013c72c6ef2f854ab77bdbd3af6897c02de0092919b06bb7edfa2e09c1a96f9a7e83331d9d8b43e70dc585d09897857a4ac651429e8ca91a37a8d66b1c0c2045236206f0a2943ad3836ede4a59adae1dd4c69e155c8359997aa810e50fe7683b4f1986f2e77a62bbec9f368e7a05a6f9a21912fde331067a8bda36714a4a9b47a89c62aa13ccb5571c874ee78e5071f26ed3232a4427a4a6f3a38bd59d8a51e05b3887bfe5d7d366a6bde5580be924c816811544599974f51c33445582e56b3a64bcc2cc64f3b7cc263989c8f973fdd4d142c3c09ef844cc00f3d6b8f795284e52ae6f20fce411838dc43687e0f2b1f4237d0175e22b291d2014ab7a6fe7c5228fdb23f944a5ea222b77e86f7c1a0f789334acc7ee07c6b576c6e076a86033b1205df5d53c029980ff59f38ced71b3cae65c1c57608ed97fd3937fb50b40d1a4ca936ec30039bac73af626bf7b476b174a6d89d02fe9b104ff83220ba1a6421f524d4efabd62d04cf33c9d5e4bff0fd6bed8d7c8b34e1fa682f88ffc673969823beef6b0a92be3d1943784426ca54032baf293f83456ec824e2ef50e4f8379a9880ae14c712f6f93ecfb64c4363007c436a0c88ffb40a008f7b4537414c8c84e0aa88ff080b64ad56b47f7ac826b0f3f2815fa2c95c11e33d5f7d38686b4d54b87a4805117682cde83ddcdd867a79b4d6fd0bbf42e3ebb51759f25d40ee5c9f7ef68b7a100ac4c489a50ac50a0b1ee52ed91a76a312d125494180201c2321a6834ca467381d69398746a804a7a5e472a9a00e291485429c1f8859f3e30fd1bd379b67fe991a90c06540fa5fd36a9579a6eb45ab1bcbd094adff1f115b3ce6c37225583f152f346bae05b1e4ed0489c7d5c713804e39f468344eb4307f6076e7101b1638c6e816a423c0a33e9f3f683c0a2e6f89789b91675d4329761c06ec869e2b8ab2c68fef91e57b6400d14c0b0050e5989d34a17e508edc39ef8f51df2e0c4d220bf38d1b1d8cda5011764ec03a401e76a2b7c4479132bf55fefc85b12f1c1f23fe255d17811aed243493a9256bef07e13e2e053d15a71ff4c607a8c3f9ff735914ffab23da7cd357b72534c51da4fb12c968e1590a63fad57ce547ee1fd4e6f394a59ec733836e6ebbeebee33d7b3a6ed69df940bf2399084264de50cb21687ff285b797e241e29b2c2327e6a33290af830e7c7ee7de593ae34f12a5a431a7f309b5abea507a2b8f341c673c39d863140db37e875cf95cc965acb1275bfb758954abe9bc08b35dd96b91fd88d9e3330c126cdb166cf36be79a465533012070e3f971dbb2cd684f65f3e34deecad9b1dae1e511b7da4b27e70aa37869c389699d3d465f9cd4a140549055412fc375547d43ba3065d1efd8e4fbcb587ca460cf19f1327ba2435b60796a32ee2c773b2fbd4630f2c4b311a6e55838343e4082dd68e871b88d367bf00ddb395d1367835b056ff2179a3d135f97767b4fce0cb0235043729d218a81f4109d1eca35f7a1342edb9cc9230b2198d4fc04d1102f948fa647297a81b1b20d81bcd232f729320523538c7318e8561a3c67db12d81a7dc61dce78c31d0abb863481a019ea5eef3797494dcc16409e028412314bd6b2a18f12d73998741d5e2cee7c17798133070dde825dc986db5b18d67cde766574857ea2fc935cf22e8a566c986a44c16d1a32390b004506a33d64dbc8efb755d51b2569b91b6b7e5ea31558010340b70c39586e3de3d3802812032e198cd17e9a0ee0b04b53696a597b535e6ec20a80676947e1bb5778b15a1d409f38acc296427fc5e10cfc4b37c2c5e714aa513135d38fab13154ec6800009d994b1c657329df7d41fd19cbba0d4d3903f57d9f5be3461be7348546eb652c6412c198bf06e68ac17e025b810bda92f86c19bba5bc1fd3c26efe6c18638cd47a5170436b132a06592d7bb6f8e9f4754687bdd22b09fefebb6e4a419c7871645ec0cbe56f4856014b42bb65a612cd517a36b1747a84d3552bf6ab9c79e6ebb88f22642f8499924548ad1f497c4f72949a97c31c2e8a02110195a2dd08baf606ae7082b3a7569c284f2230359d03df0bda2bb4bead5539e857a2f077db726c86edd80838c0ca6dc3170e684248c12673317a4d4d00791411152fdd10f1dfd257affdc8db33e791e0123da11088c010f8c2bddfb3d8276a422c0bc89673b9901f8277721cc8b6369b084680b9a5813e5fbbc5b57364150546b624557768e26e07dad0883801f6841246358f4589adac213bb11f7766e69a5c162c19849e80776ce204269e0e2b44f0a8205282c10cac9106aa3460f25db23470b556fbdce8fa442ad9b981ca1f6d9b979c81ac56907a32f34b30e3d37d30c98673de61f46f93b74493f35c89cb924f08df3c272e8a4ec5e8d4abe8f09c7cd7e22af48d98ae5be0e20c73108114fa70949661ea3c3905f78ddfc4ea56df779411c76833027e5d6748b4fe9c88f110f0503971e8a7d1c40340c5189257790703fdc94e97c33e40c250cf9df18ce4f0a9b4f3a34ed3a223ce31a76b730e18b4c3905761f239c3caaa84b4c667fe1e28142144956980357b2cc89b93a31e91513126b3e6b56d0bb9b2b4eb400cf5cf412030e48cd99da5be820d1a34b185624f354d548cca1ed1e31ad16db6e27ce967982ab3071b78621d5edb91eb5ae5ef1292651336b293a4f34eaea8967233d2207ccb1d8e1329a5fe089830fb5b8251a728132537145750925bcf03a8004d1724e129ca86dc41d3ddc4850614959c1970631de5b30c620e8f67458ce64284de9cd694233c46da372d5ff697f274b1e92b6e1a44347fc68eb4c0ce701acc904dbe82f0197e8690481d8fbac91bc2211cde066c263571d421b96c3a6bae7add1d73387721efe43e8fefe3397ee101c34dfb8d56ca3f9e7a36cea4d45b1dfaadd17d1a4e422fd801eb53a48d276ec460a4d841ea3ee4abfce495b46338d577fded3630fccbfdb8e36fb79ab0942be796a256126742ed62cb6b968fe7f1188ab009bf4365836583b947c06944699a9ee97443c712a4e4f0973398158f3471bb1a3b4f50c39f9f7777743d6a27d361d38690b5190b4effa8badbc53b5c1d5d4aa23b63d858a73a61c24521fd69ba60ab228692fa4812c8c8fcc2048a1500f77b57d843345a51fbf4b22386008ad6c3376dcbbe79a5ffa711e58fbe911f1ec972d8f29c3c93e2bed2aa6f30c8c69f21a85f0609c7e9343fd1cf7c3cf67f3b89e56f640cb91f3d80dc8b2c18baf7bd3b88d7062033c22e0bed76e240e08506ea64c368bd19e46cc267905fd6b4c6ed918504bc21fd6d4a502a18f9c07ecf486172c4a887093003c097d2823a0f015b8ab79acc76c1a9dbc3d64c77bea30a8684874bb48bb095a67c28eda7c3015433ed4d63f7be2924feeae4f7f344b9243c80b797babd4019a6b823609df9c3626a991ea844e9a11509fa808d15450e4138334fe5d93bd76146784e83eabfb92b60b9a2b8890491776338aecb9fc604ac74a8fad05654f715ac7cd850cb410607693d7c6fe37c51487864f7060135b873962570e280146425b7fd89d6d1645b054407967d4e892b61b1144a13b8337ecb02a37186c7e5784bbb1370967a3ed3a255b13b62ce97c2fc6f045388c96f617d4a8005dcc086de01f188e1775b6b3ccb0002294abc624dffc50755e10588f7aa79fde599974ca19b9803c3e27c5067bd86e77cce348f0199f051951e5b90c5c0c00e1b2603f99a0fe2fa4eb22cb5163afca574f962772d9d160d79ac97824c114b83509c2792c6a6b4b3465ab402599146bf81be38d295e374dbbe5b78cfec552e4b31b171133640bdd09312edd5e3f2b267ce1ab8be7e3bbd93d270867d919299e4a71d4dbb7496b26ec21f08308fd116b1db766e721833f559c052803954facb70cbd7c4ce4afdcdc756f839ee09bb5e730e6b7da1e499f6fde222f262306309e5952be7312b21fdcaaec8f2644189a377786842f700526746f366122015920a0bb202b2ebed391e6fc4f3bad3474edf16625a3e7c63be9f7e0a22de9d2e4e7cad07824c4316fa2d7b61a49c3915056a5cf9a7dfc860ed0764ce1b4704400c298e448f245b3945c64997b2593903691e0998bc003b4fc0a99b76325841e09a4b17b7d9b906c9943068db13dc81234d5e5cd6b469fa3288995a38812764539dc245b34188d8ce73e8daf27b5fdf4156d07b3834db799511ebdf0d70e97389eb42a055e484c199277a39955a3b62dcba23adb90229f679129cfb203c63bcc9ab292433705091f367cf603acd5f5584b2958a7b7a628223420f5a32d49caf8361dc9fc0c3a73ea316d31a91ab4de39e539cf7b8a7ddc4778f46c8d1c855340be29419d364e08ca446de659a391042dde19aad26ac76bf5ef968fb6c5d7a44418643a170178a1780a3d1746a407ce21dd24c7239bea8abd9923a84f6623ba94835c7c9c3cc81f2ffcbfc00d6a50b6e8de4c561d9a77549305de970f1c876f8650095126cf20c6007548c5017e3a3ca9575e5711efa6282d70ebdce10a24ac8cf1da20430360ebee3264ebd64b3d9fbfc261fccf6948abcd60dafdcadeb39310c3a7c75b909c6f6ef09de5701c6628245232efcdc7be8d20946800439a710cc1cc9c682cdd005c9870150468875490ce2255f7054ea5669f21fe51cc8d0ef7106d2b9a8646883d9bd0abb9c542e3315c14297fdcbc4786bd7724f3284b1feb63b41892dfdae20de7c1f7678c75ad7cd563878a4b21b4063fa07c99bf56b9438c02c23d0ad78aadd2a16fb74e26b900e77a56c46252c268f5449ff406642923b3e5b94351b080696cff03edb2aba20f5c2b6547d7f7040bc01fd946719f0de3b88d92290ad74130d3357419ee80a80babb89aa58bfab9c5476e8ce64cc2c449c1f3d55a7af6ff6bcfee175f93c540f076ed4e0b0e5d95eade4c3b29a0cae5369772a4a5a6f0bdd3920bc10d0ee93c384b73f55bfe0a3d87961814932abb74a865646dfbfc648e7100faf19ee9617351a615f5c174b08684a60da607ed8ec6c4de6432eccbd2c61839e78bd5075abbcd6f08f745f2aad1aa7e99a2f070af287cc0b90550208f2029da9e1fb5474aa85a32f9ab6c7abbbf0e7ef207933e124aabe237f949b813fa40e4bc01753e51eb695fde29bf765b8e4b580c1ce054db46e83ace279c806a41dac6ba98a3dca9261630e5b72e9595f6af3e0a6e7c9d2c69d0c1d8861c526950ae59d8947dd37fd22bcb6aba52442ca856b5b63b0b1e7775c7548452f5f7b1e9a7c129487c04d5dc7e28c27d8621011a85afa8db2a2cc9dbce2f1c47b8f02fa6fff99bced8ed5758134cdf623b14aa05bf66689c3ddc4d742e2036bfcab55b80c3d995fc9cabadaca11fba6550e1d1d01fcc3e8880058724660c96fe21b868a291cb452110d9286ea65e0a7a988faf99280f25a22bc0bd84aa1b36b6e13c4acf3c87fc6bb016e7243c793949b78852816838e7777ebea7983c083da86b01b2d3e778f17fc339e8df78b9b6b8baa26e4a10cf71f4a31bad3dc641cb94ddb4db032e8497890ec465849abab638caecef8a02f90cdb22e7c853cfd345f3cf918a01e0497d2e006f01326a5917ee8203710193e48e7174ecb89869202c37e35fe68c2e209b8cd77e990ed3e9cc918914ab9f8e3d8ae40c290e72447b3ecb081888a852c703cb1a552b2ecf834ec237fe25a904f0aa3bec1921e61d0c8f085b55eb2af0e12e85a4f27b3ed0cdf249b80840d25ae5bdf7653287062fdd8e1c3989693b192a6954ffc1560643d47ffd7f93d1e250a7e77a08a3db5f6105f9daef9577c502f18bb94cf31189b9cfba420f12e57b81fc9212c061bae85f31a076422a57f45ba64ca71a9cefd7b7ae0e711ed3834b0047f9dfb5c454656d6f508adf4f54995ddc5a95baa98f31855709b4a2ad9a40dd44480a530365aa99e79ad9667bf864ff10e20f0c1f2eed2a850016bd84fc6abdd95121451f0d0fdda5ce7de655091f615a684c33fa6c1832f75471e97a7f73c785c1197dce199473306f67f55a2cadb4a68fd803379c1f35421bd29eec13bdb90ebe7e05ba0a95445af5f953a7065c1571d4b2e8bc5a8fc7364dc91e4e031b201844f83ab695838cdedc78acb47590b102588659b266620199f8a7d23755eecec1f3b414182c40bcaf7ed95848d91a2b424a6e0c4dd115f009cd48d78f8395693c806d9be3bb265f079514e577165600e737f6d14716f22cee919ddba2813a053430c0ec04c1302f0cada70c3481ba0c6846441b60bb49c9d1aebe125cf5e9f2493ca9e31f5166b8542060132f6d75ee6cae34026a113325cdd323c9e48313f8e51ef6cb931f8acdac0d2c8293dd7aa4ced110e429c2d90b99d696e65ff3bf1e942619fb301b80348c93d5d12138dbe1f545eb805e3911562e080449bcdc5f9aeb4c00031fa669db961eebae4aacc743c5b77e7d8d000bc5cf3c64c2f44c68193d48843f5ee9e164b2d4792b16086cfc48e8fb7f31bb38ddacde3cc482273849522cbc416b1068f1d68b3fdc21059aaa000982d5aab1bc006839217c4d6c04fd3e6d63a3c678b0b835a87c97dd5bbd43841facee2b89ac690ef6423786b1ff1528b19d59253309298150ac6680c74402927386161f8e965b4ae859cac241098f9853c9e5832bed42a825bdd2ab54f344e0cfb4288c00b285a0d1dec33379f642bd8022d25fdef3ae61703ae36fef9ec841958677b0726d14c44161f99be6c64633661303e60528ce5f3e8d90c6f8c0c3aff6eb15088703b6669638d43bf8f184116db0e431e7988e171b191c31be425e214cc5b5cb612a51d9fc1ad87c6267faf72e0587aa8084906c6321733f065925506624f37f3063b8657177c3621e3c3aafe1f9ad3900aed0ea051f478dd78b4522fba64a6cbd13d5ab7a0260b7d1c67c0319209b22fa83277ba1992ce7fcb86bef24049c9329cc2ef2fc25fb8dc70acfe161a1389c0d470a63471ae6dd77b7dbaac9839475789225835589718ac42798d25a32f9cede8ae3e069d3eb712f120fdabad753127b90de5d95a6201a2a948a6cdd649f7d75c657965188306812fa4aa2ffccdebfab9607422abf2cb1fced4d1d9569ff024e61804da3ac290071f0cf5d576e714471b7a8f8fe2ea4f86607719007c292f35f43124ec103eafd160405beebfc32e6c282bb962c56ed03fcc845ddece32967955b4456b7494124e3e8cb8862592d725a38b2e319c351e9126d59c49e1466e6a72d6ff0d5ce48d1da30616a91c5449a0ac847b976ec5a3de04b3a43b99937cd59f80f233491e4de66772b2fda66cceadba85b9dc69ea65e327a5b411d94b3abcc5ed924024a2c6a36ac3ac09a8b779b30976760940d106db0f04c9c1061cae574e4735f2c62a380f98263ae0bed4f0109ff31becb5220308509f8c3905bcf74c44af03416052f4536ba1a813d95e622187ee36addbe2f22f09600c848542b29d067b29c376da468021f862924472a2b96547802f14df5b1112cf456ba943d3960612de06778c23548dade41b63980c8ad1ae84bffdf55dee96d3095d674bffcdf8d552d4e291a688c08e61e8bc6348269f2722a2e796893634d7e713e6717c9d47ee6839968bc47a5a79572b2545ee6b3b98c239963f5a19974f4c3370566a7bb970bac45d8c9265312a68e3981a0ba0e15f4c3975913e43b28900182f1677615495bc1aaecfaddd66526ef4514ff59439c342ac42bd2f38b21aaaf969d5edf09081cb5815957ccddc88317d46350a04e7f37d5b80a20b95c7d44e0f27fe8654136c81ea9079b5374d2cd17fb8a62e5e794280a1b0f9ea62d4ff52447e9584e514e8572bbcdcf9e304f5ac1a4c1d68813cf02f10afff7422f4fcbe4918c9c0e24d4b5efa762633a5297f61d179f9a58815a02487e6d0dd1377b485ed9f1aac6ede6e87921c6f1bec59a6edebd4f26566b49a4b2d5ae731ec350c74571d6399aa711fcff6f25dfb7f531639e60d7992b3371a7152565231478ec8721116517a3068587a510f59f63b1437dcf2715f5479aceac017fabd8b181808d9374d8690f299709676114522a7d11acf12655ff438804d6179d7666ea1e3b45ff0a0d05376f21ce342126d831f3261b161bc234b8fce4e45e8974e8d1346fa7010713f1a87f87e0ec2082152425dab1668d8829770244e58d4bd1d33e19ba6bb75bf028f04fae0e5e014aaa003df5946a6f6ab0ece4ad3227c8481c5d5adc4bf1bfd1b65ca9843c27d7e6a06fdaf2bcafe6fb4ed05dcf09106ee127ceb98919b0d5b0cfeeda4facc9e4188e1674cdfa06cbe69d037cde2972ae5cd9f85ae93f52c7cd9f75c400ef5d8069910bf88b3f3a42592b92534e11b6dd55a942bfbbebb83002fc3181dc6a102aec9b5c4dfe0bb37162ac59a793233fab0047289af7ada07fba0bd341716eb7bbb85ed3352e918a1a062f3354bf9e185c4cd6f48f0285d294ab843911ac4901b294d96757f22bcfd4677a28c81ebb95e437397eccf0a4acd0dfc963eeef2bb9786ecf40641b461f3ca2cfd0b598e9ff6b2550e90f1b57f6fb65a43b6227aa9f8f7af631f3df3e8d3ad8f2373a25c605eae662e77a29dabf246540a659c75278b84a906d5b7e315e0f8406c4108d002f4da052f5f1008b1c393c338f404cbafd972e7b87920797f417ef9add69a353a2fef80fab8b56f3322bd9956d4600960541d1ab886a1c26044f81b16f9867008ec3b2ba44e1f824ea300cdcdb00544c0b25db391fc1e0cf226c71b812a28faca995f24cd7e4b1d11360c1385792b5e7b3bcbc00a5b9063515f1826eb0f608c9a202053e5a61730a93d43a176132a9d6d853e1c2ff19b5c48b967c0fb37cda2782ad414b06cfcf44e01fd8048f74f2dd3ac11b0218575a48840ef644165b81e8dd934b62594cef42887c6b2d1f739bf5f35dc5ce421d0293f4c69ea97e155789ed29399edfe898c2fdb31152c4fe130b46d17ced443fa30c3dcb6c904bc545c288b9d6a80feac90d50cb7078109b12b596567bb76a3712d10dc9f47cd2e1dc719670564da9d884cee6add17bd86c07e0bdc97c52588b46ad6c5807ab41d2e004a2f91abc1b74a98c36bae6760612261126adcff8897c7efc9084afe1a4f1fcbd80f1691ce00dbdefce0265731cfb4ace726eeacedcc453c3e27b3ce4a9c501325a93004ca858dae7a09dd0fb1055e55343b37934041bd78b247de582c179497eb8bfe792658add230ac30e35ed4bce274a3c6b85d6abef10694f0bb83a1d02109f2e1f0c94a145548720ce8093f566bba6b4fc8ffd60e87cf659fe3d7fd2ce07eda7f89003ca18ff510a47c3aeb2d4fdf2ddbf622340cc940b048e01d9966390c2d843350b66a6cbbf0506c6a0723be8a530d89c0864970b602410e925f0c2cc94ddd46ebf1d8f9a9e23c9c70bb94d1ca915a6d0c61a570e37cbb6644190db1c68619d0ee1b10e429ff7b48234fe7d5c32271b65985ec5570ce80cfda2898839cd29ddeab17036e63b3324ff88c8fc0f6f7ca44f363a1249b948d0f4662fc884759ad4fc344c0fb98067ebbb68765a56e03fcd5bfab130dfc7c3fe7be9401e9984e41d7fc490a436990b245166f52772ca1aa92625064484aec907a45c1cd2230786d5713d5231c31b3160b3f122fe549f76ffd37576bce559bd3d59bb2e5f9d130a6f173dd1a93699276c5f2d82d0d9525bf06c16cb2062c2fb0641524d83afcfa689dfe8de9a47380d32df4d7126f6f417995fe1e09b84efdbb6c2c05706df96e68ee14d65aba938db2c22f62731f05a8e811e3f24b5e321377f607917b321d2c5e59a4c8f02ba7b1c87a9d53a751fec8cad8a861fb59c0d0ca880ea520135828fc09e92d7304f787c425133a819f84d33cb060ec98ea439dd040cec86eb96ec158ff85d5660382155a8ef3d5bffa8c1234033e6d105c8b4a03880355d7b50d04a57e00cc43303e6878c4d15c30947e96f64e4ab8f10a8b54ff4c1bda23b5c044d7c0765270afeade6f1d43047775cbb52c47740088387e47fc0a1409252f8078ecb55ac25224ee33b79ad2e81c7f2f2244db7c858ad8633fc995d9167814ee3e43b725b60cc769d16e7b31650e3f95cf4e5890e11391bc04dd0a0a41339991737cc63c6ffce98927a88c73930233aa73ef0b371ec13bdd191d620c4844758898de359689c968cf8c743473f9691155e337f484541e85bebf3b968ec44e9bf6660e840cf1e05bc6b0568e43c399ac117287bfc8ba18e350e14ada69d5445690db025cdffd11aeac5030750493506d7c8a3076bd2fe0d4442a0506248a577126f9612ad0f950c2ce2837bc13effeebcbcaa99d777df50cf8c75e5af3c9a514134816a65751a8f53b95bbf91b99cc505e7e0def75209e8e0bf3306904dbc037835feb1765ca28d2bf1f428a7998ae0ccc548a773371dca16b76d29fdcd8104a2b87b8c80adacd028e6b8e0340055b24021414cae3235a67778b89ab25a70b1a2c74908ee468f16ba750ff5140e5d24f905e0e0cbc77b1b41ddfc58570eadd275c2ef74be740e98343d105457c487f3f15860d9f7491f625d7c40845eb68b22c8b0bccc29e3c4f84ce2bb349710cedf9ace9f5df3ad3e85574a4c5533093acd664f00b15ecaf3ee96bd70fc6d0cd50fb559f0e3dfe4c467a01dd14f94e10e769470d86fb17d029f281c043e1af1d7da33d0be3782cb94a12671edb60aef216b3cc33965b1ad400087de28aa569a16f834fc50f48a6f22b5c738e2d792eb0517cd4cf413636ab8d9e0bf233cad5637647f8516458bcf62705f1ad3f0e3548e2ded76b97f824dcc9cfaac91522d90b6968345b13765a7ec5bd661254681b2b961221cf9019458a354864434768d869374867c8670051ce2694e6dce1a2aace1375d74f95d0840173a31eac8b5dfc9409d5f98a9b8e45dd7e368e8dfc895a2ef7014b49e4fc397916bbfbba11a7f30526da1b76e47d1d7b1b94b255fe1a660da74f964eb48cfe6f740adb9c7136a4bb9e741fcad3c1cb5d6f0556e0269f6eefc7a72ad7228d2d65f86aa9275dbfb40faba3269a9d9cb9c84a5e9d9f1f5e4dae754a09dafcc544ceaaed7f134f467d44aa377390a4aafa7c3cbc9b5cfbd501b3f19a996b05b6fa3e9ebc8bca526af721398d60e97cbaf5a1ee206e9b608da64cba614366ed7685aebbeda5fa91d9dd2f054cbba106f378fe7a82edc8defa1d1c99fa98a9db4c77590f4f57ab80af26ce722dcddce98a49eb436be87a2394fe6aa76d21ed780d3d1efe92ac8b3cdb110f77b63927a522dfb128eee3c99abea701bdc834e47bfa71523c93ed742dcef8b69395225115d10b51f4a0e1d0d350c71164a03911ebe0d552e72f7ab80a42fb4709b5f70cee693b3678355729b76d47e5cff00e77e4053c93f9917a32de08fc746a8fbb3d851b7857fed4c38b56f2dc7c399fc7f2d28cc59e0a12ec914962573cf81541f40230152db970d5005ee6b3272a4e407dcd355976e3ec79a2596a717d61200cdff4ffd2130539e9a0a3967c97e06f4a2d97826447dca8db278f4978eb67e34bb35c4d5e637f7bce803a78098fc2340153d0de6022a64dbff3d43ba60d61790a637e896a02a2031edc0bbd4201c1e9e9834222785a4ae0b493277b98face2d923e6994c250171b61714475cb0eedadd997e2ca77fb1d85af9c655067ddeca5e3ca54d084edaa7a777796613c40eaff6a7df59c2aca69967210658fe036e614202ff0eb2e52e5ab81ea07ba4f0011a70508af2ab3d663580aefab374f89dc53546450110e452cdab388dbf556ccdc9cb979d104d406a9def9ecdf9bc5617066e5416a09f6690c55be9242409b9a4669238d906aedb600d07a9e6d8a9e63d0040252b82141665faa80ad0107d0219ad75ac0e85ba5e1fa0296f2de99d8f8b3e724b854a6447ea7e2352fef311f31f39ce4c367c702b22263da669eb2147ed026d08a4ee337e9c87678a27667a1c158fb116a8f96f070c6edb0bd4fa5fc11e1e3f65e24503c429e1190ee0612a890707d3370d025091d14140f3efb9a3a49caafe41610dea72ad703811fd018c2f58746c650a22ee1b459193ddd5d2720853aa7bdc645b3fcd56a0fcda0e0fd8054da5401d4ae9d42ecd713a2ce73c8aa407b3b10f872f9e98c26f88e17fabf8d9a5d94458a1f997c66737f7b64d16a9bf1421b85df131ea70b9a743ff9b732bf33de7bdfa0be21880dec348c48f79e64a2cbeaddd78f9447c084c774a039e94dcad1ba8a900468629f28480c3dd391f870ae51e42c617ba66b1a487cf322643380edda5472f49bbd805dd0727a1b86ca6f4bfc9951b243c9a1bdde4ea9ca118c347dda0ad7975ee90d0a14b2bbf51e75153c200e1a84c1837b0a571f429e3bc0cb4d96f93026554790e3ed1534a9158e59757631befd0550f4aac170f7d580c8e6d5601a0cbc32918b5c8a89a35848f18c3e9745504a5c2aa82cc27333da2d09bd466333cd93d1cc3c6b042453f1219baf995bd2d52b7aadb00e82fe2380cf9fbed0ad9df9ec650a21604d1c3083fc196b92d00255e82f231e74c221580eac0015a893a96c9b498542663b080a39b182d45e5fddf63dbddb2b25d165efc8417e0cddc1a162edc77983076533b0020884b601772eb26f851fef7fda8f66f2b2eedabba96811330bb6d06766fc9be213c543a5cbd3ba408780aacdec10ffe02675adc9af1598fcf8f149bf0abdce8bf3f1713fcdfcf1629b108a0eb9723eeadb8473a3d5a6972381427f586d5cabf566f277456d60dc17e07e3db7e98d4d664253d0872c74d470decad67ba8f24f056c70ec71bfd5afa1af263459fc77fdcb31e9acc079bbf102434bf26949d43e29dfc23f1f96b4c97ee77e76685af51d62e75cc040b3fa4e417c329ae0eb9e6f15bc48d99e425e1b1f09b578def01dc6fc3cd8f8c85209cde102535b8b4a7b857647f185597315fce2197db0fa6f5b171405df467023ae5fa964f1060ab2807e8753baf6620f6f1ac403a60d04115a792622e9095e80783f17f060411d7c8d4a00d807d058c919292e455b4a3bb4a88642b161111115167b6a4fcbbad44002308fb167db2f712d97207fb071508840a279984dce1f691d31aa18efcf5cac4e2234b88b1ec78dbb8bb84347ac042429616764bb9f7d3ebca295562a107ea537a6b8fbc2b7cff3d2ba5f497c76a1d21ef4d67dc7aeafea9a5fa5a7ae43af97bf26bf8edf4ff7b251646e885340a2c23e4bb6b9cd16faa7f8ffbff1f322d429e13d65b2bdd7c76bce7cb23c7ed3fbff27eddb5b4f8e191f1d472ce3b7f7c48cab0eec81352fa64b7dfd27a6bbf76e40fe1df3ebefa6e97f2d388854584acf77cd7f25bb1a6d46e5f477ef6cec9ffdc7b5f6c79d541a2a3853584bc67b71b7e2a6bc74f57bd8325840cfff7d0cee9359ddc3f288515846cf9dedc7e49f57fb1f32f263ff9e3955afabda5edd2d391a1af7abe18df949ef3da2510b2d4b4d61f6bd51f76eef10ff2f3f2c3576d97dbcf48b10ff2e6b05e3e318c1c5bce6f1056517e78ef5ebf94586b683d0d0321bdff753bf1bb3dc8967fcc1fee71630dbfe4495860f2dcfac9e7bbc576cfab2f12d61c197e8fa5d592e2bfad7d5206961c193ec825ad3d52b977d4328e0c2df51d7a8a6bd5f3d30f47deb8d60d23acf4e9c9b1aed30deb8d1cebab9d4a89e5f7957ecc836c2ff6d6ef7e37a6efdb6d7dc918528ebbdd533eed397e5ef2bed34fcba5867ad717b11b59bee92b8e1d4ef8df8db68dbcef9dfae13ae79c3bc8526f4863fc9ddfd7bddf38e820d179800e121d0720d169001216586ce4eb37bf7efbbd7dd7b6da35b2c7b6cbd99fec7c436fd5c87d4a4b2fd4dc7b0d274c23d73ddfa65bce4ba3dfbf576175c9d146eeb97dd062edfddc68e4dbbdd4f8422c25ae12f633f2bd1e6a88efc47463cc2b12aa83bcabd4d0f6fabcdfff516946aeb4fb49b7dc7a7f6c63cc629591fbe5b4eb6daf85bd7fc9b96428ed9bd35f3a37fd5b3e8b8c6cabfc92cb78e9e53d7ef8c4f79f08bdb0b66478659ff37b4a2be456be31b2edfbcd0f25c7926baba3189942fbbc84ff7afdb5ac340719da2e2987bb6b0efbdd4fa7071d742017561859cfee5fad50c24b69c41b8c8c2de5f6edcd39b6bec8b6cf1a27be12d6df3dbf5ee48beb97fe59ca298c147e2d79d21ee3869ff6eb277ed0ea22535fe5ff54de27e5d6b75a8b8b8cf5fd53525ab9d714ee0885b545ae95ca1d31df5577f9223702a1162b4bf6d576fc2da6f6d64eefc541bef4c1a92b96136a6f3dbf41c692ea49fbbfffd96de5d522776ddfbd3ed24dfb8476ea20d1d141a223a10e2c2c19761dafc5fed6dd3db4da06d9423e69bc7c5a8df9a6388b3ca17d5deefef47bffea8845e60fd6fa7bb5bb5e9161e451471db7f7b7ea6e459691fed7ef95b173fdeebd625dc932d63829855f52aae7c735c8fd4a5ce7bff35a6da3b492a194f0c3fbe6e578621fabc8f47e3ba39e1d4388f1ed695834c8f05a79a5df717b1efd93b00b8b8adce9fb9ac31edfd6f0cd29b2977e472b77af175adaab1419fa197f7cf6c6c825e77a0679cad971acbe73acf7a6340bf53809f215306264a6c08a22e33aa1ef537a49618dd18891074f5049bdc2aa92a38f7d5ecb3bac72d7576590779dbee21fa7bc1aca6db50e121d243a269d1e74b8801123d38222efe7e5ff5c63ebafe5f413613d9131e7efc618f9d6f175eadf904525435f7ffd7c4b69a1adb757ea63399125bc705f2f7dc4d34f6d7590e8e0a0d3830e3a468c50ab89ac21b43b523ef9a65a3e09e109c61b584c642e3fe6bc47697dbfb4c2138c39b088f2a7df3f0bf9d4f7f2b9b7e7f00b6b89fcff8cf63faa9f966f467a86a544965beec9f1d31fcf2f697c80dc62c520731a23d5f6f38d6dd43a9ea050ed624dc9367ed8e386d3ee78bbe427d8860583cc6bad346a1831a79b7f68bd20ef17abc410c7dde7ed7b1b3162c4881123119e208c0fca6125912996af57ff1fc6125f5c690b2c24728c74f23ae37f5dc279b10bf2d7746b5cb1b61f5afb3a507712045d60b5205ffa3f7fcf7a5835d5d5472a160bb2dc7ebedb79b4377ecbf911d97679afeeff750fff8f4fde27ac15e407a7bcbcd72fdfb5b3ce4764a9207fda31ee6f721a2ba65aa7207faa2bb71a4b3a6195d3c3ca846544ae7b3fbebd9d9f7609fdad535828c8553feee7acddbeb867a54564d92787f0f56db9fc6fdb48854544c69147fe35c75a73cbf773c29292f79c1bea7efdf73e6228af15eb04596afca9ff77474d39b4d704f95fdf5fd4da52cb7fbd18d7c02a41ee9ae307a9f65bcaedbfcfc21aca50f7cebbfe7256d9c4680af9fa0e7bdf54cadbf7e6500af97a1edfe69f63fffcd3744621630fb9845bcaf9fca49b5b28e4ffbd87cfc71ee3e6936259c5e809b96a4bf7fbf7bffd667cb82231fa23c32d37be95435b9fd5b3fef81f9c902db75273fb6bff54dbdbe3986c7784fe4b2e2b6f42de93d717f7c4772e3162428efff23fff8d104fc92b5c42b613c3d7ebc375caaab1ecd08fbcedac7cc67fbf9e926ed84786da4fca2b7f2f3e69bdc44f8c9490e3ac9ad2adb1844f47099390a5f691d71f2badd1763f5f30e223437b2fff5e76f9defc1609b96edeed9d1a474865b447eed447afadbef50899732a2deed0e2fee0ae5d8f0c29e5d35f6db17d4ffb68841c37b4764209ffdd9e4f5f845cf7abbd72de6fa478e237ca235f19fb7b317ebbedaf52e391797fd8f24821acfdfbbae51db9c7fd7b8c58bf7e2bbd7e6447de343e1df1d31df66961254296fd415b3bdf12df0d25ae2373ca758dd1564fafffd30e216f4b77bc9af7dd65f49e0a21cb0ea7a6b777bb2bbdf1193172fd0f30cb280859d737fbfb15deedeffede02468c1831728215622e2331396a6927ee96d64e47fe1a531f39fc0f72ba650742c6d67268abaf7bf35edffb41d6f53f0f23bf964f6cb1f541ee9cce8831e55042ea7f2cca72e39b776ea3bc96ee5d1f5682ccebe3d3772e25877dcb5d0436947bb5fefeca3bf7764738a790f1c66f530fafbd75d21ab35c52c8fb62ff2ab618c7093fd651c856cf5bdf9ed0c307e39590061714f2d69c6b58e5c7f7e23bfb13f29db7471a21adbc6e6bef1f1947fade9f73daef845c67a59b6a692fdd7adf3d265b595f9f31427f27d6703621dbf73ab6cff24967f4173221ef08e7877e7a8a2d846f09f96b8c6bec4fc649f57bd38f4cbb84bc527c23dfefebdf477e5343a977ad187f6d21bf949077dcbe4e89b5d79572e9b9b892906fc51de2a9257c5bff7a2f3e865c48a0b9f6c8b4d70a37ddd0d3cff5b547c85542a967e71576fbe5c64a2cec5ea809505085300af9a00f5c7ae45ff5fb7afe2eafde5b5b2516fa244dbccf83f23242d6514fbebfffd5da6a2da6721521cf8bebe4ff4af82aa6fdba71e591a19417cb69e3a73fe2aff1c8f2f9db6b87fb612a6defd71d7946bf27fc5dca19b995ffb2236b4ddf85746a7bb1877b42cf24881e3280a55c44c81ccf37fdc57b4ffb69e575e42d2ff7b4c6bf358c8f0e21bf486b87f4d6772f21e43eb97fb362f8a3f517bf32ae2064eaa5c7b776f82f96b56331f9568c77f5bceb573b947464bce5fcffc6c72d1072e77aebadbbae37f23fef0f72d56f6e58a3c6fdc5faaa0fb28d3cc6e79fe4afbe887751beb54a19f1e678efc7bb3d5d6172ef1d4e3f1fadefea41fef8f2185faf15daf8efc6e2029375b73af6beef97fe57dde7c8ff51fde9bedbe3c8b78572e48fb1e4726f1c239cde422516c27dc591bbed32c25937b5114bdbe1c81477c9bfaf1bd648e7b54a2c7cb106d71bb977d83dec13ef8944ca28e1e241a6f1c90eed97b4534f79bcd7c98b4e5c5ff2a5f36bcbb5d654d327bb973c7be53fe2a9ed9ff049ef468e98fbd9f7f7fd5e3a2bbedac851f71fb98451f65ee9844a2c4cf2c313447f904626da4776e0da41ae706b68ebef92563fb56423736ffbde50f2cee3a4155e6be4d9e7dcdb4f7e75a4f37edf733a0935010a3afd00f1d028d40428685e6a64deb78cfbeabbe1f48ffe34f29d1853697dbf7662df77975cafe73cd2f776a5bb6f8c46ae90fa0e27a7589e915fec9bf7279fbf3c7e3f73888f884b07997b1feb7f9d62c8a3efdb8c0ce1fcfff38ae78b33561abdb8cac85e46fb7ba51ce22fe99c5c72ecf54d5c27ee5cf64fe109f2e02223db6dfdd5d7cb68b5afdfd6716dc93beabfe3b3514ee91f8c58ae31f2f51ebe59fded9cefa9e91323738eafe630726a359efb4f99830c2fd6174e5b79df73e3da794e3f40b6e7f043817a859135875c6ecfe5d41272fac0c8fff7a725acb4f28d3fa75f646ae98313466e37fe513f2ff284af56da35f7b3caf9f6a525472ca3c5d8cec9af2eb2dfd2d64fabfeb14f0c85e0b9492e2e328dbf620fffdbdef65df11679f6f9aec6d2d307e786568985272f04f433e3932b4b86f6f75fb99d7cded9f1c5417edcca7e9fa79a7a0e25bc6e90359e186a38dff758532a955808846e72f2fe53a845a6f7c7ab779f4fc237b557622f2c59cb5b6f8f32c628edf55189852fc67fd9207b48e59e1efadfad84972bb1f0eaf4f0009d6c812861155716993e08f9bdfc3ecef597148bec21de11eeff3cd73b7ea8d3830ef58ceb8aec39d4163f7f27f7bedf7b5991f1e3d8c3f8ae9220274c70bd92a7df506ff86db48f3fbe9558486384625c35c8f461bfede6fe562aed8b9795bc31a4f6ff4f23acdbf25745ae78eeff3b853ed6c7bfa541ae3d72a81fb4b6bef964a522db88e18eb5febded97165f53e4af35ed3b7ab9618fcffe4b8afc26a673d2ed2fe757ca9ec435833c5f875c5b19b57e70c67efa019241210002c2c18891a010000129b160ae28f2f7115b8df783fd797aa5120b1fa44bae2ab94288af7dba4f6df1af3e970cf28ef36b5da9df31fe5e7f2880a4a7c7a483444707890e121d243a3a3de8a0331fa4f08222fb5be9d35f5fee21c69c5f4f64dbb7c7f4d72737d758532516da232e2a59462ee1e3dd3faac4c23b82cb897ce37d57736ae793967aafc4c29e1ecde78f0322bc9ac8bdc2c877dd78738b6d7c3f403e3e405c42ced3638109183162c4088475773b010e9c9a5c4c644b3796d1c78d75bd51fa8b28bfa8e9dcf8f36777c574e370a4014a82b41207444007890e0ef85a226f3cabb655f36a6da597e30970e004e55222c369299e1c734d3bb655c620fbaf3ded7fea8aa3f5cf5e53b2f510478931b7f3efcbe70583fcef8fcf7a1eb5eede5aba830e3acfeee07a41f610ee1ffd7d7adaf9355dc195449e98e2aba3de173eebf9c5485c48e4abf9db7f624c7fffb05e17643fff8b5ddb28f1af3ee849585b90e39752d26adf85ba765e9d5c2cc8fbde0e61e56fefc835a647643a23a616d729e9bb97da1564d829967acebb2da4526b15e40ef5b6f36f6cb7873205f943fe1fa5b8721ae5b4d588cce7dc9afe7efda43fd68d82eceb9d5adf78658d78c65b44a6be7bbd75ed333e0e7b2722575dffd657dbbea1ae5b4bc9fbc3dbbd9dfb4a2c7d9f27c8f65e6921dcf1791364683dfcff3dd871acf6f7ab04f942f9efb6be3fbceba348ea63c13594dfadd542ffbefc97773e858cefc54f52e9f18576ef2f85ccb596567b1daf8fdb778fa390a1f59e52ddb5967457c9a1902986153eabff9317c3ef9f9069c493ce6efdfed1fbf42712ee60fd91f5f394f6ce777f77761a2d8fe584ac37f652731be78793d2d9b56f429f3526c7e8ff8e9d731af7b3933721df0d2186ef455921c67febf4f080207c049404691c901c6980048c18b1550d8b095973fc2a9414cf89abdfd55a42f6d672ef2bbe98f34831b5fcc894bf09617c94ebaeffacb08ffceba5b6e3383bacb857a8c4c2dd4f271875b09490bf9c903e2eeb96b83e27410157d11546d26bc8da23165d4f5c2fb88aaea22b8a0b8e2b4c910b0557d115e60a73c121a5bc91d7d015265e615a2bcd64ed4ae382e332e386bac25c61ae3037d41586ba7450a4c85ba2ca1258a4194a18693737147521613de10a7385890147e72ac229b2450c2d32c440b99043b5ab8872218767266a00bfd4326a6686ca4a34d496120c995ab6c21340897aa1d4320a9ba1786909c944845455d90d33549112b565288b6909c944d931c54471e1b2c5446534d40a262aa374a8055c6dd4d08322805845b0eab088600dc11282e503abc8026385b1e4b0e2b0dcb0dab07a60bd61f1c0fa62a96175b174a07d3859645859ac28ac2a960c2c226b09cb05560cac17584ab4381a1ced0d6787bbc341c115b92258531c1ece084e08ce07ae072e4c5565246534e494e0ea70621c1dee0ff704eb8cd1141515978795c6880aa01fe78763825b42db816b8273821be3a4e082e080e088e086d0a220c11023102208207c0738b0816605041ff0800630608136031a0e606de17ec0c40005d8e9561e161ed60e2c2fd61ad618961816189617d61456139613a3339a0c465188604465e48465c545c1f5e1c038395c1cd5138e0db78653c3a5e1ba585db832dc16cb0e27868586cb810bc38de1c07064382e161d16102c2d5618d61756102c2eac1f58622c1858297068b8339c0e9c19ae0db703e786fbe2bc586cb82f9c174e8bdbc271e1ba703870592c23b81b382d9c0d1c162b072e0b8785bbc259e1acb82a9c0c1c158e068e0947e4a6704838291c0bdc116e062e0a57c592c235e1a0704f382ace09ab0ab78453c2c5c04d7130702f70495877584c5854ac275c0d9c0a5c0aac399c0b5c118e0827c59dc099c095c00d5553a8a45045a18242f584ea8fca09d598aa091513aa25547e547d544aa89250f15121a1daa33a42a5476584aa08551e151e43a8845089a9e8a88050fda0f241555485a97a5081a9e6a8e4a8e2a8e0a8dea878507da9bc546e546d543ba8d8a8d6a8d4a8d2a8ba54685467543aa8cca8caa8b85464545baa312a31aa1c54615460545f545e545aaa2e2a2eaa2daa2c95161596ca0655161516d5155545836a8a4a0a2b89b686d3a3e1a0dda071696434275a134e842c2e3d2158b261a8bc5827b08ca02c14505611944504659d80b24c405925a0ac216a34056a24056a14056af4048a898f16b261f407357202351a438d9a408d98408d96408dfca0467d504aa04649a04648a0467b50a32350232350a32250a33ca8111e541dd46808d42808d4480c352aa24660a8911cd4c80c6ac485aa0035014a02940e5404280850007800c5000ad654c1cab062a8fa527d11226424a48810ac246359168db364c05c6b32365549a661ce52c16aadd1380bb32cabaaaa516b32ad350c6bae5195b32cabb9aa5996b35c55556d54599665351a19aaa228475156ab2a19cab556516ed42ae7a8465dd775b92bc8d52eabb5eb6ad7d52a8aba5abbdad5aa76cd5ccd35e762708ea25a6b36ad3552e55c45516da6aa483604a0aad69a350a40d52c8caa2a8a9269ae5155d51a56554dc6b55655a4e69a4e6b0370ad39d7da0aad51ad39d72ce79cb39ccc0a564ed52c6a46858635d79aab2ae764288ad49a5559a3aa724146c655ad01b18000c1c95cb0300cab4630541836c246580b4128aa72963543630171ad958094281b270020cdb5d6da08887356a3916956b30980733434d6a8a25a558d6446ad35cb511545b53673b571797142a8ea02800a140c2f50f1866a42801788503ffc7877513ffc78d702158472e1851b00503906d8f9e1c7bb194a86ec66080b54d00f3fded550373ffc7887513ffc78578404834ac607280d4a940a0ac959519a0dc907280d0a94ca87280d0a14285146513028950f505ae50305050ae50305a5f940418102054a14cb87280d4a8bd2a0341fa82857942851a25851463e4469519a0f50a2441945a97ca0a2341f76aa2b8da2a8e613a4296873d398820a0ada46469516d2dd88d5b490ee404d8c60946b410688c929045c0b059d4e41a83604c34860489e1389f445965c5feca39c0f6eeb99f8702f32d7d1cade7fd5956a8fbf96cca7c4d5cfbe2dfdf0f61f807c7cbc8ff5f13e95d44596f0fa5e29bffadfad75546261f5f13e94c485e411ea5112a4b7903c423ff0f42c4c7c709061a4713ff8e0d5b15bba95d81ba193087d7c938ea1d00f8f0cfae111eae171b24f4d7820dd40f208355112d4733ac990b4903c421dc8c7c9e92443c21204136e03211fe4e37d2e52169144c2e28a59857e789c58f1a379fa8fef39f90011215da941936fa5c9afa289088268d0e3c4878aed24688adef50c498a9f889166f073eabec90fd08f105214954652954a234906954612142d909e104288209e401215211f02ee649f20c909dfc323740a2235d184079d9af8243f9e09131e26319098804c8690887ab8137f6af29768f2839094f83975209f93102f91621099fcd34f129e1e6d439a524382c1cfcfa9c7894f900de9053fa727404d9830d1a7ad879092981dc8479e4e2a909008d22b905ce0857412df2449127d0242377181d402219e1f1e2124167c20d211bdeb15c493102720a1930fe2d14d5420a940869402264ffcc98664c4cfa967f7d30f09053dbb9ffc0f4f0f8954c4cf89091050cfa989efe9e1f1a92111e17f804e413ca708997c929408990439e1f9f11ba8c91f423a412599e08787865482cae49f5e104f4e416c1bd2d013e2bd209e0cc1a610210993c264f24f5138711e1f2021a01e1e045701834265f24f3d4e7c30ec091132f9a73f9c40c2c6cc26442608f538f15942504f9253f423f61195109310f988240c09718f78842743303da21162119ecc2b6bb03ca20d8647bc23da011f70fae1098211012639fdf0d4607508710a72f2c3e3730af23e3c4243a042a0403461120421843805b14f3ff074194c4ca5f1d4817c6a303a26102725424040fbd4c42b11d24902800181fe60022104f381508f139fa29e2f040bf3434f9293508f139f1ef4682722f0a7209e2118981236c78f3c05b14f3d4e7c6c30397ad7dd068bc3f76c2740bd6b163038b693a019ec8dde750dc603261fc3be70e0740100605e86606e94b03684603bf8094288c9e9fd2409b2c1d89857d6606bf4d8606af4ae67b03454c0baf81f9efff5094848088606937fead11ca809131eee9bd46067fc689e0dc4350460fe01ea61023950608716301d609819f3ca5307f23925f13f9c062b2389ffe13418971e273e4030327e4e423f403e27de7d93196ccb18306062e4000b23060c0c03605f647da3ffd07e4f6bbfbe3f2f72302df95d5bb7d6b046c8f7c315eb4207e3e206dbe2052c0b0e3acf0ad80d20a6050d18964cf1a7dcc3276da777bf8bd9c06259f03031615804e56057648e67a417ffa8ff93f6422b8204805da9c100302b385815347001a382083685055ec0a4500036831d2c0a036055222603894191614f9c6e302a4e9c78989876c09a6022630d279db6771dbffc3b122df102a6040c580cb29cd7cba8b795f1a7891321dfe4f4f34f3e411a88d3094848ca29271c0c0638d80b66c0924022bfa9e5a7715a58a5d7561ec15c9039ff12fe89298f1af3bab1166458e39e51536831d590ff2015602cc8b02356907bfcfeddd8fd8ffa7d3bb9602a38dd6029700133e20643c149085644fe10421ee5a41243c87b7ab48d3e3c3a08f1f8f0f49c9e60449c58c0a4645e7da715d23dafee3e422ad809f2def8c679ebb6ffe3a8311498093296011617317a5854585400c909400973c10c75d35aeb826a5711d5b8a05a45861066d02a2e2638a24a6badb1e1058756c5ca14444444444460c43822220a0141aa4cd185c80a46c4061c5deae8e247838214939539a22e4455b24c00d91030642f64518e58592b615d2867312036398ec80242ca04f042c3a26465194e0986764597529737287b8034281b72d670a34b91c9ca28caa222236a6c78c1a15d69ed4a6b57da4507101c47b445698923caaa5421ca42445425c36162653838db860e50d96625a7d9d0ced0a96a8d4d6655c1c38119a2ac2509b032db9421671dd168e88c66c3080aa221a221a221a2a1212b435686ac8cb49841e46cd5a5e2030a3e9c1d0db5008a2ece3aa29c16f80040ce12120b394b4825157296948810c959929982e474a9b4543b56569961b26c4859111b1b2c734456e6aa5495b2326786b5c4b161b22c1786c9da62b29c179395d960a4aa4b55975455bc5475c928abd8b0aa2e26abd9e0b82ad58e95d5e0382a8e098a06cb4d0145b3c13511c65096a12b86889a15a5250e092224a62011c694ca8a152d56b4b052650a2224aa1d2b6b584acdca5a1712a954224224cb7676debba32a44aa16b464a6669a09d286a4543b95d55a958a6aa1e28389ca1ae91a8d9c1b096180a370842c93d3525ad288c0b89c3654edb46ca6558d081112a909a0aa5ea0686868949634227743d15047735585c6c8b2da888b36d2a976a8cc2940c6b4a4e46870004c8d345261484dae30cb1a22e46a194543ab84d4e46a8b856135d96555a91a39e72a9c206e34aa2a573919990a08905295cdd4648725a759a9761a9866a55d51d9ec48cb6cc09488506d5455aadaa1196509703b80a14894a5c92a9c46547299c50057802e3924121122540e152ba7aaaaacaa58b82b582a5c433021a492e90531b56c06080d8ecd4c0d0d4dcd9db1011244a6441282995a363384a6b58c0115c507979c4b056b85110b0e0054d502119ad6a554a2c9687032d392dba5d4c0cc0460051586082905b1a9a199012243c22e16566837a656a5aa37140dcd112142225555b23422324cad55e901912fa646ca4c16366a55a88a94c1d04c0ec7244353a1316a3a4baea965333334ed8cd2929d8ca2a165ed012e6b5444d0a6602a9203661a99aa9c253f98463944281a5a5635936b3355b6c45519999ccb1a956aa74aab4294a5d44c544554a56971b68191d142d2e2b454ae8263c844ca5aa9ca1a98aa92c95a33a2ca4a2b5415cb5ae64a52a82d52464340b2569ac9acaa54938d4a33599bc9a94a3459952d69a6d632991c528ecba9c991d2aadc419353d15c3895c94acb82595a4a3b5855db963161342d3457543b8d882687a811114da96ad6c89023896aa7654d07a50c8cb32530a696b5d20eb6308d724a9418384c55ce1292a9f100052ca64661242e6ec0c1c58e29628ce08286152e678c4172650c922b7a20b9c2874d8d16ad59480c9946990b1995cd5459141e6a3297f55093b9ac652e67082c5a4e0f2eab7286702173d91045b29a2c8a855dd8989d9a9d9d26e626a338e0b29a0c0355469361a026bbc92181cb6a329a1c1260d183cb6ab2aa8969ed1ad35ac3726a708854448898728a9032d7c791223db83e8edcece0b219ea06cba81eaa9d51c680ca95a46071e514911dd140454799142cb06646c94b3b22a661695a9a118da8856c49ab52ad20c65931ce5247460d0fd328bb721850ed8c322ce76259abc9438c2e36ae1a16b21a9c27ae00d54e4d56e1d0c8e03493c3c1e285ec6685ccb5314aad8c12b5650b1ba6c6a4aa636c318db29e27a3ca349a312da1312da1f0c848ae40a1daa14c4d8cb33bb8028c484b4a6e871accc674db96fb4256e1dcc88c516a62945a0e4a2d6b619446a62623d39226c6347ae126b3320ca702d49115b299177060c86e70049015c171990b381551a3a110805519a9b4a46171d91222354578a8c960c87aa8c96070594d86e5f44093092067882aa3a9c96e7068b222332ae0cc6401c0199211c11192b58053ca008013245b01c726bb702a401d9152ca6c320ba7c80e355905a8233519065c1f4768aa9a223b381672a44821424a29936293d1644754c08932d44a6dc8156094d5d8e094aa989a15d3281ba2856686aac93b3c71051835304a0d8f6a474cb5d3be28352f86b04a052dad0d194a1419725831515bbc8cd9e2c58a3260d05a1759b264c992254b6b575abb52ba4c365736aac9a48caac9a1b2b1ed4816a566c4130a01414c23671ab56c5465414a19919d37e699aad135b99294ea89b345648ac8c864437286c0624816e5c828d38003320346260b3292c9a9c8888309a6d2133792c9a94a52da5009f230d164437048421a16a5252422ae00a34c059c7645494836247b14026ab2516603659f40ca060c48fbcaa0c680798281219c21aa9d515683130445c328d38094ca48b38126478856c3285b618a6994cde45060aa022c69479046574a56c61ee04c32430c3d695694963c6acc9bed0ad5c458516a2ad21661f49143921c72c8c129814384a2a1ca1a4e1438ea60c20c0f972074c9e1e7c083971bbcdc20460ed1808f8b0e1e6986123e31d4f89428206644d04c550dbc986ed8c2c3966c94513c1851444b11338a54c1c7125cec988204110f58b86c9122458a14295278c0228d60c20d2c629868428e2ca4c0658b142952a448914285a826571946658b3144443c537888d4d842470aaa166508d49c71ce39e79ca39ca370764ca3cc653b19911b93cb88944aa46ac7654f4ad49629a49846d968c7b22ccbaae0b0dca88686a2c1ca1c0e1fa6515623c68bc96542c2b8c254a931c5f4a4446d51438aa965444cd49634f4b0aeccb2b20b871a09a1a976a86ac732515bd2b8c3b442b54365251b1b9b9a8c26c34c33d9932736363636364f9e3c8961cc983163c68c193326fb60cb983163c68c19332609115718222e3b2e3bd648a38c16acb1258a2e31e801041031e80104105cce0893034f0c31c4102486229f0b1c6ee49043122e718cf931f02851a24449122e764c193366cc186b0b9720a8616a26cb0cab0c2e7f8471e302c5458c1e32b496810bf42043062e20830c54d69a0c33d48d0bad65ed2aa23270dd912f509aa16e1a75811e2e385a6bad357ce47aa35d715c72988a74b1b6b5d66e6ea494f2e6067983bce1061e6e6e6ee44d0d3737adb5d65a6b0b90b2b5d61a85f0d66bc8daa3285e4545b05d5fa84b0e05c81aac3fae301445b57b119080ab88a2a823adcdb0436b335057519be18602ad9928536badb5b68023a5516b6d86194cadb5d6da3c52b2b2aba8b51966b8deb8e2b8e4680dc9153f5a6bd61fadb5d61a4ec091d666301599c20f297390f21ab2f6b8c2441c70386234934d5333ed981a296b1911536b412813a5b3e4c2620a925135b99431a06a2522596bd455445d4554d64a33d455445d455493f22abaeeb88aaea27871c1e10a7385b9c25032505496f22aa26e6e6e6e6ab89141869b1aae228aca651891c7bdbe348aba9690810c224c91e186ba98a0aea2ab68060ac9153f8a1015b10eb8deb8e2b8e4b8b9b9b9b97181a2ae22ea2aa2ae220ac9153ff24d6e0d404221b9a9a1597fb4d65a835798ab883a62baa9a1b58980045c45549129161416141614579105c55564058b96236e6cb9c2dc70d3ae372e391460fd71c17185a1ae32ae2fd71cad8465ad0629e5cdcd97cbcb35c7c5832fd71c5719735c6e5c5fae2fd71c365c5e2e3017188abaa9e1464a29e5cd4d2b5d592bc964ad04246b5711bcc25c6e5c5fbcd8707db9bc5c5f6cb8e6b8bc5c602e30147585a110701551b51a4559a17a410a2b64095954bb8a28eac6deb8d02e2c57960b8ceb8beb8bcb0bead2722961f561ed119059a854ad72c55916c320030c218018b509822000a31600203018128bc5a22c8eb2308f1a1f14800a4a5c3a46442c202e180d0503813818120743a1502014445118c5501c046120cc59077205c971e47e0d4efa12cca70c0db6ccbe94bac28637cc0183e9e3ddca4514e6d266941b69203f3c85a61380b87f5723ca2fdfc45973869b4c13eb43c71c8d2d241fb98039dd5afdb7730e72444b4b38c49d0438453c2caa8a06e5c4ee2ba29e01fe90fd5a3558c3db7309d2f47100db2f7032232698c6a7bb980849f35e93659d696fc26ba981363bc0ef948cbb378fc2bcf695e623d1b01eb055c917f476fc2046e5c2ab48690047c93d3c507c8a358f753d2e1bb3f22df1724f67a5b8631d0fbc5f091ad894ae29a61fd57bd99a3762c1918bed147d2ce8411d67f9e18ae2ed4acc4d04e4d833ba035c606c77c3944ec35695e68f5c16e6b8521028220bc9e8bd7a547e1d2e08cefb14dc837a2030b6976cfd2dd0666fa85f40e0c64481a1e5aa95ac9b2da914bbdb970173578f6ab4f21b789d04b096683db4a04a6407bc62ef447ef5889a83ede67dfb6550a19f64617d2c01cc1a3da53d3fb15de4912b70ba5f3e341ad13dfd1e12e525bfbfc17c07e51e616cf7a4ceb6bdc1d71cc2362fa2b4d4be723628d37b26d1f852f71ec53f2276a20a95f691973eb2084b79477378233847d9bb6ff28e00e2605f5c4dbea3a1af54990877a449841ce3968b645fdd7ea8e8f1812fe65f1a4196f6e9e832c964e868cc0f0eaeed1cdd5bafeb2d2c5bb11d109e828840391ad7f68db7f0295489a7508e8c56a418db9d350ae97a417f850bdda2222b7a9a5f8ea34d10a740acd12a8692d963325296b313308a004888a73fc4d85e0c0777bac8e1627be4d1dfe8997798ed99ed98efd87164b3acfb32052ec6c48efd9f1adb6622029085c602c4029406cf29e11de39056e449385b0ab840dc0809b0290e2ac2cc51475eb44fa508dbd6775c44bb83486500f922339ef44357467fce98fa8eef40a668efb069d08ca4f7654287826bf2de7d65b593aa29134e58a43feb55d4e126f1bc9606797759c05db63022c2a20146c914c37e7b72381f08f99b917720fe503b40886784d0132d628530833addfc128cbe8f72a8571f013491bd9db7052b88b0898e4915406f5a82da7b8608f5f2f933cb3e7466abf00fffed082fc2a81fba909431877a92b97fe7faaa03f9240d4e76706e01282e0bd4ce0dc8000cefc7bc54af19ac31c1890286bdb2ed52d82a990c2ef98c80c87230e02901490888e5462868311225048cbe242483d27670ebe3d7bc510a9226ba2f10f65c1a4e821008d8645435aacf44e58488a0b71b53463131ce04414ae62a1f062617a0a7ebccd9eb2a0cfe06c76eaa6f7154354fd822477940dc8c2211144a8c060a89cb5ad7a89dc92803dbe15c094fe96775a386b38f376d118691d4824e2c0733e0469f053eb4b9473a538c5358cb41c71316ce8047a707ee051d74d298645302515caeb1409633e0a2534eb86c931c98722360a7ee027992b59737bd3a0b77b8fa0532b89c0e32b5cad3c07783be549fb387a73d59987c18a3af08e6435a14379f4955732aa0ddaf4f1d2119924570f457a33497e9e44041555abe0a20143cb997df865e76de39152f7fb1487e926e0fef469e9fc8fd7b72c6c7d3d99e5899031438447e1183f2a43a52bbf2a8ba3d59a1c1a188c302239aa29897f2475a482dbcaf29d9957bcb49e2054970a810a5c9dd1b92864b9f7cb9b81539fde8acb4343ec05aeff51824bd7b3332a49c0d0445413b6655ec3abb9f1e099f715b312171b4931cca053cbc8e3291f7522a601ad605f17423e649410b301c896dc48c602e479be9ca4442f3dcd89227c95467e6df67bfe894333e9fe7500978ca6b873e3b11e805aa4210e7a61a801b5152f5c1274bb43d12b17abc0016170a6321300acf4cf3e56ace83a4318009cc343a684b5b9883c67e92bb1273367053d841c7c687d81902ee6bc1b76be85c4a42391589e32ed5525247a75e00e5119b27f757288d3e7921b2ba2ed3e547da602876fb88f1e98678a6708934c8208781a8d8092e47910079aa0e8b8fea42eb3453a5d16944b679a0474aa8b98b929020930126025de25910e5dfebef4f41b6f9a7f456a24373ea0fd61a0888182894d7cdac09b2874e09b7dceb8eed13db855a892bb3e65d481098b2f68d487c3a122c2ac4c96f6040b79a6fbf66cc094e60430444e439e76c508afe7be5039dd1bdea51c3c678898ac9154d04fa3724d6a617a22094a36f4546f4ec3c1f087ae5dbafce0d05eecbaf3818551108798c91b708f0e5d73615c18914b475270fb780c326b42a8ba333c1aec03c76550551957d1c5241f22c5c3d0b674604c87f1cdb0139a450aa137bea598ff89f71c6d1487ee4a275ccefe85c4f47e6d8e204ba940fa6cbe24a44a7f45d1014a5024a9a7449b1bca798030e3072543e0c2d2b546dcf459001b9b690e1149ce4ae058682b4d6ca32f0872e1b8f1094f16f4929f81f0f5830bfd354b2e1e6207d0e0c44807a6710de7263e6efd796e85501ac2c0dd8ab47ae44bd1154e62cdc143d70083e7bb503fc8f914cb44d67d7255e50a49d43edf9b91e3816e1f67c38c27c1daa7c325e358c5903661796b6299d782b1ef3e06d939bf822004b6842e1060348a91a20ffd48716437b78f16257ce0b07b0053d1032851f85a9c0967dbf01ffcb2c2e4fc100296aedd351c26d57982bb4a241e441f05b28a380161df08fa75b19a34042c2fefeb276ae7a7c0dd13fac5bb8618f128cf3546c7a62789b8d7d5587cc19a8e6d42731b72e5648008fb5cc468c28fab2a903c726fc16add617c0dd18c6fee550308973b6bc256ab4a08a87f4b47a63ff0cd352200c663421a61002cb120778f62310f8f380930a03b13af90d4a33de32f2e7424a30ec0fa2f8fb294855f8d4e69ce0551996d557ff0f111dbf1baea9564474f537bf4a82f7a719433c033646aadb4086db8e80f365bbc9b49c8067bfe46b09e96eaeb6a5bacb50358be03ab445d03aa0002e3e22e0d15ce499e8dfad3f1d1ba2f35fd074232142a74e8015337d8b34fe83d6839365dc59342a59310a139a03c006f9cb7af6ce330daac01b52b99a5abab89a15691ad592fed64fb145cefb69184f439da06ce80b4709e0d8847fa06217f5ab698d1200751f31d2c41004ad02be4fcb62034c35d022fdb797f12799cc059a3f1261d7cf8c81305b2c959f410ee8e5d0e41891f105df93dcff1413b287e092a49987a4c788f11528154aa34789e671f98b882d01288e890922fb103c6bb7a8cc03b816f0e4f1eda24fde8254103bbf6cbf46a1b821360f0ff671e4fd7b3a185731d48626ebad7636fea907b07c9082dcc057f5de4b52e419c90b006f71395c89576916228520203197757c83c3f008eac50232247dc9f45738da7c0188ecff234d231c52c49847b1bf86a497f6438b62958c846a4ce180eed1742179c92661ad00f4f76e0fb278c877fdaa5ac2fcce37cae2da2407ce82c77b8366dc4845be326aa2634c2a366bb12146efd08ee8b2770fd032f11540fc862ea24bef5feb467332abe1bbb0a8835c9cfdecfcf6e039dbb356ecda7bb17d5c73d4ee0b7c9a422f3a0f2c44e29ab57c09d2212ea277ccf5d53a92f4fde4e164d4c568db39c8e89825c0a9690940fe52df967a2917f5d5fc02bdf70278140f8aaeecbc8e11b6c4d5314594960cf368ce28de51539e95f931c6a54e46b6c8b17e58d59b991c60335e21e9342e8e34b7577b60a4e20dbf0f363910cfd4a4e0e406d7472b68b2ecb67a198d81e6c334ee581a95427ad62159354ee4a737c0b4e8390f1877c4b32e4fde5eac3f327b135ce69b48b33e273c311005a2c16f8088458df28062739be315fd5c480d57fe19921e55794b5dfeea7771bc84993fb277daa7629e5d6ff3ecfff45f9f11f499a3832574994b58dc1a77001a34d520208de6f53aaeda2a5c99742079bedfaded5618679223b80045a4420d3b427c0758da828d9d8f544cb566d21db7514d8e6372df700c15e9b599749acb518a103b46ae5d83d9bceb98ddbc4ed17cbe4be475fdb0c11a7e5c5a77af9c9d5103cc7873539244104b12a0e313cf41930e0f6f85cd744c050d4dba48467a3752d9069dfa2a1359362586ec9d0b1d072e5b2537f0095cb6ed034f45f4f826d39f6a361cd82a0e55c143836e8a2ead9c17878a71904c72dde329b4447a184e394918bd6499dbc13fd1c520aa8510f2acf197efd32e6a0e94af4eb05361e97ddea42279b587865ac20105535ece319e22f3a6ef98013e9c184e39ebb1f74660dcf1cb4f5b7bae641b8f0d2d4c76eeba06b09b56096338e56a10ae9179b27d8566ede24db95068db57ed2ba48aa7b356b1cf29822f80ba8891e13813184222440920323184d2e64145915f962a45d676abdf4194004102047af66d8be194de8d994e683b2decb8fcbe075a296c6dcc643b43c07a6b08e6dddfc2feac184e79949dcb4ac3c28e87ef495585f8090084b554194eb9e827f80b7c5737aab31fb9439887eb2ccc2347fdb49faa71fe69aee27724a4048f5ee6cc33a2253c398842146f83a31d8ac36d2736563a12bab30d8ffa903f40a5d76f83502e0203d12dbfe29b436b8ed1700fe3262eec50533940a93d9a55764d64b922e3946bcf3d933b59aae5f6278d3f22a6a9ab8d83b88b1287658f9dd9c37ef640b530a91a90c158501842710c3ecf71edf048f60564700be0ed151b234c80c5868c94354307b90f85f268bf6b5e9ced99068157fafd3c11502b589d72733cab2e021c2a3637e8a9919f71eae186846d3c078106a01e0f5595bd571ec6e17576b70d436715a50b94a059c0ff2ee0247e07a3ed0ae47e27597e857e2d8ed1589c01a236da572d2b437c8f749b3be1c73c0d78c50cce15c8006f4a32d41d49fa7a54a8e6be7a13a366ad2e6951eb90714b39e32a0ffbc0525d1c106c3c22cbb9910cd8cabe74e41054697baa892f4ec221131df46cd1d53e180eb26042084bbd073b1cfa7c35cc6367ea5ed2fa9729a6314c67f0b8a45d8035763f905a16abe6bca624d8c5d553639af58d633348c5d4f4510ccc3d99d3b821c85ad207171cf331c28444d7adcdd0a99427402b93d3072c28a2ea56e237e88fd707f83b1523a57f8557268d232c47c7843955f825257991fc8618e8226640b20a72e08e1bc5b294598db5a5071de42f8da85ff77e58ba32556a9441c70ab2279c929681fee03f54e441894b85d69972c9c73f76f3118e83c440ef372e8b5e65a83eccb66d67efe17c5122603740f016b0b1a1770ca89236e0d5795b57abf325c7c7f680d546ad3fa7467dc297dd6b8bed6511d55874a1a726dcae05a3d99e8388bf5577f2be72cff8317d6bac4eb9064a10992092ddd78a71cc4e4575322c4aa7dfbe39529fb9cc1cb634878bd529f7d82ed874218a6a7f83d80cab564dfc7a7e1ae2e61da92465f492d2f797c360fdd38a64328f326766f3914bc6f5ea7ea92c7ab13f9110d5370d173f395bd01f43c4fb89de48b714c8cc90e9a9fa04752986ee324820ea92af4599a8d5ef56307a14f8d70e373cac4e7128d6782c76c404a974d1b526c4e571deca43c4eef4906936a0e3436ca05ffaa523199e1ef4394033ab51bae891da7ec6532e578e3fd44c33cdb3131f3bdc2927cef34d29e6956884ccf310847d692649b82341da39bb01bff8396e5024c0cdad088161fd9913e0bd2a963859975ab04d7c9e822eeff017981a9c03b3b780149ab0423305b8bdd7e0be3b8a0412c5a7735307398642a371f36c9e4abd89c2637f19a30ce07052c166ef14a1777f45aed21c417ff81e58e9941eabf86faa4ec681c01c9fd389d62cad53fb7ba951831aa45523872d58b1cc0bfdd58e2f6a5320f60a36ebae3cb45b775fb2ae6edf07d752cede26869bc996723e03e3a8439c5ed5933e9ac0bb5afaf8d52936e4143d544bf478963183573ffbd6c8260d6108826190e517b85783dc69e810367db0e7b76072a32ae68d6b468f00485974205a4a35c9f714615e69a4cb578363c478d43318e08deb71386fffc494afec02f03bb2ac5021346e9a250b82d90d3a2f6989e69a26d6546832f6e117c306f860cd4521319806232cf0048108410fa804ad83a1224f46ca3b4efee674407ad16737eed95c6dd41028577a813bb63d888a6954b023a8d7f9cf35b0b197ca7493573cfbe0f0dc2dc25b350e06b3882860d853ef7c62625a3ae9659e0d46050f54656f9cf194462c7203fde20d2b0854694a46543a09adc4a7e8c8e753b4d6322d5c9ea84a5e9b17b107926302f0b435bcd9b8e26c22f0f2cba7cb1aaf895aa82d3896c8f8cf74597ed9c7969b4325c32e938a0c24fbe196d7823c3e6f38674a3b9899452e4f366f868b579b877761d19033074b750972450c100a4160db650e9b031ba60fb5e944488740292143045d8cea206f8402aed9abf44a203d3ce87cb156c0b8d7727b01da6dfdfbd3823a60c9a99e171ae5fa7cac23c15ecdc8ce9608720858b30c9281067a3beac14019f939539c0be6468f0c9fa613a5f0ad0966589d52988660e452dbbd0e15216c4304f09a186b4b6d94e77f6d492c279bf1e609530bdf61d401bff6c7e89715ad5c11897bfae503ff16730130633cea17d323384f19cbf10dcb622bf8b4943da2ad7131bc2bc0a29db787483e34253293af19da516745774c13ab54d25c6a9601c5d7218b48f19a895fc51eb4413953a7de7fae8afcea4ead74e99fa031c845692da9951e2c8039e3eb2fa1a9f8a5a18270ceda4151d8d11335d89ae8b4c512851a48d4f63dfb6664c13e606da876b6d22cd7c00043151ba6036f6a05e7c6b878c2795b0c13a1c5562ab2784a112c86ca5db18da8154fb88aa1df61cf70cf8ddc5118dbe014b7c234b3d212335faecbdcd4f1d0caec1cfaccb4866e3143abdecd62141dbf91e47887e8539999cab7a67eef6de577a5c6be9f7375dfb8347e5d30f805416f91621452a58e3451a5041954e9b4782ac511a752e762069708c3544ddb046a22eecf762db2f79bf28f68955bd1bd3c8a457ed1c86de64abfc40c152957ba146fea86ea467b9e79b0a6f60045c46aa624e3d159fed4b3b2e36fc7daaa00927e5b3263942b3aee05c9365da16921f97acab2c0cb0e5bccb5185b8ffde88cb44b49d975cbf7a679c6a2dd8b2235f30eb77c414bd9eb6da5735cb6f0a77042c4723dab4289857f89d7bf958b4a78f8dde30a0b9f83d695035d8f1d6a4ab8562b6c1ebbf2550d975de0b2025e51d78d5618c56f6df11a94d6564397f1faea5094494ddd353e3cc9eab1a4e5ae8101c5c05dcd4bcdb0b65d9f46dbba92b6a9b5eb5446bba278b6e2ccae0151e579b2d3b7ddb0e65d094dcbd838ecbacaf0d7d715ed2cacb7b9aeadbd51c044eb7aba546986afae2f2e3df85775f509fb61404a5da9343422842c68d7d5214d19420e57ea0bb25bae48847575b7f24a66c375a868872b7a3f20b0c00dbc2679d5976e544237fca86d570a45319a3697e2ca9162b0f94fcb659c17a21714573a3d0433ddfc2ac8a852aec63e27ece24fede28a542059e2ad74f85b015771a54b20ecb9c4494c20bec848affebf459c775de3aaa16ae9aeecb926882b0d9796292179c4f13fec964e43882afe510f4cf8f29bf0b322df2e66e41dfcc16fff9e92a2138d3e9fe8e5ce525a773fe254a5eaa11b97861f35cc796c9291d804c509487d603fa64789d78181e60b4ae10ab225802aa18938a202af6192c087d52297c9412ef8bb666a4ad3f0e6781adc2ceb20c222e29785ce3469264354531c68aa36eb4783a8d69c37b93146450f3e69ca91a092fd19e33966748a92106920d295eff67a5e933500c99453b5a59fa7e0204aeaecf66564b7e7f7391092f17fdbe9ee07fcb2fb8f36bcf6f5a084440b595b4ddf7ba56851cc6e16c38270070d7ed0c2bd1b932d6fa0bd9eacaa763b70bb942fe47c2b33c19ebeaf1a1a0c04bb7c4b82e4c0c113e578551798c889bd19cc2683de0301aabcbe1b20fb3d42b5532a2ae1225977ef36958ff04266981255f463768291e160b5e1bec2f5354f39ceddfa6349d4359a41618f74c0563c88334665d6d76f455486fc519fb05be6cc4996da6f92127b5d6c54099dbe7290ad4a6a1eb182aebad6e508e20aa9d1302d73290de601d0b8ca1b1dd1eb5e067266fb724ff5b2ab75ff74a5669639f951591bdd9231018a6d2e9cd20002da240208c90f8653940b43db3fccdab8697a86a48a935a07b4b12a98cf5eb4f14b5a8489739b7db09207144e4464008f7eb97589cff6400b9b369c561fe99ca08d294df973306e4a536a954b3e2b5eb4c7b49ac6999289e4702e63ee9d6224e3b0863a24abab60a240688391d406b2bb2864e9e834363e8419b48d2756ff2ac97cf8b3a90a9f7d036e9700ad9536d925f01aa64db01f985ed3265a28a869b3a628be53dbf7e587331689d6314bb2da7d91bc72c24822d4a29cda755e29e8667363ed92b4142e69ad7228b2b1baacb00d1aa280ce5932ac8d38e1fa64663e3d6c972b314fe5770abc10cce122d343a012aeb74cf1bde60953b6e6282530dc263db8f9415b532e67c4b88f03d3948b256fc2afc733672aefdd84adbec86cc0980c7e1eff138f47516eeaa9c28cdb657df35a0e1f54ada4c49c72044c270a0433b5493603beb32c52cc1da261bb46c3f28d4c91cee52001e2c6f67cc5e63e878e20493ebffeb79e51a7159d192b8a29d6ab4837366b8e1dce80c1b26be831e5da08a41772ca167df1e299e36942723201d4493fe4b21ea8465b604bd00d9d555fde50931e738019163aadf99db04240ed03f09d4cb43423b625865445227f04800ed8e4330b517825c3c757c5c9ee373afbd19f29b9f6428a77c8c18a172b6052c937e2bfcab4ed454c3f48d9626c8a5318ac4ae32e5bd7f6397a5b128f0f74ffedde2d8d17135b244a7c6de30ed40dafa754a79e841c5a67bdf77858719e82e0f4d84c0ed57011e1701f6109e504d7ce4c86ee219c16b2a84eb297b14c5d75c30975563e60d31706e7386e63ffb85aa57d71e0cbcdfada74ad62ad7e51ac17bb0472541b0841fd4e1458ad1c9c9fa1f9aacc0938d32e69511eaaee59b7d538dd2d8f1403982171b2afa50e260125aa26110514ce1be288a1474bb7a60101b54e46eee3d00ee525231ac42a92a609d971f4f4e0534f3e02aef29687c0766d3404fff4cf02a871934144c5566e33bb636a7539535c0d7811af55ba4acc1ac51be56f89f084af4291d38c5ac86ca766aac99d08e5a3380142dcdfae43698eca30471a9788d2babec9402a496b101bcc05be097fe4e8c2d3b5e8e54a108a7199284e459d054afa41d07ba7a954f5eee0a369ff5438f1acd89656957cfcac3ea3d6a2ba30a9710cea3b9c52a64d1999bebe4cf8fb26211ef063ab9e04d327b1c991e5fba332351da812fd6980c2294329ffb8aba29b500a6476840b17a7c5fc12a14b3705ea4fe584bfa994997c1cb546993e3f9987af5a8acb581b4c46ccec021e1502220f28225d4a3ef2e03e61caf168c26231b98c009024a1d73ac71d652abda6c990d4b02c464c64ce74120f8e8ea1d1e014fbc97dc4739799538de713454901924a836fa7cc44a34ee460c4c89ad13e364ac57557a0ef58d5551d42078907f68d827aa4e4efbccbb4c99a0a777bccb4bcab9a80593ee90865991cb1ee67349a67f036566242fe46d1ecfc86ae2941af28c388cad1cbe95e722c1fd9c5e527fc4047b78114ed16960c53efbcb89fd30224ca20b7db0427225e3b413cba0528d228f3cf8111e147483baf55ba56f53384957ae7856bf31f57cff816d8521a9bfab73aaaee24bdbc9539b4cfc6dd033d52fe68c65f25129b16abef4691e3b6886c41c76bb8f915ad31f74f6e2c745f490525987cb90199026f97847bd892b8b97585df41b13357902ccba35f13fea11c211c2c0acfa78c6e70fbb78086471195477f5971074514a70494e1e3587671196e1f1cabf7b29aad9a5b5cd08a397f1c1aa955e81de0f88187639ef05f5223cce35bdccbf95f11dc118120b880b242354557b440c6a1eca4cfca5120d9ba74e377d395e838224b3ce8bd990ef2b0c062c0eced82e14d10bd13c7474b0974d1eacf72bc90bcfb45c27abc73d5255bb402ea367101d07efc562370a84dc4a60e2a43b9e7f1bdfb0ca02bd75d8ca5863238821768f48403b9094a1562744d35e856db1d6ad26233836f1b8b3d7853f87f28d731007e219ebad3a78ca9250f285d3a2092eaf21b28bddaebfa5f760a5602c63fc1b64c49bb4dbac169676e20a7397b5da6aa0cff443d9d4d92ccbe1b95e5b2127860899c2a5e03a3a35e9e3d7a48354898cdd20edfba76a4eb4361bc9b8f5460396f5a7738129a9885d48c4feaaa1e21751ca2ec9408f090289d3218a16732d3128a9ce996873c130536b11ff54dc0c83464e3019528c07cfc72932d1fe42af7d9472b61122850da19af102e551a1f5c99d19acbaed14a0672e61ada147465c3d3203ea7f3e130253fd0e7dc086330552d0157e0cda39dbcba4246cc4ef56e0360e8ec6ec05e69cc780788f12b619cfdcdd1e69afccd5786a5dee8842a05948a8fe5d72c924bfed29bbd90f21ebbd3ac5bdf364d337f9b9493f269110c51097ee065b851330d7c11d43c59ca91eb3513dee96d5b02b330575bf2cde0b3d27e0c19d012a295e8d5bea40d91f1cf4eca5ebbc3005235de21ce26acdfab03338c116cfd7132aaea05ac328188a20be8ecf72d396d1a0c1b587a4c1f200a932c8b53a82a53787520a29de46c114114a0c52e2cebbc2238af74c2121f357ed000a130b0efeb89a5ee3709e19cb7fc476b5e75c77be7e3b11c07ad97001b12d9f0919fcd1119cb5b14e5d4d557edaed75028fdf2ba36682d31610072f3ed77b3446c3845a6358a624dced93ff1251ca7e98d99007aba94a3ac3ccda32f7ddaae4da6536295ff4e6661690825a44888445d4d0a314ce151a00234c30b706d7f8373546fd508950178a7b92b7605f12f3860b4554460e79569caa9efd69756e6e7ff7cf8ca063785ff4966844ef73774421272b435c7a6fb4122d71ed4a4ca416211e28a18013f6c4190c311cdc5dae88a3cb6b81aae8c40255daf4e9d94664f635a1ba5df78df6665b38861d4469e87debe4c297952fe78363fc1720776eac0e80d7dbb093075aac187a8d856ed19dadcfcdd9a1c230bfc5db37cf07082363cc53cb036aeee6b8a2303baa1841d482639279234ca5094c152d017d186f4251989c6cecee7656a363a3fca5721d1e5d96267f0ee7e0fbe68b6e5097f40fbf899eb3c982f06b9a1374f02ff6bb01b4def0f44fd160a48218d15e05ffe644e395377a48ce192f7f52e171dc78d69cb69b92bcd9630599a69bf7429adf32d4d7102b419c8de33af013222bf9999826dbbf3a71574394200deb89a2584f4f02c5dc9f22e2d0e2b8295699d68fc8dcefcf69d41c6c050b00750b2f9f2d09dedb038dced9627cd330c49baa2281707a0d5b5812b0a6ea7373bf1ae9038f092bcc0186a8185421de324a12e13b5a470dfc86b439d297798b8e01911000aa4d82b9e8c01739603bba2060a649b3f6d3c090eee396eabde73aa50afcf9e133a233b9f01e54cb8ae4bf9c89b3d9f45ccc3ffa0587e0998b6f52eee3f14c2b26201e15eb9a2e0be1e70b8a6b178af5f650ff203ab4da9b4eb0f79f79052633f4f3bb84df208a9ef1e2ac83a34f4dc98291553689a0b86f027886203c71fcd4b4ecf45e747fbaf839e39101483c1bfabf11401a769c6f539d3201bbd776ca33e1a8477b2c3e673ad8741ce2b794efede4da8b076f212cb1303d9cdc2f1dc9af37445aee10c54af64968087e781869aa4a8ec838f69ef6df33fb5c58d9700a1e97b7b1ce9a78e9d4cde3b25f0c47aa13fe47b4fc8f7131eced6a09f38ef4f36fe399f1707560fbabd808ab00d07b03128bd4e7fa7e89440a170cdbe119b6ab2afed56ad4f3383e026861eb123bd99e308044a78cfdd19f1cbe5a0ae21fe747793afaa4835d68443d81970b04fa2cd6e7790ae8a1fee6cdc111fa9c5f294f3fd34af02dce9de92e6a96754711a97028683855d0ff57c2592d764ca7cd3ab8a2f3b93b67f97028401ec077dcd6d5d73f6f1656156bbe1a2b37b529faa0c68ce9e983e52b3b4c03c9c9929828f53c48bc18772a15eaf4b0c736dcfe8348dd5e3fee0aecd97764bc18979dd82e383b70b2f77eb62cff777dcb579a0dc3607acfbc881a1c6a7bf3d75561fd6ab5c5152f35e709ad3e639190271445ac40e14d9e085523883d6ee05857d7bcc911d0e0da31bda585a626e82d9334a198d1b58597fdface62ec301785357ef60254528ad1e9e01bf0bbb35f2c4c2ada4079da756089f11d8f50d15cdd7c6cbd6ddded430092e80bd35048b4794e5f8201c6e2d706cc09e050cc1aea99fbe4dfa75a2e4e8807305bea3438f9b8ad80b2d19a0e551863285ae93301446dec36e878d7b901a094436da703aba3a3c6a7a96f95d92a05f236a46990aea8e7910dba4295aee06e2ae6bcb7748878235c46c97cb16f268754a2f77be2dbeb7a6016d302fb3fd24928fe5dc5ff29a5019a2e3609576a3dcee34a183756431c65667e640117d4185e5f9fa9ec7857739dc1d44d400355666fcd46e526457b9e27f7b5c1f5719d3021af9b30143104d67b49b7e968cbf642333d49d822f1761691611a918b81581cf3d75f8b0a6edc738460e7b9ef88ef13eecd287c00708580f1b460fa7c48951594308cdde8a57e95015617ff960f7a90ff750bc098a90890460b8ebef1ef449a9245856c9ed690a181baa9c7eb09e6e99eace9ac2c9fc1b314477e0ab7abaf5694858b14c43d046e544fb1738ced9dbba4ca85a0b1eec2223b4bfc061b19d1d215a739c7cf266dc160879c419649c280d0ab245b52eb93ce2e5f58863c3c13b69eee24f19d565dae6a33390fb4750a7289ce1d63ff9d6e895254c66c09fb1166e1a9cc54de8d270b05c27c19264e049edb45f23f242935e044e934a1a11ec33c8788eceef02d6788c742994fcdb312af31066927c38ee3af958c5a14ca6dd893a7f93838e40c113d50039d5f91be3d3fc66da33878ec5bc8dbabc8a839e04b729f431513b8501721a49fc5e46d7c4722c68ecffac1ddb6248526c3a5b08f021379f05a3e14be8a1cffe11a776374f58de913b252b9e8065bcfbcc8b62559d3abe164e38debdb20276391b841f5694155e33e348b751f7b61f7dfb7bbb69ce29eb120d6497357648a2da944b9b1488952009980df931787f62bd148081e1e1448edb91b45b55736359b7ed423dbecb00915610a7f14bcdaa18230cd32e8c512755c0781b9605203502ec51d65ce3fd6a833f5f93fcfac8f18520c53a56b5e835958cca074c9f6b5a22fcc476e58a107dd1418e2acdcec989342edae33ed963f2a71eea0f0d4dc5bb5a47f09009dbac8ad90589eee7750624baa6fbdd78ce2e39668554b68da081d2c926142130755a58f2362f71997fad664724e4c56bb54d21b1e4ec14730d9d367eb782d61abe2a47edc2b460f18031e1c76e5f150233e9109ed0113b7759f5fdfd5196871cd97541f700179e83e6e841a3c252fb2396e11a7595fc6160433f36f238ed801ce24fb615cc3af455a2e54655c22efc7ca2bc107ebdb37f6c42338a0f7f48d5d0dd230d653a2d631b8d2a1d0e213672f84ef4d3b527ce63e117620ed194b53d2761b813d1f90fd1d882221429c34bacc54a046293a865b068b06bd2b40ed53bb140446b176bd903569f0c7a0f6185b4bdd187c7cefffd6e7459e3db10390e0781696f846e8e5f16e08b82027504ad5b8f369e8a10d4e82200c0152c8aeab7d1f02a60610c832308044aaca8835c4b878d238a75e11946c4bd7b9b1fc928a6c34b61241d9e144a807b6edb990578243326efffff58f2c12a76b5fee490696ed4123f35aa1b3659d823e5fac7f57f401da9243bae7026026e80b3609cff8bb4ece118d47f238fdfaa315201e6094b0af13a647a6dfe2861929da3c45f270cd6a5b3a95d8ba002ff206fff230c66277184dc2e307d87f73aba02bcff024a681a7c5d40d219ad0ed5049f9aea5dc85d86408a7218ecd8f3e42cf9253b9a124595db2ab8ec2cdf1ac980b3330472af83b23a300033e3efd9c5ddb9319a2772d2de0c461e9091bb71f7680e1f9c415148338dc331af20520176f9e53622654a32ac07b707950715f41baad942541afe1f68201a499dc1923aa747a40a0eb2bff595cdf2cb17f6e9ba30be2eadc0366bef1d0f96cfacc0fd9d4a27015726365252a7c95ee5342029fdd35a380dd7536c88b8e8374ef3e25b2a8e14d41c1d45ade1df5264ffd057b0f5d6388818dbdfce1887bd8a5a1d8fe6d9bec5ab1564f946596eb08de5378fc50bb7d7de762e6ceff22d5e671d76f36ac63570f9458cefde5c11e3bf25a7d9b616966fd95efb6df36e49f3aed848c0db8757bc37dbeb7096966fb48587a5e56b94e5bd7b21cb2c5ff358d169b467d9b6ef0e062199e5bb6b408d22278a9ccca2b17c302fe0d71e7fdac7012e5b5d0502f65ff1b20a6edfe8f6342108b2f6fe2adeade0f69d572bb87d8d3ae8cf79b7d4b9d0b970f3f6d6d73c98776fae8e8765bd7b73bde3917d570cfb8a3901e2d7bc641d8ffeee785857741004fdb3df3615ce7aa1dc5ecd8daa3844ebb7fa00d1f6f2d257f765ede003922d7423bd84de6288cf023a5bde85d1fdd2ddd3a9145c33d6a90f16e3a56fe8e546ecb4d397eece42ebc630ec05cb2c86611886f9a8d0dd22182f2f2f2f1fce80e1d9951d39d1a93f917a564124d7eede7b43ce651177bdabd6584fcb5bb7e5757ef188bc7c494016e843eded6faf750dc0defaac7b417bed37ef9a0283bee6660265ccd86bb5762f688fbd0ed07f15837ea583414806fd0ba0dfb62ebab82ed0760db0b9b9ce01b68b2eda6b0d7bb3b5accc8d00e475fd20c832e8adcd20cf2b0dfb5de782e540fdeed93ea873a133f6d656bbeb6c61b28be3343099d7f9de388dfd827879ff5bba268ecbbcf0e264ff2b3a8dffbdb1a45ae37f4d1608c3f88824b93e07ad7d5e60b2c05ab74c1f01879d66ff4e4b229c5e6ab7cf8be8e5a5bb5fb2c019c6b065e2a488dce98bcf3dbdf01b4248493b7252fb81a07bbeb0452d5625ceb7c8139c5c777240737873ddc98107d908915ba6a7979e2f12c19c5d454c15a2502806ce42f843e0cf80d555a0c24b211797172afbd20d018b2e18af38c6699eb93c2c3c98e3b66ce643a1ccda2858c856644aae3b45a4e4f092457876e4f0b40bf976e4a878ba6e470e4f4f814337b9c94d6e72939b76e4f0380d8fca69c21c82c073ff8e9cd4db91a31202de91d3f3a1b27dcce1bc2387a7763b72540ed6cce360a5097bcb7e470e941d3950f28e9c1e2755e771929b76e4a03b72d29ede9193eec851a13b72a060dd8e1c283b724e37edc84157d891030575539e599275b76fad9bef178620dfd2004eaafd100bfd21181f1990969e9eb226fb32cc83f1913df6d8076443424df609a96929b0dfaf03dd450e4570758043d660de86841aebd53a64c816650f0932ec7258667158a6655996619986651787651ac6619996719966bdab66a95407471e6a32cf962ec8c1a646cb3c57022707120851b361d8a5120ac9d66798f5320cfb0cc3b02c3b954082d83c44e9296b306f66acd9ae6a5dfda80d5eb0aac13c91919acd722d050eb3cc8edac2b20c48dda2660455891aec84030cfb11d4247ec61aec4b02d32f246fdaa744cad69a2cfb11d0c802879aecab6e2374c932ec5ed775bdcdd71786205b5fc5bc5682889afb966b51e82786e888aaa89bc91020ea13207265e2839309133b57942b0a4924e39aa236109a89ecfa6e8262e204c72ad55cef5667702d4d9b1c66e1cdfe75c70950b27f96792ad7d083939bda07650f56e34873aff571fc8b84d711dbefee18c7711cc7711c47b3cd36db6cb3cd36db6c731cc7711cc7711c2d4ba5d1ddd766b8d2a8bf04ee5e02f7d71762db878035865dd8d59684bf711cc7711c47eb5ade516cfd034b0e4d8a989a14a14193224a9a145902a54911274e9a0c2187f034190225872643a4341932a5090e459a14e969828349cbb5090e2fa85ee780b95c9be01004932b7a72c865c72295fb6eb5e336908a6dc1a939b3246f9364c5012a85e0c4123b8d2d6b7d4d3a684bb7619f4892f610067ed4f0030281b413a4a84869d6667196f5d269bfcb27f6bbe727db7692ad6d9e6cadb53fd93ac9d917fe0f06bc1f0edabfbc1a1cb45fbb0574b63e64d9ef2f73d01a814f31e8b6ede4c4a4891b944920298780da91b392f2d36de519b2eaa011b8dffff24b8426dd863f9124f676ca92328c43a17fc772db00f7a83840d93f061f2b84e08429f330ff100ee16a56f343b9662b646f6477afd6f4127c3ffc954f1c319be08ce3388e6398dd701adbddaaa44b965b2fe8aefda4afdabe63c5918ef136c0a3fa60c5a1428003e4fe27d63c5df48dd674e606ccd7d364ea53ee191e9118bf35d7f158c1c1aeaf8569c6eb703bc3ad576baa771dacf94e6dda94f9dc4f8944117278c30a1f607e9afdfda4fa50db5471d88fd14872bdb1a436eba857fac3951c662a796b6cbfb6fd32071bbb8d7e2249aafd072da94d2fbee5ddebbc3d07ca70e7f2d59242bf02e37bf1aa832edf0baf4aa9aa95cfca5b772a5f75b06b9c81be3064fa2f0473fd42303fa0d6e870fb75a97e2d5e073791071343ccc3c0c8d03cc0f5abad1fbeb59508a98d8dcd1003e880c1344121e23f4da420872c10e16c9a883b37680eab93dc39acd66b9bfa1b3ba073e87578c8ab9e49850fc1bc8c18220fb4a3fe18afda910c0fc69389e1a522afd6c0741b81eba7309c8504e3388e23a989ad8a443d8e7524c7711c2faf8ef6bbd5fac26b57b0fafa58ef9ec00281044370dd6102997bb8de3960265690b932b102c5245d3181825c61f2c493951ce7ce5944ea438a04454994741b6cfdf518ce72dd81b2c3f575286f132b0ddf4c9bb81939cf138b6d07f444a57c086a88546775a82e257acbeb8630b1565a9255e35dd795dc4627deadb1cfd02cbb692a25d3324333d4cb529917bd0cff335e06d17b5f109917fd8c2f4892df44d17fa91f322d4d5cc5a14afd9069d90de1a05f1aa995d6564251f42ccdcd7442a548f44453344da11cb4b69b4ddc4a6ec312f15c560ca317a132db8fd38496ca5259529c86db444b95a11a490ad1915d8e4c8783ec1fd3a13a9496a62800609b11ec48cc266e3c6ca296a697092e71d3611337212aa9138d5412a712772ade8aa8d9a6248bbee2d0b2bfc853a97c5021b9c44d874dbcc4ce919997dc7468d23d02bbc4ccec1c9e222dc94a1dd1248b88ccbc3c6b6579960f116dfd647f6b8b94255959440107aae642251289a048a1402d16b4251aa95da1a57534e2385577627773a1b2205125d71d2864bbcd767361e1015c779c10774ef4aaa21337712b75b1044e755581bf43a1502015b416698a4a5129eaa6699a5a25eb8726b832317152ffceccfea165e6274ea3d29376a685e320865aa8837e7d7f88994ef3c469ae0f5b613f53c0a146665148324a1df95f5f981521cc8ed0844ee4549cea9e3df2cf328cd17b66a8cff90414518a70846e956a8a2b882004b475504d07f46a0c6009d64a8d24656464646464649a47c6db4a9be9844a91a5290ac02636aaa5cd358aa268ed7a656897291626a823ff1e5a70c920fb6ba96d2dbd2c0cc33090d823ff2c0b8566ccc8313e20117424fb834c00ea01d40219582a5577df0087f784a2e2c04176a2e6f0545f2817751a1e27cda838eefb5fa2d35cd7759d2c2900a850884c9124597637179dd87527763717aa4e14ed79268171ae3b514891b51c6e0158e1450b8bb7e9541a64aa7b80d768dbf713f0f65d54fbee29057ca1ae942569fe244996a479557192e7799e9b380587f7bce7452fb1e2a8b98c541248aca0cb870c82c15532650f001ef7795de450cb9e75a15cf49ed73db3d6a12c49d344ad84bf5033696496617c4f8dbc4434d539b434754f5496c2e82542394d27658af4369dceb1f1a0d6d890f0fe8122848ca78ea2647341763786ae6cdbb6895e73792011b524d08d8ffc1d8493fd438c0bfc223b4114050c129b0bb49b8b14eeec79b60643318662d00da80432817e386d22ca922c95aa5491aad4f5312208748df75bed2d70dd798227ab9ca6ee383125fb6f374e53da70ae2a4ed5255ea54dbcc4adb489cdd32b9ca5a8830d051c82c49ca1f952b1d732dd546519ce50d16af70b6fd87b821f0a617ccf34460ead522ebbe64e76e41b194a610e95a1aaec076fabeccfd98897c8952e91335d1b6a47fe9db741d94ed38efc376f73e2a03fc8dbca4dc7dbc82db5952a8d6d874d44925d4b371fd20b12677c9b68474fc0bf8976e4d68575d725e4ebdbc42e91205b1f0bdd023c5f325f0c3dd21cce98e41529d9393ab16b68a925ddd38eb42b9a7483d01ad9899da343758d0cb5a38c8af62e53a5e17f79574645962f1f6a8d23570b72ba1b73e106955191a19674e970c120fb875d4ef6d7ba46255bdfe5041c6e9bb8893eddd7cd7582eb07d5e582205c38a7255d3aa8b27f0b1d0f2d70b881361194829aa313412bc8fe201c9008325d220a245e3f7462e7b85c30c555ba60d089978908d9ffea2eb10938dc36b1bbbbae4ddc449ff3063b38d59f161616fc424097c00c34b8042acd052e5069365069d840136cf091ff0d96c4d9b4785b585830c62cde0df2cab22b9391a1c28c8e13c5c8e854d0b2ebba6e48cce5c2c8c691bd7f33a1ed286c2e729f70c8fe5b7329540fd1a893914ac3fd080b4e3c984e91e5a7e25842d572d83f9894c109ca499224d9596459ae0958016bd043ee29ad45ff6c00e07c89930efa920f549aae4105518e729a2e55b006252bc4076ef9950f489095efbee5810449e263e5bbc72f24eb2424594bdcd212a4fb956702ee72dd89e20939cb95c9109f903b49561c5cd9a789a6a9ab4eff21fba681b0271479224b52246dfcc757e689a6ae8a918155eb562cdb4b2eb68e83de9f935eba0df2866c1dd28ad99fec7eebcd722b6fe3a48ed7d5e9449ec8d3c988e9080fa2d8250efb3cc54602877d16611a413221fb081cf6499ecd031cf67976773f11e584428ab308edd3ddad4392e4491ad1845c8204c9449fe77976fb68dd5d44b78f114120cfee5e026944137209122713edd3dd4d923ae4491ad1845c82c4c944b74e699e648f9fd33ccff3f4e9ee264fd28826e412244826fa3ccfd3a7bbbb9b3c49239a904b9020c97e22ca098514e7d93eddddfdd33aa549a2a9abfcc7493bf232ecf389282714529c45e86e0c5b9fee6e1d92245b09e4491ad1845c8204c9449fe779763be9a4cfedef34955048062b8d7eeb2204e41688c296d9334b6a22faeb26a2b1da294b0285586d23e0b0fe68b98d806ddf7bef170a0959ae46e1860a3a8e4a44f6964aea541de1fba98a63cbae834ab2a6e641f620fc6d10d91b49f6ef1b5472e6794da3d6b4ba0148c551bbfb6fc7a3ef6783838dadb530541afe3dbe20b22f6447ee34a994b59efdacef67db6650f03ad524c944083fadea86c129742b4db53eb09206d023cf51bbc6f5e56adfcb2fea679604e3eb873883fea2d2eca8a0ebf050ed1c2c740d0ec42ed18eacd7a84ac3ff7a7d2aa138404ded7dee53c5214425f5ce12ad840ce2e53b0b9c61d09266b83e54c9214863c38e4af38151b8aab09f10ef1eeeeef6dd2d976bfb147e45a91dba0f8201c180349cddfb18c7e40a1c18969531bf25e8b61cc90c932e9c989999394ba8149324a2609244cabb73cd2eaea73761e9beda6107eb8bfca24b360757bde99b9b232dd623373743b66eef78b8b5f65ecfb2bc90855cff9a598067b0d2a85fab0edf2e0cc3b2ccd334b7626bdcedce750f0eb3b6d97e6108faeb28b6ad7175b0bd0be16cafbdd7b22e0fcb1a530985640fc2b6ad34e65169dc5c8d80c3157275b0e66add7bd81a8b6ad328da7d050e3323e030d4b3d245c0d5ba4290fb73525af1030e103ad956fb376fc05ade75d05a7ddd5abf1dc2a1106c495df35758176ceb2d54d09df42bacafb2e054b4153527820ea9a0bff6f58fe626bf62756d7bdf50c8921aed908fd9bfbd9a6d8f9daa344407ddbb0578f692ed463bed56b5edc1965a654bb6870aaabcefca2a82f255a5e15bd491bf58248f72e8a8a37d571e041c3aea3c4e63df4717421d45e921bb104b00c2a5f80f3dd97add6e55bc5469e064479d0c49a934bc550e7a8b0dc569ec931cde08d9b63768b06d5b045f60f4450b331574d28e1c059db4a495a67daa55e8dd866bdf9ec8c11639e96bfc434ed34cc036d7f20952f2cd95090e2bc8ed012b87b674a4072b9a000527db02ef01872ebad8f76f88a278c3de686badb5da67efcd5a98b1ddb52dcc38da1505dd8d80c34e79b66477202d0f0dfadb5376ab82aee1ef3de0d0966c7777dff042308737ba5b9871b0821eaa2dc0e4be3904b3db52c581b3bfc5a9384cd6874a72d422c958943c172b0d37e226c7c2776855a32595aa558ee2b055b9b14ef95d5992dda18efc7dc890602b44765589071cdad55ddd9507acbbea9b4a43fb162d49fb6ed8917f8b2d82d9966ce9060d376edcb8c182756bad13e60538b2d515c28b85a565d0a7abc42d594e4a94a7cee1a36bb8124da2c0edd3e5dda0814ac39f02f5c747e70841ad11d62804e147a5b159ae6d5071ace4274e636f694f21b09cb1b95272cfdcd242c9eceadab07ce6d9290eaedcc6925a4c2d9e5dd97816751b670a677f2decca4e65c9929cc8f65c892bad94544a2aa552f7d896328965e50b1d08952ff421469dcda6e5391b9b90f9c2743145960fb5bcf5dd2fc42e6fa13829f4dd179c8b5dd9f3e513e5d076f7fd8725f913e77128d9ff8993ec14bb7273754f274b6241a52ca9852ccd13bde9edb92a4b0a7577f782ffe89caaeae6c27cf28326fc445db84ef0c77c7d799997c1e563be2031eff2325f90243e62dee583d49af9c7c8942fefa2c2bfbc0f15fe45c6abf0fdf98079970f88e861dee2ff189917f23de35d1e88ccbfbc108cf1cb3cb6ab8cfff3be24311f916bcfb7e8035e7ec6cbf012f3ff05f98ff98ff92033fee596332f33ef5dd38eee59babccc876d53babc8f9777f98024e90712f32fdf9f0f9797f980c8bccb0e2e9e25e359a61d59a905e3592b4f05afda1188e5b7ee5ce87cdddcb28140dd9383767562b1112da9e50be2f22d25971696d7613d90175e36b6c5b3313cab0222a4c69ea5d2c935dd8699fd962d9f7d56492c9f7d617fd72cdb696a6e4b6ae99589a492daa67b78a030b1c49353082545647ff1b7b42498ec5fdeb42498ec8379008c77791962fccb17e4e563bc7c8c0fe2f2307eebacbbeebe30c465df98fb5b72efdcf6953aecc81f462d6b794dafbca58328c09ddba6b4b1b1b1e97ef125096f794b9f168fc5bb4a2c42567c4691eeec6ad0a1b42334b23bd4a569964a4bb5239aa45dd11dca52750e4ee5deb980f214aa73b893ae61496e3a114df2269ca0ac1aa09c084f7949bbe62dc29b702777895b5e23dcc965a2884ab294a4c81499eac6b09f55115d942925562a95c24e4be2522155c6d9b6890ea62fde75c029ba898ec326b64563e090122f216f738191a182a85b5a627c3f01c7f85a5220102a8c51af5008e314550212d114995a92557af195d2f4c79234327b426aa9254b1db1af9b0ad129c9de914ae85028144a3359d2563aa150a913933c053f40156e227abfec343bb16b9dd4f64399c9dbdd164d794e80c30c6dd169aec75e3c8dcaf6832ae541bb37b1c76f7a4cd526aa3651b589a669aa5094c7495a9a6628c761d975b389d7bf78ec0b3913e0ad74bf4d741086b7bdf0361c07fd5fbccd7404bb7c5aa9910eba11d56604894aa5da441771b8895d3ad1b9f7d3524d252a82432dd54ab741e680435086da340589a15c77a0282192d15cebf4a4d7ab7c785f4b1dd454a90a24aad29ede419af6a86aaa2a4907bd04585369a98397a7f510e99a9a3e01a52cc97b7faee49c384d87333ace9d6c30f4094766e75299437162e64a9ca92d53a599545a49859aa8899a28e666ff252d373b47669a2613e611241638bc272c7068cf8c72d02d4f25671aee6bd3a14766e7b0b6a8353e9f4ae27c542a95eac2302cb27fc8adac4e86d385d2d302e1a44bf4917f36c436eae40be5c4da4a26a90b01817ff0ecc2c99d58697cb892436cc5c2ac9283d6f52c1c12e0d02a65ab9404fb4db4a498f74f5994655a526ce2269e96a4912449a272b8a53654e87ebdc2d887adb01fad43a92a0e9faada44c76113bb3b6b4e15b2ac144605865aa9ce81fd58258c8a26592ab0ac14f6d3392ed9352cd3524193ac26c89f954f133f64e7e0b6302d89cb220a46f81c410b27753852ba5267f2a9248d5cc22ac6ca8195c2a8c0d07b6e3b043d6048d51209a76a4ac190910e713af580a156551276902f1f9e328bd41186e4eb67ca231891afd721e504f9fa1e52d27cbd4b3db100912f54e500b2fd966a2ac04241c4114c50c28067c8901aab42b636a7530f18ea153de4ebfaec8a25f9fa100ef92ab120a2540da9a6548849174e5cd7f5595e03dc03062348514da9148c24265ad3d2084baa29e552fe40073d60486d514d2997183b2912251c53ca927a98291287d53c9d7ac050736ccaa546da8385134fe0210653600c2981e628ebb18e87d543240b20dbbfae4d409415006107054c2c21850b143f78aca6d3e965074a0ea5128ee9644936a57df71238b42933d503ad6955d59fb2083c5493d9c365278a254ad6b3a6128ecf00f7d7dc63721afbd94eddbf1e879ce645cb8e15474ca51b5c73689de0167bdcd06135d19a1f9b5a122127cbb66449594dbf6d0bcdb6cc15004258e8f661c1388ee3e83518ddd6eb886d6b2641c0c9f5cc427211eccf248a2919b06860d1e09ac23a617317f469633e08958e4125feb0e186cb8283179cb17ed850923a5227545dd98825938e14a7a39a3fece886700d0ede1f36b80d958e0ebf3fece8666523018361d9ffb86f03901671ee6d53bea77c1fcb68709a7b6fc7c392403bba6009822cdf2223df778cedcb781e03b2360d541af72def8650c5841f7d84eac7cf0dada3fad10ab0c1462c994ea81f76747be870f0f64f7f9f4ff8c961e02f10c9681f52c7711cc7711c47918cf61b3755518f751c45a2ee156eeeb309a51362e984a97b07637fcd15fb0bca40200da465dd99069b6535b5db2bc09266ecf65d4aec9db1b5c461053c5b15f535c558bb87029c464589e3e8a04480017c64fd8c25d9afc70d4bd20183a37a388d0361cde0a0f556f7f665e0de3ffb0549e2c39fbb17865d97f3befbf7af11e0be7b19547ee565e81e77bfd2594f927d7d9d0a8e81fb60aef7d1f97e75ab30326ee3386875c941cb7a2249b08cecd29264aaf596b5b978b526c64f9664933fccc22c2bbbc962786952ccd6fb29c6eb5ec6e3de455402fb9cc8ab35d85bff02039a74c313d912a7c8d66f3585cad6f710d637697deb58ed274bea5229ab40a561fd0d96640126885964cb7aeca3a1c41de3c978190f4674f578a192ba883ab2ded232d94790ade32719308f7ddb00df18afc21381f1a16fd45adf96bf55561c59b674b0cd1eb80e44c531834aea1d7cf024271f4bad538279808c17fd0c301ff3ddc520f31890f19a14f512fc83869a763cae0c19305f3b98183a2e883ff732bc2049ae0f62bfb31df72a1fc36379181efe17def62e5ecb6758ad09619755da91f55dcbe659a41d5928cb6afbeee5e5211d46d257d0448c244924a35a96755957d7ae0257c1ddf9617222793fcd9d93056ddbdb3b897652476f5f8b449e82eec13892e33892e3388ee3d83d18c7711cc7711cc7711c7becb1ea3878bfea2079390b10fd4424a38a443d8e75148944e3388ea3a7a0c7b18ee3d863edee56c25545f712dfe14a496d47b2db666dafcb7d50d2be439b5b158944fdf586425956b36bfb1b0b914846d7bea2d46e5f6227253649c1388ee3388e6d8ee3388ee338ceec3861bca028c9d9aa482412d5aef7b60d0b6c4f711a95ce59a0444adb80f4d169fa5367b7bdcd45af1a0a1708e98c830670f06619c6219bd6bbb26cfcae6c6e69e68683a56a5571d87cff4e719ab64a4bba286b9d2c4985bf6fa12c29c6df97bf6f919614fa8b425127ca6c29b727ed4cba537c74ffba70b92d0c8469a06ba6e6a9fa497b54527eb4701aabc58f949eb45b95fa4daa4a7bcc134d5569eaa0edd122dfbfef26c056956a91f6480179f6e708be3f2a07dd880a75b7d80165043504755777954291653fb1770807af793e71f05eb3649e29b771df7a1725051c5e54be7775cd95df5657c6db67f1aa771dbcf7aecc2f83f9b62be3b322918ceeb4b9489beb3be5aeae287765d33bb8ab3be5ae6c4cd3342b7745c1bf5dfbd6b271f0ded59d42048777755796cd35b1d9a55664ce5a9b5dd1921a756dca1b29e7a5b7e69352a9544a82e749c9573faab40768a9243a2151a8b224c9327532954aa598719d047e9b5ad25d85d9ca178654beedefeaae74f40adfb878065f6bad54143517960d5f87027ae0b2abe3745b274143c14b48acda8dddbf10fb57ebfa56b062b0d515c2b6623e94ad85b9df7d85b91f4c04fafd6560f99697c1bffb827c4192f8e877fb3f2ca9c5aaba18c6be45ec2df68599db67b1f6c37fbfeec5162b0eaee2a829b2b40a70d0eae871b116f3b7508bcb8b1f96f4c3d69f6cb16f06b4d796dc86157930550d58234183ade80c13b0dff6db5a3f2c49871dd9b799d5b9a09275946097606db18f6811fbb0c5d04f09e5346355e964db38d95adba9b60fd2b01f5cd76042a5c8d2ec226a60b18fbd2ed991b5afd2d9ef25d806076d55b954d1dd4bba846198fd1a857d888720511507a732ade7cbbedbac2e112596b25028e42d689455637d2d2681b12eee65d8f0775f90ee71f7f88370d795595f88b1f58db2feb26e5c44b8af7631748df21660d8e7a3fb4cfb9cf5d7731886699886755fbbdb7d40ec634da53461b0ef54cde6c1605f0cb5c6e6861586611886691e96655986650f815ac3f298d7af7997d6a8ebb3ebb54cf3b0ccc292ce6047d7639e95fb07d75c3ffb7cd8c78fb14ed9d1f59bcaf52bdef5dcf5ddd6283bbab0af4507af0f1b952fb1da910ffb3fec48952f22f7ed972cc7019df1a8246c586e7a142a1a080000100043170000200c0a8684225198a661d6707e14800d6a86566250389206839128875110044110c330ca18820031c618631473451c0031fc9c60218f8f35f790cc3daa0322df584d006e2915586d636dee8bb7e8ed280a520422d37ac729041932adb53054586f2660da225b59e0ee1bb46ac67b2cf31436e44b320ebbaa6d590389741b25732096f949d7567d7ec8262f398bc950f48bbdf43ba6c2eb8b2d17b1d4d8f5996f259a19d14a4b3b48b938d62510795dba825c401507beb0206a44fd9282bdcffdc1951749b3b67a321388bc0497196821b1a7b223631794b067574e09e3de16ed131d18a2782e5a26f9135cd666ef26edee64fd3e9a167a1313f3833fa440e4333d4a112864b092a351145c7eabc09adb6815bee1c2b2513dcb518e523d3c2a1059ebcbf34e420b3d1956ee88a96b724a70cb2ea89c9420c559e588024ff0bacae0c40463b29b841f6ec1fd23cb79d605775229f94bbfcfc8b9e1d45ff5953c842f88135eaaf71d65be851a479e74d0212b103948614e68dead0b117fb940641b0f5b7aca6cbebde8deae1434aa55fa2cfd37e444dab27d0c9d8784af8a6fb1a8e875adeb1f29b7499a5a2c1099cfdf64f7fa5fb0e799d5362d1099b0689d71532e10f9208babb59005d9a1e8d2de53a3b3d4552883cd3355100eb00a5972901988ccd15c6b20b21b5c2cc3f075b07114318a4e6f4ed957501e9926820cdf9bd32ec3a136b40f9ecbde247ca8ed2e211b9b051c886c1d613b05d9ed4aaa633831faeb6b04d2c3d32c3cfa7c8188a405b1585337a738a5ff8748c46a8ad421343a50174d86887d9cf58ea5993bd7be8aab371f579d28d42139e636a58602ac1cc44263e8607365a737980d35fdb408cb0ffae8d6d8c756642648affa41bd5261ce53c7f14313a5d8528c65b7d44af00a2bbbbb121fa715c3c7349f53014255c5ed077a08c16288f075d8acbee2ef9148544810b48e14b06a287c0724a3882b4634ca9c264142492931b7e5beed06cfb3142a1ae78923790d8bce12c82ecb37074c8f95d3b30095b9772c10a9470db7916f671be92e43fe11837255cb04bdf507fae2c8a3a06657d03c04fc6c481007f694c32b7b3781e0f29635ab57f1ac1ece492dbd412198c4f8a41c80d463453f902cca84b218200df183ff7c7555f59ff0e27185f78d28911f12eb0f7454c2b345c84224facd9d33ed7496c95b9ed4c32a9975faf955b4ec6ac5b688955924a8500709fd510b2fde0bc9269623127c168bd8c58daebf586afea38424e1c5eb47fca43ca09b75389ee22ca2e898eb05bed4408df210edb81e6adae9444c589e6841bb5b854b0ef4170020e853f874cf3edd3106dd089e6323b008b3337bed49cc33cc0e406e334e4288b2e07d73ff66b349349e700810f48c20fbd662967e8da1f8d1d84367b7fc10107470d81461cf119c61c61171030b0f035fd05da9085fef0154646c883db15044eb2e02fe4ace3cd0c1d5136448cf1f0926ea551edbe29e06e257aff73a732fe274aa742ddca0d247b7670fb5071d6baf0e603f0f7c9d36e2a2f18e0e96d88fe9c7b31023b7cdb3074b5b69bbffba740be55481a08d0f9c2edae44e0c305a9dd0289d6b3feba00bb8f030d76d4a5661de6ac09ed779fbbeaea71044dcd12bbc33984f82794137ece602415f2c20005df0256fa38b4c419d8eced6a15d14a9dc1d869675725c75a0b9e3281a548f90b4104036b3a2e5cc7a8fca7614651f42c5b3ad5507e1feb398f82b448bb6d541adedc42d894a0f8c09f030719da65561273e1b2dd9773069efa939c4e6e6aa01301fffb88c12bd46a6880c1420ada805104cb4ec101f2d9aa1a1640e73c373c6feeecc3d6e4ecb57767bedaf01b35d88430db8afc65f03ffc0277f068f06efdeb5426a21ef4acd7c4b3c9544f9f3168c425536298db84ada9c5d2dd1bff9620fe083a31542d9c99fdd46e1a918e5c1e4cfa689888543b0452b216a842545e81d00ffdd9808caa380fff697287c390630302147881b46b0924a129f23722ff05944eb9f8f703900bfb7e663666532d8b880c5319f4ca10b504509081937780232c3062c63487fdef8ad648c1704b5b2bd3a5e42671a830d034a14b94285558eb5dbe795397b263f89d525108dd1ad25c03d292c86190f89b5e70d10790478de6c7788778b086084f912d7fc678e0a7437eb7073b356c4fad9727dbfd83711aa3578a3c8b542c6e088c0bcfabbc953c2272b675c2303539fbe4647f568ac6aa2a8f1f21a8d0be1c102447a84c087368d2d049948409abb6480606da60c7da2738ba4d676a090563b95af11c05ec2d14a94a0e55e85f4f89ee66bfd965211110a2909a3f211ad6ab41cfaf9ea3c58188a8ceaf2a5d22b6945658446e4174ef86164af1df90c2fb5a0ab2434e4afe57019d345600dfff444835c95734067b49f909919f473c86c040458b65af85be67d7b02e7097078f03925e4f7cdfb400a6ab31041ac831dd0cc991a0b4848c451b39e572ff1a8f40167e93d8c28885f6e27468c67b5abb34828e4e2c9c4ff12512c62633538ee34eff48594386cc49cb1b0da7d2ef130525fe036271a5aaa41578d39a264c003d2827e2e265c17165d22076ebd40e1c7861bf4f302811eb50df097e2cb31a090cb691801c0cf47cb8b01e0f752e9837ef65a7a54b337d324cc9fa8222c7cdde95f9006ee00b761da202bfa1ce8e788bd3703de8e39f4f8f33e092de13e40994e30cce3e01b5e4910432425a9c2da3a2192bbef7a267ce3a3e3fd0c2ea5bc0a75248516d7e9036b76effef939649909c4e11ade6854971f43781ee7d70574c7e29d3b5613a82a71bd68cfd4858bf616c6841fbf1c5bb7721fe0549387ae921781a0b159304807fd1c4b0ad4fabcbc73be24f2087c4f540caae2fac824babe481e08530a5ddf55791a3038e7e78eb83efa6c25287f2142d7dfbf9ad1ccae960a68aec785b6c5444f6062943d89d8fb571ba31944210cf16b46b74fd25126d68e09bce6e1c9dc320e4a2df3a7e5b5a42c190894a41752a2c6903715eb25b1ecb38505f33a2e25e881e807668ab1c2de18d2f26e7b41db2e35d38964cd149df5d86b2195d302751a71977dee8af03ff86b272a9cf2157863bd016606593c7f5107c4fec8dc63c2a393111764621f752b82164cf8af9e986bc9e43875d967c9ccd792fbf9c87946acdda447811f4539ef5b0f562da59f05935f17520a7462948fb831fa6e1584ee3745dc32d9f7f77ad728802b1beb81f6dd0165c57cb20f9c58ffdd09686332a576f63a9d7803e0c8659fc30b819a91685bb14cb64a677e6b840b7b6178cf2a1da98926a63bf3fd4658084cd6339225a6110b079753d4c73ca7f03d8d3d1dfe9cf134bde225eeb8144db4acbf53865885ad1aab6305c8463ef92a93a854467cae0f77d5acc26a8d80cb9576f38af0d143f41292ee6eedbe69ab9b45b379338bbc3e0c3c8bcc7c08911004f106261c6e2a2fd981c00eac6cc107f559488a138e1a8fa8a8da379782cfde01382ac616db9fb0d2d2229e5323599dc302708e09f3882ce4227b64df6a9f1d48576a63e9b254df7eb120d39bcfe0807925b376424aa13e9bd09f79b02fd7871212baeefb452fadfe11a38b18ee912d711516b21533eaa8eea667b572b324ff1765f9395ae183ca1c87bc578fc035bfed85c0a16fa18cc172dd27339e7e807cd6e97e59dba0d1dd5e4e6f6acd419dbfb81a539ed4e4048b2ec944cae3f6c3010ea8dc011e51cd749b1b4c6c66cfe1a59086bf179f12ed36bee1f381e09afcb35ef1ec4f11b4c983743f56be88008a095cbcb031d0b062022a2660b1021611dbaeaaed4afad76660091fd83e6d87b330dff0d99d81e6be45e8481854307ae39fbfc6f1583fd7fb5abdd8b8650987cfe55f228a89b1ff2ef62218827c244d1b9a4e0c0506a8479a512d09a8dd271ea042e9c7d18e6924a0c30c87cf34bbdfec6a4a36fcf800078eeed89f2cf62b865491c3675a138261e572b17f654d9feda2b36483fe2f178711914067b16651aa0c8501381eb08b112fe63d4c1a6f695d3e7c8e81b691daa319a6fc4d26ebad550240e021b46549eed4d597a3f34e9a08b97d412af74ab3d09f8538d78580057ae2e0ac35a4ba214dc7b2a7dfb7c9b9a907ecc3674d5446fdc03bb83e7c86a8b5e7228eb55089fac75e5b3db361f55ed414ed6d01c58c02a092a8cff77a01aca2b718e8cda0fd9e0e0d050ecb26cea8f6405a5690d17d96eef9bec888f211e19c4a11bd87f8dc48e864bceff04adedfa70c252031622c79ca3b624e4b83565d7bbcc465ecbd0e65666d6604c2661d1e8fb6479a92f7226a1e26fb8b1a7cb2af69a4d5a41763b45ff8865f28220ef159172fb56d86f8ecc6678373c9758d7b64368884614c2fbecde5109f7339185b09d2115ab5aae2ac76647a8575ca09e89aa890b1f614228e909230e1ba8cf7b7018e19bcd5624b7da100bb028fdefa437c3e90b10d44c3ab34c4e7d07da93b38798cadf96ee4a487ebffe09f2cb2416d6d6507bb9687f86cdfac1e4082010bd13643938aae5a2b9fd2d11ba2c1e5d67280143841bdd21665f8e962c4e7c919d85142334a94dbb2fe9e0dd7b60c18b4a90c999cbed27618a544e5fa3ca4839ffb6812a25c729bd8600e2af54a4100e0543cd96b72e2e6c233e2b35e60b52384696ad289fe1b91631bf15aae7528147f12328a614de5427abbdf7e4a82caa62ffa77a52bde4014999052d34339a06d247d30e0420037443777d34754fc4b9fed59c58accb6f981cbc761380748fcf7afc07722b7bf9817327191bcb75e0e5b2649bd9a187278f2825468a0320dce38604cbc52603b8093627ae54337bf2e15bec0f7dae9a4744c917b407b986a3f53e273c88837a2a7d6e16d856a4f46c98ec0a1a32965bbc496b3e87d438da5cf493192097d16fc9c986caac8b90dcf9c81da4b7ef549c0e5b5a4c4e7b89688633c00dff9c34a3994f8cccfa66baac2b7bd8f31882da23efbcd13120b249a255c857b0529be51fe23f1b9dd3b86def39971217c89938c9482c44f7c6e2c198f3cbaac9aed657eae98d81401d535a2e5a15e0493a91d36e7714079dd34a228a2a8f1e5562f4c7c26a4ef65ca35f52d2e1a98fa57cb4a5fec0e3f260615c17afc68a5e3c490207443fcf8885e99633075e6ec28df88b9422fb1e984dcd5d1ba0fbe8c0e56e4d67b678138e0031ee785d28415005d9b099f2dfe1d1dac0a20cf9a16ef698f1ef1d8498044b3828daaaeecc2285991c50dcd3668b191fd3a7f6bab4a2495f9f08d1347011d4e381605d6ee4bdf6a343ac2f998388a6328a749ed3ff786b79248b8e44e0a788a591f45f15230ab0d7853d02dc6580f45d7c0d9fdd52e13f329e9ac44849685a0dd6a32cc2b6ea1c1a2deb3b2de13b42534b20ca3c87e7adda096f11e0b2e56a067bafe6a749fb3e36695558efe7901905896a30cddf2462f3ac70b0c6918b0625cc9769a18ba723278fe8f43d36a4c82a1f9a957f9b3d7a54e20486040bd5f572e52e2b5c2da57a6d104827d704e454e07a0bd00ef36a00f58ab3f3e72b11c8b82ad662912c080d444454bd5d5e267ad3d1b4eab7d6b8f2853759a095e938f53cb11b88076c4f37c6e94472888aff6307259a76f2c5a017798cb54e9c06a93ee95ef41af25e4e36e49939073f9f17a7016b97fc875fa5831fc5fef947047d25207a5e958895ebdda3fb57a85b26642dad43e73a0497ab559a3bbd4cfb1ec2c44c97510ef3cd4589f637630b372763ba3f28442160a985ce5c959b23ca153cae42f7b68325e79da56ad536e48679c63be2614f1ba7f292a8eed376cf40d41469c65c7605eed4290d5c141e939e765621e46009623e5d526defb9e5e872e6a832c004a18e3d5d65495517eac08cf588e93e7ab3c4102fe8c4e58a57f6ecc6c5b2a624b48081bb45eea2c748bda0e6b18ff3fd2bad4fe14a2439a67cadc1dbce1a9acdcae2ecae0d58e8d8cf1f5ae7651ab490115967a579b2b42387aac0fd3bbda22803a06e28f06f3282afca3e7d322ceb92436ddd53e8e667a768ef126b9ab4d68f648279a657a727906132ed032997c6899691ebb1669b6c03b21d6aaff86ced2d6401e37b38d036109f3c6f35cddac002d58e9513ab19b51da56d96f4c8f86e0f1ef30194cb1c06d9ac8ea536d37bde1d51a4db7e3116e86c349df083220a400b848402615cfc2ec0d2521b0a91b24902f2621a591da38e280ab2b39fa4e0669b9b3e88866d9a0d8815eff29bde49a997b84e5816859c2f169d23a836180e9f5d9723cc2966771bde33f347e04ca4923d7190f4efcc1d41d0d6693a312e4007167a19be17996f51740c7d178fc235123c0d2980a503bd86e8e6d00b5d19799d7a90f2f4920b505f6387d754c0e6be00039eef52d87f5b2dcfeb489a37607054f2ca77654dc30f937dfbcda1a416497d9cac81aa751db0245fc0e52f01b415347a0d7739221c390ae98dcbdbff0a71d72082971cf2f1871b48baa19a74dface5b6cd86e6cb2811a1e21c4426ee9a73d035a7dac35f5a0990e5547a7129465efd6213167fcb4fbe2c89225bd638c8b6998c898606c326cb3a3f171bb520479d0670edd8e7cf3ba25eb0933f2e3df3e6d56e130d9f5b4c90c76de0ce5a7070276dafeab3e71d0706cc1103b7893125d222993677e67d2c67bd48ee0cb6051e1ff13102d3baa6b280763efcf7db78147227083376ba2e573c569b5c396105b1f8c86bb39c0b22766ccecf90db593b30ec4bbab04025d3c044e4759df9d3f5462948171b308e33664e0a2032846fb32b0e825e32b18b6e9ea8dac681ffba738afe3c1eabf8ae35369ce4dbfb87e6bc372ee1e02a7a774a8999b77dfce7acd8947156d1cc1b33a2999a11b93f6d80595294215248448a5155f8e0fa1b53af970b357dc88c9ef8f24d2cc0138cbae83273bb6989f0809f5fbcd11149618c91a3bcbf29b205e1ae3978b3d41013e4a1a5d9145dcd7074c0616f73206bbd82cb7ad3964186f73034698b1e235a37db8523dbfe62f2393c229ad263b432630381d682df376b18abcd166d215d0d1615b8fd6268102b706888815c392b4f1f072cd87461425271f2cc845ffc79f802bf59f7be5feef060cadb987d22d170489c50ad8f06d466502e2aab3a00bf08750dae2cfca10230ca0b7652edf15fa25590843973a472c3f0ba80981ca1005aa9b4bc00485d840ccf5bef6759e1abd0a32c70be1480b6efd585102d10604dc1d28021da35d3c1a6d805c8fc209ea9c7e05bbd4603f9e3e29611c1f07ef26bf07ee6224712ad80667e50ffa3585d20be8befcc4bc63f4965173520e817de8bb3ab6a89f492258b1c6c045a4e75bf57f55bf30af32ab43d4c67219a2af71234544322085b39cb8241ef6c7401b6e60f2253e760b464ef9c5b3479f6c6e4477f83e8b6e2cfebb7bb7eb55c5ac2df46e6fdfb8c8bb8a91099f18e4105fe0b0881d75bb50a838a9096acd83c5b753acf7b1949f7a331edabfaec871ad908ae99e3e276249b9fd12ae78508f2549ab3401b1df2a247ed5e72ab34f4d7f92db1fd20575adfe0e41e2d92044869194ab64a3dcd583bc97d2d3bac78bc94ed052e37c33d989eddc3469ca94877ee05d4d11bcee9af3fc0727af415cc8ac183d17c0a11b8eeb6a460496385cafa7a3e178ede7a414003ce51bc787fbc37180e3e6ace23e9c0627b2ed9a677139ee0d979bbb0a9398db51b21cf7956a1bc6c9886757ed45552b7d7110463046e52f4ef750a410860b7484b6c4b05a3aaffe4dc4415e5c85c2de6e5212302c21903d6c722118eba07404e72dab95f77e655272fa95c34e8cc6c41ca4afa510041c9c442c8dab2231bab5a16e874696efbb0c976d235f54e388347d042147f3d7c62447a3ed452c6a240f0a5ac47b7c11840323e6c706c1740564840f2b4cfc3a9f845961057927e7f5453f841b960aa736ce26cbc31f488a8f3a538a85d9a831d860edabd284dc0482609930bb539a1bb49c52de1812711ba83b4c88218b5d6b77164a9c42931085b2b02363e15cb020eb2721e7434779e4393bc1beea69851ddb6ea8d1b6a6609e24dc1540f86d4c85c365d2d5801eab51bd8107dde8a354263e2159b01cf06411baf65a542d0bf00e093121a7c0f40842c85372b1aa4ec4c08ad80518c0006f359b752a8e308e7d3a943bb0ea744787243af3cbe6bd3d9c30a0937ce385dbd502377d00b585890f8fed21f8efff22be3109d29e2c120f225ae892ab721188403a4508899172660c25549c0d8e104ab1052b546a179a495be759b74ec0e1a22a2c66fceffb930ee5fe9e61ae30f4b2acc1e164cdcfbf25bc3c5ba08acb09779978d9d245f14dffeb1c7ce92d0bf3275085320cdadaee81bed888ae367753e635cadabdc259a815a6c24cddb446ff96d60429a012dfae6ad01ee5980641a6cabda079a9d9bc89ae59562d4fbe7f5331c9cb4fa7519c2113e7985bf249367c1a7ad07ea341963c3f21add053a4dba00fd127d18965dc54f513cc09c7fd0d56a0907b4216f8498a6a89fb5ee5e5a9f915ebc38ba51585b6065516456724749c3622567c9b5333fdb4ac38b6963e449b5078c3f8e2aed7b0159243144505e827336e6c293e84384fe42fad0960d1d0a0d7e833091184f6231df57af8c98b5b572010fcb3f90b62dd4a602c4dab010d188d8977a47a2cb031f42e95db6847e95ee8c58711db96a37da26f984c6915930a03c6051a8de3ab27ddadca783923d4191d13d3a6369d586d51cd139e675158be877803630806590aeee685acfc28b3a4d7527ecdaf6a538fd59070d2c78fd34191b321c6ccef2b93ef36437e83bb0052203591ca88ee29716eabf12ea632601eb11ef5933e0c9c4bfe13bd4f4ad2f93185c29e140c98785109c7b63aef388ce4ac96ccd7502d730da9e211d4bb3cc87d78c8d930b75cb3eafac4c52f3c92d5c41d7b2ae489603144270e4a86c45378cef78447b6c923a873821efc9c93ed6efa9cdfc2532b9b93479f27017b736df100e34b48569deb171e66aae7ab07c0f4c6135e1b2253786e3a4a2a37ffa82784e486142de325b6397290a5a331ff1370a211538741db70e980e2ae8e533608b3fd383ea842ff767a42aab4090883b431dfa9039594a83a54e3f15ecbe61eb93275b01d6bddb367519cea8bc3f36d5e90dd5dd921ae9079813978b9225d95eaa8f0c2742f13b4b0e73c6194f445a799e8855f35f49bf35d0f73a7427468a8aaa2fc0e688547bb6007cb8f2021745d8ac9c31e2dcd7dc75fab77dd655d6dc9c736634184c908de3059ac48fe302a168bf8bf849e180c41421a385cd93213862f71fc8c8a734383507d9589ad43ef960b6b3f284c6ab7c2e2ff472960587161da6ab8ab8b8916142a27fc581ac5f7baf940d85b071462bf697b826e54c9478e855c80f53d08d5ff178b44f2877465792855ae67bd5efeeeb46b1515c0e66fe2fd17ecf84bdc4c5fb00a3143c6a5fe2564f83b3b9198687999a9b727b3ff3b392eac8bccb4eb0a5b44da52ba80b5303fc0f3631f9eadbcc7d4efb2f438330c7faa2eab6ea071d20df36887f32db34603669155a7b82033370fa21d5dec40c626a0c11ce40bf368dfb94c07982bfec73cda8b4293b9f31e6cf6d6e5f90d86db980a7ef00687fabe68f3ba37c1cedc186c5f68abcda371716458af8bbe3aaece2200347ed468d23d06432eb2e9142902902bf48ccc3a6cc18a3eea602aa1e1a9dc5699f1b338afdb8919b367f27d25a3b80a6ceb20933107a2cf3c769104c831f5388fb601c8b3b5fa311052c0cc7137a00bbaccba3839163dda01795118ad2db7d4ca1936ca7933e6b1f0e0599dc1be8b429b975805c7649e19e02dd2bf16e8e670623f0408673e17b43fb9bf856cb6f6216dab9b810003e146e9473587eab62a155ed90d22a83842612cd832c5f235ad048ca28e877b39092f9e2bc63a340ade05d779ad94dc642acb314c59df81c856692a5774877c50c20a1819edc0cb5b9851da824a96afdca1161715bd44c0e3bafca85e8106fbc2a280dac4788f13e165d39217a0839f2f7c0a12c4fe80fdca14e45ea1d9faae014d17208cd28662ad5491d66791213dfd9651da463445ef440d219198dfaff262e5582322d32e25f1f4a0ee628e0db4a638e28ab0fb46256da708d7dbf1d240401b0afcbedb2f2e00ef66e4c9114bc065078ca159540517a0d7b2fef86f05cd635e4a85ce067ee1fc76f291637086fa32e8836594367dd918db933f326e3b0ba39bb7ca137a70f7976645d49b4a34dc858ce114047f9dd00f85412bcefcd2c686fd7e8fd1b7c06ff0b1a3f21889439031a32d82660395274cfc9b815cb3e06a7d80271da35cea5e8fbc58347972486b6e3e2b29075461dea5fd557139a6bd4e71bb01d8281f901708d23161047c737becc5f1ce944abceff5bb57d0982a9a6953187be29842372c9ebf8a98e13a0f40b7b8124adf19c9de9c70503c3bf546db73e174ad3b7265da8f76c9cc1191eeb733f960ae7aa5a03c96aa305138eb9bdc8a8635c887edd45d0452c97dc8a7cafc0add85cddde4f7283f0e53581c07ec89b24e3ec751382bc3d7ccafc12d723cfc8e41946bdb98b6ebf279408e397b63dae7f313239931d6871c7ea7e27d10ee98f291a4f69ce46d0f99a5a1cd47ce64d31dd6418b4651085d332554414e02e4bc7ec9cca368f975a579013933d929bd0e326d426244f6c19f80d8cc042f4e40959eb0349230b70099f6c5382c8c814246f14b6167d07cb03d9227e1cecb586e74c49560ceb18c62040ea10f25fcc9b2f8810a2e2eeb7ba53ff28e4ad6f8981e1e93085d9776ca5c6d88c4c16791de3f55bc55ebd6ff54bfc36124a467873cc8b43328ef538e0f00ff5908eb37edc3fb92b7ba89c4587b1264daa14ec98828bd64d54947cd60901686ccb96f89bce16ce4e505aa8d30c61c3b3bc86a572520d3a6618a50603c8e2e42ca8f763d2d4c41607b096efe71cec86c1b8346f23f7b80b7bd82bf73006d0ab40027d755a03e21b11a1813cd5a65616454171fc8b42304661f84c679637ffc5322229bb80830c4c4a74f3f29262ee6fd2185011b8f0775a40bc01e80c5308fe93fe972192ed3d31e1cdb873b4b8564500c1c6ca9f8751d681e625ef80a907ec29591ff5bce9fb4746339859aaf40a64d5562dc09f87e01f0f945021812d6d407c8b4a1267efb28aa7e6e9b6af8601be90b8f015f43045c10d7aca26b7ff89b40a0138bc045fb40576ce514c54a69f3970cd2e6a9d1749656201ed3330d0367ad409c0c409a20d35e64528f1a6a2831aac8559b4f1c454f32a71bbd142c191527aed46f169c8d27babb0980136ab4642bad4ca8f7d4ee5811b6103e19eae92609fd05c80e2ed15da55d0196076637af2ce4ba60fd5f959f6c09b326691925076a871a6daab873989c79167700b48340e7a7edd1e4e01ef5145f42503c906993f056c1a0a4e16e0826edf38bb8505167866d8fb44830b01d84c263126f60aa6cfce73215027218987f6d5f4f7e0e988e3bed6a90ef6c77b60315fba341ad400199b616bc4489f59da2cc8ea4588f9b3558109b22c8f838d735c03d5809d5788b11a27465c63e40a66d93a89b16a0e8134759e22e603691cf054a3a2f66bc979c4cbbf7c0cb75344a053c166a740d66704c87b866c2ca28011e213a3c003f6f9b15a9c5c87d63d61972569f49a864028d8a97040e6a012bc539e07fa5707fc6dccdd0488d99376f191a5b2aec8eae5d0856a77b48f13618fc352920d33611941dcbd7b32a0281db817346ab416c99e2055b7179ac6120d3a6e110a11c085d7ccd3c77a18c71b61a802f09a6bd14bb2543b91c5af1cc59df080ac5d3f421e2a328bc1b8bed7cfa6716e94153a93b6383aa38d0d94bacd2fac483bd54797a0632ed8249d52d85b35270ca2772cecb422eeff3a5b7f5ae87532ad79820e6494022e9089c10e53484d8879f5224185a58491d1659caa295b5de310895983b8826ce7b2669d8f864d90df1f4ed4bf7cec0a1607a8cd3cde2b76aeb0c42a0d78f8273f06c2784e20e77d547a7d66d07d9d23e9e7994b371c0c2e09fafdca9c786d9373b779141cf1681190298371c4004e6b8e5a0c5c287df28eb972fa30bf284305595c971e7f15f3dfe2720d2fa62a50e44a56d6b13a74b6b5ef964ae2f8a911d866d95ff4d4f669524add696250b9c98193e2f83a75b4d6baa21e1be1a72fdadcd5cb2365241f5cd608d69cc3ac00112d6935875e9d8eef142952664530dea79d50eb6c5144a7185ff80fc7129332613179efa126dce46d59e4d66e64cdba4a569899300b675f7c055d3af59f1767c9dbb3bb9cea0d9b939dfd2baa5294a2e4064b380c535cf861aada155b08e5c9e4b55b90d86984960da1c99472d86b5bb3e3b1e6294c8277ea028040b39c1b36a806fc0f66990cfcac15bf6c3f93b73a67d892de52d114b4c2f988e2a86ca35893a4668648f681ba3c04ae6b526ec292641ff862a3b83da7683c7c5286b7511d3c58088446fcda6de702ac29240dbfa9c695707e6169542ca8ba301b511acff7a4d8ccaaccb008146ecba5f15f51d5bfb04c9d8b071b8c70819064d3beca348f100fb2aa9c4a13050bf67a280a87999b29cd0c7b2712c2da2a2043a028a80a8e050aa9a08c4cc6011f1eec681b79fcc93a4089033634775d341d3a670713f8a750fe80db27ffbd486bb111f61f13cbe265cf2c143980da2c5054b62a2317414a6539573bc9877ef27a70f708a3b2d1f7081b7bcd6493c1aa8ad1d5d3addc7324e294373ec096d3b470619e40f9717b4d5a5db9a2cd9dd6c09ea48e580ebed9d7bd70c38d5054ddb3e180cacb3bce4668269075d919ab9480bc4e7f81369cb0050c13f4eb40c8734e1895969b76902ad26632b17ce46f9ebec0851626958699f5217dca5e0c6d445988c7c45302364b29ee38ba26fb561a5cd57db582c778a1e4e77d3f71940dade2e73909077414e0049e253f155db9a4c9382cb9b6d5294104f23da38e8f6ab39a00302acb45d1bf55f400a535a373ad92ed80580b3a9bbd64a3e45b38b770b1d31c22df5a9c776ae1e31a53409f0082e837b9899b6e3e7caf5df6c5d98ed7aeaa93d09002bed9e615d4abf72184a2fae72144eaac5654b39e0129db1e0fce5056e0ae06b2689507b02b39b6d2e0b3db03277391de8f7e465a54d5b182da5cf9cf4c5e70571c201b38f3984acb43d1deb602e423f71ed30aaa1b609d6871c6f2a675d9aeb1530a58a958bb0c08f0530524f56dafa242601d76ec4a59ade42f6ae99cb086995df700f52e64f6cc9ba790f36973487c7036c92108346cb6a67b69f0b9d0d35aac79f95360fbf1d2780ec7385a2f764ae6476e51c125310bceb406b3c2c768e948d1ce37708dc7198106166edcc4a9b0f138e1506f41dc918d43ef89359696ba554cf769c46ca9d03156dee0cd4aeb339875425ae8609277dc73ebbe4b1b179ce92c4c71f93fb3bd089269189f4d13a24d23569a006f0770998f64b84783af08cc4916f32eea02dda935af3dba96005b5e85969338c7ac6779451f590ffff6c1fa8434ddb5ae11771f99859691fda5994c4c7ef86d29dad994a4450ca4d3de8aa66a6a4da9461ee5b558fcbea6aa9b3ce5278d1372bed9362dd1b595c9351271b51b3d61d588d64aa64f87836239e1d77a6a3e2099056da846a63cc87db5a9e9c6d34936b5eaee8760cddbb19a06a124f4ff62d8321c2b496ea1cf94215d77a5c7d17aa866bb326d34a3ba3cce6eaf2b80bc9ca9d64ea11ce662529d31dadb435bfe1f18900056c956ad286c0329ed45eba161a5a91478dcbb7ce5fe2ab0d80c2a960096fa76a4b50d17228b6d63bdda52b322295ef86b1d2f46dfc6aba3269a57d2ae9dd40b07259267b6dbc9594c1684da7506754aa314c98e2a40622d28a18e62d778cdf26b4d20e593e41b9359ce4f5124051a912538fd742b20cdd8a65262b2249eb25a259338424106525d24a3b4ae23f591f00f56d8ced00809ada01d8c1cb987758738c2db154190727b0723e1ca639cce328cf099c08ac0314a61626c28aa535ad227f814630cce5459eaef267a03f72b3fed406f3b2fb96268eb3780455f89471736fbe67f39996d94a32284ea9284d7fb3785a3181a4494d44915985aecb34214c53e15ef5b7a410c3d04a7b4a2f09368907d2ca45a4627ff6fdd990cc35848d74fe3e6756a714ce6335d26d0703dadea69ea8615a696be21a56f3391caf54ba6c11b647c8440ce8b7226d4066841b22cd9f2d1b6a9f682b6db5d2cf41120d1b12cdf8eb9c56da1438e0bf210f50a2e0dad4acd411308e9ea2543750c6a5e899ba31ac01adb4cf10d988728fc562b281c5acef7df23342e962f3f2b59323b7f1b8244b10a428bea8180f1576492a9583b595ae0dbf6060420e2ba99939b458d46ee0f41dcebc1c2727eeacb5b708c58a1b289bac8b766e2ce75d6d645737ce8cabb09d652829b32bd14a9b4c4236acc5a6b33574598ff4a795b6f614f6f0c126e619b33b151e7e0845c3c0048e3681ff286574b69720dd07b7c12985584347ae03d61c5fdabe278e26f378e5720b3edd54ce60a7ddf5514bc1a1c8e0e77268a2cbcce37a13d3a09ddf9f79e040f93b1e86a6fdc38a00d741b3ed0ffba40e31b52d3451d274c16d3a9db7cbdb2f4af3d070ea5de25629061200633e039cc099e83645cd0d33ea671fe54a38a7851788d1a5a6594d88d7b672f34c8a48df297cb298f5442bed9ce82e8960cc930a1ebfe220dd05704b6a920bc6ed69744868a56da494d36b3e4ec744a48bc3c545a2cf62f4f509977d53f619517d68e4f4b1c4d9e7f21720c0c4a69576c41cbc50d130df12b95b2d66c581d8b1c2db69a55d725265133913fffd5d13927bcd3e525ea012bc6398e4a763c208a51d03cb0011db8e11c7f7db455dac9b05091bde0c60be4a6a89a7271a9dd24a3bc80cc925081b9e2d65a2c8de10337e7fea8136a2915ecccaa38c8f573396381b56143cf627b786d8a6b4d2b6a6ae6affdec6b094dd0edbc1a720f5ac373c3d3ba028d3495df81c4057a96db619f62dfeb7eab271ee0edd3e1c4bf83301c57dfccbcf6fb965aff768a51df440ad429f1509d87c61193666ccf3eb92d06f8da0237196dc00128ad4448fd7e21be1285394ee43c8fd9491b0f204063d3a426ee54358974ed31a4861d414a865c648f61d07653682af452aa3d054f63906260983929650759be5275cc3c85d0955d1b5fa13177f0814571497409fe682ace60dd5b098fef741faf6b824d29e76dbdb2af0fa15e9fdf291f181266b13f76ebddb0f2a8b1cc88063b4d2be8481ef7bf52c8c2d6420b185940649888845dd81a1addb542e938e45a869a59ddb10e6160316d5ee69d4b9b686b04a87917d7388b2170862754591e8cc0a8d3fa1b592b4f5c1c98623019b8ee6b6dcf0f607e432906e19ce396ef2e8eb5512d0c66f15220d10d74a741b9701cd3bd094ea7e010da7f41ab4d6a1cc1cb626236a9d6964bc648ea41822b3d2ae62a47bc19aab86a0e783050c8c0f7b77b6818f7ce132758014898f024309ee47d74837db63306f5d879941462366a5ddd062d8d58ad206d8632fa4874562e4facaf56039f7e8b2c76617b32eebbcb38bf3c05f54c0c050f0c8609f7a213f9f0b490714de177c808e3765a4d89ae0af073d92bf007b00fdeb85473f5ecace9343f94b6f91a2931b47349e04294d117f427ebce521ce4a9be352abdc4b228bfcfc934bce704242a6110e6b251234ebae43198c1908c66faa6a56dacc8810cb8823dbc74468b784807b5cc2a1fa521f19b3d276797dac4d6aa2886a9853390a165fe220a7344e9b95f61058e8610036ba974e85a47eef24990f23b0d6bac3924ca38f5153d4623e8c65d5d26888b10c2436d168a8e94bf76a19b543313cfef4b2227e35948ea413918bd658d539643d027a137025041ddd062d677a7da9ae2c840488c093af589dc174c2b738860c7b8aca7cccf974914731247fb7be9776ab66d3019d8c6335b0b9f953b91bfedc6b83c381a4945e260119583fda162edd6531340e62e306634e4c5791b049bd0fca9c34f6f8cfe74dd186fbd9b749cd90d63c38f78fdaf4d254b54155f5e3f9f3b3a8ddc1118aa34c2751723b88bbc6a2fa4d4127a6531854a39989a10d341f2dad576a3edd9d98de2a66dc009fefdcde7d0ef3484d6878b3371215830811c53d5291fc5af0135923f13b273864501d4ed320eb5660a3774231ddaf310850aed1b435ceb1184d0b8ae9c423e049a38087b7357d5df035eff4d4d34253fe4b4e40a4663616df1e05df4c5397cbf7ea3144642de224b93ee8ba7cbbced669f957e7bddffed312412f4638a268fe9a016184627ae93a10b8ce56eed7c80830e4fd1ed50f78ef35308808329f95e42a6382ba58ec647d393733aa9af13bb6206fb661d5a8985eac0d95a2cc7999b2b9481714770b9fe895814e752932d64104f2464e67953a9ab9c78eb3fffb77a568e0538b0485e841b2474c1e11173d506dfa2c2cdf9c3ea498dd17007b0f6346f9c9032a9ba0b2cfbf7cfc3f9598b1abde37022fbd6a000d3ae9eb216b64fa704e870f8474ece754b3544d499229daca313cef04dd9830768a3893dcb29604d11edb28ab5aa545522d5a1b8d69f27d29dbd052b3590bf1dc325da305dd6b2c48eedf039ddb657ca70d975fafea63bd9494a4c9a4400fb4fa6183a61339700f9cb53156b4181e120c1fb42419e8c4fa0789f97388e97b080cb054e899ff3fa70ead7bdd323dd065d63a1cf8bf5dce0fe8b0cf5ba6738dd4cdc4bf7ba56fec7bdc2b33462e9cb634d1b9251a96791f6205ea4b786eda651352a0e299122c5dbb6d75597122c25ad35e80762e00889a1efa3fa054c39399a05f974d657881b1ec436509216b8be9d591c8d23e85e8517970bc0f8549454b2d3201f986bfa7d686dbf024c3a903c1b1d603405ee4503a1df66228f982a5863f0dd0f8b62f7045b299e60a03cd562d6442702daa6a9b71850481d9f8ef34814691a040213dcb87bbdad8f63dcdc1f137da277b7f701f325b20d5586a0a950334aeb644410d0d9a76ec957da14245ebf6ef62da174b38e5e1e6f6f2efc6c278a74e5ae3303504d3ed3ce1cb081150b2037bafbb3a42e5c0ca71c4d7a5c819e273610b472006103ec26135f6445e19dec6cc7a151f0529b33ff98533c0c8e272bc63a6ba81f50b87bed5369da01440ed0da997ffc9f72e7602badbd26d5d57e43021ac80054316d75f8f31b1ab846bb0d1b71e5d45a123c205b495e02ce148dfb2f5650f46a392dd3a4558a29d3b3164e8e76c6eabfa56ff5cb6ec03510ca33ffd146d8c0da9803bcc96ea2d54c82330cc60c92ed3a7e3e0add2be5bbd964d35b5dcb707574159c73b9987d6ad7c73e0bc48083a1cf77c0cc95b8044463cd874cd8f55e47485534e93069149a4dc0a61291a00f22243e8e470b22e2ae49c208136db1321d465ad41b0cbf410c517e776cfa6f0bec8c13e943000c29fd0b5d63b6947df1d675cbc51c4d58116d453a75c5a4cf158e6d837d1772f64d4fd13e8079233fa56d411b4d33209f0b9925075a94cd9499a0afeeaaa0975a5fa2c2da06541bef119b379c8744edd01a8b8aae950173f8005de6fcc5dbf06bdc9f39d95bcfcba5987ccf42c4dc4abe3457d2fc46ae7f7c73d542aa90f41e4ce2ef1aa27432c64678ede1ab66ab877456e798863d4309752519dbc097ae6bdcf14b3a68f5ae173316211febbc847008c6a575f9a2ab099dbb9d9cd7f2f2d71bfa9a5e926cc1b513965e8d458dbb347b80d3035c61e1159090cd6225a16d4c7b4011c61560930deaf8489e546a65b178bc44751dca3819ad69ed175ed30034045fe1aa2c46d910619e46d281a9dfc8cb770057d847e851aa7d9e43e6305319c82645dbd6ce3bbc39ed9a822918c0727dad57e33b9c35de01a033331b48968db7e93f24cb360ea266a161f18d5d0d27b12853a9cb58c219e6b9904d653ac5cf068088e53d5b23f255e59e542fca01b102c74608052fd62f5bebf302ebd1a494a73bd01e022d7e5d470a28f1110b68e6b62a9ba57577ab3d79a7119a6f889ef52d3b59334f102a4e22b575f3c2eebc795bd5f6e46b25d42c0b45a5815251b1e46f35eb3acca457687d0aed4ca562f05e1e07cd7b7cbb614d473b74ce885326610b40f6002c84f829db1a9435194ce4ee600f9cba5d26cbcab5016584515b07950052cb98924832989ef918144bd71ddeea322b161d5f6fe6860705cbaf9b70d7a8f6bb85d443ec1d5aeb430f42168a4e8ce23176bfbeb3c73d9ecaaac1e03e7306cb18f7e2489b56b63e78f3d9bb68c47d3c49c1de730555eb4d2a1b7b4f5e3616bbe11045febd66a90f987961b15ebaba194bfebe4e0f93a896e55845e914c6a79e6636a84b7d47bc22124c6116ae23b323ae1663221c5a2de0fb67436f54db150f6064696feab8608a94a28544d5462bc30b9743845d4b86ef4464be6b704a73ad5a7160552ecc567b6d3da6f6d71e93376670703440be10cf8402dfa6ea99dc8d237fba7c1876789a01be5053ace8193adadd142483b797294c114a57d38bbe222f97a6ac175e4e7dd34618b02d1dc65f877726a3433796f92af221f0d18502652e25867aecc5c074bfde61811a4510c73ac0480ead4e54800512ed66788634bdbe82b63cc687834e64d963c2bc02680dbd783ec5e838208c6c3a506f8b592552ed6ed42e213a4a2d55f0e9cde0a321bc25ec37010ff9824616f6f158b8fbc91f8d4876fd7bf3d5d2b4799fc064fa21a81caebb882b1b38bb0744baf000bef31d2b12519d82af66e051dfe67adc8ad401906cbb5b25a3214fe2d5ffb96c9eba5e2438bf33cb1ce170981257523b0edeea3fab156d90dc036d60f58f0d9db1272abbed3f9c0dd196ef547d79a7d0228c96fb940a45f767fd9528618a602f00f486c11c66ccd39494a88e0534429d340a41be6d907e8ec0a45e708981c83fa7f354c877a359b55bfd76f1d5fad7ac06d713a3352af49a05f52c3b32da0ce432105201f3d5b91336db004f7c69a4a7f54c3cda3314225ff96a1536890e333a65d62e6e104a7e48505399f7146718dc7b3f999b38c0f61e1d7e3292fd956479106f199c7de328c0b0944faac4d2653bb42c1e61d311692ba356b976361d66c6aea4a7bf8a9d01dad3cdfe631f9a01f88f475edb0f43c4bcc18bd408374611e73035b0b98c3882a6e7415ff7fd53746e5422cc5241c0bcb5419dfe13966ad8cd2c5312cb1610df79803ec6c23c031b885420bdb49bdbb7ae86a2af9831a3580096cbb17bef6d990960ca243d4b4c5c5a94776cde03a162e429a032ee4db0d74167ffcd40dbf256a333fff902cb35b52111f3ed4f8db113ba1112f7e49d0f3a8f4233ba73ce3d6427fa11f6822cb2f65c1a64ace632ac3bee880657df782095f1822229349d4368fe872a6ba5eee6d4a9770230d89b71e0e686ce0f2cbab41c776503c8ef6fa3159219d6750348f22ff9179971922237fa6b8492ba8741289f93794eee82942ea2c05f06c6d9ae6e4a8dc59e076c4c825a294563112daedcc8d7dc9620bfbfec59c1c3186af1e4a3a811a45fd699660ce8c0af828efda0792da404c2e9b2861cadc824c69d90e9a4f2a629bc41e00faf5e447d25dd2dbc7da539315f5e5ce782fc8b0d1adb93e8f94bdc385fd8aa42f791b85e4c105a6310b3f558b37cbd2ec6b7702e850f42b87d2409153beb8173f0f363138ac4df45e8bc6487fdcb0801ae3b525ba57d539d892586978bf52cbcbb9c45bc2bd7dc98cd255eced0c2cc46698a5076ffc94c6ab7c7980e476bb83392ceb9da9a7bd9e517a93b3cac96ffa01d1bc7be2530b7324bf67836493d3c6b90a1d1cfec52d360db9086f49a868d2feca979573496f2a319bf9c46949074d58ad088c5b9a404f933140eeaddfd1078720e2ef6be597cbb97c778bc609e396e02caba02fd6400e62e70992c8ccf5550dd789328dc95e3b30c7d24d1a500b521b659653cdb67e7670ab8e7a641e1101f1062a5bd6cd044493a611d6aea949fbe2d369c7d1fd422675daca5747a84b166ed4d4bf7ec5ac4492c53de9a3c4a7b89e5eba704fa3ee3497bdbdef4571703dad7384ba614425aaf73d485d790b3e8324198323857434d91349ca53d30d4d816058fb61d5941a09be59c3ceff866c339d344550c9e317761a5bd9ac48378abcd06d8dd80e26918d1105aaf29589f36938c2d88d4d8224f1f7438362a26e7b6c88f9f46625d1b1d7e808f50be1a7309db703b3e11ed86e0902edc6436fcb2812610eba5e02e3d746dffb54cfc39d536365a91973a230418e8ec96bff6e0abf4f325e128782d75462e291fb7ece803905fab307e4317b38e889848003e6acbe3ec3d2d8e4c9987020d4dd7551edb2b7bccdd64778d7902ebfb5a7842ddda297a6fa77ade9f538e27950ab166701ed07cedc182621cec1ce18a41257ff785d36a4364785488db3b2f8bacfec9feab6034492a86b5db57098b68118e9bd8bff3449d4a94f77cacaca9b1531e2c1f332535c9946dd9511d921fdfaae447d58e80337c45b9154c9eab95aea640c848c67073ec63dd06c1a8861403ffab40480192ad8682b4ea0097117d695435c090862ea53458df4e073972f8a947bd4231cfe93977d5119a7c3faf2d8a5feb62c39d1c883171e209e22e85287a1b2827449aded105cfae452d756b772d2dd6faa3d158da7ba4497a63b9aac2e35d171136ba0679f0052872c2141667427aa8642333f316c412f1421e01ff4e7b6730aaa2d0cab4ff3808d90eeb4d0ad52c0be1397c42cf5daa5a0a67943e3f588e90f198e2311ab693220e03b74991b83ba75fdfebf2ce5e642f4d2ab35dcee30c775d245fef51d0c2fc3314e71d207a1b2ce187cad4fffd2c4d3e5a1ab21d3511321a50a230f2d70b58fab4270dbe087a79a999579d5b8dda8c7d7d86486b5d1cabf99a4488190a50532135da440a821291c1efbe2a4df97b1c86b2bf8259ba2d424cefa2ede6712bb127867f5a0e6df010e002412e303ee8703a8bd40245a1983f328179f4bdfa228752b7a26956896ab28cbb3e8cabb48298543dcc7a3d96fb2e40ffb7084df431b57bfa01375e8d8e684480e5a720c2869fc68bd6eb5081e02a0885f69e47b997318b04601e3ea421736d3b24f08a4ecabc7f5ff97fdf3a1de1da994663bba97f48eebb856dd97cfc0bc1743b9a07a95e05c5dc6efcbd7af0cb2820209898848ef99afdd540223ec65e40eb4ce77b561d98d4a49b103e5c375953e2597513465c68a98e8eece34c26607413ae173f50f57c86d1479af252589137ec563347f66b672882225fab5ae14ccbd84764b8117b76fb41ed764dcc6698c4fddf762e717b07394541737d87ef427651b0d34bd524da872a69110775e429cfbec8a42ce92f61f86e70444d3fe0d66e9f09718203f0d3895e40ada80de88ec51982f1089316680ba1b9b263ff25b218213c3a4c1beff47c4b1abae00756f7b435b839db3519f4d49733c4769ff0a5e4b2bd0092bded4c74678c513cdc798226881c3fcc2775e5f146af60848de45c7734f45e41c827c17206d68972951e848216bec0fb2e7f4fd432c40ddcf9529eb369fcf3505812f00f665495fd19d590d86cd791fa4ce0dd10cdf32f99804856464ee1c7316d2adcf9ac285cf1269183650a49e12c8b246fc3fd3d2d89089569f699130234176b2f58f68fcb925f7d3fd0444cf6f6ff81c93e717db22b39fee56ff0bb46d82d6bc15354e1576ddb32d5c9db394c403e9608f263335e16e691fbe20c57fe1233b88a8a5d2c4464dc6f73bd66d1934c35f46b00d435d39aadcb60ccc64e2c4703779115c38690d40e09492fe8572a1d901336cfa8206e3b3010dd692fe783b94b3536e17e80e67e7eb24d94ff78550be90ab0ec03fc4e25aa9b81f04ce352fdefb4609aeba5445c7593c166b3279bd93a5a6f18b5076a7e35bb2215e08bd041b399467aeebc04c8c7239c63afc534a5d8bb7a3e1b1d98aa6945f14f9e02a2af427425925b9bb2158e4062bcd7068d38f800a47299feeea400816ae6ea639077273ae504c008a08b828593b8b39813410c6e4b89f9e37bd29508ed9523edda9db8ed16a4be487f4f69099d094b358ce863d73d801bb3edd9f6c4dde2fb441341f0248b68e0565e0343336ca044dc93b173e2bdd7e2deb15f2c8fbccf1e7af2f6adba132ae2a6a767dba0bffb2a5435bea8e30f81f9a693c46373f9c3d7c7b754c74f6d078aab01f7cabda2fa81c0892fabdef048cede6c031af76f831239994d9e9034166699784e342d7deb0e35034e9e58f01d0c5befec2068840cbf65f35968227011da700502f0201e41fb74d7507d318fad7bc0ea365e62067d156c29dd90b754347f0cc6efbc77f5e32cc477432001873f9987b0451be28e24a9fda7f2b3e0558e08a9fee48419e2349034250540cc2e15ae7e100aff6b4430aac37d708ef4207c9e89db317e186a6dfd65a896cef154f6622131b904587f8b16dd1a56560f226c51fb7321c72f7751bd6bfd1c494b0483c78b9408afe9d5a1b467187ce4acf5f403c78fcd27d110a94d61374281adfcafabf193f2ffd56644e79674c67b422f2e3016fa03acea94c6e8158df890167260a4b74a3ca97dd32bbf5c230a04b871619bf5c301905a3fb6525aba2688e4fa44e887af67af6ab13acb7d56e0e75d3f14386fbd609695a99203443ecd4813cd2a47c354906593063c5523cfebc517902a964c51fcf0551c53d47704f270a59b114294c254facda2b5927a7a760da2014851da28d894ba71442a7fc039e677e73bfcef79d2a531058f01d2652f6e94df056a550b0418f46f15336e29222c8e6168f04d99b7cfac95c64978a71305be691ca839c4265b918c037cae77197a7e03748089acc0b33b84bb4015c31ec3b3036c6999087459fe0fe272e3fee96ac72ac92cb57c9318e5eee46aebed7f486aa1d1ae7c294ccd55e94c397cfaa13a6dc17c0edbd5607987521ca7ec46586cd75faba90b41785245cac0446a4d1eb18a33919a097b77f5e2554e3fa4f6ff850c8d625b479060b06318ab4466010f74e565f1f93ceb6cbacccd5996186bc41696ead21d6c2cfdda7c8be60ff8e9a3f481f3af12a3788c29db9571aa08d4402e81ba53b40af8a75acb6166073d9014df94cd847106cf5671d03eed7a458180896b72637b76bd7fe1105d5913ef0865a8fe7b95fa74f074a84477a863e53213d59559a7ce014f45634a6ce49262b2837d29ca1c56d119b3cbc890140dbecc55d7f2222d93680438b5b04ba84e5db8e356b30435017a3d64001ac48026ab5695f541048a3923a688a342e2930acc2398afc83851e8e8349fcd9d708550c2ff28de8cbb5f110c78738400c000000001012018c4400c02c36002a859dc66bada6c28fb14002160185449cae4e6c4becde524a99f69601eb05b805d905bb20545810a609196ae5006b81191c8a1551c060d518e230c3f6c58225107289172553a4ca84cc6c5163c53209eeb0685098d41cd728838cbc5620e439726c0d15a17d6de9eaf079ab80ab68d3c4c3cc88871598a426ae14d8885802114f788a6a21ca0b8ac60fbb64a3c05cf33ee1be4f7b36bd1fb4d5265f08958e5840bcb46cfded0537926bc8095460fe711ed4e8467cc5bc170f2120575e42c7167c82972d88852218611123559522ca159f201e26f92026a2b055640b55933534622c126cc459418cc446bce84504dc619212103541605815a9d2e173a1780cd9ea42438b918c0c1f15d6cad8a2a266985df1095e2df47e25e1ceb5730d05a1b0ea9347212d231f64b4b4a8a0916d61716c0ac3a5063ab6caa4bd202ae382cf07dd225d4da922282d40017a6cd80ee413b3a52e3d887c82e7d79ff8cb88113e1ffa41534cc48d2c29606a90e952f2099a6409f8a0796603460b32d2cccc14b1f9044d35047cd05c933a1aa2e349113361a87c82261b0a59387060f2e65641500c658a6039fb92c22768d74e4001448a1ae251152419443e415378002818a32804b25aa8a97d6111258d8f0134a0e38c2808932e3b8a7ccebd4f133d160a1b0b6d4184cc289ef1e1c9623fbe0149668ba7a809c068bcd6bb04c5ab1bd15337f15e002a0db79e3d7d2909d03d8233e924c66bbd5770a1eb12caaf1919b408422096a545f8150a02edc82eac25153ccc844149218058136eeb9bbea103f05dc2b5f62a7dfb00ba3d606a6d7f37de33bca73d2f5e7540057a082c9c7509e2f57a73c06ce264dd8006746a716768394d3380012340908ce97d819b8974ebc490ecb4d63715d0bc7c9a6e0ba8c054a7386d6f4b9ebc106d4961f5e82180df19974dea57695a81132af0c673ec7a0d84e9f5a640da33dd6f6e74f7265f708aa29e350115e81c7e48795d76cc7abd2580e202f00e002a30d09d6e1c9aa238206b4fc811fd6d47e03ca27d70795dc2eb1f50af370454a046517ddbbe571376cec2e0d2dda3e8b6363bb5e9d9d397f6b6da0ba2b95e70c5f582bbf707dcf68f0abcf918f27adfd384005e6f07a03dcee344bc7dce737ee1ad3b797ece2e8f312ee1f1063a79dca897eeeeeeeeeeeeeeee41f3892c8b9af7b1f78d86bd276330d3d2434b972d492e4d452e462e616a5db0de770e84c32e52885e7a40ad0d8b6b67efbb0157efda3750053a037e5e24babb1bdd49180bfa8dc3a62fafdcdd8dee3a521a30aa17e0fb5926a3967446e30e5db128454724fa0a9d10c978f3f7de0d74f2f4dc4c182c7c4af6e9f6e949b7b9817a6e8f0f51eb41d39e0254208a957c01e307c8689f4e1e3712a79250658f370a2a10ff006509dddddd9fb4a02c84bcb7687a6f91e57dfb8abc7bd20595f77d0015e8d8c518a0c75cfb73cd2ffe9d4179df25507de545f7ad8bb54f88f6bc78b58301288cd2766849b910baa0648420ef7e89c41f5fdae4d390a7eeeee8f60d2a20c215a4ec98a6e60a09b4218c714a24fef8d22e0db157f7de7bef4df7bd23fe16b108bf2a56194ffc1c97274efc001d97274efc001d9740274eac27acbbbbbbbbbbbbbbbbbb977dd0c452f241f3f8f560efef1b5d77dbf7f3dd93c2cf09a62aef7b032b38bd6f15c420c6fbcec1120e21f16a18e53dc934a5483c72f5e27d9bc6d3844d3689791336b9e285f70d0013892f8ac55ebcbb082f16ab4e9fe959262831d92b7777a3bbbbfb550fa3b6049be5efdd247871e7ee6e7417a109d2bbf7822db0644462328dac78759ab03e9fffa4699f734fece471a3316764db6711c5a2ce639ff3261231918d8e8bc785e8f33e6fddc9d3937356721d3fe71059d985f63987f079039d3ce79ad70775ef5c1fe4bdf33e98f30e86e89d8477dfabf11dcc9af7304adef708be3fd7ce134878df24cef7e369fc62f6a9884ff70815989e3fecb2eae4716311f9e5c98dbe5154c40faa5114f52797ea61f4dd133a79dc98845c2bd23fa7cff4133f760974e234e1eebd13bd9f132818f11266b291fde96379767e59136c0d7116dfe7f671720ec14b8fdefbc641b750285411e607c868bb2cdf9dbc7b91f1be41ac268a1f69ceb09042871117d6f0cc7e80b2c658282388203701569a1e3fde3b3ce48331ced887239058872c2bb3456beeadd28bc7e3de22cbbe3eb87ed56f7523bafb9d5fbbdfaee7ec2e1f45377a3751f81735cf8bae278f67ae288fc7e399a66922fffe8a9ae8f59d67f1d1d5b45f68cf7dd37cf32f267b54c90f52281426592f025061d44a126112b660a33b4d64d836db6ed46eeb95ae296e1abce00d4f373a210e1d926d49380f38762010e9e42d9e9d5538399fc72c658c26b91cb5e0b9e5b36a7c755f759b4a15a8baefddce394d8cd8be7d3e25e47de7eebe4f9070df2ba47877efe21fb6fb087ee4ddb938962fcbbb6fe12d7937c5986c21e8fc38abdeb77535dfdb49d8c1d3c8f27d9f5f346680f8e0297692b97b09eeca2aa57777dfd941af7af74d63c8efec6c33a902777abd5eafd7ebf5b68954813d2ab22f61df12b6594405961062a989950c2c51aac0b8b05a3ee8fb10bbca990f112244082a183ec4365f50812166507912f625619b445420097b9b43ac72868ad7d1d9a61015a8d3b349224531b8f0c1dcf3f6d8f3f6e515ad9eb7cd16d6e4902f0f020488ac9d0ca7f7f9b6194405fa7a7645b3aaaa255e553ba85b555575efce5e5d73f5ea365950816ad88f30c23681a8c011c0befc870f1bfd60c27fd8e651057e98427a1224b6f94305928881f623466cd3870a1c61f670630c1a9f3380cfd9a65105e688f95c2e97e573b95c6eeffc62347daec4e77a3e97dbb97d2297dbeeeebe4305e6b25e847d4f133e1d522b1e87c4e3e080814713a9324bd27c70d41e0767f34e9cedc3d9629f4bc0e7b689a50273515e8e25078e5fd4d28b20c08bd8e60d152822894d07ae60bd703505ecaccae7a6fdbd9bf7c105f14604102e9e8cf8a0b562d5ec9abaefee010fc8df27281cac8bb4fa7baf877bafb9b6f6f75ef9737826dd1d3c9ffe6e7b16a7fcbdd75ab9f7deab847174659560673cd8b0ca174a2b1528a26757f4d6a106d493df5dbfb759a5023799ac102142aca1528121f4ec8ae2a48f8383b3cd192a10a767952ea8789eb7cda20ae4a9aa2a03c4090f629b532a10448ba8ffb0f31fb61943057ee852f1b9dc46737bcd6d534a05e6a28abcd6baca6bbd793927cff5d17b67ffb65e6b4d45eb0d64c55eebbd0294d73ab7f5ee81d06bbd4d6298d77adb1cbdcd2bad370b2eafaaaaba4d182a50552ed93e97db686eafb96dbed8dd7befbd17caee771f8b16dc098b21efdb74a102dd6ca102f513980761dfd344cf83b04d162a10849e5dd1a72bbf537fb7dbed36efbc7bb77b02f243ae41be3bad5081bb9e5d7f4f51efc1c3369b54a007a6c771781c0e87c3e170caa7e1e370387b86cb6d1c0e87e371ca41c209cca9ea73b98de63c7c6e9b4c2a30976167a744d38bf7234d662b8a2b78a4ad285bea79cbe2f5eb8dea29afb7a96426d933a296efd0619b482ab00331ca73e0b0510e7be5c08103070e4a228e231578dd7dafa6913954811c9892afdb57b7cd2215a863d2f1373737667fb377a789bb6f36efbcb9d93ee7318942a1d0c8e7e609585808301d2435ef492e94496b4aa5e4d3d20f2593d0fb368954a05beba44372aa4b0a129abf6d4886ecf24d21157883e4f41bf6ddb0cd2015b861e931de9d26f4c69b87f72fc8638c31c647528f31005638fd00a3a6b6860d5b2818b731c6588924f41863fb04637c83b1f288c7dfdc6c53850abce9d97bef354bf1eb12aa40d5e8080e850ac419c5f8dcbea7890f9fdb3f40bd360c578018ea18a279df3e181a3975a1a121c3c58a950b1fbd57bd7ba002350f5420b6c9d7b0af86bd0315a84168ccdffeb6d131bd6fdbe73f237fb34df0be6d2017baed158c7f33efef899cfcbd1b2d12fedd3a90f2419e901a9d21abf7212cef3b07186f1ca8402c04c36b115eef1ba8406d03157823fa75df75d74005ae303efd74a3e95e77ce83faa43b4db7cf7f453e2dd193a61bc88aad40e6d3344dd3f496a69beb6fb74d0315784b13f677cf4005de20abd77acb2068c6e7808c8f264818baf838f2f1bdfa8ec1ee2d999cc71b062f3089ef02173e0e45511b5484cd36338800cad0731276fb1852ca39ff0bc673fb9ec8d9ce61b27f1eaa561eef87cbdd30c65f886e3098617e30c49cb3ec4882817252c57b6f914ca6b21145714b0d6846e26e57e80d89ea765250f83e3d59f35e7d3bc717e30b1df2b0c74d3e18eb344b066c377a51a9359d8f9e904bb6dcd5ed62b065de0b5a435c3e6aeda78a4c5d1fa33865253775851e21b75e6a6989534bcc34e542d892a71e0f74fd6535e741059eb823f98673ceb90619aec34d6b48236fc071c6a18ac88d0d365d5590ac61d5ed6c0c3764df3bd275afbe9de3c331bcb9ca19d6bd5b75bb1d671ab04e515d554cb38d6fe7f8fe0a2a67c73a8542d58d03998129cded18da5419659cd550ad0acab72ab65c9a144b0d2706d59175e3a2758dac3497ddc0fa1b47bb34bce10183281fa541dff7fcf4d51a0cdbf8d2392b11a6f7731473929b5fd44aed1e6d5fce5e7a5a04cd278a317e1ec27cd19ff3ece29994f632d50d829a5850e96315d74cc3a831c656481e56b92923ce59679d31c65b8731c61963ec810504bea0289a538127d9528ac4a9407d949684ce20de8ec0306919cb3405525643935c601a579a86d2a5cacac6157e51aaa1eb289d4eddae7857e7b14d58981929f7d02f9eb98e45635862731d8bbe0cd31705f5437ab1c0f222048cb1a8618cd1156411afc4c460834acb072b8551b9c8b034191b0f77cefee1183c1eb289f0d6b3af363cd1a4b122722c87ce181563d385788bf4c2c29d77986fb7216b34a01ac92706ea968b52d4e6940987e26c513d8698a23aecb57e1d847a2093b62588088c1cdeadba1d19a346514c4ea111a12223e4051214332b357b442689c92051eae1c1d7bd5b75bb3167f8161159a2a718e4cdba2b912f1b73ddbb55b72333744d66c86b1d94716af7184dc42c639952e48361b8bb6fb582a23890a56a0e97446f3addb93445d5b0e17487ab8b557443cb493d8be6a38ad3bb5b753b355ff9d7b3d18ce38653dfab6fe7f8525853d4489d44869a9ff3ac19b4d65aef52487386b72f27ddc19d1a8519f121328d30053576f8fac772cb6bad7b3dbd9f0f0ddb4f15510229f685cc9d1a88d0ddbea528aa024faccff822a13d3c741dfb3a8be9ea766796194de2e468be1c5be759a1c4385724dd4e78ead821d122d1ca20a9a56066cd5269daf600760dae6ba78e7dcc76ead83fd714ca105dc7fedde66a6fc8234a6faec8784c067a35c6d62c42cb60598668ce51d2dfadbbf75e7c6fde2a61107af46d9246913137e32b422b67f2d71696f26b8639b4cf36ac51263ffede22bde16f17d9dfaddbdd7b2fbe3a27c7fafb3226995cb9d8d931e11714444849852c686ae78c0955b82451567112e462c7049e0d1ad37646274452c1a305125194a668c05967363233c51a061b26e59da29b152646eb5b25d8d3ebb7491e3ed2a320a55995952439d08155c424ebca8a22a670ecaa6a286351918374ddc1ccde859e8374c18c800d598a2226f4e1ad324a8f4fdf2aa32c5985dad6a849b3a3fed664d144913a8326e493684a926843cc6879fce5e2e8ea9e988c75d6ba6b095a947392466b18639cf1bd61761dde2a999429f3623384c21a5a42991a56d8ceee5491d83277ed0da2e1efbd37e39c7728e17b9596fe2af9dc7bf155127a9bb75a492ed2e5cd491c74b130117977a6a277f7eb4c554c3b6a94e12ae25c632cb88ed97760650d150f245d6aac90f1127a19659c712e935e9c31c6b78bcb4d6bc9cabdf8eade2ab9949f7babec42cb713c1e8f59c7e3f1b8641e97ccade3f17834b7cef33c519ca66b69e2485be8cefdce4bc8ce6876a4d57e568a0af231f15ba5178e34f884adf3981a2993a417f99629d23406ac2d6d87cfba7cdf3aa5979977271f77bfeeae3bbc557a5571ab30288ab2bcc4b4a0053983e463c1a8f0a5cdc9e3b63226106f95696b3ebf55b681ad381e8fc763041480e29ae7186b2d30263496651eb5695ed921d314407029d0946ce514e80dae5a492d761ede2a954cfdfa56a964e986197a14709667d79bad63bca6943235a45a4f11f66678ab94c2f4b8b74a2942eb49a4b524f51ade6a29d9d0a8bdd98e78bc578c91cad270c3282a8666d2b22f43eb43348e54a52c6c8996901f396844392169094213464b95b2b0255a427ee4a011e584a48c21084d182d55cac2966809f991a32a460ba6a1324b8a3361b694a054b31246cc860d58bb71c91de31792ce9c95245d19bb57cabc86b7ca2b6969f6bda559bba7f7eadcdd6df85e37bc5582ddb84ec3ad344222bc556e3d79f5ad728bcbc808caaa8790222341b48a88b25820220644c58f239c620b316ba54883b4f76ed51535dd8df1be2b94ef8b734e9ff98124db1a0b241aac2ff3a82544f3f7de9e4fc59411eea9b091a4c3621cda77ef9ca1b6573fb87f3761cc1f5b41e832299471c6f9de7b2fc6f7fe86e8720b96e9e306438b2577f7e16f8866a9ba6d5f2eb22d4a5b0db3479b0d641b0ba134c62118b7a121163b21315b7676c610a111fa6a33d260436b012f93473209ce4752b7abd5ca647147d26974735be9d12e715a52842bb346057c55a05939512a1769b0beb708df7b3601d180f53bc2a163e831933513eb68c5d193353a23747babfc72e13bfce4c0f1c8e37db017cdd8defb66cf22ad992347679a7b25ea8c234a0b7cc3468a61c6a17aec8503e38c4d227bc5084c5997b52f40ba7cfcc67b1424193c65596f95508c28a1ac301d07f6c1c33d7299c5c618ab554221ba4eb2cdc5ebb7ca2a35e769aed0e96474e89061c66f78979434696af1820dab1857f90ad30c9cb74a2b526ca03bcbac476014d3d4c348a36d860d2b336e5592100920243af2c205a6e8c30a4926c429d45c71c13863efe0a9bbf00c2ec5d2fbb648323633b3861327399cb6305657432a5a57cc2a1a766b6732406b6aca46159318110dcfb98b0ae9ee4c1442cea87e5c150da965517dd0870406a6286b73c61abc3ca29433c6bedf86b7c92c53a6765e9401a418162d2c39ce8cc52c424d7fefbdf8ee50116f936a55d49e7c70dd59aecd47a68ca5b6f7ad0be2f0566b2986cf6fb596ac9853e6d4f53023460cf38be72d39485a42578ad6556ba9402324f6f305d11fcfb753825775d35236927c494b88fe875c22b44226faeec63cc6785f9d9621a9c82d098b3903d2a1ab49d75654ee1282ec82f1f92d928b8b0dab427632a96c9695e44d38a1e19da2f442bab74a33333750246d61a1e64c5110a5230c33b1c7357c30be6ec42ccbc30ba80f5a24dea16c13328344f854c485d114a6a02829468cd2b4ef6dd228c8dfbc4d1ad598828bf45ba519d2dbbc554a51c32b636ba12c5333d5784fc6f6eede34297f6f8eaf677736b8fa3e1d8752c9d0aec3374fdd09e6b7517da1dcba9296caf2bdf8a6cea58c2b0c571897178c9cb47342e22df24993256656acedcd3967e493ae8c2ff2c9d5dfde229778594f222c9466cae850ed18e12df2099acf0921a12c4172159150c620b9882df0d900bc4596cdf89bb748ae21f7016886c1a81d0d43e2e58db0a2650a9bf2846138c3586badb5d6699ad39ccad82b0cc4bbde7a6142adb596a1fae0f1783c263b94c218d4530b37ad271fd65a23ad293441e6e88c7d3b2777a254d055a71945d16d511445755e9e456b646a7521aa518ca13246b5ded88993a15486282f3eb81423cec6e6a6fe14b2b2b60fa76e17450d67734bcbb27430cd8c684e4e393b1b6a1b9c33c6655f2048b1598b5956d24c6963a636a558b6dc600345d12ce297418d2d9b2ed9591e7bd2c2a140e1312f2d4e2867d7c9d092f984e8c4e928e7fc84cc752cfa6450c82e3439d09d466fc8236d2b8ad79d0e69159285bb25659469bd42d432c63280fc101c039123e5bb40663146c2e4850cadd390651ee245e3ccf0a689c7e3f1783c1e8fc7e3f178bc0f62d434ed2931e240b879a9ed721eb0a0badd165b876752fce52c0c53d35a3761b2a15fbeb1497e49f19590d91549aeb50c76c329890f0e57b7dbcab219faf594f8619cb35796fa5e455bc3976bb80d6892528c6214e78cc986b4d639a339679c5154c8024eb75b66dd5214cae4d25befbcf1c6164d2619ae7ae79c3397dadd2962927e17945b136c7adff5b54b22cc9dbf313c1e8fc7e3f1783c1e8fc7e3f1783c28245f8f84ec469690d7f2221b2b9efd9133dbe58dd8a431cd23d76c535a13daf36ddfda83e9855e93e9158bac861239c245d47412e2ddab6fe7f894c6ec44c95f58c3564ea42f62bc36d9a3cc9299f32e69749d9978a8444d1ac952c6466ac00800e318000083502849a2308c4ae910f814000b37b088a0906c68228fc60271301c1083208a211988611804812808e2480629c3ea008f672dbbfc1b9d7fc2ff32c4fcdbee5fe2ff1882fcdbce4fe2ff1842feadce3ff17f1862fe6de72ff17f0c71fe4df73fe17f0c21ff56f797f03f0c21ffb6e397f03f8630ffb6f397f8bf86987fa3fb4ffcdf86987fd3f14ffc5f43987fdbf94bfc5f4304fe4dd72ff17f0c61fe6de79ff07f0c31ff56e79ff03f0c31ffb6eb97f83f8630ffb6f34ff83f86987fabf34ff81f86987fdbf54bfc1f43987fdbf927fc1f43ccbfd5f927fc0f43ccbfedfa25fe8f21ccbfedfc13fe8f21e6dfeafc13fe8721e6df76fd12ffc710e6df76fe09ffc710f36f75fe09ffc310f36fbb7e89ffc3c3b71cf47c83cbf285d52e4edf22ecf26d2b7e09ff1308f36d2b7f89ff1b88f936aaffc4ff1d88f93615ffc4ff0d84f9b695bfc4ff0dc47c1bd57fe2ff0ec47c9b8a7fe2ff06c27cdbca5fe2ff0662be8dea3ff17f0762be4dc53ff17f0361be6de52ff17f0331df46f59ff8bf0331dfa6e29ff8bf8130dfb6f297f8bf81986fa3fa4ffc7f3daeb4b1e73740265fa856c1f95b679f6fb3ea37899fff47c1184eb335d2e14fe10ef0d13ceec7c26729fd6dfd0391506d47524a58840935b730ad76a6c7463dafffcb85cdee303a1a7484081fc2c9cfe403f93cfb7add0de630fbad8d3c107728d6475a7b51f3f5ba3bf7c92f1000e51d31884ba035a89e7a52040305283ac543359c925f59e4b087e4abb8d3e3971a585addf912054efa0b0641de5addea6cfc7d76001b5920be2240bebf78c2be0c067d9f50f50735b24498fe452217811a8690e7a303a2626592cac13921d04eaa47792eb7b0e6398fee998ec2c72dc6dcc86cea2a1332547e2ae1ebc4fad8b5c572dcaa2b0e8e2c346ffcaeccaaebc3f2467aa356e605fd3ae6f9027e311eb2e27797f1c27ad97c6d71d242162c583d14acd23842003a6a244c47242a84fd6e1e3733b32c20b0a1013c780118ac1ee1710f102218df0fb835af51b817f62f5890271720be1ebaecb0ae805f1db8f0d9fcc65fb0f480cc4a9b973d5ff4d242dfa741b82ec09fb243bdbf82e0d25dd3e27487a9a1538c9422275689491e69bd92f0d7c87e050e8d5b22ac64e09040c21b9758c9ebbf00bb8f9c9e2865545a9b20a7150371e579ae3c3fe52d898ecf99b47ea67df4ec4a53df636f8c2c65f81acc5e2a5cbc839e18f7192ef941c2052e7d9c6bf4450636c039bcff2d05063ca3714ee7a4c7ba1f9004771a4539789af8bb7d2af4d987d40d0778478c794d6d38843b6944650fc4deeb6401f9e70ccf44aa8216483d1abab347300f2b3effcd4b56ef895165dc95575a5155de25c71d334c927e501f644c3467a31da3eb413ae9e1721b706a9c217588b6f2db4d9cb0560e7f7eac4d3cd50fd410ae941212c5d0280242376849c4b4756f777d231a4961fd0328010035968a6d1428e1bab816f6b7edbfb992ba7e905a90877febfaf15f5beef6e4093bf6a3a8fcb5dfed5781dd954ad00a9fa52d707a166662ce6f0bd7ae80508e0bd74526405cc7cf65a435504d201e0106c219d0e146693fb8b804f03877187e5e955cf896a1e8430b17be55822e98171bc22dc0876fbcf5a0f6a70a9bdc9b3180a833b600ad33a4941703bd5080a9aca09a2fa9546bcd6ff03fbe9eb1db0e8ea8ec37884542dd184f48fed347479579d42666ff42a0724a1c931a73bb1004376e354b00721b80ba00463da77a2780655c5f43a4caabe5db733ac34063841ff003b7cb8c0ef21c570c6de0321f6c95cf1380fb852a8b20c737c7a331f7b6f5dcd911c68c6d96b5cef705131695bf88afd9f762af13f2413e6d9b148404136214f1e7bb287f157b198d9b0bee593a608259636707e1ce00c2c350e015d223f85dd39b720fc6e774d7811339706af3236363ec24cc6f3e097f58ec9d917983afc0ca75098edf07a1c005dec6d0fe515d08e7d16028ae1e276999e25fa0d22b9ed4232e2c40f8455675ae548ea65e42ec2d9173213d8ac9942024e55c0d7c384655493353b7504a6039fd63a13936a3a38b0dec019832ec5463aea8bec92ba8b01875911061b65abc0d0714cae01ffb239751975368b0bdb794b1af8c13c098f0fb8319728c901a73d1c50be28363cd2382f32d369eae0b214e89667f9afdc525fc9e28d9724c794d7909118082e03af53e52cc0be0c09aeb1aaa7fcc4de79238e704afa8f5f95639cdba6339a5ccd0f1422e9531e4f145e1572a705fd9c242e3990786691f55ad8eba4215e025c0a8412969a7248e0aac0d3c3e8dec91c77c71abe52e5f02bf7dbc12dda0736c771d721945e88385314966ea0eadf3d680ab11e0ce184d173f91a23fccee20b2bad9b1ccfb9f57a269ddc5297efeee216ad5017703465869795e81c681d8cd891cc26df151cc83e65e3d5c3dc6f0d7a70c0ebc59f2f13d0318a1605cef01f52890f0eb068064ad2e0ee62fa6701e709f5ae3895021e1a41013da613d14b5c45b8935e128a9d77414eb0d387d611498b1e2d5cb63ee3422281c673114b764dd781e665b03dd138ea34876dcb290528449af4913c9ba0affe43d40f38b70cd404fea1d9e2bf7dc473b941e3dcdb72e92e6503006516877642b0302cd80ddb68aceecf4a2f9cfb4765212a096436450dabeb8e48f46b897d91dd82fad43582eab2b39383eaa7b00a5f43caf7237608d784c5d879b461967abce10b389c440ddef6957d2917ca639a5f830ce92c3988d4f7e3c5d4081a5c1e31b1685ff59e8dac5bb072c88f577b35e4b41a05834bd7e1c20b3e107021e90fb80211f553d7677fd181c2bb428b1036108b1c3c77080ed5635a08036df4fb76125b9865cff7a582740c7ed28b104b22bd79cb2dba54254a1f5545d40eda79c21081d3a55bec12303b47e2402e16c0de61b85d2817814925a753231d2714eadb16b505a942ab1f2a955c3d0317f55dcc95a4364fd1cb570cdbbbddc6ab654d85de917d21d338bad39a10d6858b29ae0848cff702bf93117bf57756ba01d91c30c8a14c446d32684d1ebde32d4d8a051b8d16442389cc1c013407892d6c37205a843d109134f4c3d3fefabc08feecdbb1b0077e159cd4b39cc219c8b1e7c06d27a10d7806a6901267233d8dab98f2c7b3801589cf4a944829a46ed30f362398f002e55ff7ccca7949537f1e14aa4f5770a4f11f7937b61e19d29a9ab9e95a9e6cb8c6bc19a45b2b34dd487045483628dd4e36f83e0526beaf4c6a4e75972af83113a2820bf6ab6004dfa8cdb8da9d34ef40c3da040619bdc6c445bee3a2106a6553b73b5c7523a32ab49576fb0e154f27475d54a29d8f7c2f859f8ae5dee059ac6562b6620c20a474279a6bf026ae33a1bbb69b6ec0ec7abf5bcc3d38cfa31a77741c70f1420be049b592645e63bebea28dc9379231760a3615ac2195434bf2fbc0961e7384c1f5497b366a70348ef9ddf23e5e505ebd651beb84ec46bc7238b89577a19994659162abcae5dabd003fe33efe82ae22be5ba96a15a72cd2e6dd53cb11d6506ac0080e9b3d494a16a1915b65f0d3cee95a9ceb4522ead1c06ec659f80e390b4b91eb9e2236c14d62f3a637b53734328d34ce2fee5014cd7cdd43ccf22cfe6237dc8ecc3f8d26660a47f31699c0bd37622aa6289a48385cda33fffdd44d54223bd2f40e8a6c49002ff430a00fd849673469f6c8e2096f31e557d6bab4031bcb1745eff5cf83532720e1a670da253eadcac9207468aefb5fd3947ca88f4bbf254a55c411f9a112d475b49e3f3de3c323ecc63fafa47c19c6a6d9585cc0c49baaebd8802782f6ac806784735fbe63b4892273a7b55d65e418f308268fd511e5bf8caec84cd42154130d49d148b5f8e933330940f0cf0a734baafe5f110cad8fea6aea1565922ee638c766dcb76ab4519e8a533ed1a281fa6151b9f22d86cab1763d04d89d25bcbcc5c1c8c58715cd4bc0c90f57959123b310f5e7090b4e96be0511c377f8873ef5f3a8a1a32ea59066d5de32690f83df231ec994d5e83199d0d46d40c101414157b8ac7222ccbc74c85549c9fc42bbd12400b1c238957b00b81506c3171b5dad223b839e58800b67f10fa43e29536317e78f2afb0ee8b054a1c5099341451a8a720c6fc41dca490faf1c963edc79b66a9dabe5517d48285d7e7edd26d0ac6400ea2296b42cc10178129e9726392dca206b4493c863e29f1b3de626f9136a1c118e4ad417b4be19d9b652ccf4c1e996150f25a3492315212ca071b272c25a3a22a605772a650174368901f05565d541754e85e99693b884e60fe12068bf355c28a723c946ca6365fea64bc93414f0da01aa2f6d4367b9c7154b7377a905b989b71bd781d747ca0ca4e9a1629d019cd75dcda4e6ced0f78349eb119001df01025fa161adfa3fc0b2724b4d6fd6aa75f27e4d1d57885609360b18dd983019dc51297e37aaccd8965d504745a0d625311f4910ca7af34366d9f941ee8cbecca2ee9d181a23481978734d91d5fcb60f5c42aa229c593eaee290655c01a0f942a9ac1b415621b2809c6a5cd1bbbde45df6bfe1609a85c1083d2b5a60550936bbf15db74a4b27f5cc58de0e8e333d8f915d48cf993aa48dd5c52b05fbeb94ddc5270ac10b6daa202b6422c58c6566b0e30941d80a0dabaa0b40a1ee9331f35aee5c68f9427f1c8ee85c131988ed983f0b9353ad3b2ff2dee6fc86a0d9fa793279725b7cd9abfa7cce6b8959e8d60ee924495c3c7a5c38e7140f228864dcd9caa1fdd83e6414a614414143d3cebb8d816f7b06921225e7fa6551a2858f8fd69b70dffef79465a13d7e9598b37bee5c0de3a2ea909a20794d831e89dd29c250fc22b4cc1f5e4458abec51df407dde73e89b02121a0144ec502d6563e900d2c8af5f034c34ce3c3a03664ba82d82fce616b6d68c6b7e0b6b86df05c3466c41059de167e4db2352ab760056a299fae61eacf37e464fa2f2585fa3ea48de1e1a86fff5c3628183d12f7cf99171c6ef4141193b53e00627b73f747f8c85fa19ff9c96526fedc60c74ebc0dfd33fcc52d025898287e1f34c90320b81fe32fccc62757148b27ed4b8e5c26c543343fef70c44444a8b784d1bf73964d6ec5c7bfa627109fb85b887dd147de83e7953026958d0d411e0d2f526d109fc8aa804a18372d1d325225ac21cf86dcd19817b2e78abe2f1841be93cd859cd7f969389333bc6ac1dde2c69e89d41a19041f3053c0bcacc73b7af922269202a2d7414f604e1e3bcab1bd12c399807b18902431d590e181da2c8b192764517a248667f797294174757a3896ac191d7332ec031487521401ff8ebb8445953a424638c813d42a015f8fc9afab9827f742dcff56a70a0d8116d304c5381a2e33a1c6658012bb31ea211e2794988b16a069110d18401d45738bb01b6d06753cb32a0e42546c4fbdb06a415c83cebba0fa4e41253b1136d2953c1f41def323a075adfabf04b3152e215ca2b123b6211258945e3325e4315f7d7c02d3dde2668607fc236d55700ea1a0a97b2a90d3310d00b1830f53f1854b19acef2050a790769a755bc63fcd99707ed163773ede8e4a8d2d1445f577a02225a185c0b0028177ed1617161e33f41679118eb7abfee1102af518f283beb9b5183e16586152e9614506f1d921a9478852072e9363c17f3863892a68c53d5b384e3198fcfc0979befed69603959840650b63c86dd3d068e82c7a0b92a1dc1d44c731be00073ba7cda3d7399f084c3a4d671dc8f81677ed8eaf4d36eb09fd48bdcaf002734ca1ac080bdb7bba4ecd52692fedbde5b7b87b2ec78c64fb8ea94650dba75ab46b8539633feb3600f6d76b881d58e25ec711f97f5d42eb0e08d20fc7b1f97cc93409798296d71d1c789ee4330eeb059d0dea86a48bf9afd44316a89a41f3d9c19453b2045cdc2385836c6eae61178450c1075f76741a2825403c2df4b344f527df59cfc52443509a439c6b3dd6c3e71ac837f80d3ed490cf855bed9dadea1be5c6d9dd5401716a54808b8b6ef43c231c56e4b116e59437617c92b1f237a260d6762688c6ae1091bdee0c641348d86131f8863e76bb8500fd662bc05f3d016154122892408ad5f60f1e9488ad44b60ad02cb3804db753d60c73075ae4aeb11fec909ff160ee084412ca3bcfafcab8012d0ac177831d0264df86888fefbd775854e2c04ef9a38edef934736f04cb54487085f24acea8010ddca671fd169bb9d05eacb438e1a07663c41e9c69f0b1afac4bad1382112001224f8457d1eb7fb14b52ecbbde3eaeaf61c6fcac401d2453d282b0442df107d32672b332cbf7232814d8760d79a5110fc4a8b10bdd2d3bf7fbdc69aa2efea5491a700ebc26a983715ef00f123ed3a54a58a60bd7bfef6ab285853d1187016b051876aa829253ffc8ad21419be8a4ffde780e406c5b80af93e5398031edde3bf33231bee4d44b7f1ccc19dd77e2e4e8dbda59c1b4a1bf576972f1f859f91813430225bc60890092e2250a2eae451aead7179d452506ee44b36863becab714dafba90c0f90d3e6e32ab19eaf33e9fe6fea76bf8e228b75bd2659a08e3d787afc97a4fd75c21c20d7fe3ce7d1cace6972dcc5ee5924a1d6c0651ead7ba590d6b7670bb4dea4edcbb8534fff0086f744bd33bc7678d412f409d203d1855cd48b471ecda7037af1e9f411b8ce7b5d3bab7f212488a621cd7e8ab0517732ff11c3b06bd039482d2ba416584c81990878672cc0038a1cfc62239adb2634cee97881f6b730af52749bca27d77d4e104641c2bcc30808da1110f5357b39c98b30d6986d149144696af97a8e4099a1898d9179ece8ed435668f679288399e68ecc857d301d4baf517f119adf6ab9859046885b85231c02f7d4e2c3de1748238b886c39d1697ae2c339265668f29c68a98b0e4a57981142da9860fb824db2461d7eb51d7af2a76b5bb732a64d87163d8cbcc31e883e6432626d19457d9276bbc11979730b2c6c703927cd8cae1f10e0bae6394e1f38cee4adc8ed85b081f87ece049bacf03d52f66ea93934a91db713de25c47b83661ebd28ae5d3a24c8c0d07a9aeb0e68c896235ce3a377d127a7cf0c1a5884944128d64144fcb63ca687140609a3d9a04f6790c83127a0830cdbd8a0ac4cdc939a973b3da0a3e5f8e8025cca9e1f95864b8f45fbc0347b77086395b034ff736290b01f0406f6c4d99f59159647c6a101e441ef71c02ff1cdc37a15ca94edf5d4b68976c54455225ede1cb8e9e49da25335a77614e5c524b6614f0c5574d94a5022ae99bceff62f48f880594fb9cf3d330509dd05adcf2b0773b1ae6ece46ae0a5a68ba34c996b611e6faa9e8f389787203915bfe46c62dc672e95647a1df6811b5c6148699b538f42bb683b5241c51d7d046c20a6335fb0cb5ca41049dfe67bcd06a541272de0d58c237e11f411a710aef92fb61b145413d6d2f7910e3eeaa9b0ce5068345142e66b507db3120d538ef1bece4473794cf9976fbb318e77a063b805ab7139e41010dd4ce52fbe8ef9704aa264f7e96e48f8f4ce699cb5fa1bd8cb41ad07a45e14af94ab1d33f90feb9e28f21e14adc6c6c4c33ac2de0ad033d26f343bb6405058f4ec7dbb822c9d36d52cf1e30d4d3198daa4e37aa4b51d4a92ced0ef853ad409c7723ed750e27b7dc8d38d94d658fb3f40780fe5a07fa3368253e6c1e549b6cbfd3a12e569286622db895c57093ac9596df91edbec767973f563d5ec3c200f01f674ab0f4595d5f3631d5ffc1c439c17aee7ef6e223b6e890b0c5c153c6dd85c607dcfdb0fad792f63acdac15ad39b25b45618607372836dcc98513f7f929a05a546a60abcea6899a004fcfe7c740eb6f2b954ff6d62015982f9d32c731ef420e13dc8788614ef5f6c4a3f7d003e6188903c9d09ddc5c43933b61113ac4e304cd330edf9927083e302a905fdb4ad06cbecd12073394100972063ae69395f2495f158701b7d8f964f64c9b3a7d85b91f505f6e848c57bf6fdc42674bb166a068cf6501b69886e2e94f9b7f69280a3c3f669c1176363faef296ebcf4e848512f141de545441481a8a281572761bf9e6f3bdd8564a17e0e5a13b4dc631d78838817606c80d3b641771c57a29c9665cde86f6f66d9cd1796e6aba4d7bda17bb124dcbfaa53e437ba64f793b60a1531231e73f76d6e8a07eb1823785210fa20d7961ab12314eb52f2ba622ab8bc23dbbe22112b6a0ce384d81cfa8bf8a0cfd15e50fa7aa025a449a7817a6cb8039989623f72c2c2af2c3c537b37ded1ba41f2e82d69f4abec42bd1ccdee129addc11abcc9a770a06ad9c8bbc80fd8eb569838f4d708505e2e614fba8c1b38c1a10ffdb37711344c212c9df0879cf41d90dc1f024715e1047dec632138d7176ec7ef814c596118e0459525862d92988109d136e0048027f34918dd106fae05ba55b4515dd8f90298b6616cd2a68d1fc4d1189288b5e57ef1d23ba814c46a33300096d19683d526521337ed58dac0d690b7ef2e8bd9a006e7c0d5f95514568fb2ec5486aff4e417d6700d21a1287cd6a58627c7a451754ae85c9ef3b13316a1d48ae2c278344603fff9030c740da65b4a259e6b4f488aea3a5a4aff12e4a0d9d6ac9ecedd5c29705106d8b745fd9ed7455c28c89d620c48a2539f43db805e22718b275f0b6b395c9fc3907fa86f4410160251cdc6f4f868901c163a2f76cbf6ccbfbe61ed1e7b5a988180d0b375220b9a6b575ae1ea1fabad079f5fca79f09bd49debc455cadab4aee21cc63e8394c93809e2c99a508e0b8248b552423d78325f203409d03424b6a2599ecf656934780e1b8cf632679c1578d2c1dbf3589b570094b081d0c0fbddfb76ea9c2e2442669a5251f5785aadb66373fdae87f91fc95685681d8cfb125a7d3526623a3a8dfbc2257f7f36dc2d7ddbaeacf7ca78392d123aaa8b85f8724999aae31caa047910f91b030a44b1244e3a9988afb7c89d2480df354cfe9126d4a55893d1be6fd3fe642fecb3e5d1ec51530b70c45676cad76d22e0cbb5d50daac3d69e87d6a30f3e55e4bda348797729b273bee909a792f9c0beec8d06bb35d0bd050ffe6092261c77793b4ebd0bef3430ae6a12345c503fe11c77adbed40008bd786cb773fa3e68658a49ac7d044c15189b237955eca8e30e306491563caf29b0e59bfccc64e6fae54318d4e39de7d8a375b04f8db7c3b3c35ca4b7f70e6fbd6e836ef392f03ab9c90e9b05d2f4787f2327f4d581b4c6ec2e3d0e3d17d76942f9d848c768809ce298d1b3516700c950177b778b45439f3d80362ddedb850db700491301c86e47a0213da2454b226dc07e6f04d4797100e14b5412bb555fcb4db0243fb36547ec497359325955433123b8cf8053b5a9494b4ff57111ef1032eaadd8148782e5ead5927380cf155d78624f8d941e8c27fec370b7a8cac9b17402b5a887dd6a06cefe04c1487dba7ca377f86296de1c8bcb23a96b3c04b5610638b54de1937511eab684ea1388db4e8d4ca783d753414504565cb8e82d0f2b0ebab9bcfdba3fc197e6e301ed43d38161c147434004f298ceba809a74ad14ea1b54b3f6e273d8e039d2d5898fd6024031d63db52563edf0a0e5b8be569bc4e3e9cd9bfe6458fd28de39b54060eded8054c8b4db97ce28f7565d095af7f1636a7d73794d6cc1055a0267ba0bd20fc1dd2e2ca4984f1da6e24c4dd3b71e3855ac1e962c93ca3e1c8bf771ab51129cbbe4415538cb5163668ed986d638bba415da17d1ea185f0b1876e34701a75f62328fec2d3206939caf101bdaca5308797b5441a196880b8581a2289b1499d3d662d4d58784b9219a3b8a1f7917bfb45064aca1beaa56d3fb0c7fee6437d0fc282633e2041235e9dc9642273d63e1564a870863c8a532221fc05d61508870b48c39cc5b27b0fc229392f05797244a8020e584443a83166f1c082a961fb1bd94429492b7ff3c1c1775fb1e4cfeebbdcc2906a85ef374812e994934e5637874aa4262fdd2549be26bf67e7c4e924990217c4da2919cf0cb6e8c06d45fd36202ef8138b64db3397ec8bedf7208ec7e8cd51ce11318e066d0b4228e4b11d65a38d5c0b6c3b79e0868c87189830f406d3f21efcb24dd1890ea6da4c57e68a8cb238650dfe8821e4e990b2325668050ad01b11fcc76c49278ddc6ea58230f91c2e1abbcd3a29596ae457e77bf736fa0ea3561db7aae9aab705bdd5f2cac72fe3183d2b7d8785dca52d0ab8f861e93a1f471b0207c798df8bcfbf02da93ccb2907c9120ec3ad1d7378e4d74ae1d01212e87bdefe297956904d081963928df9243e80e2185e35837de6708a5283e7ff9c0a519d8bc9b840c1a9e3644c11756d5234ec06ec309e544efc4aa14b59048a07d147f8c221f3d2a4a32a3a05984b6754cb20dafc4bde772e35a40f9e3949e1897a1c4053ac4555e7420f87d72115d103163edba3389baa7381f7ec89849580311fe2c426ffbdb05c07aa68d578349e68282b3dda3358f84e8b7975b9c83f85f27fad75fb80a8a75e635bba2c9ca6a243f3d7d91581e2ae2cc46e33cebdb43b50d9001b9af532d8f83d059dd4ca8457c147c4f03e2e02696ef29a091876360f54d3416441f4cfd1545dca88774e26612669ef2ff28bd9a3afe2981a3abd5d9b4782faecc275d6d4ccd45cf08fda6ccc12b2ef4d84c036e4952abb52fbb5fb4e1825bfa586c181b5f0ab53c9e4842943941fa42c88b412a700f5dd6c898e54b7dc965e771c12f52dc15462447a9549d722526876eeb92ce415f0912150ccb6186a1a7e138d4c722865f2f5a67904a7a1d4f786edc38e9283ba89cb42469095a1085fb9ee4a31d59953e352779ae879016d527517c6f0aedd127d1e6cebdb35b046aa20141b713e29d0d8f9486f754a44e1ea5693fe492223e0c8c3e61236a1113ebeabec5cc4537c3f8bbc0684d4724edc61f2a7d8100a3c53d82726f4f7648d8ec353302c3ced5868f2ac46519967c4d6a1eec57d84503924f714bb3e346458e41de4989f438a65374103b02e2fa0b1df4c0ff038b3e43d8d2698b497f758108a1f4fc57a00648fb3ae23deb6d6e8618b1b8863fb48c80acd1c448026e4adfbb15a0ba731c9d015fd4c1e7dfe7ec08c8dc4858858d0a66c65bf660d75c13bf66619c116a4b51530b251c91600c4095a00bc963bbbd06464448b0114502e8987acaa5cc75358c395c2dcdd1f2f581868ca66f680581c1af7e304a9736b02fee2e493708478a6550daa5133b9523532ef5b8cc03c4dc25909e388bd8614588df43ea92c49a18c495804d5b50fedfb4f9c51e42934794b9f13af8fbe68b6852b15d307d303d757c923b64e01309856a03409b32539936e1a4981f5327aa9fd8bd10e3fb4d4602b06b34498497a36cbe06bdae498d900f04e5e44e89e5ce201bc4746945570afe769eaa0fa5221b91d2f97cff1b2b9a9bf0804b5da42167f527e95fc014282b781af5a9c2086e77eb4bcad9265af0c9b43d36edcdd43ee0cc0df17e0f0cc90dea90902cedb98871d992e1e26c95b555bb5ac78aa738f11149eb3947fcba182d65749c11c03f4e62717d3013121052b14aa06a8ac4c017cb9668243349d980dfd28e4c464fb73d1405b8b2b6c4a54799145da5de5228c5bab52437f9612dd114749030a432b867e8cf5407030f291d5e918dd143d137b4159ea25834114e33613e4b4633ade1cb1db318b518c5e907a43d4933d64e5156ea1524ef5998acf9bb3d0045ec25bd0b63d2a854997543430c18ce9aff15240a96da036d3cc730e3494368c3339a5635652a0d1efda7323eda639d7fcd31f010eb6fbc9a2ad8e5d834292a788359357bd40340d86551b6603915b4fb790eef3cbdef427b8fefb0b4370bd8ecffa407405763349cb3faf6ca56a4368913cb474120c0bb04b32ab4d8119ac117e4d8c7221e69862269d921215f571d7557d72011eea058e79e0d0cde08c889faed12de11b5fb1f7dac19e140119431bb189fe2a6dabb4ae9b54747cea19ec3896cec443fc9d1b19c5b8f3d4cee06cde0035e8805dc8f34c9a7d5f99df2fc6b1d50305d32ee86828ed6d8571a73e101bb690690a7bfa472be2d356111290758aaa51c0e7b69eab6d1031bede7b9bd179ea46c7a40cf0c168e704070b6430da23a3d8f3f4865eba336a9696f8d9a5c4220f7ed2e44d030f1f2e98c1ec8a1e3df263fcc0c467e87c12e1de5a4e9f941cf50c5a1272e0f55268a7860d004416c8ee844577550031a942da3fa44505eb8275ce59bec79c0e485a275a9d485eee1c14d216bbb15ac68382a80955600fdf9067f783097ce27851722d3a7a4881df9c7de7ce16271f521f38707536eb95cef7e8ceecb17a6044704be6a07cefcfc3edea7e40b17bcca0a610cc1a975af2173df167e74120d23b7abc337d79ebcb015bfc55b83787031146f14f185e79579def64e2d1fa4c39d709804485fb00a46c443f2e213d465329b6e01d32518c0829b380ca794673a53aaa5cc057105dcdaee96f97448e36cf608c0a07cd0bee51f1e4ca1a8e23bccf7f96007cf4cb6ec3f31b591c5aed290204ae2d6be6922d8d916b4c37bdefb981515a494059ce97a0c001727e45d8d575004414e5d7a4fddd2dd05b907ce61defafc6108d44f74c333728d1228362375bd115b2fa8eef34ba98fd16d95f6a97d974b3e77ac3bf03f98bdb97f6a2a3bcd47735480171ee3b103dd2bb715b0c937819bf894d7d19cacb80527bacff13f30431e083a2fdaeaf362ad6f3bdc89395b027b0db05eed2e7577bc50f55d1e1df3ca006aa3ca4b631b42742a84c98812b8bc60e0538f4306b97a8ea2fb97807b70d9b4e0df37a79e5b06c06c4119c9b206b615fc2940ebd798b2de8621249352962da169eb08c02c15e26b21751a97376bb406de64eedebd0b9ad765c426efc6152e6c11e604e18174f82d52a2a870e1abd99cf88b8b8e29dd5b10172ed5ba2834b179a2bf94e55cceb5a5336eaacb93465867adc5b2e3a8d845e1c25c0639614229c3ab939cc5f2c87d659978620d5a245c58300b2b372f449ebb287b79c28591069d7463820e3f516c8eab2ecce5c52a6b23243ea050d561a929b383b8d7f7dda854bf048c9eedd07488876ba9444ebcbad952198470e18c8d4c475761a3645996a06d4e9e5a24081796774010bd996c1b849c0ca0092f33ec3ad23ef1c3893ac285afe61b76183e2c3a43087b4b4ca03d0ab4ba585ca88b6524332a1ef1e1d9afce9d10b998869c0817b670f66b537e2926534de27dea5eed84a49e01109d69cfe68e3b3f3ec2b3445b7dd31fca818f5926ee6170e1e28b7320e6bcd32911d16f7061cb92a1a76e1d233f7bee25a1d258201d25f303f78912d01ea2ec38c60aac964c02ecf914f9e202c043647a8764591fe903ede5cac7dd7103ce0696cb9139e1c83f03e24166ad938f4a830b7f805dbe6214e1c4e9b75aa5a930ff388be9c23d0316a81c61816c50f71b3978c15204759854eb90206195be9237a222ecc43c01b102bad7f5af6cfed50bfeab220fe1885c82b61c6bcc92c1583585b4825cf17e37dab3c8b7e5fcd5c80911f034b830c0f724a420f0fa13ed387282d28673aad540c077168a37b8309c6490d893d9aa8a8b4040fffcf3e1b232c9f39818c588101bd7e6aba92b276e64a76a0ab74677caab999df922e2ed07ad53713bf3264628eb820b9f85b487aa5f53459487429052027c58d5a63f01d74dc1851d428188f37c06dfb672f6c74490f54580fa962cb870916915b64758a74af1312582fcb771365951b1b799328c2a02769c576107608d820b8b671e876bac6a593255665ac145d8abcdf67dc1b77f1431b8f0a5e7ff9200c39745096912061294091458e9f83353219e98f81fd0d8675017cbbf8f808c8e8fc9017a9a82db7abb65425b414681e3acc86711bcf2a4b08cc59566be708f0cbbf998ebd3d8ee68e1c280d9278f0c3b36ebe408c5fc9d66d3d44b1de0a9c774d258b8b0e5430c593a322c7c0dc33642a5866e3a3d85a32019e6f0ad8e63a5954596d8cc0dfe5b688686b07d61bbb0d12289f4604b9753858290279b21c2f0bd34a981b6c643c39573f0f354737f699a9153755652e906b1e9c6d9796484666e4b59789495e55f0f7e093144456c40cacf215dc53129c3ec01dfaa2ce234c6ece11aa2c1c7e9741290df39bd0bcc6372d6242e9c1df2cdbd947cf64b5cd83239534dbe55c599f496d33c729c98b7952223990ed05066dfcc68adbef5cf689d771ae096be53fa2a25965dccc888068ec38aa3a1d8dc8111db9ebeaf4843809e4826c36f29ad71617ae44e73fdb95370b6730f04c1893fb65507eadac543b5f6e3a8180f231b17be68d21d4dca9d17657ce9532652ee6ee32c54c3ae3b3dd59fa0cabc317d2b0e7682d9cd3ba338b1a4fe91951983bc92e9f0b920bd171f1786ddb42bdf92cbef13c885af2e6533d5a74e5f0769895846d07289bb55efef46ad0cc45b52b6156ee110c15e08068ba21bffb870bcfc4e13814f6b9af773f0febe59ff90577ef1206568382aa64b1a850054657a3a37a5326b4d8268189d25b6d3ac3bd8d53cd46f70ae2905f5520782e1c28468f83b052a809f385b75b133275af8c209f497630f150d1fcf5279160b3677b844b35993c4d1507830f7928c7900c48d889b4d4537773a05e03c697a5f2ed5118d53bd0536004050b34c8286816a86720e1241c3a7974fb51194bd758076c113929bc39bc8030dcf4d41c7fd52b335bb109a3dcdb7102b6b524bd34abc52a81489f0656a2ba1e1c2cb3b58ad06a0b6fcf3d69d6c42c3e8106d1bea7c82000dd84084f6105841b0511b208586297ca4e0202eb19e811f887a290ed09157d93808fda6d085864b4cc323f8b1dba18b3c441a0a43d8942d9c55f1415a2d86a9be3d17b93164011c676a980e7a06ef2e24c39653d1544e1eec4e4f094edfff568a2cc7a17de349e131348c7e756e82166154127f9fbac6c4074b2847524e03ded0b0cda7fc60a1e84cb274ec6c5f54379e86ae8b1e4a965c71c4da118737be7c613011954d0c148d356ee4916801232876f5ba91824fce2ea6e04f0f0dd300e905f7a161db783567f49cafb1a4a287ff8d40fa5e6c10951abf976e67da59d88f1bccef684b7f5c3072b9e74f516d39120dd3398bb84fcd821f1b33778e20de3c4d75658b9e582068e5ea709a70882f39c1d1fb654183e92386c34991c39a2f0045c374eb383e8c4fe31e81a148c38a4fbbb6da3d5b44f016f8b8881c2270132ec3085fb23a9bbf400e59d8100b31e04ba2ecd729b58c3545c3f1c0f338f454e2c41998b7e4aba2bab0c2219f9d108aa43a3ba561ae0a05e99e1124f52a520ed545354c46fc651781e8102b35fa711972bf17ed462f382e6cbcf8a00566cd47e6fae57ef81178958d9dc0c5cbd8c8388d07900a3a8ffbca3f98a57c85ebc6914098c4ee181e7ec45cd65afa0fc769688f68014c36ab31016c88c014f1a0a1debd08c913da33807476c0a25f8bf1c8f058fc23840d640f1b477027de6e53b54d0f19a0a361428eda18e2a4888feea4c24a258fd37159a72e69070210f5c91557177430e51f49c0bfc200b6e287a9de45a38237b8820ddfb44cf11f7effbd47c3d328bf933c6cde745cd85c3d70b8dedac8c2219d8416012393ba6871d2ad182fc0630cf329304b4901a4e10b7721e7411a765a5acfa39cca86807079cae5e82278d60c1d1020302e92969762eef18073f9b70122183841eaf4d23753970685a866933e5b0f1e52c6b43adf036f8295cc2d68740170c210f5b41a9170ebe2f5c38ee1ca2c804218793467dbbba529c145017dee705b3dab03e048b268e4df5b07f540ae20093c9cc791c66862ee7d0509d023d540ec0deb69a4bc4c351c5460fed78d485393b472c49fccfa90a2db55b880220c97ce21b88b2046a899917eba52473e649bb5c0c7303bf5543d1648b233af2c98edbab74af9bb5320020c4f6bf3c0802c9b0cd192d2b0fc7bc83b7d19d93e289859011bdb21b32fe3339e600dc7e8ee4aa81da4c51eda999eb35742484cf54d09930f79cd823b2e94eed7ecf3180128cffb50849113630a2ca105934dd9a3c7d7a8368e395615afcc2a14fbb86520543e642483ca2a688b6020c26d4a7cb15db74a7d811c0879cf186bc1d0426eeb7470a6f56dc3945df62e905befe1492bac5b7e913beec3e21aaff9902b4063bc2634a4e2c7020d022b610890315cd9e16efb0ab2434b78fab6aacc723c43fa9021b973874b2692e226175e08551fb2452a63ada72896210c3e0fc581d18b2df1c8a22e1a94fd8833bc4904c198a47f528cca3ee42c7e52ccb11c6f083ca280848fb53b0e8c601f72401246dcccb5c5ad95aaeb4df383ca16e7938f66ab39267fd0eabb3181503e144d3b0dd070eaec9f54df5b702c972ce2be2c571bcbdf51a48ffeca51a253791d0249a8321ce360bf4f5ef034dc8733cf3a629cfb902328812fe34ec670b98d9efd3ee4428dcee8efd105e4e082324239ed49d3e0871c954900f0bd1743f49d58f8c965897b07bc8078299801e64db26a3a989c5645f96bf0902a5a5fabddde5bf9214fb4413f9482018340b233b17e9d387506849c57c7530cdf302a8c063c57ca022eb0aeaf63657d17ab2a8c15af26d575295977624aa01f3261b98582d50ae57200939aaa1ff27512a3fe99ec877ca4933d8b778824e0a4fc3bc2270cc5bbee65c980dbf6648cf698a927649abeb0d0c74d208839ccd87117adfab4d563fb21fb3203c04af7aa1733acf6db8e8b1c426d87f49cfa01c58d6ea6d95565e211c55a3e350e992494aabdd16087d4be42979949a96be8b79970a9d3cbfeeadd15d9b1e405a4badfba7e286c196076a87a3cdff28c8b1673b4531dadb1ef50466c0a776062c1f25ef08163d82f7f674afd9eb058d448dda4e2f6435e9ea0404308ddf5685110df681ae55e9fa125a04258e5415f653a905c8fa500c7cd616f87647852b9f846d29ff761ea66ec870c15ef7bf983dab278a119c16a754a47da92327e8c7adefde385fffdc399ef56d34581fb743f646b611f26532044da53281ffbfaa9160081c32b81d3ca7856eafeb487c362c59417f9f2871cf564f531b3e2e359a51e23c7c60afd2137f2c9aa7838ace0f37e422ed70642d9eb8c4521ec0f59925bd182bfd5f871631e0ef31f94f95f927b4603a022b883c9e38d056dd67850d2c0aaea5a8a920606fe4316ad01aed689fe879ca3482587fa295ed271b818ed18c8ac09dd44d95257219075ad3332197355a6db89a1c919fdb2fe4f38c23eff562b110862a5ebc866b70fc3026445b28606cd1609c55acc7fd577001019f2d4135cde6b33201a6e3463e4e57e434fbd27830eda857bf26f0ae2fa8466bed8d20044e6046025d8caf64100225f53300eaee70bfd31a3f3a577831d87c595d68089e3b14f0e80c8d974ebd93a8d0b0489357ec338b90f06406428e4b68556b6e050944b88ab4e966337f0e248ea9f13280d550091e72e0fc90b812746bfdc4df4ee0ea2e6636a78ceb20af23e407d014406940372fe195b7f332be09d4f384eb2990cb56871514b8810ffd6f7c747c01de1e529d4be0cf810c14da169486ffe3f0596bfe48ea6266a89c1160e56e80b011c01581158e63f50889607a39ca6762e2072e44de033d4e1027fe0b9ddf8dfbd029af47d05cf4edd148a3ddb4ab5103520b2bff9403819383314d3015a3dad415f504eba51079aec5c9363797a12ea8faa25d7924f83c12ff83c88136098a9189062158fec65efafdafcf41cca3c92671f3b4c07f456f0d7c328fc75301d8e5a8f8896aa41ca772fb4b962585f7a33d989344cdca9ce96d8dd64cb2da54c29c96504d803fa033ff39b9aa3c42f6d2b1b477519d45a72e3ead9af75c009c32128b7c8b54a478954d641625d7132474d180e3db931c7e3a8cffd9c2cc364b16b5ceb539c8d8bdc2b37b7aaa20fb8959fba456e95c7bf7dcc34d5959ffa949bac2c19d97cd1437fe2ae7dea85cdcbca513d6153a8c49303199904d1b51da6649185e836b99bce3f394aac378d651cf5b89d58cf3fdfd4ed40e60b6fe576b573abdcf84fcdad3e75726e35b915b77a3a4fd443f19e68eec62138ed631ae3d4e6ac76a364bd11692ddf7ccad6664c635bee9edddc98fb460559ac487263d1fbf2531d63e2c662a887c8a297c58ac416ca628b44f0991a760d0a28766db68f44126411083f819a43d05f381af51637c780ce29ef0311235cf01a40ed0e912427e83a80b14480e4605171017dc010278c5c18986fc010282fb080d4935e18438e1461c0901b204354a4310001287fd8286f54e50e1b5c10b68b2d377fc6fdd878c8ac7856322b9d9f1a28adf467fcc919613e4620c61c207880e061d97493b68991dd848cb1e668e5f6838d5b0aa8b5dd79d3d1c41324133d3e2869264632f7c30cc7d94aab40a9dc171d1e0e2e38a6a0528399b36535e0680191f621001cdd5981a356d901479528b7565b597c79c2aad860a507bc6449c7ba31589a4a6aca5c6d6af4b83a3541f9cb53a76687c7ce4ee52c064b5425a59552992f37a82043bbb6ffd84f270d30bddc97fcffff4fff612e479f5afb83efffd7ffd741e296ffdf52a09c1f20a5ff0fe4caff4f1fc887bb8372319a4ecd0e2c090078c8b587995a39cb719c1582ac010361359e2cf9e1070a39aced8149108b158ad418d235462357faf4823c63311c1cddad5c1515f761417cb0276cb0fd074203888a86f918e6730363180d3024b288652a2b4ae3db18fcc1030f0da441cdac66d6544aa94c884ca94c49ef606735d2a96860e8688af8c1c2129915edb1c4c78ad2e4b834487cc8ac2e98a78e6a8bc541a74694ece5a9538347e62fed3820b87abdfb0d44d163092b3b7e76c892a872a896e850a34a0a2cf2d451d15077c864a0a10aad5e03609418e1c1d67530a9454179a5ca8501439877408c05c444a5a4f997de184d68b1d3c68aa8ac10d992452cf34db1420ee40d0e34e478dd0092ed284f1d1a2c1c0e6f969a9c807022ce796b7c1b838d716399c6321a87d098038d4b98347809a848a4ac8880896de112db12c59524a440f901f6aa8188097ed46ca9b1c546c58821787472b081f5420976c46eaa2e4e54a14571a22409122330e0f0884571430a2d567e8a287de04105476268a1470c8ad517289898e2230413f2061a8600f1a123f6048d5b132de86912c3a15524880a36312d36b860a91d4104103b3aa40005392ba010cb42e325cb1248cc8258b2834b8613b070e3048e299e080262c113590f2b9841880b29e4886119a3b8928414283fc05e351031c18f9a98adc6161b152386e0d1c9c106d60b25d8116b42d5258b15201f284d74744022430c2ef8a8895db1d1258b15201f284d74744022430c2ef8a8893161a34b162b403e509ae8e8804486185cf051130bb2d1258b151c38cf58149e3c8bcd7cc8de2cf5589f39adcf9c7fa5349b0a78b1f77ffb9406394d237b52a4aaec1e8ce6278bf4263b0592dd5bd9f17b60c446fe8ea35a088bbdc928b61c93274944148b1b1c61ce76d47e7376341a8d467664ad6d6bdb7affd33ae377fce4a49fdce2c6b72640d1cbbe65df94379ce97bfc6449b8c3a2c55ffae967246cb10548d80316cf1c6543bf77feacf453cf9724fca5a36c73a6996f3923812300702a8aacf8d6bbfce421924924618bbb1622c90b793884bd2afa2014f2ea0a5ceb8ab0c4c24f1693b025612789dfb280c51e20e17785421fe254608ec3364a00bf97c51cf616158b5cf82f3f39eec26fcd2c7eabffe5a849da2161fb323f3926bf2c6d3d33478db0e397e2289bc846091d48c22c1c15c2a58c3b1cc21a64ca9126a6807750824f1cfa9a0a18127d30b11732597c45a1708216772209745fc8d4798a2ce6c01c328d7063ea4dc2233c451f8cc209d22cc343269aade883ee4c5f7aa6eff9190b142f9da86ffdab3c92b92fcb1c274e906d484737ee666fb4479cedfefe7b2bcbdbed76bbdd3cfcf276a3231926f13a861110e00015f0ba0811958e1c4d44058a5a07d89d036c2cc33978e2879727ac0b2b4f0ce6494ec1854b8fca4b9e302e3b79e2509e309a1676801326458bfc82254f981463cd0560232cf7145ec615dc562d99a300ced80f2d8bdfcf6cc67e92e489bf1ac00ef868582df6444814b7d893223332c622633532460a892171e3e2b2610301ac4bcdf324bf0cc1b0275c45d0dcd837305bcdb288805a1639c8b2eafa2999be8da6cce27bc994d255a6f4c60323b7200f8cd81e88a35a884c7f356138a6302f53dcbb1de38e214a9d7328ed0414e7bc85e6388ee3427f297ea2fd58bafd6d607f133ffb188a5757c0c7f56734faf8a5a03474075541491637687daa6f660cc5382f962c473681cbe206117826e6e5b879c18b393cc23db1f8188a4fb801bbc74fef5e0edec4a6be01c5bba5e7954598d24c96450d54594400971f59e4207b2c66c48f2c7ebd80def91b8f902464f7f7cd4beb2345dfc05e3bedc403235e1a96c311576577fff6271fc56fb40922d040e468b9b3d75fb7ff8dd66c75f48f3655511c0a848eb9ffdff3da95e34a8ea7bbe6091b024beddb4edcd86f3e452f28cbfd25eb966db9b12c73b24fb978cc71e5a75c7c88ff43122ce6c219175b3c83c3159f30d3d6744d33f411d0620e7b0f50e442848a2d26a1621bce9881764dec1a091573e18cbff99ccefd1c8f9f9a2b39999f1a47014e2c72b2c68d933b877677cfee103ea65d3cf6fcd97b5306ac08366cf2636e4c9e6538654e06ac0de7c7881d56d6c7741dc1cd34344104607622376e9b1fa0b5931bcf2fbf27f3850aa0d8b172a57d8c9f44a65b76fcd9313bee589f9200ab63755e58671fe3af8e725fddafeaa7980bebab923549ad49eacb515c8b3ee0bcb9b6a61fe90fd0854ce6400929e588dffcf8367efcf1c7cff91af385e31f7d8cf54553a03d40b1beeaab26a9647d5572f4b51abb067eea2bde2cb5e8c9d3a2761a34ddefea6f26dded0a1224489020416ce86ec19ba5922dd19e1b3d290a5f396e060ed0fe76390cafd9defe5d782b07e828fc9eec757bed9a3c3b32a424994f4a39d2efaadcedcbb5ada17847b0094ca9542ab59873ce56f70e70661bd062bf3d874f232c4e5224c2a270860b52384314ce504094188d191176410288477814ce00c3113e6126148aa74c6b40d2c89403e60e8542180c852ca6e00567e835a0a53a3e8c003f4d52abb51384dcb1c1d2da6de500d1a58441b1f1ba0d469a134410512b08128b0a0194a52af76d4e8e845a4e9ab080c4598e7b018c74bced9062c9a3914a602077561874736f6f352f5e0b6a5b50ffa8a7cb99ab9cf5a0009a40b3e8352fdd4b6f7c2d6731e860ed537346bcae2537f6ee07f6083083ec82c3177378c2be24c953044206b9cb9d97d6a5745cd75daf7597ab394af497cd51e2b37290d79c38cd698efad07bfcd41865c32222dcd8cb4f39290acbdc648b7e4be237781d82412dda11ecb750c779165390148ec219fc762fe6eed8ee651cfd9603742f7475fb31b73e0fab78b3d4c255aed70cfbbb7d822e0261240a8df0332a260bd7e258a6931fe3f874f220bf7edf4927a7044d09ca4e7eeade0b307833492c2ea24da9057de4ce09333e2382efe2beb2e30fa63a970983861dc6701ab55a19592b99641a7d0ff77d26b7055193d77c8ac9a5f8cce43b7e225d078ac950fcc0e7271a29c569f406285ebfdd9c4f398ee7b7b6f9ad6dabb6f9cd6f8e85ba6dc2207b7664e58c56bbb0297a46269a45df272b67afb069b9739ad59ea977fce4a6102020a3031526192e2af2ad63802e12c167eec778bb8f441264fa61e94205f6087b44a9140170c2b6ec945ab4f599938ed3874a27052d6e3157f19c92424f8d90697da63d023f0b3a8ee8e4d0429a98fac0d1832346446ba5c221ca64199fc2331498301e0a909cd0124cba61043c82279c004ed813537a80b80351cc2806bcd3bcc0069c3a355272a8fc1ec003143f185e53692ab19f2f40373762403937c01579c6805cddf2fa06189427f6926728023780e775535a69778ee7f563e92ef5a4355eb3fec854c787904cb1e391037aa6ec74695a9fd2d4e931a336688d293a352e581719accb2c3bc6007b03e07006427206f8626f8a70e3a2344a938e3a3e5cb05b09450f2d7ff9c3643ee5192b022717512a4d4bc5fa581feb330b60a9582ad6c7facc02cc6e7b84f529b568af34dbebd95ecfffd25e0e211306c594d22a0723cc19150d09637001865981550080d25498569860705e7ea27886ddea1cc0597e221cc21a18618fe3b0c8e43778c6874f98f144a6cf241aad5ccc104f2c0a67cc302916854dfb98db8ce25cdce10f8b66219327327da6fb31a2190aa12cbbcb39f93e001ffdc4d2ac125609ab047da19f7477f73793dc3d0be189a9736ec3ae330f854f684d4f2b698741b175a9db9fc7e46911ad87f6481c1af3c4fd038a57e6d5af7f403a8238b779cb3979ce2a67f5b7bef5adff59d5c3f9caaeeccabc2ba328f89593b7f4130d6c7ccb2bbba5ebcaee772856b29a6ee9279e5b3a4a553aaa4391a2e88f45c02b7bf29657764bd795ddf2f2fceb5b1f23033b8bf6ca268cc96281e2c557e6281e4fdd19677dea9b9f82fa931d575ac7a8d871059a29bb72cbaab75cb3542bd9bdceacccbbad50eb6fc88e1fc9972f6bb5ae8cf5a9902c540bc92c4bc6925956a866572eaf66be70ece5a8c110920248c8963d149a52782dcfc64ffe5114bcd5876578a85639cac93e15aab1f85004c130549365c72e3f79edb2b8211ea0f7f25a7ea22880338b5e2bd4ba81add7316158c99d6a2dbfea185de56b9e87d3f8557b7917fae72b96e1339645b7a9cd17417e6a5bee9a4776ce0268ecd7a4455e2e97cbe572b95c4440c77f73abf23f0ec7ec3f96604ac8604afca8b329eede009cb024c83cc9d82d8b1f2bfbd7ea68d545ad323cb33a25099b29ab41b62496c8499459ac525a64b1d26aad5e4e028e127fcc4dc41455c049d9ae7247fb6bbb59b2e38ba5be3e75b55c2ff575cbc6f595c5ce9f9f1cd75725ed085477b2e329569bd76a958e566175897aa50332a296ebca5162477394d8b1beb163cdb2e35739ca3369882c7ef5657316ebebdabed151e22d3d30e2e596b7b4b5c6f5759d64c7b4855bfed00b706c4d97c97c71db7465e5a7be5bc48cd1d9d0b5aecf4c75483ad62d3bd62d3bd62d3bd62d3bd62d4b23ecddea69fceb6dac58ddcdf378f26b3208620f83a02804810590e26f519b8ef6add0d8d93ada957dab6fbcaf4bcefff1c777f1038a1dad637d6ace74642301da2c76b28e3503c56ffc6866ca937daa6ffcc66fec681d2d7cd57ce1a61ffdf4343f7a543cd9f484789a99fac657fd38fef88d3fce1518c4e2256111fc569f5a1176ac156bd5ad7ef5a3f3f8d7b37ef523c501afec32b9e44b04427b3cdf0d3cf3fdd8264fe695be008f4c79b68ee6dd0b822c58fceb53f9c9bd577edbf3e49eec78ec689eada379365b771b7368f5a3e95b7d630edf981dd77ab200f28c2941e611ee68b7a3ddd18e6377a945d73ada0b515f790550fcf1577ff3389ff32c5a82fb7a1a3fce170e5efc7fbf4de2f738373f1e88103fb1029465a84490d206a973680600000083180000c44038c671188561100944fb14800847a4364a3e241e9ec5e18038100c0542613018588641000000108661b008c2d04a261b95212837e0a64e078b38417745ca029247d7cd2b15cf362a0d1fc186dbf2ba04bc99f425d97efd58cf475b08ddd4116a6f47708bec9783676b3cc8ae10527dd5470a1a9162559e49468f33fce5ad35a290a24acd0ffb1a5438f5274484905d5ae0ea19f3f5473dbd4277906a5e370ff04c7274c9bdf2fab48d74160a13e9a11b23217798eb082445794947cc1ac48b6a42a2ecd433c9052cc32896c2bb448bd7e0a046ae8bc57019306e184062f01d0af17f53ae9eaf12c83ba5bf1f08f51f473ae05b66ed540132177c3f9a71f7e9306efef19e3fdd4bcbad0ae2ef72a7966bba5823312848de0b4b0ea1e3b9e29ea33d93ac7c9a711feb7cb8a15fa83c9fb1902765de1300bbe0b51ace9fa02104dc2c3ec91079a00305660ac0ac4ec1cec9f38a1ec8a108be59e6681fe8b3f7f2d4703992e77ce16c358410c362bca9d907fd9c6642e73d9ec91970ef8d4bd84e8cc3220df76b1b55bcdb6b0a62fafb34c227c608f14cb2d2bcc3f5b2193dbb21ba85aad1432f0e24adab19bb25a74c5f09bc126c0cb77c7a69bc9d49edb096f23bb3b867c11ae7631c72f69de3c421efda48c51d2815f4a7f29aaab4ef38008a21a67e64ad5500fcce0956a94285221d2c73abfa28fd10d90134d7a5d82359be16c292867ca134a787c3aa3ad526e6f2c56bbcea152ad6e294f50e6bc4b33e5d18d4c4681abbd90209790707d0e45634f0da5541cd0073a1fa5a8b1df1958f5c62d5f24cf27cef6cb2f3690b63f4b4a5afb44cc5b898373539086c945c56c0f67535068d610203fbb069e625aba8fc6767c4be161ccf2459c4de33c90515869231cb33a7f998ff85284cd7740848b7b0aaa6c2c6a49e4976cf96e04262c6163b8a50628142d0dcc4f707d0e8b4d20fca8f041fd8a2cf6a865c9212db154de03234efb1a5ec00b26cc158ad35ef01adc1d7b66da4bf8483150120479f67925b77b18583f65cec7db7ff014b8077cde20e8589d9fc2b7d455d9bf1abced9f8f4d733c933059081c97b2639c74b1f71305839916ee7a7db95f2b0abc4e29f150749b1bf76b1bd7dc531ef3e93d460c16884d2f5df9e3394a8918e7f0340e4b963b66792b9c0f2a162a1ef51045019ba220bb53b868012d4b458f0ef53cd75ded2b03900ff91eaeee299642e38aa9c8ff588721b7926f9a290e13fa7d8aa7167c0adce72400d2b434f8e6e40ff8c8423e73c93bc80344eb83bea89f861811f037ac87463ae26c6af8e6e8ecaaa183e939fe17fbbc8be14015499af8a679273bf71b800760a0cd87d8f3543b3157b26f9a1920e784e86b30b161b989acecd49922156f77f1dd86228503ae2ff997e442d1df12fd944d1ad8092e2ec99e461b7e7c574fd2bb58c37a9cb3583d75c68275e2193a33a8d6dc37369311d7b4767ba37f2f8516adf91e65c177405a8ee20115cc0fc4d309d1e96d970d97ad31a95c04d27410fb95ed2228ea2e6ce77e475fc6e9b3b73cac8705177c434fc09b85fd588463921d212dfb1e9e8b26123ce3da3b04b85a23b2f827a74b336e23d932c9579c2aef000a90a0b048cca08acc275aaaa8bc52d8faa06b4aad3255235708e338ab97a26d9bd5294d26cc17867b111521bfd1ee20d02509f032e1fe554fc5f1486094ff25db14b014d764da5c6075acf96da7ad4a4f34cb2c6b4fe2b6de31352f23e83ba6a2de5046af21afd2e5348c7a41034ebcedf525a74ccfe8a3134b34ee31fd1f9418190dbdb1a54956571423afce720bebdba1fa2a50a5db104cf24cffd4b93e398e33cc302053c931c1e4d820cfc491f3a0690a6d4abecbed23e0d3943e7c6c99ca3b06d9db3e95ffec178e5d790619419e17c9518af2355e416c737b35dcd800c104be34c449dd0125b10b562cce159348c0551ba0f0c97e399642b675bb6dd38e2bea32b1fbab5c2d8a16a15cf8019c129ddad594da14eaa1b3cc2ddee4d727bf14cf2820861a8edfac2e6d025dbc319210a88386223da33c9f6e72430173a798e312f4972d0c936a94f7fd617e299e4687b1a2d7cff309c9ecde570a98c8c7ee0a90bebd07e5fa17d7476cc1cd43ac7dc4509441d3b2c90ef74bb71fde3156c4b79a3bc5b7826b9cd72eae69561c2b878fc95c5d4a1c0799ed3e29964da943224aeb3e54ea346a78efd56efe95da22c28b7cd1122439c88212eb00b3799c2f552a29bd133c95052ad0684998faa83c769275ec4f3b4c18d9cded6044c8e376acf24b7eb81965a195689deaea2249315b350939e56ef08b81e0cb99f30396a1c5c29b501bae1ba988ef234d7d0508fd1e499e4bb34a0601f42e9c357e4a506c53d938ce2e886792e146ce3c9438637935e0d8b70a3ba93792659b2c40df30b67de174eaa5ae99964ae0fb908e26977e2838e7e56d046a3b2f252a29f4176290b929c75deb7b860e26f4c55e7a4a2cc61a7208eb30ef61b76c6cfa934cf24e794f7b1f3a4f52e303e85a699df61ee14cf245f731f9fe1f25eab3b461a6f99e4700f6f31f44f3ec3e937804c354261b392416ff3e7a89dc22a4321acce4c3b9eef2710e619e0048a8a7176e4cce2eac9e8afa2c2e121826792a3bed53a80746dbc43a56792c5e8dc9a6be515609091346f6c85895fcf24736887e1d06562358d3381c85d624f11639d878237f912ece02d792659937513453e71cf24f3e52eb8214f88d879ffc58ccdb0562316c97e6c01f6d0a101ba3a8180fce8cdf9ec53638d45b3a4a936cf9e234323685e88f6aa270ce4d79732479169a12181955bb5d1a4a4d609bce74965a59b7648e7f4f2b5eef34c7283862e9d7053a1086e965d628398013c174509127b0a61a42f61045bb7a9d52bb41fe420cfbebea119f036eabb24d3c253d1f2dd1ce3b3efb4ef15674796a491bc5d757e6c56ded64567d781176f97e3059d7f5e3dd5399c6c263d934c27b4fd18d3e72ccc63f9f3db0b519c6e0e2e5dafadd310d7a090771f21a532606772d32424d76f6754325b4781f87e343278e867d516c6149b101ab3e6fbe422f258b8ea99649359b30d48789b6da4b40dac588c9cf8df0e196e8721d32e42446a323e401aebf9970922d7978ad1013edbd9828107cc883eed481fdfcb7dcf997d8f97634c62cdb802f1346149e9ff2924ed44a08e938bcf9824522e7eb0782bf78567921b479e6b3a52e92771bb460b297f816aaf9e49e6767e0677fe682947db5006dc077ae2f35ee06de2b22a2d45d229db8dc059530d2afeddf072fc90018dc1e34e04b2122ee8050a865539a9c58e5bb64428e6ffdb8b0ce574f625bc2991b422f7dec919f780c7877f16b480ae16ce1c63b9d314a49d2d21dbc79a6a744f022f7c4f0478da809a596880f5e996ef9964fdfd23a1bd1f08de73ae8371d1b74ba256ead633c9429670282e6e0961c7232e5dce25c2c2809e0676497a9296396bf4cbcb1868978a69c63751edf4d2eb3b211f23022ad9498c3ed3d8d73bfa511e8754877ef4f31620c833c9fa1087684f0698b4481bce55edfb3083a44f14703dbe3e7926b98ae10d2f41f8fbd15ad0ec26888f907599a60e2d880829481a2627251431a2f58150fbe24a9882175c6653f9e232b991a4afcdfeeb7451c596bab52ed90d25d9c9f5c819098626c597e85e9152180d22f11d9993e2a086f11c5c6c028ec2e902239b8c50725e3300ed56c37924cfbc8616b3b022b450e699e016744a8ecaef800c6345f950d7239f50b80d0e3503d36f2774210891975aa794ef2f70e76cc609c891793d7249bb26cc179a138ca27dc60641729922a9302f88017aff1eb0744202d540e11309a3d0f8eae6be9b9f01571763d7108d310789f61167738cb5159ee5cb99eb53456585e2dba13651a7065081321e1c2720816a8915d39b2ffffffc9c60c746c0e1ec398c145b8ccefe35dcb6a8781757081c60d8a6570dd15a5424e2784206c2a12117ae75fcd02212a87687a2c6379ed68ca74a0f10a896a8976b437fd423b2579f0f623a00562c53289783ace4904b74ce0bda9e45f42e44ad4a7a6bdf2d5b9668b7e05a97ca7ca898f5ec7b73ea4750805b2437657540f27c7eb71324fdc24a87396fc8732c34928ea45a60c1649e94f98e069808a23ad1238601b31aacafe301f4eefde819fa614d09e8e3ad3f7d9f29aba3f9db5e41744d3fa0d322d4ac26a45d8f0241a2fef91f8582810278a1895f96daacb6c57e4e53477317c64112e29c4deaee68ffb3c4c3054f3238ad86618c1e9ca6359495d49ae80cdbc355d668221871f57655081abde6b4c6fe9151039e43ffe7dd905b2e346ef37674899bfdcc51ed3b2ba9d1b79f36b2248069809f6d50a30441f469c6fb66a78a9d9caad37a77b47e853595050b1bf4e93ad320993a4431d631cba2e9ea0e21725722ebbc5922a862a7a308b8de0d6be361aa479f72c1fe474614bad58f18889021e5b6c737b301b33ea27d59bd5e7a09e89d92751e146a2c5935960d069f1d7b0e68a7bda2f8fdd493e89b1fe9bc57ede4aacfc57945df9b1b1470ad94ef0f443d46ce56a87a4edbd0e9c216842c9ddaa1fa66508728215b62084f8aef7da00e112f797737030829cbdf5fb69f109c9084219029d55fde8eb1d1de04550e7b9aecf18aae62145185cb080bb8e6d6061431a40268d326e86320d88fe993bb263ca94cb92e52af2337f8ddb16be640bf1f4979ec8bd2ae3204d72e6203c01bd4292512b5036583fabaacf4d78752f6e906a8514079271a5fe23a0aa94dfbb4de587a1d2c65dafaeb342221c61feda1e0babeeb80022875ef6a9242adeec364540f34e84db0999adbe6a1abd41732b63f551b1e2d6cd7f13b51b1e9b60b419d1218b571929be9e872229bd29ba6a5b8c63b6644f01b45c1b528d976a50ce0b6ee691bffc2a665f88100f14e7dcd6c1405663ad1e44a81d1f07925a1e0babd028c06b82a0088753b54290d9f51705d1ae78015b868166795e6fa42ebe08b8dac14dcf9ff61dda9e22ca1180aae51bb335a165d13c9f106201a6c8f76a62d3f0a62bc1e88765036d67584abb5aca2072567e5580f0d80630bd8bfc8b38881e9e6323b4cbf74a4fffc6e4954583f0582e0000bad3f3fb8a1290fa152563aec826eda8de6a5f4dd8dd007e8040cce04b40fda54ea38966c875ccf3b227571409ddab34b48d07a94915ce42d95a86477719cbac8c01edcdeed1ca980664bf3ae5cb8a693b577a70d57436f246a4ad46579ce8d52f91ffe55e693b40a6702cff97d5b55328ff8375cac4ada9eeb1b94d409abf60264f43f4c868b384708e1dd09259c651b9c8161c72ee5969b75b3fb84519b4627de80c7a64b9583e03d9092db74f176106067e5090e758cb8709d26ffa1494c278770d9d6dc34bd01ea1734878d8f8bb68064ade7284cd37a567a00cd51f0daed0c2e5cf3bb5e86d2d23487cb7a49ce6c1cee1dd4885c55e2feb4512232afeba8a0df96327989340bdf52182418556e93e3e897866a134ca186276aa630460d21d85bde61c933df998e637f2fa0acc7c96b2fd4fc6388d3a62ec35ed11f2bd1c5a03e5c4b8c6b471cdf3744949b204697210a6a0681ad5cec4ccbe5920e1312e93361bf1b88df768c6f191220b1560da28781d587eb82f869d1a4aa8ea4ac674df97d7ba48b89b5be7ed6cf3e5c73d9fd1dc40642b5048ea4b3fcef90989f0bed41874c6536074f420d25a543ffe858cee9ae47384a3abca1218610dab561bca5f4a221fdb321f8458730cbcbdbe9e3a4c6dd6df0d5ba6228bbfa8db967f023c8a90866e16fc47e83291e004a5a888775d338782a9680bdb300053f4ecec7ee87ccae5c53acd7dbab501f1da443bdc6ddd941a27d6dc5c1c09c6b23ed6f8e081a60e06b1027868dcaacf6d26d361878baaedb50825214f0b9b87d6b44fb9a0e9513d5c62946b5e2d116c8cd12d6d5685fc3797408743de862464629e43e80182f82f5b731804c3ed0fcc3de5028adc1eca3fba573604a26d18c8c0f77503d95e3010499f6775f76acc127d76cafad4fceb3b19e565c610a7e2cf0c975a1aa899d80a82b1d4574902c12cf4419807827c0ea9c510785e701deeab7c9e99718bcfae128d4ba828f5d32f817e4083ad5e820be4cf831b3276e04ad967a2caa48bf11418d5d2f94627e3ff0610ff7e1bdb593857d210b9d34de60646a653facdc591ace216d38722f08f49426c0cc3a178cc1ebfda8a2aa94e686f85091bd0eca7ce3ff79d0021e8aeb33c367921114ea2f49344c5ac4aea52e577283ee826e55992e396b1da550fb0e10db2f25f712a64d7303b1df129998e2863c5dc91823c99ae64eaf26a2aad5ecaed158ba41e974183325997f8d46a9b25aeef40cdb657cb95fba056e504b32d9b0f571f705d05746038b69cf9af440ae139d600cec006460214cd4b07b90001412fa59817f04bc43f444b27669117110c28e158f6109cd64c241390eb1dc1177afb30908c63dc08dc2977138e4821b282c22b6597148584c9b8fa265cf07b8a2176af67a35842c1dea00f514e959ccdcecc838d5380c3f0d1333b050afc56c4d5e8cdd3c9b138342d7b098b61f4d610078f258dbbad3270cdcf649107093b7573fff236e5b56d834ef5cf841290a67f440539d7abe1491790609c4380b4bea1efc867d0b0f4e79323d23bc31a4696c39319919fa2f2e451bd353c66ccf342ab92964196b5a355c8ad2928f8246efedd2d4d8f1da7773ab08c7d194bfbc1eae8b862bbafa0036d454e418d9a15d8079712b6872db86aa09cd2b4568a61cbde18ec0925479cfc6192837cdbb89c6353ab4f448b713b1347fd7e476be254ee7ece343191b31b95f20fb5c4dca05e6c7ba9f8f07277b8503d6bff18f5791a4aef0d07b7135a4e32582eeb66cfa63f50f4d5732d2eb90f2b274fa857464434cece105ee7be7d686855c972f4c52e0edc530803341c70654a48f5faecced17d3ed67687b947eff857ba022bd1ffd72f22003c93970cb0f4a381b584f20b81d030754279640455a397cecebb6ee680304833633700b9907374bff1206752ec57c2eb061a2daba0360cf50306f5ac6f4f4088547563a17b6382aeb5c1b8f1d2cb9c00ceb361ec8beb759718074747d5e284e733f751f47b809057bbd9aa0ac9dd90626636184fc2668370b98d46e21d86360592dde27759956e6b305160223a31473dce8d53791c0a6a6d9b6aaf23a8e1a508c9a14672c4c64144b5a8d9326e389a523838a30a176264b35bdb68588a7870b466fa928e3a3118908157feb86445a633aa65294fe4bd2de550213b2f61380f30c8dacc70a0fff14041fc6736dfe8bc06640a3d643ef405bf8e0bdf3bd27b756d019eef6245a4101ad8a975028a858b7c3191f068a9cf0a7975fe7c1a556077a87245e930be32d838e63e3487fafd74b8c7c5152a1016d5be1753d5c0953331049f5668b619c83fd7575430bfafffa3a1725a007b190a01df7b5d2f2d6d5675b988be746a6dcae558f97218d1a336adc925b4acfeefd5d626def3fb9f7a766405b0eaf8f029146b1096f04fa11b9d7a6f3bfd6ba116b87e84e8613471d53b399b727c1b25aa006845150cdc1c0d4c7df9dfcecd1e6c3cb497d664a0b4576b749e55f444f3d883eecc092c0324838b92d907671ab768af9ae3c3f6d1c2c48babc369107fbff6f11241a0bc2a491d93bf3029c9eaadd15507c8c95a3e001472e624af151a963a5292b04b974ed82b6b287362a2e69aa2a3c48f00ca1d0dcfa84f3b220c80a1ce785840efad27513067bfc0793d86b1b54ddc9dd686ab8c16af2b1e335a8fb1bfa9d3cf688c66d19b3c9ea8a59087a249aebd0415f09bb4f9128cbbff6aa0b6fdd1448bc7c2eb75f51eea602fa178d7a7d29ec358d16fa917043379a1e7046dd32446690f3cafd8b2647e523ac5ff45c3ebf55936bff4a87b618995f5cd2f0c748a39bda27aa931801781c44b53e74e51177e89b1fc2521691e4840941c7b8089f9ef02dd54c6c2e9a72c7c8c6704be92636175d7a5f2356a9ddb25eb12dd48889d10347fa988618e16a79469915223cdc82f0e6a2c9ef07731af772e5442ca68031bee8c2ce7e8250772e5a14a43a9a4469b1f461e199e826944f01593e15dd6dbf204ee5acc4a03a3f4e61ac507c318309f271ddf450083e41130923703d3a177d765ffed73ad069f8fb60877a18d5dd481c91b13c8b81be7f28179d0224d338f698a96a5985e2c1eb40a20198d21676e7db40ab9f56474ae8a28be88a3e337816ce2a7e149d8e078546ce46c9e887e6f99389320795231ea117cdc1e9e49018de9a6fe4dcde28e5b7f51a7928e3a2beda81b3b5e4f9bc8525835ef439014eeb12375fc6416e7bceb08e3e6ae7fb3f47dfb77f6cf68c43f68b6256cc9086a886ecdbea48cb01bddc7aba01363efc751c1982086084b008f7a3d125beecf1084a5f5d347b62a1cdd32a36d696e65f7e2aaaecab375ec729abaa25f73edfb45a5d348b22bcd018d150066198975c4f7e4ed6f350f0eab3900f26c3070d9e5ecf10ee1d9f9276f57a3816b37430f8ab1c7802fa2ecba7c221b9e8966b07b5bef152c9136d56cb49fb7615bad0bc53ad06f212dee30a7554abc9181a3dd1dfda8e86c34473ee9f041ee88d2654f31ec3e0310ce84c35050cc244624424987a6f57ab46b746325ef0aad51b8d8283f6cfd2310fc66cfbf782aaf7879b21f1d02109627194489ca49900cd44fe29bff1dfd7732ef1b705ecbb8adcf0045b44ed80e228a4d08c7e1b3a35a93f4428465345cb3fc9629a5e5a8868ff862086ffd259e22fd9d7fb0bf97f07135eac38e8451272a40ca2b3c4bd21021e32024603e41103d669199bbb12a8379101284a2ac9d938a9fddf0754e899f5129d0ff6b468d8e33897246ff3c1d60504f9b790bca00ac8702ba8a1dfba7859826c0697e5c2d99ce957400a6fa9c8c2132b204caafa1453d619be166c639a82b2d9238de21633bb48efba42ec4e89b052c4cc9d12ed214ef6f51dffec7c40853bb60ddf79a1ddf7fddc7a3b1f951a7410441fb1d7f7382bcf2c2562426fb6011dc00e6cfb10d93791aceaf892262301a874722e02dd01ba08887c4cf675fbde0cfdac28dfe197554a1ba2671526914cbbf9ba302d11cd25e5e4b2f42babe8472e36cceea345fcf4aa4c3825431d4f97b52050862b73a5fd91410e64d132e8724737a6fc5988a3e584ff6b2647dc06acbf31bb709c18dad0117618859bfac649de502c87e90cee5a60bbc119ce4d18082d1428a8dde87dfd8b0b1d558e149682022ea15f78e2a371b3c453ddd2fadf0242b6447c2d89aa4861d85c0b0f113e47d0fa97aa702d774ac20d947f2b6ce66269ea37b5787f1f945a3a8c168dff1d12ee0a135d05b0551b4452b7258a96d8f126f22b66a051af6953cf8c1c2cd54ce1270cd9ef94376864b4458322c35997035de0bae8a9f4d08cad7f2174026eaf594015a04e8cd7553f264481368c6984c68a963bbc17b7d3ea997789882c55d5464d64c195770940f3c0ccae1dd4f40b12fb51f3eabc8fcfb93e2cd256e8a73e9dd5e40820c17f30f53925a4a79142aae6a110126891ee8db557d429fa49c06dde883b64bf5a4a28565557bdf06b1bff69f9d104c6c3d5e24750ccdc8913b56585b005c4b2a3f6fcb4876d137cde9d9e5cd7d10a5ee6ef44e310d52f34a84cc5c4cd573b22b9ba3d970e06cf727ebf7c5ec8584b32d370607019b85d9037c5218e60d4fb2df0c95bb63b504a0f80ce40d76ed3fbdc5997750cb4f560d6b16b95b9668420836d808d09ea650c6531a33da52ce16d98288b55019586c7b39bcefdd39ff9185b3700ff8f3269ba0502202809f0c7366003fcf880ade0d549c003802ad51ae314e6cf2c0a65adf10c44d39d8d07c6e268c2b3aac0c9cc5c4db2ee54a362617e5dd1444e9c5e5564ab4c378b9968be9f400ab656b930afef4e59ccee89b61f521160b1cccac69dfc295553652568c1306f3940ec21a9acfc498ef1701a0578e5a474f43d0ecdde174cb55581eb4520cb3955b8fad0e8f50cddd1a1377b5aaa614539727d8b3bbaeb26add5e142eaaa1fba8601f4e01d5c2f539b17594eba00908f253af39e6ac0a93531dcac6001348382699cd6f88359436ccb8388a868d7c3397bc7aa1cd21c2ad24670a943f60cc95d0e52ab2a09816ccdc6aed88a0b00811690dcc16c76e9bf677efdfd40d507d12b1fbfdd6c34fc2c96e425fa0994f41ba596fa6b9c4060bb18b95cf30471baf3396b98f43574444eb543710b7c216690ade0ab347207f35551694c37d0ffe0042a108862b503b78bf63f4b07243c6bdaf19b25a03e800c8559b685c467be21ea68f95222f31470ac800ff52cae7976a5a128bb66fa7fd5975b126a9fc2665ffaff2da3e4dbe618eaa4744e2821d678ea0e2352c569c00f0bbab2e8a5e3b15fee0d43a37d64fa858ec672dfbef39197242d0255fc5691060628aa1220128fe5e0cf7b2950482dab0354b19148260ba0a85a804847968371cce3e83fe6a97410d43f8846acb2f745a761bd726a05645a902f0052444946682895406b3d9b6f0ab672ea893db4a14f4aab84d74443000e520dddb34b580421ee15684abd7207ed88141bc6bccaad9844510f4bf5b4f74828226a3091fecebba3880065a6aac02120f7feca8dd34005aed117e83b68c2d78c83b488c7cebdd68383515a70b20d1a280506e98f5929e4458027fc3e3ab41949acdcea05570d06a685cedc86f43684eddcfdfe9b3bfde7b63d9c4366a001944fec8665450903dad0c6c45b35f8d6a134732a3559ef60253554a090e530aa3346628d8915051a82a62cdc0ff5db08de3657acb40b0e07dcd67d63b208777c0aff6647dbd5ff1fdf5862dd3c539bb5516e6f018e95d7f9da4a06203ab9bcb5a9ba1bc2d4a6a52f6bffd516d5b8b6f3f77664a7aa0cd2d08f0e7a2f8449ed344573cb32ed9bf7a7be4b7eb7351ad45a388059f0fd8ce2f97e891858efecd346cede87a30e08c6eadbd55a589d69b076be36dc65d3fe60b3f120ed46d333565daec25fbe36b8b3def84354ed53a4488059c9ce85a2a07389a08935ab2ba31f5a3df944e7f1b56e1089deb1e0919b4347f5c542a2f7fb085ced68bd886b1e931d6e36648a36f96bbd59dba7562752ac8e61007d91e06455739c0079e7811a503d9c51b403789dd0ed74eaa05ada6c2e4e14f6457aa8b48a90cdda45ab32ac82f6f1116bec3f0b1a6930ad42c262a309330e1d5b825817d3f25a048c7a5757e0a67a245957ce3e23c8c3bf924c3446e4092592dacc1c539fe6baa5f874d4b348b667bcdb95a0992973943b4afc4500ee60622f8b6e9d4ebc09270bcd76f9d8b422ed8d4e2d11712d98bc1560501771a106b44f8e65a3ffd32062b0ce3d0f0c0502ed76bf23447a91d0322d4e5166d8e1089eef1f8e8ede96df38c79b1c82b4178f3b033abe5302d70ccfe5a2e2163bbbc41705e8e507317f85dfd302ee796f50cf3b990ab5faa30cfd6f2a5a9705e0f72592cb178a0d52f86f9a821e2201d6b27a6c0ba0a19283ff1bf8d70918d273d7a39ee9b913f9533065f77e8a1320442395b578dd70a181c46f3cdfcfebce4ba9c9761164c81521e8d025fc08aff1db529244e3a7788f6dba983c9cf32eaa099895c530094a9bd770c44f64942f11ae2b4f9fdcc50234b955a3841e625d4791464596aeda5a9af1a6c5c8f32d6c2f6b04ec25c9ab780d8d193263711a067f03b64d1debd07ee9b33c974ec856a62d77b918982937147129307c6463297ed516cfc8d889e45b10fa92764e118e47d2d58e9dd52b5c142dc97f13d9dd0e96917d52c10f4acc1b8f06b8dce29fee6fd4e8ac524047587cecdecbfe6e86a9275439434cd3c887b4f3db91e40ca624828d2cfc8f522ce1ba2105e32b44d20e22a506d33ed5a377088faddc3fcdeefebac8ec6b7c188b0d36a3e1dace6f2fe5d34dd68a7d515ddf5dd32edc7c29c6de0ceefb4905280e44206a8aa812c2fa9746fd6e4350354ef82729da496d091a9585ff07532a53bd4ac40a15f5998ecd17c2871feb32a81830a3e1040a6b3ce106791964254c607c65bf6049c9242fbcbf148c45f0c3ac26098926f33d6fbae6bf3cf5096d911b502ec3f1c6548f5c6132b5c99e1dd522670538e5ef9e525d06deaf134812397d0b0af55df403ff710848caf2904049ddec9b6f0a7e360c2b68b7445f8fa1031e7c3a6347a21e6e7b206a975a8bbbbcb0fafc48fc24f1d18ef29a6d600fe0ea40b94d49e4c4f3c3009637ca9e09b15bd32b8db60946cc2f70e8b30c7e3a1cdc910768cbe1439d527ff016414b208310d5715f5b5c4ed42737a5496a2675a38a2d3820107cc33f04fb7c894705b1211cfb029f8ebf6600fb64d05386489d69b96698f6c334c922a00bb09446126c991fa4a3f90d10a922147ac55d2923824c581a71f6347a0ab4a09b7c76948500e54451067328597da461f04a21597b40686223e180a981ddd02d7473f3104cfa4eeabe25e1331b3f978a6735834e34c212ef4744da023f8fae9961be3995852a83127bbc42a85e7b44b090e3a546daa9434035131e417131c8538950c3e14899010acd2422a09808804cd5d0ccabb0d0078a50f21095e502d7a032ecba7ba337043a49024a180250aef1907bc942919630f7301a00a08fc2991c40927859fc83fa68e2f66d89b8259a28fef81dca4f3ff0a5f339d54414d8fc42519cf90a114e995a471bd521d49e8d7517ed02382754fe64583c4a83697ea948f5bf0fca06a65e802a3d181e8c6b80b9ff88b72f54c2fc4592409618fd6fe965f8a3346f7e03c7d5c969f1d1cbe4ef783883ba89e3ffd061560f5bb3cbe562b05d3e6bde3fd6c0a848fe029155b87a170e723100277e42b4a48c43f45b72928fed0556493f57849ca625667b74d53a5fe8906f5ae73fa43885742a0cefac426b0bf9c3506e162b25388da584b3e6277d1714930cc71a49c421ab4893fc3a484b5e948fc2cd3aca2dd33db6f58f163b2f409c94a2b8776ebdd68ae1a1754358529b67fa45c798195b4e1e76e5475d61ddc813a38005aa1d6ae0b8f072b0f34c7eefa7f5cd29e4fa1df6fdd9afa8bd47d67dd3e44c5f86b07dd486ee6fdff9beb1c2eed77ab33fd993b4ffc1be7fb81ce9cb09b68fdad2eded98ec332ce8fddadeec673b82fe7edbf70f1303fd1ca0eaa73ee9f636cafb4c6bf47a1db7fb929dacbfb76dfbd3d4405fded07e628b687f8374bfe18ddeafd3665fb62b6aefa3b56f9a8ee4651bb24f6c10fded9dee372db0fb77d8f767bfa2fe1e59f74d93337d3942f7515bb2bd7de77dd302b95e8bcf2da0e73567efcf06f8f80ef5efdb166dfb72a7fdb511c27d0e94fd8f27f8be4ecc7dd9203fbe8bfebe6dd2f627ed74bf3640f9c7b7baffb5029edf81dd9f1db2c33be4ddb74df6fd4998edab0d68fff8adef3f2be87dad19fb93216ef8d76e1958e43fcfb07f5bb4edcb23dfaf0628f7b856f7bf56d0f31bb0f66787fcf82ef9f66dd3bd3d19937d9501ed1ebfd5fdc702785f6fd6fe64801bfe816fff76d9b72753b2af3244bbc7a1beefb1c0cfeb9bd94f86b8f19df6ec5f26baf665bf6aaba8afbd60bf6d309b4f0eb5ff5841efebcdda9f0c70c3bfe0ddbf5df7edc994f755c668f738d4f73d56f07d6db3f793016e7ca7fdfdcb44d3be0ce9feca11ed1f47dabed71a7c5f47665f32648777b6777f996afa933bd95f1b20dce741ed7fbdc1e7b53b69b6e7dfbefefe3431919737743fb541bd7dff161883b467adc4f3171df767bba2fe9edbf70f1393bc8c42f7510fbaffbdd37ec30abb7f87ddfee457d6de27ebbe6972262f47681fb1a5fbdb77b66f5860d7ebbddd9fed49daff60ef1fae67f2323966ead3af3e70bf3170953776badfb0c0aedf61df9ffccbda7b64df374c8ff46508df476ce8feb69df70d0be47abdb7fb931d49ff0f6cfba7eb91be9ca07dc436d9de86e93ec38adeafefcd7eb62368efb7b57f9a1ac8cf00b29ff824fbdb7b86c15dfff0f27dc302b95fef6d7fb62768ff837dff74399397116c1fb54db6b763de675ad0ebb5bdddcf7624fdbdb6ed9f2626fa7380ef27df747f1b25fb0c6bfc7a1df7fb929da8bfbf6dfbd364222f6fc87e6283e87f8364bfe989deafd39ebe6c5fd4df43dbbe693a93976f789fd8a2dadb3adf6f5821f76fb0df9ffccafa7b64ef1b2647f27284ee2336747fdbcef64d2be47ebdb7fdc99ea0fd07d6fdc3f5485f4e907dd426d9de8e699f6945afd7f6663fd911f4f7dbba7f9a98e8cf01de4f7d92fd2d3ed3e0ae7f7cf9be69815daff7767fb62369ff83b57fb81ec9cb08ba8fd826fbdb31d9675ad0ebf5bded677b82f65e5bf60f1303fd3940f7539f747f3be57da6257abf86db7dd94ed6dfdfd6fd696a202f6f783fb541b4bf41badff4c4efd7e2320bf8fef618fbd90033bcdbfefd6ba26b5f82747fed8c768f236ddf6b09bfaf236b5f36e4c3bbdbb3bf4c74edc99deeaf0c10fef3a0ed7f3ce1e735b1f66583fcf02e7af62d93be3d69e7fb9501ca3dbed5fec70a7a7f03c6fee4901fdef5db86abfccf33ec6f135d7b72a7fd9511ca7f1eb4fd8f27fcbc4ecc7dd9303fbc8bfebe65dab727ed7cbf3242f8c7b5beffb180dedf80dd9f1cb2c3bbe4ddb74cf6fd4998edab8d48fff8adf61f2be079ad99fb932166fc173cfbb7cbb63d99d2beda18e91e87cabec702beafef0b375bfe8cf6f70f93237db943fba92dd2de4ef37da603bf7eebddfe6c4fd0fe077bff7439929711741fb549f7b761b6cfb4e0f7eb7bbf9ff624fdbdb6ec1fa626f27380ef273ec9fe76caf69956fc7a1d37fb929da8bfb72dfbd3c4405fdef0fdc406d17f8774bfe9895faff1e556f0fdfdb1f6b321667cb77dfb9789ae7d09d9feda11ed1e4fcabec7127e5e43f6be64c00fef6e2f7f95eafa933ac95f15a0dce741cdff76c2cfebc4e44b85f9f15df4e55b257d7bf24ef3eb22947b7cebfc4f15f4fc06ecfca9313bbe43fe7cab64df9f84395f5540bac7f38f26947fbcaaf99f4af879dd99f953013ebc4bfd7c3bc10180cd6447022aaff9545d5096d5380711682f9c6870929f4f6b10043d23cdec9cff2ac5f7d196157a0ab527ea11ea6e485b50269f54f1512fa8b755c8b373dc1ac418020cc3d0e126ef4f98f526ae064b3f72a0e9e8df76c2288647247a895e5a5ad2a49429a51443054c051605de8857afcf9f4167e942eddd3bf475a1b33856db1b552ffc5c53417d75c86fa8fca1f24b13903ae4ecf3e5f3e5afafdb76709a00aa6de37a43876c788a2a937cd2c52d66de95bbac2347a660d530c591116cfb6171c5130c4ccad42d407d3e1f11e55740491fa2c8a2f4c1228b2b8a261e5ac3db686d3ef91a68900d3254c054de42ce6b5b37c00c44277845972db2c8365805f4942e7b54feae8b825257be0026ddacb3b1eb2cbdee3987dbddddd08a0c8ce38f2d4bf6eed5120d948130904b197c89a8fc1c1104f3db9f2919b3251144cc4012b17192083983cacfa98a716876e24495312b4eceae94d2a318d7211b5ece2d1351226a5fcaccb5deb8c73ef9b2ba0a73524a8949393fe9edec1650fda9f01ba194640d4451144551144511258aa238806f65ae60054b4f0f5d4f4e527dfca66f47dd2648a30f4d9092d02240c2498890951b083285eb1b6141a030c40e2cc51096e2c500df8e2c966abe492b0cc3701cc7915bad96a7e5f13aec43c69c640a623adc611ec7b164a43e6449c79c3e30e829e624c69c3a14e2984ea76b1013e3e3b4259e0c66c49fcb3f7588b9946a13533d07f45787ac8e70cd5cd9cb59ba85bf524963e889faa0628bbab1459dc7a2e799033d1c78e2c02338f075530a254cd879eeb4b5a4e46b74a7a4f33588c33650ca7cf9cd37f17060f8c2c17cfc9bcc4629b32ccbb2cce6e36cf571766494b5fc1b65ae6cbee6f8b18dc979402cb6ca6454f51f619edf9dc1797f5e1af4e4eb9fa80ef10c1c907f1e904b96ea18f8395026a443ccddd25d4a97d2a57497f329fd096a3e751d07b4ccddcd9f0794096915fe0e84830774207ddd7b6783f3b2115bf186e4632be92e3f6cd5226c8519691166a443fca7164ddfb06eecfb31efa403271f66a4abd80a5b390bf7d22aa0b3646188c9cf240b3bc43f5f2d1ad19879d3a2f720abc2ef04f6c4c72f85879c8db2876cd440289f0ec96a82c96ae2b948126d0ee4c090478cd8a21d6b5e2318be1107722067e2c0136afcf85f4918d0c375824195461e29205441ac84600dd1aa71017949a149441a6cd128eb21eba184850c71e11bf1c9080cdf884f49d8866f561cc5affcca066e613666a72cfcf831222d1a612f4c0a638d1ba3aaf4714c348682f3f5f14f202d1a4dd51c6b3c2c8f870156dd1693bfc155985251b7658fb46c8ba7a3a1bb61e2a5784ccb13d5036a96abf4101d2304c98514448f3d822f60ed6c1c8130f1bc89277c1e251ea596d3c4f31fb9641a824d291cc3d9181323dd1bb3d133aa6a1fe0854a4a279d52babb0c411366895de4e7766e2758aed4edd0bab05afb125ca0432d7da3ff96c79743dd205400bfbda20a27a82fbe0d72c5110b5ca0c71ddbe3d036ee312f87e7b5dfc13d6733275fabf2590af9b2f3327bec08b58a26348829b12c37544ca87aa0a984e0abd38ac579ed69a8f5b5fa3ab8d7f635ed372fc7c96b9f63e3fcb6b48b64ada81785d5bedc5e71bf793a7ee0d0bc947dcc45fb134f87e6a550007b0ff69e141cd94bf99b07b42d1bf7dac6f9ed3d38b4e7b6e7bc0eed39ce6faf837bed370eb43bb8c7c179397e70bc1c9caf3b6a9c5627935f9405ea7b9e86936fe1e9a8eff9169e8e93df16b9f280565c45fe0948ae7cd54bb981c22a14173760fc0b186eaf5e9c5ca5c4449e6c2cbc38c918467939dcc02b573e3ef9bddd5b0ac8f32f401506e84705b6c505e55dfcc6309868110f219f5746e404b1395a15f8e2f906570a08e55f805c3cc3587920e5060a8a8bdf2ea5bd1b1e4f959c4f3ebf38bf22c955dd78e1b9b8b47816ef72f2269e47791c9e47f172fcd8cfc1bde7d7c351df859783e3a5ec737e5bea73a094f55228a069db733c1d9ddf3abfbd8eee35ce292934703a3acfd54053d44463e6a943477aa2a6e9430d7b01dc73879999d9493a484ea2a6b08e9c9a7ad5bf5a86bdea6bd56c35a95d80d8e0a46fbd065ddf88431e2125123a101df6b6877445551e8ea88a81ec5047cce188c3afb9c8d7ef3f50ed3c8a085b04a233755f1f0e1207f98d3a0c7950471c7e214cb33c832d4ae17f914d7048de1018d0e38665e45b999a954c4d102eeab69d03f863408fd7c65c2771b56865ae307dfb75b8c7ab4529dfbab05c041f37323e6c5a36516f609981824b101b22b4e6853fbbcbb486a5c0e323c0b741a2602385541029f8a0331409f3b6e4b8b21112e4092f8a84ce2c20850af28418294cb486d6d0193ac37466e5682306b10121a03df6bb000ef28412ada135bb1fc984dcc104d6a1d0252492d4f980010cb833b0f5af0b23767ddce2da483e1cf8c324aaee8f306e7decea800d28b23f0814008a1e4540e1845fff46dad0724ab4fd3e0c2bd27e5fc6cab022eef76fd458964ec97e0dcbe2f91d2d6b86f4cf3a8f536c05b7f8058e375bcef2b270c9ef26d9e520bfd0bb1cbee1d39e7706c65252d279f96d1a779c9be193a5c35222922c55c4ef0476b18b69b8ca25715087a43ae42aa6318f70d53c75688a3d81f414325353d539607ef344bf0e68a25c658e36e6c6918c4dd4143bd4405aa5e71128a7296426e100ffa4374f35e894b0cb073438e520a7bce421a74adfc855f324813808d219b061309feb6cf8731d2e03655f863a9d4e19c775fe5d3743731d0cfb3a9981385fcb0a1bd273950b2a7358c2753aff120fb78125259d7f35a1a4eae16ae7efe966e80c249994c3cb53b9ce06f6b59ba133907f1e938d45047f625f20b27223eeea18fa3b206755ca4cf8fa4d301011b57a3c2e909370ab53e201dd78c0a646fc62e17fc242e7b9ce56f20e3a4b8b697092928e1275e5465aa5998627f1235f3f875d4e84fe1357dda0c57cae729b843a72d58d2973709238a8ece152fd23295a91ff7e5dd1a2f08af8081bea5f93ce86d7f92c389e742227279d0db66176b56017db744025cfaf0ebfd8c54b6017db743a5fe2391176d9bc3a5d27811d9ffcae8bc042d1038a1e275c6dc1291ec22a07a7a7ea50bf5ca2f6100735affaa37436dc41cc1ddbf0ab43edb1ab864bd07e9c1ad2a2d9c9ef745a74180b2e3a9d0ea857453e4a0701eca320fea67495c3d0e173f9d564caee8c1af0cddf56768b0e876b0418a146a047e0204c16adc817f0e7f361b18140b1282e8ac5e52758cc1f51dc921d3a345780791261171c6b0f327ecebf716096b54edf8b6f83b4c66febcf27cba6e7a3cb646117ce57f7c3bc221bb3562693599159b13326d368a6d19e8ffc82153b637a2eb331b6fdf972962c9459e82d1fbd8acec78eebb64eeb7a9220cbb22556a4f990b5b2f6c230cc5a616b6c8dadd1b57063cc57d6a2240ad29096a8a90b3b5417764bacc8abe05a3e7661177618c6d5eab55a1b83034b9c898b71965db15aaedd627c47cbb6a0468ec5a1b8140a255b50475de8a38f9ef29657b1a2f97295af9c35a9e0492815948a1b9b8fbf1671e007722ff3356f9c05592bfcfc33182cc44aafc9997014d09ec5d3b0bd89a7c3e4b767e1e9f881c3e4b7d7c162036dcb04c40204ce57f7404ff3454d34c7ba0ab6f5673c6c0c7f8fd77960467215ff120f9b1ceae3581c8a3bc27c71280ec5a1381487c292a873b5ad36d6d6da926caecd667b71248904b8120970997b992f3a720e2a17726087c0718bd94e31427ac8a6da50638b561e5137ef474a0e393ae45df8fabc0b5faf8db4815bb89536532aa55ab15a2eadd485532b69262d463b6928d7c69dc1d55f0bb396e6c38a281059385f98010ce0af2cccc2f7778fca15542ee44e3b83b9120772607fed65e0c688a272ce20ea31aa433d3aab255667edb6489494dcce62312ad4ca918263eb705d0a0eed39ad453aabc36939425f65acfc036aacd47063d4c0e6a5e0d8befb4ecb3a9ca665d967db6f9a9742c3f6da6b9e8eeeb7df16e9a564bf5f07fcc22e260587c625cd6370f35c9e4062dea852677ddd286746a17a01daf733101e5bc43f76648875a788288aa2f8a1260fbd24a7a8230f3df4528b648b7c77b6bc51d7113df9a85fdf34895fb4d52c56b746b55da3daafef154ed6903aa2e14761a8e9f331e2c5226aa9e01a9e3d05394f1fccccfc1244b38c670d668f9d3d260dd83d6675d8c4099fcf87a70fe6a533dbc2b6b0f2f3f9481a5e49236998791a318d6049b3b388a548e80c9dd91628123a4367b685058116ebd00aa05b927473377777773f377b4c836d63666666fe701119235e783f9f0f8ba89535cccccc2c697857d2489a9534cccccccccccc9266258da4616696349246d2ec3233334b23ccd208cc2ca56066666669a48368829999999999999999514e50399d510e1fcbae096acff751d7c0581bc1b69fecf361666659236958d2489a9534cccccccccc2c6956d2481a666649236924cd2e4b23cc2c8dc0cccba228530411716511294507219b60a633aee6223f5ccc3bd45195517c18896442ee60022b89905048229208bf7babc2396f2437467737e495f3abde203777ff8e9cbf79a674cf15af17d3e8905fe8f7807c888b4cc39368ce27417eea90d82a405a454887dc4f3e1d359fa04f4b76672cfb895735e4d591168be52717fde4a3a3384b299b702cfe012da225bf28ce527f5bfceecb701693df0e875cf1e217bfa4bb8dbb4e3eba0ae52916f3449f85f4ec463d69f19888f2ccaac6ee2e8bc55af184f83dcd61a0ec141383794c384fc76fc262651cec3399cc37274deaf0d561871d9e7013c43755d22937da61d131c87fc262d58f83f1b760b560816bd1f1b3c062b1d082e3aa7d8b16d8735835749c566a1ea78ec1d48243f95128ca8bce06ff8b178b2585d02a681ff685fed710fc0a028cce498737fc3484ba7ef2974f549e9c163ee3924e5e61d2858b2e358c8b0e51f8a6499436e9f5ba99de30add2bfedf682db6e4e94cec67cd9618bd74d934a9c7e09c7a1bc608d4bf0c84258ced26158e9c3e8f0a64324eaf18b5f2858d7d990b5be8091f26918007436a4d7a1ffa8c300501de69f743638bfb140e9d768efd00c6514217fe0a476d2cc3c314fd12a6e711276f54babdabf59ced279ff6e95bcbfd728681756c2b7cf365cc5c7a89de16ee256b9e7a68da1aa6e9a30136429043ae32637b9c94d6e72939bdce4a6f932c309ca204cb055adf2c13c3561db0f0ca6459629a5946e1cd068c7b7c33d4a37eaa556f9e82409042f79c94b23946ec921ed5a2735143da07092f441c8fc812179903f58e983147ef9fa08aa0916b83621ccd2894ed5fe0e02092e24b47c7c23aa3a320435c22ddddd250f1d86330fbdd4210fffa4bac83fa92caa0bb3847cbbf249214a2112626410754455a5165db16c0b152e1c25428d7cfd34ec41c50104f5a34200b12ff48f987484f58d3c0c7264e53c348dd6d01a5a436bb6ddde9a7d8da62794c6740c54455594085db160c182aea8114a84050b5a436b680dade17c09fbedfb6988bdfcfe1ace815c7abc620832ec90f6ddcdc0afb1e7255a6a91e675a943a62aa96aa9ca593c5caae25055c809435e4fc6a052ac561455a7e46b57a94a054271158e7bcecb11fa2a63e51f5063a5861ba30676b474bc141c9d1c18f81d2daa141a3a1d255e0eaed22934703a3ade0daed2183f7b2310f4770387157e9d57c27901a2288aa2288aa2288aa2288aa2288aa2288aa2288aa2288aa2288a224a4489a246b74399100ec8e74be5ef74e79cdca646338efb4b774ccce16bfe810993b73b47d21de40c22c446a99f807226058de0b2515066082c0852ea127c6ae022a36a99e32ac8319c249b976b35c25cba9818b2fada867bc8ab0ff330e992d2c627c966dbcfa75b20b228ae28a2b8880c132133f374992ecc5c056619a44b5002c23e095a6e13340f2a0eadb40c6affeea0c4bfc2830e589c242c0304941f2859d04e9749a48dbc992e5fff94537429a44332f5add72c834b29a59c357eb5654f460df76ac880fa7a9ca9799a2fd393e3b28c6fb71de528c75dd3cee821e6ced0bcf31867a9df7244f180a581581a9207bfd01f02f91a14250c5a0839f29463f6991c77462643c6c6e8d18a34b90a0fa62181f00bfdb59a481f101e262099348da8284d344602f9fa6bc994534a25389dce83b2c5a5fb12602dbc07c03a3dd2e1cbbe3930ecf8b2ef1dc87c581008ac0c83302ccbb2ec370b8d56647cd98f6468de6e0cec6bf40a0c1da23e3a74a231f20634464a6f65a543323ed1c8515f8fe4f80991c941296b132b6cfb6151fed0aaed7712c6457040244cd2a1e656cb9bda8f791864db8fc8cc224a44a1963f9fe5e5223238003f9f0f8c8dc4cc1c13a7c431899c12c7c4e1214d1c13c7c429899c12c7546a112fa7e49281196985ce24e0002b3260d0549a8aa5b13496b3ac682c16eb6b0ef556b493a65a7f62a5e9ae5c8e7b8bd5a1231d4ad2219bd7c6e8aad292d072a031a19d984616020d896c049a10b41e642f998b56f24a2b302bce62fa6ce692bd645296b256e672165992285bbdb4c229b568244b234ee9e3b1b284f8f5c32083a94b18f6fd130466d94b2369a1ca5f55864a963e170a52126d692c4e4996b296c62a7dfd1a4b3bb29190480cc5056c92fca18e50be5f09318a97dea689f04fabf4a8d6136f256cfe2c9324a9fb39e63f591848c1d2d72f14449dbe7efa42611c94527636e4ca5958a083a083a083a08320e81e96811998bd98802871846512666c87fa81c1226a3bdd47468912ef11cc577c3eac43895987171d407e71df88ce017e8679f58bce88a2e861bfd64376d237d2417292870e3aa95f9f1f35ab5dd0a50e1b642a4ce1e3ef7ed4a4921ff12bc937ea576bba4c70bac896bc69c91bd9922d79d328dea86ecd03bfb80ab6e9d74641821e42e0611424e8816443bf46cc2b73831b776166660e9da8fdea1b69b31f1b00597e421291444218cc062e5f3f7772fa1a4b9d50a2c7881e8aec558c5da54a4d40945c45a5c14df50a0b41109b2b7acac0af55cee22dbd7216ce538cc56ab54c2693e96586139c2e37713ccce52a4318c694a228192dea2f220ea12a3f55171dc5cc8f72948b4ed4151e6dea92b7dcb54a6196f41ca5e2ac4753d4093a52949f288a8e34e5a315ea2b245771d55188aa3e32228f6569035e1645146a99559b448be50f3e3044d4721199244e9fcf0706cb24bcccdc4214c5a533cb36ccccbcbc43b86366dea4284d20c1fd642387983f3c7e3445c70e5121221d69aa431bc8858e1d436a8a3aa2e3f45ca0bf1e4db5c89f8e3435ba47531d0ab5a4e3f8283445537414e988d1d4cac6e81f5bc42cdc6244cdc2f1c7e9e308e5cb4aab6518d6a25108122366c32fd7c6d876867f56d2e8886574c4303a621c3ad2d1797020dc05eec314d5c73ccd181afa6944c7ddbc2c1cf969b4e3e33fb5c8c56ccc9aab82881251a2287fc820e1228b9045c824b0c81f9f86f9ec2e454267281266e6fd70ed9e690d9da1334c675622a135b4665752b1a8cfca1f5c44257fc824c0b072471dc81c515ace97e05b6488b2e1cecccc1c9768a8e4cc551aad7334030034146317000020100c8603921c08a2384ea9f80114800d638a465a4a2c9107237138201003218a8218088218888118068210428a31c86e0d84681784eae56222ed8683bcbe364c5d01905e0a4ec58e658d0f6906aa228b70783d83e0b24a334a82c0049195a2a866d6eeb84283733e8dfc659e9317eceaeb5a7829cd3baa9313d3893b95325a86de51bea59a6c65167ccd8330bd6b48af9c7212bb9bcc708e388b4bd8bc03c41d8dc2d81491e087d11b0fe62221d1ad14ed03bbce3c2553678ff49f5a4189c8c2756dc3dab58d6bdf6e50fb4d63edb6a44188b134554df27f421322a0da456f41259734e3f607b8396abdf2600b33886d3f0b75c968e73e46708a60cc1235f1af95f5be207d19a4d9913748e33a39fa8ce3652e314261fea889ef0e5ba5116ec90a43e23c65862b52f4a6276a01be7a5666089b422e4d36974a63d06fb1743404ffcc40bc9b82dbdfc2db1db387a3c0842ed558ff0e989410a785bc04aa94898324bc2f4aedb60045e03de908a0adca22dea4c9dbf4d42e9fefb319bc61f40360957d795b8b9f3a0a63d38002c320a09af8ad4a55b58094a4d027af36efe6e6f776397a2b70185e30188ba1be3e8c22f2914d0523fc234d6565f96b6f229cf2ec0a8f913bc075c27202ba3ebe6f8ad18daf91dfd220c74b0933cd1c56a370f33959547185a2728c989a7e11a18acddf58684f1c4be1682bb5d5b089cc033b69e54123f62caedcc8752c2325d2e745913120d83e32ef6eb45157aa7a36bbe3f0a1f65545007601184fde5341fa9947dc815c59ba5c257a65e482d66959861c70ab284c0b02d08ec33068318f8ffb6fce9a0eb2e4b2e3047c9a6d1d5f9bbc2283c157901846ed886d99224f7163e473b39b8c32e9e6416ef2e6a188e42918c96c289beed73c36b90f1ceae195de8c18526e5c043a15fb86e8c48c558a3a8d8406e7cfbc4fde4f0dc48c48011a6eeba4716878e669afd32ed8a4345b0e6d85c8b2017400e29ddd0432361f68b8d0a8abefc29240070567d9e610d1de003f01e87a67931cca525306b4d13c96fa434eecd8e4d93e60a9ed8901fbe25e0a03a25e52db4b031aae8a2dcc8f415c29e252aba1de3f78090c62ec770ce38736021aee36f785fcc9e90386d86fb4feacd6da0cf4e81191d683ced2b223175ca3eddaa7311aae88260d0990740c51be16cfa7cb0c97c063e0900a377340fc03d85cc99f15a7737958edb5bf92afbce5f34a909e410c1d9c73f3dda223701c66cc705b98e2770b86f7a659a9b0cee84a78d4d2ed5c7e6bee39a028a13cd1ed1fb826bc4299d80f4c856cca11ebfc6ae977c74ab788cd0c97cbc94cc954f7281a564b87bc60be21cc2604ffc71c3a21a40f59e1e216be7a33335ca22898e15653dbca5279dc0c17994e75c559536fe4237fdb366665ccd28155c5bdb4adc97bb8b4e82c0d37aedd79e5b2e11a84b30f4f2943f5698ac81490e472b72444aab3740deed70cbe67fc2f7cf7991f9759355c05a32e16bec6cd595d034d1b993d296eb347d6e93b9b4c7a94d970497aae9a3c0655355c37c8f8425ca0284c0fa30d77459dd9455e0297947580160d4d39ebf01776b01e751cf18a471bae6500c97c9d9e2324d5a56a14a4519a69ba8a6996e5725ddb40d7905a485500af66b83c0c104bf418cc55128e5dc3f89edba106453ba0809e4fcb25ed00bed6ede363ed4b98d5e4b424f91c6327d12b8eb5287c0e42bd1750110a7423d60b14d9312016787f29e01e25c2b400ce675efb237b7c98657a088700965f10a1b312cf0e65105f8b1d8ab6b005792daef7301b351810cfa251a138d0de8bcb36f68d43a5c1bc590b2d0d834fc1d1c2e20a3a3b3782d5bd831793e14a5f708d7ac6df8718e771f814bc1b8a84d6c3c9c5cba760515711b37eab9a88772a8743459c14a313d6541ae148ccee1f9b7eafda13e7e574ba435e743e056722e20e7edf20217953cdce7fe95261d7f727764c05e723536197dd9333b9e785c8d6cf1c3e0517f4342a1f4d503dfa301ab77fbc7a5b92e218054c1328a3dd992e3fc4e56aaf3b7196ac4dc7beeb0f005d3e066845e448f12286832c82ff40258a79e5481fce61001a020979b5757cf32998485a6050ab20a463c876c0763aed2d77be3de448e3ed72941bc5e5d9251ba9635e681ba183c46672adfe72d967454550714bb4583c08a27f4fc11054f7aa817f57953417d0e76b4c05bf9b7e905cd69bc5a671506483a8b292e5a0988ea30b40ef18000929bc3bd7022b697f8b35fa9a08416047b930d9ee856bfe01d914c15ccce33b1e8b6f726f63a1d163edc36b0b0aeaf565c1c265d9e7498fbf2a0c0622fc349bd91a96b7cb9659969a4dae83cbfe5fcd663aba2cefd0ab6fd0607c6e01dfe6eef1eaeacb4a53b2073ebd30f4b54ddb93ed154d315fe9444b384d096e1d53b1972f3eb38f8315b4b156bcf93ba9fa9e82a973ec58c977575c53be80ad78bc1240c553705c758c500afe16556121588196b92a969be3910dd8c372c06ec3537057dbcd05d4f976b6fe7b0ade29b31ecaf94ef39e825de6d54900d5d9c668c4b1c4bde1c250dd00063e02d44aa8dfbe5039e16e70b77c500d109c25279cb5b63308e19869828d7e0aa62f833d59b15a87b63ab247a886b0031b81d4a5c282631499619adf8a7c5b8dd0bc03e63bbe3e05a14b3310f394034a071684f968de9db11108f18bbf00128d7d78d78dd7ee447081e95488b5e0619edbf8beb0ed80e514e18eaa4fedf857c98ae357900c7f5f191a2beee2862eccecd57cef0866f9908714051349cdaf0bf44a7697f9f6fc0954f07c65d0079929601c6e482aa44005230c19daeb4c770084c794133c5f175d747007342fda8238f3fa7ab22c7bb2eb51b582e9feb8b9bbb6bdb6a50c811e4303161be00bcc02052af833694609cc21abf321e8e9e59104657f4c8718eed02957d9fc39ae4a7668509d29c2daf553333850ab035441059f5e78ba37b4d8bd934f5250c1f4c156f1ee2c640d1e803f9788d4296c70039a598f57d1f3a9dcbf04154cf2a8f3b8397c6571aebbd4562b04fa9e2c3ff32c9b962aa860e1d7e253a1416d658d58f8da779b8b8556ce362c9de9c9f1bc18ff61ffec9c2e8f1ae783fff525a8e025037254232e301ba1f239f0cf66a2820a460a22f09472c50cd75d23dfde0dd890ce5ec094ae056721399a7ef998134e3ad47969811298395fc7a7951bc33c2ba8e02c691fcb76a03fb6cc31f15942f8cf233515eeb57f9f5f880782eaece53d2b67f68e4c32867af4790e7eeceb5903214024a1e73f5f6124a8e096467fbd2d029354bed6f6047e5e7fc227f83694ee9c44f49dda6ea84b857b8b3ef5b44048ce606f752ba86076bfe82e296e6767248c6928ba9f45265045ee3af049ecfba76a1afc9144663d0e86b614c07ac27065efdb2d971e50645fe405b82e16b74d82082ad8b69b606b8c1f3c949cec524faba17e9cd1afcfc74ebc777e72d24f06a96c4a6845158309627e69d2358ae536d904c8bb83aedc04b80b9e4450c1d409edab71597b641ec645625e0ffaaec0c8c4cb18099d122af1943f084db321b67e682bdafb955592d9b3ee71b8a18c34d34936a892532c0770b9bf96665250b88ad70732864f8c5bed45abb7a082e9c23c9241a34589066f22c88c1ff2e48dfcd8d85fc97543b06096b0208daf5ea8e1e8623e3162f542b2315b736fd3902036aab51e9ed5b14d3228f315087d159b829151984c466e21184a6f761b1f2fb4dbd4f840060c37e264a6fe276639343033d1be5b8adc31fa17d22f17a988e01b53f408a8fcf0e9b1894dc1b6b020ee6b6bc7a10791c1723605eb3544e4f177c43fba3592de9ca39d223cca004973e0126253704906e9a64f3cd31b516762bf6ee8dee7565239c856c50c0ec1da38d68e8d4dc1450d9c14f7cd1d9b73d28597cfc57b82a3e4c93224f0a5210c704b8a58ced2cd0834578a42dc64ad480e9500a6904dc1b3a01d601d096d2b8b69615aeab16cb8e9b3a27154b3f1f8a27e865846afb1a9462c42e627ab979d86090370a473485f9fe30cca7b08fa4ba346c80cdc27c609743e5723df659c97c6a1836e9ae86839691daef92acdd26807716621c66bc31d646cfa11f6e5ade9f2dc13094928c5600122ae0bd667b0198d31c973a7e636bff5d1c3bfb8736b6741d0157bc5171eae8339a5344a1e09e8935b2e0d81909c707cfdc762fe5b283ff84a1011c5cad18b66bbd96dbd139fa10e204d22eaee0b7f6dc74b8aaf01c18a3eed98cb52901e8c46d6e587286ea2da9f2a3d32c0561cb121ee29027a2c1c3d7dbd6bcee95bd76253b0eb833e84efcaf8b2aaae2d9b8243403f33af9c6c0a76d197c77496e02b7f8003f1603a08709a32617a9e2d009b29291f06c33309ad45229def017a94c8a6e09237508f943f0a744ab6de467099dc555c938d647c8e5a543a301ece3ac8a7cd76435ab2cd03e61003a43d9b820b5d86798eb05a77a89a3c984796e668b888d914ac0e754f4749761aa3661f5a13267575056fe6e499636a64a56df6e02c68915bc62b1db9c8c9a84bb77fa54b54094597f0853374f4d563dbac2391483c1368a755358d8bdd16eb705b66c28c3cc7e754f962a2d9083958c32367c2271147117ebd8eff9bbbc0e45350cc00f6d84abc20bc885ccda7661c3dfa8ef05442ee421bb206c91bc6a660af8b16773d0d8299d16734f33136058be7b13d5b65828512db2240fc955a0b048b8bd63ee5859694fdf75082989a8fa57430604158686b4b910f0af9a436e3c741b685e4c500b10c642670d6cdf4c0a764f2fba8d7f3ce0525d9830e3186e9f7783cd53d281fc909eac6e6732f527e2f3d5818885f419405690ccd392dfd259a3a4b6bad87403f4a82df9a2600c4dc2905fe4637fdfa0f53a02573c2be545dee15502ec2512456cd8066a367daa221c1dee6695d64980d8dbb86b474ecee59ab7ddb80c216d70f638baafd4c43838b3b0787fb76c696ed3f10f43473c102829962b7641c9b12b2ae53a51695c941b5fccc2e8507c5d589f8f2e1c92a61930a8bf6b4a5cc4056dd1a3b3a19d58986b9926a40437708a75e41ec1043e34574d3d416a7b44d605454496f0a874df3479ec6d7f19b8221bc45373e5c1d7b1c3d9181abab2bbabe078584c51f218964702b5a5d41af142fd40de61594c0e7f5337ca583086fc115237176aa97ea1c84b4514b07a692b293e13347afe6e47aa70e4e11f7a826e9f0dbacb6b96ee434e0b5cbb9da1682b0c90864f317717ebeceafd0f32fe0791b304aeef13b46f3db4c2eb80ddd8f1b2a16b6ab3802286f5958dc26a0b2871fc2f8c3a0851a3aa2c09354b6b8c3973f31d56d6e6e82ba40152147395274896692a336feb19b8d8f0e3e35b5cdb07f35fc3ea4c2f4b482db25cdb8e53ac08419c08195b95cdfb7d251034d8b45d40791f12af55b5267c1e41653d7c535690e94c168200631321284a5a66b0b6e40cab7337773642452703bb12f82c56de1fc6d68b97fa20ac95aa1ccd37b484133d8ee2fa4730326d13fceb5854c3f24a67806897fef6f1b9630cb0a3cc12983f9c9f81e63433120a47fd84e589793645ed0edb0f9efb726f2d900080f68b38801aa2187d41c711f2a255374b5d7281eb639e9615a94093d22d50ab8892ddde2047f2f153dc45d3bd0707d5643a9368196af2ef3bad313922acb7c1acd4a47103e4c2d8ae300aae52d6f43a58d8ad2c122f8748f6e4a880117dcbdb1bf8c8ec96442b00958f1bada8153545757c76c76bc19399d372ba030b008b640642ee2d10394ea81aff6aa47eeb400bc994a79a7a582453000e0134f2b71d349725aef16fafaab67d6760433b29ef100c82466b1884afa38e4dbe54fb5fe9d9f59c92d7f3a112d57a133348e426cf5dbaae87c0bcfb42258040f41fcf45ab6cdf08926a16459780ce185d6aa038f6a21ae759ce5d0232c82c311e6890b3fc5d7828359e7bf758f14ccf33e1e05537145f63a471703d8acc53cdb362ba528ab84517ffe57b0b5ad953c54c4791f6fd2b15e4114180c2434e748f02351bef378bd97431ceb17565460424f8d7a66628355b8791f9b223faaa37d1b2d60a2edb839cbc28363dd394dae46c47ca96dc42c533a0b56979f20aea21305772e06be7b122913ffb5f3dbac687ecf11a2ec8ef1c9d33313150d578fec8943b65fa4ef15607b19cb2872a9092b597fbe06d3dc63262d44cf247f9bd001fdfdb68e8af2e44b50c44adfdd3e0d988bb1abe657e27e501de0e38db8972752503ba7c930b551455b483e5d8792c33af481bf2f11d819d355f9ce01b28c37b2a46d9ff2c62585d24f36f3c3f019f431915b5551658d382ef075f24a46e58d8d6d6d4eee4aa8ce0087be16564d1cb3c30ff229a5fc000e5f344161cf582152644eb4b19c88b9187bb470adeb947df2fbc5f10d4e38ac08d3eddc19829d612409f9e895bc7c939d47cf69f25d37f68ab1a508b467a41be8db7ddebc32707735315518c8a30ac77928e67d61b213a20ca4b7d27d31044725f964eb7e5f9984d29bd5f0229907c1c7bba6b9da13d32bdd02b1381ce2f059eca87001d05dcce0367b9446f252ba8bf3aad2e1926106d5951dfc1d79f96d435e0785388317c469fa449503947850e943f48a73889296e22fc6bb4c4fef52d37177a1179219c7c31d93c5e07b017f72686af434e4ede25df877d95918a511b4a51c0b71b6fd8449ba4b73434b600ec36f77a7c253580f915d4f81bbbaa418eeb3dfeb52c04d0e6b66e7d5c2a24e85f66c37b3c3d975bff929c5819f99cbfc016b8d7819d5db196174005d1d9abc5873d3fe496b5ce1b1a843b438cb0c6558dfb06cc2105f447111c1f5ea694a773fc8478d4e95e77d61ba4b107a87e70b74cec5e1399ebd574b5dbf5d2ed680a3bb9392f400d5eafc4e43296f0beda0701dbfd25ab07e57ebf7e7934417c42027fe72bc657a2ca3d48db89f58036e6eadd8ad39e278d0b40d893c3b6effe8e7df8c6ab6740461a65650e41c579c5f3e0029690fd3fa46adf9fedc88f6c5e18a9d2178ee112ba7660bc8b9110cd2dd9ce30a9135f19460595ecff91be40b18242b7c2ba89863003348022747728e0bc950a41ba8f4dd289eb284ed2f4bf624e7b852decc89639b5f0e243cd121f63860d2d96f6ebfe766a59b48f757d3ebd1d4a8cfc82f5ff0bf0aff654a6476d55e6f7a51c7f72a86fcff04b00aef6eb8a7595d7ff36bd37c5c866c4130a45a5c09bd6b53cb5296c20dc8000c41a4117a0f1b0b557ae6f611390d9d170f24fe53a468f0367c8e6c6c30ed713d78e8de47104d7871b0cda24bcafd675f8426865a8cb5bfc9de7b5220584baf53e705282f736bd2200c2cf213ac17117d8f8ebf45ce99fb5a7a43229173b009861b7951ea30e2d08caddc807ad1cc8749f5cf0b2b00d1e93af80523438ff448f1f292fba096c4f2c53616c8e6b05928a9179ec1d347937cd1521fcee32cd0ea0545f2c5bca722797e53a329a5338781629c62176a77e1e53500e50d69dc2b80ae373cf9e2e7fbe2f8255fe4667ffbe03761b49efb69da8b96171c0487df6e2f8aead8f73238dfbb581cd930d38629e7494f80026605e964e97d8544d96f215b50abf5532c79e6a2d4a74118a792a5179d7195694bf4fe7909fdec96c8d2db1ccd702c35daf87b1592867b6fb05890433a130424e3da99605b3765243bb16dab075e091d8d1b151b8dcda16ce776947f58af7c58ccdc5cc8807c2e3cbff92543eedb9eb6dc853b26b896ded212403fe43b7d747c860cbccf3b5515df3d566f6ef66e3b27b6c2848e0e3bd7748193887420194a912dd0f11c2580a039357df24e9a213b3bd5ae4e965b4befd4cc41d93ef7e4dd94630ce9ff73df8e8479097bc743bd9ee2321fab82060e9b41e00b7e87652504532b091677a375dc266a7958e4110826e1bd475b025fd1c55ac82511609c6210cb22a1031ed908814334ee8a6f17c2e24b7f90a90969c713f3f986e2bfe1849d2357097c75392ee01091ba3662411f1f591bf9e1347e7f874a97c01752bcf494255a60f38d25bc2c5502144e31e2e5e5e76b4be02b7fc44c5d69c2b760eb7d2cf6eb4c5175017bab04be36900555127fa4a9acdaa017a1e95902df65b2b07bdd4c38121cd8c9d224b82a02b22ac45e6fa09c153e8a49097ca909218e0cb93379ed7f2e848012668f885c7349bf949708ecb9ea077d30f464263fc69ed7ae0025f01d0faa1aa1ec5c6154d6b20b9a56d0ed0fbc04be52162b2a0a982aa3ba37841c0095ef0a95823c50605e9dc86426568b0cf511e99c41ebac08d1c1292e7bd133f20183afac20b204be52604a428db820b5c7f6cd21fe05357a9e8113af9f6b09e9e11a4be0ab3be6ee26f8dbd9a246a47df2b1de28ceaddc287f203658cece21d75c407b0320a96dc3348b6ba87de7df8eb552301957c845b2d24af6a126c3215ec366cf771c007b3c62b09ba7304094b66bdd788c313985bf6b620fa61747e749d8c7d724bbd324431449636b50e9dd870199f909b967e7faa864eca27f0fe43500be24b49e755d485ca1c3cbdd7556ee0ac7f19835e747ffaf43b38813554277ff51f8d7635a25197113fc51bc56ba175c4a16faccc6a66deee6b044cf6d574601f0252cc392c58aab9782f24e8c377ee1cb66677bd16aee495553bf00f8122baa083f1ff5cc0f1c29cb05a4416525d6bc0c0d1300dfcd79144cae6382ad8236b2e48d6c423c2b0f4c07cc6d1395a33000be111d8e4e5113a2caea96ca5f60cf8a5df51fbb7c16bc2f9beb806f124083788acd2cbc8508a9ffae63bd6954fdd85719f8e4573b02df882e3601d3205efc6867020c9a206c5fef3daab21b7265fb4e209a60850cf806bebea531bf99ecea4965dc94de92dbaa0eccf6a89a21572be782f47740547b6cb9d8784f99015fa073790b121ff0195b66c01758b6c46960d112feae34c348e22854cc369dac249b3efb587e4d4c9eb47e2cd7932c45d49f243fb18d2c01db9f4f1dd86c21ad681ada1b4057058e1b02c7ace2ad9ba244a07891c41a41d1a2ef8f4b13077cf7a6b28fd47d6900ad92580e0ec6792cf154e3806f44fffda78069ad498925712eaa4d2c830a9fe22cfcc8b1abe760c3d8d3374ad415f54c8b1195090d3b426188e7d3d25a85e084fad1abd372c0d76cdbc73281dfb7b4afa93a3e2bf36dc8b747f39a5c9b1ba92887ad460541487ae552bb59e585292f0c08a07c2bfebecc7a7afdc970c017cdc6ed17f3dfe2b4d92456f67e316dcc5228025b7fcf7356c9a95a870563212306687f3185df9bdfbce56cc1ddeca409154820f070cade042256f05e62d1245150a5130485188624bb0dff3af17caf3fdcc78f402909df816edec918969585df3b5884c28c18aa00590023fb3a8d7a88db7647d893c0d74f4310cde0382350a271d1967dc51938707173c625b804ba932f791e84f690dc01d4d5c2ef6d293d6d9927af129a38c72e13ba6e5d800f14ccac63bf5bbd9788c0791414b4a0ea9d624e5ee4b2e041e990aab5d76eb1b15deb3f59f453aa7db98733113d99f44a359d761e3d0ea3cfb469772990b6f10c7eef9cc637816ec35e96793ac9145e27d95b3417f98b5360102ad5ef001857354b2ef44a7fa6807e23358327df1783da5a483ee91534c8dbeb5ab914612a543da6adb3878687ac3129e423dc98fa06bf170b90bda2e7a28c4e9e728a53d8e9fa5c7a5a887bbfaba8668e37ca9b6bf42e86116e4b8376ace0df2a4dcb1129ba13df160dac670dbd1c7c2515f87321f21a59496b5af17cabe9544a42272ee3c94edacd50fc759ec4010256dcc6d4952715aa94e40fb2f76b33b646bc5560118db484a665f1dc3f49ee9e3d12e69e1daf63129ab8baf3f608d85bc7b9d50d476012d86edb38f252f4b9e1ca6223365ed1341e58f10cdf7b7e2521f43e5550aa5b5c1faae7e41612175acaabe1abb144df1be1d8024ec74614c323236ad420f3d2e92e32dda5328950ef247e839394a15e746c64ccd0151129cb5269581a1c318583e8bef5b1bda7418c2230144aabcf25d177dcbb0fd24ed54c64c73e0a032343ad7db14a0c81df5b144795af76d119015ec69fef15716f90bb23b274993b917912928047a13bb0e9b9a213ab871e19b344c4f94b3d344be21798370a6c78cdbd0c5b45f9f7f01571aff3431c2bc765ad23311d88b8970e7205d5c54937dd3a6fd2ddc4cd20ffeac3491fab0f20f21671af6bce4551b48ffa3324162dd1fa2112b1379f78b15df92a679d7d0c53058246530a23b18044601b6a778767f58b2e255efc0188808f024b139ff49bbd0b8fce39e869436833c42cefc427130327492a24c9ec643f7c562defebe01eee8d9c7469ae0e5c51aef8088675c2993429b26b6006ef9506cbd8e28ec2d57f38eb62e8d48fab9ff022a6626e7ff7052ab4a67b26635c096a3c8c5201e66952f8cb1109512b75792aba6fb1390257b8377cb2ec1af068cceb662bf9ff74a3be5fc079ad1f9ae99b5ce8bd975c09f4f0ed92fc05f62e140779153293e7853c63bc267452484f7bcff59a92841f3a29ed4b4f7b29431afb259b1e5643e623ae84f10d8679f9a06c59b03f8d3d8ef13f5b069400693f1e30f63aac3b7634e1ac827a49ee67081ed629316e539fb59ac258c5b57778d2f5a0b752a6694804d1748fc0d8eb1a4273aab777aa5417c04e0c238f9c0be4fee79705746bcf806eb4e3ca509e35b56d01cc4d8e853245a11cd144760e9ce1e19236892d187b6b2ab6d71518463982a1334aac1a620a2009ae3130b728da3a4de1c39355668b2a3bdfb3bd180930f6c2b47d5d0533342fd2f07411586e65b06bdfd7b102ec15387883b117427beabb905c90942b7ce8adcf7c023ea499fbe75d3fea19ff2cafdf0a7c9af4502f4caaa04fc2c07f9ed243bf577bf90134e8275fc61e1d9617967cf55f947e39d5b96ec85f965b0d5754bcf226fdb63454c4fe0c2da0b7d7a4df82dba824a3992d11a55c04fe82d3152726ce0287e826ca28e8eb5c9c45ec02e7ccfaa8a2db21c7e5a1be725c6433f983146337d03b7214838c240c821ffd7233b574842e93cbd5869f352180b6a3721569e6c247fdf13a38947e4d292b614022b7bcadff62b0368181395ec9f06ab06f6a645a590cbff79ff1bbb345bff0f78f50df4dc7ab4342a8615b9632d5c81c42b23cdd0c70f763d13160496b0c53d285152981a24356fe316c97120f421dce98d715c62dda9f8eb8e48e566ecc35980c33f12500e616410a05001ce1e652029cf1cd7801ade93edd57b0415f7781d1824529701fbe4a493fad13be3eab0db0c0f8c152eb5c375cae83b9e581f742aa3112ea0a133c4f607f498c0272c2ec457baa336cf319d8d6b1de917aaccad3e593e4158ebbbcac75ed7212e8b8af0df0f8a26f05dd2d0c1b39f52bfe53aecf49041e6797423487023359085fcb273a4295afd779ae51d700cf65e56b082087120abcfd1e9060425c036cfdfcd489237250d957d7003b5575ab39a66f5b53ab4ab36b80d530aae353fd5f330ce85db77a586484a54702cbce76589e8bcef0f763a54bec476cf35eade0797cf7d9186ee9173b550216e433f42a79efe9cad9e5c6d15d2e69b0fccf28df3355d481a54f084cf1ea06773f10dcfdd5ab2605cce8e9d45a0f705b6ce8b7dab860ed79267ff4c43ea579e34aee05ad7efa09992022e3899d195780a71302c8373d7cb08cab7cba83b9c77a80237e7f0fef1672b0da4c4e40040ceb4f1a18c9e6a2a65662833caa691647661a505266995c3960841536591524e77e6e159a68bbe31715bb703bcce797924121a0289fbb4ad463ec22cb1bce978fbc57ac73243bd71acaf07cc1a1312e3320fd244897fab02eef0974541c0f0a9028ceff9818e5df4782a7d9f490519ab12ce4a18aa3359a048cfa6af621227661727486a2f9e3c2284b9cc498721f8b6705057a113ee08009f2ea81550e88894d3fe633cc78bc62e0e346501c9f7e6dde76054fb451ac5574bb86f6c52edc36ef83980a55f7f8b2f36504cfd71b6f9b97be7197b9075b6a3f67139ad7f6626a8649a54fe62494f1c2ee95198a1802101553dc98844221bac7fbc97dcfbca424bfd885a3eb9696ca08024b97b4c5ee1d6482f924bb8e232f8595ec6e9558bdb2c8a1a27a860f3b89eaef6d8dac742076e1ab8c797105c8b22609a0ec60bf584b147e21b10bdb34c2ddcf47e460b991da347447afbcabad4ac3eae952bef3adc5cd075c49cb95212c926be17f565dc86125a7e9aaf05e1a35921597d0cb87a8f52b8d7540883f5a9b56ecdabd7bae9e467127dc2f1280856c17a7e239258208e8abdaacd346d910292ba1d9f557de287db8ecf9dcac43d39cfb5bacb86eae7419565479c198cfaa97e4d51e4373589b02bc7d2e3c9d7b40a9b4a9714d866a4df5b9f0294b9ac00bf5135950a558dcf08ac16b9717c942f69d6271070c5d264073c9c7a218a6b6fa5c78a63905f47d83509a2c0351bb4c7b91fbfa9113f91be638888eb16b4d6a2f50f272e47361a13f2c654613c4a89c028e59cadb35c4e0568d31e6909a9e6c08200b4b3a7705acd7b1a8b550154f4ae4c21a06c16a41463b01ff638aa9488e565f5ea2d51c362316026ca40d41d094c87c0f8340eb72a15c00d16bf3a5a4c4d5479d880196662a2805c5465e767b940ffb939cabde8275f3296102d13898c6e7c2387f284c15e11b8c4eb23cd0a1801281a8b4822031037609aac1113e9b1095b80e08555b6eb8a27a3e61141e2f61d2d1f6f23c11efe13ba56bb474b2eef90e4d666e9431fb884cd8e19f81eec28a0663122f96de80f01febcf545186acc2e778bf8386a529cd934630fbc1ed35a5055c5b7531c520e3c3ce2f876cda4d9c7c0c562fd190938f591147e7d4fc551de05c99d732b1e3c138e0a2effe1c495e73076d0dec0699a6dcd27e567111d7802541cf2bf5552de82e0a97b939d6c6e8e9d3fadff4409e27dbc15b3c2b2b97714b74ff5873ade3ce0534cfc58a768a1772bdf6de394c1f33a4f854c5fa1033d4b005390ff5632a44042ce62dce45f19837f599b4554b233657e94be9bcf7756a55aefdafedeaa2585ea172e38cee7e83b4130610a863f773fa4de9dfe9ea1f5e99ed2d105cedb52f8f5f9bde7003ddb12009a92bfa7059b40dabfe49eb14303f2463f03ddb80b67a940b02f1abc5fa38815a17c5143a8f17b5174ca419172275e3d8675f96551ead5afc0f295d143f2979eab43ecbf2552ec288fc0420ee057155a621fd33530d497dd2f820196f696579792a34afcd86bcf66a4f8767412b36ee980e1d8ed4248adaba7a1bbbd48830603313ef77fbf3b1d5167dc24327a63433bdaa8ed9a375ebbbf233f9fab58225a3f1f1032762578cac600a55f553da917e6a9b4e5faeabfa79fde255b86f891b9a10a03b02b4e3156ea78edf66582e84258ed488b1ea6a8c93a25e41fcf805489b40dc98ba3aae8209c4e9edc50bcff20a8201a134541c24c2a9bc428b1f56d75743cb966fc3bf438a9c07a46e496c9aad0c4e860dc742ca85259f8ed745317a02fbfec4eec09376913a9ec9eab780fb258577aeffe7841efd3f4afc4939ab6ea647d2575101a65acea574514cfc108802e8dc534f542882125d14ab2c7f748fb218ab14709ff2cf929f8f5cd6828fbcf726f512abc1651e7e2e4f9bd4364e1fd89209d0863a3b0b89b3add79dec0714d21ca9c0da196dc6a3f874eb86e6f56962e7c91f5fb5c148cfd33de03ee29c986b284eceade5658d9fe2e183b315e2453096c7a3b838d6c774d200d49025c25b3bcfb6fb9bc7be61668ae251ac01c978797e016bb7593bc0807e33ce960eca81d06c70f0bcf49542d77b2e86e351bc140216ac6d883ef830368bf7ad1f31c5c6e773f4a2d4462f1ec58b9dff58bc8cbbc2a6797fdb431f877e9a8b76a773e08452ffee709a8a6b09c06000ef0bdcad685c7b46b3d13fd17644bd08ed5648a41a1b5968abf773a7491e8ecdf11bb421f7d5357676168fbde07e09ab0373dce6cb9b47710bf175f2c6e22d521000cd4a9fa2793d8373ceb6003437354dba14b349dd279bb6f3284649882fa5c38ce63662bc3bc54be77ff4302c7f4211091d9efbad47a0d3ab9b4731f4ee3171a2d7b2426cae536a8fdd3e10085b2391a551c34820761cf9689547a12849c7800ffe001ba1696b274452acce21bb8feb7f1b4dcd39d7f4de8b2e2cbe3024b9ee643fe8becf149a556371df716c121daf3c728cc06c743c6f8b56ebbaff79457ae7511c69b11f03dea684885912b47b94e182efa5d8cc012ce86ac8c8ef028c463383951b0f8e5d55cd961639c4e35b5839653d646546e19d4835e7de658b0121ad6e580f57dc0903684483a7122a7f419a6d4c8336f3284e6cd7623550a1ea65d558a441fae2d67333bbaed6723d2d3f192acc2101c5758525a3288674312020420438d0b92390989fe131f84fce7d2b39c854643e8e04b97f70484d5d2eab2357fcd27e1a13058e40b080361b5e672bd6524a9247ac5488b31e7665dea7ff7d799f798582a9b8b5d95a17292e294f771c5a1f44c251cbf389e0ce8731a0082047d4521d4a2e296719664a03fdff8295cb5248e740bb81832d731e55412f399829af21a41baf9b1c02225daf4bca4b1a5a928cb227723ab0e63d6d2870948563133fdde9c12e5a02929672fa92b2454e8d9ba438f08a0a43e76a88e56d9698b9cc5e49d665b93aa0e7654042b3f48b0efff1eb3b9013863fecc123019fbc75c78f112eb29a11c30ba0e541e294defd467ec5cbdec74c5acfabe774a03da73b34966305ca20345ec834266e4c9ecb508012fd385bd06a7fb36dcded85b94b4d7d5d57b9b139d241d9af8ccbba23623757b1636f6455cdd6749599f7e9ddb9d0dcb03856c3132b13114695291b6265da5cf9ac5b20f80546f6f693a3c867478a8eb1f4162f4673b4a642b5f007b215c7be0c51f6257566023ef9e461d77ec51c547b39a52282314f52a4ce5c03789277c80a46d69b114401622cba390135217c3aac52153dd82401837d72f41a341b7c2f8220865b3da1992622f39829af59018b120eba2e58a5839d6165103e4b01e064d38a4127e904867228057a48b972773f99f56f275dc13aa84ba18c744e2e2495b6eacfd268b0937f15afae25101f55a3a66ed78f9932daa4f2494b104cc1c62e083e35c6643b6be8fc0263b1059b94f29ef84096dba6bc09a71365d8a3db0849d6c911c926604fb31a08e13b9a6422602a2643ca66c20b596b5ffc0667ec3ad2b012ab74d88e8abcc655979f00e66848138755c9e5ca35456f2cb9b6388974911ef6ee1e6c350bf90f4bb906223dcc246a08dd11d34b51b9e8a48c6f415665046ba9504655dba02f91259f3e310d055c1c0634cf7e422037cca4ff85fe6b0556f59a96125003def288e134fa3bce25b1820f552590235b2ded7f69f14149dd5cd735f1a4356ad327ebd103bbf392f55e6507410ee1c073b38b2a9a703c26ed36f133d806943f23d51a4d47863229039cc71780932b4b23f322c028eec2ac0566489c67d32e99c8c5b6854dc7d3fe59724b72c0626c4c0fbe52f3330a1231f93e350899fcf995a42f135d73d0882c64f6c117ca75b06b1bfbd4e698d5012f55a988214bf0b9dcd2b66b8e800713ab1551dc3fef2e5d095a051fca5ee8222eebf0a6410b31a639ad60955917a8c9fbdc85cbefe2a296b4badc0c2949dec73f25f7e1f2da811d3ee857e13bb6b25d83f850debec74e79a15fe16a5e04cc26e14b5c2955eaedc4bcbfa415f65ba8f0e4d22bab8233304d98a2d0e25d4e60071f4e11de7ee08479ffa24880d113a2ac0f1640669af5f06de257dd477cabad1439d8544a3c2e0544399f9a68c68e7e0f0c0f82acfdbebaa568dd01519ea86bb067f60ea9660b36af5b7558627930ac4bc30a38c08a307ef54cff5e3edb2974fed3bf3e83127258eabece3a074479c57b4ac82d360e3a2bea0536a8392b3aeeba624a78d564521cbe2d0abe252012d1f0aaae5301d686b18497e24820ca6568c16076c99339cdadbd04109fdf344070c575cb0ae5f06ad612d2dcdf89c2c74b1bc5e414d304a2bcb91d623ae713a2608b464f82a04cf760f09e31c083068103e0e1efa51ff6e1f854a9b14cfcb13acb01b0fbafe7dbb6a32e465b8a4e1dace947671764fbfbe489f8e7d883692e90813b2f5d2e2cb3c3e32c5d371894281505864033d0c87116085069baae4a57d1496ca5835fd9d519c984f8bc84e9f779a894d9a633c68fa9aecc01f784860eec5f9a8c965bca34dcfe65517168d52238729295aca3d00c8cd9df86550b899b9f6003873945d72cd1f14822cf29fec2c579930c37331179c4e3d60f2077b2edb8e45575d699a7c3e55a2096f39f5fc1b381a186c9f0ae36233e23b1fcc2f3048222d0f4e12f753097340edcf5a500f7f84556a079274ee7434b5beff141ad2be0f5f27649f2a0d59b79a0abc54c6ec45215ee84260a87ab2326d23c6108724a4af644e9a6b6b98f226e0b74e2b23a20de1c0db8d3aa4dd6b807dc435f54e088b18b65d02c6a5a4395ee4b6d5351cd6409371756acd8833239bd72499b42e55b00098ab50563ab2508fef71d49e58cc80624ebb236397bd357d76d000df2dda7a949f8fb8046597f012c5ee383e63d9025cd6193c927e644828694f0a78d8f4bc6002162575b0904718f420097b0b2f3c9e80faaf828ce9ae9b0bad86e13ca3fdec6c4c5264b2e7cff178a289b2c19391257b2c611454cfeea2650ebc0a8e42f4d2e99c2264b7ebbf702abbaedb87763cd5948433c3e496ecb84845961bdb328074acc024d96cc11a5f9422751f71421b7d560f1b555ff1591ef4dcc4ead818005c31eeaede5c28467db22806ec2edf563e0941ce0d31dd2e2211e7c56b79b6c4a1771e2e624d053b038927497129c470581c14db243712924e4348164c9059ec2028a36a6be81cbb49121d9184131044e7f0bfdbb24dbe2f9aae4bb02c8789b772c9fe16af8bc34eb0cb923bd40744380cbd2b18a2c39c63cf7b72105f70347ab2594e65f4a74bdd347e63e6bb1ed58fc4788947a79d7fc8692b26432b7013c6080eca7149025bbeac4643b3a3bff843709c01a280e5b4efe226f14951f0d461b9da0c1baa483b079716e190b29f3016d04217cad32944860840043f9b25a9dab0929f9b390c9a1ff5128394dd33020a8d9cab1a35ac4fb13822c991603546389bea31b078ae290876b1bbeabb34aed224876cc406506b2e425b327d3b264d5994278d46e6df89aeba2e48f4c706207f75e4261c8928198fae7eae64cb0e1009be53a98fad4d79f919d2e5dce04f090bbd3623df09926be8fcb25a7bba67d4f280c8e0099f81474b967222f926c25a7cfdef3ae10742a4da28e5a2abe264aa4e1518af9e311905a3f503275226e1ed6b5241791b535cb356217aca2958b53d9323a374d2e756edef3b14a4421bfcd9bf7059db24c4407f664c22e6fbedfc196893b0892f9c703544220d2b2d9977973a0793abb190b553a46e6c61b9e44451822ef306e3881cec4825170d3295fd2d1a57632ceea07604caf47071f95784b9e17180b0eeb21a5c327571559b7253286bb22496ab20ea6d9068a9397572715005904292c92a378b0d61e83a848b0399f5ab10e76debdfcf2e083d23c19e4c62097517ab7c24a9bd41a05a3c1e872190990814c84f51a83cb9d541f727b9be3bb0ffbd50157fcf27d18e6067bd2a6e95eae402ae355e924b8600f044a5ebc5b7323669fb99c40c9e75d75084decab52b8e54cde3a058e048d4f29b8a2c7a22e88cdcc37eaba37dc93ac00cdc792ce45a9902a833a2cf55eaeafb4acd3cc14cb2c65b2f2bee4eb0f0a72d54460e953f495f43fc3c0d69a00f530e55321e3f4964449441f768e078df59eba4959b5569c7cba08c436b211258848a600122b807720248406d894f6edd731ec66f95908ab18d58e581ec18ebfee5e86648554f4c2bf82775970d142f97e25bb3883d066d22101acca03fab1245cc81e81d6381be9fdb5a7cf60795519a976006525d46002b4c94969fa42f58a748ff0a7903876572fc9be2fafea73171b05f2cf042dec6235adbe91055c42a4d43e6889ab97f8b44bce9f914110d8cb46dc891ba941cb6a3efc8efe94f4dd91272774051a95bb0f38a689108781c030f17d9b81a0406a975f168407f5b7631a813da29dbdc2f3432c7cadced18be1765040aed4996434bf35c7815b78a0ef9ae73cab51963c74ee51cd532689337795f50ed8d142baa938915b21a9e91fa8e8a746d1f5e5053af17cb92793371b9dba49baacf6c05c88232bf61be9ba4b9561399112a68b8f1fa5a69642408df167929302a78994ff85a908a0188e1681cfc0ef63759b7a63328550295b15a2ca6462d102467e05212121828482e6514d91167d36beed16f352110af2a6d5f0fc31250c30214b167aea20c52677cbb0cfc521c789fbd2a75882af1330a9247329365d800d2b6b4496a45161210dab76b95c90fc0ba04405bb736ea25651a5226b706a1db296b8c1ee44da0104f0009a6bec1548909e4d070c6a33c389ba722221097232f0f1c4e56c1f81bcb078469a13dfef610c05371b9e792e800101000080c705008f045b3a7186809bc5ef14f07c85f552237bef24a5dc52060f0164016c014d828c000191e3cbb22ab3a6ecb2a466b99a6ecca291a9b0489c550ce7397bc6daf26c960e8522070a190e2f8ace15baa62f94d25db004aa248ac4d179aed0156d72755673aa09d3a34a86a04c92dc62a04caa62a04cb60734c5b75acc7353b440fffffff7effffdfb7fd7ffffffbd7ffffffffffefffffffffffffffffd7b7f46faffffffffffbcfbffffdf9f77fffffffffffffffbffff7f6ffdc04c2c66adb5d65a6b7bfefffff7fffffffffffffffffffffffffffffffffffffebdf7debff7effffffffdffffffffffffffffffffffffffbff7fffeffffffffffffffffffffffffffffffffffffffffffdfbfff7fffdefbf7fefdfb9f9691feffffffffffffffffffffffff7feffffdffff9f217ea7b0c63e798747bc3746be50199f391b89f78a1ea606ccf5509828b976796a15bcd89437bce47a1d638c615c035d3230c69edddd31c618639c3de79c31c61863ecd9dd1d638c31c63963ac43bb7c884530c4ac53130a0a2817157324ad983de39c73be66cea3e8d91c33ea4546c697b469d345cc46e5e8a15c2857575d807a29a5e03140ab5c2234049afd990db80c9922c2856aa41addde295f585dc0e82a2e1e70d992a51b72924ab0ecbc746688cab3a25b6e808e58a809a8952b74cb06ba559443b79e66e88a6ab95d60ba3a49f4ca541642ebb1b6aab834f7d56aadb5f602adc77d9546a3d168eeabeeabf947cd3faafb6a1e6fd9e1620b5849cc3a696b5659c5b7034ae5e75b3f3419c187d2dc31cb0feee53fdf429080458f19b325881e9ff13ab89d3d3efa3ab0672d3b8038602638e0c3731ddcce5b81f040528d3064a522d0ead496101742bb44852bb01bb2b00b0d76cb6e657f32ee2e4aee6a3b667e04988485654886323d13c330878e65e18cd461286a729c91617801c04832c42219623bf30c8b6569181ee438dff9cec9c991fca84d50d7b066ab3fa0ce666996b312a81d48cb1c87cda05f6538da7d998eb619a8bfb4eccc406d03469e334b90e164373abfc9693c67e6af9af69cca24d1b2b3a63d6ef92b5daaca6af2195dd3a52ab739a27a45443bb4ea05c682b9674d8f92ee51d285e2314a8b846a5a24f414c49494161d012969dc4b713bce1487e31c6b8a3b3a6db29ccd59b32ab06b867e8c72718e7ef0500e8bd5f365ca6941e172e705aae9c6d859d39b1c1d4236522122a1db1797ef81932240a674f452a03196cdd08fd1901ca4510743a461e450b9cc031b591d553d26c94a75597e8c60674d8184c0b0cc50ba92316786ce9ab541cc3639418849a8047cea88bc85881c2337a4d0d1eab249da9aa149e43535de7befbd5686cfd0c45bff272c0f83ab2f6768ee54b978adce3c9e3f350c158c6a156aa3984d33ff645cc1bb0c056e5596415c87fb9039118badcc94d942a758709ccdb449ba10f7e141dce73e0f527fee735fbaf4739eae695455f6b1d574079af3442dd5a115fa006df537c2cc58cc14cd1cf4b1599efe394f6b5b76ca41e7dd6266cca99c0ae83c9f729f4fb9944bb9940dea116881a2751ecec379582c977229ef3993f7bce74cdef32667f29ee770287ff22777f29e373da1715e95e7f0288ff2a3606ea3cf5b6b10a8c5a028fec2f172b8b31cd4a2f3b4801d3307750e6ad9005380ff481cc079ced31ef4261f1b061080c3d516abbcbf200c2b9b306cc2cc0cd479163aef02b5367550870d78dab11c890960a6a39d46761bfae2b801b5164ffb527e93dfb8cf937e5d62d2a532f92b7f9d578db6d5a8a435b49ca79da779da955cc85ff80b8fe1380fca753cc87dbe7324c7e53a5ee441b98e07b9cf89dc85eb6ecd65485a6d4387595b862126adb5252c0cc510c3c2308da9a854f5af534282064319044488b2244721a49c3116f20114800727541aa04a5a22220e8c027238180c054461108861188481000682280682889ca934b409ac03f851c2c3446e33a48715d9bab48b67979307b2c6a8ca5e4c233c8323b8bc5dd344287546a8ca5e94f8ce47edde488cf91245b5789ded53d640da1fb799713279d0c20a028a7abbb8ab7a0d54658b07daf1cb96569e6a0dc6a20c06e8164ee1c7f0d6b396fb7dfba9909670e11e27e1a6a9498715ae7228ce65f8975ce5608e188cf5376cab0f6c8d8516c40c354ec3585f2d119adbf89d8f20c9ca30b9d35e1100b616c7ae26faf663af37531b051e9f94208d716783cbc1bc7caa6df25d5663d56c591637cb116a15b484aa5b5cf36bba8eb8a062c1abf1fa36881dfbe846601539da2e0372ebd01269e8790db729b101d5ac4eb11753bf10fb3173101b0d5e4cca665f101208749e96a2615e2292d3ab132d832638ce367751955deca4400d47feedaab4b0c1bccc0e8babe1832f664bd278e1fa4babfd27b8b10bc41af1599e477c7458a8caf6ee3a1ba95c501182aaec820c5f5261f9faaaef2998767671092e6779206ea8314d22aab2454a809351f652610c9fd8b4719383a90095b7e7b94a8152e4e865cf894852eb10654f405467dffc91daaa6570c8f52aa12a7bb9fcf9e4ebc15817aa1e0e8994cdda74cb470922609a9916cb78aaa169fd9b884fa18d46d0d0ffa606b3648ac313515c14025dede513a23b855ee52d64c7d90a2c91362bc7ae06296f8f9335d2e950958d2e766b9d03709de37592301caab2171886323b2af71d6c84020aa998278b64873f68155a37a1aac6d84854a88270e83e86dcdc594668c38d4c4355365d6614376e09c2cc7c292394e05590490d50958df2c0c33bb9c38693125dd896731ade6cd80660be344f5f385a22dc46c931a53de92860cd751c6e247583e8c6e5d5058cd9e8d342553613c226bfd31926388dbd5f6c1448201050c0974dc05f99c52c9adf1a5465732e763168372605be232a9bce07fc75e28a4d165465af3aae7bfc04646b5737ee7ae524fcf8d5b7f904134ee96498e9bb8330546517e6185c27cd6eef6629ee0c9c777150c870920aac226ab27e83e9fcff4fa8ef8679c19bbfab2c6cc6bc837b43648d191db2f99508e147f48cb1f91b61545a801c7e4d3594ccc7ad8698358200052cb3e88085296f664da4e427c760ec18e6b25e240765de07582d4384f3fb01a3f5ea92f18425d061ad77ee9a21d638967a49a148e315ef82145a835b9712c6f082dfa0a1136eb44c3ee1b710583df89f0b7647f3cf88fb9adabf0731b8ba1d236cb1100299d0287683465465bb20440b9361eedb0f69ae7ff985c57a64c64571afc03e7987c585c1165f44ebb80d143a81ab9312c6d8c2dfa0a1136e892638bc88bb4037e2bb0abe1be3bef21f4384b97b32d8dfd1095b6f4e555095ed244c4dc8045de84d18ab41de3027c9f199cea8ca5e88ad6f4633a2d96918945d75f3f9726b533509250aa8ca5e02bc8e10bf2a5a15cc4a165465fb048823881c4b85a9ce16153fbb96b745c183962cee97ad1fbea91f5906cc0f7730c6dd9eee372a10cddbc80312b214b194180e4bddd26e90cbda9b47978097618d9a83ac286d8404b5a3d5bfbb820c17981e05b1476c9f26c4b2ae667be0ac2ca7610f77b6562d426f05cd0994379a2891e0d092658c180a144df0de78855b0c887ae1384c9bf2baf07856e3d5b6e2b0959b8a6d8e9da0dadbe82358a8965fa333325c3ac8616041572525f1f123edc5e2cd1102961e40b2d61ee077afbf67f4243f96b0466c19af9a2ae84655f6dafa0c1e1ae85f0de778aca1a64bfac099d1a265a175e08f652a4e228302663a843d212661baf2d12410960a477c7d1ee6838b3e8460343e4ec128a14bcbead2cde688aa6cd750178ef28c40d28f59dece6b4e71e9814a746f2707430cc27dec775e76a43fab40dc0492790ae96c2c56ca2c80a22fe8ffe05038b8962db07ca7357f471368cffbaa78adf6cc5e9d8ce861108841be917bbc64a3b28cde79c610e337396809fa5541fd2269d917a9e3f5b791ba82945b3ca4c1f1249807caad2d6e313fbf0e92ea19f7c54c1b7ad4cf65ef4cd7a4d680f5621be9358946a973e01c447612345c8910b6a3571c0690b0162339209225e901e07c1886906899592429b7c9a3e3db2dd3fe5441cde435a9afd26c5465732727ec3831a9b7ee183b12d2fa46d6d733f11a05d0c4ac6b11e5ff636de9a3886113cc0918835d05f39f54587a77d8b47b89aaece5cbf816dcad6a19f1075d4017f71caed9bd23042344cb941c313de3b9d7a9bda1881391862b891940c5907e44d71e49d09ce6970826169b8fe714b566b58d6a4ba0ebd0757e43af8b2ec6194e195ea69821747a955fcff2d8f7f49532abf6600089d2912640f86693dc1d84860f924d691a0d3341c378c3a2dda24f5e57a7e376af5eed6b7ccb0909289b152dc333aab20d1484a83b2d3913a2e79730be3ac5365e4bf0741450955d4ab36a36ef7985f0d4a6d94a0ec2887982b2f7d03550951d8d5431b2a63f62ccc657cd82cd70ffbb2bc30a1bfc9b81aa6c14e390e45bb9d200e3e988d38b11d81a09e3623d4755b64bb21e912adb62a8ca2e0c1639f4ab83d891d514e5f062030e3e8328be42293f3817c84db7d4039e826405fb5521de588746d4a2ec0155d9ebf30df4928bbc252303c6882099d6e0ee5bb8f99b9bcc585113c2d77323b1dc81516808f41800826f36c48a42213901aad2d531405576d179162222310186b9c86550be152ee36421c4e72a95bc177b0b78ae970c9319a8caa6bfa9980619796707c37a53b4455d40975c2ba632bd9922b60e55d94298ad1f0b84a86c0a819f2ce9a5e70576092e7ea3356661502ff198db398951056827fec22b6de46a7c6be28d385975e35d84db7180dc939bc67455f29d0f3d03cce9b14d6a1d42a532619f7c91ad80263e928921b20355d9be3bc1984b1883426d4cd0e08bfff5c152a8ca4664559fe73795c8347af413bedb2d6c8ff3e6ef5129d40aa76e6caebace1cab508120a5d426da6d8681b816614a93d5b0482bda1dc766c9a10655d9856dbf0abcd18881ea009702eb5934bd6da0eabf2ed92fd8e5ecb05a8b6f4914475576290a2570002513b88fb3423123539fb81f40de955b214683f0ef7dd13dd2c7ba98320ada52e2692e4dfe3942eea6515465f34bfdaf62a46ca19d9622f920df4a5bd393c17d01f1490bdf76e2c87146805520ce0155d9bc6287a12abb983e16fe70634bf42dc5508d8880a036d3c1f171036aa4029bb71e001d65a15e818c75fea994a072f6689e8b55fa8bd64c83285d36c3697565cc105439aab588711027e7c956efc40fc8d70666913035db3863550790fa2fa8ee0376afcea8ca5e8a40b93d286d283d919fadff712cc571dcd4a5292d1b81aaeca268c52904c6f84e00c5afa8caa644dfdb907334475536ade39445d031ff647062de43df951ab64ccc11673bcba87937c196806b8350450a988c520069cb80e9507979c04f6218347e144e378a5385a32a1b9d5bdcec41dd8fa7b3c2f0e7826704e38d7a311446f976ebb7e8bf13abf26ad8d536c1289a3ee61715d0837ac6eb5f677ca471df55f55770623352f92209940be5cc334d9c7045d256c513e9617c84c24b56bb880327fa373c48ab6abb16addcd758ff64fdd9de05950ed206918b5e815516546517aafc5bd7a48657064116a2481fff4ca7fd60c07a7e038750c84e4ed5897da60e033ba0f26576e9d2f5fca710f94d3029f6e2e9d1a1f23dcac2c9c1ba87bed20b12a4e769135eb39fbfb58f6f708738bd459dd71cb418cca522f15e36e756692699d5f76505a98deee69e722cae969a8b2e61daac77d6139c4051e696f17a2954d822a7f2226e7de384c189b0261be235646160cf679e409c4915ab98e8a70ec1ef506f4a0c31d3e2106f80b17edac92450a1b28ccdceff38bcff24492b2e33de25fbf30b5e8f7e98031f7ec221263b1f2a415e174ed2a432b076f4337336998879640ed47226f01fc2c5af346c2a2cf19b4dc2a6d1c57c706edf4ec772ffedc6f60f3859d5fb3b7320deb29cffcebb7ea5d63eef46d8e2716acf95604a4c96bea47df373a67096689ed5d7620956dcd5f2fb19764e0058f58c11de3535b0ececa8600e55d925eb4d59455f1e0a23f69256171c7b5eae097cb76342486c90eee25d88eda50e0f69826fc6533605770415e9bde555c8fef96c5eb8f06f651e08f3b7c1fce1600a10864d669d82aaece5cc35a7f4c106b51055d9cbab337f2ea3a9c88a112b0455d9d1cacfec964acfc76c7d307f691600d4549e8670d65298f612d3c1210d66a69d55e24cc3035bfde88107d53698a94668cdaadfaa0845e225405465a31e8d0774602071786d356bbaea09a0df71ea230c372eb85be10df8ff117612dac310d7f91785bc0f55d9eb067ee873c4ce792a9795ac99f215c49844c378801bac1b0d21b7d9f79889aa6c3ad51908e0300f6b9d97b0ad9e1c05e3f33ea4880421d3f1dea02a1b59d1386feeec12c0f5da507cf44f5475462a49572d50a7be72e958b0c206abc5ea5cd809e397ab88d791c5e22d6cf9bcaf89cad975281ab74bf988a59f0c5465472b8ec8ff7f725ba0032642b9e8c14d484a485685ac288d62699b3e0855d9ab94304bd685fb826780726786c60aa82c23f8385095bd30ff984344ca00a50355d91eba06eedb4442abdd5028b16686ac3c1c6ee612e2a4b25d51cd9e10435536278a781abb10f60daab245b293d9eaf1f019d54055f662f416e3f0903e5ec55e25a8f77f5073514753c5dcd539971055d9e45271f3e385ca4e8158dd2b9839c0f1eb75d1dec246e36c7928746b611455798d43dd7e912e1b8bde2ca22a5b8f18fcd99b457c0c80d10ec56ff1eece7877d2eff10e31d4cb7a64e60e516fceff05635353ec036cde736a40d38e6877888c948eea685ef77bca7554208d7b45f149fadd902d9003f0bf835c5ae8b3a7042921e665b66921dd2c85886675046143ef29335dde906d23545f89c5ce4b71a4a90d03e55ff21a5982d66de2d6997618f1c24ae986940b042130874d3b74654e9c8e141057fdacc2f05b94d9be48661558b6063b9558fdd660235eeb0eeb14ac0724cf6e5a9345b20154499e9e7e8361550dc5051c4386c8f87a2863f807366e5905963c04e1778888685d0095da8787efc616abd48e1be086b08eccb25180fad0580b325734936d8b9a365e969171512c2b84b4352adaebf08f8c4b626b7192f9933c771e3df4aed1a5d4693cffa4c81fc7aa42002dc0aed03b9ca763911c400e348a026e1fa3ba80e303f3129404eb24d58afebad7fc01c48df1ce02a3470dc3c0ecb870f03b6f4f030ec2fd1fcedb228de775991c68cba538e451d573b253eeed72b89e53a7f27e976ff5a89daa7b391caee7ecc07824d3d98b74daa5f105a706006067efb96b048bcbeaf0d015c2623e907f16a4e4fc12cbfdf23a10cbc90ebf550292d8d613e94057603a446c811b13767206a541782cb820de31e7f44b07e364ca12e9fdf898c7fae9363dc6f073963d0ed32c24bdb8491cd09e981c5cfd2c92d4ff5f110e333bbfdc2b1ad837723af3c7f79420d2b29dc837f213644146b882c56c91331b72a0a01afe4769636b86c2132fa3afc1c28cca2da69d0a3c251555bb77dbe0279a18ec8b2518f641e9c052b7529824a269ddd38f091cb8d1a662e74b8ef9d25a10c3402defbbf4ab8dd5588f3b44baeedcb26da5c9d5a73a308c28f27b176b1593024c04e93c18557696e0b926ddd5b0a61877ad3b929fc153dea1e0ef80e28997892c3c18faf62ca88fea30d02d85935ae9616173c562c10291da3dd0b778247069c45da35bfbb822ac68f34ce8afb5a0760382ce11b827e4c5965a9c086fcccda0a33e34065943f9f2ab3b07fdfbf7d0a13f6f7d7a7d2eece41c94445aaaadaf0f7db78c4441a59ce0a76543b5c7153c1959f021873fa0f3a09ce7a1dcd098344857543fe9fe6b1f8fe650c5b16c677499e71b353863260ed235237fc0afc64ee57b109f6c20d49a85f62d7ce492aa403ac8036b62aeefaf4f3a411ca4c6f8000e5aff98b4b91e15f8652c50d8538c3b57787d299a989e10d5524bb273407d888500549d884b5856255879911e21f5d35cbee6e8bde9a9681014c51bda4bc32495659e851a15f4de6c801d4e52bc5cd20a697bd49ef175e6d09b416f8d6c1af3eff8d63394ee44ddc0450ac409bc784656cf11932fee5f63901b47d0e1d652717acc0be20d71e3d8e765b7f0f61e5642a2103228eee3a74f4fbaa370d05bace6d728469d26a03848c6cc7f13978a7e29bd3d9384307662c2f352952326858d6b149b803a1b07888bf8b9b47ad9e6c4b0846135bcf1c824c9df11c23fece9a6b0608e64badd29db7ea9c0aa0be22c0afc09474621d966253967d7a6cba2a563ae90c4edf5796e431cfcb4b004ea6f29f6349b33b4fb2cd528c93d77e5fc194d81c88dc5d7e552b44bb62e2a56abc995ca465e957772a5c1eb816d8e301672c511c5d6023dd8d6cd8b0be984ebfd05c829a51424681d2e0b610a3ff85d8aaf6afb354f517c5bc60872fc08127029cdece6f98bd758ade71ecfedbc94ad2584d9aeab2c671f9b39c9edb3d0eb878219ea18608e53a4866ed87346755e0aca8250d94edb120714a01e939596d9a50c61a66229aee91ab2cf4c997720ac5ef3625737a4937d5eeeb1c588bf449b182f52051a0f8a5467d64188accdfbd432ed330751edc90762f2d417de0eff769a52f341a558ccf852421d58ccd96494b3042d7db656c6c842aa61a84cd7fc03f173f2950bf6d5a54cd8b73b796246d710468cbca70a8d2b4f275fbec6a7056dee405f6d47435b4da946fbf6c808209c92831ce42c5e8c4f719e1654d683ddece9b0536dc4d0f729f0f9e25faab84da735dc44397586fcb8e13b557f83401b836483e109af237b10eb166c026b371f53ac235730affde40fab05b697457b349b77803700f77ba113fff503c20860879e7e58252e3e87562cedd06691c09e4b7516999b1105f091aae6108b0e038261424d4e3c9e0d59d6e5ce1d13d2aa08f2ea31fe5faa5950cfaff0b047afc384dfbaf005838fc7e4dae162e88cd76c679dc2921273c72e03352124d8ed21a900f4bd2ad54bb9be0e51d90bd8007ba786d4ac42e6e9d3618f9e4b2d0dee16b090fbdedb355c113f14e1db09cec1ac489d2c5be69570d1b6df65458b7bb637fa16bc96c31ebd1e2a0e11361e3d6a6b3efec2a0d38bad6a86bdbeed1d9423ddffa1fe01d6eaaf5303a7836a02f0344562733837b0ef15963d7a4d8b3c8138b2c0c96f84a77822977532d6631f92ab63e97df47e3954204a713e78ae2aa94b25f9347188b37508d20150c96519bd929cea469d3d0a1208f585085d33ef0e1ea1d14a7e8dc36b3074e17cb5465ac73bdcf8054279aa5998deb7a56362164fb93d9a63d417cd108da69c1744563bdd539f92794aae1af941ceb43acae44a7ee58009d2dea8386531148564ad91f4589d3e5adb5dd3d5e94b1901bdf42a69038eed810e331752503da94dd519223c3caf91cabcd6bbacbebe7143da1c7094ed5f002fc84d97805b6960c0bf427895150014974ffcbd8289f2352c83458779386f1c43ac82f51b72e3a88cc9d693624e07f2b698fc3d152c08af84e303549fdbc723103d174787b2903af886d22cce96bc54fec626a73f39e1e2cbe9400b933fbb3af7f6d658c99f8a7f8199b704c92c86889a7da111f8c456112369e42d798e5bac58286f0c008b16b716b1a96017c310302483b9a0f63d1b3ffe0ff0aa94e78231e08867ca981fea2d855030c9f185f6150e70534200d7e3e291f907cbe5c3b4a2f3c89e0196cbe53466cd3178ea7369ac596cb78397991e495372e004c247069f1501f3db3b606f6d6d54996d868ac1a3aa6256586b3320af545cc85385691d60df7078a1f2214309ff601acc37f37c8da61294605ba31afc627b0a94fd24051dd730f33b78dfd12f77e76e3c0cdfb8d7b6f7fd16bca0052f6860035ac002075a00d4c7f934c3b48c4996c9b878967d9a88b34f79162a4481ea631720b74eb1b9eaffacae598216ce67525077b674afdf5c0473a66947d477e02d0e74197b0c060ba1ec7f3481595d6d79d9be52ce761b5895d3a8aa7c69bfd77d0d6a7ab15da5ea7e0c65932e69253d6590bac48cbcedee1f9ba3689b4a68588c16b189cb0f6385000816d5e8bf6c3cd5e22a08c0310d42e3573e72ea8fa2007f692ac7af9ef38ebcc3812e62476e20296a741f1d84e40fa3232449e834ed9dc15c791874a7ea5b6bb46fe523470fcc00cc9ad4fcbd0ed651291c0b4d02ff56315aa0a2e803fb8781740d43bed96d46357e196e6ad8d12b7457832c2a0db8d2babd32b97328858c8d2ea8f9160779fdc3d1c0db3491f3b37385177fda5ff0ee1b7eb4086758266110ac2234fb7a46221f86a45ed4f2bb7651703a8ac957d40cd38ffd5425174b435939d0eb2eba00726b058beafeb188ae2dc0625456065ad5c70ead9952d4e82e7638283260ae5d0c066a888b2d520c2efb47a8ffea133842cf9c0245654bf79dee62d053acc64b204b0b5897074bb124c9b628ae6347e16ed0fe2e562901ae69190ef2378d4c46fd828499a23ea9a1437b0d4f08d514f50f402dc073806b6b65b2aa533d057f7f25a0ac0c6875071d1a03cb41a7fae870114612308159bbdaf2b3bdd27c002bdbc960a689c36eab920a2450d91c6a2c0a505aec47018a14c5395110482a276d8018b3eb53a69726ad804824001cc8ef58435582e9778490389c745e891eba6961940e5bbdac6766bf7677771fe518efc49c8f4d8930825ff6d2caeeee83099491b188c71db59fd9bd1d84a41c040204010331b058ba0849057499a01a43a5a4425249396a3a5a738474143fb505cd16a22d2823318c928c888c50285611510bd5521d156939e3ff1fe5825f711e380b134961b554aa294f584546453c444959985ed58fb2206579210b916765c951838ea6f3f0dfdd7f6af326aec487785df1df6e3697ff5494fdc2bef4d06b9ae964a53c9483a05845580e46c275a869684d6a1719611e86b80cbdf02fd4c4125a23c445a8e6402707130ce510e45358869adc84c132f45824961c57b8b812c590155c01ba52afa0ae7c03eae0f0c30064dc407443b3e2c60ad2a78ab038ef282b44aaa85145a90a51959f549506a40510100b0805f454e6500943052945e5874a13e35347ab1df21437a9d6142f5366b001c986176c6852e2484992422485889487218a1c168f92b442edae424541e27ab5838ad562f11d05ca1c284a50b87c0acb101429505035dcf9af218e500d649c34b977885a452b7cf95f1df107a8569df3556765c146bd4a0c245cad09d155020c4c2449b26449119e051f21920406553f2a52c03f93257396ac3962b2e4cb12a2254ffe3f853a5232e7ff5f4918255292dc499294044992e740be21a14143928444f5ffcfe2593012df2a8da4f9d0f159e39384e4f3e3837adbf4a99e347ac4e871410f0b7adaf458d1b3d4a3440f989e217a2e204409277a524a3d537a6aea4e2a8b5416a42343f8e8e1c50a5638f24d8d094d0d8e35acb093002f6f248e113246aa182162e4460ffc4845d483520acb100b17f95284a80825f2a60979ff170f175a2c9ea5681fb5708b45c4c23f2bbe3127e202c485efa327fbb68c7660edd091e361f075707c1d553f2a126a21ad7867614d4311fd7ff68d05a15f814e8f3fddb8786cac786ba54252610c15e2fc3f8e6f5574a159455b7c7c58ad22bc6af9f8a8f0938601b9c8e8ca154c8c98a424a325592b228c27ae1c344538e71c9c197ed899230226a65460ca0b39aeeb082938f246f8ff22fc3f11de8c34577e085700f935fe5f08ff7fe7892bffafc6a7f1ff41f87f34fe1f08ffff83fff7c1377d9d3fe37bf076becef3e0cdf81dfcbf0efe9fce9b6163498e0d288ee0c1e334c62907a71b9cc238e1e044c68da61311a71434d45f37ec9c5070eaa23d93114d27204e5ce410e2802b8c0d948d7f1b2730c2f01ce10c9e23a0502aa01e75726260459e4e53933277bc3439e20b5319314e609ce29ce29ce09ce09ce03cd3193937ea9c48c0b45405936732a2e9e4c5c98b9317a736a73627362730e67cc19446ce1d349a92c4302d11e6a4c54906377a603aae7661a71dd7d503c378745cd7d5630786e1c0787660188f8e1d580f4c074642f38103c36e60271e12301f3a1a86e1683a72f8d08161364ad8a14307c6834307c673f938ddd8c1033b59715a3a59712a02c3781c9347bdd269e9a4c4e3e662a2c3cbf7a0e2448552c3b0382d9dc03861a174c2e2a474a2e2b4749202861de000bd36c00aa3810c60000c11435ce08b101608a202405060025e1c921f9448a04a046ee8028107f8c0a5071e7668b1563a20a98ee016232d0e2822cad2f9d6190f09e580e54a03188043d00d56aa0051996283944be1c4503e1bb32a2bad59142835d030c3029ecc1f199cdc189ac0c0e405052c519204898fbd39cb9af79ae1eb5cc26d2bcda68cf0b99e940b471260a4089116107080212c0859019585089042015020c009270419801001040008007e98d04af091420f1284ecd09103c7a9003750e039c10676fd89ce0d33495c7c0b3ee2b961e68b7f1ecfb4840693ffe6c417dfae000287f078a62539df98d0f8c634846f6f727c7b13e4db1b16bebd29f2edcdfcf686c9b737357c7b83c31441dfa6e8dfa638da82856f5bc0f06d0b20d8f46f6c22f08d0dd3373646f8d626856f6d64f8d666cbb73660beb549f3ad4d17dfb6b0f14d4d15dfd4b4f9a6a68b6f6a60f0ff3e82827c0b2af22d08c9b72028df82ac7c0b1afa1674f42da8cbb7200d7c0b52fa16c4e65b109c6f4131f81644c6b72035bee170c345f1cdadf9e6e07c7333f8e6d4f8f64cb813f876c17cbb69bedd2abedd127cbb2fd052bf69f9f9a605876f5a54dfb404f14d4b075a1c3a2d4eebd2e22f3670b8604991d90e3e3e7094fcbf09dfe01ce162cdc3b8035094ff257ffd80d2e254967052030d54ae914a958d8c70931916f0e4ff797e64f8ffcb08732a3e3e4eb2a88c2e7ac5f08d0d10bce27875af28e3af26fc4805856f5151f9c1da4fb2e0238e14e5ff52c0122502d84ffeaf1f45887c8f2454d071c126c12dbcdf4e14ccda5a628151d542f261a5611442624911470aa0fa759e87be1103050dcf5aa57a56adb7934df8b37467c9875f5a63298cfb441cd62af5c490ff5d24a425ca6a75591cc987968fcf94e6441cd69224b289a1b8dfd77175582c6ca455fde8090b1b3549a394e64b1a2e699cfcff10ca67091a7c7a9488a3c48f122e3c16071dec014f69688282b4335fb43349ed4c503b836a49d06949b45a12ad9941d3cc5cf947f998698ff2116a4868d190e8d290a875da1168da11ae9521c29b56064c2b03d4ca0c69649a1a99358d4c9746e6a79121614e4b42d392644bfa66849866c49536e64e1be3a68d0153650228b4310348b1504c848484f896a2160a8552b55045484c50ad23be45b505e8ff4a1db952ff970bffd7911f68f083164d9ae0a183d609ca68810b2cbe526956027e0022813424e0c648912fa18cbf0cf02f8416813bffac558a880992fc5f2df0008280ffeb00435810b2024a0526595811d4651be0ff4aa1005d82a04080eb842050d479001a031040002e206f07003efcfc6071e9c1ff5bf9c625e91fa9a855d4821b56132b8b15d22ac9eaa1d0c1cdb5840e5e62b8c6b430830ef11fc57d7c585ab48a06d63652fda8ba13166ee1b1665c75af5c72ebe532e366d5bafab2943a4a22ae32aeac5572ab2b97943aec78662970e5e0ba2d6dac34d3597fb8cafebe5c64dc8a7756e7ec73ca47778f44f43927c435c6953156de6bef34db51ea4d44df1020191e2dba7070b996d675e7e0acbc4f6daf1b5c08ed9b10722e679539e34b8cdba3eb39e769bbb354d679d9e05a2a61d4d6f28cef182165bac2b83b57683b8d99e74d6795570dee86d9ce56c25e1fe690d68b0637e3585a999f76399336bf0b8c2be7a33ceac935b4d6597ccde0c20ab3d8377e19edda4679c9e0d69925cc32d7d36532f20c5671cdb9f451b95fac79f76cb7e4ef2171c5e03a9ad1dc7ba77b765c5fa472cc05839b6bcdaccc11eb2ccf2de116d5cac9fce27ac18db3d3a961ccb55b3b5ffce24eca259f786ec931c41abae066f7328473721d6b86a1a366ae16dc59ab74ba4f9bb3f86cac562e16dc9ce57c6f778c339d70f74bcee5d3715c317619ad743e77ade0e6ca719d147648b3e9e6ab5edc3da7dbb3d25e63afdbc64b05415c29b8d99b9d732cb97e92c2e72e14dcec6917b3a552768971cf5ddcecbd676576195aea60dd323bc115e7da0d2bc654762c7bddd05e70eeac54cf6cc3dcf3a615722eae832e7354439bf1fd9cc426b871bf4777c5d9c659d6c7af374c3783f0513c33e516f3cc51f9e42ac145822b29a6d3d1ddadabd16a7db9b93d93eee157bb8dd861cdaf2daed4986619cc229cee65dbaf36f7ed6c73aca57b304338e3c5e6429c754933869abe2c777869717b75bcf26e357d4f3e1eaf11dc6c331b63ce7a860ed66c2f11dc6cfba379f76cbea7617eb6ca15823597ee5a5f8e9a3e47dddc388bfb2cd554d73d1fedb16b796171f78c96eb2c73a6a7ee3456107ce0be89f1d6af4ffc6096185fa1c68adb33a71176fa66e6e2b6f0aae2d6ccbe997ba6b6eb5c71bfa8b85c46cca773596adc79d7d714b75b99459b59b9377458da4b8a3bedacbaf66ebbc45cca7d4571a1d62fd30ceb89b3cbee82e2465c1fb41994dbf28c27bd96ee76b2c38c4bd97bc6df9bd7134a4e78a00926d22ca1049a33499841e2883264928c1853849842940a3da42cb09030031808ea072e96aee7dee774514eedaeb830ead9a1cd7d3f358e5a5105a4e2524737745af3f878ceec9ee2665bbbac62fa62847c738e4941c76051fc605000cda527ae9c4fcf1a75cd2ee3d9844a174ac865afce5aca9fc61a73c203d7c68e758c9c469965dd35d60413b7f6dc27ce325319f1cc1a4b73337f9b62badfec3dd3784ec19648a5ac174c894b258e8e3b9ce1dcda658aa1b9b5e7b937d40e73d85da755e809819db9cfc2a931af3bebb2e72d25c4024ba2ca7c5d56cc338b31ccac741812f7eddc7987ceea185de5183be2ca0aa58314c7b76bb6bc62652e853c5a9c511ead9b12578ccccdb2fca4cee4939cce272196741faf51d3582d86346aee9ac08cb89ae2edea8b923fb9bbced898ab2db43bcbb49b5811b7c74e2ddfb66697493e3926e646fc7a961f8e6f56f7328875e072376376136f57b32723e4c095bccf5eb3b9ed8c39bb896de0765c1fc6194aea20e4796261ae7dce4627b1cc51e2ce23a6810c5c382bdf966f8b23aeb36218b89d3e5eddae34bf3db18618988b65ed906a9d598c7bad0f23e2d22e35c4d2cd8c7bd73562435c1aa9b535f39d71d4136bec02b756be65ce13ce175f46bb605fae7b15f66cdb1d5d96a7dba954855060425c5775decec2ac675996ddc42c80057133e82a95afcebe69b410abc075ddea979dce78de38ab1903e26a9bb34ce29a6d8d6746eb1018052edf523eec24d456575a1f7d3b8b2fdae93a9638db515beb30cdba8b594707df112e8734eafda8b5d50897d2e8a89339bb1cb3595f11e6d319df2f8bce523d6b94f31ac2ed71ebec754921edb066f95ae33afde08ef8658ec297697c09e1c22d658fbd636969cd34bfeedc08fb9ebcce2a1de7b6c24b8dfbaa9510f7deb18598ee78a5711d8c3667d9a79b744bb8af205c9ab3bc7994d0e10df59b171a1767dd76e7ac849367f0d10b083fb8b1ce18b3dd1c461867ae970fee7ceee19eb59353e3a8b3abe9ca3ef5e37cc6acedcca4bbce80b5077757a91fce3c5338298dd3cebdea5c6be97475bab7b57d796a1eec4007179d4b2bc53b8aa6a8d412cb4719628400230000104c0802d31500204824128984a1389204310021c00f1480031e5a4814956c405c38583c168b84015130140884426100200c08c2400cc4801cd31329e98a0c9a7113d333488bc832028a0272ad0e9a6010d6355959d41d72ef68b1081000b70e9e04caeab182d6fb9d20c06b7fed94407161135afad366a9caf139ffc401a922becf288dfb9abfd24c8a795304aa5eeafe67cfcaf99f2061a8cf2cbb47331651fd247e706aa8da91a5cd76f37a418efda06cb41aefcd3b007427bc3dcc9814dd7190d52deb737f667962fbdda2125abcb645ddd6391a82bcdad9646744856bdd4275d7e3e0437556491b964a8bae876bdb3f84b5540f47ad39082c00b42a90b1e5125a8a5e1f507dc5a3d05164308ad615b011bfd58dd08e450ad06b9ca8a107bf4bf9a151ceec3de6edc1e7b369d1ec1d19afb8144e6ecc24f0451c8350592d2925e143044d85b76a774a685e91824cd4f78d2dcab1d8bb3503891efd81d8d0e5dae8e364475be06a2d417e8e09c2c10f81c5530524aeca2fe0cfb709ea5d6b52671b9b01473a6609dd1f026b9f5d1ea5e42c302a55edf97f415c75c07802e374e8c599a1ec28edebe5b926aea2b60117bfa6b03245131858fa5895b4ec6419bd123a82628f4306f7dce3fd9793ee8ddb7ec52c3c3a18276a2b5492ff0e45c0177093d14bdcbb81178c363dea9a2ee1766557c8e98270c1e8030fa08c36b8c03e0b1f74d9069a2c3420e6cfb7673c5b49dccd1c617cd1fe795c3bf4a3d5c9e3cf8145e5cfa182c6d7ae800fc7e97f0155472ded8e4678f50f5c969b071b7abf91bbf87fb3fa21fa16906dc4582ada3554931ed1677c8e79ec783f07d716b9b65a0103360a00afa46938979386db6bcb7e966483c9b1abaae347e829264d898c54e62d6200753d373b9bd4420590bb8f38a2bce0a8ff321e411ba1aa6461f27d7cc1111b0ecd335bf9a6035d2cecc10e3e7f5b9fa75ded1d040d3e46dadbc80e92d585f8b1ee8ce6b298e58cccca90c19e40a0d3f018474467387f8bb5a23e1107178390deb6d425eba8650b92870d07bbf90465752c5d06a64aff7366ba0d3a858359ceadf6aa4a9161a94ab264b5120859d101c154264fa06870f04ffe3599dc0a02855ad53def2a42f57b818d8183c1325e2f34d51a7375bc519547c304003799aa1c2cdfc0ea9630076a4a7a1b3cc1a3e811ed04fc065f680eebb43376507629e21b8c9d939ef2266be851620a4ebdc1f8c692f214a48982073c110c031cbc36eba8833f7dd03568834e7efd1b9c29907869fd5bbded46cd00ccbcf3b8ecc15e4990caf4c92d1b13d4787f5c2566ab551eeb21d8435a7c7291ced6f585888281dbead1d2f59bede68a197961eb614d8812cbb3434815f0f961830a9cff68c6a6d5b2152608bf3459db707854fe67b46717e8b0b486d1e267fd9dd3ac960cac823db8cecd094348f85e2e9b351339f619df39543c67575af06aa07167db06afbc14348b14078bd55fd854d34cef4003ec5f926824e9065f0e283d7cbf982fec162340ff70f490dfebe7bdaf29e0f92116a69e1beef49388b4024b60b8394ab24b1689723f2ebca5919b4a015d1c537f12e8bc5ee25bd40a4555a98a5fad71ea3678533dbbc1e6912417affdf812850b74d6b2b5e06d5ca0b523cf7a72813662febcfac9759c0b74d64ad02e841a6063bef4035cda15514dde0ddf30f20e957cbca0985afc14678a6ce165d70ce9a2c00c54698631021f0f51cc3b11f2691a09aedda8dc60fa3b3e64a7120a0bd34110a3cd51e70ada09a6b7076c2dea44184c1768dca21aa96ba38614ba7088677e59b3754c06e0a0b30e277faf4502c2819e90ad766e09702d8d2db1840ee85637510b2b3b9c6db5bdee1dba40a71bed0ab20987f8d962384a79ef00ff3147746ba0a911264af339f272b8a266142b0fa5040de51a689e827f8ca488c9d586813ee5213478c4d722349feea429239f346bb35a9164471aff1ff0b777a88da32dd0092795a671aa34553ac28cab348d132175569ac0cc089aeb46ddfb338eb90700e8d6d32b4dbc129626f37b2ccd54c02ccde56869d25c9208ba6b3cd2cc6d4b530bfcb880433606daf0954bb37f34d5a539c701778ae4fea4668ef62b0882ae074cf6951612f89f07220eec2313fa062174333c133fa009367ebef7e5ea37573f544143c7dc74227b19a32a1e75fe6d3e392151e441938b72096b7a07c6680258bc7c501e34e2dee61f6f230a4be9dbcd6077a9c42a71771c5b569e25f3b4dfb8217d5cf240ec8c7e6f7943236a7336eb2e4ae9a0560142cb73d573e8b2e22ccfcd664efa4f25279dd23ef2df8ed9852c72d235372520275da4d8848037e960e7b639adaa3d1ff0405b0df0cf0a1a0ed6b47f17753676c09f2d61b6ff697f800308a19e0fa92ed22921f3fb7b5aa453c7a4e18f7de93859a42b17f4b2ec9dc08c381ca9a122f3de1943597245faee3750ef502f58841cfadc33dc8f36022f1c676162221dcaf7013191ee7ecde7aff318a9def881228a12e9d44d4678faa2d9c12f1b5bbdf8e212e9a7443ff054bba99ca700cbddd6e2ee438874867a0b607730565b8153f5bcb169e75f64294fe0217ded0ee9f4bbff620338ce267a5ee0023f71bc0838a41beb3e9026d254599ca7c3e733cebcf60f0ca961acf4d20833fd76dfb985f493702db98a068c26e95d82fd346cde7aadda36683401552da7bc190977739406bdeba44ca6520c04abf19d86a03ed04e5d370c26c0bb41bd2d8d467a3d3011b31f7d13f6f75bf4b715a7c169ff62e44787e6a166e97447afefbc54dd48433ea1cc4737936fda5316301fdde261fbe8f6cc47ff657e77c1436975d5455a6f51993cc04e948ffed3ceef030082ae2c65c3f8e8e2d88fbeea79660d3396a374f8aeebe6be962e790b3d7d0168e99121338ef275daabdda280a56f455e98c12d3d9ec4a5270023d361a22ffdd9c025b78ea763318f2f244c9d415fba9bb23f871f41224c57d2609ab936e8609b2da7667350312df92cf4788a69a4f3870617d3e1082f3db7d71f87d9a4553a95e5c138d081a4c07e1878888d348ee5856ea55f280bb9150e8b59e98e9b951efcfb717318108402e48a883ff756a6f4303a4730a567bff79a938ee8a3eca5e4c5eff77de9f37c8950be2a24bbb3453c5e4acfe85879704c896bf90fca958113d5a4b7926525b4fd19a374ba9480b01fb9c7c91c8854ff62356a1a0039e88b600903f9f9f816e0465a29bdeb1a80d5900db6a60446701af821c348e9c018256583bb9892f4635799a7c5c93186b9f499bcc5f4f06ed0f5d19b3f7e82c38887e968d99bdf504ce6dc71e2d31e0ad3fbb8835a274c6ffe046e590c872b211c4c6f0be732759a685d0a58207edd0f657e746e3a6f3eba9c019d5538c1e72aea9bc8673053ff2c806ccc4bcf8dff86a58445382fddca780c52547387dba5a320375d5497eeb648270c822cefc646baca0f8f4387462dc68192ba58de68cb002bfdafc24aff034b18a1622e42b2a5c7f5e64a912d1df06b93f40c22b07ec446ee33c8968e2a634baffea9c9cb24c4b3ada5c738b8b222198249d9b69bafaf9660ca6643f6d04839cb25b932a88c729c5d4eeaaf968d7854bad79f4085a5e5cc6a7098c648fd8946ea47ef3dc7cb3262379a3979c7b2d4230a60d951b6d3b28928a3f2e2163bdd96ec88199437154bac777676e49a6c4b354b2f49c4b8ba4468562506f7d6b50130c0dcf0b75a04076180397762862624a1c42731ab3f5f7eb742f80d0384f9b8976a12b1c2bcc11c3dc9fa1fbd853922c1a862b6d1ff99acfde5a7970d48e15b2e696bd592e3884dd20ffac74dbf478b73422fce226738c971f6e5f86bf9ee27f7c11f3f03379b561533d98a5555e607dd9717f65de6b7a9beca7c1be15af199b2ee77dab7dead32c7f8ca9560860355997fd2a0d5292b53b9324fcdc674c26915effe52643eeba6edf2bf584b97dbff770698b717a5323d5b998b9132126199ebce5add744e7b65ec9599f955a6b079b48b864efb2c6f90aecc5bbab45ae110836efd8689aecc30e19626df65f38ac7fabdacb1d307fce2eb00ffc83ff40ed6c804325d61f3cab4652e61cf3c6bee8d54f9238ddf2f4c090a33f38308651fc4d8e01ffab677c383d1f4814761e6859d0322bcca3dec3384f96d0950033e47585f9ff8cd3ce809dd5f8e361c6f862e3b02cb99952df599e7c75068ae029498d7105e534eaa36a8633e7f9cfd7f11c283bd65861bbe71a26136a2fbfe163047920d87e6cd200573639f66dea6c05e4c21717868fe38c842e311811d9af58588668d6fe726490ad1ac0273732010d19c53a2397c0620a012cda0ca1c8e00a210de2e50525761bc00dbf9edd149d3f8f4772ef2ce36fae787da40b6738c1501964b462633280cdc75dc7a54ba33be2d6acc3f3b6f1091956707aa38c0626d38e745fe338221bb3c496b2902869aa1ddd0cee8c7c06a5c52a47b82c680863ee0fa2cbe34f42b0a7d1fc9c0ffcc1ddab10abc742ec6472ac3591998c6f4d0c56459e15939032fd6d6eba82ae65540cfeb7466c102e3234c129e59e5e5ec6435877ce822d8d35d23a2a78cf30f8d2c26231f7a9075c275373dc94887160180b4fad1ec3d3f576a1eefcc8cbb86ab62b63d82863eb4283042a1fb82088d686a99c92b1941c2dd36dd6837d4a1ad5cda219682c57c849e59f5d79817dae517fad01ad999f9d094457b47e7ac25dffb211da33f3a78faf0a7236211770ee95229543f28f030a36a9ceb3940ba133c04d29e3d795c40407a02889e843462ffd1fd723cbac2fae8b57178345f31d017200846254c23ac3021ee474f0c871613af2eeb4f2c83310e0cd23afc82f43f2d4e1acf3dc07b91945a89eb39981c430416699fa8906e6b140fd2420b26d257264c3c6a54236048d30ef6e785ac75affde83aa7e1407a88d83bca5a3f9ae6632b6e92309b1636c7a33d3b202ca244dad1973f1488a42d4824edbdce8021049048ef3f0ca4e56f7af8a0bf4ed58d87a0870fe91507eb5f6ac00a844737fc7d6ea803c209849ffff1b571153da4f572e9eb3e7ec1e0202d2cb4a311a21d1d31efd1b7e49a04d7a00fd2a2d79938486bbf40423af00869bdd11371265411275dd866309d7ed580d092b6f79cdf4801483a50f4e24c5a66856316fc0b8c280aa4abd41e4b29393a4c38ce2dc7758e32e9c7106970dc45870a0bcae7b183cf6168a4dfd946d89096d32e94173aa3173733af578ad23d6b99423f1ae8177407393205ede8ef3cc2a3a71b21c282c44e06636c5041011c6dd871c657d2d4ff0e42fb8284341819cfad1fce577c46a7208f5e17a0011c5d05bcc22191f12d57a09026ed58ba9ac99016e97be730413a4e6d79a2a25e0abf489ebbc2e15e326b7835a028aca195f87c63514d87db355492d04434d88f79cadf39088c6e7e40cb17859c90cefa4175d497c5d36e783e419c901ebe49e08f28ecbdfb0d5a4da5b9161d279c90ae4c87b4680d697b09690b7e30fe03539aa486900ee4ef7022455ade23d2f3c98846d5049e34ce2de7a70598f4d5355cca82e9cab2b3e8907ede3473c6a9b4db6dba3e6dba1213bf284b76d8c2d38ac62b98a4e3d6fd9c0aa2ecd07882db81a7406adf31276df34d2384c0274d5ad99d15b68da30192cfb95e1734d29f437b7438b64713e8039f0ccd0ae99946592add0e433e3ac9938507900e16d25ba4471f343472a41d869deeefccae67ec4f92c5fe21b8a365940806e9cb7c66a86f113a31a9451434da9c867bb4ad1fa9da17f3d1e9ac471e2e2aa355648e1c61346d22d27a3a91ae8e40912e3352a497f3c58b340db411225dee049aa4496f7ca23b801869dccb4e25f203479a6a5320210c495b30d522140ed2d0fd00237da957bf524890c6562fa4cbc95c19704848f7f341693922819673dc6e463a32451a462ad26454ab487ba55fdc888875858a34e78c6e2d5b7dacac06cccdeecb23e80b718999e40876e50ca6809b9f31831b3279e2b179b2a304ac3b3de143dad20a54be3d85b21c93a1405b9e140dc23fba4c66baa156e747e1208c5882ccf22ad2c536930c8ffee248335ae6cc47226c9d702bc3df68236de51e447df5b6bd15b1a4839807d3a61e4c9c14982da425fdcb415add17b9307596380e1d2ff046cf58b82804e2c8f83842bc96828fc7146469249476a589ddc550f792509aa1f5cb595ff9b75e7c3cdce6963eb420a1b4244d289d3ce2d20a16a5372ed16807bcafd1704f5ae5f2a44734a794bf0ba5e7a81f4616b76cd41a4a57e4fc577e5de61ca1bfb3b36859099676c273594c7265bad589b4490719e371fe19e5ceff95219a93db90284d5d7e94e3c4288dc90ca52f1912a50d71123515da2baf28cd2fcb79a62252ba3b11a56d872f423da9341ace5cb446da0f89d2b14c30290d659961bbebfd020aa55d0373a5ca57fea408d4f786a3f4276c9476012acd38cb5569f42fd0949eaa3c1c4a0f60c17c735f4f4ce9b5069bd259eed97b9560535ab9a074ef2fc2578b8723d38533e78bf05044b7f29820f8cb8c79d2c701286965ddcf96f716f1ce118fd7162b90d2086c94c613691da5e57fe82424a5cd29303aa5ef6d965904d3f093f6038623f2ebfcca83c8b8744edeb3fb857140cb114045cdf4fe0ec690351ece68accce096e68ca3f42bd496ad31b7cc757e8cdcc63ebba6fb24075f603a393b0a9ff30836f7f03e2e083322a557da2c72a911307a1a6d1954974b97bc2992a713a3d6cee66ec51191d2ea29294df1a374dac2a54f44529a28fde27f577182a793d25ada64a5bb5868a8d21d212f7269fa18504a77d181c140291dbb67f55253b8404e9bff9725820b32474b9bb4eba05ce35d8946993b2990883a09214cada83c981a2bd137f04d7293b72094e62ca1f4653068099f12a5df1a281de76910483bd2807f2128bd256094cec328fd40536224bb28c539e8ac6194561b86d2ecd056ae020da577eb427bc1a1b44c061d4f061c67cc27a60f36941e0f046c07c8cabc56ae49f0fdc7217d5f610271c8e133a50d3524ee31f7f472065952367e04aad20bfd0e753e89ce8f2d9e8cfc56babab8d2a48f3c84af9011275a42ae9026c3342d415e905cbd2011d04a5fc0aff806d360794d1adbc895fee559e92766037697e5481b842e755aa5fb662badc5da8c37e7b2956e9afec944915c2b5da54390ce061859d7b83a9bb35cc64d4bfd44eef95e383baa74ee8a7410605bcd1286dae9412995eafccf1c257133d71ff3f21b3b9d4e3174342814dfd374fc9ec611728997a3fb9e765ffb99369d1c29cccfb7f3301f41868557d9786895d1e957820375c62938fad8133cabe1f1bdc2d1ddef47f82e83037541b72f1d19b2407a8d695a879fa1e1289fa3c4053597f1cf1be582fabb08c143fa8a4a99c5683571c3dab5ba4be38eb01b18d46475fad7a2f5fa7504ce99b3891fec18704120429dc22c08359d343fe2610d20e1f963b953122abbec94ca5e7e1dd1dcb86071c77f0b25b0fe615e4c00c1226c06bd3863e4867c33d4af28925638da16fed21e87f4d41276bb24f90b94ca7eab835b5d81dcdcbd47215576e43b3bd854d973a22a9b115295bd81fc7303f11baab2c7beef1de305cfc0c721a8ca46cf647a0ec1caf4c0d3d3d54df53e853acecaebd20542de39444b4be4d91df77d6c4c321be203da36cab3947c3620b74306f3f6b452bc270755d909258738aab28d93b6f42615880ae25d8bfe6d61a02abb086638403c653371c32584a8b6eb0fedcea832c84965a340f230e1d6fe741d180fec01e4cef19d65d2adea83f50f55d948c74319aaf94700d31f41119661dbf92be3e78eff0b3ccf7f28d8b72ef9bbf501d87ee2a266bcb5e9f49dc5d604275285ba567bbd9ba209e665787c54d46d058ac0b81e97635537cd6d93afa95ac1454555f6377451280b5c0fc5572fdd2135af3b8b8862718f5e6d6f54b584f41b6901570a200c6635700931d04ccc4a8a4ae19b79112cfd408506a44df640cbafaf6a4355b63e4d47d8d6e7077d443f48789cad1c5ab763a9eed9bd75eea6862f4ecec1ffeb50954d74ca7086f8c1a32a7bd958eaac85645b8c19527b43feb608dd155ad274254c16af48d10192d5e3aadd335b20a71ab636680eb4ae87c2b84e9e17198506422ddeda59a90c6749d55a505c1b19858299b017900c05e30455d970af3c55d21fa06c6059209ab53fb0393309800d138938bd7ea8cca61507315804ae7bcf17ec6776391ea5913dcbf249e66e9f3c32eb7545ff0b621ffe16d98ab5bbe2f58c9acaae5b2d6130fb22c2a02a9bb65645fcd9a408a6c14870a02a9bd37e203d11d1a1b06f8d0a929c00f693be320ab0b1fa2ec2162915e7032ec4a194764b4b234599ec5195dd98181379aeabd135c74cb8d12541038598040d735dcc402257d0d80fc126a57b113084a82227ad39c2bc0a3274539041514ac14eb108330c976a38d00e15db9808eede621369cc0b0986d9cdbab7b42cb7258162cdbc1783d1456dcafc869b3d1caab2df620883060b10a95ffde066fa7c9a2c8742c37e479dd85f62188890ad18cd5d99f63aff8fb23cdf343aa0174fb73b54f6265c38654e88e34b8f0afa7118bb8decf4fb9122ef63d444423caf4899740e14fa3697f02af6f26fe72a28fc4c32fba6cfbf4d55fa3da9f4ffaa4eee62edf036d32dd613d428d52117ca8f4d4205a87ca7b53c6741e32097ad1e2b2ec40e650d03826be6497c84ad2ff47185f4857976879d32e410cb1632c40dbe92ed946bb0c30b952e3666fe37d6fa3fd5e7d76689f1aa4e98dfd984d00a7360fc79da1023cb112a2c27154e180eea89f20e795a6733da9319760e34486fe17f9230f295b58c0a5f45cfa697acb6c7f9c0d0ad3b0d221bdf1f677900bc8bd259f61cd0812cfdffc891f395bb797ab7f09825565172f5200b9b003fa57cbef817f3163bd665c1437eea139a092acbd6bd53e7b471a777e260bd27127aaf50955df4b5bfbdb5ab87222cb470fce4e06e5e0243b5c2318416db1d0afa13c9ed3b36988599c407fa6b429ca524bdb78f78e73ec12a82352ac351ccc48daaece17831f7225b2d5ba4bd55231cdbb71a34aab2173db68f508a60dca339b73c358cfa7678955131405576198d326285d37dca4372641fb400fad71d82067ca8ca2ee263233b0a065fdde831bd1035e13da22cdf3064522ca836766f2816c83f3750956d604f721b7eac4d18277a8b26257b4f30544e14a12a9b7072ebf8b076150bcd94dfe200e26906b9eb78dc6e6af839b1bf4155b6943dcbef83dc8e3978024641a6918bdc3805d9bfafb00255d9b7aec9d0d5d8dd984b1a075cb6ab4e81d0e17450b58d9df2ccb9161246f343200575f824fac5e6a8ca1ed20f98f3664a4b4998bd092f54446a44a7253894928b067a41ea4e91f26cdebe0e0515b1845e1723faa12afbc7e7395f9a15f5aa81b9a5dcf120018ef4af4cba273d769ab25cd9d0b932806403052fa841d179630c41dcd400ca445d3845808c5648073c1bb3b1d9e6d9e6d9e6d9e6d9e6d9e6d9e6b998d9f06617f5f596a44ceaaab6bbe465ea8e57bb9b514a92492629534999b580007e0cd37d3eff13abbdc9783d3d0333032b03897d2f302c2fac4509f9bbd6e3381f22174e0b2cacb0989b3a6bd8e8d431a616155258aada8719794b7e65b5a0b0daed636f91dfa327b213161396121653deefb04bcb3eb58f120b096b597bd630fba16ced6a84a558f1b2eac3994c518425840584b5889ede4e6a534f9db67cb01221538bde71e934f78fb078b0cec97676d966438cb174824c96fe2f7f1f96cd799dc364bd84ea113fabf45ebbbd64613323f2e77f88cf9c25eb75593aed55512a59ea207b48535bdeb4896515144a50a540996475bec4bfc815f7a0d3922c4cca3de40c3151996291ac84eb9c12fa717f9709127d643d3e22c65669729bcc4fa09860b567fc49336d6a6cd929c16acf32397eaacdd33176c4044a234d9e64f044298c2c6f4e1b6289308f1f97944540405164a9d67ee9db69caf75f521259c7f59942f4cdf549cd2988acc4f68cbc7c14e1c1a61cb212720efdd1d7648bf82824586859ad3a2747a61a2fc590d5b42975e90f4aedcb9e52c862bb8ab1e41a1ea654230a21eb354f99a99d67a68d1b659095a9b53dc90f3b3b8d49116439755fd7d82a67ac9d29812cd4fccfdb57bdcdd29902c8720d1d7b6f7f743ccfa1fcb11a1dc51e5b51a6547c8a4907c58f3e962bf4c948bdfe79f687c2c76af49aebebf483ea3544d9633586d0f3f53d2a9b93a2c7fa4d3da7f53b4edb538d92c76acf7dd9bdbec6666f143c1643df1c11ff3147c79572c7da3f8e39e7ef77d291a3d8b1f0294def7c7e3bbccdea582d6542e650739852552974ac653e7eb0297b3a8925ca1c4bfd51ea618a25458e859e31950e3b5d547d4a8963ed79568ff59ec7161fa2c0b15eb34ac7a8f0bf6536ca1bebf951bed71ce3e3be477163b16bbf47ef4fe7434e2e50da58ed6cc396f4fc27f6691f6063b972ddf23d4beeb0444e5963396fe6dddc39fb8bcfd4588d65a3f46e47bd2e7d9326288dce40261d2868acc678337572abf71453ca194bf151662d3b6153ed35c58c859d4ab51f632d4f524e2963b14a8ddc7bca5de66ba290b1d29199c275b6f94935ca186b9bdda64eace98fd860a0881186050e07285fd840f1e2064a172b7ffda8e78af5275348e162a1d4509f3ac9de2b478ab2c572ed92bd67a8ef31bd3518142d5643f95cf17f729cb98e92050758ac77ea932b67bec28abb9b8eb17e882c872c96143dbab66e849eb99060b9726e99e53e5a7dbe18b2defb4fdc3821e4ce69ba14b2f0a5474d5d2276fc355f0859ca94a5779cb3ef54d69641164b87a542eefc2f0fa24590a5bd8f123bd1b5663d4b20ebf3f0714cd56d2255690164a5d37ad9b166fdbea9973f16dbc44efee979f267b5f8b154266b4fb9574ca545b8f4b156d935ab534e7562f7163e9653277543e50e6a7f5c2d7bace6e934fed752af53ad8b1eebb755aaf787369173b5e4b1989d53f810633feecf59f0580fe1aea6d6f70fa1d3e58ed5ce69ba63ae3b8811173bd6737c1a59e2d6830e1305963a96cad6c8bd4d11f36db5d0b1ccb1da26a2530e1df6ddaf163916534ee73c7aa499cdf912c7ca4fcfbd42cc53b2ea413816b2735efeb4ae1c667a6331da7d44ffdabb227a502c6eac4efdfb52e2a7d271671b2c2c6cac566756dfc6758bbb6bac3f9b2df5f3b3deed9d1a4d9aa4b1f015dbc4cdb5e4fe7c4163317daad413d3c7dd33d6e16566ac51b7c58ca54e42550ed341888cce52c66a8f2c79f2f775e7b92f64ac737e59a997089b3774c658481d19b75c4f67d53231983f58c2582a19c2a75453c676640b184bddb7f6b699fd99a75ebe58abc735339698fe3de4aa83c58b8578771b42edb4b3dbeb62ad32fe677328f9f14e5c2c5bac6cafa937c5de2f5a2cc48d5da274a6ba9f6316352c58ac6f6e6e09f92ac465a6562c57ac93f8a83a2f7ace50256a63b1a28358aa58a5623133df6709fd3dd673a658e9557a980c157bcda452281a9628d6b752859b10e532aa832297279ce826d6516dae8ffaa6ed3331e6130b134bac54471dd151af99187985458985e7d9399cce2a6d6ad192c4031624567ea2658f9a27e496a5238c58ae6d26333feded712a8bf86121a2499316962196588458ad7d522ef353f9f1e0120410cb0fca87a59c9bfaf752a772ec5e0f0b9f72eaac3a39d4ed2915b1f0b012b2b2d630fdb8e39dbdc3428fb547f4abee2963d4c1842587a5891a377fc50e7be7da82c3d26ee4ce4bfeb23d9d971b16a6b7af1d464689a5b4d8b0da534ead39e5f88937971a5662da1cbe775a533ab50b0deba16774840725dd7db5ccb0d29d47a4fccff6b9fd22c3728fdaee41f6f4d2b96358cea9de75c951072d256eee24b62b16f6e3ef838eaf3a0abd2c2a56ace4ac502a67666bd45c5ffb19b7c6cee941cd348c0a15ab157aeccb2fb53b2f4f658a85dc4e52c93984dae97e458ad5d9ed9a7a98f1b1459aad12c57a64fdd60e7b73e387a2f244ba40c589f514e371fd76fdcf495a69622d3a9ddee13f2c1d62cc03a709f0448589c5f91a31394678986bd425167bcafb2965e78a128be97f3e5f7f8ebca1569258d9ee29a77bac9fb194152496a37599eecdc8d2790a523962713e64dd7ef593267f1ae0c460830ca4116b9f424eefb98a19535629623d54563e0ad9693dde1522164295ef253353cc4f5b1962356e858eb65b3bdf9e8458caca510ff256efcd5a102b53f3762673cfa9a104c46af7bce8cad051be732a3fac5f86ded53ef72a3eacb3ceb583ce2d6bad357b58a72176f4f9e8e52b6d1e16b67ad8df9a99ed925676a8e8b0584ffa9e760c29e7c71c7058d8d241e5fa60c3e3951b567b293b61aa45c71555c5868592e2c7bdccaeb9afaad4b01659a5e4d8a9f476ad2b342c6d85fc784af57789bdca0ceb2544e5c776d3514eaec8b0b839430e3da5fbcc15abc4b05253f75e5543cd545f8161a5ce54995cf1dbd35ae58585af8dfea5d6dc6187916a72517161b96ade87c9ff24757d5a58ad4ce53e6a09d37ae30a0bcbd9e24bfa9d7afc245a613d6f2f8f6b844a1de45685d50ecaeed4eb12abd3fa3939292c878df0203ed5185d7a0585ca091513d663cf549d54efed3f429512163294e9a4845c52fdba554858bccb944b55cf1aea64192a23acf7c9ff6d2af7ac92574458ac2c4feac310d91bb94a081510d67b6e2c6d7a3bc3c3a8f2c14287fb586f43fc4dd5ab78b0543297b43944a82f25a54eb0309dc7bcf1bd2f99ec04164c966ac99d8750133aec9e5eb25c9993bf26d66d8a7fb1642174e96dbae54e0f9b5a2a59ff683d3ddc67dc576aa164bde6c1d664def635f66b2c932cf6687dd353f2936e9d246bd979deccef1af51eb544b2da1b3df59bdbeee8fb0592b598ea4c5d268550bd471695549fcba39c7629c14a9ade5b5f775e3d97dae2c8f23f871dc7cd9e1ad55b1a596e59a1467feb12fdd5c2c86aeabb9c9b942967c48b2c55889133e57bf7fd685104a94c64bdf6aa100a670a006c108257c1054e36f044000d7862016b1858e0a482678006509e3c0d38d880bdcfc006cf89066c03033800000ce0e3df442ba0806980817b12580005dc049b6c1ec0c905cc026718b059c162054751295800051d58b081069c6ce0820ab0497293540043e9a0555000006cf084830a5402f09c300e9c5cc02c1000e58906cf3970186890c1003ad8c0001878b2810c580102b043534843483348234813480348f347e347d347c347b347a3479347834773476347534743473347234713470347f346e346d346c346b346a3469346834673466346534643463346234613460346f345e345d345c345b345a3459345834573456345534543453345234513450345f344e344d344c344b344a3449344834473446344534443443344234413440344f343e343d343c343b343a3439343834373436343534343433343234313430343f342e342d342c342b342a3429342834273426342534243423342234213420342f341e301730226130613e612c612a61286126612461226120612e611c6044c091847984618469845184598441069c5640e610c29842184194410261040983f44c0f8c1f4d104c307b307a30793072ac5e0c1dcc1d85107430733871c4c1c0c1ccc1b8c1b4c1b4e18369835d460d240632946fee6ec612af4349dc198c194c190c18cc18881c84c180c18cc178bf182e942d313860b1e982db460b260b060ae60aca8828ad5a8e92766efc795ba9c82918289828182798271826982096609460926090609e608c6881130452c43c4108c104c100c10cc0f8c0f4c0f0c0f1c303be8c0e4a0606070606e50a58c0d4c0d0c0dcc0c1d60646062808179c105a60586056605159814646050501d98139a30269440c2086bdbf1f64f2963440801840f180f4e80804a26982c75b8ec99dd7bfaedb9c4924a25154a2a935424a9445281a4f248c504154716fab7c6c90e935a76aad2488591ca22154516eabfa4cb9efac3ef9648022a881c420243564b9e94fad4c7cbac5a21eb9badf273df9cea1557085144e4875c39db208204b2383553448ab903a302c81f7e54fa5011a8f051d9a3a2471e9a088fca1d76acc749adead67ea99e5fa9838e95d8fb8458a14c5ffe34c7427d8aa9cb8ef938bfa9c4c3cec964712cd4ad12f27e36f55a4a70ac56883ea93b9ab8aed81b0b717b28b57d84906267dd58ad35b6e47f6deebe4f1bab9f1f439a2f2577cc1d36d67394beebfe1472957c8d95b69d62cdde36a3d2556321979ad25172c35ee5d25878909ec79a634f454f3496ca45271f3d226b082b672c773ae1e79ee6c7b133a5a26246a58c0a196bb95597fd6157a93bada88c2146181a6000810254c058b84c794a6e9f6bc9a97eb11e1ff589f54f9e3c4a55bc587e78fddb710939f5562b5dac4796923b08b5d4ce3c152e16ab55ae714bd6e4beb5cce0096fb1dcfdb7d54388fe3d876d54b458e9fce53732a527d179952cd63ab27b89eb0e7ac95cc162b1b6e9788477a8b396b925c220084208214468d02b1d731540104020301c0c878563d1384e12e41f13004102029160240a0803026198240a8601614018108461188461100662100c433216a4ebf60cf521da5889fd6f252f40b7f665c599d15ddb4117d495945df7cf3bf41a7462bdd2b071dbab24e2a37e5a8e08485db1d2483e708a0891012bc727a973e0c4c4036ddadb568c3209e14095fc6ff9b26cb61ff7eb2219136df90f74eea8ebbc7756fa0af4d23795a93ef173ed26dbf4263bd4e786b6a8d81f5e2c89eb649a62deab4b94733c708766fae9273cc27733e32ddbeb369d4233fa5d8fd46dfed9289d950fca08e0f9243606e6c7a731b17e0fa191cf59c7aa39f87157aff4a319e01cf5fc94bf796ed96515eaa5bf6552ba6281118b0a579e4d099d81ee2783866bbb6dd2ae67bfc818e1ca87c91339fdea73388a72a68cfa17b05ca2db8cd5133ccbdda2345d03714e2dbf878635d9dd09bd4a6e632b5efda6d1d45c0c9997835ba1019b4cad10d88a8f049016f67215cb6598b9b05f6554894abf82c02f37d08382b8faf3540be6bff47cfc6b780bd2a1baa660b534993fa6051115e80c52117ce606789b4fcbdb09f8889279f3406aaf6d3a8a8963b8fae937371c63e5dd519cad6356c73a2cddd2e2406efc34e41d20540a06ce853c05dcf2d41240a6cc28e7a1cdffce436d5e38cef9b8233bd94dd232effd07646debcf9346e0392bda70eba6479f00b31c5c922ed8389860c5539dab82f4ab3259c3c0537ac31da85b1490a56c3687a5ee54179ef17fc96c75a99b6c92446ab9e91c480ed9c04b1aba5fb84b381d9500384d3e40dd4f321a5017703ec50c11ea4fa648845f04e08a3a85eda38a2168ae450e477dbf672c77ade117dfbb31c7a82fa1675e5d02629114ec2e3e0aeb40399c8c77a0f5429d1eee8244365b335694eb9664aeb7fbaacc8ad6da359b2ab9787ac33ca9ecd9bc8e0c24c9750245e2d71128d7a2265235cb4a606146b69204bdff3ad063c4da665943061eeccb4bbac12834eca2b43d31f63c20c69c8c8dbd23ef91976de546f35466c191ddc0a8eb3e58650f7dd78abe465e101f548cb3df27e2ead3a6a867ff6b4ed08de8a1e6cb38da908221a7ee5d3653f604cb1db1beedfb4c483d758ca47c4adf237c7f0de99742df8c343d06ef9442066fa6bfc9e0b5c091d0be0aa27ec57c0cbc224f065ed5b80cbcc26a065e0571065eab518445840b01501a78e7145a4e4825e0e57a22e23b4c981204caecd8df3d2600bc604e58ec3f13ea64f28fbf87d28c2a6d77a998eca1cee5dd6ba7efee5e74df5d9875df7d3d09707e31455385653f30168a35ccf0ec9b37d4b3f9aa10d73ff88f43d1a4c6ad6e1bb39232cbbe273b7e7d4690bccbf724eff641de8bb5641b7cba5db310e10e286ac0a0ccd035c469b092fbbe8b3b1506d7e8cd6bd14ed85d0942ba8bea85ddcd29a9c3798bd46a9efb9740682c7ac6b445e8c371e5bee186a553aba4dbedda6c9febd71fc4de94115c9bb78361c63ba3e7935a88413c20eb7e496e69266da5e1d192d2ee7ec98cef4f6067f7f535a2c7b86e8ea771299db913f3b942f06e1ead802a821d81cc728f30d985517dde1b06231432ecefe02a169f1be785ee4f0e2a113c61503402cb1f86c5b110b4d8027eea0e1577eefc461d7df9bc76a602d53900386b2c7adfd23f6dc153a36fbf723ee36af72b8be7f1b92f7d89bc4ae56187e4a1ae2d49c32d1c665a82afdf3213d5cb3f93720dd7f81b7d8b0893a09ddb302aa73b2bda0d2a64afdf9d6165bea930f9c838a829dde29bf288a0bdb829dac787b1195cba83cccdef0c0157c1cfd510de60e6f502feb8381dda9d8b96eea468deb5b7212c5826032bc5711caabcf9ebfcc800d8a6b5158ec4878e5cb16776251d58df17ef5d7eaef2de0f6682e41340fcaa842f6535ff9b3ae0368fc4acd52814219b53fad19b8214b3a6cbc03e25df540aff7b64fb544e8dbbb1c9d24d759a900d7ef7df91b10d1bcf2b6d0c7c6e0ef10987865e90e89391f65fe842ea620eaa8ed87f27c29bdaec51b7bdb5f5dfe33261a8fe72943ba83b3ba4d261946ede4c33e1d6358c27858d0954a176c09fbcc27af5786a50da38ebdaaa4ca60835e075bbe8211798f8a30d1f443243f73fcfdb3f0dced9e9809956cf869c71b3c2f24e0f3267da6ca2fc736ea4f801df5d8d36a217829945d56437c505c7cbd9806bae8be2e326ba289500e5a5bbeae7ad40d49c0d5d4c5308bc71b28c3eec3098fb6bab0fc4ca8d6c402b8c65c8be4f2c60bd58b2ed4330061cb52910820fdbe14f775046299290aba7d1029ec7164a070003dc5aa3553446278ec59ac119efcccefe4308e67f0f92c05edb6fdb43acbdf96572f225c90c22b03b2220f93d98b2020be5e9e79143e07ad17967a0224762fbf314bb8d86ac529ff792c775f5dd4844d0817683d4a84f70308bb3e700447f50fccc37b5e14e10f92d9bac89011f90fba57042b3954f16309c74363b1cc6f6d12517a733e34bc4b9b90a859ae56f71720afebe194c49049b1cd20d5b700fe490867602807733fe9c131a5d8e550e5f1b6cfadf01d381eea3b532d8798fb423bc68463367f1400e82168b9c11122da7332123a44426278444cbf9ad910d12692ee740161afd77dc385d1a941768ef2c41a7a6653ff3f3f77edcb2789547f97f2b48b7dd1e329796c233e02204e60514107c614caa3825a8bc42beb8083d8d560043a9f70a4573ae0113bd3b4da1b60b2c466155ee9482d070c4677310013e571714028b53892055653ccc5451823904394c80cd50cb26a0514155bbce4c5aed103194b6f832a6e76d63eba135778ebc35ec39d37d30675dc0b141229cfe1254bdc44ff1c5839175014b68b8c51f38cc99d78320782ba8b7030ae650053b5c6b31af06c8bdd6b259b648fc541e6008e602decc609611b01abaf9b2219cd72a1979b6f44d3de1dac9ad4e01d6ee60156dcd0e886ac03bbf9949042fc75c7c7a244b2109a4c7fc925b3fb5f6192e0b37bb35168509bc802f8dbe54ef7a83bcee8537b3140eff0560299bd0222efc831e20717a626fc6e3840a5f9ee1787e40494163ecdfd614df0794bf050d99672bcc2dacc13fd4127306791c026e20543a259fa68fdd47483e44798bd58ba23aa0eed3d547f7573735fee56e995157d51b0e54db18477b5a3638fbf24a2a437b73ee5e4d204875e65a9c34ce63292924cbfa9315f53b404a7e63c54c57eaf5a43bb0a7544cb4af2723ac5a964d188781e1ff37588d4a7e0ad40839551a216f336006800541283ac8f3d5764d4945341e651d494c21081fee70b523c9efe0cb7724e31eda44b9e9d9ba0266de596472de0a6c9359e55ca8ea7d7e7b2fa396e92878d0f0536695adde91027bf439eb5298e77dbbe0f6807e8d0eba7b94ff1886c8b2df4a328fbbcdaab8f39ee1d4208998375850255719b7c646d7b0471e5ab84d9a8d4441a60c9cb7a0707e123ad0dbd57a1fb576127cb9c7bfa4894843188387dcced9f80092af7367608ff2e81a4a3cdd73120a7fbb477cc1ad60fca39cd20ace940869e136fdc4a66f9df706b484a62e6e3aa9acf7320400201ddd67757a4230ef6301c0d16f7686bf8daaf7f16f506941df2fe71755cc3264863451d71435bd7351fccbda1725eef47cb51d2e2e5c9565cc1d0d75316524a5daf9120735ecffb6e348bc098bd858b745220e837dee390539f01744d0ce5b580400675bf975840b971ec7b871602a99889330260286c8485fe9a681b1ad001354853ca33919868023e2dcf675dff7e1ed7c4ff67b2596b065cb9ccc08737bbf692b67fb16b7150f570997ca5e271e155a9d9b11b3535941479fde435994913eda5c3bc4426fb53b345292597039ccdc8876793402699e5f826c381043bf61c8250359cc3237af8da9802064ecb1cdcf62d1f2555e0bca8d992c5924634d424b53fd770871256aa7f7a2c606ba69e7660845cafb502b79c776fad0bfb956265c59ac9f4145e0e6e9ef42d6f8adfaa1ba81767974c1eeaa6189b38e52eb3f3e7abd3831dd7bd59d7321c8715510659d76a1ebd7569ce7420b345cf8f5b2fe7c3b117646102baf750f3ad554bea23bfa9a0ac5170717d01ad2ef6b2e698305051a42acdd4c4cf75d283888fccdeb84cf38a2f3c4e0c4630a141544fede85181d80a9e52a0007d10c5c3bef791218338589b0d51de6f71ba231047e8acdb355f5e18abc853c6bf4abe2c5458e2074b56b4c3731afb6b2c27a7311d1e308b45957fda5a7f4e7bf244a194ac03dcfe4415e4f115d91a779bef828da84bedfb11a7a9e89c065ca5c7b555fe7a816aba0f7557c22646faf104fed9f7c4897ee48ddf42142900b05a31fbb170883a24a937fa034b6d15ef45f44b470fff725395b4d64d0d5d5a827d3311db2328f5c930eaabfc31ce95916e54ec650f7bc61f8f1256580496bd9a6d154c8e5781b6053ef00edf8980d0187bc411387264c000008100100fcff3910024c000008010100fcff3910024c000008300100fcff3910024c000008030100fcff3910024c000008f80100fcff3910024c000008c00100fcff3910024d010038795058000000000800292f135b0aa284b819a4b302f1f2ad03ec815b0ca03836135b84690ae44008\",\n \"0x3a65787472696e7369635f696e646578\": \"0x00000000\",\n \"0x3f1467a096bcd71a5b6a0c8155e20810308ce9615de0775a82f8a94dc3d285a1\": \"0x01\",\n \"0x3f1467a096bcd71a5b6a0c8155e208103f2edf3bdf381debe331ab7446addfdc\": \"0x000064a7b3b6e00d0000000000000000\",\n \"0x3f1467a096bcd71a5b6a0c8155e208104e7b9012096b41c4eb3aaf947f6ea429\": \"0x0000\",\n \"0x5c0d1176a568c1f92944340dbfed9e9c4e7b9012096b41c4eb3aaf947f6ea429\": \"0x0000\",\n \"0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b\": \"0x14682f9dea76a4dd47172a118eb29b9cf9976df7ade12f95709a7cd2e3d81d6c\",\n \"0x5f561594326291c989c065cf4770bf8b4e7b9012096b41c4eb3aaf947f6ea429\": \"0x0000\",\n \"0xa56fe8526dd0fbcefe5e4cf42d4a83394e7b9012096b41c4eb3aaf947f6ea429\": \"0x0000\",\n \"0xa56fe8526dd0fbcefe5e4cf42d4a83396c11c744ede738c0ba71e97f2a56d61a5153cb1f00942ff401000000\": \"0x00000000\",\n \"0xa56fe8526dd0fbcefe5e4cf42d4a83396c11c744ede738c0ba71e97f2a56d61a9eb2dcce60f37a2702000000\": \"0x00000000\",\n \"0xb93d14005a106a860e96236498e5cbbb3c10ae48d6afdcfe22a7a8de931204a8\": \"0x01000000000000000100000000000000\",\n \"0xb93d14005a106a860e96236498e5cbbb45577cba812f77d19e11ee99afb3b1770e5ba0594e52062b467842bfea753463beb37e055778761d6850093fc885a7422febafc39e429607\": \"0xaa3b05b4d649666723e099cf3bafc2f2c04160ebe0e16ddc82f72d6ed97c4b6ba8bee9df4b2699b018cd81fb394c9ea9b6d7990db3f2ed0453ae62e3c20a740b010000a0dec5adc935360000000000000000\",\n \"0xb93d14005a106a860e96236498e5cbbb462c39c9733659850dc31b8b35c3dbb0\": \"0x01000000\",\n \"0xb93d14005a106a860e96236498e5cbbb4e7b9012096b41c4eb3aaf947f6ea429\": \"0x0000\",\n \"0xb93d14005a106a860e96236498e5cbbb5e0621c4869aa60c02be9adcc98a0d1d\": \"0x04aa3b05b4d649666723e099cf3bafc2f2c04160ebe0e16ddc82f72d6ed97c4b6b0000a0dec5adc9353600000000000000\",\n \"0xb93d14005a106a860e96236498e5cbbb726380404683fc89e8233450c8aa19503974e4c6861e4f4daa3b05b4d649666723e099cf3bafc2f2c04160ebe0e16ddc82f72d6ed97c4b6b\": \"0x467842bfea753463beb37e055778761d6850093fc885a7422febafc39e429607\",\n \"0xb93d14005a106a860e96236498e5cbbb7aebf7923bf7080747394d9ec8667772\": \"0x01000000\",\n \"0xb93d14005a106a860e96236498e5cbbbadf50459805c55bd4aa08ad1bc123e5e\": \"0x0000a0dec5adc9353600000000000000\",\n \"0xb93d14005a106a860e96236498e5cbbbe54948988434b94a22cde8416e02ff24\": \"0xb7077646d50363e3e8223b4cfddb90fbd5b6eeb0b69a7957740c05617dc66af1\",\n \"0xb93d14005a106a860e96236498e5cbbbebdf0a7f2058d5cb504700fd125ccbf9\": \"0x0000a0dec5adc9353600000000000000\",\n \"0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc624f740896a79c5c05c809396d4c7c6a1467842bfea753463beb37e055778761d6850093fc885a7422febafc39e429607\": \"0x086578656375746f720000a0dec5adc9353600000000000000025f646f6d61696e730000a0dec5adc935360000000000000002\",\n \"0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429\": \"0x0100\",\n \"0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80\": \"0x00000042db999d3784a7010000000000\",\n \"0xebad2dde00469f10ee456ffd8609d2824e7b9012096b41c4eb3aaf947f6ea429\": \"0x0000\"\n },\n \"childrenDefault\": {}\n }\n }\n}", "codeSubstitutes": {}, "genesis": { "raw": { "top": { + "0x0b41d0c7f7b4485bd7be1d66066b00ad29aeae33cd714c36797294a802bb5a6c": "0x0c65766d004c73756273706163652d65766d2d646f6d61696e4c73756273706163652d65766d2d646f6d61696e00000000000000000000000038df6acb689907609b0400000037e397fc7c91f5e40200000040fe3ad401f8959a06000000d2bc9897eed08f1503000000f78b278be53f454c02000000ab3c0572291feb8b01000000bc9d89904f5b923f0100000037c8bb1350a9a2a804000000a11d1af5ef20e41801000000d2e6c974e90ba5430100000084e41fdde0772980010000003fdc5ad7fc3849be01000000582211f65bb14b8904000000e65b00e46cedd0aa02000000000000000042af1a0052bc537646db8e0528b52ffd00585ce1044e7f066f14501068689474ead241f0050f48bfd94342312ab9bed81b11cb790491ba1c0977df3dd2d7d5181d7a0269803f8e6d17be723003c9dc3a063b9d9842c14ca2b3492078b0af46f444961042c82664ef2da50c37158b13ca13d872401c01222fb233b7cf3820fefe6940f037e3b56253232bb8f4757e02363512821a7d75760c7bd96a40c8ce3a10f6eb1873ddc5dd0881a7536b87fd5ab533c7adbd873983dc3686a9fa98793c73329fe13a86da0f7c99d96df3df59fb81bfbde76ddccd10beccf93293bb197235ff6a9e3cd4c7f3d147539d1f8f6d8f474defccd970e97de6321c73aa3ebaec9526c4d5d97968906e3bfb7bd484b8511fefd9e42123c3eda95503624f57d0bc87b7c74333f5e9bcbf2befcccc4eb65207e25feff8faf81e8e009117d7755def610c6a41f4b4aa0f5dcc56fb61cf9a10fe75d57e68a04b7dbc63eae35db51ff6d4aa3edeabd8e0a989d6fe8e595c071bfbd37e502ea7536b33a8898a399d5aa8a667aeeac30a12ca7ae632574d082616d7bdc62ec305356940b3fac02e44b5ccb1cd2caee3c6ae71413217a27ae6aa0d21d2d97b78866bd2a3b3cb704d1ad0ab3eb0639b695c931dd3d92daedbc6ae5a04883a9baa3e60d37a3ddcc317a76d717adeeb79afe9a3a9e6c6256a2a9766c769c325de86b244325cbd00e3d9f61b86eda6f9a80e4c7b6c38bd8d698f6d476f63339ad3ad98e6bf2e6b7d135456b0d3f382186809a71f87d334501db542f2f4bc400bd5d1eeb6deab06e9794110d487f68e7edc8e7e5995eef468351f0bcc6675d9f857cd72c2b6671ed716db5669ed4e8f9ae7b5c5a647adcd6298a065c400d36b4eb727116c407aed6e4fdcba250c65a8c0a6463758a3f724813df59bdd9e5a3521b6867fdc13d87036d931fdae9c6a900efe46c8d5703699e9779efed19d8ee94ecfefc7a9fad89315ecc9b6571d805e31ec49ec267f02bbc9d638ea43af1a560002603303d8f6c7b602d8f63dac254c19ab6c3e737d3a003800fec75394bd88cafe862bbf48c7f5e9f4f01e645e4465af4fc787fb70d2e3299a9943389ecdfcc68bb467d7ebe329d23187b6cb905e84c3afebe5e3298273086673e8bdc339045f651fcae6d09b54f643ef389779d18d396463731c73e8c667741cc78770cc211bee361fc271ec33cf71fdf6788aac39649df997cd1ceaf1eacf3957b7f910df660e51d4e11cb20e3f64f3eb45f1a4395453f36d0e5d720ec9ebb83ea4e3d71ccab20f5ddf711a088fcd218aba3587b2397473eb303bfc10763887289a0f51dfe1f343f0730ed5d4fcc61cbaf1aa3ace1caac1f98deac6e787aacf398423339c0f496e5229d1cc219adfb8f11d34376ef4f82deb383796755952c70d1b1c3219ac585a38b277dda0667450183f1b99197e3a2a9841abba7151180e1b1c4fc78c0c6549995db0ba2183411c12b391a9f8b135a383ba9151376cb297c303bc7846c7f592ccb47272686cae4ceeb0c387f83bec2071e0e8711de0bb0e180f3c7cc83a0f3ce8a8aa99f7f80e98f51d281d74f8908eeb90a3c39bb901dfe33cd8c89c87973e84e3a51d76f8d0f51de60e2f7d48523939978ef7b80ed48debc03939393c7ca83a0f73282747267b69ce9b0f61bf91eff11d707e731ca5eff0219befa0830e397cce211dfef91d3e64fd1f823db8d3d0b0cd7b3ce7e6e6c7c1f98edffc371f92f9cd7bce753e34739dfdc1e3a50fcdbcb4dc5fbace8770fc1f7adf41071e3c7a9cc70ee7f1211de7b11fbacee373c78e1f670eddcca19bff3b70bee343d877ec87a8cfebf021781d36879c0f55cf994339e4bcc71ccae13838d7e143d97b7c485e670ef1c0c3b939b4630eed380dcd79cc2112e93be6108fd3d07cc7876e7cc71c22ed38e943d8ec519d3df7d2b1ed377388348748bf3986bdc787acf79843dbdfe343d764a23afbeda50f597309d5d997e6100f93caee707dce21cb7acd1caaf9357f7d484e0d5c73c8bace630e59c7e4b10fe99843a8ce9ec7876ecc205467afc31ccab9f11ce6508f39d4e3939b43bfe13de6908221ca1abc8ca1c1195830c5a4e3092690c2096c20830c8a9e602ad2f19ea7a338a6e230f5e9e86f987f3a7a9b2955678f73a3e33ce6d00e1c27cd21a222fc200c5fccc801166214c1a48368064e506105604c610d66d4c0a4e3433ae6d0ccdc724cf974f438a63e1d1f66576abdcc247d289b48a8cede660edd9854d65494bd660ecd9c6652f9612a92f93687b2ec337388c88a2bd8b8c20a35d21043194c325a05313fc0c10a66a006186b30c97c48660e55f38736494f479f4d7d3a3dcc0e48ebe104c2b388eaecb139744d2a255311bc35871430842ec6d08334a22066072639a9dc54d4e38b3404c10b2a486143184c45fcea43d51ca2e655673f14e7f674f470ead301c0ec7eb4fecd92eaecf5440f0a0f1c80224caf5cb6fdc0b43507db7d9735efb291a641baed771d3620e0941867cbc116d34daa7e523383bd6cb9d7da132ad320417bd44fb2def3653448d09eba49037a7f3aad26643bf53e3bf5eac658c0b425ef74fc77e5efbbb9f19f107ca0372597f4904b3a85608ac306ff83773a098477baedbc136f00de811d4fe21d35fa72ea781cdee18edd65ddfde878651e36755977a48edf78871f6fc33beff19277f4f119efece335274e2035da28d85e73ba1f19e4d2c2af6a424020a8d9bda94bd6f4d1402ecd4ee8f5defac63b588555d735bbebd6af4af24ef5f78c77aebf6315b78d5d9c7249b9947d3520b82197b2d965b75e71da1927f4fa3ab6acfb642a4e1be3b42f2e87d47b551fefa4ad7776d4e3dfb1b74b71da16271bb0979c50ecbd6a3e98629ca946cd6e89a6ae5c279fa68f668f414d234dc6a573e9bd3a0e97aa1eee79ca41aedb6eb263c68c19d31d51eb294ee8b57e39c925fe6a3e3ab338372eb1dc707847ff9ec33bda24de79bf9734c8eb77cd7913e8c7b5110be59d4e36f3c8a7a3371b55dad4a889355a8d9a18a33b52f30bd06ad4c49566cd87876daf46a75377367cc93bf2fc8c77a8f337d67ce4d48d3a756cb36d6c35ea18c5096d131fc82578215b535f2d086deaaaf92897baac37ce8ea8a3a424d7c1eee0855e5757cd27be87314cb537bba17e975cf796a7b8aeeb3a0a0926dd122daf5c92ef798fab6693a17ea7386dc975380d8f6d5671da14a7ad9a10b05fe49abc7e879c726927e4d2bedab702e6f7f6f17bf8317f0fcfccfcce6ff7b277de0cd9c3ef9bddbedd25609d7cd743dee1ebb1c7456d6cb3c751cddcf6721d13bdc77499653a12f43e6eaf9a90d8fb1e7e1c6ce6b489788960ca3babdb7a6c4679475b2f5b0fb1e574e3631867bbbdf3b8b8d8e0dff7acf9ecd48dff388c331e0f688218f5a1ad1a9c3dac9a0fe4d2ebe1d52240d44cb4bb4ec034a77bbf637ac386e9cda65cea64aff6c312a7d3a989de639c29eff07967af574db9f4dec3cb412ebde7b0755bbff3e1df311bded17ec736db7847b9a47fb7e19ded7712efecdf55f381dc931eed8448365f36cf9b217c783e9c42db3b954b1d6cbd6a42f63c3bfebe877b58731eef7aa9d2abbdbbb769ecc9b6573e805e314c6fb6bd56983ad93ad9fc8d77f67c9206d9e64bde512e58be343fe31d35ba7246f36d7847cfd71c9e406fcd8168970198e2b0a9d10908ddc9d66fbca35cb07c69bde41ddde24516adcf78675bafcca3a6cea6f59aa313e8ad3910ed3600536eebb6de9778a7cb7abf27f14e57eafdde07ded9de6fbca3464d9c7a6fc33bdc7b659e357538bdcf7847bfd79c9d403f5a7320daad00a6389b5eab0b0744b4e18ccbe2c2228235044b8b0504ab0756164b0b2b079615160f2c2c2c1d58582c1b58572c1a2c51928415034b0a4b05720ad20c5986fc22bdc415c42862158a0daa0dca0c8c068781c1c05fe030ec05ee027381c1f016580b9c053e622cf015d80a7c065781a9c0536033b80c960293c1637014180afc04fec24e6031b809ec8599c04be030b80b2b8193c048602ebc85c1e02fd888bde023b011b80b2e021381b9602d3c041602078181c03fe02dd8079c857bc03c602d380bde0163c13a602c7c05e780ade02a18076c03a68269c053f00cd80ac3805fc02e6029b805bc02aec22ae02838050c05a3804fc054780a9b80a570147e829de0d38ed936b60dbb865563d5b068d834aa1335a66a823a03b5064a0c558608459582aaa84201d5062a0d941a2a293a2448542ea8b4442a51061615308c4a0cf984ea09447baaa2a8aa542aa8be542ba85a50b1a07a01c5066a0d0a0d941a560bf80c9c063603a7c168603548369e95d562a3d8142c148b823dc14e51a2882321d8201c61c48f11221e581e4415ec1c20003ee4182a8d7542a80700e894c03a826504ab0aeb0aeb06160cac17c8364834c828c8312c165460a88230808a07d595aa06151414192834a8305060a0b44065813aa2b0405dc15a014505aa0cab081419560da831a8285052a0a04099414d4122c1128255c5f2811504e904ea0952092b04ca0ad419d416283014172827505f2c1c5062504da0bc504cd823ec17d412a82e54189412a8245048b05c4071a1b65060505f505e5047a086c06a503ea0baa08c4065411581aa8222028503ca06141794164a08ab052a086b06f5036a0bc9064a0b2a0bd5038a07d40e282c281d5058a82ba81c5056585d482848322823ea0a55032b0b8a8a4563cf40d1809a829a0125032a0694150a06d40b28175052502da05840ad80aa42a9808a824a0105058502ea0414156a0a65024a0a554445a19ea09ca09aa04e714c6c23b211d7886d886c886b886a4435c4344434c434e219a2196219a2984886288688460c430443fc420c13bd10bb10b910c1c42d442dc42cc4a38885788568857846ac42a4429c4234239611a510c98863c4284428c427c42fd109518cd884e82532218611bb4425c4244424442e714b04231a452fe2116217b1089108918ba8250e210a2106210221fe206e117d10b3442d62167107118ba88398836845c441bc015c82758264584d4023e80564821403b2e00581cb0055b059c02816078f096f0995130f05ef049205efc46d301bbc06b781d9c06bd8306c98f5c27661c1b05f582eec1616cc1eed15360b8b8515836c63adb0676c1516094b859dc22ac1fa81b5c51aad176b84ed628bb05cac0e16cb4ad9224b0643241841d0610ab06d5dd984c5efc7899110106162e407092244b07d4528f92142e4d2fd49120223424a94308288d0919f20244528414284c80e09861e110afa79a26489037ec82f5428680913264a382112f48324091324424994488288109224902421e2c4c81146ca8410922348849c1849f2e38506fd08254162049123689224463869047522c404c9cf919fa01d64174550273f4e94103222e424488923049044d01f21233f4147b8d024498c1ce121b5a89091cb2168d012248494c091425021233ac820e8cf1124414c88383172440f09043d82c4899110e4207f80840386a840059250e227e80709211f1ce4161a00e9032d2289124b9070b283ccf2e344c912264e7e82882cb124044a900040f64095284164892521105262c9945aa8939f238c3871f2930491229c182112f49323b3501cb9030dfa0941124a282122e4e4270437482c983092e4272807a9032d02099122983092e4a70236128b2221c4e4a708234904213142c992233de415ea248922963842c98f13273f120080b44299246144c8c94f12488488f8084980ac4271903838420912268c40b2c408224e98f8015a80bc81322184a4246da0424794081272a264c91100c82b04903550212744849c2c6142a400920a75f223640449113f4904fd0829a181fe1ca1c448109125848828418284101211107182e4720a0dfa517204122744848e1809125ae22768890394203192c49207e0c81920217484929f2432d09f1f23882c11222284c411487e44a02363a04e92203122f45304919f1f237890567489114a90106122e84789264490306921253f49306164884b18e8cf11254b94103142040993fe39a264c904849428b1e4c891be41bea08825477e8ae821a550274cfc001171e284899f214a962071e2e4c7029c6c818a80c81222489874d00f50d0920c284162048923461821042755a03f42468a4092c4c813223f4afc284101228af839e2082344f420a3502740477e903872027522a4e427e8070925482ea9284162c48d34811e41e244099220a1257e8830918409132344827e8a4882440913d09125494c38528a3ae1219b50234470aa3634092246848c146144e8470234d51a234092c4081221244a90e0a8c228d091233f4bfcd4545dd0a0250ec83a40930145e28890911010b9c1008e0b30610492a09f271b1135165023962c096242e488110011f911528249124b8ee41842992821f4e38448113f424e9408122252849125496a84a890929f248e1801109125424442b02449087238a0260b15a65cc438716942195a8930353a9d7a89de0e0a4601a358265bc158136f620d0e4e4dcd4da49110428ba1012ade95328f466ec57083bb6b31ac7897991542c80b99df7b7157ee6e552daf3e7e0b21437eef6d7c10c2b5a4aa3e55e5f7e2db2755f53d557dfb9677f7a92eab3e6b99a56408975932c7b598751fabaa32ebea2a5c8a291dd42b005314dca5a8a5a87daad42eb5d45219b55b3d95d15606c2a70c1732e4ddade0ee3ee6a7baadead308203303df5badaa655e7df1a93e1c6f21af56baaaababababcad57bfa5677df2eef0e60b7da5dd6e55d963f5859005ced3e08172ebfb7efbd9dd12c0977df83cbcc0fae550560c7fa585d6db9aa2a7d3ef4f01e2b0360e5323fe65d9d922e0f152b2bafa6bb3b30ef2e641bb9bc0c9999214b5d7e8f756d16563a2c547dd9f656575977f7ed5b7d6f9779f73d665566e655de5d69c1c5011732847021d45dd5d5cdd95d66858f575757ea83f13dc943f2db8dd75e570e9347f522f7aa2a56f1bdf8de159fbef7e2759156f5f132849019c2cc8217efd25c342ac3bf967777e3c50cd7920b570607b365c1f874df7b55f574c77b51c6dd85ac6f3753bd707059f16a9499085a92c44f1214a504f879b2e4c84f1011234e8a38f2436400403b07200093233f3ee438c2e6882549766c3a80243f4f7e921059c24812448e5082e488239624e96104092738f450022031e22788090e3a002123413f4a7e8e208280011ce000040872426489101326828ee8b0c40f1238378c10528288901224414c6e2015f113f45344d0921f24414200d0a10458b224880766809d1b6e30f213c4e3334528f961c2c4080ee644c80992257e7008f003642449086ee800828cfc243972f344c9cfcba10348028990122582881c718224890974c44808922459120400244924b1e4482953b20489d011234e941809122222146444888719a11f27447e8e3012b444c8c90e20041800912596884008076ce70004200264e4c8911f202247284182841323485c7f7e828cc079a2e4e7553a00224a96207112f4f3844812448296081939b224491223448496f8c1e189929f87236dc04a44440465a110c9220a6589aa220a852aa24450a0bc8ac82aa219142dca60506411280b8588a1407945867668888b281114284444af08d11241e12250a06cf58a28942da250a0408142b45a44a140810285880816512d42b450b608d12a1145148b102dd1168142b44444b008d11211bd224a44c44594688b1ce0f560557593706244035ca2be810d7bc75680e02934ce6666a630e29201306efbe2b64a6b5cc6754374921f3f64306e9badf014cbcdfc41a396dd412d581a76c125caa829a8456e632fa3e1646f9c3637fcd1b0319849ce5ae2c4755963a7c2f04e35bbedead9bba1d6aecce3c3b5d9619792d3c056bda38e9a3a4665bb5da7341fec16b7986ad5ec88bafa725dd6cba55dee9ad41197a8639cf60305864bd4abf73c6eeb8beb96389d5a88068b99c5c186efe18adba68e78479e3a05a6ba3c641e1f2eaf3fba877de06017ac43dda79a500b97a8432d95981d98a705d8c6631b15bbe0528c461d63162ec508848eb10a2ec588a563b4c2a518a7e818a1e0528c553a06b175304cc777eafa211b7cf7cce8986576b03beed21186d92245ea08042ec5a03737cb247129bef848c5d32b42155480d06af48495eea0194d413334c836f5aa4a3fa32c40a8028b95299aa2a0e0124555510dc28fc22520b4ab28ea83ba6a7056272e51cc692f60eba0162b14172e517f93ea824bd4bbead4d4876cf1d08c1503b5bc83469494a6dec12f8f00526ed5f59196004d1d1e5a793c710cab43dd9a5d4c83e4d9c5369a3ab402adf8f06398c793ad0e75b955b3db1ea9c3a1bb0c8718a6292a86610ff430a5f9ec55db6ef234c025eacbad182e5137c006816817fdf21e866d26829ae559314f94107212d484c91225492401ea90207184113f451c098191224440f0010f7480031bd08006511eb3a9ebf200a0a95f575c3ad87a98bf62a8ad5a314d5d035455651b83ed2677839be4d26e199776218051a786c794cbb8946197252b367a3cd9845f9e0e3c94d726abdd2cf08bdc4ab10a2c56a680a20a3c7109c2280d5f1a4f8d869ba5e14d5bf7be64f1d96096861ff2a5211b3594a2836077f04bc333b771093e727b86d70d874bf00d4906d8f81d69a7e41284c0b6a74e8fa309a640a3965e9afa7b17bd3fa3dfe1b338c114adad94e663718febaabf47aebb1eafca57b860bed2bd2c2da5bc02b6789e5d76bd7cd484a06e7ddff31eb4be6d9d021b7620f8f72e091fc8fabecb2c21f0ef14d8b029b45d9d7afc3585966fcd27dbcb3eefaa0dd99613081a3d2664010d50eaed25b5ecaf0ed9d80c95a565747cb71c38dec3ca3b5b03b5b039f67dc63bd9abef2149c7aba9dbe67876a8f96453b7bde474607f9a0f3675938d71b2334e369f87cce17726e12bbd5d888db3ed35dcc5c52675378ba68aa67d795c45d8b64ac3631a36bb245ba5b1bf6bd9cb342862de9102b6cb4b9955bf5eb0757c2542291f8f16da29b061e7e7f8b676ebdadf791035fcc263dd12d6893a8a5f5e161e73dff3b8264b34cdbb6a4254dd41692de39a544d73d584f072ef50f379c71ea79b949fda55b5639c12ed3651a600f3c26062d478e2f4c49427aa54a55eaee44417aaa34e70914e78d99c1883e4c41977024cc909347e18a09733401b9d008da76948b4ab2644bb8d9531c7577839564d47d645f3b129bc347f77fc06e7068c07e97a43cddf83d3a78333bbad6fa626c43be2313bd9d877cc4e9266b735f61b18761daf3009ecb1f9e43d48683b6241061664f493e5c6dee4c5c04b177ed04fb8b11924041b7b1355a30b2a54d04f606313723abe4d7a74b77d043fe33aa2661d15c6c95e4e2836efb12b40875e356ad95d58e94ef2378a948fe781619df8f8d0e8f86eeb5805f6ec51bc74f78e3a886599e6b3570d9b1d5163dc6bdee3d9d6cc4e72b29addf6ade17c0f8ed4101e07aee7412ec797eb8a7497e3d89583a30e6f693ef018e474db430e9b7c1c9ca64580a8776ada901e63c68c693e9623839c02ba8aeaa8157965c342ca722daaa32e30fad1ec822e5ad2b614d0cb29c0c8055eba87562e37c8a2316c358ac2c23b51663b3ba188314761e1523cc55157b814df1bbfa3ae004155c1a528617659b1b9e004bf9c4e272b4cf1d86e559ca13a0a46a2b1a5a13aea8235a80e1fd3a1256073d686786a3c9d21f4e96026d52ab0a6ed79cc712f7585aa82797e3a9d9c30c5fff1f095a7137fe35da9a9ee47534a755b53b2232637920d27c4df969a0f357553a32b8fe71dc51bb39335b3db9aafecd1c4ded17b3d9a8550176a23288e9a8639a2c6280e72291e530d4ea03dfcc675db7ca571b895c68e03f78e9e4ebc15868deb76deec1f105a8da244e9a1150c2d8afa1d3d30ccf3aa9c4ea71898e263108663208663a006cbe0a43eb48bb8b41a1549d11d75a5e37768358a72c66acc9a8f2586ed3dea51c3b7c91c7b4794e623734c86d38d799f12a2a041cf7c866712bed2339fd1863c25443145cfcc54ef61194e36b6d9a62d0381b0f3b54b296f65ef6463f306fb0fed1d7129de00dbbe7b471dff346c0af9d1fcc274b48e599c6e1896cd081035765d461b5245318596beae9acf353b20b499fc683e255b0a21bad2dd048c1a4e257ad47026d123d5840cd19d93315f9acf3bd4e31fd00430bc434d253f9a67921fcdd7a6b2ece01c162c977887cfcc5764d1fc9af9cd878f44c279872f6b2084d8d4888a141d8fcd68ce9ae4f2fc581dfeae0e5cf26379983c1dfe9b1d90e581f3ba626bc204bf44491249803a24481c61c44f11474260a40811107cc0031de0c0063490010c5c80080b548002436810bd74b075fa058b8d4914b3fc211e8f9aa49ae4bb94aa40bc8b7f730f790728ce1b21f1ef713ec8655c5a936a5b057295024c7bc8de9ebca6a39d1075252f5b73ce3bd7f539bc23737dc907dea9aeff6100200ae09d99eb7b1ec03bdaf541f04ebc174a4f04efacac723a9dbe30756a46ebadc765c195de6798c66d7f9cbcf69947cd6766dbb6cbcf6cef3387876f0ac596335cc625ebf2d86633aac9d96d2b97acf7308f8b8b4dbbbccc9fe6233375d3a650ecea2d5b8693ad71da972fb57c277fb47c36bb0d48cb29b9641d9bd6e47171b1c9573309e4d246310517d47c4013c070495bce2c158577e0a9eb318ad3869cecdd2c72dd9b9add36f5dd78784c27b029185f38a377b41a3951a53199ed062f351f784af3791cc619e4485ce24b60a3de917ef86000d680c0e1129f7a693b72ef07a4f9a5c723e1f938ccb39d4ea72826fe83b023359c70eab6a7ee61cd67e352c6251e02c8d3e1086c1d905e1e783a4d399d4cdc4471e112366ce655b96a3ef0ca69abf2c85c7b27b3771bf68e74bd3b8ff5aed42a33f9945df3dded156b76a5b6c4d84ef2a5eef8b46d1a5c7a6a301a671c7d19a3dfb65cb8f4b64b6f319e3a9fb90d23269e359f08c44ff1ef43367e8f9ce4d2e3e05583c0f6aab4e6008522a238164d19a3bbc75fbfecb1ddf8aaf93c804bf130831c10da0f501ff1aaf1ece1525cc0d6fd9dcf68f8311a3a608bf7d9f83fb53e7eb98b0bfd7e359fdd2f6ae4004b4ec757fa5d9999af87bb7b219284105e8894c5182f44da288aba10c9a6aaaaea7a9294f242c7d19da0a027a4b6fe44b6f52021d94d5e1ba7b62e446a6b2e1497dc4ee1360a97de296e4f5c7a8fdc10b70497de9713e2d23b734cba3d622b8fe7fafb1ebda37eef9dfabd77296cdbfb4ec55cef4e8060bfe2a1938b8b12458a343d31a3c6490ac9743d8a9492e99a51a43c53f6eb521260caa6167c8c8b12650a10d335a558a6eb4fbc364ea6293d4cd7a33c51ad713a99a6cc98ae3f31a3c6e974324959d335b7cad3d953c3d9f154f5d1ad19fdbeb35b2bfd544cbf7724340873fcd9a401cdef9af4b494c216bf7fffe3d122ce2754f38734a0d9cad3d17e572496a7e3002f599e8e36e4ae2d36fda2b5bb125f69cd01ca23aa984203a6406c6a640220b43c7d69793afaa2621a7eb7f8254a924802d421514ba5ea1146fc14712404468880e0031ee8000736a0d83380810b1061810a50e0ba62bbb0d8e03bfd721de28778f8a703af58584e59e4494bc74e9e8c3aca53978eb7c4d89e2529356aedc2b3236a3ec5756f0a7b273b52cbabf20cf174e0e5eca8577fda0ff274a5a9376088c7931d9e010b5040028220e09add36f3198e67e700062800010620238000f8f0a10700e8408de361071d727298dc3588367cc6fde940eafb4b48ea8a334115d10459a84ebc2a4929a38e5f548c64ab0598e614e938bb221de1bbe2f70c9fccadff7f3c32539bd9ecb6c626a92f2b36be35bb78e5d7f322578d3982ef82c106df65cdee6dddfa1eca77b2af6ea3de91faba66675d1f4fcfd3e1f355ce4e36577376a4e637334786fcf87f3c6be29798af4716472850df4d9a400a9dc1180d33669e1d6b42fcd4d74d10a5e3631a5895a9aabe74c992d466e0af2a36266f65ae8a494c9e0ef5a7cd4c883dd9e66f959599f99583addb2a9815629a6cf34fbd551ecfcabc2f558a00f3dc985ba5db4a3c37a682e9b68a0c134cc544319a98a67ec1608312bedb24bcaa9f4cd4d7ca8c8ccc0cd7bd670eb9ee0dff0b075be997151b253389496d76a4b662839f0982baaad57e90797ccfebe119ceba0ca75d7a3cd76b66276966b76da5a67eed60ebb4cb55b17cc0266f559decaadbba7a47ea6a767cf9adf27872cca9cd1b13fb55c5b6fdbdd32e33c79e4681225834f074a8ab56017d3ad5f5e96857ad02413c1dea5be5e950efe12b8b6d9b1d1f3e886a767266769b4c97a6be55b4d9c96c761b56e587ebf155655953abaaba9415576571cc008496e72a5a3e8714fd53df78fc6ed477b3bedb55255e5ad93a72b7589ae7836cd6f97b2e082ec133f7a5e1312cc7ecb673bce2ba77f58cebded96bb8ee5d738c86868606c7320e369aec97155bf5ee38f85013423ec7ff7874cc376d660d8ee51c1987bd86a39e63768b655996ed1792ccf6cb8aedbd7b471e9b6e5ffdd5444d08f903ff067333efa48e775bd3d8bc2335cdf5f1fce9c4d3cc4e28f68d5b5f4d8837d1da6f701d516bffe3a9f9ccd4316d660d69ca6cda8190a753efecdecbcc4cf3cb8acd7aa74634cb693f60bb8e01d9d4480a9856a3285234ef68c78fd13ff54f3d64638a292633d53a9ad96dd37c3b73dd9b7777af771d35353535b3e35bdf2f99cd8d5f556cf11d9f829a4f57e4d43552b8b4bcccb12b7b9a901e63bae61ad76dd75c1f0fcef99d6c7eb735bf23f5f53f1e9cd9f374e26f6627794c7d3a39764c7d3a38de91ba7bc75f3bd83a35fa7e793c6b8a59a68130431c6915d0a7b35fad023d4f4747c7ecf8d5af2cb6f79ec7a3a69d9dcca14638d4a8e3f74bcc6c66b7dd981da986eb68ae5d359f8ee633349d7627447d33a4c798d63ec301c9cc9b21f2dae5b56b674e28b6f69ea775b2bbfdd2f118f69eb79a0f568d39ea9dddbbd27b9a52e559390a23460da32e5fccb882258b162b55a6f089af8f99797fbde73dcde7b2b86b8b4d9e4ecb6947076c52b9347ca580867fffa9a97971b1c9d389a76ef2746a207e6afec23bbc626cf8063384e24fa793509c02a618677fef718c7f2fc2ec717b22de3deaf17ae0238977926c957e973e42af8554514cc145ef219764abc0dec36f1530edb1bd3791fd04a79d10357f86af399dccd1a6576daf28db3565ebe2514368d4970a367d775d69a861de942836fd9582ed7517cf68786d7dd7569dbabd379b2cd1bc53886c9e17149bec78c626401b5ee1bd7b53c0b0edbbedc2b794b059606cdbfa0e7699d2708db64b430dd350e6e80b3208d3fcedab4a57871a84af678e011b84465ddd1a637b602860a3ae462fd0d23c3aab0c5bc7577a6f7561dbeee2171ed5bbf8450837bf872319c6200634c200862fc8472f74810b60b6a0852c442c5cc10a6754810a53d0ebb10c2990314614a0f0040da21a44bb9a17171b5fa96ea161e353ab110cba5c58b6f82e7ee9eaf1cbe351d335bb684657f1a82b39bb18a62bbed2da5d25a6ab6b4e3581ae2aad3910c18555c034a7db2cfd8ef5c0e1069c1b1e3b483a72e0b0b95143b3cdc868197659b2a2227cbc1a44fbddaac2d605f1839e046df314da1ef29acff3493c3f4e21ee2133cdbfb8d8f4ab01b1cd87dcf6cb78e85a4cf376402eea5003a81020bfb0c2b89e804d21cb82f6059932cce81ab62668a8d4ace0460c6c6c804307397ca0830bd2173bc2e0f1849b29e064e1862fe0a03ede21b76568d578f658435f5836be7c9b4576c11487edc112efbcbf6fbcf39e236d70a5dfb3b7ef17a446f3198a299ca5a95b337eb96eabf4fe71ddfbed156b8ced3a0f056ceffb4efe601dfe693f5867ed8b53335a5bab6fc36c3779a8f954df0dfb6e33b7b8ee44504a3044821130b184089e2821e424a80993254a924802d42141e208237e8a381202235d8f9ef945834d9e4fddc9a61ef57b8577b053df2a788777664e69405cb3dbbebe7db9eebdf2e950afb92a0fcdd3c9aef5c0e1069c1b1e3b6a6647d2910387cd8d1a1a9ad96d33325a865d96363b5951113eeeb6add9ed67be5ec8c773e3d4f70846e8a20844e04283a8cdb389e32c735c465acf617d8720842000e1075bf840e63864be3de0811659ec000b1d68100da2cdb7e1f4e9f0f78a1c5851050e6e60030da21a449bfa0d6eaf3c1dea1796addbbfef95c7a3269e9d9499ddd6dd5e3159b32375b7579a4241988687570d88ebf0e274e36e866cc76fc75f56b6f86ead3475ec6b65a7e01d6deaacf9f046e2931a62c21c99f1a58bd1152c59b49ca654592b6a88097364c6972e6a04e447e972eb486d5d95474d33db3357cd6766ea664da1c803c354bb6647d4d72daed3a356cde79299dd122d738beba853bc028d8ede89afb4751edd1ab5751e96f59e6771d865b8264b74764c7b6c566671d85713a26a6d76503afee29a549dcd8ec8077b0f639c6ed67dacf730c65d53e8b5908b0c2ca4d0d19a49f4a8e3551b72918105191d8ff1b8b6d8aa6bcb57af8e6d26b96dd5aa79c5608bef614d88ec78ced29a031448a471cd1843f04ef71b54e19dd89d8e010f2fa53e1e659d6e6bf86e6b4c71d8e2493dbcd3c92078a7db8af00e750568008da6ee01de814d3d35a329204da997a6e07bd806599aa2288aa2ae39d40452318c06a608d8de396b783572228bee644308af39700708bd33f0909b1d3740085d72293e3e2eeb2fddfdd4f14c84e221efbc21876d164f925cb24eb075ef58a408de818f476213b0834db7a4a1a5e1bf8481694ef7a3af770a303a9d4e2753a75e748cd6ab75651e69e282c5a8695ab95c2146abc6b2a2c18bfc6e4dec7124ce864bef2f87ebd68813c2a085152884b0022d5c9c7042a529128aa610c3195670258b1760d40e67cb11acf04013a57fd457e6741be4056cece007557450051a686412a8620c659c80054a90411bb6a7b3efb2a6a2d11158d0d42145cd2e494e53df283997089b565c0e97960b63c6700231da2003159461ea484d6d1103144d3de31dd9d4cf3b58532f3d1e68a2fe637b3c437e004617b860258c951998a8d92501d27196e6b56c6ada97b6c7034dcbdcb9b4bfb81cd6d9ef10b61dad4647b8d232ad5bc2d8a0bbb7c515184730010fcf094ef01072fad586dc50d72853a4494e91a6eaca755088e09349dee2a40031554f60c7df08d92b1de30d3587a8ae4dc4669214359bcc749c57c86b19fda3351f7dcfdb534baee22233143c3280dc1468827f1c119b09bedf08b9facd26337d05bc967162de19c060575577a80fbe8db6fb563992fae0afd110a67497f50e9206d148930dc14adb70490d18131bb76e59a30bc5d268ee28457367c712a5b92d6e780598ce00dc9d0264aedfae27e1f08e72662d86a906292eca706a8aef61a2965cf58c23eac875db3743e2abab0c1745e6525407d0997a9e0ca726c86973639c4535ad169fdd0cf9756e8be3b634215ec7631a36e4c22c0d8b97d46fb26b5b87dc4d367f90b76e4da0ebd6ecf6e2a84b6e1b769bddba6a42b2f96ecd263bc6fad384e0ce2650771d7ebbd2866c5bb3e306827742b48d4d4b5e46d8aa77f1ef4358bb6ade0ca10ee3bc81bf8173483c35854438577d3c284b7431e5048c896d7f6d3c3464551fd4e197ab4e71dd9effb41ff6d5647933645f7d5fcdfdd51b314ad507a50971b5fed2203c2ff5c1d5a929ae93cddc44c7b9f1b0311887b2ed210f5b279bf9f2d4fccc06ca1684e90436f8e7948a2081254cbc2c34627c1bb7f68372a1fea8eb5e886afd760eefc420bd10358448f329be2e4f551f16e87d65a68122597ac1749ca2291cb6581a4203bcd391b44b0478673bfe07efa8910ec2f4cb62777a46c71beaef0c35081079f18078af7baf8e555c4782a63e540296507876444fadd9f181e4ecdef51d45fd0979ef6f7625e09f77987bc79687bc5373c89278a77a3c0efcb2a114a7fb8a53232c5534c5c5de6c30d622c0061b6db4d1aa8d511ff414b7635ab593faa0ef618ae35313bde727c62203c3b078e69cac3581f6d6b118a3e3a0551ff142b29be8981fb25f8f4168635309520b917aa75e3d8f2d4e8f2910f01916603abb75ec6196c531d71165cc9d35043efb6a42ac674054c7be1c768bcb0eb521f2fb9daa3ef63d9c711dcf551f7beb18d7f1a57fa2afb84e6889a8e52f60ba576cf04f73ba6d550860fa6ac6d2b18c86c75ef6349fcdc1c63d6835fac117cd356835f2c10dbad46a94050abdc760b6dae6607b60b41a6951a5974babd10ebcb40fad4658a4d17b8cca2e0dc241aed61580aecebb0a210d9c801e21a4a102d0a6262504d63c3b28fd84fb88a0edbd65736d589649ed0994d12042d0d24d66663488b2d1efd42640fb7554539a10aa3b25569084261c7593223f5c62a8e8265064ba13d2c2154835e84e084b0db4d09d100ab410bb73328520f440842fdd39d1f2055ba34a7740ac51a5f7ab0991a753efe92444c7f49ed284bc9b2c577d76bbda10232d599a3abfd27ea0ce446534f5e884a8a9574d74cc9831559686569a6bae31ce98ebd11517cb7882034e211ef2e6538f1c109f3520764c57f346087c7520e0ab2984b5d110b26821ee383b3e51731d39ae5908eb5d31f8a45c7c9ac0d3498fa0967806054637011be68cd6f3f2a8497f6d02e0a9f558953ded073da392524a8aa57c2b652cc9ec378c0bc6c4065b8dacd082892db61a598145d5470e57f8824a136d7380f71eb746f357059b6e51a38bdebff7645ab7ac018ab6e1d2a6c1ab7164952a88570b4a0d0206534b836cafee60efbdf7de7bfa9e72251ffabdf49c7e3f89f4be75d20a2b0d0fb914638c91e3833066ea23fe716a34bc16c68c7ea7e10284e62c4cd14b6553a32c40d17b52abd15119ba93ad41a8c76bb1d5e8088db68928909191d19ebd6aec32323232325cc030ec3a86611846054ccbe82670b2a63eaa4c7d545f6ea96cd4e3e15ff54c83f0ab6bcce5544fb89b401eb6fd0d6c0736a3f0306e2152f0d55442cd8e7a92e703311da71215037e4ffd712a860a9a9a57c8f80e4a6391ab94a818553abe1b4153557c37d4d4ecf64fc902a218cd7cc17204019401c6ec96a8424ce3b41a553146cf8c1933660a9375c5e986145821c595201daef4a0cb49888982e92b4e0228038cd3930544315a62041d9d5030266b9e14cc15a71c57f0c1135f389d4c3a87f450945061832934b1c6e96492f314e57432e93b267ac8bdb3a61a0668b270851cb4f1c4983126bd4d3314268a4c69518587ee742e145c5a287827e8475f014fa45df8bbc2196714293e4cf1536e98a0e01d9be6f3b8b6d8ba24bd507089ffa33b9bee940b43448977c1d62d145c68fe10fcf674d030c5106a30842c47a79329fe991e77823b8802074edcc008a628527c98dea7dc30c12852d8447d0a034cef919bc200d3901644bc0f0df11e3fa40511d4e31ca2e6901644c4bf39f4a7c38ff387ce7ba75f340d2608e30a3150018b2c40a18b4d4d442ef062042aa8f8c28c2dce6052137cf783889f4ea60705eff0f0aa2cc31e8c41052a85b6e112d1ee011e845cfc6e1523f5f72ac6487138da5a01b213e2a14f931dd3f0d4c4e1529c0a9bc9c0f65283ece492032dbc4b0df2aedf56a31b9cd1af096c1cf5b1507de89bec1820b49bec18267abb4078d720f175241f9efca3fe6e0049bd3feaefbd479ce8c35480ef61be81dfe6be8153a01eab89c3256ac26dc849f5a1572334acf8d106b6533696b1e23eb69da2653233db99066135400d425d1f35c8f60f2ec573abd10dc6681f5e27a7f8407a3c9706b9fa908f2ff1cec625693dfee29475e4ff78a48e8eb7619d2cad43836c47cce270b824ff9ed0c38f46febd750b1860681297e46a37d55f73df54b3c98eb9819756a31b38a16db8244f716b4d1c2ec908d5876ebf1e6094cff5ecf015a75d3508f6780ce388bacbaa0355d7675c57b51adda04b43f5115939bec6557c29af71f216b7fa1e96b3d3cb639c498eb1afcc24c7d9c48ebd4cb9ecaa0191fde2ab0644764c025a667db5264b4471a2895337e944d00636c6b413fd82458a13b4de09515bb3cbb0ac5ba2310968b35ba2b167faec51fbe16a551f9dfe02ba7eb8aed7b10924dfc9ef10bebcc5a9e49483d8c22def49a08799d8e0c481f1b0299772608fe361eb0e8483e09d2efb952a9a9fb3bc7c4d0e11a5a8045728fa52a54809570063d2a753d44fd8a2055ec2ac410d5f98e4d3e1ebc64e36fbf0b07540204ef754cd07c23b6a74c54bf315c03bdcac5c9a8fc33bf19cedcc5a8dae74d170da7069fbcba3c11640af586cdd028632de9815800c645a80b51a5d99d23818cf7bac0dd953ebecb027b0f59013b2b5fe3dbd96f1aedc936daf857eb526efaddfc4e112ff0053c678d8f43637302636b861fa68322e412ed9603342aa57afdec3908290c22aeec936e49e6c57d531e6ab0f05ba24701da78931d8cb885a1e5e1d94c7b0cb92b2e12faea2a2fab087eac30e35ff7aeac37ebfdf637bf139ec49392577904bf2acfdb09d1d72504ec8a9cff5275b2781a726ba936f52add1c4188bebb4bf571c507cf5c3c9755dd74908df444671a2890e7a42b5f527553b216a6bc24b216e993f99d964d7e8a87142dcf119d7e4759c3742d6a8abc7591d7c7cc53de17ec7983b081079d1ab3ec8c75f8f9c75c941ee708f61f071b72d2f6747f53cea75e784a89bbc96b7dec350fb9a407202edadd964a8bbd7fbad1972496ff36e207703cfaf8e416e8f6df5e5578742f855d564c7040965aa096122a448cbcb7808c42bae930782af8e4968c9bf277f5df042545fef38e892d67b585abf60931dd35643551fa0f643a46647d4d42127f7dd76c75f08a7cc56cb8269a4c9fee2b1c869aff68eadb6f107e562c26684c4c7f8eaaafd205fc98ab3b8c83dd9eef6c9768cc7585719ca5cf3ea430f54fde2b4b70c9bd9c6362e59ffd1f2abf90055c7ae4136e3ae3e7eb43e721b9754761c521d9b3396fc6a4b50b7a672494efdc5dd50efa1b18ac354b36647d4d62f4e721d04aecbbde4346b3679db04767c074fcd26db71e2c8856d60ef9af338116c40ef3c34172c5f3448f7a321111472353cacdebdd941e9f7ce92806ea1e1bca2e2aa430e030228e38b3126fde3baa17e5d7c12a2299a7a072501aa02e8d4080750b4d036359528986ef2c68ce938af18d243793e1063aae6a91beace6ae6a1af1a07548c2a26e5a1358727d08fc8fc05d3c7f3801d64414b1a5474410b4f98f4f2f12c1b5260c6185a28638b2e4c7abd65652371695fb56e59e308bd6d4d01b9b4d60cb6ee404abcb35700ef50bdff3e677de87df604866946f4786c2dbb920fbc03fb9d8b0ba6e80ea7df650730eea84bea92530e0802bddf0ca91e5f3d1ee87dff66f74e1df28e75792cf1d531ea2f934d7a3ceee202287ea7c24c3e4d4835bb786a02c969cd096396f14ed0b61077c543e526c83a10c6cb6354bc769cef61c92997e4be7933e43dfecd9beada429dd5d5dcd6c662a610289e92409b423881229cdd7bbc107b204dc8a3b82ece27b1e1b5c9a646545869d96a4445955e4d88f738bb8c4b7a961bb78029f363edfd035bda70c46d123154df9b1b97f444bb09803cae22406a0fe36e917bdb8641cd07be8d4b3b95e82d9fc060c269dba4c036ca6a1098c173001129164e39df1158916d065b106caa4180a8219c7212ed3e408a28ef294f797dc707d2d9044aeb75becd010da468359a228d3703b1dda01601a2266a6a4ae62e2eb6f7dea32277f3c336754a7b1fb9edb71c052bb2bd7df7bedc5584fda1065f3ab61a5121a695065310640d1b9bd98dfaf27c97d9dfcd0ffc477d0f81dee1a9ab6644bbab0553106cd88cf28e1ad1a08a9699fc4013287b851b027825f23ca36515608fe7285200050a4e404556940cc72660295cc451f80976829be0c6b4c1c61a6d60c31ad4900634a4710633944183a8ee1731719b91d132ec193d9e6dae9819192dab30ea1941d229b6a4e052b4d2710a9722141ddf1a5c8aa78e4f0c97e24ba323182ec530fbe5f1bcd3d3899f22ab747c563a8a79e73fa38e7f571ecfa66157cce3e1b19b6393b9d211872655bf2c225f9e1503820f78a0031cd880063280810b1061810a50600821262081080c8180902080f8c1e7010e30758f06d18e32397479deec70e88e47c75f57683e970eb6286315a99e6824195e91f1c11919e416a2646041c60e926454c02a314d1d5b2dc867fbbee2b655c3aeef26afab66bd87351ff96b7be39686d3acd370f2f23d2c4373d57c360f1c0d31c603b40b1005f8f063af63f47eabf96a3e3b8eed76e3aaf9907824b9b96a3e435ce2ae9a0f03b60e6a51231874f10097a8dea960acec799c0997286844254a6b6b4f49a3288deee13d9c4bebf814291ac77154d169b4cd6da644c902848e77445538b0a99109c0b48e6f8369ecd814eae83a7693f1d0e42f4e5bbf3e33c77664cb05b17572e6924bd246f3e1dfd07cb0286d739b633cb2eb3718768debdeda75e5c8b97e73ece2f6865be27aa76a0c7189faf51ece919343fc23713f0eed877d0f67c23bd4797449781ccb381e1c120dd8b2771a260997a867938935c606a9231e56b4b39522308de338dee33d6cf4022d3dbc1db99a3f8e3bbcf1f720693e58900d7b0fe7cea7b9169c633d70189cdd6ea9f7472f759443c72f2bb6a5b40c72c736eb81dbe602c071a4e6feb03c1e014ca8250053fa98130b7504b568d94585793c6ad29163396c89cebedceeeeeeeeeeeeeeeeeeeeeeeeeeeeee2ef76cb915c28dbd8797e37e43f3e18e711cf69a1aac074e9b1a43b5c1c61a6d60c31a28355069a0d040a5419d81320355068a0cd418283150685061a0c0407d81f24217b800660b5ac88206510da217165bb7538e2475c471b27fd8741ce7dd4e990284e6f318dd412dd419bca33abec796c3aeb4f639cf71dd9bfbb9eefdf7e8b175a4127534bb21ba07edd46db4213aae9d3abaa8231da8a31cea2807ea085247f3da9c1ccecc56b2740faf1982adb015b6c256b81bda0f398e83dc483ba5876fda101def88b2b47658c64e793c3e9c3a9402196344010a4fe06176b277985304701d66476a1500e704319ae085094b0823001c54024c024402e402b74030e017d97d70d08b2318a18b2210810b0da21a44a19653d945a3fd90e3379c3a837700704ae79d2cbddb78d8e1dd1beaf0ae04e5a87b989d769ccf6843741c00b323aad2da65b421427407e5a8b53f2cd47566274bb3db78981d29e73bccee395c87d9952c31b61eefa016b9917266f7eea0961c6657ea1c9cf6e468ce71377eaee63db8996bdc1a350edc0d5cb7fda83378e74d7db937171c2f387b9206d9a1419e481e1ae4c976a3419e901a3bce7174471be7cb5d5b6c415bef716e693e3853371da7d12240d43a4e99c13b3a6692bd32b404efdc9cfa9e78c7d27c6e9220c13b3c4e9d89d47c781ce3c183bbb0d7d4dc70b27970b291783cd2449d09ef28b6832355d7b86eb90de298dd763ce5c33be9e3dd1600ea28fec60340f2c1f9c0458eafdce0d80a8e776c257238aeda0f386c66b7fd7474a4865a9e0ef5ecbde617873d6eab70897a0db753b844bd379b773ba5291b9b6b793c0fcbd3a12e75cc4e6e7176a476c016012e517f00977e6ae8b369ffa9b357da0fd7b1c3ecf094e603233c75c43b702a97a8671c0e4edb86d3d6b8992f277f83af3ccde7c6d46da7f04ecda92f14bc5355a9395653c35dd56968f686652a6e5b36b531d3d030d35c6a3e3c05bf8d69be9a0f4d95554f86e329b894cd6e88ce7e711d5fe11d6c52ddf5993d36c3b195a439443a0f1b9e4144dcf09b13b1c349d79be3b0c3bc610ec1d9ed6f6c646e5d46e6392ef31cefe11b2132b7b9cc6ddec3ab11413a8faf46c4cd4937f33b71e838d631d76ddda6059c4144908ec389b8e1242d8288e071120e2520cd21d279cc9ba9d79923716ad2c1515c93068c19d346df08c96e3d3b497be78d902cc7ec664e8383eb6e5c48769b67b79940d563f7f08dd57cb6b3198fe7e84b11315d980c694104e9377f3773684f4fe79db4f32887ab6947ced5b4e3e950a5df59db93b89b2f4704e93773881b2232ed386b3714b839e918209d037b85eb79246e77701b84f74bcba6a69fc4dd1a35ec9d1d944503081d9ba85713129b67a771e027cd1d1c9149352162efec645e4ded164733bbd8407cf98d1342b5761db8cde136076e8f26b7339cf6396e89ee3a6ef98beb80760abd96177a6a9259fa7dc5e0f0f755e3f1dc7cc7df79cae3e1f177aef278487f97e13a55d3108f4be9717d3a7bc30ddd5c4a8fff3bb8a11d97d2e3379070e06eb829a4ebd3a1be839b42fa27353ba1c7839b429a5ac0d9a4010d7f83d08313086329f70b903c1f7ba201a69bdf707d3af171beae4e3a8fa12937b3043857d38ee3f08cb92754b3941ebf7927f4e2ec5ec7260d68ec3db8271a60c281530ace6f985acd20ee38a5e07cc7bc66975d0ace49d9147a1de713aab17905ce6482f48eb53cd6d2ef24399f50fde5f1bcf75813a25f748413e80a1e91038a57a35eed0735ea38af60429fce8e47bef9cd24f1e098d0a7b33c382676ec98f2e9ec77ccede9ac6a3e4390dec3a4497a3afb19221c4cfa62af6c33da97a2b8207a6638194ee3308d2bc221f174e06738264bb06183eff48847ca6deb486d84eddd374e4d339c9a6438351581476ad2c7032f1fcfe1498f67dbb66d83ffb66ddbb66ddbe14b343434343434343487ff515353535353537329404c358707f2786edcb871e3c68d1b9702c47463c2d7d06c5c5c8ba8e2eccba5614325b8aeebbaaeebda9e95a0e634d7300ec3300cc330ac04daaf6f5c09b42042fb756cb38dbb2162bbccd54464bab8126c9739867143d9356e480b0a68c74ec4ccb3635c0934226a26cdb66ddbb66ddb263327e9228a8c3981694e17af339b26530a02abb820288d93991b37c3fdd0719b43a191224d981492099b519ea8c68c19639a7914292453769a29e5266c6a1124b4b5f5ebdb87b42022c7717cbb71d2a1d47ce6433497c13164731cd7317f3c1df81c73480b2264aecd211c73489f8ecdec793af032f3dbd381a799fa74e0a1c8fcc6a1d05cd3344dd334ad6f4c4dd3344dd3b49977dbd53433354dd3344dd3debd6666666666666666e687cc54d3769aa9699aa669daa500316957d336b76ddbb66ddb485066b8cb70aa3adcd301c4631cd4034401c45bb2aa28ea4886a8e28c0bf170a314300d32b397ca737dbf298fccf724e5c9be41c0d620b8270d5bdccbc8c8c8c8c8c8c85c0a1093cc33cee26e86c03e840da98ebc6a43b463445cd7e690f6eb5ac06b4460bfe6d0ccb1631a37a405bc1643c8cca1356901af1a11dab339a4cd194e12a15d660e4d393ba1a8cd20a0649caa0ea63a9caa0e9c9d50ece11235f74203a69b000b5231422e6778efbdf71e7c59ab1197315cd8e0c50c62faad5bca904696fed1bae50ca74e634a675d9da568d86708d3a5d62d6730ea2d6750a3b1862ae7c6182375212018af18ab8ada8e6ba84e8867b7609aba10b7bc26903cfc5ebaa35cda21f2f07bcd0ef6c66f942feb6c1ace38bbd5b421977ca6012173eb3dd691b6fc82e19d77794cf3914a33f3eee4ec20e4baad8986a0c0aa2b41cb570dbb15d340d9a1b4e4bad7f0358717fc3537ccf5d8e475b75d3381ae67426cab854d40f51a2116e2be21c4363beeec3766c77d81a1999ddcd9e4ccae6717cce2e115e70d0d106cbb7678393b21f052087879dda34d807c14e28b8b4d885bbe5b30bd97e1320d88ea7202c967c72aeddb4cfccc15ab5bf15c6933ce4c4c4ad1194773713d5c92ef8034d670c2cbf73c190e3ebb7c67d3120a911d5ee63533121eea8e7679a93bd7e533dd74275e5e7547e67226b169a0ec5876497379d58660f034b3db79b39dfafe8f07c88c94a792d8347c97c4a66b8e5d6a40c003d54c9a579a1059c303a9396ba9dbbae6ddd61d90ae995d129b96c73e036747b33e2b39205ce26f9c02b8c433b393391b7c07a4b1ce2ea35d55dc644b4aca2b8077a4945f2d6c02b6e5e1a95f1c6b3ed731a8f96071de04d1715e46e8f83d514baeb36919b94e9ecaa424ea8a4b62d3d95c2dac00a8635c079b7abf380b4cc35e4d4edd164c2fa70a556aa69b965ecde2b0c182592decd16a61c12c981c6c0caaacdc367ff1f2a30c5bf74392f43639bcc333db70fe782a101b99ee4a6a2446294c7967f75555b5b42c6b36a9baeaa034a4b87427c44d3d327c16c4a46165c9b0f13521108c1540fc831d346afe32182b00fee3d467cf5cfc2ed1f1cc412eef3107b974441ddf5f93aa5fc6492e5d6ee482ac940952904085134ee0c2110eb808a1a694a4056cb022c6192aa882058a159e30431b8630c689347091010f445144990116a668b1820b6c404941056228c30a5bd00115266c61630722155c41060ad608c3862e45d05a8db874e1121f15852eb461a60c9210669c1017c0011eaca0ca199e40a30c5be88046135da4018c14c630050e56c80628c842051ba8208a152e51645c6ab00498f38335d8208426b4e04284361ef08432c250f1411bd450c5145816570e4510210a0bd4d0061b4626b022180923ac6935e22203192d54bc210219a018430d6584410a695846b09950ba44210a2b37800205698042ec821162142a54818c36aab042050bc6403941c389d1052e6431861764b1d206185e94604518210d1b16a4decbfabdf7de7b12c2c3f70ebf2082977eefbdf71e7c32633c31a2b0050a6b13e4032a5d3c4105295694f184dd8205c7af9811450c3588e9c19629b618014c8c3146205a2496299edc08c158a3a98d44803a851a504b1445da36924a1cad465b5ab0c5898a21156050a102c31755971a308a40613430c3d10b9ef085172f35a0e911c61557c0e841952ab0a10756ab111859d842821448e105625040c50a2b7038401996c0062aa47cc182302245803480d1042b8c80650c4c48026481bce1053ca8228b152f70d1061af440829105e392832f58268aa6693502a306910d1bbdfeac810bece109517800032aac31a60c5f148d4119815164e104c10555bc84e18515c27cc10b27a8b456a32fd4008316d8852384018330a84045095bb8a051dd64a00b56aab0820fa2a00627d8b41a7131a35fab111732b20cd8600b5140a3084350a30b2c240f6dc2173470421654d240041e70d1c14906688489418c33ad5bd0a8a261eb16314c395529f7458b10cc00460d46d8b2658c9468c4858cb7e37a4214b0a0400a2ba66cf128aa0a724b169eb8be3843d488a84023096c50510114535af00514aea8c123f970860c5840c50eb6f0052bbe5882f4c20aac3288811240173258498312ca88c1174617171d9c7408000a3500a30657d2a8c20613224c99e2053650c21559c8e0f2a28a9883c8045d7cc1850b5ab00005507cf103ed8b1bd0982106d7ea17b04881862bc0400c2fc4e00b18a01106478f1c98800d54dc80066c5c417592235136fa0514f14ac918b7235318030d4e6268428d28a019a26808a7409b1e86a0c50fc4e04114464ed8e226379badd5e88b2d34d56a54061774b7517ca3065425590c47718f230f8cba7c31e30a962c5ad8056ba421268cdc48704f5b859be093ac8eb21c6000df7bef3d8d1ae10f155c793a95655996655996bcaeebbaaeebc228abaaaaaaaaaa4a4a29a59432c32ac9a9c9e2986042bb2a8dabb42ccbb22ccbb2acb22ccbb22ccb92d7755dd7755d18191bf54583faa0160a1b1539a1d8318c2dce335a3f0697b448115965e1c8b22ecb9295655d965541595997052d08494fa7e2b6a753ad1116190735545555f54a63c9a205e88aea301a35c5a9a9e298600293c7380ac3b8aaaaaaaaaaaa29ada73829a594524a6bad4018d7a8f5bc5f5a5fa44898306a88695dc2a60dbf64b41e8ea13ef4385cda9e1eeda266e8971f420815421c8aa2288aa2a8f3658c31c6182f0588299ebf9124a72658c90a56558cafb8485191db9e8ef51887281864a89bb5f6722f0b30cdc1f4f1ecd7a4c70ea4f5dd8fd657ef48407ea84e576a385555a7db207c576a6aaaeaf075aaeac0f7b634ff32c2f656232f70d01858d3d08f69af1a06724c7b2815d1327781a2a036045ef5df78270e818f3136d15ddc369bd5d9a9725bdc1c8e6c60f21997a40f2d7576455a85626b25b9245fc98ad472be0d637b1dbb243eb4fe6d189b3296d6ef1fc757b8a46f7d0f67aadcb22ccbb22ccbce2761188661187629404cd8d994716a9a192715e80a26b00f814df9744ccf3ac6597fdc62435c7c6a8bdb9e0e13ae3e76db7316ea43ffb9616cb0f715574e7889d2fa45eb16266c696c06d3fff1dc707d108f275ecfe4f158793c3dae5fa3c7c3d7931e0f767dcfe3b9ae47e2f1ec70bdb97eb53c1e9ced33d717793cdc55bb7eb33c9e9ce3b8fec7e3b1b95e038fe7c69587eb17cbe3a1b9bef478765c3fc4e3c9e1fa251e8f8ec7337792b81c66910f3d3c00cfc1cd5994c3bc0eafe178289d87eb5c86e36651007c3cc7332e6716e9c03de716b7c32cf291e33e5c7237b388871d0e80571ccecc790ee74e7137cca29b1bfeb81eb36807005ce73cb8229c6f8fe3f0c184438fdff08d2bea31a9f4602a92798fdf1cbb9954644c3fce2ce2f1ed374c2a384c45f237dfc1156138c7711bae0807c76ff8cc0d9f398e49e5998a48df7e7145374c2a3e4c4535bf61e6d823573433a92cc05494bd0736a9e0988ab0df1c6752b13115e13cfe0657d4430026951da622eb37f731a9485311cedf2157f4441191c98749654d45387ec37b98542853d1cc7b3cc7a452632acaf1ed3ab822004c2a37a6229c533a934a8ea968c7b797ae7145a549e53215ddf80d3c4c2a33a622ed3dbec3a402c45454fde6345cd1d46152e1c1548473786e52d13115e9f8769d3b734539930a9b8a687ec39f282232e530a930c054b4bdc72cba70dce6375e739a5359538fcf4985c75474fd6616dd9cca9a38ae086716515913ce7b60e7e3c015d9fc865984c3e33b4eba8ee7389535ddcca2a2a2a2ed3397b9f6ec3d8fc70eaef474f4246e88a7a3d7c12df174f439b8bd828393dc8fa7a3bfc169e0e9e86bb83d3d1d3d0db7589e8e7ee3b6a7a39fe1803c1dbd0c57e4e9e8356ea7709be5e9e831eee22c0e89a75365b5505ce482e0983c1d2b4f47cfdc1a3d1dfd724042aff7aac5a93be5b203a3167a0db427750fab368404c5c7ca2bbcef5c31b6edc2253e7f4f8fa7684faab3dfd3128fa7688925983c9e22264c90783c45482051e4f1141529a281c753a401d5d96be0e9f08b86783a5c1444103c453d4f878b8000f9f1788a7efc283d9ea252a9e8273d9e2212697b3c45db261f4f91549dbd2c52d561ee9230972f9cf0d23ba5391af53b7a3a8f8787c53c92f2b01a4f478c0d62e15296232c665cf962a54b15a3295ae2298b1a58c45c0963e5a88a1953bef4fb3b7551c3a8df59ccd379e729d2d2ef1ce6e9bcf314c12c4fe79d8fe210faf5b5c506c4df296c46bfa37e1d9bd1ef5817bf422c95e6091467929dd24dd8e254b2533a3eea3541f311efbc2f95d6de2ebc43ea37af2db6edd21a8de2150c3b972f46eda3750b19aa34f6b2c76d633d9a1011081dff8274227895978d3af3047ab3ab70baec076ee5d25ebf4f03622754ed2c9b1d93ee84207f811042082184f025de811042acd28630b3622c770f142f3b22b9326a43e463a42e9d109d1a02444fd507de22668c968f5c94dfc7647b57a0d8110da1f742c8e52a2f1bd05e0ea12ea536450901d20f3ece6ea1eafb8fcc4aa5386c6a44c511dce0a9f8c2d88cca4c08b6e584fe3dea6f462ac208a9eacb844db721f16bd4dd5eb9a45ca2ce645b20a8196767d3baefb2566a61145bc8701a83148dcd6cb77f13e849ecbd36b55e36ce2672249c6fb23bd8a5175e69347a0fc17009285e76770513d584464f67cff0044f700ab402ab1c1d8509a38618a335eab25dcce8fd97f8ee0d14e793d75dd5f1dd8fe61f524a29a594e703a9aaaaaaaaeafc9eebbaaeeb0262bace0fe2f144b14a268b64b23e459aac5b967529404cd6f958c5a9e9e2d434df15233e356c8b7b579ecefee22207740513d610161635456e4f5ddde2aa476e8d1adbcc1a424e2dbd597af914393ef53b1d19d97407bf5c6142497df07b7897b0bd736667d3db8c4d498368c3cdc4a4c8a7d64d46d6b1063e2959d6c7bcbbbbfc5d7eef1df69b42dbfc45821235a1051b74f981108cd88081a923b591172de8ed46c7977e6c8fc702305802145dd4e8e20662300149c22665ab911728e8d8bac58b2a64f0a82ebe29faaa0d3910ba3a1f13c2a7fe38cb8b4ddfbd211553dc7609a3398b3ed70f7bcc5173bd4ca0f7770fc3c875f0fae5776a02c16f9766a849e0fddeccbde1a9338a7b2b7c0f474e1ba332d6866c97866f02c16b6faf06447cfb457df07ad17ed82ecd7f3cb70b97b6a9856dc4afd133db8577baf7b8bb72777737ca18cf5f4d48c41e10752e58a0d1a5562e5870694c81809a1038d70b107ca44eb42d9f7cc575b0ab3f0de2e43dd6204e98578338d9550de244d587bcaa8fea5593a186cd35790d5f715d47c10351e76a02bd6f97564d880d630750507caa029b72c1a28ade2efd2ec486d19a04f870ae972e5e6cfa7dc2103e9c406f6e172f5c7a82fad0571bb380694ef7be347f3768eb7d5084f0414d36e849d55e905093aae1b7557dc4c7d935d931fde4b513a20e6ab26a34bc90ecf8b4c4fcc8519c906ce6b299d1ddaad1fcddb2eddfd1e09d9dd2fc15b309d8e67b811d21b7ea63df83c106a917638c58e80803538c532a8e56a323a4619ba2490b8b8aa2247c56f56e588218c660830a2f5ff0c285065da8a9e92e9081832fb0b0c514635ec44145a4c5142e98208c9834c0b8410d0dd1133fd8c20fc05042142ff8c1f6562e5398d1a4562e54a0400832423845121a363c8450a5e4a09c50564b7c708a42064a50430b15a32d5ac8a2906d3daee840094aa8c21652b0c13b15b56c7bd2128c90032c94b0050660e02283351a36a402050d490d671a425846182c00230a6c18c210a66002a2ef902117524c10c29f4b7b9b56a3237811c5d8045045ca0036c22607474b19c024c95133f6743a9d4e1a99a0c50abc3891023174c1d46daff524de9179eb8700f278a0499bc0032a560006192b28a30a26bd269104484d1561b42009902d68386add92061a4d80d62d6910a1f7b45178e75dbe87bfb494d5e17c560a3628ff845e5bb76e3d3937c8916ca0d8e01b3eae93fdbe04efc4a1b66e694050d3668b4c5010a290a804c916aa93a1a02449a7149aa9194d0312931500404824160b87a379206aea0314000e91ca5850a58ba32805521032c818430000060000000044466ac62600001083db6c223982520cb51016ff098b9c219d615a8eb778573235bc4685610c9fd2d0d56806bfcde13e5239c6f5bdcd9e4607563dd19912bbbe5d2af36d4f460543415f03526e6841458c06e4864f7a284cd90897b4fa46061ed8edc716af42bbfb35a478560bc63c49dec6b3a742e6d3930ad39aaed84b711810a121df977e617edd8bfb58eb01fe7c86304456db0d407cc9ee1e52f46312d2930ca4c2b63856564bdaa02bd02572775c1a35c21315e97f7d801618685b29c7795cfc1334a5203355d0a1a95339d2eb86fecde494efc8ade8d179d0a25b69792554b00410854de09bf014894a4131ada03f91eb44db7e0f57f88eae0eb5a5209191512aa988001cfd5e29bf861af86ea8a8c022927d65f0e92869fc65804f6a5cf3c2fd8ff8de01301b31bb2f43a1c374a23b77137d9f765565697c91a7db76f849da9ed81719aff39b107b732522a7f6ec0d9c3247466b5f5d306360f6df124ac9c6ebe17833513281b3cb8db20a0f039d0bea0e20491f994d8d01eb34ee8e3fd100594629034f81216f22bc1d2a453af266d148e6a83f442239558d598b0ff668dd300fdd62e1fcb3157acdcec50f7613a1a08eb0b8edfacb544b6a45056687e1a201007003542cd9d9545ad2f422bbca7284f28f3630da8a076f3760ea70e060b7be83371ea4e81c0b48d236f4245465b1d732548e8202b814484783cf7b7aeb4f9748e1ab8121d6fa3c94fd2a7fffeb68f4571f958704fc8124c1af25808ee61c2428e4e6582ec05db33bb647f2c9ec055d44872904319977e9309ddb1721e97a92fbec0ef0e6d50026a13bac7b37ef33a555ab65b44c82c266ca79a45b351d10239172f8e30c7805ab6155ac73dd136c9feaa171ecf38adeb3ef5d080284e971893089e6b51b2e74d1384367307aa00f4e0d1ae5f6f1516a4c75b2c922b8404250f1d399d5cc6873cdf0f9fe93e5c617a9ef47935f373adb542aab185a726bb84e20869d7b0e84ecbcd1e70802dc677525ebb67b7b60c4980aad71701326de07a7b1c5c67b7baed1679440b916681b8cc484fa49955817ae48267e4a1211b497f0eda781bab1005c9e67453045d49515cbe8e6f6ec6c6d367679545c4a17475e58bd1fc22a194a0360e82dd31e4e8d40f6293308b958ead59a7249fc6eab6fc839e729047400e7b5a35edddf2b34f99fcd7d95292c7ab9ab883a334bd139076c32564397f1605cec2820263780a688fdc6ff85e2705d9411c303d8966470fd3a5a80ccfcdd3a817f3274372443b90572a9c374ebbf1e4d6f43455cad7f14e46bec04a1eb46736df02a984eb60954618a1837e42d37c1a05c41bbcb3c10597ed3a5e624b76f9d286836784d053164368b96054baeacd9fc8c871f8417010fc30cef939f0d5b19cf083c35affb43687edf7417d7bd7636c126108d0986f8d4dd4ad3a105a6ed9a5c596f12b9941b77e2b7a5e95c87eedd8773804dbad0e68c0be13486bf7d9807e3e531574c0c1eb72b0fac84b1f772cc9f59f78c0ec91c2f0049f43599e79bcf90905c46b3954603a4d10c46430d4a15d19d93b6fed9513080de1d3532488741d0d23a052061d49b225a97dc6c3bc94c9549ade843061c25b781c8e4bfdcb705e9197484495c5daa1478b0d40dee83af061acd6e910b48d3896cf3f1c4fe46cf78ec13f06efb5b9f09b2df503d32c1c065ef141ee5b17d567d11bf03b608f0d6027626185150b2bbee30d3a549e927133bf8c58e5da339094ba064628d3a9cc6dc65a91a1e0469421af481ccaec69455f02e9f79bf027b3d17f4ff22cbac028e51c7fac7ce385646a9580217aa2e5307619c9f6c133a089d388ea5f1cb3ffa0e8ec808fa24dce3e32af9ecaef6c528e8338eb9c394d04c543be8726dbf1d48d7b2e340e4145e3af1c5dbe287108f152f69c6566f9ee2b1721dfb15fc0e27d1a17fcc5deb041ac7cef7dd9454fe572dea014e27f439ff0edbb92b92e8539b4494bd4ee5fc73efeccab7babb1004236b21496e2f55eefbf1b4f6c0f154360062505573141b5d07d0eccab6fedbbefe566358d885263568d3a5d969d1349be939a93cd0f272c4a559fb1b477c431826815f52f7777a924bd2016524094b9e89a1b81de889904c2cfd550f474210e83da107d58d4fe5b09360dbe667f1fe2b6c69f40c4e612b781870c072522ef2d163e304af580a9db6ef226192b72bdd25b7aba377dac730492e7f936cf9a1350403c34e20f3fc369f4651b3d228f4ea8f6690f9ba40801f96ca972e6974bb7d1b4826d1d4f59bd2c23c1feb0605c7f8ba0886826acc655b2ceabe03110ebd5e904bc5a491c28db616efbfa59510ba9c7eb4e3a9d1061254a08585be769a2383c0af9de8b2f1d2b7dc38ac0b01d3b9089eee65d57d09c4f731e557b44871dc5477093840113f44ae9cc21a8f92e0c96c95cd2a7e06b9c69fa952691ea209a9f30d0d60245950b9ad4bdfe87089db085a7e2c8fd18a10325ecce925d91e90a66c616070445f2a62d231b4919ebd0bcdfde0ba725ed072d947f7de35dc814fcf3ef4b60399f114995801052f14595078d9634569665df954300d014fd9a2a5ae5deadc022502a24b9ab78d3ac4745e2b5b5738a72617a2b9f787fdd15829f79e791025b68b7888f58da53445656cff2db8141608b6e4addfbdccb6a393463454e0014f3bc801b14319dae38e70624f87bcabbd1abcf6eb25aa59d0be2069aa0714ade2053bd048d010e58008759d9d48484f5aa01cffa358eadb9d09fdbe8c113ef7244f4207dae2905caeffe749fc51c92d47dc88cf168868e6094a628ffed07f8c1bbd89f545daabf711e57f190394560748f17f7fff3ce4386e44d8f12687cbd27a4f8fcffdaf7e454ce17c392baca60d5ac12e16630eee0ab224ed4489e0ceb0484ab2499a187b4a91ca72c01391971f15e8bd50814fc8c7a91fdc8f465e72714e080b9009e1dadfb8695838e1b5a594b6ebe5123928661ee9bc75374dd48c46b40f586f78d4fd56de5f12248bdebcb5c669d50c18597a957cde0043b05975521578633a36ebbea6c86461e0e41911cb3580b04c13ffe6d9ff81dc52aa2a7e807130e287fcb245b8ca8edc7e81032938acd2f3c7f126dc91aa5df69cdbbdb5bc330243635030b0c55162d3a31d6396e8401a70c490eec7aac858ce51b10643b811a508c7ef1861bbf615878d29d5c6cd8e96fa6c185d2f68eb470542d4b1e564080af3460001c21c0502e671e68f8503d4340299048e69d192a605902ef41a7702d87f7d08999152a674a53767c47d29dc8fca7e92deb7e32fde0c05dd73b45f3e1c808e7cf562b4042277657aff053a973294a5152da1a58b4ac9d2ceddc4fb99a6c277f96c900aece3168b73cf08f8fc185d89b9e56ef3075e6ce2c43ddb2de6f0851e3bc5878b8e5baebadfc887639df6040eb8b71b185ac0463fe25f97992e4264e78d2a4484c02afd11f1807374378f2070734036cf1eefe1a6d71513b820c0dfc08b9c61230839e00261c4a0f7f8c4f191c74adc88f5c49cf4b5e9e50ddf28564e6eb845f8a13c3321911b6825f3e8c6cd95d234f9cc855b5e869af45dd0641813b884a302d2bb0dfa520e22bc29cfcd4e96d6388f7acf6ede8681f360677b418355194f60e5d489c1dab5885e1520a4cdf5455f90c9d4effa188b604ccdbfe1867ee9387782ba7300681c10d3e542370ea06537d6f53f940ca61242186031c3ddcffa36fe3447ce0027c41562d3cb73b09e9741d0479723a751da7094075920b9fae98e973f8f99dac9b181731bffa5061d620bc0a202681ae35b3734b824b3dcdd44ce1f2bbeaf83ef0624745c0f14bd266ff5464655a03721e54e98c745053621730ae52479cf0cae734ecbac294db1355c6e75b4e4a46da4f45e846be74581f99ad2fa191408558653e64d3bd0558907bcb9d9180ed74e21406e08fb3fc65644e37ca670350675dd8f3e7fcb10da18585206a3ad311c256a8c65a5e60ae20e25015dc712ca8f3203c6f61745da5f1b63f520bf3475cb382888827fa537e45f03255e098d06d5c78a70a5321e05a0fa210b78ea2a82a79eebc7da67f75ba5064c6895145ad96c15d18410e202f15dd7f4cd84967e53d78d5f51df11647a118103fb2fd99350797f135942c9019e7429a109dd8c3806d772c3909876d2279f0bcd4108e197681d543a2db368f0ff2a12d41bee4f82a8543f82386feb91c866bf78a029c85313ad717a9d0bbc2f3942d8ef340fcab565dc2bcb516614305e129455c0f8b1964b54715e06046a6de229ff4fc31121920a7d126f4191e9b9948fa3fbf30904f881a81886d5dc5577e9b1ca4b8d3ca20a9c4176314a2b89a77dd4dfb8de21611ba3c7072ea151520f7448bf3a990ee12df7326550890f51a93a241263bb430558fba530e7048ea62b70bef3b2af62bbfbe7bc9277d12ab492109e77e6bfb27f1ad946e35bf020b876a26d8efe39f7daae2fc6466bd85e84202eb7e020e77503b4e30a158c3cbf058c9081fb9a05fa344c5087f4fce286e97de6fc83db07754cac85b8aefdbe816da0c749ff0e0521e245ecf251dc6ce71c43e0b8e106b9105b669e3063eded704626c66490492662fe7a0e64de0b3f46d07816710aa1ff66af466c4c8d59aa02d1f91956be38e9e5076256e24b65cf329b7574770e999ab51b869ec5a0d04c0f13d239ddd61a51a632b64193f39d4247f04c8597145a6c9e645521abe25041018aa1805314c2ef28a84f144a2ffe46cd04cb29e1eea16227e40eec1ca2e4e81deb6bfa239aa767aca7698fa87bf3b6923b855a066d4539652457085ddaddd1e5873d0d6f921059264dfb7db3deb3fe07e4ac54da396665be42f4c4900e9228b30015388b7cfc8e432c121f78622cec9131701e990637d5a407c7aebdd5ef46912f1549b9102373c35178fcc64ca03f8cf128b9ef5ec3ba7b49c130a4ee82d458623c1566abce9d498825669369e3cfcc64dd4e13240b49b6e62e488d25c6bc4bb801bcdac08c30e8437fc09fe20636600926d4c6d706c2aa0129940cce1c9a0c3b033419981c25d2b266a7019281b901786c11791aacec965093f1d14301d0f11ce17fd715212de7f8d09338261f61bebd979b7f049b02078dc67ad476630ba9798b347566e7b4b06e09026986b37ea7b7c01eba2079e7cb3139249d61acc2b6b5ff37a3d98c482aab62bedb391842a09f1728e70229733487267b454265142d799d6f2adf9a2a6afc462c9ef516290063e937795938d09b2a7d48b81f0494361ee7e8ca7ac5f753255e607c4b511ebe51887b71aa764346e00294a3134633c4c1c98ba02aa9aef5aa4d41ca766020b4a9802569406cf43c2c6d204ac11843e0f34ee14a34ca404c0b0935c652afdf0eae66479737fc9ee0b3fd27cbcd758f883445ad4e122e62181e944427952cc7effd5b200a3f413a036144e1595b2e9a042addf704d6613f60355d2f9cdf352a08a543471f3c0cf692311f164a0c8510348d5f108d1784f983b2220fe7603b10cb70d089dc421cfcd3a75f7812b757e5317be07d6b5bc94b6ec380b676330943d355db72ad61181068405926f99a2e4503648eaf54b185f2e4e563c24f852e2279c856cafb789255e3ba21cea9e33c8aef7a6e203ed287a1c6920401ecffec615556a3779f97f6cc9953ee502d0ded398fe34f315d461792898f6eec396042d7af6f78daa2243fbe7c110856ff93ad813dfa6e3489599c196da054a7e572d2ef51197c2e57d198790039155da5c7bc2e47b03c3073e187a9d6222115f3b9f5088230152001e5c3e1306c7484a98446eec2a3c7aa4b8e6b421068efe738981c084158d81816c081a6fa5fba8d4033a01db2f29a8ee1976365163de37a3111516ced1d898d5554f4e1f8562dbc0ed59b87c4d9c2fe4ec1ec146ea50223f82e6114f63b36a7ac54834e159c9452018da34c6c742296a994db586eb9e5f3a86cd98bd1ce906e29122c8723521564133e2c54c01880d0980d8fbb4e87be1235c6e45caefb1809f6d991344a2abeef5195221482e747899218651e5d038bea2634e6cf4cfbea1117c637e5d8dae0d601e5ab8faa0040db10ab936cceb56585be83215a4df18cfecb568724b78467d10989b31234a922f7ca4ec8d68145b54b17100fa4dfb4e87bcdea2ae557b88b97c533dfeae13453861acb3e3a9272d14cf67619b1bd196ca6168ffea1016d10ee32f238a8c693f7b1740c21e8b1ca167ae2d0c0f0078ccc1afa5af98dcc7a9f3ccd850397610373dd2b6941c8899d575e27432d6c39f7f8ee87553e7f445766e3955ce3d664a4fe914103c7dc70ef865bface63aa66228a5da8ed678c05b06243965842981ed05bb73393a661e4c890be57daa2a50cecae577b35b139836db7747c3497eb67b9e871b896d606b5545aa5aaecd95a2e88e8a2b415e3a39b31eded1a898ca2350e4b0c6469ea75efaa91c661a33dd1dfc7fa9eb0a824641fbe76b246ac15e5e46a850c2f401e5b1bc4a59f085072b721079e05680b7ab751aa7c8c001da232740456dd5508d9242574d24f83918859218dfab910c189b66ef0f718d6e4f16732dabfb6af4ea7e4d2f83319ed5fdb57a793e7a7c9b876f8dafbb6f7efde6465541df8ee85ffeb076ce7aedbf3f402348d8e767f6199a611567cd081254b6fa5b5f057e7a6f7a5cb7f616207764540e89e8940d2d421e51348a2e5485322742909b6d173f168882c45e70b69d62c0b1d837020b1a97046888a38ceb23db76bbd1c232b6eb8f019f3c43806d55336d72a33c8741ec407109b856879913f181ccb91d8c9a0fcb623287b89493805eedac8ba2d50e9e3e4df427c1eb7df0777ab9728fee76724e361ce01382dfc680cf0f424dbe16c4c095f85d1aea9a5bd338cdd3bb6158a6a34ae07070e610b1db119d346727c067c9fa25903fd5217060ae6bffb16f89e9f012a5276a060cc05ec38549fc7098c172e8652543b278c03815f53bca6d8f83c2bc6e0ca51d1a2863a8d52c138c2d2f315672966211d264c7fe1cae6ddfd216125756f9fff359a410e0e190a71d1bc55b76c12be7275594fa3149d2445b27827408b27e0d35405781572541df24b1f9856835e1caa0aef52d954b5b5bb597dd740c655884a7eafed43193494f8eb92fbe67125bc5c58bdf429ed455346c90135e61d1b9a2be527e9501ea7c3c9f4fce8b3cc3d1b2971c946795072a5df2c4f497aeee835072ebcae4c6380bf777999e6d54ec20d5378c6737c862bc586b968cda11c59189e3590dc0593a82c82066b026791fb5fb388166598a33490434c6e6f9a8949b71b226595d3ee8cbca87e7b97d9d37b82db74266da7c30b5e9f7bd7ab670ce41cba500c8d554a75990e6bdd3e49bd0d70518ed188633c69ee988ec2d37143c9ffcb63a367c5d82915a49554352e952171c91b129da63ad979ae79736a5ff5b9e5fe9842ba4a3e5ec8c7500ac8aa09996f82e52b7eca1cfa3524a07182ddb1b27a9ab34b7cb3caaa1940052e65b7cbeabe1710bfe47582ea56ea28da9e05abf067b53a4856984e7b3bc175f9c175323d5a8289d0a9fc06046fd029d71bb37d2e6c5ca4f760b882055b1b545cd27c685c77db54a05b7319aec0818a630d54d2d6faf91e3784ef701254f85857b837921014516caf523ba7cdcdb504c8f5a5cc6262f2d81693485df1df52d53df69d7c9804d34300d0be58b254d3fdeadf235420d7e2033f70bbc05df601d1f20a1d4a1d988fb1906d87d34423541baa5e3b8251ee26c601ad5cb52a38e5f96399b30a0e99861ae68b55cfa8169e9594585cf9cfa5cc1cb68ff72e47bed481f0197be32ecd0c46d5621064d276028499d2a1f77709f1de7beccbe854e547236f2629ae71f54d8ca422d96fe23670f54112841134130a875ce4027c5e85aed1622fa15f1cd121ed00011b40d82f0160074e8331761feea41fe26417e5c923aff5949ba4965d3920d453a1d066d1d7421078e51b657d56448377f4e3f15c7c4ed04239279e1e1b838eddf03b6b8a7a7b515ecdef9bf3e515e8d8264818983ba1d0afb1e18f56f2704da6596dfe125d6fd8d040348d04edc2ab07474cb77e70e597601dca13887ea16cfa937c4b08630d21ca945522fd3bb8732f8780dbed9a71c68e0f3e25939c11224e81a3d28040357f3f463f729a0f736759614cb712f5824e6afd0a4e2011f63cf72091818a61f09ebaaf56e9d040264fe9e12919c1ab3cbba00d14704f18a17df24668f8b6912704c1fbd6a106190981fbdb1c44a9304395f98f9e60a4296eeee0fb8e03ccaf8fb4e73bc4ca128314a88b2b49e742a441c862c653b7dcb49fd06ea6541c1333643959c71331d5d80f24cca54ed3f8adc3f97eb7a6aab60382895290b5f217ea2bfffb59be358d4fed305b515a2bdea41bcfe1b85bb75ee837945268c535fd49593ce9baa0281793876b6d3eee3362082c6362b14712a283ba30394d9f648a193b537bf78ed60c7b4f8b9550d433ad2299b0da8001c063638331e27362efaae6488cf1cff13e69b2d21ab48a43ec62412b68529f6c6b075173a83f3ab5528b1a1ecb5b208ac2cf59d95d85b911601cdae5be6e38d888c37a4cd91c5ace7dfc5c06dfb549fc7e0eecd022d618edf4dc9046a16810251c8669b535deee1a2862d44223fea12a0233dc002477210cccced42836b898c39d80edef4c21e9b20639c81217a04d93b6127b347e2d2bf4d5c1baa485cad0d24891a5301159dd0af4b45958737ea4091b8c8fd8567d0c8b8092ce484913dea8f6836f865f5779f06d9251d132c595b208963b460df17f3edb01f8c05c01c5cfc5cd0034f2cc30b5942372e1090d33c67333f7494354b632a288203564ecd2aa8653906d657b2ac3149e6015b186fe538aea52e52790225854e467a5c863f74fc58a29fb62eba5bd4d9780bb41c304a524e94a51e13dcfc9989e70207c2a75fbbbe362e5e2bbb4b8816f9c79012d3106e1981553c1d75f08d0bd02a25eee93bc7df37989771d8a1e73c196f185b315b2cede1f7d1b359dbd80acdfc6258d55e567397416d4410e3844cebe22ab17c9f831019b06a8cce86d4096f7a74a36ea407286fe54105e7ca1f67a8515928c08ecb20e2d848fb1e47acf816a770bcd0ef62458c3b246e82b3435f547f9c2afdc905066cd3511b284990842045c227feb724d1e3594dc8f261d8863b70a9d57303aa2dcd151f0e091117ca6a91f292a8daa57cbd469238c51aec4836e8aebdaffc1e92d773cad4fe1e8c0adf0cc7b8980fe393d2d99844b9ef34f40b108a7f1eca711c6dc28f06d4db492132760609911f30742f98caece4a0ad90896ca6ecb9fde8473ac2fa58340c248f656a8f51b3829382f334602064374165eac56e60a1b6842c8408dec99162cb1789fb08b02a2ac629e2bfc4c723ba0d1885cff8d3b569b9402d00710b6d3274b1c5bd80c90550f064dc0a437cadf12cf636965ce48033a829732dba6390e31880acef4d833afcccbd4ee283a1385849c4d37040973982e6146916ec9b5ed08f85198d30f522c015669d1dfb97aec20f04932d7c81a36ac8e161eb8d740c84789f852b0709d3c17b8931419890b32ad97606581f07f2567f5bd8883db3ecd49a80382e4c72dca460f0a710597984612f418b5567786b31ed0a173af73da853572fecc080fd19441c736f7f97a038978410563351fc26507a9e0e13c0513a1824d59d0913a616286bdc2d24d7339e05ef17acff30c3b0bf4c77dcd4f3b6b99d75e656c33053821f2c8d3565109b5e172e6b85881fb9c9f576e164551a07858a40a1be6ec2c2dca72b914e77e1e2829d986ed518361c482313feefbd92f5ad241cfdd2a12352f3429d798095b86a69e8116bb211972007cf9a8a4aae82c7f632a4f736bb6fc32b542e4303b64a536f7198a0f520e42a0b62264f393895548daabd63c56e2cbd5099b2cd3a75ee07af7076ad63137bfa5076dbf59f3830ab585ee2a1362c76adcdfa5894696d10029903ca14b876d3175285c6cc75086a1459694b6dbb0b7c827090190f467b13cdfe8e70d7a9496c85e95f6a901763d65050a9dc74732d774c35739b769a309d83dc2efe807aa0ec5c0815475ed18fde41cf690731cb420ec5c61ffd4d03f975edfe02ac3225651374be62aaf1a93a185c9d893e401c8fd750afc876f03d463ce4efa47a4467a99ed3d17ab9ba82187a0cc160cd3a174ac715978963e5cfbbb2f503b33130caf24ba776d6b82916b92788e036c54b20f7e3dc8cac981aba182721d2107d7982b413aff014c8a579533ff7918809e835f26812bfcfa7e2cbd38611d86f9940bd8f39a7a1abfb1ddc2d4cfe87379f37d6375475c4027ab62c8bc879891159edcfdbb70cf3c6d964f524b433bcae724811ca59ee399be3c50a3ef45e6a7c0de4625d57427359017870409d5205c192e8bfec96ec3a3140510896ae507cb98910a78db6a139ecc5cf0eb44828757b92d7cb8a3044cc184785b94de7e82e2c0f789b129f151072a19800e30d5a094e129b44f03bea46d67c3c4efedcbb27f135d2caea14b15aa7eb7c4cafc0939ca8cccf42178601842b2c3800a16c133d9ba64cb94ae9a29d030e85c54ddde0a63ca340ea68961c0dc1f405940657bf687d2ec4569a83f3d9a876a5cbe1d4098eef4aa152db45113d12eb1fe5b36c3a3fe4ab34a19e33ef4a28911985cd14e1a8676bacf68750a9f4c914de5ede42411e7eac688a22e0d0e8798e19650c2db07910d3b0051280e3abf09997dc13a1f41b0978d9f5cbd7c7965bfa61103f11067a4254fc5f4204ad6322d1ed84822ada706a9b71de646e8bf28f5f682c8752728c2589a2e7767f0b48cdcf66059b7cc265dea87cdb0c3ede9f6675ac7b9827d3a0af7829e76399897ff1ea4c0c8c349525f66bd3eef4fdfb3fb27e7104c179c318728c0cd2f8c5c1b31ac27bbe46bb1c76fb54d1f1d07b0fa8557a1ba2718a7877330df8f668375f03993b14ff780c1f40ae24a56edd3f81f1ba4494e605a2dd4b3b71f558ad62f24f22d2f632df7e2eae981be98a4a911364d0150d2f7da8bec71a31f3f641dd2898f1f8ddc12a4857387853fec394557c8907f1cdb4a8a71cea1a2a62d9fa7a68211aec32aaa0d9ec4d6f1bcb4167b4e7970fa0bdfa42091fb0ce6186ed90083033d64062534908203997d36125181829a2f717559c463a3e5f98c7bbee735f37bc865da66301e699e8498c6e602b36341da0a91fc0ced98b3ac78b362df445751e9c54407f43da4e6b3e19ebbb6961a70515a61439c45bf5209e7cbfbb240f0d7048e86397578b6a67bfd0431ce647d006d5975c5e2e50c0acca2bf018db62996386fe203ece5f23a5c96ea8dd5d5c0fa42b29fa2bb4cba93b18c99dcfcab656ccece5c3e655462a37b46bc99ef02f54f0f521014d08914ec416a57d0170624ed73788d4ef296a1d6a6b18962426016c0de42e95382b905623cfccfa3d82a4f1050c34f844f22541ce28d5a0239b39f38efb7b272fbef1b9dce653abe48dca91c785fbe1fa5e43d3f359d780000689857896f309ae7186196c01d304c9819286b0b15866e930039ff50370e949971fb5281c9651a6a21ccaccc5c2cd759cfa25de798a37b9aae65479df6207c4dcf81750018d095e64f5f706c8fca27826723d816c28fe195ea9fdf0fcef64c00e25707fbf8b6a22c48835c91c9c80b757810e7efdf5a2038cc00dcd8c25822a0be46cea3fdef74a5fb7a6d583b2e62cd54a6e66cd6dc541d91941d4752d4a5418346d73f681df7bb80178c434e5a506015a3e1358ddc114aaa67e335cc8071fa405cea7df90ee91ffc19ba5566967be07b5dac73585342a9900ec7cede180cec0b8ff26aa5029373ca0b3745653cbf4916108e760fb8cb2732f11ec2e1e427539f64cd98a9512e236c54ce2a8e721b3252fd6ad9de2f57c0df337533806078c76602138c4b865fcce42603889d7b6e6e201fd4fa2ac9e28f1b3127169989d5c527618dff8b49cd8510d2b8cda1270e50627ab1315151d3d06932a3a210cb8b512c3a93cdbde38e9baec60106b1eb04886e97ab362aff157f91a5f94cde3f6e6d24c79301e322841934d3d676fed1bb626579a2c888c1a5059c64f1201f7f1e90a1ee349432443df6607b57b3ceb3150cba95e03b1b280e80d3ac64b94020930ec1a80297295201198684d86da07b3499dc7e2b977da0ba4e20d62971a545cee90f3003d8a73fe8711130bd02cfee03b4d7a8d2e8d7945c93ff8e1c7c67256052b0eabf00044b8a799920a59c02774bc8504ef911cb4cb682d7de5cd628c62706d63673fe340225fdebb6dda136fd907e9b06e28c69db35c7f47d92ca4e454ad3457b342faacf1e89ef8d5464d0c674bdd29c0cbda6bd3f4379a45b8da1930ce9dcc793023da4a46ba806a3f48ca334c04a29979920815655989c9ca617c621e786a4a36b09fd611515e4367744510b6304323aabe01e49fb899fe62787520ef3b30294169f912ee6d06b30c6004b8a8a555e24f5d12531d5fe8d45387f0b5f5695e2633952067eed9edc4ae7b11ad8bff58b01d97926220fd5ec2a78b777b519e46907478ea07cdb463db27940614de6308f2c6921ba2a870da298f244568ed11b0a6e9ad1601bcd50f5414484efad3cdbf64078d85efc1bab35cc3d5ebe3d4308e57cf8b882a63a91041dd9dd3350ecdd30b1e0aa76a2dcad6d6096862de3eb00ae28edfda938de8335f4e01dfd9163d71f40380585b4a9ca2b6c5dee031472f0fbf4638913b87a2c7066d1950511b359296d58bba153012e8b53e5ccccb1c9500c07f593e9519a1d46cd384247c1b282c6ff6c0f4f077595f6419dae1835f7379990bb02f3f9f66a8d773c28468dc084f21b26ee788b30710becb3b5b80ba5a796a6b03b7c619755dfd62ccc16e5453b9f523639efcf8920561ebe94d0375bd96c15d367032c094f44c6abe1d2c1c055868552e2cc36375f820d7b17b2e093e0674ef227d88b6926799ff22a6d9128736550667bec9f1bfc8154f795d32af6e43d42f596636bce68f5963183252e717d6f0bec3bb291b34a6ce9c494b691d4a0304cd3898d5d4c7abab1cc4dbda5972620fd911fccfc80e963238afa4010735a9bcdb626ad50bce4a0455671d8325ba94a8479cdd0c822097c2d1b261375814cb81ebddcfd94087f1ce7712f3dcb8b493ac6b769e308699c71894d4142e8fa404d0d05f06d5fd318a95c6764ecfcd4a916bde3973e7e2d2ecce059013f1fcfa6b48ef0e66c251ba9ba6b5b4259b9ffba3cbd80821c07dcdd4b5442ed949991a9b61eaa7d6cb2db60a2932a08a7cb684b4dbce14237cfd0a2b9c2e30d35c96f44e75f8eb9690d4f07b100d5b22a2043254a84241c6e857fdfbf07eb8c459927a0ddbac5dd19d202a3ca545f3257a687036539b6c72e66d296c0e6f091f71d9a4265e917e598a56e852038e7280894b93de05890995e2c8e4d390116b64c24588dca2e01eeecb17740c0c8c59aa8f4fcc99923ba6b55ad94f936b978edc39ec1aa4c98d59c516e41df536b1c47cfca27c10cac2659c15054ff3480d2ef23b6216a3d5f6122b7fb85446cb79216d311b464827abf948f6ae84e47f8c100c1b6d32e7c3ee84ec6710eab44600712bc82eeb44ea353c5338b407c448e6ae3020839b2c0c12f0ee48e99b1b0e04877655d826be92a4cba1e27957a0381a2eacef8102b4c7e863af8ea8259080b10b6031b95c4a4e877c2a1e8d98115c993446cd5b87ab05262aacb141079226b7ae5ec0a055584b7b9af37583c8977d13aa320a0edb20e1ecb9f61d91c3ec25ff68994bb80e3ffeadd882ec59ad193ab05723a010730ff5fd3f6d0ef118af05d181ccfad78ef08492cc68cd4f457711e87a42b28f4a830b8b5e1d036aa5b9a6b4b9e4600f63ea0a510f4afdf906b3e108a52d7cd48b3a131244e889ae8bb8f695070613013af4296c7e1a963c378fa481eef690a97af035fbeb907acd4b9ab66b51ec9b5790bef749380bcc30f49a39ba287eb1066e944a6307c5073d2db8498f359c216645cc7f489e37f9d1018b5d0ceb88740f9d57016f9c43a916706e2c9b514c066492c0f94c5b0ad9cd56b80ead017ae865718aa1ccb9347e0171f2a744e06e2a5139a7ce1feaab8acc321f93f0c6983b4a717e346687f4222c1c1826f288c6696d2287307696e41752c01cb3c36098a2fdfb0c7ea4584fa9d261c8dd7012fa10b16d4aefc7fe4a586d09d1db1ca099dc0d3113ef412257b8a99fde8a561c1f1f4e67add0eb983b0832f669ba9da5cadc681e2348233fcb348b615c61485a121696bf54d4d1872260ee62a8eb0b4bf0d9ad3fa5c4732770841550dc152f9647938803f27b737c2fc1f5e1dfb1562fbb97eed8ac98d67ea320a47020bed4c870f655f4d41e5bfa06a768b610795013077aeab476af62d1a8132417c2cbc3f8a88d7648188f18dc6b41a0cf44685573c714e2f42efbf4014afce3f99de35d3349f4841de2b54607614a91174b5d503007df9f138532aabd78b154aa015dc3b1b98a0a96ac22e90e153a7c6c77a4a4e3754ddaaec2b70f2533b7420d33d4fe9b7e26e5eb708cff71f87fc8180e3eaa1aa2c1f605054d8305fe95a43bb29eedafd00819a81d6483c3719a56549f78025e650512849f85f6af27cf204015ac2684c7d4464123fd7706b7b77aef8c21fddd921ac35604885ec68cea200247c69b3a146e28ba7449df211b3b55b90665d261462f26bdaffb8cbb13071e934c5a8ee913bb13593c64a59c0a465d5005c1883de8d2c5c0533a1ed2318761d2d8047842627919c56981d6843182f9ca0c6dbcca22c81a25eea0d0e42db5705eae493ff30532099aad08d0efb07d021c4070a6d96b8c1953603b63da4f03652bad42c373b1957926102153812190e23e5d39a393f874713ed3ac5d1795537ac36bbb385fea98ceb1620d415cd2adc433257b4d85a2d4cf51232e24549a049bf32f1312ff8cd743fa954bd1a10a7bac744b7316a7396ce85f0f4366c4236ab10bafc4baa3642f86d8cc6121ce0ab68ebb375c658a2e25bae4f392edd6644a9de0836caef23ccc7a8b42c2ea920efddb1c71464b1f67f330bf97764a8dbb42ea4de8aa166b7d82ca5e5aed882f95b50380417e6c9657381b33720d98738e0e61791ba9ffde88026f5900e8ab9b935dffdf2b05248df79cd067a4073fec76c5bd40b72dba0790bf0598c16af67a835264c85b86a4d68930bd3143df9860e8f0147d39c8b212562da863b7966dfb7727db9cd09969bd1dc045af64d4230b75b07cf6798facc80ef57ddcf1570dc2a7966209bdfb437aa16a91bbca25aa74d12bc725d5db0952be994f162dfabc54b7092742098bd4cdf68ca7b19a9c4503732c7b24fca6b669418e479d0b8da2038a368bc07212e83390e3b5db0a9f5830c761395d3cb72abd3be729ad39f72975f9e7a95d79df254d0e597689956728216f6970edd4b872c2a149f32f48e647985e6a1338ea3b06177e640f0bdafec3a50946f71ac38b5bf3c0e667f61d8c1777014a60366e2441ad4b7dc675ae5979cb50d77f61661ec8e9a3fc63ee473518e663a678346e00d129efbe76949f75f82e650feb2da6553bc4d3ee61e0d2ca3626a2e6781524d24fb0da2697d187bc9b9eac4c71287d0715e2a611076f95738a24532a19e7b784a5abc825b0407353f68f2e3049decbf4a7bc71fca1d6db850f2e097eac9542f819fdd4ba69b816421fd2242e7c2310061a48e6835d3acb7bbf39d22c77cf80a44c640b26e4021f35c9ce690866e1149bc6679b000eec282adf9749f62cba21b87e77e362b85d0a8a430f3ba3c50ff98742f7490ca5c8a8974c87eb8e5e961d3cead7762e776a12aaa962a0a0f139114a869167905d79fb1051896f508818e22589e48f9a833046c18a93d81fcd4f426551c61283d3f39861f87e9285f3b517d1aa4074a82abb02190888c237f0778d660d17002641f04816b286b5ff00405502c7fb63563baf9ad64dc8f8673ef74820037f03bfd7c4c649a624e078fe7f6000ee557d202f02e3384a779b913bb371f2f062f296d3de20b129274740b466ed7b46e0b405e74814b29ae7ee8499011d868b04ab2bc9bcd82b61d74238d19cfa798866bfb727e4d4432091ca8e699684f3a1249490f3ab248791ea5bc5984eb9684da7c6a24135e0eb38172eb4ab604c9e288a8e73ff0cc48750cfc88832adfd19022a5200292e67aaa78fc3239972039edf567c7fc4c6fa4365a17694994274b036541dd804e6e25b61aefe59a6c39f38ada1e056978df4fc7d8f20289d53bb42a739109a1d358ede643629688143ea10f5733fa381dc869d51e664de302a4224fb4728e9f238532ec1fdcf8a9e0e432bdea57c5af90d2cb0c5ef1500d6855e0c6a2ac3fac7fdc0bb1393054224c549413ba5025618535c05d1863dab91e551943885f3f79a45144c7e54a87cb35491e3602186980402f8ac50428370f56b5839c27c3fd2e05f3743170627c4c607cc7e573d8eb1e1cc43a1cf32718b9769a68835127305fe823d001428e0085b5117314c46c71b8be27b710d6a0222315a7013399943295919ef73bc64d6279e3c69bba69b9f78a8f59475807b6a4cbccfb0b9518a13ef95265dabc32183634240bcee6a6d427a96a67864850a59fac234b83337329bc48f3a37bd5bd1014547e038cd4152c8b2e48e53803c508df227db0b5648365a2290ac85eb3f86ad2af83a1af6555dba620ff78229fa25a23a194177c69bf54a320c41c48c5c33c16429ecc2a631d898b52e6b13c32057d8dda72c4bb7f56d357d95c4d9b39de59ce14f59b05454bb354ca681909686553b0d975633f71d7d7ace9481135c4712c08b5644cdcbfeddaed3a99d852e1a77187309f9906e9cc81f072b65fc78d67a134db0438f3a1180a0a1c7f28b7037644c811b04d4171bc0e6cc1922709716fa71bcebe93c66c2ba4058810d003ab95e60f15019f6d0957d914c496343c059056fbf75f7a33c63ebdbc4b97c68d40add123cb63866fbf5d7be27d7d5133bb2a561fc04eddb6003efc903650703efc3de880765eaff4a1f1912eadb8c31f8bf365aff359656cfdb343b603b7574dc547c384b712ede4d1f1d1e0ae36e09b5f1befaf4bf8a809b4cafe09d774858f64ca6d38f3e74a8c4367c1531eb82e320e9dd54767159cc3a5eea62651e808738b56fa7df888d1b2c42375f7044b532c0a7d8d8968a57229eadb8ea3a4b78c5cdefd0de1c2ad6f03b45b56a62c590b84a66281edff14186063b39324db5234b405f86e0272a31daa286188c47c9a8ce748be1ef5181d6217a3fc2cd3327335668bf521b13cf5a030718b9e10d98f9043646750393e7cd8bb5bb4c84993a65b108c416f1f6354af1ec7bc1e071a306ca0c1a6e81d4eabe807b1eaba8fbc5b9a6047e7a95097b7c7c572afdacf17c94af7b55cb439f6cd71e0af67f58ef5415a305846cd0ec17c0c47f6d1a2cc886d902941288b0e0ace6e8f6ba6402a5e28c974700631fac676d92d90dc061d9efd9d5d93f93fa04a8e6827d4924efd39cc404a7fa4dddc5a7f6d366553156cb36f85465bd66835990a1954fd94db62f58bc47c5deada7f781abf5d31918aec475d48b816fd74dd9caa170fa6d29c9c41fc4e4b8b498ec10f97479a1aa0f5871f58010c759e1eaf92c2c6af2ce2791825a584846521cfcfd31973f9b43da36ee4a88cb1b3a6656fad0eb237aaf32bffe583131e861a7e35101a735dd6536f5774c715667893021fa2550a1480d88dd8f78fb7e01144a6b3966b3b0a7b887bdd689a286f5b3cd4fb3b468659cfc05e270cca35afed4137f7b21be9b75554b1077987346e3f02e5347991e6a86fbee095c6f5ae8e3e3b0859a448fb8a694c6f8a5d7c69aa555c678a53fce24a8229b38b1f98b13438ef435078f4a2cdd38c777f700049e6caddfc3dad723117fe6d60249a6f6127b4228a7fc698e1ee52f92c26b81123df0bd27764d01ff0a478e23f65815af1f27dca74b9541a06ed37183aee0e3654982c3c592c1892861aea26c4dd20cf3051c33e0512c01af10d9071cd71e42718d49909acea5ea1014f3943e5d419855c3830bc9946e6df7efc7d06be4ede2ed799e5a396cf8209164b56549825f29ad35440dd9932ad89c1ab9791f0e418f6bc29ac808050c2fb4110298404c5741005b18b4c0bc43538f0dc368e305ae0a1e8978826dd3bb3ac0a71d1131a9e0451ad5609874cd389ac40af09e34f218cc4060710b62a9c31841ad53c30685e010d9073364668039eaad61d5afd1b0f120a739d2656f066f2ae968d2024c2315141f0d01230ff9e0d7b9f498bebf1e0f0d791dd94e52eed4162f59f5ab435615cbeffb17f8ad53bd2dde0c8630580bada08830538f39b8bcbb9278dcd40580af15c91740dd261f029fd1b5c8001db0e69a8df079775d53d36839a4f1ebb8b6bf665d4273831447332cc107262fe0938b10bada9fe502889652093b472ab2670cbe2fb34c5e1c81b0ac0b96e0eea29a5c6618e49654b07173208addd336addf0c482fb142f6a89edcedb3974746c8ad9df9a9e3d90ff31bf9ba7c3fa58b55d454b433da7286e3bce2b1f0f822e0162ce8f6dd338bbd9d865f051ed8c10d36cefcdf26f3ea43efe0e9e99ce905bb4ee91d45debe04d0d85d06b2fab54804b3d5aa70f1475f8cd191935145e07a799823db0f3547a7018371820898e9cd2b49b8f64d799951451115c906e82f20e8c29f56512b2778b62eacf82effa2dd83d00b9fa41968aa36c678993126cf39badce3899db6a1a902601acab3fd29f93b5821138f029f4e20de4761337318358e3bd0fab022af12ac660040a96a8b9736b89a80333519bb0216577571cb4c08e3d0da5fa33c5455c5f3b614877f2eea9d9d1019f56e5f91ea666433f9491a83981d15dc68edec7127b0619d28b4624419b50ab9dea33ee774d00c41e0543ca217ce788b184a0beabd365db464193eb08e91c65bbf661d82b95a78356602b334123152376f00851e3319c5c17e73e7c7db7730b4dac91edd28c06ad5a43b8619f808c0aca5e59666548321d9189e00bfef9d0ec64ad11ccc3591bdcac9c4490221c36fb144005b1c131d839e750e7ba1202a6448c26b89b496b2c2a07640d92852cfeb2d1eb3dad23d3c5b981e228a5c390d695c8d12245693d27a1a26f9131d3e3bf9097a7a7e63337f302a51b101af2335ebd04a1916745f60d85aac4136c95e9fcb429bc7443a79a7c0ed009ec1c251159c806de6e9190a3087264721cc499310313491f0e4d1605a33c73cfe666d62fa60a56c75bb2b9b93ddc17058149a7e9c6ed63a3c938889b1305dc173bdf9836962d6d2035bade84766c2321a433f75aa4002425f41698fde427d0e25871902315a6bd056179162aedcfd8108d2b3a2bb58f032ec4b3f3a6a6187ecf711bf8bbbc0936589b0c30eda08f292f50d27c05b188bf46a0b30fea18b2619832337cae3df322ce122020bd33a909abefbf091b7e0fd3ed5aea8831280cd8ff772baac3c657b7b591e2bd0d42576121cb858ac071e0ab02612774d48792f1caf0cbd095d85901275533c89ea4e3982d95f45e93d0108616c153701fea3f0f8933ef2f9f75bc335320b54d04d3a111941c12bb723c393c8e554cfb28acb80b763950de6d0c9535560bfa5206e9513742295885b57b02c3f01597f889d0510d1d5403d6229cfd1b699e32404e1ba2460748ca2ced70085cc3f8bf1085da37981c0a507ffdd7b359603852303824153bf2a7107bdbf44a232863ba4641de2fb21a30bd820c1b106e046cc7adc5a319343ded1928c4188ee6e36ad38657681c67047fb57418adae004325f053afd92046b10082bafac25a00114495b1223e80292a09605686949548f00e49724aa1995e69c33ce637c73efe34d73aee33c739fe31b7f92e2c2dd84d7f41c9dd12f5fa5d03ae3a287627d8e84d4a9ec8d80e30c2cb347be97f0068f45ba9d7e1567b362088860e9bbfa060e68c6251fb237afe1cd1a958ab030ffa04f66a80cdab9653d0bc4d59a8bd08842d0a25df5b3e4d612792ea9e78e55109c390a02626add084a24e720a9479017d7e2d931362db55a9b0d9a425146923463c82642ec19eb0451ddea32709b3d7b48cb3332457074b66a4b9bb257424190d20a6648833d4c9ea5250913442914d7a74cdf8243e512446663960d856e3cd259670d0a43b8588d3b7b39091a9d5e25837566c998c769d0a0b280fb75e1aa9ba796d17c69e4a70a6a41d62170cd90aca62f44a0d6b49409fc0c722999b274fe1c8600a492ff7acc955314e19d50966155e8e45aa6c9477b4d81fdb8a31d448a03d22a11f2cd053e7f14241e8a35bb757b99ae85fde1a13fefc638502068bb59e5ca4dc49908bd3f32ea30550b3a8d622d918c67f4dacca0a6272094c6004fb4f4831ef1bae5c49172230260cc32903b7c6aa8f743e23dd9f12f8ca7931382fa1c6fc6a835c8aa68dc714067b16b581e47cde8317ddc110092df7d405a90f26fe9ba138b823c187ae38c72a776d8e7373058216704e6ea65193f8a545eba4ba3ab17ae6bf81ee8b347e09c8a0de33ee1b62fe0c5488efc9dd69a91a375208624e0c5f086fa9fa5208e00afe8807e08cd4e042d4a7d7059261807b099dab322fe1ccd3a2d2e470c2c5bcdac183a2b194b6bfab82dba17f95e3082826141ae295c9bb0653b6fa2028a984008c08e24efa473e627dad1e7e5b99309648ce12e278b0d80657804ad1eaa7a8d57043d9618384ea25caf46d0ca710c7193c3abe92af7741a126c0d48c4d9a357dfb0f6aa2c54ac1a4c93715d4cc523df80809ff7ee2d0e0c561412777b29a684a9df4244ad76cfd3e9161fa307df11a2fca83948704adde8fdee1f99840c2c79444742c0c6a537e8a1ae9de26e3e0249208b44758d6f68928994378f10459a1ae5ac486f9d1126a4e468644329e54dea7d0ca5da8e73ff672fb2c500331fd64b32762212564ad4ef301c73728f3e2c7860c35ab07576fca2e46d9a544b69a96989e022c61cf7fb44c871bb467997b69458a1ea2b98726ba09258e59a5174892ea0b1d8ba8318df6f54faacf37b0e072da31678b33c7b1447f8afd1f9c6b72c6c06026963f136f40bbd61f84efa29b3861a8f01e75ede01e866946e0d3ca6c9b4f804b476a83727142f63950c98a78985ed9cda38a7e4154d2001f21254107c92ae26e7e030c7f2d21301e605a02a8e7c0b991c7e6226710e7e77e8dacb53340080b93231a06c750a521946c172affbfe6d8627668738c555f983a2243ead5e3757054f4dc36c7a18f926dae4a32460e963d189af09884c2fd3175482d32b651b81be72cdeafcad678018de753420d0ba963d7aa079b7b51ba28a06e1de4eb050c045b43c7ba35cf0255e56c4fcf910c77e404a8c741d19e4e40f9d8e039b1871c8e1004addb488cf7854796b401fb1b9239261c200fc91d970ac213d562a8d4f944089208428109f122d3bbfb5aaf053320ff3ceceeb3a960ca8e714cd08046c2448018322134bba736729dc562d605fa9fcd4467a5d33dbcc7ee0cceec6808ea375e08993efc0bd137347723a3b936a3612ed7bbb18f2f9447d1434a9e106f1279ce9df6b566cfe56692b3bb099364c96b1115797ba20c6eadf5224f2c7b01c51ec7fac10414551af51903d4aba8ccd6706c836c3907565bea7099f302fc242d20addd9cb84a471b57e02214e4bd5b18440ad1ab7dcd270b8cad76d48a16057a183c182487000ecff8f716ccb49df93b85cf521b2c346544e23a5146ddf6378e1279ee40f29e97c215b730d4e0a2bf4b21701621e52fe4e40c964c69cd9f2c6c42bb8050767c69e81ccd0df9650ef7bf3a94fd6e15eb175f9a223787c5e82d3824e8e4fda38563f7b4036b7242866b8f46c209d59c1e92369b5d7f020cf2617f9034148455e0f18bd9d9208233ddbf75649200856b335e721368f3f759be797fe2fa2715a39119511d605c32e835cdcfba70a67d6f598465df662016e6ef7c7f786fda19e33d6dacd21c3052ba5e7394ea35139957ca3cb92aed906d365802db042019440f0671cd5e042618c0f0ec4cd56762e95c82232849935e24025522a95801dd48b68c8a174e137705bea695f058943644a7451853ff288a2ad28e2d89389dde0e14b21e324c1cdf941335bae2b3a1cc6b8d3d36638324d3448914b0f91b1a98f3712d6a2c09ba569264b4129f98f34dd653be119aad7659918fa8db1e771bb795a474961a22da60a026bb6c9041118ba0e65905c54020787b82cb8c0301425441ba99c2eec24525b6ae0a77a5dfc6650b882abe2e0815affadd0e97ca050d8b6a5f2cb58b04e29d6686e35cee6988ffe655c48cebd801d84013ca5396d181688e6c5128a59c3485ef49b0e62261e47cde1999ef9d6e371b04ebaa56034b6dd80644d2444c8283222548f24bbaf49edcad41450fd2693a27aef6af8d10c077d9cdbf7cc4fa0f3128b76dd1ae721e40505573c28ac52b08b650027c06e8d1090c882900ae351b98dcb893fb02bb9f48bc35408397ab2f675d1ff9d27716e2f37e8e4f6f2e06af16f057cdc7941539c547e1129ff848a60a688bb28e8366751fe6fdcc3a442b2abeb8c07be4846b5c49fb10e91145d12b59663fc12c5d255e5296b46c05f3ac4548aa7a0989933a4ec4170bdc4d34772945ff0e5dc9f4adc0cbe3a3ee66af8d0a3071a0684b20e2b465e8dc57c17d36a49061647891ee7e59e54fe4cc632c8d5e53650b59306f8397a5b99f028b8ecdd7d481312136c3080f7a728e2429166e801603bd3c0e6546dc038eafe5d67a6779719c35ed7bede198ef1ee3f8e73ccfb2cf7fdeb0df3c8ee3be3b8c61bf712ccf5ff3321ecf3eb98db2a4808d872f92d62e558e008cee7c8ebaee090270c2258d30cb27584a398909c5fa48ff9f6fd2419ed9c585fab05c8d4741c210b81b2c4db0000e859f47d7efd748582d60ae137689e54d8244175c4d237e3e92c5306fabdad4db71688a0a9c9ebae50a7e99a91e617fe2492acae6409d38b86ec71b528cc42f1f37d8117f15275b73b9b55c099e59b7891cca9344ea8d8fc836a7473e36c319b4d5521983211910b73f36cb4a0fae75c719b3a6705846ef7563b08dd173013eb121cc958a864be14505f372491b2c0d891d1e7f8bc92af75df58a86c999c7da6591359a5046db7c4301a8429790dfb2b3ccb6f71fefeaadc50d877501bce1549aa7ebf2bc33eed11d3e2e7d430bf2c430d0655f9826f9364475682ebecd11d9cf329be4ec1b65427e7d5d5832112292d25ceac7296bbeee56678a4ab8ce7bcebad6bbde38c637c636de34d6b200caf37a52348d180008eb4727c4ec63953f3e67a89296315179651571e82862955e0d242480c61268782174498b54662524a18214503081e8802670c43318e1810ed860463ab3139ad031d7e8dcc65279cdf15d42de74cfaee16152c9c3059c0f720081e45fb529d29bdad4c75b8ae27464bbabe485166d6c3c138e21b53519eb198b5e369bc551ad375f5979d16838971d3f16919252407f910473c817cae34af9132e67a8d72f3529daf083ed0839d66a330b4ee1cb8becee79185fdb4df0b8ceba9ff195dd3d6f24af59ee73bc8e3deb6ef3cd76e940b1753acacca918779d59d2a22404bd8b6e5881320839ae6b38a1def8cec77cf7fdb0b06dfea795558bf5f500c18ee11b47750777a52af2da5208368f86e0ec2c137a2bc5af53057c587e80e497e80e5241484804070325f46d65d24750da89f3cf054e78bb5d25efc5689e3ae9780f51398293a1fe5409fa4103ad0a075ce0aee61f75d1816ca9330fbc1f8a05e07451b0aa39958a465c3352799285405e26a18d904a9164d7b4015fe6d24551d8f60b2907a0f57966303aa6df620939ef6944a3811bb4851f8a8c49c05ee15998787737e862142290c31fd401ad41a9d872ca3e46b19a400a363a0e92753abae77c1be808ca1bb687893ce0cbc7db58baea2a1398d9ca29e8234e3a301f0b098b124e932068406fb10dacbb14e8972260e0bd11e98200eda903b8cf8f3f8afd78b12732014076e96e2eec09085331aa550bd3784c92017b2d88eeafe606ecfa2de65592c6a9c35b40fbddf65203d803053b5633feba367e32dc2f283d667e15c9c3dfa0d2447d80197592e136251fd440684155135338af914a110eb1362518a707907826a799976c31ca25f8814a74990797c3884aa9f34f6e903aecff0b26975ee383bc2cfdaa4ca9022ec29cb92aa876bb3b68f43e3a40a30977378cbf4a1b18b1b9c5ee0be836e58b9970f417305242e68e6276c71aaf225231ed0e770e66e2c679332d6779f94c6a213ea2c020110ae4274760088f4476a6e70789bd9ec0513e38559768188df3b81baf4e54dc5f51932970f777540f2426c420ec461a762efff2168f2bf0973d935824c4eab6453c2146f24b361e5643055de46dec06f3aca7826a4af77dd5734e99ecc9efa24e84bdbb7ba251ede15bce3a89957e647730a44f3b300ee4ddb7a308ea82e634305ca88c33fef0b2dc7a7ed9faeaaadc1dd7f7046aafbc02a4cc5da8ec12e17eee84a9fffd22ee9099becee5195be84d3cbae54cafe772c62d74633d93a1bd9ecb19b7d08df54c86f67a2e67dc4237d63319daebb99c710bdd58cf6468afe772c62d74633d93a1bd9ecb19b7d08df54c86f67a2e67dc4237d63319daebb99c710bdd1c6bb7cce4750ecfd8026f946712322cb1d9864fc2c56bcc75314dddf5456b4d6aa581ac0c86a6cff5640cd0ccf4ceea58df054835ff51994ec23f477b6dd20fa2a680d318fe9fc92c15f24cad6a363d0ad159fe9d92a994653b4d4938a4689e4e862923c1ded5eccda3224b8f42f4c04dab802f892a485572b1484f07cf3c699eb0b109cc186ba6a5d6658477869da01b7c4e3301847d8b1fd41b7bc47b50f099538e05d71d85ca705a06ea667835c862ebed58576ef3e7d1c24ac4650344b77962d7ed5ae5e6ea8f0c27a1bdd74d045a8cde6384a583d454b5d5c9467161752aa35831b55ed6828579b34366b1dacb766fa2e35f34835f373c8503994ff9a6cff72519a3d227167f848617f134deb5322dd0bb95dc5ab7b753ac708d957ce0c61c8e9aba1fd50d2db90e50a6e3ad1902bc9ab836579f55d8396b76fb005ffed284c856402a81c76ef9cdfa1bf315ff818910bc2b0e723e583f0c518934b980af9f137ebdd1a6abfe2b600b33bd91efc7291b75dc1c2621bab78dd559ab6fda75371e411e2b6eb22862a935c1eb675755292676f262f7a11e6ca9a3277f8f1446f2caf8d8afa82a573bdf7128d7efc86e46080864415e3dcc4ac01aeff4199bab511a80d1c7783acae048c85688c036a54c559096729b0d8696d77189af93e58ccbd286ce4a2a94a2dad5566c72559aa1b07f9c38e64f5aaa687ed1781472610d6e0132ca002a04c4c22a5369267b2ca92d271496d26f854ca4746185e161b82222e26732c938bf37af6af73c9ee0a2fa28e2f5065df3d214ea2aeffd31c47f7e3fbff2e8fffa79aaa06d500715553255682c652462ce804c01e0152d1858ba609219cdc7e2350aba72dfd04a90a760c6d6f251b3084daa009797df08ee4f4056a8fb9c1bf4629f36b1899fef3dae77a9139f59ca1aeefc7d2478b2024997f460c882f39db0e8a21d6b16493760fd26952ea4c76f29eaf50577bd0398e44fd4a483dbdcfcfe553e5abe6f960f0097c5d72a4023298b39ab5e06dc71f05d2858da51df0b2bb768a3c65e014c652554e5df70275b929689c2fe846a3b08d82a5f129dec4d027db38464320c381eb59fd1bb4e5e97fe94e00dcdf21b29a4f5b0323cec243af26c7d990083124203eb1d07a2134a61a3de3a677ca3183e8be3d6b4ac300831bbb5c5499671a4eec76584559301b0601080234e76a18ee43d4f75e8f095875b471ec14ccd02a72e8db8a78308cf2b3ebdc9f8ce48b49aae0d779d2cf592894d3ee5f14b0a95e66c04bab1152fa92d8aa1c0b40fedd23e74277d4c77eb32f45fa69e29aa8094a58b5080696e5c1a70bbd1ff46878ed4862a9993a0c29a2c6a62152d5675e009f06b1ee809ab271752aa224a82812baf6944d9890325a66fa3cbf526f53b528673689d9ecb1f47273c18392e334b6f23c2a27708cb679c2d4c11da2b5c490ffc47298c29f5f00e2c8110c454c3ed8f8f5cc47d5f23867ddfbeba3d34befb78e3d74f2af810b2fa6b09fa1c833d4612550b2563674992c70becb3d58951fe68fbe8a8828c2605f1e30f7ce68ed50189422652d98ace3d351f04c47b3201f068d8b7407dcddff1235a9a57e54f4dfe03aacf85feaa11f0413c6e02ee46ffbf392110c3af667cb0e8d409a500a687ff476f79f6f2a4880e3f869b18e0123d177a016224307535b3cd74f2b205c891745966c602638761b321b196dde076cb0d0208c3b807dccc41e20bc97b2772d848191ff47947e098b5190982c0a2391ed61512d8d0655a94879417ac7aad5b0b71a031c9648bab69ca88ff13b7312149c4ed795ca7c8f9853db8bd6442efe63520e5fd70f8179dc8b10f0fc12319d05fb851fba83bd3b431c9528812336357e76940cac58d2715cdbd1421bcdd0360038aac30776974d3092bfcc3d2951496e036979e76d56b55ff1b064d1044d963ea759b5c691709611dd19103e376be56ece260eed106ab6c3f4b01a198409a6bdd265d5f603d6b79f92abd549203ba64e7a755305c116d3a998924db60f0e2beb82f6e6f451c174fbd4c76f0b0e9acbbaeb3eeb47b4c7fbf9ec3d68cc230c217878401a937c27dc73d0e3add55093422ca779d8cdcdeac18a6ff18b5ffbdd64d4468a991bde5de013e0a5e0aeb0a9aa6699aa6699aa6699aa6557a5956fdc17577c494331e21330c36c9752c18092fb64441b9ee46904503483cd112c534510b936e78ef6ec3eb525966cacdaec60dcfbd77c78407e3b0ac2dca8ed37322a2d04b98881273e83fbbc998cd063e56c0192364a611dcb66ddbb66ddb441cc7711cc771dcbbaeebbaa772ec28267d9f8f8dcf97cad25e127d04e5263b26b677b73782dbb66ddbb66d5dd7755dd775228ee3388ee338aec3359ab4c7cec677fbd8517ce3e379def77d9e7fbcefabcfaed17bf4197da594d614d675099b8c34fa588e8f76b3b7d3240fc5cc58858054e5f6300fef11ecfe5d1371e7703833666fc48667c63ec3ced8877d58dc8308d0bb0757fcfaecea20223715727b78a6df612866c6e69ca23cb56e3c80aeab5e57803ef7f3f97c3e9fcfc7de68b94f9102bb83dec3bbfd777b6cfffeb93db87f0eba3dba837af898d14144b62e41cf597af32e2a057a19122c4510f16e0adc6e0aec2e2a0576e75abab3740ae42e2ac5447757a689a6c0edb26bd9cedd94694a69f1f0bb344df43d85b5f00e0c094ff60586626620db63776306b8799ebff838c8616badb5d6da0f7fdff77ddff77df0e7f3f97c3e9f0f08834020100804027d3ecbbd608b279be7862e6ac6c5e339ca76ff302a64ff1d35e3e2798751a810b6f8c3f7214194fd77293c0f599b3dcf9e944c612428658204798191200c1f448030602408034b21a7efd66d3cd95b17c593e71c9771afdc77edf5f4e7ca18d408cb48cb0846c1f867e41f8c9a71f91c0646a9464058aa9e98266af379082505e8df515278f75c8a91db4f5cd9d89147d0e3f93c821e2971e876f590208c534bb5cf952008f456993e74bbcf47fb76cfb5d75a6badb516069641b867dc673d5eb769196609e32aabb454d6df0f28ce9c30ada2a29f2fad222715f3d371daa7e3b439e79c73ced92b55a6a7aa79225d3f7904e9294c88cad02094669e84ccd3e8b455d3445fabb522d15f2aa5a4ac8c9079878b76ed2edc358c129dc39a86238948c471e7de6154d7616b2db7717766870bf791bbc03887515e89e3f0619ce3bc3b8351dfc394ed2ea48b306a74528d4884594856a3d1b583df4bbe8dbcbb8cee6194f711468d0ec22dd1c63321957c9be77977c1f730ea3bc6280f3b1171bcefdc23f8eba304fef7fa58f121026754cc8bf987edbb332edf8751df879f883ad7595af43be3f6c0bc9071635c934bbadb76675c44db453058aa4854db76edbb11fcb66dfbb16d58c6d898ee2cfddd9719ff4eba2f312ee325f78574938feecbe8253b5c4646eef28f60d4c88f83fc58cac09019791939772338e3fa288133fe5d1f2b3e44a08cc7b83e2a18e3262627915e52f2d1dd46ee8ccbc8081632328269b6b3b468c695717b605ec4b82697744bee06ba2810962b92877205ba118c20c948f4b9a8104685fec1d2a62b39e924f745f4d147eecbc8493ee3bed8e3cbb82fff7d8cfb22e3336e725f4c1ee35be8a2723c18e579084b9c69a2a0471046e846903bb9528774e196ed11040100875207b417df7bff3be3cab831aec925dd920be38eaee892dc91ab4d159d2a2b9a32794edaa5565152eaea183b5b3c092d9c3c69add68a447fa99492427fd41a6b23ba394e292725b464762c999125836158b66e1d7d3731363035966ab5234487262708ce34c9cc134ce93599ded808d51caa01ba2ed1c3ed2105d51cf26c7dadf619c9b81f911ee3ca408d306a34632eed5347ddbd77dabd6ba311bdb19fd1e831ee22e3a3d168741931461835bae8cde883d511f62ecc0e23dc1e4e1becdab16b3807e85966e9ed423133e8b2ab3172ebc73ce1c4e0e8c0481d95a552c5ecc4c8e8c8d0e4d0a0665c46277d85d3b8310e00a4ce890a889800c80441637a0445530036797e34128d466fa27122287ad838a33b55a2db3a0f5b67c647174d9ba9aa59c61d34e3238f2803855e2f0c1c66398775ee2337092d872e803b4d7706311f800bc49d3453c85ccd9a699a33ee2fee50cc1f93fea011b2aaa136d947e941c8f8fccc99a7189f9f3a93aa28cc3c01f1791a334f01f8bc7781b82820eea3042afde4322e4ac67d940e80c7b8a818f7513a7ee9b7f45f7451a2fb287dc66357e373960ee28e2ecce8415cc68d71614607c04b2ee9c28c7e2fba405c98d1673c7473705fd99151c6c79b7845002ecce8f20a8a7343b5a05b702c32a634777472706e56fe87760669c6c31427a669dac478187162dc932e962b49837f1f4a7c71ca34fdceb8326e8c92fb52d7dc3800378241dc930b808b6fff360ea198332e088757a65804d7e8ce7cb00e2272e31cdfe32acf9879a2b55a2b12fda5524a8a08ae6c8d1e0496eb1f806b27bfcf641c8883f0677cbbe8316e3fc22507c031ab84e5cf59babf97e23c0500fb30791038eeb8f2e721bd0102fb30f90906e1f000c03e4c8e35d0e33c5decc3e4f71ee76906f661721978c3a1750ff661f2126c7168dd8270687dbed1e94d2d8d3a2e266f38ac55c3a1b53814892a0eff52ee9894949e31b10a73a6cc152a52bd57a5993257a82a8352237d32c5164fb06093e3ea0a59e4951c5757a8226f92eb1150e832cb6a367261c0800103060c18f7b102c2f8e7826e28140a8542a15028344d9f1ba70974e3347557a3654727d3bfe098fa04adda4e43ff8046686ab55624fa4b2929a0ab7d44038d8c1c8451dc47be7d2ee82e9f83304afb4703fd73eebe74f73e725f3e1ff9a65dd4ccf5999610464930f499ebb173d1be6194865db487304ac3dff52ee88edccf8dabd08d20e846f073232855f314c16a43a90aa52a562b3aa5f4306e04476e8ca6ebbaaeec35c3218fcf8a2cac068675d8390ceb2e75f5e70f1bfd6659986589a6c9d6da3131f576ee181a13d3311dd33199d6c0649d9ddcaadc31dda977fa969927cfe93bc83c45314df4f54a5544e9baaeebbaaef33ccff33ccff3783c1e8fc7e3b1d66ed65a6badb5d67edff77ddff77d3e9fcfe7f3f980402010080402d17f3e5b2dcbe375dc269bc6faa01e1fe829a574d2296259ad56d65a6badb51eafe336ada6ace67450abad5ca889695d169d8f13a3c7a8855112b47e611e204b4f9102e7dd9a8bb2a7f78822db0e5b3ce9d73883dca72db2dbe48efd72a1bf30aa870467e4299553a4c0eb1b76e9e575c14e316a461eeb246e991825c179ccc37a04a74881f4d89d22054ed185457462dbb752b2a74dc7c8ecf97cf6b256ac7a441ffbd569a2b74a10917eb092d3893464bee162764a53697665de8e90d97ad65bc6499d48a333bdb4a1dcb6c9d9727ad9a3c4c9b2669e7ac42f4099236de48dc49130d966d2cb1b9a61a98a2839f39452a9542a7adad2265b58068928b4d24b2f6cf8fc52ca0aa8ebbacfe7e31dd47d3e2c48804020100804029dbe25140a8542a150e8f438464646464646464642a04faddfb5d77af55dad75764cd61f8c2acf54ee6a7f886ac9a6e0c8fbe243f46de65662ce6c5d9a59a6bc328b6e0f22c0de11e98c724830335e528225a9d6911561d1730b79c028c72171c0c95b739fa7389f324db3659ae657724a568d2e8aa4979c841f5ad2c3cbc02cd3344f7a9822e4321ec6d5e831300a46175dc67c49ed9888e048c66a27cf77145a45f61532c668a33bcdddd5d5c0eeb9a1cc9e67379451640d342f6f7716d44cffb3f50d15bb2c3a5b46ebc58812f1a4629335c0a20a593e7adbc992faa408cc1528909932c7559130e4f9c971556448963528e2842c3b471c3e9163449147d8e2b685a5059544ae1c575bb84236135af2c0c6d5168080e5b8da421571b68cd48b4d05162227f5b566d66d79d1cebd6a9a6d1529ad8e95ef20302fcf7576878dcfb9798174df366eeb9af89cfbd63591fd7bec308fec73675a362c4ae5894319a6c2d4558fddab6252e4988d9022cf8b4090caa93c3190ac09ab6a5c6c9516cd79c9cb799194b0ae5b6f150cfb16d65b150b2d7c910848a69da545a71ae691fd43534c4450eb3e6e7b77bfc78f8bad22b770624c71e50106929da5e58d79764df0f0dcfb363b97ec1f1edcb7d3ce06c985fb36e392fdf3d8b5f0c8fef9a65d1edfb5731735e3d29dd3665c3aee9f1bed76eddf45cd30b15dfb8ccbf6dd19976d73f178b7bbf6c669e2ee4a9617f54d4eb60dbfa46139a7a6e158ed34491b114cc1da4661ebee4d5a798497fb082fd3d8a529ab90944e4f87fc229392a0b9f3c4e11399fe98724e6f62398388124339831c75368f15a789d2bea48a73e46a6d6176ec5786c354a518ae38f2c0d2c76cd57862c93f6c31d2a00dc4460ed1aa79d2b6cbeff2a599d2d9e031733d8233d6bbebfdba2e5df7ede26457c3abef30caf3fa8dbbdd3d8ef3bacdda2efb8751dc33edd6721cc7711cc775b8ebbaaeebbacec39ee7799ee7791e6c452f79bc8ea3ad0531018e557964bc5587c2e1549b8cb6ca78e054152673ad2c2970a86aa66494683978328943936c85b2c5599f91c6761a69c67e3dec6cc558b270c832238afce69152c3924a1c3a91311cc62e5db8ca8e83caca78561e0aa7537132db4ae38193a9aa0cb6baa4c0b154b4474a66f6604141d31969541359007a19c69a7cc58c28f5d4440e1163016a7d289a957322871814560e4d329d2ad1c52e76f3bc18ac98e5976579f91a17f63cf447cbf23d8347cfe0c31481b62ce5e7103250530635a1314c404531f860998c74342c93125826970c18de4522c1350409f36025516025f3a5be8e46504772c8483e1a9948041989880b4df419422309812649b61111688301c506830b712320e046eed091988c5859be0bede84273f064c0b8b2bc07d2e159d0b9f05c44826579cfe709cfe75c5891fd3e603f9b0f8b343eeb81cf7e2e693f9e0e7c2e798aa0270b90154df4a1c803f23800b2a29745c886ba1ca1ae0c235837c285231897050c191e8c6d0330ea5606120f8956a30192aa954124ca322002332b8cb658a20f4db268543130528915a764882c23cb1c8a4ab00b94c821620e390c0e249ac34a428a2af5aa1620d50b0e262a31872293a8c275c9aa8049ab5831bc4c1fcec8f22331e2109c2c00e52810839343c44ca91b64c0901187f06401a63701199e1c6262d867589219918627a2d0b765cdd0a3c495706246b63c170e3129890bcb98b0f3bc6d225b3ce2797e8b3cff9c852c3c524e4ae7a4b3e927ce316fcd9392a09fa731f4ca2af6acb64c5337a5626612f989101c976dd7755ddcdd9ab35654678b2794524a67e7185142eb52e50098ae096b84ec7cd5db784295cad7a565d89a3d8760d3d4b2566699e981748f0ce0de6d5a9735961d776334403823d3c6d0b085f2168fc87eede4eb889a1c2dc0e4ecd7ad0b02d92febe6a0b74e253ee952f6ab44b322ec9f74293b76d9d54721b8eb58987dbb70cc5af60d9f7449081e58edd7c313086838c775ec39aecb4c894b882c8f29f183205571127d0c87d6fbd7b579f64007478b4bd4e2b75252cc90e203fbfc4c0f84bbf530a58997ecdae76649c9ddc613aa54ee64bf0507e570adb5d65aebb66ddbb66d9ba6699aa6699a756a6212cad6c31047ebebb5746857992d2ec0c62173d8c972481cbcc895eb223380259e4cdb3236b4b1e62667cf565212c0804c448c290888a738847589a4955d7ecbee956124ba2453b08b44d646dad5500e65d6b65bb8c3a175ee1a0e3b233223ac87dabbc8f2db2529917dfb86736818c8e799172418c39607f63966dbdd6dd713aa54f65831451e045352b2e8fbbeeffbbeaf7a9665a34561a3416b3060db6c4e434b04a21932a539c674495af73ccff33ccff3783c1e8fc7e3b15b3db536d1c6626badb5d6da0f7fdff77ddff77df0e7f3f97c3e9f0f08a7ac6cb8627ad0fd7c1eafe3362dab3ab4bb1dc46ced030b6403e2b97cbc22888d167ee479fa9b43625212d7fbd71b03b11403c91e63f7cfb3e1f92295bd8fd4e7eefdbb24fafa8f5aec15c3b090d535a1bddb2eaebb9a0e97fa0fa366e82bb65807872b76c96e316a7b269aa69697faecb4a3dd8d4d6e4f652dab4d5895ec6cd4ebb99dc793ca1eae9d8d087258946935bbf6b2af3c501bb306c01cbc1ad00db830e9a479edf5f2a279e22eaf73183563fdba74b868af183533af7d621d2d5b6397fa0ca37acc0079d447b0d6fa0c470c7b86aba63dc39674e37a761bd7339cb2dd31c163a61fc199f9eb66efeb72fdeaa6cbf60ba3441b1669f77a765133d68551d7b5cf64d730ca4ed3755133d6675a308c922036633d762ed72b464597eb184655faf96efa8394941869ccf84598e578194f4f4410c4531f32fd7671f9110507d69624a6f5090bebe8789ee7799ee7793c1e8fc7e3f1586badb5d66aa75f6199272e3b3dd579c2c2667784cd291185be6ff0c43c7da716c6b04ecb3c6958d3344dd3346dc34ecc138735304f190ed90afa608b87f578dd755d97e452567b4ed83cb65e74b32e1294e2d80a086d0e43ad16c32af6cbc6410f975212220199d2a85dda1c9061209fdb2e6d8f5d1356f5624f7284fc02935c6c78be4865d8460449dd470e830493b27f277101dd62d48c77908775b87c27c1a899ecdf33ac437b875d42ff1c7496e909aba4a25b606094044770e87ea05a6b8da6ecdf8dd1643dd9b53576236324157206f3e47dd6e3896c957eb012fc6184ccd20f1635a3c3c5bbe7f51fa9debb07a3662a6e79d16eef9db6d87bae6194043db7182565904843660d44f15d544ab3a7df3c1795023d2d9edba352e0f7a5c00f89161c94eb185820de6bb5ba1a2ddb2d2bf3344dd3344dd35239ae2a963012c6f33ccff33ccfe3f1783c1e8fc75a6badb5f6fbbeeffbbecf7abc8edbb4cbb2244d0ce4d655e800c91e5e4ada25d1b9564c72691598611bb4b311c1ed73ceaec64b292bd65a6badb536ebaec67559569d277a6117e5c3faa140f9b0700f2240eb42f9a8a7d785b95ebfcdeeb2c3e1cc97861dc1659f39bb86c3ced9afdb8308d0fa76751011c1eb4670939d032415602cac61ea00f9450453961457b715555ce1f96c08f46dabdb2712894422d15f44f7b1028a6e49484848484848481e027d57c64597d4f21df55d741146ad885c629c04a3be93dc18ff481e03a348be7d1f8c92608cc7f8f75d06467d9fc7c0a8cf7b0a7b750c6cf6558f92c769a23d48afd3447b98dc4e13ed31ba689ae8331c5eef1eb9d8d5d8a16517b6ce32bf1bc18f28aca1cd1cee80c0b8dcc926a492d1ddbe1b4115b7554e76376680302ebbebc23622f802fa4be823d9b276d838875d0ec2d871c30303e3cf7d1cfcfe123a68fbb8eebe6061f5f2d6b2b46c8a1418a3895a576629686ab6d499628a29a678797979d93aae0777518fee3dbc6bb7878f83da6334d18ed3acd4d56d06d91996d5bf5a11c7711cc7715ccdae4584aad5c8b2fb524a5da9b46a0173e46128831e4e003c04e5f98e34ae933cfc603cfce4897dde461aa24f1c06f1f92d885b9a40dc932eb5137902710a441037e6d92d91ca407c931c10f5e44a3b4f6b6c686d280c652bff6892b8b32fbd9a3194591a00f87e868c1826a492918804c64828eafca00759da79d0ccf31f2bcf7fd693e5794fcbf3dd96e7b92ecf6b773ef3e4195122cabc75694499a740c85a842d9e90e4b14770fbf51bda31cc03bbf60bf39871c130a9e53a8974637601629f5d80182649ed3c2e4c9298c40476fa1bd7eb29e631e3527f9d4776ec20a9055cc16c4a516eda56b3bb65355aaab44097fad3d40a982eb01a70a24bfd16589dee69850c6c7fdbe22d9130b0d10a57d8c921c7f5c05a209e540e0eab3c3f2391bcb204035a0501790ec9c9224f04ccd7be587685b827f75dc270785db75da25fec52a55db1ec86ba3439cb75775d76465cf21797a32f93e84f2cead2fca42adcb174e5994329b2a4add2fd89576401e66757bdb09d577e0244a471fd8aa0f335f3856544e93ce36c0f3b4bcbd82a214ebb7ce5ac48c323fb3223efe3e04c9fa56d30178442e4492d8b524a698b9e65d3156c3f09cd39af3c09315596615633831c87600127c721594842ae9146df4683d77990c32c87d58a3c4d11653b4a3bf6ac3b8eecdc6b00b19fcfc33cb67b1ec18fa77d9b76d0857cb7e6fb8c90bc061018db3dda3dcf3d8f8749d6b91b8fed70767274ee8ebec7d3787cd770906e6c071d84797cbc1f11330d1df43df4d8e1f81c74274297441f7a0adcfaee98bf81f27ebdfe06ca73ecd977e8c051cf1d4776fb1a40ba6fb2c3f15dbbec707cbeb5bc68dfae7dc324eb2458f5b1700b0c3c826142374e13e892286e89d3d45d6f9c77870e10c8ac43878d087eae0307e9060feff511dc8e837423f33c7b043f3f22664bf37078aed5cfb5f7bba4f9ed2990deb083e0f07078b8be71e1c070c74c937c86497d5b6269966ef971436adcd2610e6f57bba4895b56660a0c02334ff58ab97e48b0daf0c8825c3755264b98699234f3a45d3eb4846469adf24eb6b9549a45334df4669eb49c79d2ae04af6bc94c93f60bbbf217760cf3a8bf408dea7449b6d09becc22eecf5a2666ec83a34610b2a1005f5282948e4a00615a85285c08a5130b590c30c54e07505b9682e19cbe6a6a546679eb0cb5f3bf374916e60d28dab6289dd4b679ae4af4b75e8ce3c0d000c7a40038d6a9e5254a8b199271a38d84290d5cd3ca540790b679e24286fe5cc9387852f6c214605ca5b3af314571226875246ca5830f3b4929313561c4a6f424b26cbb80a57aabcb4c96955c340e104275881f2fd430691342df3a462832e7440f9ba324f326c9a7813572b39acd8276575e8055b3c7997e6d6f2b35d225d8f438808c97dd2858db82288cd69aee69170718203ad128758412776f142553f72c8e56e356488901cc69b2130398c5bd8dc6018778a2892d3a598e52da288165d8ab96f114570ba14738a84c9f300791a20251b2173ff08991b1751640e5d8a39254fba34ff79b2b64bf32a9031538b2d9e6cad8a435cb9730a8c2f451ad2daee469d261943b9cac9737ad3870ded8f4c4ac2ba854935a7f214f6d9ced3f567b55535b84196d63a766b3459bfeeb42f11275a414727d31ba310a19dd305db2462012b074811400987259f1cb51cdff15427f678194b360ef1c208390ef1a28a7902e438a40f73c8b1bffa7e12335fc7aecc383019513a9a7a01441c60450029b854f2cfd4aa9044ac828ced5d32a234265d8fab2ab4c87155454e9e776915527f879c5fa2551a03a99f6f6915f9306691e7916895797a97b82d385a45622030072b2e8938340b5b9c61bd77d6aff9d0c43e0c9dbe871ccd5655e96ee15064bdee72efbaebb975bd5bdebb7b79985edd15bb144df273c361ed8cc88e75bda1c5a4655d188a6eaba9149dea7adaa8725f66194f9d459bbab5c8fd30db22f7c32fc7d7c8d7daf6a5ceb416a2a99fd52f875d63d5901b0eb9ed90bbf7907b9e20774d0f1b469b1a2dba4429b5e6e99fe812145d6a9454c9972e45d12589859d42a69011c9fc317f94ec948c4846a3d168341a8d4848484848484848482412894422914a4a4a4a4a4a4a4a486e044925b86f9a9b9d8c8928fd8993fbf3465231854c21ab954dcd6cc3dc62fe983f6464688274cf39658ca4a26f88681a0c152f3b5d6a2f64c729a97851c12066a585bccc9eae469fd2cf36c2ec2a72537a6925a6f4c224913c1ff3bc94b7ba255259be639726912e7567d137ad45e3b44d979cc8f4735eb24c3a1b085d6a992eedeca83a462621f7e76922ca165dbab9c1c1d1c9112264b5b2a9913fe40f19292383d01caa334f252525252f29f1b10296bc4f7746a3d168341a8d44378225231cc5ea326f9a96550c087da251f0c208b929cde7a1a4d99131a1fc216568e6a955b2a6a510751ec61da973595255334fada23943a431df18e350fe689886e916740b98f0c1a1d47122eeecd8182febcab182dcd8c8554d10215e74d1c5f50deb6a5cdea5837373b25c45534522d29837363541688474dce846d149554ee744949e53f490e2e47e6f81c3ce22f729ce3cd52c5a25d2884da46f2e2b0a51f844bff48956d16153919bc64c53ff7b2863e44d1875e24ec78432c8c3d641ee4b215127eaf483d09856c1dea7528834aef74a0a0e634ed4d1893b7406d986069927890393637128e940070f0e658ecc893737388c3636b1a664e1302505872b5d93336be6298adea22a8446ca04a93031aa1f13053676298b2cb0ab59b1595d0dcbd32d91ca54ae2e2cf11051a49489a610372a1985ba969148f4d115919088ae4cc295dcbeb9259fdf48ba96129cdc272179c925193d762d23ac93fb2437278c3a4080248f5ee43e4ac63c0105184a15cd35f33463bddf36f324c230124449002479c729649e9cb869957951a973728b7276746a72dc81913fa616b93f7fcc13cb34ed6cd1279945875d6313a4a66ba41673c82dd590e5c36987496fbb25525d4222d22059f8c6094872924b83a80b8024a7999e621d328320958190e0384da5798a51c80a4d4a90124c95717aa4243ad377a6a11479e2a64144912fa9966aa44bf0071a33cd7990c92943f210d3920b4b2fbbac05b6af522b136ab64e00467aa9cc5f05b82c5a801c8af2cc821096f08626d0410b5ae0020c8212c05043061c2ea680863c18019cb3db24df5fd899e3154140826d3958966559b5481b320ea8965973ce99518bce39e79c73d26bda393bce39adeb9a73ce39e7bce8901880f3a13e9d73ce39279d3d500216558059616183142bbb8afc80f1267e97ee8945818cd5511a8a7ee803138430c51a6296c007217c0400e540810a2dfc384117ccd0071670b72c4b67bbacebba2e226f5081665d96655944d200935dd6755d17912caa7559a59f9c7ae21368c552341842872ad040067628831528a557a62899521a0423a8c1072e7891030a5420b5261121c800cbd4aa446cf0828b08152cb0fa0003ca0515d3da82052ffde4f364c7d0026b592cb4e0028b3ecb725c61e182da20155c725a71f2044ab14842a630e0c913b020420a4e9ed0c34756b5b0664651ea7084295a40c38424c8a107991034a002081c8c30040d6da0d61557e327846634031dac70051768a8d0041b1b680348f580084298190217b2f08229e230062b83021656e8010c640032040b176402209284266ca10b1cd0cce00c5ba802c3c20f5ea059021b60e08233acb0e8b199425d6882ca0b217a28c287d516bac85a8e4370f69061b1c91a58558e4f02153962283ac78852ba02154564b23cb752e447eead0f53277b8355d3706591e5378cc8155664f95a4139ae880821f3e4b82262038d08155f8e2b2cfac061c14596dfba2dc715165b78588cc1cb718585163c5ec76d5a16594acba26df54582a44d2d4a69e5ded5682adba4dba45b4a2c5e178eb32f666124d9a7ab963b962a4762cd0a2b73f27584184730118948e68f12cd0acb126d624dadd68a44b39492b2b2828d666ab55624e244a150af5a08a88588522c18238c1821646d8d1e0b268bbeb160625a4548ad96ee64dc2c824d6d551062841cabe00421d9e658052700c95b73f45a296dba94e9955f5744112244b02fa20891562172d32a31f79d43b04514c90273b6aff5d2a5d8e1228a10e952cca1dcb80e02d8175f7cf145962fa2c815b9882259583199489f2c9836cdc75c44919a5691f9caa24b315b96655d4514b9b96e11456cba1a4514b9a2555239e6ad8bf12ba2c8aa4b3187164c11456aba14334b33a05302fbe28b2ffe90e55ba75542eb45de228a5cd1a598ed4bd64bab84744725ca295d9af3dfa2a6e52b531ca22c191b5d08c1caa6b11b47dca219047be5f07902c1fe985fa84bef88d26f991b1b299d5fecd2b4d50a5cd0649ba9943f58994195a515b420439319b032834df7ca0c35b9fb5185d2d9435c0fe79c7387ccd7c33ae784a23390fa2dce1e9461c7867a762eadba602a98bde7cc318164388651641a5ed725149de74199764a04204f0c8404f52d7f357dc216e76986cae6e875a10ab04ce022552a2ca3291b4112190e98191d2b394729a7c0ec5bec92a8d721bf78c9ee6346c74a86621a60ca4b235232eb5b3b254032c6d89687611174dee68e0258874294292af7a58ef9851759aab2c43bae4351b38c28d6a325455bdc4c8c2856a6ad32255dc11663acd5cef76d4c2c4a4929ba4da083661188320852d97ab59137fd3d94aa28bdc83146314ff6f1b28b5971725a527062a95552b5515abb682f70b0d611c9209266c655a9458233ec16cc41ea489c4dd3441387daaf77dcbbbede337acba274f6c4a1f6ccba1acb2c2c2a579a1516db2c6c62136b9aad991b27f67d4b9525da2b61e62976b96385c9f1ad6aac323f876cd1a6ddb9bdb636d876c8435173dc211f5ff376a97dc62c75620c43740e5d6a9c2ef51679c2210e1165cec0861d24778ecc51de089926799c554ecda5334d3bb0dd75136968ef5f648834ca204fd61aa4a9af691f0e8722d1b5d41051fa524d535b3811a5b1bc3161ea2ebad49c76db0e11a5bfddbe4344699d09031bf68eced6dc16ef0d266e3021bf5db33b426ab7b3ec8e985d0daac25d334d16739864f14dee886f7cb7b7f161fb54de8934baf7e91cb487b48bdcef9da97a68b1e12687d64deebe99a6eeb66a725b344172df8a9927132eb84005da3dc4d3b5435735b355845df504b955506ba84d9ea78b669a68e6e9d2d9c96de1ec5c2b9d9c94b0777656b326de5099798a93aafa5424c4d204e1eec121fde1e190c6e490c2e490e6c87cedcc53c3209afa37a8dd83dcdfe942f9230bb9c9fded6a37ec97dc57da4b928fa0ddc9a1c5c9f6ce17d81aa841ca70913bc83cf54e07113dc5c2e14a9e54d8f8eb669e2c9c69ea57ebbab953354d13669afa6f2bc7d2c9dd3b30f639b4707672dbf7f7febc2d9cdc077da4cd902cadfc776b3449c9454e9e3ab0f2588cd7a1375cd6311bca581cbb1d9d04bd302989499fca254ae79c9ff31487a42468789d3e95e7b7ebba44f992accfa7b24d829e7e9b73d69ba33ecbb173a12a958ba4b773ec5ce20aac7490dfe2452f7125f9a34b329440c8f272252f6bb29038ad32074923a545254dab845225a455c286c94c9092524a6b0089d6969edd95941424563880b44c130fac0cd22a13cb2aba6404ec52c2c81f59c2c8cb9756799677626a603e314fd9a59675bfde1a4d6d6a3c6dc75c71d87670aa4c63727fa3b7f3266d5c82da97998891e852dfc7c1969983ce240d0d76b253fb12571a7ea12a6d8bb8e3e2add114239e36c3318adad48f0fab7c68af8722ecb4bde25008ee180e4f7218fa8543931c866ce9261c0e4f721885c8618cabad870e1caadc2f09c13177a6a96f4372e9eeb907a3e4aa9f0253e08d1bb74e13c985e37074f19c4b811e5c5d3cabdcf32c1d4a1a0fa7905cb473e7302a3e056e97e492a5c0ed66c6e0842d24374cee0e324d8dd33453bb150756e2e4064286a2654ee53985c499a79c79d2dedb5beee43eb7517a8d3ea393c660bd892116608b5185d2d94374cb9c6387cc2da1e8dc2af1619fbe36a5b92f73f40dfb14c7a632f725ae2d55aadcabdc53b61f64ee89c3ebd8b71cd74ba2d997396c285ba09cc3c234b4a14b361eb678b2c51477cf41e761dd45d3b9505686636db74eafd3bbd85fd73a2c753a14f55eb1bb74a7b7ac6b77f9dcfab63dc3a15fb758c664b7ffb05c598cba2a466118a5ed70a1dfee829dbec3a8ee1e9636a8990fbefef90896218cb230cac3a8aebad46fc7f0f4fe598ca2f76094a761d4dcdee19619977a0ea3368cd22ab64fdcc229d3349f6119a3b38a11a5e0d0d8571b4cca5c8fa0f530ea8016aeb662110e86adcd2378e13a4d168e206dd9b5076d9513e4b875971d1358f7ab5edc0d8c090c6bdddd7edd7aee62d76ec663c67a0467b2cb5dbb2990a3ef6e0abc52a0765320cd30eacace61c7382ecbb88b9ab12c0dcb9a697202c7057bc5281c4c44b0058713d33435304d32a268609ae6e5a4810d2b8d7d4247a4917d873c69d2346fe15024fae4b06a39ac61d461a2c1d2a70cec6ceb668bf3b465962419d1a41b1e8f94f2d7ca3c5defcc7a7fe36e0ac46e0aac3705d614e8b92970f34439849602709e2e8bb3f0752c9a27cfbbbebbbfd1ce068f99f908cec87357fbbc2edcb51a9da67dc3ae273fe38261d2a53b8651d8bb6bde45cdcccfb4548c92609d8f9d8b760f876de3d275b833c286f6cdba0dec16f7eb36b85466d18065a353bb6b79b16c6ab2ec959016ebb2b321c1ebb1bbee4a2b40deba4eb402e4fbe6885b6a76bda26b9f5e66fa7ab41ead5b3376b38862e709559f5d7af246b9ebf6adebe5dad5a04ba472d3c61647bd7cf5b5acdbe5cde2accbe5ede2acbbe50de3acabe5ad72d6cdf29671d6c5f2a671d6bdf2b671d6b5f2c671d6a579eb38ebcebc799c67fb3c9ff56a44918f329a260dad6ba29e07aaca962d6bd7525f2f8a54bb441fc1285052d85640bf1e2505d70ae8674749515b017ded28a9a2ad808edb9530d344af5d19237ff820ce879de3bb76efd2bcd1fdbb8dee1fee1fd3e479321e4f906cffdd86fd8769f2cc9bb42b09f0c21d3925a2c4c0e698b7dedbfb4bb4b44a7df7905f7cf1c51f40180aa2668033d6373ab95b6f584d72785d3b4b63aaccb1642732f7d825eedc59a60e5418b5c857d562e63ecf32319ab56f9f7776582346140e87dad5819ad6754c55449139b28b2ee9b4bcd8178fa6c332c834551c51d85b64f9de3aebc3c390c8245b939a543b6b76fbf5c63c3b398fb055da567777777777775bb4bb29a55482f5caeebeca735b3db5287d25c6d5a349a6449364892689c4122dad721dbb8d26f9c8d1184b719572236ca658c7135cd681cadd184895d57a021097399472f2d31f7ff270fe5d2a1d02409ca54bcf41bcb3879ed1c319da43afe4a18c3cc38ef43006f79033796892bb875b8c8724efa126e36189e76136e3e1883ef450641f627f48f23dbcee43189f8756c60f4772a010a8e48a590a9b9c654acd8c0804000000b315003030180e074442c178a4e8c93e14000e82ba4458541b0ad320454110c4188410000018400000c000191a18dc0a9647a7025f752f708611b77c5f589bc23c0594f03dffdcc93a2fadb4f8263552cf8b8e76f876ec7b37e8bb53643c58608c0081e204c74f70c6e1ab4437f86355f5b216ab1764bc5c262d357d5b1cd878c584deae58876c71a5edb0b9e4877b99921b7fefa691941b7a652037126eaf4c92a42c54021f16e02e09705818ed7e8a935e60deac44483f5a6e52a3f651b658ee2cb26fbdf3b19ed13acc3232ba38339989b8103461e3c509a74750f0b262d2ab543dbe2e99d8674d64942060ffad6a50f3abb0114b634c4bd77a907077b68525433dbb32c395b11022a1c1bdc4fb4ea8d25f4229e9e4078e706fe47138f33c302a8f7c6691eb8ceafcfdeed30288b3642cee58f924d252a58789d35d73bab4eb09ab0d653133aee707fcf0ba10567a133b1eaca61d9d0351f2cf969bd0a8dfafc9284f166fb1b1a2ec6459f6dad087b2bb792c324d874391f28c4c18cbb5481fa2046e6ac20698ddc5a2158a5ebe1d47776636d7858b42fb50dca1e8cfa679035015c312a54445fcd4b6d01d522142665de1f904e94fb1f81eee1e3468ac05a708debb499d5815c35d554ba965b14a32f75ef4a8e307a6e0bec29974f43a2ac76693bd668f19fb3d355aee09e424bc948b61ee4fe22c599c93d758f91e10de3e10a77e373265c91462a836173782e44ff54d6cbed322b9d92f20f5f449c8ed52e40e0326a87ad9e68f87bdbc4f297a4617b9cafd358e71c0e9d4884d8fe38d61c0796862a54f37c683b9fb04885ed92f5edbc7e292016bf8819b395cf604bfe80d9e42539850e9cc7037329276bac14e256b5768ec524c5d4cf958ec506ec262f1e2ffeaa805dfb2d1e36e037a0c29f23162e91a8728b8608458b2d2bf2679f13223f08d5d380d2524bb3b6bfcd896427fa42e7c7bd94cab6ea5aafbdcb92a28527d5524e2c394b1f37b9c4d795b1a8ab78ce267e0e56b3bb925d07081d0f17cccca97e872fd655f8b0e8383120545e503e8ea3145e2de06249a533fe72f7226acdacafe22d2dc8fb12d8a92f700505523a04621ce21e0aec1fc50c225d578653a1ee4962ff9893248ebd5c360cdb3940caf536afb65dce3a863634bfaada3cee3d4c80b7fa6903ff01759182fa33837e1b2032a189c83098189011185449ef0d05de0e994601bc58381a9e773f629f7b42fc6270121efa2d85a3dd7dad63c5ede43d3d8ad9ff80517a0c51e2e111be77f5289ea44c8f19837434a565bf42375903846e01f414c2683df11f891b4de434dcfce6086a53021b46acefc78d46326da0148506bbaa31aefa6e03bb40886268ad2d14f6295e537970acacc3e83e6eb6dae1d7f3446cc99385b88b7a553a034874a55225d8f2f547b1191585dddda8fbb90def31d5cb9ab98a4f4e50bc3a71513b83ece3e0cfd3973c822fa02b91eb73ccd96482905e42cb1d976d097ec0f68ad2a5f4519a2a2675544de83aec72c4523359c95d573d6d964631f2eee445a497ac93515d2688eeb2d44c2da5930ff25820618ef1ccef5ed18521d541ca1b5b33ca273fc3a67c1856e20f879020998d3449c87f3c0f51d908624934cc35608478b1dab6f8e4d10fbd8272a3755e863d045cb46ef47edd28c3ef601b514d996e0b1777fa5fa4ce78babf2ad4d8f57e4f149905ee8c82db6d5569d4aa368486dd5d5ebe2ddceb5398d1c3a6532138bb0276bd32d54e943f480fe86b457f2c9c955d2e63fa924acb0622b6a95c44120bb0f120bd1fe69d5512781a81e16819ca1e53086db2818e61186b5ff904830ea0015234dc971bc5685862db24073f70de05ed7c6669217eaa20e9d570706927b15ca6da564e0474522fb647a6398f7dab1ceaaccfe5d15a021c909383d64b2fd8922a780f75bb0599290b24c43b40d10c7121ce72da28725392f609e7835ca61eaab5c150b38f0895bda49c1fb4a908bf804792a2a6b598a9fee88bc8887a2b22e86f2a9e723336d7df00e09616d5e1373e83210cd62fa9e588aa34132158a66fb3aa481317c4a037e672d3acf8b155e49788dcc9c42d4089f1bc03675a114c9d6d5edc9226d7a58326c524e2710e80d636b266d8aa1d690d266eccf7219e051acfb1862f2d71d2060a211fed32330d0ec920426c8552c0b7b35a6ad88dca2ef8a51ab9499699ba0c5ffa5ff6b1e12c345e7c4bc33d0142e29f542b6314fdb08bad207833c711a3f325d1f8a0a00e13cfc0147731b23279a2323a49966bba64aa4f2cb87554a56f41983186908162412c87691189ae1ce9da4c42e5fd84b95dd7fa0aded8db3d09019f14d2a34fa6ed74bb6ed22bd2ee59342d2eb9342876d23c65a589343351aa29a68086510b1b8067606b928de5a073d5d792fccbd8576aa0a1fd02390391b5e4b94557fd83d0dbb164a7aad55905faa8251ea89d20856a11aad64a77ea6286847271fa3aea443c62001d9858e34b3f8fe57370c95c55f7b128d66b97e8d635c002586a3c4b9b81cb7ddd06f8edc81724c59c874b10053f4db8c683309a422f0acb2da50dbe05f8ecd93f90c25f72788d3a19d61411d2018cd2f2a338146c803c2bac14ec6efdef7aef78697a2cec4df76cbc28ea5f16b0370e56d8a325b480b51b0614e58f470f7f79430f871bffd5519aea3c2ad25d88d2462fbc2bdfac80c5103d837f7c245793ee113b6ab36a873b911d8dc6ca978442ea400b7f06a2f83a4a694200412c6ee7b731ea4ccd014f5b48c315f9b3d039baecafdbb0c4c1845027d96d96e819e8f4adc037a346fd5aa26205c88309809eb81054c9a1a27657f781e817fe127910994ff0f35ead13a7a281c54702777ec260412231d4af83b576a01dffe696ba6253f54f09214cd32119e5e9114784c7c8aeb18c6e985c5cc584bc4436b32b64c924324531dc768d8ad1f2d1968a6ce2f0595afe43aced7a91cbaa4672b1a2cdd35ffccc26ccffa53a59c8c02e471d87a484835f2574c9de2afb539796faaecb556559da1811a3b93b33c7f4af35b742675478f936cbdb97ddac2b4bd7c8c540660b70b34d6c3be81347a1c3dd25e38e55adf92158447dae7a48f1d65c994efee5f21e9375b9d20df0c27f59c9cfa44f0286bb5b2c0cc6f8b51379394ac6581ab4532c073423464c54bf55880a14af67421503b8c9ce848685434c9d4064840fe2709da83ec27089195c60ffa98daf79073add60daa012823d69f24d387754722366c05b4f0dfe5669fa74eb8fd6b253aa1854596a23c7545372bd5c8b92aa51afa70cd6ba717adce932bf5a9f65fba6157c8e7fe050df641ee216121dcbb35cc6c9a30f8624251b93203c6a488839be3a6841cf97401f940cbe32cda6d71a018f9620fbabee7e60e6c4d1a6f63b906ce67b36285e0c0f9206f4839f7b7a0d883a15be20d2697fc67a36fd15791000db28260ce997fab7574cd1c5c3a5c7858e0668bc37b93e3f1e645b3df9d787dc8c78f40be7b6ed2bc7192863d50800eeb3928ad886c5fa8eb2632f829216185e7fc11c4784a9048d18cd89c0816b44a6fe5f9ac0065a362c1b3d9d3fbab1ac3ef7e67fbb020de27cbc612bffb2124c0ec2c0909542187a3181aafe0f3ca14541b9359a17daa1a5f63edd6c6372a018de7551e81ac0f42a7a64c0c0dd1ff2153275c45dfdce12fc7c07f6d5522c389595077315b3b1fc4942af884ce4e28c9fa18c60ab466902c79285f5a645e9fdf4f4f116637b8e04fc0dff363e09bf2398d818b11e53f1fe8b499dacb7cd6eb6a4f8d3b069ddb3f03b094bad2c160193a49dd9c2d1b949775ae5b030d4801cdbd50ccf5618e5f8b8199c074cf559911d67daaebf5bb3b797ed1a24de6377a4379c1f315070ede2a228f6bfa643537d10fbbb75022cdf52135984671c417b6a1203dacded199f0d9acf234f56ca88d48b7b71e24cd6c41e9dae4510d5febd95a47774f488b22343f5f7661dd99a015fcf9b40ca0550145523e5ea1f6d6381d254a32045d76e1f9e4c9ca16dedc0f10da705d5c82dfbd6f57ae2924d782609d29ece1b1a6b88071061826745207028c11573e77e25240300a2c8cf5292e4d356a2dfcb9b966614c52f6af5b7ef50a5ffec2d7f47b24ab6ac6f66a73d802e549e06c21f866cb10fc3a35a9cfb0cdf2bf433dfb4bd746d535b0bef3bac68550d11bcb63fa6c2cdd35b70afb913f3101d81466f6493aa1d0a0575908a63a862e9e80ae6e0a6c3c033e15554a3cce6e0f392680706dcee3f5b041033fdb9831ea421d2aef724199a2248ed07aa2657acbe31d75e881d4c41ef37cf19898b356624816f1c36911a397d2efdfa0fd5ebf0c3f1174f1af894aa13f7bce045671d05cdd423b6a1b264f6f2cd505ba584ea92dc94937f429a19ec31f668ba2d480ac645ec740450f9d17b1a9def2297501d81a19666af175fc87a4266d7cee6d9e242374c6a1cf7e11d3dda2b53df6b6fd72ced5f016049a4d5e3d1a42ecf4705dd34670e55a9fc2c38a0a9b4066b42faed1a21bb79637e68d7b264b3726a8f100ec42f7a48c17d5b57b79e8bbf175955c64c7745f047abda56afaf88315d4866bb092f08744fba096688dc3042007cc9323e7efdf85dd9b4d2a2e061e6348c7648ac177f4ca986500c78cd58f3b0d9c210bcc4d788748e65ab564648fc335d976617895e05bb7734081d8e4a4cbcde38531b56039e1366f7513633b2df923d285cc2be98176717eeac58dc3728776650e144f55ebf62c3fcfd75665acdd65c4b966a9e52c36878f0d3c174e1ecb2e0259123eca14082a3725d955a9ee41574abf070a0d610726d190e3c57cdca704356c98082dde79394e3f911b59749b74ded39940d0eafd7d779bac7b3b647d9098795fab88a61e0df0aa6b9bca6c876a34cdeb4ce93b2d4587e63aa8acee9cf55e18cf04781c446ae815d0f6330d0226925bc7d1143848de57a8a210bdfce1c27912d7504e443ec0039cdd4a2b0133db6b298f0cf50ba47e78c577742ec44199ade29b2cd326f5c00a4c58cf746a8f48f2aa2c99b31e4dc08344dd6307d7f156dda27a7c70cb1c1846da0d3f93b13a855d3bb5dbabf4ce40804061bd22ed525ef2391f9a5944147198622e0ad51948c7289c8c844f7882ce0bc2c5aec73588fde1cc46a4d1db8d769d4866b05c8ade5034c8016e0b6c8745a017eee4d6583aa142236e9803d15bca198b7ec3b2c7e7d22112d1c2647a553214fee5a9b5578df8c09b073dfacce69c81efac0992359387225817c04d20f7d01515fd1357f5ac0db4947d43dd104aea3168674c7c70126c75f1ebd4d3edb080410c4326d04e3d756a9ae00546711500036b1fec14a5bc92bff8a84b851fc6957e1006159d7fdd32eaea782eceb44cb03aac853d141aafacaaceb9adcc15a8ce94b732a179e7f45d5900d2ea5a19e1642d5253992ca646f0c8cfb7519b093e36e1c1ed2ed0ea85dd41cfe2543e26e830a23047947bccf12633846bdc9f9544fe2b81c9de4eda0e6a00a0f609fc6010d0931a7b623be8203d6176fb40e1c632957c5af0fa5891c152d7d0bd1029729de17a78416d106e678647389e2a116b5304a3075caadad16b19c9f2358d7a859f8d22226e07bd5057f81be816a90f5cf4cc386b2ccf2b3f3cece79dd5d5bc762b7c7805b0b6ee7624e92b57d880ffb4e6e0dae76642c7de74a3d5d6f12daf10e7519a9abeb49f7e15e6e1af8719594f91e5faa22723fdce82fdfa66c1c493be07e82a7c9bba6dadd8c8605a34c718a021354feb0dfb7616869ebd236d8421e0d4ca6423a3b7b954dcaad29defeb9d14fef69b00a3aa2f0f183531f125bb843903ead8e740a2f8678540d9d0f985687e7135199745fd7a5806cbbcfe48ceb1cc6681c63be75765aac77dd373e9636f2031d2623a82c391a16e2b5edbac11699df98281580e5cb765b50440970021a94b350b5e245c28b17cdd56655ff4af891dab2fd2ef874ea46a3d60231ed754f342ac631803679d69c453c949c6638a0fa791e38e3917f42d4f65f8580a44914a784250a20aba75842554cdca6ce5628f6457efa0d388f41069219d8782eacb230470bb8389b57e4bcb1d7b9e81cf4a3ba43dac1d7d2572cc886a4e3c80e5fc21882e621ef005c998346863d03fb0bd67101e466059b25e766f9900f4613754377f01da8b5c4c12b95a5c17b286f37c0f0dfba82ef833c18a0daaaea0218d95917faab27a5c603faa17bcc3cd9096a48ad5e7e1010f7ab1e57a0c3c3b05b696a761939fc2c326c371a50963a8a7ed9ace35d7bbefb446de011a49f1a59285ec0e42750125185711a1427cf3f66f58bc8d84a65cb932f7ea45d5d6239a855323c253e85ac81bc6d19d98539d6600ce2d8b5cf85a6307e01a2f102e5e10a0c68d8abcabafad650b04d4e322c0e1ceaf3411c47a64496b458f3ed6176dbf15703cac521dfda34007a000ff71c92868900273d22999356b7e0b7756bd1ce6e5da1244aadfd3c62217ed4ad43438e15a3f21eb6a0e010d4d95238c528d6b8b4a46af7a2c2353d42af78320c6ef45a975ce2adf347287ec9445d9eb35d02ea1409dc565b05e2cb882c342e145d6831785e4234e609649fa03d3d2f5fac77fb867edb2685c22255a37c3988a60126fc61ca627e2612e1e4501cae4637f7edf40d13aa364f2d8d827a6e6f595fe8f7c8ef78b22e760bd41540712685f1a455cf220e567553b7cdd38599a1d9c0e002e6a82bcd91ac1732e77b46db2bfa5a399ea1f1f30169de63ada0b670129b67663356a28baebd64b5f5de1a52bb606298e514f82e3eaba89ca33c522fae0ec69fec1fc8af7deaf530602d02c74a6ded356bdb2a9558f987fe03c4b61f16753ed2ef589782d65d03acfa6ddcbf1b153bcc8dce5aafd8669cb3dc07168d87e10f6e2681ca529bdcec76b8770fb6d7630db979eb3b28fb909f14ab88eead74c359ca8d530b63cfbfc7fec91e6243b3289e4d867b935aa82209d7e3787156d40a94dd7b0a258a938855970e5888217edcb07d87912510222ad5afa2ec1a946985b1370b253442f766ad170a0bbd4bb625a933da9180c4c8790de148b1579c864f53c567f933754a1a758b0d860e464886c2069e9da5efeeacc70b8f6efe972152782d258e3f71e6d46eb21a9d7a1fc5e8f7cca0619b47ef017d170925f09328b7c22ab93b0cfb27ab9d18824d3473c0daecc3be86f640da0bab7e9f7626b29c708efa235a99f7b64935e5625999a5a72658ba0edb0fde51453450126fd2925b461afedf73f90834369a966d5abc5d1e1b77893603ea66a92cf87d09657473a5d7f45d7ce1d68edac6df34c8964c7f37ac2873d17b473f07cbb99b0c0031f628f208684a08ae51d388c1ad0ddadd8f1688541ae974e8fc991902c7820c97e38de00fd654bc3c04e361e6060153047cfa3d8eb38b3b6186b5272e330629cb7408cfbc73ee6b22f8565ef66eb9b2f0707712ce0375275827f93fb2980926616e2a8d82d81ef3319f4ba26eb133738e52a451a5e25c5c7e8cefc99405924bf5dcaa96a7ad163eae812dc78c20025705f2d7e1aca9ab26adf6d8aa04569d77828ff91a391827cb8b4f449dc1547d5453152f0e2530147b155acd715951273a35c2ff8bd0e6b5a273975130f0a018a785f454540128d94de5e041cced46df18677c585916369c4a09d7d0400851d10cf11a9331dc2c44c34c52ac72bd57690a0d246ed18e526be6d8bba4efdb813fe339b93de6a23e4583c3115cad6e805c766afbd2e4964042717951a41657be3ed4a9205528a35d07a3c2294f19bdf043704c55be311470ca40a04a5337f24cc80faea05aa71dbcd94e5a7f6a000fc890e662a9988516705f495020cdb24f4ba4a922e76565989e76592caf326c4b3235a664331c6da8b555747128bc4ef07aa13911b5498ea3f67acfe918b1f04b55a95d9ae5dbfd33af6b6dd77410614c5b911f83da26e19d3fda1b996994b28969e5e0ab6f94fbaff5babe3f0f1aa172459f630699d0a37c3834c97de1096a43c76ac4bfca280d2627a119cd95ff15b91ed39548ba23dc5d8759783f08156ab0f0f869c6e1a69a499df475a16b960ddc6fa4e8f93253faad7c49e4ca5e05b8c19dcf2a8cfa3f64b3d3077fd54bfc8aea4bc68dd771b48b0a2b13b10e5a01ab13226552d3cf29b4d28ad210c4845a48bb384e8092b6053935611b080c2773c22531ddd65dd8575b5c348e3708c091e753cba04d36b2234d8dc1d2759bd47f8bb7514558af822b717f5503a81d4aa7916d6d3a3618a0ebc68bf6de572acf0608569d12a0989a8dda3b58fd862af4c76952509a4cca1beba8c7e423787790d9fa0a4fd1eeaf13ef61173e9d9ba855cd02cbfecd947ea7afd9fc1e748739eeceb854e4a85d7cf9ff367a05806c6ed12d57892783c318c1436ad0fe5c76a2a496470d2dc2dd40ac63f9231653d413da00cde1b9284fbc9c5baaf5235a9ac081873dea903171a4c87e6c5af7616c9f0f15468ecacb1dd9cc5ac9e804c00b9cbf8e0135f42ac31a89d31c8c41f12eacbf29052005a8f6aeb06dab449cb0634ff215d68b19301b6a4126c8678a46fb0dd4f69d7527f8d516b84f60e248b9e53c04ccf000a546bb0ebe79eb8360a813a57092f164a415e667831845503c8254351969046b32da0284e04c113e00d626bbb4512cec59329fee50adf828dc136e69040a18fc25d12a57e6ae8127072a3404f4a3bfc7ecc3605257a3254de1405eeb64eafe3deca4dd4f1e10446abd122bc223b75eacc6f10ba5f9b00b71ca7aea83f351825ad6868bd4c81c49575ecf51c2c35fa813e9ad5ab2834a1795d4fddf0da51b7da553f2420bfb34aca98ace9f5d8cd6a423439d26f53e26218034b4cfc98f7442f00f8c5145233d4367b0e85553b8330c993bdca3f43d18a85d7d5d424cc0d482a8f13971e65ec08e84afaa3671b737b6a53ba46031c99031794493cb4091960944b2bc8d74861a34bab952ff0428fc64a836ad50299e89f99e029d99689be6c53f31c4b33e5defdfdb5285c87d993e694f3e793a3059eee60be1bb40bc5c3ec8ff7672e852d8715c3eceac3952838b25187d75044adfb95691962eb77b2042ac6c61e05d46f501602df853c43171507de8c9e5ff6883d6f5d58cbf78b54861098b0c0d70002ba181c861809ad52cb8b342f75dd4a148cef6bf750245e711e8521afd0559b6b7032fddd5507f7c9125b9ecfe07ea4c8d30e47cb27e9a3eaa5545e2ec7250fe362a1ba55ca4919a522721b4d0be1936281fc6764202932e7c0eb59a14bb821292d133779438abae1da07f534e1578ab51fa06ae85e5cf6f13d94b1e90dea69aca8ce4b89022f9cbce72dd0a22eea528ce08c9cb95c2d00e9e34ecfc6b53a56805b5b7f793d1db23ccbb27a87162506b001502cff029be276155ea7d04cef4af5fec53ef804ac46edf1f98ca36d7ebef4ed5fd001baaef420d10d2e9944f78842f2c1cf3d3e8e51cce3601a45bf7dbbfe44b8f5f085fa5fd78d4a7422ed4149a88571b2d2d065d167fad2c3ddcc9a7b918704c7045d32bd40a44f6812472bb46eadd8ca5ae7d3ecbe9f4388ea7c347753504e40074752c4e4dd015182e7c54b4d8f9e5e80e6024938061409260ebdb1f2c18012845299e160b24b641c9d90ce293ccbabf68829a307ec2648b16093cf7483848127629143111ca930b783554d3b4617e153dc17ccb6a88fec7f5d7dd58001886c4390021f398d9829ac2f38b000120c499bf3481b36dae2ee29f24578c7de3c8abff0c86b54812a9995148df60379d899992e1811a943ef4301e3d9b066fc72503b91338c3d15cac7ec17d03f097758eda6b714d7d81e5e2725c46bbd75852a4e6173226b7d5bd8d0557d1c0d6b51c99d37b1793556eca781df19ab10ce19b209cfbde7eec7eee750287e2fb0a1fed9047f3d0dd5b5e5b7123e1cc15d3c72f35c0d94ced44d910f35f478afcca912fe8c5ea8aae4503d480463d9d428942437f3e00affaa54010de4c24b6b7ff8b2a5882df1f1a50ac792a1c33f3ee2801e315bc244c88ab09f34350a46eff922a1df0e5198100d59415b76a9d2ed6730b51f93bb2a9af6ccb79a2efb4e47442a3e880a378025d9956aff831278bc804eccc002aa9b938706b5e6211241bb55f4b217982977981c4e241d4d15d84d9c880942de3e6d9306c76fbc3db089b2d1c4720a7f21ee42036ab593a69800c2aac77d59d66a096eb794ef7d2a0accee6c86a59b6778e08e7fb8fe53a87d26fcadaea27969f07dd7b87289c94783ecfbeb6c6d11cf22869a6f53d87a2e14c57ea8e7f5b7cd0c0a31210a8c8bc8801743b19414add9e5666723e0fb12c1e36610c95d3172fde2259bdb85fd8d58c06e358b4827828cdb091918c1de432e4d4a1e51101a5c1378b39a43ff9828396199c87c164975a32ef1fbec2e26180150d370ad5e7e6ea53585fd4de57eb64e186572ecea4f8374e17d98923deab051115648eb302773e43fcbc423ad2b08e1b42c87ab541b4f45534700ad124c49e547255b50a6380d4ff5e2e034debe4183a7bedd0045effa71e3200792f03806768ac1cc304849541af22471644066bcc98258653ed0bc0c239186cf4152649eac0c51ec949592ad30680f916f2c683b7d08b8c51028ecb19720e1278310f42c6c241d0c3b2750a947f41d231a7912af642bff4759352814d96ff9ce293fe5eb907e2d2b324a23df174f5f1c912978d99e1a8da954448d402717e75174cfd417bf52d71b7808d546eea47ed4a273511fbab515c34a8f433bcb3ed63a6e505fcb6222f67cbb0a2390782c594d75a5d850ac0e56888d15511685fac7f803c58feae55ed978926bb72009dcdda3069b1c03bb9863699b41d869ec8c987a26c1323ad04ef73850f990c2edc5a1f6656347852c124f1da5992cd2fc242acd122583edd29c3252ef05a023d2717a91361e56678159115a79b209a6b18ccd98a72c31f78cb73ee21e078369837c7c1566bdad4594a8f0f4eed3f448dbd0e7b4688e44f22d88690a5d9aa7154664f80ce3ba2432fcf3810e63b19922a66d6c939064a09b22cf2bc00662e8e4e5311751a90e32e6e2c076cd34e78cb9247c4b7180ece3bd55001d6f2cc8c70146224a3a3b6c2e1759fdd462d487b4d6255d92080fc2304fc45b212652d1b0880d218acafaab888d4325af5e478608cb3bd9aec4ae7ef485c0f6db0f0b101a03038c25b6b0a26e0e545d2909380c0b3f11a70158d97bdb4a860b39a0fec9b2f895ca3ef60312d0ba5377a98f3d80506744330eec0387596fec3992c2a27bcc076c01db817fd1fc1b76d7ee6f20bf20d0aebf01c2a49da18ad49a7dce8b6266d589002dcb99bf42f1ff4a12d72623fe1393262ee13d5e15899ce40ab9917b078d5cbe7f43c117d0ffae6967f8c0e134cab850727d1891c1aabf9fe6de2bc51f9eac47aadf79ed1b591f8d88dba642cb1b990b72b8be1c111b22724701fda122f45c1f26df4d202c16b288539834a4ea71c467becf7048ede3e9b8d4fd0d49c81752cb987ce0ec9aa71a8bbe2f0358af874118982e4852e3b442429a75b6356023f30e2141fbf829b56ceac49bd3192d74f4f12bd63ad8824c89b76a8c6d7e2e5581820c8d1b46ec35ed8931d20e202963c3b644d6db770d3fc7df09c415c3995663c4bdaeb11245287ea1d220060b9c510f0bb20f11471134f0d3b693707156110b3299024fc539bb2c02bda8cea2300bf2313cc5d812a900da620e808af628f4916277f0ad83562e03f9c06830b367d7c25a41dc06bc11e8aa2b1ee38001e47a08cb4bb6819d400516a7aba2049bbf371bdcd36d929ea0c940291746ae12532d58068acb48fdf64ea612a8db0bba450aa64a957595f2d527e0f399218f23c16ccbbf2b3755d574d37146a364089392fb164eb2b28cd05e3ada086fa1efdaa9a4bcbd48f8202188c0fa8a88850afc7dec3040a2684daf5f645a10e0337b083e0fb494a03ea02ec21f3f1fd95f530db14c23882977c51a591eecd5c046491b611ebe98b61abb29d4a884b8a4f1c4d7e4127e609541fbc7d416b2ca7d4a707f88cad22295d3119c417700a26bbc638a88bc0543ec8bd88b62ea170c4cee5f83892cc61b1ec031eceb7f87b6c7af9c8da346112986e3e3037d2687a4c685520009b7b54e1da1f257a088639f36b271db03fc3e8165b12fe145b16b08da4e8b4d16869a7d251cf6fbb81a23c1cc5d4492607b581c4b11a04c26cdf219308b62408bcc3c9c96cdff3445e4dd8e9135c8dd520bfd4443fb3220939c11d6b3090a37ae43405e1bdbb02bb923f0464c72e7f29725214fff3b6672cbf150a121070e94939c97a5e284011b2f7f7e014764957ed451431c1dc9114d40da298693d88f3e9283c92b23823c393f5bf4810e8fd1594331ddfbf924ec4afc5ef8553e7502837a28561bfff13699961ba84f7d6ddd3989405ddb580d95dde591df6942e39f77b40bc8c3fee1491c1dbb60e05392851b862dd8c63064c25d607d04f873884f0a77e030bd18aa7f33105144ebb39c46e2358502f5484e17e66530975ec425dc6757853c5b610a8bbc772c3e682a8ef933ef1d2febead5810018ca516ddf6bfa419e9c17fce4d81f5b624dc45b4f510eec1b5e6fe51454212a83d5e31a589fc60ea7b0d6d3db1a2c96850f5056e00213502bb8be74869ce7bc3846db4114a698892482889fc9f4198524267e2228fdbc783a83b55a0126477b2b82133d50ba388a487ba4a10ec82f1274e436d090d4288b8d5323c8425e2c666c513bb001412b105d01dc350dedeba641cfe81100cf966ec3992f74ab8166208c2c6af14ee77c20cb000abb2d13b229e0490607e6d656d6332f4490654566872b528a2d37a91f34a14aca42006ad774161abcb8a9136da933e115b8b47a1666cd13f7b1abb153abb389aad1250bdbc99c405576f3146b81de66aae21882716d008adb2676175e46e73a20704055f4c58040fb00316f0ec8051ea1c296d099f87fac9b211c81fd037d56025581edcb6d40132798c3a6ba004c64bffdbfa4643361dc778de03a2c983cd65ed215b7151587516a5c980e58ff3724c044db71aafec2277e7d2119ffbdf8d8c717161aa9dab386e5908b2ae8d38ea7cdacff9513b6c4659a6b2c2e525093e00d67473753f6bc2f28455b41940e4dc537ccaca220ecfe7b60d62ebb5ac1e1938a258ecba14cd0545c31a83d0f4a1c19a507e3dbdfc2d12d815406c3495929d2288bb625c1d1eb8b78b0db3736ce45860a46000f0b6a9a5839880056dc65269688cff75ba262b031b1469470d96c7f24d86e53ce9290415b229a4539d31725ec39fe414b368614dfb65fcf3d447c070d51e212c46eeebbde96e256a52cf94999fb8a0764f4539129c7a4ac04b07069e89e287081f614d5e354d13c0aacae3e75f97c4e6742cc9c75cf1e10ff67393470160020070bfd80acc7c63b261052b82d7c26afd15451265d0145f49cffff6ef94f6d58cff83a9cad31b6745c21fc7be94207110d2c072df280c751389d6173a91e8a30f2b61617ecfb93fdcbced05537e972a7d1b479e153238ab94444a1dd1564f465aaef4998f88de9e7fb215ebbd14e57401b3738ece7b504a0dfef3e624b07d486e387a3673a46c33e5214a9c5c451707e69eb4a07248aab27fd6d0b2d342beca765789bf01e9e40edb4add1027058f71060a4bbd8b61da4fcb840058ada0408ebf33629558b5344901d3d54e4696f1be572257a7e7846ee307afaf322589a705133728c31ef3d2a05706146ed967b57cfaf25b26867d8773ca2898f3870d1ab70f788606074a2dd46b3f5165abb3264198147b9d935cfe35421103dfccb73722fc5a9a97edfa8e079525d09bc06ae057668d4fcc5bc470aa05368167b4cafd69dcd877102aef4bad923cbb0b5f17ecb17e28c99e903d026668e777ff0bf2580f714353be0d50d66b83aaa6d7a00263e1cc97a8ea27a1a20e6e719308ed5d4cfc87ee75d98b5b610ce092cb9a8fc1810c66018a5c43ee0b04506c384a40d5f325e2282658eef34cd64494ae731f7c63407bb128e969a1fcea245fddad0e3da97a6d848f9cb8335578c4e9a9f60471e7c70b2e703768445b5d03a3d061de5ae0701543e030fbfdaaf0ba6310e0dce1a93a08506dd39c22404eca6707dd5d0a07bfd8b2e052584261901720a6216bc8d7b5094b57389573e5b6ea60c17a60786bc17b6468f4664d38b0ab9c145b126d9850e521c5e7c4b27889555b25c43d4a07512f2aaef21f99fcb4a7ea4076e31dcff4cb8eec424de3958104031e4f32f1f1bf4b02ca1f7344bddc46a293dd25aa99b5896d2439aa56e62b5945e69a7d44d2c4be921cd5237b15a4aafb453ea2696a5f4c06950827ba3373fc81b8f1584ee792f610c5924391d74f7e9f80b25621f01e710749961d2f3967ceb6b8ef524cc3ff1a23e0dfa9089893d6f9d4e08044cea5fcb11b88081439c4aa5751c1a0a1ac4077a178567b65a4abbaa603c61c57596d1262402a6bbab6e3b7fdb84a68e8d3c73538c0434642fde09f386efc3b8e1f7837503efc3bad1bb61dde05d5837f60eb06ee07d58377a37ac1bbc0bebc6de01d60df0fb30c437feae4ca3104337e0fdb442e986875c3977f24ba1f0d2281b983c234f9575fbc975a0c487f86e16b40f9e6097e68171d79fe023fc6e0ea06f40a92b8b91560ed67356d4f636f7c7d47030002e33f2af60cc217b99f317539b098543dfaac60b702a1a25d94519567edb0ae9600a01a99a39b3613a6a1d56a0d8620d159fd106c59b4293713ec5e5ec72324ce92be90cfeafd06070173589fea84e60b9f4a592ea0d8abf0ed8c5b3375bc83aab318d107b881a6e56a4fbbd8e1a052b336c1e972c8d827b4711268d5f625771ffa988754e67852e5e3d8edb98e6133822572e31759ce04e53c1bf739055637cc044055fbb26745e8ab960ea1cbd58c7e81e83c3f7a97b30b26a25938d8d5c08dc518ed17883235436890553e7a856d23d673aa45133c17568a9fc12e766e06599247c459d83b32a3bb043377663e2ebb609ca1ca76e098b7d1f913cf78772a26d7b743995ac5227efc0313382d6393023da1473225c22eb1cfef7841c1f54cfd89c999e0e53dfa067deb2c0b310ef7130650cba720fb7f1e886739d89b2fa3b709032d0c086496876d63f2aee62d74d8d58156752abafc32113c329b3511acff4e9388803736526978c9eef474d1073202ff0c67297bbc9fb226b9508bcd7f883bce6ae9b485a29ae25dcecfcbb02331f4e19e8fc4e55d81c329f70dd4459ab71e2ae444a389c525027f075597ece5a10654a56c9d271ca08041c1118e3a672ce386b29165bd3091cae2b71b37290a6e624f1f5ac2d2069878f2b58160fbe2b7f55c6d3a27e4b8e7b0a8c6dcf51997c7977241c54f7a1666558c89d08819b3ba058fee2b98e5382356791667d5336d06f2c1d43ab4bf68d07750f4b56e022ad81776ce38b558e71206322307a2cb1cc7305195cea428236dcbe519a1c515519b71025e3dc5096ab8a1335ca9b26ac4054570e328ec14a5f228d495c1468025c959eeb7ae21362dcdbd1ea2bd94aaa01f22683ccf005bdda1090c18fbf949a87527ed048b5b81b138684bbb7be743911c3e7ebe98de78322044db4831635abc634a68c6494d49a7b4509240e5270a0c8460fe51fe4ad2ddbf56b430d21335d285bddda64603afcb18cd78ab9fea26597f0f7afb26a4b0f4b920f1410574c240a34113980afac11fa9273f4618fed210a512ec0ed90196f87e8c3232fa9832ed45bbedd34a6bac5ba8f1a222eaa26248e5c5ffff66bdaac5760b06b4854210f6365aafc0f66ff90e8c2fe5d127d844c9f9544864b2edafe041a54b3a7fe06e33a9422f5b33c3f21e95d46bfe33e77a68959425ebd9e43982967346c6c2e74ecd938920674a0203ff32557b1b1de753f512e09c527ce7780cd7469ec53be2ee9f16a32d3af634a27b09c005bd2e6f7ec91f64e71349a9020f6eea3ae8ffb2b20b8d610f7f4a7156131de0f788a55887c2b68cab2019845901900c2af1f66e2ef4ad55330cbcbc0246e331ddc7f549033e9c39528668cd052c4129754453de7e8d60fa5372424e736bcb199299d7c8f90f51eb2a480049196e3014e02010aa683533d0098fc053ac624309883d9d25df0f60898a82969ac5ad5616af9f9200591e2c0e780c46ed93598feb5753bcbe8127ed6e25be4686b8eb86e923df566d5978ecdc39d4eda7cf65f507353308fdd8faca1618bfee09d50c2eb02a47d8e0b88f5d24530149bf421187b82cc0ff854fc801041877fddda7c046a7157c347ce968d2ce4b6619115349ed58a039381084b600f804f65a5c04646bcdd27b5e46ef001d0db1a13fd0ad1a68eac9eceb0713fc6475f5652dd71c8b8e6cf6ac16c78ecffe7383cc6846d9f940689606d7ba56878fe64bb4862d03fdc42a714a1117205f72708022bf7fc992099d4eaa62d6f2cda061316b4b4eec0f5ea8023e4bd78eed0df0325f26861014b4c1499d312c7dd488d87471850a8d33db772ad40d3c5163eadac96c86e0dd55d0b1637d7871a97f8e1d60bf49c6976cd0118e7f1ac9900ae41b41c0a8117572088246bb88a44d4a577795dc46626d46653fc73ccfac08f34d9f5345c3798592cbee85035b72a4dddb19513d3acba94e9e952258c6c2919091e64731decf1c10c746af52dbe525ade47e7e6bb837939e7e72980c4dcbcafc733c77573c0410607c97a21ce102475e410589882a2be0b031961c439c1f8e8141147507923ea795b5f75a9c5b78a3815ca17cf461d5b0e531ceee375c14295d444103714a7ec6bdc1f02ea2b201c1cdd8262d9d3ea8bbb811dee0180a96502e8496045dad2b17117d492eb223fa8d656742ad5fc62d30c2fa80d39fa3999c67aec911721ba53b67819b74c2379988f565843594ed857b1ee5be3c2334e8ca288a69e33e3dabca6824a2c588e8e8656521dda085b873318d97127cb510aafd605633610beba7c3f7c29e5bd21e4f60477b4af7f070c6bee4ca7d9f029a38dee251f140941f4dea5aa486275b7df1cbe69f12389b8664912244bad9380ad8a4d9efd79f7be4d33ed953b82a6ab844053e332eeb29c469918455c789df996aae5603df3a8a2328183d36ac5805aee7478988623979e84329c3252d0385e8146ab7e040efe1740a83d9209fa60268e32e8155e5b3e4a5cebfd91ac2b538b13057cef034960f851f219242aa1606f1c7de9e4b961234720c33646f801f862285e1c11eb9c95265df7d4dad3b51d2156b1da4bc99383e770106aa143517d1c25cd4f31623d0d7dc679f07b80e8652892a21fb8e9948f72a4a0618f336430959a2068f7c4dc91d4aa60634bd617f4fb33f38654b12a656970f21e575345bdc610256ed7eb429aa3613475ba6b2b1aa8bac0aa1e7985d1289e9951b6d17c7da2267b199dfc476dbe95a180c534417733bae6d2c1508b23caf7d86d16b02608e146b119c4992766065086396d251e164ebe32d8bd9a984b5bdc64ef85b22c84baf630c7c0082e998d6935eadad9ec3f2bb21bbc448964bb3843803296c335e9e2a5c5ca6cea625b223af24a4b97e23655883eebe3455fc7fecf8bb53fd55000046ace11286e2ab444458b476a2336cd1ec95ddb099ed487e0e5d0760b13ecac502d7a822d15c73e4eb0cc386e63fb5f48a3b8eb2bde042f6825fecb8a50ac347715194803fc0df192214cdb60117415dbd6fd171c76f17cad6c0fba959257219330137a890ed154e0054307087fef09fb0ae10584a6d4659db4f8812529d586b66c59f2aa2e2b643c31d58e8899835802d984c19fc39b9929009db588a976165a04ea12eab00e70b74e3c4246733ac2d388607c734ccf2cda2d43e9079db383ab9423104266a0be4164bd7f9ec07f7be819a586c18672bd4e05b5818be830b8267161745340558e31c408547b0f5a2595a89c34cc4c0999bb4f506f808d0e91ecd85232604034fe384e0588ebc0b7289863b1c8b5bbd567aefe3811f8fcdf6d56f3720c9915c8d62b49be562bb0e0d57010d2fd4e10f278ffe884813599b855f9296fe6d047c155b362277b0cb45d464498f7e680f6bf0ec00312374cd30f5a6850811c0d1e0183bec4199d89452f2b226d49af0c0eb09d69dd172847a6d0e263c08af2a884ac898af8ed7de80767d00bc97df4ce395dc5e1a09c06e9022f5719006ef52c859a168cda40f1c6c81984a33e6bbc3b6106c51adced96065613226c6fc2fb451eaf3253a23e99ac8c329a17acecde88cb59a20f8dd0ee9de30201b1fd55a3e455a092938960253f160e74049b00d218b084eaff5690af767b93898b61c9008b35450c624889a903dafcce3ce0ecfbbab3d9d90a5ac140c769e6cada2714c5206e1a2b44214114f87667beb35956a704e87301746a23495505555da982538ee5c97b32b169141cd94509958ac36f106e2105c9d145100eff2da1c7341b9c04aefbd5a9f84b8e02958b442ce1b985856934053d9773e89b3a62d26f14e4d6fe867d69ceb75caec155cf8051a943f90e4a6f81d5e9b087649c5f335d2e922ab1e1d907cf4a90403cf2adf1a9b58ab6cac95d7abfb1087b10715d52715e011f2c2b48af40e966f475454983a41645e15ef70aeac87da29755d25412aa154351620484eb7a5afc7046060c928ca1259ccf27338f17f0fef03dbfa0f9828cc3c469ec4af5739848379402b85e7b8aaff26d4ed7493b235c6004f40c7f85314a3a2690bf908c3b0031ccbe997831faecb1fbb2fa03f77795b2c74c46207d39809b36c02df5856d256bdcd994c63a21d7d9598047a5969a76a7b4fa1b0468020ef15f049c1b7a10486acbb350123f279e98ef09a27b9fa29784478b59c6b9e9a0c403112f8f9740d5900f0714e0730888c65ffc81e34d4d2a673b28d1b9b28dce95bc5092602eed092d4a3f5525d17fbe3745d83a8f7b65f0324658b69d2592417a2299f86da4219a380b5f671f3847f4849dfc1bc4a181ba2b49f3dd7ed39c7a3c3c8085537562667f51e02c669358fea0f34bcdcb4297ff1ef6c4639592ac068d48170908fb2a80a69296df29dfd53bcace41367057ac390b402765f5cb788beab08d5176b925b248eb72afde631e857074ecf118872419becde7740114a3df6528faaeee7cdf41eaf3268b128ba825349c630494005876070177850b313bf229da604e80da63a12a3064754e998d22bb25643550096d21bc656616047944b33f660c50467336696a966496d889dc5205c8c2ed454e11aaa8a18850e2614a3f71216e323c187fdc7ac718a2ea75ea946dcc30fa4b3c6ce826673ce4e364ee73bcec82d7d9fc5de57bd62e5bdaf2d588ddb9dc65e3a23bb9fa94c28e95656e7cc0ca92f5a0811b302a607ad383739b78576e4655be8396d20b1ab5528a1fb1174a8296ea4361b0366e2a502274848e1b604878a906f33f03ea27b82001b75f5f8e7eb6efc9cea709644b5d4b7c90890264bf96e612b08a45945c2e42b9303a4fcf58b63356dabe3087958e4f27503d617a82f94bf954eba99b68bf4ee4af652c5cbf464cc5dbd1331963f02e3d87c9624ab132869f40dead1d7c5123a3875308abcda23096ccef53f6a316cc0f6b3a1eef6d5f0d75723ca0c000aef94c0dedb6c38bff1c739eb5213900cd4750877317dcc440fc1801ac9584689dc068a88e0091c83984bed6103b6e325359c24eb5cce42cd60105c1da4100035f0c393007177431b457034606c24e4e812abd17e847d8fd68e1814b05e5423bdf701a96ef81d738197c9439c7ac05b39b58be3c541a5f28bc50072728ad1fd395168ea42c422306ff69f5a018bc79b7f93f884a9120a2cf297f4738f85914602588e2d35ad149dc2dc0fcc30284a136127355bca93d934575fc334cc1a2ceaf0c21f255d91a195e5453444b0f37017d5246021173e7a1766c43adf1db814cb4d9e191a9de0805832c1c61b0b6bf2b2fecdeda8103a4e933a2460a07e457abd53e2558aee077030ee7c00096d2c3d64d404d0b7eae85997f4b6500bc06c03e7eb62340af7db94b8d72a9ad3aa1ca62de1f5963abb8042f7e884bc372d282a6e5e053c6afcc4b2f5b7b290756621b0c8087eb8b3bb5fca39789b301de39a2ab1359aed9010e32a607dc130db40bad76eec37d1ac4c81b0e7f3d2723660b5215f8f6a5af0a549400952fd59b40eddd163abf44393f9ece3f7f2a21a8d1ccd7acd3d78075bc1c01983b4afb123d1978f9a103af11319129927a02a4888646f928fce98bbafd0087787b41d23583dde9805e0038a995046ec6b8041bad4cdb7d374bbd91d953088a2c41d2a0745162829988614767573602be793b0c93143918323e323909423a60902aae4fb9cd7f6164d554763d0b492760e004189cd9189e95ddd4ecc6628afc717895d62765711693061aa110f27abc4efa90fb7a078354b20cc76a44bed617bf6367a199a948dddec406020fac3f831a130cd8d96a81838cd7a312ce613678fc3767a4e8b420e767c507f4718e1789f899b0211d0273aca36666715f18f7458f045e5862d8cc044869bb7e73895104109750f3ea8465458073ae53060fd68bdf3b24062f200123532dc674ff653b25c9137844dbf35d1ab71866bd2d86a5285df129f2db8a83fc5b34876edfa0470378a3f3d7f18435bb24ba77e690ff053eb7ca005c3ef5c0c1b0d5161e79e55e65606b15c25b9006c7bb88c3155815f19dcb43c1b7eba3f8db1e0b452c3b35c00ef2dac10ff010d453ac1809700214f03345fbf20fa06bd5815105f2c031c0a1e817e1de58282d5c2c5722cf82be4cbed5269a84ad71a28332d664dd991e4e18918a26362220c8996b041900cac03604ef8c1ec923e2d9a46bcda935c03d8b2eb8db7c3220076e1a5080018005b03707d83473beaa4bdda15455a1c0c21118a100cd98c26a0f5a75b30c2b9ab5742112fb994ff35a59542c2aec00191a624d7e060144c58885d58d479558541eddd1532d2498d96c54173840344819bc75c9114af54218ee89c624aa714f6f49c67bd6fe08eb402e068982b83c1db2316a8558fda58c07962cf9f73bb659f758a3bdb809c639bb0274f6ffcc61ca991a814effbee2143601bba91285d580785aa109f8c94edb83e942c4faf443f79b15d90ddfd11ccf8b00b2cce883be5fd64d85865ee327bf8b0f14660efb7f98250d1e3ae454dce7eb2944429248be8582898f0c0fd606d2d38505953bf490deb771b12558a3df13b57dc2a58b51a088d084b7d9b77a739d9a4a4243688fd6e342fb74fcb2a499b057250ed41d4fe76f818fc09acac1b0729d10ec21b076af514c68a9ad9a26756972066712f467f8ae964f2e7a3392bae365bd38339022cac721c7036c366b53c31d83e18d47444da24331a2c486d4fe215a60fc6c02e5ae52d70841e613b2cf35cad27e584a07a1719224f944c940e5bd32ae6d4f95172528dba6096272e2e9a837dd5b3bcd1856fa1087c2451127d2bfe0bd8aeef5c14255bba3a7530369f87c4bd038752c80a845edf4869501c27e23b45773aca420e6a79a174a9689da10613815cf3abc10f48302d906b889573bee61f8e52f984c59e2fd4029638970a3a68f0cc6331ef45546f46729af840e8a995f74ea2bb2d37a0630bdc0d3485ad2a6c86e6e10832ced6f5783d248848fbc7bbec6675b0e6f42e9767600a2c2baaeb089606b3d378b012ebda0ab853e4b15678e8b5cf6f4e126f5c6c06149b1d7fb98239614c352afaa43681481c26e393e2d1fd704c6fb154ea285ae5383593728f443243c0416050010aa39449e241494be5a6d664d3726460517bde25327452a0fc78b0029316a70942754befd08568d3d21afa6cd4481d144c0a18137dfcd2354d1d7d4c8991204c5c4a5a3b3b39b30d6fdf06768620b94fedd0f1719a2f1489b0c19d137586172ec202e892ad1ae3083920c460dc87445dd7319756a2047534255ca2fc043ea5765e50fc10b3226c8620ad24bf334d86df33580513f75d529b67c784b89d4bde3daa20459cfd82d287b5aad19ca065cd3ba62b0d1da26e3493891b0a37771620f0573f1b5e4c40efffdd32b7311f291da0146fae04739bea64ee5d3a895892dc330be4573b1c5899f113c17b0eb6f8f78203da69678bdbb2096f22979b7bcc47465004bff5e90d261aed954d9b9cd4afad2a1b76e38feccc98e326166300115bcf66cf3b4070a441db76a5cc179696e0975bf5c5c94c691919b742191bc8092a65cddc32c1b3af71a4de6f9d8489340ca9f8e8b6b14ca0568f58aa6941329a6937c2e4a5b170f3c4770e14a5498ac2818c18b1a6fc1b82c0a4167090a047d63b5a8ad8b82a81dfb51c1fdfb0b53771290d34db1536f62ce2bc0c6f00675f8038a8e969cef4871f8696c6a46734e3c898715304da2ea696fa0215f53e8282004a716f406a706495676ff3000d8c132120cbb4eeb0ae23c4709615d0168ac60db9b66b1ceb067eeb8deeef00e727fe0172755df6d159a6771a3ce8a057c1b910fd19b3c92682be6ea1286ad39b81a0d80ade8eb88c83b2e030bedf52f594231afe86bd46536768b708d16a9248b1049237cb8e77b045cc3a8d60778971bb9fe3ad09a5d366f71051abaf7f3919d724aed5c6b2e0fed46415c532c2f279bc9ee1198740220e5eb950ca686f26057d614217f7db9aa1b0680a4cc6d35cf7be38632fb04380719b60a27e31abb7355dcdea5a200b01e969e33d4eb854b717921af970e80acf4e96c717e2068121960d3402e17a9f304bd321021bbeb306f4cbd4332a95f9e4419a026826c3a4496881cffb096112f1845d718720b862aaed881f61362c1a2932d867cb28aa54206240db465be2715cb239912819e4d157b4b7f04ac7483cb50de4024660fbaa41ba1a2f693ea22c53b9f2623dcd3fa20cc03aed70305448b3af3a79e7d2b31054c8b328b2bc558205c11597631421f7ab6ea1e9efc10bd2a82da283344d10d7fdaf5acac391a5dc569b12d32d189b45fe6aa89b9f222763870ef60ba3907c95ab904d2ca4c5c456541216098e8c16e3918379b440777b29e9a20139a377a505c74583da7f3bfe46cf3ef34bf905eddb187f807d8b0216ac9974603cb362095d2ef777a583af81323b41aa4759d8e28b9bd51b6625b4269dcc5e93f9cb99a0bc17ab6fd00e0da440b56a6bf8fa366c68c1851095679d0b30252235ee80221cb07df42ae57fba3ed80bb9d7c321809157cf7aac5e83ba5a953d58c4d1d33665465bfb10f1b00a21f68a71260f5da1e155a5797fae4f74e9960b69966f84c4c8c861824608a9581b0c1048f0baa7bb9a5d26d6a52931a232900ca3ed7cda2c1b2d73bad1f110948031a44b95920d357f9236ab6a8b66b5bdf16e178c934660f319903ae2ff45bca5b436dc79fca76d9e282d1eeb17f706f4c8656e5c5e22248accfd85367322b997dde965d479895cdd460112634fe01d89a6b08db88bb2ff6210cda13c2f03428f3025396acbe4ccb9fd106acd4e2aa31e69887abad1a345c014b39b60ac96051fd5ae51c5c97e29809c1e5cb65760dcc13afe2c32a2d8eceed99ad234d79444c8d57c318968f6fe9e0470b684063615d9b46bf141d422d12298fe4704b01be25c13eb1b7f2d8788d0a664d35606fa78a46f4a84805878dd65d63d12e20541f08a0f946da450eb1006ef3c3ab1b41a02cf3c0b308e46c41a45f1e1657a49d97b81889ab8af8c60fe57839f9bcd23c2411d2d6653589596aa4ff2c1f1fbad01eda9faa1484d2f3861429456e8843db06e788ddc8668cfe496967c863ecd61684c1d16a0ec18d6f8d2f18140885c04e0bc51da0d06f8496f546bbda64cab16ecc67649c762bef2783d8492022417a232c9a906034df6344418ba873e7c7826b592368c140820fa4493c08602ad01d4a81f37a22806f4d6964958002c0d5e6509aae697ee7572208ef3bbae8cbe2cc8ebbc1ac44d220bfb171d2b3a212af757bcd91006915320ee2186f04a12126bf2103c897d45864b70e81b638410dd807da4013ae0a9a89ec8deffcf3bd4c512e1ffd96c802f2c668f11f6d3307d6a72cbf63305eb17f71d6ae76026b646a7a173196b0821b99c7cde53ef22ef1e087785620bd02322a22465504fb5185e2595efd6019162336b7ab5d9cb520067ead17360aa028d48a484f343e5dd7f4d969272d1030caf4db1f50c3aab32dbcaefa0280b71681d596d2698b7ddc25024740c9da8733dae2160f661b64abe62610b01fa5186241e2427e2873ccd9cba98d528842a232a3fd4a9aa2adb44ccd11488a92e3548a444ba0674451e0ec1ac975a8c9f18fe807810a388ead36e28bb3ccc75be80bc0e26280dc998e3dbf736021fb26f6b09d8eacb2a636ae739026706cd31eeb5936ead69ac2de017888198f91b50a3c59903f40c3bcde9fda4e8685ad2e681d6c89da4e135f4e14627542052f9b7e6836e7227d82cbe9a044ab35a25cfc342431a85a14b3b9d4b0e251b528dac168ac06758b56462cd16d824c692c86b55aa2f16729e8cbbd9fe10c75b76984742229522c22522715380c8684c813d34befe8fb458f0019b090e45348471d42a2587db9af38908a2a01e604e190fbf04c142059985d84703b54c2aba1d3b397c381b69328895a2264d7d9a4d3e2c78ac3bc389731b802653d22ae99488ddc122248e1daf91d52b2702458432325e27debd179ca996832245c0b9dc6750f4254a20bd6b3f95283291ed30322bd61ec9286dec1a922df01400de93feef90614344d937a2205c9f7b9ccd30ee409d0c48706003a04822e6893abd2b7bc5646c64278687233b6982684b8019a7ff1b3b98bddc7c47cf2bb33471db432fad551a5af2dc269b642737b7ce653b34a686261ebb568ec23b41d8c37d64dede46ec3981f591c43220283aa8d0a9b33b596ef8045ad69179905185ae719a54e38e35a3ce2045abc4c730745b2c5a4836e5454d6ea299dd8467450ae5da2206cba5335d4abc5e32d3c1034517dbe296cf94221a418cc6f3c6e09a94625a86023f95385209adc4d996c80f10355e93a943c8d53bc065c385b8e3895cf956b1601b12dde82190c0b5e800b863fc84b5a8b5c75acf18fbd1a5407fd07ff085bce98cc4ba0cd19195e1b72f28f054fc146898bcb91acc232dba83bf779ab738636b834e99442533fbceb90f6e35985a6e248a3d0808a8c15615c7492213441fcf3bb99a658530ad809595934f1ab77be71eb8babb2e2953334486d6715b89ec2e95ce51a8058b8f8e84f004d1f77fd6a791084a096f12e02e2841fac3b0c8b91321b6a0a616430637a43d79b14e21e4f053986b6685c99374a66fd947ea9111b3894202e51a5b6980d338708d4065f7e9a99c96b6016acfb282d83ca06bfd8fc85869d5e0d230dc151f553f2d2f97d75c08c2aa6de2c59a6c1e8824c53d50bdb423c8bc208c6a8a736451d0dcf31ae20366115cc8c8d67ecf06eff156856f645d7a89fac7da43b24a1116a88f73e2880986634b22f0d0f77682ea224b581549ea6014e41f8c4344455d41c5404f1ce8249b941b9a41ec1307237113f12425148de9cb28c7a3c2f9e476e0a9771da0e061dd776dea1db8f71c4c96602a0c759c5941e404d9f32a740bdafd34873d60cf851c0c6f867add2e02107b6397a341d8d2e09b65a61ae30a4ff097d16341157ac9ca36cbd87cf05d9547928ed34083544897237b135bbba93f3f359690f214daf24ee6106324744f9b321e6a98299ac963ddc5e3658178c4e83484071e1750124d038d580702da6335f2177a73ecfc66505f1b04a03fa54b1b0d43aa4038e040b994cbabfd34b550a9b8d5e71ce6034e8dc633c21d5d534759701676331c73b190836ea60121a62713757b673ee03caaff338046895e46cad486a09e87547df4bb5b59bce673cce16f44b404bdf8c92b9a3fa2e21939511a7812d3a8ea9a04586c3ae689218efdf204c1c642c45f377882cec64e3eb8e9ae634d66de1b07cb1f89cf2d04d35e156ce904f816a245a050edf44380f56209c15a9034e99a423ae308c9357546b8991f849c3d417d98cdbe71f49db9947b2c7bb3b09bb6b452094b6a5805041d11c9928542410071a0d239fec0050c2cc5eb5f67211f58930e01fc88490bde5de7b6f29654a32f90e9d0fef0e50e0789857a96ebcaaf4355e65e3553bbcf83e8412d58315c3afc62afbefc0cafea59cec6fa395fd6fe8647f18d70b2694a81ba144d90825aa144ad40ea144d508254a0c250a87fd69ae65af4a83f5ad2f67fc089375f8513cc950f7ed16759b749f7477ddb6bbdbebfeba41dddd60cbcc6f19ee5b36103ae01978bcb9d6e72e8a94521b92fdbbbbbbbbbbbbbbbbbb1b66832ce4befd20e8f3ba937e937e51ffed0f71e10cbded6c9eb4215ef2d78a647fcd48f66f832cf97f52d81f6d450377afadbac74bfdedd315f1ce48776434fa586aacc65c60c050f9e6ec5616cbc202ee3879dbf2f5fdbe05dc61bf856bcd93fd69b5ae70472fe58de007f909a9c35d8d43e5a6eb01f1d30e5266d380b8c96a5a6b9e70bcbffdf9724623ae75753e170c2e8f5c2b068db7ffe08e935b7b401e8daaf1124cc044d1f819e7e12948449b3c05133051a5b7ff712d29037a1bf4299800e73151365ec2c4f7526e221580d297e1cf80e2fe7cc2bd595e11e42777595ee1d3c271d2f1603f93f0d3b1d1813c1cd55dd50ed57e46e16ad85b79292bdc515b79294d4773cd93ed5e2bee7561a36667241a1bf46d84f6a70a77d4561a6b56ab0279b22f9694d1a4ad81ecb495d6b2f1128237c2d73c692b396aab953cdad7cabea88c838d4ab7a0332a4b793df3d475b0ecdfd3793d9d2cfbcfec8cda999d69abaeeea2322abbe317cbfe226e87f07b7d463ed7a7b37d3b12c7d703f7525eca4b792b8fd53e2fa0c2797c3613bf127dc917308ff4c6d7776adab42f9f56e333093bcf9ac7fa5f0d3bf7b5ffe08eefdfb3114e540d3b6fb3ec8ff1576d848eda42fb339b27ebc5a7cafee3c6733d1a3a803c1a45e36d8d6fceee491e3bf19b54b8a3fda1f1335efa19b73f750a575e51022ef2687fdc24af280190ec6fbdf8529fcaad4f771091977fc1362140955e825e11eecb56f3f4f2fe1a6b09d9fe68ab2ff5e2a95c94c2f534eca55c9c5bdcb1638d5e2a576d6e35a6c566acc7a4e7a4c74bad2c6bc363ccc4238c8647f1474a6532aed6953c5616e86a9035b5d53c7da04e2bfb9f78293027fb9b78a96f96fd4578e43e9ef1f68c7cbe1f310503ae626e841f28fcc0f083b9e86f23fc5e9f11175d5f11f9e2df859f8e8bfea5f06b855f8a354fdf139f47fbb3a2827ca5c8dedd8e9579386a076c7f66290af74b39f3b4838d1b376c48990b82ec506a5511d7086966c99f060fcc272dab71f87cfb45971ccb93fd99257f56ebb0b3c6e14f65b364bfe8139d022bfbac75783d8dc34bcd921785d733cb5a8e26857cd160207194600aaacd21409962afc78bc24b69341043f6efb68ed5b128d65650b8a39df6c7feccd7e5be52ca6d38be1ebe4aebd3fa16c7d7a106443b8190eccfb55a93c114b42099cae64943c1c8b5b23f0cb8438b3bda1f96fd992789ea642075d4f78e06d9bf13226534211d6b9e68bc7fd7d256f9d53a2ad664e089a04f34b0c69ab56379c7ca1a1e351ae4d1be4c1597405bc9ee687fb2fffc515b656f6c7f5ef6c7fe685af7b8d84ab2951ac893650e2148c199e1ad83979533c6e940e07979b058075efbdff77fdf5f6c73137aefbfb7b9d9b9b938a215c56c72001248b829097780344d60022e2074214bd1897cdf2111fb3424324322ab8bea25adc44b180c59fb7df8c6fbd07f6f637373bf0bbdfdc2181b43ef775f137aefe7fdee8f08bdf72f2f06ab426769cb8a0ac9eb462c2d9eca465f2f4a5fb373e8cb92c2fb2d61e8bbd0e4bd2dec2c5bc661205f44d0278f41e3184d4c3cf5a233996c0bd98bced78b147edf125a26fa394cd266ec7e9e92324f484fc53cb5618fbd7efbdf706767053be9c50f8f4d8f753d7c74336ca2007387055ac42113e9fe880ea776e88760a7bf97f8502f659ad6971f00af8b4226f23d900fbbca4bbed3af8ae2a2ec47c1a146d07140ed50d50a06653f8a8bea54bc09de04696a20b40b08d2d45d70b9a9796452ec822c5731b7805373df7ebfc5363b8d6fbeef3ef436373b378fc37157e529fae3fbd47dfb4784fec337df87dee29b9d9a0fdf74ff7de86d6c6eec7bdfdf7fc205b3bce205b1cc6579850f2c8f1e1bcd2cee38caa4fe1afbded7901af3b0ef5571a58c96fd5d0b79ea9e5992323277a62de42a64779f969ff1ae7b2f24b5108addf5f21cfeaa9d597f3ae136ea7ece8fc9729ed17d54ee0f7fefd48f8abd9593e4aa7626f698cb3c476cd629a48a48f3eb7b2cccc9fe5bd8a10d85f66ff8d1d0dd7ec661a01303cf810d62574b72250c0a417267989b46f9e32697302d8eb82987c9b303f19a73ce1ff3e42eeec75d5a0e16dedfb07b1a3651bf31697addc71c8bd0672e32a14bb27f18419d637428e4dcd8634bb863f7344dc2952069becc35335e430d740efd28bcbf85d28e589470bbf7deb64812ca379370c77ebd606cdbc6124ad4460a535e25041f2534f99350f45c4bd8286af2a15789fe5afb7d5621a9a0c0014d5e14fafbb5d078ffd91b12998029212b51293d3d3d3d3d16349a759320d1d79d7c95d27a02d29f61973b2aadc9e70385349140aa8f936b0f1f27df0ce5122efa0ff9e2ff43f6e4588f9eae9456fa75233cdec8f265fff843c6ad83be7c1829a3f5207568dd1d125989a88e035c9e4f430e804380b02799dfbdd7edd90b49b30bbfeffe08fb1ebef1de7ee761124dd779decf25280f93e6876e3a4c9a98c4c3fbfb47741fc237a19b9d9ad0777f73bf97283762bf30743b2f94282b51217fb9cb738a9813c99559e658ca73e6c9b1702daae0b1d89c41a44ccafff055a756381fcdb02d2d2d2e9f27e13cd6bdf7e32765ced930b3645d5cb45a3517b0be745395f179ca4d1f09b2bf95f179e08e26fa491aa6f95ee69ab904659fb27cf7aa910a8aee490f85f72d3fe3249650a24632af841265f22da1e85942941f8527af12827e254cf9192640a2542a943779d5c98bbe4312cdfd23661a50211a950a0a9c14e8535ea5427995c9df579dbc4af421951027e5a1cb622627610a0827e5b14ee11f2e8efd6a9948b863bffad5af70be2ead7767f498c766388324773ad02e77b7296d8fe9f0d590887d2f5c3dca7b1a7280e3c0cd8d6d54513ccabbab4759fcf3e38a2b3357ca7157bb3c204bfe4fe4b414343e2f94a80e3d773fe4cb913b7aecfefc98d3bb70d3e8a9eca979eafcbb30d6339ee9b2ec23fae1ba7ed7e60ab881fb74390797f6ecee4b7f567163a44ccdfe4200409e5c96843cca24f22594257f182de452f66f394b8e9a43ae6c3c725336b2c18de54b7f8c9956dc9898f0bacf1758392c56f69f7103153a8a5ed5d5bc6e34126130f759afb3eeb5fa152990b95f918258766f80cd5c82ea5efb3b4b9c8b9fffb3302ed0c1577088cef6aa68ea45188ac798cf36eb0522f03a0eab9ac5931d9c56dcf9f437bc33fe77bbb838c3a96b61f0156d23aedcce7296a3c081f8ca51e02c67b9c0ca192375657fcbe12c3fcc2397f16617acfd4823cbc7d2742245ffd1c534fbc513691a8014675c7453d571a371f86b5894271ebae42f1db56d5523bde48bab354bfe5bd519e7e7763515f2d45ac8927f15ac689ed8244212e7a9c72cf98f62eed400a4a94720c58e5131826e1f48b1abe85ec9d6f008ea2bb2ffc423b772ecd2a88b6ddc32297170fb717067bedd4f7087e827b8a37b6e07e87bc7845d7945197e7c7a49ffb8c90b37a5dcb499bef7f7959bc0f777206e02bdbfb3dc147a7f0fe2a6ee4da2f777216e3a797f6fb9c9e4fd7d8894b9efef38903ada0b1287bf838148762224d1d3cee0ad446008e1442111186f6f5b51f4dd23127d16613bda4f00ce14ae27d2e00225ec48410b28e92591281ced77286f12769e9928a18f2f9fc0c0548895e0c5234ebebe65ab654ba5ccca5bce4d266fedb7946179fb2e65466f45dfbd1585b415d29c235c91e867dcc4e4e58b7d967014ba7cb1bf1252f9625f25c53e8afd130787e0321336d9e41d3482cb26b895ecb8396eeade645b229108fbf80a20a5b00329ec20dbce629211f7bbbfb8c319f8722b71d18d70c7ee09859c14ede844eede452b5adc3d2efa7f216db9686dd7e156b2855408cda142684e11eed8348754735a426638ea9794c96940fdaeb33da1148907b8e8549b539b4f67e7b8e8b4722dc8de38c88ebdab42c27324e139dc3b5116e551f6487101591adba7877cf19f476eb71137f9c8db3f396b21d9bfa5a973eccb31cc72e6b17d72cf37b58f14fd9b65f6562bae3f6bb7cf24c29533ec5a47299476f753d97e4b80533a846bb7d0b74bf314f56f6127ddd4dab556253d87f41c2397dbc728d3df7e6ab36e2b9f44855246524da3b75b5c8420fd38ca2c32002b0e4502c008438851864b48573dabf891324eaf6aa75552b6f2224b70beaed653a3a42edbbedddd9614aa481fc5a34878a70babf763f7f3ed7720071ad17db5a1f783ebbdccfd623892b7efde7a1bd1fd26e37adfb9c1c6f27aef19e1bd129ea6652f7429ceff4023e8072280e6e680e77e103c401338e63b31cab3d60c8246cc3c86206f0ff27eceec81c021dc5bce7e9daec1213a6f5f43093aa8d3e9489c3f1de226128799e83cbf89ce131321bd9bb6ff3e2e1ce990ec4f73dcf45408d5a91b0973d705ab76b48fe2bbaeb52929949e83e50b3dcf21dceddafe5ad3baecf24d2a2ecd7e559deab7c2044ab29427d2f77779beee7cfaa4909b25f9625bbef01da5715fe4ae95de4a0a1d358770b55bafca5d302c72fbb869ec32e98bdc780ae1d21107a22e16ffa18895339c004e30c997598233774421801364edd453a954ca09cf12930a20bbb9b07d67f74b39e2f8f7db0e65e3d1c79769bfb5128856659640f2e884f787f2ad0411d025681cf2e98fb7717897a071f4d31f610309471c26b61c3afd1af6d3704a599fb0b6afcfb8d822d649b2fcf1a2c745e9fd9efb0676eadcb15336641b1422e606cc8e396f8c5cf49e93c895ef9ea57cd9c01db3960e1a6f32a520115b96f2e572e08e6fa3a3ecf3f390769efdc01d606fa0118786faca9f39b8128fa4e73d41238ee4bacb2d7f5b42ee12f46409eb822a37214b18175e7945cad0f7579132f5fd53a4cc0845ca6c4f6379be2b4fec84e70d8cf2f823954a652746b9c7509627598274801287fcb2049b68c2092e3741bd8e0b89a099c31c1eeb733f1f6b60e6ce32d31eb99f5872214703c74a74a65989ce590bab265ffc69b8c917cf9d679c16993dbb8b510ae6ec9eb3fb8a999057122a906469c5ebc8284b2b8690824cc516f6ded1e85f14616062627218b97734fa174518989818206060707c8cd81308b707205c981b37a866c35f2f677777fb0f5e7e7043146b4c1f947c20ce989183cfcb73bce53a98ba7470cdf897c19ac5c862b00e4ab2298fe0922682e6a627b863c743aa4979d1a7e0564af42898d4d8eab868836366e9fb72a48c904f06f2745df38381d4f1f5348e29a48c18b2ff10e49079fa62dfe7fa3e57f6ada7757c398de3cbf97ab8cf7b723f0572b9cfe7ebb95c18b92ef97279ee911b84eb830b046a82fbf9f4e4118c7d3d6e52e2269addb63218932f49e40bb804dc0274822c79eb00b168827cf11fbf1864cf378796a0512398a23ad705a64015b872534b192fc8135df9409ea64f12e4096cc90b87ab864b062b32159c13ae14b2832d2c647f2ac51d3fd71d823c812400535bb62c29e3657fab6373b265c9179d0f24c12ba7e6e9fa4096fc6f9ef8ba56704730b64a924ae57e127c0d0779a22bba02b580ae4027004191fd412cc8133752c325439e7921fb8358c8d304b5a842f6ff5c6eaa46dcb4bddc4447514ef61f3d589682d4e1c141e250e227495132cbecc5c152c1aeac8eabf36a8b2416492bfb7b3cf3c4fdcc924f8675b2469d8024ef7150264ff2308d0a25c5a6ae0477d0a09ca460b087068c457153de7a530577b2597aad8412d5f1cc530ab6298e3bc13c3c50dcf1ba409f27e79c933444abeee8b546704730d68130fef068d43239f172e629e5dd6b4d3c521fafd5b93a97cacf788a48d4e5eae3a2ed3b5f5463b9e841445f5fed45e00eae8231d967572c9b933d05e5c4440bdc8b8371b15992d11eb009fb34cfd066db9734bf331344c8dc3d11324f09eeb02a17af91fbba2e115cbbb2d8d227ee3c713f600cc44206ca50d775f30e30265f5277e47e3a2d4899eedcbde6c9a666e976b1dc9980602c05c65226a14d8131933f9da4a4a0ccf92693eacc92733a3adccf3c4dee2773b3f952fa55ed683dcb0ecee44b1c2aabc795fd453f521d9b9a3e1ecc4312739346bbdfc82b732eee354f347639574c567b66891524571f10d480b8699c3e42562d378d5467889b7c7c8cf8698697fa6f1cc92c162b77ce2cf5b7389deb1af5e41f311a63c59698a5d6d1d1c9fe74151b49d8a8f94c9fe9b3429bd27a5fd9ff4637c8bd833bb677ee27b863d3fa5f3331e385658f895e65f2278f834279eb2cd5a77e5197d43598dc24d9ff42e162715f97a77e71ad507d2eeccaae16f77561d785c4a62c121bb330dbb243da8379314fd6cf85a0202016080848e5620af46216823cb304823fd7a73168f585c98f2e836d3a9b6b9e9cbb366561f33463b445dc34baccbaac1137bddc344e56368df36585b869741ddb9aa7d1b4299e799ae1ddba317974e6cb355faff982cd17cd2cf50ff799272472582c1f9f1ef7f18119b56cd9773a229dee5c9dc79774ec5c998a4478734d3ce170479bca8d3a42f4266f826f402c5202240a6696fc45896abce96c3a60ac91a0839228128dcae6cc92bfcada95a59dabeb42c7d3b472ae59921eccc5ae0bd2e48d408a3c6ef2522ebae6096c7959b438970e0f4967c4534297dc4bb9c93379379062cbbbc186c483cdd3c684cd0acd679e4cf0e632015bdb2c8b0d0a30ecb3c5b0706daf793a79ffe9c50567f265d3014d4230364ba22ef7a474527a5d2e5ef0277b16851245e9f4228777898bbe858b3ecbda37abb8604ccad8ec0f2691324e90a724648f14b2f4c142f6afa07dc9177f30463328f586dbb9f3e83992679e1a85aa3ff3d43e3a3ed50d77895f2fb2ffe5e9c24de317ebd15112f349220bef167ebae1a5d83c89fec7cb45f7cc52bf4fee1be3a5ee1c1817bbb2518f59ea66b5ce3c2d314bfdaed769754e6ca593d2f959f50d2f754a03f1a3c385c1138b699d1d7d532402631ce03870337d138ac124e00e303682b1ec4faf2b45a312bdc9db944da5b2ff754d3c3619725f97d3392908d2b07b46a14852512be41a68839533460bcbfe766ad569105097dcd625b6a7562fdc24ade0f1c9fe5aca4d3e508d55af5035d91acb4d9c5f419a7290e2cc4defa2cf9338bfc6a105e1e6a9eacc923f477f045598e7204d1509b2fafc348e8a04a9334fd50d5d82b9a99e418a1eae156b55471341d5b1820b5d64cd25ade00217d95f2ba219c9d2ebf22472695db9e861f5a93fb50d200f4779b8ceda70474d875567d64873ed3e476ec7367feea8e9e4216cb815db9775696bb8a375657f6d0553501648d3f6feda0ba449d36e90254ec7711db78535483d81fb10313390ba7251d3d174e61c63623c678c1963b22bf71863619c83342b0a1dd537e8165502854914d7ada904d86cb58e07348e2494d0270bf873dd9a616f2113f2c5df020f681dfd84c4d1449746908525e44b95325d4ee2a6396afd48146130a9b96a182414a672d137ec295f89286cfed0941aeee8b159b9ad59f3f459ef43781c851e84c7077d87479105fec5ac2cfa101e7d08088f5ec48d8078f4232affe1f133798b53a3f73cb5e1c61d1ee72a8b501e8f239594878db29f50304db9df099eb2154cdf9378c9b9f02d92f869ce1f8f8df367fe50584bf42af364329aa789f2a74d79dce4bd3feda2e599e8386cdbdc7e6e15dc41ed124b6ed73a6777cb4dd0fc791229d3efef4ec8a275cc935fd938c035a648fc57e87d94972bcff247a43c0abe41f99467c137372c1cc7b2f2292b5f43fa15184ffac6352e9f826d62bccbd3fb8fc2f238df323ee56d587ee571525664842ca19ca599869bf22c3fce9fc721de19279eb29fadbc8c3f02e51fdffca3bc0c7cb353f38ff237327e0565e565a43c0b89c7caa77ccdcaa7d8a0fcca37ae494941c38511ca5972096bca4ae5d180f49c33998b73fecc93e85d05dfecf4ab98e09b9ded4dde47372b3f7a076b56f00ef7a39798091a93df3013342adf98070e4af4a29e5e88421a1b8514364bfe2aab4be78f8bf30c77fe387f320c098d790effe973c76efdd84ab27f2371534ccab4a44c0d64df2eb8c88dc76ffbb19b907d6b2cb227f15e4a137742b29ff212e5248b493c541ee58f58f9147c93f22b8f826f766a527ee56f505ee525ca296c9e462c2dff61528b95c558424e966cc9e2b9a212c6648cc650280ce6a2196e67d19b7c0d64eb20fb771c1edb07d9298c221122b79bb61fe91699c24ef0ce486114c671780ae1c6d4907226a1a88970420ee30656ce18413bf3cae0f5d859eba83d5e19fa646ded691d5c8bcaac0bfa44a7507bdc5ec1cebc32783d3aeed2691d8e24e642e89367a15379a0e3427097b31ad6393446a9f02c1c09c582c268158e84368152214fd5072efa72bd5cf2c57e1e1344c80c7a93b721f8126c9794a13e70b9aa0fe4896351c1bd60c7f794823bbaa73c26aaf4d5d5b1bce4bf8d8adc21ce7542369fcd2726ab3d3f2e6e1fbaa29f654871dc9c5cb8357e8747193d4ab8f2ad02b2bc045368d878f1bd9e933f39b9282c28a31595141aade4e46714ee49adb57ef79232b473b9a99fa31ffa7145638d5c131d8e1d15626823544958cfe6cadb6b87ca62dd156d354f5ecfc6ad386ed5a9bc9e79b276f37a268be378aa60b7607b68905d4060b9beec6cc6653b6b1dbeca0eca1eccc68f9e2c67966bfce8c56cb0dc80862adc19cf3cc957cfa867b43f1d87bb5597e25aa9d836c970597edb58fec74df5b5fba10f081776ad2ea70bd2b15cf49627ede0c6ceda8f31b98a7594eb4c11f374e3ebd3cc538daf2f7d84702744eb8664ffa9e4d61f3b21d9b5d1088f3177058f302a78144729781cddcb897045c963c7f25663c76ad63c7128ff2e077b29943cda1faf7fc770bf54f801b15eb484df4a0c97057b3e5e4f186e0f0d1bd8b64162292e0dec637f7aeee7fa8cb8f815912f1f2c83e17e8145d23ad6c86594e5152ec042e32c8dabb176c6fadcfd917bcbb239f5b95782cb711387c7cfa1778ee338962c859ecbb12c1bc4b22a373596cd79afc70b3780e2e7035da011985cc441d6e703ea80adef074c657095fdbd96a733825defe5a5463750a421501365fbbb1146e1a81deb4468fc8cdf0829ca9a84ddb1ba209d102854f02ff8d355b7b0736fb3dbc5ed82b8e96b75433a9d79ba5147aeabd353c3c69b84279ac7ea7bac7574a9eaa246e8531582a37813da085da2adec3a2e7aadb56ab7867556b11042cf54ebe8f7c6b50a124795e5ca842ef977a9ecf80ad91f0b79aa6188c57ae8b6f19c213b189c1b52e48f704146332e564d2b290312e2276de5309d2323235f91ec43724cf6cd46435cbad6922fdb2cb4cd2a07a46e3e9b4f17aad7787f6d35cac19506f607946b848d9a1c8d47e9e4f16bd1f8521cc652b81ae658dc8aca466e9539eede1e29130679b26da83da05cb1fd912f5cb837fee5bbc11da2cb859e0befcf0645efa46db6ad61f3d966dbacbabac66a1636464516b0ea6a1d168bd83cd92a9af0032aa40e0e7099081513a181c44fde123fe227551430a81abfba281aefeff9d0f8282eaac6fb7b3f6ea26fa990a3b522fb4b39dad876856db6ad61f3e164d0cd85462a9b917b8756ab65fda4be550ab2288ff6270465e903c5eb71d127f4946ce1d6f794b8e8157b3e4aaa65d99c1a5fe96cf25c94cc7253103fcd40f9cb19d9ab117a3e9ec3b170bfd53c71ad9f8af2f163d9d96c46bf16bd2af75236bc5503c4aff147947e873fa2c6dbc037e2d7f81df0cd4e8dfda951123189fb990614a9260da897ef1cf333ae712d995f9e73e9d820f54bcd53105f2c05cbf1e3e7eae1c7ef25f3e3b732fdf8b14e3f7e393efcf8b580f8f1cb114a944c2851418412e5a560f98badb2a7bc95fdb13996e562b55e546c7fbed44fad9124fbd35a83e687af11da9f98b7f25232618d0f22143f26dce1e15f4e6f7a15d8d60a6ad819d81870adeae3a6d14b55256ecae1b5a7d65abdd43c5159caa3322ab32c9990870f227c8961a23189c375da36c8979575430dfbf389c0feec6042fb26b46fbc833e89868797d780f8d3ab7c78d35bfc494b237494949a09b45598ed1726f2647f64c97f5671bf16c893d7334b52a6cbfedf13f26465905d0a29c37d38f854901d05fc7a4cc06382d90e353eaed53aecab7178f7d108254ad356b4b555ebe0569bcfb6064d5b71abd6415f9bcf3c55d6b6863e5517b8edb1557081e5a1afd661c3207158a14b760c5564ff6fd63fda59285bf0a3b24c65fd208880ae1c28cb2b5cb0640b0d53199d790e1a3fb570b92caf7801111bc4451f7d6425fa7da064edb52ba4c8c93c6479c5aa27a368d4078a65b9e836270b772ae18a5fe347fbb22f9b93d3ba79e382354ff6c7b2baabdae91a218a2cd11743294b3f93d69ea73fd62549ae44029221b9f3687fdc3456978e9b467096fd47ae9587b8c987596bad60014279f491b5d730911a5f95b8586372966a6c4ae132e2a68ab7709b61e152d98f5c91d713f645a3dbe4ab5d6baddaca4510388405e5d1be68e8b168849e086a7828f04ae03d215ffc43e0105e8a8b6b2f48e2c1c3c73c122f1f84e8a3f1e1679c87d0e603281e7c088388a1332ae321b4d9a911ff05dbe00411a253850ec0004ba5ac7f95cba53f7d4de94fd8a6a26c76fa4bdfb8668737619b1d7ec64b6f0a77f81e421c9f23847920c21bef4368834745d5f81a39862e50210953c881a5522831dff8d2ab6cfc0e5f43124d8d4f8044d5f823661a50e2dbfe4ea144994289e221acf12fa19823942820e60f58a50ab4672ab9dd13d1612238dee2130e3c637396e97732739476e17449a6b1f9da5b3c522599fe1cc3f596b848b1165225d4470c97ce642ece30dc91eae4789a03d32d4829c5919ee18621d367511ef9421f070d8eefe1733cfd6ec17cebf8f0276cb363df071f5e8216335103f326989f98469503db34aa87c7816d1af5836dda8e635217a63c31bb4375dc449a8f93e7f7326f9fc374fa98b731a737e5f82fe438d32988a716cb0411834fa61c58baa8813be606ee98328f344b6dd3402240d96e9f57c1044c148e9fb139bbf69ba09bb557b593e3691117691739c29dd1feb40ffe389ff2b8487b280f02ec2b31bf879ee48032234507151a2b3546224b0914a36507920d971b2119305e6ef82622fc13db2fa43d21e50969172e52fb948776e1a6edbf5066ca437b3e5b4c5d3a2ed29f5eb8e38ce964fa2f376cec50126bd0d061460e387c1931785800c385d4c2325a5149413911853714d239633dd3679e46172666c62cb5d4524bed8fd267d2f71df0e9bb8f1147e2459cfe34e2a67e0afee83dc894fb3146c21ce6fd08237fc0ffa3d1bdb85330b85bad4cb198297d0b048eb7fd011192bc7714455997ee2022303fe340841425c1231a05836d4280c2f1fd2882a10d47314f1f17e993640ebb4c79328579dac3531f7ef891fe64fa3ff8e0a9203fb90718cb6ad19aa714eebb487fe422fdb9c5f5a79c8bdfe5211cfd0c176795ede031e2f09ea2adc357ff5286cb32df7053cc4c11f3a47d9d71fd412fe5499e4834de73579e48f4b797a71a8242d173cc3fc3ed2edcfec1edb3c59daf33f345b4921ef32451313c303377989839e79c7382e0f6dff614d3a8387196e673e1166a73ce33dcfed474cd65a53c556d7bf95a0d016d08c8d28c8b4dd292e8e1440a889405913cf247b562d1b869149170538d94514ae9c444b69f710f09304f303b605ceceffe1bdd2397335a739a0519ca5f8a31522c62469e6060e4e95f9eee2cb52cb7bc5296a5e02407c2bf733f27c49548b81f51f2fb78e33ae725ff4dabb4a5607b07b79f8aac7c24ad2fba9506f7b244d20a438ba72503b344d2825521296f099229904ca1859b2592299ec02199024987640a202069b9904cb1d36589648a2148a600913cb185044df175ac617dea57531a8232ed97948149199aa716796261fddbeab6394bd6b355501f7171f60bd63ea2400f37855bd8d9c1fa53fbd7095cb024b32e48a0936723c9b36579361779ced94af2ecb6ed2592cce1f129d0c3878b73344fb2f138dab0b072c637c4c5968e1741c3dd3b1afda7baadfe0c7c681ed0c38959ee866181863cca2d2ccfcc0c79943c51f0e4512a0965e9c5a6d590004ee0e95a6b1d83e47eae595d77777777cbdc757777b744b9b49e294d52ba7442f61db2e4a09e2171efecceeeecce7a4811ae5b2c04dcace150cb49ccee6c24deec353b17ac9c61ab0b0c24e68944e727314f248a490de8f73f42f4e01fe10fc237f866a7a61f7cd0cfd0df1b02d107e9cce27a389ab3d38002bf73eb8034de52ccef9494d1f2fc5ea9be57691fc545dd9f30c8b35590e7cbfb515c548c1b2ece27808b73a608cf317ffbe9843b4f3d4f21246669ce9f76058989c43c49d4dc308ca872717eb7f21c9ddae86fa9701385323e04fa93b05f25247d4ad8f226e1e8574296cf2ee3c197a067638412752dfd66eccaa7f5c7124e744ae526cf53fa68524a89c43ccdcc8600e5990a6ee2c46214f3b4ef44c0d7422231c2d545c9f81baaa28041c9f8d565c2621277b353e3f2a0bf8171e3f2a0947c993f97702513db77db777887d60489c33432c05791bee508fffb47f483de822169fb7f1c948c50f4e06f0f629b9d0dd784feb18dcb873ec6e3a0bc8de4e1cea757415a5d44ce8ce4d940f2ec21797add86c4fc07b829c7b66152013a6f4f44e78dc443f432be46f43262601b1898b4bd7f875d3089c33cfcef93365ce37f4935fda0ef077d08e541e1c99342956f09537e149a3c4bb8f22a8ff2aa943f799a0089128158565ea5527915ca8b5e95f2aa930f8d44272829f35556e69b4c8932e99454811f7a15e8efecd40d7b351f3451709370713ec548b838e774141ccf515a60e50c23edead72c826672f78e46ffcdfab185e4b153b38a5b048ddc427659852cb568a2c32b47a3d82894b98ee649a2debd08d48551af5648cdfef64768bf53a3bdf737249a6dd3b426be1d7b3b8dcafee46689368d6abaec097a6e3ea9765d5729a594524a7be0245ca43cd29db2c02e0007b5c253c52d75ee17a50c28f78f3de4c6412471b165ee22473993f13fc6905eca7272fa67a9f1e56484aa950677cc70b1e52f0165fc8c4f193e2d4b285112b73a365dacf7d1820748f0c2089bcb62fd9dc44d3972c79e88ceb261204fdc5ca9419640b879ea5873199427e6ee8e9cff3924fa38f9e44d3c8efe055fba29e551422a3825942ea2e0512ec9fd27a174d1048fd2c58b437882b07411c4e2bd1b1e472215f34fdcac5e511743120d0c18a42396a05c7e26e1ca9758728127954a3d01c48c018cc82d72bb0f4c0d3d79bc91fb4b5101481e63725b51042479944844b965e7b8290052ca27c2b3942fc151f8613fcb8f48dfa200895a6921d605464b08630963842b618c50a2608412e5b2f2b3d48e3bc7c579822bfb69f3a8b84847ab52a6be0eff5165fea8d53c71e7602c1bc778f3963bf43c69d842425b3f6e9e26ed9c93945d831c29a365cdb3f62d9ba7f9492842d6da0759d341d67eecd9bd97eadcefedfb8f9d0385f7df43117afb61d286bfaff1b62d14926a456939a44ddb308987e77de86facd6390f03933598acb2f8c312a4d1e91c1775eecdcef637e0dbef2df4ded78430a97abfe11a1093787c4f9f5471cd87433f9f5413faf9213c334bf5b5ce4d1b4782cce5067784708df736db832f511424d184bab7a1ef7dd7405cd434d286f242d28669246aa2e036ab57be8597046ef24890e55beea36ef2d547ddc465f956d336d0163a09b2edc2ed6d83241edf7bdf80ef3d4ce21a609fc461120fef435fe3bd0d28f460e871505b58992840676e0b3b4b90e67e176add0d39ed3b1aef6f76b8bfa1ef85f0cdfcd096ef9dd1e4d65e7b0ed7cc0ffd166e5aa83d08d2fed33a6796b41f78091735ede709ae46dffb1afa9ef635f39398a52cb454a888eff08a70e793e453c9e178174167bb158ca029dc529421073cf403ccacbda5b67ed3e9a493e2d4f61f50ea27d5f6513c6a7bb943fb5b34ecfde052ba35c51fc8b9e86f84dbdf4db0b6af94528a4e63cd8ea97ca1ed37e032edfc5d14fb8521b8f65b9aba5fedb7af3f9ffb919b6a96e20168aedf55d088dad24123fa1ec92379f473d3c444bea74fe96fa144c21b78f2373f9c0282a19469dfd28493b52b65e4dc69bce31593e6d316d87651ba7f5352f9225bf703d9f168932d6d96ecef3d742334b8a3bbdce5461a938c70a2e615c908f9fe3819275b0f7f406570ebdb6e19a46450aeb8e52da71052013ad76c6713343b5127483f3cd239bf9d563c2e91a74e6e22b85cdfe11087ec44676f974e41f3eb0f9464273c57edf3b094edc68d35d3195c1dfb79c892edf77958b30535ad4ae981a47cf190276f422cf78528996484bf90eb98cae00eb1fe794885dcb175dc7db6d4401dd7d2d372c5a34d9eb873e44b7f8e2c4352b3726787cdd3e632580b6ac06da9fce19dd161d9616e929f67b729ee78a5cc5c87c751fe3c8b55ddea41eeb80d77eaa254cfeea27e84c5ca19e23ae230242c1d232f58cc1de6a6d1733cd6e348dadd7d7eb5a53827951354b1942fd3888bddf2567fde449e17c0a0392858cd9aa76eb50eec0c58f031694929a594524a29677c57b5e3f85d143d47bf8aa6ea09ee0803e32620dc44bf98762046212ac8b19cdff47ba455c9832406303add67156c7bb7774b39e51656ceb09c9b469ceefa9753d70588579632942c412c2bbc80042b6079bca1431e61b21c85703bdd41d2b160fbffbd926aa5524a29a594524a59694b006409d3dd2d2726a2c97ff9921b397992c77b92e5cb19122bd12c2870d4534e841977512782bf3c35e32f27828479ca5bd64d6370474f3d21854cb59151d3beae438a3ec3c39dd1389c46cfe89026296dd02587c13c69d89d07df81b352d272dbbf943a62a4e87846bb331aeef6e91fcfb184a74f2828ef27dc99a515ad56a6595e61069edc34e73651f3e8af16e225ff21455a35902fad9ec166b39e391556c01c8b86f9cb5fafeed43cd1d09efdefa58ec98d451f7289f482dbe6d73ef4fa4cf459cf660eeefc5a5f4e857c71afa245ff981ba171f85318dcd15f3a9afe887303a17ddc44f195308984ecdff8def9923260f6f7235246c2a48c15f2d429c722fba7e0d5922f3570a520ebc053b31482f21ce2afd43c79ca4daaeb54bc5e2ff992e34fc894cc5ffef2233372ff0d244024c9fefef2d75319757189a37c08915d08776fad244aca49e936a5ace28e92e7cbfe3d7cf849082ff973289247081e21809cbe51883c85a0743472f7a4d7715b6b7867943c49b48f645d8f95334691886a759a3cbd611bc9de54e422c2dacf2c4d4c5b7bc11db71f4efa683edb4bf4fed6e9b523b029da60ecbeec08a4a946a1caea4c09b323d708af79d2603f827295b9499b45419ab42b685700a2ad409bb969938247fba9b356f65183c5404b657f67c91715c817ed679e44a97932993f6e2c27a4e4118c79dfe1b8f54899ee45aed7460679e252b3e44aa44c8741eae082340e2e361e3775b1c5e689cb9925d846850c8044f96f63c8e336db649923812cf98fdb120048d49892c74d4708891ab72364f73a2e353912c813484496b820ad034c358e9c79baae192473392e2e8766ea65cacd9e21299475ea823b8290d016dcf9a0978b41ee08c63e2139a02144be21f75d9f0ca4eb8260086a5d81249659b2bc6208b0ccbd9532aed5be193a65c1ed49737acece01467d7ad2ce11e2a620c0d43c9de4af679e4e70c6527e3df7e562070e311ff4b30a2b6564dede44dd443fe6a6ee07bf4e0b3d2ab4b71cb843a35c18fa2df47ef338ea51cad1106ccd4fcc2da24fdade45d28687f0bcd119b2fb3ae227d564c1cad084ec7f91dcd83c99d42d66970b374998198a68d9fff66c1aa8e326da41e4ce42647ff0080843e2261d793ef83373b6541f1766906be8e386f7559d0c6a49f00c77045b33136cb9690ed171531137514c84cc46c017780484b989d41854241b1941aeec2ab823d63d79935ff9118cd113dcef8bdd881ee56fd844e7f1cb8195a18b4cf3785d6e1abf1c999b46ee67c6e271d3d8813da08f9bc64e0bd94d23184be22619374958198cb869d3ae2b0830c6454c1ec12e4e790403f3246789b4492b5c748218f570e52994a518a10eaf12cef80f3db7844404f02e6113e13bc165fc0308571c4a003f0a99e838e41c7ef4334f2d5dc8d26ce9e2a78b9fdc3016569e3ab3349fbbe28fa31ce3c7d194317ff55ecae5c711699bd74bb9a46689eb38aefb112673dd8f3199b3ded777f41eb8630506292505464a0164e411025945e5555abc4809492918b8e5a7c50b192129e5813b46b8e5a7e50746cc8994334f2d3fb3344d392c176690edb7fcd8afa58358704b1182357409b27d0fdca1720159b22d45b62160434ef9691f083c8eda90edff70866cdf07ecbd20d6031eb97b3d1830746ad008bd961d4a28cff3c01ddef68da182479cacf2361c3f5b6b6de8f212dca10222405a5180ce3d60295f62a860528e1248425c6cd91cd2abf430a4576771844c48d13e0fe106a468ff25f48014eddf086fe48b7d117c91ede750a58ae25152fe30ca3264fb51c0a0a4ec61943e39ec7fa5b7600bbe40291c715c20866cdf8243c830e414159510974a78c419424ef91216f9f1388a5906e49477d199a74e96ac285b966c7f1466fb2b33a1ed80115d4e796bbf0fdcb1c3db09eea021b516777489956c6c9e38979e7912ed2ba7fc8c8d623696e7c8fe78617af27c1b2109e6e21c7fe49414bc43483ae23b4a98f49a4570d109b15492c8305ec4e3a8061e2f0d1dab43580129da9f115e408af60510624096ece7106e40bed8c761134edcdc45b62f0189c37e09d690ed83a0112819c65b504b0785380230525ec5fe97f22eab7759c97059c570597d8601038f3847c8293f9f94637fbe7dfb2e781cf590ed93f078edb7e09c3cff4bf9961f959f2a2d3f2a3f6af951f915fc93e77fa011614e790b7a4bcb7293c521968b33e553f04409651ef5b8e9e4e78f94b8c9fefc910f0a0af6d16001e616289065cb99bc7d13fce10c784e0e0571717e88250a413d2148898b937691470f2595270675c1853b8658797e8805faf9a1206e9aaea5a1085d7c214b297e33fe81c2762e6c8be5685b797e477a8d3695278c27cfa7e1e803a50271930c7d84f01b41ac847169b62159f568a571b11f0917fb6b5cec5eb184e818f939d2ab5611d70b467fb8c9c7e6c7dddd4b5d53260d48b17fa4a6255cec979dfa91e47af7126eeae11a902625a46a044ba4ec2b21bbb08184cdf21c7d6d5c6c144a6ba5b5d25aa90f94acfdb6bde63f5cec2d94dddf16ba1b5137205eea5742ca5ca08794a13b3adcab225cf9f25ba69f849bfa29a0195135ea2d29a5b30349f942694ec24d49b84801177fd874c51b58801f6090e40b9956ea8f33809229c053e3a5fe99991821462f829ff5649d7f5db07d6b3c6da9f123a5fed45f094ae3e7cb91c64b17391a5c9a3f8f49e4feff4c9f060d2caf3b8d7667a1c0c55ac315394982802408457e0080b335a039dfb14dcbcfb7213de8711c7409855cb80e451ae3f2f3417f8483de05dfcc07f94b14d8f7865c404adf2926756940b9749e6fa50b0cfab4878b4b780efaaa9dcaa2fe7496e8b3bc0c4a575824ca63e8c75024686a90abdaa934c773d09f27a85d54ceca0841ef21c83261bc8b4ae5537e861265fd9bb13b57d44d63a7523407fd0e422d8d99a71e940e01ca3d26c86d34f285ca0861bc872eb36b967ca1dc7bdc7bd8694ca64d903a4c03e365aea9cf8d5ee5552b9ff2164628e35dc2184f0ae7b7840d039694d132ddfca90e32ad41a6af4c412fe36b402f83c335e0c7c0363042d0bb846025d14cff9e253cf95168f22ba1e855c2fb2961e8b7aa55215ca439b3441f443f44452fd8475933312e52141cce455fd896dcec3af2934435c77541055920c349a2010857484285299cc00432a0fcef97bb893083e6f09fc3fb53582a951a827219d93d46768791dd6d7652762f7b4bf62e3b4bf6e7b6ec2bd9b5ec2ad96bf694ec4f51b2cfec27d9df4db27f8bb2cbacccc821071cbe8c18305c482d2ca315951494139ddcd7dfc45fe47ffd43fe207fd0fff3b79d3fe7f2c57170d72b54fac5f56f3a2b1eb9493262e2643a819822adf4716aee942ce54b7f9867187a0c5cb9be0cc07c090a85f052fd98799a9866cecc53116eea90c8ea51f36b7c622e724dc2c5face03f4f38f00dff1c4373b35fe60e88a4c4c44370486e22cd507d969e53ccd1ef344eafa4b800ffa23427fff08d08bf00df8a0bf18745ff426ff7d0daa1faa2026695fe3f2336e25e9390e774ecb73540e55633cabc72cd5afcda3d229314289eac1ea51398c04e6628d798e20a0e71a569fc33d6084a08f1182ef859d5da0980f7a289c93e9273e017d6a1174a74c3ae575bf62f5db889b723492fa7977778f79ea9c9ad3d339f439dc292c6ebf7f30c2968f1192be41fb2ea144691e8d94f1be3e0f796a2bbacec30d5bc26d8fbe8777745de767e7e7e08e26481aa669213df7b38a4b579ee5552a3ffac642cbfeb572b95621572eeecc4dd06cb9cf8794a15f1f03f2d43090a5fab56ba0865c6bad3fb9b85ebf41128f96777924480fe31ba489a18a1136cc65a2e0f60a778ab6b49040334e0a6ffcc16f096f76b4bf990f9a0ffa9af9a0d7708dcb2c512a398525bc3f0a43bf129abc4a287a94f0fb94f0e4bbcb85241ad01f31d3b09dbc4a65f2aafba057895e157a1045ab1d9ba51a0aeb8b4e42394b1f6c96ea123d5cac5535dfbf62255c6507b651dc3cdd685f5fded0e7dee973f6bdef68e88dc5de0d67337fa7a67b7ad361bacda73ce653ba53336fe66b584e394b5c08ba7614689aa6859f8bf275c63a82ab3dbdc19dafd14cb91f29a598db41394de37ec34dd05cb10f39c3c95a4f31c819e743ceae50a7c4c972c6d18f5e2c0a6f0804863062e7ef43d20f8db05a549163009c5901ac1655bc60fa4f297a643f3f711a876766693e0c9dda9c73ce39e79c734e8d4e1817e7cf1917a708ee2862971b130b3e48f84291d52cbf6479c54a27dbd0ffcf391d2fe14fe2be97220cb65ef3b86049e6360ddfeb228a8b2679a4ded56711c9798e19d227ee7cd912d7d495df286828dae9d7d9de340ed7bf514eb3f7112b67dcb9e4ba37ea9b91325da65f44a7c498871989dfb52b5312f8a2c741511288493c427fbf26f4f7c1bfd86607c435f745d8c6e4efdb88e81741334f294f3bac92d2758fd2fd497743e1cce2d2371185330d37f4f7c7b74f3f0769fa9e7e0d69029fbe0d194a1d0100fdf883fb0776f374f2141480d6e13d7df00b0990e5cb0936800bd13a3c8c6a1cf44db8f0d228b7a859ce25d78d008998b9e34202543c235f68bb42dab7ab8dd4a795eb8759dfb6f85742d5343c4a29a59452c70bad37b7e7a4f6f42aa17d614bc3e3a8693fa98bb363aa3b5f7edfb9fd783bacc4fd2cadc893c323277bc892fc1a440fa54c3f046572c65384879d44bec8a7dc472908c37d5862294b589425f9b59ea41250532a21732cb072068a3bb8a37be927fff1e30097e98fb28756c3339386e3f60d24571f234ad668e80385892d8f9d3380922b1e7d6821f7234ad640227cb8d8c3c5093ee8a58c669efaf1c49744e32ff311fddea3b8a89178f87f5fe3ff611b1c94cd4ecd57d31fc2363640509f9df11a10186abf04caf6982524308d8bf37fa2e18eefe11dfafe3dba19b679bd810f141f283fc0200918944051e983bbfe3efda7fff4907bc1ad23cd3e50b2ff147ddab8225cecdf62891f2a9610ad7a126e1a617ab8a99f02edeeee84971a2f11c5ed223ba6d8000f70d32c629e62fa6180b8a3175344582d58158272fba99b80e0b29c40cc9e73466f2a2218311204085e2c813263a4a97ca57ca19652adbeac34f2a5ce2577ce259766778fc961d596c964b20a9249992ed76f69d9cc8f70f45fa32dde5f6217304a728d5992eb93ba97f138a8da61120f18317ea7c335315e06b6f98ff136321ec6e3a06af8157fcd61c6733372e0b8c7dc875c8c908331b3b81f8e66a9be8c70a6e1c67818dfab3681ec14c866813c01e12d85d4b1034a1ec55c7fec29725d72b52c9fa33b34efbbbf4478b8652ed6e97347519432dcd72f4919d0d7ff314f303e465dcd52fd76edd03a3a8bc6513ff4f561dc74bfeaf88c7a2ecf6a566b1d85f8a972b17ecb5c9d45ebf86fd94a56473b5afd910a8ac97c55fb1fe94197af3f5f730aadc305cf2f1ac7ab7e25e171d4825f5c0a7ee1133c8e3e8bf0d471b1fe3492ebe548170fe1f97ecb6a175e547fa972add553b9d6bf1be72f37d571f2f8915a398ee36ee82568841331f30d7be662fd507d50d85ac897da5c78e98bd6d150681cd55495e4fa5f17b93e875b265fead7d51de72c4b59f23e46e8fd9c79e312b9fbdacddce4e1596472e1a60e1381f175e64c9d5c7f6609ce1c17ebf6da4fd60ce2a60dcf9516ce948bf5a71aee4cd1d4c851dea0c3df3bbaa3d145b9176534fd8e7858305760a59c273afb256ac75f0bb7efed9b710f6bb8d7b0cde8b79ab9d3fdf613db6cf8ce92cd4ef73b3414db348aee742fc11a59339f621b0ea743a0b98ba04748a59b363925597bf9d24891ac6126362fb2139e49465c9b298446b9fa9ba6693f359a27e6365a271ee9cfd7689daf4d4d9bdc46ab36c3500665307fa1cd5e97ad9c3cb7b9ee9ba196adf7cd19d26c3f1014028d20c8f42fca105fae67f0ce42b8020b99a9d6aac9aa266bd716b28eb929c90a645fa75f63c352a3918ccb6969789456e4be2110b2543f14ce4091a5faa010b9fe77c325d75f425bc930f7cf1995a5fa5df8809b479bac69960b3b045fb40832c75dd9aecf9a8322205ffa479c19482ee42de01c618440768a5fbef4733ed53b2720f9dcb9af0edfd785a03f4322c9afc3538fb6504b49f4a32e14a4302888c6a0212a835efab43e4da1221a52138ae909cd8152158a4267d0ede90aa5a24c5f5e29c3f2f4a7449269fc786bd0c0e3cd7434ca94bea95f8797e00e1db0bc34cfc801872f23060c17520bcb68452525e4e44b4a073440a17f42df84be88fea51fa20fa20f7e5e47e96fa1cb17f942bf869c7ca1785e1d7a03835b981802d03c60c2c4b6986995fe78ca8b4929a5f3b4bdf286612a09ee12373926b23d6bc593a7e4aab8ad1c17c2923fdb204bf3e71379fecc7676e1d6a7b4721a0f5ad870ffcceef663ffe48905a9e346e360ddc8f3271752c6b750cb12e4e1284e0b2717f265fe8dd631b12071cc9f5ac8f3471ef24492472e74d62ccd9f52b8158bf3889533c62acbd4c545ca713336bf5b87af3a89a3a0c41c4c80a3fa271cbd8b54964731c77ef8a73c5286cb526666959fa88e97e873406e902c24d3b10ec9f46911cafae1e957577d55d83cf9f02324d4083d92e938cab4f3a6e55e7b8e0bed734adcd4b9c97bfa74899be8122fa45d4895d02e3c6ece1f7ebe384f3dc0f8f013889f4f334f3cfcb401adcfa824cc33a7c1a2754ccd08000000001314003030100c08c5a2118954acabc20f14800d91ba5266601a87499242c820630c1119000000000000000201c10c22d3b48a4eb653d28a7bffc224b7b5c7066c3ccd51acc4f673ced4683edce5d2be70146b11cfd86ac38cec12791addb1d54b8fb2aa26038d1c70c04361dc3814c24589de85877210e131bf6a9285d8b7c04ac440565b84002c4a14a9df29980548e6e8f8297df7f3714c351c8a4b60fb0ed340b58f487a642f588b8f2f6f85f5b0eb8a7ebacb8350d16511c0eab87978006e93dfc8ecfa08d11779a068aa098af4174066815d2299f0be0006370c6c49062708330a834caaa9523ede09903f7bf7826e5b3043b803c2969cebd1e51a10b3b762cdaf7c491b3da6b4edb9590d0d24ef0d97b82f7ec77cd6f2e51dd64930b670ca1cc65f73075533f90bd9aca3ff2319b9132566f14076c1b64f1895722562ff560a39c0c85c4eaad22a4b6a90ecfb3cda4c3b0785108291626210258d1bbde1d5e55ada0385e161372f6d7e1aa555c42ead826172859090b4cad56621b307edcf534538886f718ff765a28e0b3a74d06bdac2aad6f76a84ac37f85cb4b59ef8ffd242f9f1a43daf104b6ae9cf5f786e60ced2024a03d8e00f6aa55215fede9931ff7a0414ad9c9d9912dc1570106ddd825d96e7e35298818e3b37993f1c898fdaa309fc15d73d9f9d1280b7706e34396d44c3552b24622c0138690d89320138e64cf90fc1ddda41535619e911dbd7fc4b74c27f76389cf466cbc39800fb659432f53a23de5b846101555c850b83e0eec2f39dda0198cdc8db8b38f2aeaaaf6376d105c60831959662e6f33707407cf9f8d44bf5c48216850016b84b92903c6a4b355b7232703ee4b1ebba9efc98a555a9115f2124646811872d0a7654aabf72e6d7be6a09d9d5652f8519d2c00ec690edd34c094d8f1d9825e92f7bae81c2342be16c35b0e4f501d32f22de957e25451db39202b6d83b596f69c0d20e046cea0802275af772a0265222feb6e062b8ba66f61335a1a354f065acbd0f1589b3079820b60443f67d1f91dbe851ce716c0e60684fbd82ca0450cd4039bbff4907a17cb1e9cb39ee25aaa6a4ffb6dd11eb6fab91f2ac037484e67554614c5851d362bd91586e709303cf5e5075c7c2e4a9ed8ba3b54118642a8900fa1ba202b9585b54e8d02a8d75fbd3b4a7939e538a4188ea4044414a1b650793c2995cf9d9a611d827e983ec22200a0b15d3b22cbb5e9ed02e54f17ec91f2830b8adb2e0c26dca6140a110b377f20f381c81ee1102073ea7e82a12eb1df09e64d831c2de133b30ce491f95429125bd1062b5b911ff4a52c37cf939d32a8d920f770c7f736d84b7e85f4d398c3ba5b8128ad97fc7b0d56aab4cf630274f185fb342a08ecc77c321b2075d666297c1b4c33e2c311466f5243b3be64546f4556af5e49557eb8dd9e3e13e73a011cf98973ac9fa5468d651443a968a2ad03d39ecf74abb4117e2f631026c8816161b69d6b5e0c95db9aede96b2ce2aca1c824585fdab24de81545b814d77d1cb869f11a37d9f2997dbc84433c601dc8925a10e35b616f64494dda056a2bc8057f033dd2a9312426184fc7b5be44de9a517fded4eeee0b92563b5a7eec3942717d00a03a6990f426428a2280404cf1de7cb3910829c4236039095d3ae03fbe8b08a09ae911da745c0019faa04ecfdb2e1ca7110abe88ecb874cb476d6b8c19e7ea62d5b6dbd43d8cfd8460dbe783358c82ae9d3ffd0d9fe7899e9866e5460d9cde868fc324b985cc90343c42af286beec4c5fc8eb8f7e888a8a55c0b21c74b587ca2da01c395a4c227e81f8503a07dfd93b84ca74f4aed5f620b08740459a92b59c24c426922c914f391b11324d4c9bfba4be67837d05efd0359e6cb8da85d52e345ea9f90015c4e07412874302bdd2b07f766394e117b688e07a442bd781badde4de7b794f1d0f27a6cb39389ed775a4c9b195fc9359b9a4bfae9a01de36daaf3f90a0daa32a3200c57305544eca2b89a239b7589a9f3242e4ef399e72e80d880c84e06044bf22fdab73a7ec933fd7ea077097480cc6cd8361b6d9c594191ac6f0fbe1f29f4a8e8ab8b04760a829f2544fdacaeec5738fd507c18864391ccf1c50b71c72d95406ad4c1fb3c451d8feb247a1a6143349010cf63cc065a043e90ca060ad819e193bc88e25e24453e02ff46a019bd4b70771194d93b884591248f2a61496e76d54ac64925986d14ccc654b0767622996e0567bf99c0be83770b32c07aa7b88e9b2973ba8d22f45f699b58233bf3cc9a1fba314e8b69f9c4152c2ff87424b03ab71721ccc0fd9d2143e106732eca199d6c98cf5e4ceb1e94fa8ac74aedcd63a1036508542c814156ae953b31ae20e1eb1d677689ddb2fb784c77dae6f19c07d7f9c79e17b67721d97df8a20a8814f19596954aa005faf99d605535d51a16156fdc0c154e0cc53cabb091c24c04954005756aff45c968e027cec907453f038c0549fa8e1b7ed0a3677b6788f960427541cde84adbb0fe909ae8f06c0f4cd54fb5f8c7f6fefed94a0fe10a51fb615c6b8eb632177b03c4f810072a59d4ae57e3f2a4b44993d06ebfb26073d71a2f5cd4e1cfa01ecfade364f796e75eb2fa7373761f7fa7198c62736cac8eb43aac6181b09ac6f842feaf884f3e63355c38341b7990ce30e02f989a4f009d289b36d355593d17425603d15c2793811887503dcc6ca059d784782cc35e8e47e21fa1f1040fe4290ed62845aa160abe098f7d926514f381c51439741e162a5ee02a5a670aeaabb88c827ac69d1f85034a52af858020a7517f6a63d45fd476909ed4f2bd92e0e75cf2752a1eea244054e95f4e3b0d92e66f36f1417b99aa6ebd210960aae5d975a14282781666c86134a040669bac61e1c4e6733ac4f4f32b6568a4229319ac1b050668d157cb348f275ca887c9d322293825983300df00e843b700e651b7711f0a6938a8781efd5c0d85f7407718f42a926fa1e309fe19ccebe1b14cab495a624b9e38d50f62dfbfb758145671c8026295fff0002c361700258f81b7870e448761b887640edb2f7ed655ede949a9a3a3fc8326810e07280f01ba1058c7a80711c9dfb60f46d1765d18717546073fb4f7680f3ad01442866a8011b4ce404beece3bd880da3554d248223ac3659241a74e9a4ceed83cd3e1902002d8aea1375c54d12d29eee0863b8ceb37b36b3a15c62d292caa96a92afe0e2a97d9db98737d492a88c7554869f8e994d94e3ca711e3ebf90ac9f5bef2ed39accbbec6e257b32002f6f9d73353d80b72e4d3f29eaa8390160cfcd6d9a451930d640c1dc639e573a8098b293bb5e6a12b2801f6a43ce551e94a9eb54802cc466db907feb8dddd949484be4e1b4778d17b2b24e17db0a31a8a8b6e59e37efd0f59e8d95effc5cf0a9ad2f52ef5f861a3a6b81e6649feda5cb5470f80782320e900e89071aab5f694898d2615a09d4cd88ce2ff1759625a289ff0f30bd507894de683c3052cd3705d5f32c184a86c0a4183f3aed39542452aed4eaa53cbce758516411b2fe956268d287102a90f9801f0d0ff19cac50ad34d876c122eac9b83bb583e54176ebf4ceed7973dd300e9e10be47049ea4cc5da97348ba1aa46c5267a4abc16bb7e78074e7f441c34f5aac3e147d7ee3ea03ab0a5ca3624d27abab71fea789fe6b568838e93f10784746e6392e78f36fb0af4dc5ff1030edd384e42734e061a644c7dfe08ef1b8286e04a090fb6fffea2f539b88807fa5437d794a65c8f988608e17aee681733f17df6dbe49c4f4d310977278529c7fb56b800569a75786196a892a70fce40d1dd520f65c0e8725546b15898e906092d895332820913124090741c13c0033bcb40ce4d3ecce8da13ca00b444d7523f53a2b63f9959c59cb38c84d307c5f96ede5399800386262a3306ab51e9badfd5fadd2b04a242bdd2b6bf5b9fab92063508b39ad495e3acaf1feaec573c4f40be75a9183be91b85b15a59ebcd571b759e157b21024f2e337453adc2b92c9f3aa3f77166212a1e607e3082a5d0dfb8fd0fc72113bf0e964eeb8c4fe39bf1d948b557ecef90fc39c0b70d128603885e2cf4fccde14690ff1d520628a6ac73a247de297c11a8a346d8ce02b74a158222eaa607e4d96161667bffd146fc1f557d24b0941ad28c1fa30afa7e51e4fbd99845df1a707d6825a3c088fce64c9ec80c58a266b83944263d9b84d04f5848a27f705c9f0f8528d0637da6e6443a67b7ac51f14884bea8652d519d7813e4e4fe646b0fa565e2bc93484a9bc9ef39b1c8253a81874a92cee80f7e018d0157e79deed1b105abb3f64d222d8a55a1f2fa386a18c4ea88a73add4fa48b043644198da8ec42bde85e9e58d0b23df2f2f683cdaad0ab69904f17f7fe62971fe1cfdf24ab121e459ef1df5bb5c3974edfbc025cef740c88716a5525aa6265ccb04ae99c11a20ed9a79c29f83e3712c3efd97dc3be14ee592131ccd7d2dab81b5c06173e91e4569444717a39858857e5b8d9b1963776404b481daf2a62dd0d0657066b222c45b75455bcc14782c16acc863764fdf33893e4b8a9c25c71cd06fdcfa9e78745506a854045e55f09e89213e4634997cd1958293fb4d8e739996c8a19af00096a81f756ede035b272782a4bce6fe2c2e3938a92745b0a5b617315204fbaa48055342328b84d1786cdc08bb3c57238919d355a546001ca5a667235cf912b331e24b9a41e034955840f36100516530418dc9c75061e069a5a3334b9ed7aaf62717ac559976e4a14bbdcb76848f04d73ce917052609d362bf175a336feb42431a2583ab3cece0da22b61f24f98c2842a0836588d896aca9fd1d1a772406a5596601aee6e649129b3b4414fbcb764ceae5ea1c09aba88d1c154c680041ff81ba30d0dccab93d468c871fba3f4d59ffd5473fa70cf46b9b0243d1740b772a0614a862aa34708538e713b85f218fe294284b9e120eaa7a5d3364c39d9453e413c3530dff9e2828ad900e05122ac9ac9156ba31dd6a839ff0cabac7f06a20017fb0e82a80b5808613ffea8037b1e61b1c1d33908a25f458212c01963b3423a48ec847d1609b2231f661bf890512c0583c2901531f973097afad6bd146e31c80299b3729c7d7e6e0e24fee15849472ddc4ac9a98a5fe718710725b1a5384fd45d82dee30ca5ec410f7ca5b8be5f8f0a982d6ba1d9e521243b4c30f764b0d8b694d07de4b57a890437f52c1a016659025402068991e732764e7d1daf08d736c24aa47bf260f7840fcd63c82ed5806abc4cae041438d7979a8a09673e7e16967ce5542d15fee4df60cab6a2e5d8b53be2fb1fe1eed0c57423a04f96bea666017131d2cada012adf395fc33939c42e67976b21f6be9b5587ec6dd4e59083b4fbc339983d1d32fe28fec54b7c7cff8e7996cabf174b25e5a7af0ac4e4bf1957643b39887bd54d0b6cde8ef933b0dc2ba987e138c54d7cd5558b6affa05305d6e912548e2a0fff014650b9d294723b4d16f2d91aa6bf8ebb7b6803c7f4d8bbd2b274cbcb1034151e64cf83f32b151010b8803231441ebd29f4a27fc0a16430248c4d340c2b816418356ee1d2bf434c909d0aabaab9963b88ad55446c6bb74e87c4d134faf18d5aa1e66dac5ccc8672beb5098107d2ab1074d0f2d84038f5bbf8c9026ed215ba5416f006f2a9bed007c0e44bb572499d299cfb0168e4154df372ebbd9b476249864c70b1dae81c47d4c9aa8b7873ad6a71250e8e485cd1f740ec9da33f1be427c5eda7c3179edf7bb889395c3d36418a1c4c514a0b75796d6a67730334068249686d9af8c9d3963ca17d2b70da75c3554168d21b942d90dbc39c4f1259842fc84144ea45d52168842136f169f7cbc4b18acf8ff0acdef9a44521258979f9c0bfa13e35e2bb6ef42571c7823cb05297bba854dab8cc3a600e9ec63cf7b803a9707f40061c10f77813b4807b29d028499701c77e34d9b13ba2fe5e3893f7f6374b9366acf0c66e8da09519b89ca6e041ac49af4457fdd1781253468c932c1ded332adef5d77e3630288998c79f0531007c47c395e0376795e30ef094ca10c9c25568708562b885635608b9ce52252727995d639ee7e8ce575346739be6501523cb37aeb81f39d311cd2c3fb2b61ad52fb8b46ae82f406782b9232a92f43e2e32d5a1775c7c3e526bc03e4a26b581a255805b7003b2be8000160388bb45083973b458377ac04b867e4cc7b68ca0e6434e2a3e9413eae8e8f85b8570390a169950b7fc16fb03127fb291458d59fd8d0ec4a9f19f1fb7f21c4883f52054b76a1dfd2e2cc728f2386bf282deb91202267a0d98ecf7b401cd081f9c9c9c2965928e7e7b06f39ffc4d53b3cfcef841cd799f83021d0b5208709b55eeb7ecf282f006032cd0253b47e7ecf426ef18e559168226043e9b376ecdf00e02b74a0f27c866910568522e4da063267616d7c5e4d37d76fde3d77b9bc11db20eab69d96c8fc586cda8c5dd8d027976cb3a394f46486699acf783c19ac3a4f0779c1848da3cc8645c265c3affe718c71ac99868af59216a32f060492b9ef649e496dd920e46920e3600659bec7867bb238dc66484d5f62fd8deca08c14ef9f1d11fec7ef1486179b220250561470a13cfcb2225a06bfe32b0bafa511a018de2ed069fcbd2ce7b417c01c2d6e0833fe59204f08680097bfb499f973e4f12e58f297c485e484424c847faa939f3c13fda334acf0edfc31844fc17c019fcb64213d5211c637840468eafd59fc7008a2087a91421e770d21b8f7d0600f07160112032566f41cc74169bd602dc75152497c0e786aea953c7e1ffdd750b647f4bd156f8b4e18a3f501cdf3c41802f1a612b3e1856f2722b3a1d8dfa1c4a2c25704514272609e2530034c9764b02bcdc24c04a4c345b862788a7ad8404e14098e6c647086a0f578c979af684ed51c7cb4cbfe589af7a646d5c35355135d30857a5535623361a3bbe615f5b0c0ae4729ed0af22ef921a6ecc5367b5f580775daebdb88a3854f1e0daf2ce000ad0c8e0767cc2e3b6a8c1985e92be917979bd38a6e847d128f1cc57a7148968006729ad2d7f8472325b723be2ecc52ed7d7e66ecc1b2bbf889704997740a62c3aacc95daecf0df33c50da95c528e05b4d77b8fd6e4d9538bdacb00a20898a1f4fef42b64daff87d4dc136120ac4ba27f60d18f0f53f02c0ed3708e7b7a2b84101b7f2244366c6a548ee0c4ecc24ee78b27223e4d99bd257ea0388ea9bba934c1ee7ea152c3464e003c35be25240f32e132df682eb41dfef6bef1d79b969997ce29403677f87b00b21263c9c90fb92b913b3fee30b971ba929f69e7b55270211168c586480c015cf1e7f2498899efab9a21a490d60e6bc93392a9e2e45596a5f1841afa671700e055558883493bac9f06e442bd3d51370436f46a2a2db09d41ee0d37a81bdcf8838f31566181163497b90577180e13573495e6678e3a5f3094246aea67d05b72908edbf782ab0f657b3aa336904bb1273dce0873ba530a998722be11688837cf6810ce62da0b1b445845b46b3ad58463c57dee2f0d3fd92ac8eb36f584136c1319bfd07adcdcbfcccacea32ca2623cbab315a74a63be8d98960311758d7e74d58bca36575e6ac606ada92ccd3c6e03c9e15c8b6af67a1a6de6648eb6899c39e264a1f0e8a5121694614beb60cdb6748aa47ece9d2edd83d194300214b049bca51d24b1f98f4d1774e07cb2939efd388a52a76315fddf3ecbd64dc756a7095589943c705b31130b3ce733acbed3cb9c626da11556a9e365c8cbb56fd54a6b457eb908e0220e63ecdbbdb562797f2f3e004794d6d4e14325606127123c0940209c2c71077c1a8517e24ef74a7781b9b2b8162aadd6b075b77588391440820d394568c43220f782348cea25c45caac7abab99e26b3b1aa8db70e5cc3a05f02d43dc5bdf96268a0b692466829701f015822943a8c0f719e911cc472c8d9c50e69eae5b4dd265ac48141111fdfa2f847a655cbe55cb6c0692c5d16f13bf3ddf23ba113532e79bea2a84af6f8649383ebdf91d6c3251daf9d046e2bb818aaf1d06791e20a41ec6267ec00158805856081628085018f6b69d4fdcedf351d454af9dfdc638239ad15b9267a5cc4e97026ad8842d7000cb4aa225f33bb448a96324cebe3a771197e87efa0f51b1ee3b8568144bc02ddea9006388bf309f5cac3a746d50277fd8f8317c7263eebd0f9adad011b7e93edef456bed0291dbfaee9158e02152de962617bf7b3baafde96ab7c8bae76a4efc2fa16d250a3efcb2e4279acb7bcf76b8b253cd59b76589b4e43629080a66975f418956fb2682d13ffb46bf61755d8dc79216415e7400c920dc2128239777c32fca5b809c5b0a13ac81840efb59e1c228002e8e9067c0f66a607428f40d7b941bfb4130ca8e70c67fc77970b9bf7d030b8dac860d4e4f8fe18c586b122bcf37b0060fcf017ad2e68c13f7433f8beffb8c8a209610e0cdaa070833b6268fc2298908382010983224bec07c712d02653454ddae268ff4961acd07ab373843fd433ec293f6099c2bb97f76565a554565fd4af5c798b39767040df2c9ec7244061613ad4cab77a507db375937b39b04edb2760a4f9da7385a37298fe80bc2505884c158dfab5ac909c787e916d0f7f34e5653dff7d09f01dd9cde9536c08fe413aea63d199ed1cd69c7c98d918c04b81028ccb06c84381028ac306c84b810a82c306c843116a303c5b203e052a101e1b203e258a0f830a84c706287e6ae887c03f3f7c15159a23db7c89ce81bb7a26ef6581915475790b1fb6fec482d4b977df7f10c8b601d51c7b18aacdc260524fb8af28fa9e520e280513a7ef8d5f1c32064d844051913814a10118ca82709821a2db39d169564ce4904d1cef95320aa854a3d725168c214195580939af07b0076842c3b4a3c70901b95f98afd880f2beb8ec749b79b62b5144f3f6e53546461b79fdf4d2d02fb2c26993a55b9e43d4465ecfa70111441e234cfdc031e3190fbab3655364dcd23c998fc486e784f4b0ab1935bb6cfbb102310be3d668df54c4a7d2e92a3d73923728abe2bccf703b404d1c6795cb3ac6d2c73f3e25c740ea77e191e929386922498a316877bffb047e60ea2b232460d69d24feff49580f47501724ca7d6d66c628d3f470e373d4165f7484bdc810133134c223009319431220502ec55c63ac8e278690f6477c8bb5fd954e8e4fc4e0872d749f8728b684cc500528c0ac5f839c1e53aa873dba59634c2dda7cffc796620d99ba0b2d82a3bed286012d26e25ee5057a23807d9f553456c9b934a5f0029b09008f21a0efe5a664b3153176f3be440aab1e43e99df6b541176ecebffe3f6365ce772ba039c749b809ef9e71be15fcc3e5ed4d5a889bb78e0a4f40591491201ee59b7703300cdc3b619ad1616a6c1168ef82da900967ced510e88fc0913df120e0dc96af88dfe4f01679ea4fa81c121c6f70656ebcc88270f83249ad724d7d37a5cf9272ab48b5a0216e841a68d16aea2685bbd0a6b6d0911548bf2829d227633208f701c754325036b50bf483bc4e5a0734e59f2d99c7bc93afaae800223ba83474b35c8bf3cdd8f058f000603cdceca2a2de27b61c34a2c44bc39fe5e5236e7268f705e371a37488dc844aa56715b63ff56f213bec167319b64119b7ffb2e67caadd45126a7b5a548308757b184a0c2d1292dd238e20863d9ae5987aee989a8545dc1de5e3aa57065e7acf00962eef2561023888ed2d49a2a7feb09c4c90ab67eabb351ddda74c55722272c96406450efb442a258c256a400b101045fdc0a9235e636ea92193da426c07122ea6885d48218a8bef00d938061c788ae94cf2dcacdc5461962a16748bcf6e9b33718f4e14bb288b5904f25653ec619de21b27ceab8fbdd3ebcd34e3378f9fc3daea03d04438db50e6f8251ee98ed4e5bc0b459df2498a38f49adb4ae9db7cb851901bf69f697be5f7757d6ce219ff43c213c2744306dae07089094e6416627a62f8eabe563cc0db6b26d037c9d2ef8edb05561507e8d27734f431e44611ebead26e583ff95a00c800e387f24a1299551081cad02f4a128b3ef75cd6cfc1b3ce93f86e6284fd95119cfd62ea087ae0b8864f72b4a5a13d7321e734c3e215bf67a3fd0e1df0be76c9fd1d9324ea1f3e90cc4f393b2a57d60d67f53d8313d70766be95f577827054e315217dc931474cc5c0412737ebd479e0a2125dc98f34f43627148b5a1bb059eb65de346ee058077cedf5e2310eb754ff4e64e8b23ac12270a8440c8981e01809109893c067002812c303cf0fcd798cbb1816f8c0ac4694a4a9b728c16d47c6364894554c34b74ae514f386af8b7ff3b22d787f88a5c9b86abda69f576ee14b9fd9165bf031410632144589c4289044e1a72820230185a422f09085cf7f33710400f80ff015c31997945d9554a92e123b3e273787330904a36ae70c7bc15c49e852b8b41bc2cdc38cc948a0075b9584a7bfe8f6ec7dd8eba6f1a603c58c4ec8c24127f575ff050029a3e476e2edd26c3648199aca6c0dcf4c5db9239c85e659fb495d5bdb85d1bb94e8aae52fb20988ecea914a87913b3e409bea6452c1a068e37006828af2e2bef60d6ca17b18fe5732f0c47c0939b48672781ed2d9e32b33d57822093ad4fb4cdebb0381eb10e976731921232bd1459417f28b8ba0456062d29672ef80feda0ad8fa5d6409d18e888a18ba85a49b2e79c9b4a2248b3f34b0445d636c260cb0b4842a076d9bafa3f0188c30170fb959dc3eb5efc2a7f38975504be5a44e67ca1ed71298280fe8d86174ae6a56f5de4d0d795c1c313716f3b9898b780f299e7fa20a5bcdc65b58df95bc563555ec7accc3f2369fc5d2284b9df751719cc7d86cf15a70bef8b02d160dc7b8ebecb027d8c1a95092c1e2dc041843c34c73b828b04ce06da74339707095e80bc9a51c7cab1ebff3b38a5b5c68b2ad1fa5a75ace93258b9a9f79c67a0fff87f35567bbf752927aa76b8098f57ea13db9f80a9c2b6d28ee7ec8a05d3d5a66f549c8e88bdfcf6aa91f8c7f56a73017c0476694606a8e48838502f0a506d78e98bf9a19e71411a2b86c2d59b1e033b83d2cf10fb2038c3bdd80273e5c44cb4d7e856d4c3f368e894833090eb49e883422aab8352f2e1ae44eeebb8164540633c55830abbb6099004ebfd7305128f719ca73a7e8a8d9e83df1199fa1ec7630db1e8825751219bbf45e5492624376202aebf2ee83ecb21e563dac9e374b2c46e2e9d9c228109a56cd5572ff50d6150d65d2ac6610211e619505476bab131bfdca2ed743093814ce1baf2243cd02c5c077e3be392c727bca2f04ee58f6761756f11bbacca72eb008a7161fa8f7e5d721c59f5ccdf4f7d124d2a3bbf67962f404c0115d7df0afeb049e44edb49ce41402847301bf0b873698acf8920423a4fe8f334337a31f41f01220ba71dfd2860e511a0fa539d8773c58a89d34280208c5f97af6ca4c94acd9625b7de6ada3b3c253a37b76639812db192bc2a7f472040e3f35c70ee4698563467ca2cb86c73618d09afb71c256ec21064f75df392e0b20c5e06fff4971979d87b68746483f821262cfc7be7cf93b093ee6d6c2eec91303a35efaeef992856e83b5ee1a7c3dc3d304dbd37e12f9b6905c51cced411b9b5cfa47ed59fd72a3346de4fab591e12c3f052ba09b31484c438c8376ca20cb196b60b441d175ed48e399c30ad49cb1d79306d96e767631704ac303adcffbe89e6d5702e3d5c70430761baf8299ff623f265f6ca6f72f7d1ed1aa6270d76368045e10a4469483a3f2ebeb7c4c88ebec92e30e815c4e0c8b9ea3fdd662eef66adb43d423683500cf45bc2017489b648c5bd10cd52c2007bc5410a282633bc2d51b6df9366d56f415279a685192b088c7de1d0e570a5626060003b62d9365a1c417ba5d41abac4235ea7ee17411a0ca4b3f7f0a2ce252633ac6b76f7c372fcfece8d0a237fcf469231e163d1d7aa7a7b3ba5341f532fb15a10b031b41e6c20854c192273c3e1c4cb37dba2ad4cb3bbd8835eaa2fe74e3b9bfa0c62d98334471cde03ca1b4f3a3010dfda84f4bb93eeaf7de7de02cf180081901d064cd532c8dfd17d1eb5a8518f630c6e31f148aecbb0b3af405fdd3482edc6956b571464f3b92bd63aa17dfc025a5cad8030dfba706662cc37d65cb57d73861b6dd908c294b282ff5a80f754187ae47caf2a56e37a921a56881d3a0d94774dee080d25323172394a3094c959005adde260ca9ab29bb5fff24d4a23144b7f0826289034cc0f3e73fff6a6c4428f58f866fc70c1b9a66427124c643ffd5ff318cec32f8c29b5f9793007a4273c4e4470a0890b9ddd85ee056b7fcaf3c57cc58e9bfb823a68da6f586ed431c586b3ebc0dbc0b1a46067b488cb810bd7d7657d3030981fd1c51312c100e81a47d8f00cebf0bfa6cd2ffa995fb982b49ffa9cc94b66151ee804c8a54ab2be4069e3be21034399c734793bd6df021890f7243eb8400a937450b0c513f32c524977931b4efebc6c4199a76a4313debeaa9fba99bf0017a941af475c3a9ea6a82285266ddabc711f2ff514125ecc5ce27df600ce7d120d5569f37a0498839382583606704c3902e6917ede49accc97930955f2f493d8521bc50420c9618079f3cfa25b0bb8b47f92e333fa8a28598793a812cd4e24459bcc2369dd1a05a890f894c2303d920233a5f0edf596572ed7a6e1049bb7d6003d32130a2962dd64814203bd61e4f7083f2a1e3146990db86069b59f06c1af42444e9dbe77209f8c6811ef47f1eef7d183c24f27f08f33855c5eb245201e2f0c6e78217824edc215c599f6dd4a9307861c1b972c04a7d17fca63b5bc1e56c2bf934a76ed110fa823975466b1a0a2b14f1a6313cbf5380e31ba5dace71e4f9acd4e7c24d20c7522b53b4f4bd99a55ffa6fa2a2988a87e92e42e73e96a51bd991594cce0215133093963a136688836946eceb2a3b98136d9101eacd283af228436e8aafd25a6f559701c64ecff593c9f86409641d35001a80994184c379dc3925e613b3f143a053ffb9f361b6328aad43b9a4e47a61a2bd31c5a43843f2118128f149f497810440e6a21c38677196bb7193c4c847a8f510d735209181171ab23643cce3c5c4c69c6518e54313c19892b3bd21b868b1bd0b044f8b955c8a8d86599b33d24cba545ab66af379c1102b5fcca1877778a0c6907313b3d60da94fdef36d6b5ead1eb784c5a6c8dde157583e11b1ae2b13fa3eac8a6ebbd4accedb24058c81c332c7a055cb1a780dca68ecf2543ae83262ef08134b8606095bf277d24bb5e758feb0708eaedcda953578e3ef6ecd07f6ebacc27c017e84235308b9e59342c82a9f5fbfbc99355b086509c199529bf8b10ac6ede4d86f7305ba01b7746fce2461fa601402e8ae034c57a8bc8be5bd4e4e2fa6ed13eb7d7f790a66135318423f23325c674d6dcf91af6d48aa1475a63629f8727a6b137541b8d41c6f6a8086d3f16d845fc6eb4989339871c59088e3feef5878761edecad38f96b2862b60507a5fcf0442c40893265722889a52720c1807c0d617c3c13ea266da8a7002b220cc506a4efa152159be4c323e784a3741cfa2235bc19926c6522c55db24643a0502cd45aee08c0126d3131e4ff8dab5bd5221ec204f01667486f3193e4fe935fc4d624c258a5bd943b5bd21ec372744df908339678d854b20abb9f963501d078451a52b450425c750d0ba1e533f8b7ab44aa8d6b867d73c10d8cf8b8e48f7c9a45d171333f99a0de4dd90ad392229d5183587eef6c4344b8ba181b5f94ae05c01988255840c5839935cf2ae9f3583ff55c4f955e12de6e06f732d738a1ef5bef474418dd475259a1abdc935606511f2921b5ff3afb9d3ecf0e16b0af56a8c8801c0919ad1669f7d82ab1813c4da51490bd08910d0c3dcb332b1c621ab1fc20c3ab6c6c1c7047c38e656cdbd14b287b0dc28c4b491807d87b46aa0b5c0244ce40117caadd8808c85c9d94bba48c428722346baed5c3e5f380668e4eea92fa31e105e9ca475f6997ce975b37ef079c1a595a0e0f2876558e20d1595e6e21a6263ce3e474f9226c8f1d261455fca6d3ffcc29e5075f4014ac50f712d77698a957d52522653a1e95ac88789be84956b39025b4fb1118835d05537639b5ae54e8f1274be0a9d6f8b5aa8529a8fa09f96eafe15d805af8e5ad9de6852bcf245e903a5d4253bdbf7855e88b7abcfaecae4ed24a77157c49c4c2b27ac01209dbed86a8f7b698c36f40db7d581da3cacd99c63cdaa74d5408a93d674fa5371cd8304d002368c16bae56db9e8f72be0fe988da7a733f44f70e581ab6de1ab5839170bfcf5f8eda2181d85e5d2661f18634681ea96ceb57f649228231370098e069788c4315d0a2f00db625921d463a67397be8ab61510b073c95e415860f3a818e01322f99d8d691a836789247a3939f637eecb9509100de06c47039fa60aa9bf40cf5fd037b11ee90b039843a767f7ccd7f30580021323582801bbd8b6d9492f54b54c14bd01fa30cd38d6fc69a7efcc4c9d6b0c62fd7214038effa3f2fb636031acff0acdaa17180215ccaa25d8d592bdf9ff6a8d476c345337c875540f207ff8cab97c36eaf5479aacd2afd39d6e1c37a3fc5d7909aad3b4d674599b24c040753eba03f49d0a8ae20211cf684f3bcf4d77598753398911af77682084613f15dca6dee524ead88b18731d18df819298634388fd82c03b302f0526d50be0e65fea01b9e40ac4eb40ccb1df5f23c0a380c6382c79e7b0315509188b55804e0b4721c971a526b2c8801a976e8cb511416880c31a040742adaae04dfa5a8039b8059a71f7f922433c8978b8ed5cbde2b09ca32634763bef4a708e03b382defc4df22c71fb7d0e4ea8231f1d17125c3d832c98e9a105f4dd30f0c856c3520aa80155103df6b0350d484709ec1e0cb526c92b0d8b5ce2f7b88b222783d7f160957d08c71675dbc9c91d2f8d2bc923386d582feeb4f76e96d540dae45c7d260ef05ffcb5a7942637603603352d2b1cb71e2c512c633ed22701d41e43dac3a027ca1ea7b2f94cae8ce7413ec71d98ec762770f6ccb37a38fb76db25c39aca069e89f8deb0e90dd2bdbb5fd3b2c1cb67595627e5cd0c8672f695d826f3c4bbb449cdc3f5f34af5eaf02b134f415effc39d740251539a8f9b8bbf72af1742f8e6d972aa9277d49ed0f79d549645135601ca66695c3afdecffbaf445f2ed83cf3fbbffd5356826f2a4ffd992bd4a2c6efc86e92593ed2ce93e82d60ad57c249bdbb9ad6b2dea7d231b9063fe1e87786575e0b612a4f5eb76cc62f60053947f8cc3df50ff4eeba4b2dfd72f88e6f904a6fbe97e91ba60db072cccffb1e68cde6ba2ad64068c5652daa0a028fd506b8acbf849d603cf6874d68eafb9fb85c29b936e0967b50ec16cae8c1b93b46d54ec610be4671bfb257aae6e675cc663157bec8f574c9a77c719336aa90e80397f9d43e28d1b808ceafb3448f4ba4f087ec6c50cca5d9d590804469d85b40984e54d20c25f42517c504cff43fd1301f5f67e8fc4117263443ed4b79c525e0166182879d18738591242ed679f33cf75bc6873648548d24ba1640978c47820f03fde8719d6405fb8858eb4b7182732984a1c9056918ee7d59e05ad87daae224a51fba1d4edea0948958ee69fc13b146359c6aef6c16965d855a698d5af6d3aa0b7f80dacd77f03d0eb47e7bae28374ec225d2fd226502d2b94add4d093574fe2d2c391574c0f6ce461a097340f7780536f14148b0a7dbf450fb6a0d613519b5f729ff6bd1a48644289bb4af605fae086846500698ffd45d84bd563320f62f74001aa1e945aed133c9e1c432dccfaf19fe0fd63502a37987ee1a5ead6bd3db5d7cbeb56ba8cd4d11407400ccada3189c597a28474e7aa093f1330234fcb31f86567b52efedb42cd6dad0ab14506716c312c981e7d66f3f4f50f8423b613417cbe37fbacacafab10dc77c938d002cc0f57a200d00281c95f34022d3888b4c1520c2f3abd16a58bd215dc424c0ab1a94afb61da58db0823062004d506b98308700c7a669b828c5e9b6390155711823d5761d1653e9150e880d32e0ca8e7dd199d9f774d951b2ce1db2f9ea6bb2d59bf48a91105f9619d814c1a1de1971c34c33fcf4d16a0d04fe723168a03ab4d00550252ea4c734fdc5fad31453e19eed670f983e619bbef025c36bfdf00d20493f364c046eb7a1c6a116d4805641fb49ec0c60610acef881262b99e29c293a7166ce5546fc2bc48ccd775c6724fad6987ecbb0841406d99c832efc073778247c0c1ae68dcd02604ac91543136b61fc5dad30c5d6e6f7e1fa789ffee8fdc2da843e7b92770e8cd5403cf51b8a56c97bbdcb3b61fe80dee23aa3746f6dd24497b2857659ab3e9b252e0086a4ad3765b05faba6499846f9158ee71e408f482b38d3ff96461d2151b133008f91e61e9d8b149ee8f59de7301cec331712b2c0e25fbc6ceb24838416dee9b20452d524848edd081a2590929f6d86daa67aa767a6b702e2b56a4479b531433753878da3d58d2f57a60178ff29d61645aaa210e7b36709c177d207a92157f8db2fab020d140c11d3438e7d6349300ce8ea7ce25a407801605ddb449c7fda77e04fdbbc5c76f1a6919f0b2c14468d5eced4d1db400cd1831dbb3c3985016b2c4f12f2da145f42c56679e6967407f3fa566f02f1545204a64cad4671e3398bfc322aa55ac68d678634d16046a113b68becc206a45303c210bff3066dd679e7775309304e547d04330bb2ae7c19983e1f8c8878c90c2bd0564e364d9b13936dd1ab4f9f90f0fb4fdb3b62a1dea46e61805c9e2c3079bdf2b5c9c54f38d2e2d1ea0bac9de2f8a2b708efd41770f26d763e7e89ee62e253fa15b5658c53c6118139e2dbeee7d0c6574e2c29895965836fb8191462cd43258d234bc1c57b814d57b7a2bcac3fe727e65a08c111b00a59309f65b4f7397084b643942e5d7f7003cb32fb5cba330bafbc27a50508a24b85c5fd6e841260730c8c6d8c6ab26821047928954827114fd94daf191e9c22639c28461ccd37fc5ea1f8435d9fbfd8583d484e28ca923258ef186c317ba2ab9fc20ca8ed3bdd2e445631fb45e5561a97c85aca6ce4168b3dcf0291a2f1e2c86b74fb0dbb10fb61e9f545844a6b55b325e17f4a384065003b27d6d2d14995c472802696685732948268f94384c33924cc6c0900e0c7c59159eb5d3f816932b24bbfa67ae740422a0103e8ea4c074877d8e006a6c9ec8dd80b5261401087fe1470422b82844e0877101a5dc5b1b54bc1b98d5b46bf79c72ef61c51a6a5f5350b74f4f6f165bd511d1ea7b7c62c82885e8185c2caabd99cd1b0c98e2819d12dacfe71ecf308b0cd8299c946efeb1957d8489a176ecfff89e0cc20d6523e9685eb39a6865770ad761df7514f2a758faa2cf62493e9bc108d2880fa49ef4c11b013c8df6fd9a5d49f9462cd25ca64149b9f5fedeba01a321510e2f403cfb7472b130b21a502bf026c7fd40c3b933362821d5e2fd90f290a274772ae04a8e9a8b3350afed92e23b5424853b8bdadf275daeb44fe3ca3b06605ad94cdc0fef95da0296fe04f8c827cb3b43ffafada8cdfcd7d3c0d1a9c5b67ee5d6b5887064777ad01495d64475702249736e5c3583cd657c04207d84d2b3e291d14b151158c150a7abc6510cf9a8c3bc54e017d58c444209b45403c9327e55dba23146eab8ba938a24a61883c87cf21e6262ffbc00b4347ce97188ad6bf4fbd9af7115d31121b1cd5544e78ade5c32284f31cbf9b4a3d11d6a097d6c2a90a4ba430c36fce76a1b5d9001596186fc47658396217326fe5e40e0267f3268052915d4f04ad398ebfb0aa92e1e6e45608cc9c2c285bb0a4a975b306d6d85d74e45eaf368c60d0f827e37c5c5e39ada8101ef86c1c87e014393956972760df6a46770ca8ee1152a8f09933cd15292595448b3bfdd819c36603e0aec1ba84524215fc6baecc33256c942a5464fd8a51858a9fd60d60c29c59a3a7cb5a0034f5f3733866634c826872f30a9ca013e62e5191b2fa122706793a4214a9a42be6ca8a958ca3b3b3aa5683395e02b93b32e6607b610b8e455484fa619c63ad6c690a3140f1352f93eb0a150922b6741205e0aa22c259dfe525fa8427b6f5377d81ec57a88f5ca858a9220c084ca61c352bac4d684491fed5864851fed22c72f0bb9a1353b3d0d35c063cfce1dea157931d152ba5c9bbbce622c3cbad7ff208120aaae81b921a0c03d92a1942a69b657351694730362eb8e0bf9ea67ff3307b7f0fa511560eea80540ace6a24611a0028a3f984ec5870b051630d335162e16eff11ccd2cc18d70ee175f85e98b336c1dbb224d7ab9d69941f0caa035a5f6ebe11e3dc82efc5c5c761d67992b70de39d77fbbccadccf3918bc0abe2312b7db0f2112afdb7bbad588ae3cab3f2db9a8e10105f95ce1cc9623816116c53753568f9a97e56514e64fa4e7c97515b9f0e9b4ce21383b6228d329d48cde192b2350a0f62e173f40838543c63927b8134f985ebf8c51edde90fcc521292e8826da6553e61b213d8e306caf1d676c7ccef334f18af134e9e38419099e5e3880982524b8d4c9c583c795411985449be65f1f2349aeb581348d64b7ebd9aed7d328384fda0f249839e5e86cf3fa17178731ad18195378296d0cffb5d95e9c2808c978a29d1c8eeb04863da140b439d915153610950d3116d1737408062be7fa16708db6c27a29a41af4379c86e653bb298c0d08675842956f0d5c8cf43f6a613fbc454ea075f1efcc8e94c27a6bad644cc5044cc6bc079b773a2c1cfc7b126a5ba37ea058f3421e804988dcab3f13a557954a4db4535446f4c6d993d0542af530513b85e878f9a0970d10523c8b43b67a262fc33c8013dbc444eb1b3de40af102af81370c54c45ef3dfbc09cd5b54e634c93cba708d3c4d40809818a6f02192af6b578fbdc4cc2b95662ce09a2acab4108ccc0e1151f586e6fc86a5a200e037588b113a54ca51aec768f9b640cb202e4455fb4bb023c340ecae215c0f68693f139385f1335a9265cf07ed27922d7ef4f95b665f7161c374319dd0c8471060257261d2ada5c32c244bcb289507412070db36a5d6cc944bed8d645491521de30eab600485c664c93284fa0f73e1a94c7b1d8186f988a12f64d852c6b6f3c96916aa1fdc758ec700716d5b040211ac17aaddef052de1e495b4b24913c7b61c80f8ecf961a4a0aeb4f0776cf41c73f0c27374c200b2b0735c9e05b8ea008d900aa584dacd7d3ac6716e2689ea9eaf2a1a140a3dc27fd2adf2903e067c41831f60e63a5e25b38081524aa6546145a636e74d4a0a05922e8db1739d0bace80441f00ff782df5d1e960c876827fb6331745d8b9aebe4239db257bfe1474770ed7ab3226519fdb98c7f23e2c1e70705ddef619ddc2023f4bd46a9d209ae0b5255cb3905317eb9df318af474ead296c5d4d3c3f3da0c51d8c8b60b1b68977137a5dd79948f399fce0d237540331ae497d381b7e7810475074188d1de1531e22f1403295e1ecc72355bd7807c0488720a04b483b5fe59375ba30a809a7257bb2d6ec6cbd25cf684bc7a8ce02b806f65e005aea103ec652560c954fca0018dffd00847feb55ea810d62c23d14a076f7935f751d16c376b3a5f875bce9ed18045904212fcdce588811a2d0bbcdd5058a5e060c6a46f69ce329e918d2f1a0f75891b1d5a9fda0c171342d21d6c21dbaa23d3fef52ec662121c58bac6272730480eb38a90e93328ca10e255c73345d80d7da4f0033041317551eaa62ded2a762df3b2f40eb2f441316629c0971ee5e4077070eb5bd49a317f1f3e562e284be41098af6b6bd89683b75743cfda7f0437da85b92325dc4c367bd95f806cccb5dfb30f19a65b0d423e5f9b17fd5c57f663ba14331d17b327584191bbacf1877959c1fb321503a9f80a541fdac35a453e18a20b7e00bf2ae5fa24f9626dda328fa66c1e62581328fd06abb8c8ed9bb5e25f54f64bf973e10eb4210ba996c70daa0b0172f4d914d777ed9a8c2a6bc47e0b4363bf8c66c57c71c91922708ad558f41da1bc8932f168e6f99a742a9985cb03f4573f2870db0a09b319742329a9a572e1508d518ff4ace723b465c78522adc58a70122d43ac21b9b4053eab589dd9fe50269e5acef24c67b4d5e02ce2ac6179e04c8c61d71ac51a9e3f1344843366849262477754ab911b507ebbd04a7a9d80c8def5f46af1071f14aaf3a03ff7a8ff0f5f0f711f080b6ec37e2c62b54a48e5643cf6b027e94f2d0ac8f017b9bbca23c86381541333034d6c31a499224ad49d6aacb28c778c1ab455e128fb87a944ef5059fbf07383340c024f2ff57b9ba7f9d710cbd191474889c415c737ceed05e9f3cac88f52108cd0a19cc1a0e9d5280a44427171bb49ca88cf8708744a608367d77090754174bbfd7313c413a47588360c4a0dfde5615c620d69a355625c6d3feb5c42a89678d3cabfa3b661ea1c512bf28d96e08201b3665fd8476513453e55359a0d4e214795808748577357004153206e53b66384a5aa205282e1ee61b875f41d1f8f81818f9eef339a140d11fb693364cbd4cd61906f0a1c65fe37ffc4319b8ba8b83b26f98c9679d78fe792c6dc4e2c867a6af403886b609d9c35eb3f6ef2be318bd7418a223f3dd4c42789a70cb0d078b76269fef5eca9223660ce03e20402089a31805f0fc459667fc6037e83913b28b7b11c58047fd170520b7480bcac3898955050bd6e559060174b8c8a813884e3b81d4f78c29c2f93e82dd7613c49f19dee32976871c8cdd861f0ea96d3b28358ead3460052aee4e205eba1b8da6065da56d5e0ae5b7a65af9c793565c9a590487bc5244325684d384759716fac03349a372f144908e2045cebbae5549dac33c5b51420dac1a11b679b049e47f7123ec8c1982f21ff8caf3a0895656987da6c44745e49c592243637df6a1754234bad42df9c573232daebecff71a042aba1948e644f0bcda9882c2c3661bafe47c2a7506da2bd720e1291f821c2bed1ead3bd19062926d7a73fb4eba4c4ece2947d7d88abfcf1ddd8869c7a28a8ccfc51b0dbfe68b519fa37ca2edfbaa47e07ea824d09610008bcdf6e52899fd3664029f1abe33f9474380e5f37d43caabfd7fef086013f10969647c2bac17e006fe6b53b89c9792ca4bb4450d4be8e5c00af8cd8e1042c00ded3bf31125c4b5020c4f0f30699ff982034c9b6f55d0eddc2afaac3ddb26805194d66073418b18d57c1a45cd0afcce1c26fab7766526c62cf9a49f2efaf51973ae1a2f38e42c6fdd8a20cc70a0627636972f9cef4533a07f7998bf3a0541006e74a801d587d47f5eab12f4b28f2698a738702df495b7bc19714264c5272dbdc0048b5dc75aa123f228704467bcaec134e3b1270320637ba15fc7b22e51888d4db0b02c5815b268ee2b6d11b3dae422c417a5b742e01fcbbc6ddd2f8a47d67e92162fe7150cfc6291281090e2d6ae6b9484994d44586bf28838a5b5286e0be0e64039861856dec6283f12c7c938bf72aa77499526ed7b5a21007900fd2ea9fdcc528c7892189f2f1138e2fe6a3be644731c6ce4e20370cbd7092faa411429e59d8dd593c3487690fd5f8bf709b09cc6136a157c004bd22f7af78e67a4752521f9f36fc0fb0528572e2e972a8123314f0a3efe7d095cd99b00546fd52c419999e6cfbe8bb47c58ea43625de95c218cd2aa23826591061d48d8e94f76da0ea73226cb1b33b05118141164593796f94f8e1f52aa3a6aba4fa9fb6e2712f5935204517d455148113492d2ce9b81112b04818492f8a21f7a28e22982c111e8005e1d6d01af5a73b36d130a867a0a0063d5e79dfa1331af45b0d6d6b42aba6a445ffc21d684d600cb40a665ff45a4476d3300d12330955534a19d83cf1babcb376b6441f319cd0e7652281debe6cfafa93276deb444bace8d152dc9ec45fdc77b63447eaf4aca55d5ea54d7555de19462f60fc7311dea5f0f0ed6a6bb3f6b3939a80542e591ecd2400052edfd8811c316b341844880898a29648d100c115cce48be0893ed94f6a88ce5c99c5c47b95140e49688e4c7b3147a4e000c3bd108466026a1e404a8bd0aaa6e851dee529b74191e4cbdd9d013afc581a4be5f31069e412e6cba1f09ac65538438b06d4c6c727a35fe020468343c682c7f7cf8949a49e450493f27e16158a235ebba9fa943bf2c21d350864a6cda57e5ba3e42fe3fb94ff67c0f550e23784051d92459e5db4fe4b242e1420d261f706bd57b3e49819ee6d86006ecad96e4f08b33e4a350721548e31850d23c7d186f3415ede01e22bfb033a43d9bdd1e3f485267b48f4e027d05f399cb90e68317911404b3c78a8c29ca198c13fb3ecdfbcfcc4935113ce81a5bb341c402055fc966929f5d5966924dd85f092e673e2b844acdb5fc19ecced1442ad05f6164c9283c9053a457c0667c64100c25c41114a186b28e1b6db718703c6b3cf29551c613067514f230b85d19dc65de2631942388010632acb0555c605baf1345e61cb4946f30b71b28675269d69f9754904487f254a690f697d9bc2372cf2b46a62b53b022eb347c267efe91d2882989599b9b618802c18ba2b36c0ad300a35f0ae494bd4658f48774076a94174a2e1122821703b7c720e3ee7bf4cd644adb5c5af4887868d11b567e129c39b05e1915c3908c738a1e9a7f61784e6441771ad834c45556e91f1d7f9a5bc627ad28c4d0cfa2d2ff448ee313c86921756c15f07e801327ffc5eb2b03c36a787383a647edbb3d8eee2586230590d95872c6c9cf86c74ea47927954d03a3811c9569a8a490c3b6fdaeee893dd2cc85409966c11846e891a353b147af372addb870fcdada4727d839fcf9c6afb4b3b568f83593b90d8c596cee42d17ae03a7ee0ce02ca88097acbb39facec4b073df31db490499db411352a90bb0874a76b3187b44b7414988c11902690e818051b648b873749f0eb4c75e042022c23e23b450e6711b24e54d1cc77e3a412e7e5a3ac54871dd93ba18dfc0dd447b2951c1216e80bc65d286a2a02aa3f5a83bf14a25634978124a36d4c9c989f69387a6fc33af08a35285cb21cd69863862d08cc61dc5dfc183b202690fce4427f2ade6762a54f9958d195ce915848e5391db0c01e7ffaba43a050797a1bcab0acd11477b7edcf381ab19aa217d8c64020bd169e414c4da823ccafac0a148a8adf07848d216c18544b37106288fe7041e0f56931eadbcc834ebe5fa054225b57d469c015a4e0bb78cf7d06b93fb1d7038bcc4f6e00389f24db273d916a6d12e06c0c00dc32ece1ba97436546d9ec0db5a5f2b999ef96604be91efbc95bed227bdd4d332dcc1cbe8c275ffff7c46eed7202f4e13cfeba96a703db2bd00c524f6c232e1e241c4c695854744f2d91360447415fb475b993254cf3a73a869fb2c28f49508fc85285a3d24573567568d9c751dca3fb5262c8743c8a73c6e76de24fd3b865bbf516303b188d5f9f5e08dcbfa38b8764b669a265352ccbc04a91f7831078e7fe2dbe2717119143b1941a43b025164a6c2bd55cfabe13b93a3abc2878cb331616e582ec78536221446000579560b33538569a2a1892ed20d40d195359ca5d52c27b05d28b46af0553d2b2cd7d92a4d8601f8455a76bb5aae874948c3ed630fb428deef7a6d42053416db9f213defa8171bbd20b7ad8783320c338569e14644df03910558db8f53e3d3226f817a5a1de2ced64f8c5bfb247f51da144ec2729c5c274ef7cc4a783944cadd17b72404c7d96f50cca5dcff145950cc05e03ed7276c02ba9175d294c5c06896970d28980fce28211295e0803836a01c28c057ebc1969d9a9e99fc82bb08d7f7e723529c3d58cbcadcac05452480cd36c9147b5ecb25e4eb9fef5786996a9b887fb6a86aa95bdcc6e7cb838babde9a9b685bf62d4e9d5ad0799c287c6db7abc6d7b30fe8b68a4058a8d059a849c210fdb7249d07077cc769a468500d6164871e870f924c0e1683ea173eceae6e5b2c0bf2ebeec6950612233ad657fdbe8eca863244dd151c08f7d69ed35059c1d76a0a56a2a298133d6eaf0a33a8a69131a4a329abc9b42772e9a3d18e43992d1e11eb390210da13ea9c6ecbfc62651f14dc1882a5a5d3fe6c5f2514e3af025dd96140e7d6401929785153a4d855acf59a54819e2ab41a11aa1c0c641132d796802e4b144810be09d448b0cd73876dbe86976ad05f8742fc97bd89da47028a3ba0741576c118e764805b51e4bee529758feef54a3720c1e07cb03b298022b14758f0c54fae75bb9d6267e30c89080eb8238d9560003028ebd68761ac65edbbf3a4d2c9afa2c19c84f14873f13d8329db170a86905e01b76066d474107f3984497bce550c8520ce719c5f8c1f934f770efa181a5f1974df7ded518464b19e66c366e52265f9618503cac3b7f4ffcfef59d510a0ebe8df8ce20f4275fe273327f21a1079f3d24e8b7a9a59939a1e259f0e222cdce0bf28a329672e54a5a6ca381a114fe5f5836d38c2ebef4f415225489a6c8c50878c4b32c53cad28632d01efc755373c02c465bec62cbb09d4334e096bf809226ed7900c2232e919cdfeed930ef0ab43a1f263b7cdf740bb40398f41e558d289e1ffed6f59ebdb1c13a632578af5d82f0ccd3fd55f5fae770458b9d9fadefa9a8ca5b45bd02557436177cc5c0324fd7bc0d0e20ce2ba2edd3db480245ff672a34c87239a162614b0b9d9422351260cc8a22594dcb097fbf8550bbd155976ef330e6334708575d1a29bec65fcbff45782ee56d37f5c3f1a57432dcfd0ee6810959c7b99dcb3fca93a397f4eef3906b085d8ca8f2723bd7addb80a98ab74e0831a29271e45a160b316fe92c3b41f63d38c818d88490112a25c68888cf9971ff0bffc98bf66027c9801b6d7529284edf90e0f187b90f834df1bdf294475fec1eae944c5ba85ba8d1c117b384973ca9955c4dd69a1bed7f94c4cf0db45cf99576967152cac6341f11f4609ca5fe98936a0bb16befaa2b8dc075726ca4a4a56db2dcc1971662d2415195bc6522f2ea17fd02aefe5f3ae9ce196c792104886db2aada94bc39dcd66787d4b3078586c7f6a19127aac90207ab474048f88451c3bc04458b9b512fa70c3932e57ded4aff13f89096fca862c600e04682a1ca7d3d7608e4cc38fdaf9697abad89a58d8f819386e8d68447f787707b4a9a2cb8390c03880e58e86eb6c8cd117c0a4260db89d582f1dc5a6cf6e23d53e59fb48d1b0ac963717c09c815185117936bd2a1040f41c6efda39d0584c3d57c598a035df69bee3c98959704ec56936111689566379c4e2475d01824b2207367dbcaebf51e9abec2388fcbeeb0111bfe3b163b9e240a28c777f0f813f806ddf8ba20c847c6f0444069d41a33104d458c216b3f803a9ca5594fcf32d172c37b6ffff3f802eb6cbc7b8e241da4f87768793cd596384e6352a91dedaf7186b08d3b504e8476465f92a767a8b953214a4e92931132c9904aebf346d01727e5f4301285b083150427f0871e3a0302311ef8278f4b3aab877113a8997c191fcbe5b42d3a16f526e37543408b68b4918563259a8639dc66851c7135dc67c4f928d9c47461e56a42e95ed38a8566bab54e1dff38862f328c726e4e7ef9f0b0612f106d2f9a43cdcec1cbcb0df2fa9db312e0f0d4814dd1c5e452fb043a3b0543d671130831f4c11dc9d74f73626f348d1a2b85225e701eb7d8cab354905b276a349bc44d40020bcb322054fbaed5eaefdb3f10acce2afbf8d520efa4139510e5a3affca6c287e44d071d8cedb5f22d875df26625cdb395c565058719e31640eeaed2b926ecee940f8a7e8ed9f60909918b55affc08ea567dd61d330c4338dbb6e1de4aa0120791bbb4b24a6b128946c6afbe414c078636ebf7da447f2780939e8993537367d368519d68083a259a288d019966ab26e6cd20e4aee952521835673bd48c9ff2cb2fcba0d3e0b92aba6b8ae215b3308922dd9ee78b1e61bc6e50fb4c2b5c414d70b52c56191650f3bdc47eaa55fb07d1dcd0827755ebda34eb081cef0ea9cdeac590d5fe944fdf56180661c4a49498b7fffd611e97a2af0bd0de00c9a2fe3ab10ba0b557431790b74e1464b457741063d53298e2e4709ae09c00738638af4a8e656f15bb1de0fdf1121a3012e59f213f6d120da9734c0511b29bd878b3ab9983be81d4e83eb8eca8a958bf3cdb0ba420a4a7d8315e5629d700c73a01012108aafecbae62b52bfa991c5ce97e500c258ee3a01ebfabd77081f0baa988843754a6685f9bddc17291241d2e5dca080d780440b392b0d3a0b1a81a1f7b82522e1e87de7e4a323d881fb24b856fd27e1e052176ed28301fba5066ae834633d113d8a48dbcd918444c50c8e9d896226d7acf78c57b681f7f85eebc321d64110b074a0cd4183a9e3c1f0f32408a986df5ff84a1ec228fc732d2c0d4d221fef52f9900b63080fd5027c1904914594debaf95165e5d522f849c0912324077ee125c45c9be2456039ff193009fe723a82f3f156fca5c2f04c8fabaf9278c51d1f7a97f6e2d06ad13db91561f49c7079c8cca1f21a5ed4d7ccb2dd8e0d5a79d647f604040b2cf8b405ab1af6c423b9283b371cc5736d49dfb45b2f46f81429880a231742faec97f383c4fe4b8c053bfa982783a8ac2e20c8da347ae6b93dfe0604aaf16302658e9f441479c42a98cf5f4d0b6254fe956601aee8fb5bfce8260ca8b499a0601eb568adc7a1bb4e0011e099ce4ecef49068df2c14b5f40707630d2c6be6ca7f549b719d15cc5f5803d614e2e2e395b72a2b8cfa6eea20cee6fdd1d368e44054c9db6c469c451887aad243e510e4c672a22a3e338c12836e500cb334a5a38852e0ee01bfcc771afd5ad9c65d01d794d1f39c955a1615ac29dde74b0e2014cee89fe4c87075a268b251f45ef695a289450fd1807fb177a568a49c310b86931aa415934310645b96a704990f1568137bc9876498822812935cb03a5f8f777565bcb9eb002d6e074fa3adc941aedeed110a48e157cb32de7ac47db83ed46523d12c6c5e99bba0c45916f4598a2bf9b2c7f051556433431bf79cfed810389864562a6ea7201bfd93d26ae5cc2469eb90962ebd350e4a0665037a1b40a37342dd498598abd1abfc51f63b618506c89c9d6334e97de1c1892a496521188c0d168c7abe79aedeb950ae41477b679f91f435b80ff2056f0749be7d41aadaf0de87a99183f9d1d7ad97b078c4186ab6c22e83cc809234e9a481d7cd4199158170d0f99b98606a62067b52149eb13eb9fc0b2bf7c699277e84b73ffe2530e04cab003c7c81d62a2f5a38c13da2d821c5495813485c4d804de801bc81722b83243be84e573108ade9d879608e9e94663478a82be48d053114dfefb7833de0637069361c53cf5ec86f3ac8b22a85954fecf71c896ca59bd0c8ccc220273fe3a6d0ad29c9c94f47a8db55cdc69ecc03b2de0c7fc3b403857feebfc272bc1d5f3f09b148e881e6880747573fcd006cb13977456f7c5aa35fecf8944cca848f4f4457d8bcfba01a5e277e7a317293d410f5a1a3c8632d23e9a2d71c823b38d4b37044c370b5c37a4b67ba175823217c46f56d75eb33a879bcb9265146211cf9c4308604bccdc88eeebb4bf603b23a31dfcda8ee712f61bd63497cced7c1fd3b8b5d954b1b8c25021dd39897bd61e94490b9569a67989f7d61ab9807c27385c00224698f70101b95d4009854713d9efb745d5f26a58e4fa5ba4594902721248865109549c84d5f3a349b3be28888021b8c14ef49ad7ccf953550384ae82c6d11f455abe67f95e1fd6f72d11fcb9f8f9d868c7424cb6c50a96ce8f7219f6475be6aa63b149ba3de3111a2f3a013ad5167a75f96af7b6038fdfa3be3c7348cdb79634b4cfcc7fe1aae6391b04efaad781f7ec5689f65271a549e5d999eb367e5d6a7dbb7acb892166f4507a4d08b268ca4490ff709d480505576e636f0803c07402ea1fcb7dc12f974a10224da9a317c015b995109ee1eab3e7160b3a85e5833b9f2ff6ec8a20aab8b1c0d6a0b5200d2ccfe75d6e70fc385c24e83479f356d258c1dd84a70fc22b505aeae6c3977e9105133e3ee711d8e877699a419a583a4345057290c42269e23d66abbd128d1aadba3c8bc2fc5ca72552233e078849e31bc55b9c2c84045c8cca65e476df0e16161d2dd0dd2b4f4833c26e21738592c52973419ba78b842b6a8c44fecfad5e851ecc2545afa9e19ae4978afe038a5b3384176cd951176f5b03fcafea560cf609479d99aee94ab003e853d7e07c89cb591dae1ca9cd4cfe689dd0d9af7b09196eb0375157866895d0b8b10af6765498f082e280be7c9bcc461126a2119210dea333026311256e9505fbd3cc6c913f974839344d6494df86407f9bfeb83b88811b827ec806481857d65833da944c1b940e06f73d7b32ce971b59ae5016e0e6f3c49cecb752550424e859a12cb6ed55ac5668c525570872100bc7598cb2e46d7190f057687b104cb0049beeac6ecc6a1ce1d3bbdc28b5700a5ed8cef7a099fa7f529900feeae0a4e72feef4633034c32c40186712e08f1c6ec0223cd42a5405610314dddaf9c9de128af5fd48f8b6757383d0b21eaa715387f7f57aebd371ddb1ffbd1fe7146a24449a5899d19a93bd37770d84f1a352bed2f9baea5d2f8ae615aec9502eebada2924c7030f4cb467adc3a54ca7b0f91d869175ec6d356188154d1b0a370116901041cd2294dbf538d6ca6381cb77d0ca5dd57b743bd7c39f397814c4175fc8544236d7c8bd855ddd8df7f11b504e11da2489d572cdb8a482a655a79640cc97e0b23208f40fddb9e1a459b267986c3cb507391c771331a85b9f828bf39778da6eb54914b6334ad30fb67595d176105a2e50f90cb386da799fd15b5386c6bf937f18f9051040e3942842dbfe394b0418c6d31cf104dc4cc530796a4fb55f35b56b6524fd330e7ddd91d7d4f00c94f76ce58395c94a9b8c9ff924366c0abaa4310672d859f3d0a951320e1da1f5ed0b6b3d05928833d2f9973a0163d76deadc659d7392c05680e5dd28e410da7142b370b2ef43432a4c91f219bfa3c1a2b6bc5698705fe6131979e4019d8302b05a96cc471f13aec618ab882eab860695971137bccc8ed6ca8f05ec8c4bd6aeddee820ecc62669a78d7cdeece87207bf1c31d57a0f871d2f68ed12d72ccf733794d9e8a2cd7cd4d6f90746543e198d3279f345f9d1e2645a86b7895f5df653d5ef0f8f2dabc02a7980e050a671f44a9d27654e8a0da763c6095ed3190bf8afaee81869186d44ae4e37d3bf6691ff6302c8e37260d71762c159c756c6df97192a77dd62af514dc4a0ea35be65b1615dcb5e079960393b351c285dfabcfbc525f5412ec6b3cb5e583522554cba30e304416fa781f68c8fde0d19614c14192adf138691a760dd1021149a92534b091c5958607c6d81073d5f82d7d9fa622758c60f70954c7d76f0cd242b2c77b3d449b74654602739faa84bd06c968bcd0fef89df6fc67a8f4164bd6c6bf2b802d6711e23877626c7278b3fed440e1dd2f374f36dc2e79416fe18b29c2bdf04ebaa5a383c4bf13a17dacbdad04f43f637091c9ab38207819a838c02e637cdac7aecc9ddfbdfd14ec33f62f2ff98a33276c98aa36cfcc5ef68575990c5a73f773126dd92758562c2ca5f18bf8e98510102ec5d28881fafe2d2af3515c5654e47e68c905494aff4539a44eb24948afc8bb15078b1d53a1432a2735c52ac3d0f675143ff00632dcd05d7150a8983de613ee38c66b87107c79ed3d2a8e7676d8777fc7b429ff03913d70df983312d031ecad1c803b0444057db26e99ab29416e7ad393e8ba7bb5debe8fb5833341dee2ce714a7f71f75d2c44f05b7e61f23351120713a5209aff6940eab8e02d3d7680641962a152118fb860f4064c07af2d10dfcb628acd14fd1dd387cf772d32193b9fe4264834e1d76ad3f8e981cf53f34d5bf561858f8efa51a586ff7e1a1f07246e8e9c2428e81cdbfac9b0ce15e5d92d5aff76c8d0f49942ee9bfcbb7c6d436b9f9cc98e07b466cb2cce134fdd4fdea1f712acbbeabd507dc1fc6f8233bbaaca81fcb28722765bbe929d3abfa19ba34b5347f8da646828a018108eeb344e39ead6d64f3aa903f8cfb6b9ef41344c69a6fb2dd9b3f8038d5ffbb98805d1593d5c170e26f34dae1e1ced67982d95950071c90683f5f350bcb6ba005dbfc19810730b54a939d67a0da0ba09f49867a76c4e9ad2c812dfdb18506a3496d76d5aba9da0ac8a715860e72d684b7c940176b5b65c453e7927bdcc0130903f420f12dfdb76f3c6f4a689741e9dede0b1c9141896cc5437a69ffef1e7418fda24a5187c7b51ea5498109dac89d42daa512b9d31930e7f4c276f84ab1725bd8b607c735eb6f46070509a3d74646cb89870bb69298ec70661d9858baed77bc01ac44352dfd43e7cbafe584f8aad69b31c0779d8f93f26dc97b7e397a5036fcb49d0c641dfa58ff65c8328b2b4ee8ba7feb7f17f49cc804162c2203160109830085858042c0c8241e5c130f2621879603aba3e73948d1502d83bbab9b036ed9e74dfc6ca3218ba1d9a99b38e2ecf9ee4958c53a57b556a0d66cb87d5b6d6bb11e251ed47c2000f8ad528856de6f9ce813692030c122260358583807ac5958243f8558b58248743280256e0a6633fb089e9f97555d4ad52386c9c56f42d204b5c334f9ecf66308961bb8033939b8a83cb9eca29e0aaae61bb46a9ff2958e958fa87a0e7e3f335ec09880e636b4f1d01c96da8787225a0c7bb2268069322ee60c7f315d45272c27e8dc9dd097cfd63eb1ecc9abfc058367b525cf963c3b6bc423022433650c5819854f7954070f4d4e57435ea07638ffc531b7f379e8a620a3c207c0061d98972e5efb3057009c970b601bd4c4fab81a93a0c5cbc790948186713be0095792fd15c4447c504186283083529e12cc8ec70c9c5260ea3ee9b374ee21411cf658550c1098dbf4fd50b1afab9a59969c52e54fec4c04e26c42c7e441cb67a229ead0c6768432b4e7e98c20b4fc7ca8d76e80bd5c8b8af8cf22e7873d2382406463e1d08395494a4f2818f642c360da3c59f84b33080b445fc177d00d822f6aec64466f8ba1459d7f488bcc7749ae832ddf6fa06dada9b463208d936cc4d92c8cc82a49f8f98972404de550e129a2456e1143bff6d0722700fa9eb850471ef54eb0d6962dd72c2e74603027a1482e25d785a0f5b7b61cd1c35d56d312f39366da7927c519a9cb28b214a99f122c8218a14dfd384a2075c4c859e873881dea18478e751308aa0c13f1f342fc5a05ec6d495a07af849737b506656828a695f2e34dc13c8712a38276bab9820916269278eeee13bc97196f44b040e247cb4a3a3bca3c761391284ddfc91aa87c7c399ce1add74a051e50261399294f1eaadb0bd238031a9c63d85b11d8fc8f4ee48e740daae2eff97a2f43e918c546440b1ea67d87ba76c604e7b527719844d8f04348c3025d13e763443a6a07e7843d1b655db5009b4d16443a7f867cba808b4348947f68d010981166f737c9a24aab50912a0b9262748040431b5bd505f951c6ff5e4176f5c11e2541a984be92a864a43792e9321b2223ad62f4d61daec8b819671d95500c1c183636b1fadda5a8e489b190b32ce07514da5871f2aac2569d9dcf9bbedd0c385c1c4e78062ba5d031fe39d1ebc10fbbbdb01b5f944d75168f50f039dfe10be273b52488d156a58d31138e6cfa6f6f16573c23e0afadc67ad5a80e1ca7bb0d211b0ca69118f4785f934f74046659047c25295ae38873fbd25d9fe344af89928439a2ec9f7844401b7a714322f476e70c51f02a98156fa43c1e4467900385195ed77a29b5d77512e3e063fc7c6c32e55859e76e3704c5e553d459128cb51997b376179346102e3030c9adf6db31574bf25be6d20cff2698df72a8e92a41a0a7f0857735953bbe2c8a62510c85b982831767a8285a482619762c1421a7a3ae66b99bd425a2a27ffcc0199875996317507e0c899093a788da499f546a4e4a1e990de16a34e33c6e2f2eb1b23190b7a9a9ee190e10ff9209b8deeb2ebf7b345e074dd8377d6ba68b2eed0ea6b2953fd076e2f6673db80b37cce1340f948d324398317eded1ea3b1f2fe01b509a8dbcd60447902ebb422830644ab9b92ccc4d775aaedc4023a28667eb804b05b3aa046fb5434f41ff6dc7caaef543d947259df1a1937c50daddb31638221c6b57195bcc15e61bb4628e54f2148fe12856c78004f39c01fdad7c492c8555de876f6d24a09cca5394a93308412316d2c0fde46b43e655f6e9c26660f6d2cc493fd417ad5b974f926870e0b13b93d713765ad4668b47d218754ee60d5144791b353a512940f071ecd0171165cf15c1ee10365edfbb503efe84d8abb682beea512d95053436368691a17e4c9f96a503da1da30fecd177267930cf48ddeb62fb911ca5781b774d90de0dc198e69ee2575d24c66a9a328dc7ae7faf8d7706ea720f417b183fdd5767f3505b1a7c1582cf80a8d718f1587e398830be67047844729a724bac1287ac0677ce74628459ce19f6ee1ee279fa2c8a62c1f96cff0dfc0a214401b687dc32f04dc1543ea639e22c85872e72fbb7461182bd10dda7e36b5f3cfdd3b7783dea0a99e142a11a4829fe6c793722c5896221255852efc5de4747f66a647d472bb39d49376890742c6d3295c017239a47a0b72a846bb31533dfe5b64bfc108223bb655d28af13cf8850238c90ab74c96d66f8a55d197824a52937e5be7dbb223a093fb4c441c08fd2060ee9b55a67be1fd991b9643d18615530d11de2a4dd843759a28129bce27ae039beb36ffaaad566fc3751ff79c3514a1400f7a5fcddb759719129244242e6c6bbd0d9fa2a30b621bcc539a937e67daa22bdd1b23b7df0f68b351c048dfbcd5867a8310d9594e77a030e0094974fc5bf050726dfb78b53edab37f451503387b999055fb5e936634bf2f663b9c378451541a1877c71556325a4789d5bb3614cff23953468379e9972e83e07f7fa0a27f4426f30fa95716316c6e5c79fa47e77e99a823aa07f400f1ef46d5d3892a90e2cb28b58c043d7d13220c46dba7d854a1d62eefe6eed364d15a9ce425c6964917fb3b91aa30c0fa9bd11bf4249d9441421be944d054f24f0e03a970f963ae6db48be121d5137b5cba1e2263f8046311a1b919abc88e9dd155743b45b622272a092be23d02cbdaec3a9b95c68ff6e03a31f7bfaa1d5e98437a8b2ea328faf5a390ea5c4de256322cae66baf7d8e94d67b2dd039a7ed32238b159eaaf858928598cb543524227d5e72fb7dc6b99ccf3559961bffca8a2c24a494eb181d55a624804b6682a7f1b128c986c08bd56114d3637d8b84051e9a457a841cf1d6d1aace906c7dd005ddb345321882374633a077839dcb359c887df9fd787e99c52d69ef874ca440126e6f6c7395ad66a7a92ad02efb2e112dc8d31a2b1370b1370418967222359cba018789cdbdcb7c29995ef23264a605b26a7ab8764f4ddbe8c13bdeabf5da627d3a6b4fefbf6254ac0d4fefd410df86f5881b49e902fb399f67beb542c75ee12ae16361418f670d5baa944077cd6edfd0b61b21d1ba96b3acd2c01c88587f59c854ab780ff0a21a975f0ccbcaf10ca6980dab87eab5545552ab1e258104365074a731ba8933825801f524e15372714d28676d823bc00c5a953bdff075448ccd80112694770d89bc2f216456f1ba68f89a33204e35414d11f1f2c1f8853bdf7a8c673a9cb42df89d9f8ffaa5195ad6df85477103f8ad49f19e3ab62835ec3190b437f9402260b53391e64e458a4f3dbe9e9aaba893391083103553ab9589336254626714bca644bc7c92e4b7d3a543ca5c0e558ee04d7b3afd3a12d47cfd0917f032a4af8a5348e244ed4b9ae52df62ef3365133c787664a1c02c3bdef145188d81b5e8c7bc1b680c308a120e14d189075d3a2c14b5250299aaa0d29beb9d1152eadce4dddf258f236a8a05be7b0bb9a948375307237b00f3d67de07e94bf4aaf78692d21a2cab0d02b124d00d82bccf05f8b696cf98a3211f8223c38ee7be590a9c8ec430cff55fe776a0501c18ad24e52bb4a86ed75c4b3d9d3a1b0ed413e546a5065bbf74de5cfde928611c9be6733ede153eacc1240194c6931e04a698f8a9531a432841403d3cfd304aba70a13e0ebf916e173b5c49f85e28183ac206c119c6eb422572ff380fb0fbb367815c9faed98f7585daf9c4f435833ea466bddc503e61783deb2e7bd00c7f7cdbbaac7217395f85a0d75cde2b814a0f31a5e9fab75c1974acc78bdc07e6018d8a881bdf39034456c376e419d6d0a249f120dd8d708326c784c0478b82dcf97698ee5f94f3e9084c1f02512f1a5c020b1e3d04e683f2ccf719eb96491328c69f4f5760e9de7cd956e598a8664afcf5741dbe6b1c4787d3b8039855f6883157b5a64a654b55aa68c550c59905ad8e0aa8534c270354abd782cd1da5d02f124574a7a86bcddd9effbf50054a2f2fc4aee7a81322d95d0ffbcf61deee19a50bf9579cfe0cf012ed210f349fb39a3e2c1aaed4fba5f291740361fa894db56d25b762c35e73f512b6393433fab9206eaa9802210281aafcf3ce08a95647ae69534eec1df16c94ed571fa04f8993064a7b173039922d189789673b758da88af0c0bc80b5960a9ff31c96c9b6a4db47e1632c53858faf2f302ae65b36fa55e96d9aea380f67a4b38ca64fc31ca714ac450279adcd2656cf690a8d401a4e3fb2861d809dd0fb3b16200f4647c2fc1189efe7666c8ac0f10cf61801541b8be281155472f02a9e7697c717088e827ad88e050916c89ad49a6fe50bd1344e321c216deea3f5126179cfd103641c9ad9dd12abc63db3e6c95ec5f05e4a575aadaff8a77d003399efcc0a83c2437efe14f590bb16ee1acd63add7ef35abd9f5261c7cf303c9583ba2f6a1931047a99ffdb6d49949a3f10c2560d7c14bed7cdfc4a132f2e0a42cd24ba3cce2f2125124c36f4d981c2b7a5171dbd07eb01a27c9545601340df787ea8e30ce806cbf95502bbbf0a5c83a199eefee494b37d57b185270789892b1d0b2fc29ac9c86bb33b47e61ae3bb964538fd58ce6873a30e198b50bf3583ebcc319789dbe3b52c0b966f6aaca2bf5e4c2bebf28489896511aaa4b7f5721c59e6e31ae66fe201588532d8651f7279f9bcd0c0f8e384826f9c658d4c4c24e2315601c94b0ac86038271ea51be719e8018782886e37acc74d2ca991398979c16d90dc8bf33ad38a69ee2742ec3e253d048a3e9eaeaf6ce2361b35a84de60538602ce5c238fa8d158f6fb20e33bcfb06697f7f8eae5d607101b402ed8789a67c8eb117213e6d01b2666c5ca9468c6723003af40b4198b0f81ac366298f9515292cd328d5fbe96d51b4604265dd6d6351924127ced784badce9cf20a1a56348d40d77e43c8a7de534efa655b38d80a6525560bdd45acf0d8ea97c6cca2b60d8719166c9e7124f292226829c2c75c1c66511dfb475467c896c06f818b783088dd0d81ba25a277b9d3c459f2839f84fb708d9a52d8161be2c537d00aef155aad58a76655e9cf0eb7a48d74027befc82b72810744cc75f64cde2b83466a2733c86e26eac9f3304f00c420cc2965a1915340e50242a2ac0ca1ad455efcd6002eca7240e71f055f360d3e2c63d7542a703b7b5bf50da893f3dc145df259aa660d33c9674318e44d83630d1ac2c341acd5074347fd0f8b76faac54804955f3dec2ef68949b37038ddb97b6f0e178eaf084a87aefe73df2b63151050fa36febb29992d1570d09f71ffd92f00a94cd0e84d8459f37deb4e70b04d22fff97b7113ab496259f10bb0c66df2b0964220ff30be2313c32343d3979683172852a2e3b8b047740d23290b6ec8cfb03a97c7888d0ecfb503289603af57ccadfae7d5dc2880626b305d1452fd1d3341e4a0ef451b65a9a034537d6caa2959a7dab9183183de467f9ea3cb7dafa1abbf03377f0f8aa52f08997472468b5a8d6c53b3297379b2b1311c89fea40d8c7c2c93dffbf31c734d3adf4f4ac6af303d71545b463904fe77a2a7d53142d2df50fe1fe237f58b3f134d75d518fefffee4f4249044d7eedfbfa4f90d8547d19d95c992ae31210c8db106585986e4fda596b37f6bb667122ada0ac7aefbaa29ba000e7cf0fee46663935584d7d701ee07e2515a12589fe4e88c41006471c0769c08419060851c305de6bcf2dc6f23c891bc8d58e1737978742dab2844e9359e216a1c1ee68540334d885c648f6e0d933f571d21ae4149c44ced79eea497b09059b89b776f761295d68a19a28d4e3d1e7795d2799f7c856357765597c9ae4a7ddbb65acdba61bc1d2a7f71a98cebb9bca764230f60f80979a7fda4329354fc74d9bbc087e27d749baa2fe6840e0323e4201f92733884f7d8d93d82634021420738207ef5725e9309517e979a1382dc5d9e68a4477806e686320a0acfd138cc6342460eb2c3a5af5f1899ec4dc909511b6b3c01de29efde58dff8d14a460cd384f7f8b66fce2df1cb67e2be60e336e54b0793ec34e7bc00612a8eb18d8231d8d8c4e3090c41e9bcd55630b5fd50ecfbdb220612ce84bbed430dd9ace9709efb5138d742e0001343785d56d79934d1abca231e42d503b860e25df95efb721ebb40ce03e64d7baf7cbb9caa4ad5d444ad0ec8bebb7fedbdeaa22d61bddd111230200130b13878ac211497a1882b24a11ebd187439db58527082141b5f489825eb316c825226751016aaf52761a7af0568e2f7893cc7b29efa1446127b2b8c68172414adab3592209d27d74708c2e9ff501e2d949ae11ef3301816c7dc4a3006b2f43fea3a2bf6f11156d74f4104d841056327addfd52e531591b2d2a81d0410dfbcfd13702b4731da48c646a23e7eb9894749acdc5a7aadef17512f27ccae333d34051725e6c08504dac5e0dda6edfb8324b90250447f4cfb290f48db4ecd2007171f0c35bcefc74f12188dc2091888e4231988465fa5829a950291ad4013cc243a60b1feb7fd86734659fc316f08a8e4909d980eff534583391e5018bc6ebde8e1c362235caac2077edc44500bc048202a6dd63b655ce72f78d53e4dee73d46b10ac10962b212fcb1a77eca2adfde20e0987102b7f89212f30941c6c3cb340f1b6c98e870c2e300b13ec2735a01a526b443891d9f4f33f72d201171547b79f7bfd91f12a2a0bef6fb695834961c3dd4f1a62060d0c20c55b250e6c85a5eecc03a3d5655be50fdc329c86ae454a0346f728636340f81f96bae389004ff106669171a254cf2a1959d2116ffc34707d42468fb48642dd04833f2d186ff70d7f308405c5e0fa08f1818c7b96c103e934e5cdf1b0c136f89d51ab27deb86444b96e9c519c2281c87391c0e0cde2b4d2cfb3bf58e6236fab701a439f2faf27b774e0d09fac2b69819aebff547d17297ac2e5285ef7e1a36d91a7c0d9f1a8eb77d0d13df087ce7003d2057b29c418e1011aa57ef71967dacd2e96886d12ea3a2de0df26fd837b5d0c4aaa23df2f862bee99dc5a7678588ca9ad19149deb8ac9f8f7d7e25fa6cb43266acd07aff4f70376c1e15d443cb9dae9a13453ea02ae9fc79ff5224cbf758153fab7c853e3de349c0c812b2e45da1ed1d1b45d18645a6d25b820702923da965f24acad4ee8848d8ac7a0a96aeca3f866997bd15b74c83c27126f06f3283d0180d24149348671a09baed81976d6f31e3715b13f086cb21d48262041f4225a034644ff915d286c165c45ce5a00f9ac8b110584c9d6d32e7ece3c1e124543caaf2447b008d351b71ed96a1baee7ddb75e0dfc3ec3cb7c141b985778fa0c25d3e9f2139084784c18d725282807cb8aee43a4da5b427f4d5deef7f8b62419d1e15774320ae503131ecff6c0ae71211d101dbd83548589bb97af37604e042d6c6e474215ac6def5304b0e05f6fd23d4e5e4f7a0d42b0c8623f3a9c6182c634cebca2a221fbf0c8926293ac48748c3df09539bc8b40d3e497005042d9f3c950fbd23b7c4c2ca902023f81fe31714d37d6228b9db0de8aaf3236ca16994d9f36179d51192c6a18829f38f9e9c2337aecd5cbdf39697dc05a79b061da3ba0ac791a9efbdcaa3e5a6433081e2781044302ea66f622492af36774c951448e124e2ca8657320d60a2c201ac7e07c10f1157887a232741d86ae49f6c67611904f618a18a25fe6d4d7b4790bdc0f701adc0030bda6d6e48eb06ece55dec659e48da43b9456678eaa50f0a695ef82b71976ea68517200e9671b75434430d468d09cc6420068f383e07102a1828363ddcff37e35edd048e208e4c3692a635532622305849e52340a958f268368d2c5efe5aa72235f111b4e245e808cd5eb58aced85a499be91d6fe86ebebc205ca1438026a02f7239c774f87121683f9a0edbc6c113d3a86974a89753c716ba17261e00140995dd243909e86c5fe36f5ab22757b965ae57a39df5f53916090ff4c9517d70e98b25e4860affc10efe00691a0913287ad15ab0f6d2cf9183a006bef96a40fbadd0329ab832c796fa9334868e4d1f14619f5f989f4d1de21888288a357a1db3af1e055c0eb60463bc8f7465fdbfc466daf445a7e37fe567fde27ec0738d210cf87b54d67995640c22b88aedd7fbdf4932992c86d58f88c111b6972a16ddbd1002ba0a87d3d3f25e7265c8602e049318c5b7a6148f3b825c5ebb207a4e1a387be0ddfd83515bca88e7e3b3b3ab7b910a9c03b4fde6e8d9b2138008216e3eec70f78ac0609d4b9b4e66479b3008cfc9ecaef7da841425d6d212f15e91e983e7792781b5b7b542c8f8b616122f68e9c25b9d60cf52e05430aef7040ff264745ccd0d6dd9b590db5587b63d4454746b45339bf3ee4347505200d8d26a482196ca87b5d8ef33e2f0cbeaed1e9e1ff6f308d9e79b33302c833bf53ba05d9a2664aa8ded28850c9ce89497e0ee3b2b9cb42777eacd50ef569906c02c53d6ea5e5d913a4d0f486bd8913090adeb9f12086b4589dad41b61631d511e7d76043bcdd30f3b86c6d0c950760e27aee487a0c69b2b1305c81a8f403f89fe93c9d2c6441bdde8244e636954b024e32d3471c0276b2d32d712014d99bd428b2f1977214532f8fd587801ab4657dfc619ed4d8408d5d39ecf3b1533468fd48df38f63cc592df2c2fc32836b081c7a2add7141e98274d59490fd9bd7001c93d8e457f0bafd11cf819c0fdf1cc125a0d6c3e5fd4904b4a0eda16a8f48367c3e10af541e3a951ff6399cee8c958ac22fc16d03165f6c57e1fce01948120b35d2b148b559581fd1d2d651ec71368e8db506b41672e6f4de48afc0d26f315f14e2fbac1387a1e405137198a502f398bdf86ae1b2fea3567f19bd0774337e6285e1fba6eea861cc5ef4257dfd0e93eed3c9b222d801a16e5717ce389134d9aff5f7565ff6d3200f5974d32c4645c0afb41a5eac1874600c4de1b15391a41ee3c01a2e26a30905aa2a98a0a06960041a2a3c2c8120048c0b827e687bf4a7a25e88d770488a3bffca811a3aa73907a9f5f65e77687ab8d653551f772fc82bfcec7d63e8203ee4fa62fb6fdc52b80887c40678ae54d1fe089b2807de61f17e2f222d4aa64088410b562db3124ac32f1bd8cfc0c89fb2faab6bac5bd21bef0a7c45ed09043afee9f8862f516f786f8e1af925e827cb821d80b71406eead92713f9337ca6d03f11cd6a2dee0bf1c31f25bd02f97013ec837ef8e23edb54ff6c347fa779ce48d85c08a4c7041ede04310f54205c914d3ac978aacb769e7c6144329ebc4c234dfbf8e2fc31673c754024e3c98f6872d5114cf1870f5277261e1880a7a1c40af258ecc96426562dbfd7cae6c259fd5e32aab185510fa4d6c85e62092184ecbd65e10e440fa80f961ae160d030ea836ed9d313382f972552875eb60dd2a46ced1ba95fecfb9b3f93657dd041b2bde556d02d7b3b3107c48212220a139aaf9deea6db6754cc57375f32db6755cc97775bfa4bffee84966bc56336e74ba53967133cd9fbbc637f217ff5762e799e77df8da59feabb39e7c463e927536732bd27cbf4aea799f6990e3a1bf2836cdf9d5991ed777b8ac57c81b7a745d406e192b2bdb5f6d6da4f2dacb516f503346f3fa598d35afbce5a6b3fabb5d65a6bad5d5d29a66e2624bf6cc864d96ed5e11c3d22ca044dae911c46290e88c25098092ec80ae5f6c49a5855ae2837e52757e52617f5d45d75abbbd25d9cd557304feaab7993db23a66e8f78f215e641f9c92bea9a3c75546aae6ef29aba3c44e689e450c13c52543991998279ee51c7495d05f3fca95794abf2d54df9efcaef55cd7bd591b857fd2b47e25f593de548ac9ef29e5512285739122857794f5e49a9bf2c5fb9fcde1fa8afb8dc1f2d7769b9cbc9537e5b5ce56849b94acbe55111c131b9ca517e985ce5279525f5d5512e0f9123525f9d084eeaabb3dc1fa9afde1f0eea2ba89fd89bd8a7ac2ae528a995d505694bbb4aca3d6d699bcc1c909db753339b75da99ade6652e29952689e5a2982cfbd2e5824c96fdbc1cd064597b122c8d26cb0ec986d88f60ee6ea6837eb1337bea29fc2313a2a21dd22fb6749bc3da57d4cd8468cb5e1ad95b6b51d65ad46dead6e4f6c464cea7e65113bcd9b4d4524badb5d6749a5f4729a5f4f368ac68967dbfedfb7900eb4bd4da4b7b0a047ab827ebb3de1472c87c996eef5dcf0ad0f493c9e499dac89e4cf7ebee75efcfb378a7f3e1e64b09b54a505270868c4f561604f65029574044862141280ac2145620521bc6d801e58f13d2adaf0f44c3b8a01a1dd6b71a62b93fd3317a24615ab42528af9411a11f4b6e67148997b30cd4a8c89f1634595180632634b99848fdf2bd74a1c8df3921dd45fe52ff661c521f6776b399d17a24a3347b419421495ab323f335434461273fc1ddad8abbe910139ccadc908febb8a00e6bfece4dd161e7d35fb55e0e715774c368e9dd5d2e9524979af7b49de4279259cf99eab9594fb7b3eca383f5ab1397c57c8df4e8846dcc7caa308ab821547ce7aae08628cce43b57e43b67e43b87c577ae68beb6fc9dfb7e929522cdd77cd56c26cb5c237fcf80643f507caf74c847a9c92ddda01e327276fbabfd65981e65da998ba42e7ce60bc87cd5f95a65588b22d720f933ca56007eef68eb7b0604a2fce42c5775d18f158eea2657ad5457a9ce93b2bad387b69254a9eb43e671221df1437f54f5d2152d5516a4efd95091a2ec0b9916f97b8f96be4718d991fc7d9b386647f97ba9665cd07c8d13695409cdd71833f46364bec6ce0337c57c85f9e3aac81f7745fe60640e8bfc65bf91e58cba001ca58f867fac70b49b98601f9355f694f3685ff9f76ce8ce9fc9fabe7225126d7d4ff9b4dbb44583b62a9e476f681825a22da40e4bb40af9a346e890bfd7ee28994f2553d52cfd488ebaa7db2b0f5ed3b3cfa3544cd637a100b34985e6a5f272584cd6f7d23d6591bf9770455c0d38214e07f9fb9e9d001ce910a12f3b1d325fd9bf532ae62bb3c9e4cd8adcceb0c85ff683ce88aa9059c1f964548023cd9dc5911ec9dfa714bf4c488b991551fc8f5da4c62913ba5026c5cc7ea80ac44526ae51c223d8f4c86642d91098331e80f22500c789c405d1237af409654242f3a343280df2477f9a0ee9f07430d3231a0cf928113703a24c889b0151fe5e67cfa6989b014783ce76008ef4277f4ce821f9fb48a590bfd7cf9a2cbd5307e033210ae38268eb7b0d92f2b3a14777e61f7ad4e1a94f98fed0afa989fe7428b3cf6606f9a415fa654a91bf4b2af40bc5737e37c0cc05b100440dcdd74ee9a77fcfaa98afd2bf6742d915f355ff79ff5e6b4fdee84a1e4d7742cbdcdb9ed27b1ea5eff19cada726af364173b5e9713bc86ddbed4b94528ac7ede04b6d6f133cf9543a9d26d2e462be48fe7d261d992ff05f6734b798afb1fbc9df91f91a6550fefe7d0aa163120c0df361419489dfa716f30b62c8dfc74984fc7536f9019a41e68bfefb9462cea3f9b2dfac227ff76e672af23745fea8d02ff69248067d37d27545412c578a27371b9a5f2634595fe93de2c957259c0388ea28ef1153a491ea18e5aabef797e309f0840ba23013cc04372488e5b628bfeea4a6dcd55577e5282c2596db52ba382c6fc13c2767b9eaf68828b7473cb93da2ea2c9827e5aa57938b721c93a3609e939b9cb01ce5f56405f34871e555da934b84ae30cf8b9b9c7c05f3e09fbca6dc95b3dcd5f16df98babf2fe6ebcb8ca91787115fc962381dfc2f2d59160f92ae52b4722e52befc91d6d716fb9206d715f5d15be2e67b92a4fb9f72fee0f93b7bccaefde1ffffdafeaabbfb82de294dffb43f5d557ee55ee8f94abe0a07c45050725e5f707ca57aeaa2e9787e5299787c811276739119c93b3dce5fe3839cbfbc33179cb890268eb3bcad5415bdf4fee12b4f5a97cf51596969fdc66b9206d6d5fb92adadabebaa7adcd56ced2abf5f4cbf7da497a34850fef28cf935a4cd6c74d3159dfbdcb0d99aceff4724193f53d0bc1f7122c8d26ebcb8432a16f0473e9663fe897cf6382c25649683ff909fea1bd33a17ef9543d1d7affae000a9346df9bc2beefd5e46643b4f56544b4f5fd26d2e833f977f20fe59f4a8572426f42496e3659a5773786c2ba0e04bfab28acbbef740982e74c5966023becdea7914ae526e957a684667deff7f7ce88fae53bcd0368ef6df4c8287f97df291068c25c50fe4e8fe6ab6e4191e6ebf4eff57a56801537783af518fabb347abd32a7217f6fc85fd7b79bacd28777ba534f3781a822cbe66bda0094d7f0a8e5ceb24c82dd3404b5618ca7202120cbca3597770c17b8e5b28bdcb94d5d56cabaac749595a017c5e733a46d5e91b7d34ca2a1bc9d23caf35e6796af7c05ff58394b8fd8a2147be56a454fb81c48cb59de23ae68536841f3753abd2685568286c1b421da151366c222d322da9026d41d018daa0988c268884ca620a6a04c91c0cc03cab44746ce9aa342c069ca4cf823fa8ccc1f6876bf226e0047d91d4e29ff114dd66744e6ec9f9122256f03387e44191bc0f13365289f8dc9c4e5b1878c4c94e947d3c18378f4b209f79091b5f77071b4c291dd7453298b158e31cbd9f8e50c1ba98d824cefe94d4114863f9a86bcc02eb8e23ef3c91e10851129c129a7b745dea31db23ef41c1924cc3434726ac8271f393864fad1131abd21f8a317f4e22478f482647a6e0a0dfb82382a2637860ec1d373445c91f9fa4ecf19e1b0e086cc5797fac88121532e0b997257705564faa49c25a13cf39949d3052f6e8ce30be3f7faf0df1e54de22111feefd6f8fa872717c78717b447c7bc47b7bc4df1ef1f73e601e97dfd71e2efe2f0f919413c1e9a18757697f89a4e08bf3f780795afedf5bf1e521a272223960601e29c27895165f222aef0fe73e06e659f9c54d537e53bebaa33624a75ce5e2fc30300fcb8f53f0c801a23c7aefc111e5eec55d39be2cbfd7e5bf2df7eea7ba36591285719c914cb98f1c51a69de988a9c894c564cda4ef048fa0c9500aa34ab0c988040781202b7706afccb6c87c79a7dc37eeda475351b64627a3aec337c86481b77395dfcc9926e5a4577c361aa6439345b9ec4014f6536c8d50d8174444ffd16353d10cba26a37e318dc125a721d3d7d3ada7d3ccd26bca6753c20dd65f91bdf76784875748b40804888c6e695f2501e4feff1334c4af70b464ef2dd9c3422efe7f5ca35bda9b0cb9c9b0b25d80f4a75fe84ca23eb455badae56744372157dc93055ebbf4e4fd347df2a8fd645b80a3f643a7982d7afae1b1f3c99d47eda773b606503b9d62b2e8e7110afb8eba454d3e48e0d177740470a442997e3419512b1a668d28ad820e75684f4f8350984d5af1f9a1b096539783140ddda21f295186474a45a6a7dff6ee7e41268bd696724e156ef5d974a75a4ad1820a658bdcf95402bf4b2cc0eedfe9a3ccdf3fec0101ecdef9bbeab3f97083dd4ba33cd5d2491626a949c10e77cf3e1b59c5e267b228149345b528beab05b99a145ad0a7014d9636a45fb0008edab528e62bd3e83528260c14a98f0feab3e94a3e9b4c0da04da230d026654614b681a05bf45b098c32b56ec8f4dad5b8b85a92d6c564d1dbbbf9f40b35a21a52a6cfb07684b6e85bae5644bf723522daa25a095aa3d764d0e11085ad9c6a3100a5a8e259011e9981847140ca9f1e64fa96b01c1c310de1c1646a512b41c34c43262331c8d444b4824c2915ea173a9a8a32fdcac7ef03fac9e719f795bbca01a4e53da2cb3f245a345f5e1647e6ab747a530782aaa34c4f3e2623fa1d7d0755445d0782f4a620a6a10fe88be20b729509c8e2b1eb4c439972afdc1da7cf04c14cd291847444238fa88a4a13e9c8cb328e8b6934068e5a7b8eebb22cc5dd7b77bfec9ade759ad67d97b3b7a47d361e6e30c34e68b954afccc22b7d21cba5db99bba3cc220b797e26bd856565de6444613a68a86258279fa30e093419657a952ddb8c9c6c4fca14ada89a0fa5946a40bac8cd051502d2a4dc7d94fb320a17a98b893d2bc0ac8bfc9aab01d1564b9904d224b00bed278fdee9a7c31b9d2bd6a0307571f2a1b09ad39bb498af204e6f3a9a2f204e6fda62be6a9cde84345fb1d39bb898aff0f4a6a4f99a39d58254099abc3f1bd51693454d4c24d8fabb9277a86b9f4d2b85c79e9c7abd23150256d44bde9f4d4a1493452b1e7bc60c299b989898dc31d3229794b03c887b3a1097e4352ef8d8453dbcadcfdcd4490b9253a72099bee6a644315b2caf2941e6ab625af2139a9f6096d77a5382b0dc14a03280f5630a50ca351dd1d6fc6c4a3ad3cc14a0f962397d4a14294158708325b304f7c89072fdfc86905778c2088bc9eb4d709621e56e5d21344fd160d516b345afa1aeeae82bc1634f2eb90a2975fae9820eff7a3fce15e45a558a688bbed2bcb65e2fb1982f00bc5e16cd57005e2fb398af95d796d7cb2fccd7c92b015e55af28af777965795dbd9abc7efa7498f28a597acc203975d46beaaa505775640598faa83abaa14a9d6612e0aafc894e24c0558a284c95d4035629bab82885e527d357952b4414bdae03f128bd0ef611cc345449af1f5c03986144268635e4f6e003cd6ddd56b3ea01705f9a551f802bd3acfa95fb43b3ea5bee4cb3ea4f2e10cdaa273f2d00a808e02ef7e5aa0b7302dcfc5f9a59ae0f1f4dc83c64196f82c7c727b3dc892ecbacfcd477ef2e7524dd6a482b692c2d46bb1f557933425b01b7262bc286b425f918e5f047050406a1b050cbf2cceb109191a2232a23f088c2e82b128589f42e9f0d9a67eef219a0e6d65cb3825aa959215a59213a92e9ffe148b1e23dc9a63a54ad2821c92d3ab4719d0f9d82666246e247950e3eebe3cc2cda2fae8b785c51c5f098caadcfe0d1e6d63bc4e3ccae8f3303e03777e6eed6db85471d00f84dd99b2bb378497a7c6a0c1b1a719a5bc4cc69a6c9776315aec295292834058598da21ae101e3c787c3c0f9be3f8052c70817c3b3a51116f6c70dc6e18158ff1d29689a99cdee413dea8882ae16d0e4d316c0a92e95fa058d56743a552117599e848a687b162c5bba950505082828286327d8ccf66e655c5a69c82282ce739f82398835df8e4f371dde5e3f271e151470ea2e5da83156fcd593e1bcfb1d76ef1c187ce071f7cf001772d2929b8c587140ae5430c1f4a7cf021860f31e4134c238e1c3bcd146fcd6f6ed7dcdcceb10b440eafcc5544ca357795ca59aed7c6aebc43beb94ecc6c238fc01083186258f166f9e4b3c943ae2d5b734d603e1c34cfbcf5d96ca15fc2b7bed89571c83537cb35c6143ddcc0071bb06ad0b2b12b83f28d0c1bbb9d851baf03b03531f6b3915c50d9d8955c64944f6ac165c58bca37b75d2e970b8f34339f016489adb9253d41e1678099675e63eccd3de521ae10acc2405be002204d8ed5175b73bd7c7365c671332bc0713b7a196516d926e706c8c14b5cc7c66d4e040f1e3c787c882b84070f1e3c5e802b043f7151092594f8132a518963e0eaf4e8d1232727a702d7e991935373f13e7272727272727272de848e8e8e8e8e8e8ece99d8b163c78e1d3b76ecf805c6711cc771fc1334c4f116b84076767676767676fe040d71e7db11cc7703cc21f692fa853e763d3af40b7d36048edb511df28eead0c7ee236823bccded86095f7363176f374cec15b8b46562ef71b3fe21f69ddb752bf6f182dd8a9dc755752b267e894b5b26bc1237eb1fc2efb85db7c2eb5cb05be173aeaa5b211e7564f1407c36669ef92928e5f49f118565dd8ae1c02398531e7483c72ea704659a634fe598510c8f3459c423cd9dd0f2ccc72f29d303f11940e69987b7739d6163570830f44bf81a8445f9665e5f46c2007bc217b24c73a56163970565c6c6ee8a2ab4b1bbcae2cd72ca27bbd02fe1c53b738dd9d86d2764f1aea417fa253ccb098b8a85e5b2b0b0b098d8b013404a0a554202a2b09c5eacacac685907c1993ebcb1782c9e0b0b0b4b8985854ec9c252a51c4ca30672ec3537cb37b7b378b91cde1212ecb4832165fa1b17a75fe469ae343259329fb932af2b0ae3d1f90e025ccf0a3088d7b8781b3708206e10226e3088d597801e7187188425c0ed6ce3028185eca861e302719b1bc46b6ebe7809103bd8a197e5c3ebe52ac11aef2f870876bc3f244c39ef6fe634b3a6b4a4486a1a7d845848ce633763213f9d98739adb59881b0416f27371c767aeeb40dccef39b797f383c3a3828875fcde09eac18d639cf0e9c731ddcd1568d1c0cd2563361064172889dc8720c77bf8ce1bbc99a398e193c834c96cc433c83264b66e6baba5f604e3369dc51fe6499c3eed84659e6af3bce2bb2cc61ee38a5c832ff41e655e6f664cd9857f4cb8cd34c993b038f03c03de6511e7b32cc633ecea024b9636004e0ea17d7a7155eee7a375f30789459e613e62edc1d6599c7e096b91d1140994fd6bc0cee60622e0ccc9d47fa850ae08ea7fc82c769853c76233724d307e0fac800707dc8d6f5a1b1ee7824d3f7b01d1df9c85e5c1f591ee98f8fecde717b43a677d98e7cc8cc7257eed8e5d51d3b15934fa64f31caf42a229f9195ba6387da8e7c70d707079e8646551e4f43434999ded6211a858f2d974e4399be3319f998793cf9f8d8f2a82565f74887349f90243067148c4a9a566405388b727f5aa12717fad91040598468b2e485004ab1d499107ae22a68b695a416935592464100a526b3d02ff2bb010470944182482ca60afc18f39125837491d273942e814c589f09952a2b952aee22ddd84531acd2b31f18fd00e5d283e4d22914e0a852a964494561d3a754ca84401aa5cc0760737885c3fd740eaf846c3f9dfb89b26ed0ccac07e0cf269e5e4f9d34ea97fb83a7a32d89857ea158fed4dcd20db9248dba557a5f96a161aa948c3963946bc82555bf949ef1002cbd4aa3a30e094c023c02c43289b64a87029c1fa5d137c48f8403582a954a9770c84800d297de304a7827134219a1360cadebbaae63391739cb2e2f924d9f8df6aeeb3a0d6879d49177e877b68fde3823975ebbd71cf3f5bd5fbf3bcafcb5b8b8b8b8b4dc9dcd25a5a5e52e2e2a6761691967de54c696163c6645b2ca9d9899a6e01dfaed2d4f7995b6a5a5a5a5a5a5e59b4bcb4da1af57a5c5e52d23fdb1a9151832f2f69e33f28625c93784470f7e3764bc9e88f952e977675b64beec69520000d0c2f7af75bb23c842cfb2b13c23a267d9c6ac28bb3ce5eeacfc0399de91d2fcc282c79eccf2edd294ed2938339272179617bc93f2152360b225c818cb5ddef3f5b29d0a00068f33af5c00789c45b2cbd80140853f9e95ff31e607afa47c25655b71f996e282570248829132394151e1d8fe19b1b5dce519918cd1bbe09e2c16cf0a50a5e532ee28b38c83df0d96bbe0138bcb0663fa6e6c2cffb6cde52c301886e522af5c1701a4d08f320947cd1bde54fe22e376aed4aa582a2e5f39fd38c3c58895bb5cc6ed2c55245100f0d8bd3800f008b6f0a8c278fcc5238bf563d3a9899a4cdbb37efdf45dbffac5724f719d917756eeb2728aefb21de351e6956779c32b7c95b7249d85c7181ff0c8ea81e831885ee015d176951e33b2cbc71e3332fdea63965b6ebf1b2edfa1f8850b7d4ca39cbc4d52ef1e33f2f6d5616097ed2f5a5aee7d362ddb954993358faf5cb9d3c7e5a34c5a39cdbc4f61b90e982cd3c719d99a3ecac8d6f41146b6a68f2b63cae563677f43c47c2d41c664b69faf96db93644572cbcde17271b6ab00074c968acb559e72c79e9cf2f9d9a4ccc8f42eafdbbd81bd23802d3fbdbf6ddb5af048aff295b39c66badc96d35096db63465ec1d912248cca5777ccb28abd4a053faaf2e9047eecf2e9dde04fd3741585a9f01813f39cb4d1988f2a998f60267937ccf5b1cb24ae2b73bb492e2f77d41512f312213f176330d77d4e3cd26fddfc6e94509a4943b393c824d5f815d5dbf7ae135a7642cb363a321d80a394497476333b779dd0c61ab9351a93d5ef4e28f78b0fd01e014c5c83aaa2b0f99dedf36dc1aea3a11eed3cef9ae679efc9a2a19cf4a8d6719bf7ed34d4935ce99be7799efc36b739b79e4dd213f4489b9019d2c8fd334296204bbcc3e11ef2277397975300396c8167df4810345f1348b502e3b264c44c160d297784d8202a448788b2d781facc76dd1d44f77ed6b0d2fbb66174a874a910a502981d4d16525090a3204046403f477e321f9f24234948444847434746478a8c100d098d20439a78d4e690a7bcfcc147461a6494275087320f26dd6a02cb146264e1050c79ca26080108223f740b075d835c8a4167218ff348098a54795ec5de0ed857edcbe1956e8bd2ded2a5bdd327d3507514664cd67ca6a273ce634a0525ea3068bea6984141b35eea755080230da253764b9626c94c4941b30feced389507897bc6619e0df3f074c7b1dfae71d78e4372eeb5dec4a39d5eea8e63baf66d7b3d0eeadbedc9ed3dcee4dc49485e82251109e6e14a98a7d3b4dbe374d76e2ab9e9a78de4a7a33829445bf426982785795098e784794cf525ac83a73bbd04cb20928398e754ebed4da5d23fcc63314fc5344c5cfae0189a597a8bdbc6bdc5add4719b2827f7869e9e9e9e6c03fab11dbcf7d2bd522767906ddbb44dcbb22ca3992c7a7a048ecbf2700554090978327db67aa58edbb42cc60d5deca0368c90fe26695183953940612d86c00748ce84b55843943d91b4e9e3e36364ce88c973d22882b2edf9125272213f174bf00ac785c7e53d62bf0361a4eeb60571dc1419d064d94f7e3649b41cd1f294b35cc572d5ca112b3739cd4c62f5d4fb3b62f5d453ae76d5fd4d6ec95317f52a7bc4ede2a0501c4e4af5d45377fe5093cb43843b911cc73c523c4eea1ae6a1465822a1eef441c229f9310f3d92499302d969347187f1288b329f0eb9db672068182d9548806af66de7ae96abfc8e40e1123c8d68cb3e953aeaef08d44bb04da2e48892ab70d31610933fd189a750f48ba54168d0a90b7a00f64fc48814062d634f57d03fd89b5c8e52a07eb1cf8880401c0de2a8143408159a5dd124a2ad23468c7a7212a8971c0914b6f4285b4cb5982c4b8dfac57e87fbc7655ba5dfebd67d7bd3cc9b63966534b4947975cad1a6dfbd84c78ccbb22cc363f752133cf9e3be2668fe86f48b9562b26cbd53e41590a62dfb1e51a343f3552f948764d995df11bf0afd6c48f91d61f294cf6f3ebba557fa6d9dca91f85592303129e12452577d622452577dc3ab0c275172d491c8529424d28fd56e81381b3424dbeba0b0d388a1307c2b6eaa4efa44b2148a6cadb5f648b625f4b62f854c882691bd3c42db0a21db29248fb27dfded68ab2bb93968e6539ebaaa975cd4f15d758bddbd2b92b7982af92d78ff92935c70b2ec5357a502104c99dc5b10e37b5c8281c82037649796cba22d7b96954b83e6ded0967dcacd81ba3a1a29db532840f9cce78481c0931b435b3468cbfe41f6273448b62c56090da2b0d45526a9ef3bea7bc997056db345083624e8966542eee77e4d875ee97d1a35683820dab219e8659a654a29fdbc1337a7c836730138b520936587cc2eee4cb2cf48d0404a80e61d1aa884ded367a6932b923439a04cda4f8f26756129a5d488c2527f0a77b72c46514a8d643b31775a849aedb9283aec6c9222480ee1a8982fdadb477fba7ced4aa6fad3ebe982375deddc6703e2d3c5f192e6bde49dbc2ca9fdbc9bc6ccc7846dcc6cf260147141a4b0e7a640d97355d87343f6dc1576cb5613ed4dd2cb7e8c6441ec4c96b9469679b453cc572cdb7bd7ce974e4327aa03ea2123d3f74fb69a4f7f14673e99cf7c4d203f504c7ca3731441322956d446e159fb8eb6ec3320d0e4a9af3e7240434e8efa49cac94f4ece8392927452727dc8f91de1d3653e9977e957b3f39e0db1cf84aec88c645958a02f643b8bb235caf69d4781e66b9c4941e66b54c534d248870c4561a7c8968a6c2da594da0cff58e16447b5787214f6413d7b8657f428e7c9ae72dba2eaaad8a3cc5bb2190ad3a02d0fcfa3a40ebb2e3abc43c338a049878e51a369870ec990ed2d0cba653f5220d9663eb4650f5a133592b1992461ecadfd38f389665080f4448f26cb5223d3e5ae88a25fec3b8e8893827301b702ae0546d99e3bb2f3456f4fb5b0d73e1b3a6f4645bfd89b6e96c564d9cb7b24db67556444ba952463990e321ef48bfd38eb90ed96d42f3603caf6945b011703ae0639f3c86e9a96b40d792ae993d98e4a43ae6ebe64f0dc84e6eb87d3d7e9b7217303ea30767aad0e5a17da1db4a40e654eafd1a14398cfc02defc6836cd18fdb76f496302fa94ee0c23cbc14b8eb4ae0db91c9092622939184a12eaf31983b8157992bc3f76723dd90ebb4afdb594666095cd765aea4c03d81a05fe839eac2279f7ea13f6c5b644c003724bc1d3d7c068225d09f2b411999cbdc45e631193c412044c23f7131e7315e392b732752670f0f33b70efdf0aa439345eb153fdcce3357e6dadd55cc396796654af02418be562b813be3fdfd709a49816b1a83ccb1db5d2723632538e3dd67639a62b2a8a9880c3611998ccc104fa700ba7c347142dcd07cc99c9ebb62be6278b8b8fcb8b83485edb88c9f1a735731efc931789439e655da98ed28eb9066d847f043fdddd889796799eb5c4ee6724397bb62b2829ab6649cfed0eb7297ffb8dce52dc6dcce32b7f38edbe3e3437f28ac2fa8ba884d43268b7e0636056d1686bbcf86cc32af129c41a1909981e90f059a3fd0672000e98f4b0c8f60feac042e57bf1f2e3fd7d08ccc8c98cc8c1932662822a243d08c984c75c919191919994c09a0fc0c6c32ea01f8016944ccc1445cd79e4d96cc5d3237bd6ee71f40205302f77445bfd053e09e8ed02ff43357964aa7af3297c2dc097ce69a7c4c407e668eddce55c85c99ad046e974d4ea843b205c2bc3f1bbc1df50bdd8e600e76e88132990ccc0de9869c15f58b8c09e69ec26bf2992cfa1fae49e6d6d40f97be2e8562b2e8672efdc183846d6d08ef8cc3e4a25fded02ff4326dc8dee9b7236fc281f34a1d97992accf5ba584217455e521321652af39e9c5487b6a2a2a2a9657466a6d350bf509895eb32e7a48071b96026173e3e3e3e20106140a81114997ea340be2226ec20d3733f1c14f345333d17c57cf5128a0c652ad2bb64607ee66bdc86f27c09916998290c0c0ccc740338ca9f3ce375c66988c22652ea3d5fa66f432f3c7633db50a630cfb93034f02cea1799c3dc715a21cbe071008ff9447a11e2f96222a58042415150ebebf57abd8a2063271f1d1dba4e5fade830024fc14e43b44e7b3f7650806367635a97dfbf78cf8f5d7ef111cc2fdef3f57acf571dca8e00e2cbe0b1cbf830780433fe08cebc669266d434f6b8f0768404503e0297e9785c5ad671b72db634b86c6a7079ea08e0eb2fb20c73d7cd7204ae47874a75dc089c863e19f3eaf03d0503f39e30cf8e008e75c84bfae16378af8bc9a232c7f0c8935d19c912c470450eef729dc6472f2902b7f39442c63acbdc753bd72c088471b9eeb685965d783b3a0208f31fdedf8d2066be350fe2da1c886b83a8c3f0329f4ae8305fe673091de2b8cc27133abcb9cc67917e8997f934d22f202ef38945bf82b8cc6b1604be5ea799b30d208d36d03be0f41b17f30581f97ac0c3d36f6ce8b001a7af10b841fc01370815f10e7040100e80c005e20fb841dc01fd89b50137f66983b8421c884b73d79d79be3117969966ba5e8db842bc884b536b18bb09388edbd9759338cdc5b9101701bf0993b89d438b7311f0f09a72cd6c78bd8c238ca5d8f0f235c7644931168bc5c4bb13c66a443cf664f1b1ebba638603871866456e4627c49b3b31b34b144551146bf08eebe1c5d7bc4a2b8aa2288ae2fb1bc2f510c71d63779435555a3176d195f9d89f14d00a8c1c561939ac437288a5e91bc273fdfb6ed838cd89a0b9144208974b88bb6e3f1b5752922ac985c72cbb5ef3f08e60c6e13a8e1087eb38c2d3d030f69abb63f30f64575803071e7b328e8777cc6ac2d7b84e435d358fe1a881776a6e33c4431c8fbde7ab868b082386c0e3cc3627028fb3488e751d08aa54493635b7a9096d620f6b62db51d781a04ac50aefc2238ef0aebb2e3f23c2c75c8fd18c23e6fa8d781b7794d9c6bfef068ec7b0c511c362c5c221ea7723c4712f0c63c73104b6116d6eacc6f5f0068777ddbc868d9bd86deec2a30d9bc76c84b827eba60ed116bd8d8fdd013e82373eaa727c3ce2230b898f31e15d2e97cbf5ac5f35ee7ad7af9abb6efb85e3ae77bf86b80bdb3c6673171177bdbf2162e189c0a3cc36639643bc22e237178f90c0630ceb083cb29e038f57ddc0a3ea0078046de0f03731d76d7cccb2f8d27723f61d173ec0bbcf089b63312cd6af528da00b8f3d66e4f0361e0b7f00f1e2b9cf46dc88b89bcddd90268bc66c4e3387a85183c3e572b95c372ed11573b92ea5eba1ebd97c85776545b43014c330144f4336a2783bbb6c6e6ee38e59be390dbdb942bce6d2c8cf15ded3cd3d89f714bba722934585c03793255f850e6d109d884e5fc8e0e9dd31ef0b6f090750defba130cfe8c733fac9f47545f60a35ddfc1a31f35398e4c9f9b8c413703b672dbb5b4e1e4762c7796020448a30e23d594a0c7cd23927bdd1935dcf3e1b175e25b1e33e8ec48efb784f6e8289d327582211031c089102fc89db3cfb6cae905de306b2f81f3cbea3438f013c30cf88799678ce779cb6742e8fce593af7c70d6db9ae5375ee8f18b14e9d2bc4a51188c416b34f5621cb3e8a23969d70e071438ae14a3f1b2fc9c6eadc18da727dfbb6cf46078ba10a838a847a8597e475e1e1e1b4856a042f0f950455050d63e2548493114e493831e1f4845315484848485eb796d33462208bcf746e8bd5b3e13de5daa14ade97eb67c36b7335d9f0d65c4f16b4e12de52e27e092f48b7c2db121ca86291b9ad8f0c48628364c4149014de1ed6c62c01592f305d4148b73197004dc053c01b7e60ab835eff95ac0c7952c5d9727e9b0e6e25ba6264b82427e884c25f8f8f800f1112bed6ed9d23976d01adf798f531aba0387c777f0e0f1fe5c3457e234b8891c3d56e1c7efbc06c6d931e720c6be63a394663c9e837978d0a24e0b35ad6e353521d54ae16bbcc51cb4e53a0d394d71a222d36f110513660024fb909b09320043ae5a056dce9d62e54a8a502823a99292921259071f923ae4258dabf03baeb3723de73b3cbed5ed3ba2451e3839dfc9d9f110dfe8ac739ae9259976e4984c2693c994b23957d6c147443af972f0787faed3ccd4e7c248b4b8a2f9ce95d0c12bd7753e3ef521d1228f87d7aba90f6747f81dafd2f2b83bde5f382a8179a4b883b7248ca3f31ccce3ed409d6ace5d1da1f39cf348f1878a3c23e811757007749e7329566973aed4c126a226bac075ee059e73a58f6881eb5c0b3ce74a220ce85c0c3ce74e1f71fb6c729e4ad5139b733db13f13518eeb26a222468a8e986cfd4cd4141434c510a1a171e7f4600f25bed3430912bb43795cb0261c7dba7c3a9d4e27d4c7809cf3c03c446a9ef39ab23c6ecefbabc14de0e85c07732edc448e11871847e73b30cf9c83a883379a9973b9932f87c9a733f99880987e28ec02a62027d67e47b4988379a4c8e33a39e3e94d3e9b2670765c89bb9e735739749ef39d8f77e5fa8e2b817988b8700e203b98478a39d7c13c52d4f98ed7133bde1d75e834e42551d826d2f7771aa2a8a33e82a88faaebdced2889f3a90378dbb9f0f77ddf0792b491ecba4ffe6cbea04a62c33b3ebb5e57b6e62ae0f2c3f9c153813bf10c5c0ed1964b7e36720afde27a45d9f08eacec7a9ddffbfb8268f0b821d5e0714b0af1c8f9642cfac5f549a37e71fdf391311f4e741907918c69a05b42871a50e524745880d37f4e30808c19206806f1d34d2181f861e5a06bfcd01069d0353070fa8f091dda9cfe13d2301fa7ff7cd0b0264eff11a1614c9cfe0b4187429cfe13417f24e8ef04fda9a03f1834cc022a2fa8a4615e106dd197bcae5a5c492a8872084fce15907375c82ffcfc8c726416fde232d2e20889c22c700ce45c1e1a1a4a595a6cce75b95c4444458c141da1300ce45c9e95ebab9aafc2d7e038cf2a7c8bed842162d356cd6b8deb5228db1a1b345f459cde4e315f469cde0ea1b00b9c5ae0f47688c23070fafaabba36e7a6c48a5fd0bcb039570ea12dd7a5500ca42dd7fb9354e817d76966856173ae26d61836e752b1f6802a21014fa618b24d7a4031898f3de7b618de2ed725ee2a899c57e03998e70354ccf94f49fc40ce733091f146e7265c72780d6839c44278bc02af273601b73328635e961bd2c6050ee80324e73a4b84788583048ff7e4257490683167895b81237e10a9798b44c2e7dc1dafb93839df8179763c677c0ee6c9f9f8aa73778ea3f31dccb3e33a3b76ae837974bef3bae3f210094f24c71298478a4bbc4abbe31209df1f4e8ff3c03c3cdee3384a7c09ccb3e34a9cc70e1d045c669bf04bdc0a64e03a71670c995d504d029e4c2c2e758580bb9e4412b84104f8f011d19311900402308b45c0ed89735d38559fea1212b0e5a0090c6fe8c23d59de1764ac1bc687d3b70f5fc8f49e1185958ed0d2911ed74b52e2569ffa5379dc1a84b6e877dc1a445b4384884a4728ec14e40551980da2464446441e910b978e8041f433f7002fe20e71232e11afe16df1d67cce69c39ad79bdbb906d9d06cad99dd1975944a9fcdcdebb4268be37a75f0ece075e103c4d2d72114a684124a28a184124afc091aa212a7af423d7af4e8d1a3478f1eb895d819c3107f44414139dc349f0f18cddcf419809670a452a999126f70c452a73f0da552a7a1a23720659a94399f4cc1202e734dd9938dddc682447d365e1285f950187dfda13020f41588c280d0d7201476919a989cc7dd71756ece55e9487135b2c98723cb3337d9ec89f68196885bc487d8710b5c9d63e0e65cbc5f15c20633315936afd30a218a528bf0e26b6a6a665e7b6666e66309c975c33bca1c7ee68eae8b366e1ede9eecea91ca36b0248384114f436b8eb2cdfbb31171ce64d9dce6ca6f47de43d78db8dbd1b6c58ebb21d1d696c4f94011621697c832c3723aa17c36763395c9c62e4d395995d89db9823676e58ae4e6822b1f0e171bbb356e5c3445502c11b7e643dc227e806bc42f70756e819b731f97c79bb8e399b83b17af296360e64f74e28e17e08a77a2cb3e9c00738edfb80da2304b74551011bd0190f811ef1aad560b00ef2a41d79bc7dd90eeb67339f1723ffd42bf6363430f80fe8918717343cbd06f69e81f766e8be36d91c76d71c76d51dc8e7c6ad276548d508764cce342c214a1433964aa02c100bc3b00f73c2fa623bb8e4302d9752126905d378202d9f52294c8aed7dc6ed6b8935dd7b940763d6703d9f5999eecc2a3f81b178e5b8bd02ff442dc6a847ea137e2d6226e259a2cfa9a5b756ecdb9b588d623fd12bb9d717436e2762ee276aeb99d756e8b39b7c5997a05685dd8024d56660470f492928032bd97e4d5c10e1ddab84a05a30818305e93926ad2cd0d3745ec3737c208235e6518de75c719d975f18ecfe26762af6118cebc87f717e2d54de7f0373a87d83b821679068faedf3c7685787f375cc7719a19bb33a7a133b7b3ab338edb63461602733690303737475b1e3ab471213eaa683e82353e7639c6bb63ccdcf59b6b844f96db5111af81c72e17418347301721041e55b9083c66b9a687e3c0e3cc3dcce010bb3012ae1f71b386713dc7ed7eb9716d2c1185712e2a17117511d5bce5b321f3cc4d35a7f7b8a8794d4dcd63789cb9067b5c64fa96cf66a6c4e572b95a6a8b150346a610edcf2b3acc68c4b0549deca251760124777737509e514c2972777743917b8addddad3bf7284091b777ddd87d75d346d9fb28734f0db2772f640f77cb18bb97deddced50302d871e0769a793b9a09e66c8b2adf32256d6c15957ba924b397604088d8ea99decf6af56e974d9724db7ebaf4eab5f7ecebbf576babfdecca67caf55a554d799ee7799ee7799ee7cd1f2790a4a484043c31412f139325bb2130a10c45b24b6e2694218a5c4fdd9c323a293459f4f20d3454014b7060beb253076cefc18413f3a5c98d03251238aa8c7da474af2ac0013a72e6123de465c253006d4d5a845a6b0c716563be6630f76743a3e7f3d470475bf21436a3c63b99bb68ce690218441346d62f60dc6cb2fee2e3fc9c87719af91ce3128f313e5f63dc6eb260dcacb3f982f1ecc2e860b026ebc53542a3c66cdaf59cb3b3c229ac819898ddbbae8489649f5b902a0808d4adce3464f8e956e7feb3cedab52b8a3b90036327bbf35e9231dfe59e75fbaaebb839e79c73ce39e79cdc46638929b36ddb2645ef32917d762769584869b2684a9866b266768a63266b7e9e5e961658a5116820023a868086e9cfdec216f23c13f3355fa8cf3b60be52269fcf99af93cf2f315f289fef315faaa7bc543e5be5bd769f9f315fb6f4f91a34353744e4c0e970f5495b74e5f3f35d52ee3a29d34c56cdcc81d3a18f1b9d570ad0417b4c588badadb0fc2c37bbab8bd32f7d95ebc464f553aeeaf698ac3eca5d62b2fa273767b2744c9603266bb2fa2537c764f5492e1193d507efcd64f54fb766b2faa64b3359fdefd698acbebd33ae8cc9ea7b973559fdd2a53159fd96dbf5e9d65fcdcc0cb5298c67be3b751306645e044cf808f9e944dafd4b408fa8c90e0b99f8e7a2b6f5bb6fda463f6f8b5808bdf671f3abf36818f7d00fd03993a031a128d767599d34082da994a75564960852a86510ba23e982909243b28a92edd9735a4162fa7ed665efde5dfb6c3ad34ba7d367a98c7237a65feae7f591e5ee36fe76f96d6e5fa516c6a47fa213b5d77fbeb8d75718f395f27a968cf942797dcc7ca940927a22734ac9654685e107c9289be45e02188c64300ce593dc4b004390963a574fecb7abd85f392485d003904468997af983fea1bec6b03d83687104576288591a502cfd84fc45591869219126abfa00212a8272fa140ca650303d02516e92a101dc4179c9eb6b56e55a72d595995e9a553c2bc0926eb2ea4fae3d0358f2b1db82e49321506ca0bc6447f5131415940a0aea44857272471414936b06907efa14992f99abc94f3e1b13dca0cc2857e6f93359b5c5e7470bd09ed69694eb833b8d62b2aa0f7aeb842a7fa7d7892edb2926aba6bc4ab08a933b8b4c563dca55dd89c564d57f7732a15feaed9d4a68987ad31cc293a85f6a8ec9aadf6e5606d0e42a4fdde23964b2ea69ad26d7a609398526ab6a9708eadb25527209aa9e91012cb9aada9dd557cedd72aa92579a4fbe7f963bcabf839fea2725475959958c255795c8acba9e1560098abee4b42425e57a40004b4a4a7e52f9cac719a47295cb775cbe5a51314959b9894acaca4565754795afa89c66aea894a8a8dce21dd5b9ab7c541dbcea2aef9c0a1aa292c20daaa8983c230388ba49bdea8e6d9451af23067a76569eba7db178a437797f364dcc8c7aa577c7be73fd40b64f39bde3cc2847b9dd2f9fbdea283fb9dd2f28789479a709d51d3f90532b5803928ea89ba03c2b40d4a93dea963b0a3c1d43e63c2080a8776e31ca2d57e6091404d5821b44bde423a227a368e66753f27a6279055b587ef2d9b41ce57636ad5e4f2ab7276be5cb262bf56aeac9a8db59e576ae2725252c3f69b93368c13269b2aa444212121212aa25ab159c84af6079b4bad2c808855251515151515151515151515151414920a0928dc5ab21ecbfdfb0b827cbfe7b4fa677e4b177a4475d52953bf26492d3ebc4cc2647dd9127a72ebf1b253779ca3565d56dc928b797108631e4131c25bf09964726abcaa2c9aa2703f84ceb4f2fdf4d241d9a48be920ebf128bead0a26aaac39af24c3af44c4e3a2cf50b3de99792a3949cde5e947ea1e73a44dd1e75b7940eb7144da5434d255b7598ade84a877465b27438593a44b5a05cbac6f67ea12fc163973fcc046dd55b3caae8ef2c325bf5f3e543f134428227d118c07112e59a89f5d3084de69abb14a2e333f85102d921a26c24d767aed65a57389eb91fa8726782c25aec905696bb565bf9b55bce88fbed6fd3562606908a279188384a21966f2ddbc3a0b5580df36447c40f7492cbf67f03c3f6db2be0df304f0df10356fcd1b8cf7e973bbdb28a7eb962b6ea3769853442ae9742e81fea2bb6f40ad1bedd9f4ed4b014a2adfa5f203f17b73f71f1f5b28a09dbf015bfb28a96a9a7b79b8569cebe0072073f4aa11b60a6580af54b7dd603106548b4ff18803224fe3433f3025845879ed7b9becab05987da4a8dc9aa306cd60530c62743d0f59ba66519a57268ce96307929843bdfcc1788eb15406b7d3dce7c79afefd1217d7d8ef992afb84bd536c2e9971ba65ca35f6abdc71f69e43a4aa01c40eef1bb8dbed28a8504eaeaf1ed688bdeef34d30720f75fde7457dd65ee5ebaabee0dd6385d393459f5a5faae3e0b01483359f5264c63b26a7d060270ae70ce2387688b46adf5a5cfefc3398e5738fff67fc32b21daffb389ff6d6aa5084683b6eafba7d12ff5f5b7dd69a6fd3b2c7f26abe29d5964326bb4b0944aca62b158ac20958e66b1582cd626821277746a29a892ceeeee6e7a1ada9dcc4de5004a3964fdea0e6693f5531b46ed8601d1fe4427923cd18953254e9638e5c7943d909f4e347dd482f8e9c4efe397bf8f24232a777667632126c9d2c4124c74d83f20683a00a564b06258598a2da7a12dd5907f943f2e28954668c8088d91255420d8e3e80a8d84a42379cb055fafcc2c40e857be3ac94b5a548c80ddaac3414cf0c81f1945364a29720645ce24d0cc3aa923cba49492c562b1581d48df72cfe2e1955779f44b76497247d9ca3e1b0e39bbc5b5621b0f6b4ba87ce54052be7aa597e4f3822f5d0e4c56f60e4ddf599ec47716bceacef21693307dd5e1d51124677912246701ff839ee4498067390bfe310fbec5958bba09ca3d5d754fce991c750dcc0104c8084e3f3910202607823ac951b48ce4a232937bd2e21237349395ddf4150165be2c2a4d922a4c94524a27edeeccd34a5b27fbe5d4dddda5eef6b49ad9eeeecf742a11d1d171ddec3e3b3c3b09aa68e8fc4cc1d649908ea914eaa9a983daa7cfba57145f2afb53d2a634a39452d97d2a73770b91746612534ab9217ce3b8771cb75d8e2aad7b8629cde4248da28eddddd2ce4abdee4c6afd7ee9923637d972a494d2d3a9c312673275d875dfd72157b2b6c3cdab79865af5bc0e335b2a7548bfcec4711dca71db5af64b9fe3b64e2b65ddd44e567fa4946620a594525aa7959fed7e777fb67aa6696f50bbf992b2d24f12299fcd09f64b9f0681f2f388ccfac5daccd98d4c6489b37e69214f3d95ca7200b604e5ec4bd9568b6ebe249871bf0b1793722ccc8c529a65da8722331c80f256a0637623b2c30094d914a0cc68f7bb64478c8e5287f5b32258a0521add28c55da594be5bc325a92215d56666831899dd00941f33da18086db31d6792e2ba2e85b281a7429580d94b888c1491c02039d2198147b3233242ad9ddf67621dc66180dd599ed3ab916578cc1a8479b0d229ce2e3da96531265caa43954a3c920ada9f4ca6ef64c14a42e29594505d6abe9a58d923490f25db898692a9684aa7e45459596a04825d7f25852a31497536b381ece6ab7b4a90bef4d964a74660f63cc6c8fd99799a97593bbfcc06a9ac06a0aca7de32c5234feeeacc99a49732cbac9bdca4d982085c146148764295fb7d52a7fc94b2e9a452d42a41265672bfdf7551d4a63600e7fc28a5fdd12210d581489e9874c85d3e2533f7f1d4c9da5ae411b41f511d8ae6465feabe1b59e63e2957393965a66d9c94734a12d486314a211d34f394cae8e88c70a46474077aa5988ed3a2a05163c6d8443f8ce69472e3a6c8b22de36cc005197136e0a6e0a6d8643686fe1726386766b4c5514e7ff2408274ce77cf4b43b3f7cdb2a9cdacc8d63db3d7fef679bb71674b78e7ee8c66d9d6a7777ebb59dfce9cdca0900aca12b7d67dad7b667565573e1653cbc9053cc9dd4e4a30ea450a06876212a34b517925952c9b3db799cdd95a77d318305ee07b97169695954a8a0ae564481e4c52a81212f064fa6cf54a1db7f9f07965153e5c22e33cfd87e690b42b1f8ba9e5e4029ee496600e05f52205c32446a73ae9a1a49252bdd5291e3521faec540a4dbcc464c9949442726876b97b8801e305be7769615959a9a4a850a61a4e4c52a81212f064fa6cf54a1d5725482910227493a2bc8ef9d2661f95b6b96dda0b8c366dce39a7909094a3b4a2b42a7551140d1529fac20f15595e916516591ec9526a9165a9e324c7719cec699a1bd67173264b5e30052028ab98523e0381d00c923d3d4c551774fc6847dbba52a9dbb4d3e730722373f4e793e02ef10f79ee13ff208223cffdc77cbfb5ad2b95ba4debce4887b6c4117dee387dee598671b86b98477bbf47a4678203dee94ff54ad9bb8cbbe06dda0273d0166ddd38019c97d90ec03126d33ecd049a53d3a2368cb191b4ec9b767f10c1a9cffec3bbf6edfe7802e85d7bd5bed256385bf6ba0101694b34d2912d4161da71b66b97d7bc7be7d1bebd47e4aa77bb0dec58996369319e57afe11fdaabf6da22474361d9b9df70cfc1993e9bd5abba940a608ba7939a56f24ee078df5ebaccda5dc9ff2032ff63bbf71f444a18a7aee476ef38db3dbc92e7dee2c438daeb7f54bc929866b2b8dfd0169739015cc9edd993f8e17d7b125a363651eeee11b3db23b23856e684641c9d1c096a7f647dbec69898f99a197671fe66be8860751117a464cc572b610586943206b5df45b927c3a0db428a3c3fe548df7d1944067548453914a06389982c64a45d853c7615f2d84840f57d0e94ba7b626f3434bb6357217751eedcdd55c198dba470a80dc3053f5638dd35eca3adb297ceb39d3b7d474b1d77370dd3a02df933599f5306a156094ea1c9aa22f738afc8fd3622b1e886227710383fa568dad9d04c2d4b3cafe897a904a479a40ed52169b32680e3360406e6307781f90c98c780818181795604dc80926060ee01a13cbade23a725a8546bd68a63450b99423323d00000000315003030180c0805a3e1689886bae80314800f8eac546c5a9986511053ca204308318400000000001119188d480073372a2928f67506016b8b28992f177c3899c4f6df51216388b5bf611c3f044cd6b93b470348ed4675c5e05f360a741a4f633e3443311a6bb9f67c08106ef5083d30b8158c9958add428c47cd093478937b3faa2ed0a4ec16e99cbd6325189d215b4cfd2c9184bfa9059e080adc0c291fc9083bc87425ece037bbdf6d863c664198cd0920af298fbe5543c6efd546623560121b96b22ebf63de078752bdb6a3ec68c370b276f978ee22db486291ce36e1aa0a051b4b0b65d7b101773cdceec71a610b4703a05ca231d11cb3bc83a5f8b398a6caf8c8af51f99693e04d8af7d18f8674f0852f6a750c665a7e20b06e8c314b40906a38f905bda285fcd7fcb0dec0557b0e65a302b385631c28e9d8165a4e5e4450b9c46f1d844cc8749799d8eae2885ed7838465dd5011b88da6f3ca8602917b1d45b9e2e3610d580b1fd14d0e9165138ba7a4b426af4db2b091b08a7fc1294b213c552de8f01ccf962b15e7fb7bc8741ba0e5768b40ab9925d2e389a064255451ed8d545c2f1dc41dfe485e930f37acbb83539b19c940e7e932677a07250823023642c6847dc7543a2e27df2c7570e9a6735fa44f0d654a8ee731d29e50d4fbf2b86649f479220e1f16be828c3d6118896eb93f005d1e7dd9434b677911d01970283a8a280b87542f68ccafb147ac16e6a408d1de41158cd26a9802791827cec40b19b9d1d2a7dcc2a902eb275550efd78c3e250b8e1b0c8dab1ae83ad174ca394a2e929822d91202121cfe0fdd8a57b056226986ed3d63dc073f2ebb83a20ef60d375d9f57b95a2c16e4096b56bd50167bab340c40e25dfc5cc7153a7f8d954ccb0a05223a14a19ca1291586bb80cbfb409edca742249d93aba1048b21ba37de2afeaed8d3966675cd6ce807067ec9a7e4c8432908448cc63f70e3cf40c683dd9d3ff0817d8db3330af20c4360c47164880240dec696970cb8f86e076ff1947c3254f9206104491a2af496429051ad42b10f5d03f5e040d523eda801a904980e3b9449ec51c34cc6b50558c652970c6aee91416824122840e67404e00f46e108dda5e64f1471a65ea4422e1622d005dc77a181a1375832a035aaafa4474fb145876b59176b733ed1d9ec709970061f2a1aec30d95c6d3b0dfe20073d8338ff2a53534c49dc093343f7d08ab8d22ed72865a067f4f844ea768402de5e018ae31924e0178f3c782bf30aac52996ef6bb4f07b8a20a5fc27535bebe4fe34198544aacae9eb60d2c9cfc9a0c35a9188fb73b951cdb812eb0407f58ddcb5a80dea0c6aa84fccefb251ddc916a4b7c0fcc7046fb413521cf8c43bc47beaed8696c9ab49411d4cbf8034eb46a0e2f7cdf51c131bb8fbad7eaa21a39079f8651d7ec6567f1b833f97c870f8eb1da56c04bcf4ec2b3a3dcb950aa5e6420574a49182e14c8d3408a1a706edec7deaaec0929d0d4260ea1c7b8e60395225d9d9ef70837a1db0e164fb10572a51fd4d2ac9e19a4a4f09ac99d8c35ad75360075298d422223eae0cb0024a0b15674b26504106f1ed31850db3c4ccc6f616064fd64969b2bb58b39cfcbdbf1904b29bb3b464afbfe7c89958994693bc31495683983982e0a9ea444cb0e5c002edcc1678046d02e1a2c771a1c56bcb33201c2b6605eae8b31dcecfb6ac34ed58ac9b164fb40df1c42cabaaadc0e151200e06d7ba87d718f7cc1006310e2324b493b02c42df3430ec5ad640c3c285a1ce774495c1ecfa791424be0a6f1ba2c497e607117e91e6170e3d17d04d031f6df84bed28cb94e23f0edc8fcc4201aa7b4e36b1b27fd7cbfec3357122ffa79724f1a0f74dbea3ecbe81179dc0581186d541af382c1eb028d9b08a05fa545f00d534659035772e4bee99e37e6c4409796427073feb9d22a20909ed41fc2139e242c746c93787cbf4c630a175add930a070e71c815c095234e1e462cb078e21da3c07f097a57159091e9fba0772aaa15785a226431068a3af0a65077f610bc0df59dbdfd14ce970a8939dd738e2d15b520aed1b24ea31d88805127209350b79205c09bcd822c4c2d8ee8f4a451d640180c23adb8e81a223b01f140baabf3daeb483ce5f6950e174ad772908cff1e16b7d62e9fadd8b470f716a08fa9c8d7ed11b96f8035c514d09654d82a50a3fe20209b317b114313287eee2cb7efad74fccb6d4a926970b816ff46d1c2fb6d83633d802c20b8dbe5adbdcf875f5b6422db831b96fd9389c32c547ff535e11b05e8cd97eb549ba87860fc51e181ecc38ad52f83b3d47a89a9619a7555cfb15748f793f67520d77756b7d9218dc25299d3a5886bf8e8436baee50eedd5989b03b129e5a4a1821f23b41ee1db76219921f0bf64305076eeef96ae5648dad904e56bcd5786dae191aa11ff6609d2480a826c81aae1320eb4029c232eccb55b1fd8094c3894793c2a182be5dd5a1d0bfc4d280027e10a6f330c5d9e761d8349a5e9b2cc52f1ccdccc6167a8c19b24660f48ae5adbb9e50eb9d9f6b4c7638454d56a9027b2c3393c05828a426d8ac5b00e33ae2e00be81ceeafd5224c6d1e77f5a48958c13e5e165abc17f75fa8228c10a9a1e4eddfef3d89f2607a63ab45878d46c070fd4ec38db8ee53107027c9f29e75ab2dee03d92049ebd94bd63bc6f9581ea9262130c18d79f8240ac60c06d68d9c114a93f0426050af9f90c8d5f8ac8f2cc0b0988eb33f601c3ef27acaedd4e10018751eaced18b31bb796c5e20e44286991b7cd22122f207d69452ebeff6c88cc0f4cf3e247845260a38e513aeaf30a6b7c23a77c24c626960c82af08eddcf59e20782ddc97cf5ed856079d0c1be0d2c652fc3c545ec89a5f32a6e86eb6468556b4bdff421b0496686402352538d96823a859b2af0afec2235fabced49c878c991ca6bf9e44af43e18050a965b85cc9bf690d645461c8a8f6feff0eb97be7c8f6578c9ddb3e5c72dfd329115d9402c5e9058e5de8b043772e84df39686886054368dae6bb618d6c68011c919893c09cfccd1f25a335745fb8c6479774ef8cf9c7b122190338166eb2acf1d7fab5a994b437a0221028405577b0d870d4bbd437276d7656568b6e7aea009639b4baf5a03e2995bb11f2db052406eb8b44f03f51106a4fc29768dbd5c92828b0f632d617c16eb687e846eca2f60dcfad7337c42931ade24226d29dd9e60c283edd707e23e13cbbd062c51022d1860df5666983d21d5096bb9ebdf06449f09d12e8847a95af1437ff78f9cbc294d4630b1f98a0b56a2ff95aed9e171a75af7ecd0b8bba82d9a46391a97c9906e80a7420e38eeb9f1c874aa45898225080531d86906f0fd629e578d803a50b0db3f8cb0cd720a1e9c98bee2e7ea712a485cdbc6faa123867425eec4c09fcb9744946baf0642304fbf85989e42a55f536dbf09e7f3044c238d3040c9604afca6e502390702ebcc9682456a61dfd70dc1bab564c67a0d6efd52a578cf3ce6965be20ed2d9452a431bc2949d60135d232ea93afcc59ca93c242d52cad8736dc009dc528d718ce24ac4a3103eb9f8e87ab5b4dab57b06ff7132fc11e7466e09e62fa9486060ec3190bb51c1a0fa957cbbd50bee4863bbd6d2a62dafe633000c3eec85484e08e1892d50d5873f69a42b7b44479ebe50ef46c5d4a577f69f2958c8f58668439c981561ca3304926513528f81fed5ff12407c399cd3ddf8c4c447988b745637663fcbbf0dd367067681517b148e09c003668cce6663bcea7072a57d80b8c727c156438e6cd0d12c80545f4628778aa4683e5dbcd947c8b603c60631b926b8c88d460a1ca849e56ee93ca8d57992917f18706cb345ede953ac1127f1a5bd28166d38317f57d84fd0a2248a5c21272132a90c6874c9e537a3725b3402360371754d3be568da577a754578bd2f70addd7e1d59c2c8785201f6ddf9555cb432a213f4b5f6b32a2f43d110950fcbc3d3a5c8e1b4768e2d1762018f93556ce30ac81448b61f3177a55554f86d7c03a12306a8f35e0dab1fde82016634bd49e3d74b30b9163bb554e8dc1d71aeee33c6fed529b28c877a00712bdc7c69d1887aa472697368dba65a10220b18ba03f5ba1a4aa066ed21064ae6686c82b2c1af01358ceed83a6da70fe3022f4fff7aba08c1f617b22904d90b5a985c19082ed5d93af81cdd970dc321f55a4a6915e8fc99ee8ab0ed6c42bcb15c3133a640a17ec9cdb020c26aba6b655f33ce6dd1f8f82be415db30ce35c248d6960e1664f5f20cb422057a1e2f6e05e0f7100f02f437d3f53f37d99abcdc0b5fc1fc27a40ee939b59b800931de58b01b5e0e754068b4d7a0d75dd8c44b3be48ffc44830c9bfd097f0811db80c167d31ad3b26b660216b295e5e24b953a905dda20f20fe4f8ccd8c69906b1685b334cc73708fb379ed52c479226878fd04e03c8df0a9ced1c62160922fca8a0691f3fe0745320209bcc024d0d817530d1cc02faf5c3872657a81f5052e6878087d1123f2625f3324aa3daa87a92d55b106be4038174389840eca5dffbd4c82c93295df8b8512124203ea253f2424e19305cfb9d1a2d578536ddffddd078d87e8816123c0f82fa266c011c4369babea29e6b6b145decf256ca5264a004cdea2517c0e39f1acf1fbaf7dee551d113f4781de28fd403cf17a951cf82e87e2ad0d7abb0f02bff7660b472ac6271ee94940f190f6790075ca91b2920b7a51bc3dc0b48eb5d77d9fa88e97afa39b45c8889c1fa3c8260ef73708c64a12e66df9b1b0777134c9c5c2be23418cb120f6b8c15a640a51e251c9db66961a70954a1ca6a83cdb2b9a623e86892edea790c2c8a156adc2b5eaa6cecb860b5b35f86431528746433f38e57be3e8e90b5c12f24608a39d20f9da945de148742c7e6a19703af460ecdbd934f45a35c82b59652637f9c9e6724283252b6f32272be49ef8b37cfb97fdb866bd6ffe46e3ac69e888a8a1d12b82d1e615b51a7a8235b4cb80cf834b81f0beb11f155f6c28cdb742780082283c3e3478f8ac86e3b868181b9ae75cb0d8cfece8d9348d9bf55b69df7dc1ac44b070052de060e3d2c707a7f806a0502e9a3d479417badafbbc0b6f1490425b84792ecc2e64916b56d4059386f01c4561a06f16bfca6e2951fd4144b98315a101ce01e788360085c8d2223af8f3e4a3bd0a5bb0f71d93dbde4be03794ef80769014df3d6a09ac13d2def30eddfa4632c7c4537899b2c741c2eb7683470cd04563be748e8697bf1d1370be48e218833ab2f7bf977fd7aeab773d54ade9c0f124f2d2ad2950b03de7c58dfbf9b8a545b56aef7ba49a3208303473b9d96ffc4aa7665125aa7e1666bebb54b653b09dd1020d68427fa86b980fe05bd6b9292b1ad133dda62c60f1a8a8d4d2a5e371d3d7dc6417e15ed38ebc8d10bacfa4ca44d97a87f1dfbdf43749d54a61f2f0880a692d544542e0b13d94f6f7fe39735b5a23775bc01695a13f37547e288c37ca4e07edeae90f68b5c005812e0d35033bc9f2fff3dff35231cf2bca920888e200c75025cc0e3b3a646607bea30951242bbb1826f834c828d3d3f2caedfaf9ff063682b75f27b119475a675ba79a2373ca99dc913303283c19469bc78a516f8df34eb6ca18f0f66a11d85ec1113a04f5a784a0189f3dcd6e0a50f09b155ff8a00fcd99a918ee428e23e65bec6d6b8326f6af3191ab35a48d38ce0390ad6a6c4ffdd3be42bc13667dec5bb8af606306a79cf2ab7ba8c4415b9e7470d0b628af49490dff8407e369a3333d092b1eb4dab47ab22b30857d1da131ce00547b01a9f2d09ac4575481b5417d86ebf5b151594289b09c4150bf4b370d0cdca7ab29d3647f5eaa48c98edc6d84ee2ef3538e70bdb91840a87b23ca38655a871825e29f894407f8a15327e7dea1a278bda914c05187b8c7797b263851acd72efe49573b3ebecf72eb8a8f753a68745564a173a03d5630971a2e79d1d8f8b12ec5b5198596311eeb5f0a7042707d17fd9f607c9c91b578e60965d7396ad16c0d738f80201ab05df77e8e5922c922e7f5cbb1a63d9e0e922dc6ed1623d4f2d80236d754a4cf1b11a100a1362e445ac97933478bbe4c0c92861ebf349c115d827c0c0a684c684e3573097ab84b703893096a185136ec1a673cb49476b3eb2d4026625abaf980f4dc101f3bddb72adfd16644ec8778ad1bdbcc5aafd4d2bc1402179168d347bd542673b29eb11f3f96edc17c997dbc3cf65cad9bd188bd7a5c5029911c06db928cdc4de5e2f10cd42de30cc10be47a76da5833e8487bb069c00b721e80e917b8c8419c946f1c7b246c6661cb9fb375274af86493f37578c8e3eca8990f07c441b1c869260adc33f601d38cc82afbb6455134a42662194986bf5eb5e4be87a93e8070de9447ca7319ce4b37fd7832766cc2d259e23a93d3e66feb21211b6ae9c662a36154f953b9c6d41f5edc2c973ef081aff8e29371699d39b5dc3e1cf30e0ca3d9789c6899b18bcd300ed28f100abd3faeb382afb71b94c14fb2486df9f267c207bc31d66f4cb88c44877bb335f54a0c9b205322477a8d71d2c6f6aad749fbd309ca826e263e19b914a6e64667608bae3d2d83368f6135f09e28e9e0c805203981fec38bbebefc03701b0b96a9ebb9afd0c55dd04dc163d2489ac3f4570bdf0d2cb342d93fd2db9ad544c57a36d8360828548211a7ad9763d7520f912bd268b8a68fc4f8d9f01ffac55d448c3b02767c515959983f2c340fc923d6057c421cc74605ef0bb588e4bb048080405007c619bc8f475d0ea53a3bf9f42d51f5686088decf8aef7b873dadf751b0b7852a8c1a811be2bbc448210f98e80a8a42cbe02449dd6993f8e65e5c560537125ffb5eda45b5d0d20d981736e600a55d29cb68f383f0d37abcf8756671e47be7b5ac50e7049840c36c7ba3ddd69a92325ec16ea444731cb651100ef1b6c9574299f393487395883a794b550349041b0a84ed8b445af1d6b4115948ea5d3e37388d058b4137a7c114aeab655d22acde520aeead9f16c40af3a3f08c4fca9f28e0c06eaab6302ea58708f14047cbf91172e90f18d945928e2a193eff109077e5d5b6eaae9a726db9b31c4f7f2dcb0a38d23bd9d838f32f831c91db5eb23500a4c37bdca5097f65138b330003f580f448a1262c9e7bf42c93be1d005f2c147372b5dd529690d54369081a15ebf77c8cc989bc7aedb57e33078e76f96021dab34c0b8ea3d60033f4b6c0c60865794db49051a950a756220bfaef66360144dc26ef2fae51e80e1d2df23192c78950d88d10ffbb1b0717049aaa5e94c44eea79b0bd5d731f0502ddee465fc9c005fe2a881408d42ed384432650eef0511f0aae6bc85b41ad7e7ca09f412f47cdd2ba21268dbdf1ce9ebc18575e187d1a0c7bd6c0677c32d618729e4ac6e9db6aa82f2e4d167d0ca5874b70dbce09c48348fbbc35e0e01b508b81bd717ce05d5f29c55154043b71851b7b5e57de28504ccb0a7b39318fb5ea5a4aa6313f34ff3e4b9556108d862ed618f0c929cec952e270911dd8000e2473ae1e8bbb49f3d1a0a9527438cf52b446e9ed9362a9493da45a778fb11d9ccdd55d02c94d80d50c4e7c9189c58e309b930baf6b29fbce84639a693c8f8416222bb9891e80f25c5ffa20cbf756e724062fa9ceda61407c14c54e226996cbbbb02d0c254653ceb272b47c84b95f38a716f65c191b1f31ff403cea4361d1091c9fa40660e859e1f435d4c1b2c86d3e83f9df99d06878e4dd9f98c6ada680f72caee37c85bfa4890aea081b79840d311100e8125435b49e4539ccb86be88595f21d9b49f280818a8c40471461a346841e3a3d0068d750340258ac70579e413e4a11b09a58d2a49e73332f408b989d42d543657b4575fd5151198194ad48ebc986b2083bc3bf97528e6f124681ededa0e4c7768d6724bd34ddb4f4e2bdaccc74a50b34b87af715996f705f2f27d317eae7f498794cfb7c8ab076e7968ee9007bf46d6ad1ba8e95d84348df37b16c56eb6f978451f46f5ce3feba48367a95757a3b8548a5b54fa42a0db71e8b18cc0cf011d2a7ac4c62b6a187408809c2d8128a2b02e59e5b200361fd92b725365c4f3c3a726290f64a7c2ab3d1235a3b022052681192644a61753fe57659dd76d5c2e30356e33d9041fc266ce2afe42e4518846402ed09c532a08bf2df1722b68f58ba0f026fccd44a201d176cd666526c876d008178dfedf572635f08ccc516c61dfbcf78da5422b115db2ab6a8b1099525e97eee0a9cb605ba51ce156f2d572443d6a337d253754abef0b513e7d50fe029eef4d8364f61de836f6e792878365792b13f82004a564fe4284783d80b2ffb5009c46c7a9f5b16481e66a52447467b708184b577e87607f29af9573f593202506e67402273163a9032eddb56de55ae5a0ba03ba6c0b875ea05b87447cbe4020967e83947c5919aa230100e7f79edb78261d82bf28d6f008626ea6c7342597ce7c9758e3a35059f087ba524178025b1bd75bbb74b0c02e23604ae734313fb331b123ced867b984c532b3d7429f0820337fd3a3118a1f8b6c3a3c527a51c7fe088c263c3b52e802b40dea2c904e9fc3011ae0a9cf6eb390c532b58780e707dcdc4cb6107487504d93fac5bc4e0becc9c145d79c2f9bed7703f5f80700388d71997856111ae9498119b37947ea1c52a2bb573ad6917ca2da95a22c2d50e840956c766864f1ac448c2d57847114ca8275cdd2d78705238658942a59e96242e358943383ddae366a2340a56c3f5a90860a57ce86464350d90520704556f8302b81487fd40a0e9378bf3f0839d916abc62eb740fc5d2dbdd50577e54e660557240c904a95b8524c08fa6c230e634466221014edc0d779116cbe4775ec295ac55dc5b4da871c8d390d53ff32e404d56aa19f08b486be514001fe993420bb9eab30602fa1161e02413cbae31cc7cf7289b65c73d4d128ca3d641a9a09ac70ce1f697bce6297b52cbd51d459406a9882a66a34c202d053fb82d2f72ac4cbd83321b905098ffbfff09e8b7483edd1526e5dac03654fb186c6f86caf03a72f63d3b877d7010ece6ea9eb724053f36bf0c2610354c493bfd588098a3955efb4e7926343eb8006d8be9b3cf725819027a3edb7817f8ec54c8cc5efb239db9d72cb0b464ba83c27687bbb6b25c668ba84cae06ee2e37cf1a6fa2b2ae5662285ad05e2a721ed3fb64f9580268f7f4426ae2f3fc4be7e157e35d0fd96038df7c86c663a0a56bc20ad7123b650652a05027c98176f17acc45c3e51995211a228bbe9f6aee72af5c670042afc45c90c16429baa804f299f02e2c31318936281497e2817f2906df3913c24b30d1f997c2389a152a9681ed67250641b09aae81a00fb090675469b3ec43ded088f4ee1095affe1d8220fbe5a62779e1eae1ea08bb508c48be0a513b9fc403fc102a04669bc18bd26054f560060f1622784b079125290b345923a081996f63483d494bf3508fa4754b60d80406a22783f4e9449490ae814513f5af704252efe778e5045ac12a480acd29cbacb74d8fca5675054642860007b6327405b926e61ad8c013882419a2e425f2341740641ff7538b23276fe5ee849b579369415cd7a5d209654e0f09d357117ef93233a74591326b877c777acddf2d2bf9ca4d9d4f3ee5e63f927439ff278956213e2b6f329f87e53f59c5d16c10dcc179d993623d8eda72cb0847beae9b5c8d944f9a48a44e922b1c3cb0cc191ff9a94dcbdd99fed1301bb8c7097a544c0e68dc1d573ff70fe99827ce272350f7d1ffda514e992117f3f179b4dc16f9b702d6310bc9d53863d89289d9fe20c445d7acec374b8dcc7d5fb14aba4276b40aa452dacaa83886cfc980b033c10542f186b70cdc3734b4d29c7cbd9ef9969e5a5eee2d66e65d609caa6c2ecbbb197d438c48e4c098098b77f3142f4c16e938c2d663cf5ad0a2b3126f12f3e5fc8363b45b6bd7f2e01541d1675f4ba3a7c3eddf5f190a0f4c3100df18a6313a02819eeb76a787e6586c60d53e3c65b6d1180fc939cec4f707a2ccb6d21bb373f7376c7afd5801568cd873efa2d7e7225cfabfb59ecf87549572d19b6022552609d9c9cc378d439f427cd38b840c888181301acc9be6c3682076abf99ff4050863ff1445ede4c918734121466c9b259f90ad5309180edb1e8931c80860c127befb29c49a67a11173b0830b5b433b78ddb8ad23be79d685434eb1a86cfa21b18634a9ff4fecb03f81b70b4e96432021d7385b5e172815bb711dfae6c3f850936f3e5a12582f99952dd9aa6341f35eb5986258060c1b65dffce0043ba63c99f08675c9f9a155b6e0e32a29c34dc0107ca6db0968665daeab4ac3be490264717917e6c02dfa6ba03634a868a6e1a7f864d8572e26875b0a0ed0d1c618310586e4ae2b51f15d9277464dac4830f317f7de522081f8696169d682ec09a72c005940c7bdcd7ccc952a8b250c37615443f8b26fc954b515649112816e31f43a7497f7205fcfd5c7072facda319358285930c7f8a511f9b5639993e8f22aff19eb07c03a8d83fb1db9f7a0494b3189751540b24a45f5383fe6b5dfebf51c994bdce87a24b0a6ce001429805453d750a514597f1737bd5354be8f4e2838eb14a8bad3a2e71234be45392635f4623b8db1f1ee46ca92ad02ebbeec3f527442cdcbe9f5f22a54f2a6096515fa0d49f21d1833e987084ff9fc3fb5e7577da5438af1d51428704f3e038a03d32fc9c760cbec31d5ce0617284876366c5e49cbfa22194822eb85dc2f49396c05929ecb7f38ca8cb6c82c9acdd9a88fe176655b509b06e9a3fe84d8cd8cf38af82b2045514bc7254935e110ca6293349fa8527d9abc116d8402b2ed9d19baf98253f5e2e8f4e16bab60b926a68caa07e598982ff6b970fbc52de89781b1560d10061f26edcd35398971e909bfa23f09ef046356624a77d86b1666ba0c4d5279165a277c9b3a11f7fe41cb5281933c1acb6380136d2ad845469ad00e9dd23c4178cb82b8d6ce7351148626488dafadbaa8cbce854f816166b6aa89c5bdfd3b94a6f976849c534beab5d56c2d50bab6cf2deabe530b540e439a6d25ba6986e0241784682ca2999effe75d14a5293f4dbac7c7b6d226f483d9927cfc84ad9e2a873a023649b331e33c40aa91aa67f6f65b42edd9674e8a2b3e2174400be66771333109974ff4f01118bfd1257366a2e3a5131136c1004c1d42adc0b95c200a36685b82fb7e07c7be7d04212096f3a44910ceb50441675ffbdd6c9c91b02b1dae8807174f1ecd3fcabc51dbce96caa02a4115bc539f1644b81307b7b9c7d39dc1d8b042759d2e5bd3ed3cb3b63ecda5065a1acd2b8863c14fd715719283dc1817a05515335770468b81281164ecef8fe89fe4a405cd11948a4dede29759052c7c0910c60d8c3c46a5411d314d8c21fb5e908fcced65819d847688a0cb9f803b82740929c71a7e90c09586d06d5122c6cf4b6b0d1f0ecf1c68ad73eee0fafc357390ba657beece9b4501921a1a70c513afb56f0424013e44955027084e959b107f43d4d893795dc03f3bb9a38ecabb4ce1d0bc86dce5a92ba7f5d1355aeede5cfa5ec85860b756d678ea339dcde1a0f8ed423b2ea4296a3018843d568c123f9e7ded6ee752d7186a9f18841fbb42d7973a6fdf4db4e64a3b365d69f539f1e8e8e29910ef385ac6ada618a0617e09691fbf5919464e233c9a0ee11083f18338d6b823fc44b21a16882dd1a4390220b7a04655fec7818e8d0bdf3ee091cdc5eda8032b70b8c6b0f82247abcfe00cb8c97feafacae59770c4ea99f9de71bfdd398100c205ecc027172af84bce6fd68d687c7d389ee2320a37d2bd1863437e9ccb1ea4035c4ee880043ba50d9c54125ca623449c7d140eb6ad1c4b349a5aafc460e91f4191ca5675b5b67c863b01f2a6aaa604e3b02a7f8917f0667e21fb9296cc72f54d757aa8b4b550dd3e79c5486603b3955455c46cf0cd5e64e480ad96f2c972fe7248ca234536914a22ad320a15d04ac2f4e7b7a74b967be3b4e31c5ff84a264df2bec645c937b2231db5b348ce54f87353495e1f93455516ab6df0cacf6675051b9d9f08d9145cfa7991663c636d75691358ef9edaa5b6d1735c53f4d2db06b2354939a9a08ef59de6a16b074d7a3b094af933a6c98c2660ba030b49077ec9e34895a1b13447169a12cb51ab0f1dd0ccd2ce1d80d550748b9ac848e6012556b02458ede6cccb57c040cb189db9a460da342e957210e174b9ea26adb6678447702f814f83e73877dec99cf464aadaa09be1e25d279a4651b3e6290195aea2709bf93c1a9c7efdfa796229c19a9eaab8e8eddfeccb0882d4f751e40b901ca5caa637d6fe140020decc19f34d2dfda451955bd9f07e45472422b645afeb4a0b3a07869437ffa88d034fd0eb3a4470f363de8ad6152c6d84eb8f56214642940159e48c0e6b891553d6b5da41d25e7773a7e8372aaa1668adc8dd099cd5b103e8dbffbc20d394da024bef90304310fed5c1b2cb1296cd657051a686c8b944c725fbcb2eeccb561ef38074d190bb927ddfdf0a882b6213ec540e34cbd05d80d0ec0abbdd611f934c674003c388208d929de5578b3fafab7a22e15c39c2a08d362c0a99d44f8f7da4e9e54b0e5e256558192694f92e42a9a40747c286cbcebfccefad87ac7c24c896c6d36fda0a8416a46f179e2dde9b0de8b116c85cd5769986b661de942c3b0c70be15db4b3b642fa6ec578b1748b8dcc41ce0f5b36ad37c2efc71de1b34ee6c0419ccca13b6e93d7a6185a9e60427d2f6fdf9f8456b7638c3412d6114a160832e134583d6d62d834f96747a77b725b564ccac8b4a9e8ff9ada9d6f0b39bae0008b41f5012b2f132362684e94e925de70c6b6940a47d7c024b1273d0e004f440c27c9c0b0162a731be2ef5501897d1b20221f33d164d950e7fdb8a2b31e1cd6dfd84cec3e8a8c2bfb07d841596ad402d3a0db80b7f0947e8cd6cc4ae9a85c00c432ddcf81d45b28300e67be12e92820e37610595cde06cb05eab08496b1092b9c00a50b1fa2204a439ef246f387056937fe06dfb6b5f76c0609a1d740b05c05b8b059f110d20425e08462dc54ff19170225606cf858a1d3e40688829cc062de3a7d96017dca07f6a0aff4a70ecd71493253f511155e1c8efeb903200a1814d2e1bb9a5bc52e30981a4a4323c26ded336194cf305190ad2b2649868e6fe49b2c829875c599e7020045a30d27bd8ec001b5e92c5501967f7fe3ac958cfcb1b86f97132831f16f9cc37efb2fc7e7565b22e4829e9ed1b468619d9c6c3028550f6f42bd3b02132e6c233098b9d67171d0c7d2da9f37dfe3259e275696ba4cd38aac122e4b89a3699277434964e57f8e854a0b3d34334c09cffbc425d8666f2071b39afd4b1cba1877383a68157c1b3ce96078fec651fa494ba21e8b6c8c4fa18b4741dcdf455d879335f262bba385eb6d606df634a7a17063b5929ba85228665d5701eed849aac0c4554b30204be661839cb75cca398acbc1fef3f246335b390824c2141d9375fafd3e4a7a32f2f54ef1190746c3a1d09d92641879628e780478f114880a9d44595dd7cceaa187b73d9b219d34dcd63d525213d10cb98f26c7e433c9361198b3ab49404f74f91ac49a7eb14aaab2b2af16316efaaa80cac315ba94b6151585131b5388b1cfbcc029cae4fda48afefbb0f80250cd60abceb8295153eece553f847f4f0f0727071ce67c4d768748b84ce3c4e6d3f3b62a659b15d3d5dd6b0782762c12288492024f5b459bc2cdd3c1dc823f25e523cf8e9b8a418c809238238cb5bab235a2afd0f30c6acad971469e07889cbb99af04c7a9c88a21cc00b043b6187164dbf7a46ac73c53647e108b9ef649bc88c93e26e82ed6b51cd2662257e5038fc3f570b110347e8378a4530adb6eb494f59bee768395091d84d2fd026fffdf1b5dee751c4d3180cd64d56fc7e7b110f1ae551ac9006a8ae416236790679c5fc300ca4640e637e4f2ff2b028c6947bdeeecc3b7b4f67423502123f8343102509132cca1bcc80208d769289a75b18f185e8ef93dd6d54b38f4a885051f4c298fed451650da4056e04ff37e2916d86944e6387fa8f6548d372eec1516ef41bf48fa383ad5aa128d31785e306181a25dacc3418e15aeda3743f0d4ba7739abee922efac687314933eb20d593d9863988672cdfb5a9c8d7acf42a1776ecbaaddeeb809557f8d8265e6c462c2521a6c70cd1c9c414e244a27b2f8cae7ad091f10fdfd355259986a092fdc58e59d505871a9efef41a5dbf7e4fdfcc481f7d876af7dd19223694041ff96a8b2e829bc0cec72a9c19f08675becedd73e6732e9356f7a539f34d29bc76e6ad7da8be60ba4ea9d543b1ad93c598c154f567a95ebc72f789d317d842bffca84fbb7a6a9ca0c56a0afdad0fe73999faaf45398b0cc064205ec5c413d67108f9da7791ad27086be78924569ce78a81ff379294a65c035f4536b94ed1f25980bbf111f208b85cb190ee49b96c0b36c0787b55cc7330016b4e6abc098ba7100cf4d1842d4aa0b91a60913574df559d6affcdb9690280df77396e1d981489a4e34a8e96782ad2f23110a19e7a75d681e4c66169230fd2d99a2cea374c628f8cbb3dfbf6aa7ea89e2908374648e51be4bd94d2480601b1ba44e898ab68e26e8497bee416119061a84d5318f40940dd0ded80e8c72bd1ce6a543a58de0a6f10196981137c656daf68f9ef471dc4067e9cd7cbe1c5cd7606bc02f4bd1b5e814f194ef488e5fe34fb04adabe17515f2e610b9d7b1bdb95ecaee2a2e1ae10140e385a6da240f84b198e2e17ad31e29eba4d7e2a95d367e274ea80d1f579c7ee0ed8d8eb5ab080f4e96f005c18740664afdc7a614fe0c51dbb8ce3373391ac9fd839c415e14d2c8804b817d0a40906427edfd20038848b63e476d2400c0716bdfa974bd4573197f7cc4f530e62cc8c1eae348a1e1d6159720545f313081c0818ed522746277cd61ac14698ddfc9e9a8bcef9a2ffc2ca2e19c0c2188d9a09c3bb140a38d0ecf2d3e7cf84bb0bb86ec6a4737dce4a2e0e728eb2c28b7ace525158eec2e664a17c5cbf2527d96ed3fc19004148aad558d33236ee9e344cc9dabe9e664dd2faecf745503e6b9adf951c7290a47e9e2b4a7e8a5445b0da33c43a411f130d790fac5b9294abdaf1e354babb09f8f5552ddbe016523e8db52b8b214107a72e5b50a1cc66601bc5fa953c2df98300cce00d97cbe352358ba2bdb4d433157e983e89fe06465f6c8319b6e5fe98e273303a34ccf43057f7922e35b0a0132aae9b600b83a70b435ded87056905d4fcc7699c86a72e5dfa815a3b7bda06f22ddd4a03495bb870f7c321627f514a14342730f2e676e49ba66762a7f7d86a66739e3ddbe698951033bd2a66a61129cde2b45818adcf45b6fb2b83e73c2e464ee806e23d09814dbe54d27a38fd8beaaa8c25a2b2608289dd91154413719c84ed8345f5330afbebc3cafd1e40932150a39fb29797e58129eda37d15c82ecb82ab485519f46f53153fa63c60fcf3540b6c5986235a486521b0752a37fc75002dbd821d897b0f33d0dc70bac820cc7290d3001d81aa798fb0920f00743160c150c19445f15aec6a6446b00137a42d02464878ad8a43f8b8929a9d12856980ac40796fd800fa3a6c857233de9829a9e4abee1146de5f67c93e1e63ac6dadb899d053c0fe9ad0469f93572d03f739e0006ed229cc479d21f14ac06b1fa1b0b5441c7d115fee39437fb4323792cdfa29fbe20e1fe3b2cfefc50a3b232cd0e35d3ae18ff520bc8b1a0c8562de909884913b1e86e24884ee16cfb08f40203e9c786228b1d8c5a9ffde81362d0c72d306f596f0487136e7bdc28c14ce84998fa3e7aedff16c77d0897ebd7ebf9942c47f862f52dbbd9e2cc16fe714f6327e9336a67eb5eec44327a936da8f13c8b94ce8970d7366844401986978d8be13821bd951f08e16263e5ac6a6b02b03b013748a58ee7401dc4aea45e4a786e193d6e91c0e2976c679eaba839606e98e99eeb243f97e40f0d0090624d69097525d9599d2015db0d3879498c91df93846236e462e016e8e71d34f09c2bb7c0a81a7206d96650279d4e5eda9072edeb11297f89623e5143777edf76b89351aebc522e430b2e7ebe901c07ca2adc383b6f35538a03fa8e002ca0c82864b5a423a0acc063e5dbb7f2dae2f43d59bc8e28d6f6ac097b2698404025408ccab21505d7c68103dbacf0bad6f95325fdfbfafd0e04efab7365b6bb9dd86c70042907e7ffea2bd8dca688648ea655fc80a2d8dfa57b07f3ea44c713681fe609ab3d6b9ac9e21b2a5766c4c95158ee803d16e0467e33aa5703a06e36d83655d653ccdbf730a3a5e8bc3534a6719087c4045966722540670363371a68c3ab8077a86093912e6a721672871c511b282b3115c148452288f27af05db470815d5f64af0d646189903546be0d58ce144f849ed25d07dac47ef16134e40d3a9e234f1ee2579f6b3fddc5bd57d188233bdb8da6b9cb297279017a59820dc6a3823597c63efc9c93ef5d11a53acff5ebd224c66414ceb77329def0d6770e216e271473ac5a893013ce326f4f58c0e1c1ef8fe0eacb9e92c1dd17ab50dc7e0dabac64ecbb89725777bfa569bfe39924be2946d817881e9811f58e6a2d1f099e37f23b3dde9b33ca7d0f50227f4c30264668b572c43837aa17f7d6e33618c25dd1b911fa7637ac021a193e7bccc24ad6353632332bcda69e3b5525470fdef3bc747ccf36c40e83aa32ba2425b78d0ee0a1eb993505474e3f7dac126fc197aaa53334db49f89954ffd210f261ef35d0ccc90264c24242962a058e97a4f4f2c33f4ab75c87ea47082b25ab73d939933ade37296339a671bfbb808691c3a406e0c369cc2dd1200f4b74dbfccd9e15752c1a5771df1163cf6a0952324d81b8d8c49ac77fa9394417bb0392af68f58ff9644702beabbd53af7e21a6a995ab174757e20fa6f2c807eb2ddfca6d1300f0049bd0cfed7003dfeef487a88d62f7df133db0d83a3ccec029b825f735af6a20ff856466d2cba25a1504b734c260f4e331e223e2908d9c918ca5d5c010d82c9448d8f5062afa8778293de2cee76af75b8ec811a8d6816814af76ecc45c26128c76c6d823acefe7c12e8c7700a7003b0547bb7aaf0e27750ce9f5fd892f7c4ed84d7fa93b6cb137dcb74533ece373d9a7114c3348658ed8ac6e2d26000bb833b3a7a462813d658b26d69b5e64f0bac2b3c7e6041aa48a94b7356c9532d33891870f1c88151e02b09a00ed3337da911bbd5e3d79ba7b80cba724ba6cf021dcba7192dc8a7d16995054b4de83bf677b10580c3466d64a1edfcacffb241b20012fb21b5025f3ebd08db976c117cea9a0b9b3611c03011c9e371b7d38976b788b59acf9ba46e7345be6753e722f3ccd4246af0d2ae098a5c9901baa3cf8c4264dade498fc6c4460ce7cee37861c2dd109ca1793c29e99dea321e882729ac39b46ee3953a763e330c0b18710b78f9ec836d7b61b24bacfcd86d6aecce1f3e5a808b1a1a1978df5e6651ad22f3da2e2f1442e9032d74e1c49b2cb132c5663e36736bd3b5e2033eb9289e3f3a3a3a0348370c39fd536c1d37ca400924c40b5e421f61c41314d8efef3581404ea889f05ec11b1e58c566d76f345df5b12dd05f50e7cf213e78a579848d679640dd1b52a2e600ef33f389cb9e689fd15b8c5e98f08aed44385244f7194edd69f77704a5b7d128ddd50af797653ce028b34d00dd74a3a22591bee8cec69008439a162ca222f09678b59ac64615960b71cab181c5a4d803db4b49d47268195f0b9525d8dda107ffddb9cd5fa8a60cd88f8d25fdb2145a15a678c59f26b2b421cc9a42b6bffefb01f80b8d5add471559e851b52d7e5e773dcd07475511b92c75617473eb1542f0db12fb5a783b72120e29ea6d6b6eab847ce2acc13867b4f6440a7466521fabe5858ba2279b5a161e85fb9888ec04727c1bdea0dcdaca75ec8c75183f29c8a4545e19c6d5928f6f79d5f52b396da9778f48be4d768dd596982de86fa0f3c72b0b77bcf76bf05e0628c7e0e1b87447b16c7ef42f333e06f1bba1be2aff400168bc643e87a0289ce24acd3c1e88d0d8de03afc77f8c4192768f8115e3e557b41a3365a7d68f89b45a54b34420afeb9b35c5c9b089ea077b423a821ed7a0d4363c8d9630a0bb68efd8e8e620bf1c535b5e9121ca1f2a90b82e98455744e36f77a354a11cf0d27f5ce9989f166269bdd5de159b90e7f08b8396e8c19ceac70a3b818d0162888d587bb50d77b145317c6c73d318dd98448203fad5b26dd1378f2216fc5a0e6dfc99158dc17fa04892d1f5f941071cde32d7e61b06b194e1e65a1892bbc8fd7e51a715f81f7037a4d0ded944c297fdbed30c54f63f193c160bf10b1bc2bc08a47b0c15b78c6f57cf3ddf6000ec82a8e0654521e206710022d8d104a5481fb98c02485c077aaf08a3bd19a8645a2558666960fe7653066b464ab5a977d46e1acc985f7476a38025eb60b2d8b351b669a52bb2f9a87ad4a519f44749904505f28aec526371c6fc23997a16df01d038a125ce9afe26a725550dba4a50abf42590660170a4ad0c7b920ca9dfab1015caa806ba882b4299b373e395d37fde840238bc93e99e43d5300867011e277164c6c52a6e9d34f05a4cbf9499ebdb28a0be666413e5de59fc2dad7fb67b8f8062c4954513aed64b54441e3d470d89b838bd5bf3eb6eda09ca7c3321a72af850f87f6952a3b3e89a6c4aa99bec64b8f13400a07ce24450c3db67660e51e30f5cdd21ae749125a9f4174a190127ce9fa432058cee57a65fd9109d34bdad873d74a5513bd85a4e9e35039045fb1014e64fdd156dc5349578d518107a117121154675f87122f5c6dfc9ab3c66c2df251035d3a487b4c8eb2d37e15149c5b308ee7998aab643f7f956708fd2a871223c36ac488a423994509a0bc6e98b5e6efb49b36f777aee49b31c978e72d2948050ebb58a2fee4050214e9e3907fc19945876e0d4b859cc7ae0e53bfc1c4f8361ba4800983457a2e3e34b9ad9b869fb555b379dd76caedcd081851abd9912ebd8c4169b8c16a3246cca927356b4489d6818371e089b2efa43b725e5c7ad80d309a0b3ae368ddcc706fd565291336453a7451d0e552e073bbcca84fa5b4bca2180fef0f19d606e09260381c19b2554250708b187ec747410ef60253f0970cd862afa80a4c6dfb78187728826517194d39da2addcfa22f3f2cca5c826f3bab5c08f01d15615e8f356596c1cb830cbb578e98510498bfa6b211251371f0c4a9b5596c043f2e05fa7b818029fbe9696f88cee40b2540f23ecfd1e40b0bc619546ca3b4c9cd0bb4079b42dd817a0781335f5007a5ea7fc2b6345b7ddd976479cd75e1d985afb3d811ddaa879ba976e39999028573df657f010ab03e0c189ec34b19798b4d97b4826722497c17ba3fb731db9c38574c0edfe8363e397168954e2aa1dbd280de906540b76b72cda5462fac6a6c7b518a458b8683e280cc58b0da50ffa9b63a02742c11c504543382ecb8d280908ce68f0432fcf51e66690ec8cc56211aeca18bd4eddacd326f571f1cea18a83fae30b0103877a362e2a4d54a2803873fad118b4a97779e424776c18b8b32d363bd36ba493efdec1d27ad68cf0a1b70b3678ac145883eebb3425c912367016c2df5646067d8b0a94255d97826a612727793e9b30fda053031624f36e2017bf2385364c19b7cca7dd56ea7c2b9f174aa552e2da24a0ce87da824640612822a8afe486fc2d88e3ab85901860670c394f08dbfa252753d6ef032dcd0a60cfe13801d180ecb1192a975cc69a96ac428b09bc5eb25013472f8518253a54f8c40c8cd1bf7475fbaf17e521a45c854c582490a5cf493373054d1b9c3602131e652b35c635c2f3f5fddc46dc4eb07c8f723e9b9ad3b03120acea57ae9a0843db33473105ff12c2af67d757dc9e18fdbf644fed9f3b788e8885626a5bb4564eccd55a1332658f190097c2a90eee745fcea4099619ece5ccea86ea8b884b8012054a5118d9ab4043614a5a9685964187af7b83731c2e7c6a85efbac99992e6a6cfd966a5f8e85ef67ce65c0ef192bc9186017a46a4315682522dfd9eba3f332b838a577e2c1f93fb3b3c80692084dd2b9d596812e58849857bb961bc04e378c947bd648216e05d2ffb35fab09e46865bd2684ddce3100b15c8ab359d21172a44cc9135b9897a3262e9522103ee1322a615bea1b45e2edaf8f7c1b5f3befcb6ff967da9c0c431425cc3d640d342230ee819a7a78999dd0f80414c51bf5d1b8c410c1f5833fc17278e7c0fc868ca19e603c71373cb72c70c32b09214750e6310d335a7e0641aba10f0330631f4472c33e8b25591abce987b91d859e48999276d8da804a7331ee1d32980f7b1319c21b5ab9b66b841678c20de7e80acd39f0e736e0c70605a607369b80c75859f07c76f4e0591c9c3041903ac46910b0a2dff31c7c15115793629033f7976332abf6823585c19d4ffad3072f36a9d4cb83ae924a4a27eeb0a643f6abb4cbb57ed83ac32571cf2ceff7a2f91debfe64ebb88e8afc56df66ead9972301cdab501b1eddea2d9d54245d78197990b5f275da57942ad2ae5744bc0f6bed10969e0f8ffedf0b2cb1830b61a610b43688b038c0dce251ccb6caa31338e7ae8bb73658dfd8c8ccdfb770b62f484dcb53f33ba7ca817ece6279e02e438f4cbd4bbaf422b292d1d1fdb03dfd436f61e02330437b98ed7f56617d12a00bd88d2c19b17bbb4965fa51af48075770ff53c99798bde5fc6c1cb0d288d8cb6f5ab85533b006287a6e99c5bf72e12012160593f87609f4e12ffa2159466e509304a93ea939e2ef8eb4c5be5ac0e3cf66eb63b29b2f3dfddb0fbd0c308b3b2f35bb5e41f0efe582e90d1501f80b9348d30f479356bd30f471bcf7a4f4050496d07de73e1f25fdd2b4f81f46391651eb69d9e9edba99acc086a5df8fad21a33f51f7f56f35c4aebc0fc99c2dc375181958e8c8511c7a542ae09eec7ec4bd5a151fbabedb11dbc9266e55ddd69c662e78fec9d4b6c66b67c173a8371b99e3a5bf9bdae71125734096e343915a2b5bd7d95e811e6b26894ca4ccee0eb212696261144068e1a60d0f41d20235c990bea0941fe6a0612311169ff105b225842b18efc57f519d2ebfa7ebe73d04be081344d6241c2261f7dd7cc74a9000cb60c2d68fd8f82fb0ed2dedd0582bb0c43aca8b68733dccb621e0fc593856e72617d46546503aa23388d5eb875bdfce44ec3c0451880ea18dab7f8224eecb9948f950fe029ba6898cca427dac03549ef6e9c7ddad7610b36ee3441da11cae9f5c1cca05c59313d459908c8352ba161de59c178288768ef89b28a11218f9cbbc9e1d9796832ab1a775e0e467619820076350bc4ea461a14575017dc82d5bca2a3aab61be2a6e2ec4ba08e0fbc615946380750c8f92e001b64dcf683940540e51ec9c37ec3cafe07ccaeb661bf2442215c29f6656ddee3d33bccc33002b761fae75c594e8b0a70fb57fbb2644183d536b69497c21a16411cf686ea2434688ef571806499316c472266aafcfae29aea7018f327e630a5831c0a1810b69eeb12e1252761b82f22c863e4d912960beec4766fba14fbd4ca322e9704d3e0b14caf5ae0ee65e790091c3a03b6d9a7a253a789f88765159adf42fe0e29130052b79dadc81c7d2cae0b4046f4998ee281b20b40b9e01982e037bc9663a8a979e54bc9a103f393a27571d88c9e5c4d349fdebc7f2d136e41663455ac90a940f9b691d164fa981027313e2a0f28e255cddc3a0b7715381df305a43e3af07af597749dbfe897a95d00e5aa0ce39140a65a58941143b1b10844239d0c05becaa457d9ec92a73ef2c4577e1de8b367fdf724669f34f78384f9d8d7391184540eb5e7317d1f920bf101022d92fa12a171a8139a41138b96a69d7bf9a989c3582d371c96c39cfa6893b68a29f7baba94e43b01e54215547adb3e9d53af2d633d040d08fd6aedad7b180f40edccbc6d41c93416a78f9c6c3b40e874281d92b1db86e27eca8c71c4beb1ad894c3e5f967dbdfeb2c8425e16d69577f783711291655ce0297a7cc155953082a1c7c6f09d2101c379eac6ca3294db464a62783a1d0343ab59a03fd36d9c340d6c0b05e567bcc9659f9e32424386b6f780c203cb99f35a07f182a1fd34a4ca75a943f082c8e6db3789184c2b9b2d0063df97ef88a9f4d724c80f236d6b0cd070c22426c239735756e8bb122a9d5cc6292db096d8713546a0e81fe89bdee5a92e77f4586e751f1049243c7b8321839e99fff530a42c95d5c1a19ce0291578cf1c85170d3afa4d1f0495ca0d7afff58d39f244c646d9b9b24307495c15db30beff4a24270df466fb657d2572e4df73e969261f339c9cdf7f9536cab1259a62599bfee58f4232835214ab05a1d922a44022a2de7fc9d0fbc61acaf7e2af2db001504a53bfff727d58cab4927c72f02f629a93fcf05fe0ef124c4d0aa3df745401632e562c5a4c1e1b461d4a2dccd4c59020f812fc9763e7944606d89f0752d2c6490ed1e7af89f8f1bfa62a7f0d3374e22893cf2244a605f8a0f27433b1912103a14c88c1d49af1fff2882153476ffa1f1394822ab5aa9920636316c3831991b039aa1c74b60b00ff801dfb15fe0b48ae939ed54476058d58cf5a6f2a38fed1095aff8db9a467111eaef6ed4837baa4315b22a36321ac119c378c307588e10656a508529ee4cbeb21e2cae3630c644bd9d14d60909ea0191d15fb62012d95e8a32ec6ae680e1c20024d89e31b217c28f8880ccf2d4ec984822671c982d16e7240f39572c8bf93b9b172ef72aafa9d9343856746e0d84d6842eb228e6254928f1c29b39282ff71e1bda201f697eb99e74f0575b44c8d1eada7aa9ef90b3412b9f8180985bafe74580494d0ea01eef1a84403ec0396c2555036c2fc7f8e719211a973e3a73f7a2a41bf496bff7c8cce6d68beeca32c0580ca5258e032e94a12b09e542d6540bd32a4f6694a4c908bc39c459b68911fef8baa08aa379a3b8bc3a543037e188e71e913c9c9fbd4ee20578fed8ff3523a1b45095083401faf22528097f3b6b81b4568ee5e9f49bb3b03b43e33d79870346d23cce8c4f417ef747e47b75f6072d4f3add246c263ff84e15c315ccaa4888c1360c4061bae7d9383b0ba892b0a77446c1d4fe0a2708aecb586486af46a58bf5a8ded8d1a2903c48ad8b44e58a90ee7ecbd930e84262a0c55014397367db34d85ccd02f5b4929053e41f034302765101ca4f99cc1259187d4f77b94ace08cbcd9c15cd71aed89a66ad879596641755ba89db638a47cca97415721480d1da0ca1ef1d44adc92cacfdddeb0b5ac2840f55f94478242f037815c25bde9a1a02871a729ab70975b803d3139dd5318b7a25fef810e66f21242d4abe759282e70df728527822b7493e10f5c4fe18b8428012e3eeb2478a8982ca17d882145b5b1c80d6618a5c7d052480812eaf7ca25274e1dbac444f842d4753a511760cb778455a2179491373706c78b943540f744ee4efc4d72ecb02a63408e232aa5f39c8c22254afe8e50a54719c164f4524e19266995fd0b2d8862618ac3f67e216ff42f543f5dfd8d201fd5a9f1f01a644c91ad2829a9c7d7d00868112510c0d2dc0d6355fe759598525e18ef8c8f35f000b59d4baafaf705aed3d933d472fef6ca062073e64ddc0706743eb8861ad6680b94818387cc58d1f2cfa50c1d0a69cc69580d5817fce9b46134327649302630ffa4cb2b452bc6fcc3a62a098c5e700d86d1a650c7130a152792eb6938331f2374ac043e15e11295a332d4dd544d8690aa0069648a3ac68358ea67dc8ef406758ae5e2474fbaf8a247979e8d769fdbb97e680bbb9ddc1240f52dfd779f7b0d980c2f9bbe6c680b4e63b1c06b3c4ca38631f78a1b0344e2e9424532dfa953f448f32d6d1e169b6f7b4f34b68f7ecad42bee7ab2286345ea167bba68c31c2b5ee2d8c863f26ad773e0ef02d1e93a29e86b3c0d7f95ecab4e8cc70d1e779581a12720218557393c53ea0a79b2243f698c8fcbc9932d34b46f8bcd8eb8ae4012a2e48de58fafa4bb486a0ecae1d390f3dedfbedad0217b5aa67d592c2452b5f4ac88cad1b6b18ea15944f3c5444037e36a96a80f8c45be88d4f95cddb6d2920d05585e5881aa7f290812e0b1893617d677f2544986aae310b9a0b4733d903881b7a61a4c1a24d5c596d920c726cabfd27600ce2ee9f1f9b2ba5d782a3eeefb31527943768596f0fad1bb0fba0afba295aaccea9331e6421c74dbaede32631189730b13f4f469f89723414075d7a73ba8d3b2d343330688d3cdb259c8af256be892828c90aabad0fbe06be449e90d52f1d3462980e750fa3d16bf6411a31595ff5225828bfca15a7f5c2a79cc5a048fbebb7c5efa381bb4f01c8edb6a85fedbab64541c4f102f0fd23caa5d0b336d577bbd197ecedd8e3df6ae1636b9098859b17497ef325e0c257999ee22cda16b3a31a5fd48c5efde2ee7ba39dc3389df68b3a315654ce52a222fe771ea65db4887197ef33c20c6ae9ca0fac618456b540d2138002f65713603b18428de660a77b0181ae65d24e26d7c9a9314be9fd7a20c586d1be70349a54f582bb47b2fe2646ae951f3662667595f51e367da921a1f836cd56f1859beca2e5568eb756af44e85554150687fa020fc23514966a09195c88fdc1a651da0f565b8039cb6da1d89538ac017d038277312b9c5a2a1048498d360b804719a83aa07e7dfda36b401a87571fc8ae5c958b80bed8dc2505c42e50e48489b18465f709ce377439c17119451a80b53a3f37948b5512bb415af2a16f1dcf5490b04c123b732359d44d20be216dab80d0d2979050696702685b6c7284f0b6d14bb05ff3614726833912dcb1068c9eb566f0a0a6d9dace7c6aac91322f9ea4281a1fd89a5a193d32abe5d08d45de3f706cba2946ba93df08dad7137fe393b92d500d122749b0122386f3f737a92a648f5f9faa2d026ad9e0773e032f98dd593a1fd0b21d6d3b3195c9e33ba2b012e20a1c818ce1b0066a14d2d034415da9c809d2591d578d92a8350b63ff868b8488b00ac0b76535a63f11296fd0c6d2d52cb2c5cfcf0a19d0ded2babf3605d14c7f6f50c6d2749bf7ea5a9d04ea0142aed510ac7154b9bd0a6a4a37d8764487207bbc94a6f304d38d4dfa5b3ec86bb3c6d76460efe89dd93bc62745b9cedfdb86bad5dac2df9b41d64bd01e981d71df7d36e7cce8f34d0614c9652c03ad73aef8165619c9f365b067517b2ab1c44362489ebf7ede36ec7a44e291d9fc6775e7486a363a7907d58f8a7dd685f99f3e215e7bd310798099fab8331ebe97cba74eb153e20b31b4fbbe8b1b26350395874ad21a5ca7d92165243f584a8828fd414ca1c36882f13c122938b88da4f97934913c61291e9d5be486d2d332d2def248eebe636b42d60ff7ce8eddaf1361d1a6aaf25d8836d6ff2334ff093fdb98680140a28dc356bda9cd854ff895a76b66d652fbaa95e119e4def6e747b67bf8c9e1560cf2eba7d20056daecc2f25ebbb3f676bcb1bad41f487f0842a105a05baeefe86c54747e2a83d693ab0b4608167ad04f0815794c0d0db36e0ad184f7d5a06fbd8debb1a2a84b5f1c54ffc1167c2d3ea9678144589b573f0a5c82d99b7f61c6ae4bd429e59acfdac85486055cced411db5de8c7a12dc907fd6266883dfe97b8e8b4bb8e56daf435d399b834ef911d1eec61acab37c1d186453937a2cb18de02b2a56262279a55fa792325d962466a368262bf650c1200776c44c27a2b2633a0adfcf26c47300c7198a53dd3b91b22c87cde258df8e393ad23f28b26989464c4b8d61ada62c52fd363b93c01b46093a565d07e33b547efaef470bd9cea8173182e185985ce4c16500a014056eed4e3e40d60799e42dbc95ff970fbe856f8c58b37da1b7b0796ca45582758eefae4a1a7dc65c49bc3350608a5fd3f8c35fd9de02b81423b59fd076b7d5933cde02a772d3a67aae096837f2166a77888c60958722d80f4dbcd36daed5f01261e4b142f04ec14066af313e0b61ade1686442db47ae3f11320267f4f24255f9386d1bce88d51b6810d2ffaaf5ca2bfe8a057b1f496b8f7379f2c2666acaa0a7d64f541b6bf50046ad41252f0c62bc82c11ec042681df61a10996ce397603130786e6473196f176ee934e6e4858d8c471b41799b8f3ef7964a325effb590d7162ec5c75eabb643a9a8a47b5e700e3304424312de4582decf83fd26c48236a360fa194883fa5a08d42e084f9dd70792f29c174c73c3b70e8a50583ec87499a82544a7a821e705d36f306bc4808a3fc013a1c2aa6bc1589057b7e7a76d02b02fe0e585cf8f1e8f3cae42ff5c841a979d38cd5c8b7d06b297f2a8528e7af6d2595558a8d95a61691ba481355fd1d25f6adfd2a4aa30941a6101faabc20e8fb255419e4ba65e1592ce944ee7eb1220af84b7803055e27e00681aab82cf1cbf0916f4748d4a5215aa642e99e311aac2c4d72a95a37873a9c0753ccd12fb6f8c11b57de1693d812d52c26a970a437feedd3e152b48854f7398b2f4274d4962bb1f1426eca5c286c79efd6070e4194a7795dd49e7dbb192b748faa06c4e26133d79263b8b024101e44f0b0fc9502ac28354604984d63057cf680f9769c08d8c2acc2efc0e2f12a4787f967b6800ef5eb00040caff019dc13665bd3c2c33ba028949057a85de3ac9826952c582773a5283d3321d34da566d8dfec506285ee4bde09209a3daed104c61319d881cfc504908e2474780208520543b0202ef332ef5aacc4565bea010726b2b9c8c97616f60bb8d8a564e4a567fd8935fb5ed74dde6b41829941a75677445c3d352f507c7d8179316f8af4ccdd2a4e30662bcf9c87b3ac0792963a7daee81d4a391a04a889250a0823a9a175b49f27e2ea73ddd38d74d365a83626609b8132db4214209605b9168c175edb116d31faee9a9766bb9030a6901b021cd2b4c7f9e22ca7c8f7a76a01067cdd67eccdba0c6ed3e277d4297a6fcf45c840fb2ec1209a0e8889fba17179d9ae32554c71a623f28d75da5c5a868f562dd6b26a12f54ea1d770df5a84eada9982bc861bee718a5ef856566b6461ec1454deb3ee2840f3e56b16108ce031a8bc413be23e388c26fb4170bd88dd261b7d679ab2fac9e5d50f200451196a0b8953d5ba4a1f5f33edf231b93d42691d6ca663b715354eddec26209c9d9116415ae62724f90285d687ec2abf91e3bd9f99fd8579336b06abe475dedd441b09abfc5f8bca3a897dfd58916b458dd90ce1cf33dbace4de9f72fb976a9a8364704a215442adc066d6b46993d38e381200d414b3f6d591f37a5cdc671246d410ff33d6853ddf1c9b489358217b84756a5f5c65c84545b01777fd1e145ae66653fba3310b91eb2ff35b046767e9641823ddfa3ff20f185f35a0123dbee3be44c54bff33deaa019a56e5dcfe4ee82e58fc59453b6506a026cdeabb62aac1dfac19f4b832205970bf434c1f1a775c06461b48ee3b8f068d3f4aaa71e6e390118a591db3123919f835125c5d9c427af2238373965ea42d9dcd19ed20f1d248f6405d0b3f2090e563dd4ee122188846b1fa418fa20abcfded92ba1ecc984046e274553eba4838463c4ffdd1459930e2c12c2ac84e689ea0fc4a725831f63a608199a3f7c6aa89bf38e1ca425ac90526aef1759a50e391c5921ec344f394fe886e6d985bf1c0ff2ff45be5420f84ba90cb0674e597bd21fecafe6508282002e5f748a2e9fca5937061ae64844706194a309a322e65415576aa2630211fddeb34b8aa11606dc066ac501c3670a4d4301f49aa19981d818ec0094f35dde94c40b98c68f7238b51eb06dae54ac439b369ddd70ecede62052653280eee047d57d52fb31139dadfd66be266d13d031870ad4b295670a1c5b991733c10a072309219ef9d51df036092bc4a3a8de9046a96e89e1d1c245b08ab0163f92cab0a342cf1f0963728e356af714111be54d0d8d99dc1fcc1f327a3197d6d9e07ebae06e0598cf3d1fa8c765e4899bf46867c7caa3327dbc764cc3ba950fec70e27fb1ab5ac20a7de65cbd5096deedea6db4f64d21d9a431ecaa070712ed1797e999c79eacba1abe011fbb7f41a1b70750d083ab18cf80102ccfb4fa4f7c8c2b4f0830a884aa9e38cc7bb64767bcad80b45037c247123d0b673d1273ea57fc62fa88a9ec836dac93686801cac60c12aadf8db04487f3cb35d196e3d428da86095a8af32bfdaafcc3c19813ef96ca99bd1f0f0550014613b23eedfe40587939186a4f2c20942edf5414d466ea3eb8e2530fa8d41d8209262dde1c1414747e773e75981797ec48d7961d20d05944dc060ab992ab0c3c2108b798beec22319c9e4c2960b94176ac09693192138a668a44c4d809ea97418d54391fa28fbb1f5c8644947ad2eda264f6cad3b8ba1c312b08a9bd702471fd010b0bf1579f1099a7b63001154e26a0ddfc0b81461b29703813940abfd5cc1d0c41baada2287236299cf8b5cb2a4d37ef0be25da1ee84bb5388ca8c05cecdb89f386099881e4cda48a41648444146fc1774499f03e8722588220a32a093293e2ac3ce5d8baad636a00e276bf29fae05ab441a26265e991e0e3cec4800920a4136101014d46b095bf284b1e10c2e7904043d0606fa94c6fc6dc75daba06fd1f4380a15a29a17ba46a0db8a8519965a5b5af49a60f71aebbf53c8ec331b990dd6b5e3758d2af72b3349b8031747ea119476171f69c8dae18edfa408e056ea83edfb5c93bfaf31869ed2500abd370e0b26f6ce9de8bb825ab6a3bc5421c336f7fa0c9a4c4955e5c54c1e7deba8e1946531a91a0eabcee2eeaab087bd2c75da7078eb7c0b6ce6b7bab5b2e41c93905b2d01130d7819d7a35af669c610fb3ce7f79423eeb1542ed250fb44095b0ca6cd459e779c50e4c0504c8d4f4fc181ed6c1851e47b45df2511ae82234ace653ed2ad75072ad231f4c9153062f6712c4841e436a01b970dc2dea053616543afda248b816b8265b5753cf45b8f89be268bf683880e7125e53a0db1b7e7ffeaab1f94945ab602b1249ce181e32b8967cce3190061590343cf7dc960c3120e918001e85b1579ba7a712342c332ebcabf710ab3c1ed95738fd7abfa37cc4d20876eabee5527584f0585e16dc14dd94139af287159313a652d51ad86062fac24291114a52da52e501d077b65e120f386c37b5315e309757393362780dcdc47f6f1dfad9b23bd7f09facd5376988f23419a8db37473d023527988d44f746bd4ee56619b41bd0097a9120a6e64b5a7b6b1a65a86df210bdb399989b5e62447f27ae642efcb151e99512321cda67d7d26ab56fc5c774a4a8725f0d96221ed86af79d631d49164f7b017cd73a67eab6e7270f52453072acac13b2be56fd06d9e331ce0616a831787190bd0809a04dc0b82da723d0d59617800131e274a3f66bc37a6e7e4c20e4981ae889077eb328bb234a70f533e935f17bf4d97119a5ea58d8fb227a2a64d0d15093d0a1c68977d8de640c5468a7d04bc4c3e652de6bccbe7f7bb03b4e4326fdf803f5091e1cb8dd61c07163d92db2139585ce7d0938032e0bdb522a3146ddaa7912fd3f5c3eef673d5ee1256ba0191c931aaa78babed5e5f9634357081352e8d261179b83e2a8a2d234a8b82725160837b7ef72909fd9e508013d88560680ec4d96c503749f958eb8d5a504b7a23156e59ee19f7063635d85f914b9b96841951419cd352ba0b75e427c5238ea5f19709a6f5fe748f156f50acc501de4e621377cdaeaadc90957a79d60464edd001989aab9041d7e77f4dc5a61114a9f40b80660843e58baed97a38ffbefe075354f23517f3c1270e38024b42d6b1af49c0d995da12a2600ea7157be4646341be951e9f037d76479cc089395f16b957a52997df17a37d3179be72b1fd43b8ee67d85210f38fea43aa248ecc1fdf751c5a7bd2d01f4fd6d6c9bdea0a200cf744fec0c5d34517c38a3c714aa5f105ade79a82d6e01f4a2151c0a9195e3a5b695bc29c167f0f36b337a51216d419e8655ac5e10f35d8c7a46a78b20e6206b963d633346ae2f1f4ead8d40201c8c6c7ee72fe24d5a27ae7a721a672356b0431ef4f1dcda2415f093465cb10d301f289c618b7823a1b65941e11b4741c3e8ccafbcc42df921ada54f93d71bad1001d91516a4e071136e37fdd6cc92e06b0eb56ed227ac712fbac0d8aa4f17125ffb382d97d2a979b51da1463f31170240948381bbb7bc7d9fbaa81e6bc544072e0e7addd0bb081c668d2d1bbedfe975a80304a167741d0e8ef8a3b77764398322f9cbf90fc3b5c4c1fb57cb5146afb5450b3dfb9ab55032b76b41ac29ccb3cc0569a96582df265ed793a49bf0727d1b18b011e57451395fe026203dc4565434afbb02c2e9adc41ce49b7d8fb9534659ace9a484b9d5817adcd1addc2c7ef4387b44397c0c6900ac2c382c8fda5e9b729dc782573ca9d6aff8cbdc9d421dada354b8d015deae2217f65f0e7fa7eb3dcfb69752a03d20d3e7298638f60442c5329edff700b0b6a921cf2f158645446c48ef93719678a519e4a2806a51549ece0f5ff34d23db74440665446f6ec843287e2a294bf37b187f6ab6280bf48974a7ddeec5512049631d237b7af4bc3c7ef8e6defc60822d7da1789f81d6850c88226b7bf14340e749efda38cf70b4048cbe6fee5871741d9934c0b6c2c4948a8ab9285fa7d933685ccee45ec77977e0bc18386282a2f80f4aa99a236e539d23adb9fe60541a076405bdd2e68f4d87eaf7e88a9912f7b3fc450adcbf0f2f088dba192b715ab49a90f47ac4d799f0ff0a8e936ddc1ac1e735f97a7bddc03932781128776273abf4995806e9fe9597f2ebbb52b0596f7b401747ca6527ed04759f4de1ea1fec29afeda221c83e55103c6a575d8627f963137bd8defe0646f60dbc0955d4845c40c1280010365a2a49d60b06ecc0b63f457a51ea35deb672e89d04eec1ed7e633e29ea13809d6051a64d59bae068928cbdc5a31b9d93c5b485c061c9ed77bc4b14d48b1de344196eceec8fb71a3758a217bb3055d1153c6a692faedd2c6b51d51a3c48887546a26b2e62e3a56b718f7eee049611155901706f890f4fe5a840b630e5d4a76bcd14a91de0b8f3317d03c8ffd0f278caa583048a99bc84cf413506dbc08108a7a32dc85aef2544d619bd5976871a58500330e5f30c11686fe33359fea991d025935154b68cef43b17ab2e2eca88370180989aff70169775f3c2e8b16518600b88c593fea446f2d679ae8e1ea3f0274e8d867e57e8e0b63ebc0a320af63d8ff9bb32109051406713e7dd733f80508e32367dd2d59a906b649446680c1be101566bd322f0f727df96ff24716a349217c978bbae418d8bcb9bbde9602e999e91e27c7e6e6a48b41b5970f40d888c60cc91120217dff4a55cf248bcd3e4954a4c4ab33f1a842b374310e65335223cffb9bb83f22f578e9927f72831864d9dae12fb0fb4da1388bef6d3049929b50cdf1e6be432465ec2f967c97ab2ccfc8b156c2ca3d1bc1550b82f65e44306a99370ce7d56ba2365f7aed2d77d29f85644d306ab93e039c6d03f0fc993c18804f9f9097a9f66ff7d5b463495b827c6169e3893206613b4c98abee1e95e5702f12b7eafc4ef727866896c9a9b7a77e8c214c060b42c73e1704bdb795ea3bae3a3bd16a706d20415194f08d366c65cf377a88636a8d5bf5e9b5720ad393b85626b5c9c8c96c351cab39cf0f1f6667ff09efcfc576a6790e8767912f86222b35c031f7b543ef1ec2e82052a70d1bae0f7d986dcb1f006dcb6ea0d2b7c94eb1128fbad6dd35c3c0d9f509ed4a8525f8cb41e1e35ef073201473f1c05687b02136384f38bc1dd65e86f23106696a94800adac7d8499afde15b9753fc0f8e93bd215643ffddd8a6d2cf062bbaecf120975c3261479056bc022060812c239d0dd1fca17e987d278062f0619ecd888f456869d60e86e5452011cb18e03e88dac2568c1f490b1d83b25a672b9fd1baaf91c5c4832fbd3391cfed52827ceee691e795593a646fd0168b4104ec441f1965841ca4916adbebf00ad2f78c504c6d8710c2e586980aed782e7d2b389a9e1b20465ab8ae0a8813c9a28baf891f143c3598c1d6dcdaa4f049afd3119a793d20df82f83277c2475523da7747cf04d01ec7114bfdc95114e8c4607d8625bfd7714f54a7d3ce639e1b7775fd5a021f7cb10e8411adf932f17f76635e74bb1cc00d77a9b3f9d5020eb95c4fab2bde6796488068863b233bf40c5b6d9e52f4eb807d325f4df25c8d5771b644c5c871f4603138b02af562c607b1c1ce2c29f6556cbfc75aebafce84394b2598f38068dc29b5020bea51b8d34aa2530d06e7229d27d7741907a039d8afb6d67864676db6fd6889d17922c139dcdf0676726e85ba6f74b165ac6436b56d0621a56f611594568a8d70acbf280551b2ea17ddeb25b5701afc3718589e6e0da6b3daf0693e70e34769a1525d3d2ac11cae7088f96d5455fdb181b6110f5365b290f48787c0b73e671fa821752988c84c8b4a52015d06981eee27e17182183c5bbb028e9c3a9b173bcc2f3b51f34319014042b301145a8fb55011522c3e06d76bb09872c397e0fc3f2baa4a229238a8b8b8060ba72397038514beb734d1510aa9e03b8a455d7e3a39481db0638ba4fd43bacc7c52582ca3b7aca4e0f94e369bcb89b74375dc6d1d812522c9a47d4eac5890d3b3a1a18a3ac345bf5de85a7c23474113601cd9b803a1b01820a646f4c92205e0a32a9ec8863c19eba235c57309662e9c621a40147b01a48cc1a58fe2778c2b35a4b320aafd0fda5430525a67bbce9aab1260738df8547a43e329dba952268b7354bddc25b1e347c26cf2a8c4db98fe6f3fb7d80607b0ba942907e4327376865839d9aa11f61031df9f71a146c59f7c0df32205212e0417b4705771e502fc4bcd69ba660200c009f03c374a36cf519621e48f2ad1eb97e67cda802594bb9bef173c17d9736820530fad0050cfdf016ada386a7a512800b60e57d772276e051c9cc015d3ba4d34e7594df64842b7a984a1e4e8c1a25513f6c946c569a1e018eb2b6238b57816a1410173c28e2271bd666da277de5f308bb2228094842df8089bd9ef88264442614716fb47eb172c464047a5a57a85720da19a703cdda61868a99443c2e721c31ca21b040f4e25c7fd7aa6d752d900cb5759871ad22aef1ced9f9e08cf64c08ea713574d8ac34a19f9acdbb37c02f1fcedb572be4067b033ed05b1fc96e7bb735b9a594292519490a630a180a5674c1badc3ed0c65f017d13f3d9675fbccc37ba767d333af6ba70f6dbb95cbbb83cdc380b845f9792cbf36858fa76b9b887b04d97b35f97ecc797d321bb9ce53a7ec83173cf4fb71ce63a662addccbb743276c6cc979e5f37cccc947ee65bc92d7d06371db2ebd27d7c5dfab2a98bf132ba92fd766ee9bb632e9e707182d77db9d00a2ea0dccc355914ad385157b16d99caf61f538979978fd7485feefbbfcd1ae9bb7ddbd2437873faaf5ed4dff8b69fccbf3c84a7ce64e34f8fea204c9deca7c1fc8d0ec2148cfde26d98efb7d175334fe35f3a1210aa8c2562baa798a761bf785dfee579eb3184fb784f76488c3d992ef72fff1131dded5fec17e5e5193b64eb2d87930b8cfd76aecb9f7eb343b897d7371de4e5d8e54ff6632ab7b90baea11b26839b1739f71168863a7fa5332ef6abed037570eff406c2d5cb672edde99d67e371e9b6e73abe3ee0e5be07bc9cddfe74f9994fa71333c721b8bdfcb6fd57efb67dc63cc334de250e35ca61b819fbd5eaa7d3675cc73702c5cbbd9b2ec74517171b8738f6a2faf5813abaf432f0f2c7569a05d77f2b0a829da5084db13de0e5a80cc5700fefc6457c8585842749f7c4f0c319a5cf4a251eedd2c146cdb037700ae81bd837319edf646f90d1ddd0a88c7bb86d16368ab31f847233191dbfa98bf1706be627f186d3a88c7dd85962b4875e6683bb19a695bafead2b5d98d2739ff996c371325c07efd6956e29fb2e651bd5b691b691b42dd3364ddb366d2b691ba76d55db58b4ad45db4c2da62db3d1e91061c3facbc6672fc457371ef5a9cfeca8a340a384f840a448a750376cc89e9a16f293b517951f6af0c6f85aee8bf2add17cf5d40a87cc44fd5417472505d6b4c441066bbed8dd44a3e2dbf6e99fb681888868e8c64ba42a40abc8c53c3d6d4394f9ee38c92b49afdee34ea68b416d431442a5b4464a6b119fa2266ebc5f13c5be2940dfc0d617576e8c377a4de4ba9f53e117125e1700174279028a516352488f2df918c9f5cf38ec39ec9b3829a142ab542bed13d4dd6afb31924ec5976fbfd6b61eda631fb16f09af7c082f6f39dc36a6f4f07ef0ca75d29653cab24cf66398e4c730f93c5c0e21fd91db70eb666fde46d813bc037bfe8cfc37b25fdfbef4c3965ceeeeb67c491f737777776376087dd2f77f4472643093dac7d88e0ebf6cf91171f9f68701dd6f7e37a4ffc8e5eef32b3f6e3ffc52397f247f6461a33eac496fff614b4614c3ec872de1a794523b84310cc32c8661188661df1f531f1f1f9ff741f9a87cf8a56dfa18db18969f8ff5b3fd7ef4b30efdd8cbc77e7807bfe41fc9ffb025d892d2d663f4d20e914ffa6dd301fb4ef505ae22d0a742b560dd31b4ad476f3a00798f62220c665f4ed6c5ceb09fc97ed5c668b1242997d4b108358adbf6cfdf3aee79b896e366dd97e3d5a8d944da7ff23ff99a1d529f94614ff08e8f2ff7938b988b988b3c155fdefaf3855087c8af7ec641dc932a0331ea2b8cf066a4c19b6e00497e7deeea6bd2c6643fa520e95313377e921b5528d4ffe9247f7e462447fa8f488ecbbffdd7542ef7d8d683f443d87e7ce56b3f371db44b62f621d94fe354104249e5ceffe84b6e399cecdce5b5838d923fb2cbe9f40d4321a1264a4e49905cfeafaf5c6e2b97998984b02778c78b0ab6e416f98a29add55968cbe1f844e8c5434c746310db08949d9ee4aecea5b850e70cc43cafa711595ee4e29113a3828a94d18894695b4983edd35c656989619221e49232e5c2f82f1006728c06fb86060d8d8ea69be9663a1792e91c7a347cca1694b03c991c204d24c3e2e94c66e65149d4a7a141c44536e3349a86a5547fd8699109568b4ca0d1be80a96ff405cc5e8bbc23b22efcb804ebaeb883fa3591f7b8fb24f925bd8a9f4371a33f618eda51dbaf46a1b1e5744dace136fa06a3b4a845f587374503113a29990e7a3e39ee515b0ef7190d9da3bbb1eec63e77d5c7b0519dcfc327cb7451daeca08e53e995ca53f14f57ae66e5ba481f8b906cdb203bf00ef9f181f00e0cba5c98a412fb1c3d00de313fbe8a778c7ee669fc67ba9feaaa6e34c11aba86af234c35f6149312001a0e8df649f208a17eedd32de8267a15a10ba00e8736fdb54f9b56da9d01870db482ca0b88569b00d453006a7012739269543cd1d09891c96a5019c1322c6cc8ab4954191a1a3598915109c0a7dcf8990018484a55048a40be722d602afe16415cdce859b8f16304dadc056d22f7c48faeca63040d1a689091a1d19900b40168901907d3652068d32da8fe0dd42866a0ef6cd4d807000d29d4c74739819e0bfd44d4f600e8b96b8b4a33d3591bb6c65a7b8386c68c0c006848a1e48daf31c3db3872db3de5b2c696e35e43801c6dc3d7419773e4d872f861c755741b3c02750baa7cffe68bf19546c5e7679e12c39685f8d5a8f8b188daacf822a81ff3304ffc28356ad4a851a3468d1affffffff376edcb871e3c68d1b33cc30c30c33cc30c31f81e3cdf0331fbf7f683eca7cfb085dfbb1e6e3fbebbbaeebbaaeebfe081caffb19fb9186fdf8cef215cd4719fbf1bbce468dd5b9f13566a8d9729a88eb336c396db71cf90c743249771b6e302222a226f25504aa1f0301a1caf7b63e3e3e988fecba9b95cc53af9b2802752b1c294f3495bac429008da766b202e8b0728591e8d8e10f53edb6a8ca8e1b6e30802643436346ca0cd1bc6808792afe4ce72eefcf5d321f61aa654c4456a2a47d1b5b4e1b403b80064f276fa276ef7eefe453da3a951bbdca8d9f1de00008e0a171ede7b1e5b495464577b9208a65d783df73605716b7ad78da47bd89ba880b95898d67f28fe4f2e3b041f338706c3b6c38d0b049a0fed340030ddb0ed0a3f1bde110df85a2b7bba2d08dfebad1876efc1a5b8f7a99c7c6d7f88fcee0aeff4e91d27a3a451b366cd8b061c3868d3f02c7b361634d4d4d4d4d4d4d4db4d65a6bed1f81e3595b2d0d0d0d0d0d0d0d0dbb8e5c979686868686868686e6144483060d1a3468d0a0515b333333333333337f048e3763a3c8c8c8c8c8c8c8fc11389e8c8530d5f6e328d735c396e316011a843a68cb4008a18510421a1d7c9a9918989793cb0c08219461aa893390362d1b51884de90d995fa54fc88d75e7d4fca408bf10eaf08e3206163bc68d4de79c7546d9d1eba44cdb4a9c2625f6f0b2dcac2fb5b1de8c9354ab9e79c7bd77a5ebb367e976e7f4c692e61c431b6e6718fbee608cc960c4f272e1f3571bb586eac6c71b5fe3c68d1f123f47a39c6da87054977f48c4e91bd4fbdb0ff5f1335487a3cad128cf81e6f64d7c89eae08d7dc39e6c74b0c67777647d8c52dd46150ec7688a6e8349410d2184376edff23b6cdfc23de977e09e14bfa5abcf92fda8a3b423fd88d2966ec763e9763cd28ec7a349f69475a41f8de848d346df19c5baecb96ef4a58efed691b20efb2dcbb06ec7e3ba1dafd4ed785bb7e38d3aedb14ec7498caffdc8ea8c5eb3d5311a047b92d5c170308f3e873888f30f02881ef0c2ef016ffc1ef092a4a840260369f88243dcf0e6745a8cbcf3fbfda564d88008b94b40fa26da98181383f4f7d037100209d2831088d9528517097461cfa3f90937691b7e1ae5724157852e9cc9934525c49347f702c0547cd8452cea8773637cc78136b17a2a8e28b48937b22a4ec46922f4505731810e7ae8034118a1778e6c985a1e326dcc8fdbdff0466ba473e030c208238c2bbf1ef00ad1b73f5eef86a491fe22b437090839bec35c248335f0a3bef1d0af13ff887c1ee9c504f1a74fad0e8de7bfe3cd39e7d37f41066b1c73cc318c62d8e867f7f86a64b988165130a2f88a7ad0f5d6f5a7605449c1a8f23f2ee221ec3b24a3a73fbbd901045cec08f79c604fbb23461e7d67dd693f6931e71e4ff910f360d8f3a06054ec250f2742ccabf25502acf0f214bcee25c00a448d8237015618f214cadd5db2a713fde37d1adca0cfa8489cb0133258b3e287deff449402711660aadf0bca6054119c90b8fd407f5370bb63d043d0c688fa31eb2703d79f2445a5b9d00a2b58b9df0bea708b002130f5c351847e5c3f517e4e27db3fa4dbc6fce8994e645977b1515bb77b94b285e01e2c5d2baeb082fb025b1e23e0f2aa867ae332cd6526f2d40d2906bcd176f48fc39b6df4bc846bf0a6024c755301ae7a0453ddba7c19b62e91af1a152d51ed298dead7ba8ad0883671a11fdec1c5ed25bca3b768a1705e8572fb5517aa427714a04dbfb44b5ac888fa71931e823a7a409b28befa01a6da07f3f4370ba74845847a9d842a37399d6a4c0e308ccb3f849f5917c6fc60d6754ba1cd476f109720aff47003c27d8c42d5a00ed2edcee43f5a8fa464fcf081507e8d3926fd1b0f6de106b989c0e1f284951ce0682d4079f10c192617d4e54f753f9ccbaed9e3332711ea278b5e3f4386c9a5c8574ce5e5b14a118d3fd026bef4e18b83dfd373ff499e2b9a48ca8d2f8378a40fea4a1ff9e32bd20bccc7973cbe12f2b2d22b89e442b95f0c92296d51888370ee178382268fd338d9cbf82728a888af48244bb23f9366b1619764e949ddf62f9df6305d7d990e7a45ec4d9581e95e8a20b9c2b03996a4ed3221fe43df40e923d925e492c2246dbe84ad285421bb4842a3191f65d868b22e96c5faaac5c6b0d1e5abcc52e923adf489414e69ad4137be4b3743864e8caea56339615b8e9c3c7c00e981fefb2a6a5b966559966559edb22ccbb22ccb88b8f2e776b3e73af6dcb5e73ae8719092e67ccdaee185097f8872c7c87379224f84523fd96a72637c962d5ff193963dbe629e285a5c831edcf8b0c9953d3d3dfcba50092a5feea1f749d68b880987a409a803dec85e94dc3d91e44c2baf409b288ba04d7c29627cf9823aa8f44aba5c556ebd32e2a07ed4e5924978b6a8735a96af38fbce8a43f16351a402d223dca8c58d5bdcf8510ab88301b1a584296efcf882530faa9338831b3f2201230fd4213f4616dcf85f4cc18def44a37ea25b2d84a911949773fd2da7a651f1f9f21515d5a8f8dfa8a96200bce246c9aeeab23f7b1417aa7c26301f855e7e8722ac9d6b6a81a15be6302ccf83797c314fe489af1b5f1e9b12c67efcd8c3711cc7711cf7723a9d4ea7d3e9e43263c68c193366cc9821c36432994c269329464b4b4b4b4b4b4b0b112c952bcd39678ad99b3d3033a8727ff0c187bea1efc31219ac7188614c35494f4c5f7eed1bd2cb37f5cde881782ae2b8f28548214fa8f27b780f5146c295843ab8975b12ae21be2c7d36bb5207240c75fe075d41a08d849c247be81a26efc749b61ce9a58e6fd6d98cd4056954ec30f9d97ff2e9d30d07295fcbba0f1b69dd668760afd90bb36ffbece9a669dd97d91e803851e743c944e699c43c09c88d32e6e58c975b4663604e334c32be65524a99df21865cbda7e203890f6de2c77ca42e323c7cc5c2c2c2c2c2c2c212030303030303030363ad74b1b6ca30994c2693c9649292a5ab9d9dac754b92d74ea73ffd9f644e27993f7dcde9f6f790ab4822cb4fdf43c50e88584f18668fb5a6659aa66d9aa63d4649cfc363155c03f63c9c7a9f4eeeb3a33776c6ae44c6b708e719a4f472f799a89c3b978998aef4e7e111428c790926530b5500ca6d6aa52083dff1fd0be10d95bfa69140d19a984a4e56b49edc3f4d01c5ed97f1cc63c61fa9b3851b0ef49d8767b2d3dcbb47737ed67df231bf1f7f07763ecaae76148b3a9a23fb49c943fc69d47efee49bf9f643feb4df10ff21fe2ca9afd8694d673c214e7c7e1ee4434b047cf96c89701204be7c22264647238a4dd56d95afe447c8dfffd864e848f821f454c356b723d173e30dfb5773742abeca57489cb035428dd49bf1bc97fd11cf83520fc27d5b9d7e6e47db46b58ee8a651ae7b4fa1de870684f4d9f3507aee79c85eb34458229c04217dc6018d46fc1c675d8d310648cbfb17bc98205ff0585a583e9a9e47fbd0a828e3102c0c8bfad3c487a7e28f64685faa3146d2c71091cb878b7fa6fd41c8cf6b498c3fb7ece78fa7e294d1651fa323bdecf89a3a27194be85d0003457c80556e9c304a939e1e253f4b7e7ada87af8688455186289a3184bc64742d1fa363796e6179d306b72058c731e027b886f87349a7da868fa1b8917f30aa09d10951afb40c9824ec06116f4e0c90968737885bf1583e6e31d3927e6af0c34da00eac0584284062582448b8df1e49e93506f08ee6897940f62d1f24fb161d0f427a16abd34ffa11ecb0465f1f963412031a15b909d016c5f503c447a3a29fa0ca6ec942066be267cdb47de4d2311f913ae91d33775fcc7e452e63188661411886510c9312c33019e7cc628cf133a9714e0edb1a8de5851826e58fb0c630fa716b803ff6d48eba6e4195fe40e69c1e9d31fea47752fbd53b3b068769638268bffd0eda6f8df50ed03b01f195669dc8a13ba76c0cc36697a690c19a8ca363ee11ea60bf184f0a49ffc9d1a851a46ea43985a7eac5e9a713cbc92e2bea7c1e1da75b086dfa25952c37c83bad9452ce39bb1a49a120b1c92f9f62fcf2a3b4d4c646c58f51b294958bdf5f3a7ad8992adb8fda53a322ac7d03793ce8a38eb60ded840abfa3c82fa80c5521e23cce4383068d97f181bbc05ee8cf6431313159f6303f435f1e66e6259b99c9627cf096f3f82a0245206f45a0a2a256bb98be4bbbda55e42d6fb590b7dad52e1af0e58245170c8bd8c33b65de0719fbc1211ffa065e9e35837dd3f9d0379d0f8dcab2e78db344ba13d237198e4b04c7e5efa1a345950ae9407f085b218dca9e0290487b1e9d75a1b9e6da0b192619a6772000f86a2e33003a1a50a9479d6ed458054cf7125b110ad55c3297ab41e150e5c811ab88ad08e5e55dba4af3f2301f5b3e5e5e60fee57dcb7979e9606215b10aae63f99642518abbfa8ad88a5022940865864a23f3dfe95f6a7c8d7d0857a9a7e1eb43b802c0b73c840ff300a02185bad1b1ab46cd0cf6a3d676f6ab6f696c4d8bfd70dcfe1916c67e3972c8d84f754f96488e1c3972c42a6215b18a082556e1e38a962ef08c97d27f2a4a6b3d9d5028958a3bcdb01f95b15fa5615fecf7a892fd54aa19d4cccfccccd03b53fa99cf4adde95528d4f770db1e6e0e80b764ff3bbecc1c9fb60d55f332a71cdc0985baa7d3e9743aa950a8533de5e02eccccccfc77badbcc7f7fb799ff5033ffa9665cb6d3a3541cc7fd0cee65b8a7c1fd8b4b8e185f8ad185daa252c9d80f85a2614ff63b9d38870a07aae672049201ca512a715d80f9dad27d3577a625e37e5ec44de1b8b9520b4ba9a585a5e5e1ad34309fc1c0f0e8a6b11fbc02de2c7b20fcdc15377b1f7dd3f2d977e7a33eb73cd7b13cdc6a176a0b4b0bcb7b0bc7e0182fb71c491a514aa242babb58c4a08eede1971e7ef38e0a700dcebdcb6bebe875e958a04df6482e8d0b03cd047e8c8232d16f3935ff28d39f706ec6d2f2fe2fdda983333ae8a9527d1355615887fa2a355f6464bf5aed663f94fd549caa6e0f901e8ba523a8fca892fd50aacd321011a9e9a84dd6422038a15c5214973e4fed61cd2569f6a3c0a5cf28d2b7eb5c1a2ffd1a1436a90c143a9db8a6269048aaecb496e7803690b945e113951f4acb3ea2af11cd489dca530f708f5a94a7e24f13201f987accdd9d25e3103146d1a8c8412c32c8627e7c7ed9074aae91fee4659b03daf08ccb3d98025597080e638949f3e05e5b94a7205381416f144cc1f7ee8e31c618ddddbdfff397d1ddbdbbc7d8853229a594cda66a8ac1dfcb9f9fc519e33bcb9f6ea79536d6c42e8c486e4de91c861fd9ff17f29c457cfdf40d8402ea984f0242855fbb2090bbda15838f082a5c8cc6f8721b440ac4cc78ce93e6383ee513ea9cef43c836e78837212f1fba1f84f868ccbaf439a7bb740ee0d0581e21c2977c6e593d7592b9d274a55c65fe930cd5ffaba6209dc2b1230be40a0eb598fd4c2eabbbf5981f561342be461d89c00c4d9106b59fbb63b466923121e109256c68bfd83d92dc344aee26588b79a0c8006bd540f6e0cf18fcd93d2370fb1650474f2d8aa1f61698d6410d05ead802eaf8b10e64a10057eed3858f162e6ca01e6a02fc26025cf590a7fa9ff412b86a17f589c23ac26ad695164802e5380b8ccaef2cf771c9721943e4f643c68dde43be72d6102b9b9d7c674d67390b8b1d1edced87097297a8c529c0953daefffc76b90bc7c7c31f264981db400dd4400d64611472dd472768bd86aa105929bad2ac56e2f5d30488c5e33d2268243a05af21a2a25614178bc562b5fc25e48a72d91d0c5cc451ce67d2b3bfc0007568df7216e5d9ba1968680808bdb8f0bbe5f1e7a7c9cf8fff4496a7fa4f41956b161553dc515fee87ec4daf6029504716e08d0020aa9f73709528df2f5ff96b88d78bc80a3e52b8f0b90970c53e1446b95fb38a5cb77f58a7a00a744fa7af4a86c1912eb80447c270fd91a09452248e7cf1f3f3f383b1582c96246d39d0dc12979546236dcbb46c64bd874615c9ee1e1868085ff52054d443198ad0c2121b389d681698f89973c223fc20b2222b1581eb230f5c67988aa30984598bd3a9d651fc19c59f51fc89726750f610d5c395a391fd86b8cd4f1ac52e8594fe92fe92fefa3919885e206f08c35082eb3f4c0c611730b800b4893f042c6ac885133df8e954abd0ce14d79fb1c7f1d3a956d85d0b5c7f6e25a08e189bbd046d5a35b8c8e0432c40f8314622382eec2631c68f23c94c2316a3b450401bf83e85f51486fee7deac30ee1087cd0a72699c41654ae107352a7e5129f6188641013ff612faa3a77d8331a4b47fa28f2cb5cde3dde3ede32cf8f3f46b1497504b4613a0a01fd3b39546c197443c24e79431e49cb265cb89724ec922e79455ce29b9578c3162ec2c194208a174ec87b3dcc33ecc2a81210c957f83cf43cb484c316e792a5a96d8c367883df41f823d8410dae8fed24608a1fdf887b4e56058534b1bd514c36c0e462f86611806bfdf878a846060a81cc5c563a254382f31fb611886cd28638c1f638c3598b44f081fc3aa7cd87100c71d82bd7cec617743a3786c422ed7010ee30ae156887ae3035162d5aff5f9599e6f0b8b6511409b7e23b4df0888eaaf1d17f1314be87efcd3df44dfcc620931222f4ea953e5a8a27e5d748bfa4adf98fe7b34c2ba0fc7859d82afd9ec2149a323d577228223b2f08442e947dd87e38e3ed4af5afe3bc54b6f35955a58348e7b296549fbfab3e33e96b697dcf6722b6d7c7a148e7e2782e3f6fb9683cb135670a08a40a02d2cafd4fb63dc3521eda555d18a36245c942d8926a4116957369eadb9289cab6ff8b92bb8bb9b94651e69f735d175fbd18ed411e99417e1aecfdd547a8a1428bd922d4f057514f4db4aa2cb3fbfc80f56ea64962de7ec474fffbd6c05dd4f1392444017fb0f1631a91f6d72b9bbbbbbabe5a278ea0b5c14ae8753d2281f1d784113bafc301fa9090ef16a4d8036fcd10b52eb32d744941ffac69f9f48910ede0c9344b0560ecc03e589dbfd116b5d7a2b4b4b8c182d51b0d41616d7da135cf187fbc6df802c30fee3a492478ffde8e10624f215a88374e1ad2eb7922520a37d03f33575a2f2775bda28f841f8999973c8608f0aad108242ceaebb1fcdba139b3a370a71aa527642d0dbefff613f892af6b1fb74ae91bedd0f236532fad1e879bc23c28906bc58873258f3718f4afe68daf97b0e1e0a6091316ab463f958a46fe8a471d2392773dcf631cedfe0a493a88811aa43534a8b74a1cec772e09d1b93c3f6dcf7e0eaef5cde72e8cff91cf770d3613e3744a3e417e91bb6740a951bc009d1975a233f534b572efdfa996b5c477f882c6e3fa8e568f7e97cf4b3dfb68efbacfb74f8a9f52d877bee98985a646e8d97fbba7546e2ddbe88af62bc7c21be32bdfc189d104f996cfd522d62848876ebb3e840bf5a2164eef6999092101f88888a64458cbc5e424a2f213e14715933eb2df6dbb923dbf2ed43f48dccea6f95d3a1effc21325b249b5f64dbb68cdbb6af9f95b88dcbeaf3e86c2b5921d50ee17e3e377f7bf93efcd037d9d7dac1ba95b8df2cf75640a14aebc61b6b17afb358208d92dcddecc757bbf57be81b6a29b51f11ed929efb8cd4f500a451f27d8a4a3fc8579ffb8f5e19852497fef670fb417fdb3abeb5d36e0fb4ebab9924b552e7b325f2f1a54f9fc8c7973e918f2f5b22fc6c5540823c73eb665c7deebe2397b3df7ce636eba351f2abe5d1528014905c960badb8c2755dc351e1a872b84a55c40824a25c54788df09dbe71b588912124a55ccc669998acf63cda64559e926f3f7a5539e4435456e77f3bf7e33e9dfb917e8891befc46fa7ef339237dbf0eecdc4ab2cf752828d4edf9bfd761b343f8e70fe1af6994e49fdaebc03fffbb06c56ddb675b072bb775247ece1ae1293c5810dd1b6f896e38d0edb94e0895af84bc54aa1c425e2421af5a5524158e17f5535d09045fee49b592b6accb9e87d7acfbe2d51edb70203d7f3681e030e8172a107ce9e740134b435c239dfdf60ae89b2f4a21f872afca8133bbfa0cebfc92a53f279d1d44354a7ea3648fecb7afeffc8c769c158281e84bbf08d1ece2d54a9fd1d00e080ee372fff2a54b4a218d9240649dd810aaec98983e33753a97be162e57d0cd300d88af8a784a66522b22a9a554a8349b1a8d5ed48e983afa47bc57448c4702db862f5e6a4dcfc34d43dc8f81a05f3b20388319d5e046eda753247e1040b8917a8bc40f4208fafc46ea35d253337d1bb540788cce497cee8cf4a52cd68db4fba151b1516c63a3e447a17ecf75f0c2bb49ea851a9f9f6a94c6db1b6c14895a23dd37f12fb5b051a51ec01631bfe3c11aee62e6b367f2a017c30347f148cf513c9265b977248607f648cf1ee98ff0b3d571b203f48cc03c7e1ef7d8c6f0c0af4344189e633a5947844b29eda95118f624193bc618638c31c61847a3f78f917ea431c618638c31c6488a4db2d099e444035f1f213d27bee3c1cd49d4e6f0573ee63d8be0b0e71ae74f6ba4e1864921fa76ecef6c7efefcdd7d3b3a377e67326e39f8958fc59bf318164b78e17d308a154758a2dda9041d57a0600457a020042876e0cd2a8a7062074025c84218a67093264ab8f093b97e9770fd23ad57ae378184eb2f58e2fa0300d5844509d79f862a3de4021b5c4a3f457350a4dd16bc6ea9f4a82da7542f531f5ac2f2fc6fd42bf85940868b616f837ae9a6e575fd6bc4289aa130e1ca8f7d43c3955f435dbbdac5225ca1582c56112d16cb7316ebfacfa035d1ecc302276ecc71e3db2d270ab190c4412dca7a2e8fde7feac743accbb24a66b71cd9c5fcf0c74a9f0b36e331192d2f6dcc0f19e325573fda981f51fbf83bd76dcc0f7ffa5e223dc97e24128934e42f9250cc497631d8b3fcce8d5d8cfc2d263ee977ae7731fed4e55ffec57e2feff2f2f2e272717189f2d2ba2ea70eeb7e60cff2b2fb217fc427bd773ffce9673366bccbbbd8cfe567b8b8b804cd9831036846c7d7c59b788aa5fb581efbadfb36ffa219a512d135bd8c97613f196f92214386f7984c26e731757c65704b1151e9337dc96432bd4aa5125f53bb62f0cd5858581cc3dce7b2747c332e08a889a7ea0f865d0e2b3df63b372b954a1886b13c0564dbf86a52ca6e798a4422459fcb7c658cb1c7534c69e4b9ec0210c0bb008ea834ed12625f55328021084f088da0e80befab7762c1829d26c8f0052b3948a268095c78347cc830f32c16ab88d78959a6e5fa2879c2759f2d5cff983a678d124c64dcf99459070c3341c5f58ffe2f3b4a98f0c1168ed0831c804165ce2bee5472c59d2d7782a18a304481094b9ae8890164d6c14b54b9de84ebefc23f2c16ab04ee7e822e970f7af082255318c109ef53b9bbe9fae3f81340d7fdeb4d123a60c10c984082570e3ccc676c392e5f460d28458b02dc0fc79d3730e17e108a0a8270e7118c5841132a567045091677be0ae70825b6b8938a25a0b8f34d5bcecc01898962a820490b118bc5228147832a78218c1b28c1c7074e7841dc91703d06d7bfb88293256028b9010c48e0f90b91ceb2e5f8859fe94e999a24dc0f0702ee97e3cea7028a0454f428e1a28ab8f3557d03a9480116777ec5d142ca174cfc48118328868e00a505adc9429881144c08c20f10133c6593ca2521831bae7fc95485922a483d4990601b6a79218579a5d5504084eb1ffdb3b855f18410361ee2a2b98a1e3f6914862cae3f8da73ba5114c54ec806874e7571413f918bb6c5cffb9040bea095872c8468a132988980082144e86a2285194ede0600a1e7c6185180491410aec2e90453d53b0d73fc6a228705085968b07c990f7551fce6f04264c50baf3a9af0e100526b2a02289241ce109de7c215007bcf1157f0abf1ab5240990bf84ee1c0a220b3e5fb002184c8e58c2b3c21445c841173880420c94f03ed59d1fa46ffce70bf1e12b1efa098b70e7e3f40d24c2cd7c05f40d76e7575f35000a59f4a00a099e58b1c29b8ff2d5054212454c11650b4bc0021cbad2f24b280615de8fb1a81dc4455e8bf2d74097a9304118ae5f16f215f5185ede581763a9bac770850cfa4aa77f76c0d3af7324030351cbeb3f028940f4c4ebd7816078476011bcb64ef8e11f61de5159b40c0b2bad130c6aec203aa427f8b03cccf630bb982058c6050fb3423cd5bfe34918d4d892a115c215b8e0b9bb54c9410f4a5504e53e80441c1e9efac153fcb319ca280624589e6b5817c3034604ffc4ec003deca91f513f28747a4f35f648e88f7ec7235dd1a86e35aaa1dc6e96fb0bb88b229a50041f78b183d9d444d08415548cf0ba80820c5adeec6011a4e065a42425f0b02ecb88d0730326b268799996a4041e37590192124ca1e5719226e4a0e565db122a7a5a5e866135c06209922471892c3caccbb42c9a40052d86d0f2b26d892c3cde81908775316c1f1004058b96c75424018396979584c41046cbcba837432a4bfc44051ed6b19014636079b48b0c03264e6079b363236ae065d3d9072bf801cb9b1d044389974d0deb6c4801094dbc0cd366a7834dc13b62ba81371feb74464628e2f174e6eb1c997f64167da108deb45857430a2678bc6ca4611d01bc800496979134ac53613145140f2e210b48b4bcd9a99e789926356df4c48b206f7632487819d5fc0718d4daa80eded9e944275df8f18ed02ebc4cc33aea29276a0cffced55cc045cb160168d366073dacd36125c6d0c4d33982fd111b2d14e161b6a4611d4b8104473042131d5e6248c83bd2553cd8367c1a57484bdfcec53ac8052f2c01f2669761e1659074c5d01645deecb22678b16b67957060d2226cc54afd665a789b4d8c4513b53f0823f4fa3b5cc974a7be0c470c4cf7026d4e22a8fcdf099a6ef37fd574db07a6e675e741c63c78523956328020283288c27df17e44b4eb0fa5c462941293cc49b806f9dcf5cbae9fdfb3085f724be6febef9c8829631d20a7b4cd0ca5cf831ba8d18218da8fccc51f88afff9d89c38a6952ca88ed997f998895db9f03166f95486514a20753a1dcd8861183647b4e583644afb498f986acee911b39f9472c214fc391f8b733e94f1ca28ad8a0406111050145e356f7ad39b60e73edd14a339069508992bf45aa9cf1eec2c2d1f6e089e9e22252042aaed35aff9d17a7801c954ad287f62524b262a3f4ea3a6bb1761f1d01fa6fb68cb711f3005ff43dd1c32289be6ab9e6aa34c988ca8458b16b9e0eeeeee10aee80a63ac8b653080498b335c2e713a6d39104256e1d4d3088391f106191a9d71226232dd09ffe1d68018770884efb2e540a8c51386c98036f03b7a8c4ac685cf5546932b60b9021a142b7d3bd734034a2595bf36aa4f1abf60f155e7fbf3ac74ca7ccc96036536a3c1adc7693ecf39a71339dd2d07c6994a43f35785cf44654ba3f9abd22947b4049be1a8e43fba6e5b0968030300466b0aeb2453a3924afc6a8b01421fde20cdf2b26726da535f912c12cdf2502f1b591eead16f0ca3dde87938ec98902c2c42801bb71c2016ae5b26313ab0e57d80fe0746dfd4021959e8a93b5baa20facfe55b63b4349a1ad5eed1fbc6cbea0bb71fb07563b44a6aafa0f63b13b59f663bfafaf790208cc4cb8415c3037bf4d9a39647f3e8434fc560cf37e60777b1e72e131070770f9e8a9f3ba4e2fa77cb74ddbfbf9d2bad33929807b447ffa396e8facf6dff995074c617c60cd630d309694b8f5163fe8cff87b06c52fd9b99bff93fb614c2db730719f33be4218350c756d2e08f987609d3c1398c2e5b8636b1a7e4b4be69888a0f27086e3f7373892b95222b831ee9a7ec1c30457aacab691c391870a949ca8c52a4f78e448434a2d4466f271e99dd59641105b0c6dd33ac06ae541f8eab8a2f576ae03a56630259a436421bf9320451276ad1dc2e93545f05f5cd7cf81c056c9d80bec943771eeee161af7978783a86d0067ad047df0401048731620090bec156db933e5b9556dcd300b8839f002569c248ae58b9ed832cdce327dd53780707710dfd53baf6e9f12441bca3913041106e3fe6a5bbd12d07cb012b759da453fd24ed994aafb4edfbb18ec9f6d89693d9e6691e08c0947c29c82008b4914db8c1d63100a6a414287ed08b3db6e57005162d961339e809efe0a09ea09ea09ea01e7ed2b5c7537807bfb8867e7e6d5d2be9543f96a44d006dfa1b0958c3093a0968d3ff711738946eb4cd638211e497a7780aefe829fca7535077a96b28ba9bf4926ea2533e3dd04609b4e91ff50a6e7fa700d6d04f7a0aef6825600dfd52ae80f28a828929dcfe118f274b50f93f12c32ee5006d247bb06f9ed0d10292d0038c61977e401b24f8206e3ea08d8c8f0541d4953dc4215032be48ddb224aaa65797957251b5469dbcb5d891a37ce67ecb01d38d8de2c98e44067d25a597b196c92e7aeedddeec1aa6224988db547abe31b489cfde9425086de04e9b40c6e6ea273fd187931b0919843a62b7d3bef9fef39fd3bfddbbbd23c3ee0ea8b4a894adf67441eb18a21108000204009314002028140a88c462b1783c1e89d2f80114800c7f9c4c785c9b89b320c7519042061900100000000080008ccc504d0040fd1b29904705c26b7a6882235ac58137bff6167f8c24278b1b39de51a0337c11a25e33580264107ae934106865fe8b03d84cd1e965713cb44e34555a598559d45415d77df57f2ab361db7a14f8d04184980853fa140016b7b5c340eece7451ea1506e404c39e68a3fc6353193ecffeda223092906812d0e42520d050531b00b4a03a047a919f61170e9972d4d773c63efb03181900583be2a5728f20b51cf59da2789f608ae4d9bfb5e022bcb93289d9516f6d0e03a56ec1d6e739476db785a6e614c555a95451db698aff9e7c1d425dca4454ff1a63b170e5c413c55b769afa8f493d48457a90dd642a358ae8361a29fa38013695931b2225395149d55739a00bcafaa4ab503af38cd7ff97b1804dee1ea6d57dc0a0e7f6117984588b50ff2d96706977809dcf642df6df7a59881fa46d2665501bbcc4f19ddd5b934150280ddcafb4173439e94f71026d73c129d1633cdc0639ca6fa80532dca3e04aceb9e97278f17a7796e9ffe25f329a254390d704876d353227f21702c011f6033dda555c43f57db395523be77e3280ff7148f154030686c8d952cd6244b9a4297da174c56b6b515a57077210e59aacd2a81fd342c55176f37370b44dec39d9b399d659a0ba4cde0aaf757639daa121006837f879e0a04e54f8ca56cd1287d3f252d454dc9cd41d130b1d36378efef23bdb8b56acb88eb277c4513e4828c8114b0096c2b21c7c0388bb081c59f4c8ac62f25f45087b6462b5149b3e912101b4cdf1168cbd2f6499e8b2ad3dcc8270b4a662d4f267a5bf154139af0125359212a6a5079fc20b5614806540a305f8d6b06ce44c938c47b79eb0bd763ba41d706f0e52fe9ddb23b534a92df090ddd40afc688c829869129e072fa2b9466dfb1159163f48fd706afc909d6dfdd3978b2efb5c9106120ce04ddcd9325e161097c3cdbe95b6261a7fe730dcb28600f631e9b9ba1cc33d49e80d1e4814f9591e71282407da9cde96c1bd9b47f3bcd13e3a0c97811c46476a0802979fe2766683ef98913e7a420547cdf87a0e94ed019db6b72185b46cc7573f28a79df9a68abc52494afe7299669564fb90da162177d723106d6d1423f0452144d5b9e2351c20d5cd3a74c08772adacf3937a2e45258a9d0f4dc3c7d32ddcfc001f48a4ea4c649fc4f3382234584d9fdf18ac1b43f4aa8270aa267cd1a33a50073b22d05fbb564077a879c957b1981fb0a29812a8af7d44c42376abdda028dc45a26bc4551f7da554645b75a3de275d22d4ddbdd772389659418713179e971698fbefa21f1e431669530fe9b9d981b19c7446cf2a95e378bc549a4601ec7c50512d87269590a16fc20d7e20c3ad019463fa8fa5260b872ec5ce2c829c351d3111d017597c2acfba5fc284da7c41648ad052cdaef28af0a5c426b49026903cf14252a0616f68871fd2bb9db00ffd48efd54151bbdece940ee4cf00307b0085ac9af33ea20c42ce1092343882cdb1895b3f6aa358c84914d9c5f5eaffa3f98120e1d3809bc2127bffb2f607cf10ad9056a3e4e171fa2858ea46cd8656e58a12eaeac666ed7e6982115da0399296d4e2c80e491343effafc9db62614a574dd1a486901bc92f1bc253535f86c7e0bd805d30d31e9013ede479be4c1a740f4070eca099d1f1aa12ec7b83e952b07b4a2a47aec3464e2e03548c833f47338c3145bcb02f47aaf4783374154b32ff4019ba998c4b1ab4e2198b765622944f11d4217993e438431c318f13bdbb234205f2ebe07414bfa0d1a50bf4429fae2ee5297726194de1b4d1a0bf55308003e837a97a0c1cdde1cd1378b49ea5c52d0c4dc0bd983b302df79860400176e6584752cc814b353a47049f930bd48d0b277badd7d18ae113d6a71d230beb49b488b197e27447b7fbdf10afcd6ad46f10d82adbc15960573908967627f7f35d0a6464bfcd52f3a4428c4c45721fe02acd72f2b8d81206d38b97261c2dfbc43e869ead04bcd6b50f3b6637496a761adad22f55cb015320b93c36fea326f0b323120bdc39d55328a00b66518f0b25be393681be955f9aeb6f7f29f403350641905fd9734dfff6e6f03a80bb384702e4da8b7d420211f1786acc317c51c9d60cac5b49e2dc30429850844a54948111a4f9a433d41adead56153213af68879ef50c173771079f2d41b0c8bcf2006e7c644a3726cd87bec9aadaae02219cb269641270017bde74805d17ab6e990ce1ee3c2676ba8fd3f4d7b20e428443dcbb4912f5c4708c4828b2d1057bfbf1a0e3ecdd8559edb4221bc1ae677e099bfc8af867cd6543cd6060786763d6d4b8e35d758deea176766d730e10b9aae36cc876339f183767a786fe1d377e1792b36954c7f3d2406b2145d1448f85c71deb3043aeab251fd6fc64f406cf7d89d01ac7666addb269ba422395604bee4d4dc9af82e60efa352af9a35b5d7c0c1134d938577cedb5cf8c8f42920d506a117d18f1ebad7ca78f34e6f571eb503c8d7ee224dd3df69acf32b841d138996225f16095f31916b7e5f345c83cefb4e0361cf4dcc1a21b8bc84518a1d8c506fcd3e3b1050a63062384ad2ec96719face3e6fbb6b5893ae417b9460737d3bad12312f336c1379ba16662197a7291d1ad4ffad9625b2790eaf9e5e8e9a4dd2df123088bcc0de680514aa861603b5a29fd724f946c0e41c291bf70104a09a7c3b4e812fcce774495d7d54cb5ec4b227278e65e115fe1c5bef92cde989fa6e96286922130c221b9dd688b162f924f301c2523f27eae72615a602f3e2d410eeb15bfc944955e73a5c9f2de24fd6de7435bd4563376ecbdff2df0a8683956713273261ce5461295fe2d9114eee2e7dc8597552ccbd77df0bc74150eeb4c7f7038fb59713534cf1db8807714c699e683ad7ed3840d7cb9efcd03464cf8ad3a54e18554e9eb7789898b2e9ed7c80c2d8f1b01bd4fecdb26b21004f7bb4adc5e37e0de347667ae073f98c8eb0406c513ae995c605116c09b5df11adb51a31160378c38c75e4668919505d057044065868d3687cca10568044107558f427b63af01b4ecd8be96b0f9ee9f1a61275f79b8eb30c90bdb8a9631fd34f1d5cdd7f0d532463c67422a5d358a1db80cd5f5eb11c84709351a13587207418e988fb10d605b5d578e128698c10d71aff221f3eada0855a03536c0c980eadbd413536c49823283506f4b67ae2e90a34b958fc7d1db3b932ddcebcc8e598c0923af6b239734d65939bb169fb1cba60080a0c6b09395451697b6238d01aeb876758f2a40eaaa3e6389c26e7f9bf469f95605e41a10337d703f5df63e2508c2be2186cd361665871bf065a2279b3a700dfe574ab09d8943d92418ee1c09cabcc461089ca817fbef0b34141178d2a3fddd50bd7e4d346537da88b85f9ab56685b78c0ce906723702d01e92907d577dd9a70384c62c416a8d9b349e93f7fe56104912af8a8a5c62272e7bd2d7b4bc291fc5b165ad4fe6addefa9fd3e9eff5c907b04feb02d8bfe9fda30b1e2f0eaba4a10721355106f99ecdbd6abf873294e210fd49d154c8b3d7ef06f150906e390c635a767e84db3f15c16358433f1555830562fc770015677c7895a044b580b1a0e58f1a1c06cc044bc36275600a7fc4b1c41827fb4d8a81ef070c42e34be5b49e20c5a6b1aa428e08da5413c5a01e6d43248d571e0a04e6ed65f5b78be07b9d80a86ee5035a7cd156209c4b98a0ea6eabe4991e776f018bb88955647a54345590159eedec86377d3e47621487ed46db240ac238973681aa0ce72154b64a99f06be1afec42aa6e29c3c7398fef01dfc394d59450ef4c40deeffc8d2c8d6849b3a8a30ec38648296be44d98fa8709cfc4615b5e277cc064952894c5731d8e3e8199db04214d94c3bd054724cb402c3d9e95d3828346e7d4fa9f30bfeef13791ce46f20ed617e42945f5a0016935266ed02ad7035878845ae7c52a34b611ce267db0c891b9edd8af6f87b80c63851df30717bc827bd7e6761c63b934a715916d9203fda3aa3b5ce5159832a598a8582de723058848aa8bf1fe73c13c61bb50f9f525a5f4a44100fd9e823a9f78919979f39616bee8cb29b1fba0b76c17a6d2600b7c846281a024d196540078acc69f0660bb4c5fee86156d165f0a4fe931a079ef424af68578b2cfd606ee01346287eed8c7bb08a726ea294d083645296a8708f9288b048076c34ee7e0bac2990bfdd4bb5f0e2203f5fd63b4aca2a06f5cc56fe314feffb68f1c15c784f675146d5f0a95e3fea28b3e21f97bc54cd992eafc86faad57579299df8bf99ef6799481725a6b68133b7b0787c3b06d57017d2ed99e81c8b0772da145e349c745536ff39cb56ae67c89251dfecc9c4391d7dc64abc627d3e2e2ead36880eaeb888e62291a972f4591b86c1f01bdd5cdb3a0ba68de6e07c3ce7b5b479421699d6820fe151b7493f99eaa1d8bf14999dcd94fc565f21dc31291a604c14a8c807e8a79b7edbc2ab114137dfccaf468cf301f46acd1e727f31dae042578ff76472ea948e9fd209010c8916d0d5d94e4710de507d6ca61181c168f5f26423aeb229c085e40b6779b081675158ab2de7d3bb5ae102ee3cc2fca99666de593ed7e9a0d45fcb8f36374f84dba840e78d08ed3d6d618f5708aaf259704c3fa63f8bbf0f2a511e1e637a3fe629c2d893ca611560e7210281030d07e378a2b5b9e92eb9a4da2e7b498d19e6b81fe4eed1e8487a03b2761ac00803798fb0e439f1469be0a49cbc08095307925d24d4f0ec8077328bcdfd3514a4712a4b2b600bf930709b861b29d182dbc5b30facc5b0e1915126b78defc195510441133c4c49391d57dc284eaefbd43d0f97acf840a85dc8ea7c986aae0fe6763c83d3345ab9272fd28efb5c5426b22e7d10db77b8137bc2404f44237fe6c4843d3236438b8bcc927b55f21cb7a55148b1646add6098bdf0266731b32eb2bd44fe3aa5f769ddc874352b69fa2b9887b3e95fb9a95ded03a744dc49391c92cf9a63c5db09092c33c78a0475946027053b47a53d68e4d97f590ad66314a598d8c8027f4169c22c9207b72024098a6fb9cfacb0d5c467ab40c72a24b364bc091af89f5fdba2045ff4e9844fae08709e371c5a809731e0d247853f11fa94a9a15536139ed4381f994474f0668a749dc40e4f5b22f1d9000c4de0631f54ec9e8a75daade8a07568c671eb90fa6b8cbab93c34d479fdb952187b3092087d58da3fccf438bd61c5e718f0909ee86c89a92785d396b49a17c808bd57309725503b2ad17b4bc427834c0f13936dcf61fc1f49a43126a38822a6fa4cc068a4c4cb5bea7e6b6331c236602f54b85166a0c0ae79d86dc823db49c26a7ba42e04810a812a38b5aa662ae387536a4e5e6dc58930854cef535fc49d9425211a18e1dcf50095929ccc609a0952363d68c8ee728bef55ed6460ae7b0fe111ad8f20f23e5a2a5a498a7d2c81b18f5549acda37d93ac91687cb27a3577073e6c5abf46ad3cf4c81544e299d6563e93cc5198ffd33bf4c791d94e6bcbd6a161e539995bb9ac116ef484460d300f7d93ad2fa5f09c9af94638e2d6e6c918f8f7eadf651a793879a0c5c4feaaff387438c72363708d6cef07659b0f6a8d9184396de3ff917d219288ee7176044dea09e3b5cdf6ccc38b9cc4b035f4da0f3cbceca8ee8738ec49d886a891d9072c8a467f6704ebcb44d83554322b8de73e00361b87d991f6a6107238f3ed06b4392c96b76d47200d0360ef0582314004d3879f928219f5422662d85e8aeb8c15d95e04586c1cdce89e503cf66f37fafcf2a4d049e3937cec745b96a40f5b6fa674fa294ea98af490099d838755a7c788659a18f456966a688bb44614667ae42c43a8bae1e9cc1132704fb17ccab68ccadc880611563a247a0218d6045420fc4947a7bf01649f02a33e4a6090a794965e240395e61f421a08a6dd4dbd1194c8d4413cc8c0bf80483683b705edd8f240e700a2e69def022514df5224bade2b189f1a82b1d57cae73266fde6597296b27763a9ccd995f0a356acdf16f85a0a5286b3aa68011c85f2e67380aa33845fb15992f66527f398ebceeb59e956e4c369e873cb14e4125a636ab794f1ebd939b27aa6b0722a4985cc113f26c4e01a104b4afc854455555eb7e6e8bf0eca5841064627751b9f87017f7511cc56c80c1a0496d8b0780a5ae043b5f14c6f5730c545526772639900e85793d060742c1eb4243008847f208b1506279c602993bc3c8da9281fd8a2367b5d892ac16db1a07ba94e6278986d804e6d2a2e7d123802677fa33e3f4745be9ffc1ca6868c8c8853fbc89380797dcea7025071fd3658f4e80cfd598764dbad72e020ebb4488b5fbc83c271c7ad8f9f4458f1606ab9ab72aa05fd501ffd962a298aec3a139fdfbcd25cfffc3f072427c02054be95c5c53f5ea60941a3826b55c873fdc377d79e9846c9942cf7d088ddadcd8b250ec44873554e65f3403de085afcacbeaee3871ff86ebf632c13486e0452732b0d69b4ff0f38417f17dc62804e607a44c6526f066905add9c47f2704434fd148150fa7f4ee163d433da68537c497ca9feb9ee4b0c62dab0544c4e97c6bae2eb4599db1692c0bf66ec7b12aa9ce963a831c021583b669996a068f8dd4d3e5defc8c93583eb58e2162781a63da105fe5668a67810819861d3e0a295620731e32b8f7b27f6050e98d94ad68d1a6271cbadc6f17b92f3635c8c7ff86a024af3018011e4f549997657547da6456224e087b26f9f3e9288e08716380c461db1a3d0790393018f16849ca8da114ccfc401e0ab6172d0a18190c7e5116e3ad51a4b3c97200633d6a866ce8eb40b0a5d0a1dbbfd030108af4622d4d43213283fad712379099c648936865c2d168ca92bd58bf3d908c1a4a0137115358f6889a0c8e77c555512627f8b21a3337f56daa944ee9979f5ce4da230d1381d05ac26e0f9d64cb1346acea6ed1486400c1e2176e6e2c092c26405e02f1609cf47c88e570ed1ab52843a65461de4c8567980e185d40fc903c9df1457f44b39200a1334dbef0e432ca947264ca8823e94e9edb8be52fab2d44ad5b1e416a5a0dd2fab443ba9db7eb843bc3df5162b5454d5dab0eb8aae60ee54c5e1238b137b8cc699132788f2135ac9ef1bb4bcd5b111c568e7b3fafd6b1202c5a17137ba8983c7eb5ee1127778799f631d3cef5b9790f1442daecc2c0829340843a300e6be15714e68656a44935cb0fd7d8a355f84802a7ef0c96c0338b219d2b0bb662bf4dfd3857be96bdb8fd60768ac0ec084afa01b791de91b67d511ae2e3469361029e19c2994f7f0f6a995306da4c006348a2978b7e5ef26b660307408555fb01e809a6ab2bbc84ab3380e052289683ea62173180bbd0243213ed0c40d916ba5779d475a3051042819987e6d22c1569cead69e7e0b8ee7747c96679527fcc36543ac59f0c333a081d84ddfb0ef9ee1fac2b626f0add7bbec0d4da8a92625874de7b65651bfd9888efa00d1ce0c0e8242ed84d0b0ab12255f1b7e17629d2c20ae2dc69b2dfbb96581690e1d4f931753856854ab866b50920caf0c2b527bdf7c519f1c8c8a104f2761b0316119116ffda22003b0f5887b02a214bf1eb22960b71722125ac2d24128ed6364210e09ffc3250e7439a0c83f268ba951b4911bc0f773cb27aefbcffb1648f32a9900268b211ef527a0cc728a4af980fe61151dfc3e1a93b426ebcb01d2cca79a80cee5532c866209413088f6a8f78613d2138255101c21085c5aa9d941f0ca6df7ac93702e6d2cac3cbdd688380b0db29a6b40b376c96b48564148cd55335b054948a1b8224af45f9fd175a47498d1bd39224a720140fbf30e8ece39da3504ea54f253e21496e77ae3c1d268a3a91dd7518738e1da202483d2589aaf03890de11f02f2a3aa7c67b60450e355e27fbe2061d59e1d33e200d86b9a44c6f600e76812bc9ce761ea7897c65816bab598b83f3e265686718e21075a88dc804d85771843506ce29e211cefb6314053022323f3f35026a46fb1476caac0a9050059137ae2069745b1a093a3a0200adda28f9ba932f246760238e58c9db5ad80cd8c1d17e783e96014ea878061f54629061ecc60f3c0f1154c17fa902aaef5b3180d1d38d8d0aabf7049b59745b214a06bf7b38cd40642b76cdbaaecb4b592bd723e4454834e533e2791b06b3fee195da7a754d655ce06a49627aea8798777e1bc0546666015310449ff1514cc18aa4ae358573830fc4f2cdc94e966e0f447450b6d6f94c861b40d9c1d0835ba66c682c13adce76faeb6a8b8af9acf3b5c7068046100b451b59f4b73798d38b104be8860eb8a00705c2a7893413cebd808216035b6304fdd1d279d53061c080955925e8c3a6aff9e56c6d21be3e9421d11ef168054f67806a85334d4ad016f855616770fda887968e6216614ada5afd036c15e010effae8bac39c68628bb9ed68e576a9480300bbc80f417df64413380cfb219a83e98cb7beaa222001ef3c55f17cf020d6d1a142265d1b7e754b60834a31226ca8059f01348cb79195cfb2e9626b10e049a270e45782b208111a37e82dc70630cc950aca0245468b683bc7afa00fd692700d8a8f34206f5d6a82a1158ac0e21d43af128d3ca681a8d400e9097be17e6f8056c27e5ae01f4e1f881a7c78d31caa41eb0ef865e3aa69db07ceea0eaeba8a87e2e586e9ab7845bd6b9fa1a97cbe32be25aca881b5ffd58d1e2c73ab9dd2e35f88225962f58b2f3f453dd753f283f3e2a74ee33499e5a56febabecab878ca20e9b0eba0911197d36d7575a9a1766dd1ffb4ec3240548180bd85a21a2485c5b657dc44049097b4e3c9455a78892e16284f655e9a8632c854b3050ae56184050b6caee4a0565d6d42440804f7fa69c4ddce87de4a25176926bd2cdd1095b97e3b6ba35aa8affd6740f69df91072861c80137a62903d6a834d754d521809ba65bf2cb3aa49fce4207f0c0410b6e146bde3e3d79c18a14b4b67754c1ed7b2dbe1bdfe762572574f9474d244a8e1140c5c3e5c8cf8f2f13f35bd208e8e9f746a664d82ed56474c08581d863fe75b023b6e317c76e2ef048589b1ad8680eeace30b6e54107f214c283f66ad1ece6721f382804d7a8b8dbe405ed5dacd7ea9b2cfabf67d4c4327a96f5efe4ace6a80eb827f858a8b786aaedf43d323f1614b5120274f0e22974f585e603ec701dc089051262b9041d6e992b78399472ede12c686f7184818016bc02db54710bf139c32db5e16c29049e8fb6a937331e8263154e9a3fa2f68277a6fe2978e86e64b07e53ccd24e5af725a1a25046b5edfce0fbe2ad837acc9782015e085f1dce183c0d9008d7ef06094a0bcc40094cec84fd69de366a4f8546110b12471f4af365dbe59b31b077e30d31f9b2cd0245b9692af7e7c9a8bb24e177dc555c2278b195c493d7cd517cb8898b7423a6fc07186fc581705490a15769c8bc7c2221bc5738f4dea5e15747225c9ac90b73837df8040e098e68e72239896775ab8ddecc089e2f7228c6c05b895e0549acd21e157b36cfd50299b146a4a4913d5c585da2e23f5e3dea571db848f509ad3b770068b0451ec628c43d4c6e6a2377b6912770c8acffc46b6181bd2dc37633085459d9abc1403e6c5ae8743a29015cd4d85c47cb28ba1b88b82c9b8defbf1be4668901cbef8c319e8e187f6127edbe55e10145fc93ae7952d62cb4c027f4b0d4519919b17a34d752b0de0b84e5697e837b41dffad431ef0c069c2eb39ef70a6845271b534b8aac26c3af2b3286b477462f189a3503f6adcd1983a2c6afb3fa79fb8b7c4916329f71448012e18421bdbd1fdc8bbde5a1c17e0a58089845ec680b00bb23c035efb0e95c4cd01b4249b1624340e464ada0ed1d4b848a64b0e23de78dc76737b7d060c0f6c6391e1e2773fa7b58af518ef741c7e928c6f252235a6d9ba51b9c6cc506348a0b374c62cf152533da287e636cbb88c7a51694e26c8441cd632f034e1f2861155d48d4b548241d474ceba4783c50bf4b8cd69398ebb6d64a4adc52d4c8eb3a5eda914058521a7fbbde1562a7496d16afb7d0fc9904e4a9d6d36817f6ac8367ca7816b2173a0fabf45b9815a9a1437b096ebdfdde8ed43117ee360e27f74789490a9061370da7ab05a82e29d95b099f2f8708eb001014b292668221deb9d1435d24068638fe4fc37406cea7e0597bc3e87e46d1c99f6aadc659d6d6fa5f7382bef47887a4bc790c2c67adf134a12a46c968f3322b7457ecab21b35e45d1d7c896ad8e272af12a6bc970a0f3e61dcca049dfab7cb2a152d37df34c7729e2f5069374f63f7efa4b6a0c459f87b9d888e36e40eb3374ca725681eaafb313da190e5de9890e3beb3a828796fb628b9efbf7633a10e4700a241f1ef8ad880f8cfebf4173946521811232fb30da3c70140bf441543a494753e2db390b80e19ce7bd9c5c2b3442249388b84db3f9470e71b45aa879e9ab5b62c9f39aaac025f5c805fb3594c0026f6974d134dabedf23c86bdb6be5b404a06d90100d7c459014c7b1dfbefb23ff5c79ff4ffd36d3bb5460572013cc0a327e1ad40e2936337e32a7989282358a320b8c93f2380a9ab128e6077bfca1d0289445a03ccad8cb2a40248588e9dff1961278c7a8d032024f019007097617ae4738181857e6189d9a0ae4d40be8598c6ef0a0ce9b9ca281f02575709eeb7bf1e625b9a9a2f3dc56eb3a94047ccef96909f69a9932c6e2443a188b81f543b099500e720639ccfb073bd034e6f3c105a291a5c86c70d42b9e583f0538058d0b224220b8b62f568f41ec666917f80f4bc72ac4fce270470c5258b934a5ef7e7aa2c5de863908c61816bea30e83232c1841c300847abac2a1a715e0bc48608aefb9581e0a00b8cb3d8278e79063341bceb2a1dd0dd9b4f64c57373492f8b2af51ae979343578388832c73293caf64a4370821c4369519c3209f0990ede15738ce854af462ceb6cc19237cc694cd5dddea60971bc8df80d80118c702e3e99a87f0448ffd56c4eec330919b7833593bbf201f8ac6a4c64968a09c091f4bcf220c1304cafd81a1cefc17bdf1944c668f3dd3c1ef13150c408a57683affffcfef003ddfff1f459057a27cfd71edaf29186a8af87ebb723d508fa8f54b6830b2f076b2324ebc9eb5aaad7172f1dfb7a1b8cb854d26b64d2ec79d4fd687161950573fa62d4d547e27dd2b68767bd5234a5a0074d7ddc186e49fb6f98422be692f26a2f6a822669cd3bf6fedd5220d656c39f0cc577b48e71e14ee9b6e792ee6836a529486bb19eeafd93bdb949b37db72697467d6773da516db6a6d5849848b64513ce4291139ba0122e9c6ad19306238f9bb5bbbd3dc217ee73b7ec72b819acc81d3a038f15d79016fdde61d1dc2e32d32c7e2fd0fad3656eac15d0ebf88798351e46a161f49c27cb29b386de50061aea1520cb53c99d6d352933337f5017d719fce830c5ecc492d1920ada03f291a73cd88c247572dee85f8efcdee69280cd9f6f0bc434c066008709acbdb5737b50b0fb391b20e3bade0d64ae0571a9f4becd12d1cd8da4adb422c3d31b6e64bf6ecbc5acc4a012608a237aaad00e5f34c3aa9e84f7a66e34be70b986b82782d0619742ec0f2868e91e00e0c8156eab7b69e0da36fa310ae3385b5bc9664aad6562af72413d7257b96bfce4d6aaaac374530089bc7a60aa279419057a7cbc707d2abf4c3915ae02acce2471c4cfff221a84dbe2db205e598236a0cf16acc9c7cc88226114a3fd4d5ea252356e6d6ae4d094e52fef659e1910982414c3430b94c8ed6b2cd8bca4510c16ae0ad6da0e2430ab1950939a27cd462f5217a15da009c78a41cd703ae9e00babfb0e7f78a37ae6235f1f761d5b232834f9a05817b1f510d8c0ebff7e90c92fa316af2168454edb4198913ab5844de168d1e74799aae64e5a8494fa32c8eb36391d137cc078e09340d548d5c8b1c9884887affd4878a84328e53cb3fb9a0f9421a70f9619eb12d1783a682cf7f1860352347be0a82f94c525cd92dfb73eecc767b0cdede203d19dede418bdb67ba9404cac246d4a8562778ab65d74c14b96ea7c15abc23d0b25afd0cd6f78799db33d525585143d9ffc45ef75b4742b57fa50e1d1115bbc52881ea2d74d8080dfb28b211b42cd77cba071e7345cab4d0c7bde60cae4b857cad1aa171465e8333cda5880fb019f45e7b102f73bfd73b9ce1c9d41db8f95e7b2ba7f9e995d111cd27f271d29118ac9fa761d2fd9ede41d538e7a6eb811567d5450ccfe8fa3afc0d6cf90aede42d3f6b517c69aa78d1145782db24a5398e565ccb1dea8aff53a2e1cbca19e6055d4da3c28a807563caa2371c05d44bd43a670d4eb3ee94e1e33459928719ca38cdfb617f7060d67a488fd9df3c5723659c0ae7f753e9cb4ef40fa466e1fc97cf65f48500e496a56a69027f4b1ad50886dfa00e2e4715b96f299623a78aba6f1596d350608376520a5451a11a767a2bd682cac25a0bbcc40da3effe18a9129c0dd869d249ef68d297ffcf04ecb03ed4e42dab3fbb03853c4a19bf6ea35020bc92d5b7f728ccbfcb7d0de85a3d9af32337c4c430cb83a25e868167693a7ffa021f9f536e74fefc67ae5272569ccbdb363fe63a74f45251952122bfd89c778004bd4067d50bc98c9ccd95767a175856644e9b3f6c573901e521a205b5bedc0f50ccc9ab3ff90db6d576c6494ce8f4ac8b5b176b77cda0a67f47e4cf8eb2fcd3cbcc56f05b566b35ac20c3e9e955c7d5ee169e5fce77bd7d9d89ece1d8ce393f61f44272bc000d45a79b671d6ee15c134458f4895d3782baf8bb62620ce7be09cbfe5a31bd02e7a99b33b0122bb318baefc2f692cd53592732fc057ec9ea949470b88a5b9c9b9787837a91f43c820327f75891d9f5b92db25762d6e8a42407f265ebd5e5ea7b8fa17d1873d451aecc06a0f27ab3ff7157db7f9c94a54caf095200b2664602ac13d9389da84ec911b549229371fd3afd00ab92068b119cbd025476f620a8ff4d8a2d47ff3973f0a6aa64e90695c1258b8ccaa2e3354da012ef178446efa736ab419707e77be3d3144c00a6a15cb0050deb6cab81fa4ebe6ef4b35f2c2deef57b1beb27b994f769e739ad1af200e9b04e2b3b126224f94f9a972ac6ba5b65eb98159dd0ee3951ae6264f09f32fc4ba822aa5f68ab571186549f32aff0886cb8110b01351d48fa5d48f883c0d538058106f137950c9c8240792b79ac7698db40ef82c0c5cdabbef7c006beb90ec5a2304f85af448e9620705177f3bd2532a3bacd44b4d4b206e896ad37226bfa0b481534608143f14c76548489d8b2595ffe95b07aab9e1fc901b562aeec71ee3c10c0789a8ec71318a01d647f37bc1aa4a65689aa90c07f403c3d91aaa5d6ac28b42d616ec60fea4b14e89e3bb3392c1e064ab9cb85d1ca3c0c71d17a1c76b82bb7d6cf4fdca6d03cef7e2cf3eb82893439c1033e975fc15fd7f427fe5697a5b71630cf38b94b1e97ad710a86e6bfd3056d74515a11ff8123c504c4cd845d3e6b0d80a7d2853175b7d63dd640cd231f71ad1d6f242e82efb254c06873b6001da2c622a9b5b979b0c5200a50da43335457d0b38e0810d29a36d9e39ccfa0f0c8ac9b0e62cc35b503ee7f60f6d8cec5fbb9164fefbeb11a84f33a8f41686ded3cb2172bcd3a16a3899948687b5a8f51146bd17e5e8717869fdc260ac83aec217fb77ce23d4e9adb0a72e382f25d04eee16e20b31b8213b60718d26e67febf57b8cf9c2726b3e3a494c5dd11cd40052aeaa6715268deedbbd060c6df9fd1ed8b9d6550529db9c80658a83fa012718b68fd06b32ce2882083df012112d81c8a09aacbd804a5dedcfd563569a8f74482fdb286882aa416d4205b3c4c7a546f5d0be3a16ffcece1e8bf370f15af846c50cd70135420b241296d72ff7ae1c738c230d9320b0edf426c9915a3b68960d90f761e5d3aba5dd262773352c749c80c717e4f96bb2950b5576fc2c391e67015dd3d3e22dd4520e3c2a557fbf07b3bfb14397cbed9cc0c2e15f80ceecd61867903b41bf64976d53c3419cac2d97d38f2e6a9c69defe699e93f0d5cb68f1bbebd752e1b4aa83223a8bb5e4bfc6c83613cc060495f1fa39f821281ba935664a6550a2d83ac49cb299560ffd93bb497d593cc61ce31c1a78716e5bc73a867783faeb0db235b4b4b1befbbdbf5e445d140a005ddb24e8a67f331a9b84eca6c98a7d6e774d2d37fe959232bf3faf3676a0bd53313ec4fbe0d84f7d634845d303c4e260035d2f09837ad0505de30f131aead6b845aab439a37a0386f7732f45669a270bf40f368a337a4d39b77180f22f0cbaf6f02f410cff232c497fd3ab2ed64d3ccf9ac067a8ec080801856676ee0b724b77a1c5ea047dab6ce71933843da053281110890bf3955df46261ce0205b0137a781c834b7c07c01082cdb9d2bd065651a119d5373c22d213c4dfa31a7bbeba81ee21861850f4874a708598e0f8dc762ff877c2371786c4f8ee68def2dc51324a557dae503f808f0c5c96e2210c4bb15a69177aaba1bec9806fe10d959e809058d8087885efa909f9086876dec1206ccd03aa21304ef64938a09c03e581f36a55e8129a706560c7b89887cbc4d55d3397864fb0f743106ca8963cdd33d19bc7521c9e3f13f92059bdd85cd2a119a973d88e5b883ce980e2f9d75f67ddb1f60a0b4374a73cfe0254e8dd6de9bac575123299fda924affdf28153f0783a439dfd2b376419f9121efd09c8b4259de95500a08601ce3777a5e0496f94014df50ac051603ed5c33a868a54a92b708fdc2781f0c2a6d144c97ec232685898e9c0b505383823ed3cc77036391517638634af5c00c71f8b5bd5a4f885561d41ef14ccd10e2b8d921ab2b789ba978ece0b3938b2e2861bbfbe9ba84a7015bf495295191840943040c4fff789fd2c0750a52c265f2e0e34a7a39d65a08d14db3739c1d5dc21b195bf2dc677f6989289c7e76b4eed292efe711bbcc5e186e1e298e97438432e6a78b4695de34bc850912504dc42189c2e49bc121c56d661b05fe64e09ae5960a9f8f1d94d3e1f1ca26f275fc1ebe46e78bd0f7e3c037d09f837a86d0a7a906de94017fa98d975aabf03e7aafe22b3d86a13331a155b493294140e2ecf5d0e94a128301c29ee6b6605c1216c59b710d497c558c01ef9439b44f5bd9248e06519f36d1191fc6be4f6ae50fd7568a3b32617bab7e72da1c7a56acb90a12357b4af5c7dac8865ff433d4ab21b4ae5c6f5d87057f654c4d95d752b055ad19104ac986fc799222cf8524248fda4a1f008f2d1c34df02509553c9b78396d235a0a458d1d95da346765f56f74af13cfb4ebc9651f7908581becf2dd3aaf7569d41665afe7e3d3e938ee2a0b8b185f70d7b9f9dc939c7cdae4c4afad2bf8ee3eeff452d9b7ae61c15d9c16d1d3a0fc9ce92ad3705880a000285a0e1f65bc801526eed431e3719a9e7f8c2a30df637592c9c40c55a9b6a06d6bc0617c34177e9374745bbd26065a257660a62fdaa152c6f785b7deb77037deefe8adde85041d770bfd7f96a6d9cf938752e244ccfd83e21014ad39a6994aca40fda68f73afa1b38b521f19107488978ba5f0beba4769bee67ec2827e5ce7c9e479a4650f4943033abed1d8a40ffbe2a5912097d3a10f8103a714f3e4e75406db7ce75ac1fcff6b18dcfd7144afab1addada004597a009891d0ab4c45844c821de8f44b7f7fd5c42d3812811ecbe86b22cda108f7a5333835dadba83add2fe2df04747bb04e29c323865df6f97a76e7267247f724a92ac4c3e81782b068f8a0ffa1c461dbc04ed74f1107991e1673c0694d14ea4ae2eee9948dabdca574d09cc9733220e4b77233883229ad76911c2992e45c49b9b6ff1097524cfe5850c55fbb11a5aaecdb3b5484ecfe330d6b9247614022d16b09c092ba58eaec45ead39a4c70abf3d182da91535c045d596936413f0ca5ee9587e11ad5a754c84d03aaa637213a239a676e6ff3c0835d2d7d08ce882dbf128387586368cb2062302744d82c171b3de933e450dee8419fe807a3745e6fad0f4d85046de58b121e039d950d923f47dd1b71aa396307ca69d078b47f6d2284cc1fec602bb484026790358e5815f326d514c3b552683371995c672b4a205a1161f2be2a0058f0b5c2d1537fa8c3f4fcb12ebf2cf17034774f3e69554909e80226e6d28ac380ff10390a7b55e2954a86b306bd40ffc62a3962ea09f5599181d4e1460c2f8a39177cbbf3e831d78273348fa7e645a2c5064c9ba31e557f8da5998157886d65d728c8dd0e3ca5c8050f9d6d1a291abaa824dff34f1fe84cdb186f3dd90ecb9d1e9daa2aebd812a75d4334375a218eb026cf6b757c7ce26b1194484e95ac262f0f8278135c0de118a7e3062276b82ba481a716d58796d981adcfa15943dd850a4a77ac851c85b237827ee6c57a2b72a782526d635d71dd5aada141fb5faa0d344e95031f8369a2a5bf741c0eb568bc7fabd59d3366de42adbd7873cf4e680ed58092977e77d743dbec7f348f6b17d17ab8e054b727b461e624a00497ad470a7433f62a538bd3640f059c08b92d7a1b5b781487c7726692945fecaf3fe1dcd725d184ab938695283a9d2d4beab3fd00b7a9985502c2eb9e2e5c722328fa13b89b28a5e69302094fde24cece1d177d13bee56431a863a001d235b48ad7db271c61b2bba9eaa99da2a34ae43bfa6a8c84f312d96839281789a881cec62c164ef45a961081cfd4c6bc60fbe23e08bea1f64683a17f5a9880e880a0a3b4a454ac2592556fd6d72411731bb68f50fb08df07dd76ffc245ea475b3baf74ec7a2a8d888a00a61ac62d8e2fecf1ea2c49dd794de2079ed08065806aadb034d84d1860626ceae36db37afb1405c0e2cbcc71981ea5c10e7258bfb30966d492878a76f253f34aa33a1107234d175e8728cf5550e2226d4c825242045f1415df2a4728b49617413ff42dc55b00af15998683d076a3031c2b0d2a913c5995eeed956b4109f734ab3827347c3bd34dba461e6ab8981175d148cc494183c0a8e597359d3ecf40703f588149bfb750e0fd832a1050648ad09135849b3e030844d778e819a27cc64d9cd125365275c2cab975d73d72a724ad34790507035d34186e030ac7a10a53d127264410161db787b4d384a1cc2f2fac8bcb9debfa5b9b4a422a0b71b89296fec48580ff247dcf41ec3e9ec35132ff5efb1e8f1366d416114f7c4ae3b5005e92b9429942ee36c26ddb3dfd8f6ef3863d2e2c4e3bf736e82edd9377aca3cd9be8a72ae7db943ed460e497cf7a7104d86b7b52d7cfc402ff7ac835aae86ee4c0e8133e177196a1a0ec0246075732100ceb30e4c87c86c8fa7669653ddc01f3625582bad23c709f6479047ed15817e74546fd1b2735497b4e76934d81051048347147b106607293c6386f7154490208f54513ac43c446d07dd2c174644e76209c9d2f5cd3be121d4e110737f0dc22983da282e81a1ae16ad209b58ac61632f2a011d3631a6b83757734e916878cd59fa52dae5aa1e14904848e6d99a95ca4afb727b3023f8287ae613ac1087237ab262a52ff8c02f62ab5a5efe6ca13093b2cc9dc3e1d96026b4a6592389f224a7ba22d180c71bf1d12577e3547bcaf261327a5848889d68d7e9c3dd4e587d284e246e630d2fdfe54bc04a80c160b3da65be8222714f87195afcefa5188897fbc9ca810b68184c3c266069a96e04c925506e2087b04af3d77ea412cf72e7592939891d4e769a3a2162075b1d0516a8a100e0356e0fe6d3ecd143adc415577bc879974ad39fa03d0c1a49a9f9bad806246cada88945ef8b8101812e514dcd3e40be040cc78fc28db7f4ae756b788ed145ea262c574234ce6b39617640b109e1b04f687956783766b68936791774ce5872a14f957f79a08a6dc9d03a0cf3f078e60ca00eb4d87a059e11a9a6beff5f84425ac4462f8abd4f2aad2338678f2a9e0f29d3640aeb6d61b8892267467d642325b52a0c0e16afd8bc5d1f818887baedbdb0a6542459f44bfdaaba930c34c5781c2d7a2b3c21dc0306b8451f28fe6af96306e59963cec61bffa882d8b93699ab734fa5cf0b8ffc2fbf6fa7ec83ca1debf4f76d1273660dca04891c1838f80c13360b40db8847c7d96748430a20a6978780c3b760f0dbb6bc6e5afc847c33024ed104b62587aebc0ed2961070c3c76e7dc469cdc7a2b184a112a0dad170b462f062497a9704174c6df809d9bde750c64e66c0447967f71170f05fb6cc256965c6729fd6564e3f617d545d025c9fd8d0f4dfa204e347ff7f451ce7fd4629f8d37e9d6900250a0d3a1a6171dfbc9b16b5e42d7a03922e6b85b1b393a6065513d13f2cc57434a946991c70b4db495c8946963a091b592b6994a080596c7e8152dbcd52242b56095b197309661e48ec07076b71895388749cd0ef026a39e239d09d0a21d459e81a126d2b704fdcbb9867f53f344e346a7f2f5e6cfb847cea23602b8780fd15de751d73e6d24d21d93749d94dfabf3766d272dae04bcd2044f6aedee1b90496413d4480f310a29aac5903daba44483e67e777aa4142a8319844611134660c2d3aa71256843814664d521b5b520709692e2e009701868eae1746a1ac5e1da10dc95aa220cd6da72f83da92acb59faf4759766249ef12534caae3e7f9681974741f233135fa9e96b9404109d0746ef1308fb90bd1ef702621acab2acc58db83cf3e6b2a244246dccd638cdee9a4b45b14bdb3917f13e8ba19b9a5d95aca93b372a05ee9250b8b7c211d3d3fb69a6ef86a102f21f78a44191bdfe2c2233c4fb22b01099b11b83ae4ef981ea41fa22ca6f7d7ae485385b9516b7479c2b808d5abb29b7e9c1699ee85a712d651173b7bdded8ca1f4b503e29d3744a8ad9067c32eb9c237a40ae016af26af0474e9165e803f6cb68c6f43af99155017aac4903e00d8acb23905c59458fb4e0caddacd475fbb961488e97845898ccc2cb39cdfeef57e64cb73592d2863dc9eb562f7d4aa38deac2462d1935da21115cee1f30781949d9108b7c1f4c85f96ff9a1132bc076e9d76f8f726bffa98c35b6a3e9bbc333fb3e29c9b9341ece87e1e24437fab1fb02baff0b44e9ec4a38500d7347d934d109787dd168896c79a66bd0cc66561f58182d0e8dc15a393154264120e9dcf8374901c20d77a204f4b5b06fe64f6277caa8793316ddfa42392bc2f24d4017b944760d973a0708e8623aca57e91dfc8b0d3ce3f98b7adacb96e81b23958c6e041b7a694dff49cbbb643743af9270c5ce639fb3ebfab84c54877d4d4ca794148fc8ae60790e3a4d7918f178f7253677c1dbc9d3ec6e823e0c10192faaf5d3a8239cac0ef3642b926cb4909af3af5a9095aee99cf9a6a2a3b33396e43611ac2e1e72297abe8072f6e7c4b854fa8e6c8c4e028ec6f66d5635904a08c274972e8f6ed119361f00b53b6104e37e19f5e66a5fdfb2ee1ccd6649dc5b311f54851375d1f1c337917b8201b42ab2127fabb66641b4d4299792f20347b189bd26232ec996866e6263d649c0ff30bfe2fbab6ef2e630e00a9eab936c4c803c563977fc2370cc6d516cb89bad1523c05c6eeb6b840df47ad9fa2f40b3a708f71889d073d25930ad1d1032ea9d41889155d38a61ae6eb26d243b65bd1a53e047e4c58ffd72b8b37f31b7b00eb82086f41ab123156130041da030ff0740ac207907f671650b95ead6a8a79dbca551b8037fc27313cdbab7bfe8c834976fbc678dfaf6468a140a31587ae9e30fdfda0e926278548cd19809b6266c6845f888c7163dd70746334b10d68d10c28619c476513b0c6e5082f7b0f21ba9e364e42282014094a155c728a7617eeb17748332684b10067cb00c98c8b6132555727815f1c5047d1accc14aa04776cc8041386fbf810c4162a6ec807b5466a647c4fb05695cfbb03ef85b0558db2b7a5392ca6ae03dec4f05a7b962da4daf9c1db0db09430f015c2a635f2892028b7b13ea8b59ee9f72daf4ae94a5fd79321153eb2b0397a45b71dff91fd6c38309462acaff01bfc79fe5dcf18d282c339eb12d4a68321d9cda5bc0a4a65f699de757e17670db8c52be01d7b16b228922305ab2cb113ce268c9360b26c039b5b06c47af07b7338a1322b148e03cce5ccb676a024c05fc47b1e327d97de5a50beabab482fcba34bc888e2539aeb6d743ce33482056071f228688b809e142168f4cbc8ccaf02dc557b85fea4edea7bab3f85b52763e99486eb3aa38486f0acf6348c45e9904b8e7bd91aeb859189427154daf26f0028260a92acf8529f6ab2930f8f85e6d338108430d1642ee32adf43308f761570182fd751904ff8d03bea74d0a568b8b3e50b8d9f2a1b0a54346190e50a74f4c961343cc2eadfb0b759297894f46c61165cf6f70f774a086671e12e687a9cf31cdb134b329c58a261beccc3c84899e426939ea71ee62d620664f86de3d22ffb3d0f51194bc93f2b8856f7a207abb8e87869c9b48161961a8e6e8cbc2b195669ff592f4199ff6b8b5ecc2e24be54cd787c05db6060dd5002ce1d66067ca381f36ffd34a65b2dccfa8ffceac8d13feecda8470ea16cff334a7a929689680e582f7c6298d7947babd621288f50981689311b2c69356da0dde043cca384ce7d64321164f070c81cb57e6e750c39f8a22d19d3e406d4d71613d14d03a89d38b24c0a51468688ffa06bbbe61507324848813bd23e81479730075138bf0db5219e75b10d1f1919b489596904bc89041d896cff2b0313de34678c439c71060e62358f5111af352820f8429c03285c9a757dda1b8e2194ae47e037c69da2d0ad9d09e9b2ed22171064825bf2350d1ae7539edc9210262359a4c149feb05912686a5daf8abdbba400d41f9980db94a9a31a18f9869f8655c012d23682f9c21b02db67d6931ac6768d350052e4ada6a6b1c70482b49c3d60edd173d524a711ba0108dd49397ada0007577cee2d7a50d4b319701e0202849e282d97da393a13c654dfbff53a4af1ff7f1a44e850c86b6fb83c9fa0633e87d10723e8b832bfad81405f03e880f90204d5e0f86321727763e2bc0361847ed50e33882de20d496221c68cb15d136fcb949e6fbf40f9e1d363f181759b37afe74eb42c695a84a3575d5ab6adfa4b2a50a0fa23f4cda9259faeb2fe5865c9c46b251c418b7f6b93a3dfc0bfc68bba21a6ac784e42c3ca6154a8c9b2dbe152acccb8628776f6f9a3268cf65ad8a04fe22ce1a246f0dbc5cf0dbeaf2ce1c344a50a25263e1689503e929b692fce0bbd43d6ab364a514d28f61b1a7bf337de587fecd2ac3964e8bc1d7b1eec6715231f8b0ee96474584c9ba702622a1349a9f6972febb58f6e8af237312c5c98920414e5ed0ba291a1eb77c4348014cc83b430d14ad7f757e222c60a90bba02936eb793da2574b67b27b0b614e8a368fda8cd686feaf54a1bdffecc883a7c833e2992de0411bc07300b43b3ee6a65184d086a682001e71a3cb64eb94f6fb3eb9a2d01e32c064012f025acd17c7d0323f13a12056ab0850e7b3f4ab8bd0714e8ca0147fb55534d64b74885ae8d12afa43e0adb35ed1240fe97d0e8e3b6eb1f62b1e31c544a583a45ce9d04a185d8a41ff6495a9b216f221a36e460602d796cf6593e31789e41ff634aa89e144433e9c8c85cb20ee4f47350452a0aa0760481467261724312771dd8086c43515c5cc9d6406de2b60826f5874290de1bd22048ff188263a79f8b3b71a5d73ee2304de8fff16940a7e8c881e885314184391444449caa496329d902ed4fb5bd55d2e494438826e35ac444322378baf4a84e52bc104a8355a986840e704104bab6500b783df34cf1151d70795ebea8470eaa3060e84233fd10de8ea14818c918d40a6b4891b12aeb903031101839ed9dca8d3c1915d85126c2fc9daa3d9f3c36b7d911be48ebbe136fbeb82871bb9e0c8f7691130e5256c1c5079748b487a43c8ec1c8d43c89a614ecc080398e80471bd43a6d92e6361a702e2158cbe8f1acd085a0c02339a097631eeea4a1c8c2af4ba661682ba87f2203eb04532886cbb1f88a70c85de8bd8ce06ce9008333f54abac079de54336eb3bb935713c33b1f6869c90c312eed32b95ef72d00ae799e6d35d6ccd7700531bfb7b2d57163cfa1ce029c32af0862ada1f8a4fd05a7523dfca9b973f9528cd4f106c2dbe2e76d59ca5b0c67cb696176b239b23af5385313c8350e67d79dccf05dbfbc3f763fb067fc7e0bba8de779b143ac4057a8dca57c980c421ee918a73038b7e02f8213a513745735e5e8a46883cc448ccf178d303a381d93c9e05a38182225346d3cae1aad4ef1122fe9576e7ef7f257eefddc8f39ed153e28bde48ad963a11d5f8955a435cd6a5c7cf09437872e0b0c11300d11199d8a01f77f5f5ff8240223a1a4e6b3c3b53d719ceb67aeed8cb0aca9370a6237e439980bbf9be7bd395d8509cf9f32f9ea4c49304de66a89997d89d04b9adfad6b331ab008d54dfa8fe64eec189c7340f4c2d402c2c9f95d5e65306892904e3656ce365e53e9f4f8e4b25113501b0a2e3520aeb7d11b576358ab3e43f68e5018b753a6c45fa0886b2c64108614b5c9f0e2683fb24a8af5db8275ca0259bebde722965953cc0b70d236150aa478633f5f970b7e3c0674a3fc7a92168cdcbf2b108264b7a9b097ba4ad852b43a293e2963863ce2040412c788425a40ddde4b366f3ba02fb8219549a9c9abc107efde8219e43019397246a3ed69afb8541a0c2847fd408780f920dfb0d127ab219eada7693fff71510a22160810e983acdc6f45b6964e1d40af0e98715a3c16032c936644ae52e8711d9948162862c8a849688d24676f90e123f30e2f389e6eaa05d4c8a52b4cb7713459c610be76efcc6fd318721f0fcbb97484aba43dd2218449080a372e32f309b28d1ff7b4fb83a9aad069716307183fe3171c40f15d3d17af50575d00a69d27e5e3cbdf5441e3fb6a4b4f314c650574456bf48b628463280372fdd6fc1f7ee26d1864de0f49f51cb4a546379795af54783fa9b6a4ef2548b8fd269eee9a58e146fdee8cdb6fc5ddb9ae950d816fbcef90d40a201d85cea91b555c8b24e9ace0e1ce2a5bea595584e9ccaa1bc0a811c96749fc061008788b552092c22112e256d8ef83506a8174a435c9117be50e3e4c814abcb447eadc7c31f37f286a1a3c9f242b838e39ea449d8482b9f784d037076bf7d92473010017acf64ab8670fa618ab8aaa21277b6d61b61b79404bc62c07d4a0c38b418bdd9005ad2221f06440923a611c3838588c8a6ad8cae5b095d229e5835064068f016a1f3392268ea634157f7383acfa689096506f4a5ae8fb57017e8443f67879edbb2dc5b6be540484a309590005afd7979a9c237b84c0fc172a4899ecd371a0c899c0b19c2b6488bda31e4140ed8ec7f242ef89be8a22fff43c02dc202380f01c59bffb105ac3dbf208392950f696fae4d0ec41e38e185b1f82ecba5ec42fe6f730983dea14f6d73be3c40fe0187b2b5bf353924c963629bec6bc0192ca088709f53ab7f1c0dc6be2cac60287860c4a41fb0e5163618d7a0805e876383a91ff604f7dc11c24e019f0881bd11ba09b0bf3a5057bfe2639534365a5892f8313bdbc33c9c5d1d891f53120381f5713d9426f2d87cd107472dc90a3c1ac8a3a001582fe10a2d330c6e8bbbc2f39b7c8fd4238a25341466c74486a4196536b918e5531909d6a305ff5f928714671a38c9b21e0ebbf10b022815e5c2208d72aeef01a048748f8e008579415afff2a7aa1842e7e469c942f8d83ad8ac786cb05472121b6ead4e3ea339dea49399dae5febc03bfac83916ee1043344b445089046f841192c37f60b10a0f9e907215c7b06196640176a2857549b718796d65f60f1c324f81c395dcf201e24d1e5f52ad055009cddf1257d9d3e2b8a6101bbe9a57bb1236f6413d88ad3bf4b4e958b74eff3e8e9105c34a03ffeb67da9f38705b54f2d7f38333d6b0cedfef9d4b07639ec8c06c5be543f4983b64212aeb86283c369c1b40d5a4f76549e872a73cf8f0574be96de6f545864d707fa61f90db6664affc333fe316069b59be9e5be01ca053b79a3e1d6423d095bd64ba084f55a753dab8486f30d7b6ed3f475fdd2a446800157bf0a9690b8d07427b850c5a107f509295a4a87d2317dde564662f7128b39b7d7fb1e439ddd740321b8d51aaa5a38427f03ee7808f426c9032adda5ba67048e2405e0f314312897044059a60240f14fddfac5a27e39b04b771734efab386ceb503059b9f4041580973a3031c11015d05a2f5ec66322ff68c55227196e95dd8ee1470adb6baaf26c7d509dd4011bed786653fda8edc5f83c24e58b9a8a2293f010f7309a960ea395df65b8aaa23014e4f5c19051b572b499103214414edb1a6ca65436730ff6e9e1f2e2700a1a1b3bc26d73db140948f32f316011728e4e412f725c0fb7b2c4816658f8fdf57d8a886f320ffcacac96bd00e4ff20aa0a83cd79ff4957a49bc3c14906031fcba076822cf0d9a0e221c6385862cf32fbe9633a5abf5cdc340384df8032c30121b482098936822b763d64c6355972fe0eced4ecf05c75771f67989cc7fd94524efb26c97340341fd34c788fc04fad8cf585867659a2e72a9c47fcb7fd6b328ac3671d40a4ff13da075b8b29b995735cf5733a8cd8c1c68ef12f2adf4536f703e4b4fde934bda8ee6ee366d8104f0d6f5648f019eb79d7f37f9e8c88661896d9f5d064bf855b1804288a016a1ceacd92fc64d4d262d6dcdbed7de47c39fd78f0b76cc7f18e6d836c271dd76c10811bf5d0c936f59300cb0242a6bb9d858faf8d4af14066e26fa7d8fe617e1768ed271a14c1fc98fe4d07df3ffe3f1bc25eaace6b714cad0684ca89868d7d83986f25a0669544329d536a68194abe9e8f667088a88269214405c330be9f8b389695d2ff710a3f9ce7696c1c3b5c9473e8499694fa84f78060bbad45255b1026c1c1486a3c338c90afedcb0d1260f5df7adf17a2444145250eb2b0464f51232855f65d3f17c0df21c99f1d58943ea21f50c83ee1af85b326c2533949685108ff64b95ff0bb0a959b9d1714453b760a5d69bbded400978e95624521a16ce5e811732e27c88db762b59152586b8511a8a5772392a1d93937427183a192e4517e60aa8ddae120314d60d24daf40565c4d4840b2c774614565bcbf2d2bda88d40893c3267cb8d6ea5e53fc6c7fa44a9f4d81e45b42ca8c16616a29ddcb6c50d3a8e53e8b11fece8f745ed38865ba49ead72484e73dc779bb791f416dad81882946ad12025f6b840b85cdba2441ad84b049be2665a34de08b7369f663068407e99e75422013d0b8968ca32d149e98c431d1e0c1feff4ae3ea6cd8c67d3d29e6481f8aa3956913d227ce700e490bac8e9326b9822cda10704749dece071829c45dabc92677f4d13a6c25aeb8968f008c2d6b44b90c41dc035e35aaddce876305989dde76679a0a4ce987d8fd34c657f3993f7e1d88873796649ba1f5dc5edcce893d31552b26956c6e3d5d7260b61443b5994b59a77c76f16a1412f116382b882a125b2d37e10fed653741b45fbfd425425fdf4925eef8a0922de5400248a6ac33bde76cf0608b6737c50c28cab7d189863f3b8444f677610762ab0dae29432a01cfc871863e6fd549217c48159f2f2546c53377d8e82110a239cac79e68129b572c07d0de05432bfdcacbd51d29da7052b156b24bff53123918f4564ba8ff84d6cfd44aae6920a448bc781d343103995e079bcce2a25c40301764f38c79f3927b02f080920762edc522727c3ca3cb0248dfde25342e3b5ee5c11d8536926c6e10b29b83ec1b3a6d0f2cf435d4c90313bc2ef632c987292258775d17150d91428b8664670153f60a7c33cbc8653c8090de1952c43363a6598227178cfbdd2f7f20273995740ea228e92457aadd264df4990b8afce85011e47da0d159f232c789084adee0e0c88e160d68f4a17ef1b34e7be0180daec48834e52e8a5b4fca13a246e4a0765dcf8862e373857d14ef6b96d268b927d143d3b88e5831d6a95204116717d6df7638cde13df6455e1b5563587d94fbd5f74c26c1ae62a19b924cccc7dca38ebb428332e5e471145d9dc8f9a029583bae574143b604d71309cb1165e0bc16c30f3ec6a9c834e1207268014e0d70cb7ce6f1af565c7c6e000ae39c8eaa7db985f7327d39f06516388a87dc9c57a03c11792cd5bd5dd625277421520707f7838ad27813d187194210fa2d05bd9a7b807770540d084173b4ac914d2abb508695af5e850260f8eab11005aaa0a43fdfd85c7c28e65fa602f2990e9cf255a9026f8a60a3062e5db8ba08b93ce1e84159a58b9a8f8c48a1d81685dcd0940ab8cde03e5625374105792189e4a641f4ef9fc1c3c54844bbc08cfdf4d96d292af90c6d2799e03d391ae1f1e4112ef79568815b046323bbb781757444934a4226d9de85a881810743b15e5eca1223b7e179180cf891604d12772d299526bdff97bb9d6abd13ad38162f836d69eac2526543e02d911795720f693d7a1fee16231e84c3b78a81253c0da714c4570ed64e49ec4a0f201db13ffeae4ed24d99fca38e34862fd27f564117d71c7fbd6c896df576a5a2cd9622bf0146153cea4ea175f6025c3b7b60e2b882b06ddfab0343b2bddd534c6a639d353216f6d2d43053223497d51f3feb6c43a3395a868003a73e491056cd6464ccf8ceae0833c96b247cf718b38b611f38ee3bebd52cf5f394dafb7b5e8f565869ef75e8d6a037bf9f541f67cde44f693bc8aed29c3f4413fc654d306ec3210c7955427251c88d2fe4101bdcb2661a3c19746dedefcfb762885d73fe42cdc159fb8781bcf11fce953a11e36a0002146a377dd0390dbcf5620b06df8c6eba4541de421dcefbf5961b2a9149e1765d4cdfe035d6dfbc505000f75d7b9036945dbd42ca957cb4a1e4d0f2a88d322765d57cdf76a508efac2d66596e833267837d22580961a872ab9a79258f3f170ad155e6b9c87d7d0148809a101645293b6f2b182dcaad51e08811929af3c057cc6b084999660169f17ecb17130dee0da312ebc882221d03dfc3dca03f11d25eb19713570bb6a11e26a9cee728461165127e59ef89c543c3e27d10b2802fc20f4574d8f040e333534465c7943be5f680a23f77f8a1173cd3e3aecef060c473d0302468800e62a0ee91474244bf98f5db53ed991957e7e32552e34b9b51c0b861d8a515755db2e868e20739a80b6a1200df0892b04b78f4d7a21c0e564e037ebbf621842a81630da474f6c09cdbb8811317b47faf9aa3b76edbedd0fbf427f6053850d0f09354f1e1caced345db87b43a4a9c03df84a22491c5b018defac73cc552e79e89602d2c8bb1f49e699f2c003aac8621b3ba2ca282aa443c6d7477edafd8419826cd8cfaaba294b10552bbbbac12c6dbc141d9cdc0f003b04745ae1f6b2537502c0a0ef19223e89a9965b273ce3d65c78c03ca540ad3391e255b728e10fb2d7f2d56a481a9e1740ef0e2d51cf8059f928515656d3a6eeb3f16933a2db64fec3cfa89c32266f151ddb2a4f2e16124f8d10697dcb5a41b56e09586cb2f0dbaa692179d7c8c3082b85ad92f8c696e452bb01ac768a7b5aea54c8466f5401f9fe28bb8c647b97cd2b4aea5038ba05ec0ba1d38067e40a99f3918502e1c05785f071dda23390913872c638940898d9ab51b527d7cfaf6610b3c746f68cd269f854985288413b6eae04de6c67de55abf4b96f3948e3e775ed5611058a398ed824546ad1deb3c8c9fbd05395fbf07e652df063014918ba91925e16de4972c55e3e637559d5768e718cb467ae6b801d36248667c07527490028c4cb06b0c58e23431040bcef40aba76b2f8a133fc5b80bece12b20cb9588110dc78350e403fcaec41af3e731aa749847fdc4c296852220aa24fdb6eaa9001709eb814b74f73e583947ccefc7454d6f381f542a7bf29feae495b89ebbf2ae03df465c6f6362d3470e4903d51874447ec5cc9b2228a920571718b9175bfd9a521370e072286abe122b406d78376973b317c5cef8ac4720464d5a35b863b349bbcd9bf63e5164b527e7101bd76c83c6e7b06109847b7ab6ff5a10d3b08b8f6948e57b80fa556c9e451773ebaf3e53ae9fe4bdca4fd5c43f7a3c8dffd70723ce63ed85dc738b0e9ac8056d7d3bd25fc139a94d02660e46dc889fe9519077d956b6e1c6b00be856c7f46121572095144ee00c03cf81462be97fb31385c40b24277f8ae8f15686e1b9f9c1f49a75827c90b38c6b3d64b144ca99f147eb67069f0ff82692cb4623470410cb333c55035b7dd5bb33fc0eebe6034f7308d0844c60a064e9e161928183ef4987cf9cbf6b0b1e8d92961644d88051f2fa7ea977c9bc436d0956d409375038b08d140651ddb96195927ba561049155b451de0282b2a4f74bd2e78d591ff4989d08826229520e0aace63d07eb0557f50503bd617c11bef86dec519f61c13690e23eb05cca6fd0a5b0cf8ba37704840354a8a86368488b7e30ae0ab47487d1d5ad117f18ac2417b0a4f0ff084c6b0b3cb686c6ac155469e6f3b00cc88c9d8443088665cc85dcf9d7e1c527769e91880ceb2515263ae6f2a1339d72125c428c1b963375eee54f0f4e676269ceb9f13ea6a102c58a09b07fabb60f6913ce3ee145c6198271f60b70e2af5d6bd6c0284585498c8261611e9334644f90f9727bb8173563d0e6bd120c4745617581810eabf67cee0d4397e314bef6e77463688592102c6e6071f5f3baeb135059ff6fa88f83bbf0c70eb384893aa11a9e3d33fc7dfa2aff224f2907020403d8ac5715b4e8e269141452c2cf609652d95f96a9a8cc75e523b22fbe03be0dc64308e15942830cfbad77b70845cd3f54b05124558c0b4943fbf2fbbd7869e36816dd43fdd53beb851cc4ccb5d6c7f2196077b8f2efc1a30beea6bdd0ae9a5d8881af261a8d32e7700975151172d331aa4a8614c016db3bd372f1631677d76808859e76f3e323550d88a566f21ec890c04e688dc5181cc016e369160d7ec9ee0499241b051d14f74f4c5f835fbf647222b46cdbe1c47a440aa2bfb9344c720076ec7c6df07f0f97fbce14f93c4e8c1361cb8ce7d645e826e5d3105a7e1b33407d9b5ab5cb7f319e3f9c39ceb69abc84f10c3c5cca5843b5e42f644cba1bf26632cc411c7206946cb98290074e24ebc4b854bfa5a683f870543754ff49bc37e8dfa9ecda28d6360966b055bc02f8962c8a23ee41075511304cfffb1e30e1333f35a5ec712d7a25bfde58a5d8ad882772bf6cf51773557c247b7ff78c659dd1bed122d90afb9ea1aba6451775397a20887e37765c289ca2c61f89e94b80ce45d3dab226ff9e055d394e164c8322271c0a61bdf1435179b366452dfec38d6601e2ea2f06e6fa2a6a5fdfbe4f98a1fc31183762f56bcff9a11bff0c69959146217b884fb9b9730b7724b7ca00776be5880e122aa2644f2df206882c25e0943305989349330b8b28dc608b7e436349fd5afbeb9e38b861510d2268dfa888ac81b98a3d80d0e2adb173c61fd82cd804f041040a33b499fe6fef1cc1771d9e1a62e364b61119a56459de9aff1b5ac7330763926166d22eb56e1ce4625dc5614b109306697862553082cc47a05b1d5a5618fbdf719fc19beaf55fb0550e40eb8eaea0fe8ec143ba8dba10158d0ecbea6626a114582d90c38d920e070540a4b8d2563e0a0b5f9d01fda403fcec9542e140cc6485ac42c49b404aa12aaef470ba4ae87c74f47cb55a620ffbefab69caa97f556520ecbe379c3b61f389215c0205fe46aa71073cfc8e96f029f760959abafb001b2c82666c39a5550c2040192c80742ffa0f65fca75ada0720fc8cc6bb71c666d524a0f7ba6cad7325c07fb0ead5ca0c0b19e4bb82d3cc8cec5588517e9c7033795867303aad1f3ca770e11648a0b73aabc9839b299bbe0b779650d04c4a16905d4a0a680adf51583d85b699db7c3d1f0160dc6cfd82f36d0f51abad3106fb37be04249bddd76a6249e6e5e63fee340851667dfb2c478e801e98be09620f942ee85aa4c6e9678426e2f0c1547cacdb94848fafdf0e25571db74870cdc8ba5582228a9b0ad61b3c3789b53f4fd3fa314fbc4e455a2c1be9f62f7cbb8e58615752a8e645a415faf616ec1b012e63ee0eebc316b39dfdc2469fc0c773ed86852865156717dc601d10bd2da4f86157ec3f8465dd6229e0603886a506af2b94715ec79aeca45ee6d46fa3c2dd0d68d4d3c3aa16db234e75610d4f5b727bfd18bf9810584c646f6cf257c1e6f82afb2fff04d96ab2326db535d957cf7e30905826f584a9770b190487cba38b9bc8d03ddd657f81f7fcfaa7571dbf2f5ca3b599d6b680f82d6512f97158b71a58b7ae8284e782ad1eab51f2890288b31a048b29214a1aa1c63ffc41761e94c22abedb33e47fba36a7a64eb047fb4b7c2ec6c4912c01b7849e2ba58dbe2bb2b1c2a2c7aa1941e9dc96843cd867276484402b437296f9eb2fbe1c67b0eebd7f4c43a40f4f782fd51b55380c1b0c40ecea5c59d32534268e9df4974c8972ed610f1c1e898d6c9ba35e3d6bc97cee8308bd233497d91f2a0e04535a83f8aa90f9c8a1d4bec65b126ce98e40cc6b3ad75654df49d6e595c496ad91aafc15152e9d3e0f986014cc9acdcd9cd5b407d58f7603f80bbcf9e2aa6d970bbd2918ba1074664e75ab8d6920db1f85512bdc398a5e1d54a99e689e059f2df28487c27339a9568a46dda3467d9046a6c00dd14a77a4131749a09f946f9b3662e2528ad404c6a589868bc013a6edb09f072d0ce54b4fabc03e5341ec594ee0d529f47601235a3f3dda990665b2eebe15ba5d363ef0005364c21ed6f5f724c22a871fa495d93e2b02fc7729d0720fac5ac9144a4e680684e7e152a6e72fc4b4aa0402318c8d9d2781da274c6c1554958ce67aeb43064df52faa095f68bea07ee207b810e1d523c1c6982de7653986403f26173c252afbf6e338e9acb13880f0134af26bb8222e4703e3e33847e3e06176b9930728161118af054a6834de3f3062eb8dddd9b88bd75b537047c034e3f3fbc89342bf329caf528c0fc32f971d89bd68f809b7c83ea982ee6728300edac58551b5eeaff539c42a215d799ff53dcfdbc4ce8bac4c1b4c82228d743cceefbc88fc1c835a23454c531398f803ba4da5569e5c7bf45b668ed4f884fdd822ff540af30497d79b93cf07e652bbe1388b1a6f244e646b730fbd2dd690216536ee00589b498547010712cd69771c684c647caaf2bb17b29cc045b4ce464b8ac660d0faa8ef53562bbb0c419ae66caacae298bad8122a3cf82d0e6c054ab875d4d72305c4f2c2bcbe8bc3cfd242999e9c644d56b913dea54a794131dba263386b206af8e4e85dd4610819c1c4abda172063e82d5649edb273ce154b89408b1df49478718aa2881e4cef58826b6aae797d92eb88d1f3585f6f577526a035dcd5c5e95cabdc9e7b23ebb69488fcc59710c0fe94396687ec0ca4b619fc47dd3669160da50fc28b0ea2fe4e7727e959839f5cebb439437597913b11893876643b9e536de337951c59ee3b84c8597604d5260c971418905f8c14a0e9a2a7a43c9eb53aa1f3ed5b13a1e5d7e182d5c921f0604736cb2928ce660d160f706601a7ebe1a430c227eca0e8880603065a8e286e7592da180972f685fff098496981b70aef3b72b4c47ebb16ce33d258f0a80bccf81535c035a2c78e7b8f816dda5f1ff66e39e56132987e083d6daf88d42acb3544eb3545d85f0fb90d50e25aa2e32820c317dc5536a0b97b70f9d9dd04a2bdaaf21647c068547171603a3f6f18174bdbe7b628419a25d5b81124b863b83b7b4fef1a2401a05717c83ecea0b5780eb681db595839c0cc6b4468364335d4762e2d0111f4559a10f4ba46db01f0746bcf37b80c5d964fcc62f917c31b6ff8a01f7ada8eef51d3227bed9f0b4046e04f445a189329c7d8df69237948d22719c1680389db0d4aea7c1d3df2bc5c0ab929df9af45ca940d3a05f3bbde4893989936e8c62b99eb2715f7cd045e39f41c9be6cb247a5e49985720d9feee902b4bc6164a81560a20c487140850519b4ddf4ca42834aa2ad0ce0f21ed920bb071c4505538ff9293d7799bf514ecfc7ab30dc1bceabe766bb7181359ee9a6505ce1864ec7bceca28f71ba8c54287fdd223fc0f36d07ed28a58c0b5f28fce02ee53a914ad1b687cd21dfa07dd45ffa4bbe81fd1f365b74f3a989b9076b4c05fbf801756ca2ebc4ee7bcbdac40851740be671b2a3c31d14ffc04ed12dbe76aec37b4ce1f39356910c9bd593520a57ab8d14e5169dfade433900d292f811b63e93962625939523f34d5cfe3811ce45af76db18620382f4ce9f54be697d795b338dc36bd8671b3809a7241e644141dbbbe02165c9508c5c588fe41f56576b25437225c52ca942270d79183accec61753cb65ead45585b0e36c2686c95c559d00f64757be4dcb2270096b2b648997032612ed4fbfbd669226cfdbefc1a91827354c2bc4010f1161fd58b131e3763b4a8767a48cad80741e1690ddc6e9688ad3557c10e7a850309479e3f2e937feff90975846d8d5e2a750d0021617a53cd9d1eadf4e2258b0a7c3abede9a9ac181a08340ba619b35c88000911c3abc54a5236e565d5588e110a22108b21476226208f01ef0a20e3877c1757adbff31cc1b3db0c040ecfa35a9f20d505f0c9135bbd4b08c454dcaf0c4077ce2d212cea0de99dd18764eb3f3ff79e43d1e3dfa9e176f0e8732db468ca5c0b44b38d8aa1610052fa1bf5b0a0353a004e6afb1d1733599f47b4147c48cb16c668eb3a3d2909c92abe36a55a91bc2ff01b1323bfaa962d1d080b568ae2fb3e02c927f85cbcaae302ddb1e466ccdf123dc023c1074683180a21ba21f2cf44373ec9127ac155535030f4e4ab1d358f93ae09458583e6a5895d308e51b76b128f47c865bb36834cf81e0c290f878bf5ccf6d187ceab417d3e307f2fecd7b8d135c801cbd24328cf14844a807386aa3223ebfb475a41a7a375ec6c110b85dd4f4970224626210eab5f125f1db1e33b93f9553f6648907a330048f67f68046d15b70600ab49d355a126b698cb6d4439f699e811a44e3c5b0d9c813ea36957cc14bdda403de078b7e3a641d0f5c678533d60f342b8e28838163de958a670a3eab80ac733a44f05367139dac3c7f7a6cb060ae73236760a41eba5ff89681297693766abc74418694758b7e97814e6317ba80c1dd2c6c5148e03dd7aeda587349c8198ba3c3884d3284e8a3538bcf08172376a556b74cfe9b1f41f3af1a81056e10857b59616dd16a2d05b149e5148d9c9bdc18aa8df229f30d905ee17e775813905614bdd56de0ce7843f85373b33d28185daa99900b33c68d7b265907a246fadf8ce343b8fb750bab927b45363fd5543e0c660c981c4639182945e301e7da96af17a828dc1e787d849a1bf506b1fa88d824833bcf8107df0ceb84b4d615381b9d81df15936f8f04403357b4b6822ce6feea1431ed152550772b050063246be3d3b43f864425cc8807086493acd9d521f8468aff908e50d0f1170637be540ea9438c11af3730e6c0ec2f233a0ec339fc7dd9b09bf72f1b05dda8745d29fcc1a9163699b4c84f1e56a6aef3465a266228c247780885a6ec466d166ed8878b0df3f1bcceec4eb9c5bb08bce983b4b98ce46b73db4d8f3841aca6878f8f6a201d6beb3f6bae2433851c876ef6b5789345e3c62b9ca6242b032a95411813d9d8b981e240b5e10d5972f14e8ff2830595bfdf93426d3b9c9fdba8ed1fbb233d3a993751cc21bc51745035793b9d78506630fc94cc557033dd35107b3fb23a98cb6b9535c58c09a158daafaa941da03fd6f9f1168f03bc431181292059398def5cf10eef20c1b6edacf7dcda4a43d1536440d06cdf39bb61c2cf775acd264769ac487b9a0a220d280ff516eb2340d9cb2ee2727e6a62d11392ce1a3a78d7324e4ffa2a620e72c0de9a99887199589fde029370a0be0d7dc76401416491cb8a2fd4168d380b0584723a320a408e2ab7f88839653c41092043d817f80c11dafcf4f2e6e95c782ae468435d8bfc8c21e53050451525e24d6a7542bb47c8a5bb3196bb715e180e54870e5ab1969724e2d2122088bc1b7db338596591e12fb63c311c245e1f8d0c1c8072699b8f08a8e8f7a5d2f93abd026e5267909e1383f79e9670f1ee215876c46b9babc4cc2a105f48f181dcb371bc53d2a2687dcb6c3d942a6cbb1cda2e8e8537736c2c6264254d553311a5e7002349ee7c6d17b0fb694e955254252769531aa309c60d3fffa16b670ffc9ea175a88e050ff9b6b1e9c7b89c0276354b424405aa04a7a81607e052ad413dab102e9d569814a49ee9de2c071c65e1724be766c883d64d0c86e066cdc89a2bbe8b63d49045f1d95b78533043545708fe7fc228fda147e81a4854ed3c326e14546f2486a886c27bcaaad1d9624adec1fda6a9081fd50410d08e0abcaea33e23645090441ec2bffafdcbd1722637552650f80f1c6b36802735cf178fbc4afc39f77146a79908e70dc02542bcaeeb9d23691bd83ab410548a7e4331535df29cbd3d4840d08c5f11056b5eaf99077630ecc0931e9bdfde2ac1a74289bc857cc38abfc4270723060b84f76bbaeed8a8b22090567a90427e684963d9aa220534867b738568b10373c563710c8ffa85539fc576b57d56925e62a67098242b363f011bf295288069bfc6254b87d0c4eb1a9f9520322f4aa2c60c961a0960501ec755ffa789c4550ab0f50bea1a8cc02c99a7a222f85a92296636f8a6d9b2a228caf34d505bf3fb8901f2c1dbc3ad3a8b622b672df23064c154d41d9c0d623a098665b71221394984075cb670b68c6c60bc9ea0d4ad5bf555939a68af005e16374d94b1f1efebc2acc50f8a6b90e0e828200e4b85680896a9909169acb5d3d8f6db82d2e84e2f6b0c0812f04d7fc6fa552f8859d788c772385ad61760b018361f729e15887b061e7cdde8b7b32df954e4ffac6a020967910d44b95ec30892eb9e08ed267c5f7a540082d5cd8ff24c06498f2417db9371a74868566bfc9826903f253d807bc164609edb17803ed6364bc93dab257e063f6348fab702c77583f0175bcb3cd1e1bbf6f21aabde2c892db9040369efa44bf48df9493681e17a07b9aff775f90cf3e50800796f7bf545a2c446d04883a16e1ba1f450e336f0285c1d4638eb529ce24282f555063c182439e82ea6c23674e1ff2023b8f33b9744ea0a4b43153f3d51eb2936a58b4e3c46a4c248ac01ef79101532df7efd7e99667e371dd1784828c7e3dd8629f4b45822d59475c7d6b2c0a0f944e752c5a0a64e8cb2e80b471a0140f7b6a697522b73f506cfd166ecf1ce03489498efbd7db67a064679485997469638af3214145fdd10d8476f5a8f543c95538fb35847ac33cd15ae1b8cf8634c1e27a8d858a6066021701e44d033ae382a2521048a3743abffe4d382adc2513110e463c3a73a063148330969d0d0cd6992bdd50457891072724120100006066442200000000000000e168821900b37ccb433346a5b0f0f101b967c7ddd69b4829a5dc7bef360a1e0aea09fbed45dc9b1b88f6e6667bd3f7afc4f97697bf6f77dcb77b6f63bb8f6f6ea3d7901f26b3265461d876ebf0e08a8bad3232235778b0ede6b94282c4598173715cc1b69b880631c0ba86888adc8e6cbb814d65569a0c09ab7e6cbbc384b020ba35b158fb61db6d04f285b7b837b5db9b1aed4dcdf6a6eb1fdcb7faed5bedf6ad26bee95a1b5b7dd46726b002fc5aa294620a14b6d53a6f2e01f2235662670b15b6d54c4338b4b83016413c6cabb7b880c0f9ecc091a3826df58b224546304c5d4efcd856935736c8e2a082538e70b0adb601f94296b837b35b0e729b7f6ddfe630df6630df66e29b9e7336f27c9b8f6fe6b337a518cf9c94f041f2c4b659ca171510b02022665e6c9b79703491d26298b4e633836d33d10b7e301187d8b00a0ab26d062e81690da112b5a38209db66123d4290d2ac4aa891edb06d3e01f9c21b58dc9bd84d05e70736522bee02f74d0317ed4db6371dffd8bec5416bdf62b56f31b1c5c7c7d8d853ea81a1f3c3240309db621d3533a4a3aba2236c6c8b794a186a4164ec0696cf0fb6c54436708136a4f2363443625b0c8400104a8a152ae2e274b02d7e0231b4b2b603a5099c906d71f04db7059c0b38479c26125453d354199911760a0f0f2126ba4a18d9f602ef6deff1de2fdfdea51bf4a6df9c37fdee78d32deddbd3cbb767976f4fe25697797e9d64ed797cf33c7b222a7ce05c51fae262db33274c962c2ac4c2a6bcd8b3078c15596e1039d9c2b627d1a750d2e9c1e6d6c5a8c8a62038e42326241b9b62792cf93996457921c5b6675000e40b6f02887bd34db7374d3414e2148002f942e96df9f6cbe1f2ad1984f6adb9f426716bb3240a66a8e0a2428b41450acb04cb0f8b14475ec0cc1f462d2e28393950b0ad19a755542685c54a0a20db9ac0374bb74fe3de74239040c211fce10288908b192c09215d6d3952a634611162b265d7595b3e91dc62e64c3f8b402680bc3c33cb9b679f49e3eff743c19a6e0253c465c937bf055c2772545153b104c79a43241f49a2a89892826d57b3a189246b47b8ae9658930631c8220797a023b6edbd09250a8c5bd88ca10b2bacf9858b9bd8120c215639d8960cdef588908808dd6589d477a5bcaa7a89b3a5c448daedab3e79a047c74f48961c3272b0ed8a4507ad9ae263dc6165c8c70df6ee13c5d65f270144b5d53248e5c51843f711f610c9e755d58d500a614889165f6a346501835e01c6c5288135e51c8386986cec7d4b3cea45305332ae477109f087f32488926657669ea284c0d8380285cbc8ee4d8412f52194464ceebe42487d3708a94fdd367eeff5d57b28aa3a10caaba639e032f2c3c413234e2ff6f127ac04a03128478c8a57a6a49065f983d477a7c0f8bddd07ea464914eec417615414ae20636cbb7e19504f995658cf96233d3f48585555d5b407a9ef7649e1b7f3605b7571a95d2d1d95f008b1ddca7147811f23713857827a5461f11539e6f57bfb0e2a90e345599692aaa9156cbb56012aa2532031ca3ab105ca90091d08c78c6078d573908314bd5c3f8abc70e10102c2015c0cad1f3f74540021a3b2c34597252db4b0299df05a7a812ca7cd0514b336218a83ed37308742c25755b7c156c125b1c3030a19142360a6d0a658498a21817465e40b8b141a15a81ad060c748534b55f5501a37798a6081c8941e674048569e8cc9d011a629094f8ed6188c252c8aee3b0335bdf70dce0b300ecd08e4c4351a85ed76c065c90be82b0ec60b963416555555d304c8a08c818aa6865d7fc03602600b0a2d5bd25e7518ec5da63f6ceb0b5ca0a23e19455b50566539f3d2327cd55950a648ae3f605fd5b7ebd4adaab7440bb1823b04763d8aba0ab68a9298c1b654848b10199025954cc5c24ea819d88cb08de9c81a4ea1be8d289a7a0a4a115e865982bcea284025a0020fe5d10318352360866d4123b65d3fec6f8c9fbf17494a18b8b42f1f3858a1c996265e957216f6aa9f609348c2525a0154b4a2ca184bc4d374dc8ab2564cc1fe7eedb8b149f8a881f5e2aa4a0b908d0b13176a4035156b38a46ea35bc6040ad8a1f8d44b605aa9587c5e75e1552c53af3a09d67d2f19b6e5c6056cc913952a554a87bf47c0bfd7c916aba1b8a5a12bf67a2f45b1d4f6115c994280575d04a94fd58036b77ebf1f10abb576520befb5f6adbd7453d9744d1600430c7f6f4b66dd0ddf92559700f7def2a744fa3b7c7afbebf7fa26d2e4afaf44c2feba4331fdf51e9496bf6e1325fceb372360fc750910fd750d2cfd7511a8a0c90f8b1cff7a0e92fe7a1074a4c078a6988274fe0e8d18ff7a0880f73a083e704364cba2420c33f2310676bc37ca5f2aab237f2f0d1d1e60b87404971cb1f76eadaf07ca4b9615bd14a170fd2092856d571197bdf742f96be2efc58125f625c817299e32f65ebdd514cd87175414cfefd701f43cd94eb6739f2756983fd193ed3c9ec7533d4faca13f83e5128bf33caf92fca93bcfd303206cced36fe0fe8ce1cf13845161fe0cfe49125b3307cbe851bfa87320f5a1688afa06521f1a54a675fdf6bb5d03a96f07eda0ed19487dfbab24bb42a13a06d47b55bf40ea53b3762274929dd70b789d04c96bb7c0aa4bb402bcf60aa43ebdbbc5eb7555b831fc93bf7eef3da2e3ef91b7bf489cfcf51eb1c75fb7111295fc750adc126d0241ead570ba2ceef354d508a43e553b04529fb60af2f7ba2ff5ddb30639889840d1e3090812b568a485494829315b1b335a79f2f100d51d90fa54aba1d7af9d6d9a92028d6dcb28886d6dfec991d0de4a6151a6aa50e1a8c2de7bef8f487dbb8acbeb0fafbd01a94febf33c1f70852ccbac2a8a1619dbda9ce7797afd6944fc13ff79c3e5d614361643c7496b94010b487d9b2accdf5b05fceb31a4bef3f7fbfd82eebd31f04a91c585d9500d876d6dfeba075440deeb37f7defb651403eeabc68fcac85eed2a4d59347ba551df12a5216f7a36be929b540019dc9e8072e6cf1a10258a6f6188e174b225bb48b23fd36fc93410e7f96df9f3278d3f49294f16f9d3a7a4f6caf39ecdf04fbf1921010d2cf9d345400aa7e2fe7419e440c59f1e0423317ec21f1de29f5ef29821486110eb4f2f8388844cc0137fba7068fc538880d4776e0db4b5aa6a897623d5f65abb88d4a7b726dbdab68e9c4c15539875c920a644a0a1a48787921756a66c55ef10524efe5e3f80ce55c1a9e22a81a575e2924d623cc9bc01bc80218639c231ca81e1fef8f9ebf7ba0188c4d24198214ec7c1dfef97c3e213b093571e63e7617c3c3e79d2fb19b6c0f2e7d0c5f04f2f80a7b1a713c0e68678aae7799ee7a98bea0be590c5cf63013cf601a43eac5ede9f3ec20c71fa03b64a531a69f69758007b05dadfbf0ee257b666d5e7dfef77826d4de267379d4c11259bf9a17416d9cda01a40d06f4d1a4cbe3597b8fc8829b8bc251179e243d1c35544eb02cac1b626f098f3b9ec2a1ab13e93956c24575017900d35ac2f21b62d8f2fc0d928817314f285826d4bb42a5344592c66b5258dcf4e9640a3cfdf96499f9d6ccb2010bc1c7780803cb284b16db99400a41f32bea4301352624ba2f9a174e2cf67922c074cd46fc9b4ec644bb2e596fc12513e9d608a2883cc0fa567cf6e93a988489fdb183e3be92bc2e2a32a6d05da0e76ad0b855bcf508f31c635187b0e9a3cf6f16da963fee0920650c663195c26e12cdcc3d84b630f2b12be2dc97a605e8ec9c2e4094ae2d1e15b9386f9843f6027cdad9ec729601d58e7d8cdb416bc35dd7e3a3f13be3d59609de402c6c21f678f55c05875ec2719068131c6f8f25043518208151811e340cbce0d331543806378470f291eac1547597087a62a6458586d61bf183d5260769cdcbe705957172d9c125545ec247612638cb1ff98f12040783925f58150555555555555552fc7529fea63c8bbe08297c6d4e782e6f1edcd6b078ae3a9aaf221b4c406dbf65e3745c51909e22c2901856d6d5ec36d79ed57fb607aadbd144b7d3a9824fc16fcb6e06558ea6b41a7d3e9745e82a53e5d8fb1fff0c1cbafd4f781865cf70a29581c7f385d6d566c1bf6b9dc8ecff93e45a0f0e3c54e92162c2670b0392fa5a4be5cbb7b127800791248e851e249f032caca13f2003e8fc7e3790925f5f17654f95ecfcb62eaebe53b937376cf55b63e3f11eec0f12cb0e0a557ea6361a52a73fb755d7daf5e3a71b0afa9f1b22bf5d508814daf820a5e36497d2ad090eb6692faf0d2cf0720005e72a5be0054f918143e06f8313131310e8370a9c4c7c4f0313131ae8298982e2880c21f182147d2d4c0188f5e6e2cd6d8989818dfd9cbadd49797a4be18e2afb082974ab610a3efc0c277d0f11d3a788dd9a183ef53c403c8b8b29071d142858ceda0e34817b824ab243f1d829031e0b1975a3b4858ce5e66a5be8c7513c48601aedcfefacdf1d7bdc6046186c8dd1465a831c1bd7749cbdf0cf7de9206119069c80adf9649c4328b847bbd3402f1a9f9b6242bd97e6688981c9a1b94f3f7847bdd7c3243ac7edd2ca2c2dd6ae22ae15bb30bc7b7e611d7786bbafd749c822f7c7bb240faf624029a213a24ade0ede9f4f4971c06717156fd75f2349a21787efd2463c1dbf3ecef8976a2f823dca1c182cb14bb009fa71c261fb3216a972c7f4b4fe5b16c4da2bf7e9f30f9f8a0a9f8ea615b33ea2d48f1a78654dc0fdb9ac60d600102ee487949a1c3b627cfdf1d604d6cb86941c362dbb33d897ffddc72eaf22cb0e06592cd73daf23c1e8fe72531f5f168c8d59bb0fc0a2b788924f5add081ea78e23b74e8d0c1cb23a9af030db97ad3d1d7f835430ce06bbcb44a7d35358f6f1e3bee3dc6a757a53e0c64c8abe057052fa9529f0aab93c05fd775f57298fad6afa7a1f15298fa6868c875c7c4c4c4c47819f421d3ef4910f124786924f591a0aaaaaa7a39e54b4daf53c0ebbc944a7dba9af2e87b21c8da0232ed10e9fcb215e39433ab2023181d6cce6869e7b38f58122a92fab2d2d6e7fc9a21407ccecba8d497a321d7cd85c76bed3ced5b7b0995fa349193cd6ac5a368d1a3a8d78030455c167518cc1ba047655022d4456086b88eba0950d42ac7a328fe4149d44ba0914735a0a876d4cb2cb4ebd1af163d258eec90858d2db1fb14c10121b029b89ea4163d2c2ac24d890bace803ed07ed21840c8debc88e1bbf1f8a3a891279ad7d6be7692f9f1e708c130392e2f4048eaa6a2ddf28858649c208a511491a72efbdf7de7baf974252dfade97d1e36117d3e3f5be97cf61dc429f5a162efe1e63d78d994fa3c08993c070e1c3870e0c0818373180a8d6cfe7a0944071b6f974ca92f2fa53e0e34e47af365c7bb7ba994fa9c865c778ddf6df8dd6ee7353bb73977c12f317ea7616763e722304368dfb90976bbbdf35d5194161c129414b81d0a4e2f767c195e2539ee447c3b93468405b11feb07d380e8f4b56f1f3f530302862e3a3efbdd679f7dfdf1d9792ef539e8c56c046dbf27ae2e2da49c38ba3564703644c2230484ea0a8bbdec91fa300f12adf829a4e0e58ed497425c92dfb0c1791bb26fd8b06183ef0d71320a90fa6ece39672f75e4b8c1f200f00b002f716c1d4f5ec3cc6ba0f11adccd10d735788da9c1419821b26b709b5344c9f3fbfd54b01a9c187dd698b8002bb21a8a43a2fc6678c105b1edfa1a3294cc959be414720c1fbe25ab9074948024c43134c481656a98034cc78fd49789ed0d3af33b546c291af221e4c241b6bdbfde924472ab6c68c65f771c4c4c7f6f00b1b29a8040397eb0d7cb23a3d18d4f9447c12f0a5e16edaddf7be8b7bb1902fbf69abd6180f9ad6ea1ed2238456c766f75ef9eb0df1a76d0f6727bf983ee3df4c1fa1db34b193bfbf6326beff6f67d8a48c18a0c0a17d859d612bbad507139d232b686c36edf474542a4caa67ec6ac36035c98e0199a4a4af1b6b544996164edc6d390b5dd43e96c8812153823b62d9f7ebbdaeffceebc24dab7bdf9ec367e23f5e59e178ffa45bdb4c1822b293a605881d9c9e949f15ac7f81f5cb559456da1a2b3c56a2f6b380cb11268dc7b024f97093c5b6048fdf57246590915566f44299f1ca1d257ae04ba818ce0932a1f4739a658ece5900b199f18fd097e4ff03228f59d4043aedbeb655ca6fc79191919ed32325e385e46838c8f0c7619992ce339324f60bc8c8c4c8f0c2bf33257c6e6f7fb9990f17d8a6001130ea0961d20a51cac4c141c3f703c1d8d8a6cbbbe4c151852cc8a5e40c9b8a111517071927241645b9238841d67348e8858241db12dc9e602d897a7381f5d9884c990365e4f7f875e637fbd94c1fbb63da12becc3d009f1b3973130761ef68dbd044a7db8abe9b50aafbdfc497dda27f5c994bd097e4df0b227f5994043aefbf7e9a7ce4bd9d47b20cc10d853b7396f883e8d41046688eca99b8024cbc1934fd734f592a7fc49d574a76b307532f5f1aaea258cd4a7e225241a684aba44c161db15c65fb01bc69ea8205b3a5eecf59227f5dd26295e93f0dacb17a94f8fbd01294243d885896dd7610f174c1a630c01de1833327283cd5eba70265f8fb1972d58a4be744570c6c3e93a32cd3ee3a1bdf9192f3378f6d0debceaa787f6e6cff26f062fd7acd294e0a1742b81860745d26c30d19052454409ef45d95b10912ec1a825633b24802fbe5ce4e8a1e4c40886cec510c0b8283ae54c7911aaf062a2f6640894a40505445b7c4e6156e5aa696b2d059b0e09134d48a680494c58490161b1d422c70f2b45415f3c2964b0628b921e9da28a201ae58a1912bf2564c72e1c1d664e28bc50719202c771c731a8eebcc0e8c891172457464a276ef6de9f3983ebae070fd74b37b3577a11a0b06cd1d8f2a4552407d1ac7c5e3f972a3e2331818c4a314e0cc9d1059bddcb9c9bde59839b4f69cc9fd92bb5ac249ae2374d6bf3e5a364bc91028908abd27c9223db09135b8eac60f500b09080a8bc38b391c3629ad63f8751aae256161482c55e9ab6b725eeb3dfd2049bf93beede76716feeda1dda9b6cbba013dfee9672bedded763b2316205a49d46eacb99560dbdd9122233f8a388c8241b6ddf1e022e1172d418e82b6581244ba0ce112a68710d810b6dd01df8cc1a3ca54d4980f16b6ddb585310a2969c5313961db5db0a82beaa27cab23ea746c39413a9d4ed7ea8e6fb63a20f205a0b837d127f409454d7c8b96f8165d4251d4889e115101b24569c70aa122b6459d5ce42029527d01b22d4a8428a92b2d3fae083d615b74c81399d5515a0f9c2e6c8b027b723d3926dfe6827239b6373df7cb09cae57239639b3bbe993b2b5f04666f8667b464f46414343f903c72458a210d95918248c4530b77d85e6bf275a6319a1fc83f3a9a1fc8f5e4897822e3f981fcebe5e6a1c1a29447816bbfd74f52ad09cd6cf8b2c8d6a5caa273676e9e6e95ac7bdeb34a5795a0560b58a6c4c82a6239726ae200254d683955a008a3c82c45822bbab4d282544c3ad0f5b364cc02b27674790489b12329c78cb81e9949c7855e6db92a7629e294c413bbf1d86f2e9992c2788890bcc45064a0bc4565cd0b0b8e37a1243f4a22314f0ec5781e3f194453c3c49b9d2ebea79b17edcbd2efa529af9bd933cd2a14d458e8905294424c5be25740b6351ca229aa60c6c3a0aaad0db082c891a136e18f2d608e5c96b695905762489d2545395a42c65e9c3154977befbdf7e2ab333c49757cf1fb496193b8ad9bbfc45c7cf16d11c7854344e8a227896d79715bb295ae3f41fca905c34b153048584a44545692b652d0726404079c0e0eb82ca5201622317e90641d97b0ce7798a2c9df7bafc643143cf75e7c7557cf064a05cfa9ac44bdeec9610ae2ed12bcb1c11244c50a4634788668210a4105a17acbd25124609d00ae4b97141c546b6d580b6f999216d952e0b28294c8c93831ce6aba59927b77ded4777f6b799aa55aefcbbbd7d2c9d277e9bcd2e637b9dabc540c302ac9ea4bcbd68f58f0640a2373c523621906b79eb8a898be367c614118e447aa44269375ee5ab53049c5ea850f1e5d84e08a654bca7c1eef1e2721d1f3e5a7ea878ab1322d38b7c77e775cd563dfad4f5295dd78fda4b08c883661ccb61457644867dca5fc1aa832b33fcf1aa85bb6e4f7935465485e50a9b9dd129ea45283f2b927a9d4bcccd83991e615c402caea229288da01044d4bdc941210158e10120e91471a92d6490eacb81c3063102055565f7686502ea6641cc1513d35a28838016b42d59e0035b9e14556c2aa6a480e3227a11c278e6ee4d120598776d2c9ab69bebe809a780192e58cec44942a331d1f533d28c204c1ad66ef2677fd40e1236504e6aa2ca9c4d4ac1d5eb6b2e480319157787278a4e5d5278747c693296b2014d097b430263d8a615e1ea38f878f3126b904ad70844da9d185c562f26a9ab19c84c6ce590805a6c92e8c33be97f74b619ac39354614d7e3299aa239d84c1c667764affde220d3530f3e11404638453ca11e3e618d2a5908430a5a2a1226f4a4272ec64b8ddbdf7e28caffcf57bef18cee1e8faebbb7befbdf8e210befa64158e26f44c931927c1193fe12a1d5627af4a47d2c73c59a543c87ab38eb0125d2f8c86d87c8854e7910dc11260384d193222c4c8181149473e490c116973f3e2228cb04895cbf260840454545197222f2858a060ef99a172182759fa7b73b8fdf5ddbdf85211957e87744f0c0329807bfd2ccfd3346bb033017b767ccd9aebe63531cd09375f9c77768c310fef76f7335b7b7b9d7c9386b71a611326802f4d0d767f92782eba93287863737e20bde73c5d496e9130cbb349ae3cf7559088f2776ea87dc582c5de7bc3a96d9f7d57f26e0e3f4995240beeb91963e59690f0c213a6b95f5143564eb67809b22d0f8eeaaac89f1afe9c8afb3d811175c30d67077b9ef73c4fcde149aaab1c271796ad1f4f3a80ac5c912a419723524d42c060f4b0a4933120c5ae6a7ca11843d163c5b6eb17298262e6d4e3c4ed8b1696745206300811228543242de7eac81dba8a89ba543a9c844c783c31e1c92a1c2d9f9fac1a0ae6d09164887b4f5301e6d36007e527a0748cc9d349b2742eba2c73e9bf5d9734edd6ce732fcf82e4907447947259de286f747892ea488b5f9fa4b27ac3474e900cc0bfcd106408d331be34f847983ce893545347af7b926a2ac8db18886491bcf9b2e6fdd1399959d245e5805bf3cc9e9e594f11e4891b39e0ce8efd6e8c57b357922b49a373d2f6fe3cf182779ef8f9f35c67cc0fa50f59774f5225e9f2ba2785277276903ce6ce7400218f3797e877f07726aefb66b37970f36e4834e25fe3dedb8dbf797f7d7ff0ef366f79cdf296eb36d712f8b75cefbd64d0ef725def2e7be67a775bbff75a965bfb66a7bfdfaf7f5f86f9d2db003ce92b900a28d9c8174a27db8a3c89ca9961028abd5954b4fda071f939c192460b94504f3a497a0d9980fb37b8791a64f099129c749e19228393be923e62ebf7fbb56095fe3c7def4e9f314398e0a7f37cca96f1b607e2cf16869b3f859055241185290edf924700385b1c973f7336785beab068cb9f20aa3f756709f4e050c69f551ccc2c0fe669c5e44fb2f2589efd9976baf9e332757e88d04ca40ede9ac0a43f4f3378e44fb3ea4f6f4d625600bc354dd354626292fd793ad99a677fa6996cbfa03f379c275a7bb258bd3d7f888227d2094cfaf33c99f878ade1b5eada6bb4d6aeb59523243ddab6c21c09a910bdaa2ac900527a72a5a58b5589bcea2518aee3afab976ba96fc522dbb906282d9f5e0466089e6737010b483e679dddcb59ebc5e79cf3ec65d687289f73de90ddfc993a392b49fa8ce6999cdd2c92cdaaaddfe79b876437d1d24cb79ccfc12a399ffd642124ab9efd4c32b3d3e7229f95143fa73948f6d3781e73f6936d09ce6737a76f2fcf67bf41970829fb5d5af2749d9abebdc4cf7eb76e7100dedeaf6bfcecf7d875cf807c8b7f3a9827077d764cb4a5f419237d66fa163f7d761c3443e83c3bae7ac15b9c85b73e3b2e9a21482a312afcb5f42d46fbec98ed67e36dcef99c753e7be6c9fa9c7f3e67e067cf4bf929e760eb24258769688cc70b099f219c8b62d51a161a64896612994029e1133416c6a00c306c6b16cfc8908a3c05bb3015b1ad695cf2ba7264e60246d0916d4f9e3071417656dc10334b63db33a888559011b02f1926b4d8f6343343022ab2e58ac61adb9e5b39583f92cc5af48039c1b6f72714e468038a5897176c7b753e3b158fb4404a5302c4b6f7e9f3942158db14a29ea218dbdee0e7b323423b36ba5ef8b0ed45fb5c6426dc2911a54618db5eb6cf4648dae9396a1b02d1c8503a5849520419c1c2c1b6788986d652971a4d38bed8161b29806426a407ea498d2e36077dce636043ae29b5e19691b7b1f1f24beab3a121d7bd64cabff0829769a9ef05319dce4b2fbe04c60f20003f002fbba4be0128a9f2021080975c529f00944c3d08b4abaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafa55dd551fa1ba0a542f7faa9744aa9741d54ba3eae68fc61693c8dca04932ad35d2d3ebb24a7b49a6a4b7d626d2eb1fdf9a4f9adc228fbad4795df20097885baf7362a8f845f1125a61dbf278831548c0b4a871e9f9d1a6ce6bcd011b3f71643c90d27ce82d51ccd89cbc1155b9b1adb9642cbed69acaf8f5da476857c1af0c0651db93d75471285ebba944c86b3789b416d3f82ef875c1cb2ca9cf859a5f6f7ef5b6f7abcdafebbaba93fdba7a7996fad6a1968d6fa1052fb1a4be16b2b6fe4303fe83975752df875c2e97f39df3d22cf5e58659462b1cb1ce9e0516bc2c4b7d2cf078ce33436cb08235e46b6abcac92fa6a68c8759365a2d20b928a0a76efa970d382f76d0c015720b0c46a0810a435276924848cb5215d010aa265075b9a96663766022b8a88b034d1c23133c10c164f43ab2f3215514a4ea89ce46f0d948d618a1a281b4c286c6e0e2d633acb1ceaa12646f7ca944cad75ae78cb189bb2b805ce6b825bd8be751ba1be65994c72b5e6e2258614427516308c71d675298131c638e37b3c828e8e222a2f641ccdbabe8c3521428251038c4a90cbf0f393412e4053409e3579621e3049bb1827744f5461706aeec577e6492a3059ae151162528aa6b0705184040c7185b20c1c899d4d09932135f40426297f907a82e2cb0ba22f60dbe72456c46638f948b296c3c4caad5245f62d59c425956f49362394183e9e7c50c8605b9218002b4ac6dea64a145db1482e80ac05e91cc13db12d791c8109a6154520959a916d49b42c7dfa0830504d4e3d942184ea599be827a9d8825e7d928a6d076b1cad8bb1c61aff5c9d79e55a85932407eafee427a9acd6ae1a8e5b492735de9a07eaa406619e50ae043acfec33fe446b4be3296141c5eb60084de0e49c33bec2125f68c0d5fcba3d526c585080581dab7ecace2948b0d418e2237525cec9072f2026970028fd8e460b4f0a4dc4bd1a04b1e3d7278368566a70735f785298e3e4333c19dc12d7e45620b7b3d6ba8dc66bad73b99ddbb9362346b568dfba0d486badb5d6ba2d58e3f6a4b7b6fd3694ab765bca69adb5d65aeba79caf61dcee3ac2eda7b5d65a6b1d86df96a0e6ca9b59733a8ce6f69b150a57232c8222a8cb8f89d01a98381333e5d80ba8ec4041d506040a2963acb5d650eb08b85f4dd65e752eefbdb77e6f9fd93abf3d99e41bcf93b3f514ba42a38e5a92dbf8a443735b2c6d466bad8dc78c75898be6d626ad51281e154ab5264462b95923698d69eed5e4cfbd57eb7526ec6df57c9633c65530c639e7115678344e7d3a37ccc978c5b80a306848ebdccd55d0324b6467a9e9284b0a221a3a1d1c4a630d5610a9a5ade8f136043fe11dd9b5c5c0c018638cab76fc98608c3176a2a14cc6b64754c159679d31c6187f08a3af2c51efca9b59677823b23ca1b9bd4f223c4ccd19ded9d6ed9157a274496a8da5787e20b5cef8d45aeb1167bf9a6096e019bcf2740220639ed7a84dd2d467f26474e5cd40adc7e28e0cc54eeeca92ee4dc52e6343b5bcd066c09c315fd95d2c7099511fb9c7a0fcf47a3d371bdef1c234d3b9365694238ec120959f9d1166c5601325eb902969fba904e9a8f4d011096283eac832773570cd7b79eebddbec956aeb563966423b12b14912afb534201b462dbaeb3bb11324390ed91246094b0d631c36b3ae5f266f9d59ef868bef25f76e4373fba63ef3088b924c878a101e32a018939bb5f5c6386fad5da80de3181b4c259cfb068f4e4553b62868434609e60c8f684ba7d1dcd0060e87f2c636faa54e6c6e60b0c146408d73ce180f6b1c498022e2b94445a2299f7dc7c37b358e8bce2236b38671831646734c3c18e32022183480423b6c8da5b418ec0ca3151743c6a0af1d96061a3bb414fca264f533bdd11aebc62b6f066acd69471d9a779416eb35668c7747d6389cabf3d619de12be929a5e7ef70b0e05943b3214b03487f7dd6918e31c14ad35ed29aa884591174e3c945aa4b965e197122a84f974c19549f9ea7a12dc82b186b58dd35dae84d467ea7e523477efce09ea484075781d363afca548737acff04a04714811dcb03bf23493d35e66d0add912c6ad21f56d3497b3c15ad806e70c32395d967d86c7637fc6bd519dd3391a0d98dc779b88497dba8d07949a14982f676ac313c45ce6a4a104930013575917a31d442ae2986cb82754ac856d6e60b0c138a3d04951147756274e519786f639e7f0c61b632dfc64b39f72c6796f0ca448874384d1dc5e777e4a336b82a8b56bcfbe33cec238e09a0ba13d6794cdd1d139e79c75c63134ec09b4f303f9dacf6d833d3b8835d3a834ec89e0f9815c79714427899d19226cd5e532a43e13e8b5eead3dad0565d6f58a891e5757de3ac3830ba2f9a4608862cc8e3a3b34d52c6c47c7a6939a6db940db9e76664317b91e9823993353d2e09bdc77b305cf0f249aa3c0d194133eb208299255fda4c87cbdd6fa0754681c29232a2919b1dacd6208b17a9de1c1b199e100e536b4bdb683dd80ba8ce7aa11739416271a46e2e33dafe985011e89b828df964e3f267918efbddacf751e6a8ab80d6af2882b0ea2c890cb429dcc0a79d6a71f678ec6cd5ecd538d0b83502b5b766bef7933abd7d03c1904b3e4365ac5deba20980b999d9f74e8467976d6d60cdc9a7ded794d4f89ce5e528531c63ab725c6b3d8a8ecb2804b78dc9a8b71ded2903b951cef505dc27367f28cd664128792dc776b159f7646fb9c097e05cd680153e488d144e40a948f10a3529aa44521ea020af3e159e214658685a275cde9ced4393991d199c7bb9cb31851c701ad2acad22065c3dbce00a538b39665a0b06938b196dcea6bcf6b7a5fc70cc71cb33a6f9de115d964525fd6b9adbb8cb9ac7acf6b7a62c035f5658c31c658e78a3b75284b314b72bb27446a92ac93724ca9321af6b42b92f3dad239ed3dc313d341bbe413631f5a3b21e66664c8333c30b7b09cdc06e00f1a2fb8e294907c6510d392a3189d866948c6a61d6136bd37fd6a0d033f396aaba97dd7199e974eee92bb52a0e717cf75d38231c618e38c31d671dbb194a09c6d6e60b081c1bfcc9c4dbe6b3b0a5a2e0adb9a71c6180b9ba0e9b5488485625b8f854b82d09c75d619638cb10de675806957c4cb450ee3ad9fee8ac55e42a35e68626e6945de32ee22423230131e5d84458bcbb595c3f49c4d8238aaccc76c72bc514c804a72dfcd754655b960c2767e20771991cdcaf9e097638c940dc61ae31f4e1e63df18037979ebec67c3204a61be80f1c2b941b7a714a0bc25b931238ac50fc74f8e69bcc66db0d85b102b11679aac18928544858cc90fcea80bc261518b249bf14a182e155250461c60d449e1c9a0dadb90addba15a47f171ea68589ee00c89a9229c1a50e2ccaec0b12d8f877862e59ea86044dca166a646858ac723f7cec30cefc9a0b14b675e211945af64b686ead9d0c9a53e8ce6dc2673cec8c699f47db78da5dc264ad27a0f65a2b36987897ebae90e79ed3bad3550777b5ed3bb013c7295a5aa85d7590e16443a98a8855716a02169548ec2148794c0e87016b11215dbf4b5e735bd1bbf7bd736b55c9db7cef06c144fa2a3d75aeb5ca36806b5bea423c8d04e1a6c1dc0762edd655d0e181b75bccbe5760ea3ce83de5a6b60d26b8de635474e7a79eb0c4f075af61d063d7ded794d2fc753f680b58e389b2daf4d9b1bedad0d0c374bd7461b5feb32979bc9d1f0746c9d1fc8c78e9ea90fe77cd3b8d9ebd5e4bcf51a1b1624793b522b1107f715a422a54e8a10f7ab1afa7961e2c56a1bb357d2681adffdca13e2d8d23d1a72ebe0393f909fdb1e60307ba5af75158792b08af88c0157546179edbbaed75a93a0417635747a328cd2c26a9a1b1bb36773e33d1c449bd4030c625a3b3383d75e31da55e6f64e7da69105ce617cf4d3a92faf5c2fee3ac3c34194574cf9643f7bfb629a5d043c3f909f1def1545354c5f039ef8a8646cd9c87a922923d50c0510005317002018100a07c5e2408fe338557714000d4bc4949ca05c22914964a12009811404410c42c610040840c4186520a3b100b224c361c0bd0d162614945b2df610bb00ec016832ab1da3cad9e4eeb862ac368113d0edd16a5c8190081456c352da23b5ba4d4f1f2b8a51c59afffa954b356e58e42940eb19ad81afc1e14da14871aa9886bbc923f5ecb9e8944d7bc9e68306de7759f7ce390818bfc2e08b5f1bdd266409ef1f47f7634e825aa6c111c6e6fcd57ab39295d131abfda3e34456aadb3862115bc7143e6776ee66c01ca872c866b2cdfa6dad5cbc3ade0656f7f18007fe9b54ca4c45579b1d837577d0217d9197bd82b08a506fcee50c12dcfe95d9190778a6be7d61ccee0571843c63bce12c77db5338443e1106795e3dd47dd81bbc7dac8a148b7359baf2e06040cbba897346f2900d247c1e4c12886ab78b24716667e82dacaedc7a933ee37a05b6a9d9c73a050b26216b746386df15646a269d135a9d474cee211d3a79a38e5eacde10a99276bbb08345b3af5f556f4dde4aa85da1279005f2e5bac05d9462b0eb005bf067e1121d6dd1938e7b4871f240534eecba546354906a59e819cb2a21e5629c058ff2956e8ebd328cf5889b9a221362279214a5e0d45795e6a23ff4825f56a633aff36615186c9379b99975e292c262aa045fa460efad874872ef5f0c7482942883474da74b80a247a2006e91503f4c3ae8ba3394e6af78b5b1c461b6ae7cc4ba26d00a4833b525f5a3dbf4195ba9b12f1767faafeb6ee00477ce69123a73186e360674c5c5c8e77761d5381ea891507c8d32c0ebbb1805f712b9d5349beed5721334c8aee47cd048aa1dc681323010c6aea1d19a5180f71f0346c6321a043678a684c7c2fa52fcad9f6016572b548e99086352b2d2d6dc42e198e49b2b666e19e4987d134bff9fdbfaf82e2e1161b297bb2d823bc737016841a88493305b49d3f30a5a797dfa560c4e2d2aa2b3576b95c53d8485c3be1500cb335ad27e33312b3b30cd31e909a35caf57efef107404c402d2fbc0d322ae465f4a5d4285ce3bf0b8684caadd468b1d5f7876ef876ff1953ef300491444b114fd26bdaad6fe0132e3daf4f76254b0356e63b330d2c1ec46c072ef71899ea748b8b6dc9593e354365201ca57d31a40d0428b210c04a60f697fa7aa2e536cfe9a4ecc2c95a58061674eb44b8d318d0218966a31247233a1c83ee5bca13bb139dcca5ae9d7385bae98926a91ad8422f62198a8dc6f1643c3ad8f965a327ccc073b07c23b1714a0cc2f4fd89b3c68343904c02a245e988f9ac0e05f7819321f01aa151603a001758f129162e30054a49c57b680cb0449a96d419760c314916ccc265b5b80abfca02c072c21d16fe137a4e999cbc2abfcf121fdb57e136d95a59211959143152bcd931590e320c20704fcb30494f6f579561586e70daf8ced1b5ca2048a0c3f21b2df7756adbb6875c06daa457b101693004e00a5cc196ad5eae24b566159923d52526d16b31ca9ae956762eed596996a37e5c53addfa4ad1e9423a7bc9498e70628fc43a212832d01406d3f4a309ad5b4e997eaad7b1f7e0e14bf5c13d2561d6853916e2d89149b656152333ff4f6957e5e795bad2cd8cfad357cbfa972ac16fe37c2ec9d27dfb058644ecb0d20a15d607862d3bcfb2348df4aa71a03cf6a9c3ff2161d4636ce566102189975d45d94d82d479429bb4a2dbb2729f3b2fa66f5aa9edd02e3e4716dc8fa3533cd4a72f7ec646c829cc606b5f0ba644642d25fdef729f63c4d14f5f2cab955078ba83ce7b7f361641ff0c49822ecc3c5e5b49df6786d32a208c846f271316273c0d25614e9f33c912265575026ba231061fc7fa9a8e361a202d3275e12b44028ae67c2ebbb1d3d2bf2d3f981a28fa6cc4a86db0e94f2570a907d9da38918573b9c7c848fc5a304ddf68fa86129681821a7b7472a434080d128338c7c9f7cb1ae2e4e584cd63d0bb9b0c0b4a43630743510f27a7ca432863f6baa5184f7970bb4b5f58268ea819d19628c1ad083cf65d136db4e26d7f1e9fa6475a9060f84eead51d1a62da7cef21c762cf102c407b927a2c2fa9a29a1a25084a8a1f73c324022b87e5bf04de15b7526d240bbd9d2b43be99943ff794fe99ecd1ef168c99945ea72e1b541c29ff33ef4f9140c5c2f7346cae99de65d20553027dc2fa991855daead15097841f5171bfff032c0c859f2bbed160310016a0a33e85d1ad76c3d5cacdab1e1b48f28f72070b6c6cb14bbf0687963188075f010ad058b170f9e61be760c0e2ce11b9d60121730eb420990b2c063bbac0ed560a45b4d5eaece67ef62840740720d978df1e6e374cb0b28508468d0b1b84b2bb92ce78d5bf3758e31679e0086b17c00ab15208cd11dc45f7de96a389ea2092f383ed245bae0e8bb61b48796945708ae03f75b9b7a18ccb22b83feb9ec090b36a085af1f44f61dd8ab8c02fac4510f39a813ed41db8d03d38c56143889505459588314598e60fef3f3dce01fbcc2b8841e9a845ff1f1315fa9f48d3407d749bb3f25734378c7156be944d67ecaad9a801be32461c866229c2404251a74f09aa9386449ec61228ac84758c8ac60f28bbb170f7ed6cf71241e8aa47f79f1334fa9ba8d3187caa54b84fca7a252d912c82b351236583ae8c80e653bde6479b94215847d59c8f3227766f8b50a11049978ba219e85bd75a9de44162ac96d709176697712f296ef9311754d29df22fce28fc3fda53c9929cea1040d03aa9474eb9b9235637f2910102d440da8822556acf22dcb23424f6f13baaaa5d3119dd9bee6209a8526e9547e11a779813b50fc652bbcee3cc4b6a5e432f579296dac9c6fb2cc7132c4317ddfb9e7137b3e45a3fef30a20c8f593d3a84f8a67471802c4b12a8e38aea834590259abb6b8c989061b7076142a65ab98181aaae7176a43bb04295763417a95bbd351d54c441b3f42e9f9f7f667dc0917dcb4ceaadc0d5701176d60daad47b14a18e4bc1ba79511c3291a38dcf54d4e842ccca73e42f16df5910b4a38586e56f03bd7a3c107a899b3c6e07a328aa21a050b6ae1fe2751f7402c39096d73860ba3983d6b10551d8010878281a9185e436f06f5cb16c199e22bdfdcb71cc87e5c3d28cfa175cc77eecd0f5fb53335039c57b35c3a7a604244df811b1eac92c0ce1086809c5ca41df8c9a0b7c9a2697378842a89613ddf8f3c038bc59f9ab5a5275cbc79c7c60766c33c2ed6e80ea77fbc97524ef9b224959e3f07f6968931a650ee3a623f9e27a5f0a4b91ada5552141feeed17d35924635efdaf12fdfbff65c8b7ee8a47264fd83a188a1a15eef1d4b8b1493fb1e7ac0d8648448471337d43d1ae44cce102c8638cd510ea1deaf64decffb36778232aaa4272cd94b45000ebe88edaa1e682e52efc989025337d0e821e21c862b14446bedec802b079a381f61a652b7cecf697339aa12006eb23d4f611b3e268f5a0b374a235093f98080a7f131b667dcb838f1eef0c870fc0ca3a55a21ad55fe82b6c6ec4c987bbdbb1ed089f3d560fd26c4dfeaf6ab9e44c2a0da02862bd982709c951a58aebed00b49e0c358b173a04504ff9297f69e63e04648b3499d9822c7408247fd3e0b6d3594f7f1fb6d26a92c9fb5cf3af9f3b4932109759a0e7e08bac017a77fb14d09e61e3a2949f5819ff40a426ca0aa0c999ed02d429e27ce9a46107aad39d17f4cae0266bf0e3c5d6b03384e27dd334a2bbcc748e6950a604c650141aa9445ee078fa7f6d114046c865e0bf40c5ef07640d2805aa230334f443d92865b65aa79844070670b06aeccd73738d045eb2504a6ebd883bb98b3154818ca02ceb2fa690ddb0d8da162060a825c444403e93c91d78025bcfde11314b1458f0ca11b9cabd129c2ea84d93efa2cb782474524496fd01a618d4b6953c5c8cda641c6200ef0cfe3be116800af17a1d9581d08389d90c876370e8ae7bd3e3f2a843d63db010e4aeb45bd1e89405537f1b7ad502559186d3d5ed3f86b2f1eb978645b6788a6d750c84477fe3259a7c9dadc31f6ee76016aef8fe88dfdadb80f63d616fbcdd02be866e21849658b256c0eeee0b0da42a8ad931b85e17100aea03e9f550ff36e83e9ca755ec3605761934d68095f28e469dbd5b61c3aea1a7586f04a69be9b555780989314cc8ac30c1eb31cf6efa00f024a002013da787992ee2aa9cca1f1ecf11cc3cac7fa0ef388a6e040175e6f713344dc8af40749dd3a0cb887521d67151ddaff0c5eca3afb48ce0cbd472bfe59660e758f6ef495dc4348851f018b65f7e6a68ef974633f07dd38674554c8af0fd3b87c9d8109ade50f0b8f51a17f6bb5a0c2aeebb8e2f220ea9aa219192d98a417f8e5de856344a8c157081a7736619da3bcf953f1e7cfd74a52652b3033030ba46e09f2a83f183c4d5bad52adc24f259690cf41d5da1ac562d49ccd581081b121b27d4c6308f8ea9027abc6d3b20d08fb47dff5c0d5b213c93acb10a7b03e1b7cda8206f3b282d162c772321c3412e10bf6aef9d0a2cfd3ecb39878f3e2382fdaec5a84cd1d82cf68c1ebd0cd5485c47474de297a58897f74fc6c4fe8d80ab4e5a3fb0ee803c6560ca3347552e2114c25913f2cce8b003691bdf7001f5eadb221a6c80c4186863e9d7f3c20ef0b818e1c466409d1f8c4bd20e1638eb7b3a77f08468d3e9bf58825d8ecc7a1eebe9d5ad47357f352ac0287bc8cda78b0256a9206ec016738580bddb9b88016bf222aa57746adc74f773c2906757835362089b2360b78b3a05d3f5cb565a1c2e11b2bf08cc6634aa378ccf59b8d10fc56972e7a9e50f5116655efc8e296e6de599965483d8cc361aa95847db00eb825a85976a188ec1422abbf5f49b4a216489d354b0feb685cc33273ea4097dd4c021d2bf61b320192acb880ec51aa8963623acaf4219fc1eed4dfd88375cd57fb9175086ac573c5ffee2d866f826559049dd6b0a720c7fb579dfe9d67f668be4c7a4cdf77d16a4f904b9f5fb4e6314e805b93acf22dc2ca00f6f7f6fcabb5c8f7c2f24d0c6971e13765d82b00e2ca8782061b1e1f3b4710741b9393ca5be6cae550994169a38d53058d6a77c3e900043b343d57bb326511bf1b58dba0e671a630c2f5665e4b699a4a9ce54752e84b826dba0d8dae961847264254c22fc934db86c01f6c6d64b69dee22ac48a1fe08dc40fd222b0ea7bc6559ef0fec5746b03b89ea0508b4905c58c122444da04a4c0d8ede1405e1eb4674a8111fc9a8950ff624ce97fb541ffb3da98bd907d213ea78bd1f692e63a19a815c2b75033de3ef59333802f00ffb7ab398a8e51d4a971e27b045999420ee71cde9fd60d035593f8776a80952f33204a096a59258a76a2c72ad452cc00afb6c90d23db6e3cd223127fe04e6974cd982e3cc502e701a260678110271cccbb73d27dadd1e56a0fa619fa9287b2be8f1ee15eb27cb4da9290c93fb8725431d327de1962edd8ce1c0f5c55c7e7f756e97678c1937283233feccd63e59f8cb7d3879a294eab8b575bb4041bd90fa5bb278d2729c0fcd9ab1a0603f66d66352713c48a9218704f9a9fc6a44528cf0bf67f4e1fb29f2ee8a53454012aa3e85af0329af128a538f584f19c087d168b5c40bb596b7a02aeba5199cdffb3ab72996afc63b3347c48bcbc96052c57b9603a52c2ecf182154c0a0ff0e2da61146aef9f76a48412c0edf32b41520c8eff4d645504c3e35b42a24e8ef39591545618af024b506abacd5b0258e0905483e37247c3e250a94069d49fe1a664ca23a5d9fb2e96e8ac5d34c223fe64c40bfc4384b4522a0ffa3ed6e8062fd61f259f1c5a78e543deb9e4106b08c50008c20f84f620143d99e991f93f8d21c3c2348d0d3aafbdb590f22e4b76b8e4bab6d3436e29958dae4ccc3f4e1c42634490ed0a78121af4e46c8bf51c3916404383e81f4f934107341e82f3024d61d269c795a8f7280164708d8aae71d71cbfbf29b0c8d6493563299c875a7eba7375b93be613825d815951ae9dc6e4da7a014e8f06970853874bf795a39957e11524be80242d73460dc2fa64b73bf0a45154ede12ec89fd4ed645ec82e354e9afc9348563046ef67464bfbe5fe860c61688f0f3b937197549d7544ffc4f63598e549a241a8bca15c99ae40ce42d091450ccc4f3a2b3cd55c487f3d00d977e09c4f90794edd92de30d5c0590d60b81ce6e7310e7b06c6b2819e86e0abb6be806a4ee41d46b16b5960017aca80d7d1ecddd8d95e61b102cff762b4eb1457465b6f52ee4e517512c4acab7a71349f2268f80e3af47a445fa341b5422b05072d45fd773b891ff5da9af93ff95ddd52fd613befa1adea1f544138d53362ba2b0c5cd8d91c46fa4fe994c93f5e68e0ba85e0df2334f435952e5eb4dea25cd2ee499c4203a53e2c6fe6e9b0c68724aed9a94cab7ecea953c6821f04edaae348ce83f613347476875a4c1a02986f0dc1e107ed47a6c49ed462561a0ccd9b6eefbef1dfcf39e21a774a3e2b83e95537646ed71f4e1bb7861475e01467d5edbca7b838f0b9e6235572345933983767a4def7efb27d1459231d3c35124e451d238df7a21de489fa5d41dc0f95a05d905966f8074c626780494375da73904a7bb943f340eccad9ee84e82f1744538775d4b16763390abee40e5713e955b74a1e6383f29b774a0faf83f95d34f2b97d973a2fdf10a938292e50283407e0b8ea60d5d91c7ae54445c09447496cb80c821eb0fd6dc93779a9228383430300879b0b6cdd6eda4ae268d7f579cadb0cabe8895ba48521a5d8c7babf4b8eb17f86223c8d3f2c68ae05f5200f2ad20e7c08e9c37064bacffc2d048fe318082fb0f4bd1da7991f15a25c37d62f9febe5f7d002bdc522d07615c2fc81be620a7b80da1dd393c558bcb9b86eb5f0bdd338d04e71c980728893a0945b4bc65c319b93ee4331200929596c8f3faea6e3ed4104c8514cec333ccddbf7da085049921e74cf22e5b5dba1084748b9b1a05264a8279d50c37e9838787a86d865fe98343d7599facabfc506167a8af2e949ca6ba5d5d7f504ce698f2ef6ca5c792d85e48ea2c2e508511c85c7026bafc9c580505f7b75379c550621ff81eff0c32b592a2ac5fb7b260e4739e40329ed53ab3da6784d97fb4be569facb15b368efc61c74221bb3188347415e9c30c6e98225049a3118f68f018e59929757f1969121d5d06e8777b774f3e93c11fa4c4fb3e19d9944d9bf350e6978c43b1bdb2b441e253530281b207a71be60d6a373cddd512293b3795fff658329200a49f2439c99a988e502c2a04255de35bf5c63c74d3a1d3b9b5222d9e1f4a53e1829128a51d0d16ecf7066ee496632793b96e826294ffc3133a2041bb34292e41a6144d2928c176004acd16d50fdad46a88fd62a99900ae3be108ff1d1818770f031eab36b43d9b0bb9bfcd0281c3f63b8677af5dc23035859d120e0f3232c4d48f836d185e698f8f5a1d053b32505cc33308600e859f07e8e2c07750e9c9cd0a493d83575254359c92b57a695d157f53ab8b84593105a49793d37bba21d1ed8fb9e931609245b6de671a19ec6bb19398fdeb80c377b76f9226aade247400ce4912483d5ad678c84e7f4b828119a741732e5a958722be56badcd2c41d1678bb23cca2db71621e35efd76a9f70d4686745ad6656c38d690159f3b322b5e89d865b62af546c6ceac11d45b31b91483a2ed1d446a5e01412760b75e667da07e1d8e9c1616829ebd9456559f8442253f9aa243e10aaefe8624f88c54e7eecbeb0407ae2c6a16120a6e2d1f3564e4ce8622226528973cb60231d1253954d512015a4b919462b71f2243bac7577fb10e8a97443393d889312bed9daac9ce7d2741a8dfb609fb93bae26a54263451c7e7ad6a13ab1ac940aa2ce8a6a0915c8a13a3270e39a4503c5e96276f2631593e0453661f2d8a4062028431b502f3c2514ffd8c23fcc64c56e6b01f51b0c58cd994eeb86fe075dfd83b147488d6ba33eb2c0fa2f8b08241cb37a8a3107aac21641bda06476c4474698e003ed4fd609cc0edcaa1913fdcc232f165ba994fd06f611ca5d2a5569dab076874269ffc69080bef1703cd7d197425c1e88c5c5e7f795b742d120d07261dfd7c8e9c0b0068f959b517a2b8442b320ca49bce90c3c47e1f2654d2baec7b718856f4cfd3d00eb0acd4eae9a96de8f2505329365bc625ffe69b9d37018178c5aeeecb992218b4e8cb0056d7658b3eef5cd59914f416becc73cff190924be8af1619939ea020d525ac241c2466cc5e2d811855c79b20aaa6ed063451ddec7208e6098747ca5a8cca100a361911ab23b784c5bdbb46ac0e170b08402ea3e585bceb10b8f8ec065b928ccb6e042d8b8ce355899abbb82762b65c995a5a55d954c607a669c41e5616bc9b744faf110a996422f5b11d24633422389beb82d570fa01bdd3253b48aeee2adb683a8a1984c5fbe5cac1734a78b7b75dd8513eed7db95641c36755401caa17647ae6bccd649a646a31422cad686881d4595a4dbc92f92719fb49bb3c36c361e0e141a7c4e12b1f33ad57b8a9284e31d08deae84d5faee214221674f3e58d81b71206c515da754c93debc225c6590115d0f5d25ea3fc06af17a3f8bd4c412932e575fbdf3b2c13ae0672f730d44396fbc16b3ffa693d99eaa9d911084db2194056d95be092b241ab0f7f81b34b4bee442c0858ad623072d999c4d4d3b4144a2e0b53571d9781ff2e0bd14c8a4fbac1d72915e4743ce72af9d6f51610668f153f3bf5b35d3c3d3942fa6d1b131b8ed4e976a042d0b7d1d8317ea14174297f86c02d00a9a482e9ed24d5587a7a8c12f64faf4eef33cdd908255cbc9fcbe82b3d78f8fa35b68d71fe3acc16fc386c6beeb59b7c6260f438b7c573dadb967b0d351cb0f6dfb0dae663cdc0bb0b906b3af1c6d728703e8a6e2643d40d4c4d09061ddd62a861736eae8f7f36d7eaf412ab39520be90756ab62c57017c576ed71308c35b8f44c397478e70a9e583174fa861052c3005c4927af5f2d4a47cbaeb803746304a959a2694bb34114f700a3dbc9168efce87d77fd143a1960dc728995e79d734abff03edb1c5b00ef7b02bfa83cc1112ba2203fcfd4aa0a3f3f4446c36eac92f10638f5cbfdaac3c88b423cfd7e08314409f0efcd01e142f30c4594a403e4540190946f33c6b7869af6abde618f7f6f73719ee41bfd92ec7d9d9ca843852ed3e38d1b71105ba18faee6b20fd57ab95e34d6bbb47fd26df17b5a5c10310d377f63c7d52a272166d98c5be6ca858cf4d701ef9255f6f60335133dc67723fa7262805c6a4123f72a28832695b7c834e583ba442cb72a0c8202b9814f718111291be602c71443b08c7cef4e3618d485fed04310ce32ad67841632eac67dfec546387229ec117c5a404214741928512f5184fd0ce382dc7c27b07dd85cb620bfc92d937919bf4740b2014ad4d0128ef9151215c60b50f6ad9a3d385002c821e952003440142db777d109dc547b6cbb08de51768f6c940a81983a0a2aa7ce6321bd60680d8e604f3e4ab54ba652b93969b7f63369386291e6791b0cb166912c37090174e92b598353f1730e4c59389a0acffa7894d274f2b146318619f27df1f8cdae680cf60efbf8fcc8292a97fcb7b79ce5bb3a3e8560028c7d299ac454e92e2c739ffed4ef0455fd0694913aaaa9aaaeac4b888970579a5237d488981451c0b8256365dc91983418fe154145fa575d38038a84da338735b9bbfb6e3989fe06c8a396a8c9b9b9c80d9508f43b52f9c21bed97f9f65ae1b718dff8ccf7ecda81b36e1f476c0e24cb69deb912daa218c7f20dd77e9bdb3831fa5aa0110f94e66327a85a09d805379a4cd34ee4ac7277e5b3a3b27cbe06e194a990d6aaee395b65e113c056ad47206702800f66f8891eef62ed60953720df98e104bfaadd8e46d56d8a6c08ae7d78b252f08426800b7913232a0313392df18e2206705a7bf4e07535214e16a2883e9dd00e80fdee084f035d18812f68232a38a62df9334fc2abe1a1d8a571917cbc287202b5cc85bc9d44e7de665fd1e3d66c2ecc642bfd72ccc9444d96f47ef0ccf0be5978d785121646eab4aa5c835a859b6f17ce6e7242a0f6f314ffb9a33f54b7413dba083ecc8f8381b5e6c5f0a7ed307e56605aa268e28ab4ab8d1f81c1d518171aff6cdd7800edf3b09fc3ac17f6d6c9214791d5400aac6fdf03833faf7145aa5adc5f189374c8673471b23c99145cbb0d92d2388711a706eaf04a6bc7b6fb51ef4c1aeb492a6b2c6f705bb51e3bbe999dfa1e1836180ffd3bf64f53a3a8d34735f191d40e044e77c0910304261f42308072395d4e84e0dfa00cd5777030e9bfd4299a6861468ff1504d318a9b761a44b7e7bc9281613382639f8378f653840808b9249501fc99cdcf7df41a9eb8414b3498c0d2171ebc07185b4a0949a3deeae48d501adc465bed32a17c470324bb4f5f7c553797cff337b76581117078b787c3d1f753b3734b98031d9970a9c6e9bbab9007cee74898f03e1eb256f127d93aa8cd80cf19f260bb6aa3963f3c652fa9dfb2b53e6869856e79d4ca23ddcc18638e6d0cfa38f0ca2073a096166ac3001d81ae8b4c5a33a8e330e515c879f4ef5abda5a4b244fbee1cbb6f3638df198e03e6c5c2520367065b6ca666d6326c93f9b23c001ac5d16410da7d64acc43d0cca1f67ff98b319dad56a8cd222ab8b391419833f245ad78af7f8169963b529747bcabbf8f678ce3a4655358305dc471b9927ce090ab4ac8dbc84f398123e6ecb0c313c21e14d37d53a022d30226db2dc4d979eaf083826d31eaa9f50ba5b1d664f71a57b8957a5421be6685a592e55897105ab93225f7330a788b2d46b74868c29452095d283b5d219be2713f912c2bcf60ee20a42adccb58e6f8be864454dbec5ce34a499d39c0368345ab0eae94e8eaa0659e18e9e42f5403bb514c4fdb6cc2fe62e2c95053938a8f66fbe9e273a79b2790815d39b25d2fc1dd073a03521e709fdbbdfa5dad9a2778220432168bd851125a313ce1a8abe88a859bc68a288fbb347b6cdda9cbc4cc574f2cf9fd2a8d2b2c9a6b9be33860484ab76292dc417308d39827f672fc7b66aa3c83af8328c4f7288f19b78d5f520faee27786f4821ef9356560cf84010230fe9fd2c2f9712c189e9129e591ad3b8489f5d4f91dff1157e5a926a6ca75258a8b0a6612fee2411f34acfca3eb4ffb0164d01606a54702e141fe1ba1bbe6c77a2d28eee96aa378c71d03ca2affde3166ee68a20748141ca07ed041f7a05014d648309023d9ed41082fd410569ea916c4e12de44e41fc6f7e3d0095490530753d510ec71c002e211a74a34491d70c0a8f851f168dd6ff06013ee67af01770c58978ab6687ea306c54f240ed9f050ad7def7663b29d6e765b91205f952331cc4aacf789637c252449c36d8766fe9c8348969e34c46c9cd672bb515b6e20c0cf7123d7290c70105cb7416da119010e86b8d0b808a924094b53ce2b88d9047d466b4558a0f986781689d57d0a461fbb961ff8aba32b543cdbc53b75ed0767246a1c0d09468f3da3c2b18b240c287bd2cd436721f3433208027523538481ceb5b63acc262af69718db2050301ab8fd0ed0bdce5218e066cac4b9ffe69e6cd0c570b92dba3cf16ee9a04d4b3618e55d37517c473ce8459ddffb5d3edcca4a0945d4ecbd586714c2f2797fcbef50c9c07959958dbe5aa8a44ba75b62e091cf99123b0c982339d172109412b9ce49837086a720d2171ad2d8051e2a80012de675e5bd2c59a2144dc1d43697b26e5ba67d08b0efa848694c8c0edcc0961e46f772f1e7d94d35f11fa1285b8afc41463309f216f4e763a65a3276751fe0657f00fa116a2a0cbf5d157355cfc701d8b035de27606da49801be740bab291c86c6d3227fe866e15809a278483ffb9cd64b25b8b2d0e7cf9ed44ce1c69dd658456ebb60d3063dc38dd6049e82d68bf1a1bf7b13481f65d53a9284b3fe7d0e30fdc43167ceac459c677b9853228d6c9445b53a2871b8cbdde6d1b147e141eb52ab4558b7f6d4f7e5e42804349cd92ff3ec52afadd954e9db6a5fb52f41981e0d5cbeb65ebcbdde5e6c93141da70a9b4cab5435aa6f4eff62a663ed5bda852b42699d8298345fc1fc4b9724546f1952a670e51dfd1d1a6348d2764c9bda87ca9544ecf153f28f65795c8170f1eb937b9cf27729582d9d7d92b7eb713af5ebd5558c7e83dc5e9783c69fe8af32a613accdbb683560247b517ebde514136dc507161a885002039c65cdbb3dd85d118f278ece00f8a68d97a622b706b204cb2d6a7b3ad008c1174af09a54c4d46e16add9e1d0cc736d0d29762021b6285a34530851433928c16995af9bfd52c5d659a7240c7d39dd09eedde2b20ffd818bf1b48a4b2bcf00314dfa9c0b163452af1fe6d19accb4c3ed1457ba3cdd39fca3f0f7e286160f51e5047f5dcd00e5461d755f4fe642c2173285d093f2224b41634cdc647ad1d91e482649fb6a55f866c4fa568007f5d239f4b378af9679f0c600a216e7523c4e6d6d422332abd211fb41bb4f0eeadde22e3c2d317541369ee85db6a532e5e595c566338b5472c882b364161fdeb603a467af9c8e92af72264bed8b5a26904b400ba6069e9ff43c9137848393ecf778767e2f4403a0931b2345134c7f880b2112a8fd1ab1faa36506c2db545db359c12641a180ae1c0adf1101af0610d98069ceab2e1a43c2ff7b7881f4ec78c6ab2821dc820361f9ec4186a9c7e0d3255c72a36a5218077a7003374c8f48d7c2701f98b9dcc68f7dd6a200e4c2ae91799b41d0fc49e63c0470838d47a451019369a51f133b1f0344270e8eee3b35bd33a7500673d44377809525dfd7c785d482f4d2415f4ab99750426ad4200c07c3bf4dc2bfe9b8d89b01b4201f2bcc8d6a806a2874cf06d4a84d7bd4f9a1988d0a7f9aa2a6bdda1d73055d62449c881e4a4d0e71b483e861d0f95b1ac58ee2db2ad7c9b66dfc4245ba5bb1e8d758334e361c4ead32bbcbc2fd9bd9ee21fe79fff2c3f3f41e7e8169035b01fdf3991f4419b1e19848d3b22e2fe8fed378ff99ff4f8a16fd401a1fce1bd78fa474dc985c753403267af2e3c05dd2e5753fd2d2286a8b0e2c0b8ae42c4db0f02360dc837e88c5d0d5a25b32b0ddc3a87e9c50c017c18a0c238e3afaeda2e351ad08648dee17749cd2d9f0dd71decc256a0a7eb10bab3a5197cc989b5a4b6de472db6b8e6b6311b706c6b7306e42dfcd6f14dd4d7acf8514fd36a9a95e84d7f5e85a9fe64d05e035b7a3cbda75225d7f7b4d705090bc2b2379012437ad2df2f1b7fc56cd6ddea29207445a03e0baad2956bfd9c13a7c9308d1912fa39ac41306b69c094909cf1e9ba1ce452cbe778ba2333c12ee5f6144dd8810b2056de787aee288e3a2f9a11f2c4a27907ddba34512e40283cb73fda220070df06215f3e3aba7a87dd6a7b130b37c8ea336702d6c64a216a1c9b483a0327578a1c40f526578e1a41eab4a1a81e6c16b2cc3a218bb1bae333dfa376b643dac375f3b87549545e793ad41d851d3824a27e09c1646f99477b63275acda1026648a89caf88be4ba1e279ffb436f71989b1ad94d0d824ce8d0ef2ccce4197ee6ddd916cb64c9b7a03e1e3f01a87515fa1dc43e2236aa89739cc00723c4d2d44150b2a102223fff04e02b38f2ce32ed7c4ded9b34fde79fc015d44f40dddfcd121d9b8b09944c42430eb415539c4c40ea4b670171477c121b3247abedf04b3b8bb793505571cb128f6750e1f419abd59c0d3cf481e40a81d11f54ff33f8211ab2ed406c10d9a6f22c593d4f93fd400b44c67e3388900dc9fb35761ffcaee3fc3b7b552e88df504823bd4f94bf9466ae5198089e09418350a2ba066b3dd1b07d6637970c601a4c012c30d631a2d05660f330544fc7b9b9fcda8e3e4c4f63297b081fcf5a4cceef43734bdc750f30546cf0cbadffa6ce018733e4d375e5a0d1997de6d9d4095f12f44ccf14b620061d0d000e7cf1fb142c28ace80f3bb30abd1e7cc810059d62179a72e5a6f960cf55246727d36a558ddd880f2b581daf738e73cd289c9a6a726f001654d9699a82780608b0a6768407768476beac679ae63f6b753462e250c0164101cda6aca41151edaad1fe76dcf7d1dcbf7d3b946b89d834bea9199a076aeead3bdad48c682d91b3b58fd1e72499bda005025a825457cb3474c3a0974fec1842336abb55e43f531d7152683b290345944deb93d04229acf5b5605e64d44f5f6d5c0fa1a25c091940086345e6175804d16998c84021755b56abea68d7d7e2695d79400a8a73985d9152ca6807253d43cc4a37708fde31ba30ca336c0e0c153d19f1e5587bd2b0a0d54bb76ad3d73abd5962ec0fe70d107a0b6dafe6f15e80ff037edb2b80e5fef53eb0dfa458f90ddf066e38fce2ae76da0122ae8a60879400c8a9367d56710530e28ae2707f383c49e29a7eea47fc2569c74d5f057623da7bd2fee7c24284f7dc3ecd9af7676db0114dea17fef00998493bc305c4ae1d876191307ce8c1e4b188ee2e528d159980658a54c24645c891a258e32287bba87d28284558837dc6d45eac3dc7183096b22a8aa90c33a5a8aa8aa1a4f4555c09682694a0b9505497a1169544b9c00bd5329041f315d3113dcf9397762382bb0d0be79c767a8ad9bc008f4abf89c13c1e9cc8f340632d575c7f6e3b57cb2f87185bdc0696d952090d1a7ec6a8689e8aac366ba32276ae469c332d58202a04c1f2df5231e0f33f56416d67e8cddd176d8cca1f59bb3f7a388949988ef625abd00d5be798a7121a18041091a31f42d0856705715ba3d677f31d3beea519fa4aa84b3b51061c27cad9938c95bbde1fe1e6fcc014034ff20a6ceb92d14504e8357395b98c8e98ac1397e1b259299593c2d8f6aa4dd776cb363b327e681eed8c793c3a8fc047b1c2c1564433fdc9b2426690a79d8306b1bb1211d3d29dc73a463460168b04e7fc258da354b2485b8fe056b0c6c65b640984f4d8033245fa99fbdcb98cb3f282d84fcf05b5069a2b8d83dbc59129d842f1bf49c64518042ac2f7f246160eae51880e98c8bf06dad67aad2246ab364b54e5e5d3755908689b9eba337e969606f3df9b62033a2a428a3641407fb3c5a60bf4a087a2c77639519dda6cbcb85f47d7044cf1d4807198d76ed37803582b6080582d0c6c24584be4e8bfe912bf4671f4a41a640fed5f9d08a2757acce961fdea6bc8fafbafe63658ff85ccb656dc0e6016f793d6ce842242126075df101e4cc036058406ec2a60b7d7b5e31ab8c21a7e9c1aac46235054d6310283f936c37bf1a5c0087a8a5be33730df6b796f9c1def4e39b53171ba4313b44935b070b96a585203e256d55f30d06882f97743f584ba4981343088f439e9c058f910c44148bb69d4d8493393a5ebea88f880acf2723d281bf611e3408145b077afc6907add4626881f2cb38132b9b56570234665415ada7eb4db4b9a31af3a5767551c5cf9ba3af3d28ad4a29684098775503df1e054ff5a5c6113be3cd58a1fcc9ccfee2c5210b99994fc039d8dc2c9d8454801a47f794fac2a8ab158da1932c7d2e77e08aae159b11aa9c16bb1bfd92f88b13b72e3464259a6a7f38d16d3f0d8ab059e620ee1ec9e8396ade887df6e46f7978214bdd9d86fca8ac9c3ba79b14fe3a411fa0a2df64353865f49683012b1815dc531a2d0b76a6b7a0af3a31296ce86b742dd1fbd28ad9356e0ee4c296c6359a73f483a41e3f2e20653ca3637f9b07815e2ab9343c2cb7ce0d029017da3c1e967e216363a46c94e648fb28530eabf482965a020f6e7185b05b7e52aa169a899c775de577af8772725fce1a4ecea3e23822b04c7c58d691179cff9e5f30afaf490503bf4293e9778b2b78b5e3992928e314d0d9bed5e18772e6d2a386e7486721695deb3949065734d5ca73261d2ceeac6457291bb17c0001ccee5f06e2d590227f628042c0c1c3d8196b013505ba903ac6b863cd2cdf5af1ded27592dff5595209594d16b94da1f03b8d319c0c1a855169e62fdd7c52d2a8f21b24fb4884d85f25350f46a01195f6a9529ea10c1c06c572afc0a955fff5d2dc33c6406ea52ba6b7e4d1bf8ab1ae644f7cdabf4b2cd6ce648c84c544880eaf66eb988e2c112b6a163e48baf1c59f986b74ffd3f27c525e4515849c84ac3e88c4d58a08988f3072784a00e4417ef340f6c5079fdd2da80599a44b205c43a84a299dcf87ec9a416e8db74f20659ef20533ef3e1129efa7ae265cf2bdcd5b233f4b01ad0a075d401c1e33a90f3719c9ef3a04c5d9dbe2572365355163edf6cf5ba3fce2d3d471c3ae796de7c5b9e47553478630f139db5053f8ba2da5ff0d8825e80d9ede491b9bd0051748367fee090e47424412c1f7a9bee74900532b4a42754106806dd462616a7a41cfab85877d8d990bffe6f75ef8fb50a47b406c46749b4ae418cfb914b026d004d81ca15a45eedfbcb7fedfa346313adaca96170378fa6dde51f70cb052a6ec11f56385397f7b9417179b6da8438910fce17c5fa1591ba9b5f1b3d5b5c050a1b71923a7365a320e636a134c418e1c39fc2edb351c8dc3768aab65914e2f9b6420175dea1421cff2cc2e4c966dc9d06c67f35f450f1631e3741840800225d7130ea75512ba5b79d1a9d72fce74d064bbb018a86c97db095adde12245ead7fd915cf9ce6c3d5db384844d76a570ab6d71504e5e2225c1ef48695723175ecae460288329f6f682bf39c999d313f4c64c94f14dab1e28d95602e063dd48e6ac23276e20d91e1d1238612358f414b87448df406e53b03d51f688356c63c19724e46e20272cbf73978322e0c8b91ab3bd8f05acdd2f791497b7f947ab8b1d7a0c8f0689731e505ad0bcb9c431e9b6686a1609cb8e5d0c9386c44d2ac61693e26b825ac056f808ea90182b34d82c47b4e2e2b6f7d3069bc6b6e01b2b04a1e842af878aa612cdc8f0223a2f95642376c43e72613dcf74afe838666e87a73eac98e45f0bea1ca3606fd785ce7bd1a23040534893e10a10880825ab4515535c5a14e277ee9b5bc9a47c165841b63d5f0a13d37d0a94387e060879d4408e5cc73d65c272d71e3bc9f0b15bd75b535f52ad6e4bf359b186d647f4ae681c5477268b5ecc9e78998374b2d9c1747069ee789d94634bcc9b78e0a3e8688b4e2ea6141041837760b24cd632e07c5803090a4d2dfa5f1dd6444a0098e4b30185583f57e511ad832387a78045c301a2054c9cc5bc155492feabfebac51c8e229307c3da555bcf542ee7333e2452caada35c9507f666c60c28ade3aa264a7b35a2d64a14f4f3c7b2d394aacb7f39b092ef6dc1e202a1fec4692686113f87c342fd036b9dae6ba0a08975f1ed1e04cc4cdc7d263e54e106db26cfdfe0690b598ca7c7eab853ac46a617983fb73bd17eea3d6ab9051470fae28fc25930eede51a6172d77863a0f6d77f24d1318eb45c5039614c12f85017648e4c01679755957c97e61277e552895efa741c8955b33bf91b9bccfbd058e4c5022b2f367008ab503b33750de353215f71399540ec0e9c52ce850c8eba2311c0a42ea8c5536a22e328bc727cae63d10e9f7ed709e04262fe921443a44982f164ac18a88c368224214324c941cbaee06709d5c8122c7f571eb31bc7f96e4ccd8d2442be99183afa3e37990acf8aed40165162c01a9da31d8995ec313c4753a067e095dbeb70a8efb0518b34eb52ee091db002671f96296f5a0f678906ae4b07750bbf01bb9a9bc2b86a5e50f3b607efcaba1bb16e116392e072bf2e16a7cfd6825d0211d5c5f50903bfd80f72b5185b042ae1a8acaf915cca46c14d85aa420d5ab651377e6d41237e02c41a8986251558cd130aa1acd1eaa1d30a3eccaff060f23394b65430ab48417a4c3bc2729edd447fd754f6e788b0f9a2eb446aa2a89738c82ae4f87d31009a0a2178467c59e5bb7e6ec843bf3bd2672e04a67d56313859262d984db8c1aeec557fa81281bfe742475ff42eb6053db8bfe052a8c928e7b02d696badfcf580966bf051642da645e6f72b932b2316ceb9d9f6f0d5924992ad94283dd2b8913d3548818e3b644665888a885e782ceca39e7edb7ab1c06613e26d2116d14691445a01954dc329e4ae881051ee4045859d3b7ac8fa60a417f386b31152fbe5fde99ad19824bbe744766c10d2d8685119b37ccabe8e136f7bff9321eabb551d6aef8b339fe4444d43116b22de99d106309a71276667b800aab83111d14fe809127e75194adf58422ce97e009e100b87bb47e5981be97594e3b10923180b029102337daaf3620ec7473fa6752d78fa307ae0d906eaf5f19e264bb1b3e1d93578a7f4c63540190e8a12888ae346cbcaca7d0b07a3344d24f75f26d1bd0b1613c7dbd87de4147b6b2050bd3a3425ef8902efbfe54172e12973aba9aafd14c45827cd6d5c44e0d5e7d239a80b40cd88119fde8dec71804a59a15012a6135d06dcd5dd5022a3f7f535b045b654fc859239f48b4068a21417c7a8bbcdbf028a98c1a622148ccf1d6e426cfa905fb820693dd336d46acd4adbe63e7cbb5e9c8b3a1e0a431b95a223fc1239796eeff1f707a2736349f26b2e8728f9faed7a1e13b2fa63daff8ec8cda25b018cfdbdde6d42731776244ff2ccbd054678cde8bde327accdaf91b7cc51ab34cca3efc0f69b48941bea8f7c683751ca1ae6b3901a8d023eb59525fe1ad7bac8d79c4b8122b29cef2a74dd7ca8a28570f55d92f92af9397001a73cd4e38d02ba7de84d2df4e7f187c36a3f0c62a23e578c9bf532b8e29d9fe5c40835b9080497bba0eaec89d9dfc7b237dcb4974f6ab7883d172296d9befe7f4b3883eef3184b228f15b116ae07fec59e7a445c11faa22a9ee5e2b5b2b9847d3657eea2837e7512a10eaa46664ecfd718862c2af84feb0313bdb714f3a60ad1597ae9ddc4923db8e80e6ab88a71b7378d41fa357768c0e48f4abad6057fbf6506e9779ac27b6929b34e4c45917020e5e30b01227e6cfb7acf17ab56bd1b706b785aa2766dedccd99aa2b11b12bd8ba6e9ca148a76c73b5d7ace6f26400f92f99383a1053e2911496fc8e74ac41086a1fe606f9427c62caaa9e6730921094757414e83a54bb66579c85cb79849958ffb41448929ca27c1c552deb511ee677df0499b95fda959d1ef2cc66062b3ed1e81fce378498ef492691ab52e8a18964612a0517bb4a2c79a9b1a574ebd5ce612a1bb9b9e5513db73b03e9ac94920ce43eeef26b68bd7262c1ec8d321910a888f5cc82fa025e2b5f60bab808bae2a7376a0582219c3f02fd1d5d4af1f39cde92e067fa1bf73a5d1af8cb21f1f66126a145b04541f10dd609a0e3f4779311b731904ec175e8917290f54ddc2bf67ff9d314e97dd1c56aa29e6fb016bd0f943af0ae8d28659a67e11576d088ab10732f9b5c23a514800059b4be48af886b9ff7579518021c62164a82cc2c0bc51fbb8b429a4dd8018cddd89e2fe004653ed589990c6ed5e5bbe2b60b2ff2084264673dcda22b67748c4775a07c85a48ee28f962fac324aa86aecc69d5bdd2ec137454792a74b12876239967ba5272c275058c9fc199b9a7ad35f06d737c33949730b5fbc529f647bd161ab9601d36211630042a67da3749e2340a6b23b39e64fff50594ae90d21faa20b88153cbc1d9dde81b6720ee04bb0012ae8f3608b558094c1e22a8e20090198efa6fb575fef81cd55bce7652f2efbf5025c69f6db3ae8117cc81c6d533775abcd173c01581e86adf71ffb45e5baa97ef0c3b11780f295d88acffc9e141cb649e97676b043992f6e6087559593f691c6eb48cfb74f6f1a2f63b4ee7e1b135c4ce0b47508db4958dc99b924d8d4e7db73391e8d6f0fd00b8f95aa1076c36a5a34512f634cf0cafbca7bb1f2046a124a956b4d8f26b995192d338bdbae493e187964e6bffcffd063f42b7e204d7b81f1bba1a4bc0cfdd8d5692fd6b91ad80cf66478108a2e3ca55c1a24c408f71016aa8c40b0f7ba891bc170abcba7de2b97c082dd989826cade3e33371557123c8a4e02ae996907a9cee49629d22420d812297811ec6ae85821e14699b5e1d93aba48803044517b48f2ea4e10b0bc841f0b773138d97d8a18989c9d7f58d05588941b6a6a7c62bf6e5a6c66510999e637927fc23d3396f1bcba4a982f78aa0017e439d36a1ee0437dcb114ef13dc4d2b4a3475966ddc408635455b16533a3e95c716ef5157b8fa0ce78a2602024ece407a4d1a67d6e43a32058060bb031c2785a887f71e6bc05550e243c9cb56fecd4c65460ada6e04f121f351e64499e3a13e7b6749003ce6c7cd035a8263fe98859d3ba30ad5f4a895bee7f0c79009ebd880e018b9c7b2421b8a33ab63d6715c0868e7479ca8302f888a4d222ad413e82a3a8b1d740eee3b51ed8a57d345719004110b438ae431e69ed11dcf0d1cd70d002e9e75accc29918feb6547e10da2fea33f60bb901d9d79a3535dd8eb1400e95391db9d3d0e242fb8cac01c58f0731c08a2b0448f0171f11218dc28aefbaef91cc6abb44bba8c856c78f26b3fb0febfbb18085a1c5febeeb14eee750ad00dbe075f1e5eb57a81100f23a8e74c79c0b30081b65b3e93d7a90eb0391d1c351f02d6c4fac6f35aa1858478fb03bc8bad218d769c5abaa7f6590217a40f8e4db3f34b24ce246da089d76f964dce32f861c1b4915a04990c547e898e5afb8a38a0e2f3c2a5e2204fc6212836e4eb115c3218f9267460a018ecd13369843b46600cf3a7adb936f01f57d539b85917d959c3af099298855a74e240c456a29971b51044dc2812413d30f130c6d423be78ddeb3922a4677aa0ccdcc4347e5a59df92b3593e72d2a01158e23406e23cb5dfd805904afd9fea598e088010da0ef6d383d99f7ffa9986ac30facae3c75da294c7451ed34ecb65fc3e0ea0e00569398281e2838c14c580820430617b56b496fa465fc77f9c74ebc193f8ef7044bc2a4039c47c9ba07e6a4e20d9152b969b1cb49f4b89a2914d7bcb5bc840c102ea6a0301494b5410bc8c35077775e033e2852b282ec62ad55c47c172a1b653bdfe7750a3b8909926c165fa30332e92e2c9c7f6a5b5a0ee23e95f126e39d0758e8cf2e14883c1c6d1ab4d00b4105972a6ca31a8b260968d137d292ca018b3e9abeca0cd1ba87ab6107b4d9acb647ef760094168b3ca3f2c7cd35046db4ae49daf2b6d8fa374570fbfc5537dfd61253ea593974b3ef2e95b05029a0b22a238ae501cba2e52108de32ea1fc3cd7aa827029f6234157e1a63864a7dc212238c7e682b4ab95b9f917468a5f4b7843321ae8a6b4170ccb5709dd00f09831aa28e01e5d3e1bb491d5016d11c3e56035985d3e7edcfac07d1f9ff888551f9caedc21e516e37973ddd13fa3254631fe1fc80767f6dcde4d74ffedf719887e9fb0f5230ca47f226259b5c912ccd33609cffcb331c01059ad777500303eb0ee7d95b7c7caacd2965b0d7a382a17d1fdcb165fe564c398e0c6c78e24f9ef2101f7e74d64c0fa150dcecddba0485491281fcd6dd6ffe9026e0e8606c9927cc8cfce2f3f0bcac009cf5ae6875edd922190df6ec0512fbdf56e36bd9526e859ae0c8119cb6f73e32f20d4f6890a84e7a750b4f8abe4b451b41a04899e8283e613f28b7add0176849cd2fd13ef7aff7625245b9f894c00e98f46201d2acb54beebf2d542fd9a26a7011aa6970d2b2a4cc59f7b2c5dad27a503a8369dde73b4a45d416100d0436fdea912c9c5110dc9da9fecee3b2ed0c6cad32b70c42a4e4be60c8ffc11d7ab12e96344ed7edde15113f51195365d4e1c6716a5ba1bdfa188a9bab0796040baee398ec6019a9a646f0f1f6f6962cdc6d7e8c951c0f1408721e86f1476ffd381c03c01e07e903a994f1106d7c4f01df689d08a1e5c4af7d5ff0ec1e8c1180eb4e92454d9e6a125d6d71f2fc95d34fdcd7875b8d89283695215f5134632c49b2fc8833e30445fa9afedab8d01af8434802d44300b43509e00969972e49cc49717ad0b969c22f49a2be410a3daaeb6e9761f06dbda688f10460c7676be0c81147e4dff5beb89227ebb02a0829a9faadedceab54cf132f2f6414e546454101a7d258ad8bc78b687368462eceac2e942bd02a125533f8da1f100b70a135f7024a292f59cfe538d3af5ffc1eb24dd5c300055c0ea5e47791ba90c9881d290b71ab1f5dee6b13ebf27912165340266faf6614710b6c2f41ce2da8cc037c7aa8ded76a5e37959ac1d272f1a62aef4373da269893ce2c313c15e5d61d406698f6391888d96e25915bf5b56b5448cd2f11beb367d0d4dec093c541091b24272c7355b2e522799ac91fedc62514b385661ac427583e5e0b9232b1a6f63722e83f12e8da68d7db1d732d618d2d18def20a580146d92920e2674a2087f35b44a708a9fcfc5183df5e80a5fdd86d87974e8c9f61f70a53767d80b36ac6f68554b634a6d42a4810d8c0b6341eaad8bf36f1d7102838cd8429563caaa324a9f26fe552b1888e8c4bceb0713d66acc452d685de790f27cdf8bc1ea2c2ba64ba6ad0a2045272f85a2459ab79b23b29d20c02ab33d9d9c48c2641582f458d123b4929b54d535df6b783ca206a35f30ff785acb9358dcfb30bb8182a1a76171daf608bb815cf2382bcddb19094d574d5da1bac85a2c2ed15fd70f4412e66db8245ec62d1cc3254f6b9e8e9e54e437f53097221b48feaa53b378833216d7634897687236c1273aeb9458263c14415ab40f1389b9057e48f295b6a412ea24ffa0c03240fd3e242308dc419b53c8efff60477f4cf72c2a503f7f6b5a08bcc7744a31030529c0d25e3df3fcda0c9b002ba2666dbc55d6e174534991cdeadb643ba76cd659fee5e9966ee4d3a9af660e2bc381ade01fbdcf669daa4b7e600a8478f910e22901992e573af39e06ee606611f2b0406f98b82e621d0fe9ed6390f91e1d7dec2bca3dd8325e541efb91058a6aedf886abf184b21feb86e601504c2f498dbff473b42cf6c00d04da1aa956c12a68853b3dc9910a01ef415c4968704b7e04f0f12c9f88ed278fbd4257b39e88f360f7e1492c24263a8e89894c88f324fbb24bed500262727f6960ce07a465203dd3d02901419a149b643814e3b0f991af424b28c6a7dd630760c7c2a0389f7c1f720be6e8cc48d68cc6aef24a3fd5e63189906507bc7e7b4028e06755c19a4551ec8013d51174704f6caa2e0138485434a1fe0aaeb74ad9b473a13f40ad71d857eb208ca3c139a4d9837ae4eb25c7146498b1d8893b4e6e33520eddfd8d9210414bffdf81bd4787c48461a45a88c72eb2af504f082c7b4cb7a760eae08ffacb44dd84e813bec4805d95b8937b3194676fea3b14cc9d41fc2134ab11cdf79cf9a0bcd8ede5ab5adae6904d8b36b04971a854cb0f0e35a3406b485320157dd93ed09528ea6ed8bc051124549ac18a982f06ed551f81351a037d7651c4bc1a9ce1220a0489a60d7c5301fae828354e4012b93a90897d35b5992d738ea516e23a03a1dadc6f92c58122ecc94e821093b6667055f71ca0ca8b56ea823bfbdf1ced1d71f66fbe4b5ad58277b1b48768c865e3fc0d321bfa26654a2925990248036d032903cf417c0d3a9b01f2dafa9bd179e77defbd39df7befbdf73ed17ca5716f564150454d5f6451af04b15956a6ce46110be80deebcf33ee38438ed99516d5a59e4aea8f63c026d64b49951e9d0a5d0956cde39b119a55a0be0dd7c53e1a0ea128ed1e083f2ef5edd58c07cc440b8fd8d43c6f97b5789ad970a036b3d6efddb7a9039e24fd385d00d3e2b980eb79faf35608a221bb9241c9d163864949c686aadb5d6279a6f1e7797ecf616d17c457c0c5dc282e1851deddbdd2565eec617e723dc32e5faa24650d312cdeffd8f29ea27847556233744fc18ba94d4812e549b30c54a9ada9d0c29d20a3868944a07140a2bc2af6b860f3486064d8c54c9de7c43e16892597149694bbaf02db5db6ab0322035bf3379569def1140018c803a6fa26e471234718aadc865dd2db72fc4859b15cbd90da4b1ee4a0d66a70900bc73a9364e63777c1c45c3ebd18f31073cb4f90fb347d7bdf7de3bef21fb634ce27a74df7bd61fc9ddae91fbb7462e241e3b282fb12d1b3d59179a6657382be2a0ccd6e3578c735ea36df9ac9cc61ce76a4ff8eaa36169b1e5c45737182385799103a585f465a845aae68ebefb711576af660f25074905929dcbf5c65e8aa69f96a42b9325a8a431bddd8ea5f0b9b62d359d509484f4407404cd7e06cd6c788df4196c6cb80db7b9b939f9dfb64fbf6dfddb7a106c1c8ecb1690d75a5b2b48516a83e4bda16499b480b189f1d39329217935a8dcc8a92b1b725213f8383a08564001bff5f8755abbbb248502645103c33a1b64d1213845c4fb09724bba5d4fa236367d3c4950513b31d0e413dae476bc7b0e2d397dc124ad641fbcf3fd0a8b5aa8b5d69a696da87d087d5f5b4d9a3e767641521ea2afa92c264c598f5d510d1debd4cfc6664f0597f30e2bbd1bc4f264e7b48278eb3ba9d6b1ecb6ced9035655a1ab52a694208f05c419ed2c75a0cc1625c811163ae26ee952b0987a9b169525b1c917cec66a34f15c7dcd11659c10685df3634303cb6312602e8b878845061491130608ff73f7ddd01543c19186933c7bca06210de452e9472be7c6d4a4dd38d2ea59363bef7ceb131f8f8869ff0ef0715513070c77350e1a72762e31b0e2a64a9020291f2b1288ab4a53b228d58856f7dc908faba2d4a26c306ddc813a6e5ead35f1d5ae94e8c405600bd70cfe6d3d48eb475a8fa2f531b4be87d6e30f11da10325f170a43301859c27dfd9123dfed687cf067bdb5dbb5e6cb3141e256601450ea6fc9afa8cf27cb826f29b3b74cd1fbcbbbc37bbbb3da9561bbeaace8a6e69ae45ec4fdc0e1bcd5ccb8d5acb405b2e5adc55dd3d46ca479e5c0b252e17842433a0b32cba9d2acb841d3626390ba573647761dab8a8185d1007b7e4579055163a86b87ab666bc58bd60a93ac2c8dba291bd6d995989596b42a1aa34a094af4ec996143a58c91a14499f273da49b9c5c0d1248be282923e399d989a8c98984b374a332a60cca80401988487047794e305d5a846d115910c174e43474240412d8054287f54b030057df47ae478d4766ee87ce54c5bccc081ba49622164a3b3a4a99171a19149aee053d2cdaca93093098bc98281be345d60b4b860e15959aac4c0a4c49ca0f49d605b93b63689363826b815180594fa5bf22beaf3c9b2e08391d98349d1fbcbbbc37bbbb3da9561bbeaace8a6e69ae45ec4fdc0e1bcbdccb8bdacb405b2e5adc509af6a6ad5b4b01c5ad6280e275ad3d991595055e7468d0d1718aa0b4ad91f19de589c985a58152cec4bcb2b5ac3d9d5c475b415a4a5935543a30566da8282f57785671527558b56abc2a02c5a2f7e4641707ed0e4c15107411ce86c50a3010bcc091614137f247819c461a07641d582b00ab446a2143827682a71244150043a10d488acc01c57501ef87300af8138126a0c548d61215a3eba805381a6048e10081aa173408d012a30202a2805fc11802722aea836405580b000b488d1104e009a3e8e3c82863a6fc7529822f3a6acb8833dcbed369cf6c4a327a196891e8458e43af36cf673f66ff639e7639bb31fc95c8f648f8c2296f1be51c3579ebb3dc9a5426b299e84c690483ec5248794d2a45cb21ab83bfaab5dadb5dfc2de8b5a6bad75e7dac3201ab1d4ee18e0e3689b13518b95540a031f47ad6efec7c751ab17169611612bf8370929261e8c0708f3ed65c8b4ba74bc2ef3f9a18545144c32334263262741cc1e0150de274a32c8061b5855c9e63aafe3c51b5f8d829255492e9a2f39214e4c30335983016361f6611c9cbb7d4b69e4e869a2e9cada517698f07083656252738dd1e335949c7369e7bdf7de24e59348f8e2e661cb16e6500d1ed48c1c1bc39cfc7b6f1bb488b89630c46a68946cdd855cb851aa8313a3e2d3f53f3e96e60849c95e7080ee9cf4fa8eac4e5e69604baf4f7abda7dae3dd454a4d10e6d06befbafe6d5ddfbada2877cdc7d675f7538b602fdcfb75ddddb2951b67273bf6ebbad877ecc79e673ff6db8a45b09f7a519fef7e5fadb566baaeebddfebe588903a293dcbfafdf7ef8eef775c366adfbdd532feac7fe7deaed1607d8542b717be5a2d075b77ff72efad80bb1ef9cd9be46621128a78aa5e494ce09f25dddace4e1ea89225b732e85f8b6bef0e3285f7527cfc8d052bd1b8caae14cf9f8adc7ad7f5340e13cadd6a4578367ee960e20c32d7b3d3eae6a2e65b114e5b28aacc2a899d5d4b481b49537f67672c59a6b53f1955f328b0d57486f405fd1a9935c478f0c5b5d1260a017356a503ad4f23d3e960a5987724c8ea980eae713e344d5c7c702b42d470ae806d5caed4b1d6a7befa6b36fbe77888fa14b407408b42244f4ed72ce39e75c0bc66e62ce396fbebe4acbe87f7c5ca5b58336b2857d1f4978121e4993d0c5d7ddbbf7c065889df1d639b462f0e4ece0e000ca6598afb5ce41ebef643933a8862dd1fda8b5e0cad7cb12ad35c80ec4fb5a7b2f8c0a4ebdcdee568109edd5a0592dcdb97d2e15b27abc0c6768a23776be8ad64a7c25b3417981cfa534802623105c7c8841e3d9d50c3273dd35ba3b3125971b20242724a8d3d4e757b965812abe2c34da6255cbb1c339e7fc1d81abc7455c5e8c1b9aa7d50ee4e481cc32c3974e57d6ace94706021f439d945d365452a394bc9257d8f05e485d4167a830a853aad7750f304a28cda50c667be9d7964a4b30bb1a13ca918c8a9155e0f684a4734451344f1d73a8f044d34748e89354dc39d1f431f171e9617be9fede7bef13cd97f8b1b487cccd91ee38fde1c7d21d23bc7befc78fa1524244ac11bd5debe657adff76de563677c38a7e4a7228fa6bf74ddd5a93de8bd9ea9ca072e8c1e68bc3fe31851d1403e9b2cfb788f79e722e2f44efc4a2d6dbc9b3e35b9817045d1d168b17fddd7b743abce647fa1102c876c8b9b233429131f9a3a222e614ee35ed9b1addf851750425b51e992407907f43bbdba65211b355b62d3d807cedb9d73e87e8908f2d46bb53b695ad0853ba538161edef29864fb62e47c936c61082c4d661eba15b9717248e91f94864cb9cd1c66c6c3db16d036ef7248ebef7ee49d8bfeb2dab36a1adda8d988f23fa88de43d026b0150bc5367fb6f26dcd249a44bb71ce3d09fbf310b21892f8dbab9bb6e6a347eaa7d84e86401af2d0fa5db491b6102e1182dccd3f958f1b67671dda9efce32a16cbde3e710b1a05157ad026f80ba291dbedb71aabc4695b94bff523b2ef5d499b18918d3e1b55e0be1b7f703df73f74bf7d8a9236e4ddba8be88680e011b9efbe3f47a4b03d37fe9094fd0f483c35aab0b128b44847cac7316257ea45f9284644f6e7539bd8bb4f77b67bf124d588c17eeb871d1e6d9b319f7a79712ab79650922bf2f0c821b9fda155fe76a9b3da04f76df76df66ec72f16c122584b1135166ff0e20d36e0666a13ad55ef64db164db19b4ff9944f39753a274702003f5f718936fb33558bb4d8e7afff1087acc053e0463d351eb5c8f71aa19ed0222b70bf3dfe488187a045f0340266559c1530e9f1535e6557f54fad536dcef8a8f37436df6073ced9aef95b3ecd24488d45219320f9946f6512144abff5268841efba97b23f9f9904b9dda49924dffcd6f7692641f2a2dffad60ef0b7fab72d8b8ff47831c6b82bb509138a9df951e463cba7bc6833a71b87f0a27c6c95f0d188d4d3a336c1877056cacd9683ec939e7ecb65fcd67b64c7c77e1d928b708976ec238728b414b41e23b1118516697d7f230e3f8018e1edd603922decbd7d6bf6add76b9ab585b4eb95a3686676bacc69a6e619a1e28615f1580838d97307b4c962190181caa107fbc9e8c7147650bcb3f17c460288d87110e815f5d6ef785e21f27e871ec0dab920f0fb1c36f0038b229782f68642426aa36de58f8fee62cdddc0ebc7333068efbdf7de7c4701f302975bd8768e1443042912874ccdef2af05dd775ddce85047c0c65823191be36cbfd661b098eaeb8aa5ed0588b7a183caa9a6982ab03a441e9670a8a8d49a86a990091d287cf05adec67a453a5aeebe69a970ac10b27bd97b51b28a212b22337d79049258802ac1b4372da6199c8cc5e153815ab36a7173a3e504916d0a460caf038cfd6b074cba7eafb76ccc8d24a6b892ad27b52fb6e565ef1c18b5f5f6018ce4fdc16cbe1aede902badb9621e1f4395028d8ea8648d5bd94e29119d80024318000004604024086220075268b23d14000937905074784064384c400a0643a480481808858181f1110660100682188c63308ae328ba01f8f947eddd1245553a97e9c41db608738d53db214e3e2ea871582f5b28bd251aba38e6e38f8cf3b972ca65728aa7198256626c8f9cdea38bc2aedce663fb8bda3596316cdaf93aeadb763cdc01e75370670fd30ecf4d6a8699c8c405518b4062bd900143b96974fd139d4300a4cf3a969bc4e8996a1efb465655a791c800bedaf20ec857b3f03d16b95eefe70ca43dc253a8d96c0986f9249d37f4d18f4f5e40b375dd848f1d11c9ee8d515e1760e84338dc6dbef02fe37b56bb6b366828a641d66880c99dde96c945e7d3fb146b4c1d60dfe0ae7e2832179255f9a8a7c25c0548530388f7887745c0a8204a0cfa952a8d55fc16466f04c6c4b3d0a0fc626c0803c4ba0ec45874b81a6d14fc8d857493b75eaed0de234abba2a9bdf4161e34e5800589994d3ffaaa30650775a91c161655618b407f998abb9a552f46c2347d759ecb6c4dc2d1e86010683f0c39bfc309ff09688d624410b88c53177ed01767f02f48c450d6717a0a31149718f3087749e82e13f6dd1a841c26e415bdcdd0340bc813549fd665fe5dfc5e5381a0748c0b160254cab078c15b35d71c9570931f0d194e8ddc2da8f62fc76cf09e89920454ac552324858e201a4036ce58023552099c59764ffb2e727b17118ec0e268f651d5d4f775133cbd679389e36ec75b3b5481ece4dfd3faa4500fb4521b197be2de1733038ffc6e6e5424023d48a88f47e870a40b8f4b2f6b8d981160c4987877707e2c429f9ff1a722e01549b49742a687950d220098ef33135d9b0f412cb471c4b3319cb711c370141ba2201cec20df581ea23838ef7294f7392380571610f2aaf26f504bb592d7621b7cb9ef5e84e9419f70941920f180d654a9fda0251388822d6fbfd0c05f103a739aed52bba1b020d2a842e51405adcb39ea4a7fe8a7409af0aeda19f499942ef248bed151fa5592560ba76b1117a4570ded57f969868136c6022da0f8594c0765a1168d6588b080b53541ee2bad0cbaa46aa139263b78d4893b15ff78ec97d036ccbd525b0a9ec81186a28eded224066a0c40f2bfe96fd2264462b9fd21f664d4abf1936f337cdf1e253432229d4054396a26cecf4b1e277663b47dc80c50b14e17b9581c03deb81445e088e386f7785d14291649a7095c1f15491467ab3bb6591431c141c679bc228be111e026a3225e7ca90bfdcc04e68417cdfc606bd5f52b31bfc7650f074f685612634a8ac6f5b837295e50968bc128adf1ecebcc3480d57e35f103031534bb2ca2db6f81302b41af85db2e6a0d2cf3574a403f77117689d6090b483443f79fd2988a5fe09115ec6e54131c109bcb54bbad3ff926456682044e38115d740b6839f05fc37f1350a850ccb9a0b328d6deeb9c95ae4d484eb14df4113e5470f3cd60e84c249b938df0542e461478594743048add28d411e1c9b264ec90ef3c4bd4790b88a05d8b1c2c92f4968f5369ba0d63b7fbc50586ae7069a96a7a2e9652c386eabdcf5d8076931bd7da96c3c604e23f8466d99d8d255b7ae5313b29d8128885a77647e6b9d6e04871af9a6beab434f31f05d14e51c9c730ec43f2b6850b6835fcc561aedbdf43120e8b38a0810adeb3d203a2b52ff0944edae3f1ffba7496e37f7623a853a528988d5652ddeb41fea74967a873bbfb0b6eab62423d876a0392cde2d6fb39b40c6a483fd00ba68585bceed273a8e75c8fd883d88f26b0ea308a379599adeb564ca67ac32f51a0a71aa2545eb4f57f367d13761b6e3a5a158474ba28cc131ac1a56dd802c2e8a0819e8dddc4992a3cc967513b40b4b9eedcf505605d4383403bbb8939aac0e4efa2738a684741652f16305087e681a8f2fd8b622e4b10946885ec3c508b09f1874ec69254f33cb16c6945e7bca2c19ce28dba34d13fe070ff8828443da8e10ac223e98af28d44cb5f947db3803f1f1ac41277135734aa45497d2ab55c8f0e2d1a8a364761817b2602778e8a8ce8ee28dc5c04c8ac5448d52466c9194a507ad1cc62755b007204152d474b77abe870f47c8304442a591e6127eb89f16634cf3becfbd21cba5bd1c57d5116c4890d844d346108c493a4019284815e34255c0e7eb6dc06a01f4241a3a2d65d3c274d32f51f6bdd6037974569b687d7730d618158490dfd1ffa56f5ffd82db85ba7ebe6e84c73900c3ae4399433354b2009a4c13a94338447860f514e69a2dc0b7e1063baa3671dd25a5cc2d4445dac86448b10eeee78a5bc67f0c5a13ce0bc0d767bf17830494818fb57a68c43f1093d8edf49c732d0a5848a46004a5d0e293614f8512f9678958a7a1cb745bab5fcf90ef8c92c78706cee612db6c80a49846241c24f4e23a1c7bcd915c6781c63773f4860f3d1960ace2b968bdb915195a82d1d7437391c80292410f3867e55769d58c2e874d30ec869a94106ba8a83bc1d52db05408d76560b44279cfb2a86ac0058ebf6aabd1c6aa3889cf4e138d8ea1a220f5bc1a918eb85e61e21f3b143091f6c5497611a0071ddf008163477ee98c0bab375105d08e87dc029646091d448486588a4d6cd2a15e69a0ca6b39326b85b6fd0dbdec3d0cfc26c7b42f45b7ac62ff13859e824f31168f0e20003e45ea90189c81149b3b8dd012607e41517151b0b09e846f053fcf90c1827e4c4d6b424bda414f146d389c1ae2aab6524f52ba3c9f82db45463a3fdba6fe5e3b1147ad4df153297aff96718a2071f5d9ed7efef0581999a0cd7f4bfd0d487080e842d036a881b791a408dbd2f09d3aea3b4b7c9c04780732ec6d5c42f1d0d707e64ef1c93c5a14cfead31cc111570c0c95fad05688d13ab5150930b751ac7a4b1bca4f5eb921461ad0da2616a9b1a84190bc1303495d546420f0b012a1704b0aec9713f48e46488a11113232025615fb09f33c85ce0568beccaa53d1a544f4010a1aae5200cca3b71c6d3866f7ead099c2ed1c4b7b909f80e0488fabfe5a5429d612e681222d8bec5be57eaf3de67f6e391e113df01c6219f93bb0da6f24c98e57ddc0d767f4002e60429a4223f11ee867ad791768859190f0a9ecc3973c0a2082d9d7c7dd595b4a0dfb9963d1acc98a22777d78f124f1ac416ed9176ea727cba217b83e1876c0501a443cf063a2625424a6ec20953cff81f595a5b2847d9e86dd0b247f86cb9b9a7a38ea935cbdc2fcc1ff605bbe7d49f6311a1656c4288868b36c1fc1cc15a70ef8bb1e206568e98d73936ac77a34847aa8e8d4d5e38f2927d842e0b8af9d46dba796ea19c5be3a5087c213613d56dc81a975a15610780a3f45287f34034fddef6a7b5d17ef9081132478cc2b9d6aed27cb3a323bb9bb9932a53e53bff6c439ddb94cdd71bf3f103e632247e5426c022844923dc84b6619676bbb193ed2c5c545688edf6187a0f44db382dc56a51675760ca8c837f18316581816b1dcfc3e8268e91d9daacf59d8029f3bf3f5908f46b005b57940067159bc5414abd318d8b86dbe4e300d842e1e2b28dfe8c2bba79216e87c55b154e62db44ed42222f58666bcb23f1e400b2c4d900554ad25e475591ca27b1b72941c06b0122384eaf1b6aac011eb467e52a681b4b659b3128221d9759a1f3d28234918a94f22aacf2999a3350bd284141b1dfe417aceaf8f82282974281ceca40e7d38a62bf9bf6d2cde7258546881a6c6f589185b895cd9390ed38c88065275feacc39c89285985147e145e8c22bea5841efe414c5eab1341a9faac8b07cc7be0231e0ce15fb418b0ac4732cac1c61f345eec246d8d9922fa9a5655155c6e7b72463eb9b367b18a6ab42caf06b85a88fe6d5388d8c6d0105bc80307774cbb70f15b7a0f02e0b5c6a9448468d0f571c24dfa5191a3c9ba04855342257ef22ab03d646d8c3da010aadd5dfb7c65a73703729143c423ab758d439255563e9563f2c4904cecc4fb244b95b150ed1c843f83b9f93f434fbaa2ebe5a56125d54427549d8e1e2296537df1f97235d44148b9a4bed63bb6f3d080678dbab856d1e41216cf13a84a11aadc7f3c7565b783af3ed94c796715405f4debe5b38001cd6d0ac1e17f195176a867d38cf3cf049267d91f6d8ebb7d6875b49632898ab2ee53f6f2031ea9c19d9e36fcbf1814681c46ccb6c531ff01c4054905c63aa55de100853c9be79682e89b69d7db88e96fce1905e45b315e7014b275d2d785cac9246fdbcab8519afa36aba06f52e71417a1c7d2c56c3b660835f79e157548520bebd34fc82bb5ff5ea08e4424849f6633856f5cbc2187f4f46984c85283b708a43d1a653ceb92e3c7d1d1239b64f25da4efe855cd765af3fd0dab22f99978a0b199c1c31667e421a0f41651b9529f0fd833ec3e0e15e747f8be36758f682b60b5428479c9e013ed3f7fd644154349c4359c3f8f5e2a301d89d41ae763b912e3130428c98303201c7fbf773384c990d7840c9f0eebe2d02bc1b28b74d56c3b1621586a275175a36586d092f073e5a6e01d83ea01a14957f547c89ffb6e04be5b0818b6840684712f4ca17a666627a4df8c11f04812211f8299f9712a4216fa0a348988a0aa81ca20bf23d9e8b12c621932bb3ea3e9ed93fd0846831cd409dea344ab6018aa4950e3abaf9292e03103430ca688b6a8aa5ed8f270d2a74de8ce7b7390f4ea45ca357c9c40ef2854e5792eda6fa898ce6a4b6d8e128722aed666a018eb7a70c93edef0faac8d68f30d49f9259d9657df8d474d3aeb3fc1834210b61da39f484086e7b4ab8c055691c920a7f4461a19896ac4b212a540824a46bd12b85bb6db194684a2b0ad64d7fdb1870521405aaa5e21a8ae48cda94c180945c91e71fe3e616a321dbf4f366c42eaa1341c5f89846c788a8f0cfae11694f15e32cb33858cae8c23e2dddb87f51bd8894c4bf2b86f287e71945bce7a6eca22a89518a3860f6922cb23f99ca8d3e02255efa4239a4513d98259724db58c9ee3b861e2d36e81a67e0d5020c867f8f26ae77a6fca2aab4a318cfe2bc49f092c58824a4abac130eafc85125148ed1bf83b8ebd47e64cf410b12a43afbf4483f30077d74676024af17a478f936ca19cf20467c12f2a8e16a6d05c012a6733439ad107f0fb988cf7bcbb81e4d51856dd22dfe26d95e35837a1d95dc3e72c6b1fb4c8c65ce2b15c40b30e0f96547dd9540ae9c4110faf22a525a70688d1364d2a364ee3ef8d02a8f8d4e71d408574728a4256dc31e1a9a18f3bb5a65a973053c4909e262f85bcc467900091486c4489376fe5e1fcf0a6ce2be1bb11d5cb801111c27fa5156ea285788d39432879b6915a39aac93f8000ed1c862f64499e0ce91d896dbcd812eaee0247819fc0989ce1d9c984dd18490fe9841c84c32e3858c8cf7981be79e634817269b75127a08be8c9ff477d12697739481f982d1b2481c08a44ca64966b14d9338084e9370579f499ec62b93c831c624b7ba601248cb4ba215c827ecb7dcbea91e9aba64960b50b93b3935e6ab661b700260d436934c0e8c6fe6f404f5c475d460de8ba6ddbe8af845b88e60258378a75aeff4e3191a1d459b8e668449d14c51b1824e8818c04e4f2e945c582d8d6b9de3704013b1130bb9057cde3a114221e6ea9c7db10e9f756d5ddfff7a0bad9dba1e07d52463b50e5ab3622d98d6f7ba5ebf756facc3765d59d6db5bebe0b543d682694d3656ef41d5ed580fa7b5bdae97b7e68835c8aee9eadaf2d6bb60fdd6f5785817ec7a0ba2b6526ad1bcb6d4b5e25d73731dbaebeababebfb52e5c3fb216cd6b825d6be0352bd7e331f5bd5cbdfcd6bd5887ce5a51d7b6b7d6806b97ae85f3ba68d77b70ddceb570ac2f056ac5a79a136bb0b5a695f5f5ad37e1fa2deb81b92edb7503af19b9168d6b5b5d2b1fd4dd943a7cadeb656dfdd63b5cbb642d32d624bbd600eb76acc7f3fa5ad68b6fdd0fab615335adac2ddf5a07d74e590f8e75d1aef7e19a19ebd158dbea5af5ac39b90699eb6a95fafeaade83f543adc7732d98b5065833722d36d7d6b25e7deb7eaec3c79a5ad7d78b5a07a576e9b560ae0900d72febd66d68fdd6f5605897edba036bb6588be6daaaaed54fea7e5a1d3eebcabab6bef50eac5dba160d6b825d6bc07533d7c3b9beaeebd55bf7666aa85d4d55d7961fd45d439dacb7b3b89ed3f5c159afd1da256bd15893ccb50eae99693d1eeb6b5dafbfa8f9797578d6b4626df96b0d5cbbc97a38d6a576bd05eb565e0fe77aa9d7aabfe6c51adcace9b5eaeb837a0fd6efba168f75d9ae750e06373049ec43a3c12b7c72d00f0a0cba02cdd3cfffb941b9be986b08ce9ab9adb7e4754d585f786b366235a2a81ad2593376eb6db9ae09eb17dd9a95ae13e71ac25933696b2db9a605d62ffdba955c27cc75842b75639fba21ad69c1da855bb3a06bc4b18ef0ae9bfb7a535ed3c4f5abbb66a36b04b186e0ac19fa7abb5c5d33aa7ed5af5bc83ac15c239c3593bed6926b1a68edd2afdb8975c25c47bc6be62db8e1041eae099d658d22a1a60d55bf76eb566a9d38d710f9086668dae2f6b9d0994c6ece56766c436387bd9e91cd0e95010a7d9ee14da6eecbf31a48c7c68a0aff7096dc6ec3bcf0faaf742ea4db192e11110f153aa1177b29edf3469ee2317607c1bfd3fd4cb242e6f56d7e5157d8aa5a8d5c5155bb70bb52fb080faffd7e7cb43e1d6d50eea7e668c0233583feef687270f8e76339d6b1d3a53e2cd5394b778ed76130490a8a50db19057ccd9e50706d54e763b2b04639c5fb80b7e20b3c4dc00893024e9c76705bc48692b6cfbf603a3f3945a6a092e10a1e5ba32f08707b1896f91412c9705d219bef166c3b9b34c69b128a41ef96205d344bccd69ea5fee96ddd71c2f8227f9951baf0b5025a29874da49d6b7c40110fa08b09f2115646e348a76abf422c37a14f5919af892c3f1db7d918026d6d4464944592604243d4c0003f5c636a7e34b149cb1ee8af23ebe16347cf50e3a90f8f4dd3b5c6c78942269236fe74e564e92106818f903a2ab050ad3500f0fb27bb95b1b924f59674b654ba3dd53d5e91b114342014e805f108a8605700c507d5961a2c6fe02b390f9acc192eac78874f90207f44137bc2301eea26ab19d00ce72262874579950f0ed7c0bffb02b0a3854b29ce894800cf83cedf71c9593738baec41853d6c161c4e00cf6db45e2ade01e718d002f8a6b892feb742a6ea998891d038edb7d01f2e23d9eb23a8ee752c0afd1848fb3204d0a8c008fe38f232ae30470d60c499dd8b75d204410581f7405211d2c098c7c11da614fb014e0619668d44fdf2db50a21fa62d8a014604ecdf402204acbaa7807a131cea3372332563929c24ee642a82da86382d65ddb9e50a49a32f92d6d60321fdb68743008c0a8150a1b42c0b73a00c58572271d9c929d854b14efc23f46abb7682178e6c1f86d20670ea5ae9af26821759b5b4a9ed8e8168953651403d7dfab7a005799a175b430c537f1c5bc64bc3e82b0328318b4ba72f0f03e59d2e92cbfb39b05534865145f092b41a8b468c3cdcb4a22dec3178c00b2128d070e7281d3ce247a98a13b44cb5fa4f253616744a74a21733fc4889df9dae5788e3fbdd2b25e8568cac7b9d6d56f92325415fd19e93999637cda8eab6a8dfbdad06c50d483fe5517704a7eecc82b5a54340efe0c1316a70c88cc8e2f0ebe8440699a9628e90743c7ea4391f5d112fca39c91d1071f85565c2a89361facdc9f69f0b5499ccc810714227a7e836ad083da406bbaac5d1ada2fadb9c1cb6bbf20a906c7040ca1a1d69db6f28d3df7338d00f3c71a90d2e9e436438389ccba198c9df99ee2f3052b8b16e3f5c7363b808c8563080164177e60b905be96f723a1f4c10fcb8e1795a869d46f5c6b2b61e6bea13426efe154fead5d5d43f5c737117e5683cc28630d310d0daae638706936820b132118a45ad71d0a83c119ecf189699c858e438d5d44161ede9065092db74e8880246be1d6726e6fd610d01fd1da1fa4b62919de8966167fbfa0fbd9bfa3ff7cbf956b318fccbeefa6328be82ff5a3d8087ae991af16f22003c23058b96666db3d48e49188ae835cd34dd46c83f642e7199e741f7050eb3e81a74faf3d51f96399da0ed589d5e1d4104cac9c3f217b551b23766e82a3ce90a918d95c02903ca8821d267673c53d0bd639ec0cd2428d161ebe5e681cfa67d00fe2904c8015d550e0828e36a75c47a73322ba408c478c1cf991350dfcaa46eba1c1c8c1b6d1551c2588cfe2b0370512a9f9ed112a864651297fa245d2fc385bf5ff845d701d735c0d04285eec4b01cce5c1717ebad6a1479d55b1308d6fa01e7820a5d3cebe1c6fbf525140aabc7cd129f01d46d736c5cd084da53dd6f5bad09c7640fa1591ef4fe208078ce84053cf3d8207322c7b7fb757f95de2592fbcfbee34ac3a702bac233dc28a5938582654d9c31c1310e8c3c5f2d16c041330d2cd7bb545fb3cc0796e14656eea883683321a3db8beb60d85a2cc071eb727cbe279095bbec07990f5d96333c0140df0a08320347fdcc8eccbe125f30a137897ca80a6c1d25aa4c95470f9589dac78303f2f3068db8949d46a0b242af6751062232bf55b7e306f1d5da77eebd26ae1bd2fb60dcc45078e4a144abf38ad68fe4cc887d3989ed6bec67deb96a54b86b428698813d0083d3ad383adf9955a84b34ff911b924ad5f73b44fb73b95321b7caa14ac2cbe576e7a2a478a0557b08c29579d8618b07e04b47109b812f774d31e08d49627cde5d1f548beced15119e5372a2b2af5207178f640aab663a380eb36958e99965968c2ec40adf37a1b5838d491006500523ec33cf983ccceb1e47983123db608fdba8ad5f89baecd133a51543081fdb8e792e77a9201c5eb38792d1740685aa340011ecb08815d4d1cfb1978325362c71c4344ef10dd25970fca1cec4bc9918c0af43239b650affd04f9cbbe5e3f07aa8489bf79af74f08ff4e94636048b2e661a160a53c03a3e03b51510dfca7511ea32b1c2f8b890a79468e55f3f4894659dc57228982e0e95a3d5560e5b9132db94345222ce4351d5179152fef405478165e2fb86c8591a576371dc3f90cf4f9cfc97d4f5fd2a143dfcbd23d4804e5b0240fcabf11c124ae59ed1e54458fd5107ba3e5f2c18e0229e21192f47c4ac1285bd4899c5ad42a06e44a3eb6da55e29dc86eb625410fb3082c07e5f05c59bd0e587797de2cd7a349961f3f42694a4fe90ab786328fba6912487d0172ead9c7f57747b6534cfc9b603f68a0f95754c9879440ea07cac98655e058318215e3be7a4836f7a5b9602926817905b4410ae91bcb28acd8f7fec2ccbf973262fd231362255475284527aa4c3426e9f3aca4da9ba8de1322fb971b8134f36220e509825460ff8414ae252a32f7e9b2080f8e15594dccfec5153d4988b5029e12808bd77eaadd9b84c5148865d01b58e6f520e153571a580568fa4f16e3b127553b684b1e910e48f0a00ae386c603bbc0a4022cde9e296efad8541ef42a861e154b14933db108002a402d74e7f401682ed5b9e56be951e51fdd9bed86e57efcf18548e60acd8058045224e97fbda022765fd153b7b726885cf4cf20df2937d146386d6a3a95efb057ad75bc68659b5374c5c3a0e15e33eaf3950ae4bcd460146bb95d4d8437e4fa5956f0b04bef56096e660e43d13399aa99fcd2a31e1c3733c5a9b37067ab052faa08e4168df61416fc94908d4584cde827da8f994fb61a376a1631f1957824e1828dde043f116760143233f44b7218e949943bfd3b9ae66f83da16f415989c3d1054e7a5a6fc93dfb0b64d982aaeb5276756cba036ac5fb76f06676c0138f98e48804cd810c7966a0874ddc09741fc2912702443ea476b76c3b83b99069d7bf4595805404351025379ab78f7b294849575f8c2c47b41b881182c5540a314b38c6e99e4d28c1cb01aee48deaabe41dc32fa551e3212e5013421f64d945e7edd701bfe21c4a0000fd5ff40ccc8547a422daa0f33fda1c7cd34105be1d4daed5e91c4256c8d5b6be0558eccaf06f7a7003de535d8bdd7286b1acb965ee916f0b9d4312c0d4c76922da080a84188256f311f388633a454fd890bc2af3c45c790f5159af13837b0eb7ea7c93c740ce5a99cc8759091cb7d64533cd8277da48e36eded108fe481ddb1a65444d1bfbac3a967f7a32024aec0d9a741e839277da154fab5712185814e689613b80de6e5f57494f951d9b355dd65e3151b4d0c0d02a05296925240ffabf03f61600977510cc200bb81414424d5d130ba98df4298737d8a30d672f0ceecab41a493daf271470b7b0a05709652c99e229cf604fb9bb7cb7295b20e1b3bb3307110226b625101c46e1170d7461be0829da0665a0544a933a07602fdb2acf761ea6c8af857c294e9241da1cbf6dfdef32cfbdb0ce9aeee74ae946e5556ba747ceb0fb2264d056a5fe0a0561f57f129c49b214b24c301ec6305fec284ac0e532060d5261d9972d0672acbeba593d58e1f03cd7eca11ac65f471797d3e2cbfe32386c2a8002e79d97077800011415168efde146356a06b1c1adff9f6697c60d88bc16f0dfb64fdcdd65a4208219b10b2b7dc3bb00eba0eb20e28311b426766860c4e5664e8e232d22bf3015c70d2ad36a8e10f3c30d24d566391063408c10e36d94ccde8a18b993dfcc00e76d8bc952a0c5d5085a125670552512814aa516fd802638ff84bc9551a9adca8010c376a00f24d99492cab4192809804f621f89a02e72bc3b02b26466884cc6e1114e85119d615556c8149b9cd503aa3d2431766c46093e2b81b953600d454f561c69be9031890f079c15259512c75b30740503eb03a9d16932ee585212d2dc3b24cbe402d200c334a7a75069c55b8d6aac60eab3020f93289a5a810995e89bf8cc45cdacb88a437ab6952d69235f85e33d8cd5a5a5c3244a84ecc4b26aba9e9152db256af401c314c62f2d2549362c4559a504821149aa20315221d823dc5c21345c1a30c26a1031530f46ea0600d622dab6982a35635fa4ac40c2c92908ec834e04aa3d9253333d32b7943828dc44b06c72ccb322fbbf58ab9627a45de4c8b260de915ec164179cc562891662b1cbfcdf44aa61b15bd721c4f53d284f2781a4355a9560959824253113ff4a5884429334498f9425f8ae82f8efd8528e543b9564317748f801efaf798f201419d8ec48a95b0836445b997e5c1d19858b39b7980304dd114a6429a141f04ec13f30061796c629a8ad93ecd8029704cf4e905d829e20de778472df1771471d6308f0ea37874b8e3131c08c39b4d5145182425cda6b011af58c4394754cccdccc5cb08fe05c3beb15f3c0cefd516735736a4663a210de6ae89615d045d04222284b90b7411468210d28831c619247929a5bce65570dd3351a8798847f02e715d912c4198231eb58c5afaf02f9c94726a18ca6c8a5a9bd4f31ba617a6de8ed85662eaed80abd3bcd036e6b49927e4d161d9f110cd2b4fdcc58ce2ebf9c235bba8fdabe775b5c42e8ae58d7e809f45c422e2bcdd63982d2ca184b0fb56a87da3453f90afb2576617b5276c3519668c0daf4fdb237621bd09c813073db0c20e44815035e343a9a7d62a1275543652d53631f381a7d2c87045e58d34c19753cd62ea8cf74ec9526b17d9f46785722f8b6f0c2fcd0091d86ed39844b700c39326865d19c5428aa4c3cbe9f3e3e584f2cebe9ca4b704cab9adeb3a9daeb39d7fec8f9753ad67e98f7d3969ffd8face769ad25a45a29f449ae1dd88783bd779353ce77c029e73eabd4fa0deebbcfb043adffee91924b8df5434927ee9c39b9b0637aabb156764ac91a518d9b151c6462b9ad4e758cf461a182c4b9ad1a423682ca049fd697144a049fdc6e2503b26016fcc94d6a12d94b882cdd6845fd184293c55d7f024dea0c22459dc602282700d6c21c8ac0017f241854a883cc1182a21e2c401432afc111d12f009862421b8188d502c023124dac8834048810520f21067b84b3ba7dd110e0ddadc04869adda880b1b47c665f30b43e2e8c69d13509461cc9806406c92a00103ed65493e675cd79cd6e4d96c6b039b16b4e1e447bcd148e76c63429f6c8a6ed1fb3f197851d17ebf46a4008219c4d8237e0fa5c5b1bf2590c6a74f111b10f24745498e40c4230cd304acf612f3c38c6d835697ba641e31ac8ae0068a2b294fd0a9805ce0e6196c5cc09ce8a6852f6686734292365cf349328a5996ef6c631a5d16a93d2ecbac09b7907159613e8e4eb2ed95b2a36419fe3dee76c663bf9ba8f282777795dae0b770c6db498d7322faf85fbb43d3ad804105f9e0e399f884f443ccf75e8dbbbc165d73eea1131fc1313c7f7e8e078bf7d7a3ab067f78988b9789f8818de2cdf9bedc867d765de47c4d89d2e7d1f115f367ac41e11f7a55b9c44ae4bd832e98590d49e8e1f392e2c5b260af5443be18362088d88f721c2ddd97d50dc652d504c2fc77522abf66ebc4889d12cbb10ca50e28af8258b1d08193d0840ac69da15679c526edbf617acd9fc2672cd71a3428d9a9da7f60547ebe3c2596b71d5f82c4a24d0c42e081678088267b462f374743836479c39f71c267b4729a5f7b21c1ba69977839e3b87d5c0404d9257f48a618d6934cf98ea720c82af6f1383790cd22bfd2b5a81393b477d88e581d48dde4ed334ed9976e30ca211d729bd76eeeac6308bc46cee709c4134227e06318920187622c6874e3c276550f011254b7d558449d1101151559a88d746c4a4e1928e91254b7d5739b2582a91286bc804c72c366aded69505176330f3184a10208b1998440d280c5f31bc62c60d550b223089164230fc86e1155180417c37811f5498640e4270c630c91c80e010865734410b0a74383a69611cdfd504717142b598a2422c00c104104b328558006206c3771862018822c4771776e0253eb930049cd4021712432ce0d0043238c19962010726f492d51894ccd518a8c0780449b400c28593336c81298ea74cc8112489c392c6f08a26a49e240b1617689c387e0357a06898e09a3a2306e72264703e82669bc1338e62cc52590c9ccfac90030d9e4af0cc64e4c0c239a322438267b6c233a3c1f3f1922bfd033c6d2012d75b764ec08b0695269b02cf98cc07d08859ba59ea8a41cdf4463600e659c006c0502e4006c090bc50fabca4810b287dbe31f4e40caa3cd7edd59873722e193b2e5e2688212e1f25dd826e910dc1d94c7ccedef93e9fc9f48a0749afd8cc484645a6ca88e029839a65cdeaf2cec1322b70fcf57d97e7b22eb3f2d1c6ecfb9e9da39d7f875e4bf6cf6bb9bae8e9b8b29b23febbf94a7c3777d995331ea5dfbdeb79393ab8f3f674c45f3da2d75c0730f46e0c81bddb63082cff45cc75a02e56504c82a292c8a126265ee79c06cf1bac991b0ede88cf54d9414b40e1cfb9c7e82e52cb364d1512144bae7bf46a8c3e89d0b80870454252e7f3b3f3d97916e11729f84507774c192c75fea273796e4677d91ad74b762ae9d2bcb4a3eb5349935630d53e77cbf34cb9d052bdd22b5bb489f4790d468be9157bcf83e079983521786aa87902bcbd181f3d1bf7bcd9a4eb3a8acd283741c44ec46f2a578667a3b137ea11b1fc13135ff7749e8efaeb3ea16243de45e53e22ae97e1dd70d91e6f8f2870cae5cd624095501a698af17995e4e7f699b98b9e2fbbc9d88d4893e6bdb4254b6f482028627c00e73caf252e2185e3b3474f470671e7b580325593a6d6987a2ddc951061e1f898240e433853923818c10ae82eeb44c43da240617a0ede88e7dc648073ef9e6723aeb0bcb92b3d4fec1ddecc952c9023d97bc7c53be7dce5e588475ad853229e33bd16ef9ccfbb0af66e966f5c24c6335b640017e6a718cf88b429c6e7b314f7cfe7b32199aa57429f42c4ce66de6f1c732ebd1be1ddccb923ceb30bfa6784c7b9f5891e1d7c1d7443b98011a2328244094b0b1b6d0b5490988d48af74c431ec4c01bc1c177fce19a0bbbcee4216e21856cef07248234d5291333c5193e633296af4be876ce3195e0dd085d088fc79e7d3d31105fee48897979723fe73b3e83e1171cacd11775e8e0e865046e6de79e6e988e70ebd1adbed1163f7d918f1e6801ed1bbd1c1d76723d6226e8077a3e21e08f06c1cf788ad2f47172e4296ee5864f759a8490ec6585acd8603f0c5d29cf7cbe6285a80af63de8dd805e6dcceab67433efee4e5888ff8b2189bbc1b0ec0deede1002c7f41cc3594b127c7048d9fc0b0bc0caf46e746ccf84ee843d8ed41d8cfa9e53e8a5c013a242fe48c77847de2cb3455b234c3eb6050e7354f47cd512f3fb3c2b5a2fc898851ce2251acb57906006ceeb01036ab5c9b3bcf67cdddc2a91879234d03f88449cca0ca8f31807bd255558f953235cb182c65bad54dda49af704759e92e9a31bb8567acd5e39c6b128600c4f2c2ce66cecacffbe763c6587a5d36396294abe3dda847f94c412ce1ab574366290f11e7b8eb721eaf7bd7bd28ef5df722c7ba7c1e05be60ca754999a28333791093f02e1b8b7e1d7a3a383737fe5c7473e34e9e31585ebf6ef6e17df275c9ebba2eefba74fef925e5cd20f908928f9388675dae478165ec783746d039f19c3b87e00cf2ae730eea3cfbf040f7d1587aefdcf3bcce7591bfee651f13c648e5b239277630462a4a7ce4e3bd3a97dee94d288821ae2bd52bdee3a79098843c8b0479aff6f36e702eaf8bfce7291cef59cab36197c8bbe27597c8b92e6be6e94dbc389ee8500e11440cd1e08fed64a9eb5e4230e829f63b8bacd5c2996a12c8469a288cd1a154b9d77e33e9c5630cc06300ae8bf717977f3c37bb1c71e820d9ad9b7dcc89bf67f92cbfebe23d74f9ec23c6d03d5085a2cb944f478917f1b739ded18b83fed31b69ba6e266100dc4cba37bff4216e163d889b6be8d29bd1b7eb697b33c5b44696e6e961cc89431fe277ab22860efa77917723de2574737ce1e9e870bcac098586b8b95b1874216ea6974de8f366137ca1abdc500874183705c3abf1c9171e97f2e9706e731ce70473ef56afd4739f3c8849445cdb246964699efb4ca15888b94fda816c0ccea07f6c7ea9f1e911bbc09c7390f31b10732e144430e7d17a9663b3fc77ae3bcf863ad17e37b7161874cfbe84eee441340234449d3178e2e87117d619833b364b65429a34efd92cc666349bc771ff5894cd93a522e6444e3c122194911d4219f27afd0baf469536d23455b44e55e7726e8c97eecd18b696ec91f8e9d9f0ceb98550868c618fc4976cacb28a7a3d5e1ec645a30fe659244b77b96ad6e658b62096aa264d253473c964326b7a455e1933b5e895ebca214d9a9f5246ca4879b70aa4fa810a388b91a62c9501a94b642a8bb99c73b4c2f30a38d39e024fad0cb0347f07511cf09cda1af09c32c04e64f8ba592a7b41953a7a862c411a74556529965a009f40e9d6010ca074d22750ba5096487fb1408c973e8118b7f417bc4593e6b301a8f03cc9ce974802c852b2349fd09b2c85279326c9f96d0643004471bddc66e20dab9637deba62495376486f138d9003a4f0510e34dac4246aacb91a86cea0244a43d29b2b8e5766b973ed1d99cfa8cd7660e7b07b59eacbbb04902bb324598a4fe2136982749841058921820726d1c60890212a999968d32b79b60fba0866af43cf027dbaa29378136d282a3ee9956c2a05076f23106aa66720b280b6029316807a823348e58a16c0e04c04139c8bc07d8626381f813b09376da061f1448513d036b60f28a31f443bb41335a71b5a0d03b191ee204da467a68c4d3ac618e33724e48db7059160a24ff4ad95a4812baebd09c0937641204b7d96c61193b849bb1bea6e8f49348c761b55871a9f67b4704b9aa1e619ad92b951546e18d29804a5b5dec8b20c6303ca09ee0ea1d0cd224c4198ceef3ba5d7739490fd0edb44bae7d07333c5dfcdde3f0f9d64619742375fafffd817f7acc83ee1b5740e79ecdbcddc3151f420f0021bb76703bba2836ce8d47efed97cfc5d82ee42ff3988fe73facf053df435fe6cbe0e43740c07c423ec2edfe9472ddfe9bf3b9bd4dd37a93b4b8bae0b77795d1f17e6eef67a1639b215a76018364325b8fe85cd4de07a905743eb01bbe8a28b16f6315b10108327e9fe8827d24b0fd91c710809c644291d0a768a87488712bd5b155dbe539cbffb84c4f9f803212cfac72291482412897429689c48efaf6b7c2c69fa3ef7f3f95ebf5b9bf4f9e7f9bbe7edd9f8aecb1317fe1c6294e9e5e040ffdea07b9ebf8f89fd6a40a0bb7c87584663dc409d57e3e35135c943c463c433e3a1c27a9034a9cff13c325b5841195ea8463c33d21451280f128f47d52ba0f73d1daf06c8abf1b9b05214c63e26bdf2bddff17270f7abf9c5fa9894a0c6cf36e6bafb3ed657d3ff42f5a44c536cf6183902e965e9d0411f2b4056f47d3e17744e7bc88e205b6117ee9a76eed47270b5baced2945696fe4479a4c27d1a95bea10093e850d0883e7d530191089dfea38d84c68c6c0a338e20d926d948b2f064247f2cdc9f73a8df45ef3a94345d1dea62a1ae0e5584f4b9b979f40dfedc73eee3c9a4503f1f10e8dd31b88392555141d94c93e8536c464593e83f9b2169127dc866564019f430ae14a6cf17eb0693ee05234bf49ccdd90ad3d3678fca66075988512cc59f89b1dcb900f773df608ed7e50e853bfb663d44ecf5c834a99f5d8f4a0e357b54bda2b857b3578dea790a027b11404733fc21a3d9a6cd37c001493ccb0c8e7fc0121c8fdde0788e9351ae9edaee9cfd9c63a180c2fbc7fbc773ed4b781f0b85e7dab9ce42c17977cffe38b283f3cea39c43e19dde939d93659cecd542c1bd735964297adb39ab7dcba8b665543b51f9232e3e62e684cac52e7b42cd90269e32ef9bedae59eed472cec5ecd4be9ca4ddc1c9e839f707c76acfb4fb233b97edd0cedd1fdbb573fa4796e8baf6ee8fc668180064758ac75858c56654385820121d869a52d40c57188aa3c15818d692267a1cb2b4842c5d409664293e62280c254dd9a6d1ac088a014056a7288ef4b3cc0935f3d138070380ac584e7f58611ff101bdc200202b2192a85a8448a2c27d472d0c00b2c2cd0020ab22d9125096f08e9a1dca52650090d5099ea805b29bd10e7ab56489254b117a4b64b76ba414f507d50995a5b59ac11a6edb81155a5f4c2a90237d2f5693ae9a4e40842b96e948168110307c64e1f861c38b94ddd7d5d7d5d7d57db1c8b6d8e56c421df5236e8ca1a4e9c8e898882661291868dca6656d2f2bf850e7c55817a3695276201345af9ab3e0d81e396e6b1ebc40a348c0d94ccd243c2f968dc67d8c0663d2d808c35870ec68820786c231c6186fb0ab3154af641a184caf64cc060382a1babb5b1a17c196d0481326935d8c06c7781abd922fd6c5ba6ae4d59226edf1b249b9a053adee056b18473a182af94113faf270475ff2bafc1dcdfb9078dea8017a1ad274249ebbd716076673cf602aa5a89c1d617f3969f7ec08bb4b008141bf7318f485a2bfc37b1f3b3c71fe72eafbe308767774d7ee8fee3f36285478da4eb16bd6bbc7766d8f6077c4449ffb8e3ec7bd6bf7adb244dfe168f7be43bb57af1dbb3b3cefee8fee9e77fee3c88e1e31e1bd7e87f77a7f1cc1fe03bb3bbc77f7c76589debb2cff7164477ddf1f9dcb0751b0430f8e9042a1eae704ff9901f1b0842da44004084bb8020e2778eab348ad7647fafe38b2a3e95bbb4dc8d2e1a9ef6887f6fea904b2449fcdd40c6f30bd66af952c512973b1626337e09c6814be2a3cfdcb099ecbdefd07f78d7e1ec7121c0fc209026912e1b88034699f139e9b59e0fec27dc77647f0df3162829efb08de1df4dc6887f6ec5af69713c74109fbf211db113c1447e2a1d8de1d8a23f2eee09c3b141dbca3be87a7787770e71c0ace1d4178e23eb15047f0dde169042db0bde30e45a77b77e1298b56d908a6e0c77cf79713e7d9ceda8ce0397f39fde8ee08de1113ddbdefe8ee1ddebb3f8ec0bbc33be7fef02e0e599affd19d3c16599a466a8532e26f40ec8408cae87ba08cd8ddfb6639cf8374b483fb76eed23b432449b20467a811082f89cd09e5054534f02d7041217f5d6a010c8a1309b78daf505828e6999813c0463bae8f7648ec5e174a550e3ab50363122054f4e263ed478bf2f1d40ec7ebb84da319764d28037a45a4bc15d44f602521c214e886af7359278f50e361de300785e186c2f208159e6e1089ebdc13b826402394e07e1e61ce0adccf28268e8a9916c80e7e464c22fe0018429a2468ad22044053d3486e46967a469aaeeb17896a55cdd0d4ce2fd52f12d57aa9563837cd45234d170c0d13f2d47946da36245b8a86664bd1d04824385f30dc0f62a211fd0d89347153704a4082043fe1b6d47fb9991ad20b319d55775650665ea85c4ca3b0bc9d954633ec6611cd383118d362d32969522218dccf38a80e0dedd04c2b687a654a0e121d702e7b507367d5a1e924e4a3ec3c9e3a17a63b75ce8d627c07c79b5f709115742e874496727c67d5a40e4decd03489c4cd08a9b9b3eaac3a4a3a7626938fb57315546c76bccee558b2d41876895d8ea649d914f53a07c90c670a68e2705ab2d49c14709f431293c0de9c1fe03e27262631df1c25e0e614013707853b73603227c5d14853e658b857d2e4f94f9f67ce0ab8cf4d0136e0f3eea02467c56971aded864294b3929ddb5b14e9fc63a5cd12a683c515d088be922e3514987496c8c8cc40285cf3b2a3a4497dddceaa43d30998b7c868c7e7b9b3b23f3e87c2059d7feec8021f283cffdc2323384f9e63de129d73b1fbd477569d5587a6c39226d0439d550884f2e9a0a4a92312f53b5ba8a4a973052cf5b3a05fc0fd4e19907468eea83a483a2b28a33b4f3a379d15ee67442ac4b97393db088ecf5b8c34b52a26a6de3ea1bc1662c8932c018801304c728485dfe92a90996f9258462f8d42083b46982b849226c991190c5763e002674e0cee1300c3244760c0517597c46066ac30198c8a256da40ed808139c3123b8fb3463e9952c551826a1dc73dd6e912dc6f81b12c70ee662c7a5b41694a1b5011bd1c760a4496be204b7b68a87786230bd12efa82fa55031182c05a7e7f9b2084270c660b0198c21c15815520571d000ee199302eec3c8808c55a148e7d5765db2453c16a69e3a9745802bf918a6852fdc2bbd02af8021c209e91504e03ea91a083877180c86319cb516eef9a457fa33e38ed9ab5ace37dbb901b11310ca18cdcb449f366d35dac179852c2c3b76b4a3f3fa7a7fe0f8cb89b340eab90c096eac855b1ea1668c35e52539f1d24a513b1cad0ab89f1da9595b69528809a8c2b3d1386e2b8d46cb026a2d6d0b6d0dd0a43d91da16a0694bc92d063771c00d04ad261506dc9c663925dc0c17036574b4a31cd8e31b5f9393da136c081222216f918e669391a566c922401310294827ee30a253f716796003b25402ee43eeb983b3546554d368b6a1016e9d373a64cfe370eeb6da2e7633bd32b8cf756c3c552b655476a8108fe27f78bebdf3cefd51cff9cb296f2b5c63092040b67b2e10ceeb95359ba519c5d7bf9c7e6c771439dfb1715e3957ca6c2fa717ce293352352455bcbba6cddfb83c2e9ad45bab13d0db2517aab7590eaa13e03d31793592e504ab542a956ad3a2499b95325b542aaa3fcbab49e1944a6686432255dbd6da6a9a54839ab795921728c12f3054d28219bc9da5250c6a73de9df7e54c7b6a87c3f9001ad1e79a00b9295631a8824b6d402802bdb69aad469aa0c4ee88893e6d974bc9922c424d49d356d3b4d6bbd53cd9b4d86a7a25725dac33fa974c02ee474b7f59ec5cd6694fa4c99391a52d253b32da139cda523853429dcf5caa4ffd2c09357329cd721c97e2627cf00388043645e6523213cb23d4cca53097e2700091c80144028348d0f73924c0154fe69c0ea0c95bc9524f81b9a0f294c01999409fb653bb3d8132fa99dd5adb1a363640197d4f469ab63ec095346d6d80a5e660a2c0b540068a3c149cb79a1513f2b4ddad4696fab208357b355e8d34794f64a94fa9e7d5784f24116af69e3ce995f86de5710191902b0f67ef498cd1bb81e11eb10bcf0850463f7329edc26c6abc875c6fb139398a2b87d4ec94422c5337e03e4ea9e2b5d1f84a1fd4296350b354491a88449433d2344f48e2ede295438046f435a98232b615ee2bb1a2492da9e8669ad49206cae8b37486849ab7150e4c46aea40943224b7d6c953716eed18e3e71b808777f4471c232a4c99a0cee2b48931a83797c265347104b18d48ae115307043b4338e68d2f63e8e98847cb718a44aca4423fad1ced37665919a31984f4b2307d9116ac630986e40102c256fad107354b40d708300c89e9145b17660eb2673c3fcaf3e77d98a929045ba3ca9e71db1b48866ad1ef800bbba07dd9753d44ce3fb299026f8f97e165569a9a4c142e377b4e3fe80c7f18e76cc1ff1f3be9c7e50a32a1022ad1e9197e227ef9296c5e2e804cc13a9f79a3189949608ee66f3fa45a349443469cea841cdb0e581d820a03c7ac503bd32e5e5b2939ad4c4d4248e25b8dae1789fdde759702c214df593bbd953afeb1d4b61e93ac74258baaeacde9d75468a1a602e566dab408e68b15e1cc7ddbc5d1c2cc7221caf785d0f9852c0a00202c3400f50040337609622d4f9c6f08676b705165760c2c1108b2b60e10a4d628cb3575ab6bca6ec286767577767989513f65645760ebb6216a18c895fb078b15675767359966559966573be0815629811a18e768054b86364293e65082b90803aa1dcd18ed0518e727f8c76fc30c9cc007542f9cb299422a5a8d79026c51f30624004199c421806210621062146e9651685b421823a89a43c866118b6c9ce3b8e2c52b163d70eed083a06bb60d76ee6debd098657bc8189120caf70c30ca63880493c41b1e7f13475851b541826c1f08a265abc41098657bc810a066078851bb6c034254d19a5b58a443f8994d568da51ec6807cae129b391a568473b7e8c3c376b9db21b598a07fde584d9dc3118cb6a64a90fb52606b7e7ca21355f32b4e295347df742484a4119f1b205355f32548048781e9f552126f1d901c6feb1cd83d9617662cfed1d749ae56e9d88b87b8defd8f9c45e402e692f21170abb174c930cb08338dc9ca0b7dd2b48762fd5b5074aa413102fbafc42204cab28a2af53a1d7a367831ea3981db55c9d7be7ce22b124364330f7a697dea10cfaa8059526655954ac4714f87ae379104422520ecac86e8f882f278e7b54ec63e2ebbaf4b96736774b9f93967b6704229c41806167e166351bb750e9b3d3cfc312d4486f06ba6ceee239911b22a594928708c74b197988e6cfd06f8846f46537c1ddad6eb50d1c389881edf2f2f0153427a52ef2dba3b5e122491c8260eedb17d0a4d822bf5d227a25beb3f2baaeec3abc1e63fc8c5409ee6e97ce482be4aac6f7d4424f1f6d864ef631dba69b74abdfd0366dd3832c52b8001826a1694d8bfdb2220e6d9376ad939bc019a5dae3767aed7ac7465cdfc12e65b7bbb9628aaf7727045ef0a8fba67dbbb349d99bc0d9693fb3e00c75e888cf2fb82f9b20a1486ee64dc7482636f842c7248149ab9544092adc49b2586105cc8034709f449bc8194fcca0a6abc1b16be1282303219c014ddc8d2cc58b8850c1b083264cb5043469b4a6b68ae06eb4cbdd14e92eb91b1cbbbb189f11a95904429887d9dbd21176882f49a9a7420ce4c826833449c2b4959737b8f7b5e7f94da63e65aa49a4d897fe92a99984e9952032f589b3d91e045e3a69b31bb67b9e52765653d2a5786dfbb4515b4d17d4edcad495304d8ad2d2770d7a8e5a58bb7f7d346e81624882189480b3c3cba3cb01c59004312401f7845e475b3da081dc43cd1153499376052cc56721f3051c5f064c85cde0a8ada08c6985a6c2381d4cd5e178dd315b3d4ea7d60ec7d3aac7e9c80e47abde05328f646d95c231cea462884c1ce11532c847e0dca5529d0c8e5748d1ea521d121cbb158edd29773438b64c90991412212b1fd0fc80d52bb9a7c0f131f7101c9f9b0c1715383ee6cb0e383e669ab51be0f878ed06d148af2000c72863851222981c81739469e2246e218418049c1b08168948221207a3adb4192d85e329935ec9f409b5434783064d0a6731980a43c912151719bad8dd0b7807812cc5262778ea2ce02de1dd917c39c1748d2cf5905ec9adc23fa83d450a7ec0273fb850bdea150a08aac3f1baf64113efd0cb806c7916156f50a85377a3804d4e476e5028dc771461603a8fd3e970ee75425242529edab91caf7ba7628674905e19455524d2a4786da5ad341a69e23c5e634953e75a0d8eaf9de678ddeddf98b8bb16d74214a9f1158a207661316577c73870119e83192eb946d73521841042082184f09a114208638c910140aec0f13ec07457520a1686de8c26c119181ebe088daa76009361118a210b5b9c8e4e4f07f0ef41a030902c82896a938ef854f9a4e60e5545f5c0f40af6872c96b400f73d41ee491d06942916ba3462d1cd94e3d4f44ac47d6a8a2789e9bd882112ed44c41f934a0fe4c847a9f4a83c9c57837ef623d9afa613d09355e3234dcd1d2aa3a950a430fdf77dd6a1f6cd3f560bc346a5180428a2080248959034c4283179f13eb518e651a1f40122e1b9584769029140791f65d52bdd5b74084332143a84a60f44275c21f1d8882f9619b0870dd87339604f193836c5e6179c720ec546acd2ba0246e10246794b0c18e52a8132e8591a05622246bc563589fe63cd6b037bd6798a7d71cd6691857803a128e92be43603ce1ebb7935ea68446f131e1001bf78c77e7479f40d7ef1e8e5e8263c18027e71494dea894716e2795345df47ba47b247f531c982e8dfe7c4c428f720b9d9410e380e7aa07fdf2144827b6e2a306604c3ce916c7b542924aea9c0f41e9534d1ef35bf60d0319bbf8b1efaf25342967a3544e744165614147a7d48dc2289d40007f88372793412fc21528314fe588aa1f7b9339e7cdd1feb624245cdd755d39857e38377d4e2c4c40338bda3162726a6ffe80b7e21bdf4d9d0950dfd52d2344a856ea4e943224b43fa03d24142ad904dea8bc11f0a879ea8707f44701fc647e93f9fd9c2df37c3c2df6c6283bfe9047fdfa4c1dfddaaa873f5791013059a3029d08c013de16e381bae5523a2342b59a29791a650e8a230e5a31969528169158f109e213c2b14084d2a2a94d1cccca48125cad13a5ad56c0ea11cd1d05fbf283d002c004ec439ead5204212416f27006c134c5bd22451f4b7456f5bf4bfdda21f62452fc48a5ee5f68a1e060bd38f5454f42f5460a469b26a6ca4a955f4d5a66343cfa191a646c1123dbdbc99d27b231ad1e70110c03fa1156e14ca0aa505428154b81fb219b402b542a81c525db00ee003384b0761bf0b0629b2c00238b5958b08bce001dc3800cb63de60011c7a02b8b049441c8bfa79009e4729dc87c17a9e73ce4853a70523f5e2463e913759dac81ac9ca9246ca8fc592264da664cc8c347972dbdcf49317a9a66956d720a1387f483e24b82fbaf972cf3412d6c77aee1818371f6b220980ad374dea00705aa0cb7154dfc5ae006ebd91a6110d175d5795260037d72744dcec01825249139501808ccc9599b117496dd2a6786a27b85f51d2447f338519e2e69aba5994670cb591256903e36679837387ba593ee9b4a449a50b36409dfa9d9586d2280d4b54536fa6329d2b67a44a7a2ad9a9e44a9ab4952cb1a489a650d2a4b56a583877289adac27d6b284c4dc5a8b4382a695259c1525fd44f545a7dd33648bedba154562d837387a2988b390534b219390911394b7322fcfde3f96e6efc7d060501a6cf3ebe283ef7d81e11631f46cf3dabb43890959e47060b18fdb82fcac8a85444644637a39b91cde86664337232ba69529f5a151bd427fafe82bfefc328a51d0ced50182a62fab13ed6c7fa581febe3e27bf2dd882cc4d80c897e1ffde8c7ba42cd1f0ba704e9953cb211791cd167f339b9d9a257425745f53de91515998f8b14201ec7e3746464542a958c8a486764337232bab92e16931a2daeab7f39b96e62d891cae1a908934a4b967ab649454543a150a863734c39f442a2efb9038944225128e521cbe1a4dcf35252bca7a478a150085369a1bcafa24279a8a55dd1ed523142300cd4c134a983d06307c97440b04f0c3bbb4441288e0b896e8c92854db25e937cfcf0000f4c29e81ce8739077cec7a372627a6c5641f9589ee72989c12857a08ac0f00a940b70fe3e56af781060c3040123250478e1b5c87882514436472cfae7f390cdc7a10aa22a9e4a390fa554f40e453d1e9ae941bfbc167acf2f56af68813feb44c420d06a880d5622c34ae915504e39fdf79d76d846cafd6aee420fbac73e71e1efd322c9165018643fd6c7a449dff77d291fe6e500d194674a41183da463d0b6183b261f8671bc1a5f8a67860a0f921a86faf9b08f57e3f3728028a514f4bdf1d73bc01f8a512c8f8eb1a311e7858afdfb877dce79595488e9f7c13e8a451535a95f4734b8afadb495b6b245589a92d2f4b164a4099e3e56eb63b55a5446e6061e19692ac578132006a52fd19328a5a1361a4a9ae04924aa95a6521baaa170c3150af7359534652295a6ba517528f9b94548ff2e25cd2454261f4b9a3c4380a53e126a9ad0c25d850d6e8fcaa3aa5d0c164ea8c840e9a47731d20445e91e5922c649ef1f2fa7128c3415214d321ee30221c063dc42716489189700b7080bc591254a37c6fdbe9aaff5d9401217b973995ec41d620f47244545c907c3b063d83f0cfb6caef84386ecc6a322e211dd63a9c07dce7a6492fc83c19b3d33a09b3d4870b33454a1e995febeef5965a5e4f3d91cf1d7a3833f5791013dd3aba8faa6d26715155621f2c4c49f0ba18cef2cf2b39f4c93be63ffac8a0df63d64555a57d411f6178c7d8efd73472da07f40d7b3e4733d34d8f5acb24a0bf7bfefc3b00ffb3e0c04c2be0feb9a84d5d4f8eec5e264173d1b2a4d58174b843d2a69ea30d13bd40c9c3d2a1a34545abdf26962d32bf1e351d5f87c2c767d346e892186248c818728470c3124410c98d24f4cef88fe058f5ab07fcf11bb60b733d2c9d0dba93a883f76627af87df13b8691beae499f47b5f23caa2659a17656f44a5651e14601810992ea1591905e81dd904ed511e99594abb26a5227d32b2a344d32d21d156df254bd222222d3e915d1bd013115483c567856bd524fad0a8dcaaa49adb2c27d959554a1e915a8b2ea15ee7d1525bd42cf9de32cac9fc5e8af8ffe5251a910e915fabe8a8c57e3f311317d4685fab1987c355ab4be26107f369f93efc62626524a29a59452ca7df662cf676193be539b5f30f5780e3decf690d8c3f19ca569ca69cabf4805c69ea3159f1ffb97f2612ce5664be9db26f36a50ccd2fc823d67694a3f9bdd63391c883388b3b74dcb98cc6363ab499f877e98a51717f389dca26fbeefd8bbc96d9b267d87d136d8e758e3d0b19bdbc646c41c0162a06059f48f00177629e57d3f963495ae479592328f9d643d377b0eba47253fe7b17717abbbd9737d4cec79f70bc56e5554d1739cf9aeeb6362eda01b2e9f4ffc5d17ede6883dff8ef22c3aca85b14da16ad7c7c49fd367d1f53171e817a6ef37c4243cd725f4efa0b797e3034d97cf877e07dd7e4334023b4b73b6732c7b66705b813b7b56b84fe947e921f618699267a6495de3bb1e222a8f9226358de8fbbecfe7d6267dfff2f71de2ef3e716117faefd0b341af67c905814007d54c6d5010e82c4d293d47356fa342159d9e7b7b3744b4efe9e833c5a12ed187cec9cea392a678a2dac7d226d14fdb35899e1ec5829a440fb222ce52eb5982d9f0b03c4b9a143a673d443c2ac979c7b3598443ef6cae38743365f54aa6e915a9c4b3a457eafbddea37b40d66e988a5128d044f5c2da49f1e55ee501d10985ed1be0a02ab3d1d1c220b4d3e5dac1907bd161a21344072c48825ce2678e93ce7745cb0838e9d9ec32c766a3f798c09c67e294992052ab047a685fb1e221e233944071db3a27f6c96e3a3b456d823eef40443806e0e610f71c76e1398be090c3ac44d60d03f99fb8bef1c476fee71fc040c2c3a7df474808e71c728fd3ecf22fcb923ee42e0058bee487417ee9f8bb87fceddcf9d4da2c72cf690cddceb2f2f029e8b7e793822f61c7b163d09c40e9340c49ecf4577aba27eae0ecfb1ebe2b9e8ba5cd6c7f5b93e2eecb95f7de7ba99736193265582de94a73c0a9c42ff9dfb6cf47264ecdf61937213f823b112991efb2731cacd50d02ec536c6294ad06325c09f9bb543cf867c9e4dfa4eaf0f89bdeb5dbbf714ebdd1ce9bf7f37739afd1eabe643e2946bff3eb23e224e79f43171ca6f8c9ef2cc8a9a4736b83fcad13d6e98a361e122304c4243c46bd930b69da521f7ed37e4b72c10c1db39d1cd2f587490cdc74de00fbd5925643f14941b142599fc30926128f963498b44b536154bae954854ab14128593a9ba54976a8b2017ccec0b0666da4c9b6903572c58ce4f1a91a8d66bd2bc896ba9ac3d81a0b83383a34daf60f3666ed12b4f261717eae25822024cae1afaabe66a5d4eae2718908d060b72d55c5c60280c064be1f88c6e34bd92672c89dddd55cbb2486d2aa5947283ad25dbc6bdf3dedd29dbb0ad64e96e56b04172b4b9675cd69dd151cbf6fe76e7bcc11af08a78cfbc7b2de952fc64c96fdab78d0647ae2db5174d15b59f2f9a25591da211f1306a369a89e5cde840d32b9445b196c72495fd4c03b20aab4d4993e26645c6869a61cd057048130d1a1a47789c4ead1d8ed799e9baaba23b4f52808a7146234f622a0e89327166c200e99503ac1860a2686a8636dd6d914636e0eb6d86689236d9afdb9d49a1b6b4c11ea37639183bbd9983b3b42903cef04976e517b20403beaebe3efb86d59dcd81e32eb16719bce2a61d362977945ef73aeddcd5ae0f7c1d9b19043cba172e761662102b628cf15c3ecaedd49b5f70cd2f38763a875ebd3d64d6e1608270354f5c33c5750697a783c3b5d647983a835a67d0b1dae52c4af6088382f28862058acd3a1d8eebc44f5b39b9d94ff56c919473d2b39e5b24a5f36a70fe59d1a3ed1eb229afb6d6fa22a1b3747bdde32df27dbb454417e6a7940bbbd459ce6b278af758af769ecfe7f19d8dcfb75be4bb2cedd922a13bbb54a39507d9ee4542ffd822303f8542767669661a77a9e61019d342b814f7087367e75c3df73caf8ff8cbb3116fee2e3de70eb29fcf411de63ce73a9483aeac9fb8bb2e9f773c9e7974785e387eaecb7c97a3eb78bacfeb526b77730c8239ee1cab9db373ce79f96847d06197b7d7cd900572c48b9c8571065d93224a730051d500713cfd76793a22ca35d0b594eedf437fe152cf71d5d677ac27bed68b94581f98e379e799624ebda3ed0443e09a475bbda34ffda76edbf581b973ce223936737efdf3ce1343604f07f79a3becf976479c0b8117ecdd917797ed9c7bdb399c4baa9dd77b6ae61c76dfba57ee9ecb6abd5aadd765eededdaaa8dcd5d1bd5e97eedb7511bd76ba947b6ee6d161d1e15f84e2ab2805f4f97af3170a753a57035d03699d6b57227b5e39ad73cf2be86628b0d669da3d97bb79de87c4daf36c52ad1745b3283747dc79ad3773d3d6c73a5fb5cfd7675ad53435d4510eec79e7766faf653bed3cbeb3b96ca79e8df3582f9ed26f9c0fdc81d139e79eed7a181676a976efd8cca3e33c9e16cf3d6769cf73bd73ece71dcb49ce5d3ae7cee9dccfad67911edbb8daf678ee52dfb9a7bef30e8873bdebb23d72974787b74b0f8fd9fcec03c3cfc8a3c34fb48470bca839433848c4fdcdd250f38cebd9afcca3c35886868a65f6014d9a3f86a357e48fec2c4dea5fa062de8d071cd139c6197562e8e5882c0f68536d29bd1a97668fe852ff247967b0241ea4ac2d12b589eb2c94a54debc9050e129167ec1bd40c5957179950203843164b4453eb0ce99dbadb334b4422bdb2b19c98384316a5b566918c35f23a31716e9b28234d2d2345ab8a444453136bae8e63d9f44a109972d22639736d6a7381f1b4114b9534c92dbad492c5056e559d91375ad4285992c56a02bebc80e56b10230ef065072c1fb57963901a4491072c1f9b268a2d64645a063a7911b2591c102e993163c68c5a6ba529406ded193951699af0248510db039d3e8ef0b283108d8897143710c65061c7e096310a11119966185eabd0279a2125a9a3a955f46b15f1b59222d1e5009652c3f0242230cc2a20936c356adb2ade7209f0264d9f8f676a1cd74188c4acf7241b644bda893ff6054374d145175d74710222c54f9fa35cab88623ff65ac97bad7ada0b7e2c10297e82d0001e988079d9922dd9d8632f1ad604601966c4d7f50d36c1d7b94ef3749cbbe675cf469a2e7aad602e377030bb7678224845cc38e201389600410952204da1c3c794347d878f31d22492a694bf388471514bc6d0ac4696fa998d8de401eee7142de602d2943da1214d14260493a0421e27ae0da461ea6d8960d8786a948494b36d305e7236918da7141b02d80258923d649441147cc074f3441cb951104019f2218ba3095892db12b024a54d0ca6db461f3752cf5849164c1fafd1ec8238939852d1116844ff088b36a1364da233313330b41559369e5e580f2c6d87615fc0d276da921bb527b8514ab778fa2c063a004bf2b4d5c224c5a8f713cc220a38a00c79144b830596245d4949b1c75ed96ebcc0c77e42927c67419024efb122589a91263a239bd02cc568134a5ba82fc7d056cb469a288b6583fbd91369a242621274261ad1ef08f3040bc10d833a43f52ef7c2c6130c1b51f55dbbbe726cc59c4719b5d5c2f124b22db0d43dc532014b1d06ba771caff37a3b8e8703cae80eb22458ea1eb23360a9a32c69a2014b5da6351dc77be41c7617c0de61a9ebfeb1149628e69caea4a9c252f7ee565d13d8832f82b00180a4f98dce68da4c0c0b4456647d78660efb320b43b342d80b49f334469a64ab8ba13102c84095ad8ecb3a401876ac77b083e6414c221bc38d3713c3bc43c7d351f176e745732969d2b5a44b1d93b8f2259facae151650069ef75ac174f5500cf5d0b0af9818fa0349b1cb5e90342f81c09131337be32ff7943138431a1cd3c2f95a31716566983246c6082003c7d92176792d135f341380a76b06f29134af67d8e5a9ddb4da2a22412227f4741293f18a44950a93147ff1d349216438372ac332a65f004d34464503dc3152d438e499c6e07e7b3126c64c8be18ffd84c0331340062ac624a89bf6c2115f2921c0f2717a3566a89b764698cb2b1251dff575d34a5009506c8a80c0e69336057eec0b589af7d819c302d887a574d3369636b2d5cd824283068d0b1459221375d3c6ae5de462a8f1f2e67a3f3c33c5ded8c7f396b85665a8b1b39a1a51401d7cefc0634545a4106abc1a10385fab6869c8ab21bf4f6ad92349bb306bf27935ae94ceab31a79458a33e6f1893a743492bd4f9dca8d1259b74a91bd5401a667ebc1a725ef7745d8a17ed85455e0d56cd266364a9af7e4686da31b2156b64d22451f41a48378a0a9545ceeb1eaf86fcf010e1eb1f2f478c89cd2689308ceff9c24a1858176de3cb16f17c7a6cc3d2fcc86ba118934da44d93fa2a5e0d79654bb628e77a638912e2681ccd38ece226273beee05c11bb747be9b404dcc041228e5cdbc5c99900ec1063c185e5b9794558c2348ca140eb361b6109fb657744ee7a48805b3c588e98e8cefd02dde57e81eddb135ca00d7e39bd9c7a7eb340b65720dca12c6d52a83de013ec436268805c6dbc607916c9c15367b9a39808c0d93918614308a5c7a1f789c631c3ee4384b11fd16b995b67586ff60876d988695f4d9833e6bd30ec8a7e22626c523c11f1b23c40f8c230aebb65132f45143b77b1d3a07486ccb86fdca682233475b0147b62f23c40f216216d9c41f5c0412272c552e20b7ba62bfd094b24289a92065285e79c73cec922a78d8f694e1e12c1dd982126c63a5306270d3b3771c68a5e8130494d0d9e876dca910a3c6b5a71099e5a44286394a51af142ba343f413738c2cc29334bb0346f003ca7cc157846992c68be8027ac812d927cc19cf346bbe12a377b65dbb66fdacddbb10ebb8f892febb2fdba9c9b7cec11bbe04a50b7c3f96dd4b2699c367f7d045e0dec9bd53ae85df1761e9431cb500720d86288051d8460ae4335b85dbb3c163744f00130c4c20e373806c1339e76292cec708d5ab2c3675cd675f0978d8f52de0cdfd81bc3bc96c6194bcbc3c3b33494da2f8b5997ed107357b71d7e7a39b46f6f9bb5c3ebc2655df4b6675e0d6dbb765db66bdfde713ab5c322ebb6bdb32e5b0f89371ddab777367772e7125aee6d6dbe5e2f4fe296dd5986dd1cafcb7cbd3b8bbc24e6bcb2c88e75d10e31c77ab6c70facbdb32edae539db43b6c416e011bc2ddab76bdf5a44386fd7ce22b7e9d5d8ae8bf6fefce5b568f7ba5c8f3347d6941eba609fd8e57a86dd2724fec07489576d5c6061892533765c8054c424cdeeced286ecde4295e76aafc41cf43773177d46b50ecb4319f2510bf5f8910c351edaae3d9aa4ce7737e7bc8898589c56c03af0f0d03b94116316338cf33858966519a66df11b77f8f6726ce72ec76ddce6752710611f221c6dde4eafd9c6d166d6657b76254ff0314ca2a4066b8f73e3269c5072b68bdbba8c0bf534f471cff13ab40bcf75debbcef3381c15d7fcb5d1aebdf91c59965d96c672e42eb96da31d8d9d2ee4d598e7b68ce3389dc771ba684b5033255ce24137bf606ecb8e5d508dd1042f28cc9dcbb8c3226e98709ecef372b84450932012f9250aef74c0cc664baa8bf64cbe522f07f60c621808733147f6f8190f21941172e75ce2332883dec7c410caa04eb4c010431cb363cfcebdb3247bef10e763ef137fbcabeb19b1c76be11edf20cfc6a825beb4c4733773f906c425c09e7d04d8b3c7478f3eda1b106f5ef6e9d5a0dbeda00c15cf72a21151e5079cbce6595a5a0cc3e6cd3c6215b869871a9f3b621b5ed8c216ba3a7f9dcecc0546dbc5cf88b55c17ce2b36084b2969bc5d93fa9aefdca9e0bec43480635e162c5e75505139761830309b5e09c249bc91234aaf18aa695d036ddb36c8711cd7755d27a58450c6e8b1552362d58ee7791e175b0411c485102213e226080b9bf464d4a4061089202e5bf0a203be9e3d1c7ac7d010e9015ffff77d5f8c28556125a5d095349da657464b547e35be563295a910f550d693483366e03a53d573dd5c7fa105be44352256a5f94814948b06ca4a760c1211a41794d785b8b90671331dd9ad8aaac2652ad7bc08bc609573b10b42e5ba54de586574f5310f8b6e8e4cb06492a30a6453f81f8fcdb0553b36c71596e7a86c86ab0c5b2d9f591e1dd39f92890d5874b282e84f20b86905e65eb5506b0eeeb5bbaef59d7a0ede88b731c259823dbfa667a3cf75628fd845a6855aeffd3afdf45aae0be2b8855aeba797e3ead44ebda026d55fe74e2f9bfb2c7d794af43d575e366877d86510ae3766513d36fa5ce621ead7b374b5a3967aec154219177df7ad34a854ecf3c6b99e854ccd8c0401000314002030140e89c482b1603c1e8831d60f14800c98ba507a4e1847398e520a19430c2104000000000000060380002ca10a1b9f9ca8d26375809fda4eb0ca980f3c724a37865698de5f71e59b91974d022058fa9d01158c95cb00d9343c481268649ca54ca37ace7654a3d24ea2cebacee9aebc662024a112fe26dfb58a782e2ffbdcedb15396543c130b1c56dab1a93091b1884b67e595d0462fc0f9af1bc3ccde67748f5edd943b06fc0987047fba1c6149d4f35d512d8a9a5fad225ad4d04ae523e75d89c4af8ca4e8fcc7d87d047a66b21344b824373b028ecec558dc480d128e5cd24d500f96cd5c10204421b1937d87693b966a8fb7372f050907a0ad5810876d0ab761aacf0f380741f246bc13a3fa6b441ed3242979c222f1355355610899bf0a41cfa212203903de9ddbf58dda914ebd29a107733306bc156afa55431920db12828057da8a322b19bef83c934b19a6d77ab1b16cc38d5803aa02e8b33c3d7de89540036abfde800ab50674181f174ca92f20b14bfad342ab9de082ce6e839a885a2da40d467d2047cb69f3e086f705d807be8c9e3c04171be857813828fa4cd00f2f0582458fe27759aa2e03c929eac0ea4d5d319e6c88528514054ef91bc803c45addcb13c1a069559f3ac0d8f940d0c4450ba09ea4e69eac996b95e1bbbb241dc2b0ae1d6c82d8c930847dd23c0e38d1d5bd02b6827dcaa77e21e42f3331b86f283aa556c32f1c6509d420b359fc925c8645a322807b8946c1c413d7e143f4487e07c131d05e45cf7902023ae1df02c0dd52c4ff265d341bbfe696c8ee6c9774554cd7ffe437e743881baba3a0b3c3e71d7d2d1478cd4f343c5709f5e3e572ed0ac6d2a53299259c6c53488126b58072e04466395883d47ffb6ef0ffb86c7e572befb7be2b388958af7460a3eb2c6753336625ada245028afdb2680e5e1741386af780dbdcdaa7c4f123ae61923f2a42676dc2f9307a57125b8824e4d5b2068e3f589b92a08b238dc608e5983250644188dfe66449f8793d14ee02f65a9669f42bbb6540414ff5a6dbeb6210a4063ca4a7250b46c1d90c137e89e10ea6ed150e6478208ed20182d605888a048fe31eaa5f93338270ed0011a182e08108d91adbace1ac916402cf400e09e32aabea620129050f14be1e42321e95150c276924ddf5da68dd02cf915d797067b7b9dfb08ce8db47e9b4c87caeb6a517eee52b4c8893d8492e52d7c4eec80cb1986d27b47390a37764da9148881a08079d1d88dd4cf9f9272a1de89a58fc76e86b761d593e9fc0bda6414f3823a2ac96374e9eeb23b6adf809e63ecf5b9b63db557547547f084e44b576946805091e6d99bb63304573c79aa1a796180775943604bb0a254875a1b1a1abc8266cae70adcc6b9e407423ffa5e148e9d437819467b196b957c3d35b9e04f5961614ae90dd3e0ebc686ea4408ec1af9eb58cea1ac9fff1f8284e14cd1df59fee29cc5de9f6eb23a3c2f88739b6c9b301bdeaf22eaa038c10b1b711f8b1f355e7667ac575db87811d52f747df0f5962b1cbe5f590f30d0eaf71fa8a8c6097b031fc4c276455fd7bf4b0f4df74c1c9891e01d9318602914dfb123734260e6935506a356dd5dda01d4257f05d6cc260023918ec7ec79213f6a84eefb64a34c3c21e1db634492b4d3382039571f2c062f1f420e83d435b41ef3183d277d152488079a3f98762b240c572a6e39a8edc1952b2e55ab42d8d590eccb823a49d0bfd860df259b64dce5b3ee148e3223defde2216880b1acbb94c6f7ff33626e6fdf4221125f3cb457d962348b962d4330777da75d60620fd39ca80a0e3c8e46a4a42333622603de253fdafd17c4c9af8469e4178bcccba4e36b4729fe50bdf7d5aceddb6d7b0fad327a08f7d7e93e7256ec7c1336b21f76628331b39704e6c05a08df3e0198152b40c6a503580283194e00fcb68ca197f700c2a3cf3c048c51cbdaec86b03be65c7916f16ea86cf1e7045f15d3350fce1f9e03f5851bd0f2ee4ed98cb4cf840a9036bece7826dc103e36a316f444f434efa460e67b8a2e0e7f10b2cec48b3a087eaeb7322cfd0ad68622a681dd0e75a6cfd9cf32e2f04d0352882b6f240e95219d0876949da4743d03f80bca0c72131c72637e8715260ab13fbfaf7e83cd6cfabe8b8bd24627e3ba8ac77b58a2ccbd7051cf46b8c2d4ab35ef1594815278cf7fe58b3d7a2c78335e219dd08fbed8526ab27df69f5cedafaf33e8e77df7510ec6591d360b3f6cbcaeb7da7f4cd9d1fee33b7e4911e6a4c2b43a7b90f1ce96be7612fc4c03102e4ac9a0f46a0e27503e5657bc39a96f4c7af943c7aa4077b10ed1f24b8d136ae7a8ff4f9d1d79af038fa4cc5900c29fb7ea4afd2fc0573b523bd3c8ca680eb486fcb74ae8541e97688833ffd4ad96979680e7c1b59aa60769a45a2033adc6c3fb0460ed55222364c86e40fbb58a4f7182fbb8252654bf687e7336466a09c7049ff0ffa987bcc9e91199aea1d164a23527b9dded3935e84a49de17ac5e998eb4af7571bab703ec6573e315660b650c5c5bc8786f162cb6492a082323ddfbdd61bdb6db5ca1d3fd62b8f92c85640bbd01b91ba52e4461b8dd77a7d18b3c692e335e83d903b0f60e266c975376965ec14ecdcb274118e6bbdcfc0ea25381cb8a3d594206a7d89a7176c03345aff9e395af920cbdf7231fc2eae786b5cd5a41b773813e55c3e83b20316488ce86571c95bfacdc90bab58dd977eeb5345cc7250354f8ab25ac527f046aafda3424198b10d46d0a4ab138464a3b586d3ed202ab85c13af3a4fa9702d2ee180685fcfbc6c9e0ea763042b9bb24f75d3eb27d02b1dab370b4110e1712cbb904525f7ab74e4539e7edd69bbe7278315f2fec8fc8bee4fa3aa5f39a1af2ae50e8768f83afd9974646c380e33f769feb02e83b82e366926eb853f35233592e464a73b256556585a277744825df706534a524c5a68063bd19436fc86e2a8d6154185f809ebb9cb16ecaf33bbe10f39410d2df8073a901afb8746383c6f700b3b73f8968c94b7351d650010a195992f629568ba9a63857c0edb7b7ad977aa8a400bc5f9546d8f7eb9ba6086a2c280f9530e0a1740ef76b2f7c7b0f0dca4f8159d0448ce4b0ecc809be2f4008bb73eebc99d7fd3862c0c23e49cb8a318430d561a4a5ca7bb85a5a3347841536e12deb082ea8cc6592d8203bc1c24781a5f7a4e6a06ba62271f975746d5ddf2efd2fdd22fe92b40a5fef2c280161aee2a92566e26551ee781dd01cf4edc8377009db8275e5d311c192bf1df476023230f3d0013955c4b07ea908b0f35c63012c595b4e4d7832f627dfc89edfb393ad83e4ed847fb578c1ca3004eaf8376435d93bfa502fc38a26da00fd6290d42352fcdbb69ef12c6cdaaba7070469600f2c39afb2609e90da84a35aed82c9d240a125750d74fac044ff9b79494bf6ffc3ee192c53f83b644f11272e534115d03440b721a8d8e1f052e2e87896cd4be7e4ec3d95fa99bc5ba54a51a96184844c6023c18d6c68fe5c86f1d082b93e73907cd79cdcea00f88066a731c40b8cdb1d210bc15a7de32fa26dccde06752841f3a42cd16dc0949a8aa5786045e6d9320351c3a06e9b780e96aab9e093d57898f399c9210d75ee1c687fe07c837069fad514c4146c9912b53727c43951c073d32408e8d2c9c7db675654df0cbe246a52b9b48b3d31b296967abb0222b5f1e45ccafe848610d2516bfb0a4b3ec2acec6633ad29498026d4e2c9dbfbd0410a5ef72c3b1e2c385bb53fb09d31feb5ce65de552f2e1e208276614e2ec97825ec6fba918f0568ee90408876c8bd784beab9fde0f25b858134257463de3d99553c7198af588800b297fd0c040fad535246399a9eda091512a90a2fa0239a88e4648f7da57d2f7cec0ae4f16f28431faf8231662001e382ed9833dda995858aec82a6d052285fd257b66d0c13bdc5b2d6376cf3aef87dff11739e54474e227ee05120efc8ee082f134d1884f32938f3e588625b24ed8b986cb2ca344eb4eb3bfbfa742ad71507f088f0b8fdfd1518660ee4eeac5b7a457264e787df19401227bd74865d86dc937ce490eb8fc28260a34de158b92ef84deda45b6b5ed3283556563ffa2e176519600c7f599a0d2eb9868c4500c4392aff0108d50d749e1b33cbaf1ce0c55452db306c8ca8a82073939fcf4690635fb613bcb442c21530208626c3b45a46c4eba2c30f85e09401c4f8fab4b6ae9ee270677cf30698d369f022e9cf2504823f61013490f96934e1cd4cf2f95a0ef4563b9a2a8886975537a2f0e81f773c650552b026064bb4f80ecd4fbd30ebf254cee5b7e3476a34929d814a0eea9004a37e9a212825223b519b042709dcca7719492ef6d65317a8e850596481ded39f6368011d42548be595792b3fc4196a8b30375bb918a346e106ee0acf1f5c47923e884c6a6dcaf1ba59c1365bcd3ff19903ff28bb2de8b3c3c999eb598cb610db1a13ac1437706669f353b7c4921fa66eab418c0117cd0dcdd79377889984614e5f36abee48f2d482b0530572775097abfff15175eb3b1d610e85fe7199f542e015cc1c20ed2d8ded010c51e2d3070257601c0e566e44b8cd33e2d22e44a5b207f03bf1aee3edc5586d747f42c0b990bfbc08819216a8b2eef15351cab66dcd6ab5b78ab341660c4f871246c61d140855ad05d788648bdadfca2e3c0675ed2ae31893b0394d9dae06eaf11415032acafa0214428154b6af1e40c5386bf13d117686e46dabe647b1cde0f304e80a7f8bc7b2c4c1d74aa39df8aa00045231dd6ef96198002330d223f119aae184053feafe971559dd2731810d7bd6d595ab55901e09198310419133e6118616a3676689dd752aba8bc9406509dfddb1f3226a304d27b8667713ce92e6a8b8ade7507e6881248262530ed5a44985abda8b86f1af997ab925ac755ab30a9908dfd58145ff14ffff3db1cbe0a4d78403b13e6883ce6e89bb8bffe8638d0b1c5cae623b3508db92f2ddd2fc00c26301b8e6d88aa04733439e09687f8fe07a1d621884878aa3d304503354f6d677a16045c440471f7841fd564ff7ca989a7bfe40702be57390badde10767ac77fc3d49c834d55d4e1a4038d2738899706a1feadfdb870955eaef50475b8cc12764739fdaefd3f1932bf2ce8e4ae4a781c9c732dc3f8734c217d9292ef902c431adfcd1588558c2c820502721e0559bab6bbd0911a0b3af0bf1f968598536f073b2e065e4d98f61ff5893e67e48a09aa68048e793ebb3697c4f14c821c25b23126508e8628e6d64e2b15107505b56ad63c58fd7ead469639eb53ae635bea4a645e215c25522046f0548b19056c15a75563c3e7c350da131a9e003862893570500f4305ab3f5f09c573a21865ba6f9e05a8985e9f96d215ebd66781de69e2afe79dce2cc2938ca0430b7a7f576673e0e0db711209cf691fa670f303d4042b2e6415436bfd8a25d7d3fd093660518145152bf675df0580f73ed910e4b4e2313bd67d479791de2705594e12c3a21dfef99f98c98aa96a693728023870819c695182b16bb500e6d75e472d464c287ff162b77e96124616cee4840ff8d4ad5f2d2cd16bfba8cfcfc2067b478cf6676f176a26cd0dc88117f217a96356a2307413688b2a31cfb9daad3027b79b16ddddab4880f825916d6b79b845e82921a7eca2dc7787662fc80382a31f34fb860b87c1616f884141561ba8344678a9afb57d002424f8e76e036fbc12de5ae324bf202cc3a0f70bbc86d9df5bfad7867f8294375f3f220801d7efdc21d705f14cbadff42d47c63df845a004ccc891dfec01641ac3932aa2f697d52b8bc05c314a3466a685da2c4855e286e16184ff9e286725ff342aca8c45760fdf9c1989b05bb58d582bc08947211e638d23c9135eb6d8ea5f297a2f7104575bfbc9ac81347a61cd0c8301f0adb2231e9e0956ca00377225557ca6ff4c040bc7855b9b6b1859e602d72627abec84507ea1f17ca1f62e6900e3a7fa2bb9843d265e770abef8d66898bccbbb58fe8d61adf23bdc154c79d7e591d1124538f76c58b3c1ae22fb1d127b2fb1e51b69463d5cb6e99be171158c8a2ed75afaa3e14634b608c59df32010d71ae917227490a78f1e4fd796d74c0ea1227b9649eee67eb7a2266a542a311b10712439cec6e5c6f860662f1934a9a834991cb13b0ebcec5d71a39e4b861b417a0bea4187a1e00f400072ff083c924026a245062bfaffba32b1617f1c6cae5ac95059afcd0163a9f1f76c7541a388c9c30a5623b2e90aacd0f1b8ec0a469b0082c7502e486640432e53550a11e8584c430d1271049c69b4ce44278433d0aa8293ec55657861de639e6210386751e0acb9badc68019b48e927f01d85f77044881f33e8a980752ac4d73c78535fe39d3742dc6ae2ccea09146cc18902a7eab2c0599b8a7a58d30e1e3aa7a1016158de352e237fd65017f064e2a1ff60640b49b4c379456f497a0885db958f317154408bc5970cade5df2be473c8826e5c70a3718641474df5b2276861e6831901a26496fe1e772fe85521a527462c17976bc82431eb3e66294d1a39d11848f93afb64ba80801d8b484ccbf61b2d3b28ec48bdaddc1077f252ca5a685332ac1917a8f66032047d6dd1375cb74b091ecdc9d49f9ecc6f53a64c95b08712e421c237dbf030611b455a17948fc955274e7395fa406f41d729c7497790ce9e422552330a9bd9400b4792e50688e5ff5d463a22f9506a4bdab2a8772fe0b8c92080fbe5f10b760e54b693d3de5d0ffef20b39f00166beab263121cced9860242a72042e57e0d1ed055a09a3727db604d6305aa90b8326655a8e5779e9795326b196e244d43332342c93a9055b7fb7e80360dcb34bd24a53c46b7339efcb876b28c4ae47262cac58cb7bd53d8282afa4d9a1ea79e969bc271354638d816e3d0f11d1a94dd75550a0f6cf3c96cc335d1d1361e831265c05efe249f703630a1cf58914b412b612d50b2ca50e1bf45e7199843ab630992216be16a8ce5f8352aa3d89bf9a8bffe1c7ea5e8f583ec0e1c44fbdee4e88cf893ce23b293d055e8a0295cf11c478e4cee8f0aca0cf7a0a4ed0a3e595995be3caa28cb95dffc3bab4cfbcdb783871bb53c5c4db34cccf622f089a860aa78fa4da3de991756fd564b87ebe13d3080d8e0a9f31336abd5adbbcd33000d2567d97f89436b8b655c5033cbdc112ef1fbc97878a90edc49985b5f6c7242c59a24bc1326358670f6c3e7ceb3a910fef585f38a8cf27e8e5a72a21311c081ff7c7ad2e1718de647d7486fb101b96bff97d37f3cf4c1cbce58ca84474bb4a1e32b6171c9827b46530ccc4741040f1b2cef6c77e9b736c06d55f4f325a32373c0b5a3fd17853540e0f192d2b2c885d400570318bc8135ce1d97b0a7f03d65b70bfb5403cc4fbd89f5d9adf2e2db5563ad3d650d83bcfc15dc3eb58f53e4d570655360ec89b20421fe49ee3b6f2b98fafa6847a871e1c626502128f7ac249900b1435411f55ab3a43259fd9914f24249ec546f8d8698f74103c56ab4f6bd38058bb98c6e3015fe1b702179a360b62454b83f185fe8c8d16a179e2ba8bbd2ab654efb14d67c78c926b78965478a45b3f3daf47a2d71945e0128deec46454603dd479fcc018374076f73fd8213f823f781cd474137f561f5516d82e807286727b43a0d31ae954b131203f9cf6e195995c1bc5229f2bf5fc38f00909ee45c272460f49c54228ccbaf92e438f8c6aac87f0b4d663ad2db0006900a373362e0a08330336feb8d8aea52c2b162ff2c3fb91365ec62c1fa6b3427ef8323d1b5e38aab252251c2ba66d6653bb4b7185259b31769212b7eabfcc7f3ce8001efe65e5932413ef9f87142f0499db703d8538c09bd25b8d4ac3e716db211f0226b0271f0292821cbbc387eb801db50d5ff3f0b625e066c13036cf13f25bfdec18b9c3ea6a4e483c05f63de7d126200c1d5fca659811a043b1d3141d81906fd2247cbb731294dca55caf21df2f88ea0658860285e319d944bd1c3c3d2f56fbbbc9107dd12721822d80037721ae47fac38c3452dd7b71f733706d0fb7e328acad68bcf7f3541f0a61f09118a2257f726cfdcc4e35157cac0dbfadfcc31ea6ab2e708d74b79948d282a79adbdccc7d7cdad45589d77ed827902acdc820da06f153e6c5189f2fd477512f9adf9b1fd57f517bf9a095fb053a6a1bd042098afb0f74f9d14cfe2eab233311ebe63d23fa99dae8bf59dfb0877e4ea460f7c510e23295c5feb0640f5bc5ab0c017699c68c14217fda55949528f019e624ea0dde318e270b158b6136cb8c976f7c18acec841bd0c8afbb04a2fb951f622bb92b7e6de5b9a83025e6a9f139427d324f11398f960501e5d8a5a917d8c52eaa967e804eaad3197c11ff687d66b5a66e9d2baf8c7a2387af63e7d7d0d759a665ce322d6ddf84e01418e4f4b03e33904a0bc2d9c7837687711bc12c251cf7b79ae3adafed939d6f70e7bb9b2480ab0a25637bd89fbeafab94b037133782b3f344893bdb6c9ee390500036e2c29de5304aa2bbe256cb3049a967335ae893542dd2594137b4b53bec88ec63fe0f5148113afcc6a909a014cf32146b8c9bfcb79466c31107158bc9b019a55ebcf41f7fd54018971f1c275e057e682831bc45504493739336a009c48d5008c3110d7271f34ba7637089d31066d5fca238a972e8e1f7c0ff53b5356e0d43aebdf3d65728735fbee8ca75748e7061a907f2474823778eeb3945fd5d10dffa5392b8615c343f160deb35aa3daf3d9b6177311b586b4d415b9b5e7bd33aef6b3fb1f3449c0288bb08c4da292c85383cd4786a47601e6eae237b80f698cd5f07131205fc8025630b0b2f3b94321fe424d1166784e631a6eb3934d035c6a45760fa9fc0192d43c29dddfc4c321705963fe0eaca8f66876ea8e94cbaaf83d3d85feddfa6ae56255969253009eb30a75e1a19421d8fd307818f304405267f5885cdf9dfb9e3d09a5cee6898be8fe6aac63bd2cd373955da2765de1f498352b2044e2788593f4d37dfaa408bd3494e382727e8cc93bd89212e5338a49a426990005d5675d3e2a5b45335f4743d506c8b702b19c1163047fe92ff7ce71fbe254178b4a6846badef54613bc407e72467d106da870f2e319b231d38e0b8a08ca9313b6d1db45890325db5bd66c4c3415b476caae70c9e333749278ef1704d434b2bcb9fa08cd194c6c3c8b7bcd6a66f42858ffdeaf63611f0e04cfe540332ee46369609a0913904bc101563726d8ef60b012959ccdae946b71fe3b9c53b0d2647e7128813936c47e086159ea82376bffd97969dd1a357ec183d8d23a83174de8a5b8e074494a3745e7e94ea877adc969ff782e0f700287ed03901a0c82d2c01b19d1c9a9ea1bf6982f1afcb36d3205b6437d87dc1dff9c99abaf1874d8b758a08ef1992880c4c1474e2f9c9c5bc9d0ee987b4e7dfddce1fe24f14d7f02aaed68173ea9a2b14a4df546404fe1ca26fc716c4578dc6f75880e573061a31b97a17f1662af54f1eed4c7a07debd42e4d3bdd802e5533092851147c46c3a4a099995f976120feda5958c7df581aa51f72dc679cea5ca4dcf9662e5ab79a98c25d43b2bc038e9abc764f7183cb124e00747b0f395b909f95eb12a40d29b0c0da06ed15dc19948a529ad03bc9e6c2bd16d8a17327fd67fb32354611b23797bd8ef6cea21822f694cc15ee5f97701d0b298225928d8a97af8c7c524e85418f7396acd42c4d016bd18609fefd2aa645132edc2e11bdd1da0aaf892ca7d1515211ec1d9af086349c8d89580191f999ecabf54b5fbef8bb86bb6edb34db681c25bcedb9aa02ad89cb92a439336039e9d3efb52f0f9ccbf13503409bd65aff7b9e9efe9a9092313cf8669467c1b4feedbe4fb135d90efd9c42202bb3c69d6907af89484b48bff604b4c0a7bbe30dfc374b571b48949e4d394357ed0b53dac48689331b7363e4919e07a84bc41116a4e93c89c200439f78cea43c406fb2d269b48dc563b05749f4be636ea0865e647f0eb922b12e651d11414901c619a420fc0a9e833293841f8f80c9c07db66a00a99ccf7055b8494f6de44e2295eae8b1c7a305417127ef7e47ad468848e19b411dedee70761e266db839f75fdbd7142844d3ae60e1986bbe107fb4a095f109daf49e2f2ea30155b172751094d8603ea524922e54ceddd6e7077af32db36b449ed89d88070ab13e4cfbac7938ce85fe225b1b26aa11fd32997517b9bcfe04fbc03620601b2818b1f7a83bdac7731872b4081f58d2a3597e81e7462d1d1dfb7344b0a5ced744a3a06b425126688388b35d17393772791413af7205e265f94904e0f2cd9d64bde30b1ffe4614e18bacb83e395a62e90eac9a9e6848f60d8fe0ead2366663f9a5395ca8757908e8a7c7712b3738da8ea4ea6bc7201132189a179e46d05273d35ac774b920d78e70cb80da28f5848e263acfef422f30d1a1bcb11f4c0e73de2da1f24a4155ce601d22e64f134e01d6c9a4df4134347487b68b0e77997910a73a87d11ce7b97ed3c8d4375d957bb719ff6cd8b2b3607ee47db7bcfc41e9c3bdeabc8199f571bb35b4904ef7b8f9cc9c7cecf85842e0502b7361f673de62fe733ef3db30604c1553719626bee2134dd1c6f684f2de2da692aac66aa6cf323ddda97ff2a19f4f60077a36da1327760af67d0f8dda37405908103aa73267cc340776f31338aba91790d3f6d4a1411225e3deae5fa563831c02931145c559a0edc0acad43de30a2272f5b19a7e92485f213287e71a05173263f164d83fd63f5d3456678cdced8fc195636e3fa800e5d65aea803b3838a91a199f944323cedbf4f91e578dc1fab1b42b50d31bfc74dc416f9fa5c353f655d55572e29adb4965b63ceea1b5c9947a9e1ebb10e6fde0689444238bd1976e97a2eac78e4b03b768ee65791ee2a647298846e29f5f71d640f4ab6c6f191a0734ed89ee3baebed45414756f68225aa96c327294c94cc2e0a5e71fce296f69b4ac2c7e8fe8c62488243338c96e652d05e428d2c3a8ae579da86d9180c10d3ac3d6b28e822ceaae4539c3dc0d109358ab88511b74110c52753927fa4bac0975c58deb1197bebd2e45912986576698613590713224b39863a8c452dded508a6cd5a50f65f5d00a975da032402fc8e8655e30967c499fd4d7ba77ca05b6284091ed7d752c67340678b80751c4d73ab9aba8b03f6e60977b43346982348712b0592f574050192e582907ff5e4a495fbbe9de29eed5850a98baec52363790464f0bb52fedc79889d17cd3b1b5fbec9249daaea8cf02153bbb3fbaf6e522dffa68b061c1891742c2956c836eb71cb1dde263127ef07a5bc8005753e048fa38fef41d838acdccde18cf46a210d89e8c7fcdea6efa5dc4672f1ed9da8ae1583ef42177bd5a62cef25b291acf6f764475a103121397dfca005049dab0f3d92ab98d9793ce0db751f18210c90a37f4f73d43f37c89bff89410ed7d7887166d4c533f746e80e319565175bb4f140d402a3009a936e86154bce767189721814768b6801d63fe7098044563dbe57e25073d710e324769ec55fd74a1885b0c38f71bef29defd674185d252dbb3b7bfdfe0e09fe38c957eb772ef6f0e2c16194add18d0daf58d2f8db21f2129c14cbf1aeb45c8680b8cadb6c9d60e0b300d7de73f0d6da9bf067a581d814f75409b10552561028048bf07a5e3e820fc63c2d783afd039f974e49d88a2976dc1d2b3345d9e9c7c4849d022a6896265019fdb9044dcf9888ce9b986b14a016fffaa59e4cad34cce9f5c51efa429bf93c3951254aba49d5b96c625e7bab1838e6589424f29c51d88840bdb4855046f8094bb5131497621a4354c0fe19852c59149334ff1864873026efd227633dc25a56430085a36c801b9c30116e50c0f81150021aac132ce9f08986e920a438362092c32dadf942d3a729733f545b3612eeb890825c78600ba63d63e800fbd0ca47ed489193f8cf72ae3ad79a3ef06d9c53e57c43499032526eefbecc9c454a2dd76b5026d0e754581792eca5dc0a6b66822ad7f72786ec4ddb60af3decbb8fd5cdfd401e3988cca41e3753d3c9636f41c732ca4ef1517f23aab6ddb174e93cd01093f09a8802a159d9c9b54b6e5948eac0a0f77e748b753c88e68dd4c38624b7474249a7c0955e01562987f88f3244b694a4c4ad380b4ddc01aea4970d213a59ecb78f5550845b38e6f93678fb39c7332d4af7c3f707d0e453885f11fbfc3108d4e4a1457274b3ace52442b0fc85e61db833b5148900fa7e01a6f8a7b1b762582277c6ee6384baf0b5d07eae7feb7729c0dcf9d1f3fe1a6885a623257b39e30a0325697c2a161e21af5294707acba86bb11c3a5e22d0913eba2c8e60f29c59f3ab1a451a9c1adec64de19e7972a83a8f752d0a92654bebee2a8f0135a183304bf84bdc543b7455bb25ee611fe2ed729f5184158b9b68612ace49d51653aa187eba0cea4e506e1776e68b185571640f93df49ea71ad0565d28abeb563c6d51702cddccd20235361849ed108c065f9e2c6b43a1119d47734daa428853e5edd5e31b57eecfc830cd199337c6573899dced9fa49af9c509b9f7651af5965137551b85385959625f01f4f1fb2bff550e27b32e2af7951d288848ca36c47fdb9b2b09c2751e31da88b5963af763c07329e171b48a00e5de512b897a7a60f16a45e62ca30cf6c9d2d27469bd49759e3939a2269716baf6dfd661be896199d6018e318ca75730566fee510db93cb60bbf337c1ac388edef082fe6075fd78dd514eb6d4394122d311fe47ce77f8dea5e8ec42e476f319f17366b3d26859a93594d6fe94ddc79498ef02c3be7efa54b20e4b5fa1df09bd6f1db7c50cdd486397ee41ecf503ac0c5516414c8e0ce5d8020ade0e337eadee6e6af3589e3387d90034652c2a223c52b6e74d39657daf0d252530d8ead9d969ec79be903b5243d05ad7861893d8f64bd514b71617635651480ea4e96baceba74a19bad9af1815d33500d6566d14a50f974b940987959024b29e4c41833462e8d4552a4ee200fb757294421accb7273f252c4ba557dbc10b576f527902428b4ce19e00e5916dfb2143666b561f6ca59995aba1d700f207b4ec0d22094527993479f7c3024df17e7968bfe0ed4acdb121d0312336a8d9c4077b4e2015412b7a71585b0b8cee04f821ea88469e85204c32d9026106e9a945843fc0a33282cc6838e258c9129943b36842ac42d0de98e48a54efa469d2c12832e7a6df0914d806105a71614d906af5b2f6dc5204f62cd60972810611b25edeeceeee2503c39ad877f4038a6e34c9885646b6a35fbfdd798dabdafbef196fecef0f4c7b9ddb55dcf8703523892373f6a8989222bfe306c3676c0c61c4e162c4a0b2369134494fe83087ddbee6519158f587612c426f359b08cf0f4cc4bb2611be3e6d992fb7c8e2c09a8dc0f0ee42fe1de6968c161a4ab4201bfb16954c35f02c99487623571056da0e90f8e4f384bec3393f36428e1a0e10f94c9ff7826142e8a88e57687627fd5d0ba853b08c03eadc0513efff41470394fa08664a80558be3b76c95967b6981b77b16b12954837106af07b764d3d0b74d641dc2ec13de25ae43d5017ebb7142ccb718f4c574aac897a586869fd4a441c829da81c7e3906f7bbd8f0e0aebcee928ab54c96ea383976fb1a78514f79999b1b69ab85dcb1f97cda25dccccdad78fb60ded0c41365400b542dae6ed28fd153e1766948006078d3762541352ec065f52f899647629c790fa5a5a1c22c7d672f0d7c3dee78cb7b040b680c766bcbfbe726d16ca7b03f4a48c2c2bc37957350a14de82315bd356f4d7cf40856ac164491c7a263e9a91af4328850a28ffc60d75fb711a9c45a22316fa6a4bc58a6fd56520cf9a9504d6afa62f0ed7da4febc036e999a30340fa8c16e8c1de5047f33c92a879f52e78f02171624293ae86e56fe5a7c021991dd5c1d3da46ef6b0b8c6a3dda80c17a4c5236ef05d43e520923c20f4859dc86792ea680e36e8a777155a812cc69f6cd00d90e165585919c8f57832dd500169800f28d4f77d423fce5ac656bbf90dc669e2f101094312dcc46d847b82c066261adfb10f2a6186f725ec0de8959c00e17e2b03b6d5affe27497775b5a93dc4f7f7a105abbf4ba6591aa5ef9f8420ec2d2641e0e0f4d30e1c828773a3652b4e33b483c4f43543b42038850085b29fad9e508aaccd3b245a50d9b9a3c24d5c5973b6fa6ae2f544413bcf0fe3aac2dcaffb91507451c8ec1c18e309514a45710adf5b76bd81f2fb2939e6ccae22927a0728d84d791e122c13a70988948707af7dbef9eb0098763b58161e65b6a0251717414aa7249e4ba70348e610dd6aff27377afd5ef4c286e19525598e5b6c5d12920d2f083bc353bc8caacc1e8181a4bf7d7613e90595e03b2b534ae958949ddcae14aaa54bc632a227d0d7ee0e33e27a60bc46d1e00e7359b3871c297a562ab7873a59ef7992d52f14f2060055f982139670be23f3c3f739147cc26ef74e25ce4914e1c65c19bb436887e878cb7d101223202a45c55c5be2d0c9f4778746d66e3c5c3e562f1e2da9167386a9b4b1240c68bdbc3ca230254212f9edd9be0b85177fe56a839a18735974f1210a6909e2d18d4f2d521ba74a1c033c5cafed38f540f380ea540b7c9b22ab75da22cc00788524150fa928b91dc03d9da9b736fdacdd9c174bb1d45911e18a40dcc6c1ea2c30c655f35c2b8d821ee291bdc86e7f0dab71fdcb571c0fb029c5ace4aafb6f2e5cc7785491b7e165e44f25060dbd0a07b87eac705604a727c0913c5b606f535e345b48c1f50d8c3dbf4fe02b6a81fbcc9b6f3c2b9c01c6c6cfd34b39b9589849edd1147520470e6ae60761fc83cf6665ed6fe8b4c3530ad8c219718396c20a4f7c324987187de786bbb0f8e42f0a6a1c0ba3712bf12eaac876b47a1baefbc3432805845cb275e0f8421237a60817f97d50e7b19c26ce7a3804b39ab1e071c67275f12b2e592e2d81820f77d4a1e1eaadbeaf286d12892918eefc497c7cd007c2d96ddfc11f846f01669ee07c00524ee137b3a8749c32781b71b80749d1f8683ee592609e5170112c7ef49d25e130f33a00a5496601996cb9100996e96ce7d289f5809aa671a75bceb5d27444235a9ca534e19198a94fa45a1c02ada765c403a15a4431d62dd5aea9e64ae82e0c9e524480ae79f99c95964e61b52d301367310a528f40817f0ba04ef78bcbdc1d9195117b6dd3d5792210b448510a2e946da821174525a8727286f7cbe0fbf4dbefc1e802cb01519f08659a1b6924e9355b5f08456dd2664cfdb1e3e61c639357ba3a32c391c3b614173d2b1436aeace106e3441223b2ef8431c9888bbd383425bc04f64d0b2d317278835d6426590b80c5eb25a39392ab64c55c61611fad37ed0d8079aa1a1012f7c74518f85e75cb51ed8bbf2c1fe54b1de5f3e140a71d57e0d2356f3cc9d16b77b4f3ce76ae5284c016c4297c3bf99bb3ac0492a01cf64bef5f57fd9c3888416bf4f0407cd2d084f6224918ab2482e9f07e8d71ded882e887ef790f1c0cfefd23d3504b712fe89db415371eb0a02307ab6f6d583314d331c65a16d6b75155f5eb8a89071057fd461ef6756053b504c8913c22f4c7f68ac1a0533f5ae0ac802bfa23ec0e5f1061c82281ce19d95a64b298ae8bbb89f4011814d71c0769d0f9873cb8514fd4ef018b0a11374ee5e233e456cf0e114b531d3c04d4a51bcca9558686f62866964a6a548ccdf70687899e3340db520ee5cde1c2562f282cafda974b453be9e4c51c721a9cd644a11966e6315de8b51b0b20ba5284dd250314bd00e393ec5a275c00ec6444f5642a6f064f72c041bbde9d7efd2a86f81282ccad35cdd36587780822aedafb88549eafc5c00a7e2e8bfb6112cd8835b1381a9b9a99d67adf3015d7a1c063048e4c12d922ac04940333f610a655dae3a2488d63a220697535ee42fcd0f9b5c6f96cc7280ce13ae5d79fdf7dc0b7c7898fdbea9682a9f056a2c51965e0a8fc8c21f63a392c2af43a53bfc461e47531d85280721ed2f0cb2e8470a742218f3a36035dc4043c5bca7c38643a9a07da4ea4034b030f50070f22db4554672f51f69a8c5da7f7a1d043b4908793ebba6229738716b0dd52c2c999e24ed17a871882e3b15f0083d2bb28281230a0f78645a26cb412e9040b8d6810e9f8a1044bb0f423ea29830c95b6456d55606fe7a3c0796eb49a2df77dc4f62a3665d512c12a2d60cc7f9df9dc145458b3623271b6c2d0054d5b5c81b22bf6c831622616c9ae8b647b2911f1f40ebad188f4a519dd578df2a700a9943d024a34f6382196a1bf26a6b50067f0a7d8a6c308212a053056125530c349d510da37f86f9027da9822bfe4f8a068b6e6f6e39c58516263f76f9fef3ac1de071482b0aa705233a43a5717d7f7f9c6eacc19898e5f145ed6e209c846972bc0961eb04690ad4eaf2b2a9e48801b92f6e6381c16c5bbbcc758ee8041d5cbb31c53a27c5e3a93b08f431fb8747ff8041409a97dec1a853f4e7999430c0221fa255ae30b6c5afdbae74af0fbc12ad9ee12b0983a0d05c5d85ae2e42de56c075061f34343703f447c44c2c14f52793916d5c6a8cc3e3087531a4b6b721194768b8cbb9287a8834a1330a03411cfc25ec3f52ee6d08e4212365109a09b2af6665f8762a8c2d856173e51ca6cc391bfed77bba1c595a4a712c74445ca4f644ba67ae11162f651d199eac8cfb863155616f36b77d32a1aca049c8211317796700494573de8fcd01b85acec551fa4287a8277f69ac5d1e62ccb531a2d32cff689f0c34e136e9a1937b50e514cab50ed1630de8f386f4f3eaf21927c07cde8a71715b943a7409f5b586bed02e754736a376b802c1dae19236611ecca46b70b3a0138fc248e4e9c30783250c9b0d938020c57e6e85671de38e4324306a4f87976dd2caef2a7a1136ed4260d03034c2c9765d51385d1c4a3880ef1c9c826bdca8863a01080be049f2558fc062f3c8840baa729257ed061e24d94ab1916f31699f8c7f2b1855dac39a5d8fc92c94d1c146e90d75db0709ce7975598c8b2872b0b8f5f32b05c45f6346a809762cc086052cdfa1de93c0e2e1b5d01af063abb13291ec16447bbf29eae058c945a7484a3a5d6a60cd4836cd09e8b9f1cedb04a09424e8c4052c73fc921f5dd3f0f2d1e128be2cb5ae3a30934f86f6961021d1bd2b6a954d21a4afea1d90f7aeed28b6fd478289cea0ca6451296513ae37ef35fcdd013223cb31533d34253a9e55c1de97337398111640cdffced7138f11aa56a6412b240297e6240d10cbf4fa957c22e95089c0d6808ac18de57352c548494c2d257da4a8db09250d64851aaf586a2bf61f3a44c17f7271fd7a2a0497a11f43cddf4c28a4836eebbd44ad71989ccd53f5858b93dc766242849be904160997801240e828042e8d1306c8d8f1e2f8f621408d58010a0e070d4aaf944a1bcf2621ce668f37dac03641779d5a7574930bd28f9eb4e571d9c0159c73b5c0e6132f56bc52d783930e234867930b6528c29df29376211ddac3381e26da3c270820f85fb2a12fafc1cefc6be12ef2d01f3c28d715842b0a886c39ff1b4c5e75c45f2e9569d745c1c485240189a43a12008186174fce0d01f147c3c9fc60e0e6bcf349779749dd49b65f7d905c5e9064e81961861184e28f05a9e1d16f64641d248290c2b221bddd0516546f4a4012382c887e31e1e4bba40a8cbaf02cacd20b36092a838cbac7e444c3b3e880ac7dc1c6179e0e26f73536ff7ba19beb1f9c18e4ba825785ed71efca84e6b1a171231f07b3d404d9e85d65aedc5de4889137bfd04a2bd4fb12879b1badf11c8108a822e50746ff055cefed32dcc24aeae35eb33b7d311d99120f0adbf938811f78f31202e660d1b71ec47e2ca74fe1f8d069781242d8243b5a33213e0243c179fe30826baa22289399b1af6d732d4e8c023945a676c9fea8b6dabfa1554a025d450a159c09cba7f54283a81d0e901e3192a1d530149e4e3edfee795097c0b62e25a7f919a004f1ac9512143f21cf7b694bf3f5ca8869fb4a5f9ac22e323a09b9e2ca773be531bffa61703cfafd9598e23b03f11df3958ef3ad8a33156ffa600daf4d0df1e0468393b74349ff11e8e1d08ffb8697f619147733a828c104ce14b7af8cb696d30f4cafb36d87ba80394975392cbbc2b93ab4b968f467288e76278db9cb8192c1542b624dcab2fc3d0828b16c7ccffb51d8ff81481b6967c4bdca445c0d247e33af6fe6b781acd4cc6f01a8f3ee93a718cac6c9a0345cce25677992855848acfd547d30405eab9d1dbc0a8d55eae130974c4a1e0482e069a4abffa63710ab4d688479fd07157c0a8d4b24c1dc6bc4e46ea7f5b364646b68444c745d8ef990a972e577aa470cd31db76f4691a395268c468f4d73ee7fbaabbb4ac194c2f9a2ea41c4362953b395da79a3f7a248853cf00a8b0bac3270df0488012f4e2c4a3eb439d8c8f6298780f423d3896eab0120a3d5879b15e61ba2d23da51af590ec2fce99d1619cad0cd753ff1fff39a59d556ef9948ce92dd20932a8bec68ac5d9d5e6d2aaeb07ea3344f345579be26b1bf4bcde98de0c41f2d94123d5801173145fc74a1c4e2a0e57ac91930725c16612a5ab6253e62b55129cbf74b198946b2b74acfe452e06ec618d78ba4c319f8d80bdd5b8a207d85c555205d9cccb1ad9cc80ee5877847db4f4e050fb56f5a00a8dee552cb10d01bc50af0993a07e743c8c3dc5a94e34a1693ea0a4fb7cd9f6af966ab7c60a91711cac0c8579be5e9eab97f8ef23a185bfd77a77f82dac5ff07ab89cd0c597c703011270dd7934ba25576185dcdcc89cb06f6c865322b1207154f196f8d183bd7ecaa82377b3cf3c2497cd9a4b3d85cd3d8ce2d74d6507f188683ed8a808f8a685d58294c955ad496bd3a3e07a308b522fdad7f95a31488a1e51e04927741dde756e02f9fefef50abbf628e205f4bfd0f64af08971533cbec652e30cb3bfde727008d66dc0f4f45731a05ee70f4ee3d0967b1ea8d9ef407dc7f106a83729625687e9133cff4e8128c131392c245e91c98f75d4e383edf68ce193f1dc9c829348f41a5ed2ebd591ca60dc1adf780e5b90f0fc97f66058dc6f2be5b4c98a6bfb6a329b62131494bd108b8efd97fa9434aaca4a23e64d7ac40a3f5d931da18fa6548d239d4462390e2aebbd1146fe369ab545a58337581e8b3c699151415579a205886ab8365e73fb1790f103a011f641201a7738d810db7666f6422c129e47cdb1406cb5d1c507d189c3a3e8c700f85192487c99838b1ad2a9eb982f3f0b482c111fbecdc78debbc9b8629e0bb76ab53ec1ba52ace5570c4239f05aa019e78b186acf974cc158d1e9a6c36953aed60b19e726da0df8d5825d827f6b813eeaac15923de808f28f9728638af9770588fb7bc3ce9962054b8942ad58203c13daa1e7fb55ef1cf42da2530a140bac1fe8127085a34581c00c614636ed2dca28a5e71067b217d8fbcdf727e6d7c248550ce081eb38e470f8132e86c59639b2d5e366d8c7fe5fe12caf72d3c0d473e1d2359340455221c52aef05ae26f1bb5f8b66c6a29e08e29494784546a664573815eba043865233bddb18451beac1588ef92ca2796e2e1c8512731e87b55f12c0ecb24026efb353d0c2468e9861200bd230fcf4630f26c6c9d17d41521add56d76742a054939cf0b45c8a9e41bdab7987ac671697cb7ef082fff2e0ca3e0e83093a49991aaf97b69f9843389ce30d54b1a1f4df046d88f58ea8d6a3662072829a81a43075cf109e36d0d7c8ce1544f56c20bd76b3ffad62baa4391699ecaf5c7a5b6bca68ecd405dc74290cbe69e2d540f11a96673a182197c4a6cf1bcbc3a02b0f471e2331a7947de4556c32afc7e6182c1b8f1617972a243e0c040ed328b39cfeb2798eba8987e49a154f9058336ef36a5669cae60b88e7383514f3d16df1969cf4989b40839f32dde717c54471d449741b79f3e8f59b29e3a2cd93f8adb7ad65e1ef1856b2b30fcada0aa49da4c873a52112c87134b8d0ba8ac764c08f4b40ae51de2202077eb7708942e6cffb75e2ffda9edf24f7abad185934deffa95629860c62ca7eba176bfce7d3c196cf9e3c74c999cb06d47d6403d05890f2b0bd659fd9934c9da3117085e8f36198c10118e957552000caa3408298a67a2b281a356e6bdc880d8c51de848531539917966b6e66ad1da3b85d01d1e76bbe2c09439b1f19c87455a8aababe0a1c168ff8c0d7c9ab52db25477ee92ec8d8bc5637b398cce8c9b5a3285654deaa9ab562b28103ef6dc272e060fc137cb5d7f9a74c429de1c58148adb4040459ec6eea13a4932260f1957739dd0b107af58dbffcbe9fd37c8cbf3041693844f44c5b9994c92dfdafb3d3d687bc4e7e283ec17a5e58f844c3d77098f52ca85d6bce8ea2c8cb310d55cf2701a4ccb3a3d47c61bb2fe8a1699081926b2aba7a990878e287821d54a876b248f9f06e864f992c7c9a939af2629f2875409a61d9c08a010536d6a565482bb2d2a3fc903d0d80068d27afad44a95037a3c4886c2f2f71278a41c74be9eb2d0886201eff028361ae0c9d8cc55dba9c17cd33bd71cad1d33ff80b282259aa7133e9a236bee436d1e57e20848b1d242d57f6c5a4f4e13fd259b72223c3ccee36839c053f8dd97d5908a95fe7b8817ec2d87fc9fd4ba80b0fb01214bcc98d02e965e985a08f98e1a63329bd7900b70c8da2286af824680a24fd18f7ad1ff5cdab3d7526b23043c75346ed65724cde6d8cd1e128b5468fc3f1d6b5ea753449b95cbe79c8afcaa0d80c21d17dce88ea66575546b426f29cdc1705c3b7c85b51d5523c2225383b2be6852fea673cfb9d185fd4140f5f8dca64a49d0b40902e65d8d260860ddcc67860a6ccd23a70f2d59efc9cc7b3622110ba159e8fc353f57dd6c48b75af054643ed2b7e254bf79f030effe3b71c719fd32be3dfb12bfc63a4c4b07296e0e13db3cd53165c7b765a357cd2eb230f6506c9dd1fb4876139de12c389c2cd3e801f84aae5b1a585cb4a36f01dcbeadd96f1a8677dc7b9bb766cfdd2244e104e75caddb6598f8738cec275eaa5817e26a3b4a6bc6caf48b0b88f0721a7739ab71485589b4a8be2683360cec4639ddfaf42c34afd6426c67837c3fa3124ddabe2742cfa1d175a8e46ae5a1ff03c95b82cfd744253bcfa951f7363979c2021ef9a5969ffc546ed9c615f9396d79b9cf51438a25cbaee43eb005546b691146deaac9b01f58b5627689f9e7d3f0f2f0645c01f18b7b4bfaa8ae4dedcc213249c96a30cf4f7c3b9dc0317a2d0356a69e578afa62a14d2f8c0e5e12ad9e49074a67eadbc2c72c023ad5ed908a479b56466d73813562d70e1a1f0c6c789f652de533566819ab5086c0473684bfb7d76912d4bf038c49717263ea1735d8871465a78a0a99d53df41db12cb75f76b2195aa8579b8811d25fdf148c9f3c0f309572129c495e71f9aa516bc52c792ce98b8a253421e39de7df661c42cce2fad7a98245c8046a6e2482b6e75d58b6361109faacc32739c5f6782c44e14e2828bf9a7ada44208d98c3bb593b8454f01ca122673d152a002433fd8765aee9f23ff38d310f6afb0a424717fa61ef1f0b699abe9691166202d1fa659714f2ec27575a8138c591e93a05f1801a26816a1258753a9cf1c5c1e2f8d31407d331c77384bbc30067b686f35149a76f9b41958a5253374ad7503e2b550daed9469bc1831088acdbe06c801ac49f5afb7f518cf80b684ba45c7b329e9603cd41f703cd6694afb1357d4d65dd47cc8c62f8582cb650235b7a4a40b533dab1aea34e82ecbdd5f3e46b87512352b53363ecabbd89d3efcfb03bb3d8287fedcf5a695449c005a5ccfd063a10ace62b740f0a7816fcd7ac632a6ccaa66b13cd891b62cf25134d610cceeee8d762bf3a13b7e15933fba709cf0e166f8376b82175b0fb6bd6bbc0978fca269fa8eb331777a7727238ab28a9b8544c434ea387820ab66887c0a887ed0cc3d3fea41206277a2e4aa96fb7d8ebf0771d066cc626a2298600d85292110529598aaab25e5a9982f373d973ae931a844547263ee5398382144d0df03d3851b86d3ac98f20ac285b31942fd9acfc36c3ad2c9ca1d0aba4fd43abd4cad148b3bba2762a7477384c687458c5801a42b83d7b3e115c874ca836849b18f8452417d6cc97d763cc723431668cf89388fdb07dd5109d98ab15a5ecc21fbe2210ddd1789e513ce20219cac029629fd11b5f7c0ac9944774caed02ab599b46cdbae0bddd858de02b4e030098e1d5ac7d731b1fcc40cf7fa517b093184336cc7594fbf3c68c61d403fe071abf54b083154a94d572afa0dbd8e66489c069b110ee138751cc8b4fb5017290dc0621be59bdb1367a9e863ee8c43be855eb82de68cc5cc05b00106cea0e9c3d62804ba259a633da5f1d46214c0d17ca9c106274fa1e300f5c050ea6ebaa07d29930e784c9c2b10e8449ad9b95f7e2517367efa4b3bad32e23f3fc6035154d06a0e6a72462bb10a0e1cc5b56beab29c14324987650e4a6756c42dca469f11b660c7a245d6ad19d13ae41119ff6ab8c116b53f77da28afd13b00a2f9b065c9f5bf9d76a0caaaf4650c14f130044b3f1313c6013799fde9eeac708d33a446844602834d2a7cca8825288887129484f319b4502552beeebf65b8d0b8127c226616b0ce7e527655ba54127a834e6bcaad807564bd2483fdfac572ea19dd91a3a835a4e0746bf24e2edacae538ea89ae0390f8d89bf25ef2eaf97ac9d934cb0f1d9412ebdad4c0549341b002ca256479fe23852c316560b663c666e9929f960bbb065af06eb25d34053ccbb38b6a185b2e0cc6b0a07eb35b2f0567104d82b844605757698e159e914141d062eb9c32bf9d8e1a7a8c51306974087c7bfcadd267b193cb7b1db861994da57dbc6641c5846df3905dc909c4d787087d26df8eaa740165f7fb517e513634c2e34019485389ede2c8e770b193bc84dbfc44af7f20b523195b86260808d000140cdbd06a787cccaeaa2377cb58f04d8522446f684a155a963cc78bd63de153ad120beeacdee997a7427bf4abfa7df8a59a9a223743342ec6a7234ddd652d986225861c9765c68c486b23eacec4dbf1fe11916fb795d76367a78f1766a7b3af2ced272da406ae56b240a7421a43223cbb629c6889101761d60ba12386fa55283e4185d494ab53e0aef4955591a5b33628267c9419aeac8b9c001bfc179e15b7c89b5f4abf16a61a41aecd05327357c6959d0279c66fc19d1f5e524a2fe5bd6f408b487e53abfc2315768ac399516bbd544a4350684146bea9fae753c1449853fd7302d2c3f54c3c0e084f873fcc03d1f688df4f6e27ffd77de35f84612462aaa09d9a9322031efb959fcfdc5848d74170a08f45ead02014b4cca1f86a7fdc84e9436b4b0473b448db12ff40f43a431514b7ebba54287282b4a274b78b31ff1af52ae951778593ba4ab666c21b960571b3a26cea26708c39873048ebddcec92417a4b85979e18184703c2e2683722a417c91ef12d0618d3fab943113b9c664fb64a201bf9e8ed2703b327f88a2312e6b07566ae37654341c3e9b5cb0c963a1b2cd8be545e9680733b5e6c9d1b7fc401e13150acb4001785ab07bc505ed128cc494ba3536159f573b5864899efb05e269740ab3968fca8c7cc6c53b69bdcf74008d24bf4cbbe615355f435244def8132f95fc6a7e8ddbc08108c83b530e2506ada89188666b57dcc1958613a9c94ee0806a298391a98082ef46f90bca6c45cd456bcc3526c486de20ecdf08d99a97dc6f51221b46b463714802af4925fe965bb8d8fb7de5e551330714d0a79c7ad7a34f304ab9c2df94610eafae8ec17d10dff00212647aadc48a9729b467d806cb7ceb3b74986103b09efd846d50974f2e4a6d86c8d3df502de2cce150c9050ae3f0305a4572489430ac4db5574f542a9a503b60232a7ccfa61af9e87d9ae4e5d241d5aa21756928c1c0722e1523ff6338e7895d57fdf940a3c21b83f1773f4d552588c57a85106072e760870cd809137f82476b48e36d2439547416cf09330948d83dec6138105fddbda1eaf1d95708bbcd7e2d27814274421d0ce74f4fdf46ee109018c47bd44c8d268db741011e309ea5118b1c260e0addaa640779bd949398e38dd54cfb1ebb462c0aabffede0f44cc9abac86f1180fb7c87107e92c03876e8fff69cd03cc843cd56c2f148a821e66cfe9b637f70c606e5f210fb5bc42135d6281b1fd5ac61d098d8242e8cbdb81a0e857d62df8760111d79c406e31ee9f4636637cd4e35a288db991dbef5b058f7cc004a369a0db538a0cc965fb7d0241052489745b31acf1260031afaffec410ece1cf84d7e8fd034a52454a90569703fb61899f73c328f2a51f91e1cf4697e9f6fa1e3af1d2f900f1c64772d65d829a5c18685aaccef3c64fa2f63e81d1fc551848951c9fb2568fc2000744723262266d74f04a86381a980e2d5d2b0075cb032ac9561395565f0df8ff14924aa2b7d80e819e24bb641c6df909490bc22b224ef5e03a42cdc40d9b244fc12b65a14f4360edc23a60e54415996b3e4a40ce4af21b529ed89dddbdc16db8d5917f7f64e671fb569e8b53b8502d677ec44c8333bd2497a0573c91c4d59769c91fd6391e30d6d5ad8e3505ee485b5a774d946553248c6237c0515b5cc6cde9f382642892c086a9cd4a1d97e32dc7e9fe776c3a31dd565a22d91228dec7a71a9fec5d49592fe5b1b10627f00ca05d4be988081a1d4c192cf7569bf941f74d7fa3cb374f6a9e134d4ae3cf34a3584890662522f1540682c7a4341987570fb85b081bf7bd4ef2b52eaa5e7b19b2a2b32497ad357b44722b594584de384728425dd7268472bb002e9b8dc349b10ed874a181cdaff5f832001c71cae20fc5f0db03c868c8517006970c290458e6aba1a83d34ad967aaa2028725d23a8697dfbd342db42207e61eb07d9d1092195976eeabe603b85b555dde5c8177d18feaef26f102f17b148d434898d412b0c811949f7b408035115ec9d5842d25e85473804855c4ccd23268f378f20c7cc5c406ad76b12005dd1ddd8968237eb8960c5dc0661e84ed92a31a053d64aaea36d1489a6cac35c35d835ed3e01579a9e3bf10acda981f10fd0e2ddae9f3d056168c5fdf8721cd63db706c3f78c0263b465e93b4fd06a57258ad788d4ea5551c528d29b0486f0644870e8dbacefc3c433145212133d233e4a744339fe8edb0a050b0d352e1e86f50a9e2136675c74e4942c556ba7463d68aef0042fe48b94885f8b025a3c1d7fab6c95a4b3f60716a91fb5492097205ab8fd4767c2889f375b34d79178095d2eac847149cd62e8ae47e1bde29809173276f00026f55e323bb076badaa59a6fc9911cb5c5e59f68831c5356eda02f9bf8d36b671a734e058fd64e619b074020ab32c25b3ecc9ca87b9a4c7d422c3151016a74d2141046c8ba7f40449322f243fa34f8dbf712ba2eafc8aa3a866129d809c87112c170427a0cc268ff137985aefa887657487e9e13a07aaed09283636f7585fcdfad6b7738e2811c395db614306cb7fd3a1124df30a64520e328f5a2a707544b3abc001aff5be6a1bc501c2e6106cdfa18d709a1f20d416eec9ccc4a834058461c15fd80d03f9410c652201fd357e4632982f01865f2149d35897cb76ae6df5937eed1442b9bdb343f5a6a8cca805199d5836acbee34166dcfc6a23f1ae2cdbb36fc1c8171c119ca75b04842f290848e9e0a81af55ba9908b0563e3249d240271fec7c0c0fb8ee27d463bf8c7f5353c271b76524912ca89ad510210f0421bd8b54e4e28c23bbc8fb3d184871b35c1071b317220dc9077fa41977e60c46bb9454f48f4d5e22a50019064fa71972f2de2e6a66d44459f8e0298af814e718ce710ec0b900240ce32bba810e70c66dfac03c9a64ab1641e1330c9051ad927f30fc5467f7ce5fcb6d04b5c6c18191224433fbf77df398ba92531bac32dede3bf5176eed2fba960d6eb4192407be92661984cfbf1650c271384f4bf8c11a5c69ea89a25f5f6dfae77accdfdcd3e38bf38eb884312c1048fed45b5dd92394d02443cd1fc15cca944e990f3cc2c481eecac982193c363954ff3f4d1e1711b35834475c18b49c82aaa9714503bf12245fd1aad7e4e4632e5c8e379402e15c433dea9a022f1a053df911f366fd570ecfcd366bb56d74cb27b7621d25e1a73e88b094bbc7e90888eb78e258bd6ad60041ce85d2dfae40b10d0c4170cd15baa54769d7be3fcc1835b787aff575c4e70874701043d4705afc4ddd11732b33df5279d3e0b91d7337a11229feb5e36d2d384ee4465eb74f9800a20f46fc15c511d89802e74fe7703b081c503e8cc0f6501b5a4588d79ce59d80214cc05d03c2d596846a3eb47f145cb5f8cdce1eeb1581c1b29ba277c7f3c248f618e310d4c229710a80f066816777ada96a7d75e9f58194b0a5b40e6d7b5db3f6425ea90e53d3eadc4da63d102757ab770de121c8c844a8126a9889ccea2bd58b4e35cea1c4f839c74e563a0f1d4b8ec03fff93f075e313f2c50929e0e2af358045c08ae538c874eabb8919c6b1d408a6960652f9851203327b8ff0921434c5aac1b0ac22db65bb55def4424604a6512cb9f903c57ac9cfbc1a8b3f402c6ab6679703fc33121b5b343c0359f29fd8b19372b569f08740cbe76282c5eec8d900eed52f27c90c97a4e052d388e7851efb024263293a1157159a7780b8a8e8fd3b98244e02e941b2c0358cb2000450aba49a19be0edd67ced82e1ff960d5e3902ba68e9488751d88268b9553973f1480aa3f89f616ad6d0a181b020304d13fcdda04fcfbbad18f91cc2df6177401e0bacb5b4edc7888a26c474165e5e68eedb94ef237809ccdf85b28ecf6204190a8c01978bec5ded5ac2415f8afdad5bea0fd958f1236a882cf2bbe69299a545253a20f83202e684e3bd50f16d60ac1d570fd26c7b45e95d983ac2f523f2251f21e62d6ce89bad88ef65ee6a5e94d0f99f93acbc834f9a948227fe1f29dc6dab22b1d4b898c585a3ed3219af15f053097dc051596ce4787ada2db3511edfce5a8de6fdfbca580216f88554c95b05746acbfb2bb320fca5fd1d05da601f9b4b8a6591b3584ac2bc8b5bd5adc6265b89e0378914138d11c7d7187928037bdf66db0734ff28ab26b63380ed13df77ba9850f3a5e087f1e2f1a6448e64fcae65d24cdebd92a6092f2f2380c03dd9623a8a696bbd302e817fae006bac1e5edcc6698554bed2522ec59e0e1acccea041148b8da05af81235370db3aa514707fed1811c57ad81a3403fd1063fb54f549e6f5317f67a7998e903f3e4b8f7b98cd9f3993c8aedfd6ab9420af8a15d68c544aa221541d95ec2465bd2eb2bd5bee656af66899a9464db259c9fcd3023d081d472d7380ac6fd2c1c249f1f1a3b49bdb25e6e17cec6744838c52b30d995634090baa179387a367a8302b753948456971ed6d5c95ce697022b17146de3056c87430f9596160b74333b311dad855d86740a841df05c05922349203446be489ddd413bc1e037a9a8610e1fa165342cce5373c9555b195eab6c5d27a85bffb2eac54e413d4d81132d4a364e4bb0ade9c1446c3f95c4c066abed095cb6a373ba0f9cc72249218c0f41d5fb0722cf7ce2c8c9034c0b1e42b71a4f44b350fb5c202076ee80daf18118a9961339f6f2bfa79940ab27a057e123fd2a2e93ca7b2b995d9df53c0e6d57c60cfc0385286c7529c5c95be0dee4ab4cbdb8a501f12b538e80db990aabd8664a927f7094d60fd9088807c8b5635be8b2ce08e635bcd6b08a7f73023f8871aa029a0bf0c379987148a0520ca7bf2170d5b07c623de38ad2719d030880aee5378f6de8dd0aaa187e83827477538969fa97493fcd09935107c320f432f9c0154b990102dd391b3f74a1922d7940c04e7cb763e8472e5c963e8db46e56d22070e929a37520381c8786793bef4f126c43fdc0a94f39d9c5dd3edef75e2dc1c8650ef4c380aadf69d2624adcbc97ce615223992fb411223d8a412be461e3c626f9f123aa2fa99c72e80218b0e620491dc5555b99e68346b40e52af47697d6d161f20f7ff44834ca48d87760399b6ef0a42c02ca05f1d4730516d475d2333316a209e3d0119cf5a5b18e5f3227b9e31cea84deb6ddfa6f312a998cd09392e9bef38660e1f1bbbd3bf8fe79923158de494a43109ddca83359c0c7d91c1bc7c371fab67a61c8d99e0913c28054b704df2215544fc0a237730a7388c2d4939bc07b336ae88d1bbf9277704a324936fefa81b1c933f5305cf04f09ce00952d0a93213dc77d242183be6b7f58f690012f01fcd13672e2d55c44217f7ee08237631b5882e35e971fa781dfa1050c694dd3704764a09443ddf4be02d997a564784c4151d77baf7744587da72c9fbd84768b3d70a67edb97ddde394be8cea168819ddbc27d8d9c69e697effd970730df6a587d609a864f842b5f11addb4f75fb312d98724c8d6716478cd07ea398cb6444c820b765b0b0897c835a2a7902eafa421f811b5e87325b8552e58b3fde32bcee65e56cc031293f1ce27f64213f26eca05eeb4cf37defa1d20cc55fbff6b089023f1718104fb5f8f2f67480a0d093ed061033931ddb9260d67e429effd1fba8d34d2a27e931cfe413c5e70e356741a493a947f46715c4d7a5a4744c5a9c138b1a7362952fcbc8ab87a9e34731c14f190f02c0d4862169680ca2d96f3e4e243800bad4d8f64427c93423e82a99f335f176761fe11daef24d56823c390fc9d5423d196c94d0935759a1b41b5dcd1b897326bd43dab62bf33a63610e3930ccc1b1976755b56ca69813411d5bb0bf8e07a414910d40405ebe14aaf2da88e8dc6e9b3be6f6e4ddf33d7715840612f36e89a44a03901b84b94adad42ed84381b25187d5014787a9879511070ca2cd8ac2313c64181f5223214409a1e9357f6302edff8c8279e0d4b57918c820184bd9bb72ffbb659281f74546fb8f494c4c0ee79d7239c5a0589018ec3eee8a8e1312265c1f63ab50bacbd8c3285ca0323292e1d005d02899bacca780713e6707451c137ef27a88c6305af261df75c86c92543b4d3af994b7a14916b847aa35e017a4a16b6bfea098228e60d273ad542a8032f284a97d7455b553300006000633c4b03d3a4db130fda4ebe9f2398cc7dfc714f43b9eff43c591ea3cd7137afdbe6a32f57afc281bb2c76d5d09fd237eb24fc0c13937c1f12634a0f5ef5db26eac141f6389b8850751fcf456eeb21481064fb88ceb61c0c6d6138d10befda13317a97f2f325604dc090a9f3ee0f36be135512f96091a13ae784ab3375a4b43732bd1ff78ae66bb7fcb1ed4e4c1008040d3af3f5b5b81db4e89e184f71dcecbe4dcfb5c7c6fa7536afe765f8d3cd5fcbe5983696b56943f98e73d52a8ca745f980fe741fd545a9e9b11f09096548ed07e27a1c325125e042433ddbd6871847ba184926424cdb0ccb637506ce4def55604b84c51d117601dedffa2738f5ae9804483b343f28020a7973e1a15536ad9f18d64c84c253b6e36858ce78e1df744fafe9aa02661c650c437ae0359d74ebf2d141cf94d45dd747127678ab7324a7f0122d240b25bfde719d61c204cf01f71955c095c645cc7f49d78554928d3f4bdaf9b7ee7003db47e25d669c52afb6b81431e577d777eb463fabc1298a1deee684bb46b116f1edb41815625090cea2b04d7e4c7b4a58200c79661658c150d496303e258ec71074e129e8e52846dbc6075303d13d94c6252f9f19ba60f0090c648851fce60c0a6fc32b474f740e41bc5834e44b87a4dd07faab5029fb745ed9a28d0a3b3f69dbce8ec79d95f5c077c510c570160c15929b0fa8394e6e358fcba4991d1a7c6b27caff7cb5a3d32131e0927004972d9c940a127b3f98420a3c8850b493e026f960346c889b6ecdbab8542b639f3c1fa750fbe53dbd4816a5cb1a20afe81d3802f52f4898c5e1c4fa4af51744e36e08243dd788e62e26200d36d3bc09cf696a6664bb78494ca50da8007d478c04b1aec2e2c4f20ad60ecbb2b0fa02892a8056311bb5fe0ce1af070cd98357c1e61a521cfac1aaa51f5bca266254ead6e2e4515af26d4c94bf4755e93cc442850d11f7204a29ceafbb7d2999762d770664bcbe5efc354883cc29588914630de21486a4ba51b06870b66e4871ad60aa34f8b6b6590c998d2f4a84dd72adc5b64248bb7bc09d53027149c2e4bd2f40077523f73a0be4871c60f685036c6cb2de238280afd40289393db79bbd41c70e696a329b2ce91226a44e2d7d50921dd522d9b22884d682bf6a6e897201f895e79aacc2a0c3d9ad18dca587992885ba6631479567fd02c8e4139ee0814432ba9daeaf0dfc4e0bb33b1e01fb808482c0ca016a3bf107ef2a6065d67918c9b03bbf560b03b434a05dfbcc9cbf0f03ae1175a2956b268108b764edd11f13cad5c97d09c4b3f999df61a5290e7183ff0fa841df0410c60b6cce0f3e89a00e9c9f80895aa6ba31041e99be19b1600b0490a5bba791bf084642a08d5406b6633789198c5bbcb4a9f228cff961bc846a2094deeb6bea64cd0f2ea012724e00e049afcf8f462553fadafd56120ce6164d2398b3999eb20d1f0067dc652b6d2fedce10c0a69284ece3d01f47539b2db5b0f198cd81b29ced13ef03e03bf0c207df3e93d526b71154d1c04e264beaf6e0775bea2b13365830640ecd8af1b3037314bbc112188fe466d3521fadc1d0c4e7439bedeb8b3a648cfbd852acaaf0d7b6b80f4dd47a88ae33741bb688ed42d770a6816c1e97a6e7be9634b742438a3a7d2f1996e3943dbd18a512e29bcadfc629b25a4013a018601ad3c5a659f2e5b3245fb9f28892ca3002e134a783e01110f73312fedbafb3bc48831fa6dd03084d78705abb7fe2997f3fcd844aa83911c05f28619b24961546685ab8721dd6adc304badc0fc6dac1754fe69e221f4fff8a1ca3cb7924f6362faef0a9a123f1cb5d588e83de56dfb1b59c208f6c161478d81dee60b0804ae3a68d434d03bf2858f2c25c9ca0e9a6a4ef4de27185eaa1ef56a267a1157ae5fa88a84561da02ba996305002e4802aa508224442c82ed5f2a32fc223ad900c8c194d5ea841eba3e94f80376e4769b68e13e2916980af0dffc96ddbc18c0f3376a35d2ae292e860edfa63de8980b9aad51ce730fdb18e2916e7863353fc85af719a2219df40aa4f90c7ad6584bb6069b68e4206517dd535000b3b1d8fdd8d2835984004b4d7c74b0459f70c031e1ac299a7f24b5425d8f90dfb7037e0abf52ff87dd871063b319a994535ea4bda2ca63108816e18649998edb2af40d8fbc08bfaefc4fbf236530019f4c94013427da08ca61c78a86799268f3019349e481fe56d13496f495f13e20111010cab1da02bda13d917fca8480e0c55bdcb32ee84d79d6b8143d6739ef237b56870fccd61ad3ce473f95260ff3022a62b0fe68376b3da7615c07382f32257bc1bb0ef0da43dbf339a513d7d657a4fc30729b81156b2f5424981805577277470d7ec4e3412202cb5058c36063b8558996ea8e54f1af5cecc471f8615631b5ec9cfbe39536c9622c80d00825daeac9948d40ec2ae5a93e635d34f4e591a8254d6590d1783e680380cbd1b550da835041bac3d5498528348996c637bfa9f42634e2c124a0b637e92922b1e7501e86849b5e4ecfa9b14192c35632818f0f551192d6ff453aa90abfb2b71d7efaf2bf23ad6c006389a7087ed45020f1adb79a7245f335175010275080544eb46b31e0dc7c3fc252adc811ddc8cf6d69aa9bd8745c6731a351f67269be691f57e4f181dd523e5a142952ba59fca2c06380fd1b2d89e8f07dae575b79ffa39078c0abf060fb750748acf5be1ec4e97e094d26e851a533524665d472077d72b510f8db3492c851862b9acfb258eab5e32d40b52aa87ec36c16877be8c66de8a9f21d9122dd90e7e92c819858b3df5ec88cd32ff7c99b04ece350b184f7d92f7e1a89677eeaad49dfd48d2e56106329fe4ce064b3a99dffc701839fc2af96b8030a410236a0f063c1a4ea55dc7c7f9ec5b17b596865bd1747a5090ce87972055348315cb18630a21d80ffc15d17d295dc472d5b712d4c3ee8e90fcbc75cf27e7b1d4d6e5be86a88248ea3e273edc9912ce29ae3b876b28f114323dd8062590bebaded7e43838d5ff46b3d3464ace654977cad9a777c00d37cb632fabd2a11e9301317e3e9ed1956a2aca8c3b87853bebd79a514fe708b27cae474ade323b13fb9ebb9743899c20aca37cd87de4d32d11ef3da3d47a6827514a763678cf6e3d28fc4a3753baa11e8fe752ab6532590a755d7187eeb94fd2e82f9e3b30a2b5be6c738ddb0978d050def03be989d7f89064a65566529314aba20f39fa3bb72a1d3d49722ae34ed969e2ca3db106fb38d620476e4dbfc686391bd2638e88bff9475d5fb58433510a2ca333451249a275cd59131a7b43f898a65dd457e1c989d896c068d915739c0704e8e6b2498a09801a8a1d9a7305738a5783c8424e23cbd2a61e6181f16b814e0c0cc0290e34af432c7877f3a546ca70ba314b757bc7b57ac0e2794899d9faabb19e698995f9dfdb33acd2bbf2f493ece285b9c9e4272b4c61d50840aeab68d627f9d61a482a99569aab3c30a518597f26f3d95125bebe031906f352ed1ea108b0c67b063891d0551ad0a07ee911901007ca6a56b1e9bb61e2e89243f559c04a3e376a1088ab6834cb498d2f79fae198d6d3e75a81a6bae6ef8455c483108d2b440459bba3c95adb01c4e2440dd966063ae51678a6e4ff0d131cef01db872105e04894903bfa72b9029b925b38abc6b2dc84923ccd50ceac20d23c6bf93c949391d3a71a036c2224b7253df1c319c9f23a8ef84e3fc7473a2b115345fb04f682beb4af74ea60dd165381db1c8c003dc89682d8ad1551883f461691007c3155cf559ccf8344904fa580c31df67f8321e6092dc9ecc52862df2e63acda0f9699d9a2f6c74befd4087ab022d3de35a628a4789584a42c47b018bdff602a4f6606e9b850517f8f2c4f881481bd958861a964dfb9eaf3a5c02141303112e133d217500ea9e3f045f3218beafe994277219de2b7fe3117cf29c75cc8569eaca177651167754fc0665664c756075efdaa1747f5768245d42bfa1761a96e52563935bf52e21870424d4ae586535d356a703a95d694fe711de13bbe284d49d349ebce1ceb62dcca9bcd4f86f96a9587f0a2d81e752e101196d0b103634d8cfa7008669ad65d30ab3d020fb8645a9f43496a95f0de1391639050b962b79cfd41e4821747ef2b6a3b8dc5e38cc1c7c7fe52bfe986a792cd7446e8d8e1c2cb331a66d501d2508834ce37fd552d800192e4db5d591baf2495f823733628ece06c9d4218ddb077361a118308b2797fd380e1a82bb2ce3bc1780e2d19bf7af27af2b4b84c597d5d1597b6c0d83051749c382d038359310010dfb43f8e378e8dc32ee5c74c0156349d3617ebc3ec860dec0d6bcaa4b2c62bebfc4177b7a9fb53c56a3cada84bbc72d15494495667e2cae1afe37308f968518daa9cb5fe99a4a295d12cf2f0ad4ec0a1a7d3c9adfd47019a395f011553d44ea60750a2923f0c0f7d3688a619ac082bff7e41edf222a52394b5c5c41e8419e78c941150522cb518a5c4df18330cde3aab95c80b0082d50aaf09e566319c03509308cf6281bed16733d04b2f5545e98762938587265030533bb706ff2c384b85a3e4ce9014f3c6a3983e09f4bb833e3252f41e352af0315f566abbd6d7194c4ef145fbca686b6cf72d3b2631c69335611152866038d24273327d2aa498e9d9e432a95acacd225a45312ad1ae480c49a7ad50d1e388aeb11d9ca2e394dd31b764159716eee23d8ed8524c1d97dee977788fa7489c163d63be9429427d77f9bcf028e934be357fd6af7bb67582d53c945c048522735ac54c07fd591eaf8ab7367799fff8a17331edfd487a9988468a30b85ad22bdf6fc891b17cb93616734b4b47fc731962de4a2c8227f598d7770f3c7c631bb7ffd48b879ea27ea5bc00baba788cdde3edff4be0c5e3950e31edb12013b336531bce2bda7d8e8c362111fa3b4832c101c95148c320197198b4855e8f1c2ef58abe4ce459335315732c74752681f2eb1dffb4e109010ae3dfa0b98ac81ced0f62ffadf626e43ada146d77142b3ff0843860aa84f375e41cdc513487fc10dc4f1dfabc0a0cd17d637146012cee430780e24cf43cc2337b96fc1db9f25e20ca98f92cc20fdf81dac383bbed508400229372b2df2f39f99cd4f5d3c2e88cbb3dada713a4a6cdcdca68a1e61a7c13ef69a62dfb53617576497e464301ae63fcb2957164fca965498a9a073428a133e8f8698925379b00fb701a904b074c200d5f2e96730143da60aa14eae6980a928800f403fc0940883930065c9498255fe6709cc8a985e850e6253cfb51b84ff6aa53d5e0130f418d1697a63d52bc7b80db26c6fcfd78243ebbf281560453f81a6143d6172e120b6302e551cf94733ffb58b4179cc78036b88fc8f0997082634dcc700ed69a152ee36cc374f203cb215eff81f57b022a5740a39062eca83f7bec92949f0dd1753d279ffb8f11b125bc8a5a8a5278a52354ef5001ea79c0d28690f96c65b47d771c5ce294d0944a596300958ebee60c880f6158a6512818257062373107ef36a7cb41ac1d5d96f74b40393b577cec806a6f41df909e990a6cc3255fe32c11466eac433c2bdcbea661f60c646eeb51fcdf6a741e9eb013f16612dc396736092aed94416f899be9ad9d6e223c5011872ce9a80691cb8f7409c8343a1e4eeb77432369ef813b879a9576c61d9efefc4bf3650fd93e38cb86911d823970085f1916a265cb720904743217f37ff42800f540faf93570c9873b095949b8f31b8445cfe33b7bb83324cc8e60209256101352da75950092c53d9f7aca91e30709ad95ba23dc0f83f626d568460ef9c52164ad166bf48889f497c99bfb499bc09865ea9a33e1fe7dd2105c3a97b9d5dd5d0e249c212020c989a061755fd466b2b7625575a389a23e68d48f119f1acb5ae2776ce24293c61879809276dcfe30424b1629abea3b799c37da0c6261a94cdfe444ad9e297664961b132045001e2076df7758ed656444e125163bbb72924b0d49afba260272264260a7473a564515c9a4ac8d1ef8598381c04165115b1632381fe72738b39897ec0eee9d64c06b018d8038234298d69b31ee521ba42db87ca9a4660c25334bc133d9502e9eef5cbfec38af634f50819877888e7f6132381d1888d03f76463efaff6e4f3295e3c5dac81858aaabb64620bbf597c209c6216f13355c04b314357d8f1802faf78899afaece5c8ecf3e19c473063bf82746966534112d0947d9430fa5a296cc61b86fbfa4940ec19063ede09ca83939eb489ccaf8ab47e18a3eecffb52778c3ef418e5375dd7c71274f4ffb0fe8f0f441246e849e102cdd2dac36c763de381b772ff7bc920f416a84558bea59bb99c932895afedfd5f461975c0567714217724c8e8e03fc9337da30299389b5b6368e5479837204ed68311eb71b362660d72ac10fa460a7631d73c2359837c3a95efbbacacb8336cda9ef3cf9f880aeb4c2c47626ab5d142a4c6bf42a24c3d00ec1d19a57abb6d9a4803c23f08aed40d7743fb6840a825118e1618a27f56c94904b975d74a4dce57dabdc013b56c6d8af33aec402249c70256e73c980063b02a5d3936f063aa58c2b9367f85853301fa2a6bbd8cacd2de4161e114b8d4c95fe3863f5a5d8db920b6c20379ef5a0eb360d4d4e371b5e86b7632e7a116bd6f81e3a7104cbce1f2d3ec61c2316226e9111bfa2546329a90d3fc7a35126f072fbcba0ee1158c8642ab3b2122bacbe3786209298cf079ab5a44b0d5222d883a0c4245c47c830f28cd51bc8cd73a59cadc2f421a3cab5a08d00be716cf711756ce787726c8b259504d98ec5994fea73cff7a8731864180ba7c7da55d93325f74b06d272e9a0423e211829763502206cdb0c4b863e7cb10648e09df740e33bf150d936e3886c312f32a716348e857ed13f0409497d3c65dfdc5923115e896bfc1e83a33c45afe727a84c32787cb023beec6d538dde215d6f9b38df846cdb8e13bdc5e8b3b67d5a9ba66bcb34433470dfb7554e9b481b6045ba20f9b66101cb3afaf94df8689c9a4768de4041bc737eb86069f6363316923bb5720fb3a03b6ac58c8a04642c640d575d79d7f6a5fbee06def0e06a57ef492dffd81c4e07a62068457db6fbebfa71839c44f2cad504e5de86bec83942f7a1a82b7ae3031b71311950e76e5ef3e6c722b3233eacd10f2a7440e0140b098d90b7a5b9642a6a21e96278e4158c805e27288e8bd44535b89011c19a841e77b929d5e2d400e193e9e179ee2857774d83ca34e72f7b9b02039944bae88aa50e3cc48c8df65ca3b04e948c8f555f68628dcbc9b75e0ee4c8f1681aef631646a079c301d1668dc784110b7b11609b804d3b37fb9814a345a86eb7b8a731bb1f134eb8f0d99544921f4781444052e64151748f34906421437e22e259e49ebd2f7235258e719826996791afb3e0e7034669d00bb6156f83205c7f81a6308bb3f8a7faecdbea43b02e328796067e75c70ed5f3405057f02c460a1587ac79e5dc75c137d2c4751126fa8201c577ee26705dc71047245064083f82c01647388172754e033bc95f30bc2d85ca025f4d18e5c42c286cf1c741083cc194cbf6eb57245ddc56e12a7eb33e5845a5a5d4857f8aa7d60e9e716d8dbfeb47f279be23f5cd4a501b6d21041b9a03d0958806b912f43e9fa42e8c5dab16ee2dd69c38fc60600b065ddbc942b8c868c68ca9473017430f2adf14298b7c02f380fa6d6bc1d0e10a9a1c6857f3fa2557b9a70530d97fb470e7691fd82be58df10cd38b42350969f9469d2345cc06a1c0a29109ea5f4830a0b3139344c95ea9f6770a43e00cb4854d4764c3265c6be6301f6c569098cb1b3a5cdc6f3f5b2f3c27b88338f2d3b9f8b09b1e3142b9a924cf9ec2708271ea3459100365d07c4439e231c800f9030f5ad0c9d91e94201030cf0ba087b64b4571c9771a2962ea1a54c1775d79dd3d5ba05066702cf335eb05245b61a808a29543471c135f61d37160e9b98e5ffb569fc103781683391350c203e5f0b1dcffab69db88b06d81c1fce852ccc18fcc66f07305738c7f624fc027ebecfa8cd032984560427091555c91c4aa8b0335c342de041af615db23058797b038c23eaf8415f6a48f2696f128661c5bfc5930309190108f0a2d6bb97be9ce01a476ee99708db20608dce841b8919ab1dc0f2bd73daf83404fe50b25588a0510f10ff7db322cdaf17f91ab6247cb27a2a3eb24b676d3b1dc8f06fbba6ff920916f53e8fe20c645f06536dd4fc64c13ee9b1b2e27401c07940a518ad10d6eef2bd14b2d63f35a417d484056841e8150d0b9545ef2daeb6695012cd1ebad159b937b18a475a612ab80a7c531ac7fccdbe4bf8d4bafbec5b914b4a1286338c7cfd1ccbba85f2c748d358a63077f1ecc1b6e0fe6d1197b33e20390e678385688618988764dffe97f706681afc597f1f8f6f04eb044406ba739e33e448586e59e5704ee53d9866f0267154a977656cd023a1874ccc5b143bd074ac76ab8201c5e78c0fe6fae2386f33b7790413bf0755a11e6f2f267e93f245e217a0f1209fd7b4a01cb89fd7beca1c0afd3673dc2b3f61e9fe3ef6d4d320ac1628452229f4eabdfd71aa5990111a18f83d3f67d7532f7be580a4d9d5a9044e0f1e0cecf0467488dd28cb9944af00d86b24d47490b259b4cb43a494272fff05005572342cd8e72b3770d3cde189c2192c9376d7020a9c77c49bab65830f6d65cdbee37f27dfefba5a1bcf989e2f856b3d0b67deb92f87f61b00d40735e5ea8e60554f003b501144aa536084574b1f03fd3704e06901f8c49d5828ca26630a860a74661089c55a6bccdcd3de9fed6a906fed65b5a397dadcc7406f1eaf37bf2efc8a0107dc746df2b46fbedd5ad68f451240f11326e26c27328ba05f4c948e732bc17e42b854e1c03fb822cd04c3d7e67029899a74e04532f240b1baa2fc53deeed738a926c6c3a65141411a88ee62dee24b00a1bd4ce65527b50285870e6c1d87a551e41abc6c971bf74e71131d9de29733b9b84830e47ff6ad96765308a53dac240696b9771ac79302eb6f6f8441d47d66efb03b942ad03bdea9dc1d4be8f35d7b67a98b914c867dde856547dea0472e4d0320ca200201e83850f0c4066d034c09231b1a84be9b4d253737f0bc25a16284e1164dbdd8dd71eed97d0f20df9e90fdc5a390611538879a6b589d16bfb9f338cef570c2a1b7fedaec4c078b1666cf3a7d5854cc2169f0d0a11e061f72366a146e118ea7cb6ac7121347bc636ca1a6c2777c6ca527d17349446fab88a8ff79b7642313e9db18dc842bdab66806398de8acff61c9c4f5309593bad0955e67c726019c242a6be1c5de0c207f0aa31f3640cab0a7236a05f7ef9d84068318154027286398b04f0e2bc9ab66f5fcdb00e27a58b29c9a2d4ca85a42c445533527f6b5b9a47eb0f1e61691b1441dbc16c2e96d0c42e98c8bc6540e315c2540f9d104b9233397a0f516ebc81e59020e6c104240683d96a781e6cf95e3634d490f7f32c5293915901a1b68126040570baa10ffb12e6f12c1e9c3bae2d19265a2fdf3520a43f164176d1b6c1a5de16df5abf83ac37901148ce428ce960bc418b29fe004059e72deaaf116801392c5442e8c02dd6be141b09b780aa9fa3515338072cdf5229df66d59a676aee084fb4aade1bcc9cf736b2ed4bd06e6df981d816d2f65ef709c452597d94dec8e3b2d92b74eb5c47d4d2e0ac4686ea933610fb3e6834dd67ba405c79e97ff7370f1b993e9e45e8319d05b3c70a488b31c2318a6203643148fcaae151784df7657ae52cf2631c8b48b4fe15743b91582ee8e0ccf6effd9d2e25124a88051e53dbc16bf0622e845e372ec8f5d40ac9d620599231bed754eb26e797048e5a5aa43608b8008502bc3e6c7230c4e41b67d687856989c0853a934b1f211e3c0a666bdfbbbd7b6033036262cc66168df3d15920d61093f94fddafcb17f290c9aaac22d2824c0d1e400bcc413063515d93d2588e9b4fcfe3ea19233364a1e212d00d93d228c23f8a0303c265df134ef37be34a84f24aa449a28f05f618004bc169b3b5a056843b627970d82b63a8f8bde838e9f2606f7267dbcf2f4e15255b09cfbd1b348209a9652761bb43051843100b06f3a55bce47afb2a3ad4bb0059249a9e2192ef53cb503b6265b53162767bf1150348ec6ed237899ddaf0f9462124a6a9bc324ed4c42ee1f0b9badd9c3439f46886de9bacf6fad3bdac06da6d3f5713eeb8f06ad730f54e3aeb3b9faad3c680857049942afec439710ad8969e8470b7e4e5038f033fc2662d29dd4451abd7a84eee069843eef87c858fa62b34e5dd5b512186b8a2b62a90a6b4abae951726a607916fe76491d735b69a4a2a25b9f346d8863eb4d8918fe536100eef4701a047fbf26d677d1441ba6667e1341ed52a29b14cf46a83e990f5417b1a82c41971cee57b3d8f4669322a4603d889e683312845c4b8a8602898deaee1a0f00ab440767b89c6195c674ac4188e1770067ae12bf3d9852d5c4457f29dfcec9a4d8ca341c0121cc87233bd5fab097edc7d4645c9be0fe9795c2d89f49d22c4d5dc20fd849eb642a92b47243bd53f934d7b5904b42612356441a85e43fac107dce5153eb38956fc622485f43b9b3f378277689e87eb0ab7b44731c019d23ba7622d2929307e4bded2329456f72d831307b3fbaa65b964725e56d60d37baa52646828f23c404a849137710d8621d0e878272a2a816946fdc04ee05d028112eb161ded3be0841280d32c5d80c3b88950c6468d71b617264a96de2172e2ea3b91b9df33d1341082cc32158a263c5c5c73e8c9a1a1a22ade60e4370530bf8dd6cd65564ccc5cc41e06e5575c2a2650f418dc7a965afa8c0847631603d66da2b9a46f17e2e14411c8a2d12ecb7652c9610e252831d168ecf0296a37170114fbd556ae1d4f3708755bd56ea359ba4b7292c9e3b5e8dd8033c2110556fa18e59d0bd5d6736487b743bf9053926cfe4132e360346ee76e9ca81c93ff8e0e78f0a0026d827f65f5ecf89e3c000140ce3c2a451d7916c9eab76972e12c7ede0454f9b9b038a028be89a00fb184720aa0672cb9e6d96f6abf063ca83eb8b538f7f5a9f666b4839e2baf1213820cfac531a5289f8a6d0b893e5716a9b1c117fe44713cf8467129c5493b909e61b1e2b0ec7971db8b583d693ad10df2fd3dcedd6ef0ea8818ca393c9cf78b174165a0e9bfb2800ac22aab4f25cec0a30f5810a59968420b4127e1a019f0903160d451698818d541fdfaa810d1a5e4f92adc9d03b4ca50976c017e3a9d2585c4c8a05a6f6ba364565d59008b995575731419f84ebbe3b26123f7b0bbf6855833ff71d3ab26a6567c63fe9447ee3436ff238d04c8bdd3d38c4564684b62bba321f217ed5b721cebbfb03a8d0f01e8c21b2610703f98225865c02974f622276f1112d4ba112302137d2515540dbb99f70978c249afd69555d5a6bfe106c5988c81574cb68f0948bf76557eea94d87a85b10e0144fbce0cc3156ebd321ebeb5c1e5ed3532495d61b73991f4a360e1cf4c70a0eb6a687efabb3e26e891901b28c53758d099e3f9a2683a2c8c05c4551708f1d1900ca9757688a1484e0e100c6075873c303c036920b23686e0b76f0d9c56d0b40ce63b1a447f83d9fcc7084e3d0087f1a91d50cfbed6fbdcc4051c4f71c9d1533ddd3e9e0cfb5c6f4af6247324810110098e4dee18036c97c0e17e879ea164d9b566222099ecbfc04c1a33c2b49d3a149e2a30ee51698c425d722968867a797067c9631a158352db607b145c3058ffc6aa3171678adebfe43aaee37d7ab20c9205fe7cc4f40d56305c514d3a9985d4faa6be715cd5cbd7fbd8bde53e76eb87f3dacdd7b28aa85263123eb976b6df6054a43bc0d900c0ea094939b24c9b8b17cb8dd13a05ecfa503aa3b197c7db2abfda649f6c238410b209d97bcbbd03f90d7f0def0d27dd9855687ce4863133f6345452b7de11206803188c60846c53a7398579a0ae0e1a5789197789026002dc9881b8b4e59264dc96015c1b2cf7468c8b63de1c02b84cbc0451030101c0318c3dd96f48ca25dc043d5d96c965852acfde1ecc0f5a1c01021590c0096fc82a18b53153f63edc985f5a5cfa435c50aabc1f23d6b82e6f8c0197bc03c6571e1ec6fbdcca35dd46b65fb9a14b5eb9f460e6ca8571d30d2de6e192ed611c0656b9f89a1a94bf7725b2c8bbdc216e9cd48ae0db9cc888e8badbdb6d5be9f6067808bad8db935a6cfc46a3466e8fa351a1dbe76894caed27d028d24f6ecf44acf1b9bd9da9035c88dbbbcc5410d931e092778c3ce55cca5531995cac355d0cb86494478f8894949bae725db245b954b9e9862e5945e58e1ce58636b2ca479e724315ccc3258b7c24e58e9cb32f5dc584c3986cbabd3f98b0c226db989aa893eda34784355d0cc49dbcc33ee592c552857127aba45c05e571884771556c1aa128ab3cfcb24a6c1aa64771d51058e5261cdaac12b3e92a266c5f52b9a5db5b7aca0d51308fb8934dd84783f625cc4483f627974783f626b7478396849768d052d2e8b6d818b9377034682f72733468ffdd0934680fba3a1ab4ffdc1f91c5fe00d7f6c95e88fb3ed907715d6a18e0c63eb9dcd827e9c178378c59e51e59ae3db25c3f298fd87384d502072bc8f53663f4a54117aa3110ee643b827cacd1ef2cf4e0ca7d249a8bdc21cdf5613d86c48d46d55aef0d1b31dbb85191e81ad22c91b0b1fab01360610a6dc8fd98eda109fad1d017481e7b7bf860e22584a7c7c0d343e2f1e2eb22778b288d524a59e76fcca48f065ff865b95ae5e10baded56cd935d8a2486d5aa655bc665f41c7e96552ca335b359562bbd32bba84cac13cb3aeac14c53c6308ccbb2495f5f15055836b3acce63c7b05a7188d55ab1966fd62ccb322cd71b5f227a51febe0fb3d8edf65a37fc1b78c8309c612c3b867d2252cf69ab0a5caf9d213c5ef47ca1bd266bb6e6cc6b87270425e815b8707256abd58ac6756353e372b9e616a66ba462e7b2cfad8b57ac31072c5fb2f5d92f4727878e0e4d0d0d0d65ad5aabcffbf2f3c92291ba4ff939e79c736e31e79cf3355b2707a7c7874bbe6c5c37ab9916abca1a80a00cd204b9d2a1043434343425a803866198cbe57255bacd3929e8b21512f93e1d48ca7bb6f3ba8d66d91d3e215e5c6cc4b2cf1c33e5a2e3e2e242eb67463fb5b806175c80d2d0d0d0a821d717d0155dd1aad1cff97abd5e2708681c18a994cad643d9a22b1a1a9a95f6f9c11edeb44fcdc7883667e414add66b4ed96a7d972d295bb245eb27fd94f5937ed64797cbe5aa9f927e4a2965fda49f58966599ac9f18fda45815e91f8630795cdec7f5bb58d239d979de9d94666fd5acd5abef59b19671d6faa9f7e89c333569b229a40bc78583838383a373334f3d249b9999952b9bad2e3a35695a2c4aa3f30d691a2f649eade91ad2a2a13495c60e9f8cd5455d996bd215bc41a359270729fa46d36eb41bed6666b467b26c269bc966b429b479c5766dc47ecd686b355a7b69f6f923d3cfc9c3f5470e72c8e43065d7a774366e1a4496381c61697c0d17672a08768be1a0f503342666673f9e2666cf6540ee41c63e8a201970c93d66a6d7a2bc46440c55cd5929a5734e4a699db5b1204e74a62f8d554aa7c8a4e81e995d741e6c270bd58bc802562c874eb9ea9e9e9e9efa493f638dca61dbc37fcd9a214ab591d01c0975dc47ced048955f903a348f8c5c74a9d374de91db3dddd379864644228d7aa92375e68aceda35f3b073a0adeb5c65cd3e91eee99e49830cb31b476b070a8d8846a412129393526db55ab565536daacb55ddc0c35373eaab0ea93c347f484276582c16892b5da9c25ef3b56daf0fc795b60ff7c9c931a13fa1973a947e72db27e77db86d091bf1445f7275c4133de6a27467266f1cb77d8a2877cc86dabce4edf39b7c6db20b168b35736db55aa4114419fd11d870a1d3200d8f4dceeb85e5b044e2897be99ac413772c87fb9c1b9d93c3b247209ee8492e05e2891ecbc9e867f619a530e945d7259ee847f7259ee8319b493f239e5bf649e9bb4b23480fbaa208d2872e299e6866ca6234d7a15d4c27c314e322e7f5b2b5ab2d9b99c272725c3385b95c2ecc669e5a0681d148193d53183624bf7a3e0c836649e4d84b8447e421b623f239412773b288e46046802e7540a087f22502fa9c5f89c807fa087412087381420c07f439419ff3a2fb78023d744740980de8200cf48a26281700184d63ac90cb486afd565f79664aea541ea983751cb6cfd96d2612ea624d415314d4a16655bef38e00b1baa7e9a598106ca741ecb565f7734311ace7baa75124113ce92f4a15e89e992289271f72fd0f11f87cd6012cb25489c996221b8dc24a485c6274cd002b03f692321a9372a4c6482314c9f5d80b7bd13a831c4e2ce64df74c96c99d21121a1b0754151dbe3a72b178aa1f5d924fae17659e11d4e4d688a77ad2cd22d74f21d722641a001202d42062744f4438004964ba8542b99e58201bf1e56c7302ab9f1ee808d6db731aa6e1f43f0f8874b93e6a23e2019135352259c65e3a1837e2c160af5234585b21864d32d496ad2d1e997e524c23ab5158dd401e0cf6f9c82a6ac89334924624ba2455f34102997e8e78467c596a2323593fe9a7c8831165b235f280489664d13c2ac176620dfaca24d7c788c403c2447d564feb45f523b57ed24fcf08519624587b116b74919bda18b95e5c3a4a3c2039a24e8949f582ea60393288daca69217940c010ac11ac0f5d2d9eaac86b4b8e6417b94532b1da37eabc1bdd3387eec9bcf8ba6624a1fa7922c941ce9a95740fedbe792dc983a118bb890753a7fda4f625bbc04e4e3c184c08c751d34b08b683858eedbc5e4242b7341ffa08965df4a96383d84bc8cec888a83bf1beafe6920743311626454b94676b9eeac55a0d767d88b1a4a8ad99923a29dd87223d4c08b683bd017bd513ef084bb1d769454413bb08c33040f2aca5a689825d20a1d750fd0cdd8ea7fa142ec3543c188aa5ce7c28758ebd414042c2b04967b6fa3a070cb22ca3f5033468a67120a334c36aa5b43eaaba0311c6644a29566ba594528a6593091ccf4c6d9fab99e23eb399ea3e136c1eb9aa2f1d413ff374810ca2fe40caa0e2a40689c3272f57abdc980d727fced879fa221cbe692285240978e73077a9e230ab53796751950cf728acaafb76a5aa3d1c54e5e128a000a9b8b7aaa6bb108840605c17789069121108ecd283c99a90b587980db890b1cf1e647a8bb14619db91a911a34c5b153d24b2d3ec584cd6fd976dac062919fb28ae0a321fb31df3d388790c53217cf3d3ce1b31e58b8b8d9ad8a4b9413a9de84a29adef617346fb927a0c98b9624e346d4c3612b8b812623918f6b983ef16f561b395310cc3ba6398c7a4c9f39f45c3371fda6edeccec66c3373739247578b278be6c62b7dd876513c33c264d27a10443264da60d4e1c732a09b8b8124adba888f2d90ef448dad1893146510c57f28d96d845d0edd1a766826ad847a326467d50f20411ec32a5d807135b7cf361e4e9d1604b56a3e4aac11344948422823d33e8ca40c104e8df2514f173e5140dce340dae9394d64a6ba5b5525a25bdd65e261aec1ba5ec065d39459f6a70ef4b11c810c41addfb72156b78ff60d97ac347bb9e5e1959eabbbbd58ce688a22c9536e81d6199e8e183f67c7b471400065ba0816a9fd730c5181065af7f83bee4fa4929a5b5ab3373c3373fa7b70517736a322d499c0179f3851647b82237eed15f965f0097a313d6b0c50c658c31c6283fa36462bec69e571b84bca49006775e435e3967e2a00753f4400a1e709131160fb6c0a490aab8126236594a6913c36937a4addde9853eb2d4620c6f1a6c9bb6891ff9429f8c7c5591230e5b70d892b99819a187a7075b6445f0c10c2b1555415c61ad3df98b46d1c064302972bff2646cf89ae8f1e50a062f4419fdf056d0e4beb162266a3714550f06c3b2cc5a4bab57448db2678cb58b9157d3c05633633294453bac63613259575b8b18edfaa97fe9d0e79ddbba7a67ce32af88ba794560185644d75abdae6e4af8ea6d2d020cbd7aee53718f76fb7ee59169171542c89ab4b169509e93b86f7a1ac56179935d9101e1cbce6538f83ef764484b383cef31aaef31aae889c406252e1111b3c8a28b5212a0cf418faa5212df135ed6c393971e4cbcbc3b222e19e165792fcbc71d1a2e192135ec44e71df1318b2cbac8f2d2cbf1c62cb2a8c9f232e1e5ecdf2d25e13df1816e29892740d1cb81d59470802e7211fc0363ac0fcec9f1d1cc13d6c2d8cac36d93e5807e32d185ad4af531dbcc94f74fdb7ca08fa77dd5d420a96d6c7a08efb26dfa467ab37b99d8e3c5c0a4c93be4b173114750ce74f0856da3d3b3d9992cafb58d879b679ea4e5ee8df3dd9555c82e1aecb0c50743a40f846440e6f8e3952bcd6dc2be884a44cd1173dc86a980a99715f398349962212426d3607710fa0837dd04574ba1bb1b63616cd560cc0468f0852d61dbc82b1a95872a72bfafe8c6220b5f286d62d8344a6e47f8624f6e82e6b6c9d4f0852de08c4efdfd2c0d1f6693e2051757145085219993b7664ecedc593a010f39393ae10e5be419393ae10e2ec81cd6c9887d3220f7904bbe97c9c9aebb78352a6a41858c02aab0d328892317389928ae9aa7597cb193c517af2c0d1f1333b66694d2396de8b46954e8326f76e615d38607e5f9e6e95d2293ddb226c126630fa78d03a62ac33ee4d0436bed9bcc6adba6d9acbe3224501ecaa3c99eb46299d536aeeb3ccf839991ba68bd1cd2287b894f6b286ba62cb5a1aed68b44692c89ae7848af4f8726c7dab87263abc96abd2c4faf68685e315559afc7134677e88e6be706870607cc9169a6b128a69a0c4cc5da4a5bd12be2a96291ab16f6655ff67545ae1fd86273b95c2e3ac510cdd2581a4b6369a6173fa4b076655776750a3931073b97e1e0d36e6f6f0987b58f5169b78443b3dafcdcb46f8faa92c5dee7e69c73d67af93af3d46e54d95212dc13dd764b493ca1ddc6ed1bfe01dae6e9bae51c2ec59c7fa211dcc8a1a3729b663b878e8a3b6ed3309d377a08fb3e8e1c37660e2bbfd250c085dddd2db7cccdaeb5ccd16e66ae76d4ca79fb316299cb3aac66ce76999d99db3aad3311fd4db3dc474696f846358e99927e012413c555d8b34f9ba661595f38658e0fa78d9c37b25179dacc2be6cd4b1bd159ce80dcc3ccd113892ca1c8d22fc216b947e7d9449ef88b2cdd39d3c187c90ffb44d109ab2b26163bc06ae66a95c36fb2581387b3157e389c3339fcbea9c23046334fcdf385580e17754897c51e84806c9e8d2deddc9daabb4e31212fed1c5ec72ebd11c3acad757e600c2d8a8f3ebb614cce4cb7614bb6989e529e06318ed24add707a314ba91ba40c7aeb83f260b55aecb33ea314939f8db52f93fb4b3bc18b19f9860f3bd7e1302677daadf5fed23b9a0602cd729ad5300cf3f132394eee3488dd5a8ed3ece7c5ae5d2e62ab693774c9da5f1ecac81888c51413311913c26504df12a18b102232b2fd078a1faf7b9c293a0d90ed6d42e650d67c1fce17715c2eb30c1c82a75f924987371c79b6cb98dab6f8cdcf5015526841c61e5d8e0855210516d08ce106fb96664e7a45d86cb1ac892ccd0369838c1d0b3352e06902eb0841c8adc97c5d83507ce157c25d8fe12262a66f7c12c524d1ca274360d86832cddd79b2fc5a3a2d8aaf499d4784cdd67b226f1e0e7f444b9291b877a01771486df8995662e40d735e478770dc76cff33ccff3684bf670c863c6115beebc22423fb9e9e4f1316613936fdbc8353dbbd8c888a484f41851a5b7d4b2cedb702883d3b22ccb7a687787f42e72cef334ef9acabb4c44a4d32e511a208f82294fee5ec2a18c17096fc70209de1ee3086f2378dbba67f72db97b8677689759cc0f8c7e91434c1b92512f300d3b7503956f395d138ebbe4ce693338aa9d935778e178c185851b29d8342173d20029c96dc7324cb7ee1e56c13d3a6b1d2e951c3ba76329a87efe2fd22119e5c921bd20af88ed1dded17df4cff7e350860a0ec19770482275c7bcec24126f9897e150761e75437789a91bbe4f0551121cb664ec96ab347974df9568181d32724d17b9299791435b2d89da986966ea20ca431919907bc8a62f8137141cca00c11d9d0eeb7cb47b0f79cc68c99bf7c1de27d61879d8923720f2e6864f14d275ff7c7b483fa56ebbf5ee07973e5267ca9001feb3ed3debce955ebae95aaf88ee3bace999d7802e77a953deb68760de1e5ecb9b77141cb66437c8203aef260ef36038efdadb7d9f8f6946de5cf22644de4a3692ad6e1b1751276fdb498d6a893546be1d885883f4ed91baa1290fe5b1d6465c3a629e7b11f31c8ec9de0de98cbc791fefd2dcdd98bc7d3075839491bd74439a4d6eef092635189f831bb9747b77ef3bdcf6789a65a93353a46fc32ee0c8c548578b2cfd915b7348ca9bd775d9bd4bcfdd9007298b9e7dc483a19d45224cb3261ab933d30be47e17eb8cdcce747b7df3d4251e11f65cc76d3774c9db37d0eb3ace2342bb774931b09277904e57f2762e72265df48ae830e9b1532b43dc6bf7e1f326b23d7a9f37726f0be1ef6e56c3a1296f5f911eccb54bb188c74a0eed88ac91556825f842a9d3de3754c8c32577dfb6b691a5bfe1f0793bcd5ed865cfbb766ffbded8192635b8bd417befd64b7b6fc33d680675f33e3bd7d203e197fee8c606291251e4c3f1d26c2deb9b6fb0b73bcf6d98b39f9573b73305e31c0ebbed9f77c4963d4a63dee8b77f3c986dc6c3da3bef9cc779e7babfcc4ebb3b400741f6a2e76d2fd31bd1be793bb08344ee812e82c3f6369111bc9de3b0ce3b76d0bd7f39e60708f2f60e7b5df844ce5e28bdc861f61ebdc33b08f2d661e7b8ed86346f975a770dcb219cf74eee68d8437b8ec3a1dce17eb22581e21e1d5a4e84e31ebd23b6abdd506e00f001d461d8375c026d3834c2fbf6edd26b80f7edd2667bb76da1e81917f28a10e96e2839111ee13a8e1bf93aee20eee3c158ed6ed7de6ef332ecd98bdccf7db82b07c085e16169b36d98a7dddb3c0fc33bba73d764196410618f3ed992f06d0f370eefe86ebf3dec21bbcdf32e3d0670db35dc83e6ee1b2e61cf0eda9efdc4bb06c2db11e669e5f6a0790be515393be715e17d0777ed9bd7802e7b1e0e351093b76bf6d246f360ec766dd719c1c5fb2dce6f9bccdbf69d9c7519907bc8de3d5c2a39e07ee549e0c3f803a24a6604f72b38ced308f061e098cdbbe1f6eedaeec664ee4a9bbcf5a0d9625986acc6c7e37b6fb7549a082870b1bbbbbbbb6f18752e71cc94b2079c8cdd2e2d51c639e79c73b68c315376116494f1f43473209920f2aac715d58d11db68f046fc8cdf3131120d76c4b931a7bca192361a25e796c587f3e6064d153db9bb316c03891ba1a479c92a3a6565172e5cb46c016a712caec8ddd9ce946c79dcc901b88b8c873d031fde19c6f0ce8c4f1c3e6c298078c42169a5250ebfd343f945eedb117ce16cede4de99a7fe4eefb4645c131595cb78f48850b98cbfb48cabdce4aa0ce02737b9c9bf46996e7251a30c7093931a15c44d6e6a54016ec2c2711cc77124a5ce7443e992b993dcd04626f1489f88643acac9e8cbb28e4e315b738e1eafe89f8f3ee2c1887874f94373f6f11a357a7f1f91d00808044af9c89dd112035c19dd37e875300ee324251807793027db66baf16bd0e4b44193b3dcae41931be08a1a34791097d4a0c90b704d0d9a1cc6b50d9aa04cae72c3671393ebc353404dd01cce164ad8a366276adee1c37f20c287fff09796717d78cbb532df0efe8c198f59a4b1e461ef502e9bd324a7fc4cfc7881b8e986a4cf0d5bf2e4765e578ecf793040e0f8c91520f061ccb83113a06b2c9d4083f395c598c52c6347f94b677907ca0580720108e0289717e5a71bca7cda8932fa311ec62b9cc8306a91256a44441231161a5fca04a245c6e55d1a15aa717924628d015c9e1e808c25a0000a88055079f46008f0978e31c6183f22c744b07843971c3fb5a453aacb0cb7959143761a95b51ad54d31c335cae4dc9dd11203fc3ca95ce59f1bdac8f22af7a2484cb948ca39d97d2997996427a3aecc2308f88cfc9e913a273f033c7a302e7fe918638c31c618774a9f2fcd7825e89f48e8f22453a33e2fb9fc8a7c8c46915cbea551a2cbcf8835b84b1c9e9c13cd16c90fc0a39a33e894a90f70c13ec99394646c47f244af64e4e6085d1c22df45c2869457ddaf4ff2a24b7a514083f29f3b011d914596e068808f6eccd100aff2a51bca1be09e077382e31743318887641097e65110d8478d6b0097dba34199c24b8466dcad00d7c68d06e509707134289f02448b8cab4483f20390525e01d7a54ff208b8b113705d2c184533c13b619b6ed82c0180d76e3d98007c308f9893c17fbc237ea0610830d84326a179eb2f626e9dce01af13592639f7c31d9d824e41ffe1871f0efa1efae7bd53726724fa68f4d139d39dc7300cc330594da653ac1e6c941335efc82e3f5cc9bbeb78cededd30e21e35c783197e83f39f1ba35bee8c0627c59462de4d230fdb0647175ddae0e823b76b7024ead3e86dcaa37f971e8c08088340d7877ff787ebc30fd7072c048e4ad55bc41af72dc40a3e8c87c7ef9a1ddab77330eeb491e561dcd025c3b884f19709e3e24f1e2e591ec3b818ebb8391aecdfcb23b2f485b836e6a9ffab8af156041fe74496bb6f5c779f77dd39ee7b8e92d30ff111212ef2251a657a3c8f46a53c9e891e8d4279bc8f46a93cfe47ac217afc043ad5f12726a41292fc8280c773f4ca8801979c5d2cbb9c25cf6e6823cf979cde70621e2e79f4929273168a4f454a29a594529e5eeef0c8f957299fa9e6c454d8c43eb1986fbdbc19867d549c82727b34184d372ed160a40d925a6cdcc091e3fe882cf1f9da3ec5bfdcf7291e01d7a54ff143dcd8a7117c802bc49d409fe2db8bf8f3b9dabd1ba3e11e5996d7a48625eb667bf8c288c3d5997a6c62d974c9524a19b6e42c9bd8e967405b092985bc15c1271f590df6f701e3a5fcacd12e5ad0aea42b31626821bbe7a4b4568c7a301ea5a1cc1886434d6463345831bab292e79c933e6b77a1f35bdc345cf195c217d22c15715e6894488432d78985e0117364775aebe9c4de448f18ae56ecf270e111b5c893562ceb62e8236bf2830695532b478e6222759f09e5a5bf4c948b4bf751f4795cb931ec08582c1c926d81812d4eb92a37fcb28a0acd2ab7325f37225242799bbc9567538c6c4926141857b91f93e9a41bb6649348c8c32503e0308e79309f1e3403e053048cafa4c8a0708172439951acb52d3a399f494525e5d18351c143b249489e4083269453941b33f8d2c540ecc93be841f0f4f6d2fb7043994f7646b6a9872ed9e61884641180a4e4440525004084a66984bafd4bac21002db20fffe19cca95190501037879ab0c8025868a8a8a8a4b16111d457494db8b72d3551119d9badb7f88db14d3436762a686c08d3999cf440a56a352de43dc93378ddadeddbb542afddd9dd11203fc3ca5e0d8a00b8b0acb45ae88e5d68309659977c48f1b3898610c7952994f6ac810e25d123347802b3349106f39c0fb2fcd8d6e01cec98fc60c15151515151515159511ed26d3ed35a98cd853db7d2292a95122df5028b7071b9572fb188d3a01dd7e46acd1b964d2bf7320c93ab956e63bb90198f0f1a353a636c005fb647f725d5c5a50ae9591ac9992098292f2067d88e7c07103091b28d7a6dc6e88fbf589f4e25d0574574764b19be98671874678e2e0e9fa4cd79d3877e64416152765d320b42b5ab1e992d365f17459991beef19a0e3657acc96ab5e60cf6a2374690e289a70df6e2b096d3916e2badbb1690784e4932acdc37adac4a3732cd3d48f7e583095247cf08b96a1770dcb92b639bc6d734fa51260876ae7edc95988b347efb4b7f8d8a546b7087a578c39d7661eae70b40eeca7c35a27ccc4dd4dc83e69add180d36a5ef286ea934f8423037166b6c095097185070c1757d6adb776173983241e87cdcd1d1391fd224e474201433c8fd183364e64ec5f72c277dfd4b7f99257d4dc0c867f1e0042716c583381a948ff15accc98163dbac766f3478ed5cbc39ee8d7803478ed71b61b2db0b13f185408c8ad36c56b31650f17a8304c2e1187dea5b0f666250c338a382fd7a9a4604afdcefb2d8caba3929a594524ae367679665599665946641b2639294f221eb176d03d9833d3be6a17c52402adf45ee49962659de92b2ccb22cc912cb9224cbeac3c3510ded5254f270e61f1e8e64f98e35b64b912c43593e5ec61a9ce91287d8e5aac19e06bf68b07b72f7d06cca9e5526658f0c9bf545b3a2cb8bdc5efce003005660e07b95141453e9c484544232128d84443e90fc47de036db7234b6491b7d74616f985bc8f39a7ccb0ec69b0574da31f92e6e9c32ee3190db6c8479ffa31abc117c679c94394e725bd114bfaf9a0313e48901ab8d4270ffa21ff8408faf251f5a33ff1374f11db79024510b47c001757c2af6b0907b63803fd22620657e2bbc7a85632d3cacaca3353a33452a364f735a8f9e0b3c76e716c30c33bb02eced3140217574292286f6294575811a3ac91ae507ece3ad3a8183f716dd59929623cc5347586f585b55567228ec7e28a06fb5dd799daaa12cb9a9387f2b5d5605fced4995b5bb5352f6728b316d29898dc53cec020b2b4e4e44cac018358a31ebb0d64108738795f3621a2be5683dfcc0ce9a3f95a10c1d9594a29a5cc989c9141d81590d2eb05825d20ac8fa42a7d2d88a8101862ab51219d0667660a4422cd80be990c12e9504a41a22d4260d069d4e8a6457ab0db5a3749f049d08d0c62621012620d898d500587d118c41a26c8fd0ed469dddcc1174324a82ce83e244496fe6ea48c26c1178a7a90106b4819c4fcc4dd4acae84bdc8920b27cba3a73256945967ee98e76e6a9650fc9ca8e5ca39e0649560dd2d86038fa22f729c92a7f39245941ee73df0dc905f3157e2f70354a3e93706847af063f1e4c66ca5a232133a48a3372cd546d493c7a6d9264051135ba418d9210c17e483245ee93b4620d392a9d04866ce6a9ff3dc3a19a16ef46a8c60da11af9fd95fee3152147371d8424c4ee8a7c457a7466aa5b6158c39144c261c784afab62f49a2ef8c2d1ab5fdd1f6ec5587186290665be79922238223859644664668ae0cc919bdc385964466466a4f5f94b976ec8d49a4a33d382e20b4137dfcece4e6827e4c1dce044a22ceb4210593c182f63e5a622297226d3604f83fd45ee2320e1668ad14d6eb98722ba55c7ea5ad86844865883be3f2a834c752290a7feb68572c6ba107434f3d4ddaa05ab2c63f2769e241e7531f2c2e80b91a57522cb0abeb0b674a2bc49944a189b19d1d08c6a72275172c0f756ac61f27e26d3a9504d2d6561c613665e7c37f3846373745ed9354f36f666e4aa69d2c8c396bc82981abde6a94627834198dd40b3391ff6b0e2b45cb13e9e1debfa704839159bc17a48aeefa67e3894347286545b79f40a41ee7709727f5690fb248fde676522627938de4e06737a662a67a6503e7ac5eef5ed8c5e3c7225d2334f35339572d3493835a19a50cf49223d9f88c512bdbc9d46d5bb5c37373636211c92684261b70abdc26ee50dc9fd4d1c86445c34e87931a2b312e5e4e8e884a1978aeae41cca95aad1ebc635dac119f1e4dcb878c4669ec291942b55a19a56eecfd8d0dcd4b83c7ce37884c599ae5489f4cc5428b412e91911e9c97d23f49aa78eaa7ab98e9628cdc97d45380df64fae644df9dd742b3972cd54547d2397b5df4722fd20585bb525ead93ed2073ae956362d7bd29d94a49c99a9111e3bd2238adfc95758416b1592d69a4a33d2cd5b5b91650591850591257f5e119c1272cf8032d0cdaae3416dd92f245ff0c587b505029121a23e32ecccd409fe306862d00de806747303daf96e403b37a01dd04eeef7f78a2c3775a6d2d49a6a536f42af1156ac21474a10511d0fe44cb70abdba55e83533d3ad66bad50c1135a357cca887643553316433533137d3157b66662aaaba95a867b41a458ea49b24f8c2902bd66819848c41ac11bb55e9c649bf637535b1060f22aab622d8ea663a9a998aaada02ce2465491e2cfd07ca51f00fd2635477313de50f88aa14fcc386a495872e551555a6873697e4635427b72471130f88aa1bf8870d1ca37a5495ea4f1ea3dab0f8a20a059770948ef2122edd50790947e9292f3de55285828360402501949f1cc7fd5f7f949fe01f5285f2fb18796e6ef1c52cd6b093651ebd46af919046d1e896d1abd65a2396f94ffed2a09b46c52c8c2093fb202c1aa552922fddd5c94b8f3979e95cca5dfdc6710987ca7f159cd5a85caa54fed227b784a3f493977066938454fd52f5cf28beb0b68ca0b8342f7956abdcaed1abb64af4f83b2787f1244ac7f809fcd261e02782e0c02ffd09187789931d7c615c9ada327de5b4747c9993c3b8a5fa95c7a84cb774d371946e7abde9e42bf8070c5c71fe03e3d26354293746c59ddcd22de152fd11e7e904972a2e39e0e4a5e33879e9f525fc2348c5384a37e11f11d71f273846559a070521b2f42f7e692b0caa99a7be0a06d184b525ea19d1c41a3da31b944aa21e93a80745d49322ea11f5e4c6f82361b89b329f7c08a209d5846a4e6e54856c42378dd2b07085b408e1cc504eac21332d7c14466b403d4673a685efb6dbbc23eab19190d20d9d9c826fb48347af06270a3edad360cf6aa64a499cbcf4127ea2f493f784a6e819846842ac50ab5171055f090709432f1b7a855e3e7e845ea197080e4e8ece6b8747644664468446a4c6e6c6b5f3f17c3d22ab998a2e119648cbb6bef07bbdbe9b8f0c11558f10c17e9fe03ffc6c8c1839fc6e725bdb187473525b58bd892cfd8c071fc5a1d61aed90b046af11cf4c5115291cbd4e4ef00f10a8ecc4209b5a832fe21d1944e875f25019224bdb17172a43e82583e8585246ff0477b525736a6b8a067b269439d90dbe986949b6e4142733557abfd2cc94e98d622a9db866ea64a622e5a13c36083c76f5b12c4be6c89cda128115b95fa7a833d862a64edeb736b1c6fcf4cc537fb562b16aab5bd520c468a5106d13e211a27cbc7d3d4b1c7a35386d3cc11f9e30f4cafd233a47d92f9c9010bc05090da92fb086f93df4b812d29cdf340d57d3787c3fba62b4d2d5287979d360bbb294e00d631739e4d1491f3976e7e2dd411f3f598e8f91aface56850fbcb8c37266b659032b4cf2660b46b40667a79235d71e210cb618f99e579745966e10b671a5662b0c41a332da58cf3e6bf91d3b44fa053f2669e5abba65dc8cd4c7d9e50324fdc847cfc3ce8e5f81ec2f1fd875c838d6db0bf79ea832ddb4834128a0d528f01598e0d7e3aef5a0fc69b73ceb0cb1f7a41dd29e89fee2fd3c3244dcdf359169fc5e992b3d65a3428dbd560bfdb35536dd3a77ee384f286fef93cb9bf1223cbc2175eded8748a6ad114bbb2f085edcaf604d4f5856bba648db4e2d31f24b4dd361e390b455bf72d6b8bfab27736673978889a0ea2941409f61494524ae50ffc32bbda91dcd1a3674f85e470c6574cdd87d33680abf7427a8a7a694c8e3274b78443994b9f77343ac9e52bc76844f2d18864e6687092cea9dc7b4e3690949b2e9092cb69dd1b45527a9fe3ea9db5877a31797a88cc15bf2a96421aa4260fa5901a9ae01e9d4d5e693de99fc7984a79683a4dd96899758471c8a30bf59827f5364e7e72f20d7f78749924fa49f7cf698f9949a2779f56443f26ffe0307691e734f934393d62d4dd04efb016875248aef525b7f47a49344a45d4e6127a3120ca3b4a1e3a473bd31561203fb91c0e4599d66b0224e52f3dbd07a8fc9e7a302694fe6572b5fbdc7ad13599d43b4085da064b80a45ce52405530eeb4c6ecc2537f4cf3579cafda35744e825401e8a7249c94dae6db0e4bf5d9f4a4acec94e2688e9849ee454fbc98d180f510e121212296476df67bb88c845270f8d6ebae9a5935076d4f979e9f65a4fd23243089796194294dcbe5e1eb9ab5ded2a2e996c4025d7974c6acc3cb205d173d309956c72fb5af2faae54821710934df0a684cfd66baf1e12a297bc7a366416ddded0be62fa925a6f89c5db113e8b7988bc8a77885e827790bcf210d9d8a089e4da516e4833e9d33b62bb09ff836983a4f90f0e8d1e1a8566a89eda506884c3276c170acd578cc3cf7bccbc3da427388cc9217cf2cf5fba43f704873287e629c521f7b9f4f2fb9c86fe39fd4888864216055f1875482e824b466c9fdf3e453b441739d79e115bdea248e486a25711918bba1b8a784c7a93fbd13931d2ed4d9e72639f4cf0e89dbda0936ec84354729d9046f411db452e8243d18bf814e5d979de70f48fbeda4cf250944928de21faf670847988b2088b5cfb72e803dd9047fef010652764deb66bd706120dd267a25cc31ed9fe50b90d29bead08241a54e96c27eda70d2434ed5da754aea970d3478aa96f0fe4764d2608fd762e7ab56e73dedacc46bccc1eca6b43469ce30ab861e7b511655e9a868da6d1aefa2a72c4d2f079a1fa31bd50d52cdf3c388c19b6f11273185d9f55c1c7bd9f438794ae2de064304717176f706d412747d7166a324b8e2e2eb2c8371c10532d37333f88820c8890052f54fd981c6f68431f59bedeb0cb7553c2e7e20209793e9b19ab7705c8761b1b6ee91c0ac0426269f8c296dc325338fad45dd8137c6174bd2880648a3c9607dd2190c9ddf671259c2da594524a89dd68b0412ebe3006ddfc6ec86325cf776077b3cece176458f7cfb9fb39ad1e08040281404d4f5f6badb5d65aab67e23e5eadb5c15a6bad9c3d576bed668dd12087c91a839b33b69c4d67a544502262f6a198931e8c7749517476d38773cee9cd39a78c9e07ca95cc453a23b270b7283a3bcb0ec2f3cecdf95ae73c2704775b64a53846838d9a7833e52ca3d36669a7f0c97f686e6f7694ab1ba6d946c939e7b42d5b55c8302b533112e8ccb2f97db72799e6fc3e499f88c318fe2e8e3ec174e7acf5607034387378ddb97973dc980f630e0e1d208cbd304c27d7cdae56eef31ca6d8a64d1eb3e7949fce9c404517c880832544c1085ab0a04704f60638b0421c8a70842778a1087bf8b0c10e32ca46c5d99d8c91520e99916ad1853ebdb3a6694c1b167c3cd8ce608a09e4ab6209328888db055286124e9a8aac0e5f585d2e1a2d68aac8e92b38a92245197491fbb4bb516390839a35478f04dc080fe83214a769f46582641ff904f2519c28aea2394da3b34b79ea3d7b26bb9eb1af6c3317b9ceb2337c31cb766060d264d0639e1e11128340ef0f111f9b8dec900fc9dc715be60a7fbc3226c31f2fdb796f17c820be7b5804c7cfbef24bbf34c5919766efda0cba7247f6fa49933dcb5e3fbd2228e838998878e97dfe5d4c0c528677d0a54768d9c35818224bdfccd488edb84da33823d9e7a7592a818cd8ecd8f4153830f8620b2e463e42af681b1cba05cd78382e389920daa3b88ab3999b14b96bad2d98adfb8b4a536b9a46a5b195c60a9945e10b2b4d76596b1a556976d4d42a62a5818116d8159f766b4da5c1686a158daab324719dc2cee0a50c5716865bf94a99dca74362724c67af6fe2b04e912babab8d1aec4c172d313b76caf3c993a2b8ea51f84212fd65c5258aed4d26e40b6dee2b5ec0d3f3cd4ce10b2d19bed0c2e005ac0ce7eb635726c8d760931a7ca245ddf032eb8dd128998f562979344f9ed8bebe21a83caec418438806a5f4b89892d2d959468feabca80ed5895888a943bb98d4922cfd4b646b7d86a94e83fd7a487576444c5f5d48175094abf842aa435ff5288985a52faa4375e8ab79c4c8d6dab845ee6a23b2441b584e6459e94147e5a16cad766c66bf1b32258f519dd44a758254610511729ff6ac58ad199a9a9b48005a7956acd60c0d154277284fed9569a64a53a65174876bbde66ab412ad46569f8e888e8e67f3b1c96672bbb4a03a2e68e53eed820a999424cbb249492e1095672a968e44dff74dd0c72391be1e574e4d8e12b40baae3a2990e25b2ac5e47b5f4a5c3e6aba4a0b85c2e17cd742891dd7ae54d57aae88d0e25b27a536fea4d467534aa2a9165a5191d75666626a3a51b553ab2131352890e25eaec51a2a787670e6970678a644e8eeba5850e2568469d120379b39c3cb8d4d60cc541c4218e18599eea20e21ba3c1c62c8d750accd238bba78a4f1a4126f7e8d9514ae9eb0c373b90478c4c7fc32aa99418769965ec2cbd22848872c6493ff22f2d89a0596297c84229fee2cb7286878f75cfc3456aef2ddd9031b9cc89e9b5d5a833c4945cb9e46a45d362c9884048ac11ad8c08429043ac0d59ce8066a648b85001c0a552f56b8ece7785aa5f7766ea0796aa9d50a3ead71e6c35530450cd1ab0547dac3553b20a968aaa3e55e8a5ea21aa3e763353a21a551f73cd5414a2ea63383325f285aa8fe5cc1413ab156ba5b2abfcad42e05aa9fa75068d9aab55adb9ac9952795fbee4cd4ca1bc1e8535aa5fb35be159bfb909331cac07fb820a211c0ce954922e907b29cd2959ad4698f48568ec87735c94b2262924d9d8ace10f479da24f5d5b371a15769620c8f1f4d36b40e7a9727fa7ca1f7e191f63ac073b3765f7875e45da942b559467f24c9ec973b74e4bb95175c3d21c32d820cf9348df47738c78d779d8394c767f5e228bbcd1a848efe30934b92e1e4cfc8d8ea7363392f08d9a89aba034ac1bf28b94458f834796ef89274fcec138b29c9236f1f4ac2640c54d3d466305a427ce5407e2a91f82af042b882a1fb2064b9a066912be30eae4d08161188661d8a3705161ef2fe16388384f54144ff1d935adc488a71959de479c980776848333f8429b7bf051c102c15b664c5105162d151f7d9c25890f8ae07309414bcf90ae842fceef934422f13c20aa5e6cdc70459e9dd764c10b67091d2d9022f7951892fbd166ce89c3786fbc122e709e328bc30c2fa163561d3325553ae6a96fe38bf483608b9538d2a60e2e1f0b74725f649240e8a36a9ede78ad0a3e52ff0d6295ce86c20b34d840620556c41321b3944870361abcf1858f34bd77ddaf387439c521098bb873629fb4872d196ba1058745bee15088ef1ab6388cf179864353471cae8808e1f2cd6801c5c8f121f82191683ce195788a31fcd1d2bae6810ea9343d4d8358c3e656cdcbdab2c9ad9a9edcb426f76a4a9d3cb1a5c317d656abd24c21ee6428befe3c859abdd56eb5efb01afeb67d2d9896e190348ddbb06dc361f7a966ff650dbcf6cd6a9aa63d7ba136ad2db61287b5f2883b59563648217ca86048eeff903241be477115c9e34a8d915a1f72d534fa075f187bec7dfc90abeffbf798ccd9fb950bc66899d1608d74b990de6083d67e81d2114a4746429676dc8cec868e467d8f9f00c995b125862e7904cc258f38e401ba9c11e3061ffde7d12ba2050d5f187b7c7cb7d65acd458447b0088e980c5dbe121509b6314f36d31e1e5127c6c1ff687025651ab4d1fa6850aee17b69b0adcd11f5a70e72c5aac08adcef449f04b3cc19f89183165babf8fa31055ed09616a4008b0c0538d3095208c9fe81aae5e45b4b29f522f7b12f64be4c8a48738c2e15dba241dcf2c5c5e56566b64aecf212bae497061b2777cd6eeacc17ba4c91a38b102f159788e81c5f8a18c3c99fbc838fcba0f83a7c22bb44967eac42cd4c6ddd4c71a79f70e6509b199c4635b5c9f3a523e2eb2bde31a3c1c6a02083682b48194f88359a8aae0217beb045c785da6837f3d41f2f6cc95d07810804ed74bae2242210b4a5c6472ee438ca34dc91e3b51bcc6a37b9636d691416c644168a5b963004eb2aed2e21b5c170b02d5cbcc87d21b4c8ad09e1a2e5787b08d2af8f2bf5334a7a3f167c11351f104f3b5e7ac156114f6093fbd4a679ec0ebe7e6c6b6d640d376de48c5e13f1f2f333cbb20cc3308c5403130821032713447ee52bf741c82c4f576e1457ad9c935fd7e0ca0d324f2f319da73be8c491caf8b5941225c71b81acbc6b54f84929a594524a29a594524a29a594524a29a594529e1e06be57494131954e4c48252423d14848e4037dbc8edb349b61954e147cf103c2ba6ae52339c10456acac5cd1676d877b830327f3bd64f4b21b9b99c22e29a53421a5c95c991625d0c174b6cdb5e17c5b0e09879b8e4ee69a7466d2d6a42c4a33711aec672e9acd0667e2cc2d5eb4ab092c298724529058036b15ed997953821920a26bea5393c2cfe5da2e1f319069a9f8629e990e70f2b434b606c3d17ab215180e175bcc1df4b199999aefbb309c1a0ca706c3a9993538b36662ed46dbd136aa0227b058f6d352f1cdd38a6559966559562ba9c10f883d277f40ad976112a9eb70486f31133d1a6c7a7df4a84c489e8f891e3eba1e3597eca3ca7bcc9dec3a4aa58e25baa594d2071324c022f77b7c91fb4af4c95e8906b3bb44a328e5bad87576091df4617c29d16033b1e5b0ef2bb1445bac473d42c55e6944e744cd99d5c130120d76c540bcb78b94d97369b0bf96ee06a5e47a0b43485f769565a2d8e2e35cb9f34bafe235a273080289887cfe80d03f1cc792aaee9f4e8425130502541ea62ca9da01e4bbbcc88d2a4edee8cadfedc0ec99a7ee80774e7a373c4c572b4c59f3e4cad183b9d1fda53b4c5bbdcadcc815b9c83b77bb2c472ef2078c5c4474d21f203a2974ef0f08dd93b8f4000e3fc1fdc7e8a077f8c7e74f80ce3d263ff1bdbbc87da2fb77cef3fef1fec4e722e7389277ee23de39d27dc23bd7fd2bb93225279de4ca944e722e749f1879e8a3fb44101c230fbd8443e49f91cf4957e6e4a6975c19d24d4e7265485ef2d295f13ee27923de45f7090ec7f7ee3223179dbb32220ffde44601aa4e6eba51b8444152999c74a3b02ad24b4a4e72a1c8be188d5eba1877930b45f605e94201ea59955c96557127b9a3cb02551cb6a291ef2297e338fcc5f86254f1393b5659e6fc0862639e3a2787f4156bd4d7585731bea8923fe44a556f49e21e59d6f00e18893310f790eb9dc8723dd98eb07a0c6b0dcd4c51510716d4a8fa7467a6fab467a6627400240f4074d0e3451be0a08a5820c11457b8c31b6230022ca822187886908315c8a0270b3ba8686731fa8a1d6bc45ccde5389a067395c117dad5c63353dcccb13aafe99af3669e6ceeace9a1b3c61dc49d1cce9e1547b34517b5a135dcca72ac8f6bf57033b9dfb3a22e924e6e9a4371e4a434190e3f8ea646bbda7656b98750cea5b5080a122413443b28cb6ca276e74dc49d94f7bc3b6f3e5b1ba569f770386f344dbba669d2c373cee955d0959937d395d91b2c5c99c7b4c95918fe78e51df1f545441cdae4ed08dfb4c9deab0cbe70de60355aa76df30634bd8bbdbba10d4959d370d83d399c5f8e9fbcc43d663622fb420994f0caf573dae4ec0b2550c218728d91623a5844310590cfe9fce089459f6eda1069d75b0abe226a091223a5920732b7b44eee10cc315a465093fb3384e855bf720907fd3cfd8caa2fd31bc517b6ac4c397ce1bfd22f7907197a36b93f270e63bc5b6b63c5b93381c85bab51f7252f12db445ec6d4bcd9588d9253bef42d457c63c62664919c59f16d331b0cb68d2592e70ebe9d4c075ff62fce39316cb3b11a157a351b2b4b21c3336db2476fb5b1a6cdc69a361b6bda6c2c6c07d3d9585d8f8e4ea3428b75e1d9582bc8f8a5b8f86529bd8bf17c2d2596f86bb0b35564e949f38516dbc15e5f1489895ce43cefd29b3bf8b09d6c156bf0cc54f79ecfcd3e194dee0fe803ca5ab93fc7d1fdf3f80ffe1124e21f3d7967d5612f892716228b8a0bb215a8648c36b6452d959a1108000000005314000028100a078462e1783caaeb7aea0114800e86b84e745e1ac9491243c828430c00010000000000000000006d481316b024b288db8a365d826097ac595beccb51bf8afc345b3263f8516399cb817ef125d0068ebfb3623708b9fd22f6fe51b0d9ba715af63dc95fef939f5ed5f915229f6ae49453589d1ee964241b1095ad24ac59dc4c987cfba4a95cb3af6f950440d3b869e4182b256322813f1760d384a05cb54e26398d00dee76b1408a0c2e8b964e3f6d5b7ff977655cf6ddc6e1a874b044d59728ea32d7fa2f6787b9c7b68cfce1fd8b9ccb191267a36f264750659a508901e3da10a288403469b8e43a238d41fefad52cedbf2ca230d0f42df0ce20f1a111afa63368e0149be5ae08833595cb746c195a2cc43446ae8d32f738b9b703e92d33de55863f50515f093c0313a93107011e6628c9844ba25a33f5a5e63242ebcab86546fe223ee829f4b087784a75f16ab17d6249dad3ba7cdcf0073247d83dd7bba7ae0aa2aa781f21e02842f5aff7c48063ff52f442e0fb2217918fd1e12b46bcc64f26906f4992cba13c88f5d343b26a8196b87ffab0fa2f49cb1f442c3f63ce14d32a008dcfdadd729e5a72a75d80241afc38b5b84a249dab15c2f3089f229b3499b6d24279671414b4e7a7c7af3adf76684969165f11ac183dd2c00231b764600ab38d2d634e4a9956098d1cf5c745db52b59617de93eabf62e1b8b832a70ce55f39695f37931ce1bafa0bb8ba06c1438276017b6f8555071acbea6d73017468a34f09afb8603543c051cf5fb22cb1dd4f59241aa5aa9e9ffab57700aac1471eb25737bfeea2d9875fb87ee7e7fa60b594fdce3ae94ff2b5e801ab7591e3fc5dcf60fdc12a6444ea8b5c57e00e9e9b531bb99383239d261f15d891e1603f38b5b0581c53fc8d1e9a47a806f5a7d825f4a7d825f523d847f7aeae70c1597427499d93c3ca775cc70f75604450d14b14f20d1d70962b0522970c9dab3eb93944226d6646be8be3668e2fd06c4f0cb43027f67077899b6ed3a56948a8c8bad7432016d55c1d276ff72345a580381eb55bb152846f6f56520a85601040f9b87ad43a043cf5f87e39a41ac0179ca002adfcf66838f288429066bdf136009a6255714438d935a623d56c14d63e31afe302c2b869b00445e1eacb0365f7f358b11d2406495c19071b30525d5527a2a6cd4c61672ca703040c5b15ec12acd66cadc5b230c7773e299c2e42042a445ac2572baffd3d8fdf41e8e769eed840b88f863032c8e6238682c40e2d34348380a8982005b045407e9cab41e4484e0d1a2669fbb347bcbd9d77dcbc02e6beeb56e3d25a0e5d19bf272427108219e4acfb5accdfaab961a895bbfb2bc78bcd1d90bd10f259ed9c9d95b23f11f2bfd24b1a27b82386140af63ad15ee60845b36b9981c47277dfd7b978c0da8dbe9212d639b831f7935be8c5dcd42766254b662a5f2ae1a4d28973522463d0ad124eca2c7b9a23f185409fdc72db8748d443207aa968eb4ed34a2a385aea7d4619163345593bb5b82528d8cc3e2c116104fd2f32c7f155210f57247ce4ea09ca12d812347a75919c16df7170e035fd8828ce98ffbe93de10241b77174a8df3d2d41daabf8ee4cc5ff663f7baed478a225c88a9388d20114f853a747c533166120460f61be0e36c20b15b0adba78de94adbd3203484d86b7e22ce0cb30884e4ebba700f82e59c3f01366fd87bdbc0411b1bcccb30f39331ab96a2ebed9f6114f8568bb130a8b15b571d2deaa67996e13a16148bfd7af53a6d2a33bf4a954cdecb98909636af046d4644d3dfe7b7c1b8eb77052aaf93c443254c272122012270bc259d21da6315e125d85641b2cbd0a1527e7652197f4a285cf4d28db2d10bb80e2b8a4317c6b46c88775496d3880c9404ae4ed5a6445affa0216a6e0437dde8730a61693ce8c4899b9cc15f5eaf952e0eef0d39840d14c6b0b54c83dff28fa54716d93ac079b192bf3f20438257f6df233f85b6f22e9fe921a5a10f807a22b514a81dddeb968cbb13c49b56fc127bf6cb39f1c2a8f2b2d43d0b1dd77f377da75977e17a2ae87ba99823c3f1f42739ee24465df8b4074be231392e3617284bd804dd8a26766406bf6de389aea7a1660b6877407c5521c5dc092ce5a576b19be99ac14cad8935bb1b8321c88b499d31b0910207a9be5f971232ba03ba59e0bb1e51f5268c4c427233c8bca3eadf0a9c958ac4f1dfacb3aead86d03ab6671c641e4bac5e6098274f79bd1abf2b9d6595cef4e790fa1d9ee5f59f412c24593ed78d1af6f94a371689bd651676d55002bb29530c7c7e0ae3ee748a55e68af4b972333069adb98f11b7b25ce7cc630299b9947908049c665748f2bd63ffa2e5f08310139ee9380713e058881fb5c2bc2ef4e4557e33a4f6ae5088f5019f3ad46b4550a047ef622ab3d90e16b8485e88c24e2809d528678059839b1575f356670688d894c749ce8b5e7419b4996c20247193bc825a8cd2828dd019e9d07ddb64c1445f855b3ae64a5b961304d049874c9c26f96197c4e610f6e5bf36d78bd51fecb3572dab0e00a0ba12f2d078d4ab2b53445d55a6c74aca88d24e1b0dcb734c7941728770c42d914effee16706a9532a118579b8c11abb3b93627e3172cca207cfdfd09abd7b95b3946211c7b8662fd3092c3a27854f4181452f07cc1b56440db7203dcede53ec025b1f46426d23f2354a8c15e0ee82f90b9e3e04fd520eeedc2f30af886d5ffacee050b8292392dc278f5d79e83ab0c05e44beb1796ec760b8cd2283dff4a0fbaf3b4dfa8dd0f7dc83f6683ee709154a15335847a5823fd646a69dd0565c0f09c48ff12927f19e6bff2eb243590dbd5e0676e72d12ce0e04c930bc630801ebafe92d0fe3fcc65284a316aec391c2bd0a3182744e1b26a83d51d437a7aa97ede9ed304af1089047d24e9569979ff42b5cc8aab37765673032504a205b10c004e4f2e541338ae6c6685e31d902e7006ba5a6d3d52bf62b738a57e76f2619e7dca95b78c665c24300e9ca009103834cdef95e5b10666514084c2c0c85296a43b65b38ffdf93090a527b509c34fe89dfb0ab83df9c23ac0fd792c30293d84d8be7fa4fc038b20efafd3c48f74d0809ee93611273b40fb32e154670350ab20ed3adc54ed229c881ba06836580dd746eb07f856a9ebf7f23012dc7f492e3f758f099568d271cfded3678d9141c95748de2014a6c569923a39036c21ec3fafbec0beb01d52f2c15ac50c820b376ab14866d655c94d29171ad0a7bd0b05f8c4355ee4439f33662c48fe0ffb29d998058c045f61b5aa2456dd10a3a860e32804a4d1de7a3b6e9269bf76e5bb9f47cafc0844e746bc0dbedd4177c375b3a90336ee84aa201d06ee193c9edaf35e8d6696e51ab5451f921765e121a4a17a20edfeaa2abfc09075d48613053354ec3779b86d7ff2430175a4db970931bdd1e37cdb28a3bd0cebabbf80df3ad961e0b77df6fa75a9fe1da279e052e07a07927aa90c8ad751711de93d8ef0f381f3374cf7c0b047aa1748ac06e785e406e61152ba72d164a27f68bdc12102b9658586660b117fc76c5375eb126fc37fa495fe416eb5e6ac36ec767fe25724e7b38165f8b719bf181393d13f9dac6cc90129d4ed6b7a5c1fa90705f2e0cc633d45c375d59e2b232f27e910b13a8b9c6334633ae949b5bd23d434fad9af60feb8be3588010521bfc86afcdd817bfb58ee3efa4e687b6a7a4474871ae92b8eadbcededbfaa45839b602f5bdeb0477f7d169fe21bce066a870519b3538a475ef7030058b17779dc171be86fa551c54513ea9db69aa9853daa41311410d2446923ed9da63494061bcc2b04bba23169b9cfda680906831b84319c1d53e3d0a8bd7b621c7f1d03b36b31e23596caf30968572ec6c35a5fea5b42e168bbfa13111ecbce225dafbe33b8b4b370dc56815f965a006230ef3104d57b1e8d219d03ece91ad1b7119b86b24bd5e6ec441f52c6876256363ff425214ac23bcda27d46f2738da193944539adb5fecb2c7657ffcd97bbd701743fe7a5d1574b8ed1e37773bc4ca9b84dd0266aea3f9f2d614c0235e66c6c49b5c852e0e7eb969aaef599085f4c78e94d7fd3732236edb37aa746b352667edd2e3a27a2a2959d3d5574d61e42bd5d8a63a83e75fa393700ad2f6579093b7390ddd5cb3c58acaf62f0aeef76d2f931094139372610bd0011bc60e622763373f21f47cbd3b2661fa881c24ad023b85dc48e403ccea9be00c1c5fa4318a247dcc6a35a55bc252656a2adcdd1bfea55a20f651e6c76f6e8a53f6d158fac0a4c88f1d294aabbb3338ca992617f87c1f187435ce73daf7a712874559d684b85e8d0c8f719e87f14a8db27fc39e5e35732b748a218071edd39aef6b6dcba1210b245f54177eb235640d4112e1c3ade9819ce237423dc3e60402b37dd5a094ccdbd2426e299f28d7a984d2c94a4be2113b223926e8a2e9e7d91069f3259776cd7d570f4a931b0f517bdc1bff7f314a445a511f6d7e5b87e89906acd97e370e27a74a7672b3f75551c699a0f18be0a032c66e191887fdd00047322263e8bae5287ec810c18f0b5901bdbbd49c25c4e45a5f5631e71a8d47c2a229c9473dad02e33494b4070d4e371384938a13c629b813324e36fd719abb178089db6c6a5abd1893c4618cf7a8e8841717c1ad7c181177000f140eedc5e0715687c6f151f3261dc4c8efdac806849b0c345325df826b6e7787c3003cabdcca1570fb995822216840c2d1d31d67305e5f51b12c637674ef22ab39c706e1342e72c2037ab0eec505024b8db93d8569c1531ff2ddd6593b41b21312fc93afeebed985f735781664c77d7db00578547f790c1760157802c7bd4f93cfba0fe3cca39eb90881794822afcfb03bdb8e1ce118de814dc78b63f4dada2f3d2215067e554b24e0f300a7e9ca5553f88742b01579ef5dc1b42380f8a0c2f2be141c9799fa022b75621fabf12f16dbb3c910296ada00d69fbe8867b4af463bcad60ec2e10e8babeb6c6b72094d302a47efef6349449cb7eb12e43b2634033e054b8261e85023fcbd448b4e3681b2ccff01902259015e44116f7674898021a3babfbb6de4bded7f838875a96da9b8a855df23334ac1b3abb02fa180d582cbfcd1acbca726b65a1a98b6135aa09b21421ba7a4f9e8994068361ad7878a66937c3075f0b032ec1e70a3248fd2193b2fc9226fdec8de319fa68fb7e28d0d9f1e543f717f29b9e2bfe5b0b1f8063bfdbb125a019ee1add4bf88b5bfdd453164f7fec593eb219820bf39277bdc9d55ba080543481dbb33f620a2c4ab58fd77bd10ac042718a8c25fcab0ee68614c950164b64bb6ef74c8867fd874f02e63d00db36db3c72533081cbd850a77483a845a60263f80ea233f1043c5aeb1b1873067ec06301629d37a34a95469ed8f3274d431764ac4c0d1350667bfbdd853a170aa3e409790b46f1fdce5a27f2d4b52bddd27a025eef5f86bfba109292a786cbb977ace81ae17c9f10fbb601124f3779d0d1510353b10b6521b205fa432019b1719901f663214885167b39e5742b682f87daa4cff9a26335f8465312145a1506c309522894d58287cba9629c19aded1e33cbc1fd335f647fc498ec4458a73f82d9a2c02871b52792314b5ea50e554df82a9ca52c894867282954f714ac376233d0731f372647afe02a5411c70bb7cec41d9a2b87cd9a1ffe595fe779c33c5c16248d28141eca909cd0bd5b356a114bf8ddbe47d01092374fc735deaccef63ca2d8f19f2a3ee07159b124858f8068240a0ca1322d8489d38eafbef5c99f21c94bd2a975f1ece0b8ad59c1e6c9e66b32135630de62bf1401ea5802a68757393a593304f75964da08ce9403f0fc96deda6009c395800e2cc8e10270d18a22680eba4b150cec446baa42eee4c33c9dd8a4a44d287c5ba42bad1378c7a2e17e31aabb2681f2ee456a590719660c500808b54e0b37eb3cfea2caec13227108196a01861fed10800b0484193eb9f5557a9c17ce2679d4db9d478562499e5dd07b29f75688c15107f3d3f0350266cf2570ae221070798303105c94b89dbe41b11b8eb085a9549f1c6e0482b2d11c0887d989ad4539e51debd15070c3aab5597c1a8b6e4f6143ae761d98d17c5fea3804e2ff24c3d449e5eea4f22bcf012800878b99b1f5559772c8b05390e25a0584e30032f97b5214dbc50900bbc128e42fabb5bd39de2009d430b13b1b384e9851b738088971e404c5653589854deefa7c05c17048caa7f2a8e4b86c58354961c648efc58f67743a2982957edbc988fb219b43001998429a2bfc4b2159f1f15ed21574242be3de30fee7e662a1a5af84a6795ad2d9c85635f951b549e0f8acd04b5a6c20ac56ac5cf861c2af7fd5b16705a0e434a71ccda4bbc7539d18bcc60880bff73768414ac085477ce39f82be286560f316964e2d2bfc2a98fbd821b002de5a3887f1ac95f5c4ec843c33ecd51391591d80296d27f8779c32d00042349e5194881cbb284656d0fc70f312fb761751420e37ab4d536198c25998570a1b8917f8b2166b99a3151c999853c42490263ae047af478adbc92002385a3035abfc027e0cb976c0e56335ee8fb73300cbfda342808ba8942dc2f56fd5b04de251d7a0a2af60e067507b5c684ac9700421d51cf9818548f434f8aaa1d7cf174e967a0981fe0608a931ce2d03ba02e0d94d6e24d482bf6522180428408bd4521da9ecec7d25b0a6df09de696e32f1d6c1595241a6ca58a4b49a54dee515f6b8092b1d6edf94190bef369b546d9de4304510a3dc97dab697ed3887e95255e6a3f290366c601f8c8db630db630ad9aa881ab203c6b3a42297f7f51d1ed1e8824b41c9ceab36b4a3bbba579ecedc9ec74199360fe58c38055da1df3ac9bd154b90903ff1d56f89f622e2024c0574b37b39ddd97adeb914d3de6737e0d06a783eb420d8f976ba0da62c0e2a3039fd4ebf99ebe560736520c8656078d677acb36c0f92b4a0086348ec52e2383d4066e238ba6e6372ed20e6fe377714a6caef6ba814c30907905d2baf63fca76ea10ebec9b9a1fe493877b2aae8bdbdffcbb2fe67114b9b814754c3280474b01e24ab963a1472983430865ff84f444d7a20082cdbd0c505ce2332c556456e349a46d0a18e760444a689568a937a53cc2bc2ee2a9e866c5e0e6ad7099601b4bcce980b4dd182ce78f9e712dba717c6ff1326b482d767726ac8bff3da24ffa9e79bec0320b2ba108e0e3be4ff1879dee792a6a94b05c7f9fc726e0cd4d6e7dbf9f6f47f33e6eedcd2e9e404e7406ad563cbff0a883cd25b86e89c86830cdb5844756e5f0a7f2a326812273acac5b8ec8d4b72b488ef494c29b9cc48abe04e7140b94f0b81502bc908010bd5a6e25e81185bdeb2ccad8cb8896d38693701b08ac8f78b60355b6248e84bc4eb5990d18d50e50f180555577618a4021077f7140487ee4b627f73cab43fcc6b04cd54ba3bb36e504f3d2a80a9fd8838bb29e3114a9234090f6e780e86f241f1dd98cf70663ec7fc042850341cde8dbb23f2d0f139cae75563f8b90c0f67b78455ed4da502c8688e97abf9406be5ae2d4128f8e43792b43ba0bc57d8ed94d2c79a85e3874fb5692fe316a2654648e71d0ac9b58382810bd2a77fadce017f852cbd85bc1bb999ef0267f9367a815459d9dcafb46da0702344fdbc13d011ceeb7dbb167173b73476f612dd12379efccb4e4b210795162aeb4a0f0a20dc5b0894d9a3fd0db7373692df3d4b8f5e9b95936c960fc09503c97312a9460e706f83e75d1f5beaa0c902d7059d4a4878b907789b05b5f14a30a5428bd723da3b081a4fe1592f351839bc225f5f39aae20c95278ba8897581ce2c0bf0d909e95e16cac1a97a1a9d3b48cd125068624c053a2f06b6692357c4013e2adff1dc21a0e285084fb61bcaa16aed706a08a0b3832b28056bafde50e2cdeb94a0338e1c7c05bf0fd14acdc1d40bf0fd1a9b638260f914df47ce428a67af35713f0c91bcbe2e313c34e33f94040a5b527a2dd0eb39356f26b7e9c107cbc0fcc8475db6fddb2061b20a41cc53d1d73b35b54ce20f9029a4583b7ea09f1645df2bdfd173fefbbbb967bffb4e573f9b8e72bbaccc3f43b49840da5a4856874576768c9ee0d0cf5b36be2f90081461d7f49c0cbd1a2d9efbc9cdb303e8616f7f06f58060c2f7ac507f6b5dee266bcbbf085c979879d40b0305f1f82ff9dbd8cf0f72bd49a7741dc9bac285081738c7fea34c8c9c73998fe1aa2e6b97dc73c585cce86791dafbf4e89facf2e327335aff0d98c7938e202ac2960300b4d3fd11825de17bd5f8b51b05a45a83396d792d660b857dfea19fabee1d8a8e272ac314f37867e3cd5623a1389c54d91880e8d3a2c085c5d9452ae577f50c33302c76d296854b4cab24654720151d1e94a7d4af605fb8a1ee80d3aaaf64acfc3bedfed53b79f9ebac82ab690654e436d1ce165b2b15a77a28bcfb23140886b857a5a69d162c64296783f282f2714c133e75db3d7b0b50268195e29fd22952354bdc6fe06debf7104d6ddd20de85ecde423cc33c9b9c19c589ab55812964f0826723c1c08b12284a0cc1e41400eab8d6e6fa76d4e4b965a00c71358206e0e5ca5aa2a79a8b9f634abc7795901dc9e5ba5216ab03a309e1d86831891be652d2037f9198d0bb51f280dbb5970b8c298c6ec80aab8024cdf43a01ca64295819b90475c04ef7082fa7fa9a99bd26613515e488511491f09aa66010fb25e56bba9b09f7e341bbd4c3bf6a92c9a3a1413bef2b2d402f1b2cb4d8a4c176f8fd2e965e4638ec78abc8c478c2adb5293c99f02c2abbfac5fc06490d3ef4754c51b0186c8105b9130cb5fc6bef9551f99adc9fc3100da22d7cbe7426109b34ddb28d6a25aedc6f8d87610841de345a5ce65a4fee7e00312b184578a7eda5e5b758708661d68b1c2f6c0de117ab13ebe4125c83b23a2b9f23d2fa98a13b0d275e8f40c23c92a5c79c573371c1e70b5f1eff91bd8b9d2b8d5bb965ef888efde48f1bee5ffbcfd4e22872373aafede984dea4fa54d36b16d9c177339d34cdede5b40f98edb971fe73ac9d0b063349016cd1d2ed566307418bc1736016c89d49085ac9b626b84346ccf3b6c499626a5cf5e83a310962774cd1b3c7fa6fa19e5564b17d5fba3ffe8c83c486b95fcde1420b0e4e1de908273c9bdb9dc4e5076746bebec0c13a18be3c5d368504172d47bf2b46eafc5379a1e76f1e009eed6818307e8c4108db564de3b12728a634966bc96daf63a24edd38bbf599dea41ed72636402d897b6535903f8f428991a84d1b7ef56e4268b68f8a7b7d10b14f2be8d8d041213c08ac50a2a6584d82cdd2b288cca962784cfba7dbab8ae72d5290106cc16af75b03abc28363ec9a62d8c32821003ce2a0d4998b67e693091676a8c273348bd83c861a2bb0094fc9fe5a37de7111a5e87d9a9be1e26dd6f3fda77f577325fd7e9dc5d2dde039cab2c57fe2f71ebd710460b961386b37428bb5861d5f00456c16d329ff42b77263f736b033e5782ba8a2e0dd50b55268af736b465662c32c10e19f52ce3b3be9bab566f865fa300c6cf595e3bb415710324010f118149040ad4695886a283a682e5944190b350a2e85472e2140b72831425f0d40d42dcc7df012772400c16d178058c623841c2ebc41f6e82120ea7893ba7d1c0a02ae642552bc4a8a7b45fe687ac444817f70efe22dd720b0d4d6cc73ff5ee1b2c0256d7e24463dbd0db568336d1cd391503a4834da94c1dc578749d0cafbfdd61eb96f67b46a7445b5f78254d6324ba060b8c920b6db70d8fec4c0156fb17896494c10b68e23a59c222e6db83f09592f7978c0a2bd6dc1f297f6d9699db6dbe93606961a62201161b8c21ff6380b9e3a7e1b448bf48c11329112c95ea2da680fd2e062bbed9c07e427ca04e9a919a8cab78368991a53e8277ea840f0d3f0b49e4334994afd9238fe38d51d7535ea0d7da5373070ace95672144fb6d6aaeb82966c70df61d0822863c0560e3c11b17607062e3340fa13cced6f2fa48c90c22635792839961974ec49e929dbd80400ce759ba1abcdddca1b0d707d4e47421fdd5024b54f907303049c4cc3931ad179b873789721110616a059e5d7a1c398e32e0bdff75a75e843bca4f23b7011c42cb935fb1763b9a98bdf6b1cded2fd6083c4035a29e0ed8cbd999aef7477230f30879c4b6adc0d8a65699d310a687b518d190b355c546d593d48b861c901294945e462f111af5100ae3122e2dd67e1eb644c14296d348a8dfd821b3e6d4d610cae56e6a899a198aff98ba0c1f59ae26c24e56dfc5479a0c14532a268169fe4c43156961968167c93131d680a2ab81db1c63898c6919957238d79e5bff69c47ed6992b001839953af98437f9d1cd1826e842be62acac816279161e87100d3128eab9f3864f0976fb7461d216cfbc2df789bc23c32e29ffff841224dfac786fd4792272cc2fd137115b73176f9f60dfdd57cefbd349fcf83c41967ca75a1c37f582b4f14631111e37f9e6a0b62c6ad0bd5a32d9fbb7f485916931919881ebac3d0ce932c8505ec16c54388a455d499de7faee1886981425705bbe282c08819e8787f1b5cc12cfa3442c67b6cc2b685ad0054a39c9c4346dcd3568151ea05fea125d06a1be1c935396f63568a0ad592c10994a7528afa735c579e54e90a422e893e3fbaa28a06c3d744d2c5c1a1834035f0f1be99f2867b8fc69b2fefb5bc487b26f588655f48cca70be3bfd65c4c0d67f99a47236999035aa9119f55282899d0b7324d6311f1ccee053fb9719504f711f38017ebf8895dbe858bd96984b5154441b88928d83e33ccc774d7b63f718f11fcb43fe0ced24e65154d45ca29a9101ff1a481dac375d726d95113833f498572f39d6a91f6284bacd2f3c70c36975404c4ce11c7fcfa1ae2b297f6cd2f4145b342e4868a918b35f343a5b44f933916280e6e12b4bff7065d1eaeba0cc2cff3b6ad55e37799e13a6920e6f4a810b5902096b670ce29b642f4ad77d1d4bcbf997e0bd230cce12d6de575907a94951456eba711b2192d917d836c3186dc7c57bf1eb51fe6bc85f3182450a221cbbbf6996094130d416c5e621fad00dd7cda666818fb45dca406b8306156b863456957d8b5972801460ce6c8033d50a29f523c136cfd16de4d4368458edaf3d392806c747a9b7f7458bdd801757437aef0d3244bafcbfd3ce6d37d09f840400740dd167b98a4d5c440e05a214fd86d2515d3b0c768cd92654c83645bf51c0291a0bb54d4cf7d7293af84ba9edd2ded6100cdd14ddb38b24c8e8145d35ba92be441d90b60dc4d244a2de53abb763d0b6ca256e26e2166e8248c4bc1790ced98f2f01a145fdcafbb165f797664d7849f41982bb91263caeda2af8a39fac6bd164287717a1fb3b0b66a9515bcfa70a8242ad9ec24a93a9802ede9a33702b280e7ec86c21146d214190d45aa230c26b7e8660875f7cb44894ba27095b20fbc15c7511572db0f513a55a3fdbd410bc0914dc10644e2033adb2c2448001b35161c104b03fd9b05dbf828be30622406cba703929b21c37842498d4163f452c7304682ea33b29f1133128c6fe8ce677e63f825e390b64abe456b9ac589c43bf8a0b7f12f09b37befb4f050ba8d75adb11ece041f111274c7213b67dae219a4f94ca65a76be48f830561c913159c9cefa6769b6dea0802bcd3ba6bcd011dc05d1e4d93545aa00370e33bb349abda3433b373119b0acd5b5ac2ed7f8e290bc51a4cc69bd04a957f6198cccc719e4a00a81658eabce73e997f790025422a29d0b91f83dd0113c1c128ea9794d2b7f7a96497c11304975ab5dbdf14ea0a7e82730340f68cad21f5c8dc0a46e47b3d1af9a0a342a60b766d0ae4c826d0062300184c8bc001c476e0de9b911376b522fc31d2099b1fca94a5f90c30d42af1d03cf45101afd6859ff127c2d52a89abd512156f9eea3f729474ca7016e808a5f1ea6dd1cf4f5095555daf2ecb6a6abdbf4d57357c30f08f73a91578ad4b060cee146643d20bbe1ec7ac2a5be7034f1420afc12d4c626bf91d40d9d239a1a81b1eefe7adbd8ca61fd5f025732f30ca8983e15e981d0dad0b6880a893d4fc105c3f48f4b80a80b76de91a6b92c89d31f11ef77d5c3014967686e4ba5546570bcf0cffafe2c30d3ad3c6bdebd5a5adf87eae790bd35cb9e6532e702f3049452781af6c85b59cb77cdbf154c1f43a3a8fb9636d412c8964e87552e9e5c62d045049a67a684a1ab625db2614bdd27af9c35aea5b71db2598a13aafcce3f677e8004b4c44ed64ab7fd41f56a1856a4e512deb2da57bd32776855aaaec5060698ff5fbba1ee86a54e19bdccaea70826899d3ad6694de5e34821774f3189776295c418badc85c7c06466c8b8a511790f26a18035df3eb97cbf2d5f5e57048dbd08611281586398b824ecd39c7cb1c9b9f768762e60491485d72286841d4101f1bc338e3593a6a91b6945c088de0a56c435bc35ce469562c00467f762458bab300f7ed556f6223d3bc6ab070d3a8661e0bfec9ea968cf2751cc550df1ebacef13b04f308f646f0428162447501bc56a118c51cb2e888c1d6896254b87ca86747c5155d6adb31705c70d2b6397775d7767e5d5b3efbcbf2dd4170ed656f6d6ffe1a3aec561bfa9a5ade9589f04e49bdd7dbf89c4ca8dad4214a3a695b3dfb38eb9e0d03993aa5e96bb1c797cd8f5e49250aa51c399c05bee522bf385d41610ec14b61fd23b64f25d50206afb016045da41716768a08c9482e42c16d14e7e4a729b2a1fdc66891eabb529ebc0bd6e3f7f7fce8d30a03d98176624c75338760bc05955cc5eb77c704a8ae2bc9c91acb589ed54db7ea9e23468415f2d29a4938826e51a55cc4d0c9fb61f640a40b7e831914c9baf43c61cf1a92d320bb6faa7d17581973cd261803951a01740b572d89992da7a1dfd28dc98877ba0d6515dd90b7f8fdbc6d39da7a6f2eb3c924fc8e17807682548113251ed0c0f90eb5c5159a604a3883a7039509210a5fa55c9b9812a64dfbe425a0d2088026f2b7dc6459183b5641244289f8554828be37612cf9619844e87c69e052894e63a200ca2800d8b3236466727f2b55706ec9c70d01f98a020457561fe9e24313e7fda6c28c612601a107dfee335513f9b2cb958482f3415ad90107464d0548db5258364d0fee7f94672e5cfff9621c03a3e5a524ccc7a88767b6295b5298848c648f05f95260bb14bd0301534d584bf231d6d78197545fdda4e6ac778809eddc51cbd94ae1e99c1c3159d614880799d8f9a230bae2083efcbc5b6a5bd26ec77d9c81ce5d88337d1b1e5b89f43a1ef1abf28196ead59b154bdf74b74c4c479b81fc20f6e47bb79f7c4185711f64624ca7566ca4ef33ff0cde8bd03ca49cfcab726ac02f1229e4b5f9bbe4691091f1cebf001cf0f9b21d96e706a9ae8f5e688598055e10ab373af557613b08e9b92765aa991b00247ecec6221c425e781b4f7910cae5652fbc35110a8ab5090a96e437f5957bef19acb70ffb8ebb85f6406cefe97f943678a1aa3dbadadd34a14ef40a612b9c3e4e8d30a1135c4d73e5def443e7157ff477a1352a6cae58a0805ccd810f1cd44fae0f119f7297bbbf0cd62b93c2d3cf951727819ed028be832f66750a5c1f0b1830cb93c62a1b87ca4dba5e1cfbcc449693e06a2c92a0c5421087ad196a21b30c6d94a2d1040b31317146665c4cd8d87188c80442e5c317ab8170d2ef73ad5150a616e3eb4bb50642af1a96b817193ad68f6d3c804b2185021c2617e14b3b8416642a5b52d39062ef4db8513dec6773269547f0754a6b8df0ec91059c025af20f794d2e4d91e7575f79874241a5c53a1021f3eb65c6748598b315abbe1a3ab93de84db74a70604beebc9b29dd4b5ba585a06b887700c9661831404249d5de04e59360fa708934068e94bb8cd59638f0d1cdc74ddc86151ce407e650417994608c15cb19e003e9cbf95f70943142e5de6d494573721faecde23557c199fccb9c324d94e837300a54efbede88ef478050f263ad36cd33838dae3f5f402f82470df46353a8685e193cbbcdb850b17d4f92ae87833ddb1c3010892d580bacb24514397de60d118afc3bd319207c5ac4a277258c44443ecbafbc5cf27d4938b007ef03ec344642307daff824c15f32fb7e8cf5abd92bdffef91d4cc784052fbdd64a218b936dc8d497e442a137936e0830002ab5a2306ed3e6cd4c4c1d134d11c80ac6a7793ba6b8c87916dae85ef39b9ff0906d1a39422a986593335f79ba2a4701fb800dc8be5f28874ba77de3efcc34b1a70053a0fcd5bedbd1da29003feec1a8ae409cf71e529f2e48452282089a561037d59c97ac0c6564a7650b825938eedb204ad5db856324d26923df7fb8235ceff44700194e2047a5bfa1c2c95d2c3c0be21f61a4cea77f6d36f58fdc96a424df2bb090636fac9538d798758cb2c287c9272a5cdee0afbee248386881d999301033d1cfbff32343656634d91496a6dd0788c78310e98db69f63d8c51fcac0062955881fa6069e3952a7b06ebd9437594f58e9bef598521430095683820285bce0163d1ce0df378ee74d7fb34cd1c3ef2bdea20791d56c56bcd726cdd48515ea56b4535f56f4a407cf738b71b2a7d03fcd6f68a627af843b0e0be682b599432cb2c30f3dde069002a80bca459042158f0d383324a89be2cb25fa14af04357ee8d1dca3837a000e83a46c8e22826f690d91483124bcd02fc04f25007b69c00968a6544d58dcbb4a4428f499d5d44a7b9369ce37d2698825632ab84551236cbb3622f61dd24fb6ed7e41c76c8e3094aacdc1a75b1d53e7253faeb2c1c10ac75075fa81ad8e7795cfe05699188c2ce0b2ee752cca5e1a71bcf116f6f83555ee6150a370aa5aa22a5f0e59ec843ea6f6b9bb155c093730c3a28167ff7741d90bf14a9e97ce719b3d9abaa7821e969f1b4d920c78daeccd739c55625bae582e81ce5b096ddac0d63a25c23a3816556e8014abae426c61ec94c852e1f1a1f0a5a44a24645ffd66d814e423eec11927687bb862edb86ab3d186640db886700ea1dd99724919cbd6a99e76631d1f3886f4b30a6a087b7930a3394f221b9946ca5f418bb8c4e44741344f373b396d192aba27761957f1e69346afd391754c61fdab668b0f052375b54ad299739ef7f7855ac0d78cc607360fb0d6a7cdef4bda19b46f268da5c2bbfbe145df7e7f370ee2e45908c57f690bd6075fd0c3a6ce652bb5ae71131aed296410574c12816f26748d7906787890471a37197b32bf24f5e0e6b982b729af9bcb59fc34a485c13fa0e4851b76ac84fb61ec980d198feb8d222281dbd17820233af6d95d3d02c019f0d6857e352e4d01048c05003279f4ee725ef2bd0cafb0123e977e20c3d41e3ac68aa82e9bbdf584122a971df86e15336c868bdf56ce3e08a20a3d1a2c0817a271414d1f4a20db63aa50206d5294cd91bbb993351e5691b318d893f29204847e67072900905de74a78503bca4922654b3c40741f5bedf4a19152ce5438f1a2e544996a807aab4941b2d226eedb6cd2684ebf393fb250b3d00f85320a1cb1bd2884e410066c57cfa50cae7b9cf8a6a5447b3e886a76c982e56fb16903cf3e7a88b6703aa2e46f96562b3a5bb287e17d98dc7a5a16e57e9b69e0d7a619a44fc290999f12122c37f12359c535e9ab022a3673b692cf2bb01d1c201087806fcc20aa6ff5da1e48794e85992a614ef8399a9640e4853a9886784f2a61221a59c6ae6ae223eff63a2e897203d8e8210907bc901b24e7ee47dfb4def7c11e2cf04af71f2bfd341bc7c1f65c156d3ce23f6f4f1925132fa9d88b4a135fab4156c9229c5a1eec147f162de42fa88e7a4d1524e9763de91da9b0d72b9e7272ca581e54051cee797559a2e2abe5cd1565edf0c60d5af3e159ca29a72b9afbc287ae14e06ee083534fa819aabe7325c516739b1798bbb79eeb33e69443d8f0ea6c7872c2c9c5ee5ec56cd6f2281861573c55dda1188262c9835d4c594d8e64bef823cd951ead7bddd1a619ce901bc2f138f5f01764fd5e108712be0b9e82d22007fd61814167c1677b1b6df7db008b87960db55c9da0e8b53b557d49099803e5c1ff83488d55c7aa61aa851ae3fdb204341d0ab193aa7c10a3eb7978fa48d2e4ebd3ff6925b72181fa1334d0279f9b941dafa13d866711d6b738fbf722add7c6f489ae6c3c1790002439e24c3e2b6109bc54ee628f1dd34e2f695fc61200c194c8f8537367bfe94f703a7c91859e57ce44a7955a86f11abc1f6d6eeaf3f78789ee968d2b1ab25a0122524dbd3ecb27028dc1eefdf77be05430d8efbb6c065a4e82b68ebfc9dbd20af9966d14ef99bb6fec0613b3f49f815297a73af7ebad824620b01d427f4217c4fe3060ce17d5eb254d7df79c21dd7bb9563c12624b42b36a746ad4a39f33454ddeb363b4679554d1aea99ac7135c74d601c06098139ee33cd959f18585a90300ff8a3ce66efd4bafd2123b75550e844d2aac10ba94ecd7b2b7dbf0ecfa56da829058e34268a6bc52e06229916406887906a428cd648e4e688b1807dcb8d831a5704f880cc6ae54ad3a8c52d8ff2dd6ae8c709380bea08ebabaa8f709592c287dfd48af413ca7805c6c2da844bc77121118facabaea1606ea9317fb79b40b409ead3d282bbce1e083b128e65a2dfa02d589a9911ab7e517ba5c3f08c4427e9b4e3874705c2a04614f1f24467cc29e0a3791b3f3b1a500b38d26aecac3e4b2525c08b13046d42f4d565abeab8337aec82d3245667d3d6fb03f096bb073aed30083ea80916dae4b15c1133d49ebe1f522d3ae03c14626f6e4f46d2d7fec57c2c7171e61e582893b31c7adf7fbb8bf218f31806f144fee3a0b0390b9a01a40ed4d4bb3d37436c23c1773aa74b9e768fe4335212b9922ab30969893caaeb98a2468f12c2ecdd9428b9d9d15c610b450b2ea10a35e20ddeb5ead5ae746cdf3bd305b7c5c88d5cc6125a79a65a156f53b5529065d76c868381af29dd96c99e64014d1fbb870bd5a756568bfa39fa771d7e50d85bb0d9b054e4f06c011b2587f65cbb214a2d36592c540b22875e8254f3911054e4576f4239f7ec4d9c8d88fa73359a25ae46fdd49cdc2eb8790e406cf83eb43700aef1874634aa80b2fe2a0cdc1fedd1f092c0e2d1a34c2d247f91da48602e07bcd20abef229eed643866153cac6814674128e6bf4f48f7270019c07cea21a6cc845ee68bf48a90d23dc0ad381627a975e4d80cb2647bcf15909fb104a530c7beec1daa480da73a90adee7a3589916457805be7bc8115d2f93288fd9f9decb2d250e99b60f335433e12fbd0d65008e8ff550cd54e7ee0622399922326540d51fe6f5d95811c974602b6a761b431cafdb4453aea2dd6c0f6e96798bb476d34ce1db70c224f41bd1606f54a160fe36d97b7dd2718e282dbeaab211a268ca90b25894ec86597175321d91b6f9cd854e50334ee40aeee77919c482e959c171bc6076ba12aa3a902b0b8d6bb6612add07370e6da1fc7a44041fb85713ace9b82d935ab5ce29aebf0e71171e4b985578f014051112642fc495d8a8a31a737a7c711fbf8a637707500719be99ca037450a57c8019c2bb1575be3c27d21ff21b040d904bdfb78002ca1193d1c8170c547376199ebaec3a6913f2f3f1e29a90425655c57d1e0dcbca84c5a7748c8b90ddb53cc864cf5d77a6a2ffe0aaeb233cbbc5b1b81ebb760fd677b0a81f5a039462c6e615cae5fb1e5000770d115a1579c038cf9bde4e4129cc21a4652b3c5cb724a909f4381c671c73facee39275d49065525a07a6c555bd5557ce48be64cbfaa286516e6b7b6a12942882c7373aeb3410a73eac13fa8016804f70fa523eee381a0314a9a1d6437995e2d707c417dbc93b3c62288474a0e87c7d93c5ccd74c2ca861df7fe31069e90ab03385c58a2aaadf39c0d4b425990f64a1a7b7a1afd9df24ad705ae6e3d0af5b44b4ee08e5504e58ea4129d62f8c60614e9c21c47769b79dde967dd55016266b88250bacbabe91e574149344a2da3561eda77e0f5120e82ae6882a854d4ef2dffd4087653c98f9660c612cb8d2b09b88be5fe1ce287edbfdcdf4dc2717b4db9818a768df216fa5df0ece12fac068b040d69a696fdf42e75009e4ee91a539a772a06af99ad6fbfe00f882ec9af1b3c5c3860526bb34144fc18d3a6ed579af2b472cea99d620b90516e01ea6d8daf408e8448bea6e643a6307a5a4f07313030dbd7c38ff0401db622f428eb50b52f2d34a3c80ac27afebba38508a4e9344dd8139aa3f439ee1012442df8874f8b030c684f32543db080ee9a608de024dcedbb294f9040264ac1f40a4af373ed9d1dc54c21506743a911d47ca833f058bfb32a3cd71d7b4de56813c66d81a712f21a783e849a9e139502d80100d2b600e6abd835a2d542f527056bd67d9944c56e02d1eb14555f3c33523b5744c2bcbdec5394f25f3a8553785f85cb9104a5101a13ee86122f053c01340d3d73f393161de2d790329bdfb499f1d729f4053a1591296cf236d55fa8cf39bcaa0a5c16db48dbc5a8b06499e5c0c152d95fa3c4fb6e5675e9b900fb6ee9c1489bcf223590f2c02080bdc0a83532b3e39b633e3be059301879b1f27382a31f1d2b561d0a971c2bdbf21e246216020401b7479e00804904e2243bca24d3505d6e88b728961755764edc0918741fa9f1db3d4a6054140424efdf60b6094deaa242f19ac16926f904d4fb955708d88f3dd2d6c2d60dbce4a875edb008d0f0a136448cfa59c215bce4329cc9ef026333d3cca972eff4dcfc9e9061d32b1a10386f04d260459000cda828fcb8d10b583e35e9c286ae871af5b0ae9326436f330ffb5ebfa1957a39198f4a8b4d8202f144c0e411f19c005f6dc2443291fd61da5e8a4b84a28619c024f61cc885afc6a142417d62a082f2fa66e07490a3e31380b08664980ac800eb0ea1938c024d6c8550a21a7a0f23ec6e311d46fd93943d7606b9f1381c202c18650b488c450f56eae5e25c802af888ce18624a3e6e6ca52e9fc9c582562720c32d4f2546b145984ef8685a1518c41f8f2e6dc9e51b15ff86268a42939f365d9a44ed1e3440b753cc262eefdf386c72fa168e715dedaa92ba3237924a0601424148d35ba107af208295c2c2b209e1fd4e78642bb8a5adce28a4d23d533d8c3890ec3c942460304c59e8f51baef6ee7a4292614946b25f69e3a6332d3313982313dcbccd7501f6f77be2841fae772871a2158fe9f2ba9431dc1ebc3252cc31a2ed42d8c3f7a0d336905ce6bcf80d21172763e5cb787ca34e56cb1ec2690edff3a6a34a13e65caa3e70c7170d2af0775ccce7374cc83a470d037af6751d7b9793eda82772d429088969cf8697f770ec0c4f68fcaacdc018fbafe0579a572117f827d9397d36eaa291746ee1d755c9031da21c5ac1956c50e6286792992e08eca50907ec6a6a024f81c4a5171fa47f4bab468d4935a70e5b04450bf2a3e86552e63fc67a98e1b84228b5806e79b6db9b6a210b8346d2a55a3d1d905cf1fc3934b68111dd7215edfa21a2a092d7389aeee7af4253eff5774fab057e16435d5109db3d3ef356ee854822b2ec753cc470a2e470c734e48a218763bcaf8264a0a47e1d150cf12b1f65600a09bc33d17ef33a0b7a7a09d9ba948515cc53c6aab6b11d550a30831ca539052a3ae8a93f54994109b932181a8564ee8723002d004e65900233d2f747df3f2406ad0c93dbc7c56ede120abd6fdf8a6975253fdca2421f6e884900ad4c76b501d7977c923fa18b5823fe7881a54cd3d3f8c6e377c8e402829ad82ca901916f24245d832367d5982e0991e8b52a7fd8c3095c611f25ab54112fbb683c764b27cf335f62951349593ea529af88d1427a94743f62d22d96f27f37a009da35b60f08d39b0068823e2b31e19edff0a27f147c6419ac261ca201c9e8a94c8ad9c3c56fc4ae1fc659948fbae1a374417d5432fb45e6cd720e10835ab222745d77f4a10bd9723fab6713a8ea5104bb6ce61b354aa2368631c814eedfcc7343031af806e5f4a8feb9f14dd79e37ccfcd4fed9c052148e7733623dc20a144070326e9bcb3789720304c1a4a990e1f4b38758b42a7a7e680d92e1672c1115fbc207d0857502dbf8b77e1052f4c1c7a0092bff8d1d3f464237ac9a5005562dbe74e9a75d1dfd9baa99ccb3b9bdcb744af7b1fdd865aa1a42aefba88d82b6943656b0cbe05650dc8e6c2a856f9ab854d2253f414b816040bf3407d457f1017b60510c9926c04edf1b3a6e337a5eec927a3c6030ca23aec730451f85651a6d2c3561a68e530009b6ed110eedc3a386dbd7f46844bd4ddeeaa47c334858d99973187042758346116cf0c9432d38669cf4bbba29090ae100dfceeb430fbd6b9689c445661a5f7545d0311b30ef990b18c14e99c5b2739fd795902e973ac9197e62d0ef5136b19c07a0e745eb8ad6d13fb738ef03dc0af3554056c26948974581105ab8f0b514a145d33d832e12edb08fe9ba31a7743c8b5f41d12a0828e7d4209bd276a40040a30c253e84a42e7341657d800a346c8246ec1cdbfe10d397e59abe78a858964b5c032933683a948c9a194a857540c16cc962cc4384320ccda42d34dbc3e98357871f568e98b8858a61eaadcaa266a6539b14c24084199374f2f4836098e4deead417200be21029d8db00ea93c7c3eab5306aab6ecbd4a3a047a2aee77bd0e8030e51afa0309662969cccc2d0dd6131668539d4b8633fdc6478d482b449c63c627a46785c03a8a71e67d59395c28979e8cde6aff9d766873230a02e8818518183d695c8bb3e1d4324dee14b01d85cd9a6f43f049c8990581b3bb2885c88e263db1cab6af2689639401c4681c50f0338977bc6b61ca5cf9f4728516795e0b42af3880114785b8bd1205b6a5b50c0e9b42ad4f91434dee75ae56c946dc0d9689bbf6c6dc1f26bd8e4f919d15661f3d7b9bd19ae1a48cdf5021de29d33e36cd1ba59ba1422d09f5b8d179c027ec1b3e1f67fbfface34407cfe7a033a9f7e97a514ff8f9fe05d4d4eb535d5b5482213c8c6a50d35dcfe270452fd448032fe92f64e325e022333ba09585438a61811b185435c26991e1821a1fa954fb88b4441970236ac426a8fece155ae68b22675d4b3478d7173c5948ab79063d2a8d72f151c31185102f6663a6ffe34e734ec0dd6f905c928c36c2cc9b60159d9e741ca578668da78628e43208baf252807bf7eadb9709bbe6b39089aff817b95b9e63849b05ba51aa1cc4039bc27bb7e0b1c28dcd9424064ec0283c17690cf8a28db0f033b5438eedc4baf8d742aff0a53f022c20ce7a654931a44650d120f05ddd4a8728676d7d561e08e399ec2b7250d21342b6c8370763a70da82290a938629cbfbe9a932dc58b47dd83472e044d2f4bee1d6176df7ebda50b281d3c1f792e098a9852efcb269fce606222a827ef40ea4c91ee09251a25d3dff3b7c43dae30bf4c973c8bb60e2dc31a10ce3b4f7a442298a73e6fdf580fb04c2468dac4342f9e0c57595c169d5eeaa4023ab449813ba07ec71811000ed2296ce42b7e42e22d79c4f33d30e52dc8067fcd05632f54a03d5da662b5d0451ee10d2d0cf08aa3fc81d020706ec6149a09f214bb4711ce289487cf02946a494813e09ab1cae1a4730eb117773e934659fe58a7b1b97e5179be462035c9233116321d5423509150d7eb6c4d0bd4c2a4d846ba17364c2ae7f999c755fe6de436cd88036fbb9126ebff9729e0c2b187c5440da741120c036cc4b5eeb5815354ff83dc8729aadc745109e8bb46334635e24828f6144a6304ee1c30df0d3c8e612ecd04be1e9f2113cbca0980e6517810a294d5dffde6dd0f2e15c89e08dc1d831bbf4ebb7c11126f04704840c539bf083082b52cf05dbaf904f424287138a59810ccbeb6a55c347e78d6a612947745a0819f37dd6ec04e6d9938e9f7c15aaf2aec0972666428630d2a41158284d60ec93cea49b11e9241f84098a614b3978c98f204eb9bc83296ac945fd29f007672745c78cdc49f2cfa34fc5a260fc068e170e060023ce7c5cd600ff4a0027ac191a48b44f3cf7b5dc1fa51ac0f5ea73b22d17bb63829c06ba280a262fb3bb30b44d861cc1c11ccf0ea4325faa346a4a028c64c63a4fc65c8386873e4c7da2f6fa8d2a37675e0127c8949d883f4f46216537d5ed5c48b462db4c5b6b09afc3a81cf842df2893fc68b5e995f3f1186fc28091e9be2e55e0014e98233027ec159aaa6e21ee7faee181936198ceb21e468bd332ac36a7d933c2fabdabaf03882a354e10a16932b6762b171624e0760446e01efffab592db52479869517b5bb6e0056a0b740a663a51890dd04693bfb01f3845ac89792971d450ba8dda0b4365982c07a2d34f2b3222adbfde438641d842b659ddc59292613b5bdc68a996609c93f011e650c507e14884c29a8bc1076f654401cf0d0b3cd33e66a00d77e33864f7ffc8d6cb280819aaa512d7e29fb98367494bb0f4b84c5e41c868fc0a708194861899a6b0d2d36045a966bc5a4849c2c87073f3d8323ff9bdf332c1f044c3195678b959a95dee5dd702829014bb8922bcf3949d7b5775fa19691344b8b88e61e0cf50df3d0b4e4336e1f9dd3bdbb811de2a59ee19e89ff20fd7700bb6c6af0b30f1e96392b75274e9568f804729248526484040c7684c307cf801bfb05c7518cf41a6d32cc39fdab3ca8b8ba009d4b259ba4d0f2a82e6697ddd12d62a32a6f05ef1efea17814362c1708611a41cbaa0c346b81e3843e4188e397d63f7e2bf23a35f24687a90014e0b4a2ff47d6e4489a5a7d4885d7ac6aa0d05400ee084366e0a76cff1219fbc5f6be2c4c6ee63e768d6807046236e540359fba0378d531507463fa58b274bd235a76a08f2afb67cd829e3bc019fe494ead30baa225d57324aaf6a8ed6a5d9599340ce321a6617a762a2eaccd25629c2b3c199d47759dc062a73ee2688b8d801df48af7f6e4b6729bc2982618cc34856b301bae21b4cdc5e52505b2362be33d69a64b525fd96ca34d2e0f35b4ffbbd81ef6ac5d3534527a11cb4710f658234b4066a69d1af11568f320d0fd9afe94386e7a10bf7a51d9370e824c69408ead276be5b52f94fa4af46511848062bef635c6dd0dd8dda7f92cc1d0a4dd04ce51921ec94737856156a4920789ee5c79b0a4e2f564bc61befce75e7bf04c7cd6ee4b4c0191227eede4a654672a9bc8eaa7fe9727c8072635c310d31bbc3414af068986e72d8bcbe7115f9d9f404953e0b5ea74a290ed9a7d1305d5024c0b4706038f12c4b4a661a266adfb228a1bfd6011bb430667d98865b899f802573f15dd0250b84a5a99b86ff9b2b62d3190c740a768b8365c845113551c32d0c237207b93c414028118ff4161607a3296ac24248c58819a261289758f25c45ebc599b253f5f0ee54275f15e42e1235b017eb29a7614f2b49484cf80a0111f48852dc544687281c18b9dbc5ce1328b2ec72a656e524a4097ff271f6646998a1e5824c983cacba7838354a4db83ad637bdf9264c44be7755240218f74423b3de10f25644d6f12fb99deedd25367b830fc419ca1e0446512c694b3935854e819c4af55a215755b1980af8ae3f91d0b46f13d249a92936265249efd84a52357746e7ebcf77d3c2ca3d94784aa399629ab05db446f591ce9ea001a582e3485c9d4465a9f5e814713b4b89642335526263fee3f4454dd6cf5b9f809e0374c485134cfc81c1d5729be16215f1fdeaac9002c4903b35e6792fd10ac951b34d772dafee6322d388391f5e3477c866629f29d96589873cb024fa49a3e698d4569489dd3b8be4c19d52d8d0acbd315e334ff226f218d4b71495cb63186e41a5c92a309ced67625d95397a9cf6f6691e323614ecd4fdd3aee8e75e1abacb0fb8e540b9b9a191cf18bc72361113802cb0e27bd70da11fa35f0aa23339ab93d99d2ded112c6fe3f344c84632d95910cc0b611e515a2343fdc20845fa865b310a54ce4e4ca42b629ffba75e494475fd901d14ba7aa6402300f04e64791504e09db588557fd878d627bcd28dafba2e777e133996de8bc8780c62e81de39c0ea4919d4e2daf831a13d544fc4fe5cd554a762fcc4860f5d60624cd128c418317cd97f29882de7ccd0439f0a957bbb99d08b36cbb3bd44475975a592763b67c0cade505ec2da04f37d1e690edfce574a1c732f227744bbeb2dc23e1ad74aa04ee2e96eb96bdcfa50c73a8819019b528500e96f765f7620454538b62593bcc196ea6e4d2f6e9286a5669ac18e66aaa5cac0fc89ce879191b87208b2bf6268c0b0bcefc2524dcdac0d56901023ef627df98e1eebe4034ef11deb9bb1e590a22d23b666e45b5679b1735a8df572cdb986713af13b4798087dfc6b8899fc62867ff8fa1cc816ef2b7922b3a1d99d73a0ea8154dfff7df9e3d63240d3402c71960b3be7c856dc236640297208731344b65f05ff3ccec70dc492aef387c13ad2ccedb1ebfde68a44495e623a1c1d6fc7265ccf143b06adf6845e0ea101d4eb321969d18a2ba31417ef09fcee96a1d4f736fdd13d723e04abeb8d2bcecd01398c641280fed3bd42361685d1b604a163453dad048cdf84b12cac30d39f092d2f1415ba148be90021f0ee3e35b85a9bebf4dc19e42e38031e9719c82eba7b8c797d633209b8aa76ab44745e8e11effebbfad7da5a9c25695d49f6c2fa6a586ec24bd2eb6c0414238398f26d72fb44319c833065929ce28efde1e2b9a80a6c3e4c111290e0214d9db9fffcd652d74ba32c3aa0401046ea0e5e253cb40003d01d03702bbeea606fe2f9d3ee8517624aad3bcbb35a8677eb507e03378c102220491c441d8f5403f141620c86e96dba23719371249c732e715a334e8b53ba6a1bb35d527b3321a8a626b65b24e31b95123a26772da5e92c37396e019ce0dc4c766509c7c1877205ce701900acfdfb2e5008ec3913bbf46d3bc8d005a7678ebf860aca2305a31017acda44a52ff90ecca63c066e46695c24e8354a3c105169a5141a101bd712918aba4b48ec7c9a1bf219e043101c6d858447cff52bee3c7b53bc865fd85672141337450a8ee54af253503556b28421947080653f5fc632b36ea945bb3735b6548543ff23b20207080b401d48bfc749422c33e95cfd1cdbd2b8f591a768739a88a6ccff57042c005b8e0211de2befbab422f1545ef4f4406b21d654eab47bcdd965315c8063ce560aa872c533cef15bf5315c7e802b55fb94c0c9d90ee8e5fb9647acb89499c4a22581dcf157bdc200b063236f47623443cda8cea1f1fc3f80c0202500b903c5b10846970405beca4122b6a7a0fd95105547361401d9ba865ec9935ef19ae6d0e2302cf778e069f00942b608a057caa00005f17d788d6127230b2f196b914d3ce935e12360f82d452fdd5747aeb1d53ec95c97106584aa286bc117db45eb6e8ed26a08afd1d6cc9504f51be360e31212b266c2d35277c42eef0b6437d20c65dba809109023d0609b81f2e2127c6a2b89d3d8e8f171358ea39749d00bb4ca278ed39b4062ece41ef4a6c5535d8b9dcd0a23036080ca29ec0119a2176d4228169e263a03b93c00e8b4d895356794f283746e5304f12cc94959bc40129216372a3a19caf647dfaa44f2f729960e9dbd363d44865ec06ec121fd065f1bba1494e91f8828de9184ad9fd985013af036326f706d491197cff8959684376643a30816c70eb8df257681da17dd1c9f01c4e3818ed229d82f4dd20b7b84b6d71d18f7475601b01262348c16b20e54c89b8333c5ec619b26421b36fc5030888202296cf59ae8311711bba03cf8995c457dd043b9046d3338f5ea2d9d37d613ad1337e2d7409fd2e6ffad54d088e99e186a997fd5a9388de7d12f7c0f8f90be63c1c29a8a498380932f057e2e8579227d146559c0e8db6c1715220ddd404d05b4d2c1a806ae172c6bc2b9e6fd56193c194b926ea4dd5245f5875cff7160a80362bc3e86b646a54ef9651189622cbeaa92951fa2ebaa19611553ff11e0b2b0b9b7f725f00c2471d9852fd3a0cc717aad3eeebe7c2e07a17c6b1c569c77677a8f7e84fec8c8395fc4eb8e7a33c25b2a740963c0b25550bf228d1449c388e34d183f4508d7273fb0ef62409294abcd922e5cda9351cabb8bf3a48ec8cd0c0412cedc59589a24bc5e866d2198648e221c42e1c15d662fce2aedbf643d88f4c4ea8eb681b41d190035c8a7d9a0e8f4f610d002e35a7d2542baec441abd877b543b08ed758c199b585b44e0674efff92ec15a5c4556bae279894b9770ea0371bda071e63a281c3832850c5c3ad0904009d0322116b034198370023c220c670e9cab3c01d2ddd9209d54c50d8d206bc1fff2706b56890af4ca3b39ec210736407e649084ab15ca6f9c4494574a5f07f28e57188e211a60cb724a2d9341fab22ff1b2838cb2ddfd6afad980b71d7a566a6ee40441bd5e63832daa32a9c87b5591c74dfe49666db949f632a90b025a853144439e6af62492fd00221a39c95eb03f5da885e83382428f3747eb8830d4b805e98163486c6d884bf67b7b380585f838d4b731b95c757dec6d6363db01c8f39c3100fc0cdbe5dba47a3f576acd0dd07e9768d6cc48cbcddb9cd8323bc03529d3cc5fdaad1a6f1d09d890359e6126407414f1e4684eafb4fccd5f446840fe4c8c2df4f7fe05fd62c8c28d8094402f2ff38d20b3816cf7c2d7eb3785094f1e0a94292c2e51e9706f783f695cb78ee0b03bb3a3659d45b88c0d2a5bd90e5d35df7a52e8dfd808191d8b242e3e0f5f0059bce6ebff7d733780b5c8db8bba2bdda161bda19b88169d522890d084c2cac358bc3b0dcc8976347007b4a07989b4c82602c982909010a7ec5a1294a9a80881dfd4d0806df0b70efd09fb63ebaa03a76a703cefe0a763511b827938c9ec17b4d89d8a759533caeea63e2d551a84fc93877e2ddd1e161722081a5a1b7b036eac97fb2f675ef9ba251ce63b9288aa5acf446292df60227f15367280052d8f2e37f298ff8a7cda220593fc4009c809f13a7e0bda6170aac42f7763f5834d526f8fe808b24e2cb3900ed9e86075a8b81627440dc03bf675ab182b50ca28b8077aa1d10ab4837754413c08dba591891bcae0742cbbbad825d5b006e0caf1880259cf77e20050b7eb0a4a9256e204772983a347f0363d31b21dd202e615c8ec8f0803d1367af188c48321d4986b96da2034ac373a0a2a15a6972615274ac034412b54a14f2848b544095515da4a4c2c0e332459f80fad82ab02e7ff55f1b740f137c75f11f82c6fdbb5e781097b0764162d2bbdbf64746165b1416dc9541e1f5e3fa365e0fce928fd9c81efeb394a02137df20dff5de0a6e5a682a2ed420f69cf3d992ce228399c4131478839bd004d63ff43a44678998250f4ca0beddf7c4bdc57bf7157e4780ca838d9f835c11542c47a48b38325e31f66da42cfdab1c6108a734ecff971a903aa8bd45ae2bc7c65ffa61a0b5b8a6393bde93695776419ea28b080abed8826cb2001a5917a7d8edfe531f9ff4d95e087e410ebc84198e3288bd19172178f3302cc87d3b7afa0edd64c40289063b0ecc2eeb01d677413c698a3b8b1370b5ec4fc38a1ac56e1b4409c9f396c65e12d838e540c9bf5769ad1319c9a08432baf070d897c01ffa6b563304bbf669f6fde4d4c728ce3429caf3326486954148ce65c5be3994486831809f8b52c574eefe6a6b966766d61a9ad01de39a0fca6b1a018679893a6e156e4235afaae8c2901283875820a561319433b15abc5585285801747ef7f4dd86e2f708d45de3f9703f0b4bf07515c9c7fec478b6988d5322b276055654c7b07aa53a9a7547670443fef45276b3dd83a59ba15cb937b9ca0c621dfc976876315f1cdb458c5a36495f159ddcf55357b05e6b64cad255ccf28f5706236de2e3884abb040fc61e37e44399a6af4ae8091ce2121a397359adddebeb56685492d7fa46c7301bfaaa22484c8d22a82f35edcfcf6a97724a23fd58ed6e173b3c9bfbf16f0ae7838cef4bc4c1763bdfdcbc19d5154aa19f3f49f49862f8eee0758867afe26b14346bdf588d5f184a97a24a27cddc5fe9d3d32543a83542071f565c37e5312880050d9939f46451869b5e1579712b02f2d780b78d4d3fc02345d6aefda7e64b0c41196eee015c3d098e105ca217bc076be9422dd871db27578cf21a5a430df614e0f876e761157dcc074e9947a707357ea749e8198112b5c3c1b4b08ebc5359d74c38bec99f68821afc2e8d08715c8603ec09ed6db405ab91399df618a4fd606b0735d71922f7d0d7edffc61fabf39f221e81b12bddd6a11d3291bdfe0f77333fe996122cd300b56b18d5c26c92dc51649e1bfa5716a0d0b0de0dc2d5ad92c939a179a398106c68f599835538398e1bd2fd972bac43346724759fdbb1af4821a7038df054c1a8d0610e5239242309a168699e1aa8f80f902fab28962052447bc7ff065ac26a5c761c6575667597f0f4e2231072d59e3d56ecebe89420ae845e22f5ae9f88167d404a71b3fa0615f21f82cc1d86e28aab51bc2880d80f6ec534bec4fc55d73b7de520eeaa844df97a66917a8c3ca3223afd3a0221523a17dcec9e8c466cc9d48526ce2628dc44cbbe767286d343a5d657b369f6af806ce1c5fbfa22661f23adbc6906ba292dd3a732c70b55fbb1edd815404206116bcb9585294e33ef6c1e092a741fe94cdb75837360f55bbac333c350ae86ba7d5e474ad7b506ac58a1b644d00529f503be5add63dd7d4be6379bb4a8827b74edb4927aad77a17af352a3ebe9411970b9944d6e15d5541507a8a6ceb28509691facc5126c6e3f40c73c5b584227b4a8eba9f5c3850d03d5263146068a0e22e5aab2562ab37d51d20a74aaebe1cadfc6a90793d6b64dd3eae108ae1c0fe7bedb27c92b54839f5d9c35dea0660cd44c62c062253024532b0a8014cc80fa2551b7ac896e3ed61a153f2f8ebb350c1f8e2c63e1339c567bf01a6dac95be64ac44e65a9faad0fa5a0e7b0eddbd6598d11d767d6e1f702abbca5879e6d2ee44dd8d4e17dbacecdb791af5164b82e57163304b4eaf6b1f343409a1ba111c60400e1ee7174a3e3026d36d0c0e0fa4b3d466c0494ea7f2c01daf67ca40f658353392c866c67e90860d95258134c7d915b5b19de8a65f4a2b86e0610648f234fb10ccdd712054e41f3883fabee0768af5914562421bc233e87d79b4e6149a4ffd0094eada5baf78e6c12db28504a2a927ed1e749103dc6e17ff25eae1878ba5e1f9a6a6f9d550e2e22791069af0a38fe4b3a4c1cc3a20d089d1e787f222b2b28a0c74a9a45d6d9e5540950424a7e7e85b8d7f80fee63186e42ce382fb3007727d50ebeadd073b858cf5408778a8b305d06b840a22b72a5cf5f22817d34497b6af495fe5d2769d80f70e05f95583cdd7522eef26cd5a6f808d293b8e1a94800376c5fcd028739d9c9bf4ae536f68ea6921aea10b851590161307f51b05dbc62fda5ecb6fd75e5ea9a862ea8534e9a7d2c61ac766def76082805608b476d5c17e5f392c888bd04a609243b28b84208d0b6d9c14ba3e811c14d1eb254ffa08670aae5d019c1f01049385ec1bc0589e9db2d3572d44a6c4385bd4d797188ba181a858ec3ab80b14d72fda7363a91502a0706cdf32d936edb5faeaff063da78bf98c2348904e2bcca3815d5671041c7896cff562985ddd283d229f34024b2910c4a9b09a3ca5f1e6c9bb34e588653d489748c21f785cf2d7a44f0f028a3e6a163a653484975b95a710acb1be903e11c0cd6d96b2c1e7c3520bb3bb35bdb7940fc914c6b0c6eb12c1b341ee07f0199476a5482fc22a66f7e107de7e37989bba711a6ecf685686b80c31ef8e966681b7650a20e601404bf8f11a3e3356b4c57c62df4a202faa0041fce2b85e7a4884ac2930c04a264bdc683175c626d4dce6f161b531c6a2ba9aa349e49ab516a4519e9b7569e73fefd31ff560d4d02d0eaf13f7a8b6c7b3358a17dc185a3469ea1ae640f8c57c6abda855b01474caa283abcba97e3bff6f1b004e47346e82c5beb2b7ea45267fa1f15b7203b2a4971345b09db901865b6ec0a323894f7a82d5783a9f6dc238dfe9aebc9813b78f0ff8a6ff33d790366c3d91f8e2566cdd26d4d93a4354ec125f34594c356b79cbc07a99fc43164f2b240bf2526431e616ec2efa97f887429ebb1f9f4ebdaee7530ae603c00fd00faaf8003119ce4d7935510ab4beec9076cc92339ab1f6f52199f4567f0ceb7b2ffa0875e0cd0a2d0300ee1e5edf5f401efa9acf1ebea2de520609595ad85ceee4ad5668dc99100b4234bebd49524d14a8a8bb2284ea59ef452368dee034784d3869f7931437c4eaf37049e4676f8795a0c5fbc8179631f08e8f12fd12c795f23f54d4b8e25a25c380571a23300311e52da5aade697eef4c72a18a5a5fca051e14afb4f101a51e062db9de3b32e8074fdeeaa1b19fdec29d986ce984b0be130d324a111133a8e860c55dc28f080bff1469cde86b5683013d3783e0d31913b6ef2a865850dce322c01aa7c544a2158fd19be0deea1bb517a1fd856cbc81a0f295368454c7f973903147e3fce8bdfed5e30fc4f55e47d4e2c5bfb8577bb38ba3f72a7dcc84ad4461169e100fc74d101f42251440ca4460b757f67ad326060501ac5c70735f83ffffa2e25234bcdd5103cd40f59e7399324623cadeec1d4331bc556aeece4cbb365b01354e5f419501be784764a0776ead5c174d48f62a3c3911d0f4a770903f26c3dc5f15bcf241d228b7599e92cad032307f66eea1946780cfc2a5a3b0e5348f9c929563226af5ee8e0139c19403c4da5b508a8515aaa08c0533f82ab0e10a45e0f100430ec14cd8b029f181c27775174923d3d89f5effb3747465c753fe388c778e718913b7ae1bded3e15a96369cf73d35f7acc2e3099f92083cc81944b56aa89cfd96c44acdaba056b5cddb7ca1d6ebb10aa29a4ecaf486ccf806edb627b463c57d881566d6fc4c5a753e9edfa2068f60c458714874d6622dbf0c7b0b2b527119be856be4570bce6165865ce0d188b911416232ac6e98f4ba1dd4f27d44778b2b8056ba14fe0d8dff2e3e5a11543c2c0a76b31152c03ed21f3184d9dd78b8c1f157775a437cc65671005c24ff91e408b8e3df17b716328cea7ea12f4c21ec442518b83bc8486fca63a8363c53600a9544c483cad4df34b9dd2baa34bd51c11e8b0c73f670d367e5f72799b6d7c002bf09e8b8fae7cc563e750f6368250fbce0aab72d3a08f8aefb4aaf3a115d4a144f911b6f392c7af963001cc9e6e562c6ac6f63c837096f4040cf74d775ebbe440a1ceb4a3825b99905c5557a6429a83a44653a40e4741f6f65b710f6656919cb6456be9c7b6712181b66f1c13682f423c6af6463bbd65356b162bebd0631938726b2ec5e278914840ad1a4921ced363f38c50af957ec1ff811c323d33e4f5397ec3b6e1d0f426bca2ae77903c1d3a07e55554d7ea962deedbc4d43d2f35fe19a1cd662ac58e96078396f65e38cc4b38a3be4809d211664321f03c3af95c78c0a975b6695d243a27000233069556429ac48bfe30b4ff865d226faf5c9ff99e7c92f61c9c8283f1c359381a83ead0ad82245fe4d7d974dd837ee313dc025a1c617bbadc20b4098db6169a3a82b82ef19850575b70b056adb92ff41faa7b185379ee8cae2897b6059f8e46aa1d2381b47a76d77ef1d3c24f70aba71a829512f4428599af566ccde1bec693beed29609f458f4e38217cda05b2c32caa89c3d35b9ff30879a3c89d8f5d99320cfa8cb92ffc26a632d442475dc3f71fc05f6f61b76aa3f1287f57fee68f5b35f22fd7d88b9cfa0a9f14bb2fb588be3a4739f07951287feb138bf823e972303c9a92b1a5e9b6af06e07d36af7264753637abdce48be804c0e43afad2f56e5372d2b45eda6d56d22550bb3a01d10295e7e5a8294dee1dc60c11a1a8f21dfaa84664e41858c7e6eba079b6915bfddb106e45aed5db4abdcf8a7080695a698b99adf0694d2908ab9acadf8e2a41e72f4a551246c2f93bf71b7376331f7cf9fe0eec09e761866048bb4af2bcff31e3b7cb016d243b436decb00771d0feea184842c51959312f71468499071fe28f24054091a06219b330fc53342f1af026006e174aa63b2df7a4adae0340ae76fbddbaea3e597c01684230aa8ec6076ac7a4d5565017030ec87893b0c64494b71fe68f27cad39b9850fe8b903fe9fc48be181139ed1855f4532709bc844831bf9c58d2feb5182f7991ef182eaef3f95639c6f8607af87fd63cd8c552f563df163e3d8390b9c5651a22b13cad7be29fe6d404f0719d6adad1943ad36253e391e53441bf04725cf6723a0229426510055d2217301f31522671a40784e574ad090d6bf5561117a8d9afc17408bb505228656467c9b42838fa05d24345798cb4358954ea03a2d4421160453835e05b2148b29dec713400be3fd537ee94faa3fb8094e881ea08fa00dbcc37399c1411dcb98374ccec8618fcfbb4b7a4ff8503accab14d8f120da037eccbc8d3ec77e293de29a0a40d15c3c5135d82d6c6ed317bae7c163f53731d9dea7ad17e3c5096224aa1315f3d8e98eabd74067e121caee77942a36549d5452c6662cdb5373fc4b742cbb4639db95541aaf0319e1f8799cd1b804128bd4a3b62e869037fd50e201f9eadc705394507f26ead6acecaf54f5a4be78e3866034145cf86e8376b960d19f521ac71907e9bf3453e68f387e0bb921c93d900200613121e3baf9610831cd310cdd2dd0c4cbe875fcf2a3e975dc5684bda319af0412044fd51e9978b80558ad669768f81b27c7601e23efeac0ec5a1c6f12032f92864d2870a979eaee9237e59e2208ea347dd8cbc45299e81957fffb6e1043ea008054dce4c6e947474da2a4afc23b907bf771ab10b918829f8816f4b9681eaa052ff2d7c8267899a618abf5970ee03df62fccc914bc28e6cf71a0faaf530b70c78ee97bbee71edd0a7b91f2cfa88a0ab4af6f7d4b2ccc1fe22287a00b1a97cacd7e23d38210d8a379f8f27e44d342719f42aaaa5155305b6f4071f4671f8187ba9bb41d2e1ef3251023c44591212e23c98945f73766176b51abd64ac14a8a9300d83c865f8dd4580a25651c5cf6c0efb24502ffb0f3c2baaadd9604ea1c47702f111f1b527b6b96d418abce6e82f97c73cf2e284b4d75f798865dec4c8a9dc08d7a3f83be2e487acd0b57a60f9e86f6bec1ea8f17ebf2d6880bce2d16a18799a1ba972f10c02962a047728396a5e0416b3a36a7a178eb191a7bc2124284fe45f8cbbbf0877ec56d5d8ba5effc8166828e80c9b0f291d96d166ffe26023053713cbd60c22c96da93120f7e240440f457dd9c54c06599ac2eb9b6843940bcb384ff2191ea6aefd78a06f69dfb4556e30f0223e6107cccbcefa38f3a1792fd4ea66b5693de1b4fe285c4b3818a06b404950de6deb7148cb51b58bfaa7812c513b2b27cfd96bcfce595f187c5530a9ef1539239dcdeabd75aae13e3b9331d75d5cf90085d555d2610440749b4b4fada936fa23ba3134c9b7b4b2f25adcd435a4bb96e72a39128c48da0e84b6313658f42525ca2c7dd5b6177e2d95029ecda23df77f9692410ea6510654cfc2f0c38aad229e2746b24a0ff62d394a577090102354173c1662c6a4ac4bc404e6e2ba67c80ade429169976fad2a7ed109d40b6c182a2195f5fd211cd1f4238bfbfaa7ee28eec793fb978849a78c22f34b1911266c637b14271f3b0c4855593ddb1d75e141d71147593ffade0521026df49f9cd4163af5111452372334565d202b73e9569e4ae90e4eecebd497f3516453bda4cc9bd468c3c76696e956d9d1d2b63f0c2e20b9990f92d8d9205b934dbdf9f36b42d119439b3cbf8e7d8782e0c02725c37b8e2ee5a1100a3ed639c8034590890285f5443e4bfed11e36d09a27609100356c1db036779b7b5b680cfe088ba06c1e75dd7a3c2f99c020b56e6f201527e11c566755bf83232e7438ce6c032742abb07876c5daaeacc71f4a612581642fe0903fd658d5790e8452eb6fc8cb24e57aa9ad357b884faae190149516e09695ccbac9d61542f5ab2341808b68b1caa29c988a3c1f4a78cd43173375eccd9eb019fe8926035c762a02f20765a15d574baf0d412662c860d527e27292648d696c016a9ef7f7d8caae8ab004035c9bdc165a4fd04f902d69aef5b8606aba03abd8bf1c6561810e916da286884c09bc3eb665b61eec6be471724fa618c5c2d5d97a520eba6e58245004d6487c54a26eb53e13febe6e9836cb1a6afa1015937624b893a352b1d791df894254107dcf71d6a8fd48d70cecfb712249a853770f8e7380ba5e91d717240c82c71c793c643c90e12376063563865e9f8caad7eaaf7fd959ffaad78cb659dea1e892021b9607be88a764008e1364de50cbd9e2a8847c30a10acd4d3ecac35dd17eba229903e0debbf81906be5a88778633aa6d7814a0616ec336056f86384737b16e5873b72fbc4c54b0c2c36b50cc2de48f8a50411eca9fcbe6e188b0fdc3d79a378765a7efba40d8b8fd789f14ed0ac803bda842dc6f54dbdb38575e7ce33ecd4c3fe0541895041ac702f3bc33e18d07b6952a0d20c5ac4b6d616c3ef8d3947e78c8c63262896f08671c3255a5075544428d5626edd91d4b40c577ed8e675e67ff93fa7b197ff262e82a04d0635fa054df91d3dee4c8412d6b85891969af89645ea51df4d014471fe61abe4c3e81d58943e4f981c14657857401c86b403facb0e24c0e6208407bd55600e3526b88498299dc720f286e103501e316b0f3d46be86cf0f37ccd9c9ee7510d2eb102ee790834e30c007a7346463e59bb35149cdd5a400ff280c978061bc7f6b0024d302ebdc31609bf1f422b08fdfb2bd2ce6f88c0806a3303e5f7951ebe4fb963cfc879fdfc76bb85af4e7ce75574a0d68cf3402ad780d6fe356b422178647f4d074ff2bb6de5c92f08d5a1c0061bd6bf8d549b11dc4866927c1f01b2276823493afb66fd34f2c37165ec3a1b1880674eeeedc74634b8b34eccbe2bbb5605d68cd8a9803ad7e9175d0203dec1b7824e3dae2a039c5811ebc5116f63f323ced49a53bf112aa043179718ad8d63ff7fd2588a132c6eafafe1f11c87243547abef65aea958ae79bf31f6469585f60eeb01f1f385c4d571a4242a47c66d5c464422668b034cc98dd40ba2ef672b6848e1b3c0f915cc89a9fcabb735f3c3ae402a66d72410cc2f1ccb13674cb373194ae798f4c24a6030d368034e1f2ac7be759cb599d423260046b7190392fe7a130f48de851a919bd84f034e7e0f65d74064891239e15429b49598e61c8bc3639c3711862bf058879ecfcc59f5d45486b1b8581acbd5382dfa6926365727265cd2a19e5af97dc82a1b0a59dabdd2a30f05fcc22fb8a9e297575745b338958703a43d281ad1338840ad44a42e6a1d9c283333ca585132f0078fe1e8ab80dec161fd9e737c31f95da85399d831afd1bccbed183fa70748621e844e85a6db166d6e407b259f8ec951c63518281a2e17622b88edd64b8af70d0f345906200945ba21e4928f826c37062353ffa62f03dbc482e6c8a0548617c0667959148c9980887bca4c60e363ce293186192a666000e23bc3f7a2e763fd9edd2e5b7d8538d2af297d4a6430ebaef315e9c0c1f66fa78e17ab5748caa020f8ce4487b4bbcd5b69eb09d465ddce6045330106fdcb6c97073515b025dd4d28e4984205ff0ca124b865774af6b8e24cbff69b6fdc5e72a79b85ba519f800d5e410310fa3d9275ada3cf4d0e496f291160b1d9167ab8bfb195ba2c5d90a784ccf17677e10c9772dcdd6fcd32f9c01dad6005900b57bc007a4a28b6a9ecadc5e95fe4c1dc42b1701a78b30187afe8f15da9cf5472c0599e0e0ff17897b50aaf495fa1aaeadaf04aff2c75da05afb80ff9ee4dcd8e6a6c29624e3a1a49f8cae241fe913f5c45ff25fcc0b2550085427919e90ac0bff18874b50145a14d238251b50ca37e14f43a53b3000c2e013e62c08a5f8c818f87253fe5a24976ffb85946cc8e700b20347868948cb2b222138723c5c7df9a953aff539ebfdaef75123d9a05d25b7d9399ace6420d144e52e5411f3c2f2a5b66443b4e4c32a888f566fb670a11a6c664dfb32e8d9d04ce79ee9940a3a02d56ba6ce3e4e893fe8d8d0609dbecd21b19ad4f20f1f1bda7ce9993e725c90c6f6981a20babfd4b9f7d890964d971f352c463fc2394d833935cdf6142b99aa932116bab8b9219de237dc0adb7066103aca6f281b4716a9195cd41fa6f62730743af6d11b1c4b05acb3862762329975f0c5bb2f87438144443317dabfec65437fedd0fcb1b1327f4b87d74a7dc4d700ac8db35e054a411db87d15d8001b108e6573b034cbbfeaa282cd1051a106f926c9a423bfe65d3aec1cbe76d8bfbb0ba0a30fa96fb09ca0fddd384203fe9f6363b9c94c80ce91846debc9a7c8ce870f1049aa0c69a7fdab18e6b2e301b6cf5ac61837fe7294ad329d2ded8d86ffe7980fe4757cd10d5460465dc43cc10e1868fc2523f2f48122bbaa9b831adcd3764a039c5aa1478f80e02b7a5d0f83c2d8fda3af7d8463f225c9a39709149fa70f9ae20a9c24b51fb42c578527974de0c14a3ca9d0c2e1f59c27408dd4e5e86f6d3cf0a9606af34eba160d8f805957b7d4cbefa7e2c4909858e5571dc24ed1e96cdd9e8c01d95350d65c0567a142a8f00a5de4535eaf97e2002c6a62a102a87499106c4539447afd680af70d76645ac041c1efa3298c87f8a0642f3e20c3f94c0f70a60e9169669869a01ba17350a1007286311cffe1bab7ac2968f7f4309ece832eb8d88038e17ee35692a8f70e5a26336dd139053c047fb81221f7827bc4071b8788a5eab1880f46bce637da3d72ca8bc262d5faf4506828a3012a27a546af7fc5b43dfd5a6b1e567f9a060ef37fd9ca29f00744f0fc5f8c4ffdba72fd7fc0b8bcf2cc2bdbc5104838f3740c516e699b42e2bae07ceea1a1d78ef77f6d2f53c32db1caf1838fe609c8111a5cbe0e8531ff2a8e311af98d13dde8cbb5410e07d73950e2573c582eaed1f623cf1d21d6d4a6d0d108b562e534e5a19a051c0f77c2a21113d8732447c92e2aa40c2ff258dc6753b82cf71541e0f35b6040d925145c9f0cbf95a3215c77dd4ebcddb657d0d8efdb9ffed1f25695b04f06fcef6e076c7fdc4fa92e57c61d84d02afb5064114a7a9d4223d8d86587cb004de73644f471f3b1882f42c14ad6683330f426e45e8c989178b331e8cbacc51b83a9a7e8283685973eb96683b3601dc22236d4cb85c822df3b98006053a09f81ca3b283cb58140399d78e4023a66c4dcabd6db14c4ede14f32c20be34e3b5f56ee336ad038efe390555292eb2da58a502010867337b5e4eccafd1da6f50a87e117693cd499ff86292c0b7287a7338c40b01d5255cc9eb60557e80e91629b48563f51045db726e7b69a6ef11b75ff2d898e8e52c70e4254496b41a751f6ffeae059acd04f1ef02a4961dc70008e41fe6d9b4968fa91f3b6873661eae3ca34a0e700d14928fc43668ad66940d6fa638802d86b9d12361dc40ba1b3030767392aaa34eacf0088e181f5b5f8e2cdff802be20c982db56a69b568c31f834d61e32f1355f21a102225657a1eb6f83ae0aa4065023c96513b682b83f5312e0985dfa792f56696854532e3349d8703829fd4852b292282bbaced6d8f7aa3fd196a02cf9ec0659ac6bd4a84d2e5a04636852147abbaf8851f97258f35d420fda1fecb1ec1200d8fb352a506792fcf466e61820c49b264eed4c73f488a4491cecd71968aebd5b218f4012a6de2b4ee0d18f1ec475e651b5719f239de539c866938c96c71cc70f5f00c3b89cd3bede01e104e9c11496842b7c697710e4e3cf2f245a00dd768e152cc432a4b16f0d2c0a65032777f62dea4e626c92e930bcca248c01327908ff661acc2888cf6052df00624ec4f43523b92c462f141dd877583f5702b6abcdb1422a7c17d881f635378d477806431052ea02dda19189fb02958c2644e2798f76cb9ee4c3634e5c0666db0451b99d81460d06b363aecf9b80a3655b69518b0324d7b70429b02cc287c6a1ffee4971215a9b5d59b8dce41579e585c9b42108463c8d8896c0a9e30e182d137f50d8181cf8a4e1f9416a3ad6867f3da14ea8b797f0e69f0ed2ffdd8a24aae3d37228effaf899f9077f61a6fa5658dcf54a56fc5f2eb305fdb36010831d240943aca7a07f5b9cf4a0a6f8315c789fb17330ff7cd719c19a760f5e2aca220ea91462f0a5e9c6515113ccbef9e0dbe125c1a5baad1bb845761902439c817d4ebcc1f18fe552ea07ddc336dae52e4537501c9bf0a09e1521c5fc629de3b6306f161ecbb30b5d1f335854791632bbf29248dfe26ba401d64e04fff189eac4e6a9327d15e5be07d1226abfc57e0f941cd5c23d3ec963b3366b61d237d7d5eb88fa9f14d0a9a11de109e8841a83bd721189663da5e11fede21100e92411e17a1bafa11cf82ff872e65c10ab8aa28199ae55001c1f921316d0af73071c48ba3dec1ed0f088a7d72502e5548b3b15d1493eab2682d3eb1cfe2cd53a991c92932e88fcf85ec50ee05218cd07212a016313bc5b6644682c0cc45f3f5282a976a85188c2a7141dc1c28a0f18ab6f3e1043319910647f5522d3eeb397efb8c8b691188fa1c2287500c56e5f801e8c00cdec1cf92672937088bcf45a9caefb63002db5b2117d326bc7f77e10364905ab33b1add071c6e31cda7098d4b09d2de92b82892c7f6419cbdc9f637fe064a85411305778795ada97f7260ffb6666a806bd16046b46f862f7d5761a4c00453c604aac2859f2cc2e83d29fb4a171e4c3ee7579908d5284cb60132ef52d4826360dac292397e9c2eddf4606e0e49e9ce2097779b98eab428b85c8202627b59dc4f9d8bfc0b97b1375808c224ab8639bb2be11cd8c8538356dfb762ef237dbadc186bc76c3f5ee3717eb92b72b591aa8380f9d700e09188d7008c68cda93bd4e442c89cbf45a8c2e294db3ea3a8c87b280fa640d0c11ab69c0c808e4a1c708f3ba61a0932a04767645180811b0ca07d4500b0267bc40193d003c17e77a053b224770150e4e55c52e3c4bdc15b0490fa72af40eb4867a5237159327044100f303aa7c44874877fcff24db4834210a1bb54fc5b5d0b662b907e52edecfec0763371a49bd07870ee57573c9c60d470a211b4fe0b48ff3d26b4322fd942616ba30fad55de6f398ced03724f32bcf921971a47c9170c764baec6ece28bedbd63664532354425a0cce27b395896f9d0859b233bbef5a8a30b23473fb5d37a011d0f584fb98c79d331a3a13d10d4295c9d1575f327530b150e2290d157221361853576da572431dfd16c1349f85f98e6da9865ededb90cbf2ae71c6b9f34de7548bd68a3d00314b94f9681f7e15744c77b0e88acf46e0dfa6b5771027116fb27f724071100f3be9c318d53baa180f30f0e744399bb0c70a3d3a6630c63ece46f98346d038b979d5e07a4840804e0693794c2c593e0b4cbbf49cf9bd9ee8d331ac7d1c63f23ad9371cdd7daa0920e2e22dafae1446278aeeac553a84ac11bbe7a400021ade5e603de6072c76f4fcc0a9037b4a22784880c8d699b5d84cd56bcf07f45d78503ace1c1776e1634abc26216c89d2d53d6ed5305040276baf8cbd0d7edb0478e265898ce02950a55c092e1ba60da4bc7d50e1860ce86c40a34805f4d0938b7343a34601664e4b3f796309a85413b1de73fd0dd906aa312677cfb10df25ed15d953946d4ee43d366f90b774b0928dd0ee36b23659c4118086f82e5249954ad968eb617b58a7009c026e01dff538f68e9294785d7479c24c4c9c413a3262aba1382009a3fb0bf8a77dbdd5aaee9e22a0750b892d241402f2a204fd354e01fd04e65292b0413787662c7a96f5332f4007d8efb4e085e63bfe92a0b64588027792fdec07bb3c2fe064eb9fc34a940c0a8eda5770426697f30260f1331f6726ed7fa20b0243245e75c28662cd690a3816d059d7bebe4eb798f37f05a0ed996f29442d3623da081c8d58ff2d093202d2531dad009ae87ec17152f1c81a0536b54e05cc5b7929d71fc200b60afce7945f2a1ea702a2bf9bd0cacd0ab8e9a7f50e4b013fdc1a7c669a31741b458865146098b062c30fc40b6562b8e4487929ecade6982e9545a0f80c6050cea4ce9baaf5393ab062291893b2a122fb72839e0439da9ee71c167499439f0a86efa16af29c353bcc2d5368dfd79d80fd83c5d1221677c7b1a3c6bcee183a9e0c72ddb527b99936ea5e237142e3e100f4e1300c97fc033937aebff0c3db41e8fcd5b9d8493178fd863431a75c32386fceb9e6a6db57148b2e89a7b868155a85feb379d82512ed8676479b2230318184a8d5ae647c90d8cddbec8feedb1e298cec2c93b4c03e5a29e37814257ece93daaf82d3e73ea5e63847ff3c01ab920a6474895d83d036ceb59c6b5d592e686e96f1255c1d902644cf3019627c3ac31bad08547e1b22cbce589f2d56fb44e06c61386204c88590ac98bebac8e4f7ec893b3fe249c1bb71abe84e202854f08a308065457a03386cc6147d9705d0c61453e7f898664775e5b478831f82111c42aa284ac41f9493398f87ced39993929f93c24574b1dd4ee6ac8db39877a68880adffa16bcf49bd086389636e4313de1e7df347545d2b7e4384705c21ce4d9dc1b186be99fb39b55827aafa5a85c3a45a8c6f2c8857d4b24274d1357668fa195693a5caab946f4a21fd2a097f6d3319a9025a9a441d93d7ea779e9aba6341cbabbb465e0b06925de46d1457d9b6bf18948aed3ea2e1c792dad771389cb5f51b205cd2fc2477a523afea804ff611471c9b6f0a8d035488622fe4f4c565aff80880f22e69c95ed981c021997e2faa3cbfab119635ed42ea85fa34b00c942d7f45c5c964404373798d5a1c26f3d797355042549ab4581c10b845c93ef305cd5f6abd4e540bd2fd55bb6ade4fe4e08905fc5220af5d0a89ebd7c929f25b5cfd1f97de50fe56841424d124ab5e98baac55550eb2ef9e4878917bf9c6d096326ab5d9e0a79521b04a86b6713f37e8f90fa7b91c6e3831b6036f296f76839908d83ef83877ab0986e13e31ad2f0abdbf58132cf97855d54f0ec632ec1a981d951d71bdcb1029c704cb314123b5dc9428126da9f6b18956765038ab4a6a22325a24fd1cd459f80df86c0c7eb4c6b5c7addd4afe13884b471d61955a50b1d077ca4d086eb515d67da72b3d6936eb5d0e131428efe243a9c5d78f7da51825b73f0ef3edd169ce672eaf11b0134df6a6f0f990c276c5709618bf1d872a7392eae3af08b3543e4e2a436fd4fa446547fa22dc4821b7afd20cfdd26cd9d1713015c9e9dc1d17ad5339ad3ee486b9b0a6801ecc19f9fc0f022c583bf5a74cbb056952b1c7ac1132cb4129583170c176886da6298b4e3c183c442a1bf6db0dca460b1e714011d4d87e55368f0fa5554b14f98a179fc95fa24737179f2bdcd54ca6c6593ed7ddfdab32a2054648b87e2fdaa71338d2ddde1d24159f7266a410462ab77a619230e9d239f500dc2f7d5ae7b681ab90047eaa7b013dcea5075c6fd5d879a12ac34b962d051b1bcac6c6d4aaacdb47a2e9177032148336e362b0ea5f206fa06c0634eb3913fc0dbf837bc3c121f4307a36a8fcaefc16e90867cec220c1ccb114bbf822ef9dd2c4f57bab9f8ece3a395227971ce9935493b0bd48ff9841858008316ca647e394808ca6d8d13305b7cf7a1337004e6e6bff4b11f45dac567e70388bf815491f1096ffbb9bdc91474bfe2ba6a2efac0c05d92cd8f00778253ac0feec1debebce053d4687fc802997099f78e8b673d4c93e2600a6537b3ec87cc73e86129b9a426bd6a272798340ba3f952260610e35cab11b3d82d045d8f7113382714c106d58915712ba549573421736a8459f398c1d5ee11c86311a0c17bad6aa5e696f22e6b09b69a6dc3853d2290629ee8b893efaf6544a3bfb93d43bf3b46ca78d6b8301426a57e3e3c83fb4d6f09cae0a764166051c57e635da34cec4c7c2575e1875b3662d9570292c4db201bda875908ad9ecac4682ecddbd58f0c75932908461d64378fc60a5e3381fcb557153f1163e7bbd20311250fc89bee17eb72be6194a0f16476728af447f5faf13630a08a22907cde00505199aa4e09bbfee8f259c73625e03ac32c4473bdadd209acf9eaa1ca016fd4d76ddda08daa5038ca59c25b2a9f5c15f1f4402cbd560fb3c1f49d8133a680935c319cb6b9fc1e569389d1ef0d17b5f783974a35917fa59eb06560d2fc0d3f1ab7a5caaf835b84309839b275cbb285d6713a315d2ed3628f48d7c95fb7d40939b447abfd8105d42124981c1d29ddea46f62dc21d5e2ac6ba9109f84f28ec2ae83de29365d2c14710bd36b22d8f9eb37067a2fdbd20d0161ff82083a7ac8fd8bc75aa81fd6ddd148abcb7a898fdcb959747d2f050413a910a295f651a4581caa116f109b7636c15aed67167fecc3917d62f321bce26074be2880dd955ab8aa74d52445fc551dbacc1e3b4ff48622f5c00ec4caa0efef43dae9b857b369c6c82649f29b0bf04175e274b181df08601fbdcdb57b79a13586d4046efec7ee1eea3d1cd66a162d3982e1e49a08f3189095c4cd534ce5b7857f1c4cf57e342855a95f7763279d1b8cf1349eb818f1e0f1491c7ed6a006e16529e0508cdefb1d3ba41d1c8cb5f4693601eb9843d89762d521e23c4d65a2d17c99d979b983aeab58c8d95fc92c2402207a96fbb2ef7e14d82b7ded9edc52ebd0d0c600624b3cc0a8dd1bf9c0d50ad2f8228ed92ec81ba5b260774a4c3b91a18330d2fa72818804246ab36508904a1feb5d5bd756cd8d80e553ad886175514c7564f9905373dc1b85502a3b66929b9f9aa77b1eddfd6d722133d24d84511bdf1886352d026d918c80e1aae343d63e6635793b28fe468f7f71017d16eea52712f871f79243a499955f8c8b44a0a21c9043f84c857e4ec4e16ebfdc93ca88b177d60f7d192cfa929d89237626058c577769f439be0dbe76250db2531d5e3661e1ee69802726541ca80b38fc8961ec3fa605f341a5a0cf31086f946dd633c147748fb4c77fe0ee152543d51cf00c59d37132a9ecfe8bb3035c637fc5eea3c811cf9aceb00021361827faec09453886ca4fb8b15c342a547bc696801b29f05eef94ee2377992e80a9c1223b63efcf47f8e824c4e1fa6523e11ff9ba39cf0d2b84d49b011fee39343bc8f528aed1d3f41fe40a263d98b3efea82fee5088ecda2fac2a96dfd90692407c2204711a5437eee9c906d78e1e6809d8a9d6c105cab64cfd15f6434885928af9024b17b5fa74d233d750d227c1cb4382c61018eadfd73b812c43479ca9af1b576d6d6d03d5be7b5f696410df64f54565ecfb394e046e4cf40b2ee69699514b3cc0abae8ab4bf82f656a38ae09511a719fb91ef54e923f336a0aca6cee03cadbdc7f78b54f26d773e2acce18d7c31b26b0eed9e0673b0d6da466fdec5c0ed44f2ac468cba30be5877f9069feb81c176b80210764b05b32662420ac3732295c431237c7b1b2ef460b7bc7c6a2d97351924eaccb7705043a961b0f1717a9af9fcd99a1088a0e4acb8a5a42425f49f5072d7d90b55d1761dfde47f221dd3fcc3d3ff9492de5292d2a5d648827de14e38e654eb4cb63916da443975bab23c43010e84275ac6b84222b93739a4667534157ad4503c970f5299c171a03d928b1930d245a9ac220db46c53767822b1c97a7a0f342326e26366a64d4213a451d6dac017b36fb01f4e038c32317855c515bb8163086286e59247c9936b57a99de47e0b746e255230875fc28aac5b9349a77ab89fc9ec2d2c046c56159e3a70b9d862f1612e292e305ff6c6c0a2c9987c197ff4061fea7b106dbf3574fcbb4b6fcaaf2598e27cb56cd0b615850368f5f9a396c52e55ab4ce7fa66753d186854a8e5010f6dc4e9ee9c9c70195b4a059ea834c325b9839a3dbad4bb36dfafc48e2d9f33de7bd0a170b646ae7c15d8a05caec1b450374fcf7333a2036c909c0abad332258270c3d5789696b790032b02f63d396cb1fca5c0901fb45688a3f4e02a4e20a7496040e1704960c57209c15271d4e9820440c0bea58baca6fb18c7aed3634523ad77c6f3565b1cc0327a888c802deff67d1684cec7d202e05203065aeb456858e90ab9bf6801170ac8eb5b19978b4da9b2176b7268d104208d964efbde5de01900ccc0bd10c5e6e24d23ed1ddbc9f6fe2ecbbf97c3b8fcfdd726b1ef4cf97e7b389614dbebbad44a375cb3e8afd03bdebdab22b9bd7bb8fa499e49e0136d239453a159f885fd8311c71c41147f491be018fc0f68217931cc1c5242d851465f0e4a58409dce13ad6c7be894df336ee242d45a7ec19bc246d060ff42ec2eeae3fbfbe89a5a93fd7e4e3ba3c8f4bde1bdc5f6ee57eb6cd740bb77007ea410fba9f26cc987e771b3ac90cc3cbe9945512a18cb29bbfa0273f17e7233ee94b231bbe886118016b1c49129b94a1de92a13e2a5112d90077a0af8f5fc430a2185aeca135d7c35cc52798da557c52c2de12723d8234961896b7ddc2fd4f7fbedccad8ed35f883bc2133e36113487cdd0412cf2bb3924f3cfc83c4d79509e2e179673c3cdf37b766ba9fe822c01a483a552fbf76820c5e132002a2182001eaeb9b09dca1df48c4f004dc4962ec0975b405e3a5de0818b0087007fbfa46e244cf0b9bfabe93ccafa588d876e135ae47fc5148132e9a4423b32312b1881279804662051225489038f14463ff4cfb91d981fd631b89edc2db9e3b494b91dd0d62fb85b7dd7e5e6ed7d19f46d24f7cb6db473a55ebb1af8bf4119daaa75f23d1980b9cbdadc0b2b16b5383b142d97513b0468db8bf88651b016bd45f6de48bf8081d4a7e10c38ea17a9503530ab8c37cdf27e6bcddc2eccfd919e8eb026bd478a4be3e3a0177e8d71f4922a3d7493a555b8a4e5588eb676a259daadf82975f3a0917b9790dc60965970058a3fe6eb046c4d60b2f4325f5d60b2f7b380a814d6abd1583978fab93987ed64d265482eb23d7a36fe63efbdcfbc6583078dcb5e797075ccfc0e0c5d45b3078d8dfe4081b865adf49fa065c820511b8bea5682548fa46c4f51eae87eedbb5117f7ab8c1f3f672029e90fe3cae87eca06b7dedad11175a72852af00c0c9758e1059c851438fef3dcfd653bfa72ae1ae589b1e75c351add960de9b061e65bb061faa3b7fdfc54d72a8e7844d2b7d3d728f7397ce47a6407dd98cf8e8e879fd873e9b7b2c1d965636e873d165244ee0736cf7dde98bebdbd0583d7d7d483bb3d670289eb9bebd141607b784d97e9fa345db707bd7c9b7cd04b2728ed813dce3927c430021e5c820512381e8bc162b0c76310b6fe690908612fadb9e05d9f17dfdc03e28f208dafc7fb90f8b2b045c362bda4717eb347d7a6d72bf723febad69ab73db4f0bc0ef9458b1d627b8865871cf60bbbb40d76171ebdecbed6fdd90b27e7233ed12c17deeb219ed7cdf3f48de9ab1029a59432364a72d11ac4706a87f3f05a8cefcedd7e8e7d197bcaaf2f8b9eaf7ba1f7974537b788d08434a8e1f3394d097f9e59ddcd9fab3ccf380a85123d8742a761c1a1e77e4aca432a7883174f7803c771ddb99bb96fcf2aa74183462825252525054b2c210b65e8ba0ee539e528140a150a85344d43018e1c9ec4413bcaf38cd3389d4e9ee701e1051244e4782893c9f4f97c80e081126218f12181402052a954ba9a300327a001c5e3f1a09048a4aeebae26a6c0394307dab60d050545d3b4ba0428bab0060d0402799e47b958831157785f799ee1f1783e9fcf74c317b088c2e72bcf2a2d2d2ddbb6711c5785183620424a4a4acacddc579e5358585868d0a0b172b3dc0113e06084eedff3ca5bfea350284dd33a0a25ce6085f6efb9e52c3366ccf03c2f0d5d6c919392929272b3f7ef99e5ff6e8e53908110348843f8408918a3d1e8e6489232e08844a29a2284a14813a72252686203d3e974fa7c3ead24088109263e2593c9c4715c2b0640a081181ca9542a755d970225605821850e854422699a9682193ca982121a080505c5f33c14c8a08a2ce0789fcf070817b0200640f86c1e8f87e3b88b08486690048ec6b66d5dd755243df0028beef48ca2418386a669d4064e6e2003cdf43c038542799e37c110c216c8f04acf2a3366cc6831c26042920fe9394545e5342a5885e3b856021733c0e1509e472929a751c1295dd745259ab0c2183a968b4ea7d333e859341a9d46058f344dbbd103275441fb9f571e32994ccf9ee79048741a152cf23caf6627074b3ce1cf2d3f954aa5e7edf98642a1dfdc4282901aaca1e52b56cbe7a767969b4824d2338de7efded3a8e07bba59057110c39327b07cc56279cb574ccf2b2fa1a0a03ca39eff7d9fe9661508297245152d2d2dcfac95af582b67794be9f9741208047a9ef1dcf2bf74730a96f084226660616179669dbe629dbe7216d2b3e9281e8fe759e599a5a5a58574330a96008725acb0b2b2f2cc327dc532fdf41594e7d241dbb63da73cafb0b0b0a0dc7c21c10b1868e1743a3db34a5fb14a37fd047a26dd4383068de7d1f3696565057433150313aec085c9647a6691be62915ebac9f38cf20d85423d8b9e4da7d3c973f3bc821588f8a0542a3db350be62a19cf4d2f60c3a8d1933663c879e4b269369bbb9d1d0c41668209148cf2cd0572cd0514eba593b8d67cf512a2a2acff799542a9d46059768dcdc4786b0c40a1494d39430ca33cbf315cb73d051cfdb67a4a4a43c7fcf2824d26954300975332ca38824380104023db3b6af58db3d07ddfcf98c671a57198d46cf7f06a1a09c4605a3ccb8d9660e707841111e8fe79945e32b168d6ff7a09e2212899e5b9e3d20d0695430c8a609335c6109db769a12de9e59a8af58a8d3f87673f794e7191fddcc0a92e1d059341c0e9dc68343cf2ccfdb594124f69c45d361cf6954b0a755040d5f60030d1a349e5933be62cd38ea3446cf2a17894422d14dc0e8661470418c16e8a050a86796ca572c95cf38ea662fe5211c30158128220e602863c68cd394f08c6756ca57ac94ab7c461efdda80a978cd000e51b041454525e52a37735f28140add17244290c392949494949bbbbbb4124e60c1145a4bcaf3bc68440b8e1084c78282a958a32407591cf159394c458ee352b0451a94900537fae9e45dd3de755d8702189481d3c4e82bd6a813dd44fadcfb8af5b9774dd3347a051326d220fa8a25fae8a19b432fa5a4a47c868453ae08a622f7cf572cee9f7b9ee7ddac72b38cc21688d8c268347a6685be62852efae8e67eca3369341a8daee775e7be6275e7fef97c3e37a7dc6c33052d90b00391e834252c7a66795fb1bc67173da37c3e9fcfdd2eeddd572ceddd398ee36e16ddac02200cf1862b42a1d033ebf21eba19fbe719c4711c776dd5b4775d771a16dcddfcb9f922d205111860cf3b4d097bcfacfa15eb7abd77b33df7ece9baee3324dcdd095371d5cfbe62f5b36bd7b4d3b060ed1a81a40b47e0bc5d4dd33e43c2da8530159f59f4abebac7afacca2b9f075160d0abe4e53c2d7e7338b26c37d164d08f76958709fb5ca8e7dd56765c736fa91be539ea93733628e2934a1d9d94c34134d88304185145060d1c512356ce0059136945145152bd0411493848485820cb04a6bad550b4068c314487441076ba8620c0e0a385d2fa181225e4c4185285c808424aa204357c5166819d4093188200ca1e4094a980c818a624efc82254a9ae80882a843449a4cd0e021c9ab8fd1ce1b53766c04c018630621a5f4ce0c42582b7c85f0546badb5d65a6bcc33d446db02f975efbae5750ccb302cc3b02c9be9ac53537693a35bd5aecc6298cd2ead6e949b9df4b4173f1becb84df3d01963bcb82ecb6e2f8f61147b6318a96f60c7342dde9988b12c7b4c3c76312cc3b00cc3b248b32cbbec95fdc2e2bc31656359cd22cdb2ecca9e7d8735b66f17866118866595c6182f2e7e7be576c47f314629786d0f5b4e5aaf08ed0f187bfd75c5783dc718e375cd34be2e795dd78d9187fd95afebbaaeebbaaeebbaaeebbaaeebbaaeebbaaeebbaaeebbaaeeb8ab165bc2e963dabd7b22fcf1b53c64680d6d95b7be3f8cede19cdb2ecd0d2182366bf2bb68cd2068613080eef5b1cc0121a9d8f13cb304cfb50183b9db3e78c90763a7a4a2d4a25c05367afca7195ab9c9473ce39e79c53d65aed9c734e6d9b73729cc7765df7f9eeea6aad1e201baed5db6c36af3c43270e38a7e59eadadb78fb3d653a7e0e79cb5fbf5751ae7f1783c1e4fadb55639e7b4d6a5bb1c006b5c22d9d5392936a70f3ce73d9ff7cc73774e8e9b1c37396ece39e79c73ce5a6badb3ce3aebacb5d65a6badb5d64ae59cd3ce39a5b475d65a6badb5d62ae79cd6dad75a6badb5d63ae79c73ce39a7b45cadb5d65a6badb5ca39a7adb5d63ae7ac76ce39e794b5566be79c75cefa3ce79ce939679d73ce3965ad754e3ba59dd24e69a7b453da29ed94b6dac77963ca6efb3ce79c73ce39e79c73ca5444615b6d9c7356596bad72d65a6b95b356596badb5d65a2b95734eabcd68e7abbd383a75d5699f6bad8f75da6b4e0fcef3b05316d7c08bf2cacf392985d8e9af4f07ac719d7e1932c197085f9ef7ada3da336e0777c8410e485fa47137b8730fd28259379ecb7b2eef4cc4dc31ae87bc27469ebb1cc7711c27a594524a2929a55a47a9e4382a398e4a8ea392524ab74dce6d7ba7b6776a8b01a36b532e4d86bba35c4f7469321cbad9739a0e6716e866ed341ace1fef420fabfb765677e7a5c9f076ad76bd3b612a1ec32ee9f6fea2e009a622bd36602a7e7e5e114c4117988a87bf7974c191524a296504e2b205fb86eb12e1d32f08a494524a292f79f30da60d849497bd2e292f597fc94bcaeb92f292f29794f066416bd831c618fb313610541334680fe1b7c76ccf5e6b635b0fb106391eb9b18cf283b006ad346230bb41620fd9b5d67a6bcdd74d3d327c69815fe64ae2a96d21058618e2b923c3f0f5eb916168ebb4b6b91da44eb5fcb9b7ed94073bb3d33e9b90fbe49c98fb24a44da10e797da4efd4f87bc60529b00a864bb870e447d5eef54d5bebf5050c0384f0870c9b20c3b5adb5f6870cd7470f0a38af69daebc457ceecdce1976f3084afdf0f3701a482115c6f8554308267bd33de05318e0c5c004715b60ba47a0ddedcc250876c4cea54cb9aea546bf23bd703be1efb522e5b4835aef7a57dcc1bc404f0f2f0ce07ccc30b7e3c2096d7577f7d3de60d62827aa955f80aef0c7cc441e00d12718c08ae05138440064cd57d000fa4be01e521bc6e94f5ff41f7010c022ac4f88ef020460702253cef2ef38183c0734d1d80f019123c1ec4e82e133a6c14353b2258808ece36f8d17811cf173c1f65ab6fb61e5da1052e7026ddd83c06d4d7171b758916a4c01557523751637d79b11135188124efb62db07dcc02b7c346a7b6e76bdbbab9cd4d5a6e87c5db095ab0cc0af4eeabcf654097758341ef4017762aa6bba0c78366babf6d877c6ff1c6c81ef2daa51672b0bdb58f5a3802c72c8c81250f7bb9240b5f60794c0b48b07db45c0ff4984c0ff92d5ef9ebf1d84572eb425d776fdb36d0a5fce7db6703dd1cefc9f12b1bbc6ddd0e9079b95d538fedf29b376fc62eaf48eb4ff41e3a2219ef79dfc6db3fd67ea0db88747af4bb83ae0eca6dd9880e1b46beb7cbcff35e451cfbf37ca2addbee4c4bee87bc5b733e6c0fecf18a70f65dc75af8e6dcc2331247a7eaaffb120f6722a67f91d28a60138e8aa7c183b4d5e04d797949efd8f7a422aeb24daa254954bb74219348d2260321c47521ae13d13a2410b8f6e99723eed60ff5b15e268887e37dac5bee9d1a2ba517ce261794ef39e39c757af60baf0fbbf07a0c6178f332768c52da30bc965656d9a74e5cf0f3fa26ae0f9878d27357e47ab0f395eb7151d91b8d5346896dd79771dab98bebc1fef4f5a397b659ce87bc7e5c37c69e9e5eafdfbcb9551f31acdee0fae58935bb61d0c8b723a67b573f6bb11a33d3b97bfc5cab976f79b737d71bb7576ec6db4f6eb466971cd75cf3c0ecbdcfe7fa101e545e0ecfd67bafd2fba00afb206ecfb7f2386e47f6ee9a7a7c7297dc3f8831c745ac5d8332a5bb5aef2a3e9918fb4cd5e4c31e3b0f7b83e7a915b89764c1059eafb5de5ce72fe9a34fb156aefdabbac0a3c1bea16952ca1f9a26b56fcf32797935b723867ee6cbf4f1d795e96b77adc561dc3784075577d839ba5bb37d080f2aeedbadcfbe78ee83aa6b65b38a5ca57d792713328cd63a9f61583dc5a8164fe07a7aac6a58bec159c5e8378dc02555708231ec3ae4cce0bcb0290055dcb767df8d8abb51fb32f6ac9e077dbd26336ba594fd18faa97d3a393c1c99d8277dc53e4e0250c55dcbb0c7634378a8810da30de101abc1babb4fafb453689462c79ebdd22648b076caf1b8c1f598d6a2f2d9eb46af69da8df5d96ac1c34e1f6f0cbd7c0ca5afdbb75301ee5af6be39bb33add16bb3cdb98a3bec1cdc6d6139576d78bbadedaabab259c54dbe66d1b2c11d2a95944653bc263f518cdf17a33cc53758c693e4a5d7db2182d3ca7fc18b38d658bfcb4e58ebd5c1de10c0be3302d829b9e40a24f009c32554a8019e39b638a0c2a44a7e13d5150a3378c762bcae2bd277aca636f9b8f0de605bbb5b18f2c87a4c3b6994f3ea4aafcbce6b5ebfa88858c66ed8efd8f5baf3baaeed3a83a73d42d365f2516bbd3c5fbedebd7ef93a775ddb396da31ec841047090003ddf17b7a35e755231faaa57bdae37f700fa5a4fb15aaf1e5a8d69fd65a18516e249ebcd1d46e4668cdd3bbadb30bc96ad7d7213e23861f4b2883dbbfa1dd795fb4467c81ee46477adfb4c5ce7398fee7aee0de6bedccadcb7775fe638eee281fd7a56e72f2362e81bf79c33ce6b71ad577d77edc8d56bb5d67ac98e9452aa5ddad51c8ffa6c47cda0ece6312a9ace39bb67f7a4b34253edeb36c37ace6cdbe00e71833b98e2af3df7d933789995f3ea4cd147bf9e475f7883e3975bfde5b8234a8ec725a3d72969c5f062cb6d833bcc77aca7dd976cb9c11afd0dd688d60b4bb02882e3922910b1e40a5b6c5b7fe2c8d16bb9f0e8d57e7c4bee01fd7863e63b7ed8b5f1bac1b1eb8da7871006b4a347638c7146eec7f34da4187661a7ec149c6088656ba66f633f7b907a7b83d46711cbe44ceda64d6078d518edadb1cafef5715b29838252af56ac627576f1a31fc4f4ba31333ea06fe1c5038d5a0dfb34db56c3b00bbbf678b5168e99f6412dde99c69ab59d9ac2d33e6d1746602dcbd37e41b64bfb99ecd2ae5a708c7c0b96338d35c9f5e86bd0ce5fb72f61b7f6bafdf5187b51f6d94e612745cdc6fe7565f7eaeb237d9e16bc3e14795866d7b6bdb96f3b85cdebd3324aa3a5d102418bd8e135d2379bc3aee582a75deca46f5e931836e7bc3eb156b7e67ecc5f580f2dac61106bd1238d4efa7c7ba3ab699ff3ce7ff3f1dae7d1465fd64ed2349c7d1e0fe97a6e8ed935859711816315d8c0045f075d03fdde8d19a5871bd8a9acc362852260eda0430925f783758375586eaf696f96cf9bb53bd378f494d1cd8d47f75c3bcb9773150be93957b1e460b92d0ed4d8ac5c3bcbb5fea8bbc7f2416e5bf976449f690c025d63b9add2592efaf20d066c54be23faca6d99bed25a79ab88ab587e62d1449f8e90d25bcef209517acbb55f62852670c4267a1b2cfa6e30cbd7dab1df998fdcca071b46fb0c794bac6004e71df45dd73e2abdd35763ba455c55ba3b2b1b2cdf6987183b9c2a37df6810fb26b6b5079beb06a53718681a779b71577be91b39a6a6f0e0c4da6d696a5af680ec54939be4760489dc8fece6a86533dd9f4e77ad7b76b5ee2be2aa8e4edc5712866df341ea206fbfd0d487095ca06f64d72896c5acfbea70d7451e80bb24999d240f60c3cab6d83af1e8f5a15339f5d8a4ad173cedae5ab0f67877642e9dea1bdc669d78f352dee585d6aa5d1164f77af689bb0ddeeb5e36383e7bf709c1bdcbb877398470ef2e11b061baf7cd13089ce767b26cdbba0faab22f7319f7ed64d7a0e6d97ec8ded9b59b207b7776ad673cdcdfe69327389be91dd9f53638a7760cf3b6c86559f64c7677da67cab46bf2a1695a865dfba29c2d5c2fafd3d7081b72346b8f179aecc394066794a7bd592f78ab163c82788849f592a3d728fdea8d71527a75ecbde005758079dec26b0a1dec318b5fd6cab92acb369b7355bd79e6c06e0bbb8d3d6c98483f3270c57e484cbf135f5772922036ecda74088dc4db509e4908fa4d77590dc8c30de1a106c475f77493dbd17528874781338d1bc2c37f0db186c7bedcc220c88537bffda07a0d042108ce28bbeb4343e89e24b046fda795e07aecb368f0e4b77b196cfbb150361288720b0f3f102429fcfc3e2b9b55ecf1d1e63f6f6ec7e7c2eb681f76f66d278ef50dfb7a4c939bcd8d7ddec95d748867ba91c01fdcdb894e71e1c96bc7f3f613f2f37102db8f9da0cfb783de7ea2efca26c6cc7c393b046529592031f127fbfc4029df2a625ab91df4283746d283aee582d777a641a07387dc297d6751644aee073d77106dc5c4ccdc9cdd728d452010c71d74a177819ae3c20bdd03f1a4a29b43d7bb31f2f6cb7d673a48c4f6593c52ff4411be0823f7975b986a6104dbc0700916b68035ed8a995fd6deed98379d63bc6f9fe9fe3247811bd5e85a47f268757bb73a663e66bb77bb53d2b5acd3b0381661e0786c4ad261e720dd566b947df4b9f6a19febe8ec83dc8ecf9bebf1b9735a49fa86f0a01a0de1a186f4eea40faaae950d3665abb81d5ec3481e6cc77cf77d33fdf9fc27fb62805ce7b00b84fb8c1c94dd066bf40dd238c65e2017c8c3f6cb6d45cd61f245151e288e11c9f862f4fa38c61d2389149d53a46f582346c01d2edc482201ea3ba7535f76ec9bb79f3712471cb16178ada453a9eddadcb089add5a83d8387c484593304f228dfa961e445df1b463ef4a11a461ef4a51a46fef3b978cf37d8bb329edbdd6bef76bd2bbaa47bea77ca45bbe97a5a41c396789089128e6056c42f415af08a95e26cb6f8fad93cd31e4aedaa6a593deb06d7186dbbd9066fcf324dd61ded157efba84ee890e3116a85fe796ee17af3f5566ee1ece6efe6ae35bb9be679b4f1ee0e90f97a500f8955a0affbb235f9c094bbf9d2f9bcdae0ac65e369adcf6dbcabdd5c55252b334bf5665dd1a0691e4d5bd14f0c57db57f4907583690c774fd77573df2ae221a22a4f4c6b5a3bdc61c36cdb574f3ff8ee9be73e883d9fcee79a0de6f0f6f972aefa74db73aefa50facf29f7a9b6af1e760efb69617a9d7e20cf5b395759dc71995e7b0b749b4f77337de75cd5daa1b7f1feb93b40e4bff8eceb21f13c66bf99c6d735f978a9de98d50f387bf04c637ab5a638d02e0f709a87ff211e110f4fd2d172787170003ee6c8036c87a8c3db177980100800bfca492c8707e2e30470b3c502787fa6d403701aa7dfe9e2947e7afdee8cdfffd7d772712a8da76e3f1d2e4ed3eb70ed435d1cd43fe3dcb772fff9000080d707e028df7771ee77d4471fcbc5d101e5f62a1f8e4900279cd325e2a25af91038379e0f87e51219800a873bcb4bcf4a9748a76ab9e9e2a8dcf3d32582a2c2b95e3ac974d1b3873e1cd38738bdfb70ba8b46f71cfb704e9f9fba679f1f4ea79d25bb444e2a9ceca59b2e11910ac78483622f1115158e7de97d8958158ee97da9c325125538a29f8e728954154e7796d34b04a4c241b9e72926150ebd09a5c221dd73007cfb70007089642a1c50bd443c2a9ced2ca77189e050e1d497ee7d3828d3e59f720ff6ff7bfc70665c22adc2f17eba97480e158ee72c1707bb38de713ec7011d47f4d0894415cbbf4be4002a1ceca58b533a91a8fac589c7e9e3c8e3d0cfb77c38a68b4324aa4c67b938f538d771ec71b2950f27f4d3c5315d1c94e3a41c67741c95934e24aa4a17473bce761cee381e017c364ab00a6994f201118f481de0459f953ac087be17a9033ce8bb8010cff3795207f8eec3f17140ea00bf7d31e78b4f481de0b38f2475d02147207580bfbefac524f20c903ac0cbef87f845255207f89b68a3435b1d18871994a10932aaa00218843801bb906386257e00c6123080f1831fe81cc106585843164a1801859b1ab8e08a2b9c9084155e20078921931d04010db5d64aa73d932582f0fa0b242e901293258a746e4c661b1cebaf7ae30a2a8c393de20aa0d43c31f0fa16d7c72232be2747794088979053074c709083f38683203064a2832d70b690c90dc2c01832b94118220df0854df0c6c319b352298fd400cb588fb0401ec9c1ac940c1d7c81e50c2ca5944c6e100629a59472ca24f60659c0d97b1326411c21f2426bed2850d794524a396b1263c8a0c893f002e7bf346193e8824846691251900156698d2289298a582f8924b55e9f2252123a304882063048c205394910c14962882290206308126310818a625a10864c9070c276067ac91a8721184645618616d82e8c5c566041b5624ee85925338a22488c8a420924a828902852c4086a226124cbc216510881420914561cc08b8790c424082cae056e8a984319347002153b500213ed03289c30c210b490021cc288820a1e8e00c80664db206ceec714424c8be4dde007c0834c82c8c159843bbbe0f8ee0193192021ea1b2a22542c5e720798528a7ac161a3ca6a2ffa9242511b158949bd79a988744949a50cb06b5e529ee61391ec94524a291321a6f8bcdc7925e9c54686219320c2d0ed70c109144ac8400b5e708211481c0086226da8811663f4c008bda0ac34c8ca90c28b6b78c2028da353a090523ae79cd4a28196f1053a93d8274770f66e8f8063091955582c5e94524c29b5d70ab229318be11232c2c051de408b421882136470b1054c430823003c49020df60d094dfdd9a998012d12b16928f01ac3256448a1913c2276e22a3ec19f09c7c3785b01343051c2086870821960a0e301309640444e1198b0e10d2a7818028f5e0bd0019132c890042314618ae6c10d136af8c20837388214a0c0453cc4c284e59f8505bc38a2892e847085375ca1437c3286151e10ae4aa7ec6d8c2dc8d0e097c0e106f888370619200c978cf1058e2a804be8de200417bca107396f38828a6272182e7903154c90b8c12cc2061e5c22461870de96b8c10af883e112372c81066e1802ce80e6e9a2a72f7bcc8925865c0f4f089e78aee2934f6605c5102204cf80f07539b3e1eb073c65563ce0ae32f533155f87ab161e708435e857f18903a00bbd31fd79cd73ea1b261ff4d7698572fefaece7e9bcc9471f0471c5ae3a6b0ce817d78345f50d885b74ea1bf6293ea40c81f222a2aa4a1e3718b3df6c4cbff9f9faa84d933f663fe37e5ce77ef443dc439fc9fbe710876ebec1a18324b7c33bf50dcfe321ac017af6065d9377938f0f778eebcba33ce378d0d7facf87ddfb7ab889e11eb1e47acc2ee6cbf5f4621f76f3755997b00189c635e0860a0ca18bb66d91e3d1d7b81dfdd2291bac88e585376fa1d6c058d1d7d50656f1890f187e7eb3c6ed417e462a7a94f08d0e30ec02869755e3e95d40a762ebe8ffc0834bdcc0d5c0c8310062085d72ccda3cfc416f6ef5003f1f033fe127d6d1cdad8020428820846008535062414e19068cdde4833e740c0b8c5d940626b89e4aecd80dfa78ecd341b3bde47ab00c803516d0a978db03ee70ea1bd8cddaed2f7bcded07767af38e9306027da22fd387ae65dc8ffacfafcf435fb6075dd1076b8842df06fa3c177ddde9670f391f8688aafaecb347cd37789b3db05f47f50dd0e3e9b3bde7dded97b5f720fafc815d7439ee477dc6fdd862733c44ff818542d7e403f4eda06fa06cedf57c1822aa72202c000af7037bce3a39101600e5dc3f5f9e899e2f667bc4dd17a3bd72289f953a78241c3fb06b03c77bc9a85d88b9c08b6f6e470f58233ed4584ea53485e7e567021c523ed39b717cf9589b3940cf36f4bc893e1f77fbd2373a0fe81d376b238e2e3521b76991faa8a153de043830bd31f34aafe71316cbcfbe269e9be88427149e77ee9e4feaf9a0e779337a7746424ff7893a85f5707dceeeeea25442a3955edd1de731ec2438709cdb5cb08b30cd9e51dee5b58ef5db8e7249adfbaeeeab9862ed8bda66bfeda5dece713ee2c66ddbc4dadcba4f62ee9bddd798d3bacd8a4e57b6f8baae17ba5fe8285caf719a86123f12c3c31a151be2813e1dd783bdc70241e14de3ae07080a6ff7703e4e49d20006bc5df36cddc49a67eb3c51a78678d6cb5ecaad4dd1b2d79989b3a9e4e27cf080c2aeeb8a428408b19c0ff8e4c99327736229ea2c8bd6f20bce406ce079192bad347e330cdcb3522a46adab0bd72a5b4e29fab129a96fcc4c115432b520824d846600ad009284273c2c81c570c91b7a30c920059674c652a69f9d82b3073d7d0cbddebc117e13d618b2067c1ce35fd2a051b1850d98b822670a70d801c7061d08210954802164c9d637328d36fa7cce9eed3f8752cbea8f594ee5f6197433761afa41797738bad9b2667d7cfe5c3ed36418c5629726131dfbf6ec66791a9a55568c37c7d3d87969328c1d745676597166d9b3e2e7f3e8f1d26418e5393ebb59ce9b3594b3e4a5c9b0bc3dcacd99bdd9cab3b24b93e195b3b44b96e72c7bd073769bed358e05caa0b79cb57269324b3d2ccfdfeb5b3c5a0e7dc3b611c5aae7fbf480bada69cf2def7f9ca74bd1525a9e9d25af5cc57ab2765dc1086600837b4eb97dcb8aa65d9e538ea31c6824b7aeb2786a0b97522376693229377fa7b95a6a1994cc610d38b3be7bb4e794f9fc5d9a2cb7ac709a8765e562a9d70a4bca412b9edb67cdb3a23d7b1e358cc5e3f964b19aa6b15c5e2cd5c3e2e1bec2a55c4b697966793faf585f40c2124de0bcf2bce579b5f2ec51796ea92c2b9bd6751a77fbec792655acc773a55cdc3d74c5a37de5f9d2e7968b79b89b72cd7369b214cd93f2957bb0f8cc92e9be72ed9f73cfd7539e59348ab3821a7881f39461791f859e5de5fdf9f57c8d44ea48dc4645cf54ecc6895eb22b275d544957058d4ca51444e18a38500167960ceb06b79cf4d246a2d808e559f4796ea9a795535ca9f4b4524f2acfa610b6624f2614cce45961792edd3eaf564c67f93c9b560e62f19cba15d2bbb49d8018e30c70e0c24493ad4cb4b4f26c5a396d265a4ba463b4ade9e69512c772c24c3f3d8b6eb367964b93e5955327639221d595cb883819d60d3ebd54dd30062d949061f9a974f92c42793e6d2c978b37f54b1a36472da7f16c17e82d9f9b3ca5ab546279e82bd97495e7d3cd2ca7c14ea7d1b8d373e9d959562e2d497412e999e528a7cf27168a059135d800e7d58a758345379f6e5e390d768a1747e92c96d04d004cc5afdc543acd85334b5445cfa0fb02537185f44c6f7a3e7948a7e9429726cbf2a1d069389c59a29b4b2cd05921d159a4836e369d06c399253aabf4d0733de8b97469325cba3419165da2d3589c5925d243cfa0cfb34cb77433e834146756e8e694d36c38b34867812e4d86410f3d735761894eba993b8d076756e8ac94839e3d0f3f6c1b106b47d03094c6a51f22aa40d03094c6ade140c3d0c3790638c0e4c369022b1760c940cb573aa1052c40878e042400070e1b365e5e5a6e4dcb25aa52a89f16a02301386cbc74777777777777777777777b5a3a2321a6af745288387da58392b3f2958e2816d161f94a27040410a49919951f7e000101f219c1083c101c049ed71b32abeb72a053f42b1d1aaf59a7a6e5b2726b5aa9d3ad69a14ea3149410cae81fbde529bfe8a7870e44e728dd9a16a9f49d74fa99ce512aa9dcab9cfe87ce5132cd78e9f440401fd4083a07e8d6b42c003e07e500c0ad694d007868dc732f070068dcd64bc3447ad48cfbbd8565e5f4b9344cc3945448a31414d1160d03c26163a2a80de9266b162a68f245079aa4d729132698ceb394e0eb662985122c2104c303c3633d9903be8c4aa837a554d229265558d1048b2db87012862fc210830d718c4886101cbb088e6d048e4da291cb8a381e3ab989116b2ad8165ebcca555462e9393621820932e0189269f49194c29329dc4055b3936242398ae9b6e61667b8e208aa9a1d51e8a1bfa8fc45c7f4d2e3bc0110b2a085aa6607f4a94c7451032254353b9e070923764085aa66a7e32a144b76704455b3b3798cb0248c2654353b596c43109e94a1aad9b12bb8a27ec8572ad739dd9676851c9e3c51d5ecc80fb9ca746b76e63d4fcac8e207aad2cd11cbd8e0d2572a3766856149e5f906ab5c99d1bd4ccadd02c7cb84aecce7ca78e265ba2bb3c96457c65e997a65e67db936708e46303078f0a5a666d0303164e14135d04f0ba645f638c1f058479fb92730ec67ed08863933223fe5e385b93aa14d1af625846fd870c67885a641ee5bdfc83aadeeabceb1ddd6ceaa562104b61f42eeac22b672c890abb85b4344192a0e360cbd79a6ed6b72aeea6ecb26fb020daa0842b5dda65621846abb3bf3cac4d843cc8a58869e20093090603ffb0561452ca3dd55c4daa74c9088afcfb4607bfab1b2afb4abc3caae0e775b353bf63bf443aeda76660abe40832a82c0d757ab1002d7ef984a7933b691375acb236835d987bc46bb5eb37dc86bb80fa9e9e66b3c3bfd1aef43aeaaf97c479e7503a7ddbc868139354cbc32d88550c65e08614aa65e085332f44228332f8429197921843065636f6c473968abc6f41ac1b166f6ca32acd67a96cc2f2b0feedfd828a51032822748089e2a0009c9a0982094072ca5a434055ff062e45992bebe562963e2ef0fd40b5ec8486604d36b9815bc8cc92a2426c8c4f5ae5ab439a30a70c4b8e0c5ccb3e6aa5e7e2662086b7490d585e765e60d2271be69617983675612cb37c6b4f0eaf325467c7dae4e326da264bed26356a0c7b4f0a2114c6fbc0f4e2491b7d92eb2e0cd954ece552d209c4041083baad60e57438415e02451b576b69617475c3186aab5a3dd0c618c2be4a06aed6429f802112494a16aedd422aa1042d5dac17e1022444810aad68efd90ab5a37aa9d2bdf607a65b87bda2e49bba2ec7af56ed8b5d78517d35fdf095a4ed082b19bed83b4602c1fc21d56977d1f8b913f179e7c911c2284b48098f901c80840c0011f310864d064a684d7946b2c7ab16b1623d73db1182397755f3db3ee8965cd35d69bd75dddb4ebdcbac3bceecbc36c87754b4f86613d2fac67ec2acd3425bcbeb98f78ee3725dab99ba311239936b1cf6e9642b07adbb1c98c37cb2770746f818528600a1a44651a4a30ca8813489a3882c41146a08c507a7a8dcc795739f04cc4a823b0860a503913e301635a78f0f05a531e7015b12c3c88e1217d9008042424a39e880942717757f141b8bbba30bdcc0d2231bdf966c6de2012cf6bca7eb10e897d11dbc6f1f3e0fac139e0ebcba02f7831f4ac2041263e3c450501d6904270bd4e9c7cf1851862c0314063081182692807d388f30ba67489114c9f41426a4615c1f298175045fa46461941e5a08e38f16cf09c79d5aa73a28c60c94243c955056dc58a98453f7f832b7482e1cd9e8c8c8c0c2b95e1fb3a64bdfa524e2921841042082184f047e6132d46615ec17bb982276fb76c42831eadb74efbf6c5601e78cfb7835de3300c83ef563a9e6bbf3c9ac7e3f98ca7dfd5a9388dbe5eb79462db57d857dbe957dfb16e5631a63b766da7fb2bf78bbbb931774b3b8f877ae04ed7d5f95d56c3be202d79de635f90168c6157068398d66f2b1bacdd552c5d3786bede187a4bf36a8dcd419b357e959d75bd0f6336cb75ef2647e7b14fef105fd7cd1bbeb2cc6aaceb3ae4e5dd8b468c380289234d2071e2892224914209932aac6882c5165c3809c3176174ca73337432bbeedd6f7ec1dc394ed3b267cf51d3b20b0ade3c86056f3bc5a0e045f90407030dcbc2d35cfa465ef5732a9542a150ff4fa71389441289449ee76ddb66ad9d3957cdd6ceaa0f03755c5c52a9140a85fa7f3a9d4824924824f23c6fdb60e29c71ce8689f3d6d8c4485fc0b25f5d67d99b27b657bc79be8fcd436a04cf9b373cafcbb2b0afec59987d1f99d7afebd77575130905e8e405cb96517e5ec18b467234821d1303cbdbebeaeeeeeeeeeecf99bb0996193ac1519ece299d5c1183428bfdf2f2f28243ead02c08e7b476db3c4f2422914ea71f8562b974caeb2df02ae22014cf0789548bd8143c7af30b8e17da60c86155f0e2a1e039c131bf5c1956bc4bea02a809dc879303480c102dc0d3b1250047a7fa322c1b371883823785109c5fe25dc50cb464c79699b1983e4b174c33708109f8e000062c40470270d8787149a17e226d50ca283327963db8c8c8c8cc7833c5b405e71bbce20153a8044f7ae785115f6ed0b0261ea644eb3e991b215866753c3371f7eec3a65083bb9b6b70f7f96589e7a58db87b8e4670f672075991b05cb57077f9f517b8fb6a604c0a5e771d2d2323232323232323139560eca3f26198539d100d1eb3e2a3af208a745d3ea5f2157cbdbc8b4ee92b683f1f3a257f3a398044628048b400cfd3b16d09b016c7fcb431ef0afea553a55bd37251b935ad541ced5c7702f5eed09b814ec9511cc9511cc9511cc9511cc9511c5dde5a1c0d23738cae0df8d230f2f20270348154c3c0910f9d63e5b6500d0347e72eef80be31afcee9b6de3070f4eef20ce81b748eeeb9a4a37b37ae9a800b74791c3b3674791bb661e05b36a38b729060769b948f6e33ba3b40fad985971b4ef960c344946f86be2d7abe13f7a1b40f3aa181c66a2cb36a9c755c52a89f48226fb3b166672662082f9c76f344a4d3513b32a94ec1cf44dc0fd282fbba74aadba0b9b8a45228d47f3a9d4824924824f23c6fdb366b27fd9cf4b2745c5cec7549a5ae9b42a176ea45fdf0a7d3cae149247891c8f3484d5239bcb5b6612669c2f9943c40cba56162cbf67954e768b9ad940de9dce7df39586e0bb5721bd269e5b67eba0de99ecf934e36a47b9f57c76443fae753a7745b3b17e8f35bdfc0ae8eca6dedd8d0e7ed0e26fafcb436a4a3e450b9ad96769bd149b721dd1d209f1b1e7d70f34e9d9aa04fe47da7ee436df38b79b149b8f48de952a229954314e9d74787a79443124a26125df3421b88b39fc3eb1dcec3f9789d202d78dec5a5443f934aa9d4cfa050a4eb33ff47f633a7530af699934828d967a24824d23ee379a1ed33db06e2b6c35bfbe93e133167daf1ae4c9016ecf94cc4dd4ebc33dff77ddff77ddff7c59b51571a682e2e3395aa2894fdb3d36923913a91c8f33cd0b689ac4d79c74fd23b5ed60d6e9dd2fbf0f33a3957d1bb740e7a6b5a2ed7cc71dd9a560aab39b05bd34269363b769b43bb35ad7319fca975f26cddb96f393cb7a645fa74de3d2251c8bbad969723746b5a1e0ae8b65a39a01c28b7a6b58d44b7d5ca11e518dd9a965549b9ad564e4a0e955bd39a0d234da4db6ae59072986ecd10a5db8257f966c3c493bef9d986894f41f9b68689177d5bc3f4439fd730f1a0eff3891a26defb440dd3f77ca48689efb8efd430f1db77fade30f119f6a11a26de7ea82fd530f11526c2f46d48f18281d62e9d8a9dea54ecee53a762933a155bd4a9d85ea7626f9d8a6d3b15bb6f4cc3eee71bdc17ba742a3e019d8a5f402ade013e64e09b39d0202a47e804c7af8f35c18b97919191919191919191894686689816bcd8dd2de3b9bc7cbec1f2cac874e7b263a7f9067bae8c4cc76dad7576317b2bbdf3624b804c986044c90cbc0d4326568811dfd20d5a0c421694b004c7221318020a32c0394e9030420d306c225210832d6c618629a078e20a384332848002109a80e1187158e2092d70866ca039484208516028864d179a0861018661b48e3c214408bc8a675d4f3421845bc51bd31d6296f6640e181e5b82b761d69339e0fc72cc095ed73ddfe0eecac8c870a053dcbd300c1c732402c7c71c1c8b38a12cd0e0a14873718999cfa914e8d6ecd0d0418747a142b766a78a1e3afc2fba353b17ca45873f9d506ecd8e4d2191526ecd0e367acae145a2d1add9c9481f1ddef348b766475339e9f0dba6726b76b6d2550e6f6de9d6ec709f9fd731dd9a9deead21579d6e3a5cc91be3dd559f15b17788754eb766c7f3d3e14f9fe99b0d235ffa6cc3c8ab7c5bc3c8933eaf61e4479fa861244ca9d1a8240c98488b1c750cd18800000010006315002028180e09c582b1689c078266f614000ea0b24a5ea44ab32489519432c618438c0100000c8c9088c0cc40012a0c6052eab50b94300c967ef951408d386802a8ecf13b441f3b10f99130ac78ae91428b9ad5dd42013c5b825783a918bf05332ee12db9744ae7b66fa67b238875f9491bfa744ba71ed8a554dc89cb507cb9c5623ea6de88af5d58e4bb3a1637527549443b9466a7d5dc885bb8096ee0462e0357c6a0efb9ff841e5825efb7cae5b96490f1d3315b4b3b7961ed0488b82d671a9c21ea08fdf3284aeb2ddd1a53adc7f748e9d6575e96f523e081cfeed244425af304b75796d1fea6cc9da22c9a4ab823c469e70f30ebef4a8a8108c88a6eaac6f0ace5a466d532bbaa4da27eb20ef20cc956b45d014fc62ab539e2536644ceabaad9759af337daaa73bc4e474a2364d77e6859f2d0128b825d523f6410674c0f1f10f6379d9bb4f51c711cf3f0d99341a8091429a5d04e8eae6020521f1df8a770af50a93a29f20f53aafc464b9d0adbb68ea359d1a106410c0161302eff7f2f713dcae7ee7607d4ba141867eb181a8a6638f2a8e1362ea8b785f783b561f964b6ace2a4ef282a6151e10261205d114a2fa406dc51e932593127ef5c5333b89352584c5d46c6a5028dfcd305c07b5a1c9576a99eda947fa1a6067ceff0672b2b9d46f041384487ad847611d356a87b4d6ce26bf4c9f094dda481995ce5f848053a4c52273f6ba75f6cc6c5c2e886ff4f2d9fb070f907812c0575d6988c0a6a08ccc2a51060792fa300992f241bec467f9780aaa078a707251390e9d7834ae851bc1812905a99b1ddadd712d7495a0e87de36dbffae6c450de1a7cb021d12cb38496094f77e348548777c9cc53276932f4e4d99507df31c8ae36dd007caa6e2bae509a1573040f23296b5a20428c34cae8704de411f24ae9771bd2d29bf71641fd700b76791c585338d7934c789a8eb9f3c0978c36fb515af1f29fb9ac66ea022798c365a0952e5810b4061a83bd0b22e19b478ae46b9031d767706a5d540795d57ab3f380db6ab72ec32addf35ca911e0462e6d9535c87d64ffe221e1ab72da21c7cacf6987763874f536fe38365057ea1ae17526cfeb7999f25f4fbf238100bdc40827652bb3d42ecb0b6faee8e4fd90b0dacc2f7b340f1652a8d2d3534bb29b0d4fc3aa4d59290980e7ae392e93d1d748143db0c87d31e98d6b39df8d280e78870099441a44d80f34fc11065a6daa19868d1b8d720103433a9034cdcb0d37d12420d75ee023956266ccb9b492c2e0a87000fde57bc9637202976b61e060527a1f19c12f204d9870e7520811afda1c0197fc16825e1051bdea034733e95763380986b86adf1ff2bfb65dc80d3e6f6279af3a5edd7c0159c62aabfb713ddbc181aa5e99378db57d32e5e3ebdc0803c75fe88ed8c8e85f41570bf0026025eedb24d3fd657e293b141af1ef9cd506b244d285aad011d94ce950a4b26f5fd305bc69c76b220512dfbc632c4edbfc08faa3a01daa49e27a249aa7a5028f9efebbb7d3da444e366e0e8b854ae9f799abf7abcb6c88fe21e3b080c00b87defe3084c23d54559a52cdbacfa2f1d0c1ca9eaa96a60cb2a171512c5693f3b5a2705a60cb8b288aa06d1ce81eca94299b0268ee442f66288e40be36a78dc6cd25945a7ea5b777c434384cb255c15f02696c99560d499fa20aff00239466ebf64e59b2036bd050afb8a33f49ba4c47fa3336e7011aff4b884fccff8c0f5286979e111109f019558392a18f07adbedfe9b609ec2841217c3dfd29d819580408124408f1b1f21aa30aca7682664de5c7b098fc463ae412ae465fe0ad397925e95121ffd51db465c3c74cb035f9046db75fcaddb315d11b8a3c265546d005ad24961272dfb5e32a2ccc7e22659fc7ce89c69af276ed340d4f9c314da1f0cfe571a744b1f3aab91c00138a5ecdbf7ca5a49c4272d4c99b518cefe54275e24289261c6bda2c90abc3091c30b82e5d7b4fcdd673986d0d988987014eb4d1c91a7e8c2a2d04b7b8eff8cfe0ea2e1abfa2256421fc74a56fdf703e0397f33189641f691fbe32e7bc220e7c5adc8a3a5bb00caad9e8550e806c7d67ab4e693c52834550acd5849aacadd1259311b29a87adb1583f283aed3f973f8140aa1af47ebc45b35290cbc08509f9e5d9d81bcc3ff7444856f76a88a7af1d6d04325127e5238e928b4070f0116c41d003b6ce326d6f77313eb3fd61195104ff1a9aa1e73e0d080b924053f2d393ae02a37ac5975bbaf9db2dec68aacf7c45eac5fb5c95e9002e336a38a514f623056ff72476faf960e15a8e44edcdb39bb29ce5e000ec2aa9e10a35a8f61e0d240f3440a7f5a7c13f12a406a94a7778e10975142fc6a01211eed13419f1a2202512f54eea0dd28e53f1d51e94f3daa355b1f0fe5f6985faf0061c137075c0358c710a3d067a8a02c8f0aa7cd85a554c68ee0b6cd66970006dcccc1844f1d8dffd31115bed22155217b9fb32995079bb19d0f6e00ed4e5b536bdfbe53ee819eb2ea1bef780e123f5d1bff6faf54fa4ae7547e5732829ef6ede76af56f2f2ce9d4bcb374dc6a4720eb1dacd3352a9cc94bf2d021512f7963968abe57a143ab2b4a8c333f1d21ae40179b0814573744b947a10c743eca74a5ec1cad7691bc63e100f0c0e679c42fe100a0b62d50c80c8bb17f8ef1bd618fc5a6fd99567479ab86e104fc42bbb9d41f37e85531bc5c41a8c77c7df3c3c540fe70105b339c3caa4ce5db3b45ebc850f3e00c0bc2abee156f71055fc0b2535a20d92315fa275334d9ca71cae5e41e2a2fa40685a13ad058deeb6b13f65f097f67f0aed966cd2daa8c7dbc64c044324b8ce8fb1fdb11f50b93c27bd78fd8e105fce1354ebd5636bb49003f602e4c8dd63f2e8bf14bca8e8188542b4f0c49fe529f915f0f0f02aaa44f5da03c158931f84e7e261249f543d8d4dd676a0048f5a1f3ace2df065dcace32f4c0ae23e04acd08ee5a5574494eca4424d461d9f41f1e19389d9c1e002fd1fb184c6030e67f94efa4c041d655cd8dd2c81c0b7905d5783cbf0a8012e4385561c6806de6fcbfddb6ca9e535374e54d6dd190c5f9905d1e6ad75d1de685482a4cc2ea0350b1495b50c0e1c4744dbb12cbde0e8a44b4a4b4407a083a68f193df26aaf59fdd72e95b23d85ad49c65c98d48b7f613433d0ebb787f61c301acb89fd874d04af950f1b41b8a7b3881630213e2da876d672429e78255a34dad33064cca7491da4f4c437170a91e11a3567f9c4396dee55c1e08b27b0115b683538c52b552105f62faea2627b67ac82d6b34804f120a8cb5f1509dc9d13d16bc84ea143732f7c90e2899e8ce969fc07a69690f92f033ff8b372fe26e541a1e42005e44313136e504aa1c15377c157dbb0354684a71c6434df932bceb73987c1f74270b80c43ba429a772344f8e151d1b4f338ef6434c475d16fbe9fe7974340fb09867453ad606c82d28dfe402a445209ac6f6ccee0c0d92b5ad3401a2ece3b355246495157bd804eac91e4955f96eec95581b9e231caae26d7a6a66c911cdf1cfdd7be2f48bc475c94bcf98427dfa5d870f1a678cf54b0f801b18e6fab57e97a8d8403bf53b15000459600f231f446eb53e3a2f03328151deaa0960abefe5d694966e1efb28c6319c592e0bfdae9dddd3d9347e8e25a3ffea4a3dd48f9349330076368b5be3fa9504295fc223cf0130000199d95f241faa8929a1abacb8afa5013b6a9fb3aa6b61105e742de129b2e7b19461e768dcccdec9f5a36b7937dd292a370f4f79be2c07214bcad5ad30086d113844db9ce4b365b381266b955c6fe8734ff7430aff4b5a1c3020e31455dfb2814a7362e966236a8d087eb05c31f642889f033f821ac82ffabfd97e27a49a19989e25708700ab5c67268f09c03599068e430744838f8b01b9ffdb35c6dbc9d39721cd542d60f19e4137ba591d9d661dd43c172f85cc0e8acf77b22a3fa5522e738cf221226fa8e166705c5dc223912f97cf969e8968d307987c2664a22dc0085ddf56c5928b55d1f3291c44ec8fe57e780429c3de7b2f328a8a56180ccac3c3a5023c8df82340e4cd4d27d31a9e2e846ed4c00a920d883cf91b14d977ad28a0d10aee893ee3aceeb02db1cc2484b3398018e1a311542fe68f017170cd2682444fd87fa9a9a9a1fddf2eb0317d8ef9d17b95037d7c7b61122e18d56be097076f267eece454c851520d862fc2624d9977c25edb8665181281e1fa749c05b721cde1ab463756e98c45e8db9ea65a6cd275952f44d39eba3cc39cb4d98adc306f636c03c7a579afd6951e72673e8a4175048a78b88267b73b6c803b55ca9921705f5c2be50a5b310ff957315868d4e875f26f28744419b420951994aa14c412e8c7f8d22c1b7438c143f98c0ebf647dd2af19c1022b3c50410124f96230d9d0d8429f281d91f0a746ad7fc7d9ce6056864bfb62dc571842ce06b90218476a8047e63a2eba28f673e448582689ec9fba9a8977852d06463489c5aee63d746fc4d3794b0688ba2a097969538a454c1ba9889d97174c403c2e833d7978bebb5f5c0cc441808bc2c62f29e2b3f92fd031eedee848a1c30f40297a90d07c478a5dc1be23ef32f6d65c97df8364862cf61cd38c3035fac9d4bf8836303c53ba135d7b0100cd817eec7d224b1812f2e5a2841ffcc423b06056a29e59090f2c62de8a901fa8be21a623dcea92d5e681460b3860e11cc18f9ecacdf411a0f8d145f8d24f77248286ee0ca272c4b8f95c0695016787a1b6ff7d84ef6de605b18356f0202db485574504a27eab3bc5282adbc5566d50894296fdfc3050d172a3bcbf0c5d34a316455eb4b4a096f4180c7fd20f6aef92c8dc3fffb6b9b28d6669ebc4acc62ed6a55f571c57c092958cf7d7a1e77e565315fe505f179faba94ba8a81e30c3bdb7997aaeb1958683ff3d075ac77dd829f01ddd27042def9e4c79b8aac4adf1dcc608ce0573de4c807e769aa0b81c14473681a384644893deb8983c1d3e16f5fdfb00eed7929c32854541c3fd09a2985d815e1e2573d011c6b83382af831fa946586a2cf42c06a150464023d4b694e5362f5c32725b9f585c17ede95f66661a3897aab41c145fb523aaa502f9981e024e4ea2feaf9b9f0b25f03a84ab8894925760ff7dd18de73c6f2a91206da3086a67202ff144f67bf622043b76dc08e0b172319f88c9527b7ffa0c4f7463f9656f84429d6152838eb9d77a496d935759bfd4ff01dd5e461529712495a083eff0e6b476946430fe775436127376ae2e59fdff7a0310e3e6fad30cc87e28cabeab5187c0f39dd1ef7ec02e3af5d6c43559cd49d85873645f1baa6b204d94325841b2a77a854179d562fb15663b8e44c96e08704864643fc2da6a846c3868b03fd178ea25ae7bada854cfa67f01afa20d75ddaef72c180c951dd9c60c4738b8edc6b1e0a3a685da2baceb924719455d7d4e7ad3dc90d4f9f93cf44ff8b1ff382e425baec89fd3df51e799b1db49dd81c6e1112af3bec8ea35d77b314546352e3ee51b46c1d144a6d067049705b1328a6f8a6a32d8f70b29da4a2c267c0ae837a5b36d539ca500f75adcb2ba9fa918eed27a7de86b50c4217700f6586d509442ead17f8734939066bed4c136272efa3f24474ef30e168af69769355a84cf4754a5a803ecf67492d636f6cf5098f72d507c9ea628bee9ae604ff938dfd2893fdbebec1b19eab3884ad8d72c96ce51057ba6dcd3f59daaac627f12549122185ed3dc1a53110a90330f681399e23df3a30d3b4158925af936c3ffdc7b6df86e750104bc36888f4a95b549c175c6b33583e55f338612f9791121d49f99d17ea7d31b2bd29cb17db56d2567d7e2093d53f20ad4f93e6ec2fd541af23f68bb420c5860704c29b469993de66071f73663665334f1f99f64e80910275da011bff8d5ba52ce73e530c71c72ce999b4ca0f53064e5ed1cb9a554705ddb5301416108b788aa943a33ff0ea272b6632c1c207b65f9d0d1e4cb2f7cd970b36bb9720551015d62c59e517f6dd7a809649d477168f6a45b0f8f91af1f0aae6081df17d0d18bb1c9ba0727f3b83d8c73e15208e6552d86d499f35d49e79af6e9bedbd66ddcc8922968eb116a6fbd0cb637c7e7516469f4982109f0ed5ddddf051d2e05159b4322bf52fb9525e53f73f18e26b35e341aec297372094ef05c48c7642abfdfe8a8085f774b454d96676013c03e2d73aeb0a41875afbee7a3b55fd368916739024578ae2d849dcee7cf84d950b6104a41144535fe5304d6da746b02f1e1b6469d6f4d7e881b0ba58ae9b1ba70ce084cc437758d078e9ba866c4c258c7492d9c453cdc85ee0f710f8618716009932c7c074354155ef2adb8dbee692988d6ecca2f40cd4770f3231cdd6946ce6a4af63e5419c472b20a0ffdae65fe9cf91ff72c912cf991f939ca312803fafe1c3a3238b1fa7d2e04f050a01e9eab0165c3c96796fe64e879cd71c7213065fd28976c2cf4ce1da93ee31afd65d003e6ac620268f2f2676bc3ce8a0f2c76c926b707e909763da475cbf720a7b7889c37995cc8d21eb9ecba57070867ecb0599bd6ae50170c9228ab4fedea4133f491cecef7b4dbd1c8c28a75d3fc6c7270b8cc6cb3a239028832230fbfac405a9e992a2de84613a7300d8324eef576852cd626a0988dde34d08b6ac38fa0766f2e20d36fdd93cb9bf30d12d534b1bc17c10c0a3cd48ba6c46382348ca557969307fa0a06eb6724bffa24b8caad6f0d2b157427970017f6691b61626fd1a8ea1de50c65bc13c958489317e0f7995e5cecb9b0e0d39e3e981f890502f6f593c9b6649c021ea11996764a1bf4b67d86e24410d49e7038a74b99aa843b8367022869c77f001d4ce741c707e936385997825b9e52dc665d33851224342850476ad68543cdde17c1c81bbdbf6d26acae139ceeaa59e56b9804d6ee7171d53e0fdc581f8ac478f48744101f193a4467c7b3ba82a3b2c63ad5e2a8ce4d6cf53baa1c110dc7a38a522f733106d86e40c802798d645d3578af394b120640ff74d6f6246d7a159a1a233d094e36300b933aaef5be0f6f5827043dc8437f3df16e803aef4838789fb1aa5263a248129d1f6e8ab3dcc1584f9066bd649c239cb8a72ce170fb275bcb611f3bdf22c2bf3b61605a74ca2f60e8476d219a803a680b256ce7686dd1332b329d6b5d833a58d16176eab022ae24927e84bb605d70101d5ed33d8340993967857467ca0414150788c92d9ff4f382faa579ee029ce00fe28568236993a45ff03769169e96ce365953b8f84980f5ef08bd9c5d3f1ef62379028d4eded8db7f2bb4d27b5e78d76f139acdf86fbcd29f2054974ae6f2d2df2eb47b8e5daf68253ac67ee39427709d42dffa0a1d4097846a347e8ef6a9a28272f39a4b27565e4134bf7951ab15a6b463fe1ac1b6577011ae4d68d457f06f696478d215208ef2d1c4c4c6d3b54e6b67b7dc4bb06ebcc5560607fce2cbb9ff5e8bcf14912b9fdbe2360a80a7c096fcfd0b89be03014937a5e17402bacdfe4533d1705f0a3c3055f93a46eba3a31f5146a54419dd81928d08045d1ba9e94827b548689da6428aa897a8dab0886643c77d4414d579a3954b7c1baf83f89545bd2f9b7d75d407280df2e4039f2669a59e4f0d937632103069f6cc9e4b8474edced1499a77c78f1c4c26f07b84c70d1689be6ec43718251294b1a72de9f1784935f9a2a2d70140df79fbd79b9cfb00c3f52ab98504993867ba1421454d83c54abb465c1c6759bbeb0d28403041938d980c72b820c483a7f61494140bedc815d296b09e11b9c792f761f828a02b9c825147efa1f43db44ac8ab50ace2a9289bed61a99d494d3bf5d05f8b4e94cf9b0011d36752e1e37be7e2745a03a6cba22981229a333d964b2cce720176c901e3c92cd6a104dc6ca329577991242e8cc5af24f0857cf3294f86e0d2a45d84f02c421cf5d1e118c77cbd85c6fee1f9adf8ebd9bc2061948bb052d80b57a9f4b468854b2522205b41d2a7c88898e13e968c102f298d093d3466e47bfc7d9f40003831a522ea20210d9f098e61ba1e33eb935146ca438905be54b006d5aa13a2896dcd450f1a1d887826e42f44d8fb2ba31088ea471405860427b4e847d7a74dfe8b255769d34fdc8fcf97e3e06936f06913bcfdefb926ce21c034704236b24d846068ee540f7055d27b70cd4d26618bda0a258ab7e183fcd3eb945a58818ca1e4de0e392ef4b9ce715c979a2a02b5b59c33a57ac93d8e7d3abf04cf86e08394403dc6d8a5cb2f4572ccff85faf400a19fc594af4dfddc404284931cda12e1d41f4a65ef7e38563f88c8a9fa6ff3c71992e11233831aa22382aba464f725f7846a1c971af85c176b41778b843162810e8b2ad5a8ab8da1a7daa616b4fa64b85d4befd886eeeb498366967a1472fa618ada43ebec3116f24bced618eb1004ca240649a231acced5b2a656440eaf845aa372c30e8c6e26023681c63fc8d95f2711697adb187a81dacb55a37ef4dcdc22b0c2007d2f97195e9d7ae92a77eb27d2a5ca99bb62a3b758acd347cadd8456fe16ea65295dec58276222ff75e47efd44babaaaacbda011be3df2fe55e2364b1b0145faf3dfd06aa6c5f613d1e3604cc81f4b31915e1fae6707fb42b25393a8f989d4e605a7fb8944a40d554a1877d7bd7e5d79d41a52456654586c879984282fe369b77e2d56ae1b1925ce9210a15aaed58cb930931c34e2dae2f79158c572ed01af70e5ebf9f565414e804ef57837219b47d3911d5c33be37e4feecb96f5e94ee8b19ae6d2f37bef8de9c560542ae28e1d11a000669415b45c16b31656a6d3b554ae826a1d8826180bb16d42132fe8bb117a93f6111abee01bcb529a146de2491bd11707f3bd4821018f164074f2915f960b95054442dd4b18177efff56809c8109d8d02709c672f5b166b858cb83b5d9f4ff9026caf152343d6b95c9b87bb2954fe9ac167bea4b8ce28e406a8dc0954a1884ba92ed9dfab3479aa38a4f75b4f10ec49458b0dee250d0bd0b0313379dcad47782eea6523a5caef1a0ef711889879d7abd909a8933c07e64cafda179911531a86072ea15fb8001b0cc80b5caab72ead850eff244c9581b3212a91dfce5d75567c81b2db31c6097a7f97a56650e5fb95634f984add24ed4703aa864b328db7593fc7283fd49241521390351309f294aea54fd11bb915439204d546072c2cd79cdba336c370fc394453a5738e965bf253dcb534ffdcc1b26cd1ae5d45423aed3abf14cfaa5f90e242bcae9df109978bbd4b4ce9c4b7237dad524cdabc024b38e715090f93902e436c84ea06e7e1584f57758cf021ea2166f732c1678b6b2486c1b64a441b31c8e45e1300cb9560925863f3e95c18ccbe7acb894d15f8c79ee298539f36c696786e386eaee10b2986f2592339a93157ca00127b9e25ae1d055b57fef530eb95107c6d1bd0ab34c225b5ad487df0f772ce8f6721359504c71d32458a57991b9cae6c84138ff89c46bd0ba110f5c41b2eceb4674c458f835fb21f7aeeef651444e07e11278c4964f82c20e89bba0a4f47698a4cb0ecdbdd32bd161d4bf625a7f17a3eb563f15d7595175a92fb6aaf8c961ba33f39bb34abe4b0ce833352cccbe690fc2e0503068864f4907e71daf88534192cab961cb3420321021b340cb3ca8245b48a3c4e6c65360cf2ff313887dac61dfcfb42a691df8112380ee073ff0fe459a110fa076610f94c073800a3ec1d1cd316bc943e017f6a115b81f20e063bc2ecc2f14e880f03e580b15c748fcc51368fa7a2b816057aa42104ba2c3737826320eada25e5637d4c8a26ee63a9fd502858be387e94dbe6c0133b7ed51c257b8e0ff5ca5eb4c53657db66e03135fa223fdbfbc400bdda8ca020508a8576f282e2eeb90114dbaf4a062677a2520371817c75a1455dd5185e904e7d5ca53acd16e30135cec4c5b1a7673af6848f154aa86f86bf7950f02200315541d4b7a3fb31ffbcdb51425db71f00b51df95b241bf4dc1fe67ab9a1b86aa2065035fe991a3a48c766cb822e5a8e8b7646aac64ce19414fd37a5edc06818b0530ee2bebd6dfbe4033503515b73500309f079abc028e2d6f2c8023e0faba2d0e81b059e5cdbc321418bb314095d37d87e19e756d048e02227923e436b465f2443ae5c7e5098618b6396494a980342b070307e3eaba1fbaf84f2441fd7bb6e8ce9e00bd4b42c985e723451d9680fbf9ec9727b757f3c79569ef3545cae4334e63ffda3ef96fd88452e9d361fbb82b1772b3a99fa1d384e7cd6f87b4613f7107b6411053d6bfb731ab55737938d4b8f2502b27e0e0e2a6be98d38b96ff7f00f9757448ad02fa946832c2bd59993cd2d745339c0426e7c971cecf99e39ac8de77c562687eab46e28e5424dc900f56c46948ce1f6f225b7f2d1d8ff5a6ce5a4eb2c59e83a05c6682ed6030af0b3a886fbe50ee9e0a13d56a58bfae676cbfc684e3bfe4472c3577810d3e156fac70df6d73a992504976705ff3594b3b603729bfe18ead8cfb7ed14d9e400d51ba77cdb413afcc9a4fc00603e065215eb2af32017d69bb9a572abf21704b72ee790c9b6cd97943fcce286dd7ef0ae6e37678fc19559517e43dd33c760a9d68eaf4062a7a28699b89b2198ddaf84539b315cf95c53b6b52b6fdd20bdb8824c15649616af69bef980f61e314a922cd27aeed5e4ab286b8f21386e084d02fe44aaffe9b219cf874ec88aeb9c641765ee3a3336ecdb13fb8d8e3d6e30fe90877e0f2f2245d5a4c46388b2c08925c766cec25ff8b8ab1870bc6bd4e1effa8803649da7ccfd5f592a26e24a139bd6a3e167ddc7166770584b626c4bc27d08dc4fc6223fd03d5d97445f4bc07598a3cff1ad2894596dc9b6c53e0fa2364e05b8439577a437399865418b2938633dc09b02caaf1512d71009385d9fa671728a1e3697d34d67967e868ad054351b7558bfca49e0bdd6cc4c72901bb1c3f77a6fbaeb9299ddeb62b8ed3fee1d06faaa6e632b55beef92bcc69342a07e1f5581251f12f949db4124c3c83b4681253a2b53ab6c5c2e26d8d1d93a1e176225324dfaa56de84e44e05b612cc03328e139f3ed3449f8c29f7998f7ce043edebf58f804502900c9390d4ece8efa0eabf3fa9bbf233e2786a0b544a02daaf1c0e0babc8e63ecdb886e90bb6e02000a3cc39c511bb89248b0411b5c2efcee985a25af4aa6ef2fa20ba21560881cbc3c90a0c1f29da215608cf1b74f941e98e838a3f6bd4c7ab026b19f36908bf3d8a0af452bb89be71571bd610a1840111b1a2c8ae6fb477c0371646bdf66481cbeb3700a0b2fbc3b0125783c74615176308088422e29c22cd6196a5d00165b8a7206a17e5a49d04122814bc3ca2909c97a850c8ca72b070e3a81a92e3415fa6bef7b5a2469ad21c2ec32d02416b32b279f644cbd90f8ab62a9febe373c610e8ce22ddf525d8dd39e3a35d0f53ba648cc36b7dd06e81d1258249300d92589938606e476f3a9be95cd8273d58c654514f42bce1ce9fbb7a7312ff3ea65d2dced1517e6d30b4aa2f6bbfac3589c030f887cbdb09469d4dad515b11ab8a0c957338d4abdc778814bbf4aa330c159e51dd7eb08556ea0953cca7a93993ff38e78206e622e2d099228a735ee1358432ae680ecdc7f4e65a6360ba0f0925ce8e61cad180544d8555a8294bfbd50729fcc537c1a417e78569d8d7c2dc9bbed1a0a11561e81675fd95f30c4aebc9c365bdf3549da92ed4aa1805e594035466084d43eaebc0592c96a291aa171c762f1a5a01fbbf0c11b89ea1963b6148505dd6dc74581cf87a5453efac4117a37a19a0cac1a80815e3ff05d5b481e1b4d6380e9189b23720d5c19171bdbfe883ecc720bc5c494abdc4104ed9b536635c71709d61213cb866177e434602b88727f1fe443758c39978087456dd17267670490f8a27cdae026fc9b5b5befaeee20c7ec55b5fbd8574701831dae8a526aede47b5673c582f10d175c6201026cbc8809d336d79234b8bd6866f9db7c18e5161d60abbe24c572a9d3b0e001aabe4d91ba8d051f235528044d86810198c185b0a625e87144d17615083d1103b5168f0cf04f39509dabe9209d01c2e14abd43626691040aa245c7e74f566f8945ab792d96fbd91ca4b012ada67a09b8f186f0c5ee2c202f142b6daf21543a50c0747027a832481bd83c1d478ad10cc828ad4b182ddc0763084225a66d2876500a293cb21bbc801f1403b7c81404983fc3a4c1e7c3e7fa1d1ede218e2a5b38a0312a9157b730d5ac76d7f476836fa069817fea6182e164056232bdbe8fef8c8e504c02eb3276de5da57fdc2aeb02440bca3e05301c44b2a27e9ef7f292d0fd69615eac943a8270a31b0d7c864b362449f79f447b82981ec9aa2382d792ad82d04bdce6158cfc7290eb09592a228e5e5f4676198b673177b0d2e8a54c6443465518c244f12328463182ef73c6857b7ef646f5119d3c4e466ecaa19e76ffe8d3baa34ad8a3b44ea5220009017cda94e40d2904fdd1568f36b76b543b89a28511266bbae1a20f021cfc7c9642f5c34ce9b13700bd46036a3730756dfa62d62d84329594cc60e0e4cdd9dc10b0d79612e8baeac4542d7fb9fc51d8392bd69b0476917e78cd30d59896fbea9a6c9e8cff12daef9c68f5df6ad93769b92dacc33668ea0d61a46ade9d37bd642224d23da7263f0ce60cbdf6fa096aaff9a5f54a754d72e4019b66bbb85741d83433e402d96b590ab50fbaca1dbe6c218e9e60963f76f321da565d6928ee9e369c75ed455db6a4452193bb175c7cd48817f6022d794baa56532d15b49a69fb48a7512bc45919c6c5b0821842f29bf19548f0e19400e8f6b8c8109aa42502aaf9108f786b562216246ffacde16e41f5b68273ccfb554f1d684c594e1c1e06cbfa14c563af74ccc2a527ae113860b2de5874123125a5b26eb421535cb87921a078b786ef2d58ad1c0e6586ea4423e15806497f6628126e2240e0d7909592ba13a4eb1d5d518561ec74d9a783cb724e02a28236ea6321725415ba9b4d7fa054e469a459782095c6a4819b0edfb974e86e4f42a6c72e7970c880fa01c920242c6ccf782ae5628a664394aea4ca307f8f6a4b7160ff03996db93cfd74bc86f49919b69885d66985cb9176f9154b0e2cbb6f1f4f547d019f6ea81cd341e9ec25dd39149d1dc9aa0e455be4641f355cbe909c1f97910a3f4ec8e61411069c5ef28a7570275c87ee486f1129355c47adff01d9255edef1ef8de29f309cddcdbef9a83509635fd102417fdb6235854590da95124f493f06a27b55494f9ff13ade61ac0fe55f1b22249733cea1a443732bbe0b0b8c0866171b4bfa90bb44a40afcdd21dd4eda3438af89b842e9b8395b195b1df68a46fa66a4799835ebc433d4b5a68e5f58860f164d989e0e91d43c137b87657c9fc3aabf70e8dc109d9eeac80c715d6ac93d0b694dd5aab4c123c6c57c0a3aef9dda488113db32d209fce8f91fb0f74d9ba33d774f04076d57e2bc944635552310e4c5e973b2fe6944c40c44ed65ed38504e3f629cc9d92f412081c7705486e6375184c4b087c7dc61b0dd191a721b02e34a5182ecfbf01e8402df45c71e98c9be6d1880b4080e93303e3e99cb6e9c6dc5e3e3ac89ea56557c9e39ca61642c5b6bb9f447410c127cda6ac4ca1382ee34095b8bf41f4300b040a931e2422893315f994d68dc5c5828ab80b30f04edff4413e76f3a39fbd67430c88dd5ae4f32d28942c6d795e80f9035328e93da0333d0f8cac589b070591fd469cd3e947e9218b71014245b8fa72f240a1b8db08b14a1d3d38712fef658064e5a6bc4d01c2ea2e0e7baebc295f640d901185f345ff96135c2566bf695a86a30fe91f277ec281fde25d52c5654c6d621561d271c66f96b905e23c22696106a1c8c8683630d8b575fe4db6cb674dcdc4f86f3370b2da6676a444902943f047ef5a4328cee4a0a292381a1881953e3225490fc910c47129670bd673f9b1bfd84f194890890366a81f891a5138b7e0bf5fa5a88d3ede6b1b0f7993bf931da26ed7ff23da51407fb4f181e8baed2c199e1ad8b4fdedd4700bf60a7876c8baab7901775b8f1abadbe5fc56dd041e5c66a35eee1090778e5e072a5c72d8955ffbfb9baa6e681c2493ceafa64fb29a3f4ac0acaf1b0dcb70e12b81c844acfcfe676ea429ba52145ec2a96c6d440d0fd9b6a21dd2a8797abfc61a26327c887ca2d7a90e753bcb85bdc7fc36a13d9874ec7135006f9c333f36ffb957cf87e52fda971f44525fe77ce0b3a894f16a63f6bcc392a6aab0d34f9c2ac4f1dbc78e71da4029475e6781798da2e3405979c7307184c00a84d6df3d7ed2d5dcfc8b3b38ed23028a06d3e5ece94ec09f156e86a270dba434a4d570be63c5751350d8425c48cb6a085d28ab6ee233c39627241811be8dd2c566a5e962d39e082ca1e016b3c91ae403c65bd396691d6f0a353081083d947f113b12ed98eee0d62f7a633d1fc80b92e342aa6f9b89748885ced86cf057693c0b92e3f55f3289a75da71bbab44eb25d9e490bb570c003101b60cc37062cd2a1e09ee95c53400008f1d041b8bdce572fb52dd07634375ddc58b6d15f03a7978682adeba65fe2be356e10bf6e2c6bb3fcd9c4c30cd41526de209368bf88e71ea0c87a9b9a8a190774015349a8012d0ef1d52f30916bd704d6759dbe834c5532d3ca9603acf20f732185236b1d5b5ff2039822bfa873b1be166d1e67b4cb80cfb0a5b841d89017c3cba23fcf7b7139dbb7306bc4c22bf3e7a05b5a6fc04d2d566a4218329c4d0319b7778e5c7270a2449fe31b18a3b92efa19224a199e83a83f61365a0d3907b17573e208c220482ec841b0bf6a72d95046bd0c2ccef4ee1340cb36dda648cb20242ddcd8a6f7fe1b810e58c7a1f75200ac20643c4100665fd419b26b476017154e407a0a9adb2f48a0f72cd09eb014b6200c9ca3962622f8f9f72e3f58edaae41b4b7f21428aef674c610ad831c00c168ea802fe05852871a949e7f0e70f716662c41950bcc5cf0398a4cac09e65e1a02b4942a2c0d77571b002294c53e56b2b75f33fa4c7a50cb920a3d633dc2cfe4462aa194d1846cd35355a42c294e1f76e411144f3047a2b00db10e619240e143137b4d09c0d3b52c5d778975d2f3e583c55d2ec7c50abd35feed46422188391435cff42b207f3c4036569b5a49b885b2311e856398c360bd7177f946a123e9dac91d2246b7a8f84a4726c905fbc39ef2bcb21c58de26803eeb6d0485c74c7e5ca6e98542171700137089c1356dfa54210924daef4d5ab6410e4568205d78f5f20c520120ec0fc08caaa5e3599d0562ed3ca53b9c796e09bf63cecc14de03aa352ca486f895988cfdea9166383a019b9a8d2342eec4ed164308499847beb612bd32fc42d303faaa8ef4d0cd6c1c7bcfd8fdfb3466567806539819633060950052c4119bfad48424bc6f98514ea4b8236666fb84ee3dca246debb9c0298efc3826b618ab178b0d75c2a0bf462983ac02d15aa691a03fe12e54858e0448cd470e5a764e7128ed2f83b11697949042f40bed0e817b6cd400bb0b2828706a62cba008aa0063bcb94257289dc05ac009dd84c515d64feff9e78aba2f052d08447aeee3b307875661fa86cd068240e0fa536d225246369b9ab4613171174396868dfb522672c21f012e01ebb7a9f70d087f280fab4e217626fe5651defbaca66829c073771b95aa464c0ffaa98d824c8bf2029e1e971431c78d457d03127541805228cbd02721175186b04bdce81b8c6fabc03bcfbad1a828fc17de00409023713d71cfa05d6096657c86f8861ca15c635f6d49b552e6f7082fdaab11420a4667e62b922cdf8b082630454ba0d02d877c619a1ed4d4e24ff529256e0d5cb1009e6be9b2e63beacbb69f8e4c9d7dbf68319088152b42f13047ca6d597563905713ee72b0017a40146f24dc304a3c594d15349150c7debeba1e78a64b5894a89278e2155db0a2af4c2067bb8a6c446791a93f3dcfd4841fc6e024a7ac23ca1dbf922daef0a60d98f3e82206423b6ef896cbe1caae5f7723e1b0a35e33b63d1b847e3a1f8b11ab195e162d42c9f0cfae8395a48664db0b208707828995d3994fbef8188f90729fae25265819b9dc560b01df0eba3e76acc3f305ed91aefaf6800a654496d289fc7112ee79ba33d79f9d1739802c2c1cc7df61c2a45ae82d639d135ea33909316caffc82349c72344d8d86f5a9f2c4dff2cb80029203883e16d23a9a6485c7bd28846495e804878740abb144093c8b9ab780aa41d47a7ce6ed89a26ad8d36c7c8dc0fad45cac8e07e30c0573f37862b098879d416e494338460f4061e050ed5b0b26b1f31b0917eb4d5ef41c6baec42c611df52d2834253f785968ad66125daade9f8470cd1f24bff829c4091242ede5eeb6b65a905361f0c6df4a1fa8628b5bd7170e72cdc64d21cdd7f80f780fd7de80d7f4ba2f36b656df3aa37c2f2ac73bbeca3a7b9e54e73e8e5053f8e456b48ca6f5775b498bad8d8adbc4c84aa3227141595e03a5d63d97b1d58f1f2ae61fad30cd92b7891147a123952c35098195528744e50c71cbdd32ab1fd36040e703ed8f72fde4dade0605f0c73229a8ae0c22675a51dbc6ad99a81a015f8cf6ec80a4ac3f2eda98bc7b9deb808d00180dc3843c60fc3af99215b0ded80d48655d7ad8b4b49757043635fd13ff0b423a9889ecfb7ee22675f937dba74aaaeccc9ff92d03a0335e797c44c15035926918c21ce3a7665392c32213522c51df851b943e0b874031e8826d35e6a134573e9f98129c8716fba9b7bb33361eb0783cf39cc495827bf35226446906e28a0035c638e457fa328e6fa36a2364eccc3d6ada8bf7d6cb1e583b0f30edaebe306e330c18603266318e702b5ccf2385f540fdfa9a982732c528339a17c953d5bcbaf422161095fc278bb63573aad670d7af2ae6f2a9576a795533aba44dd1e807604ccd2bf0091c5b2bdfce3558eac9a3880afe43847302202d230d0b339c284b4a8bbdddbf661cbdd288616b4846acc979d2ec0e076604baa4e5ed08e79cb584ee91f17d243b4c22afa18cede54045cca7996ea9f5a195ba8e3f3ee3821bb0ba3113a724d3852c98d413775daf0a66b7415295bf2bf85db6b0a24ff2c752e7f44dc6879b69ca1a0871d58dc4549458c247f3daf8cb04cd24a084470cc83cae3b032b5204008cda4b8cbaa398cb8c78ded0b121d8b65c204754996d3909caa83c306e787f677005c3f11c4191845a115a889ef46fb0c9c23eb3f0d9d365513bfea75212a35bec299af6478c2dc868c4d37edf51c082cba7fd5c73a1cc8b478efe8993756234818b593f39b4b64f468895a525cf8458fb2c27c9303262eb4f39e6d5ad8945c83e3fe6b0548bf8180f4ff5cd2f9e73a1573e167801e87afd44213ded5df97b48f644b582823d28796475ca5d63d12e4581fc690aed986c0ae7580b1396cf177bb6e992bbaea5f0736db4092607dd0e5de9ad4cf88e5abcbb39a3dc6c276f129c44125ca5310eb5374ba3e3b99f505567ab2e6bd3ea837e2c99d969861a07013f331416ab3aebd830e97125607aeb9c1c4e427b057c9d0cd515b5120ac2b380163e8f2b054aec370369606d2e92649aa218bdba95909b50f3ec73cf0a76a85a0cbf8eb6ebb5ee6c3563fac43c6c5ce57de98dd89277d7b93a4d1cdb844720ca517d0f7c2c3228c2c83d72f393c7c68e3b8c3e9ae63c8c2babc3d1d17fead4bbb33cc036436c79487c2103aac367f11081bec1b3f79ce0d92405a0aa79db9e3d5f0d3f4a7ab6b73265c053206c93ecf6b0374a64db0599feefbe540fd0abf3541920371731e064d3543441b73f9ac070a25289ad6d823350e9e69f71f274f5cf6eaf92010438bb7b9f575a0355e799eb350842548cdf5cb99b5e8248fb802222cc50e84eb83029a153e9659c00048d03984a5af621b6bff0a57bb28b649f712b3fb63e1c38a907cea0496ab4c6e93b6181cd10d17a75e2e1e5635abde1e2541b11cee915473d8ab5f363a45f4a1763c1b5f2c0b50f9ee86b0e6070b0ecc10491945919675d5bcc89f4df72d1aed1f14f461688472f02a76eb83b00fc1479ef53c53033f0948740e9af604387ca431bf63b07eecebada44987caf327cd0fe4ffbc6620f4b06dfb20bea019ed3f88fa57ed815d0cdfb1181a97118f44fedc6a7657e0ea2d22054649009a11c5c18c3c9347cc2378879ef298d5fc4f845779d3266a22098fa909a2ee1ea6196925e4e88b9b0c69034a5c5177894ab91f2c4635efab8b7ff76809d219227d76ac120d2e37c99af508e5e83a0ecbec963a9e20e258e82b8edf03b684fb84d100b0de849ea986c3512e5438a09fde771630d5fba2828d60a8fce771e565fbe7c287914fadf33442ab10e4402488e86e3dbe444367ad805488d7c04e3f04a1894bcedfe2c8a22cfc4583ad8ef8a7256e580fa7620112545fb1b2b7fee398abbf88fe1d642b66ea760251f1b1060eef80b3aaf1846864f6578863ab8c8f56add7303c684ea44b7fed4735e8164853992db873b6058dead1353d3bc5c90016d643645c5f12620f5125ca371e2798ea7e0787b84d621ed27f61b75931bc999d3b95e13e96604a2e9587b5843c69517fa43ef1b2db3b87a9286f2b580145b757813d6997ca1ae1a747cec0257d40e3894bf9da759840133308618ed415299a5a5a0adc21c607364912876ead015b007092131b9c6638aa2b466e0692558bff834bb00be45ce54547cd7b09c187cbc962fb101f3e5989067b5c92a7fa7bc3187020a4bd521f8b3077fed173798ec5520d3df7b7b8ad1a2f1f8c81b7b6d1029bc95872b5e05f0e28d9e0c7d2ce780ec905bda16d9d3c1a99e30d9098d881a5ba2ba35e27a0de6864ccd65ea6e161a9414f2b219472f64f56eb11403d5bd6607aee3adabdb2aeac44f4e541c1220f51e425943233ae409b9f256f53fa719bf97857c2537a022af58f0e0f73801933e4d0f4622d496d531ec9738d235b1269b91c3b4170c70117f50e676b4de672ec90b835e28416a5fffaa6238fe0a8fed322bc6d605611bb78c54294cc0b04d9d559d81ac2d858374642bd5b44f935c6c497af7defde6b6ecc0abf114d25ec2ef820e18580176a9a72ec8a3642f6437cdc6b2ecc940e4183507f39df596e13a9ec2f39ea6e6c1aa1f138de40a41dbd01a47a1c5a0298315f5f10bab7bd90b59443cc860b4cfaf9a285a437af1a08535078d9e882ae00fb61800d034e7908fcd637ae5d2f1cdbcd7fc6c4395643209d36457a23812a861d9bd9e4f424c91a419ade6fb3311c8a6725b02e140534475c27ecf692c009ecb050e0fb3a529bd079f5c694bb9cdf2dc4259e72d20244f29d55fc8e344a01440f24f3f858a9b28153aeb20073d8daeb3d7df39ea7c5caec2f5bf6e4fd42ab400a960453bd64703eff2536d768226c178d6c2eb08370f29c3c98437dd39ab1ddceb2cc9880e80e788c5a0abee07e8c4cc9354c680daeeb5ce8abd583f5f6495c97d3789a28a0e8119d0a521820625cc889381ac2f6af8e1429b424ee4ebf532dbe2d362ee83450d279de5b81fbadc983feb0739d6a3a92ba80d6cf2f608100b5624fe4d40d1a0b3a88f2e1854b510b1cdb320cc74f156c58f0a05792cdbf2cc86cef561a5ee44ad23f127f0906548c43aceb45bffeda69e7ac36839d5e437c581cf9d74abdb0c107f057a1ce8a0f44dd98efcd479b78af04eebf79b73b455a5d6280338f49a0fd0aaa95bac31dc093dbafa779f0561045c45e39579659682130d5d9cc14266f80285761b8b01bb1188725814ca510859ffe298fce0caf782d3df346518bb6b5f93962df7ec014c1f3cfe59e608a0c5f4c4ffbceacb3a2d6fb922c1cc88c7e2a5a3b4c0d4b2747d35e5591f5debd98db269d04f11e5e47719fa248c2ed685d0dd0decf259de14237128c6c81e01ccd1e838571921f40acc69481acb24994b1afccf829f19ed3b926d0f002990941b310389be5df33a5db9e263a21f89c2619556ab5e18139e860131af5aa457e8c70baaf067002be38a237e14845124863506827e3338dfdbb02833b3980de77a3b19853a021089301eac72b923a82f951aae6a32d9fd4ab0118f172ed893629cc08d2ba83ab6a95ead9b93661ba683e2216f7d050be5261c9a78e1c413c7d4cfb01fcc6cd782b4e6a73841d942ca5f6e66261cf010f86cd881ea0c368d4e36e76f4264df80b2d3d70db808828c578a8cea7d5877ed6918daf8282906901af350dfe3ad0cc5f646225cc7804495e7f2a9d1357d0c3cb04453255ff85d07a7dc862c16dd13af47ffdfccc7c7b8af959d13c7632d14599d8e232cd2b661542a9db7c13bb43e1a043bfb26369ab2a9758c649e9b9243172d4fd825e2b3e83d1bf3722ad5cb11e0c88eb5a3744e92fb68f6c3923d30c0108ba5443d5525fc5b486a0699b4bd07deb43157f0ac7b48b7c3ee3705a75977cee7840890ed55c4afc6cf5310ec71b9400727d532bbbd7229de2bb06c5963c376340633348e2b58f44a0720435efd3ec47008973357768e46870ed97cc5df95fad7f2ebe36a8ea485d080bed9c6fe32864195b09acf3d7d77961f30ad8c4c28318bb392cb4bb209ac3a46423f99cf0fb68eb41ae5a20f92c3f1f182ece88f894df2cfdaa9c571adfa21b3a0520349d9c1b805b37b22ac6af1873198f96c3ed75302bdd70891cf6de73d77997f9874622d98a54f7166044e46a5d03928b04d575a4c62b4e9d737028263cb23abb0c54e6a6394560a3c4c41fb9a81d4b8c0dd02ee28359b09d307aa6414db1818add8aff337e1840b5472486df798ab2891f4eb90bd3d30b88cec04100f8b4755c51e6658f85484d170ffa5f74e25a2fe358dcfe6bc8605e3749cdb4f224a22abf9b2c2204639d7295c11e0bd5a5cd799763e0180acb46697481486c8a6ed51f55ac0d21110cc0c675055438fe986890bfe27bd4a9a0c3edc0b9bbebdc36cc17a82ebee7aacb447a7e8e46b3fec01a9204124e8576ad1280353958c1bb5afe99f3456027b580725268ea69f026212ed4affe895e8524df5ba61eeb6a315390e043cb8b38edb787e10aa17f8565cd970b19ba1d645d3d2f9409e208a144b7711767d0a5f4634b1108eafc2217e353aa1fc9b08ef5bc30f76df04314457a2a851e077b6913c561502d165ea1a799652f84498946a55091fb00439c822806385efb45dae5193f2ca3a0cc8e1fc61251d24b1a4eef4054d4eacde246737687e0fbb9620c473baa4af572d18706ddab01480d4d362eb84089c1fdd268ae0fb073e20983f0d4b24ae08375d2a96971e7f00c720ba4fac7e91f512bcb7f1261f44607e37b076c4f981bda94d98f3c3a5c252237f536d5925be89ac285b9c8376ffbd076ae67540333441c47091acdd1b4837b0202f91e144ce0ed3730ca00a9f29bebc99cea960fe5f7eb4b39c31bb32c6fa9c25a69ee627becb30b6544e1e36a85c85842cc6994896d6524b986d2b8a887d1c400e840e38e95c0749fc9a94ec72a2b56aa7878a7a57d3ed9f7d2815dac7e6b0bb4dd9577f4d3eb2d0e595334be0d3e2024a2ff016e3dd0a438f80edee027d960560cfb134e2d379bb269e095bcec48a50dc0a6300fddb226c30ec6490a099a6d73423f1956b93b65c329b6db6e505941de3cd71c5e8660b14423f13c66fc495a372fd4c6c6383fb8e51308fc7dbe9b20b524e5cf69505b1e129b9b17d602e5a71ea4ae87342365bb09b38b36b6e41f06921c5a7603015f240cec14e707e19c8a52f7c3c06582ccd202bcb28f4888bc3da1596ef47a534804882211304d2e5588118e51e02c7c80c8e0494da0240fa95f285f038e38077d2b72621d5d6502ba155e5b3111c7e9d732224628d2df666213ca02f3799c60fe5842009d775572b21caa1b4f4b5e8971819798a8dc2443e2182c424d53ea420cbf8121e3d33e926530eb813321d1c8e66a5335031867da2775d33397694a3b99610ef28516f36863bda460e030493e228a3e05090a4c282d7582ea47bd2e6639889f7402a8c5dc3b3b4792acff4145f71d2c3b046ef1f785cbd40bd8ba4f03216efcb8d170f9a57cefc8021c3b6effeb3832b2877b949b7e21e3a3762fae5acca50bfcfa42b7078a787281190b48c112691254e1ee05e76166eb02a15c1f0a2f798d6075733dcbad07dcd6ccfae49b3e72a680c70909b49159bb252faa165b315cd21b94799fa0943d16a811d99b26b4f989ab83a94a1af215ed39b3f7ce82a9fc755e06d54412f047d0563d22693d23cbd68a22514ac625219e072499e3cd88aad567768dd72160e3ae5423a3bb69d1800ced4aa6478bfe4ae482982620fc2c13dddf17bec8cffbd1ec474e2b54f940157d50c8746e39da188132f9fb4736e080c2998b974c40c39c9b6cda41339b7572bb4d9343ef0a5cbf39b078de9b02b1ef5cd2d96d0b01eac92959c3916fd67f02be372dc0597e0f8580459220097cb31b57b48764704c128c3d5717926a4bc19e710ad9942738ebdccede6268b1633f2e166e5b288010544409f38fac8c04a0aaa7bb0096d6a80cc4b277c96082f7708343ee75dace338e2ad5bab98ce960d702fd5b0d50a82179f119365d03d8e808a24c870d7f93ddb3de6503d5975749813db21ff2da05160f624395ecd4d7105f94c29b4fca1bdf679323f9f09802401747f2e6153f6b9fbe10fe58713f302f0561ef32918320626a4802b79ce9a5d37ea0538f369d7668da8c229c1bcfc74e28103f215fe594c7fb00eca702ad88d15e5308ce121ff36bb3f8d0ef7eb8d7ec6e3fd34d7c299781afafcee80e889a62aeaba61d9c0712aed98ad98e0203596aa3004e1f320dfd296a6352aa3b4f96abbf97495035b1ab569bd9fce8a5e43375a1ff5e8bd429251b83d18e4c7c0dbdf976a8f9c67ab47662d6dadcd81d7656e65d1ef55a92d3b28d983444b79afaabecd8ce7ab13bbe2af53644d7c84a05f3776266b56a4b915272b79d584c246676d576a7f490b8902da1664385163d31a9cc05822e21e3e574b3da816ca7748ac26d4c4f58da5ff6415d7bc4892850b46094cc714edd4e645e00d033a384ed190621d5648d13e3cf627b95edbc0123054a32ab5047200267502b77830c98ead4f7b2b53f03e97f1c8fe88aa6bd04802f54521024fa2ed4b2dcadbca650c225cc365b020b78ad45b4f5963d6ecae4ae669bff44f7071bcda9c147c41146b0420cd0e0e626ddd70aef200fabd00b691adc626c372a6a0aae0edbced7d190453a11e62cb436b75ed10eafd7ef30d52cddddb4162ab4559f182f73f715522651440dbb5a795e1248cb98d28bcd890e8d1b1b76986f4ee28643b6713cfae0bbbed63f6d943402fb4865028fcc594b736b2ae235cf581cb777ad8aaa299e858adcc3b1a3a8471654dcd43aae4cc04079ee2faefb8d4441606e29b51348d4f3e5d4ccce1231407b70c87bf8e0b3a98db5edf260cee79738cbb94c0de0c0e574107fb1a3cd02a771d6bb49dbe5b9f1d8a424e47086dbfa1a39d042cb74bf9847027c020dbb8c01bd7fa0a016191569f5740ba96c5328ee07919544e01dcf6227c561c02fe84f6f965d158a36562d4032ed7fc94e974569c7852b0c39521c5208fdfa6dc98eaa938ade1a88d5ee1ab76d8e88539955a887740e706d642adb4f35f523a3d59a4a768d7f02807f44bb17b774827da75eb3b981fd7eda15dd28f87238df1334ed71fe312aded08e14f7e807fe89f9399a1d90b0f9e898c86b3047a143418dbc97d2a38f54af905b89aa5d51336447aae870b572ddc62f6abf0758376160942b6553db715af6b8fbe24b91a932fdab0fdbb73b3541e3e052c62ca6de3e6946db8d389a4d2cfc458739cc0130d68d630ee7a89bc873463d70a6bfdb622186f5e11b6c90d40f22832c94bb1ffed011191f5688c3bc74d5c804876de404faba41b8801ca7f283990b16b2829154c716ccb8b20dbc5291d7e2edf4a6d521d6a9c07fd55ba5d00bc5a25b54e4144b9c50ffcc871a97ad15130763a583bc87ded3817ef72ef1da36c7d39f5131c4984a7ffdfd47a6d9e10750bba66789829a1dade80cfd25b8b0ea95c1709b0b89496f91cb45ea302988893b148d970ba2cb3945293d5108ba500dd083370cf6863ca41d096d98a5fa7932697bd62707647bbc254aef8e03c847a0efee814cb47016a63fd1e6942028596b28e6a3f56b07c93c7ce2f4bbd5500e87b3e5b6017b9a861aa564a7ff1e4af02a1b9c414b88b14db22f60908c4a99671bb44e6ac3d7a94320ef7877c2b6a9af4d27b33fb72e22acb4155cb6ccddc92687a65402122d7885114ad49a93e88856e8f2b498a30bd14cba2708cebc914428906fc11773f30e601c6f02a1f0d5537ba1b5f3956cd831b46d6044bc1928378ddbe42a3a30d890457216898aa43c663c8de69356ddcfccba16752a80cf62f630c2f455c3743102f0aca0deadb9450d3a7dab5871411838123b80b3e6de36d26d05b3ab869905c01c8af28624af28e8cf1440ce3766a589da66ab677d6f399b501163dd444f2433f7dc0f46ed05dcc75b8c8d5329d667c6bd8706023052358325320a0ebf7a5b38f56ae7809d59a65ef1c1da76f11da7dada80449f66d6d96bb47dbe2afbc234619f398433b2c59d4536c12773c84d7ce65e8b563b5babea511929742343e4c4c075614bc1017b37b34322b332d859405d84c7e43d10b0afef6c487d269cecd6c8697c942ec87a0d9b9df521989a6781cd1964515fb5ebb6093b6a39cb06e50802b563224572e086b07e300311beb9938f62ad1da250eb08ffa7dba4247d131b132c856348044c404e39cba9b178f2505b0d284342e7a955fe79f582f579995d2db0ecc504d62fb3d5c1628d9fe5abbde055aeb1a4911c0112ec66094b7751cf9dcb5ceb6d14b4921ea436ef628373cc7dbd57b94c61fba0e7fab1174aae71743ad8ad0371e40263d4c9bd6308ef773e1c5dedc20c86355150790b88035a8077375fb17a6b8fcdbd99ae1b63c870d5bb59cf4ea68dacf9b1d583628e8e1f5be9333cd4849f019a60a3ece4eea26e5562115431795c9a3ad38a19eb1ee88237f7eb358cf04d0001d4b5a7562bad92ac596b7af7507505ea13331490d62e4f11cb728373fe8970eb8ed8fd98b9c7dd24a33422a40e92bbd0583940c6f235a406f2e7e69f5ea2018f37aebea9da7ba14aba08fa78c284e1b9a5f49c4de9bb3fce615af502873c1ca972c6c7450f6812aa21f79c71e0c48bdd517aec1e0161ede0430f5418ad2244a75ed3004a85d6c6a35a4de32047da2d801ecda169a515ffccd7d59d586a30d7be1b5cc3cf0164f8be9e940c49b321a6ce609caa0b8d80d069fc92b8b0de54dac6988ab4a3819d1b1883bb3483507235e557236bd54a1a1c1f592a633c1fc26bcfc3194e4d88097d39ed0adbaace4cb7929f521a16f25b14111aa7915078ed0d9815469f30bb125865a980463052d1c05ef7f35f526dfe6ab07a8f8a585d183344ed27612ba9488520a20b444699a744ef180f2bddf049e24f863946b73054cc20bf562ead7faa54d067426a001408b0be8f192353b30ac936a223aecb4f8cc50e396423298184c6528d63e79838a3cd7b09b2644270894729eda19b404cc0d3efd8adfc5f2a1c7328aaa56b792360e5f1d55532af5e7a8a2c34135b10ea744091cfa0530f3aabfdce302263eb517433e052652ec9283c677797983f5e83331ab8889f9df16965da1fc1a10b6fe8de92c0896f16dd668d1b5b4ee0070007a04ef2e8f1b198f7b171edbbe87961838fdd1ca1c0b9af772a2ad749ae91152005b22f840c5a5ec5e6c1329f738514015063ee0dc7aa25e780fa21c146278c16e37061dc073381d517653dc91d22cfb81af3ddf12c7d09d954e79357b3b7e79d473811d7af19d31d67bb0be7c8a11caa8f74cfe476d2a8a86072edb65e16bbcbd9c08468ead9b6883a312a7f418fec7c39a6ada4b0e92b9a39d1e91d3ba827810b0b255f242118db6006c2035d73847cbe242b8604bb10784c1d0a9033b42e335f44c475926f5ee20940d013066201d7e5893434275df925afb78c9ebeab1f65d98bff97538810819b0fcce08ea4f825c2377c73d3d42ecefd6de7236df543b24d66e6a4af1f3cfe2d61a1cba012894ae1c2692e7e04f0f4ff4c4c74dbecebbed4c852acbce9db4c216fc80d88ff60d30283b9efd9b110267632637e87a31a3a6f890274b21fcfc26ec27ebd9955410532dc84f5879c10ce992142dff909f7eed6c4f21d8f3ce89a21f4feffff78842bde69fc2e9ae378ddea8a88ba45e5aa813b582938c829404afefaacbbcdea14ee19869e6d1b889204cf82166115954c3cd6954537bb831722e5061c013a6eebbdeb89c1367135c4043a432d7f4bda75dd73915ae0ca5482dcb793a85a6ba54714e3e5f2ce3b0cc7980750a47c06baf055aff3a9d96f2be8dcac20e1053540fdcb99cfd91675c6f0a271aa0058c8175ca1c914c07ed715b71a600da780d4c951205b0516471d3a992773dfddc985fa00cb8ca844b8d12fff00a522169111016ec9b47fd4c98028c3f6bb3ceea7be0a2b925c548f19463c9b93243a5b6ab174fac78ff0129ed0df519a1d0ac498f7df3eaaa2bfc0ac5d3df0504512fd1f9762248c62d089db1d14697b2e7abb316ad3e18ce1ce4435122ecb238110eeed8f4cd730f995b852bef6c564e8c655bb8f4e04bf2fef74ca5648608219ff1736e7ed3515c8f9c25b667ef0a3d6f0e1844e48f7a094a7e5f3207e6d957a90392b65100b88b483ca8c7e7baf8d64250207ef371d9b04742ed29ac810cf1bc81f2ed58c22859159b9f2fe935cb66fc5e8d5f5cd5f818b0fdf5081a7c6890690ffde93671202d5d2fde622e19b00f8bcf12e87dc9d6dd7c95ab8fe6b31676bab3af50abc1aa5377cff0949a6bea7b877b8e8e131f584337503a63f2198a357aec550d784008cf8936ecd883a6ed16d2f07c4ab4451d499334bbb0fd8121d1b706d578318a3982060f7f99cd55daf02e14ec4bd5181a16a401bdc5be74ce6841072d0ee73036e54bf2339a9903ee69408d64142b2c6b99974e2160e7874632c07980f94a9db339db8b48bc8614d30027e912eff9ceba6c0988c789d93761aaf910d089f0ca438a05076f4bd345091c38d7bd67fd3976a9641d230cc0d0353c93a8c98b2628366acf02a151ffea6023fa5946b5d7f4a245563c2221f5486e9d8910ff913b034eac06a3c5ca6399935a43fddec0e9d3d46b30ec39f36944ed0a1d58dd977bd71d2d0c0f2f4005471e561f8963dca86bcef221c4fe0c50ba11d65273778bbcbcfcebe271ec845d1b70cbe32e6ecb9804c29d01e943120462628523e342ba47f92ccd6a9c0eb48acec40e6ee992c447a37cb441762bd383c0375d76e9eb0868b59ba04c52fdf6d5b7b08554c8456c340639739b9444eb9e53d7fc52c42cde8561514fcdb19ea77cfc1948e5f3a3e0de5729de00c3ba3591cd7e0d17649b1a1980a23173090f6459e975bad3544f4144c0f67beeb31f0634b7a4ea5509df40bd0c7a1ff77dac35731a82e7ee2c96f389c6b8475c0fa980e2df05cb661804f59b148d84f23ac07649fd23388e78a977824c72763588d4489ece2a673fa8f6f0c83c3708be3a047174e2e73761fe489dac54fbad90c70d95daad4a8b9cc58f5d713819581cb183867760214a09adf7f5c76daa26a979c9aff28e9b0b03b3b452d48c93c2108a85028380c2155977931160cdcbbdbfe00a82ccb78b39c036b2002944e954fbb9566899fa4fb48d04d3b70e634e7a5d186b7e46564d493660b4d1e3d50113c10e359e8c4a9fbd05de061e37422a03a8d0f12b4c46470fb330f76ff538dc20bda86a288b5a0d3c01631433da43b268d0e4e98fd01b35b4b90c1c0c69992513385d8c388b0f00040e3dd1806bb167d0275c6b88ecdeafff5550dcab3cff1cb3f101e4c0f7b8af853764632dea6c0ed754ca077578c4e765b25fb8ce01f6d509b18116029b21a6a488dda056a80827d24c2d996236e31cec594bc5ac46a0cc5e7611bd4e44f0f9c6df4657dace78fbdde3a2215db8b8d81b9c7e553286d0930b8f352acbced1ed373e82102c8600cf374c555ab34956cfa202803b046e48f06c04fd0753467161f5ccfc2717e37b1b7df11765929eb21d65d1a8964468b63efe99642c53be136be1146431c66c16469ac6a40ee0c4b8ee891d7540750aa003edb9f938505c53523f99630137ee4920d440a103dc8ae397f306263a47d1cb3755a36051fddec23eb6d081e6d8a000ee09446bb769c2e31a90bf2b2353779494b70f398e3932d6f61f96735c82b01f900060c1c2ae3c8fb2725f6345ce48a32c52e146d5d24ceff579208833d13862f7ba9fce828748cc5d4b4a272225383df7b429b98241a759c8e87026f18036f5899cebf53cbb42161b4b3aeb766fc3dc678d024ae220ef133ff302871f14a23f1e4bd5a2e968c72d62870d6e9e5a27e122de15c4f22e902eb8501e1333c8026efb7f327e861517c029984f5b082cf20718454a3a548d67e01241188e1d1812d2f694c113d85eb48033629eab67fd8c21ec707de3c3b3855f69ec186028907727f75356245e4f73b76e8249a902db2674412bbce0cbdd5791e48a7a6c50b9edc306a0ba6d51312038335a04c247223901029145ad970d00394b5a2ffa46bc31fd84223a1243c2d118dd45fa234df02a36c481407e9f444dd5f05e6389976a0aa83beeec28f8760117c29ecb4f311728014920a8753e5c6a6e2e2443b893481a655f6d60b65f99fea29bba50e4b33e02e1e726f6f021f181fe50ec257bca3506cbcf02656cd9a2c4e4ed8c2ba87d9999635046c5c992aa15c360190f4c80207526c347c83de9f6a9f07fb1c6dab723d932ac1f2b50b27fce856306850303cc14d7654a5e2f30d4a65ec8d361d146a89167adf78da1afb063c6f38b8d30b473ba78b6d972ac799c2b9d688f419a8f09cfd129e41cd829b653dff72d1146739cd47887c06862fee7b493d39c9e1362c4e166e817cc97fbfe9ee0b39640a925c1ebaf2f8af1b816d447eb9de5300884a703aed57b989ad6d251e215127336c2c1507a42fb92ae27ad3d87bf42952a0b553b75550117f1dce28f7dff541de8af4a953e07dee8be032c2c9c8a3c01134a54d805082e856940f3c737320ee393c37dc4ec150e276a8ef1be58f8f82f9e42ed65805c8d7e14f1b415dcd3362e29fa1a9b2c3e6e65108c81e325ea29b619e16011cc187261421e22ce3d25121f5971b393431f87034431c696f30432274b831529344a6adfbf98e7cce7b41210691563cdf176576205577b539b65aff7530fdd42f0f987be1018a98b9b0bdb9f4786b5bf01985ae90050772c82d8b5bb00f80ed7a526b0bdbc7f75459c89b4673a3b1a5ddc96d30350a2b61cde384d682fd0b04a564bac3afdefce3288b7645397dda4d1f03f59b49ba2cb87471d221faffeb2fb9c284e67ef9047098f4d625faf9248cbf13baf53f7ecc6260842bfa90497efe8c2c724d52f35a935894b87897c562eddf2401a93e8c2a7ad524cea76e1359d6c221fdddc648ec4fa9810a2ed0fde5cd2b238b1e7af3aa99abdb23f7a3eaa96743ba76824066ca32573d030ffeaa8380c9d0920270c318495f41f60690edfcd7cfa6d5b7e66491d63086dabfea2badfa8344eccab476fe57e3fcdeb5b5b3e4e7aead60076f43d446b939bb9e887356534312f7fbe6cba10362cf9e3f929cd4d499c07aa7f0eb52ba29e0ece941f5544d4ea47abe2444b7518cb4764aede0a981474307a926adda2da976221913069c794146022483ce732e5d2221dcabc2d448a9990bab948e479f9d80056ea9c9099205011ddd0c64f65ee40a8f864f1ee5c87f758648287fba01a7c5b30311a5aad168c55629ff68622d6e41b2be2ae1b3bf6fca561a0d50caf888e0c33fb3479912cf6870655159de175d8a53f43b02923d7b7e483d45832642b5fbb4bcfaaa91a1b59b3bedf013e1937262b73a7b1e0ab622d6e504b23b3443588533136c853a8a3b9bf8e66445765bcea3aa66eeb415b068e8341ad9a97749450d79e9ac60cba6b3d165dffc4a556ae842998385864ea3939dab8354d45097e608b62c3a1b4df627af54a5860caa285869e934baec80354a71e715125092ec2b473ae8217b2d0e51a9666e8a135869e8349aecb4bb49550dbd294eb0cbd0d9682d7bf550f2568313841a2034741a1d65471f209e69d08062014486ce4647d9ab0792c79606ab8573bc07c84ef8c207e0f6edc6e6e23ba1b9df4365e773e127b0fa7263b9b0ef7351416b987033f623fa7cba31b4b037df0c1d36e18c09749ec41aa3134287fb7e81d7c084011863410a46c381dd8de9b617404ac7ed34757f98a0f4a11b88c888b1b2693126ffbf2fac47c61f68b8610812ed9c00fa35e0c01cb3bfe0fbfc04d64bc60f2eb03104156d4e18fa2270e01cf9bfe0f17e82d64bf20f06d83204157e4e083d1272e0cc39ff826adae7274c8931b0c4e803d8fe4c0f4f4307fb6a45738e0e7593fe307a93419a79282cc060fdd1e77c4fd7095cd061fc7250b440fba6ccf3c289d985dbb9297a34b25161aa671240b812e66b0bb3d509884ecfd4de01cdb01bd29759408ed536f6fa7d289d6661d08c62626b83dc67994f3266ee9cefe84c43c907120944cad60870875ba88ec17d37f9da2c60770780ec59f202642d0fb6b0e1434e5f5c43230faf7e370f298d365edbc52eb46ba8ecec5b8d8ba0e27b7f71acc18b4dee8a82c61c2e6f6e49e9c01a9cdad1cb8fcc00820b97fee4d4cf83cf3dc71b4f3718fc7f08299c1870aa5d9ed956185f6b45c19cbb239d121641751b627d7ae25b1542d9c61c1115dc0f7c7927862b160394df0903f69a0f5ce31427e31e4fa6751d1de62a4255a1d352707d8469a5615db691a5608456724b38cd90d024c6d02b4eb2db76e4328cb9c92ae39fa4d589354e2b247c541740aa0b95080a883b249092ecb321d8d24e9f6c4281710b80ae0fd948668abae50e131aef447b45c43dae9532abd5963275915cda12241a2ff7063dcb8aba8b2c8517e7e783ceeff8b88548ab2faec965c2ab876e6ca1071ac5d83ea5733a1dbb841c261e1f7835e20844b879e2a7d41c2ee4d0f394e22377832735e8eea621ba9c6669b03a6aa96198c53ef9e266a79500073dabdfda06bc5e4c5868cd43b6084a26301cd97399f5f3fdab912c78acda8955aa2a10f037835ee2f57905298e2ef9dea068287548b80c76c824f9e0e87a303d21c884e9cabdc904ad81fdbe9d178ac953adbaedcd5b6795a85734acc09d74d6eb8a84db39bb3ae20ef77c0086a40e9dc6f409ed965ad633dc2dedafe0b27905b5bff13a781eba46e13806e163aa32d7c6b559dc9814eb25243093ad433632631f9ce0b206dfc72b892e0b11b3700f4b8ba28362bcfa413c0585a937a169de14f61ad1e7df8368b3ae894aff6c4f5a3e9e4726ed8c566353bf5b0ba7381f67ffb6015698dc64d03f58b078169d512242bf457e0c795f9f8da99393c98a8094e5f66155dc9c90318c82f95f70b08313a6f7a1ffce7c99b12e957b835fb5cdd0f685471a504814391e95eb7df9ba07a983c614552a58ff53b1a3ae5e211c3124a20ef5f5a21dbff43d8c249f0d0a93d32a2c34ea36c36465ff7faa399ba601607864b0d6fcf30d051f7e426a893cb84edd08f6be62c676b082941c83c7c12d0a1720c69573ec5ca7883c9f3ab14a8df4dd3ec71550dd36bf740b5c4385f207e1c0bf6f8ffbffe2313139404350f202593ae4c27cfe690ee8d56fd3c98f7625f7c0a570105f92769aaaa7cb8c88059da5a222468941954ba943361e2b669d9a40d6993f216156327552825b33cb54c2b5cadcf409b680a909294166ac708d19eef1406dd2a6941e5241eff56df054b823ea291749b72e0023708202fde7e60f1ba35a0d4da48d96f1d9659ce23ba50596544598108439a70e7828485286cfb79000eb3a74d2857dc21512f1855d7a91cdf644e04bdf2cfa99db10b021d2294f32d71b3653e434de9867253cb590646e897452bad678aad0456c2b0c3a91117fdab472c92c7b2e75424ea44840e3f6e8ea08e21716da2341de16223d540943601fa18fcc1ac7f90a0a1bb8ce4ebf8b8c7dcc8ada72586f27d92e844113829e7418b7063115a9ca794555305c5291a2a87271104bd78bd45482b1986d991635a84aaa41a7dcd21888460dd4c336fe7dc4a28f99401f35a173095fa60f7b7851898bf0ba3eed89e755591dea0acb712a4f60cef01fb3b76b249543b20f637f129fae0997772602bfffdf51d0998cf7d057abca106775da2aedbbc567a172caaad29e17fadefc11bd0779d95d253c4e540020b6034c7213d6f292f7e49fb77cfa1f60a2c6f9e744366f574245535ff24ea22ce8603e11768661b791311a09ca7efc2ae640dbafb7911442673d5f123dcd3b54dca444e37085d3c2347c92be720c308a3b7d15e740c9fb58c82ca6f0a170848f02f20b81a2d1612f3f8ee7759afaff832746ee8ccc57b198262bb7c5c7c37cda0647b583b000e2ca8f9c62a378346d09979f397d6915a43d68908049668c6868e90b42fdfade416d9ee925a669f8835dd4bbfa28b6a92e926893d4323efc510c80329e43d1f905e2da41a81e76e2f7d5d213c82735fd57344d1bbf2793eb25b739f17d9d6b2996050bbe26dfd001bdda4dd7e0b1e47673a8a872f6995042fa171e96a087127578d01ae1243e685a12810cf871fa34466e06bf26ac5b83bc1996f587c95e10ac648791e07905fe77951aeabc0ade3c95e11e1ea8e53a50b49cf600836121e6bc3e10fc1e8d2b2333a77a8bdade9502376dffa89c2d06eb3dc4a73071432d6b954a9a2ddbcdeaeede259cff326d473257d1c51255f95cd10a9951240e762c5df1a4fbcfdb5b09723f3226154fb2d448db70dd4c152d2d7701d8665cdc77d9e0ef4cd2f2390e7fbeade412a64cc9a450f33e6871cab12d582f0459c10df22d9e25fd1a0c96324ae91a88020bc7edfa45a075cc8d8700508f4ac2b23c01fc5ee215baa8747800b41247e7149b4124d2230722f846644bf43a32079360a12a51748c8e17c3148bd027628c344e03e75ca63f183de65b005eb6332045ea08b0833e55a83bb275af1fe5f7516b2a359bddce35b1c81e0430508b97e29a4bca00910d3fad47dff7c271d2a1fbbff88587300b45d2a7709187c5babda3cfbd559d3a745c7e5d052b68f7ee24c185dea59ab263079b17ae2cd4b90ef43ebcae78fda0b70cd888446ef6eb2a3591e983602de7a1a117d0a6e829d2a9d571f070bfdd9c4dd08b325fb40469bc52fd6326ea074d5cb8f5252e81a964574356f618e48e641a2808684d99b115f9da650bca81df9a9cc3598e7fdffee60c52cccb5e1b13d49a9d276a2ba313996d377654250ed5844cecee2f9ec335b82135e91efe48c6a300be001dd988e2d9c964ba298d0fc5144fc148e0bf246be4776b1187e8386c6f122c0be0d932853e076e1a6581ae757333feb380189154f4c104a0ba8dee5fa348857eb8b630c0176ae83c9624536b3bf1a1f191a84a5918f14f2ac6e1296bd10d6dba503c17fd08315e23ece9f588523f1d17a6b07f7c6330404722574a9f025ead56ea8aa31572d21ff01e563155186690845ad3d08e355a146ef1acc187704e95500b4fe2b9851de412526ab5323ab52d9b86cd3318234929f6ce7e5a2416cd587163ce0b8ca0c361ae12930de2f9eaca9e964d1479a661082ca30cad1a20560a65a45f0dfd2efca14cfa8a90b2c51370b8d66505dc5e10ebebbb6a1661a8246433fd6ae33f6dd1826008e2d0d9bf2552d0e7b1cfd68443e8283af6a2b230cb5a9cde09218588f7fa5320163a2288e78a52c3392cb2c1a5fb21ee0d77412f436d0a18887836061b90750a80d091419ed958a8db231807b38829aacdb4e9a4fbc6497442cc7ea06238d446f8b41e94580591b56f2819bb4632ef1604c332f8af2c9f2509b36c84e27947103d8b0417c6af20b0d1752d3ae73c208662c4fb415f9e8f67846662f1f4a0ee5480d9f2c10a0f82bbc95812f2240024e3cc3d8afaafc75606be8558d4bb10104f26f477c247b3509ce1dab05e2a0af144330b9dfab8e7551a2489a8c6ae70bd28b722756ecb732c82894a4311acd89b5b36549a3442d06910a2790b4fda02d6dc28737b4ab1508ef0d250cfeda3fa3ed0264e3ce386c790bddc9f98e3161338c353787a03054f3ac7d377a12db4684fadfef25789c76a77d5e6b4a29c769e880900dc06b0b7c5ba4414877f5ca0d7701db235afda173be04921526391989ce759aa606bcba204c1e56b04344fb90f652e89868c7a5aad9c1e2c8dfe43123ec174f16c870f51e6bdf60c78c2b0ea78fa250c9ecbd17aefcf98045a1491b066a35d36929008307757bcdfb8f6b0b58c2b9dba53dddc706ab64fedd7e00874f6f79129a157d980921c0b66811b5310afc6c86d36cc2f95c660045c9b2bf8dbfc9b4e1d4aa4e6efdce8c29b4c1c6e20d9c9058adac70d865239cc7fe542577cf87f7964e42a7ba8219e21977b1a639dfc154e2099768790619a848d25df4ffd52cc4cf263dfd9c110587274923ea1cc1f0f2f3e434bfe9ac177a51f35e360999e76999b96b762efec147fd5d63629b66228cbdd129dafb8d4a6a155fea53399c9da36c9cfd61e7c43d943c6c8b08a3f00b173da1bc66f5def7ee63e928a4fbd365c04bc2205de46453e1257105885b63906c4cf862af7a0fe41d945d58bf829ecfd15cb339ea7ebde93ba8db9700079bd38aa39465b2d1a6d6d0cfb26b3588bdd56ff572daf8030b43473889712e0d5dddf476f334490413c22decccc7677f79632056012d1125512b0710685669ce94ad8cbd0cc98bc124dac8cf9189af308cd279971bdcc6cea082ad29833b329b22f6753202a3e949987e94657cc0c0a8dcc9765cc0c0acdc9e49566768cc92bcd4c89f9293b56ba1e2633cf298cc61e6636857dfc1d3ba546588ad72955beeb942ab16c092c4f31c7533743a5745418dde3f8ee54465dee5488cade9d2ad1d84f9928ec7712f21d948531b1127f41c7738f3f053ba5c477748f4f65ea18c723fbf52a67bb2cc7bd673bfc29d7b9c32fdf0592ef3a7547d0f0d459a1e1836878be19091abe1217060580e55be056ce82a54525eb47eb97bd883f918988253651000c3f2cccaf1b43ad1a609e030b8bdc47933041009825f8a86ee75b335d50df612d743c43ddd8656a0cc37014c5f014c5711cc7117ba8057e0056e6a29b1bf975365d5ea0ef88e270f40766d3057511e60ed3f92b679c637e60c23c8cf93218dffac1398c855bbe156281bdb484e0effc81297e88bb8c5baf0ec07c8b4a122646c20c6700f31cddcc8f0613a32ed342f3d36082e88c09137b9523288391ae191326f62a47500623c39a191326f62a475016c2c89a191326f62a4750060b4ddcd4cc98b1720461373737a12cfc1b133533264cec558ea00c96c20636ca52fc14ec064c71f3301b133533264cec558ea00cdb98a899316162af121cb18d899a191326f62a4750e7fa2161e6508b860ea61c386e2cd9a8a1843eea72d1d0c19403c78d251b35945ce80a432acc888104e3c8a888e889487285211566c44082716454441225c9d81102f2e9e149e1858b77118649327684807c7a78527811ba08faa1e1b4d03961c662858a9b9ba07785bc1be4dda7779dde05f2ee8fd36d7ad7c7e9f67877c7a962080a4272829c4fef0404c58f261f3d6432580a14de15f26e90779fde753a1d88fbe3dda6d3f571ba3d4e77c7898708311104f6e46402f9d1e4a307def1ae907783bcfbf4aed3bb404ef787db74fa387b9c3b4e585612a6952a3d5009a58451c2276156e8246c1262853b8437844cc225e10f092f46742982cb1611436c11220b10577ed0b252854a0fa014300af804cc029d804dc01d402cf0069009f80397c0a064437e487abbdd784c412102db01757ade19727a31a24b115c88d81a620b0f2164a9901762bb05f920b5a77ffa9c95659f5f707a2723401e48911fffc385a66f6ac1c7fb60a1c7f72022fba91dbfe35d1df236bc926c0a960ac9efda4ecf3b414e5dbe527bcaefbe707ade713a5d23a7e71d20a72e5b29f223bfebc2e979a7e9d4e51ed0fc6e0ba7e71d1fa72eb3707adee971ea5c22a7e79d1da72e47c943703e5f1f305d3f9debf71280a993b99030fd75b2170d66463d0953176afd5e3298b021b21ff2348408791d41823cd3d3d3e7d8f1688f57f2f1359adec68f5f02f2379c80fc781b5ea9c9478f1db09f92bdd3e390c95c3c60b221344e5d6845888e53175609c274eac21e9e729cba908a138e53174a0172e3d485517e2c9dbaf049938d531766f9a871ea42273d944e5dd884c71962ed404f5db8834b07ec75fc0a4c4c3f9423c7ab8003c7cfb871e3632c2d3d920d1b0f43f644e81729bd510d2554e6fa29d8d7f823188ca4e13a5d1d2b9cbaf006a6336492438553172ec131e3d485bf1b314e1d88c412d2a903bdd88071ea40236a1c9d3ab08b92d1a9038b408b4e1dc885868ce8d48144902ab85e854f9a31e365c488f13b48482f047b17b27f41f429143d8fd1f71cbd0f8c23a3b7e1958a886430f2a75c0fe3815cae7088747df82e15924e1d38c40c19a70edc1263e7d4814220099d3a300b0ca053070271e473eac02b463da70efca188e7d4815a44299c3ad08aecc5a903ab0cc15c9c3ab08750887ca10f0202fa1f1f9fa7f5f43c0e0fcfb748e196c2ebbc78f127b85e05ec57c89e850b19cc15fe14f92e7e4692373b21f9374f0a059d3a500ad0cfa903a3f8d04e1df8a4e774308ba7c5a9039da4a073eac0262f4e3875e00e2e66a70ec492b13875e00db015a70e64b2737adeb9d1b97ee09216b7168f828ecee7dc4e38e1cfdbec6d78a575f67f233f4675bd8c863d0d4ef625a254fc89dc8a47b1b2781b5e29b742854cabb7dbdffc54f82cc230c54f41c1093fc5eb94a037a7db0285539791d0c93975d9cb09e7a9cb46cc589cb98815284e5de6a2221391b7f210790bcee9792785cef5cb42c0b2a6a0dcfee6f3fb0d8a87c2e495d49f3a71e24d9428f13534343f2323f3668c1af33051b28fa9e1831af7373f95e25d5fbe47e1ce235a0d6f279229e2cdcd4fa538a5a6307af37e93e2754ad014a78be2cc409c3071eaf2951235a72eff4073662d19f3d4652b3167ae223b730f998aebcc527214573c615979277f7e82cefcd28c073003d82b002f93651713c458ecf30cf6ae2f26f964ccf5ae0198790c3f361bbba063166801b0fc955f662deeb2c7b18fe972160c064b78c2986f9a389fba1f510b0873ba4c8b0c0b961cd3027381a538fe6249c03c47974bd9cbcc77812f1bcc8c8239cbf5c56c42c3afc1d429c959367395e7eb03a6875a68ce3976ea7017d7598339fef822d6cab31f4490c555beeb0cc377cdc60f67648ab02c4d9b2397ab3ccbc7ef3bdf3ac7536a97b350f0c559784ae5ac5206300c6ee58ccf9c7f63ac24c4d80b2cfcf0d4f90f29c85cb874e9027a01bdfc50ec4c402a547e28f863026281586013b0099805668151c02859d92867e528394aa692a9e42ab94ad6ca5af9ca0f2bd842773f68fed27fc0a2858ee7ceb7b211d6c257f0159c0567c15bf096ad2d2e5c8c6cd9057e2e5cba74712feee5f77399600aff94a569daa07847c98849196c61a19285a33caea285c48205a4924f300bb885ca08fbc1b0602c4f3e2cbf5cbfbc550e200b9a43ac2d2ae04fccca6199554631636c605e16c392c7addfaffcfdb494596816b140a3f1c7c4d4b2b9f2e396962dddb8356e6929b5c04853cc722d189d98f56216386e658959f9077b988ed4d292b332d622b1b46492bc02ba307f364c1e0b34cb2c3000c0f283a50cb5802068cb812e4010044110049934f939a7d0ccc898316398155219c71f9a9917c6d2f2f333b15ea42b67c9390bb805e6d48d5d462f2808923f14044f1d99bd80f91cc39f0c265fa0c35db016c60ab59a74c91abd44f951414192491510d4321e81b13096880583583c3189352201e639588b89dd0877f1f2d36272050b4b48e29f90062316b95552d1813f1f71e96a92256b4b942d2e2216712c5db8fcd2b19865134c52cc594d30c12530cfd1fd60c182053fd6e2f9732ef125f62ddff22ddfd28245fc71b044d945771466d10ab75c9901b568995a4c2d30b133bb4af2acc1251698e7904f8e3f86fefe29dee64dd0bc2ed4329f3c75b8cba885d4123e76a7711df89bf177613175f908f308337f560cccd3bc0b0bc62a67f06b9de195531766c93f34dc9299845b190b0db9e4265a3ee675a1d6cca90bb150fc325d4e1db885e287c9f82c491ce6f006933ac05c47986d7561a1750415595d6e74365b26b4c2d7d56481313258567ed76fec62e613fc3c03df613f85046b0914d87964ca54f8fba119f6f9480da612f94830319560b133890c6bc9efa7043ba7e0d395caa54b0424ca4c449e339812aad7f962b4fc29d876fdd4eb84b25d27945886e11209d692df0f2567e1ef17e6eca5260b15491a2b56aa54e9a1072a5468a4d048a189421385e609cd139a2c9a2c1a27344e689ad034a1d98166071a2c1a2c2b557aa0422385260acd139a2c1a27344d68b06876c83be2d3dcc08466090dcd0f092fa4115d8ae002123133ce6c953327cd0d32270d13f3a4591273d2fc60ce192464e78c17f29c310276ce74799d3345c4ce192ee339b39577c407cf1922f28e488a643813c1f09c6281866118034a92ae300447700c43309c8a41cb300cc3300c438c418c3126c9f008315b5d645a4780657571fd8e306e75398259238382ab8ba9cbd1b162a54a951e7aa04245478a8e149d283a51749ee83cd1c9d2c9d271a2e344a7894e139d1d7476d0c1d2c1b252a5072a3a5274a2e83cd1c9d271a2d344074b47e7063cf35098dcc04486c9127389ce2f46e787040c125e645e8c8042731ea131a24b97225e4570897121822687889c2d119f53395be7d40e674e9d1b644e1d26e6a9b324e6d4f9c19c3948c8ce1c2f3946e474c92922874bde09df15cf9cad1c22f24e38862318ea727e20064118d0f1d4c5808ed8cb277fe3528ce1d8eb63207e4761e19727c62008822008829b049f04c1715c020a5931d92c420949189360042996e3388e6429ce7c2cd0b22cc5532792a5383e398ae2388ee3388e38843480798e0eeb9005055f9412e5499693263be422ac12260634f6302aa0ae2398306739d3e5fc50f35d46301dcda18822b870218288adad2186d8b2450821b2640102882b577ef8414bab082e446c0db145882c405cd1c2395809533c142656aaa0a8d2834d0f544e509162424a1457942737af2759b02c27a49326b8c90e63f853e2e78095c3732a3c4b9478f0c51427cec10a8a13e750c5e6c439f470e2c439503171e21ca4b84e9c4394d7897378023b710e59e4897370824f9c43937ce21cb04e9cc30e79077cbd48d7c3cc874db1404b9c5223959a190e47c5cfb33d8e314f25f3332fa379d979238a271ad2cca840746646054e9168789ab35dce0f856181c2cc302aea3016960cd46502313c5d0f3b75382c330eb1f8e463717c3df8ae536afc9d7f0c4f5d0e1a3e8e4d8d288e208ab11290f34349327f16c2562884228af86da12216bf72e5a7d3e5045b68ce162aea60a13fe450f9a122c6ba0105dfb5041333c94558376479c158180beb9025270030cf712de38f22f6d0b5902499c753f7a3256721497114732e6d20b5d0104617a2302508636aa9f99a1f9833355ff32e2da6163346e3d2326ed1fc4c890f3f94215de3169630679980294b10fc2998120cb544136f0206e675c2c088a2288ae2a97bc1381a8b791dee82a5448d0e63cdfcccccbb7e60bacccb9430182ce493a04ca8050373865a5a74396bdc8ad1326ebdde8c8981f981f992c53e16c34243517c61fda061b9a50bb57ed4727621b56830cd103097113c475766a1e08be64fbd74216abe64c49c858aa21923f353668c8c280573fdc09489af504b7c61c102937f609a322f23669932a76ea4a2c514b3b46262c42c2d5a3ab28b6ffd0034df34dfa5c58cf918ac05fec0df0b06ccfa8109fec02dd9969618f8b0d72be79c73ce39e79c3fe79c73ce39e7fc0393d4895965a8c5d4815ba79885823f8a6299655600861fcf5e3b98f8074be74384436c09b708110a91650cb300118e405c19c32b3f84e30f5aa38c8c8c703ca1c8cc9c5064c213ca0c11c6baa11f34c5cb00eecb0285929f8808869fff6914c5cfdf448e25497efe1caeb2fcfc365e2e254e7690800faecf4f03f67a7d7e193198120e98a0882768fe2359cc8c7dfe21987f59a0b2138a298016c83e5361148af92f0b14e68422739e47a64c2581810550f0a7c4fc91295331b4e0882f5f50f0a7c0484de122b928e4c93be2ce8b634e532e223fef9438a5cbc6462e7ad5e41d98f9b0d8b9a7c08f7d2e5f0673ee29f077f8304531e79e02cfed0f823fe7d07974ca3869d83873ec389b9e8814c1f2295c2e307f60b20c03d90420164abecb04a278ba8a30c9532482093ef8347217148ba985820f8a5a5aba90e4933ce0066d22f9398360c6191479d0f107c5a2386672144791071dad54e9818a94284fb29c34d9018bc4012a9e3a120c45324bac08986b08ee5446dd29a9d73b1afe944ec91446dd29f1f34fe9309a7976721ec7a6c68c951ebe744ad0d7e9fabbb17765efbede75bd1bf32ef9eef8aef86ef86ef930a73b95617fba5359e64ee5d8bb537908fccb3ba00b760416e3fac945a50d24cbb71cc91e298ee354cea11a9ef0536431cf493830f0dda64686c4194fc7114f1f42c1ff713767cc13684e388fe41c39cf2353c412e494d144499e70953630978a1c0cc5943045921c3086cacca698334f312b633536389fb3c393895cb372e6ba1fd45fafd70bff8e58bdbd5d4e7dbdde9677408c31c6397f0a79e2259809be0107678683f338382c707056e0e0a8c0c9e1bc8a63c34c40a3233c277c129c5f92934e789d9f0407ff72d2f99a7d129c23b3f3c827c1b1faf3c89410e765711e9922e2f47211794259711e99329a78f077b9a89c429e78f073534a3527a978e13c8a07df969354bc6e1ee793e0c0ce140ffadfa498a1989527666689990dcee7ecf0802594c8f2cc0c603bfc29f07728c40f6808ba8758cb464bc4780b6bf920d4caf2831028f85bdc8282bf45110c8182220fcc8e2c27f6309c978daba634c318598e6176987799ec3d167b87c1de5faf7797ebbd2cdfc3f09d24dfc7f13dffcfcf0d453291c8844826f22d4b9e62a7ce85c0bfa64ce4598eec789d3a07c22a472612afbc36ca53e73ff4686422516b272313c9c81d6522f1c7d3d5a14c247e3e7f6c3f584707ebe8601d1daca3837574b08e0ed6d1c13a3a584707ebe8601d1dccc373c3ce0e939c9c25fff89789449d239948d4b1ca44a2ce9b89441d3133dcb10c771cc3dd51b87b0d25771fe2a68c88ddfafa6e6456dba55dedda1e0b773722c351304805a550021e6e37b831820f4e10697a22430542b8622ad203cb8c0820d530458a2e061141c8b2a9408b570a35e91053b490d001072a15234e43130a90e447031e905a28e0eb42041d088480081cf8012b63aaf9a00700d855e0756b8185234c60f14291931676ec97171bd38e15647478e1da36211ca1041d10028c114a0000c74d8a0e000100740351313290c4460735588d15c83a4103acb0c06602095040cbe7801392308a32e4a0438d262b3268a33c70b3b9154935d941010d4821e3023fe0218a013890f48207bf0d20e108146ce80101299060041c20907778992592f0820998f023c20045c81409808090227855411071ea0119b254cbd16488530a888020084638ec8798672a97bbe72f4d80594942a2a984800e06e70615a6380b5a3fa41071d144e3c70e3660a1463384d409e286f396e2caa6090500811403c020e683736a0657a10e801de11342102c10b31a1841a3cb05742c3842161fe028e1e30029a889c10309ac4e2011a500aa2f4828b2011bb09ae01433e1beb5dbe3b537d65703ead5debd83eaf95a37ea81a29e5dff6d59766d7baf736fdbbeefb6b8f5ddf980b8bb8ebb17d130acfbab5af7ad56f74d797ff5aeacef71edbf6deb3ebb6aa86fdfdfebeb5d7a7372f721eefec2dd5537471b1d4e534c2c60ad2a4c3951820a6d080d07baf442e03a10008a19371fac8069fc8245051e5e8f25199d64050d8c282568300018380801c986850536f01a62ad8126a1c4620321311a805065c3879b2110e0496c851142b0d4648996186680aab1000a70dc68226a40016637406c70e3051f97921005e8808a0353582d20d1447eb0832448890195410798d0f0f2f1013801060c06702f4b1840115c8070fa007a81910ff890c11990c104767490054a0d0f005108e1f5aa8a40069ac4643269ce872384400215f98acc925c0392219c52c864bd40063f66c00fe8415013826c80113e0db1628894870868816026043326b0430241041161490f1909ac70819384183039a10736b03016e43004aa163f6e0b743f171e9081151d5ac023085522a872b285642015188368e0c70c03630438b042060a80be6880480b6e0d8498380192ad221c7081d708742fb460a5024146d082837944151784600b87228ed470c48021a0c00713f842a50042371c57382043cf06033e52202b5f2aab8a1e373660d6c21a10b1c1021857333d495948600e4ea063053bf4882400034baea0c90d56f059b77a5078c135832482480203230004d0010486080cee0a6b101c40bdf0cb32850858530a60828b0d14296842d1e306a82236408006f4fc0891c0cf950fac7da660c88109745009410222e0c34f10349ad02aa540528024bc479c4a50423d0258811138906844a8e2118a010b94a410832c533748ca35473c820762cc5910a306ccd8c42ac0e4080bb02ac20538601535017d01162a18220719c8e000001620a0ca94a01c8892f0800807643986441486d808605c810112546ce0082828e0882c3872307315025608d48d210e380fb8216aa08223c3a1640217b871268102257288401e3e4678d1c20c7290c3c88f164619a0c10c1e16dc000209a0054008355244acd4601aa5b436701f52704300a284ec78c96429213402892401b460cb4b4eede582a1188c70f001013a18692023012db79107b2b829c27465c8550415a4afb208b82040c8c98cc00954cf0a340cc0080b2cb8e24190110e98e0063e54f180038f2d9e982add1180504309025040a27c41c64e0c701228c19627d70f1c9020284ce009461245e4c87eb907c4200126048064f32496d02a5f685b357af860008d263af8411168524532cca4c48c98f22a75140570b9c117262211f8c8a064d5916b22534343c406250fa060003c94d8c096a549161548b1010953327efc94800438ac3382250cdc968a105fe051c3830ea6d42d4d10410f0294e8d0c1127e0491814696a02e14188253d3161652892b2620e8c18a103027129e72f8c0323962c7d11102288ad914b0571cf4f80c0491030d146058820d705e5e86823001cf89116c60c608b096ca0908e9962a252b410c0dc125016402ce07378c3a2ce8c9e0880e36308059096ca0f180bb3b4d104ac0ab020c04f8014410546098a508d03315b88500c5c9450390e41082b1a574f1b0457412c193fc25091792f8f2e5cb97adf7d6bdab1785af71f7a524772fe2a67864bbb48d6b5bb7578b82414a851c21e771b9fb8cbb03b93b1137c31fb64b038aaabd385c0af086c63d0b00c3c0c81dc360c91d8be00036c8b8e31a669001490b777c045be11b6ab51c359e50251c2de8a8010403a90109a9b1708309c89210251f3b949c6e6014f8318f1027dc1d083b706f826397cbdd95e0c2dd7d70f741c8dd43f0727716d45213eeee849160b83b8cbb07c1b5ef6a289e8ffdf7a65db7bdb1ebb72fbbbeaaa5585faec60aae83c7dd752ee5ee2db889a3b83bea6eba3b3e8ab96323f7edd286868e866abd55bf7b07e57374bb1d11fd00f9081109dd8e7ed4202320220d647484eb898241aae7dd3ed767bfbe56eaa673379f778df269a3dcf446f3896257965d773edbd53b888f3b2e72778c8954fdde74cf4a7fee8d62f5eedbaab707d7f6b8baaaed7dee5dabd0dcabae556f95f25eefa0d2dd9a52a5af73efb369ee7d5747b1edeef7faef5e77afea75d7ebf99cdcf19090bbb7ae86e1afa05eab2bd5aa7efbfedbe3e9f74dfddd3394bbdbb8e9446c97f6f27041ee8e3190bbadebea67d35735ebfa5eedbeace6e95d8fb7febba6eefb51ecfabe29cf6d719f3ac6c1dd53b8e936dc5de6a66f772fe1a6bfa0eadd9ae27eebf70aea1fd73edbae6ffa576ecbd3bcedd25c74cf26dc1dc74db7d92eeda6a96a55a9eb7373b7cfaddded529f2b3775a1d69d3bfe71c73eee98e6a13bee0959a00573addf0f75300ce20618ec9581234792e4073f09fef08f4c79227ffc234b6a78f19394ff7a3f8fd4f04ae27924c9f8afd37526294f26af84938cf8c5938618f0fd938c9885bd30806ba8215cc2a4860bd898af0ef8b0049c2da9614809fc235623939186b39c3d853f1826228e2fcec61106ce828c0f9e479428812fce6031e28c244f24e18b2e1b323e487e18d680647cac1492e48fe459434c297cf29560e26c494903f9e5cb9787c5dcfc1021e00f8b89007e7c4200bfd780047cac94832851121f9c1d51a2e4e44ae259434c4929cb969ac02767e1631911f1c7b306ac249e3560a5f014017e9741e11f315f94c09386982f4a4c8694f2298224630e1d307bf5608a5fc6de9560b259fed80cbf4c06c65cae25b197b972ece606f9a3147942b9ca3f9e50aec057419c61d82ce77fc11e36c296840f8bc59620793d7e7a3d7e24b097bd92dfac061594c087cd9630c14ae0d7a08252f82e93b9665829e7b03c7faee49a2d7195b325afd8ebfc814b9024011f76fece254c5e097f0db216c097cd902401df75fec0cfff047e7ecd9860a5d7bb664cb092eb61b32535a8a0f47a265809f6b03c9385b2a59b1fe1cbbe05f0635fce9694439428c11e3f92d76724b0c726e842fcd2351b1f2bbd40604ef917743ca5a05ce58772157ed8941fcb6e7e849fff29fc07f3680158091ae5f777253c6332654a051464325bc2243ca74ca950c3942915d03ce55a28f8180f81bda898f96130f06161962de55386433c95805807ccf30c061377e592196440f3e7107300e68f31c6307126853ffc720a445d611886ae27cb9074852048922ed73975240cc31004c37c04e3fc822f3e281e29c5f30557508292258d2c259e534750d72945fea8448a3ca7c0319ce9f2bbd803cc75f9c199ae7c5074bd836148957f7c319c4dd9a0af73eac8940d3a9e2f9803a32588ba74e5397504254f290fcf291095f27754470c9abfc4b90430976a8a052afe54f8f9df29163635339c5c24b531eafac1ac917af4c1ffc14ec060194441144471bea104c41ae666eff107bdc73ff41e7fd17bfc47eff127bdc7bff41e7f97f7f8bfbcc71fe63dfe31eff197798f3f8cf7f8c7788fbfe93dfe32dee33fe33dfe34dee35fe33dfe25bcc7df84f7f89ff01e7f1beff147e13dfe29bcc7ffc67bfc71bcc75f85f7f8aff01e7f16dee38f672e1c983f84bb918de9e567994ab2cc9f12cef2e3d4c442500457a0e03b7691e0f58097034cff01045b3aa9297226352545be4391797226f51a75e3f96628334fcea6623e7c984c6636ca649927f3ec252bc1989954cc3bfa7a851f03becc5718429921677994c5ca2432a4eb47d9cc14d86399cf301d79ba1eca4c8c6c0665e664f24a327b8aeca7ecf11d3f3973c1c86258244f29f2a958a019965d3e80794e1ac9d2f54a82c560de3f2727c5c8bc3f4f2e5a3165c5c7c0c862b097ab2475e0ffc0622f98eb55bac872243f89f82a3e89f8379f44fc149f447c1436274c94a8a1091fcaf833322a6638b3b08c993536389fb3c363c6c0c862b097ab24cf3389f81e9631b3c606e7733e89782ac14950647201301c9c1a1b1b9a9a9a19d39489c53088c10f3188658f716c6cfc6b6afc4dd33f16f32f4b518cbd7fcd0c8dcc8c2913631e49128322fbf0d19af308cecc79c446e63c5263c69c4762a5acc427899d0e3bc3d759bace58799ae459f3e369239620caaf042791c9a30d301c1c0737000bc7f21583316770706c6c6a6a4c33162bcb309499856159c662a659536363838363e2300730cf819533f25d33528afcd7bbc88791e36b016629fe52d8233f7c9dcbe572b95c2e97cb0583bd4b2451d84995d1d725d38102759d373a60a8eb334abe6bf69ae90051577e32bfe78ca714c6128180e5dc0504dddddddddddddddddddd3d56929ec1d0b174717087264eb29e449142a5872a790704330882200882200882e0396239c618638c31c618638c31c618638c71b8431327594fa248a1d243152b687ecf01630c00f31c188b67118e5ac6152a706e52a0b03961a2444da699913163606431d8cb05cb3116cfe25d5a4cf790c5a8fb1959e4ffb752a5072a52a23cc972828be042c4d6105b84c802c415e7e179284caaa490420f2f5e5071e142cacece17b9532d1eff94f8507a5abc0daf1484d573ee409b35f139c1c9cf8b3f95f3402ffe94cee30f1f3f0942e16d7825a09f9cb7e1957c683d279229a7784a8927f9287cf83c274ee1c42f4eece2c43b276e7162144eac73e29c139f70e2f3c4b313ef90774216ffb12cd9856f29b74c2e365dde8608bc64178eba4cc062649131b682abe08cefba580a3abeebe227380b3bc14d6a4e1763e11b3013bc04ff62c6775dd71ddf756d796724a2a4ca3f1621f2d4b423870d1a328e86ce29fc5b09fa6617594607e4dbb251ce02ba207f0b4a6ea12417942449ac4ba265a54a0f54a4447992e5a4c90e58373059827f487831a24b115c88d81a628b105980b8f2836bc9381afae119c7711cc7f1e5c4fc9713737cf249243f546a07622b557aa02225ca932c274d76c0ba81c912fc3b62f5f67639d55684c853d38e1c3668c8381afae1d9c9f9711cc7714cb195a0f87c41252f069837e348821fce5e0c3063e78dec65e708338ee3885f87e25f8f4f4f82e607673730af0ba5c87f31406afc3d3e1546c52765e7d4897ff7a6847b4323f3325276ea669e3c7531ff3a6f605e8702e60cdfcbb739a74e9c5b09fa2a415fd8539938a74814e6dd9b12670e243628e8ded09c3992a0e33bfa9a3227150b5497d1f1d46d25af77a75ea76ee694314f1f0bf4754ac59c54200a73ea761214f68eca66b1192cc7754a813f190f60af4e0b85e1d98d0e10f5cfa80ec3503f7519c54f85758048d08c85488dbff32d927472267e4926e982ba8ee07057e9fa52049b50327cd86ba7c48502937c129f37ae177d3c6f98623fcca5d499361f622cdfd2c17f2881964bcb2c512507604116ea3f80600bc5df03e639309c9994cc3b2a8ab3d9ac14673fcb7997efca331c99accbe68332e679f3652c569653e2970f4e1d41c38cf3e2e3cca4c4530765f632efa828ce664c5e69663e93579abd79ce660fce66ae24ce746fce32a78ad8fb0d8e8c8ccc8dccb9656e6e5ee67170706ec2d94c443193a2f9dd0a14a3360f4b01f3b18f95b24ff1828039f3321813efd2c10cff84eb61647ec4f9f163b948850cc529ce58a498514101c0ffec080d5869f600983dceecc528ceab98bd1855517efefc295e06e7dc3832bf651ee76f665253f8559c5bc5aff87df32bce29f384323b99bcd29f47904c99c29f7f4a8ab7e195589c48a64ce1536a0add18c591a999a598e1d8e49df151cca0d0570e66f8afd7993a1b9b99a327666e888e6fa2c4ac6676b22b9668ce7744c3a79167662f464359cc6c09f6b2cfe5f947acde1e3a057ef9f2c50b6abe38d399680c9539754aa642d43ca9320a83c552bc3ef0fa14af0fb86064a79418839d2fe839e5f9f29c14392607983bbafef59e83822b28f801055ae38f5ab07021624bf632504b99c572099a45d8ef13e4d9bfb08c5fb3c39377c2ffc93be10fe59df08ff24ef83276c2b79177c2cf9177c2df9177c26fca3be13fe59df089e49df08be49d700cc79cf3c2410b60e5c36250683e2656c67e8a3f6c2a092a33fe2e4fa93146b5028d392ce6df8cc6a856a031a787a8eb159b79de89fd2833f3b18f819d33af99590c0acdebded70b067ce1170c765417f3af979a8abdecc7d7c59c6f46c5777d2d0f7ddbebd6acc6f1e6a2563dc4d52aab9d5a57b7c0b63d96de9d6f6b204643fc9bbede691b133072809113231d8c7eeefe482e7678dec5ceefdbda6bdfe7896a771fc5b24cee4e0477bfb9598415463a8c7248ddd2772321b99a657d2e8f4a1bc59845471409a168ab48062c2832819147daa5b5bd6a5c6d97fade5bfa3c8ff43c8ff43c8fe4c22f45b53b7767c1cd2222ee1af73b8d725fbb4e4fdb4525cfefb48a68cb699bd7bab8dfbfe4ee3d6e12457177dab39a6a8d32898c78fafbaf763b1fceb75fbd3dbaa446b53b88dedd7d1e429688cca12d77a7e2eefe3cb7c5b9baf7edfb9f8bf2b5acfeb7ed3184e54ecb45adb9df290e73c8e6eede338772b8f318fd1409f534312d0dbdaab5c6fd2e7ddb37ddf96ebbb4c650d5767bbf531c5c6842598426e04ec3b5cff3b1fa6db6d7b9a75747b9e9fbaebc7557db69d4deda55d5d42ae5253dc9c0f9d86954cdd5bd9ad6b8dad5bbbaedeaf66a5629eff5f5d835a9882828880cb65ddf9e8f77976eeddba554492e9ee7a70828c78e8c9b16f2ee75574bdf955dddddc6cd202f3423b6a0a02dbb5d7a0ba2423362338372a019b1212135d95c78ad9d826ebb5d7aab32835eb83b6da7b9ffbde6de7fd3dcfbb9db9bf6f6aabeab7bffb2e9eaa6549ffe66d7f465db1aa88f255eebded0bcb6c6bb7d3cd8d47d59ad81a89a5d715a6583e4a2d61c3bc5b1a36d9ff46d759b768aa32a75d5dcbb0e7959cdbb4a9bb4be51d5ee5072f7181a8675f37cbcd52ae5b5efef52df948661dddafdbdbebbc7b8630eb8d8ea3d018091700b136288d16206153875c079a005a660080d2049a2838c13945003bef18213b86323ee38c42eb8bb76db1b2672c72de4e0d8b5d65453d71e75add54c9f1bee8ebae923d292b03ddbaedbd554effa6ebfa9de667b764d73b71ed6c7d35ce8d777d356fa5fbcb9a895f7e273b73557b5f37b97b2ae7ed9f5b776d3dd4dabff38542142d60274a035ae47ef146aa735ada66e54cfa7a95cbdb5cbfa76bb5453adbbb4d6d35aaa56d337b7c5a9fa4d6fdaed69b5567bf5cebda9566b55ed6e97d65c8da3410043cc1e2cf71fa11782aed8f4b7e6b9e9f6b52b95769b5e305dfcb8fb0c377b8edc3d8a5daf766cfb6aaa77dfbebfdf15ea5f56afb71587f3ed57f58b5b73fbd5fb5dadf4ab77cdd535766d756e4d47a57b6b5eed2add6977b7bbdb4eb36c9abbd5f49baeefcaaefadd57bbd6aabeddaabe5ddb402c1019a237dbf6b690ad7d531a08113c6082e320ee8e898e68e1c455adae54addb7b0df5eff6f154adb63756ffd5eedf96fdf44dd57f59edea1cbbfed34f2f7d376f7d7954dac7a7a848e86868c8c84708061194060a82ba15dd848ed21fa01e57af2fdbbab85a0f12920b06bcdbe2dca895f72dfb0070a283edd2de5bdae3b5b7215a114da8e7a6d5f6d6a377e96df7ccb87b949b3b16d8c17277d2cd2492dc6f7be521216d24a45d73772b3777ccad7d7baf3eb99b7e7d78ed8d06e5cbbd6b948f0fd2eebd6feedf54ead6eea0dcb6a7ddd73bd5bbdec750b5aba3a256f77d566ba8df69eeb5ebd354eb66354eab9fe640e73e9a97ba389f9b1111d08d88c86748e8480ba537212321a89fa01b94518f7e53f7dd50beedea2856efad793efbd5bb5ddaf3d93efa96f636946ffb68b5adc16a2a5db35a71daeded76ab54edf5b5b977adaabd7a6f1d95f66abd54e76aafde526ecad36ebbd1dd2eadf1f67caeab5f9649d53b954d736c1055bf6edbebf99cdeb64792fbeee7b9ad6ffaee1632aada1a5a6d6f3d1ffac6b63dac521eeef8e9eaedf1966a34a9acefc64e71bc7ae3703e703e5e9f0f77eca4d5f65d79eb0e966dd7bdee766d8d9ed636daf669b74b6ba85adbd0516c0aa4c7f3adc032f950d92052b7f47552b5aad5f5b6fa9c80a8bad76b5fa777b55a7a57aba5d56ae95dad969090b4dbde6a3c2aed8e81f82e7dd31beef8c7eb6a2a0dc41d37611f5adf6e3ea7999c28eeeaba4ba930e04a90cce046cc138cf00734c0dd55374fe86d9776db2bef86917912715b5fcdcbbdab9bfaec522a0d4388f6d3a3ddf6d6c3a3d23d543df531f6bb9a4ab3ffaebf7db9f77988a03c90908a888282ecad857aad3be6a1b25aea96422121f1a8f46ddda992beb1e92e85327294db690e09a93654942348c8bbba69af765553d5765f69a99a8e4addf6dd3cfd32bd7bddb1b7beddd0ed5269d7f7a66cd4eaa4325db99aaabd6920e8937e53edd648dfd4869010184444404d4c4b3f4230829a9896ae6e6994dea1d5f6564bdfd4069023a2a226a6a5a422a2a01c326e5a4854bbdbfabd5272b59aea1c1292d5ca53f5f6d5761a75f5ee7cb715875bd5b7b7ea9b76f7959baeb715a7590d95db69aeb65dcde3b559450b762e9c9b2c76c0b6eb7b4b379bba2f10eda787e7d3aecebd1a3b8a1665b9e18517f810232b07067a30c4054090c417234b2d3039d578f8f0b143e9631cf95ce0b5ed0e2af7ea2bdcea6a215a6d6fda46fb742329e9c827e3a685c8b8692157efaaaebb5488d593d44de76af47c526dbb636baaf55d79abdbab69defab23eb7c6ae29af55ab522041422ad3cbfadadb0d6dafd21ddee5677392477ae8e10cec64165645194c7a0c164d60185c0685460eee10ae2073598a2188b19fc834cf8e7f842a602763881e3362c7188be2508665c718833907c624ce1883230c19674c661340301e31e919cb68601ec79dd7e330e7100b8718e7174642c62e177198418db12e639ccb20f926e33c86190721633c66fc039fc018cca509449084c126302e5182b80138e331639cc11acee1cb35946338a9c4620e380393398740e02b67ec22a608c71002c16e804dd943cf12c021b8138a19832e1e00eb007b76d3341d3b0e71c643c0657e81711673063116c23eb8c4b19c731e6be016398719ff8034188a12052c9b49911380c58c028718c49e9bf2bf70e8791dfd6d9800a0cf4c809d060a3288471c925886c126399748203e0271cee1e7986b078b18933f21108b1f9c5f639931c698c41809e75c0370c4ae1c8254f8cc3e8cc11eec82655c9238d3c82bf28aac0274d0710c1e73c6b2d004c38c22e78c471ce2b02b07c3c48c450c638431c6f82633913057c650658cccf8072e3106330e710eac22c3c8381996c92c6210679c61990c312882181b6110ef60178e618c63e015f90592b80c71c61809e3d144aec161c6628861641806f30a0c82398739c43072c629f20bbb7019668c311256915f2488c332c4181b3db67951ca00531031885d38b4c12e1712cc859b15f88410e73c665263b3c40f2c07c619678c718f93def31694e02e2c0cc19f051eb864616146441143521d5c20480eb6fc69460377e2c105da296d8103e1c14a0380cc5a1f3f78d075694a8768ece061c51172a4383f3078b0f18191c258c02807b21ca3d90b17e50037a1c8f6c501459f84d36c47ace8b145c93c5b136879fee7450a593c446061fb188b3f31e3593446dc26e6e01fd2e00ebabbebdbba73e2b5ee8d2bf7c91def38c1dda162f01519bac9d14b6f5be3b47a834a611c1915110d090501fd14716f72f71d375374d92e2d7d53b5268b016fc011fc4202fcc21de38bc72412643027f013c51889020d640879000a4fc49e586014c02fdce132f1c2b1a1e1e762216c015c017bc75879a33c1a5f600c9b97b8825f59e5575344069711d80023c470f013bffcc4588a18fc62ef39829fcb06269331441f71072625602812304378c32f661633037b647c4a1b992f3388299447a40c300694513ef9813c807cc6d728e507c2c614210f0c08c4612ce479dd1053205918538caf5117ab89d5b86c5c264816c026cc30a600a9cc205ef9e9e842ded774548448b1985126c4600f58236c8a9d18333984bc217b882560f00803c5300682600649b0045d2f9c1024839033314d2f19722431488643a14f884b14e08d0c2e16a2057e3052649019c39bd2c60c210e66386bef5f92f0c10cb6b8200b962bbe28a71cb09694549861d4b24418824f0b33a6245d68c1478f2f4108f1021638fc3449008d05e040062d48810f1ec000141f1a0a08f0bd386c170945e832040c84380107942479a1480b447cf4c07183c58a1326ac844009062e9004494d054ecbb280c1c10da678bf2f49282109455c3861424606294001097cf040073280430102507b8185213e7a30b5200814b040044d72d480062d48c1097c18c1049e0c00003414a18b0c60e0c308ac6860c94fab4c4b32b22e3c200207584e100210f440811c08a0d5da0b455c18c2b41403c9858cac0541606900037258a2d5175660bab114c37940440b8250010a4200821e3240011d0ab0c4c80a4c336220190d01b9989109fd0b0f88b8810ab0a0e0042100410628a0430e0520c0121dd48c1451c18786c4113b74c4c0d80007eb86011019f20301020ce0ca6a8aeb0b98446e82784466426981b0029902190a0eca40e00fa6c17ac014c037c122e3e01b32058802db8427b00917cdcc0c6886313118539622860286f3927191e548e671144510fbb8e4a5b3821fe9225d214c5944ba4015b127197a9ce5cef82a8fc2580c0e63632dac0265a04cb8858605fc46984cba421e998aa30bfc5e42626ac80323431eba11838478945182df8c1d366468c8e12bdce14209bf1eccf0228b0c584492614143861ca6007b7a789624a60083df38b2685a5222460900200e196cf8a1700d89d5c46a60b851a257ee57127e325e170e9b0e26e90265a25418801b6428439851058e1192c1071070bd88c192d24b0260324ca42143c208756817a8cc4023eebc6ebc50188b842f4818337c80071c3354000713e6cf12d96d87007ef8c17c3806d0200b8ac14270c018248a22195e248cf155c280464c384015af1b49f8bd4826995399e366e9c6cb9523e6a4caf8c0ef44c853f41a916864e30bb674be3081dfabccb1026a003f1134453cfe185f628cf1459212cce76a51e6185f240a990d574ed8c375a206078514265e9429e80082820caf92460ac9848c989ac85848a61091c022572c6cf1344817f90a7d441de1110d2cde8033d1c48fabbc81309662d8942f132e23196af4800d953b614e983356e0f70226b421a620ae70e584383140a08a197e341f0ce2c09e101463385f30c0085a160317c8a2450503157822002548acb6144edf6c2f1469818890204e4d3b56c8817424b48382ce091fa2e0045f8850840f5448d23953a020b35800049409fc585201494589186cfcc10a08a64481f224023c643520c84e0b1f1a0316f0e4f4050923a05a20c2107ca8b5323ae0b0e29262bcc828396019b966b08502519060149da881bd4a12e7c6031d28a2551f3d5660bab1843404e462460646163aa00001b061668b480418b84005940c116254645313ba20cb118424cd28729163066a008106208000030c20860738c00138f8e89114a3450c1f0132217b09bbfc103297d0073907e216a64196418e810b063121b20b720bb2959c011003592ad4e11ccca25421e2c850e413b904ae91a11167b20c3643980c135fd955969924c51c6210e3d1fd55e4ee29cc123cae7750e9cbae6ecf47abed6d657d2adc3158c2bd268bfb5ebfc601a6114d660d96bbeda3d855e7aadec5ce0c19cfae511a6a74b306caac69c1dd5170b366c8dd616ed6b8b03dae7d17bff3afd575b3ebfa31aedcd44d73b74fdf2b2823341acd05d5c7db8fbb28c4452593e607df2e8d75f5fba63d1ff7dd323450ee9e829b3432d0ecd8f5dd5afddced4d79ba55dfc58ebeb9be76d3f430698e5c65f59bfe36dda4b151597dba39d383192170edebdbbadbefb6b8d74ddffd3a8a4d5d775fe1eeaa71ddc46cb9bbf6b9afdebb14e7ee608975b8e315dc31131060007dd2bbaeeff602068c231846308a6010c118822104230806108c1f18308e8e8e8c8e8a8e888e868e848e828e808e7e8e60181d191919151911190d19091905190119fd18c1283a2a322a2a2a222a1a2a122a0a2a022afa29824174446444544444443444244414440444f4430463e868c868a86888686868486828680868e8670886d091909150911091d090909050901090d08f108ca0a320a3a0a220a2a0a120a1a0a020a0a09f201840474046404540444043404240414040403f40307e8e7e8c7e8a7e887e867e847e827e807e7e7e5653a6c6f3b131bc785e3b3b481ec98be715c33fcfc7f0ffffee38873bc6e18e6ff4c8c41ec996839d69da6005a6a90177b73dd28bc7667ba417a777ff2f9b8b3717b5baff2f4eef766c8fe4eabdd319334cf306d3dcb9ff5e5f1fd4ff5e9fd53ba4adb2be16cad7be3b5e7207dd3499723c4f8b16ffa6af6aa9dbcaa63dd39cc9d434b923bd3e1e6eebba4b55adebb64aee9edd8c39c2dd69b4edd2d496e7f3f270da6d6fbe637cbe5d1ad4ba7bdd162a0d956294cc9823ff197ff5aeb7b497de3ec6cf7856ef6a559a75f723f7cc811c0077b7b90943a5aadde15c4dd56e97f6fa78b51fda100da8c70707f4f343049442410505a94640b8a29e76a56dfda6ee8d66a55576bd72dfbd4669d7863baee18e95dc9dc93d94f120f710344275c728a6e18e5570c749ee389ab7beaccf5d7b688d2620b45fdf1eb7dd5bdf345ba3b9d8290e9fdd2ebdd572afdef9bd4b7bd8968d7adcaa6bb49da47d5369cf878c9b1662b5dba55bd7de5e8da6df94b76e279abafed5bb7e5a53d9158784e4b6b9d787aaec7ae3d3b4b6d3a81abbf29090acd61bb775a7509b9646d554bd7d3c2a5debe15a1ccbe48e7bad3b66dd310f8725d4e09e045e56fbf4529e8fd6ee0be5b393d20dad3906a080c2fffc8cd9b72ea2c0eaddcf9081020a3f23e955568b461e86c0c3291edae0618d502944c3a10808d92eed75dbbd5d9aabdfd5c7e728281d020a0a3a82d229908a831282822144f43344f43334946a7d23120a3a2afa81820143c8e7e68e7944ad3d546b5cad7d6bacde611ddcdd0537957002edd56ddfd4d5ef9a6beece7393870a40e0c4766952b7f4dd3e6e0bc4a3d22d0f45dcbd06c6b9af3d54dfd896e622954a77ae5ced9bfaf67da2e1da2cd6dd85b89965e3ee345b9babb2ad698f476bdcbfb9dbca63b3a1ea9a36697d83b6dbf77beb8a5b773d5eaaab6c36b5c7f3417ddaaa3cadd3d35e56efb7f5d677eb75cde91bbbee182e52f818ffe253f89d9ff1bdf5adbd7a17c3456f7d776ebbf4569bf1ffea9d8fcf6bb765a3569e77fb5c9bcdf6b4a8defa5e413d8f8bdefa7ecb7eee5dab76bee76ae7a6bb95b7ee4f9ff5b93d2f9bde6c3d6c9ffe9ba69ab7d9768dd2eeb36d6f7d3f4d9f5dd317aafdf67d9bd6b89a6daf36dbbb6bdb9ebdf57557aaf36dbbd487ed5d773ede6b8d7bf45b1ccba435aef66e9f4e4df5aeb7be494c1a57b3a1f58d16ee5908325eb0ae3d9489b6bf56ab69defaf2d61eaaddb606edcad5547aa74a5fb3d251ec7a55735b5c8d66b33d5313fabaf657effa5af96a379a56db1b6f4d9ff69bc6735bdcbbd79ad58b73a96a7aa7b23e2897e6ea5b02a8b88f9b09d8349ffaaafefdb6adfb54454441396e04c0e6ba4b369b8b9d5eea56b13e2424dbab484808f871f58b4bdf880b2a0e80044de70054dc3dfd47c00154df2a040e90e316d881089aaaa9c470b20314a7edada3d25eca53b5ea6a9af669df94c6b92d4efbb4ef878e8a4a9f6ab4ddf6d67d95f2deb6479a53d9b6b76db677b36b1a95fed6ac767ddbb75bd357abcfbaa9deb56dafcdbd9a27e4ad5e9a0d261e42966a52a9ae924af510a79ba64242da7ab76b6f3555abacaf55525f2bbd3595abd33755d357f368712cd3d66a5b237d531b4f3980eeaeabb1ae6045b1eb63f55c655299b06c70d8c2a1893b0e3a989c7c14a08a59002ba7d134dbb660b76ed502fca43bcdc97093005cf64a80ac2876dd290172ea4a8023770290efcad3bf6bef5669bbaadd3181175cdca4d7f3383d0f8f8c20aaaee1767ad77ab834d7a4ae36ac54262bdd436562d7345703c8aa6a1e136ea79daada1eacdeb1dba12e0fad6fbc56ba87def556f78949b34c3bc5e1ea26ad6fe89d2a35050905699ff6527bc3d55bef74476ea7399a581f6eeda56f73b5ba5b7d4ab64d63d7f7ca4da9f6caae376a6efbaa6f77db5af3dadbeb6b9f6dd7eddbddd0960712d25355cb32d901c286adab5d103654b9fbf64de99d24e30aaa89c7b3ed5e7dadfaaecf93ba3ef4ddf6c6d3a268fa7750eb66a5dc366afb36ab37dbde9ed5bbcddddef5b52c3c6d6fdf9bba69af97be4f6ddddebf78815bd5dfab9b5669a5a76db55d5ddd5361afbcf5c53400d879d4e6bd26006a96447976fddfe9d37e5c4bc30edc5d53b550e96fdfcea7b6bc7d9556edd2edd65a1c4b0396af696fab6e5aa5ddf6a5c1a6b7a681060d2576ad9babfa19bccc1084bbd366c0f29b66d9f6a6ae3766c8e14ef331830c59dc69aa0c5832e4647877a731fdb668af5e5bdd2f0a6dafbf9ceefd6634554d5f65d3bda6aa7e57aba57605964955f27b594d652ac9414be26527a9b29358b9d36c30d56093fcb8d35ccd56b57ab74b6f26122feeee7b7de126122d77ef21f9ed1eed22f9f1f4dd96755b7da48beb9ebaa6fb8fb4ec6b1ec9916a975d5b5d7ac48ce18ad3f66e55bdba6f0c0f88a1c9dd736f9abedf62afbcdf6b0c25cd06d36bf76d59edee77e52dc1b0e5b61e9b8ca45ed2930c9589060c2697ab2a574c9c66e4aac8d58f3f12b834042b215677b0c78f0cd3ea88ab5916f76e76b52a62958387d50bab19f7477aa42acd7e14bbd268b8f6b59bf278da9a56a5afddf4833c8dd7ded8b5a6dd9e4dbba9dbf678fa7df4778bd7adfa7da5753c6db7552f1bb5eaf57d28b83fd255eef6a63cdeb64754faf4e6a2563d848d5af746dba7ddf670355be5e36d7ba0426cec7c377cb839da1e6d8f2876dd7be58133d0c205a77ab77ed3dd6ba5592a7b89b3afa1529ecedd760dc9bd081a132101ab47aea67221bcbbd507d5b26c7a8bf13ddaedb93f41423bbd45e99765724d77a74dbd80c6f3b27aaf1fd5ee7ab4dbb4a3da1dda6d9a3a827f4ac86368b747db7afb768bddeaabf12c929a42f568f44cb85fbdeb6dadbd7aebedb47d35ad5d1c159aaaabd2aa168b86c3cd96461be3b12630d99ebbeb37bdad2abbfaa2dcf47729bbdea0a96c7bd35b9bac8d3b9456795ddad6dd284fcb6950bc2c1aefa76a9e0f77f7e1266fef76f7afaf5d3f8a5d79beaadd69a87f7d50bbcd55edb668bb2a3e73f7dbeda8dabd3d8fcdb6fe4eab7c7baf525ddc69a8bb23b92915a57d4d2922ae7ed3ddaf3b9b869b5226cd85bb579e767559682e5a9caaa95adeceab3badd20dc0052d8aa6779c545d95e69e766c10556b955d6fbebd99d4202aab7b5b49d52fbbf250756ea73b2755bfe9eabe694f035183bcdae9dded8e77fb6ca8baaa55d9a5f58a57b53ba5f5a77deab7efaf4d4e5359bda3d61ccdcdd5c69d6633735bf67eaa47735156a92a1f57e3cc5c6e97ba66eea847bb3da55ce95130709bed55ad6f56fa778f249549dd5ad5dac5d5aa348b84f414d5739a115b148d2873e6266eab859b382a4e3362c3fd704468466cb81fc789eeceb477a98f5dad521e34cd5bdfbf62d37fd357776d0e8855ca83dd6195f2a0adefd66e8b7bdb1e4f9b69b6fd77a77ab7babe962ac57dfab89ddead8d47d2ecba7b5efbbeadd2d35a57c3b0eef55d5fbb52a5390de5fb57475da5bcfddad75e313dcda9b5f16eab4b799f7ecff7aceeb548527b759fad6adff5b557ffa6dfee6f555753e9aa36c7db54ad5ddf4d6f76b5bdc6bdcebdac7e36bdf168a8f55f5ced76a9765fbcafbd7a1cd3cf7c00596ae17ba0399e1ec8d213ba0404c72f29fd9353101e4f6375af7dd57d76e5bdce3db5ffaae6a53d9e966a1717c5ae3c504e6cfbbffb2b167d1abb579bedd3df7afb9ec7e646b1ed2e7d9bed37cfc6e15aada6eeab794a349bcdd7b2f0369bed91fc27a56f6ae3799a9e2749066ea79d64f0d69c532fe531e3ff3f867fbd5b7bbcf6d6b2369b6de94f785afab8d66ddf5d8f975ae957a25adf5baad5f4ddafaf7d5c4bfbfdaeacef050cb8bb0e375f50dd9dd6a2c523a96b8d67e3b4fb6eee5db786416bf786ba6b73ec2b36e5d1b64fa9b6a1773e55e76e4e51ec7af5aebb152a5559ddb35ab2b14bd797d5ef5ead9658a6d57db706e29b5aa384b490c20d9ebea90d20a8cac424756b77a8eb765fd6d7f252a91bab61685d9cd62e6e47a53b1c1aa456ebe183c909c89290da120e14888f27a75a0d697682bbdbe4dc2c5264bbb42b2d55dba5b7b600f8e63ab870058806d4b3635b77a56235865235d45feda0d2d7c7d31aa7352ee979547629e9f53c32926aef4e77492e9e47656a71ecca6bdd1b3be979925cf0ec243d8f8cb76d81e8ddee6ab0bae763d7dedab7759b765a6d79687d63a7d59657d31ab7a3d8b58d7a7d6dcd2ae56d5eeaa64d35985a1ccb9424e347889ab6bbabb449d51a57d3afafc76b6f6ddbd3fac6da4379d0f66e97d6785eebf2b041e4dbf7d71eaad71e0a84b6ff5d7950bebdf3e1f4f6fdda436bb55a8d76a5a66fd4e6d56ab51a4dd5beadbe379ffb6eb6adf1519bb769dfbe3a2a7535d5bafbbdfe7eab168a5dad5aa8d7d7becea96bad46abbd5b6f5d7bf7dbf781bccebd4e5b7aa976abb85313b5e7b3d99c727a873ad170776f9ff5e184c2775a55a5d947550d44d5bbddaaa387aab5dad6d81b48149abbf37013485394ebd33756bb1aa7dd6f5d0d43ea9a3fbae8ad56b5bbdd0f20cc1f4c5436bde9dee6a5e68f1cee1aead31bab71cfae51abdbbece3d994d41309ba8b83bcdf66efb36edb6355c9d7bd7255ad52d6ddf777715dc6cca39edf63d6ccbfe4e73aadeedd2db37a99074a5a5f6959682f26dadb6b72bad2349fb76a9902bad83a7dfd5f4b1e5830acd888d890f9b6bb5bdf938729a119b0fb3c796f7b0d27444e4e4445b71e9bf5229efdbf79f5d7d2d54fa552d2bc5b63bd5409e76d3bdfdead5ebea5eebf6febc7144b4f7a9dd3f2272727a95d6825d5f8de3a16cd0b4544bc5aecfa637dd6bd33755716d6ea739682edeedaeb85735eb737bff6eadeeda9def692dc57b1e4fdb3b857aa4bd51f8a7d9b49b7bdf967ddcfa2ed49dd77b97de789a2d48c867fbbdbecdd6ee577d2eab7bbd34f7ef4e77af732fae7d9be6a5accdf6da6d5fa7a7bdbbddbd86fad750bfdbad55bfe2d6b765bfb5d2eccbb637dccaeadcfb36bd7dafab1eb7bedebef4a6a1dee6820709e969c7f6ba77f56eedea37777b350ed7f2f6caa6b99be67d14bb4add52f7d5abfbfebe45a5aea6d2bb7577eb797351ebee77d55e734f4f6b597d5bdfbdb22bcfd5af56773b54c6d6ed7bd3549fbac8ed340712d2d35f41bdaa5f566fedf6b4bbf3e9b35a57bd1aeaa3d8b5d74b793cedddebee6d494f326cbcdd6e7df76bb6d5bc76bfdee9edd915d7f6bcbef6dba87f5bd6aa557a5a0fbbbe8e72d3dda7afa9d25cfab8f685b44d6fbac3b1ebebbd56b93af7b6b77f999ef6ee6b28edb638954d9ff5fd5e9fa7df1569e9c9470f55abbfbfddbbf4796c3cad97db698ea7d9b4edafa0fed54e4f53f5defad6babd8f62570de5e25dbf7d778bdd4b793bbf9fb6756ea7b95eca8327aa7dfff5f576e9bb2d8e5dffe9693698dc74e7bbadaf9bf63e65d7ddce87eba53a87a46a57bfbbf5c66e97d6d0efbadb1eafadf1ee7c294edb60db1e564b7aa7dabdb14cedd356b5eea179698f9bee39651c110543b0b16505586c74c006056c40c086026c2cb131830d197aedbbd0d979a4f779173a7fe5b66faab229ef79741ea9d73e8fceef529edbb23bff483cfbdf880b5a6d6f48eee3eaee2fb8c9d3126104b386cdc690fbce9bbebbc370b3461777df660d2a6aaad5bf5253edeed0d6dd6bbcbb4fd5eeb3ebfbd8208f745ba3da1d57bdd67d595d4bdd975d91340ceb6ead21e99de67a494f326e5a88eab6370de46535d5d276770d9c06b25dcdf36db6bda56f6aa3c5b1bbd6ba1a861adbb237dddb2f2f0a09e949dfd896ad21216db65d37ab5f2bed1730697071ff01a2fdf4b81a87f341f5d05081bb33f1b0b177ebd670c7a96d893baeb9e313ee8f4d2080060df34b0d5f8eb45fa00ee0ee35377d96788e97eeed737d37b5edb1f6d0213e686b2f7d574bb96d550d876b692fb5d317876b5fe75ea74f42427a72b5ba6b6db87b0f375528dd69aa7ef76aa55fb3ede3d6fd7b55776d8cab777d59adaeafeadced5dabb69122ae6e55df76a1c8ebdc53d20c8c14715d28f2347d4b77bd976adbf7dfedd3a19a6d6d6cb4557d4eaa8e62d35c8d2bad435d559f53521377b5ca264db92d6ea9cd5555693669b74b6b0041424a8a5a716c5be377fa4f326458b54a49e50c2e5768466c3322b0d35aabfa5ebdab6aaa667db556f5ed56f56dda9596fa56f5edd7365babfa9cb4bbfaa63410d34ce18bbbf7d464ec206389ff9bbe8b1d3026e3c8dda95a9e06e20ed6c430420c1bf823b9f0efb638b5174453e5727b5f691db4b5973a7dada6d274efeafd2b2df52954a52eaea5ddd61d94afb7b403ade1f4aa7e5356bfe98d6d6ffb6951eceabefb6d47b8d767fb4fb7aa35bbf5faae56fa3f5da95ed5bbed59e9d76efbee2b2db56aa85777be36b775eee969aad65be7b6efaf76bb745f69a9adb7de9fbe7e5357b31ac7ab5aef97d56eda7b7dbdd7e7030929b7d31cecbb75d4aae6769aa347928c9b16b297722021dd5657b33a0a09a9b7a56eed4ee9a67b4e516e9aab71f5aebbf47503a7c7a8e4cd32e579a0640c9919019001000000531400305028160c87a3014d53c596760314000a75a462884e218ab3284829678c21041820020400000000000000009b76a85d151b8c415dd0f5eaa267e0d6ab0731c582fab567755f61dafdee01873f10f6bd08207302f40023b33d962d080ced30c53efe318153129fda07c095ba4eab372b2b0b135e2311aabc69dcd288613bdf2f728c860c714a4d654b81732d69020e4924a40567948128d1cbaec90723ce7d69a884862849b58f9e24a1e5d0ac629b3ea3baa68fc8a4419a3a953f5338683a7ae7740230203bb2d037149b0363c2c8837dc58e0b5edd01407059fc174a615b41f5e84c85b104b3d7126991e27d6b668d9d60d07364da836465b5d136a3eb60d42954c1e97306dba904121de7017ce4a27efa0dd1a50c8fb1254c79409d465c032531f917e59e70b17dcc3e4072be1ee14a0e018bfd66968dd2501ffbc7e1703ac62996d112f02ee2af0002ffb8a0df265d0eff2cf1fbe3c9f0cb3cf5981fe2ccd31125fc23faba1f3eb9b861c3864f1c0973f0ca0dec5582111806910f921e57487d2fd999a1e8d0f5e15287377fd070a050afa744d7de902814a8caf74c95fd9967677057ad47dea60360c97a75bf7c2e44d65108d0ffa59f90501c857c641056636289b6f243c544802bb0d83cc52b36ab7297d347031eb12ff0aa182cf94c9e9e767ed4b524d5ba37f71edad9abcd87c179fb17fd51e2610dce92d8ff6ddefd7056e6b7592c9c951c9918599ca6c28c209c3696bfd506e57bfc1403b6cadd97f881c9609711b689dfb1837a4e1ab10afde31874a30e0f063c526add4f6a959a1d79d7b9d8b2e935d5b6920348f81ef644521575bea9d895d375443cc9d3a52487211047514659421c87bb9432332c35843791fefea480c9c558733f08321b5e7f721fd87e2e2c3c64afaffe6853a8ba33b82f6476a0fda0d39c57adb3ae7b14bce766eb995444d9ede4d72f10368095b4e65b28c64db6cae1cde8486b90838c71a297c25693a824cd585a831ca1bff2a7d0b13be6d86e46aad931b0295005cd05209f3bd373321ac7d8ccb8147ac0dc43919c409cdc652406129a4b2a5eeee0655f1adc7da4832136e28e40d143a468cd4dfedcf5e2d1fea1c9ea0bd46169b62d2bd39fdb5ae3c388c04898602f576bebc637ae027f1ef5cc0275c6b9639feadee64ba6651151ce6ae81be9b640a72daa521ac339317703ff651a9034f8e8b776ddce222a0b37834ee06f5ab38928da068df02f9413f0a0a2afb14d0be77c522c925eda0a742aeb4e634aa176e4b3605a844bf691fcac0fa9f3c5c5642a7170d0fcb4324ee7320c9fc76c6b0c7d96a8efabcd8272d571df57a44808773f722d7e02180c9bda263d82de40b0a0cda8b78181701eca80b22c2d1d04ea0cfb01468a8a2805de5c451cca85c7cafba5d7b772a6696c6ccb9d3118dfea9e1878754fd28b229f2b056f1d8256e85bdccd4d07d0466bc0488d0e196f7b69d34b971552173d7e0fa200afee812123c6142088b05fc01cc46a00b29d10465b2ef0ca50a587ef83c5badc12f388966b638558103111b5fdd4b33ea79315031b4328339ea6677fe9e0dff791b3554f2ced828fee373939d4ef31bdc757fd7cff579bc3081293731087d291c1ee45a23091cd9eb6464c8f0cd471c966d093d26b543f35c43d0457e0aafeb479f8d9bb47d64806d8ee05939437d23e1a8cd91ebd43fbe6cd83d551058abf20a61af3721f89f7305dc38e94107e4a7e48b36aec970ef48dee27d6fcfc783b00f2b92fbab086053d1c8d66b049fb1a3c6576e448c1329747474c62ee45f6f5736f175f17537b822e8e1462b16ccd6a166e6c16521b0461ea158c6fa96fcedc15fb10746020f40a3f0a4dd5844efc8462a5030bb8f59dc90cc04364a847e64e023d1a187f3969ac024ab7ccb3711fccf65b67502ac47645ec73d3fc2a7af539433a5de60e5b4ff5a1f7d215fee893732fd865e13f8b6f9432e4aa8ebaa8e0af7e823681e9e20431397f78354e451e0c15fe97385c0e45d7d7affd21f793644abe47fa0cc4cd9888983b446aacc48b50125f6f14badf5ca2fa04616e42e8032bdc96ec347ac8021a4f3cb8175e21a7939310295cee35570bd94f80772026a68cdad5df9d97d5b8ea102ed4da1e946e1a3aa96b490b54627c95d420cdeaf6f07ebe05e205bcf2cc487869feff34d68c9de59b61029ad5629b5803cd69b72bfb27668948607616ff495f897961aecb4da6d2d9b229eba97bc3e63eecae8ccd800dea5534487a4fb74e60502557a26f21b416ee2e11a60e6cb40c13db1655406df125aa9298a0416617f4c0f64d13aca94dfa422acdf67570a6574eaca9b1a09734dced98d7999e2386d205bbc8d9e51b6dc20407835f6b218a8f99869ce3b08f6ffb81fb934c37f2b03f76a75fd12302b9b4988d71666dc1a07227fbe22e807bb96e84d86935f97ec0b6019f91c721ce3d52109f99ed501d647357ff41a44b3149d8ba39a5ce94e7d8c8ef4be77021f75081615a8d6f3fad1d44821d194e72876c1b7a08cb409539242eb13243b8da0b1788c591aacbe4185866b225353e9861cd0dc124d1a7272826fafb4bed8509bfe1e9a3d79670620482f4d04d14424fed0ec387f3799f62b51d2d11dab46b3bfd6859b7c7787e1ef8f86cff56178b82624c23e6cae87c58a0c087e4b20254e25e691a930e31caf2c0525b011295cb2cc3926f64d40770d645e0e290c3248c005cd66bbf1856fd5f1ca2ad9e83c35d6cbb01e9e0f2699440007e18ba9366bd76fc298e1c0c655f252bd4b57b91d5371dea3fd61a256c37510e6688dba04a5fd28ca6188f6499f682c8f9995401a8f22b002d52825d140c0fc3fd65d3d5bb10c62951b578b85fa729c228a2c02b575202e7fd328b95c1e2343c7cb8443ccf9ff8af85ea3efd5461fdd9c9d7f334584b572fd0f9e6a02f21ad5597c7bf1c795152200b979b62a1233c0fbe08507ba2a80d386c27725cfba8a0c04b5648875347ab267c24e2eb93e25d698d5a0963017c67240c19f1f9451e66032536489ae690e41d56c29bde6bb59565d18c710cc6abd3ded07ec2159948c245411707669b658f2df951e22a803b460640b143c99bc2a56e2c2c3c69dea05c1472dcc86bc6900700e3ee230ba1382be7b23f152ea15c41984ef65d7a9e488903258312d563bb06da8648425925603165aa4158555c053fdda6f3ef4e186660b26854b9590f25b9278a2b75aec0bb0fee791d7efc648250b11f5a11c27c69ecb5010d06361b55e655da68a9536e8f9032811b2aec122b28f05fffea61f04b7ad8c3215684031a19072a690c77c8102e32e69ef5ca8607b4d76317774995f7256e6bcd78f0efd3d65f902ba14c25643d7fc19403d27a278db62234d3f54f3f33ae03872c0f9c4d1b197304d23178af29ff018c67239babf8cdfdafb29d1f449ffef1a583077418e93800b7972d165ca5c1ac509d01dfb7b9bf2b1c9257e2e8567161a3138683d60a8c239e839b0120f3e71366a136401086a9ce15c1b3018601bb71920944383300f3b7ba113e313bc85bdd2e125bac91bcfeb4d2f8b3cb575c9a497a0cf958e04297ed81239089ee63009042f9ec1b3dc35e4c587bd135c09985df520249cd854430b6be5914b151cb720aa2ad75235999bf2101b6d68aaa165c78cf5b2855e19159df294178a976d0b726057c8f5c0fa812e1ecacd9d46173cfd48965a1410bb86ab862d4861e8d73dbc6606abeb63c8d938b5146fdb70e778b4f0cf08657da44f713a9a719310a1730659d8d999fea4da737f9e0e79419e73946b65d7192e0d1a89dfdce07c774954b441b1deb12bcfed1b25c2816d38810761bbaa7d4601c97e725b784a386eabe89d333f0ee3162f93d357790e78c2aa24d487fc2888528a6a659b597b36a78b85dceca69395f41ab2737fcd228e7895419c4d85b6f76e2640f2daeae4b01adf7abea7dbbc568cc1cbfb1f4cc3d9389a388199ea6b98f03d3b6179a5021662af871840d1d50e514d07d5fb675d4a3753168e52b3b804df5a7b0defe7e3809d66ef49b2cc332a25cf47a6cf5d11cf215a864bd2b80a82ecfc0fb523277a5d3a7695e72f444e459e0ce12e2062c3993b8d36ed050a6527b8ee8065f2f3868ff850440d0c50c2ca23da3b86559c5a0433e4de5c85a66f3d0a1d03707c990e325ab6fd419e4ff3421b901c71c3e5372b81dd314bc656a0076eb5cfae4ce34cd69b7bc6d61aa06d32e2441c9723490e116c9bccc9ac86d49f673d3d7d9c60b7c5c12c99a908be36be81e5c71078162ded87ece1ef30bf720aa35c1ecbbb0710c0256a97219ca9828f695c0ec6d0646bc34c241504aafe7894e64e52105c1242723419aff28b0c12f31e416655aa97cb087fb6ccf5798045927a75bb1144cef75bb51e0c3648297efa287d408222828d94166a41b67b8cd3c7f9218ea11eade2b47b713b8bf9229ced3048cebb152508819a7c11308e086ab0cbe6ffec08c5e817e0f7e40f089e8eb3cc99fa70fff93da8427c500df31b3deceb63a435a326132628089d5bfbb0b07f88d92702aecc9e8f1811b7974c87084fef5d0c21f8f20c11388b8d9b345b0aa60daa71ad324ed746bac8afaa84e002da7d5826cf39308f249f9457e02ca28b41f0db79ab63df9a12c2c9a369ca1e611a10d85e929471263fd017e951fa1ada2af5f1f677872beb09aca328dc160dfdc8728bbdeefe61dae0d61e3726e6e96e4476d04f718e190077602f4e46cb70e20cf3d317d9f97790035c3af8410de19ca9e5d3379c5637ccdd5894f457aec719947c4feff04745685fecfae7f6fd1c86e8c640f75b0f37f6433fe51a123d70bd67db7de1317afb2e6b5081803a813f2b39c6ef57be045d966c4770d9a009eb9a0fc71ebad1f516a8e4484141c53ef2510d255eb41ef5a79185c1e8954aafe6703758fccafb4dc990c2ca71cbc2aff7c8f3b85499bf3a6ee725622e52404e6872c88d1dbecc9982e2c8dcb0c42d6270d4186f03b437713893e0c86f875f745f04fa1fbc0663c0dffbb5c3b7a2ebeba5d2a9c987e52a6e60e482491061b8408fe635ff43dd22fd425801fabdf772de877b7d02b3fd8707ecc99d7ddb8360ef86cf821e854c0d7614d6920379f86c6954fb3cefb4fd2ba364077c97ae6db997f861e7704a39d27437df6ded7a02c98e9a107257608068d3435356ca4c20d1c6f33ac1f54f58ad599d1f07e31446dd21b9846e0968ea3897eaa37289d7715b6e49aeb02b826f6754f91fafcf1551eafd8340956b9e717b1930532249106ecd80d37c782a00150dccd869639744d41150d45b787568ff895c0a984f343931fdf032b93e38c51b8b737c14315dd3a5a83e346bb2da17c962690b0f3a0756eeb2ac568fa66ef3f7145f569bae7ba2c952b8eaa6770f5733d1d17f5506eba0ea49310002439b13eef17ba481aa526be96c7a85a30b12d3b51a387667f2af7a6b9467f1b1f1d89cc343bb8adbb99475d406fadba2df5f7cb04470b35c4c372723f884b08e7381e345b2e3cb4639b5e4c67d088d0453e22a6912314206ef5d53f0db9cd8669402ea491917363b84383966f17aba035e2563cf4cd2b5052c607c1678f259f0eb7162adf1539a8872621939649285fd531a715ba2ff6d1cf7d5f40f0d5cafa3b8d1a92b539b73389d533b1cf612decc00c3493ae784933005f9dbce5f41ec5cf590eeb9de6adaae1ab6d0f8f2b9e9f3047c3214071e2a427a68ad673c4c283c18490a714acea55131923c99a257dfb6381fc009608d1ff4d0beb85660f82bab2c1dcd24415139d84ae249ec5f18c1162a412b96320ce9bf4d0fa9e9de42432339da78a7a2bfd74e24b13ea857ff7f07a0565f3bd523b813ceab042883f675d298f80b583c4f3939d7098617b82a98202327f9fb98a194c4e6794fe9268dd158639fc2cd80c85ad12a7dc82833401bc8abc7ff7cec3a8eba4ba3bb2cffaf73572da7c566f3007d22bd6db357b6b6814332a75e0a3a78dda64c401cb661b25f51e91960d05e77411ad57d402d7ccccc223f27f442eb88a45fc283f12e38a70170f1019285ed67d33596c389d46bb1a6958be21295a81bf76b5edd1267eb75f2980eebd269960bee69e2cb0f406bd2aaebed2aee41177eb040062f8c5ff663400b15680f40c2669f70019373130bbe9b826da43f97be84172fdf8cbb4c78f7dc8a9e67db08b98019442c4ab88b5de15497bcd9d832e8d7fb1a2e142ef59c6d435e6c3eb98ca875b2d2edaf5f914a6d12656c1755021a0ab9a3d206c8da792ff3f03f5d414d630b635554d04c432e86bc0d7d846be934e0a5426131a0c3dbbf5370254a469bdf7798fb0b209a9a15774869f69e6342c4632e533d3c2e4c5aefe3025afc4928d5066e738ba64782bc1ae3e98eefc154833936307273be1b014ca7462e12bcb850c3ccf8677a2ea3b625a40bf24a4616021a0ca3fb720ddc124ff2e6005c1d2cb86a089a403b0d8c5c5f8ba471747a327837fc3c9ed4e2068b9c12f2b066cd1280e732609a79827bcd381bab7103bb864b686ee21a4b3a63f37a438c474d268e64a9581fb38842e34989eec49491369eafba55cc715200ca4e4ccba6215dc20acc247f2d9a2833fcc4cdf70a0f49c1c5854e6e4d4fbeb0dee881835c0f92b51308f90c42da3b2207e5724e8434cc6e268e7acc4f5fb35488ffb54d72807ef801fae1c05cf2782f9475ee28947c2dd8c92ce293e58af4fa3b0e2e4915a656f3fcf97113e1fc5867cc27514a2d6aae3f62d3a2d6bc4a7ad06f2f465ff93efb88346d938641c5bb19ee3b85233af2d2a7f5ca5dffefc402623d525a83517c537dff31ecada503f647efc67d130d90c4952cad33ed0be5b439c3c354b440d3a5f2f684502397f5ae02229025b401f34ba115913c024038e2f2b86f42e42546e3621dd8200054d2c0c5b4b852f9c4714a628871a31344842f9ad22fdf1128d5a907590b7299ad3a588e1acb971485f44849047c5a6e7709fff3367b078ba4fc4cc5618f926309cc2392bacea15887fe1ef5fe1e5a55676e9db6f742e6ba3d0cfa66f4337992bcc62c95f88374a50e4c96b25034a648022665e242257163706836c9f52ee2bf4513cabe547eee2efc1b30af294aa5673d2bc9b9b8a2b8615554c2fec30310718dea8edf2695943d83823b1cb8a9935e0768acce541bf5b94c6e38bf8375a773c19e50f581343447a06bae9057da8f5881bdf052d6774abf8f474f886468b42f1018ec788f92d256076e33012a2ac37a723245177d09bce278506b9dab8b7980ffa0117ae2c9e5c19f065881b16708cb66675e90d4f03ea944291a9108cebd029c09580d2b55fc81601485bf7d02ad229c518ee0915051980fc7879112d19e6e893a43cd0b696a2bcd824669e4952e29f66f530b3688c2cd22c528d8a3567dc453abe4ec698355c0d836a1f0187e460bcd36878f406a433eb9b4825de8f0d0ccea24c30b56d2dcaf2bc13e46b5c788f794823780638352191743672793e1486ff5020dd5a77b4ecdb8336c7fbd9fe60a86378a4292975c66d7950f16857b5eadc537b33c894b0191958cd4c118a92d8a55924ae9e81a8923ceab8dbfcc27969662991cfe8cfc9cd386f1d97e3eef213fa4016b1fbbf9b868e9e1ab4f07e7e65a5ea77f1387481d509171a641cba2ae251119a781aa4f483e1ab403a452635f3040fbe77234772d23fb9057e088c769283387d77eba4d9b489386df2cc3f6b4d87e23fbf404cd250e050e9ca6217a0b13ab7aca01f9458a5cbf44e6b347ca485976a67703065d57f8f0e14a6c3f2fd478e8ec0814dfc3502a3e94d6ed339beb57b0e40be28d6db7466292b61d15bbf27abf7b5e37299b8b5a1d669f39057e8147455f95170b81342cbebc3bfd3429b488bb89f885d532fc05659d24e0fc868862d6dc471f0c8e91e06b9ee18c10fe2c290c5bb7377ab2ea87c84eb44a2a0d5ca21230c32d3694b6484fdbe9db1192250f250892ef25159d7200d22d2f12e029063a3aca3c73735327c1fdadae10bec906e50e7dcde5076b688ac66a3a5e134c2c79b0af3a89cbf5f7808ea67454bbb267920c3e63b211d691b1c56fca4e9dc849db9cb1c50b9a4b8db4fc64477704e22dd9123e292beb6b04500c05499f6d7d4b9c99e4c7685b5d3da91ed4e3634e1cc5ab529450c968615462ea310ce494f13337c11303a978233c112ef6a1a32e8014bb9fc74f3028214331116206ab461d959b16922b17e635095619a8d3d9ac6aa48a1e1d57dc76184145f622259e2962918bea6aeff52509896c839bc208c0056d518e2553b3edb872368f18d2300702982416de28742239cd3c9a5aea1af6f97075fc9dd4cb8411e20063705f9873f2297f065b45e079a3c227e8c14c5f7c131c62ffda3652d70d488d524ed8737025599430d7931438d6a655da7e9aefbf883b1025c803c2b2a3e7d4ee06b1a329e6b7cc89514bf88227c9bc2acc5cfbef5f089c2747b5bf38700555792aa573c4fe221b3a61288e62b34004274f87188818fd09b81b883d35e8bfcfc25981bd8d40eda8186324964135c50dc64e7e7850fb5da4004c0be9fe112b8b70c3f0a745c7642c9985bdae668ee91cea217a13369133bbe805d737bf7689706105ac4e433dd28ff0dd6a148bb49ca3ad2448473a31ebe21a6b5a946107044046e8db3592b40c6c37943ac7584f7d0998a8ca14bb954e1d0eecb04c1674586deffd1afa723df1091190aed07f0f5e6ebb3d526d41e2f8bff9cd7103d9b4691d772e71fb41fd8d74faf7812de33003ab3949ca5c2110c728e526e44308f45dffd362fdfd8f39147f78e96fc917daa1343fe4d5ab8d9b953a91bc8b94bdf19202acc6acdabbd3d1d224e7c8a5436715b0286962fe5aa93c97ac8fc7152773e99af3f1307d5bd92a157c7cd3107f60d29cc3eb3a1a99aa533c60b929e2bc35c133a39073be4eb0355d2f7bee29bf66d65eb73b23ad1998d7068ee954d6c2847934d079023c837ec2599f2038ca0ae8c8368a6cb9cd81c63d81ed51c6ff8104b9201653f850aeb0bb83068643d76ddfd05f4a78ce4e18b79c11c35304e0f9edeeb71c6c51d9be514bd1e3346b234f559d3df76eaea9108d0f2de39709fbbcb020ec04ef6cbf3cfed0c40265fc682bb305f26cba7c93ee88935f0fd8a618acdb50271d0c6b1faed734bef6acaaf9ac6bdc0af772bdb9a05a1971efdfc7a3a0de5e12fbebf6b137b172ece2afd1a69834c38bcc62110ed1aaf4cac87790354642fad966757f1538d5c8ef570faa2af49a63e32b1a8c2892ec36e7f1f82945979eb55dc9f5eb8aa927bb9e7abf60ecdd2e006fe7dcf91cbe7bcc182be10718d41b9222ca28ac20cbcde5de426a79b0ac8c5bf6e39e2860f5c1ac6ea868655b9211fd4343e6b9f97836b7838ee2efa43d47867bee778c6f39739f92059b297dee15f161c1ae9a8b741a101c55885391773ab2e4a345a9f1dcee4c78e5f6454247458f54a98a50fd39f160d7f6cfaa40733f18936b4998beb046f329b76b4409b0d985d25e335d7e2c6ba3d27e787b51a611ffc100d563f25a4c681c25325ea2d78e87b7f7af4f51b110253b11a95f7a0f22fc2c1a1e909e130127c640977fe84595c2ac1bea11565f1c88388916f398c2472d0500aef319aa891860476b699a1e015c8fbcb75dd030765e8ea19ad1490afb4d2da2f8bf42fd718aada2cdf216126486b2f5395d9f2cd34518e3e8cf9c7ce422cf3e6ddedf2e215d7d310cbed1d74726fa7e496d9a9325d5e7ddc4b79fd27b5c71fb38a072c80c70f745b5e3600f8c7c3d7b217b09f357c68b95991e53831a5fac29f398733009c4366fe0c71a0f420bf3345a6ca1bfec137a0228d9fb9c9dbe79e1e3c2bb1442a4b9a96b75cd069504185faf411100f227476462c0d6fc25bd36823bc6011904b35704278fc161277c8a262ca19beb8faa718e0427671d4e2b179df3800a292f16bd3d387edac4120488674f70660c80c945f500a9c28d6a1ad04bdd3693692406e8e465676df7c228d0282f47ffa0f2066497580df6c5a7e228aefb02173f17d7c6a5f69ffa4bb4862f91950e16e0632e1bec9c8878cd628f183f045716504e483c1dcd594ac14031cbabda494bcb1ef8311efc6a58016aa6dd47b28a3e914eceafc3ca4aa3a7892fb897f3b23ba4405a631a4e57b0b31f1105b3642f095ffb382a3aeda205687afe30f01d005b6964e76c1a17d7acdef1c23938489c83ef20286e44f0ebeb6054efd0af30f5e7c6980ae246bc27570349e760cdd5be16f73a279d8633fbe30992b27c142664acf9f68bcd3def88d5d75e63b33ad8d3d7d1c7888f8715b4115474ba60e23c45ba32ff8032e4a402d5bd47aeb71f43ac8db2772eef5739ae807876abf58e577654ad5543008d1803af19797e69ec66bbe3064bfc1c8d54da395465143b9fb60c372f856c3b18a3ead376801e8f6e6cfb53e807b06df69fb8a5367dfb0ccf51278627a93d0deb4725708b5e329659f636b30a91c4f626207f5a5578e67dcad1fa4194959a525ce8ce1881e20510df3f4e7e7aecf28c9108e4955d696b3bbbe4984a10a5327b2a6053d357fd6ce24aa0b77bb0b0d4e833b579c328b01038aaed71792e36078f672b721ab7e81b3002873286a0da99f86b3631bef1f53397a617f69fb93e971c99e01795410ea3a8af3c733657d3cca90244d5294a29303bb9918616f3f8857855248404f2eb807082aa8c0e80d02ed126e862a71d8fa03e9fbc71b96efefbc2d7069e7c1cbd601716fcb1f3b0e17d0f9ef03931c89301a2f1af705bf8416fa240a7641eadd42b7fef48369d80fa3c0fae79a9a1596ee5841fdb838b33b21f5a72b86cf7ab1705c3ffba705e6f89db6d4dee9f2637e6f406f13c1b15527425cdc9e046fd2010cd471fc60dabe67f38b4391618c381935e4096219ddd67a9a57f5cf458f6789d37f87c576055920b7c09bdc38a0db89ded1b6fa8fc7ca6d2ae9fbf23726afc0ec47e40fe2cba3eb46c353a1237e144beb10df20bacc0dd2ae2b981fff9f401eba39d53f013e2321d48550d6ff0edd1ce8860e1f63146355ee4cfb2a187456706d9f6301dcb9ddf72fab45262666c2fb3eebdbee1b7e8edc5a24d745d2df0c476367cb4785252ef32745f84395ae193fb5e30f283cb709abe85ddd92acba891a0bbac432b7bac19a1f819ebed6ca39ab2e3d78240ead3a704e25fef2ce41cd529cf58ac3bec42b3a61168a3818be44c1d51bffb76fe1b7d74f44f73a7a4ce0ee43ef727f5869edd7bae913967a6fe0f9ebba92f51d0c22f5a5fd1b1e1944dfe29ab90ba1dae73b80795f6b7aa3702fa06dd1bf95c0784afb1fcf71e7b1997fbe2dfa77e5413324b6f8f1f2a0d8c7b503cf5de3e92d4323618e9ff95394972b1b780692ca50107ce3c7396c26362b20bffbb3a20292f66bae1d6666399eec6f057d48f9329bcfb4a4bbcf211daf1fc74766ced15f27db9d36168d4a32178e2f63ddce58fc1640dc075ee60358fa237e6033eba57970f262522d8e55dc015d1f79a0e84f0eb863128c7be1539fe309d275e27e7634013540876b696b351d94de1f1ecebc87a214b2f4dee5463eddba80dd0e021314decb7bb8924d3873380d75df2d9fa86b932637f1ec63daf2045e1c8d6e9e4a382b1c4e815e394998f920e71af0c597f9383e3f9e27bd07681f27f6be94b91cbefcf92583c507af00435afc44d9c28fa1db034d3b1e69775c314b3ad5ef912cb45827831ef3dfd49e89171afd9ead39cbd484e32b714e974728b8f03848360734ac4ec3fb10c2afb1e9fd94c3093a61f7b7a2ce0a7cedfb78f3ba5a947339fac8953f4f9c9c947e362527c317373c734e13f0ef7133c43fbf5af59f1648b4d8df7386faf0eeb99d7521f2ff276ced531abc3a98b3bd1e9ff08e81159c35ac4d29cc729e4278343b68fe68e04826f3f32bd1e78979921a100dee8cfa38742ed5586fabe434f9985791183c1e65a89bb92f9589e940eb3d346fc506546ea000f86af3785ffaa871a0e800c14e74b6332a74a63db020d231817778d22d8e03067728010b6c77e520b3cde986df0145af048d6e7fc374fe8459effbb2d66f33af7efea071beec4f75d51f73de4b409e49e1ed95e53e7f6a7f9f6a8264c39387227d23bb6e5ffac0df9514e2b379cc8ffffc7b82551c319cd1c2510d9e49e1c5580bf17ac8e01fc4589ec58b9b8fe30128e61056232965a10aafd134944d028245cc9b7610279faa36e19b8d782d787cab8f660d074bef299ff2674c2d251e89c27d6a7f808c1b7f18ed9ae30248d7bad9667c435adcb701f516c2eea821b6db30142d32e7a0f2356558b19dab71651ed723a4286af21b96ba0ef04a411fffecb05bf724b6a1c9da7ab3de682378262d630f7bff87abb8bbbab05fa7ed3c0ad8d2dc339536b14341d3542126ab11edc8735b326cf5e22e53f09f90aa55bbade67e1bd14bc15ea653b56cd295d3d4354832281602a20232f235653cba21641a0e03dc0e232b06f86da04a1a8f2c0b0cd06cd97c7c273c648c7acea789b5b273803931819c8e159556f2dc8758cb11225903bc72786d5e1052b2901a96edfe2ed85cb42f9686c12492062fc1969dc90addc5da84dc786b63b4c98ba6576927227a4f28bb79247827519a3fc12c82b87746240a25eab9d9dd493fc04197576e2e6eb5431d9fc24027e692dab311b42e8b097d0760a99b6b80436c7f2ddcb0d5e5203f22a816c0bbce9daa85255fb5d73983ae720298d77c8a0e16eca4bf703075770c96dec7d326c0b00a8ace728b46229f891a9d706cc29a8a21da57eaa8c342e8f84518476d76a95f91e5269885ee37675a61779c83c72485b662faabeb1a8baf98cd3b1aab77368129c17e8947621adbb24b9b9e29815500f0f87e2ce555638762dbdff59b98f121451dacfeffc7833f69191368a15d0de89b695a57c5a24a711d33f1b728e01cbdc015cea7add8ff41fbee3b0efc5789d65bb283f22c00b13d556b85fcdd71844ecc245c2ff81e3a038cd24cfa5d44744b90acd5d8cd3c8831aa593042476938a9edf590385b2b361341b8dc868064100e5a4bfacd0e19eac17a549e389e2d04cd8a13ce1657f90d65ff3eed1c1b8d9f1f900cd48a3e51c7d3a925e4b2ff657015c6191f3178d370b4c7edb73e12a5ff49856d3c911d4187e30cfb58a9532081ae2877936c3ec7ea09bb90380a2c82003c4ac995760bc84bd412e94cd86b6b4f8d1e8d9311fe0fa8d54689083c0cbb66fc9e6e3d67c436d5720a4664d6a04c3aa658f20d7acc5bb94f32ca88d75081c4ce19650184852747e60ed461287265d36973753bc0e5854718ce1ce16f4acf2f9a0b378da2b6b5fc9d2ae56cbf29c96341c540984d8e65be3575c9e35d2f6d0e6fd29594c28078b51840c293b1e2e358e46d040a9628ad32e5ea090fbd780a22c0edf83a46087248e25b7c7bd99af0a6e7c5a9f9d08ade1264b65b149a62435ab04a6101dc1d52d9a6a2d92b866196cb293cd3676e3ea31ef12023e51e28e4b07c2da52ea0a7e3570aeb819d12523396642b881c53b80d460ddb8ae1591bf919e0e6302c3d1633ff66eb8b563913eb0c8e774ed2c748ef23a5de7dbded6e0c8a09344afb10e11f6048462dcd002aee942d88d17850cf343c058d24b82e6bbbc1ca807d9e90daf7b5632c8d4e8c56f01aa30deca4ec9ff68b51c2e44236de99041cf07f79c86cc4bc1c2c9db1ed98bf98f4a67346d906db5b3e9f993ec538584d6349946d9748d5409e5f9645d72b2c808173f8c4db017984567c6c8e4a7e05dabfea6f22795b1b7f47077298b648d826465563e1d9c8f3fc682b7ec1e87e4afeb0c4942526c6246af610b702e0782cd50bb9c6121b884b41af1f14311bce1e1173410c74257105d10cb1e35ff144cb6a4f74d6cb0e9e000a108d50c430dd48e013207ee40b5f4c31d822e86279e6667eaad9bc71a4700c6f1457488e1bbd15626c2e79d7d03b9a4203dbf33d3079124f0c55f0b202541b707ada9209bd9e380bd0688db85fd262912012164c2b2f89baabcef6144945a8df621e542e4dd021d94d24644b252d0d36b6c65fec1357faa3827efd6cbbf783c72c6410e948a988625a0f6a073a50af0d740ed52505cfec3f5b0e7133b85237982741a82f08c0407577a1359ebcfa9e9de6c402a673722366687b83135e574a1f1627eb117da22a5359037bd4d7c5106328e9f17cbd70f9d524ea9e45baa5c94c1bcdf35f160ea8382ffdadd78e83fca9ff2069d7dbdb66c2046ae448baeb63f89093f7b28c8aca44145959d3990c814e21d22c196a45dd88e6b8ac3290a50490990b7fc10a71d5d4a6b42bf35910d92baae611c59cc8f688aad5b6043f9bbabaec2203dbb61e425af6afda21ee31f2c930054834ad3d6cff101fe5960be1fac14d7af2f03004632702cd9ecf8bb4997a726dcfbe2a6e6742b4629bd6e2a577ff1411641d35c0a2935ccf1ce4c0b4244667b37ef88098806599321ccfe7d5d9013731455a77f4d6f8a4398e3a6e73fa16bf1b497b822e39d6164ea10ddaa0059dd00a9dff1350f314c7c5386e9663271c15e668d938a67fba22191f503e9e88ed09999518bd37a255c76630b9dc052db0b451117e82247477166ae056eb2463508e401f72ffcbc88857d478275a1fb3471bb301b93b679b3a8302aa86c8d89d841f2ad72c560aa6cf7d559a361b2375401573bb4de964b56829eaeefdce73c6d7cf57c39188691d537cd951bf3543aba686781162f197ac4a943dcbeefd258015e77df8316830f445b5d20fe04fb574c3abdb6c7898c290ba2431f293c87fbe245eff291c96df19c6dc8b29915083544f82375d75d759936752c8405f6457266bfef1f5b20d649b81d5342573bc5e49452cf798d12060ac6b7a1949149d3ec6b6c6448402fb2b9ab86f447b14a53136e01022045da5cdbcbba74cb6a6a44c23d627092c226cb6d5fa656e56de47f8dff1fbc277982724269294141690a2caafc18b74c4856ad87441e64787d54011f536617b0d4f220fd647829fe232b216782059f88d3351d8386519da21ac6ee8b229b538fc24b876eeeb54ce18b8d4cc971baec835be073cedef7e28595e857789143e4bbd7f6310a31a15ed58c3fb89eb7a49fe748dcfbba6c763ddde8026fa132574a2653dc60bcdd32f26f67d5fefec4717ef0d81877bee0c2bfe0d0294331ab680e3542d4503ea7a825ffffc4b9a7f048804f7a01b5203e69a29bd43ac13c4ebacf07d9a4b082672a640f746fbb94844c6b09581908c4f128b52e785432f3990f5c42f599ec5cd2212456c0388eaaa44a360b3988fa5bfefc7bb3d1706f76db03cc41236b5a255bdb9f5ac50b80b349e6be72bdd9c680c04609fe19d7e4823a2e25d2611543f51b79a05a042ccb35ee0f1d8476b3853bacda6aaa47912846f8845793e9c4867ec4889e6cbdd70f03831dc6b924897c8fe41da97ca7b99ff21bdade99256f9c00958cc55572a6fb3d8e4e0b4d6788d5eec532158bb99235e3cefa70d2da66a6910ee1c695c8fa2132429791c39e00ed721e796dc5c6dd593a274efb4571f574da8e1628b4e5ed353127bdfc2b404d5db83dd57b92ee61b5fcc5e379a80b7c4d6b9fc874ae81039179caf2726b2d6d0f95dfc1cb6975122eef37f3d10696a03af82b363d144c9a84d185db74a423fa5f43f632996acc422b34293f50b287ef964b519b515685196076d04836d771f4f591cbe350375be6409916f539e13bce36d095581281e02d63a4dc15d82c8fca762091316805910191ec49a138b48cbcbc7d0c636fd681e314af2f93298eac86f93d48412d466a124ca51d65463629ade6d6ca96be3130850912568d77ee8e585d1a55fdee105cbb0faa7a653139cc7c77608f1011d2e8b28cd9e25dae115c728c13dce7770310cf100d9df323d32e2ce1d7a6c8b3a3056e4b63c64086bdd3f716182a699ec10cca00b268dc3670e21c818824748a6345827c88604a984bc4483806988e331b14b065a47633cdf9b4bb42cb884864786b8fa3275b3ee7c18d4494c55774ad2965008b63062ce9d814645aa9ddadeb3b308827224b91c1818ebb611b49679f3b230174c5415401df1848de1e1fa0ba0763148c1960c2165967478bbe796f00650d48841a927e9e2e6a0c3847bdab2888477e0f5e414b9d11162293e5fe9a60f846bd72044dfe80864dddddbdaad2eae6f36cb4b7bbbdda1f31a87b1d70fec11348f11088e53d12f4e21bcec3c87b8dd305b444b27746029f7995c769f4059b3666673722d6f42cb94f837d4d6fd231a1c82e34d476388f3524ec36c7f035847aadb7b672e8c6ce0b7148b6ce28ff257b34b59d2118b9fd4698549f8e830abcda9283d3439fe1abc428fd38c35e840fc4196f089be48c553d498608ac823c5a0b096662e7f8045392b2c7a4688865fa7ead988e849522e85ad3a82aebc78aaa86cc93e6fc147fb74121b69bc0eb40a2dfd6913a2e425191d56ff125433bc4ac5c361355910bf75041e1e440b3a1dc931b980918ef7604f443ce8d6c54a6615e394f358893c415c03374139b961afaadf0a277ae79322e770c9d0344e92ec3a4a118c948c642a563818dd5774c40febc80714fb6242bcb146975fa58d0e37e1ad9e2e60f346f6e77725faafbf565f3e94e1b3502b274882ea52868ca144a81bd29916822c6eeb3e608bdc3457c4497e9832365a7047c9193a7272de4d9cf4637f63a950804c23000a7ad564c486524a49d405dd1babea544378237c9d51376d7e2747acb4104139859d6850b494cf0abccb8dd08a4ee07a2732a22ad76133466872a6f4a632e886bce4c6b8882575b061ebc611b861cd622dd9b3be69dc488938f205da49502ca997fb9763404f869993ebaf017117e1b2eeb3c03441116cb4046cc243b1c07cc5bb22a899114c6dfa807d167366b4e33d57c9c980804e4be68f9f88f055b08ceda2a492cbcb292651cc5bb8630971a41747f24a52c1d23bb5f16e3aec380e5b74b47881d8fba039546fdaae562c576999e090173345aedcb9419c0eceb114e138e4523f0a11261795e88d9809a94a3ce1f5b881dfea1dc3be99f26479158f908ef934fa82419a627119fac89d87b3d3e87dd18f12b9d7432af776221b2cdaea1a33d653e5a59d68e119e7221d116329c85970068dadfda56eb76b6864ad98c9db0dde8daa7c7e26326473cdcb5ac9f70b857a0ed4ea1ec8dbde702118d0a2fdb2823fc06e083a6310ea6f5ce2e7853a637e6c97be9969211aa491c8305a8c1c8a8b807a5bd81d1003c4636ec9724c1517a470ad2be4f694a56ba20c9578f8842bd23b7f6d9e95b15d7485038368b32c204211151864e0a68d608d31153d47eefeeb79006aa6d05588502e502d9298569f18d2b03d4c2fd2b6825e19e299aca927c84b0e7280a821306fd0d0c1c50aed99a22d20fef5780b5c0712a421b30a450bb2c03d05d5a8c0f5633bda775ae48d5048bed3de7e649b8c104a2d00bba07e1c82185e8ca43f850c8e0de23be0174ddaa84151e5c044c3bfee8897a2680115b81ce52d88a14600c738aad727a634e9934d61702015bacf7e6978a328348284d62ea15c0367604d42be448cb62b32dfd0ee59ce6adb9d6aa563ecab2fe9f9b2f58db53943f6223533a44b275386e24c95d3d1247e4c2c10cb4383e2c02cacdfcbec7ab2ea40423025e61d33880075d1a4483a4934dd9384fd1ae90c8aa8fec721edfde5d78fe33e5721fe94fe4bbf0eff1cdbaa93e7437ee5afe3775467ca9c8af354e893a02d8005c4e0e958a2bbc96cb56f2c1d69380510fdf6b13c619f5cf9bc6c56332429473c3221d7c3c2a17207ff11fd1fddf41ac486031b5f8e569d7d4c7bef4089a0207ab388b7c0405ecf0f7188aa307f5a42793441d0f8da3ad9ea83fd7bffa4aec35eba0500136434fe8fd9929fae40580c6eb9ec1dae8236fd913fd9b9ce14434bff3e774ee83201f5ffb81df40e9daa05890226e0971189619d690614f997951b29c0ecf9b636a78c56a9d5e937cd1f59bb11c5c4691db96b003f9be81552c4e126b8f2bcb417056ba0260376b12a487a0ee50496fde858112cd128623e4bf69399140273510957d8dedd6a2c7d9878e04c4b846cd156c4f2cf54c84542941c53ca772adb8b5a7d9cd0403636340a48784a42fe8406f7615fa7c35515793d3366ead190e04613138562e11f1ee15ae0d4e042f5cebd596b25ae5071e761cb1eec6bc9a0dcbb9e650fa63303cf293e4d7baa2d7b2878f8e35f010a9d5091af96d2fccd3e783e223ff63a4d2930f236c40e8162d42097aa51714953fec2ed75bf4e42648b5f4722914a515d065cfa4fc074815e008c59fe2b7db95389b998def6825993f8282fae57830a4e28953c83c558bc6ca9c6da958b0615ba879bdd503e14a0dc3118205c3bd86213a5d6d29afb58b119c770a4ed85be3262192c37cfc1ef0d8ef2d6791494fd972b88a0d70e5141da9ba1a095fa2d000dc4de9accecfa202977259930759ba5efcd7e9640fb91ca76205aacd0f44a8cf2bc036fc546c8ca81221e1616ef13089f22b5cd02bb634f036a35a95f42b3e25a7eb5e21f6370e484112504011e299dda8dae5292c2bb03c738a113db88512a3ba00fbfc85d1db2aa756e45906f6aaa798e961d94a1d6e886085c1867ca822200043bc8ff468b16e6cdd5d8295839ac3c34c278e7bf202668d8cdfb93f2fce03662ceaf955c4fc13fdeaf196463f209a7093a84866ffc87fe6fe773a5576485acdc0284ffe2ca1720bbf23fdd9cc57dc427e7d803d0421fe395c28ff4b575e077450152c5c682ad063428d315168fa66c040873430cbe845b6e7e07f73bd331fd6328243a86b115869634d196a83c05b7a8d3ba3c1d3505964a4049329d057ffd24f528d1579eb273bd22b8eb23347f88e038525ab83e621ac5f9732bd82a1ddec945c7d2e231ad485cbb1f2068f036e0a093b4a3a18f262b4143ed5c64351ad2c172cb044d7caf8069929c14992af00a26324b99a66f44d465a942a2e711423e707fde178d94967086bc2b0e5558231224450cb4acaf9e7e5f72fcffd0d058529e5d4ed2ff114d238401a46b56315a28c7995cb9edd403b4e9750601d845c5abe59a16e586dfbe108a1664fbd1173f64485390e81f48cf8b637b3c9add8164adc1265c175d14d13f5bfd70269a285be7e83c3bd6c9414c4e3bd2b8c6e2c028afcb8a27ed491faeab0c08003fec43e92a60191f9ba61c20e0f55a15b72ca8d08ab72c95ff3f367699286c81310faceaa211d7987dbc018d717dc80fa4b45b815fe17a8786d42c4ba6bb68b4d897eab8dc61426759cdfa449e641e03225b0b62202062a6c9913969e3a1a036bd3a05e83f5bceb714b140925323b5f25a0ac8da0dc1c4631a204eab9abe0cd5c95e03a51a89474d2f2511e684b13d99a5c81764bcefbafe2a50bc322f5b08bb66d4faa85e52c54c0b0f59d4664b21c982dc688ad17d95dd4e90f822e6f932b93a01b2c3d1e3b4380b1c84ac742af5705f29eb085956c369c804857a98e8e871cb87687fab5c0542e174d0fed4d8b8f774ed01422971b4cd9a55e0f7b4fe1c38f27dec92c1682f58b5b2b67c889dfdb388fc10ba59464496829473a23e51a4b0155087dd6583d055e4eecec5a07043f9a410a3ed6128bc616e5a88d1f620046c289f1662b479489acc1dac71e14aa175a0d3deee99c61a74b54f26dbb638f27051bd0189b8211c39ac506b582ade008f1c56ac352c113784a787eb653d1d770aad3faaf47c919a77602bfdca17d088665d0a4d9fe388664329b43bd711cde1290ceb23dad095961f7baa8ca86fa480068ea8c64b2f0a08876144cb400ae70feb8856480a836d6bdf8ebc6c690b041bd1b9c5e6b9c674f8734f21b74e0bcb670c6bd40a876a343f239ab9486f5b5a1851ab147adbd2c0885aac386e491547b41ad5716b3e3ca2b52a8e5bb3e388d285eab8250547d4366ac7edb930a235551db7e62057849df2da156844d1c39109968354a8047c2f862fb5252398b41da6256e981fe2c7f803fee0d7f8117e85bff047fc247d8e93ee472956d2771e14b1c31723aa736a801271ce9766522f37033b1e7b91c98b2fddcd36be6bbdcfa4f9388b22ef4b7a4cf6f44dfb4acd76083da2137ccf2dac1ee45defd254df70b7d5e0fa06bd2bb7ebdf04dc91d72eda9c97c3348ba2e425fa297bfb86f94acd63083d6e277cb35b509dfaad3ed0695f6b6eaa69f4039a5656765b65ac59ff456a9f96eb388b22cf4b7a4cf6f44df795dae6107ae227f8ce5b580de4bbfe92a9be706fabf9f50dba2bb1ea3d44fc31bf2dda7a2f8f791605894bf453f6f60dfb95baf7107a5c4ef862b3a03ae5ad1ee0695fd66eaac788d6ff0963654b41a53ce7c7cf9b19345f20daa11a0d95f30cb8834b3f560804af09f5d78c832883e3edfc9d15f1c7ffd20f7baf7b2a6e38be949ef051c4dee1d93aa94027b8cd6d18577dcbe5bb65c30333b94110845ab042fa11f29a22e07c7c50e8a7c5197c039b0a2b224eea7ba6fa85ae8eedd91084963f23f7fa64b8de65187b53f0f64cf4f2b8b591a23d47abdb348e7c661ff705450bcc86adba8ba0ca4500dff50565fa88f4d537bbbb9172f0d4cf837f6fb509cb8b33779ed1e49293d8c6634eb0bd60d6391b8cc4ed967d0eb42353ed51a16d92fab6c96c5567bc905e3a40ec15fb439d941f9ebc6729e2a536f386ffdf47313a56d46a603afdb402387aea08f4f4d40e34965e57526e49da12fb0675a11325343af6546c897d938ad0c9bc52a9a1ae43cbd20b48e1f6ec8be9a1d819e5d33350926ba5fb294e2767587b6a03f870a788bd72c358ee6493688ed9dea07bfac3535cc0c434bd3f24f65172f8a873d2b138303130a0a831318eadd469ee79c6c83aa67dce9ce93c39c690f610100d74850a47cbba48f126b0abc7c65cc333871e1232a95c44ceabba8db1d8a8ddb0cc28841beb4667c8aa4dee3fff799c57ae9db70227811e97918fe2ba1b188428d68e2506a5b32b9a7c02c1337981e6729353f7867df9502664c293e0c4ea32705c3bae062f15046699c21dc434b6ab82f3abc91be62563b4399cdbf98acfb94a13b0099f585454fa755f1a3bc704f9c87459274382cceb00f101f942c1e37c2abc63c1a8b9536bca3a020fbb45e8b72ee197721c3e7305c9722f02e40212c60332e12cc4d1a041aeed52af3b41f79cfeff923c70ca129d80f43ed2e57ea4c44d6754eacded98a83400742de53a0b307cc76e2023ad02d275d8407de3847375110aa47c09f1144676eaad300f9fc76b1b3e4b7c01500a4f1a17d00d430ab79f1a92089c7e7648f238fd84f0a8f034b5c96925e2a181a45950ebfa015f21ed41b72abfc5bf808a595f29c30edee18c72ab88a6211dc39a4dd5c48bc0c2ae13c2756c047e24897d9a3892a4be906b77493ddf3fc2ad100045f5c4020141980570e928d2eb57c89f8f2232a2df1f481a0465c427206d7fe9663f52e3a41b15b1a6264a521828a04ba4434e22340d8d19d614be46874794304f325f878180c89688675c9a807c2c83a944fd1a40a921696e40d762617203b2e12485b976fd4cab7957cb278492c4c69a56c520bdb944dae1c529af3f3616554bd0fb43c5a82f56034036af0ac0c4922cf31cbce03cd35fcb88cdde842066d98d50259c26b9a74381a710a8f2b94cb1c7c0ffeff4c6e7822dd1d95e6ee95e2569fc96cea28545ba6be9a6d6edbf4573d3b29f277d0ad6d8780870e71346674126c4241dc3b44d45a24222e4b72c0d37944a34b4688612470fe1d10f21ca33cfabf3b050649ac4f9879d9588a9db0f64ea229a28ef313a2399516b4299178c2174e01043fd71220c91852376c050774840ade48199023e6bf8fea707bdda599f6c564b08c79c78c8492708b32d0fdb493e851ece8aec540f93201cd11e7cd058f53dac943c453ce4c37adf4169f89ffe990e0f0590df2e2225a01db627710a3ddd1b8855117c40cb8088adcbed1282dd472b7f5ddd420f005a85f85707825c19ccf15811deb85a5aeb2bb1759cc29463f215ded3bfe79584aa14b0e0b1d4ec6e3f4b2f9adce7af442fa5b546f1f523345e64e3ba5e63f0330cfe124353a8fbb5282c4dd281f917a0cf92bee22774aca96cf7eddf84e3aa5d92b05b42c4f819e28693d4d91fbc56c0500d4c6ca7e4ec18070e586b3e79519896c3420671b4534880d32fe83b3465dee8af23f2c84b7b7aec4a34e62339cc21b2cbf6a1ceb20374cc8c0357ca1a4aed5a878cafe008b7c905c2f4736e6d4f23e645f833d61050be546d2289f127b947568e959d7c7b9dfe81116d04eca0d2dd95bd88c325be8b70a50324a07fbd3ee7def994c5857609b089a34e3edd22c1bdbe7203d0c431e2a4cbbea9f8d159ecd320659b26e2c794ada089b656cb349bc486bc653c7e4f9c702349d378d470133a754e9057015984ad0d78197e0d35533071f0e847c6b9befd87344da2f2dcc2e43dc1416ed9c8f66a9bcb9b4af10fdadf5a36368bf38dc169dc3e901fb46343931a183d21ac262df56693dcde0d8a6a9818e1d1d8cf780644a9fc95d4f1cf6a132ffd2b188261508c15620bae4af54bdf490e4023b1d002d76e69599aa14d3130951c4554ab671a525286bfe9034671bdabac5470534c6f9ff52862aa7947f9e858a039f2af6687ef52dc1d51e12848295663bc8093552f9bb20afee3e1339f24fd7e6a7db586c85bfc0607005c8cc190de5f814048c17ac4b0969512eee7ca3ef0f5075a3a52bab6c0b0d4503bd24c8773f722c47e161b6a681a38aec17500ab88b421b6b9238b313451f54af11003db3b26959c5d8b0cc061e6c6b429edf9aa3f47f61ee5c80c286f01444de73c15e731833e3a9b4181225687900a282248a85a5cca5505426fa71033171a9cdccdad928d4395e666d4547b494d68aa6fc0947fffdc965ee7dd772727b0fbe34bafff8cde1b6577febade240b8c4c3bea674df7fe5933549098a858182806a53c3fccdd56a144e8c1795c77b854296a4f780ee734e4aa24493b9701f959d6c2d63244bd4e90368be763ce23bc2028fabde5d5dbf7a893688c3858f4347e6d8bfe39e565b15de1f985e43f0784925f7a73af99d5408caa6050cb27d9c71bb0fb5d470af484df6c1598be05060b03cf9f818ddbc011806226bbae750ef0666ec4641331a80af188406c3e1f8e241ea60d5c1bbedf29d6c0aaeb635d2a5e96ec78677cc7938d399803f18d245998dabc79eb2387c2e273c4381a27beec24140c3a805cba13da17aa8115ee2352b038f1204d826f82fbb9008af18ea4b0bb711ceebec80d29fc7b523d68bfde0e88970e2040203e4aca95b1da8d174ae91bfb6c0647d08d788403c76eb688a91ef1c971e863431df4d8b2425e8512500733d87bbf15bbf79a69125c17f2157d085337ddd684c050131a6df75d29437e15620e42ea7c03f2a7cb23383f5cf24583a766ff50690773bb259c353cc98852bb0c78e2669485c06be912222a6e973642563758efd829f94924740bad72ad81498f5f67ae9831b433273a1c91f1d15423592f69b9d5cd0bbfc0985a19133f640d145e05c610159b681b10c9f8a49ca949c3a0476d4bfa43f8040b061d6875a73c1aef62a800286de94aa646a9c557046c54d4eb281df0cdb50bcd068c21da38c63e62ff2c188051a68f56407b9203016794f6c0f73243f39335138354d74c474050dc0dfc0173c4f8c0ffc85b5089ebb362ad56a6e5deb784c398e7105779131fe6240ab45bae422217fd45d2b32538686e5844331f9448bb9145771b95053e5a579310c659e53284f5d8d7084c61c3b836639f7fcf36933594905a3eb0acc57ee51264b5ee51d6f8c0fa00a326fdcb1e6843c32c3bfe4aa6b45876d51e494d5b166f214f03e22147a188b3dc0095a0e5b5714ecabea8265aa4c9796107b929cb1788a6ad0e1563ed7acc50766b6a7d29cc4b3a45822beeecb218b529697537ffb18d06956af3ec0548fbe7043fcdeedad471ad8a71133108991bace83b6cf15f61c27adc7193984d886d6050b286cd286942f4e5506ef9a116a1815af8a294b94109b241c525263a21e8ae8f13013d346143967813bccda1e1fdb20daa395c749fd937e7e8641810a1009a25dc4dbc836e94675fa67b717dfed58e4b3da9b7303e726d542f00f8b1902a069121c0858e365bfc37108a0a9485701b633be96d585f1ba10bff28bf918b78bb5129ad5cacd4346d6195d05a16ec1b0fe47453ac6fa9ab76e422abbb2222626feacc4c31e688e435d318a536a45c8b6921246e880c870eec0701b9dd659d31409531987ab8c53613a775ba631d2e14fc650967b45bdb0ce3b2eba5d4355928e4ab20d608bf9f6d4761088b6244b68918e6c28233795ca6d523a2b1dbb934265d1954b3e0523fee44129cb4d1b5be2921614729123e4738d485a3f6ca86926134fbd3a9189044266c9973c7400c289561a307db8a2921244ac964df6ef44339f0a86013e91d86b2fe6be2da24b04f48d1061e32906d7aa38a7c9350f28dc28849d6d3650bfca1e51d2c462e1b2d29294c730496f578f7331767b9b98049ba2f8255ddb48ea18ce1fb8f8b9b22d1121f2b508d481a8cf97f488b4393417702105ffcb33ddce8a6f61606d0e0e0c7afa303aaa07e27e9e708404de5d589e9928074d03941359704a94b40777bde719c76f48f34d1772b79fbb2611b7dd03b6a5d8abb9f657a3981ce01483d1a6bc7de5f4435e41b84a7029f607a70fb8248e8f480eaef8185acee8a6bd4007d949a5aa3464541fce91a35bd38fbdb1b1d6a4a5b8cef7b387a6519c861c667ad1e32bdeba51f4d83c5c96efdc9c07b71737b08d798e1a9263d18ff21ec0f0c8121e6c66ecf72bd67d9cf129b0ad3f7c8853bab3f9840269f2f315fe7b96c4c9780366210018c0313ff35055845fbda65b61061cea88248071aa18555f6fecb4c1410bbb8379ef244258d2185c9ed054037a5047947d9cfa04847f6751a9e262db0d5215bbe282732b5d0e4f0ff831661882ad200d4d404a7ff76e105a59226f9f25f5838f78ebbe3ab17fe3b90e12eafeb5e1d5a4676c9eab781b8942f8cb27b720fa8a5f3646fb179203f7ab28dcab74af424d1472bb0b8477f7515b7e9ce9f91f336d35bcd25a8c51b0662edd4bceb68ef9a59f36818a435ab50b9b1757430a3d7260a25bdc6afc74aee742dafb4a73fd7cefc6dd6274450685b786bf210955f7980083895386980336e36c152d70c76186117bf3e698eaac52abe50e812742364cecc25abb3f532d6a110ef0f07c2c1bb26465c64b6109ece906a1d75c8d33204c0f48da50108d8a43c634a4231838dace19922205aac159499fd0c68fc9b88d1ef2e9a5553cb37b6ce90255bacbd1019950d32197a8e63264a5d570037e6d4319e8a0b8b465087dfca5667d197f241a648f897f3f7204e57023b9a143045c22d7f248b045efff4b5c0d8946c2738c579c74dbec55c33d6690685c16f7b00df348d29d3845f2f7adbc410bc2b9c710c71e0dfcd144840fc3453be6f8b0dae28d89643e9aaab2469598ed97b417842d7553522b6f642c003232250550d7956180a9e1126eefc29a7ce980a1356a178aed90d56593627da13fbc4fd86476f27e7bb617dedc13d67e0b1e58a76fb3c1082c8c44c8afc428658b98347506554a5068e7f38749dba86f573059ad9337835f03e4916dc626437dd54ee1a9df9c2f67301c680839548fe948fa39a529ca510b4c4b0a5656a261238267cf9eb14fa25e7395d5251f4dc88faad01ac33a4da3d70bf40895ec57b62009327b69576646e83da648a81f473b4231621849ef813225bf985a2dfe8de13fe629a279945f9d875fe18179366f2e9391570c25ea41548eec13d09bc34b5a47e40103c1e06c415d6844cc25f1337cbd6549113954b060c8a37a20ea6bf94545801a4f6345e819b2bb225f59b4467c18e39b6d3687abea5d982095be64c81aa17de7f6214e98285b5cba9366b49124ff5da2d25ceb2d14a324f4e4d5a617c14c896068df3059c82faaba6a63346dbb9bde010c2a606b10964a1f6d84c85e5dc1e87e1c4f749938e0a12d5583f24986cd058685f1a3eb5a0bebff0f1dcda91013ddbdd8a2359ffa2337f707a92cf3e2d95e3a43fac443d98ca028f0b3631bed6f5b9d7e3e72fedf50b23a8ed9f729aec5efe518d42166042c896c29b10ebdbab2b16b9b3c56aceb3de0d360c1e47a5261ba032736e96daae2174be68e97f00bf49527cd13bed1f8ff0429631cee97534b79509c8a0cd2be245d41abb3bf49890fd1f2e80b9c59d45a39e582d1ee51fc3e44b66f440c42656328b81528bd0c95a0391297a6bf7945551877a79f81ecf1642da61e00e38f55f684ec64e7683075aecfe29803a7587586900d3d7a3e51d21946fee72204f85ac6ff41c2074ef4f06546ca3a928fcfb942c64c1e79ebbc305cabdd7394e457f99a168ba67e42a7d08996a140ce507c2cfd452844f19188d61979b59033db081f9b231bf47417525e9d87ca57322fa1a40d00145b64a40199cf418ffcd2dc9564e79723c7e0282351c2c30bd9cdd10191c99b432a5f208d73a3b365f8474d0aae40e300a34603884ba16c6141bf943b45e34012137133b8b74fa4be31e4e47d6b8473e522a8368aac1c4e7db268a2796d2b6f1dcd77b0fa069b4eb48fed17f4d265e1f61c08a7537a7cdbd85176258e321dd223bd7b9f28c20d2b91fa4afc6b17653be133dd5693e7fe17919c012ede7c4122d2a852c56712cdb5d4d9419631c867ea596edb13dda6404e45d5ef503c69416c9ac1472187972f252fdf9893c16ea15700f775d56fd40deec3536a4f97e9f0907aabe78257a5768916984f72684753dc1241f8f0a74a6286a223abef213deb6b1f73c8480ef67a966666f38596547b317252c295da1d22b094f79c9337b15d17ef0a3b7a5abafed4e604430070e29fe945e18ff2465bd72d9a5aff4cdde6fed80c5c714d6e748802fec64204f4914bbe8ac757c6dfbc169ac9c36852f6807f85ed982f13d51646b3f7bbef93ac1eadbc6295f896fe195e32649043ca5e1d907cac6d177752a7a108833d3875d58b9fb3e5fb9d03eccada6fd7447df9d1068241f7d6d65dbe0726ef7fadcf162784de4b0d8baeeb4e6c3f8332c379d2fc480899c336977a6b6679a0e8e9a5c148c290ac9338a6613055047e90845516ca3c0dc9e5ce7cfe41f0d0d6c82a4ae1b78d42b1e75c7f6327b25bd55974b3347908d8501762100f30b5bdb504924d24be5040ec5c474124aa088318869c8ff20f31c0b627cbd89f48921ca0f8c414cca9e5ee85d4381412b1159a13d5d9df97eadc86255b6198406de45ed6b8b499218e8fbfa3a5edb9671b5e5944c165b8fb293d662302770515065c9b588eebef34f34067dc4e8a69741a35b6a1da43bc2d1915fc27e3a9033dbb92829828ae65f994999d3324e31dbeccb583da033e235677b4656e244649fc9d632d60e8e4fd6a1b1775e2b41da5f99e17817780c5485a9ca89f5398a30969d1af472a0651762b2561cca5c9864aaeb3a7d1c280e9740c35cc4750836c226ef7124836de7615334dee4fcc4b866a23b533565a2468e26e328822e0a4e15c5231645d28d82534471c4a394dc9ea8739fc8079b4c84a4e51c9a6ebc324fbfe70d509d086c0e0549913676d9ee8a988e5ae12da2b98d2ff422d9d7b1fa18514ea3dd9bfcafec65e2a283681181ee8a1a513e0b4edfc8de6ef9cc1142d2c964d50e6eddebb14b8764ab08797fde40fe0fa64372d62378f8a8d60ce977222a1230b325696eb266d1adc278a71284c97e29a90810a93d0f6952a73d3aa2ce4e2fbb80fdf6ae7ce9d9a5a49cf2e6918cdbc6a8cbde3c747541d01b87d5c7cf91deb875e4fcf0d142b322266ef1c1c7b4286f623068b60521c726321f8a8f27b04fc0fbd187ae204f5eb692c5b3726f62292ab3b8629c31fd4958c8eb4479205ac2467507005ba49c5d411db650013006ed9e0583e231a8c37153c128bf660693a43e9f81a5755f677ff72c93bc98404b5141b26bb362a52c174d7117d528e19788e43dc07ae9a0245675c0ef1fc45eea44ce2cff96b40d893d84d42acabdede564bd15eb20f45a96a56cc8afd6082e14a9b527990db9fd8da5a9cd60e33d26c6b7132a8fb44ead71df9d1245aab16963b226052c444d1a0cbc0056d6ccfeb29139025928320d24fd92e3867eccdeff6d0df4eda3ea0668646993e2ed1b943f40e1bf53aeecc0bcf0a5a9a4ef2e80fd71e2b6aaf5a891a1262087b5a040dfc7d0d0e66989a4332f4f267f38298ed7bf258aca654876b368596909127e0bd52aa522e9dfc2183b475c5d33f05274bfe06af745b847022033f5d1f395dcf4b7e9b31259dd4c7355c29d90c99725e7a3dfc4b0c4a690a6ef4a702d5ff5a836590ff5aca41889908febec2ac95eba559b4a6e35d6e3539250e95d88b84bc961cc1f41e466ccdb47121e059d490e31fba5793cd02ba804a7d4a369dd23981505e5af2b9d17c95fd032d331e5cb67951c5959d7fe7a329f873ca1fe7e2f8d243265645dcc494e87acbf48d2d79013d924d758d0d32729a85bf094d88de414f041707b5772bb65b71b39aaaf0c7db5cfe55333b203f8d1a7c1de5ea8e21aa0fb80d83effc249588e4e9994f3c633dd3199e048bdbab38f423a7d839b52b0da8ad18ed1d68af1a07ddb4a969d0792bf0d1b9cd32a6be281ccf9e10fe10e04b48e202472c848c95e305388041943867cc816ebaead9ea4db96833ca8d6e7ea540c50dcf8af1ca0be40e66edd998bac48126687f06517a1f2ccf896757f5b32c3f709d20ab44a0dbcd4380fea45f06968671eecb0d0c1b79639b0ff9d660208f5c2402d4145eb618d4a7e11070b27eccbabec8fe25e9b741cf4024a45449f9eb56fb0320291977f1c081f4f4c4a2aeacda7c778e8c2d505fb3eacd9b7c5e118051c1ed124245e6f73dff0be07371c4620968262784df104714f94566f3d405f9f42760259d7c4242b0ad03a2acf938b97f5ba99a7016395bcfa267d42175f1da3079b09e49a74d49e3146afbe54df658fd7e29a4a0b1bc44b8a809d011fad3b40ccbd7f4a8abcd61dc632169fad95437c4740efd770244215e818e3281ef8ed2e5d4179164487bcc71f2f81e45ee4610fada4144c037d78cc98df007d84f341254b51e3cbb65a924cc409c697de9d277bfdd2337844b36e252ace76f400944cb8381444b0225e775e208d2d7ecb395f58b08ca58d50808a30fa518122c3c966cbea619c32e6c4d43ab1096f3a71a8bb481c260429f6425422507a052d31b339924db0a9213a52a64979d570bf2dfe59fdba85e6fbc4ccf720dfeb2b5894674f76ce2d7df647f1dbb29caebd0759be638dfb3dfd6703c56c3cb7fa2051c528552f3efbbbb32d6f4dc43907133936024be590c46bec96c18fe5727f7f248302e347d28365e5fa3608a929c89d57999da6fc2d1d598da193765af0be9a4a8a5f22627aae8f224fa20f243ae85f272214d4999741fb7b4c908a053fd6cced7893fea06964b5da95f86a4b9822ad6873c5cfc99dc847f0ca4a2b6c6cf1e0c5f87d15e62220634e743a50b3059ddfd916664e9fe1d065f4ca5d538d5b64dc48644da0d6432167507c8bbddcf1ddc18ed814efaeb7e99d4bb6798b95874338fc6d4b9a330695084d8c164487e6095a11b7d63898bb97f3c290db4a2c0931baffe4720c35e38959705ffe9be7ad7e856d244a6e65770bc91d89473d2c7f54b0f8f25dc55172265504030f73be16f4faaad5c2bc99dd62c840b73f64a5fdffa85b26b8851964bbff6837ef981dbb4cf47365bc02144cb4988e107d2dfb6fe2f98db7984cfb69cdd50a58fb86eee3a19e283fcbb02b5141a2d21751b73ac25f9faaebe4e705a8b7359aeb95ac5e89cdf4c461dd4dbc9ee998dd0a81a2c1259894dbb5ee6748df68accd00485b9a5b99762d986d478f7e48ddf02bb7c21f454ee080ba1381334fb83f45bf53571779daa239e729c742d03c9f8d2f61ac871a80524f280a566864d619eb3abde1a72f86d22cd4807a65e7d2ab1a55182c027eeb6f3024d520a18743c45ae20a0706cda836f4a2518b60c389ebcaf898ee263fb8656cb2136be3f744099c792e4e1e1056ef3a795aa182c6b175768dc1fcce6336b81c0afe08563d233f768035128578551e169f8c388a9a3205217d3f585370617c87fa0e0029e175aae8952ca9a200633d77df64f0e11ebcf3934f24d3feb5eeb031bfa751f3c752023cfc7ff429afb52c9937b69df992620baa755378b0fa9da56b1318e865d8aff792e63999cc9e900337e13563098296d893c8f6b33f05799e8c382ae000927a009a5b72e6219609f0cd28355e72a7c0eb84613b7981faf204c016bc376942451fbdf10920040230ede28ec1aab0eeec9efbc1e1b2dce4944b77e638fd2c9bccbd7d2c4e73d1e1c88a416c6d568f2b5adf45facbb4b16ac29e577e2fbdb43fc03b8b4d13cca1a70091ff7176e4510abf461a65ed8baeca105d86cdc1a3e56adc64acd273dd9d6d95b48f9478c5eb4ceac626834700dd360414e5139b4d15d3cc306a879a8ad1951bdc9d978d84196e9170968a82d80cdbc06e5859538edb6c0d39c4cbcc920c5007e7628c085f0ea7a47804914335aa90f9a9ceb170d1c9001aa39e4eaaf858d7bf6920d7cd18173f6a1976558cc59714093d258e8557ca826978fc6a5eac0ab3b5ee0101ef131cf4b544da1f7fde3f030438e04d710bb4971078edd881ebc0d3f9a23e83819410b262a04992577e41d47eba0d5b417091f7d568c4b9439e70e914f7c9c89347408ec6040e2e0ca0f979e54b9e0050e7acb7cae101095204e2883da0399f033a763e75dbd62eade1630f0135c912f8b0569cb4c8c0527db99600d23ac51c6527d3a89cf7e538f49bfbbf25146e070e25e12120dc9881376ac934842745c44989cfe080be773864816c1122ed7fa7a23e8e25e2375aa1363e486e7419ad417b861da13735365c010669abc1983129453efa77d23614228f4edc3f84f602c9972edca5c9cc66d624b758e5faa4d7f973647b1573c3f885047421f208bd2349c561ede5a035deb3f794a4c351c05beaedb893a2d87efbaadbfe9d5ec70f5dc4da8640d6858d19a785271abd4ead58de0222f6216ca44d8f0e0e5a02584f8834b9c4e32ebc17d7ab98891686ada3050ec2103017c8255a31a50bb9b51c1cc56ac12791a78c0c896bdb6c8e4e6b8db4b6e7c20c004163a5549d4d8e07dbfb5256536c44fb0a3abb4c0770b055b2aa7956f3fd87f9577b87389f9c5c9cc079b6ed6874850fd70c17badf3fe043c4ac8f3e4b35cca8237068c2ac56808d0be6ecf1ef2c60b6c37eb3fae5e5f7b5335f4ecdec2eea656be39b1f2f4fd3bd6e70edb2a076aeb0255db6d3ef4db1cbfa361a3fecd12d8cd569d8d8f668dced671318ead84612ecb55d53b7da24b9ec2b0048cd2c4f8c19c922d445320b9c652b12395d56f6bd4f0d76138ddc93fc0df6663b3101fbaa6096e0f8b978328bb3f61cc41fb2a23a1ae30dde2a0de87bb5ae867de1189f77e45ab309a3c374a2b9678c15c23d3ac649e0e4fa58afaf4690b1e84601c4e6685f9c53d4deb3164e650c5d4f056386574396bb835559f69fed28fae21cfecd1235d70c93c36cf9f5037fce6b5d09377de331fdccc0dcfc25e37972ec229dd1d2b15e88d9982cb7ab57d72a7bbc2dd3138d8d186428697667c2453b6795b047bc76b30d603dafda6ec918518a0393abb1f98928b9a7c5c33ce44880b6da04f762b19307929c02660b845b1d14f5cd67a00eb4af1eb91464da42e43f35911ca20a107ffec6647b31535608067e72b16bdf070b1b08c9392fd436663560df918ed1c86ae745286412270cfe3fc6e31694304c7bf02f4082025895fa8555aa25f782b4c6487d21180b62439755b099874fcdc274662c6e227f2ed40cd98534793977c80e081e0c581bd4e47eb17dcc666344d5f52e2365e18fa46435e90a3d0c0a4a6d01d301eb05c9b46b74ba283fb872dd1d0cba9d064683a83ff3a2ff2d46eaa531262f8fa130c760e2d8761f21645502e68adfd3fcaccc40b27cfd7f3a9be2e5113d6d17075e437b28977396ba909d2b5f1cca7681c1760f0c0deb26d64fed922dffebe38da8c28fe59ded1327009539f2da15da493c8d6a10324160a0877a36b51b8957a5dedc69f7315ceafddf69576e88303a566072d39bc1287a0b8136657a3336454f58b9364ed79b75c5661bd0ad579ccbe38ab21e6a5407d29a76577307d70421d96869a65d9d2aaa39e15529cfa067777b5c9e4910c50b21eb4b6a5931575a0c595d13eecd8392f405c235a44105e3a9605529ef4208d54b7fd886c48b4283977dd1b5c892f485f9dab8e0d9e6bc4e61695d14d8e3f3678bc44cef6b0b6ff2e944c5455f9ca7567e524be9e99c67a59105add79239f17dff094116425d11fea415b6c79e7e829570038c1a256b08b401291381c12adaf401408df94c563a65b2344d8e24512b8a0da8a5ad9c890d389dc201fcce840cc813a203dbb3f882f3992001ff04f4c08026fbbada204d804906220985b955180e77bed106f52aef27e5ed5de8aebc439577ef3cbcf95554bebccaf8a65716f8f202de0bdf4050afe76719296d2eda148555f2ccfb39d0871f40011a54098faa514b935920ab7c5e261280d84ac9164e319494b664a61af349210ea2601946061570222c359a83c72d623b0ad35598ade89492787544165466527aae8102be41630c79fb3027b5f9d6ef246676f343d77956d246dfde2e232509486ddcb6aab484a5679dd7847fe245bd0b86fb8e7e885c96ddaaa80e2a221542e5694424043e244605124210a0462936c330d2293a262d27b76ce3da60f76105e33015f8bf11d21b211d9d6425572e25d0ac0cfa8247235e02116a4bc995bdb3ec152bc3fa490b10fdd6f6640733165b10ab10fe4ee0001320608b152d0a80240147625375369c6e9f49b57ab92a8cc4fe9ef439d69cebaae8727a4722af9b5dd74a0013337a5168b4a10ef214a0487cf2a77baa1632b3f4b9f9bca7d7090c68b6a52da605498b6c312dfc5944591756f6a462a8167c8fd3db3a4024fe4b5f534dfef7ba3ec522faaaedbdfbfab51bcf26ff612d4882b408d168341a232d3f5a84b42019d232fac4708ecc8e46230afd08c6a96b9c5a224936991c0c89733a6594294a95735382461bc523b8223aa9a653eaddae76cc29a757865ef4d42d084820247633d8183e5a99bf9b1d03b122ca66c89235fd2abb2ec7e9f5747c433fbf61dc1a1541a27aa5587b74b97d599bce614abef0621149b2d10090f824a472aef666ad4aba92cf7b3cce99bd2188b11bd76dba2c1d2fc81ea777c9a7b3e1cc91cb4da8f2be2aa2d397f07bf59ab3a7ab2f2150dd7c409dcda7b3f178e705f471e201c16c7ee4311e5ff28b99e047fc37e762b9da9ceeeaa39c5ee6470515d1b1b9755f65ec1a3fa8864c11a17470b2e55d6b7b142a1e4174cf1f366df8be55ba5804d12963ebb5f4c6f67d6d4eaf93da51f2e9843a0ed3560a29a29a92fe720d2eda952d737adfa3e4b379ebc4032a2202a241020488088886f9c7912049ae1001d1b4c644926c764c2104712e4aa553b5d89a6b2ac6e9f5c4bcb42009d2120212aa9e182c368846a3e40b2f3688088846b34a341a8d061249b2690282b870317f4d3ad5cf60534eef46f481c866a3ac26af745e4d3a4eaf7c01cd4dc8ffd3f16c56c9b2da2a5ca2aa74be7afe663797cb218c153a5777354a277bda736d7bb1dd2d7d9561d3dfe50e8d44b1a37caa4e5fd718ce6e723d17e7bedcafab2d74ec3da9d16898854630435a7cfefa355d8f9d73ea1aa757ed06110161ab84db4814138244926c3ec062edb59873858d69ab764c404356b0e29bce9973337cde5757a7c95b117a18182d5e623e6b051c194fc8aa55561036f75cdf08154b9ed0fd569edb2a0c4c8c8ace5e75ce35e80f157bc6e96df29c4de899803c1b2531f269dbd08fe0e8a5ae0f782052f853fde227fd615bec2989910f590a34f155c69456daa07c25d7727a5b90046979312d4886b46c3e9d0d0c2844178746300b4611ddaa6b5b9d6c363b57cbe97d1f02fd08f91692d93a224936dd81087715e477efdeecae950391e55b902ae78baa5eca39bd21e74cb526d8405c4eb99bb5d74ad99e354e6f6824dac01624415a7ed4099940e42618c5bcb40031d2a21a91241b2d341027ecf54b365d4fc25a1ba777b3d67106e2765be8b6bf9f6b4525a7b78d5eeaba000662a3ee195b05e1fcf65c717a43fff97436bc6ef45297bb4074d5f99b62d7e89cf52ba797238a81713bc402d16585ad95b77e4eefa8e38111a97d0afab0b63b454b6cdd64abd952aad9be95d3cb041452b259ae40a4bce894eed1da1aad4d717ae9c737bf24f4cbdd822448cb142d3f5a90b42019d2327f0b266e04a28002715dcffdff5f94cd5f8d7e3a4c3e31a0cfe6adcb04e2b2b9762a663577a96aab054990165e31215075e21e1851a70a8d66f452359a0f81668be298160fcc4ba705c990960d379897ce7a89f9acd14b5d9225d665eb155c5f4c99a7e3f4be6d0944f65e35e892652bb7ac38bda397ba51f2e978013f049a8c48928d8a405cee736b3793b4b52619a777d3db8d4892cd83c00b08b4f1d0d0660380076c4431a1cda6010ee0cd66bd708d61e68b361d68801206ec06e461c002141081043005106081033cc0007514b3814001e86fc0078340a106ac30070102f8871a3000160104403412759a3c144f6cc8df331d0080a580132e3d1e5068033d32c023e4230ca8ece6450c4879bc9b2620262314961d0fc8ece66513028d7c336af211484fb0d1a3104bc8fc8b7f527a14c20e028022bd11c71c53a4b442c74b3e0e5024f3881628d21b71b4314522841e883ce188cb25caa8222bac18e087159e48c30556a8d491892e68a28e3aead8444a69071c9c20a3046ca883c971023e84000b0de0a286a102605001068e90013330016f60468f2d84710516496cea90840e94508726de40893aeaa843135a9c20e5892c5c408a3a76f060c4017610813322d14627115080c4d680c3f0458f42b80841c31048e87017ea78842282d4a1891f92a8a38e3a3221052a240734418d16077817ce75a17601f3804f1958e0814a8c34b1c3080980021c2e684000134a40c20b7c5023066e48b201e508e700273aa0854829a594524a29a51547d860100fd8a02008053610840c2e50410a1ddc00011a1c014790090ca00d321c51010ee481076e243e78a1073748d2814460c239c0c90ec0e0e263008cc8030e6c20832a689e01d8308833fa9003371c7004308c000a8580c31bac30630e1620821c8070022acef02213425e90082c4c8205531832883a0071e21114208015305111f10041fce0105c48c10d583021055480030b7bd0c02284500810b4210e0aa0001968e86c7cb085276a60801e4e9861240b0c98c30f8003315044183411861c51a081821a0437880102718083258c3c8ce69086079cd8c11dbc20c28623f6a0803eb8b1011fc4e0052e78431a6824610201f200051d7c900918d060056a8080132259acf182467cc10753d8802618b022c5025e06aa508318b2990a204c2004377063063590c20327e0c2092a28421c0e30881711208082e17280391a914520f45006070d0138608c18e060a5a5080e9ca8ca0831e8c006204181230c8613e8900301ac618e1bc444332ca0112c8f648631058a2560f0a9011c8ac8c1032e0c808d0c18d8908413c05051053980e10033b85083024024108713e48803650d73dca0058d680100ea104b10821af421063c5883e8036468a28607ae208718b04107185aec10840c437ce1c5134f6470a40d8933c1d21352c0404a29007540a2871578c083125050870f15391c20082124900c0e7814c186307ca0820aac8108862803128f38c28b8f219031081fc021082914c18914606c81016644a104113888c20f90508336763088209e216670810e4f2ca1e3090088438a2322e10709b0073005006940c6c721a00ce828c2150e48830b3fae58c30e94c915368004180520831225c71993b0c2245a22a0461d9bb8c2913aeaf88214d4c8f858b944f2b1a288e463850fc9c78a1cc9c74a1b928f9536928f152d241f2b50483e568e907cac8c9152eab1c2031357482b9888425ac1c41929a50100600a1f0250493e02f046f211801a0091c00514007d04c0937c04e002c9071488483ea06843f201051ac907142f483ea0e022f9800248f2018504928f27e8483e9e4043f291b0483ed214c9476ac947b240007aec40e931c615d2ca1867a49531749056c618a595316a5a1943053e12108380b412839256468d482ba342a495511fd2ca080e69655486b432aa425a190521ad8c669056464cd2ca48495a1925492ba320696504d3caa80329251f4f1800010218c00a545a590103d2ca0a029056b8b8445ae1821069850b39524a5008c0002b698579a495d5445ad945a495fd435ad939a49545435a592fa4958d425ad924a49505424aa9010018c00008f0048f1e50f0b000025ca00550529c887f482b310e6925b29156e212d24a0c23adc426890010204091150b7c21ad58e00a69c50252483d84f850c02422910122a43212190a008228a4f148d95984223279c88c2123061f0978929e389179f264064f9e7892d2932769c79384f224e5e04912438c949e48004829e120251d3c490078f264064f9e88f124a5274f74909ed020a5946923a30626a8612483454a69a58be4e3006f280d47e1e4d319b9c65ab8b870c1583ec05ccce647bea413827171718db54829ad241f07e0b89152f2e4c3007e108534232ff2a34e8809f50f3117c34b5c5c60443e0c80c487017e240db0b8fc171dd1a6032c2ef5431978bf85a8033385a803e3bc62947c3a1e98970e8c080913d08f4e68b48111a5b44300a2a7a0cfe63ba1510a92a4d83c057d3aa1514a68ec50c0c89574967800467f84be0744847a40567cb4f8fc17a01090d18b4453fc6002f23c154e3c9f2c44f41303648a1188c8080432f2d1e203ead04f6907144f38f1212022f439f3a533a48a5845163f88c48d912c8c18899b38448b2ab2c062738229b048690700524a99e60181e48f5c89c3804230439648a1c49114891e9fa021427e86624047b6d00244e408752a3ea00e752a7ebc1151e48c421d2a9c8af7f8e808108fc77fb8c6202648de0bf75091d20e27a64869478fcf7b014222021131f2e3d351d20965419d8a1d3c52cab8e489a1202ca45002f248411f06a6131a895c5e44ce04044c401f2f3e5ab08c409f1f1afa010d8bc85fba8745e44ca678018d44319345e49c26cf84330a75248bb37c5cb2388bc839a39898aa0126200f0b48f4efc461584023968f108ec8add8a192d28e140fbd87626badb5d618638c31c6185b6badb5d65a8b99999999797777777757b162c58a152b56ac58b162082184104208df7befbdf7deebeeeeeeee76ce39e79c73aeb5d65a6bad35c618638c31c6d65a6badb5d66266666666dedddddd554a29a594526a2184104208217cefbdf7de7bafbbbbbbbbdb39e79c73ceb9d65a6badb5d618638c31c6185b6badb5d65a8b999999997977777777d5c2d7aeb1c58bc58b1014f8c86ce1a1f70015f29f8e924fa431f49c51161eff233f424576a0808efc07442483c58e1d29edc8a4b4235510282485c8c95fc119754ca0c49dbc17b4b3a19d0dedcc90a88e4d8c4434a58c269cd8cc90880a8111a594e1500d642093d23af1a494c9444a194ca494b9041434a102b911891c667a0d5962f4f14fe7a5139aa20e7d113913169015228f8fbc3a712f402229a4783120f09153118c88be11259f4e4a994af8c8ab482983c51657c03816ff212422181117cd71c1a890877182c4c95f011ac138094d181128f4499c505185c7d379097d1191924f8733da841ee6f1c63c5e2d36f49b74aa8bcb06e6480542605ca2114a2ef182240a69382387f18093516b380a50fd7428b14423518c119617252f62e18c1c86c5e399c2c525a577a0600f2947e8f1809188b28420042c33243ac2b2441102168ee695d0df7106057d508044c88f298a4cf18305042c4d68278d0924952c546284c6a809470319f8fc68d40931d978913220c8b4097c3e047a61a12c23d027f9874622d6348d8a02c6131a7566c703d3e405a082496c21252fb8e0e51a5b0102162e142bb7564c4205e9094f0221094770e0029218236d240109494422a5c4a29a285148233bbc1a154514ec29e847660a9180434a89eeb08028a4898407584200021616972e947c3a9f8ebf7ca80b9691c86196500f8186f0169f29768b3732f2c48842d18b2c3e0f2385063a4085ccdfa28819e40044235618c9922180610f9b60441c6ae44049ac4026a52f3aa2a7a01f29933229a5a494e44426e81319e8e10140172b29469c788313ec5030000e9c60b4006d408184084b1b5d4045433e451dbaa3e547de797901cd94061f3e4c9079c52205cbe73d2a7084408a517dcf867a401f90c83f209183462fa0506dc402583e5330c21048fe2b9327c2e48928710f109fa20e16ff40c25884165a4748c2800116b18094c250c4115214daa0022be2b1442aa618c108909480c84a2286a434fa805edcd8710522da48a290268c8f874844d278c8a54b961f324644838c0c3a6148090c53c89c2083824a5002124648f00143ec21a5348150c8674a2994560c8164020ba0444a93480422a090011245214a909674280712620d51a843a97b60f4e9c4d41542ac240a693cb0344ca3a2187d3a4a3a328a9798cf92cec895fc67023dd6307f09d340063eefd154cf8b5842000216da79492933899432924829138914fc210e0648a0067850c3082a9c314a30002332704216927001c10712a13028a102182c00001d4a524a091183e04c0009112db2f8b1a98288165918d900d95c31c58f1ff18a0dfdc480422c53a828bcf039df8b233f5c5ce653d004d58f902f3a2f724e112936a18769e22f4dfc25f4454452f08a0141137f1992d182208aa494441d960f74b10981365d541651e853f278e88bfc111091943290a0ff21209ff70234aa1b9113871189dc3341f523040b91c83d3f444ebc484ae90180f002208600081c88421afa8901c4165db08c9ce5470efa210a693cf0071568341a0c8cde23f2fc1213b8787ec97b5c4044448f02281a40071052ca60f1013f68212551e83f9bd08f3a9b1750a87a60fe92153a8aa4945e40200f151b911290470a25a0212098bfc5460ae5d68a0913dac054171717d1f93055714a289994323b9e702293d28e4c4a3b3229edc8a4b42393d20e941d999476645242c9a4a49249c909151415944c8a1b9a682003a0d07f1182098044ae248a9725ef8621ccb9e10129fd171d511c73b0b8c4e1892325b5a10d6da0890d95486c28039456d8b000381291585ce068c3e3f109471989c565e428482b707420a5b4864ab0b88c7c0d405843176ac844528316585cd430627151836271494324585cd2a08594585cd2f08294585cd25045627141031c3668f09c211367f0424a2c2e67f0241697cd19584a69b3f2c61f585cde3823b1b8bca18237569219de4889c5e5d38a199098e10189c5a50c85482c2e5660712943131697328c2025169732ac24161737f690128b8b1b4d6071718393128b8b1b8cc565d34625da7883c5a58d31585c446db0a494c890081617323c2183152c2e6cccc1c61a6c344989c565470cb800c3864ad23819c1bcbc28f4a37ff10fa82362a14e0588c61cc1620b293a008210c8e33f5c5c9e7071d9889e6e3e4f6987b3e9c0f80646247271197d7e494c3121c1628b9852c2628b9840d4118c70444a9946a494610417e0c08531ec90021c14e19923a5808e94524a0eaeb8420a26e1830227482965d810f2326187247b10414a29f344034cfec00709cc61839452e68713a030c4680d74c89152ca2c600e164648a2011058424a29050a6844a18801c2a0864e296544e083146451460e9020869452460c44484003211510a89152da31248a60106260400c4aa494501040061c1621842188418e94128f22985189cc1c5c36318294d28e3924d1831764420882e894528a11bae841040e1b58e087285e967c144b7e115b68444a5b88c3169a9052ea004b077e7e409f8c22161d9908a464092d2442250e2752ca2402095fa4d482941227f9f0718794d29094524da9a634521a8090c31029b59152e222ad64410ce96954141c9173be131a2122a5cc210c5188943284482943474a9941a4949923a58c2052ca0422a50c2052cafc21a58c1f52caf421a50c1f52caec21a58c1e52cae421a50c1e52cadc21a58c1d52cad4213387943272482923474a9938a49481434a9937a49471434a993852cab421a50c1b52cac09152660d2965d49052260d2965d09052e60c2965de482963869432654829e3464a993652ca9021a50c1b1931a49409434a1930a494f9424a192fa494e9424a192e64b49052260b2965b09052e60a992aa494a1424a9929a4945923238594325148498c349e9052c60929659a905286099925a4943923a58c12929052060929658e9052c60829658a408494324348292384943241c80021a5cc0f323d482953464a193252caf020a5cc0e52ca8c21464a191d64709052268c0c1829656c90a141e6494a191948214a2913839526ff89990205bda4b4064c934f6aa4943c69850a2ca5cf7b609a3c05bd78e03d9d100c0c5ee0822f9c3891619224076d4869045360a290c6d3ac5151481ac57742a325296562524a2999d11a91486b9821a5b48507d6e8403ac21202b11861a920212c2e4a3e9d504a53146a01165d7421ea8c7cc3c2423f1d2eba10759102962efe0322d2054b07449d2eaa10164d08f4e3481742585e136a2a5144642ae77c26996229dd37a7b79388b8fc6bdbb6d67bcae8ff2ff9102262b36cd5b982edb7ee21225dcb6cbd7d2c1fef738688dc905605d9928a4d5f5e88285d2faf5eb79762b98d10f1297cd339ca0d3afa74c4baf8bb3e3fb518537e4e2f0f2236ca5551ba10b2547335a777e788cbb3ade98a32581db70b22be76ab32efb5b8e9f6e2f4c24044d5dcf77a3e975b351f20a262ef1f6c0e52c9e6ec3f4429d7f3e9ef4fb97bad9c5ee78738dd65fb7392b10a25f7217663fff5416ffe64758c0f712dda16dbc72a33c6d4da43dcea6acbfaa6628c32eb213a6dcbfd5aec4bb2459b3311e521fe722b997a13eebb7678886e41375f73ad8db56a77885ca1fafada548cdd333bc4a6eb9e7b5d57e565fe9cde5587c8d6f7a7ec97fdfa2b1d625be52d1bb76ea8d4634eefce21d696edb5773965d6688589a17288d33d6ed277e96253be1cf1eb547541f624dbf5681ca2f37a2fa7a25d57538d727a1b0e91b9c9e6bbc54dd91d334eaf7b439ccf3db6a0a3ab95924a717a9b1be242f5a42ff39e3f773e4e2f8b23aaff65fdf3255bea571b62631236dbb78c0d71bd2bb733f86bedc2c45038a2aa732db6d8cde59ad6e5f4f21a62edb96e7ef3f65639b96a88af5a395727379c6dbd717ad54a439c6fcdc6da36756bf533a717a22136cabb4b97d95c6cbe7786487dc2a5e693af2eabd039bdfd4684f031aaeafce7266593727a9d19e2af9ab231d66a75e32f435ce9b2bd37b8fd92323722cbb79559a36ddf2ed6469cd455577432e72665c864883bdfec5ab7b927bd3de7f42eb3111d73d3694bc56388abbdf385dca0a25235e4f44231440a5f3bfb548a29a6c210a93384dd722dc7fb7a727a1b0cb12db6da3eaf4fe182ee0b91a19c4caedaeff7bccd0bb1f67ef36fd6ade57717a273e9a6e49fcae9e3c585f8189b6fbec6fcaa17734e2f6f212e35eb6c8f6e7514f66a21f6bbe7da9f56a5e45394d3ab76b310973ad91c73de5c1b3fc442ece7de928eb529f9bd4b4eefbb42acb497dbd61aa44f655b213697bbeafa2b9e0a76737a5d15625d6af53ebfc978356d9cde4685d8fdbea82fe75da15392d3cba610fd2987f59fda6e72f6727ad71a51d6d7dc5bfebecd75c66ac4c73dd77aa3ab4d25e54a213ec98f61fbc2b78ffde3f42a8e2806260a9152ca72c26772f94f163d857989610114e25c269fa2b236f792465ce6afeb7a59ddab39619e109bcde5946cd5b37d42c8e9edc0bcc4b0c009d131089573d0b95cb590727a615e6258d084b82f656bdeea737adf87402311efdac184d8adedc2eaad7ba111db5c8c76ddfdc7dce4c6e9fd25c445178495d635a99c8a7bc71991fd7af6a4f2bafc41ba762821ae7fad2775524ef6985c2f6a774712627dd5cca69abcea5a0c0609d19da95eef0d72abfeda11e29b0cae924b2a86cdb5678448d754ab7a5366ac2dae9c5ee5b2a308117e2f9b4a35ef75753ea777f35f74b0702e043b88106993b52ef8abbb9b7402039a4388fbfe665bbd987b0eced51109212a591dedf7065dcdc928c8e323a71e8fcf7d3b821097f2b9de98b16570b19b11255db37e9d92cec7e44f4e6f080871677b38db9fddb56bf507f159abd435535b556da1900f22acfb8c39e50e9d3b3b27127a60470fa2ef4a0afde53b6cb5324eef08f42923d6b5be4efa36285dadda848c28ff35ef9770ad3927839cde1088077136c3cae684bcbd9a6cdf4164bc5e95af29275ff13a4e2f28f45f883a63c4d9149b8b42ef2a5f35e6f4b6e0c5880e32d7e7943dbfd68c29d14184ea1f2b26595bd5fd57510e2264ea1dab3d6565cb16548283d8b6b52797848ed7aaea717a479e8e624718d1256bfd54b653e894aa9cdecdb21d378853b953399592cc312fc9e9f57044ab0549100fe7884633ea482249367307185135bb3b29a7d3b59e3f4a3a6ddd0e1b447eeee0a28a42878d49c5e98569f23b6a10e15328a7e45ee98d957b625e6810d75bdbe5687bd78e1fe56d3b66105db337b51863b2fd4e4aa9eff28e2771c9a5dc54542e9475ba5a47646b5553cad473ee8ae52662337bfda5fabdd77c5f6dd3447c59677b4bb20aa154b039bd2fa0506d4132a4e5051402a2718d856834220533117f4ada5056051d13d1c9fa4d2bf4f616949539bd14f4b259d2a1ed1a6bc12e11676bccbf4eb74bbf1fe4f42ee9504bc429d9bdb9e4561236659c5e1923aa44a4fceaa974bb7a55e51e252265dba4aa3c6b2fad6b12711fd3aa56a3d525a34e727a29f5a7c9482232c94f2bfba7b5a9ac8fd30be34b1e7a7cc9330f642211a76b6f9decc9a6fae7a646d39bed9725bf2011d75aefef5b63ec8badc5e965bbdcdecb925f44926c92641e112b33578fd583dcd8f27744942da9aa3c9b7acbb1a9383df2231a8de665c9b36ec4d301641811a58255754ff69aada72455bb45cb8f962b40a38f90c630feb252905944542be584aa5be5b5e66c8a88ccfb9af9a4b22dc5e0f3163ec82422cae758d375b4dd7a4c4d44c4f6fb8a2a7652ca5e927a3287882e594a0ad9ba5afe5e35449cb0b9d79e77be9b741d0b215388b894fbaf50ca26d75b634244d5ad553699d5b5d6557fef07193a227d6c52aa9e9bd2e9376544c80c22ee93fb546b5e5795cf6b2b42668ec8beba51d56adba7e07270b341c80822ae5a6a3db776cec1861536189940c4ba20c32aa14f361b9b0a10f1bd999b4cdbab6fb695bd83cc1f225c5356e7ac5f936c2de687f8d2c1e65831d77835764a4043341a25208f46e336ab04e4594c327d88ceea5752a9d8ddd7a55668341c9173349adeb0bd41860fb1bdf5cab55aa9eb5f5fcc8bcc1ee2fcea6afd469764f255d6420f11f26bb2b13fb5b299bb729b87d88dad0a9bfd3563d5ed1a5ba1d1f4661b1e224b76f2d94ae60dffb946a3d1f466ef107baae7ccb559177baeb1162441341a49371c91733822b742a3f17446318e4892cd0a3276884a51e9585bde75f67b5887b8989bcb58e3da9a93a143fc6e74b62a5ff6ab6f2d7392994364c764bb95ab49c898cdf58824d934c9c821f2b3c9165dca1cacd3b9971f09d1681e91249b988c1cb131e7ae5b4b259bbb9a8a775f1ca262afd6c698ff3d65931b8c27b4e010a9934d362bb87239b918a717c613521a8de63dd2613ca1b7d9cef420f386b8182eb7f2977ad43da5dcc2344724c9a625e386b8b5365cbc9aab6eb216da312d1f8a11813cb345764ccbe6b10934a18781f110138da603e38f48924da68c4c1c9159ed26e9564a2bfba738bd55683455b421f29a53b245ebfb5d5f17a797fe08f4596c88efd9b9591f95f01b9bcbe9ddf086e2ec889c0a5e293270c4f6d6d72ff3f9cd8dbd4f47c94bb52ffea1d111188f11e8603ca1b586b81e6f55ec4de670baa4cead8c1a225bbb2f97b9f7783d6d6988b46753a7cf5d35558f865821b37ced5e17fdca4fa3716eb3309933c4b6ade55a52fd9250ade7f4fe17ff312d1035159937e2f3b61a5d90f25bfc6b727a5d0b92202d455a900c69b942b1934f67b44b24c9668a8c196285bf1aae6fe68ddb8b09cde9ee0504f250d11e91249b28326588fbb329e6cc9672ed2d854cc8b81179b67cd257bd6eccd76427cab411a7826acab976bbb9379f46a351bb59c56ab790214364eaca1b2fc9267753fad0c8b011673ba8dc333829ec7faeb1203386589929a8e6634dbe45256b34f397b4cc938c18a252eed5b37f90d54fb6c2101b946abd94eb39a9dc02437cb2d19dbdffd6739297488b5c2df2c0bc745a0c325f886f3286cd31dd673c65c60b91ba74fbfe21636ef69e33f2228c337218e664c46abb1059ab8e39c85cb2b60c32a717543f1a8d46b3819bcd1c21c385485b936d19f394b02af51a8d47a3715b88ef962aaa9abbafccda6921d2f6ebbdda72d7563ecab2107b36f65ef4cd6dda9cb110fdb9a2b2773ef7a99aba42f4eaa4b7945335f8dc9415a2ab7567c9d03df7ab7a15a2abd25f756d6ecfe7ba351a271e0a793b2249365d64a8109fb9c51e6bcbd0d5be3a85a860af5b6d76edc51464e6d688bdbe4de75eb739e87639bd4cfeb342cf9921ff23a1d191dd0e8d446a44d9163b9ebf5673eebd3848460a91c10529376fbd4cbaaace8942844a5656cd7533582ba44da810251f37a2d168342218d03691241b9a81426467ec20ab352954939bd33b0a6d60268dc8aede316f2e573de55683fd84e86ed6f9935b419e3ed78646222744391b6c3565a515ca7d6ae39cc3a20e3967b2239926c4dabfae58652f199d4e8140d28a0c13225c95ee640e323759fbd188bc6c2af8f6a59cd355d8f1a8759925c4c9bc9ee4870f9d3a36f98ce8e87c48fd752fd656c316334a88aeba2133f66885ea61838919ed762609f1b13a55732fa9bb6ad3899010d94f6e4db509e952fc263b426492f2ceffaebbaa6d5d4688cfa9b6aab7d7fed58ab908b1c9cab0d6caf499fa39371bc71922c4e9dbfdb2b2d654b6c938bd3ff2f810e2bfe5d56ab5d5ef49b5428852aaeaaaab70f6a3aacd20445f6f5563a74dcd7eec39bda0d1a7b3612e66f3a290c3b0651933e284f0e15b9017548fd1e60542944e51c7cee77406df3b51670874c9fc203a59dbaa0dbac76afb7a191fc4a5cdf9544fe77390d9727adbe85fa607d131095bd287eccdea97d3eb5419b1baa2b2be64afca5dd7ef818941a23264c45ead41569b25948c970791565fa896b5b75faa36b383f81c7bd553ae6deee7353346541342a75e6db3d6f361468ce80ad60a6773704dda749920a383c818adac9f6a48f7b7524e2ff57ca7b623bb0f04991cc4752c7f324aa9b735274f41bd8846230afd7344926c946470109d74f3b5e7d6ad55dd398cb84bc195cde8c3d712f20d22635fdfbe7e776b255748068ce89e5176d5d73ebf6e10543f4266e7e345349a2692645333368852aa878d3e5d0fbfd792991ac4b97a51f5aab2acee5e23926463244383d895eef467ba702974e87665661027c3678ea162bcdaaf5b8e48928d0a324fa2ebb7a4537f4f4ec71ad5683c9e9fca1149b241810cd6d2c4b9f0f994ce1f8515aaddc4202eda5ef387fb8b317cc7e9d08f84fcd068e877604013889116b5a111cc82419cb271abbb53ed82724dd114b01149b239c10b6255ec656390b67437b731212e88b32733e8eb0d1d9c8bbf88cc61656cada91ca45d21a7973accd23889d3ffddfef2f6e995813489fc2e697b6cb2664aede2f47a3ca4e4479fce863a0c3f2651b59bac41f8d2eb37e738bdccc56c462fb597c4f7efaeb14a9bc2b6ae727a6967f3304e46fd9942a371f271246e1149b2893151d266f79c9bb967465dafd0086605196d7c88a26a5bbdb6da85cb669b1fd0c6e3f1097f7eb2f800714f04035a2ea1d8abe163e7f2d7f4b77c6d0be23bb397bd6e75f77b70ed28068b378a79d94011c044e68a5676b4d6b7bd4d779b024556dc9339c79e52d674ad6dfc894ef93d2f39a5ac756de3dd9748f7bde7aab37392bac93cf169ff7b75fe9eb5650c055e44559be794bb70f6d2f516742c8893327e0acacabaf9b9065f27bafae67270d16f4aaeba84ed28e665039b13e97af4617b4e5fceb90b3e25d15dbf75f47b3af96a2b4e2f05b9d4e8bbdef9aa50c2f9db9082e0c7caea49585936fbbbf75534bea59851b68c3a9f8f564eefe219d9f4b6166bc6dcab8f77657c4ceb779db54daf759fd30b030a51053d2e77d557fdcacae036737a3d302f9d0dfd9073446fbb8bc8b2d55a9bbd67f7870c3462fec026324ab9b55ef8abf957e3f4566005f11b550e3aea0b615d70727ae72fd97044bd8e8bb87ac90a9fce551b7a7b9cdeff803c73037a018560961b91241b1715f848417c471d53281d5cb79e338f2049948f41c80bbad964654ca220aefa6df9bf6f6e311acdd34d55293fa6d1ac19299b88cd65b73beacfea928a3511995f954ab5e65c73ee2a135135b6e032b6faf92de54348c14464ab3d744bb1275bae534ebbd00826e51271cdc992b205df5cec1d5b22bea64d4909971955df2ea51291bec74cf6fbef9bb5ab66490a25e2624e2948fd399e4474cd2db7156c96f029654d48914494f051c74faa57ece45291886c4ec7d249f6769fa909893857cf2a15856f3d22cab67552c9103e37e8de1171f79fead6e892b52dc81a112165eab5ff727dce6b1b21851171695dabe65b15c2570b8fb845c47d5ed7d295aaba379d9f91a288d84fb9b65aad5ffb715b4eaf5a989444c496ed3583eb9f21e3475310111f5dac52569f840e76ed43c4e6f21b9ccd1733e6ae868813aef6b33af40abf77717addce5fb280a4142272a3737dcb6fccd15e21f4f3a3269186914288381faab6fdd4e43727ddcd8f7c978e489964b499ad628ac9faa0911a44ac4deb2bf60fae5a9b37180a7a71a34f470b251d2ae6880b7bf6ae5e72256552895cc9e62d4c93a7a097c744926c84a40822b67daeda62b672252bcf4634ea28e9d0cd8b3a4c461dc9dcbd7989f9a82b5202115dae7aefb49f5c47f701119bcda7acae648fbeeadcc908fe214e381b5dcee884b2f2ceb752a4f82132f7743957a59ea4fce8cbc3748cf4212ed96a36adde76be5fd539473a850fd1fd55f9e4632f17733512817e0cf911359af7c0bc74441b95b287f8b0ce379954ecd9db7e4e03d1439c3b1b5c5c1956c7581e62fde94b49bacb3dbf37d9c24364add16dd5d8af5765abef0ef1a1838af5efebf64b293bc46faf7949baff8b4e39eb10db27a44f4a596137e84e87c8ceedc2d793a9da907e4b99435c8a3ab7e06e572827ab95435c863de1f373dcd6af3afa17c911f96df3db29597b6bc2c569c752e2101bffba7da7e43f760ec221427f94bbbac55a56769ff28648a764ebd0edf25eb4991ba2aff3ba53752e39d96b9b5fd2118562e6873a8e58e16a8c527f8ccef715b621ce97b449e84b35aefbce86486165c68a5db14be8646344926c489002476406216cb91463e5d6726b883e1bb6f736e1376ff8020a01990f7344a30123450d912a579f73e50d364f2539fdc9823766f301ad970e4c43ac75c2f7e473c9706dab6d470f52d01057e35d6b413897943ed5ba9433445877fd62edd8a79b8f6ed6be9437a274ebdf18cee64e6086e8bad255947a7f65cc1e08296588bf5b992946ddd147ebe3f4ba115f6de9fc18ebc95a4b98d2465cad7d35a6766e934c2e19a294def3999f92cbab4961639735d14dd56efb35b9d8bf065dca1822d3f97359bdabb6f4590cf16bedae70cdf56ee7eb9430c4d66b2ab65dddf29474717a3f1d100bd84804faa1b653c010b7baf54557e3ca7452ea7690f285e8aadab99c2ddfc55a4bd0dc883add8224884613d2688e88d47a21fe6aecd87d53cca9c67c484a172273cdbdb44dc7d66caaf5cb9257295c88cefc985aa68be19c6b19d99d21de942dc4e6b069d327e76bbf9e5c2dc4e9749ff9640bbaf2e938bdbc59884afa4aca9529a5efe71321050bd1dd99f7f6c376f6d738bd4a48b9425cb432f77a5765ab390a39bdcb2d48b1425c8bcd7df2a9f9abe472a3cf37664724a50ad1b9ad2c979937337dbb5488b4b95eb5d656f5f939650ab1c9291b7c2c5585bcf3a914a4ac11ddc3b7edd89bbe50ce4f07b6200982448d289f72d45db56ada7c95a4482156b972b99febda3dcbc5e9edb82d52a2109d33d9ab9573ef6d41b73e5a2806420a14627d67b43155fb2948d7833c484923362af96bcb6f06d9734a539e10574da9169492217deaf5dbd820c509516df3e928d7b58c729d64a434213ac59c9b3bc5bf8c4a958414264449e563ba93d2f76570a111ebbf6e4fcec9f56bfd5e429490d79cb251868cfee4c78ca49c11d55296ced4d6bab856f9a325aadd14214509d1f715ab3f9fe1d2689090928458bb5b29e7d6d627ed1424c4fafea59b6fd1ba54b9e26cfe8b8e08b62009b26142ca1122e4f6103efb76ab5ec9d1e797ec1a21ae9edfdc7cbfdaf3fe65e246349a46a41421eeba4fb6587ffdf5a6332d40a38f90222944887535b71ac257ab7c8dae9421c4f5ddad1843b8dc74ea95db1421c4f59e5ccd1cfdf7facf71da35fe5164480bdb424a10a25aabc2a69e79ed5a7644b51951d1a7ec964a359d2e09538010556d0cb285deb4b1271fa7f797805e3ec47e10eb3af9edcdaaa4cfe63cc507b1be65fdcf15accfcd6d9c388c5b514a0fe2738fd973debcb9dadee2162441b0d82266d15264480b3791249b2f52ca88dd154ec67e3e6d533999424664cfbd194ad79442b69dc283b81c75cd18aed69e7f7d5d4752761019367426d7ceba52bdca6924236641ca18d16b5367f2db49e76e55f7b9989322467ccd6485533aa78cee6abc5ca4e820d2c7533de50b5fce9593d3fb9d664f4a0ea23fd85b9fbe6dfb6a4ed0dc2c16410a0e22e3cab43a37056575fb6c7fb41c716144065f3df79e6f754a4a4eb9415470d5a673d506c1886bb964ef665baa32e66eb9141b44fa76ab54f3954ba94164b52d548b56ba5268102764da134a36e982fb3a65065149ea146df5d8dce71b5167ed1f4132a4a58846235ade9427517d73fa5d61f37aad314eefb3014a1d91e57bd32d7be3b5d81d0d5036115f4f4799b7c55349d94aa369fd82a289c80bbee66be97f2f63de4c1a28998892cee76e17b26ecb3c1e9fac0549102398880f32091d6b55c985fb8dd30bda384f11e166817289c8ea737479390ad9aab47906289688cfbf6bbffaac39e65ecc171ac12c2728958892d1b65ecbe6d84da7927e3a9577035379a15022c256b532051fbb87eddf24e2aafeb692d9728b1d5349c445fbb9c9fab8b2b5aeb62ea044222ea7ceac1fcec5d3ed182890888cc2e5dfb7d3c17f6f39bdf313131a6d648c68031a7d3acd2d48827c401d911018a03c222e94eb2de6d6bd67efe588e8e8f2ed9daebd4aabfb4644c8aef919ad70b6663a39bd6f6b80c28838db4bd6f3cd97ed1afe2222758ca9c596ad92b0b622e2fa95ecb52dae2de16c89886f2d3f6dea8a515a95444464b5eb3a734bee2f49fb1071c97dc79eb7942c5b1b22369fddde944ae6646df21fde7e014a2122dd7dfddd6dc166f649882897aeb79a6b5beb728ce9888f25af85735fae938a0711bfc2b5cba183dddb3a0f2873c4d9b839848d41e5adcecd5a41c4e55aab6ab65cb9ae9033f9d0e64731b2131a893a14f257a603944044a9de15e46df3d1daea02225277d80bd6efe6ec711bc5c08c62b2f8439c6dd6b5eeff5c4fbad80f717d2fa4bf5cbe758aba3ec4e568ab5d2985d29f31e74384ad9d4976aaba658f2dde02ca1e22d35dc5bd9e7abfa446c3bb8824d9ec9803450fd1d1b994ab6ea975b2d7cc43e4396133d94e5d31a4bd2e28788892956b7231dbb9eaaacb5940b9437cdc50eea474fa5ab3c2cfc380ec1097eccaea52afb4b1765e87c8bc1ef2cbc7e810592e4f589b49e9aeba7a0ce35854e116c65f366ae7105df943b9ac35e6f5d52a87e8eb9b6d758f1d6bed2d4eef0644dd111439a2fbc7f8b5a58d69bb969c5e26ff79edb938c476486775b69c9ffb51e7d3d98068734b24c9c6080a1c22ec9d922a6eacd633766ca5407943645f1f9c75d2e6f56e76439cb5a95c399dc3b6d8c711f9e9944cb13a57ebe68fd3ab04e4d974607cb3692249361a9436c439e96b4fbeeab531065f080a1ba254ce4d6ea5d85beae53a386263cc1ca40d52d5586dcfe9edcd9c81b28608652f3fca0edbea3a991aa273670cd6876f275d956d9c84466a89809286b856aba658e3d56f2774328d6896845eb4ec641601050d713e7b76ea2d459db1a49cde1707e32feb0cb16e93ad329674d97b2415a2694112a44549a77e40f361441f211a8d46a3d1f0da1d66a0bc1195439e2dddfb73ffae2d34437cb513aaafacbddadd24a7f7fdc8473158b87e8fec28f9c4d4e79c1628658850c15d5cbbf9dcd93f3f286ec45a9953abd97c6cbdfa1eb72009d2d282d846a4d4d1c74b1d746de7626488deb065af75bd8f2ac96cc46eb239aaa862af9dca86a48924d97c50c610995aae95e7e2953b792d4311437cb07fc9ba9acfe6645b4e2f6f440943642d9bfef6be251d84bd1c830286387739859455299fcbb61c1050be10f7ad37cacf9d2b57f89cde508ce8f3bb8ce285d8e46cd9be3de8ac756d1850a80a8d060614a234e431413cde85b8a453ea98b3566d9dac9cded12b59f6f85a24285c88fc9a6b0ad552ef9df96a285b888c3e33f50db951556b03d118916203450b91ee5bbefad1e618550eff6b16e252b8a45cfe98c9d6d68f01050bb1d5b6b6f62d5817e387ac0c285788d351f6163b09195c4a6eef1950ac10656b2ad73553942909bb0af1416f3f1b32f7e8775b425a7e88dea201850ad1fd94d52b55cd1f656e170e942944b62d575325a56bfd969b1950d688ce35c3f9d69475d529e9c7491310151a0dfd263f5a288c6301e32f6ead1ad151f9fca774b249b7265d32a048217a73f6d63e0a9d7657478942745c9574a5d8abdc5c3da757a319bd48a3f90f8da446039fa040214eae4f27547436a7b78546302869c4862cfd2db84ed2f5da6ba111ccda02e509b13e6eafa8af2ad973fe765d460d1427444a257dcb9c5696ae5c732237ccf43f5a3412509a10d7a56352bd744aaa66c9e97d2d4882b488461d8fc77fb025284c88ae5ec2cacfa09c8d8d5ef421de8e879068341a0d0a1a911d5b6fefa9d7ca2d56284b888beeba55575dea8c48df6b4c1763d02557b70a450951ce59e9eab9fa41f9cd73379485c73ba39017d168605e1e2509b155658ccaded73b2b93a31620465a7ce455c0d45d1424c45fe975aeaa4da757b89c5e2f26c823379f0e64942344f7244ff8a8ec86ebdc3b11a018214e491d64febaf15ab63ac8c7785ca3d1b44c0f508a10d77dd3057b3173e90e727a3720da2a0a11e2ebae4cf5cef6071bdb2144afcc1dcbe787f58d68d418284288ea2b6cab1cbf67c8ee39bda0d1e66111232dca48cb8f1655829622435a341a0fcc4bc76d7b4940094264cb31aeff58bb5f4599924f67e4a198918bd89a11a584fccd1aebdadfebea8633ea30719b040508713293cbaeb67df5a92939bd9bffbae11fc4569d55d66a9d754a187a1b042e1f44d7a45af956b17cfdde620b92212d2f4be2e3256a517a101b74d6fbef5de536d96544c6ba757b6dc8242fe96444289d7cd6fce5ac0bd7f1204a0677dbdbbeea6b39792f361b187f59560be32f2b041a39dca0ec20724f2adb7fcbd6e83be6f4ce8ec8e55aa2768c58dddf315692cea5f305411123b6f7b7ebdf987475beb7d9a0e8202ee624a32f1795f4f1741a40c9415c4c55a3737aa5dc1c9b38885441e5eddfa4df9a766f874630ab8312467474edcba91473cf242fdcb744926caa40b941ac4af9c265599fb3f37bbd964892cd0750c088cd3d5d96ecfe4cf20644771533e155cb6b8308eb5b38e75c5dbbada79cdec50ed4d9c0881a91249b10a0d420ba64ee296fca199d6f72fb803c3f341a894283c8e84bef05fd79d3d76c359a364299419c6cdbb7d1c9dafafa8746229427d1a9e2065937666e35d69cdea7319e0fc1741d51d1f5a6a44ed57bb255c504f443a3d16836117d3ac814af7b4cb16faed13c054d18907bb2431311b2fdb56cb9da4c51a79988f21d5c5f1d5bb2beb6e828f44b3011db3aefac527e6572a9ee19ecb8449cdd3b9f72f5b9eb5cf208acc10e4bc4e7dcd2b6ceccb5a7deeacdb60c0d76542232cab8ee848dfdb1fa1e25e243371f54ef687f57e99388edab2b0a555b58217c4944d724fdb658a394db6b2d12b1d58250eeb6f5e0fcc690884af5e20a9dbf41e7a0e3203b1e11572eaadc5b269fc2c55ca3e16287236275a60d7fe9a44c2aba3b1a11b7bef37e2ae5325dbb781911e16af6cbeedfdaf74e9367ffe970a663d18b884ff973d217844d390d5988fdf0db5b9b4be56cf6b010a7dc754c3db92a64576baf102bad73b6a76a29f5b4a91562e527e1be934fae07371fd002f964a1d188bc008138bc0b5fbbc616ef8f16155b8a0c6979438f2a44caf8c1574ac94785d8eb9e3fb30afbc165203da610bfaa7dadb566cb9862e2a1cd7f6dbb466c55977a0e5bb9858ff55023cab7eb6d59c225b78940306b91d0430ab19de207176c2c67ab5346fa1f259d23bc368d1e518855b5b5727f99195327a110fda9dad857b2c9d6aa0913e3050834a405c990377aa4119df9d225975bf62a75c511c5c0c027443ad9b2b9af4ab51e36e665a38713e23396ecbfaa5d5ee5ab1e4d88bf6a2ff79e733fa752dc8309b1be06697bc7283fe9aaf74023f27a94b656bd985c923da7573516f45842945229567d3e9c3b5db6a0c719d1e9f2b9969413ba379546a384f8945f5bae0dee375f8ad32f3d92105f85ccbd37e92ac75e4ef7c9e287c73345cb8f96961f2da3263ffa807eb4fc6879f991c80953fbcd093d90109dc19eb3a55ce7675ee5e87184f8b3e1e4fa4f41d596f221f43042e4c76aca571b75bb73bb4711a25a6b574d281b2faa8810977df3e5ae9621cf0dfd382f158b87109dab6f79e984ff18738cd3db3d8410e5626c4ef8ac27cbfa2c063d8210e7ae09e153c6afd6d6a819f197a794b4b99ad4196b408853be67affe62e8562fb8e9f183e892c2e592525964484b1c3d7c1097db84ed186b45e5ebda83c85aed5c937d3928db6cd8a38cd8be55b9b7d2c15e8d36a779c54055460f32225cb5b1c6aa9bb249e9ac070fa273ddf69c5c2a55335f4eef73418f1d44da2a75af59f6fbcafd18d4638cb868f7fc56fdbd7b86134910277f0547e456fc6807470f31629b7529a4bd8fca76b4870ea2cbc7b599eb359994be7ae420b2ed395b5d8cf9b9eafd01c2db030711beafb757d99433f7fc805e5e407311d168349a5d27691349b209f50823aed5d62eabec94ff73b3c70de27c2b6555af52afbe9c5a41451540ae68f9d162450b92212d5454017b8011a7abfbfae774d0c1e67cb31cec618358a7e30aeb9cbfea64cc717a456bdd0e7ad4809755173d6810d5725d359937a570f97a3d66105fa38b9d3bea6ccdd6e472d1e349fcf65e157dab2996f4bd3ae233d60d325fdc5eb2959b880e97a48cdd1dba275b6a22bec9dadc7fafaa7cf3a94c44e5aa3e548bed6a2765c5445cb2d17f0cabf24bc446793efd9db349a7dc5a22ca7fd9d37553ef26645989c8b8d2d7ad2a4b4a44b9d8e73ef86dbec9a89b44a4af5e7bf62a9bab573e4944d58ecde51ccfa74fca1f4e4522fe2ae996fcf9eae25e098948979a144e5eb2b9da6e3ec299b28395c9f6091d11a7725eb73ae86a6d13c246c4ea947b4a3ef8950723226d4ffd35f5e862ed6e717a5f6893cdda223c16116795cbb4dddaf6a672c8e965eb792822aeec465bf67c0b1bb284e19188c8a843b6b8abb3f5c6a0163c1011dbe7cb7ecf77e9c3fde67188287f17fb57b85275ddb00a781822523adfd54ae5e339173bbb804721e27cfd5dddfb252bdb7f31efc5f0f2204484aedc82b57d7bc8943e1e74c47d4da7a2ebcdeff5d87b9b31780c22c2379b36499f29f94be51cf1c15dd2a9c5b5b17a5b79c04310f19fac4a4aef35dd2bc60211d7e57bf3ac2fdb5a3701117b4a86eed7a15a6745f90fd121946b4ee5cab56eb3fd107db977e575b296fea8b7fc68b9028f3e44276765e9d6ad4a1de471e24578f021b6e5ba8d36279dcff698093cf610e952ff8b9b74e7e0e4e5a187c86ead557b49f76fbf95469387089d63ffdc2dc9788874aa65cde54a08fb9bad2ff0b8438494769b50b66557ca951de2bae9d3eb5cfc935bab7588503a960e32847488f0b9a6ea7256a9a450bab53d87f8daaeacb557a572884e399673adaa786de39623f6ae746ed7b93ab325e310e1acf4ed6477b0199d0b87287dc23721945339968ddf1097b34665b786ca29764f083cdc10e1baa4b41da3be8a3af7028f381acf95cbf60d3cda10614357e5acac1f1be2ab6fb6279df4a7d0956b34bc8ce1884dc266059f33a68e2ab686586153faadc185522eaa44eef90183c0430d11beddc61eaf9c6ad7526988739faeaa987dd1109f3ecadf28742a199d4b073cce105f49b8fec1569d53acca2cf07823b667d5d592adb555a1646688fdbcbdfe2a79b27ea69a19f0284374ec4f36c9bc7f1db36545cb8f96202d3f5a80fc68a9a2e5c70e78b811d9faa5552df99a9bab6d23326bdf3615f5ca6ef94351a3f1d07778902152c8cfbf9cdb29d7a2cd466437673bb7ca5aa9c6acd168349be55d028f31440725f3664da182cd2a258387182254db8d3677751553eaa7a8f3c2a6c0230cd19d71eb6eb5b96bd62418a27c731dac6fb9b3276983018f2f4487bf6b2b65942b9cab7a21bafae65c8d17e437bdd52ec4eaaaab06d79f7fdbb64d7870217ae5a9be29b7be85a8762aa73f9d6c0bb2467fc0430bf159cfc6982af7caf9ec2c446eb8bc6755ad6765ce0f0b91f6322a174f76870ed51a3cae10ebacffea5ac6fdf35daa3478582156e64ac2f69ef3d794374c028f2ac45f7257b3ead69f948e71c0830a91d1a5ba7295f44d212ef57eb1f27da74ded1ab1d5fa5cfd59a5ab061faa11fd574a051d52f59efbd98264484b1378482132f796ac4b5157518892eece399faf37a78d72810714e2646c555f878e32c55aa7117f56d914e4e58f068f27c477cba67c4edf39976e8994b807884623ea010f27c46f5f38abeb269b102784acfdf65a53f55b0e9ac1830971ee540f7fb2ca0fe55344926c64c0038d38196dccf9e46ffb52b125c4f96457f7cb0c1d6de567449fae9d5c39616d4f7fd1808712e2abf69a51081bcbaadc87c12309b1569e8afa944ab1e7d622215635e7ce23c4eecae032b3a3abe9a44688fb7849f7e6da95b3ad22c4c7af165def5e254284f3695b92697f6d4e411e4388bcde35acae9982cfff09214a06a9737fd8ad256c180429ab72072583af9911e553eb19653beb6c8d19087131f9fa3987fbbcd6277f1027a5724205ab6c76b8a00fe2d67eb756adae8978f420ced9582ec5e85c3cca88bcdeefd9eb7ea5a082eb0c3cc888aa3da878a5ac542ec6240f623f5b0f57e3266bdba57610657db5beca4adb79b37fc2638c3877ed940a72cbc9735631e2fbb372a6e46c5ab94a1d4439996ac91863e6a9dee520f662ed1adb3adfdb9acd0307b121534b25dbf54ed1ad2d3fd6c0238cb86a79bb1b53553af6bf5de07183489bbf6e50beca98b9d99b8562f00023bed7ed683bd758be6f6b83a8d6a3efd5adaed8f79a0a0c1e35888d1965af94c9f7adb2a2416cc90de172b3992d5d9579cc2052f6aa68bf4a591c796272c0e349acab6b73489fbf7a15b23554ea88502d7bff68938ac1e5dc26a282724dfa8db2b9dfdf9a88b49d7b874d99e39552c39988f23527a9b3d75db52ad776b3707b102a9888f33909a974ebde5b553d8d0646d444926c98a85c222afad2355f8aca591faf07868a25a24bde55eba3eb4bd6b92a115dfa72edd87795abcfdc8b0a256263f85e4de98af6635d2711997c4fd6c6d64aea0cab46b3bb592ca848224a2aab6487abf97cb66f77b31c8948ab6a0cbad3ba75d1e673c1a00289b89c2d53f0779d31a6b5a141e51191dd52524ad8d6bf53da36bbb60d15474406297cda7cbe462975dfddecc8a941a51191b1a394d595ee27846e6df6b94185115151f6dacb9fecb7b8a92c22ca596bfd06d56f3beca7d168341a0def6697eba0a28808d7abdb609370ba82df6054121195925455e6ecdb356e6e8b88c82a3fd5de3fb39c2deb2162bb74a556c16d3dd932b78688b0212ff7667b3f1f5bac10d1759b2d9d7aef93ef1122323827d3c69a9dc239978da1424754db207577bd66af661f446cae35b3945e9d397e3b476496d03137f5b52d5a190a224ab952a9359b4dc5abd6be40c4753debcf75de13b272aa0122d259e132a7ef50cd7d8ddf1fa264be6beed7f6ab77513fc45fa91c75f94a42d5efad3e44bab8c16db3b54a59558f0f71bd3aab74df9cfa97cef610e97255d2ca1a6cd5d1c67a886c2ec98bbf325fd9acf3101b7594b5fad7beadc7561154f0105bc9071b9dcee1828ce11d6285ff1e6d0ad927bf5c6687b88d56d75e2137b8dec37e824a1d225deb7965d76e9fdfeb2d4e43850e9177edb675737633756be710296ddea5567b94e952cc95a1228748ab744afea2dbaacf7f72c4674e4956f7b7072a71880c3e496175a91e74489d46a3d1283354e01065b7dfad4b72cf6f5bdf1055b7275d375f95b1b9acd1bc40c50d71aaa51acf75ede388b02dfae074eed71dbed986a8dc3f76aae95374317ded062a6c88f531a614cb4a5783701f1cd1e7b753ff987cc7acc235c46fd9d472eaeda4e2666a88eee472b5f5ec469d2e5843ec0941250dd1b59b943ef7fb94b1f5e01154d0109f84dcdcffb29f212ef95d1d93df14a4effe474be89db866b36f44ea6f42a7d8ba72febefe68f9e1cc10f7294ba7ce554124a89421d6555d7b7fd2c1f6702d37e27355c1caf4dd7ad9bf54b4fc6899a2a5c8901617a3d24654cf4f5751c5efc8107dbeb58fcd37bdb1c7e0365161233ef6ea9fdbf19aee9d8e21d66df0b15ae69ca95faad1b018e292ac327daf97c19ecb351a8d66771141250cb1fb9d7cfe2ba76cdb2418623fb9cbef5352a966ad1acd66e72f592da87c21bee7132a970e2adae6a347341a8d66b36e611954bc105b5d7541e71eb2fa7abed685f8bdda755b5c9db24657850bd1155d122eb5de8eb6bb2dc42561b797532dfcf9cead16a2824ed9bb29573aaa9cc540250bd1c1ea9c7b9057b174d465a08285f89e7bb4c2b92885cbd4f140e50a71dbac925147d9367dce8f0c152bc43767f76bb54cbe77935588ca9b636cca36e9bff7eb0c152ac45757ae7cdfeedd8deb8b9c53c489ca14623bf620abfe787e55f569343a505923ca27a95b54d525eb7453aa11a9a2ed70ca49a5ac8e321529c4079b7b93aee4d6ce59bd4d0741250ad16d759e4f27fbc3ada3b96c850a14a2af62abf59b6cb982ded2888bdfbee996db27a9af577942fcda533a9b8abf4a55978a13a2723a79eec386eeb5d54d88dea073ed29e81e4faf8f696fd6052a4c8893b5eafc5f377f369db5fc68d98d1154d088adcaf7164ab95cafb57309b1e962cc7756eadea4afb3d91d81ca19917bbeb6147bf0bd7eb538bdabd1885809712dd694b5ba8f3dba6b337a25bda30f82039524c4d914eb7edbfffec1295590101fbbfadcbdeea72a7c4ae508b17d7defbdc554ab5e48154fa16284e8d5ff15fb844e9b1d1621d2c65335f5985db57d2b72f25788a14284f8ab16fbe7bf553eca9023722b5a7eb410694132a4e50b2a43884bbe7fee9cae6ab92855114274ba8caa864bb9f1f61b8140465a7eb4b4fc689143250891bdbea9dceb5b295b6b2a6644f6559b7bac3e08273339041520c4e66ddd55f826e53a2b844de507d1eb5b0c9f5c6fae65ed7968d424b6fc68f9d1e2f1f88f961f2d53b42019d2a28546d3760c2a3e88bdad3a86ad41d81c556ba9a0d2832895820e1f6dc5dfcbfaa5c3116996289644a58ce8ccab5e33f46eff98359a1750a86a34eff1f88fe7d8a042469c6e9d62eeaeee7ccd312f6f1483c5074853e141ecba2095ee16acec5c7d232f3f12323b0e3e51d9416cb5b65cd9f62d5776abbd5019233ea4ef1bbfa5e02eb70e43458cf89a297b5eb231e6828a0ee2ce459d7c542af798acab9283a8167c75ddbe355b7beb7da08283c826e4b58cf6f2da37151454c288952e7fb765fe9e5fb28140546e102183d0b59efbcdbea14443058c081d55bd9cff5caed6862a36886dba9bebdcabadb05f2927a8d420d245ff675b3d556810259b55a9c626ab9459be19c4eaf6db3bcbb9b6196b4132a445a3d9dd2caba1f2244ed91874cabdead5b722ecd5112babf3039713a844af0a25692410a3208861100020112bda0000f312003020241c8f07c411a9681ad716140005506a667c382c1e15c6c2b160200ac2380ac2300a82308a8118628c519032a8740008e66e0cc000dd9a4de847ac86f230180c769afe18d82a69e58dc8fbdea3e4bcfc1c5c277c56ee0c79e8546ba86399a9ba4b019934131839d15a19e3765c0be4032c0672069dd06e175c5ae76a5ff8928beed1b305b434a043fd6136550bbb4981ee63aad853fb3dc4551a2b53eca098460e47db55cbe6c70f96d03c4eea9f692aa54e5ce4ab0d139fa943501f706cf400573aad46f7c0e23d516cf329dad564816ea71de8e2616b15171a90292a5c8c78d23f748ce8f84cf5d9ab800ceea2772e62fb6076ffa1978086c32eb3d4a7bebee8a7869c32ecfcc1c045d45f4d0391ddcc7e6cfcf219b5601decaf9172f59d8f3f7e029eeb8c50dc450d2c48773efc60ccfb37d50a808506880b48bd2f3f77b6d47d3e309dd9ba4417ad8d2e0484c099b0e1338e3cd3a1079e1e3c52e01bed0172ebfc994d86bf59adc715ff6497249dc7d54401cad30dbb3f3304fbad21034f8fe19548406ab33215699fc83dbc12c3abb8a8c207b076f692f2d0a510962534035245875a6d5c539d6fccbc9aae21f35bdcaf3009877338c5c2e1d8729f36eecd66df8ac4e29e725a6481744381cc4b70a48213e15cee62af50dd06360530c0b412729fc5ea4b63462d7bb357f68ae456406128ddc6d698b3941f25db6dea3cd2c897a314765c3eb26e325f633ae9f473b539f8e44a7252dbd0125c9ad71d285fd5e6a6a980a8b936d006d526f7f824902ea7f670a9d433db06fac1f588e73fd184ed1cb78c884c07cc33c6eef9f3d7b6a0ce6f2e573830d9dd64b215b20b42521cad6a1344add58941d6d83d8f371ccf41b6977caa4c299d58a054870cebac4f49ba5fd6bc5bbd5467bec539693e811bd395cbd618a1649daf52df9ab52a4428e658b7057896761405c7f7cae406ee3000e49259ca7f21120b84316645696921f68faad58c37661e63742730ca5678746c5a08c15296b9b7f80e6a25ad14c4d7f7a861e80820028ddb0d7cd130df4e7316f674d941e4b021bd848c4e4f0fb3e9dd331cd2786c8a35467ac64eabae22eb5d647e5dd206c0bcc8d47a2f5101481754992fc25ca64f1042f2289e4bb3603ad19fe644c58356bf1ea2afaa7d9dddcd4a037c6711e9c7844763ff7c46662e71516e474fd73c2f50d3fb1c418c660e4d35ed520cec7914b4b16f5318f6b44b471ef510a5b7bc953bbc646fa5ce203be656c2ec1a20a625a381a24855d3567f9c354c9e5e9d61696f2a81ea5e32a3ebe843f5d9d2e676f47acfec516efbb7af91fc69f3a3e1179bd4a3b4f248d0a240201bd4a62e3449f4ad86e27e67250336c09d0382680e639b6a5a2ef5b0a24d0f8912d507096433ef7d9a405580b26b07c77b505e75a789887c434fce1ec208c6fca082c06cfc19c356e0276a955b9e442b64030562947c2f184d5e623a0258fc34dfa050984370921450954ec2c58b3f8576623f9a1b46f0c8dae9d127a2ecfa333ade2b01200f759624f5434e8547211fb162e562bcc440fe45c16b3ae190c40787f3994b663dba4884fe04cf0f4c3e3426f11e311679a46cfa38aae22b043069b4aa6bd83e6295b8ff136e2ffa66769042758c0075c0a8975691c8b18a851fb331a7a5ec14154645cc63f080b26ee6f11091e6364d0bd1835a4b3520c7dbb5938170d30389a0682568d16008fd540564a27dee21f66d33731c93007340df653c8c2535dab80907869adf77d2f423b1569b1db5376a9a4419399955715eef45004659bca6198ed2d50623a705dd07c920bff41a0c648276639506b93e32b67105c07d44ba35c7183d8efeec19fb0d5fc8df817c2e121a609d499a5b4a37e55eec59721b4bb0bc1432024fde64c18f6d124cc62c2434305210379a1dff090019246608510329f6840b346666fcc54b314a47a9d6a04b6dbbb74f108675503020e8a9c1950417d846fbf01ecc9ebc75454aad22d3906fd0011e25bfd09634793cf05aefb8a5d5a4d015df946a604e1a8fb70442bccda1ac4e502ac789af53a940d88cf0f5a2018a5dd402f0bc80a4de9bdb2b57b60a558aa09263b5877a83d90b8dbb1b5449a1770d5d6ad7583a39bc9ffc7462e8220281e87b65e30b6c3715445808991cde438cab640bc3f5197f0320c14c871a6d7ca81cbe081f2279e0abfae022e6dc79bb5599500c2bfe2f68b99a5205593c4b16c8403437e2c74600069023a4ee1839d4dbd08e31dc65286c2925d7f118054f171ee169ddc33f1b5c40c70282afad742623854ca95cfbb90fbe6817b9c8bd0c6cbf8df1ba81ba9f096f3a816dfcfe6a1a1a2dbea79048d00014a848237cb4cb1f20679093d8707b078dff94a474c1004579c3ed17c344203890b8efdda9bb811118092c3ab05eb650163062567d004a2748c3a0a53b0369ced46a37d5529fd9920f48230122b579fa9fb56cb1c913e0ce0cefb5ad0524302d5c5f3f14ecef4dbc57227c5fce3a307dc9403e094fcf76cc77adfdf855624ecf157d8c6e85d4f9790e296900d8b203bb40faebc60832f5b2763f73b6dadb14e468177a2aff79e1e4d86c57088893a08ab83cfd71b982166b847a916116b538c26f83184e2b78950304e77bb44fc6f06a197caf5f5c2013f58168f452584a74f35e2c76b26ed90e2fd06abd056920ca0759170bdad0d70bd25b408d327c1268583d6e12e8b3a507bbf5b5ddb8ca13852ac252b63756020d2fd21a4f97446c31af9e010d33fc0c0c2ccb2e85a99f1c9dd9b3ef065f2d72671e20706674c9ce7d024d94bd1d181197df4baaa1222816934e2a901f03372042d6aae9c08fd6851d67d0f8f0aabf3866222f9d90a6978ed4872f2f282ec9b8c495e5644e7db9222c1d088458e1bd1df2c213a1c45edf421b3376fe144378716a814e01939bc058e17652bf392a233e90542e5146c7d0704919a307e3c6a09e903e80831583be16fa2ba10c5e5bd48e2d18c15c7db9e1b3554791ad2207a2c5deb25556843a1949e8d250501e8fa392c1030d53449eb899d0516d13fdf24cc1f3a30c461d0d89d1637a5a81a155995b2ed85d0943f21a7026b2023b0f372b87d25e245a87633d7ed1db351d39782c31c982904fc30fe925d3de32b9e7ec0181c754b81584cc9d33cfbd936dfe5c44148f010796fb96b798a10fe7c51fbbeb205d089d76cba08cbccac04743134b51d0330e22305888d076da95f58c36cfb52ec704d6ccb9e9cfc7b9a4e82983922143f2c87d86558573a67ac976accd99f69db1ebfa67c5abd4857ae3a06855763f73528fccbba1b294c71b7c227e0a30d3e4eca8d2dee8ba0856fded4014690585c5f5a63513f3035981f192a92ee61c9f3d1931a1ffef8ae31ce10845bb485e50958aa0c3c80893f55e21a262c5f4e2a60908c9461c7a3b4f47a8c36aef552a3b9c20c9e9726fa2c9ef5a6ac26dc9defecb25dc169b83a9b922666f9f4a91f1eb6b401da3ea0762f604ea0844bd7805461a347b24811f2724d023c41f4a261a994da5610c102256eef21e4a1b3aad792cc427a6155a5f602cdacda24688e2c83df9493f83a5d61421d271b80d50335b512c685c3208c2b6cad226493508c2aaa30328175d08f064998a29689964f040f338a195a1566e09408692b9b69d1c397d2dfaba2161b4a9214598d2e33708e67dbdd898c0557da09853d1f665667438f6469b3fb6230df2dd34edd7326a477e96b4332deccd53292e90f27086bb07ba8a920792d1a2329a7ac655578b68fef8ba8c573a2c92303bc1e95388921d3c8909b3c8ff73a51fda4c19155115522827e3012c4ebfe926ee253bdcf60c3cee4384be8303f4fb02d0c1e3bf50a28cde1d6392486ce1ceb7967481064c522b638d07a7bc55c0371d5a188a2a26eee03bb78a4b9417b740b9422545a0c2b318cb46b205b16736a677caf9eec9007ac082a8c399b61df3f679e5e8c5988b88ce839ba279ef2bbc6ee0482346f7405df5c701b85dbb114d1c1f30dfbac379775582370f7a8e44b929e9713ac904080de0f7e7ac6ee29eb3f606d7c878760a3c2de8d9e4335cbd617c0129cc2f3b19c27b1b0415748a314ccead58483417ef9ed63220b87121755372904299993f5c06833f048bdb0ee8702d2464e00d49aba9a98c85aae9e03a5f681a5afd73ca3723a211ab76084b001d5d484309068f7b93a4ba82598e38d4599ec0c8b94556872d084cb04e902a7a595a9e68856b76b10ed5a25991c884225987a814a2d152c6b3917efc6128e01349e6646cb5a5b031a41aad7d0bcbd279125739c20ee73afcd93169c367bdbdc3dce74d8d238f52a9c76346e176827c5cb7b2c07413840a4219b7448051425a88873572d52804dded490dda47f29a2da24597d18d796e024c6b156b7b0b5b406011109e00362e56ceb7ca165fbe9c03fbd362c26ae468d72bd55aedf0e9ee62ea380bdea3eff17086ce7d7758142693f10ee722d615aa1543e905e88a892b50f854b634b15b6843b2d74cac42412c8355a6e4162da518d232cb79b8bd52a36128dd6d411c55dab9aebcfae7bf10db34744ed7184d4615acaa261989542d9328a35b6bb7d8b59427aed62b15ed0bc1397fd4f2d5b5aaf137fa79b40c0c8140406220e694aa5974202cb19015c91c4dbd4143d34f52e04ac83f1271f2b2e64976a53979e49e6804bdbb27ad8024e40287110fea98725dd093169046d948aec47e50d9d2f5a85bbfca4d9bdcd4e5a6c4f8b323ff781fb69cc29e30960281d552b9a1a809edc730fdc60fa5e938f0cbf6996c7e440ffeb38902bb99d06503add7d0d177e88ae4eceb6c0934e68a9d42e7b00b5901e6c1e73ea780c105a8c1a06b7876d59082ded87d5c868477908b2895265939e98905e4caa88f8759be476684246e55fb31c93169885dfaa0d54d8aacd305b73705e4de61ef5131a5e700e8f7070c104c7b9cda9f889ad2aac4314056cd5cbd2baeb9255022332b11a694cb46f70e8bbbd36a793c90dcecb4ae8790e4b42214d7c7ae2be8ce8ac7bfe9ba280864cac2d9f362a464fc567337d227ad5e20d0c24b79dffc35e325df7eea1f6f377ead45d01e2d6969b06026964d459494cd8eb30a00673ce7a94214dadd082e983f416d751798791a29dd72c1e79fe1a922873ed0c334fe0810004d85cd634e2856550a313ebc60725ac8c2cabda0ba0ca323c65be18b13f84ed4408bf1494d9860dd311ef67ce7177030f84f1a2ec299bdf85efadb1c7c1f742143d1ba3c1f786c9ac17015fbe6ae21ac6662a12c2da4c66e94294c97d24e4524dd5d4f32dcc36bff70b3f5aa491e3e349a6af5d01324f899cdef0aae64793b6c473b0344711a7c31766b8faec0266c0e8f06dfee1db6531597960acb1729edac59cf3046439e738562ae3cd5445caeaf2916aebee2805317369c658b864d3efc7e37dce7c626f1406b3d765b1dd35a1612d177774ed4dd00f7825bf65648893040071e26b5478d27d23bc57a4368a5186b670e4546ed29d4bafd6b5f640b6ae1ab1f09bdf1370c254d8727b50c4785ee5873bcaacd461980c3e565a6ed324fd9909f457f22af32efba04b868165bc0c43fb436a4d1811b9a01648072cd60412af4ef93e8c42edf1c41c202641b14337215f76515aee672fd757e2d3f75e7762949b75294fb8989d898818a6f74f0192222509288bd56292a559fedf2230aebbeb3d7ff58a48c2e2a3938433c46cc99abca6450d09857abea739ceb4b44b009137e119c0641c6d76f97633a941c2c55f82f6723722fad5ef202d5d234b36ceff8869500b147b548135943fb812a9790ce58dd47c63d8a40d5e30d8baf88af9674c85437a6604912a76e8b44ae8ec0560b943dd00a0ebea71a189223a70658ca0ab418defb42648822ef046df80878406871659829288c113d47da8243d01267c3130b57773c377fb75226b2b38f34e7ca28a0c95aa43c4cf19f08843024ee88748bf20dd18e2dda15a669f53598eaa3a39823007e4068806ede847bb728550c43522c42f4a7172aa7d256d20682512880bd6597bbf164065b3f31607d94b3084483e32d87a42d849e1b4d16865a98058f8b7e10c3ff83277a487a896a1d8502cf11a164f460e202460c3575071651e20a7e0210127f8b30b0740a40576bde45d28eb2b563215eeace4c961598b0150488958d5d07e0634cc679462152f9ff8e2c932cb72980e6e4200fc755ce98bd542bfa2b0e9b53e1635a357a2583bf22ccb32e37841d2408505b1ca245a5c39fb618f80059e2f53fbb1d12fb73c5b543d260e6b0fcb7bd81b62fa00c2978da99211785fa58ca1cd5aaabe404264039082e33613d987b90f171cc51c8d1e43e5f6d5613485a2dd867ad8d017ac5504c8acb9ebfe300d7539066b3cc230ce1bd17fcaecbacafad1a4f3079c2d611b49be4879374d5a7f5e61b704f17e72b23d5b37d9b9655748325a94636dc72ba604c02aab24a92dd54ec5b074213c0a74487b0b30cbc553d03f30d838178ebf408fc83db14de4f4159c49130c98b2e082af75c6038a8c4c51c9771af12b543d70a9b7b454f01af7357ce5615af56b644bb3fad86bb4bf2c283145be48dea9ee8af9b96eb7456ba9244ed39c14b8922be8a230dccb1056415ffcfb92ba199a74cbd82475245421929e8e9095ca26336cef9cee53da8a8c6de4841d10d1b43f725d2310943691b51288dade4ed2cc356342168c263e1956032125405c653354fc03797c2a600b40ab3afae7a501f3943b0efe98ba981f07f33e710f7b65dcfe1d370edbd7c3e345030b3002da14e6c8c9b21d44364ad3b821bf5fa4af108d7fc2a74181ba98b808c023a1f2e14fd8be04ee437d93e08fc05e2e731fcbacaddedffce70d12ccefd06ed0702fbf1f58b6cdd6d639027f6cf2405cab859907c5a739972abcb521992cf93a1e1ae82c470af3905fdb66769e3d7c3e56e5dcc75a15658cbdbf06f33e82df82fe1801eca4fbfd4a1d8cba72d0359d5929adf3c7800bb795eab236956a99b4647b04298a43fdef0c86e7fcbdb927208111fbedc840548904e752eb25e475c476f0abd186ba4a983ad30b7a6420a9305219dda50792d78b05e1ae1a4e1c6b73917e8eb3693a64ba75f870710cc29113a9206a1f5fab7539b085df20da95e418dd766cea94b22ec60d015691dfe0a8ac8c8511755e12807bd9a85eb412d10504cca74301880b87ef8f1fdb6f88dc6389c883de2298de6ad4488b8e05037238d650eb181c4c9c1a3e4ee20b301e4c2f97cade295d495d208d69d55b0a9a0204754f5f33029a3225e4e55801b380ae87e2b96640c78d061828dea14b3b29f442ea3089a6c657d67e95c5901098eb4db47aff8b311e87e4e3ba77905be1fc122a8b051eb6323aef6e79e340c07144475f16834c67eacd6cbc27ac42fc116649172a5705272cb6b9729810f14e42f0a2bc4316d22cbc944c5447a08ec260a7221aed768926d9c00f40a174ac588deab3123c8ff748a8159f4dab6f7169a009476f5be8faa1d6e854ca1dcc482da4ca8c9af7966e466ca0e3667178289cbdc00f5b39c28806619e05d31973b47acade8229010344d70c7f9d3bd64bc80392f6db85c6e59721418cb014e32b34b0da43890d6e957667a39717e3ab4191d844580436062b5e8c181c4dad214373b8e7b1e6e99fb1e8ac012423777024ccc71c630131c88742b3e0a3bd170c93727676c7d5ddae0b70f19be94e28c306a331317cd95d1ff324057ac0302f8817c81e0eb55c9a1e4d77a0bf3219f61fd93e1108275cd3f8720b8c7253632c698b07c4a4e0593a0b9589e4c3546be29976f14ab5cce05b49da59179e43a5af6c8fa23006d5fb2c309375f959c6230510119daa0d190217e9a44092bf27680323403ead64d9b7fd03e549a245dabc9d6ef30609ff3a6fd1bf8b8a1acb481ab6f4f3c53de2b32ea484258c83903b66efe2b99513033247c48d6f459b503bdb4e4e8761b7efdef4890c49769553971330223c72892f56e88ff21f7d6e449494a03b607b139a470aac805557dfed69e37880a726533d0aa403715ab861f82e5ed501211060206aeefd46b90695ace1294025ba520eb0685a7843b9574ca5582f4d3e206f0a60340b09a84215a6b15a8a1e70eef803f3326402ad30ead38a6f51e2cda1a040ff86a31b1152a688057ee874768dcf118653de6435d60491cff2af57a8927145117cf4af49c4374ab72c20eaa49744029748fe00f3771c35c8e0e873ecf61cb5ac22741f4483ab7ece60ca583e61989d6f10527a8d0c6cd15a1f7b99fcfda332b73ed6e2d69d8a76fcd31c476df51d5e11136a86d0f87ec3c09369061d9c2b051c171bd37731ccc6b6a3368e8976df6bc33722d042e84ec2f620a5fb0eccf6b29f27056c6d05468300ca071ec8b888128c1dbef7e4db634b42a80cc375f64f4ce079f8d89c3e2f62c789e07ffa0d7adc295aac39dc92e522bbf599182cf17d96a0f1576dcc72b141092cc2ff014d57240cdf69af4c9d6cc49beb3cf8ad119fea4de3c17f9e50cdb4ad11897c49aa8407d2e8388349340a813b064fb690730c373dc0544ad2d72e54a1552cc35d6a6bcafc62593d1d78244f3c18faaabf82bc650e939089ba71e7a1cd1fb45beb1de418e45e81a6d721f68216c23037d81ea880ce00e93f9be17d08bda6401bf0c231bda33864243c6008672bf40e72598576075434c3b30940740b6f4a80d7d8a0312c2fd76da6513c0b85017f2afad83a206550c0c3a4097b1cff8df590308b3e3170db4bbb0bc57da91014492f565038f6353040fdbe4a2cf7790b8dd070dac5551f3a458c3e3f17e7cdbbcae4b76ed96ec691d007bc151359b876465b670087c757e14f44eb792b36462a2619707df72e04084a629d979c5ce34300db1b1e54d923ecf8180f1aeedba12a40c67f2107646d18a2475b8a98dc65801ad8d0f32468b096c8d16596ec6a0bbccb07e52e5e32dd2bf9dff39584a71ed3e994517dc6ae8849f70135982e824b4bb34a29f5489547c6dfba918dd1b286874381c4d539815780f0bd426434dc0d98e2e8a905af4a6d008947fc8474d26d62e31226e2f6123a9f9f1e98e48177c8089b3cf45494697e2b8b3b8bbdc343d3a073a24ab26032bdab32fdce7e67a00ee7ac63c3aac5ef8d6d789a8e3edb1adb316a78d265afd5fdec22302496c062225adea1526bba604293a110394aceb48466d8114549968abe72c0599c296037290136fdbca6921c6421c85ae2aaea1f722a562ca8581b8a8db50ccda79be4a2cc3abe5ec955da37c868f0455a4da9bddc135f86ba7441e4763e07623b9305d283c575113ca77fb2fb68a2047ffe3d669247e90e3f121f0f76a923d04c80e39a25d73b4e08dc478fe1583885cec9a14a3f0ab9e9c5875cfdf72e843d1bb85c8489a4457eaa56522df5932fed122d48411c626850a2216e627e01eb48837c9395ba6d524c8619dc30f461ec81a4eb7350904c9c7211a6f656e29983025c58d7555914a6413303280dab4d78047bc73c1c1ed9e1032ce87547b9523935e0ab6566a10a36352a3bd51442674ced1a4084c6bef61a1caeb9f1848cb6b0173363164a75588818f62fe9166c26505a6219872528aecf5e0353725c91e293afd286221852cd2b9e514347b1a632d4892a625fa853e7e0f85c9fe5eed25a57c1c7a8cf2f67f8adb12638818b1d14ef5453b79ebd4c8a3d8802b012350a2ea956137fa58ad2b9381220fb5be993eef3e00869bbaea6e4c11158649446f6cead7052c24184c10f7fcf10dd1a2d6f77720cd7e0c54d0fcd35020915810ce79ae260c7463a3870372ad29d778c0f016602bd1df38096f2c8ac944706e29ec11758019f6716fb693a8b2da78d7ff019bff69a25a3aa0579c228b51e49760460fa0af137d91b05a6d61638c12d9f35ac3aac16a5510dc649c9574ff5c2d3e311d6509ef34d4fe73980eb3e64459b684ad2b3742a6e208c12a7e722b089ab2d1267433fb519b79e0e737422c5f35061b0f3c6714c47d2a463a346bbe2dcb7896c8a43fd5bddec108322672bb245dbd3318434cd9fe73711afbf9f0f2bd830909f9ed2d68811e0307ee4366131279d0e15b0edacdcf685bc6dfc32ac12ccc008a37627e69247107a346044461824d049e5c9f6e11d0bf88f6108459e9c1e228bc7090df409970db75b7f7f14cf2efeec7259433a1b659f1061d0341481c729b6d7c1cfd80bdc2ece9fbf8f6bc0470b899103af0e6bd8807494976cb9c71851f17f65cf30aa6ddcff69026dd421384a7d26e1388bf1c2b6025f28173434b03eb9b29edf613dce96292b89fc4b40479e59d3c6a9c7ca41794f4e37cd1f7067f2556162dd6afc562fbb3a0f2dfb61e90c36d3a0859351f31dcbfb520589fa354e34c99a020da3a8b7d6ed44434a5d37457b1e8ef73b65445d16d119224fcbcab9d0298d467bff72268431627f351f724062eb616e17a1d2fbec1f490056114eb28683e2ff573e9beed01596b0db5878c85d378782f28c200d1178428c80813f55ef926d4e6dbbe16511388ca3b0d806c3ecdac9257fb480182d062c08059bb9402704df9101dd33ec1355308176f1d5edc9ff88b232f280cfb5e5a9301106f6dab4b7a8edae2d81c553622fa2e0c2a3103027c032a0a21566fcb32f17f58c01c48912bce05f8a83c852d0aebb6167d166492ad092079ca3fe8524d1e7f91eb2dd715d05c955fd0365d01b57287944db455223031ec23f999778c1bf0d870f200c8a61377699a05117b3b4a9008159a95e1610782bd165bc3b81004b4e4aa048321b569c1139b0ff975a4e6d09816aa667828db66748e2a4f64b7d4c1ec51b7c095b1b4843782e3b6b147a5700ce1769014d262300124809ad85ab2a5a12ee0803403da8a8a03aaf75f4167a6a8a981361c8b4e2b388c8041dd52e09311dd6d2c4d711f463ccc78d22139357a7bbabd9941a929599766d6f87dcad8983594404fe75d74ebf9fb8d33e48e28a3c6d1c32e7f10e1a777c9857296bd5412b11f947176a22adbcd340ab40c60c10544433756c1b31f45f7f532585db2a62be39d85a0ad9f79d4e84446d564f198f1e82e1a6bd2f4b35bb0998113bb0c88ab05ba2b468df2b3d6e717998362f1ef1a28949c5c8a9bbb94438f138797861d19ccf749146d2a87c8c2af521c0e1689aafc33483949d5fd86d5f2ecbab0b5e477030ef33c72ee86801976509ac6dd9030030c4a21c1c5852368540533f8fdfd678b6643a002d9a0628a3fb0b683c4b760248c604ffb6e690da6a30161069cd612a5fd871d1e1834eebcf852685a599f2315393b1061c9752b7f29fe7018737997dd3c28e4fabc690029507573651cff8cb6742f435758f19b5ad5793fed76fdf5c4158abd9343f3d55ea74243e73facbea35eb7fa3d56e73ad2634c4edb20e235e1e3aaf72a7693738802cfb8e6d0a2198cd833eb046a9710a5110bd641ee0d5a24b9616e5c9253608ea89aee2f385e802eddb925fa9d1c163ea554b78fc798a35a0a102df410134baa058fec1ba44e324c3eca2375fe32c19aef42b1a188f3b84d9c053d23ba7b6429c18a4725da1520d547609010b562455e3b7e2eca73803fdd1fba2343fde25f46175f23d18677c738a254e643aa8d1626ab19d492a700f27416eb31485df97d870ae6d3aee7146eafdd341be59b830210eb8ef2e4e0e5869039a317fd0358dacd23c84c7101a669e5ca16c81cbfe6e44463ba5e1f9d77310cc05332ffd8f126b8653d69f2c2298ec913ee19a1aa2715a9684e8cbaea3f0458d93021095513d610917c390f00a07f0033b865c7577940d9d9437a3bb112022415ae330c2401cb0a2f3bba62e085480fa0b6b291d282e3945abc4127b1072ea90496fbbc346dd1e8165ea0525eee5439c6fcf17e534cfae9c019d2ec9095a02ddb91d83bbbb7337a43cbb0c96af956cd1b0f8bf78871825ec057e4654d9e2fbc180eaf07938237bb1ff549a07b2c358da916545dc8f31b8bdf8c0401b1db300be4b5f34996afa856ea64e20566c05c6acb11135962d2ca22e647c0d694d6aa5abea05e2ce2785a6c55b71c4313ad28ce2895da7853b706276d3afea191d00794104407e80456b48632eb7ee4986fc2c9a5634cef48caa8e3b43c144c63f3486c3028647be656d1610984094702e8ab3b38dec3d82b0732dbbfe860608e77ffdf15034091f1bc4d77d94f2ba70b1e570abff2c08088ed36a6278f5c787908ce092af9e87376231135984ea0d5e9acbd26fd609c91afe6877e6500c30a9a9753d6b8256ceb1020ada000a719b6586b2a94e18b4ec180ba7b82146320b18b8cda0dca65b791fe16150cbdb20db67168a1dd5048d751d2db9d2d983155a416806280ad3e3d44a4c8ca5a0a83a7871c2548477fb3807ee8313879897c992eee6300a59dbf2eb6459d6ee769443b3e57151b33896581de292789a690163a9b8b5ab2ea7734da7112d98471ef301c1f2a7f28238a4c1a6577f75a6f0b37591e9f1db36f806f2f0e62e9f8aba36899b9cd2d01375e7250fd438cf9fa23ce89c75e83004116681be88d56d7c8ffb9e2677fa67ab03cebd096550856fb34084a708bcd95114a8d6b8ed0859191499fbb9f0f679fa31acb2fc6ebb319fa19dde397ee058e2cf2f1e9e6b275d1b91c2079c95c2f3fc75abb8366e84bcbb732ea25b2b8c3d82ab217ccf0bf771b33ee8057cd6329fd030e9da6da906c6ff96471cca7446f44f716027762010401b176107c955861e3e6cc31493f112f84e7c8e7f91e550085d85087975cf1fa5fd767fcf4938cf012ff574b42205a493daa2718b92062f5fe805afb1b1c69023d61d840090c2d5e792f11c5e1799d5a7c2a8e60aba2f959ba6cd3c5296c67cf8457dbbece8cdb51606a6ac523e6c0041b5b3c4074d627a9f256201a64a9409bd78361e0c2a37c4494d33fbcf91acc4aa59009a047024fbe0dc8daf370e55560e06cb596eb9a6b3fd71043165d20e3b68c758f31e42c80e6f3fef069c7b5534f05ee65b19c420b63f938eb1420306b9365f185234182724e4386ff1f161559b7d8b3e9eab6d126e3187a9497f2cac0ed0decb6f2dc0db4bfea3181408de37d3f63d861ca01c87861a9afa781445f2d118a7acf4f268097082ea0cd7970d5c2cbd529dbb64ed6b0a18e45ba34940bc40af4d03b049321aa1d85e54286262d29ac021a8f16f0280bfbb363cfbbd7c7e89ce289e4115eea6d1a6c5f3e2315e4c04d54793d47746f6a52118f58c03f157d6f0459144630e638a2549192da5659b045717e916a13398ad184e22a4b583588cd8aca0e58a221aedd24381ce8dd3bce70b424eab6fdd70c4444359b5dc9a9ee6a75c90f2431f6ce1408d08f8cd42be899ef2c51896b4412a5d660fc026cfe12834290641b7c93d1c967dab360eda515303a27da20a6adb5d7991016e86037ec79a5aefffc78d5017072ad2d2f4674aebaaf90d482fb28957c6ac3879569ab677a11742ec7c47a4b3742ce2b100f0e9999e867fd0c40b486fdb14eaa67844ebee46788a112f76855a5a3e76580317a89465077792949f7aa45b83a371288ea4944b962342722ff0fc04c9c8a4d1381505f8ff077d054ac7d48138e7a01af48450926413308e0b4d73a26bf3ccc814d3d62a3ffd0685013e7e93bb32d025fe4ef0ff9868931d318ccddeda9e9c98f2ab2bd97a3074724d7dd8c9891a73850043096db37193a84d3bcebaeb1f502645dc26c58dbffdcaa51d39d7425796258d346198377bc76f49a5935410d5e491c37db436026bebca550b3fbb81b02cd29718c2c3ec233ac421f2b576d4be489232bd1aeeba45125e43188ad6b1b02475438fcf09d385ab78e950bb974c4392206bc5880640fb901d94cc602d1897a19087aaf19f6f617667af454da740d1ba477b09338cc38339e362c9f9371258f91cac6a429b11f318f95e7299c85a8e166470acc75610372d692de53cbad0a54541c513277dd1a3d0ab91cceef63f72b6086502bb36b4e8ee8300baa6968e11170afb82b7352a653c54f29a6401d319b14239ae2559b850ab88dde7f2c9d48ac0943fdc6d51fcc4b2566af010a62150abc586c2fa12d41e2b23ed31af8c55880159e861f8777ea531c3cdd71905fcb72d75c809a22df6a2fd8d84e3c92d47cea2faef737d35c10980b5022e0f1e68beb387613b28feac0364bc3671cef11a0711b876721202aa2fa3455613ec28fa287af1a4e259c9e0a6da89473cbf80286d2b981dcf7426bc2461a677919346f67126cc213341f41c5ece86cf409803143b0973f158b7d37eaf0c328d22a3541760b2b20dae00840cb4b875cb9546ae9e46987ee1fa6508768b6dbe309cd2e3b21339cc3c0f7dc7f52c9d4596c6c933c2903285690e0d97dc11b4f80087a858f94d49bc49af3f33cc17c894b0858fc35329d85838718781ba2d1074382e9806cf103a6c92e23e0bfeeeb022c3c4b572ee18aaa2b7aa8a089da942ca07b80bde8c06dbacf74f6e184182d4bb5a8d87389d69a4b65434631efb5e1114ccf45ec9add3025b8490a6ab9885a934e75274d9c05f28213f38d353344e47c18e96def91c932e6d499f1038dbc72b338155989b41d154691f05c60602cf9f6793b81ae5823f41cc3800f355ba974a7e0f321dd001e1f195673db972fba98cfee3a57921e7a273cd15f22acf9bbeb7f7647f0aa0a5c48bf7ef459988e33dcd83ae04b8d77532c502b1691e68d0a7d6a23d98cbe0708974709c3b1cea2166a26e77189a09e889302c9829131582260ebd2a8aaac5b7aa32ea99ad0ffab62f2a7253b20c7bfd182110d3cea899b227793456d76ddbf3cc2415254bd37d759d70829ad9ef91328fbbab6e95a677caeea938628b9ea9ea22ff369e5f62d47ab591509e84f5590c8e372c5174fb451647119c078ddf231af494717ea42cac6f0aa5878b0ee9b26bfe482ed993fb36ccf3c8609efc04ee473b6e3615eaa800cbced99bff0a39ef9dfe9f6cc97c2a2a331a5dd1b0ab4a3c808433f45b112c635efdb665db1af0996e96e7e40206b4ac5a40d729e365ef0e13417fbe3038444450de7e04b65de9ef9cf0cdd339f1d24091b1565d327a7506f7c74503842cfacc133d3ce05395ae254dabcb795654bacb4b0cf8a1adc1e6d501084d268bd660458fe301a7c27ef99bff635ece66e093023cf86783dadade6266b594175e8d354e1638d34b5c9b66860abd07a6887fa4293566cec2c09177ba32534bb07f72d90eacf54463d341ea0ce0ff6dc8c8ddfb900a9e2e2296ab31619b0c61a8175f7ff17d24b12150e32783b7623e2ff610b17fe73bc7ad99bb178f7b49b7bdc68789342d55256ade1ca7f34ab1bbfa65e33a63a6a3bb049f8a2fcfc22ef0d4974712dc0dc73e5f7eefb73c54323dac2febdf92f375e7ad21f3c766fd0bab46edb1f6311ab27f576ff8771487e1f28bab0e7106412462f4a47f9db4360f4fb42d676c951c1b065ef343c64fbf9e8d9f7c7ac2bba701e70dd026ddd08773a8edd70934042ccfd626e73796e8cff5eecedbf7143667847030c374e067ba5fe05f0279eff9ce7ba70613e9c6f7ea5f213a6433cf574de7adb2ebe97d9bcda602c0c5ff0603c07f5763676ed3c571e032dd6a0f3c70c05c1ce95f03d9fbd12b87dcd684e994379f75320583e06a0fade45706160ef43843373525ab936ef29cd6de4b74fb05bd511b04cc3552a8b0eb92d38685440f9cfdc2ebe7f5410880f623dacf91a8524ba9678aff1108ba5f581606a11a9b1cbe865bf978a764b42946762f0efbd1329971fab4fe8ad268f77ca0b13ba4e33093f26c4b9dbda7994ec5d9307ba51d1192f427ccc9a6f9ed40452eeb253a63eef863ccbce4be9d514e7201398a5fff7fbcf61942dd87cff0a81ade4618c6bdd246aaec6436148dbf787407e750ed7eefec3f110a9d5956d5b0dcfe26e1b5607483ab966f8b6d8a9c8bf53593e83b169c4a376ce4153a4a2b08ec4f81a55e878655acef0071a8c363547068d600d77440e44ea842f191271253e261267cd83b63aec2e9d423753107e3b85309f1d1bf633cb7d76ad466f0c2a61bfc5086f5e8de66130595653d587e51f648b7e18f1d0cc98b7b7f55c5607ebc5d3ad6a33bbb22b711f8571223197bb9de405d586e849bcb1933bb3786ec35beabb3a822d48ac9e71fe38664ff02f635b7e29630d3eadd287f7f7f56cf228c90da9a0a6e580c9f9240322498809b9324dc9c0e95f5927ce109244abd5c8a78da5c710f0cccd771108506722bbdf8635c9a5567e5be6ca1f72361f31e67bb4d98855e1ec11b2007574d59f16962f1895ada2eb3f036d4269c7e7d97d96742eecc3e64f126ba40f1bd252878fd50fde9449ff77cd3cf2bd08d66dd1a9977e17cb59b02becf32ce280f3b4ce381503f71b54e345addab723f58d0ff6e986939a4912a9e6c3c0893a95c7eb21db244d0b6a9fa7ce29ddca11b6c5cac3e9092eb2daca3897349982081e8d8852f0e58eed10a55627ed4b482ddf9833ffdeb694280cfa7b52bdd98cc4fa0366bcbbe7c2654c891cb7155459470261571ff490b0d9434a8980ac45ffbcd39875389c29079a258bcca6102d0f15efe9694ac448d03c3dac431211f1995af8fb8bb0aea609ebebf9c1cb93ab3ccc835a4942c8dc707bee9e38b359c8fb262efd3dfd6f7c6fcda69b1e1d66567627b6569ec79bde2772b25ef2c0bf4c3a1ec5c780a4e960a81747efbb8f9f560d6ccba40a03d33284e2417f3fbe6e3cfdad36592e11280aa7cd0c8c03f8fb7ebdf926a02ab6bbed54c837f962b83a5f7dbe7c3a3832b7e51ca45390979d1a9b1077e1f5fef478d0d4826b4c57316756425c32eee5e3db83d3b1692bc7110da5fcacc998491857efb78f8747066ddca3b40af332a4e293622fbe5e3c9d8f1a5b720dd029e735bb4e2e116c09869bb7db8cd3d6423692b149714d756ba1557b95da8956dc5acb3ba210f7ac2bd2a0d80daae8abaa009d241cb1a33dd408e740ee9a35ea43250026e95f89619ef4c0728bfbc819ea411bb2a9c043b6184eea417d657cd188f45715e952d20151f05b9d807602feb8a37a4fad91184761414f7ae875946940c0f4b1b0684843c70c98aaea686e869094f45fd0f11f644333d993df068c24edf5887b21e8df136f8413b44149e7505bc705887ee59b7730906eab924816733db3433e20bac287efd787573dc0479fd4d4f619bd10791bca8a50ddc8c572d4a80b55e2c18065cbda9508273d0fb63011c839e2130b304bea80c25bef6ffcba2d565c5521eb35d970b5c18c9bfe99bfd01d0f03a03fc7a90b8a7dab07273a23737fab8bac74d04fd8f2183de5c285f0e67d9d723837ebd7af1f35ec2ea5dc20a1feb3fb1c1f10b402682a330f14126938e4a6df66c18dad0d9b389ba990d10c3d9bf3583f833a4f1a6fef6fc057549d9216a8dbb43484db3aebcbd29eea85f676a8718e68357c70b7d7ca1c874d82ef290f1aa120bec3e3c83e81b1ab86e9429572c3f531b37594e3eb0e1efeb5a3ee1d672622a4318d68b649ec292340ced1cf669261938f4f1de16d69b1b7ba95862dc355092bedb46855219c7df0cbedfbdd1b1b993be27167ecf04e4df6687d8a3435a881c1e12d27e6f2cc120b725b1dae652df42cf01518ab00569763aacd882b62a9c23a32007c7fad2d0928d1ce0065c9bcfcb96017530f523e4c6c6229af9bb6d31025581950997fc78cc7476459ceab0c290a919a47a31e08d7be3eff1128afea1c913f18c875e4d776de2be7c6968a95dcee21765ebc0e60961c6ce73c056bd29a0d91b9a10e015ebe061f44c1f590aa6a12484378adf80a11fc5ac5dcf5030adc4175acf09fb4e1a13f659cfc5261c86b3ca28f8e0b7a176233eec4e30e85bf6130ab2312dbe90bf781751fc859f94527c64eeb39389c522898eb49c8148058ff89792991c2862ee89761b485ea1a0ccc2f79463c47b0503c341f38e2e33b23954a001376d283708e61098e663470357abaec1f78d95b3755035427754156ea9ba0c43a180fbfab74e6a88ebc0c300d5ab7496557a1e8bca5b06c2b1de531849177a6d0925c5fe5d34c1c7e7caa5fe9b76db6b5bdc82ab93e87d3557943a86f73741983dddf34f762be96db3221fdefce499a39fd2e69e612e92a20a8a301e211e5af91c6b216268646cc2ada788d207874bf55631fcda2d17b7faab8b5c96505610c01a375bacee3917e1045cf0f7b911419f3dfa08534c2d7ee6a862c70d14bd16bd5e6fc0e111d92670048efc66d97b867fa7e07df09b56cad67bfe1ca0da19df27f65af37add2da5f078676b650abb8a381dc70d640e5e91b0df69010b092cff309d188f4b51916ca279d09f226266b4c8ecb592fbc37a1d3d686cbee997ae8a8a538ec7681170713b7e1810263e18fd26e449ad96231cca196b8a7cab06198d75eecb9e597e844068179b4b8ad11a7bab7c16f5e94ddabde85c116a87225e188fdc0c2a4af7aaf6f5d6715b399d6d1390c3e69fa2c03db7d625d1dd3cdeb8d78f7962891c558fdacc86836399d0a6e14534efbf75801a8e59a1420b19cfcba826cef482d328f365d6219cf88b43a8710b103ce372e9674c26d7c458a7e256db83755f0f9cccb026f4ce5dacd100c0aafe862ba92395dfd371f0b5d66134f947f4f0b42b6e0f994ff396ccc9c72db9930f72cfce864a6f1e36df28033630d1e7c1e9eff1f33a85e7138d05c74b10c96b783ac9fc12e83a6fdfe631d7ab33f7cef13b8c6e00be7cd79722ef1ebe2573b973f125bcd708775ba0014ed465d3b1c49481704c32e88dfb8f019ef0dd5712704407d735bce7fd0e1d1fe11b751b47fad1d2fb973e8c6c1131ef0319520c68c98fb5a4f12ee4a09636861878f3b6687a31958d34a6d03c61267d472b451690ca27e39b53870e96e20e7c9641d5e0f4c174c4497c47317d0b1fc9504755707ccc932a0271ad431eeaf79bf7175457197c2d975d4322b67d72d41b85a0c606c5ed350ecbc8304bb92e3e4697d2bc27a6026eca56b97801adf7cbe70c617e84694e408314d6bf8bd110b76605c0c89ce38b304f530b07a5559c8d11195cb80837eb6900f4f251eb37afa70254fe1a2a37415dcab57d685ab0f89f4d80a7e584f685dc2732676f06be4dcd95d83aba661e7ef2af3bca3b16b7743776b8789ddb6ddba07e09fc9d66be80c566e4760f47bc1a004316c52b1626341e6271fbe6679c4e04b05956fc408d2cd121db26d9fb078ad6fe5c5c1c8525826b160fad35d144b5d6197830417bbcfdfcf4a4d0e0f50e43476548ae14b8616c15dc723b83cfc6ed167872589699a99fbde21736bc79fb38d6f4b1be4b6f0da8d67c5ced5b0a22d0ff8771e58a7952547a21a4fe8ef7a30ffd3be340e8ea566bd2a10419b6ebc35c56f4c4277a2a0238ac0f54e409a1785b209ff3e8a066247169bc0295313aa30bc78e46fa272ce3ec461493d7b1375eb67638dccdd6e5820879ef3816cb1f329389365d04368e29d21408b3a0e8867c9c13db88ecb825418ad24339cd404127fa25ed589613f836b9965c3bf83b6ad96a025135b5541daa5f77741f322ce485c7f535e0c94a0987c970eda4e2a399b68034df21eb5b08eb7968d8964884e4decd40b325b841482bfac88bf73640f9102d8272593ee4aeacd32a19bc35cbf9d5966a77444390483ceb4c1d4a127de3f0a5ba7f2ec3dfa686009f4f36dc9166e9e4d6e78d78f84fada51e9c5149414a7bf76226d32c1a8da7eeb28f0882068d09874ec619f0c6622eabd6548ed2a22b35c30251be5a0b9645d157cc65b3fd2050a1de6f14e3db34ba3bf136ba52a4802a842a540ae9c2b9cc5119a8c5fbd51a7f9fb9a74e4566895f76d06dfe6f16a82a47ce53dee03942f79ced13776326d2f3a7b4d2afc54b24b6adfbc77ac1dfd3ae896aab0eb80d1dbd4a9032c75012ac92d6fdcc92f774bd92287e8690fec380652e70274f71b6efa89d0fd36583443f8ff0f8ac293b7051b44f46cbd023fcd5b3116b8d1cfef31b25dc8dacc60acecba9cbcd606c3bd644b1b2587bbfadd10d695d4d76680e0c2116759366671523f4cebf26847c9582d8f997ba495853756839f59dbb7a02d5cb220568d591b751c6634c8e9b697756d3fa91a94cd005fa1ab8f3284df31db5cbf81dd2bb4002f574517131d509589915c46a13456c187e17ad8f1ab2eb0b7e35bdf39e0eab38cecb6a7caac9d5426aa302f5aaa26a0be28f17f09e64d9860be6a5aba1768c8b12b16db9a0a425ebe0178de3e6baf0469ea993f3638d58ae588ef041af0f3eacb32b6a15510372a3ab047eca43dc13a319bba4e57f1196b919e6ec6af01abb0a266dbf57a00d5c65db9867fcebf89dd94056df2b3c18708df99faa32fbbd65946fb61aeed5cc346b1590eee7c6edc0356a0bce18a7d4d633d8f64a90b1032c3d2829d82ac9fb636ea16ab8b8b6ffcc8125d91a22d21fb72f41b964d41c02eba1ff472ecc8eb7e6f16f15bf404477d457136106ffc66eeda6d8bfa988bce094ea7593d6ec819b7bccbfc1fc424b2c53c15b7cbcce7ba01f664adf6c21b4b03ad52daeb42a6eadec0d18ffbbdaa51cf45ced6306c733975cc459c10af29c574150f1fdb20f1525e96d28658ed36e0fa5c5e2166e0e42093221eb2bb0c027ee152b9e22eb42a808a581c8b1616ba76f12106c45673682d9cc535e9773893c9183984bd60cfa8d0cbe9dd9929707b6a28036dc38a824e0fc19985be70160ca2d32e4a3b1fac5a8e8d872a251a4a1f7e00abb42fd1bf4c8623b5091d211d442c45067d29bc242cc5acaf837cf9125183504c71818c7b201ceec32df063d35ae5619d50fde655c691433e22106e869051da745706db4e6dec7940484f8c82775bb07a2f3f82f507bc6bf7c686a354bc77e73e1cf5909608ae638846c7b8f295238394a8f983c19eada944de2fc90c7634465966f5ddb68555c696ee637f9290b73fea5ded427301c0a22b3c046579cb3fac4f4c15a9ecf9e43bbee19eed8d401470c5c0f7299736e05925653f42a0de1f37bf3f80cd8cea9641f3c14ef059f71f434fd973790c8c9f8c82edd664b847d60079a3e5127a61cf2538c6d4dc9518050304fdf1da29f9cb70bfbf92f7357f168f67cf899ab5ff93f34e3281ebd7c65a93de91169ede0fe0f8ff8f73ff155e7ae9526f235a11ee6bfaaf8bfd15b13931fe8e955ffd611f6c76bcca735c1690a0bfe72fa95b3e57561d07b8e8ea2a3072d30bf2d9451e483bdcd3704380de9792bd8109047f08f98ae026c464116e772cb12b6fa769f33805bc1a9d687df0f3ea8510a3c5bcab6058d5301e6b8458ec0c1a937424046facb05ab82294b6eb1368a0e486ac3eb6ef7018de3e30f7a939772580bf3b0fb304b5fd6a1973395f8c1b70573976e722a7764a6f9131e63b8c7f3c493ff526ca884b9a51df093d96c6242704c3959cea35b68bb8ff6657f5e05c594237d3e1d96761ecd496a00224cb12bdaad1d9f4c31799519af3a13119327b343aef0c6f065ee2803bb11eb3468f2e873fac423e2bd32cd6cb0c68e098dc49fec76e44fc1b6e22589f951e6902100e146a169195ecd046402cbd4f7c5a78b649e081a50a545263bd767b0d1c2bee031211ec406696bbfa49bf9c4699bf7e361b574809a5c7b715cd6654259edf852feab08fc4824d26f917adba5aaf8500cf2632f77a4c72214d472246849a67f765a3f64973cea40f9b5644134bb6142760bf7fa21eb4a61f05ee007a64e1404630644ad20130f06385d4467c6ccda116a731742fb0618aa9e1b973e8ff8d20a211820420adc92493a4dbbb6fcf1bdc60c4e60006524a29654a298913a9f805cdfb4764071d8db103f703a60397a8a463f29208e51106a03802fa7a6f6eaa5eebc47335023ed958ee3a1699bec99411303ee63e9936e6bbb6e722a0ea7492a3bed853bdf78a80cac5989c8c2bfdf72d4949046c1e59aa7af9e22a7e8708c86d29e398e44bcec9180f011db71939ce16bf25a6a4212047c6fe9eadafc48d5f21a0644c6553bfcf1102cee8cf2f2ee79ece57731050f64bcc9f63cd8ccd6781a008023e7dbfcd5d8bced91b07024eb9b8adf754ce5e692920a0732cddb9c96ed5e56b7f806a7da697ff3ed94aeed3d641f103548cad6cb1cdf696bf9308b8a0620f4a1f206b95dc549ebc143e407751bd4f93df7aba49efa0ec4108450fb0a98d9adac6a849792d1212cde529cb4313143c401913f38acbe26a2efe1d6073e98ca3d3d79c6d0702558bfdaaade98b8953db01b24e8cc9c5fa9d64de4d06a50ed05b6a4ad201467e1ce38cb1db1ca0daf57ca76a4f3940c5da712bf59832f7e97d67a3e130ed42b7f39c1507a8b3397bacc9c66fbe27d93c262953e000957e4acb6bb66e83f20698dec695665acc694ec6286e80b371ec29d9ea92cd297d9436c015557b6c6adbb1563151d8009b72e7556a794c4e992b692a95be49111488415903644979e4f694fcf13ba906f8ea5dcd9966fa4f9ede1a9434c0e98e93dbf873ffa96b688032aad953e94c722636d51960fad862da5ec58e2517cd00fb9d632d35972bf52b084000022ad2b2a40f209432c06d4d92992eb6ac4ab9215e441c0a19e0fca924db55df78c6e668b61819e168b628e9585690740cf07dbf7b74eb9272ee668150c4005ba7a4d8e792aa96ad929628a369328b0d03ecf7e63f95eddf536f1b1b1919e17ca7488401050cb035f6513f368fbcccad48ada07c01c665bd1a5bcf5edfbd7901aab697ac45a7ecfb889c7417e033536effb9e8ef718c254df55100814abe953fd95aace24ef6077c77b55ea5d8df3cbab624850bd03dd96fa57af52a7dfb1660475ed773a59ebd9af303bada4feb45a5cda7ae6b012a2b9b52c6e6dcfea9a66401ca28e7f3a4563f394d2e1bb6b684d32549dd102f220d50fa806aa9c76f3d45c1028ceeaf697a5faa9c9253ae0065c7978bd7abfe7c36b3588a15a02f35536b4eb9626bfaab026c2c6afffadb259db6e5f8804a26f7566b51b635bd33ff12459d8d8613653496b59d8d86a3287bc0d5eb62f3a558722ca5d203ced82afdc9f7947a2b631e702916dd7b2c1f6bf6bc2878406faaee3436db2777b53be03af7a47a67b55263f776c05d4ea52e2b3b5dd21da50ec88ecdd6e9b5a2d001a7d3f5ba195baff8bde596843207eca95627a958f4a769291601723c7e808c553f76fb126352aa12cba60f50c6e5955ebf7e6ebd353ec06ed5b9abeb34bde42f9e7451c6b307a814cfd9f245764e9d2e277a802f7e63259b8acd996c6a8c270f70aa7a6bdaadd7974f174fba50ade3c1035c6afdf16cf9ee5a49d99c8594573816c77307d8e25acbbd9fbff337a52710e8bc3a957bbf892927bd0d79ec00d5af159ba9c7a273bfbca903ecf8def3be5d1bb7c94b09275a5d1d78e800557452a754cfa5ef1ce04bee643bedd8cd497d254de76f22cc6fa22f2c52d55df1c861f3c401fe5bca3dfb4cbd9e19dbf4a59d93e000357162abd25a9d1eb3374679e079038caacbedfadbf6edab79646464646484a3f4710364ab547b8f57bfd75ab20d505f23a79dce4d37fbb9cb5c2478d800992fede68b31756efecf1ae07a64f6d6d2a8acf5754953d9b430d10c51038c9adebfaee9dacdbdb5aa1cb65dc25143bc88d29306c82b4d97a27caa6aad6a3440995ab15d535b5d7e62cf19202ba58bbb5562ddecfd98012a5f49df5aed5c6bedb1a70cb0c5e833357331c6a4641ce24554f29001268ff2399391c555f1750c30a9399fb6f9d8938fa92fd2673c62801df7979baafc45c7a48701c6e85c55f1bbe4baabc0002563ea55fbf7d67e8a9816577cc0045a60c13a449ee9f305289f69fa8f4a6a4f7fe5c5e3051877db6a8f5f39a58fb12ec0f994365fde6eddea35d7a663f20002bdddb5461915fb5b6faaf1fc01d98c4cce24b7993319d3c305b8fe319b5199358e91f5d9025c2c697a23232b068f1fb0b93e4ee931a9567472f7d102e4661a7b6e5ab7cc35f764214a4f1f58b882152e9786c053050e051e3ef6d8478f3c2e97f6053c7874fab9438ac78e4e4fe0a9e3010f1d6ee17494c03387031e399e3828f05021c2c03385083c7040e7c4de63a752d2ddb71e2950f144010a0d789e2081c709d25280e78d073c4d2801061e2640f664f3e85caf4b73b9256ce05182031e37ac78926081070918788eb08f11f829421b533c44d844523c4310c2c346059e2044533c4068c0f383073c3e80ea4ffaecc456546ead14656684e1341811f31a1078d48820f0a401d749d9cf644be6bf383e3d80acf8f9f47ded95e2d51bc8bd797e0f0f607bb6a48b9a987f6b9b254d5799ee20cac083860e20db5e6fd17df1ae75f139033629e572ea196bb9a44a8f1970df93ca779faebf7673c878cae04cf190c18027079055f67c76a6cd4d2eefe3c14124c533c6029e1b40d752af9d2e45b64bae8e8c6c31b2d198a4f1d800aa94ba45c671466f9b67e5c2b9103c624066ed9fbf36fe7c538b6c3a19b8cc786a009f6c2d367ddb3fd34b6cd331796820c53303189565ab5dfbd25aaecd7fe39101ecb656f53396ac54054abf1819c98255e917ace8a0442282820209e8333ab656bdb5f1d7e5d251eb583096e99b6ba4614054804fbdc59e4bfe54f28d6f0af095fda69feeb879b109075c73c5e476c6b756ecc7a400a5944cadd693d53bc91d05f8c9d939973c1f8b6f2d14a07babe6369fabb5b9349f00b99b3217e5e4f8693e7702fc18b99bb3f2426fc097acd45c2c59a54cafa126c0b8664a4d9b29b9deae98005b9ff94a3c59635f4e424b80f33bad331575b25b6c92404a80ccbcee1b67f4d7ba961bd0799b92ed746aa12440756d723d35f5dd809000d7723af53d6d96cf5f1d01b237a9aefdcda7af641b012ab73c7b9d25b3c6ecd1808a00574cf3b95b955aec3eb5019d4b53f965b763199d212240e7af2463b66de3eae792a6cfb97cb4d144268d515d574043784c7504cab9daddb74ea935f1729a31480890599d6f9bba94cdf709b10175ad5be692ed4ccda75b5010a0cf57bda977a65e4f4e4ed4e1684aa2cc664932161212cd05424080ab25d56eaa58d4c734413f80ac24af6a1bfb55f4e638900fa0ec4e31cd7daac9d6146b035a03b24fc6edb19c1f9962901a706373cd9d7acff25b32280de86cf1dac65ac71ec0e7a2b2d3d991312b05f1006a5ba99c39c9ee31636f6404da01d45de5ccfb935d7b6a259dde62a42134e0b29c4aa926dba6d7e98d64201d40664f49e9fa3566d7699534b5702c4ead80ce80aa2b3d2bd9dc4b71353503b26fe757556ec7962b03ba6eb7bbf97ccdc9eb3a968b49179b0e0722032a3995e7ba52bf9e53298b219a069403c8ee2daac952dfaa951c0790fd7e8b29fe8c31fd436340d5a2724b534bf5af6a9634c56c342208c1ba0e74031819b7e84bb2c6c91f93900da0b33e6b8c53534e7b4593220e8901d39ace57b136b5a57a05d500ee8bdc3abe1963bb5c0bd1004ef6d4eb9fef6cc9a63380694afdb84c7b97522e211940f7de4ad14557cd98538d0454ee97bd7a4fad6cccf58104fcd83e176bb19db7c57d2c781e01576ae71d75c5d81ee5ff465181022c4e4c325938026e6b15674cbeea4595ee6904946fed634a95cf4ecab1871130a9a4b1b9939d1253d21353571b36c48b4803cf22e0e317db95aaf4566b2645404fbe54a9eab7de8b333e8980bfeabadaa56b44c0b9d8b7cb169b5b69991d024a771a3ff26c4a495664f3180d4927a3c124b5e231046c5f89edb2b32863e98bc9ea2a0454cb2cb5f9f8497f6a5d4953cc6f30cf0521e093cfa9a5a27496519b5f4e30979312fcf10c02ca4f1bd96269fd6cfdaa040197cda658ad8d4b1fc7138e0b045c29bacb5d6af1f36eafa469d22b981f0f20a04b6bfad2e5bbfc71d98ee70f70eab2cba95a99ddbe250527011d225f4586c4c27932c0b974d45c48aaf82732b004277a420349b49134b274002499bef81460fc263e4633822017485b454b55f0a69dc2025314b9744a482c992ad208b7119d8000962812ab6822890ee7848b0028f1247d4292e9cbb30467f3500bb47882041c8b4937a1041d4970387124004b74a7e5880094e84e4bcd668492040010006d3e8a9e4842092114130c1f6c899eca1e948a1e6ce95c4a389d471113c7832d1da9c1dc21359819808a1db07d1f4777b39d328d5ad2546a305361a2e5a24a3a8d511ca8d4c196ce171679124550850ea8dc7bbfa2fba44a9a5b3d59c5fc463eed642c27a8ccc196cea684738922a82247e73998c70ca012078ced25bfd4d24adb724a2ac077a9ecf65554ce1420932ddbf276cb1a377da1c1601ed358050ee81e636eaec4a65beb2f1df31886790c73329668f3174b450afb54a20005c53a19cbc913326d9199bf44184d022a4e7863339bb0994cd8b880b384cb094609f184e38694cd44250999a554909089e46f329a0c149523b0b51523b0b59522b0b595361050214218611421a2952174be057e1223ad08e12f964ec4a9b0b1714e64626231a14025086a22a402848b9f7cb4993fd8cc272a3ec8445283893a4e80ca1a6b32a30c89e5d2412a6a3851492393892e27184e904a0f321111cdc6c4a4a3d8422a3c505283e1288aa2b2034e17a082c6779ae43724241d81d19b055474d0b1642c5054ce989a8a195276191b8511693ad1732cbd89a2420654c98109918f82547090892e514699ca189728a3cf582e4fe50699c844a3b9449bbf5c2c18272a36f88c26e258a25593591163d5847362c97cd46ca6904a0d5885066f69a232036632a3548448542406a9c820859152112242a048ac3e102494c98c1e11b905a3e9682e5ec4a3801cc14c667439c150a046ac9acc88118b782045a8442c223a9713cc21381792680db1855842ec205610fb40815840ec1f880881fcb07d583e10518e9d80f6b041203d6c1e160f8a4594b13c01dd4149a28cc50928903022ce49c68289388fb174ecb0eab0c088be73428730c2888ac4e80b8b84a039b0b591d4609c80e4a0c0884a3a1a4d8c365fd26912054071587050604001bda17339c1b821ea5c2614501bbeb890449dcb09860d11c722045ac35fe2898600901a321c1589d1e50413044a83942d834068906d00e80cf184c304640629db09a80c2633ea6c5cc0a14064f0224ac101a0310881c44000280c504060c814e998442943c209027d41397602f2c22508d405299b09089028a03f3e6399b3234d070a880b2633bab46b362616ff8d13d016326d891a6f1228cc685030240b136c8100c80f8e85026941398ea40613917cc69b80b240f2196f02eae37282a94058c8449d8c0613b9fc0d13d015204bc62ff69b69a5f75496349d4d41568069ba36994aadad9f4fad027c2a6ae3f72855745de603ae56d1b9d4e79ef23527b4075496e46c2d2d3b375b8c0d480fa8ecbd65cff9dc133fcd03fe64e6dcb7d66f31738f076cca3edd6c89257f1ce51d30e9f2d4bab69f1d909baf269b52faacccd4a5a13a606cfcefe37f33359dd4174074c026d7f54bea29aa5aec8af466d30b03cd01db7bdd3e25e71de5ca9503b2c6afcd25d696eb5b8dc001c501d955fa1684aba8e3a7612004210a628831841026e34907531140203838208ec703d2904ca8ccf5351300418aa4b17138140e04390ee4200aa220638c31c410440c3184180359b1034ec18cb097eb38ad33e96ef49679ee1927cfa50bd0e8de762b5d0c28b6ea93fa89de56c6c672a6f784ca2d751314a64f32a3e2f351f89ffb2a154852a87651c6ee43bcbdee6d221330ce65ed05fe99318e7813a7e4886ff8d2cc7ccfd7913abe0a440d52e291f096056ecf981312bb4ed31f3532ebcc5e6ec96753359b8287897fd73989de4a574312bed1a7cc903fa2d8a502c8121fc976ea15444ca4bf58a8ff29f1e830ac7d030b1a0f9c08b08d34a904150cd6935c8eab494426f30cb8a630258f98edcd692d9d42ef20ba48111ec2572b18a6238de3c2dac50d33eb5b434fadfa9973a96e6055686bd35493f87bfe90d5611d8a1a592a1111e27c47fa7311023cf93bf131894529999be1052119dff8ecc482d85cf82fedc1eaf8d2f0441ba6be9eed56fb07bf3519070d3bf4f41fc008cd202858e9b6868346d537845feaabadf2ace7c7b6ff386c2077f325d18400fad1202a01c2b8b89227068420504d027802a8016c85406c8d13d12f18d0c7670f90010ad47de78981cb23a0395ca0bad4c94a40a35313b66586c05da9e5eb10621c70ccf926e9830b87e8dc3f390e5c60dda9212ac510141d5889b2cc3f3fe5e44be7ac4de65d3045165786d2ed9bf15324390d795750049b646153534b14a5355119c28ce4d6079f21b155248cf8b548c6c61991f2fc2a57c07410b4a86025cdd097c19f080131d7fd6d4c3684c4d66a4b63d214321f174653bf5e152d9706dbe6d4e23e58e92944722c183d545c94041d42b5806d64e5788f75ae38e02cee1031ce7616e05050a0102f186edeaa36fe06fcff75301e6328025eb0f73ac2c39c621b0762eb475406d362670d40a7628635faa3101b68db1223b5ace4dfa28e2c2a9f9bdd2c526ab63c226e4d79f6cb63c6c81db5e607febf48c3265a9024be0af8fa3a1d52dab420ad27fdf2fe4224c7c7ff46deb4daade17e30c55669bcd8f70a72c237ac394545c2ea44adf7c76ef6777406ae811a5377832ee2148575b1f4389649708043d111bc029faed13882fcfba2927befdd56758280036c22f1be7bbd8cf7cadd90bad23b8543fd96ff455110b5223f2aa336c72f05bbead311adf2f16910702ee258412364a30c207d1141fef91da7a395bb6ed3500f81ac82b02648d7f813646e86cf6f185c5a8986b621303a6d3cd8552f1584cb94f1ee10e582ead024b533702c5d3ea8a794ad721745fc2eea6b1adc93e324577dffb63f47e37d52c4257ea8e170420035b7c5f6c59e2170339764892dcec22f830e152b2c33825e96395ed701e78404bc0e43beaf29cc03036ab6877e0ba4821fb502aa6a79e1868e5844825595bba65430edb9eaab667cd2a94b033dffe5bc340200bda04998bac4100c7cb5cd058c5b414ee0fa7252389f4cfb2f54420d5413398e552f5efa8fb841ce3072bed4664c9b0bcb297b33b41c6d40f69ae19dbd5aa9597ce3a303bafb879f6b8afac3ad10c02e3d87abac3da4d76d98a8f0942060e4d6b22e0188783a7ddb48a277b75450841927353fa13a42a816082db65ce29b5110db1487695689e421144893ef89b018f5be7d5e7b888baa1df6e45d81f55adeacba4728fed97b8329368093521563e86c568c1d3e12d3d8d59b40fcf4ba9f801dcf174fcbd5fbab46175db95eff1d8d4726274ce8d1b0e19a1059764b4dd168807b3063dcb4097254f44b21b9de783781253312a6d330efd1193a88738962501428144f5311d1ae193849c56c795af900924a45a11f65ce164b3da2704db6b75560b96151e48baf47ce0f2785b644462408ffe4db87775ee39b3d603570c014178c459606ba463b8dd102a875deab610cca82ccc6519235f84029760e06256ced729ec2c5bdca1e29e3375efe861fd2352085f76ccc870879e5241d312ca5733a676116ab3c0d55954db557c8165ffe25cb2b687cc0546c198b6ad08b98df681bd76bc8405848a732744fa8b5fa4be596163cb6ac9b73e96e70a1c38b7b6fb9fa7f9b7392c1eb600c30c67cc8faa8ef10c2c391b2160f486a79a33e4028e80655f9ee5b15ff4028f09f70e4ccf2061098da1b80a7107c6ed856486db498979a0161b4b63682a8cd28bb47fe45d077c1c0af04d437190fd01056c88356ce17c6d081e3012df044485d20207224e88266a6a04ba0fac8de7c45fffbe9b4d7c117632373e75ea7757740f4534f80a37ff16a77712319edd1d96501b7dc842439797ee983b60418ffb874b0a32090b56380ed711e73d037c78ce6e7912025ce073abb0ad6d68fb5072eea93245bc733c95ebac705a4e857969289644fdf930efa81c893648619c80f15b4a593b416e788d4323b874dc9899fc8434e687e7af5d658fe24cbeed48088b47af9048c2d7ee79b9d7989e5b4e1199a5cb00ed4931c271c721328677524dd3038aab8419719828df6719d1c0405954e33923c89a406d48fb517363a0ee2f4f8a732f4afff4bc247f0e5534e8c98e2cfaf699fe50568c0c922064dd6201ae438a2d5793c36f3d937511497816e42d66699f5eee2a9bc10fbf71efe7f4853c07431b5ec9ed16e689dd159470f3a4bf7057476b16066de144f5a130e872009e6ac855137539bee2383405f99a8c729840cbfd8d24da3b589e151d34f3a0a66e4594d86c39246afe33aa0ab6039a496496311cc6c2408807c474239f85358678c882311c1872510048ea0196c0065193a5f47e0d92030a6e28e7144daa311412e9030764484ee8b8411c567dae2db08735050a787ef812d428fc0029219d948c8bd50a55d47e12d8140cc8f107941fdc20674d0c1213a608a1b7b5e3b7394418d46571ec3b500c9defdd9c1ef51acf4c4509a7c4bf08c7f3bc3492cbd046f56c9eec2842bfb11ce2171e0315ca60f72f6da2594111817ab19af7082d91a6834274cae0a927306db3fcc33d33b847f9e91057d73bc333c696b3341ccd9b2ec7d7406eca2513bf509b7b5cc3808ae6f4c37d50be80bc8346c4081c285619f681da5cbfd56e002d5c140da6af0779add1364ecfbfc446a92e1f90939809f4a3a5b46a81872b1b060d414451a24fffe045c06f41219aa088d8f8786246e5c01807dd1bd8df80f63bc4c3863586e80b7277ad87263be23589e9930a92211779bc291f59dbdfa400bc809d1a493dc092e09561ad848415b52047f8636670f440132d787b4b464b391567a3511bad9222ebe648e7bb1193e0eba81dd1195ced70833ae44c1f5ce8b7723ffbf84dc2629e3752022b6fbcfb671d0b3440d65e6361bdc4f65d341432dfa196b81af95cae2cfccbcf1577b01ab395fb01ee92ba4f0c4f54ea0b9c2be6c0b3558b1982e1f06142226f7379e6a83e4f1a436e5674e6f08656cd585bb273747107aa535926dd461dbb5eb827ebb172a78c0cf0494b9801d3929b8d8053a0482b61d8fe4af6ceb0963fd5b632b8aa40d233ec1209d768e450088ee2be749a7debb5a258d453e37c3b8f519ea95be6d0b130426d20b0b5d1c22a2e7f47e50eaa1513b0f7df76ade0a42b0c77f8baca6de55cfdae06fc5b41c8ce95920b6a0223504cd1d62d504cd8bc6e6e9902f3a22341dcdf08eb64e2d55246d58718f99bee019e1bbb2a67d47cc0ac6f45ca15edb36946d0881ec0c3e5c11bcd86f14d4d489d161f0b76856b26aeb20774f764e72356d8585778ab894d006f7b4fc7f1a4ef88c0c9720338d08203392da6478aa55f6f3e2f9c994b58db3b84d956e2a3051f00960cf1c7b8dd305e1bfe0e3831f1835dacb39330b4473f9a4e036a5c95aa6028b6b862e3f2c8db3f20f0def9c7e750f4ff32b705a843c1a7437813a825eab8079500814960f8217e27c5323e578ae09d45d47624f0d1f8a9e8c285d5876086897483deb2f3d0980810ceb0df7240f9443d317a8770ca31a183e96ce2ddfe11c21868ba5225890f332502edf3973cfdec3ef2b60e688407222c0aa4d9992a4c87d8bb1f75fb68f2a45b411146b8da0876200eeb74d2c2b17b8d577edb1b500ca31d4834fcdf9cc05e039e396d53e16a37f24fefbbc043d53eb58d0c6d6da307b395d21b1976946d4b41cbab8e12f8328780007867d1b004bfd3595f41277a41d7ae1120cbf44bb48d2505a0889d5e2fcf5961288a0399452b3e298cf2bf2a5051b3a4d453cc1fdb8fe4c8b3d3f50baee568ce8b20127b239a03a52d4af413b852ee3c56809491fff1ee7f76970fcc856b27a843fdf12ba6e8aac54850185f844fbd2239498f8e99e3dbfcc11452049f998a056d285010711d544133b1c0194bd684df0565f3b4cacd82ae7ad6e51da98858b2fed13f45ca62022c31f8619c5626368c77d76e333bd012261b1dabddf20c02e113fcf90b68c309a58dd01230f1502d044c6bff2bb256132662da8c4718f85f87e5ab71c7eadd16c692dc276980257d3811f6a8b626b198607c65d5f5279fa000084d4766d2c9336babdef2f4c14222a4140f8899e33602b5d7c9cfa18a99712b493ed917352bcade2e6545f510586e469eb85cf3a6e91f43f750c74aee6428a29922b47fb13a08716ca2f6a042599ca7b0429db99817c20e522d1e9979e220b5ff96e4e50c80719359a2f533eea071d15f443a5f9169a5978688ed43c7da477df3d399e880bb1a2800fe6b469f2f0f351d3a2e7f57d3e5b778e1c9c8043c7c880e9b4170f2b52f524b88eea3ce3ca4c8b46987d4897e4e20cbe43bb757be3b10f25940da65b42a2194972cb192aa950f36967bad747b63328cd682a4e7f47b703506d6881cd481abee984d968f1598646520114682f9dea76a4dd47172a118eb29b9cf9976df7ade12f95709a7cd2e3d81d6c2865766d2d646f6d61696e00003c000b0098f73e5d0113ffffffffffffffbf010000000000000001000000000000000a000000c5157b2273797374656d223a7b22636f6465223a223078227d2c2262616c616e636573223a7b2262616c616e636573223a5b5b22307863666466396635386439653533326333383037636536326135343839636231396366613639343264222c313030303030303030303030303030303030303030303030305d2c5b22307862363661393138343532343934363433303966616437363666643065636538313434353437373336222c313030303030303030303030303030303030303030303030305d5d7d2c227472616e73616374696f6e5061796d656e74223a7b226d756c7469706c696572223a2231303030303030303030303030303030303030227d2c226d657373656e676572223a7b2272656c6179657273223a5b5b22307862363661393138343532343934363433303966616437363666643065636538313434353437373336222c22307835623236376664316261336163653665336333323334663935373663343963383737623562656239225d5d7d2c22657468657265756d223a7b7d2c2265766d223a7b226163636f756e7473223a7b22307830303030303030303030303030303030303030303030303030303030303030303030303030303031223a7b226e6f6e6365223a22307830222c2262616c616e6365223a22307830222c2273746f72616765223a7b7d2c22636f6465223a5b39362c302c39362c302c3235335d7d2c22307830303030303030303030303030303030303030303030303030303030303030303030303030303032223a7b226e6f6e6365223a22307830222c2262616c616e6365223a22307830222c2273746f72616765223a7b7d2c22636f6465223a5b39362c302c39362c302c3235335d7d2c22307830303030303030303030303030303030303030303030303030303030303030303030303030303033223a7b226e6f6e6365223a22307830222c2262616c616e6365223a22307830222c2273746f72616765223a7b7d2c22636f6465223a5b39362c302c39362c302c3235335d7d2c22307830303030303030303030303030303030303030303030303030303030303030303030303030303034223a7b226e6f6e6365223a22307830222c2262616c616e6365223a22307830222c2273746f72616765223a7b7d2c22636f6465223a5b39362c302c39362c302c3235335d7d2c22307830303030303030303030303030303030303030303030303030303030303030303030303030303035223a7b226e6f6e6365223a22307830222c2262616c616e6365223a22307830222c2273746f72616765223a7b7d2c22636f6465223a5b39362c302c39362c302c3235335d7d2c22307830303030303030303030303030303030303030303030303030303030303030303030303030343030223a7b226e6f6e6365223a22307830222c2262616c616e6365223a22307830222c2273746f72616765223a7b7d2c22636f6465223a5b39362c302c39362c302c3235335d7d2c22307830303030303030303030303030303030303030303030303030303030303030303030303030343031223a7b226e6f6e6365223a22307830222c2262616c616e6365223a22307830222c2273746f72616765223a7b7d2c22636f6465223a5b39362c302c39362c302c3235335d7d7d7d2c2265766d436861696e4964223a7b22636861696e4964223a313030337d2c2262617365466565223a7b2262617365466565506572476173223a2230783362396163613030222c22656c6173746963697479223a35303030302c226d61726b6572223a6e756c6c7d2c2273656c66446f6d61696e4964223a7b22646f6d61696e4964223a307d2c227375646f223a7b226b6579223a22307862363661393138343532343934363433303966616437363666643065636538313434353437373336227d7dd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d000010632d5ec76b050000000000000005", "0x0b41d0c7f7b4485bd7be1d66066b00ad4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01", @@ -65,7 +65,7 @@ "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9efe1dce87a8138c87a9755a192d55aee4e448bf0f6c08e0443fd318476062713c3b84e1f0d3558206777991441ed0a1c": "0x00000000020000000100000000000000000000ed95c28f055a2a00000000000000000000000000000000000000000000e8ffffec95c28f055a2a00000000000000000000000000000000000000000080", "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f2300b6e4e4a41213463d1870331bc97b089c0020178b1025ab79018dbf442db463aea6b55feaee7c8500e6373a40c3a": "0x00000000020000000100000000000000000040b2bac9e0191e0200000000000000000000000000000000000000000000f4ff3fb2bac9e0191e0200000000000000000000000000000000000000000080", "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x04207375627370616365", - "0x3a636f6465": "0x52bc537646db8e0528b52ffd00589c37051eb006dd145010785625e9282c499184050d3e5f6e2c19bcb6d816279e9c183d2be8d8c083e42a98f69f80a4edebd8c16b6264c216c79f9bd0f5ada1b5cef9cda75daadeccb8c0a68e6d6b496b84104208217b6f2965c2154b1497149be6d130c3ae2963875c351af24b67246431d5f2eb7c04237451042270b13ad6e51d0db39737853929d30ea39d872084206c01841ff880f417d2b9073cd062073ac8010e76756cedbb801b517dcee20636c0a2063498c1ead8d5b1f57a0bc84411755d2bc117f2e39928a656d534cc4834fc541a0d4d3564a27a3df3786c97c7891bb81f48e383eb3cd7f92c0fdf7cc84dea75eedc84afe89badd7dbcbe9cfd42c2a47538ca414456911397902852534c44da81c4d31925214655b396c4ecfbed054b5efa65655e25afa7a3925ba9f467de60cc7adb7d1f0a76ed7c0708dea7a391b89864f54d23530bc589348b68c22ab89aaf699905b55fb8ca61d276a207712b8f344edb46fe7bad340eeec1d81558f864aeafc06ee60b5a3e10fc771e07edad7cbd18ed31cb8519f587b6c59c8811618f053355a648dea7cf47c6c59c84116ea3c37a359f161df9a7d7a3919dd0fbbf418f053b173dc6520d7f5309a55f9e6713aabf3fda46e0d25f2c76b962f90e89bf033a0d237b3868b0579f94bbe5ef2e157b99df1cd9b70fa26cc8ce89bf003d237d77758a06fb6458326f5ba06fa46d62bae947ae5a8d746a15ef238dd9a4117f5baaeebbabe362e4a648f7a0ddc0af1c58799fcb696aca1cabe6cd9722fe5d78654a2a872cb33f8b66503a392bc04699d5fe6f618f08304ef0df23d904817d1e7ae8fd35c7712e4ca71ddb15744f6ed1c186e27d29d3bd760c88134a4cb1aeb7a0d2855a9a437d875bd1eccaaa4e374835cb9f6faf35f7cd9d4aae21b74e9533cb7a96f5b50c2a85b5d39c7cd8ebd9ced15ecbb384a9f6fd07b090cfbdad7e3d15f394ed3ac0e8f865cfbf1edf1e87fc7891f48e3a3efbdefd19ac511bf02d2f8d86a7fab4d6976b84acd82e58b2916ba11151f232accf83a913ef7b0bf9fe7328f013f48e0b8d3bc22f81cc71da7b9cc3302a7eede08b58e3d1efc7e1fa731af479ffb7a3cb8ee70954a845b1cf1dde2885f6f174764a24fb2a2a8a4c7731b18cadabd3d1efb058b55499467678f58aceac352bfefe2d8787cbafabdf4f58e40b28161acdd4b20cf0e11b51747779fab96ce71b78161d7ee2490a7749fab7e5fcfc78fea1da73f708746f55e027788a8bc38ba73dc91c01dae52bd6f60c8b5f3e8ee8d8e6ec78938bd6f70ab06f270cdc090bf6f6f7b05a35f9f2edaa7755217ae4af8a7d4d717dc003efec7ad8d908f6a3f865ddd2f8dafa672e596c62753b972cd85174eb8c1614115f65453235853b9d8112d6a9d64291c163c59d4d65d1d382c80b238b6b24c8da04ce5663754c335622f277bc29769f1f5c335cab6f8f83da359f1f150dd1aae516daa59f1ad51ddda7cd405b7310594c17ce5f338fe98022a9dc6f73bd014fc980b201e08bcf700dc1453402b7425f3d2ca5f0e447ae9fb8d292090ae58fecd1ce8e7becf620aa8e9aa4b7425e59baefa99a453f057f233fe1de885ae60602e43572f5f010f63e3305fc9bcfbca4ddf7f3105b4d1d5f618cfc1d0157d56e33e3c6687f92a1e86ae30ec4d57dbfb2b987307ba3e43572e2e67a1abd235bad20e725f81e7e8aa54fa8a3bcd5bbadfd115867da3ab125dc9f8f62ebdbfeade7485b57c851df51ebeeaf740572e2e7fa1ab9767d967d095cb8cbf642fefe1abec3dd0d50cad34e32bcd069de2d442572d7f79394dcbcb0b7d8d6dfb0c19dbc66d1af80223f3953a8bda265392dc0bb602625d9430df4a9460d6a5deb2170eeb64606424b8f2619ba695b8ce5ebeae65b40ee6cba28cdb0a88bd94b0179892f4e187e6e20ac81d88af87cd071f5a60b89286427d158f42693232f4a7963f753ffcf0d5f61f7e00b36ce5f4a86e3b0a3b9dbe027ff2e124575efaf43fc07cffe1407c25732050a8afb8a37a401d88af34cc071f38f0f427ece5a7e8830f3efcf055f61fe8ca071fbed281e8a107195f7597a19d1e35e3326ac80071d45730479d4e00780f74757a8d1e8efa6a7b8daf9ada784b4b8439bd0f3264bcc68c19a7b98c1a97f1d57719f23efcc6572bbfc1363507e2ab9503c1365e0388dff84ae635be92479d6a6ae86b50aff90a7c0d7fc5bde63dd0d0bcc60cba924157325ee334334ef355771afe0a7b0f3f7dd53f31007cf82abb0f7405001f4ee90a009f31e3a7af4aa75f69bf41573ffc701b74454357346f69790d5dcdcc9c86ae6aded2729aaf5e4e435733349ff9cac63b8a53834e6143572c2c9741573374357319efbad3af285db1d438fd8ae51c45b228fe7620bedae8138be20341573fd02918c5bd07badab6bbd095cbb91ece7da5510b7074b571afa1abed9df6eeab9a831489176ac4a2f827baf2e1e500a02b4a57f43d80b7415735689cd2d5a681491da2500506714081900aac82145650c10e6e700150155440e071226abf02e94a86eee946d49e067d44ed6168b628fe0c1932afa12b9a98cfd0d54f1180a086222937c8c1148aa092f9798108ba70822470a10e5264a092f94a86ae56e867a25944ed63e84694006878aafb8f9abe2a512616c587a1ab173a05ab8056ee4257df5be814362aa0d259e86ac5fb47573f36c8020f59d8808a186c7883aab45e3802420d4ef0022a49a883aaf45589ae326a43a2a688da7b74232a0034cc51f74d737474c5d1294e2aa0f98dae760ca18b36f4408c2b1ce940a5d129ae02a2e1c51c8280842e04d9410d2aa07ef655465718fda2f8ab8b7e11b59f74230a070d6dea5ed2d3a2f8910259147fff1395fcd038c610c11a7eea9bbe8d9608b0106bf36b3bc1f119447d61266b5f66d912dcd6b5c1313fec6a33776dd52497c760ac5eb73a78d8a826e9485c770ccada1dd51dac2661f13a5292abb43a7898557788a8dc43b258957b7cac8ebb5d1d59df845ce37df88a90345bcfc756f93a0cdcd6ac6fc27efcf6f9a18daf1f8fe8138934ebd35ef669690f6e677cf2367d136639fa26fcde37f342f48dacf326a23a5fd3375d670dbb1adad4f9ed54abc2ae86a63afff54d7fdea56fe2e7b3bed9cfcfaf8d49896c8b9970fcb511da74b24f2cfb0859c445c3d7eb597bdb2bb24f34f48995bffdeb1b0ee3304da3a1f6ed1a96f50df6f8ae6fb4c77318c895d3c0edd3f6a93b7b4574957dea68d87d3b066eed409f58b573dccb9184815b3970eba681364c95bf8b23de147e9569787d3e9e8bcc17b895087e06faccca5f2fc7a5f6b9e5ba7ba25e5f30cca2b7bdc2e7a4b772a5ebd3fb148fbda64f184ee3c405251872dd5fa04fac7b06b33ef5d9cb59da4dfaf5a9b3afa66ff6f136fa66aba96f5ee34fab23d6f8b511379e35e0d6466853531b51fb6ffef06d2b8a31eab6a2c0420d4fb54f80baad28886a7b39a8afc562d5b0abfd8f9f651b53dba8f0abe1d7ef6fdff4cd7c3f6b2f27d2fde6d963c04f9de7b89be0d60872e5d89be726e8c33b39b24ff23dbe3acf9e115be7d7cbd93e855de5d6bb68f853af4730cc66044359afe33417c150011e46c3272af60886dbaaf1130ca7114858000813486afcf6297ca2c6c7096ec5c09d58a54a152a753e82e18e2a2f3fc1adeb1d81d578813b589d34e41ae90e57a952a54a0d7f6abc04b74f4c659ff87d717443778c1cfb381dbbcf97efee8eefc8fcac32a5f1c197e748438ecc4fe0c22c7e2ffba6bfe72238b772dc45f0aa0d726530fc40e573cbdda430049523c85fafc7ac7c9c8ea0ac0d6efd69fec16ddf7069976370bf3e57dabee1bae762c75ffc8ca6824f3e9e1fbd1ca6fbf523d85e8ea45c77b26fb6ee39d9b1b71e037e6ae3f40f3373c1ad8df0359e5b191fb7ffb64f6156d9e3f1048bc58aa2f2b9eeb66ffa7dc3dfafb77d8ac76906659fe27bf8c2afc6f7e5e33997bed91acf71f7f5cdf6691fefd2375ce34d7dc38f5f2f47824968d49e9facf6b3da94c6475fbe2fa90f57a6dba750d6fd7a3df84dc33e1fa7717a6dc4668ec250e5adcc7c97ca11f9f8db43ec97e3b6c6177e957fea9bb033f54d78aa7cfe8dbee1caad285895efd2375df9db2956853595dff1d70653223610e016fcf61f7f316e99f8c2acf6bfbee1f74dab836b3feb6d114da97d97bed9f7d7462380db19dfb6585bd430abfbaf6fd68b2956d47dd637eb45144deabeeb1baefbedd4aa4297ba5f1b4b89bc6e8d1f66223420050401059bc482bc82b4c26c4d24cc23481ac819c825c827120b5903a904290549348b30bb985acc214c214c27f3065c86e983f98338d447dd8609845882b9c57c327b30a1204f8011818b7c7a260e660ee60e269449841984a9839882e8858885988558855814951093109110bd885dc41e441ec4560442fc41f481123a494418442b6215718a3882b8245ea1c5e8319a0e3d876643bba1cbd055e8a29e424781a1b4149a090d831eea2df409ba0ace03e381c76035701ad80cfc053e438c825bc03ae0252c028e82593f5084407e70808120a403413690010bf00e2617dd849945121c378018d23ac08480f1200235157d4553e1ba436b61f2c003571b2e3604718521b2211ac5345c5c8826b8a4f419ae2c5c5a8827b8b67075a1e1707de102e3f242035d60b88c2e315c58b8ae7059e1aa42b44224c15514a988410dc64585f88418252ee19a428cc22585a8c51585c8ea18f408ae2857132e265c4bb8beb894c053ae2eae225c44b8b8886fb882c063b8a0703de172829cc29584cb8bab7521e13ac265840ebaa05c438864681a5c5b5c40b87e70f9e07a72f5e0e2c1a5c5b5834b07570e2e1c5c4eae2cae1b5c3668291716710d570d2e1a5c33e8315c44970cae185c308853ae2ba213ae175c2eb85a105d7035e9375c2cb85670a9e0b24216492a5c29b850709de01aba4c7095e022c155c545c535826b8a4be892e20aba802e26d7924b045714176b56997998789863cc3bb40da61d661d26954987398729872946b360c661c261be611e4d37cc364c36cc354c35cc344c34cc29f30c8d82598626c10c6392a1b1e82bcc314c314ca319860986f98509c6f4c2e4c2dcc2d442cba0bbd03568a30643dc42fc02b381c5e039301da6156615a21166519b614e413699349841136832611cb4095a8b5e816c4926328a3846a4423c8a60886a886e886de827b413e219221a621862172217a2944643ab214221362132213a8947884fa20a3a4a6c416c1259105710b510451085a214dd834e434f6932b4183a0cbd86fe427ba177d03c6827710a8d85f845944267d137e8273d8326ea17740bba4967a155d056740aba043d450bb1165c07a6c2472c078e03bf81ddc06d88603018580c1c4664c25c6029cc05db80b1080108620c76901c59824622705c972f30b48e3a3d413af00349101d267efce038266144e7c78f6d59a7480782f8187142891f3e42747886246164c88f1f3219164cf82c6144a7480d564747891f477c7ef830b1c4101d0fa0321a6c4f9121417c7492f8a1a3a3840f19d11e51c2c8901f1fe0d17162e7034190782683d51162e488911f418c1c71808f11278e08115265643148e288109d24686430d89e0fe810f9d1f343c727088f8e119d257ef47c40c7879123437a7a74220066572c922682f8f4e83431c4e7257bc1f604f1c00f23438234712409176c123a3a3d3f963032a488124a38c144cf8f9e1eb216147142899e1e1d21429ce8b19135d1e13922e4190bb6a7091d9f9e0ff4ac40a74812469ce8c0911c9aa9608d1c19c283c4c8912114d0e1414288cc8a4d42c7c812437a8c38f10395a5607b927022088f12343bc1cec886d64789213c4934e14413439e08d284097c7a74922872a4465682e5d1e940134e18f99144101d26c08c04cb840f129d247e2c61648811277890fce8f141324447880e8f8dac8afd004f902686f02099c9a8581d9f203e3da66c04ab2324088f8f101d1f233a4de814f1f1d189808c6c8aedf13112c447687d7a9c089308f22389224e1c61a2e79449b11fd021f243c890221d7002c90f9f2345906441dbc3a39344101d266a64403e46749a58426746c6647d7a86141952932dd1f1399204cc44b0428e2419e2c48ece0f1f9e234874786cb228b64767092341786832d6f6e8f4f4e81869e248124682f0fc2812a403478a2c4103abb2468e0cf109c2e344123f7c8e14e991c1f2b03c477c84e8f4fc3032e4478f8e109d21487e3c11a4896378581d100ce9f9f1019e233e3d4398f8310449d5111204494f079c8880091b637b748a14092224893bec124686204112a4891f477ef80809320449edf111a21376e0081f303bac078620a93c3a44788e54e00810abc3eaf8044962489120497ee838a1e3c403249084ce124b049100101895ed212244870921626c8f8f111d1e1d268c0c391607234394a0c1deb04286f41819c2e3f384ce8f0f14418224c80f1e9d248a0c71424544c89122aa1aec687b6630376c901f35581bb6891f417c822411c447a7012bd81a4030a44890213e438c0c79c18a968810213a4fe8b06054589e2309e828b002816542884f900efca079c00b12df112c0e58258e1ce141f263091010f9a1e3e30492268e088159c02271c247a7e747123a3e3d4ef0f8fc4822c891222c09581f233a4d2c0102223f8ef8fce8c091221d8021e2838275143b28aafbc36d8bc5aafc1365ae5884580446c298942f524a39e345becc789152ba64734e2fce20b0c89c95da25632c4ed364662f4e2c3247e69d73469e3176b764ce226fc73927c76e9e33ced8dd2c7bce39d9cbaeeb62bee6755d1763d87571cc62dc9d1c4bfcf1c7db6d97766d0480352f2fc69167dc18b1c893374a2ee3ed8e8d61919739f2caf2eec6e5ed00c419b97b99993366fe22ef0a379926723b7130c631167997638cccad314f66e696a8f1f6c6c8bcccbc1c472e6a3434cc1c73cccc5a8ba669bbcd18737364668c3976e4668ee18ecbd88ddd5d205a783b76738ccc91bb5b36f7fec0cccbcb8bcd38b93be378bb7b23a3e47acd73e7c61377cc1d9763dce5dd8dbdbbdbbd591627c7e58edbbddcbdb2ddbdbccbd97636bbee68628ef1db38232f47de199b992377631cb9a7ec9ec9b2d8cc729b1d677cd800d0c3ccc430aca58dc6308949ac5b766fb2bb3b76c796db5623b3db71cece9bbc456697cd654bb1066f1c9999e516e3642f9b5ca2317ade94cd2ddc2d33c9cc336eef32771a902645acdb1fe039d2844e13970e1335304af838f1c3c7c8101e2432ae1d804e4f8f0e0f92268e08f9c1a393e488101d9e1f417a9210a2f323082237430c0089109d94cccc00787a6ab0e810f9e1f3848e91193d3e3d439ed0a96962888f1127787e08e919d20425222448078a1439c2d3357144c8a9e309e2d3e3838c0da200410c31c40092d0f971c407c9077884d478cd0ee0c8119e1f49e8f0e824c1734467088fcf0f2c4282f41809c2e3f3c36748131d70a2e7879121419810a28412475060101d9e19962564629230a2830449909a95258e149121dd0c31801f03d02112a448077e1f278a1ce9f9f1012586f0e824f9d1e3448f119d1e234784f8602aa29344a7c88f278234f1630923439658e248111a390610c40c1a3b80278628a1c38384c6f8e8f4c8c0f004d12922e487ce1241788ef8f4d09084b8f9f1c4110ff8fc58c2c810267a8230216375747894a849624427621bc40f234786f4f0e824f9d1c40f9e233e41841c295224c80f9f2774662431a213676854f46a5954a2847f5ac9cf0ff7135302f2c33f5ccc80ac12253f524903d91f25181025fcc3407e7881ac12250d64952851f2f313812861251c81ac12254a18c8fe5c407681ac929f56f2f3337f26901ffe61204a7e7e24901fde9f9f9f08e4877f1ac8fe3090014421de5d6ea227c806efee264f2a106f41a29b74936ed24d40178f07cc67649f898580f88ae723e6e1cf93ea5d6e818562eac6af4b2d64010b57b042157ca0615601408504f01e6868aa2b00900a53904214a0f004270400944d904c904b905f4825c824482fbae30025128e60842e8a4084d5c1c5ead8d5b112caaf6e63f178c05cc62f30fae6875fa887d9e9e1e703001ebeca1e1e9e240d9518552068e8bde69fe723e63fd0f067a87a2f793e8ea8a112a3ea3d3ab98ea26176a2e1e7030d4d360e001abec67ba0e12903c247e3a184927d261b347c0d25941a343c5518702b05570e822e3fc8721a60e91ec8ad3a039401865c23187df37a9dc1d72998d44c51450ddfb43a645647926c667524f96856471253e55ef39abdd95a7306352b3e9eaff26bbe79393574bf98b3780cf8a931bfa4f44d0c2dc244ab27fa86e6d799d5379b9743538489be99b9e6e5cc9c9b990137ee2d2ddc39ee68c0acce80596522a632d575247db39c0c6802fb8a3e1de34fbed090ebfc75e36186e3e11780cb68dee50130e1f86e806013b980dde4e5e5ebf1786989094d554289a8eb5d3ccb37908b200ff5e93a0bc8427dbaeee36b79c842f56aa9a24fd75b0e25a6a29388ba9ec5d030fb60e8a407f818d027223eef67d5ee6174c25d7697c7bc1c79c95f467d23e9f5eea57406b3bb3491f4725c58a86f587e9dabe81becd779a86fb6462f87e51c0b0bb8616761c1b0e334c835abd7d7bdb2d23d3bfe563ebd9cbea2e3d72b672f6745763292c0bea2a32112b5fb06864dd4371c0db972bfc2ed253e5702bb499fae4be0e31e769322fa8af032eabea2d5271b0ee4ba813c543db00343246a111b9bda5cbb495fc160e951b6aa935a02b79240eea24f57ab5e365f3f945032ae5cec56c0ac7ee0d6ad5c064a9b2a2b27bb0cd4bacafd9ad237180db962ef1eaeaaf7edd48d7b34e49e6560043eece16554af7357c7dff6cbcbe1ae81fc53b133187695fbc40c6ef432ead3750ef4785c61f4e93a769c88815c39f0ab1b183ec162559f958c9b9d06caba5e118c815c2fa3bec97efd0a037b76d9a91bcfbe3615a76f80b28b465d5442e9d37509053b0240df78c1f135bbe8d39cad3ae7933ecdb9459d138b3ecde9a4ced9a44f735e51e7aca24f730ed5a9fae2afef733e194629753ee9b0a3d419ca29dfe47999eae42dfa347922e527d414e7bc262b1681c386ea75ae3fd97ab205164e9a5c51afab8a6ba85ec7e95d1d7d267d2a622bc664715c5f2f528cd5a7ab4329e5fa825e5df4e97a88b1eaf59c6f5e0a1f492803800205ca8c366d190f403689a9d9069e5362aa63d4f57e68ca6838f3502fd904a3e19c43bd64139ed1349c61da6868ca988619a3c2af865dbd1e69f8491aca1ace29f5bae694d680f4faeb15c175277e6bd0027dba2e413eead3759b4fe6d8d646d9a21833ac398e3b0fb0708a8f9238e1d3c3b383e48891268a10098730b184123a4908e94010203f38b0010d64000317b0c0ead8195aaf2fff50af6b24d04cf0e1749f8fae0fe3a37add021736f4e580e32fe34f7a395fd627feba3e31fbe02e5695e73a6ed332ac5b31d551591451f232dbbe0c637e228bb2ef34b170d2e48a2a8624ab4f5232a9328ad12719a954c94faafc8e2f8c454f88f8e4932a9f5354e5650d65b7aab4a2f2c81acaa22adfe0d727f9d9f549765f4d9fe417a7d9cb31f549dee6ebac4f0af8f8172bf694028b1418f57a8c42e5f3b96dc0b72d2abaa8f1f2548c41c51a64ab661a1872d5b06f9fdf6d221574136559f69b6fbe69d87d9ffdf28eb81ef93831facc8a5d6ae7aa9d011f7722f2f161913e11edfcb0d37ac8c733e0e3a80f57ecd7e737eac3556a340957fe462f87df5e4efc7a3eb8f2334a44b66214a031a410954f95f9a6cacccca5eb492d99ce5f0ccc717afb865ba4162fe7ceeffaa63bffeb1bec7ccc5439d3c3eca69b8e1df372b09887198d79f72b0452895c0ff9d7af739f5e0e47f7632abd233030ab1c98d5ae2f413e7f9c7c6cc0ca395053419126aa4c8d34510da130aa444a2f5dbe2f991669a2bab2d20212098b2839aa4678a87af18cd3e7f8d3588648a499196d061f0f55798ec4d1b0080f55eef1a42e76242547d1e8e67bf62cebb067637c61134dc949ce624a0bd219f071efc79c2be9da498f9ff9a9f22ccf854f68accb6816c5273394e325b8f3446579a8a492c01dacb27cbd1ecd60fcf472e2b35352f6259d038d90fe12544518710ac7a40a265630b98209164c76909d2a83a7ca71c7640b265d30f982491498608109184cc2d8d326446550885a4515d1239dbd22b80e217dbd1ea4bf9cdbba065b82cd60af67eac0a87d0e066be0ba9b798d8c191c8dcc7746cbc1831b513268f8d51aea1d118d68689855ee3334cc6468f855ee2e1c77d331ae017c8e2689e7f1e13a7390851c64a126e1aedc77620ba2600620d4245d39cae3232bf79da5d2450c4c5093c8ca51099ace3b346ac875897e07863fb54d19c7815965d067d6e673dfd143e56dd5acae614a0db33e078591653115c3e8b8863a1f7e7562817b772029358c46a1e4bacecbe1afc7d1f0a772f42ddf98028fbde3161a6634c368f8815f95343455d054a53c0d10274a30e60c86406a18736e8b01afcb6b5e8e3c27c1fd58821cedc3809ec7809fcad4f37cd0a852a54aed73319d0477d42b16b558643bf8b63075f12f16b52588824ded1260614f5bb51d95c11d9505431588ba5ee0410b95e3d8bb2e277d33dfc21d639c71ff3ad7e0e5a44ff3177811f569dec7d70f2fa222b2161a669d46c5b70229b288c562d94035cff17761b182292b385a0115d6a25800b4a83ed7435daf012f6f0f894825a290d888e254eb4180558c131becca17d18545a7ce62b144a09a7f4c35d1a9e5a14dbdf6faea95d5997da617d0a7cf35f3722ebadfb66a13c554349a2e34cc5a68f8d526622319b918a3910f1ab57b5cf7a9ad1240a92c60f8f353b90b94eb494a842fbf0236183651a5f126953b0d301a55e10ba311531a7e948249dd16d01740d46dc5c08a1a8d62189d8a432c16ab05aaf91708f50b86fa054dfa05448b636b9018755b415fd4f022aaf300a8db0aba82bd6e2f27bbc2173fd7a8cab8523a078659e52e2fa774ae04eed71c9b500218d4efa5a6459aa87e2f793e62134a7045fd3eec385d02b3ca71b7026efdd69344b8f7496096ddf3b26bddc3ac729486bb8d178dfa346ff3f1c368c4d11e362470ab072a39aa1d18c629756ae734703faea30cf8a9dc7692e7032bc1155072361a16b115894ded8359cdc0add3ebf143544307b4aaa446d6a84a5a648dd6eb81440d7baa14d57edf5c9fbfb9a8119bdab448bd9eccb40d16b7333e7e16515efb329a4c35f1327645f8ccb3582c9fc9056e7b7cdb1a0116ea3c575a1bacca3865c3a83e334a1eb1e1149288ea471ae65896542341142af923469a2842241cc2c4124ae82421a4034180fce0c0063490010c5cc00215a0c004241001083c0089d5b19a09be708bb4a10fc93ce23e1231b5aa6c5559dcb8718b78381f295ff60d9149697accc74f1a25d8717781ab5a8f87646324e096466479567a56b367aded7b1b7df37d7fea1beffb1b7db3f2bd4ddf94be17a26fb4ef73f40de9fb1d380ae89bec7b23fa667ecf80bec1be47420216e85436c462b1bc50edbefbf4723aba1fa380a8321741966731660fe3b367979f91e519f8b1b09058586808a412213d6439e9a4972e59a8cfecfa9469dba7ec38bd02865c93cc5a7add01524b340452fa1ebd9c8fee57a2ec1d71168b55bdad59d5c0ad2530ab24ef31f588d27eaadac3cca66aef72548d667dcaced10ddc3e65f40243aed967341514e1a19a51233c54432547958876edf37d0d947de22a55aa4451335a84872af68e62075ff469ebd609662b7c41e91bf9eb7bee02b74a30abccdc76130c5f2f1a72bdce3c2fcfad11dfb6968c5165eab69614552eebf893cfbc1cf9cbcb89a0a94ffd22beeba1c9e68610ed1551d3a7fef513d709be9e622a93efd774ea63b1584c542d6568aa725bfb31abe234c75eced7a7ae4fedd22724724454f3f8c21cb53b25592c21164bd5f567b24cc2d737a5fdda08e390fc825b7753a47b0fb3eee1c73d346d0f5ff7bb29ede1a92e89366ba3af211369343cd50c081f2b6234fc7eaa61b33e16a34f914aaf010ca3222cd4f8f1177d8a1ca57ef33371fe7abf419e7234df5ece64af88b3e6e373be7ec844599f222815f0c5a1ebe76a2987115851c3cf7f8bf81c7ffdf57214d0270916b155018b63e2f4697e6b8e2f7c9d0d4695c742953fc0377f56e513f1f5cfaafb790635159ccf5e0e174db9c1174d54e3b7bbfb7bc9ccf7316552cafb98ba39e77d4cdf755df731b96018867d6fcab2ec3eafd91b1e9e24a6aa3d4956b5f3f8647527e68155b5fb98aa46b98a67200b81cca44ff117c8ac3ec54f70053ed1a778067d4024211b759398da1ecf46d1a8c6185935c6f83b7c5cf9e11e6d0fb9a8c6f7e4e0becdcb1e226a33611294a99694a8b0824caaed4c824eaa8d32098aaaeedb830ca0eaa8167d0e64c24428876aa3419a6afb929807964a88866a3b9325d8182c964aa8a4dabea44485c562a98258b5511e8a28665549c3a6bb38429652e39986dca4c63daa319e89d5d160d31d226a3fdcc1a9fd3b7cf3fcf8c794169326b96adff34144ed2611b53512654e22aa92e049446d0d4dd58a6fbda85bc35313d5ada124fe607dc981dbfa6d4b488c9ab18a6ac632aadcd2d8a32acfdffc11234d1421120e596db3dd2594d04942480782fce0c0063490010c5c60b95780021390400420f0008d049f36f4c95f6a48e0cccb479424d29cb09e642c28758619ab5567c68a52e733207c51cbae6dd58dd234fca9fd0b0c5f2fee61b669df4d211151f2190daf638f1e8f8c4554af1381444c759747c0017618404701361a7ea597c0d4cd104210600041900410001c3780f801253dd00700f460a30605bf3ab6ca77e0234a5ee73f93a68a132fa130a6d01a1635bf6bdaab5567d11e65ada5805b1b40eaa421903a65dce6f91d49d7fe3fa648d4a31d0dbfca5153d5a8f8fa1a0de7b7234e9c2056c548c62dc3c327e3a6d1f055bb76be0c33ece1773d34d56da3a1f68d299c886a8c52ed045fcf961dfb8f2956f54ffd35d27a5ae13a7f98d016150b5788b17d7175bb7bda322ab6ac3d6d041f92c8a42d6b139288ba1ebd92e438ee1a4cc2b5cf434c2a5dabe20b7988a3e2487a393b5cfbacca43317531299eaf13033ad54279884fa916ba61843c4442c2edd13cf28eeaf50c0f9fcce433b96567a9ae739312895402c3d7d22518beca5f9be23b5da3e2bbb6accbb8ccd3a8f8e44b465c5b363d1ea412a89d046e3dc5d476161a662b34fcbe53bdae9de00b37ca96753684800fbb968559cdc2af660f4d35e3a19882a14644d475eab9945a28776d04dff7f870a39ccbba2cfbbed0549786d33be2acba0171628188ba9e7d23cafb7a103022a250d73f1af6e58dc84a34fc485186bca16e881baad7a3c763fb3c4edcb22cd3b2ecd8716286d1e521ae090301be6d498185ba2d202cd4bed93a99d4b36a0b16353bcc85aca8d9fb625429c2a8d9495f1a59e54af3fc5de74f3b7fdbd07cd6e4abb34376529b7e88efac7a56d5dee73368449fe41b2caaf21c0c0db9c21c03c357ec1d18be766701c35796732b2b2b2b2fdc537c2bdd352a3eece15ffa997744769898485d68686279e186e940ee2ce075181a32d7755d67227dd7a8f8e2c3b37c63ca25e4638f2c4764ef962e3dcc621e7e75c5e5a1a9ae7c63ea1135bf42439f595bae1df37c9c55bdb780e14ff5fe98627989c65017ca8263a2a4cf3b4e73eb1591b1589569f8cac759b946c5a73d5ca315047cdbb973dc7a3d6854a92cf7c0902b4b77f7c32cfc42530d5fe7b5137c3831c5aad9751c173bf6c2151a725df9f706c3d76666dee26336a66acef230ab2c0fbfcaf2d05459284e4cd5501a3a4337a260eef28d2919ba11f5f2966b23f8e6c3fef5708d8e79392110566539c7de039eb00092889a4722a2e6d783c046147f3d080089a8799c889a1a0abe181af6b16b28f8e281c4d4aa9886198cd10bceec5c68f8b5d0d0c402862bf73ebd9c70e5a5e3c495d07bcf4fa5f141a30a1112a5f191dd7b76efde1bf499d53b4ec4692fcc6ab8ad3acf71c7890c6e652f87c3aa1855a66124aacc121a8a4d8ca61c516945299242e4e40994264342cdeaeee66fc7899897b3d1d540cd8addaa1de0cbf68b2a8fd1ed53fc59f5a29a0abe8cc56aba5fc662559cc669af88b36e9a8f5c5a460db8ad9771bf6fcec709ee8c203f7a7df6dacbf969e62834a201e4a7a96f8af0508dcf7226e8136b0fac04577051f9122cc243b2f2e5d90bdcd2f8e277b29aa4a6f6fcd47ea9bf3642925195e7f8dbafc7591abeac0d5f388daa94ad9ac9e1db871b51953b250a89f1edb3387cb186138c2abf75e3bf18e9ce13b599f6c86ad30c0e1f4e677582c106d82ac1101f46a1a28f1f72947eb6832fcbe2e3ba0f6514a12ab9c551aadc2955928cd0708550edf33654b1cbd5d1df3758804fca56c59e71f1c52c6ebeebdb6281943a13665bf8c226aafc2c0a1fd77016cd60f77af474431bd8b00635a4010d67304319c220c318c430c300862f80e1852e7061b7cf2d68210b58b88215aab03a76756cc5a8a682af89b0675ef89a55b7d5648a56826f3e9c4515fb2c8aa9556d349c522a368d2a96d1704ea95813d5ad217654b1af0d8c12d986ead6f8912cbdc0ed8c2fca53dfc4c71867b0831abbc61823cf931acf3df3e20b79fa3c4978b836f5e1ea23d67ed324f3fd497dbafa28d53e8d19326a6866644c31302f2e2d2c2b5f89e475dca665d835656cded531a3a9e0dbb75704d7be04b97e86b55e8932129ca82b08ac0099179a13b62a705ce8c4e0a181f486d2d6e18b62650a9613b4b4c065062f3880f1410c17262f649c3053051a2ed48841061a662c8e7809f21bea7a4d692c8e5887aa95e0eb671bf949c604272410aaf2f25550a9fdc6ce955b191f099ad4ad5bb9d2da08fb49bdaed17906431eaafc0886af9189322ebeed33375f3cdfe3a15d7e7a3cb4f771a29633bf81fb65672f073b7fdcf92b9d5b6fd2f0a7ce6b60f81f2550ac4200820f3ce181244ef8f4f0ec203962a4892244c2214c2ca1844e12423a1024a4514bd7967cd99b35f74cd437dcaf33167dd337a55f5e111b0db96effce60f8ca59445d67f96e6a25a2ba7b3466c8a8a1999161a1a12906e6c5a585656585865f89e4755c741565e84a1245543c4825cb4457fbf27218ba9243f2543e61919134a82c923368d00d15e99bfd6b65241934af69b9667ae92c4425a31a4f228279f6557c1c8ada692890888a8fa12b24222ade85ae6c56edd1553f8944413754de37ba8a4711153f4363d1b7c80693d14c313775c75cb877713b17b56fbd722d0eb14c74853d86720b5d2189a87816ba62a2125db5d1aa8932ba8a2d181ad788e87ac15ce84a0b09b0bce5ab951612c09e7d252484aa847d15bfd24202a45f5f75abd54257d95928b7e88a9f44543c4757bcd1556b741557680fb1f8c95ec10875189a5f46574c823a5589aeb49040f68912124235e92aa36c1451f1f3185d71d18a44bbd5e255494a957413b6f0010aaa30c60b5493f2117747459c911cda5a9a7c321fc62792a549a2ee61349af447dcc348941d6d0f635147ff84a32623ed611cc2beaaec616c6dd444a4d1af48853d8cac8c7e43f2abc268d62dd545b388ea4fba2a4937a226fde176110347532363068d16ef4133bb83f42552a84545fadee50526c6245343bf0b09412a793b844c2bbb43e82cbb43e874ed0e264b4a2a211b55cd83bcddf1d592bd8211ea80ed0e21a9ea760875daee1072d97687508daadb216443d5ed10baa1ea6abee4b2c312e830852040210a95f73def0ea1ac7787d0177787904955b343e8aa9a1d422755cd8e1abae22664b0c119b690051b541e9582081589ae56ac8fae96605554a44b4184aa44573f3b488214aa951444a83abafa001011847cf0842daaa856dda520425543574ace7045179a38919202558d779247574242a83aba5a0909a1aaa1ab6cb5eabeaaf9de26a63c3aa95482931ada5820a2facdd130c3361a7e974643535c291c846f5bad2935cc6adf26a684a48a49477a50a6f25ef37e56ba102a2625ca24c846f5b5b07ce5413954a53309ea542f0fbaa17239463315939f49d055a6c71ce627199a07d9a8661e6452a17ed14ce8533109caa1927126419f8ac6836c54331e64a3aa396737544c4e834e2ab0c6836c54f4412eaa3ffc966055544c82ae620280f7701b9f343409b9a8980080067d2a009c49500ed5e94126950f97347c8a89508d8a098a7e57b9ec10fc201b2ad312801fe909246283e0fb001a6087e00300d4b141f07b00732c01f836402176087e0d50001b049f8201d820f820886383e01fb4d921f834c0991d823f039cb141f065803436087e0df80d824f037a1b047f06246d107c19b0b441f04de08d0d821f039e76083e0ce8c306c17f01b31d82ef02761b04bf059c1b049f05941b047f05dc1d82ff81d706c12f81d806c127813d6c107c0f0477087e07026083e0193f5b732368d520959aa2c4929712dc731ccdf5adf319c844285365d78e8142990afb82a11209344b955d038372a8b024b2ced3f460a23a69a4a1129a8b22817dab043e55769cbe2eba53aa936691fdd4289955331003673715a916c44b5048aae4234881924a7e3746ba53aa59c8ef1658ddec8215b46a6005f30ed7f81270ccbbbb328ba39b7741d3e2e833c840dfb6a08851c34ea6c50593ead2273a7046beaeeb05942e760b2d586e37461a32abae8f52958f60125965fc6e7c6a771747134e881aeea89b227dffb9986abafbfe6493e3a76620f60efca9130cb9d2f898c7be3454a98860efcaed04e427ab76953918aa7dd1f0a7924026a407ed0621cfaa0b9c2781ab9aa4799cee687c70dfce7d7b57ed88c8799c0fcee3e6b3731a185ea7e9be55bb04693aca83e6e049eddae580a876d5cec58ec8768d93dd065e32641e5d8f8ec66b747184dae3115d3b4a24dc2ecf55a3615722f23d3ff5f2c195a3dab5f6b4167cd8c3f9f8aef235c4288d8feb72521a791a497dcc5fb4c7a492f2e2884af867eb8b0a9c918fbf7d3e54be5cc6e67771ece5198cbf301d917646e323d25d1c187fab4cb9c5d1bf401eaedd445f4751577cc098efc0f17c7c89fac22cab82b97ea00be8014e0bd67c833d5cfbed19b1556b1e5e1cf33e59ddd92a957b7b3cba6fd388ad1cd3dd5aabf2dd8f6a77ed1c373b4d03190c351ff2ddd7eba1bd3b4e17819d3b83dc35b07bf47c643cb233ddc5c1c7e90e0c9b6ae7c0b02bef93ec3130f4e19f8b5b0df23b8052af47242c90832951821169aedfc609081362d4b9696b98939979ec17d7a3119d05fa26346d1406f40dd7799bbed9960e88ea4601a3ce1a6e18755e4720a9fde5fb5cb541ae36fa66823c7b9fcbc78fdabffacb6fba7b83bd1c22dad6b1c723c6301e3b87816108eaf515149d29691afec4d568d82792d1307e1f5ed7e371faf27a440ac5d57fdf3418cf71fb88effbe08bfae0639fafe99beb539ef1b0bfc0e50e03b7958356bdc0593f17ae3d06e0010f79c8435dafcaded85f2057a9ebb1f646b3a2a8fc8e475a16b8651a7cf2f1e3855254af37943ab7b0ab83a397c335f8ba07755b3da8525b06755b5a18d553dd961643953daec1179350b7b5c5132a7f51b70584a07aa36eeb073ca8d3eb71d5d0891330410a46750748e5a318d41d25a41afa8c010c2619d4d0c7890cc650431f2ac6306bd8c38520004184a21af64029aafce9f5e0c618aa6111630cf5c858acad52b987ec767574ab63abcb020833ded4c5a8f885328636000e14a315c0d68b86fdf67a340d95d4fe4593745d82872b5f73d93eaeeb322f8924ad8e2f808850774aa5d5b178a8f1171b606b0caf1a41cc0711a2502f1ed7fba762730bf5fadc420d7b7eeab5b355aa54e99fdac7a2c085930a56b072dd3548a362e0dc429217497ddac7fbfa0489b4570457a918a5e9218fbd08798cfa70b5c54594ead375d2b09f84ebfc4f05eb04c1da3e5c65a692c5f261a75960c8364c385c2bc6ae0124ab869c01180aabee7b75d8d47ddcd4aaf61cd6498fc782716559966131cb6467199f48fc2e0bcec827ebb66cf085916fd66dd9204ae51a65e80669c045751922c6080661a8f619e85b2fb628aafc1823a9ae1741108118cd5ecfe66c71cc2fc840f3abc96c7584c169ab2327b2101ccfc7246e85f8b665032c6a98b5b86852638c2b8770cb4dbe30c3ce95e2638c31c6b831ce293325dfb66cb0459dc789d7051ea7b13716313131307fb9cb5baee463f9cabf971e13131313338719a5ec16c77c045330a5ca20a21a5ffac2506d155425df7e310356e5afd44d82900f6a98d5d5717ddeab9b0429d2505da614a5528974efddb9974aa552690c1cc76de7388ee3a4708b9ddbdde5f61607d62d0eec0c2af9aecfcb63d8bbd5d1c7ee353685196db824b3ee5cd69dafd62c8e245d5dfa7419ee27be2f2fe7d7f371c963d4c845c3eb45a20f8eeaa4d7aacaf3f508ee144c502f9a45162aa9dc0431233b85a13a1f82a05ed87cb8aa170df9d1c80198b44a454e8e20802d2481864f603146ada9dbc2020c95eb6e82a52a55aa5ca1d2b260c920810dac20e2e981a80751583e48368c9a054b005b48022bc90198b49e00419d22d830541a656d189366c18201830f96a081c5522d5ded951889c10cb810c5182c962aa32c262c966a1fca1b4943247b09c6b7b71e0556c400861be46149952aaa75a9b195f4cfec4b8ba1dadffb50c3a55c459fb88abee1b1a959c8ffac191ebf924eca2408876a5ea8455545dfb8d4fe8c66c51716a95c459ffa363574a9e196010926f3547c21575186da5fc97f1125872b862083213c3162b154f3f1135c550459520725a881086860041593201caa78a116956412d4aaeb420850c54f500801aa951612885f211151fd58b4d24202d7275de1acb490c07ca4ab496d50f1e116ed1ca47042166ce8420ec46005a26f553f2a8882116210032fa4fc200eaa55c9873612388ba58a55f48d0f11dc88e2963d30039fe3fd611e224a09ce3363735e8fc7e69c39cd859a3ecd476f86515dfa34e52f5ad3a7496b7b81e367ab83a91760b0213e5b1df13949306a5517902b2f8e3e6591798bf8d531bfe766f4f837b2c7ebf17abc10d9151fafc7183f6bfa94d36290c7e95ee9aed3c873ed4a23c9707d62b4a64f1757b938f6db5a03d75c83dba20118aa4b892f5707d330d4d72c0ee652115b77b8ca5c1cfbd3cc532c81070e8aaf3d1b5451b32c03f241f1f1b75b1dfc8e3c076ebf36e4eab8be9fab83ab4d9fe6bb6e8b065ba8376208c50d534c6d9fcfb13abe38b2cf9ffae6eb53f63951d91f53594c9d776954f6f985526356474d9fb2472c5ce0942baaa94f190df658bbd2607487abd0c00b755b34e04275e953f60b648dd6f4299b8b63bf9e5c1c7b9cbe40ae510beecad90e7adfd5c17d9ee3c09f1a763cb0ef8960df776088d56dd1a0a8cac5317bc1be0762fd2cbb0766d78ae08c86fbec5c7719d8dc39eb32b03bcabdfb7a456cddb7ee5c03bc4e3bef841eb8031eaad49e2d7262c508eabee7a72edd8eebc2272ad7008f864f54eeddf2d8bebd12d9786c5f8e12c91e66f7d1cfee69e0820b4a8ea512166416d0170ef56d9f60b8f82731668f6ffe6c64ec6510a855f8410aa230a50e74f042b5322bf3243f29b57fa36fbaf685e814ab7abe3ba65ddd1651942aa94b9fb8f61b6ef48dac31666083d82f37eb26a109173a341dd943ad72dc8c7567bcbaae7b71b35baf8848438e9e115b776fc42e8259d79e11d13b423eee3cc1440451b0eaf6e9a2616cef086f275622f1d35b00d765605f9c7744739de7009cba2de0070924f67818a93b4a2af6ac4747a3629de7801f22cf2be287a8ee00a9db39ad23790bf83141ddce95bacdeb615377b8ca76ae99d7800e4b153b4f52a86488fb3a4dc3e9ac49a4500951bdbe81bb37c2edfccf3ba2bf69e0722b9d066ebdbc1efd8b722ccd1b49a192ba8b23dc561646f53a578c3a61aa3ea67ac5f323117e3f3ed2f003b59ff1b5842403ae6e8bc88a5ac3acda3560529955f75ca7b686cceaba5ec8a0074770147569c8ac1a9f44d6bd047d94ea4f0de5697a6c55d29d52ddef16aa4d0db74a0de39b93dd82443ebe167bf6765ebf1a690dab7fc0a1bebd4b0b67e493bdd2f549f6c9852bf5c08e1ddbda5e5f5e525e1c2665376f4bd217c766944803b6cbefd46434fca9d9e5066ec7899c04b94dcbb29a55895d736ff0e5dee06fa1ac5c25dd59d53e4e6f716ff0f97cfe266b1fdc89b5b38c661dca3e65678f07d7ee1294926ecef6245f2d225951d430fb0e364614553430f41e8f8144e6b15f52300cc330933b191311445179925c557b12acf6fc548dca673e5d498f24bac363d4e9813e5de73b7027d649697a70ab628f5e0ef6086aa1fc3c0626e91acf75870bf84142e5bd917d6e9fe0ceaac667a0042ff91c276367343c4ebc620d7b7e6acdae7deec41a29918c12e16b746755c3f8d5065d228d0469e4fbd839c6ce7decb247ef70151e9f6ebd1e487a00a9d933ba7ba388fd0203c3ec44e4b1731918b5ec3166df36799fab6e0f9b67cbb4e374a67d93e00e57a9da3370776f488fc7bc3c7b3912cc38ec338fa4d94fc79e12b8952bf2719e9bf11c7b3c79ec172a6e3b57dafa7d75743635db77e0d73736753f7bcc6fe7367003e7e7378c4756e2caedd727edd9b1b39793815f9ff618a881134cc275039370cd32c9cd519236fac5b19f60468960e72ebd9dac01d8395ad2b2b3d7c4758d6e9f32badf68ae0351390c0cb167e7b8f5341afe54ed1b9881e102b667fc0c5c4fa33bb166bc23eb7c287fd11dae93d6f469ff93f10ce2e2d746048b7c44e27da85e4cb16275843655fec81e5b9597d8c3484325353ed41ab064a89266811da7bf2076095240005bf0a28a6a1fc1705563385fe4e78a7a3d5462805d0184dbaac10aaa0fd78b1ad930ea4eac52a54e9ac56aaf24fae048855156b8aa9286f1a156db87ba5f0f033b8521d5fa50d746532236b3bb883b6207134ce1822b847830866a3b6e9bdb78c567ea13ffeb131fabeb051a9e54ae9148065ff81c7dc3dfd13757e5ff46e5774b386ebb9f38b3dc7694d28b13f0620846a011c745ec2da0494cc00f239634a331094e035f89c3c0b7de027eaa9434a33fcc0a302a8a91bfa65bc33e91a53b4aeafeab410c8ceab662d0e22ab96b82a0e46f7a0cf8a9d74fbd68d6a0a6822f72d2cb99f13a4ed35c9407d7ebd756fe04b97e54380d7c911fc633a8cd8097870cc0a8b36e2b0663d45de116035d95952bf1779d9bc6778f343cfaf13a5f128997bfbedbd527dc62e0e34adb37db8ac151cdbaac74812fbebfa384bf923bc0d5d0ccc89862605e5c5a5856be12c9ebb84dcbb06bcad8bc5cf73466c8a8a1999131c5c0bcb8b4b0ac7c2592d7719b9661d794b179756431758d049f09be7ef6eed6648124aab1f5dd6cb13601f7f92e0109aaa062045364d845025b8a2020264b44d0514c0fac92073c8c71073bd4810e739083187180c31b56c7ae0ead045fc845f32b91bc8e8bad98fa281fc512dd8c4469f85d3434654090a69faa6645132954c518927524469d310c9ce6a2988aac889a17ca86bed8a44e2eaa73c7b7bd1f5b753e12c514cf81f928a66698613e5225aa7346bd32ec9bf6e39ce2a3889a9f249819359ca9f31a0966cf1f1cd880063280810b58a0021498800422008107207184031ac0001f0be86144113c7214900055c599e7d6d0cc26362f9cd9ea9644a427543ad9b5c766210759d04191ae0b1c7654af73ecf1e47ce76320d7f5b8edfc65dbd7d38ed3d937ae1fc82be07e31822dead6c5a2027120a4b0428c1af32feacb5fb050b1a82d6fd9e2498d79f83334816f5b53585163ce75045854eedc2594cb683b27d399bcec1bb875cf39a573351d8da77d05cc9e1da7492b1a3042020b0ad8283976dcb001555f98950ee3e5f45fbc1cee8bcae72d6acb5b581ebd1c9973fcb97cbd1cd34c119aaf97b3ead3057ebd9c027cdb6a3245037dbace5e03368cda843ff3ed341e18be7adb0663633bcdb90d641af089ede15259f5e9fa769c86b151633e3e945062603ae6c1ff673c1e7c208ea46faecf844566ce75e00cc8848eaf7bb8538af4e97a4791f4e97ac6c5277f19cd34b9f9bccb783cf83436964710bc74f969cc213eee401c7c7fe5506ace0101729286cca7ca36952f2398986b547c7c799d04cf710704c8150c00089a2af8e824a60440259400d00c07a54e2e2309c5ebb66b4a4cad2a068641ee89da9d4166666666666666666666666666666666f01d83bc9ea43dba72c76906c1bb7839e03910e4ded2c201016ebdaa5c79c0c31877b0431d2e3a5c73b8e4708971c5e182c3f586cb0d571b2e365c6bb8d470a5e142c375063394210c328c410cab6357c76a435fc84246d965048259c5f9625ef329c260524309e502a36f3c1e31e7730c7244d53ba507c1f015fcc1f0f5a741e3bbdb179a4e975144215181f07efdc5f31173ef97d17619f57019d9b88c6a5c46f232a21bdba811a14facfb6b376e8dc9a56e785dd7755dd775b1ec5377a1cfecb2261ce90b926c4820d71cb9d8ad2a764dd3384ed3384ef3e91c8e631949d29bddc5615ba669d9867157373d498aa5fe78a5cbfa66495ec76d5a5622f1e2d8cf2be3306e39ac5baf088fc49db9678fd734ed5c77537b6bf12eda4ddb76fe76a63e5cb58d869c7704774de3388ecbb863e7389e5c4b8e637a691cc735f8c5d1bdc3344dd3388ee33466cc637ed781cccc54f89a99b7a39c17c69b919054edcb815c64acf98d611886314f8e69c8c7b2871886611886611886611886611886611886611886611886611886713eb2b20d0e5cecdc3522dc72cccd9637dc0668eecd1c1872e5b82fd7dc39ba1bb396f1b10d337effeb18883670bb37523e6e771f9491ca3ef18d94b10dd0dd5c6957c73eeceeed8e1ca3e038feb878ba11c19039961b67e2afeb321b75cbdae3f88b18275b4ade49dac5218fd35f4d9fa49492767cc2caeb2430c3a4dcb6ad9372dbb66ddb389f1a76153b273d29a547c3ac9632128974791246c28a7475fbba4c9357e833658e1d75a594723b8661dbb133d6f7c0c86d97db26a5941be91748e2bc52a9542ac9634260372e062c8eeb9c94524a2967246d979b94539392c64795f2a5cbcceb215fa2eb1db19d88bc47a59452ca6d93524a29b74d4a29a5dcb64d6e9bdce4b6c96ddbb06ddbb66ddbb66ddbb66d9b51ca6ddbb66d9b51ca6ddbb66d9b514a4c4a29a594724696524a3923b6c96ddbb66ddbb66d8bdbb66ddb16a5dcb66ddbb628e5b66ddbb64529310cfbb66ddbb66d9b94d8b66ddbb66ddb16b76ddbb62d4ab96ddbb66d51ca6ddbb66d8b5262dbb66d9b94db86cd73526e0fa594729372eb2aa594dbb66ddb864989c988c988c988c988c988c988c9886d524a29a594524629b187524a29bbca4feca1945262524a296594526252cab84929a594dbf6796edbb66ddbb66ddb66dcb66ddbb619a5dcb66ddbb619a5dcb66ddbb619a5c4e439b943ca6f18cdb1c96f67ece1b6c96ff24436895d52966a28a58c365828b78752ca7ee823eb7c9c93ee174778a3ee390a1ff7f90bc4591cd72718ee17f572f9be7734b4513b529ce7dea7bef7cdcbf1bedab76fbcf3574ee18b2e1ec8953daf94d5f8ac464ae3a3f4f8d223f5e1ea5df37ac4976838efd1183dcf9b33c61863f4e6e44833ce193d6f46cf9b337ade9cb3ebe2d675ef53e775c7891f1816b151e3bbeeb279c696e348e740d2b96d7aa552a9547a69f3c0ed1318fac4ea7dfb9c73ce39e79c351c090c73546ece39a737e7fcb23e71dfbe99739b736e73ceb06b9c73ce39e7a437fac4853695f3e855b7f206cadab1c6d96d605779751bc87562ddc6835b8cb445ce8b5e8ef7ed3eddf246c6ae3eed237a7d13b1ed618c316e9ed7aa9edc0d0c6d54ce9bf47d9a17627170f19386b1ca1b193b56a9d206f0bacef389f070ad52a3f770ce39698c94e3c2223b38d086f71bbdd1a76b8259df44ba691b28e3af632c858f4f923494b5bdd8496e6e97c6615dd637e18ca68239e3e711f1442647e1e3483b09720d23e8848fb3cd48e113b5c48c0224449e021538ec1c06b28d1b37bee0ee18a59cf3ba3a0cc43accdb3e854254bef6e9d227699a339399ccaabc2e70fba4d1ed934d585399ffec7366366cd4f815121f53dd3ec993e4346d6904c31c355e6e9f429f1a9f905f8ea42e55a31a0d73d49993a34f938645b08ca1f0718b5d53c6668c143e51f9095f9fe5dec88793ae133e591727e36dc95edcda086514552e95480f4df3381da56eab764e9e40e1ba8d74ebac89932750648e5842433288a81cc9683245c690910c21293258a4a328a4292d921114929427a42227da376ea625e509945694a21a219213122ba298f4842414514c82421a8a2826b5484d9c90a29088b6a584a25a64a9d4ad339ce6648e628a05a606151933ac985a993123d44263e8204c8ce989c9749919283333a7a969d5d49cd6b0f11ae7cf3489a9950c1ac42a19334431b59a4183583563c6494cad68d02056d198791253abd32056fd2ee7cf4089a915488358053e8a0c4dcda90d5a43a506ad29a2604d0d58734403d6cc8035536aa0d418d53ca90141195164101d94d192d1840628038a8ca119a08c2732846480329cc8604594f6508693cade4319ac1a212995431aa3ca0f6b9e547e8d10cb5013a2157e8d9315a3985acdd099293274a63525a656263a73144367a21cc5d40a86ce5079a13345345468582d74464a0d8b85b2e7a354238d5eb0a0d4ac7648f84212ab48a9039370dde13cd4785d93e7c29996115c23ddbd11ceb3175f689221aa4cc2a40c919781e1890492349393a2986215dfc48aa9551d4d319212a505e589d0506513516592943244db65a2c4140b5fa68865454a8b514c4d89e1cb10c9389179220345a6a59dfb0c482314517c1970c628a2f82690861551fc1870464a44f161c0192a11c57f01678a228aef02ce1c4514bf059c891251fc1570664a44f159c0995644f1855dd8855d9876f53b46c2b7d1503e24859275ba340c0cb7880365885831a352b242c9f2e26bc5d49a4e33343325a68e768ad14a096d6a38d3caf1cdb42acf90582f2d17a216d68ad1d7924e6a68ce3397395f0ab19c2f875acea6c79c61fe7299cfd8ace4a871f992186eabc644031369b854c0d36e447d34dcd646548986a6177023caa3e15bc015900594453185c41e1d491aee94296b6444e7afc5114e7a7d6605d482025b45c5426507cbc3c99386175791d885612c7da4aaa43b4424b9e6648e1c3932534d055fb3aa3c83e1acfc15508bf90becc177a89c05cb6926a54049c5f2ad406ac8f2cd9a60f85397b08a85ae56be84868ae538cdb1804c84b4c082b4d821a2ce5f940514d202fb4654e813eba5a3627487887a8149aeca5b252ba6e425d10ab82a93e9fb5636ab6e0d492c19455e0fc009b73642136bb3fda9bb3842ece126b4b1175fb845a1b245a991bbe842182304d48b25c7b55e5aad6f6bc2e2887f990213374add1ac234a9f12f30ac1c36d967da84628acbb2ef33fda7938d4dc8e5a8e12654e33330ec4bb6ec8e808e864ed4541f53edbe8be3fab53a88ecf051ede80572adc5115bf5a21c760deb4ea976cfbeab2389ac1d0db96634bcceb5626a55518aa4184d39e2a8d4b8b16ac8b532a3da752f5348f12f47242adf4a3c0c8b85251e4608e6a51553abd24b94eff12f452f52626af5f2621453ab98c31cfb7c0c18e304068c618131443054629ac01cc50cc14c891182318aa87865d9c561dbb373175a98c120e1f368d83de45a59179eb62c3c65188c518dbfc097d64b2b33aa21d76a61ad187dad121189c5b56abc8d8ce9b1e52ca4bb3cdef4f2f8c73cfe047396b7d89072bcbcf487db925931c1fccba8c4c0bcb8b4b0ac7c259205b22ccb4c2cae5bb6e0f8a512976908ee2c573ef52395bda4e129d2f0548daa78529b683e8c53aef054af304e9143d228a6560c0547f15085261d11c90907c5f6503e69274f22aaa1482ab5bb35594a60d52056714fad569e5a7d4fad4adf88ba980a8b594242424343434daa74932611856a269252c38e9275946d45041ea8a0227d49d7b1b0e8cae5fd13126fa14698be985ab21d68c916d7a022bdcf4e585a5e58283b016271f1bc7b67a10bc4f2e242a128955e3a0b5d2017a025db594ea1f8fe612b54fbaa8080966c2d148a8ee5dc5768760de4217c91c67f2097409ec2472c858b22aae7a7c629f1cb68c84f302a699cb23898154e21665d818b19b8a00c6fa8818ab4da34002d9192852f1841e5adba0e62dc8025050b07aa6e15a700c50c3060d5a1082a6ed55182d6408711b0a18a6a7b7f0ac5d43714050f5d342922921253ab36ea294a7083aabd18aa61477952c338254e89a915ab48d4e628a63c9a235289a98ee2b0628aa34608c5d446fb4fb25ec1825b52f70e8a5782f2a4e43d89a806e25e02e2bee4fbaa806493886a28388e4a22e6222adf0a1440df774fe62e465fe9312f795000791ee9a6933aa0ee4bb803755f41e179a7b9779853288056be845b99a15074dd67de41b14281967c07e22e73ee2f077acd57de432c9449962643068d54be02369588ead780f1088c4f66c008058c2d303a01235116a5a744f968240fb442a5ac7cc9b74263d131503621c2d74521172541a886cd3ab2e93795986a2711d5cfb24fa39251692a8dd1e6226639e9662911d5ff9cb013a652fb46f8c21885557d79d9a48fa2d4e62efaa16cc2452b9f94d25d5c8c486f699912532c2cef0eb3720a05f797efbd72a1484414bff4be248aa9550bdd8822bd2f9dc4d48a85b27cd2975036a2b89748369967139a6c260dbf2af951b6fc68fddd815b1b4fc4fdcad2835825856610ab6610abb0206ea26d307fe26b39b34cdff7df38a35a490a69e52c4675b5d2b5d3ae58a8cd4757259ae38ba85d7514c71451bdd2a811f411d57d8a280bc4d42ab3011253ab2f071331b532b590c4d4aa8f813c0472139085228a053e11515b44858b4034064e0650cd4b4034277d67ee01c95c06d5804c2fd11c31051473128df91e27a68060ee5123620ae8e51d7df9fe8998ea38564c01954adf8148a4d29256bee7263195ad50283c0a4577ee7b0bc494cbf74062aae57b26628ae57b2431b532842f09567798559b4554e72f0d04d2b4d780403535cf4e0302d1d03cfb0c083433230302c9c81c68db9edd0402994ccf1e0302c5c43c3b0c080403f3ec2f20d0cbcbb3732010c715d5ec2e20908b8b949abd05046a69797616108885e5d95740a0959567ff40a0ef3b15a0528955b3934020124908c8fb121907f2be11d58132306e52331ace217c3c76b84aedb92e6bc055d180ab9a01572503aeca04ae2a065c150cb8aa1770552ee0aa5ac055b180ab5a0157f581ab2a81ab2281abf2c05575e0aa3890551bc8aaa99260d88fd4091a55c9cbcfd5989427624aee5783f97e49ac395fdaefb718f695b3ec336dff719dc96b71f9fe2e2e7ff992187398ef9188a915e9f2251ac4aad2bfefd7c3355aa141ac5a99c2f26c7fe2de3db4f1def23087cb5f36867213241115f72f2013200f81404016022d00320b44027c02e42920b740368a2828204b89a82725908b4012c8514eb51f9eea29a656f136527ee6f070b6735f12e38d88a9ecdaaf63ef68f6c5d46aa35f44c5d46a85d18da88b4e7aa299941653b97cb84592461a2e951a8f842fe4aff478268aa9d576edab796e75bd5b6527adb07b8742fb66c37de6e87e7d490cb7b5122280ea233d3b5d41e11d7bb8516ac844506ab854a8904013d8811f0766e029a2b08d1251136c2422aa7f7434658a9151c844ddea7eba2514b0a38b4a0fe1e399bfbedf488f9af615141ef7de368e42a1c96f4c75148a8d3b1ec2b7c3158ba202eabe122280aa44a1e0a0e8b08bca4525a63c0ae479f4a21251f1405d4739ca81388e5b1715a0ed4bb2036d144a44c55f5480b42fc92814ab02d2b86988b186f0f15cef73175f3b89726dcb0ba37a5d45ecc4494c6574953d89296ff1500425a6baac1553dcf7788e12539b46a1304141c4110fe1936f1af28eec3313e163227c21467451c1560a3be91a6251b02831c54e222a3ecbbecf8445a9f12c8c088b82116d1835bc8a2e2a57d1006a78b12e27176b3e91329fb8d4501a4d21a32d9443b386b135253689ad3e8a4da2f451477152a93861a662c3ac30ab2bc526cc6ae42ebe227c5c3b62d9cf6c52155c1653ab25516ef2ad79f98e6b3deb165d65d7572cbf7a92bdd3a24dfc341211f76d45dd371451b168b53c8404b7d24640e88a8fce4f4adbea224b6b7dadce463bc29ec8efc87ba21d6bb9465f13795f5576a28ff470bf123d8966455e474ddc90662a52d2a2c278a8f4c3bd49815b1bc7ae9892df2f899fe09228c1251103574be23370498cb992161593204f25bbeb41acbaa4fc94d98358954d6de7835835b717a3ed41acda5ee88a4990a78a61224484eae541ac7a89a12b7e12c4aa17bac261a320566d488004b16ad215175dd215b7825895d1d5c744ab0d62d54557485cdf64c9adeb46dfa3c94654498b6a7ea99216953cb332f0022768026f23bafc7063459c8c00544ba2118d25710c2149d33b845c64ec0ea19a19bb43c806263400d5920e6255dc2184bdec0ea112ccee108a89d91d42344cbb43c8878b89100ed5924885c562b1822e550bb5aa3755b3a87a46d554d53fa89aaee68508a08a984ac846d50f8aaa3855d153c5175594a18a3da8225dc50b1140d5dddddd7425afa44585617d5d5f12a969ce2f895fa42b2102a8e297442102a8562d2a49574b6254d2a2122280aae9a3928b65eb9be2a33143460dcd8c8c2906e6c5a58565e52b91bc8edbb40cbba68c2dc5b7add6930a838fff614cb825c1c737966b756971f0f9a50a692bb349ed87327387f06dad0ceef079081f0fa2dae73a8bd085118e800422ec0e8c62185dadde9f40d82208421802142e260f7af0c4073fd062774c1a7e7fde007b5016bb43483ad91d421d0e7687904b0e7687508d0e76b03b846e9c86bfaafe9cc1ee10ca68b03b84be1aec0e211316bb43e83620da1d185dd1308d80645ddb57422e2aee42427c5936dfd24d1998cca56709b3f1958cd7f8aa657ce5cd9a99ee1e0e80af4a335ebe6a92d61f6b68014057a5f740814454df065d215183ae58065dd9d4d01513cdd055a4b48764e80a0706e631747590f250cbcce9478306dd506de7b8666e9b41575a48a024f36ee9b63e3744c432e8aaf41aca4626bae2a217baead64aa32b7ed244da3fba92ac88ead374f335539291f9ea85e5abfefa237ad2327475dd44db68d52d7db46aae1f4323111bd5eed8ca602ebaa22e5f71bf322121542e74c5bd8546a388eab3d0552c8aa86e221a9f445477633d3daea3b3392a8d7ed1952c8aa87e4657f2493c8aa8eec63479248d3ed659362caea2d2429ec974010fd131581e8aac25a5cb8a1ea21f6443359b3001fa2137d1d03401096c54b3041b443fc8a4ba1e3656a54a1eb8b08527bc80287b500ed5946283e825a5a01baa59453ce23668a10b649041942ea856853566051668810b29a4308336889e401b449fc99252d05593c906d10fe551ed4f19ac0ef9fe64c514d6f4fb626226dd9dacda92d2d81b3c5bb1699ac0ad8d70b2562bb93769d895615f655f32b12935ba928208d5755d0a2254d9c4e4316cc64947355ec84595611746e325a3a2cbf4f972d3cb751839f4b7b49ecc1a971a7d8def3bfdaae6df7c94398d518de06524916449cdc67b8891e1f29875f9cafbca518df79ed44824e4a2925f692181996f5f1dd5f8a21adf035d69b7415f83ae3e4a5738dff71aba8a3401a857a824e9978a93a11a0499520acdd040130002e31500404828140c87f340d1f4f6011400108cc8624ea5ccd424082a640c3104001820000000230211412000003080b8ff62f2ab75e5bea7e5268bbd94d1f5408f56038bbc9e3b6ab1153cdf228f1fbf620d07926830e645b3a8d42b52d3b7bc318cccfb4c65587497ab319ccb4df334866e92b2d1405c0dd955c0d2bf87261569050bae95fc1a4251017cab0ee1120f1dcfe806c3218f175302f1dd6c69cdeffdfc12da9ddd3438fa3c039219e845644bc4b6c3897a228c60ae66986488b81fc4da652eabde66b10427b3eddc9e494b4190d80de3f049447754545cf19c6ff952bdf1d7e1290a228688311a071aad03a2c101d0e700687610343b285a07009d8384c64146e780d17540b438009aee40e9e81509f8aca3de39f81f2df4e4be2119c982755f015d97817aa5748964baa9e4b4409b5f6e59b5dacb42e5d1b91bc600371fb5585b0bb55168005888eb58be5cdae1a88f12a55ddb740e1d811a589e93c9f0b5dd77234e42da860928de5c87a5ea4e5d161d8689eb97c10b2fdbee2b83b24d1d29bafe816f576625fdcdcd1707c20ceb4dc125b3f48c09dd557a9bfbbd335590de064226bdae722431462013e900ccf0700671f8512f5d8822a7e994202170e5d5f3a4fd592d1cd864f1827aa0889a952acb699867a827cf62f8d30fb58cc5951b219286ef6467603e2f0aecd0a17778dea08186282ff2655faabdde0a887daf144e7cf519488300aac55c553ac25effeac6832a96fc7fc826f5c7257ebb08ee82b8f223c59737e991b60908544b9427b257ddb3e0573b57f671a3430f1213970bff399cc2216cf73e58353a041b55555568fd7abae7e5c323d82b1603a1d6bfed9cfe63bb7f4cfb2e0c2130f9552c76cec3b4b56c0839bd2d804594b0b27087b3681917545b12de8b7add0ebaf60cafa6a66f7508433ea4da618c7aed3c417d421a5a2bfb52765b6d065b4abbc25c56fd70ae843e5bddc8701181ba85b291a7e7c7dafed94f429288a018111e434375cf63f6faba5fc284412133fced0ddc306965091ad871bae033d7a5cd0d890d0610524dcfe5601759e760e9331f60f10124856c8c8865b995c04a8005658878a4bda895634152927a0108648653b2400d7f46f5eafd4c3a41dddd64b50b05e94ed84aa3470b9bfb7b02e554553acc2ffe4c744f11fc02ad9c99be589d5386aef56610a63e30d2aa22551eca0c42884de8aa67d7199238e8fc0e2381c742e254f4e70cd8d00bda9b3445b843715ce0c6ce197d4035133c2c11bcf2ef67534d87fea5c6efcd831df3e0bb6d90f2f408e57dd82634f782c4355103c2f90062f38566233420c69bf57e529a5572b85f98cb7871e40ed1ba87d19d22604466d9d40b3ef0e1852c404efe6b139807ae4fdb216999e70ba93356c4d4712160f756b41555ac0283ff477912d0184e72972244d880ae810cc3e9ce0ed379a71b6a1561da3bc2fe8bcbb87b55f56c52e31b71602b99aab38d954b566b4ce8ece066eb802e138686f7e81628322bc066695ec1df5a218fa237f4cc51457a31a2179abc812193bb72765079fb913b48494ed4c9be052444c97e4fbc11eac5fa15dbd72fbebd09c33c7f6a4c2621bb32c70d5ad25969f90ae817b063bf1b6bbd70f50a3fa951250d711fcb6dd24f374503340cd392b4595c8c72278983c1c5a48f8f18eae6937b58f86933728f3a3e797e66ed21c290fcb31eeb3e4d8a12b51e21a1bc68830d810503a7d90fd3082e46631adfe545c544149ec2767f24780ab31cad1724d1b79ff9c0530fe58d3b9dd25e92ee99b6296cf4c837395a54d98baf50ecb3b2ddcf3326d65565ebf59a7400a3d3ead18d403a4598d436f56d3ebff0cc256e02d224963255d25df9189562ad918c8d42ff81e73a49c3962a9fa0cd35da3e64a3c718be672a00f07f70d9e858c4e319b1ce6b94efe1992cd8a808ce971f510ff6bd4641d235b08fd3302dcdd2974623b5361ac74e9bc66dc6c5afefe5f3b548460f6cf98b069449a8aa8d642d3e84ab6813f3aaf9200a28dfcfac890ed6dd35db68610ee2281b1fc9a53ce561d439528aef983b0845455d8f9fab07699441a39c25d8f8e8366a183a9701cfa8622bcf3f9f436e35787740e71274718c0e38eb56b08d5e31239078c966d819f64a07db0dce7d14c446e5b34f104d5147246c73c952b893dbbfefb6cb8522e0e24c1c27104702df9ce94b0d50c4b481fa0e39c28c2c4365a33cb79ec8dc55d9134aae1792ae5cea7036b887521232bd95a947f45f374876a14e66ffb3f78e0f8ec16a87f898c53829a8f9505ed58082a4e0c565cc4c064fb78d36d5363c7645c1a147e91d81c348c9a339ce45813176adfff700d8bdaad2f9777f6d1439da8875a2e30c0220b95710e4640dc38c19499965387554de96ad41c3780ce6998d9e72b4b67bbae9aa2d91af06495112f098864db8b1dbe60b521cf91b9aac2ab237b90f603f21263a34a88cd9fbec8deb8b86515873ffaf2263d447dd2651ee824931d06c741849fea063981451fb8933d3ef096bb47f6b006fa247610b888de2ceec9d61d0f1c6367ad815cf0a7a9bce38ca1a5c97d838f3b439e8e0a24d6c679c120101eef32efaeb1de44c15d6057b30762cbe22acdc533a3118fc367acfee899d4fb6f6fd6bb4e53d2bbf7158755ba8a5e7ac5cf136703e2303cf9f711a159952d055e2394b5249769bdc5046a3d77c86f65799cc77344cfa3ea2595c86133d6bc541118b6fd068faf355ac422da2113aa147df82a0b24b4c52b665f1744f8bb3ba47e3561d235b2d497c58346edc966b45f3ec82397e02247aba47e094dc0c96496b9dbb9bd5246ffaafb98803071dc0d38849eb06c48ebd18f776812a2369e991a5148ab41f9e3707780a10a73ab38090dcdb12b4222565ba94e1eca0224ddbe9d0d4ad51b3b19d94c2c78e3d6495594d93390a97ee84d50c289a74f90c4f9d1ee9bd2620170c8c5d521ef4468272a507ea85eaf372b30380d778ffc7d002b2877e8709dd96af0e6db7f9a20cc4b2d5fc144a5d720d261ca8607efcf603a51d23100faf474ed448c1a0bfc35122e17aa55595286cadf02dfd216324ac501ac8ae92375b70c3df8afba8e2ec47a72b1b8c7a3523924181c479a9cff877d8c76bb542baba7c94f9139d0e697ab7ab3e7d70533c61d7b4841769d192d7d3d92bd5076265d9c1a572ea3e00a097772f112a8303bf6fef8ffa0c33e95d2f7ea20cf5654309d45f5770afeb966a245cbabd104de8fe9fd9c9760a615130c5c92c79f17bc3fdb9cd925c9a5403d2e6a6c7e50e6f059e79ae8329de1b945ef0f54ad8837d21cab5a278cb445e72dbda04101adbd936b25457e4853326bbeee5a8f050ddf93c24619ead331f54a768a6e940ee686ca79d2d64e94f64a4c572d883440540fea44d84879aff50bfa6926ec5584b36f307d8e43f6a0f913966862b0410f123fad2b17493dbdcc4f0ba4d2d089a6e70761c1b2e38bb0875b353fd2b0ce0884b6a2644c37329b4d729d02831380cb9c646bced2fe32681270b68180a0aa880b105211634b3a1596c21ec713e9bf0406e3b1d81eeacea7bed3d06c60e4cc0aafbb2f7dc2ff8ca4ec17fec52b978eb6b2c9ecd17868547b2fe1df2209d0595512f75cf7060f10004d88c4c68998f24c56d84e55e3388e647d19ac3350f81fa34fa98729f40ff3a3b527cd3b2fc2a106cb3f42877c5bc100266f9a054bdb201d5bf876a9fe5cc514032402b0a9cdd4a5dd47df1c032b11cae06ad11721f348242c22c6eb105e3e6069dc8d61222e8a978eab208c389d51899189a4ad7ea09582ca11cd12b540924733ff1a15360b8b12ce8797c446246c80c6df9b292b6fc59a92dffaedcca3f566a269f50d7f3c25e0840930a64574406bb42ede8431dd240accc31af3da4aa2ad86bff319bb3f0fb9a0f37ce2833a4b31a9f04afce6d9afa258193889ed32f4f8940e19d24912e9942baf6ae8ae07944c9ed61a5089e8c7cf2a537021a7c2de137e4fe4c7341e4e3051b504d42d93597d789ba575ecb3a64e79711a521849f7754fcdbd97a6f1d3848ccbe39ff4eb1abcb16e490f6d1332accad520b51167f93f8e82d7e4557aadd4f7ab4155ccd6d50f819d3f50d31afa8c2d3ad3cf0105cf3d2f65f2a4254ec07dee3dffdf1ddd12190e57b214dc18d9a2c4067661e27042abca58e3a74f574a4af9059e93ea1c386dec7d6635d311ae491134bd3310bb9b0c3e7999e9eaeb616409142a5d661261468276e424d854ddb50e07da7f85618099e2f3da52baf7d46338ae102ed77d5a13520ef4245a163db8a37393e447431f494a9699c38b41497f028ac07de51124c2b4db844a2516c18d51618a3d09e4875836d4924e5b24978b6fe9a60262854f2f9f926374b7f09f114ceca715f0385c482cbd9687bebb6d86cc8384cbb84d26846b6db095843c458a562a4e2f2e9a86bdc6dc4ea797c860e34be1d798adb875576f5e8b152ad944b25f7aeaec7babaa91f57a3e6c0a3a192a4895623efb60fc94471bb4aff84b8b1e2c32920109f87ccad944af9922319fb48029edb691a49f8ef2e312209f45eefa070a28ea4a1079f0218dfe1b4890d2bd4601e732778c864c0b25313dab5fb0c0d5573407b7d7243d71853d0d008c156b2faf9232c2539bf5bc4ad6467d84ab58886232f5c1619c0997708793279c57f56e639b37424fa2a3c8ec10537b8d94baa611c14668817e14707641d604090d381c4bb5b618f44e56418a0c304d5527695585801d28a4f584875c62495aa98a650e1fc0b2d2b3710fd0d2eb81734003bd7bfd0199acf3312f0f58f54dcf731850a44eaec60944958c97d4b161488e941b8389a5efd89497fa6ef738c1592d4929689c05bccd92ce61540bf5c8e0c2519d63a72298280bf11bb400eca8272974fe22ce79e03c8f4a5352fe4f6cc53031902b3fb780257414f25992e04538c4278fd1312ca7b4dae1dcbd5a71c8d0e2ff2039890d82a819d9f568593fcbef3fc4a5d2d44e59ded7512c3f1bc2e1de43441758911cc1e64b56485351506758ab72a09be7e7825e9580b926b6ebb6d72978388d456a70b584b1e506413082521e6e142c33792941a31dad159e234b482e7a7afead0c62ac77c0782b9b05a219ce4befc8b40ec22bc5b3fc30939d7e830d5127bab091086e340c31689be0ddb521295333518efbee6e1e7e28bc4630eaedab564c6dea7c1afc3cd801bd17e3887083f2213839eca6e07af0a41c19c9fa2d3637437635fbe0284cb11bd6902a51ec9295f7d8a11e9ab0547e75f631db3a00b15fb7bceab7affce6557e14b083df750193315d98c0b8062f9c766864ddce4f8f0ce9792e4b5b71e7b8a7b5c1f1b7b3ae61c81482c6ff3e0d8f84ca27f721b4ea1cf7c27a6294b0a5171bed19ef79744035382a8bb124d38c1dd512db84a82db9ff4aa0047c616a479f9680b1df25eb49c38d1da1c8d5aa50221967a9c37f708a47b015604616564d11d3b84feedcd0f0ddadec3afeaf0edf738872386e05b7c3da06c1347ff7b8cbec3f9d4bbf6c65ef95d6d50078bcbc6e8b37706b7a78881e5b5b48b65072c4d65fe1b25159f12b002e566ef997980971663bd76bceca934fea033aa9e4b1ce85395f1e7a11839fb1f5e42ffe2085e165bc88585694f89bf40642bcdd9fa6983e719fb700cd2d6dc75c27f5d210aa63f8a12664b4250ee531aaf50ae5ef49a2275694843d313c803a68042aa0ba1ecde2232eb1dd4109dbaba6f5d0292288993d97137c761b9ac178b144eac95ba414900d9cc84424e47af2df52b0913d0a8364d734febcc53cf4a94bd4b86b6101aa797dbf11d4ad974c819916e644e9842fc3e40bb60378912e9cbdd59efa59e4c2c68e576709262a7c916a3b4f6bc9a6061285d2edf2d9383904292264b72f7441a4e915ac0f782b86c3c019b9a15d75e5b7b4f70d66af49084b52471e722f590f380aba4b2d88aba42dd19e0fd0277a18b6a272677981f44fa8b8dcd4b3e847180bf673e061c57590222c53b8496fa8ad8d3dc57ec4c6687b1ae8448f19c1dac346871b4b81b6e759fa8594375257920187d958ad1ceb216e8e0a2b9c8351a8359887211f57098834f3a2f18f3447bf9e0c10d42bea042ea18a120c0708c3894a419a9f0c3c4847fa27a170b778a5ca7afc0f670ab1408e984f8cc7388aab161b05eb67e10fa7f1301b0b6025823018aa1010e0a91b2d944e77d747bcf49a154890ee3b36b081aa16264e210d85e0dca5189f9651c5dc2a1d5d6d231f980579e8c77a639ac2bfa39e1388a21bb4ebac3e6f4ac1ae8f9bd30c0102b90615a4e374ca7407ac2c3115c9554bc0248ba4289621a94cc5dfab920a51a7e500ad27ae23903cb9feb48e65b7c611941b5aada7011d5285e9d5fe451e888508257af04c1dc3eda207b03f3a3688a3c49096e7b2580cc5a8254ea12acd230c128641e55dfa65d79a9f6a5bf5253cc6d189cf4af166a7dce962dee0d425d44d5b14a4cf42e843a65939f675c29a55de0abc4a5cdb92d883c519fbc393bf101748e20abebab341bff9eccfaae587b6aa0c7af87404911e9a849cd6ce9ac13a5dc494b601211c5e3aa9f3352e99f72fb45eb626a3cb7433fdea852c6f82e968c9835fa293d25a2d80d2eb8d9db977fc35a6d9bd01823659c8e62d199b90bba781d3d4884d061a582955c0d05dc3f9d8227bbea7524093aca175e8f807a6376629e07044c9ad019bdcda3dd235fc8165c8d638a731683b88a6945194c845aaa7932e903337f3a008a54d17f32e2fb3c46ec8889324e8ddb5496a9c1bd7343b4c0bb4476dd9290cb48537277895a5fe0f9de4d119f0208d7e70dac1bf25cba061d41a72b4eed0b5a9b07e786fbc689486a2c9903e350fcb1410961ac49480a606cd13d7e3e588b47b76124618015bebc25b2c9a0bcb2496db2807705e829b3c09e51f655b7967d18982ac1a79d4fd5a03a05ae019dc7cb69110daca146bdc6fc44214e71ebb749c4fc36fd6f4d60e9ebd1102124bc650a36b437164e8e1556639d589c5580e04a07ff1d6740b29a0ef9d4f16b863c2acb9b4d75d61ebf9f9b9533608ed54ff0d9967876356f24da03b286b15bfa426faf9adb492b44c90115392da51f6882c42175e21a6249171199b0c4528f48dfc128a6820f3248c03552043c00a40e9ee3522b657488635ed70dd3fe04596a352f6ce704c8160bbcd53a2a01a232d162168d184e34e0c6d672b941552a79509edf851ecfc055d419d524ec1a27cd1cee2cb2c612896a7f68341467bd5b9aa49ec12eb131c4bd051218e62a109c2053220ef18dfdc827bfa6cbc398277d42f562909616c37df33a51dde1b9caec5140cf3ac380bdcbc1beb47a20163a27e5331ac5a3a6e284c9213ec4526010e849353ea26efdaa0a517883659c92a4d717e07a622f8d2d0e3961a132dbf0574ef77d6f9e1cfcb9d0e4d8fa733f7efc240bdf832ea648eabc1a276edb61b6fa12657f1cbda902784459622b9969c38e47f578b914c2f5bee3a0f2fe74d682293c318ed893c8cb6038f96eb74f7fed3d8388e8d6a7ef1073f271ad8ec6d1177e8eb28686463f78a854ec9aa5d72af33461d10e42b71f9a51c872d9e57506d5aae1622ece4b69b54e5e833e3bde0d0328614600b344d4afeea569581081a1ae6041025ef50c2e8ce797275e68818260951607290d5483aa42e6c260f49419bf07e3e8760b7e8496606b4a658fc4c58f4f5ae6542d12db8b3a3f6a033610b220bdc923e648f589a2d57e5666e55a83ba139393ca3f0eca546360cc9eca30129ece8420d29829576c0f674a49b4fbebcfc3295b067082719fcb6618864b4e447f1f41ecf9b3d8486e1275a8709c3799f489c922c9d10c204044e6b2d89b62be608c4b791a91dc13dbff2d982c96737d3f0d7d906a00e0983d6b249caff392036aae8b326af8dc7d75f3beeba00e11279d96e0199aa7b4aa487c4ad9598171ba9bb107f0da12b8f35311e4d68321b17a152fe991e4fa2249ff4abf4d01b5d56da5a94e7b69a90eee5dc0bb6693727b507cf8c1ef13ed8e05da5e4c905002e7f65262a970ed19946dc549a30e5fd01cb4950a5919d389f3a72d017ca7acf59ed318836867de47739396f07ef934aac3c24c47df3fde94a443957b32090f29f6f6bc494a653e0c7e3011f30880c1bb94ce43e442d4f9ddd4af542c8705e72e4051467f23abe1667276eb13430e79e1ec7c70f1d9e050a6437d110b1e2aa2175a6a31b28219ab28c5469c3cf5e2a7185b415ae4ba6735c92fe43137808cdbb5f88b74d56dc89f0530f652512743b33d629c98dc465a9ac6378ebdeda7b13c0674c5d83554eb91b68498511a75bf1b09730ad19125fd4bbaababa0a7a4897dd2a7cc0f6c535ae80ea689ebf826bdcdbfb5270bb62a3eb9dfc19f3b900c2dcfc7fc59c506f3ae223d6955ac5704dafd750cf6cc56a3693e58c647005808dac8fdf5024bcc60fd3f307f58fd3fd6fbbddffc06ee7d9965e67d0f967dbbd6fbb1458fbb000ca63e4bd695ef9d918a6c7f9cc5f776944b50c8a00588839ad208496c7b3cd047dc4463a7fdcf6ac5a975a5ea60409f853837dc3ab6f634e396682071266d60be5d6a9c7fc9f2ee7224e2451ac012974535e0fad92a23bb5b622268d635fa6e888105fa98c648184683959e904e60f1b9bd27443c3c362ee8f13d12949217e58bd99a061f2fd206acd360d005f16cee1bc3f0daf10bab7008d78ecb1e17c6e6cf2d044c75c1e5f783a7739c1f1a1ce52b89bdc014caa0e95b9751af297ceb8e2ac823f1c44ade9ec646dcc5040f20f66d4313505c48dd65106032725b93727d6a816f585498b9b6ae59cf5c55433681e1dc5553d5352ac188c7644b7135c0d0df7423f207866f7189be558f9ed070f870175bbd295d18267ddfa0279b0e26745a2e02a0564d66f350e192cd254661ad074ac8209d2dfa13146eecc41931ce750c72bcaa86adb998ce34bc581f7b4043fc2b4d4a54b6e2912e9684bd01740db22192aa492806f4c68277c4b1f24175b02271ff8f1cd9493da671c974bf4cd7c62ab556ba6412a1aa00b9ddaacd63893af3352e34ade820122b67cfed2321cd92f283dc36d069ac0b3b3337048a101236376597712549be7ff745898883ad12b0dfd580f51818697a2954573d14f1522b20c7ba1ba82290f1cb634b5bf665534a1500316e32c22bed23a93bef57cd8fa30e68c47582f22e3aea344573c670c68fbc9e1d10cd7c2c43193552386f0228cee0f7dd0399dc5bc121f0704e1d8d7f5ca205a369a1706a8ee1a86ffc00ca102acc856c7428f7befd49cc7f17c8b4d318ad14bae8e4c1b273d4609ce600ae46fe898b13faefb94f73eb11e33aaef469f5350740cdaa3236e77802ca09863c9f3ba32c6fad575c6f000a3552171dffb3a4d5c4ba073b32c3f989377665b7664f5b44cfd9e976993535eb72647381ad0b0d7e1351b12e22ec21556b484c83e75389433e42ebf7929ad336f65fc503bc1fe5abb06d827be720d1c319725a5132b64f3e01b042ff41e4fa05f8d1a4d00a654d09a1cae3861b76cc39de3339e6d920b73af5ef283f69deff1eed439a4d375072ba398b0485d8f355537339b2c5fc2ce008cc6cdfe7e904a622486f17fde92d9c53b9ffddcb4af38745412f23c4ca37716e0d23ce3bc27e314b7f107dbe424191b74bc24daba72449f6b9bdf48e4dca35ece5f6f635cbd25cfe8f15f18479e1eca315d32115cc29ef655803adacc35709be00ba84bbb4ab609f6f685134ead3e2055f627302f18682bca20d02c83b40f21909fa47dc3111601b080c27b0fac342add8301d282c7fc438a060aa09552349c0c9810ae68d21e41080e696a11cf54104716e20b527160a5c2816b7e50d7a119246fcaaeeae09725f6e4a9caa03c2421dc091f8c7da2dc80531f11feb7f095c80bda97d503d870d4d047cbe0d6112559e18d240120e8940bb2d193887514698230887eac35f6b80c6852db293f06126af19154265015097d19efb67a831d8d4af682350cdc11c61ef1319fbd1737a00019d0844f22ac461fb37d5c1890e0133afa199d3b1ec734a969ac2b779e03211b447be6923842d42695087b29444622cde9d1089ed88fc4baa91e3ebe5ee93243d4ab72f707bfbed6c25caeec19f147efff63cbfeed0165ffef8032a6d88cbf9e781f0191fec20c72f6f24d87e4ce74f6811c5b4a11356b92d5aea0c4259247d7b4446c9a94903196c6537485026003484d90550d8db5f915a83128ef7c3aef36b3319028d92c2136b8a5516cc8b29bbbe693b23001142746d96ca0c70465c32ae7528e0624c66ed66adfa9fab44246be39be357c6bd79722a70683a2babd4be48f5d428f38c7d91ae5a99d3034ae9534633e1dedfd1eca6a78eb715bb3ba32493a7a806e896d5c72497252f2ae81bf98a7c637bdc82f66a10f73ed39ec8833589dfd92a0a6c775ab153447ba878e04e5216597879516de4ce639d3ff3e05d0f4a2c21c9e8afab7bfeb7618ebdc35bf1359efeb8c4f2c1f6416b498dcc64dce6b0aeab070efc606f113eab748a65804115c418b978efe3636399ca983380b990da3f1d3a73a03fe9483763023087afc68da065bbc35b405b6446a908d6e03af3f0c1c0529be3ee3471201fcc2aabb2c2aaadb2b255ac6c652badc00a2b59cdea56b1b2d5adb68a95ac64152b5bc5ca565af1adf27fa410fb08020e95e34e2501b62923327fd5d4687ccb5dc6d1570d588694138d1e8eaa0c4591a4b9983865f85f561fb9e8b9e31a34410e462735bccb256b7782b947f1d07e795c35859ba97e2b2d0170e09900aa20447750e433ee2671dc42547a129b7737d60a8f60095278efc954a1bdc1a1c2ede6d208f40fc8dc8bd732831cf74f710d3305101d020cd8472dee7af7a02ddee1a910b67286b956464f0217ea699fc318a110cccdb7666d3a5b100e5469b02728d9d0a26be62fad1d5f63edbbb7a924975b9beb417cf01c12b3db52986406b52430f16624925b9fa37de6d78c3918496531e2c0d4c3713c21d77f2d739387584ec2df9311b336398cc26b853363721d134b5d2a05d413189aa2957ce310067111fba3cb6d2b83cc86141688eb01d8e3fb351e6ea665cb27801001fd41375f0018b8574f7867d3c6cad74f8b6bc384693d2356060fb4b7cfa321c126c6c16e9eab7fcd0555626e83b3f8ed15c6a43b13aba9af0274f30e56be243baef454d0455c5ce8c15ce3830782fa286b3883502740145f759d02915886098427a0bac8ae2fc3d5af237a6a56a9403c61927cada1d952a74cf0b9b8d4ae913a1daf88f87491c2e4dfa1474991399bf41f9fbb0b9bc5c3590c5bd2475c4465b58104e1ddb66483922ebd2da52a4ea2a8c31588a1206f1ae010dcab95918603e33f1e460027485364566dc4cbdf1f802e2da86d00cd0f7adee93f5b3842a3f04adcf2f302675a4877ca1110ebcfb502893418972c0c480421ef20f33a62bc4d4d704174de75003818e02cda8544e489dd71691ed5f181c988618b1ac61ecea61110a2dd8b07040aa556843d24839837408e08b6d9f996b5992801b1c82f3d7d17d0999f280450b05c14b3dad12560240d3da329e625fe2cefd3b3925f9198930c4d62924c232c78c56695e2c9538ce2ead75001511ff91c877e38b7984810e6037aee5bceca3a6b6ed4025a87770054069ff1e0017181d7b610827f41ece4602f71cf0ec45d3cbcfaedd1377b3202b01f1a674ca2bc447999cd3506506bf62942649f039b662571f63e4a73395f587aa414889cf9b88f679ac0aa298cc209d9aeead93c50d777f0594f30768a56438b38140867c0266c0db158a899dacdd554b470bcc1468511f13a756603391c9b80974e49305f754ad899f0a9709ac550b0e7700d070951433e493597c03515d126ced6397d30896b85fc5fcd31ab271de5a25545890b18ec018aadedd9101f0564c4b96f1b97e154d6ce5190198279d393fb866056cf98dea09dc2b50187224fa11f69710725c8f3821a2790eb148496ca0f575a3abedcd1d570e5db7553fd1f73c92e4ab8baec986c3aa6559abdf94a9e51351d16d0a4e7c9e57a8b86dad9c5432761c14bb07d844c223957961d7c1df236d13fa60b55843f1271b0a2263d50d3a5474b026fc08f14bb62fbd5bff9827657281637d7650f89a27922188e36c1626db1b177eed163cbf6de0b5f246e666f4ddc03368a1188610f279b444a98c0931dcce85e9f8c258783aae70b5a3041c24fe8c2815b83ff06067fe080f6e6656c81cfd6ff93e7c6dc74c4e33571da3eb6b82bf4f488f269d5d29d81f4a7182b626a1e42dee459f7dad9de0c03f6d6a302f07b42815181935455cee927e77b869bef3ab1bc38c09a16a5ed416f122afaf25a9ec669e97e98d6d1f05cf187e0561114d1345f1115627916e446fb66e0014f3ff330e81975b2526372872b26fed75fbf6f889832dc47d6e219858b34a02ce58c27db64d71e193e276b5f9c4ae9ba59b13d23b9f6c9c6acd502b115cb4703951ffbfbbf84c42b67ac8e06eb6040d5d6c7ae448bfc8a2c0b7a0d0fd87b1b04b459a0a60a6d9aa80e24dcb03f37adb6de8bf64a3ead24dceab3d80f1f3a51818b2296d82bc9e26664a3edfe5b18c90ffba30f2d5e25b13369fb826c247a020dc1842527f39ff1f7a1b0debf574d1869ae1785f3419a1b6a48b23f126b3d9b5038d87118620ffed931d12b183e3a11e9a5f8af61e2913a483c398b4c0428fe930bcc638cd9638d5266bc7eabc48b71ea3d3ef94e8828233d0cddd0ef651967a2c3e352d6b64252fca6ab4bce44a5b4e1dcd4b1ff224d962c5c148ae5cf8aa65b8f780e75ef62a5f2325358c7a1091b85834ad4bcc2c3e1f5c243bb9920441f75bf8c3e8f0844d513bbf1bd1f09179588374d6fdc3f8dd01b85a166735e087f16a3a7d59adbda5da85492a297dd3004d20d42a620978ba056cf3a6a68368f93cf47fd9886be2ba17fa37c3df9c2e23675cd8247f3f2f82565091e45c14bbd17517725066ffe27bf57f837898c201cb90644244be792ca0a1472b999c819ab730429b56e2b92b22eff5b039e0dd1f618ef5eef8c4c32aa695e20178795d75e98421d405f655496ba588a8f8931ffd823eaff51f37b8bee54403ea941c73f296e60a779b7c5bf1726cc22acba4629761dc9919949e5069a93daf101abdf852d0fddf6f4b9f25176a7e43fce53823051629f31287f7d4b7435926c25490008532953b866b9fadfbb6758f07bee122017334f2f8e2a0c0c1d2ca8f0419226aaeb37499c06eb89804347c1d5fc040b22ab29911bd5662f56715c4b3624f127b1890da657191d0550f896f0bb82b50de8ecb472d92c08731897e3bba6e276029c91a8d6d5c8f52904c1dca9462d58bf6eec90a873445d90e6cff5373e276424c6b574c5bde98b9df2ff968db22990dab6e05c9b5789050537a1c1c100d8faa0a5173ce9ce7535d2c5142555c88d078af461852781c3b761f796a376343e9ba1599f6591d958c4d2d59c02ccaeb110fa39acdc5b6da32e3132a39f0ce0a57c75c8eb76e8524cf85cc8e7030b44f700d286f7c16f0019df68c91fcd2384ca6af3795d129c1d0a5552cf81bce007917e8e7c1f954a2785c15f9ee0b0815c376d6f8ee577584641cec2ff1ae6ad826151eed26b4970801364130bcad4a9b0b973c54eebff20a1dacb1e163f5be52492a9a5faf26178d6d8931060d3851aaac96dc0193d54c125314dac124a5332e0cc65a632acb756dc69716680e0636f4b1f33737b00d2a92f3c044e580029878a55818903ac5f0d50734d59e3e336d01d95e7f3b674301855128343e1bd98327c20d817d3a36d411a212aded1c65ab42d4ccf44ddba92dd94239cf5e03a0eefcebbfd49805c8ae71405bab51e2f675547dacd28d21f5d65f77091e7ea6db708e1c8a16f9fb2afa2d444912a252754add38e70b440ef8588c0c9afd4e0c996741542c5e1a091f259df9969f6f45964017de9e1ad6443033dfdd9517dd5d5804cf65ca14dcfe0043e1adbcb59eb19fe0e05c1405f9cabec2c3cc6766295c13240f7f6bff50930e626981c463e51425bb720826f23c7cdd4c6ca7ab04972736038e7ea6df5efd3fce4705420bd2f850fc83cf7a65b37d2c41d75d44d1f0a6c2bb77e81007e77b7a0111b01eed158b7815787f27bc8fb9e9eafc34e236c46668317d31303c7952274e5f2a82122ee5d69c36f6fd8aff487adf1e0c0356d8f73e503bbb68518530f6f30e927a3f2a384338455d42f3666fae4266580096c6afb0ea28445bd04c794b0139d26ca5564f8597286ce609c379932beb766aac2096c0c31b44b9b287583ed5e3adb219a8f19efabce5b890e02c140ea2429ee0929c6b1ce3488a2fd52cac78357d8eb64bffc814aa55ad582304f0b45cd81be0a507402d4ebad962869b2d161923637229193ebf66f7be16df4cb065791048091238bed78a5b3e037179abc15fb7fbd90ad6e26b8fdd29d77f047597943297d9bdca49dcccc233a03bcd47bd78ebbebfbdd4dc7ff10aeb10a5fe8b52b716d8737c470fb2427d8f0cc1e6b1fbda5b7961c7bb238d0046511685e66143c1878b104f48c77fb66382f4c449e87856c8dd7888165b3493f814da495c43c28c1da10032afd9fb441941f585fe0d2a7bb1023d349a4f67927aad66cfb15ca34a4d3acc6dccc419da30cfbf8ce39edb8a6228c27a1e3d732d1429785209cb58e2fb1c87c4753900ec24c01a7da6a1d87fa79e60b45ec7aa1df1c9c3469281d2e59437f4629a032f56a6b76ba7d72a180aec21f3cf9677a176a30b2dbcb1676972587a591216cd155382a9e4a78f931bb45043b68aca406c0706ae6fb8dc0ae4791707d087c16de3fbf516918bfb6d1ad34b8a1eced591c60c3ee94e6f4554fea7ffbb7cdef0da8823c8214ebbefb5ec89955b2ad38cf457f751ace2b6f449176d425750387a5f30fa67cd32b6ef54fa7f4750527d8bfa9197fc10c5a02acd05282be3b14822c2c4c6f02f169dad2e75aaeae905e0bd2dc900b8c1c34b4f66c4c80a5cb0ee387aeaddf7e2852f322cced9ebb133903cf73af9cd25c8095d643813ab7bc582a2e528f0a7d5d7fa80d5c2a8391e0589df53d7f12d8f0f7c730dd1a260986af0dcb8257596c58900c83fbd82a0e0d0ee2ec15fa590bc89cb3b59c4f88f30545335420c9ad56bc855f69bd798efd9483d4b618d1fe9dd2af4810bf935af020d8984c1336e274d2743106faa64186a211604250b7662ebc039022f72139de0cc0f08732202f0929820830da53f36f0f2d0fec6fa03d0afcd8f6ccc81e85ea5f902efebbea3bebaf4d2ca79f9b8f3817e69bf143264c238c8d0a87dcd32b0db8b43d42637e02f30f488db374dc468867c57859cb2a770ed6fa46b9487955a128a49ccdb98e36690d40136e65cd3a8de5b9a1332e305a5b79c3822939b6521c23a8bf43773666d3a755a893a5a83d0c8f3cd6eeb9422cda9fe5f7760aae4b0d424d9d836fd1e24661b7ad5346ae5ea440ffdc922506b0d17020822ce655d6d5028c99bc81e8bd5cc9348a3637351b56856ed16fa66e0744298a7a5717fe6582d44a8c133e900df88137ba2b7fbc574379340320bee65b55c4b6ee56b54753692469050d41635dd3399680371aa7b47ce2ffad1c4554c61f1bcaa4f93713bbc7a7708e11f6cd3d86cbc84f8d785722c4d3747242d2a9cc2cf81a9604d40b393341a38adf890610dacac7e03184789177ef1cf1ad59d1b2478f9b3399c93a84376f24146a6a94181c39a0d060d02707e55b4d659d59ee55a2f8304ecce65235d948239c068ba256fedd433a4e84111f3d944e3b4b0474b25cfbdc78d3e0c927ff7c57a217508d5a808eeb02ab85a81672970cb3cf9902fe34eac0c9aaea1f7fca01e426c02c674f26c10f9a87033bfda8504180e1dbfbe01bc9aa53a65027a47c73c11ccaa1bddc68fc87f72a8aa5c4b9174ffca469fd7ee6c38860c37a55893cc1ee73797aa8863bd1cea9eca6cb6ebe9f6f9a2ea3eb43c3d7e99f4e2fec2e8ed74f1bae67d946f4d3da8f36f84d825152da0b02030cba1bde6f7d91ab6b5d01965b128bc015afa0f97d9c456bc035181d3683ef209cc7bc92f479259f50b79b8b283bc5475639dcc0b70f16642a6c0994ff6f84e66e2940f1212d7acee86f5506a36eff628804e9b132c7e45b513c77fce6cd6068a399ee48861c77a5c5eef75771585e123c71e50303fa65b02ad88d6245d011f07ea748c2526fd327444b53babe288d617f092ba7c4d574252d0c826a283a4298533cd83f94be193f39194b3d1cc2953958c9ea46691b1e7b34df4b7c182dd7cf377c96ad6c46cbf9dbca6dfa439f0002d7895a7679b5c2d2a1f794d5d2e98879369304269b26d8ab4f40d58e7e417923cc4887332522d62ab815c0b0349346d37391d602a055d9e523c3f93d530cfc5f6c02d7014570ac804a947fefc0064dc648054926e1a1fe8a3e7251af7d23257d644c538ea0e0b8b502bf57a1f078ad2cebdc97584ca1d534527f3f1fdd9539b2aec6491494ecb059c9350f4bd0cc9368bc2e93ac93a4c48b170c0da8014b5ee331e2cbfaf26967e7b433e8fa9a544c6edaf2fed60e9142079dddc4d2b83c85ce3909222fe90c98f616ce29a464180b8be5783a62b69acd3bf750ac228339692ef62b4011a7b621241680c9218aae169cc3b1ecac54fe7b67756c296a85e6ac0aaf833e8ca5175c09720f4cf0409f96b66b1a63baa2abe312e1da28282502e0788e4078ad2a6e7a10d969b0ca87fd6d564cd9f76786686bd19e4a0c1cb762c5d6ef1baa91967c5d9ba7c14a5b31fb9244e3e9d1629dd20137e40d6a7056d202cc010520c44f1e49692d41fda12a46f00ce246474dda32bf6b51a74ac69d1673324393aa82f872bc30c2c5ebfe2dc401acc313947b5f61ef3e9da37ecfcd45ad088de76b4d0d5152f9725b97af628725069fe1c0cd5420a1d88592f8fd6e98607dff82b864063cc45a7e9bfec287558ffc57f2016f28ee3b109b1019a971af2f6a17fc8cd015aad78e9a47732d629af36d11130efe760e7dbd66a093b0d262838f130762ec65240d1621f3ee2fc8ba80483ede6dee824a62629bf51f1a0f18a9d096f9adccdff2fef8a608441478bd4f82d88c4bfa800e6be882428ed44ba88f32263fe2762a823525c60d2eabe8710839ff51a69f05c1b5f02c171444177e142fc4fd644c1766de0a878edb0a18dc5e30f1b776471ab6631065445f89790c843e4ef2d8ba908503ede0d90c65090f4296786a00869af8f113d9900781f32119d99afe5b5c2b7c39320ef926f17996c55b853dbba8e99e1f30546a2658763bc4684c12a55e27721f90b7912369f01e9ba451d03ed82eac9840c08cecad337bf979f47462c05748b186704250c264fd1bb01ddeda569d9f329a9c88dc2d36124810112a6c459d8860f5596de85f1eaa78ea4434c496d0824cb76ca3931d8328ba018302983645fb5acdb63d0470227baac02358eebb79e5c5db42a9da72cf489dab02d15efc8f7b2c026d5d01c366930de113f3b57d90f584f6428bc98201193618c2fb89678519075191e10823681ea18979b940b86d449da4bb6190f0ce1dd10777cad206a3d7169013ec91c6d20087ae00f97c65c9e2e434ed4069b67ffe99f4000faaf7aa6c81e9cdd0ef51450bfaf0aaf5a473324f876d8443d446a8d9df3bcd33eb7d386fca04decb3d2b6d60cbbc3979384d28b7297e54d23905da1c1e742fc0b8d51da47f6296183ac4050d60b627052873f9db2c2f6d82c7a09c081dc6c20772bb718f61df4ec1139706c03a709b0d08fc2652f23d0edbbe84cdf9591add4569a51f128c6eb3becec1f007aa2ef3cb40e7fa4330fb80bcbc8a495a0d5c640714483bc7416659c5c9147b2b5bf5486659b8d87ca26f3891fc7124e91083dfc7bb8463538025205ce10af0579d142e2715ab18025c201be01280c97b70b22759e146dc0a03d987723cf5547e5a06805fa3cb436b06ab9e54d3af5e63c0cfa035eb419cdeab3ed936b43b4f2f2132fcca403a3451a3e38cc86818a1e9488180f0c7cef05ebd82368aec8395ad9a9a050dcea27a99cdeabe543b7f8a310c3dc2c02cf1c50b7f65c271b911ee4b429b7083e1da6cadf790a66e8335bfe5f3b061f161644086590306bf06fc25aff608521580582ed1c849074bf701c8d705d59f0daaa194ceedc01eb0d36d30151f8c5945e0149d443e16f89d6c43d3e3bd23d8201282e2e8ba43c7e961d359875d9c159819d558229b80c069afd293adf0cadf1826648f20d2dc534e25e9df5076f0c3e3a5d051003a07fa2b05589382ead982b397a3a31424c765ef40d09d9e5b0043d014fc85de00ed70eec4113427cc2a4bba75b9685a9ae3f7468363fca117b4ef6d9e6c8671412fdcfe451c91018df36c636ab0c9b4e815da421ef0ad82488c069d7c50bc471b3ee9190f0a348dbe0372ffbc2553a64027a8dc3ca2546b0662fe9db1d3bcfb6a9e5b0ede062fe0b914fc586ef88cb1a80ddcdcf894c68ca90917fd655e08f6b35dcc04750a3000467a47febf032db4420d26bd1562939256f5b1d3cbe5e7a4a1356cb6e6e734312e827262598111b7c706ee07d004848f3e6d86d87bf4e3c886c3083d34eaecf54ed44b8c0c22b7ac1c38b6a12fe65b16aa96c5b5d5e34c8af5c7e14ad45c5a39d945b635e36f9b5e25c2aa7cd6c473801bab815baf3197e5d376f2095bf33af2b4dacbb460cc2184e8d7a9514e04cf035ffe6c8e3f9422328ad9d99d11dc07fbe8340a68102bdd84787031d8087ec2acbd020c38dfae71c08a3e6457960b89a7cfa3812ab5b45695de143802b058ec501d5389f520fc762e4485379bb6edb5fb74478d05d5210307b45688c9395a9c430c69d05d7d7ae13d923c2fed1ab8bc7c199c1128e2c8c53a9152da32ff4329a978861bffb13097f34ce69c24eae066fb4901d6f8a1a36cfffbbc16036577988b93fe149458a9b127aa7416c7fa41a0866e313fcc640c7e98d8134605fdb5fe35f612436aa52f29919aadbe458ec5f081dec839b019ff98409584c484295f266d73db1808ab434a5e5087a4ec54add2c634473f048f630850a7936a0d00a49448359b060e604478e7a3cbec378a4b64b2a0253178b9cc917d29ac32e228aa5ab5d44540c39feaa76641bc34a722fc0890f47c19bb07525cc20bf42d223ac330c526d3342f79824ce1ac0288d33e9559cac689b9b22176fed3285f16c124f9052ce0262e2638113610aa02de620a614660125630d6933404d0fa0ae9840d3a0cfede162aabe6af37ae43e65c1659da8dcb8bbab222ea2bfd52158205d77676948474444285ee3d1031415a8d40989af57d0fcc30791b60bacedddc51eadeb810ab055a06f11cc4baabe177bb915f77bf437456d53746e6d509cfaf359ddaa541945d492a9f7e451cb1336c377fe47e8c8146f0ce15967605c36f694570797919d79d3f22bc21338ee688d351f40f832473679ad0eb815c3b82201083767fa0494c23fa78ea915d900777eef14c6e00759f6559f3b852889d1e1300997180769433c9ba52e53103ae1dedb03877cb573f8163aeb9c3457b8855dbc0f89ac1e22d71ee880876ecc5fb6bd3743166ef97ad00621db685043db2268d4880911c3192faa018d479d35d8d1182909a8230b3b280306060c0828602a11d3c26b95e9d10b3cde38a896f9694d71a422f7e6e125e0b3095f8b94cf8ad0074861f0526de4eb5b20c02ddfe45d4606687bf87b75351af068697ca2024a114bc43b080bc663138dddbd91b58af266bb1cb82376065850f2438e5ef0f72116a757234b90a236abf3ccbf726afc4045a024ab49e296b3e30add7e3d94dc3f572148ace972b51896158dd2486b2c6be6613962f2afcee110fcd03752c2564886e926cb791b77a024d5dac742f466dbd8d480ed298a03d1963ae9678b2353976fc32d044bd537c96286f576380e2563002214de040924e2666e6a5406253c2fff219c1b783208c6c54aeef52efd86391549af298fb804e380283b0afcb78bb3462e9c3f98b2c432f7ddc3f60dcb64947e6f7fbd33312af2a6664fa532248fd60100776273c63936cbbd9faa227d754e84f0a377c7a053f695a8e2f951781c5fbc9e13713c5719a055655b1a3c85df32226dcb0ade814c74553cc42d55a3d37cd4159dda532f36a226100da787ea5ec9a85fd688fa423406706880aa8741eb81ced6786d2206bde0f1f14a164da9be3f295af65b6d0c8c508d04bd94eb38ff67553ea9964863d86eedce7ed7f3ec00e271bd7dbebbd3012a15b10ef049d505b09a0e1c8f2e4af851eeb57ae0a59b36a4ea7c1ced276a8e3189a76a4759f64b686a34d0c367af473281c93c311a6d7ccea7c4d0bd0a597c5780a564e8dfed53f92e02efbd5b8584c49adbf8082202e1005a2e026f0f953bfb68985da80ddb302fb1fe53099a84f0f69217bae3c72cd2755f05ec8b7353a7c141cc508c2bf17c823568625f6bf0c5d21d25d3b7b962c31a8ef6a4acead578c805a5d2a32b5bcc1ff4620f1454c06fc41d944d3f8eddba4abfca149a87c00c96861e6c70171ecd06697898f02e9b9bfb27d75fb007e339e36a53a305ad7f9d25849168034e797faafabd66830b8f9c8175b5ff12ab090c842c2c5ed617c1aba776dbea586d47e12d3f76698f32ef3c4203133d48e5fcd06b6aef6dd19413aff37ca1d835e84ae1589e8c556d08d397385306cd8c2d076445ae22290abc2b4c605c67c92255e477a3c9dfe2961f517b2f1a1f98e172a94b41b35fbe82c7635be4d2e25dfc087bd4ad3ccb24d866c2260fc435629d83e67a53c7997faf9ddfe0f1a094b90e182cae8f400df5851c5dc81070a94d7090b4f7a2c9a28bb7a7bdcc827b8faae6c96be9da3ae5cdf0ed37174827bd00123243711d5f23f7358e8581e07e111969088927e431921057a7018db4f05fe45a6e87974525345d0f4201e4b9a1066c58f7c9fa1a983c886aa31723c0a647574b1e7f62aa0f5275bda75fbaf0b6c854cb81ce0d32ad8c8c0c1b8a229e87cb9a1732770adb1b1d021c8b1bf2e7cd1a8425e7de5ec76912e32612feafbbd5067366d4f6cfaa2ebba89c244e38ac1848f65688113b4cbb00f4df5e9f967e4b0343224a8761e5681ef8c8600b5cfa88897c6ee6006772ee243a846a70488e5b0583a002a2f2a981fa282f50aa7c692f9c22d6ae9391da0c528266dea46d3bead41b34609b80b4aad8411d15d7bd58d54dd9ee4994ef6eb309769404863dc5770652684230de6c1bc34eeca7a4f5983ffbcb3cb9b77094d7a6641e30e2ff7b58244c4a7d66a224fc73c3dacf9707ad2b388a2df131c0dfa01475e00f26579b4db6b8c81b01f8dceeabc526e0bf7c2a7c8b82003a81293ee0ddfb8a24ff7026d539b8b2780e5965aac9eac7aea354e2b59607c75a2525cc2691522fc846348c569d2782bf2ec39a9505a2e7e2be5dcf043e887a3909f20e64c5b61bcd62914b67475894e367c659fc87c7ef287e541c0580820c44b96818f4c578a89457cff0a111656195ff39dcabe00a4ec371a64f44fa93a26c248bb92a3510ecf383431da8a9b48e8c300e638fea604fe3149bdb0c3d4ead7b33baef72c1bb97374d477238684d02964447c4739831cd3be677baa64a50f53e97a3d464a3119416f27791a9e6c6cb057c10b20eb1f8006045915de53e0c26c32b206545b513361c209eb5d714ffc40571be3d7a5388040dcdac60c98dee31a1fdb29ec6fb2a7b7826c49b237a480a70d2b47abdc06061b658cdd1cb9bf5b763c8ec600e7758d01574350d6c6e1d60b4e536c2223e67afa358bdf2fb83f46c36faee5e952cffc7653ab8f4356a80dbf759b073d9753f40a7fa9f22bda22feb177c7194e111586db390cc071d8cacba766616d3d28dcba1884101f540629ad04f29aa46ce54875214f45ac1929a17efc5d5ff497dde02a86ee43c56d94e37d881bef31370b82bb4080f336d86ee7bd87c1eeb784674eb159183e61c505aec7bb9a8ca434ab54d99ac5faff6c5d6b6190b4604edafe7602725d4e432668e218844a00c83d94910ae875d0d244c2d25bfe03ad24189e748b49ef3e337d155cb1d12415b2d306c331d968ce34eb17e1e5ce6dceae033221930cc227d922b3f8e49052af72fc742e7f64231151316c8c6a49756fe90611ea0a34ecbac2b08659e1589fc1c014301ae4f03af80798a26a7d5ee304da0307934fb06b9fd870a567142d6f9fca3766583ec19b6fa8f3fcf80c5a6289bf439869c9458c631cca74c5c2919a62e60e83173ca3d51cc0c2ee5d310c3017446ea99dbf17e45b6547b7404af80578d0bfa2a2e223de603a161b3e737a5e14d31076d91d1c2532022981fd33ea10fe4dd9748b6c179db446de0c85ace5cc1d38f32f11632cbb4923681ce70288d2dbd871cb7b4f712b5de70904a97a971bccf0935b41d55e2231d288963c89f513788b6dd0a72dc6cad7571bd49095cac70266615a2f56a7ef8f40a3407d7d23ece8c28f29ce3086a2cb574f596e87dbb42db84396e31b3559495f6b293d4a4c32f6e08da2a3e3cbf989f77a30a2a9a5408aef9ab5d4f6c6359af11616234ac8df6f2fc2ca078671052b58a58717cdb8f7338188aa854317065ff09274682b481c7c00761e56fc9738831c47ee037135f67e6782d107b9e766616f31c6d92bb9b1935ff7942d5b97ce1043feb3cfaa989df31fdb1ca70f089de7c428da8c5be8ec5489f4f70e02ac760285c745a8abe702411ee6478f1ff238c91331fb7c9f7e8c11d1b56969827214fcbba467c486a3dc350186b3479149d8c84033fe7b45577ddf9951f8c7d313be50aeccb0088f713c85a7e26f7d4ee4286cf76a7a2c7a3128aec9c4a80f6fb674860f233d0370ab46f52ea0063cc10b4f42083e24cee78ab38e525c62f6d3459cfd2e402ca828bb7dde00c253bada473c96400a8a7af7be530484d451e7d0576c3fbe7033f646c0ca96987a0d6d88fe5264e02f8fd1372e97792c7ff69fd9a707e946a3431b8e915a8f1f40b0a7d143a84711044d04c2a38f711f3836d164cf570adf2c52b8ec11aa81b2b11d140fcf1ba472341254250a257ce28c45ae9eb78721e0b95f62a590570af783767d82bb7543fbd939831cac10e77cf998b9d839117f90bd79de7d5cfb7505e4d73ebdb01ea70b74c731d0de815c11865550576078c037bbfc230e67fdf301e3ec136d33883daed597ae120068156ad3d39309182dd8b5575f60095fae5032c32cf1f71be29029fa6f7255406308b62dbc6c96c16b7a3fdb46ce9d9c8b75b6633b1e25e4e2397fa114e03a4ddfc775a5f89529346a3b323f335548f3509df1f66196e29e143d894538b5fb2deb316b37c6691abb27fe70392616e7738d997275b57582cef40687c9ea371eb5a92ccb657a374e00e12c4ab813edb61551dbfc72096bf5f4504d5e100b43c4e966bba7259c140b78763941e7422d3f2a93a233d3c0bfdc2e66573f2154b704dbd7240428e730dc946a3197966d4ef4b49849c1b8f909ec6f85a61d2c10df9973da43ce9e1a1bc839b2f27111562481bc441a1d81c1e1a42539578fa596a4c64d33801502af3206e2815c20f17cb18b34eaff4759b4ba2b8a1910d800548bebb1fa7ea396c9226d3942fcd143b82756ff90216983b2c38195a2209a9fe94fcf55a8486c0aaf39192193df9d29861475608405413b9cf63e2dda0387e584557b375417eac790c6426b54545580eca4230baa951d3f794839f298df1dfcebe516779b8f836a13b7b5131af60815643a81c8532a515194590dbbf732dfb6b1385a60997c996092930b540eff3c752b4690ebe1b51dbcd6f7b236aaf52dac47349eded748b29e98671e3abc1c8c709864e7db48f5e5aaedfb813ff98170c4c906183f3499a29fd4e1170763ef6e609c031eed2928d3f64b41322b0d344ed766287a606e867893b80c4193c3d8d099b7c172c1cabad6b6ae5a03f8fe44702f64c5945cc361ac2b922c745dc3a0e52170a8b868a9a99214d32c2d5488660dd505370a7bb44cdde5f5e20469df699e413a7a82e575133949a886b0a85e982ad212fd1a3358c03202537012e1042cc021f1fc2f1e2f69e3f5fc69586863d04233c70c67a200544293ec900dddf6b2d11057abe556716e77e2c6f33773cbcd6505fd12b730662cb73a33524e1b8fbb44f47cf79b169db08e4983c47122b44cbabec83ddfc9b9879c920daf012b9125043d7c8c947672e39a432eb996da0346c12ebe296d5ef86c04bdbf97d0838cc47722591529426c888120f494623c8ca745e7bde42f033b12b200349667d957ce22defa6472577e8c3403c97d861aad31cbd9872dddf40ae5517290c30336b4ab05ecf315fa4dcf7d54e0abfe863789dd29bb7de96256364b37014fb769a905d81d91db17d676cd29e964052f7c3cc20bc31ad13a07096a8ce94a29a7ead5ef9e3873d17e10035251cf0789c30626589c620bc15db979973f968bc51ca38499f160774d8d0e3fc023c3d9cabb0d79c3859af43cb82b0972fb5bd0451c8fc205e9a89beb24bdb90a300ea93ed27d371272a2b7feb01b267522691ed2c6713a7960d581b6f08707eda946c2820ca83cf4be01aa3fc22b97ef0d9eab7474b62d61b968b15df3a9ed4a49b5f6673b19f4fa3ac829350030f4d0ff12d08f6d045d612aacc17bef36125d94c8ce7e8c376661ea3dd51d7ec152461df7fd1fe385e4bda6afcc21b7cf46568cbc8a8f1685713651b3ab9bf6b8b6d77a3ff5e17946fa60f03b5556343f9b26dbf2da31481d849c7ebb5708311ad9af5f28d11b8bade4b59a1e886940f9ab2673615cded17827e600c4491d092cbbeb83e75b61f8f7e43137270aa229846ebf2516b112c0548eda137730c158d9ecb5e88da65f60e8ef6996bdc0a7c919ca40c3ca6ddc64aeb6750122efd27599cbe9f2694420b052f5aa8bf34ab56cf60281dade0d80ab5ee2015950760cc464bb5a650639599cf51ad707859b58583a9cac7b56be079f9a79c77a43bdb112f67242bfa4d0216cdee514d31da13a5e98785c4bf7d61857120c6e6f1874427c0b2e4196b039e055bb68946c0b0c94a0fae07cbd7d73c5422e3bf85c9501a0fbba46067bd205bbfbda3414e67e11408f26c3ce13fc8716c13b2368fa0a7333fc32c934b5b6b88499d23a73f113ce2f78c7783f61bca585da2237b391d26bd314b9371b46623175c829391fbc9ddc9c457803483ad12eaae81175efa5688c052353b1278aff3d8749c2168e8086fe0caeddaafecdda5d026ef5febf95693971d5ef808428122a59508884d13e3850b85fd62bc7bf557bf2688395d9274be9bbaa7056e686eabfec83924d43a66123189f2082677d00d400b3ccc70a6ae8a0e51c91239f74ad59bba6c2605cccdc3b45eebc6278680487408c5dd6fa88caea912aef58baabea069e5e3aca682fe862279bcaebb0747b8e1a15ed6935e8243b8ea1d82d3c1d269441615b781b96fc90a1ddb0dd3a09e1305ad5c5e1a83c983c9a5b26b85134d8fa2b6c49980ad4b41139f495b089b8246bb8275350650b3f1f3827de38794ba20e759213557e28d63c52e0bc544ac04835cedca8f3c710d9cbdc788b8fc0f1110224cc2b18496f94625cc212cd50c26c8b1aab296c0d0c401aaec662bba004214a5e1e504d00df07743a50b84a20da23509701b18d74d9720df6c307954163fb046707381628b6ae37d744af57d4a69dc94544839afc45c5d37ca938a661cdf610fd6d7d00e0297fe2c1ea1088d0d8b1eea0f88173fd4204ea620eb50577899de02d8bad84572e644d7f304528410139c486471e5a3feba05c521a944008400f68bdee1dc4a3ff144754562dc1f8e36d4908a8ce3900149e068c5ddc2bf7352f97b67d8ef73ec554c53107e224ef38744d698be388a36558396286018f8e4341c276329c197419a55bb661860203360635699aba67057a06a8c9fa465042c970ab06bffceff815f15a7bc5e58e0d8ff42f315cfa4d62dc52254a72ad4bd4dac831d0d555fd13a4345fe43929044a3868db95c0efae99e33024a91678c6e0ba4f1c4614f112298a91099575fd01f35c6d2805b54b8ef915a0a1974cdab37e4f9fe8478f06420bbeb3470c50562ac96dbd76880c6314d08f2d6c580769254fabccf3024c8c87f183ddc59f956e153bd0f32b917372c3d90f9e4dbd91733e02b776e3a37fb352177f356d2d6abe0e27e1020aef95ca9501cc8f970644ea38ab791bc6174b0f93a45676e51880c8122b57d4d3ecf31473d3d73dc714cf5eb242fed7655e7f8b8ce8abebee40c7a54eae323fdef4342353209fe6d571015ed0662599cc037fe65cde223323cb667be7098c891768af9a59cf374c38b14bc76e4baf0bd9f60dbcfce69614804751ca0ba02f2c225301e95a7ce464d20896bc6a0711c090f8b92dfc74df518b98d2e9c44ed8826c5efcea737c99d892c9272cec11b64042e1ff318905688cf7ffb127e2c8ef73847c7a9db6ab4b3b0e4f62de6b0046570843820c3595427b93bfc5f01966c9c08e039632d606b421d42e3a3122c7cbfef4c26f9137f8bc83128532e2da540b512892763620e48a1a11ce06959ff42ef35618e084675e2ac38bee911a9308aac5faed4fd10f0490e0549d046d8a8966ffc2300aaf24287f5b10e815f380b6c637e455c7487d23895942e474617f63727434608b78d1d71a52011d62ba4cbb8e6f7cc6c72a4594a5152ce405d0904b65f90443647eb9b4a6bdce62ae838777838f61461f76c78629417896393e3956fec5ab88009dbd47def7222a713f7a043b45960be9c85726046dfc9915f672d68cfd2df23e843248e42c55658053b2ef46e034f329dea1b95db8fa122610d05f1d3e2b56f8a55df7728ab6a7d89b231e3c3ab7d80de0a424314c80b44636da009944b05b0a92330a696d809bce8e3858fefa857307c67267a5f308939b3b04a2f5be43f0bba4a21340e8850ee44bd32d816e28bbd048510e0f07c8b157bffded85c47ce5efe8d587760b42a27a91d73d2f5c474b5ebd1e9daa1031731247bbf38539ba9079310751095f282feea25e06e0eb8013b0748967aada919b63b371b36e9a6ff9f85cadfc0086888d3e4c4ce7d132963ef6dd00c30244257a2c27fe57208de0d3a75fc066079f61bd5194ba36085ae111358e39c9c31e3aefe93ddb65d76121892b42217e0bce39213530252f2b1061739a2a8ff2cb0d18b666129a58e7d90d01c42efb3ddb7d2a79f91ce4259d046dc62cec72e27dd9958d121958b8cb0b516400d5d192d14bf702b39dc258f3c8ecdbcfb728c93bf0e21d55c15c0993f7ab96609de103dd557c2d524bc88ed1718fcbf8fdc98b747ce2f1b644d9bce3dbb8da2714a75d01abd6d8460f3542116d53f8bc087a75de0d6255d83e9e7bb1dc70a49cf6ab6253adde3dc66f5ec0f20078803703e6c0c2df6f1d9bd0174be30e5f6d7c14408a312efe3304f77a101bf4f603d625f73ce2991c159d130e50ccc6dd4cf307ac62f5b413339614d8aa4e6c62aca2dca4ba4322df7d9e53a04c10a6f830c9496ff049175144c732dcf6e11b21e1a3c34dfabc359417e0b40084d742a315d21d301fd726873fe40d894bc63c28712350927da3d5ff2259ca6030409894e8abd466f8ef39b445d6fb3b001386bd5cd06817d389f6703a29ec6b96b4dbe567208f4e898f5df3fcc978617d795070531853c2bb85490fe47235d7a5dd886c3f2e5b0fbc6a4706c831ff431a1413fd9cb8eefbd141fb89d8ccb4f1d84db40ba232456cf3da786c13d80578926e88dd463136c1eec11371638c761ec304ee4e9f841be1b551ac4d90ebf844de00d39ec53291bbf04ff3c62c6d142b13e4363cc937c8b727b14c6c2ef8c9b8616e3bc7c404b9033e63c43edb96633081dcb1a7f900ef8703101a1ad98eb930a7e1b97e9acc451a110815c6f260ae147215cd6080c1d64277b5d8cafee5bf002140880206ee579d5a47b870fb53fc031600e434a4115f25285cfa4f4f0bdcdf13a7438d782501baff4f7fc766bdbd945d27a06955017205bc19d8db6e94630155ac8569da958756e5dc7a867fac67e4c37f78e02b2494fa2e9c4c7f5c19d07261b9c79e6befbe9eaea9d93a626d518130d556bb2780067872ad6296d94d20145ae489c80e08e16be452182e20ee11d6c84826aea4ba72c00af4a0729d4c0645318d76e12bb22897c7bf47b2507b1ac2012fa997b1b21d74c8e4dc77ece147b4382f8e6682d703f87bfce3e6e023575a099be8e5e53c7a7b13d05bffbbe7d06beffead5d4ac5ffcf87f446eedfa695fa4d30639d5c882fb4565aedb7532ccb03f91c1e62e42733792b832780ae75b788421c3057b65f644d8500e9ef5dde00313d060883b36654b37e701db323e3599d22ff2898b99bd389cd78462e2d1713a1e10e8d0496058c7759a747168a88e0912eaa5a4110e1621ef399889a9147ee66a887ecd31e10f275ad4d49624c2b8ee3be7ea144b30513ec44c0467bb7292d63432c537ed7be1dfcefc8f7d7026c655f1723ed8609642a0121b9efa7ed5337c84eb6033ebea0d6660e5d9c433b354eeffa5acb82fd18113725029c2dce85121824d0432a22c968753e191a0c614908cf32009b8dc9315749b3dfafeff63957ea93216955c8ad737a6943754629a9ab6eca1de2431c433a8a5874ddd1c104ce43bce15e7c5281fe3d43777e609865a15b8c54edcee82908ae8474b1c6113f825c3c268f5932abaf3effc4b8374dd955c1360715b4eae24b70e6b4a8a608ee64fd819e7e7427aa9104cafe71ecfee16256ad1db8633131892916f68b1b4df27448d9e0548f46ca27cc22ee769fd43689142056a9f5b238c61ae0a972cd7b4c2976fc40ce43598397c25b39023057062db279d9dd704ab57e7a9f256e12dfb2f71045a45adcb0893618ec39aab28d25434c403a66eca6678587a6cb5cd2e226d73f13d6874be51e9e7cc9c27b9adf659a7a84aa5fcc116e62c7396bfc5e65d8e3644fc574d78c5e65441e371c93679e11110716b06461a03411a03c2838b08b2cf0127cc74ba0092b1ad5a92064827e4311ccc57a32623e8160bfa54f55a02367d735489d9250bc7444ad09fa4011745a603251377283c768cb5c484856a6546e21820e7d8defc2d1051d8741d1fcff6e3afa25fe6eb1d4ccc21a1441702c8334d0160dd61b8cceead9f5497644489b6a9a94724c2558da2cc21041818276151e62800e87bb784343be2f9695dc7712a822ec63678d62f48030748e0ff5eaad4f8aab0ab3f69a0547101e7f12fd0c713326ec52f4474e845d530008177e5fad694f26077061351540488502423a5a0a4e07186845e08b6b04ab65d7099b7a1a8611732721b5da9f66cdd07977ee681eec66f5b8407286a61f91c6533e079815fec0ecbf94d654e80f58c8f5bffa133b6bd315a4bf66518d5f9cf61f9cc9feda3fc6a3858d976ddc14db23450179245680af8dc636859b16562e7d3dc8e5b01b824f2cb788a91dd875f8770c9bacc4ef005c4756d518412ae982efebdbd5614e885f1d8a52d779495966243b26eee63bd9f29d99922463469f3677c1c2d61a0d987c4ef925473e456adaf7e08f61e5a0da446837b09a7ddf01f5c6e7bfc7417e6c9a6ad44e1e0c95085d765f9ff117581ef440aea3c34fb5271a81eaacb110dcb57d02811ba1888e4a754e7107ba880753ee8e7b3184d58e713232af334e7c4d840d02009e192fc39ed4168a57479aebcf50f4c707ed87f6ff027877bb101b06b997f606bf8980b37dbc240b2b8d8d4617b6a6de3a747cf0410729f64d3e9bd97e9c7410c221b6260e91274c8f48b224f129dac0b40b9e5e0f36dee6d43b967cd890f9e009a2ab399f22c247cf1dedd2dfe663a4a9be1210c5852983b2ca58e3ca76b68d431bcddb2f408a6d31e0d7ec72d79d631816ba894ef7ae555f22ea89573cca6dbab21580e0044ba2c248ffd3ee84fd4ea0b930b4eea019356d52a345547cb9891da4b704deee849a0f592054324e3a460a86bfd5c3faa9746147ef9f39aa45c32a0ad07be8968cc574f6a47426c4790b0d42a3ebcb0101068d9b187854ab7851afb2d3c74d4c361768060d777b221a7b837f3344ffd1da36b5466837b209217befbd03ce0fc10f180f1e12272f2022c963cdcccc984c26141825818b2d4c2f2c16cb5a8b8221ba74b1844dbdbcbc7cdf770221b20061e843a15026f8a107272f4075a7d3c9f3bc4d8a294358e1e5e8bace643269535c70842f4caee79b1c3972586b3323908e10c2b69e71dcdcdc7cdf47931085186e7c33cf323870e09049675cb182623dc3c8c8dc069996f13c4fda608c2186bc97e71818181893c9149788e20324986abe72b95ccfa9e7554ccc6d90e9186bad8e0b74d085fd9f69ae6ab55acfa767d56a751b647af57ddf0d54926001167fb6b96b6666e6b97bc62a95ea3823a922a888346ceef36383baebb9e62d168bf59ce3f9627c1b641abb704e81148cd0058b9afbfcd4dce634ad679acfbcbcbc3cdf3cffdedbc23905414d7a90c5c6c6e6f987e63e3f34afb9cdccb3ebac542af58ce3d9e6ff0cce288861d18409353535cf3faefbfcb84ef31ad673eb2fa7d3e959e6b9c6c6c68685f309626cb0c007343434cf3fadfbfcb4ee3acdcbf3cc535dd73dc33cd3d4d4d4bce0bc5571842082e072b99e7f66eef333f3d65da967d64f3972e4788e7976d1d0d0a470ce8c70c58b315aadd6f30feb3e3faccfbc757a7e79777373f3bc7a6eb95cae13ced40b1f3071626666e6f9e7e53e3f2f677da67b4e3d070e1c389e55cf33ad56abc35936218a9626b058ace79fd47d7e527f390b67fb1ccfa7dfc8c8c83ce367d6cccc6d90e9991c38cba2185cc1c5cbcbcbf3cfe93e3fa7a7fe82f3f79be7ee386060609eeff30b8b751b649a7583337c43072b74904add86994e3dff74f7f9e932ea389e735c262626e6f9cfa99797db20d32f38704e32053680d0e1743a3dffe4b8cf4f8e773fdd1c66b55a3ddb3c9f52a9db20d32993c994240a13bc8875dd6d98e9eef9e7e63e3f37cff10e67d3619e713c06e79f1a4aadfa8f0d5eab6ec3a955cf35cfdd7f6a987dfa8f0da63edd06993e2169d28422a89123478ee71f1cf7f9c1f19be7887996f96ab55aad300b31389f4008493e48b9b9b979fe91b9cf8fcc71fc06e70fe62a1ff0154da08314ca7803070e1ccf3f30f7f981b9cc71e08cfaea39e6b8077cc56d083668a0868c8c0ccc6570f6ae4aa552e19c2951b471050c0c0c0ccea6eb904be8a0871b589bd7f77df1890f54e0f0d5dcc057bcc1280930a0a0680e5fd1f33c146871820dc0f062ee727db7f62693c9748220de188a12739f9f18d3ea2d16eadf7d7e50ff6eadb5590fb0b4c009abfbfcac1e7315cef632cfaacfc0c0c0fc08ab61f00abea277d47d7ebca3fe7ddf87b30cce530b3184c48889b90d331df3fca3bacf8feaabc33cb362626262f0f799eedde7c774ef28140a85330cce49761046154cac56abe79fef3e3fdf555fe15cfaeaf9058542a170b7d99beef3636fbae7791ece2b9c53f0022551e8814aa57afed9beab70e68e7a4e799ee7e1aa597b93c9741b6ada84330ae78d09194c82e8efbb0d33fd3dff68f7f9d9aefdc3b9de7b3e994ca61f61b50953f88a3ef2a5fbfc486b6f434d5b9c3d9ce993294380d2b9c3d6da1f61b5c510bee2f34f769fed3fdab3e71f1bb6defe63c34b6fb76126ffd8506af91f1b542d6f434dcbfff894cedd47fea7c4dd7a3bed5e964bbe8e6838620276605d74d61cc6c31d2ec7cc61eb647a7788e3509552e1f03b0b1fde04570038d716c0632ec6432b04e03bfe722f1ec2f737475d15007015feba778f8776e8f8cbedc581876e7e1caf37071ed2f1f215bedd193ca4428ee35cbb2d8ce3f87f765d7868c675796bf0500e9cbf2e73875a1f821327c3980f505a00355fe980d1d4dcf5d31daac14c56800d79aff9cc4b3398890966f3161e92f9e92ecce40536b47de6ac3b546a7d75d51d6aadeebac975d35798c9840dc5fc74ee0eb930931db021d45da6974eef90093341006cc8bea68499b86043a5cfbc8599ac6043add3a7ee500076602632b0a1fa99ebc04c2a6ca875f97987940c01c156703d009889061b32bde62f98490a36f4f2d361ee100e66d2820db59ebd30931bd810eba703e0dd1d02006652820da5ee52013339c186bad73c0766e20336a47de6df1dba379809006043adcf1f33c1810dc1fcc4fd8f77080766226143df5d57320404c39849026043a7d7e0216e75d5994458cd2f66b2031be23e838766ce24c29edde60eb5f01093086bbde63477a825f3973389b0193c34343474ba006e12a396b9acfb8ab92f5c134c1cf817f8d555dd9c89039fba314c1c78d48d411307fe833fdd6fe2c09bae8f2bc3c481efe0ed8d55260e7ce972b75e114c1c6825bbf4b6408289032f6f843271e0e38d4613071e2826d921ab140a5f5710a09a17598080d4841b08610d2866bae0666004b551c0411050e8a2cb115e2023861a5dcfb39ae829046cce49274cc3580f44330ae5aaa6f590436b9aa6cd5a31d5341ed668ad094cd3feca92afaa41adca17ad995ad33458b597a6fdbb4283215ad3b40cb328fe585cd7f04a124fe8ace11525bca892bac162b1a26859a665f46301c9a00915691c313405134f9a706d4381196fb000063ad8c114cc88e1810b8e073096c829e30a4e871994a4a8620a9dd727bbe6c381d20b0d4f6fc4377a191632713003a444c32134c430c7ff0075769abd33cc8009d43cf2252f73f0c9f3c828de0d4928c539cb4e313d3492e18ca425049ebe079ef24809e1fc41942a3046988e518a3ade747cc4e293afb1a4a3f3474f4b1c1287af4bbe1a46ffc2c7ac6635117a61d6dca1acd3bc8c5e90f8844f6b287534281b071d3ac6ac289bda953494507f98999669190bb81fb432566850c94289153944d1c60b0f43783c3cf1438c871d4c192da39e1ac69870c99cb041393e4a430dcff39a9085671d0d9f7d34845920d576280caa80cbb6d34ddbb4cd09ab1d5a4dd35657801045c321d3325a46a578d5f9eb89c350c7048851440f62406c914518b079c8aa5fc32b5ad4e8fc9d2ee1d3e0845cce58020e98a00425ced80296a93a6352d4d9ec2cc6a48ace86806519841d6171d530c6a4056d1b5e9182095f1016ce1d24b228064b6048e49124b150483282c9278139489a02260f211bb02450073089a9c408c446253ecec6c8640b93319870d1cd84a8616c87a4ded130b684084db3c01ff4f35a52cf48212061f24a74e63ad348e951668fa4f478ce7b0cdcbb0791f29d47a650a79b6ec237d89f0e612953e9a64318ca96b8a0b4a09e4f694b50a99798079102637f2add74bae964ea342825cda8e7ad96a5e74f9f46d4f39e56a459d1a668556c7669a03f99f00da8970e61a7c7d082c15e7515be21757b08337d086c6d7515eaab432f86d455cf8a4c537afe74abf4fceab6b4af0e04b3f4d2901d0624a6cbd7c380e4f478ee34f8c450df3d06eedf8348f16ea31703eaa5472f86d4ed0b42a5db976e716b7b4c6694ba5b7a1e95b4e11760b0959e7fc1595617a9e755b7a5e1178e7a3ed3426f6cee6a481367d2e0f313dbc7270210661f01084bdd2786160c37981e430b06ee74ee1096fa106823ca83c174d4a117c3e9a5d32cf23553971e512dadecf64030ed666d4bcf5beac5608ae114010813aae74e3de8c510b1c6e116fdb78547f2c88c48d3325f6f8be2173c4c916892bdad0cbf40b94c1c20d80c37c427a7749645598ef2d4d2b7f546588552f10d5c122daaf388cb0c9a4ba6d1cc327166d1c4815e9049046192cbc49945728aac32776284c95b7a09dfc019c50b274e96b80503bea15e623871200cc26cec4ad28a7cbd208b264e2cc122ce21098f30aef008e34a0956710e49cda5b7b4156a04837cbd7cc533de160cf1f5f115cf22ef85c9236995b9258842a145d10a1c7030824ddccaa8514fdccaf00b1296a9959e9f55e6ce0ddcb432776ea8279a53a6d1ccb265eee814a1465252d1dc81568ea496b903611c173969d4f313cadc89c748a8c010d1908116f54882822a4e228d70048320580e738c253c0982c92c3de5e7d4921ae248f2016532b5c41544382cd9e10c211c0d633b64d13528358c91c1041955c85801848737aae083b11cdc20ead8e4a30dafe0d0a4238c41e84bf2c1980e6e7427f9606c07281ade6b18db01890ee2fb1ac67668d2f113804c9472ca3832d4032d5862a0c6183bc066aa27192be839af0c49d133a78cfad23046c692d61a5e29628d16cc90f3e204184fcc90a3c109f482329e1c21a1c31488b84039a17a219453c612a848228d1c84500413621f1bd9156ebce1434e1999118692c4c8a2093438420c60b4e9bf24adaf14b146d3bbe40e34ba913b10965346ed1a5eb9b2840bb449a90e5b9a3281512a9b7eda65adb4e7af57f2f5cd1d4a7520a3690f304ab3430dd72ca394ea1046531d6094d28c7a0daf70e30d3a74e3b2e2043366b889b520a9618c056e34011ac658a045c7a0282475e66f68a538d7f8848fd68d7ba5dcc4157fd9b5bbc2f2d137ed794db03d23e97a0ee779ea0dd1f0ea9b3b249824b8e2a3cf3069c811f9ca4e5fb379bb3eca4e8223d9a9d479cb5776e5cb0781082210291f8cb1204bd31fc5b6671d990588a5a1f6ea21772a0cde42137cf04ad09646358c754923bb9ae4b04361f3c71aa6f2452fa7921f7a9eca9d18141414a40436bfc211e983dfdca1b0f8ad244e7c1cc217d3f00a10849a368ce9e045e79ba8c9f9830e9fbc8d477cb5614c872b477c5cc3980e5a74bc6cc16611c64fb23a9bf411cb67126b1a6641678f6d4f74a73b7cf7ad6c77937cf633744eeed3bed52c42cf05dad9b9cc239245284da555b74ab4846988b4933a134be94e69a5f4dba59f943ecb3a9c7d4254b47bef2e3cd21ea10e506b5f505050100cc21f705a4c4566b8351f3b6b1ec9234f87ec8c6f4d2c44f67c73413da21cad4c44435d74fe10149d75e4e89c03a78c9f103402ea383f2159c54628a529e2f8830fe21e7884859cf8cec472205ac1f7c5265f3c34c5ac40d13066050901348c557146c389aab7fbe46b560e559380d2f31372d13e1cc082d431c1d80a6e744c3e7adeed5676f25e1df2355fef4da769ffe42b4341f9aaf23567ddb8bbaad1d30e3d21daf48ac46b9d7c4ddc13f1e7923a12b324953a517e7a2ec42e2db18fc8637e7ad2894fb68fdfe4803fb4cf5bda49cf486b58c297d6f3d423423b2729325bbb9d9d766b90714a484d3eb3351ce10e791e297bc258a1d10adc686894c4926ec9d3101b4b29fdd985bdeaf93adfc9fbb12296b2e4b012ee8e36206c9ca82a5f972f781d11b592af967618f3014bd3968685c4b63cd99946f02d4c408619a264a886100de2a273d7421e1578258c33ae845183ced08caf33dc2261da9538409145be606757e20045917cc1a657e2004514f9829de375d7120728b8902f085fb4279672235f5faefd85f1a93a7f0d634252347c2775549b9c55442057b42028612c8733fa2c79973dd58923336d3aa7943952acd9783ba7cfecfa1fa09ef330cb94b636a7b411679c354d8b713bcff4e132f71fa0a68777bb118c2ff388648f3867d9b9f7cc577a1e496f275f517ba6698f4d24bb8673cf7cd633df6937cb6e0f7d8dde9cf7466a56e217dfbffcc56749b1fc84a850919fd780949753ce1d390f27205f6f6b02f3d9678b3efe0538713004240c4e9c9824024599016b14140459dfa66108cfc11b81ef8955c667b7a5184b979630952f49756284124809c2f80c43a869019d8a8b3c44205ed7a3fd8432c2e18cb36c4d85f31179d23a8b43fbe9a5db12ceb4bbf9eb6e034252eab6521791e8bcfdf6744fd2f6d4deed9c3d179f78d433926577b791870884d39eeb3d0fe748e469f888ac5ee9dd3d9477e81529bd2be170e164dfe1d6e9dbbdee259c89742f19e95e7a0c71490452bac5ab6fff6e8e43ec4bb8a774ee28ebadb0cab3aacf7a3f7926a3e66ee99e2eadf255ea70697bead6e3b8f8a86b3acffcbe18bc97b4e723b22b751aeeb1251e221038462e95667bb8a77b7de9f8ddbbeed173c1eb4ab8c57dfba9f42d1f91ed8dd127cc0df11d99ddbd1e5fd3cd708cde6ebd21dd7b3cacbde419e9baeb4ad76a3de705a9a50bb94baf0a5f7759e5cef775e919903af3a52e3df2108178414a9bcc60b8c78fc03d06ead2b537d3b6decda577b7bebb406d2fd4d2a523b32b8e3c441edb79e676e9b59b61782fac32c846c2ce389ddbcd68679f574d5d4d87f8be7b79fbccbed3a5f4a3df857dcabc0b4b77bb769e19e9bc193e22259597d2146710d6c62f88b6695aa572db288473ce39a384f2ca9c73cee0438cf81fd6ebb6e734f7d5b7cb0df16d566eda63d46843ef76f62fdbd43a6b4d77335dcd74b3b637c21d9df6eddeada6799e572476b435d335ddd9dea5a62bdbbb145a53576fbee99a57bd6dae55a6bdddc3f6aa7ed3daad67edcb3ccacea3eceaaab64bdbe409a93f75af33dc7467bd0bbfcdbb1377d7ee09cf70d3dd4f5e1197152794d1ddeda9eb706cefd2b6a7aeab9775832f7ff98379c5d16e4bd7a4a64d6c141414d4a56fd52ba280c80df1c14f8bd92b3e323b7bf58a40da5a467b5e285f72254b4cc4de40923753fa9cce33f468aa6955d3e4fc348261e4a15d5e7a46cb292f4fe3ab9452bb949a86659d12688b148bb5da9d734e4a792677edce69836fbe74e79c58729ae23c438fa9d124f9d2349a34e7d5281a918776fa79b5794acf688da21179ccd379e7a5499a469fdd79aa6977457a7a35edc66029e54e338e72a512a5f4dbb6e5249dd148c4d18cdb68e421f2a0dfae5dfa2cdbe2128a63883c441eda37ed46a248c4337db6e636eddbe53a1ded74fb76b38fdecef3cce3a5ed9000a8354c3b7a59f0215ff2b2069f08b20f16e44bd63ef1687a93f7a6ef6c89a3f232f6760fd0f4d2d0c2dca9357f3ea44ebdd489269c79e4bc707ebbd68aeb23dca1af177ed9868fc826928a928510ad1de2197c144945c9c2496bda696bb8a51da873e44bd2b611c72970873c09e64e7401c4915a9468f93886d4d1de05942c88624b66d03246d1f2d28aaf932f49030a357af99b978e1c4b6f6cade9c42c534c3da10bc21129838282828e482e7ea87397e38e42a552dce599dd53dd792496a2a388c5a769da53389ba053a80d857a2ac52355372749a12e94afee28ce6a17750b3d23a96b17954261b881c84383289c4dd0a86b5706f9d288d4eeb42b837c6947dd0cd4a8f34c9fadbbee8d3a77b5a76ef74c53ddaa2eea10094bdb4e6151c117ddf5cc553045bf1a62514193266a8ad4390db11851a52d6ce183588c48ea37c402254ad3b636761fce11a542a1aad4399d52471df52a75ec5138cfd0f5a95af94e9fefd4a5dfe9a6ee275fa5d7b3f257c567e785944e3bdf3cf148e909f10ee52b75d4e5548f9e90da1caadebadd2119a8a17ca96a8d9e875b45be7b1ff2dd036aee66dadc51372389a139d3a1873a22bb9ebb5947d7eef56a19f5964f6c1486f2a57a6ca0de5e0ab24d1ef95dd8f2d441a9335b75e8055161f8d1e69196c33576fd542a95eabb3d29d5e9fbae5259fb9d700feaa92c73ba779b61feddbb7df90bcef6c533a19efaf70c834db7b1cbf6de77e815413df5dd6cb109f53d031188ea9fea1922bd3c5398e79c4e6115ceb1bb9957a4d429cd1bb27a77287550d79e810804b686fa062210d8a8cb2075b4a3be79415016dace287c7aeae6af81902449d9672002c93734eab653e799a99be119adfae9f6989ea45137cf4ec5dcaa7e7a062290d44f18ca17ea3c13753334a367b0cfec1c3b06c73c751eb98108c4cae423b259466270966d3a0b67a98a79cee9199c67ae6a3dcfdcf56cef52b54e373dcfa09e6d1113de40e4a17a0af348156e99eefd73217514ce4452471df5e819491d75d5331081a02ceac256dd7b8648fd7d7573ecd54bde9099a3708f9db939aade52cddca5ba0b67da9eaad5cda8eea94cd77442dd23623b8553475d18796438467b97b9df59f7e53117e63c7375615bda65a77ba87bdf33eaf65975eb7da99f9e51373dab70a68d321d7a464e4f7d95c21b884050aaa354f6d9f4189c731ad5a3ba7d36e123b2554f3d9ff011d9a7a70ebd22a89f708ead3a8f4ce1d6e9debf6f200241ddb3cf39fda5705ee123b257373dd3fefe72d3615ef0119973dafbe70d49bd6785736cd4ed519e91ae53df400492c2f907a851b7dff79417e4439d5497255ff32a7ca9e7af6d9fde69cf81bd810824b6f62179371f919dba777b3390a5aa5b156e15e1aefa10ee2aac3a50a36ea68d7a4a656597baa7436f08eadf5317a88fc83ee10d441ede4d37d3f6ce33bdabdddeae7217b6fc461f9bc2ce7a4220ff9e893438d0d3495f2a4948ebe9b542369ce72d4652eae1ae7dfac4ce4ab7d0935d3f5fba19a8f3f6c79abfa65d57abd4a9c1e279eab375e9d2c58da6d46776e99225c547a411293b72914e79821496c861091e9670b2c4114b28b1e32828284806d30006681e494491515196a2af8855f4a217902e4a823c60e71cad282828280692000420c276af2f87164de9d93247be97b059200e3caa5a3e2488035b892d6f2592e00eb89311050505b90006dfe174c4d9e1af1e56b024a6441443440c5938775e6f06d0127e1e461fbeec23a684914e6c165afef04525165e4a29a5fc2ba76574e28befac1251e8674c89273d9f591a3d22f047c3c79cd1cf4f8f882422df93618aeb843fa8dcc142b9002239af8e39ae978e1e272ea3a5ba82de7a7bddb6afab5dc4a95a9d3bac6d53416fbdbd6e9b0e1ebdfd636d7fe5bc5e395207e6f7c4e9fc12c016518628038833921082f1c0e188ce79f2a43ee9f80e1a6991c385b1c60f9e16a1ee2c2d40f060b518c1a454372d2cf02657b7cc094bf0418b23e8e0c3900a041086194eb209ab942aac140255d460052a282349081eec90011033f3011759b6e5aa4126148171032b485011e50d1d5e3cc1c3cccc20d234ec0335324df3419720e85f5e1069737593811897a4218cda80e2084657681aebc28d1ea6e605114ce435ed947aa144534a69a665d90cb40cdd4c243ab952c3d80fc868aff373524df8b2ce6a9b174472a5e7cf882b5d669170e53271a017a4722d4401c4109a14c10a22501180d80a823415e0f0c3f6fa3e2b4d4b4d29adac6fc5d2327160b65d1ff00b5fbe5e4ff8309158423f21a0c8efac6fc5b232bfb9736ac450d3dfbc6e5ef215775a05411307761f0a143e782b12071e61543f327e90831e7828020750a6e060690114d9952b56f8b0bad284264a604654e9ee8d14acb0d2ab228d1ca02881c94cc32bda78d2b5610c4a11a0ece0c58739e7cc29a3c6a680032856725c218516e4f0358c419952a324d5f08a31da68daf08a922c519874c172240524266800cb5e9d11c10845b01a5ec1c6155d6a182382183b64505b8115ca29a38d1ea228c2104758c2165100009420ba2b4ab208d5ac618222e4434e193f9e68a3072d20c389299aa04211464011410c1e72caa8a78657208144af1ac68ae8e2092dce22b0dc20359959114ff820b54cd3b422848042c4149a1201a31945a25d96f4a9e195241c656cb8f1848808a4ce1dbc8243516c35bc728420e9358c1191d422227b5ea6e006ed26c7843b784112415c01238830c4c8d1f02ca9f35980b67dd6c142478e528deee464d69333e87195af23be3845e2c02ab21eca9d26c28ac4a970eec01c0c21c184348228aa82849b2c441c6df863adb4ec49b60421ca155320021845e020c288c688c022f49fee2cc088cbc4813de7edbd79c32b445e18b1a4f3734a321be2c28c1c0058c20e5a24f1831d20210a9e920320641ac6a640d15ac3d8144c6a4250c51364bce10424622b80dd8eff626de84522389405521082f081cb103d803d02423cd18e86725e30c59419ac20892430b171c2c5c684b8c2879c322a4ec3981047b4e071c8e5840bd711df07627839a9c10caf9eef11e283312763680d63423c69181342884b770d634ece70a1ab715245a6638c239c24f144194960a2c68914748d16b4aa61cc49516cf221d150e220c4140df111d910ee781561253ac9c1095177b453b5857e5ab28e0b0d65c566abd4aee32d17c49392c92776e91691526f3d7146414b1fb49a35e1342dd332cd490f35d3b22ccbe8d7c6b6d18cd20008218b1f20b1242807556094a629111086607d416c11420b420b51c6459320ac0822882a3d0411a549104f886a128660811083006228eb1ba42072f08112a9f1c344ca8ab0d2e44643430722927c88b161d42f0d634440d0924c31c89432c618639473ced39e32e6200548f0c089133c00e208458065aecea49c212477f84a0dafa4d18610d10f9410f94088a8074a601a5e49e38bde1a5e5183ca248a10c21d5964d0b759da65894062c3c72ce08f282f65c7a16c4e2a1bb23e2dd6509b6a1a10482d5b1e96bd05a94367677f0188a3ce5a422d4519cd5ed9339ca3160d9ffd46eab4bad55947c7a8697348aaa31670077caab35b4dd3340877444dd36216b803d620cca223a9e49327cad21373437cf1a873043080358e4612ce78c21023582aa320a30077ccfff89946c01df3720db8635e6687193d14f8030adc41d348f1840277ccf34819f4a526947904fc01a5f0cd6b71a77ff802e2449dfe610cd3932f52d1b073aa7fe0017c4520fd830f200fd845dd0e623e20cd4729491db3fc80d4314bcf5b2871f8608cc84ac7a86ce9bcb58c11558941dd4662962e12b108e273d351a89b689fd825fac42e9d2502811da5f0c14729f0c74f14ea2805ee80fff1d30410411db3b44fece2b910b168da44cc027ffcd04f2c7a9e4766017fc42c70073c843be0a316f0c7c43eb5e325cdc1ca96ec013fdfc557163e89039f21969eab9638f259c72771e4ebad12477ebbac8c462dd2c286b4c4558d4693f77a73bdbd76b376d4b99bb9c37cbb79f5bcfd535ddebcc21989143970c21350a8db30d3a8e71f13cea8cb3ce3f8cdcdcdea59a5ba0d35ad7a968781b92a055138021651f03ccf740f67efddb3cc73e4c8a18281818141010b62405882c96432e16cfacb33cc6f6e6e6e542a95b5f604436d749182fdcb338ee770b95cdff799e00848082df96e5aad160a853241134b243d41b152a9146b666666cbc1103a68c2cbe9747a61b1582693698b728321344ca9aeeb5e5e5eacb55a6c064348c3a652a9effbb231d278d283ef34cf384ea7130a85a26b14e10b2d50a77996b1b1b1e9bacef3bc2c4946480103030383b3779a67989a9a9a1c3972d0e03c99b8c2860c4cbfcf34b7f97f737363ad953458020d2eecefb3cd6b70e0c0f17d9f13c8d0b20406060606e7eff7b9e6bf38c71d0891031151891346493131314045569630b45aad6e98c28c26515c4db63832a2e572b9502814122ba268410b5033ad56cbf302d14208e1261f253c7dbc904608a1cc3228e9b31b4f83d40c07dbb1a13c49599a050a94a66d4d9d29d5c935be5c6d959a942a922f08c3e899651a666998aa10273571769c0e57388f944b4826a41459744aa5505584765c1d573a010a5148fa6a4d753002a138443378e64e8438f61986d1d3de7e02346885470113b0a4c256900144c092176c852a200b4b7cc056803f505d843fe2ede36d592cbf6829f2ca2ee00e7904774c287c3006032c2d9fab1a2498efa6cce75d3e7ae634eaa7fbbd5e686d7623eb745656a17b9648b6e27c24c339cadc1c5bc61bb2bacc2911ec083b9e42913a59f4bc20d9e511cce1dce90e27ceadb538f56a7fb23fd5f893fda9a66e8fea49da4297b531ba52948808e4f4686d4ad5a2502c8e3f656ba3b5d69e704febaadb18718e0142526d4c7cb534cae9f6d827e9585b3f9d629eaa4f51243ac79cec5d94880824f598d64fcfb5a174cc8fc88ea7b77e3ab5704fbcfda97a272f1fa1a7d3e9146f5337d75f9ba48aafaddbd6e3491ecde09bbfec23ce44ece3ede3e9f5f44904125f53b05331e684f286a41e714f3ccd3fcf48674f97472f26987ad5a99e6aeaa6d3e765514d9d54f53787b8ce78599ae6b6a2c5963ee998bb2eeb3c73b5b29812c9574cd2dc914536f8bf00b8f77a8e59736b034093c30600f7d0bce631072582f5981863c4f908a58d9f63cc1ae31e7bd6e36722eb3338c72399959deb1fdc89adc753a8937a7c853aa7c77750a7ba50639f03e7d8348f34b7b855f398e7b82c9a3b1107e757bf707e0100e7dfe0cc3a9e33f8371d4e9cfb97c71c4a1570aedd057d86d29ef94d0e9c653df398b3cecd60fc3a83662e6f7096481d731c3869e6f3948878cc9af99df967708eb90dceb559dfbc20ac584373a516f99a591eb1cce8ec724b67f28cce2e91a4ceead929113bf18812c9b49e9d4a9dd4b32c3ba5501a7a31e791ad2b8fe417528b1c43bee623d2dc59e1f3f1c8f4bbf00ad8b4ba955e10959d5d46d2b7365ef8c113ce26e87aa401b06bec626ecc59ac4f2f08eb747bc2ad16609f3e04f60973467cef7c43943e1de8ebfad6cc53f5b670966374cced05ea7824eb194c89883c62ce33636e76d695b9955dcc852d8fe64e66cdacae7ab4b45b9daa8d44a74a25dec6b6f6aa9e792b55fcec100877d00759d91b3b56993b9128d7cf3e85e1c9b24af1b33f5d0877d8d70be18ed82ad5e3eda7cac6a3502914ca26e9fac526df633cf4ea773a6118799c1eaffde9e61a7f3a8facb0e33dc51b9bc857f4d96c90537df46c04c1517e77f76808ec2a02f99a15cb205ff3f18b27c13731f7097d54b6b4d63c52061da297ccf9c2c619294ea40db108810b2737446c0d634fbcd1a624a4daf00a132b0660624914373abef3f1c4d115264d3061658a863126a23464a28809281ddf45c0a807155f13535e00c7155dd0000a4c08420a150748c24444611496b08437c4382a020a0f7c30d9e18920279cd0b661cc89234c49ea0c8da4a8a4bc6cf21055e58b47bee819d0f12bd973595785e475f8f6cc0b120f3d083ce830080790594d4bf071a70cf8f48ad873971e91798e4efc022e5deec9170f9bbb951b110eda7cde86e1177bb8bb30bb74e9d245d33a5e095ff171f6761b5da0e1486d0979c41f61d12c6b9944facc2e6e1091411d310ddb8fd48e7f41eaccd9f14e4f88ec19b75b3865dcfe82d491b2b73bdfdc0bdc853aad9403a44e2b857d62c7c7d80c903a114b91a76f41eacc67c845d3f330a08517ea94b87e4254b2bf602a71e8e557b64a9dfc756475a988b7ad84b9d9a552b6c4cdb8c52cab503ac66dc354bee8b30d6675855ebe82b9f1e552d1beba4a48a0a2536a95682516419c885b1090b0d5e7ebeac24a250e8d4b3a2ed9a1d26d8b35e301eea0f5fb58acd796ba50d35ebb1287b232e9b4fd656d675318ca57ad1aae9803dfdc519d7e031ac800062e6081d5512f9ddb0e732b0003052620810840c0c8035c7040910610813f60eaab3b444810062c00d63caacb238f58cff563e5a3a251aab31cea3b6db4d6d3ca533f9cbf13ce2c9c2fc597733a524a3b6a698972f45502a91a94f13cb2de6c49e4a1d10c43d5f3f6ec76bbdbe9762a5ff43571b4c39d0a71e2379c355c61d3d3d7936ce9509353b9b8d12bccd8a269dd90806c108537c680e20753e8208d1d2778f89c98c2c37ca3ebe12c3366be6ce582a3d595254df43067cc89233a5f7ba2a6c60539e8a10a93921c0dcad0a08c2954686104152a30aad3945e610324f49093d1af94981a5eb183292e5041852462b09082881874d1051858186009ea02269ccce982237a6e3d79b8c20c1774aae1155a1461802130892209338640c5951eb127a810c2401651b6a861c61427a45180309a38e11a5e11838d1b684c74e9c2073d8882108820c0143000c205413a5816abd6a8c518638c3c329339f0d5ac6fe264393cbae793ffa4f8e6a6d1eca373d2dbc8acabd965ddba279b3851abf5fb70ce4edfd9654f56296c2993baa3296644185471418f295f1860c9d730f644134352927e90f2c692293a309902449f1ac6bc9081504c4a16cd358c492943271eb68d37a33ddbce2e5ed9551c358c51c145f76818a3024a5bad8b50db3e59a4a561ebc018173568d85646284d3aadf8d811c386373092f1a40659a2124d3c69ae61ac89250d634c70e91c1b320104d944152694d0513abeca268c3adef8e4833129429d29962030d130d6049786b126b674aeb126ca68c28b8ea7529e4861429352838e12064fa23ca9128b72464e4d6a0a7fc486d10acc71ca84391307c2323c82a578a5e5f3e5969cb9336b5671cda939b34a673944cb4fa249b4e15abf0ce74f6e993268ee6c2f6241f9885a2ea9f5fb58f56856d182d4724bcb20b3cab664ee0c29e93ef4996e9a72424d294215414111cd9d21ef4a3a13de964c1c79ef1ede88b6254b5a7ed332777488b0eef21b125db2851225cd1d24a653281b175a44a4216d814264a5e535a2b9b36d1a944dcbb769d1825a5e23dab46c5522849d55a77466946dc9b6a09232a32a19972c56828e8c268ed4966841214d1cf9ed48cb942a9d54a7cc1d09850e846084237ed002265fabcc9d398414dc90e2040baec0e4ab95b91375e801085db874f9014cbe1acd9d0160614411bae88005265fb3cc9d58051b422c818293a0cca8230ce665357754730775791ac3e506184cb3dcf082e9d157986ac137a830454261ba65e2c84bf9209b96a06d4e1ad4f29b308d68ee9c3458678a3015c489de920ec68238b1c34a26c48935a924573d78e9f8562e38339addd5333a89d045a98b8e1d73a4187588850c8845125ff045fcc5137d3102f1c5f3480238f9606c892951bc8872a5e3bb2841c8808571890fc65860859e5c52a75564fe513bb58850dab3edc9047fc48e97454e5d9a7e1289414de967e9b3744dcb7e446b8d06ad44af65f7895d1c007564f4f650cf015062ab75d99587b2cb2e7df486c8d3f9ecd2cf77b7a92be5bc9c4bea70f4ad22386b5f3d88eaf2c236c11dd9e5cdb165e9f3666984d2cfadd3bc20aacf7bbabcdf5d52e7b47946aaccbc67b7a57a4aaefe725b45ea57af5fe1960a0b016ad45b4552f79eba770fe643e644c17cb767befe74b3f6f9d99bb56f9738578d7ebb399e108aa727449e5e7a45e4e9a91744629ad3134b9c3b53ede2e5367a4260fe72e8b5f07219205f44e08f78b3db03f37a1e98cb5369e7923adce3768bbad9e36df4bebba44e5dd2dc5b45b2734fbddedcc11cc21d2f2f17e6e6ecab47cf08f79cbd4e692ec60228ad3d0bf23dbba6bba44ec5d97b8539bd11ee30385723daeda9bb913a5008509feed25e1fff62ff725bdf51cf525fdd5c4fafbaad22da53d79ec2adefad22a8dba36e5f5012614b201c40cce9df1502d4271c734db7c763f558dca5eb43be62c55ba4514e539661182f8310813bfa7b91990eb292f6d52ccb991f414ef7d03b6f7386a92901a9e7aa7aee3ae6156be248d34b3f5d890395fc504fbd5b7574a92efc2ef44e386738fbe4ab848f64ad3d1e7556bab439383f829cce700fc5338904fa248d328fcc5256d4b4ed939ab6edbaf8bdbc20d2069ffc7864e709a90d9374a97458b96f6379aa5797ba7843c419499720ceb4761fcbc3d96571bee970d6d1259c4bdf9e733aeff48c0864bbb795de755dd775dd33753de77487f30c3d708e9e57a4d4b6d4baab757838737ac6cc59495267e6a592ddae76d5adb9fcea05e631acd2652e2bcef5db7066599cdfe1fc2ae1cca37324e2b66ddb2a6adbb8ee9ccded86c23ddcab0ac5bdd2a870965d4f83b36cee34a9ad0cce3c905838bf801083f3bb80c19995c50bce5fc770a9b46d9d556db887d3a81b9d356e3b3d63a36a681c4adbaed1e748937270b85c9416efd1c379861e1ece39cd457c44b68d3b2001814b1759c4da3b401e407ba56b5bae58553145c3066f38d3b6b81573edde21ebf4a7ecd0e6a6ff83f48cad94ebb5679ad4dec91b52bac53df62f3795be1f671e3638bf6870be0cce2c16b6d7baed301597686bde86ebbb0e0dfb8abdcf949d280c8ed60be261f86545fd726d0cb7b98ebade5317b6ead6fcbb99477e3db35a4a0963983b91e834cf2f9b671eedca326d70e6f1a2c1f9f57f918888c3ddc7bd94d3dd877bb8db973e342290ed3210fe603d0fa04b879900d00c8b7becbf2e7db72bdb3de21c3f9c6977b8f5c52c3c78bc5e59bafb36438fb6cf33f4e8789ae79cf656afb950be56775d0877945ebd21f63dd1f5cd33d2b58538a54bf8ca393c705ef7322c54735dea4e83734e6f8fa7684420b6bbcbf3ae7941bceebbd45e7ea6ae4729b3d02568d4a512ccc245974af08b2e954a67d11cf843e6a50f00fe60bd7448d12040040243e4215fbaa44957d239bb9b698f2edddacede8fb6bd4033f4e80f5334228fedab9b69cf3cde169ec1304420314be4212fafbaa86b9f5dfa7a4b2f9db685349fbd51d7ee5edb7e9dcdbeced18c968731d5c5af3ee505c96e4b77f3687770e2d47777bbcd4768aa848fc8a6f4b4edec322df225e317a5e755c774d01b12ef79de96334bf2b5759b770e368c27847b775a5f7abc23b8e91eee1dce333756a683de108b670ee50efe76281370cf1ddee777e95045548a5daafbea9d7c9550f8bb174a1c0e6757978e715e75e9d10be2d97aeed6cfdc196e9a4628f2f52412c5be1cb3c42fa44ecdc285d4c9aad481d732960c867087bc94fbd2edee5759975e294b0ebb1dceacaf4b5ea974bb491c7c39decbc723a9b35dfede2a71ba2e487ce99a9ebbc79bbc20260cbf52091fa17dbae7154941972e5db674876760f5e956d54dfb8db6767ac9973cccf50121aa425bbad568de96b0adb564c216e7f879454add9dbc21dfb37fa553d894a864ade53ccff38e48eef69c9ea461d7d93ffca1c38b15b608c0153856bca400c0132ab420870a6e84c061831eb00d94dc369e86cd126acaa011c3e5456b8b992b64ac604911f3044c0b5e54b0124255831e523550826ae34be3b40453199e189d17768b5ac2c2d9a052b1c1409b922d41bfb3bed511f3dfeb3742c8efac6ff5654d5ab63cfc11ff49293529a5943293d20a21f91c8921ce75a6a1060dd4b092d4f674430ef2f148226ec1806f8021919fd87b4102c1a017e4852432462066104a9961792bd5a140208c513e4708258d120ab16a50bbb4ca6cd23ce9738cf132ce27be799969da8574c618b5ecd2aadd40ea442a73d750be229d32c2cc243116da36b36c06647496dde4f8e88194d32327ab5b9665cf79dd64b407f691235f3ebea05996ad58db9cd90cb6e8ecb4665986b4cdf92ccb6610eb2c7bcdb2ec66879b9c19ac91e550fc9cb953735839dcedd16a189b41133340a2738e77c40cab0218c1051256104216a494524a18610cf0524a29a594524bcb28a3a0b42bf722d7a11724ae56acaec626d7b6c1ae0759612cae0b80c3b39e5d0d6fe08fab43cee0833e907c20f940f2f1c281ed2baeb9dccd5fd39ca3cd79ab948be6d2c6d5368732363438646e7edbe09a0b3be5dd3cc3ab731c47c53676dda55d7371fcc6543f4b731b16686e8e4d536b7db551db3840be6c8e9a8bb6b9cd79a40dcd278d90f9d76bee082052f7ccbf5e9faf775e859b63ab7088f30cafe8a17316babe211019200f3980d7d3dad104204755b28131c0eb79e08f155e553800687eecb8fc8ef3481d1cc771399d7a39cdcb695e2fcd6d6e8e6d73eee69ce6522bebbdfe55eeecbcc6e6aa1d2cf1ccb30f10c897bc0c52a7e6f226108a4ba48ebd7c6c2271ea5d9deb50eab8ee5d1df2556fefeb8635716a3094af9ce65ee8fa17d576d3a56f5e111480e10418445df10c399dea52d68dddf22100019c47b22e6c9b0bdb0ee0c68e39008ff3388fb43097003d0ac0711cc7711cc7ad50b741dde6f5da70dcaaeb7a32ad5c5227655f7f2375685eff923a35afd721755adfeb7bc01f9e8f96f96fbf5624da695d3e12c52752be755f9738f59506220951a1a9b9bc08a4ce67593117e6f2bc5c167cd0dc5a73bb2fc7747b38e005b8a35a9b9ba1961e9729ea1e5fdd0c34a5eb513dbe79415e7db4ceab570449164ea254e9aa731bbb5fda3a780206e8711d205ff505b82f10003340be2aec015cd8393c04f063c7cda1d7878ecb42e9f2ac706308c0bc19226dc7b959768648ae4b03ed0c91666ee6be5d7a410080a5480a98f0c11624005cea83c7017207aa7061bf72e477eee7cecee50dfc712ff1085edd83e337cfc771fcec6a797b736d6e63e8fa9b9b5f7df378739e797371dce6e68a6778753d8e9b8b63e772f85e17dc1167139f1d01dc22c47be925afbbb5ae3a535f4d3aacd7d7b97380d77facb9e3e3f5973a30af7fcd9d9dd7e7489d97d7fb903aabd7b3207554afe7913adceb192075645edf82d469bd3e06f8e3f48af30c10a9b50fc5ad5e735b73391b9c81bad66a734790d334879e909adb9c47d6dce6dcb579bd39a72bcda317c4e6e69cd5696e7ea1b9d7d56b6ee6f00c399dfaea3cb2e6ae6e6794efaedbbcd65a6badb5d65b731ec9d5d75c86b95361f222983b3148422d6d736b6e732dcda1d4b1e130942f1b9ceb5d36d7f57a5dafb99906cf00b534876590af7a178e41beea5b7702f2553f7333205f5506bf205ff51ee05689531f737d5c96c4a987b997affa9dfb9238f52f3747beea57d7877cd5ab2e0bf2559fba3cf2558fba0c90affaefb6205ff5a70b02b8a33e7a414cdee5995a068202b7f47ce966eeb48809c070028c255df10c704b9d069036552890945202d580a72590959623805aba47e2e88278da1e3f19bb469ac5ace31effb1628d5dfc262b72d8f4095191105e5299b15952278b904806a334c56b31c3ad18ab8c5a262bf63ed842f068de0a6be317a51015280d2044055e87f790f1f5cd0e582a0f9b5e2a8166cc803d812d5d0ac4d32b143195facf72d7d667eef4a5db4f8f08775b6ba51e919ad57fb2d2679957646a9e0bf4935aaddf2aa6a16effe446bfd55a3f596ff4844418a5a99e47b66aab629fd8f434c4a6a797584abcdc72570512ad33fe4cf48cd144ec075090d218020b154e6410831d6c194052b821052a70a08285066fc0e8155428a157780003211934e1899bf81aff0941831d7e3002184b14f1840b0c4aa05a40c7b772d51c48b54c43238d1d64c9a18b1a685102a6519876d3f915048f82c801183cf0010d1e24019b4638f4cce9daf04a10977a25884b472d4e1f34396388294861872a7c984201579460426332d082891bc820069b96d129e31448ed46aa616c8aa446e2cb5d7c2703a2ce5506451d5f536069cbced5889318a7206a0314e15372b343a6a54469469f20e5891445681893624ac3670d6331d002a5d0b243970d6459962db90dafe4c085e8da0667c6c4c86b927323c513540f3b60d9220628210d4ab144490c113429a08852c568520a5280898d2c6928a18a186c18019680cefe0575f695d42989118320c44082c90e7e5829b92234852e00156c900185882e887e808028d638ed808a1f241045082a1882142a558ec0821332263b685284d31726a1984a08463185f7d5326814518402408335b620421b2d78e309206d60c129e16249abe1951c74c0c594708124aef0b5d7f15dac82a54d1d6514429dea53c753ec842d699a56254a6b1a37e9a478ce2a51b4a6d18974a3d1229cb48d07921948e8620d272c7003a6fd68ad8a135a4bb5a669f4373838410527b7226c74628a0d0598a268da12572d9e46a538396d5639e79c33cf3c915899a5cd38b53963bca6cd382fe5a7a63dc6f8795bf2dbcd5a867b8248f91ab6968f72ce39e79c7366327b818537909b4573a7c3d3c896a20f1f39392fc9caa851cbf3f88060db84027fc0965b5067b983840a85d2f292e828462f88f6b8bd86adb7f7c46f33ce4cdc936db47e06f5767a797c10467790c42018cfc491974179c347b6d6704f900cfbc02e9dbd86adb3d320260d9520c406175d86888293293079d6dc91ffdc91cf993b36b13564808320e8208525c036b9c1c0c29bfc92d4f63040a2651ac6a0306a2bbb0efee0a8dc81307828135061b96ba821cd9d6f08e2d8979e4f1ad2f4a1ed399ceb9353679395b65353a3edb3d5bae9b520508f3a0c15c3903a57f4d17f13c75e7bf6896373268e3d77c40761f540302058ce69a489639f792f08692fd4cb373ea99327d2b744eac4db7f425287b6fd9ab4dd3271ac3d3ce2b6cc9d2f735bbe2f1a6d2ab8d63006c5109d35a457c3d80b9068d830b6e54993196e886f064da48e8b91b582e5cb5fd037e53bb29f96b6ffaa7c41f60b326a6be583d29686d9d1fb82e4cb5e6ef1c92ccde19c3547a72cbdaf7c5965d4f6d95ab9c1974d56b2ca288bc9cad1cb0bb4bc4c81f46245962d2f53bcee650af732a5f432a5ede3155f7e096afbdc7169fb972513b63a42249a3bab332494b9b34a03be04cd1dfb97a2b983bafd0a69eea4b02a68e2d8db0a278e6925f441a3ad610c8a215550f554416d5553daaaaab45559e1b67c415916b58502086dab442031803fb8dbcc6d697beeca23e00efbd29550220ffb99da34d0ce5f907d96451a927cc92d3eeef652c9f72efd8342e600831a74d690dabe2469f20bb2d984c271dc87c0e60ed4f5c29b65f83afb76b95b1fe1fc76811a6af3d9ece40bc686de6318b193724e4a67439c9134843b24a626087740232c24f2c118152dbd695b94e988eac8757c8db2a331fbf0f10c88e0005f0c66a169d774dc1cf9d2fed25ee74eaddaf4861c3ed6c738379ac5ce5be8c2182e7091b3f76c27f2f58f3cc75dca6dde9cfd48a4b845649efbc41ceee12e217748845e663b50b43c777baab743b8d25b3ea786f8f6d433a27dc3354c23d921ae2176c4d9f539f50f843b327708774c23d3883cf74cd6106b881dbd8a5b44b6cf6fb8879ef6c81f89ed137d4a914ac9e48e598384b223cef41a111a141414f4caf4daa7670409cd7ade85491f3d223714a11d04a4e90d01eaed73ab787a2e64b8026d517689336adaed097a0d80cd45ee966e4f239db3542a7d08ecd2819ae3b8cbbb1d7af13c12a823d66e96633495d308a21923a51995489dc54aa16855d328d5e889883ce8b36b59a444198542a946b36794c6ac28678bf007b4b28d48e39c34ebce704652e10e69bf255b1d867579ea05b1536658322c9991f6fccff4fcadd3cf2d3349ea442e52c79b674c357a223535a3e9251b5f86473daefb24e9cd75fa18744fa99cd1dab3add5fa95d76e94b4d5fa6f6ba7e5ac88f6d6a147e46fdd2352b2da5b3877d273a185f3a307e7c535c4de708e339f9e11ed2eec137bcb7193b5030dbd2136bd611f1bcb799d0c44356e994e3b7372861337fad4b15e3b324c1c5a5bb3dfa31704750fc01f3d73fa0f409d095f33a79721028190c7cce96d7a66e6f96b5b378833731bb33b73792b6f94380451a561baec06c97e73a390c4c91e856290143e3a7334cab0c89d1c47923a5ba48ef7f99c99d1a75f347d2af6f4e4e639807a42dedb4cf6d3cda7ffc4a6417bcc63903a15ebbce9579e10d95bcbe7d419969e116854436c8973bd7c4f3d34ea9537a427e61af649d2359758b29109654be60e7ef77934776e322b59759b537a7c352e13470df99ad2dcb3bc5916f9a2bfb999d1c4a1b7b0b55f28fafef747a25faebaa55d8edf808fe3967a44620d5afb7df48cdc6bd323f2df436f22512f08cd3722aabf0421a9b56b54dc68edaa5b57975d9f24342f68d2f22fb7365d766988ed9324a8b5bb8070a35d14707dbb27241ab5c4b9bbc96e6fae1095bc7da667bbeb36f38a44a226adddf5e8b9a0dd758fc876d75b77dd0dca570b67576f38cbcbe6993cf2570afebd5270e02587e14f33e40e3efd3c923a5f481dd5e9a716a9f372fa3986d48939fd44923a32469d33a3eefa0e79bb2ecfda7076e196eb17776fb13c17aeb56bf03975f63f33e2428b1949991b4b9e14416105cbd1185b3435accc85598c57249b42be569915f992b9b1f115a222b36756585e11dc2fb7325d945cbe9c5569d19c47ca5cd9305e90630879e497cf3c7a4692f4cb332b52479e5ee22cfb45fb0bce36b886d8355855e4a4facca567447b0cf6896d5fba6c935deb469a1b9bd6f8b41c72ea0cfb9c5abe15db1bf2b54f4c6af9174fc8db2722b572ecc9eebab511f248cd8676ad0b69eabb6547a380ceb08f0254d9cd49701812bbb40bcfbce40991d77ebd2253ded8d9ed96f1862840b6e08c929a7e64afe08e99bf7841b46755a4cecce9b329a48e763f981bf3d57d79eaaa8ebaf38ba945bee84d9927a1f7e179245f5140caf3c833028dfa74ea198157fa247110a2499f08bcd2a73ed510fb749ed9cd4bc3d619226557e77994bbce9951d3d34f40ee1c467f9e165852279ec6a03083c56a56d3cbb0e15cab86f3f76538b390b6a01a7920ec9d90d29b810ee98d13d207a712a8d4ea162a543dcc39a6d490600000027315003030100e09c5c2b1304c74751f14800f9eb84a56a449a42cc9410819630c21062122000323220280261a5937ec65e9b56f56af0267dd7c3f5baf7cb3f61a28cb2d7bd9f5e693adb7c060bf7d0fd8f4e83bbb87c0b26ede9fa5279f59bd07cebed15e56bdfa64e92550f65bf6b2e9c1377bef81b2dd763f5b6f7cb37a1e28eb66fb62e9b14fb17b0b94f5d6fd2c7af1c9de4be06cb7ec67d7abcfab5ef51fc7f5acbf826bb3ddd89f5d6f9fd97a0c3cfb867d597aa6af57bd5ef6e1ed6640bb01f4eac2ddaca27dd8bb05d7680083ac9496fc601fae6fc3b55400ac7ce25d5092265cce0c45d53a5df7c9096396d8f84e04a151c26dea07aeffe3e56a08343281a1a4b2dabb590fd4c32f8e4c8da75334fc6c3edaa48050e416cd7ab07e234db9a123506a0ce9530e604c2beb33c87bebb0727915f8894ab9ca6909085613f88e3395e658ec4b502582b2d1eecf828fdca479911a7beaf7e49e7aeb0718c151edb41f9310dfff9f8f00eafa0af6929fd217ea0af072f338a863053635434bee9ed0c67a6ba12e4a9e40c5fe436a3d92cb590f6461423aa7373513ca0428ac761258f01e1af4eab7c22f8e06c9854de00c27ff1617a4906e14e09e59fb60539935ee00386e6103ef9ec0cd32c1a8491290dc926cdb980ebdde3e0e7cc3c8e02a1ea0a12d04464eb4160d6aaa1ac6b97d96f57075c3782c9181edce69c2fdddea206522fc8d62e5a3a1cf25eb97f5c88eab2ada9d5cbf8aec0807716765181549f825d9e39152e72b229dc2af5648f60f12992452e72d7e3333e4484b092916e8c47caeaef6f744c752986d199396a3aa0d653f5fa1819726e56a49c8bf0e2e58e9a2b255d278aabb204140e43880a0d8c1e5bb34854eb8b516204512925b8c714e23d7d280671b29f8fa3c9a3e02c86efa45c768fcf2cfe26af19dedc8cf34542684b41b808d65ccf8a56d91856377270e91238a558e12dea98190f2d5271e98fbe968b1c8851dbaf1a3b27f0bc2f2f54b44185262803ff6457e11fbde12b3bb398badcff20378915861d4276dbae29a575e814ebd40b4426e61a8fa3f2560504992dc3ab5153211fc7e6b45e60356d9f3f04cb9cb8f7b7cc8a34afc588c48e241d73c77935936fbc9f684936d297adb1d8e8dde1e6e9f609debe14a2580134f44a7e5af7edad4708a6efd727a6308b494d7c3729caa1346b7422fe3c5a5c38672d20f04e81c0f82498739466173b2646b6def6b72a0dcc71a9dbe96851a20fe4dbff543124c8c4588cc302e8c963a5a32a899ae0f2ba955da464febf991445d2fc24c7434eea7a49356e758948f5e11703167b3d67599e4948dd2db80b89a14eb44a2e6840b51db1669c796da2f545c7536686599945de02def61a3552e1874c62dc230f0fd6009124e6fa3c524f3c4e62baf6093210d31860ca1b263258d704c21d8d28e28d5f4eb9060e63dcb8afcdff2f772c620072d9e143ca98e46e3b09ad3ead748a6e2b3a1625516e11fb5b8993b24596a74ab96d80100377b3cd180610a2ac59bb344219d7ba7d7befb05c3532a53dc5ed64867ffbc817f4aba211ee7dbc28629211d6bdd9ae287d0f74d0c0629252bf24414bedd08419da9fedd4f1e9a800050fa7f79d424d658672199edd46fbf2c5827c28bbb74ff9c7987672352f707122afe363e46457f0d53c36859ba07fa87a4686e07a4edd255ab4568b877a2e09af35c19a74bb19ff7d621cd782e8bfcdf62c5a451f0969bdf0eb7101aab346746b38292973fc2145bf0bc761f0865d857bc6ca6a8116f2fa291f0c8cb4eb7567e044bc79edc8348fd89fde90969144a882c1afd3c499ac83de1941582becc31b1ef17819d82763712f1b8092c340fd80d27b423b8bed3f7f8383386327650deabbf7d402550a8b099d063ca0ab064fd7cafc57f50b1fac9c4e022f35d439b33afc0048db4db0516b87a23a93b23ae602e56b6f1d2690871cb764d94ceb5ed773f5911b2b5fced07d1dfddbe0937a8d3e0e9c1de61b52a7f34f03ac00ab8a730c1ff9aef3ed411bc11c1c8c9d0c08e8111321579cfc8eade295c982492b5bda8aa78d489fa0d064638a3bf8d7148316bdecdae4710ccbc431aa9cfc0f21d3493694e0f1d9ba6161d55eaccca3b8d913b95a224ffb228198ab45ae424cac9b3bce9bfb2c47dfefbe1c73f7d219382d712548e5d05988fe6d510121bda09ae86d438313bd2c2a87a7c1f22df9e1079f08f94f2371335b80cb6eee86310d5e512f60b9eda3fa9cbc056556e091f95bd18fa6b6cfcca83a24d791c907af2ac042f229701b1bc2dfe1a8e880c73e662c6dab20293b2f660bb6337152959b418367530a1b19b3f3cbe6ec53ffbb9066a9f0e096e9870ce1df959100db81b06772297d2b6cff20e419ece2da57344d42642aeceab02f542afeb53686f781b45cfc53971165b65a04d1fb2638a149a48839feaebc540aeaab85597751e603de4db862fc5439a45cce211dea85bb26ab31349003758dbe18738eb5e609b6981beb836dccc6d8a3ccf503f4f8b02bb7b2ab1512a4c6dcd3fa09c252b4e4d84768e176b0dddb0882c6a6933735d32e0c33f73d1dc1d5fb119ef9a59d9d4ee0fa2fbff2a815b0dcd7a5f665ab0b55474ed840a3ef4eef7f33b5b3373df48c7478ee20310ae610c4471c3a5c8964a38561efe849677e4c891275f77932d8a39b72be13e03c9e44072e50bfee0f0a3ed0f5d725b2a23c77fe23f1c523608eb76998e4bf1f981e3259e424c4f9b53df3c567ee95f625dca3553672f1595d037d97d48a1dc0033072575081c80097da7258dc1172d7b894a8a268e103dc85d507e11ad13a4e0c33e3ac5ff282dd1dc23a5987857fbcaf1515a844637a6fad13fc71bc44675ab953e4864bf0200dcc6d2f7fefe94b9edf203882d2198946698b0e45c5ef51b3d4212b1192cdc4c9c5531d635c634d6d44b6d0efd359ee5d248f02bc1622be08f4130b4982168f053647681936912f49a421e88ba9422caf56729de9929e9300ed06a4674b70da6a1b853f754b0d5da2d016f318dd11eea97aaf1ea2539c6199ccc51f48f7c5fb105e96ffa53c5cc52fd2f763d046d6d7918071938ee8d6cc1efa1b54cef8fd05d06b53d2e763617fe01178447bfb9c2aa6665209e06fc1c291b066e2abc446d3f812e290463523bf72c4922d377012d6c6076044fceae6d29c55b3e5d8af4b2e61bc1e34d6e926f3b3d1bfb174aa8407b2a7228510ea06065c2d236f7f8b8647620f2a89ac2959c535c13e85d0c455c794cc118d13415a220d355d44a8573ce2cf9b8c78172113a6ca2606c09877c6e72e0025cc1a065bd4335e4155d246ec59bd4034a21cda704b509683eefc7b99bd4b05646f8a322323ca2e85455cb4f74a61a693d0e402dd414b4ad03a2679803106794bbf4d6beedfd915951ee5eb0678a5f239ea45cff68b82d8e0d7050aa0dd84d2e061ceabe06f806de9d121e802f6f204284090fa26115f569fce67730b81e17653961619283bbd4fba395ead92914fa28e09c6191d5c381ccd593f93a2fef279689f3842d330f463eb1c58e1296188d58191e412a7f0cda7920dc0df0b9cdd38d78ea015dd308ea30242e39401c620606bbccaa0d68ac0bc625b89760b8d8c24951b979b3ae87e6e23c135780884b8f8fc6cc1429215ad32b1e26001ea69ff64f84ffa808f3362a3139063d20716571a0a3c53a83721027ed5b060df87eb1ce6d7859879020c634e09984ab650764943cd3e18b90063cc818a28ad9ac3ed43f41296d2b2620a9918b5a9d72567cc8fd958e98f80911c75a9ab54317ef2fd5d85dcdd4a45d365ee6cfe555f1dc9f86ee3e6c3c98337a98ac0f12615a824e685f6b63bcdab32a720718828b6cb763426222a6556581aa1bc8e638bb742791dba1c169bfd5db2d006c8f55376ed59eda4b2d551fdc75e0c3c75527191f8fb7cf099cf481861ebd13d0a55866752b765d997d7255112e593ab79142fc2fa8f63f81f872e1c7bfa0e86c9a1baac254a50eecb99c52b57e51045ad3a70f8ecf01902aa3908f24a6b7992bd589d6f72b810573f045aec43090af048a32817e578905ffb010bfb9d63a7bf2de5dc8a83442ad312f53f3880c1c4dda21d12d7d226c512c8a9b92070434dbe72255ebe0005cad2a97702ca957e5251b1c58ce3148b78fbcf0d707bfb10facd131d83e24be0e2118a79b6683436d5a1f623f8bf166093ede351ce3bc2145e0c3659836c63306686bc0b6bc7415867a09e4ec6dba6e1153194aa25c32b861c7519c196b4b06c4099c1099650ad6c8f7664f7fff961932c8be35424888f58c2f0e0e2802144202e1df067967a3d15c82c20c3f4821fcac023f7238a76a0b12a56f850302ea6862dffafb5c5b169750fb97d652a8212383dabc8ea87d2fac90de2a3654f4673b1331256375adca25fd1d8f5d0b572e9099e84e8fb62acbf1dd0788c71fb2bf884187216db9ddf5fb8c100c773d252bbc184708de2d2469e8ea7c2c309cef59e01f116e085906f2ea1a3a70a6e35a02a07fd059c8c80f572bf2f5c275b0293f4f67b13d11c659aa4001bfc549c4bc89cd97116f1bb8f04333948376f4c826b276e7cfc353ba1e51b334ef9b187c26376539aeb709c9ca1bac9cfac2dd66d421a6ecf8795e169c8181c90e46b15123eb68be611ccab6aad44e4ec6d45c813b0ca07d72e192463577002dab9c453d6ce72786797ee31be81ca333fe7c888b98a7de2d2f553751a3151aaf5f90fe2d8c9ee8dc2d526e62da8a6091817dd55d9764c66edcc6c00ec7e70a4f97c0cab5a0b7acc8e332269eb832424e6fed90e33cf32e6ecc6e03530117f9f159804626398f11b68ecf76b5e9b4c005ac203b0d9ff20b9bfe0f5e741d20d91547250160f04cc04c659b520e1557729bc5144174c687bcd07ce2213ea34b91724d6c23b88aea1c703a1476cfbf1b6a8decaeec90555b2ac90d318a9f5f211a48e8f209321cba0fe06d703f129843776fb60f89aedd0103278851bba0e0ac51a4058fbc0cea68e5611f74f5d0b4a0e14f5ab45d43eb3939dabee0459b7ec98d7144da0edb2be63cbbe30dcc5265231da887506e3fd02fb58899f7d64b0930b99396d05aa599526222c419b6096ee713a7d50a9c816ea3e7554a121c6246662374dd68b77ded8f63e97c7628d70d89043dc56d293a5e358e165d19b516f3d9bc2330de2af3f15d35c9ad977e18fed397fc8a81fa4791de4a0c58b0e2d73b17c0a9fcf4e858131d9011c0113980a78d9bdaeb6b8477866927cc06440c62d014424567def5cb3d98ccfa8e2885cdbcfb3530fa2966dcbbbf384c942e5752a741ac214530c1b0a37397190207ebdc5e6a6e75cfc1c52e7384cd39b85475690b9f7906351cf8fa79de749ef35221cc909eb6222b570db6603b31b3867984cb3126ad4e7248570d1e3d16cfe3b352a280fa08587ae598289e73cdadebfab6aabb827cff42541741e08d11ec93d630769f3f1e94638b3769f66ae876eb61fca76e871cdcfaeec5bde44bb637ba428046c2012c25d8fcde9ba10dcd1750d64a8d6f5f1d093e7cfd4489bfe1a80e77743a0122d5611f485b9a05ebd0cdc721cfd3b4439b3759f95130cd74bcb07d80f8e2199033227ab48c02e29a1549deabb751b9c72e0bd6c6173f42c0879d21b46977bd427b8d86a552b9b28534e410caa1cdfb0a72308855cc0c384644159ba3381811fee1665d01c4670722e3330585aa95d7cdc10f53e05f3fde0fcce88e526095ec042b7e9fccbdf14f816286c6b0d1532472226b41171a8bea853f6ee79f545bed4e2135c70e91c44fa555c07945aa01cc3cefe38f507164e4728a40cdfdbb65ac2f930718ca34f4efe97d961bdbea8f80f4e1475506b282aab763a1c5c7a89e0475e55937ec36520c81ac83db56ba744137aabc185e1df13cacd78a2a0b1b281cb1b4ca2eff4273a3eba4e3ea449ef0fde5dcedc3737f305f81b124478e798b1c67f05e6b59b1b52ae4495197d1f0def68217252b2ed34a913a931bf3306ef2ca761afa99fb364ef892610cb36f969b5762a65bee7d099bc74a3431b543e3a4dacd6005626740330b5e267ebc90232b55ef61e1d891091818602774d00500e77130261185568f4ec88eb0e5a494bb69a1a499a235ff49e5dc236ef2b65b1cc16642645fa79c7202835597f45966215f464a810a9efd3e935d95b53a58dcdcd17f1f77ae8718cb4c38b70dda1e4b5e422f10e7499bf5afe1806e84e3eeac26d3eb68c70bb0a6e4f54fd38c343d17e8192ce212a186cd50f355a697a2f202b07f6ad5b46918f21f5fd4448c789eaa3c74b44e4e83fc89ce905276ef17323f4ea33e75a9843f55f599ecdbda1f374b870e7f71e8c256f3e532554f4defe1de158dcbf1ccae081e911ac0728d17e9c299ad626f48c4d7a73f5c2adbf971bb883129386075dfa944b1fd5ce89d27f4e3a66f6a27f4bc11572dcb50a53b4b82862fe3d9d7ec793cff4accc8dd545b7e78ca0f14905465e9582f357d6b00664de61a8cac333d95a77d24be8ea1cae4f161da21cd7b321e25613548a4f5d58c66c891b40c33d037ee17f10ce8a2ddbde446d4ac16d8dd117b3218719e5db8acbf993a594d9ad601d55d32a713901405b97db06eee73d31039b3d4f98f6238483242bc4d9fefd9e0cdc4dcd31402c1a7ed87e721811f8785b40a0eb94a676d4a8443c57e0caef8b4fc21ca3e70533715d07d800a1571736f8e57580b0a75b1a0a2fbaea59cb420234fe964a05d65af6b6de971fbd0d371ea5e8b295ae202cf9d4d3c173ae6724f99d5bc999895a280609b234f194efd2d2f71d540a3bc501bddb4f1bf87404fe22c50fa4f4f693958524f6ab719fc60ae90de9390db921ea3754aa759ff4353c0d50a3b244941af8513a61d74df05ba505c819a83ca993e3c5fe119c9dab1658d714a16a163af7a32f976df0718ec18983b20563aa1b1818a15dc4af627610aacc122cf5cb0a601da39ca9babf8d585d06fa258b0e8a4b668588b9a990b24e4417e889dda7c611ac77e87060676da5d88ae9b45c059113109b4198bbe0daaaf264c38460dacc13db212b8f1ed67cf6c1ec51b3288a916cb1c985d08610ae4e551020d72f25c2667f119f26fe8f925e2772361052f9dc44350c2266b53dd88c3468b48b9b7e9e7256217f3ba9a261664f87d53d6468ab468c47e05b2d97748b1977e05521275b8bf8ea4e815920e70ec99a4456a7206590f8df90b8411d486464a3d81722e32d8b9ffea5717297f29fb1895474e2036adf7807a6c23aadc932a894d56e39749702145c94197358436d32039a18f4678dd45639205d432362d35119bfcc75df50821bd15a05cbf4f0cc96ddce5a23ca7b4b26f45f2219afed58864e83ca7c31185f6939dd6df450c3754dc25be5072077c298267207a8aa73b21af5ce40a170dfc248c8236ba62f8763c8835af931552bf83669cc65b52a4cab26b68dee1adc8b989e1e661a12d702269af438120c5cb814ae72c22f0d5793976cea79a3111facf84d9aeb28715172a4bd2c40a91bc9513932eb811cfc3be1172e50840903778b34db12b48ff8fe9c071ba8dfaf556cdb61b58e43459e4afe10ad5d3e80567f84f90306f5b88c90935fec745bf0d9b6475da329c61b4c8a7b5204483049f9045144abb6a5fc4222d7144279a1561cc43cd580862ae7d4c2ada07e438b1276d7f0a9b713f98dda5345469da17ad1b8abb2f4c0a2901fcae75a9de4978f8f62241428f4ab6c367053cd3585eac14ff3b96849e314815bab40b5b4a877bdb4806092049d4a7092acf043a520e1da61c8af8042522ffafc226f3e24822654d8d292794453c1114f38c292234f38cb319d624e70dcffa47659a2c40adf4e5a6a7db303a867f5c90054e15c4a405086ed3dae12ef8e0a94be8b2e36e7d0ee34d3af0f143b096d3980ff172f2976cd598582a764cd0d046fcd7d13096e6342d7a0d7d44cfe14c78d914bc6c23381e755f29df71b465702b8bf8e9b1b7c9425119f3ee77911f0707b3a97a715688ce45887c8fd90d218a4415130e002ad50b3fa721094ae10de5bacbce3a8e9928b75f1567b98c5c86b490276aeadf84f7a3369d0499cd8161830945236fa47e1222e1bda06d98d7568c8019d3bdcf5bd5c591bb360147bd1b45d6459008ef50fa3eb61622e855742236d12b7af8bcc24429cd1062a053d6a2028a0c57573c089a69981f0f91e1bc75e0882930f342c960acf0735defe350ad87be2ae0a26d93f85c879df770fc9f801d378165cf98e26c2e56d2699ab22663e41ec0d3f5766b0450eaca7dbae865f8a72df0aa9b04c288d46fb88ad376ce25651c9074f45b432960325979be51eb9ad0c65391d28e4d7414d068022fdd768a1ba1ced1e6878b32e2e2aae30e1696b40bd6917497d892f0bc8325da5a18062cc58d808cb49e238cbde5d0753e580237cf94b0e4579d07c244ed39aaf1cc0d7edbdea24fdfb5befc5d3fb4457a0e214b839261b22105113d1836d4285ccb9271dd5cf1b57ea6bbff0c33d5266cdea029a7ac4e2e9ac57112938448246bc874ab5c026070d7e861dc3dcd4a0cf8536e96322a15d22551feb9fb12004190e7da01af00fc4ee7525095e10014c6011425a7f9b0bcb3a6d0118596d6d968671cd56e77f4e3e8eace2951185585a496f7dc7e107665d7ae64e5a6ca049c16f10a67ac9167e8b70d7aaeb65db6b5f1493c8070dd5c958a9f6341c7859b24829b0fbb0f02acb7b1802fc09e2ab8f1ba48e69e4530ee07f51dd194a6a6cab60e86caf8f3983ab19c9eaea7d60ade0e4abfb3abe6ca7278a86c0358b3d084f23738a03400367051d33e9da2a115c65a8c66866eeb27b77103a9060fb18e0c293ff38de701835349e9a25c1f887b3932394925884482ea9a2662521129c0b2500c2dada9d0051339e040e6057205946d56e012745973e317dd2f09389bc6220ab275bfda8d9dc713d024fdf86c732dd58ff9a47847c5e9295dcf5bfdf02ef9209553dbcdb634afc96690b0053b1f0edfbb63bac809295f7e6df6973d47d0c44e634d07e10f2e5156cb96cb0274d2e1d357537d43d0feae380721b5eed0bcb34f3f396b0d7f8aeab2c4321b2ce033d01494631840e8fa1117e4e9c5bebcbaee5226f19b3c379ef429fa5c5aad4870e4b2b1c17233e21c4a4d091dd103e446fb2f107d90dcb163b1c2c99041283fdf7bb58f7b8aa0640b0daaed8af7d02bf0cd41868cb1fed0e3e7f10b2c039c0bcc52fa0f76440815c5a964a0fe5275b6d4a3209b8f5baba2e53947c1ce8ea76e0b015ba26e67a6381ee448cfa2c095c3fdcdad034fa3cf487d280daa0aae730d224fd249d6c2068e4b346f3b61014a8475dfee4a11e9dfb944b4f99fb19be33e722372c2624c62243c6e9076aab63674abc5fdb9897a927649f43aaf6d32c93fea8b1f11a1e9939f47dad61d9f1a502cb48a90f6207226c294e60a0e75e096464e5ebeb0d427750a9869a003d1461cbc0b6c2fa0f106281154a853c8b66f1fdb934bc87fe4f341e695c3f05ee1fe2a61b0145a951e6d6268f24a78442a6a5fb19b04186f91c299adcfc566632f077504e72543482523a5e4cc9b1ab556e5319d2760b0f32f15040556612b7b97bb5c6b0ac4d7303aad9fc3cc4d331cd448af7a45b87872068cd231c2bed0d7551f98639cf03aab286e20e3f4a044a6352c6d3d38d2f92e2aeab2ad7a7a3b29581300c6898a4a569c6406da1e63e337f0e28f96caa780a5fa7108fc24146c08cf8fec54963e1748742354800a13861ae4f92c0c353fd5459fa68be535aeb705f659056e4e4f8ea4d496218e8ff8fb646745fabd99d53e54d20a5dd9ae378ffe0f5cf51a1c1d43d20b5c93a06e70e1c1ec5fa84b39e6c05e450c2ed5671f1a03ab3565d03aeb60c803bd90f25ae6ae982512a865517e7f142f376dc04f604bdc4c80149106ed47c5ac2d5fa04d1e09bdc01551565231378c5af6d37d5654fada0ecfdf32dd9e5204e31c33586619c786c66dee426c9803320996ce74f6f498a19928d3b454b8308a491d21b0ff4ff2d2181dd8b3df5cf369984b733d6c4e393527ff0f9d04d04682093e035c771ce91b4569c21b1c62e3afde939bbecf906921a285b40ab39c9d752a5c07e407f45559a333d89acb27ae0f9b7f6182282d04760e2cd8c2cbf4fee20cde79e70003392d816ad86454af4278760de60b48616e90c54d77dfbe160172e1a1969d414e9ef957ae7f7830a5e1bb05ab0027653c63928441a94f8b8899a18675586baf520da6583b8a204d2fbf6af5ab234ecdfdfe26608bf75ccfc8ee91c5a76a7b44aef0117aa48b1dc345c5541e14d907b053053b7afb4b676e57867c2f92594b864e0e23fb03492e985a001acab21763257357dc314a849e9f981e390586c88969346651d97f7e625181aad9461a24c1d880c9daa5a691ac14f3b530618adbb1450f8a067d081b1fa309478606e9f90db3b8a6d30d2bf08ff84f973f9724d8cfcb786060271b26e0d1738107bdd3eadfab1f0c0f39d401022edb8c1e6c9208f87627744496d9a0fee7554e95f923360c593db5ddbee9c3e6acb3ca12964e6cc2f5607764429cca12a466938edeb86c4072a8dafa27ba4d90af0784bbdb98ee3598690eeb73da15da5547b80b21c3d3945863a1d88cd19b9c204374448f30c7725aa1628f48716bfbe09df7d5f1756d2042739f8187fd2b67245ce3613705dfb1849f0c60076a402b77429b75a346856f2a15307d351b51ba387cd79f6138a78cf8c864cb343b051d7ceab8b0ea18c4a0c5c960762abe7393c76d083db92551e1fbd95ee105ed4d6ed9f989d43302ede55328c8314577574e2ff46d85c9bd8c344edf861a36c2372b744b557d2be55f638c86662ff790244bdc23b40047e291e63870f3422b7dd85cf85cb75614437bb6f5e4048eb1f60a53bb6a62363c3d4cc22130a552322a3cbc7c132c9c45d8d90fec13c576f0ca03aa3baeb841697896eae6c947fb68e975a13642aabafccd88e5ed66ed78eb1abdcf46e1b4dd28423c748a37279114d06705a83a43ab584c7c5fd0c3e13d99644e7c0d1ce6584d2c2fc910bd7e3c583530678315280727f52d7ca977beb61fe9885fc9f26f092c00ba24944d1e44b00867b4cdeb837686333cfa8d6adfe00511d18b307d0baed249e08c1cc499af75281f6752bc19c5a01133a38528ca1035305c3e84a0eed6bf0cf7f6cc620e0e688f85501b5193b5e51e2cf061aeed54ea1c69c37f6b05f04128ead62a4e27322aa2f9f41a1eeb6cc7da9e51d06d8b34668432c097b574609f0620b72019282fbefe33ecd3f8cd33a7df1c2bc088114dd0bfaea2f07d64ac7b1c558393d8569c58b9c988aacb25f9bd4e18c45e1ea4fdd160d8550962abe5371e5af442e48b3beb86eb5a67750ff9581f5b943702a276b40ee1cc66e8f21c24a9edd790957350d7400beb17709c4bc7b58253290eaef569a23bb27d6cc30f843e27ca590a414c8330f11a9a37788a30c303834f18a7cb13a6f85fea6151f5fb81d091fd5c10c9e1d87ac23baa9f5213dc5eb63ee57cd39009c6e41a1516beb0154e819c50dd6ec84f206649440eedf8403611fff1326039cc0d3217e6a8d5e3432d44609c8f0dfe8176731246b3ef3a62a284326240e5ffb187f127ee8516b5a7dcfdc48514b2a55903409b9b3663e270843ab1b81077157283d0b272dcc0273aa2d856deeedb51b5cf24c0461032a9742b8f85c878a836e154172bdb78d57a356d0ff7c241f1b27c64f0829b15b2479bf643c75b212b3404073276d1cf3b7f97d14809072c32ddf61207cf058d52ec5fd4b1cb0330d19b95f32fa0cd9906b6be2906f4a34698892ca7528135757c001b599eb4863c50ccce6e9efe18893d86d979fc121f69c19aa6be62603b8399cf1e5c121acd0e93c56d797213fd6378efaeb5f16258c374c405186b327eda35e3c767fd03f57a54c33d8811e850eb36101008e7e32bfc9b0c38c137741dc411fa893928b1952aecff8211f3056ac9c86d19dc58067d967a39b9580d486cf7cd028ddda780ec1ecb7a18a2464a3dafa5acd44070a90eb8288cfd6eb4640157740d064562dd778bf539c612cd6bac8629a4090ad5500b86582c7837dfb83b349b1c2b246b4aaa4d24ff25587c01a5208ae9d46390cbc30284e07854ee9fff69a617a49e1b370b3a552b99c1073739a738413827397df0b13f6c3713ce119130271c0c919bbc5ed3f643e9b01f96857ed849ac1988fb087876fd833a46f37f4791285e237a882b124c6ba9beb7cd5739f63f0424105d848f34e6f9e6db9c1ffebb997a81f35f122b665d38bf5752976fbc427ad53df35702d64769fa4ca6c4e1863546a88dd5c78758c19f32a0548b31272f2c5ee085785ac42d3a53d5c09fe5d225704ccfded551dcad4d8f30e4d3d408f327a0bf69aff366a40e6e5dc37865adb14fe87fdccb500ff7f02c4b603ca90c47c06e554ac749e88aa8ac1971ed14f1a11ee227dc2813b529c4556438e5fc0885fa9101c4e3ce5961afcd74c70521a66bac990cbfd95852301ca207366b554da58486087d80cc5d20b6a716996ab89cf88334a3a28324826eaa591ada386feb73a1de9a9a291b861d79eb03bc232665c2d61ac57f3aa71f22275f569fbfaf73933fe8f3fcacedff922bd76bd39f6259a19a6d550562d148846e2deaf6d3b6b19a053d043e60c320ff08b8cda1896f95a4c020a2ce5742e2120ae8c3cee4442c2bf33b7e21f2800402e2993436f53620c5f8e0785ef8a3c0a142892b32b42128c44d380b55ec380c9aa124497ae51e45d20eac22c2c5efe44fca6e760f99b5d6c996da132be400275b5bce30d65e59281cdef77dd69ae6b0fd5428bf21e25633b2faa100e49ec65c6cdad600a60439de1414df0807809ba517eb4c7d24b8637d8a5900f185ed82cbe7c068b8f7a7b20541dc4204452cd0957a39a6f32d3739ec0fde8993eca3347e712fa561965dabc406692be33058ffb93b5722a405734ce218406532406b06f217f71bb466d755f4339df6336ac6f040a2fc931e507682528d590a1ba57b04cf4d9bc3df88b0978d38dcc9c69125bde83a63e2a46b0e739806cfb0e80b983886de2dc86092dee0930f59ac87697411682986145b3d9f1326ca41289b7c567625ba10a6510ce70c864721f428088bb184162218bb7e2f55a60b02a0e584e1b3f29c3b0d030bed97bb333c8d8266c620d5b982d3d99a6e1590d87a6cd05f030a8bfeedb4ea0262a16f33bd2a60d8756f47b7120836dd5be8aa008dadd746fa3540b0d6db8ea63e2056fa6ed253011e4bb76df42b07d0615da6894fb251eff6a0f37378ac853d1a801e484a5d70b3098fb03c119633458dba2f31d66dfdd666ac93338fa537702f8f6854aee1935743336222ad3e2674eb44abbcd29cd60a24d88fefc53615a3b24b4b4fc18474819712ccdcc8ba6420bf3dc75c1ad87264d3c1e433997013e86da9e499eebad52d003b8c08a3bdc24432c5d7e0d242f90cdbb53daf12f0e3dd5d904e71daac66a40e56817164978734bc3a0f899e803b7a8e8b4edf59f1434b9fc2410dceed49dc8cecfaa185c1b1e3b2f0f842261adcc5cf80e67e916db71f963870f73df5dd6774a39d0d765a16c2e9a49eba93b4e5353e0f0731213221383b8ee2d48d30f3239cfdb5ee82db673a771b9081d30001904db81ace27c98f35c158f24406635e0a5cadc28e44a9c521e992ecadd49c7a4bb5e50e49070eb1e97135cc02897bc6b29e68f4403d75322d3f8f52444d485f1871ec832c5919b2559ca7bc8d8ac472cba397f02f09e52c1dc75b1d58986ab97616daf79412b042c0d63a38d34bd7169b9565072e26ef8750304230c24f251130aa1a1f11f6c5cf88affa939289e8c65adf047042fb4524ed7f5315fe955e65e8eb856bd2fb3108eac91c255225e6661adc06f91b50eca812363e47b9dec0be83046b7aaa6dd338a8c0a2821e758023a57aa3faac9e847874a5b9846b942e38eaf7690b606845f81bc143cc53fbc75bee8307a9fa14fcce8a2e6236e7626e4e0871ce47dea4e94f918e717f0a583bf25c81d84354616d3e0509c8b377cfd25020a2b29d5208cc9a703e89adb4a75d4045546a1f705ed3e2d39c09cf16d89f11f080471ebb2e81f0516748fbd5a1251bae4258f0ce5db58eeeadfba1496104f876cf1454c27826188a7123eef7e692e9296a728574cee8093b1fb5812858dcf644939a74aacde1029a1bd1ec271170aa12bfe445cdc28bde0ecdd9a673e2e79b1fa503021a80ddc468f62819b523b77d4a4d8df2116fafc7beebe3a23191eaf1551622504eba4f375191fa933d47bf428bebe2fb98cbb65b3fe7b840c2fd1b7161b7c33dc32b82c3d225fa9a6c6b0d92c24b01a19c55a9cefe7bc330a250e978255a9b5d70ff4b100af21d00b2676d84255f86d19cd29610245d50a1cdf9cad63149b17c4940020fc1458e4c84732420983bd39edd3d6de5b5450af23060bfe8e5eff47b34cb9d193b14c5e0cdfdc20f639380afe00e2935252385ab3b825047fc8d56524e9014635fb1956dea891f89a17e8503841e2bd18cfdff9e8b1411b0ecd5ae559f17956fc2ab86c1c8ef961556bcb10df9c7136411c47f32f895b1bb081b13d4ed6af55e21b646a4cf675e4662392205fb6365ce5fb799df0429db5c101309eab45e068622246d0c8864ab6c0a4f4ce592bea30c8b11eea62c29de3e802b5dd70e63e76a2ff2895c3ff6155d892812c1924a880a2d8550dad5cb790ae4cc7888b34897dc4da334cf71b55050dfd407243cca8d75110974d5d12c0ca9d29ab49399e24e323c21287311940d9806cbeb442b27d47bffb920378a8744d640c7e0da18d6f3e170468849fa41d545c5e441a1ca82fedccf4ae8e201e7e8d966bf6e4ae9335b73b82907ec487903c42e09cc3090d5320821e0cf22e7221de1243de40a196e05fad57de56be442c559b8a0adc37016f5c2340f06fa936a5558f73aab909e53af41dcd9620fb818ece465c53cd640426b5a8a8675d0ef4902b585e60ac1e493d591572e61908785c62a511929ffac99bd4bc4030d9b7d1561e2eb5ba109f739a1cc86f40deef3d7e84f71d7fd8841b563ffc12333ab21f0779dd0aa45b7ffc5f7bdb4f837f6c5c8aa6ed3d039bb87d3c9051709e026104c0173dcdc5a4edad5248349ae5d25c1ab054a50746ae4459a6b3437f1ad0c80078d3b63609c05160be313e7391c02abd4dea737b044b6c9dc7a78494b0ec9289d9b2384230417366e9c0a28e4876d618f488e83b1d62878ad84ba61712cc9518b17b96c38f57e00f83917b674f7ab2a631d969794a4ab91d2dc8dbbe0f6d85de201ca53b6c2075ef6a22f73f44849866ec34ff24482138f92148d83e0c0d2f14f79da02e3659665136e91b7d23e8109a895240cd912dd761837222fb79a7b0ed6b4fd97cfa93117acb0a2efc5b1ac54d91f62a69fda8a5bb1f463f08749355c19edcc8833b3ac09351587599e40a23f6820c2def4acb54c1efa2d84a5123e4fc8eea931d6ba35257671d85618d416a87d31cc925517f7ab13f58fce3fd7fb33e3df8658c40452fcffc89e6cba2415c349b9423b214e91043b1323e9884c360f48c51a2d0fc4bb095ff38436735ceeac310162536cc83574f447712f3b48bcd4cdfe6b3e05e497f3094ee52663f1495ac55e618862915be0ae51c129a4fdd3ee2c448a646d15695b4cb4857e0580264a20fb49adaf0cdd51249f31326f9b4cb43a23f3890df63a743b845750a99bc104659cfbaace77e5a6864f8d6943cf7bb4f7fb0bbd197d31befa8608a1d08b7368c2121d975027e007b74ad6c6c6b32735fefd69d522afd014f46decc15ca168095d6c22ee44312b77b6c9790ca4e512184c5c035256551b7377296770e69fe100a0926c4158212e74157261dceb3a1a6d4598bb4b99e37da7380782df7de2a303bb4160ce784bea1f3f56844b914eec3c969de8d204b2e682b81e8f3aeb296972caab76e761b823020e9cf55caeacb1e4fdb81372f5598ee15f940229a7eab8c805a58ca5d0ec74b6d5d8498862c16454d77ab729c6ff96ce6966fbc158c3a585f2c3bcd2b6d0c8abeb57219d4000655f5ab2d341985bf1072112154a9f88999f1e02fef08ce8426fff78bfba35f1a102880fc61e7217ea3b360c15e4c4f94ee08bc1ac8b4ed192390b661dca71cd3389d855a5c7b441965a6de60bf23014440f7cdad5b92d0b52579185b81eb8ff4013c3e95b0298c93394849cf7d281c59c0d8e3d461e4bd202e6fa27603a2cc30a23a2b87a1d4735ddbaae0a570a1aa06a2e5186b9e518654449cd3453c93f651aa51a535522ea2b2341c997d73ae160ec6e44c26f416eb662075d480ab15ee37f7d426c0837677d7d6e6f6ea7343adbdcd4ea310ad5a8fd9ca77dfe91644738dbe75e5f6e4bdc67e43db7c8749f0fa15dfe7600ed1f14470a2594cc13c80b6e5e903b1cb256851ee89554c2fb632cd70f48a947e0232c98959b7d2ac302b1ae18160269d1193241430e1ce8502bf2c467020a000e439f0bb963fd5eff42f608a833e05d8eae15721b6faf90dec071bc5a3eb71cdd8fbec92400920ed00954f79ad0c8d0b3eda10ac1c2b0ed1a07a7e2ce47a29cea4151b5eefd811b205333e8d818db3df757621ead9436712a0748ecc5c44d620f3d7f25f6ae7530093f87e70ead12092635d2330862ad4bcb009cef571790ecbe2084effb9ad24e73a3b9b103ea52793511c38165f8912f95488ffae9dc4bd558d9231c8033abf6203d8bb20adc74af8b2be85afd75aba06528f95ac5aed120d3ac7b06260eece9eed3f169a93a8db56a8e5908dc816df468014232b3d42e4f475e94bbec3e05c52e320174eaa7dddfec155b4cc7ae1512962e5229e9eaa6bb6ec2aa8663cb5555b00cc18e08f6ee7a261c5ef7f45ae7dc80adf33ee87db22ddebf3b9850a3d8ba4c2eed236a8cd6357e9a183e5b61fd4cda4af379f5ad87f84672a1d721f8902e8c3a29d9c6a9066c832f282afc36356d7843896f753caa2307835468e0d83760397bd9a21f7ffba7accb993353cb8258edbf7c55f7ca52c5281f78445807761e0636b20d6a59b571aeef9bab311c6149467dcca8d08b904891867ea7879954aff3805fc194dd96f3708b5a32a43515105c3962ee848fa9ffc332155b2e80234bc06e8e4bad35c7603f33b755d6072a200e31820f33b555381af0ee432bf31f45f54aad37dd1ee1e9aaf2a06523731b4c0574935c38316362e54a779ba49c72dfcc98deb0d4f3dce0f3e40ecd101cda7658c36c3ab620f66a768aa30a5de217ca1e791f14e44885518bf8157e9e2464501db975260e546f8db3e57ff7824c04fded81acd08f64ad4455aaf22edfe249a356affe5bbb7f3056fcbb5e9ab75f43d8535e0937559f05a5f3405ab0a78f3d9c191fabf77533262145aab899d2a52615abb1962fd06259ae22f03014467c6f5e3793da5b392a2efe5b428594a6a92163122ad943d6c768a50848aeaa3af4aac64c4b338f444dabbce70c15da34460886ee02ba307fe7803dfbf0451e9bcfe31ccb248128d3ab4fb42d31d24a5a4fee03671a0934bb58d67866291ea7640d6294d80001808dc6e15183930d2de84a269ee7198f2b024a9c1ccab4da3082f43b0f31648b6642fb6cab127fb44c6d9184e77f6d9fdf569a49857b238985d3664f487bb0006dcdc8832626ae712ac81ddd1917a23df757b6d3e6aa9023b7df90d5f582891d42fdcac12552dc3d0b5167d0634599466b5e3ecad4014a5bf128bc6cfb09a54cfa7d494570b1861706a2383ab48bd4de482436404e6d1c009c5b63e5368beac2b5b5878ac3064b46ea2bd93817260becb29fb6839b184cf7b89dc561912feca10263146414f6dee341554613250a4fd3dbbe63011545679a7720a6690c2492444097f9debc82adbfd392cfc2c5548d594f18852027e519c3663325bc2bab2824bf10ad81de93fa8afc5aee78f5506c1a65749f0364e0fa60ab4d43dfca9d6079b1268060e9d961140ab7a94fe59f2b346850ff347953893a328d12c9aa8883388983ed2cb1306ac68b88f90c3be4f0007c08b4215fb1c2c618e14d2fb419e5f0006a83ce141f8db2536200466a9045106f92a65cc5eaf21ff36aa629da9ac1fa318451ec03a85842889035e79e7a07550081d30310739c0b7528d2e223e6d50f34af7c368fce5a7f5f46ee04bf3193cf12dcdd09eaaf4f932f19cd326aa665220de4d46d1d2301605b0eb5e2111fa7c0a93a7a1fd5ee1bc545e425d06563283be747de5e555a78b9aa0d043021b9c841bee5cab36b3f99a0acc27ae60ae7b438ad569e2c2e9037f733c2f6a55f8119bc62f87ef9227b7af1fdc8786928675257d7adc802b7efd7a59605a18ae54fa34095ec8c432d51cc7066f65e1493384ec1b0bff3faa05b8282a33dd3293a59576c1fe24fe51e6f772ca816f0fe41f597b048a1791efd6555749443632e8efd956c97098ccf34300927483c67213d286d394a48dcb53b7ce500df789523ea641d692cf00624559d8443a03343e3eff047dba641fd673dca2be6c048da4e0ecced6683fe43f9c340dd265580ea06da92885e740b3768c51c4acc2c8b04f00adc4d3346328ea862ce3c01d5b9933c7daf529ec5aa3dd1a62944aa915c746f419c629722f46cb9d15fea8b35bd7f01f436c866f218df01fa7a0c11fde4ed0d5e3c8ada47b9565d53302605ea9559a830cc8991555df260053aed36778db6461baae4ba54d62e6377860023f903c485597f96f6720681f4abb65a9698f705310b6d70ba9f3b8e0883648c63ca413f584f5288b36c783c5687796abfe8130a1645f9e7a14e896c831efd2ef7cff5dc8ae8899cf532c388110911e81043242e279c4119f3c95a7018097733077484e07857c8557994c64b872edcc551df1f48acb7aab6ab3095853c92a86d59831ed599d640510abd83f73467f3552d40fac847bdbf0c2a323477dd0d198e78d700ae48c0d3f0a3260afb030cc849b5d930be68649a74730327411aeff05811225607421ee951944a1d1757ad3276020f259b8a2259925f8e1b15f27dcb7efc2db504d09a44beccdf32edf754f1664141b222311c7416b0d435666ac44b1b0ee8a9e793ba8d6fdc2ea84a97c3486b5139ec687b2dbaeb89666c11c6212fd5c0404d13d9dcc8b38be7f64155853b664ae2ed917fccb0874c56aa2d989ded802ff448fb8d54a097b30f490bbdc103560a731b2ffa2780538029f6b1773348934df8f6a6f48dc7c0eee646f8e43df038341900cb3f90e8120f830532048bf8abde2cdf65fd7ac415c226b9242be60d4c23b185df1f3b57e2fae2c408f8f33efcc82e3417a8acf36b3bec8a7d1c7423fffeaaa7957972738855b67428e5b35bcc7625e2d01fe2d7023d0e04379d9a8a5529bfc595c0bdbbc8550a007b490fe1731ae0e446b036b1b1aef76f5dbd1fd0c21b6193b1b87631fd705baa3f5b7b68fb463d34d197824cb25873b00907ae8b20a9c0932175ee9da9d195d54d7bf448a19f9d7fedf47403b594b9c100235832aa5e2e16eae8062b54beb5d208906c6590116cb05815ed38dd298faaf4785ad357cacd3d0605f0750e9d718eb33aa0a35fbdcb8b963845b6351a89a495cedd4da9a655c3a1cf6c003a1ba67a2e566d2c8fd0e9d1bddb8afcf353224a279299b20d70abe968448a59d4871cd1243aa9b86b04f8a31996e7d719fa15df070377258cb2cb846dcafec326a8fe059d63f158dd29c267ff9f232f68c3038ba65d8b14bda9151401cc6030ab4c6aa2579c1eaf01ca64d0fc58f7159aa764daf454058f699d0aad921ebad844fef0600ceee69e0b0d8bcef99396203d4b24aaa3cc1779c4e71d7912b37050fbccb715453129414758af288f2d0e1ecee76b501476cc3ce717351ca3d94f84875abeba8d726eaeeb5b89cf1d88c4991e71db4735e0255efd190117251514404677542624f0e854b6e1e5f675f0bbf3baa1a8b5888b5129273ac99cae6243228e2bd37747b1d22f1e1e52c4dfc5e38f9f60cdcff3ae790db155694d18aad5015100942cf35e467826cbec32f0c4c0a32ccbf72e68521da2481645728d3c82c18aa4d6794f5bee32d9592a11c261b8711b9615bd73a4e5f77d7578bce3b63475f4bd8b4432dc58a41339c952a56452c205929bb1507303d7c184546b19112047911ef89dc49171f334b959ece9b313cb50fe34dbdc0522a103bcb4556ecfc4752ca3882bb4e4015a5d43a8441765512e7f5dfe9090e9822eb3264bec156498411cdddafcf480dc598d21b0267b3e9b4f324b1dbebb2f5e49490fac32cea8895d0f0143884f54fe1b100adb927bc667dca924710ab02c1532fd0f10309e7cb0c9523d81821e58fe3d65550640620a73434fb659befe89b81a2da30ff65052f9d1998729a4fce427853324ceb9c40050a95b35f75be2c0eee6cd6e38f6fb83351ed21e9fa47eb90863edc9bcbe4b9e8afb20a9fbfd9744301641045aca3ff4617c6147e99b60d0da32acef4eeb63f44b90ed7a6d12dcb93093e6a7e0537f0a785f2ffde0d656b148cb7077fe20d02d51d0e765df56d9e09eeaaf4061e4cc031d4286fc31b5b1a7f3c80dff18d5c10908d25f40d1164198b49606a62684e06e8fab316fa642e47e55eacc0af484f0e0945f2344c35b2536142ef9b1498bf55f086b1874521d541f9eec9dbd18c0e1adf541bfb029409cc009b3c58cee304e982d396d1b47ada12f54755bcf3604d3e20ac6e3d0cf28c0a7e1bc56d3364339e29f918811db30da1a45bbe92e0626d86fbc01b9ed7b22ca7c3021a7f2dcf891c520cd6486be6fc7187aa7875782787385e014bf71e73a182f58bd55cd2aac847977692a1a549519652651af608d7daa67ccbc7b4459497c1548e80b2e960f2c839ba99df5a6adb794f97b1cd85e11ff0547da06f05ac26c06b50e2a4957da279804448fbfeba432412096d674dfa349c1964652af3fb34860e03badcdeae3688b01e0ddfba356e0205b149c268f9acd1b0a84a481eb80cd851223ed9e9c7f133d72e5f5fe94d4b891d9b661c6aa2bde999df01187c4da056d5784c34e1b9a464f3168614b44f74b026a669c02c2049b6486098cc6049bb0628acf83838478e94350ab8f814d400fce3ece6be7ca65ea7391403a90fd6debd5cd8034390cc57659767ac1e664890b39308d1d1d25c9282d219ee372a36c7cd0c397a5a8400a3e006467f676af742f647444a88e12d7732132f8da9b191940488a9dd3298f91f08707633f3ef451ec5d9082693c77327456bb9aa702309f3cccdcd4e96048ff5a6cefad579d135cd562ff70f8a558a284ccba99526e38afcc713d3e35f1d4c343bb0959b03b936a83af0062fef06c33bbb53c31812a5720a42d3199e0fd76bc762423df334d7ff47ee749f9b6b6251c6ea77e59e7a7b018b4d17b90f72c5e899151bb6516f760a140f9ea474ee885f2270e335fca334d3e40576eaf44e73b8cc75fbaf4db0d092c3464a892086c57fde5af34667cddb45ccd7e05b74c83353f02184e4866ac147380d758bbfbc83f2e630f217ee73fb20c196b660357cbbd6baa8b7954afeb638d564cdda86989fd49b66a321129145a7aa0c30576f01806551f9a6ba5b85c2f417a052f2ecaaa807aa928f3c0ecc22e98ed5bee05aa578f516f747515b98e9f9928f628ecf52f30498257d7e6a8bf25d73ac78c06953670452c9591de1b3ce3407a98334c05b7d2ebebe73296b801efa1c78693158667bee3242ee1b8343e1ffe0e2471fdad840df4c4fd1f80a00aef84489016db7d047c5257c58ac1cf8fc745a983b45b8f2dbb7ff63026141edb85765a94b8c248b6874c2d8b56ba33d5566634cf14f6c05156b4e12905a88798b62a7654afecf6acab5b3159be11b8a01cae5a930771ba81aad224c22751405bcce2e44352a84447a7fc458cc7c4452b91951dc747c0927923e9af1b56fa4acee4522fd9c6a37089cbd5514025101c95d8a8568e341d5903e0696de6eddf659b859636b5883c04077ae663a808f46e5331fa315bf07193e8fdc9b5015f758479743f8c8c02b0e843651b8f60a14bf8bd7ee0a1ec843504f18ea32bbb0b4ef7022d1b63af63b9e4778a5510db8a5c03e9a35acae41dd5ddad29a937e05fb553e8dac6ac3179f6d0a16b6242d7eae449a0bf7254be4f304a978d3ac402d195029a9709736a9748f64977a2a7964c85db42e93d6ff9a312a455717b5bd078ffd39efa4aae97e566ed012417b1698381bbfebd1c23ae4322a0fcf1ced2854298998df10a4017544e6d751513a917a2c5286218bbc07e8064026a97e625dc057a7d4aeaffd4083266bd3b46094613f37a5db17fe2da24e6d65bc2206ab1dc910c5711a8d49525d7d7f9cd28cace01321186b8888eca7c395619629acbc54a488c457ecc16c2545025dd2825ac53d20bf93681ac6420fd910efd93e019dbc4ff7c0cf1a5834ede48c742d2c337abb9ec4338de4449b5bf72a90e10f3e40e1a534c738043f722a8b1b0c6a3720256bca316aeb1033a742e4acdfe570fbb73cadb2006449d505338c80c06142b6c230b29554170f6804687ab210feb86f1d28abd6274b929fcb57c45ba85e41eb0591212f44f11b5fd54528bd65fd4627d6d6ad3a29f4ce77cd3fb0636763668c9ae5f05609c9803c56d5a8d1b55a17214b0c89b86e6efa72555b79cc53bd231f1c8876036775b68287f3ec2981d2173549c9ac6b84baf064365b4d528e5bbce0e072c44c4a7ffddc367ddaee85147fd75db4ff930c0273b63e6efff740f01be691cb005769bb18cbbff2f2782e341f3ebb9131d92ae32e8da1eaeaaa507b409585820d8ffb1debf3f65bc0480eefb81c9cfc08046c65196b067f68f209e58f06f89a5829e3f45684052ce13e66fd019a061e57208289517e490846c235dd72d8f6fac773a8b1789ef83846cc489d08b4d2c567a031919417054958997e4af867c1b59833c3c2acd68ceac1f795d83d00f305a31e7690dac84e8ecdc1f5fc88b122d9e12124e6062cc91d356ff6cdb65b58ddb28f0e0777b1d4ee64f964389633de9c1d03ac963f00b506afced2fd81332702362000a6483e421d4a3074bdfcb2cb2171164dea02c25146fa578e2f750820dd15a0418490f25fbffd5b21760c113093f43ef762181ba2a7ee872071cbbb289ef0c074e6c1214196862316614c6e709b206a9c55cb333b56dbe96ec75d9e80fc92107b7adc24f2f8154be46e8fb0601a2cc4811f84df394516b33db18e093f45180529947ccfa4af18519ca5261de02568614567d5639a8ff2da72237a73fa0322184eca13e96cfd37581b9fb6a5b3800729e93f9114b08b04404933f6a3a56c3a19b7484b4a7d4407d75d66bf0ae3b0f5074742c1a70a4fb1514734033ee6fd12098db7926463caaf290621cb1628a2d1f43a03e1158ec7662072b1ea73596440f4c32de01276abc60ac258c329babc4d1a88386ff48c05e20c62f55d42cddbef2cbca39bf14f2c6986024d3fa4b563fdb5590c9fd0fd060e506efd0c1dca884d3f0676d84a602b68d93cdf7f773062327e352bcf7cd840d5679d8af61f5c0c1f827f34107b5edd84bdf39bed7ad76cd44f29c09d465abfce9cee4b6ecbd3be5577d9f617a9f5b7e3a63b039a8ba7b60b7c66d0c7fe3a52c59966f2d2bf6b5783a3d5d0f6ed827dc7eeec980ae8e4f8146a653d30278c9fab7fcb84fe717f81d654821c2821fa56a43c75c2d2dd68b04192845d45d08956c640f5ca6ada9825fe9428e54142e890783f2e6464040bd26c7f36b78566d57b83de55b897fa9e738509471e944a7424539991057c27bd05eec2fe4b043600acf9d86e1adb91813e6a228fd361d690c50691ef7d9c892c0f15c5020542c8c6eb9f420683fb585dceddce760c133aea47ecba2bcf1be3717a4c2c530f28bea5bdcf813bb9d9b85d70b59f57444e00f3b0d1ba20ec70acbf2949f19d9e982eb6d66cc6937fbb04b29779adb871da9779ee6946f18a12350c32df6b718ee0be337e57b5cc32a30d3e55ac5ab04d3922518de6ca2590c0ea1a822dae9f9f859c6fa3b4134351f6422c45fc003ed1c54e3df727e3473fd0de121f3fa321375848a112981982bacabec43a79d59b1f4470ca10964d34f570383cfadeef814c0a8580078200107a41916e40ec930eacbd0405390015493eecfa2db15fcdd2274f35642a2febcb84145315375023f3197526cda5e25d7cfc6cb6c674562726c4db74bedce0cb804f33bcc786c198da6947206707eb52ab8dca9110a56e3044e083922709dd2b62d33fa8b0d6b582cfd981ca345e44b04d9b7e5dfc323b79c8e38521f62d46b42e8a8d472a38e521bfcb37059a540873d89a2f49e15c5c24acbb889c36704fabe82cbea665f898536f1eb80c74b9bda4bfe72663e02a9c9e8d87e3977d107f9d1f05a4f52aa7cc6470a7ffce53e793729daf27c79513cae4484bba0afe3e61ac74b9c8afe8f743c19aa43aaa2c48748421d41f661acd24e2396fd0d75eb9ddc88000900e0d550eb1b43489fe8a061b39d7b57fbc69a9f16b3361de5d3488334c41be6dd9b3b21e166df844b1e693ad852919dd4ba90db5856b74851a4cd4a424829ab7eca56e82b0f61432d2a55ae952b543438b006cabfdf2fc9617b74372484f2806ed227294bfa7d9507f9509c47d82c83a837dc9f142faebde2e3a14b39d9d376a31c9052202bc32dbc3ee4d631c3da34f30227e9f08f2b52742e5a61dde5de05f9497d9f804b6b3451ae87cd2ed3e66daef42141bc0bf34278bb44103cc41038778995b644befecfc17565e035f1a2c767f13ecc680ae2d1817b64bc508c82de9494719ddb7495433a5c892de7de81997bf04f358928f30042ead96995f720479d3ee96edbd90428e7f70ac216d55385cc8f452ee76127da52e556ec7eaddca89eceb7b5202e559e0f58d3b79dc4dad116148dda93859b3ec00c12db19b493f9e3263b7a451e8304aef7857e31f7f07d00ecd4dc57872075c11089dd99ea578d25d9bcefb26bc2c4f4ee27a58d87fb6f248aea05b2648f39699af557a1f9b6c8ce985a6fb587651c546991e6f7dda13e70cbd784704f321523ed0ad49e6a52e12e2c1e13095634aebe48b43f51ec2c98e2c137920977624cb6d6aaba8077761e7e0e780aca29da081a88f34f72add5bc2022b1ecf3a65dd8ef6b835c29135b34951c326a049ac5edce5ba4689884b6a91b850c62c25a0733d9676c69b94921c9539e5e28fe889b6b1d98ce66526c28da4def66dc8b91a45d8e352024777e25265a3a9ff37d863c23b508f4308078c70bf28da83137ed925e2760ece990ae0ce49bb91372e3d3fb62f7dcfda7b740960bb8362a98929e8600c2d94b0a559e8a1038cac66b942e1a50f089de6f4bdb320516e0affa4836b636e3ea940e333a5c05ac237ebde14a06114fbac9e372881811cd59222d748a0f122d8469ad6430af508f83a53d7a8033439a63205a3dbf1b3728416e39a39d9d4b5c1dfe319f4c8b571a2d887b907e45cb55fb1d0d4ba44e145fe813c56b786f57435c5c8bfb2f2c32ef2f8ee109ff6f04d054f2e3220009295b3147c88140cbb7f36d1155b561f57a885fe63702b568fd7cbb4bf387efafabe1966f6f8d7a08d3e64d4b9cdbc90054232ba59229bd4baa745cdc4b58ef8e420a847a138696d3238abeaec6b445490c0c36243315a95a283658aa21b8284627bf10c44dfe2834552391652ef1ce1ac42d82ea60d3437d005d5a614396831cacb0dd356ef5d72d4e1394af578830b4a1dfe7172589df5b511200a85162857501b7674f2efdbda7104e24cccffb337732683966609800a3207bdfd5f66232b669c45339794d75e8a90b01944a7b965e16bb2cabdd0bd590b01150ed802828b1618518f9f2d995cd144f357aba56db078e339d2a65f6fd9075a6e6e6ae009c02c74ad28992b3172e8527355574cb719c255d4bd4b2da192cc3f0527725dd9c9ab79b3d5fb573f0b4107116e099ec48163a2553c44402909eb8a8c1c7f2e679113aee6af69ca17fa9060897729e6374a064f6d308381f0df9fe13c97f7716910c703ab93c45cf3e5f5c49a30158ff4cfea2e974ea201143f9c5ec5e1722398886a16b1f59e23b62f618bf911c4d84b548ceab95a8e294d58ef8ec675f0fb9ced148f0fc01bfe7f254cd0ce91c1fa3133d33c81f93d99969f6ebc9ce05643e3395fd5e42e6667036f333e99d7c68c9eccd9b99ec4dafc35e0d2cefcfce4fa10357b28f4643426a12d4a1abf593ee2fca3e2d5d08a981491d612d093a7e81ecf9a82f540d4035cab578e8e685b203afbe7035805598d7ea45372f909d4ca6d4a7be02be6fe2cea3d24d57b203ae7f213508d451afd543372f901d59f585ab01a846be160fddbcb0b21b6a7d203598ece8ffe942375d59760fed1f9006a15dc43f5ce8a62b93dd61fb0348d29039698ebb16d9df11f2c46afb04ab21aedd33372f8aec0edb3ee0661afbe8f2c71c35e6593afd027de6cf174ecbd93d3bb7d0adfd89ba8cf204b23152bb70e73f0f9fdd12977c806551170d68dfb4d19938853c63b6eb1b7f180b2da34b9b4db294053c4f9d995296d2e43a48a9373c21b8637148dbb69022970084ec96e29426d7414abde109c11d8b43dab68514b9042064b714a734b90e52ea0d4f08ee581cd2b62da4c8250608a9b15b8ab9f06e9c58c67fe5fc9913e6c708ffc6cd647c28e7c9343f1ef9eb96f442a8684d06f8ea1467c88fa91e66d453e419e40f465bf2b6ee9e4c9ac2b43a9fda68260424cc91eb6a579ea16ccb08d20740e593df9db026d1f14acfc3f7878ecc428e881072af99538ca387a6af72137a604f4b9213092073116b28f9136e19d18104c9cfda6f44fbd018e6da94c658e3d0b7005ee7fb5ad7eeea699ad9732605fb8669fba401f51af6e780c639ed7edcd9f9ac6bcb3bc5385c8b93eda71d91bd36683975a16a0469b138109e150c69a55b1adda714c2da859f0d8e73b946df07407d918dbcf5ae23e9c27a478e2f66148bb36c164f840a3441e3c79fe998e427a061ca72a2d87512981be2be0da91cb3b99c656b507d0ed55959b7ab7ad02326b7747e169a3995cb726f732bf1ccf215dc765ea93eb92d2b6bce9b89d9aedd0e528907b8caaf86663d52977b556d8b57a9a192f24ecb0cc782e555fed5ae496401a5b897886e4ab5a12d8d6262807a7439af203302152468e8eadc01563ec8078e4fab6b7093f988acc7835fb8961e286bbb95e66bbaaf5a2fdefda87cfa457c40f263d80fd0b23fbcf84f68ce488112844f857dea3997e1a789af40553e376edbca5044069edb1e22ce1fe0b5cf5fc90d8e3dcc6b1a9cd9a1dbdda91a12fe2074808ed7d05d45e1cd4e6bb0b17a06c31061eb91a277dc3c837f1189a3407cb94504a2f4129c3c61e482e87ba7ee86d8408bd216ec87e99876aad21e2c0204a32387fa3fffadc9ca62c98537b9bd37207f948dc51db35be5cec4d70f0331bba80ecf7cff58cde93fdd452700839c406f5e82aaab81bc0bcf81cc81ec79c65978c528686b01a99463b11e241d113518a1d05a809172588a3f920a0ce0f510db0b3d852439b478a93daf7d72bd1008c44ab7cf13b7fd845d8b365480c7957f3f2b8cb3e6bc31bb42a6a0163a2938d250659a6328f2c081564f21ce122cee06943799082a37042dbd2d08c298881f57e2dd860d109a1567009c91c2d5331fea75c39ae365707760169b2b28f1f6fb35243bdf31cc435ee03db073342aebcc5d8ac697fc020ac99e3a234edef96e2c96e5775b6fa7276cf93036272967eea0244f2c0be7532c1e7341c8191e4116aa1d7183670a5f086728526dc84c2b2f9aac10793d07d11ad9d14e16a4816cf67ddcc6c1261189c0e3cba06702a670d246baff320f93860d8f26d8d7dd160f0fdc50f2bc546af6fb9e2448deb4d8d4315e222af10bf798d12c0545e4e86ec5483fc0a93c2833373e2cad339b954f824d3581d51f3cfdc84ff4cccbcda5babd40d609b2d9032d7bb1ce4725c1f12ab316e211af5a88dd56df0fb5c24c9f1c8b736da73062659136a594af32d82863381dfd6cb6bc4e30cf34ed1c9f98a9f6d4af8134f451621af00ac15c3d72ab10709d70f8cc737dbcd01fdeeccee37ff30f0b3de42332a65462a855dd77926c5e10da42698600b10e91ee02738a5d1a89ded333ae4d99e19076e01aabe2e1fdb0c0517db8299f0b6d03024605d6a5343cc418622537c196112c989dda3a59e7e5af8d1552828492a8732f2b0ac2f9aa3362e309cb9669fa95e82eee0dce95b45ba89f1def67e5102c9d90ce40c7d709657891a67d2b5ae0319081fef22c55dd44ee5761fd30152a1ca548c566f9457f4957149c81c8e0c7f3522e71cea4139c001370c3b186ccc792d9387be6a15d70960330485e2fee08a33382441e048a8f700b808749ad70954790d3df9cd7422018b808991e412934eb88dd4be7a93cd21cb53b64ce5a388857fd1aa2e0d81cd6ebf579df6b04b98b3e5af0b71fa41ffa2c702efacab93bde707ea6be426617ef69e7b24cb57e2d017f5dfda45a9472c3ce9692eac1e1ce54a19e994cd746448f62a49f4e5350d4b4d5260165b3adb30ffb122e80c77f41524a62ca4dd3383245597ed8209df4f3f21164fc52af848eb576b74351a66ec1b1756b32a5f7cb75e75071aa33e4493b734e48907de5c08439908809fa8c94c13fc61fd8306cfae0af5ee1c70a22fd802f19c61facabdd6f860c2688da90d3dc8c25e2a425cce654165cd605fab716c53b805b3133a91faad46c7be49100e7d282ef40fdb02036963e76c7c37969253f5faed9a710744a02eca3246dfe538b5679c26c824ffb8c1c432051a9769a54d2bb5207294138273d96482f85451e30989055a2c15cdec4892f1b166f94aa272d638e221f88d21b725ccc0c529af9d103fb50753bee457aa3ddbe081bab3f783098dd25825c77e8508e17f9a2301342e662cfcc6c2cfafb65675efee8ac70b16cd4c54c942b418de08755eba604feb86071d54468a86c2d9461e30154dfe930600a4ada9c790a5eca5149bd83a7e6f908d9a2567294c01a68d4972643bb24a498515cdd011a464f3f00314234e1a973013ff92fe9cdb9b73ab523cf8016a74c3270a54e12d90b8dc1c854b4c31363856229af481facb0ad924bad0d5bf1216a861036e3cc72ba02b9dd9c8b08bc1f3fde70c50e95553d0f713ba17d3c2130afa01eabd8785517c9d42aa4a749a486af548e3249a5da647fe993d5ee6ddb3e584c216f1c1dda8daca6f08ab11ede3cf95b37d9b670a6757109f59a85714f39fdb591ff1f27b5d18ee0e46b54d49b605c6050f8c1e1722166f31012815b9d852217d408e2acc1a65eb8136ed1164cbd9b800cef3a6e8ab605b0674971d7d81212b811ddf458e193c1b200ebb68cbf7e9a4efd85ce5dc1df4822f371ac8d87de1c50edff2d7b0142487c4e80c15be19bdd41e9fc44db54d8af1858bfd91ea61efe78cf70bac901e61a3a2566b84c22d70b411ea7f13a2123d44b4630e4093b0a8f69c27a3b0408fe211d8adc7495ee6736a5bc15c1430450ffa1825d98ecfd8666767cccc395db80eb73a0c458f12f561266a0c5e86a0ae821f0c9e4b2d8912475a6ca3a4d198d5f090afa35d3ebbf4ff3d6622a2f9ae0e88dc535d1dd6ed3e95c5b5b6af37c0dbeb6c3ffaae93b7abf4f0d8ea9862478552321eefa56aaa0339143443187dc27784ede7be1b21bde4ae6b9c2b2403e4867534ab986e1a5f13228ee2dc254c46f389438f4674382ca1b9ed074df24ccf35457588ddf232d097601f81f785ae48e072ae18c210ab849a17705acdba1248ec5944e38882133c9fd1cef880721f42e1ce3d418224e5a939e521fa683348a2f3bcf0b68a7d704839e0802f80cab2c08a9f66e0ed3f41d90ed42343290183bbc8459509da25a449ce9138ae75f472f2829b967e653b8192dc999643d23986efcbe943e5c002c3fe096763f8f567916ae3d8d420da06e3a28089a841c3bf733c8b8f3b92d9a8095b5ba57ca0ac77c289039922551a5ce18d88201962645ab6bfc6c725429e785fda55ac75f7ee88d65aedee347d7d9ecf6623a718d92b8bf6bdb99ad170d02e2764304cff40103a5e7efdce6ab7bb260d9189b28780e0a6a4d1985c33da5bddf78f9975926662a32b87fbf148124487919c0cebe2345c39fab52eb91e360b60565df4e72c76368f3a0c00f0eceea79d21ca063f616a7d4c2fc22c86dc6495bd38ec2b60cdb1589accba02a6b529806289c1fa71a3198dd8f568435e4c0337074c7bcd202389fe99708a0c1d50e87b2638e5cd24111d150124109ce84faaa5257c3507d21f424260e69471e436a18291772dc876165dc00f7b6786467967e10b9a34a6ef35fde96d4fd390443cb54c1db0b8b6bc2121f07592c7e56bc20f37d6cf9eaae60a573a3f1f71ae21bf8216936636d9a0c27408ef7bfcf5dc513d15626287f9f5cebea9d5466a76bc0d8ae5baba308be77b5275e1ae03635bc84b7355786d3e445721003cec06e50ea4611c144d7856726aaebb117755fccce70191339e48a648688b66723593d26ee17a7ab310121a7348a704bfe3509f900649b0989b1b22d46b9b9cdc7c24ac34bb166006de65f539da8796f2de48f30ecbcb4504b48faf4e4a7071bd0f7e9aa6033bd39341c19d48eeae48e6a26fb11efd571562555f8378898a9e583cad72df7b08e61dd9951b1e3a300353ddf7ed9572b215ef16f04d5d580aed2779688ca2b4cd915a27cfda66870df0fcf8b70db07995b7713be4b92a40e3d89445e3acd73a0bc0faa193ee8e98369230292288c123e1736ad1afd1dcf53ff688eeb4a9747211cb60fee46418c18d7f6cd72a4834b9ada4f1124dd1bc1825e413315cc97d069106e22e710ddc02ad5daf846165438868bcd206384abed87faaa602fed9c31f0d023d31625e21d580bc1ca611c80023bf14ab65b5ffde7ae71e5b300e526f85912b5c99143f2fd0cb890ed9139482642233740125717e4d19f0f9d03fff23df398c6f24c1367df887d2d35a3322e4dc4e3d1196cc81084eb2d656c10decaba80514c55a293c57da4e87d61e1227c952de12389ce2685049bcf8e97c7ef6b712a2ea83fc0d912e69f15de2b3a0cf29f10b54b2466f813fc2f3b7d8d100bdcc55e765ea281bc65f6dcab378ba722733d26bf39edb4f7c688835e8aee01b1f746337438f21a681c6298e977ef8e828f0e9393083982e5e3dd4e5cc5b791c8afc11ec03d92ada58592fd5ec734e1b711048cc89e84e4a5bdea206ca7a40baf4bf7f4bd7526e8006d6a5daffafb23fd3d183d740099396e8d72c546a022b8a0faa34f465bfb053bd88697e0b1e26023791b62c86ad5f8c965a4b87dd93a94e2cbe33b44e2bd3a253c6634cdf49c55c8f6e651c6ae576331070b87b03e7a71487423e2668ef14e0c72cf7ce6bd4fb8a2670b17f2b9fa5abc1b65451005b140fc728864f6be08e1abee857439635d7e1ca09fd6bf24fa982a04957789bba93957857144e215787c27cf5a5b3e4b6daefc02baa8f3cb8e3f7cbdf1a48bd45079337f3a16dbd98214242d98c54b0eab7a9481d45f8519f18f4ec034f02a530ad2907cf4f116d8b5c1c06b7f154a704753028b5771b693ea72ed798053284abef328e39d1801a86f9846f5e54d025dfea730412d2836e66315a4dba1cebfd835b0f7731ffc9a94b38f332a99385a1165a907e6a7b1be86cb8a56ad03fdacfb61361e2e5fa3f8e90d8030aa187f128a7e7a324494896a3d6a2c000e2486a5f2bd79669e189ed1315153a4db352323182e746810a4e3020a5e527a5920d0ba4a07890f1b57292c781a878e1efa21f004bb93155f579b486ebca6e4faba7265280a55e5d1c59c3a2385a871204045d2b905e1facf7d9cd8c02979470b5b43e504505a97b726e872c4b241b64df6267bef2da54c2905d2081d07eb06eb0282c160f8fcc6613095c36a9cc661360ea39eba012a79bd44984e13fbe954e8a7d780d36dc08d3bd36f8a3e2a79258967501f95679f7e7a2c43d975443294a547576fade252812b9ec89c21c588292f2e5fc8507d29ba6166339bf28b9697ab9735d0bd028a188ea042063364803175b1c1e2a5e98669420e4653c4b841933356b864174952d090022228f58be54a90112eb5cd261b5ad4a003164b4f7e70452ebe20d57ce921872b342c99414630db97a22f41da64296fb225d9fce2e463a4f4e64b0f1f529737704c8c115b7e20e20a227658638b19a1ed17cb1a31c44240460d35a8b2050686174b5ac8508d50c3c98325f517290c23defb450a0308335e599a98d1069525bad82207372c0963c977bf58d67022c600317868c287256c7084a4c5034edc600c2c6ce840868c6b6ad134466b2223d4e4458c33c6189ba62c91b27505c9e90a131e3ec61865047f919a96682ae243e7714197f9ea84738778716a1afa45a20195bde217090c1afc149d27615d9a83eb92e0ba32708b3b3bb1c5e940d7d5fe427b8b04705d605e1f762cd63d8b0486e8a37750f7703ff9389d531630c25236dfa3e72a658506f7e83770856c85cd3b4e014ddfc0e99b2a615dbe201ffda67e80b42602fbf519d83109f610cb843dc36473b52b71b1871d53da750e3b9665b3f06bddb7980168bff64792e8c32f57741f3a00190274020a222801bf7804f6ddc1ef87fcc2479f5309772643c7abf970b56b5936f78709a4c45a3cf887095cc6d5478fcd233a2f0f13c42aa57d97073b5fe9562787a52347a66d8b03e7c68dcaa686e64b791d8ad3b22963f3ee7a8f31c1f8020606139ffd6259030bd690fde84296e3817a3bf7941dd81fbb711eae326002068a5ca004122c50010a4c400211202224c80f041ee07a20fb83ab81ee1ec99e62f06840c9ab88315aa02589a71a9e94c028628271442c845f24306278d42f163664f0c0cbf480cb2ff172e4850a0fb8c8081e37382c60090c981520962c69726d16584c89c587148600383171c5186296b061145f882fb8f04274c18c590840bcc003a68b906ac9961f9ca881082f3630cae292577409925234e9f22ae32de1f9024ccd122f689012a9cb0c68e852f4059628562e5031a5ce0a890b165cb0f841097311538fe8e0c214768c5c0c55f0ac819a6f2a730d5c9621dbb8bb3431ca290b6c9f31c7c8115c90656a661314b22caefb5bb722fb10650b16d084cb135a88b40cfd226931e6c36d91b4c47210543fd0711065ad7baf3d8b7d41e8d6bb408399604c3630f1c054c4e48269055594695962f7342d61b494d172e6d93b14d3d116421df78bb4850e1e7b97f27e919660da2ff6d085164dba600ad2915d8491da6633c6d94511408091f10519c16c5a9879011767ccd50dbd8971b978c208284500e183d111aecc0a1f84b8c081964dc9851808f801898b2d52d8c024872ab85803072eb2d098e82c17411c8c070c174b38269e8061630a0f1822241fc268c2056830c1834b5241668a1329b794b121719183131e30db962f8c326d6ed922a6d3b4050b18b648d1644b121bb7c5086d3729b9c881346e20a30c1abed090658a32708873cb140d01544cf982058c2d2edcc09565f92ccb707065d99474f58bb44588061e89e266cf16b518a3cbe69a743419638c31664b6d38a1b34a19638c5146475a2a63da3037ce96bee834cda52c9c70d9ccb26c094bd046b79ba526b24c73396fa27c6189ca0d4b3ddcb0e424b654030c4b31264b2e34b992431818d21661bccdef1517c2f0b8ec86b445165b244d2d66523229bdd469ea82862d8c905666864ca80d2693e98c9492cb0c2f97cb0e413a2bca05089d262e4608e9c82d88403175d1019643520e4a538640c18e0e017b6389a00c4c2f4ab0c1040bb4b4a1e45a294a98220807585861428c1338b866145a3069d1c586ecf70a0d36e060c41443d731ed4c4a7a02f946d80756253a137779dd837dbd1284f439a682482f968812c56f94515624f2239b8931c6c81e237b5dbac92ae279ca539585ce3d57e25adfa20fab48eaf3edd6fee07c9d0ad96f2d8fd6f248813a282d474747c7b59c1ce951f3ccd9fbcda78747bc3803ba79b6552399d78111a95b0fdb85274bdf549ec52f177230faae489aae4e48b388cab28c86eec3aaa0325fd740890277731da83a339f991b99edd3a34722a8d4346dd623decbca1cc72a1dd35e8e4ea0f32ccb328f9e65994fcf22c72cdb54b6c9dfed51a1bbe965f1cc99e965e0d6cf531e753f1c0f343a6b5d56566f4362d0ed47a04b81296ceb1eb47bb46fef844a5ec70e45323afaf0a6275cb5561dee78f686e2db6f7a8b3afe95dcc68122f02059b1c3c7df2b2ca0c1873caf6535cc33df5bf5968e472d8b715a01c30e68cb4c1b64cc90c146186b30a991c553146934810612671051c6056478d04115426654d1c4690739380307636e00668c176568414696319e10938418556c10a5063d84c1010c15317ca1e215461a4d38a0410dc0e8e2658b2e547c81e4851117239882e882055c3cd932c50c4b53bcb0851a5a9cb41043098c2cb66061c51558ac98411530a062ca142dc8a28314596888220b0c0a36927480658c2b4d485d1c61f104144e5869e2082b4330f1c30c869690c20623299828d1461265645006125f8ee0120325184851e484113228824a1520a8ac8088286e18228a981067a6a021e506418479c11751b40031850b8e7e5082a88816bcc007282c7002050a197a80c285153cf19083211bece04587a51caa7872c5c9123814dd2045c8071b72a821298886a425416bcc60860c6262a0418c8b26573049828109580c9608f10211bbb003bfb0d470060b0c3b30d306193364b011c61a4c6a64f114451a4da081c41944947101191e747045c88c2b4d9c769083337030e60660c678518616646419e30931498851c506516ad00317c60918a419be202d09838d26323428030c305ebee8b2c517557881850b134c4774410417406ce961c9c916473368395aa2051b4a64b228030b30577c61c51655544105962998c872841444440104143d2439c132c39527962039c1c6b647641c504603c030e08b056c3142153fb02880091f47f810d103448f1e4470920027664080134b0ec0060f1903945100303cbee80658aff16c54946fc81998e40c7406ca5206caae651cb73c6ca4c66a44218f61d69b9b322d66d3db8b975a0b41fdc35924511a8ed7e1f0b67b7a5940ddc797ce462fb3fcfab2b6fc72597a152835f7d1790b69b88a593adc1828fb0ee04325cf2aa2b93a97d2551654e042d58d3b2a4fc6e8cd0d6f712079cd9b736e47bc5fc7e9569e08c2d5af744dc6e832aee661f4385ffeeb350d49e4071233f0e6c8ead771a47e76573974782896b7dd1336a1ecdd4abe4b719be6dacb1aaef0b16e4d802858aef613a20f2b5616099d7b6e02fbd6166a0b558aac7365712d708ef20c5533eaa15035a39d47e73ed041a06d66d49315a88b957d1d483b492bdd64ae3c3ebc453bf36d7d34cf2aa5e139819979c721dde28e719374f6eca1e3206ae2eb237368c3bfdeecc346bc137de5fca2e4259cba277e7436da1ff2236bf1718a8f481f25f8fd04795ae9569c958dba158fba47745815ee150844d03da192230d86ebd44d15502814474351138adbe9c56621253eb2829938cc0f441f39e92377f91879ccc79eb38bcdfdcd4dfaad6a20084470a45b71720dcbbc34291ba55b2c2b13758ba7343333333333b350c84f9e8738a64d6769d50727a00d880089121ff9a0830f77a96b3a03061f6e1311d3873b669dd6cc67933d7e1251ccccccccbcae08ee73ccccccbc2e5ab7cdb27151a6c447b2fd8aef9fdd6907bfef983223c1958bd8a8fd044a99281365a24c340a5319a2f2ed1bfd2c4af6b34ef9468169c5449928d3fc13e24e6fcb74f4e5896ca16ef550f768875589b285d8b55aad562b28fc8a69502243f647dc30be974b832c7625cfeb730e41f9f60d28eeb4d315f5f527707faea2cfbabcbb5df10c2a2b953db3687a8f9b384cb778c150fec854ea27e32ccbb22c3a7f34f2de53ab6ea57e72584a29252b758bbb36eaa3ee31d4569850da4743d1a78de20efbb692f2de4635e3a5f6612bcd4d2c8673e6a45f0fb90b950f759e9d9d3b94b3d3e736fa689ca666b4c6a533a5714ae3bc19a52e5328f7c0ce67cad358d3344d5bed0b55f02c22dfafb7f0dcb72fbb058351d7ee9a0a63222c5870a14c2b283736ead67a7b19d8dff59367ef36d6b6511d9e058c11e1f9689b72a87b427622ea9eb099a030c728377e9914da41b1e8c34fb43ef153b7b80b76ea9eb08dca748f33962b9280817a68448d5c407a59434a6337d1f427c595324cbf577218fa2a7eaf3cb9e269f7ac24958f9ef4312cc1ebf57a24ab0d53df1eaa4648ad01dac39ab82d21f267366b187dba8cbffdd1a74b598d44976f244ee9dbfec878b68c5176acab6e75f6852af814f80c5d491b7431dcf1d1bb18638c31c618638c317af4f2d16b79c8e3ade8c3b33b0c444ecde9eeb0b7db6e6b5bcce3f4654da104dea7c0c2d655cae63add8a5b8db19d9b852610fc1d8d0f8ff4283df3303a4fb77cf07c471fdd13ebb6511a630d7d3028c212ea4f048597ce23828f9fc8aed05f56ef562fd1906795da7d2ca07b1a28fa544ae5b6ad5631e371f262c6cfca53330adba626613e4e16741850e292be3a610ba541c165d6b69d0354a9806758b7989b1d56659bbd157d380f97c9739e671fd3c3551213590c77ed58ed977fbf607275bac55bbd5badeee165529e03e9e8755cd7aeab12319218a27ec52225dc690c2d455a77ac7bd8fbc5de30eed773f4d9b620df6fcbe3052a37900584725609eb42b14c28e3e23c3ed1f5dd2f4dafd7cb0511804ca07bf6ca93186ea72b340cf1e18e67ef6586990f7d3ca721f4e1263d7fec653163ba67bba4a603e9059d9e1d0896c136d72eb02e39a65bec281e5672a1c075712e6d5d135c97f4b8c3ec54594cb7d8cbd0f590c53cbb6c214e49ec940bd3bbf58d47e81785354cbe421e168b2b8b041a4fb909527aaab650a5487459e32d48a7a9accdd7457d5dce94f3ccb76634e5ed4c394fc2f9e46a46699c7d036bc02deec8178d3e49ba1a6e2ba65bf6b4d58ca62a8c95b05401fbae49682a8c938ae8f25c9f687c573460923334dca7247107745d2c9447322e56117e20003890ee92ec8ffd1c56916e515895ad0275eb84ee311d5625db3cb641c3cdf5c1f4908b6e78c8461eb8e3f090a780ebf2005cd707e0ba6ef0449fa30f7df06c35734efdb0406155b29aa45bf3d53da6c7325600d16c22d064e0f4adf300a4f10fc09477554a58170c06e9340e43f4940ecfe15d7b710dca67e8229161e5b904e18a59a431a6fcf423ddb35ffcf4242c744f7bf1a1f7e18af9e1893e730352ca76c50665f73c0059fe0198e39cf21c00297895855a83f2f749d4a0ece13efda490b90a9977f5878b4f94674483c65741aac0425520568e6f1ed3a0d9ca75380c87e770168ad3bba87bb49fceafe8137d26e9664ac8f74068d09e2c07809f90e31ef8a6803e70209dd3ad9924ee4cf70000f10cea2b16108b95e39b6201d1f87e9158c69572209d03b6103de52cb0852a99b720592448a7f122d2693cab45a2a77480359e43e538401bbf017e8e03de380796b02e184ce5350eb371ea1bc802a271132219576a03f771c0aa57f4a9f1d9b2f1307ad7811cdbb418ebdca277956328d05135e5116421304cf58b35b08554600f11417ba2266a4e39048d60bfba35dd06ec58f7982e85a01d349d9f744fe61a43f9a867947e2004ba15eb9e20f99d7377d3a1c08dbba3ec6678a4db3a701504f57e76dec5546a7a9285407ed2adf9b2726ccaf6440e710f6d50e4567779a0fcc8cd7bb7a6e7ec0fe965bc0af355981fae829647f6b385b81eea28ddb356ba67939a0cfdec24e904a52889c90e1ff69424189c3e6c2404f0611bf55167f9195f0d9342437ee22736d33d5ce5b9d342dd9a41d0f9bbe3c44253ba0789eed9a4185e3fadfc9caf273f857a68e24326cae143a6d2fa18c766cae91eef27cdfa49b7a66b200771ac5bf305346ca19f2dd44fba477693d7383390bba969804ed26e7db9ce3d5f77ea283482ccb4a0e8f57295d02ecddb9565d974144480845f1cc4b0671e7a06ea9eb075c29422cc2e0fe47667862878e9dbee4c6e4312d4fcf6d2b51005cf7d8c523487800f8fc673c4136efe28f0b65d31a50985d8359ba2eb98e6780ebda1316021e14f81dbf737faf852a3677fe2b786dba7d0458f242581edb7be1adddc6fcdaf93e9d699c31ddf3f59734a66666666669e729989f4af948cddb37ede24e2ead7b5dea23cc2cdebd75b2a40d95651f2cc6086cf8062dc2323965260d90350f4d96626b7976dc5113febd64424a3bb977ad4ba374fae606b8fde701bc72551bdac5256e89132b6cb27220a3cb76cdb7cbbd5bee0b66ddb46a6dd8405b4758eaa30263e5c9bc73657e75c8d6daecddb35504a5751be8125f8a1d5dddc0892fe293d0172f315b81e2963bb09711b217a28a5942af0cb5022e997b2c90ac4711b4fd673876edbe597567e4366a38da726354df329e5265b618d60a7691ebd37af86de9aced33c5bf5c9583a4bcf6a53364697e2dddddedd8d28c92bb9d9196b3434fb83d3be6f7f6c5b2ab53f34ce4375df3f668742ed0fe971dcfe88fca33f4ddb1f9cb1b6bbbbdbe4e4e6756b7779c418638c5d7bbcbbadefae67d43177cdf2586fe61f4b97c7fa0e94dd4bc73088810cee599498927e3a1fc5952b574e202d7f62c661ba9589f975219ea770103fe65ff04c25d564eb795efa78b9478faaa10fae863c5b0d5bbe3b4b7977d6a52fc7d9104fb10f371dc23c21a5c1f4e196b403ecdbb76debed65ecfb48f4dee69c53ca29b9656403f8047fa2b34709eec7f56e6725d3e79c60eaa7a54b279b14369497b0a0276c26f6152b6483df1a4470c17c79eaf4f46a319ca5959ae928b2c441da40c3d5778eeb70be5fa45f2e94d3e8a36d9c6f208c890f1757358f6d2e54ad89f9706d8e02614c36d7e6311f2ece37d732df402d85241fd310a3bd09685efa4c41fb588d48fa9b92c08af15ba5b0a2b3b047ae15325f41936e423c73a63d7ae6ccda0aa479ac25ac4bab2638c095551ed951a9ebf606879bfd8cfc6008fe6629f0991e3aad671c8286b4bbe99ef6b857dd73236b183d3b72f3bb483f9d594478a1f84dfabd12176877d6c7765479b89b21bc4eddd1ad059f6974f7e22c5a59030db76f4f43292bd22f5786c6131a4edf37dfd1671a999e811a4bd620fcebeb8af9704ddf623caeb979066abeb1966b3aa782c85fd7c098bba6772ac88cad5cd3a96baec736d7fcad2788bfce09e0b74a5941c633677acf9c714d4e99e000d7acb123155d7bcba6800358ea4099e9d7957ebd6354778c613cae3b07ca2e66bd7b47a662e64596393abf3b34ba3443b2ed7ccc4c6a716be7c856c4ade3a4134dc8f79ab779d15b082abf9b4564bef455e137cd47dc598fb1b678648c314a2957db9cf3505d2bbb41a93a1baf26453f1aeea3a91acfa65339ea86bbb1e1b477383c6ea501a0b2d5cc21754416770e00bc1682d26f67f6e04665534369be1b13c5d2b7f5d95cd650d26ca58c52464a1337aecb4d04dd5af78f59966535c66da374d79733964f28fb4eaf9df298464fa57ea4b71074e79b5f7b47e375d4eb1ae9c4b3f1240e945d08caaf9a325b1691ef336fe19be316e90270688d352dd3328e919fa78422c9c9130846c082638c91234bba92975595ea66cd7783e2a8210f75eb460d99cadb30d1b3d0fc8e535f0d79ca53af86dbaa55394642649c96527436ceb7bdbbbbbbbbbbbbbb3d1707eeeec42a456b77f66fa1c8a55b9d9f39356dc1a985f03af595c0d7c05066f97547e1b5b872e5ca385ff36e4ae7f9d2e5c69571576efd186594ab2e282a05691ee7a120379d15e7b594e0facd86eabc2591f8d2e5166f7873e2c091fa91db2b97c7caa681b6afdcb42a645f465623f1ab19b1905394abb443d3366ee5c7222243156851025a6b5a6d62ead6ba8c49213944c44cd79db6f8f42b5fbfde32e8a3c75d975b1ff5d1a0a857e375356067e3c5f9793246d9434a8364fed2a47eb686f6d649e9606c958dbc91a44853faf57886b2ef114de9a3dfa47ea2bb744dfb4cc6df2ce355c83e51f7b06a7c3f07160b7aa20d6950b428ffb2427b684af718754f8e7f43218ad2546a7c7a23d13da0cf2e2727870e00f88d1ab6fe0696a4289ff38b2529b663eb3ceff32e45c2ba8454168478caf300cca99d83600df9dd6bc00f87cb2738700c1180872d86f38d5c0d914ca983d7a58454f79a9aefabf1cf5132cb54da6981c0a954dce72a558ddc0d68246709f011e0c639957f04e06c3c871bc04d8e0fc0e6f32e47e561d77d5dd775aa6ac4c673bcfbbe1ae270dce79ceae36c543554f22ae7c00fc76f38bff91c48fc705404903af008378e63b3fdd0e338921e80ab6c5ca5b2a9463eef5c35000f5bccab70542ad5ea55dedd70df4e0b849ccfb96ae35f65e5388eabbc873e58d1af86dfa772ee73eee6e31c47e5b5fa9712b2c3bf6ae4f31b4fed50ed50712ad50e8f5379c7a9a8efea0354ea07c70d9863f3e1d40fc70900e27021e0101f00280007122b8e03e9a9147db4d74e0db7560d29081504ef2ab8dfedb4fcdba9463807c1bf160ec7f97ca38f90afe250ff9cf38f56239de3f0cf6bc8bc292238fcc3517db328ee4cffaa7f39fed9f877e31f08adfa71de5516088ee3ad1e0a400d5721549dfa398e8e87d0d2711cc7e1434001805bb702503f0f01c7359d103ceb211d9f9f878043c73fd0f1954e0d914c8ac367ea07c707420068e738bce6d8dca8aa83fb1e80fcdb3e352de66bbc9ba28f10afa9f19c1a9742208eca6b7cf372b84dea4787e3e0b80d18a74aa57221fbaaaaf2b087becf394e05869fe3e0f09b0e54f21cd84a3738701c48dcbe533575a91c7a1cb087a0804dd4ad284531635ab987dbac2bff6a8d03691cb0c66d40f71ebae11fd415adaccf877810dfd4578b04f1219505211ec481740a4848f5b873e30698c383fc0a04007b39e006e99c05eae87280db1301d7c5a91c4aaef27076f9e91d11301bc2a9d9d0e7b273f99df77957989866516cbd44ed9523876fea4787cb9405361d392413aa3a97a404f19931c59de9416af77911dc9741d0e8a16249312b37bc9333a0e1542202ae4ba632a62e68e79fcfa2ae6647df8e70824d89fd7182d5dff0e9b24822b10b30ea1e29317709f1e9b28b6c8a3e62e498f619e2d3a595f6c998b6a4ed333156fcd24f1f02cea5dec1f14ec9775f0df9bf31f255aa1a1e59a7ff1cc7bb0fc401a7d212f4f3b934e66f523f5ced212934cc86549053a97b707cfa5c9a4c9d96fac1a94b3ff7521350f25f3db24ecfb9979200874394299ef3cca85b99956ee180f239c5551691ce3fefaab74e9f41d93629423c638a3e5329ee4cdf36a6a99431fd74216066a5776cbccb8eba4755a7f32b07caaf230c5381d951666444551e66466fe5f5db46e96ae5de6af1f0843e32d87f2a30f39ccf9bcf43fa37e1f6378e7303e7068e87dbdfb8c1f11bab550d9540d930fff9b63e6f1c9c1a6ee0399d46e1b9af6643ddaa199478030cf7e8c31e0afbe9a75166a57b8e54367569e7dd1186fde75d4a025a93191bfeb3f92a8b488d7f5e536fea0818f619946e4daa040db3a1d6b634cf86c222fff9ec3c8372c254eae68a06017777348e9b9e0d754f573f24f43b4779369441e99e0fec162c0f16ac01a67b600f4526682889fe05417cba249251f6c7e70c88b584f8e91bc44349c44f96563be8a504a94212889eb9fc942783a09e2793a0df1de1113af633082a3b9a8e4b69dae728a72112126be69de41a8dcfd04d6af2f4fc610f85f2e9678f37e4f4dc51a246d4517a4a53e13c19046d1e96c7f40ee5c92028bf0a72f38eb44f248a3bd38d603f63d14f0fd7cc4f0efae9b208ca42de5051f7682f0d4613e57efcf8634a1e41b598f6e278a0de5cea47d6f0f56a23f9621904c95c7ad3169b1a4a0f2d0f24e85c2a8a3eda2bee4cd75e45d228fac823ed258fa093a94ea56ec91828713c34452568d8438ff21ecea787dea7422f886bafe813a4f6d0e7e1e63db4814db4d526ea566b6aaf9faebdba87e68766aba17c204da379e71dd82f355ed623de7328aec67e3a951e89b6ad7214566523ea1e3dd4446ca55b737f445ed2430c6579c0804a8fd3374dc937371124836e31cb78d3ada6dd5a758f5e974350eed11ec18d015dd76a78f39a6772799dab918e713fdbbacdb94d62803a939be4e4d4a4945cc6c33b34ad86dacdacb21e75abc518375583a2a19eec618cedcd396736b329abb0cf7cbd5eaf29ae95b2f5bb3eecb28fbc58f929a56ca7a08fb59df06806ca4e11991f41299b4b50a68870d2cb407e6dd2e859ea47ca6df14cc14c1199dbaa5b4cd9b5d44f74af5b7dd3ada64cd005b7b9ad29564e6f47f74cefd64a0c6d025a1f7ee5b40f905596759ee695087447a8f34dd42d2928bf348d5f1abf347e014911f1cfb214117f59e56a15a2e01f2b17655192628875d9212809aa43719b96ed8fa9c92d728de26e3b94f7854a9eae5cb60f4cf3adc2d225f784ca99fa99724a97d55382ab98de713f29efce5c59574a8fe9aaaeba35a74b233e1f1bcd6511b48bd1f3a9dd7cc8b1cd3defa274063fefba0c2871d9f8a67e6cf83d90bfdbc0ce51a0e71f189d7ff3c8f4f34dfdd048b087605568a86f2a763f41254183aac438a8773c9087ba05850a0dbd0f575e0bb5d04b5608746ba6b4180b059a87a8444c98ea92183a453310005000a315003028140c888482a1681c06a1e80714800d7f9848664c18ca42410ca32086612080611888070c3000186208310619910ed8f0379f59f998d5b7164ca938dfd7317edac6224b6e096ee7a30d3571dcce8f71cedecc298d0d5f1b990ab3f64773b37e134ac12c507d232c9faed2ea08b885d9dba1f44c21675c2f50f999d2c570a0f56763a88214d3c5fe106ab04c62ef395af78ed48ec8245439337f7188eb14834085207579ba18408874b1f2d9804721e44168b9feb180829b502e357042a86727f13a659acf18f0ba8a1f8aea7c91629526c041ea38ad420c603dee4cdeeea2bfd93709c1753e77f25b8d8fce2b9e082fba6aa5529b3c77a2028788d60bb830d84f56a2d13ab3c08ee478ffb9d3d690c93376a7e4ee50380912c24bd6886cb5811384a9dc05e4bae5c57a6892dff4e5a43d2fbe421638b410d0fa71a62aeb4a980bb0f3830ab4438bddc95ab9c32ae00dd963cf0d9e0fb0b02575c16277722ad8a0d7092fbd7d93f1978942d4f865486891207253d43590bc53f6f3eb65118c62b8acf123b64aa731617e71970f81e1ec6a0c8172cfd2115533d47f8a8ef9336f0eb04a03a66e2363b4079afc986fefa41443369dcd1b611276ea807d197452c12d019e40d257bc78b4da47edac4490c209d1d8c506782a22f8d259b86c8e45035fb166161fbd58a13780eae1cbcb85734015a655bc508f0641aad8a83a977b325dbacaf47a5f523fe625104f45e898e899e3674121d434692e0591b8645f4e0df0f55baa6cf7625738d35b959ac071fda924af116ca36a742a69f6b359a096da786aa51e4fa4a239424595caaa547f5f6a375369f5c732424ae2aa25cf4ebdeb44f05a45cffe227a68536aef72b17d80bf294f1c9c1dbf0ae0e919a7c271ca10d4dedc639a27097454346809a5d4066e77b26f177f0a6a8a737d3d0d5855991348d2135ad1b94dd2934f37077b421eb84d61978ac830dff8c4b00669ec33669c2231b1e233dc2835f58c4cd3c852e20098f9fbe505cc255f5fcc6f536a827bc3fdd2a4a7b1265845ec6679d2d36e44c94ca792cc53f958a8defaf985629fcc1b2fa9c2646cd0bdbc49408055ee5d67ac82bf58cd3ea1fa233d2dd2db9905aa4eb2e98e0e2e64a38c3293748c35f76b659a0b75a3774d2d4273b349643b95ea48909f1ecc81d8ed754c52e7edf0d1d71038e16ae4c4c8fea6f5820975920ca1781e7bb98a63684842b8088dd16dcd86425824b948095f6776750157e52d5fc92882300b58f6c5f99655205b3af79b3eb651362589bebd05a64432cf4f147f0e3c2e0a910ab6ef849af8f727c79692cb7526367c58eb2613e2db0bef5f291fe323ca7a02be14d1050d5e83444750db0fc0e7f8acb1af95217aa958c88686ac1b61010b1ffdbe851011ae19a1f755708ef0a9e8dacd87c0d723b5377e716114ddc7ebbaf2f1b279628a1970c40a2b5205dafde3f072fa0bbdcffca80316c5b0a10415ebe321e9907333595a751778ed7993512ed8a11271838b69bac7f0290f807bd0565160119d11355ffcfdb51a4f051191d3197fbb83217298a60527b3a4cc6a2f4a36ec4583fc9e2c312c2bea52c1833dd8815303fbecffa870d39c6f9e63ff047cf8394811080bd67cfd62aaa45c459679dbb5608368303cfa630118c6779f722b352ae5f670a496683cb1b1085da8689aaf1a30b3604253addc6dc3f343a67416a12074c6a07305ff2de365824d54cc809524f2ee23a967b813e8d9f8f2df13754eb63156685fe199dd9207d6328f04e312df8a084ee35f32698b906f55a63304a2d35e11ca91ef60905bd3c1467c5424f0df644a8a87e1e32257f7784cb5e5c038d443a6ed8097114a360a730892b69288059865a10cc2265d2b121671ccd14a286e6e442342728d72702d0508737f6b320d83d38d08c7b3a2f4ac02bf7d029152c5b12a7c956e98448fbabd664c67f1f667a658dd073c6e3e418d95c590084526775211a2a8f644d72ff4e3c58ea08d0099f2703e746a73afe35e4ed0508ebbdb401f661cc78433c43e6505f99e4f2661b8947316d76efac529a9054d29f9519976a5efc87140abb8effc224e22d78ca0d66e3781f2639961307df5a6ec801687a2e08addaea1370144cfc270de6b9313acf9ba27e3b04330193261b6da0c0bef4cbd7c939dae9ce38bbba0249ee9003e8d8ac25a2d848851353fcf3d2df1e52d8ad0c4846427e674ca9906dc8378bd588485a4c11530e61b8a49552e1a8fc967894a0be8c2f6d13944f51a2e13817c905b41bc34e05db54c6b213f9e1823652dcd3d69f4cfd9738a26b94b75d71f4963633e6cfb26d3bc9ecf61727371f40d73032aabc25f3dd14ba26a90f4f187cdd29253e7e1a6786af14455fd61267d8130d789933fa94b529061d149e367ced846bdd2482f1a85b8ffcc26b4cbcfc74c034630b1d8375e74dd10f69d347c5c4a8bf927754a9caf5dead639802ce1c645ee6c57dc03b59f454ddd4aba98681a7c47fdeac1798be9fa30afff961e10ba74e36dd822338705d5e9bb7096632ba9375720d675d12c96f6935a7044f5a5b2a64b9392e9a02b23866ff2c00298198a50e34c97fd2b2819a8d699f07ccfdfdc868481ec89d2f08b37cf010299c07b17889d83148ecc59f2c9b95f6c217f87cd9e0cfc29078588bc0e5193c51c08700022d3f595314a7e194a78865ef60e6b2996b7a298688b64c3640a000cee243e6f4ca12472f7ff8b014ece5598b6f01af89e29a4dd2389c4255801ac6afff01028157f455a66c40ba31e762ca502b63b7ac7a7aef3c4973b2c2e0cdf02044f2c57f8a9a384ee7bd75d111ddbcc5a6cb8cd5d37e660ab8fbf6b52518b9b475ebb5259f8e587646894e6e0be6990d28fe9471afc36cd6fe0d12368133907a1c724212e2e66eb128fa64748c4136518ebd486488139226f3eb4b1cf1ba7541a6480004d4ed3ca081432e941e69d718bbaa83722984e7cca6d00bcae6fd65b7622686f43019e4336e12a8099895be0389b963cf3af98d8135ea8ec08a807630965610bdba09ea4ced740de11f950bf07d283cf27ddcbf94323a95027d1cb15d57d0e5e2260ea13890c7ae84dfab9e5fc4dc5b1c7e48f18fe568f41d3821eea64667aa2832a9c3aa192dd005223c23a4cb8ff4378e7d5cf27a074e06660b6c90c2c388e974505fb5edaa0b312d70c556242508907c5ac04b05e7ba8feb5289c6ed480d4cbf5e053719643ee4ffd3fe6c2336da8bc9b1b09463442b3490de610630282bdf0e636432c62456d822546194d8f13060327d6f4f048dc35a7c8e63403a2058ff5bdaa2789e96c583a30951ec8d0cbbc174de40caa104775a20e790cfb1c796b007170455ced6fca2a9eb73c8b649230798f05beaa0e9507746d31f2239a1714dea2272bc598496ae029886db3cd5f2f9a8e4984ed6a12f58c24d3c013910b613c24b9ca93c0b7bdb2b0926ed74f996f6815d2c757fbfc8d96e3e856c7363ec3b3af5a131d3e79448b223f6b74f1ccd207d492674cc4d3207bd380c938214b20e0edc36d7b234d23606e73297f0473c38ff28aa7c40879a384d345ca2852891f811a197c118147ac5b73b06fa077651d33551140151b73b2049a50960d901a4a37b0257912c44b12178f0a7d0a46ff8d8c6684410f7be083caf794505e5e843cd7fc8158163eaafcb9fda93574128feeeb3c4b993b9c04986e6c4d03d2a16a59f15bea8afb431d0142f20e3ecb1ef1f9c116661e44cb7562cbb99b852abb726f43c75ab38e85e6822351308f0000678107b7241f65d0395b183acff6813f89076710067878579e77121a4ed0bbbff4df515e01abdd26bcbd16ce502623c392a200b387bc15b0e22f169d518c3186db94d7fa6e617f613ace3207462307ccc257968a2e20ee4585098761985759b2202f28942f72288ec0bd0ac617c27676f9fcd122311339bf90a625fe950d7a701c216a0de66746288508c0fbfac8c9b956768655565cf03141c84d5604c88fcc77afbeab5b08936a91891308e85f616be37f6fa3a6d86aa135485c867bf161c4f5ff0cfa23ee9bea11b6496f518a5a1451d72876107a0c1863624de29d045712d949b03e12d8c79deed0c8ab8b92b0964e7ab8347f70230e938fb6023f657bc441e968b3d2e75bc5f6f3b51442e555c987ffb27ef41104d2ff545620c53164d10611456ff2acbab125ee4465ab14a2b7fbede47eaaed226c78f2e18ddf7350c46490c2922b393145ba5152f6d68413749fca81d6b8cc3c592a20ac0694bc6316dc65dafc8d3e58e7235ecde82ee9aef49bb9e9403e2eb25db2197858782335e651c69211e6e8b5f39fd9cf02734a189912d841eb0b20015641c01916a373781ddbb4fe0ebfa0300e5caff59c05d4b3118dfdbc7389c7c53862151d83cbabd510a2d806de6cc0b3c0cddd6a953614f723106123c8e432563595991f620d04113fb5655b9061510874f9b806daea472e981655ccecebd260062e95504e723a873e64ccb40342e163470baa14cd453044c776294d9cf597ebf1c7ac8fabb946b4d37dc19e40afb00e8a2f2c15e770027beb3a785bfe074ef892a9ef4951ef3f58cba52ba1924ef79cd485a08bc6272528402009ebb883ea22c058d8fd7b303af6e46bc285adbdd725bc5273b79c07a869732ee39e5091a23a39a64af3f59ba48a1533a138ad7127c56e408fd780de6166daec1702e1a77fae46cfab8f7af3fa60e368f5951bee782f723a08b188e861e9718ce52a6aa3f4d0e9a2b2704174223863390141d162ec7943338e02e0bff75762f60bb8c3ccd627e02e6d2887e7df71c6f315d24b3f651e8c5e9f5a1cc6454cfb105b4e72ccf8a97a3483499fdbe7bdace0d3057fece4084ea4fa434d700ab0116bcb35734d48a37008de50ee0c3ebc5055b3491e12ff2c8f39e05ccd049128f29329bd4995d0b22d1bcf1ae3893317f37b669ea74adc31f904e1900d1e4ba20b1349d1d8c890b25c86d01a1503869d134f0ba5896742f3bb73cbac47acf11fc188346b6d0363338dc191ec5c9ceaf1c21ad9f418168e02345cb04660cd483b9f9b9e5816e77b5e18af879f6dd4e2b54e020d50fe56b81532621cb27b7540420acbd59c3489da819dbd12540e6e5709b86e4f709d2083b3fae200e764cab005010e76ab70b939a6e8fd7ef53ea37ee52adc43fdb6d7a8fc3f05cfcc9871167354022c0ae8f4b0bb107b093a9dd0ee1f6e737786aade9408603cc775fe2a69b51725bf3994ae31dcc9dce05a65f44ae7088cd5f381f108b135c7bd46a877958b3b8aaeba923b52f8d0421b785fcd7708d9c764e20e68f46a98b7453cff4bdfee88b0e47b3c8f693183c1177540fc5320628ac9971c0a53bd4e70f39b4788ef810d4d93030e5a4d82aeac33dd4d16a8b99733d27407b517f1b61b2e4271c847d847af28b8f6d2f7a007957f85eed73f1a948e2c1736ea89938af5a2cf25d39d88d38decb911d3cc70d488b781c0a487837f7df5b63855a4ec18e0022ccb1aa2b8b47c4cfa8c1b71701399ada2b9014a8acd880ee4006504a247d04c69273d5b23dd2df8c951106cbffba053068232c25004749233b8f449b593b77485429e400810e80d42449333db1b4b31cf0784b2856109ad6520cc04ba07018eb986c6c2afe71fc75eed3ff6e607b2cf87196148842bb34e8b4bc75eca2c73dab339ffc00ff1f19b608f345289a4f60e28e9e896fc6b7fa236986253c04d818e3313d5389e0e692babed1ee01d26039f660cb17a501da336e67f9ef3889f776cd066418c3c4260fddaf108967dda33974f9adaf19f2b315f7f91ee3157c4d9e1a9c83b88a8611e84685af5f39c51dae92d9aac15d9c903a11f9c33a76afd19f9cd899febb40ad0ff06a430679e334a7f3f85ea1323910e578ddb9d83f289c72c972f41d92b03aa2dd06419ffced08f558483aa8f18a8e0ca25505715427ac20556524cccea3fd03ef99ae3493a0b474b352ac78cb183205bc1696d6912021e9a8f6e168900875dc0b88034e09eec0f28ed6657302826782e7ff76d31c74ad33386ac1823c480178290e66e757781a5d808c47f99ab8b4518548ad113162135e636ba6536f70539e548080cda5079b80e1647d66ddece207a4382e4bc7d2ff6ec888fbe8001a6bf35c19c819ea3780a6633867ea5fe204450937a81f4f735560ac28c9639cf059e7b2be623019f5bf1bd263e9bac862dca4731a50ea0d04180cd846560fa2e274b60c5398f310b5446cd95c61d652860679e5b71fb4501be5cd3dfdf6e162a898ca36e54f6375a7dc5212f17e76719f995e75fdc7ba21fb0c927c67ef19d2aae1ed41e38d8b6033cec050efe1db799cb8e3e8f73d6580e25963ba80d96acee690ffb0c8ca28d474814b3e04442d4ee2d70ba2b55b384a035d2b2785edcb154ff2063cc59c9016c6b3e10862e3644db2297561aeb6a0e1427e1b9dc5d57e27d422448d100cddb6d8221b8db381ea8511caeba8bfc26ae3b85418cea9101ce145d498204d22a3d0df72ae62bb418d03c3f07802c3b4554faa624c2db9feaecb28da0856eba92159e4938b17536593ba0b6359746579795b02b0ca729af97f05387472b91e360073d2cc8797939e0cedcefbea686de7a9fb49ebb4f46e4e40b8ccbf9ecb5ffa6678e56789d3900c7e10c1692c9ec36105de27198c99c7c5eb092671aad255ca420e24afb6e65190ce9601d953caf9e7a06e61d393ddc3438654f71660b581ad7c0fcbcbd4c135ef36b11bb96ae18267d57a4a0cc84da6ff0a80bf1d1e378c69e04071d0747b34d2444da531f2f5052f75ee17303bb4f9dfe14fa349d4801f52a1bf0d8c7c3128f77125b80768540d3f7a75905849b9343829175479bbc5fd37d4aad4173d054e535d2450918c3550de8d80795c97cba29507830d1ea9713856519da670d15578263d01a3aef86ec3884bac329c34427305a9b390a8f4b4a44cfdfff9c9cd654680099ab4f95a02908169b6f01133a90aff998e148196eee90b4262c1f99f806e73d5934a1ced1e86bcd99bf3697e390f81d9c7aa02cdf7bf63a5d13ef1f5b3a5563314c356fdad712e3b87a71e1546afadb5476a0b3f775c9b5dc9c8f1fabc78e28b920cfc93d1c0398fd3b04010207c1ef84952809fcf922588c646d753709ec0d621ea19909f0d9d328ae59e14f52b7827611330ce835b90ccce645fcde3fbeb64da5a925c4c21ac91c0adf29acc4990714a335a62299e00f4c8010c14e066c9951525ecb099e14c943630b48f7296a6f7d92047f48c2237b090383e45142cb38d131cd9ea61c7b3376b540386382911b2801205b000adebfde7093a0ee03f3f8a7ea299f818d7755c1cb6b222d38919230dfca25befb061503c62cd44ad1c2be80828ef7b8305cd5d53f7dbc7360c2ffa2e960a200ba6f75c198323a1824fe19beee1dfadd9b3f98ee9643ab11584ae3be6a1570a86f698aa5566f7f82006844e89d1655bd7341831219333e7360963804ac4b74be7d4de7deda9c9076422944c2b38896bdc319cd8038a6deb15619732ef5fce1bc2ecc87f1c146bfa3a7730c52111470723243351f58337fd03b20c49e65ac3a27b71e4562aaab2e36898d759ce52efea296779945fd184f451509204750192a24fba2d802254afeab99f6692b4d8bc82201904d4426f0d1ed08d491682d6babf6b9eae17b91912d648a390ddb4ba7a66ef90c9c11fdd990ad54fe1a408c45ebea1652a62a4175257c2693b89963e401e02fd89d1d28c77589ed1d47c63abbbc8981bbed12aeb85e38468189d9e681c15dc2172dccc0e0cecb821f7e46713fd7640f9c48bd9dd0bbae6b421f9b61290fea07c3b6b67d8485113be0780179fcc614fee5ecafd9fcac0978c0c02f0a21378b6702180d8763b46e3f5238a0241c4ab8db8566e6bf2da2fcf1737de5c7edf192264885d81950e6e3826a044cb970e2f994a620083e817cad7dced05d7c920e3fa8358a47937a8562b288b19f3e28540c941e41e37d9220b6362cb363dc46630cbbb92d34415af9cef3d11081349fbc2cd66c73842394688d585e3129d94739bbc621d4958303d9d5cefc10ed70ce7fd6422d8efc59403f7916bb4c79248c21dc9bb8268411e2c97af9697112d0f14a19463aebf68af15d8431ff3ee13136426fbf6434022f01f7d8c508e87fd1f9ca7bb4ff8a553712ccf458dfc7137c3b5f62525d36656126cae48c4b87b7d75b67eba3f582dda30910913edbadfa33116641a4bc8c138148d2de6741c41c858ee412cb9ade82b7fc8f21bd7f2ec2afe8a9395cf38c2e0e7f02fcf0a6fd21a173fd822286c51d6ab958b4235f0bfb765f869600cf63542d51173b670be229525652446f168849ba696550ef3edab0be02a91b07c1b487316732396edc87df7747a18e290681aa265856f029d1a2498cbcccea1289488f374487426c7512d8f82aa44f27fa5567747fca3cd1226defdf40dd8bd6d8c13316e2fa85897c730b9de635a7f358653cf5718ab45096b1a5944ea41b2e8cc460aa4e049f6f6f58e86c5e2f852f475d505d92870193408f34cbe0bb68470ef52d90614b0910676178b61388e4e0b0d08c56e6fbf67dc45cc41c64dc5adc10d5a6af0fde09f914c488089c9b7da43d2549390ee4ed9b32e718637526499f4caa7d259fcd21b1a34e8144b7869018cc3183c863a76c16a7917e43f1349df2b271051ea7ccd66567ee6e55e12de806efb6a2854d4149da62d672aaf8fcae82f7a90a4ff33cc4d717a4bc4c136b1567e608ea256e3f6e6f314b1e8a27576491cad729b8cf7d105ae6fb72196bc80143a59891bb9290a0e8bc9dea063208b07517e01713dda5af2d9ee6a4f22d092b0a6db9284d557e6e9bae3aecc4a447f80c482fc44dc502dcbbc4c893fc7b20d4b2c1e13a3d7e937edc0fef331fef5d9fb4c67f67591b554e2d7f09b177619d2331a19d2483044356ec793394ad1ec24ee52706432e73a0b5b8362ec7ef04be89038d3dc5249e024578451fc79dc90fb57f2c571194ef776b4a230f2140fdd8d5a6c6d001864a0dc350150728de2ecaf85b2f7bd1335a7299506b974330bed0d62c3d2cd972b5ab6233f48113d3ebbad5e99ea3501a43122d156bbc866c90ec0ff02ede94ddaa40b0232c66386bc77eb47c599ae5925fb2e4e70de338fac484ac55b28d525b4e190be5b8123cf72787acfe6fc70600d82e6410414045fa5dfac4fa24f061ae5b7c89b459bc5cec162b959882c6b9d20492411af57d0f7393eb6b0a08c14dca91bd47879bc4bd0f948022860c7e5f3cc0fadcf1e5dc7747e305b5248cc9e0c92775165ebba65e12bf032d8e4113603e68ac9c79e4b7a39872d9f4c2fe21c9e024ae2d1096c9276f1443aeacc1697cb60b87260ef3b969df346afb5cb6188f770e9e388880e18b00493554a8f840884208adb915d756a7bffe40335ce1c83e19958d05344d138b9add28647be291803a8fc3532a14d680a38e5454e13c10b6cb9603a99dc9cae3f7753906e7eff5090f028991c7fee76571ed7e7358dbccb9fa13a02642c0c103cf41b4dd85430231485a0461c010b167764ae89e25e4eea63fa448de89d799130823a47523b9ba6d2bf69100203557faaf6e6ca44972019ece64d2343086050fa9ec24150f6cf738cd685edd18875495e364cf59dcad96aa2dac58972198312c120e083fbe6c13a908db93e53cdf66f693066e9bab16fc218172bc38a71d9b48cac17c31b2c742ce917cbd73713f47e776095b0dcf9182b59d195355dd5969796cb14135244c16537b8bdadf77d4ca0d550fd422f3cd0caf0249932ab0936728eb28fa82cd28487ff1a5514071a383f7fe1e46d7560ea88766a16ed792fd4b27961073e77db1ed69c971ff1048266fd36b3dffc2bdc0495771c0d59e7f3e939bbd1c380a4978a09d9af7d69e3cfdcee96befcfe096bccd135700d3f808afea79982f8bce6fd6722cadcbcc8bc2a04df6593241612430801a3e9941189e6abab463ff49d97ca11a88404a01b7f116c036cebe97cc1ff8bfdde188c5c0f2e8729304f11073a903cd62c9073dacc118055bf7da2705c33446ede96a131212e95087db1b177f2daf62bc68e9eef3192ce9f06cf92743dc729ac3d3033db3ede26368632ef52d93641ebf94c86d02c803b83b7518538f42994f412f637e53f7ad24bc5ec3a69aadf0794453bf89211136d367a2851c1960a8e16bace777d852733383f69445296651731e6883921cf994d7bb66367ad8a298101f4d5f5c976f7f9dc2e19c614f1132f8e6d5ee891b95ae5ce598e7a35d97065dc722dfe7fccae30ecd316ed14c34ceaabf0dea56727072aa49acb16d5a66dea32a5687d10cf7ddccb35e42ced1fab042fef14072df846edfb905dd743fe3984b951ff7bc082d4ff491c2f29532e44d2c7d46dc2fd03d3df1e5e569fec94ef8c5ad0d6f4fba3653481e06600adc548c0fe3bc76487ebbe3723c0b4dfab38f2ecbeeb1a40cc6b81503139a539284b1d1cf3fd138ad8271eef216df007849b7c1b011be90a8102312f82f110401c0b4e72a04d17e0e6d0485764fced0d8f184e5eda2cca72233a200316474cc6829e8f2230b2a53d04a25248197e74f78f0983851152a2209cf517c64078063d7403b0a3e7ba2d50b1100e1bfc1fc2459a3f07e93d118e4006fcee61e6fe26e500df905cda071f74514117ac5553469d6f819d0c9a6a05c61d0520097947873c503cd7536b61f4e0126f5a86cf08651d40749c5ef91d42f69703ff97aeb2583d804b63624babdf5e98c249150153b1384f73321a0ed10550c4ec29d00d75c2f868c77e38e941139509c513faa5b1fcb1491a1c6341de7935f1d197c3f509b18512c99358d6179cf4ad80f931e0bb323cfc710269863a07ac395db1265a01ed6044fbd66db929089b4419d714f33dec79ddfdae473f4af74424ab5babb337a65b5d4e5ec8c4675a34b1b011220080ec8c573d6faccb46e17e088affb86c12eda9a9ef36de90d9ac0b6b4e3bf885f03cca8aa10bc80da7610197f69aa1e7da95c6caa03575e4ab6198158d847bf45c900c234ba62d4e5d9a4326a14d61a393f45b2e9413991edf9e028adee09a413cf004c8663ebb8f9afeed3665e634c1659d6d40741c8dd96dbbe7fa12e41fe9f58048c4d100c5b69af7d13b4a20de4ab6f0177ca53c50baab7e0d82d195024d2f064e38e881200a9abc954c5f1288e7a6766deb3085e64b7db1e0f1f356f09cba454e73c011c6beb239adbeec0c8b92d89eb58da75bfc63d1c6e99f05ea8be21333b9dbb215c12282a9b9d03d6145524baae95e58932a29926e7c1928e057b9f57044d4033b80c343450b1dc753125aa460b3978e2691e942a14e4c37dbfa0aadd2e80d5e59aafcbca1795b3f0b95025f425814445d4a30700dea747e2825a56b8223e95c7d78ae9383c9247936da37ca385d1c71182bb232db26ad5e47dfded726c2b433edb9895836a3554ff0e182ccd2e4c5e03a4d734224b0a11fe81175319f8ce7afc6f0f7d487db0f8c9976f2d3031f392c0300044475251f77c099d68374669449778e2fd8c641ecb1632f27921fcf082910a653403d54eab5095c1dc72f2afd213611750a7bd6f12003bf6ad378a54cd5721d27bc6c928f1df1b6d811eff4f8229a6d38865b61452542468e48c55dbac52234dbe70de026654f11c200ad617fcafaa8b5de912ec9f3f9bc4d5c2a14470b2652008e98707576bd8fca1d4745c783fef43823e140b65287184af9b45b5e249207cb7e65d017cf7a49bb668e9d4972affad1177768c436635e7c1b7139af975b6f1ea2d7d3f3597288bd3c637cdac27760f3c8b056166237d2b5e1bb4890d4edc2c7b7f6e1991c66c64a827af4c0ea5bd3a18a5da453049267a3d99451abfa9437037f6774399bb997823548f774389995119691073bceebf48035c913f61050f9b9b28253275cdc43b897afbc38da8db5b7b7a35820f0372d0ea6742207d4f450e9b55f69c3b0b7cbd45da1a823045f64b7ffc32a1ccb4c2bb781930ba0e8a362974e389e6a7a227bc7f46a8c09d1c6d60a2bc9125f9566ddab5c74d5121d74d92a437767b6a456eba0037deaa85611d466c0516011e42293a4bf8392593862961dba29f77930f63a5891d31a3f25e085822aed4d1b20163f4f4aefb7a8f4e27e540a96e9661a33447248c485e36ac253b7a4eee082032be6235e4db7558c1ed8611ebd706a3258a9a2434481b87a9ce5de8980d4de8abd4d166f83d08e96fe8d8ab833c919a9cb34e1878f3110dc81b20508fc8baa2e39fb629ab9d646bed4b57820ed020ae544c8a53a5dc805195055467661069e9dd1a3c301d875dbf69c4250f645f1851db9cca01c2416b7ed1315e7a78970695cc0a32bba28c4afe009ddfbfa71a085c74c4b762829b021dc2b0612b515914bffdc665091d31e188e6cfedd8fa36dd8fa8845b8bea2a2404a606c0e77e7a9ac58a88b4eacf952dffe1126807e7165e7579fc5ea49560f6e7c0b04f06c557f00e8aae67b6d305751d9dbc2c4882766d105e5f91012c0674c90c99f14217ac8064cd58436b9981f8fd062bbd37ec833073cfe9ccb4c904e872c85c9583e83ea248267408477f10fd80558d1d50e8911bce3b833bcf54342f2b647e234333b655c42100322f221e0f87034f5089cb87f87cee12b239d43d06acefdda8329d4adc8535b00669511b8908e0e8fb6cbcc7706cab3e5b31efa8eb1ef32a10f15e8d8300b7a27358cec33239b3beced6cdea012aa08606f8aa79bb497988be61ef293205f1d792c5448287182a1bc0269c14acf656551d388496f49a16ff8a24b98383c512f4ba2a9d2d0b1ebdd758eb1054053af337f2f9a83218f4538b1e8d85f0f102c13cd46cf2943d4d3179b365cb5fcf5092f7b718f16f814ed1334c1826118902c711d41ae4c25745b38e8f0502c0256867e2a5ea90252911813f4e69e7638af719caff1b639aad1a0031675d60c7c7f7a27b63aaec89ff6a9121da374845cf228e561c78958df8d0ffb5412f9fd2ace537336bc5479ebd9db4e7e51717038a93a336c44787635e8e29d44d9f0f064638a5cb55a55b5a025f02ca179510216d39113bff3c02ba55379e22328fa692b8a8198ec04105edd2fd574022e99ae24f4124a23f30c04a15838229b4501f8a61fd46cb613a1722213b4e00760ce2665f47f159f6db2126df43c02f282e29fdd3ae0a5f8fe90194914bbcac1e08d04ebf96d647feadb5dcd8d1f5c56faf0cb00e6faeca7d54991f453ecdb2b9a1871a21989635656d5afddee95a923224b711fa7081e5c63edc8d054b34d736b9b7fc5c38521b545e522c1896cab5dc64c24814f5afb22dfcd8e8b5d4a6c27e2834832eaf387151f241df4738aab15071537a808583ea7c07e07edce4857647e3a0670a3192531b2f472a2db7013478046601670132d9e48181b9f71d9576bd314a229a2a756245875a8c2ec42c213b57f254ba681148665ffd54d8973e4397d0520567b15f3ed51c275de9b12342408c7cfabdb3c4a0df81705f681b5d695fb655eea8c738614d6bb884f9372fd6983ee260c8327fffd84ebc637722364478751d3444f6ee1d024d6b21af4f9e859cfb7263a96866aa31a93d2a9fa088f09c6d506ba51e0821df2f068204225982931ecc4ec40f0a1e712e03c5070e1304d0936d80669784f101818856a0f4de99ec9cf91534e874d48ddcdca159c8622f1f6fd5a0d287058c10d142a249868252a08b713596207b2b712b139970492e2d05a5ef6123cd1a969d4ef249664fc0eb10d0e032fbc4681c5e72218ab417133c32b00d2113b458c9c09ecef83f39dbef2f241346317c847e8eaf11dc2c4f53576f3623b3aeacc13f2ded4c36ed06b9eefd7658e2de7861d704c012de9597cf29973dcfe78c5baf846f45e062ab9d123583638aa06e86b27d61b5dc531c9acb5c1a56bc1bf192ee6b02a66946247e85504f9bcee7c208348e646758a050498037e7141eb3413617a1324b82243b3b41457aa5ffde0f4debbd422ff67c59a7ff51f07628e04c9d4ac81d36a6cb4b3868ffecb80a6de70815a1952caa3bbefe0661b2dda0b919dffa6ad6083847445ec05be8f96678f13d3c249f26a2a0df743c1a33bf493b2026a85eb29b3ade29fa09dc563c9ac4024d7144e9a386d4de38be19270f2c54ac0a13521d9ebac2b0d1bc59ad0b8f9b43c52284a14d08bc1a80eb555bfc88acbfe0d092b3f7fde2d6910f0b7f4a44ae49ae221062a52920468a51423dce383c9c83fb993e8422f1732abf06a8ad413330943712dcfdee6ac3be91d922fbf2cbbf5ca94776f749646b2b6e2c53374fc16809f809946bedf833e79f321934c7a3f3a0411c575c26e424e2c38046b325ac1a06a3377c717aaaabd55fac688b7ba279ac612c8072c64d763394d43eb6ff37719cd6d67b9a925c5c4e95d17172731e1e0a8652de22d0f1abb9649e9d273baaf62914dc492248fae0cec6b49d9bd84b6324dc39281bdcb5389ee1ce9c0b953c00aa18b46a1077a42c29732f813b410d0b5295e5bcfdcde75a1da3cf29c512cdee01c3a786618dd88984e88c3fa4a7b7202c2de1c4a43ef28f9557780667b65bc7902784dacef98b22f5aa23b257016dba1278a636c77b1301e60c1661479c4ee0348233829514333d7caf2d86260aa23e7ebfb0ea011b91615d94578677c0f16769a7133a47fac3639d28769c6e3447645c3cbb5e32b3a4898f6e243c35fb0b5c878dbd3dc17524f74f9ca3caf71f4f999cea5ceef43c8ecd0c28bd928453d3f11f66eb9be89ed762bf0f922ed64048ebf4abd78d56d85d6bdfd64a5bc9a8203bbb90de70e5b66a228fd932036dd0ab30eb829f899ddea652717e833ec094e03404fd90c574cd2f0b93711304e9b82d6c007100c70110a30092514983354a1988f9a022c0f4df76dc36b9250b2283982043e063adb31bc839676952c1354fef0d6000931ff2ff72889a64182db3fa958cd80609fd6696935b935fd49704716b525c5b79ea144d8c5c436160688fcad6fecfffc4ee259e9246c30cbd2e73f8016998af52fc94d73a964b318b8f74a6626e45d3a44070a0aa35abb4ba5a6c690706dc52b05b60eeeaac1a6315e5431c812d221e9a669e761a5f05afc471ec9182e1b70f3b7a39313e74cd34611c0277912ee81ac3e730a03662d9bf0035ae15b98380b08fc60a0674e0d82b229afbee6c67384770801097f997d12817fa07165f59e1cea90687781764f59c694d8bf8f162560924cfd2b3b1263a4bd7688851c9c15f0da1d43caa64cbf9101435820773ce08f71b9d43bcc09c0093a44eb5f18a28a514e7ef04dc813d812f6feb1f3fa2baa39dd8b0289d51bc706facc1deb833e0361048c6bf254ef018a94a7c4643011117f9decf32e011788026b6003e8bb5fc2fabc1fac692df180db8b758288efe2779609a93d52d409c85c45176b75d1b072d9c07b31f0efe966670dc446fa37b7511f4587fcd12b3270c5a5965d353b89a7ae7b29b40f0308b384ed80214ab8ff10d616a70076ba9202c8132fdbd18b4d435670959ea9990b5875f1291b95b1038912b51600eaa31a5da42b9b0e45219a918e94832237f41e49f2880ca93703fbb62aeecff4270a5678d180b721129163c65ac5a85e51e876d5f50730576739b7549407229a13220ad1516116bc571895329c333294c53c5a79217c1a8b4b26efe81915cc1aeae2932fefba621c6db696ea778a1dd51e09441658aebc656d9a2ac996290ff7574fbd126341c4951afa4fe27607822c0d40bf978cbdd8a0576050c36e10cb475d75bc8f02254a5e0d34d4e893129dd48b45ffc4c187d85292c5047e7e24dda11b021de64917548ed5a3b727810113368476e7be07654a71e1cddd9c34d728e35e70eab4983ff7be82268644b3457d784323934d06920a0e837b09b984e4da06b93501c4cc28adb57d215e5fd752d1f3bf19e0d0cc3bd828c5c25e3bbb69c41bab3c57f3adb9e2c4e3431fd135d63f8b76452f68de161dc369e34bf87c84b92164012edcf980a2429ddf222afebf044347f66fed81627770919ccee71b42a993eeff95a646d01d77c47b4d88efb8dab72b39e1ec45eb423cd8272bf5317518ec03643893a65b80275bb26c57627cae25c138f65e393cccc0b2cead772b4b42ea14796d62c30b8e5b1acb68bede1f9937af0ef17f119f8188612a471d6b37bb00a12c4ce877565044863384853d63c3c3d8bedb90629a9cb288395a70053f11df50cfa84a46ab9cc9102d1a5bf66a985bca6da94ee38061d10097dd235dcf4f382f4ae9f3e63b1bf8cd951126a59f551a3b69172916a0853bcd9088811ed0a6af9f174eb29db655ec40ac32947a3cd22ca2d3744edfb4bde71d92eb0dc3b9bb53debc1e1a0c2f2cc8293cc5aa57f11b6f062aa71c279856693facc6b7fb9c31f6f98fae2210053d2250cad0d798dcf49ed6a0c763397d1eec72caeae1883a83d1fbdf6ab5d369015cf72c3f8023da185c7cec1fe4d5d0d237bd02f6880ce9c2d8f1c16226541f1008393c43204b1a978295e1ed01a0b9a515200148dfa7b95dcea86a844d20611c5bc83e8dcb7215e2f3784bebbd0e94a26e321931f6776d3c46de9b94644efd24458e065ccca29a3b7c958ca146bc3fe8b1d6b23c6cb3cbb6f9510f0c156fdbc5513f7f7a02bb8b5676ec4e8458d8f8d2d1370181cb5e5eddc508371e099364d2ce23872dbb25cb966ff9fa58e1c674b9a56667451ad38bb8bfc72e5e4aec003837f7d327e3114091a9c5f41f16e0a9fe33f0b38711ae8e431372fd8ae22d8249a5f0a44d758ac1fe857fa1a7f966794f9c8c0c7911bd8e019044743d2601672471722708690734a867e144f9ef40e3a93db4967ceafc4aeb3c1535bb894e82be273b1130b9939d427453b7228884551bfb746ac894ef438c9bf98cabf9980c689e8eda6b5d765e895153a879e11e5ce9108099260f7257cfb2235a1e42615aa5990d438883e47e23a7eae2c36fc65982149c2aed8a6691ecfb58ed7a0de359080bd4b352d02ebf1e1c1519b06471dbff329de002ec367c59daf208fedc60d8d257e7407a7b8258dbde978eed0cc0177d3a6a3c90460241d1fd0990200eac65b4761912d93317325decb05e0418db84f7c1e48aa85bee1ab05a3663bd08859c995ba47da3d74fce1463d3d2131a7f89a999df70f8f7ee8b735a46797ad7d98070dad75c13bdcf01027cb6a5aa2cc2a5986871883e28ed27b4d2552466ee3935c1d3f4c6cf47ad6d05c8f54310c98fa18c6ae1c418ccaab5b0a5a5518b053a3d4316707be4270722f4489e32001a4b8d0289250c0c717f7015e4519792186afbe1230e58010c382663b87288df219be6a6612b381e9d481a58f15a824ea907748608819e9d23ab48610c35406e5a00510f3eaa0a4d238265b40210743d26c509e71929527b0548b55dd82c1b268f3719513926121be7d656215fd105a4f1511f83b58a9df474b50fa3b0fe66833e1b762280cb2e124f1bb05761d2652248557fff7c864a878c8f17d463330edeb5af50a4644e7ded3a09c8d669cc569da5548b14c84fc786e8c72e1ea9db4be521a11cf657d11834851405c7adac1e52477b6b48d514f7e915157e9901ae0060b36bd792d76ea86dd502eb94f46a9057e7a53a8e19395401cfd929eeff7907dd9e23b88a5931e5e03021980bfca9752043dd4ffdaf6cb0c4d4229068d4b06e213da294a40d34d0ca2713099e431d6f679683fb930205b0f867846698b7376992784abb6435e2df8ed49669e0fd57d8b596d5d385b5f34c4b38b610bca850ed8c61284ca2274fbb812a6d68759449de6015cd47f97b2a2f6b202ed881f53b9a72dc392bb9b96fd547b32876ca80f47e0b469e3dd87a058d6424b2757a220c449c75f482efe08220699d9397a8011beb1077cec7ee3b4391177f4f1ede448e1459e0eccfe449dfb8fe8618bcc5e3c00af62920cdde6bd41c0d5bcba0dbe65fa3b2852341efbddf151260b513521a88746898f8610eed4306988c23997a019824280ce27f41a047d54459a4a161941c91c477f0386b0acc0907942c688d5e27f36350beddda1c24f96d49d54b03d83c90f0a2200c1e671cc3ca7378e93dbedceb493d8e73796842a14bfa08814ea8128b63c0725206ed5ed777e47488dc6acc6314a53067620a2c2ed0a26b7908111c1cbe749644d8c29056301e24b926396fdee78c7fb1f7862a4ad401770b33454a76fe4f7415a926decf3339766670d5af5a1b3a5313e807afa960e76f0354e021c6d9890e828c7225d7647f12a7ad3ac2ee232287e7c19c0c9b1462a611bece650b4354a0327c665415f70ffef359bcf755cfc90731345f04ae870dfd37ca0e45ff46add09dc8b9181bfb3dd080baf17bde425a52a7c49222ea15022b0b11ddfbf5c37e0c8f342283820ff6c205638692c1f3eb0b1848488e95950134fbfe21f5b61776172f65d12561540397a70dd0059a926410ec3c21e77fbc4c10b2fb5312a0f082874accccbd627949a772401eaed42a6a07ff78b2276769522f66d2c9d1bc402db55a282de510fa04f25f68bf50daec1120b7c00a18295ff59b2313ff3f114acf9e4d99ef80636102d7aab6f467078f67727628c5d49692ffbc8447ed8f800d85b478e59d366a08559a416658656092c332f0b2c09d2c30bae2e4e722526ec1f3ed38cd65da4a51f4148f7d23e94c2bf4a734c15bc6cebace27b6ea83a78316f0673f5c0c07acfb744624344b6efaca0b2c48a4babf84a7c8b3a9c32364b003a18ae0396e37463d43bf87112b063df58f87947726e9b6984e417bc10648c909ef1230086a3127c815a238847b378d6398047fa3f9c339ad90e38e2fdda8dc884bffb129a41a91e16a4ca3bfd70e50a387758cc8b51c0195069ab58332eea154b306cb6ecc34b5ad2b16e8b1748464c848925da34e7b419a77d23e3b6502e95d4b1c5760f550be2f1ad43dffa3a55d4936951b029574cfbc82a5f5b0f1b43a11ebe61cfc075577cef8329c7c6bfa364945a7de3b57a86be2a2246ec6523efa7a5c6b10ed6821a5f95a85aa9091afb52b57ae2c2b09ec056ecb2cf818639aa7a7b548560fe58d0c378575b6023d0fa2b0015b5395aafb110795e90e4d899d5098fc72d8ea1a8daf22463f98faef2ef79b13da5da6baaa194340fd331aa7b24f82356b0b81031c5d1d7995179706f6e112cae257c98a2c9a305aceec99bb91ca9c47ff0acce424e4f825528ef036316c3799c12419886eb1ddc04fde21c6c147f4ecf430f4b4e30580670ab730d700cd05025ba4c603c465a7e8a10da6847d97ed7f8d755cfeb647f820f5134c806549e55f2a58b4434ad2723cc5c007927d0759853ee2cacfee9d185ce90106557d034e8328499431a720e848ce9094cb5fcba69b715601f656e455984d00fdaa0b39da2aad1ffaaa6603eee35b34487928e7e51628dca8c336743683156d24b1d818a144d71178df29e056ce1a7a48e4caacf74aff4c10db7dfef35e4ed4a6ecbb378c6e8b0e203a6581c56317257487818ec4a9e02987dbc72520c72008755e7293909e8a1c8cf9d63517acedf9da02ba11f4b894d09e6839f4d531b4a5a5e6446cbfcbf1fe192d3c1d558c7b69a1d30af4e5925ba0e5e0b46ae2051014d4b52c94e25372187afc0330c005bc804b9892099931a8124ffb3ddf9d702607d0ef8ae4da5fd08b39324bb6e191389d6226f9282b44bb430cd85f4123916bd4aec532bb58fac5ca1e32873dc20630142354d5636dd35b7574fc62d2cacc3a3825bef5679a325fa07ec50d57865224509e567c1574aa8dacc41c2025df1881f75cbb905374ac9b773d15c66cb53a5b782844c949f69aafa8c52d56793aa3e9354f55964159f851cb3bb96fac62d1af180e6e8772bd7a1ece41f39a779b05b19ebfc1901a2d5a5a2df4095c804bc03633b523b64788edc2c3a7da5748f20c52d8ee85391f213fa8b863e40a9732253c73aa032f3ee8e67057f9e14b7c0f31075240db18b6ba2e11d1715e9abaed683305bc689388714cb92178561fddb7ab02089fc43e27c773027e07a44561715daf0795161aec73e318a8d98cf8bb150e814eb17b02180188698d8dbb2d5da26820553ae3db617ba5299c2afbb620b3c6cf81525480d8645deb05984a09f3611cc5dfca6a86fa2142e0fa5a8290cbacd23693ddc43387341e251fe46113310a06d9ad0f2a96166c01894a69530edc3184668fd33ce0eb75520af0485463f8b1eaca13698f11432fbccb46840d1b7ab83954d5573df1d671e8692a0262890a902b05c5f086119224b99046fa29563499d1410b51a748a06480d7a4320d7f6b791db659d062090fa823b28a48e0c74234892bb4d03c441a79b782940eba71bec42ddfb2a33516ae6e7831576d7a8c447cd0ce3d20029d2aff88d158c9b83ac295f06c7f11a06664920fc9159a8ebf0fc4accc339d2d049874c87fc5e78802a876f6280018115f0f639d3b2a7c404f611079256c1390ad6fbe17a0c447f3db14783c26d45b1c551f92a2d80c980e94f6ac6acb00d9a84a900c6ecdde86513f935459fbf93635c57f4dbeffda200eb94c462e5a4c75bda2ab4a0d2d3f73701ecc459d9cfecf37e1d271dc7e2c68c994b36ea0f9e868fc03188f32a411bc7872bd60189792a5e62ac6fb0bf1859f630581bd6ba82544268f73db0cf9da5dca83388d70dfef9175d07deed5dc209145b849a5a0fc198a68e17e7b02820e66ce065a155aee747a2897e46145c4708a1c7c52b14457293d15d7207f0258cd10d09ba189df7b1c11b63426fcce0c40e1927201e76620eb35206d22e9800bdd19544c84390d94876028c03b77d8e8e9b5a52213ca891bfd7b21ded1cd26cbc372a03d31457d505db8a9db017d669eb5f31a863b02480a989e8e30744ff9274899af2a5010426e0dae65df607816ad6cf6cbf3aef94e04508cfc9fa1e47a9b25e78823f617aeaa4da911d47db7b600060de5233a8d5969cd9ccb32bf70b75aad19cdffe44a2ab11a304e6b15f8724fe21375b4da9f7d984c13ff953d5b1482bf30d1f29ecdc82360b8c8e055a56f70166c5cb570cce600e6d40935b45c27b2fc17ee286eacc4d446152225cfe40c5045502d35fe903eaaf204e460244b8f4572233403f9773263c59bd93da44000a16d619613556c052813523c4bae7988e2c4fed63e488d2bbc130577b2cbf115404f4f4f43b5dbd7ccb4432f40bcb28ce8759f25bfc4310f385d745f8b7fd248cee894b339c6d6b4cf87ac582f9b9e6c20e8bcdff9b84a8db02ce9d2a02c8811f3c27d423e03ba6199e865a53f6490abc9e877e33606a044c5dd405306ff7d7364ae8f8064ddbf1f22c1eb335acec389aec2f64b6cd24bb4594cd91675380b2579cd93a96ec18adec1ff2d81693b15b44d91c793605287bc199ad61c98ed1cefe20b2ed4cd92d846c8e5c3605247be1ccd66365c7d08afd870cdbca9cdd20cce6c964d340d94bce6c0d76768c66f60f21db66ca6e226673c8b329a0d92b87b075ec63c768647f10b26da6ec0642369f2c9b029ebd70cad6b0b2e368b23f10d936f3ec0641364f666c0ad8d82b47b6162b3b9e26fb879c6d31cf6e10b3f964d974a0ec9573b6863d3b469bfd87c8b63389dd44009b479e4d05ca5e38656b58b263b4d97f886c0b737683389b279f4d0365af39b3f5d8d931da63ff10c0b69965b788b279f26c0a70f68a235bc7921da395fd43665b98b25b88d93c996c0a58f6ca99adc11a3b9ec6d81f44b69539bb8998cd91cda68166af1cd95aecec58daec0f62b6cd34bb45c8e692675381c55e7388adc7ca8ed3cefe2064db4cd96dc46c3e7936053c7be59cad6365c7d366ff21b3ad0c963dd1ec613b51c0ee11665381b2174ed91a96ec186df61f22dbc29cdd20cee6c967d340d96bce6c3d76768cf6d83f04b06d66d92da26c9e3c9b029cbde2c8d6b164c76865ff90d916a6ec1662364fe6959eb8dcb9b327b5d3b37c4960b14ec6d21665e1e65928a12c8b6716ad254b6c3bcb97c8623f656915b2707359a8902ccb338bbe9525669be54b1e8b7d0296b6280b3f97850e67593cb3e85a59e21b59bea42cf6394ba3908537cf428764599eb2e8ed2c319b2cbf47beee5bb19bfa9b7f2d52561831fa9bf702d3ac00f6a95eeab8b2f4b4c97203cf9a983dcb3d78d60436596ee0b326b065b907cb9a882dcb0d5cd60436596ee05913b389e5062cac09d8b2dc82674d6493e50e2e6b027b961b5d648e02bc98045ae89fc55a309a554d07ad016e81bfa65a9b35071dc2dc0a5440fa35f1a672eee8228bb8abf8bc205b82e49ec4371c47e8a031dc57e7f6bc0040200e26549351ba3585b2e30af1850badffa562566ab3d64d4224c9debbdb967b4b29539201220c6e0c2a0c31aa38acbde886f04c8caa9ad197af65b8e4a9b8839b12771f72ed082994234a9248b5b02fd1df65a633d74c9f7e47181e4a5966928895f2cadc5d9a94d3f0ee43b76552dadddd4d7fdb9e4aeb292e763b6d71953f7781b832f7d28b09e159838e294da3dfd9f48e734eb97d31ba687fc3678e3319955e4c367928c960c11125a56c090ce8ab1f33cbff089b3ae081b43446aad3903d8439b9e855c6533da78d712ca384edcfd1e5baa9a9f32527ed5777d6b4fb55d3af993bc3f054ff742fc66fbf7ab8b963e773a2b9bdf6d16bdcb69f6f373c37ba659b863bcee948c41863a43166fe33e7a433c698f5b4828b116788fbf80f7525eee34afcc77f284c76cf39b3a951fa0485d127280fe59973dbe1624bd8ae1a5b3ea4e1da1d41f49fc6791a8ef3880da38f64dd88d18b59bb314f28ac8fd05304f8cafb05f0e8e1abefe5ebf05deeb9af39ed670e6157d21a7ee9ee8c1a2f336af82aeb8fd6f055e8e5cf2378ff513c8d60b38f398c3e50d8a640057cc5bdfc1d78c8c00f0ef8aa7bf961e7d095748c9d16f0c49d16c0b2fc0ac42b5c49c7680fd37700edb490a398bef656ca8a438bc31fd4eb10132ff565b6bbfba6391145b8a454d2b98297724afa7ea953faee72da78caa5ec6ee44266c1eebd0fc1d0cbf7aaf651b29e8754062d8fcdfca34afe6f291d6aae4d33cc83b703e588921d645973f4a47c0ca4f2044129d7cfb8add66dabdb56b7add62d7bcdb7762222d03644114688404da3f96451939ba60aae5d1c48f6ef893ba6a807a47b3b64ce66d6310695997ef412303bba5c4d5f4d3c71c0716d33b0c4bd8bd19d524a29a5fe92b6136957147c5ac2e8d3d1c694e08f664cc98f2eb3b7eaf9ec6839eb80c0969701b84af654f619d96b64cf68f55518631ea30fcd025862dd983293524a29a594524a99cdd9de8d5484cda8f1e229f982551e86afe4839255eb9c47d4dc60664eb4c5f7df5c37457c157db5f393e5db1cc9b297c89227cb9e2c9fb677792a61c3b6c952be7ba6b2936997b3b88f608c4136d787b88ddfb0b8a738fc31fdc66de6136ee343a417b3d1ef1a2a93696b9ab7c3006738c31972b781995b48f594ec9acc5dd35cd35cd33ce4a194fbe7fc96ee9df6d4a57f31baf8d7c870867a318e5b88a7eab338f96de3abf9327b49df6db82b695c259fbba1972f5f3996db4f6771bfe190872efbd79774e9587f1a543ff721ace22a396ba0b97c555fbea4f1d5abfa6f8e79e872ffe6ed884e38c20947e4aeedafe112c640975b88a7640f6c926ca3024a21bef2afd1bcb37139cb3f4e9f4dd810c4f138300f8fe343d0823996548f59581c4d0372317a3132a626d3395d480e225f940379a369ee1c0f1788ac6c8aa8a24f332bc09069f633bd181fbafff1038bcaf1149d49b8e4f8f287b318a92d8d21f114fd14bcb2cc99cd14768600ca720ad98a1c7a11cfdcb7711fc4b772fc7771a4f296e96c1fe9b74c87f4d495e36aafed7160996e25e0e9871409f5c9f499702d71c5280f8d1348832c4f2ee5e8c44e12994be9da6e9fe2c59c408f87e3380dfa5ce45a74ee6dd8879c489bdf14c14358cadf73288ff43ec453a46f6ffbcd6f36ec369a4b1a61bf2f35ca8be170db24e0e9732e7686b09137b4c7670705495c0ab427da58f908e0781dbf72659e43b03fe4781c43b0310078ae2dadf11415c2840de94da634c8cc9c8eab80e7b8d8822cf2cd71a705b16d933679ae3c673b9197a3c59fbc02ae8ee74cba95db190067b02e26b20dcad1092a0429ad725c2ed7165a6189c628f82a3a31051a4537b2a7a731a28229b57fc3135077bc1bb171579bc1759f694da6e3abd37fb85d9eb2313eacf9436b800fc13ce3639c11f31c82cd7038d24a0414f03ab08c027e06ad9e7e7f43abb827c0c796f1e1d0e615d7436d507dfcd4472fe6fe0d37fde84e2f66f45c53a03ff0a3c7999e746732777fd00c9a58de745bdebd9896e7eeedfce28633f9c5732af77b17379cc92ebead0af61f4fa9fcc88b71414474014726cd45fa8f8463c7203d773d49e6de3bd2ddfee37c89ef721f3d07b80e76581d996812ce92c9802b6919df733299fbef62d273dc0dc1d7c04ce61e87fddde8a9ef6f484e661499391ff7397cc3bfed4d42b0614644a66fe29e8868236693e9a23c27bb0bd29e69c249b0e96f48f0ba78d355f92bb38be7babb37661595bfe1303eb459c667457cf5e2e9c70e6b96f15911be52f94cc6475fb978183448959bbdb85911161797888e6fb9441650c3c7c061cd35bc0d38ac198736d7f02a03e010cc35e0d402f00c0a92aa1b300c6c7acea403800302f0ae6c3d531c5fe170e3ab7ffab4081a4fe3ff1f87ffffff8eeb0e071c46a395d168b492b2321a8d6a188d462ba31a46368c54a3d1aba8a8d4e0755e0e188ff2b4085fd1a737ffffdf7335e0d168341a8d46a39b321aad8c52b08f95bfa3941beedfb052c3e8aefc5db9373ce9472b2ef0a8bbcf8d5c8c42a3df462ad58b51b937aca45c156e763468ac8ceeca0a8c1a5868d05819dd951516172bd5cbb1a2ad60172b2a9917a36283ea8eb81ead8c462bffff59ecf4b55afb71df752ec7e94d241c7ebf81cedb974c7ebb26ff854d93ed9f2c3ef91b12e5d222fec68c436705dcd8da71270d1937f4d50d3dcfb83ecc133c736e38978831e9a9e3290a80db59c78d2d7a83e3ab1a6ae3ab3872f1b486a74f6982328c0f69904c1f006fc26104caa6e760dcb0338ce73852246dd17f5c89f59fd30d271b4eaa93b541f5bdfb7892cf95546f47c8cb81c3e3771f4fd230319f44fff1d509c7c51b6c701f4fe24b5e86fb7812bf42c6bb12194fe39f86ffe4cd061cfe0fbae3378ca2f1a43fb98dca6d711f4f42c20187f7bc1cdbffe739a03bfd6903455e8eed7d8038ec6d3bbdfb8ca44dfeeb4a68380973ef4932e965e0d091be0f9fc381c3eee329d2dba0c2b6c57fff718f391faab7aa6f078751363ce9b957fd0d4fd1f00287554948f272d8f7c195ecbb4d0bbef80755c1d695b88fc98b59b14165ff6631243e495ad8167ff2aea4613a9f3c8cdbd97df0c9c9c989ff802018b3aec47f4e70b4fe1343e293e4e44f1ebcf8b358ec5b7c08c6ef2b4ffe7af2f7b1fce1f0e346f7fb95958fbe5af9afc6871e24800f1dc8c687fe93b26192b72354f272bc78174f617487c2e81394c7e4c57c6ec312f33710f00538c00fe039ee390e3c9d4e27f0fa68893470dcc6d9df4e34601ff65bc02f86035a3e060e3ddba73c79fbbeef4f37ecdc72fa970fc17fd9beefb3dff2df87e07622d1284ef674223df87407a44748274b03f8a496d30987942793fe87e7affee9743abdc03f686ec13ebe7085e5c4727a96d3b3fce9743addd082610d6d08b66ccfd993fd0da35a4ffad38d3740019e000378180aa33b204879f2e95fbc789497036c7915f0f46ef3f2ab19319e06c83a81a7ed04be8bd36bae1368836a7bd60b6eb1c5c041b9e5b6ec477732e969b82b7f43be7841619e22dd80c34729233f8b013e068729023c0270f802f307c0618d97e7627cc8fa037cd8fa03703162fccb7f1fb6f00f9a5b5d0d37ec5c43d831861ef4e28ba7cd82ff3df761ea6df850f536e0944d06d607f72bff7da8c2e1e754afa4a24579e1be85c3ce31febb210bffa039c6cb939e45e353335eb57a1b320eff060e5306c061aa009800387cc9a1e61a0086c1618d9c62038735a708008736a7d8f0357008e61419bfc22188c3cfc0a1bde1697c4fa2f121f72b16de546069e01f34d3f890c33fe8cab7f072d0781f1c9ef12e3c077499c66b2e1bb0ea573885c39a690f7da26168cc58918171c0a10affa03760baf22b5eccca4b8c95076f3624bb29020cca2370043ef823148bf2a3a74fd4703b53980bd2773c39b4d7bd18fbdcc461b691564ea7154c9fe81824ca93676eca934937b3c986643759119e1abdbd2e1ebc61974d34e7e2b056151cdac760175526d3d360fa17a66fe13ebfc16e434d306ac82897e5a6dcf00170431e22d0fcf1148db9861bf3c98d19c68d01c013c9ca8df9c4cb210776c9160a02383ec7e7c032332d1c1f5b383e7a39c4168e6f6149a41bbe64d25397af4ca80e05ec780ee4d39f7ec755c08d523502331d1cea904f3824fdc973b373b9338b193483826051dbcfe44d279c41338bcf74be3ac2a135619dec2afadcc778faed8469cc9728615f82f67426dd18cbdc0d67487b6ab55673cd205f9d3cfd9985af5c27519efc4b568e3f39b1912afa277fc3b9931b2d777249f8fbf892bf8fde0ed3114e38227f18b5637e18f5fd4cfe6e6c24cb87b88a7e57caa1dbd8846ee3ee5fbb90f6842a39a43d3e19fbcd6b456c58abd9e55bc26a35befa0259d08c81bda807c4d64c2bd48aad950fad0b1e2cdff2f365774dc118d3c81a2880ae9452ca162c256e292c65b9a9bf51aac2088b59d80105a66b4a91155b6de54b2c7e3e98af3c7b87d3e1743f9295f548158f64693f9ecb270848d3a951e3a5ebc952ca0e87c2cc8fdf1257d1091b08c9f15371c5e51d1a86e29718a3a66126c62f5cc7cc2fd8c659108d794ad2586bf2a55fa20d8a819786d1d131fc3b1c8981667538a0d7b3f184882efe1d0edaabc90de3b120c6f011b4ca738111b6b04354f97baf2e58991f95f28d51a7ef4c9fe54d26d3c96df947997e9a4cdf37a67713ce6ce7540ad5a205ce2c0ba6e91e24ecb44cb929ae4adaf3a6bb3ba2c3e9cebd9895956c0c32b2201bb4ca3f4cb1fa4676dba03d1378afa8f22d4b292519b2a09bc3bee99ba8f2cfc470d3309965f9b6293f536a84c829df372929cd82b3a0dcd9fb260b0ae1d0b6c02128411f27b2c47d23258e39ea37965878cc57a227b174d8c16464b9ef9ba9052b445cd131087144137c0a1bf64de348d64a47ff698cb8f830d537decb5b78af141ca6b20b1a355eb02bd3dec7f467326df131a7fcb7b8b50b81fd1c763827a68fb105d3c89c24b4e0e7a77ce7e89c92724f36e55b88a7bc578beb0509e9b778940f5bb4a0dfe25b7835be6a81c3161fda163852a5f2a8e754ae87ba5ecaf582782f8a4af998a51783c2d1a6a43cd79df7f26a5270dba0741436f45edecb57e1d75313c413e22befbf1ee996e5fdfbe5bd407c82438b433096705829147cb2f45e2ef05ca26dfa49b11b1c8b43300bcafe2bd7c3e15984fffb7aa4f7baa11bba4ed84bb05c7c57fe5eef4593ad6023618713f2d03c99bef6d58ba19fcd3927d56e0a46f832bf9e9612d0c153fe2e7ee5ebf15587e31288ab4e41d4c1575df322592ef00e2b3f2f5d918ef145f1006fad7c5361b992ed703a1cfae197c30ea753e0e2fd776842244b6b41abfc3514c4940bacb95c7c58359cec4ffb469b41bef15ed95b7db72cbfaf66135d58105de68f5db9b135bb6057aeb7349764c5966693fd63e3096443cfc3912c79e3bd244bbe6a6a6ca4f7ba997dd33737e5a9f08b4c542127fb77115d64d24c5b59c132405a2e7094aacf47c5715c81c7a646d4c221fb87326e88302f31867f7cec2d19d9572f31e55298f84be90414aeac034f50f6efe148b86079f82a3a31039eecdf438709382be6b07d08a362abce2dd89c231809c2865dda4f6b7bfb3ca28dd632597948ef9f1c7e1e92b5bd96d19fb326899e1e327249cbe3e1cd2dd8f0a55f80c89387749c590e47e793edb091f0a525ad41424d12b97158bd1c9e7be833cc39e70c612361ece13167744979aa35ef5c9da383c31f52474789243a47091d9d1870b185c371756701624f2ab256dd5df6210d39e29b634cf9872aab937f41c5d58e98721d9ef23fc10d33a363f80b0f19caba46aa72a20b8e8d54f98768166d845d733f370e1291d5504495bf2fc107444e2f924581ecc34f87af38b023ae3c1053feed4222baf87ba08d8829ffd641ab5c0dfb7e90fd25be91aa6cb63f37a9b032bb1763f2755261fbb3e8fb7a1236ee18492287feba9dfde541bcc685f8fb90ef5df4fe8ee3453c2709f7f725a28dd1fb7b10224c4321c6f096c210baae5e883b79ae76f28239c7bb9f39ebba6bb38ccaacbb3feb8c1a8144b63e68ea4c647f1722464741741664ff185be4fed065903da3724429a51ec453eeaf2a6ccca1cf3e644d6c475b48f6efb8ea9a6f991ff4574c79ebf4214a8e596754584e5e2f59ce3b0f857c23593007f134d16974160a8542a15029ce982ccb32db27dd3a19c0e94330a39c3e9e3e6c91e3e9c395933b6fae60675a365a60041c98abd558c02c8d91a6893d334822476fce395b66a579dab2941d9193e746370275bda47bd28d3165f20d64f2bdc4e46d0779319d85a7dadb213decfe01332ec801e20b2b78c28813a4d08a5165d275cfbdf470746f7a5267ba3c74b974823b0b57f98b3a7cf2a4aebbeeba1da463bb0f3b28078964f25145c20d84a3e61e64b289091e7d90c9fbbb8b0b759d89c9ccd133c1a8048cba25b507b5c654f70dd4853f32f731d5fd77634c75b881bccec3e1e198b9c33dc864ee3bdc4b42b7b3f0bc189a85bbbc988a3ba881fac7539ec453fe222fa671fbb8c09aec099f3e6c9fec1feaa65d8ad2a671ea9a0a5bb25c772d65df2da37451b27c6ac1facbf6d3f44d0d7a4edfbf7931ddddddd1e5a4bb7fbade02b337436e29a5ccbcd554589235b1feca9e4f0c6833e49e3925979185d6c9abf83147af7ff8c4a81d51e21fbd448cedc371a2b611ec769f59b058b031f74f4f89e6156c5867a65561fd29a599a6d56d464ce825c7e722c7759d8d29e5f0dc5afdb175f34d4a2c03a4a5793175731beabc18ef6badad8dc9e1f9bb6c6315388491638cd2bdf1d6db874a40c871d881dcdd0e8a3842c4124444c18148a7f48e3348a440b27303e48424a4c822c726a28081393611054e96e20a6b851e1a56e899f1f212a36f50625f60c0b08187f501e271972a6841305229006831a9f964abfd68405a50952faa24a9961696e9352615622fa8106bf95f799e30f64ce14ee1555450356b6145bf5440f0245beba38982507c220f582a91eacbd71a2cae564aa9490a38d5555dd5555db3279d7396bc986edb6dbbb3cf322a6a2c0a8a829de19c9024c7269c10450eed2bcbb73936e1849dcc79e740144922736dc3d98ec3997947de84820dababbaaa05bfbaaaab2601cb3f8028a2732712db3828cbb75e8caf66722ae6b0b9ee1d882245f22b27e1acea7295fc98579d97f054cc389c99025144078822b098d54c8e99f3621c391045703c1573585d4014c91980b74373ec401429e2a9984541d6f5b646071e5461dbe774c76197e7574fcd9f60b44185cda6b0a1168bf9d76a2d08bed47ab28f4a9efae8525d2e849a4d1c6a3db91bcc9a36a5b0596b980730cf9a698e7e7f0c683dd947bfef54c1840b4637c103213a5a68f94b93244960ad8dd342abfe4c4ba6930872c14f0b8836c4abe52730c2056b751039383d2dceb9dadd44f5cf23041581b5621334e802acb55d54f74b22aed0e29ad0e29c7e21902c5f1601c418ac80b5b6db4958c20d5a9c4c424d2bfeecdcd53af82102d68241820e602dce3bba3b4d424d8ba3ddbd191134373452488136af80418fad5b08ac30841308018aedeb572c53001f14d1696d3fd3fae872ad14b663e4735c8c2e60ee7087188967f6f3f20066f9dc123e382d99ed81f807625d6819a13fd3e2eaddae06244f548f1a62548fbadd0da37ac86c37e419ce60863cb37700d843670cec907900b3b44fb0210f5a4fa61877b43f8b393e2105163f325a145a404a3768d5dfaecc5684a057ad0f240bfac213ad8a89a0c40e4f2b36210b58c05adcecb61b7b9ed0c2ab3544154960ad7a5f92687119cdb2fe180e6010d4aa57458816a76df5c6313c41036b6d173ca275830994006b6df51600084880b5b6cb95a1c5cd6e86212708aed676513e68f5cf9013c05adb6d21d2e2b26e5ecf526605490b08e90632edb2421052d8b607d251c4a840446bc3d16984367fe1c75a0127fb9754b2d7583f540fad157a22212c03a4556f6b01084cb85adb8d4c70a2358ffc4c11c439a115df368ce7f8dcd6d56847d1468bdbaecc34b2859b16903a8528afb02f5d60050c3f91d3daf0dcae4cab800c38db0371c1c2075a1b6e2888008a22e0b4647a053fb11610bfa2159d4658cadd5aac510b5e2822a7552f87841617330759c0b1aad75ae7126cf7305a5cc54bd9a51c92a5ec820887d3564fc9519458bead3b38a0c9dd31f8726c22080e5872dcb9418c043f3b476451022182ecdc400543ecdc4067e706447232a573ce39679451c2d2ef170c4fd1a7947a0d9e5a863b484e13a12df3ae0f201ca523fa23ad6a99dc421fb2a3911d8decdf9036f4def5c1d9ef9eb336f49e7d2fd479cfbd1d793694d1972efaba110e353013767ff4f670fdeee573211c67ac38d432695b1341b7e4ba6bd69f6559cd7a0b7b884f9691e3ce90222fc0d15e60930190e3ce10204de3bc4f147ae9d5ff6cd5bc1b6387b3e73615d8100e330dfbd834d99536a749b811926bc87127063f3188e546418e3b30d8c928ff98eb6cbb69b8f4ad695a93b4272de92f5d1f61e8b30792b51b431ad5ea6bf47f78ce42f5a3c780ecb94fd954107aea6992542a914a25d2df9024ededf5f19144a5d29348dadbf724daf72073e96fb8c8fe57faffe1b9b54f09a9498f3a2b4993d82fe2aca7b8cc95748c92a73ac39a14379cd9ff0867bca1f5dc75aef235ec237df490c3c63193eb9c3332ad71ef495a0b7d890ffa31b7f651d3e4cff7240da3fd9c3d5f06369c3972f847f6a1ffbce08a8c438e3b2fd0c93060e28a2599931e0783225e9045e6bcbd5b332d870f6d0babfd10ccf3a5f6dffd9e7b91cd1af7f6063d46b28f5e1656fbfa212435acbf791f6eef537ffbf7b1bd8faf36ecb55abbb9a2eafbedb9efb60f92f64cd3da47c33b508009b622b1354727a2d0854c73e82eee6ba63dd712773681451b75c7574ee32fa9eaf195d7788a8908e3404427a20d074174f1773258cf61c31a6682c516f538ec3439be5cb10d4dfee159c668db7520220cff94945068d24c6582abfaf1c186d1d139ad848e86e1d130a952a259fd84db4497ad5ffd440d8f8669168cc005d97fc69e7e451b9b10af97f72bda7032d8fa5947bd51a6b773bf24165ef3923abee2e6873e063b7aff4003116d643f82b643502fc797b7201f3c872d7353d12cff40abfc4321139394940e2206db3533c88e3eecd7b66ddbe8cebae5d9ddcd81a017335fd3debfa7882c07c2d5b19387e3cb1a76d736ea9efee83b87eeea58c3f82b7b2cda70ed76768f7ebd57e4f6789860996e8d5c36e4ae7aa3246fd855df5db1470759c314a8b5d6fafdea7ef5ab2d3612bacb5ddb56b519a9ecf93c07258cb2937a524fd75bf5f4a6cb993e74aae0663299408bf2e06632994e2d28b75ba7ebadede44d270f5e540f93098811f9332d2b592693c934b32cab38e4fee4fd5b4ef04be31b27272fb1a5d57aa2d1083a4635ad7d3c828ed10a3493fc3e2ac86e85dc32c8b1426e237cee976dac5d2d3dc43b88ac3d3fb14631cdb22cdbb62c6baad52dc8f6720b7eaa3f9f4e27d3bf7ca5699a667a91ac1da6e93ac9f62562fad37dd5d39fb0cce94fa4e8cb261ca538fabba7dd7391cb346ecba6d9a1be077fa665baa8ed6d6739ca2e12e55028aafc431fa3e86314bd8dc57a62b19a4af5389d7ebb3d4c7f82654edef41c7875f0001f05eba027278f8279507af22731946ed9978db2e9c5505a7b3eb9d51e6bad2dd19e6f72ba3ed03b4a810f4d3bba838d40252f2673d4e41e0ff33b6735cbe8e44e4c26d9aecd04dbeb653341b31ad02a7fd74bc3ec305a81ec4cd75b20706d26d85e51e55e8e2fdf50194417ffd10a9088a31ac9ea19ec000bd99f5661354dd334f71ee0ad764dd1ae5aad8df5d858ff7c6994524aa966923b85069ca5bce1ab6edc5ce44adc77cb644d1d784f5a28d774694c0f721f1764c5105d1ce5533e0505d738d302afed42a4e16fba3432420b86ec1fc48bc5c249339bbc9f400850b462cbf40e3e788202a2a0a0581f9407411005db1f0b6463d6278662358a51171ad5689ad6796adb8c44b733fba826846b3a3cc29c17d36d7baadd70addf979e2b7ddfe9c656d6add82ad59e70e40aed18b65ae2beefba6d9ea683868fcb8bdc1f238c463f9e0a60fa96e9a565fa7025477c232539504a296ff84a7b98865f327863ab0aab499992b25ba64b13c44bcbf42828b7591069441961bf20c61ba40c6e72a7c29e41f61c1b9c5c548f93071f3cf9991677724735239b939307f1a806a3fafbe44f17d503fcd3837874c2a8fe13d39b70bbfa65cb106160740c2844f9340067005b5853ac314dfbedb505892e5b09a2ca3fabb5a76eafad049165635b9068a35b541c9abcfeac662ed92e23a1d378cafbe9cb532e4f79d8aedc3435c3fdc2edb2cd728f4154c5dcba8288a88ad9246f2fc9b2b16d7bc51a6f2fa9f2afd5b5bd5cafefc3ba7d68650e184d80dcef06c8fd6100b27fedf970582bfdd0521cb69099770c15aad29d4ad6def0d49c396ca1f22be7a28b5e8e2cfbd0cbfc50062227689dfcb7bda20d9b51209601dff4332deebbb6f4df8b997f727f3879d30d29430ee4641fd9873ee4408e9441f54079d3a3e010ccb4c0373df8db9010cc57a1ecbfbd240bf515657b4956add55a1044fdf7c4b08da150b00cca9f7ea6c58177879b01a942f548d901a3fa6bec512eaa47caa37c0ace0046b5cf8f54a11ae7e02df0415c7b62523545f46236b4b19eec6f631649adf55b87648dea0887d58a70add68e6abcbfe1dbcb93c2ba8ee46efbe8e5186ddf8dd974632b3bb93ec09eb042ebe4f281e6d0c65ae4de5ed1c53fbb9b10d165ab912adf46d0297fdf6c3613748c89850db7ae2f7df9a1e88423b2dc2adeb65ab58c6aa2d831fa4739248780125c6c0967565d24a831198d666adce0a9e1010eb8cb3d10570d0210c45593a05f244841d7d44bc4fbed12e95ebb44b24be4655b5d440f719577d86ba4ca26fbfb8da7dcc48e46d6dad18887a7fcedd521f64c89ea8beab79fd59a551729282b5ea7d222c5858752b32ccb4ab594d5d2f3407dccfda54ce35644df5dd37bdbed1cbbf7be6d0cd1acd669416ed80cc6607b78788ef06446e448d60f5c073ad93fae5cfb2eeee8bb877e8a51d56ba20d1444964f11551e7a8dd764d96f3846ebdc890c8b299bd552013e1975cb3496e83f761cd8391444c9baf43d4de869ea07615b26261f846da134bbe2a2339d4e482b24179b26d2445a6b221cadbba5b7d7fbd31dbde98a9e7455fee4a6bc0b23127563cb849bdda49ddbb8107f4aa9a7459c197ad596f7a8fbb2add29b5c9a205e5aa57fd996f7d1eb616254f683911ee08ffe07943779d1fd01fcd1c77ad0627cd07ec331d50754867994da8707c4168dcaa7bcc4a8ec21e0dd9f6995baf75e7b0fcb18d1700ffb17cb806f1ff5332d0ef52d018a69b19816fbb64fbb3eec904652b084336422df4340e432221f8891fefe954ec4d27db4b169357bb000a20f5fbe8f47d84126e2bdab421fe26117e22aa731b23d4d10b6d57d10b5e534af9756f741d8d6c7d1f055b8579182b8ea23441ee7f155e7c4d4113a477a4cf433dff7b0ff7dff87658c34eef1bd08cbfc207aef07233f7cdfcd540b7a2c8f50fd26ef635ff410f8de04ff60f2df8bf00f467a98e01fbc17fd87512d23f3c3f7dd1be9e1bde8adfdd8ba2637e531ebe59a438fa1fa7b7cdf7d0fd17b3887efbb87c0f79dc7b4ecef4092e57d504ce56f78114ff98ec3783af3588b97351e245f2db49864dde4984f863dc7711a89f4988fd3f022d93ff3faa3c7c3becdecf5d8c5c9fe19ea7edfe28aa2a7611fe8cb0ea3bac5f530aab996dd776d6c86dcb44d4cc724cb61d5630e83b9113a47b4ca5f74758043068be383f612a3da1b834f115ddca968556c19e1d734429f42fef2863d26069b3d173d547b1ae8ac3d9792eb8d2d4ee5762bbb9c9671b6231224374eacc29178924e0601b9cf39b7ae92dec505ffe49a52ae49b7a8167251bd181ed5f425151a131eddff98944c2009b45917bb5100445df77d9fedb21aedc8249a68d7f3572a6559c9cb1fa9a340f828f90554fd995ce9b77caed4695a777796b5b649eea58b3a6818744edbc4eeee0da5ab5e8a97a3332a87ee4bdfa3fb129631b23d0acba06094f6df9b7cf71bee61dfc3322046653887ef4d1ea5e11edf9bbce8478fea21fad18bdee49e7e744daf72f22dae8bffbbf2f5f434276fea3a9bf2d4c5af9cbe7bdbe2ceb8da76a6d30969c5456c915cd0786f9f66f4268ff278746f62471ecae341f3bd68abbd4929a59434dbaae88bddd0a24b49d9b6dca2ebdbc28ba1dfc2cbe1995be94457fbbe2f9157aaf56db5e246a2fdf7a24c52a0ac4a9a4517a57dd7fbef21d0bd08ff20faee3ffc83911e228ce2f13d0a0581974b5a228cd27ef4b1d5fd0f1f4669189583e8ed43e0fb11fe61f4df5bfc83911ea3fffe07fb22adf3fced27f26e6c75a3a889ee0e330c36e6a8d56ddbb66ddbaaa45385035e59b9f7b2384bcb8bf862464f4c06005a5a68a08186ec55322e21149170aad073357436441bb2ac9272d8401ddbe5976d7186e3388ee3b82dbb3d51749c4b2a55430d35b8745ee3ab4e04d99f73e9425e8c0f3ceca8c5774fa3f2de47affb950f81c7ad5cd3bb3879957b7a14f0b593373dcde94bdf17c5e3fb442b2d6e6ca9c48cc234342198019f86e6e4694cff3dcde9694a2fbafefd64ffd28df99fe489bca4fb91ee8cab15932af7e99887ed85264303f5171a8b060241f6e760bcc4975a6b35c123ebc3d1a0d1896e6ce18083c6b5d5babbb91933bc18f933bc1c9ee97f9eb955572f91ee45f7f52dd16b77037503366fb8915c9a20be25b251aa3a16d33130d898bbf79e8a68830ad1638d4397dcefef554497425cc9772f6b1fab9185eccfad3a3b9f63755f8d58a3e5475b5bab81808068e5b45a535a9cd13ee6b15ab5e8125da6f43a2e562d4b45977e3fcd847c035770b125fcf08b54f9774ae40e073b393a913dc718de805e658d56a1431274d0ec2cef1f760ed5613640870e0dd3af9706346be5fd6a98afa763ec2057cdc240bf3a9dce88e8e28f812ee7eb6998ce07f108207c3d383a1caf699bb9c4867d53232dcd74792fef1bc97281b35aad05c1ff2c4873bd3ed46ada7b7935d3d5d70be2a9aeb128393a71042fe49ae30e0e82a0d9683792f51f19258235bd7445c120aea1d0df90fe9d44ee6f9c2ed2a2efd0f77f1ff612b97132879adf79fe7751b3c70ee784ad59fed71ceaf66278e8e0ab88a5375d3fe3d581078f8d1fc61e9e6ad7fcd6216fdf1e0e410e4755c881bc6d98470f1de26771fbaca212503f7ec51dc6402acff0549d3d7899319bc653dd0345bf5114f3d0a109dbaf7eca848d4e80012887ed32bdfc364577a092a740e1c40c7a72587756b024cbafb54e0bd45abd258c3d31c618638c31c6164fb5a499f208fb337c357dc6c76ee92f2538c1cbcbcbace1da4e98a7e24e8eee309f3cb2c753328adccf7523c171f30a1ba90e3d927b3c15fdb9a0ce22c7b0460eca812cc1716d5dc6748de97278e66226bde717cee4185d4e0094e5102eb6849b8c5c9d56aa6e040046434bda5670df48384c7bbab32683f55563db19fd5985d5eaf47278069674c3bac900b337326081a8775050f774820d1b166dec3c7542957b8ab0e4338e645583655b288437dcb00cdfdcdccccd73966559966d5a0c7dcdcbe13ed18677e4aaa7fc3de52b184fb5740cb73f3ffc60e2ca474cf9fb509942abbca78829ffd89238ac40190bd9bf379ead87fbbedb11236e8e6c3c9dc30eca32c7267e40821c443183be416c1ac41591b8a2add33bf0e1baf6912eadc61bde371bcfac78e39953c36175b58b6ab5d6ca612d7b99b1b5c785640d4ff94f0d6420cad40ebe92f886cbef91d75d3d86579b81bac0861de45fd7680d64c053357cb58367c0571f35c0921bd7d8e1469c31460705451b59441bb30c91b5f17808f2f6040fe2135dac007a42c3e6c60383c178603cb08d07d65a07c1c40044f69f4264efa02136dc78361ec96a18cfc6c3d31406eb9ef8e6e6e606470775100cbc01f9cce63448307d68f3744bd13d3249c790a259bd05da5b70e5240de342c43190404976314497971822cb91c809f29ca0d947689e96a27b22d092a02c7c95bd0f6aa4ca47b2440f2ec14211c4440d12493812116603354b1b1b00b3647dee4bd8b4cb5bb323116df4f59ccc8f78ca63ef31c9f21f57810dfd276bf5fde7c77f9cc77b64fb15312918299a279e21676079fc48f6ff71204f491c59444a1bc9128ddee4bd1c1fb629bd7d9ad25b540ea41f7d0fd28f48b807e94db00c09d7902aa72db0a1074d1d31124f6322a5971e91d7b74a188891faeec5689e05ffe92df48fb320b2dc2503690412d99fd3a6ff6ce127f4f1fda7619ca76378076da1596d86e93fced3301eeb181d24599e23556d8666b9127e135dfc43d751a044b362378ccb20c618a269e054647faf892eee35940536f4a09643ba59a2ff3ef4217288bce1beeb2d596b0d513ba461fc458558cf3ecc4c9258d850dab4af44d93de87b2a6d244f06a50de841d483240eeaa0e963901e2443548668886ef2935cd7755dd7755ca8f3b890c77d5df46827dfeba8102b4d4cbc182a6de48dd3f0efe7954388b0d2e6a6633d2ba02ab01e84cae1fb1905aa5fde902eaa310fd9b1ee0922fd77ed735ed7d75f397a31a81c444ffa1ea227611923fd32a517bdc532a17ed548d5db9452a4d748184829f362b84eda601c9deb7fb7753c1f1ae76b9dce91aab075b247b97909e80fada7b86f4ce4fbcdc34044d8c87c23fdd58b99982b79aa13755488a5df1ef7df371b75b246a5bb90f4344dd3340db714d6b3d1a59fbbb3442bd7960b6ddddd6288365a5ecfa75357f2707c59e20e1262650e3b28069543e949dfa3f424dc83038d798cdee463ab3d1f7a90be8465768852f580d8cac0adf9634bf4610c226123dac7d6f749985c79236d5cc773a48dd790bc8d0535639020984164886788abd0cf9724c8fedcc98917137a0e8c60cb8f7a8d87110935ddddd2c32d85ed44372555b5aba1f57f27ae03f79c18c3df6ba29c73ce296da48d8ee9d3b94b0fb8d812bec8b1383808ecb2380d93ea1ba90aa259d806298b836dc0a2936a181626f08d64b1e880c589ec1fd6606f60717010d81555fe60100a90afbe9307abc987f64ba00ea853239f607c026b98ec4b09e3a46231f071e4d4a48cde15364c1982729383a38392035b927d98a69789c6e42a0929d5982c61a263619e7296d8e3803ab297e489411d9d2c31e6799cb616833a30a7e13f31b8440a6c08ea747f8b2127ab726422c806acd58be9d956da0fe5b3c43cc5e2c31263f1f19514813a12d491a04e145d161f96d92f8a9144467fc38998bc7c8b8f78cae7fc8a6b7dee39cd8be1b86a5dd52ff262448f7b44b7f394e524c63d18f3c88ff3dae7a817639bc5a79b6089bcbe35c2d3556de5bfbc9b0aecd411e3d4e45bda2defe77c91c761f1b9fffa97afbaef99e51036e6f071708faf624612450ee5b893031c983c1020b2090ab89b84ab43b020115d60d1e567167262f61cb2e4d80ff2afaf711aff3856f4380a4f398e657f9e23a00ecfe3e0b0fe0ea8b384b358a6882a7f2b76ae70048c22f7d0992536025bf1fdb93e1d0e81e4f0fa6497cd1293200cd4a143d87e8951dac72c7a59aaf176c89f436a575fe012b604c2280a743e9322b2d71dd49c27b28565993e0be6912c96585831cfc7126bef31c21579b2c4fa596238c812ffb3b0c41a890f4b926823f4fe2f6a7ce5657f962a44d6fdd142be4060c87eb1c8c2bf9a23ed131656731aa6c5c2242b659f685600be9a1380b639b961aca5c11a6175a8c5a9b113477e5f99bff7fcc99f58b021a883f293fd0abb84a71c84658fed5ff6599e57d8f04631afb0e10c969864814bb8ca7fc7e7c84f144048588292b866e410d46979655f92fdc3961afb59117e71f302e7043664c97971939384af6aadf2e75f14e129ff10f3b020f114668999c05afc0247845fdc94c0862c39f9458e64c961c9f1766c1fa4c66297a79c06df04b121c637d8255998076317c62eeccafe38092581afb468e37bf7bef3bc0f6deebc0f4f72f7dfc5504417cc135d3e169f0fb3c4304f7dcd07cf21e6f181661c6b71650f5972b27fe631608b9198278f1ef38c2e0b4bcc531fb2c458ae8f64b150c1d2052cb0708158a6707f5862d1c51b1f1981c53d984708bbe107fa10f3648f614102aab0b0c440abe13fc212cbae03eae07c19a618d4f194ff94fffad7bf58587c9c86ff8b0589086cc8126389b1f858984e6c0b6bf0e53da1fd89a804e4c621906c61282bd05461823ad91f3527a823592717ec480c5492c31203af08c19dec1b10135c702287604ff628e8e41044921df4017f40c912f35568612c487c159360c1861646b1605d9e921e0e9abd1c20a8695503ca618db086e693c31a5a2c8735e6cc82f55c5df775330b36b4b0691292dde41666614139ac91935deb91aa7e209c9f1b1f1b2d96fb433a7b7258b31722b781022eb6709cd6af4e02cfab61ba8ee19d84669d3047825727a1553cb4a4699aa6f59749b66b9895784a65c72bd93b97c98b3eac16e43efc30e5f1d4c826f8254655bffa157e0f4f71c053ae6d37ddf3d34b9264919d891c7634211892ec841559b8d62f5f85312807f155a442f6e74027a58d9097102d84cfcc2dc408a20d1fda957b3040de40967b0326b9a3f6d246d6784ada80a0460a91363be2ddc0c4d987cd933f6bf1b3b8e372e509821cca1aa94354f9d7ca23adb0312643b8d65a6bf3344fad294fbdc89bcd453be0624b2875ac5e5ac7ea4547c3749122451ac6fe4cd1311fdb307d052ab27063b418ed632c4f2fa6634d0177bdecd356fb380dffbe1d03c2822e57672c87c021684d42393a0185128a63b198cb25b94ab22ec0cdba00ad8b66ad762c02768ab40cece722b6a70514f09957a03e314f21f980ed969c1e847b931fe9489695ae174e8fcdf5aadb751a4f1961495f179f1b5d6f55110bc25ddd8d66cc837057c71a068607d1ac55abfc61c460344c178191fd8b682514b87a892d6ce9ca74abf435aa36d5f63d57bdfe86d11df420ae340782bb13d975f0735382c8ea570884a0e15ae01fb01dc371c51c05a261befa3ccff394ab90c1ce1c36acee348cc769f85357ada0d73887fcf9efabd1839efa335857f194ef8854689864d51609e2e61ff077104417415c69efd9444f414640c7f0effb518ce8b90e7d059243df7151b272b078f49265dfc70f99e57b0fb0d87df40024771f7328ac40f2eca17387c3f91a98c935477df9dd7f437e0d679ac753de3b9e8ab336cc0c3674d73f0fcfdb6a6f0d8b365c4e2abf19dadc1d8b857c8707060b8542a1f7cdcb616f5b45008d91fb77720f8c141e60f734134af02c2136d10426786761d1c5dfa493a352b4113f6c3164ef2e64ef2b646f2b4a9854ab09b61837f6a173d8319f7e4d116d38102929a1500576a0c09c73ce495fb8b653d4956eb74837b6287045f60f258fbf90b8cbdf69bc631cf572d48c8990fe866f2498a79ea06301bed2b00e9e721e65b0a30f63a896a894acb496550e33453302000040017314002030100c08c4e231993c1225c10f14800c8a9c546a5a1b08b42486510819639021c81800010011008160da00efe162893ea75549fd6582ed44820ef6f66cfedb98dc50d9fe6006bb729760f5223bc089ce170de95510c071f9f1d7edde429de1c83d2f63122c75e9a0046ec60ddfd235ed08a16a0e2f0ec99668fa5654d72d84ba6108843e8f5b348077fcab178fad8b5c7e94e6a9e13d8c822294ce1ea61a2fb84f3dc04688038f600cdb49fe57bb6b2c5efbf4406f0eb9ed3c994048326f3f4d16271560c6b79344e7e27b56343be3be9d1b5540d9cd0a3938f450b9fdd353cc190a35b445bb6510329e827b8df1123fc67489ab718a58cdfc08e771bc6dea374dcd329bf66599c2149b098c311ac834dd865c588be84b53f1f4f2dfdca2480510b57d62d1f9c198978a09d2b06dec535601101e03113961f3f11211552c90645b7dcbd108a512d31d4b3784e5ddbcb18abccf4e376817eae7119860b4ba03e5058f94ef3235de0c71beb1d756e294d42eb0ac3664d4db5a3394fecf1007a392f99e21ef58af5f390494406667c7247bbd7cba73d7522fbc9830889266ec1b574449a767d84f95dae06cc3fe4889aa7e6e31cf8a15b3f24d49b6c49aa2001d53b29375ddf8d5df34355b34fe87441bdc1a7521452772c65144287b08b9008b19484a1f2b31772884c3972a56e2b75f95e357b0bd1f88b3060257e6a2a36dd235d830ec0f8c25e19e82a9505998e0121538645aca24b82eafada50106efe6c4a2287c1958264d1672300d35b0414d5c4670cd651a7b6a30da9552c1fac3b4e4cbb3215d085ca931b380cf7828d83ff0a265adb899ad0f1c1fa750b3385bb00d14f98897e0bbd9386b97ea7608f013130d5b58a2daa0e74b92eaac3b04b9e067672bad278c899665a97d21a06447beb63e8765e05530be514c2e1503f341376d1135f631220cb0e33bca9144c246419b6879a59f99e729b193974a91d84bf369da8a235da5003413b54a677b594eb47a9b33b0d1b2aaedf14159f12c5b6f8d849a60141a7b89c448ee2c3aa6581ad778c64bc12141c1dfa5307fae5694bea904f20716f5956ce06f62993429583e2bd7804f63f900ffd4127d5a989f68548485f5d61904b26c1052cf2fc653b7903719243ea513f28accf9140d42aa70653705c773d6345931856a192632de23b6bf8052a1c53ce2ce2f099c1a1c0424a4bc1908eb7f41a0782789bb0ebe0293d0927bd054801309934c2ffb8b5e1976db0eed00b1d724c67f5b87279223be2f8c5cfe3cc11e2ee5b1c04d041c3861b98eb5a0215ed84275e98cb257824d3dbb491527aad566884e8112e49cffd337c854210a9dcbfb54b70a31a25a00675b783f6eae20f0ce70db1941f2f11f77b8b5ea0341040449e9ae406dd6ede681c08c3c2176cd6c25a2f747331104d162987e20f81616499f0f2c22f9869a34a31cd28d1ab62936a4a58bcd6e7942ef9d215a835d1d556d98ca1f5f31ecec7927fc205d6edcec9675894cde9497333f910fed038d3f1695ab41fd9784390ca660e8c7130e813a076974d78ed2d9d518c1fcd9875c58a7342c6e0a33c1042b47a20bc34f022a910c440a135069230a36652ab6c9f63828affd615ddb070c2b3898fd73965721c4dcaaa05998add7d5b6bd998ece286b528ec804261c6a4739d5ce9825e006d482094492a5a8432f8bff1421963013e6a0082159849b30278d7b38b13d30e55fdf5d7f32fa28a51d93ecb6444572f56d2c4440220c30786f7795057c25545e18f245050bba96ba2e6e02bb82e88931a1a723480337467417166e1f16d2697a55f4d3d4dfe121c74d806ab78174a8f49f7e04bd38c511344f9da9d02a8a298c5c8d04ebe223bdf9368f4aede529e3740c70e617d975cf297d5df1f32a6c24ca7327856c67e5df4c04310db61bd84aa0380651a1ba81b51f5638d24af1bf136ca875f708412843a072c2a0c9bd2c6e15b11d2b539cbccac6ac65608a8fbf23ba7f5a2d7499909e719a7895d20da3d5d4d2571e8cb7358db301c88c365a5ad6eef2138f953e6617fdff9a398489c7f10744581583074529b182b4d98991152c986f412b882e3405be43c07006776ebc608fb10f8ba7a726a5aca72e19beca1e6ef723c9980155be4d996ee4d7a5627cf77a015024fb819051e85a6d8bf1b3696f90d9afc4f1578408e6fed969c2651d8bedf792ba92c4c34f26ea5556eb7772fc052543bf4a16f953eef4ead4566d68c4d6f5a78349dde7f8f4a1520870fa70ec95c48de82138d10cd94144f728a4ca054ec0b4e7d3c09657e9d22a5008d1dce3c7a0ea6f1ca54300162069659400afe84c42aeddbde467c4c6a73d036066d4b5e0ef67eccd0c353ee9c280788953a8093cd611f6f01f7002bf91f647c1cc214450db2c420df5c75d8db468a59193ac99ef84d26ac68458dd952b7ef0097f44dd25dbe1497d0d9e5b00d2a891a50bcc3cbaab892e3076f76074f76fb15f7c45ee7f662fba5fe5314c0cdbe8cfc24947c7a728bebbba7707208a50552300a8d0a5d9e1af7797244cb6495c1b87661054fb442a9f8c2b36aeee415ef9980e0388cf2dc86b68574b05402c8230d7261ff1802aa948571ebeda0eb89def5ec9c638e09a06391dc6314361a4553b4ce20aa30a045ff864bc11916c818c0de6b607ff424e84ff72b343da0d37e1a37039af9167c1ac0a040cbbdc69b8f412a4ba72e740d07aaf8071d140560f3c459d50184656f50f93a8f11035c5e3d898a58002ccbf636731006f2d73b2bb6a46da67303b59af6d45e279cfe4e330878b23c21db5d70ef8d2d0959d51eff200541e3e41edf8a1ae30bb594da2ccf9926ebf945c541c952282f3f9c76cc5b6e737a1dc0d1d136021f3d7296d507a1c6e8e7ba2b9d6815bd622111d73f99132b88d8fa2618ec7ff80f71e23bd7dc3bacef15170bc401ee21e01b06e18ddf1f33efd57138aef14c0fda80a8f022c02c7df4dccd1ea4e7bdf696f98a228505df9410d96db86e00783448f65eedddabd8b6189db0f94dc48506a78091797ce98405fc0d494f57a2f788721047c2561343e01bd475d753a0a6d5c415188802c32c4800540a7c8a6d0bb4a0dec5ccc652edbe2b0bb7465bd847c2b2c5367032b3c56adc714e33c0265082303a594327fb1d79ff29b4c49dee8f5eca7f5ccc14b81d6cf01d2480ac89940c028f30cd760bde3a8eee5c21072f17f166dabd1e53b6828ff3749771b95f93629a5a5ea7d51818276a611268d30f099f1bdfe6cc9d2e68ad624666269923d72d17f8d812d2793c03d7c980f9ec5e8f5eff4d451d6df7173cf497e5814e2f9e9f2bfb887428d2758b34fa9939780014381f469e0c42b0a2180638bd9730ccf78d95d210ff80ad2983afd8fa87b60ac48370c328d8ec94ae63258ae92c412fd64b473ea76d2b8f91e421997154ad76123ae0abc01a2e23bcea4f66dd39ff536f4ce4b7f1e83ff84690d0e262871a568878533869bfbc164cdf11b2cf59c843a2b3680bfee340ce155ebcbf1328feb83000d9cd4e7c51adc48fda3eba01baac3f0c9d0738f05faef13d2d1c8828d5d35ffdab20a2ff3debff345ecd633af1084dd645dc8fd295deafc0fb783e938b5b418986509df6ce745fd524aad590ac92ba3011433d8c6da0861e04a05558c0224fb95c9c1d93ccb01d6d58ba147d6d0442f8881a2d761a70f609072518bbb6510f12a66132ab89eec24142d0ddab6ca7f184d48107c93e6a1b360996c9a1993a832fcf6af5cd978e950c66190b83403b613286fb0fa7793374c2177c1d1967d9b890e7167fdce20113fee56f3fdc0bbc60c1a511d56490d693d07cf9d53a727c912d5816f5d22e856c8a2e855171f6b0364f70bdd89bcd8062243e7abb8fe1467928b339927901d339a905f2e1421f17cdc22897599cdfdc94358868d968f2e0fd14d170d564ef36dc761055cb11435d00314a0edbbfdd71ca73dd4fe085522d21e958a47913f8bdf3393921768e1e91d41dc7f8a887153dc594dfa212aea801ff8c21d6a5f41610548ef1f0bb6b25674f3de4512726abe8a010f7d72a2bab7b65458b590525f1d72f04f348b57ec48ab10ad29161976ef29cde48e13b34cbc2c82af5a01af1229104429d668f95f1fa3ee8f03321b571d103c5c577f49df118f2ed461c9ab32ce868eea2586f4c4c6aafba0a878e1c8ac02faa84c4e1095d55092c572a4be6e0dc156fd60f64dd677924c4b9f35127147f75851a4d9f1207fe803e687952151dfca9ef9057d7ce6bda2a5e79ae2a6c0668bc42d6c7c8c8141eaa2b5338c7bc19155c94cae6efcc21a0359accfaff08568d9cc4c9c344221d661d849359e847a40fdcebfa82983a41fae6a40209dfb1b0d3fca17a3d4f5e3c1fb63e398f84fd2e04d966c4a2be980ee935770063241f6215bbeee73e4d0751482a2fb40c11917548243686114c3c20bd39690836599241b3782eef87dff2466579c3c1b2c681323035a3454d208acf902391dd9dde9a351363919c746daf98546e99581b20be9fb2bc1ee767688cd083a6d87d5a4ef180b5e667f109fe5099e7ff344802939fb04e253bbf0b58046550377ea4821e1a0ff24186c01f049b1605b5594444bbb1dfecee05cd80154e6c7c278904cdfc85c9e70cc903f1844d3f6275d13da797eae4b37e4b281750d52a67fc8782b9c7b25f71aed4e02ae50bec86e5cae8579d4dd5a90f538999a9ea12cb485f2c000e52ea2eedcbcb53a1519a369fdab7e5d388f1aafbe50b1fba4fc07e7648c73d4f8d112de8862136e751f282a98000c00963f9b0274f5975c1f239f2a128e0e157ee2c0fc812b2662183c4f5401417ac0a624cfc318a6a8608d7cb4b997d8d2ae91092e009347d825e3a0523dbacd23803125604aa6b358e86d2cb0531c839800e0ce4cca31cd8c71dc6f8725934d655454ec2c7dd7ede95cb3cf1bc89044de9228cd474f71c371fe5c5b4967a3003069c956b797fe38043ddf767222df392876b43a73e6e893bba4f9a149a2f9f9ec21639d07b3414b5dfc17563b6cc9cd92da62c5308556fd68fa7d31d5a007a823259de455016a5648abc1b78781dd2f42941fa1111174b535f6ec8949f4caa108fe50dbb0eeb358d1805dce82d1527582db7c00d47cd70dfcc284ffc36ce9e6142077ef29cdae41156756f721cf2726f6a0152388735e4796c8572b95570d57804b461e9375d924d8163ea5ec4ea58e6b2aa78d03461b52e1e659b5def7fef4d7d772f9a4da0c81a2b6f6dd5a2014be429293f0857a8a67b3fab5456990e23664c632b229a26941e308e6da69c070142de92e3a44e0e34839762f6c729a62b6b36ab44e08723c61b8220cb718c3dbf783f6a6547ccb576730d8df1425e6e5f49e937aa7830da2e9179cf7eae341fe73f29eef6d9efc6e8cf9f0158ac1479a87652669606acd1fdd8b2d8830d4641c3286837e9888b060719de1f4c49450f5c2e7aa36ea526b8c42e47ce380ba1607fedbc207a46064c4c0b6b26737cfd8056247326884f01e803a5348210e7079c58d75aff6a14dce621f580103d20ed1983e1c59f7fd16c86ad06acccdf10b07ad83e0cea514214165fba418ba621490b28c023649c8cb1ea66ea491dfbaac396ac052201cb5b99979802d0ce48dcb5effcd4874dc90604e49afa268a38a10d1871d1ec513f6a0b2218f294e5cef14664f7aaa97d53861b902c1e41d5a528baf4cc9758f8c094a11dd1d0e9ccb04b01621934d99d1348c0079f52023d3f2031d47e8a16e80ffc2ce6f8a057c5cb2531e4819614df442abda3bb74cd7b9088aac66b4d3a1d5e612c28356a3ba84bae412240b2801733725177113581e64f179d37b716a98ef97571bc579c4b42026c98f769bef4ed671738d1edeb2750001d79278a71f8f83e2441ec630b4d1c643129adb65c187b1c98a103f316faac84a0e24d46b09a61326f398ad4cff75286fd529600e332498d6bcf5f24463bcb6afeaad119c4af1aec5fdcec81a28b29da74f36bfee5511c44f00d39c96546526c7074e4be137c648e6fc13195c8052679f53e540f5a9721c6cbe2ab607ff32f1432f495597b79134158e8ad5fb25eebf9b9eb3ae53ede2f89b6a8a0f5f09f81387a7028224d559b2e28196d42bfe5c4ab098fe3a236576dc35771ce1f617a7698e59d19bb3b5c38f234dd5ead176ec4bf2a1191de321e8ad6e11e1c9af5312c747f9cb8fcb672040556fb6ee31e2d680cd01142ef9c116d2c2d9929ff3d56a9ea019cf393556b2f623b0f5dbfbdbe1aaf48b472a2c4f721769c1d75c3082ffb97bdd68e7ff04c3d3d8fae1626215c787f46fa15cc462b81102e0371a677dae9401824cc9c0f638b4ffae6391f4fa860e32919380bf68a5b162361765090bd891546748425bb51f79a216f5c73d86b1509474ab881559c134517113140ca40a613eddc308dee1fbe961daab8e4764ad6af130c27ae6c46e56caa833e08b0be8626703991739d722f5858b25f5b2a8640f65eff5a67b4ba6aea9a6a5774bca73c59081375617df277169ceaf40842ac57e590ac00abc62c9ac4f16a58c151403d5f1ebbf823150edaa91f376cd10798bb1a1546d3d8470b5cb35ed0d84ae55fbce37843acac2e44cc83d403f4b9067d885af21f0a93f3de6df40ec46ff2aa6771845d76713f0bfb8135a2fdb39918c0c5809ed8739a532833196ebdb9fdfdffcd3528298ec152503cd8762ae7a7173bdb333d6b369df82c3517850625e39b0872a3eccd43027ecf3195b1db81af3876c4003c8af5f7877223e68bf3715e86d1d6912f576204739333bca1453691bfcda57072dbe834be781bf53464ab54c30a833031b44b124fbdde4e986258eb85f0c349c49a91133ebc903f10e17f8a67601736a451980dde2b4bb44953b3f69d44c22a974bf53a606ab69924d3d1fbc352aa0805399fc80b8aacfee9ea2aaaf46f1f16931047d835836a4fcef19bb5348162bc18e80090a2ac1f25563bed9dc08d57212d66ca983c0a1ed93660ece10e886916983ba8eaa2bbdab35b600e6047e1208aff2c3f7bfe62e1314cebdccc1b8c6e76a99c79a7aea1f18e46264f02d8dc9914d27d25a685eda16307bf172681107b3ee2b067adca0d0894464b47a76ec3bbddaf63ab24a63f5a5810d55c6b5c3f80a119b30d0e080ff63cc4b9bfda432428571f2d1b10e5bbcc5388920caa7663983570f5e1d53b8cbed1cc609794716613083bcab49ae3f8c805b8dc2344bb1e788921bbb9a1ea4299b650e7ccf4a4370b62f8271c5876835a38d3020817413b6c31ad5c80bacea3d529e0ea399d6206122c675e66a7802cf16ac204da4c7f44f3062426735f87486632fc38cd09110376b334196243e069969ab36baeb642c82aede18ec7c05b367ad92d96627d20836dbd469b5dcb26f48e8697065dff9f84c2397ce7af5ad23969f9fa27da77700272e62b6496d7d87112faa22b26f98680d55ae92629ff66b327411f8709ab0a0bf73bf3ccde4d06806068fe90eb3edd6a852e98c06509b4a2d263243aa47030e03d1a87974ddd92d0b9c4e74f4ecdede7af7896988fba54d15f1de448c9e56c48c1e2687ac753b7fd2a518969ae3856cfe6466fe063904cc088b2ee1078326266be9aa429d6e37e75ec03154a7eaf26a8713890dde12ba1811bb951b65e28ed341e17afbcaa721c031a18796a753e253af5b9eb67a3bcad0fcce57f5c98cdbf350eeb042c2e078c5bfccf1ce342210111ce58084a6b7ec11462865363e38f9991232aa55981fc3ffb57e04be7ff0f879a1462be87df447d3991ef078fc267b529361c7505277e071be1f24fadd0e60146bf2748a9d167042131d613b727d6068af0c373822f59129807213ca7a856f7542cd5ac869732f8679ceeb7e67bdbd55f0ced93340eed2bc00217be4214ff9c7e57d66f709f3532ead5e8eacf4964efa1b92e10b34e177468879b232da787afe7c282616852c7ef694d56f9c616a962a2d92d1becd0cfc1d4096049588bf8e841090d579f425a1a866b99082aec5ddd910af04e1542ef5a02b56be66064be69a6c08f30df19c52ce93f0ab9d03c9770af69c3045b6a93072c63fccded9ee10ae060b94a62486004789f00c913cc84db34980aba6dfbea2ffcc2540c3b916684d02dc9273d76ced570b76038c85446e45ac1a41039dc7b0d4acd880752c3266f4fff68350c631a59c099527cc886bf63898e6d00fe546b6489627f801059e9a1ebbc01ae8a83c42ece82ec166683f4b9167fa2ed4e3d4ac62be9f3096866c5432c9f3418dfdefc38c3fa0eaff06f8343256076679761724572454a3e7c03e05905226a153976f3da2eb8b828876923031d133deaa830bcb0fb75270d407e19142f31adda43c798f39790034a6dba3c9506e6d096d85cd2a58eeadbf2b123cf644b0cdd9660d0b131e2ff31cad92f10c94d0c9ba52172e2caf485dc2e161a2818c2a36a298da96fe0d1b8dd6aa8bb7881a2edaf179015cd1aeebbba80f2daad444a592b7d97219426bbaaa439611ba5c802400ae3f8cbafeab649152f103982dff33e909f306c0f54dc9d68bb1ad33c93b18def3433739e9d69b09c83e004b26b6a0acfde2a0241991596908bc540c7905c1b08952b01caf06180e7752b2bd7f7b506576fc7d72166258d6e1a11e90e1a8ddb59614f6c531e0d96444d8d6a7473fc96a6df60cfac6f93c7396f81edce2a70236247560e6fa065166d583c76a7e4dbb85ccfa55271979cc0ea9bca4f468b151abef09f8112206f4676aaa08b64b51ef0b8c52c6899d6af992bada0df2fad79f16877046fe05c0806deae43d9420bfa31752055ca7feefb779834ad6ac5918ee7d0eb4743da5e736828f4b64185d4066fdaf63c29091e96836b07c29cbd85c59d4f3ca44cbea4bd899d3a6f9f6560e7c1986290302b011e3387560be63621831a17725106f354dcaee2f04300bfcbd2a1df4a89a24831ae461b033c476a68978e59591162160047dc28289c5b2cba0c2c9fa4446966171a3f19f10f538c4ab6c02c39a795a1680f00c6090f9c8b48039a2bb42d6dfe924d073efa51a4ced4733f41514727494bb1b488ab1d8d88845c430455ac2588ab0f9ffeb8832b699f244ab17571fd205f10e2c4627215ac3795eddc0e00c1e9c400d2cf6fef3b140430b80b37e3b3ef6bf40724b2adf2515d72f4ba2b44a493d4b501534b8890b32cfd01814816f5f5086d8634e706b77e6694ae91ba284e27d766de9fc15e6958d05ae47bc3416b0fedb22e3f2d733b1841db8e85c982ddc41f8c39e300c96ac146569dd065d5c030a5d2d012980d61b3d2816bae207e54bc6d30a517415e9108d0373a367a4e00d3efa14e938003f4b56b1a6734c8de494796e5fba6b15f886e07318676984bd845d5d6005ba3e7290d83f41d7c49f1cfaacc6d825cc6148af4f8339aed7c11ee8315cfb8204d9fac2761ceeb4d579bf61a508badf640d6a471c0bb27a47500a2f7c7336e4fb9eea9a1b836b7b64ee1c5cb09da403aa0108c25f5cf4ee03b3dc9dd9f2869dab0abb1341df3a5ecefe8e1936fb2b7a908763510b0abb7e336022e49ce12ee3f08107fa49fce1e69bdaa05a6a02996ba2fe39293f630e3a72e93c254483f96b067b194b9800cd82ba7772b5d6aaab063917a33f5cf0c42d973fc9501cc1e26c9971d86430977275f88b0b79d547b72ac84bb87a9b378aa09ce288b81a63edca05fe3a72d719af427ecd5afc1e9b8d6ed8828d1e48718963a92527d388043d6a374f63b850bf0799974fc7227bafe21463f330c40ea211b94e57f586ee623e9dd4b3cca8f2ee3b13033e304e20a4a424b8fda175578e51fa394094ff962cf001841feabe4d4e97855092060e5c5fbbb3149a18298c032a0ae095f3fc17987e42301ae78c0fcf317ac8bb3976ef51138c8a63ee25743da7bdd6f6f02be7d958aa2b003c42c73745c329c8aa29819814563fc92c879279632b33d42894d1d9388a431ab082a9106f1714fc2282d30ab01344df29cb712f4f2309ad53bb80923e2888e3e48237744a204fc4812176917a1a40de4d04a11873c9e4e67e205f73f06b66c152a9664aff995766439269dcdad17d6c5ed41d3e930e9ca8eaa743f538d882f36902edccd9a5acd871fa6608a287f7f567d8eb2298058e066635a69c457a5dc8ae1db6bf42659accbe8d92d9902e9213316d094574f8b5c0e844a975dfc98937c889081df6cc24f6d7c4a31bf293b9888827f03439aaf0864baf119172bf66ce3ecdbc3113f819214285bada6899adc753a79e44340ec678d8936f06322aa1c741e1a690cfb46695b8e8fe02980f96d95d95c86ded85caeee4775fade93c4e4e2b406dc0af677e9f2b0a7905b4acacd7ac7f30a63f025a8655c06f0575a1f83f6b908f4d38760423eb9d1fbb79980edb128c9ead9f702e13cb84a8562338f9e43f6dc816a802a562d988f54f30184a29addedcc872065198cff7160c079daa89bba8e8843d5cf4540307a89f57c14b84c8fdb417181b04a9b877dc2b073a2809343e574bca85044eb2ecbb4a1a9fb161849ebac110385573c327615534fd42da2326bcf52c7bc270b08d99a7c13f3f04dcdc6d89917e4a9d461c7141d8e777862e0c5c4bfd8b14e081eb8e5d90dea912c121947ec1cb58179b108c1315654a6e9be02b08f7888dad54e913e8866d2def8c83123f18c013862df24e8c032ef720e94253784fac2596de8dabb69b7428208c3d47d0e7c83bab174f90a7ac8c8fb14371727a4cf1b314c720d4d7eeab2dd47b081e5a5eab21629eaab0b7a4ddbf03aa2ae580f8b789128190323c478f822c0b33b81bfa9774cb3919efda6564a01bd15486055dba4c2e8515bac3bc465151f454a12ded2f8161c18ac4dac04f2f01bf26a729094699c351bc0465bf79e64fb7d763919a06c302824e7e2bd1c3893d42a6831ae7ba8944bbdbea5ab5782aed0ff449747d1fa25f11356e7f76c0ab23cf1f0a3a7c37a1415a4cc04b2ec12f8a28efa50a1b9d3860e5f29e1ca085c209a0cdf28f2405c502aafaccc9a49d5c0ad9c03b31b93ebed9f3670522a0fe8046a05ba21e7d1fc43cbdbb3430c59eb8827fd36985dfcf09c7c0ce43b450c488430df8caed2c47c2ddaf4917e456698bbfc94cf0240d2d1070fe0c8f2d0a7842f06316eca4ce2086ff9f4fd165873e45d58fe2dc5f1a965f57304a69571fb4598df6840c83804da551b20518b77d898d6a60549a049a280fb54a730734797c27559e9f2fa421393fcb45a8a604b698b82b8d5366c0c9ee2c98afef49b6f48ee565450f6aad34deceb74fc55390d5ca313a51c3d775239fb40b2dbfd89d159bd92d114e2c4a91e81d27ba5c5685ed0a516786aece975aac444ec61999534be85782c11bccf3680616f049d4acf44a56a846a119b83d89f29ceda5efc986959e9829e8632c6c0d28e3cc48b4c0c1a6c16da4d495e7d4e85cfbef2ba88e7cf4eda490bfbde2bf148e2baee51265488184ab2853145118e27f3e7a4449c0dadea426ba4e69a4e732565aaaea316338fb44d08085ce0e6c685ff831113a6dc2672f46f6cee2d8bc16aece5e7efb2586aed912326bde593457a7e4be216512777ff1a1d50d9babd3adbfa69ab3085aa585543bf3f00ca73640a0ba68ead6bc758c6209185e1470b1a4703d1b1ccf574cc837f2832d167bd03389e9d7208ba8c17a1e12f386b235d541c2803523e363483455d77c679db34e91231c472e92bf5e3af04df373cf2f414b122b160f6fd5b4e928476ad847e166f5b312279014ed60456a0e23e0f09b602acd1a7ba36500707603e35906a26509639a05495149460e325d05cbf09b21cd4a0ded0700ca77f0e76d0f93c2b9e0450c1744470064b91e2efbe6c93d4cb729fc653e05f63315f8d184fabf41c645fd9d77d7c244dceb98f4920b278c442be407e63a45475e0e3913222ee59004d64185c264898c6380c2e4167d6cdf5369cc3360ffffefa74207331626353e2271a288384e3191b24276caf130021ece085747c9951c6cf2e6c72983e718ba87692e09472e2b9acb3ea745bb1324491f3e014d74722922bfd0096e6ecc2958ee223d43b1c25b31a78a8c84b2a7fb63a3b0c9122af79c579468a54db5888aca5967a9e82fbca3220895a2e6614ced2e094e4203d705548440d0d87d5832c2a6145b0abe706ed3436aa69fef6595c4e23f9f95cbf728e189ddfeb51d392f99ce52c13a44aaa4b051105c893ddd7f4040c0356b2be7e8063709a4aa96a934007a5cde0060816ee010ee54147195179059ef1047e7133c6a21e01bf8b68b6b087e42a0771a058cc4c4795429d70424122ad9c9d5203a8778dd3f292edb0d0e4d765d2f5fc6be710f20e33a73da76400f5a1e27a60030762f6093b0259af279d5078b680a70a3749be471f8b71d85a094968bb6cc2d95f752ec21540393544c57bcaca4300eaa7dc1a7bb4039f680c855e04e955f931a62fe69c471de8a240d678206cf2b3102b4853d4ce40152acfb6b96e76a131f80c07e837160fdfa6bbd3e78ea7d96e15f2307c3448382f252ec1fd0f99d25fcefb7c074bc055e7c571a95d9d85b0cc61da5a09946a8735dcc67cc3d5ec12eaca34ea01e36ff513e97833444e2dbc239230287314936a672a1b77e298564abc1a66c02edd61f1b53ee80bcfa73a109cde5e69a5a7f13f5fb4185b5908fd85ddf5d60366011ae1302326ce5c7e1324cf7b510db8ffdb76ac2ce8ff3310faa72272be9aca5cf39e75ab9ba3e9dcfc5856eb65837d393f0156bb1a0fa95ea4723df4aa7ed0134ac1758f27d122a9e692ca44330d21f9ed2793cdfea50e5d5c61535a20b80298a95d403eb033fee95bd87d2425c94128a870eefa4ec8ee6f0dea5ef3d85aa2b919d53c190882e51bb086c83ae1cebee29c019be4910cd68a0f71f26478c6de9417915790f955a8c2295d142fb58708e67a8e93ad759cb28c6bad7b4cfddc7e9466f2863c135a1b0c4a2b26d168357cb793b049fa9a2375a7c0681746eed3633cfee3164e9acd3fabe2abcbe1e17199d3814ec4d99002d626c9a55c96640adf079604782da6e25ed3fdc9fcb15165170b59d6812485ce497972fbf87f60e42c25ede0c500a8583dc948a5339663c8c8053820c91333fb961b164914f8d648d9c640bc205d772b727d848ae2cec0aca4ce3e63363c6915bf85207a64a5dc083c27172287b0988efc854a0a066c58a09f8a890f22a18222053b1e48095ea57b0672205d77f7142b1c3ece775a2a6ed3048a61989262f7475fdd640f407f88b211c5b91f1e73602088f25aa2924425360e3503309d6628ba762a4ac45e96d3c7a0f090eff3a621b44bd0650b5a05c91f0b134f8fea5a0c1f221c432027c3d197a5467ce5970a57eb58f8bc30966779abad2ca11d004256c882abf1353c44a905ff30f00caadc91231bc36a51e6ae38543459cb8563f3735d813865d7304f77c91177833c079824f1d92c9f90ef9fd574dbf4feb3eb021eb68e77418a2554d2c5062374a26c2f36e1307ff095e21af845416ac318b1ecc59dd4fd693edeec73a1ee9b529ce6b78e7d8c4ad560b491b772479546d1666d5bc07051d835bda0f492c56bebb770a63a9764d3aac935e26e2acfa8fc5930a909755bf6e413439a019b8032726e390b551babe65efcd933d220c30931ba062a0761fc6ac8428ed47a9f2c6b945984048e323b2e24411f2d2c650c1f89b1e89dce10ee8b17cdcd1cd0fac023c211cd6afad79f84194d4aa1cbdb878089f112ca1286568707360dd522a6ad5488b9fc28a271b0af6239c5fa6442cd937985f841ff37cc1dcf3860cf4e65a95bec579892de297abb5d853e36b2086bf2d600884b9e00b7ad4272a6ce9a444902759e976bc6b58d85d78c1d2ee67ab3dbc8293e133fb26daccd0b65ad81de29e260843a8bf70e3b81e0051507f763cffad8e707cdeaf1f58b79127aa2aaffb8ab7697afb32de3de0b7cbdeff69a4b25fa60e4d67ae2092b8cdd17b0241573ba1c88f0f4386e809fdc3356159e7cabca47dcce3584e5cf9a5fdd8313fe561ed9a242b1adc5766e7c1eab6c443e278c006d42dbbc333336e07149808d861773fe046f875a27e7799fbe1b0bd7a108b7fb9eb949c88d05eb8cc2bc5453ab95860354ae50bc98ce550f20f6910e833ff0a0631f225c662d7959523cb0dcf529df0430a4c5decd6e167688c0605415617f3bfadb9e886220b3c67dcb1c367f2bf8f5960a5b6b6be5d80315e9a7ff39949d415533a2a4089d202226f27e7b5a0e13487cd94ffe6c59179040265f3ca2dc1dc5244bb8dc6702f100a86f9e98717673adceb87c9a37022633ceabb181e4d540cd3afead86efc6a88cbe1e4d1fb2f04737b14e7000b65d117894286265ccef9622a57a573749e73a83a28273538e8d849c60303b0f7c283c97a54f37caa1774369d140e92e30f71378daef0f9240074b1e6fd403a40a17c3c1b1c7481c47d28611003d38a71af0b332898d5dbdeccad66687fd2101ff2d3ec85e8baff766718a748a225d16c246c2b68f76f6f6c791a8052b7b8fda3dc5551d8bc5d30e09f8aee6fb87e63b622ca698c18e56828c039118ddaaf466137916e50fc6716e5e6f305de49c9df7416f09695f0b80370097da4420b4277febc73db35c346ba5d2d504793128a1dfc8f5375f78ce5ae103030c781c1128560739e1ce4f3a8f1609eacb9a1a666479cb769d5c1306028c31f175c6a7eda5d6de38a514224dbb9604628de6ac2912f4b83c104407730c971a05535ea9cab2bd360291147476e9366c87088f3745334a1c74ee19a760ed0509fbf2ea1457ba457aabe2b59a797f8666340cde01385169112893342ce2950e72f241b11ffed941bff35aa1940fea1e4c98e1269ec1e97360780f8db2f2169791ed92b747e481a5e1888fe2adbcf90663c89d0412cdb3cdd39880bd42a6db34f2fa005965b51c7c6dd293ee97cda2baa08d76cd69acbe0ce82c865c179d666ceaa329ac5ae581606e8f380aeca1e235a410b20c961683746607b5c76dc692adf55dcc501e2ec0c259559e0e65d0a094e7892e7f23b40d6b829daf7839b33c77d888bfd7469ea3272e060a5e4e82743161a6e6de53677c8119a22a2288a7c721050c1a544c1cd8239ef4131557703d70bcf6606687c44d64e67a08260c9a44cf63c4432405292b4d300289926596a0e7f0128905c28adcc56ec5487689e88dd92a36498ae9f6e56a584b5de060ca84063a0225c8d6339cd836af0c9c4fc6c380766acbe744683cea65d366b37b342584e398b34153c2cd4ec3dcaa854b6b99fa6bc4b0c32281050efd3d390fbc84c27ca7b7348c13c56c73d3edf7e943c4a59265a7ffe798cdfaf1420ee388e82aead8482f1db000238aae6e642b720352799a06b2f74bc944016627266dd6d58e7641037dd88b234db91ee2e3278faaed0af8d61c145f671f52fbd6328453748d1c62305b2b2dcf4de57bb8c22851d0a152bc293faf4c179599461c7df851d85d0854a69f617e6f3443d7f413ff860ffb01cfa5b5e97ce46785008959b294e0993e1ea0a26edec8bc74f8d1d34760229bf87cd3f879612062f29d914bc1ce52ae4090c497e740bd1982e7f312ac7b2447d20f65ff19190efbb2694f5899fe500fbd3461999b03279863bc62626533ec3bb0493adf5afec4c0ed993de980413feb41fa470e35e185df5266c3c234358579c83640ee503f857c915129d760b0f2c3dfef2902b353ac8045fba272a93b84134209db4d9ec4cd886d6cf9c727a603c79c4a2716f800a9382551e84e5e5aad080ed6e617743338764bf9c918f08a859a33a618b08c7ff8a9ade235a350082de8d55e7382889e00afe6a6cb37590c9d621f4ad95ccf797a9c333597b4a8759622047397ce9f9da065dea762272ba05da1e872edb6be0aab135bda0c680ce12408ed3041598ddc43858b7262b18f14385ce7ea9aedb55c26538ee9b68c12af1fbfdfc4d6efa735dd8b2e3761ae2f64dd76ec09deb1d6b27849c933eb3ff1fc846219f39d2232d9be01615520584408fc32408deb9a74ae63ad07c8ac0a4696cc504660b86518a9b9fb86b91597e9ab620c61c992fe85f4359f6f01bc0357cde3cf4c55bc3297cd38d247613052a93e32bd513a8998f9df7c8fcc9a2a2c802a8dc1a0c916f817105cef78f8dea89e91b706563d8329d2b8432d42f214a77019432ebc7f266e87a30c137b803303eee71ec960f5d06691b7f1244256d2369610f0e629b0e2c26492f9d961176d8f4330691e105b2e52a437c753a209a5e7baabfa3e784b74a90aefde35d147380770cf6ee1572e387ddfdff365f74393c93e1d9e6c33d920ab85e0c6bf52d26f249a4dba30aa4369efe44f875e2ae040a09b30a12893b1708ebacd6e4d2ab4bdb56f869939678b65126854097d0cd6f42370c37f40e4a0fe8b5d2bba5703f6f0c35f715094f0a7455d532eafa1e8e80e0968f08ad6a95f59c875862a94e834798e240b3c33b39a6a959d88758603fabdb439d4cc0f0a4130e1405575ea575d1449d9d93dc1e95d4ec4f89725b21bbee5b5e8964770bce93a14002d5861b58216fa6686191fdaad4cd1a1a4f0eb0201637dad8342bd6f472ed7feaf1b78a66e7d761e2f20c6708531ddcb7d0b42e83719c96bf04b35b01a1c2a2f59ac28c6e08975c64fb52650278d34e908882913324388900379ba22c23db6beabd85e6ed00ae812dd265e24160eca68d08ae37ee7990b0b5ab1f37b6709a1a113c2c49c0ce3c1cfe2c1c943a0f0fc1f685fdafcfa1744381dfaf9881ff5cd2d295a8842bda7cb5470b681fe785b912f1c50aedb7119ed17a8f063eed5a38fb437fcc32138b3e1ea6716df820d251670a0a25efe69ff60e9d2f5a6345c956a52a8e96e234837e3abf73b5f66042e7a50c73f1e9bf85d3d111ae96329248d760f9fdf0475d6a1520ced609bcca84887900b3248fc5ca3f24b80a13606283f7a70259ceecd2f577867703d025466ac518aeddeef8de101f4f34fce3f0dbe27aaadf4b4939aeef046d7880640bfd77a3ea03377922c45681136d0ba13fc70d7205c014d7722ad424dfa4be04f0dcd624bc4900556ef1b9819f912b884bac141629a4c18afbcca12cc620c0b92e2a431090788b76d22a1e6ce19c74168adda15a314ba6dd3c38e7936eb839778d5f62b14f912622e9088f72c4e69469681c7ebc48645a4d651102f096874405b5277357c25b1f33f39044e6945b00a36d18602e6084173daae9cbf64cbc86a261c28a02893c02993e077179de491cffdd0edad94f3b2904491267dc68c8970c97ea3affbf5d721615351744b79a8bba36b950d5b3ae0197acd21c04ad262067de9b10752e48e442e34c309ed9e268e99580ccf71f42d2eb75a512cbcdce308ff9dbb753eab8665937409494f71a5c4036946c37b3ba2e5105ff8f3946784c164f99942dd676dcd8211fb7f99f9061ba2ad5e7bf3b9ee64f3219b858dc93c5e99ef7e5bb86fd88fedfb6164a037fc92a73b54ef6d80a620c4abd724eccb5521f74013cf43c98600d2262299e6871c7829b7db55fd85c5dabfc8f08fc7fbd8d8acc866201492e0cb70bbcb0aa9fe6672a6d087a8348ed6172e288ffffbfde8f0967fa108ef5b4daeb3fbf00c562ada9bd857263f303b1ae4afaa358ead5947054486cde7b9adb1823c70212c0671d6bcd765bf1aa26ab7dd00ea9ed38d4904a53085f586e7a055a27a244d5810e8ba13017fdee9193425e71a518a18f37325d4a33a0390ef371bc388ba5df62a5f8466acbbdc3a736bf073521966919a853f2444ac31820f8fe952f15e5d7bef73d896a550ebf65901d4cefb0c251537ab6e7372679860c157fde6b10c8e9d1cb6b7fdc361ca36f700a929d39553326a391738b2aad6060669eb85691e344ebdf0537febf04f61b8105a718bc1cd6958b605001373037a3f61c4aaf6a2c024a5a6aa051c405aae09430a142d9213ec6f65b23b3d9374c4236e688612db19719825f37c256446141a25fbea55a7caa6f167e5f492c41fd254580608258d826a79a7b2759708b8b8dcd2d89825a02880f3eaaf1eed88c91cdf1d5fdb74c8f26b89a54c7d2b7073c4c53170c0e72eee11f40382e22146c3373a88d7ad87bb2c9164637d80d4ce48f362c9227ba11a4cfeb647d7158f1ca2d47c80a90d5136219ea819dbd086be6ff4c45215a57d438c38c1c2b17ef7a309761c587f0321ac4eccde6112811bfcdecd6978ea847ed11273aa16f180fe8b03d38053cbf7debc697142b9025baec31a586c06cda20daf3e447120c95d814c73e70706152be08f5e1d5227ef29ddb414b13ac4486c160e97a63ddf13edf88248a668e348fc40cab7cebf91c976a5430d47cc7bd38ff88e9f2d45bd0d1ce3791206e8fa718ddd001163756a893b649afebfb9f6108b862a62214fc2e5f36075a5634030ff6962c5caa576749568341cb5fcc46afd2ebc84362de11554894d9d42aa9661904b0311b2c5cccfc209201bd8da3a5e84663b7656c924d119e10cd7ccfea3082c07679bc3acc2b87c01bb48a4917b68861f6561ff1c44a178d588a39c258b0bf03b1f8c2e1937b92f61bef845cc13ecd175baa4ccf92401cac62f54db8334382a4ad694e0cb939210b754eda0256638ea77c5497a0db781bc1dfe28d5e9dacf116a52dc18ee1a84ec3c147731dc904f9321061fea6dc73959983e53b4536d6b4ba903f47906b91eaa871e6ab5a68d32f6e553c0e63cb3ba8da518301e1ce50b04db9a9991bba48bba173bb05a2e9af7cd9d6d375619e4df58bd964b24d9963b13f470039e5138b7a3a90a272c6f88fbd6cc194b825ada9237865bd331c0fa6b948b19bc62ceeb27ca333401f78f0dd7d382af819d622a276e54a4d8d77380c88ecf9f5ed99434d20c7e3da99c16b9d8fb1b08de2d129b604a34aa35cea0003bae2c9a3f9e396b9c0b87ace45794f540fada23e71b2cee0a446accf6d9c966f18593688e0b1e338fc68472587a7f93aa08ecf4751eb8730df0e9142bcd4b1f5839a8b299147a1bbe43e9c26931fc4ca83ba2f9b7358514005d46c3ac8d0e5e8eb8aac1ace05f81ae82bad080644d098e111ade9e1f438b70654cefeb67fc805d3d7ca7e54fec1a895d90c2ea625d035813e83354d84c483fcd72bb0a28fa2a86b34f05458e80955bd21cbee7d275f5ceb87b8b165340945d429033e129ac1076acd2d608ee04b08bdeb6bcc14820781272d738b6d3f970149c9c30f78ceec6791f0a4b4f7bd336dfa83b0bb55dcd346b15c944d82cae61895a5b57867d171f873214eedce00c84ee008cfd55861b556c0c79114f129544287e50b116c21b9b0d744b4dd7223c4118280dfe8cc12cc13a256359a247cea20a9d51cd49d4b82bbe7e960eebff5b5000ca96e8ee49e82ae7ab1001884013f08034157caa0339aded2bc130168699544e450b6e64952e697a6ce6c0320e18242644ccf61ba25c7f24682f222c7b21ca0c588d750d85cc19096d1d63e6529901b81f913fe11ffbfad6500189237b532d05dde444325e358558b3af8957bbbd35a4bbcb294c151b6f5168eeca7f06b8d10b066eab2d6cfb45422fed8ea2018db167dedba5ebf1739ad2754df30ecc1bfe404de9ad4fe70a13e95a59cde14d438b800555574f23bb86dbaaf6d625f5b923dd586d5a89b8999253f76f276bc52a24c7c2d1dd7ac510ee9087b46131ed60b58d4454d6d9003a5ecf0ca7e6c53456f7d4326af83420ea3be40833c434fd278bfd4546e1c094eb7b31015914ef14e5c7a21225d57f1261f77e19fdba5bc6b22d4469c8070a1d7d4b27cd98fe11932d9f01e11d8f3a36adba881f2fa995aebd2f527143f5d8bab6ad13e92f21ee52d81e7bb533d7aba2dbf942b43b7b4f23dbb9611b27078005eb7aa618219eb73473edd001b94100ce250a399cd58fad058268929803634d644d7841cac3a46fa3096f339561d5ac10e13705228a8742c924c59d29a3169126227049d827da2ae68f81352873a4acbad34a28be6b05b8b0aa58113bf0063e9b4476ad8c1edc50606e7e566e22e5426c8014d8eeda2c361880b90743a22284ef849d4344a41e9a622fd48cc0166e691bdfdbe36457cd94c4c75736ef7866fda7980f006e150399edeba58ce5a88bb2e49e6be056fafc47042b41fb32bdc8cb7e474841ce56ec492b76691978986bb3d84a479bd2f5d721db458f1c407decc76ae617fa506a8a8cce816f3b1b2f343c52e73424b46ec49a26bc0a0ba411dd22032fd046db02930e7d20a064a9fd215da93d8bf2248389aa2c6e96fc8a7de6290425f6d2bf138663577804f8aa29a21d4d7c5e066753fde65b1950b3e8b5043b834ea1c91ed2eb0d899c71d5a1bd72f35ce6bc9c2f756c6aa1499428f2cc20aaad42648548182bbf213dd80ae7cb41cae96e26883024201337d13eafcfbb6c547171185587a0411c57fa15b1bbd8ebe8e64d0786b77dbdf5de2e909dd3944579b51a7f3fdf09c041fbd44fc5ab91e4d11cbfc2de285d66eae46f2178befd4fa537d2a59411ca4f76a4d97859635ad56480ea06deff92e723f6be1b0593885e6dd339b7449b26fc14487d4c1b1be8b63c2552325ddbc7ab666d5b22367d79f4fb03f2b55f061d511a057cd370b598f04325dbee8841dd45efaebfa4afc6dcc26d3bf18871b7f78d29bab97b33e24bab35077f506684e09367df11d79851f3883212f39ad2f4eab4992516228ea080f68c6f8ca81650ff2279eaeda9720d05c5c00ab394c524de511bf948816e0d6d9a105dad0b1d005ae4b78b7aedad870cf87c80adc8dff418ff7f47aecc830570910f0b45088cf9c789a49c3f8a5d78cf483965ea9ffd1e8533e4cfed26b05391a2bff1f81a6c84baf67e4d82cecd157d50c01bd1f72b67ab66fa9024b67d378d0cdf78943fdb45e9fc71c4e2bce8d6609f77b8f3510a4782f384cfacca0e3a37d7595a669b671928001d61d19a5d39960e97f78320064fc42e763a7ba03bea6f293d978c0916021789dd6f06242daa721a025509e0935e058fd17893509daffab296b886eca61b305633c0b0f444841eff2141091b78d58d17e627750ae2dadd508e04c146bffa7d483aac1f8032a2a65cea6278cbaa1307b86843234fc34d06ad4d15147b0d3eb31e21a1d92b28f21a9ebac565042b2bdf7130becf6a55973cbb1c9241bf42c89c5a303dc7977d40d22359200213a83141e7b4c40880ede658379bbe3d0456d10ebad0e42f5b8499fe63fa0f2d9297f5635a469e1003e5c0d4ea04662753ab9c036a02429f5017efd4a9cc61b84a6eac0abe0fd75252a48d434e7e14ac3a5c3be3325182d9ed25c50406e183fa600fae4b103fde9a0c4831c4b2f5356dc5859d55f176dc993841ef61519cabc4b7e4c033e10194bf817588d299c804e665f917a3f478b4cc3ae81d34803ef124adb6b2c8ef7b8f235bfc7cd2360305f4ff854a40167c89075ec292ff76594c563a114e7c92f325b33d6460f47e0cb6b65eaf7e7b3917dedf1cbef72b129096c7f7066f57b81e5cd28a073fc3f8d6c0088bfee588704aa08362b832c1fbdbbdd0e4706adf2add58ffac99633b400d542cf7431338aa029ed8c3bf44eaec3a74b3e220c6ae484a35317afa2d3043f82422f1b7b559f34868843fca0f6979438a5fb6bd3b2bfd26f9f3a86a2ffb7e658269ae2a5264e80ca9fa5de3dfcff3199601b9c057d54a51862cec23af53aab2fce0badb50bbdf46622ed6a97220e97c2aeb52fca8f4b85aa9a8115a5f520082c34f36be480e2c5ce1bb4b5181c087c5a82850d23bb14c21ef50a2726c922709b0128810c15843d808ff8e1f0fb9619a59ed68124fae382dbbeb18488ed97d56eb7c048e280e6434703d60930ff399c07a1295354526b2d74c5069259af5fadb0f2a202527ed89bb7f1b49b36f81a215808b06a09b621d0645f5b11c9a63258ac3d436c1760a20cb43c2b871d422fbca79e5800382e21b16c74615eb95315a9de4e2594c7d5c8d6d734d00e12ea22ebb3e4413b8500d966d2a325437715085529397531f7003e666cfd98f5de45f8e1ad263b55d9e37ad6929bcf866c9ffe8373d97d185ead8e1224afab71f71f1b084d504fd432178580c9f6c6b9d9853562e2b0880d702226a712321f569b276b10448f00985b63c10df8ab1a82128bd6f228ea37dc0091f605836668d47790b021cb4da1881ec6485fd6e88e1860c6badfa9cc79000bf563f0622b86ce6019240009e2a6a5ad8293c660e4392e4f8ac46bcea974010085319299031011190a2db01f279d9b0c200acfc0694e4028b0b82bbcfb10fa9dbd90af4e743b7e2e8331b3d104f2322c8dc9e311530bd94cfed88ffc3f192c335c22d762adb2d0be6d076ee595b50c811cee8b3a34a2dd852a70a446f77e6575f430bb8b83a4181c53dd375a19ac3aa15ef93d4f6982a27d32c8b4b2091c4ac53741d8f65c56b7b48b34dc6e16d0de3cc365680410485b996b70b52af7520817ec50a871b7ada61378bff71fcd05c55d8bf8ead337906b8edc5f601d1aa2b8e6e5d59c9f9838c5be78884203db0b13b149c3bcad8692c1d77dfea9e28309b1eea1e8748ff0fca92eceb6da22b718226389078a815cf034ac252ff9a36d465d691eba6ba0d40fe1ed125a2c5c4e0a50b0dd4dee708f40c1d9ce00e8acebd601671719ee8e997492c6c132e605cc361c47be446de9e1f519a2557c2011ba48ccebd570beaff42f1c1a633e3fa850f1826949e55d0004973db90d836e9b1aededa136a82864d40ca0decfd9cf815f0a171220f9737271a2846467c5c74da9bf7269001c2817f7eb3ca0e22042c327f58b9d56c266a870c4b7d85b757bd835a4c32152ee0961744f682b8928616f19acc0dfc424947c3fd4dc13de9b30a86413a7240210e2fe1c142c2e2e93e0d73e9d4c500543c71ac503becd3694f6be2e63e76bf6d5425a59b4e561ea9618e1c7204f3fa9912b02647a2208f1f416595d67a6feafa995883c707a68cf0706d89cf195496fab31296227b06a23df62635ea6e206cd75231b24246d14740640cd2ad9874d10fdc921805d1246f90b17948134a710e4aac41dba9448b383c294312d094a99912d00421582d494a5463c69ec914b105e6bc1b2fd22041e4df4be6351a1e90e01b0b2fdd1f3ef4cec9c04ba1fb6219095f2ee6a9efd6f68deb07317d89f15e884baebe345ddc4b635848833afcc5965dd165640a0f4d876b7ff354328a2cab404d405efb2a60ba19f19b68d9e2cec97cd9cfa3bdbe3755a5620f3a4c5a810d9919fe7c556a0e75770e7d3e4ee8f64724b86a249b364f11905d0a9f4d554854ad624c2e2e267418e1b9364c663bd05253d4c1c58b8ad816fe7d6641d956c8e4a087a2e965c83efd39170adf9509425ddcffabe4b193fb4f74b32b8df5c6ff577fff7affed39f15bbae7d027ea1abc7832325a10aeefafff754dfa3c4a15cc6f40b70f137bcbe38569530a0083ac23ffb616d458d1df8f1768586e40a08f52262dd8fb57a66237a7ac1a345a2214fb1ff4ceb94be59c95b95fd88ebd9d7133f7be879b1ee674d2fb34deeeb221f859099a6d8dd0e17826b22bbce093f1abac3b81f534456e8ca022401bd24d6fd5a4b2f36ff369f87efe676d74a1c724f3d0cbac6eba841f59419c89fe36995d8265baa06500fc340cc9d9aff8688757fd6f56e2ab6dc3bee015ba6356cb558240b27e9ab9baa6045586f136b3fd6d11bd39c4b5c2ccee55aa9ade13a0e75da2798b85f1e32343c4de7dc526d13a616edafd8e9675d3d1013574fc9966b25961e70e2f60f800bed547e4c88aed6290b1084f59a58f6679d7aefaaaddc27e931793895b8a074b6ed3a63ba7c7709665502bf3d66b895d499baa799d13de578e2f7d32362eddfbaded6c243053fc0428c8df5bddb79cd40c604887c42e20eabc82dcb3446d137b4742fdad74121df086ae746622703ea7c113c25bec95cd867a2f8490819b575bee7938b60d88fed632171c1c88f656501d1739499a0eb5baf2ddf02476944b76bcd240a840e12d3f3a6091b68ed1d633074d6e1cadc3a0d2050eefd6821150ba5ddf461d4f1dcc481f0c5eb044cf8ccc961402f876636950be594718f0c9ff1415a3ef15b9f7fe4b660bbf09295edd8c5dbb27080291b88e528307db7b30c7d5240d75b67957e2aa38d3bd0794621b05a7eaf326aa548d232eda39abe8d048493d02415b4c646b413f7a05c063ad85e983a35ffda17ccd774c3a6ec9c421413b67dbe4afa53c48a9471f2754d19475625ee541a54c99490c31f2ff5d3d3ef03f4d695f449c5bab063fdc2fa5304847e1271932be91be32a2d8c9adef9cd440947988a4c1173b52b27a1707483eca599d50cd109ea5a8452a0ee1e235fcf03ce9a3a889031788832a3c7ff2703fad47c5a8e291d44ad9037cc7532d11654d88026b0263ab73005ee617be129a72437c39be01872026bd0790bf6a908b690eeaac2be1742edbf9b1825d3dca6bdb715fa7b0c01940ac42423783255c7d52ce9e68c85b783bf9708ba0ee5b17da4b9068be5cf3238184e65171f2c26f4d36d6257612031868f0b55d2228ce76fb6ec2b43b110e5e5b7317ed3d2f7cf913b091aafd912f4fee4b04bfb3dc34d0e03765c2cc33d6c776632e6a209da06c6a02e9b6094e749485bb8c9cf4932c0e94c93c4d6810d8d17635e3802155cc833ab9b5753dd4f640f239513cf62fe7ed3eb4a1c508501e24b720b2bd0a336669b1d85a4cfdcf9f3a560d87f459c62aab6e760db35b56da24f6c505723929d872499455cb9e479526dbd1c80ad5e55504d7322046c5c2daadeae23cfb8c342e811223fdea11116b5fd0b7511331d14925874a98ea703f0aa468cd1bccd1b82b97abe940fa4ead2c3bea7653b1e72f009682e901d0e327d55c1458064a2776c043042fe6c8e82dd25b4a38a35645d9bd31890cc954689ebc3ab7c459c39dacc419417d2de7f4d970347ab7609f8613815eaaef975bedd782666e99dfc09d128a0701a2808257ffeae03e7612879b13aa85b4c2c9b5809e2442666595bc8deb1da577a2b14880bd3169a534839e0d8292e238459332357f337255e6861e8a360e00fe0f768bdbfeabf1af4f044db4c3ea8e86726b1db67d8bc2228860fa054e805e03a487a0292e48e5e3b6aa83ea9acb6ecaac87564fa2cc0a067f02340e4e44015e2d38e1945087d637ebd8933f4cbbf4a559e1386b724597bbfc698232c39fdc72be0cf5a56b076589722ee4105e4bdc2d594b1f512993ab871b0bbd71e53427af5dd9b698b19c7b783b6af842756bfbfbd90f2249aeaf8c6d25da1fbd7526ef7796832b412016e4a5a4da782c3551493c1334c1299c2ae69785d9b06e00c570f7a0446bacb1181dfcd57714a3900079d08940bd895de50273479583ae7cada9e05b49b038c4b99875b97e396437008171f74511d8ae6787679268717908e722852542f84c8f51b1e9b887f7db70d3e063172201793c97e8b32dd29b62486b1471620072b5a43722053d759407ab1b0a4e1cd7d7f1fde68c2d8c990b78a5f505ecd861446c924e11078c8a2bc051e66080a068162476c28d00ea88de1fd5261d339be38688ea4f3d568cd947d7176c482f1655034e150847473d3128554cdf453d68b6b23cdabbe23b87cc8989abc6ee2447f29d02e06742a56e3cca180ce400f415deddb0a01a6c19d79450be9d1f7d975c759dbd71c2941710577f6d97335a21d364011089a8068cf85ee9c26586adcf6ff9c87be89a167c6a31c38466499eee14a53bb28fd3cc366c4b24fd58fac97563a8d7867f37dcdd9699c63fb184cc2aad31c0adb5c4f6470761ae9c84db80fb1fd21112b6c91f13cda5458d426f9b5b41194c3d63edb544126184beebc05514bb804c1d3e9e52cf8d49484b741a3a366f224c30cf084317cf1eb87310b73496a1cdddb9c2d617a6608cd2a3198277abddf1e1875e21b978a91c4a7ad6126df23e931491cdee3e825bb7f8426c1d41939679ec241a8501e9e48282a75f2b4699829844916116a817da937e230e91685d09c792128a3a2eff0270d91416299ef0295ea0a429701bc196216604ecdccd9fed3e426e533bf30449717633e22bc1cc2fc71a9556fe2c4b13277af86e78c13171559888c92b5aa69465523217c518558802260caabb698fd82586f89a109584ebc745646cf6840113d59d9fa581ac8189a3ee143d3aa8cb8983cde6bd94999ace1392cb0cccc2a2ee930e5a984a2a88873085e7b7c17c0a8012aea0dc4592f56b7971d3b48ef7f64f9b65bade56fe937e922c04ecb9c8bfe88bc7a1a420112eb2cf165d89a4bf976335b1d6262324a6d6ae10168d8152f6a1f27b34179d54023ebda8105fa46bcf94c439d7883bb0d788c032c195d592e2b9bd482f1d5804815b73f8b6c3c514e9c2dbc713508df2dde771b2948ec1ea7a8856e94e58d1c8e5be5bee1e8e5751587775278386d0421a619bbee1e447a480c2564107565dbf2a3a353eee7e3dd223d89c099f4cde32e2cb6330ce3bb8936b3f8ae130b6b05b8d4edd480b5968fe3fa754f385b8dd5f86c3bc18b15836a3af19956c36f0e88f2eccac1e5ee224cf9afff66196d0fbad404c8c978d88809371339a74ff5c15f56bcfc4d3692f046e91d221dd9606c8a36f51be1204cf6e7f48d3a1294944758601435b7545c098d01d0ade49590e681f388b047f7a8898126270d89f49e4c9c4fa1aa63e9ccfe7c5278387cff63d6eea8f600c5ed44b8b3704863520e8e0a652fb493e083281de96c2887249129462101279588fe13c0245b7b6f3168952bae92cbcde212043c06442b55b0307703e95bd690a635adbe928befad13cf1571584b84e6b924cee060873742109595e65251b77ae76152ebcbbca4353a54e2d869e74d8bbe6fb71071e44af0d7c74c9fa35c5d1f9bffcae1b1d5c55201b6effed65bd938b00d0486cb17faa112a3be4f558fee6883693f18c35d9876b541143eaf2434a35fb65d416f93ecb09f5690eb52ebe3261ab3e665d9446e9deffeead696490a09cceb1aa9a8a6bcb279706b584157ea22a39b041d28a9542d7a0ca385f43fd074013fafc87edc8726f80312684e1c0c2eb6852c3c75002d7a5997bed14c6b6d96a9b830cb0d8e236c306fa5190e1f4303b5366d16cdd4e23b193181d31eb816beab193b254b06a4532dc6cc743153ae9e5e3f0b186ca7bb1abfa1b721e203a5b8b392394ea4642a0e16a25cbb6a1a5c83646439c8f923e2641c8f2c006e7a146da3ac9ea847228e9dc0ec4362e48409058f8fdb592bb4e9ce2148fc43690aca885d4a99f28e9cd41b4161d030362bb55dd7b4307194b06a8c1ebf099938cd1f4adc9010d1a7f4808c55b25f68f4fac84357d0cbe4da96d42f1b3befb5ea06a1e4a5231d8fb227119a0ebe2ab05e64daf1dccbe55ad6137dcfe39342a26d87da131c452253162f8119cb191d5d526d1d4c270c553cd1f913eb91c6ea39654763e8143059036fab684f9df4c322590f1d72ececf9848f48e62d9418120967df4b42eaa4b07f4e3eaa4d4a2c3672e56fd43d5c9b5dad42b15fa36ef97088fed9e94cd76a5a7c9d9d7045398a85cabdf8813efd24f1403956597b0c6acd341e8588ab532efd8c3fa508f961eb62372e946c21a4e4a4c577178c6163da299ea92c3bee646d65babf5cabfe68c9209c5ad99f574b87a68eb8473ecfb6354783ad31d6a1f6cedc4b44f2b0fd0405a3c488b35f46bdb22382415446d5106ac222b86a989db25b17c5f15109f1e68108baf64c0a07ba052791318016e5f001362402433e9671e7130f6a5c990e13770e1048d2ae8b8263361a69faf69f8dd5e2858846948199b4ab06ee18039058f228a570a9a80924b7377d48bd707d7b2166f8092407e15edd505619eaa488ed7e8e6acc7408c62abb0e1f04be3d12205758b46ecd93bdced64413530c1288a069b645280cd26dcc892f98398b37f80ebe01fa18cd6bc66596f011ec653f5c3dca7a0ef04b818a2d62993d1532a3e31f92252c8318bd12b33f421b6fbc64e18ff57e19c556dd8a895b7409bf3b4fe1ad5841ccf97547b19343c26f60473d9d414916cbe75cd7b6576432278ed58a396656d83c2151f6649a19d6efc76dfa83843533d57aa2be0cb0d5871f602102b8db8f567a6b4b63a36ecedf788c5c5940e429d7374c9094c55ce7642efb6d84bd2b807bbbddaeac7d7b020fc96924507abb1a92b6811487e4b041edec4bbeb3be8970cb7d65e99cfefc34501100dd0eb0cab7461ac92139a14be921f73e26be5d9cab14f15cf7fded8ce91227f10944800962fb888fc551bfe6aa6178825f17487d58b0d10579db59317910ee1ba226e93a766115e8b4e377f8e06d3d36ff99654e56a5896fe7dad15bd1f48afdc1e2e78c13c8de2271ba55279307e6d112117aec83d4a5b698bfd3250c86cb0c4a74f1199b442819d726630fc0efc2cc3d909e8b2079869d81f3954fbe1a37bcaf31f7a0a09a66325c7fc32b61df04a22602b2cd10f128c29e7d883051b8052bb0db78bb4f89a3097088f59afa394f0ca1e4cd61d9b84e8b528c0a0100577179c8c95cd4d415c1a9d25c45402d5160260672014adfcd6b01e2066f5dda8bfd1276b6094a39e260824845b806801f8668cbdebf1eb323af93fb199975e527d49a3c881b9b0b8bc1c16bc3045f59197d920775dac418f372328c10556a5d596b31bdb2869790a9427396de25a451c4a12e0188ce60ddc5d9c03c93d4b3210cb9b6748ab8107bd454f28d60fdaf0c0b112e14f7cb6bc8d36bde6c2370c29c7d720b1b49a7910dee506e52809a6de06ba4adc44aded468b6fd4e7d2a77207714e006f72bb7e1828068b2b6449926475e5f775364d2577fab0c86844a2a099b9a6d3d515b59e0286cfa9870cc29863983fad6a11ba90c82380aefdf9e3eacc0c4288c0fc58e50baabe022583e91b1556d36b2a7b50dbcdd2b444b6bf7633ba281bba7b550602ad8a7d191dcebb6c913af99b7cbfc8a211eb7b70a239c966f5ba743b83db70453b829896d9b56e2161af4ab0fdf1af5d82bae28d8476a9b3689f2cf7b50c31c5fdb0106d97668e32f5efdce4165cdc5f85832ef22b722e20f44e5b9fed5be9261224886236b8b7c0800d3a7e4a46ba16384c30d3fb32ec08047ddd80befb03c22e73fc394ebfe1594e4bf56777ca5edf4f28ca7812014840a3591810899491ea99bd1dafb919b6bb46e0d9556f5eb83545b29b2ff0fa24b0179e80fc039e288a8d823b558d7707fa4d497a3e8a57a249212c34dde02cc0ca48f7c8c03b996910c95416de68daaa93ed82e7294a9e51b2a131aec13cb21213406eb12023ea4b69da4c886682d2027117a6eb2105530de33061c627a17e0d0bc339edbe4bfa1b95f72d326c34b7c7c17e48b2e1e5abb749d0678ed60cc67c0bbebadf50d9367cd599a62cbc7e6c319d615a485ce4ef21ef3690acd033a0bbd4e81a77333dcebc994441a1f222d116008172ef2c881fe03f7d10f739a3c2abeaeb434d5ee37f65416a860191ac44901ea27d92500e09201e5f4fa5fe6cc39b9f53fcda5ac43212184905f4164eb8ce4da566d6b55fad59296412f702c355966a6994033a1e177e4b5fa4498cb7174ae4b51a9375a0f76c60246550f9a5ac5a1246db024711f5f526b6d7bf48972c7a8ad2aafb96b0df6f350f70a0b4be2215f5c581c207f6b3fa98134c512e22a17476895b1f5a64939c13554924e61850b227830cdce3776d395d7ce688a3034a02f6baa22b413607c7ea956078bf68fb804ae08995848066734cc764ce91aa7c397a1c6e78a549e898e5b82588c8b101fbcc212512a59d3e3e6fb3304c2aaf13273d0c15294575ae4de5dce0a8198e59bdd87a5a8ddd81969193e09d4b1928269d94a28713f40fffa758a0b080761f1886ea8fc2f49f5e3e4345c385c5240ebc37c71348bf1a823c067aa284386f6438d20728b823f49d24696ed4ea7c7abf8badc994def711012c47cfbd0c13cdf2fdd058f3531f28eca9a68627974a2cd00da0b71913bb58123144f5481ffa108d520ae6b3423f06aa762f1ec2593f993fade46ff2c7380862d6405e0faf7077c24e55293c9178c77613f5999cab07a829726673c735b3aec1c5223f2207b071d0955788b3fed83e2902057dc6c242c31e3a92c01a12f8303b6bd692a476d72110c43c5e435dd52cc32022e4c19c1f258b663839fa5fb9af445426bb118635e7060c18dabc3d8aad506bb849e69facc6aa8927962763e61054807426f67dc9097aace0b32ac111f87b3a7387f34da2d0ae287020b1e668c8318a00e9f62651dd3c3858fa1d2fa8398a7a4c4e07f47ef7f62ccb68db279bac8ffc947a882c741ee67919d63fe46e268b551c79996f8baa0e08476c227b0f4615324f40cc5d71a8540ee88d6436d0bcc2527cd514ecabb5d97913bf7f0f980bc7945b5f945d61cf06dc66182571d296c03b72e26d14db33741cd46226da62d75d7858f2bdeac855595510d14bc40a76e376a0fba8db5ee7cf4ea73fa6ecd47d59856b59d942e2580846d7dc7053e7a9557528225635bbf21f6aa08be8258594e0cf71bfd7ceb4648414a126b86c2b9f42d358cd9f52f2110fde3294752876075072fd9f6c60030ca682a0d5d1032147159e8e1911942a18d4de60d507b9ff47836d9c32076102c150fd915e90d155d3283db19a9e3a5012ac32aee28b9527c24fd308f81bd64415e4d9620910f1fe790fc0745d7f9b2b6aa27b1721f946ca9325ba44a9785550ff8172b250c4a834fc1d0453c186d11d7ef633683155a9ab453b3db888d0346cee1ecda7b1f28a9d36add11e0adeb828316bf2e58d4b0a4c1c35a12745863e937a279172b0be269df51061a3a3caf1a4dde3c155da22277c0c948b59b753b1d51b15895e3a79d3d1b6ed1da28e37e65f02f137797eea8e3e564228013d1f47ba506a6a94bae731e6b309066fe31c4097b433aeeba8fd3423dfbc2d6ad1baeae6069bba04cb8df7e169023da40775395ae3ee4aae078054131da57b7b576435c35015207cd9fb416808e0c9e6880c1d9b104a94baa4b04504059e6ef24a08c1b18ba02dee52b8c893c2ac98f6d48666c6facbce2309addcec6bbf9cc8dd7651e8b2e4cc0e554a5a36d43a99d83185794456e706fa8a17ba0c141859732c4e311999bd256c1450c7d2d9158358c08534a63cfff5f3e551a18669e924e024f2bb1b0c4ae3df1c99091358f0f1979675362824cba5685169a40c52c5d059145fff00e5e6649e087664a815f1af98947ce031c33c321ed14b654d8fe658905da45a95da429cf69d25440d5e17e712059e70285fa2cc1de09a3e55cb06e94fe4d4a91fa23b1d47e6c2951ca37a1bcf8342642486237e05bb189255dbb916a6d23ff2b99fbb09be3860de9dbd4b08acb8cedd42a2a64898c75f396df3ec9c1cd57d3b59194020b2074cbc7068b236add972304b08ad30609904460b3fd650c677cef2b0e1deb557f84f5a0ab3ecd77b9c72a154b1bc4d7e70b0ee309f0aa32b26f71216ecfbbdf58686bf76b32f534a38ec8e8334f39ee51b07cac17cc8f0228a36539f35deb38bfa8676a52ec93ad8267e2091c0289d404cef53045b651a84a9c14f3c1b35eb979e19d7f2d4ca1727aa4b89c32ef297f6b8ef3e68f040de24a75999d9acdd23501c05d2574c8617717a4d5341dd080e7d5c9ceecbaf86aec22367640bbb33abebddb9d7098a27eea016e72c6100da47e02ef40d9462dfc2ea865d13c4fa6d4a7265832b18920081fda6ddbe78bf57f03e0e90bed9cebe8e8330ce7fff280d1565a58583e9308856a8f6b7450aa5724ccc509a4ae461f5f0659299057c871ea7fc9025dfc63b890ed8d1c625f6b3c1c2eeabf1e37adc6cf07b0cbacab991080c5ef00d6d202b19909a57c5003a4cb7e6035937a00e77698ee5757e5ed4d233e762f426c9312d28495b589234397bf5ca65157b3f73a6da36699004b70d10d2aab83e35dda468b1695753842dc3d4fb98cefe0d24cebfd0ef12d63c4b70bbd5ba5363ede00fb6f80d44e0c800f14d3582cf81d022f7b58446c5c889b57f8e40a959e4a22c710e13fb84f1742d1598040ff1f765b67e75ccac2820debdc232527f610835bb20322ce2ea83ea382db61769ac106ab84af9456203f37b6221da11a3fcd0e061456f02cc709cd78097e47216a13ed40cd1de93992030dcd77779b6001008e2b72eb629e242ba90f14570ebfa7301855bdba8eee415432455d294c69a370a7734c09078406b138947559d205dec0924dac0ebdb535c85207e32419cb2a6aadb4e481cbd870306a86a901962dcd602416a4d40be35053f97d5d43c0b66531d5af1939da3e691ba33127b72441e4f407e61cadfb867daa7b3ccb5038c310f3ab230f0944c9bf5898ab03369ec63a41a374da14beb619cc6915ed37894918387dd3330dfeaf869cf34d60055b4bc036ae7f8eab4188945954be199a887105edcf5a0aff78597763082e47e4185ef604af06ba07ae939bd9e5632bfa5516f12af3aeeac9c48f6f44ff8f922ecf53555ccf54650d0278c02e6abdb3fd43a42297ce6b74ca57d92359f4936b53f516cd9da74d4141b8b8a190b4fcaadba039af916b57d5974ce89e27ceee1747ddce64598658aeb1cec1dc62ef5facba957d8681ac08d8fdb3274061cf4cc295668386caad8e899ba24e933b98e823be770c81cc175778794ceef3598617015e61885e2d252c306a3a6018bfc9c4f25dd7561d5533cd8e7b35d2624a0bb7dfd4b3fd7d119b35442c299ca8ca6f1bb1818a3c3bdf8f676cd81945723ddcec9a1c8e2ec3292a2afd879b34ba60108ff6008706900b5b6f9179a314bf5d5f86c994acc0234c1900f058973ca1d15dabc84cbbd436b7ad152e564408550f7806951899efc8b84d1b723e9534b9fb0ceed9ba5a91fd9c38f5486bc2c1502413e7929b6119fcdf9242e61e4d18f0605212316c577762ac1efc94239ec2a84b489e252df5341de99023bbb493b0483ef66a4376c8c863db7cbc037825d360aa4c0348e0d9ba1c238db35a8d9c1a94322f33e212d432fb8edc98ac82a2a286147533a9445c1abd896fe3f768e11b236a3ff8313f623d69c9c7f94a95bd9b6f53f0d7c5d49e9aeb956653830febf0a165f0c085e726d20d335ce357f623b6c4bd3633ae61af82d54a889656f5f73461cdd68167fefa8614dd2c5325a40404402bf050abe30a247c78530b76789ed69b0b68f20662f946388215617d0a84478553e5ac8e179f6abce0ac5611be7cd62bf2c6b7710a0319a542e92bf6c823e6941615fbc8793ec0bca55e77fa8f75381ffe570576d2cd33800c8b0279305e836897f58f7b284da18b5cda740bbf31e7f5e69e1f83a537aae6fabfdc3ed48b91bd31f6b8672ad5433af50d36a7bb3ed8e15ba800145dc51523564162139589fa1423593e7442f062738e77a6955975d476b3f02ff5b240ec6d738343d115ca83f4894061e38a7848ba5c5d1aea8c66c35e8c81be7cc89e9eeb5d1a3a246f3cd73045ba5c5a8770dbff639e22dd9ce60c4d13e56b6317b8c436e169ed1fa67926b04251bc8460cd3f4c1cd0006d5abe58bd996a581f5bdc254098a6d7e274e56864809b34c7ea2302182a61663d2a7cce9b81dc228c2f4f2ea3dc93adc444bf81a3a613581b434ac0030b0472d3ca01fa71b40597b726754c8b257423de580375c447ba3f0e2a702850de2eccb832dcb0d6fa226fe3fca952b87f36b3ffd3f7b79d0f50b6f393d2b4c5dede96645128f779bc2ba690658053530582c53e40e2582acb5ba5038d4539df959d39a28729db3fb53d9ea35dfe020d3aa29ae8d2a06f6a2e3f17e32164f0887fc90e8ef7ced205e4d7e0056ec44a2ecc809ed884d636f98cf80d7ae8e5c36782bb5c974a82bf4a3ea3a86a8fd9c2895f03e8e1d8324f27cb2644d437d041f9c2917cf1511c0469b9ef12b790c9a3ec389b92e1c21e4d82a46a32c166261015f2428600f97f9d0c1849dc66d936fe57db282c7162f682d8c2dfc1331d328a801e5a390c49d2c372eb5ae1681359c6b3f3554014f9f29ac339cb801f2bba218cdac19bad15a770f83f5ae427c39dbf255af40ba5847f33d365ab94fb96c8834907341b54a3ee89d190d3e6d36e10c09fa8916c3209c61d555d43fae635a5dea9d1afaf14f243f9f7cc5548ff6a7639ffee38f9eb8e406773437e1861714fd8c1850fa9303ee7135b1fe237dc9ceb09a7913b944b35caf4044e304f1537ab1162f9bf946c39026e85c185597125fecec4d27fc36fdec7e6c06437bb1c433c7665c7b949092e76dca17bf7cc1f551f9d4f876c065bb3ee6a4ae879ba51218f45120d88ea5bcf295daf6708545f70f1dc340283d61a29ed432bb442b1e1761765a90e35971cbd907b96de0c6a8b4baccd5d85084e22c10413d6749ac1a1278f2a74944f21ce6dd58ecb554e9b29cddc929965ce42a815e818cd0a50e42060c67a503f3d87cc663114d01425b8e813ec10e81c95daf99da5b24671d259c02d820ab0056bb62af272ed8694f81068cf9eb64dd6588b5cd462c9289ac492c8ca7bad2ca5dd83d476363744c8cd0870a584744527a496aed9ed0cc5b3d76f1f0eaa63e29f0564bd2f80129ead71eea599bb71187201202f4fac8cb3fdc07bbc1eec425292b1691242f81b54407629d94ba9c4f19825d4f657349e2a1e06cb3dc20815dd8b601e852ecfdd9cbbc687587ae9009aed4ca793d64185af9680a65d8939ea99279d270e89749f412a6fe5eea26970be51cb37ec13b28d55c52de2b1ae0d528d2d50e296d9e87e2793b92a2e20c54e8da9d4bf85f117c0907dab0fc5159e0d91eb11f796a9a9e7130562d854897a3dd0d75828339cff1eecc11401e9c5348b180bae847abbcf96fab90a151b182f7ba98e6ae8098b70ec2013ba1df259cd87ced2bbe9dc29c5d15840e719b2d50bc4c0bfce99ed1020a362a9c5bbb46d10cff30e1a801dbf9ab84b630b1c901ac854b205b6dd3f5d84ebd16f439d237e222672519573e9924257c5efa7ce04f9f9244f3c522412c1e197c663cfd815403ecf5f94aae03759aba755689d0ba7d9a4881b3c74e24f99c3a3dc67635ae88d98523aa08f401035bff3290d681913562013e832aabe24830e4645872e013ca8049ae1cfcd54103888553ad1c01314c25131800352cb25d55919db6a3929369c096f10de199c28521bc64ae37da2d2d48b62f624274aae059227e5ec064fc627b95acd07965d10de6c929f816666b911d97b932db79452262903c10bcb0c720d2cb87f02095dd416677be2f15142c12fb3a5a3c40738a7cdd46916ddb2289cd6a8968dd063fe39a54e2dc204665eabcf7cc70dbc3670dcacefe02755d594afe27aa29f5455431eac61581327306fb556eb48e798c76be304f5b6add9b01ea30f76185b6242e14241b5209fb98c209ff9f519a9e3ca2565cc3c0352871069b4e3867508d98c864cc07efd92364e707dc804eaa083a48dd936a5aad4f59b1fab0d5d9f5fa9d4ce4bdbc0218cb3289d2f3f4cdf0df61dd6394ced8d3e2ae9530e1c1feecb029d6e59cf152928a491fe6db5cd8431e65a41b5790367b52b1604590adefa151d60530024ce102cd08f379ed67056bb621d8be2b4cd50803120cea20c6c78a203f2ac268a33e613a4757a65bd04c18b0e18431ce429a020833c0525ff98d8c0d1f53b6e3b6ed8c115e8136fc9598d69e64b4c412ec3b8c20c7b1cf5adcfdb9c04907939b328160eaacd9bbdd1da279a608039ab281b4916f4cf6a5758d00f54a795ad501f880c2708d6656429aae0699e36db389eda1c368b9d62e9784ad2a7a41689e37efeb275cf2dc982fb14ab6dddef9121a041afb8a8979682a25051fa8892d4a9860af3cb5e328b66f513500b617132dab03306eff9ad95731766a3cf499fbde28aab0d1cd6de5baba0b51ed996a2706b53fb244fecd763f0d96bad9ca1679bd17f9ef49f57c509d8a87e6fd3cf39678c2bbdf3c18b02ad491da99211f49853909cd46f9392b1690e524aa97be4c4354b2999af52a559d69ef9ea049c36be896be5dc3d76d0f33cd2060862108318246d947402b19a0deca06707bf5a7fec8b4d1b186400cefed54a4761d6a20fe7d1c988ddd6fe3eff4813c6ebd5717f66c17d1b5ec15c03a7ad7a49f4a28a7984b1d3268cfa2bd0273cac81b5fa31076bd9eb9c36902c55fc976bd107b6831b1ceacce14227cf2732a07e8ca44d103eb7fed5ac679bdb56ed6c324eafedd473aeeacb49e70425d639e7745aaf2a0df587e7d99a9b43b96d3d9dc2f1399d6b9259932c3d9f5c134e6fb53773b7386517e8f33c2fe3685bdb0f9338f057c3fe7d1fbed7bb40b4b651cf73f49197a38f2cd9f6cb731bd6717c9ffde69c3272cc313d9f4ec7eb2bae9793cc71a39c5fd7f368aeb7c2e0d011c3bc2ae6f17a1ef66ce879e19c9e1863be47df5eaffecd9afd9c6b94a9090e978bd7ddc8d147b3b76c6fd1da5b5b94466d6924a371cc5e9a5a7565e2a757176951dc4a69dbf2ed5569ae7e56fdac4ae3e3c10edbce595ec771dfb3b5dee23a321a25e9a3ea49e38e96712dbaad359cdeea39a34568f76a4b6dd319e93c6f3829a8aeec2da34f87ad91918793d03052a73aa7d06b0e6c0da0a2ce14f15585acd7eab4fb76c2face51ab0defad17e35bebadb56d589bcea6b76dadb6afd7ea35aed7da5b717b94d6475e136a5bcdde63b27cc1b75792d621ad8f4adab5d630071b8b81dd5a6bad536badb5d6524bb388b31ea51414adf56f4589732c168b654f74cf1349a2c6d83f88c56aac865ebd6b54726cb2ed678d2cf6f0bdd6de6ff4687d1473a2a7311731a70fc66ad6ad188b31bf1c9f7a5e6335fb94c66af6dbc57fd966fba455777c2d6689ba3969dccda449eb42aa518b2a52522daa34da56a322d5dd0d1d4d499268932e9aa344a88e3ad1a7a42d12ea6b600694b134aa7169b4e92f34f0edf592345ac57d644923172f3eff3c32b769777777777777a55db7d6e8ebd5ef9d5e9407d737a9906cf9580663461904b3df60220a4957dfdac1584e327af1d170769e2e5c7cd84562ce339a7f6e237bcccbec61db3239857238e9cccbfe398e3ef2fc8410f4d1a44212b6c705acef14dfae421f4daa17a4befd468ecfb3f3ed99688240bfdaa7e473b0f617ba5223e5cf3dece16c07c4c819a36d5d42db5a86518391296c11845a048a6be568e76ebae858672196ce3a3f43a25bbbd7daef04dc8d1bdbeeeeaeb51b7b8c13967014db253b25e64a3d05a49efd83b635c6a50dfb477ef07dee3958459ce77d15f45a41720c4bea55d2c8361f63aa9494d4f36b4a93df627ebd46db2eb2dee1579d7a152b3963cc6a27f67b6bcdda5c8be1d3be2d466d4b7770e4fc8d01be506b77f7ac4a7c50ef096dabb7662fa9c768dbc36dd0a55a69a5b8b614e384b6551336f8eb27c458aab46354247aab6f49a59a2da96d31acac6a587d6d8fb1d44732926e8d41eb5c9d208f6b8c5aeffc92f24152925252d7aeb9d24a2fa5d4c8667b91f422673942ac6de3b6564a29a59452cc95946464642bddee760aa8ba9f7e9f46ea79578ba6dbd27bb2de55db66d75b436bada5b9cd280b3dad1dd290524aaf98018bd804a7b51f7491b1cc9fc351a801f36bb53e542fd551a72728ef2b2c479bb0d7756dbd165bcfdaea2f2a09a4b5b54ea3153ec0e956443fa95af041b594683ad50a0a588a9f543ccc90c19385c7eae7149e2deffd9cc263e5e7149e26788a3cfe398507c8eea7378d3c426381f7cb48dd666dae3d29a593ec9aed1d6b51ad764eb7739677da59a34f5b640049e71d6bc7b640eb61affaccdec4d5a78d49d2883e478f7041fd6822e55c2e97dbddaa914f1aad67a6349ae71e599da09f27b50dfb50ce5e7777777777777bf670e33e0657b0835f92d1f319e36b2d3f152b3947ef84b6359dc76498e7d5254938a13da9daaad3b16d51f6cee412e287effa52bf5eab597bc96cdb66dd5a6baded910dd599a82da7aeafd26e5ae748733b43e97fe9bc8ec99126e491426d2329b556a86d4dbd8f2c2669d4c7e9ed154dadb158d05cf1ede58a9fde13a967510c9e5e924e10da04fa768ad75e48038d9233c50b8a52a0a7d4cbd9cf6cf3a4f292fa59ed5bb2a41346d96ebd3669a36f69bdda68b76fa3db929332d9dbf40cbae729c41c932c608fb947b2704506f698b3e039e8b836b4e4f9d0500a15ec8653e080a662934d9b8a4b39d7226b9db6b8c4547bd22af3ecd586aa7bfe790ad833c94276ec1fc9c21519d9b1b370bbd6c1daac165b9b6b91ad41a36d966b7ee11dddf605ec73c2c83e427b9902a97a89ef57b2063929a62334396908decf46b2d5d654681b765bc35e6b737661ec35268ca73ef21e639f550a37eeba338ca287de3e4017ddc7e8a1480e5d177dc72d2487aee832c07befedf6ac45376a119e6135ee0c230b57aeb3303a487d74d0658ce45076d1ad837e491932720805d1ad0f65528648ce5a6487648c5e7d24ab87bec438ff3a75eca107d610c88396d6e818fabc79a40cd07588561cf25c8775d03d0d84636d28fb8d1b581bca248d19e20af48911c88335ccb518906f7af086b9963390073d2fcb3c7fd0ab0da1203ae818101d24873e0c843ef4914328803eba0cd0471d400eca5c46ea90f9e83b6e19b78209f43f9fc0bccd9666eed5b037abd5c0fe61f796409fc0bc81240b573e67c13a48b2507df47ee632accfc8b176df3f5246f5d19f84b6e11bb5083b885d861d087b885dc44b356a11566a1bf64c26b50d7b051bb175d0655807c9a1ecf326a3fa5026bd6dd8e7cd568b72635245aa518bb0638c3f5c03a3d051b7655e28bd945e924647d2568bacb54d6b4f809696f45ab40303e8f7e4eaea3ffc863f2021e94a59bd3da96d4a6da3dd3e9ba4392365b2b4ae9444ab27b9ed3a2b69a454421fcda864d75a6badb92225d14ae584799b94c47579f092eef524a57bbd1eddae5dbb5e10d74848ba4af8764d52aaaed425f451cfa049494949f6aaca8627a7301898727453dab3f2c94e1f9c2c46ffaab3d60f95821269a405ecf99a45330549a12854de13368b669e5f0abf65c6924251a89a73ad9ea276256321149e9d4dd62e194b9a039a9fad2dcd6811a8d714d8bf55e3cc3d6febe7f3ae51267092a5ed272d73d80e768de6fc7324912c73489623699b72f9799334f7d1eff314187b8e364daca58fe913aa512b1451356aa56d50640aecab60fb49d22b9afb6a33fa2893d4da2f04aad12d41b5253263f6726635c028fbcf5a0ae814421a6990ecc253189e521e75d6c6b6d11994bb576339ca1cc8a98fe074ea6556a34f1b27590291748b9728a3f551cacb551f959f9827d2d2e7e08a8f865105dbdb00e700c6ebd6af5feb7537666400b532c1fae7b19a8d927ee4502665cc5a54aa60fb9857cfc03f8f91a57516d08f5d8fd52efd6cb6e38db6514f51730fefda462995a2506da356da4657a03f733ab697341e478a1b6dcbd12250bf3e8c25cd2de54a25b48d867db2abcb553b787919598e619566ca15e645b2cca4fdd2ba40dc112e97387faf0e517fbb30fdedf2e6af7340c4dd3b80afdbf50dd0b030cbf5a510075fba78ab85cddb1fb64cd972e76d15972a6f5d03f7cd886ff456d2b02c7d3e0c3d0339670c5885565f86eff99c37bce761a1f35e16a8f7fc023420aeb73ec34669a4abb31235e641b7a05b40c481f676eeada720e26c05724fb32a92fdf22c136882cceebd57c6cf29e7adf53c82bd750ad0aad054a5b84e138842014b4b8aa51c8648a0833345c408e0800304a6ae4f193041275c5963c2cd45c08e1d354ec68c5143d5e78c9a7befcd6de1075cdd75bae2e3ad5beb0e504097225973aaf0d913c5070b4f8a185674786bbd0167ac442b41de5a67000c395d534f90c06a62d7c419b00c705d6fad9730a797913742c0d004431122c2cc6cad588088c3555c78ebd6fa4dc459efa28961c886d92f6b8fdecee1f3f7ba9288bbd64eec34ec8eb7e270cdeebd6c14e0e5adf504d8e9093103d82e0d5393a9a91b138fdd439013e6cb08f09c0411e755ddd034c2f5269937218c223878eb07b0e1cf12a7214ee0f868b284193df7deeb2551e141006f1dc9b35f2aeebdd73ba250603ebc75111a50a6cf9d16d46cc1e3e386f79c8192dd7b2f5893d31375a8340078eb2f449cbd33acd449b305470dd51d302641f762bf97368076f3aeeb31c0f5ae80f7deeb15204e066f9d0022ce7a1e987101f48ca6e4debab51e8288b3342a92fdc2b1980bc57cfef0b1582c76756dda5079bca64a8c9f2a1fd6548db9e1b10fc01f840f8cde7e55a49bcbb7ea0cd357bb4d37777397290b80fa01e1af07a0a98f720b333c6a266f13797337979fde221187abacb65cbc75db6deaa3f9f6292b97cbf9b8355323d1b026f2950efdbaf2b57aeddcd7aba35ba4763e502b1a49ccd122e4894910aa5b49af94781aa5916ece0a65a24d4e3ed73a78bee490668d0f353fdc4aeaa4e7713492fdea22ea5f7ea6168d335fa997130bc9727511cd7aea25d1dbac7661abf5c504f8b421c2b47bc3e4895b9994c46be912e218a34509235a6ce021e756bfbeee844a22a22f5d703913002e4ce820a68b0b8fdd03dbdb5d3fb5bb1166681e7b07fd3749ebb848f9cf6d1fd5fe730088b84f8ba9c3df12c4e7ec2e445cfe904aec39672feff9dadd7206ebd2fa79ea5ac2def39c0311e7653e8f9db4741ae9eaac57d5df00fcf59a88bb3aec1e0d6b1bed5d2ef735ecd44fdb681f7de5725f62b273348c6a35d2cd59385a7abc78eb7e7315e9ea2ad4d69a9286e99a9ee20dfae9ed5345b25fb5883a141d7a0c01d37a218930795a88389c650816b90a6b088d28e8c3bebaad59d27cf5a1915695a19201a52bb048f9eab6ba0a3c77401981844b081240aa986e78b282284dc4e1a8ea1ad0a75c2e27a4d65a47184747b0c020650d10ae1c6e15893845402fc5f50c44dc05c097a1d0639f25919a2f5d1ce0cb0f5e90b0e6cb69b5b332c363325456ec5c214275850b072c8fdd28a98f26150e771e53e5f0655245e91ebbd0cc7213bb4e28aa7c7dad1ef495cbe580d412fa0827d51d48bac034ede9ca1365e756bdbe4ef95a6f9d89b88a7d96422fbe247261e6cb0f14f0e58bc73eab6c8f3d8f473c765a96c75437d4a982e5b18f49ba09b4d1b2430e629e94247104559123b8561981a80021e1abcb74bab10c1131a82388beba3885c3fc5c52174251f9eab63ae8b990d38418e661e5fa68523f1dfbde7c755b3d8f4230e4747dd6ca78a76cc1b6922933da40e7da5ca53747526de1614413243c82b8e13b669a80d65ad286e5bedc537cbd6cdd3219cbabd35524fa9134cc76d3d3d63d6d274cda40457e751b66270dab45348f7d2484868bcc7eb5cd867d3d58dbe84d33529f4f654392017c581f55b284abb38e7dac48b38fd61922d03cc1e101871b3602859b3a4978f0893335a5eb71559c241efb8b3e52616efd256dd8d7997152af7f28f596a26150b4a461614d3aa77e2a3beaa9d3a792f206c6db2f1b2676fd8deaa06b0d4592e817a760f65afb62b9673ed2d9e8e5fc022a6de3e83772b45326ddd8843e41018d3623a90fc21bf50b67e4940cc6a598c73801e8068eb6c53c282828e6411e94a38f82c8d27fe61de4b67256cb51bb81e32be637fa68acfe9e881bf18d1c319246ec0b470e1d7db4d431ef582c16b355a41b3272a491256d9659c8f10d14fe914a55a886a2e6d5cae9951960494b7775c7ac6353dcb85b4a6dd297104492925a4c920cd9ebee5bab79b57ad992d9b6add626b7ea7312595b935c28b8adf512638c7da92e596b41afb6548b612dae35c6922d2fa96464adb5b6c6154c964dc6a82d9db07442528ca6956a8d31fa6849461fd924ec16631cc37ab698ab8823deb331aac5d77b8331bef8da2efab7d6ac9444425212094a95da4ab033ba737e8a1396c3414c1fb095c0f61434a03600fcf9201de79c73d600add0cf3ba7d04f146f63da7969bdf7de7bf39cd34e3b2da5f3061afe42178e7bb34c91a2fa71e4a7d514281f7d8c7e4cf9311c7f52f938e2a9873cc0a9018ed02a4953f8d55590b334b5ed8a88959f2e44e4e2cbfca26b2a4b180f2d525441763fa7b4404d6949f2730a4b922f85accc64f9399565ebcb514bd3cfa92c575f86d4431f110069162c4294e03fa0f51aa74f8fc9f859d1c015a4c85357c2e2cabbc9e5391b1da3e9fd35f6c982fa3294fa52e8ea4ba2ad2f5dd4d0f5e5072f48f87ea1ebdb08288392d18a86ac262c3fad68d84d9ffda40282e7a7150d51d353fca46af20242e78955142820aae9403fa97c00f96915c5e9cbe6fae9e04f2a1f503fad6878fab277543e74f8694583eecbda44e52306a6246897d7388fb6ec48c893244fd3cf293c613f5d0f1e2edd4f92024bc639e507ca8f53f873ca0f919f537dfc7ce9eda6fa84fd9cead3f5a5f7f4d3f3cfa93e5c3fa7fa644d0d7e4ef5899aade5aacf981b8b5d656ded6a2c16eb3bf651bd4e3660fe0746774e8c633467efbda55199f4b7d65add7a25cd6693463a2679e3db6c3e8bdcc662185fd92c6b95acbdd656aeb64d9d682fbd40d41ded734cc3b5f14619ab97a3d0bdf7d2702be270a52cb8750ce844422e90a6f5d9965eb7f590fadb513d7637ccf558737bec2e8a7b49b0b4dbef1eba64a49ebdeeb6d6da8cc7f6b2faadd5a3f607da1cabad9532114942fdd4fbd52b25f711fda4e43eb2d66b2b488f8651ff6833c5fcab64ad75b5687aac566b58ae2be6b1e974cc5fae7e7d83393d93734e6b6b6d6adb1e3957169cf347becd989a926e33daadfb86484c3f926ea237e59bcccb9b80527cd1cb9978f4b99d30a84f163e65536494e66a8d766b6db5d6dada668d5a04eb4c57eecdfa8d8ad462da19e6204d0325ebe5bc52aa518b2c6d54a146db6eb4085d5eee2c5bcf1bd466dea2367a1d7216b9c6d43eba97bd4645229f6ee84862adb5d6cb94461f599f615d0376cbbab5d6e6cd3c8816591f6b938a50ae98e304c1566f516ba762cc59c4c8a158092608d66f91f59e7ade86648d0982cd0e6607abb7ac5663851339930a1f72b0d666deb5d1bf5a8eb659af4b8cf5cbd95563c290bdf5c9c253109d0539945390f95066e129cc9c05c9c21519eda3b3507de6298ccec259902c340a1faa05f98a5a06aea226e41ad4809c564b9181a37026210ff25b1b5a9a2d3131f900f214cec494810b6950db912ba16dd6faac1684c2ba90f50caca7a859a81db91a312ad8482d75594dacd925463a7b53c563eb679c9f55393ed5c13088e643240ba16be043a16be02c0c396d060b9fb7d91c72224f217416240b1ab0704586061e3a0b341ff214683ee42968e0e190d33c85d035c014e34b99bec274f84e9101b6053a5a0ae4b4266306a554c60c164ee4dfd27859d4886a33fae8924b1f29a36df5d666b42d3bdd6235a01a8dcfe879d7fb84ca7c89a8c6d284d13483de6ead1569ac3ebf587839c3be859734c5287370ac484f634daa5eab57b02863759c82180a67414459d44222a5be8195cf386d58bd3631ae401d97877c853385aec241c7984c81858e5a58fbea1a22873e6711924328b0f0211ffac8145890434ee4a10fa540e4a11391a12bd515e617d65fa1fe47b68b39561b5a020292cd1765be2327abcda845d581ea2ca83a8aea4255b723b7548b2a0d748af2d5410f046375a76364ca9a5d132cd760cc1bfba8342a1b4aa8a620461f65b29bb40d935342af49d5b15f19f7f3bcfc7ce9abcdf85ca967d49cc79a7dc6524d46dbea873d7f78690656ca5a9aa101eced34de7bef1d2bd2121ebf318f394b86ffead25daa48f3092e1d4d5f6f009b7d39c3724c135ffc657d1ff6a58a9442372304377454ac2f279caf595c5260de9733ecc3976a89a66ed2df0e4e10eec56e3df7f1da1a2671547adb697f1400e664a4ec335b27a16d8d31ae7143475392eeeeee4a67d0d0c096add1b67e629c5543447dffd28c23dfae813ec2df2ea38a0bea7b827d7f8b0e30c0abd045372a6dc2c04e9ddea851bd9c5d2a98d08f49da0481aa784a82582dcf22ea5f2d062d6b3cf61e8fbc18983ce1d6e823eb160f39e03af54b860178f46000c4f085e50e98168c44b9d52f5f9de2117135ca49c57b4e91b08a7ae1ce80c5891fe6acd15519c2cb63a75e220ecfaebf6ee911f40e35e2e9c1af567d06fd648e6ba5edafd75a692be9cb9c8ef8927e5090447090eda06284c919218ed895e92184aeaea020a0f0a123c4872e61527808c1ce8fc7580d16dd9ba95d952e3bd48903b6804d1ca6293837d4f122558494d88b31558ae89183193a76ba8440e70b0188f0588289ab333a261de6f009b5d04809b38a63c30f2c5c601031248724980021c49e3b7a9e6c19a256076dad662d1591191e632d7096808ad3021593ee86b53c769a10d7886de95f6bfdc8ce91346c1255b1c2f2c41722a0f0b8e12c8fb1254b1f62e6b15b2a44fef97bc422f63cf552b4f32dd2f9f6598a5bdf628e2902778ee4b478f5b8e3c4ad14b17c29cef9f3839719f05c4df9722b45a7a82fc5a726422c514265ca1f1d6ea50895c39762d4b78b52e24ebcfa2ec52c514bcf1f3d4f7ce887eb2b746af2cde386a82e3b56b27cdcca10872f431e8c4089e33504980c4eb732bcf26538f58415e182d5134e68d0e1568656be0cafbe3d0cb5e07cd339f365d8157ae50995e461f26192acb0298c02b7ecb240aeaeaf32cc7d874c5ee015af1cbe412b3bf0e91b84faf6d8550c8b83291f5f3d98d181479c5b19cbaaf2656c6b5af9f111c4549020c224b99531ae1bbe8c7511c104cc175d104d98dcca18952f6339b04957824e60132362628c18f31db38a4995b1ddb77f5c1f9d0cdc79a20f1253864c69732b3fa82f6339ddb7c79c624d62516256ca58d4776c4b9d2f4e1d21be3f38df3ecb0febfbd3faf61c06e5db8f8b2145d47c3df19587cdadfc7253befc9a8a6ab053c7490e1c28666ee5a7b3e1cbcf29ea93fa76dfd59c3d7398f8ce60df51b5887afefaf6ac4bf294b7de7cd919d132c706196e6596f265beca595b3910f9327369f065a67326173973e43b13c9cab96f282b4a43b8ccb8d00508125e6ea51715e54b4f8a8a1146e0b04586a920666ea5b783f2a5a7850d9e1e5865fee4b9955e0d5f7a5c7d247abb47c7cb03fbf6597a61df5f7a7eca7852ca4cf9f6a2e8bc24a3975e936fc7bb1c7c60ab152de8e9d221d18446caadc457347c89b3eee02122a5650498dcadc44f5f622e2327b26af82108243ba85b899f7c89bfc2fa28f4e3317944b8e02f5cc27c632f52380a6f5d385d5a4c7a48230787dc12b7f2cef0e50d6bc24970131c45892f31d437b622e5b291d2e6b5a0ee15d49705cbe186b8d246c89b3664a06ee56d72f2e5d5415d2b77cbf542e7cbbbfbbe564a905092e7ad53131124c8bc70274b9d315bb7d2ea9a7c699d80d469a2856a8997959b5b699f64f8d24231c9a5e1b3e5e3cc0f2ab7d246c5f0a595fa76bbb36a8b65b5ec9685f38dc4fa782440be9de9e61aec7be665f5f3edf589cd778d62a7851dc28230c307ceadac52307c59eb568553e9542f16aa933f4fbe36c9559d547bb9dad103881aab3751437039b9959de5f4656fd59c982f6b53256282e6824497efb2b7dc68a8afa8d62a82cf9219aa6e083244d3ada45b4cbea4585c76619e7cb5b0a6865b49bb96bc506e073d3fe688b1a3e4cbce11e924dd24f706e8998f93e62916ddd5e8af8fc8b9f18a93c6883fb7245fceb026a798dd82c3967e11cc11203043a05f8660c2983fc38ec0a4083b46e430430b726efdc2b7d32a5201b2c000e547173755736e4876b470a78d1138e8a0468925b776a33ea22e7cb797e03264a34c2693c96432992c88948d538e92aa0702721a87ab22d9af2fae4f88ca0723ffb9fd3e1d90182d187064e398270d42c4c9de88b86ffcbeeffbbe2c2e7029a2e608113f6e9f2e4ed6381bddd0a42f85a8acfad4a8c434d9a265c9b2beef73a3effb80dac8664066a4beeb04c4ee81dcf611d203396523e280665e45c68b6c46de26f2a35a22eeab0383076b76e3eefbbeeffbbe0f0dd87fb3ffbe1f44dc57478a006aee75610be2852b74852e117fdde6310724f3590abd8ce8656ef618bd4cf646cacbdef07999d32c1127cbc9807232a769449c6cebfb5c6c19f9b672f8cf0d90ffdcbcf9cf291a11f7e53e592e77866289b82b2be3958119372294f9a6942a3b801931c247cb91db3df21786568c0c1920e680d046774545314d743cf41461e584113872c29bb3f6688ced09e3fa5013c0e6cf7f40481143f339fbe68e235d8068e1cf9e3c65f8dc6e913a77b2b49620a1018c072552874796f9d8249b4d2b20a755220ee813fa8fe83fad23ff7d9f969cffd8f040e5b23328a676226eac5ad32629cc6c1c41488e901998d1e9171137fec0c4cbb8bc7cdff7f9d2f77d489490928325ca0c9edbe7b43ea243fefbbe3a41fef317b70ef51e1a8e919b9b6f9aadbf70fedeac2d7fd508f9aba6cedf1f96fcfd21cf5fa73ccc9d8d1a654034c448d111b1d584871121719c508c64e7fc4c20a73b883820af974965395cb90b1b0d74f864639c2a3320a0d1291711374ebd6c4bfe7c470e6cc68c19224f9ea91e82fc8de3e5afd0df11c8de306ab11a72a400ff39cd22e2be2c247b13fd0351a43aa3e74551149dfae9abeba324cd44074b948813ef9f3331c8be4f4673b0f7de4ba64eecca280e7747113f6ea8e00952e5494c93103f30795dcc5d315ff1c0af07b5abab4540320e0871c4163553b87efc0092e55aa9f201c9261e3e61a2d4a889e3b4e7767fc899028a22d00d32a754e895b5f01740e29589b88ba7d0d06d6118e241f1a1e750e8c366f2b2a23688b87b3f363748a151445c48a52a92fda2a0db2a5267812068c504e441d07305c10fbc2efede7981ee78efa4730970ed9d9736f97bff2cf97b3dfff1faeb23ed0f137fdd9d28f3d76d409e78f3d793fae886bf1e6387bfbe44e6afcfe8a39cd75fafc1e3afdf10f3d77334f15842d74219271afe5af568020ad45f5a03a541c481dfbdb70543cc1933e488179235b74b7dfc2d13e4ef0d43909c61f776ef8e2859a48a8405a9d30295dba54c7fe7fcbd5f08eac4af2b40f0d0838e3ed9a727a84e62ad95d9af2486bca5606154cb5ad1da2f216f6796c83a8d62ad5026aa0322a44e38ac9fa945e305155f4e3ab3ab041736eb4647bc7df136e9ad90d71fa1b79ead8f76d622fc92e1c3f00b890f9d3e8901cdf1d8e56e5786469f0f340b9dce30d62650cd02cd82c2d083c21a350b9d86854ec3912c3390979708112f93397522e2644c4d09b879e03ffa467ff4cd0332d7220a44e25b11f52f8671de3c70cfe570e340132a8388c2bc7940b6d393b1a461b2aa3c565e149dc6100e893e6f1e78e873220d89e494229f379b8732b2cc3088b8b0c85633aa45d43da8d99c4d1445d16958a562e821d7d197e1833e813ce816c413e741a74e638cb4591909177e4062ce7f4e99bc19271add97c24b89979d25b77b042522eed22422cededc07ee5842040f2c1e49c81084c8cdf630e3c3bd4d20f942d11147e21ce185644e23b0e6802e80700748107788d07de13c4344d0077e9fbd4ef408b519a14b63841046bef0c322b32204bf2222ce8ad0c5f4b74d5710449c6aa6a1e739d5f23cd0f39a86bc6775e5398de2799fe739d555798f3ad1a7f71c87e7d178f31ee87942de97f7e5c26dd5fb71e4bdec799ee7429e53edd905bde779596140b47ce836743a44c485a1183a1522e2c2acdbe447110f824e83d82c302441a74d220ebc44aa7e30f9cfede714c8077e4e7f58b046ba3a241f3220e0af8fadbf4e7de8ee4796d7a9007f9d3289b8cb65b72c1096034bc29724f0e8ca6a41aa87911e75debacdcb5b5bc524c45ba73dec38d216280f11f7f57657af2747069004adfd3ecf694ec4795b7fafef1071d75eefbbd205436e4858104afab420a7860b9237779b3e8f8188fbbe0cbde72c949003cc0e506efa84bd90e3d125df7baf8e5c92a2f71c06f986d65ad0add551612a12e48b114c48dd6c4eced5f53c0f417f017d324efe5eaa27ccfc751788b8db44cb79752f049a30f5b0040d45088972bb4ffcbddedf9b6bdb6d02f3bca24896df47fd7c9f83e4478220597e63e839445c2844e4e203fae3cb1724bcb59ae5d482f376d2995ee29713ec832fa79fb7d65a1a2508ebb3a45b3ecb3ad75beb79a4b9cda888b79ea41463a98f9eb73e83460d6fbdc60d2b6f3d079f1d727eba341df196aa0f9eb74e9d9efc6841fd818aeaf1d6a9541f4d2a27cebcf516ecbc0b7a5850defa8bef8264799d58d0c40cef79be024badb5e067718485fdbdae829cb397d048342c67b76537bae3e7f38bcf3ecba4cf39bb5076037ef64cf4d9a99f66a2f397f6d75320e2eef5eef515c69bbb4d9e3ad51da91b22cee6c64b625193830f2fa83c517082c9f534574be0cae5723feebd77bc1cfcbd374ed8dfeb799e774d603f5741c47d217c29f4c3074c34b16282ebadd33cecc85bb7850df1d66d187917f4e82724439e26be5ab823e5cfcd3a31d93821020b1b2774b0e3e48ff517f95e70da72ce11623efef312f40fef9579cf6b88380fb425586badb53b803c350922ce99325180b8593fd65f80d97e24107176044be4fe5e178188bb590dd6618fbde960afb2adfaeab177160f4ab4d6e3dec25787bd3cee24edc4830d197cd9511aaa99301ddaf5183b05a3619d7bec540b63ba53f2985ad12b6cb97088d13c06c2257542c259386b6ad198a2f3d8276e817778e7c286dde80b4c7afc849fba883a26d2222a8a89871e5e74db47492f7a08449c1825cabcae171d04224eb4517907349f73de41cf67ff808dcaf4b37be03221e0cbf03f9f36fce7e6bf2aa927fe731a22eecb43329f2f7afebc03222ecb6a01620332693f3247819ee7d94e81018919c12d109919fb11ef6769a3106dca097b2d2479d613ab3edadc85cdf35a30b2f3ded7469e64f422a9cb1ae12dcfe679b45d56129106229f67d26d2e3e2fdd85535d79cff33ccfa86dd4f398477bcfa9c25c79de3672b6ed3675558be67fdeb9f6a26d1a50a2b5840f3f7c6471e1e629f19e8f49def3a86878cff3f0b585d919bd30da853d6ba2ddd8b4a25fee28708878f7fa4766f27ab9f2dc13715e94ae23368c53c5390a132f549b7b78aa4559889316a26575d1dceaa2f965fec2d545d38e15694e89813ee60223056657314dcad4e31c76219f305470612367db725d34ff7a69ea1e69371eacd3d1c71e277f7f5239edf0d9c95d4baab674545e4ff41cc0851f51fe0cd1614149420886cd8d8ca8c0b01d31f2c7479ffb237704c68f29a010183a847f997cc4209bfa5161d458ad5398c798af4c3dbefa7c233482578fcc6da39f8aa76ec95954e9adbba1b840b2238630303f7cc559024bcc170f1fb4851346d308342f04f1681ea719d3918b860ad367041a26200c7cb1a272e74b1d2c19f250f50893cff079f2700d16880d5e951d19bc5c6587a90e132cf021aa073970a65469c2c343121d88f8b305cf1513247670194244c81166b08a0ce11562796142c914abacac23dcc9c75ea0738a673d727462cd113d789aae68c972b377de3eb9fa31b68d56da606891b34395134c5068b8552384f8320a5509812504987e027b2d780267489b365afc9cb9ddae25fe2ad1478805f38181dcc9408894d06381105151659a13370f48a98f2ec04061bc1eced885fa2837d9397996631173685e8b9f55458879d9cfaa22ba8ced061cf39c620a4630d470416286862398b4a81d3b74742f70f59182aaf3a52dd784911acff33c10c730ceb1cf3f3293de522df2bcfc3cf4acc2e47aece0f781b51813042fe79a7356407777b78c2cb34806650faa211d89f0c2000520c0ac16c20040f840000128eab1e641070070c101e94646b0bbbbb3e7b66557aa459ef7795f48fad7cabcfbece067bf8f246d999f3ee7ec73d680be72f6b2774ba0af2f71f453ef02e1a1214cc7e4a42164b7b5e9b956027959113749a0aeb6590700e1b1355b03fa6a9b47aee0fdbd3fddbb7762d91d628766b8709dd1368a42069c14c961499825eaa0b95572a99c5b4b6d44d8473fb31ea461d7e62b758b22beb43da533a967ea63006a707226c9175d9d3fb71d519ee0c2650a13a63d416ed495a8cf99f54abda36937c97422c9dc7e6f676f4b156f6b6fbd2c7aebe3188eb418f991657e9a3d5cad52db3cb4f4910478fa4a3d5db4d71546d730df9badb58dbd9243edb6e9f6da26892caed51b93b4ea96cb7871ad649a762b17c752a0653202cd39e734aa45d36d4e03c75a666a998cf5880ce8f1e18b161de2b88064ce04b66c8113e60f5510505cb84d22280004048479f8e00194677eee237ad47e7d6672888e4d464f0c7902a50987260ff46a34ef4991efc992a6394233fc7521dabdf8824f500901ab3338f1d5a7522bf50c766cd802d5f0e0b44533a225196519d18c685c9ff36864bfb8ecd5e7ecd6759f9fdee69146a9756bb3b6d2aad3dcd4da9c2d14a5e37883d7abf85945b5a374b4a3dd8d5f9f69a67437727da646dd4f6976a499666bee33cd529b33a5b6b6fdf4398f9666e5a4b756ecfafc2010a57c9eb29823d0b01902f549c2105fda7e22a1e386471d3f5db4aedca6134d18f604b6b721f3cfa74f1ff3f4395b4705e4cedb985b0fad759ab57de0e50ba5336f437b35b152b4f5e2e76d0adb15e6f5766669134de2b4c3db2814cada3264de82168966e572b922b79262bda55a5c4e50afb7606ffdbcf5cea9997adb4c332fbbc9e9890d5594b2adbced2d526fbd7755fabc6dabb7578df5b6b5de5a6f2e22de369db7dde5f57603fb06ccdb0c6c6daa44de5a9f4c1c80c717d80f3a487469ba65aecfd989727ec3e3f32c4f209c60428837568e78d29285c839e737483ecfaeec39fa688567d7c1949deaaa7c4691731ef2ecd44adef27966b77a23e5878686d4d0a8987cfd8a1540592a54a850a142850a15de69449c0a728e46d5dddd4d12ee06ecdd1b8d88f333222ebbb9e137c072e324282828c83d28c8b79078776f3322cec93966aaa93e9f73cede659accd69a6fd1c2fb4ac4b56833e6455114dd4551745b15b7762f8a52de08b1a225ac872e518ee831fa48858b7e8218248a4148416de67c50071f14b415644c1b38af42850a15de3e88381554422e3e7ff042cd67b7d9f392cf3e6e7d769a1510763ebbcda8cd0b6292cebcdbf7315186f0e14b87207a18b9799c776f2b11e755224e64f384032a17fe5ecfd7c7eb442a8c7e88f3f7c5f481870f61bc403df1e2ba954970629cb082c694bfb7091e667c70428dd3d7ad9c417c0e1d43370f8d96f48946b1b8bb2f7f555c9fb783eb748bc2b92dee75faf5e7af0a37517fb49c61a28bd275df7cd9b926dd06f75ab159f2f7bb3eeff596badebba9058407535a40be450bef9d886be1ee3eba771811e76b7a78162cbcc1883816e41cf30f4afcd090f71711379473ce39672f3f4cf9152bbc7b10712b78b052d3e655a8f0de41c4a9a0ea32f2a2c8030f5816303cfc617313ddbce82d25e2c42e9d45e789dc1279eb20e288b2c6b0a8800e75c224b11365f5e336dbfad9cc89da451f659fb96de659433e676f2e56b1ded25acce8bed6f9277b75a221afb5c8d3d7a4182710f9d0214c2304991e59648a5082b6f9727e895e5d078b355f53540a45a35ad41d92af286aadeed5299c0dce0451bba989904f2f7cadb5d6ca41adde595b5fc75a840f3d783841c6c81626950251bdbbfa68e6d5dbcb45ad5e73699a7c65aa401c3b33a0017b128587caa656af4d2a006a4d33e7eb50ad7585d7da41ad9e26ea3b30c077e09d45c4756087eb57ac888aa2e4862a60863003e5b642eb57786311712bc839d2ba1e002f1e00de51220e004141414141414141de3988b8203450463810fdcc67e93fb3fd6ce679e6e3cc69578cce7c3d071c785b11711c9073cc67a43c79f4a477151147aa50a14285f70d224e059611bfc106de5444dc06eeeede5022ceadb0727031258967918067e16d838863218aa2288aa2142333554f44e41d45c41111f9df3bbbf78eb4277fbda188b85b86eb8786bc6b107143449ffdb3edb3cf31df089f9da6f5d99b06a3efa7caf565987cade6fd44c4d594d87184694a0c0e3dd2843972c36b1e3bed55ec80024f308c57c401c2730ff61c43505c603991610243d71a1bf00ff85aa95c1984b045e188651e83e199636f22444dd079dc517648e961cf0b594bb0ec61722b1b8aaaf9b2a3a4767d34593421d4d55f2d6a0e4e657a3c05048a0b09903a62e4dccada94f565d539f55150930dbcac51a01e7b8dbaf2b86e29411d2943d4e0c29818a8dcca2a95e6cbba7becf5aa8fdcb157ac9a9755ab6e3df6cad5f4180fd133e606206a708a33c3adac5d68b0d7b01ce9a5656a7aec5657c62679ecb3b44e8fed135414075eda2d7657a6e9b1d563273959fa78b10243e556daabc767b0db2d8b5d7869e93cb65d64eabc0b17de3388381756649a3c071c783b11711c5c593d497a37117164125fab79cb20e26a78deddb1debd6310713e2686df60036f1844dc06638a7c5090e7201f83bc9d445c508b16de4c445c0b728ed98737cf628367e1bd44c4b1f0e1c713b925f25692c5ecf9d9ccf3cccccfbc9388b8996835e645514c9317bd5f18abe61b2d17ba0819224c131e6899cfde48dca8d1aad5bdaca6a6be52c5f095ea88af5561be5ab9f0d5db0530babf6e9be8a1062590b092a54b06327fbd75583f34fb21ef23226e6897fb156efbe800bfc2db88885b11a6ea55a8f02e22e25410f97a2f1f86a18f61e81e56ab304e3e0c1d40849923438459c304955b99f4e15518fa09e10d279e10fe7a0f11713705fe8331c6d80accd6636f21220eff51c057ef20dd24e2c22f6b9e46f30622e2685fac7e1cc7d1697d847d74a2ae3e8efe05c9d7eafd43c4558c31f6f6d14c226ef442e53570ab81770f11a78117250f0474e7cb4e930d7ba086f8b9018d7920a7f5517520270202725b45a2ba5c2e17e40684dd6035780dde0093f0d8a79554112ba49eb0da618b8a150f7e7a90e1b12bf5e0f5d8bb051187bbb4c560540d0193c11c2633d43123078bcbadfaf0d5696ebeba9154105fbd79ccabef9c8803ea92c4a7709bc2e913998bd77b40ef21f5f0cac243093174a86e9e98f79ce6445889ccb3ca372fd481cf7b93ce0e2131f490a68f1242726c6ee5ecaacaa14324e23d4f092b2d536bd86c19b2f3a8aa7b4ead007529f2406c9c20faeab3d6fae44f951745a77e449c68a50394cfd973f6313bed23e23297151f3ae58306c596af212e43b8b869628b9d8a6482951aa00cb172030787db9dfaeb344cc45dca8488f3e694cfc06d064e97107119682579109c444819a2070c1b2baa203770f7a0d3dc33bae1c1171fa0a2f3b281080e70c2dccaa430314e0031086e59f2209d1750f16a02e5898815283730a0e7a848f9063a052b08562d5fbe56cf5aea7c75ba47c4d5a93945447e5a6539f3d82998a78488bb58761ce8a149505dd80bb9ed23fa25e284887cec639e633ec63ce67e8db07cec45528c13bc58cc69747d6c8cf98ce5e8a3ea31d711cbb19883f99c9de61171792aaa25a824ac17a5552c19aa21090000006315002020100e098582d1709c287a661f14800f75ac527a529a48c3300862cc18628c31060080000000c0c86c9800007f13ab4435366c98de9669a31ca869eea3e44b96dcd25ed2b7824322ad4427c7b6e4230060fa39142341d4e1d97df3dd2b37dabdcb6d820e95ae0381df925194bb3847d41ff8eb585c69b9a464d84087b63ea01185a8bbdbd51d45af7407be8a65174de2dbf2ceaebf37e075e963071c6f2a8264d6f369691a127c17ca34256c387bc21163286865d4c83ec575b255374361bbe6c7b0c09c50f3ac206161095bf26d0a9b0d36d5d87b57ec1a4981ba2bad745d5bb0ea46667e7ea886072a911b8042bb19225f16371680c2fe9f4e4e0582e818e8cdf1aee167774f71d1cd5770a6c7ee92d90452ebe264bd6f684ff9d334b07e4d1f3c5af9a7e8abb24999669533abbca3fdf484b092b6f996200991aa72d7b4688d72b55ee7ce64a6f3a3d7a9d231cd8ccb66ea353223a59d981df1bc6adaa01d40745f866d283f7920d14e4772b823ae5b9f393bf7870af52d7aeaed739a66bb16f7d8b67560060284dd0c09df98194f9acacf1e9e0a10641acedd37e5a3acd823aa8cf8908ebc27f5fa923a16e7039dc7cbf4332bc3edd86bee85cf733dae8bd30a85456363555d69f2bbf2cd98eb558766234241c7078e33b9bc1451404b5f7449eba6e732e69610fb879914393f70fbf079a3da3177e19aa3244443aa86ecec4032edd730ab718944addf573e4db66b553d5968aa2b1a342b9c439dd9f5d4bfd2d632b85f875eb724c40e63f63d4b33441a2eabffaab4e262a2929225a2b70adbd4abb99a046768359ed5b0ea8d9bd173b83cefe4a2d3365caf1b8dca0c3132bf89828b9d79f36b92d1c2af64d273fbf4fbe8eda2cf557d83a995bc5be9176fbb24d32e425a19c146f24ab2db1b2596f5b5c4c193dd2bf48d098313f4ded631f5718b9079fe6ef0308d92781132c0d88954bf68113732275a37d931569d817c24ddc4861ec6d3e38f8dbdd30bd875d2e0912701d6109d6a6683cda79cbcd42048669d8fe795d3f4327ba6454087956dceb6ba43c7b7715ed501a020a0412f7bfa82adab29b2ea1afe7792352e9cace2fea4b1c386584d748dfbf607dc1145321aa5a1dca9665acd3f78e23b6b53b4f8acbed2ef3aefb5461de83bf1ab4c9d68f0b138ffc234d39899c8c3b98aea0c520ec1107b7e54976eb456a8d012262e11fb7c8828c6b50c194586655df15febd6bd470ff539429737bc30e639d160bd09722869fad0c2ba2a7232bd3e7da4fe577cca482bfa2d839de8487d144a01e95f17da0a0858592aae5e46d10aa50c2c5ad57a51a380480a89334121c6bd8c7fe1a7474c4e89de262d7288790c3dd0489d44dd94dae94c31650a4e2d1b3def35735ef2c5ffc9d61719b79a1779e2667be9e8cd7bfd2bd4a0cf2d6f6b8bcebd1ef8fac729ec04a782f11a8313fd346f338def663d5b60a29bef91d7fda835f15e746374eecac7335270f35608837ed3bf62dd1b66d3b7660599b9fd052f15e549a8bb4d415b8c021648652903db5e05bfbb52a839f080791837a3643b21e90bcf679559be80fe4ef24de783b8b08f449a8dff413d8c8bdfcc6369f822e76fb099e83e7c499e038b455e691dd005cbe33436bde98409bd70a622280c7b49e88b5e6fb3259d6420c6fcd345d8f64b7d0a9b4c7f3a9295fb0af7b665b39f4dff3fefba4ad21272d41e62134b1fc0579b662474e1aba77969929a9d264b24749192119b517d6128414cc09ead47b5dfd28a5cd58987886d308e7511a492e1ec61247905241cb097a95736e362c760696ee4fcfc8efeddb4a84b362a7df1c2eb56860fdfa68e2ee7ab0db06d7877f81254703c8b111a452db164c077b17284768c08a950018786c562a4cf332e46e7f8efb6ac2ecb6244f6a69a21618cf9e22dd7082dd7c9c5f5d4c11c1848c88f85f7455f594978128f12563d8ee28442517a3e0f24553f69ad95b8ed17221aa9eff7532d26b72306659e227817c12577133d97541f532d3a6d2b5bbcf637cd6249a98343c50c4265361a38c9c42f3b904a2bc500d6f36871baae678511c22d1ea12e5c1ee6ea675b939e6a5b06ad302a9fa90d2b1a70e6ccd00863b81e274dc8c2f9ad68ee38a57678aa07ca95404f7408b1607d42233ddb34530080370f9d34ec4dc3b5bce10870a99d2120100838e5ee951ad009398885b00d4ab5f69d506d5ca4ed5c60094e6a78a635723c789ebf160b45116de6c0ab41eb39192c4de8a03175530b6c0778a4b8eb39011c076dd75e29c1d027ac4069d9a0517f8529271ad678c24f6544e53518ad37a2a5ad836c09ce1b8410001bae5b3420625bc54a31b0c1a2f3a96593d1872e48cba111d36eddb55abf7457ea312799db3dc68f6a4d38ad6488eb349d0e2f0300ab068b5819170ffa17cd1bcfd9768deda89dad977030bcbe8137465b2bf00b4f0ab1fa8f336495f96370646a109b358d61de4448ed9968bb5c7470e390031f6bcfeef2f00ab2ee3fb4ca563ae6b91dc2783a917825b443dcce1781dbcfc47f7f5ce03378df9db4f637ff161abf09c43174438f7826c3148c8c0ca756c7ab6132c4e665be9f83582d038c427f9091a662b394490ed26ff7e752082865888a3f3719fa6ebe094bde0c00ce7b91dcfe901acdf6333975856741338ade93462451d3484c1a998e59c45516aad2ad9e64d9835ab7a4abda1cb921cd7545989f129f9fefb4a4fbfaf4b7052d0c0ed580c02fa71c4d0126b773e9f60ef8917371f83532af5cb0c2ba3a67123239946e74336660c5dff8bb0ffe6018ad425c46feee17c330b6d467a1402fc0fcc773fa1481fe9d8ad5d82303e11c6a3453741b506c71455b79cc3460838a44eadd8f15b1de67f7a42667617769d8c56b43ee3412128f575576bedb860c49eeaa4623c74adaeb40bd2b53dd8737a0550146349cdd01f205b70ff3d06e88fcb05214fb482f17a87c56f5623599ee0f3b450b9df75416bb1f1077960928e8610aac0058059d30d10543086c610728d0ff384b835513ad2dabfab1c3e043d3dc5674261dd99401dc98a209cea14877ea549dda7a7e6ba1ad724813cbc97f63742b1209957cad1953d015a7efea2508b8cc40b862af60a96e4900ce244f9ec82416252b8a45ced581017e8c143bc4880915858bf44c4db1836a829ed46997f6d03b13cc65d80e62b6c5687d55016fecd91b497d0f7b22fb1976a682b43d0f8a8ecc2b88cc883747f1cd21e98e17e9c54d427277410c7b65195c1575345c9d24044abfe2ee3837a753082e7a09a1951d38412c58f7038e3f4c53438ee1cf415f1cfe20ece54970807f0dd368fb8725580c24b85383a662990e08469150d623e1c1870057bcae33949c54e46a45420f84d6a0556b740579aca58ab9c6c477e11a42c75ab5a82ee5b8ec6f03d05d336f244c085ce32e9a8dce3cee4fead0c88380bc39018929df7d25907d365fdc1ac6847aa65db3c19027ee9dcbd711606d700789d6b4746537af1636c8a3c9ce57399ed72c6b3c99b5d3cef44c906d0581653bf9bf9bbd4649a0a98ecc2241d61a877176bd17b8c9a7fe060df72f6c99bbaa5f18486339b1ecce1a61aee6dac3375383fd66dec41a97c324902385ab5080b826e3c05f8f4c9cd6b9bcbd0398b461958a29e2fa3aacf57fa15f7ebec61808cdab9a31fa329a8e1382ca7938ea88d312af8fbc809f3d8f82685742891469d35fbed131d2901e325ff87e49eca821118f096e744caf3d8966807bd4273fe1c60d7bb9ec998ffd846b259d2ecece0be150337734da602c65663183976ddbb2be6280a89aa20ed2256bbc467a121635fae41886864fc204d9f2496273ca1aa30d503c6658fcfd733a85112e0ea7dce2641b69d256d1d73150c0da350ae20042e37eb8e76a98eb4e8c7ff8cae5176bf4e07c708bafc1eaac2650528b9215c6e6abb688dd142c18fc847c165333990228a76a9f2ed266685159d510bb5cd1424ec9f6f95ac55388c074bed942eb67ae0aa95c7caf63009a1a06cb69acca8cc3189e4494f1af00cfa0c04fbf4fd8f7482ce963cdb9a9422e02627f87245058bbff7657de1fa2333498627b53f7925ab6a3c2b843b3d5bb8c2491ea238c4a935281a64b7857d19e6d793402936f8aadfdb9a6c3a6cbcc69ccc7f3f7234382db0dc21521aba0b69a02020e75a10b7d79a98fbe3bb73d9087fb2ebfacdc3caea1e0740abfdd53f918571ae121b3afe5da9b172eb2d4ec838a36a5c3376611486a734e91e0cb0cf31f9ac04ca9665ce320154d79b1a2d06431cbc88fa09cbb5063319d794468d207c0b0fccc647441a46ef6a05167c7723edd3e7418d06f99e484d819b9d84a4cdaa891b216961f6160bfe363c9d18cb045ca9b6ca62fd60ee61b041f2dff7ce8f2e4f67586660dac7209b5a749c340572715374111ec848327af42ff79c2f838598a218b386394d544c41f58f760033f02264b2bb55445d6e669dd5fa62f93d67e31917d8ffb097b3363be196d69dc5e47af52426bca0ed75f7c10551e856f44976d3bc0e9387bce98c2beb1aa2b8785c8f028e84f625bec763d1da84120fc22bc831a0fbf20e3d50ce606d971d591cdb6eb716ab2efccb50e0daab63aaea35429e56fb55a252ac703e792c362b6becbb935ff5309ff7293b4e065039735daf8d5b84e303b7cfb5e78c8c448e3882777002c78c2a9ba9cc796d41c5885599b8a3dfc7aad3c0b0917b235db7e979c3c0e21905e78a93029c9346a175a2d154555b5b69b6bb287a17f5be86c96e3e9e8a077b7309e76e28deaa32307f675ea215ce1097205ce42b69789a29793a0447f68b652a52ddbb8e9df429a3a3840078768f31738fd24c0ecfefb7c52bed02d6546401d90782cfe57e50e874d99512c788ee0097da7be8ccaa34ec1fff7d2a1920736236efa8dc3dcd3721703d03a405ba4acb82f741525dfc0419da9425de8d07213df0c263f3f096fbf1d3bfcc963559cd1cafbff9723127d5ac6b0de4554cc9f1010e4125e59430d94b0bf97549e365b17446578f268bb4ddf2503e7432e8ecebe5e2248a270601cb2fed208b1d5215772a347a7c73610b8d867337c54e3959d9a16d41f5c444f7acbc01f704038a74b8b11d2d2d2bfd0145c83021d49c0bd929d70a6fbcc0d5151a340ea9ea88873c8b5e69e551d6f7a0cf89777aa4bfef458bec49bd46579ff24090c05dc8ded89799395888a70be9624bfcdd31c91ba75086a164c86045caf1a812dc242217d2865cac7ecba94b8aad82c82d898320195a92a5070316050042fa1eb3483b06f80678cc3891edadc6b13a60e6d306d4b561dc0947c7a99f0f4eb0870e98808d216a41a874f9b76b8e60b9c90a56b017e70c341f9a86623227aa5cb5c3a51280661179d50aed0542b068226f217dc830fb61072590f717437f4ef7e84b27f04103ed93b4539aba14ef3d3d2a029716397d6905bfab0e6ba8fa4bf8a7a61fc4d27d542d392221ec4589981dedfc2da674a0bc2a2faec660eb594f9c5b807b2719f2f64d9eae1bfa8a7cf7dba416d958888468346aa4920b26439617a57121960f4a9d7701e0f3ccaced170c69d3bf233e7c96827db84ca4545395bb0511c7a661b99a4125dc53c527409e390eb9c149f1cab07fb99ebe14c6720e9a7f5fcab92c6c51967f4865c85e2dfcf41ee5231e4069e8c1c8785871fba05340762b60928e1c7bdd76b0f4e5699b712beac663f38d49633f8bc0b9625c71724a0fee597a6725d0c6ff0e55d6e07fdf2a4d67ca0fb42c82298037315ab4f69f4d47c84e58dfa6aee7ef3f59beef27805637f40429114ac7faa6286c9319251794f217d016db29bfa17734d727925653eb359aafec6f51dce63f2050417c627bf020bbdf20f611f020d4adc66ac1328e5a727d6944346c9c41f225dbe7cd30374e3dd8f761f07c7f0250bafa79fdfb1635380301839611045a507bdf648923fc5d23fb6c91128d097c9e5725738b0b1ae04ffea2b85fb736b72e8c081037da7096aab0c2b5cb220f9a591c737a9989e580e151c41bd6ca3db79b102fa76b334628da08310098ae23b667c987b8704ec88a17e1589431e7f62323d54b5053adac4d8cd6f0c7c4bd3a9514f55c2fae776cb3493f2d4dae55d362dcc34b723056d853945b23bb794cabc90a7d3a467afbe92e36a74e2b0e4387f4cb395788e4defc427f15af3a788276c301e0b08635481016c2df70be73b6357ca405da70a15090d9c8573cdd241bb1518f0bf8e7d4c13c3cb94d3f47c7b1d26dda3795f5d055bf1e6a2f28bb497930ae31aeaae9519a9061efea844d4de504c2f7c2a85d250b276d3eca8175ce89b2424e242cc4182956c99268d444a28021b22409011582182e7bd478e296c9275f93934ef5fc0203b9d9c804a03b6971d1899ae110bcd4da4829b4db9901bf88c4f4507a5eefacb11e0c683e235211b12fab67685b0b055b002fdb7e5e045d4658559c9b00a9425e7fe10a73e7502655dc1641fd5627aa088273da26fd17d06f4aee49deb7c45872816b509979b00adf4ba12c8436ebb67227db356020e7e4e3fa55ebd0884d1849e2140eda69b4aab4a3f574f5ce7a7c2e579cc0814e83b660f111caa5e81503dc4ebcfbc8a7dad53c734e40f82b9cc97b62986af30b4958f32aebb5c6e6968214171890bd59abfdf5ec1be3dff0e0231a7f495f3cd3b8a82c2237b1b6b47820b6a033eb2048748c0baa035b6115154fda2741b3d29bb859516f4e6b192209633072ab1aacc0bf69b151383cd41dc00cef94901cb64d368e97de98560952d470670347fb8363b0dabf0957fb958f9d6c269e2189b306be9d468131e166e251e9e8f12c6c98eaa5c2e8c7ccbdb62bdc0ac2ec00a12831522e0992af77dbc30c85a8379a884870e6bc15addb16a9ee9b54613ba218655d20889106f9b7e166cd1926ed51b1bbdc09ed2332ae8214412499803996e514082f19051c574d50a537079e81dc2218941898a1b2245a0769baa32a16bc0bad7ba047a237b2010a2619cf40b2b6c689e9e0f6c078993eec21bdd0d0f0aa60954c40e2c70e9dd1492dac04b674389b26987af791cc90b1bcc30797613e0855b108f9e9c3d0868c8ab9a1f16f758fc53e3208cbf46cff7eb8515559cb5d7751439700ece9e8f1f0832325b6a55535686581f9cd786e1465312e6f6c6006fec1487496a00c738a8e4e93b039dfcf8603ae152e4ca00048a42de857cf4f94d6061acbaa2a89dc54cf8703f00116ed073e2d86221f715a6cc78e7fc120945576a4f60072dc5170d0a374984a50ce44a44e2bf14ad2d43419690cffdf3bf97ece700b0f6a4e3a0563c3d298a6219c2fae2c4f845a5acba29fa0d4eae90654e1d20d83ac07147c030b42de704da2f5ae3ce20d5b217971f0217c9cc465d2ff9c3049b48746d881419412fb289a0417c0eb0da78d6e10c3b454fd6acfaa46558a0036a42b2325868eae7ea6e10281604a3de3bbe78d58c8a351ce28cb6fee078af8623e303e5ec8e3565e22ed6c478b5674be61e688f508752cc5f5e22b7a015fbbdad1edfb7557dd19c35d11f2b37cce1727baacb08d3a115636c91f4c4e54e78a4e05fd98048423df14b3fa6a4adf1da3cf5e25cadbcdcd0563087152e3505795532ff42005d02800be900562b8c9be8421b1691cb637d52daa2bb28000cb55cb7f1643ac02bfa51688b98c4267596d9f5f2cd1241923eb7e3ed803cc1fc471daf5fd2a328a4e79c4d4592af93eac660baaa792b604dd7318ec6c38f77f339e8ff520764afe3dee5b99ddb2e6a8ef74ac917b5c9b0daf2ebec98604395cd00b3e00962392991741a863ecc96f8a17e26a5ed82eba9f3d894e2567e98080abe3bd0dd69998ce85493886ca186efff4be8f90141f35bf943a502706b5b2ad674ae108d14f032370c3ebbf0ba9e237e428f6097d6381aba8239e6ddcf6c27ac0673f0dd3204b98ad378aa0e041a55db5947f443296d29d36afb2a3a210394a2c765981e521725bbf793e648f67f0e6d774cf719ebe6cbcec3c14673c9e8be4b9ce3a1fe985cf3a522ac3b5fd6ed3a23d8f357c65edb5013cc8f3105e81e28e9abc1d8e011d24c4c709a65f0b6abf35041986cd5c47df852dd37d52a04dcd1f5faff5867a98310b3faa30ccf1e77a6dcb84a402ff9df94c427574027b286641c923b2e70bc44ff28bbbb3ba08fc9c309eebbb2d35be45740d351a252d7c2757ed969752a11967b4e3c4d961325b19ce7c8f483e6e0c72a83620d757c22521cefe44b805a1ac076af6eb8bb88befed5aa6359bbf3b5dd7ee5393653e8eeb352bd6501d23391b566384659d6799b8c0762953deee0e51bb63f9aa6447a33ab6bc6bef85a2acdfc4b13bbc5a080cd766ad2bb1a425c6ef668567cacbab38f418441ab4d11180924315411195df3fa76eeba70b7e0b78f51aa4672f0175a16ccf3f25aef67e5755159147a3c363214d7307835dd5051c08709a637b45954178bd7a9d12f4f0c1af70ebd27d4d7be308b9a46e5e5bdce65d35946b219c3574c1be5cf270eb5ddc7877110ccd35aaeccfa62e09ef56a9b539acd9a3a9e5fa0c2d6958c2ce55c9d7e88884729e3576ecb56a5bd1ac2f276aa5a8aa5cfc18711fe2edb6a0c2d83be67d1ce673388afc66808b76a06450858322a01c09ccb515e081f91f1df4f43b923adcda288627348e8d1fd1ec23b4b2fe18e5839b1de3246e8a30baf3ea25fdf6cd03be599fd01e92ddb99da65d98c9d3ee4e419345c00c74c3436526b36145d49f67cb26e04120d86f30e2b4170355835ea5c6ea154e6bdcc34c549c87b4f2f53ab1447fb89a0a01c2327c3c165530d19f648fa1fb2367dc632280549b90286e6673f6edce6e07c2375c2bdd632057128e0e0774ad4d2439ea5745ad0bdb1aa333293e08348465443b0aab29d21281b20548c5fe5820a4f350076902cdb8d3444859a94718e4b1fb1167099706de117369cc1994a9768c0cc8fa67a2deb9de9781c3f07096f8c5956b0b312535a7933d22ceba8dd9abc1636c49039e1f6a172edb22c273939c0573be5aece6f7f0352b25e943440b63f04e22fb4cdd2f63bd28ddb306346952b0657bdab9ff190bc7fec946484fc4b7da26352dbd769c9bc994ca9cdf49f2013cc7d612056d5c90e2013f362ac1bb98811895392968e0f838338277e4298bff862957fd0b00e778e36c32e7bb8b3ab1022dc3b82c4065acbaf43ecc5bc8189e50d8e26d19af84d7d727a6b4a2bd7867dcca0fade695d1de0042fa5f4e9e0e947265c0b918c5d2ae70befef3c98b8c87664fe1501311e21d8e0d41010f48561cab1cd4a33410108c87fed970552235030f8fa08013348e73a4876cb247d2ce26fb68cc84471444c4035d8dcaabaf4b3a5b16cb6c9bb4c9bc5832bf8e4d5a102b27bb8f72e537e758890f2cb93e259e9b8ecc8c545bdfd460ed035dfbbb750ecfd556d7950b79adf13ea4f5fb11c07281a381e1a8ab668c55486c2fa26e435669c8b7e662c1762db8f4b26e64e5eb8d36b9d05c1c08698b52bcbfccaa60fe8e0bc2cb0ab24742adf1229d020c291fc91fe9491083cc9429e1374a7b106f72972e22c5f9b79f45cf2b8fd2805802090ee7e47c9c6f9d2028b40df0b624b8b787bf8a050ee7f9e75df6898db07c27b3554d66790286bd448bf327b803854d881406ebbaec7802db5861ca0bff4f111999efa516e134dc90bf39057683f6f0203f0f7b87b914fe2ae99209628fa9de854c84a033cd59c0099f7991d4adb94fe547bfce22a3a3a2df494e0432ea0fbb89e8312fc6831b2950ddff1e29b97082a9f612a9245350c6a7af0f16e3258abcd71c63a20fa34a568e9de11abde7c321eddda81a6654286147f815325f30784a1692baa54b60b085d953a39aa90cf5de8b4e54e33e25cfd8c7679a033a4abb4e0d2363b60d195fc29356ba91623852eace2bf5181b0c8d670fde34a37de3621b51616589c927084432eb0c0e6731b40db00d78dd4dbecbaaec18a9540eef8de48469b5b85d9cc04a9effcf4f2cc3c51e5efdc5e018e7db0bf784123fcd0e132d86a05f32fe5cb9776c7d9e918577efeb6fde0d2060dc2f556f785b7cbdbaaed8d76324f1db4b7476218acee3238dd4c8aefccf66f0bd71dd495e902ff61b23ea19b3c5a77f790b588741c2c677bd5f0fb8b19736eaa2345ec1361c368f4f3a581372a5113e0ba8b70ea83abd7f516c5b4dc5cfa9baba6065ec7d666025b55205341b4055a26c30004259f97c4c9b2258625bbdb4ad8737347174aea3470d19643836f3361b1725171b5e8f9dd67f596894ad421528316c86f58b9c29df07606e083b0311af6fe655b096f166273dbc102c28224c7b79fe1142c24c779edc446c6b99d64172c63e10eb107e699a1e37bee036f7b00b5f3aad901801f78fda1ddaed42a1ff35e05213572140fa4888b1960922eb00c9661bb687fac695f4faa5f49082f525e309e0f2bd560b7bc61c418ea06392ee9b0964a324d03bbe2779134fd649211d088005b0573065b7209c7e326790e3b3288d09ef451f2f7db1e244ad1db1c103243331a0509262aafcf336b29a34a06e348de0ea81e1193c895e89a1eff688260d42a38725021183534f56d3855a3b9d7c7c3d51fa5fe1ebcd6629726de49096417e01c4e4ad893c7171ee580058f1a961cdcc6b99ca14384bac6886405619f3b335658654b65e8ca0702389e2958c12d9b67526b7dabb2ccdeef6f639d929e64ec6d6fb9d898452ca1d3b111857e5890b9cced6778a26520055622c88651a030051fb305a6a0a2599644e3659ec4588d657650e9ff0ce1041c8b414098668a0e50440ad29952fb5c7114a1368c202e2d186d235cfe30fa86050892b2968bc20b3a40983655752ac90be93a72a695f9a949763c17c1b21f1febcb6c36f4fca07199918a0da12e7d23f42ddccccb30343bb3f4c1f81c0c1958c32505be9e5228df5da217b132aa439adbcc2d621e5d5a721d21fd9e903032b08735ca86a4da94449e2c04207b4b45a6e2e2e9e6a2d45ab54caabf4573d4c0b75f06c4517c8d38f863ca80f17f0d5401b061b070bf48018d6a422235285e42a893753e8f96cf66c897683fc9853471c64b180bb7d850055c4a41eb767d86c087c82ef24e91c3022e4ba342cb50e48c8a2ebd927a74a9c2e917d9b9ea184ff314f532b2eb1080de713c48651d9b6416b90205367663bb994058a63c9e66d4e43e1c93c89e83a62fc86d58b510c51a837d4931e16ab6df62d2f45b73c57490a5969ea05f742c7066977909661306af4c769b4523e1875b190e4c823255908d70237f6a52d4346fa2e62e66a9e1cb334e68672d725f22a2d15e827c982d87b39a94929f79574156cc742bd2eda794edc215b3e7795b86f838975dee23b3861693a24ff6821cfff5dfec7cecae8015da95b9705592cede8369f16246d1e9efce1ea6391610d7ba36281c1b7bae5ffdc15a5c4606139cc95a202b6e478e88faab46b392dbec2d276e61d4e62b2792f1c30674da3fee7ccac7208c50ac9fbbcdb85d7138643f814f3cc2d283bab673c2b87d48259c77fe55605c0dc20d8c0ef3bc40b878fd38dc9bdb4662240d8fba4f5f0ac028dee48158ab6f5f58d4ccd40bbf4bbe875110d3a55b859891082b60f788440b2cb860ca804f2af76cd58026a9fad186cb39a7687814e12be9cac313833adb7ac8a264e11e0919aa44d286202da7fed50b23e7bd8a258cc87ab21eacae2a844894d24486a888abddaabceaf0a293dd421df7b6297f28261085f8d5fefb7e52f27550069baa3091d9b318207cfd387919760cb34eac2c58a915946e1d7404a3d1f209ba7081420d1ea2181c71560c7ab77db0c0ad888f4d13a1e02ad76b19af16e23620ec349c8de53f4bfca3167abbea8a31468e2173210c089f6d895acdce60520073f4016023c4cfa7be292ad867be31b1302b0baa2d1648655fac03a3ddc048486671dade389ebe41757fd8f204bc708155489e8ef702d10b9ec0884108136711ba4b6cb55eee018f3383fec32422540784eb2a28c1ee7e8844c883c40243f4610f1be3f3a2f76dec4a5e9e9c1f19ee87dc7c2e93d588f2a62404f33b0bbb3975082529bc556459e5818d14dd972abfef1406c65fe8e582c0d49847386c8d5f43c541a8cce3dc8cd3eaeb5f66c632fc447d8ca539e1124535b174efde95f7a5359fa5b2474f10d7e912e20a7dd136774169800bae8db720f3ca4b898372474a86be2994e410de2b582db72025abc539c017775b85238dfd365a17d4e5f04db05906e0cfda436d48bbc9d55b25dc9cbea834f9bba046135671eb92e40991e7d82eaed28268936fa59f3ae2b5ed8afbdb8decbd7c3b1570a5fb04b9aeec0688e673e967007ec7c15d5c9d5e26a8a50d39ab3eb30c772b5a467e0c5efa5bb32ce6c8865b850bdac684deddef54669b16d1df390b0b62f89b2f8f66bee848fbf193fd573dd722991ca27e4b5db5f303e6ba158d6b8853e341adf0b0ad911a0faa64664aeadeefb1955e7238a9aa54f6fa25896aeb5f61d82b5359398c9ca31c4c4d7a5b0445016544bfacb648d12ba706d20c28b126f385a1ede106694604df72b0791f3171ec147569d69fce59dc23e2e03b3a4d290b7c642cc13c5f428bde37b35926948699724f0074ecc79558f6ce3f4cd056ae4b2692c7adf0f6c38580e6ef3ef0a1150493b63c0813fcb0730a85ba5ca63c6d5aa16cdf725aacad4f8cecd24e545103f9d4262d6f67189b4ffd714c6daf44f52a91e3d29dc01498046086431aa2c274a299ff2dc1ea8ba8cd4471bcd42c43519955945246a99eecbac4dc2712bae7b744fe68db724e61d104ab160318d957c364b20a581f03a07b6cc31fae344e245f715426446d5c75124b6af72ac700f5513f42de1b09c4dab1350035146da18e7eb6f75355af0964db664b221a2acb96af33101ecd603200f01e9635c1c02b2c08d4ba5d04e2bab624b8389f1b6e2f6054f882063305d962325465175b7177e733ca8f50c3295ace7f51210538ca0bf7c585f9f9e8758e54dc5470f058b72001c9468ace0a7b03fd0b3d9bb2adbf4bcbe3adf1c445157836810be279f6863f36e97d15592d34e5fe041a6ec47775dcb1d64bf2dfb5530196bcbeb22d08902613bf8a1456438c5f095361401463b3c6dfe3e34aaa1f6e9c9dc3e04e8037d6e41e5ddd9e6882f2628dcc633920bfc3bdc4c244f481c2aa5c99648ba682dbf55e8c5c995bcd1e9d352db779e64e97c55a34b352e1e45187c9542844bf911de5182e3234f235da4e059b4d270d9c371dea7a4a20d8c80d5a9ad9d3b0ddf1394396dc1a02b6f2da34a8e1c5dd933171287a022e4539576056188066f8526ef04dd5aecf46cdf641dab5c0a598edda4873bef5602f8d9797c8ccbf155e4a96c1c77fbbd09a4976d31aece3bab3ba39d56aab444759d9aab0350ff7065bead576ac70786a553d2964ef725486f099b48d99237c7c37ea1f8f8b87fcd7a6e6a669c42a9a4ee092000a6b23b9914316948c5b7c10beb9e587d0eb448b4c9aa8ade8c7aec670e23002d92f5531cf4a17ede18c6835be7683e5184b4288057efcb5fe96d2b21a03df258157db1be53ae2f964a29cc807890230ccdd6809414ca80ed854473b5a3c58b208f946cdea30628014adda059a50fdf4f10b0e34829efc4d7f4c6670c745391dd1f78c1c624c155eebf124db055377536761eae8217528c092831e36f9e4f9cf4894177c2f9f7a214df731a2c0234f752ff382b4b2cc30409ef57ad511a287a8aca691f95a169ef2f119103160a2f9bd925de3ac63ea884726bd0003f7b36171459e54cb02418b56e89390c4545868948bf6f82f03dc0b64c86017eedb26225ff5549321b14814e6351424e1fc7d6fb39ef83f4ec1b751f77f235ff60a28219f0edd2ff0992fb40e3fa7b8fbfbd3bff3b94c097806dcf47e7c71c10bdde3a5cb8e6b14d34cdc7484fa98ecf8443e8c6cef2f5f1287bcbc1f24fe418501d5cfdc7ebd17defb0f0beb6423eecdcf53c9b862d840f06cee00fc11d8754103699e028053316a80efef380f780a1814123718f021d20116b33d29bd9e8d6bf6e6ca382ada3495e2eb5af6d43a8c54c22b3751cbb470d1e6908f578d18d2d1fc7e41738923de4550d8b27cb4aafce97a36e839fc5a1ed8b07cd8102215544a51f94c8ac9bf9495fa895d5b6d02e88c45cd522b20755760820f0b2e0bbcda6abda1f4102194e9b719956ae4d9231b491fc5b11635de4f3344ba6c5b51e8e2f61c107991acf7e3efc230a5beeb2298731862ac272298a669532159e16b8f776bb4f26fa89632754afd4dc92d9fd6f48754dc0a159a19dea0ac76190fef290b8cf4ebd9173a8bcc9a9091e9c6cae4570c0ecfeca2fd95301865099f4c57ea12af5e591705f9b5bee8f3aa52e8235f532156c4a4c93d824517960e474c9fe6a9d663e177b47fbc0c4d6b33a58819260d232c5f0512cf77770b9393cbd81fac72f14dc124a48c9b4174c4a3ae045e1718195ed830c08b05fa08dcce078069e935103f880f952a803fcd1faef20a89facd153d5bf81ec856584cbd2852f92ce87f237ccfda2f4d95bef0559fa47f979af379d0df16fb749ec964c5a9919ac7c892a9a9fd209d9a93cab9c719ae1d336eb35eb09621de23b789a8902dbd3eaad2b382611320e50ef6ebd0bbcf8a7097941ebfa1f633219fff61b78c9b4801023142c1084cdcb6e85ed147f051f20bc8cfc1d7f9136429efded2ea3f7c98887e7ebcf76388e3802582bb0089eaab7cc5ed8f1460dca01f94a1b508088de2f6a9d10e7f6102fe9a550059e1bcdb0735ebd5b296ccf8937ae7bafbe10334a0327929c72511806ddefb683df734a894ee12ef6ed0016c9da0555d8643e4f1607bc02a27110139870cc8a14d6647f77dc152a1670a8143197f0f3ee7366c8760d5e3a051a16685aa89b3ee09c10616a32684d9eb1716d0482b52f55293216abdea12a043292fdc5c978850633bc5986fe01cf06f45e5657c2f74b215a8d8caed4236de3315d1501f0cc9e22bc31690240e15270f60add750b1a7c83bcd1e811a7884f63d2d0aa7baaffaf3c5a9825c8608e96c86b33e96e2e6e6f43a2b6c4fac7afdcc6b7f1c616876cc70bf511f796a4a31d273d1a98406cfc29578545acc03a23f91f77b3bc1f1a698e83fad3372f564210373ef60a1e59cf809974f07c054a4d41cae45341abaca76a57457daecf80b5d240d64dc1276abfce604456a2f502e26ace29cd258bab94a4a2a145ea6635e10065e2d07ad5b627aa2aef8ddb96fadcf5212e4946b28512f6545d6127217e3f60b9471afab9165502e473eb5a4673cc308042563e260bd297cc684aa1f013208940c7bf18eeb96bb892d0cc86b2d9e466ac5ea1d80011ab9a3046ad97c44c5a8474dd2fe3c961fbe89cebfafe04799048ea7bb2d741cb2014cf1b45bd6f25a3a4418153399b067fc28d1939955b48c69992da89cbfcb3a8b22758f7a4e9a3c7fbbab6d0c8a4946c83177455d31bd1f85e107a8273cfb04694e257f9857118fd8591b17c421b927657ce1d967ca0c247ffaec9c0fbb69ea7e6d2c3e75d337f1a057e7d47ce090663ad365d1f2849890af83c02018bb68f6fcdf35a4f717caeb27b9afe259c607b294ad59856cbb02e859619a9a144539ca4ea5e6a218cc7f2c8d1bf6a25188949bb772eb9c70f093ece2096ee81f5ee81fa6c9a0e6c0adba937fe21a9d28d07f53af617de4c288f135896eaa120878b75e54e164f82bd6b5c5deae001c07ea49a03535d4cebd71e75655ce51f7ce8a32efa1e90674de802c5bbc42907450a396c138bfe430d1a2e2d438120ca66a7e1c61dbb121aaccc3991c08a52789525c2d7242b53b7210fc504f37c24c53521483d55779eb45ee9d902f7524eac39e55eaa99bf36d6d21b5f2c5280da5d9c080235474cc13f71aa1e7408726870ba1b990cae5bd247c836259cfb964d84f2f5485398eeb10368cd68dc5036232e6d09f9ed57f52faf9f05cbcdf7b84f681d14d86dd8670f529c0829b61f57796a48409f320255cc03411ee09eabe8fdd13ce3849d069006edd24a07f7fb89d6c10e7120c9ca7f9861af463177ddbc2c17fe4c20cf70f095a472b02bb6b0d2930075f28b57774df855304a79cfcd64f64145fef5033404920109e2601c419742970970db42fa0e2d2e2834f6553fe5d209a0fe403782c58fe5feb919408f0f821b37a03d0ae0e56a3caffa147a8adf872e6901c63afd11841ec6c764fc7d4bf277e60dfb73b64d0a6c39ca2ff83cfec55692afc420387376c418f961b3b4c2b30514e36f54f632bb7d58e887979e4ac8d4bdbc3e1bb15a258be1535b8b8d3fe4fb2098c5881f390bc8bb686c7425444542e887690ba7e3fbe343f4f832520b4123a59cb5e501240a96460a72d871552e7732e658ac94caae4b90f89740e36a5ceb03406289d428e759beeef1f69670df4fe22bf7e1c86ff77119edca24768101816cf71968589e5e217ea7014d715f542647369990ebb7fbdc6e44a70bd0698e3f131984f6856bd5b921aa629769820af8809b8575e8a5f0ff682073d7646b25fa0d60262d107ca0f2b12d5bcb280dd4db0c758f49f265f6055a6a86177af0eacf6a1e39b279efc19641b06c8b1602dbf547b4ef22d459a5ce3e52aa621820c9bfc7098e2206f24ec035aa22dde379a15567e901e7b16c9ce4d23003ce4b833319260825a09d5690f3ff2526565671484e54329c07bb0d4e3979d30988d2660f65f2ee51bf6400f5ecd1943e1f44261f96c8b168f8214a50d7ea089985b0dbe64ec01e45a0e620f070b25a94bb4207fdcd5584d894a9d9af1ffc2e3640ca13a55f4a50879c110ad520d0862c1a5527668c332111978a9f43e5d6ce35488778adb97a4c0ed0f5a3c6fef74923849a5f3b0e634824aa8d906d2b4e35779a3659507131f02fd30c883b1a390d4e06a088ad46060dc4feb71504db898d7b29d1e276f5b5db900427e0e7b3835d4d4aff7f9abc56d3ec78021c555416d65821b0608d88d7495ba88df2f69673d51b801650e99f9aad270f370c125fa425b977b50b210e5ea5f0666ecc0cac21ebc087f985249819675547e451d957ce9dd9c987a6400dc79492293b4629e5e434123ecbe40c341b8832d34ca414801f9b3bb6bcf92ead7a70918ed7dfc4ba4742639be26e7fc1b910b3a390f86b1f5c22449ca2517f3bcbc3ebee8a45ebe9de6fbde36e61d1de8383b40c5964e6dce3d423eb97711b00220be542baaffcc3b0ede1e35d5bd9f26d8c1f0a22482eed53f9d562b03e0d17782fd02dc0fe14297d5ba8c5b5abbed7781a5e3aed6312d77394a65366b60344d42df65dfdb907933d294d043b759feeee2310c48aee41f5c89617067a4597de771b803aa2c0796faea0c822c7096276869bf06878bc5571621aa2d8cc135f2d77f2e32da1f59efa054ed29bb4b5ddfe4460c19d3fcf26791ea16bc7a4bac275000f6c37e6102c66bbe304303f584aefa553e7db4b14c95b4f4ed477860aead8d0abb52482f4eba19e28e22faadbe891a503c1bded36d0f1bf94647aad47f623b135a84ae09117ee708dd5861e650af3c861151e8c5d99eea81638eb1c5bdae62de719b0d45acce91f7fa4a47013fe6a270128dee365d9f3ae33c6cef7e3fca330cd3902b0015ab3482583d036ce700d3ea19b824cf2effce93181cd4aa61a036c43fed7d396e721b8ecb46823313761815dbaac733c086dae703a1e108e3cdd2c2754f312b101a093a8ea68d968a62c73fc7e74a21a59d9751cfa5993cf156ef601af8ad5b236c6533497a667de7617a65128ccb282167628ef1bc5eb86fb85f069a794b36df87b7fd16a099e55805fe3e1bdcd3381c107949cb50f451fe8d018985aa4b32a27c384754e485f080f904b81bb9d069552e0ea84dd73af1e20d7a0cb712b990916816ec30c2f0d79376a322eebc3f59293fcc33d4e918d112dcf1eda603ff8e305fca322f9215811a5574eb15f9ca6d6a55332e68576ab28a91f94cb28881ea8c6ec7de7f9538b5d9edabc3a05011335f0e566179be4072528cda620b4370408ffe9e655fc897c4f26f6afea64ae43984631647ee07a9262d03a6f83a5015a6e0e9f1cdef6a8011af65421ab1b0cc83c3072a0cdfde3f67f04483e54d3c8cf3d3e37a94e87ae80d45e047e0e91c91d15fb451096f434caf931beeda6c4227e2b0ea98557daa1b82271625867fe9034269566fc58cc2b5fe5c3d18e9bb2e348b8eee6e4927bd8bbd3b5c83ad982ac10912bba1244ae4fe64a8ce4ab84aa5382bf3c01d0ad93078226462a8fb546735709d68017914bdda841f7026a6422120cd34d0d2fbb1590a08485540b3e24a366fab4ea16802cc8f30e67cf636ef803905ac69ae26f0860212ce7856dc316a64c875fc4532493cd16847b61252084069520c5e7c731b7e416566b03198eb10ae61677d60a076d021527334c9cc2d920671179d80d09b143e15aeab45176e03f0f2889169f59104c0fc28f8ca6b52c1a58993e2b40f5a625e4d59417e75a308ef15af27aa2918f3e29956180829862a0fb2ce1fc4dc954f0be6412c3e90f6f392e72b6de1377469c1341508b30902d39b2c5da573f9d84506a138ab081f24cccefe1adb54216d524678c7f9fc017cc9935f8557a3d968bb91a2658df32a3ca0a1449f73152347927133fda902c42302a24edcfc30d14693357bd2a640d4d831ae50c8fc8fd545558fc5683e1d84194d851e2f56d9cffa04f8406a1dddbcf197baad3020d08ac9cdc89e5bb263df47067a7242287bd0acdb3d4c5b334756ef082c5b46efd74ce93dd53132177e7f5f81d3757706a915d404b0d5c9069739464493c03efe8caf23c994aede20f78fe452393d15e31c29d042d751ff81b9e7a740c4e7747dc1d52f2bbaeb64fd4bdc0a16113a6b6b3d43ec55fd9608d72ca44785eabfd0ec2b867cfff306f40cd51d02451b334aa17d29337bdaa4652ce7daf9dcf2abd84569a706a0aa7904a40845ff1aa7ce95fad1aaa8ce8e7c1daa0201d2492616ef56933d9af569e636d44ba898cb93bf5df2510ab3c303f0b4673cf4f353795326b82416dbb7d4cd4afc406559236072486b805b4c6776bc1f0dca815c62cc8b4e44b5e2017a87a22b750c5d22df19dad490a4524c287ce0028f266753157e1db8be7767e772abdb7ef70d57bbeeee5c6fbbd973bbe96adffd8ecb56b77beeb7aeecdcdd75d9eebec76dd3d59dfb7b175b6ef7ba6dbbde71b7eb722bb8bdcdd92a569f5bb9e370eb96f966756f48455c33c5ab47e9dfe64f73949aea974a18272a65f8b8e2cf33da9fe5fb0c64aa373478e39832656d79b8fbd64aacd857106e650bbf2a896c824c366b68d0313d74102c524810ace125fb163f5f0dcf401f45234a5e4e8bd9296fb4bd410f2a20fe49e7bdd60e759f6655404fed598f723e6662fb73d761caddc0d61101033d0c8f1318ad2885df9cc54e8864d7f4fdfb299d661f5e42d7e4c26627d668b78e31438542440b9e690cc00b6653669348e2a3550c06920fb365b047b72d7c2dbf28171b4ffcffa98ef50d83346a5e2262fabbcaa92fd72617ff1e051842ccbb286e26d224e38d06056a1134eb08fb340092becd7469172069d230a80d0f2329c91b27a9551291eb31d4bf23bd0ae7fc396643dcbf1226e4b331f4c93388b193a460c2c92716958e383328dc386b8c1c0fb41f832602d669d154ca850deffd11f779159b6190f510d20ba021e4ab26430d9bb91584822aff8a0f8cb6e63a410bb000ccda5372b66b756dc172f965db92058054db93d6f8b68b2de037e2b3fe2e529d8a144a2cde16eb6ffe6772af23fe55c3ea6a769033d84e7189bf0d9e838b9c885f605292fd8bf961bdb1774dc6d8223850b6163e2894844f0d3a3df36d720d404b539ca6b1357770d4f4da5c58abeff8eb04a22dc995cf3685a009cbdd6a5223f5f8364d81830d2e48151bc64aa0b5760c8b85db824d161559006e8c2ffdd525ad65e397515d73e004a934776069e8e606e85fb0c881ce1f1223fdb11d20d87b7874d6b27f6369bce25f190192a9cc775784da3b22b4c0029ae6354f38cccb569beee663085978a90ba9ad9c93b9d9a220ec8e5099e165180912b741e62bbf38b0a848112a8e2eff2d2ac66904989ed58ad3ebec4c415948b4c8c0da71d08626426e4500027ec2b6ec225a163ee4e8c9d59c0520d950ebdf93aa1e810f891060b038975dbbc215abe01ff304d0565d0549e7c4c040a8cc6c15185277efddce51c032e92b31b7ab399cd574a96eb2b760bbac6970a43247e9404325aa89ddf051620283803ee19d902e0f4d4bc8a03858f310711d901dc47ae95202a96112dc37457cef4dd1fdb7e25241fcdc2eb642bd4cf7a6cca62c395215cb30460442178ab981f6fa1369eac108bd4a8e6546810ba2d6b8adccbd0026cc709c0a5786295dbf4f33d356af95de09f43dde0d44b19c16ae93cba066ce9b7a1ce0d211cdcac2ba46e24924124b6c37f756e99e1abcd8c4f1527e6fb99d680ab202f7dbae212b206c7b713ecdb66cd490a90c9e0b67bcc7289467d534d1137835b53a4a1a09b5365278bdf575aef0f262c8d831350ae533f42682e39f631f6947292cc6c4f0dd02c333885df180e5e73f1e8b3a94ec0167e81e2b3be1802aad4abbfa3b38fbc5f2f7f2bb3d4ce75a80d4503b4f048f9a3063fba145f62e0fef93c16f9ecec85ea32701f4b7b9e5b48f9b63882811198181d06095e720ad4ebfbc740198663fb89611c0ef6d52197f669e5e00c7ac71225caf4d9bf2874363a0bf9d76490594634d3c995c6c25d01591e94a25108fdf1444e6bfecaa5705620264b20f1ff8b78024e9fb08da8358751153a6c7d41a56d68664eac5b30efa4eeb308d9d74e4adc736a2d44bab9904cf33f55fd23ecf08b8911072ce13442114f83b85fca586c129ed0004083b9931a3069496e99e60012cc8e76848ead50be630af0095802d598a9e91f4a3c1ac37b1710465a54243eba9a0a6fb6c139ae585de3cf0be690226716c692d51c4796142fc81cfc801d8b3c073db0ac7b8270e15a13536d0ca1d087f56f5e17b3aaaf29e54a01c1b5a96aec723bcffb10196e50e73fcf0d2a12a748c3894500500acea58f4946c12f5ada21516a8f5884b3595f22f1b754da03ac22ac85badce186809b92a958a0728def7fd5978c76620faf577de321044745962192f4ad357522fe5c509f0222e4022208250709cb9f99755eb68b12466a673e83fde51a1f1238485476b91357cf5c845e82799594b97c4c7933ee0f765a6ae99f03aed5d6e35f905bbfbed5f0451cf1b3adf014b947d076ece5e290bd9779bae23307cce40076d3c321667ab5b6b67e8bd78c11433c1f9f7ed4e46bfea93fc90a704d21b0081c755b5c77289512b11aa18ce62765201f66297d6982210d62c9fd00195fc1afdb215b39eba3474f49d39cb316c31d586155b711d0b1c2e22f3251a783e23104644f929c423314cf7b5539d5fce24ddb4d7c6d74acf274d34840547bf5973f16d39ec3544bc4cc761987341aeed7087c4e8d7ca33bfd8d215c19636143bd4c8797c836da60418bf80ac09cd9c9221164827fc3828435f827a3dc1ed8b4ba6d3629c54f404e1717de2a25fd5d1eb8fc1ced1b92de69d332086886d5f57b792f77a37197d5d28d5e5c2ac71a62b4197e95bde90c73501c4e263f0e79729fa948a130b15a91b5527a443eaceb1843ca438e1e6d55b7bb5fb7633952ade3cca41514a046dfecf31b08ad3dd97b065225d395bb2759670dc6e43c90006719b4f304fd9ac328c114aadefb317da80e7d9824763e2c39c628bf283a4d5be56db8a30fabba68eb499f961fe77b52fc7b045be61850f0f41a1090edfccf71dabe9b55e5e5fa00f90749860af1955d7372b53d1b865dfc8c4110bfdc602e3a767649acfc807a2edfec8b53a50cc3e9f681c51631855e486a791a9a2f72f5a9aa34ff85994d95139bf4802f501b7372b1884e9011866e5fb4ce3aa50dc94c5112dc19838f2c7925614c21f9a9646d5369a7f974756940e283ea142018636f605069f5e1cca53ada4df88b18a55d7d133d5129daf990f166deac5bcdb8f35095d372e3fba28675a18f18fbe5ee848dd36a18d611ddf3a9045d9e43c12f82b239e53d73648a38068d1357308ef0d0a8478cbc88e0163c150ac3ab87bf82523587ba8e638ecba1397a655cff7eaa5e4566afb0764624259b8ade96846392f3520eb52d712b6c81fc28983dc793ec65250fc35abf1961e3f10e70b008f625b12d8b97bc1c8000afb2c7d10349281de67744510367d57dca6d538d469670b41c4030fa47e9472bafedc25b552c333071dbbb686125b7ef1cff1da31bfa2a22b45a336c928ad247ffd59362704438bff02a9d4d46d2a6f9599f5d9bf31e07c0843eb9a0b6a1e67407aa7708a39c05f8295085071141cb53a995e5462417a2da92231358905b45d1e9a3e498228de06104ff3c0c76a8ea47f76e2507d62d4ce76f1c98bc68306ae560b47121ae0f4a756684e3c14cc6ad039c434a30d82b4f60e19891acd5c288367bc7b17a740c2cd618959f933680548779664891abcd2f250153ab18734d6b3ea118369e1fc52017556b581d002dca9e0c4fbc5b89e301844631454f7e2e6713a8a2b86ce49be1d4242f31d22a0f6f7448e699cea64cda0586755a42798379634e7b9cf5d9c120a73287bfc7d98597e711c27aa5eb9e80f5d55c10d9ce465619c723a994d439f1337806d6391cd0cf5a43d346b2a9ec0c90ef0fae42a803fd083fa758135982542d055415340ce0efde0a98a2fe36e66582b6f6eff14fe1a2f1b190c2697b88ad9b1dce6529de832614e19701e6d11341452637d6d66b8cef0c24f03032275dc2d286b25253e37832153e3ade486d6941b92755346e6a2f2faf02abc8b32d6ebbf867538b04e4c777bed5fd47a6c7cdd7feacdc497656094d2000e0641d33b0f74e5e70213eff5db9f30067afa075d30f5b33ef6ec1758449c933ba8cab9eee93311ddc35d2ecf7a19e7554673723d7ed52d8b50e94e9d850695da3d7b6dd8d112935493aad50afe59350e6d3081919c41980b910201cdf0e9d0ce50e48a475b082403186095064b8168e094a08a37b58a4efd57830ee764832bd71902c6d5f4ddc3b219a549ea3f6a999c2119f50c410d5342d7383fd55a5af1360653048247f80bb4de76a96b6358bb4bc0af08992d59b84b04728a58b49f83d89199fe6255bfdf5205323610a788d2c526051ff0aa6189600b3e8842a6500b209cd02c4dbb9a32eb0ffd9e671f32c13fbd92a78b92278dcda272f4272fd79946a2b79ee83113f9500cee6546810fa57071fc756f96eaecf87feb106936315a978943a77bcdb21504858ac291526852674e93ed4fb92502fa0f708905223dad151e224038a01a7089ee61d0f9ca43e7f7f8369079cd5c0029bf9af082f2095dae416c0fe2ef1d072a8851f1e4d566e311c4a2c0bbb0313c467c40626dd109cc325681068b027bbd06e274c86d1039b15478c4f24df93812d9111b94c0313a62951c6a2a50d40fc5be159c39e5d30676a6ef0308c2557fd1a85866312421fcc3d123c1339852747edf0ccba3f4c05f7566208a76d582c531103da2a464737352a87ebd61d104d558af0b5811cdc4cba330a9ce87fad0f6cf448c5bd6138115190978db74721160dfeccd461c066ce6bb57022b34c07299474ce5429b60f56516a480a4c291faa98cba7464cb1a35913d0168177c3f9d97857f6725f9f1dd467fd37f2b95809fb47a3367f90e43233b95e6dbc4598596372ddd9a3e210896c6c7e70dec1af0fdceba8d840c23116cadb35bbaef56ad48f3d1d037c68827ecf30fc3db3a9d892b06fc6f88ae1beb852e26e4dd0050f6c5e888fb6a8baf9ae2acfde0c6a0dd3ddfae23034310c239db58c5de562eb0a21f579f65d69e753743554d63afb7678e88e5c1b4222c778d574da271720fbd8e2badac8e85be8e75a09a731a3bd51009376af761b95eeed65ee8f7c320444fb0d98aa4fbb66675cc843c7f2c8b07f7406c3c67132f25e2b81d6d091b05e95960c7038b2f0c8a8891a06a4d44454175c618fd5a758701f39fe651631e522ee1f884e6a6883177b81515999e43ff9b664c96489af3f4609e3089e653d3904694fa9408e7433739512417e7119ff81439790e6c90cdd6cc4a88379fe631cca335e82e15a035ff369e68ccff734e61b766516ed2939d4f9de8d50392d497dd324c4a84bdb84757a818e659293172b3dde95ff5b4290912337c1e4e4a328626e8944e5824b9b46662339690c90efe383ec0ce7726e26dc8d50969c745d25891de7300d7ad79848bdc734fbb7d046257f684f8dbe03910e6a3688de17d627c8f68c4ba0891b018d480830b2c1836b99cd66971fca7f995e2705bf5e44ba4f51ba9809730628a4239e1dcb7afd0d113fd73ea883e9dc505ab64527a5b381834fd3317b0fff49d9d90552a40f0398c9935acf097c7ce2eab53c23c52ea0276fe3dbf6d92dce3b6018798a4bff36e90c8349010909871104e12833bb41d8538062a55aacd00385b0432cbe287cebf6df2b4a8d1f78d8ffc010f899d5d7399278ba5a4f685b3915bf6cb8778c27bca4e8ad303f83fd9e36a2c41e5066621e7fcbaebcb1d51f3ac83aeb659a16c3e64b0fecab33132e32e2972ec32b2f872362b5762093611063ab40777020ada8a6f3215d84b8e70dd032c1250ec6bb6ad06a3d47af7cb8bce6f9071e3dc9939493fa4def2ed29c830e10005b8d9f56e4b6cd62db3e7d54998d821bfc7d1636e72729c81d2b249cd4774cb52b4a82cda613c73d936c159ca06eb6c63c43aa26e5037b2017f5161326213a5be09e36629d0e5406385bf8c80fc159260205a523c2eb1939e63933289c612a0b843615b10f7f3724b3311429fe0a5eb80ae83c567aeb4a5b83468b50cb44583a64e2d6ddfdc3639accf8e759f3e6c65bac0a6162f1c07bbc4e5d640f127838eeeb8b877757fd0a4efc4156a147f22d8f52e72ef404bd8a73e8e9e95b5fe9b95bd5dc724ce710260a00eb179daf5680fbd8f21f1413e144c3b14b29bec0b238367c698e053c10715bc42b87f9f36fa289bff679d263bb4d07fb811af4cc2dd468be9b89838da9b1c99ff0e3e1bb355f8627f72299c2c0e911400c8a06079f0f53d1ce87bb158dc55a9356de9076a514bc46a751ad48d160889e4c9fc546d82edb6df7a202e88c048547f59dc669f5f7d3362c9c8b0be84c1154ff7cec97b9b6543076fd1842765e84eb52f44b5b1f6b47efd3eed9b1522f5ac4a38a0082434ce3d790edf4edd922558e95bd5f7acac57d3f068f9d400da5441a6d1d1d946071a8489d4cb8e0148890395f06a1d549d964358b4e2e26a751019bcad5804d89302c010f14f6e197db7ebb7291c507ae001bf87ea12e2a748390a57fb7a3c52153690f7fc4368e7561b842b051461b0c1d9329c0008c6c2ac8c1f0b4dc70e06c73ed09fa6d26d5507e0b89dc1e61d1d7d863037f95e9f7f3094600d4ed2c47a48d404968981ed97ca9c4ce0f647ede4ed626168bd760c45ee96446f62e80a255d033883f006ad275ea606cdad1867a6c049fda7183cc836070e5458d080d3f4a661076aeff962e43efda7c574958ff2e70e301d2e3f40e63ef5bfa4bcafcd0e6d3ab9c5a2c1875a907a5b014895c6c99e85e65121618b225506927d69882dd414acb153262eb6e72411922d171d6c7d57090cad36c9e933194e09e18b3d9e29fc8cbc486c071ee1c3d9ce31fdd4e58c1695d1a0dfbd846ce20992384b5fc6aed1e24e50f4ae0fe99b797fc385e52f0bd76cb51efc4333af03aa5603759866d0bf4f8237d44baf463e9c0e6854929406bf074c2cd300aa96c6c9536628f8509c79174a605a2056b3c889cadac550ca3f468a7186a1b8859a8f4955e01d23ddbf78a95e0b0d0e030a91cce22047971106e9b5e742bc9b56feda9744f6cc5c04308a90005c8e909861942d0929b662407395da5c764c9bc7fa70ee64a798d0e021b0f9fb0a73811a964e130fb90bbb664bff767457a074011563c57b06a3dd6834ecb27907b80626aea66f79c4d2222462dec6d2dd1e1a3b42358e8c81b9aa07f2e9bd9f0fddc34ea72cf504765854ca8e5f247ac78dae89da3faab0c692d2de8e6dc38e338de70a43d0281c4a05ef3a38e18d795227827933a17514f8e65e60cc3cf1bcb505e23f55bd81d99c9d89952ddcb64510f27b3bc3347eceb807243d5f0b5ad43aa5d4cc4cbb6e04d0d8381cfc1f968e566cf267c12bdabc444686e053a70917dce9389c3803b25680750036209fdfe611316a16b471834a6087287b09b9b81aa5b8655ab152439bf0f38f056e4947d674253370f71bdee3710a92ee883035daa804391b4177ba6d0f2aba475de9e3f45c1eccc5fd0dcafdbd256e207d655b6561e4d33d84f954ff9c644173783550cfd1a705dd460ea54deed11b3500b5b286570e02ac0540a35ea53e71a5da18b8756a050f49229c9027e6e4303c1c79204a48191359274eef028b32684928c0190ad08f1b1910d5c42e6dc818650dc45677ed92bd5c19396a9847a5b688e0fddfc2c1a3451adbf1a9c4c50064bb8aa9e8c738a949c47c8bb984fdcfc76bbc019c67145ce75e90769cc29ec58d7d2a0aa8f43d0b9d622c44ec319d7f0e0945c2f8de32d16d9dacd079ace2d8706985552e9c86d971ee79160153929473dc25856cebd1fac3f6787023ad3ba66d0a11b9ec381232e196a29a24eddc3326041baaa5e0c11cd707b8fbe85e85783fc0d77f770f61d98333a301b01f61f93b094b1731f9673a5bfc4ef6d34ce97a93c2407f34d5c27178f92df87d856193d9d979070d59e49a587797016f818e036e3ed447c6a01f3eae7ef8aa978673fc103310bfecefc200a94a979b6c1d3c95cd79abff8b5778129b51c860e38c2b2fdc19b9afd574277b507fded15d5d658086ca8e53a363553078d00380bc9a5aeb563fce7bc4ce37bcb1d1ffcd118962f23601d30ae73eb7c51953d9398e7374a7aba5282856b7fd3e3c9f328a36f8904ed9e89d20f174d506b8acbc1222d3319b529ad8b3af0d6cfe42414a952afb6c1ba8dad2c5f1fae1a76aad327032c421a2b097c5f6b132d29111cecc94cf59501823a64d7684cf60764a6c205568aa17593a9c92e6e4e379476cb26f756a7b8ae57beb2ddeb508546fc4948b83844c3fea33c6537eba40bbcdb7ea22f1610d18e7ed14c9ce88080f339639c8edd2051c59909798444788a6d380adca8d5cba314d01988d723105520b78c44a3f52901778b01c14a636c7b806f0508be4640bfd884c16116a33c1fe3c1968274254dd0be0c7b1e7566be571eb3a70634cf18c6bfe4504d264692ce3ef1817cd0b181eade0e22f2d080eee04f7ca6574df71a5a868b42c144a3acb365d253f7ee2bd1bb285d816f9767842f75dd307f9336e4a5a4aed971aefb21d00116996a9aa449ff46391d63d204183735cb88bc622e243f44fc65849742f2e34cde03ac2a038179730dfc3444d8a7fe938727cc249e36ff376fa4f48fd4126d29b024b0a3e736eed97cb06401bc35485d191c7d3b2486269f69806fd41fc9f5e92ae1472260799a48e9a7ce54119ff492bef54663b06581aa3885761764a3aab590054ab82680f16e3eda6a0f85645ea21595506d4b5de90251eb8db285a5373b1a500da1bafbad172a3eec4ed5a47f4b7ad6037c9c611fa2e5235922ac615b63a796f21d35b591bc74bf0a08ba501dccbb2b4b9db901c9587fb86a3e58e7bc5fb4d70b92afc7fc2e152613f3ee1c1744d738176863c78a71b81cf5125eb5bc5bad0b8d4eefe2fe49950f0165da2c4ced8e7c55fbea55ba7b8163e43bfd7b96a6754110b5cee606f4cbf983b29e71edeafdc21910bca9fbf72ed13ca6bf61514113cb2dc5b2c52efdc395f2eebe1945ef61a847f8a998565fd5bbe3126198b2b1525f59e9044e39dde9fa5e6a51492085fbd87bb92786fad2712bc63250c64c98ddb22e56ead8f80fe3271485b002ca369be78a11f42dd2449d01f53875be523bf590057d5c5a46c304158424b02b5c9752228586c16be58785a70f1b5a3478953d4314522516e18e8d0036f8fe130c4274bc6c99788047d12b394b3b0f005959302eb03a6e747e5112ecb0b9f3bf88f12ee4d483640e77df590a0e446a1c33b86fa24cca5759ff83650dd01ed1ad25c585b7d4340e97be4821172825a49d1c2628c4ed34f42cf9cb041c6aaac2e6a232a19ba7d44aec71af261abfa589b7f38922b13412888d02a88eded6c4b0de6c08e7d912299727388183694119cf5ead330aeb566df180dc8a1067721577d3546a30155aa28c0993d363cf402aaec1fb6e295b11868cf00f1e5cec44791f785097c71de127e42323a182d2150d5a60222d88cc825a4e03dc6d64b6892bdf8fa1a015807ba1183d9f57ac1e0f407e26a1f71cc754b50e2d6e5adf7b1f504cfee3144a31c9fb9fbb6e0682d03b8258fdc6fb7381f835b133ec84d994f14a6fa70302804b94506320e85515f79a0a1327a2d3503090392185e4d2fc26ff4a203c34d22ec84129a4648086fe3406f6a51519907c4f8165c43045cf57b7509302a91eed805662420ddd541a3175dbdd1be236f33bd57284ab49dc44f7a3eda07edce162a62e10466c6e179cd80ee058382edb87b7aa3fca63ee0797d15cfcceda83bb0238c34e8c6754ed2d6fbd3142b9ebe563fefb1736faf9b2f67deecd6f6f7e94adf09216e4128656a3971a9626bcf555e9cd9106e110b684815195ce9f5521c68d6c602dbc22e670369b779924688697e618113a3298bab178d857664fe10fb7c8ea2057742cc60aea3d5d19bf07ca2229a698612252d01569e59d7d5cafec7088a67a4688a124edfc0276291091c2326e6669b687fbee76d40800963d7094cb05090c79c9ff6d6427890d75d120a03ce9c8199f25b44822313315e093aa0d3e3a2928780b8a8cef3fbf1e0c7f3c4e328af1e5684606dca5f0f673c592a18a71b0210d81f3af1eb7c80fec33b4e8ce94045e6288c7955b91fa40de2720778fe37125228d9ced98c66999d39c917d078e8845ea45ed7f05745fc2e177d015139efe0a25b6488293e1ad6f824f31f1eea8bdfd5963b510dfe84cf6e918403539ccaeeca077ce64a93dbb7cadf33f98a664375d827db174be9ed1dc307c6c8164e55466ea8498fe8ba88863e838652bba12054cb8deb56fd4f75f713ab2640b097292dbb4b16ab3a4807ceafde6548ff47e3ccbd44cfc10a2b881f552c5720ac069f0ef6a6f0b919141af3eaf5da68b0afbe70e1e161cee22b0dc1c2e1da32811b3cb7347a7109fa956a1422404ff32613009360060811218b71ec9385d7191f51164f5fa60cc63441787e9962a1fb5a43349c9fe6c3c130e9a806fe2044b0776629380393ecbff7e1bb4784b542bd120ec55ac0eb14feea9d72ceefa0da1c46369f48807756b04f1de50c5ebda0fa33d0de5ed396fb1f867d692c872f01d103ed49616192ff682474903f0a4c90526d36a22d30150fda0d502e2ea0d4842d5a433f7ed6eeb870fc8319047ded900675107e73803c282a765dc663561184b665c7b326014edd857481910b12babfdf70e96dbf4934fd631042e6bc808f5c006309309042f722c74da48a5576f69994bce1adc2299adddbf3b67c8793d6929cf599051301909d485eaad4d945906412829b25620cb22bf9157d585d1aedd9f68cd7b7ae06c393582839ae8444bc2bb8371f21b9148e997845de61c392fdc639d0dd85ec5999a74673eb225b6e969a4a082a4b1b0f9199d7a9b0cff794b2747ef48f7287e111ccbec2b594190c3a4b299b00c891b0ba50003253394ce10b3fb9ff4350c8706885c2843bf7c23a2a94c7bf17b4e522660b8e186830b95971ea7a77a96b30e03f7f811191a0192358d922ab666ff8568f1400c81cb2906aa31204986e75c84d731402acc0facf3acec1d8b7e32d1f5de98598fa0c42250aa45df39c323a4f9029a867b705c941f6e2ef3f97511cf57e94ad2fa40f2c9b0a8c49077c8bf58c800830885dfa9fdb1c53baac9b26d8115e6b18f8a6d055f67d8414864104fdd20a804a2d3bf7a5a6a5d91db0ccf062dc3cdb41ef52c6c53dc68107d025cc684aeb54790336ab263f0e4379076b6afc238c8fa4817ae0c1498a1cb108714e7246e01d1c7a5f5635384a9840c8b410fe4b55bfc6359354ac13b5583221b11af5d16e716cb125758089ab5891449a7504a9215d1693d8ff0682b77f0cffbea29527fc6995a8ba59347b1418152560308214d37b22eeb7b4e47168ac411adfd82a7be9e1e19ede86c40464a59dcce699a6ace416339c1a8cfc6f35e8f204d1ab4042e6ec8daf9d8d02c07b2f5e2478566845319c368bc1751b0bb5d221f3fc8739efd3e126407dbf4cdb441021311fba45d86c0790cdb522378162fe8a7d1b4380b4a23915ec0ca7ff5248671f0ca7e4dacfc21b072ba6053096c5b499fb1abda0aacea71afc9ac797ddb69da4da58198038404aca3a3b8a837b45ca0da8d6c424cc5f7d178843430177fddde77543146e2c1a8d771db31e428fe21a9a303226b98648dac69dc487d465155a51cfecf0cabd3ef64cdd017ae8f21e9d2c5d94fec04bbc426201f63c00bd60fd438e136b695f8928f20948b6b1a246e3c71b2c3a069225d96c7e0f50dab93923363e31da610fcc72a07a46c342082dead97e01ebe86e5a9a7f59ee6f776cd7c096c92c5decea7752c1068df6604da8926481cce36cb21c6a53ff071ae7d9557c352635a4ff7f49e67c3ca17e4f20095343d5370b11f463e9a6eb79cd3074d8994ea7c269addbc52026b53804f04a5a6313f6189a16cfa9ae665541452cff7602e58fc4f7537974f4ebcc8f72e3ca1ffdd8a952535a415d830ed1e7dfcd6743c5f9f3dd0f29de6ca837a18833c7ca702ef14904ddf495f806089d91308bc3b067e0c993d8cbfe2ca64d7027c59b8275d798021dcc4246215b899151a379b755de7c67e464d0ab879e69187038eeecdf760cbefc3baedb0c5f7b0cb25d612a2d3af34922d2e0e495fa8f0d5ad9896777b634acf38f09c50bfceb3c81b0386a96840b333481c0e36f7af5f1e1d65dac4432bd2a63680dc508abcaecc8e95b11ec2782166a6960d581671284fc939d88ff475527d628d6e1876fb36f1a454eefc67a98ffb56872d40e4e1c84b9c45d3da45dc01ad2a09711b4474c9a33c4364432310ef170a9f94d6adc3941fedfa81c182f1f583940c11e87259d510be26e7f90f0b35794ef4ed95c22aa00ce2d16db9a44e5f097501687df3f920c795f0b36e220abbcc9e03495a26c514b8401f12f8558ecd50395ba7a9c47bc89523786f52acd4813149928212634c1a5f4932cac21c5d3682b902b6c1244cdc1c6119e963e037e4df5d8872b5c34b2ac5890cf623b1159d7c622961f41d983d242692c931bcca79896e3e776c259f3819c7498a88e4c41a5f0dd11cdfc7768b36b5e1d35e4c5a18340a96527d4f96c7f5c3b190b550a7ca8fc48fa923585ee87488f00b99c314b11c796622764f0a492a0d71719a1077434be88064564e58e45cad449863c275131bac13a74dd7863d892f50f9bfcffa66dfe89a7e12833103a25b80794496b85ca867e0f06b6b162da662877010204529082a7ceb428dfc0f50a5a6252a00b46733c6cbaf34bc8e9565ae3466d354d5071cf8a8c0b3195b1f5106de3141dc3a82a69df7b435519d9a14b3de5036f4eec4e69f08e64c6e1d26fdf06aaa4b3dae9fdbf5c303f2dae09eb66719805b4d4eaa7af4b310b6c0f7ac98d93dde60cf2030ed06a45023c54ec4dde63ebd182f5f391bee18e812b8fd78179387e9b3f71b1c4bb93c4c27a5b3a96002a6a027fff72caf44b2ca992e1fa55dd82014b2673ac212504a84c7caf1ed7c60c47f3bfaf9ce941271f0f89ad09977ac93f027f23f44f193a8e2c49c79f8807ef944b16b1972289cf667b49e8500c117030807d942d09e5353686f4bc9c2b387aa645ec509f8a00ebb2a15d6faad312d3a4864f32381cf5b2d889d912101a4729f97de63824a4210864f2af956575c1dec5a60f02cf99b323a6e427b944553a7115be432dc6cf3a5037eb218f50266228267c4e6bc03a838ece1eb9e157da24ac41c818d849773514513ccc7d62a0a73c93285f87a36389d07db28958c627f7bd70416b6e504427a9f4c3a56c03c2ab8954be93680e39606253ce3245c51502682165c009651177dffd8d213fcf12e73c4a1f45be705d84478eaaa2eab09163710cdc1c907d6052dbcbc1742bf7016d0cdc2cf1dc90781de2761bc6251b5a9ac34d60786c42a9a5eda32b0d24ed644482a07122a3e7ab3d9cf1ed941acaf73dbf70a3dd9d8a2c72ee363b2f9172af21eed1d4b14e1704f24e3b71b60cc3ec1761c6bc77c5919542ccf41213300f491b13cae391d2299c8c07c6537cd5083daef1a933296fb0c48447406b8c110d2061441f013fde4e4a7824104bd14715cfa90ae5375e27be88795f5682acf4f9034d4ea60dffc6c21dbaa6908d3c3aecc0b56aa6d30199176fdb947a0a1e9a324c3c180cad16c290be0fa2aabf1a80b79d5af9e6f538d62d1882adf893ff0d97286b87a214c67763298c11f44fe6a2b8a1391b05e108769a53d447f51c695d04d39d0ae7c9c3e2843f3469a6ae28f397fba08de46453459d75877023ebc57d46951eb911ffe55d88341b9ac48dbe796f3ac1e304265aab42f1c8dafba52e3ffecf5a1179ae70b8e7143cb59bedc0effaa9df44ff15d52779ec41cb3c21fc741d1974c4b40dc5d31123a17a90fed4c86e217a06088203aab66d7ee33f200dd3aab203e394811bbd3c8d97b3c6ca16b08ad1f86ccdbfb1865f1547872f8162d8c3810aed242e3cf8766ada822d686785f42496b932d1953f679ebff889f2545984014f72d1980abd4df2ad081e3afa1fb3a9550cd429776c563aafa0842b3298abd621e14269508efe4383cdd6f19bacb0dd8ff32314555548740fe6dcc0d0d237ad571b0b163d40c088804242a9213e4f068c050ab25ad1194ef2d5f7bfaf50461e6ee30b11e2c5767b55c5722c972ef7b72818325950645af869f4d2a25e365f85749b2f7ad3a2b0b8d76cec94ff18b3f299e9eaabbb2ac0d399ae51400502d4e3cc717c7c7a755cf75084f52f74c29320791433544aa2c99031864ba916b1f1cc19c911e09f3c43298b07e831b5e6c4063cdb43aeb5ab6731e5408db5e47bbdfa4cb92f3f43053f9f1f1c0a7495443f0ea1d48208b6bbc255e3ae08df2204be4167846a1d4e305e84736411211e704eece2111bc908f1006227e211b66257dfe4e69b18b5fb9f7494b3c7d9977323c567f2c33149f7336a75981fc68d9db4edbe013ab4239a8d02734f5b1d4383987068600c33632c756196b70ad7c1009e0190536f118eaee3769e3c8c47879200ecd0a287bbff0582b4570c22b70b9ab8500260a67cbd6416ebc8ccc78c01fc0cec93a03cd6c221659c18a964bf0208e9b3baba7480cf3ab9a31dbfb65df44b0ae11fa29c68c314078c0d152824eebc852c14d19d7e827d56e20bedb02973ebc2e44a6ca363669ba1d931b6256250af368bd4248c2eb6973f26c67736907ae92f08c8fe75fa9153e71af73a1055c9a91e742a8e842005d18c95552b2e7ec1b85923fff73466128046465a95485d82cd20ae1c8fb3e3b685045777e6830b8d910a6ac020a954643784b2e9548dcd0ad314599d5115e915f0d849f86b5a95d1b3b260a9f316e0d50994c6c34c9e714838fe84dcb3c63af98a9a0828ac7f84c40e10f7a8cc46455b90c2e277f23faa7dee9979696e5786585169618e9811402a5f49c166e64a059a50f2748aac43d3485273a56801eedab0e42fc14e434763b0f90ddeb08ddd2f90743dc1c947452ba69bf9f354ed691b6f65476c70e0b4edcaabb2027045139dd6e001a03bc2845cd708aeca266b9f1282c5fdc31b9997543bdcd26fe092b56ec3cc6d242deb7dd8296f29a7a277e1917f39e263fe47018971c8ca4df964f5f257043e1c6140c7894999e46375ac109965226f6e5965ac13ae476d80cfd2031256df731c1517368c52993772aa406c58f9353d56ef2c124b3203ff90bdad84ca5c7a721c045aef404daf2e06e23a2603b053459173cefe575b3a7ae2bf0f78ca2a29b0eaa6b81b550fcf681069cdc7f80b836f6e7dea446fb7fa2afaae930c99dc7422733c0fc05508cdff84263d14703091ac57e63b6c83f7b1790fb79138cd5f4f45333a13c759acd1181da7e4f0ce332eff952bea83dea92aad65093ad5c7649705b01bc547cba52877afc5906324826a225a8307c6bbeac6c3d9a709a18112c3ddffa2cd3cc0ce03cc46b5111bad8abac7e503c9322d764aecc28e826071af5494a1395e8bc5c4e221b96e3562d1acdaa6c4049df124c6746641c7fe8451d5f39df5b0f0773ce8b3812b4b5c877239518c76603208fb18ec1ad7298166689db76f1ba2b291ad2dd4f7cc98a1364cf4c384f4698f715230796555b5a995dc7ab433ee368280f82a472c8fd53fed1d220dc3b40d98179dea3d5529791e8861a386a96bf809c6994fa0f351a4e51f22815a72d85dd86083359f05668ec2b90b58ec56c34f44ad9c0becbb52ff5c87ff68910923cca50f0dd8e474a32695211281241a12ef4dd4e8843324707230facc09017708b7ac29b11b7f928cec1bba7051833e92f8fafc88bfa7f906ba4a401f401574630b62478be82d9fed3718498db97b8a184328ab5b489e424c3cb43a87d4e02824991f86c3bbb0290c35691ec2bbd139778a8b264e55efa1fa77b2c9de441ed25ec8dba3db84c6b057e4fe3f0120523c1274881804d4ce988368784e31ce6e656e69b3673475ab223a714c3b0edd92c5f1eeafc5d30b3764c21475754fd7e119ee04d4999448da309f97e8824e49d035f3cb2a06df8522331726f80fc413cb5135377e38f411438c39392bda159f36af074997bf4a8a1f8cb33346baca8e4bbd108495a463cba131ea7896f5048db13b971b287bec9a0bf9c9d45c81e5c83b249d78c3f9302ce502aa13426f5e40ccd19a0e1606e002cbeb96cf3365ec291717ebd9f680ec5dde88e58cb89ab31a5634e082990212db1a0ac4a381af66b78bfe32ff02bddccd1da9a88efc214ba32038e82150657b309411badda4150df2ca31b591b6f796522629a594013d07660778064b21d82409638c7b40352539a900f7d87d353749f180b23c7a4dd7632e15bc0690ea620e227d79a69f80fe4dfd0377bf0c733af203080c4db276a03f3facc01f5a92ae4bf980728cb18dd8f3a32a27e08711406a205d6fd1ac532af2615bc2d9120a1613bf572b5c77f72851f712f12ffb950cb1efd26c730d51b64caee826c7e4a362ec186b1d603d5176b7921993d12479f6ec1863ecf8d6b46cec62add65383502d050b0e0209c087a96e86c17b4312fe1b72d7e8ab46ee5237d860539ccc149cae014dd21335c2d6c8478b29e74c650362030fc8908dba457a549ba5f45c061fb4c706277b85c7ccf52ad5977baf945ba5c99c330287926bc12225f2bc5f97a710bc12760143e4cb784c13ff644f172b1f76483b201bb7d083f1f52b83972fad2f4bf7d268c27ae18ad197ab2635f4b88f12d750560eff82fb31921dac81fb68f692c36003a45039a20b14147c1461e35effbefb76a7cbf9a330e8a0c28254982b147a6e8d7da5bc085194c5d9d3d98c8b0dc87f8f17a79fbd4e149e625fd09959720d2ef0fbb240bd90dcafe73c85058976f70bb23c057d39237d3e538440304142f9e521e83e535aa03e247c8116a923284762310c7e79e9878718e3a32c4a933f46aed81188a3354403d367738e9b63d9113524a6070639a06ef8d80949c211b5020f8bc10d777349d566232bcf92f44445c4db810152afc8c708031cbcd996524094865a347f56c7603a7da1c2af862944408c87b80079adc2f321cda5a8528dc3a75315e412011ae282746f49435c926e4f952a2070d07d3878b92ddd0c25e12ce518ce1f0e965d776f952671d50946a058a3330bae147d9f7356b24f17ac39e43c07220a8b59d921775f13cadca3430fbbbb1bb99415decbdd73d851bf62f3b9f7eae42b4c46b51aae58c77148b35daaca366465278031b14b250a4775f7aa9eab05a6828311b554b0dc7befbdf75a71aa3499a91071a4d33d567255b90b263f8562741803814d328456cced46096b113b47e2a82a28490dbc2072d496f405517a32563e1ad3b0581151647e70618c31c63d62a0dc4de0f143992b1a8408e285353db2ec92ad49e331463e184321d3c57b8a58d281d2c18a945b0b3a7caa7a701262762e25a688a6998ee1fcc81a7f37e79c73cef8f68ca9b2e99a7b6e2ae1384a933c18dc70a234b969565135fa27233dab9fa57644d5ae0afed9e47bef54991afb5edcaa0a5d2056ebcc2ee451586c079ec97d58bc9c82ee48216ef02c83af99a57befbd67965cde7ba7c8e4f6bdb84c94dd39aefd4c678bce0c0b57ef9d3283dbf7defbaf736bb56d464775ec02325105d8520a47961241398750375988178219242289dc8343920dfabe9ebdce8ca82af3f07306c916f46387274854228e3f1f5efe4438bc6bd9a1a5db02f803250b0b4728ca06d910d9a4196e12c64a009832db3c94abb4dba355c391896a12142494c0867a16b062d444cb4f953059594536bf81890a54ba44152133c33ca2869c5d4241120ff1296b5d0bc0540e9f0bbbf7262d85000091b8383a72159c2991c30936e6de44559ac421aacfe5d3af67af33f3d12ba1bb2ffd310d8bdd6e1c7ff866f5d96c779fbdce8cc79376b5b8d5f157955def03f7aae16bf5b0d9dca0dc3029e792e182b05852af75ab7b0bf80312152ec956e0cd08c64a50dfbded2871b57b6c29698929bb5a7c3b424e76c00541f17e7a5c4dae04901ffc5e7cf1bd445f8a9a5f8bf16dc87538e17b6f353e2b74d180756967a68c25ca4b4dea37e6d21dbd7bbd96c2829a05b5caf3539ea8df5bbb77ca0ab64bceeeeefe834769727f3f7a9426b79ed2044fe1d0e10b72e8a680e85a3788f006400e7e2d570bba43fa64b6361ff142570b8c65845136d281367060a4aa2f47d185c58e6ef90c530fd7dd0b8c9edccfb07074c151948ea53339ec80c590969c08251c5667d42015f12a4de6dc0d2125a9a32436516e980582f7de0b2617823677bfee8edd3d94bd3037ee142746f9e28baf87297277bfeeae6360703ce42d5fbe9fab05cdb2f1cdb94a8352c60825bfe0c90d9b29b2d1b59886c564a8e2b2d3c28307272b9cb94af373897898f161abce0ce7391c86947690c251a63715566972dd4c90a73a5b860045184f3da9da38001b17997952c1bcc0898d468e189a1c35d9806687151a1a702f1a52d06126079c0b647032a2c40c281892e267350b6e7ed4ec0e7042d9d523a550c7605b340d3f7705a4cf5df36c8c62128d940f90088ebf0f6a1b8e865215011f54423c2d59c3a4cb3c330525099b2929a3a3d9e7deebfcd743ce993e29b96758ec021aac5260445769324f1df9c2c389c672565572d802f134e2851a8217d8e004a333fc593f6dfcb0180b1b631c9359c3a024c1b3411704a7dc64ac9bc1d0fb5c2d1c0cfab2bc1f1061f62b338601f765181256f2c931dc88a1c867d7f29886c55eb0c258ca520c4c425bb0423b7b9d19d49395326774b882820cb82b584e1e030a475bd604a0ea8f69580c4ac87964fa7af63a331872b688d5426ca6fe9886c5a02ac631d836c61863bf18aa0a43b95a1234e3f1a47455410f39e7cfd50aa3863288bf6f7d01b52adf76fd504ac9238950c18a491090a12f667a46bae54fa9626ef9333aab216d5dd74b9baf40f2dc485a7da9805aa57467febd2926cee99356e22863e6767efb6196d56644e8fce34c01745653d41a8aa38e555b680039bb4f1b33b0bff0432b27b5a1a28e3c710db06f288e1bd8dfcbd9155d19e8ec4f0413f6f7813f7757da463625edfbff4ab0af069f94273ef1e9acead059cdbbbe026a76e636701c4c88ae98a301fefb586c8560e6b68e7cd73fdd2921cbf2be5761cd3bff958d25ec6ba17cb1da4e635f190975bb38b54c14d26a4f7b03295e937712cb4793bcb3f214441310eb545c301482f061c22d9b04082284a4c0047cc19ca8861009c323400c21e21f11206e30e18ce32999298185444972f5ba41b23421c9921d06248bad69076c7d60d1224457585dc232d5f484da3c796029d2e476eac022c4f443960923b8a4f1e2c5043164adb1c20446c914255e788839382d7697dfcd57ca2f2cdf7b338ee97baf0f33ec7bafceea6f4b291f5cd8a37eb722a5062405b0bf90500972c306293ac424497384b5f6e62861c3882b68126183aba90244811c474cf1d0352981a227a8011364a526cdcd1144442e6800da414a8dd51144d449cd0a6a66b0d7efbdd75a4973958667fdbabb5b3557a6d4e8b6b5d6a7b4f6c85a6bad75eb9aa5c1f2e9fab15a1a195c40c47096f6e288888e8a8854b821727737f241230d79c1c961410adf1094909e0d3181434784c21d379ca075b713fc80663a2f0404516d96a226a45404e4e2eb1e1bfa925b6ada3106078a4448851b212920f6de1c9b181d4a559caea61c091273b326e8672684c20060c886fb755b5301d62c08e2a107b6b24b113ec64891f2e40615357243ea75c3ca8fd7cf0d271f1bf7eb3e1491b9204caa5620e2c80c36ecc8ba01278b2a2b88dcda722a0b8a12a144bc48b9627a620412185048124508249876f0c18c130a2a2073fc006282a6474585c490af290707c45471814c17264dae282ee8695b6baddb5bcbdd80ef92eb48cbc7c7911f2f43425949ed03677677eceeee9ffdcb3d940c4155f9b1fb91ebf1a62b2af96a07271d8369d8fffc160d64addd72eaca480f5fb6f2eab32a7439f2629d0a7631e132240c6e2921c2853044c210c9550a78fed9225bb07c49e106ceb02163c2647169efe74ba5c546116e33d522acce1e54432815e1f69b493a2462dcce1d423801136e4925840ab0dec4814bb729346d2584f081072f58d4260b2db8b0c714a3ccbdb0476935ca5e0ce35c9a9fe7ebf93fbf369fc57c18f33d981fc2fc699b3f6f13e7392bafc559415b783e525f6ed11490bb5f173a124af5209563a2049862eb1143d23421818649912a214550550f22cac504e0410a951b397820d1d47383ec4b154455109dd6965441c4b0c7af2185b70a159215901428faac0c06436183942434f4d04393025311921051d657a5b6d862a1eb44692acc06f9ec4c0f2045536a86a08018d121dd4241c3e785888b14511522a9104d1115701b95ee5a730b4a601c5b1be4d6da87c5acb5d62d368155c34dcd890f2f34867035a2dc8c3cc9f2437f601dc1582804dd208fc2e241b19690b08a60301c3e88085145f5c399a22c1f5e6c953337089227ba2cbb1f404170d0257a34e7eba497985798d7eeb57bf1866030db2405447b58d5b863aa34e9e07e7dfee0806806275d8850a5e0a9c7ae4d2f08a15a02b4f196543f9cc1d604124541f8e28b751acf4ae2688b3bd09de91ace9653595c1c48ccb1b5d606e1a82b5da6ba28d13df140726501d9d65aeb56b6e5d4115f8ed0552f54892ac91d8a9e9eec80448e1d42e818c562b8589eaf6505dceae8b0cd376420a2c57613d2f5384ddaee8e6424660906ea9244072a253e4751bc0801d11d628e5c40322cb9303b4556c95a24084d2e2806326474ecfab1da0b5d10905f7b31bdf7cbd6da9f18b67da1c7da8b3306ad75d1c2accb2b3f394e98fdece7e81ff449c2a7cbc6d952cae70a1e52a1c2e84a056a369ca07fd9c60d1317d4d9ec6a4e8852e4c21118aeb0e4e80df16b866a11666910e199e982bb618b0ea89b8d2146e410257cdaaaa51a4ec845790168051c3686e8717d760300f4d84308d692a72017a4f460a48d6d4401626be03e2350a010626535a7bd4bf407c734924ed041cac8169b0a398ec6087d4e38fcfaf519971ebee0c0c18a2e498fb6440459eb36c5d4d50cf90a092a4b2ea08b2fbe4e9565048480de8feb6c508986a8cccd965359be5c22450618a384430b95326b72f4d4a22a982801b1898391139222ac088185280153b07530431748df087a19e1402317c0f60b24ad740f8dd018592a1f273b04e5c042911e3de3d3a13dce8cb2ecbba594110f48a0e834be960aed71f6c91e52a0e369471260aefcd0a0ed358b52569623416a0061eb01daa3b4c252e608a5abfa2fb2d8d0619182054a881a37d03fffdc4454140a60f787962f712de3292a3028879495475b6bdd1af1b06ba5025a41cac8894f123faed1d411493bb6a59411d093036c29c5e4a50888fb598a690829262745469cec8002274ca4eca87285de0822840fadc9131d10b0a554101cbbb5a554919a046c2915444b510a0ad8524a8891919098b6daa2d8524a08d40d534abe97871506ebf77d3d02b959d458e399559acc52cbd800b69573680fa05a1cdde95c85f4eea8050c9c43ac42573a864471ef531a47b63ffd4ff6c26a8b300346166148daadca40e6f614452861cf24ed7e2da7d05131ea9cd796b09d7e385d194839b3322b9bd49f7251e840f35b1708a5ce08f27236d894eef89674e7ee19e5b979b9a4a3614e7b949655a589c735b4a43bd8a647dabb4277a495d47d20cc322438ef41e5c11169d6cfae77d724a1b14c62fc8b841eb3d06c96252bd81ed09ddc12025bee73ce5d8525adaee6154aab28656102b5aa0a07f5f13ede874577e812dc53cd4295077c9a38b2d9232b0fce4b9dfe515695f8515a7df0f12a0f4cacb69c1f7febd82c003fd6603fea725c3fc60420e698f862a57dda0a47e65ee2a8f3c7662d71fc5a2d6a8fb497a2a9b7ed1ea58eee8c94978de80e5d61d7a926deaeff815b814865cf55a33fd74da37360d0debe3d9dad2acf8da82b2d57255538e55a1d290f7cbad2373fd25ebed19efad4367b7305deed125f9ff62aae66db5cd1fafad98654e11f5bd2b72721a1dbf324f2c4bcf13c577928af3775bbeaf6acb25fafd22e1a8df338a250eea95c344c6c89ee3451ccaf44e80ac417955687d0dfd3a376312c21635169f59ffea9f27c396b9dc5d177b6954a15cfa2e6d1757bd3a76b847e6d39d574a3369a9ac0a79cb5be4295c77592367f9779da7b7b0ad99c849e6e50fb2e45edfaf78c9e3f7ebc5d5d1b4c0cdc3cce7770f3384f63c33e46e5817d8cca83f3b56582ceea07610a539d68cb048eec45a5d50f6b0b4706c3f559dc12427ba3fe407ddaa33b724a08d3ae4fb32a5541e7caa0830a2c70f315bc50e5a9407c81f355559e6ab3eae9fa55e1265b9022635d32a70718c7db32ca96534196ece96a0183f6b0b4194d3f1b851e541e9a46d2ead7d80dd51c1ef47af2447d1634dfc43cd2327aa4915b79028932a23bd2eefab508dd91534c49738a89698ff50704c3b4c77afbc1b6c7ca5471bbd625bb3eedead335810ab6aa6b839ac14863e74fcc20bfe76741b39883458ba5eea33563d19ad157bc11dd45b7a2b3f9feb42718d2b0a108400a47d0b63d3b3061f6dc0fe90ca82d63dea7733b0028758009347aee5f31877eda97cce56927a3ad384eddbe3c2dffc2a81d80bceaeac0a1446a0b81ce94b43f6d2a63d30e640fd8abb4f9778cb64f65326014ec813db007f69c7a9447795415c15e689b4f6560169d4db007f66a68a33bf2c991c21148c8db7f8d96534696ec11022f384077680a7bca4891b9e7949943d0b639d68a4f21983085a88c60ed39e70c026ace25eb92c99e2e9c0b6b4b6e17c719525bacb67d41774608c8dd58b744edb9e74461d4d993031ec4d0c0521048da7c32319966d7d8f3c7d907f2c4fc497d48db971be4e49f9b4ea0be8500ddb1e2d5967fa72c67033ac3b6a998637f5f19ad2aa4e51ee56e5609daa00c3a0b21bc38b75c5677f8b55c46777841076da5e094e00d6de4dbd6748930b7744145cbd3baf28430c7d86d4fed92da8c23d852fc80cee6df30bae53212e42d025e93846d53f182d1765359cefda2e5cb4db7756550317091c50bb94b81b6559afc51eeb64ed2e4cfdf628e51ffbe3a6bad555e9b71c6a6bbe5432875ea6ecd15b44bfd5a0a19d2d60c289ba4dfc53a03ca26e9b1b6ebad3ddd494177aed76429a49d3db53e8c5e2ef5f574c913f3b78c62329f2631316d076c4905e46afbd3d9fdfb2108fe9c257e94ff726d00ee69e37281dfbef5185bfebca23bfe2e93628e7c29c510bfb4d1d6e5dbf9d69f457510be9fb1a77ccd29a57569992bec4bd77f531ce9fe5e8b23ddae298e325a769c534e2b82e0faefa7b7a4ad344c90ef55be4fde1eebcb40983f634b77fdae9ffdf3dcedb1dafcd5f5e238afb6b4d65ae9da40fe94c9f9b93865628efe70be14470de64b0ee6cb8f41777473857c27412a6912e896efe27b2982203fffcbc5816d7d76ba8dcb857d978b831615471188a07f618b26ed2c93b2d799d1999c32978bf9efb2fa2f19f837b212bfc51836a28bf2fb51466b747100df104d42dd9f0882fdfc2eb5cc15e3dc76be14c7dadaae1f65487ffb528af5660259be4b1ce728e67c5fdff5bacaaffea38cd6cedf72f98f2454f04bc848a8d9e5c21f842c8e4e69ae6f65971f5e570b50ca5e278b07d06eeb8dec5a0e501e29df3f06d53257cc79b52d8c871857baab2b2dba185aaeae7c66ce713029ca6169f5e88cd6ac999b32d323d5e5e86885b611dda14b74577467ceafbdca636b6f537a4569f4a948c350dd08d64575b5fcf6c7ec3fead85c9259198c5dbfb6ab68ed8dd2bf252055c85d42c6b3e3000b1ac08005d46e64b591f2bcea2ad6d9eb437fc9a4fbdbe8a9abb5d2974d0d858dcc747c30f7d47e46577c74bad34451abf8a2d2aaacdafdfbe668ff1333f6aa4afb3ea82d3f3b767f92d5ade65bb184532875c2a807a458408d3605303fda021e20932ee8a6b6af74df6e4b459e9c64aa799b4e2d4045d1ddb46a858ffffaf8b3dabf62296cc49a4bcc925643316b31966bcee228dbb5032f4f64f0dbfed82a4f08a22d84dc073919b75c2e77eb71bbdd74987e4975eee68eee54a14d6b98fa2662f9b39869bc76e28b476728e489f992ee84b5e6fe5456df29ad957e912d56dc9cbbfa545f626603eacf6a8228fd25c6ced8b63e15d2238a3d670a1452454c3e16c7dadcd576bbddae467d3fb4aac6ed8cffc5db7988d33ec09653436cb8e6dc769b95c98889eefc0879524d1ad22358fd636db95da55329299212a1d19e1f867594e1da00dc15fc3cbffdbddcf45f3cbaf33da56195e90fabacef2ee97b7d2781da2a6d6aa5d4c6bec4cc15feb48a23a51bbf78738f94561741c0dffaea541c2d0d136694b0eba52febf8cadae37d122808f5676c2af168b77c3bbeb0f678ddfec5efe2f8e2edfb3a09c2ebbf3e6e892f293af5fa541c35a84f39a8ff0a3357d097a27d16d5ca3e252dfffef8e26d6f3dfd9b96df5c28af52464bbb5cd407418ae37cd5d685aa6ea371dbca84e8acbaa8afffcae84bd97d1b5928f74b3622d1d7856d1ebf957efa2f317345ebefe3d71f4e8bbfd5d275021abf8d281b65b8b098e3fafbf8a16ace6df446ffbe0ca9dbf84719f743fdaf1f336e870fba5ce00741dbfce7e2a0b5b10ca99321ad326edfc7e228021aaf7fedb2ab4548656efb3980a61f8a2f3113c57d16b4e67f89992b662e3b6dfaaf1d2e17c94be84e7df176385df76dfe13a43f98894fccf1977b04bbe7d39fff41fd252bfabd14f4c71afd29e7d75ce5715ba5cddc9e6ef32b8eda6d33868c037426f1ed8612600a0827650657ad891e738ec1444b679abe389542ffd043d9023ffc30149d767e776925ebc0e65b4f5d16b011efb73408dfbe8b5094f28415ab16ed0ac51c0bd8bceb3bb01165753d8d2d5d61f82ee40ec5cf877e1a9b050565b231e3b6c46d29c25cb35fc8132c60541afd2a93332a8d8fd21974a87c0ca46f54ac1811ce133e7c43cfaf62b6157f3a09e9875446011895265dbc9027e6bf9027e4bb3a605169b2c508f33d70db56b227e7de899b4e2dcc2b7b5eb7b237e78f9e3f6d18976002dda93c1347a79d5e67ada2823571933609a54eed09f3cdb946edb0c2687c7123ddd9d993bb72713aa15713aaf24ca729cee94467f4edd76a7936492875c68cdb1e82a17897d0efb6b03d675b944a29c591bedc52aac8f97c68293dd6db8ca2478cc3515f1805157e504f95c784f0093b551e2797ffcd8127f8a22a8f0950ad0fefd3acd25c3cc14c026b783dfe610d9445dd1eef56e59678b79d90ce66b5cbd5d1aa057d6fd7a9f2c89eac635f93d7e96e5a0389686f5a03c967879bd638ea6d70d31a483ca88fdeb4068e24cc9b2be8fbe332e37592224fd8a7b299bb01cccc499942796aab22d952e5096a258dde5a3448aaa8ef3fc3509e6cab75c95c81b3260a7fc771c4f671626dc7594cee1279c2bfdedcf6c732aa7d519034ff7b8244719d6c771794e024b63b35d1e375322367fe5766b1c813fe38ebbe7fb6551e9b85d2fc1dccf61f5f7bccb66dafb6fb15a95babcaf3168d54514511e49a7ddf9d6753bfa204a402a2a2a2aed3766bb5fd47b0feb97a9d6ed096be50b0524af1b33e9afed4a147d3d57af929a496a04c7ef8fbf297f1ec71c95ed2ecb7643349b31fca6a9266df831a8b695d33986d2c8a48400cc65cadb5157783d5ae1fbd4b7039485c38dcd72a0f28cbc93adff03d0afc9cf9b53ddbe38c9a51174b8f332a5669568c1ea9cd2662b1d650f4a82850b4e252a5692069f4ad38f9f034c4a69f0363daf66c4fdcc48d3922cc3d9327e8cbf69c386c438f331f62773f747777778cadadb55671b4bfaf2c03ac43ab27ad36cb13f46f46e87a8b8db514adda126bad497446ebd71f35fed91e7f7f15359da5d8e35f99dc556665b5ce59e7ac7356f7b792ceaa9d94561d5e1707326a7f72bacc52451d6fd977fd7aab3c53d2aa5845b7220b6ac31946651e189436adac74ba5c8af923cc448df2b4286dbefcdcca22d6a1c7fbf8c7d6fdcffe856dcfe2b53fadaddfac52a174a7e949fca9f2e0a74f7795463f6bdb96019d50a8246db9153154343501400203170000200c0887442251164741140c3f1480085dae405e56329d8683911c05512005311003410c030c01c618631c624a2aaa007d7b342c169ec6f1c21485aab8e515190c416a38d496510f86865628350bbbf86a3522a92dd253224fb60217514a7ba258d04141f94d6af94b241dd7d0eb01dec41518484992814a6b9693223aacf0fc884fb89d0e804700ce02001ba080486fbc920b8c1d5782d17f0a866e359a2056982a7e7748264a387df7efa9ec04ba95c4b00042b1d3b9135ac3cafdecd637c1c01ac2b42e6814bdbf0bc5d0a2852419e3d022a22c0493438ebbb19e561ef3b4d336945d5e447916eb23dce89319d53218f52a2fcc249087e1810217f00113042df8ca57ccf7370662ce2cb84094a14e058918ce87798971362f434552bc867a1d7ffef4fc647385fe66255407cf361e63a07686c4855084fc9bed1e622c147e4a8d38c8f8b326e14bd0b93e6500b0ec62759927039edfac6af2efcc7c6fb5c348c753cd25c3054414e02d76039aaf43e273fb9c58db701964b406acee9787289278402bc30a32e2c1d0e228688bb9d385aa00a9b23325289e0a3d9ec3188a563841dbbf13074906ba8529b7b6254e120bc9834187817cc5b51077df6dc67bd04c3d25ee0d0c192f4ad5afeec76194ab8b5a1b3934e5aee3b825d0256e05525c9f66f6641728d88bbd74f5816d45e8f8f8a123645366a7038ab652c296ad86ce3c12d321954d491601ff57993330bb110950d2e012e46beac8c81aff5c66537836403ea4f76a617413417b09fa68655be2f2abed5592863c3b8cc0c1305559780020de13b4ee36e350b4a172db4e1a243c74ad4682717eb7f1030eca41515b5e6e65817b623f8d2bb7df0bd182e20f548b2025e5c1ab6d1d58c3457e051d11ccd6d0efe7d5b6754d8f736f7e22e9d018836bd90b4bbc8c5650ffa49114e79a52b7c9dd819b7bb70021fd2941e9718d43aba2fda900287720697de0a100c9a10846b8c1948b7a633325f420718a251156e72c78f5fb1b89627349d00c86a63ae367ba3d0814ab467d2e56e2bcf2ff238cdc20ab740535ce0e4a860e0dba8ec94a10e124e2be4138607a8995651e6b0164cd94e8e3a82a6b205496bfee449599a8605f30a781d967ba206b099fa3b853b910284923e4d2203bd092f82593ab0ebce4b9b44c4126ebf2962030b2d30e103d1812b03247c340cc4863dc13edb024a31dd28459e149f206dfb4626b6e68658b804d299205b7e65a7696574dfae9dc6df9f00650e1c0cd17c8c6dfae68d304f260115335a80ccb732ccd65db472d1211f8403ccfb275d2cbb6291aeac57a0666852acd441f84ad633e944afc28d51a979c56cd63f2f94be551ccc82b3629be5a7bf4767367e5e73db7eed4bacd6b42ab84aa232f8b5e177f67a45f66d40ab043469a2d659a784368a3cbe0657cf0c48c877586af9faeb2b54f8cf841ae1c7e9b01d47f5c8124836b83ff39ddc5f047a0802971190ef6a6077a054db9976b523f4d8fd987a2ca4a299c68248cd396df488f412744185d30cf0f0c3bdeebfb4e063073727f2111ebf3e40e00555a9d66ee158ee2309aa09a97b06c352b229d8e6b18eae415ff825484232e2c35e5d2d49cb4541104a62f7fde552b8ee3aecd477ed546f419844b015705ba6c1addcd26754da9304687b5855eae6c264034ffdd26e9b656a6f876d5fc42e1d420365b658d9f848fe9700e5baea4a41a47d052655c182f6ab83475ac41c1c5a130f3ca0aa1ecada34dab65669b5f87c426159101108d14ae3a92fb91aec9b3a977db3cced09a7b2f344481e9dd51e18bb3c32e5cfa520355a4b27e3b3529aaff851db63baa61485fa0ca7fc8d45a422f5bcc0f26d8c1977b87c9ed03e28d3955076cb6f642c1363d6ae557aa741ebc74a46383d62222034dbb0ff54f50bbbe7ed027207d45f6b534069e34aaca988a0b4435a47c24426acf5922c5793f358b3b0d0065972d1395800e3fa19c8a29bb7d294a0c60ac5789ee44343d52894d9636ac44fe30ee7512ba1413c53602f5ea8de496380ac319577449a545c95e448f300afb47987de7320a260b036e9c7de615b155e3222e4dfb89020dcd0467a68e1f9645f37bceb190062f3a921e9eeb012da1bdda48e4b60e644427da4085335ccc94fc26a828a6d815977021f6faa3240636e3faa0fc88db37aa0af88ddcdb0d29e4708c39c2fe624739f30f313c282becc54626a9d01c3843228c8fa46f5152866290b244e299a4a42492e553d21683a241386dcaeee87e7fa3e884f75d7d6ab3602929bba70a105f9058afa9c402b1d56b9a3634ce9b6d6a4a4173d9734b6bc61e7f4f76569eae8ddadcdc1871af145746a4394517e12f072864013f40947ca612f77070d6873692dd340b87d6b08b9b00210a80ae23a025a50713a1433e753aedd122a5fafc9d5c4b6ee8de033715c229dd7ef6f2a6cf43ea059f1f75d0c5ddda9f24ed4c98e14b7d76994372202198e2084bdf2e77a2317eb587e84477052c55d2b8e2d76e2625f5f7f2bf4d78f95345bbd9b50074f9236e16f1db727b214d6d15d580c5777f1cf98cb4c4b9db993fcf9bc4d99b8aeaae49b10af7224ccc350821b6d0a3d1122ae67060c0aaa2423c0e32c09772d95264dfa748d4e2baae0cb284891f4a045a3645482c1250251a0eff2d89404d30347a0f51a1e543b7729f3c5a4f3d5964a6b1cb4f207338306603edb5e592e68e7fb29f3cd6b13d19e4bde955141211fcf1b158fb1c1723a299e427d26573a7100a38a1728f70d48db07acc9075ca1f8a7908fae515aaa227133bbcad3477a37b3b675f89669d16dfbaec2274d30a892c3204a7eecdd3879444a3730ff239aff81ae1e2cb587c9b6766316169849db8596840493bceb45c34bf5dc4fafd3bbbce3fd3d684ec8aa6e01f5ba3d63d104a177fb54feccc37c28cba9ffa136fb583f18ec821b98ada3a0537dbf7da1e4ca1085ce794463cb253cd1e4edb50c3059fa95399b24f5ede51de43a96b9a4416cc276de24264b7d4f3ac99360eba8bc8ef81691f59f460a65860085425b7e31ad7a87d37eac3d44a5f20fa1bf56cba99413efd3b102f34605ad5c9c6d2d7ccc6f1b2720c769e8eadd793024c7d079349ed34f4193563d6b3c466a69297f51014f81a473263f7670ad4872af632bd40807fd34478391aee7d3b2f02cfb389c58101720e2bc60596d8fbea60bea3962944595259982918873a68cdd4a7d0c20da7fe07b02ae527dcefd5fd43a470598f4e69d9be7219811a6a7c0ea70d6be5ce497930407c17c5afbabfc379832e9724ca2bce3352165dacff3b6c0561b6f870f037d95fdbf6ab247512cfc4f0e6796591c9f56c660c514fe9be3107531adcc71424849a849f52102885d7998ef60544a2ca867730e5fca0b10c4c172a80d3744f96a33c3a4e0debade3c6e655d223403477dc8e94102bda6164a7bfa04d8228c0285088dc5d83d41ce0847d8b5422dab100101b9759d9ef4a88bd4a97ed62c89aa63fa10706a6652e9f39299b67080d5d94ba35b4f61946e898980dae93ba81af2629d93a68ec113bfe73c5b0f196efe41a671a932a05ef1ae28ec095ef8c77e0a2295b136da53e5ff6a2d0615407d5d8f24848b397a24cbf59bae021bd6db9f5d598404d3db1005867862a3893952ab5e9f1b2f8df896279a1085b49e59e52f75c34fba62482cbdb0f4d1adb3e5772f8afd181292ae12587664bdd81abcc64663aa53b8bee34153aa534dbea2587b702287111c0692f707844a7a8ea6ec2420c801b7e0353df9ccb2b93896d18b31c151fe4a0f7525f81ca564d6b2b58951b73e709de14758797c951cdea826c298b972f364765ec75f04c1f5abf51de04ca22e14b0366fd5b87b9a35588e9c7a0784638a2de7f268468048cf0f1e3a1a1243df572f98d6271a45a658067a4dd1308371345c05dfbacc21c22dd01e094fcc60a4f2b936b9517f036dbe35bcdb08c20c5b22acc8333fbdceea4fd55af8e21ba356419f694cb69dfabeb230562862654056d4b53254657c2b7bdaaa84d00a41e9476a2f3c95847eed44dd6c9abcf53277d95897e3899fc4a46270fea895ee1e77c9b6eea797031a839cd99ba402d94d47c5d033d9e829a5db8e08cd658fbaf2e9ab24b785edd8edceb5ce40d56af0860dca6e0369ed18cee515dcf776addd8f7f99ddf9233df44411b94cde804fa8580d1296e90a6e92748d16b55e83456c3b715a0aaf995de1f272df028eeeba7961e096dc978fcc189cd4e4f984c475e354c844bbfcabb770e92bd6d2f0cf797d2eb211a7055fbb23cf23db33871372d8aa729c584d9cdfcb68d64fc813563f27d81e0f1840fbdb0293c0ab7a115df180b0d107b01a95e1598929470f22d472ee81028612490a9af430a5e260bcc7103ce949cff1de5617d2c8af38827ab6f0193716dd9a4196c457b0f3d1b0fb86f3c922494e99513966cfbeb1467b24e99a02e387e17ff70e61fd18c0bc437501028a584b5d6ed2bfdc3c51fa58182ff7f9a97ddcd35cc6abf885e572653ca723def53246f54f60f98293b60d0579c1b2d5b871fefcbc387132fc1e4f849938b6456100a894952a38aa008f1c99206aa0b32b831c2c81c87908019affd40488845bcb9cf0d285fa7ef55b1a37631ada7223914a0bda088caed754e2f209d4e73a61caf3d354c247ee00c7025a00226daba30874c9707fdcbe173a935a62f9c0f7a987bb6be26680fa5d51c96c624af5500e2999057ad8a5ea16630c605440d464a82dcca569af6ddb1c71c09ce613f701c851589aee4ec20250154e907bd9e56068a728e363dfdce5e6d7da1f99aabc9fef4df0228952a6c164cefaa715f4d57456b456c4a7a616b796a10c980e917ec6e24dbc315e09327735196aa4bb2d2f927dfe337c4b4d1e6e3335b5aef72e4cfb8c6528d519076ae04e4e4dc2a0f39a40be97cb9f7baa596fd1983b6d096fc2cb80fa581594e06ac4ac7b90416b53f01ae7281ca3f77f67734998472e49d47e6c5624619e0a8f99854942148b42bc71f1b276f5c1090a33291c0c8997083dccfc0c63bd091ff5c5dbeb958d70561e2f38eaf0a175161240d4541bfd4cb4e37aca4fba809deb781e19af2b534428524181cf32dd1663ab529ae0f43bdb229fd3c1195d2d49c9ec97789e5364500ec7e3eb550065662febef11fba8e2952fc26433d57ee201199172465a378a331c37276a2c3de9239e3fe1e6d3d2088745d02d0bbc0988da18af010fd2526c21402c567517e392e094d47a29838b77f99cd3103afd9a13043ef5898782f1489ea3ce383089571201d56308c6fb9feb159a3b87ec7ceb093082df15a9007f0897fc7a6d3a00b5994825cf9a899400f2742372a31175a40fde4fe9862860985eec74efae6f48b54454050819c611b1f2105f5086905538985a15abffb2800d0cb0040b421e8ce9a40357862d590ec26ce8f51217623c900c0e0cc4eae5fa47779253740b83ecf72a5ef698dab3561236bd5f674a372af7a130808c4284c62e40de3cda3415957f866e4fd676a38ea50b556ef478cafbf1d9b9da74ace63a03bedb37cf2cbb777073bac9f33a2d65b8ab70fac3e69e44567479c06aa082036221156134b8aad1f3dee61854e6193c0967e7718dac3a15eafdb5dc7d6befdcc22f83713e032d81f9c9713eef953f66c3f56783d28906d8b283932c586dff0a4965c497a66295fb83ee13ac3f75e854904d5d2db15a64ea160df42568bc385f1ffbb2fa2d083b128d86b1be186636e9c3a4ad08789d463e4718e58cdcee52c28bd46adf652c0a55fdd6c069db79afd02fe217bc99d9ea10dc6e3a8b7532aaf1a9d3f9e09b481e1e5d7f6aee199aa782392db287658a2a6d69c74f4f835ac40def296ae8712da68b0732aaaaf867b37bad8c4e30abf823730da8b9dd4c71af1981821b46f3b626149f693f79792840d6dbf370e1602f9aab66bf80c6f6ca04b845d027b4fdd148301f5fa7102ee97b508d823e128bb6f42db2788f2e8ff997ae17b0224c6d977a8e0e506719979fdbd530c4eeee96764ccd1c81bd8c804229df8e23e5fdc5310b1b78aa7b54f000977e9b32e5589695c3ba0755e943a3e59f94c53ef11de582ee26969fbb0220aa6dd89c5a8d8d21b2a0118e3f7710dfdd886bffd8d8586c32ef4e05f4eb8d06f645d45383d548e64e99594177e2c63a407a5a93bbb881453adf040636f2c1146efeb95f0914ccb88fe98a7a7f70f2f8f45b2d0c78b0d1928aaf27960cc6dba24c2ad98b066d8f3cdd0b9136e1bf4966a486e00a45121e0eb62a337016233858cc65dca480da697aaa09e558aa6effa869dcab2a72a25107e2138ed14734d7f28678d5cbdfe9dc61223d7e082bde3ca0754ddc7ad5c43555a6607bc30915c3b600301ee022d0c20118663236a26a8d445cbc4bd24c21bd2e5689f29f12a3a8b419c88c09ec309b07456f0d85b861a74c641dc97a53d572e6238540d8da3681143a95ea6ecf131a498d27e985d892ba422e28e1eecafcde3d2d67a3acaf7665b92b425be74071650b9d398e637102fd927b68aa69d96eade17085e2e688b52e4d48ccce0176b27855af54a7a1d7e726eeeb41214f0afe87efb6e17d9c7d7178cc20248ba99c50d36a09399a727bd28fb8eb53351d04c99328976d2848361bdca1c2895cd125d4bd634c2d2b6d84f6d6014d7c6a09e485e1e32c72262f4f4c90199ef697af4627c57913ce0166a9081bdff0331fa75e9ab36d3784be5bacc50023d045735a286b8fc1aa36fb16ccaa3fea24174141a8a51826dcface923f671e936c002b840323296c375b1fc3e2689876de968f867d04172da50723dfb4b6082403731b886529b515351951c14d5a968d80f3eb4a83420b96b49faeb463b468ca40b16ac84582ca602a72b7b4a8e7ce9268cc472f5b05b5f202b0b7cdc2c88456e9e97e01bafe0a7e863cba7e851f13e08bbfd097dd852745f7eb6140d356d25a405879b28d41000398a4dd626314f6ab6365b46f9660db2839348e881cca006ae5d451a662e7633ac2e1a3dd6fe106f8c8825972e7baf4ad23a8608895d7e2599f490ba71451b15e182b5cbd90ca3adf1778ccd4fd0d3b7f3b2d2f3cf4b8463b933826bde419b6c30e91bd6bc4bc3dc28ad63a6305e26952362cc334aeaff6f0dffdfa590e7515b2cb38a4baf03383eeb7805878fa237c132615a3d3703c76ff3e3386d8d6e14f61a1c5f73ea655d80761bf1da1889c31012cab47c8f746c78fac05b495d002297042031c36e9688c6cb9ab301127b430e1533e3a3e9112388712dc95fdd6a3967c5fbc6cff86b2b096021ad2f06c6425fae64226eb11d851dbcc67928d9c7ebae9a49c37e0e19ca0e5ca8703c98611d5a4d5c3efc14681988bed20d3ae7b867fd226c9769fbd86348bbb7610a3755ae1b0133b92569a8dd14d1026d60f95522a4cfb35138c1d91321809e4644eb196432793982ca79dc0708bc5c419819e0cc317a1b52d071b7cfccf2d2e6dc841e11d5c461d6149f208448352a25f7b88684835354f19a0b147f8d27cc73d70b2f982e0ef1862d6fa8e8720aa0b3b035e3624dc81cc3635cb7a09c1a504d17ba8166a915865bf774358ae7d28eebc04814c883afcaf52b0284549d3012e3c9c241ea59eaab11840f3795cb23704cef2dca010a87b616975624c817485b104dd6048bddc0de031522dc24871569e5e27a21df407ec5f4c6a978e740e584cd2a8008db838775fd3add18552d5703c420aa9a438f02cf000514c664c390616bcbde5f700c21dcb80134763f85e7362f233a8879fea890021bf832865ccd40c7eae2846d09427efbf5ff38b7568b9c243320e066dd26b93f655955be29bdbb8e4d4b76f7a0677c888c89a2e84dd02222870723f60e32bfcf280667fe102a5ec46029e0e04475279ba5254826ed48eba87d80c8ccb8e63a82ca9a4948ecde67759bb1d675bcb877107ffcdd7d2db1893a6a248bebd51d6033d460e698b7ea19a486a1efbfc3bb5df3cd2ff7459b37995b17161bb2a342656180c9f0d9b06e3effcbf29d33a00f878595c410ea79f011cefb7ee552a55944600640a8869b584e684528a5a9443966e05e972d4f8a1aa0084005ceba35b81a0ea25c0e13468fb5d7435406483c630996a7bddaa1fc4eb41f83c4f1a1945930780c2c178e932ba031bf138580d565813e3b18857458235b2211a23265b0026d0caa9d1673c59077007f1eabb9da80009d2944002e85af1e3ef9d860a2863ced0c450e51759f41685c8f4bf689a608071786fe34437a2d1c4db41c204de9124765aa80df5e58b7e6866436b5df8a846d9a0f68ef0802c99e5085554ad1d241a757dd735c30cf7e7596a342660933123fcedca2d3da8b8f5175431f67074ae8d0f52c49850aca4d4a3cc2f9a3dc3abbde81fc0fdf7d3dbc5aec5c08c1fa511b51fda280ee2bd844e1139fa151c906605bcfad4f67c4f3a64f11b3907752efdf072d1a5fd89a9b59d59be073f2b7199e2a1af7c932c21fba76509e9729a73471d2ed434cc42fc3358c70714e48529afbe94883087df1c848c6f42f6d5e68e976515e188d9b8353f02358b504d1a613db64df6909542e9a4f381af0ae4c000cbb3b5b1c3abd8583e25f92e9d735ab7da182f521600a10237db1995a74ac560c424cd8ec60644f527ad050155a66ddaf65246fe93d0dfde51416310c873dac226cdbac9bc2a4a145989c9ae43fb37c985232706df79dfe4fc8ed9822a62cb9152983598548f171a7819c1a2705ba5ad24a95be4ba2a2e4fdcc06897a4adc9f4d7eee6a404bf7d294ebb2711ba0fdee5d89381e8a90c747b6761da59256fd36453fc6720faacc7da837ad091a0c4c557c7d08f65db1daa434d0a680440df426ea85a5a84170f49f048ab38ce39fa02293677554c083e1524f3cdf0e556fd39f5501e56dc94eabfac9f0f82dc45aded63c2e0ae39c556477de41e5ac5a7ef3da3a3601e6ba3c803e1f315074f24aa6d0741c7f62caf51f2bf5adc83e23e4467baacc0772b783441df139af0a0d7fe1d38cc273dda46faf0c41f4e142967cb857c7fceb37114c75389ff9f065ec84134b32819e9a5431579f6a2fd802dcd5e0872a8158a765dc507281cba85b063de9cc676e397c0b772d453aca82de425e36a002cdea79bdcf14ba9efb81ea491c25b729e2a3e27ce6c887f7440b9aa614600b510f682e4092bb4771e5c49cfb627e2a4c3f1d72272a0694ebd76db09dab20824bb36d2897fa5ca2ff8b6001ac13e6902f086155745119fa9a0df9cf10b213112a4ddda578e24ce48ad45f1979ef494a3c20c498976c02e87d3e0ea33207dbdb5e0efa4ba3c41a8ef038df4ed9ce46ee6c27738002235aa62f2812363975096f1cd6862ea533a9af4cb45a35701c78c46414cefd18d4b8d920aecc9c1453133cfe91a10bbc20315676c8fb8fde7169a8dc7e189a51ceb749887946b4c9013b4950228208d58a9c9c6a6382a2fbc80961e67efdcae4afd7a94c7aeb4403aeccafb3932b02f109fae61c9993c4167ee50f99da22f773977c301f31688c99021174dc0ddca61074642ee69168ce5bf1a786e748949dcdb07a97eff8c3030e4e859489e0b3b1b38992aa6e582ad6aa07c8441d8c51934705cc0aa08fee45949c96d94afdaeb70eb5da5a9e4f062fadd75c479133341d18a3839811af4d9cb5b865c906a7f58637f0cc5839b267925361bd67e3aee12bddca8258b8a78f83cd49c4e2d1396b2c97f17fe2161366c9cb6c8ca4010e815143c80b04fc3ce0b165f9b39c94ed00f954ad52943b077b584c4843e11251353565713e7fcc2e2c32a92f6c64af556a6a5857dba32d5f0c0fe8e90c663e54193a36d89cf423ff8c20e25a24877d9776d555dcad2fe19adef1e0e0faeb715bad833be163652963145c2988970b34c736317f9832f3dbd0f74a3b2263c09e7b769978ed5604c574709188ab5be54716452306c7bff30536cf8c834285500a8a95e11db158e6cd3cfbbec9e08b4c477dd3241367cb017a8fa6596724863f588375462a601085dee2bd74f6623d2319e3c0eb80cef98c049de94becbf41c9996c64c3cc5964c696f24894fa8f38f0c79854e9cb126bdf44afa603b256c4eea81dfad70606d861d0b430e94a88615626c2680647388cf57ed27cacbaa932a7fb6a9f3a2ba08f2946cb488560ed27817ed31cab54272e1fa1eab6497f435363cdbe17174309d58a00d6fea6bd36214a44919c2e47fa4da77f615eb0041390b6388355a571bbe82c5961284aa249bf010042eb0e2b0924d2d8b22e4814c7e7058adac3e235adb342dd14b18ad5d911b144491639d5a932ea92c44f28c05755db596ffacde42544287015099f6569f71450ea4f51dfbb21e817711f00d01e8874bd517a6df56897e30dddf6ce567c95fa212981383ff292c92b8937216d677840b47760bf3aa0252b203e7eeeedc22914a9338d9ecc33723228a8254b1f0477fab0b0555e0268f41637a4ec572dc6b740f2e1674e45ef333fec3940f416f1e1a5df584e10b5f6980ff5ee7dc9b85f79448e44a40c6359c10a462cf6bf9ab2d063b47057870fc1b0688cb6da5beefa8b95f2cf3406db8ebe24e85324891b7eb93cc642e2423510b845e7e82bc943bc07e565fcea5d5fd5c8d1165d05e8a9dc07e8d619fb7c67869be2beb06db6291bae30f6894850c6abac7d8d91d1fe9911f189db2bb82d2e63064a1fd9bbcec605e27616953b0689ac2562ffb9c5199cd266709911e77cd24ae2981177513cc5253aeb675ec26fcb0e9653f37558092d7163f4e454e8a25167c57085374cbd9c03ba9ebe0f42575d46404925c1ae64e7b4a4e64f952eeccadfb72b01e93a2f1e27057d0bb72bf418639a1d342621eb7b11ebc4730ff0fe215a19a966beb2f8dd496bf349939f68ce9e99fb4ad554dfb664c1c0dcaec3009f26d90e6dde97667f7ca56fc9038fbb6f90017c4f98a67c53b374f8663da8a814d3c480e2d6ea1bbccf596b8802177e2e7b9a7785411cee4ae097284e10a232e1609ebd8b76503cf664288c2ea95bd0fcefa0017905c783926a345f4b5d3d889dcafb391b21432fe057329332ffee24bc4cb8721c9198915d7d85ed9ca62c321dcbcc73cf20527243e7346d643e5fa24a5a5722b5375a4fc04c0983dab239a845b08478b9202eee6ab522c4082c7d0c74f738525460521043750cc1ff332ff1a682ad75e1bcc287a40e17f2855d1935bb0bb7f0b761ee5b2b4072c5423125cf99a9d0d27e44eb98745fa06e046a3fa23b9caf032fbaaa5c9a9b208975b06fc01bb1cd4ca272e05ad74fc7e6943a406ce9f0e961b42b453286ef5298e360239cfc6435cf82f234786623b40976d44c4e6355616fedf3a5699440ca1ece8714f2631127e897d25485697a5df691bacccc1ca50fa3499dc7a833b3f825f8560a9591e1e48c48e6ad58b51ad151e689bbe699f65c92770ccc53e2e2f183fdc03776308c617d48c46dc1085fda677c6bb379c260e1d73764a58b06c307f583a706225e019275d46461772b2197e8286714d45bac6a0ee79d3e46a5eca61ab42b1892600cb8e9680717c1701e6a570de206b630a31131f5f6e7e51f8ad48b02b80b3ac176518010bae48270888b199300a72aeeb42ae75360049b607be6851c19b20fd1d0f4e2a8c62be6abfdc6925907c79b85fe34107d55005d5ecb5ff7f5ec6fde71cc000a6109f0815540f89ad851004dc38af1a7d2e772590e2cf66c6d2a00ccbd015a1e5c32fa7ac1439a5f8d58017ba40d98c776ef3fda43a9d9001bb0633057b62e8393a05cb4e8b32e08085c0ca3e865a14918efb24aa40d0268ca2a262fdd9ca859f90336f80c6ffe1db3d667b90794614e70fcc92d4d0590d8ac024c540f184566bcaea1ce8023b442b13d1eb0cbb45f16533211e80ec2c4aa5e668ca4a70172003393fcb24fec5540d59902db1961e0669807c2015cbf15baadad3f327cb816088d40a42abf5bc2905896eb4f9b5d5b7e0b5372ab0af2fee7669e53ad306a3f31c3964c984c8eafd1e1c07ffaa21f83ece698d00bb4621a29bd8fdc0f09531dc062a2b3a51beddd7f4886e914dcedd160e7feb8027c7642adc7e52a67dad7290fe22277286c007860e00be43b973e5163e09122a4bc656cd50d65fdceb14f23aaa8e6fe40d0beeb3e2abcb70a9b29edc5e90e4f3d95a34927788a9204c59e9408255de105fd5edb43942643b4cc1c1a27505296e39a4d7cb410e8c4322e8825e61850e520755adf71c5a625af23abcff22f8a7b3b5af0c7632050c390141221a32084e59c0ddfdf72e551dff51c1264035442644d62f2d634cbfd5a0d8c6331a24578091c0541ce22a667447ae75043590269e7232ad9f51bd91d5684a0fb2d0698fa0b038210769d22b3723ccba23135e31d39ceb998294a460e8646ce7a33c509403a3b00dda04b3aef96c2cd699d186b05cc80b5835156fae84ed73bb4fb3e6be1d821eabcd9d7c0d9112272ed32574a156c905932c95777f32b748d1e0b511e4d36c67688c6c155d123a2caef41486cb4dfd3b83c3c4386c4070ac9bfb3cabb2ebf1091900477cc1e79af5fa0b19df0a3e799f1be852e6431da530fae4cb4f040951124f4f04047e61259763d2190b2fd65877dbf631c7e1ae3c3c82553d882df2b84286090f9690e1eb1c24ac3504166e423b06a702da32032b7ef7042d2503229a60d90da6c9a5f69128d790507a5e1f6bb6471fd831bbf995a7944a17dd3a451d35dee2998210952755c0039fc6deea8334284bcd717014e69a103200ca8d9acc20858dea165d967d423e1f93ac34407c26e8f3635133f9a36654b8217f2024d85ad52d9825b540b2c1beb6d48dfe4d94dec9072582382c3100d3882989adbbf3d25c6169904afce5099525d0824048be0f4df1485eafc80fba6cc2709ac0bc210ff93d6b2762779797725ec928423c31d8745192038a27e901bd50d2ec12891bbb942cfd279852646158ce9840718ee355c2201b63b8466c362ad9fa21e1b759f4662f57283eba856bd059d778f096afcbef98e8419bf7087a1899a5e2c391e8345fb78f58e42c542fd0659c56085c4a7430669feabd70b9ac1cea61f8a80f73ac7e859f5c4114046baf212eb8b4a4d106d91169fc4584b6da04afe257b25b68ee1f05866742042c269bb26cfeb02da58b1997e7fd868a6cfd526660864391934deeb2b67030c12cadf3dcbd8500ff7ddbcd0aaedb49d1825d52379b6adba094f5eec05deb276f58ec82ffb91f2a58448fd165b5e4166d688cfa692e1877413cbbef8acc4a80acf88e21acac1d123726e45bf65186d4d9e47c4dc1c7825f7272365d4303622fa8e4154634140a64f24a399b916cab912f5b5eeb8a10a276e447f05035d6fb995a87ee3ecdb6ddb7ee3b7ca789dcfd534ca78441904288edf3dce1cfc00c2014419043aff61137e2581dd38dcd58951aedf7d712e668f3cbc5914d3774821f3c3558e7c056c80d45f28be3a4ae6ac93bef756769f77071b633f747a6da5081ad7e9577038efe4c1a64f615ab4d70ff2890a6c38fc277196af8e1b93028ca9335609950c4748b4bf16abc40d5b8e494b02fd3e8d8283b03993e76d2a8408fd864034ae83a10582311e10859304f0697cf908fe8c5a2acada03cf624b70c0534c8533fe84ec3f6fac80fbdc1a3cc3a0d821dfdcef5400e56609b8a96cf069bcba49b89a25c119f176c4023a444399227870135501661ada3031b6e138bca15d7c4080dc67b5d281f1d1da4873383dd031ab7ac4fcd19781a198ff6ffa11b744d09b1707bffabf22f59658e1904771a68963ea9c461cca2dee3173078adda6c89539dec521de6d9b4035691b7a2cd9367ed17c898b4ce6d9913fe6590e40fd52272499cf45e18c297c20b7cd404cb3cc6431c60bb4f019032dc774b84023b1a104d87485159ca116672dad154bbe435534d9e574f580aa5af65d69cbe2a43064c35534b1615250b02129b6d7e054a26b1095696b40aa306b30867b350cec55231995353343dee80d0dda438e8d188f9d78a845db70cc4abea4c829087adb5edaa91637f59c442eb8233959379cb2c0591b07510c5a39c8275e64fb68d5b50440ff440869e70acb17663e41ccac3607ef8dbbf4c9f769dfb0d674de05a467d7062967ef4054e2e7678a908ca5d553f896df979976e9e18a7689ff800c112494f91f94468003e2f0200bce768c3b6a75f34ab6e12daf29e80ea768f7b049730b80568cdab36e55e75b466af952ad34a7a973eeeeadf5ddb50f9cbae758a9cea4e3690916b743d45431137a46e42cc0a326c84e6b5a7ea73b12a943240c17425ee56935678515ce6c21fe1762ff99502e48702020010acd10357e7b8cfd6f0d6972d4a93030666d6fd818c033ea958e167d77800d6c2205918fb803c9496856482346439f67d7e6d87d8056fff74c5822c55b589f0b0f0143283bca9683e2c2178759eee77ffba50562f9b217765aa6df7c5ce0c357bc283722db68036c2cf434f0fa71218b0d9028708323d643730fbac6dcc68c00585db7ff88f87eedbdb4c7bc21aeb4a4e0961e887e5ef9785e1ea46a19a86b17fa18af38775a9c1c87bbc9edbfea11195648372f9251b736130b8408797bfec5dac5b8b0c674238017ccb6df43bbe11481ce54f94ae4ee999217c5eb1838be31378010489ddc7e37474f1025b976f0f79f7297bf0b90d78a1f0a9e0273cc1448209f402ab740ba7a8a8e30b032b32b84f568675d83c7f47e3a70d34d0135575984014a7cc5066b2b6d3d2d18ab1a03d1c40177699b4eaf35d82a969a9efea0b1dfafbb82e03635e908977a4fa0bb30b9a8e98f466aacc2d74e86da0f689dfd1ff9622432c98a70284d441dfa6140d1eec93fc16776239697bb34543df6689009d365d50ac89559c89f137c71a94edbaeac72d4ee4292f04837e1e61550a7724e28b1b29343de47341b1230c98b03c8df67218357510d95e3839a42d97de85992075f1868c5bc46008b5ae062e4fd47e143cf1094750a8ae45f742c130e1058548842d357c74e8622bf98f791f0a3046fa0bea48a4019aa3014d03e4f07f58cc677945155065121e83dba853093d4f488b4475da52ec531d7119086791075636119b8d324c7ad47543a84a2494f63347b89d401bfeb20f20f695781667b7b0839999a1cf7594714eab9ebb67b85835e597d93acc89021bab31fe5ca3c1d6720286d4178de1e624866500f3fdfca0a9da7f902bc483100601ec6bf751e33c4f6e468c9770bc43cbd0f38b45a53ba713d44f625364fd5ffef5ed7586c6c04f804ccb76d2004ed12a90e851fecc2a3da75c2431f6f5df1899eeb0d3d5960d42c1126f7ae4cb40dcc729d84c9f51ab4e8c04c0457abaee0571b78c0a1375729ca34ff5ea81b0ee589b9b80901baa989c534ff7cc029f072a935a81f2415f3c5a5d27f98cccbf14e508265a786b837dd78ca736805dcd14444211e01cb3b3222ba5cfd02b72fc91cf460abca5202581008a0b9a62d5b7132695cd95fefb14d2909482a65ef98147ae565ba561c98bdf5c7431b948bb5d8964d4fbaa3b1782f8e1631bfb3f67838ad18f10a3874da34e3faaa8f4e26527d9861d4ab0dea14434ca67f80b0f66045d467c3fc45ce0ca190c968214aa297af2799586b6dce01c5c3de3cbf11774655e5602e65481a101861080b0210543d11076faccf707fc2c26a4e87987df922d47a7a22f5d6b53dff052119031f65cb139a5f03d4f4a640a2d732388462568776e54f3abd644fd34fd459937532a55faefc5cdd54e8df3c6cddb17602973e0336dbbe7305609f5b27e034efcd71a325162ec0dff615a79e0fee88b5270a00fd90c3bd6891d71ae839ae104c17b9a952aee62ed8716dc2062edfeeec879fd8dfe8c98b51d286e7660d734067b7d52e67a78c7514d2769b6d54718a6a09f0dbf8a24d58fb73cad8429a13bd680c29170b41596accd29d13643c5a2a6bd826bd3ceb8687c0531f1f3df159a49b8ed788148c6754d0fd2b9322d29ba5365624831518a9e19b5b9edc0518e28c7329b1885e996db297ac0fb05738a5a787962be08aa77093a3b74a735c928dbbf4b2019fe958d2943487f981a70183b81fa5f2abffd1f253ba030555e0f7d0e01310df89f487692a7c0fe52d74d407c40991f4d9fb1abef815bf19ae163d5e30cfa92ffadd73b8fa406466770d1bace8273899e9ba6f673c4240eea51c387c8250c9493e7ecf18bc216e3905d909f247b8a8e8fcf8e775f9295a5110ab5158547a4423c47994f442f9e2ed8f410e42648562e2f248162b14dda19325af855e3c6d449154105d0da46ba7d15e8e919434389f1001aa2ebf0433866fdb041c78fc0cad249a6d145365f72af88d8fb2c448f5d7bd2c1e10519f9b410937887d3213dcc0c139c6ae84c48370833e64b12d5deabbaac291b87e0a847591c3e2e006d14160c2046f442eeef8292632440a7df9d3f18a8370a16eba839e9b17104dc67ea81fbc3413ef38c47785e7096c744ede5bfd52df40c1f68e9b02aafcf71c32c367f289e8983b5e062fa72928fa796c78e7bf45b2982d091ca20bbf7d2d89c0ff177b9eef344e6ed3441d472ff0cb9faad4b76fbdcf72f2fb28ff8943586f3d7d3f2a1cd63071e389df0d3a5f4dbd9ecf8e33143fa90ef9f86b1fa7f11b61ad58fbde3a9a9057da65b3e969b81aedd376160d65795c52881e3abb19577a8fc367396f7c6d75fa4c40a34db9f6907369cb6d1f54a6b550273d7ba55510495996a082ea1f8b2a4cb891bc8b133eaa38d0752eafe7b4ccd501f76cccb6d402ae0586ede04850a1a92d8b236e216c495c6247077623a8d08d0fe5549e6cccea6c3a496e9cec1e4c08ad09ece5bb6cb5652c014e9ded32073d50f72237e4c6653ea7db0ddc598c9ad09f40219a5ed173987744793a7fcefb40882e72622bd25b9261ae34148dee7ac53520ddcab13b99640a923448c8b849d85860ec42768fec9942426ca1cdda2200cda50bab899bb28063fe782a8501642690b5063a7e43a9d6f767033522815e4af68883aa4fde050cdec7db872d713ead778bca981fad79bc83c010994c40ef7d129b7c14f9d6091ce81d9e62d0c19bc09273d754e72810b0da6de1bfbdc3a5ad0d2339e1a99bf2bb44f7539eeee76d1ee1dd099135a7dd4aab70c27d0ae27408f876946b4d3be184f53a139b7126237663463688aa9c85918d7976bd89a2443450965f5bd1c456d45fdb642b4372f5b2c5f753c66e9de0575c58395a774cf8c3476f048f58a3affa7cbb751197f06303abbfd186a4b89da573666e98fd2829a3afab925fa250ea61018a4b45baac250146007be616c3227dad6c13a2e050e69dd241a01afba00c9537488c8c30a31c1418cfcbf17ddb22eb53e2697849323ca7fb98a123299436f9c531abaca4ccdbabd394c02068bf927296ffc020bfbe84bc54ae094cdf97105ac26634d8a079b84a5cda9e3e24e35c2f219fb8ac30276b052ec57f1a4fbf3b9c044be1fc2490708d2fcdb664154a04a1d92df723e2c032e13b5d20d1a228a31bcf28d98f6b4057372d268e47dc18b6638d9d26c20c139da91a38cd72fc1b2f19652da8cbaaf1302a784f6d3e64758408fdbf2b678142dad87cbce49805adb609b792c5920bcc5170e217dd3dffd63defa01706eac0829233251530c7ce97edd7c3bb4b357510340b168e4c31e1b1622d146266f2ca2f61dda1fd245d34088738c2198a5529a0200e743df95556890bb15ae0b3f696669a6b4f906f4144ae104c8b76d380168a2a42785dcf46bd6887b085029875a04c545c6da02a9f10fe280d94f78695c14230c48c72d6ff8bc4ba3c0e1141b58075d0be0bc5ab1b08771861e1050118b1c8e2b68999e87fbb1e8326ca0a055ccff75bb6e9cf3280a94757affaeb57d0ad060dc4ebce5a3a8fe059d4380ddade8a782e720c0df7cd210047e1d2036ba9f855745f32b00e8a26521350a7521f7f3954c19555c14457a85516f8cbe08b5818bcd7ec81875b90cb2152ed761aced498c9867bd35333b5c6ff3423d392099e9384b6ef882e5233e41a496d763ac498996b484ebd0c0b30d15104456a2ab6e76d71f8254c939efb1f8d028e7f307097dd998d3373646f2e0856e01d320e91a376890182b98068d254a2d9b13cba4800a86d816986926801098808774815a122d8df7dd706ad50ed6faeb884b3497ae6ba8fa236298a2c20a600903b86c24a041fc1b60a56543b200df64ebbc70bc3b7e27f68bd7f33520e5e37028ad0fc1b2a0b9cac5a40b2e8eb1b6f0e5e6fb164c2ddaab99bdd3ea1ef47e106933b11092080379cbf37bae79585d8240f003b4932353f645d80ef5047d1c3f16cfc6af05e3f10260910c632315d03fe09bbcc01d0aa3b6b90d371b5d2e79b6aa87aa3c999bb0f1dc2ac4254e96b167eba2fb80b755867355d9c762ebc1bcde656399dc928f72fd36ea5920336390e7542980c8e24ed2f5389de2da62f1aacc0be284c90de981e065ce506f846d8d1cee13a01518d34883ed7ae01ac3437198d37987396a420e042c2c2f9bc5f1877145aac637c4a9c43f375362dc48a9bede787b38f621d7548e4e49061204985c57fe27d5ea2663565ad73eefbd059673be75e0ba2c12eeae7683bd667abcf19f0afc628015b0961bfa7128f9a1c22121b30d8c38dd6624b18cb047af84ba4979c8ba930b3bcce5045f18d94b3c91918a90e0a199f02502b3723bd115e4e47e0469cd37a6186f1b264ef3c98852ec393b87a2ba42b188a427f5c6602189bb6a113bdf98b8b0533200177b7d1e47fac41ba51e574a45da3d7706e3942b80b24ed6b7f45789e14a532181b5a6f85a3ce271b1d6974ba1d66bbe40908c631ce409957326503c5515a979c2f03e3f78a87f9190c39cc205f4416aefc19299a0c87170de30e6424b4cd335f3f336c70d90e2f2662f03312dac97933c800bd65217c865c2b59cc4f869833931a95f466eb3899f82ad918048533d8f106df8c1f88345a1cfaa190c6f3902c1614660610ed3285a0a19ab5b7d6b2b7bafd948bc53b5067a8132e4d6e4a9d0d0a10848ed8b791642a995d7a69203b37ecdc3eedaeb6b2e7cdce91dc3f0b5234c7053250f0aa835052345e3c8011d60e5c59106bd6de377032610f81325ff436d7c1cbff526633830c698c16fccbffc0ea35ea173e8b2c471bd20da470003870394347eb74d7958cbd720ffca385b87241569ade71e837457c8d5bc43ba8474b5d82a88c0fe5c60b13d49e60c01282c7b1dce73b94325748b86cdd7688f3e7d321cfd340d13f99503fe8d9a97e8d7731e39437bef05e18737606be83cb3226cbe9486d367faa4783289361a597eff392c9901dc89b07c5b6e098611c0bc1c0fd97fa8e3c9dbec4f0058529960a2d3bda7eb46306b35e68e425eb46b5b8070394ae041369f7b25b4310bfc2a84b24480ebbb5e34dd1f00c11c332fd3eae6a6d99bbd5e83d64f62bc5180c104f10f973df235288d407f466989d5039035031a4b925afe972c0da8597a84eefb8b5dad3408d730741ea3b7236d9b2550f27b24eb7f54ab60ae052674b164aaccec8bc9e076466c79325721fe39a01ee1dc596d356a0b12110a0d5e9b54202999ba39c85936c9554fd7f4af306ebbe05776caad373aae1f971e58e84390c674f6aaa5f29082b8a4f41e674590ce6e8234e53e55983ba651edeb80148185d08869615dc4b531e35a05af6617ab0f8d04673e95791ec39742fdda97871b44eff9b2ecaeb834b7f55862adbc209c934c12709d903b2b4f407201ebee9b3777b3cd62502530c806b9f93f5fb6a273e36b3be457d90a4ffaf2a0630517c5119f9df993e395f1b73dbad9021b0f736bb8d7aa710f1ef425ea05461fbd21d841b380146d54e1d273d22ba3b66d39fb75b17fe5a81dbcc7830c6c63595c9976b3593db60484f8254a28aa069370dd64a4901edd8ad209583e53e4b56943ccf607988f4f57307645ebb56b8fd6f4ba58c9eb1f4763730395fe6d766aa23944a3983122b3da95e680ea7f106b8c699764179e13d0e5b3301f6c2d77802ba2f3b493a575eda0946173f10710463df2d2447baefeeec6813e285f2de415cf8c81e311842a5ccb05b7054a1ce21f218aba4f1077d76308ac20043d871f4c8de7755ca575901b5c93d878a99ffcad4accc03a3be2eba275e89499a0aa61136a7170dc7b5eef5fb3d252a0388dac0400719e101461c9a80d7bd0893f7edc269a61e3d9b97fdb887b81929f9a8d02a862cbfe412536e731d24ea8560f2e996bb03cb093b25c9975946f6bdc93e49df87d48ebb53f57d7d037be157a911612654bfb0f76b080c1bc0724a59fc047f7303dcf27561a237e61aa5ce8d8ea9d71fdcd12c4304915d58971a81ca047c06758653af3e88afd1bda00c788208f40da2a726496ec356ae291ffcc0bdd17d71d0bb918c12f875d0bd3d9b817addc36f42ed23f597d669b7e51533fde5022d4ef3810f240968f10787b594205d1116a1e91b4e0f53fe82f17bdbe6c9a51ec97f0df1119535e29d829f2f65e1e05d3fcbd624df01dd394937e3aede878ff89421b9e78a4c77277304b92fecd232aab004911fd88081dfe6d2253651ba5e92aa490b250d8b8c573edf716adee96c785078f111c206c17c1220c7ba4979be86a5f69b686f15f367a9bfd5d292e57a1ac88bb8faaf3cc18658b0e677b952138656b83561410e14f72b2639b34560cc42655059fe49414e49ccf8cd13f3011b71ab8a7eeb6f2c5362642722f1db5299d2d9bf8e42e713c474d4045c6935e414be3cb089a661652343eb978f611ecf9e9514953a283f8ae26c5be94df6c7a570e8e16a7166ad75b28c9b729eddef3583037a8be998395f8fcf9a036257c6304d2fce5e9a770478fcebe792e8360cebaa81c53c6a678acff5127e79a9d44b2b0d0d50c1880d8a95e9b42cf90c1c4b906af4e18cd346625276c0ac443ce2b3441859208fc6d27396133666dc6cf7e4ce5a650ca4ad66ece8c3b17bc8162b4645492c298eecb86f2d87749b2b6db7c7783de6c522542b2111a54ee3e3ba43933a9bfd5a2553ab8878e3cb73c54366a0ce1cf6ef62c909c9af29bccce1a1627d8dc777260099025d0009413bcc5ffb219905e19facc43b749f09cdf9b8494ee87944d2f48793c4c4f54273ccf7fa830600c4cf1ec2d5d092e1123cf900c03ace11c308da62c0ebff57fdfc6f5a9fad582420fcdb12cb6e7785cef4df8b64548fd6a29ef519139ee17479ca8849f91078b44e1985e4771afc68c9271fd4d4c9adaccd6798ffed48856fd414d5858829163d13544bace8ef310ed07d8262579292148533da2f250d5a6c5d819eec400747ae1ad1038dcb6addd560d856e036311ea43716549070a0eb04c5fc86233d90045338ab6f8c5c03f6775250de7af44391e010c235bdfca74ccace2193832390c7a554c131d70967cb8c6c8db20cafc3fe90bc9666ac95e0c258ba05ff31edd52404454ef5c46def1c96559ab8b4b68ef51ea79f0cab9dc48f9eb18d61e8c78e71bb72481b4afd18369336381140e70a94ed93505c8e4a1fa70ab5b6ec5ffe6eebf87e414cc273c4ff15f5e6602cc4dc13417036e7c6aa48993d9ef7840280ba16c0add3532193a5699ae09f84f2d810bfdef401f75a1ff540f5767f7f794e6ce2c3cc9ac6c49e4c4f363efe9f23f45642f0ac8ed59a92374b67da935401a71e4ef208d9bc8c5f40f43fcf35742f8786feb89efef6411abefd51af4959cc9488832889b30b7cd07d79a5c04634cdfab91f3fd5ace6c837d48a3d59cfa84658c934efc1ce4d4b520796ce8cf67c830d3549246bf75cb4d21687bac530ac9e5221265e317e3b5a7dd7e00d8f412dbdcad043460586c4ec179b1e09bc842da0588f55bbf28b6b6cc790c45744aaac4f7f5d1f64ccfeebe96cb476cd94766d8f0c7204f2f0c27a42c0728170ba9bd951c7b02ee119399a7a66aedddb9acadfde9aecf7d9bfe4dd0843b3f76c575cb07ad9d8b9835bd61e63b7b412a2831014210fc95de26ba09f620d8f037ee333b9692f21ba26417ac04bafe18c1537fe4f8348ef90b216c426642423433f1fa02c7e7bb11db3cfd03d4709b31286359c856d4d5933299d265e18e3d7e0f81f2d583add67d0640aeaf8ddea8c32d90624869f6b421c31009c7600bb4433a212ff3d6db9c98bf47279bdce4f301f5578fd7425d2be62a2c3df57fd74d325140e94686496ca4476c859a31282a6d8ca8b2d4a972047fd8125315bf023ee5ca95d9bc9d0426d54fe5a0eb62f4ab7a862e074fc21655e22b423550bf0f173a0bf9d1be507777b3a3cb843ace5b4798c7a0e640a2aab170124c3f639729204dd91ee3554a28e14405d862f1ea94a35bae4631285d921052e330ae21a89d1e9feb7e7b04901f6a390db3ab6639c38e72a3de12008ce39fe8df5d17a63bb69669bbf89d12c615dddb851ff7525fcfb13e3e7f5938504cdd866c8a412cfecafb4224c2c0f956f3dc2041beaaecb36018d6907c0dd8871aba3bcc58322e83b958e6242ccd426c71786718be8414ea4632583234c6c251ab4f41753258ccba5206d24db8eea67501b94acaa06f3ec069a47f468b5388bbe0dea7f062bdb51731cfe8d1eafb1a4ec64f9edff467615778c1741a936939b03055c9170445b8df6415399b6cf07419b64cffb41209fd60c8ca8485ea165d3e1f3727906bc42c2fcfeddcfb3c99e8e48e883a1c2d2061117ae6b9e61537cd2689f5cf000e55e273febd314432a3ba7e106c26aee4ce6f10082f73a81c5bb0596869b4f28e9d51978d19f46a1b2beac2a353811afbbb178841e5c2b3957928ee7df2c660983accc53c8c52fc7bd64524970dbb0092391a79933e988199d0e62512cf8b9b76d967fc6d6e85a365dc477765e386f2e6cabc8f08c124f303896d9fc8f5d532bc4523f1a3b6971646ac7ac4f17b5fef719b64db2b8dc521b64d16f89ba39de814902de29fc7f50d904d4f6ef8f82553517f9bd8450bf0c761d4925d5449945b1764657de21e3236b404e5f4dacd555216b1826361c6651b03cfcb25fea000197c2d14866ee1900b189081a0e5a8ea66c59c5a06bd5d38d633d826509b72957504432e2d3cd8dc69a7d7da263e60aaae88e86a712b7ec44122756699881fc38d159e69dd5119b8d6822e11c34783921e48006103f8c2ec829f5029c8c5377b635c642034684f33f02e447b168bb5b37a9fe9128424dbce4900f8595b749982788aa8e6493142cfbdc6b2c9e76a1faac8e7a57cb550bfc4123ee62151abf166f148c60ef9ce78bd9c86921381110454cf20aab9f48224bdc6d05de7444c90d55305c15a903994de5cfdd63ebd83d6e8e9be32ee1e57aa94ea23b52ae71f4109c1cfbcd60df6437d92714e3e87c7178020ca4c0ef3c867d4b192dca6a3505f1b645545229225ba27c03be09217b37d972ef2d534a32a60dde0dc70db4c970e573d5e383e5ba0dc770a50573f895ef575a1007120ee8a28b2e90f02ebae8a28bcbfa3cc7eedc2d0692a64fe1e7d37d0aabe893ec21df0160eb771de174295a22ab4ff560a51de57489f45d571e0035a4b7beade1bcd5863fae0fefaeacac3cc3a8a10f5797f8572c8f70b618e5f4e9c5fb338effd9f2a71cb5fa043effa8c8c845027d78df10310b3cc8420f6edb1e23cb01d1d7db44a0a26f0e51542a282a218a4ae5555e46148a2a9af8553e7e35545cfa63848872f9b81cd5c3f37f68228dcff357e15a71f945b5571dd3a50d06d47359afd5a5a6056879fea6a2f9a3e7fa6e64b7ad7724b6f0bfa85e4af58a7489595de2215d92d5bb1d0b81ea6008c893b5bbde914823e358b26ecfb5421fc6b8f213fb3d9ebe97bfc5d3c9cbef62fc91755e3950e5584338163764721fb221ed6249fe49dd6249fe573d96e427f492cff239f9d3de78e979ad3ec96fef48a4319fdf1b420422f4621f381485227cd346dadf795f0482782d04da37b23b2d23892dfc2193efdb42a021d3d4bfda6f2635e42680396e8340d422b1238878f9b63425b2ab7db7791d04aa3d1231aed643e51a37f123a046e73f408d6e32408d6e9251a39b5cb80a9765bf817214547a2dcf65624544a9ac4c6a228dce3328e4628b7c9595a3389aa448c5069755662ecb6f1baac85c669a22b49764c1b03e85d2c6739724913249776ea4e151115b6e10511e0fd8c44f7304205cf68270f9438e8acb063080dd91d15c5106255772c8432e7fa8b134569f40ffe8b5fa14af28431527d73c040bbdb8cb9fd78a2dfca1242158e8c5024ad3ef9486a5d7aaa251a0952783029a41c55e7932377e8822676efc907443afe5313087bf7cb7a0263b9da758dcf820159224209512900a8bb65b5c9b21377e9179e4469b5054809630bcc250d304199b29dc356faec5b9fac4cfb1b8217df2702cee08edfe7843a6f9dcaebf1a4ce351114dfc40a8318267c5e5afb9f1438ec572141b815fe3eff04b166b34cfb166876389248fe16acc55708d659a2eb5f595366fe7751d6e328d9bb0f04217b8100b1d66831b896e09f94806069c50ce667399075ab8a1d78a56f0a0e6865ecba4860755b8a1d70abd424da0e1547d5c4eb8a1d70abd9c40a5add15856f0000925e04110bc96d7ba6120d21069f4ebb6a3e0faaa4940fd462b784006a619855e5e8bd3586108a40abd42382933234e088daf1b6f98c2bafca19cd02b6595a28add90cde5d04bda30040bbda440bd93524a197ab5caea3248755965a552020d51542b50064575f9c19938802c2ec0165802500674e138aa658e70463897472635977f041bf98063a3236d3342421cbd5a9e7f74d3c3f38f5a8e6ab1a25738690f73d4ba2c7af1a4a2efd8b024438a5e973faed7e54f4e8c0eb20b979f3faecb3f6a71acd02bd4a4d7ea12671f7aad98e297d56bb167438eb9d16ba110f0323e9c06f8901ee043910f1f7e013e2cb5c41a0458194df10f600d607d60f902f4506a49800c567536c94ac98d1d7b3bc0a626c91230cc5cf65a59c430185e37f498bd65cb73f5295c404d9f428e45d3a7d057b7087bad2a2e23b97ebf21aec0828b10649a2d5888ce77b1b93d1ac7ea53c76a0be89366c1520fa59f5a3f8db3d6b160bc09f05a4cbd96a6b5659ae62ba299651a661a6e168d29066b08d0ec4416cc40c4a611d1d091069883bbfda08d4d0437fb7873e3196e3c8347f57c3b5e6420ba09cdf367b1b1f927c210b44f889948832bc176e06a75ff911b7a41525996bdb4aca44ba5cf4c4045579491524eba5ca44fa2ab032e3a3cd448ff4879877fe713c23dafbf1cfe9146f6d9d82e88433eff76f9f237847c30075b50fb78f94922eeedf29704ef882dfecc0346bd9ba88834e4bb15328e70bd1484eb2fdf232afb50c6757775895b45680ef9da67428039a4053f5ecd562a9da0ecca5674b3f2b3ce3aebaca59d616fcfdc990ba5d2bf48447926cb6c0f37e456c63356ca687bc76fe03f360f94db10d8012c96e20de90b023ba8b13b2a0f94b628a294bf26cafadf723b78f40fbe8117d0301a01a78764073528cd36a4b4637f37e8cdac102a3d2f321059ed5cfe6ab0ab5d669ab6659bf4de386e9ae7e9ffbc582a9564fc53dadcdface4c6db36e4243bb298c52c6631ca601b4edb49e7e13d60084e2cc5070c91764797329bca6303decdbe4766796ca04b5ea368ca87dc789df26e5b6e6541e395f6f33802a1c4bcedf14a660750781f2af22f75e7f15a950a7bb8f14dd45909db24ac8419c64a827014cfc48cf84b0527d12c17e952e5569718f529ffae5cb8fed251df739dcfecabbc138964ca9f5ffe0ce358a4c12d28aea35c0f92f254486ff7f180f08f274129b346c151a9544d2871580b6ec8473a992bbae0831b720d276118c764d69f4f08be1dc88b0cc454f5a7a581b274c9bf4b5eea1fbc953581faef7014dfdce0b4470622468fcdcdddddd987e04acb385ab7a480fdcae9b9b7cbf666d97ca5471a1c4fce3293956369ca1bc4d9b9b05992c305bff8c585c7e4d8e4e4783ccff33ccff3322f7baf378deb7cc73fcff3bccec7f33aff7d1dcf7b97fe74ed7dfd757ea479e4f79eaff3fdf5e75ee7fdf7fd791f2d3e5adc6d05a08f9499fc70f191f273f3f94f169fcf16f283f3c1f968e1f4e5e7233f1ff92e2ea534f97c5ecaeda97cba7d2c126ec2eff1bcfcfc8fbe966e3f0a33d0d307556a6587fb90fe88da0fbfe7f3f465a51ffe68f1d1e2a3c5478b8f16d166fb42e79b37fb93456fddb2f9b7253e596c5c74777f6e3e5b6cdbc7be019ddadcdcf3db77e8795dd775b6bb1f7137f0581fdbf7799ded581fd1a651bc090356718c8c2e25a008922132b73f03d226a04ded9568c8aa16911517e92b58a0e4f6730c9148c302b1a57ffbf877b33b58341129b328d14d9f111560ab5279b75c02ec6e9a363f389a9cd3a79cdafce0743e38733e7f35e2dcedc3ef3df49ec3e93a6d6ef0b11e1b43eda3a09ff5f72cd7f1c17de883f3ff68f1d1e2a385e7614d064a6e016e44028321b2f37c17bf1bdff6b37a9ef33e7ed7b127bf0bd8dcce1bd1754062b7f39dd5115b80b86ea70302bb9d07d920dc24bbae0322733b1d1bce8f7ce357c3e37e7e47879bb8d7e1a6cedfe8b8efcc8e052760625d5cdc343b9d0e377fdad0c707b91dfecdbe963aa0791561028d17387aac2c5d6229459b84bc3e98e6c62eb9ebcaef587abd6b8f3fb6d383c2fb8ebbdfd8462943dde78c6d2ba03de6679d8c0bf19929fac47dcabe7b7f6f7575fbadcb6666f9553909c35e49fad481312719f61b14f339f9d1827de02c6f2ca0da477e6d2ba01c73bec9de3b9f2db2e71863c14b3e5a4c2bdfa5b72ab3e73edc361bc63ce76e3f27c75c1d3574b14ff1b91ab9903dcf3e57c3d97975029fff3a1fbf0be0dcf9dfbb340eefb3bfe1cd9b3b3ff3ac8f815af0e5f39e9fc0c7dadcf91ecffb1bf17a967b7ee7cf06f75ba7c61be46e5ae6eff9aa0e35749125dc5cb71370fb37159af674c07477ab5693339c3e8534a74fe1d6cab6c8708840b5ef1795efed556a7c5f73556e44c21a723bf63628688fecb3ecdad8258ef9e74f3bbf559eab8a4c97ba7abe533f3f6d086339e63824fc725f0dee3f379f2cb6287888ee6e76ce395d7cab73ceea79aeaad890af8ae7b7cde3d9ded36d4f6b776acf7469fed65de69ffc291ffaa7d29fe913fd993ef5b70db32cab1ffa9f50d2642b379958aad862f2a3e76f023c93f37152e8f8caa959637ca2ecd4d93334b763837ea7868e8ff16186d3a97f9756a9f16a9d8a51473586ac4e753cfa9f1b97e61bbf21dae6cedb728f29e8999a741f828190285e140821117273bb0fe560bee1bca427c578f047307a64f467dd3ccf957b8ebef65ae57e7bad7e566d5c40879b38b341c4160e3fdbfead8b9b787bf63cad61168118af7d0cb7f75850f71349143377fe4a142b2442728ee4a0f4b73adf53e9c72f07f7ecf94eab9f9f757bae9f9fdf0bffccdd5eab1387f6d9dfd082c8dc2d63e286899bbb7dfc320eb2ba5b96651f1b32f162e275b7cefe647ef605c137c66f958b82825e7e43c4f8697bc478cdf658f9f959f5c134773ec7b0b14ba4e7ecca771e460de51dbd7f39ba9fdf1f8e152bbb44b26ff2d386a08d5d1abdecd2c89ad8948f9f102a9ff22a3564e2a670ca9723dc7e6643c89b2244c8bff955b121908e9752fba6bc4b6f36b3a1c9ff701bdd872cb2a237f970f4157d4a15d9906fca7c69c3cea4ce676af2b3a6bcc9cf7f517ff04d79ff216fcac7efc68b4f49010573f09d6fb59716c4d13d7fe7660f8398dbc38d48a288dd1ed987beeb0f4767882e326f61846dd507d3dcd09f3c5795e03b3ff421dbdf8def257e38fc866a98fdfc6e56ee3be6babd70d0dffe06b531b66c5c7379dbb14537f1b6fd8d7837eb729967eded519e3bff6c7017f72fa0c34ddaaff86f4c1b446cd158035feaff4fa05a173769ff36e76accacb934677b64df7db8591f4c73331b7a51e94db92835e49cdbf9931a32f132893e98e62ac1f7c311ea6af61f47c3bdf695af0b0ae80d087c86f3f96635ab59f47bc60c19324aa5ff49a9c7dcd4efb1db1dcdfd548ff7c99bb94020866636d7a55b19ce9c3833b620ac3bbf6b6ec71ad18c98e1701d62013bee7cb633a65d4097ba593358d19b216d0f0bf817bd155194cd05a34d566c5ea382626648911c969982d5da3269c44b07a1c3884843fb25b6c9753a6f099fe13244f4c68886d8861bad0562f620b89b0d392d2b8541c2d2ed8fbfd443f7f09765c870b6a41ebeef9aaee74c97c518bfcad134239451125dcd66cfceb90e1e1c4d59e6cf41bc385371e8bf32c19c190f22a52211ad51ca9f1dae7319cfb7719bb6756cb83d1d22d28834227d8d43f131b684209bdbcf812a09e62692ca5a6b493092ea768ada79e3060a4a503ecce71f646138969b9a3f24c16e47eba7ca8072069452da17fa200ba3fad89cdb31dda8a023556ce91f35115b5a25c74dfd2a386eea1b269148abfee1734362915afd03eb3673451a45ba9971d48774644e4a45a21b8e45aaaedbff615d4e863b72fb71dc54c5eda7f3e6e6b919928ca3628a24735d34351724ad48aa2ef91624d5edff802c9e37f3863da63316d0a58ecf373ec86220a49d37200e220db6330db1a59fd64ef17743430305ad5a54be4bcb1ad079e3281c470549f5cf1ce754dc8a938934f8b6dd885007c5bad4130dd1877e9f37b1a52773c772aa2ef5cc995c7031955b75098a2e3527135b764043120ce402c16ebfa7e675fb49b03949301109e65950cb4d93a5051a46980ace6d9619088a2e3548c682569b0e68f74b2728bdf10a1b7ce1863266d4201c05b2dcf45d02598e9a376eea9fd36f40d6bc01599ef22c378486a0d5bc59b9e480f2873356549dee614810b49b6041cc25dd6e6205acf7fc80c6bb15a1f233cd037e16067cf99e3eb5305c330728a020f57d90d45ff005e66383a4b61ed090591d95a7b3babee5306bcb24fd3e9f16d07843667d3626d66cadfea14b9eb9e0aa5a2b67d9c460af1a9aebcadea58d6cffc46b9a16f3afceec0434fb7887747388da4d4cbb115d6e316bcbe4b669f29d7ecdcd29c82093d2cea8da72362eb2ff4cd58cd2466649c109384b9c59aecd322bb35b8e1ca8e6a83973bdd560e660f6f279fa26168686dee4613e29944d6efe09d5e92615f5ba684fac94526221aa34a6c2cdc53788267f2aa63fc7ac1a1a32cba3bacd712050a8852a37dc724c3e8bdf7773fe29a515f42fb9c93f162ce2f3f4c19793fffcc97f2ca823486a4604434d2aba2908373910943779157162c1221cd0c5e79fe8d4e783a4a85d750aa51ee126a79fa7754693fc582dc74d28158ca91d31aeb71cff10e1f1e56c3550e8c2f7fa947cdfe7fabe2f76635e2496b8f36696c8e77b39eaa3f9d07c2f9a2ef97f34d7ff737d47faf43252704326bf1c707e390e059c25bae44f2babdce47fc4c7e676b41789be989b5c8bf196b3e54c29beef73e9cf73ce1a68f8cd2107a5999a30c009ae02ee46021a6b4e4a864d41059ab67ddf21c645cc8c41a411270ca210f20217b420d2881c0b56a0022852808213f834c17c623a31636609260966135ddcc10e5cd4810e73883462a411b71c6eca8f8b2ef997e351f50fbe050db79c98a3be9c582c2637fbe5a43e93f5a99acd37014e6937fd833f7f3ab4980da8a43146246b365a4cc342be66d32769bd05a2135c974d5c9f83d56cb458973cd4625a2c2727476e568b6d39b18504312db6ca723caa3e459a65dbd45efb6050b82e3fab81b9f6bd3e9bafd8e2ffc17cce6fb3dfab4b1fec4b127e2f693fd897a40a5f8ea3a830852452880214228d68927392539fe084262061c215566c4b504212aa40c2118ce0b41681084338228420441a91468c2e37f99cc9bed797a45199caff236ad2f096e3fcc51cb5b9bed817fb622e9b245ab85cb3e615696cacd802051a477d5e8615664c2e5c671b316c336ef29f3339a2195446a96d8e373d2e61a9be9c39415f4e9fc22f76b9e0af061256e2c01cb5b5dce4da9cae2ef996e3da72fa246764420dece74215d327ed85c43bab66071a6ab1a902db6e39315df22768b8b93656a4a14521b6b41ca5c1b61947f18d6cc9b056d7e58c6ace98a4520c53e34234f9e6cae41a28107ca3036f390c443f61f2e17401fd70a2e0fa47467d3e9c24b8fe1a1722eac46e313779a4c126386db86e6fd0707dd3c4709d09436237dc54db10d8f5dfb84882b5989c42e6049aa6c9df623e27a534863ffb3df734f2f924cdd1623d3766a65583b18c9bb4d86a6ab1bbb95ac02a243e48c2c4e2dbb62ccb7e328b1bb2baf54626e4a0757ddcecb3d36a311f2877d36cb622d025c4ef7c5cae2d7c50b385151a163289920f1607164c9b32d04c616b9b15b8705640852578b21a9a4d66c5b2a28b1bf8a0e33639e826142f24abc68a38e4808399410619a7a203123a3a58810715abe6735df18231bcc144c3c1a2535dc1823a2cf9a8c0b09852c6460b596461cb5858b842e60d4da03576584212e6c75577c0f164cee0726e93db96a9a8a44cd7d0e0863366ca6c3173c339c564cdd6cc246b8816ebd36b586836d7352cbae49af659dd8e74c9376937d74693bd9caa2e6d3447b69c2168b1cdb5d1f429ca6dcbf18c53698869316dc9f5ef3ec09788184de0f6f3c6bc1b1753d5a56dabe2bad7a8a09819a2c566912d67cacc29266bb6a6b669b13e855bcca64fa167e6fafb1736bbe5e8600afe625fac4f99dd8e7c587cef5fcef76daeeb5f0e6bf38e028c8b2ef996e305caf7afeb0b2af8ad936d39ee1df94e3fd6638de458cf6c48b79c4c6e39d7dfc3ea34bba0055d6421b96b526a9ad434a969526afe5926ba010d4597bda39a48e403a5a713a1ed6d2ea0d207caa4570a6c3f3b01650674319a38c6395dda904e9f193712ba08ab35b8e82066fe3813304386c746bac8e2dc5d70777777eed88fee765865215dee63a378977bd9dbf6dcf33744ecd2c6795ebe48b475b623dbb47dfc86c8c016c30cdc30be0f96f729b0b0bc7ba18b7d0ae5c7d0caed455df2b6aecb5ed2faa99eeabde4ea8fac47f6dcf6dcf623bb1b97a3862cb71f99977135e45e0b72434dfbce5e4a69c31da2ce86da739f05b9b27adf236edfb911f25791e0cdab1dded8f6d836b9c94d6e3224dd30be94bfd93e753e94dfd9ea3683d9837bed7b6c5aa723eb9c6f837b6dfb4eedb1d91fd9755297e26b75926ef41acef76f59b74dc6ce6792939ce46cb8e36eafcd7001378cff23eb6a0fcd06c7bd77b64ee7471639edbdce19d0edfd37db43b3b6875b1be333e141bef6c06496bd64296526dbfb04dd647115575e1d08f1ba4eeb743a360475be21badbf1743a1d0da4d5d87d43300af886dfd3ef6a28639f560c04e8350df49ce7a5c7f31ec8867c3d2f3d9651c03ec8dfbe1b1e46814743e9928bba8fd6da573d99108a2b51a0310a1888782543d1a7fe2aee5625d81f05cd6c1884a180c2b5249dfcc812823595de17cf5f8d94e70f891b7cfb7164b7fb53aaff8b2ab7db493108b932040bc5fab4c5e50f25e993f4422f9a9a87298934bc2fdb50be611cde2215f64a4688a33eec3ec2b5fa146d50361bd0ee3b062157cef8b8c4c085dfcc6f977d42745eabee3637fe56031a320d0d0da8e7a59dd12521c01c1ee9d5587d6aeb587489a248fa71f5b3eab288e422fae25dbaed40bdcf1e017f8097f106f8962fc077cf4bba149fbb0147050704ce08dc90cef69dcad7d5227dc77484d3251e6da175378828194df24946083920d8c85121b9217d72ae7539e48a5ce65c770b42b8a12c441f6ec44bfacebd4ee57ba50d29892dfca15728490dc1bac4ef142c8594441ad9484a1fbd6edbaf0695d597dc7f971edb3f1b03f8d1a8867c47ff5f8dcd86307d9984d2b2a5d56a28af764324d2867489bb0b1afe85f1f20be7fd3e1bc2b05a4b637589238b0d2707a27cbc9c77f2281647e759da103eb1e19c9fe5dafb6a944649bac4dd3e828d5ea010130f3c987800855e940408340c62f25d43ef95efffe8af510433a9a2d710a87cd087a257f55a5e11cfe5491bb25cd9b19aa685ac77a44b5c0501683c177bbfb74d41fbbd225d6a4992f6bb86f2edcb19d0fffeefd1d6ab824606f43ff45a9d7bb4c62b3b1754a5d7f25c1e8da3e28f5e5d6298fc70f44a3282d9979de77d39febbf6fe5fda0aca7c0567422191e87a28140a7928f41d4d9b93343f110a0a8a0de9c74d8ed37e4e93efd8d7fc4d7e735fb161e83dbab4afd430d4c9dae9d4d0e405f0fcd9e8beadd91ea1ff3709892abd02e8447046fe3ff7873e58eebf9de912bfada08cfcff1094b9dce31f14d225963cd830c8e5e14d3cbcadf28ee225401d40ed31fabff2ca6e0fec1b3f6edbf0c7ede7a1867c7990fda0e979087f9802f0f19aaabcb6ca0bca8023589fe22d551ad2f3fdb738bcb579600d401db928009e29e87f65e5513a67f993705efa14e561bc49d5aa7f57f9effe9ff8e5f8bef35afdda82dc77a782dccfef6816e42c8e0cdcce6f36ccc0eddf3ec6779ad7557e173f1cdf370eeee777ed3ccb5fb7e06687e0a6ff57c3eded675f04501ee5dd725100e0bb8d3f09b056bf8f9f04f8a2bcf69a7d00bcdb1e283f6d8fcfbb0f96ab7dde7eadfee5f88f955da2f641ef36846165974cac102121427ff2a113594fb62f47e8dfda49c88640a67772e2475ccd86a0ffe1f7e44316cbf2a067f993ca6243be27d286cf14f47df2a0efe7a1fee07b7283873f91828239f89a3c5f9397963e5b10c7bffc7f89226b0f945f31f9f80df1bff22e1d517ee57fe5571ee5bbd8b9c79281fe8d74258943f9fae5477bf8396df879ffed7ba8b15fb3ef35c67f6ae883e59a7ce83b5509ee6bf2fce5f85ff9f8e130f9151ba2bcc94a0d5142f66f08d7be6bc8725f0b430ffe567ba0bc00be3f1bdd5da22f2d4b97a849eddc8eed81f2ff350c591f2c17c5aebc7d17e7a1d27b52e35da9f182358caf6b3f460d33702dc807cb5582efe308dd7f5b639fde862a2a2a6d431f2c57002f8019ca57002f3f7e3704606797a405491f2fe88d5c7d0a80950f7e27ebc855472dd2c78fb4f2f1ab1103c677f580777bc887f12655daae2626bff2df5723c656f99ad48e6934f18077ffe367c3a48f702cafbf1b30de84480fefd223579f4836e44bf2273d6847ada6a1a40f47ad519177e96e8b014d9f28cb33a98e5cb5a335942cfdd96079d91f2782f569363d09bd606edb507bd16b86867c411c9defef5825b2cb7d5b253a14bd4449ecf4900dbd5042af135bfa6a08737bf4d3e76ab8e3f690cf422d23a196ab20e2c3bb34d338ca073b27a5efb598a64f9de7172511c13c94d6e97c0c1c9b0a64b8f20d475c0525e46ff2e24326a21775860c5110262f945751f93611a578e8fd43a14fb130210b66290f03023ff42246ffac1a5177c45e60714415bdc9879ae84ddea53b9e2cda72b53f98f22ffe25e5858531e2f6e5c58316e605c982d98b0f925af97ea6314615c3a83c376d458505583721d0d0833ed45421d0c3fcc778908559f917efd24b3804a341307ef42de30cbde8fdd321e98bd08b2c8c9117d083603c0c8a35b1302a0f7a189487310293f2a2072db849f0e79c5b15ad809dc738013ec8c25879d00349f9d00389615f4e841e868501b262b9e5267e6139c4a53819a43ce843a6895490498116a4210bb6e558976cdcc4b1cc7d64639cd5a1776f229af84f70f9590ad10b556ce19f22cbda551cf295cf784a75bdb0ae7293145996314e9754329bc218aebb3bce122630018a1513981073f93da66bf8326a93ce1d92a64f1acb17efaad00731f917d09b7c7c13930f591813950f3d0c4814bfcde36bb5556acbac56f41351dc550c0ad566554dc54279cfa2583b5fd61735a5664a32d80c28e81f4463758933255aab95d9eca7ea2f57b339b316ac3325b139339bf8c5fe2037138928d55e565bb9aad55653118186592b6bf54916711da1e993b437e2ed2a6a3224d9ab4f60738c06c5e5f7954301ba7595bb6cd0abbac44fb8b420eb60bbfa882bdb5cb56d3f6b5741c3d186544a77f77ebd5c25c35af1f59815147df29f71abc57489b72068328bd13357715722a0d7548e02598f81e2f2bb4aaaae4b4b226d4b83692feda52571969bbadd6a30edd525d6607d52a954da1b28b7b79daaac7551a0065587b9a9e554a9fc155bb8794e4a35959bf8573346d5a3ed5ccd9833441a513343199690610c628834e20c7d48556100c317b0f04217b8a06d410b595082852b58c1a456810a53482285284021d28891467c712ba0f1b5d754cd18fe8f286f57f52b6b65add65e5ee32850a4e1cfef3047993c67366e6291a45d9ad563b185dfa43aacfacb4d368ef296af6a444e436de82e9bdb2dabb53eb73a5ce5040db5972a6b293bfbac951d89ae8ad1552ec4595e4453f91157f98c0ff196bb3c93aa3e85998db6ea53385531ec9608e85dba6b56a44bacb54059ebb2d6ea126badcba1f6ca96c054a035c1afa9d855abebaa48c32f3fc8698c3cb146fae528d7a4a6b5ab5c25635de52b47699352d1ab74dd0502812f2730267f62636b2fed75f95b822f20d08b094cbfdcc49182401b11c90b6ec0224e4cfee4630af4a1b06b2e7fddcfb5875b1007e8f6836e7f66411cfd5689be3dfc239217dcdcaed1d76b44f282215d8f00ddf8a10a16017a9337b140501e54049093f81901be9cc034ac63269665040ace89896d989b1864b399864d19da1478411759b4047449c6186326235a7a02fb6d3863b49131caa0cdbe8696d7bbb274a9d42596922dbdcd148890852337bb11490e8ae4608a1b73d0821650951b91e02007034c38c31637013732e10c466ef749427ec7bd4e5e7affc2e9bacfc7ef3b5f84e73f1deb51f9af336967ce2775423ffa22567ee547168891970e90d19742ff77cef992299664e7933e4e0b1291f22b5f44e8491608e943a40f597002117d8a4df9986acff3cb6784aa4bca8c199be69eaf65ee8ae74b79b7217f7c4f8509bde73baeb52bbf8531f292f29f8521d9948711592046808c9ef42f3e548d7ce83d1546e545ef34f4320ac6c8cbca7b2c4c87f4a0bfc97f0fbe98fcf726ff59209ff7fccac38c404f7ad09388e8fe7bd0c117ef3def0151b1a0db97eebfefd8bacb695c46467677bdf62b2855147a115352788c3136cb0931c62d85f49f7f21fde7e37f3a9f62613edf597998ce932ce841529df2cc2f49e2b1528f08dddc7073734f21b9c0f8f9efe37fdf97fa58307bef97fce8a8463895ee2e47f1cb36d3ac6d2862fb929fd7e789d182f17ff005fd6f7c206e89e8fcf7451879f1fce7817cdf792046da02e9fcf75c5f3affe920315df9182c5f4897a4941f63841986cbd5321cb3b9c1c9016b4c3d4a74394ae6d25c77d1b4e516b3a484f50f53a474775f531e460d7dac7c635423b1c61ba3e9404356d58860f78b6158dc6cc1345cf0cb268be6e82ea6895ed0dc255d363cd76564ae7ced9b404cc160561dbe921e465d798e116fd7afd822dfe7c039540789b4f2f103dbea484909bd4bbb1ce876e57625ab3e8f13724ee7a503868d8919bde86354fec5104022529ef42f294fb23046e2c3743ee5a37d09fd8a85f958303ee9632a142d48c4f7912c909393f73c10fadfc754e79ec7816eae2b511efc28fa1731291f7a973ed225f929f5451555953aaaa02a888aa64bf2a3755797a46f414356b94022e87f6fc4c97b5e47e75dfa84d656c1c43f89319ec8f82732c6685fe89f5818f9d432cc4d926fae94fc7293a4b185ff46bc4988defbcfd39f114135d2faa1f153c197cf46dfa22abe6846198abcae6365b829f6f51741b426001a3a8f1e4b2ffacb4be8a8e84b335daaa97929b1c982975c56f5ea08737f358888682dfdcf902123881a23dca46333020db9d5a7b63c45979857ab30dac4d4d8d8d8d4d4d4d46c36e8220b7d1498f20fc251a0b4201131f6b305c2dffc6d41ad3f5a508ba90ed7759dd5a8f7998b5b4df354ea2677f13277f1f8e988ee50e8b2198e32922ac9b8b16b10da9cac02b50f92e2fe5341cdea8871a2ff7b27da02e97ff97cbf1624d516c688665f3ccf5918cfc37c547776dff9f9a0ea3dd7d588664122fabb7fe9efba6fdbdf965618232fdf7bdc7ffe85fb0fe8b9d7ec0bfdfeb3304640223e0ffa97cf832c8c11ed3ff6e5f31e0bf3d6e5618cbc80be41ff655214810d31d8818c4a454d52f14d5231d51fca886ef0c116471842031f587186544ccd9802c514f5628cbc5818232ffd9d85d1e1a6f9cdd91d6e9acfb1686a5af085fb8ea923b62394ab598d9be69cb64706e3d678d0c58f31be8c555cb71f63db8f39b8db360cc165439784c7124ad5ed1b99fb58198b2eb1664454c620e6c48c63f1258d8935cf567439eb8e8d45d0e7af88e9ab251c153f9cfc21dd7266cce9c1fbcd862c9a6d1b49368c35dd43ac9931014e95207e48189173fb4bec32c25fe0cb07f3596e15118b886eaad34d9e67e3cbe7bd20a9ce7bcfc278ffb1f37bf9f08b69b875633c5646f5deeb2af8d281e9bef341529dc3dad5acda723bdd145bb773c8dc1f0de28841ae7482baa8a0108558d64348a56a6b4f093e0c048a8ab9c680b14202472aa217292194131310fd783eafeb7073d332e91d5bfa9b88bf4bbb6d263808b7b3003687c8125a9bdbdf51dd28bd403349553674c66623634e4ae766f373b572d4c4c159cdd54a7e4839199b7fdf6c3899fe916aa4e268f6aaad0a9a3dbfea6676e4d298f28f567d72771b6659d538b6214826ab5a1dc57c3578b4ea9392953c4907c1ba34528d54dc088891aa4bbd1ad9d12a26eb9e539d5d79a9ee3916ffe77267b919373515944d66228dc8c920818623d548d5a79846cd54bf9c979301c11cc529193010fc4a808270fb412e06221342448162a01c10136e23013473412c50cb64a6e5a8eebfef57b9715467abe743ce06b79f9b416c80e79b737de654b90947aa99db0fca71548d894435a7e6dc5068058a11e9de5357a254f75d667b105bfa2d15d1872256d0a00a7be4f6875646c6cedcb63470ffd0c26eb02dd225dbb2aefec12d11f0e5e3f9d07a2a8ce78190a07b8f058bf0fce73f16c8f71edbed9f0e8f5db53297b6b5d996e57ae328bb1289dc8694d61b2576e5280b846984db6fadb8fd7652bbb2add8d2366661addbafb981c61b5ad8edef6ae6ebf25718ecf2db5caeb0d8e50abbfd23d5ed9f6ed8b070eb10511b16d1c40fc46685e8037fff7c4394433cf9a3e1f2e3dcde9694e04a2f50f614dff81dc72b6eb86db1c13625e116f36aa7ac0dd72232cc9bcb97d24cd4a7909976a9d9f6702bea523f4a975a26a1cd1e123a19056de7247ec84b440516c1a9f99c9a76e5a566cc79be208ecf95ff2122822c6b1eb34f590da315378b56dc86028d56c49adb239b99ccb28c399399cc6426a5d4b46ead03709d25b6781268bfcf0fb7cb313e2dcde579737bde5c8e0d5d640957228d0f2806a0158d512bb6f483568e1a51114dfd239a18dc1e01e1f66ab4da7e40f92568d527b672a0263520966bff04054101a201c980402d900b04844823fb7ed009e2096445d02ad2900f7a4566c0ea53de872022dc7e5010b8011e91ef69f5da24e56b9508a8ae68ea7b3007f1d4df813898b9d90de74d9f4290c5ea534882dd569f408ad2a53ec52b70b0bafd330bb08b70430fb4c2c20a132cb99d53d58de1a875b32b1f8cf50954bdd7ead3fa794ffd6ec49b448c2da0db70c4badd0fbe7c82a4befa7d90945763bc077d276b6842733b043168f5c4a72868c556a09ff73e1cad4624e01ffab33a6a22b63002c2d1139e916ae52399510b22102015d187065b2f8828b007d1d42f4306010800000080e0c90d4156385a451a40c80ffb32cb51231bfa239c89860844f7fd9ccb5126df3fd51051276fd3920155ab0584530e5c6cc0f7e17cc30d3dcaa35820281f4af9d0872c90d0a7842a90d07b8f5281a0a0845050fef328a1d07b1f0aa1dc3042fd4330c6cd6c4568382f9360336011dfd3cfce224040be07d91409876473fbdd2349b0910ac8f7ded30a84fee73bfe88a0fff9f84de07bafa3157cf9500bde80de7f16b4897dd5b32a381f4b3f965990884e79ac8cd1109c31120c8c9160a42c4414c9a524d2902f5a032dc36dd21798e472d4a86676b6bea0d8c8c651a0cc08c75124171893b1b1d36aa39a6c5403c64635d70b3404c5ae12f3b24de2079d6eb8fd13877de8ef58f2f7e52a11cf779effea4a94fafea4c63c514a7dbf12a53c0fc6641c4552915c548b5d99db94e4921b0f28e83f1b34a0011ffb14f2cd6cac010095a877a8a033b27d9c5be5ce3312356f915c5fb8b3a02b1d947120e85e529d4ee5f883fcecc3e16d1524c2fbee8df0ba372276667f17724ce7698de93eba29e505b111e47aaa138a6ed7b099d0b2efa2f3e7995689f63a0da37d97799d6ccb98d0c91bea11e2acddbb7ffbfecf028df54a0dd4ebb7d3bcf85da6496fce3c99cba881eab67fee6db04843c916dbb68834bae7ef993eff7c39caf3fcd366b27d141c56596c4b6e641860e1c6dfb068d4129b1522102ce4c11c3d649768fa347f45e3d3722b2e50fe25580803c147d887fe9999905b351ff1bebb43bae4f6f5281fa1dbf3b77d139931fa7f01fa1ecb045804a73ccf298f5d7929fa2b998af1fc1333c5df8b4c51fb44093e29cf77aa43263e95a301bce7afc6e779af630de0cdcefb2b94c0bdfa193364c82895fe45222b96e01f8e68c5e5ba7769cfc6968ec482da74896e81ce90c622104474b78b44ece26e32d2f483545d7b4dc4cc68c4fdb71efe5af61a2784ba16539fbb9d6cd3699cf58f7937195b34c9b124332d9352661ff97213e1826c344dd334ed338ed46dae16bb1aec6af375b59f358ee2546ea2b19c8f7943b53150ff707a9caab39c6a9b9cea7628f209d3020d67ecf6f4a8b6cd9bb88514439837577e4aa8db08b21942f7a34bfddccd39e79c73b2dc26e77d3ec6e28c904475c8f0e2a7fe68533da24b41aeec12ff129effbc0ffd4af91c81f05edad007ca5de20822383fbaeaf7536378d53ff47f9563be1a9e4ea7eb2adf4fe5188fe779efabf159566581caf62ac7d2f6de8723bbf3bb4f7ecdf1fb3ee73c9ddf7cfb72cc237eb494d2258883935f6c9188d270b6cbcd70fcdd5e860c193bb4cccaa9843aa557ca93cb2eb9edaf3d99fe18a3a6454d8b9a16a3e67c448c71c90db96dd8060b6c93b3846dbad457a0fc21dbb4e3e0a6596eb0e9216f38d2b5385ef186569783e3862337ec5a57b8a148fc702ab2841d33b37a0a8eeb7adb242f71798bb567bac4715290688c7c1205a30d65d899372009bb99db61c7ba3ce3a8e93434891ff47625882dfd5d13d187de6868d8b55838505c46c55407b9f36e57b481e6865dab6b4391ee488cccddee1967630b7f17b963ec7031241a6384b39daa5bf50fddb5ba56913eb934cf358ff4a903e9c7454d76e6e1dea541fa7dd7f1b81a2f3373df7552caeebbe179d3de2879df8dbedc779fc755bf9d8f938272dff96e70df77c32ff79d2772bbf470dfe16c8c2dfcd598ae496286acf24cabfac496d5a769993504ba018176bfb968c7d49999995dfb583d306f3a07c1cc9d37363eb7db7040c3ee54b7bf0373d4373bfcdbcce797fb59432aba1c67c34eccc7bcb9fe5ee5ae8a90b0c197c8f72f5bea8b36e6ed6ed7df043a36e4f758f9c6df6a101ff3e64acb32bcea52b37445bad4338e6a29a2a9ff06b79b8a06c24c77cf74aeaed5a5b06b41a04bacef280a45ac29fad446b8adc22972fb7b8a6eb3826762ed999ed9ac407be686b451afa2d18a1b21287d05dad5a878a18b79e253fef2bb556c68151b6e6e775f813ef7119f64199331ce2be2b9bcd68bf9d9c9a3a0fc09ca494ae8abf96abe9a14fbd97c375fcdb784fbef4339d190b4fc641cf5a2e3f9bc4ef68bcf3773fb39195bd21fce117777e777e7fe8227a4f7c86d5973276bdaf69f0d7dc8ec67e5a7cddaf7cbecfb1efcac8debb73fbbd967c3ef7783a3e913dbfef95bcd28d7ccbdc6d148187f30f7b36116a740411c4cdc2460aef67cfbf2f7acdbf7e590d03e71df2f6de66fd5af56fb22b9de71d5eff6dcb3b4f12ce7a24ea512ce25a949cdf51a432ecf99550f48d8ed316d0ded9548589f401b2d615d93dc50f667c36f266177da903f9d637b42262ec7b1b82297a547c663ce08f20b427883846d307e420764d86014c7e4bdaa81ce2db6d9d0421fbf1cdca7c8c7f569817ff229355eef434ff42f5ebce88568a4426b680dad19596a436f542a5dd2a5a63636f4a64f51546797bcef3adf7973f417dff7854522f4383a172545bba17a63bb28360cc13db15b8cca380afc40f4e39980a7401350a535a4f7fb4ff5d4f0ef67433a73fbb71a7e58b7bf536353b569da8ddf0d8aa3d21a0b228ec775fbe424fac89fefe43b99061ac61b35d0c9b38a2e75cda4892dad12af474897504221cfc47a66ba84e291e912cacb2c68f7ea124a922ea17cfc385897506e2ef79fa87e43bad41276e7871ceca27c0825f45ec31d8e0273e760cec1fc85f5b03c2d0e76fb53aa674897dac3bafdf33d2c4fab4f28375a49979a5e93246c6cd73f0777dd8621b8d4f2e8523fc772948abfe7a3ffe7ef3d0d119e52b193c64d6ec379336fe7bfead550743bdf55ae865f6b7634b75ff3b85eb44604162168bc620a2cb97de71f5964a34ad1d42fc39b116bdcc54023d041c458c865a04f3db877ce8239e673cf592ebbd29fab7eb949a4fb4eb825216fff2888bafa54f79d571d9d1a0122dd874bdc8e8d4010fdf3f6ddbcce9bd53adbe4dfb58b81fa773e2c7532d927d7d87a19912eb2745d0c59dcb7efde3fb65bf7c8a37f763ed619fa60b97c254824fa4e425e9e7547f6b31ae104aa759bc7d50cccf92c1910b1dcae49c8196eca7e4e4a3b9f7d06b22d6687636e7cb436a34b9ad46a28e1d6c542a04b198fad09349c21b33ef5873f64d675a2440e84d225698fdc1f7d3b107bc8de24bb943ddf70dae8cb23b6643e07aabd6760011efacff9ddcc66365f3b4d9b4d513645d194fd9cd9cfecb52ccbe40ccdee30a24bd98cefb3672c68772313c040e466f7bbe137c696ed69a4d173ce2cf341021ac61b1e47d048c31f472533f1005dc923cb3c9bf286d7d72d8d2d72ce8f358ccfa34b5b17b49fc786844aeeeacd1841eda9f6adfba39d3dba56bf1a4878175d78b7271cc1d5ae66411c9dabfd76b52e65b607cb980841f3544cbf22a89bb42f62b25665e9fa14200eed5b732fb9c9dfddb5cd86b4e4b107d81642c9334a7779198bae637a4497e216374e2f50b929911bec4a1a2af0776db83c87cbcc688826fe084eef4ee90d73daae7639aa61b26dbb609dd986b5929486758c79063b219233229148c4b1d604916a033146becceb8ee6d13fc8f832c6283ddbb6cce78c915e593a6ed36ce8bf7d28fdb50f7f08b733ba24bf876659b6ea3ca061b4e9362079f4899bc7f471d26c987d3f577da07c2d75b46129655f8dcd371f28d7e70eeddf5a9b1dd96b9a6b5af759463bcb63c7e41d1b9076a07088a678533658438cb166c756923b78b8386ac794dab6c38655b3a914ba6ebabbc7f8f1b3ceac74f77e8f71e6e8638311c1abeec31f593a900dbe223ae73bca259ae4cf39845ffe25b8931e0fe996a33152e646d4f7f25d220dee2317a21522143eeb62a57cd073d5513dbaf1a7c98d9ab538ecf5d778f4a92dd83ffa04b645826ffc245ebe8f3e454ba4f3f28fe8937f18b7b8d28a22d8f83862893ec5dbb1232a3fe41bbdfd4311cb68bde57491c5bd87f63c669a1663cb9218885abe9068f23301672fa0fc317a52767429a5cc48c085f38a90906d75530265e762df7eeedcf8cd5b12287ffc39e78e38fde327c48fec468dce18b91bbfa57fb18ee2932581d2504a29b34ed7c95873c3cc662b01e58f7676e9bf8d0a3a67c7e8e2b1fae0d78d6fc408e58f36fc99d3c23091da6c7429a574965276a8a02ea2dae7795f8d782343d1b4d087e8c697d2e31fea71fc24cd3090e02823f2e3cfae939d7b4b4ea5f27f3165d98783ab2f92b31c7fc832f9e1a846ac8c2031e3f6f8e177fbd20d92e2e6db9063b87fc2081233ee0f37803f7bdd3e1b416e7335a6c21a3211ca1c2757fbcd2ad157fbc8d2adec925c5d819373c3190321a96e06929776c713681883e853db0544a0c4cf97774c4159fa4b13e7f67b4b747100345e31a48a1bad684316fc3ddc78c510190f76b9d5caa22623a23a1b37c5d5ca8b285fe988286ec6686c28918e3bab42e375e915ea1a4b6bf50ffc9a1b68c884132ce6e2ba053b1f2ff75e041a6aac3b4f5b9fb6edbd86d2b5ca55d1267eef98a3c9aea05aff6cb7db736fcfdbf58fd4a76f45a021b7568ee28c104dfc564c285c7e2b38fbaa538a6917cb89ebd49b4e3ddb9997659eca51ec92f156423c96572407ad04dcd05379decc6595e7f252a14773f933ef16142e191a213552bc64009b41d85bb8fc9cb1e17238935c7e0e39135c13441a5d0523615192801b726b491634fc31ec982b2a894a9daa5b71345c8b4bd2a770e24c36cc0862c62b7629dc64ee36a3b134558673c3ec956da18b6eb246b8c9fbe8261e6ee28f4b5231d57d186f8af07478160c928a6e5a75ac07fc3d459f58335802460699aa6bba4615a392cdd17052441afdbce412f13e7e17701b9557558ca352a53acb445c923282a3e21514ab17222344269bced1f4b7cccc140d459f4066f11096a3389a8da5b158524a8e86a3e92c47e3c13a1de3481759b61a536d896c35a4bbbf21a3410de9e3936a4c49ba4488552fdfaf3cffcaca872c0cf82b30a4ff2ca80549c9f7d498e23e5b626a354e69e5b784f4809361c41c555c815183d425a9bd481d46f40f4b388a53ae97335f63aa43dc4bc6126e922fa5dce42665126dd391f29eba849be4c71981f12b2f3ef4bec9504929a59433ba8e6f13c1f8ae2b3e57b825b427791ca8bc49c8af4612e0b43a60ac7cf65b8ce843dfc1a8ff2b35c693aa3f58596609d92fa5944e84e7ff5f3cfffe9edfeccbf7312c4cc3f8be43a9de8feac9ab54931755d0bfa8548b31799a7dfd8137c5c6787ff23131a08f09d5984291acfad07a5263caa4c61448cacfa4ec5090d926313246fb63cb16c8dcaf76a8348df3964dcd3a452303000000f313003030140c8804c3d16838242a6aba0714800b92ac547c589a674910730a19638888000000000008204842000ddbc22e5f62172a130a16e87df655c98c9661d57245bedacd60e94db8acf7cc6f0f4ec9ac01f3343f622aed85080e75d74de8d3a0b2ce53ca8205cb3524eb9edc39a1cfb0ab41f35c286897263bb5cd63bf75eea2e0069c08f09bbca7073b9a245203177ab15fbe8bf1abd0998f47ecf2363b5d74a9be978e29e436da1ceffa2774ce4e30f9d845859418c77382d0fc28f1e7c71b6caa29f525ba2522b3720ed58efea1d8f9b9634619766d65ebcc732a68c4ae14027d0b710a7088cbdde92dad2ad32617aad5f5c21bea984247ca4e6563d2f9e96c80ea21514e2f982f7b3ce4fe1e71f76e50fb248b142790d41ac9c46e6c1b2a0daa057783e05bf3f4f2b957f58f2ee8a7f1a7f155957c901c924882586b09c9def7e6d101669ed7d887c767d6c95927cf3e382eedfb3fe8ca9ac434f062ac06d120e8d2f829d82b3e9edddf6ab32576d55f87ebe1cd675804188a7c30f7e71c49329e93a97c7f017df901af1e0f1dc6db15e1a21c4489d530ed477262c14ba6537b30fc304f19ed8a31db81014802b26444bcca1be544231a43a1fac61287c1d9c5f21e9ad21d9b402544411a98de74713fd35153a3c1d033cd121765aaec76077a12c24079658fcaaf649e54d45e5015744b21f1cfea8cb2710a51e4e63358b584449b7f7d567de4be41a4603a3ebb31b305964a50fee9fb92f1a4bd1afc0b2d213e93055486fb0da1d32a41b7202fac3878f5ab535e89452d10582461059bba2677b4dc2261a3187e93b98b4e7c42299ac9f1593df953a8d89512b298b00d9c1c4947baac48df3b0fd5a321d25b5751e48199b220b11eda2b584161d63fc1fb32b5817069ddb62d72096269382dd54b23b737d438cba72f8f043aae88614713e077962ce0a8e3b65ae9b06b74d3496195571e812c1d10d1d085404bf7eb4d67651a4a8a379153c58b5b2a0bba5a043bc59319cab40e02425a8ab1782bcc3c625efdf6c2a257573ffdd3fbdd53242761fa7002b0a09ff10f2b09f33c21289b8adb31a9c6de705488efad3af11107a98085191553a64de4c87a88d09d1922a5017c3ecb284db536334d9ca0dd2d8fb7fc0d46c2354202cebdcf52430e3762bd1f0f6d671f7c12993423d25491801cb042171419c30999a5bb835c01ad4212aaa2bc0370c6f0b2034f32299e41169ac64199e0ab68287ebecc4d63166df42383f7dde6181dff473dce68597d496f6e2f8bc41c98c4208323ba157aa8251beae92da5dbedbf8dafc9bd9a560722afc8631fdc5fef1960fd7accd676e50394d2d3f1a6939d02ee81a63b7d2b2a9d46af98944e74fe910a91db8deb3486c256f4c01575e246b91c026d257e6911e56ad835bb86304caf6dbb0edc11674c56dc63c7bb82eec63ec02f90857e7d7d0905623e3c510d0828c5fe84737048904b41bbb151e95c5e37ddb74e9f5a2f78011682a1376359978bed8297d78bd7cf15bbd0164e477b858d04ab567fe37b692f05408e1d6f4df66d9c706c4402525186386595662c3078fd2617362e41b7a8db24446c72b3e27af18a03192e396391f24a6e7b41d6e13c77f67ede3cbf3f5ed4ffde9299729ebf33c1d33bec2cc9b4f59f6d2651c95d634c747d0e298f9151005325aa904075b1a1cab8cda118027a92a28d38946278a55f8eef889b3527c82c200851712943b68fe2c185571678b995c152ec5e3a151ec40af4ab81be56b33853c752728e068df4a82ae7c040b8f6710393f45951598764f2f2e2bdc99400c2ec71783393e319ee807cbd691a9562fb4b70b8a73e3ae2b93fb94fe643b8db198814856f22f44ed442759a4b0cc9ebd618a93523767501f7ccf0b86a1086c8862e6c2bd7c5df17b87fefdf8b2250a19ec1aaa29525c152c4f26b2a5795a50a39761f412210b1e445700c4adfb4302511a6a99e50adb0fbfb473b6febeeded1e5c173f6493d77d853b9e73f51438f479d128ebb115e8a62973ca37ff8c38a55d17a7d0defa820acd5f3881fae9c26543ecfb1417077b69973311b5e8607d920b8a01ac209c7631e7a51f05a63f8cb6b6ed2ecf3d1d0c2b79582a47a3575aa7ff5d0bfce836d0aecb61f683b166622c448a93337466180ae5bf4f4cf29b41b0ff100e27bea3092c896ebbd1ab067e7339dc7d70b71fa52af255f815a200b3c4f00215ed99940a4dc9b4dbe35abe21c82aa810421b0c7589ca424237f6f5243bb4e109184a4a0fe8a3e7d0d08c4ed369222852f1e42d6f146e059678053fa22c8b2fac1f24c5c7bb31073e06aea659116861390cc99895db180259bab31a274c86c2e6213c0d489102bba97bed31fea93c72b222abce3578c4b86e5c70af901cc3dadc04072f30774bd20ac2ad9a6b8294f364b1e978634e52db005b3aa4ad4b981a582147d6c40411a0c1e166250c1caa1c9cfc2ce536b44c5acf5d25bed1c5af83d4af1c91163aa1eb344d2734081353da777c4e9fe91af6895653932d8e9b0941abb6e26282c608a0ee103d4454a7a6c2d814a1441342b0e0afa3cc68f14851870b37338b58403448961cbffd906bff898166eec05fa180c0aab7192c4b532906070209aa2e17aa94b037259166a120222ed0eab06913749d59aaad138ad794346d295659981d46d26cf80c8c360640424a79d2fb8ee0071f6f3bfb033aabd55cbf54c18d2ce6c47366982709d872ae3031443824cd402cd1e73f629d2ee906fa75fb5d25a2b83349dfc220ef76935a965ee265e3ab7d09a091e5214d03cf14e3d26bc08d5b9f62d10a8278c0ade69de3b33412bd334e76846f49690fe2675e54928853a1ca1a878122aff02f382dc0bb2c4e57a8f956f846d506f62a832f5717eb4332c60ff8c9a71089d6f9229a93399aa86735a463999a316d3bd000891d487bbd52ea5b1b58002351d0a8e7fdf17956a88313335dcff531296b59988e9666e888944569852a768095d47045b77f44277dcb628d66103657328eb62a7013b59087af1b35369d82e58f993a99328f97032563f8500c8380ceb1505a07bd38f1e8302abee78ed4458913bc562c34221e7d149b1f5c3576d469a4d47e0fc8c24e9ad19862da022896d45131978f1f5e9490fa931c93045d97887425f69a086770f04e765fcaf826d40a73e98ef9a393e2e39c4b1e21366dcda7622f35c9e4c1bbccd9b0e77f1c177fda26b8284503502812a5b9742cb7c98e30fd4a736819024bb708679f70c25cdc39549551324c15a5ce92353e7f351709cb28324d772b4a9fea015084efb895018e200b0772fe3cb812cc7b3318ab6c0641c17338be784139f91d95802902434598a30e519873fb8a1622d645136081d5f82b910dc8420f738406cf2d1040ec99d53c6dfb6b490c159b5a62b8c3d95fc3f230fa50317d5d2b94827e704747637a66b49b6ed6aab3156046c912b8ea36580c895e607111f78f355c89877a75b613d3db103b882b60ad5a0257b6b065dc8dc423a4958ec30abc12aacda2f51651ba94cfc4391995e97f9694b60c43f998234b44c33f2b6b9a4e74292f24222298223a1e5fdd98a7d7d2b08934a01c8e4506b50a7be400f5807b3415400a9409eb096c504f0baf949f3e52099c540aac218924cab7d77b613ba3bd0aa6c36b4b3546b3f7a3865e32a00e3e52c6f219d4c9e81ca0d5debba8fcf3ff9e4f374b3721f95a4a7b99e2f08a765e800bb8a7e68c27f9ffb03ccd6c6a85061d2bae1fad2bdefd6cf473ad32f7914c68b68b499d852ebd1c81370684823ced193c644466a250a58dd636aca250af521656b7992316697760c09d7faf614c69f14be8613a5d4f34d1c30301df349027f00cd3fd060783af5739474eef0482cea23cf2c295d54f8a42b6b8ccc75f610d0bdc0c7128ef3976d12e14ab5431df90e715b38d28979a38ca8325a715cb6554944ceab734add58113f575feac0b6695228484a9c3546ff4f940741416a8833aaeb01e5e703d200e33aadaef694d7f3a494af241fbc819f42e9b4420b4a5e3f37d7a86f10ea993b98f98b3b5298a385d04bb176fe88f7a158b12ba265d1f7b6aa75f365b33ed8b54c6b517a91760b997931d3d8a9699d01b963ac930c5b4526876dde06ec3db355ee19f219cb32054f5766b07c523c99fcf86f41a0696b0c6740ffb3ba214e3f71bf36d16e26965ed98607cecb81319a80a4228ac012e6d9ac00309a51625b023af31023a1ffe8d100335b4f648df85c487f49cf435cd3663f9eb2a57f9504e535f0f03e02fb36c1e075b0e4ab22b108d37524c7abd7014bcebb75c61b8ef4da18f1dd84c390510dbc7f71f0f8314caf6007aaa98be9c2fc6f106c6860ea2511287b0910530947972872ac0274aad0ed1abbe2415d40fbc7791dc498c2a19c3c744e6f80242cb79eda8ee8f5402da4bf23192f2994a5eef7328a9cf44d67afe6486d5eae9d200d7b0da528431d129fc18087d0d762288a4ba116d221299cda9ee7eea1b54195e997f75373dcdd6fe36f8921bfbcf285f9e0ad2c7f5422311fc9e586900fb45303d90e015292ffd35646fff897150a1781a14af74232c554a0f04b2edd01d8cfdbb868698505d1698b81932931eb9bc0d169a729b7c34b19b9c51d9fb994ae919b766d3a824925eeb1b4ac301d81caf39045d6142f29b00badcbba050df403e91ff2160153f43409f3ec133b48fce7c6066686f13eaffaed7150ee582983cc740e897c8d722ad3d09da1ba928549d3819d4e09a45c8758ae82dc7332ae0dfe681884d6e7a8c9072a396f681c48c8fe3ed068f5ddf0d79dca10cb1e7c604698c62c15b5d03e7542433b63dc4f71c3ccfa4c2455aab00b088907e977ac0b76ce348055dcb05571eee02f0e8dcf77a31c10699a6f579e05a8a61d25d0352f5ec9705ba7def6b0441c46d290e5e19a0c63dd449c24de254a7585192b512487bbca4b7a9b5172c32985d4123162b1f770ad7b7d038a7fd5bad3d1e8b3de5510dd25e97e7558bf6467409751f274db49cbcbeef267d140c01f217b3d50a64378c2621eb631e8e114db08723ef07ecd618d9ed0d05ab3230caad20ae26b317d0624c7bd72df5ac0d7f6db29ae769ecc9cfd65908a95c54fdcdf525ca32cef152e2852609e182b88fc1be59f23a5940e16b283d7e279b0a966e2b7dd2675b28dceca0e0faeee4546345781d2f1ad2db68accbe6bfdc8541b01e7dd716c52d4faebc6960c3e53506aa3029ca706106b4f09164353e36a64d077a063c371342a0b6cca04264ec002c4563f87dc8a994943b86dea7d777202fcb6f8483e093651c5263ea102cecf0bbbc316a1e0f7f942c3b429019909bea09369cd88e9c1b82ea10c26c2f3e19a8bd2acd6e67918b9003c268fbf87d11cab7f3a6886f4e6952faa78de7f85cf0ff1db425df2fc53c150e57c2c90adb5a7279d94b8fad0023e3a9a675e684aaf6a345e59873de6f3ba69d9600d70518046003116de8c1b754bf31eedbae101b1f23b2c01c966df26da7a54fe44f813f7ad6d7ee40848f910124fcfccf33660ec7a81a110e712cf171038510a61131d6590a31495c34b821a8a3c0d2a7ad63897202a34f27a6f2dc1d7a731fcdaff604e4caccb1f401ff71b4525db442d191d5057047241112fbaf0d7269221ba197404a5cdd4f433cf2fcf68e19349e33e6b055c8c0c4eb1181b2cbfb11011105c4d7ef94fb83ea5771d4903cc24738b68c2f328d7e0d272ca2715a1e71ab22ef700f52250de513aefbf957bd6658f62a5cf05b92e13e2e3a33c5f8e15fb129368dca1fad25cfdc9a0fe6d2aa74d3a2bebb47dd2497c2cdbdb9d9af39dbc0e6daad26424676d197cb1e162b18622dac57c2020b5e96208c04af3df5ccc858afd70a478ad7e5a2ce39f5ecc37d0b0d0389162590adda582d2814621c76c3869a7224e2cb6c7599abb78372ae11a7ad264d904c4bd8b4e9f08530d335038cb9756edb9148bad9584c3176aa1972390d5e0c491be68c917082b6c58209c649c9c9b60592739da034921be0efca14103e004da0b031fca54828d2c229b1b9033e45b539a8cc8e9c666fabb16712c4f9686cddad80c0ca6fd0ff32e13b224f235c688b41af097106c44294da7a75db85f6ab668ee0b9de68638023e0046c207fe5478d5f38b60ef22837c7bed82b6c79d0b14a095d9263015137751d361d638849f9297e56e4ff2c783829ce61b5283e56d4b7c0b2489073dbc080aaa7ce7dbed04035084122e61bc536a07e4ff73121fa58f4aa64d425bc8186029704e4929b831722d341a3d8505f754b3f1f3af38a98681ee5cb381057d8898fbc0f0c353d29f5f726445fcf999016e4bfe5a021ece2199b6262853c799f5e3052516a612b1ff1a605a4c816afc769e7c8a59920c4fbe6a0443630f1848efd0602a8082172ba99f37801a0c4eacddc55aee70d05ac74cde9eadabca5a265fa5abfda5e6986749f7c80e3920d0ac2ada5648235e96e5a78318839513692aad931d7750d7be6d4cdd7a0548e16f54031e67f8ece8962af76f710e02db7436ed653ab03137a6e5c0b567fb1bd8386a52b59610196d1cc55db698f62c51411ed03232d17fa82f98c86d260773ba4a56df38d140eca5fd6abac49419a4148555f314c647cb3e38d90d54d6bc36919e983ddb31731f9b349d4286d61b10faa3c09ce5375b4577e6c6938a495de54abdda28071306042eb149d9ee00b3ef61031f25e45d31653b90dff929e5f751d3b01cd18e89f88e60111cb30404c1a908e51b70f16edf8f14d9b7745c20b54f15b8e44a51dc5290943fd437b3214af3237d6b1bf75304b164083c5eca333c3663e9e2ce0f97e974d67e04f05019d505558cbd554183b08984d19d24bcc459673433ffedb30c5eab548ab9a027a51d1eaf944d8aaca8914926b4519c2f90896e1a2f8b0ac0e4754f8f6b44ecf9d61f67625a28562bb099a39a4ed8843c8d07744bc7dd5f075d16187610bb9129057ef4116437c6290da38bc04bf852c059f2d6f3743eb3752d2af5a5c4468a51a6382866982a102fe49e06b44e5eee53fdb4ce90343ffb091bfcb5353a4275d49399b2c84cb20a263529101781162c56418a54b639981cc120545642fa4d3330cd6ada5d91bd0b0a11034777331a3e3c63a5dbd6f6b2ea49a2daa94e029632c24451e9e6a2d0ea7c7ff16f1769e6696aa5b578fb036fbf2541352207a96835b13b5e783648fa8b6ce03052583d7d3729544366e20c700edebc05a114d9e08f5bd7bf64f05e996bc9bccd745134aff5f4f5d0f3cf70c9baf71f32b69f1b9a69ec207aa98681d0b824805f00bba5e67115ba33099f1bc59260c52de9d4486c4ca6522e367a8f4ee9647ef38ba0aaa296597f5141640ed73495ad1b8eb78e1a664a0a245817e30184c92e223a840e89391d6af74e132c6012265377a6b49fe91093318bac18552145675604397b0933b012091aca24bcc41ccf585c05fb7a29d17287c4aafd412bccac4272eaf4cf430fbba7556b2e0e3a8c89828bcbd28ebc9f17760cc75906a10f8ac7ec96053a7690a1e410a04659921a471e2a2783dbdacfe3091cf8c0878dd509324e695bec781f08782361292b9fbace4509f336b02b05c4b891f62791a428fa1fc4ded472785d9c6d6945a0b0979c189222ba2ec2ce994d1197dcced9607802038bfdeb0bad46a9bff6a3e16232058e6546ba5782aa10d05f86c333ffa2b35386aba225d030363b0c6748b09333667475a9854ea1a6ce7555f67ecfae7b657fb8e9cf1b841408ac49d575d554756cb0f5d2b819811b00ec9ba281f9ca58d407c6e0244520d0a2f7b347360c538c707f70eaa98cd7befff1b662a7e009ab31ef6e709684b6519c63da75886c93a51995ff9f7dd1483bc8cf0131d33ec8c9266c2c8ce81559103482785bbee9a6972ed67e8e78e0373cc7e49007ff695ce464b4542563dba183886507aeb5202a575bce1e2ea1fd3294c0c8eb150ae28fe24b8b494945ca11af36f41f0093e20f78e4ed5644f27edf12efac49e43c6e10aada83f5ef3c4b004fbeeaf64aadbdb07eb58ba2aaddf5dd37fa22134bc6915f3c579dc6d0ba814ed7cd66682dea5db75aae4b95b0b15989c4865e66f5b5e2658bfc255f11df503040ba6e87e964a60f6279415096f3ecfa745ae4e24816144607d5240ed54ce532697a197231dc3f1edec762cc7bc449eb9e819fbb45c0f3ba9014c666637695f8a9854aa4ed425f4d276d0ead6355ffb5cc59ce9cf2604de7b81da42386be1f1d57f7fc912dfec7482a0663211f7b9ff4886af9f187e0a54e2d251042b0f4281a255154aa467d7f1551df39bb8bbb3a03a83d81dc17a9f55c8d191ef2c288d7e3d1651571580ada8a5595219d25f5b97b6b0731cba474c453f250118ea458e989d56ead8655a225a043bb96e56bb9ee0078ee08a18807955b4713c9af56eec04a077b6f0c058d6d54ce896b870c9bcc0781019485cfa83537311fbbd0c484b35c72f3db283f91fe8fbbe0bda95f17ecdc59f77465704f582c61097399df877fa36a51452ea5d5e8b69f4eb3c07fb08419a0014fff3205edc9efa00893aa0bbc534746fdf668e2742d25c4fd7984529782f32f5056648aef048b3b9cbd9547e8fd67b10ed107db387e22bf128a941d067f68505657fa11d75f990ce9d9096aa2a1d717986ec22b4d0bee479d6db26ac1a4e8c8dfc82e4e3bb5e18173bf7ac3a0d4e06fc26d76d571b9a4cd37620383b523981ff41eb2a82e0b94dd1fa5150d57641911f73ba3db56b7dbff329914fd9ea8ce212d54d089c15ffa39747f76610d286a1e1c35d9c467c684fc60d94e013d4d3f0334e59c36f2f31b378bbc66f1771a4bb2588ea4c9ab892c805b1e84f7471cd9dcbf7dc75e21fb4ffff1f4b5c90c85c698a3d4da5705624e9f373bb74c0159dbdf270cec363f9dbd07cd45716bce3f5d5a1eb8df316dd059802fd09065557571140d9118568745520b996c0d60f07e2fa24358c3561f82631b9e8ae5dc500896c7c1f9990304a4e12e0125d03f335bb6d1c9fd67f10c8ec20308ad90b511ad19b853ced1002a291db4085c925af53f0698be1fb074e44a953e1c9a950ef169fb23fa34be22397d41f44f3a644c6867f21c28798134508e7f0b78c01fbce2bc466a360236ded6079dbf63d09c802204528309f37a3f20764ac6da87dfa4c32fb5e8cd73c7b0b893a5657137d1cf018e70eb203768a68786c95b2d0600980e8f104ffad2fa479e449dbe8a0540819f1d20a757b8578044c1744af80efa7af6af1044eaa1cdc51c04ed741e3f16ee836be35e763d26b41c1cd63a0612024b9f5a34279effe087a226fbb5567d4b1896c1c8ef20ff98c4241bfd68399408b2def493cc8ac985d810a0248540b8842f8f4947351b9a91ef609f43d4f3498335ff266d9549262f310f21ac62b563c4c4c8c9c020ab8287de4bb975f55797963160a23838a05a5f0c1cea3f0250ba86ca88284c8f20a65094327f29b0c6e1625d6da65d225b9e2b92d526451e0c0562f8573ba87ecd83e5496105c1a673910efb07ed060685be68cbf3a5de71d32c67ea9643b09b66a88ee4190af75464d03a0111db88081b2249b6e44b86a9db30e7bf138d3572c597b7c835cad6556100d04a114679cdb5a7027ba04a6f66a015a44affec7495611bc422f055a50fa2eb4f830f20f12cff0cc255b48dfeffdfbad9ff7d764cecbad14223682e489ebda2e34fee7b801cc8b3465bbef203f39a75ddb4c41c23a8e0087f55acbb73e4828a8f09d750148a4ed5bca2f36f41c014559d23d41108696221a13c4a83da920644d83783aefd3c1863c4a81b381ba3428b047fa9978b11f7511966d4aa045e772dadfb00590dd78f8bc0762640be862acc507e01d737729afc1c8e2e10fdb47086ca8407f045c7e3cd74f64192b03cdcce36658224ddee09fb01ec00112315d96ae9312506111adb8da90903c243cc2a176f788a1fe1215524c71a48a693061a25e70636cfed84c62c81731c5bb9184f434078fc7559b9ef77a1d8792a42311bc4291bb1bfcf012b9e8f482a14dd0802af159df062e6ba0e586669731db585809a038303a29f3d8ccd7e98a631027a62318a6f0db9018a7f05e36908cd8d0f45b4e9241dcdc0ede4a4232d8e02a61f47e8b4c3e5bae43661f7bec621012f0ce108be0438fb8b908017239c28996ffd137fb8e1b295207aff6b75698f957d17eb2d924025a7ff498e266269364dd55c350f7c280f42c0f42e88369118d622f1f7094e7cf84c63beef0640efb3437e3fd87f053ceda9017df9591de93226f559f37adee2be27bcd48c746690f130fa6cfe321b9b09a4c3427f07cb2d3e34c17b39507199dba1169f8fea2b17c3fe0db04e7958362d2b8d2e5733b1b9240672166cb411e390583ae118110011e83d18b5c97ba510a85686e52c802f32907fc48dd0473fe28bad5bb3e6596147b2f63e4b41d0460ece4fe2eb2fc539054bd7255cd2e55781460e1f96f80b10254277fd1582e3ae44b04f8a29cca9161d2d47984849acd241d8a57727c20648112a8661f014e1200e879d6a1c0d668df3293a483109e1e070157d37b88a6ce37ae29dcccf54bdb426decaa2c9c834f128fad491091646955768b83fb7a2c26e6e420a10462259c7b48d8c62081262131695179a9d9611bf176ea1e6904671eabe3215f4c7682bce998e4dcba7c902bbf43aa47aefcfb76ebfdd6be871c455ff620936e600c3ccd3a93385b0139e1b486dea1c9b8b4db9d1ada860848d001f26697a05da5e1dcf38d1628638adbef2eb6076f9fb2b4d67bc1ce7cb1b3a9163ffe37a124245f8bae6324b44854c3c8e8aa70b3fb50e81d57462cc6cd6a279baf898aae8894e684ce149a178701361da3823868d7cf0b5d8b82bde5552210aab1173b2634aee28e7d11452492d2d693900ab146152b9ecbdbb095105b3f111bc3e9c93046f66f44f9e32c1236042f52cf5caf0be09192d06f726e761ea1d6f1297c891a2d2f025052e95d568bf01379fa041ca9ae019b8f341363a097eedb3065869222f00b349b0273230bb35eee7bd49c2273d892724fdb55065ba26503a31e290f4a405ee7042c9b9fcbf1e81a03b30e17d524ff31f4c8b1124961ca56bc2f54a48dbebd965a68867a2298e39398646ef9a3410a4b4272f23c2a89e44c242315d13ba3b7961abbd5a04137411d648e184f29c2372038042d808333623785a9a2e3869952c434d8b5e9a50c4c92d14bdbf6408fb59784be046f06257dba3fd1df37b9d4765bab783003e1882ae8ed9314198380e587ea2bc06e5b729c8e00dbc82bbb1363835e48638074308353fc6711076b0d993b15f46132209b5060677b825a93462e9b9a031970383844d4ad307ee1c649ed193da31ca36a1c3cf170e64c9f726c26815ae610bcadbc34a2085948f14aa03161c09d8313939c1fe23c15e95147ae4a94b4789fd74c8e27c3b33c0c273c0fd4b996d02ba14be834e0c604108d809bbe6bc1d76be4b9d6dc266497ed7199d14b0d5865a4f58c7e7fa2f48c9f812bf7c60a4f7244033ca0234c08b33d823dcba68053d5c80468d5f7b463778af720ef9cd20689832c675ae0e93284af5d00dbca448579fe167d0b826ccdf23ffc5679b824b811d99c72a990e2409ce3224023d37e16211178d722cf9db8e071aaa27908c60353993d20975ee9939e97f2cf57f0d368367a45159f3d575e7965c0ae682de66b67a24301008d4e27e06d2c567f5b8c833e83190f3f867140906beb3bd7e0048ca0d5086c48228869f30b82923e59de1a6a220c83a9321828833a038a18bfb99012e5111c5229f5c883223b5f85654b43e4d382b71923a0f6d7dfd3c75698b80c2d34354e88d9ee251f6f942399094c1309809781410a718381f2e4283db668815582ca3daba05b73d8cdf62b5b8f58b79e9e9bd314efd13f54257f4dbeacbe0562b4cd64da0015dd5db95bcfb88535cc8f4e0b4c5068b394ff5424d9fd46dcbae73b3e86c8f9a5e9c2ba5f2af04bd6cc9239c45b4771b1ba65bc0a5dc128f7841b6e4319d8434783a00f83d75e6619026d523670e3161af4b69cda091b25e2db8ef5cc30b44d7bca03e876b03f4224aa0c79d89d2da0881ae6870855098a655a235b80b254e536f92fdfa0364ca03559dfbf0fc9c7f5d11116a259d5a6433b688b8b9d27dde43d9a8edb98333b5d104339a22ad57963f75cca3b8e784951e3f1c9d07b511c7e053e7aea1f6bb770fda04fc6e2c1a18fe84c16e89ea57f67569aa5eaa0f54f975d5c230bec375c4007e35264cb10e8a788256b1d674ac2392fa1528984db7c00e68b4184c6869b511c5bac7e54f6a8003b49fef04d0a7bd3b51f2323810a2299547dd54a9d4565adb4cd38132cae34128a150092c9ec4608c281129e811474a8ec086295fedb030b8a1dfec4dbeec738c9a3512e3c5968aa1b3722c72851b1993f420e783ff270ac442091fde685e4fef19f5ab47aa7405357ce13b47e2252cac7ae277e1ab180a7c43f3f37146c467a526f44a3224f8e9980b6542c88ef8de638802365106818d41f047676cd9df4e96d681f93084627f651946dccaa9860454323a1b6160426d994d38ca042dc804cecf186d6fcbd62370484ffc86069cada33ccbe436ea263ec00d316582ec4eaaf372402ffa15bb049b93b7d53fda560c782e98499fed60bd9e0e75feed4539e401b81e31a71ef15aff94b121ea25e4d57181a5272ed9c793670c7fb0bb402e75a10c51597dc65f79ca305d8d9541a33655e4b87440bbd5610648236ee019911e58c1605f46a6c82d6c14b8b022012d3a8b5c7358e752aa4f1e7a204ad6891ac4e3b25ccbd44d36241b97efdd7810dda59b0b6d6879ae2f170b9ccb4160bffa9b0ccaf7ec02001b9cc88d311fa30cfe85d58af994c1ec233eb59d6d4b0f18375e1729389a65b583a6451c51ebdf4cfaafd2b38b8cc6a27a66384c1333292c6799d34c22004f2d482890d86b271132a3df0c79ee16729713658332b38a3263e50df3bac8adf9c3259d4d86e0187348d26f455790e1008e60767290d5f71921461209f81f9be50f52ed8cd1986f115700b646294e720bc47f4181f421582db3848320bdcee5451c0a4213c3715c42e9097dd9715e6051dfedfb469ce663940f00a72c74d5d57f00b3cc09614946d1a2ad472f54aed56568bd2783e534d986dbbc85c4cfc03d808a9e03c4f6620e73182eb4aca724dcf0a7d641f4f848e0118d354d923c2a39b409e0f2ab8fd86afe8a1a7335c409a2a9c4471e6d1bbeb638d2133468341ff4799c1c35ce6ea882f92972ec373dd97a878bcfbbeaa7f16c1aed936c1c7dcf03afb0e78f2c574c5b9ceca69e591569b99db2b77711ff69b9b6ea4eec44d7d9a84a995d4972dc6bc503623f55bc1d0b8ae15aa00b38efb803e298319a5561a9acbb2bf434d58af4e5a29c8dbe6592843e350e51c0ce9d81c7685d67fc109ed8d27c02411bf78e098e1b10517ae3e870e58e8cb393b402f9098cacb87582f540c149c480b39d29f65be7bae37dc88f539d420253e734e94cfa4d0ea12825302eb5933de86e27796316a3201aee85a062143f935e5ce311a1d5d34d101c13f3f23112f25d50e791194c48f83839dd8b4825706fdfa7d5e06321e0cdb886ac5c109407160776b5318733d43c22aecd86514e91caaccc786efee8a500509718e13aa73815bb44c04ab52fca2231aeeaf4954fd5d193c4a21e99cbd71c989d969d8821fa7562b3ddaddcb4188b038b0bfd4f1bfccbf0a9d5fa9001f3fc548898ffc61e032e80f12c83805b396926c7c79c7719c098d01268155c2ddc0aa13c2242cc58d78e79a9f6325a23de85b531ade0e60c52bb4d4980ea1d5a2d66d359f9cb61047a4274848840e24e76b6fc8bbcdfba5cd2824dfe62c517aa39079817e28c06cdaf0bd372927da9017e98853eaa96f00db007bae79d6069ad5c5de6ea0275151ebc2b690949a92b49de8d2eb6715b2084810b44520bc98588450b795b8507c22404f0e7bb6f316bda2577bfd8e1759e1480c0fc2c6c80ccf59b37de0c0231c3526a415e489a0666dd7b5355dde700c5534faa29776625db4365ec75dce3e1edb8f08c330100b9cd605621134d017f85d886313b56ba8ea0dce2b73284356a1029ada29f43ca26d3bd02317ea40994bd42a5f226f8bd95319eab470d27e6c192edfe0d9b7c53f04d8bdf086fd506cf4fe9ef33bbf2bb420be9c0adda76a1e1d422840d79a25d780a750b7b26a65e8888b56b239e45576c0c7da35ade6311df2989dcb24d32a7aa00947be8a5189faec303f6912a55c42342f71fba4c7d15da7391f25521965e8e3ab638f5e9648a9a2c1037dd3186d1f6358abc3088cc77b7205269c58e77b09801957c7e08bfbcc9eeca37004e52c254fcc9afa75c398b1994d9c0a96e1d844d47739d3f4ff13629fe654f836b80118f85710f1617d0f872d47f24aa330dfae59b8ae2da340d56d543c9782a5f7bc86875125b2b0daeb2ed5afdae7615d5eb44c625aaf3ba48a57e8de4d70f07de4b0930798de79f65dff0bc666016596565cd95bbd1be2420070d6e6ac1b130f110d73fdb75798910415325057eca3abd807a227d55a1ebf07f8ecaa3ffd61ee36c6d77474735aa760e454cd3592573a254205fc92cfae4222b974bc6c054c2c701d572d950fdc55068bccac8d5ab610cc3eb831f2e52a4c52cb0c10d28df29888a722d1e0dab0dbd83c1fd119025685ed0ee57ee11df4620b0cb669b799658d61e15bf58e20a6e6f51f0da97b3f03a90140dbd5d4629693eef24ca1df7d05bc7e81e70488b025da71cabbd60756faa457897a6f701c42e8f33e5f45cf7f0726c3dd7200ba0c994787f78016070ca1c02012b1be172c9c8354518ebe03313d2ac307510e67fd81afd49ee795d99728618084156715fd060a8518599ff153e60d21a057838b3040c57980e126e7ffe8bb492218af6c2d1f58b9a62449f2beb5440820a12277f4cade8d7dcd747ecad043cc56e397e8715a688073cbc90bd051c94c274101b9ce0ffb4724f0924be4a8a0e3d5930ca1cc24cb3a5fb0ab1703f1e9fca4aca6d3b4a3251ee45fbaf486bb213fc93d072ca7526a9cbbfc149ac78c7b221fdadf6d9b150436ac2ea8cf423e7589f3ecbda04d20c9924de95912d8e332d2eafcbd4ea1517d8957e298dfb15f91c7f7d0786144fc15dcc4ecfe10c7f14b018c3a30c3f8960699e93be01839844b3cebd0e3716958be01ae3476b37bb5c7acaa4a402fcbaf9914b6d59cdb4f92622b84c4bc3d8a8a2111a7cbe2a8b2b42f11767f42ffe9cf8ea6cfe011b1dd0a62ae98b84fe0d1af2f1fd9418503626fd50cd888ea86717901d550724f4f03547cd02a879d9009048e22621ea4bacc0080788cc4f57e2b51e5dfd8e1bd7f6473fcdabc466f612ba2cffb701544856712198cdc5c3fa8856d61db32477c9af2e8906f2fce092e00cbe49d2c5aa1ea413f22c8bc6752124f60c50058e23cec06e9f7542645ff11289f35f610958da3659732c73b48c642eec1b6490950aea40f658c36d576cd2a9691abad3225a8e8e9405df56a8f3470e5b6cb5e0e979b43ab2263a61ac213ca1b112c5a5469d7080d9f0f5103dd1d65605538e3ef8aea1ce449602d916af1e447f24fda5939d4e39e77ad72aeeb712ab00f9f76f82df04897b35e26aa8d8eae1e6c95dc4a62701c205d81e359de0d9194a4b024ea4557e6da2c6c778eb7441cdaa2529d1812eb6053df42128f36142d0f7ff31b13afdd7cd3de82691ea542fb7bcaa06fe6b50824d16edde8e279ddd2444432840b0d0ad277793d6f5a584146246468d415ee9efd8692055140c24b024036a7a8065c27e87fdc6c4c4f899766359d29ace3d724d3066dd8486066772b070374206cec44396cffb3cee747454c749ecc0d986f6f36417a94793499584e8e7c350906e78d57934e2ad995f57bba778bc4b996eef51c0030fc6bc8565bcbb49912ac5a16004e5881e936d22e705efdcf44abb888abae0501f8c38f70db3f3d7bba80282cd29db2952c6ce2435ec5e6dc4beb081db8c1ab11e466d0995f66428492c09e86a849e601cc2c78944381093fbb4eb53c2dfb1b6134d86a095027c08137e90ba201f22a12ddc6c50da353178c1bec015c81a29ce38ec4198227ef91b9a53bf641afc2e67a2a9b6fd830493aa5b917c88e4059f63ce3d5c5024cee084cf12f05ccc0601122771b43b9ba64698236ff4e898acd4208a6bfbf3af8b6c9cd3102ac4f1f027a9f6854897ca1fb7151c9e7c4d065e8e6a900667d65f2b71940b835e23dafd5f3b84eb0248f47001aea0571d8cdb32606685111bbac51156161c27cb9e9150930611c57fe2fc63c53a32a0efe4200b00af0a8006ea4696c24255a3c07acb44bb01c519f1e25c76081bb1f312b02c60c3fc349ed3d488c59b463861a533355945f1b9196b84a83c2601cbf3cb03f32978816adae711a03de1171491f3453c52da1898786315b1b938ebc5b02137c2a600d63fb3f66b0aa05a390be045658f11c72a1573968dffdc2a79265824fd612cb87434618645f7daa7b80e97550901a492681b7007692e2e025587f81ff7bfb89c5031d6bdb206eaaf8c7ab9cacf5e4b6ff92fc161b772614a8d5894c53f4af00533d1a3b810a911fbae3cf45e388f6bbb8d70d0682c8279d68262d4c8a4d2a2e735029e13e0e919a5528135a250cf7a07a7d931b79d4822a01f6688324fe365fa6c8f0129f96df729097381d4b2b0d60bde52fb40a5f97f03394dea8449b02ef77ad89a5737a23cc6e42bb0e1fe262aab7ed44ef1474a2256d4f76aae4c1345c91ad5bd278569dcc1f925ed812680a2a7c659c13f004ac563d1d48229850a388574d091ca547db3b7742bac35ca39127420bd1abbbc086ba373263a4dcd1a92f86684c71eba6571807ec32510d90a6279bc8dc845c2d403564b44e9d5816d5e63df1e76bcb8895f2e5ae8fae42d157075a52c8dd9c6f8ecf568944f7701987cf31d26345918241f9ef328c4025e1dfea18f1286b945b7a91132b60b5214bf7e733f34ed2e0709a32c8a83432efbb6e09afbd392de02661078d9ba9bb2bcaf8e6afc3fbda3770d3123c5e27f90c5b4e881efe80eb480a6586479a8f45d4b615a84ca0f6f1e82bdc810425d02634ae00a7380c698562ecc664e58dd1648340195efdf0ce961461b3e8a25e7f6463656db7a0a66e94ce05006c62be19911faa632211e53ddc831f9ae67180aca43c71a588b98f3809b8e7c893bfd76f22a606e8c816b2b92216f23c49ac656a9481c5f2fc2b06862af02ca8142efcffdb33a0b0df63331c0e25105a8029ba009d4b20a2e53ab88490edd66f095a88a3ffa1013f215ed060b2a12b10b0bfed3ec79a53a769f5ba11e07b738b021a029594341f6f41b395bc7b317b97f500bc3b2d0901f42e0177da057d8f052ed04389f883177e6bd597835c6f340d8429cbfd6f85ee66345f22973fe5bf790abf0c1d484414001e18289cd8332735a3106f986ef020f91e03ad7663b9fd8c6de5c12d1a1537f1f234d42623f11c57986ea0335c84a1a58fb31275598e2fca81d226dd63643f0e13a6fbe63601334c94a1721023ac2ccac8813609c640d556732deee0e2e2dbbb4585b56277741cad7727bb66ab408ad2ed5e9a15e51631a1c517d27867fa399a7b514fcc7e93a7ef7d878bb5e2c4e261971db579f594127051f29f751f4bcdabfe9a8238d007371b601172221938ca4d9cd7961d7103e5370f73dac1fd5b908241735059250b2e1f828d2bfa9fab51f9bc06647c0737d04942a24a85bc77f7782f08f3e5bc5de22f5b99f8cf16b68dcb891724141b19e7927e99ccd12419db142db070f33399f708da368747490753834c963bb589e2fcc434318e3a147cbd46ba79890c85c6e57618a5e3a10e32842a47b059e349e3e13f24d9e15b07b85acdf1fa79eb0a22740cdf6afeb2776a403739a6451fcaf0eda25256829e88e7aff6b2956092bfba1955f0df00f1e6bbe9e252972c85f43119f863ec9f7155194675611294c54ed19524bc8862fd113289f239df2e17811a8b9d1eccd4db92ad26c51aa57a94f8eb478b5e297414263754f23d07ca9294ddb909b727c6145a4c59bb5da47c9de3e923f32a7cb2c04d76f4634f89084d4d97f84f93a2456f1407cbe05ea504e588056cc89ef16b1b84c322e64d4d1de6a1713f5bfef88278b52d73a6590e660808095ea78618c3dbfa2b40b12d2ede531f83cd63fc938c8857a3441b4d6fe4a6a0948b2226e4de67b48fca714a042c6449e16e1b4b9181ac3f0b65c62b78055ea03f788e1b278051725e37c75a951c1aa7cc4a7100def618eeaad8c744e62cd1083521f2a5af2e2a775c7f71c393b402d5e00b29cac048e4bc8116f70acbfa0e729f083cf4109b5b5f26bd008b37c3deaca63ddf4099158c6f595ffa2f12bec1253821c6c18e43509b77c1b33fcd089343eb0a0596408cb64445b4eab756fc1fb2b91a571c8e0a93c996239c1677689748f13d476eea48ec0a845949660af07db69c84c236155551a4357d801eb55dd2a82e7483fd11b2b2d4e973cd6c6b4266fc5eab32fe900c0e89095ff4128e24a9d829cb5149d3efb89d2ec48f771aa10c18fcc11c5592be580c60e5fdb9b36e899176caff09624a00e1f851bba8f9d364fb79427fb5dcfc28668d38ac344cd83ee6e02d92730a2d7f87425005457a65c4479afb94d8c324e27e5d292db7e01af5f192d8ea0b6ea10db8070dc21f7b9652987fb651e5e7bbacc93c69f0a726334850cfc9b0b30f28a1b3a78ad1cb333a297ac023b2e82e34a88b2a53a41beab3e7a5d2a95519e75ecff225c88464638c9a66efc1092398c0681425979c3e5384afd632446c1a0a340b72305ec945c621c2346c8e01324ed7b506fe890c9f65d1211cf0e7c7c07258161fe99f6a620ed23c6a5b1142f1a7dd809d93e5156e198ebd365158eb9fcb72ab9ba55bb01c1c99f24e501d10c50f7876bedd4c4dd2410ada7307c62962f19913fd0bb13ad8c150b0714f0e6055695ce94b3725c148e43f15d64bd1e258f3c8fcd83e9f6b52231637aa5de658824bf6b4e3a03cd39f5e75e77457ad23c2ea955998033aba502f6f50ed9c14c80947d2c99340e3553d403954d41497ba99f14fa67a30cc1b1992c8dd794bc4aac4db3c88353404de1d687cfc33520a2026dba063a871a018c8b410acf7a6e6c75c81b3f980d3c0f9b3bc726671c43de8ae0128e6bad77c1c452170386112580643da2a6f0e333ca23c709112d7b36211087c1d6f43e94e796a43e3d3b2094f1b57c34bd43d634b7acc373802c28f42498ab5386ca49adb64d22cc2d92d1a950780525c890c0c2d98c15ecabcbe87e2ad4b7af6959fddbee7490156bf0b126575ad452b211c69cf1b3d22e979e8cabd8eb2effebd7d32a70d591282c87311e03f8bab8003ad663de3ddc616234c83e2643e6b884f0ac76091620a18f97ea51af6812053bf6867e52197827c7f4b4999156e15833c5178a5e91c82658eb34189707a060a0d86e0d7e0674e1d8e89a00f6b9410cfdb2555644fdc02af82a5c863e35ef4ad548fa12764a8e01a0e59b65448d91df6347eaea01ec7caa241496476fba1c9b15613370a886c4001b85c6a450e95270da63616bff6d55c0ec74bfdd438f5bf7b1b554270a6864f2a3c06318677119b66651d69d62cde8e2c93d04061458b92ae57686885a688ea609b1821e06cb8e0d497c0f874daeca6255ad08064d7e7b667cd3ef3aeaaa33b97d7739c2cc2c6cc3ea3b34af82524f236cd9cffc8704190976fd30bdb185433fae5f1d4e8ba05a9463a75c5903ca3c29beba63c23ce224193619469bd05f81ea3e08f7e9990a7fccf329b64b49a4e25387cc32efcac522d9538d4c605911784ee0e08141a6f5e8689a3729ae76571dae53a539ad5ae36509bd906d875d0fbce18829f838890749c4752174ad4c7280e32319f1416b4768181fa0e479c673526dea1b2bc586fd70b506cbc249dae0a1353de4f40669d1e6505f5470701d9d242a3db465a786f37f5bdfc91100f89f262fd1d19d9104b0a80f86ded92b02a8f23f420d91fcfbed4f0c32e43571c7684591e9213aecad94818e66602a5aa2031b734a1ed2d8c8034a6def82b684123482e11307edc916aece91d4c20120386a348b266252a0498bcb92e471ec3cc7e5a8e7671c813122598cd09be867f73a7b681ee410c05825d9c32ca93959e831db4185284a2b9b1bf774465664a30768183f8dc687860adf13cff5b8020cbc7fae4f00baf60edadb86c1d3372b7d83a4b53415248c1ed6ecf419d61336146440a732881241e0ac674b6c4726ec443202f344d516d6059eb612708907232c65211ff4b3c9e52c9f544f21c569dad213242e57892bbf1f5f86ee8aefba8dd7077b724b341d2bbfaf5b8209800ba41741bbf0eabf458d8b1b48328d50d6c0490b5435f58ded252ac85ddb18cf8229f08b9a3e04b0b90e3fd0c11dafc210b6fb1deb09e072f3535289e10b52e56332c2a9b16852d009d0bcd000559445f4808f3206fe66a5dcc1406eb39b6eae2befd8ae23deb7ae1e911049a52950e54c1e020fc3040a89875065493d5e81f2671f9cc6f41110f66508930bbe152ea9940fca9f26d2e0d4bf2f08893b487dceb594fe6c1f1f6dad3c3d4ac41f570751e7a34d33511295ac875a24dd761c0df5891160ab3c28ccd77afed488ad6e657330a18570f07eed42f5d4e96af3c9c372940588778d98f76250646b64f80a16e53028d92d8bd0a4db872e203d2aefe1d23d9ca41c24a76de63be75f22c22c0bde8d2de46347b2d829621c85b3d724ff2dd992c33593c905d863d8d0f5bb2ca6a28b632d54eac858c4dcdb1b3e556bd449d158acb242e610b4dfbfe2d2e0a9442598c9f3d7d59e5c51dadaf9d6e9a9ef279da9311c14b98450f4e1a160f6a47dfd8255606b6b7686ed3d3f9833791ff4cd2812f43069edc38c7321349426b8456c534fa35cbccdf88167d3a0ad1a31f1c70d9ae3b40dff7d7a354c2e437caef9ee76740095dc9013af3e9222cea645640d5d60fddd5cf4935301225462fadc9684433cca611b7bb1f1a1314e8f467a936ec632a3e58e42253227a1a0f69d38b69298d50cef07616ae0fd57b8d2806385044cb64afa658754350b08f8b82508b89939f2d9f13c00c071195b33370917dd2fb0813faa81d2b49d56cbdeeffc1fe0d19d148cfbbe53efceee1427e9e386d8b62fc0b6ac79a7feabe644a0703bd672bc1f7b697460bfad260b27243648185936ffcc7f515ca4911c8a3545e736d0b3dd750030b65153225b3f3449bbb7e1e5c1d5e5d224560b9d63abca545b163b80bd61966d9128555df5ac7fec8fcae1ce5b7d05c3d10471944a4532dd765964c9259286e08af1b05cb4832996d235e3581181d5ecc5506add44cbdf344cdab062539bc8b3e125a82b494d0d9ecae61c480ac71e84614572297c2015b0b4a5fa6e39baaaeb4ce1b8049a5b6c8d8fdcba3c8afdef451d01b4c2aa38cb0adbdd14a4b3e7d0143e1f3bb3bafea23daad1af464626d6a7f242dbc81712eff9684c82b879f550b0211ef703723e2a24f66a2bb0bcfbe33bd8f557f93b8dece71d7cae763f572e26fda2f8e1ae4a3d359ed9ae244dc1ca74ebc95be009e18492b15f68e3533e472a1e4742ae064f0625f7fc8b53929aa7d9bca6788f70479fc051c984d75a70a0a9033af0d2252f188302e630b6ebb349b25942da3344cb2fdb66c87c1ceb93da6afe614bd0ba060f52f65702a8f8fb42a6b95311e13c159c2f1ff02723ebe8a6442c732788b9d12fcffc495ddaaa9e482a38c170c0e52ad91982129712ce64a89b2241d9690cae5dbe3dfeaa65d0bf87e1f26115abf7fca85a0db6bade8ac694b6bd942f127fbeb169f581c37359f74dfa7b94e48e40d74fd796808266936f3243a187c5ef3e54939806739ead2acec945970036987998364c08d3f29beb3128aaa5e986ab0f3a59f62785a02795b969b21d39b3a072db987569ef72ffeed9240bb42e81e55e29325dc4e29d3a387aab25597382dbda85d7da8b64c9a51d0d13e794a3379a3ecbfdbc889ee9e4198403147652029db48400b4a1753a0c14406fdfd42e2896588d99315a78cd2f80f3293f212ccab6a5063f6755f556e40dc448730f5797176ec0735b2a8350a6df1790a352db74fb3e4c0fc25a9ceb2e4612ff9ae5a30f3f5ad1a3003a9b3808007455766b34229a17aa9f6f2543853e6f2d0d87bb1241643e2e2a5acc028a994b2b20ec252a29e3d246188f6c861b828e3a7127218f964b44d39436c499c10b801dcfc872c8e5368bbb99f985e4058437b97ca203c76b20de2d30b463bfbe75a7d4feceba4caaffa2cde9a2fa0e67f1af6572df1dc16327884a48d26a7f6c270445c505306373449b747b15b195a2768f47a8d792342aa7ee36f2520459cf68157441956f600f60685de840216168be1d5b2f48641d7a17e32761e0e4c944efd8038725bceb89c10d9a959b81ec36cc82d1c0c843595e0f70d2e071aa0b2b290fb8554c0957311c576ee4639ed951dc6ed9afecd07490956a7d616deb6e0e57311793ccb870f92a987f9eb80d94d5475e88669db49c1bcc469b73816a4b0c1c959443f5a5beff350ba3b7c1911b4fba2a64b195ef802cf899d5f1fda920bfa9eb77e0afcaf98d690b4ade740a282780399b8652ec1071c4c097c93a776572e790b27ce9b0f0baac1e48c822983511d07ce3704cf59b0024c323a649f8962ab6f319da2c2ec17dadf2bac9b93bf6809a15fcde3f99a9442c47d060b699030bef55c1db60f043ce7d7e116780dc59ad203d1ed51a49458a811b68f9063218e0814b16bd30d9947e490c3c15efbc4331c095b505eb1d3152470a89861ee9605c9292f4ee481f2eb0a0f14b20008f094cecc462f1d3635525a85b12d5200406f79476004aa8087369e06b85627b0162bdaa9dfedd5279f7c5ac68cfe7ab84a03a7ab6ad47ae1f0eae289739f39228b3fa5eb6dc39b61335d3331d9fc0c41232ffe06dbee4f1455ec3c937c1b7cbce12a649b8e9cf85e5cc28c758b4f484c6d11b7625d47513a8f604888ba16abbc4ede4d6bdc3cb3afcb9552a100a90520c27379a6e5850d240f8023e30ab18c1d8569c5e71dadff5af2152600f09289c2a847daa7751b628fe7459df3d853b6ca14ed0d92a3bf7cee0fd85a21e24a2f48ac552ed3874000bc0c454f60a8fd9c61bc0a0dded2bad820e4f895844b6bfe056dffeab1322a4c6c2f36835661aa1dc2b1f22c2d951452800250587a0f8bbab066c5c8400ac3faca9a80c9c7e9c9b9770406a603dc4a65351605f77cf3133d30532b031e43a1fcf8ca8b0d971422fb129e737b804be3c8674421c8926c23f60ed99a8c5b9176705ca7296659ac979d486d4b0e1232a232688dd232a2185c7fde2cf3c5872747e8bf4ca6372b4511663af48d9c8803b4f5936ffa376fc0608b0c38b898af97ba0e61e5821088e1949d277c4d20db69d2abcce0857875d5658772e94b98d477ea616aaef0a496d8e60f6112a7c857823f7ce080321fe41a02f0a27ca95cb0dde24a34ee5c8e6fbc2e5c230b717e47b38b785ab59a1d2406ed664e8c91c930e78090f9e966bc4400b391537c64fc3dc5c6f38243ebc08e83fd0a2f24e119d167c41349a501cf5a110217b6d860a40bb490150e8fc2dc716b0e6ba6fe99254ca1f480c4af56a2963c79e394017940eafd54473b25d09e80ee32070193f63ec4ac59933237b8515a5c638b48731612ec15a3319ef1cec22ff3e7270e86fa734e5414d7e85e3cffdaffbdb6cda0207c5c6ac44beb5fa359d36286817e25aba0a4e47a63305eab4990d1c38615b165eb5e54a7a737fb7a21f60f777d71daee59a8e5c4077cb97b4d9f0aa93bfd9b76f5cdc4d1f84b4950d908135dedd1237b73643dc0fec6c9702819b9f5804759891086303890ef508ac8e3605c8bfe92d6301a622e9526b652d7c09dfc5d9b9c56e209a54c687406e4808539cf9bbd188858c34b4fba53797ba44d140ba85bf592dbcccaf4f44f0166b70404061bc2e31ffbe3fd126c03bdbdf0f69dcacdf88df8bce74da195ae0f31f8a52ea807f61861d32ab045f65f1591387c050b4603032243c5b465dd1fde7e643f502feca3b6b20b16023c00029e498655e46ccc48bf8c837b9581226c36217820e0170f66bf58575174766698cf5c9e95ebee1eba16dcfa304005e2c41b32d07cb7ebc5aeb42c2957cfa75277b981b32d5eabee666769051142ba5ecf42ddf4db3ec719b0fad79c33fd32abb19f1dea4fa49bcf2eeddee43a7ee43dbe7282c111727f9c6a6f365203bfb100c8bb9cbf8ba1f9246b8562d22948cd9919732d431744b24a92a09d233a7c39ec87c4a5e8d4d6e7f9a9ebe6bf79d38e9c65ac39f4665ba10c6bc41a7045304e680d42f2050e3618196fc258cbd43f59209e5fa97317de5f322e4bad1f8f0666010f4e9c8abf0d22c91e41dfa7beb36d40fdb101ae2a2d4614c226c10d585607ebf46636c7704570512fcfa738bd91f4fd01acbebf41dcf23ca2b7a8bab3238ee422b85eb192d867c2ef94d167391ca12a8ed84777f26324153e240cb363a91409b3ab752667091601649e5df0e73b20b4841750beb78e3d56ff00200d352ba0794f9c3f7cc3359a0b3b1b08f7ae9fd548350573ccf35330bf0fce8d80d87751dc7541de54037e6ae6eade8620fc8721b188a38c6cf24ae5cf49165d265739d12258deaebe52182115508e2a14d3006796ee01bb4ca92a44985ecd9fdda3281a2e6a6117ea35cce6d3e4c212596696d99e47a04c97a3353789ce8d58e613019b1760f2a52edc1d47aec4509ea3340ec626fa4b38fdd8b74381dc841c51d4c3dbb8feb9a4e712e3a4d9c98a7739ae1c30438767176cca1920adceb4f3982766344d452fe775b1577ec18eeaf2e087a86bfd2fd974fe7205972eec76e05fb5c97d5ef96574a141a2d8174d4836948f48164a6922b7e4c8ab056c075c65a7deb99068fb7ec996e17a55c7729aa29452e1e0b8cab106d8eb9b162e1a8830d91c0988c9a60ebabef5a8e685dae3b32a86bec558f97f7dd987f71db84d8da1ae289fb7dae4b1a53d8b113e12db4293631ad19e84dff3332b12e3a04331a8b3584bbbce6260df9a7d8662a62420d5aa189e190bc17aa1a18963a3a3adfe964929afcc0390a8c331b057f85b43fad852b10bd68b92d42bf49a553c44127bfcd810a3ba4626626707b9e4b55105ebf4a2a4cebe040604584386854360d2857028e2ef00d458bcd24d7f167fdc2505346461c998644d9216e08893cf5b62df409e2955a50a9e30fc99ca80859843bc29aec71a9e21b9f930dbbce98ae40e1def1b71e6d08627f33c0292b5c6bccb64bb415d9b56fcda6dc013cd4f9593c0b42047bfde33acd32754381035a40a1e7b5582943c474681bafc8b3fc3ef8d93b97090174941590ed94e1c921e3f0ee72c962e526d93ff088b080c60256e84d9db7c49fd9e81736c97f2942598ee76c1d0f0abbe6aae3965a57b9aa079fa93bf3e1366d2b4e6d1e1b0a09897a97e0c1f15d74bb318bdfd41d031e45644f82c23a6a47a7bd2f296a0c3e2d25cfac856530f6042834c1f9878a3c46f6eb45dcd08b018d5dfe0f1510f030813fb97b9902c2977c59c4e3b76224fdb54a1b7607e30d82c41577c6c6a0154494b5fd749efbca0c34bfb9c13b9dd65afff85ec50044939f67ea12074beb5d484fd465e118ed4104a3f6aad72f01614df26e3ded459d986e4cc38d3986848b9a132aea21a2dbbc32df999a8cd6062c67f9b34a8dd226e087c10ed8934834f9915e5a587d2b67e4e5c9b749f9a6d7a8e02cdb95444c85d1c5332ae60924466fae92b6158ed4b04a5ad3463795a790293bbfc7c2a5690a4629bdcb02145cf9c78002e15220696d455d7150e158456811ed7f9275c574541abe228fe825f8c90b623a94d813906448c97ac4abad8890b9f27c274678be58412a0d683efe8c4ce09085af94db47b3bd72e37f94260ab081dbdfdb8ab18f7f469f08bdd485172c08148da59d4544499e05dabd69b1b1d18f8ca5494b6e97c41a1bfa6bf232f4dc2e09d3d8e7f426df868ef1a5fac0e93e8920bdf9af51ffaa7d73b42db74b8235f68a7efaa32890ac3f8a3e708d3a4968b13bfa58205df60d3ee0316e93488d7dbe786641045d298b9dd8302db14369ab74cecde6af0383e9e9b12fda57fae85b38793d1299b1a75dd62b3d752d1cbc3e12b6d817fde681891f4213e137488c31b6c5004f416b88f082884c6b29b279dd24a688ad1a4857b92a5a9d1ac76e436438385d245e6c173aeb41a1e6861c8f859ed34d428fcd7d6c6aedd07a35b61bc5ab8dffec3ef43bbb3efdad452a23e95ff66ffde8b475f414004d18365d2ecfeed76c98e903fee88d45483ec0c99e280d1a383ef9b5ec60e818025d5f55470f063d07bb656a9e4f81fbceaffa86b7ed8cdcd379cd7a856b41d6070a7ab2333d18031ff2282761c33dbf891b79249a374f34c1ff59c730324b45fa0013157e69fb05f645f86010184d625d487e7f046873540b32dce46bc184f106a9afa3fc17130d2c2e48b298049c34ba82fcda85ea082210270d94583962e30280af5fe16dfa9b2df15fdec02f1940b287105c9b6b392adedc59b0985b2c30baafe3c5639a5516276be305b8a954e0e21e410acda156749a4902a36f49bcd5759203477d3e323d5e3c9fa9ab6f720ae06479194d586baf82763dfae4242f6e920a2221bc2293fe7e18ed572c2632dfb5b6a7bebe84bdb3745206817c23182e4704c9bc6905b4be3356ebc060d21ba0b5a91411dc2cfd1a99d87720c2c9938daa148d4a8414a43778cb9236334bb552272b0ff080e7814be5d8dfd3a13510131fb47488fd7b8c22dae52f4706d1326d58ea1664f2c48d86122df07e2c588d7fab992a83544916b3da79fd1fc1e2f3d25c4ee9ef711e8c7ec50b3cabc1e5acd82cbfc8cac444d7eec27ddf240b57f4da21c16294e5dd5b7898ef90ac302d19be5ed325916291b6a8e0b6b93dcee7517fdacdca2d4eb6bcd51c432ffb7e4ce6a5518fc7c7cb7796deefc2f292b6c5a6a6b5f5bba9a7294db11c74c005d222932219bdaa970b64ef8b6b6ad4d35b0257aba93d3aec800460280abe3befaf8ec1dbfbfbac1e04c9de0c1aceb4fe0db3c2023fc626f013526a9202af6493ffc747c41f983667987dd4e1842e98b2a3238b5bf91d86b76649bf0ba048b8b2b1424af7dcda814de674b971dc21660db3d043b86cbba8dcf8165ea1287ecd4bbbd7fa9bb77158c51fa382dab64e7218cf535d79c60a8c3938918685696c9e32ee72c632eed494292a42cd7f4778e19a1a5ec618eec9b537f8c4b70ff46d378d34b77b1a345496709149a902a505213f10630209055ec17f83fdc6293eb8a99cbf85db0337c805d85c1e27f98facd03cce18ca31805b4ee61bd19cc7f8fc1848e0b0b0c53ded5155ed3380558c478462cdff8dd2ee5a19f52ef90e49afe65eff7bf939afee03152d2a8262e87b08b6ae92d04bf41d586fb06c3e4aef1ff106c6dee44abd289acd87fae293602230764e91870827332cf203ae368b4c82e9ca29344ecd9d738e88d681d3b21de62ab68318284e196fe2440bf835338668486030da94c69ec2ab1e9e8ed9add49529cdd84ef3e145331d4ccf3c9328b31e0195d718a3b8afe4badab66f66bd3f63ef1a870170c11750c9c5406e0f3e06de1e34a8d63d1747d1fbdae6b9e2c23328a4478304c789f21ece2f230e930fc47a7dba69063f65cee54375688bb145fa008a0fbfb26a74dadca68883ff76ddc3d768407bffcc7f28ded5ba711a4b2dd27c6de652e3dc4eb27ecbd1feb4346bc7d306be9d1ff04e48f337cd470a7a94e77530edf0934f60faf1106fe62c79bb0463654e0dc1127e61bd2207accfbf99cdb05d443e6afa74adc82e76ae804ed2990ae8ece60aa76b4b85fbbc5565455e1e301550953477b64744da9486f151c45b414b161ba41fce8907c9b306939cfa2d8f0929ef3c2c2e212be3b9fc3fc55392cc19ff81e41585eeb7db8352c38c1ec4bea21d1bbaf24ea6bce2eb970e12f7ecf13d3c996c5e6f99dfa2d5b22d532e5d4b12bc0442c47578e1e2b934532582c24f8c85f4deced847a0b0bf33b3c8901199f6b2021061b3020327fc21b8d81c83b0113a3344de88789c8191890774722f0203935b54268a64f3ac383f0c0e790e72794862866f8e5c10a507ced946002f618add8ad7347df99c6047d281a109f07a0123e9e0c0cf01d0aae6580916d698e807c10beb453a443ab1879ed5a5060a00a0225c38e83d1c1212a93e48fc021cc4623dce6983c4c70a3094b3c480f4651af7929533c03ffb679b05a8c13c6aa2513d73c101e6c933d8ba1a43ff7c582d7990bc84ddafb81b9a48bc69ff2ec853baa0ed16dce3fff203ed7b15fcbd947939a61d4dad78a20c9b841481fabc3e8fcc511741a92ca635f7178f722537a4527a8d485702bebc2e4df2744291421b85aa1f7c343f19d06728c1150b5a316f8cad2dbac60c9575a8013c1d8bf9d4f1816ca4535de716f7b00c8dec41049561217117e34160b03b0a26ea12bfbb41d8f09db3c20ff65db867599f8edf73ab143849ee2150849e977b511aa2722b59865e3464e7a80af5a366eef975c78fc85ab252ff9f38c77e3b22ca9279dce0ad5876147fbc1406fdc29bd6d26a60617a1c6244c7266af43d7652f1ec0a1c1b5b428fc4e939a2b981bd00aaee7711cb67423e8f65949359016b936b33cef4f43eb0baa7278b029387acedf5f9f1351f772d33651cf2a1da2fc1034152085c94a81598b64f782d021d1335209f3806f487e33ed13dff28ebd65956e655e9dd44604a4bad45cee308470ffaaa9459cf7368d1f67eb424f5e9ce1962d8301fad9da119e43756c8177c10db07970f275570e1bec6fe9f7df0a8d214d436b12dad0345442736b0ec104e835a4b06b8a7e3b7a15820fbf45e3da6b60049e827d34352c8aa71d3ab3297680ba5aa09ab031879d4d6c03a8c75f84bcba3a5d6537347e2af668461f8003dcf3a0c95112ecc22a49e781af070e1a1ce89904a607e4568b050be0bd78d02260c934e77d1f680f575f82629846357d7583908b033f4cb46c7b245e4124bd26b25e1d5e74e855a56e9e30f98d1baa7bcc2b16bf9d317723e6b6e0058a03f95f1c083e05eed7287ac23634b81f7f1d3b642faa10dd5d43b4945af5aad79f98ab15685a19d54e40fa8c529c23d2e17e71c1c159bc55caea27d0631cc79762b70f27019abe27a154964278e634593631b49687533698d557316c46fec5fc79262118e29e7d556473d5d2fde816bc9b1c6429277806306d9a02208adbdd5f1473ce99eb81c27a4859d630d03d4ac8b0eb64d407e3174ed4b261a006e64f1d49632fadd72cbbc88d848988d16e53680204e7f43568de39f06b20528fcd7da52088cd28caf178dff02b719e312b46e3eca2c06f24d205d3ce45794b62a6015c1273df9dcacf8237d72c38049ff10894953b27156c0bb2d68d49d9ebbe20aed754b4e30afbe8c68b33614cfa7124a3ce993c5464ffe9f60eb400e2fa822933eab8db1f4d0a46081f21d66e05c3bf65d9f2bd352e8c8e787fed74b3aa75468bfceccf2151e8aa37b7e90a1249f196f8839636e9df6a25e4f0c111e28d5998dddaa295b34e906361ad4390d1cd17a7140f53bd59e4a0bf33052a662247ff254f0fdd50ca909871bbf91e93711b9681cee4421e09cf5db6be0877d2d127dc74d7e6a4689e86dcb28acd1ea685507aae23d89f617e2c3f32edf0431fbaa8e19911ed42d770134d5d9718b34c277fd6b185c1195d252245295c60ac193d4a14be5b15c4dafc39109b3cfaadca2fa89bf83aa1239d48c01ff1cd3fc93a0237e539421af38ecd238c31a45a5ecd81e153eb8dacf3343d22c9bf9c94753ea34ade8b49db1b68b4499dc292ffc35d65d83bda28756ba560f314caffe6adf0840008797a309d73c115b52b85d942aeb473412c5748a7c5e4a51adab2ce5d6b838e8365cae899997fd9cc5a14ca185283bc7582b86618a4051c804d0bc1e9daf5d6c5d2e5878aa677158e39fd2d19d44b80123a5f5ed884218e96c0ca1de5ac7d030065a12be4e3982371d071fdf2761059c1a63eb9c803a2fed5f4ecc74cebdf4e18c8a7a386d2b20262edef485d667040515d51af86490a389e6d42769c7a9e2cff44ae754de7e96f49687758b98b1970f1075a1716ae438b08a16738dacbd81937f6a27988ef6913e8c1f8e6aecf1d57633a5c4b2bdcf811486160c4d539e48ed8c8713900b09a0d38619a2c9b06c44508da2ee5a412df77521808ecd205f135ed33d4228ea00d598a3c99d4cae2893a3e759569a4b996fa32ebe0b2f345445898561fe0d4c7c523a48512bdb633b3d802727ce8c964d9141e19f3b1f517ff912ab27e0fa80d0f960073e269b3ddcdada09bf3370d0d30e12fce6c179444eb9caad2e7feef403def77b5f6ee40d163261c4597d7ffbc9ec94223ee5cad644cbcc3306ed3c934629d76bc10b366678905da6034a11b463c01d9536b0401ab4aa14dac8cb68416374796aaf54099d52da233d6ca93113bf5256ec1de1080387d04177ebe63f0242d14641734d7d30cc9331f3fd8062b9122c96aa7f5197963f2e4a499687acea058604826f17fa47afbe725e8eece64301c6952be53edf96e910a12bf305d86d4259651193462636995e9d865c6bebae0212632c43d3306562ddaa5375f2cdc8a9d1ea318029f98b661f86af449a229ab808e26be38c0cd2ecab2e2e30b4e7fc7f8f4b00ecdbdd7f22b8c3bf1cfc48948575b08304ff9afcb491691a1e7bfaf6df2f4f9a693e0f134bd666ca6465b27dd92131667c67b0694e6d2b9556f555cc7b8a1be3f52f207562c86b69326fbd2d23e49ad2707451b07f3c1d9dcefc16990a60a8d574eba00178a206e9cd1677008e16f54a58006e505488d51b19f60fc16a72e64ffde13f2bfcaac591fe80eda118f5a06e3eab9a72f90807a4265841f94349664cdcd23706917cff3b69ba439ce008338f268c1b9427879d01e2d3c34d7fd8709018128dbcf933af4032284587a838c14198f31bc6a680bcd55648d84a0be68c46c53de37ab7530743443b6f80ea472a6736b4ffdc56f1d9eaf63b248183401fcff3427ac19f520897cf1ec22884bc1c2f38872a379d076691a1beb2be6f874782048db2efb52225f5664082ed072f8c0728a95435bf1db580f01c4a6a3cdefd28a97e5003ae461becafbc7040df929b8f363025910241415c4ead5f0112a627140405ce5c3a9d08562555995fcd94542e6282cabf34a28f3812bbaeaf960b3b0194701d924abda71c0a43912b4ac1ef3eb9ad29bb7b0eee1252b818b0a90f92a4400c58b100be092ec8b557287b4908e3f475c591cb02e9a2fb8c7179d35220e040f9d1282b955b72e9e4960bdc1e85a8953c3e3ad4d47745e07eff4041a9430814d59047f1b2a55f3f65d7666e5b5cbc5993e97cd0a96245462dff38d31c2935b780c15868bf08a936771ab37c082a8fc7065102080065f022f06fddd807dfd63e33707e086ff489f4bc2ab3b6b9268d5c47aee46c1624fdafc6d164933dc97cea8b0991403ebbf0d67b9ece8dc762f6b702e1343ec9d8a6b8f8efb446ac1357956ebad6cdc9bedefb51750c4799ced6abf42334a5d726f841d89f8ad43db8bc20eec99038fb2f154f5ca3e854b7b25c904a7f5f813c51cae6de6f836f0b638bf6233c6eb294160ef75b415903d7085e21abcf9ce178527b241591d849b9ea520c4b78f71012a1dc9c722c23fb74583435f5dfb9d561fb08877846701e05984a35f443249fc8078ea2c5dd446be1a0178a3994263d9abdb935b59e025ec26080f768989eab04067bf5e04d1aa0bac0360c26ea1d4e2ab89f7d99344558bd1c016a23f7f22e7c0003bb0391008cc4e53c0315a032d926ff37f6fe97a95647b749876b25f5ff07b7e813257144c3c757180f2728ad6fca690be1c730fd5a5d6e7747aeddf35ed39c47a2e761c57fdf052354bba711e31f6752e3794e3bae0b2897056f59b679fb10919db95138480571b95aa60ccf8bd4f0da75e4b1e91cb40c843662d050fa01f2580816481de1ab844143c12f6fb1525a59264f9aae43d85b73df259819ec0169cbcf9162457a4d24a968d80396670e37b55b7c03c607870432fa6a7068229d557e23ac6cb29aa970c2f8fc561c4a576d1a1c8f8ff9e743f16c71b3cd59514f00bb094ddac940682d0677c839b6b4e8bec8a6f5dbaa43f916f1fce0b1f5d9fde92b6033e0d18ccca69e45c839e8c693c0a0fa848d5411097a621e889b9c5fe2e49f819c23f97ec10954ca5147ff976f19c269bf06f56316fa959c8908c6558056572708482119d3fc739cc729446c95ac034cd025edbcbcf240653b5a26590ff6d002c01b792ace11b1d13d98150204fa19684c4a6c4ffb109c4e4862376ee1c8cf67cfa9719340643f8095c982516e584130bc325ce1138da2bd5c93ec54ef149ad6fb11b446207ed5d16d49ae4ba1a52080e8f040b2aa984ff41eb9310b87b2388015d51c1bc74c5cbe2c3cce6e7c114aac59f692ba91abb93bcb9a2fa6e28703103647a62e9e1851700f92c21a2f6a6a8ad330ca17dc4bcea173542b3172b23eb27bd6d318bec8cea3b4b9a6721fc8af17741e9cc2a4c587a3ad685a4f12486bd6ebfa23fb2d284846a2a79337a432d3d0ab11c36f68a1d1dc01b7e68b4ccb6b70e1ebb525f6560b243d8d5bbcb3f3de235299cd75235cadba6cb3e7f3e24dadd6f6ec7f952b9bef8dd99b898a3a876bed59edce0be446c78330fe196771f3056555409e4860cae7b6bebf0f2620558345f4e35b7c888c9358e510a281c222e2d9e3fed2f9842b8316a32f700dfad9163972acd07886f94ee2a01f383f9daeb1ab4b6a1d6aedf6015104f9e8a82941840fda5ae0067073c6642d9c161aeaca62bab5697ea172beada3df770cdddac3ebef8e9e189c0bec153d8ef78ccf706c6263bca3b82707dda32967407bed4d51bab0ddf28c64d7478f1de63588774050ce9ecef9ee3c6d90993243b1f17ea66bd6a594d170f47cc8a6f4cb138bbd831851ed623844987f86d5f7f42b384c9dc277410f2ea7e3a0c37ee930d1d1a062a1cf28f0af932c1ef9259655138a451ea195a9b67d5c5489de5fb155bf09a85c560443738877770cd09e7a31601215209b390a5ad02d657f4c7afdf69b5cf45cda4a9fec380df75e505dfa08813b381b83a7557a2d6b046205ec454aa4c966d48ef14e910206f19740bce75ffbe72dde9efbe98ba49c10e908bc481ce6af707d02f175d325592f240fb50c3ad91f13cdbdcf734e1f9adba5ed0edcecbd1b2410324a3111fe0722915d659d044bc92a962488ada6f7d58511dd0ddd5c832333572091533ea6cdc53f9e08783df3f5479c632821889189d8bc66c4e4106ad16e3e10341eb6ba83383047ab46fea706181bc557aea302a66da3292d29c280f70f994e99784e700bb54aecceb08b275a330cef7d1eec1e8c3ecf58267d43fe02e1838a24b8411bdbad8fe7ad61e3079bcc08822be3996b48600195aa8bae53ca4031f2f0889da0837cb1f516999c682bf6b87af481c195951e03c790b4782ebe31549fd854cbfb00f46f74fe91a47a9e5d24928afb3736e2304e36ada56af62900155341b0d3224d5e42fa93a524b3682b375845e8ccdd8fce19541232675406d116fc2448a384697972c115ced906a81605061ea51cd65f6ca64a088c935b37469a006bfdf6c1946bc2035ab793e7595d008f6e2796a748a8ddfcdcf57e2c580abb93edfeee2e4a506613859496cfce1c8c20a115625321f76a86494568712afb4a26d7bafba048b0db6f605f8a87ed8a37930338005a812336d29cee4103c2b5afdf4b0d95ed1ae2b26959bb9499c71e71153bf7bf8a4d7dec5305375ffb270a9c184247841aedfe8d0ce1f0fb083b7c1b76e1b284631376ce0e7be74d1db79648986825f3c549cb4f52312d8b313db61c51625769ec70444f66228536b5d154ec1129430dd807a026d3ffb7c54ec3f16de3150d02bb2939189890f910a73a34858fb83cf7719428772b61946dd2d8ff1e31a8db81131e36a041a0bd5a0d224d5c2ad1273e869e63a332b5a7018cbafb8097b78610e4074bbcc6ff658da690dc375896326cd9e8a13b48785f551890bd89f4adaca1ec8cf660cae269e98e0cdd4c13579c154d49a8a38a0b48300fb4b9313b0302029ce233097360cf672d73da0a4456822431bc5fd72497593584be1a067259a340a65314ac61673154d8cabc6de88ef14a022493b54ed67aa3d024d66f9cdec9b0f68f52fe4fd9736ee3de97ea4b46766f99590dfabc5d22c6658d42b029c7658de8f3800697358a0c7b550c057259a3f7b6ce60348d882ddaa9bb719954fe2f432fb9aca17b07247420da057ac77bc11a69d49ffbcfb4b4c42dfb10394dfc920fad7f4020363f5b677640f3296b7825d76254db104423d77fd03d88dafb0f6dd1bb02990666a70648a9a73e9b55a94aa7cdaa12b6fc44442e551104c953fcec3216fca97c9be32fbd1b4ef311ac7739d668565255d46da684553b8914de78245aae33475695f13d203e926735fcc4b2019bfc3e3793756b9e86bebe0a93c68ec286d481f7269c895e34c7d33fc2f96ae420b9cc458a3fc2497509af893e9b3e79784602c5c40ac6c68d776e82fd97520fabf5948bb8b4fd005fb2c92ff6a43d2bef1f4816d7f15c8de535e39a646d1fbbbde60e6b9767ccfab05a1591e26cce625219229903548552655dcf58aca33746f8377ae537f5f0e754bd21c851594583b4f2a958e3e406105dc2f16ca238eacf2ab236b760119b39625b6d3ea5d303b5fccff255779bd3ca25b141ba8c0553e6542125dacb5f44ff7599a53494a15dbf48974587a61130c83723e79d1bba070652f2a2e55e4c992b71b9981e0ac71a0b72ec89d4f647b6f74f6cb4420590ddc6370875fb74d6d6e139cce276454389cb0c21d62dc84a419a4a67391b6b3a02737d09e0080aa698eea0ab39efd03fbbb230381740b672b00205804ffdb2efd5c87d0e62de7226e08bcdb22571a5902235caff339b971c0ce50b1bf23e950fa633990a6ecade5e798df19b85f1f4032151a9811a5cc6213c7eef4265bb34fe804d87488d244ca265e2daafd0a3050ca2e7f0413878d998eca4ffe386c8cd4ac7185437cbf75e34cb04d4e14e89ad13aab97d2f1b1a7d376e93ead3a90a0e385290169de603a9a332e9110c0d3a46468fa19314d68040a4cc766ddb5648c93eade9bb014d2c1911326cf14972c483c602e55670850df55e9a9b1255c1b4c5d5762f16a9fd2236baff0c0869014f9b067ddde4d51b148194138bd8d94164769b63f3ec73eae33fc1cf9ba5c9175ad2df3e6fbaa3593af91cf2db94a04fbb4ad0acda0223fbb283017c0b3ca4eb918873a959a7fbee8af9ea146fc904ac715e0ea7fbd4b29271b7d14f6f736f90a58b11572ec278f686a9d0360589aadf5a8e15b034ed9350a57a720c919b58228af4277927f78109c492c9c1a156cf709e675583282755dd1a654e832834e85b62a6c1ba21d8004a6bf990f617092ceb7870c0584a22a1a4624017191d0b23bd7dbd69155423e10f6e9344308acf5aa3e3c1e48f21857581ec4481edd7c5e261023260fe3ed10cfcd31bc10233da4a629f812ea06686141153141990861f2f6ffd63893f83e8536bc3622674a74aab536d3217471b54eaf1ed8c3af634e0f1f186b821eda8917ec7db9d9694d2770ba2cdc4f00af0ec3a85a2ba43e052aabb47dd8d50083d76aa2aae96d72e1f51dff363c37aedd1ed2f30745109d775c8d08d3b8fbaf264094ba93b41be3aca28f59968133e2cbe946af3bbbb8d8279e33c2510deed6fc502607666443bc7866fc04195b2fe8602cd9ab8e52de0f243cf7c6f9a015909c3017286b8f28b1024daa2d9c8cb78895667f25a33dbb51bddf625c2407320fe845360799070c6211a42d9db6ddad5747d5381c316801afe9ad40b68689c2dd3a10885a46eb9091aad24ec13f9b78c2e400bb4fdb15c63e48a8204a420dee153685017f090d9e6f709824f4a64689d9228dc5ccca9759b94843e1625cf1840a01742258252ab4fcd2716d2ce63ec0ee26a026816c5422e6898c573473cb55b93361e33b792f5e4b6850fc92a3dec2bc4ed93a9999b30446fcb05307d58062ba8abd127e5470c330ddcb256c711f093154a9781f29a56001550ad43e08507dc6d43c941f68a80a283af0ec11544a647e544c5ef5042a2ce5d7c23344d0113b040c60c0dc14c03240ef1131f061d97a5802088ce488d205e9025bae8ecbebef077b80b755b7df23603d865d6b9c582c6a999ff168c22e4ffb082679d422fe1d7605c3919c0e5a139901ba5805a064acfc92b6075db368bcfb56ac9948d25d8bada6732d47ffe599d6e1f74fb4a3fc1ba2e55b0a42749b56319bd417450c15c98850660087922e6bdd8bd09f1f7e03798ad06d697b6bf187ae005a2b33f5ec524a1f41889455f7efff69b9f059e6a0a98b19a27f22e5f5fbe8abfe8c1911d6a8ffc5544c5acfc913e908ec5abe02afe6a8e94f488d5550b50de96a2bc41c8899052541d6b335d7474f7ff7aa19c09b5b82b8240b1437e733351081fe1b6ac44ad6872aa7995f53dfd73132987ec935ffda3f7a1b1d34f2b3001545f2bf67c854a40e07c7f452a76037a44a64551fc9272f6a4a5fb3f6d1d9be7474dc06aa09774507e74841068a5b199731ad37c5479d31e25c67edaabd333980676c37d09f02e39bd68054f6ad6d505fce54fb829d9145e578bbf04281252abab3c93b4a978529b5be9fc22cc0fd4169482a6591bd39f13751e6558e7aa4e9a7d9ff19e33bb23e41c8d61e1a84b4df9cfaf797a84d1070e385c03f2cbdac71ea48f59dbe00317bbc0ff0413b31247526defdb414d68fc340dba170bf9b86f3db212583c35af570f6663f222c589fc6be102f85b8179dba52724ad2a914f070abb38d0e4ef179c632f268bdd616bebfceac318b08a5ef0061420b4cc1675ac7fbb49e74d91871d4ba73fc816263a73bef5023f5d060764c62209d37f58a88df7062de5e1b5f2f05a9083f0d97547a8e0087bea201f89fdf108dbe05cb99b582722ebe8d5eceec53065bf618ee18f8bb6d703ed1a1609d0ec033d5d176f044040250635bb4ea609069e13f08ce2ed2ca992e92b6ca889350998def92b8bd8030b8cd9b24ee542970e83f80d6f1ce601502918f6c104cf570e08cf01cb307d39a6b42b900bc2da91772a7b2a17793048bda5d5a9418d9184b1b168e9852eae619a444ea68bbfb0dae5d9abf525a6b44fb295961e908b71c5be759db449d04e165c64101ad54c09f623749dd8b7ca9840eb76273ae2d851460b42c0d69f0244e8c4d10bb16f05164d9afcd065c2d96dd76bb7e277241ae449a1ee2aa320b9872ed68cd83724baf355f58317ab8079cd42ef6ee61a34c8f479b9dd0f64a53e808409f027e9e3f6fe7de852e8a9c4bb5bc893ca2fa0d0111139e10a10afd14d991647cceec188499199903b16f8bfbee1f440bf7accf349af5a62720c8eaed104d02d9ba050f6d1538fd6109e9e861264e62244dee242d87375377effb4af272cdb5c7d414b2c7c63706a60d2eec369a130d74c85c735cd7ced51ee7d776e46456370694589554b35f4c8eeeb9cfee48d8cb81c28cd778e6137a3af42db017346fb87bba6da47bb94a4a86e90fb5d5579de01147549cac0760d4bc777a93c771bec14b89246e1fbb8953d6daef050fe09e73219947c03f3e7f1de8cf42c8a839642fcedfe74083138dd0b3065d7257cbca93e98a0401db9b485d19079c030b899ddb6df4e0faca4cbe55dd11297feab552555d6d5f4350cae3a86ae693206d974f256a1987037ff4f5cc4fa45c1616cd3f21beffd1b9fa83b012b3189c59e8e60a4b73cbc77c3e0b2070273cf5ad10bc8a8cd1c93c430b8e21e9e1b7f0316bfaf0d8f408a1655103cd4e8bcc65b70aa89069b8e229e40225257703ebf48bc72f737898670c31cdd217fb005e65795eff5a87f253b8afaa963864311b8742b4f5326c12a10af2bc04ddb613b68b208fb25c1e109b494a6ca8965a65fb00c935d87f8f8adc1e05ee439a88bff9ca783081fbe2ef4c7c8dabc6c16a3db24412d8f04d3084ae323d4d26c6f0e6ac10a5772b107d68cdc0a2b21a144c83a6b24d607bb44fe0520d1295c0d023d95a081f891aab9bc8c703b825848195e6e6e95685a936322bb9bb31eb594ab05cc4541771634f3d17f4aed14ae7cec7f9ad4761518f657ff3eb10316964207dd8595967076ad5535e8fddc87b74c02181070dbc4c6c3c5a4348de9782cfdeb8a0ffc5febcee6573e339dfa373e93eed5f3e57de9faa71ca2d76ed284fda0bb52b65eba3f4133d6fe167a5c485bfa1a5abe07d278e5c11e1d0782eafde5193af63640e25f179ee84f0a54f50fcd49a25465c59fdb0070a3652e3cdc9711353d1302fcd0f8f8916b6ac512bd77886e796126378b258d14952e7a5d83db1ca4d8c8a2894378db67459b93af51ae977dca6ce3206791bb75528c8d23ad73ba90439b3f043fc37b3793afab0bde4db2685b2c1f1d834d6d8099d9f72cb010b015776b8eb093aca7b2f9afc310cbbea5f64beef3bc7276341c189c60fcf0e16e3b646b444b5865e8604e73cdb2f827294a0d93efd391449d5e624adafe094d7a125646ae9326a09520bee9fbfcbe52b396eadbfc5fe3fec557dbdef35e3781304f5c4c34b48cc688160a1e2e8b4d6ba0d07bb5d9794e670aadcb243927241457a52ea4217a858cbff60a02f267966c3869d668a7f364a420dfefb602d4acce413964bd12b6869831a65ddd755a8073629c4782e6876853242ddca942a892cb5ec528714ea847b110c8291482c60c4a7949dba2d26b9aceff2d87f885fcffef3b65a001678a6f8309de5a2531cae26194941732f704582ca53af4a920b77e982fd9eeff092e62c965f05b9dc89cfcc7229d3d182eb050ac9ea33f21f50f174933163ed5bf5e0e2a7eab232eb852544bf5928948a8004dfe895c5fc3c7adacc894dfb0ce07bdb3e8517d302a053e6f8f2f6ccbffefb71cba3d465b221fada35390f1d7bedbbf6caa446e900bd6d01780e456b39b54866558dc17e0d6a3e511f3889ca3ad8341bd61e46b9c6a17d90904e5bce72e87ca420abd524506cdb1dbd3156c710e757252638516abe7ec34c90d652ec78d01e0d976a19709f2b89a5157ec71f50de7191fda90333fe7dc190939117df45a430eecac7c6ac805893c726b8e65a2403a466ac8ad9541610ae1209cee7a67e974fcfd4bb14fcff457b3d842ecdc9ea404e5b5105ed8b7d4af0c1a670963229d96c03f9facc0a80566b18783c27a4aa25bdcfaa49a7ca732b7afb3f33a2b1ae3315c951c91a7323b7cbe80e36e9613fb989ca503e4e51400cc567868d8b215ab81ecbdb05841eb682bafe7af1adca54dad4c473ff153f4b86eaf236569e5c8c184e6f6f3172db564497d504152a4db37a6c90bba1e52a9252510083692a5eff5690f4e8b7f51f05fa5915b2412fafc81c4dd2ea50543a83cd91afb2f40085486f4f6d28dbfca4cc055a1acbad298ed9f3782e8d7fb4a99eea42017707850e81f71d2f2c5e7e630b412156ab34bb4924422dc133cc6e9a85d2d6e523afc2d2b29a594e47354715994e5895aa1b63628d6932e581f302d6b5ee6fb832746ae8eed1c9369f0845adb8939b60c0bce98f59d7854435028495a573a4864fd14e297cd8f2341394ea9207b8afe4a523b6aeca0bde85e43a4de4abe13ec17988ba0f0cc7bb975ecf54ee89a66f81d028824fb6a506821945fc6b383a8c0c62dd834325eb9f4d20eb50e9c9b825400225463684cf219cd1da73962878c362a8884a0c456fa91f7ac75b4c1efa013f70bc522baf250ef06004aaeb5fbb1ec6ca134a9c5583656ec15dbf0f546d75145e93afb81dcfd66d5115538c83add22edb9ce1b46fd0a0c69d892579cc9d6d909b40eb279e58db2c73f43aa2c07490cdd54195cf69755a5b1c7c7548428010b23d848190429c2583f065aa2cc822979e07d88ec9adc982696a147c08c75587db0654e658d651b1aff675e25dee7069076e9aeab295be916d8a0ee81d00c02c48855b3552ea9cd5c9da5469e9a3035766c3bd5fa000d5e03514015f1d006abc6e0fe58cfa0124d3c2ac5e574a712e24444cc966de3a3b9ee7a03b22344e8dba02ba8817e26d96aa0304a92c6234ea60be9c5b2cba609d1d913a40252b3d84a8867c3e78e0263e423685dbb5aece14804a13cc6d67dfb05e4b020d3bc8504f4433900190b4f0fd9bf8665c08c2a765e2d71f0a07ea895b4499b40d22d4afb64e5e5ea2f081e0f9c3570fdacac10075babf1135b4d18d8350cec65245afc5af13fa9227953023f376bdeb612f6d82be5631e8434912498b054ca5f0c1f8a274df6db58ea481e6e181bbf33dd70ea164b4bfbb555b8656733ad99ac54acbf66a5cde03f887488f4951f3939e984613fac757385732934f21dd42095cc12a5a262c50e6124bb37428c6c958689e63c2b5ae5c0c16cbc1343aa657bf8707f5d3d84549c584bcce500d1cd0983a4ede7da745305ee67ee6e83b597606b58253a8a7a0bbbcfb50fda25b6fa42e145ba9d45cec38605743bb087d5d315831000b943db139c65ce57d15d351724293fe4c58cf1d8df537374838cc47d9d762dbcc3e5d35ecc1d3d8aa2af647796caff75aae2f0e9b7bcbcc8084af7eba2c9b45265add7451315510b9ab39f929e6e2e20de571d56c2c5fa9b7d54280ebd24773031c0f16f76812485b9bc6658a1f6512cffa173e3e13ffc2f296eaef143f97e4c9afa0cdcc98a452fc409698b62d6beeee8291d4b73d0b6f232c4110f1c28220b460392dd8433a899a162afef4c27dec4f99a1c3c97ec2aae1ffe56c1c134e57e0a852e617c960304e0aa0b93cd5138bf9b81305ec459950b72be5f8ec5a77e6ec5713e540a773626bbab40b5c9c68e3baf97b2367f0c76fec00badbda6c4c7c25afbc0d9a4941097727857ed51a859eab3c2cfb20cc34b51f03b8f6db1c6ca1e1fc1133efe5ac68bf345af7c9a8f77845734bfd6b834be91623ee343c1057607e25baae7258d43c12575e170856e25e8bd0e530c6df95e05aa80345e39c33271026a1a13ddaef3c0cf18668874f22484a1290f312dc7b8f28d1b303ad9f102e0a7cacfa9bd1aa3402253f69a3694d99faa1bdda8c01ed07d1cca1116101782c7a89fb8e548db590b36cae1d41f7974f468126a024581d1f209496bc6e237c32d80350d489714e87139cb2fdab999cb0911a7d25f6e25f92ccb161076da195504d2708d3020f78afcee7da50ea1c7970e02037aed7d73a2311639c0207592f6ed33db58225028a48245832b96f49dfb1170bb77532445a3e4863c102471536101094f71879f0e232efd329bb246a5d66575e7be15cd251cf316a845ca3d5a713de3f27405ce3222ea2deb854209e04ebf1f68c4abc4fdc559946042910275f7d8b7807c30d9536edc7dd9c3ac78406cece935f33d76e468be9802d27bbc523f79ad841eac0aae186deb3febe06cbe9fd2c48bd12f1b2d58b46ab0cf5b44f2e2f237f5d2980ef0c177755c3dda662b38cd350a87b93f6cced3d8b5ebaa38a1b5d39e346e7e7ae5b6c84aad24ee94ea64cef33be9005994e0736d5ac517976df6a121b08e014e2278f4ad1bfc4bf2950c9f833e82470991d96a84ec4ca6243011c8512016b2efe628d0041902fde02502c16e88d9e77c6f802f694953680563447df30a2089bd4ab87428f7de873b030326e9f55a9580a12ff32e0236e1225d106a99db58c9e8f6aa7774dfbf9800d19b174ea1034a935b53cbb6756d6d04c8187a2ac802da11767cdf12a3fe74dea6da06ccedef5747f509fc4df1c8f64262643297c8af696c922d545ad6d465726bfa4416bd91e2e45bd023e1ff47134a93c90d6a3cbef2c6ddc612d1353318bda9e3dd97848d25748341e6e4c198f7e48e055390c650fd5466492e54fd0aed8963a935bcbde2af4a548512dced7b2ab1cf2f08328fa1f4d377f44caf371c612a9b00f386f1fc64c6dac42f69bc04e024ec18b009104da7153718137cc55c86be9e288ad12bd70c4313eebf59cbd226ce8c604ba1a5cbbcc714af87288157c6852aa39d722692aec855fa4a6826bf418afc759cf53f2ab4fdd4a47c2e7ac7c3f879f5f5c3a7cf78663643553aadcd8bf62b6337f42c1718035d3a13dbeadb9057978baa86788090f218f2d21b6bf5712e8ad6d5e6c1a8180991144b6d3c3ae93aa78a9e05b6a7348db31bde9aa8d036e18b481f0b57bb650817a2a2d47cf8081777a68089c3de74b1d1d0ae9239f9ecf68140e5798cd3bcb41a7d31b37703ab991ba3da75f5a611cf60563adf68129c7f1beaddee02fcc3cb35c5b2b47da7b3950aaa86a2bc6cd296348b76c6036e5dcdfa0f025e5f6d3afdbd4a0216a367e083b7be8f7e914a04de7d4d9f049568ffc6ad8fbc9f712bbc11bdbb7dd56ca55a1d04078fe27659b17b5481f3adfb76d7f19718eb146c5605fe9a447e0e56205e514d3af97c11b827c1b444704f827560d03718eff3f597d470f227970c5fb67d6e2c9f4a4b6588e0008003a5a5ae12cfa491e998c6eb9561579cdd95b9b2a76d6c0615b6ca6e6f668d6c23441ad984ecbde5de013e0e590e9f0e240fa25d2d4ffdf227355cfc003759a932a0925d56af972d18f5f16a9a4a0654f2166a7254c99486ab6fe18823d3af700e955cf25547a740e9e69c73b6ccec541a3a6b28cdabdfcda985e31072cedb695fa58fbcc548b428cf0a936851fe4578448b18631c2dca305c42c6907f8880f0764bfe24ac11a6ba25ef227c8bf20708c56ec99b84ab5015d26851be246c69515e525710dd922418f5f9d948e111894746c2d251e1784fa59bc271e21c251e2d96308db0e5068ef08810893009204225988881b5189b3e5a14658a0350366d694d9373ce296e996ab69b36cd0138651313140901456dc6002da309ddbcbd81c3081cf65abf636fe0a15f111387760387d56e486d621c46dce001bb59b4125c410a6cc001688580f3299840d4ce1bc3a389212d06a0a0145016e0907caa55ce69edb4765a6b294d813636668c0de078bd8e01552cc0d9b45a6df3804c1fb72c3fc2c8f2b2296454c8aa90e1e0d84c286c6614520cc1220b2d5410209b3083b65a6574e160e507f47092a512b4058e2359be4e20784c1f7ee8808cd11fb5d415f2524e2159ce20a92b402ba49cac3c93b814e7fd944d994cc3a1ae19a45b2d0467caa6cd9d36535c91bb771f53ddf4d1430b8a44b374ac4592f4691a4f76e0becf6302d1534c9566e9cf681d3c6054f938cae38c39ebfe692a648cee20b93b47f6141388d681c4a979ec1888c70632ca63d3b41072f340c6e81ce4c601c7eee99ecbb6ed232cdb2e926df3a911043b3cca2152e40a8220c84da0d2049bd075ddf7508e77ca996f6d05cc74e738ac5526bc996e36143a799ca25880af9dfce86d88ad4745debb77b7d5760de872ad61ad94d653ea8536345df44963327d42d12c221ba64ef3c67a3282476b4536a8474f61ee684938524dc21bfc8e9a8427f806a3ea67a37b18be380d517f885fc3131e3dd9e2cd511fc137e14bf0cd0b4cf317c6b25ba8b07bf552f427a1c949493832727a9410232fc13721a6f9eb37c7b55bf52421aa8a9c24445d7e4388fcf496bef947feb0762bd52ca2d59b52cfda5429e88f8e62661a3ca138dd74ef76ac160a21a66b445de4e4f624e1c8497e83e2b17ad99edcbe04732c005138879751a693e0b1666f0897fa9a51d8c584c799478e12f998c3cba78be0b1da4c47b0cbe9a82250de09ea27ec526f33fd1a6073a5283c4e28b2b5efc2d56d283a9d4ea7d3454e4f1779774261d9e2e9f4f90921f25349a6179dc2fb124d24ba08f73b33f7cbbda5ebd7954a26933d3d0d2b776b6f1861058e1b46b4b422b7c8bbdb50e4a7708cc92715eadebb91d30856a1f00d9955da5d468eba3672d447509e77fbd3bdd08ede47611d39dd719251a7efaef5541e56c04c466115ea2ea77b479deefd84658b9efd48387abfb7a75bfbfaefdd363f06cc6c454eba8b608e05a0955f034e6eb1cbc94fd8c5e4364735f9e56e552525f4224a4242624944f5b6b324a20e8f22ee63b5a98b4c61cae2b11385f61314dd8a6e4fb22435802a2cf2794a4b957ba9c4bd54fa8986634ca6232378bca8872dd48e39bc5cfae85d2d827be9253c9e3e3f05ccd452389e5e51f7c291d3b0f3ee42dfdda31d961fe96cc3b13b887abd21b3aadec5722f00454eb1c8658b22f7b0080abb9cce7dec700e2f9f7009cc60387e8cc9f7f7b321cae171dc6ffd36840a2c7b1e1eed2100727dba75f806983b1aaa620afdef654b8746746ba3f8860d6be5ec069da669d6725b68ebb6addacb7fa35bdd2edd36ab61af457b691e3ac9eaa6682bcb6dc3a335779ef68854365b7cac68161f7b45b3ccec106d479bd91fea1a5df48d8687a68746f3d17ea80da2ae2da503e2e4feb1b9319046e6e943047f812327932b53943259de76369d3903a4ca2b4529c5f9519892adb932fece7b92efb57376f6ce3c6716dd8e906e0de07ce8b49e8a212c3b598bfddd77dd4eb733061a54408af6a37001b2652f0ab590ed2918b2bd41a542108cf846b3d16c3455a41cc1922dabfd683fda8ff693b74fa76b0f0623b1dcda6cf96a39d78dc55ef3c3a4435d414c6c73b553cb1ddd641b4fb36c975246816499900c53ef682645fb54d133a222f78827f7c7d11454481e6f0c0b90c443f2215d319ab5d8269d12930e1ac0f9d1a41303025d88225b770127f423c2d6cf464b10375ae8afa65ded6ab725016e039645bb5a96601479eab44bca1fac6804a535d2757fc8704c4d489729f5339aa548d7e8caa011e4344e5b12081ad3e6e9812a454943d368e4a635ccd54e3b5969005b6432d908b2a58349c7a463d231e9e4966970c168369bcd6414b29d21424b02b9a24851d346da481bd97b357b375b2ded59ed48ac04874eb2c63b8372d3b4d85080b76f142d3667690fb582fac83c9d1d1d9d5b6ddab5e9a47ef4d49a1e9a766d3db4356bd706445bfdfb03149427e65800d2f046d1adfe7cd7dd1fdd3b3ce6f0ee8f16fbd6dc28bc900ee99637b55bd322a6b3164a69cd8de207d771efae95f6cc7a669bce06445db786b67ad301ba1bd005ba3b2dca6fe1ad025f9d1f4a81dc9a5b736b2e2b5b59b3858995f6e491cee80c0de0957553bcae94f3b57d6189b0b60549d9a6eca77449dac939271e2d90b5d3d0a4a2cb511ae37edbb4b062d6ec2db6ade794e6969f5b4f965f11b7be67052399a51404c194c4d66e6710924526650dbf0bbf074fa9ad678a000764d87a72bd2319bd2268161434e399cd344d935293529352d3248d51d7bd3669a48b89fe049212080b4040338ba016bb2f22f19b6d6b4d95e8596d8376351a7333b5bf9552aa85474c7ab5f088d7a5379c72856ad7ded0c7a5947254664a6dadf52dad7555410a005ad8c11652acf14528488b9d0241d4106d67c311b36a8a28ba7fb46bf5ee1dea5ae15e45b1c23b5c37e7b7c57a4622edaede1244b37897bfa1a22aa5e44d0ab954432281d878441bf8edd492d0be9a8a76354f374eb3d8b7eaf6166702b1dddeee40fef0dddef65057c9edad0f4f6e19248f6dc51599fed0acb5a2b53c902eea638390ad3d02c947db846c47cb436303445d5a07d118a5d978ac0f6d5d8447d1c3a34ae91c1e67dc200d53ecd3336a5468c45873dd635b1185ac11c126dfdc34f996e028a9ef4c3cd92ca05672d5e5cfea141419b23c278140cda60fa8d904e2db993ef4edc79eab502584a7452d5455b1338150a982206374a65bd642954e8b55b40a48a80ac2435b3d5a2e09553bd552edb3a1759b4a0ef14461cda59ad28f4d0ab92ffa84b05914d2ac0a4130da628b2db6789968ff763e20a14fd62cf4d42ca3db5fea527d457c4066d077338180bef05e1ea39185e5d0ad78b1fc88a83964c1f0fb8ab8dfce07e493d9d0e75d7a0f3714a2af697a3e9f5c042159ca1fbe23c818a30a829f0d7ab0e469218c05df6d3c1388906c86643c9d4bc2390b7fbc31268bee773f3cf2f0c22ac5d1e8da2b2c8bae89a32dfc84b4c8f305e9c0f03b828c21d26e0f6d85641388cf099fcf0705d0927aca5215d9cf2c7271e249f96f27288fa781a9d30c5ab6228f2a9d6f4755451e4b35a59a21e0fc58aa39b9279be5535531b5301f7a2aed52bd5df7eaad6b75acfa76a84ba5122253e9c81879e3c2fc88e056dd94a3b45a5965a78150ad211983b3585b85aa2a34695b74a54cae6dbf223adb5babd919d2d004c2034fa91d202a9d3280b2455abb7e36a6250338a9b67d3628dec6004e6a7db8587e4474b6b5aaaa50ed50acd29981f3a34ac71e6b3ff207e6656e913d1acd12ba3c8e7695fc1fef0a2f2fe78127d50a89769ddc857c48465d212ed5c8a8ec866d62726f6f78251fbd8abb3c32d976552b4ff5d1afbe213a87ce6d3a3838216ebb79e56db962d410179f0dfbe9a17e2a57bf9d188bfa41cdbe9dd0b7a369ef5c7834440d69f1597b49b5d43b898850fa8be7141a96d9e49b3636261fbd8b6f880eb5cc85555e29de87424f8a574af1866e13f97e1201e6b9b970f1d19fd81c9ab7a16b4fee9d7cf4ff86e81bd65933693e41ee279f8ded273684b1dfefbd27210f17a27b4d883c202dcabe20e1e7d32b7d55f8f1f4e4fec977431b7ef4f81ba23f1b3748d89fdcc7d87bf1d9a07ff10d11da429cea5eb8e3660ddfa86e4318ed3137c3c48099fbf6520d75a16663a94645a42d1ff03b42f81541fad0afa819757d41bad5b722f727e4bef884b059c3df0e17589ad55225e17d752aaf24d4268bd53ad01f1135cf79726f82f61d4974ea435d5c0c64ab9f22c1630a4c61ea3382a58b93b94cf2487d72e394491eb918803af60775856c68ab7f45f078c1be3ed4158ad15673a954085f9f900f7883463868164493bd8f4084c71e74c8f5f41f6a66435d9f8cb6fa36219b2f642386524d183e59ee2d9c90913e681b1e40b00a3540c4cd9b1c4aa00a31b03d14a35c28c685625c28c686accdacc03b379bcd2415668210030228df02b6cc9d93d1a75220c8c9729f02dca5cd9a07425a9ddb48b3c9bf2ebcc6a1aed5dbe4fdae249c2f55a55a8916ce576847ae972dedf823e2e6fbee859c2db25f85b2ab8ca13dfc6cdc772ebc9290be369706a4f16763d376ac26e31efa68e3993a25af78dc64a1b6630650ebde78a82b2413e111b49827376a56d39240b62852ac7ff1115133f88e25678b38948c470a64cb9231eaf1678363d94bb11e8764221c928564b2cce10eef8001a4b7f6187f1c87b5704703d22c32bb8968f522f55745c47dfdc52c7ce29584fd6a9c66a1ed23c3d4dcb1bc09e22b40b069f28bc9b2a17d49b8bd5cb050bc4b5d2597f22561ea06fc02285ba495a2783a7954e9e4b62ca7940d6f0f9f8d0a03c667836e59368bddb0ac16cb0f088ccf86d6226a861aa23aea47739578b9775033d41095f601e956cb931fa5f5226ad662a3a066a821a89f9191af08a9851d6861075eae2d4a51dadcfa6cd41a86645a180af1946a68abaf96caf4219e90cc0b20fd18928582946aa8ebdbf94a0000c0b7831ac285a89fd667e362d40c35cb2dde8764a120219eda2c7723a5524500400b3bd0424de5daaa00a001d8b4f0a6e434bca1f9ab44db404938654b7bca470497ebcc5af801f9642df6637c362afe763e015c91bd663556d78327df69b6eb6ad7d19e229116fffc386b320d8f908ecd818adcef7c7450e4d6a2c51ebb5817cbdd3c5d6cd65059bbda06676c9eb6f901475350dbcc9a1a535090490bef54339282a6f981e227f7bd4fd91ea5b5d65a6b9517acb4da98afa3fc76efcfcf7353a1853c5ab41fb7f3683126bf7d9441db67b36860d3e071c678cc101624cf0316eb8d4adc3a383288475701f3d12c63efe47eef7415b959e479348d0c0ac34fd68278cc9f9f1f0ed6a20ce2214f324e3cbad597937e4e8969cfaea00d1eb5bd2db466a18993bd77cf91dd73e86b9d7796e95bfa720e99b3533c87cc1a1f3f70007f86d826d642dfc2d0e7142db6c4f367ce5aec9f399b26aef6fcf133f1fc996579f1d4990d912dddd52f80f21d0a16648c3e4acf0ca4146d407fea048262961de40f1337e10e3d9a68a385e0508ab182c8309b3ef467006241fe307168e2101c648c3e2be8b2824240dd0b42f8e3bcdbd139578062237f982835902c287540c1a1ae0ea3f4741657cc0a42e941c141c141c141c1c9fd0f2548c69833949ef933816650c76afd3e21668e02902dcf89470e64931a9dd64e4bd6e269f550977c893eb31fa020d146e4913f4c310a92a57b811443402120d18666d2743f8082623413868f9c79e950977cb55a31eaaaa1aefa6ac566009260ead0228063088826d6d174353fbacef39b18c6c6cbccf342749eadd81476b228cb203e50c24bebe418fa9947931fb96f5233734ba7e5d3d2697541b469e9b474441bd146b409e1a6810138ae64628fd8435d2a1cdd675e3e4175902c7326cec41f11a80c628f6afef3bcf97b877d17fd01f29582819f795d85b6fa332fd147308947b0f451c5bee4cbf4beec89611e205f37304c65dff57c18ab708ce6ebc3391998c0f7ee4790be7718365fdf499f99ef720094678ba6594656502bd68ab57cb4c43e4eaca01ee43e4b8b6639c9b3f3c25877f09d288c9d7ec298068d3e5f23f0dd415c6311982ff0f305de864450acaa9f40b1589eb39957d76a793f3d02a28b7ec23239475019d14b8916fba79009da6aa0198eee2dcd7578ce4c58454b5845f111de3b0ccba187cd19c54774fde3332ff9d00b55f4a2ae5151ef4774f72ed2eee109935e3deb0d52f6ad82583f2c1840e20f1840d4e5bd2fbec0f360007d308044308046308060008d367c9b00ce8fac5996d9c09075a17cc1e081d1d32cd60a1f1857c098d1c3f8d998008e33f9b361ab6502483faeb4af087adb52e19003d8a2c1ad588b323aae64306a60fca02e5504ba7bdd650d155d058c1d183630709a4552017a3847c523c37a965bb1566cf603140423068346476747c6d3e3d343ac87580f343dd4f4f0a3871e706811c0b115cb7d9420941e943a48961e012b88ba3afc149832a2f488eefd40d04ba5302b28f769d3c8187d998823f2883654d4a1aefa6ad166d5d22ca0ba0550e2d1a446465dad19757572255bc956b251cc2d1dea0a01b574805a3a746ce97435b43567f3675302287355cdd8f4d162082804445d7326434021a010d06ccee66c5533653259280ab9573f345b437366f269963164f2315d31934315b93f874c2ce68cab82dbe174ba4f203fa8ab7b3fb4faa1997ce6cc9a7ce6ac9a7ce6cce4b3138a42680c32d485dca12bc87919022a0569b14b3cb94b3219a34d3813af64a329d4e155cdb892f9e44ce738b392ad82e05668866b2068a6b099f9c819d1eeea08aba8d039a359c6799571068ff28a3ce6f0f2e831348f5eab1449f95a6b8f9ce5f7d1bb1196d38759fd5eb6fc7d340abf0ed262aba874b8795afc1862194d0519a3f18c6e213246bf930dc1c28a9e3f96c69c32d643e5eb676356998ce6daf3038e2a2a17bd4fa32508eff4a0c473ceaf018b6e19750dc000b92fe9ecaa37c3ef5d8b63c733cefc757847bc4800c79be903246d49daf284f8f0e8a2b7d05c45f8866c91140601e2964fa50ca0cafc3cd975efba203ef0c15906f142165a465d956a6850a1ae965598f9b162296bb15b36295691d1345a3b03687a95d116c5e3ad5490314e47940e9b6ad079991e82b29651978a6c59cb5a5e15894da303f1a8a80ca0a5bf1911a5948e5e1ed510fc5e41e993bfd0bf907b29bcb4d509717327c4f60ecbb7d02ee4ddd2ef1701ed55c2b01eaf8e93b7eff700fbfbd9d0ce8537a5df50c375a7ea089940ccdcaf329e126e9d3e9535cbf4b1a392472a9b3181a804e5be0c1adb127ce471eeb44ebb6a901eabac77722f011c5b566572a8322df2486554567b7aaa15a9559d815d32c5a9abdcc23147deb66b1fbadff078b76ff7f2f61312a79ec3e90452d709fe4171481dd251c0f04cad56243c5d7ef4f5bed6915a6a6dadf6b585dab05e2426193a2f0c611a9e4e17f99c9d4e223f7d821d45ee344f5e2167f8630c3d85221e122d8ade3dc4ef66df9cdc24bc4169de59cd1242a16c50cd82023516b35ae7103ba6704ce7d42da6281512d1472ea5ebe4a3c9eb49c59e30091eaff7d5e976f5fe8ae42b115e791f31c131348b3e7a2ed7a55447521fc1a79f6420c12ea9d78a27194ede53d8e54e324c1fec5161e83614e96a3da14ef21a66e0945d502779573d93b0846fc2f01d1e4fb9da307573f2801fbf7e36520f4742fb52685253979f8d92bd037efc96aea8937f7582bd6ea15e3bcd4b8532a342928f84a99f84e1e5374429bc092f3f1ba98f27d92d14ea61e8758be4a83f5cd58ba0422e44123a272222c13924cf1c3ad780ee2191ae95bc34f292ea2237344345068d7b1b6af7c23147f6b4d4e9ad2a75d4afe7a952f8a8db7b47e5f0484e298b3a65cfc32a1456c04c4e617b9270f4cea16e38deab691ae658005e9ce3f4d9d3299f4cce89844644444a232f8d94464a25fb7a4ba59152a9646f29546b49099794bc1496e071e6522dd55abae8f5a63066e6d26769a303a89d845544844e1fd2b4936ce824eda4d049a46ba87b6138e6c897e2166ba52478e4f7a99f84b25b297cbac7fd86a38f9c8eb245844e3a098fda2d291cb5dbdf9ff278aab7dc0bc09b453e9e2a76d11e3ae11ca7ac61d239509e32972373a750e85c78c38850e894e9c7987c2ff1686fcc010c0d61c4a977bd197adec2d9cd7cc308d7c9b95faf5d3fc7c9e8d63b956a4f7f624dfa71c022488691e512d6a0051655a464b90435cc720b755d200d79d45db27ce468efb6cf39e79c5d2882bf726a7d28b4448b3db1865b5abc815de6835022743f7db4dcf8b629647b103664aedbb53380e365b8bacf57b87d5491f196965f0446b25b3624969f123246bf0ca03ddd70cf0878aad069162f18cde2e57d620ecf500169ab45252af6a1e2449678a6c40ce1d6f625bcc1268b592e01c827771200a05cc21b6ab25cc21aa08891e51280609095b88074a9ecfce801146220042c6451c436847b95e1787970dc12805490bbf6b829c37a2e86e68b27192c66d19b4e654687559a092582e4fe128dc519c0514585ba96c042093980a394cdc65410a9d58c75274881594091fba795c6ea39ad9dd64e6be7b41bd662138c513b2b062728bf799bee396f2877d4ebae7af40ad156cbdde669ddf5b69a3bcebb218febbcd02784e7759f10fdee364bd3193aab18463e44f097f6ed923592806e50afc47aa5df6d7080997905b166e91f641671b11bd42cf352e61662942b06f3cc2dbdd900a42e6d568a41d22cc78ad0b13868c1f9f8c29016fb276f33ed2d3db537e9f2f0dc9e3c82d7c7e7ceee2c8fe00dd23049670b2069462201d5b645c8130e58f8c8a9efce7defd55e96ed6a22168b9de0353fe5377f86203a0687987cadb91bc96fdae947ed134f9a5973ed1a9e3550c8e49473be661884e4999fd16215739425754d9aee490380f7c7193e7c9c407268c3a34abe4673027c9c540c40ec89bb08e0d8381d8be1e0c47c085fbcd67b1feec35bda87dfbf08ef8bbff86d16d65ffcc5c166c17ff153b3ccf88bbff8aa590af017ef2608e3f2b311e32d7d3a9d4ea77914948b7c8622a77054c9a73f1c71e4a3c291ed262e3e7f133eab84448655d3b492cbf0e45b28f3c84b3efa6c9ce4f0f2c84958f336827ac9494654262e52a9d45d842922eb2d9684a9165122308e43994f307e1418ef3e1b2ccfab197b186cf18500c2dae28bc708bd165f7c46786af1c57f08532dbe7801c2558b2f0e23bc2dbef8fc6cac60d9e28b172fc2d053214c35f9b0c36697d05badb7b40f61e82a40a028c311944a0057f5b4cd113a808f84e3f3a439adc2319543cce2c16b9f8d0160094edc4d6f0061cd24f03008d0d36d41b43883c69c73ce49259d73ce39e79c54528ac71ca6b7b410a607e05b9801f9935d4c0f40006efa0c4d1785e3cca22f40023169a40f2997b2f3acb838b9d462c82041a103b88a0f2606f8bc11f20701c89e2c3a00b49602bc0bf09626c05b5a4a29a51c515d535da32a598efc945a1dcc07f8c6caf42492b6700a7fbcad0430fcd8db0ff01679db1598c27a8ab6ee88ea928424ca4328242827e1ccaf5123f34a38b30b04d498842cef2638e3f2b3e17a4b4b29a594524a1fd6e959f4529ab8f854fde413f5d5e736f2799566397d5e86fc41e4138f3966e492bf78776a25800718795f8e840708dfadf9555857ad04d0478e76117cd69c8441b4d0509d423015ca3022c42163cc15f699f192506639e3769e158ef3337e3f1b2f3af9c3bbf9435873c90f5809038447b4383fc31526d1220bc6d1e2cc2ba1cc32e63c693e14bb355f80508500218d9616e707a012de6871de87d08816e705102ef1d988814da5a78422989ac30084630ef9937b78e9f4b30100d9937bf8f615d18120bc40084e3e008628ddd451d84c20ea02e2fdd9b5c2926fa9b7f40e9b5d526fa5de6a3d65f253bb0ef012d54b4e5e5272af595cbce420eaf82597d475003c69483ede906a9aa669dab418bf6a19486597ed23a755287226b214094789df22dd70aa454a7f0ac516e957614a8bb4e25a43d4edbc863a56c9f328b0c592b7340e51f8b658f293b0b6587217a1d762c9a95b2526785ce592937c7e365438158ecf2538950a4327095be1186a85211a6fd2fb130bf9c3f7c61910b30b78181f53b321a13c12791e46388a19c6278c4b318b0ebea56184e07b3876295dd21c80a70cc89f2c62327d44e4a7137e717924926816d6e595681694cb2f217f08033050e41806a329d510c132306fe48461309a538d112c03bb24280c83d1a06a90601958ed15aa4a61188c2655438565304c9284b5576aaff447c2dbb7bd5e993f99c212293cf5a957faa330d52bf3a2f00b57bd32ef85abf0bd321f0adf2b2bf33764856228a6f4ca5ce9f748cd2d055da7b4385b6c7136abc5d96f71f6aac5d9a916679f5a9c0db638db6b7176377669d9e238931bcb2ba3c5f9192dced3980fa2c5f91b47b4389f445867d0fdee009c6f181818181818181818987ea2bb32701e86d28f3399621818d1bf7bef6e47a38f3379846160441f962d7ab8c31de2f0c51bbe3970c20608077700bddc4ef0a087cea19b3ee802129a90a13802045158419e34332984e0823c7d7440055ff061431e672c0945d0c9c228b5f840147ae0842c83ec60031d2ee45166616720831f18214ba01e62e88995204b2c60363ab10fbcccebd874a688c5b26cf17b99d845749975745be021f773007a59c71678c83c004739138d3359846160609468f1c3128b3c2fb3c8f3528b3c3f7dd4795b824e5eca9fba941497faf1867479512c61991c6b62b14c5826473bdd74f9ff84657236919f2ebf5a8960999c8bbac8e553291496c9e1468ebafce9348265724229104c61999c8ee4a9cb7b1e0996c9f14a4e72f97b4bb04ccea77ac9e5ebeb6f5458264774d81397201e673278d9e2fc0bc52e207ee9eb9819bccc372b2c9333faeaf2ab5015d65ea12f096fafd093845eafd0a742b057e847c253afd0a3c254afd08b84ab5ea13f85ef157a53c8ea15fa524802c18f3319c430232c716dd1034f29bcd22aeed1cd88ba62a1bb38603b21452ceb98198f2a3b4ef28bf8e1d0bd79cdbe497664ed8bd685b44b1d335973e9bebd47f61e0a6947435a4e77d92ba16bf25e68df8532df984c30d3499b76fa11964378d4704c67edb773f72da4dd1b61597b68a45992ec95fb1e20cec951afbdf4163a0a89a0d9be57e84561a82aa23fdc85aef5006bf4002f7bc5c3a3f6f96bafbd42b9e4c2d4bc692fd170a8353774dda8c78b3dcc8bf7177ba963265b97efa377f213e1b147169140305f63cd560696f35d5e14d6517843ea91bf7b347f9144227b98ec15efa45bed5f584f9a1c1e43edb26bd0fc45aa41c230d92b16c7749ec99e87c7cedeb7974687d1fc25aa51c2b0111eedbbc34aef41baec95b166d18747af14d2fc05cbb1ef019e847372d0dbf95048045d816d585544e7faceb544c32e2f4de47194635e6271d73606a009803a26658541fbcc30c1ceec23eae9ac61f3d056abb0e817c0f167cde61d4841a4d935412cf7bd532c37870352fac38606d45e7fa5cbbe62f0de1b148213bc40db6cf3d101480222bd81f433037ae9c82e6946f2b94017a7c6b41f7492359600654aad6891d2ad47c6a07787bab69f121cdaa2e7e1e9e9f1a127fd8c356605e8d323633469277703ea0522fd6cb8c4e6026551d203049512cd0c159e6993bb6e3f5a6c4e0a30e46ce6e47e70369c8d1497319afb916d54f2f5d162df1875594d9eebf9cc6b4ce52d94a9e6ef675e3caa89550ed85e7fc4f6fa8b75389b1d495b1bf743e2d28f17c8182f0d976a6889a67a92ba4a34b4d5a59a1f32468f2a259a12f783d4435b350047514c29d96c545c118a1fb99f2263ca70dc6b540ee0bca429526c51456a2aad69316d53115344314545ab22556951d401ab94e29cb1190302c31b4429afbd756e38a834042f6b734b0ff1fa2d027bed92a5ad7409a898214cbd0d7c69ab20810440aa9bedf2a57d0b654f2ba1932724f0641034cc61ce0379c205d9650279e2c704f28414af06f28414597e170309088804445b1cc7711cc79180a84bbe4841b1128d694643caa259ba08cdd24e8ce087090a03e4993bbab5003400502bcf3006b2256f10840e7810840e822063c84c225da69801724b771ec0119c81b3661949403f3a439ae52016f9050d4840d434031948110318bc40fe20551f2f3e0928fc98caa1c9052d6041142b50410a706842c1094c00450948300255687a420421f001820f38217f90f207698ad1567f40a6d88d49cc03c9a27abfe3a12efc3e88338120791fdc81fca1e47d5087ba5ef800b4f92102ba5f1028a2e1f1663e3dd4552f08a652bf28aaa8cce807d14115d9872c83e06091bbf9d9c0a13a714170aec863472383dc68213d55b8fa8bf0a9e330fc6d168b83ba56e707286b9cc6f9a12eed87f4f3537feacf8fca01d2e2340bb883b2385a900e28a32eae46b6734151455b852e1e86274f85f20f4d4c31ae86baac4e8b703527aec6c4d59080c0192803c15cd276462d28c740edb4d8a8a33008a44553ccea88e0f19eee4d58c70424a02e36823b5d8cb61adcc92112d207efe00e08e4c4fb5c7852626d87ba44d9f24ec22308e29defa06c84459886b009088407b87357a17c492976975fe85d576773a17ccd584745e7a38bd5133743d2254d7082c6c7d635d0afa0f63c31a4f6ccdc55a8b5d45590403b760bd3bb08fe3229a94438594a91142d765d03384f621282bda29252e5019dec7d86a35d01c93dae8724145d0ff424cccd396a4f1e2d16d9b428a222dfb8784b4f31edec3621e078af8fbc5745b37032202d06e1785af43ccff33ccf3be79df33e43ef1d27a459ba8eebf1766c7791775dc809693148f791ac5946faa3e8c7bc94dd48c84d011c69202db6ea2d7d4b3eaf68b1672d6e3e262f515df5ce3ff9bb6a5e74d5c4330b52ec32b421f70225f29c2128453f2ed7e3d32bcd59c1f5648e2415d25c12ce4c329f3221914ea6d235c1d71b096546853777379fc211cca49bc23195492f85e333098f37c6e61b9abf5c7c14eed07757cd4f7a17a16a5ebe4cceed782dfa2192a21ff24eaee7099c9594372dbd0a45a22c88642d9534c884ae64051baac515b9399c91f3e1e41cab4f1dc2e170389c0e0784e3e1ac20030f570527e384703edc15dc8cc301b520c5c020d28cc32171385fd0a745b3d0d79f1aeaaae77486348b0f75d5f7b468c59ce5b181aec8f25c733822e0a8e0aa580387c3e10c01478d47e3691621a59aeecd0ca915a41a7b988b05dd20151134cf77200751d77c755e906ce91aca0e6c162d37d82c77082d631821b62c5f0497251e3990279e4e884067034307ea509d9fed87bae415661bd0a6c5a5b951d4e4be50e4aeb93fae14d766fb190119c9463ba0cddd7e6ca8ab5f935e7eeb6619afb7fd6091fb1b16978672fb3103f8d32c57803d1a10bafbaa06509e874ea67f62eb0901152e64f9f648210a5b8f8b1b8569d3032b3a6f6a73ce39e9864f29300be09dd44737f3d144aff4e50d7de4d0dfd3a640a39c12488ce1a1498a7348a03c9f6ab1818c680228f763b4c854966b66425e091e707e94b36e4aed5b9a621519422c0105a050026591ba6e28b1c40ca92cb774d79ebdd1621b91318e239a003a2531c71cab76c5e45513a2a4a2284a2981644d15b200a5b41848468b9d82451580e3cd3331f8d8993ce3cc5462157d0e03e80408a050d10ade3a85eac407ac90b23a43cc297296fbd5a33345451c0158a528af14c42a3a4145eea7d45bb157ec19c0fe28ca2390c0214a794a6995a214f37c8175770ea4bc648dd3e6c6bea5e5ed5329a9c5b55b4d48a0182d6aa676caf963d6b43501b862e5791bda9d0727623cb92f83069dda6b9ca7afbb8d2a32c6f92a83cea82a5586cacea0d54ef1fc2daec87d564aeebfd00fd199d2b0c6006cdafdffb21ca8e461c8bc16a648bae2192a53454695021c55ae8a8aca1dc1bd3d13099da59fe10d6ab1c7bc9f42c0f106590eabe86786b139c7e4c937081402f6803c1d9dd3ca96972673b1ed4868afed1382cb170f596c3a983f7ac5460ba04607100f3b53889ba7ce74c12f1e625325ac71a0947ef2887e34cbf8d18c7444528c70b4e0c9fd1115a3944db599728e70e64738d43543d033d201d22c3c232b6e10cb3daa22f748361232ea19f98cae18cda69c728e70505a8cc4504123334965239c91d90867a4339251977d6d40d2f2b04196a53543ee5b1de9b26010b9bcf5b138d3ee20d4237bec4eeecb1bd43562752cca86dcb26897e679a7d36ac562a5a4c89041238fda494382b6faf782a035e1623316d43d357d99adf96ccdc51a5b636b4ed607895b7bfef594dad427d247932cdb7ac01e3550eb7031ea0acda8a1adf6b13e1247d12ee9f520429e9f414345869872566ad5b646da1ed9eaa74e784cc99e1bd28274854ec2a34950a80734431018443f641d087e34b9bb0b8a7d78ec410749df0fd55057b7a3435d5d6a4c815da826056a145f6f24fa1186ce87ba463ab4d507ef08071c753e62f8f8d18441e271a433c2192f8e8cf441fe6240b6e43803828c35205b72a604332bc8f3dd4eb7d3edccc7902df9966f27a40e00ae64d9fd40912d08e4395220cf878268d30e49517a1ec8f3dd385563ea5515463ec02f9675e81774e4a49204546da8d869962041b9eb14b9bb02a942aa9c9f8dfaa3c3a203ea7e648c1b70b95f6d74bc9e966ee9f1569b28ea0f2da0c8fd2a459de2076cb1eb8ffa63bcfdeb7db12c5fccf4dc56a0d22b5980340055ee20936da06376b062344fe78f9821ccc481048ef951f61c31e5127277bf255b8d91c0d162e3b8140cb70e4366ccb5fdbc6e4ce719a4c52710db4f6e1db120284634a788f07a2008822a54a7095580410c092a3d53d8aebda505e03823db5935ec75ab67489f8ed1618adca751b37ccd8fe21b047c4ea566c5337a80406fba534d17e33ef1c8aaafb4f6bda994fcd7c5ded2b83fdcc5c28ea6f3f1b18bc95f1c9addd775342d76e7a3459a6699755696fa8563e75adfd174b1ce328f5dec5dec2b0201f9bb113363cdf5de7befbd74fe68f1d4351dc526a59452ca6b9ff2da3b595160faa1438f8fd72f8063f759f269b1d463daa1ad360599b438c5b620a0cde3fdf76ecef1c3a6a02dc0d114640a0a5d461f495984c374ba09c8f4435da537cd7d995e0a7d8860c6cb84c1d3dcd70997e66966bc4a3f853e44705fa5d3cc7899dec9ef3b292c1d24bd14822f3cf2b7043afce4d114336971f291fba48f3e3fec329a13dfa8e66152f6e200e91ca8fdf908c82db67891fec94ff5611ce0277e807c813802087891b0a987b6fa1389fe89b0298f2a1ce0a822a273290b19a32f9790bf50247773fc3e9a4b5774eea837c399c35c92d9b4d336cd035e9bf6ba1e0e4b7b2fb4194db25c7fe76568ebf531e6b83f738eb3a61b01387631f9d5df3e3a2dbc588b3439f4d043223aa3b3ef9bed7c6c9b290b85babbbbbbbb1b7777777777b715409bd1dac8eeefc53be094d16bd65e1b7007ddfc0caf1dc0f99a515e71858f8f1556f4f40811c2430a421aa54c239168540ddf904af886f498935cf14d6965ce51864a2eb975808939c9377d242cadef1fa1d94dd3de37e26edbfb37b89be983087133524481032570efb774a1d0fb34bc6e46084dc0628adc9ff179a0f7be0cd1634ef2876f404c022b7cef1d33df808f39c9227c43c21896f3d2430b3cc8f439a3c3725e3c60853be4885c5e7212cd52b18e176a9b756d7b8b77f57b2e1544b3844e0fbd03df7958c70bbdf7dd7f22ace3855e47bd88658475bc50ac437ef43ea55405cbc033300ddc8283c037368ce3082470122d96dc2180a2fe7cd0d18b632dbe5800376cb500d2d3b7748f0dac6ca7072adbb724a80eaa84ddded69e52dab3a94da1947ed3aca6596dd3acb69d862959934076aad0a102670a1b297e44d12c3562c876db68b55b8f874577ad8079e90cf3e2127ab17f9919e6c5beff32cedc2922ebabd409f4aeaca110869187f10ef31d267418ee30a3c36c87d10e630f530f732fc2302fdd510cf3d21fc5302fed1de6a5e5c3196b91721dac1b713cae1274bb3157db9ad8acf6d25d97a82f9ef379b26bac3a7a99e2f089b4ad342c571657ac222558025f985e6018c6b01c1b8a6cf826c4b01c0d75b711eeba4875f8c60586e57024968a6f3a929c5ad283e5a94ebd4c0a73c0509684d73ba55667895c78c32d0c99fc2514aaa1dbc7603c629ac8c1c412a1d0956891ce39e70a3f67c3d3c7a49950ac56e16af5d5ea64b572b15a99ac98587d899512a19026f4e23d56d347d77811c2efb19ab1ae81318cd563050b4387f558f13886e5d455cc0986e5d855132e50a7cfb131d1354c52a75fa26b9884562739bd125dc324a4faea3d56382747979ccaab6aaf8c84a048985a9d25a6509199af4b5de864fd0b95a752d6294bc9ec9c331915aa4c27481599ee647a1d5200c994d513488a48fc58debb5528c59d2e58bded6ab5a5e8f2fb2e3defb2eb2e43a14b8ebbbcf7b2d6cb6dbbd4b4cbbe8a0a144988f028afa041a257a48f8f233c3c4a2b660c478747d903332284472984c78d5eb13c31415c3cca204db4f48a95e5a0d12b349898b1848c5eb16faca2325150260aca4441992828130565a2a04c14948982325150260aca44419929295088220d8be5e39fb1d50a964af1389d6240b009cfcbd12b1685895eb128f62098af257ac5a26019257ac5d6df30428563758409122e9238f9cb8d2988205a5a68d0983143860c1595132c034b992f91f555102d3466c850e9eeeeeeeeeeeeeeeeeeee1ec16e4662aabfdca07cacfe7223426302c58d8bbfdc9878f048c5c49034d14429470e12134c804b7c89d1351698970d2bd1a2fdcb0dcab5f106cbc0524cb00c4c5c6119186b35821231898cfc233f39ea2e2e72939fbebae93cba46099681a54ac2a76e1fd3354a4a48f0496edf44d72851bd78c9ed739448acab6ecf44d7286119d8ed81f4d2ed97e81a3d601958ed61847225ba460f2818a672d60b1cfec485c94a15ca5e2921498da0444ea1ec95d20c19a99950bba802e50148036ab7db2982645baf63c32375220636b2672b80d70aa015401d5be0213795dd2a544a652d06e111d26385cf15b3213f5800651134b588f9a081a2268a3cfb479eef993558c7ccb923b96491843709e03cc949469259f271f6f8b8811ab24bea231fa153d8820a3078c9e4a0542217516158f569831586f092c939996eba0ac9556e542ff9ac30e84117b8f092c929914ed26e000617f878c9e480a3911451e040092f991cd1a715a10938b079c9e478232134018b295e3239a129071f6c9187974cce258115b497fc85c4deac30acb3c21db6d8e2259343ffc45f2a2c93533fda220f5ae0c1ab048f33c3f4c8257f21c12e2f5996907c9cc9241866641e0685a54f9e8731e1515a91e7616046f330220ce361981086b918660656c132f2386b6e146a6c4adab2a1bb5300e5e5d619019470b0a413106834b31f45f6e3377a3a597636598ea11afa4a3fb1d466b6a7659f4af9962deb9c5608c71b98e82fb76b781896f3a2f17ce0abe16158cecbccf7347ce289bf3e2ce3230fafcfc332de65af583cc6f4bd0ccd5f220ceb1122430b789c787db887c6f3819787732a86d13133cc8d06649006226cf1caa9bfe10d77cc7ccf853a6686e9f0cbccddeb7584b61066c7ccdb634ef2bd0d7584fed2e11b1d217cf361984cce7d8efd137f793995eb00195ac0e344de428de703590b9f432fa673e3f1b9079de99a0ea19309fd89cb74db65bc3f7199ef4fc888ea6546397d19f04ffc25437a0ebd8e997a3db0575656bd32b9d54d6d270db41e965284a1584ad9e3cedc9e77e85ebad3f0e865eddebb85421cd62eefa25d07fda8f232ca7d3a05534dae1e90b69e862e3b2c0232a5d4da0ef0802ef43aa8bd46358d523b7113160aa0a9b910ea46589ebf4400472ec6c5b27d0d5d76d4ace197935c2f7357eb146226cfd10379de20a04bbd8efaa29d3e8c9959ca18bde365cbf5307507cdfd02cbf43339e68566face1708a87ddc80e6b58fda6cb43db27acdfe1201c41708385f2d0eed60953a81deadcdd2042580f5e586e62f188f59147e90f382e57c3241204108765eb01c0f76861f56087ac172ba19200459e10e2f584ea80364180111f2f082e56822e0f9c00b96c33501cbb97fe22fd8cc2b671b67b2c5301f5e7938d5e15308831af6387c372c6b8bf65ba881934d032799c3e3fd8e93cc71db7d57995d76d03c6e995e5e2680f450d0c078c434918389259490b488e903ab86aea9e49e00db7ecd4d70b6169af3ebaedc9cf30b756f5d43dd950bf5d75c7ba068ebb6ad55af451cd8bd81dc1571dd7414e2b8ae1bd7758a341beab82740108f6d93451fe1d1dae4be27ebfee171d68cb6078f34b6c934203ac363f74ca0db62d66209a0828c554305ce143652fc88825563ed6d4dadf8a5468e9999652363d0cbdc79206b34994340be404079f96eeb57acb2b743c89cef5b7a645ddaef981f739462993bfdc8d271d961b308bfcceff860f00e9a2d1e67626e8777d05cb14ae616ca8533df50663bca5a28f190b7702cc532fde5015dec75ecd851b376cbf2818c518a650d8fb3266bb3d9cf0f1050c91433d164fb8b03ce3caae8640b94edc7522cb3a0c8f4170a2014cd32b26a58342c9bfc04b047aedac71798562bab26531728dedcaed0bde89859877d7d8f335993b32cf108c2c0c0c0e8a07894cfdbeca6b4522aa594524a29a594758bee2661ca5f1fc81d506507a4b8e9a4537472d4b527ea4eef852edc488ec21ceeddc7719cfc76c39bd1bb6fa38f156b9e370a47a391271a755f67b1e89b27bad672de5fb8bf78afda0dbb5175119d7bf77e8ee8d7b6cedfaf6834b239a25799fb35dc6ec7853b4eaaf69d0b779c648ec31686e3bef0a547a632d39799e9865dec35ec62f14b2ae6f0d04996a6e1f997d0756cef4fe9e2dd6f07aca28b3e7a7dfdacaddcb9d759035ee66dc3a397b750e876a1ee2fda756c9fef70088fdbc7b671095d8642f0e0ac89e287143653e050a153c50e1059101e213d56f85c311bf283c54e0f46df45178d2a2adfbfafbbbdedded5841efae8755d88db6a0fc0fa7b04d0abd7f952d05d238032f7bf2ea559c697fe288a228bc5fabf5aad52a9d4e9740241d0f3bc7b6fa5f9abc2725efa2bf22625451445168bf57fb55aa552a9d3e90482a0e779bd326b9db5ce8a657acc6951d049d6486799fee2b1e6bb5d0776b135b96edb1d2b8775707fb9d7513f5dee650f40ed75fbd6dfb6b17bf2d63db4077246db6602d51d70d6e471d670e7e8efb6757777777777d78ac79e4cb559ad33ae08dd14c5bf411d52d67aafe781e0e9944aad563f8ba523a5c5390770ce7c3a7a557e997987cdf53bac0bbd40002d1e55f2ec91e5778700ce1ac8f2d4319f2222c13ae2385646a46e9c82005b3c1a1746479dc9b707a014b33caa4cfc329380658a694f0a4353b24d0289237018712388161a3364a8a488acaf522750e6faa21da6be0a91020303531f038fd69ee47126bf20205b29b3b8e26d0edd1502c8753fc0ccc432cccb734ccda28bc20b0470ca64111e65b2e895de39f3088ebde32595e90b2c8bde3f5914c6c8570714bda5616060606060606060a62c73a4704a51ac93f7071fb9a767a5b6d38b247f91d74e9f7253f217798b6365442a75e3740a02045b3c8fc6bd33eaab8c8a5fe4555a9481a59060199888654672367c8486732c4ea2453a3247e8c81ca12373848ecc113a32474e7fef8c5ea13546b00ca9d22bf454222147de9dfe08b157e4c8bd1a2618c6ea1539f28fa5be57e4c845a775e4a3d307513272f0f42d24a4d3d3d84aa79f91734d355218767b451ed663e4a71a29197a0fd447de6304e7e4e887b03ccda850f6ca94f22261bdbd326f0abd390a57ef156fbe93b316743a3ac3bc741e6f5244d657a913e85d19d92bf33931334b8965bd1e784aadceca81115b948f39c98d535a6c39742929a27816eb5fad56a954ea743a8120e879debdf6d5621de14d4acac529a2b86191c5cad130abc5bbb8fc6a259f4aad2e7f3aa92e0f82a94e915cfededb2b35557ba5a6b04cbdfc0ceb45ea82a5f448dd7b3dab6b9c6098d823f5eff5ef1a2e308c65f21ea955b3587c638261ef91fae81abe5961588e3dac47ead42c1bbe51f5489df48a6f4a302c672bbdde6b160edf906058ce35bdfee670a7d7d7db2375911a2418567b651ed6bdc7c853ef91c239395ebd3c124a6fd5622d8527305c89429617a6842e2a59bee8719ab97d6590526245924b566afb08cb5da158b894084be874ea4093e79558be4bba048febe7e56b38deec38c9f5292925174512ed3193c54a6ddae5ff91fb98af5628ee31a9944888bbfce974ea1e038226afbbbce7953eeff2f792448f99f953e5801866c7491e3d666651cec431338f2ec3300cc3300cc3309c3323adb5a04b49a9a2a8b158f70fad565e2a253a9d40102c79dee95ed47bbea6de13eb98c97d53f2ae7f4ad7b0580696b255edf6b5c686656022a7dd6fd76a705806c6ea6ee8dc6f8d0ecbc0fe856a7c5806b61a7935465806962289c08f4e2713886130b08609cb04af81a8c44b96b6518f32452300000000009314002038180e888462a17044ae8982ec0114800d94b250765418e8495021848c2184080000000000000000c2043963b34e3bc3d9965a2eed286b34e6c94b5ac4d520fc917a03a6b6211240fad25ab7b1ff8e2cf0c76988ee7a01f9135887a526f66934b3aa4ef82dbd9a8c9e8a3d1db69c4d8901584fec314a6328010059c7950275ace3ed9885a56601c109e6d353ee057f223bdade96587ef6d9ecf802494f8e3e6743003006a9682bf370873752d2bc63337af7f1d8e5e2ed5c378676dda28ee4a92817351d5a686a48d566534ee16de4800d3555f9592e1877de5307fbba4657d635f8b60d34b19054ca71fd59432acaa30c94bca883fab89ae79173ba88178b685ecd716813d85cbafb6de976f24d6ee32c201d729b6cc9f82db2ed36cd454255e8604887dc512ccfad85a62d94988a8aac6d668040a14fa0ac6ea7575542dd4f030407f05677f5254e12d2bfe2dc1d07a1ce97610c16520248158b26498ef9e59276a996d8cda013d8adf1cef9e96beceaa8b8975a6c1601455ca8950c1b4027c869429857a11500b96b2aa66a1781d2b91918ef08b903728f7f82ebff3017dd14b44442402d40b8373faad44132ac256feb0a20b5dde9a07ad20c4694df9c49bf01fa2fa1adefdf8738541ef508e7b4fe36035de72f985e5c138409d3817a3d0ba3dc98bb33c0ae85f1ffaec06937bd411d4288afbb0d9c2c78e5897ea85d26bda66b9965000cf153da29cd6ca6038c2a13622d2a6a28c19fef6cb2caa375e78efbddb0b715563c5709fb315ae8a57a47ae7c6d36408f42335b4e49799bc0c0640fbb317dcfb36c7cccabfd055c55be264274ef0b27f64e0b4e98a7559b0f67a298c5f0e186f80ba8147b8b64511f2e41032bda6cf2e668453382ad220347c61074af892afa8fd04e1307115d016ae8d4c2b993d719190461db663836654c694bf96c07d5a8247b852cd717c6a43cb331b85ff824d1353593507641b7d4f50cd5f727f01f6e3f04c491e5d7c69effb7d9cccbe8a3ee1ec679889ddd1f60f0c6acbd7df65eccf82d70fb89f94501d77a981dfbafa485f948fc553c98fb925fb40373376bf7f52f9778f91af66541bff707be97d91dd03d85f3b22420b4007b19058cadd61e6e09dc00683632ab1b2341dc41bf723e2c54f2a0e627ab25be20a54b1592359742c9c7bbb3193cdfb63e53b22d25eea24e284e0f69575ac9f0ca972e4b268fa92acb1c00664061882ad97b00c2b245b74f0f5fcc25132dbcb711a96faf8619db6ad8601fcb95690c12b9ce75aaa8e8949451e3d73a9d60c6f9326bc67d70e59bf522388301330a7c7a17bbc4a2ddd6b6c01373e2358d5ac193c856ef5eaa9e74c47bd45539632bf09b25c6895d2a74b42a3f8a4950fd84c624198fe408707b66276794031f066debd051d4d8702e47cf68745e23a0fd51bad191bce8ace93b5b0162598a836c1b5160abd7121921589b2bd5c0c4f967cf1361724fcacdfcf2eb0e809fd2182c786035f73211491032fda0ae8ad91910ea485d5a4a5af8fda726275c440591fee4c0c440c8fc4f3e119c282a13820f071531c9d67165ba9c3594968a261504618867bb603686e1770c9916b2daffc2383aa9ef85382bd70b04f780fe02ba05922591a0fef742ce482e2c4499266a134195920b5166aa4bdb188837a819ff4a8883f83262d3e5cbd68a1fb34ca2c5b59615b9bf8d13295c309129fa08f505daf80e1cf47300c503687e188ff493a0afca9c248bc11070228f81addc3dc484c11dd5405a4ca5659665354d652792a7df17a6dc5724ae77baf24f87dce598417d447b87b152b7413b962f8be36e95c55df10995ac3e86d0a8f54439d893b0128065d7976873826522ce1feedefd5c16fc761b18c2f57edeaec88fcff51a7d13479e80eb6d0bea767d70081757efeeb6e86b095a6ef53edb45eb8ba0bbb317d331d864bbdb1595655e45ce0e71d87cc9bbddd308c38d63163b5a4a57618cebd5dc302cdb358e799b8e2249de225e7269bdf5978561b6ccb075cb4f6b1e1cd217dfb3c95f5d4c98e104b748dccac8e22ede653def46aaf3c62385c6827dd19291dde90b32a464cca31107c087889d49e920a616b6a4fab9a53c9c8500354098e4612318a2b6613f2b7459e876e16cd5188bb7202954e942a089b0aeb4124bf97e12547bea569404537407fbb255ec362010116853775eab3b1a04cb5f62da78f05036398211f47f3614ec5f39d4bd533a8b95c38ea2dd028ff79cac277a88e6133021ffe18648063a9abb9f05a50698ced16442ef1d94d8f9ef1c5612649a3ed21e590fff83cc335c25fb0cdf887ca225a29efe038987704af0111c91fb88be912a6aec9f161c6dbcdb9027e958551241149ad231070086cbdb5b4518b038d20f51ecee504610e001db5910a710d27d1a18452a405a66468ba0b13479c35b22410a53f60bb396e15d52fb56cb5a3c636441f3b01ac0c49186057978b6e279688660e80861803c795b301eabe3404b2ac1425a3da1ea11770e25e7fc92740e2e8af6d503f65e3780b5ffca1ebdc4bf70c4dd1f41a3a43606e85a4b5315780f33735626175434c88bcf16f13c897d39cea8e3b7a57c806e09ac1c1cd4781fadb87597c965749e3b968aae6f2c160e7a1cc183b1a122bdf0681576629a946fe882f23fa5d783d74245e487ff585c65d50d8b6e0235eb4a249ff291fc900fe5df513164f95ac1f867b71a5ad3d3ab0150b22b21cf75c73d6fdadab6ed9c13be2342be31c5a7ea012f20c7cac5e91e59c3a0e9085a8dc102f5fccf44cbda7288edd243d85d52eb23f2514888c153b5ef8414614fcb8e56369698e9acf695de85b6ca6a2d55158dd6d62a3f2b2c3762d6670d49dabb9ac972d2fc52e9f07eea60397d2294685e13e129a3dd47980965dc458f789d4eaf71e6ccf0196bc21570de5d158b06459795368f48cd2263294541e5280307d106c0811a90ee8980ad4e648d0d8a89fad1a2a454cd0435693018f58e342403d364ddc0d0d67e46d354db4077d0111406d448b2eb378788e1760a799befb2deb33c1b5621b3f56a4eaa1656e9d80a46341f026aa1748a69264126f868254f6d57e6cf20ed3e3abc315507dd3531e72c2248ddea540bbc4157c512667c123ae6049f13214a5ac4b771eafbbfc1fd5088766559f2c4c5488ad0b423e623ba3ae821ec3b85e53f12837512224abc48f5c6f8722b9c82a21702d610bdd3f9d03150fc6414c51fb90c2d5b8c3059ff5f6478df919958a4f500d18b2f26325ddaa05845c5451e204de4055c82b5f8013d868071572e514489f66fe145b774f83904bfa608222802df7eae2248ff1361dff94d2bf7d1092c7be720cbff832d88edadeaab4999e5802a9c83deeaa989b01e799e4041b8951d9c509219d0866192c050a7038690db4fc7a59f08cd136a6ecaff9f6c03786db8ae4e96622294bfbad41045e4f4e2db5296b1e34979988594b8e251d7959857e5b06b62e026fd70d79361e9900eb2a15ea1ffdc197fbdb3a56664c71ca8f60363af8e013d36858e9750ad0948be4d4a3ddd3ed680bf0b9d7a9142f0bd2df82da1901fdef063fd37241859aadf23706d419174a37c62bd32b02a330000957661f98cebd3695964f5b50d1ae915411f8b56e869100bdc939ae15cfdeafc913dd97ff671eaebaf3348d56a02dc578ca153733e5b1e7c26ca1d9abdf33a4670aa9b453d6f49064d9df1dbd2d967b9121a14c84d1d7f1b20b50bab8dc73416f36e647036014fb66674581807baf56facda270a672b98632e64642119fbac1667b6234c1920f288993f00681a06748bf1bbe0589d315f74b6308cb92633c03d899d6ce69926bf4f6ac897f88c1f13c328a790a2812ffec144025afb701473fa95e8c104ce0ca603af21d605958c20312d9ee762739a6478b7b81da2b8379e847ae396711de3fd84c17cbddcd1bc45000a55f2be5820d87471d8b948390df0f7882367d11207ccdb2c6c413af58f1780c457f82f5c4c3bcf1229988e91a0853a02067b390931dbdce388ffaaca2eed6dae0e2d445527bcaf7bb850bebe690c173ba68d6653c7d326cf2e08e7f9e1c984f221aeb771a3d69dbae62a89f3cad673a83ae3c9a3c6409cabb03785fd2ba6dc5c1fb6c99f3241f6b3bebdcf6ecda09a2821f42f1e5a9cf99189ff2ffa2c843627cd994c38809150f9bfb92606b2c0860c25c2e0aceb52af15d723b342129ab3e072f12ace9b15410a5a8fde69428676997e3df966b97d33b108fcc2dbc87810e806b076e5ded00edb8040aedac69a855986577d0d95c3b47e9eff76c5377f7c447499ee2b3a6d3324b05561efdb0703fcef1efd62a9eb2bd44a05bee7ca8ea5ceaa8e7ccfee17284bb64eaf319c21a2270c1354f1011d74c6b007a6077e6d2ffaa3dfa00d5dcd15645ff93b0857eaff20e34233425eb0b9eb586c908e46f6c7818f0fc2a24d554004109f2f6dcd09aaba7afc04ba6b2c37da1556459a5ae8adae5e4c60505e770e7fb2dafff15f2c3021fcc54ff0c82bc5176fd0c9a9f2b5451fd36cbc50126ef517e61f48879eaf277142a13480659db83d0d0c0328b02979c3ae9c2f1e2bfc37b55a7c130268d18bed9aca50f18fb60aa7da54c593cf1715dce9a2b5421b5d63907edc64f08f9357cb10e7b4a5bcde39484bb0e612efb6bde8db4556d16d501bf4ec8b0f0c6ea3d70cea496f3478d5937e31d544da86370deec95e0694d7b960eedebe0b1556139cda4acaed0d71705fd00a58b477889da94d18a00158f3e49bda2edefb71694c533fdabf23da09b122c4dd6c2bc455604df74f0539b156142a74a830f9beff20490b7f8a2651ba95e301dd89f95d872502ede7001dac9f7988a909b650e140db85d35dd1e2cfde21a10ccc261a58ccd333077d6d69ebff4fb269f115c921153449dc6c5a018bb9f49e0f68a0c2e5de8f067917f9c51f18be48a5f75b9d834e6dddf5fb2f3ab5f01529d782bfef41be4e7d0264a9fe1d4b29761589868435d389e4eae087d899ec2c66757bab83a4b20faa3d7f625561bca140c5b64e8f9a7e2b00f1591f494fee898e7df7779f5b5b16f1b1d1beb01041c67ec9328efb6fa22e55e1c4e1145fc98d560930901c93943c9a496c8df5b6923e86e175bd8df0638fe252adb3bf5d74344ea0267d1e22ffeb34b1134883feefbb67b8f71fdb1b3041d73c52864ca1e9e0e9add46acb2da8c61ef80eae470a0575407bb7cfea42007d31f9ceaee6a6369c717022af5cf5646c07e3edf04a187fe247ce00743370a4faf2fd077a37e5a6f239348b233bf37f79a9c37f69b4308c561a14ecb07f366c15506ea6c72f842b25aebcdcd43288c947af0c8e8e818c66ff9119579c3aab4528ff0cbc9f5bc51a457c0871e729bd4e71830dbd45b4143749d9e3c60f65d289466826fd27e41fc7897893f4f67ac6b10a76d09ca999fa8c12f6002e8341089caa06c7acebd07dd0945280d416b6cd442f04946b95adb6930ff39be402a618e865685fafde6bb8d9d559f8753d0d6aaf74cd7333fbc36e9c08735638f6386214bad7920ecd56a1e6b84e75e707a0342ddd60d54dec369e56d40b5b3c0af58b3ced67928ad70db982d5882dd1de37adfa6cd25e3c46a403d9e7213042a9b0ed022aea91512a474192fa6f2c63979ebfa348bd7cabef35cec6d43208eabca5e194aa731d02caad119f3af105a78f37396ff40f1859d3ac4c40feb4b6b596b1a45a7a9ca11a0b0a301de3faeab06085e8e667408db67850849feeb39d99c6539792860910001450d3e4c424c8050c17cd39b61e7d06407e39a510e476a27c5aec0a398b8e3fbb730540eae282cb270c3c4c10364a71366708aed6d64af543fff22c8ea44526cff9be87d078d96043f7d34d0d507b81fc8f353929c801248bdf5f09bb35359f098a680e1365c3c47cbcd497d0fa4b9a4ad3a1678e50dbf1f13aaf5d06eefc6b6c4802548a9329f2d26f1f54b4b5ae5ff7d4741fbfcc61d42832eb022a3bd7c540a7c0a6449ff5cce8033285c4b44e1718ee5b6473ddadec34281e2bc8aa151d858d435960674d762610a3f0b239e11e3ab8dbcbe86d610c79d44fb94a4b4bbafac9174095623cf782d56c45c94dcc4fa1d4655a5daaec6253cabe6a616b234cc7a5c54d2db5849ce6aec5d645f6081e6f097c9f7d44d79c6e7ae929193bbc82a8eef340a3e4c260dbc405d6c470654dabac16d993a1ded49bbdeee13548e180bb32f7ca3ca7a8f0594acd7ec736a1b67c5c8f324663374947b2f752afbc00011a8c1145559f7bcfeb0c8e5e6e9d5d0f4f6f80dbb7167c4049085a7c4d276d9ee419896e463a132336c6acca73e2214dc0bef3dd73611abc707411ea5dcda7e1268db1fa0afec4757c28bd0769cdc3c721564b13783d4746d08359988419b578eda9908bb868153d5357d1895ed7eeed4d38a88be6248dee8747a1625d46e3a27756d7e10819319ea24d7e6069a87854225efa9e1b084e9ccfe4a37e6cd3d6de28a1942df2e2278185690cf841b343c68e52bca37d863f0f4dd1b02c78f1fd86a8a30179d59525bba4c1a88e879107653cf1e05522973811718e38bd4278bd34b6e43c3b32875bc36e045461a7ebb8d4b472dd0d4ebaaa8db6bb5dc218c9b8c7e2d4b4f41cb07efbe2f903b9016e63645e4fd3cdaf7bb220b8d2511660435280c705cf6eefb0d5ed34a120b9377261cd0931efc1d097d973a788b07435a0ec2b91a4d089defe7868a47140f5de969e50c1ebb61a43d321aa58b85aa8d2c1914fa8a08cc99e043d755d0d1db6c0cd4a550081be7bd0f5e8f070d4de851206f60fec687fa7ebe20af7550fd0ddf417273fc4c161c9822a9302afd9626fa97fa9f9e223bd6678d01dc0ad134da04f29eb3efcfe63c1ec44d293a156f721f4cd1250cb0f7fde91c6548d94055a6824a750f7b656c6c8c4d2fda023e9db34dbee9a94403b75d7f72c2693f8dbbc7b6fa9a04b778fd180d9406274d0b4aeebae3ab5c98ae19069c2a2152900f983bb78cec893e4424a0f8a8eeacef1c3dd160fdcf5384e5060518eaf7074f0f8db2d3dc876225f690c9b8763e785ff66088f906d384e9940c17f74088e8b7fc7e52f565bb102675d06a2a0d4a807718a62f3f3ab1b3e12dd07f16785bc0dfe67a8ab36ef666d8379d1c7d470ab5d3a59c8ebe9fa6c958cae4de18f15af368ba37cb24f49802c0d6885e449aa30e99fdebb4f666e5b7f2b59b66f2d6d7f312b71b1afedd77ee32a23595f81d59e7863b9317b8aa085f7ae0719d85c7739b7c6f6c4cc314ad33a4e0405eacfb5522a3b0224eec942554e20f6096220ebc58f90fe94f451cd08346a7d394f37a3be8d050f1e512d53536c53e679d50eb9837c39d63c7f6ce3eb061343d40051f2003a42214946b092e458dd0aab6b46b4eee5156d0bb92ed59272243016f4880b1a6dfa84fcd5b34f5f4266ee9bbe713532bb99e915d567a5dc5c797523ea173da981f4a85264c0cb5c0dc42ec55a1b701fd53c5ef066ab412691a406c3b0b4cffa2a9e3ad684bee29439bb6d2b0fca688277e7334bb81f5e6bda54c48e0e56012213b4ef8b9e9b091aa561106fee2fffef0fcb98e345e80e4bf39ccec723ccceb806ac0bed500b3f101cdf8922b18ab5295ac1960ca78d7853027f40e4c80cc112e1aee608ed49ea2a51afc3b02ef0e47ba96184bedea2bb7c295b4898344865ce5a627e54290a01f6c220be21b49ccad922fe5766a777d755ce3da1f183a6a6dc1827f7bd9ef8d1126d974950d0064e7aa44be90a77219b8c16f8989129c0f4f603998f369bea4e191e9e4c402f71c8603abd2905c7be087848f6f0e383725c135a4e869f7b82a86b78ecc4bbee1e7978adca3cc157effd7aaf8d2723b94cd7092d9f008bc30ac899ad0b9670f8034d4c192707a854f9225e576b14f0618d3a2806553aa2269b695804980979efcf7522ca4ce03721909a279444932c642d8c285ef545caac3c2c83e14c1c4455524b4ece86c15248e9c7b4e528641bf60100ea2ccf90f88b92964ef100aae9db3fe56704547de344f0594157df3c5d7c6600d537cf809f19417f5f5bf26c7f6ba965b2a7d57702af0e7f7688a251402c1eb2faf171b60f4e99a52d4151939c2d6e8ba924dd39ddf65d6a9364456d0d106a934c3faab6bae98297b3066b684172e9a525c75d786bb4d1a902dd37358872f6df6b99cbd0d265cac5a6baa9b0388e1cfd990d4c98c60f2a4dd4d23248b4240e9d56a67bcb6c0d869704b47d9f088237924a18f203312ac4bea08146770f26522007202e700f2346e244ee2544442260fced1c00a9a9c095cca58c7fe1af89766bdd6a21d3b8d59da2bf5402d75e4245715ea93a9f362f0bf9ce8f5f386d395041cf803af5705b38e0b04bd5d9fda94b5e68a3fa0288982a8ef7ebd7e9e0ba9880d5666ae27dfa28320ec1055e0b5170c8d9030abcdb707a76db42bbf19cd8cee58a4717a81d08626fd20024333bd4f2228ebaaf39bfd08b95e6d71180123401c59bdc486b3ae038244f9160b4d148b4e60705e2931c1d7881ae47d4749b81c5ff46ce014fec8c7b5b331fd8fb2d467036e92611531063c4892ad7942b05189ad4855222bea89cff4430ac229b1328ccb6dbb0596d360e0658caab6aad48bc7d938c91a4931d728aa43af95370932e674adc94cd4d1b77ecf5fb155ce85bcb39400233e56cc0556f62a18241d9abe284420423e286a5aa110497c106d00ed8f063fdd5d55249701d58c475c0c5f4fac7e64b19333ec10537f076d464b1581e06896f69394662164064809a37ab22b0ede3b1ca7853e80ef8236d2cc3d665a7e2e850ea1570abb53b6608263cddc39dec2c14a401f35a9a1c17da2c918e209da779798f6b4f3bbe2e13021be89462c0b8942641694d83a40de74b6d0de3a307e04b6d0d43a31be1d3d6986dc1549492ada9d90be370201ae1a5fae20d4a29da997a33732da353ee1b83d2668046d36b0ec9a247028254a5da44bd24337e0c8c7dcb1032d79c7b92b9b97e40604d6308ad711f83b2312c683ff9eab11e29e0fae8e526f70dea07b414fb177b32d2e9b3dfaeb0dce4abbf8431b75ede127a80b9678088f700ed85c77a459a486d49a3f71a1a2d423a397958b274b875d064e9b0e6b064d3e5c87cba71e7fd5648809d34472c2dfcd83733abb913c605f60514046dbdf7bade6e4f86b40e1a80adfc72e9bbe2bae52be23783ef1b0381d80986deecc97c886e2ea5ad168ec619a3138bd41e3dd0f5878cfb71b9c215c38e455a773d3d0184b6c79604337f1c4c3bedc0db1e241415e0091690eee45f4704a4af358699291e944db0449ecd1825e549b40d8f08951ae7a238c13602110fe44092d5a38139f0b9476ac6fba6d3d58eab4b4c86efea359943491a12525bfba357d1c2fb74daedd61a9d429920a5288735209ad9484c2f49e0cd851de390a0511570236807364c1106b7dfe5c267c7b67a0eb688b0e5167f46ff5a204ef4e517835a47046429882863b2bdc140663ec8376b39374527cc301b9047fdd86bd4d1450497e0e3013e4dd5abf37f4d8af02739137ddd4493bc74dd42e72716938739fa7437031b88ad81677074a099ae18ebff74433a86891713ffdfa581dfa5627b31f9154b53838a253ce0f677a98f79b1b79805a65bbb2a96244625e35b352f262366c392c438f08a15c5d438f3b6ac8fd61a8ce201dfe83169e3d4705472d71412e3ecb278a0ce0bfe26399e6d198488dc24824e6c3d62ad7313de958141ee521c6b930a9294931cbcce8634946b843d7d823bf82c404c3624e7172eeeded2a37a276ef7568ecb2ee0886d6addd706e34389f4920fae07036f4c203790234d2098674454d8593a7660f5cd017dab46b46efc991da69194ed5ac0832ea76ac690a87603fd6003d791dcb84705e964735fc91c998cd1302d3e237dce5ffa4196502391bae1c84908c4c927ff4d34b6f8db62383142f8331d16a7e993cc4f8943fc52b3d1746146d0fc9c746b86ae747496b128ad70a39685cb7bad091cd41333293ebc04e4a2d1a700a2bbe8f9c9771dfdd77075b60013392dad0e29676a8b7db00afccd0b51c54a72308e95d6d000b5b3616711da9887dd7e30be0e36adbe76817868f3c9658d413af808290d3fc6af6e033e473cbdcc949b7e7468e7be22533735ed5121e1eca018054abdfdfb1453052b34cb933902dc69da416a98b9ac9a8768955f2fa180580a18ad008adf784600fb712ed816848660886cf219bc0f536c0b938df44bf36f3277f0020f2354c89b1bc97c0f3345d4422366519b282770a9e87680086cb6c74d0db7ad9bc7d44ed683818ed8ecf7205949785aa65e43a781f8ed7a414c930376f934755b7c4db28f4a8560597855986a600e2c47cecde5517c8e39574298090287bdd58071793fb2c5ab162a6c2e126c741fe50a1ec7391db7e2d65d4dbb6ddfc4a1b3bccaebad440e0423981f4364dd161524b84e6046bcc57dff627905ddff20f3a3f21645ade274d7384ac3bb8551461b5f8fbae2407184e50cad7ad8a011f9e708ca7b0c48a1f244eef6f614fdd22f3dc257ec91297a2fd6a14e485929b40e17aa7f3e5931f9a50cc115116cc6840845d89fb352ed671fae3ec16b094f5a1434b76ff28b7dd26587ae57bc39dc020f326672a08f3e704bbd1006fc6ea66b6ac909d7ae0bbfe85e17a4f2a8a60cca9340e6178c1929320c83d7fc2e8ae26d408b33a8ede2cc47c74fe62421dd70b7b4814ab7d4a4668f5f397ac6c364c40999d17e08014043de17dd1494d5be6898e40fdd973d771e35df3df723b58814d9b6191e11734c83b01e397165e2caaf58483a15a6a18da960a95f3fddff6010d6685536d56a0a581fa5b9750a7ffeb2ecf822ff23dd8dd3ebf92cbec682e0fb08ef1b5ff6face512debb0a8ee90736fea8ee496193759e3fc430c66645d9e9dc4835cc11f47c8781d862862c9bfe25e0caeb622261c0fbc2dc65071105e7a538b803f301376f8a90527f7f2bf9447af2981664f2cb121e369817ddd5d96736b6ab0a398b573e298b805d8694354fb0613d00b57c1775b2dc1e59e81ccb6306843e0fa2f75c848790dfae715c36788b55dbc154ae13b0de69870ac37dd82cecc2e151ec78b33475ae6083b0ee55105cddd83b6b9d3c1cdd991ae8df3ccb01f6dc27b5bf72d7c479200b4aae40dcc6a22c9bfa990548ead9c4f94050c02d251ae178f8cab828017a61f3212ae1070c2869e58dd3dd0484306a1814f6ca9528d2a2ad6c936eba25d5589fb9167f843f8b0abac3c3cbb2bc834a95925e9abc62c9ac30913511a19e8706b41d146c4d405e20cbdc41a7061ef9a3e1ba90688bc20df309a44b3629f383a25b27802d1ef95745f725bb2c300509267adbd37533f08a2f4e16e36e7f1582f390a79da530a5f8f09b8a587032328ae53a2c55dae332834cc22ae11d551490998ff13e1b50b1fb8eb22177ff366e0c809cb1da4a6af1854ce5c03c361fd09e78128ac6017dbb0b4e948a587c85a20c932d9de2e95c32b5410845f26560c6a9ffcf79219dcc9f33d5908e17fb7733c64d0cd5e0fbf458bc84b6d924120b99db9422993c89d553a81e8ded834c7df2c7fac833dd688155e4b2d6957545cde48049ff0f29dcf6d2d872e4200800ac5610f87242fbb2404b3fbefd196e5bb4007e7e6b2821df55b3afbbd3acfb3dff66d0089cf1728735dea1be571959d0c16c1019ed42e10370d3a9c2cd68ce0fb3488c223f875e3b60da82eb7dba2f8bc7b43f04933ae05c2438fc1bebf053c056648a5276ec9b4d3f04f9b62686ca18ef653fec2bb6d77253c4c0afd57daf8fb38fdcca68ce47cc9054eb76df57daf451c78ede3b66b4145ad85c13410ec31af0d0968f11963bd0067ea684b7739726267d0693410e9f52f55bd41a7d4313f58e13acedf57005491c13d7c81a5980c16ca15a4fbd703d346dfcd64a4549be0bd2f203d707ebf261aaeae0bf77293b05d0a905c50515cf7b4d1134a0e4276e70daef580f68495a9561e28bb3ba69d3616a1f105a68a65f4a405e3a48e6ef9f794b7b05894e1bc42d45637c8cc37e8018c99bfba4be7e3c2d995fc2bbff3a072a2d6eeeb7f0e12597b8f6a9337ed102b8f8b4aec8f27a0a64347566d4cebca5121380f2115a74334e534ddfdc5689217d6345e6b9ceb2204c9e2a7fe487e7fecfb68c00138e4a3ca5559eea72272da3bbc00957e9742308aa872cf298bf7869233eafa4ff5e27b6926dc472bf8d74dc7ed618f118da3580c9c0e60b13d1ae0356d93b72d089f39e56b3c71b31ffadfd754f9e10a04ae61cc8652ff202a78e5a1f91bcca8358c18961ea93dac3491aa840149fff7fcc2bb8086c6939e3ac9b8570d403b9a1b169cb9fd94c33e199ae70adc63a806fe641a315a04426040cd0521a8c9025daf412d2d197ed7c61fa342e73b15a80ce7bf1f9b6e9a8b99547d64c28e6e906cb1abe4989ba4fda838c88930737130790a50ca9970ea0a54efad224bd2ff814c4312a21c28d15a47256b262eb85830432db9b5055a39f9c65570a954fabe68e3035ef286b5627ef79d7fd271c0c08828418c1b2d5d6d2307259d6bb9bfd4f64938ed071812bf6a0a5cbcd2545b94230f3a757df86d682c2f9c2022569ba6d0a93dad12ef301f4f5e2fe1010bfb312322047b1acddc1a264a0b5ca38d07095072badb92b4c4580b3d847515fb54c975174c27251326b525044b58513b486ee7d12c48725b1892211ff9f1afbcf2d2e630acbb1249ee96bc34044ea9a7a13519ca811a05857e546749dfe3872c68211443feb0a9653c7bb1588c12c543d7603359488634325069c6e1578d56d317f229faabe7daa02334adc20b8fd17eb64f639051015aee76380adc6bb41cd630c9030b3d5e5b182e773ea01719cd0a062989aa5b3a318adef11128356a4a54f0104e9b8fa6ec01a5107700c2504385b6cccdb82779120c263bf2a074a0b4c180ec4ce8e3471401a86a200a0c66015180b429d2bb30b31645600b536fa7e68a97c3c9af27f304e395a66fed02e6194dd8cbdaa873ae619f4f11727638f788d0fb9cb43dd1ca97b2efaf81c4524b701b4fa44983ed0b7d19e435475ade6c1e4d7115c82c31a1630e9a15ecf49f3cc455bc8fc71e810cb525e27cd1b51d007a622013fc950e5e2b1ed3d14dca518ec819ee077656b9f2d8de01f09a9388ecda2df4a45e48f76ce2d83b9b3541873ad63b576998e9e90c4d29af25c62801ef88c24a49b1d10b2a38c8ddf4a6515855f16351a39746e8d0c64d14012baa981536cabcb667e39f6bf8e448cfe6519908a07cd026e7eae026b49e73d975a570a9897cb6ef0c718d13608a25a7f7b2824c6b686d8095427c63ffc17cfee5761ef4d08a24a53d2145e0668d71fda4965770c81383f1224c81420b1a70abf6440aea67a0562ac92e8121fe502d210015902f7e0684a475a3f5332627ec5497f1b7e1f543ad3d432f17d6c3930263f57d62077ac11c5e2b32439281de6985f20a673184edc3e80df82e6c68c78db098490afd3f6b3190f2b187d24a75e80a3de69e8ad9d6e3f0036fe3c5b5b5177866fc4b1800b1003eb2d3c87fe336e2256adc5fb512829b160e911ae2b5df1f2377503257d5700480c2414fff2a1a0e7ab7ef96f4ada85310b0c98abfd526605875788936088310dd0b1716453e9f77022518ad0e94ac9321bde6331bd2056a44657589f6c104ac07d2d52c458e0cfe742ece8739155786ea2d0635f6e92fae0c05409ec9145f603d756614e49c824ef1c98a2a6212d22a0a0d4d923a0bab23d94b14e7341ef36f0a53c653d0d192fc6d97ef242c2d40c7237118ccb4b6609fd224e62fb3dfa30d93472974996d5ab56ee580622c7ec8ccbac56403fa2669fd0909d71c8acbfbc35352c8d75556cd05682446b83a18b412fe194f1e3ba2e377f785cbd521513e07f5f172391c07d58ad368c164cdc8a262e4501f97dad4bdeed93e90ceaea4d363fe568027569653c723095ead9172631a680a041242dcaab7a3eda5ad1b08f0ca35d2c4f0a108034be6200dece4a852a8add8a9ea85147e64914c994ca08c0bd8042c1e35f75ad7a16cdb05a3488134742850a443453d3a097cf52a2e4ef4f46ab8bebfbf15b8603a3f9cd7e56d33a76443f49cc64c5a478a29cdf920c8e030f31f4c71074868279d5efda748ae24bf379c012a2227b43ce1d1020180c60e000040b86c97c4cd80c92da7ec62258c4a512c5364b96610f5e91bb45a207d2641ea62f43b079b8035e8882dea9c80c468d1d50a0842455d161bf2c8838418c2b7a8c6edb560b63b1617dc559a87e4d0978560342e1e8fb1c1018282abe5ee2b714e9716f9a34ee3532d03418fc882743a6dafbc84075ebda2eb7238892a43895ac0edb62ebc26bb869276c2dc710eca67251148fddb3c0cf8e14a93fa2ea70a02f425aa410bfb02aea626ab80d8832142f431a365736f319c0836bacbf13f84d90f276afc6fab8cecafadc2a5d4aaef336b8957d7934afa7a2f4a44711892751109220717b4676650c6ba6ab163e70b7a0d3bc2538455a800eb03b30516ab9bc39252a7643dea5d5dfc3dc68969fe66daad6afa02a7dc9e4e85f516a78952d6190f85ebf0d5a160655781f8ef2a31b69256dc56c49edf36619d1e0a84ff558259bfd2810dbe9dd0b2f6b6b7817363b2e27f4d9178a4ae35eaf4074d4776de1dfc6cd9d6f6a35771763564aad53f6373ebc66387a3217b0ce938b03d162ce1ebe56d34b8caf04d427036a185fc42404fc0709bc4ab47e77ff92b6ab0637ba15ffcf05e776efb3131684beee58d784738bebb3a1562df8d4cb6e623cfa11b8631535e0d234246eedb23c6c5461b2cd32a5a3185a4babf242cabb798b3da2f048429690d215628c448b62899fb1e64946e0e15396206f51f8c7919e8d7c949572598c2ec07cc4d3a453de86b974913550542b761e79ed5b464fb65c05b5f5839f37075faee5fbf733b91be2c41ad2adfe9b6c2cb8d4e8d9b74f4cbc2a59c06d39bf9af963078d83e0cbdef9d37d1d954758f6339a38ff3a6220495ba64ad543d50250161609ff9abcdd05553065f66bf87908581d5a18beb7a9e2e66352ba3731c95974219004f27bb3bc87cc2a751b4c33d2f23e7d22278756c88ca1880aaaa7a75548e27db292a4e7d8cef260331213c9bb59727e5934214c81fbcb745dfc048176e87920f3413a053bbd9cc0faa0e48e55156d4824d870e3bff67581c311ad1761cd2008d08111e1623492a801baab2508f68aca6cfb9ba635ec0c3e0ad53ea617ee33957799535122b786640787bf6ab78cc7b50f6c026e68af2df5e600e68f5a38001888b5df0df6e295825945a1cee6766d9cf63d42f20b4499dc044ee4f80d91d8da9b6a0745d35e9b4f08d4bc5031c8c9f0e7dd2c65ef1abc94ba2e40a5ba01357a031ce2c055f470367885813617259537908657dea07335a881d7bd2145f258fe909515d50273e3c0f0c786d94af9cc46d0ef2bb5c6aafed2102dc91a5f05cdd4623090b0639b1d64211829ce9a850afb5d903fedb35c81c273f51b4c8214deb3656f60410f7353a4dbe19d1f274e189887529d80a765d862aaa8dc95e0309f9e74ccc213f5143a1ff26e329e7dedf05420960e92c6c8df511339a4ad2559392230238aa73110ca532da1bffb9c914e73b5255d4dfb8e13aa93fd4c44fc8c0c1ba8c0a4ae2d90f8b5f89e9d7f97e18bb0c0185be9f024af42dbc2272686c9db9323835cca4f5a1c12894fc25583b2849971e3042c71c871d116fc089d3c91193ea3ab30c198b91fb2d524ce42a0936bf328b5787a6e27249404d72e38f5db454d1df70c3627ce65cc919021b1dd9e0653668f7b43ff6b77f34a8db5baf3d359bd7171c34811762b882c59e3ce2e34d59e5f3a36e06551acdf3b439aa5c16bdfe46fd75cbafee075f4170dfa22e96cf24cf5901591d00553475fb0c883fa927cc7be185614704485cbe4284f25367e94e22025bd9157be8c81b74dba1c2388d54edde1b4b9f43b654831451a0030c06a5d1846a8e14ea20051058056f46c64d73092fe265cd495126ebc4776f9efd56efd22de0ed74e34e295e953d7df7c6088561d2e95268d90354d935b6cfc7abc50d5bd1bce3d9beb8b303599cdfd6136582e92a585d64d699975ea5bca382fd71b718f52b9ad806a4effd9e3a66bf93a34c2e7f7cb3fefe3ee431f927889d1a558249ac961f49f24264c83d4080777c90be45d746f048d69bc05693f9570c4bee0a71cb9296204a6f56cb49fd1cad51443d601a1512e2a74200b4d7b2e457d80e81290acf884787a1c4bfff9494868224ac11c710e6829d805ec91d8dcd74c2726674bb750b629bfa54b7f8109aabaf6a0e279235b1fccda50661ad80130e285e416197807488b5ae58e5d5626cee7f6caac8218b0c2121793e5e1c15ec5618a85179f2902cd42d061abf922c63cb7193ec587f253e1ef7f315cde654e71c723de187f06b929bab61f63dba5d874a8e946ce86b0525e91980081465221c4d16493320d2fad4d4f66754ed2dbfce59acf3858fc6cec1945cd1a56c57b8478a4aae7505fe59da21ac6da17746fe5c91e4a86e218e843fd22b7e473d5604c67f5cfcab2dafdef893c4c8bd85d1dabe061fdfdf607b7da46af5ffb1a9d7d1f6ed3e28b66237d36e9aa92f17092e5f3b1682a55b94f5c2c8ccdf542f4e6f919d392b79ba16e05b84d8585c642b1d9baee68d243d61caea8cb31b812513feadb462784e6f6908c0d7695543a0dfcbcba1f8f1bddec9ad8d1b988a4b038a3d18e1ed2aa6b1dec39525ed4771820c300703b1df9e604f25cbbaf454ea6961b696199b4d2b2336adb615b1b2d01f41b832c7b4ef302bc663168bdcd3253c643721bb4de556ca84ff80692b8d54cfeeea84ef206ec5db4c18ba00e0a33090e502c56b0f19c4b390f380b79cb4b50aa12106bc659028d4c2a3862ce0c3313e7b2415627fd7a83acf340ab018589e0586c49462c456ddac2d5eb3686b2ce766d5ea3fd0c3c93ff9c9fb190133c25a76d0160e930666db1e1a8d185806cbff8cd9de708760ecf70098ab50836313749477d6ea56f90c2b337f7021d3405f53d5c0370e1a2123a8c1e81bf148fcde35c47f3d25f6eb181a1a108d0d33ad4ed9474ce9a8a1db5c6f2134d834d6505c1b5af48ee4f301ea643c9cdbb4a9e7e91a04ea21df024239c30ac89359e81acf9f498a6e86c8f65763f0bedc08f0ca036613b2aff8272186d5968d42591908383225865d7d2d0e72f4a681edcfc9fe296f23c455fff32ab9a42be4a5e5c17ec01324f6746469e6533d3d24ae2c1058e8861622d2ac0136f17786170642e9f11c1c85adbc504c868143a2e951c14cfef7350da6a1857d9b285ae3c390bb599307c73c7fe0a21456a20bea03e8e423e01d6dc1110645f42e5de742dca43162c563404749f1974778e14a2fa534ed621339ea395d1370b8b2298335f1749ce073310161aa219840a6c3224ceccd032d2c2c67ad9a05973db2bfacd0147915e31f4d7364448b4ba717d4293d3f7523c9494940ed46ecfd4607bed519cebf98fffc039b9fcd2d7874fb9803fe9b50e34b66e7ed4f6c8d2f3977c6abb12d8a10e08366a281ee4a0d4ea47f95c6f53d7c4a9e368186ff7822b92652d18201e888ddacf0b4d509c268f730dab126e649650f125a852718c5ddf0c21ec6d8fbd85511a2e94ecacf08eb63a756ad363058cd1ee5bdf14dddd9c678c4de13ec7cbe4f2a805d9bd485db0ba5df32b5d579b70a33614f37c872095b6ba4eade0a567c8090d49e0cda7b5df4d39867118857ee856b817455d762f1444358c76727a79834e698b153776e55176ece8bfcafc6a949f1fb2dacf76fefbfbb0733ed0386567c52b4ac09d5225f68a82def114abd3aa70784e720dd4f804263240875591ccb3f210002195c9c40bdbed6e7683712134b900609d068b22ed5d5f39a16b7988efb9974cad380ae1d90a027fe5ac202107385627f2308af336a796f08e9c7abebbe0beb861357fcd3d5171bd79a13867329a95568c2a73cc59c7060a9eeb561e3f860314d05e1c6197f005f9721d02ad71cdb2ade7e427c9d2991f5c28d4c6dc1d671fe82f290b0b83333274a386e4b8ad723258b96e907e84ae4ef0320d4053efe6358f9338dc9d250b250a55365228845cb4aee7ae14cf5a70b5ebe76e2856cad02b93af73ae23d158c82b5c208b66dcd3f44eb24e5e8fa08bcf006cbb0f59b50b406e9de124b94fda882489911a16bada43f23ce0096c6daaa6eeaf3592d8b92f465f77173c1fe5c452d8cc047dd7da6144a7cdf56e46a8f754dee6f13f5f9d8221b0ef369561aaf0276b951c83d5a1c0cf978c860e091a6f6a9847583e98e2283156645dcf2f0b6ced7ff849e10cbcf49d1aaa2bc274bb7ebb92c87e61a780c48a398524e3a7637afb5db51454dfb8cdeb4f5646a6cad9d74f397ca55bf4739606124d8924a672ffd53210cf28f41d5271891abe0a0da9dd1deccf260108d96518c8fb9a1354e1595fd4de2dcf98e43a8d09543d2ae0c781f5e792f20cd1aa89832e2a203aa5863233d7cce1f44655c47832fdf9ea85388064722592efb2232030223a27c0bdd9fb8f36fcf61a09641de16245aebe0ff20d964a6799f07c1785c7786f2b96ed6dcd3133ae8f6f455e4a0cd769228a1686bd7df28015fd0864ea6e08690cd7b1138b88952b303262046f14a0cca5d37021ebc6c6821f3d6d9fb85e7062b12a9bbe82301fbd3fa11de91b05f8986d049b300dd6180ba16b5ae09a72505c7d3a78576ffec0e6255acac64d47ea20c7f23f36e481211ae4fbba7e66b30cd8bf76bdf48f61f35076aea242913cc08f7c19df498b2f8259ca551fe92550736f7d1a4d5aa5ae6be7ffe10c90fd1f70f78d0ca61a144e5f62d00ba90901af54dd9295b115639044d5232f4158f7afb5c2f091a392f6bc793aeee8b3aced8b9397f2aa88030e5e9f54827bd27e925da261ebeed551caabb6767cabc22ddbac0ca7a46ae893b29682fe5c323723f28566ad8d80fd9738c231008e7aa60db8f89d8971719604179874b43ed2a51f01ef10332fb9d1331030ac4c17b5c3866d6fffe0c4a92365e5ced704287021e039400f809787ede0b190589cb53f9d55ba97afd59836e55fbf8611af3136dda6bd6b54057d9ba90b3712eba8e0a0293543b9863197d9201776d62a2b027eea503bc59b15418d151acf2de4c54e76663824f3b0c86c96c1cdf5e982217ca777662bb57f83f14a3950ef50b6dbfd417d08efac160ef55ededbe1ccd4d773a2941c03350f8d6ee395aaf0dda514fa4ae50c202d531ed1dbaa00c4a07f4531f4e23b3e9d7e6363482f2c429a54ca7d554f709e49d24d90cf8cbc752d47d80ba961ef3e6b61cecf7510f36cd0a08a467ea7d68f88564fd8f640377d1033febb909dd67ac5a3c5327ecf02aee0006f6bf54db09bf22e5c1f015683ae442640a0a16826aa18eb4692d53a9a0c94531dd6ca488d5c87acecc3476a28959363bcaa6dd3664163650b6a3c015e332498e9d78db47a685b9b2f6b541cb8759f191df9942da92ad16a105626542e9d1a85a129ad5a55a5f73048d09de6beb1e082030755798a75a4e333f0bac7963ebb4acebe566e660e3dd7b67767fec1e3751314599ba32f8266ab32f9c9812a23e29ec554cb985f4a7e0fdc098b27ded62fb209974969c201b87e6b58ae1c9696108c80a96c5347af80a34234fc313b4ba34243431ba44ebbd0d3cd04ed7f6a93ece8629aeab3ed59bf04e7b4fcdb1048d13685bc226e1af45790f90b19d68f3a521498c81ed65609c82f2f3196ace539036285106ee81178fa226c6dbe66febfa52227f0820cbbe0d28e3fed279800677064e1e6a90cb420377f1ed9a0c827e67105e438059c678beca3f4c3bc871e443e5f9d4b55c1e6ec4f657c23badb8cfaec9035babc2b7441056d118ad16b2bd5b4de338f31a344c0b7208323cd66493da09dbe81dadf39a2f4688b5f39501271c2858e958993259f69361e6cfa60ae84011118eeab238693c32b91dc8507b4b0c4c2ef324c2a50a4399e47ae688466de0f602673b55552e49391a984f94d42c1f9d466c756f511276ad2c8c83842cc1f1103fb3da5f5c22c4c5bd55900d839cb986c0b3a2cba83c3dceae1615ec468852dd2c3826271329448b406946e7db6121aa961b7d80dcab8e4685f0bebccb9ac290de2e72fb2890e84d124b6cc96355101752794afe1652800b9ae4c90176f5a4fb327ad2d2cb554f992ad44bccc8d0a8f2d2f0b9f18412c0d0cf86c2820d8a39091fa2a21e28caf3d37f3d1721bc01f6dbf4a87742a49916d3e647285843f5d412ec7df1ad745a7d48e23a2dc842c6917871c3e95a8fe44de229662be3ab1518d256a54d95c34ab8c21de68e1b185e367ecea30b57dc55207710b8933efbf6109324af986d7bb71143af70f6b9666a60f37e55acf253a7106aebcd3e17d65551f935ab0c47d154114354d8c6ec4111069285285f28288faf9b6464e73cd3f42c5ff3cc99146fe3b63c3e8999649f676088de0e9813562d7b66f78bc5804b8af9ac5a4925fc4ed3c83e853044d4c60ba4639b72a89857709d19d19a3e43410deb521cbeafd23fc9a9c144ce5ce3d22f1923a9bc60776d8f42a256d4c27ef6b5e22ce1da50568973beb4ddb74a9f9f0f03bf57b630ca992d05b3f1ffb70b96911a3b9b74a00775497b1c673c6cc2568756eb037a83d1a975479478346792efeb158ac5941a7e5775ca68c2fc0bce0819d791bef6a5be6d72e8d430606a283b91e1fe66c260a017046de02cad22dc4520d9932180ede866375dc69d0024ef647788ded29a596430f3e4d92ba559757c1d893d918dddf21dc8449d9559c807081c25c0a39ff866ba85be9452c77801f0429e74c32368e818a586e127752fb4441e32c4510ab256bfadd8c93a9c3f5330be799e2278edcb0090192ef97cb6b8839e77f8f7193839ad66a11969dfe38504a095c7eb3b4d52b634efc4871cec432b68d091b36dc8e502e2fad9e192ee7f31b81d701da8fe4e21afd5261e694737cad316dde70cf4ffcbc5661175c12f37838b4218868a6dfc31430fab26da728977e90587cf3d2d793de7aba1f524fad7504df456fd2bc3a7d76b42123a17c70783711d0b96a929c84c87dac875a0b2e07acac21100cb012bda2539cf3d9dc048489839b53e16c3696a0b9363ac8402a7e5684a1a12b0bd602540d0506c0b4346c067e47e6fba39c20bdaba3646b3882006cebf6f168e0fe2ca9f2f041fcf16d12cc1d8e41b061bd1c851b7b4cf0fccd5d33e5bf7eeb6b1e47c2ab045e10f45bd4ad811b6dce7e8584b6bfc001b7915000965e61280048975944830380ed1c247b36069a878f7701eac138b2a24661ba39b6f6553743fdd6c03be2ef592ad846488015f5b3e0a0bd86a0503d277f74a06fe3a1a7d3340aa42135f3cce4fa3ea230234d5c2231f52fe403a003035c38b363b7c83723c363fdfc0cbdc21ad428414c1fdca3e2e6c69550081b7c428c038dbf9a3e0529b0f741d6817fafede2ab0e3a4591fe18345762f2d34309a82c470529fc0aa34f53137cfd47eca2cf7809d5dddec7d4388bc84dc6ec8ed8348882ab2062d28ecabd3ab3b3ae6a47bb2239e648c98dfb911978831af4938aa0bf0ebd44531a32d5445bd80db518d524b801ab93aa1f7164e45f353b6b48d3e105f5edd0ea2ea5efad7e399f69e0c22c2d9e907a07f12d72a9d891b42a3deab1e5b2a7a929681969e3f00add298f365ac57ec54a03d80297745a01a3923a9cb48293c13c51bb878f1c8353eb041705d74e0647ded65596d1a4bc53fbcc028686bde8b58ff83a257afa3a6b095f22ff4fc1d3a47893e470d302c0ba8dd72025df3343a7340e71c3e8844e396c37fae8e060cd1ee2b30f20f5519c4f9827e89d0c3de6db02ad7136b1ba2ef4a8c5dc5168aa53b40e8285fdae2f514b276bed7c8211155320056bae99117dfc01a079425f3ec08e4bde830bc815eb7b6cb1f88c06b95bc66828dff3a94c5aa0b4244ac108cbac34b94870e80057719088eb56836f96ff3a35214e4cd260c796a00e97ca03527026619cf654d86a94e95c9be3aa6fe4a7e6877b650263fbcd5c5aa6e2c5ce3f5ccd153d45adcf38ff48d89cc23a44c7431c84ced0b895bda77be01c27371052a8f15e8f292f1353631e5667b58ca209edbec7deaa85437b68af3d83f1b1bf6d6bde470eaa05d8d088a184645d64f1cda59d2e8836ba81958ca6f0f980c34804e17c7ff8b2904e5003c21f803aae619406c5314889bda679f514e3c12159414b1149f278f31ee8363f8b9b90aea0ef403a8e786b07d2bde9d0fe2d90f448317caa34b433e8a7e2a1973827e2b2f8c8c391f5bcfbb7f2a80c0905e28d1b0601da40cd6cab3b9138d6b2525b5c64194a9bc476a27d12bfb70dab58c5b0ca71556071a9d7c1b9cce4767e5618465da220d237bd181d5abc4e346c93d51b79ecc8222839db6f28c60041bc0a54c7d2915267ba626172a8566738d528e737743f01755c2b1795081abda2af7007aaa4b7ce075eb95960e3f162bede8ed014e2e2f7e3786deee6f7279f137d249f8b9793cee83a42cbeb0a67b58ab1b6a32d81f662f0e5dcfde8a599d94d932d0ff0f8c220056f6f6a5423b50a3a96234c49679373b29f5c91e52a615f60ee4e59e225c8ffd57a81b7744ebe64283556a6568a8b83c4987d45eb4ff6886338188e2a1f1dec390968551b197634162695e69df53e403bedf5e97e2cd6fff750995eee09a1eaf873508a7720f63bcb30281bfd136185766244731c9d20f705ac1e6df541c4bf66f10f0f2cbe7dfa60a4daa1b91073a4983b175ec9ef62f6ecd846c411ed702986823a7b5cb34b27d10647a5edce5ea7153719f2c6b8cf26418566bc5f4360df18c53b70aa21fef8475c750a9885f56253aa464958793948aa217b3facd34b78f979d20407631405998813f740010c35d6a313e6ce9672441ac84e066e8eaca37fa2c99ad8313cfc0f8167e8c8dcf14b98fdabbd759cf2c994bf064e31796db3936f0a72d8b613724f389749f731a2a395305195a99a05543a1c227e84be5b1240f0c27673dc50d6e44282a2fe8de47ebbc55954ec54b64abfa893139a84ee3157e36fba4c376c32720f15fb8b319dd2cad5b7f41c40b49c32d6a501c1b30e62900f4e42c5a0e266a546027ad81042e3d526010f263d16f9378dbc5a8f26d142764a9bd0181843539ca63ccd0ef6b1bd1bfc369db475dd9d9c61a8bb20dd4a6570f424b64641578d1c01793e391547f564799ba94962dd9301afb2477754459b49a1a7ebd2002ee58a0606c02328d97d45b71eb29b1237f5ec6ff53af4234e66d5ee1ed4b6fec6ff45edb8024d217e1ef4312203699ad4288de5a0ae6beca25a6d8dc8235508c94ea952d4f9cf22b0bf2e2c60cee25078724e0e5180095ad01c12cd6618f739d6b66aee20aa9c7ffb438a7120b264d747d7f3e28c75bbd3a94b35479c111e0541fb78b0ed8987e3e5122f16e007328f7b2ad1148dd4b33dcc02692e5b5d01b994733707e2c1e87b847ff9f20fa8bc98ce595f8586441c28248fb95d240bd8718508b4b96453941877770fd20022193e5bdebd654f43da1b7c93234b0ff78c790e9a8dc3a30a0b7521f643aa7941196fdc044d7d8e585ae5a43c6b2aa96651d7d3b234fd8527b97ae8a2744745e02bb6d4546824ddfbd7aaf74ba1125b91f49c2fac8262d2e56a4b557d611ab78a490f946aabb5b82c91dac2a6c518e27b80c93b7fc2abb191524f149d3bf38a906d3251d2439ad258513f670a084c2674aea27d67082bad32d91ae8a5ebdf5499b2d6e3835631fde969280ced4cd18e926b5c10451e7df2dee6be8c47c2667d6d3b26e999ce051119376dd5f8313adee4c5f49681faebd319fd9349f078275b60d935f4114592035b0744f95e52e276f1df1300011bb9a05f5cb1cd498722a7065797d70dd5988ce0cd8d67a932ebc5fa8546e4172e3d295a2b0ee70498b431864d0435f854516b7ce858c073676f69b32a994e60e68a5991716667fb9bab393c89d6242459eb920fb2ef7c4da78294587682bf232e828f60e1304f7ed0d1524594f92885c6a941fd6cbdd9524672536d35eec882d446c24c35f43d5ef6c68539bf9b4069186bf2f98533a2d598339233ba264e4faaeb48c1e0565d7fe8ca6311fca74909246404ece62f1d07d82ac507fa80b986d33c0c5c62a2fe84a20f4e012b955c7770f88a3da13e0876ae8cf8b6c1e8d1efbd8b2a5e51efd8004b5c28842d59cb698a84c1586f942e93bede0895707ffffb4beb3601f02a90415cd5b4fc5cd3e1f2bfcffc9458bb1bdcbe660106662b86895c831c91f8d8cf9bed8237d2e17533ad533d05408d505975a1dd4c1b67c20dee060dd8aca52835608c6d693fbccd8d439b2bc34a7bbaaae79e5b8d837af19b4058ec55b7980b3becfb81efb8f4d71dfdc0337825f792c6bec2ef87003f6cdedcb8d2ce4aa65e30ef89d6ff6b9b5509fec10389c07ca679440a95ab23d8c4ba7b3c8564778ad97bbfdd5e147ea175d79e28dfef804a63079d26fe2999092ff59927e8ea4d4063129766dfa1960b5bba1dfd05de0f70f7b20f983c9412e0b2b312fc0064e341fea097b7746efde934a2824c79590938e3eaa3636b38d9277783aa5348eaf0b95a65c62ca743239b783e61956ffa9ea057666aa51abaa2a803889b316f37f1090ffbf6714444eff3b5481938677baaaca45ae8620bc21a7d2c515575d711a47ad12aa58d46749b674052ae6b2e469eed8f76d0d3d63f7a4efb1fdfa96b94e50cdc459b3b2a1c1ebbd67b45141be38f7ceb2101cdacbf5711cf4ba7e34fd33ae9b765c4b15b956bac5d5aae8ad2d2bdad119b058cb65c59a00ca3f355a305523194e798ba687f15cac86280498dce43d022d38f594dc13f11bafcfbc5b435c877ddc7b399b8d0065429ec860a38916afc62b3c5da0d9dd804986715e9cb26afe7dcdd76ed0a86bdc0dde5594ef5aa6e5156723f2d71166c22959cee36e9c8344e7284b825543ef70bb51cc1d37eaaa8c03ec231ad46c43a55fa76245ef1368f4362a35f9e0b8105ef0a866905617ca58e460ae69666f0fbd0db6977a90d308c0a8f1d1d7b26c4a0c54470c0097193922b33b32979bf3c58c20f461c517614813abf0c5da89b2ce82d1b25fd4a34667e383030b00ac787a9dd7cfa6cd4dcb9818fb3bca071282782b140201b57458bd046bd0e46e31ff1179e1742ab5b55ea8fead1c0cdb8517566d4a07829fa3d94223fe10d3d73c22496ea23c7a01130e33f0906506a1421467c3fca8a53b10d7004497ed474d04c1d300d50c6833ac0812582bc39d7ab20cee88cc14ca546dfac02b9a8daf681f89c10ac341ff034f9f4eab1121b8aaa3ff91bf470a28284e7167c56ce78b5c45822a8fe113815f29a989aed8733993fbf6a0110d03f97a243965f19e6db3bc1e251228f9953fd294b631a0ac0cbb8757123325953d8cecdb983c80413e9868604b47681a07fa5eb4628ad271c794453369bcdb1149d74e655213845e001568488837fa93e62fe0321bcf1405622307848988c295661f7f8992543a018812553efd5d8397acfa7bde2e751add458d0743bfc5059fadc24d1358bb584b8fdea617254e8ae10e6a6993c91c0ac391cae2a2c86852a6a014c4192ecb14b90f327a8e30c1f475bc1b2e8d1f7b0b050b137507222ed1341eca43a5fe70f386d9d19b46285f04c20a9184b41e611126337be843a4420d699aa2b1b288c9e0ac81166b70ee4566d690cf7285b16281ed8f6b8d835e43873b1f970de3e4af4ce87c3c5e36ccbb32a1432e0eb18f529b2b13b467612804a267d15523e5c0c6c21f5a636da8034740b6d682d0b14ad4ad94a54081c0752e16ca5d253931365672ba9fc043b36c94abf39da010347bd9b8a38552cb2b13f7d298df1c5378e51a2e3821009a3d9ebdacabe0ff7fd1319e7c233b24d993666044f42e366cbe7ca48f31b1ec17651628aef7b8147fbea68e36a1e1aac1362f018a6d26e256141b53747bf5f804ae7e1c31bb6b3f56958698cd0647ac4d1f8fac82604d831a96e0e8df7267be81ae81e33b5a37202f339169caf47475cde0b0137752608100bad9e5dfc6779d03cc61eb16188ee170c2e1190025a458241c0c1d77c1e4b3bbc2c7981a3d4e1ebd6a7600e9cb93c56976819b5e737efb91fe663deccbf8800b665316e61c8f66d8861a4a6db0eeb44e10ace4b8501b8d3d099daca7d067a090d9b0642048083701b4618da91e9c2f2b72f155d416e2c2c5083423521b41c9fe50636682e03586d17ce869089e018ccdfda8500c17b354d4ab1121589855daf3720b264d658c618003c3d2ed44e2071658141951e858692e0ca5ee7c5e1d11fad698b57e97f81efa8878e2526cd22dabd1426264b55cc74a5018aa90a2704e1de861ca64c05d1ffc350c1f4b6f34a71f23d6952561ebaa9952c3c402427877bedc0277965678d42d2c60f9729e6f2e1b654f74a04056c3bce2886c584b942283c65f4b1db25a54dc8bb7774aec5d9800a3a798ee2ca6065316f160445bdd19358d4d165c37934ca49ae5f4d2ca4c369a95cc0efe61784d8fad74e63fb5a0b562790215b208bcf69e43f25b090adba03db233372463e5b91001535e09ea0f55e96d9fdcb5b98886d27d5902424f8d953d994f163176cbd5dbd0139906dab3dcd1a52835c74649b02206d091b11de570875c0f7a573ded5fcba19619f815f60652afdc77b44e21b488a8a9c76ec2f238829641a9a77437f5980ac1cb593dff1c1c935c6b76f1d033016416cf87b6029cd558fa6a2ea9130c80cf79ade6d63f053392b3836521a33cf81e8624552444cf861266c4f5b6a7cbc3dfa3252d268555abb1f0f3ae01b8347aaba6b3f038513e67f47a84b10c76ecd3cb80104d6b890f525447851de507a332ffc94380390de94bb7c89c59bc6c0e2e730e9393d7aa65347c435d6630fccc7c1160fa4e072ada3d666853dccb7ddd6d8454d2fcbf2103e0f2a20639054653b8ba95044852f5b38f6df4535a0d710cd809a3921d199b82310ce052563c0c4549e0b71b9ef721a8095b5cee6c54c372c9670ca510dfcc1416c2c465e0e385d62552dd8451c11c81c2fcd169015ff6b97a36019901011040b76e0dfad05bbf2950df4e2647478d7a5de40f30b7245cc2038f38ee5130ed60c6c1755cbe91770e5da0e0e48387be54dbd6a420d8c792d474e9fa4623aa961ca4cd2ebccc11647530d51fcf2ce119fef09f0c79bab9cd45077296ec22408b51f1f3ecc9275de27eb8c0f7b8154fbf6f4f138439f5ac1bde81d1f5b90c1f3daea7dd695bc75a51454f5d2a17b1b49548dd34e08ec607940525c38d6a070929f139913c12a35fb7855d2f727af0ad820531a80eeeea788118d30fad3ca86ae6017d058af0252c22aae553b6efa8ee3671a1a21a7c7204e2c43b884b51b6c323499f74381bf1c1f1f74f822b1ded6dad7fb2f0dbda4444b823920601bcd48b660709807dbd0b840522d2df835b04268ca3f5a5cefb62d3854d7c2048e42339a72bf1413828451f8170cbdd8f47ee14f413fbf15138b9329a41f76cb132ba9b53fee831c6483e752e70222148db7e7d8230c0e6802e62b7fa0b498622b71fd080f85b527fecb5da68f59a154e1be054605493217ac7256da9f519d21ef5acc7e4aef60c875420bdbb405219f9211af54f570a81c94c29b05e94873c2df65f1e47a50e2954186a683e179713959791dab935e136e1ec2f9b1924db2658b844a5479c2a8e978e366fa6a37c125477ca5dc2dd383f78459f58fc833ac06010350203178645a9cbaf0ba28c69ef24e4d619db7d52ef7a46513f3fca503cd7458f71500822c6753a3eeb0db94cbf9c59956cfaf01448b2ab9eb732b4424038d2923f764c4444cc11729bb84deed06a8988adcb1a703645806b1f143d1546664624aafcad851e2aecc941f70c511dcd55a7c259d58a2a5858fc30263501b8069524b17c76d3d0638f26da176359fe14849b5f8bb83fef0a8c8a7f66a60f7d0b3946aa1c849143e7ab59b4a0bb223ef70fa2ced40d0e1024a78c617ef7703366e64f8f29e9e10f699c30bc8ecf2c1eade118a08f33d2679a617b7e1b167ca7d361b6516936895841aae931fa803dad3b54152e066ebaea92cb0ac4acd60bd1219cbfccc58a710088142a067f32886aa82c3f405e4556a225d19bce89bf343e81d50a6d4be79194ac8a0aa9c76956bb7198314116ba35b71965053c94ae6b9b465adc10e62c7c6c24ecd5d1ca743ba688a0fb697abb8103caafb60008a4e60a99feffb88740e8fa80940c744705b4c0a4881016db199c41dfa1a2912740bb118fb81719d4a912025744461f4bf0de3489fbc677dc9a4f6f42ec1bc5106f1f30cc43627a4ac38d9756fcfd2a63d2099be06ffc7daae11efa988c32e42b12747e8d2858aeca13104ce14301cf43daa96fb3e76d0df199f3c433c23984c99d1ed3fb0fe681fcc52c831d271193860161bba20c1cedae98c28fa0cf703d8c9f15723f18960033cfc3cbf60591e8d13e324d73e5f877f91376342d46df04a18813c301e80f2851f0694fb3eb6b22e37f9f770114e714feaa67419f7f8ea761afff0027bfdec468bcde2708042685bf8a85ca730a66b97c2c7f64187858161b5398b8ab70609ab5f46dbdd53b6d0a0a29db7181de4485c987e01199121dd446152ed0b2c98c42a9f4ac8d2af9a08352ba1f290294cdfbdb0d374a0023d9394420f03a3f3c1c92aeaee97175f329884d9d2a225c00b422052557d023359b85662e17dad1c1544284266ddc28401a36c36a789c29b3d63d0d5344135686c29e4bca71aae0d61069792df4ec2b74da107d32f451d3c40ccb2e61b28c5b5fca8686690f39a98e0bd424227e421af171345fee6a6a21a7e6c899978e0eaeb1b2ee0fea993f7dd61cac7fd861694ab3d4617e320f7a0f8a1193f57b78c4903256580c4b4b566a3a57aaf944f942e0b4b018be1e4caad824906794e3c3534c804a193f0545faf01de9de8efc22382c09914938fcfd835bd9757e9f63016ae88eab095281d336a166669e77a8a7b9dc29c108a3a72e33c2e881def218b2d78984bdd94f2a0c9b021426ddfc27bc919cb341f94895895ac4b50f90c452399b6ef209281d122440a4ac09d54875802a756861a6f0ecfc6589ed6d47b6867a3c3b1021c8895e4218001e35885e7d8b016fbbf8b23d8492f58b1376e0e3a9c3d2637524e98d3d9bed5fd1361cd6788300dc7353e6b87b2fc1b450faa7c415a2de1b2a85bf5392492da9fd57708795a56cc70ae9aa4b0bc01b7821ea09dd5238bcd13b437e48e24d0eb9d8c0188804b5f2981b2468d889d844a848cdc522a057190aad86d41c3deae6e7bfc6ce61208373ac6552562788b8b3738e4fda6d077377cc495fc131c77d71ee9c766929e045207030bfa189fe22a4dd8adb064bf6fa3ded1dca43dae837f2375613fed30ff537b2ca792ef5a638aeca6d83b5beb59c98e1b1cfb43153c2031a1c4f048c0db50e33c9f8ba078cff2ed0340a98eeae09450cd9a0b441525adc91392540faca0a435d78054ccb98f54d8ee3db724f37e52ddef78ac8c5daf7f6b566c6289ae46455db8d291e50c03e22f10ad033a62387ffaacbb3199f3bc7cb916840ae6d13887d0a251c90076a334c45973a45f92402ad9533e8cb7a048c0fc198bf2b995e887fc74937ff3336295fc5ec1d2ae8ef32d2385327db73eb26fa851f3fa7941cc66e9d08e8b67c2cdc085fb99014446e42a41c68e19c786f233f0160000f0e49549835f7ec527549857c3cde7bbae998605dbdb95f8f10d03516020da012eacbb8074a3bbade40ddb242943695e4c648902185038547598dcedc0c0b3ddcb47722b18471803bd37fa6fb015e4c93ada9931b39f4709cfc6d0244eabd2fb924f07dcd195184687628d6896ec66a1077a171c6c44f2f94d06de8d2b1d6dbe526ecf22e7ab2387942b29ca5cd12732ce91e0745910145faf1ed37102732265356e6a9f84dac264a2cc092fd347fb1bfc615ab5705789815c5e57814092ad39824e58f07e1ef5976aef0a91a408523fa779d34e8ee21d6b530a6c0f148649de98f2b7cf6a74628560bec41c78a3d540b8a7c60a405185d6142c2135ac67dd5adfb3edce303a24470baff6a297a38ca41a50440f8cb55a6f8e13e2032cf502dad150d862731258f317ce4908ca7c173170d78b9e77d4722d192dd49eac29100fc92b07bacab5bdbf5dbb5e48119212c10f0a0c176fd2fca62d799fed550d322435967118e08e8d4ccb5cbe997d3d4a075d568b9df86016b813b0bee37af66ce2d3118a9a87129c9d0424d387541caab30ce600eaa1f5373bed39a1f36a6a5782cc1c60b80970c6cf4fc4f8d68dc5161be0910283b1be16c8e771a65338b3f9052c032ddcb3448343699338176132570580ce264d51902a2e2d53d4d2f64df255060c1f8650d2362f0773a740dd27d2bf8a6ca45668d898977ee7e0599e50be234f75b8d2c48c04d28a0a978725da384c6cfe6be3856d8bc7792d1f2e5d06770aaa93d2d766052c3fa098f44bc29102f8a44b4e7d33fabed351e302e9d7ee578ef560acc2a4bc20fd944c660886fb69505cc9505c7e16ca23d8ca50cccc2f4a3dd56b172946a717f010320c555f07ada5f3eadff5ebb8f1e4f8f26fdc2abebf70bbc80ca59c1d99aafbb2f8eeda3a23ad234c4ed5a429f95ab8c8127d6c884aa5fdb4997df0a70216baa557869a03fd06f4344bb5efc9a9a5b624607e91533d7ae81053bae3045039449fbbf32d444a7be807f2daed8e9001900965f8f4bc5b9348e7fe00743cb00231e55c25a6f6e2665ae2960d1b355245294a265a24c63520cea227662eb2260ff908f7340019c10b3ae2a164d2d8d0b2e688e495e53cc8614233fa81f532b4986462fd067128cafacecc10ce1057915229622f3acad79a006e525e95471737b72f694a5527b92005e24a0c38609d295c4cc4e44aab14facffab79c19ffc57ddad932ab426eb889d0b7a6ddd250e908b41ccff6860d776366be0c706382007b3c305e0e1b544c8a489b85e1f0a27b5bdbd5d0cca9d1e4e0334cbba14bbdab761595fa94508091cf00952616f549fcb31c60178311e5518ef13accb8eaac49ae6111054d608a584c7ff7c7fa877f523bc2161858fb9548cf79b49b7e27ea1642147a49e9b8b8c23eec322eae7fb9f64e7294087efa887c1d0ee738ce7b71137e580fc318171781ead39c6eea7199130bc6b7c4af1f9be7048eab08ea987c6b1565ff437e0cd1dbb445c0e65b8fbfb90d7764cde690e267895e13c09131cd80556395d8cab15d5371f57f707951f53c62b66a864d0b34050d06c0fa6325a2e830533834ba4734dbbe572ab1fcca255177265600227be213bcfc15f22d4fdcd1b1151c805abd4f20633eaa66ad6c2015ab08f5af22e25b1ec499734f0c49976f7094021a81875778be9e2cb8ec8f133761dbfad31133656427afa9bb8cc57779fc2d8236ef2e885c3ba12c70b93d7f0afc5217288a71cf5305fb1f51557d6b58a62a834ebb60b84bc4287a39221d49192d954bb962625865ca4bb6ed99641ec9b414cd150d93e2fbc922c984baac79a54f9ee46b76510f8ef1ca212928bcb94fc155e2974a60bc75e759974946e7e1b8e8e9a80c4f72f807731bc3e3fad07cc0b2661bdff1183162f867a8b402bb6eb303d2687f276ac923bccc779bfb4a45f5c579e5f9a5d530aae110f1c120e8a2dd3afb40469157334c3988342ae7f83ad3af86be75dcd4d751147a12f4ab4e490e8c260f04d2455254e0800e8e90be8b52da3c28f81e210621546f68208c716a12830fc49f59007c0ea0269efca1432008b7829954f2bb2a97a94e952801f77f69bf78a114f17755850e9289445ceb01b1fb24164aa85d0be620e983573fc2d6615afb833bd8359c6272470bfc4b565e922b767463ed6932fd270b358d6d2e4604d31b6fcec128915705d515b62e6993be3babe878c555f5b929af467db2f9242459abf80c75bf379f0800342e8b71fb17bc34b71c24f2a278cfa008d60c494cbce69e2b3055a7243ea9721cec61dc6f68655afbb4849c3069709220bb48e25a8060ec8b1da393aa2612c21394cd67b1dc5cf92b6753433901ff1b77903606310196f0797f0a619af0485617826bc9728748a9c34ca6ab7e1941163fb74b174411c37d8b7c39dc7462921466ca8ea12628507aad6b1f56b89aa55aabccba1b4908f092d4183709312bb44f19c5b92155075f7c90d3311d88276194d772fe294bf3d424f03179f6fa5ab0aa7aa6b6ed267a6975398e74a99772755882030ad68bbc9c51edcddd12e153de674184ed6bff527fee1568ee1a081aabf4ff3c831537915a15eab8d22d063f8fbd7782dbaf1c21723795edd1c1954056e59badc4cc25aa293bded5931d0014a05264abc5851518f22c7d306c40e3d856e40dae6fc63403f8f973101c4721d4e1eefc64bda8c127c03f6f696847822aecd2e2419ef1ffd6dcaeee57ddf382638b09224337a862263044d3038395c27768c6c75f544e7458f8f12770fb89b06bf85537afb1ba8c37b8e9c7bf1f8fe387f45c328b07312245487c0816c5169f2e39fa464745731b4443ef23b737883bb9029524702ec31353f0e7187ce1cbc10ebf7003fcee6de2f4f94ae695d1249a62398c2ec96f2863eb8dfe5b4900c10a6d8f8a1e18ee4ebf1fbe44c9bae41833c80a1acfb48c7bd4483c35da69384ac6eee5cccd4495c71a748d3967a40899b03942ad92b6b8354384ced92a295d52b7745754a1ebfb73b95c3aa7379b4d649fe80eb196d8fdfce4320ea773e96f8f81d2a33ebde2b873ad182b2f8cd9affafaff8565294caefea0a8471b2de76f07b1c8d6e470d58204dc9d2e0bf9896cbd740ea611d7db004126556de86070a617e40059c1e670a13be3515ce988e27bdc147ad6a11f4c45fd9f7d4f24855a6ad1d365581442373ed0cf16ac0a4b148f1b91330ea8e686c022cf5fb0a79014057eb299e6e8237755bdf9d1fb2b9e447a6fd80214ce58437187340abb7e44880ecd77dd0ff6720f6df682fb4123798e74ad8e0d14fecbfa6d26b84058dca6dd8a60e33679f2f32349f578307e18d198eb62f1d193cafcd4c61d4360440a44fe006c9d4da5b322891a4854f796d2891e1629b709860e3841809c874f0815f2dd1296594b8d45db89944e9064920a919d2c3dff58f39050dfa367a483619fcef3f458e972d7b57c8cae8c6103b2e8498d3ded5b1f8c729a61bd462d940f50a23eb443a63b9962f90df2d3a66b2745341671bf4a1fadb605650bee73ba3ca8663c67954fddd52be012b4fe49da2caa2980d72215526c17a70aa2c3f2f5ac1d271cbb8521a88ec2400b6965876e58d5f34664a25470650c54af20712d9f9b622a61cc80eb2674310c05187eec247282c4054d098c550f696c83508210d83b54602602b8457b0b134501c980835acc2487e8336282cb5929d90a0112666ea76b882e9e6dd27051940ce6b8755867805e90725cc8fd0f30c3eba8b9979dc3dbda4331d83a32f2301c76163e906dea6565d1e3163211ddcfd5bfe1c373ae04038270124983c744563584136e472c509787b9e4679d3f1aca0650387eac7c4c5479e604f03d00cbda81820087a86493f971b70c5c0e393fb7e46f157261f122e56bc62d8e040c1d1e8b45488bce8982a608d5576ba1209d3858298d2f4948f8a2f9a54c8f335f30c26209cd39984798449520ca25a841b1951245cc2920af054a4c7edde2a1263a96aa1ece339478baf7bc55bcadb26374891c02e28181070f9a7f1c9a0a1b30224eeb673490aa095a9354962363b9a7d59832858f4446640a21a4bbd92e21d778ecefa7ee5bb3b5c2e2d5b8cafd84d55ef05cfc639e1e43e32fb189ceaa1887520fcedab8a5dd3405d901f6071738f8c88de45873b1003475e0ac29c39d54bb54cd7200bb4dcc2f213e5da67d005c7e25b7b44a9940d156b1c272f9be1093b41307381011ed4b067b0d8c6c25b8d46c0d4a381e525bebebb8f911e1eab7ca0f242f635223f80265e894c26c2d568fe473bb8e5b040c4feffff6b21dab99e753294aeea2efbee836ff291fa29b02c2a0670718670443e865f1ae9a203782f076f4c07dafe58dbd8ffab4502600df3fcc1f1d5f9be48f9ebb6bf89204b0d5306c6b7b5e7569b2b057fca7ff848f77955447682966c12afa3237dbd3f151c4de695d7f887f40ff34e20eece33070775cf0164d61c1d836ba9e75b8d521a8db4da230502776f905d04bdfa30e52771556680c57b2710d21b3dde6069869d749a0650b8bc5dbc3d2a71427c95130169dff4d67dde9afbc81dff902f06e36a4606fd7d3c6cf2b14bd9680db3c92cef28f7534d747b661ae79b70b4da4e81252321c59f7a50c7675004185953135c1586cbc12d7b539b6c35b2cbdbd842b8be4d0600895f0c9d38c19370569b5f1b78c35077edc258d33873bb9632ce9f38efa1f4ffb4d2dd8adb2ea26f0b2768761737b1c293fd84cf527d6a0af8abdf59a75ad47282cbda8eca4f99eb367e98edaf6abee488ba68ea4bb5a1a879e829a7a2bc878815e4daa5cd6110cf6d6e35ab340844785a4712a30f59a0a12dc3ae27f15d0d54a61cb0f54c37a0f194fa2424a340b9b9f5a47d852c3f9be3c6b0e1870c6f543be3816480c7eb354d3d0a4889f458081a8b3600b7100380ea8fa1ab0369b688a495bb9dc761206013fc8fdc32083fb4b8da0a0cfbb53a3e56c88a578d434627ae425245a30c62dc7f89bb08fe0d37d9550100d0d0f2b8afc6f5cec458496bba88bbfe1a6f0dd84650397cdbe3e84aa28d249a5f0eb3222cf9a2384264b7639211d534f8dec5d8ffed814cec314bd44a4b44c346b35f59ee66df087ade27e17cd9e833f5e1092bfe333048d8858ce79c7fb1e012e87a6dd6427d2b2b3e5fab6a66190c25486ae9b8062265b6ab2c57c98905e8d5b55a330ba6da93ac4d1bfcfa690d6dc2d2d68eea6c453b38535cf69b5644987c92d00ca21bcd7e93dfb1aa8e117e35700b2ca105ed5460fb024e1803d46e245f09975034e03aaf6f9106f9133022a40b8cd258ecb19838958185e9144bb41e5824f3de0b00c3074f6e50d6b500920d44b8188721f5f86bf98c64bbe98162b4e593c92f52d6a63e5c23459db995c3b1a7528fd46ce155ff93d3b56c885f948b5e77ce65a72f467918d4de8b29f7576db05748940fb08b9edc855e84e6b7ba8a5f94aaa12e23d3ee11fc26dc9d0e6ff938712d574265152614e66c8b1d3aabb0ca13cdd9bfa42f13c50f8b22903a34445fb494521faccc2340d5ff863b1275a9dfd4ce0947b7a706d6d4906dac663da7a804160938d71bdda52cd5fe484eb1bffed02f4b84cdff648369192a27ecd474d1d78c70e434ca1930d6dc5bca28aa1ae5417b18f0f56be1683fac89a27db3c996ed9414952d9e0aa8ee4eae7ee3ab0da5c39407e469287900ea3aa29abfdc9a76936369dbe880c7ad4992d29fb5abe3a071410c0ca75dd28b2295ad59ed66816c2cdfb6917dddd8105a31358d7ed7462da71bd2e2cbb2555b38292d6bc63e2bb1965d9828c0b948954a30743ab15173fc2344794bb744da4995ebcafda492d494231995e9d21cc8d123d1640205fe041a1b359591d306d03c977c68aebd5befb09ba8137807db1989c86ad0e11c735274553fe981e05fda019408594a056c29f72b77a06132e56ac693ded2cfb06c342590c9817cb29f1b6cfd1b57d460ae65c113d6ce7d1e290c116dacc0a690c593a7508d0b2fe486148c334c0f77acf97b9f2b6d9164eb22ff79ae42794fd6b0a0d4652486acc41d28b13ca0cee6d9744d0804ec5a880570badf32206409db7da9c663b42a4972cc62e1838841ae27a7ca6f2f8b9c40dc06deabb65ee72a52d1cb454f1087c07ad8fa573c8b917a3482bdf0d453eb744e76214d70277ffa413b429855e0ba1b5e3e8dcf5e43242ca688901801d876d80d1cfc1f5749467838f9df4b7096cdce7289d389eac0b1f10a27d614cb2c6eca4a1f1385e25ef77103585a9d9b4e50552a751ef1af74c35ebd474effc1a8480a0be8ee4a854a31672b2cafcf44aeacd944862572af752b1d9ff6602f9ba4ad86925541b6920c2d26672e3d0688736d2030c2000b3f9818c9e3ccfa13af7f0366db967d230023a67981048d11f20c66be614fe1e1d19032cd5108dabc0bba57f77d0e4d5aee02eba5a9ee07c21c8d8d6936555ab47f2e8d90c18828f245ba63b260f8067d534b83286c9533fcad4b63833373b5346e89c596e87b3e5de86b1dfdb4342f954e41a235fdc628be5532d2fee5cd827ffb0ac4d280dc209c0678ec46d3e02d5cdb2c9d83254b4968804ff0888cab180ec2cc20fd720ce3d6843e66f0382767d9a82bce5a956eb397c52040bd5e1f7a3c087e3aefb6276a8fd9cbb3a638dd367b98c0e6fdf4d8c33e93746a54223fa365878f6502cf4da98c64db48c3c58bb8c563329276aef7a16402e953317dd3aa775e84832fd17a61885b18757449afcd22e813fc7f6aef1062862645423de483f4bc6ffa76cc6ea47d48ec5320e4c70fc55f2e38a081b595791820d63a6292f798b5698e0aedd4eec5a79efa2e23dae47d4baf1aa3ce1e7b2c9a3fa469d9dd4ca50e5274d92bb49bd74e4e5c452d1f9c1c82fea3c62363a3ceb526b95e57c218b14ddd5259f6ebdc23719de50babd417660c02a52d644cc8a21ef3fbe3f191a3251d6cccbc19ce6b6dc603e6b5b66eb3e871526b1446192ebb64b4c1bd6bcb500712d68cf4eb7653181a5b30e2df14220bda41d8d6d209e1e902d36fc8b7ae844867c7239dd94ccc364c44680532ee1a0c5f716e186b621d1472f53db3022d2d033e4c812ddee86adf79c2b0e00936b24e4e0175adcdb096d305cc685e06276d22c68a699ca4daf0c9c39af6135dfdaababdf631c0967809f901fb381c562414ce82eb9adab127eeb22937f68b8c65edf15674bdca1057bff8efccc23074cc705fd60a8e979c969c5083c4c993e58f7ab84b8f829c621b072b273c731b871842b28560c40b575ca12d03c042863482ebb20f246c350819dd023e458be58da3604ee9814a962fa85225e212a3b860f93235e6d29e32724bd8353d56f5f63b2cfabdc8bc68f61198c9b654f0929bd18a25a657d67613196b54d89ae0fb910a06cb53e38b3847ba9e2813efeab77328534198535beec1692ceb0410a525b9ff08e92548e99234d8158ed9e0c7658e4906d9867b29f1f5536e7abcc4ceeaf863716e7fa11681d70c44ec76bf8549abca60cbb49eb609326b7b42118756ecf885a000f68b8202e090d410132bdb1963ba707e9cfbacbdf3f249bf336a031e38af81db439e0d14e00be77c75e2588a3a0267686ed1cb69d1c8e7b7126047b7011aa38e0acab32acf1c4fc8d2406741f2640a85dccf25485562193a2d81ea2c2fee112aebd70caf5600b002ea828bdfe642ca4e94094b60ae57b2fe46c897b0b517676ae9d50d887945ea17002d189d8ceeae25951cfe23f34c4aa41e7efc0560337a3742110cb2545a56fdf6a26f12c64974556574e90d18c0df00ab29d2dc53ad557465919c8589213dd096acc5f216c6c4afbc2b1c8421b8b8d268ed2a86b775a24a7a8490b2f5f85f65df1218b11a2b9a684b86402a5191daa6e4c16c7b02ecdc1d4f486efe215258e1a377fbb1f622ef5876201f2290a0faeb8b41eb337fb55e44990c67b6bd72bfec5137244c93641b1effc213d2579030d1a8ce5081ce3590f674a254051a55c9910ccfd18feecc71b6243630c869045959db6896e54281a82bee422cb1dc26056d220f39e0778d58ca8864f4856dcf8c6edbfed57e6f6ea8ae2c961d131bd45f6a62551c65b4e8eff00a15bb8e9bdb5f3af320e946d0be0bed6dc376d09d500cc36cd5608acddb0c16ff9524d492e81e222b06d651d6ded1ed4dab6b397238851cacd253f1cf229231700fb11ae11e2b99cdf575f4152781d04aca9b54e4b5c218fd08f7bf4f1689e117cce0716f0c1fc3b719a6a72d68d41a69d8a3462fb8516499635df51e622c8a374ae5059c8f6f151540541add57923669766bc5b7a5c50feb739e4937fd2442808f2839d9f04a492c41ddce057d45a1ad58e2eecb7bade4e8ebb974a023b3be93d6e144bdf86a2d8b48c5137eb206778f914b34a05fb7c20403baaa4fe187d6f20b0bae8e14146c5bd55b4a095d35fa49d21ee35bec16101948eb420590aef2f81e2454f4507dbd282e25c0bb2cf0f30bde2e6c85306b4cb4227cadf53aeb2f8c9660f334d8f055a4fb7c33b21b075a8af1b5feeb1cfd0e3228d605d500091f1158e3ad2d6ba05c08a04f074b33570f87d854af8ba2a887fd6ebb9bd665d4019e16db4b2a23609805b3158a35e7a685e9c99ac493d56c6558d04ab332202c6ef20d5a0cd5896b517d0e66cfc6db2d214e93ede287c61cb227dabd24187455298492acbdac90a4295649b41ceb9ce4cdf5b069d6e5daebc3de4ed82a23bc068be892f0007690323d6b28fef64fb3c28b27d8c1fa4b7d5ee1e48ecf5964c3a63c70ad5b12b654179b3a71f9454cdfe78bf7011067b782a9a821ba9412b2043a43b4d751db645654d6df73d443130bab00396b106881a1879e74865597a22e6f6ca2da3536e01d689142c3bd020ffd00724ded01252a13f7f6592df86c56762248febfb10d0546f358beba0ee87e2c418fc0d410ff489e15b1c067dc152e3a813c6c96933112daf609cb5de9d00a961964760bfaa4a3e415d1ab354b2ac301b9d19312630f0b22b8b205dd5540601e94c95879f68b073c48781152e6c757b2309dd44e358caea24cb4200545316c514f3cbae359117a9e9e43777bed171b0e2a759ab4b23f18648ec13f2350ed903cd7e8e4bb82f83bf471985bab928a7fd670d08b241e5eec3fdf1cb1745ed848428fc73e0a142640c1242b3ad3e11d660b4c454f63ae0d04432f937d07055deb32c42aac32c4f622fa9752ade9aff42f300dea3bb1da3ba137759812ec0204a2fc94001a4447dbafed228d4cce7cb9558dc3333b425da5879128a1bd9b169171288c71c01df5b83f937293e70523a5010ec8c45747eb7205c8e36430ce2305670d17c8107a5ce60d54599a64dfe406179c7d3b8169d26fcdeed9815e6f2214bc501c7defb873e22ba6f25c849a790b49137ab19487d9a264489a9339e0b8772fb2c1412910e2961a3a821323af51fd9c11d10056248e0f8e59e6e032a87c15b354fb2e53d7ca64473107be7cae621d4decb2e74750fc0acb0c4817f21fbdf2ab2dfc5232c574c05a9f794de93cd171a71cdc7b2fdfb1369d289d7ed5056bf7463bb6e8f045a883afff3cf7483cfbff8396aa0e920c676f6856f7e75e54134758a096fcc99d93a74ea7f60a809772ad5d34a7572070192c0a1db44d2b012520e3aa5ab3c22d550e25a22865d87b60fbbe312f31fac14b0594287ac1e44ea4d84a9086a27a6f9d167dccab9af8c2b5a36b6b6454069e9334e6192a3cdc6eb5ba6964e68053ed6124b06834e8e28bf6f24cc2548fa0e6420230edb41267c6c260647600059d5731aa4d95bd474657a1e9e68d2fdf057ecb888c7349cb9016b0b4bf6dc64d8b6b82c0b00e9d4d02fbc605f9f8b4151f984f071e3784ec5b35815400d07474aab0a4d679a3b6a2037029b7ff799e04fc60fe49da0710708f2ceec3a07f548b528220ce9a2e082c03b668b4ba167320d3d2e70beba9f65fdfbb3e09ce2e354691383bb4aa949ac8680b5bc7b831ba30cd4e9dace9d75a394b2be08a2e5a21a4f47d2c92a739edb259737cd168cbf2448dbc0fb8faa309b466fd3bddcf87b88307fd31488b39b2fd5b922c8b2e6e453bff44ee6318f1d792c016402e18721f3c26468ef608d87a7116367377122620732504a3664c2adb742a4f93f55e92410f199c703883c14e36f6fd8c021c8a8c04af52614afa7c4d548a66f8c1fbd4da5896545acd0a1c37d526a091426e62821b4aeffb4e3729a60141fe4a98fb9167fa8c329452115369919c97f11a905bd95c472f5b107def9f65b9d5c45fb11f3b78daa79707f0eac1d0bb2d0e0c2e2828f50b779333f87a6e7918e87bdb9fe6e9b6b593692eeacda9e97f113e3e26cab5d9dcb5878b491770e7509bcf44fb46dd94451788d8b7eb5bd8ba5a5b45ef829d2a87c663074837e68f294a1b714882911643f2e9e6064547e08a4e64eced91a0842f4240b5a22a2c356936a137e9a6449c49f494e319b4c88daf79809561122de4b66549c18868ebf36820c07955c17ae0a746214811fea2409ed3a3a031c1a9e7b49f348e5187856fd9742f2ec6c60a56b19e1e59748155929967eb262608be05a198d6ae2df488cfa48698284116218666fe2e79fe9d0ee001728da3e10162a32f2d84165d3d1e4f031e86095cd4c3c3945b6d3403def0a97547a35399d091f9b886c41b0322dde7d7d726f05548994515996691dd6d16a0f05c491a085eb9651424900ce6944aac20af16fb07dcca05be194783194c1048ec380780918008a826109909880435180881e0ae88cc39e218803829ede460398d8962130cdbadfa2b7aa945f6c48f4f3e49638f863f5c16682b1f4fda093b3d61f566d6feefeeee2d53bc18601ae41a4d82699babbc5553a2dc7cc77255c91acad73ae54ad6745542e4e952629bb6ba693a8ef25597a673d552a2aaa64455d33455535555d5344d7d2adfbf1c4261cf57087a8ff2b4e5bddebae3bf867296ab41b523621aead6299155aa449eaba684b8e35b4d75d594105b374de568eab2acabf6c4cf218462b0a74c51a3b86d3e45f70de852ab20febf20ca7bbb97fa82827bebb78409ca75ee13e5dba743d1f687fe9a04a7d0d84a792f18c56d6fa57c0a8d2d95ff7859eaeb057f3fceeb71b7bdc5e39bebdce78eff8fc76feda2f896f0f8deb94bcc94f1f8e64b7a1cfd2ddebaf21f5257cbd9b4d615d38672d615d396721a4495ab3e9dfb4cb9cef78b12a40b46e1f1cd739f6994254c52de739f6994295c48ca7fc1254c521ee43e53fee391f294a3bca0dbdee2f15dd06d6fed782f18650a8d2d1e77db5b3dde4383bff4c785c443e53f2e24e53eae0b46f9d164ebb7f9121e4797f47aba5d706f0522b26e9a9836948b6953d79f18cad71f120f95a3bc4c4ce529ca5ad0d3a556287ffe5b3be866468d869bca51be8351dc54d7cc4e4bf9de3f80e9d2ca775c8059bd5d971d034094f77af39ada0ae2cad5548ef25a6d0571f35f7d473b68e443abd2e84dd44100344ae344feec95e8f5d0949812d3e7bd377fd373f49b9ea7dff47cfda6e7ec373d6fbfe9b9ee9b9eefbee939ef9b9ef7bee9b9ef9b9effbee979d0373d17faa6e7c06f7a3ef44dcf89bee979d1373d37faa6e723bee939896f7a5ee29b9e1f7dd37313dff4fcc4373d47faa6e728bee9798a6f7aaee29b9eaff8a6e73ba8f30078e783288aa2288af68edeea285d7a2be0f329c0265380db4c0f457de99aaa20a6fcb72ecc4eca2e0a107582809c12e5ca96a7a9b5c134b5b4963f511533c4db605acb51dee30d7125fb68500c116f836a425ce5bddf50901d4287788b3effe98284826942fc893c9eca85521e30e56d90070caa6da2aaf67c4131446d50b943d99f4fa76bd91f91991edf431ced295b7727860845834a5d500c91ebc6b786685625b6667edc0ccdf2dfbc7da290af75d35ade06d75610d11ebab3a1f7a816dbea763cad9e2f4868883f6732a3820b05fd7c3dde4ed72a53be7f5d4fc494ab18eaf978bd1d4fb76b756ccb99ac3c0567b27224ce64e5273893959b382a4162845191cac5b09c88d7488929822882aace07343a42c15b28310185827ebe1e6fa76b5d254c56feaace07343a42c15b7026abdb64333181b609f450a0303a3a2a3232220202877cbe9dee94ab3bdd3fbe511c1d3d3732e240e0739fefb94eb7f2f7f1e74644454344c02121a012263e313fae128d5c2528941c0db94a8c8042ae129fee378233f1b9df73559eabdbb93e9d0be4ac7bb48e701f054a85f2269bc910ca52e9a140a1f4a9043d95d5f17c41402214288e8e8c8c80409f4fa753d5a1a0aaea743e1f106864747484020570ab31f4bec5137bba609bd6721edf055bae0bb6bcd7b24fa06ee5693b9ddb6cb9badbad3dbedbed76bbdd6eb7dbf57a7cb7b6c49ebb8612ebdd2f8709e2ce45cad123ee38528e94b873953cbe0bf2823952e20ee52dcaf7db1a0745f93c1afcffffffffffffffff7f5dfb68aafe193e9f6ae1d205eecb983269d8c4b9419552f40d9c38754eb073670e4f1e544929d5adfb4d0b972e705fc69449c326ce8daaa4854b17b82f6394508ea2fc5ba44205f4be456f055ff16a1cab22050aa413268e4a9018618416110d0185827ebe1e6fb782f750df0abe82ebe280ffea0aceae4039e76ee2d8a42933e60b5c97ad270f9eb93b764ea81307cef29998b818b7b81831d8c080916669a98c92125767b5177c73b5958b697ac1a9f0ada8b726578b30c8c5894597a71670507ce56a49fc4b940b4e856f413db5e054f89693b0c95d62c65dddb4d555a39bb8e02a6772770c77c370f792bb95dcfdc2dd2edc9de4ee16ee66e16ed7dd41776b419556709e065dfa389d1c10ce511d74e99d74b1832efd18e08a15e8de6e882c9fe779de65882c9fe7fd85c8f279de5d882c9fe7ad85c8f279bfed2bdb6d4701bacafdfcf37efaf8583eb37c9ecd502516cf1aca592240cac47478dda8917535f5842aa55c6d73ba09b1e6c336594287f2b4dcace576f2ccf1e1436cdb1e133937716cd29419f305ae0b172d6f57dca2ece71f3f7df8e8c98367ee8e9d13eac481f386c8ca655db12ccbb22ccbb2bb2740be7b026479cbdb254f62da327513c7264d99315fe0ba70d1f2c6b22ccbb22ccbb22ccbb22ccbb22ccbb22ccbb22ccbb22ccbb2ca2d4737216eb74e9bec9c009158b64d594eb3412e928e0d625996dd5c6982f3f8769f0911e5691029882b55624a0caac1b496ef9c007d5cc7d358bef2f6e7aa95e07c461ac15b3e23152987f8affdb94a22deba4a21ce739182b8d284abaafc75fcc8552be1d24d88751362dde36b245cb59618c467a411aed79223a374462a72bd981059fec41a38e4aead202a5122eb2ae926c4598de72a89dc215729c47f1ce83a5710796e1aebaea54421772d55b29c6642ecf127fe82df6bb173d3d2e78f865ead6c42dc7ccb117b3b889423253e4789ca5f8e1e71f30faeed1ce91222ba7df4be455aab7c227e1b5cb9aee5bd5d50c9840f71a764b7d3e9d6273162abf29ebafc3922afe5edde2ed26e7dceba485fbe2771e53b8f12a8f25fd174b7d72cba304e1c80238201ea884d8800ea88a893324f22ea040139e2e66028826943fc89aa1a0c0677ba35c883288aae9ba8737f5c2a47c17b4125ead62811c8d321a08be4f3e9746a2bdff11aa99a12a2ca67147ce5288269abab1413e4439c0951170cbaf1ad2090bbf1ad2007bac1204f83c1df5a83ca1a4587dc14fcc787b83a34348434e4d24348487c88a340816228f89bc8e3edf86a229856c4972a88b10a621137e247ae72138f7a3edd8f9fd8b90189f88ffb7810ef058de03c4e82ef388f9fd0f901aabc04e7057124cea6e02ceffdcf841b5cc1eb156b62a4701e5402656f05b994204711ac3711054f11ac37310590d33a8e72949fe043285c1ac510a783696a9ba770e9145c05a791b80a570de82a5962466d73949b39c1a9f0ad15ee12336adb4d5323d2483c05af91a6086ea44d448346a812cbf2132c37113c23ea8200aa9cc77735d2a3e0134b046795c8721223824641375651b34495d7408982f526aa3fa120578fff78d087ea5c2547ea26512d0d1428901f22b0250eb9ca266a2a11e8aea1c41edfc4defef550cedb413f376df5f5dc3afd163a77ddb969ba6fe1a671212cbd99dd711eff1660c680f902068ee56cdc992f70bebcf922f7e33f1f115d757888a8cfcb1c11e53e94c779ba33bb4795546e842aa9fc085552390a265449e557a892cab3502595dfd0812aa91c08aaa47222a892cab2aadb02063a3d1deff986c41471219f8efb7cdccc0b0df1e7b4ce4d637dca1d67f99a0aa2ef85788d127d6b2a883e5ea3442157c76e22ef5125e5a34a3eceee88b8904ea7a4e72a21e2719f10cbaa6d22eb2ac514711e8f1794f2362f683f5129c4793c4dcdc77f6e8d12d9a0982236a8eca96c500974e35b453e9d4a2c7295147126443b3e145453425c8bc25222902868e6c77541b594b8723144bca764dd3a484cd110d7e98482628a5c37be4544fbb81bdf223223c4cdd03edd8ef7d49810d71f900705d536716539ed73d3d8def3dc341ddfb969ba5f941ed771152d00c8baca20314db9b68934cbf23594c8f2590d25ee663595f8e3b39a8ee8e36a40628fd34c883bcee32dff4f7faa904f47b35cade7d22c5f031259be0673b0ac1222cb79419ac7d305699d8ea5691ead72b527d22ad7f19dca5b5e23e57155e53551756bb4c96ea755de7e2e9d43ebbcc9a581937baa7cf8a4aa9fd50d81dee63d15e54ad655e5a6f4be458fad9a39110f30d5e500d4a59cf8dff43ad45512f121fe5e6e3922ebaacf55955d57d55d599665d957e52ce8e9b8f2880f8c9a25e278e253ef880ff1d7eff19e8e87a2e846837c40fe9b7bdaacea53e382e6d4333d951797a2e9d35579ca55950f3b47410f0f70cba0aed0dbc457aa72370053221130c8c7d3b1e9afd7ee8880413e9e8e4d7fbd5635220206f9783a36fda9bdd6880818e4e3e9d8f4d75349201911017d3a36ed212121a93f95239130220206f9783a36fdf54e1cf5d8df09aed6434a4f20f1de1109232260908fa763d3df3e226144040cf2f17429bb8f48181101837c3c1d9b721980a85a23c797178e2eae1b36b6889cb8dbd5c8f1e585a38beb868dad1d1180291a33640cb1aeacaaa83855db02304563868c21d69555554ba595a52405e5d4c41403c6125f5255ad2c252928a726a61830d4a5a827218a17492c822b54a440428ae2b30f3ef7e073d94ce6ce637ce6318bf1398ccf607cd6e1ee1f2e7cb4e8e19671b231133cc4c2c07ebfde09177cf6c1e71e7c2ee33399fb63eecc83cf62ee1ce6ce60eeacc3dd3f8e7c90e861c47bbd322232e0180fb1303076ebe0b38fb907119fc9f83ce6ce3cf82ce686cd60ae0eb707872ae101ba896393462da38e51bfa8706a17958bfaa66a51afa86e6a14f5f9c74f1f3e7af2cce1b963e7843a71e0bc91731397864d5a261d937e49e1d22e2997544bfa965e49ddd267efecf783ff788d46e30e3531407a3ace7ea0dc4f1f3e7af2e099bb6367c709bfd707f76166ecc17b14cb781947e1d01f478d9071b222637c8c080fce638818171312c6c382807130203faed6e38f2ae9e03af81f7f702a7ceba7d67bdd47957cb84ad4cc7d54a9873b17dd4795ca5c25fa8688f2d988fba81299ab44e58a8ca17c26e23eaac4c39d87b88f2a89b94a940d11e5b310f751a530770ee23eaa04e62a6720eea34a3a5c253a06fde1ee0c00ca29774f3e40e54f4e2703f0b9f2770310253e1ea05295b301d8fbf1e33f780d1f3e788e1e3df8575919f7d2c189607c2b8cdb10e3377870ae31de4536c68353e15b6261603a7a5cedc7c9388edf6fb7a3f7e33bfefb51c355aa6e7ce470956a5c8f2f57a9b229f372956a1a321cae521deb72952a0f2e57a98add70956a980d57a9826db94a7587abbee920ba4a55cb2e478fe7e0007c7df1292f2f4e03070e3ea3ab8bcbe0e2e2c31b3738d68f531179d516b7b2b145fcedb85a8fdbe057bd5e5b63b7dbb9730e005ca57ae56bca55aa6e5e345ca51a05c70c57a93ebb64b8caf40fd7d055a67e6e60b9cab48f8d2b5799f2d9b27295a91e6295ab4cf3d4f851b9ca144f4b63c76970ad193378960c195c6938e4523dbef4e330a8788c2ace64c59baeb813d69515a7c2b7aaa87ebd96abed381687daedd4a9764743cb55a6776664b9cad48e0c2557999e30947295691d2c285799c6b9727295291cab265799bea9627295a91c550c5799baf9c1709569dc546fc955a66c54a9964bf1282828fee4e4c4854d4d1c0513137f11c3188327c180c159ec788a1e57f1e32b967ebd9dcad55abec4836d8ba4a4b61c89b75251ae322d03f5e42ad3314e4257997e6942e12a5338a617ae32ed1223c955a65c60b07095a996a5a0ab4cdf7e2b5c657aa5a7c255a66e4aeea34a48cadd338df2c2f882bb484ae22d8c2c5870d718e454f8161ce4dcd872a1e38e0ff51e2f42fef808b414bc4452053701afe054f85652458a5f3f1a8d1c89aba97c055fd3d4b69a18142a3fc15524ae6c424472e7172e5c25fa27a985ab44fdb0705d25da27b8c245f5a870d13c295c140f3a87de41eda0701fadd3a2271095bba79a182347e2287f24135c8c1bdf3a72b5122538891123b8515111271a1ae240a1a3100f42fb71df51e5696f39cb1fc991b8da098e867495f4a36a749798599190b8da09374d6d1391f8137b9cc7914e706513e209773671e42ad1382548b84a14ce08177d53e4ca0db98fba1172d1b89f8bb241d3ec5cb44ceba263e6d5edc13dfa8548f4a2dbca0a3ddd0ee8ef87eae680ff733daea301d8f2d6b7e33b1e8028abf29f53eeb736a8dc7c88ecb760dd34148e4caa7beab80e253e518ec63ddc5a67f3fde3dbc77d4a14ae171714a45ceb04b9bab8dfdea8ab7c22fe1a9706b9677c71bf33aa2f6ec7dba5ba271ac73e7d807adf42d9d3fdf8af0e5107e4bb54b707886e8e069f06a01851d503543641d9e04ea7ca115114f5b9cacd67b7f65c3d40b6a70b2ab79c128573d225cd4ec777aeaaa6bb20dbdba94fe53add558ddd4ee7ee76aaaaaaeaa368d0b768ddb4e5cfb9ac9bb644e188295f83aa9b86c2e954e8a9a1683a37cf11b78aa2db45514eefdd44dddb4f4fe5aa93304f228bc2a13b4f1e3e7c523fa99f774bd3a47912d3a79bdbdb1b172e70e998e7ba31281c6a858e1993264d5cdc46e1c021fe8a3a89408eb8449d8c8123b2eef2e750ab2d872e6d0e87b8ebec3a737379f25899a14b9b6feee7c9ee5685b9339fea765c7be64c6a95c6a5724454e7fe1cdbf2b6f7ec71659ae64c8fa74c9fe8dc1976cfe9acd421a2eadb5c9af4a9eae80057385407040a1d05f1df19949d7b3e7570cfa70e0e659f28eb7605943b62e7d8b9b839253bd763e7e27471bd566ebd020acdad70ecdc0a97b2732b1c1cfaecf19eb2958b9b6bdfe2e41ef83c72e3ab9aa2707582a43c5d9d9aa6a959325d7abaa5fcc935534434041462d5315ca9a661d12222de7e4be39e6a00bef1da5d9d14ad93a6ae92e533c7fac9434cdb279fb445fda4679ed839144ead6168b725bcf9bec795fb8d9d4b97b8f08163fd8c7912d3d42d2edd695ccf55ee37f6e7b6faf6766675d39d725d0cc0d5dded1bfb43ef5bec7473dde69b8f9f273145539eaaed3ea37c62815db79cfab6e5e6cea4699ecf6edd8e4b1d383b63d43cab6e1707d471dd9f01ce006cd73d03306da3a4caa733ba336736df71db7d4ea21dc175ebdbcbfd5cdcfa9cfb74844e55d32b2357a9d6912b7295aa1d38ae529d23a643699c72cbc505c9b9cacd07dde95ce536daba107adf42a9f221a22d6f59f5f9f313fca8882b55b938209fb81f67d5b8364ee5fb85de885ff44f22ae3b0354a23100535d0cc0212e54c475677a6fabbb72222157b9fd20b9275c25fa34e12a553ba85b099784ab54f3a05ce2e488dca1cdc755a673c4cd83505799f25077abee5691769ba5a75b213897c20ab91552c0a580a43c9a2321a772a5115c2af4ebc1a17cf724b2290051f77b5c6dc95b14554ccf5562464d7d3e89688fb7a892292d5f12058a50a03fcfe7968fbb01b77a4b98fcdea298d9ee9c86eae61dfee850aa366db2c673eb4dd471b54de4f1dda3775c8de78aa177ae181fdadb4bdea23c9fc436a83e9f8fa27e8ce0886b5be4c64d5c1c1b3669d21495292a5334a6684cd197a22f45704570455d8aba147129e252a4a5484bd15bd19b9b3836698aca148d29fa520457d4a5884bd15b91165469e54557dc8aa214153dfff869fbf0d19327c543c4aa3a22b7e8ca905be406748ba208b945cf2097e8cfcf25f2d3ba447d7a2e111f9e4ba4c7e712e5615da2395469e5a94b8407555a5bdee335525555d5b655426c5b555577aa9ab229abaaa9ba0aa59c55555555555555e974efbddb565d01c872a5d0dc4f2e85dd7305762e85158046431af4be85d2c58eeb52002a5b3c89496edcc4c5b16193264d5299a432496392c6247d49fa9204970497d425a94b1297242e495a92b424bd25bdb989639326a94cd298a42f4970495d92b824bd25255dd9445c8cdb15b721b728c028494fa1a4e79fa03f7e7e7efa8829729514f5e1c3470f4f4f1e5f1e3c455c2de52df0b4985b9fa8d6624ea712b9495786dc2437a09b1445c84d7a06b92dfefcdc167e5af469c1a7859e16f3eab6986b8107555259954d55658b679bee34454264f7eb78bab74ef5f1b82fdd7cf3822ad7b9692d5ff9de699aa6699aa6749bf2364d59160617704228508f0b77d83b2cb4ab8e6559b6d5adacab0c3a5710753addea2ad756c759aef21ae9caae2bcbb22ccbb22ceb2ad735e504a82cf4be857267a9434cf95a66cc17b82e5cde585d1091e8e33488ba158041ae2ec8751c1854b67812815c6707f8442c7af4e4c98307cfdcdc9d3b76ec9c70429d3a71e2c081f3e68d9c9c9e3c78e6eed839a14e1c38726f50a5946f2c6ed4135c8c9b9b3813716c8ed8a42991a60c8932637663be20f1bec0f5e0bab45db86c2e5a5895abad1ccb1baaba6aaa3b62044ff97ac2dd58dc98703796b82377636153c2dd58d290703796323b776319c37337962f3d7763816bdd8da5cb7637162ea8bbb1bc6d2c5a50a594c7dbf11e90f7d4561047b8696c1a1c4f5c391aa4595688af0d7122fe2baa911605d752a2d2c7574e145c4bd55aa2ea0283cb164f62d00a62504afc0595fbed2d8ba81bf3aabbe36d505575ea5e591e27b6c194f3dc3496d32867398a23a35f896c4adc6f5b5a3c896d8b72f4f7e8f93d7af43ce7886b080f07ce3389cf173922ca5157d9628eb826bd11bd3c892a575ba4d9190044e19ec455b9df60006eb7b7fd7605ee85fdb6df76963ac423b44500bd6ff1712c67d7fd715bae6ddbb816add3b6eba33a2aad1c510de26abc2057a9128374e90e02c61971a3213e4464c48db82e0e1807f4f9b82e8e9d2be24423b8cad5a176b75351381241bad44db95a902e55e556129c445010cf0d0a5ad7d555f2829ea88bf3c50971e5e67366849172bf117122aea303241ae243ba5ed09996b7e9902a172417a744e1d8b9f64d288e9de371a090908e0e70fbb8cf17a7ae2bcfddcda9729c8ddbea966be58a76d19d9ece0e1c31e52b90abf1942a11c81b5a5138e2ba028584f8903bc4d58042432b1c3098d6e34f5c7f6b9c2e0eb8f278bc20940e1038c4875638e090ab64d300e58456b838391e1fa0abfc393a405d9c10079e790ab9ca2762fa54e5361d609b0a5011cfba46510c0831ff67345ff058d0fc146b088d460522bfce7900648c0ef22a002304b0c48a9fdf1dc1eae08f1101bfdf1c8192f524f92a9a10906d50a8ff11c100342208caaf60f6a4480612f2a9ce8b066048d079f680329e03ecfcf6498d1402f4d6a33f9470844b050cdfaacd719122009e679d84748433f0d1a025153ad481f16a1152f4073898ffc11286552438ff47865585475fdf47c19bb20ad2f0fc1a773580132494576b0e2630e00894f7315087c94b1336af3eb9d20f74ee6f17a2c4608215b77fb1006008c4a67c356b045e0c260ffcf340a78d8720b4474d20a7b6b460e4d3b42621c89191fe16e14a087d5268f3a9033020b073f1f66b179c633d84e3d710c0a49821ec866f5b7860cd004956785f1e212a24c101ceab7b78d0e26088f8db2459cc0f1288f16abdccd183e8f06b99056865ae107f7d61ea894e1f1edfd21881861acc017e3f890303074ed9b7279ad400a8c5935775288a7851a4e55931360728d1728fa6b0a608054ed04fa778dde02f50f9201392b2ec6821caf378406187025156cf667db9061c3df95ddc89b9007a00f2ecda0e06042d10ff3a940211f0cc8e57837b4b935608df06d9755046060c7e7f6003112e8c20c1a36b4e0ad49980c4ab32889c101460fdb678419423357d3684ae1c60bcf8552964ee0939279fca99d275854eef59152e9626442f7c6ac0012fbc5084d9b723906d9960b1fb9d97a228027c41e0d93869111d1ce05edd7281cc02dc9657a1486053e08fd7b30d6889f3064302cfcae0e18201602cff1d30410bbd1cf97771e409096be8a36473020862a2c7a313f407daf880e6b754bc678ff2f7ed9611d54483021e9d2a82899ea9f8771c020cdadd925755e451018848cef77c54a0400b6c7b5ec781fbc037617e7aa78fc52083e1d52fee915b1c165e551eb9f99094f0aa0b31225a14583f65f2a008b3006ef85d65022ee802443ed580843ac3082678d4ea4c191142e4fc2a8c01d87411e3db21e8d7141b5eafbe107226a9cbceb72ab835b07565e557b93a485bd086f8dd5cd7fa8606205ee8a35479c278e1dbac123c9846f72b941e49981885f02d59d6102b80847e359a61c83597c2ab793478e34283f46a9715cc0a33213c8b63843e834aff8a6403a2b327ecb32f7cd14931613e1b64922ef03c7e2f0703265c9951e1db32360431814786e721a59002025b6dbfe260e5664782fe2c5a9530638c28be858008351fc009f14f0601187781e9f70b15cc89f35bf23f27e684028c3c7dca84b3e32478e0770a7b50288106a84ff980fd20e34508ffc73437ac794a79148ded461dc48e6f991288202aa8e6d537833059a0c0f91d8dab15968845bf13b3208904b913bef541c79dd871f63c2275b48079d1e0d521991a0e90a0cda73b84fc249022c0b3407461d3e58aff0f51e2021a5bb67cda020f4e603c91f2bb4c8c0d5a6a267854081e1838320091df599eac287bb247978e3454edd0c3ef271d7cc191c205cfd342848e51bce27b4e1d04f8610ad3f302a921a222baaf3b92830b70655b8fbab9a103d386fffac013250f311478d4988c9b1ff8e0d31198506762575eb531a58d8e2d039e2d80c6af8e9d001e25830588b30706bf42d5e0228400c05f9d84f4d96147d8b76ee2acc22288f37b459e2f7f4ae8df3a708cc1823141ef436226c0981df6eada05ce4e097c36053004b51e787e4d3346870e5b9e9ee5a1040501f0f9e0d1139a7e19d0a0c3af3fe493026870afb61900a40014da7e13ad549044907c35ac0421960870f25baa84390e4e4c3daaa5f4a24f0d4afe2f502a9102fdc03fd6aa420d2c5aaf532284095e66e4f835aa00295f7440bdee875e4f4b0705af8341cd49074940bcaf800f7eb82263fedf1191943c25f0e91d1d4098116cf26b067d84e49afa3f2308233208d3c0ef4ae8378c9120e3d3b502907a889b7ad547cb009323976f55c00144066b57bfa1c8bc2d684af81608b8af2442a45f0fb0628506c9c16f1e2686b740f02853061a00da947e3d20ed40ca05d5af4222b8b16707ff5f6a615889a1f59f1647841e3ac0f0bb83266f6bd828df9a20f381037fc25edd6da0a5b8c1dab753e0bc111922d0b33c7aef0c3881fedb17addd007934072fe10f13b0fe8b88e059a4060e8fc64579a97f527c2bc580304f1d0c7cbb83912e18f8ccfe5100f38780a3059e457a0140105c9a476b3017f08019e859fa0a0835dad83ea573432e7d8e7d2a26b606c30524cf2aa0c5c51a1e82fccaabe6c84041a06fb13e30c265b5f9d58607ccb6dcd2ef314a3246c4187cba4384a22047bcfc0b09050a9403150d489f5e304119343c425ec80b03b4600d7bfeffb918aff14b784c7cb8e32599dfe56b24fbdf3ee4b657c7f3799a7dcb6c5f7d75c6fe166e1fd7a1ddbed05e49eca0ad8b52ad3ed5a2aa68519d6e55d3bdbf042a7cf4370f95c6fe56c6fa42ecfebdf7ba4ea13df4f7de29eab577bbd1bd531609bad1dda224c6f66677fbe8fe0953946595787cab28aabe6d756f94b77f40f7eed7ada269df5b89ee8dea7aa048e8465915dd39a07bb3e8e6b14bec9da2ba0ed6b40dda24f6de1bc54247e8d2bdc046378bee8da6c58daabcdd14eadb5ababdb64867ec164555a89487a27b49a86a2751a17a5da918faeaa360b69a2aa92bbad35f0dd8326ce0efdfea46b70e5b87c2d81b5d5134dd5b6a3b6dddf6a1288ab236f60b1455d1fd940a7b26742ef68fe804ba65afa889adee743f2a8672de561f85d9e7665b80f4831decaff1019a6e76abedfeed940b8aea86e9be4a378aaa1cf5ed94f6ba77fba442ad78da288fd5a1eddec38da22da4ecdea16abab65dd4b977dab4773d74ebda8dd64055a02ad014e9a7bf85368ba2fba70253153581a2e866b78adcbb16bbb7a27bdd415648e857dbdba1fb4ce76bd1cd63ebf64ed1ad6eaf9d02c54251a03db445d79d6e74a37bb853a03db45577baa67b5bed742bedddf6edbd656c15282f6db74edde8dec3bd5912a8d156d1bdaa1b0beded1455b1d314455554dd5828ba4fa0bcbddb3a15dd7b0f770a94d7a65bd5a97b6f2bbe8f60e8b2d218eb4ef76eab477bb71bf68620a9d82cd48da22cdaf60d1cf1d4f3da1bdde8debbe9db6fbe90269b4f101d9e0771204f9d20413c7a7ebc329ce911c3dc97055978320748e8642f9d1f73c0cd026341398c87034a3e62ef540d1d0ea8f0c1eb45f184e5c09113d61b44c62a865f0bab206f57c5b08ba8320bc4401507f44233225434998d4199e6c2c84cfc09460c38a61d569871df0a5e82e8e18a8abcd98ae5b90ae53f7d22ff62ffaff44014beffdda31be12519539ebbdae6b2ff5dc6e2ff7b247112614231d57c8d74a767e15bbfc7221b859734c2b3ddb53b354857d5eed214be322760ae4e89e5e9ae549fd0567d6c51654b7fe9906a074a024f36086d772ad32fc5d59927cf87efa832053941a790d61eea66b33878ced07163080aaaf2541d4b413c6b7802a38e93bd0e8756d47082aa27d2a6e60e6aad315078b2ec0ab1282384b6a4a4389c50799ad8fdf019f98c90748d68ea681e10cfac7a87c32c0bb0dda5bf354d0de08a139d1ac4a6d842524e6c7860072385283a3f5b82d0de5a63a8c55273f421699e14ad4abc2e9e0b96880aa3c57a628103389e44400009e053949f51479537cf9e13a900945f94d0f6812295d19aa872c26bb1589e2e28b5fac291a6e07501f1e4b55f3f329d171257176fe7e5233b6659f02ca13255f1d861d18fe5f5b85c23619e3c9d978a332bcf3505ae9be5c1f256192c0cadad9e73f742e7c5f25a13bf1bbb162ad8ae84110a172748c0d0c5c831e6c2094f276ca57e52565f62ad4f6d4facc3b46ae7535ff01aedaee5a94e6b0ef5aac65e91d2e04ae269a733a6585c328e743c123b2b2736c07a533a25b585da828de0092348bdb1c65855ec5aa82884a0d2144f9e42a79d22d326355d93b8460ac8408ed19ca92397064d045faa345972844e4376a39911224280f8e84126a60300afe19594928b24165cfdc083403be8b1818656927bc2440b27278e98303cb8680c538cf0f5d8376e2e303346cc172f0ec02dd043e98593508104cac802fde9732664071d3428ca43590880915a3278ed182c6f56bb15ec403066885555c2a8c7d3b528902aa080483f868101f0d5c5c5c0000150219aa3c200cd99089afcf061557564a49250c7071f5a33aa762dab66ca056b1e38a0002b491a60800102c2c0b464bcf06d22d221503f2a1fae039a47b5018d619ddb2ca02aa029ec50f09d809280d241dda06a5234689aaadc2df60a5d8a15c5cf045a021db18d868a5622746803d520b4b7f2d09d4e87b6ed8aaa3bdd9bfd9f508a9466f0540578aa3a58187cb73f38018679aeabaf75c18213d50128b584ef0b19b6ca53d5b123c1437104e5b90ba20a4955f46ad6a7ebd25db1bc54c6116f1de1a98b7b1a1171b2b34a17e8c107c3730df45c7d275278fa6a3783e7ee28086d65ac4eab16b7113d135b9ea8579e4241a160da34e4a43b1a0af4648da1bb6ab352a1344bf7e599ee807262796c9967da634fa84c3da874ab3e9589d7b5c66883b027581eabf419f98c76473b126d90b48827ec8934cd9315ce3349a932793129853af409b143ea4e9b521baa98af048bb63f5aa4166c1d11b4d95ebaaabe344dd1b44d75e98e87424ddb1e2d9190186fa865db9db6ea94eaa46e9d8914c9c96ec54ae61954c6c910ab22e96e3c516178e216f9070264c30a7648a813021c271a199637ae2d1a33ace478071d9c5e008574ed1021616081e69c50c20a029eb86ca991000c2ad00141830ad0887112ba38c0591340cf3ff0c0e70e0a27783041132646880801120686a36b858a1224dcb46982e60c9325c51428e47845100c2fa8319f8100050104912125480ca900c2071b685001056a08182080a291203fc2c0bee8ccf9400e065cbc5a60810e081e689041982f56a440e1818f0a286890819b35519efdf8c535f4e343031e1842f0a0cd056c20c022403f168d1019f2e38b4bc67069e847674e080b2880254a3f1a01e0ab8b4bc630e8a73e0d78e8cc11e1833617b05103419601a21401e06b868ca1d514d412d190fa8168c0f38208217ce0419b0bd4409005cb00024491a15884080d27e11f2274e4100a7201c5db152b407e3c3d208095b623667681524068112b11e8103a326a042804a8981d8542a54f5bd86b4a63a49cc40a14c5466a4fa426f6915a6293d8151111a54055c81704fc9df099e8a1e00ded5a1ddba22cbbae69d5ff9f781e9084d7f7e5d95bc7f0dc74ea47d908c7ce14ffbb2581e2d9078ed00138a206e008b925aec4793fc2740cc35c46dbfcce6fd2c8df110300c1c400473cffcd385a0cf7241b5f529a91c56318ad9f8d10fbffde034770fd9b71a4cc6998d76d67458442e190236b7cfa5f7dfcba05349a7b7a16c673afebb7e934d7f4ab29fa3bc6038b1628728be19aee479e34d62fb3cb47bea4d48db353a68b94c0a2b23fc6bd7e390d7c60d1d431eeee038b50223e4899f35946d6f35bd3bca3c5efbc1352f1bfd37da7972fb23be7faff53ddff1eb61708e9f9df649b070d58505c8bcfb3d308030beb0acb0aab0a8b0a6b0a4b0a2b0a0b0aeb090bebeaeacaeaaaea8aea6aea4aea2aea0aeaeae90acbeacacacaaaca8aca6aca4aca2aca0acaeac90aabeaaacaaaaaaa8aaa6aaa4aaa2aaa0aaaeaa90a8bea8aca8aaa8a8a8a6a8a4a8a2a8a0a8aea890a6bea6aca6aaa6a8a6a6a6a4a6a2a6a0a6aea690a4bea4aca4aaa4a8a4a6a4a4a4a2a4a0a4aea490a2bea2aca2aaa2a8a2a6a2a4a2a2a2a0a2aea290a0bea0aca0aaa0a8a0a6a0a4a0a2a0a0a0aea090aebe9eac9eaa9ea89ea69ea49ea29ea09eae9e9e9eca90387d098ceb848129e124f69095fc29370cec463e225e19c73febfc5fe77d8ff061b9281fb0108bc41052030033e3433e3431e9399191fd6c8bee49c67b65427d1e099f31ad9974a667c48bf336600815c80c023ff9c866be719e734cce3be1cd2c7d8299f3965febf77fca70f04f628e34c2f5ef0fae5c79e6684e3b7096c02d646ffc3dab96396e7998b4d9e6779ebffd10702dbff170a6b26f26921274fcfc23378f9249c1242353921a19e9ea8a0deb3b3a8a8a31514b2aa49868574afdfd9286c9b6b1a46eb733dcb67efffd6f1bf73fc6f00feffeb5f1dfaa87f350573f3bfbfba73f9ae71b379e632e3f1cb63999b2d2935df992d760e87f5d249f731337eeccbe56bfcdf5eff1bc7ffeefadf5cfffbc6ffb6f1ff26fedfc6d6ffff78605094a76721bd846b2752d0113d0bdb967273c5ff17f939f0ff6848d2a26270e080f105a41e6c280144ec4b96087bdabe88808530c3cb708a99324a197872803b8ae0052f86d17bc78cdc9f2c301cd3147928450cc0e4c9020dad091038f9ec90f4409b1d26b821fe7d156da841ca32029e5148102543ac3052d545880e9ae7c7ec4b0700435960ec68b33d3e7040c19ea01e4648c18174828238528812a0c950c3e448862947d808e03c58c08d1cb30ec04020e764800510ecea044b161b626e5490d12a301e19abd2b8684160811359676e70604c011368c1a0e129c10f44b8a0c2e680133ff440c003a8161e700410463a18e289a70022ed892d0ff8d0c3649b0384ac39f683abe8c5e5071908402ec8a1cff7def81e5ddbfd3f1aa8889e1bad3f62ba07944128aed030f341e4789401b224568387161782148b7eb44973aeb8c6136d47450c7041990250f0d9e0aa116d3622033d229c7be6c471822df4a9c1e78c528e0f756cc03122cc00108c6438b0c191127fd010580bf4031109a8bc1541e623f1ff4da73ca37128341ec3bc96634ec3bc8e61b9c97bb28e9d45a866b1a69767ff9ff4ff44fe5f966b3ecb48b85e3ac7feffc7ffc3f8ffe303d9b81c646a5f41de601a664a8c4823fc5134019f669b97a18a8919461b46f862038540838909c635d499a828c21a3382052b5804ec191ead202301ef0e6c8308842e04177cf8a0e0c0764303241d04f8e253d1431b2e2e514c48f2e4cc88cc0738bac4a81618208834e6429711a7dd960f0464589b40ed4dc8920ee4861980289384a802056e5078613c001658480a783f4258d1930707370caa842216840d6d352a845192a18e98290da426f6f0786c5ed470f1fd86dea40644ecd920050a67280a3a65c91db213437025a8c0e3c96ea086a822a2a860a9657754dc791df0227701519b196174809913b54314b021302a96500091821b8b1aa8c43d395874587bf134d3513e972a50c14d163a3b7260c380ad0bed031d8b80edb18647100deb650215591f40055a0344c8dc820f121e2c99d3c3c0195e064a2342dc4410d583090400898823a1cd1c017a944cb95240870f6c081328cd0052461c702670d23c421306c24f57a78153807549002caa2d00b92107ab8da8490b6e98c6e0418e11b434a9c02089db11b8bc0080133cd7e4c2c86e0540739804610520408eb12020486600e01e309c1979d631b3c39b990148e4b961020431136057cef44820c0024d4f3ec03cb585edeea48624860e72a469b3c58b064f736a14216f9d583200103511eed69954539511fae0180a776063924a414e931829d451435aa2835bac3e5420040cf6b05a80e8c817819b0f091ce1e1cc0447d0c2f4332b44b88345852102a4c83920ce4c14162a26340099e0e735b51291f832c08283c20f2924f0c1050244d4c11103515b9bd8c759d7d404ef00f2ce9434287e389a8439d3e50201c1881654e90ea71e6008592106af223c5e58a9616106939c171ed8220c608f511a103736bed832b20baf0108570240f3a18337041784dae78f56153a737e5a1479244c25b122408303646059180263829165a62b90887cc199daf120c2cbd3f180ec81437228832e674d0040b15224889c361aa28a4cd0c10b1ab03940c08e39262136a50f38d86872808b3f3a23594a2920c17060a76cc70339d6c34598322c407a5afc9ec90652d842a2cad0ec017111e30209e76c80852950838b0c37f0204cab72122ce3eb6386a7eb6310c8f342a02f2a0c9c9c34817324b90c191501a1b255c10756763471c1ac0e973a2294a1f2835a168f270e3640eea40cb8d018b9f4ac467618392083dad14e1118341dd024870c42f0e8e1a4469d283e10e8402636f7361cd1e676011b372704b93f94796910bb11a1e38a882a553e330468180630ae660e961a2e9008e1020a9e9fa9391d3095c84002a21e7af21a190eaf1db62d3773a67e2081488740da70854d92d35441890c1258097240a5a8829f958a90da52d34022008f3873d652b58e9ef4d1b594de23866c6981255e525876743b07ecac64187c4103011a022850a04081764702d39c4d9ef91178ae5f266fabe1d8c99132af6579e631dccfb85c731ae67df91ac9e85948779aeecdb6fa9f4bcbc5ff9720f24016053d0b69a42ccfcd221a92341a3b28a967fa7fa2ff6ff1ff401eb81ee959088556ac91c8ff2ffa47abe4b0fadf2870fd6f0c0cb84265e87f4f79e264c98bffade448b1e865a38cb88543480e1b637bac08e5a318a4eb6b8ccbc756988e2db2aecdb4f936f17bf75fc4eeff83f8c761861378ff2f67e9ff35f8d740eaffdbbcc5a0ffef41e2ffc9f61652e6bc36f679968d31cce53a86f9b1a7c5cea48dff34a6ff57e678e203f0ff421e8826ff81ffbf997cff9b38357535556cc2bda697674e5746e315d5139493149594f1eae918650545d5a1acae904d6848d29ae8da293bd5309a938c36bf46a1d3f16532dfa493e9d49972d229591f61367ee465f2be3c7b97f0bbf6f29eac79fc266b3e77b4585e721a3e7678d96c3ac98ebd36f6e691ce93355adc975c66ab9b9072d3dcd9e4264fd6301baf6978c989bfcaf97fb0076e25ffbb068dff97e78e84b79df17e84d7e023976b5e3799bdae5f7a16cebd869dba115ed27d968d4e5255584f5846641555879ab2425e555d41752ca8a82bac27a92728ab2a643722b1a0b0a8bad1c958d3ced9696d60fbfe7f3f3066fe7f8907eeacff377ae056fab82ff98c2cdecff871e99493345fe234acc48ff4630ccf9d8e617a161e65a693b1aff17ff4ecff8f1ef878e8595833915aff7bf8b33ccf9dc72f3ff67876d67daee3ceeccb2613e635fcce35478be1ba7e99b38ce4ef6f04feffc403ffc6ffff1ef8f4ff8f78e01b39f625fc2239ddebb633ce91328f65b87e79db2c333b939e85bffea3beff47f1c03fa267a1b1af15d9ded9c938d34e4e6df33b9fc1cbff3de37f67fd6f19affeefe1dea00c5cefe59e4fe2a77b83327a7abddd02bad44a891226284f3993cd55ce722551dcf8d65ab6e32b67a2e33cfeae92297c6b7595306139cf75e35b29dfb94c74eeca5b9709ebae2e14a1e74cd81df752de4b8369eb8f0bc7eaba3fae26e9ced17bb4d743f9bad44579e284a8b603a1a8aba684a8ba69aa9aee0954555557bef70ec9da49fcdfaf11b33a76cac68e04a63b1298ec1813e9dad8956765ffbbb83cc6ceadbe7c6bb2a54cd6975cc777ab8a2acaab96c18eefd63176ca5db50c56cbf258afdf9a0c29cbb31872f6717cb7faecacdf180d263bbe5b738fd1e0b8475bdd6472f535b8761ae3af3e3b6b6757fc35bf5db25c76ecb173166bc2ddd8c762195e2e89461aded17b57b3d34d4cf988058883cf3faf5fc474978f349cac79d20827d93853d9b1d34e371c16e0807b2ed79c467b97487eec68f19b343665de9d315cc7b2119e6bee9483bc924f168d74f189123e09a1d6b8b6c2c6cac8ccf6ef319b9e85fd4c9e6b1a4af8248c6a8ae1e5dc993eb691ff5de47f13796057dc90393926564059818c026bf20a8fa0b12660c27e1866c53ecc6dd0ce4851ee6a407beaf6f3e9e4c97bfe3f9f8f3e3f7d7e00cfb762e59ff7bbff77fbaff2fcddf3e9e4f9b4f2fc7f3eabfcf3c9ff3f5a0ccf35d970d8a46be3db64ca368643633fca4619197ff5e33ba3357b74265cc7ceb19a7e75c0351c7f2181976f0c7769d1efd2589c7bf3c8cb4c33cacb33adac5886eb66d8f2ade5fac8cba4dfb3b98bd13ffef710ba48bf495a2b4aca9945d3efd2c6dcc586c3232f7387016fd474bd74bec87ee47d7906d371af6126bc64f69a6edb427a9fbb8c34cc1c0ee9b8a7c9f57048d3cefaadc9ba317e97efd6ff0ef247cbd7591b5f19197f258df5dba4e11b352d8bfd6f209b6e7b9b6db35cbfc7f8ddb17ce7de0c5bbecc5906eb4164b0e1906e7bc5e859e8b47c871ded9de59a066e75fd0b85c217755f32d56f9fd1782d837121cd97efbb741a97af91a3c5f03176f23ebfbcff182efb5a5f166319ae8d2f1dbf733da46761927e934e4e564829a97e15e5342575d5a55ea39495d4d95394f1ccaaa9d7ef5cd3674e9a7e93c3613dcbcda6932e76e63b238958be9ee524cd65b94ed26f920f3b3df7b53ef323bc7cd7e22fba0791c1fef78f1e8cffd7f1402297f1ff461e5803ee7b4df7b838f71a2e32e5195934f626ed64ec6bc01a51fe9f4d5e22e7be26f3b61a36becdd7b8e6ff970f8ca1cbff1fbb1a97718cbb3386995c8b1fe39e7ce7facc4947d0e4ff930fa451879e856cf23186d9a48450c2a8a6b4be7c8f4d58505454517d6d761abf5dbd107893a3f8db063248dcf4ccfda3988b9448eaf0eb952f5f37d82079f60b45d0846308af82f531c60082f4fb062d3f503c3ff815290b171a5c9ebfe681614867a0e75907aee0a678643def02b321ba64b5f0bae1036010b0f3f5edd0d896e01e2aaf9a90b4f16445fb6c4c430b8b1cbb6fb7827eec1081ccab08b49d28b381d1af576537b26ea0f3eb035c77883091f4eb120b2f04a0628867b96c50837002f12a06591a0c41c410bff641e00802314fff49787088e0d5c2b7442978e2659bffd54310dd942cf0bd0152179d88def398cc142020019b7f1f32d8712688f23e2180d6780923c2af290cb14092973e9f92c1511a6235e2f7150f0e92ace23e0d020407086880caa324b4981110c4ceef5ecdc2696ff0ec067be84c103afcfa43ca0f2ac43c3d8bc1b308adecf2e90cebd490a6161ed523d44c5b3ff8a02c2e15863a18bf63606d2b4813f1e90c2b164cb4e0b333ee0c0963c3ccab3f6058450062fe7b8c28a37604c4a325109118204ed0a7bd226a02932cbf6b5450840a45de7cfb8341002e14047ddbc013130abc619f1d3286488f52d5b73f92b858b5a07f5d93e5654893fc6d00be5edcc4c4af41bc2f227a8cf0280b175894dcd9f2bed9f7e43265caf76cfc5c6dc0966f0d983d98fac3e7d7162e78e04601e7a34532f208d121cea71a28c5089167fc9f0144808bb72aff2c8cdcbc59a9f8344a01640c38f1e551ac374b4e382afb0fb4c0f0ca032b7e3f2983a1c8d1ef7d3ff4a02ddc90f03a168268f0a007e3d913702d283044d9b700dc70416f12e35538427ec0719abeb5c203368081149f46e0b50433e3ceb32edef8e08024e9d5dd4ad5b4a6836791380141b164cea362ccc875b0e3826f29109a25bd49f1ab1b9f2c1256a8f8f5f83ba10603fa6d07515b8c0948f0bc657a460520dafc4e89b66a608793d795115182091966bec7c6628a14130efc3a66d8ab1397e2d529603c388942ff2bfd00a42506328f024161c3058d19fe2da017207220cfafc4d886f90719ff2ada90b97d90e7d7a1d30407510ef814802c1140e0c1f5dfe5a789c7313fe57184c36ac2c8ef964507de8c78f894f740133781e7ab6bf8d4f0430f04fceee9832d5d50659e357bb2c10005258fcad02df92051f82d40202fafd282df3ca4640c91f2fbed260706b28f934f5b250f8a68c9f9f40de6816301cbaf492a64a8c8c0ff58486a1b0e04dfd23991430a333cf0ed083330c826a4795f11812a20b460f23b1f114c0084078bd7c5582aec3026cefb3058b1027aa0c8ff5815984cf088f3a99c2842b224617ad40690326c7aca4ff30c11c94004cfa3423f0ee44980eb539f933e028129cf7a4064058c352dfc7ae7834009a8407c8b02e96375bcf32d7be594a502b667e37050c1156190efbd45143d455d799d190b4323d420bdae85a30cdecca0fdee670394141486d705b0c5090876ee7cbac686d00d032e7c5ad401922f119c7ee540051915129c7c8ad4c24705716cbfa220d2438cdaf36a5201944c0918be657bd1854406657e533043074122527c3b449a3e7e7a9c3dfa34220acac7795d9f18b004d054c20759c0839a0a945cbccecb82b82e3ce8f9f647c407556168af5b214883141d5bbf3ec03644a40711df0a1132a3429223afc6012ad36265ebd3233604dab206d0af60840b88d06ce0f70f1d920857283dfad6410a3b266dbf7a31c3d2d3a7c8b37159d2707151c1a3772468529a89dfc3c33bb2d024f6bc16666a428853f53ed48c0519166c3ea8c984142cc835f9558c08deaf95ffd964d161e0a4cd6f386e1713cc24f996484d200d6ed8f06b5200a51be4cc7cea84a8e9c2f9e6d3152c48a0c80c049f1625db90c0e0815f59e872c21a01a27c1ab69401859a105e35a1c0543a67ecdb2a4fded0b891f53b1728cc50860ee177ab1e348714f5efee28e9e20351ea776933d2a5d294df4d90a65e16a03ea5f2a358428e10bedd0a4464a2ccdaa7bb8bd00569903c3b82020f64b044ccb74bd894a8b908f8f428880ed7a23cda674dd7c00ca06fd7c06120032fefab0608998049f0e9d533411b9cf0d5c0af00c488e084a7e1b7575f961484b1f2dbc79a1c8e42e87a1d0e1490ba79e977962b5448f081fc3d66e4041b90c4bcbadb8224098eb54f41f869793147f87f960862895611cf0a7d28628ed3e8f78c048f0a64708f86d9a3401d2e4bbef50510c20a264d5e95433a6d1807f87629ccb5f2d2f4ad8c0edc18e8007a5d9d303c3e240c3c4ac05309312588be17839db4610c5d5e8da3a20c8424019e1dc24d73b31179746d021acef4c9a323b617191eccf0e8538a1e5a20e2fcb70109092bb8f8faf4841ed8660a767cca82178c6488d4a75292bc18e091e65118d474312a05f03a3f1c4c6005e5ea7726506996ddd9af02b0e4ab2325c1ab596a969184a56f4bd4b0d6a540fbe80773d6540701fe1d0862011047d87cfa24f8e48253d3b317a4f1600d9e30af5649d2a407d100cf9e7080c46f4b05ff1200529aa0cb9967b99e6d86dac5a74b4b643080898b67b7d47b9236f04fbd84200953840dcf46a12a615f21beef8d861792b3915797687dcc6c10e0774c5d4a5eac3af8368690214c19a2bc8a1cd3448725fc8e4ba382dc1c0ffe510062c16972f23b08ad778571e9d9402f200084468267adc8f9400112949f8e704701263bccfc27396061043262fe0fd873454516fa796edc1cf0274b04afab1fb0600f0851bf9b6201d08ac092f7a938a27131668747bdc430050836619efd4139c39c03f8fcab01a18039c31c7e3379e3d1e4a1cf6f1e4c80a5f1c6be45da401da211e75321adc21b23151e1da3010d21f0c1f26a1b0274e81021c5ff50ce132048189ed5d142d2070e28dfc691b00ac353e7d73856604850d1b3725e411465727821346a5960f8b6bea742f7c18e1adc6fe798195a8340cbb35d47526812edd9354296085480e6d5323bc4d1c08bec550f5878320b82c1b77273dad41101ec5b2822ee545940866fd3158725f309bfd5b4f45bc4ead3295c15d0c0d1e38372982048021d98f0698e1940102182c5fb4a00408210a3b06f719830b342958befa18d49cab9827e5a809b246c7050fceef3630a10317b3e5d923134421b37cfaee1a1831d5c05cf0acd0db08007391e7d73e249031bb2578f38686352c2ff83d192d36706167e07d1010e5a7862f836053ced8aa3d8efb6a0c531da425f971e80258b0c071f54a6474b863acb478f3a98b34067e4832c7842c132cc866775bcc0a52a2cc5a760d25c4094c4cea70eb898208f5b95df38106087f862e9ff4c5419b438b66775786a80c5efc4bf163b3d8667c27ecb1087032928ea3f003fa789d379350ec6f0b583f0d31a4c0835adf0df702c0aa87530f3bb170c285a5103805f971bf0515bf3e47d451a74300051c0a711f07c552be67e2d00869b2f0cc4bf77504c68e2087ed5f1e3084a0e491e4d2143060782c4f875053a2a9c54e1e1d30e5a2e5ab5d06f12d6882f0ea8e01f01230aca3450f35fc314ada600439eb7c3104d0880e57b500f3ce9b9f47925aabc85eda0c0a3040890a3a900f1b7191d291ae4eaf719223e720cd97ef5b1a6c7624af94f253542660621be7d8b665a72d1b7c3035400613de05b14d294bdc0187ebb0102843a3900f06a17f36d616bf82d1d384c21bec079954b4a4959040b7c0a428f26ef873deffb2a228ccad010afa6408092a10ece479d28bcac79e2fb36a80c10a0a5dcbf5b1a1196f4897a550c55eb9443cfa36a2618d0c5863aff34e07270810cd0af5b8a9b0c3088f91487ae3b33072efc56b11585458c976fe56041a1060b053caa228b18302617ff3ca5aa1a7224f0aa7c83141e2c507b5d0b13b8f15d89f36c5a33a18005f42d9103e6f0e066f8ab1a225c28c2cc9457ad4894912073f66a040c7cd16183c3a76572b89e6174fc0ff1329910c0eb570cc0d070b5d6e4591a7b821e101c3fe555e5d0666c7f65a10518e31067be2d2296840388b15fe178c0dba2a4c0ef989a708a5c2c5e778353102fde78f99d30871d7a002187e72989208639411e9e47c1129f15dc76bf2a5d01a2479034dfc6b9818404ad20df069f4e9811e5805f976c986491151f258b93d439e18567ab5a40820900ecd91b74f0050121806fc976a0a182d1895755f07ce84187a9dfbb2e65607628e1d7312d27aaab001edd1ac2c71b04573e0d000f1a366e627e0da28199250d545e77c503051d39c8af26df312c64dc1e355a1ae228acf9e994189a2837be7ea5d3d5278817da5721d09282540e203c7ae48f1539f50ddf12619ac333635f4592840f8f0ef357212be8694008e3532741e26eccb0fa554e1a96ab43f38388a8c4d97306f8eb129a50d740d7a71c4cc142f1def87608336f2fac25fd4a84336b50c9f91583255bbac8417ad448d0d82c80ccb75937ae1818dae0d71878d8693006856fdbc0f0245e80e3d1ab40bf3f4b4d7ebf61a92e30a1cbb380563f37eea4bfbda04116a86088671d282244e4cbd7a72be8f0e40404955faf0811266528e2d92b5f600431a4c0f776f02118c7820e5e255bc2d0a129c1ef233516485826df62e94804ae94bfd5125e9053547c356c6cedc4138b7f11c4ac5da2a83e3debc124500fed7f001f84e2e40efef7a85041c2cbc2b34b552ddac048f8d6861e23c04105fd2e4a05088e4a98f17b84015a3d5848f03d3b6e453761c647bdda355e53d07cebc787ad1d47308feea14ae386c3f92b1c191a075c40c1b3481e6c0141987b36cc121542a6ecf8d40e1602e2960c7dcbb6e78b4f2d7b76c72e88a9c0f529924dca920fe64fbd187970fa11e675465e5c90830b8c6761708909748306cf833345586446caaf08cc517e02e0fdba8110320c930e7e8d0224892b04cfb76bec7411f266c86f240b84c90a495ec5019008748460fb95cb8e11b29c2dfcaa66e8850e478e7f3a317e80b91edf9a4989b1c8497ddb35cc8100018cbf7f76e26006bc3eed71878efa1cf2bb127e2820882823bf5bf6c1a341d6daf3b6d4947faa04f06a065961768ea4f8146693461258f1aada1503f60af6d1a1130e35e020f4ac1035fcc920888d4fb186bc4130c2ea573531aa7ab022f72b0f2c7b34a87af26889a1794e4fc9afc03324fe00daf2fb86017604d043fc6b9ac2110c12079ee7a3019f95192fbcef4e8e3d7288c1ef99b0b261888426cf6e8541b16b6afabd67850743a4fb2cb107af3931597e05b2f486c4c8f89bca0c32c82828e2bfc49e1db7e0ecd3132b20292186f12c20ad219214c55f6bb8b2010e452bbfab2081739364f0e9189692340ee46fcf308d812b41c2f38abc1de0d2007a954c30479519923c0a058b073614207f870376a1798282df2db01dc162c2e8593513a4d818a1e2d53e7254af3656cf021066029813465e4501d8e40804278f4a7dd0030303047fb561f516f98cf9fdf4f130c309cadf4c43a0cdf0430cdffea002031d911e9e4724c787420020af9aa05644e28c8d6f97942b505005874f8dc41d5ff8245ff783db9f114b063e1d8e69eb82a47a9646a323b080f9e98a629f1342d65e356241e46cc593579b14a08b3321f4df420e294806a4af9e69fd3001937d76820e9e18f900f1ea019b0e1d36c1ff0bbeb31f4ad8e0774cbbac3d71fbdbe51e233243707c8fcc58529f3ac8b7fd65a04c8c36ff136b0a5134c68267d1687084618008bfaf04e026c79a0b5ebd211003cb2105bcca0769c192107a7e1bab00a5908006cfc650b6c111405c3e35d334a38118d7b76cb638f3fce1f22c4a83c6042dacf83d076a45084ce4470300c427ca91d9efd016883420e6e97f402a7ba8c4203f0b0391881e033a3cdb264d001c04a5f927d28349ef80027e4582c04a0151eafcc7e9700700f7e8571524d45dc5cfbf1d0652487fc0f31b68431e5947098f0ea025cb96163e5e15f3a306195770fc5ac40411acf0e4e757107218f21a469e17478820a23040e05b1a518240c00d8e6f753460c24b96e6a3c70ef088cd379eb5d1ebe3c1540f9fa2e133428a37a5471948406dda023fbbf680d48cb6ffe76a6852eba87956c654075050f6a711c8216244c0fbed5a8f40613bc9a34636384082394ccf3a9911c1872b507ed560470447013caf9a69a568093bf1415b12d8a354a7ceebb8f6b8d90cdcf0bbb9314b545409f0ba39461f6c94e0e7d70c20a841eb89fbcdc0b205226bbedfb51b1f1db2387995841b3d4ce1a0ff7e52b3bd44f3d917436f8cde94fd2a56268230275c5eada2e088c61699df551a40c22203f3d91fbf374c24347c1ad451ef4ee8cf1380073b35e4cccf7a11c1a6f541f6bb19ac2480e78be8d1186a607be332c0af7f7cf830fa32c3af52448460650ac9a32378b0020c26ee5763d12d06d4cfaf31141f218255fe7118916606fae35713a2ac60c2a41e6d0fc852a54ed1b3547e601aab24f91fa3911eb15c795f89e1900a8a90fcba438a249a8619fe57c78732422c10f03b1e053fd8a863e6533b65ea35859b6f81594288b343d6ab1dfc8e7644c9afbe69bb20c81e093e25235582163114fcda9bc184027e38f0ed98d00c363de1a7286af02852b6f5687fd346a456fadfa017c0074d9d6fdfb7b1125dbcfc3a8734ac9766f89d0f6d9240d1107ade5138868f89e07789135eced240cfbec18ea68329cfca31a1c1d79db24765f8c0c3c5141a3eb540c903a7bae4d73bac017ff040f0e810de981e0c9cfc8a0269c427c0d9a3808648b179e2f3eb0c3e3a9ea8f5df447cccc039a1c3b34bb28c770031f9d6001d4a9009219fc72468031823bafc5a068f1c8d0cbe7ecb3af05ce0fc7add929ef34f1bd4ffd71909987270e055080670abf20081479b144896a101805f57301281c20171ff007481818710453eb55285052a6f6c9e6df64160041432af8209c310c909e2591924643153c0995701a9a1b2e0071bcf8be3018f9cb5e783a0ca4200a305c2eb766851450203825e0d03c2163a0709df76208320a302ae477f4e1c6711e8f9b4cd19231c0221bf95fc40f45c21826799fe90701383c5b72b725c392255e555958665aac0954789ac30c00e6b09fc0a000b66735249dfde09d4c5c5737c758837eff8d0e35b3913b8e898717b554f9f0ec40c19e07751724827a840e2794c4868a030d579960b8a9a6711c7b7422e08a07ab7df41132d1160c43e3de048002a109dff6650b67800633f6d0ac22a4e4adab70324b188c853e4573f434e1073a33f95800112492b083f6d00003d04b83bfc8ae603126a54c8f99e0a80ba8cb5a97f47c78a0111885cbf2b02e54d0e6b545e47009a335fc41f7eed415d426641fe1a76800444349dff7cc8963c6652f88f334000376d92afb2a11182090b121e8d82f2801fa0d5b35b8e1e70b14c7ebbb909d5cc51f26b726a96d3a3e75721926c79a1a2f8c703800ca811b36fc5c848bd7cc8bc6e87201a726ac4f02b0603a0d08376f85f0663ee645102e3532a765a1c408779b477c3061cd4e88fd6c802ea6063e95f86971fa63f61fed723d306426bbf83a07f584204ff4f0e9ce9c10325cf56f5245d26e4f0aaba248503b630df2631cba1ca12cfa371946c482387c2eb78673cd0a23ae1d9038801088025ed772a6e60b12454f63ad8cc19250ffcfbb608a027cb990c7e7d9f8a551228e155b2157074c08ae1df855c95ac2e1dff660934c13879fc4a1486194489f2dba40c63865ce2d3193c303d3a0b3cab838b19b2bc6b9ebd9227882b72955f07883147f80306df734a01d705c10acf2ec09a8500d3f0ad8a3940bd28c5ef51b0c33976c39cd755edb2661842f4e894b526a527a74f6f183b618d9a02fe33a09dbce025f80fa388ef010b0e8fee69518581973cff63b280f035db3f0680ae48c820cfa353d89090a1ccc67f9e1115b008b4c0a73b846d562411bf856001aca937103e75e1c79f212b73fe174684832f18ecf02d1496406e0f147e1d21c40a46628a3ee5e00017fc3c80e6552aa2a9f6a9e7bfe7c40314d2b74f4560db584160ec533614723f96d0f07b98c50b7201e6a346438ed4cc69f17b87db4e85192caf22f141401292f4d306da3c0102c0d4ebe2206e9072a2ceb713741d800309779e6513868519a4587c3ba6415b036ff375682faed8b474f8f6a1fca0e00f9c6fb70c489a3822e5ff4d8d293da451f06b18237372ec8c3cfbc6050765c4c85e955376569452fc95dea18c30eecbabbc2e25c4bae6d505c8c45996f0f41f23081475b8c87dab254e16b61154fc8e042c79aa60e0c1ab5e5b4be4e4207b1e2f2386e9e2f628da0812e820b0e6db241002bd31d3e3d9678f1104d8c1e1d75e0a5b5c58398f9e7972c3093225be6de6c00167c1dab755986c58e68abfce055aa14686fdb723c48a1751f4295bd0929012bbdf53b2badc1993fca03513c039db70791f16dd0f3732103ddbc59dc0a9819b6f9774602302149d4f7b3060876328e9b7d89b065e5096f06d084a5637ca98fc27892816a980c06f3c53764f3a88f39f3432529403cabf090a029dee7393d36d2fdbf2e5344cc37d4d3e23ce51f2ffcd39617362fc7096e7b9d7b20f397aa292bc7e7ba79d40394fe1d24cc34c3961726879c96ba78c16c34c9c4d5ef6335e3bcf6839c9d667609c31ff67fdd88f719a716a599e69629c1623b4001cc1add9561f63a6136d7eb950ae397084abb9d7ef92c34a9c1ee1482882dcb1cf46ce6466e6a4695884e78b89c05f7826c20beb10e6fe43787be112dd3b320431e1d2b10ee1490827cf2fc9f5b1afc94c250e27cdbfb0cf7002703265b263677b93655dcbb8c7b1f7630c1be93e763cf659ae8f716fd24eb2ad63af6378c7b127e97749f6e3d8eb179eebb7d9c78e3d8ebda6651d35edbc71ec6cf231e60261f9b2bdf3710601c877e71104fe2f34fbc00f9bbcdcfa00cebfd0ec032e709ad307c9a63e37dbe61736c2c81ef7ad0faedecc8c033df043133d78e38c7b120d4e7259aeb58e5f7d4616d97a3c1c9679e081d27bf0c222666feabc817b6111b33747de78bd21f1452f5f670c1f797708dbe297d72f3f2ee5e49177477ce4dd21846bbacf32f21877deb60cf658e635fdf625af5f5ec3b3535e7b91fce5c865a7e51b7cd86378c999725dcb5b5c48c37c76caf0da9bec75476b7b993452e6bc2f9b4eb9ed8b0bc9e41b7c96952f93bfbce9e4716fcac3341a9e79cc26f3d929b7f1fae532cde5e3dcd73a9becc58566c75eec336cc63b92c7af91a99fc1fcd87bcc61b42d976f9f6170a7dcc6915f3c1836c625848311bdcaf8185719916b0c07e7dae265643d767061dc9bf29bce7d902b51c28f9dcfd0e24a94f025251a16f63e23992f1817be7d46f263cc44d3fd8c2c9639bde46d31910b69183633a39d66f33bd7b16cec4798468be5e5cbcdcc38dd69261a8994fbf19d6be696d0cccc2907e16666667c09e75a5a596ffddee04c9c492b2b8b0927c99aef8e8ef6cee09cf3249cf3be849b4cd928c76666665c9cc52cd7cb26f33dd2f9bb06d7c6b71fdf9aae9d3247ca423876ba31fe7f8e07ba39fa7fe18b177c78848b4c34b2cffcfd7ff9816d1c1076e44bf37e563bcf383dcb31af7b1b67aa63b84d8aff17b6bd4cce895cc8db8cccb9d34e4ee443b4188ee7f7079d669475704e8fb5d5f01176aac137962f5cc71d2d86df7e833e2e652fba23e97deeda428efc79ebf7c6d8174dcf694659c7114e33ca3ae28e449e9134dabbecea7d461e83500168c191ff7ff9a663c10d21110b7442217170c8d0b238b71b3ae28cbeaf5560a78235655af47058967544de2ad26f159473b97c8d15d4f8afe0880f0570feff2980a3c0c90b8b98158b42fad8e9e5f2edb284c7bf674ebaadb93ccacce204757e829eac9d34fd35c1945ecb3e8473afe5b5b1b91b9d47796e72ced90071742e8d31cce9978d78649366f8403649a46c834dd8bf70382ce34cb21650823809aebcb0889904b090e61220fdf3a19895ed660d97356eff7c788c9d32f27f83b0e6eadd5a73f4ff6afaf01d258c9a2bffcf6335696ac468265ecb4b5acdd3ffa346d2e090068334698efdc8cb8c613ebf48167c9691e8181a2f3457c034c43435a6fe9f05130b8e94791aa2342c1a3bb58cc699f89089054f9b6524e76d4b4ec3a8111a1fffbcb371fae59cf31d341add991aced43973e5f9d0ecd8919809cd38131f32f121d3eec3d6c199f69fd76f3fcb91ac9bfdc6b0c7ffbf78a0192af42c2c03e75fc8d16298eb58cbf218db3bb67cff1f05193d64e2907143cfc2d8391c92b9f2ff6666bc7e393f762516c108fa64d9060cf0ff670f8c40ec7f4a0825846a5abe5dcb196f5b9ebdb59379ecbd8b795cca1d093cc7d6c1208883213842d09c9b70928640ec787c395b078360aaac0927e97ee3d87bd7b1f7ae63afc9eafcff9834ff666663b8fcf1d87bd798277f792d8301c788cdbded8c8f897adaccacc8d6e3b0630ce7180ecb8eb0161c7fd5700c8b917336c570f9232f2c622606082d2f8d62a496b27cd6d7e0daf81ee1e2dc6336f9f82576ecbdebf875ecbd8b9697368ebd77cd3d660b3bf6de55cb60f4b1f7ae2ff489ff77fa7f62182f7a16ce72f1d83b9229cf48b906e3070c9835f4b133e17769e3d88f4722104c5bfc32b92cd7608efe9f868fbd27cbbef8f9ffc77ae09734df39fdb2ad7d7972a4fcc5ec6998d335ddd7c0be50fdbf7096e7596b38d432c2f55b9371fae5c36159564df7a397372f4d2f5ec2225e56fcdc91dd470cef109a9971a65696b1fbe05a33f8b1f932f99016722e26cf5d489a51d62197c55f6cb20ee2b11f7b371ee1a28fbc3b5e4b87ffbfeb8173dcff3b65e6cbe9b817e7de2c1e6578ee4d321ff23c7719197fc9c8182e26e93759c7ccecff5b3c100eeeff9f867b36df3e73fa658b897040fe9f7ed98870574f841bfa7fde14cb3c0e3bf6b1635f2ee11c60fd28db70923500d78017daec9c3bb2cf5c9e3b1206f26c3d90012b4006c4fe5f6836cbdc6c966dcc3d59c35c400680ff71477299f7641970013d0b8c11b2f5387e99efffd378e002662f6c8ae598d36fb2f7236c849d640b0cb5ba73f9fa60f61aee47d9a8d5d673b4f5b428a93327ddd67374a9d365ccff3fbb00796111b32e572f2c62d605a8c09cb088598a072a50c1bfd81515199910e675dacbe472cde77e9c651ec34ef9ece56c729c26d36f1fe342636fd2bccfefd2d88fbcade6ee15154dbbc677d9ec33bfa22223e3c7de8f42fa450cd71d0717f634792d8679fc1ae5b77e8f489927e9d7abc96bba1f97b2126ff69ec6e43bb890a6df33ee820b39ef49b33e276b4ec7f01b7324cc979438179a454939cd380d73333399e647e75cc685bca6df25efc9ba33dfd8accf724dc685352d2f793f6372da99acb91c73f9488feb583622e1b8276b6e56b37124cc3bed7c8dfd8c9b2d310d87654a66bc37db6a27dde75ef7ba2391329386e33769ec4c8e16c369c677ae69b477ee6b7d092f8d4d75120d5e725a8e3be746b8a6e11866cebdeec7e59298d58ff4630ccbb5b1aff177a98cb79df163afe34ef7b9d96725ce5f1ef7ce56f733ce85350d2fb999565916cd5c2ee19ae63d963bfd1a790c23e5a6da2973198dd7727c44dee2c28e04a69b629877b4f95df297f7b537f972a4cc7dc862f5bb44c630ef34cc36f7642d735e7f71610cbf49239f793fe3735feb31efb38cec734fd6c7f8e5b193d3f090ab2c0c8c0b6b9a0bb94c2f5fcec4854da15937e36d67bcee645c7894e726478be17ec6976a98cb35fda2f9329538cd85cd7707d3dc937547936b5e3b9bcb7729866b59c8b9f0c6d7fc2e9d46b89edf267ff92c23974b27b2f9f6e4b0335f30636f76faedb331fe92cbe863ef6046b98c29dbb811cb604bb86bb97c6da028d60f92cc97a69d4e4ec3bc1f65b03058dea038c1126379b108c1c2034b16962116aca6cc979294f8903bf1a524ce94c4874d993325f15889f32113cd799121fd281b87ff2c8c440d01f31b102ce85b9effe7c325a5fa1df3c037b43fbefdc8db8e6f9f972f7f3bfa771efbcc63981b613459475b539eebb817dfb98ee1213c1c0e3bfd26c53afd269b5a6546b829d7c75936f6317aae63a76c03d9c78cef0d1919d34579ee488ab11c1fa9df998b89361c9675632cc7c5e1908e65988e7b7da40fa0e2ffbf9a9ab486c3b2acb91f97b2004a5f84c810225cd88defb2c9d364b9265e21e1e1239df758e648981f3bbca4e1e35296d1561f7bd258c36c34af69a79217213277f9e8a48710e13d59d663f9064d948f4e321b6d3dc7113e3ac904f8ff37abe3bec675c5ecaf68bd9c64d32acb4286b1f5586bb97c6d68a1c1c858b6c1e9979765651d91b796cbd768450e4e58c40c68e5292c6246bf452bc52266f2d1490f87664378ef64f4dbd6d38a753ff6d859948f4e5a3e3a6960953c42fa4d724ec3c99acfbdc9ebf885671bcbe56b43d8d6d3b87c74d2664733de93655c3e3ac9c6804888ff8fd691c034d3c98493f5cc6998370318a0a7f1006efc3faf5fde8fb2b11f9798da7a9a525a815b9c6feac8a6de9145e103a98079a63c2339cdb95c73b46253a787c324fd7a89f5e5d94bc3378cbd498636bf491b344cf7b8e32092c9731772a4ac1b6319ac48945491a7a8a7a82829b677ecf875a41fe377382426e937d9d673b4f5b462b3582443ce6bc8d9875c44ce6b696f4dd6d3de9a4ed26f121986948bb2f1074df7b886d98a6d7d966d90cd7296b1fb48d26f3249bf5e5554516751ddf8ce7556927e9353554e7949575145796971262dcea435cb5dcba5132c49bf5ec7af1bb5bc24d3aaa28af2e24c5a4c59f52c93cdbd29cf4de6179ca45f2f30e73b77cd33575a185767ca643d96c1cad8641b3e7234df1d1b3cd55fc2ce33fae5f52b4617eb66f1016093fa4583d7ded8a9f7b93e73a297b2b1c73298194fd66f3f16d9e4e5f22d1e7bfd1afbdcecc7625f83976fb1d97bda72f916fbdadce93ec74ebae82cd69dfedf05c4b2b1d3ff1baa9697733fc67d571de12257ed2cfe92ff673e5009b1a7b5f51c5cae39da4ccc51058a91190f4cf246a3c570db3296f9f1ed4b2ed79cae6124d249f363af917092fe015ceb024c327c92321245d37dd916bf9ceeccf9a59d32bcd667b1bad345e670b864ce323d0bcfe4e370281f9d74b1a9cdcfffa3c14c2ec75c4a17197e9b40f759ae6bdaa93cbec55a5ea38ff3cbd667ba1b8d6f8fe5b6f82db69d15fbf2ec8dbb6f0d9efbb148bfcbe55ba4df62d258bf67c56e9c65240d788818824ef3654fcdb7a699708d949def8c2cd63033cbffc6f2ffba2d00d9ff7efbdf0434fff70075feb700ffc9e2b12fdf4ed3b35048101d688ee41ffb198a067476d93438d9ff2602d625d415fc7ffbc03a0d0d339d8c34ccfcff230fac9fe8eea469d82969ec3553360acf9cc91a4673721ad2cdba4ef2fae54d2ee3d8e78e8606cf358f7b3febb37309bf48ded7603aeec87ee46f8d820fbfc97c6b27208dd6673946fba28fbd239b8cb5b3d969d969c99ce519ed5f78ecb493f733ceecf51753aee33729562cf2613fca46de97676fd2f8f63976f2639f7b1d773e5cbef1dc91c535ba2f9dc79e34d245b4b5a27396914526fc2e8d74477b9bc5e6db93c5bad374b176cac91a66ab3b7d0446f6b9595c2ee1b462b286d98a69f3cbecf3549593cb754dbfc6b9a3f53a86d5dee4b923f9156bfa5daef5b9d92cbe35fdeaa0e93ea3c9b3d8b1afc149e34c5cbe703dbf62c32172d9c98a7895e100e3d2512423e302db1176038c383655d5439ebb905806a3bbb1c34dad2c63f78116c3cde6bb4396ff9fea3f250194ddfc37f5593636d530b2d7f13bbf4eb4af6eecb0186f3be3c76317ddd56318892442e1987b1cc36848d286c362afe199edf8f6f9ecc6b6f2ffbaa8b5e270483769605c8cc1fe97f8b02381e922131f76265c17917d5632761f34dc243669b8f91a7b132d5e36997067be71d1d89b3eb23a3cd7558e725cecf05c3f0ead623fca313cd7017432fa183bbbda967118d3c9846378079bbcec5b75a76962dce3b894bd7afdf6d9465f9ebdc7b8378f70d532d8b1ff6f372ab10ccb36e21ec7ce262f97c4a4f1ed6335cc8475ccbdedd5218315e112f24556bcc17523cc061857712c6c6c8cabc8a5a3c78db01d4520c41d2f7d34729171c1f5d2b9438716da5b9665ec3ec47afda2bd4d796eb6d5f01add56c3b30ccfcde51bcfbd3ec2b57c8db28e2fb2b61af6d143069bfbf1ddb241f7319a2b59cff0d6f1ade3ce6c7bc5da6ab858451525b395f5b477b9d5d3e4321d3662180d9ec38eefd6183d8bc960f4dc994e3a966db4c5ef0e794adcd3a410ff7794ff573bda4bd39df9bfa12c9d4779c7d6ca32761f349abc9c61a75a9f792cc331cc7bb29ee5638fd1603a76c63092d7726c63894d5e9ef1970bd1845d89d3bd237967ca346f7b9b5cae39125e2e61367e7ccf78b29ee133febe494e3bdfe491cec6946bda6914f2f8e56f3f7b97c263afdf9a763239cd6530390df3329aeef3f1f872b4188ed1607af93ad57a927ebd9c00914fefdca9a8a8a8a8a8a8a6a6a6a6a6a6a6a6a6a6a4a4a4a4a4a4a4a4a4a4a2a2a2a2a2a2a2a2a2a2a0a0a0a0a0a0a0a0a0a09ea29ea29ea29ea29ea29ea29ea29ea29ea29ea2b0b0b0b0b0b0b0b0b0b0aeaeaeaeaeaeaeaeaeaeacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaa8a8a8a8a8a8a8a8a8a8a6a6a6a6a6a6a6a6a6a6a4a4a4a4a4a4a4a4a4a4a2a2a2a2a2a2a2a2a2a2a0a0a0a0a0a0a0a09e9e9e9e9e9e9e9e9e9ea0b0b0b0b0b0b0b0b0b0b0aeaeaeaeaeaeaeaeaeaeacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaa8a8a8a8a8a8a8a8a8a8a6a6a6a6a6a6a6a6a6a6a4a4a4a4a4a4a4a4a4a4a2a2a2a2a2a2a2a2a2a2a0a0a0a0a0a0a0a0a09ea0b0aeacaaa8a6a4a2a0762cdf7a9699ccaf2045daa767e13b77a7e3578f61b498ebd8ebf7d8ec51c79d19cb33bc1673cd3d59872ddf4e66a3cf62c7e1d008cf3dee68cc5e7fd57447836ffcef264cb69225a5ff8ff1bfbf6dc98ffd281be3febf93fc6f24ffbb6dccffcf0f1c42a4edac48d36fd3c938239b9ce82375fcc630139e8d347ce44c67dce97e84d7e4b9c999f4cb46cb5ef42ccff38b6c7bd3643acdd89336b4b4ae9c59c6ee83336535df1dbdcf655b345c6cd25c6ffddea8e33ef764fcf5bfd9d062f8281bfb8db1e55bbf5dffdb876fa7d56836dfdee7bad8976973670e8774b149d37dededcb22522e22dfbefcdf6bcefae1ff4dcf6aff1f54050410080fff2ff4402032003901c80640d800f9025c02c29b6c163b5296e79a968bbd7e6bbad8e766dbfc32e1b939f733a6334ed26ff2ecffcdf653927e9345aeb665b349fcdf35fa1895a88017c6887101dd419382d7196096112d22372454810300831e449e41d41fccb40884c6c43c725c002c988ac2c5eb8b863623d0c0e5c8e280a0294aa090379a61c12cf78e16f7e5f24d1a39d78f1b4fcf423a865fa67c6c6ad24e4e69b3cce624cf624e6ffd1e9dea98e9541fe9752c1b8b7371f91ae565b117cffe5ff8ff48d4a6fe7f81a59fffffaff1ff660ff471849e854d679a2c2fada2844f4d67c7a60ecf75f37fcb57ff3bfe4f6b3631e326e4bce6c3293721e7b5186e42ce6b5d633e92f4ebd535e6e3addfe35bf71dff9bb99ce929aaaa973e1a7b91292ee3ca39e4f8d59b6d656d3d875c37db66e370d8e728a9e39791d835e6a3afc973338d9e8da0cd181b22e7b5b4e61039af2587c8798d07978e1b4b53554ece3455e554a2ebf8ade958b611c36fd2465b0d2fe1b3f74c9e9bc55a5ed2c7e23bf7e5bb36f73a868b6945e60c2363d9581fe9b1164df798291fe377ac3ed263fa7dce1bb5bc7cc586c3636f36dfe19076d271b199d6439ebb90b6ad588669780dbe711505e5bc8a82ea71ec47e0aee2b11f8191c3a111ae3b3359c3f35b6cd29d5ebe5d4e35ae7ea38e6159acab063c1be97efc7f12cc37d641f7ba6d6bd9d3e6598e9346b2634f9bdf1db5b28e3b7d46fcdff0ff4ea2bd355d44836927b38e7b4dc368309973c7f2ed6b7d8c966dfc6fb4ff8de4c65e3b9bb533ac6bccc7fff641937db1985fcad8bf68ff6f7c208f2b4fcfc264fd369dda6a2b6154938c8ce1230d7aee3012aee37e84794d3bc738cd93f5dbe4cb25713854ad82ab04bf8af9ffb0078ac5d5e0721dc36f1dcbc624fd7a0d87734fd2afd75bbf475ecf7d2d968dbc7e111f974ed9c8e7056058a0301ed26267d2d8cfe2d78894792dcbb3d139d7742c1bfbdc93684e39eebc96e33034c5be06d730139e9b479e8cfd28dbd866fe1f7e6098529550aaa9a92f5f23ddd456c3f3db4493e859187c20d894e733b2381f9aa1c5700cbfcc3e9bf19a7e9bbc1be377edf8f25a8ee3d7388399fd0b8f9d7ed9f872f91a6f3c100c88e3813be4de247f99bd86795fa2c530ddf4c01d6eff2fa4e937c96be7197087d7ffcbf1710750c79cff17d22f5f2e3b1bfd7226b418aee9194672a4fcc5856dcba513c98dbc96637e848f9c3e72a4cc69e2b177317bfdc5ecf557b2867ff4659329db38f6bae99ce75e6f45f9a8e30e1b6322940fbad36f5ff6b1225a0cd7f25a3fc2f3dcd7c2ea4e23916169b13369a3868f4ee2dbace33ecf4e63478bdf22fdd6ef8db9fbe8b5ece3d8e31e694679b915b3c9715adca337dbca92f4eb8516cbf38f3aeef32b8616c3340deff8dfc65a5e9275265cd69d6a6f33ec18c3398e319c06cc61f4ff3b1e080008ff5ff64000e817162152cb4b9ae918c369438808e99ea4df25cd7bfd1ae165d3793cf61aa6e5663ff6b5ce693859c685b5bca47967c2355f32c248d8d89b74d33186d3948ef1cbcd8ab10cd374a7cd7ab3f926b9d93186d3cc78dcd76034a4cc8fbd9ee5669fb9cce397d330ef734f967563dc91c8b0baa3cd6f198c846bda09401dbfc7b81be97ec3462d83d15f35cc64cac63e8bf535a6d3069bac4396cbe80ecf35dd8d3191eeb5ec23fea2e77e7cbbd73bd747b8c28c70fd327bb28667e2f1abee64350deb180ee70eb7d56ff318bf335ab1eecbe5db3cc2c5bad3fffb8ceef05b77b2b61a9ee5a429a884cd12d589a0644c29342332020800000a631400305028168c0664f14454e556d60314800872b06e8848a089a3208929870c21841820020400000000000200003085da71ca94b4fe0e3e5e97aa4cf069ed35fea1aa9f4aede081695fd70af76e1f452bc0eef88533a035153facacc5afc70ee10a2755ac951a865526881be313ab8fddf98346dc1cef6928da9fc8cf4f8b68703636dfae2ad12e7cfea44c58d998ab677e9ee1c9bc461e435666e1f56f93fe27b414c49835ca7908eb5e11ac8b6bb2174b34fd0ffff9af2f1a47cbc87729c1bc05bc460018eee8f69f14e00486afbb383aa106e791f761fd6c537e91434ab139ef9c4db890b808be3a20f3000296bab38fecdc3602782044a5ae0de3041c03dd08896cc678478bb3c667bbf4d21c6491c9ceff04d7e19180a0a8a58dba74522458ab565bf3ee85a9718d6fbd387021f527d71303e15580b96601601caf6bea9a36ddc4e241ae2fd0c46671942ef55fe57b78cc5b109309b99772f2c24ed8fe145ba48599466fd92ce24c116a85e90be0ca05213034b2ebbb38e46684e69bb5c82d97f0161b200630ace3ec44b58262706a1075dd0f341dd7e7e7bcb9046a907009eedee442ec2cade73527bb62e34e4ef3850e0ea25065f61a09fbcd20496a849a9c9fc95578f6bcd64fe2b5fc63525419b06087037a5680c72d514d4b573d48fdd39a442357b80fc1188256d2f337e64670cca2c80add72cc4c13f0f07279b68c4e5a09c3724e98a75bb73fffd3f4fe9c2b627aa26ae0e686d5bb5cb4acff776ffe1abf80888b565f807f49a4690b43450640f626ee0661d0129a9e276f1faf343e22d7026f8214ca69f57dd52e36a7af3caf5ca61955552d8c25eb69cc6eb82d8c0e105663274903daa2644d9f2560722b0b6cffe55d67a15739bff8d23358074ec114936f60efa7a965e33e1f57f518aaefbdcee2401a499f6fdba5d6774071bdc21b088a764332b846089cedbed4d1d2c6d01a6dface06ed731856f69a70398cb27897fe12dc21a7f1c84ce2106319802ea665b00fcd1647a83ac76413033755196997a8887f639e0e6efaa0d920a2dbdcf7d188e7b281c08d91965dc3532878c8279db30bc781fbd78efed5a0c655e12e6ab34cd4dfccaa7d97f0c76c018c1bce4c2430d0fa7eed6f3760aaa8f208dbc89a70526736d2ad0c1e0c58485a7ff5180d113ac321e113c38c3f985764b1c8c565e74b16cab109652bb550b91197d6ac81f6026135fd4b94e2e994da30352df03dfe92328e6b00a2f28778f2de396380ceb460a9ea3ddb205ac22ac18547fc4b020e1a7a5cc25bc29c5e7598101b722882df6f777cb890b22cc48df9f6a61a22610d4ce282c46b0ff7897d936ed36b0401a89795f5457df8b156f889c98a079084fa6080fd05e65941cc4f29f8713660daa85b25e2882f0a609b702e85d79e2c752865d7c065aa75794e465672331fa77357adbd1f712aee2171d911ef87d9b8e5b79423b784d3d4078784fe4082222647ba2b82dbdca19e7976bc1bfdb4eb24667d5e581242f69bca7a8eb0cf7ffa229f20204963312270592994431b1a28404a3d82aa588c8994430421d66da007b093ed783932f45f4a13221e7d553937c432d56715406d65c9fb962875a9bfd1ac7aa2b2bce692b27f96a7ff769c0afc5b17072ab433d158bef96253d3238976379a30af9773602ab1a6bc518be431f0ffe2647f3d1df6a3a46797246ee9e6fae4d197b3d5a8bec96db1de1b7723ca593d2e38d231b6c0357b8035350df77c1f1f12eb34d35b2c82e5513dada6529a2b6f808f694e523ad379aea09944f37f7a99f7369fc74b316c13de4006ad878dc0aced75c3237a58ce5a9d2aa33b03c6f6b93cfa3497e32b3314ddfc279996ea53c4afff320822b09e61a1c191fb2a54f30befdd490fa4d2fb70bb8f3e893ed909e9f1f36f1333b292712b8cfa8c6a99859ebc95e37592d3ea818fd759a8aa2667b3c0c1f857f99be42b80691914899bcc01750c057de9369ee940b75af7bf0667c8e915e963541304f7fff2c440e640bb752617124e45f63428c79d98c340d8817d4451ef4ded8ea51798c0c6cfb829fc9dced61562fba882a33a72b4fedd329b969f8d8918f662c6156beccd7467788d1834b29415942dc1b057931062f96898982f610c845b65a79aa1dbdd4f87a17e9409af197bdd0af0e47f481772b56f23efd9ca92b29ed687913645068713c39580f733d0569e939432b34bdb1d67788f6e30be2e313f22a63c042747736e42ae19af3b3f7cd9fad2413cdb21589d6223244b22e57faff627ecb470778f07d24a175de0b9135b1076971412c85c5229ca3b3dd842b27ddb547734028f65e083ac704986b260937dcca00c8df06c5b2e9bad8d289f18cba5eab71e87e6fa8fd932b12395f9e410bf48776a45e7d01cee3434d74102384e3092ca48b9bfaaa0b16cec63aa7f0edf6a22f218d9e2f206a32e2a86f8ea7892ee6858cb8cb73675a2b0e0099e2588ac383b236cfe0ee87c3e7a0b18ac826c043564373c5c9b5c8a313b9d646bd13f993ffaa2c3f822e3d95b219e8cb11ed0b44fa40a2bb4a7a3ce706bd2a5209a6f033cfd7f39cd7d4e9f1b23d74b95ee786e79cfaa5052188515da535d6dcb583e3046898de34108a422cc781b39669d421d48e8195408f592400dc85e430a0f02c92a161b59233adb1283ccae19dee1f1cbe131a7d9fd945c3f85af41b80f58f23df9d368c6cbcb668cf48f8ca975d0cff7089f735c7d7fadbf3f4f0461fd707ef67ddb386b19c5763a4618bb32ac44fa6881563f263b0c562192b4abcf5de7b594830fe5938ce1e23f59e6a8018286c7d6286bcdcce9f034f354d8ae50ce57cbb442b5bfeb355b10f63802517917c7c8562f95768b32d5c184dac1fe4521cd88ec6e39fc37a28a21a42fc8807a10b1556f34412acc7020521ab129f901a13609799ff66673a082fb00c1712457e5fe6e9639ebbcfc4d9ebfe2d2e27ea1109ee746ec2f6e2c761521fd6e79fbe7967495b2844329c69650a88890714773f6f6263d91edb43b4c94d024533eab5d28934d4a77ca062c478c80b1359a22178e8a70522c4c62e333cc6802b79adbb91312cb3a210155640894110f9abd93b0f6d346b69d145de47cccbd836801293ef119d63823e3d53586e24277386981f9d095b0aba5f1673b375a31fe113de9e7efe7130fc0ff7afbc4c51ae4dc1f0a839c23ff7b7dac333da126053a55af2be2de1b5a63e64897f7cfaeef395c7e97fc75b631217f52d50368f78e263cd104bd6613b450aa2154f12ecfd919814d8a1be65b1b530ef883d1c31904fa337c230843dbec7ded0befcfeb47cb25a57b7f015f1b8b114b13e257f03b75dadc21585af327d013e96d529420b9870efa8cc2490482a1980565a446586a396288216d2d5bf72711663786279377f4f9ef706c2c7b149a7a34ea8181ca229f101298fb43ad956a998127edbedb8e32a799d391377df37c10842ee434255d439dec5c396ca9a85cd85d5cb9f88ccb95a137af9fab4d8670c43f38375e9fbe8e7977606b50be543eb55fa61dbc62e0d91dba57dc856052c70ea4e99bdf5d271fc62bdb580bbd06dd8793888c99f50cf5fbc80517fc26e70e0dc270cb617cb3e9b8959e466055ccaabf8f325fe30aff088a153a9c4187d631b8ff227bd47645651cfd7f98f7af57436cf2a7646ac6fe944a33ec0856a543166dd047b550f4b4a85ee33d8be3fd79a5c7088c06fa52bcdaa49b32fa4d1ad587910bcb7ce7248ff28a782447afe009ce225e62fa8de663b94057ef8821f72f98608e29ecb383cd63b791ace4997c6816eaf1b8a00c0cc23bb3b84a6324f39e2033ea0e1666fd4a068603a01856cb462be9de1f72734ab9c2e1dbf8b54201664250c33810b1215206640d158060809a5538f31f4b78828fc2a42e28f6c0140eeacb100938e3bd10d0da99663a258dd7a40ce3db8503627c9c9d1ec69d43b31f7fe485d0283826ae1bc071b1db177ea521d29a7b36c5d10ba3626f8e8ab46a87b5251386f0546ecc5c068698909b918c94a3a3e28d346c60c639584187062b6d6d42b55674e30df9fca017759ec4d3eb82a573b9ba326a31e954ee022fcfdd8b0a24be588bd5fc340f3fb18a2084699865b3d38b77153a2b733800396e169ab51ed3fc0b9c28739b7bc3f31dfcf81e29ba57ed34f42eb080121aaf511352e1234d39f9e834e0aad9436842d624d9895304a433d814bf76327a9022e109673ed4bdf8c75b5a0fd398a091f2d8d71d19deb2ef2a57f2dca9b92e118130d79b48551ea807830012fae5090a07472880cde68b376cdca472b5da5d1d43e612df3321d01375b06d13fb6b0d007d57821fcdef1f83c2d5a7c058f1d2af8c3275af8138b50e5d260a9a778857971cac7831749f59092731cc0d04a51a85504e04930dcce984d148b5f3053a8515aa675964fb0ff55de42f576dd5df386e3e5d14eed55f4ae54dc532f5e4b973e01be146d514233cdb8b56fdecc290fb67cc928ad980c2ee35940e254d828f355b9b3e2d8a2b38d79afa655b3ec9c4740802c5bf11784a230dc02ae934a91bb638ae17405685265c70b5cc5e99e30c1366b6f95f48d719e8a96215370503c1d67c7b42df807790b6b1b83e8083dc082727e58174aba791ac754c8111932da7dc29d7eacbfa795d1a3f6348211787ca9e309c0be6935efe80a5dbe8306ae472ea880513dd13a727476949d885fac05e50a4d3b02b73604e1a7ff8f4316c963a1dbb3dc9e59d21e725b302c5470e8087650b2ad83febbea00cd03f7380788305a75658ab937613664cb1cdb7cc6ae61a4e940229a50252300f53cf8943bdd6a3648c562f05d9fb0d0327c5974f31c8665954ebac45551b20d32446c6e0b81e8a9955c4ef11140615516ff392d85fa4592303bc712def6519b18096bca59d34db29b80e60126a4231c2490e8cb739b2d913cb8ae29cbe7431321f04cabcfd2e33197aec4cb3f84d18153e96fcb43d9b4bcfef75ab4ffb02c36045ff323e950278473a6c95bf042bcb36904be9688a131d311e16470bd3afd7918c0cd9dd1bd14db9ac30e8d493d3f5d15bd8fff28de3387c1d154b9229aba42efd0b321288af873fabc839821589d32dc310058910390dddb7ce96f31f18a9b86afaf513f9284bbd78f2a1e713a9ccecb2fa63876da0fe4c980384c8ce9342cb94553b217888e29d8c82278ed279e51ef327e1cbfced380182121b684a7719ebd4897b693bff20ab01bdbe57bf6f00cabf806811517db2f533d4f4ce5b60ef7480c047d6fcd0e1aa4f88206469d22a7642eb9a206c75aac96ff794fddf5b0f092c4f0dda6cce765b170db1c8f326d65d99257178c1f01388099015472ac6d1958006baf8589011eb17d83a64153e924468565b1106e8b236f2b0f484f3c2ed9466b868ed5ff019561ed35e9b0617f2a7bb2edfaa90259b69c9dc232aaf55dd7d70901e6c77e7d4996e17cff0c8f1ece28e1e72fd212cb4323e95f7694e99c9961ebdd4731851f254d8fe1bce943eb04262c3ce235fdc00345abfa3ba85dff32e2dd160d24d7a38ab22f8e42101009db07dc2103ffa8f4d10d59498f616f289971633833c6441364e21f2ae9755d7326f2aa23c3c3db14dacbd4157ce6b8ebea383c5a81aef64c09512d6e78992c4960ced4072a568b0c4ac56329bd096b73ff8239cc668a8bce2ed84bf4603b51aacdcf8865ce4e7ae86cde27b9386393d6f41ce50721d5814a1e894fa458d5d6a5f08eae4322ec22b88c0924253edc57fb0fa86717ca60a0398fc67154d3771e3375d54998f27bad144b4c8900c87e45f4a32278b239b09f38a7142b5b0b13364ec0db8e7fc82e23d4cd313ed1102aa594c5d258459e8965eb48a9d544afd51cca8ca8b842a9a2fe414e63133fed912e84e147703aeca7da30cd817d2f88cd31985bca68e2a21b31b3870390ed6f67e8477f27b2d003133be9f49e17fc5c37c55d9a4ff219ea8595ee4a337dd80b8889025c4716419b11bbfc8cc9a56fa08f89d9bb57320221a06944c6e61e7613f39fbcf1dcd7f22bd0361d82017f70a2e4cb0367a424cae1b42add725e9afae99015daef037dd749ed9620eac86719be5f5700bb011a02c571b1d95e93462fa5aaa2feb572f53ce1c462572940c1f46cc5a1f41cac7531da981d9d17fbe65f8cfdf1ac98e81d0b42e7b1ec6f77c95ff23089b87247d3d03634d7bd1f40676515d4be7ec4324509c77d6cb93623d5acfb8ab1704f8ca2eaaa632242b27534d83a72efd12680d250502c8672f7dafaa515f264b491b99540e5425eebc06c2e796906d5374cacdceddae8155c8451fc5ed56eb789e995c241e039e7c11d3fd8f6506dff5d357f37525479e114bfc41e28287f8e2af36596861c897888576bcdfe6d88f7255af34defbdcaaa41319a500970325a9faa925e13c574e9f96c06eb64f3f2a9689921a18a9f7f32421c6b30a71307c9ec20d2c306d44e5145b1834f9466389c0a39b70505ba49c4864f738aeaf4ea3b1f2085140fa172a46090ddbdbb1084ba34d0779bb1ef33e44952a4d3eb9cda201a047cbd3cde9f81a041108d13f21d92b40c31bcb651aa419d7b375f077374a7b3f9ced418db5c0ca1303d39178ec7aa267b37573d7138bda7b23709410026179f10dab4f986a4c79dc29b94d7a19ad4286130e03a02675ea6a22ccfd4aa31c4d6696593658cd67473a7bbaea0d7c990f6f80b87500138d0e8650f3e3622b6d37361ec5134e847da53738f0c64c103fce1b4eda4d74ef732ccae184d19d6e6f34884b67496c27e192df7ff3bd89614e244487e0b66b4c66491b1b9ac5ea5b2d274bc2c964f2db2f53eda79f3d27b8792d559ff1185d5ee9fd314b231197e05fe18ac21ecf86a1119fb646c2beb98ffcaee671bf5f14a6022b62091a43e6abf0323967760be451c38a5f5f6ae451083194f88a85296b4ed8bb4778b63f0eda5608c15b655f2c5e89f95163c06874a997c961850153c810333d4f2f136c8f5cecb6008e869d721eafa30e786a4d060d6da97ec36a39210d55a2ac9462012f350319c5d296bc773a8a919916d50249f2d98d9e211807b0675dc65cee56ee059707c83ac203ba709795f4b6e3eeebc3067566c6b9f13e8c804237b32a2ad15c31faaa681b18aa227d5fda1f5cc3b15d270775bc7264e4dc41332553e578cf135742c6fa70bb0349c42157633bb4f6078939e2fbebec225ac7e105994c75faa21e7b702e5ca2555b6bbf686c4b266b646492cd62cf2c30eb6940fc3967f439bd0cce1be834d6496aaa693728312b27b6f703ef6de2e06201bfe1a2a8b1eca7ba9b9567061dab9d51a651ce226e122d810b6cda7ac6d8ee3f83d1b483a84b7770bbb38ed8974b0484491d74952110404b05e506ac6ded6d6a927b12a42127f9f4ffe098143a09360c512facbe1f27d6adb6a737dbac1e2f30a31b358794a5d20e1f70a1a9a806eadd99bd6cde0f42fcbeadf8ce710f0e346ef9ef0cf25571d51dea8f0b1ec638873201bc9110928a2a34f108d39c865d0893b85cce5322b33949baaa3654f2e7ac68b4354ec5c3c768ab65706a770acc19af6bc97a89872bf10b322b6e64ea3192621ba9a37814613b5993e21f9b5e7066ba46aef5177f3ea21b2d495c34be7a453862b5098e617944ffd6a801a90cab969b18652fc987d291565bd9ead7292d7613d1e29bf967845d2536b1e220f67db434ad9163166982807eb76c5d7a5feca988564657d55a916fb34222a33b15cb5d6287c14266f466ab352cdc42dc244ee324caf444b3a7f8486b3a16f13f2336171f20083d199d531e12fc1359297e21eb3312be3e1dafd33d75a285c8b04dde9b071f1e0cd42af2caf452f9044c077263ef3ee68cce01b9112768782d973fc2332ab87b40862efb6f119d35eee1cd1cb1ad313208a1adf35ff3b5f0fab7f7f76fb932ac866ee779945787b226a5bb194a91b3a237088cb4e2d97fe21382ece4b9f27eb2b4108e215efa44afa05b57f01f6da9831c56dc6e4de984934a3cc42c7828313d87b85325367339a3d6da046fff9da25d32dadd480a594a4eca92d19b0eb5afa5ea2c0e3a9f55bb3af3376537548d2da9436db16dbaf5b9df19894af774e38f3408fd2d9f05b37eabbffad6fc0fe4f21b59489b5d33636da269e855332cb1a79622e152c8d4c842a6d79fd46f8f2cb03a3c2bcb57ddd2a6703903ee2f3cbc7318acf70bdba340b0ddab1d5878251124cebdaad6abdd7af3075f1c427e43fb269b986692d2319460f43bfb7fb8909a4e94c1c1a1e1ad3c177f3ec833bfdc19fb0eaf322943d0feeb0037e883c388c75248f9e9e1a6277bb1632d5b766df00fbdb29d6f9c723c043367e643f2680bcf42d6dac08065da9d6feb0e4478f9cb2a5b0c02c75a5ff8bceb6e5daf92caa2db3e59a6e00bb0a15926a3ce8ae4e156b6513e5fc7f0f920ff1ee397a44f7d08dac6c5be09b3082e5c40d5abc312a1c56d41c44f02f6cb790ad59de73c078e285c4e4d0b320de70fa371824d0d91d18ccc7ce644a242e214786881fdf5888625ff46b3a4e81639e025d98c6005d0d400920586880bf6913cffb1a59d0a26e5fea557d30a30e1b795b3f02e5f30b9418426f7f0c60c88cc70e44f24daa7af27a087a4500ef66b6e5c38e24a3424a8c1300c62a39f9d5c7a7eb5397db6b2037b6f25e437ed97615ce893215d30b88eda7a7a981a95a00c3dc3ff61168484c4698382603fe00f23c164cab845580ef841ab902430333b20ba381e1158700b1c530888b1f1ee354ce40df43acaa6b90b6d143964b482bdaa1c9d96c97f1185404feaa7a280a4475e27e12cf5a15d21814f56a85993e2d37678ee921064cabc74142a34f8e72cdd0997f25bc2e4e66d9b516dd4b2f1c136e85abc35c06a2ea4267c4588389a8218f5c14970883795f9bcf0091ce44144ce1f3e8540b8d0ccfb8fc94050073d7679204208dac5c95cfe4c1c847050c2cf9f9540405c4efaf7e14450c09d16d999e0499a443d42879e080ef51bc719888bfe875c4e179e78849827899e7cfab65cfe40936c8b7de71309aed26b7332bd4cee55cf987ec20102f71d45aa89f0a6b71734ea8c01edc65d4d92fcf21a06398efe3b8167ab47a333394607795161c68f20d7a878f9570231b61813866dbfbe9ea91fefedeb9e778f9116ce09ebb76b86c176a24f0969216513100434db9bf1cc4c15105582c1a45a8244056b7bd6301a5d2aee44d7cffe4c145bfbf681237e9cff3e875e63b767396b843216be8f587f3fce7c23dd0e5f5526bb9117e539e46111cfadecd1ca0698a6f53b9bc81b9bc581f3e786e51cf79ea57639c10329b35e926c16c37eb1e89721c63b86279af59f90b5438f88a029e3e8dbac91a017bdd9f9ba9531e37b9176976da0372e24f1523a8f510e1993c39884238948ac14a027cd1b1a18bfd9b997097dda01398b940a4c83f702e6830cf2d13556399b9ede62e23f11e4ee1899c73028a375f4f3d476a02f10187a49b73041ef404fcd0e0f638e120ab753aefc63f5257b83b831d0fda87ee5925ef0eb35a8bf4b6db330550589ff56989d4ed6a5a1a325ebe8faffe929717f27e716084f6bd945a7ba512cb63c16401bd6bcefda18f18df5c179bbe8a85db0be964e1ba282985362c6d32e1a760c55c7a652e1ba5509dcdb61b29c37d6840ed1df4b12e4ec222325b73d2a406c0bbb7d49ced5d4b78b6857f9ff163868851092d72e42daf8bd8d87ce0f44a7bfbea39980857fd7be58cff7f625179710cc374fb49597b0f1e8e12d76f3b860229e11b85df501fe6e1f72fef6ad4018f06ef494f3c137e829fe6287268fcee53f210882c90bd3a7b4f3b3ecef56dc2b04b29d21f35c743f6a86fc3a3fa73c9adae88c501778c2a8d60dc7e64bbe94c7b9a7925cb8e8b2cff157990b5f52645a16075c0b718e3e7ad120ef982a17752b18eb5b7c66921c878b93148fcf0f5211841426d30a4f2723e00568ccf4ed0fc3b7084b7c69a7c7808e72e3351d770451d73a48dfdfaebfa740c4763fc2b9b5cfa7e3fefcd4f7abfcb27bc8d7cf7e321ed513ab4bf4937edd77917a0219845d6bc1b593c2e84ee3e3de2ef8467f4ac39cac78b384782a26b6edac06c2bdfa87e664a6e14d0a4962d32b4306a44f32113f70bf391138ea7fdc17e66801ab6508942b848dd2c35c1ca4e5148829c74afe87978f7511254b2e4ff9162d14413a634306012573e82d9ad77ef507ce4d912583338248ea073dc9a01b0746dd0771ff5dd87a8558bdf8fb400c2d3fefedaa200bdd51509ea07a9d40c56a6d4f3f11626c4b6500b88755800bddaf902568d0ae6ff8b7caf2b54bdc0fe049bbe8f202e0dca2dd1e3626ba7879f278f49b8c4ef872f8fd7f27927cc8655d9be305bf9584297d375c837e9b21017ad576d1fb89708a02f7a04597adf48dec97017688cc12ebc00e7b9c1b5f9785c571d0d4f39a040bb16bc1bf14d5fb5ed21c930b915db843ecb9bb320c4a63cefae1810297bb566f1e40bb3d6bd75cf4b7ecdd81fcb6288857ac83138e421e31485610326376bf6c7fa83d7d41ccb1df667c105f36d2ffb493deba1edf555ab67d8f8ba624e152f950da0f461677aa184a684fa95a8eee162c70d005fd2c7af70051ac57799b5f05f1852557e4aa2a8b6eb79401d7f71db14bb9870086852010084d7a93a99ea7309fa2c548917a26bce02c8431fbfa57335ef54deb32a00c11a4f83f34ca2cd30641c4a2d50e307c1ae20e4b0f8b3e06fbd24007954c0263576598230bf8317d92ebb7675e2f802a099c6aa6eadac7c9728eb4590607aba4ec496d126f00309911acdb68fc71fb0ebddff5166ba30bda3be00e00309c056bcf607bc601db7ab12fe828abe85da09eedc9ef31ffba4ffe3bce0bf52734c017b4f5ea8266daffd087144c7513b07c90a4fe3f423895874b268638f2fb281080d92bac34f96b95fb1354bde6864afed5ded5fc3010fd1d26ff3d42dc0b26edfc6a2d4c6d019370a786b146cdee7abed2adfbc3c68697b99147f97643afecb9e302be4793f956ec178224b3af091f8e34b083822751aa6df934dd01fb4962fb4f8973b955a294a57f84a34fa5a9b5787be1831511cc63a25de15031ba3507c8fbb0fc8d89cfa3383782b7bcf34e8a2c4b746ceec366d36a2a23fcfca323f064468be604f65b16655e5fc93706348f29a97fee901fe721bc13342c0d463a51d3be24c5f095e782d9e99fb72f57392b05c1d9ab29b7f179b187a5fde091e2de1fd13787fdfbf019ad7874284454552f5c7e3caf616e36bd1c377fcfce965147ac1ef1bf8fa2f45a1dac7bb74d548ecef3ad721ec665d859df8ef929e7ceeccd896263d659c047a6ff03e10e448889cea200cc33dff2b016d18c34b0e2698acc8f97298af65fa3015e9e8af5f8fc247ded4fa556f750690a7e6e7197fe906924ffb5ad086a2d83ea4b75d672f0fc06700720be9f9bfa7a4569f95f5443cd625dfaa36c8e9a1385e1fdae126a6cc8dfd3f6e96e61f7b8e1754ba1f76fb5f0fab09bf3a07946352c0e6ea25ff7b0e5711496e3c586c1defe43c50d55ec14aeff5c12250c8e2749f99a1f9abce9435d22057f58ebab2ffa679f98ffdc61b5f20ce45dd68aa1835a395f2f5976af055043207afcefae29bab44730e79ceaa873ac420ac40899a0845932e3a97930c6d0fb566cb6fc8d4f8afb45453fb60c25a251733ceb85f5ab20371cf8ac514f5c1dc6be8755fb412cd1e6f06e419b196009c048129d8667126b46a083ae90e094843e0638edc37dea33b9c442c6018393e8cf0ff2d57f882776efdcfefb0b59b68dc3da42bfce9eef4c7ba1aafe454c14fb9270d3e7237bcbbb0affa9c0fbc71c7a0990e730915e99fd21be4497fffd472fee948c59b29fb63f9ac3650eb505f9a79f385a6f1ccf1ffa147c939cfb0654632a2914baa4f481e5c5e8f56219a31b980b8caebc85f682d2dba8181532f1f1fea634c2021398d63c19b44ffda54e55c5fa73edde952fb6828a22e864c10eac9346503f40ce10c3747a4f62aeae57c8955c1a43d6f91d4447abc1e43ef273b51716b9eaf92b1aec214340ba0cd10284e8fee4d53a6dc252470f12806f2b801f31e2ae739ae93dc0918079704e481b44108b0b96d34350c23c9496a508b538d9c35d095a54d025688503418f6314b4a6a519d97aea3d1a444da1bf7ac83ca58ee226782246149238873e38519e4fa1376f325c9aee117b19e804694a43d424f439e9dc4f2b2eb0e98a324f52ae12e902882c1baf9d2794352743d3ee95a091175b9966d1e65a55bf3ebf8c511ff4d3329f7b8516cc72875e3bb8d1eb1490735af21738ad202344020561dfba8bf06cea302c20114923cf226b558107f2a4b2396c4614a32a4ee7c9060cf491a35f2849dfa8498d59be48d7153aafd0e9bf07faaabe4f736616aee06faba88f994e50bc648be4bfeb16cb32a38c2905beae749b4fb90482f262ae778b877b98021e9344b1ca6aae5e988ca2093788b5b097ad5bceaf57d395102fb173e1f18a921adcf109a96675a9e497cb47d71214e18f2275f71fea24aff3544d116b8993acf6ede3cddfd0c932e4d255cff6bb61f87c64eda78e2f34cb668df7bf06f20958596aa26f2d5e1d2d5c012ce0cb968bd181e9722a6ac4465ef586534124966144bab0d4174ca39b2e645f0448183c9da94c7f6cbfb505126519d95457f4c2a02161146854d6cb19aa849df11346a97a0de08d4af9bb9a744cadba82140afac4a3167e3ed86d39d8e7a7570bf3a0cd2d19e6673b0413dd1f99961420febcfc2b273ef5940272704050624d7b503356b8c7b30748c4b8478567616aaa6d968f15c120403416d67131705c3aab252463a643d78bb45924e591989a361b85b796c97b7662e14608201dcedf9c895560dc06edb593c4f002efe1a02551efb7989c4929b18d012c039cf95c04a15111e5cd64d35ba9cd322b486469bca778fc530af4e083ed02da889d30426d12665578c6a5d2d7d34783bff2fdbac67bc6d483ef86e1cd0e1a385d294b361f0994dc32b2a56dc21f53e8a7c46d55159be57a252e4e8a2842d042051a54d0ab8eff63936b0ac5c18f34be164bf91d9480ddaeeaf3b90f5c7297aa8db879d38e00853b5d54d663cf257071afb32ed1c4fa94f3b7ad1f2391465262f0c34a07c7e033d05da91511f51c71d89e696250374bb37d9ea9df2b444865dac848bdd6763bd401bf42a5b5ef6b1b3c8b993cdaa0154323a18b9cc90a8843aea3df7883144e79575e5d9015d2de64c3e2e2ce176bfbeeb00c3ab3b31c63b9558da950ee497f7381cfe92093446411650ca801bc2568a05da8b5c77940cc57f8bdc1fed5a74916cff105ed4e55d3eb237285c373d606ac9fad640a16438524fd3418ebbbbb6532c76908012b622a4da01043b003b624567a51ee441171ac94f85d708f62454b07b468c6d4a2a7d6ec8655d1475ca8409bae1d30858eff1c5a3354164c74ea34a7dfb64a3e8c7e9ddf40e0627237d61ffdabd5d6969187c1455f85cc93f5ee62209065cfd6ec77cfbefe2c9e47042e3229eef45b61a8a00d6a1cac402d126a9bb613957adcb28215bb483dbb56f618a16c9053b212446449279d063896d4636c39afd8572db16aa7ec677f685401c9de4a8f4b2d75a451247cada2a985c6da69a04513a5049d19ee9ccba1c6948167a908c952f72ec1c6ab57c306f8a506030284fe38f7b6462de355e9fd43c96429d253263bd7ac7a03807809840c8c916e892fb9bf2d98854255e9023fae16d4726d985a64da9ac5cbf5943797069287b149ce27cc26484e69c884f9840d01e313b067198e78c1934e6d138c0a895dddb456ee116888ccfa045aaa10999f9e970a31aef30c24bc5695eb9f744cad47b0733a43d253c16323386f4a52384c4320b04a494c7d76ed83f943e04030fac02080655deac12186d428655d08f70ff2d393b78922999df66be43ee7a4e494475776e6c370a9b90964086b553bae082c2361e8750431b09919e954a9cb075f98ee2fc676431210bb8cf6b287ced887328433a1773758c66d09f0d7888f3c8f12e6e27b2379afd02dc7de69cdc41b053d8d8046a3968e1e76026f20f056c55bebbc89e02d4478ab808a83194b5bf96ce1b6a7326a317e8a1442e12633b770140e89d451714561792dc09d6378df1ba8c39ff2ca793ca370637bb7f1202677053a9e7afe28982cb859e4c23404fad912ed55afa6ae0f24f730a6f0f5ec05df6584f48da18a51670950c3d3542e249ab7dd31e8a89fe0c795dcb6045a1d958e51037811e417b61c35183ab453f8ddf6762b649fcec2a8749254509485acbeda9effd559c8b19b90a4059837d740d5c6d59fc8fbad0f96ad48c0c4dc3bf24af7d3bf455eb61ad9b80930d631c74b1655c4bfa72b7b6d6fbf72714a3fa93d6829d242b53e3aeae02062121f446b4e4462f86e782a80e1f08b11dd23cd5085c19955370d0036582d8b38ad5594d7161545e55596e6c766dfe1a9bfe7edede5e2f0d143bf8d3092af13d5f0e93689b5115b74117563840f34dc18ab711f2ffff0da2576e1516771563ea310d229ce720ee8c0216445a9ecf0d7c0a57920290a57602e6dc32bd1ae483fffe9b559b0876839ffc3a3d093764c84228664ec37c2165559bb5601fea4be9cddf4a841c48ed7b948265ff9b7083896395d8281f8e2a781498f3487d489523dca461e923f342cbb6723ad301462e65684f4195258c1a00924d625307253ae5329a14ef9d31277d6629c15a431a2e4c820ba92d13becf6daacb285a59524fe82fb4c0e53e5025864149db2ae3e1d6a638347e1fc307795687a6c9324b29817fd78b6efc200c40d6eff1c7b6f79526e1c3eb35c45a7d72b1a37e749b1d645524cf782c6fb2dc833bc2c0dc81d6f8b3ffbb1c31145008601189bd5a00e87afc56880907699b266d84891a46e7e750ccd63dd2efd74abf2b073b2f91864ba57a742eb4e5eb5ceff02dbe78cc63e004bd7a9e83fc243514e1f3a9202bfe896e009cc4a5085f874f24647529d45f0c7d15b1fa54855d4db0c41e4f1aea18e060cfbe53efbf3611a493577015e05fb44ceb071273b8f635c7d2386d50dbe34a3b56c1d5714523316915e9477a05dfd76b3a593da6a061fa2719c815172bd5e938127512e76fb6306cb9d9846ae7c48d659dbc1fbbb2042dc24c39bd806518acef0d6aaa880b22879f1348f6d541597564ab1444f2fca2a060b0b9fb2d68ca6822aab3e52dee2e8cadabaf62c8907c4cf6559e9460bf8d3dffa905b401162dd5657c5d0b8a246f743b0da800a362944c23f182b0259906921623611cb681c91e675d3d029e1e91b3b798ac7f733788c2ce900ff49755276d6f1cd9535392ea8abf2ae5e77d5218b234cc3f058578701676e85f3a2f83ec1edea9537f9a663f9b0569b39e8439806a82a016059a7d9b399115ec1f0121cc97c87618807fb4dee38ea1c31d4bc7e75ee30d1e82eb40c2bc24c9da8fde6e9a0a485897b9d8ce231c88e4b0593fd9accd9e9c74694fe4be8c1ba64d9100a3314b6e40ffb34642538498c64e01e3597b872c22323b72e27fbce2df2dd59d596e874de9e42b03bab3b26ec7be513e1cf887fdbd72ac2f8c4a3818111d40aa3f9c8dffc2a92fc441db14bc5139587eebd24656abb6e46785b2b912235151966022ab8cb8dba00f6958c586bf6d8b2c839dec1b1292bf2a023724b71f3ac6dc44472f647e2709da6e8fd9b75bdbd3a9ccecf2e4e0ec78bfbdb213620e8cbf7d3e3e1e3fbf3ff7b999f96ce2c8ccde61f89e74b7b3d78f93b9180a35e1cdcc6d1fe3500a71ce060119185e435a3029cc5cbe36899122086bab57fd4814300bbb794f3d4d144fc8e5c8478309c7bd2577a6349402856935f8c8123993c740409f8f12dc3914c869d63d90894baba5da98b858fa18270853ec40fc584af811441553c69a284096408a409b634b3f1078ad39e3905964d5d453dc01e01d152ff226e86ad3a04f4f12a5801db3edf6bd8c726d83bee500284481b97623c0992d1f81b6602773e17fe70001396566e1f4c60bfe3adfc7985ad343c759ae5ec83395eba9acc4ae294f3e016c74bb681af6aec784c4fd83777579ecfca65988ebb113f94ecaa7ea3086aff792df6c66e5c33cec2401fc2c6e5177685beec42786bd0c198d50d6474768175713e9464711f0e4d9074d0a5ac50bb39004d26c22c9085f6b7621d18329e26357ddadca676830e1245f220fb9d042efcfa1c38374b65e586727f11432947af8440805350e3d1a410be70d7314a747706f0fca9e84a98222866d84938a823744dc400a6c0713ae654745aa09d48305419658b1789c919d247c8ea38771fed804a5e1d94b8f645fe7ba3f4db63baf32e2b31d61505b721110fff417baa7c9728cb2d9e23c63161a1ab6845a351a20865d15386340a2e4bd7aa97b02a09e4e3e242d5f8a97ba69989625d95d1cd0c70a3d8221667863ebcde4b4e6647a775e837ce830c8e70162144c542d98c228db243ee2b5a82e2caf8a91ff5111ce49befa2476826889cf0bc34f35c195026a18c37ebcdb046efaa36ae3e0e7fd49f662c450005b9e247212ec9531a9d75cc9cabfaedb40b1fd72619fbd837da7d3294f6d5c572d9180bb2802c51b2a0f720a29e68e9a488f6ba3f5656164c38ef6758cab64b14ffce79590e4b50b3e014525596fbc12b6cd7d8b6562de285ddb09a51f50d6a2b168d93c15e65adcafd2daef25753f7b0bdedac301211f9fe7277670575273ca2877a13a10532cfeb3175e79331e3ae76971ea369510db2bfcdb04d19697d9580385bb80c10e8f73155f272cc12e62a63135e5c88d7d6d69c77b2e14b4127a475aba04cb2d9462f1710588a8c585a0e366015bf31dea0c7bf42c3861445822d9085d274bf2579e0f96c06715eb934a836f873ec0d202845f213deb9a30b66328b969c2f8a8b86208b84da79975fedf29202fc311b450b85267a0ad6312a6adf9ca20b811420da87300f5e5be8e5c591459f41b9572194933e91e081d4dde5eba5751ffea79f59cba366af981673e8c2bf4e86975e685a27c56b9d41ab23bed863dea803897e3b99cd3aef06dc1946760f697d29170c18126228892e24702e8b2286535bc27edcc627ad9da5a9b669f64a07a8cbaaa29de605b8f165cf88b5a1a777c6b448a484e62e530c54026cf9708dc982a1878636baa5dfe673b4ab627d54c36b545a73cca80cd8f53c15a935895acd679beb6c186189acfebb21ad41e557ebe8be0eb7fec57e7cbf2ebf1cde609da9eff783fdf3c95fe4b44f62ae3590387748e8346b342b8d27eb172c01be61d002194e50e72629892c513805f8534a09aca1be66c897232ab90e81811a2abe7602e4f9292822bc3fd77048e17766abb30769ed1de810771ac45cd50c1e7677f0438c8528841bbb9b05c376b32cdccdb2ebe266c13b0cd0214027ed5d1a5bebfb8aadcb61cfce1660ec97ba20af381f044111169ac501c2329e9f20ac9228939dbe550dfdf3efd5d2a5e022142864c7edab77408ebb64a20c090266eae6912cae086685fe58307bdf96ca9577d2f7834ae9e4ebbe1cfa89d704a9bb024ae92242e6d230ae2017a35140a8f882c2199bc2212d1f1d47053ef79420bf21371f6bf3c05c9085ab5378871f4be519171b9c2645e0a0dd4956bce39848fa9ef3947b09c6bd3c863e9e7e52253c257be9931ea827ea7a0fa4bec87a447662978b6c841b75290a432ce41c9133f705b106876ac764c602b512bc868a86f80008e1144b0d98e2793303d816ef537b85b68180b803d20f93292502fdf659d84042b5854af58feb70bf5c86e7275f222fa7c68aa29df9157eeffc59c10cc91d4b906da853dd950c6ace006500de08fe3bc3d61cdac1fa2c87f690a9aadbe0ba05a824612ee33d6ea6317bb5df8d7a603524a6c1edce456ba48e48c45aa7b8615528c0fb72994b581de155cfa8c24ecf34a0b0bd9819075b607bee0e6e7511c8144d3863e1a01ae545a660991ef3e55a371851677a9e61402b15a64c35d0cb9911419abbaee049c140cb55c87e089002af5930ab4accffc926cd9518d9f34ebf0b0b593204f504ee613141785ae27c887457c5e45d883301e011bb5551a586a3133d82da1ccba46d48a5be2d4393723adae1a4437bf967d168bafd8f5849e856844c45f14119aaad75882009e382614103c0a919cb411ec641fbf366c8047f0565c138e5f3871a9a2a5c5a4a70d522fd38e1429396f13187f034030611fc436dcde01593cfe534816b482fa5945f0a473fe8811ee8077a0b104c5f7c855ae9d1f302e426bacded1a6205ce49508550e5c3ca2618967344713d13ca59233a2514201290f934f880325d6ef1f46a858830d795015638dae6075bf7db9570dbda4807d853279c6b49ef5aa2228c93411df1133914583202224936e8fbeb895e951d45207c43174eeefa54d970e69a4a08a1442ba22925722201b0a3fdb446550507e299497b3f9f5e964cc31b3d658296b39361bd87d6b926381334b1789ab1c4e7a40871aafcc47be8728d0e8b08eeaa0bce926a1c3d2b06f2d9531eeeb3c180344f503894d8d2d52b5a2ad65c1fb98ad41b8e50e0eed7e77c4fbb279019c1d46735737c62e02f57b683ee2f4c112eca5d2ddbb93834fc7a70b61a4276187db387aa3405c1f603057a710454bf7ea920c47c18bfe34a2a0ecddedfeb23ca0ee3e7f9b3a48aead9999f8350a8cb0235ca682854f809c0f72e04bf5211f85d57ab1083fc70604b57a1c27c6c2e7080e2d74b57714ba658316c784bfed8946e92d5ae564fc5df79b17a34e25a679f7fbd32f3827c414a5b05fc62e13b54a0ebd3a35046f114c8e6d5133a2f1608437a923d1110c14a30830191d926674d4cff8a1addf4009b37b13f5b89bab1f12fc9b5257b792d37cfdad194caed1aa006e599d4ae45b92c4be896099d622248c82f0ff58c9fc5a4179ccc727054cb29ea93e79d578a652b6fd78cf4599e0a445c098387acdc668b30c922c2684ad75d39a190a6ced50e1764b7532a70d0bad2018dbf120a8c7ce90d0c14cfcc13e02a0db46146cc61ca76e71708d9d2413ea0c60ebee7bc07f0628d8a6d620b82c0affb4d4da05c5c7b562f119c6d4b3caeb63ad6a7b4a101361e6df3d2dd6cdc9e292b829e20553fd17c2bd224954977d84b635d136b396d61e6a0cc5ddcf5ba08e6ac9ffadf845916bf0e77dd9c85a3de8b3e672e1b8a3d3cb15224706387bf1f2d8f410ce7c1462c9dc2e08c53505d6538c5a155d1bb9c7011546b7ca73914557487d36e820a26f441325374a8c2de2625037f1109500fc2c1886e7a8ab70eff11edfa14f73aa523cab3295e75235aa7362d9770e04614fb48e1ae8e687b535e1422077444f14c0a5e27ef886a5d0a6e24a4431d53a5a116181851b15913950f3b3cd24b514b700dd42acc871323ce759b6344a58deb6dc573237a935e6f7be01b51d6d48e5b84c188762671dca20d46f431ade3166131a291e98e5b44cb110d4c77dc225a8c68609ae31659a4eda8432a6e508ce83801c7693b487f21e0038f8bbc8c1001600f58a8b881fe903fe4dffc917fe757f9437ec83ff2dffa267f931c2ca404fcc714f0ed6244af2ffd1dd471ce97d6a25eff794083bd41d6816b7597b6f19dfd3ef18ed86c1b259759d7df630ff9ab24ec86ec293829a9fe02fbc8ef93a09bb2af702b29b7df8dbf32e9be2a70f4c80af809b0176456dbf2cbadffdbbba7e8aba4ba43ec239d9484dd827d05ef93dc4ddf477023a9bacf465879a98622627bd43ae407b1377c16dbb04badd5edbdf7e16b52f543ed2b9e900467a17dc6ef92cc4fdd77be99f4de9f465e99b24a14b75a1402f840db9b3abbedd7cbd6d5eeb5aff84552dca1f6199e48aa76a17dc57749eb4eef27bc9df456f43e2656f439055af24c567e1ee756fb1e262a94a1d17e187fa04b97b612a7ed23d446ccd868d5660296ccda9cac72697ea5c69eaeefea5f1a266a15b1a770ac4f82857af5e9a0cdbcf3b97caeb661c22c3775b7402d78e87f0c7b4d1a381fc1b0fad3ca3b6d5028708588495dee535d93ae2edab30d2b50fefebd4e055c6f6d8cbda8f0f6fcbd9c3045f157cbbad6f87b954ca38795e9135920eac8d268c30e2fd17bbaa4af98b19346ca53e1adf825a214322c2f06d8b2a7f6e91d31ce310bb43d5cd6195847a25fcb66f0fa086cd5aeb7a0a8816fd7205b0543e9de8901b1a554774ea91f7e533694253d4ee5eddfc92d9a9bd8abdb0f7a8c646d2adc9ba9b8287a68dc646d2adc0f25c11664d49f096fdce8dcc0a0ce7652ea9f0b45822d88091d1ad75f280d6ec39ea84fc1ee889e8185ffa892125a8c39b7c7c1e72479416d0808e5089e5c6ed0bbe135d1f6c1d81ba6581f8817064cac6cb6f3efac2687837d075dc1c3c4b2568d8e317bc6a4feaca33106c3a9f6b9374b8efd18398243b269a041a87934af45c634e182c53fe6cde7a89c7f72f8bb0f57c26da42a9d1d4a691934c28bca0dfa955c9beb7b6c669c9bd87fd014dc286b9c8f8f29e16ec07ca20af9253f28b143a3eed3601ba108fca2b0eabab33de03acaf46c3e62eaac2ef515ae6b53ca329564e8696a5789e557236c876988572bda26dae319c41b0e18fd6f4501a89a1fce6f33104988f575be0705e2bd5e38dec1e1e2c3040c6d8f64e1530b6e9e5750d5dd976a1ae4b7486f3b4a2cc0c1e9337b6e1a5f0b20a39e4c16d00b7421a4db01820e998472501457548603f5cba7c91f841b046ba4f5030aa4da6b539c03980c70ce011912c8f7e95d0537272595b2b0bcb79137cade610252e0342a58681459653e8b87472bfe27e9de5701c828209309e885241c623fe48aa0653fd029e1e5fd902b14e59810a94914f11140e4c95390fd886fc2428a8485773e9c24c19719f64372a006f1c1e86da5f57d1673308fef38702443c022004745766b77b21132c63ce4d50332a4c9c8027afb172aeabe27e84424123c7511a6224cd0b815cd7940d80e815e403facc95b78b1b0709c070c68391537cdc69d05ee446e6a0f044890efae70344d62dbc5d98c1e4e00413203da2188d504b48bf54cde6956016125496500dd70171402d0174d2573554a06556d944671a2314f4c9374ee887eec27a70e3aa662fc217c37079cf7d7c622fdcc214018ae0ac0b421a867003e041f4ae6d85152bad497853672ade06e647ea68052f910a68800e8f6da3722e7b024685a5a4b172a691f6229512da032364bbe776890f0d05ee0c82eb3c8b3319d12e8210586d141e888213786994c1515d778686359d26b4892680cb80d69a1e71d0fdc32331ee41a04521df427681cc842a8283fabf8c4db0f5faf3096919c40b5548e5fe40c779d1630268b1842028c3034094ee201431722bfa4172f9ca717f2c7568a2f129ff5a13db5d8eaeac443c33c8127cef26068d930e86179cab0ea4113c107ed61c0c9d7efa12c2fcca4827c10f71d0ae280ee4685bcb68b68947faa7c443b082d71ca3eddc2112b1d7ce0df80c0d694d7983bbbcf4caf07e8a88068345918bf58aca86a6d7a400194d781e39bbf90e938cfb99a36b010011999016316760b0b0a558d1b462488eeb080cb205bd29839aaa8b586471f625750eb2d8ea2d89fd599202268e63d411df9b4852b241bd5d20afdecfb15f7a0c366757b322e04817ce554fbb0a926129fb641b1b8f0628f86107ffd916e92f0a1063f40abeea8b1b71058593e096e98b67c8bd8385ab14a40a45feb4e0bbd43f1093e8dba8063abc9bc1b998eb570d6dfc00f9b876a656729cb44ab69ddae83c537d788c64cb1c4b97928829db14347d567d8866331059d95da657d302d168013f45ea17f202777ede95a6e5af97918e152580ac31ef1534933452b8592079826a9d3c16c91927ca6a4648e88119ebaec6b8c879cc54a0d4616da38a5715898497ec297f31655c11d2ec28d0fcdf1ccac9c6a3513b44f0558e3289d7afc15fc30f399624a4efe7fd4ce890d686d9fcde591caa6441b892ab5c32be74e07b6faf80711b679dd6107ea14974df183926f345bc9464fc58533fae3047c6e37026b0d13baf028e93304007154fe1258439619e6059dd71e2012d7b72dfb443c24f7ef9bd829bc0cc887a44a54ff774cf731d2901cfdf1b4cc76852625e1fdcdd8100d2218f441f56faba289fa57197025b0240df3a3917c140834b9f9abc1d524068490ab8a115143a86640564b66017da65e2760152c0e6f99f9b4c9bfa03f1ca26d3305e58569704194356aa357204e28401d311665e520f733b6910284bee90255a486d4489b7f3813cca6d9cf06460d9b074e9eb361f3b503e4ea09e984378d2d47820cbcdc71cde5ccb4f0005c24256d27d6b981f59c9b45a2833691ff67cf10c3b35bf618ec8f26696ec37326121aca251d96c1492fe5fe28065c718fcd21e6a036381918ae8e82e72e4dab28617a49c052c2104da862fe39537a0db5ef069cb4b15e93a1bc847def15bb933142fd5ecc030152510fc9ad3bc7c6eb2304ac31e88869862914338837011d27e2d9c845db399708a9ec9f7bea6879c249b60e017d0707d609be6fd687d770264e1008162febc1e2b00a04c87f6f61b6fdc87522dd11e7f33dcdab0b469e9491c9e6509d294441533e027af92553badf8f1acb7e1e035d3ede3e51addba3ebb309dc310566ce0287bec08e65e0ed3570481cd8fd0ebc571487b6ebc631264e04898d60c49c0f71ac83d8517f78c31e0e1bb861f65554e7edaaeb95100956dd8a7fd37cbbbc3c8c5641240f72a1aa4b8d49894e686c5d6a47a88e94b3a0b80022cbba2c3c49f099833e85e253dcf634f1ee20875b12a8c12b30626447f319407cb100c200e2e5a55c69ab9d45a10474630fd1e098c0881733704cb0a361fd11bf89437218ea92fdfe56f53103a95cf1d39c88d345b7d6f05b856d6aaf3ca805dc74ab0dff4a03b8d1fcbf1132f453a17ade0f185503bd1536e46bfb9251ef16046bed9b9c1d9e4a03249e086241732000c175a85a81295d182cab00268a6a4263e8b792fe5eb3de0cbd72482875a0348b283c5bc9bdb359b77795769bb5d547c8fca5def271845b7db0b42d6fb93eb512217e441a58bb0a9acae93304e270e1c2e22e2feaa504af5773289bc4e5e8432386dcec8fe0d3491974e2c47a4e16cfc54daac257ec5d5613f42cd6f22d5257ae71f70126a5ee4252bd204515512a1a8a33287ff1127fad694d11fb587ebee0a1d817bfa27561ec5b41d0863cf6393054c8a307286edd3be52739a3d40aa0426688381693fa3a369de220ee0d5caef69f44f7eae985b3e6bd14cb39147f4aac03e1a2c655c205690e304b768b8076e4d21049699b72830c2de79e13394a7f3d527448ff79c49d468244f6a6353960105ba4b6995cacb6cf589248b5578e15f4ad8660e83bab75834f76537e9ea869f3151ba86d1e1907ba648ae9b22ddae3b9aa156e2d6473c070f02894002f7f182a17824f812dea1036ef98c0894d657a7423098dfa562074b43f54f4011b87f742d8b35bf9eb03c6faa4e3ae572aa03e4a4ffe515b1b5add5e6a177c91eec0b3ec826e53e421a65936d2fa00f4a2d9852dd6858b50fc5f2461d5dffd92601262233c28794fcd28f80ab1e3502cf8712a700305e78b12618322daa022306381f6e646f97980de75d8c05f543b2be5e3c30b611b685c3be8ce61b795c9fa16443ff20534c22f75b304ae443fa0af6b764773d9d4c9b12a73942a691575446c2baaec2574fa92286800ca51724881b16ca729544fc9a2528e10135046ec36c1c1cf1851f2100143e5e65c71d24d4c2600cce54c9b32f6d4cc6de9e186c62f187ad9715a48a373d5c56c98fbeeae9c6e627ad5bc5443951bc4eac5e2cca86b8da0cd8c13bdb4a3b82f2327f4c1557240e5411628d432943eee295a76000e7ec5e42c54cca1351b639c7e1af6041a062bd62a2462049767204761fd00d27727ebc7796003e5d04fc2a29d2ae241cf27847aabc7c635a228ee1b4cf8a43bd74de5a6148195d475e89aa34ca317bb0e7b9d2066f58e323d204d8d967831e78e0146502a70a32715882903e4a89202eede188872313b2112097732d28f0100ab2fb4497aa24b95da80c101894e6f43443e5850d20bd16420f8be2d7368a90c965994284bca44097340236b5729603ae08b207c998537bfbca3067a8d44bcd783008f1b1c2412039196181c9fb2b5aaa411896fcb442d4eb47e3a0dc288a067503ff5057c4881a70d9e840a4055d1f424e64e9f8af2e1eb6876a047feffbb5b3622166f73714dec1667946f7da696575dba26d307b068cadae700152899ee9680530ca91fc6b59477d1a2da480f02c8b0f6be0bd96c416c143d30317b6046e50e74fd58aa0c67b1df2292c36043625e7f8fc8eb9da0e1fde0472f5f8605cce051568f9adc30453f6a061fb678fd71867b41e3f6c8d431b3a80680484207dcd10382405db8c4c2025d4fcec9fdf6378f6b92e75af007f39f0defc87915753e1923282600999ce3cb0ae4e10254b1e9fd068c170aa2efa110dd1268bf3413ec8f5d248fcf9b3df5e608f47dc1fc4d81495e29fb658ab9ecebfe44138524615582015d2b5fcb09dc84d664e97fa9248850fd7019c0bb68a270ed084e5f903e69c8aaa9f25fd69b3ec9e08372fffd125ea25cf7721932a26095fd1aaf5ad8ff3c43004cdc7487325ed96e6ff7e25e4d20a352a02417446bebfc83635ef458b27bf9d41118dc1b85e928b809ad61392be59846d72cb2a9f37c58bad18bdced92deb7da36ce1d32d76cfd61635949c122f3a06da9a4c9288b7c9f64e8eb181bbe7ce24f5ad13527a4f70f235424309c5198b50de47aca53dc010d7bc8681b265f643b17eb8017ef2a219f360c93831d99673d535205f25f184f81d12d0d98f84dca24f52488c1083f6b90421296b1b5f225bd9f79f22c32714d88a5217d46b8ce985cb64b7b0140bdd04fa11bce6be34db32f7c49fd5fb7c6533d2dfb3af05f57e8fbc295e4f4481497051d8959a3480671062582af891b5c750ab7725403437efa7c3396d7be5d5b54d50628cf58cbcf694644627ed8014c836ea335d9823aeb6f31740c8d16ae3010c7fb9df94be419bf8f512e4149832b4db0579f58fb6a605d58b917fe4154431d5e06474044945b485061c090503e16f8134151e190275c8522a4ea08d6576d9eefda2cc9a9a03a643d1ddd386edb018aaaa9aab48ea525182e42a7f266f56b6328f23e06d1690c85f50d2b976b502c78389f824ebab6e5a01087e9ba8269b6acdb05134657b280ecd285f1a6226437cc83c7da0f63dc183b3c61092ac1d9459ca5e86389013fcb14f09c546322c09f0784c1351c9f0ed90297d1731deaa72614fc6ab5889d0225f0ee347f327807e071c02be6a09dff56d6d1164a061c8196fec2ce6fe8ee83bd88e681db2d9f0933a897627f481e22a7cefd6814af00cc0fae499f1fa656891ff49ce5a088c17290a297bc8e8630ca8883c4b0755c9472cf14c788a2a6ef23b4a4dae70b0068c5a3540c3be83a0a4e2a8e80e76d4cf7672b3ccf2568f4b438d9b360309d3933d7aaee39dbfead91359a5ab743e1b54982657c21e94436854410fd2870e60ce0f00552827a7a0dd4712ea45ab8a127f1d48de09eb6fb56f1b56f10fb22fac75920e75b1c2c6291606cbe7682df89296482b7cb1a277449a894bcfbc5c639eb46b9ef01eddc8a91befc22d08cee896b81537ce33cd5b77448ccdb25daf961612028d6f931b61622c4f802f7d37a3ebc53b7ff8f98b19688d1ecb58a2a94a13ccfae882fa94beeb04a7979f39841d3fbadda78360c79412562498a260aa08a09a22728d80e80922e294eea3d99c87377a755bf17c3dbe4989a809c324f102fce93c2648bd129552745bf3a7c3a686e48e5568f2670da171b16f18f3f51411445b060ac8a20a6ccdd9e8488b3fb0e03882c1d782bed34005ab27336dd20001528a8b81e03d3db6da54e3bf5dec1ccfa0251446d71893297c6369a9ae1df27c9ca260d9abbdb0b05809dd1846202b52eb22ef04cc8ec6de806d8f40051d6e4b6b008df2430e66097ae597e4d498dfce530d295ee556dc1c495ae19ad5e03c1dd08d9720fa560ce8fa5d7fc50f63cdadefb793c62027e16972cb0aa0c650841dffe10b5b457b9963bc7e62f2cbacdbb19600459fae136ea021c53c82cc018cea73fa783a203f8b84775e4caafb7d7e6d87eb91004ddab24bec7b78d593ea12964d86d582d4d960dd55daa82f10dd4a0d7048b529a190ffef49945b482ff6a6a48d197acbc33b13da072f041f5b4d02b6bff8362b2643924f278dba99ac415a294c4e9fb084d3a7ad36ef8266ff9d31d97ab4fc6482dbc8bd3327bd0fdee7169efb6e9f5f4405372722afa3315f4c5c27f4aa58ae14bbb8c38c3fb2d7e2536c255215356642908de9b11eb0a9949eafca866a1d19f30b5dcac07c84bcecf44882a9468b3b79eacde59b3574e17f3dea3d2258aa74c1698bdf9e47ed963614b1e3a7eb8131621982fb2995f537a25fd2332eb1566175cb3b71c1b4880d870a9666f9674c023c30b72f7487d27f32469943ca6ee02c757e6073362df625eb68836b84e42f78abb173a2aaae2eadb62b5beeb1b36e7175950521a65dfa03156ac8aa3ef10006dc490ee48bffb0550b9104c98cba1741c7d1f1d6ee609814678f42d016402bb45eb6c1e69b9172394c849720d4dddbf1df18859b1ddc76f822e88f19afc6d69df2d736c39ebde5218574780ab99c6d51fe5aac8e10a64ba6af2bb2a573d4166cbf5a75834be4f3852e002c295cd9fc8564a594b93b4b892199d362b969c41921c739074ac48c20864c4578e90a2849c90f0448cbb5643ae0fb2120ca4470831289260f0620cbfbbc8d7948151d488f163478c14710c1429c7a3b6754805def36d9cad833eb1851255e1fbbc735d85f16bbb783a4b00ae2e7dc793b27ede21813be66665c4f874b8768f8418e2d96defdb143260a2cccb0448c85a94771f82b2382d93b8267b28e56f43245270b03ea063930b8fc69e2d83f2b353c45ef11dda6d35e1cc9e96cd47d1b29b5705b3ab89ccfbe08242a2659b87c9421cca7098045577f4e310870cbca8db21b8098b7c8fe9c2a88a402ae9f3727336f8df12f72defb40506bc394157437a575f84ab22872bcce0aacfe74aa4703d5c79a24cec8b73350110cff046600f5f31fac1e7a73c9d484c35c04d1170d2df7b459c3d35c05b043143def045a82907aa18214dcdc9cdeefeec4d845365b430812e9f1a699f0cacdcc8204183e70884cb1869480e6ef5eb2187ce731e9df67ab004ef879cd323768e9a9cd66c204da2667054f36968ee2cba9ae9d2ac6168ca3525c50b229def43cadc1e85734d0a2ccfad3de341c07efeed3c1fdb4a8927e46d23f9ffb85117787353f5079d95534b7d8cd808a8231bda82172b6f858f90cd53c014c342181cf8c862ce9b1306b04f644918229332f11101fb57783ff81057602c2f26c14c83ac194f881b7031d8c6d2e87a65725bca65828cb7ae1d4c527798ba45c08d0bd2a2172a9ff624d13a06f5b386eeb21a6ed02063603859e4767bf766242f3496a538d22c4a6466b1ecbba6287b3532f52722bd9f67bd0c25210bab50fcb6350c0bf633d1f9a7511b32860bc7c4355280d2600344464de81dd48614d05b316bb8e47cea06c074ca867c166800e5586af702c0c4c4d82bcf0c455f76845a7f3d422bac4995dba9495603638483326b3b47014d43e3cc48a857961c57f9637ec6b746ab638e6e00234b6359bc7ef1fc81a4e842034c9d3ca809546adc05a00222614611fad4c89ce71af63e28c0a950a73b9857d8935fe6f434cd605a1624970e5026c883eae80c87694dd06f1d6030836ee758d7ad8ff90f21b0c0ed7887c11e7df3fa2b2957607a5949489330c4aac42215109625ec7e48a4b0a49f6a33d395882ff2e708216f0f1259893812d1aa02da5542fe8d879e4a0275288ba78448e4b3704e979281cd1f4c918f99d71949d4bd3793c8c64c421368a037a11259aca749d223b6e94cc581219e79b89d22fdb763ea98951e69864d3ab0fd0903fd045dc60c8d2634ef0b93c45543d6218fbc12c8303b497fe0a0702afae46aa2a70bbca0aef894c8929c3c5bb1cd5722e10609031410ffa0bccf887b64cb2e7adb27c78e5ea028355c8887954275e0644b36522617deb848c744548764cd4e8d2824223f182886ca8d023003317488a76b0535d0742aafa787e0b71130d95a4d67e522463ca85fc020db70270b68eb40530e717ea61050ad136b6098f31e411cd8d9fbe1783858c2ae6948e38c549c2e954cd7a8e7c6b47580540899bf77672e5e918a154b5b2fca8382f308989875035adcf0514c7ec0a91d843d3e9d5606e110748d36eb08845226b4005f4c12434132682bc893a52e6690576f6e142763d077318b68cad3f37c881c934fcdfb6791c434c48503c390805e153ecdabc5df11a368d4ee6f71b8130487a33709091776e61b6ef8c40dff1e9b814b3278c225c642d141a2ebff7dfd4b322b691d0113a02840b451199e5ca9d66bcc7cef8eb632d6a5e9c3681664ddab7fb81917d3ac7dc62ccdd2135527b40f1cb10fe0697afd0b89c08c0117a138b4dbbdbb414e44c3d0bfd48acfc24f4311e70a4c363405f20274a2c45e5d30bc44ba72f36850a3281e182f8cd18b88ddd32f2ec588818e5786b9c86cb651c9b14004db270c2c1a164c04da0801b5e87026526e3b4b73bca4e13eed0378e7a2026368700d5aad19a347be51ed02618910adf2d264a481c28f8d4d2ecb30681f16a015992beb2591f97913dc830041b628483fa490ad505dc53c28b80a75a3b542c40e92eaeb3f8205d69e8cee6c9be8fc9bbecb068a8eec4c5a94bdf46dfd2d049f3de33d077348ff6479d634e740a6cfbef8d3ce98135feff96076ac0a7d4f99d94041b3b132f28219f5f4c5d3bafb9bf20299ca88220d381b21b138f49f026a23aa689de73f0382bc8389f4b8b88a655290d4b5e0f3a48e4e790d47d601c5fa62176b3f4c7a7d1cce76adc18358136fd809597056fca0153dcc45b74201c481ce64da0cfaa8dc5cbb6d5ce785a2492bb44a2dfce18141d34af0b6a55168f73017dc4b93446c199f35363ebb59809d99c7d4e1608b3b7766dbb243bdd562afd48b777135aa735cdc37720201a09463e01d42af4c8779ce269037de70009d599fdfbc98f8d6928cd9307e225218380496ed13b621ae7508d1925eaa5546b2eb9e24f4da9b940734ecf03bb50038829fc4c600649d3ed2da189494bcdd4ac9df140ffe48c078edb83a092430b51b1874fed672fcf566534bc90d9f4d01a81b150029f7a2cf63ab616067542e580183389d21d7b98f29a46c0f8c09f376b6c30e43af5c6552006ab5ddbb2332ac9592c99c5e581b53585bed75c07812a8ef23742bbc2f706ccf8b5fe770ec11fa62a4607df62105ddcf011d27e717e0ef76c0ecca8b5026239c1e1ebf91237aa6ee4b55b0160dd00c68742ea1fc5bb8336c2b3af5b0a8d26d477aee0cff96a9738bcdad3aab86d07916209152c0e6d1fad3e53b15b0b8d076633a63a9eb21ab4e78b41e2ceba68f19a050312333b4ac9be22570e91892b2ac5ff2f112eb272f95353fc823a034d263f052ffb1e2fc361865b10840056d97365ff343ee8ad8361b8424d695889df3d168aa1adc4e343b60fe1cf8553dad72d5500c85b6300ebbc68883391ebcc8b4f2d051bc619c103271cf32841d06162b9d1066dccf690a988d129918e1880fab82a3f8864aa43e82e1605d72ef81f9c56fe4e8fedae6b91d5a272ed4c0216c36042cbb318d05ee7cf65d554d4a469be76ddb2915159742918f1a83d03260bfb3244fb4bdb3d80ebd600f6307f431a6af6a81b446aaaba9dfcfc9ec37b471c61303034b59529dc38910440f023ab0b55d55102869d5e6002099c70baf6d98ad96700030891dddf39e09e407c6b667d0781a625d5104780365ee950bbf3f4bd2f49269f6dfc4a66b4da1e5158f59f2ef46c9f6f8fb2b859aba28f435ec86d6c85e207b656f29539c05be05d7053973fda99d656dc643eb759f387098412bd7a9341a4d8f39736d3ad241403973d5292ad474aae569e24cae4b8dea54a1152d6b349a2ef55a961bc7d1d42c4f1dd256359ae6cc55973a5d7599541ea53a5d356defdb8c46d3aab993521b3953358dd8a0d1cc33b79aa70ea7f7be6952ef7d9b9d657a4385ecdbdeb7d93ef70eb2f72d67ae3bc88d820906cca21174b3d96ada74254f894675737d963ab4c4a536bdd512c7cd209adeb794ebad964d3b692db7096b692a917ae4e759ea7692d1d0918e5b112767ae56305941543362c5aa270a3d5ff4e4c817fe7fd48342ce34d2a3617a7c46bef72d671afdc83325d400b30805203435d735454b756bfea35113c93cda48b67d12ed5a992b1a9b7e8c68aa9a358d9a9ca934026a3af75a9ab68dc3993fab2e571bd58d5bb706fad149351d4e2fa5280c41cd15c62025355d5a37cab76adbea924eb90ea2e95b9a53aa95479aef14c9866e8da63acde952072195da0aad5912021a4da3268db6575d0e97d678ce5cd7bd83f031c9058da63fd46d4b8786f86996eb06d24307edc8412457e2f4b9d58d630a04bc4653edc366cea680fd9d23eebc09eae1ff750fbb334207de8c30ea18730809dda1a00353fcc8b7aa772ead718d9a33a5722f2995db85a2da36323434ab6d22bc5c4b2039d368e526b7951b051b6aa6d0e483af6a9a439752348516d65d441aade9c9937899c4f7d16c69a3524491c493444b9b85512df59adb4aebcd54818ceacaf7d191e6a63e7342f4b8de4cd5a683e8b58790060a4ae26552d08f1e399a6a3548061a126aa23a95880f0d21d162d0dcd437dbde6bb99640fc672dcfa475295591741a2d6bb6dd8496e759de5633d70290168cf4d874eed544cddb52aa2235a92bba8390d0f4e41d6cb54c511d34eed1d441fc3ccb9597fa66da36aa5b73e64e576d8ff8ff210f73a2da496bad54b7fe402db9ba02d9e483fc910651f79a9e446b9a0ed93bc85e9b7c70beea88d49448c852aad6b8097cef20362e0415b2cf9ca91a316d16f8de417ef0353d8b842ca52cf0a2245ea2f0c10012901af18d5422a1e5109b10a6cd825aae45a56a02ba5558d18d4b57181a325a4ad13a51368753e7e79feb66d8bcc78ea623add650f34d134b7cd3397234d5a5b6d5d441a5aa23b59a06d123d7a5de6abaa49bce73f334a9a6555d0a831e39d7ada55ae672a5be71e366da3437d57269fb28c13481e8f1c8b667d024aca03d405394abe3baf9ec8331041d630e324cc03043828e96ff1f978af69a120962a393f4fcc6c3e8e45882ceff8f4da7492ea166dc7c476d13e9d1634d89ec604a7dec353532ebd16368c8680753ea03841074e96cf6ff1e3c6cce95394973e6e4d48812482841e64719684a408d32d08a50219ca95c0188a9c4fd707513996a7ae3eaceed3535a253f83102d194687a0ba5b95caa79a983ca1fad6d9b96024deb8d338d4c18819ad61c6ed36a5a48eba0fd685a8da6d5bd6e5ca99639ddb49aaaee6869ab3a24f3661a31d5f5348bf4c8f711d19a9e45a38e1c5ba7a66b899ab814356d6ba96e9c2ea7dbb825ad4bcd4b35c704c4cf33a8d468fac3d7f4e4eb2dd54b290a7a2cd5dda46e21ba544d50aa99ea51aa4b759f4726e769aee95c79790a1991825053076d9cb9a26913caf9a9e3bb86a6eb2e5ad333a7d7341da2d554eb26ae1b9212a9e5cd0810df7addfc27a7ee352502b4cfda8f4e73b86da447dbaea126d75c8f7abcd5ca1d54aea5cd884d4d6bb734cd71ad9a4d5b497375e3d4f2a66d7bddbc547791d6a5bad3558f5c4d6f7ae41a0935f5909448f3adcff2283d4fd0e30f7d9a2baad339d672d7d07dbbb500842cb29940fe30a20db81ab1a644be376286bab96ea3a94d0721e98ef48f0b85080f2bc28d16da6aae88a82268ff988a22f4d3d6f42c5a7fd0e298f9ff51083571aca6aeed227b08bed2d9f4ba39f9d86210f0511c19ff8f592082079c4ed11f45b8032250b895ff38c3c1808787b30706c703ff7fb4a201d686df5f6b59fc7f9eca3b7c30fe8613cc80680860276110e3b6ea686870c17fa0011661c60dd87f00800932908063a0276071e38745077a820b64d82a781db3f4bc80821a237ca023030cfe031b46d0fdc9781db3cd2f883163da013082ee4f82d7310321841953bab4ce90503389974934720634b29dfb2c3212a70f230169ef84040912244e4e4e3e16d09c6c0c27249f53a63d12244e9786c422417241da23b94e2212eb6469482c1227ebe40486ef04d2905827a7eb7469ef6469383e281c2f3fb5e98a74d00e353dcb1f43432dceb3b4992991a1a1d90cdd369b99343373e52cc7b9cd4c899c676a1b1a5ad16d44eb8da6668edcfb364bd719bacf954967e6c85d43531646a052a9fcd9ba1974baee24a371347365911e77ae69f540f3a552e54d5b69b6d7919ba002f9a308dd6b5943d31a124a1be1b6ea68fb689babb9b5698469eba6adb437e7bab4692b693387e3e5d26cb64211e982d67c73cdf76cdc668e1cd59dcb95ea522984889ccdb69a13da6acecc91b3d234c2f96c368eb3d9989b8d3533478eabb9c4f9ae6d540b2122f5ac36e3e668db2a1f7134dacab46de96dc654e28a66dc04faa1e99b99dbb55aa9cd55737336ae4ca7eed6821e816c6a9934eed1fce13733889f667903e265cd56a66a8afee4ceb3e49a8f7c8fe6799a388d9a668ee435cd67b39999235d68613473a556b7929a2ecd6eb79497ab16badd523d6eddd6cda0d57d53d3db6c444d7ea6294e4d6feace959cb672d42c914a5d6b4a579b46d5729f699a4b5a378e88665af56a9e25aabbd1341f9bd4d2c8096312375133881ed714d56aaacd8d4b6bab2ed5a3e6b491a675e95169434d19689c1683de3c017a54836cdba48db6bdd1223357d2b69afe6880b9c7adead63d44db39a94dc78bb69aae449a56f3840470de82ed32d3f56f23f06fcd70fddb2dad5805335ef782d50e6188629c69238294185a88c2448bd7ffdb261ca801a4e21d63fedfcab193e5cb0f1cc7e9ff6d8d9443018247032cff6f83900085b4444b14fdbf2d42430819feb9a289ffb74d0861c3922e5c1440f4ff5705134ac840930e9a54f1ff1f0550e24861e58a9711ff1f62a192c77e0d8dc000ff7feb5081c3913d569a10e1ffc12c345187a4218a2cf1cf9b760a454343331b6aa6b0cfa3925cd1ad64aab0a6b652e94c89b692a942a99644ffcfe211f0310a66fc7fd6bff5e1df5e95e9e1df92d9fd5b2c7be5242484a6df149301fec762b4f92f85b69a1b23a63b118b61f4baf4118b2180580c19ff7ac856fa88c1c8b219fceb89c1182157e2c23489c100adc0d82f5e5e01fbdf56fd7f4e6fa899de50212b4f899256d305b5cbbfddc152e929cb45279120890e281e9405a03600b58392b25bb4c8b05230da8b2c78fe2d96ffdab5e0c260370b4b1bc5591c802e202888470f1e1a88c966feacb7adc2d010b585f5b655d05a6b74013468269b39db48b63d53aa956a58001661c67a7a3c7adcf689ddf0d8a13dd0e83e6733db997e4ac879504ac460e536cd838706fa41f739d6547e9443f7c033787c4c025b8aea29291d5ae8766eae79f0d0e346b26d28ff1fc3c75c00b1a5280c46427e9044e40fbd4333d9cc109ef6319f2cae8e387225eefbbf3540a9c3952c1c70a073681e328ddd60331c70a0793c5ee171098f2f0029007e8113008588b598b1aa295f400e2bff96002c5e88b1306201c2eb217369b3a0653a5df5f7844a2ce3f9cfbcb7c5f2959c7b6ecb28fc7f2cfffcc744dbcfc7c43636b43412ad3e26d6f046317184ff1109359bce9d64141365fc8f632ccc8a8534209bb6a9a5109aa2bc1c6d3bc9281672536b9208080be4901350cdb5919dc44b14b8ed7c822606d24cd47c2106caf8e745629f051d7cecdef97f0d3ef6bd897d53ffb1af015c1d63b7f7bf6fdb563b2a0b30820821100084017ca02347ec2ef97f221fbb3afe475a9ab44433cb5cd0de379d54338368a4cd1c39cf9937f3cce1cabd44a3e570ba235dea7523a5457a5cd1cd352d67aebcd4ea36934800f24093a06f680ff48fe6a173e63a5bf74902507932969e8a22269177192b63652b27669c5c8992d57062257e65ac8cf50ff3d19fb564ab2b329bb13256c692d98c6575d05372f4d49ea9291bf6646d813daf8a8d16125aee8fcfbf0532591537558aa862812a4cd82a64aa98a9c2abd2c68a75c4362211192b63d19c3e2437aed09ebcd35268d4b0f6f3cefa3c0d245b8406ccea177d1e095624cff8211e9737ba87cf6bd8f36ac8228b64f2d54891229fa7068a7cede27f832f0103ab7f033b44bfe8f3b0d71fe6a912aeceb4f8e67c723e254226e10d601bb008300e0804b8068fc0d2099b844fc224f80abc078b0034030e01beb9746e9b2b0428813b078403f640376196d00a0641b8247c0a6d08a78471422aa056e824ec0a8908bd4238160e574328210e61943087504a580564031271231042850f08a342256010600785f878f8be7c60be2edf0e9f95afca97c347e58bf241f9927c50df948fc917f52db954dc0fdc3bdb56bb1cb867ae9c6b817b81fbf579b9bd1bc4ed778aeb83f5e1665dac0bc5e6b1555810d80cd83a96099b84c5c02dc25ab156f601b60627240ea0c19c3140064be6a8a42d40012ed8303a728467c21a56a1200f92c239978afd1272e9421fc237219bb0ea42e0eac121c0555c23f09dab038ee256004371b560272e1e9c015c073771d1602570121889bb043ee232812b802f80e5600bdc2e3c072f81318099c014c05f5f15b6833580e9d82bf006f0137802d888ab042ee226718fc071ec1a1b042602c3f9b47c3a60097c5bf09bef090f81dd5c27d70a1cc48d729fb01accb34de008e01e3663e75c29780d6e833b16e236c140e01f701a8c067be133b8ebd680b9f016d6c259d8075ce656817bc064ae04f00e63611ef0151e83c5e030d80a83c15fb0175c85bbe01d3e294c85a730976b076fb96eb0162c85b3602c58077c055bc15530153c05e78071b83de028180a86007e829de026f806cc0447e12558094e82a1f013b6013f00d7005e018e001401b8070c016805a807cc03560182e04281548078c00f801e00a700ef801db85ca01460142007c027c00d8076400d804e80756e1cb0898bc3dd0231003201d2019700e75c325f986f673560a5b077ec146012e0053e1c400b5c2ff00830cd5701d00b74f27d7d6e3eaacf87efea1bf389b93f5c35f78a4fcaa7e482e0e6b94ddcddd5c075e266e0d6b96c3eab3b818bc4e57281c06c2e1117ce5d737937cd95ba5b6e16dbf54d5d33df958fcb7d72b1dc1bae072e931b75975c2537c9b5c18ab11fb01eb04fd80ed8282c07ec06ac9d0fcbcab14ad8252e05ec11b6025f960f8b656381b06a2ccffe60d1d82cbb83a56a62ba50e452f466e3f36108f18707414c534344f31c6763425ae186e8f5a378e63910bb369f31a547a8794334f34ce9d1aa4b6d885bcf6733756f206a6120663d0dd1876f2acfad6a2096799b69e648753795e71e2243ece17588649ecfd46de44cf94c48c47a2e82c8c3038957cf6d88629e67208679abd74004f332f1cb6f207a018058f533c42e3fa321eed07433d3db8c376d251e22d5ff88537f43e4f281b8e5670310b53c57f78a9a5a947a7566e6c8ada63f3010b33c961775f80e442b3fd36295a72152f91a620e2f13a5e010c5491326514b9440851d08a5406a80d22c5d6747e97954418f9817f1d9784d657d59300200038411001839268661e8f38563feac155fdc9868f31752105a6b7dbe308761f8d930671b86a1fdae0dc32ffceebd16bc611886d64784e1cf5a1c5a8bb1c518638badb59fb5f9b3a27d61ad7571eff7dd7f16f78590fd0701706d68ffc5fbf60befcd36c8662b5ad15e17f6b31ed81bd67e9fadc0dab7f6b3e1f77d5ff859fb819fb5409fb515843ff63f6bafb55786bd9ff89f0b6bc3cffedfbfdf67edbd17bcf67e07d6be7dfb7fffef1539b802f8bff7debfffcfe25efbffd7daef3f6beddfeffb2ef8fdffbda2f8857fef154316f77e14b8f82fb4e2dbeffbecbdd986e0bd1688e277ad6d11decf820d34b021b320cc395f50df9cc10ce60f6cd16206ecff7e61c8c2276cf1591b6b11fb175f0ddbc27ed65a0bb6f8bed0fa88a17d0180eff3f109c1fb36837b4111b401bdf7de7bef5df6a6f7de7befbdf7de7befbdd77bbd5eafd77bbddeebbdf7de7bbdd7bbec4defbdf7de7befbdf7de7befbdf7de7befbdd7ebbdd77befbdf7de7befbdf7de7befbdf7de7befbdf7de7befbdf7de7befbddeebbdf77a43f45eafd77bbddeebbdde656f7aefbdf7de7befbdf7de7befbdf7de7befbd5eefbdde7befbdf7de7befbdf7de7befbdf7de7befbdf7de7befbdf7de7baff77aefbdde10bdf77aeff537ffffffffefe6ffffffffffffdf4d9bdee229b41f1621fb788d1f0b41e21afe3f94811490cfe32901bb4b5e44f53431a29ebca278696048c16086c134f96a94e8216790af26caaa49c620088ad943c220414b829fb30cccf98b4d71d1e5e4d3e1f77d1a06049bab282b12cc61bd9ec79b52026a19e4f3785ff09730c90e1913904fc2908387441ef2794840f18e30e2a1b8928d119377564c15ec7947c401d51881bd1a3151c2486999f964c878a12581255ebc1feef8a4c1127c4561d08b97c41c9f3430176418aad1924386513ec210835e569f815d403eef8710902fc8e719412709171717571baead1fa6b8ca942953468bcb0c17171a24f27c76c8bb05b39f1d4c26df585599325a65b8d2589529a3a5f5bc345665ca68699529a3a5c5b5c5c5b5c5b5c5b5c5b5c5b5c5b5c5b5c5b5c5b5c5c5b5b5b5c5c5c5b5c5b5d5d595bbbaba72d7125812d8f3d054616982a64d9932b9ababab0b8d1525aa3c4fb0e769d9d1ca830362cb88225fea7cc103660a18a8ec034ecb0c3384a94386f9da12464a8379a3ad90d056505ba44881a9e2a2c566eb6aeaaa09316cc2e099ea016bf7c44e8a5605b4be785a57b8785bbc2da92d2f5c9515aeea8acacd10614819047892f120f8cc00b3fa5ff0aaa2c82279cb499523b0e7555d3912c3de139e9cc15e21c10bc570f14231b4951d3972e4488c183162e82b638318369460168a23478e1ce942a7cb1a2526198b49eeca5d543daa36507690a20aaa203ad51a2a2068a0a1cb1d1aa8ced02085062a292a3352a87e209f4785862a0bc7650a8c8b17972b1dc3eb00632eeecfdf9f22335e8d9a275206065c9eb6e4a1b2a3c4a3c05711dc799ea79214292a2bee13395c296e14403ca923ab61794eb461f39f15c30b6c628001c897f55ad890cfd352e5f3b21a9f7736867c660b4f0b1d185c9020e933c1c3427d6d6450e3ff34d64a9f06751892a17e1724199f8701e633c1df109ea7e58bbc2a3891f6055083f6285bfdffff67309fc36431da8b9cff7f998cc91713364ab29454c96a40457d45d589ca8a6213552593c99864c964ffffffff4abe94b0f9ff7f2b79c42f71cd2eefaad8d97df662b398283c4ca68870a2a64449652c6bede79db5f61fc73f0e9b778f43f66fffffffff1f078effffffbcfbc7812383c961b29887f93c0cbc3f40bca6fcff014438ffffffff38b497a81ba0b841ce0d6f9cdcb047fc12d764ac1636564b822c6c18b1a47dd26a90f7b559f18a9d7c756e087640f8212d99b5d5334899b5133cf91b1409c990133c6c86feb77967f3ce8a997421cbe44b70ad7e988fcd3b9b77f65fe45d3e93777957256365ac8c6593483d493d553d5d3d653d79d927364f6f9ebe9ee43cd57982e2098f6d22250585d49ebcb356fbe81d0220edf3c84ceec9437e74aeb649f0e42475a0ec9045bebcb34fae9e643df17ac2e6c99b275f4fe43ca963ab4c7521227ba162e7a9e4a921aa4a942a54ac7dd246e4809229e4f3a0be80708207cb152c5358acb09081229f97e42bc915e9f3322b4661f32eef7058205e5334b8c2e7f5972bcda44e0693c3643132994c26ab616dded9bcb3796781784de10a01fcfb739dd840e7ed8b70feff3f63e59d9531a9facf3babbd5851410515794745de99e1b5318004e2642c28d96730598c08275b2dc1b3644fc6b2d98b95ec258f7998a87f099b2575a0967cc9645e72551e93bf78c963ac8cc95db297ec258fc955f92a5f592b535207aa8e6cc99425594baaa094e091c91e16ea87b1d00f6ba13fef3256ee92bde4aaec2557652f794caeca57f9cada8c65f3cedacf3b2b93d578a828281080c013eb447c42ece29abccb5859ae885f6baad8d98953884ee45dde8954580992d8a814704f8741ea148d00000008808200f3150020402c140b8592305175c521ee14000559864864462e2a90c84381281c8e8340884118886100066100066218886251cda0ac04a0c14e4fc11d2e3ee5c35e4fc5dd8c3a49573d358a3439ca1b427503d6dc56cb8320f2bc6efed0d06b00069ceadde1bfb16b2926007f2c74f0101126e79f9ceec740cdb422db32ad83c7cdeea8765da0852217cfc7ea4014dda4e9725c8791b15a420e4f49851aaec51bc23533d20694fbbc1653671b15bcfde19c12909a0a905524de61f1692e6ca854bcfb9a8e5c120cf0caa3843f73a7a94c0205afbe03c6c7f572bf4bc9dc68a26bc7c6b90e8ea901c4452e6efedb6994e96bfbac4970550c9ceba09882e1275b08a11bb1166b221b08d1cd5813ac442c52e6a5901cfdb8387937ae08c8d175a715dc1dbbe60fbca7e3b4c7b2c6871acd3c143605c6c2542352d245e07b21fcf5745da67bcd6a55b6334c07c50b794ed8651cadece23afd9a9634392a193c1503070d1e3b061524ab7655c7f227262d7434369c6b509c92f5105b0851665cc36f18f9b9067016d6327fe01d5da54df95e7fc78c8bdbe57e9792b9d34247c7c6a90e82a9018445429cfcafd328d3d6f61953e0a8d838d7413125c343b610a29bb1266b20db10a21b0eb71a6841c45dde82ccf3bba9d0762797f35ae68cbbc2854e6c8f9fdd41114a01b54a0d782a5103e0f8205eac834311a4bd2f0cc97a392c3d7fdf0b80d47cbe2f40a9f3f94f90a5e70f2f54392351f04518d4fc48063e452bce45549d561d0f3e7867539560613fe565e6e71d52c6107bc2c7ca2b38e0e5214ce0f1798d3aa14cc82fb0b2d865c3ff4b442e0db77fcecefc874a33dbc6b9f5ebcebc5dc6241998a8419c18c7dd18580c7a17464248acd711cd662489d52f460e53ecb58e75428f84f18b9891b851dc205fb860920beed2aeb4f80fc315d51a0008224f71355617d7904cd678acf31c43450cc445526496282b0e7228167bead49d02188ae0a1c78e224f878a267a3d680d6aa2c77654ad436c7f829422a34fae56410c34d08a7f342f6f57b9a2e34d2790361df4fd4827df192a21caaa773080be6301f75990200dd098f8141c0a25820c559337184f1fb8290595ae8482bcc4fb8fd5f35dbaa2e14a6b403406c8f9e37a16b07e28f8192e584cad911080b008cbc8d2a6d00a6be1c8f078170b82d42cd8d882acb9b8f82451831f43e3d51954a0772d618384454cc8910fd90e35e1388fa8848879c85d8e57c5791a115cb8710f8bae67a9b838c906ce8c0f28e9ab39e84ed7d355258bacd0aee16ada79ee5e6e1c181d0ab37a1bcfa47559cc200db794f1c539904a3a5799a0b54b622d5eceafab4e9062460e16095c7e70484190b9ac41fe8f3c1bb552d0ba4793d0ef83202bd94c16d816f7b2f0c381961ea27b4471058f4be53c2613a23be524446710b5c44eb7da0400b5f338428567f7dd544c0fa2ae1330175006028b8714dfa50eac248be94c330a0510c3721f1dde78d35dfe923ea8b4511a3d58ebced29e7903e21585eff033a74f24dffdb791792e2be17147520b3d9369c414a12391e9598da5e04c9b03c846713c71d412d056df742196fdba96b8906d4ce503ed8da0bfd9e4851b563869c8d32fb8a1021826c8c0c20d2ac06002ffa45f7f60e2c471ee160db792a01f976f81f58743851fb07ce91f1110b695d4cec335fd6468640943ca2a6650a3b569750b3c005687ed6983e764d0ce833c28731828bfaabce5cf81d1ae7d7120c2f8804028b466843a22987606284d15cc2f883ac1be1424562040894a873b4e57d2c20e853789167960a18e2c582ee6ca4e8b7a3bae8e8001bd5f0f5db6f236fd7e4015810f7cbd9d9cedc56d8add483d1217f0ba3ebb5b0b1a94eda1620406f8797d74b040e11a0096df024d5cc9f9a18aa0283d38b806f298b161a93c2ea52888ea718012a3babb87e547c759166d8e43e6b41c07322f041c87e085d7654df3d7f2e6ce49e4da46ac33e8f32f7af686902c0d64037a115c64b0c83834b280add8e60820fbd8c92034d9c75e406181cd485b326ccb199032cf76e65b70e6702bc4e564d21f30bc49ba68a2060e57b2fc36fdaffded80d9ae157b1eaaa4e64a7f00c182ee126a8cbe25b2a97f3696089a593303655a85442717a456c71f1e185f65e2a2c8f09de7b1f26294841e9a65d987ce1b7192dc1872e68a7c02d5f6340c9ba6664b153945e7079a60c3d114d05d4224504548bb6ebd1880c468b19bb531cfa9be4e05f7b2bb4e4147b34ac51e6c23ff02b11b437838ac0e53d07cb26b2f9fa11adeb2264aabaf1808cec9cd2aeac7c808f22af7afa8373d4464cced519e24e2a8a6da033b51603ff4d6fe6ed07118b6b7d829597016749774c34893b755eb0d06d62f78bf9c84e99e83ea46601b7b49ef47da9d0a9c584c03242e731388162c873eea48c49185cc320808014fe34272721f5be8569c9d030419dfc29cc65e4249d8282efd8d58c46e13508492142f120fd79b0200f1d85dd20709e488b32172189894ad61e6b9787e2601675a288f5de064d76a5e209e2f6cd25f00a20c516932da2c2ed7a438725f7816ba00805c37f0d30cae10f0474c3373e823df5fa408af54e239e9a3a9ecb0c122f8141e13144edf70d503d7e625770fe7139809c05a0e4647d6ba63fd3d347e8e5f8eca4819bc55a50b89d911bc345c4b7de99e0c0d032a551c934b9a22c73083d58ce5463c70948c0f5d379e2f751d1c371035f93ae146d040466da069601a88d60aaa57c3c3bde4d218ac2ca41aa7030731051ddc8bef03aec81a016ead0bd93a40159438dc4b3cd5951c616548fdc318858998699b553a0876f00347202d78a26f7816752a6a00d7bf809e18fd786cf33b0fa06d07706bc41cc02fda79ee8df57925eb42812ef6a26a2cef8e36596b2709d3c24c5577ded4aa67678215805943e9f8575fe1dcb25dfd10a1fef77c79eeccc3847e064be9e66159c9274319041df0eeb61b94c9cf0171a1cf46de57dc1ec4db00bce731181006580ae99a4ad07dd7ef599b87c98d8468f455e347318fc8d8fa2860019fa0210b15df2dcfd21f37a848457487ae73e4e1b2eb3ce7e6851508fcbfe74c9c2485289af64c3286a15de3068d27611f6f46fb88870234fb20076fb81c0a4e9f53b65c8e485b8242c760a2fb23c8255d15db1da25d746818048b723406727c6de0ccf40b3b30abfe1bec70ffceda80063ce872e09fa594399618eb9f4a3d87e8d10f7583b2bfe68d5f7b1c1e06078cd1607d3c9685bf9d0319d992653a8b56fa11f587e3f1113bf172c40fd32d797e2fde1b005809bd389dca7443e932e0c3420b239d4a851778df04e61cc2f8eace5452847d36108670d92fd0e87f5055904c4ae5afd907c85fe3baee5d7e0eea07d50714b78820bd70445a460230103eb2469ca422791665f231a5bb20e118b118d016e5641fff1cdb5b23be9af8947ea5703fd2444e8b8b540870ce34bfbf27e4fd6ae9c5fbe37d6daf683d6a9e229f3744584d4787785f321bfb0462e5c0fbbfa277b78c806c9eea831246d0b8d9f96d6761999a5f655c402b481ed1ec18ebc51d8ecc7401b1f92f7689891aba854c2d029f4d41407e22f1261c65d065f44ee85af7ffc8443761687dde44ce66a5ca4892fc599761db23adc19b4e9d01560c93caecf9fa6692360ea007393366927234dc381cdf93a7b57acb5f8350ba42afd07f90f6ed82254ac89d5314904ce841749d727178f0e3ae441a67fb52aa1f850c62ac132105c19d3bf71fbe5f57a8d8056747739471825c1485551597d0d7f12cb702572e8a6e051b2f36d67c9ebdf849684cfb7c64636c7528226ec00033efda084726e94f4170882d6bfab142da9b68946176e8361e8c1c051df192342702924977dda6ad8dce3d17e132905293661ef21d3b2f876be23f0bcc7fb54dff0aa386b15049d9d71f3049a6efd5ce4120fe3e7af33092b879bf91f603b58f5111000da6800cb130fe5fba2b54a478f37d8939e2b653a7dd0d0614e371b862b7de3ef424024826d4e4298d4d13cb96419205baced13ce95de1e0eb46141fe4ad29e0d1cad8de360bf44c5c29516741fbb2cb2c51a2e4f2f6c903a9709bee280fc2105b715f42fc1df403f467d3597a4e14a8bcc00c0670618c43682e3a7e11bad573987ed5aeabe9b367cd8ccf209cdeca7a1aab70fd6d1d41a35dc4b8f1274032899e64299f7d8e345d183811bbd9633e7d0cc65dfd373a17079fe93d351fcb497984860e9baca837694e0f4d98f074986e1c510492095d760222e9422a1424932e78d65ad0e8530b7c8ce23cc5277266ea164a634e874aa28183c72a0468f24ee8293179f63ad1d75f821590b71e5b2b214cfdd55096bf3854f05a4462bb8d48e23e80da3a9179ecf7a225194201483906c0bf461e7098c75ac0561106615c49cde233b00b45fb7c040a337aaf7e5d6fba36e4f0e7599cf8fe70b89628a141d7407d01e4f6d065bd2c89c127bac7bc6b6227a47da61ffe0f160b1f805c88245ed3c0c9355cf98832d1fb4d08e83854b39ee6fec4795f04dc4b7dec9946908bde6e901b832adccf242fcab65ffaa45a54ae5ecc1f2dae7266b1df4eb07a6eb8f0c55d11234c0c03337d42a9f97bd569aff2e8e173152c371062099201f3ffa558d744f38c00dbaf08d0a7d24a0503f89fe014cc0f39857d7f498ba241dfc9217f7e29e92f663994645e530645abaf1942716404c9442fb6e701501c0dc3c4b2079ae6858f96979741e76d88586a2409b9228de98560c4ed574e58190dbb22fbc575594d8f9e405eb93b2ade3cf2b6e42bb12350afdf57fe9b8f3cb8f7b7f0a506c3c4987c9bc8bc486075a8523e135ed10318b1d332aa322d7897c2e315f62ef96a64463a3d170d835e44904c2e1868030fde4c720ee1543cdfa42d6d7f04f8c0cbf48953c753c86f5417073276a3fa447f5323938b02b6b53089bf99b0751d57a050a109fe5b418bebfcfe01123e755eaea2872863790c8a616d96e9eb1a80b468ecae59c1c9e482be7fa448d78670ca0aa3c49545d7b7b2563687f8ddc37ffedbca62e5b895d11be33273b00fb4b8012195a57216995cec19b60b7209b48982862139af58fdc659f5dd5675323935233fde13cc6bdb77b43194621b5d6db00839b5c121b08b97be836ef8c7070dcda5496ab652226d1a34b4ba0612295eaa4ef0d44f04e03858196a700bd001e5e264c5a3b5d0323c27851f41c413b7a2cbbe58a0d03481efb7db5ee27a392652e954646845b655e7a165a291d2d8652677b641555fcd0ad3786ac76d8960c1a4da95a9a057a1c24f4a1250c019c896f66291939972ab452e8e14eae3e45f13090498b3a5aba6d7cca9bc1cf4805da9deaca0a4bb9f9b904bb443f47f1a6803be9187d5ff09c11c53aa9e643fd412379ee3ec6b483b51029aeda6b35002f08c58d2a12a2b84bbdc14897339d02ab38fe6827ed2fa95e2000e69a214621085bf33ea93c954c7933caecc46cc90ff3894ff83f274003051760459c30a080f48a79aebc3d3e338ec1ec4514df8ba264fac50118610151f437c8a5608d01460579e0f5ef6a0dcff5b1e622dcbdbeb97a0d54726ea45a5a9f24d67f53851931324c082fd8f3e32a117c7889c1bf858e0a2b9fad54c58a1f637e4f7c38479d76111a3c95e3fadc099f4c6bbff8651d8b11e4604ecaee7c5b348c79cca11c8b7999d8554ed785878b1fb7f317f49ed134be9528c2c71f0237e49c82e137a0efbd00759f459dd1cefac2ce38daab4f923d0b23b00d5be316da651556f5890447618c587214e1a8b0be923203d149f38333a6c9e8c1b5f00d29c3b84ac61d15212f645ec653726d1ff10d48f9b0cd74d265d26d9fa75e5eeba6d574ce6eae34ffb369c4cd6ac02615a32f7f412ffc846ba6b01a7f0577f4a734d4c7233ef34ed3ee9518ca7a1509eea94937e2380470cde8b9149e0138fe160261ab775e145726f97eacd2bd7241d2cac5a7b5a864c2e7fc6e77b3000682e93d4c98d8354ce870e295ca1705e97cb5b6bb0da44e39e87ce30cce48e6123131eba7187804c5a2f76193d3912c0ec880f1f93c9125e9cd60fc0ce80a35326d46279a82a5e5832794e227ea6e06007c82eef22475b233d4e894b820c0aca64531d134080309550fcc91dd9395346a5f60ac4e731d3ed1e1585e00fc3d77706f7ff867de7890244291381f053039c4c345d7ef8b50c080dc1246f1ac2d230fd867e1bcc703ec5dc0825d539f53b995c68bffb2a9968f3ce91d26dace622934b0b52d2c2045012ce2565725dac27939358d10e1796b9cc64a25b3332a1bf0465d235a24cda5495e227135d95502674bd0a5d0f08fb1d6c0111f04ab441f1da6d2dd715331e80257ad1a2d82dd459bcd8919483982250b00a7802d5b180888146659374e1c1eaad9f3946db76709f685b46527232abd2cc5b7fb9642a5827cbaedf179a93eb238711cf9cf6044397d94e5131252d12ec6e8c9f4cbed1af0d950b9828b2ed9c688677f171b31b3f79bf4a28044a7c633898e9364eec8537f789a48081baf6d428d26257d16f55df4920f321b6bdd694b4d075aeb45584de8b1f3ef2573dfb52e16ec1a2d006eff7d78d345c8749dbbe2822c7c5b6752e2a535f134e50379db6ec6121937f5d922eaf5a6d05121115a6ef0e0ef28c54c15bb4ca964ce194406f762bc1ba31879280b1f09c839edb1b41373050fcd3046ed890a803a3e4212a9d4f030f5117b11bca1425e5e8dd90adebbd0bc01a5219b00b798415b74334544fd7ae266454f2cce6fb2c292c8baaa61494e8586c8bf64408c03b11d8973c31b3bd713e98e85585959bce2f9f2624c6a13dc1f1ec4b1a40e28637ebcb2ca3ff32e0db42b2263bf49bfd1a0334608823c804c26b7a16134481e8c34ceb62feb0069b34afa1d47d7d7004577b925098fd3f4016bc11fadd374c1f0e5af0e77abedd7f37ed08e1ad8df269db38ded1c1782b6730cb9baa92828a064d3cfe41d08456ad8b44221f136f19f1ef455c3ee464d95f3263ccbfcd9af53f12546409046f4a7a97093cc3b8734acc16942091c8b348a074b9d73adaee858fadc990033d2f15ad48006fc2a16b1a7d0afc6cb85489e0e14a03b7eeb84fb37b341ac77316f1c8128cbe300806c1d3e569db4cfe653716c2c7eb7dd3254f0e42b5532f8dcdd403738a07e1e8713ecb31b198183fc3d4c092afaadb24725fb1c03f92cf8bcf95dcc7b7ab6af599ec9cee02c018c34114fec7a7499cd3d99482750fca19b9b4c91286da8ac3e53c8339e50a4cb1bee710123ecfde77fb27310035690abb7265152c406e70e41f11b484061aa88a3c8a160ca81688147338322ec39fd88f3f3fec21321344e969a71fb52544440055e19b3947e0c22354ec43dd57a4e31737122ace1cc56886b6c036918c1f8a63b265655466e6f8721204b28c03be5f9a15827143d213d1e3dff3fcccbc24c115593f499ab4dd8e28ff1e871c7c446de43c90140636665c57879389062b1037dfef080e3f97428680064ef92a5df0864fbec09d1366a014f2d5bf27be17367834561820201749971d703312c23d3fa9f00331380d45e3ed858506dbcf456686162be323398e4a48188959463cad06f17eacafc1ba49cc03f5a124520c3dc1624b8ddfa948465a30d76163dfbc34f7aa22308612924809de2a6e745e56d42670a92f0001d27f07a7b494eedd5506767f80cf4d64bae23ff20ca2a1e4e14e79543151e7aaf778e0f34c20ce58589ba9846fe4177fd970d76aa8491c8299d8962c6d3e6f652c85fe205e53b23d9f0546a9323b714111d0e227708ac8562b646071c2614900a603622d9bdcbe7c2834268d606e75f79c3aea4061efeb982b283112a2a31931d132703738e8467f28b26c1450782462584109c9410e5f13efcadfe179ee4ed0b165830cc6831b5b8eb8933baef924c235bb6b0d5f4704b6a2fe09c7ee69c50a6949a060fc4639fc07e58a39626774b9b92227e8bba0b52857e0421e4a88a4083c0315125a3b3838108a55a3da14485028a8a16915db8907d742228bba19c236839017b27c50f1385f1ed1c9ec5c3a6446e53d3db4448c3d01efebe74cd0d7f48e4ed9af8f4c268be880d220cb03c2e6dc4fd46aeabf20e7afaf6ce97d60894a9279380dc05740795b38eca9d41f6bd49e3a293582ed5655050ebb6958c5c6c31fa809e2fdddf5223e5367922c89e99089dbe13f6230f14dc176d88b8d8551948dba211a91076295e820af0309219c955ae950092e68d82ef55a199ec0e3c16b8a177cde975904f5a0d42f64a936a57c248a105b1df482235d4e99f90b00a958752f98bd7d834dc32be8b40a0ee14fc39ff09dbfd0a77f44b31f8c2b9d10d7cdfb3931646310f6b5423c162a0dc1200240bdce75efa4592e81088ff8dc9f5e74582884b78682ef60c5189931a5abf0af9297adf3bb7b6467dacbc14d83d3fe273a3300effa68bedf1d87691f391aa42b216efc136df606093d88121ecdf5416aacff87a80f879b2b2acda95e05dd5d89308826eca7abca7fe02ceede9009222df7dca068c9b6790fafbb9c6d8779a67bc56776a48601e90b89b89440920e270f724493ed05c480f509e153700c73f1718c7d64a0557d2dfc239be47b2ebcedba94c3832e00440c14734e38867979e82fbdc90b9042705a207c5421420dfba62fe5b6ee27e610c7eeb25c64c634d254578bf4570ea31aa96cb530e62ecfa3096423d4dfaaedc344d63d08f9832c431ae0fd0b16c736fdf9f51f70d3f9bb6bbe3c5af116c0c2aaef00ab9b867895e6583669f9aceae1aaaa3589019f5ad76d520fa466a62e3250295c817c41a0ef6136ddfe0bccbc9776c60b6698dd3d0ff4909d491d313b45110f554af824c1e6b644c99668a40df2ea451b99aea5a8b86b13b3efd06d398e0c3e399a135830794f061c9aa2007ad7cbc103054e693a7a28eec4102642bb58c4e20d99e4c574e614c87ee3033a48fc4f82371e96b93df7fbae137cf1d32bb187a0cdeb9309671aeb8a3e4c70d976ff8258e79b283665b768df2d467dc47809fde283751136ab57ba0cc74f3677a79bb4ff34ead9aa410fbb95cea49a30186ca4bbe507c5ebafee8014df4e80993726b648e2b47764cec19dfe4d42b5a298e84b025a16c78c00e4fd82956f5a099a363438d18d9fe0ddb73d3634398d496cb475e6af9fbfbe5fbc4903c77f33ffacc3e0beb66f8e0fb76edc8c7fd0acfac0ee7f8f7cfc43617ee8526a78b9c752d4707aef4c383a39fccace9d8f75b94ae1c35f8ab66fd7999a2ab27efdc9815e8cf072e4ad70a6b6b5acbd3f003eaeb24bd7eed1959985db7190ce4ec1fee130eafa02c7e016d1fcb5ab330b6f8778887b832fdbf6cf3f729f8736f087813f0e7c4f8fb45cc4cdc352e7a93718f9b03974f9985b0384595d2f87c52087e9eb70de6370a6ba6afab6e70fda8ac9cb73c4ac7a5739b6b5433f3e9cd41e8a3995c0356a74ff1865b03a698f0a4e828431595c3ef919ab35f7b5188d1db68ce75cb7288e18e97a402fd9bfb07e25b03b53c28036824b12431cfeb087f337b7df93cf6186f96f373761e6a6e1de98755492394c21c80c14466fadb4e7b99bf59d857ec8e7fedaf76b030b07f17a61ec7c51dede27c2d863b920c05e1216c32b263ad10c2fa0730afe94e7a20ca3fabe79fee7417a9f55304a10ac41774d250143183bcbae398aff874d6b26e83630d8c1637b35873a057a4ff1a7b6273e45ea62f1e6ce9caf74fd89d4338faf16acc90b779ea634412a39567c0ebc7264e10fa6b64eeb05713e26c322af728758e88f69c2077cba959dbfeed49db357822c6d548ef7c34b7c5313b022d070c4808e4e22ee5df542e3a9cd4bfb2a43743aa148b2a6ed625caaf20adfc4dde5fc81f0481bcce3c6bfa084e47a57b64bad108e051d6c01269775439999a00d7994f0c1ac035c81cc37a668142f0e8582145ddad327374bad134e69a2db7608c6b15bf331e3ff8ab72022d70886df5ad00a72c7e76b9e3af163206ec4cb2e35e338ee0999c25d29ca794ee8b39bea2a9e05f48117756fff692223d91292763e8da42ca4b64d3b3faeb32b3663a2607676f27595a9eebf6dc4e3cea314f06f186e4f35610fdf823b9d82910adf49e20a14a9fe76c77ae202e2f81180b61981be0032be8a2254c93fc1630cfafc31dfe7f65b343660ce3d6e31021bb267dc62baa33fa32b82074c679853cda5b82d75c2e9401249838d8560c66c7de4068668db5cf55f28e31690127bd55d28f6c7ab9ecdede56d298d43a18851488821429690bccffae3103123b6301b396a486d37bf3c1adf46c8a219865676ca17261c29c6a6561f774779d67f50d3ed85139a0981d88920dad4f93b27b2457613bca275b49f2c3dca3063e45d0a0c3a8fc39bb7171e92b7f30c35ee00bfbb55f263a5643307e8c4c20727f77ec1537e52f4d95e29eaba0214ea505733dbf98b30956e84964e771158d1a4b8a6a8a2f8632bebad9d8e61ccd2a3ca4f51a38cbdc6b7cc1ce862afc56ca04654fa963a8f7c10bd99840c5fad46a48205c0778d4245bc3a1dca63c352977e0761d9c2a97d33e0bc327cafb0d2130468b1a8627611aa6b0801f5ba0bde888e5b024721086bda8082b47964784bb0825b3c5d50a728a6722fe7a776ea654fa50772351ce6cc45d9c39263abe94e2d0d190b945c45c8506a729156af98b884026cb8e95d63a5bd66694f9b181242f9cd644599a01ff2367e3d50dff39226a495358e2f175cc235fd09d9646ad12510ae305981f4088236a9953f9f5d3b380003366bc8134311235d7e1bdd00ff646d7245c4337c86ace56705b2d03b6c54d58c5be64528a2c3005efe379728f636eae9a3db3459006ab911f49d3f6659bdb00f3ea0f20348fda02be88c5308d3def1950959203cb7628a78b3551b6d368a3d88c788c281dc35a010979d28973a3978e45d9863373d11bc90020ebe2a5de8ce5e8f4d865f82be535206c8ba848c4dd8b92fac56d08e1377716d6384ff05385a8b08dd06eb3cf89ca965dc07729ab69d0b83a296b9ce13197753e04668eeb24a448859901f96991163a935307ce3770631a02ded4b0076a9d6de1de0a105e8696d9a854f0ac015a9496c28719ffdf75dcb3b62e767ff481095705991fd88d7cdcd09c6f2344d3bb683917b194255adeba9f6b2441bec2c976d4c4385e04960d727cb1be355b00d10d9c657b0eb5465662516b0a7f41b2e418d5bc0e84c12b138c0f4725354d877fa44e360911d272fa3136e32ece74d90dccbe4de7e18d089fdd50cb1380a39b1ee6cef347b18a86c350cda84206ed23ab7e111f523562f930f378ff78bc40ff16feafb1ae8ed4aa91544795556eb2b2367c2ceadd663520b1133a443a72da8c86a52adefbb7e388dd26740dbba3491ae09cd8e7600be97bbd32efc420df36f6aac354e20d3cb82650ac621800210d07e326f5d02b360e76b9a128ad7260e38a32c6a8a27212068eecd255e7df327f75c6c89696c6ab64f30aa0dad8c1a67fa573c6d1396c30248ec27fb032f8066f925db49b4af372103b28052efc569be4628a7438937de5247216c9bc021014311512c052782655d1975f9d6e6b6b0fc4a85ff300419e7528193c477d9c0a25a2423afe63d3eee7f25f1762866b9c4c62660c26896b8d5565bf069ec7e92cf24781f35f217d25df63844172951e74e8ef5ca49aa8f428a7275d51f564af187981753b075ddecc9a8c80cdc1a70781515dcec789b73593eeab32a05d507c42f800080bab8dcf59fc036ad35087c0f2948c2cf9531a884a3a7884ba86ee4eb3694761532d33b97216c142f7ce21376f9bd9a205504e4bb3da40aaad1a27038d1f2e487c6209164e85d988a09339fe280989132658f5a3aeb80ad3b8c42c695c0cf5f0720b86c76bc5553ad26449e8213589127d3841419de377d7324f7a85c48e326d13d1d7babe1bfa02e1f7f58f3da828b830abbff1d875f0830777b7ff1aedb50db2cee4900f6f169f3e745f436282670e9dde03225ca66d15b60241667efd63e5c8963fca40c2e3b487ef3115517c05020434790a52ae6258b4792348d44244a8d97c31eabaa69fb535bd60383e8df2de11c549724cad00cee0274e9ca3b37ff3d1ac81fef0b0da66c5aabe86574765c449fd97614471b359a16bc4d7b1895eda9e59fa1b7a3837402d7b133fb577a8464a7cb15fb04ac2cc790d2c867e90c374866404695caec4135556fef9b80cd4ee00872ca5bf6e6c3d294f3fbb2a7137967d3f95ae7a0ceba4f34fd8876ac1fcec347e89346426beb29a7555e8f07eeeb5ba5018e18c01e2c665c63b42090979ba6129818cbb4e0a22d2dab804f535a5712d81a14b03b708c6068dd2ea82ee0adf5e918b1da23811d8cf28901918c8d7a495154f7a44254cad785ea2e5c5d842d40a681168e58e10be53aa766486b878acb06bd66587273ca947f2673fd850683b74eca35d52bc3ae47205201aff8cd37d4105b8c3db310f43840f4c31b6b5d27b96cae652b5babfe268aaf73388819b7cf0edae9e7c28a4e786c030c3affc5eaca2a8ae2780f943dd356d8ed0150fa72d83d0e249e22d5820a6f583aa463c18d6992d468ca26c8ead2c501524d3fcd3d1e24a7307346013947f60a7a78acb1ad071096ddb501b561e3025b7747cf5a455c221bf0d8545ba01285c592a8a8ab3643c1927901ca762fb93eab02f25f948b9d289e26b1545e772cdc6dfbc9018753bb5f7e8757ca14b8755de6d0e48e891684d409561dc342b79c248edca0ecf4e6b0ed45c3fe82d785e3e22ad8d951d9044e37d072c799e858479da678372657f750729b55e56eb3b8ac26f484eaf73646a93b98030fc6a8ca94ef85da1911fee8e6024129dc7ea3a8e8248b4ae077377ebf6509a873b4ab0d88c50d9e944fe5931d3f6b98ee8ddf7cc30697b0adb25e441091d5467f77a3436568beae0c1716daef962ce7b18751bb7d4cea0df0155f27cbac182f039a915be1a4015c1403691aae3454b0043a2b01fb4a8166b4ea32e952e41dfb8783d03c94dcd82b3d6b685e85aff23faceb68ab60cc3ef4e548e5379eb11afe1bdb4c85e00497b8c4f7660d7fd68f7d83b63fadd890fa0bbfd49ceb8e64cd9cb42e07acf59980d3503ba47876c3a3f98c8ef3e1eebae35493bfff553345f7719a83d98a82d0abc5f8133f7283fb69824e3480f9177a6e70415572126641a947246a68137374aa24caee0b96ccb96f760fd4b53ec97b128acb795bd52b52b8b05cbdf2a8044b7a7c943d338a8c304a844a963205a4c93f27b7a4c3e0258afb7f04b8c60648f0013105e60b09a45ccb42037450d91857fa070114cfed9a1087dae62766939dd8cc90017711e3182e406303b31c166cd68ecbcf0d3d8576ffa36646a72e81b2b1dc59accf8612d7ea8d418b5105e2ada06bafdb3ea42de5a7c1f0e9865fb598584cd2bc66cafed11bff52b7649154821d7632e2bc030f7cc4d3848d618fa2700e1d0b54b86d1efd0fc37773dbb9ab61e71224b23d9f42d2f21727fc06ea2a90ca0b67a2ca86ef2fa3736be4dbc9c6e82854860fb7a319e5946520fafa4ff3ca4e30684d9e65bac7be4a70c3acb4dc49fae1c502c99c846be6eab22d105e0b8c770ca118c604e71a910a4830fe132f36072f852190fb56a4193f61a3747607c559b8faa41c1fe903083a4624e0fd7b15f46169966f462c8569908f822ce00e52a764b3284e4b6f33bba9747e9c00619803a55b83c1ef2d713e910c1c27390eabd241d616970e5b270e00171fc5429a33da0a26d89074106b8905c363402f58ba234ae36e9da433ce980fada0e574ebcd536b95352bbfb869c98883afe86329d2e1112aec08410f377f6bfd250e43005d6704716f951cb26583b4a2bb00d70702004d94142c5d6525b37982e6025e4e8f5d4f05f039e4d3a16254a059a20010bacaae0db1d1291f21606d130945d4bbf6868e27790652dc2017ff26ed9e7f734375ff7543751256c694c1d02695fa4a309a74d0350667069470e5340ab06e5b18298be5233c0bc09cc464af15b891d88ad00bf0650678ed1817c5e577bf4df2e72fe5df2f8e77a80d0bfdc6852a6b96b4002cfe63770489d0cfa1bf79fe2eded2e6a1b51c8b43f9be912b9a12fd040267067f897e03fdf0b7b42da5b0a42fc4848d3174402413aa461927144e709440a1c82f0c6113adef41d06128d5bd2818244d0e387f3f1cb7cef33695d33025081353752898c80c5d89419a228f65d4631a317366f34507a93def15f401aa036a3708b5612ca383382a82cc20701544dfc9913209896d3b544235fc796c4de6af030fc7ce5bf78c9393b5aec8569c11983c755396016fc284a7abd212c63a568f8e3bee583043fb8f5221c936b044d0a1eb49e4d4081dc06717ebdf12b682bcdfe50da4a4bae085dcae0394d71b85e0efbd8c83404c85922f31d1354d21cfbe7ac6071e7abd47b775be2cc5a08209a2d2b8229d4083d1a7cb3e093655cd39d545712902d1ed0f2d1d34086c6815d856d9c05f60d4c7ae87fb490ff1502e9b1b54066af54c398a61da19388eca104683b461aa8aaa5c535060dc14af6ffc59cd3414cad94781a4b1842eb93818a3d12454e88a8854fef02758b1a797c643c87f6d29ab09417fc68b599e670584b889e3a3c19ad773b1640ea2f87c05b44499dea252fe441e42f1ca410d2c59398f49287c186a2210cc13e4ad5c86a2f3d0be016c2effb09b98a5822fc201b540c9efe16e9d10470dfc84c945b5e92b3006d9b2a9902df397598a74d5443383b1090e35271f08a059594af5f1575f5c28f73208fd7b3890075c0608083a3bfd484407da9fa419802fed94f6357b883bff5ca603b8dc0fb69783ccf611a61ee130a14f6c39794438b3d348075ede95ddaab4ff0dd92346782f2e60f896618e49dfee4e2b30c91e1da4488c8d68d9992bb08073049b18a310eadaa1b2fb3d42b81dbeb99ae49982c6ba4a9b2158cf7488a7f326b246c985d6057ebf2b1c5a5133c0850f24bed2489eb63e82f9d6857f32542e6318874d127e63687ce03759c3d292b9dd27cbc24c64fbbbb0790bc9b1ddb780716c177d8a1d28b09047a7d538807fd6f4a4a8af9b9aea9f3b0796b9879eb99b32f861ca12878e64fb29eb1c78c8b690639eafbaa62162c33182a4dabfd219ed685f6935df132d1f3560a4cd0c4eec8b1fe4ab6ae06bfdf05798fca882b78a4b02d07cd4e9739f4c618fb2fdcbed8aa40a848e013a4f994860404e695107922eba4e65c8bfba0995d6f06e920dc023942d22c5c4a3c49b3d8afd18bfbe53250f747a9aad73bda3a360668ef563568c0bfb4ee43ba07105810e73ee942bf9433969e7a67298dcff90cbe349ba46220f174fb8f6fd646fb9650a980423045b04b3376dcb83192e75d95b1870dc0c9fad087880a628965d9b2eeb60224ac3b42e7494171a4a973d4260003f883429114902e48280a4a7274e8441004861c7f8f8edc6bb9620b22339099d78a0810427515accb227f96891cbecda099387d13070802fae0fc6a9523989d1db5242d057429ec99ec4a289dc625a17670e3792c2af091517596270a19b60010a0202dd0002f980402c00815a003c808b2eab8f1230e787c9eaf30434c04fd2ead305f8f302f86302f067085880a04f0ca0bbfe508d00e27cf0a7c80b7b92e4388e3a0a2a8fe33892630b19e456f660940e103afca8baf7f2f8e57b6dcc388ee30b8600513a60c8487caa674924df7b8e787554c338a3c9fe69c2a4a74993166776241cbeccca8e94e3a704443e58c0f07bc10c1706106537935d471146d1a147005995bd4ea7230127802c483c433e16ace4904aed8c9c989ef1c71f4b18a8a35375cf7fd9ab8419efa87298535f79121d9bf75ef2090a806280daf1b002ee0620df2b9525df7b55546a9c6a99ca5e505234fe8c3292830c59fd9c1288244992cc59cb55f6e08f15e4327bd0c7efc754736c23b23a0200d90645d981c2152a39b298e001a3a10c168c707c4921b53c3220e4a1071d802978e1850617185d453299f1b1ae4e5052230b9416bccc10a16fd8aa26367c202555c933d991acc820552cf278af762204b82508a89b60b1c91eb4a1cbacec492cae8c5d70f4142d2304b71ced00cc0264d2017814dc2214dcf2c5c8f2301c8608311c0e87c3a14ec3201522c4d07ad14c50f9e2b268381c0e87c3e170381c5a1e86275e189e78a1cb89177238f14216fd826ec8d3592ea76ba6a61d863413d350c320144533f9d570508f94350df22159b5122315b49212805a3804acfdb0b21e05b795a012915f7ffdf56fb0c860adb2c6a404a9f888a428a5527ed9be4cca50b65faba53d80b1d5078c592c411e42560885e096232bd25a336449895ef2ad7aa9677a8ab416596bc129256b6d870d4ef1685a2791613dd24992825466b86197763a49972458b2fdcc42be3f8af75e15f0deab7753be17073886c8aef7903c1414434ace9d1e8cf1148cd12405a76b24a81e2e823c7c249cb9d33512a8dce97af7f4dec5d048a662485967319ae4a260be3cb87bef7869b20763ac59953df8a3e8e2f01f556a30ddf8f1c25b822299a144e242cf55a948d5f86306f9c384f5cf58507b51fd28ca594b56f660946e05282d804980801a49d24f2b7bd20f13a6801a8907e051704a482371a1a7a791fce8692444dcd3b2c8fa383e8c9d7183d7d3475ad0477a596d40f62ba6288ea4501c0d51ac37c411e3d9e3a548421b41c1620be5743149fc59b04b5659597c158ca27571ea2b35b2eb2b3dda0a14283a987e5203a6d256946ad478915d9fd05b69264f797cf24fdcdbd513d00981ceee0ee5c119ec3cb843933b8ab5278ef04ca6288ea4501c0d69b2bf6e78eb8c72bab27a1a41c1758394d97e89a47a1bc482d4f4c43af1f4c6eebdf7de4b7b69efa5bdb4f792dd7befbd9796f6d2de7befbd97f6de7befbdf7de7befbdf7d25e5ada4bf6de7befbdf7de4cf6de7befa5cd64efbdf7de7befbdf75eda7befbd979696f6de7bbbbbbbbbfbcdde7befbd942ed97befbdf7de7bb3025072cd73e050c1e250e10a4148993d6ef317356e9c8821c789187cf8b36cd9da5890c1a21a803800eaf2022801bed3beb35857dc60cc1bb04c5974a6bc2203956e8a56cda607d7e61fe8c08a6764f4d34a3c925473b24f0497020e4356c5124ecbb33d2b746f31ef6f87eead7c7f6b746f2b9cab6054675661b5542d4f7518b2e3f2c7e94cd9b3f8b6e54119f32b1c939e65ca746560fabd993bac1f77cabfbfb3fa180cec10a9d029553847a44287f523de191fe631e038d613e98c443a37e7b302477ef9ac34477401f2cb27d221bf7c33dd21755638a64ccbf44c4fb0b2f6c9f47bb3b8eb38934c55e4ab48d5933817437e99e688c427d2b94fe25cf95787fc8b7357766d659a235a3d910723ce59dc48b47a6fe9a81e06e754647aeadc1f71aec42bec09604431c8749c15592ccbf3949523d412a2f0da4c9bf6fc6075c5882970c5f466321df3896b539bd194c7044e9c42a56650b55dfa341aae95e50cff64bf094411caa6c8fafb39e7bd79706df74bc8ee4d377bf46b4ffb1a7ef534fadaab5f834f5cdbfddaab3946365ff3aa6b21369884d9a35f834f67aacd5eff96e4fbe22a1ac9d75e7f1f338b6c45601593aa25c831ae5ff9bde588c8076192291139c6b02ae6f15f6f3fd0b1f9daeb00e0d17714e7886a4f7b00d8e46838477e0da31fe339f66a3d8d045a1ffb966959b40e5afffad6bfbe022cbb229b23ebb6c6374716d9e200fab41f5b3ab547edd3b085c9de54453155cf9368c41fe8a05ff33a368f127da043fb1d1af66b13ad98a2a9e364a90aabc2c4972f3d645a07346f3e0d120e5e26336a31ad03f3636f7e4c95f9f361a9eaa2493f7cd98a00ad03f35f6ffe0b8770730a1706e1e6d58fc8aa5604665e6cba37215307944440a4837eed6f0de7506c75215e7521ceab2e2562f68ed3e0dfa61c40bf8673696e056ef6b645bb40edd1d700fa1cb042f81d373b71d1d4ea594a4b85189d8efb477fa66a5160cc2d0b901cf80781d513e22c5d81f39605c86cb1dafa15b6cffa0fe93922a710dffe4cda812ab35e83d4325ddb7d11a96dbab6fb38a9155edbfd10a94ceaf97109b29ac28a18848beb5d29dadfb753f736fbfba2eede6a7f5fdcdd5bcddf1779f786fefd963b2e57f33fe9db96046e8ef9599a9bfd4ffaffb53457fb9ff46dd07487be5f9b88d59bc57487fe63bf35e90e7d1becd7a68220fe2cdda19868c42a4ce451c421a8f2a8b32a0ac5dfb5ddbf2f0aef8df665799eacd4e43181ab7dcdfbea676ff331eff796dbd5f0cecd3b0efd7f330d41756f3fe9d75e05e1e6f24bacdeacc24486f934e53181bb79fc73f3356faef007e2cfcdcf5e2d5ffcd9e09f9b473f06ab2506e1668b43506518ecbbc122d8bc589eaaf8cbf76d300e4195d5159964bab71946cbb2069f22d4bd9de7a5a5deea20858ff6e3a720df75b624f689e0d726a6f089307b527cd2eadad7b04cd465734c5d675a2a8265d15211026fc28466ce87f54e18ef8308111806e2d11415c274b3de4c683634e3e1a4b39d504c4868d2e8625e53acf7415f52d7667eebfdde7cd0e771e19dd53bce077d415d9bf932bf4a2d905385cdaca92127fa63caaa0c4a2926840aef0de59da7ecc4aa2ca3bc6caa284fe627eb496999b394c9b44c67d9ef545f428b73dcb3a6603a2955d68b29c584643d991faa655fab29c59e466382fd6c86e21d9ab7411fefbcbec6f5e2d19a6242148ac6855f32ec827269bf3718081afd01bb6242f7e62a65b05aca585895a931a198575953ac579d898555678ac1ea881159654db5a462e89bcf9a72e95c3b1a0f56637eab67f338341abc8837bfa5647e4bc8f5e67becc7e26e60afb6a660b07f5546174b55995d36df7188576578ff0f7bd59bd2f463afba10e31f8bc32f7bd5a142e01f8b0bf1e8ab2e357bdaab39b5af79b584cde3bcea5a033cd389c0286b2a9b8f93a236295a93a24ad7864aa11a850a91ba84b3219cba9a664269ea629af53e7529cd7837a94bd3a4b3578afeaecd7c578a0aafedc7e4d2ab7f0967bb13ab2332ca2b72aa323fa86cbe8afeb2f928efe5ead1be2634f4428d5e340f73b91eeade72354cb3c32fa1d4bde56618c52fa83b756f39198ee19794eede72304d835f53e8eede722fecc234ba2b23b4a979f3657ef7968bbdeccd97d1f796733dfae6cb28dd5beef5b3375f86e9de723099a67bcbd13cedbd30e176641fcb41df55c2e6f53cf7cb972faa6b9bdac3be06e74c48e176684ff3aa2be9b2ea5353b514d6bb36f369294ce8dacc9fa530deb5998fa6b0ddb5992f4b61b11436746de6c3521a577a9570e5ccecee0dc6746de64b4941410985305d5356657e1aa653da81a94b938c470ba5aeadf566291593cae65b169caaec25cce6cb84622fd821152e0645348a39b9acf77af3653fd79b1f53bab71776e9aecd7c13ab2508ac9e7e6f2efc01c794b2f9b6072f2756cb19ac9e325895b5b0fa2cac8e3073cc125975e9f40c49ca2220d68ba6e1c97639cbec493c211c13a79819218005775f0193457bdfdaacc2fee2850bdfb98b172f74240b98ec9aca0e19aa2928e4c8145e0f15a560901e649caea7e835bb9ee2434f19d253843040a487485665d75592f894f871ae60e656c208479aca2eb865c60c094d6504163153bb991bb2995d3bd1e0637af671031eedb4243bad3e8470e0c40b725ac1ce698753519ec91efc613213630412a6cc20c36447eac106ce941e3d8529c764d75370c041b1ded0567ed9f50b84e817e84e5cd3b24429a8ec19c5d15024e1ba8725d9b3295a176550ac3d91040dc5da731c8f41cab02c2a8b80001902644891224086142952a4c8af481122448800190204c8900e4a9201bcd3750c465a8a9396b2e4424bb14106cd33d2320811a537ee3e9ba6a9eb70b76591b55603960156c91a20fd603eb9fad58fbba4a335699d4a5a95b2e9a9304d6a4127b5d04b6a81294d7d3e9ffbaccfe7ee2bace03e3b64cba3b2a82cb2e55179541e9545d6a66591b5eeee9ede9445364dd3342d8bacdd6177d8b2c83e05735071d7e1eeeec04056103221480f7dba68c1c1054d30206941480f1c366800692d3c5cb44455717aa224e928480f1c366800e92c3c5cb44455717aa224e928480f1c366800e918f070d11255c5e98992a4a3203d70d8a001a4a578b86889aae2f44449d251901e386cd000d23af070d11255c5e98992a4a3203d70d8a001a473e0e1a225aa8a131426485cf8b1c003077066bd019c59350c6a00350c7a74946eefbdf7de23ec3dc2de7b84bd5540180081eb13707502ae514d80322b098de5673dd2514474940f777777f7344d5377774fc1e73e9ff5b9bbbbbbfbdcdd677d3e77779fcf67ad8b5edc5de4e2eed6ddfd062f413800e160c20b1c70f07008923f64476a01d4122ad9310862762780880318b1c1061f59a492e4c079925145329949e155ebb82268298a8c1280be1d27e0aed20d5452a8c9ae6fe0e123552368ac72908177c91b784c16465a904e7c04f06515cce14a8b9c2cbb31e905b5ecfa8620985f09291930503e6240f176e47845cb8e1c4b982b4f577294e208107c19636148f2243359c2a836b832c5c578477dc5482eb37a7e8f697d10ed48c01521c1212c987ec69c3d442e72d033ea38b024286f525ba6ee04186925adc4bef72c3e998e6929fe295a51878adc4f3ca89e54f04207b3871c913c45c94861d54f32c824a5f64806ca9cd2a6961a2147abbe4c56473cf5ee530a2c16fdc4b33ca4a0927e02a263476665d74f2a9861ba5892b0d671440bb8c831a3e7acc2947b27072a9c3c248b2abd1539ae259019ba8a0ad9b50d504682b26b1b72e82abd20102fe41aecd1e501419c56196d039435c9ca97b586c528e8e384196ea820086335826194c97f892456306c9001634966650f06818a61e2080eeb038c0441ad44d6a1d50128586bda05bb6090e0ea00e1d43aaec11e2ee8618220183d2ddce91ab8087bc2a6ac8e597c10d9b5f0885024e158e4510397d615eeb24a45aa64b24aa552992a95aa54f1ac4466800ec8aa3f8f64d5bf4412208a6ae8e181a40487ac7e0e8c094009b03eabe39c19c1693fa865619cf64f881b342093a4aea2432663e048b28af067036bfffce77d701124c80c5660f242c8005f408fb368860b9c14048138015a49bfa204c9094d4c2fe811a580205d430c791c73d692965dd7709467d9350dc3a102fc28c0cc289b6f6a1aa0cc60944dd11c59be8055f6d7bb5e032f6cbeeb35e0d7667e0b4a21650b4a212f9758807305ae1cf205783653ac561fa3cbab3f21c6a42accd02d47b4c24a595531298924aef92e4239712ec96656ad926da1cd3f77e69fbc7b6b40913587a2e113a91e38f3cfdebdadd0e1f3e2d3313584410c70e69f42f766fe39746f2b6c9030450692942d4d28e0cc3f8deeed26b8c31017a6fcf0108533fffc997f852209fb2bf39d49258c81bab753b7823af3a9b31a86c69bafcaae67809155957044763d8393dc93cb22d56ad5fcdd0fc48f71991f4c176355c4bc05724a6065879c3a97169ff5aacc2fe6d489583d875ca9c9b3cee68f77eaf20aabe7eee802298b4c9aa7e9c1643d9e0cc6bb36d3e7f5329f176beada4cbcf37ae196ce94f9b1a65c3b3e2ed7c3fe6b4a2ed9e3bcec693b3e30582cf6371ffbd9fbd03ccfeb7d686af00e0cf6f861e9dbfc2bc53b34349f3ecde31d14fbf0b8dee7f5ffafaf799f0ff168900ba814ae76b429840ad140040000006319000805513407921c8598744ad30314800a3d943e403820242e1a8b03825020180885c20010210c0802c040201810448428208ca99696044932ff0541f609c741fd122ef75b8e56f17b95ddbf4defef33c8b71ffd48d587d2b6afe15345bfe18066a6f40a84ee970e83e24952ecb78d59c2f368767f99dcbf67a76f7ff491ae0f8dddfed6a78e7e57b0fdd2f0507c9914fb36079bf03ccaee5baecbf759fced0f7ea4f523b5dbdfda2ed1ef12785f3a1a284fa2729fcd6913bfcf99fddb75fd7fa6fefdd15ea97c5437ec0fea4375b3aff159c4dfefd0be7030509f44c57db6c3267e9fb3fb97cbfafb4cfdfb43fb72f928d9ed373e8af8eb08de271d8eca97b8bcdf76dac5efa97cff36bdff9f21ff7ee44f561f4a9b7dad6f11ff1dc3fba5a361f97295f65b8696f07d24df5f2e16df63e9bf2ff84bea47e1a65fb83c1437fb1bdf52f47a81f68b0686fa245ad8b70dedc2f753be7f5bdabfc7c66f7ff493d68faa7d7f63bb887e47a07dc1c1a83c99cafb6c8745fc7dcef66fd7fbf799faee8ff6e5fad164db6f7c14e2d711749f7418d52f7371bfe5b08abe57f9fed5f4fe3e4b7efbc18fa47e483efa84ca47c59eafed5c47af47587ed930a84f26657eabc8223c8f66f94bc9fd7b36fdf3c71e69fdd0d8f2b7bdebe87705cd2f0b8ff5cb49916f355888cfa36cbeddb2fd9fe56ffed027ad3e527bfe66ed1afd9ec0f2458341fd242af3d98d36e17b9ccfbf5bf7ff33eacf1febcbeb4776a37eb83c54b77ced9e45fc7d87e68b0683ea4954e6b31b2ce2f739937fb5acff67d7973fd495d48f906d7edba38a5f4fd07ca261507d89cbfcd6a65df87ee5f2af92ebff19f2e7c7be64e521b4cfd7f656f1ef309c5f368ed72f5599df566c8bdf2799fcdd6af93f86fe7cb19fa47c5437fa05eb437193bfe929e2d71728bf2830a84fa2c57cbbd02ebe9fb2f957c5fa7b4cfcf9c37e79f968edf237354bfc7704ce970d8dca93a89ccf6edac4efe13cff6eddff9fa93f7f545fae1f259bfcb657117f1dc1f964a341f93297f25b0dabf07d95e75f2597efb3e49f1ffa49ea43e1b35fa83c2a36f99aee72f47a84f28b0d83fa2429e4b70b6ce1f3699ebf4bdebf67d32f7fec91d6878a3d7fd35b8c7e57507ea1e058be4ccaf9768345fc7ccaf2edd6dbf719fee68ffdf2fad1b5e56f6a16f1ef08345f3618d52753319f4d92aeb00cdbc12093d91dd9c462273bc1fc9a9999718bccdb0543b3440c1e8b6e0f7f7290c7dc17837cd6addb76a9d60871849602e1463df99ac4b9d127d3f4dd35c2149134dec4ae51a1071bd40dedd7a84c41ec66de3f4619545738908e440907fda112ffbe294ff7fbc0537484d1664a83d3e480af2d616f1e400e830f82d20739e042451cb2abd5ae592f0f3c973e520c636476f5e8182b8add00824e12fe88ccd563f4e4f0527e0eb968593d29057b4144834167479e1c64c97249550f7257cc4fbc4dc45e180e2f92cd5ce14d02376bff150c6ead57b442b41e7ad08f01f1bbddfef4e0d2cbaa3c8dba61fc427a2282dd2a737223ab6132332e2d332289832e5b2c420a8b272fa93fd2dafd3b8988447c9bafdcef6f6315c6892241a91a5489658c012c72aa9b0407d23a665e6553d4ee7a3e1c3306118307bd913a6690f6da02e2524c21c7d632424118059448a049d15fa34db977a02b9f973617240f44313b54cc6e1301d7de2315af940cf4d2287d15ea284caced941a7482361c79d82492e0a17ec24f543c127894d9843e0d28eb2b9318c02198b00127a7dc55106708e0f0be4356218232dc518a74213aa4ea0ea930eae08ee167d9be005f07f480f1e011c042a51800f0ede201f997ae4ff880454ab8d74b6ff7d922781fa2f49e1671bb84ad03a3ec70ddce9fff460e528a006841752b6dc01b873d7e8e458932adabe9eac01e2e4e27a54a2e911505a545afee4c16d77b6ba00a0d0cc6ae5810f1a9e23aa83819a3290190598fac82403134cb8cbc3ed35bd6cbe66a276c90841eaf5eda46e522f941e8be6301effdcd4503b7ec7d6be3e5de5c39e3d88e6cb771a85f6fe950152d16baaecb994ec3e7e98f6878d85c84b65541bbc768420aeb7d29ff91e7b0a619de15a3ae380970482d3d009d6805bcb7ce46f86bf4f7525034218981765d867a04b944ad558dce90ee7db26842105cc231105be12a81b2e8f0ffc7ef645d46b58a2806aaa260c743856fc75c8bfb33805e25c529781b3e8d5c6537afe4093976ae15dd5d8b24670e8294706c7569e1f7873f3f26b16d8d1ff0b5e6eced66bdb0df232eda3cb3d31f30f80a3bd6e3eab926e1af112587b156373fea8c8aa0106a930ab57466c4910acd0e0d5ccfbcb8f86bdc4bb4a21c802a98dc0b016fcf5ba08e5909c755b7a10551bb0c8ad8a7314db4300e70b4380ef229eb754a82de67ca4d8a76d0a895149cc3d9591b20fe1a77e38de21799896e225e9be7e9aecf2c5c67223780328b6e732eb8c937244ca7ac1eca18b44d8e0761f34817f7ae6d9078318c4961ca3f57e58b4472b406c82ad3adaf47e99087cb62d5911c0a0a6ca341f914e20abbf0084203d41690993891d0c005cfb6eb85b227eb42bd253aed49b92751ffb4aa9a174327a30ce9e44b02b4a2aa8648a1dd9e48e3b3b6360c1e8d33eb6dcb2d47c86b40e3ca73b4f05680db39f63c82a987f73430f8e939bf8782a16d8941851078573ee2210768febf2b5f758aacd0e42f71b0c2306a97cfdec2bf617421dae60fa76fcc9fe0fa46aead0d0dca06add8a0df0c985d33149091bfabf3d17c205a0e7a6da07ab58a14eaa1034234793aa522208fc32cf81ba08e2fe19878d9bee0148a25feccd7dfbdf4446bc50ffc1471db990b7edc868c4374d653ba9f4afacbb98b7f480de17da8f21d43684b5866476e2efe2e25e18c29d1c44cf6fc49d1e1c264a31ffd795b33073d6491775fc4dcefb49892f140172c8453644797f8965d29c526bcd0d4ec19607eb81e3b5c95086e3d4072e783d14f9d2d2ffc3c7c76cfc57afc3abd8689316f4ce49700f3393b8044ab962902091fbbc8971292a7ceb079a733879d15d5e41e28dbd65eb677a9c808bcb3cd9d42688edd4cd163bb32a5e9bcb3de7f7dccf86da7fe733c719d0e10effe0cae1ba06bb387b4fc4a9c086da259788363dbc6470b86fc6e8cab1842d48022b0f0fb0fd989002b376460b60e713a46428a327023d9a8d3632ab632ac8a8c058b2633be309396eb790829d46875b0ef2a0c8fd7dc4ca42a5d966f00b183661dce04471a8341d2059c89c2356fc9993060322bf6c5a72184cd66a02700b3b3307064c7b6f64913c0ed6706b09594c956d91ca18c52212e2563980e333fd21aee57e296c039477692e60ac523d73b2e40dab3d9fe2f6d88b78fbe297c0b6f626809cdabb8269163eb1a51795236e8363f2d64a314a0902a7c0f68d9e8bddbb88f8f8dfebdd1e436e03241432678cda0cb341b8fa18ebe5cc8452c1bbdb51e20b62ee361fc68854499a16b7492e138c4fde3c6835870fa05c8df602c22510b9f2027b748230ed5892b2126b525be81bfce08c564298cae96770983474111d68882eb977e0dbad9ef0d465d62ff4402faac1c1b5db3a27e4373dc02155b37ec81e76f76895cd18b6e53ed570d8528f494d104f7c8dab71c29334a6169a062b50fd10b684b195c03c2462f48414cf9e9ec52c1788e30714f60425df13736e8a50bca4231b8f3721b05e40361ea411c4942f054d32fa26d4016d7b99dc00e71de2e2438500d3685d77202aeffe39cd9c77fd786833cc2586710076c3a076cd46f58a62024d7f99862937c24cd40d7a9c011876bd2ed20e311868dfefdbdc2aa5f8c956ab268092408af2f6cd0dded0f17d2f964bff3b707c3065d1eaa3b63bf823771cb56e1941a8e61a3df141160bc03e73a5fc221ed345b9f2c8c08929bcc9b7534d746c2f51b45a2e696bac155ae94fa5c55913792b3b9a4e8e4192c0297a525aa449308c02c57fd9ad05689a5b5a8bb884596873efb76c0866bea226e026bef6c1300f5aa38311b4087e1b6cf1ec748b6ab21a906049608e4db9854916644947e8a28bae99179b1ee6a3ecface33c61436b05e50c10eb3c0f1a174311233edce70c2ecbb5195673ec81f4682fea4fb5faec8df3031f4af0b28ee67964a87b52553fdfbe097f8564ed1f100a50030d90d00abc6807088d399f49f1ba2c0578f39af3c607906d91c951e287b8dc01111adbbff63907d4b3f6ea5bd35863199067b19fe5ec83547f3294b96290b60041965d46b6f51f57628154be4d7e9f8b9c78e4cd75e92cc3e943db60dd295fab2a31c08d0b84e68b58325a98e5b2956fa31dc5a592ac6a19859d2e1289552a92155aba20d460fd3b3317c665ed5bf0d7c24286588d4e74cd29b369fa4038b20eb36b75ab00b887f9c92923bdc37e644fb9a46811ce06e4a6a33e504ec04eb635d389ec9c3e38aeb6e9154a659d60306a2ee67b6d3f9e76a70670e480b73c1dae30435d72313d8f8235609f5249482789b0482ff4bb08ec0054d281dbc4d8e189f4640b2bfd01782cfa2c0889766da1ace8c75bb9a3fbd10eeb58b60bfa933e92e65aa7a9f7b2b44450cc7034a091c0b20d17adbf9a955cb8a8502cf6f601ebf897ae8d836d8b605922bd0e2e45ec886855b7e54c10eb14922b5e1c8e524eab333d7baefbaa296a3fae7e7496fb71bd4e3e8c572582ea6874edcb6af4e42a5628a0d795cb706c24a56095d27de61bae04f4d0a649550938181dfd92a44e0725c98842fc22c73eada8e0e95d503f30949070286406c7f49177edc64acbde43049aee90172e4552846c34ad1bd74ed6806a68ae2bd306ae11d17b0d76b489e39205ee24a6a3f3ec64ab0605987de42aac77db071a8a4372f6d7a9f6f514b356bf9926671cb9f13dc82aab4577d1b9db14dd478634ee60b06a7595bea480cfcf016d05b8033890f55c44da9f4c2345c34e538837246c2aef8f7d8c54d05dec548aea7d5c5ee88613f93f0e6321ee63415c7d0ef5b7f3e477916392a6e216f202c009a5513ac4956b681b893777001f24b59e72c784f60950f94da54c03b08b5d8144b2363c3f2db47c0dac2cc75e99a7336e9615aad86a1aa421059a258d81f17d3def102763dae22c3c910db1c1d1f16b8ea215f77287f7cd5f166e6df758efa32b6396129bb87c185d19ae0d53ffe3a14757867dbc5d7bd616397bf83c283a4466bf6b04396e169d51dd090d9155e96aeec8cfac75029f7de13592bac263b94559660a65729f2e81e7deaa4a99d0d8b950f4e5b4d53ad8844607bfb3b66b9f19e794dbda8f3ac0dac958625324cd8452600deaac7cf554e67fe958610efa5ba3bed03734176df9ba4b399816c1b3c5c49a46ca66f0daec51ee8dae96a069d854a454437fe9e18c9c145169002abed007eb84c0a236def79187ce01b815c29d8cc83d7d62050418d0eec2779f4dc381e1f4b57fe486de842cc877d84765b6f89c711562919c92b1c1ede2bdae0edd750f557455d750ad734c4b569923c3f65bfb89a985509a7444e6f939a2988d0df4f91c595f21f228b0f59a8c09ca95a783ed1ff7208cc9a730ff31f4d8a729dd63624a076857a31fe2a83da5d330ded84bfa6831bdd536931a679ba0b9a0c58f3b5d8f5bd6334e46ff4a6bf5424a22a59d441b103acf8bf07c7cf175d56b919a45ebc352aa2190e0e2f719111d67a3b6ae0761144c90bb696b6c84bb7f8957edde287df6e7e7f0bf818aea31ca8fce4c8a46a4722c21fe338f2f2075a3ebe17228a0c515f49b4a1a460015d4fa216ed3b5ea5a75767a365d5bcf4acfd6b3ebb0f4adfab61e9b9e5d6fa567d3d9f46df4767dbbae4dcfa26febb1e9d97ad67ac3f63a91fece87a1e9531ca3d0f32d3e9820d16accccfea27d5fd1d7cda645120417f9a07b48a389650edfb9027fab1dc7b1a1335ce2663754a6265b3fe8d8e58c999b6cb18980b3775675b081335643eb458ef6dfd41dfe5ab4e855c225fba2e421102f8ceffdd02b23bb9f0825626a5c43ef2ba154b19b6bfc08f6ab119316f210e7a437561793ee53ac3aad6dd29bc4537529aad391593ed68684be9fa2a9c03fc0fb49030432d1bf5dbfcccae44b4e366677764fec9d29a3b04d29c1473854c216ef3dcff6b4b1e2204b61d37afefef17d259950f446d832a1283443b79d54db8d3f0f5ae217a5d9077fd095f6372b47d2e7e399b286ce37d9f5a9bbe00c6b93fe210a04fe94756ccc7d6b7b3d14de175efdc167beafb9c11f214be8c7f4afe22573d38091e5265d7216a631d376627afdac8ed71416a8f82b132d18dd44f7d5aca2d6dd2e407a62954caa327106469b1c8782194845b00c28f4115aefebce8f57a4933348bc67a45044447f6abcda62a1333bf88142754db17a587d461089656e92c4ecb9494aec787c5ac09f8cc08885745a93a389240d49810ea96149fee00f7466ead682d746eb37aefee0833f3afa64ea4975ce4682a3b6d145000cc21ffa8c66c1ae645148851050183e42c3b3be467fe6facbd2433a3f8c0f7eaaa17b26a6af2e843f34b5a8ae4d24330af52c58d5d239b54727caf548f21615c2fe9982002d5c22e419078b70168468bd4c70c458ab03d114be27eb6030cd53afb0704a217e37c1e80bcf98083bbff2f993cb58ea1f777260fb4a977a3de8efeee02628cc42c80d8f8fd801295b5ed164dd4037c689288a833646f490fd1931a35edd73b284deb839a689b0b09828ed0c7c75e5b397428608bea67747143938ad6e9a10e441e4c646901c3c18cb394e43417af20984fe89f46323cbec1be177271938113b85550d5982645799854a771a7b148feb5043138c39e1deaada9b3045ef16272e85d55adfdc318a09e16c8e446bb3da08b9691144d26cf028af4dea234a4e89ea97b25bbb6a00c5017397689e33225de6a13b6fb5b3d951ac4cf96bcddc82580ce8186854330fc55ffead896c0e3580497c9996a7f7b0b25928055cf05068abd45f2dc07f47d48c113f6ac9990d9731c9dfcc6d25bacde073208066adcf878c98a137aacc4daed6554a944d73dc1f738fe1abc4fd375770ec619db122a6c1aa045388119d14c2812b6ec7da3a69e2bad1c07dbff15d8a4233073c5cfea12fef0d90eb1247f0a2ee6106efe1e9494bff4f55b8408aca2ae8d3355aa178d18f2266405fa8a593e81b4d73acb40ce2b83226affdf9d33108e68020399f23338f07d39be89bac982b43aadb89d9b444cca84b88b8083f7098c65dc1a869c290fc5e12995f189cfded3187f4b316cc280e95192358ba281fc4babf1b10d72506a22e9c2d660ac62918a3222d8294a79b870b863082ee90a95f62a959cf3b53c082ff90a4ab19b99ba2a180eb240e57fc541c9210bd06c58115a6dc32933ca04499931a74897997923ff29bcbf0532d1b9b6d78c14ca4f37a023c947581902602542af65e7617f10832a08f9f8aab4d6e5a8d1516bc1ac68316b304ab81c771170e5ff4030637f038244faad5212a78c358d402b938a68139fbb948672f878dc94f25b8195607e49f17adb37d4de85e57fc00fd11b48c1ac5dc95ac67e4d0d770aff1c006a7f0ee317dfe4fd2e34e5a9104f97a1673ea13e91e80152c1b4e25ce82304ca8d0a523968a575a207084cdc778ee714e28a2678a4c17cb40b02843f64049541109fe64defb2792218659a0dc73762cf9a1131f15b86608bf1fac1787d876b12800d4fba3aaa749059d79e2efb8a2ceb04aabbb261674ab990fb3750256908c119652b8ca9d3ee46d5b9d3c1758a7a85c1a2b7d2a9876c1d67db73ac16c0c743f762ba143710d950dffc4b91a0b6f6b0086fdfe9a4216c53a97f508fa2caf6fa68a9304128aad1da114c568f60a09339172292a5b9902898bd09d239f7d68202c07e16645da59cab743c7b293e65a06262422d33c46c29e31af86d2b159347b58c63773381eb81f83c88c01b82ce3400fa77d10ffc56d6785bedb69f53bf20513bb2036df70c88444a802411195a6a9c22c292fcdbe24836e8f2f7f7350a2a70477a56ac23ef6213e717781b51bb03c6e087af10a17b8c0f6aedbb80f7e276f36e84b8ce652660a3a52be46292c2115d5a2cfcf5e9640849249b73b42f8a87efc581d482565289677cb226d52448921f0f6142c85bead437805cd43f21db7ea7e857f0b102cd6656ac9b0cd653752eebcb33e6e6fe214ce80c4ca91f4dfaac862e09424145e84a78aa5682ca785698a8f6fe39079a00f74f09bd0aac249fe33d0d1299aca23ee5c2fbeb93789f429108957af3657671c3553daa8a4a9318cc5f1403b06b2eac034d45f971cd4eacf09a491fa4d3ebc3558f3498bbb5d44c66585b8eafab7a1b08ce6ee7fa4ae130256b5d55be03254fe845c2369753111a01d20488e850c31266818dab02fc74a91580010193425e2cadab371b15a9089271ad3e67ff454667a8b9da66afaa6c074173bc1e78620a6438d24a0aa7eaf12124f741b6a49728a74acde314ca133c1c01e0100a56d361b101c552cce06e62ef6d2a8c86f0bd85cf163fa23ff1b19646e07130da8d8676d1aacbed933aa467f7a08819230821fa7a0fa660a2fa1c713c61008ad5c1d4e24c0ed3e397285799637e2e1ed6de3daea7ce59472a1a142f64e19a14e21603bf005922182cafd6aba329327d174dfa2159ce62cd8e284209d32120b82b9b00d31189082e6937bf5cb15bec3ac3c00fc49019f7d97f1b7167f68b620b61baec2ce64710063fc11b06a6ea6308afbf41ae894971f49d64e21281313873ce1b2702a390c166d077f7d4bc98c745c2728fa4a528af0584408871ba73bb40cd28bb3f638f50ad3200251151cf1b8412a652d983803b29648bae0a85ca7e6e8b1028839d6310ad12c09e51e8ab32b8d5050b4dd0e9a9ad35b9ee2d2d15f8e61d60119b189e8ca029d0abe735c3394c0e4321fa01035b0e456b79d55eae9fb95a2c9612d40b62375cd3ec2366f8e91ceb5933522d86d6a1b7020e5a5e8a2dad49e53ff25f0886eaf4d1add0de428d7b922d620abba94e511ee890f375973313ccb40697c4a7d16390c20e0204ea3e6c08443d47a882e520c00d7b7399c2518a12bae3808ed45c573472c19fbcea42cb5ab045e24fe42b8b2889b966ebb532265a4aea84b313339d4ce40f4ac791bcf8c5e8df373056b92397599dfd8d7da6edaf3005133171672397618e16b707e08ada99bb16f80832e0dec9306a70eea2910d6bc5a6667e32f36850a78f39a5518252b6c5f14e44026c636ace9bc7534c8e2119661be9402b0f81780d160139957e6883390c18d06638fb5b17619a6e1f81750b1940150e189d6418848a5c02f2cc14449e117068c5445589527abbba77f52ea297e15a2a19d6ff58696e57afba30f35e9394341ea6284e444ed9eb8fefacafbe92dffed9416bc11fd66763e232add851a058b44d201c563378b04becfd9feafb4b1d3a068ec2cfde67cdba7b6ff826055c0c79e2b9ecc44f5062c0ef9636c8588da82389722f40bdce89f626cecf8c0c9c1401083c02266cb9d17e4248186d043468123e828b81fb5a05408f20d964d4a9726abd82884dc28f6ed021ad66af27aef0b2bb6379fd847d4eefc461ea61af8dc284161773885d3f7400e622a1ce8d26fe921a9a081f8f6a5e323ece28f64426feb321e57b7bc2c9fe3d97c66e69ab78e6c35f246163320e019bfc5f5fbeea7f5f9a7a5f54e4419c69cc2f3935019278eb422f70324c599c370de8edf327bfda64274ee994bfca5b00bf047a71e8bc654e61d4d6ac13d2464584e118b64a73e0f813c1e7752926706cd7604cab19aa57c5560c51cbb3dd2342956e45c4979570409d1a405080e5630fcf1a52aa61e38ad41985950ac541de82a91613443c00e0baa6c56d60da476e1bab5816ba761fcfdad2f806043842aa3bae72ce1c717192fdd9b396f103060af4fda710ac6e88d59d1c3d0a990ae2e2f384c735e48cb44f01ec4e284736b6796cf762cb68e94f0cdd1f2cfb872d2f77c5b89b512342eaafeacbd9e6436cb6d882e58c6664a6fc25326e1f7c77e3a81a9f12f321fcffa4d19b2ca3738241b8e600853c659c59039ee85dadf85639010cd03bf98816f5fb4329fd8697a3bc45de8658090e16d44c071ced240c5e083504646d6b1c9136048dc8f9d0ae1644e450b17fb4cb553794a861fb7fe7ef1a783ccd4162e96b20e37f0075250a34ba7432879fda59ce8b0d4391eeb130df42d8063ce47d6cb7feb94252871d56d75045e1e7274d438b8b75cdadd1ed4b9e49be41285839ee69d6a2a1ca9c1f49165c18b66040ba4292f0fa1ecb2d8e52efb8829f300b335ba32929b8698ece5e22466f9c487ed0c6b1c6e2a8db245b0337491d9e73c89357000a23f5545de72a7614c27446dbc7ea7e1c0cb213ee856bc4f1594e8d36ea2611aa2be70da5ed382276f056f2b201408a09d3b9e1fac31059a306558d7b688c306934d8dfdb68c354ce1fdca0c01c097c8254b28f0efabb25a5a75c81b0e1a6daa860f2797fbe6c38c2133967198534ea3635f894823fe90e15da14197af259e76dd6841d12015023a2dc6f90d0dfbba7de592802c2e909b0eb2f3d9dc3f3ea3e29588f42b768f5fee169c4c238ecf78281813e3e856d8c5089a33cb2a8ef39ebc30b17f3ab5464f0b8133260059cda3a5a192a838e597cd1f4fa9cbe4890f09c7d22772e97f450477f597c256b2f4bd5e96f29285b41073ef9ace1c87ee45cccf48532d2fcd32ef9865d01180b8617fdf09027db48617913f360cd77a1c424fb38ce046de0658e355c1727030d083b825223a9720af3c01dde8b6e3c5379ae908496ab439f00a0618a5cd5d506f76011c442bd0b1681baf3d4e84680d034e21ac3a1fdb59b6bc44e4d618aff8f2cf47428ffa12111df060e1333c2ea44a2881c6ad202270fb00ba759ee81038e56dd22a405113f9ed05c7739bb51f68d34a30f809b6689a2120bc994604a6cbb82d25ff4ecb5928c990355605f30c5979f4d5d70e3e1f021f059ef2f208d19ef756f6fe7d7aed8c5bb0df4ea9c3ddfa82a66e33bdeb634451cd9b32365d98bfb4e2a61b2ca227d52982345d6382db8d45bc7027d5215e3041e203552f60ae373fd7c460c600b2877963996a1a46cc66a7914cd9c0620bd90b69c40ddb58f60123fd20f8b5ce4cf6b84c0faa307c6b123e03bce25251bcb55860863d0fa7350c9cdd68c21336011dbe991b19af6500fa9583ce6c02d922db57b5a1bc88debf5c93d5c1beb78f83404cd7dbe3c7b77335eb777cde428d3aa28f9f8af48fede8ee6feb2922178fe8480e23ba632cadace06b765e13414e3165d40b6c8dd076a8a939dac0793f4a33d4c80fb41864c3038c7f02badd15625d4090324e072e08e6e5e582eb1690ef9c380c7b221b393e35eaab2f80c9d4c0a33307440483e0413460461af8911a83fcb090b9f048f51cd45d96ab1b12d474a71f165006fefae54a18ead1742f991dead314417edb6d44f69652a624536506b2051f06a8294057e732119d923d9d52d2a9255c23ef738d2cb95e4d00f93ab3d63b522caa5f3567b5cb55f2adff5ceed9f2b78bf9f4f204cc924258c52fc31ed3cb973e7209e3945e3ebf287fb892c1b8620965a357dbcb7fc6f15e3e0ae6ad05ab95f9f96ceda35cdaeeda6380bc1a9065a850f29e3d18509497e3400765401de943b44417fed2bdaffb3ae043b63ac55ffaa40ed7f04b9acc82e2501fc28dfc1c9b2b4fb852c6455caf442943fae12265cc5fe9949445b45bd4290985943de9d5fb51161e8f994e4917c2beab5ded6ad795cf3ce4c3151e12a28706baec01081a886d6f4b9db5d24aa7bd1264b2f5c6e16c87e215dec8f72448c38277bfd79eb7647ffa2daf6f6e9c255bd6a96c49b09990f7c53758074fc085179a00f3eb7b144b73dd8c374530d9abc7e707e8e6c6591cce59c1d44b1dd992ae26c07c273222ba91ad6f3ed1cd2c0ccb43496257de0ef46a3e0cbde2219e9f3b8de64b9d2976d76f9ce502ed8676e30214da17fd4cb6a0c8961256be7c7223a58b715e3f40303ec1e5aaf927181b2333e3ebbc8fc3ce8945e1a6534e6465073e6475fcfbf58389719c71b8e7d7d12b164bde35b68f551c828d1456be6853c302d77fe66e8e6a005cfa5202d75ffedd387072cd94a0f881149d3eeee84f5cd1b93cd482da500b4cf0e48a0178369bcd66b3173bccb6940eb3f59e2af3e972c81eb3f2255b8ce3ddf9d2d52bbf537ec93e2af53637ad335bb2e52c9aee673c9070be74398ba6036958887999ef112303fa68d2813d647e06e84306a48199f13e62401a98e77083977920a1f76c4f27fb6c4f2f5ba713586dcc770f4363030fb2ff829b50251086099d6b9f5b31a08e6c49d1e1763f43e673246ccccbfc0de3783f3f0105e01d14d8c1abd3cf4700af60263371e78b5702454f36b76c396b839ff11dd8b2a0682f05e48eeee7c39cbc4fcac035f35f70d606a0dce995dcd18132047284f9334aee7cd34c72e74f98b55c7b0bf054f05b72750a7e29285b5c336f5a311fb3eaa6571386fad9d939cccecb0fb09782dca9f6202043ce55de2faf4b517826ada03bb8aeeaf2900e48d4964c2fdd33f11e859e73ce5a6b75a71e68a35592a3ef4f3bdbabd9dc8bde4d8ee3e6cb0b7d7901bb4ebd882fa0ed54ff06729cbcce053167038050948d98ba5dfafe137a253229d14fd1d256e7b3f57f2e084b7f7b6e4eeea33f3d0e9496729fec7af5f2d2de9717ee9b977b557af953fa974adc376febb826d0efa608cb9d929cacc4658eaec346bafc6e1e3031207f4a97cd37369f0936f457d3e7b7cd0d05532cb0b1281b2b51d8d8d8f8174e8a409a1bcdb6557777777777f72a5d26b84f0a32e1a673eeed56b67c0df914137f39d85720a93013690962274518bd44102be175241644831734905142931f5080e4880d279f7ce21bfdf2d0912efc48173b20892286c449cc8924261231880cc1a40b62434c902347e62c21d1e208122c4768508282faaa45016a68478b161d868eb44a30b4833444e260e59f60676527b223c590109810a0cb433c24c4874b5084878a6051c40812234a8c3031b28222234818092912c24548962242ba1419b25364c80d434668437e8a0c01a2c81023645b6a45b0102a822454a4cbea491128311821258809a1a1c811a129458a780dd96a6c8632849ab8b5480d350ccd7005115e52d2b1899530030ea519aa24e1e189c51891f1943043106e86263c3631ce76518ba8d25d5b5c3a845c5a84b86040c4354528e61a81902b08113184885c2144c48a1011288462449e0811194288880a8488a04088888f1011120809112134e44317e9aaa121570cb95203f53aa791da9d73ea1032b2c511aecb6bdb3152896e683284de30857a082268686736c4c90bcd8b1e94f07085879a3c0113244742d8608b12063902940a23c6083201951a8c5296d891c19458504da886903211a4368370a1c10825336451e398b9209020e1273b70b9fda4879ff030ce66df976326839c496e88d90c06e664598c51826464301982522507a111ec9011440c2e6a3088a289274142a4c0e70624b21a08e9d2451631a03901a50544a8800712bc645d8890f105172c533c519444114d96e050c30cb2315a60c8c08a2b55a20cc1824081099218918911823090ae780114529c20b1821f1d6c38220b43678c19607124c514256243f8b0430f0db2a42135f0624b152e1867422cf8a1871288400686ab0c1a6891c50a95256446007102253c4564349021690b2d54183141740410931c46b023fb2288185cd4601045134f8266524299b2760d9d925394d65929a5f47d02a1b28130f1978303422e802699e098a3a0400e9ca09862c1258d9e4c867400ba22c74e8ee872fb39677137777433309483942b72393cf12a433afccc66b3d9ece3994721222528f20dafb6d9cd2df6736feafe47a1b7e764e5eeb65d0c6c5f791231b9cfb61716bf83ccfc1b38bdf471a597d24f60db40917ecdc1cc5c73d0d76c369bcd66b3d96c36e3e1e1e1e1e1e1e1e1e199cd66b3d96c369bcd66b3d96ce6549cca13366592ddfcb265c735fcd2bb9d7ead36975d4629db4e1920a623819b33333c1ebe513a43a64e8f87c7783cfc86136d115b7f8ff139e7f4cf721ca5eef3136f2ebb974afdf26232a55e47ffeb80f954f77242f3ccce69fbc8dfb579fb3989a30fc2946c27ad3eff5336db4ca7a63377aeb2f1ada3b3e42f6dba91ee8447b380edcee709829d9bb2979959250e0557f1fb3b387fdab0e4383a63d1ba6f30c3cd28c9bcc4986c0713733a79309d35c5a45e644a33b8994d32d78831fcb401c8541a948389f21ab23b681e7e696366864c8c8539799de9a5c46d7583d38cbfe47ac5de5d2ef15849027d993cf6af18d33cedf994196fc2cae7b1f2c2d87a1d143f7029c8710dff6cc69de219f323400ae6d287fa8f8958369bcd66b3d96cd643cb78ca60405302310e1d3a82890082b59dc00b15e082a8bdbcbc948e008d2f25ca8376af91af44795d97b1eb2e8daecba3eb5ebbde9403b78f7e2f74cabf7e15e8945ffa964a905ba6037314d9d04c0b095c30b44451a54e88a43047798146a3d1e875a1bb0ad3649f0a7096b5322bb3322bb348ae5792db9bbc1eb38c4351316017f0133c6260f64eb27dd6590a70553f3bcb5056b4b7f9dbba1b057762e7119d3224c60f5e2cd98161a6d2e92d41f0921cd5414aa6c226c94457e4c047314b02b338c538db956fc33827b100578a3cc44b5cf9d2a8530d5a54a758322cc1903af9f2e2cd95f545a6c19c0593527665ca55b2414993638a488e1c42ca8628d505962282790a962282710c96228275a08f1c1dc88814120f151ea0ade56824ab8c3067590bb330eb50d8ce7a1196de95b0fccc5cc591cd090ae841460c7645a791605a5cd1842bbbd60db2a12e59aec852aef46658afc48ea17080bc3931251c4b2539b152064b11c13866e32ac9b2a29176544bb94ab6135996dfc9a38e8cb73dbd6edb733ce3386b5128c9d5d60a3257ab3f904dba919fcc51b87b86dac93c73f9254b9e1334cd9a83b99f2f27c8e9e8144f2c4cfcd9ede59555714e9ff5c5feef94fb7df1051dbdda7efedfe9be6d537677a73ae5af4366db3f55eb3bd32ca2dcfa0e7474e78c325efaa6fa498f0773cd9c2a9c2e37873ab98f0fe3783f3ff44abe1c1dc8a5517357ec0c171d363abd73e998e381dc781cdfe3c6e378ee71803e9a70600f1c9f03f48103fc1cefe30648737a06123e5bef5fc06affb767ebbdfb784f3db0da1bcffd09fcbe8f8e3020d8812fe06fa0fbd01bdce7f850aea28fe373242c8ebff123e37456986542ab9ee01d20c811aa704bc1ab1337964bbd2bbacfcce540231ef4dd5b40df15b886bec9c4d2fbc479299c6e093451ef76989d2fa58f07378435b1a782097cf9dcc797742a099bbaf4fde7c6bf3cc72c1cff028a15f41f9f99b53e32a5629ceee977c059379ed25fc159d26542b3240872870cc1e6070955b3472e9a14cb4f2e154fb894ba049253e48e7ff771b98fcb859a4053faf6eee3ac1e5d4569cc3c3b4bc67612078feae0b957261b4fbf939c35815c6583dc61039c53e408747496fbd08022aa03b0069884023948a2018a9cc8cd00458b4281e25f981e659da2624bb9f4c43dcde9b4bdfbd0f71f225cd62b29a3d1a50ebb94fa78a9d32efdd3c6f548eb953881ae11edf152251e73a7cf7f3a45dffb7c89ef00e42cffa1e714b9c3799023d0a7a23fb9a89875278203dd876ba8f75cfa373e66d5cbe3f85ede7b5e68a9a7572f603f7125379e3690abe8d306ea1405baf4fba77fe8d506b64fa768f70859495f8e1c67519fb291e31c511db264f3852d715dc3c2eeeeeeeeb4963898534d5783060de61a356ad08ca3d1581ba95819ab4851c3c26c443baab5b6176a47b55aad6624020e1a9a1b376ee4186b23152b631529462c39f83ffe6ab55acd68040ffe411064008cb5918a95b18a14e30800fe20001c802cbaa86dd9a2566323136427553a747cd07df041bb546c443b1a915aae578fae6a9a1c7b14652d8b2e6a5bb6a8c931521c028720036e954e8fb15e6722c1444207f3712882c7c35f044f85bef4b7d2b66d36363603301ac7d1bb186b23152b631529462c03e0124c60136ab55ae5b86de3b88d1b478e1381dc14d7c83f7ae90a0c11d6947000be295d2dacbf8979ce39ddfbc5ef32eb8699d9fa7bccde9cc038f3fb0dc02ccec54a5cee86c9b96c6e50dd7ec9f5ebd0636045cee572165b8b42b9ebf6bb152b7ffa534a69df7c3cb9e686039a5d976018730e347b62e7c2ccccec5cba8865274cfc50c1ccdcd5aefb6cadd46b7b3c6218e42e0d59e911434bd815704d82dea15320026623a69d98d90546ccb413b367c4ccb413b3c76cc4cc3c8515db253d66c576b5cbb918626209b31133b3cf403aadb1b0306c44b32766e78287a6c824b31133d3ac673bd4049ae912aa90393157affa579effcc89b91ce480dc6179e58b24274970f162ecb93cd4c595a12e862e0d5cafeb6fda320a60cb08c2071f00c08b789401c8828f3e00c10f050ec5342e92b23dc0a25f200e1c3764cd73d4b6241c1d745063a36d47d76eb50d691bb9497345ab031a3436a0510eb45891a3212313c36eeddb542b665821733a79ff22c77137596c4e50979ca02e8e65e88bd6e5212f9086bc38baa6eee63377aa3b27a69313d3712c1c672d0af59f4a7139319d5ec5745e3931d7e755d89cd80ed8591e9d13d3c989bd3ac537a6d329be39415dfaf99a5e3e27a8cbcd89edb8ae4e4e2c27e6dae914df39657f3931574eecc52327a84baf805cbe252f27a84b4e5052a7f88a5c2b27d66a9b067382babc5c26a04a57ca4fd3a3fa90c9924516d60712720feac3a445481f48c82857b98ae31a5f220647ad50422922e4b77247b7621867b60c3284210be9c759828426d9d54f1241f9010a153b45c2fa99a6122f2c3af4c8768a84f287a7931869220b7b091626ead74641475aa169db52d04458bfae42864b166ed20627c2fa99a81350382164438b46beb4c189500a410beb4723411664b8bdb77c50412b741184a048169ab6ae7e2e9ba2882c3471f4c49d9244d410d6cf652618d20ab7afa12419d20ae92783a42034d55afb8b2d45ad907e1c4692d0e4be02136049228b1914319f64c1a215d6cf9530099d18b79085f5dbe145a84514465a61fd188c27a169eed09392b5acf58a1eb8fedb153f70fd9364c1c50b5a689a1d510f5ce0982134c9160f48c8c2fa21404b68eaa02db468c9d80f5cc8c2fa9d8043284720206461fdb8cb2c34d18e7e5c861545b4c2fad5a02034d58e7e8d0408308ee0109ab68e7e3ce515723e035a4216d64f1625094d94d64ae9574a69adb5062b596421fd6c88084d95d62a9f06440e4921fd6ccc109a2aadd28facad9f69a395d64ab5d4ca61adb5d65b3fd662064b8042fa999a084dccddf91cb80e7a9f7a702b499ffc989d307174eddd5a578aa5cbbd04d065d9ecca3dba2c2b6ae2728cd32febeb70c5521fc1b9caebf6a51834e002f7debb50faee7930b1334616d5cdf4302f7f82f913cc09a4a1dfd1602cc8ee1d25d59062e8f9c2ec2f06afdbcb9b401afa1c802df9420374cd489f2b7f06bbaaa77d5c259ffb4cdef68bf968fc4d62ff74cd7de9db6ba1bab081fd7255bf4d9d681a5cc103df55f23bd0e4e00a37ae920f24ec800bc2f68fcb595c7dd59e2b436e047f947e689ecf95d5e52a2067bd3c8551d94dba636d312dba21057215cd592fb3e6aced9361fda88fab7e94be6edfcf955f419a16ea0feeeb44ea945c61d25c55b7ba7d0b52062c88d20a43c0bd0f1070b02506adb0d59a093930047e654b925658eb4f05aa3e74a4dda28be4acede5d724676d1f4d0bdb73bfcd249a16ea735f9fa3ad8b426f5f4572554fa499d472169024ca283a7296ac21398b657474169010482852da953ed287ba9c7553e38e264da43e2ce338da952f4759eb56bb64900c32c85802ad209fbb016a1fa68d2ce3b6d6650f40200384f6cc084caca3b943f58a039203b303b7bf7e3309d73890ff38ccf5d35858d5bf4549174b7a0cfac3ed7797bb5c0e8ab45f52d5cf71afa31c57ec1cb75f72070078041980e6616e1cb87bb8ad82d9c3f47124ee6295ed23ae31c5cce89cddddb72b5618a3906cedf6fc6d333dfdb6274f3659afe8dbbffed5afcac8b0227d7dd5a9b77b9da038692ff74904d7740cf34ea05ec977a7d918bdc8fd0a09590ac0a587bce060a6dbc0538106a545528a3a2f85aef20a8de6d548c1bb9407e8a3c97c1fddd13c1dd58e3aefb47d0736683a1b363c1edbf66d4fb6a25ebda96e9f7c2579c91dc631d12057acb04dd6e5fa773e3addaab01f4de6ffe8fef4c37b98c7d1d197dce13f720421c96a2d52d5fe734d0c907c654fa79408d15e0aad42ab70ba12a42fea23821fb983eec0ad45b258d21a24dd611cfa4d7bb8ed2fd2d76d1e342c74dd4f0f4ffe48a020f9f3a453ef9f4936739928cad1449a4992dd4fdb06d29daf5e1fc37260cb609d7298c34ca07bf075dbab57737bb20d318bc2627e93314ec93e713717bcb81dc1d0249835b99975e282ec2a2a858f263d4c7f7a1fde777f027d9cdef4e204ba00ca3f367540ca7ee42be9c8c6878f263d3a1fddb3f700f9a701c9fd03e4cf767d859b01d4f5eee3d0f471f89e03b6973b1e0fe97ab92ef931ddf76d13e41ee6935b4deacfe139607bcfe1a5d097825b927afddb5e9b6b0c5b029b366e21a804f04117004f0593aaa3b05ed1c80772e5bb30814ef54b9375a7af1e67f5d397b3681cbc000c275aeba9f5396799be82620650577e0fa7a48be52b72af9be4f6a3d09246b69064576424d9953a5ecfe5ae0b4165abde7a5d342b9cc01f4deaf3edf16ab54218f047f730a63f7d8fee6140aeb55dae774bc235fdfe7257a7409840401388848e7b4545e83caf565895cdfad5981356acb05b6155f6269d5961f67b8413d7fd09a4a9200a0af0ae07d95fc2e56158ef615ea430113c0fe645f0685838bdf73d4eef9d40570fef61401fdd7b20d77295c9a6935f0539255ce363d80dec9e09f60b66e3d1b0607aef7b747faa27afd612bc15744cdf3d8549496192c2248c524abdfb6e6e2a121b940adb64ee5fe9bae7a530e79c144661a65577d395ae69d5791ee3bd896dedd7d744943fbf5f9dea11fb35bba757136c8eb37302b1aa7ff6f42b49bfe45cf99ffc3daf0140aeec86c9276cf7f4ab535f27e9147dbdc8296ce93291169f4de6cd85fd9c12c6d9be9f6b713d9c4b0c0fc376eea23330820a2451e03002242bc2ed6b295cd3bf1d398bbb417173f53bcc5be43887f926e31ae949120ceba0586be0f7a04e635bd10a9bcc55fd5446619d32dd780c78b927cccb1e8f1b2136d9cd8ccb4445b46b2f3b9172c44d415edf9ef81763759a4870936d4534b0227db13c1a1656a1e95b2040962d302abe68b55a61c7f278d0ac60fa163ca42651201144431965841de82e57357dd1177dc540e9eb728d714dcbdf5c51ae7c2aaf297a6e153eb7dd95a557624bb935106e0cd62b7f26da5a384903b8f2c58aa443870d1b333315767b936db239dde5ac97b3baef6f298cd39d09a9d4d20525884b26260688cd8dac721b8001865e756003bcfa806c0531d2ea9574c924adea972f97abdabb7b646c4c8c057f586b63629e63a6f3128ec1645146d8481b7dc61ed7eba886d4492daed63a724bc66da68e1287fbfe2e225912a8862b61dc15c9644f64f5b9af77e09a6e1e8480f90054f3b92ec6998159fd448f63108c4b6d1cc791699e8d8eabdf3de39440dec1abfacc29679dde890a6e921dd7cb83ae228d70aa7b255dd208afa4134ec93a2565bd923f9c72227f7c1c693f60defbd1a407cc7bffe3f41d10e6ec38d22c8732df7f1e34a2a620127b8cd9ade63d5227b5f3128ec1645146d848eb17fdd5475df3d60d1cdbe8ac1e39b6a4ddee9ff6f161a3ee25b6daafc751f6f44abee4ab5f26e9558f462dfb1b06db0188071f7c7c8aac286b359f991565ed89232ae31423142bcada58cb81a3836fc6d7c0d1b91256943529dd9d43c93c8ead54a3836db332331bc87c1c5a6a8a01e16432799e0763348e636da46265ac22c58805866d0cc7d46ab51ab351cc8c8eadfc193c43666806b35108546430ca5ae94a2903992da8d44d17253de910cd08200000007317000020100a0c04499424398c6361f70114000d64923a5442308e8b227138180a055114c4303402210c0221008330346418c93c169306e51743d7162e48093c7a7ccc0c040489052ce4a9c79c3a6fd6e6c8b1e575245b95aed0693891685cf70dddbaa72a680ba7c2aa53548e1916cb4f406ab8a0b6e669c49fce6a9422415e158b9ef715a447e0f9a3b41f7a1be92c844d0a6eb23cc87d1e38604b9f97a6de536324646f0bae6bd31c18478b3c1ae0322dd3e2ca3c28443a7a5e6219166f454a77ef9a0f7c0b0dc531ebbec82334408998e1bdba552f528091277ee44ae72141edc2db3489a3b2f7447575a3349605d7b7c33d046fe0d9abd175c20db3279360c118163b140ebeeefd46cdef6af3b9fe14f8fe5061b9b7713c21491fb8d08724e3d8ba17e1ca0c7162367cb9cbb228d076c0439b05bb81923994b4f206fe862d110988cebb6da37d1b1c82bbec6d57333bd31479569021ae96857a13cdd28bb7935e86d3d613a81063e81ad0742ef091b793ff035c9880132661c7e5196e04f11313cf00122bf1fba04c6294dd773f644a8416b756b21aae45262cea06f6e83201ef0580fa0e3da1d53229f4c52a49d7dca5e3f6c29aadb82ee96ca67102fad8646334ad59a65d828b08c45e1a3ce733d709705424602e73ab4ccd1d091ea7b0f5dbd8d9b25bb2e2e0997ca0f6bfa01b444672f35c44c88654fee3025bbb7ed3e3bfa962842abbfe463ff7c3c0e01943977b85b5c36284122ed773f623b0c46f9d2e9b7d49e6011978a70042a6d1a0db59a18033746e710a96d755706443c03d7c4654711a16c453551c56c762f9ae9bda84972c5c14ca8cc710d7a0ef5e001740a3c74875081e750aa816414509e78379a5e4eec70d0b0991cbced203d361638cbf16b740bef7b049c9526bb55185ba1b29c75e167330d2a3aa0eed50704d0a0cc674925b14aad141c826181d6e624d67365c81fbf76da16f8138ab89338bddcc96562ffa1fec7ed8bfa1e8c021f8303844dd552ac7c3f9e348febc175eae94c5ebe351606715a68ebfabcee57be8ce944af8571480c491582f3c275ce29c950b1829510efab5644ae27c6a85f9b27d1a29efb817332a0241abb3284886ec6d671b8e7698f86e93a48125b36b077b02b47e8766654d99773cbfa21345fd277c23b9b6a151b10419873d5d01adfce37dec86e412300875911c4f9d9b20bd742735e65a95c788d217b2af49c182aa2171d998cbfb83c93bafb43328cda88b8ee678cbeae663b1d834cbc1981b032890e0eacfb8b4960e292c52acee8c6022c1ff2f4c4668515f095ff995820234a9149a8ff0664534705ef73e09ee5f8f7e913d50a5c4cdf7e3c115407109e29b90aee8b43e911a25b138c5d3077e6a409937025d044da935e08b360ab8d147789438138f6a2accffb332066cfe3f8b3fb794b0c520371cc540148a01c6c7e2b60a2a3db9e6caabd5e75bd5688e11868b8c7c50674225bb9731f2a296e9dbf796823622187124a5b16441e1e53c659e5efaef2402faf0bb7fe76f5a3d146779fce0d303722e0a1a86c4a3267eb4e09dd043baec6186f7f18637186f8d6189556349081b7dbc8267fd231e48a0681af8b1e7b75292b8e27e1cb1563c839faec8963d12fe4734a824a1bf4bf4fe991a589ef01aa0846a46892b5dabe769f4968bab649cc42d69326161f21002fbd3b8c637c1d655ebd3a6c437ea775313bb742f17534da2d882ded4acf38336e92e51ea570cbb7db620c8ba1dc6c2461d9c7ed0097cac20b3796b2e2c71a95316488d5deef6eccaa41b2a474aa39c4a6d2002845dd7fc02870e4a07c13dc0b669b11e17a464257f2c7053b8c5fc6dd6a2493c5911e10d333c28f6d2a033c7ebe1ceee2d45305981c171ef87679c49b6cc60083c7691811642dda6748b13696dfce294bb8d24f3c18fed1640a59403aee8fcf6cb60cb2ec01911deee2225b5ef3b3fc9da7226406549637fc4d5d9726cf6bcb56542234db4bbef085048a64403a6ceac8bebab111358ea620d291796d26bedf057dd077073a9bb4a0b53dc346d92485f010562f6442a7f2a0b15432f9a5eb8462a6854164c8a7a432c23c823357c58195fff9d06d3801f95df2859401c28c831e16a4b55cf7600eb066c94b07ba9768b06a8399d45449287d94b3d9965d13dda909ec903862252e18182d026a01729cb3a2fc8fbe756c4cda4a0187d49e8fb9ade9efa5f5e0bfa7ea0e0c7e5b8220de4e4ef7d8bee1dc397aeeb0f28f0ab5db4e5d290fa21d301738acc996b806b9f7f6e28b57764e878044252144ec57325edc17836b6ff1e7bf6150c1f38b95fd48cf873af37286cf0aed77370abaf1911eb71690bc4e8760881150a1a2b34e8b1864d9def85a180f57c19fe55a30c9c5a2b5a63b1d8e4113176826b35dd5879254da5dfb345d58e899c2c9b7fcf57349a52e6abd3c875951eed58385b995525082b3cd98c3188a7ae9e5c3b59bd199b911d1aaae4360c9925a06db53ac95c0b10bbfd39f7c15a60fb6a51ecc946a2ca15126526a7d056da787cbcbce5031439061603a59c2ea64caa00e3474b9e10ed415efee00282f96114c558c4d1a38cf506e8f0a42acd678d654c450a1706c6ad94666c32e0bb1e6f016591b3e1488c67fb08319b8048b8e62c663c1a02288b384ba5305b111e69b6832152da652f03e949376a9459e202a320920c604b691f69318e2d75ca518bbaa666e92593c1293ad7ff28205168668e65dd3844735985ecb97128f4a3d1631def3dda6bb53f53d81b180de5af45c42c3bc33c613a5d54cccd095a09d36c883943a5583624605466e6e95a17a671e8de0098f82c30854f6a1e2a3612c53a57e028e62d52a14f46914e9090e8214984a7259eb0d07e0bc85647230802eac0cbe1003cfcc2379785e3312c745c35e403afbc325bc125b762153f36655392c72b3982d76dab05678e228508411fba4979b7c0ce42d90d580ebd18a88c1ae0d00d4699dccdeee9fa0a591fae61ef7653c47ad6d3ad0eb3a0e11115f95d680729a5c2dc10ae5076d8cb3ea597c76d30af18ad9f5c12926099ab92c4b85116f43931fadca27d7b925cd6f4b17c91596e131ed5c0ba4a419cf7be7e7188b5727a04f4bdcbdc32b935361346de795f72e87eb899f4b337759f46da0771bb137322b3de1cacb168d52b9c7877dc2fb4c92e4714157604fdce46a211db9a4541ac41ed541c340c04e491a911f67443171a3a53add8d523e0421db140f60d4048c1949c9c9a7b949118bf9e6e49217af5081f164b1e88d74bbe93070042006079c2b552769aa1109f0a8bc8930d426b4c99abc77b52cb4b117a26370c112285903cb5d5f7c63e7c03c147f1117d8490aa470894282a05ac5d444291a6eeb6164b21ab7a84bb05819fdb632ad59aafaa47e87eae282f02595701eceb899595fc8faa1ee164265c1f4b8d980d39fe0503bcc4723b438aae15783d453b8e37702f7324819aec6f38ea888227bd387c5626eb51a662eee1228676e5666df5c365e9bbad1e81a6571b75758d60b38c076251688aa23f88ad58ae3354f57c8ae3caf3ef0ea605a10941558310033a5db13dc5a84634f25980993b7fdfd8d990ed7f1dc3ea116271824fd410208a2aae55a6b0048db2ff89ccdc5b061de38b380e82fb669b060e648c3e825d68d240073baf5b1a92ad41536ef0393e4658a5c0701f3d6a8b8d87ca1e08a19a26bb14961075c11c5ba2ffa9c4e5740ef305d583d11dd501254a6e1830795841d6d49f930d70d1b36e0c15e9c49c9a5d8d496fbe3268ec5618e5c4213e8a6f41181b90ce04e58525d0274a27ab4b00c080fe5ad3ebabcc5c284f0babcb99921896f0fb1a95ea6e06c28253e81cef92d3e71a14c227f65ff526a39047a87e4108305e090f0b4b70f840fd310bf1b282dec1124accbfa80816d62a2be1c3bcfd5307df8e6c0e53f0cee81926f466aaedd5d591f52c2c41efa58cc110b365ac1561493f08cdec8c5b1ccd31fb7334344cf2fa1f1e5173112275a646d37994b1952614f2fe23c22b584cce043df9e22f12594a841d8174c50dd56a1bc6f02db1b27b0f1ac112d0c03d1558c311e097f6c802a7c72169c354399c9b35169620b26c1bf4765fb050b428e5fa543e702f45712703ffec20c56525d14140a2231067bc21681ca46d254e7ac18bb3620a5858028dfd9540e3c674ba32a4ddb69d1e8f1dd18de0d18f8a69c84eeab7eb27ef949f9a98065237f3348b201dc294a607660224258604042e6c9431cea6328059040b26baa48c776d991050c87ef12a803fa9403b8ff6fae8cbabb545ee40a711765ed71167f69a709f179670f919e77516009f0c5f8f410c69e5cb7447d823a5827825e16640fab6fc31212cd12c01dfd704ab16af3548b802b25bbdf03c9e727e303739d60cbce462f870ec02266a09dbb0001eafa98c0e42f04673652c4131ae56b7ea1511d933e0c87d6d81e0c3d292310573d7a7d661ac16f8218b83ba483233352fd6384d61eafa57eb317b4b2f06d12c4127cfd27c4d96e623fdfdec1e50256a77d89ce520b83dc44c95d19b48f8d80c2eea7061a8ba8166c2698566a74d8568c90d39fe30219e2450cea51e23f6b78f407c2960374c343b33bc12e3c6743401c9fc772c9416889499aa838585ad5555de27d8a8e0c2a291eb2826c31d7080e1200fd6c573a83647e6b271735790ef270c40b79c903f4c3065d69c68d335fd2b122b8da18eb39aff1d74e34a841e822df83068a5c04cc684721e2f998dd93f4cc02319de8e61ad84630db1f878550d94831a4921f520789f046bc4b92f48739d893915de0169d79bb0fcbb083e7f1da23a168224aee3c318a257fd61c235f4f9e13dc1727281d58af8d16e2ae80181c413c704374a7046ff8b68f3cb0aba5628b0089278ddea466f8d52e12fa14707108e8be45c5fe43da67f9870f7bdf6e559a02e3964448fce31647543deabec0f25bf7f887575f5715112c4db80f79fc77dbd02a031aa841ee249371cea5886d33c5dda310dda853f4ca0d7afd8952862d7082a7fe5baad3b092899b0eb4ca9a42bac7cc590dfecb02756fc6182f381aa0f9889df4a1ca16962c4b3a10d8d88c43788810ecd62a22145b74f970b2cc5166abf1f2413b870ae89766718e0d9434bc1cd710203bfd2cbc6d3b6ab543ce7e56f64571376a7bf4ca990bced24a2b890c067d83f4c588132063b541ddced57520c948688319fa052819ab95b095046e294aa677f7b7cbeaf9ded11e2e63e88b04c39ec753289ecf6cab675930c847f947e26bf41ca532813670af8451cfb9ba5a4f30e5a3b1a4dfc217bb03fc0f8b981ee8fa936854c01635e7d03120506978a63e26aefa7ea74e906c8f65fca72478cb72837bfc47847bd093cc2d4ad308c23e6bc32bef1015beba4079afd164d6bfbaa01d303f5c38496798b563f28cce0ed45e9841011a6c9b83b9569d3cdf5e5e24da334410d6c11f94c9aff5bbc32753a2dc690e95d0003bdfb38430691bea6ec1aabcd277108b905d8e268e107e2fc37a2e11430b341b213f75f6e9c858aacdd50175ce011ca84194e8e4bc43d2b57a4f9c041105bec825466d9252035de9470fb6caa2f840b3c461c3e6be9f8d37be9b52efb75d35b5849c62730555f400933d31a580d336a032386ce8451e36a66fc8a9f96416b144ee3751697fc6b57753a58d5b341c92d57eb5f2718667d817420a0e1fbbf51d63c607d812226e7b4d538320e06ee85e3023c90881306b9775dca0c8db46a197adde88d47a410e48dfd01260bad5f28ec6347bdeb526099ea413f738e93a67cd63af7cc1851a434cb99eaf10190124fb4c4d938901b3ed46cf50556a599116f0c265e13c3707818a2d0e2a9a45d6c324a5b392a481dbea2692fa54873335db64019fe3c12c2a61c3da6e037a99aa2f3a90e85ec42e7af5c2fa672cadf4c3545ce9f0db40ca01581023b67acd714683390744796b8a4557d8146d038833c9624bc2ea147341cea6b9b857cd28536c1a99c5dd800255b3b13358a317a2aea59d85bf5e5f4dda43cd9dc8cb0e7ec11b650aa718aa1b07e67218775a69a119441828d836d11281322fecbb128acdbd66ec9c8aa16ca595fd01366d50cf493c663303279861c81fd033e7d12167ed2ee0f478219013f436c566545ecb27ef0be97be6c80a3b0b1f0f720332bc0ac65f9ec5ad8dcd617fa00e59feeda0fe0d617d091a409536f129e5c2f05573c4a79af6d07b83e374dfc2223efe1c2343964d039363569ed4ac57c8e82cf92de4e3e5cceef95b98ae532e80be509be5dedfe1fe2ed71556d2e7a2ad91ea46c4f0317ce887f71f335b32df5083f94c26858de9578a88615785721717189cb63945a11987f8862901fcfa321ebaa6c6f97a649cbe68a8349b02107b652001598a2848a4996def5cbd2b9ed9ab2967bc4d1c00f0a8b244a0f5565edddb6d6ece5eaa16c19bd96112979ff8f816dde7c4760aa085faa33fcb2d15c8a24961e3533bb1577ddf2927e479a80a4c9108b223fab7713e483062cce80f6624191db6d6b93bd0cbd45c3b57cda70d33f7cee57da9822ca2fc6c8c9a212c4efcfc85fdcfe928e6a66f512636fe73a25277e7b4cfadb55164ba55741aebaa57d01c1d5b4a5dc34b1570b1ab18f3b447023d7583d162e1dac572210bab7c54394cd57375725d0decaaddc4503d58382b3cfbc40e733c5bc6820ca5bf4e6508037fbf4c671fad208d1574367da1809ceb1cfd0eb01f08b06a8819da1a54fce5b54ad12d7957fdd90602b94a9f2274c32ac41a6043cb255e4cea34d3a213140088c86058204d09a504da116cd334481e766540f9a3099c1add61419d8d115a2f5bae3498e89d988e00ca361d5972cd35504b92ad1a294dde97c672cf2afe6f4155f8512a4311a8280d0d854a93f266dff10be402aa89b42242de578143d29bca27ff3e4f96a090aae1724321a62bfc3b3ed64e85a6f6534e85d96366cf493b6e61233c4b7c28c86e85991aa3bf7d2e70c00ba0426169b86144968cd399b466dba5501cba679970b07f5f0fbecd62f9ece522399ec94cc4cd7e79d06fa2d33a0857d40b1506f9713831065854f35fd6672f8a97cc5686767fce26d14df2b9c9211865133ada444bfb2d96e1b134f04a08270d2949a1550792fbf144099354b3ef78fed67bf1060b0cda38a170288f45912ba1c1b9a566ac9e4a1b7fbedd990b37307ff7e1ce8ab89954d8826374a963f568fb7c9a51ca218899bc20cf6935edc43831ea349b26bbeb7be569b932253f93f27c61ef48295c481f925caa2ee6264acaadf147edec5d8f2f9b0a1d7c26206f6e628afea3d4ec7cb5371032ecd0eef8ddd9e49e75c67f85537a21f273de47a9ba0a4fd429f4d144f6c3747c334afcf1e905fe78c0a9dcfe14c1da5271ae6355c1e0922cd1c4f43d29bdcd1e77061a8fcd7ca254f8686609e93d9b79028b2706360d96a0d822b43b2f00434ae5aea2c6d6e68a51cd3036625566cd8fe110ed3e87a72bf3645b064dea43ec655169f0955ea56ae87c5b62122a7d24a258d2a288b0dc7a1b7c517b51417d15a9168349d74451fd445cbfba77bd53fd895ba2245ca772e03018eb878d0904250c731d988defde1e4370c86a91b75e986ab4fd6bf7a619b935f98daa3a25dacac26422b1018011e626c48b8f60b53ade73746d54d56b3054948a93665e648b8ce6f679a04d805ac82c729df7ed1fa6e5885c03418766d66f985a91e0973385d56521e480a881af405bed0d53abcd426146502c3547ea29326c0c239f5e7ce8908cc6708c53b8a1a13212bb3ae2c889515ac1e3a217a843fdd63eac03ec92f8b97b036dec3b44ef8c532ce633d5ed2498061ea8eb2a90589aefd47bd17f0147109107e3857606ad933095c0dc354174115c49d9dbe4fdef03813cd0417bbce20410fba600e7ef42b7794b3ee6b7af568fa5d081277147b009cb8a41f43539e73514ae65a7b82ffc284c3f5b210550115f52b53d79131582f6ca919135aaaf8955045f5b2432500916ffe2f4b8399061c3df6fbbc53c707728a0208b7356feb7186ae0876184b4bca56671c8e1d6a3f638d28fa341765f9d925397906cae4e7b1984d629dd19af46e1ffc1af219892b5cd5d1b8f67f511d8320c3bf82beeed06b504ea97e10ef45391f1ba5838ea699e17a0906593c22fafb46603e052265e53d6eccb55a7b74009ac1bcf6a4977e75345094d0cbee31b4dcf804061ff30eac6b67d4c3b67c422c588148573743a23bcc89135e4568800fd54f8f7462178c025556191066d04eba9add1627907e68496e9cf1b9582914705418fa9095b536e78d42a17289890f57c2dce175a4572cc70a3f95845e41cabc5a04e3f0bc5587ba2e5edac7d4036aa1fce328f33c2940f458aaf4dc865e159344d4d12ee5acfb74faf064f94143510af13645dc0bd93b2f9b869a194324fdb9e323caf0d322a14b35307c6f0f0672b7d7a334a4dcc2da19aea521c032129a300b91748550588f1c1d7f6f0093ced64582458c7b56069208cb88a813e53ad05f5346fe279826a4dcb7e7c512516a8a888f7a607ac426f2f48095b439a68f88c0315062995230a31089f5f51da608f07423a17bbb84d1b74837d23eb1a615762b129b838e8423ed86572a9e5338dbb44240ccd981f09446f3ab2213e53602959a5316dfe84d2bad3df91cfcf90b4b736ece92021fd72fee3476f4d950441ad6971af16169e742397217125a060040ba43c8c0e27e371007cefa79c856103b82363ad6be9a3fcb3d91c81c6ffceed75c01b17aeb421af436363ad617370b11d35471111e6f3ec11749fe1a025c1421f86f0d6cbbe852c22b2104203ce40e8830321b3bf4135bbf8adba67a15393698c8b0faabf714b521a13b65a9b1f5fe509a410dfc882b7b0692cc0bacdd00dea2d725b406ab66e1c869d8b1f094828788dc4519114ce717078ce8f261f1110aa719ef1ab6aae82b1d0b9fef7b254d5829955dc4f4a0e7f4b628e025d27f8e4c7d07bd0232e8acc20c2d89b56d9e077d400cc8a3be2c11daaf633d29f5b719eefb2b9e10558a4fa5cb548400b1a35c67558e8b68964f1cb472b52b65ece55c49977be1450f152cc23dfa7115da752e347a5343bdd1d65c14e732e2f5846b0451373ebbf23e2237a9b5a516cb2fa9a05be0be560a2f47c48f12a28980f7424b53cebb1d3352932f648b694a8a338f47ef8af62399c69a63cb0cb74948b2921dd6a4e54a79f129dbfa66e537000f735fe979f206703c9609280d78d434ad14fe9ba293c6a892b8fc92c8e45b8a1e4643158cdfb20e8e900526c0c0dc8b3340c39c11318008ed2c9e9dead0c850144277dd4c3ea459cf148286249472e5a4a6d6bc0241961458a0420766087f143477d6f209ae2af8f3dfbfbffffdfdff9fbf14408c5a1866797354a2093d5ce37557085a51994c6f9856c69541c7dda6b8a17a81d4eb7f4830e6ddabdcde2750512a1773256696d390f3752b24ccc7ac185be67a02d28ed97d8ca22ac4439f393e77ecaa6b7bea55b17491e3d42349b44f240894412d32cf07480a27dd41b3a6589af8c6182c0ac7707914c8a90b62d6ab94cddd3c4892080c87efc6d009b7ec2196b2b9f1ef7fe0f62754a0aa00cb90521b22c88dd1828f1575b4bb74e1bba0561e8a4b0edc63be18b98f19b548ae1e08dcf9fd20878f494c939bc0e85365c58e262b2ccdf986e37c10074abdf3a88bdd90e51ec2e638c789810e44f50154831d88392524119780a471417f545313a2dbdf18b6e506ff6b12d47403495483afa14e12eef32221213a670803ff19c0aa040390e85b31f358d1ae7441a30e119605680639060cbf43d0e019c6bcbfcd76101d474bde98c3eea2642219a89f0e816032800e1e6ebe5ebade58c29b60140cb48685e5626a84bc985a500ab748e507a1bf3c39eaeb05728ec9b5ac665062c47c9002e60437a411ae43594c728eb57f033c7bfb734ea34363850431cc37602f9dc342d45df7b74fa7913d1322bf7d965fff946907de7d1d29487cd693ec9d6143ddff5bd0a9554092defa207911a9ad65bff4b1488cd4123826e29e0f8b67c0a98f8e564a3f2538ff6ef15d3944c9ebfb18a4c6b9b4695c1c4380a5f3b3e624661a164c5246052b61b658e2bfc5e83942f78db5284948a79f6f17e14aeebd42d0dad6b5201632d08509777347bff2ec8efb67c71293ed5137fe4b04949f6f0819acb635fb6b30f19f08bc2521a1bec6ebef40988cdaa3683f25c97ac1fe727ace3d13862490420ba39931c63223449eda6c35f2fb66eb63172ef6beb2575f9a93c82d3ad5ce4b19486e0600177ebd5bb5f6671ff667dedeec0c6e4122746c5a34b391252456eff90ac60dc9a993671c458c9e5987310eb5fb7b9921e8b87048812fcfcd3e314f2aeb02615ee8106c73dba818b2d90c846458368241749b0baabab303692bd88296bc63c5909e46964fd290725326ee97812ac3d6a841a9c8e7e15ecd57ae2482090bcd50151a0f2844f4b6efe663d5898169c7eff404c2f0c7f7bd140e0c8a13426a734def291914777545cb569b38f8386e5443b0145e729985bc14901588ac97eecb88b0c677129d65437e2b083af211f16253c05d849cf05bf167ffdff16b1f0a94cdf44b166ccfd6b2efcaf6540b0302d39286678a99791f2d9b0c03ef3a5b66efe5b0b592fcaa6f6c38a16e5682f726ac367ba2e19ba3d135e7989f8f44be64bfecef8d6803852228ac80184b22dd7ba9b4fb80e46b5fb06ceeaad5fa63e8ae07eb64747e49d9f091b1695f09770308e5267d4b7c6b342fcf478a46845ad38a4d5a84789fd582f8c655f28972341081eacc3cdd7058ec9dc781acad094f702ecd0d357e7faff73518568b4ef78de16c8a9979992b0c38a2d8a4a60e49607ff7c6ba657eff0d32afa030f950e2e7d76c716cf7559d084e1d6ccf101d671d5c1dbdf52807e2fc3a19b22ef083f8e4a79b661052c4d12ee038a950807aba21681b630233d180a3d3897ad6c783aeb39c48c355bd4c6b01c72599c0a5062f7a691ec0690187c89be06b9c6fc62fb6f0cf6ac138a83d18a782fa88150113e4b7707494a63299ea0b19bbfefb2167700bd5bff3a9a2bbf5617c1e3a2cb9d1b3aae897abb22d25eeff30455841190fc27cca12030ea7dbee07c0f974a74d0fb8420817efcede6ddecf3e0e05ffcbc999261504ebfbf75460892569b6a0cb81202e8eace82ee2c3e1d297bdecd3e316be9a2828ea37b557061ca81808f5555ad824808ad074d2ffc2eedd53e617991d69c0a13de4089d7a623cce38e94245a4bfbb96305001ae3d939f218ad30a05ef4929c43006f9fdae45a30085d76ac454ebd3c4bd7185aebf0a733e1b23d4720f3c8950bc105c299e003e3429d29841b6d1f3481a702cda2866b18bb59012f80c610e7d07b487b6a6030eb18046056c25056a8200a1913955818073111e3c07f11f87d05f82cce1e6b267ba4da90599b0e8c953f825973dc1f3e113af4538b5856bcd58acf1e8828ac2e43de1c011fd5f183c68805bdfc29e47ce993361b5239bec759de8b34af591f7ab635411b6d77dbba92433e214eeb1e5436fc027ca012051026488324148f6cfad5102428a93a1c8ecfffc007e793fff7ecad1942512dc60329cc0e5196ef8d9a4a788e5892eb7a848bc1252ab287c564fe32a358b1c8d15709055beff00b7c7c1bf04617da4d48eedb0ca6614c87552a4fb2592bc56493e0ea3c38ec85753b5e191c8acb450eaf14542d862b4cc9fe16e8fc3393384049ca1b3b8d469e4d27092c5e1353bd23eadce1ccd10e42a6d266ea1c4a65332012eabfa917945beb7995dfc35122c57a4108294f0c1edf289d54a6528ac2f90c23f005c67474a501a492a71055bb2110780a0e979c5d3e700efe91a5f055c0e3fabdbd965ad270e77bc7194c6577ffddbba5cfaec30a5499648b26a459290fe157a3eb0d4317d16987d4b5ae9df5f2cc63e0f38f29a4d14601863dd44dd69395bed71acf18f74a72bb39034a18492e4cb881247a5c1fd7bcdcb63b885682676e9f12d430f478fdfc87abe6aa88f07cf75e12db70405ee714473093ebd66664b313bcdc0a7a498c171cff2a96c440822af8618fc5c26dd986fc4264457e784d63a8c3445d91842309c34cc29e6a9442dfe28a4481021246d0a9c359e97489f6e46e788b11417293e23919a365630f541500be45ca0fcbbc7d19a6bb2d355290deadab82612fad23d0ebac63f520820a1ea18628ab2c5cdf2babcdddee6e91e075df2571239ab023976d824df833cadd55f3695db6993af852e5fdb82495f8d38d51d05262a13bd888d06d48de46d28ae44dc18cb8d521e8436884ef26b3453d241c2f9928d2a4a821ae0259332ab0abacdb7fd05518d5897ab49629dc2857a5eb0fe86844b498fafd1135b6a80e6c0416fea4d4ac9adb8db255a7dd5c0342563458d6b7c407c9b128aca1af42f4ff1a449ccbfaa857817471525b5560db574ea35056a50c66fc4e3dc6cd24bbf0136eaa019739505a2f5103a960e169f5f23a03c5e59fffbf2b15d867ddc6d6f178676a6f112bb529ed98b8f210813e222efb4ff0432db4e484cccebede66f06fe9ec07cf5bce24bb2ad9e48dc8dfbf8553b82a1f7fca8041b27ec2ce3be715dd026b73b85bce40e5bb72423eb4161ef2c7c7032d61a93e455995c8fdf8cd10cd0850bd9159fcf452cd4bffe2b0cfa9a1a4aade973a5d46bb3e2c508a659c75bb2d32472f391141362d7b7c74898e2817325652154b8fe2fcdf196bf8542c7ef8a79ef4862c98db7e0ee4354065ca50bdafd7a1ca1bed10c08066c5571b7026b7968de52b792c7707653a175f69bb9e5952610f68dd1b8f11ea35499b4b52879a54bb3847535436e6a46389dd6cba1641a2db0d76557819c9afde67f33d6c4c06d076e6a9f28d2fc56c36b0159fb18ab17be27f216e54ddcc224cd46c1712df701da3f57e921eee219d16cc5b899612d98a6427e351c53ca1cea956896485aaedd4fc83b5bb5ea53ab7365822c61f385eea4e8c2f27b85dc0f1cb34ca4016e1c03267d5a15c2a774c9fff9eddb35c1cb3f8c82e9deca34d2d3022661c9f6e5db3471265a6215d03c6290b35f950aac06fbb1b055bb1202bd2ac76a552ad4cad8d09084e1f4123d04892cfc1ccd4aa48c7d0aff346bd8a42d7a636d35b9c57f3f95e4c5cf911a3409152386bb65fdd68ec9e40527c1a9608d30936499c165020af3ee859840183f46eee0322e9f5769c8e1ef5d65a8c108edd87a5a03abb22e28e7ed5f6381a8b25ec225b6208e1516178e34a49da5a9176fff0a0e7ecfe429e363949cf5f57a8dfdc9dc5d6cdc83e693d26588d67a0e460af29faeb7075c3ad1c13448a93eef1eb78e7b8f5ef4128fed7e37fa846b91c37e0d581e1b561d83131c1b09e55e7a610bf09c344fce783387d39f869a686bdfc1947a66729c3b6409ba4a89fc128e48f6c5e6e90256314fff240cbc05793ae4d7fb57730381397f689e5c320f008b8315127ec24eb8b9fd4676a271a0241da389e6188feb0b48ff1d3041b466427f8c2dcdedee747034c6c22552e2ea7edd8e8cc841f7a55cc2b051054cedb973eeae83e897302976dab5567d7635e1121afabe02b974aa4425c92dd34d65ae2b8d28bf93bda139e03c37ccf6d19af9e461d79e75550a8ce44edeaa8b4fb81ec25f2c7b245ed6f2ca55cfae921182fc6536e7e31fe1a46d14948b65526347788498059548dbcbdc292985c2b7e0744b8b04ef67cab9698b570e585f5557094596147cd4b64eb876acac6c91214ff12767a9ffeb507fc89752ac4b53c2370e786f2c982f0b6e86134d41316f24575c90499c5a9b77b1aba0d6f26a15af46b8ca32f82531a0616cde80d71dbf0ec4dccbadbccbf985d7e57b917c3efd03eb299e18b44521d89ff5110b60e16e6b2bc3c71a563761ea84431f6015d15c281f4d151ac4877afcfb9ebcebb225d0891478fb86e7d998bd0e256598ff59af17f51e5ced5e37be354855cd284a645b886190e4c153b3adb558482daf1693a0ce46e7faa134cd859a62b5dea877e78d0c58d94a50f45dd57b333748953a857148e9eeba487c5a3bba83a158fa7fc2c93398f0abb73076b64355016a87351f469164d773e3fc51a75b958ea0759de7519a7cd13a95d29998127cc3e3357736ee45b0e8adbbef8aed3169de0615c590ac441226391cdbbc8f5c177f01b1c4fe5cc03247293d03af883e63222f282b09bc9f3e79b55b59ee00683836438fb8ce0e07a15fc37c22897e9219356376c9fe78ccac73c5b39ee918fa85eb6fcfd3de722b8b9b26062c190a84b4d5f867415c463fa0a7c603eb866cf7ce6ca2f44660d3cd9297b64c629fa307722ce96ae1f99af37dcae4c2314b5cf13d5b049f259e0f02362eecfaa8b32c069a2f9692332730975880c7acb549b73e3be8c27cd4b8b46da5b33c8ecd120f1dda725e3801d070399ab02b8ad1857b0c12001acbc729b9a8862119ae939725d49e88a00fbac21b3692a4f85646c9959927f7654aae70a44aaef99db1f81cfc90cc52cf535e6f651bb8acdd1a747829c918d09e4fc624572a77000febb6804a02d0f0be2befd725fd8a230092795eb7961f416e4ff9a6070a5237da03a77799a1fa6573ce4fd3518a254dd555a2de55fcf222e9544c6d44299614c805ae8c0d017100d935f6b4c9e77f491713ebab8cc399ee3a534ac19584d2a3f7085eabb99fa54d004c89a8a47005c4489c431ba649e304c3297e03487cf1eb8053196e7c05704181ee6fb5150ebe9ef15649b68e8567b170e069c054c0f65e19975716278217140aeaec3013dece0ca66d236a049ee654aa015add2bf02b624b3bca6e2d31cb25b280ee156f2786721eaece99d3bfbd52a142696d2d5dce7141f03c926f6ae8ffaf54a20cf78697c292cc0641fda17bc2096b2d51d1b7cc265411de58de5e196dd310a10a483edced95ca94ed91491f93ddd964c0dc5e81baccaaede5f94dc35b761dd551ebd1a8350c9bfc910ec4138da3daf64a958118ab0a45c9bcc04cca828919bf561d88ee1026c00c5989abbd0d489406004506e9369ac150cb6baf7c5b1a76a5bc8a6c597ba535e42bed48da2c12114fd55ed94a6fceb01f502c5c5944121e2c5af7f315c904f1a8e338d45e2973938a899119625bc1a3af2e77ba2e6270c2aa78dd9a73c04ea030ac1b8d61bec4135f5caccff3a8e8515d0946bd5bc2fe69af54482693f60a42cb211472a312fef7da5ec17175fe7a53bb745633a1e860a472108060b657e8a913ea6dafd06ff59aea37f78a5b548af193d935e8f1ebe22c3a4150f16de3ea566000c590b07e11c1604284dedd9e612a07ada39dbd824f62f7a828b4d02fc483dbbe2a85d3edc340e7fd84dab0f2e644c373d65a4352d1efdc7911ef0f76ad292e6e6fd6b392cafd8a40c3affc229e834ace71d6746bf1ceb9b5b948f5b8345e15c4167e8bde21b927e366dac4a4e2e2e7fc05aa6184f4bb6b87cd49c8279a65dcee38b83e3dcdbfd10828c5a384997c691e31de82ca0616ca30919ac4b4185b8bd6c0f290f33c53ffdb14b5230e611c0ff48bfc6b933aad8a0600f9663d2895e17a6052bfc8c3c919bb68e58a5a7e45d0019747bc63160b6c7e68d02c6482bb3d5a455ed9faba62b8965bc0c22fa5efe0f22f3c00588804cf10d4ac46d5c8d1648d2705835f3902aef776c3b7df1fe8ef3558c7a8cce4c01de4ed85abf5738511a6ad5336053242a8b840ee5bf2c637416f7095220ff14ad1cf6959440b48f67d9fe0b01a7f5e5b797bb0487eba516b43db3c0281bb24fd69b943cc10a93761c414f0a2a8964eea8b8fbadfc741aaa72dd12f0e3875614c8c862bc03bdf3d7c6b3ba86524e8e1d80d77b062b0768a8f82c6fd3061301525b4852bdd5146d4fcefc2f197e24048245e4ce6d31898a1f96ff2208e2855a702ad85ff2212fd5e92c6645c879939221012c8e7b2a8f07da66a9f92c77061f9f775649a86b24e5650612d9b0a238beb5e14cea0b1344fa4f38b0635cc5239c02b35e3129ccf10ac308a48c654bf44239fd1c47f94d06944facca8c2992018690f81dcc9e7e26b23d20974d88ddd7b053a6e59622917cb70735c1c69cda9d8648e62715dc89e401e6216cd26bc5833b7d343221e4814aaf766af708f82c77cbc489aef20d5a4fd558283dc4afb2e404a8d8a05e22f890c2a5469391bade5309434e09ca94310b183477a7b62004168f8d16186ead21c26d2e60628a69de096bb23b56ee8dcb88a0ad58d18625512baf3b3c18fa4af955c2715ef654e2b4f6a62ab865891679583b496ca7c22a0170ab0deabc4666f43de14984e2789b42c03aeeb1394b419f9ce07a4b3a50b20938b17574a28677aef1ce3d2eb48477de56ae6d2bca7536dc1b3fc4c7d7976886608225b70ec2fe134b147204dbba0efc6f851234ee107f8f874bf28058dc42580071132f6269c002ec1cf5c367c5223aed266947057622587de846d9fd7071e1bc6c08a03710685ab8b0f206d91c3a6e7aab4391be18230fea2523bdbdfc283ff32d44ea034bf73273a2238e5af1f70d234a2708e2ddef54c9e895e6dc014d383bb94343de11b4fd02805553797ad91cacdcb30283bc7e803845bde50a6da8cd933459e7369e4098f2700db9ff25071e1edbde14cd7410c2836186dc8dd7dfb6177b7f889011bf9c91a9c532fb91a5ab1669cc6cbc6d0816ef74d73c7146c433a9b7f77d30d5ef77fef9bdd769f808c811d7f77e87933cfa579b2b5cecf7b3629421f0241ee0b44e47e79ed0db456677258e023c64045555c024559c1873a208843fbcc34cdf40e5a0ca8e914d9a12b9432a4ec5e9ad2e629f358bcd3a24a9b06632633a07d643f1d4269a18bd44a433500b3020211c2bb9a7858cca4363d9dc27e22625b6b8610673885ecdec24cea4de4fe684a0cf81ef4e1edb5d3927fd530f014d69be543c291049088f7e79d8d1c1b8d167de1afe0bdfd0a516149f19b48f829ed013de42a097b195dd049628c86bc1e2e594af622081a0a2ae22ca8b87d72991e33fc1df521713233a58ec3d476473d3a9e441b035e1aa20a89ba695cdb56a20ded59ec09ddbca9f51d666393181eadc6b1e60d50a20d1605e88437a324b13962eaaafb6554a6a0b6e9d5190ef2e9b42e3036971b36f6ae441b948cb4ab71e0fe07b37cd8a8d7c704a26fbc8fd38ba7c2781b2f200a9b83510a99fba97542463b8f659059a49097f11f00c3f0ec54bbcc2c56192166ae84b404c4b0966883fb90e68d6e87b4bca06226295fa2febe77a916100dcd26a68525345a5d3b3f8d62f4dee4bd39d1696dea977674a7cef75dbff9d0a252c3378dfa8bb6ef2ac7ba9968a36f5d47df1bc41e03b441a3aa7db17242fb3019df683ee3de53b99e579608ed647a96d55323a52e656c1354bd92ae5d04994d6fb1214b923adbd6fb53d312cb87922431dde2c53cc432c5bfcb123cb301a988c5648e85ab4cfcdc293b1f2a5db99466d0189092a27172a3e27e4a47e838c6a5a1f0f80959e4ea8660f87a1def40e89f7cea449e7f1597558f75bc884855b9b03a528044778b9c801696c9a9e08713889bf3ba336e5c6e3e58c6cf62a34dc6441b01ac884f353869ca1cf067f4135bccf6915aa254d85cef2f80fb126dfcbd8aa4c30d073d39c88e242c433139037bed9473984268d43ed29be513b6200bd732bf4e04098c04ec363be11ba3aeb0aec0ec27b3f2c4f679f8d46bc870c5775e4a91fc807e355e3bc25f27dda95d0e41861ee553b3af74e71b80cfd919e11c0ab4e19873e248374372073a551ce80947f2a6220149089b1a5710a0db554429abc05818d1a8b0fc1e25cb3fce3f642c09a0141620041b762e0ab42008e8d19c6243f392687c33e4e55d9f6f370be3031c455e82dcb8f005ac503b22ae8791b7d52f2817d61476ff8872616d69af9f68560496672f590fdce46ed41c0f79eecb6db8aa07a2c270a753987771cb558dde128b23dca7ec714a1528aad596765ec641301cd249ae122d7b5819ded9ec07a5d933224c65d650c3a960d7222e21227b8bc0219a7f5719e72ddb87286ef5f2794f61f99d8649525904923ed8eb728271771a1bd11ed17641c0ebc796cbee25928884ff362005ea84ee256024b6e06c4545c9be0377ea3bb84e82e5f3242e86c15fa4cbb65d52ecfba7c5e3ed2b39c8f66a98f79594793bd14967690e4b8fbf0c4d863b29c12aebf79eaf9ea1250a079d513058ecd9d95b1d3065c332c5c5705e08b2df0565bd35f2f2d06a97a814f6c1a3b0fe481dbca5fbef30e474821bee55eb951ce8ed2014e207025136085220dfc6c2d7494dcf1ac936f26d9cdfe2957c85ea23a20b8818e3eec253507ee0325240a95335f1ef3dc14c3bb803c477ac3b51648877aedb1c2d3be0a18e0f0c547fbf1f10ceb5a9a2b0f64235118d7c8cb5f5aa5fefcfbb9f5fb5fb07af67ea07d75efd92d377fc684bda0fba3c46bfb570fb3dc7dbfb97967f3feb1a597ec51aed979cbfe3475bf27ed0e521faad85dbef39dedebfb4fcfb59d7c8f22bd668bfe4fc1d3fda92f7832e0fd16f2ddc7ecff1f6fea5e5dfcfba46965fb146fb25e7eff8d196bc1f7479887e0bde342bd6fc2990fbf49e9ceb83a26c5fc0c510f2ecc4f7f53bd8dcaf4cbf7d1917a4e22973dc57eee4191f3a65fb022e86906727beafdfc1e67e65faedcbb820154f99e3be7227cff8d029db177031843c3bf17dfd0e36f72bd36f5fc605a978ca1cf7953b79c687c67f0e0daf5f10df7d8c39aa7c0a72d82719f90c0f2d65fb009323e4d925b6cf377c77bf52faed634c51c55396c33ed9f86f7c6829db07981c21cf2eb17dbee1bbfb95d26f1f638a2a9eb21cf6c9c67fe3434bd93ec0e408797689edf30ddfddaf947efb185354f194e5b04f36fe1b1faaf73930baff027dfbb2dd10c553e4705fc9d9377ca894f705b91820cf4aecbe9ea3ddf515e9df97e582289e2287fb4acebee143a5bc2fc8c500795662f7f51cedaeaf48ffbe2c1744f11439dc5772f60d1f2ae57d412e06c8b312bbafe768777d45faf765b9208aa7ec6b3eb8b97f92e4bed732e97b4d69dec79aa2144f2987fb64e3dff050a5bc0f3439823c5b62f7f98677d72b4aff3ed614a5784a39dc271bff86872ae57da0c911e4d912bbcf37bcbb5e51faf7b1a628c553cae13ed9f8373c5429ef034d8e20cf96d87dbee1ddf58a3ada1517fd83b8db5772f28c1e2aa57d01d746e8b313b7afe760737b45faf665dca1caa7ccd1be929367f45029ed0bb836429f9db87d3d079bdb2bd2b72fe30e553e658ef6959c3ca3874a695fc0b511faecc4edeb39d8dc5e91be7d1977a8f22973b4afe4e4193d64ff7734be7f49fcf731a628e553c8619fdcf8373eb494ee034c0e21cf96f83ebfc1cdfd4ae9b78f31452a9e528efbe4469ff1a1a56c1f60720879b6c4f7f90d6eee574abf7d8c2952f19472dc2737fa8c0f2d65fb009343c8b325becf6f7073bf52faed634c918aa7e2e96e31f97fc474dfd733c2f7da34df977541154f39877d65e7bef1a153b62fe062843c7b62fbfa8eedee57a6dfbe8c0baa78ca39ec2b3bf78d0f9db27d011723e4d913dbd7776c77bf32fdf6655c50c553ce615fd9b96f7ce894ed0bb81821cf9ed8bebe63bbfb95e9b72fe3822a9e9aaff1c1e7ff4192fb5e8ba4df6ba4791fcb14513c851cee938c7fc38792f23e90c901f22c89dde719de5d5f21fdfb58a688e229e4709f64fc1b3e9494f7814c0e906749ec3ecff0eefa0ae9dfc73245144f2187fb24e3dff0a1a4bc0f6472803c4b62f7798677d757d8d1ae1dd40fc06d5fc9c96f7ca894ed0bba1820cf92d8be9e83bdfb15e9b72feb82289e420efb4a4e7ee343a56c5fd0c5007996c4f6f51cecddaf48bf7d99db06740bcc59045a66ffac5c30d6556d0e79649a4527fe24bdfd4327e90af9ec23f1be9123aea002964a8aa2fb300ed19fec4346329873c21008e11be0c6c0a3c3c9ecb92d0dfe9fc05bfbda58aef71ac1fdbd97c1b610064c54f6d7d27fdf7677afec2d654a3205fe0ae00a6c0a5ccce5286e09c7c433810b6d85dec5725cfe65b4ef6df426b2bda5150078033e2d2254098026ce13715e51f4d4e6aa41d8dc124e36e39a74aaaec2dcd44fe2095ba5c7ba2f2e6fa3c5b7d10ddaf7981211f20fd00f589ff8c78923b7bf5bd2c93a268de2548b80b4f00dd630532d8c3b7c48fd33b88da5e673fb635506744beed64e06d2d0a9162c91268708edcbd524f511965c8c8b899c8abcf65498b56108bb313771357c2c69ae682cc9fa245218d6988f2c0c596e496597079c9fca4dedb548acf05b5917cc068542a4a1d82565345e8d792e6f88278a9e277a3f3c1e6f47f45aa2c7123b19cf744f60537731168f03615785dbaf908bd1d02998b18bb94988f0bb989bba6e5d8c83a0f8b95a17eb622c21dc3aba00dee8abcd5a6bad31c65a5f441a911cba936b6d9c13dcab6acfcfb5a6cd17a33e9c1313456930b9d6179b36e06aceb02e37597075fbbd4dacb37a05cfd42af08c265c618b4174eb08ae6c13d6e5a8aac516b7bf044370fb398ee3ea58632608cb2e0c69bad65a2bcd57c5ba8467b2e0997ead36b9fd1f6c562cd080c9edefaac57cd84d1061d9c5ba98a338c549816dbe184785dbcf31e162dc4c5bdde662b509cff47fb16953b1c0337aa25cc62aab5b7cf354c7d94f8db1c2b28bdd18ecceb18bddfe018035acb5d6dac5ba587541037d60f454a207a6d7ca155666a52394849a3a1032ad9829c4c8645ad3262648c6153385899269a235afd34b2f288382db5f962e4fe1f6cbb46264169c734e2ed4113267978e235609c2f2e710b6f707554d822a07577d72cddd411d50455d67f581aa1510129017542ce9fb772f3da83f06e86fe3b67d7daf036f6add5e8ca166c11bed5f3eaf3ebeb0c697953f839e056f3a0aaee8fc0169e434f086abb66ae35c22f4ef9ee3b40ade4c176bed21d615b802754a53cb03751a4553fd14bc99ad84d07f76977f8a30c58bd2070edc17f487adc986f2b1a348cfef91c44e811e00552322462cfaed84306674f9e70924b7bba58ccb51252199cc897477deef4fa2ef978171cdc9f7cb3cc1a818d70f6ecc6b08b763804822a71c546994c99c41676ea2596072fb1dd4c4d16aa50a5918a9984c9b11103347ad5861248229accc5666a1ca75518b0c57f394ebb91661f9b28ae1d2deeb97578f26fb85759b678b5a64b8571696313f7cb8b2b07ce196322e1997a35e7cbc76603f8282080d197a4126765f8ec8c8bcee2778c332354b56616a997638fb25c7715f9a5adc0f35b9f2fdcc5cc83df3ca6fefad88261e53cbb4636a995a7ddab4bfadfd8a666a99783472a6e2d9e7704e6a6abd78ae4fe0f77397369469b9092491c8b41c656ab9a9dfc5381acb9024d3e2645a4d76f81e8be8e22f296bb25fc65592e844e9be65b4f2324bfa549a5a2b4db68cc618fa8eba97711de9974122132424a3a45f66a84fe1ed97a9422626237354a7fa472b9da9d5a79214e231ed987ef469e576e78264626a91202c4999a9c547eea6fd8fc692f47565652c6d28ddedbb6e2c7790b23e3529ebd336caec34c9a44fda2833440e0d713fbf248548257de24632a8c926614d92b34bc26e3f395319bd919c597246c5179001a207c792c78d51d264c70cc504c5248991c504c504392ac6da18594c508c4ca6479fbeef9721c23533e55152beb4170585e5a67cc972517e8a314fe0991819cff4cbc8c8b8645c2fc41451071dea2d656264a5cc8fdb1bd800d183bf8137da8c91c5c8fa249279c9b89a3c89f191f9011014af2bf373fbcb18d7958999c5c844a38cef5de625e36af21b65ecc8b85c57077a6b73d3f165d564d3ab89f37238bf2454122a0985322e995749e8ca10194158cab8ae8c4be6d5277ea1e2963ca68b50f3dc16cb91ebf65307c0eb85b5f3d2d3a77afb5f86f4897f66aadb2522b7bd7cf1719b8582236e9113c46ef9128474cb179f17d78bcfd28ca700410823260a31b252164ab316ff79b7cfb508b50857829adcc0186ae952c5ed1f5d869aec9ff31372d42693c562437796751312ba2b51484519ab52159a98a81111d31413346d7cdaf82803089e2143754b5698a6fe98a02b4304204a69c637c5c59d109a5a269ea6d14f4510ae6ac7bda7f271f8a2f2d27a79e9316285202c5f5675f5f2830211f6c91f0572804dfd40ec04f1e38246dcfe7214e4f6a3803739cc0baa66a11d4d2a7206ae426f2c7d505d722643ab2e9da4514809aa2ea8224da76fc10668ae0232807e134efc9c862ba3d688fe107aebdce941b7b45a8c8c96b2509a8931b269636acd19a52c985ade9c73d656058267fa4d2dd309c01844d73919225acbb91ff968b71be907426d9479c9b87442ee41d576e9e86a9aa6699a530ade8011bd7d2ccd645c2fab1712c8b84a2f24a82c19d7b4a946bcac1c554350512073830a446d95ea6a453d1072dfbd8fb40321a82a81370faa4015a8e220802a8d87a6699aa6694e2927da165e56232246ac97d5b429cd40959b889828f007ed654599c11f46addb2324462618b1a064855110239e6ec4dabaaf3d665db19a06f7655d0525c951d25666a52394845666d3861c2a09392a26a87484898a99821cbafddaca2c660a99d79d36324ff08c7e991b4c5347a184dbeff527630319191917074a19971309595cc323d96876fb854812d9452e548e7a59bdac562dd60b4fcb7dc2f9231fa4172fc451ab698c58aa70d2118b34eaf0ab342bcdfcc588e52818df3f6a39eae54d3b4d0aa1314c9aec529326b977e7deb9c7807fa94993edadbd2dcd64a8b4d24c93a1ea46ac11abeb4419aad2acc9d28c0130d7bf44bb18a5990c55c98d3133134f936d6a893132ea3254a5598cec362935f1e60f425a125dfe6902116dc41ab5484fc5918fa0b01cb146ac518b24ca5089a5d9166e6a35d9262a30b9f3962599cf4c86aa4f658c8c499f588adb5f9a790c1d8190de46bb68da69b2dfd47214397353934caddb2439bbfd313e7d2a47ac98217dfaeff24f1440aee89623d6cb38390a3538411022b0c8010c09a92a96604f8b4b0b0da47f791c303ec64fd14b4d628c5a2f23d6884786aa341bb15e56b3dbef12bba0ecf633890483c1961cd288834708a8800dc17cc0a352a57c14a99aec9795a346d6beac46ac9715a8c333fd231649043fc0a6149086b83d62812310a9fa54cab46eff0a547de18b514839628d587d2aa74ccb512fbe5f86c751a4efaf2b25b68a705bb2ba1b933bbfac3d37c88e58b77fd4ea53691ab1746effc8c768c7f472d11740829d222809ba438fe821f07e5b8c6be67f250981c5b23b601bef292d5011aeb8fd73b43b36053cc3aaa008f7e57db35642477d0f7eef790f8e2d7324bd9b9a34a90f75897408f5a13458d545e02b2b86345fb5153de4ab6943792aabf2f8aa124169119e4165304d4d8ddcfe92ae80c680be7886fa501fefeaa23e2ccbfaf03c2258b487da0a7f5d29c026a25913bce1daa7691ae86916e8863eb83d6a42e8b16d5bf5d04b71d124288f0b890bc90a0e5c3409ca437792d8ad87f74c1b77cd199b135ead9b585df5c5b9a64dab2aab12314ded7297c378c6063cd3fe4425c26fe051dcfef9a5bb4830765c5ae53d856adaf410ca439318d22a27c18cd11e68d514df48763495ceceb4a9aca9694d781c7ae2c794c749e02bca336d3aa8594e82896a223a88f250b1653c93049ee96f2266c76ef7135a095190e2d2df9c9826cd356d669356f9e6c444f50fb38e653799363da45dddc434f577134fec948603cdb5bd7ac8b469244d4c544f315dbd7910ba6ab27b34d98d64da501fcde53dc544694d4c9f46a271efd9ef86f599367487264179a88ff63cae3696f36a6f693b18036b3744d487b80515a13bd366fb014d02e6a8ed0708b7dfd29debda5e9add829204815e81a1ff38dcde73816ceae334eeeefe7db65659e75eab0e6e9908ffea40df0363e83b14afd9e2191f769836d3089ee1a81902144ce1f6cf15cf700d78e9923ef9bbebf6eb7d7e0ed59edb753544aba043cec4d2164fd3682bd29d26e9508bc7512aae5b7ddc3453449fb9acc9ee98fbd04db373e8479bfabff7c6d27a24110ae703fe89ff6854cab7682cfb08ca583692998453e2e2bfb1fc54de1b9b87e5bbe6d1c692b41d9b1de3c6d27b52fec5b3fc3696afe2a2b44c1af5625c093f12696534badcd265b49774936672bb97348aee74aca4ad161d7ab55e3047b90872940acbbbaaeabcf8b673ce2943cf15d774c87d056fb6ad7b49165a4c1b7fd2c8b3a106c0186815b11b3ee961be0618301e0606ccf700e349241bc2183da98586961f3d8e961fb97ccb93c61d31fee569f80f03e679fc24c1fc8ed1d83249cf431cc1f80d42d2c37cf8e3380a295db6f22e1bf90cc68b5fc3ff68ec61f4ffe2d883101ca3ffb165f6f00f636c996f43147160bc464f7a98161a464f7a1ca327c1f8d1cf1107e961c61d304f824158d25685112b0c51a6ad5c6b31bba94bd182d0a17904465f4da6b870f1fdb4c7512a630fa4577996b187d1b33c8ed1b33c8337e6481432c71c70904621f3557e8e39e4b8783bd2c02395f2365c2c3556a9f1f88cb2883445dcc123e5b21784fea5cbe810ada2c9fe17228d350daaf2f62da352de8ee51c696c6868f68939e5cb6e718d869a3cae339bdc39961f938bc5ed9f61c7725e71fbd4f3891ff01cc2ed5f197241632c4ffa1a46ef62ecc1c58fdec58f607c0fa367195b404e3d8728ff3d8f5a4842793a84f28d326a21cb7b0fc27821d2702cade80582a4516706e97c4f87beef6fd4421691c6dcd4761c1a7241386d37f2583b9607e0d9acb5d6fe17d270651452d2213a54a3c90943494cd15078842dfe803ea008c0157704d79ae04ae3381877c444714e80b069f3c1603188e86a356dfa478f12ab2a8252afe6944d9ecb8388f650235a89eea12ea03cf404fd83c2801ac1a81a046dd1963773086df4dcb620a16a0412c09b93af2cae098251dd152c16e83dbd316f0e274f83a7fe2b6b73798591825e241f1baeba5893dbb3ca772be49a4a297da628280dde10dd94911e11be3ccc93569e24b6c078afbf172ee2c7789bf22ccfd2c2f27c539e59c470a50b4724d15b6981f1c265a6d81496a742842c634ac7e2ba15cbd59e59e33846114bdb05a1c32c39511461582d987f591bb26c418ee25a1e4483341b846b398a7b715c8b6a3b5c4ba35cacec8060537f1060cb07175c812b7005aeb84624ba76c6e2542fe30a6e1711c262b7e4181dad4fcf17ab3d3d3ec193afacae09cfad2daf1bbca1282a28a375bd9a460b597915d112e9094bebbab34fda6f1d93ae6bd227140bb32f4b44e53d0ea98d4611cb79b7b2068c92bcda93be2485388e1aff8585eef6a2d11e6912c9eda74042ed4b7be4f66f6fa3bb584b177318cd8bb1247b58468b32966f89f46ba5bfcfba5e63176b72499bfa576ed9c55e7b95dfc6f24b22ec644dc62ee642ec9688dd48ec56468e876b35f9a3f4fda515b9d2d85dc12d8c2471b46017a32c0879bc1f4df6c6bd604da37f0561c9bd389ea6d14222b42eef457221912eff4421c5e65f8337e6a51a8a8be825a4d49e6a2ffa923ef76a9283712f1817f35ce460dceb08f7d29e7bf589fed6db36723328e460dcabc9233c6c051338f1fb3f9eef479fe6d3ec346a53794341bed6c7badfca8b5d4f6685ecd05892662a63195ad91d5de328b66cdfa23d4d798aa67ee89490d9b3d945405c68ca0bbfad7b68ab764f0f4ac3a07be811b4250b4baa9285a5fb545174415138b54e8b69b23d73ac43e019158afa04a3be273e58adf3d336d70624e43e763e0809665d5fecaba7d9a35135d6266d1584f423dcb9ede3ba5e1e8ca4e984b5c9fd623cd3e5c92db7da73724b2adba86cd634fa29955d199d6d5dacc6a84f1773d26a2cc31a54d17d11678afa689feab9a5c7a2940e116ee326b405812b075730ae798239ee623c7344387e0b2f6a076ffc3751f44e6df7072355d6b635b1b934d6b4d982a86c6b62a2e8142a6b0b9a36b43567d49e294c545582b6b6a04fe87ba22af105b5a6cd37840f8aaf082778826d34606f145ca301d2ad23109d1fc294cb2769d4c7a491344ae7079ad4cbafc294cbf77f3247e9ac68522eff43987af9fe6ff604a3b8d60fca4fe84508d6d6c4e6e25ef64eebb227b7b4ae939dcd5efe816101c678a6bb19ca2dbb5877059b7a023de1f6fbf80e155c3509b25210d62fc1550fa6e2d6116481abf92da99acb5711ecd1a4a36aea93358d2f663fda69dddcdc9d7aac574dcdd1a3906ae1a700de466f3347b5f03056e9666a5c8be3a9ad195ee9f904e04b8f47c653ddf656e4971e0b005f7a2d91533422a766889cb22ecfc773d9977575319005aec09b6e491dbb58276b1a446ebf569fc11c97cf31b9d0882e3f437c790188421ec0299dd2b7f033efc20b40e49447b5ef45d479f9185d509f4aebba15d6c5a675398a6bb5b8160804cfb4c010c4004d00aec015b8a2114b3f436c4100638b8f1b507705cfccba2674b10e0ab78be5407fd29fe38df625f77a955a780601f033af43be0befc17cec28974e552c6aacd3a28b7531ae0982515fcc4ddd3d81511fc905211231cf08db5521e4007f40dcde6a4cebb4e862b3c6a68deda1ad4e8b89a2476c35667ba64db3e81113558968db73ab507d8267faeb102a1445b8edb022c2705e946f8ae085f5dcb28bb5603c4f8b08ab0b1f8702aec539c1bd4cdf079b365f6cce985f6c7e5f15f9ce3ae79c458427b7ac302e36df01738462c84ea8fd14bb254d7699e36260fef6b383a02b80cb3f3be0b99e376f62f3639d0c0561d949a1fc60a09ddc146e2769b21dc5bdc015b87a119fb9579d54d6847b559f3e95600f07eb53597b6a10ee08f7dab9f137071d777b1e81bc3c93263797f6dab8096d41ffc51c6571c0a6363296360a2f2d106ec73ed807fb60dbb66dd4679afaad0d4317f5b12e976dab1af59101531c3035c2348ae9e253f960a25b7eb04db430d1be883a3f7c8a67014aeb84fdb93658b1ae23e1fcd2bac0161a4a2f808f400b3fe35d7c3b36902a713ba43843006e24e478b85649dc2104c7cbb730eee0e163a7e7062e6042b5f77fe671fccf8c3b6a6a8790f9ff73c401f32e8c3b60de46ffbb20c2bc8c28e30320c63c00c4f149517c066f5a68a82997c7c1585021841d4cd17aa954a997b7d10fe0948ecef8ff3ae2c37c155b725cbe068f426a46e4940b22a74aa2cbb720be0440e41400fc9a461d9d0ff050a952323ee67574c6d7f977791df17560fee56d3429724aa693c1fceaf68b630c4f4f8cc8a951e4942872ea5d6474b1c9bdacabbe0deb933a7e5d0ee74fad3e67edb4d6655df365c51258b0a93f0a57d03c70fbb9d77c4dee35b9edb78d8b4d53bfb5312eb66d55e3625c136e3f87051705ee0a9d075e2aacc25e1461782f9fe7202ca90f1326b831609b66cd1943a80b866b689f52bebf2ee993caf7d75a655412a95a56d86abdbc8037e07b313e0e533e0678a3f231506811a1ca7fb5d62ec635224dfcff2f368ee00de8a20f4683976eccabfd04bb9fe0033cf5effdf7d9ee8b3da053e2d3e029f163b430806bf15efcd2b72e77cb4ec6575211bd1f1e8fb7c3332d56cc4d9cf75488d01b3923c2559f588ee25aa36d853c5a8f65c2a7fab4e4886fb917c52e564458635c53eb158ce2626c6aae56e16e516575a6a96e8ed882e88de216b7e4ae3884baa84f8d7d8d812b47591bb3b27076fbb9568b6b712deed52cea43eab71b8ce8f5783f3c1eafe5ed4c1b2f053cc353c19445612446bfdad500f84cb4c533e02de9ccc7e1c6db76eb369e887c39ecbe05f0c6fb16c01ba2bb89ac89f36eae93aeeb9874b7ec625f28cead539a185f760b0b6c33c39ce1e328fbee4db8a6edd7ab89de8467fc6798368e059ee1ef5bf4e0fa1fb9a5bd62fb0c11d611a77deefbd39ac4e352a9b16e8d269d633137d1675aa70abad5620d1b4d5286c9beaab8e6bbf4eb8a6bfcd2af3dfac4a23e2f9e7ea55f5f8e1a3d253d25c5c221a14b974c9b79abcecae7df4df5b66ee3ba1e8f3d27529948672eebd3f6f49d89cfbc499fbc49157de64c7c4957cbf98265f4a4f7b781e328172befcfefef79a2cbc41bda0844e5bd7149a354461ae4262a74e97b74e8d2d73ce6289ba2ef32ea4bda445fa3ef4c2e7d9a44e8b22f3de64d9aa41e6b92be2f69923e273a9326e977a2b720a4335993f487ec5297b0e55dc6ca0136d16f31820423884b1f089faae219fad5e5a8961c956779184f7ffaccd7e85b9efe8439aac57bd2bb3c0e92f7a4f7c61c708cbe65dc21c47ff43ee6e8c01877cc14cbab8c3b66eac5a4b3d9297b230d6a920ab94893ac20ec161582215297487d8c08290d7294e71bfe7b554561bc3f8a68c5af493a7e6fb5b065f4608cce2e96e18d5bf0c636e9ccb7a4de06ded80dbc21b2df04bbd7c007784ae53dd6a72242ef75a015bc31bdffe153301e8628a4f4ff1e06f8e5f755f5d12f73549d3ed9ef93f77fe97fe2df202f888237de58be0752f0e6f3afae545587272c6badab20927fce4356b8e05a77f728cb5174c5af1a1f8b7dee49fa34dfda3024919a07e0d3eee977923ed9a7ddf2a8475b7669c72e6d1ff489fbb2875a359ca53d5579fa629c3e5375e9e8af702c59764b86d1d0aa68e87b2e54de9b9f0bb1a57ea768ca6bee160119d1148335ccd468dce1434ae55bbe2f19068a9e039ad524fd16be2b22775d06e17b8c3e2dadc73c4f34966155794f3db0aabe91864ee1b849ac970e11b28f707e2772e28a481257c28f6754ac0d43aab14e1ac6041e97caf6b93e6d7a75f967f5e79aeffae3700ddf1c47b97b3f6566544b8eed0f19d542dffb0fd5521f7c4d3c11719a863f1512ceef39794dec1f4d7af3340fdf56d3f06fb1593ec25ef5a907d730db60d5f539bbeeee412f974f0f0f8a87fee1c8fe39e000eb8323c94dfe75cc0187f79f37869ea3d38d3b668a1bedb863a6f805f3dde3517b6b81e7d686218fe16b226df2c6f7f55ffb91ceef39c26e0ec2fed275d0038f45189e1aa817c8e997eeeeee3a000202020282e2050510140c34818080808080801868020141f1820208680231d004026229c1922230e0d94193223020410f234eec14798115f389c952f094828bc09d7518266f228ccf20305b26ba6bdb013a876097981c83184c66666e4ac16c97985230b3288a73ce8943eb882313a2e7762416abd13760d1826d3be9199e5ab8c9e6df69d9255a3168f1c060301c9e6eedb45a3b3cb3c5c3cccc76091c386dd4380dbce1388de707bb58870e1ac381e328c7f3835d3a74dcb071cc6e3bec1293876eb55c2f9e1fec62e6699798d38a3c883b9a5489dddae169b2749d063cbbe176cba993fc05c5f5b10c6f6f6369af75534f902691423b2424d2476eff5ccd1e3e26a9c747ecc1901f1ec87887678bc78784e55cb558ab1eabd56a064ac5dee956b79aa74f9cd334fa3711a7498659bbdabe51bae78ab4e1f62449862b16d983e6202ce76ac50af9270bac48d25fba70bb45d36a777777777777a5cd4bb8f386bb9bc55a6b1aa5dbb6e5d05a7172ea38da206b34e935728ee06029421caf51df6bad3c7984d40fbd7622212944e19afee9e107c23ada267578f86c201e7db17adc80908be0a075b5da69555c69f2062af8e00049a7d520a195eb3f3991bfac51836b782cb9d762985f89cc17cfb89adc50a60ffdb2fefcd1a4d771f20469d27f4e14fe964a1f873e951376c53186be15a5d3434054405497a5606386162061bab85e84c8eafadfa0a35286f5c9becf213c539f52cb3c02f1de463b7de64a5f6c9181015c055feed6e01a0c706f00aef9d1d39a0cda680386b1465f11a6843af347d3f0204dc337b1fcee6cf5a9f2fc98277effe9d32716c2f59f43b886f99de79d489a7418a8b333adadd97293d780c16bf4a9f60c3c668aa9e8fe359cbebf02e8bbab9952eab3b5b9ac0957b89afb501d5b6800df7b1ca2ffc61d4232c055dc1c7c8b2d2e0ee4dcc2ba8974ed10125791f2deb75bc34d3808e7aa49efd1a4f3e0267f4f9c3e78c6af104e1e9f4238643b7c02147ed0da82243c00685aa910b4d2945b522021846821c249f29276e827545441eddb3cdb715c67bdedd3c02aa2271e36ca4cf94865bbab78590cc104212c238111564f124b80fc20c1f9b5e71de5aad5b64de33aef0359b4fd609d34041fad45d3686a2820c706e724a15669ab4fa772f6ecf8678304d8668e8067f83323e1963448b83cda254256327b5029c272b2e658ea11c8f636704dfb808029331542fe15785cf21803dd735f7f7a25796d59e3da6dfb3eff30b0432de7ed7e13456ff33ab1afd779de58e6b8ddf3f6dcdbe82f8679b9efc409d2c0bf558ede60be67e7dd3afeae7beba8fe6eb40c08b5a71aa8f499761e277eee72452ff8c4db93b886fb6de36ef815f945a2ff89d8ff897ebdff44eefd7bcae437962f6ef7f44f44eba6ee4562f760e78d249ee9de86dbe86ac572877ab7af54b441389f865b91f9dd9b3b41c584164c968227f370dbc0ab2f1fc3f328ecbce03b0fb97f0eaed9aeff0d5cc3d75f87a374bed7d1fe873075f2cef3e47f0853305f92fcfd9b24e996c35133c5bd3579505e454a517177f7dfc6d056c07f86803973f350c4f05344f047a2e857c4f92ca2cbbb105b5e457cf1241186386f879d072372ea84d62f027d2a6b04e5e0c8e15f01afffb77e053758c8efdeb7c8a94f8309ff24f4c6162b127b1082e3e545df438c3ff929f6f0f2a2e71c3ce3ef4e846cc79c90b6d8afa1ffe46b982ffae7910a515052fec71d2f9fb27dc943391c4592ddb0430f1fd779c9f5a973bde3b61afe30780b0d281f3e0e940fc71d42b8871977c4185bb6ef3f7994e7461c290f8e3b5ec6163bd2d07ff22ddb88a3ffa405c7fc94d18bc495771159be85e547afe3e2579e8a2d392828292d7c61d43107e5755cbc9722dee0a695910b1692bf8a8ac84395c34d0ec38b84ac03fec9eb883efc1414ea3942f10637f99f88227fd06bd4b8deb2141f6ce4878dfcb0911f950d1d3bcc421d5cb35deda78f33f3c0357d35122c7c6953d39e071d74880c7c70dce11f5a913955a358f130553ae81099f58f49c8b7bef61f5760c5e2e1861cb29fa14d0128a20e22da6f4f72262456000f2291dd047a3adca4e134a9bd1dfd2724491a37e120fc9244e97093f69ac66924ed59f6c3a17d1d32550f70f870f8983915cda4a9c10e0d0d0d07b17a30ab3c8f99d9653c6b929b3cb7c8406f7ffb3089782e0bbd95c71f056f7868728bca1edc0961695d8b18b4db3268b7c7f99b3bd35a356ddbd85ae6b8aef33c52056fb4af49feedf6b762b9eee69b9ba8e47139d4b4efbd130eb3084b17d8bba756e9e63d37518b0cf6f6ef60a1c003223f7e10e1812bf59ecc230b511439acef593033dbdc32e4dad391000e6126e9e96fa37934ae63fe923033b310950845a810c208122c6810b64c503a5574526bad9db339a39b6bd5e3fccb981333094c92050dc23c9b4db886038ce26042987912a65dc232d141dc7e6df6978b50210463c1fc251939190d1378fc5e8ad8a96964bea815742885ce17b5820ecdd7b4d961ce681eac98281f98cea7123c81cb86305224a808134890086addf2ebb9e58aeb962e30233f42457a60468a34093c97859e111de8c8c0082c032173e673d94811d52de9657ab9880c5c708d1479156142e7b291223e4564b0e4b291223c456440640a234e10a1a2c81241978d3811a4c81234b85ca40776e4b291224596e829b2c48ecb5cc65c85aac810b321965c2e328492218230849115b856d073b9c80a5a2b4002092490400209245e54ac900012455164a0c94013088a171440400c34196802512160355e342ed2e7f27b8ff378cb59afeb09b818e03877122d7be752e76a75ce9d2b12cedf9e72ab92b64a13fde749b32810adce8996e32610f78bebe82b7048c903a574d2f9048f4531e761fc07e17cdb5b6bdd762ced06a36113e9c9f0a35278fda565723ef7c83c636f0e3b6ebfd62d3ec6d0d77f047919d1c1cb48904adbeb4f5300911d0e7aa26d68b29fa78a7e397b706a631f224726ab6788ebb569b47ba6ec6551208453d6273a4e9d267d0462bf7faa7ccc11812655488020c865235cfef9a107d73bf95222f0f29c42d1a6a6d5a923c342155a9d381e0418f3c73833e4e4e000c166c8c10182cd908303049b21270707089683933303106c869c264b864da12964c3ed9d06618a1eb6dd08388a532ce3996afa2b119a431327c7b62c4bb5121a8ac978e616c74d5e8306f643c333e0e4fcc0762cecc7f287d332128616f663351c27609c1a55d149e8292a2b20a770dce46193303b85debe07f3bcee71726cb861071b7a7b9dcfd8e7f646073b4e254dba3602f9de69be912608a40bfcc20c38389ce538eeb9f72ca7e1584dd3689ac49942eed55a6bd5386b990082cbe1b836f216434aaea34c6ec29a039a6be138568e0d3b087193a02d6ec94944413fb125b7e4215e32e3aa50912b28b9fe5f9f46b3f6cf7e7b6520711f6a61b881afd0ceed1eb7599a47a04fe5e7b0a185f8e78a2a2260038efe8929699e41a0419082e7f1bc2162aec1e3e7f7b8699b7f4e9ea1cd5fe9c9c7a766923e6b1bb8fd93f2892ffbe09ee84444551e3baad951ddbb56b717983eff2696da851766b876a5ba70b47b5fb91d0e1d67ed38533ca80f5ab70fbc3642c58e7ab90144347358c6a2cf03d730a594d2d4a83a7880bd705c3d3e73ae26abc543123905c382e328fae214a5afc34df4493be8689287a6213b62a3e9578a23fb81014d6a471e4ae90ea554081fbad1a6d4ce1b60392a40711c454303a381d13841f382843192483052d75fbd1c78867e15a74a079915743821db818ed9541d91e96041a19f22aaac8c5c9cb8e0a1d24129a5f345a27526e1bcac425132dbe9573fea0a4b7ef1744d227db224a95bce833bab57a03853bd2291bc4eaf19a4387dd261077bb9efb73103d7380afc7e1bfad4bd27fa7e1c1a35590d609f1e3d3a4d6870fb4bf681a7e6906e25d366bae68c7e97127063790fd7b4692044700307c5392476f7fdaca251df03597d0afcfe4d04e28dbd120204d854df082cc0c13335083000c519d854930491c1deed3790013c531f899ddc223af2984165396aba864c9be962b9582e968b3587746a2a99367368cee89f43a0d83e7ab40878a6bf8198363d02ee12f04c7f399570fb6d0d389e73c8a792f94f2285a11225b78374f7fcd86953ffe68367fa3951871dc22bc4edef207846f7906e25d3a687e01949901c192252c4ed2ffb08b79f5ba5280d56935bc4009e992924b70eb1dc02a29881b64d6e910c3c03050d2888c333f5891a50f086fefbf37039792b93f5dbf2f0435da7fc9834d79b7452485f639a829086ee374dad36e96c4a9302afa666aa7b369b6877a9062e2883ada90627cf501f6effa4298ff26caf559462f7ee9557fabbedd397ee0df4947efb6b631dc7d97d62bb81d0497760ef37597ab243124b8deba1a4bcff0b9124b2882ec491b822d2904d36b9b50ecb8da1682c69684290869a42196d0c569e246940d9379635bab1b4bf329246e6b823b6b974bb6f2c6db8f699ecb8677abb91e98e6b6df94dbf444eafee92011622914eda7aa0ab3375efae6d2ff7d313202425faf4a552a97ea4d85a1289f91424856ea2480e66b48a155b253c06cc618fa5e91ff0faec537bbe9b2b11b630000603fd7ff9b6c8f0b7fedf3a428189222011020a78004516a9b247f26fa97f5211c411b2b8ddcd039ad7ede6d9ed534f29e808c4d2f437d9ee231512f2d0c0e312d34680bf487469537d92a37ca479b24f5304f242576084c14693b556d1835f837f8f3df4fb83630f4270f47b38b66ccfa993e714d534f0e9ab6ee1c9ab1bb9b124859b168261a58e72d6e6f5d8a5a5d6d96ab2f2348dfa3a42365b61b8be37123915632587a36ae5fae356b75adf7fac0f2be6b81089f325d6a75e0c51f43022f82f1ff017fd07fac1ad46fbfa0498a8a99a3577b27e6efd397deacf2147eacce1f5ebd06c591978a62e609aea572602ebd672ae44771b7160e1fcfe62882d0f23babce4d08d2d1a0dd7705f7f008c9a45b83a5f3c53396ebcb17f24ac7748dbde898474c8e78b6bb65bfbeb84718dbdb51e09fdea40af67bf0a700dfdfa1660d434824df52b1259dc5aebd371b678a6be1f09bbb6fccb47c0e563fc0473606688f1e246c21c1c98a8877ef05b447f110dfea2c7e12f7a6dc4d130c4f05f88274f12539e4544f915f1fb91a8f276b39b06d693faa1581f45ac9f22b29b54ea7f75bedc54c71c4dd6af1db4b50b2578d4279cefb4722fa1b952d2d31a9772d08b41f2b918ea6b6fc337b1bfe2c0756cda3fb84111b7ed65b07de878d4760e904a7dda9ca6d65a3567cddd46934b8425e94f7294b596d4274b7f6441b0eecce59f23545cef844b1ceaf0cb46d59edaf059b972e53aeae8ef9ec7b0c9f936b83904c5101bf3357fa6dc92f61ca249782c8a4a84b307e1fc49c7174a9f1665ed56c34d3473f6a471afe32016e2acd7d5e0673b926ee2679e9e3a1f6635593cb089898c2e941f9309be69cd63492ba59b6bde4e5e201b92785aeabf4df781e5eeb164fe3c8dbbbb7b7c38fe8dfbadb9fbeb38a657d3b41fed38614a8476b3fcda0d6c6abb0509cdb96ddb6f4878869f267c91ed03e5b135070b7211f7537b0d902ea3e6ab4597f5b4717bdbfd5fcdfe77620e09e07129384e22ae28849dc351dffb1c1a427d2368ed1c997bacef0cb6e4f4f3ad61bef72b4d863bd4db0f3e8fd40e2138c00fff7b1cf3c371c78e1e29f03b1145506cd1fe86d427b668630e4e1d6d947fdd1b85d0a7e1b55d9df049e7141e974a0eaaac43552f34d9cf24fb82ef50efac51d2d4a0c181c7259ffe384deae041676796f3c79d73ceade6e85349734305e6dda14d53870c427f1fbf9285e838830df6e7e3d4a079219c3fa7abe8d4f1aa4f782c8a2253efd7e5497d9c94524a97f8e1ebdff2cb1ca5ff4b22596b970827297e93ff9644eb53ef1ef8f891a4053e72c07022023faff36e21ace53aef03452727a25054eef83162832553566bd582aa16e4932408d6a7edf927928e13797cf23c79be2e0d8b44b22d9eeb251779814da51536d5073f176ed5e1a578273b65537d4e64366d36e070b572c7d5a68fcf0cba5efa9085db1db8d686a16b4f015bf238829510032781870e6e9713a0e3f3cc14adac36078323fd5f6a94f56786e1855b5db8f54bcf27665275afef472e8735acb3fb27a554b084a044b36695cefae4bd6ae273b63d97f66e238d9b9808cb299331699667e171a9a4accb2c3eede29ae96d0412d77bae7fc922badefc365174554dfaaa696c22d55151a7d56aef3dd8621b9b16116e01a77ea824cd3447492d19a2110000001000f314002028100c084462c18840910435831f14000c7ca44c7a5a9ec8a324c8510819638c31c61000320022002233b30d00a8cb1a7d043c46d7ea4c9ce89719fb0e2496fe158c385344a933f66e6e4e9f6a11140ff93e3843aa68e2ee44d3620ab9f80e019f11f919f12a9a08d0c4b5acbb690016252e83b434ae855f06b995cbd45e1fd5e38da47ebf66b3047f0f7e9d5810a6068daf102bbb3411a5379b8f45b3a4c1250ba5136bedae8fb8df2aa2d463704fffbe57d6b79a759b3e3db376bbe3766942a65e17fe288f081e2544b42e11dba803ec8be25c6311c861f2629c611ef0d9ffe5e07597268ecf6b5a84c73f55063d7f36cc9833c564208aae3c3703ddb06e8cec577f612c41baa35923ce8c7120f6a115e8bb6ec0dfa4d1a45e2cf7aee85d727b770392b97d69c2330b7ffe6a49503a0bfa0f1579f6cc457418da3ae508fa368666b04b17e5a88378b479d747afbae877017a47b22ce7b5c9a2dde0fb760bdd66f05894f2cd0a37d72844c56b39ed27e663927b36271276f2604bed9edf040fcde1442d5124fae104e2094bd858a1283c2b2933e4ddc81ecb0c938173f313f9b9b72ab79f637a3db5807e8fd64a71aa70a291bdbf1aed1cacbf8701744ec177c2ece11984898dd73506fb97848aafa9d5b88d6e622203d5682dbcd908f8ed5b3d625d4ba7478f8f2f649d5052d329feeb83289807f6a5613b4ed464e7ee63b8766d15292e8dffc9b5ec40b609afe9c4deccee938b70c2858244671c990c21852eb6195e6a8657dc98be761895f8ab45f7094131ce98208e8882f920d14a380d0d53b86d9111f90048601a1c9b1b4b565d06503390bcb5e826ecbf3f0d8bc3b5c289f0dbcfcdf03a48770a0d03f282685ba1348e22e2fe72a230a37489f3404f03217df3945786745772d7eb8af67ff3585d315d8276bf27ad96bd0a35745b0efb05ba232791a4164027f681b1bf9ad88204dc2392cb0184a26ccece40ba50c55f60286f3d07456e254c5ecc9ca27db7f1c12f0752fe87a29fd3061b51a704f36b21ac38df8c71281fb89592c8f2380d8ece83a4bbec51b741a5c89a53e709c13217a69620e8bbab47f52ad1f9116d637efe2b8cc2984603950c6b1e623e5f256e91a94086f9092f51ae61a29ab24eb6685d69fe8cfec33a6cbd15b9c3ac5986174bc6046bd6021c203a62bb56e55392bbc0050d230af51cbe0fe81811a3a23c39cca353a935d2ae69b5ee339541fce4a65111d7501c371afe618b233288f916c7c9041e23c1317ee89024c619f76622b7131ed3d1667bcf35508faa49c2d2207557e8846cd19dea6789390dc36edabe7e3724582f10814ec722f885a20b5215bbd2ac4bf14f6133cdadb34e9ee80ea91d6b4c5c246f642ac89baa391e5d681c81c7e2fa9a274f44bd254daa5b68f7d7827d567723de68a0a13f87a1607ae22ecad36bf6b76aaa9cd938dd49664dc731e7d6d8ff36493c1984e6d31ba55b2e17a23c71c1ad048eb2a4457962c300ec0121e169656d657800e1d32bfd5ee44f5aec6eafe2873c5c4ae987e9c0b09165d4c3f6f6be2ea9f34ea8ded9c8c5a421af1fc991a5a85eeb07cddebf89b54391d4d06971f244beeb90d08aec6b9b0750d2eb3bbb95a891b4b9d5159425e0ce6d04a5c8a5633daf5d26513464b87d6d4d3e06b2ac1340ca13143df32e8c2987108be04ec4a0eea2ed330270a7186d2816b94ac072a4a62f53f69842d978937e392a86712a563f556bcf59656e20e58988d289a5af7a9a58a93e85cfe3eecce643da6e7ff5f00c529e204cdd1f6e4eaeceffb91c9ac35f75dbb984f1e97a18a5ce82c4ad6ea19a68f185fbc39bba9903068128f39d5c4b0524437f2af5b01a8d3b909306355ccd9a6c943bb8b8f90400c298ca4cb1b5f0c4c5617a8fc582b33a0a74d677c1e937137b7608a655d77fba8474cf737354b8a85c58528f728ca99767d25a21fa36dd84c097e44072f9a826fcbe5be135add9337f27c889a1baf6269e97005bdd311d931b989710f985a280d94c84f02a4f24653c9b22c47532bd0ec19412041917f1d0aa407cddf5f05e275bc5db7bf08d531fe94caed003d7bfeb21b50e2ed24733202071d1a030b446b28f38ddff4072641d71f1b7e90dbbd1592c619539405c190bf2d49c33e4cd9d610f1ce0b61b87f0be8c9769dd84544c7e5150df69477b4223ed2dcfb7b3cc4c4e1703e70802d95583203aa3ceecda877cb92644642ab85c8366dd0a905a69a37ded11f261291a71ebca8d1b9c52444506d28039a6caf4aa55fe4b695baae3afa8815c6f5d4554f6c58ba2ca8e65d20c29bcbecc6c6da5b68fb146a0cc1c558032e195e231db9fe54a3afbeb0b2a2d7a9b5618a29e599e08df0cc6fe0bc4823dae3e94fb1ce3461f7e8450c24a1d4a10ce143e57d4a5a1fc4ff594059a2c9758e616d4218ae92954048434805a7dba5e6ac182a12fa210014787968207dc1635901ca1dd10a81219683d9f17d27fb18646078293c57384e280a850838e86985be9346423ea719d2c112a588b9ca8965b2f06bde5896decb8c591acae489aa26aad6624d94923fd2da57d649d44a77adee1fbec9badc837a273819eaeadc4067d7179423f1be614d069e16e8a9eea2077f3d7b22bb05bb428f334fd793c27aa89b57c75db39e9ead6950d95a1593d1204d5f269b6a2dc20c05e411d7db7ab42d341bec8c0ce9a0fc208faecbd7484a052e67f13b37a90009f96350c608dd47e9aab6c4b666910957876b5a489c2030dd9023bfbd4d3cf1972ca336e06f2af1be1b0bb3014f39ea8a710cc2652df2f0add55c095161d40919b1206220a5b6381d60fa613e2ac43ec1bd3cb6d70e80e556b7a8bbbb5a8359d42470031fbf53ad946c2c7fce4507d4347fa8f00e7f91fbd40f6cf39255d076e9ea9580f81c0b2a51273fc5ea1257a6a116584175f48cf941856873dcabb3b69223f8c3a04f2bb36620ca9b0c490fdae6d05c322629d08e9c854bd1c8ecb4c063f42aa5b416ca25b5fb1f00cc1dd7b624c1a82c854f9e1e817d9903231b1a82ebce059f0de18b98832c23309eb251a8bbc38a8982240774b46f2452a616fa92681ad650278183eaddf50492cad2aa9cf08d901fd4e02a64312f7f50d9b43e62833ab247aa3e31a0a751c35c226360887cf0329272846899db780c11df96f18fccc584f9fb1c80b32779fe7988cd844197111122c23687ccfde9dcc3ad399551959396c4f2eeb08faab3160357547842c9e55118b234b19f54c0aa80eb93bb4e51e71cc0ad14837e72109b7f8d4dda1f0d5a9cbeb6f346b7c941164e339e84c1f9a7d8dbc3aecc701ed2485fc7b760b669411daa203adc7a28cb8da3accc3338320a664afd1f0f8128ba488a8087bed8656a459e260f0ed9fba8f2c9803dc0b4ba24291df277e6e38536503fe8635dafc9555b641033b9171adf89f5c187386386266020eaf41d86630a4026ae49bbd6a0a1a1c556dad8db2c4dc55c4fc2b8de5bfa34519cc0479962330077fcda354d95ad8f8a8b29265acc56fd0a8a0c736fd18cde0f7968db14e3e09d0600c0bdada812bbeb60762a90a22f7e105f2e4e4c9e6fdeb860392b7a5231bf58937c2f58604011e8fd77efca3d7db780395bab4872790aa96ddc1130be41602e3f91535ead4150a8aca3f19adc6b794cecd541c475594290e98b5344ce58f3a8b9ee20931266a83b72d7fe1bb30816bd01156e82244a49511b839bb3b9030def9e5131699da2308804c4bfcd169f2b5b5c37917138c9a1f0167d245ccfbf267475c616cc45e80b02aa484f06fd63f39825ccf80080faefdebe5992b40bbae9c525ad0c1021b1488ba7d0949767cc69cd83756236c5c624e76a3190deabaf4a77dfebc8712b1cd74eb62d8fd9d9b52a52c6257acf17368f39979614bd26e8beeca7c088448b50eb797b4b0d917aa5e8bb82618455b6fdae7b15d4ab7938cffa3e8d05481a22882d715096cfe3069f9c2fa92f85a5ac4a09f72c5816ae2953421ebcdfe7ae8460c23db37c2a0bc514817e726aabb1856d2c3d728b6d01046284af7008541b5c4ea5b50ab16fb6fdb6770f200fcc0c17152c5c597476fda82cae4b13f25d5b3023d441a14daa2e617c2308a743adbaad669425dae9dedd7b6e51cd76f871199822c1aa282ae405c93115d485d5446b930bf061d581019e7e2e3a02d2d29f0a18e03e186fe3a609c0769d75adc1ad96bcb302c64631b9eb80a1c1c19b750e086ff2e5b8056ceb8d57d45fb87505d4b8a138f2b77f30820cee0e6cc3708a46dae514a77897f0c194921ad9da5d6276092241f08d7c9a0f3eb9efa25776065dc6893d5bb656f17c9d288a38165e001c3cbf6df74920f257920d23cc76c98fe0610037a8783498ae31006333375205255c10cfd15f126578d072b5827f15c48714f19860c174b1bc0a2d5e78ad3f4fe8312b98a08f150da70b0f47f3a1573e4aad60ada605bce0acc375a03fbf16cf042b30857ae55f8597a038dedfb1894f8ca344acfdc369be3334ad7d17a8ecede0e27b03892fb74d5b163d47fa5f11f7d04b5163ea4a379a9728f2ca81633b58491611a10afd579aca83b9c5b9128ad0c558fa3c4aeb51f0ea9be188eded120849e7460987f9c4300b30c043ea5b08c8b78e476bba646a3fd74d4e751e61b8bcb548228b4499bcafedf76aa7726653f994dcc185396008b9cebdee5bd56707b37359120c623e7511806098982bddf3785477a727e4edec484e1f6d530cf602b9fc172d0e0efd5d89ff6b9c49c107611864470d425881a22a663b45abf4b5c0d52fd45abc0f1dd8e1a70818084a8682128b85db145a3e06609184542a92b03ea082f7be00b28e84dd48a155f47eb950bd221549f349001a778995ac5579f6d575fca0aff1a3bce5e2bdd1a6e8bed55495f87c017a1f49284ff3d1e08b70115e3062a4b626fa4f41cf06b8451d5bba68af1c110526561d3b72748f0c3391aedef013273170ca51fc145d36a1c19c49eaeb1c72967bf133526680c86c137fa870c896192c36e895b4f88b5364a8be02849cb984eb12db0b5d71284f16bcccc2de2e2edc3b9a06b518d7d7b95d1c90a9dfdea4efe278e97b08997dba192e158175cb34dca6387725d79207ec56efff5e7392dd8c0da5bba1388d6a2bec35cbaa4f2d302eecad4c051e68f001c2da098a3d518cdded1be6765f96606d5e34661efdbdac1b57da8f6cab0b154ad4530894c45c63344cf8d5bb8bb346893df60d4c1d4221e3b9fbac3362914556dd369b7130f18f7acc92ef9e22f0cbd21b0b1d6afc4f0c921202d4fb9395c860485881826a34e0fcde805f436e27e7775ed2ed70ef103c91d3708f44bb4635c68e489da57eb8599fa4c1ba0d802a7f688004307bac323250d647878c029089801c74451912e89aaac9bca503287b93a865cdfc7f6feb9eec51c143646e992a792d195db442956b5b0941a0319b0d00ebff7c40d212400aca93ef2cc9c0e48e69476c600a7041c92699f9d942aaaae9444110b2585034fa0374717d54dba8880474d812c674ded92b5d1b45ee759e18f3492be94d935fbc548602662c3c48455f50318fd23ef4c44ae2181f83d45bc653d87da0ba40307dec3542c2205977561a522d4e06c3f27f0dc111c2a882045faf0dc1f34d2605dc1b55e0d92450fa60fc56f246960a7c060ca31d35551e21ca3ad01df5e4cece65e883b6561b4629a6a16182b32d86039706a007e7f39e387b357173097703c124ab09dc6caceb33400d94d9be2d9b6badf125031274ece5f85385f318789d54d2aa1a6fc99f1ffb2830e8884b7848c1cd33a205f2c088f0a5c9bd196303986e7c0cea73d7b8760925ce047316635fc556533ac2f8acf8d97ddad63a07aae727886b6907c37d62e91b0fd6b0be518daa1f90dad78c940578df45acbb19e50ec3c231fb4f43da270a814be1db40640fcca39751842b10bb901ffa730bc3efd9c92badc8db5abaa1c437ac6b05a6b122a8af636cc4649f5739343b206d52aa389d251e30aee92d979530ea7997359a5d4b4e617cce324873527d14e0bc5dadd95f9ade921f92af29304911ed7a7b17dda642347a582aa15f630687b00afbaa31ea844758925167047b0b09023fe64e5db268a851d49c067baf11c5dec13d6de519852744286307382bf4b38f6963dda4517c6121098b2ca3bdbb64f7a155395b358c05e34147f303985129689a5ac300e461c6bdb5a4b292aa4377ab08c38269ce2af734d00c3c644df711de2896c14fd920d2b572246937d7d64e8442bdcb2301be054422f99fb9ad658b0a0b1617022896ab63675bb050ab60952456dc35812de9051466491d02ad5b8a67a236a706e8d931acc43c5b47252ee37c619e45629f0e49c1cc321d3f7cc4255da28af69519dcd6a46ff7364576f90f524b0289ccc59ceb6697e6b48418e1cb27ef1e744d5710931385aca97e1de0caeba6a7974f1e93e784e818ba150bb9972035fe4c9e34d34067d6e126dfa28b5869747d171a0fbc2183f07d43a3b47071c19bbda76becce6903a24195b41100c5b737ba57f57880bf8bf2ba3b6c9cc6139eacc8d9a0dcb915fdb1120f229ed318ad25b2a105ccbf3f79b166e16192b11b365abdc10f9800bb8f09972d58a9d17512651bce9f9079384a5d78f2ead2285dbd03526a84d8727475d72fd37c62b04beb4d890a708c97bce14364ac8c9519c50f3f49fda1165d9db2221aa7f5ed6be57a9977148c85115ae98bb1309639446be3d348e065542bc2a465cee44f7e6a9f8a26c4644b49f88927428e2384835f3455b8bbcaa44dc46ed8a493f74b124d1d060c173660df237a9d3e9c2f457515f570cb1f683fa7eeb6649b67fecff244388420bf428e9f3bd915401eea058f36ba94b905b63b8d050491beb1606f020324e955244f7a3ba10258738610dba7a79470774d65f0f5510eb68b53e19d68543a50960901b2509d21723d9f77b41dbb8e980322936da045802d792ab9391c9ab1d1a12f74e32f21294fa9690248203d5c4e58c175e4c647b28a2f420490699112d8e412211f1775ac44e98e042519a4510cbf5d190fad2f5c6b459ece3eaa3b46895568e350f17c1d6aadb272ea04aa4e5d4fe2676d1aa2aa02d0374d21cf4db1ed064fe4a1c554056e0f885e1b852af8a18af8fe2962835e9c5c8dae6b09d7ef2db9a7323278856a458485e60d10272300d04b587b61795af9530c0d07ef2378cfb7e54e5a874d819322e60ebb92752da1dd67fdb4da194d6cc8bb8bd6315a37e407c1af2d18280f75f210246a19526486c0f2ae628e2fc25e670f834a71b380b068807c0acea67c3d80b463b1d156b4e105a25d35d17fb97adda06e37a5ad8bfc55a0ea368d9dfc54c1fbedd764016e4ab0105a6f68e3b20190c32d46f9929bea2ec5058d055d02254425fcda3d50aa6990d8ac3bc5020e34e97bd8386e13aab25ca4844dec398c4c929527ac776ca05a4cd7be2cc13670556fd761a75da0ec8a8a40662af1c57c7e4ced3b366b349fd65039395c385910770309ff88f9eb2de1f7a316878e570c4a59fca3fffc4351f35f1af5818c7e052ba701d0a4cbf005b701287f795f55d0bef78924196c3e23e3347168fd33d851a67260f2c79e24afea6c46edc0c02e3bd9d2303914dd48d8243250d81b2c05666f2ce4ee0c5db271ff5e87272285999966939b3d6d571c8ce0015cdc3e4f76690b6530953ec3be3c6b070342757f121c2d83d8a6aee996e2a485d5810a7a20a0ae92a74ea0f643fb30e54c87768a189f7a495350140960d49b66138625d8229b2ae21474e6764ffb4adab95c5c9dfab236bdf3dae72334b60e50a2e7e4755c18495574233f4188266438d215d6f0e478974f70806c1601ae9212c535aa5f4a3fc2a4e6f21f0083f3d77c70851486db2f7d87351f4c16c897af4a54d1a4edcd51859534fd55a2e083300ec705d558e5716410968979088d54e5c924db94b570b66edf34fc786b094b5d25465269826653da6f64a2b73f9ae2114c168c99bc83f81ec67b7819da5e277ad7d8429dc228291710634ecbbecc6bfd86deb1b382898e190c70a98bf19b5b0a1615c4ecf374fa1acec3852d4e775073229e2d77f038a103a3cee03f17a20b4c4d32042d8adc7b8a725fa7a2095c929f36056e950e2070b1c2438202453e60df45bb3d079c9ba06417fdc0b69760e5ed10792b96fae7f770fd413e25fff2555cac5fafe44929414348718f3da22714d74b6f8b8cb4105f30f78fe3042aae983232f5fec434b10a25b3394071f9863dd1d0043ff906c12aacd7c5a599d8bc7a92c41730b11d5ecd02bbf6e7529d2cefb698a979eefa60cf30cab008fca02bc7388f6210bd143c6a178b887a88be8b8fd7e9f5fcaa283826a9b621d224a369bde5e8e6b0c24cf21eacfdd4ece601a0c99921d0ce8113d292eba9f30409ee9734ecd20e1d2bb10ec77dcde77a23d5fc71051bb1dadd6555bc168a37a211cea92e78932ab0fd740093ec43a38c4f0d5cd1865c7b01f941b7cacb52df0e4d1cc2bc5095962ffb40c13149403fc1fc052bd31d6904388230a035f3e8e5b85a95ce1b615afcd90b4fa2b0e3dbae12ab7fd4f586ebe0d144b4beaf644265afca58092871c731651bada3ccbcc5ac625881e2513c8c1e58eb463ad5958aa82b0eb7be1548f035fcc3cb1f48b43e2785c71b17edfdc4b900f4cb4256cade606dbb500b884511e2213d0672feb6c9ae14149b968ec8e0ed97212fa557144c0deec57c8a7d3a7bb8600ba49081ff6331b73a2f9078e0c5a37640205d3ad235fc304374c230932d2bdb1695fefd915739f012fe6e5d389b8781bd1cfa0448c4e99f1c204aada0855b211a08cacf5a7ffc9678724f080ae2693bc06c20f899d2a349de99443a41738630e98be90f0bec47372088e30510c61bba08b927333034932586be8590da3d5ba09c86dd1af05af16f5aea0aec21265ca4e0bb1550d6a16047488258a9feb2e72994d177a5716c1bc1d8e3e22997376e2d9f89645f2778464da85ff25f4a10b5dd964da50cb942ccbd58ad23b9ac99bc01d33074f426827219832d274160fb816964c7073ea6ec0b52e71c4d22a00939e0ef6e6c77ddc7c180294ebfd829031fd4821a847b2f3a5febccdb8c0e5f4c888111fe15e8c8ec82ec57636edad48ff9edd0eb1f4e3b3a83a41db60f585ca911ee8d000c51ea428573ce441f67e54dc21851407af3f4ab30019dfcd02bc1ef188c8c94d87e84281d004983c8872127cf83070ba47689b1eceaac57c2b6ed4dd4df996a0265f9f732f7824bba705188030242fdecd57b4a555d6b11e15a74027b98e0f75721cde0bba6928282cf6d7d19d79c190b0cba98f18d1779b524c079b028429cefb7c4255c1b7add84d91a9f0e5aec6b0258a13dadf6e9bab731f6e5fcbb89b84a96cd56ef92387b5f1ee430d14c4f2f229dded8b691affb0349a7fe8ac14b5845e59b27c8aca07138352a1de28968dfe7c8d68dbc2aec7a82b343eb77c301139cec4d7829e0a987b2ace35a632c6efb5389718f97ada1fb94d81b16289badaff77f1c91798989ca76df041db4c242c427e356b9710d6cb3e9ba0acff613c77f9313f82c5c161681188f6365b0bc76aec9990cccb4ca7119390c970b66c2468d52746ef3562cf64c5e0cd42573e86c291e56879bb9376757398f2cb6d54d5707a7bca6f3e7b27c23c47aed08fdee73db6f81f41ce134a35ebedc635aeb11ba74620d93f87306f3c2a52ec7510ae789e2d1ccffaf9ed2f1adf98c66a7c231aa946d562a54f58ec98949adf092e602a36eed0351333749595b552c108aede630978332bf3122d125564f63915f59758f0812b56aed51513d689117c3d32d0a72ee43530c963306e90b8eb8c180b4c4a9040be2266df1e22c0d97c0f87e6461afa9d1978c7d5be65efb03afdf4bacc2d1b3f8a9ed761de1375236bede0c8fad89d65ac243c0d42921082d219f394c7e517ae22705f23dd0607d2d9434a28165bdefd6afd82d881ff626993822d9d1d059451e724cc10bee9938a1eb10d5eb5972e28d421d5d61a3edeb50bb95925b42bb02a548936025a22bc12282d17866dea44875569fa1c36c4e5c2ef1d4768692d8513b954082a18772e67281be236589194c39b62c0e077830fa1788b214429d174d51e1ad81a28bf250f34f9b3b9456c4592b0b4155495597a4092414a6125c2fa07532a980487f4beb6218c3f5075ab694934ce07453f91a11a0781520686ba5d953be5c07c1c1f2b33c06697b48a6680a2bb71ca62faec4d192b07cce4534ac2ff18098632c7e2dae450344db023b0d314c6f00e72081f6db00024e001d5802a6ae23b97a289deedbae08514f9115f4da916e586add065f065751f8e63c956802c434d17cbac97f23585862ff0993ee5a93d51eb051f0d64e1048bf5e7c29d502300aac0319950820ca5ee0b4fceaf25cad4a4f34581f991b4deeca9966ba08d0534e02e51ad20472d53cb5a6a85fabb35bc5256187a84bc3de44a910a9415162d1129e46c2b20d2826c72e4022ac62d127e1fc12d4ad8140b7eb34a55c7a3ba4ca59e7726646b7c980398a06f43dd424d6fbd2216b890d5c78f5bca0fa9ce0ce5e596ac91855b944ed76e39aa19d7ebf1f7c48f536758b5f1e0bdb67628cd5a7a544f21af308fed53c6bacc3c1f72dda2647af3a6b2e4e0d51f6cfe1d516b275a143786a4a7402732d22be7fa0ecaf43aa34b1b491c695caeeffc5c813776360116343f2e247fca6582044fbdf0492e0e857cb45e8e53f7b30347565083b5b7c8a16bf47c156d97504b3985496dabd3407ff0953966317b7ce757e89ca7e8854058fe6b7740b8403990d5e2c7aeb5abab1aff08f89ab18904ca404252d9b28632feb322b588f4dfa7ad5afd0720a646f311fa3ac388b335f3b18fc540a3ace845270f568205b31db4f5b48bd0705d7c6babcec306d9d6eeab13751fdf02692e3b551a953801e7bd3ac4c4faa759ecd845fc33980ab0c135a4a7201104f0236c19aba3c85ec0375e1f1f80e7f6b8d2fae8ff4cbb4f416bddb1e147bca14f93baaeb2703b570739eb2717750056ca8ea7c0f10c85ea5e51e33b0b8d1f6cc9682276f2782bc0b3d406ba6fea105672d3fea9dec0c26ce534a95a3377aac44b38dcec73a8c0d51cfb78d10ff5e11818e61459b0163837a602da3232516dd0e90f97c184cb6dc3fffcc35b17b8d8a1625756231c566462f1786606666697b73f72824dbe225cc534d74a1343ab12e253434950973b512e1dcf290dadb57a34da533ce5572b194d2b6a7160444ddf4df591940f58f66d2d3b8f05abae8dbefc65fe0ba0cf16e679214454fc25653a2332ab2392aa85751bd1e0dc690ca6421c1049ac4dbcbd102972608d1f21bf22b5db6f3324852ca684bb0efa60c120822dc1fa07b77b9d3e19855e25446f72f3e9d6bb39734a3fce902e22953ff453d9bbc29c6b1523179cfdb3cae790d9c6014e4b232224396401bff990e934a2e6dad572d1b8bc4c9544adb866d23167805d0239ae54826fdc22c689a06f885f108d8de22fba1d2b9b5f412d40896f1949033037728920ae01aa270c80961bf3b8cf4457c73da163d91449d3aeca422a5fbd956c74cdd2a7ac5bb92b99659caca0003dbf3c12cc5dc9f5e2374ad69d3846f5044e251e05c4fdabb19f3eec4c84129c7b7a29b57804ee23f0af6a89f24f16f5eb76f28f9f9f771b52e8d2ec85c7cd9e46dfe9e3f17704d79d070708a4253e3898e92b29df58c84fedae6ff737a6cdc3fed00413381b13c2890109b6730d10bec72b4292af6d0980738ba7b73d7114a41f990ee64d89d6e5d0d96a53a5e32b3a16b6125fb61b4d4de7c57a6847510605c39b6111fd6a89e53034a3ac7671a4ac49458441a685557ee80a36b21a3ee46e0544c9c278472d149ecb25a43335711d22ebce562c60471ca9e00b44c63fe37ae4c941b49edf3cd2d205ae61327902cfef5b80e743a0f1b68f5bbb58c109b39092023a6e0ffab66e51bf8324adc4b1e198cf8022ad2b3ce7de129ea686f1508921e5c17836433a8bc5ca82227d1c7fb4468d48c338ea48f5b318262f1ae4d33c43addeed519718a401f31214397830fcfe34b20c1253e16790245039c72e58da2758adc3a6a65b937f4031fa684a3d00d8900e705261fcb8846b7afc92188e5bdca1b6438894c3f1a5c29486999133c54625b3ba7f0586714d51dcd35412816c0a060b740ef04e305820eae63f432037c06ed7858c3fa8a4f2b0e2310895317a831effe90544397b3b44d110b8fcce3619773e277b93a373e92d9c7c072eeb08e0b6236e652f3bb94ad28f02973d8d52769c716c0c22136dbf7c2318310b68af0f60b967e893cabedc4406138894560a97e5b67d903cfcdad0b970d25273e5bea94c4c964dcef268eec6b92cb16a11949b02a26e557474d25c69ace3500cdee4b0af7e08dc6de8b15723a39e1fd790964ca3a870aa47339a9af7b866c95eb447b844ff7d5919edfe8c5a7e454e38a60cae8cc140e28e29e527f1c31c1f47203af6a1156bdf11057b357e2dbeb4af858566826f888fcc801d6029c26d91f123cccaa06665fd541548799b2edb0f1aac445890e75094e9b6d03e16a81688f4297c8cb91fdfe2ec42482ae4829134f382934eb80433c873032378d29af7eae1251e01a30e0bb47aa497c326e5ab866435143b99d57a619ee34aad7af645890565e57b2af55540ef26ca6b2af4b4f0dbdf1af393684d1d428c90ed261968ab763c5f86c13ec5ca4e01ed48b9ede8299ccfcec282b3c824cdf7ae2a01b401f43f522db150d51e32b8f3c0e39693e69f2b46bb817a6b7a11fc3034993bae229b331ea04499bfe4520436aeda166bfca14010cbe4a71c8080992a5b40c432e7bdeebf4bf0334bdb819bb860ee55876d57e3235c131c85825882a6514d27be5a42fad809362a86347328554a19be62f45c147303bb02335e5155751485d4ecfde6085d9bb487ae4fc27affda3f6830a197f6b7dc78d0fa1130aa08f47477c130fdd1f716d643c44d220235148e02ca13ef7c17d6a1c9c184bed83fe0348da999528c5b86275694a22ce00432fa5d5a2dc5fdcc7e1d68101be882f42b0bf76b1927c4f29f411748afd05cb1ae1814838a8562b3d80662d103e945e8717804a815061ac43c3405fd58fb2b00a17e41f02b0147832100895d41a427d06f621edd805e41f3c532a26047bdecbf8392fc1e384034c69f14772a5ff16879a0a816626dc18d867b0ad14d5277bc5bbe9c28334978c97710ac6f9438463b56ca4c42b6653eb2fcb0da879a008b55c7f5c32a179b6ac6ecccac8b253c6195761c6746a4e0b076876f10b0846228a4437804923613baf6c7efa41867859eaebbf6a9456ff446456faf948b4792c937cf6c9f05a10f36026004d0d8211d0e513a03a8ab41f8c859a9e82e8e94e4b32cd55cb3196edb487fe5cc0f2e68239248075d6e77eaa941d6422bca711fd0f333fea4b1750cc64475121bef7d6eb39c3a273c54af136ab010b933137d3b38ffa5b8f7b0711bb5dab3793faaf26bbbbe1359b95b221dfa6eb3575e8217897602ffa874cd59e11fc22bc67d94f5395b740053f7394d62843525e47d25d2c107728d9544dc1272f96e5a53dc09369bd09c4ec642b98e58ae04cf2c66c4a9d192b61f90c32de1e78308f16475d0be3bbb2abf492e8c5b94b907eb40065cf50907800bff9fe2fa6e71fdc2e5ef3d79c55abee293376b18394f8a6d1c1b25a5b79146e05818d20ddbc009ae4fe84c3fd98b8921231c59cc509ec2861ac39a708bf206c95b7000a00c44547b3179df1e4862727addb678e95fb1ed15adda0fb8d89c75909522f00bc2b1a8fcfedc22e38fca599638ba1073e2ea085a3d35cdbe59702034fdc6d44a779c2c134c5778717421e4f9728a7b9926e4c9497ff1689d8176a96b4e3f8ef9f1d686fea24b9cec6856c1757441b8c2030607d3c88598fe5b7b422d492bf406bcd962af861abf3d20e17f7974a163a2850064bc5a24ec7e403d89bdf66cf5e80289439a2fb893e2c620c2d035980581df95cc1defa10bfc623b34447f86313a0771c59109f458590088f6d105073983f9af19ce8fa2c4ecccc15e6d878acf9b250faa091fcba7449d88069d7c1f0d162c5ef6b876ec73ed2c2827da8c393831038ae1e87879184355a5b218be3274e498db2c83ec9579455e843c3899cf74936b408028d4890c4062f4a0d43b7628f01c9ccfe69fa9a6421a3c398ea657a8ebb9be0bb3ba4320cc89eabc490bc60251e5547848ca489408cf210d3fb53fa52fe7dbd1f8cf009b973beca66767b9c685dda91c1386e0140447ca5aac86e7f829b9943aba70f9761d5fa61b10f30788a0d09c53ff2cc379d8916568fb177782751d768dff4142d9ff6a8b1a340dde2b429a5be4fbb286cfa3324ca835b84805e77cc75faba1a258ed7b490f5f49e89270d2c736daacc432840d49f3584f662d5bf7441b80a94616d9b9852ad927955f6bd9b5a68daba3a30bb5f640cc47de1edf38699b5d01805c69f17edafa8e24a58e2ecc9536cd9f8e2e341a54987693295bbf9d4ba95bf4d9f7cdbe92dd96860bb050c93ab641eda0976f9592693038e2c1b0df1f7bcc6af51c2c2ae56837b2da2d90c1294b91f3335ea7a4942c281400c6eccd5cd0e8871097530f27e1143a148ed54b0803fd0eab98ea580c2ba7d558ca3c9124f51c0682f3a88c65d357e2b2f7c35ff0e70a3e6d57e3caea9bc9eaa9d5301d75dc904db0419b5a0f510a990d5c41bf9843d231642919650c17ee572e6979bdf156ec7f2d485d8b4f1ad84b3250f67898386934e2d4820dbe37396840bdd523732307ee434138635670ab91e1246980a88e5076c5c29263736a3113694a5e1c08f2ff281a7f00749853697e002dda24830e2f9b287764c46767a5a7952042b3874df75a3782c894c63116000e0a8dc82842a9ffd788fa1c44fceaf66ab771e65b25da1d345ca8d21c775123be64093751ac6d9470ffaa2e36738f3b9082c4631d6c8ddb8bd78f951246ad78292bec3e89809f259ecf7b195504b8400d8a01cb00102c07768bab501ff8874c44cc33358997e740670a0439224ae1f24b66a6c52837c3b265d419d295b22a7476e4a6473e3dabca818ae0a2b92af5525e91a8cafd5f3e4ea62d143af4029090dc161a92214dbb43fb76a41bb0c9389fa14ac8cb578c710598cb3a3a99a9dacdcd5618eed88882aa20f38106b82a21582ea5a0648213001b40fabf33c54b0a43020ec1f2fc52df7f448eeac5f4412f54764ca941206def65297403f26500966ee294dfd32985c8c92a83378296bae116b1204fa0f0ddea4a6e240b171a5fc6da0338b45c0b43d9bb0fccd8913d25750b3d87db9008bb1f9deee12b08e49b2eb8e17db2391b1f131e0c4b70d9d41b7221e957c81ccde2110ff87f08998ff1cef9288129db2096feb2e323aa178416d234dea0aa2d0cd974a06267c4325a67b1b1a88f80aa5561bcc372107aaead51427ce308d4a7f040556dab848026b28f85283cc6c1f6024afcfe3801a4841027a52a89c1b150368d2f1e52f6e4cac10b337552c1a1088d70e9cb7b10a2cd6480232d7cec3ff5b520360d767138a36152b94ec56bc2550059e1fe54b07672dcb67cabd50a7671aaed0fd0297e6ad5e0f144ed31e016fb56adbdf0cdfe72c6ad27dc7c5f5e8840fc7457bc8574f60e7a1547abd2c69eba297dfe14545313307a0fd0300c9cf3f3a6216253c3d7f4bac88c75e10f2312f5401fc9257000db6228ed8cae114c39b52dd42951144d4c428c31de913acb2681e727f9d104014a92125a5e015fadfdc2ac29381ae9ede7ff480999c96a04b5d13c122c4d0146725561c957039d6d0816a386c687a26810e23ec7315a188a295164d897383626ff6d8f8721cb460931d3f6a5a2e0ac880b132ac9f12c7d3e05fe3140ac75b059f12a4e08ec46f6b881cd7a400c7e514c7f429f5816ae16fcb817d94303475c05629917d701917b797be8166b68a2a45e4521ae4267b02a508626bd8c0029a3157a02e51039b6a13123c60e47f7a44aa858a1ee3122842336cef1da00648588d502ab510dfcae97ec30562412b199e673e3e81b1e0fb20b19ab83f347d3be68e43b0dbed1b80f4df94d834f34f74773be69e217cd7dd0c8679af9a2693f34f31969844b87a1f28203d72c199d47743b956422778d002117439efe8eb25252f00f2dad50018cb5bb761ff2e9f9fade8e4c2be562a54f945f832ad53c0935bb0b32838eb00f4120ae9b92bda9a45e4eeb36bfb219fdd26bf85f7a1816f80f3e860ffd9d3f03a1f237194ef9a9950fd498c66cb49aec8894a90bd79a128f8d6fe542b99e100a2ec03edc1aebec350d592e5dd00b49420bfec5ac075501bfcef78125b5b222e10908bc21cc5d3bfa452a61034ebc940e086408543e367e7387347000bfa1ef8057a9193c47d114fccfc61fd10e091855c0640a6cb4ddccd1bed30088811fa627f92d785502812851a4c2dbd3962536c6510dd29710ac0b5481dcbdba3fae2ff3d792eaa5e97df733d81debccfea6a7b41d1492bebfb7441ee20e6b2448aeccba183b748a0869476b2d6972e281576b7cc8601919142be5a182a46665dcf604475b0f743ad403b014ead2431de9c3a64584e31741428624c9c9f94cd56570ce99a4d05f54b1d29bcdf61327352952750a9842f96c6a1b6caa3242d494933304c9c4b9fb79e6fb39bcf41780b1288313c52b118ee59fc38e92d88c02da0effebdd06239578029f747f058aca996f7030be99feb74bbc0d5e3bab85c1e8b75c15a35e70c747753b0109d5e53566743ce830673acd16c4c01378e24110119e0ec8169aa10ecf1573e9440b4a2dcf54d0e2e582d3f73e9fb6d73f356a3a45d88b76f3e809b730164cc904611c4c295332c745b5f5c73cac490108f4ce39a6c86560e2d6f1413fd40b8066d2ac56d06e55319331cab0b146895b28ba637d196d316c4018f7c15912101755d0c26d2a7cb13fc5e4993ee632c2aa2e9428c2a7dd8727c6f46b349cda38d2310b9cea198b3010b6552889ed0c2f817a3ec2188b9bf6d491d339c2cd6d0f20c73a428b4419b27dfb03e68b38e16c3ee7079758a04f5f0e17f45a4e060d219323063591ade89310a8d95141d18a5efc8bad93e232e82d334d5e388abbed1658490c4f05704664a23813af2a3403b8273f8787a30230187b0ef511570b4a00e6671b6e966bc1bf2510c615586fb712da8efe5e23ff027c95fd2b1932417fb5255b03249b4aee66dafd1b055f3d9d40a028ec552de60a9a7298a9b507fbb169c3831d2be6ce013829e8d7731500b5a6db9d7b1b4fa500ac2acd70ac212d7b627615d9597cc1a6b10daf65d44fb5a0ab9d34cc1c9c23ac70388caa2ed844b6500aa0a49e200e8a8fb83e84510f635f6f733b57baab94ca9efb54418a93299024c9b052a82afe98cecc4ce7265cf0b82638f4bdbdd7152c49fdbd0ae34c699b45459f51ca1c38a1360b5be0ae63095d4bcc0271518d4d2faf7465bb0241e6e18c5013b5f398ef819f1c4c5c88743ec0b834cc1e139a48cecbe8eb49333d23b6693ba78a497a23c178ea6bfb181b78bf8ec9d5ed2b85b5f7e971f61e4ed412f47963c599526d082de93689e5b18802748c25d6c4230b7734470b46849357839e02b59a810a6e1b8bdc8e71616177b8f44791b003208538c3a7056a6e35f225ed024f9df0f52aa5cd16af1f483b08136f1b6af45e52578889c8f61dff04054b116fae116ab1d71012d63546837b8b12685d41ee2e4fc8d3ecd590bbe7199d1193e777df766c2faf2f2b3e65b4f04c146577d817788b323dd3aac034d2f2de09dae3fd069e9a4d2e566f216f79ded44d04877b4949e001d6cdcc9e3520b28374d9b78d29fa415d4a9d44a6d6509912e286854ea0c5d6a1d49212b91b025aa3dab5df0b92d7e740973dec497dc6ffba46d56b88c6553bab8a8c0faeddc657f3f032e1992b252439e052e30165aa4ffc3ee0641c88aab7aa4d90ecf4fc9f9980b1a5281dacf4a6d5cbaedf4a753078b3bde5323dc0b5ab5e6f867b660b0ae3ffd49b619d9f999f38ae6e6f3756909ade0c9d50b4e754a01529aa89cdbe24d2260c62e9309757779a9fd2040641a80743e21db7f9a06dace40ecf6bd5d2f106abb5478703a3429517a9dde2397bb777fd46e9cde00d5ee5af284a8f3a23f6ccf70ede76c9da98fcd2ed606b0152fe593ee3b9d4a88cde0ced9d35247d953703fdae9231cd226363c02723fea47da6fd77f3af9746c39f7a0d6f06170d846cfd24484875c2a9419cc29bc1f5be1987e93c754bfe4cc721b0ea721d0675da8f1937910065bb59b157c93d09f06670bce064e80a2fc221d1ffb9284629161aa0fef37b835c17859912aad26fd709c97e3b24a220c497dd0c37b97a052b634948a0fe6e86db0ba31047fb44ffc1cffe8e9debc0491de1761769090cd3be1518cddb3563cb5742d8c70462bd80599b2fbb19ea16fcc65bc4a7a53e46bfc117e3f5a2296ad7dfc6b61caed360194a7164f41afd8485276355057ed0fa7352cf8a78a5e857821f75398ed017cdbda72ddc0a5e1d29b9f74b81a3090fb4c816db8bba7add7e3c537b7d85bcbf7b7dbde78dd4886ecb81fe2115e92dff30c4ec2195465e4edc94cc77af5ca1ef53e90d180b3a308bb5121040d34611e03bbe5a14cdbe18d5e2d997409db61fea5d6673087d17c09e17fbb312554a27b95de10455600f348b874dbf7aca9c43483e67a8a0bb3e55667489fdc238064a9deb862b448896bce347f774a886d2ee2fd36472257c5031cee6fe5c4ba382311a79df2e265ee06967e6262f71eb70ec04dc3413a977bc47f44beecabfd3a062729203237832c5f360fbc53846c2b699827197a92d2ea8dd843f657cb3b6f971dbac10a4deb7890e4b9cb967612e99a7d9e30236a9730f6337c6259986b43da72a767f89104884f464a4200b840a714969199bbd116feecf736e69d1728de74237a82d5c992181d3c042157c3fcca1707846fee5845b1d8bd1a427a5569a92945a693a310998656aa69af470192f9f935004ff0ad65e99f941d62bf822100fad90c9ce70fa81d54605a042385cf9fa43740508be456ebe411d20377d42f13141bc1eff4805241a6f9bac36f60f0ab86c5c3f94701c221cf42b184470e32cfa3090c5dafd78a98bbf952f58d88c72a736a5d56e544c257d3820407cd8cab51cce6f04521e494c7758cdcf1636745d86d1b8cbd99f04a11fe995b85ab8548945992ef823598d18b472b67a3c03a8542fc3cc11e1d0c318b94085edaa597b71a0db1f6820bf41a51e12f9bed3782df9834e515f69dd4338108a7d5b8a6a258c0d037f06ee5d9089ac211c26a0d1adbeab8b641f2dd7b67fe87ef0a66345c3fcc0e2487b0c276123f790507acaf55fdadefa04d02fa6ee1670905343cbc301aa1f8ce0ee00e6a674a67f9bca231cd6677eae28427e17dce87d356ea6461e5e69ad10390d397a8dfe18690587f86e8222346c82100eab5f1ef79f19ba8dc48002560c2a99ebf9243413d3dbe1420ccb3389b982dc613310e7cd8aedb0864142ff5686c1c5bd909b7005e170dc0781fc463acee88671c32bbf2d2a4afe26ecaeba31c476b942ab81167ed70e84037de4995a7c6eaafa3c106ce000f721998eb8312792796f4d3380319d0d833a44626e78399ebbbb0d09c793087b4cbe277b42805611b267ef43463a289c5b683cbd39fabe62fc4ad9c60872f34593a4d53126f6044af75eaed4c9056856c20145dd03a323b4d8bb7fc46feb6d071523e71dcf3e1a35b1ecc95d0448972e84c6661a4088cbd8630f508eb161a32593891f93d0d9452d08b9e7a7aed9b7689cbf183f2ae60e1488f6cb8d5e4b6143ff5149a585927fe8b05a9548352534f48002dec2162574ecc48aa586d1481c2c49413a6b9f17de44721bf09b8ae09797965f068ca791307e0c6200ab71a1a3d69e9c3f6ab9aa5b4ab54c5dcee8ae0c59591f53185d6dc4fd27126fe760d9709c72afd3d864f2d22bfdb1a9519b19366550987a34fb60b4b019c158574d3e3f7120733f2c864326409cf9f3b0749a51073fa6773dba51fe85f9f08d8158678bed680f2f18c5e4e9bad24e298f05e1195bcfdd2d3cdaf4ed13a725c77a978b19c1b226f22331ed149f16621a8ada01f496305b9cc2b328153db7ce6d4397b6654a930da1fa1fa4563f8a3cbeac28ab190e4b4b33350757445252f1063509a7f284618cc6bd4968437049de88425d4caf83f95d7b532835cc4ec54272ec0f6392e2637ac615228ac39c447480e1340014acce1515f2b974e6fdf338c27d41c1f51707771e8e1426028813556f1e9c0805f6212c3bc480a3d39dbeae9d7dd7b8127b2e81a8028197f0710902b73a1b93dfa7cb0e4bc97c142a873c7f3200dca21a99c6163fe129a9d513d9541a702437a1edfc4e632021536fb70422b7ae3ccf8e6483e7fe8c1bfbb3af6c2c23bf3609ed2ee77c7759fc81ac070bda14586c6e1f40375d1079db81ecec590f5e89e13625960f87546dd38bc000c59f822d1c9d61855758a66fe2a7dfa43e44e74f779e04b8d666acfe0682724fc0db1c4dbf50fbc015b5d43c68312881cb811f519762e79821dc3290f4cadecfb692877764c68d5872b87813a3e0cb40cdc5937f180ebbc2214d96ac20f80caa0ea5612645f8e0159f57f8334dcc7aa544213b530810d38c42be919e15b68f9c0bbb09c6a753fda65f443378122dc36852f2fcbe90e2fef8c6ae81c3b7510373f614a5ccf4742668918fec5636cf66a035f2e638f5518823b7d8e176f301798323fe3e13204296f854826d010afa241941eb776702561cde629b5824f9e9bc303b106b797d2852b0b7785cfc4b056880e8106ea55f2011bd913828ea7d7224a7623fcf5e1753cfdb40aa20c4a3f0a585f3880503b22dc4e1ad916237ffdc084ebb9d2dda767d74a640e9ae2adec1815d97c4f9e016881577f4c1b5c537d4de75b6b981aeb08bfe453bd3f90caee7bad2cadfbea1593907f5d4180c1e288029089107afa333e90ce891fc0ab1f1bddcb97128151a5610b19194b7f6fc05af4374b8e8b283e48924442c74c55aceab9985600fde4e603b405d4098b4a51df6c12db954a6b405da803d416a4a354a7713c78e0d3c91ba5e94a627bb96d990b3024d1fd20a04e828fdb24b26dda377889ff30e79278e2e85d0ae2ec99fb93457d403754248f5deddf523d2f52ba0be7ce9e78d0c52384a78a34e32aed34a2258ee5170016d8fbbd38b94e3a07ba62e720a620121b43de0535d51ef8cbbd7baba4c55f75bd9ee10167b8725f323cdb42e69b78464e403e8b0a206c5130563619be12384faaaa9e2768d4bd007f291b71150f1f8f08e11461f8847f2a52f10c415648c48f00992b5675cf439bda3a1a4cf5cf0153c76a7307c9a063922643ce5e1ad564dbbd920bf3d3242d8f99ff52c2e6d267ad79052d893a72f063b7be5ee4e7f435f9f963e77246db03669d9ad232ffec51cc435e8242ed68d7aa882648fedc6b83a5dfaac2e44ce830a0aeb799061dd3843f65f9ab7a01a5b9027722ba2cb982d980c5ad241dcfbf420844063b185bd17d06f652688972cff9b932f7fb4008fb323df32b34b322ad23478e414dc46c54c52c2c74ad451fd2fbaafe5d6a5956bd09238f09031afc5f3a09c590edf79321fda22958be48aaf8d27a23431d3d5e74633a045892549ed50206db6d6a02999b0fbc3112c9cb027cf30a307d5f58be7ee948e8c49d81daff02d9d7bfcb48c780e4c6ee05082cd1fdc97c5807e53493dd19bf44dada76d7893228348c5785545ea9c3d0e72870a0c89c3d545161272683958efccb978a2367f154e3ea039d511d1cfd8a97a8d832b1c1b9f66c66a5380488b2a2afe612a2d0ce67070588977e5a7f8bcfc153c6e86ee2b24b97184354d61f500b2cf05fccc16ae8058c5650149ae29645516a2e74b216a2a92d21a08841de0263097f85ecac1b19532a49a5959bc705b429527e35b9b4ee6492fc26bf3b5ad45240a00dc6c113460e9401542f5f09aa13a5b79c68c032343339201eb7bccb7ad2d485626195585dd418ae05668e933499143c574864a56b8b9a7c101afde5a9e0f6e4101bbd92d04e8d4e6808843957800bd7fb094d707ee453d01edbf6f5ac3695e8b3cc03711c8b510a4111a1833f70534711fea23cef2d41203d8e4013fb32f70c9e6601815575943ca4d0b715a6e945e30146393842db38a78ff2e7aeee125b7c5f206212406e3286a0de822f9e8a6900cc9dbb0dc4e2760392a7543c8f1e395ae42960a92f1659047e8294be72a12edb933db4c2aea0cbac505019a0b06ecab7fad10a80aae12802fd5a69c1d0c18a5752214f164823ed239ac01f07d36438afba1a336b3a30feb54c159c5cb008793f896af6b257a346e8050a1358053aa2e7486c4f8f05291f04487d2a60b41d1aa3abf3959d4b85159548fd3168f28e9374ae18e6347ff97619b8d96d309213e362dc14b3a1b25304ab407aadbe45866992f1eb70492b7069e487a0ec8d6955adbe57852aea291757e1670259c0e183807f4b0586252b4faa8aa5de65f70a8b89432e71124f20eda40ea46a82eee326435875acd7273cf9b3e468f0ceeefbc53b588868ba1aaafca25569455c80768cf52bbb42f67bf426bf18ff79f2bb7d744388d4ad418b8a10b84dbacb96e4d36cfdf87b673602dda897f0ac8cdf49790f374e087746afcc0ad046602e77f9148d249427536bb30272f8e1eb1a35a9650cfaf00ca0c81d88cbe8b8f943ccc5543d0ea9cd6ce5cacd2d496ead9458352ae3ff93792c5670c05269261c5b5f1480e0e98ea27d29c64a243b2156bfbb772f3eedcd580b7127f357ce054feffc2043e053e778fa2666af6654a172bdb69c9309739e73809af9fb8e0742e9db35bb18c0dd713103741b9927ed2c726e9c4691211470f930e2824b75feebe82d578701d29f9320092bb389bd740315a6d2da8b277a3096ef3c1de89d8e09aae254ec55ffcc5be05c42f59f5fd74af2f3482900f7875d99dd75d5b0b93c74841a80f9fcab67c5ea6bee8155b2b9fe14a9e22f4dd18b242ae011a9f562b1fd8626a4d11f1a926322e45dbca32d2381ae26a363199388da9f4209acbacb839f8e66b2bb76b34a80fbd28d3c5d653f0a936b4c5a4a2ae0aa5f7d24469983c5d051173ecc22245be540334e71092b02bd377264cc3649ef9f8f374d542cdd83af27607ba460a38ded30a331fa3af106e74118d5286fe6785d4bc3c3437f915a7537d74d5aba2a0cb4bde92bb938e4ec905a49e63a4236de6143034ec9ea3f2d8c82af57b1f14b5ae2608078e739311e4d79689c7f08c20adf7aff100305e1baa705c494586379a9923e6dc361cb560cf672cac556ba3697b77021342b9a6dd09d08c2e3fc8d1d4b9c2c6230eb61f1b3c8a24f7cf72031a3ada72c0dde499b8e6d743e388aac61b8ed2d5089ed9566dc31e271b02cc5987e3de9a36a2557661f8ebae7a5ace147ae300c0d4e3b544db439e6d72172354440b07836c10152988a75c20a499124761ebf22637394058f656331dac872ba502259ff1e615e53d3ff7d0fd6d33a7356e6d06e40151d52dcbd988f69881d509232cfb37a4f0407b666cc47a7aea723c9112ac8011e6e8ff92ac8424d524292703ee7201e4990b2b0bb8592796f93f209d120d43d32d536165eb5df9adcd34849a6e95eb79d0ffa0bf6d4491852665ec9717064104e7728df138e60829436cbb2e0e8000c928efc7c99b618c57d5a28a3c943ddd0fc6d43c83c717f10592613c35797ece18db67bdcf515c6b23ea04926a0c8f5b0668e35d8514a385b6db51b6479f8981e3c877005c6b5e649ecfa6a14e92a3b0a2ab96e9dbb6be9ce1e60899d2c60e0cecf04d086f751aba93f3cdbceb43b700d01484cc2e98ab57f153ee48f96dcd4fcdd4a5e367498f9f2186c099f24bf5bb6d5477a88a3ba93f653719158689d6c8001422367438e3d6d1819f70d337192ebad4d6c76c4c35b19e540574fa9174084d50c63bb6ffd2b247b10e3c21809db669c1d9a76efa332d148fa99dbe01b213f1d55e651cba049d5373ca266953caf854feee1c906cef13f8a1bf13e4df249ce7ae9ceb85b461b2f432d1be756e3d1a49ce5a67a0acab52f974c95fe1cacfd05aa602c4406c8ad7a6502587396820a2c635ddd40139a759e36ff7ffd5683ec3874efec288090c0944282f3b34760005f8c66296d13c3463cff615e8b9b3b2c994829f063d4bfc7eda5e777797cc553cc4838921035a6ef849066a650589a833c14abfa04808f581db7f93d32307fd88cac23726f1438ed8bc4020bf911bfde2befaa51f17e4d6cb0bf4a69dcbe22451c03460f5a2ab3faf6dd5446897a6fdf123e940e6068c4650779bd4aa2289b2bce81754da32937e1eb0959351577bfccf0985007d2055ca8165b45c67789775035451135ab3e5cef4d79695a391d332d8858eff18e48371804e555de697252f2a16fd1b7c9ed7d635135c6b290d07361ff75e944984006a97845f57b66ab87d4ae5dd683a83d67cf337b66001283ee11ae6a122186a079463ac5f9754c3a80b6e2462ba8b5d906059276c096485f994be4f65d0a1606c301862c27455e2a9d5d76f50db0bc2712da5d5b7e371c48e4487ff0a224750bc21456169ea422654c62dfadca02b86f0f07bb13fdc99882f10850b3795a1a3df968f6f01e120807570001d9f018039373c62fb75c013b134ce9c1126a35d3af30b98273387dbeab34c798ca4bc04770fe3a37cdb44b5ecb5caf2ae0a0a0fbcf62536cc9ee02ed2e6f5d98befafde76864f50c399bfb304ca8a66c941a67722fc407705b7fe6c1b8caf31956d797dd6080bee2e91bd428e8361bd7e82bb247c65c4edec8ffd63932b53ef0622e50463045b74d2e3ef0048366a40b56cb57bdceb4aebd406bacc3874ce76405109b5dd1f75c21cf7ff914a57a5e99a773ed74b5d4ece43228af925ed3c5a13f5c5ae9de78a865dc390023abcb26f9066d3cc87c348897a0c8d135ad85577145516f833fc911592f8a284c0266429b97c9b4a7cbb548c7839061ebd0e7109b907c75ca1ab5b4ddfad3d1d3fd9c5ac393ab18bc678240bdaed44cfe4b7c8b8d23f41ef35225f3b30645845d128dce98cf46029557c758f2f702b149eb00ce6246a10b281707e9f2b8f778cf1ec0bb57b049e9a53a3ad25cf95c873bc161fe5937fd3dd022c90499a4f0ec1e50f6102672f0617259b91a84a9987e02474c417846a12c0cbba32ef97114a984062e1c82f0badd56cc4c1a6ff42694aaea1c2934494689344a2384860f7e210496459d2a06a17939391a3ebce21a6e0f8025cfbd43aac3363ab5312443ba3fb14cc47cf879f56028eb9200c3ed2b369841fadc690bd3e790a845c6192048f79ea3a488787c7955cbf651a83709c0efeaed54deb47044774b7a13ecf0675db0c2526b2d65a224624beb456c04fa3a583d205d62db81fec044e87f13e56a8c6e38e34989436285f245be5a5b430f48c70b988e1eaa669cb1952b0f25bcb10331a4bbf0457f874f8f761e11d8b7c25af48b7e370617796c8ca35569bce45aff2a7e28726239cf3b610597250f5ba3d624f62315e469b414927458cb7ad66b942a50c02bc9b6e3d5d6e019c70e33581155159002313cac6eb3ff21cada739d4a6e5aa860a04a0e18cdad8b073a42e6ea891839f1937040833cf25934de9154f0c88990629014d163e281391c2b20ce2425ad47e8271899a731339c24231bfbdd0b86d51e7e5f842d23ea809044fa182dae34b5079fec6345ee04d7ec53b0c33af2ad0da065f63a35c7f22036b3d9d07c56a8f468dcb7ffd1e7045626730ff054c8cada7aee7b066569b462edc7065e350ebe914651d85b7b1b576b2426c4b5e44303d7a1ffabe70c38899007c28ddccd0b5b1dc2fdf155464841f12e320e5b04bf03c1978ea647e509ddfe1cad6afd330febb78c409030f8b4e3378bf17578a7b43c176919a8c8e2ed79eb05e325e14e185be98f9122c0e4f2c66847d5917e8665553a8a21a53c061464ea9083b52756cef62c16fcf739b7ac839ba53a004ef6298571194dffa58a34467e71966378902708c55a9a23794cef12ca43c73262b301b4bf01972649e843a15fe4c0d2af6ae18766912dab1e034457586c73f3aa96509f220d5589e047949cfc8b72ba0213379296fbe6530e6f89fc2c1e2fa90b69d2b226d06472e6059e0d77a8132867e79311db6c4e0183731acc0283e1829adc82e8efa88f504831d10bab1ec001c1a7c7be3ab252416fe78182d5aa79ec591d0c066c7eb297944124b6541d7b5fc06e1da3f7bd2b4565262a4349cdb0af56a7eb5846965a549b1345ec4c5cc542b84b84bd8ad90be5a29918ddaad3334c215ba7b996edc5e1bbd2099c93a02a41731f4d173c50c020999a4152e88163eb9a22951286d6101db506f4e57419e27fa96eba8681ec2c13bac4aa9117187c6397ea4447e2ba949b76ca45d4e1ab372b01422ed41bef77ae3a82b13f18bef7d7a559b9c27104500d3221768ced9a5d09031e9cb2492db62a6010c3b6583d6f23cec40c76c4af47007f1ead881d5654e841b074cfa2bdf606daca44b9adb32e40670c77856b633cdc54ef2fbc715890150c1dc29c3d3e6a1f3392172b93f43d263bb1be63e0038780d12406c20db7c431b1fe7fd2b372fa3a1193651d6ae7ff4f37160ad93e9b071f22a91fe04cd585a971da1e8b6a8e8368bd1248250814ae7464413e9fb0f711c64105152093e27616591a2d80d87f5a2e4aa5a2c8ae886e13c9c52cfb93a15698fca9b9247275b8ad8fe018a18c2d7841112b920b850d0401f50aef12a8310f2adb5bebc9153ee11ff6904ba99128dbf04be8b1a1d417f803acbaf4d511bd32f36830e657407eaa610654b4434d6a4087511b32bfeb478c59cfda84a2520b3b13e346d75eb473708e97799e7fe7169175395e69f65de3b9f33990843ae416906acc331243536bd0e3a1033da0e8147f0974e6f6dc8533ee1c3fb06187bcc6642352b2355be975b5407a2a6d7eba3d8a2b9a05856a6bed94d0ed955cbe58bf48d016a5c71db36bf56506ed180dffcd69291a24a8e1012ae240c6e0590b798624c9e96fe495c1f24c0d008a09780d92a4a125513e4ef6f18650274354e92f59cbb222545052ae63fce746af31d6d26a1a18f8dd78ebdb09636659f5ed42750401ffa1ec286722f848e4514e688b365d1333aa7e74249074f90ccb67c97a422e1c0653d7e4996097410cf099d64c160c1060d45bb5590c561b7745b7eacfe2212ed2825b6f1e46a95e953d39eb36a33dd7ef790e7c3ea5d794a3dbbcade4fcec52a8ce8cd9949e34b0535dab4343a36c25ff7b3572ec4ad2e3a6aee80cb2ccc8ce36d7ea6263400aa8dc7056910c01a1407d34242c87469d864e0798052795d2c909c715ddaac660a940e0e1e2bc405eedc5b0458a21baade1a96334b64949f6a7c7dd45a7cc8a14a5c066b7363a4084df385cc4873473813135a4b5de8c6ec85b1b1ba2ad44d65e82ca199379565eb5968acb3c720bec8149ca1b8000e60013ddbfd6fede6cecb63623cb1b509ebcf6eb03bd833bcdc2ab08879f987a17515b727ae7755755214f8bb8cb7962ba6e675ad453d92b312d4ba364e573560027b254883c64c990877f823a329a09eda6b4d2b2d92df0dad4f7fa91b40695e6e479aee331935038eda1e18dae0fcd9c03ab10dfe01ad7d36a488b960f6490a3051ba53fd455b5e295d7372cfc21e9dd3d036218232803f499013a4d01c46c8ec437fe73b6345b26c812cd0210d922db09ece42c5dc2e14ec4b938cd6dc789a5eeda06cbc2a0424969f029e540aa2ee64f036811caeeca0ce1aa7cd58da6189f14c2f516835a0e9aedc83e8ad0f97a8a28737e6f867e0d8454cb5304ad8d848717ed27050fc2023d9faee0c06b31bc7489e6ab2a5fbf360442b044dfdb6d8467ebc958b6f2be86644e9ddf08b1375464a579b116b1c0f55a3cc859487fb07e24421f0c6e5bc304558606610e718a0a880ab5272817ec122215e883dac1a91f1fe99579915f8c0ce4a544ff264c61440d565782008d7e110d946f633cf7f23f1fb4a1edf0e255a4a6124325d3bd721a696b63816640e87bde513d8a8476655262df0ff0bafd900fd9914a05e82f329bc554fee6b76478e4c9d22462455025785f39dfe32f4c5d768067194c97e5e9e7213603abb856aa04cfe493afa50916a49d1e97a2f2ab1ff25b7bfcaad4190525ef84be356353e81b081f22bb9aab509e6fd37d2b0b840839ac7d1c06533febcbb7654c4848b5a51c2c70732f851c005b9dfdee4ed59fef8c0f82ad2bab1e7462af928512c64a37d2fd084fdffb8b2f6b5ca9395bd7972691ef025b2142b2758cac528817f82ff9e962bbc02acb46828745a261c534ec55828c462ebda9eb2d151da8f7a610658ef3f9ef6c61f03adf242df4539a690fcdfc25af25f89e695e95c8af9571b032e39158a30b35704478297b640cf6655f2c3b3fc8a5bd12c7f75ab7412c8029cf848af9d66769598988207b2a2b3d9e25114945fe21383b91c186e45dcaaaf1073ba52860cf438e1d206088f4b634d832e9eae9f9e852089790a37ad523cb758fd2df40310340510846ffd70891919c43ebe523b2f706bbea4c25fdd4a67cfb4c82594a7bc0870bd7b6cbc12fcfce97a5d56c6f2da63c9151b61db0d947c41ece415d26ce40041c96a9a2d224f2e83792a351a4b0b820eae4620c3e8c943fb2328e7f5244d909a54e228c78878b29b1d864eb61520b77e7fc3979cf9abfff66862a15d6245dd88b4b63a54e19a95f2041b5eaf7f7ea29b0aceb05d5d5e4990e86892199a81256426ea63efa006044c0880ae2e912e17346c854bee3cca040582e82f464ec389eddcfac9a008198b00276096b79a514f932cb9af992470fe38eed265a6665140244498f2c1c57060d3b41893022f88e517ddd65d3b9abf8e910cd57d12cc3718d87b4a7500fb55b484d668ab531ff02f88247158a465b8188b27187c8bec22fcd8cb8bd030178c6f47e353473f8c1450719f8ef4a857fff54bd54c195f003020123c9602831aa0f21d019140ebd2fe5d547a781ec02c4899a671fbd5fb9b697c041a6485c71b9b04bc6e8012e7deea8e2a898f1ccfa28f50a0c38e2cdb336905c030865120a2610effc0c8285a3a44787be431ff30a995a7b0dfe7c482c6929642d6a7ac3f23a56ea41254e5034b2f354ad06656e842ccf9e7b8e34a9df15ba7c21e152570ec42091de96d01d4abebd7a8ce3fb9b233a4701a069c290b1d219a37f2c1ccca00c3a85728faca2224ece34a08a9ba10809606aa300d71eba654deca9c049116b6405682051a3a8f041f1138fcb80de504e8cd3df6616f792c1cb6c1ed6a6f2ca01df582b8f051ff62b7c25566b906a356f3761f4f09979c6ed9e0a6d9b463b7c1f691a3396d6179a8114dddb2c8a161fdc19cfea92cfc536d02809006276ee49ca9efa890d6870a82a596debb3c12649e6906104c0a86fbf36ea0aa0cac7a2bf1ded59ef608e5d348fec791501e368c80b355b976cf6efcc8c84e453454204a00460b038804e180d0fe21f09df4fac15cf23bac9392522a0fe50b3a4f34a1d04fd9a334e57ab640af4d64aa4f2f1a2340c9ed86408d078c6d8ac1275ff49d328a192981737f40eb813f71fae193db5567110374cf73a717e84f8acee18adbe918fc657bb3a2717cb7ddb3aad3bdf22354dd20f70e2247251681713a4577d09299f8d2c914818954149de4e814faae55e22ad9217d2c5e346c2bae2a19a6d8f6672aceef58f6a7337f25666e9042230ea4625e91dc3b05c81830b225539b6e50e6911c944a8d396f2a206fb0b5ff1c68f8571a600ec511dac88f31d19861e4e26325cd52aa5f5d76a49a67b0280f9372ba2507acc585320549cc65b8e11b44022c55d7f3be57b8c9108f4415a0eb3aae671cf4aaa1eca30a972a02a60fffd4e536a425859753db61f14343d01969a476044a0278d4f9153a777074e3397f1246e5d0e56fa548c5a7e275539c556492d11cccae80e48af66be09080b3207c354d3b0d5716e9efb4592968809c73d56b125f48e604f371aacecab15e56d14bf26353de7d8775839324516dbb128c0b8b2257c3f1f48cc8d3bf80216773dc7677d4fe9f34626ee39c2f6c2f4a8cff6bccab072bbc40ff21227a69eb9a7ee55f144192f1d5afe3a0a6050cf27d0a14d1ccbc75a03a864cf351a79037b42974b060f33492eda59184de0d963fcdbbfebd8a1a278c2732cdcefe6b7a1aa18dbde7fd51624dc0dfecfcfd19cf3fbb68295b57591ae41fcfe55475e2d9db145d9e80b6f88e9506a9bf2e2c4add00b6cb4a28137d94e010698cafe7086988f8bbb508b9956ee1c524798ba49a5064bafcd767843d03813291c7f15d7bbc9281b64d6a4fda29246755fa07698b2815d8273b3b47d1c0f2bf070a6881d1c000f26180aec03c802b0bd55e316060442cbe03a2c259876ab4c487de7fef2685b9f56007335879987d35910fec5c2e8f70bb52753a3b74bee8fc05cb121c7fc6ed779c2e1f5123b590a695ca1561497508eea5277443a7a6ac31ebf8c6b24b1e9003b5047e74a5a644822bbad16e48ac2bf1f2c9d4b6962f24fdeddea4ce07ea8f99ba7452f660db8cd4f9a9ad9a023a233ae4f40f8ddbf1517085a79b1af82a233d22af895674c07c4b54be6292705a02227de49fb49b14a1210894a172edb6152bb84486a00d495f4d579902d62f2dcdeef62c899f639e92662565103d3caa9f530883213b8f409094eb015f1f0cb7c84a4499540e07f5b5d2187059c1ae6c17aa5952c992b44c95f7c8b2c4938bb39a99978a7f3020222ff35508ce0face2341e680521792b743beadf56a4f07f9ab0454ad1cb4da51d10151329ccc6c16902adb724413a8c50c89b2a06459c6ff88325ace4398a0d2753009d861adc8aa9b94428e99542d1479862bb98a5d361be2fa07f356094a75f208642e6103e020d1a026e21ca2ae7d164fd00f5b26cdc239541375f7ad97f86b21a83a5202a4cfef8173af5d7ad03e75b8d1273beb0e5d26a81f86a4a25431556a281c71d01007dcc73d528221238b399ce6c4dc2107c1c499b9a67d0981d3d5130f6d229ac47a1175f420ef5f7c0e106139d3a9b462cf90360151e32b6872cac724ad261cc58a8d1400d5d525c842c773aca3155d4226a13a706548af64fa8fa2b878da661d8dc02bc92e1b91d1dd5874aa80aca83b808b8f34c38940af2678dfa5732a098b0b2e92136105d09bf92d6433ca09be53e1a0c5ccd7b756a0e2cd4eb1056d95e51177deb523613812e3cad51e73c9aa61a98b210b291da858617067ee37fb28681629c892977f3ce77d621de6560e5c44175a5c84cc251732d2bac1ec311726526c4076c16e89fac12019a3295cdc5d8b994496c8fca11118489f515b532a02f6c9ef9b104b5abc6e0c249a3515bde28d2edbf94ec20dfbc77887cbfd156401887de37bc094aa6e6d1f651b45a48fe10f451fa973d6ebe78d9c822aeb377a5f3823ebf7da3428b7bc2aa9ef8a88871b816615a42d5df05786bc5ab1b9e31824d1464408e0fdf19c0a3ef3fce2b362026ac8faa4305331f07708eb7e2437692c866198c662c540d39b7f45f68a42535179cb0f7451f3120f4118d1c0040c608a83cd6c2e05159a668da4ab46197298eb2b2d4706fdc8500d19acab5c3ada2a6ca0d48279fb88f6dbd1aedbd30de57d081b4fc4bd9213562c73d2172501ebd3c39251a80732da58f10213a314a98a9472cfa5cc20756ee120416cca49b04dbf08b5801156ab06b76edb92a7e9e260ad2ff3a0b53d4df605815969759b38473db21033aeeee3154fee30484bf0b8ad4d83a29493314a9250d40745cfdec70433b53398f01eb05eb68c71017a1f3d54309dd1474d9d5bfc6c090e87731426c3c70f44eac7d48964f699a912725e3ace4b6a5e341a24b8f7b126e56493c40bbf4849bf9f52bb0371835484a0b1df39f69a03c87dd0d559ce74a1ce90ecb2863a73c13985a3860070ef9c868b7748f720fe847f33fdce4c150a962cb54926b8ea8c803381662986b01423c42390cb2c323ee3d4a365def61c979b1771c4b58a7b2c0235eb5f4d6753da482c84532a2e8cf88befcb7507578540e9f116af6457c7b198bca7402a3876fe6db248c884b6b8cfe9fc09563c37f018a1e44142326b288d971fce4c0f48c0c659f888d445b97aa63250f57250d8f2f786a3c7bcb66e5b57aef70fe90ba01bf286493e0c86dbbb161d5aa76ad498370952ad4e032aae5ec472f35d96fd66e5cf3bd2ca100e8fe6fe22a6411876c50fc5087ead3b9becae1c1f57368fcf15eaca02c460e5ab1a229b9924b238381070834e44372a49b8cae8bc82f15ecc75e2b7b42b787abb9921a0cdd709657825eebd2b7fc6cd71f67944410b23f5ef2b9e80f350f49de46f288603e99e96d3507ab4247cfb2c7e8b822d6b3b08b0892662d6bba1d77818d80cabfbd6f31b8edf6c3c8ff52d52f46b426c6b495b3133ca5a2c28d09075e9c066ecea5595c8bdc6b357a6eacc952e3db1701cd03087a0be34223b1e702d83f89cf77141d484d37285e3344e45ab55aa4210891d543eb2077b548b78faa4781b3b3db7aaa775d0684aa41544bc4650d4c4464ddf8fe0b96044e9f12ea18e2dedd654a5b7ee109007c12b0287bba825b0dbdd8e0dbd7111c21a310027b006d81d4d5e46d6a6164d45fc5bc334267684311bb8a0d9953cec5ca4a9e70d8b4194cd11b8bf01e43b526a6eec8427f878d0b8b8562aca05d60b138ec0e751771f143f063355cf7aed87709951d42e5001242c88801b62284a5c6841a6c66bc84a2d0078d5a078ee781cd27a8c2de13824b07a1828b753d0d7226dbc94143ac2a4dd4db4e69b94eade8a83d491c157212a142ae1845a52492c3299a45c44ec8feaaaf3eb6f828fa70ff971c512821bcd9d4e717161142e2b0552217ccef4e551d9b26f9ec01dfcba99d82db1d1e73aec88ca22d46381c410d0222c65a82278c13215610f01b9222ef73728cbeecd88067cdaf34c6ceeec2556d9112ff1c80e402843967a63e0aa2b15d1991d38579fe8bb5977bd3383b029c26dc5d5bf6505af99c84e549202731b1655e1112ec061465206f2fcbb17f762c94eafd04f096a3f19c45d740accf38aecd601a3d22c20e62102f71685bdb971f5f23150eba209728d2a33259ff35490a8428af315efd6feebb1668a7e17c7ed29009edb5c74f7baa76cb5dbb7c7aa80230463b61ea5ad098cce984bcb23c058233d09e1a9bc49bdcb98b85abfb5c484371005a8f6af7a89584d86f416c066ca5e992b3029593ee6d8e26277faa0ae160da28e05e89e6f42c266b98cc12bb0d423750b0d268c1705e9ab47e1b4b7a4f01f731d0ad2d0ec863df774fcaa40497f45ad44d9a8b9d63848d243566f4a4a51cc2974aee9652daffa516f09f00b8649227cea9961346e6ee9ea4028fe7314d0dd4e53851834c11624a9965413ced0eb2640940b24bd666f27124e2bf4d6671a64ccf981ebd9be3cc17dc888e5ce793b3bfaecb18f1fd7cb8c3fc383d7581481881717424eee3f093553512ce7948cf7ccd5b090e911164e7e3d6c5baea8a8512bf471e84f21d2289e65352e97a6ea88f80ab3816607fde8cad61e3ea65bdd839d769d6965869c9f9ee60acc243423972942aa5335aac68ebaa616e532c4cf8932443f2584d823dd159522a7d940ed7414e632cc2f272c29e7d200cb8b294a376a6ef00ee3496bbfa0a05f6989f1fe1fccba0faf79192848b0c1cf1ae0479f383ac2470933371e8a12cc453988bb1baae66000149470d50bce65d1a50f9b70adab86d07c9b7851eb443bd03ae5410aec2037dc04e73744bf0534d91bb827b8d81e8dc4e5d5c5fdc86c8d519aa99d59cd5bb10026ce3181bc2648d503fb720e49212334d7f6d8e9d6b46c873c72bf25c5e8de4594d1f496e325b62c81681ca70e6146bbacf761b85857028bb982fcf261aa2e8301d79d2dfc27a507796efac3f4af5cb46fb87b0511b0c7651fadb8591f237016c9284c8a94c1e93938df328600be03d5f4ff1b6015e17bf8d706d50abed5381c47173884db545b26353f48c085809e588940c19d180ee1f423cd430ecac73e15ded605dbe5bcc832698ef91a099749e0101c76bf34d0ff9f9de8dc314c43b4ce343ade38fd552ee76329116144a2b642f72623e52d91e3618ec0c0efec60723f73208ba23c2ab23e064b8edaefad91eebf5be9853317f6fd9a12a6771befee5bf059965ba159b48f1227530aa70207c3c3b0a9d7669bbab124a1c2d0fbe93ec3a3a9f976d9dd82ef60e9625a380316f47d6a897790ca1864de26d15bce0ef0a626a1f3a488308bcef1911021db7b97bed4c85c37fe250cf98acaa689ff2d059659a334c4664b4c93577f54c380c91dfbb4a6454f14e14f4cd027a3f767d531048c38c3ac0f700a53c9328b0457003246c206987c882355fa62874b131c332e586bc61ac397398118980518e810800000000602402c058e56a66c401877e6d3a0eb7ad22117a935eca6ddc4d4a29a5dc72077a07e807c0072c36cdab8cd166d5084e9cdfdbeb8a9e1db2c0ad3551104e7b2ecf6b6de2b5f6d130bcd6beb59fc3918b08647eeffd45e9f79733bfbdaaf05d9245bfbda630d33ddcc5b10b0775a1837ac1e1e54d9794c75e8b867bd84210c6a1de721ee30e8f4b0c84ab2e517e6fffc1d6659cc727ba943e98c2050b00ecbcf61eec128e17159a1dde5b820797dc8155c0ef7cd2e0b828bd761dd8b62edf3c7677f3588dd7634bdcbbd61c98292e1d07665a86c952e735962b2d54aeb6fc78ed37d8348cb770b0410dcc74769545f87b3b0dcc746b4dc333c77edac812221ebbe37059d25898f90ccc74c655e6b7dfed3230d3ad3570bfd65a6baddbbcd6da736b5e3b899b99ed31b882010b63797a8c45cee3ad2cafe23197d7635fc14cb10aa512728808671f59e46062fe645bcc489f6b180e1d3f39bff85ccb39033330ef2aaf29ab32fd581fad461ada8f7dca9eab72e6a0dccb3d52a83a8d16e756adf4f91287912fcb1247d8970e035be9d557e8fad277665a6ee1201b361e73b121c363b7096f5079ec2f3053bc85bb8ac0c74e64a6b8d4f2a65fb2848937dd05666ae2b205668acbf7f95d23ceefbd9b967e3b0bcaf2b1af6067f99dcf6ba0dffdbca6e1f51ac46bede7d8eb1a545ebb0acc54e37beb634f81859aa241e36905789aa3c04c692574d84fc094e3abcf10f333dccfdc04663ac31afb1e4b60a698045baf42ddf80054b8ec90c459e2dee3084a30c919c00ca9c72e021d4405ce799e2138b590f0da41409ba2c1dd963fe04c4c7e5ebb07f0c6f1a20a3168a329862e57c9312b996404bdf60ee871c6c62b6a7360035b1ac0335db6e00487c91624356154596cd024e959064ac74095f1947bed2a6c9c7d3eef0be079addd0266aab106064de19d5aebb2021885dff9fc40e1ccf2d82960a658975aab8bc3ded98e9598c05553f4fa84d72e0133d578568e5a0252556e6a2ca97ae2e96438f3249bed320210a84b460f00ca1c6787c8ada2a2a2193a19d1f8f432994c56cc39e79c73ce39e79c73ce3957286111235d58f48446ca3c097d6f84598447c090b0b82144222686304919a11227c2254b9fdd01529f3d6d40ee2dd00ed9a10ec894c97a11436c494b0c538ad4f6d6f94684b3ce398b51f1d183b746b1897f89f698f24efd35aa3ca43c95a93e0dd9e1dd8d76c62d27b863d88f05e632dbfa48a1ea7598eef5154adf8d7060b878995f99ebcc54262b65fe662ab34fd60e5293df7eb733c04cf7d396ddb62fc04c7798d81aed0ad0da4f98a9c6a20d1db139f162eab127e0c42506f0d81160a6d8fa72ce3901bf4bc06f0be98a07e68293a3de5192cf7e0033cde709c700268a6f7b17bbd0d912ed3067adb10f99299efaebb78499de7cb32ceb356894e07db343a2f60298a96ea1f4e1b193e8621a6a71c943c78d0e3567acec7bef2500f131f601dc7d01a4a238496366f076e8721a342a30c6b2ed0230d3bda319b5b962e1f4d77327befb36e0de2bf37baffb25feb54312578978eff196e56da735ca02d10a5afbbe9dbaed7bd4f794790a39e79c73ce39e79c73ce39e79cb38f79947ccebe4f9be38a9a48f9ec1fc823e7b313b150f4d9775004a348c50b1e94cf5729ae3e7b6d7a92fa3c5ea9b0f3f96a8597cf5eab787cf6005420be1b27392dd10ec3485c1d03001e372810c912f71664645ae2f9159f70e2b1f2f7fa883b420c36319c40592123089aaacf372c244c02fefdeb3833bd43a2dd22d2b1abb658a432338411668116f8c28fcffaecd357993040c0defa0ae490edf5b28f3b1f2b41625e182106cd9825c3149f5d04ee6d8fec8df8ec26906fe19043443bda07c5cc28c14c65f72b8c1cb2453b0c7e55d95bef8d65ad10f786e167bf5925e4902ddadfd76098248fb1a3668a89485c6581c8576081057c2362c14291437668a7bcde7853d70db31b893583397723b1da2d3b6481768b8c1a2f2e105b0a9517b69f0dbfa38121bef5eb05e5ad7f38ab14ad0e4130338664367c019e1863a638d3b57249f2f2998b9d2e5b5e787cf6dc18f402e673b08bc8e7e09771eb4d69c7386c1906e0ad6fb0b6851f1b31397582bca7233a2be6adb578859a2549162f2d3d3e6be9b285c7673f4d14bf824c72e47b33b629ce7186ec26ce2b2a592597d708141226d720970d5d6b6216ed1091ae43a2152a959f13c118c0c8a8886a700beada29bf73cbd00ec354519add7b6f566b98b1ded76d9673678b6f8bb21bd1bed5227cabbdaf8e05c9edad5faddda875dbed3b12fd4cb9f3d949dc76401267b52cd062ddae9118c462a4658bb6e80506cd8ecf4e822ca13fe39bd5020239c7df59e0d7d116a5886ad33856541f062a0778eb75bf05daba7b7f8b4e20c92193dc968a5cae3ae5748cb55e9ecd4b8c246e977b13bbb1eb4716fe3a7947d2655bceea16cd8d384c81b7b85108abf0d647218c3fb0bfeafc92f6c608c8da536103e410cd471fc1a8a166f66c3031f3f1b4433e1c6c26369cb99e22eedc5bc379b2608548af4cd6b36db699ce11677d56f84c43652c7cae3db244ddb34adb1adf64607b7da3d51f85b097e8380a713d36727e76d2bc00f9f7c680110018ca5baf361b90016fafab60b36d520ff7ef4620992d4c533fbacf4fd0ef3609255840b0b1245e40b02d3f0287c4dff908cfe439c57c3f02c1987e473352849704830719777c6d90f8a0fa2ab2c4cdb1933f12935a8fc3be9e0412bcde315312b4fced76bb79b563a6b7b0178fa25eeb98297aabe72e4f88d131535ba6c7bb5ff73ac74c3d08567ca0fb4040405ec7cc14082ceb4384f03a839986b8d573d7645fabd56a6b1e845fb2c4d0830041a3d1e090d9f13f08f81faf6fccf46718f61f3e787563a61f8e48f97b7d5f3fafd736667a8b668a47de12bba4e4fa08c2bfa03ab5ab92ed23d5d368341a2d7b90e1de7befbdd76b0c667aadbfc50d55d8218bb75ec5ccd4d63566bac73cf91146f0aac64c47108e29f2228820820822882082082e06cfdf34db5a4b4463a62288097b9bcdeb1933b57d75d5b0e54ab2c7ae3787bee09820e68619db570cbfb7ef5a980f0a2389df91f0027bebd7fa06f2364c9ab761c6de3a2ef70555c68498c77e7d23012363a6a69792f7e0c1ebd04c3d78457d4f8f6f1dd67bfc87bcded303e6cddf01fcf53ac64cafb540c4d42f33ed0173f421f80dc16b18330de18b9c3fcff3c89fe769fd3cadb528bc1d7709783b627519a1cbf0addbbc3479eb7ef4d6715f6f3d27ecb2f3f6cb95b75ebdccd49277c8bdf7c4bd5292f2f7fafe76c1faeb39b11f6046adaf5fccf4e412e63bf8ede0b5cb4c3b68f162c4161531f37a0c23b3a8de7089715d312222e47265ead6c6bec6e56b5ebd9869edde7bafdbbae46870a9c22d49dbeb1633dd5ace8ca005862c5e1fb2c8d18295258b095e5c8c6111f3d434e4b157aeba65a63acbd1fbf8f5f18ac54c7db058098111c4ce91bab41cd7d3df7b855c53fe7a85c14cefad5a8b45ca5b6bb1b079bb7505fbdd27161cb58a996a2a663a1bb53c07bf1cbc4e31530e68cc205961e93bf841b9cb5208838ddfdbabd64896b8d7f705f2d76b9699de3752aec8f0d682814db91862e477a4a5b33fde7a8d62a6f68af071159a6959af2c5083061fcf8c6f1bd01536dca884b61d1019d2300a53242986a82055d5ac051e4b4cd21c79cd00a382022e09fb5c7e3653846b0acbea27f4f1d96d5907942429526a92becc30850c901e56393ee3c005175a8c6d1d61f9f138f142d1171f62d8b810d5636bc5d36f76513448254583a272058814a2cf8b2e3b7d769bd727e3999d051688964edca54c98588d282461767cc6b7aa23b8440627db166d71233de9e3d4588686911c246c906634e976da97e377baea089e14795c4872c6a7db691cbfd34e62a2207d91227524a6dbe91bbfd34362f1493da6edd8a18ed2409ed44060c67a81642b4af1c755bca3db651bbfcb5b2d40f3a5e3461d30635cba5dee6afa5d1e8e60f325cd9026bca92bdd2e136bfc2e17c77491e6ed74ef49cda4427e21ff7cd9d785c378b1a1e5cb15e01b3c2a743b3ca4d14255d2588b1dc43348e8e87678c6ef30066af010e3a526c80c2dba5d66fa5deee5a6a72c95a758309a19619f9e2e9c12aca0b1c3cc0d2a633a74bb3bb6c3452da44822c6c5e58b5711a8db61ded2efb0579711165a98b0f1d5d1ed7093d2eff013c63f0c7c1263a52006303642bfbb623d2bc4436aca41d18b8796ac264574bbfbd4fbdd95aaba58d7cadd72bb6e980a8c57ae91ddb2634fde27a8a11c2b70088132d3064bb7b35231d088912186276ba2c2f2e876b62ae977169802ae1b66b6f0c2a4b1a3db5918368c0d136bf2704e581d27ac5387dfd91c4f0237d890030391382f60e9a2db915b48bf23bb9e2c9225e0d8b146407e6779160900e41200307972472ac991524f6e915b6a538e9ac0181231c345b7ab2f7e57b960b8510462b4830915ddae128f7e57ab782919336c8167871917ae13883185eabb7ae5416079b25a211ac54e184874c4b06a08e7e8766391b7240c9629647a3f31ba5ddd3a7204923ea1959e06734ca1a279d257f0013b745aa16b6f6045895ad1e4cc0a1dd962acc366ca0c577e6b827cd1b178f208d58faae9884bcac807d1f60a96916169b32666baad64a05526919822d50c215bd408eb8a11cc0e912f3d52301121a3420d951ef33692381a13aa30730eb064972de0b0a2e549120f2e5f31d4144a1a4a2549b62596e59e21d9b7ed5b01643126eac818dd2efabd6b5e9adbbc332f2b234e9452b1cac8579edf678cfcde5b6559436d5859bb95fb8899eeecab65399e55841a8846cc7487102226c310304566754ad34964aaa4d5f6de34da10215841b274112215649b9be67b57c9622b6765796f9532d34d03b24bda5885894d8b2939a68e1cc1f3db1d7706cdef4da3a19648a3fd8832537348eacb55101c50276db6cdbd63c80973a74a9c2433cee8ee50b9c2b3d9b6633ecc74770092e64b2f29ac1eb3dad87352a60a172547667ae8ec50006a471927787c40cdd0ed3abfcbfcdeb3d96cd72a8f1101b4166f7a7d325333ca8f3940a0bef4ea64a625b1e67befbdf7367defedbe1d479638e1f79938bf778d36bb8d3b9b86b3c769b3dbae67ef5d77985e75d41f5a5f965e739869f96487ac6fe31b904344337c45a7c663ec230ec2b61884b339388f31c6433ca47aecd7f709a4659530c748c49c2173dce000d280e30da0b523e56733af36cc7406dc346089a6d9d518efcbd26b0d332df7cc2b0d33dd758699e2de5bdf2ecdd4791cc263da0c631ac695690624bf4bfcf62ac34c3736311bd2439b795d22e5e42180d22e47138a8dd80f2f4554633e1d9d04c4e0d22ada52e1421ddd1c357534f462c8b93280a492888666862c6cc390f343c4975e91ccb4dcdb2c471a086a24fd70038688d39d313444b4595f98293eaa754e70616f22116d8ca2448daf07a7c98cd60c416a7e35b1130547c147dd6e24d2bcf2c82e25b8a09522aa0099ed5d5b5cc541f265e935545f8452336192a4df5f15d50af463d0090b144551144551b49cf568f46899d3ac6e3832633233c5657621db639601996d9cc77d3719adadcbb458b1cbc090b1a2878486c1b4744f191a656ef4acb46a171c0c3607c6140ff674dbe96323f384af8bde7093c3e2bd678f58aba7db4e1f1b98d5ba4c8fd77a451efd0646246b3d392e70508aac9474e882a2288aa2e81cabae7a02e9f65c9459e7eaef9dc54c2cbbb6d3c736cc3913be33588965d64f9c07e19e641b25a17d6b3fb5d65ae35f4e6ba297d73232e72672244ca829b242e3cbfc9aa92c67874ea296065cceea664b03b442e3636b22ed9b93385c90cc771e44e2aadba11c00d6d488fa05895556afc657bdbc29fa117d5d288aa2288a5ab11ad62eab475385c6eacf04afd0b10afbb01a5656decc960ac3112ba327229d76e80e7d192d2b34fef57a8e411b515e8646c85d49632f379ba733520a2442234ec67ca5a85dd620c95e742ece780e58be175f1b0da7385c5a9c24ce86abb608eb6bc785fee17b25fc81efc577ea8c2c37fbf14ad8756d9ce043b23e52020c08303961d282c5f5a5870e63dd6403b370c18d0833e654154fff182c1ee55112c10ea93563535feeb4d09265c5d82889717558d102d3126117214e787cf9a859bc4c28768141a587850f268fdd8705b97584440e0c60596fb852e02ba8164839638cb10bb6ede3497624a22e05a5798c5de8acb3c6525a14f1f258c3e315b8ce630f8f8f8a2ce931d2b8ecc15a5bc44891250d66675b1a7ffb4ef6d9c73a0ed5b1e2db0715aaf77cbd344e3c067e4e043921c2573a4992e3cb817d3c62047d5ab3a31346b0688f8d8c4885f99d381146085890c88e1af421fd88402b8a8e59751cc9ea8366a5dcd1190457b0a4e16a92d5c3cd568e2cb32fad20e1110f5f7d4141c22f3cc6465e51353568904636421d494a253794cefa4127337ced47610eaccc060b0c57acf8d69752aa48f95129d6275768f25ca16933850acf7972f4bb925d44d92ee668c118e38cef2d226573c3661c339095959545252b2b2bebc598f5c266c9cab259b2b2b482505971393284727426cb83070f1ed07a569eeb5dcd943cb1fbbcc8ba33b38175d65aeb1fad1e8ff7db18639cf1dd3fdbe19624b1596edefac8009201e49efd18ccf2d23f766ee7f669b3599fad67cb0d6d395bce662277b57ee7367a1df87757f2ee4a9ef53ccfdeef5ac97b7177f8fb7e25bdd64dda70fbdebbc9addfb6b3ded376f796ca9df7de3bd6e23e2bf03cbfa2288aa2288aa2288aa2288aa2288aa2288aa2288aa2288aa2288aa2288aeedea886684ca1fa384c4095f23b9caff1814588454c13151a5cb6c17df43de69c3307cf390b95cf39679f9c855daa3e5be94082f9fa9c47e208277b2dbaf239f7e4ec214f017eae505275ca36e68d865dd5b2f2b96ea9432c9f7f57c388629fe17cb6537486c9e8734622999a3e3bf954e573ce4a486096cf24d6672dd2cae72d5d9f9d1cbef94c867dcebd1d29f6818c23c61aed2ccf22fdf8ce32d9a6cf6e67780ae177160ac877566aca2af99c5df837bf37278f98e94dce8f07023a62c6891c2d402fa1920e28cacd81fc870c224b807020c701b99a07918007e1a4cf4c41dc6e4e1a31d35b1133058a33f53f3f4e1231d31f3877be565bc19615306cf171c4494c57c302f29affd43c881cbaba9aa310e7c6d736d46ab59aab50abb98c9c325320728899d6e0f8fe835088a37e9fd8eebd25dccb26c5df0df77ef0eb3f3021cabd5ea744a4f97bf1ec08aaf1259132c5a7bbea0a03a2d8a68a87df5538370412c9f494e42f09f5974a0c18205a77be9860dde075bf4efeaed0bd6f78fcfd70af936223ac100e0c12ee28e55eb739c8137c67a1febef9fd09273819c44c4fb8dd6eb7db4dca4dd78f18e12410331d9185846e4ca19b2c0fe4e40f33056a03f6427e859c8c3253217787b209dba8789c5f9c933ecc14e73bf32142f8b643425d5a6a7ae0a11367852e04f04384f82e0fc22f88e20f1ee7956feb7f7e7e9e846c64bc08112272ad56bbb55ad5d73c87f435277798694d062d6f82094eea3053137298e907195ee470c440e651d4c91b668a92367c3f1e79124870b2c94c4910637a9adfddf334b791256a4ef31ff2e6349ad89ba781a0a58055034fd10da1138f068506e434da071a2d86ded3509a028a39da606901b2e60ecd8a46f31fd08c9e46f39def704a5cfc75b286d893fff0c1491a404040336c6bcefcede6249399ded6747dade6db0eb1302745152978b89a8abada0b5f73528699d6c82533a59df992430bc1a4c7efba11ac5f0d7dfa2161cc8712a47e7e4c18fe88887a02844be3e426245ce3b32046a8b9f3234638a964a623aeeef01e04081fd40c2143acc854f1a103d1e44138d9335310b77adad42c7921122fe4640c3315badd6eb7dbed767332c94c6fb77ae6d2c4791cce4918668afb79201f77fe403e922544fc0ef7400e040404e436202791cc14e856cf5c9a175e8408275f98a908a29b37c104278fccd4849f9f9f1f275d30d31f22d5975082933c332de1c3870f1f9c7461a61fd0d879124870b285999280c6ea51d449161c6ab55aad56abd59c34caa1e9bdbb932bccd46ff5dc1c7e7aeebd67c4ae932ace10f910219c4c61a62168341a8d46a39de1f134278bcc9496a792f9a020af78cc34884cef315e72060a98163cdc2445d1e1aac76efbf9f065c388e6a747092311049e20a93a1582cd4f0dc89b3c1e01c3410a8ec9f05bf385c95bc74e22a1423348523061c89ca33bc77d59f23923468ce45c455ffc4523c76feb77a2c70fadfa9d6062c564ea57d3fc0e97eb9320559d20559c21b55f2556340648d2260f0c3b5ba68abaddb83576cd7911c63a047068dc8fc1b132635ca718748895901f102b213c7ef0d339faa8735813298f6c25e17dfdbc175f99b554718af8b47c8eca8b888daf1aa41206a37c05a9aad060142ebffa2418c5175c1256cd04a568f9d52741294282544922563c2dc7881f8352ba7cad08851f83594554523811ac9c5182ab37851f8359534b64d8394391d2a595c936142276a2c3e4dab786c243eb536b5bd5d65a6ba68c712714a40ef5bc1bd8a4b5d62d6c3ea78f9343b9babc69adb51314f308beaa5192e70cff6058bd302c585661c25a6b6d75fe955690ceb86b83a1e8de7bebbc1594aa1c7e0c3675398b36c63132de5a7bedf29584a7814c9b112c4d260bebcd6aa59973ce1b5791f13202e9632bd3c3a58c4c30840ab6b5b319a0a96f26cc1035ce39634c464a84325a42614d57613d6a8ec3b4ac99222ba423f3c4a1c7de9ba9578452ba5579891d1671155227a6ea9249aaba31441b86cde79cf3d06785c6adfb2a06abb40cd939c29cf8b4f99c3e36df93ac44ca3b87d869a4b8558241ca6127047bbaedf4b101f1132dd3b164927ee23c0867a47781d697e6f1131dc65aa6c3c9749f16c618bbf0cb1863cc0bea983a4f5d110d6ee8009d961089b8a9658e40e523427c9832363669b211cc9474a2c96e2f0c672294c2261bcdc36f69fbd8824d21d082c40e66aa7339d3845b3e787cf4afc8c14cb1d61a676191c379438f7643c3d94a0a9f668ab5d66338e0f1dc7743d93a7127c6d59d284b43b10a267cca4fc6c8a0d2e1fad8805d35163913247218e71cf49926c812e30bf68559f68141c238e79c73ce58e78ccb39e3bc770c3466e4e96303f64ad936e133751d73ce50a47476ecd8c4be7af274ca72ce5637e79c65196bb8e9ae8836e79cf7af76d35d016d4f9a72754e5dcaf6063325a1a0947471ace75cb2546b323cb36498483480e1d1b4a0c08ea8b4a0c4924eb79d3e36dd92aa4d274916846bd28be271d8e3bebb578e5964da3c898148121f5864ae9c103fe71c8543eb9214c9a294ccc8555a3b6aca115652a4a3b4f42e55512e03c39e6e3b7d6c4f5668dc5751459d93e18f15494c783f9460e89874e17447881e148ccaf29c07a8bd6d5a564ed9b0b35555d9843793e123ef736b265e1b64199f3e36a2ce757887cabc2354c2248611ec3cf15c70b07e379d2e1c44c6bb61d3dd299a8347c6c6e182a731121f5c871723e7b8a09ff374b04a8ab9653a3b5a32d9d61a8a983cdbbac963ec3ee4d0d5e1a09c091256391263e934824c5b13bc62c9e3c1d840fad8ba6e10198f0ed2684756ef76a187716c176f64327d54a4f5d89d194c3c4631647b5fe1e9a191723c18da670c4551b48390271bacb67cea98aecf39635956d273fa38c85a884ae2ad995135848a872e8bf9ec02cde79c9fe038551437b8e98243438aad1e376d7ab51555670a19260a163d0d4c4834235eed4969a6c333348fd8285b68d1de507992a13022ceaedea8a9b1bbca1433f4504623ebf234eda817d8c78622056fbfb82b86f9490e7bbaedf4b1b5e8a168d1845d06e927ce8370453d2b34a6d84b8c6ae5a2c90a8d0ee74cced951a87872dc0f128aa23eac745e4d2f98a54ce6f5a461f3f6defa0a8c8c5396c1902e722648e44890b8ea352f23493919cf76150442a35c332b8d3ac8f41e6a5d5aa42cb3d1a3f7dd3b645b49c8e36c3b7d6c4ec3ed2406f6e9734a4de77b3af9f270c528db4dbcd4b41df7dd4f3c8cb7c6a7999a266da78f6d4791151aaf2c63dc9bc7350887e2a9cbedd0b8834dee6c991e9d78f82733d238af21954a1b8a0785c006455114454b2e3e7a48d74c5606a98c72e6b1fd54dc4a565a96b1edf4b1017555be417a19298a83f51e164e15c98452298248215a17e94dada21822653392150221ce82748d320c196a100e61a3647d861c90467ea0b2d94e3325ab649828a09e3498a9aeb244e3d154fb8231fb61f6d4cc287df068c25e1e193220c3d9128dfdc3574a2d691f6332274af9f4b1fd48a111cbca6983e37b8122aaf843060a1e5a557a43af18287c54a98181a287506906182880f84e1b8729e7922aaa2a14544022501649767312f70b3aa9b44aac71481e74fb31f8eb792e1fd97ba6d5b37392d6ac2cdaa5e521b5b58f2d86960c5fa62f67f613e741b8184f9b4b14d6b2341ab0f79e3453b0c718edf6b4728d928711d5c5381b7190595d6f0c6faa5ba346fad88a7709535d26299949eba810723d75494d393bf915eda39f8f2756ba18f56b09e39c75d6398c12d5059e618282a2288aa2288aa2288aa2288aa2288aa2496839e71b5bb3104a221c7c6c35ba3ad488da80a3e853c329f7f8d89c8a1c7e3f1a565a3d2b5ee559f5eaefaa469195d60c5a6dac744f636bac743cc2ac743a7c61a4b858e1d0125a3961e99cacd4a51e503f13fa6add04efbb6df8f4917db18fad8998c1b205525add0edfa5f373b2d2e520e67cf42b22917259c5adb1eb0d2952687cd90d1f2934fe6e9f99464f631d0ede558f16341ece59679d31c618e38c31465114455114455194cecfb1cb6ee3b5da372ca57d66a69a0ad25e7a2abbc4d03286323a665e641abc4da758038ffbee195dda050caba531a6252b26a91f32ac96b49accb09ad154ebc09064c5d46585c6ad532ae260a4a98aa1262587b14e1102e3ad8cf1d6da8110d62358c30c120b386080c00bc47aeca4c3d81d8a07e11c28ea335aa9f5150fcf4a14318a103812630c12d81332019dcba8a48bdca972c84a684300b31800088340208bb2308d4ac8d4d50314000c3dbaa4ac9478360e4943711886610c05510c05310c0331c028840c5390e55800434e288415c5bea2841e3bc0872c0fee895b19d5f46077bb2c556a9a6c4f13b1a558a34a08d9a25adf2dea4de2869ee78ccb4cd588057fa90b25b86f24e349983f38e340293cc1be9520e8ef1b80061ffe7a861c0e97611abe3e687a8f7a9f97b7f32360a0faa110c31a5a78700293e1e85358967fc0ed8a51da7b5fc1916250ff69df5c4746602ae2e9fc88bed0d4c5212289b1ad164cdd440a2db579e47d654be403bff51daa4db802bc5bb654936c0b9cdb26ee74cd69a34af21265470511b063370b01643e1d57078d1d7fa1faf911b77413e0e3b544768383cc4e85bf992c74ef5076680d2a4c2db38c256671c71f30e8bf4a98ce00f085faab9cc23f304ad33625f292fa3a48a034ebb4dc4c4c6b0dc184e092aa01b65a6955fbc75726edb5f05eee0d535ea3c0e622de606f42113fdc0e1d266f90a0148c1602c37fda4a888c750e80f50cc3290e8f042624c09085a604eac0b68bb8ebbd81138941cb29fd66c9f9fa9c1a5ff9cc93684b4fc426e84bc0fb06b27873aae2638426769b3cd20366d67883418b9e6e53b8926a94335609fa119ba75c4c8031e3ed22c9d34bd1630bed2f815ba97e19bb4dcf90dac78e103e055e5cc8425b7030bcf6e201c33fa59a9b573994f1a9b2e6f0f46786022bcbba86fe3a053222a6d94ad21e5989dc90a90022fcd2d5d8bf624d38707a3eb1a10b305b9f02ada07fe2d46bd36724c94ee14cbce8f318cbdac002d30a57d14e4f674727722e0ce17b4490511fe96441cecd330a0a9319eb51162cf595c935ebb7d923b3835f5c8700a35d478fb57daf8dfe82af6fc177aa74c7717f10e39554c6ed422409fcc7bf90e964d9782e0e6949d869a4ac6dcf52fb461e936740cf017a82aae5420d2a7c31567c69d83767d891cff68fb4430855a471937bc504ccf0c409feb26a47480f028f410a84d39ff62dc2ac33ae662b324040b50f873faa9221280dabd291117b04457d91eb5625c608a2686ac81e2de26d82778bc634c66be693691a0e6a966c1d2dbd98d6dd2e1a1cac9065c816f9508eab2202beb3fec3cbf15f026040331c825fd4c845d75569ecd80b067d018202b829ef9f39718317f609f52ff09aa04859a51ab9c006930fa207336bcff9b784babc37303e466d519e59bd6de43ce50037d0f95b5246648b001f3b28191419321a7e35374ef44d14c0c3a8e911550c3437b7c8ed06405d5e062a57d9ea39ed29f884f2f4f0cbc5922876000e72e28ea60baff3a5524ba6d2857bcf4539beee94ec2d37d9474caf97b864b00bf6864c58000b8777f6109f84ee69374108e37d0503eae19063653d65d81ffbad8cc78046f03467c0e6026c3717d190668f1e8489afcced7bd0185e79eeef1b3bff40a2510d7854413fc9e77b6a9cd1b19824b127a9e9c1622c84a8892cf5a69408d157505fb4882fb7d7aafba2caeb07130e23b655cd8774efdde4479b1d0c63107f4cf7fdb98c851f8e9091103215c5c30d051ee9528b230677ed065f5c6fd9ad529cdd98341d2c1562cff4646b98612f4add1c0f6746530795e5d949d72bffcc7713c0e62b31e9ce92aa0f71409f9b75756797074c8583f56a1230027654ff200c2c683653db920e35be6d59ef753359f255258cfc740d1d337706053f03d2aa9d5614845183328944fe970057a10eace4b0d56a9d3b681bd69535ed95f4084e93e2fc159f833db0f89c258f43c173a76a20b3dc234784ad46734ca500071138703172772ee18b14c322c8fbc9c8c38e51aa37f26ca92aa25ab135cc06870afc11303df0af1191ccbe088e651852fb4182d3011756190162da866fa2b691c52903e25b581bb63b86c0b4a8b9931a9ed45ff707f3aa7ac6e5d40fef610e0dbf5389b452cdfa1142e92d38f6e4a97a6b0cb88eab9f910cee72eee4899238fed80e479b9d1ea8143b5fca570a06761418128253def8609f43a1dd767cae7e8465c659262aa63039e3f78a18702edeae10644a08867b89bb9e2abfcfaca1ebd5fce286d8552b7984bc370edcaa83b120468b65fa7acd2738db621b060432d0aeb6c4ca277c36bbfd92623ed7b4a3e0eb03894b32f630ecc9a08e56b0a400fb3ee2ea83e0c11f3f0ee0c7c74e1b251f77e8a9b8f16708be11bd700f04f6826f3d32e40e8cb9bda24e7ff5d52c26a40be807b56d669410556ac7c287ced3390a7f705a5fa746ae6e920afa4b892c740a88308b32714f5980b6a3b72947126669a35985cfdfef60f61ca2e760a9f93e842e09de928a1526f8c2132b8428c9e5b8d98658e52aeb2cff68d4aa8d411f2cdc81be81fecbf8e96238c0062c07e5e8b5c8086f50192788ad1a08d10b71ba38b0efd7cf020607a7698886ecd072d070adde18d1e8275791ff56b88e151767706b01bd3e5bad2d558d6befbc7318ca3726a37305d9c0b339ca281c0be6bd666787e8f9e9d2b408174c8166600af707fa5ca6e44c123dee59c0791f1b8a5d44d9475a0645fbdda670f561c480190592469e3b5db3c253bd83ee22bee33f9f0a54e79c13278084db9144f542f7d4414ddfcfbbbcdd0f6c4ce14ba3c732a16a226ab84cae6bb31639cef518263bc01e4332bef0372b4035f459ea099d8ba4c1bbc89b909325760d21fd4c815f0a5ce33ae85d75e188ae4e171a46ce58e14bc7a54f398d77f3a150249b9d1603367a779cdd11495cf74b79812270c2df2a563a93f34126592db770a9699af861aa52cbf96f7bd72dd446635527040195f5d05af4715b61262282e9761e7702fc0f5afefc3145444b756352a1be71d5559866442de0d001ab4570af3bf8cff2e3a14d2e33f7a893e543a79804e876256b3a866e942019a1072b073606626cf0b1884c1174e9753cf7778ddc9040e9f821e1b51b2efbd8c860a4096ad1d4c243f72e3e8b96efa5bfc364c341daf85b29133b7679841ff1a5149bfa026a47130d9ed2f97b72e374fbe07a00b1e2de8fe4824612b8b7e5739a69827147b74e7311acc6ed5faaabc7428fc4ff1beec5887c3c51bb590a8e9b5a8efcb3d06cdc866ca9bb4e81d9619bb5fd22b5481dd76c4c6617e28ae62539a63c7d93e8d44097795899392d1a6bc22b234993ddb4610ee6df81dad8a08390e1b57f32120df23647ff964a8e766750d4377ceb985a9ab04a4b03d2a7ce73f3ac4b97019940a00c9db85c0727498a0ccb7601189929aaea0756fbe95eaa44ecbb7ba351ddb284d8ce6eaf713b2f656d82d83e9975c433fc7c015edd87e7fc7573f0099f3c870822ccd0345765f2760c2bf79239929263701e1062bf65fcf49ce637d4c132d99d24a536190e09c41c8b8f1449ec7519e75832738b4f34836c6af24352a328c35be9ea09649187bea040e45e4137aa52e77c01771b82538b8bcd368e49e0865b6e4b7bd249cf10b86bcad4ae8a94b12ddf169ce8b168ee268fc4289d9103ba98855093c91d90b237802b38996687298f2b4243388825ccd4b3f79a9fecd0405f4225f7cdc001120ead172850d98bdf30ec3a605f7e56b85c47ea4db797208c520c648801308ac9f8d4341c68146406f25a8a9cec7d8481f209142a62497bd3b058483d5a9c62a1c3425887ca97a6805f664c4348950fffa1c746440908e9215ac3c18e65895a553a441646047e03943f77cc02c1528fd55c8736f89f92af0212ca76122632f4b8da75a8a4fc94c9afb488e59057ca923ba8e9e331ead04801c784656ef3c424feb4693c5cf691e9b32602639f016042d335edae29b03f53f86a22147a60814d4844fb902ea5f491415b353f1531861808968e0c5f21910163bf92c3c37f7b5bf36de2654edb579968a5398400a0f3625be15f7265025c142e35394320037abc332e3174b69443163434e2e29007ea3306642a4c1119c47e7fa770086a58bcd0cf6898341caa69a6a72919b25d88a9f6ee35d086d29901e6d770215081adf90fe0484eeab4d4edaa84c1452b905ea8e9bdf1fdd382a723f77a49d466f53c7600eb584f5ddcbc392e2676311c2eb65cdc03b90e69ec688c91f9380917139014b2f66d9d615edb4f309fa2a11c128c44521428b3792ce56c58f62b03635a0f4b2ee80bddc4319ddfe81128b18fb05a984fd637780e1ef2b56d3d467a31a298883d72099acdfacd82abbf1dbafa5df9b93c318aa88b731c54c16df767db23fe965e8d8b8168c34379a1a91f90be60081ed1491262842fab281c671c9c9ffd2799f3ad7649576b213da6fe9093222e3d5a8d1bb68a4be6cc7ec3f90362787b22017251224079a51ee6f368ae18434075c0ef9f8ae71c4925624c928d097f7f2f7a0793484a1e06ad738881866afd4519314ad5a2f5b2bf763dfbde8aa2af7532a01229827b9e8a285098ca79cc1eaa1bd0d062a08b88162d1283692579c870ba8fff484994ec57b3ca286d2586d537389518415e2fc6a7dbb7b5abe316322705610667f40c8231a35c4a92a0ecf28fa31e7debce30a9b3266bbe98575a883610986918dcbe64357c6a31d2bf3aa48c82691bbc884c1f7da73b3edef6899b752b1ef5d5925c6514f36e69491fb3417a0bea3eee9acab6993c3b35b4a1f57db015fb20ea239f0eaae2fa80d297586cd8a0ee2d6e92245fc65cb353b9219e400c4154e447913e19b5bd8fa820b48ffb0634e517c256cf6e59c764a0ec8fef1a31392a9467c7d0aa7266d8df3692c9a5215b3e24a49182f60b9adae5bccfd86cd5fcc85e4fee07c04f3b4f19a0374966f139af93529c1225529f7e38245de009a28d646fa0dd3100d26c09ce2a2c4ef7520018e84cc361d1b17f2e197687e1b6c1fa9488ac99d35b022aee3764e6932806052eb6d04daddc1c502060dbceea42269b83287b8643fe46751012bf1528ed4aa81fc678a22e1fe43f6a9abc0c1ea53c7615fc09ecc29d797632eab5476a7caf54f98bb22f0c126cfbad04841cc0e152ce4445ad666d43fe3fe4e4e21c92706450ddcb0cc8ab1ee125f71a9dd1549397bc5133fbea78c95b42c48ee825c1d98697a073105000a638c507f49803360647f20527d01a203c9c8030508acfe14ad3074aef8a2ef4b8a222ddc865a6f869a18feb5f999649c7b1feaa93d25bbd9c47ca4515c16d3cb2728a2abb1223050a74a7990d731b054e0cc817c9639c56210e0bcd55205060e736d466db09dfa7322622437e351d9f9732e5cddb07baab120363b01f61db1c13b090e1a828248e88a1b25941d0f92423c13719a91e4633007c08c8ac6198b0367304f40b1ae5467be12702e0a419cf6feadb8ea4f2698a683550cf816d83c42c8a2c34ef73aa6be1404681a1d129f0d6d2adfd5a86d6c52ac4d7685c143efef8b4fc5b24b727d8fc6f95033d74b123760020a1a954a770e863cf03af5d6b11a8ddf4c06e8855c01150c41c11663ad2619c19b20db2e54fbd3c1b5913b2c3e21391282177e2993fcbf5d40f4394b344ce861f19064a7c5c9de1e18ee64ccc9035165792a49f901d27aa5c80114b1b0f7e6fd7a563fef643018cb7eb38c3436cd2a1e182c2d042f209e268313f4466cc19403052491914117c0d9ae78a8266b10c20f794570b8bc5731506541c503848675165639d473a03a7331dd91d9f333c2c85771f66c1bc49717c1471fc99dc375a376977127a9eac816745d2e0d47ee44306d495e63d8125d3fafd419a4b3d87d3202e447ac0c72e933c9d440b2692bcac598924ddc74fa20b582bdb455eb4798bd6473591367599a4c12f648e7c6c85f3db310ee7ce2f7cf67f1ee101e37af5d36d6b2c8c9016d4adb89e7eb26d2d9820514bc4f51675dbee7420316a23fe46aa6fab03ada6455571375ecdb6baf224a87f92445c4f68696b04c5bca86dc2d37123225ef13dc057fda63d2cdb1b410656d042c9b1f459a8415d453ad6fc6a6778589a9b602bf5098368782caa15bdb486fced2b36340870da142445236b96b32486d61838ffbd38abb65e380084b13d35aef2ab665da46d0cbf3e64a52be020c2da9686b5def5fe6a7f1ef8e9b305684692afdc4807e0e249119303d5773e481a580d82a5a5d30dda36186b64cf00711d07cef0c090981087bca9a34544ff0b8a801c5f851f29dea28488a663118d3f2f08cf950146bdaca04414e481448fc449ac8717bbe9ecd2febd198059f0afb7d054db3028c88e1cee085c3ef1683a9c3e5ec7e283ab7f13947536644ea4421d938eb707e69449eacfa5479006b3fcd6697acefaec0c9931740b307c2d8a70e5c53aad9f377eb5f877e578816ac7956099327b8901e6ddb0d6dcf6f4f3d8059f79536f28f0576ccecf917b5cd5a789e930e9c7ab2da5c7fb152e5239507880d4296778e066b046149c64bbdbaa7d21157edf54cf891aaf04fcc1508c595857bb611ee81395998878978e20f00dfeb5392fbac3b4f41583f3aaf4e443ecb6220dccb079dfa413a2b2ca33e187d433675b2c9b312c799a7f1cceb067b68aec61187638a5cf1587d6d682c880762f76cde80d1c867bbc0f9dac8557e722282e82a221d03369f97abfc15cdab3c1ee8a55e7a1b69cd78c7ba16ce27866991cb6493e6cef5de4da0a35bc94bdda9ac8da1b19effe5d59838943307b2ee340b4d28c2151844e6eb6ca1c120f853c2708be6b75e8cc0517205c816e83cfe43c8d3bbe0d64988721c18fec9670a250fe042751ab331cb7ad16fe496609f4bffb23c14d50e4ca2e5da331964a3213319b86973755816d2564f31e7fc40185d8568af9762eadacb9e5ca1688718be78ff6d7579d7a6c06fd3d2868bd6871347aa0fb65c36738235e8db6d9b7529e0a1ece17fb7e5866d0863bd6a5d76d44645058a1fb5b3fa5e66548fb6050aaf37e5a9d528bbf6a7ed5ebc3e3b30e33b7898284c2b7d5c887313948262378da0281269082fcaa1fbf47c81a614263acb762a1986e96a892ad829d4a60149f458b662bd1c8d95a5c5f69f8d45cbd7eee138607e0ee440ea8151931ac11e3637424285bfd0a1e87cff0b192530088ba31c5c87836392351cd20c2a5a9d4d486e1cdb8b6d725de96c8c02952ec914dc94fb270af21ecefb0687c8883290e448d68fa98b17969d95b6cf52722800f7c51f3626d8188e2e1b038fae6d31236838c69ba5abb1707281058b2c113a9ebb555a956a5aaaadd1597b144cdc595a0e825ee9bdbb026c8d237dc07241d831772baee85490f8a9aa91399094b7254e513c92c108b73211d04fcfb9134950f62a689616025a0c6996e2d1a85a2b50c59af0add18f00c4237022828847b788b1b5266db5a9eedf4cf060cfcca511cfed7a10ebb2aa1114e2be0267bb4be780dd1a73aeef10fa4dcf9e5c97f88aab2c950aa2c924c069cb88748b0c18dfa91060e07a04989287717b3db041c27aafc4fb2903d5e2e554ef03dd4951d71a7ed65b37ca5a69a4cac76a41a4b40fc9cce040a075f453a4aaff7eff7c5bb3cfccc965112c67ee2d83258bdd1562b6f2ccda1323720b1890dab3fae4e54bb4e4c896776487f7b3e9543d999a123be8bb64068371baabe76a0e0ac61e0b295c31ea700fd56eefe7807c1d4208e5f4e8a2b74cbaf1fd9d2a313413fa277508da5b5153e955d6e3814d2bc8995781cf46b000fffd76dbb7b13f107c2c877ef911485d49a5000a28b6113ae361e6de54e50a1db62c6b72e430ab20e6890c0eb89f4d91968ab3d511d0c2849db091a0163f6735cc24c52c8222672fdcd3f5abaf07ae46507fb664e31450fcf29a7d5272c20b50b0ea4c980bc9c204028cd4c7d21caf6866178431b158bf610713a258ae67de1b5147801e530535f77fefdc17dead1d263e2840c48d01eb9d9309be758e20b0e939706dbb8a7700a13944bcc37eff59aff9fb06328566bef4fc74d63d007b166d092b9b4ff83743006f324b8bfd862c3d061e6bfcd9268d052906eb8c4082c5f4171c19cd0c6e9c0220b85ab6d3fc132464ab2118bd409c504d85ff68f643a8272a9e41cf11f4fa626736bf4ddb095f901830020299606c9cb534e99b178110290675d35dae42ab1f858f148077c346ae7cf88970d32b5db1d58a2998565acb5623fa4e871c5acc5cf2d20430903fe975bfb62028b148472d06143a217ea5f988fe06a6af52a47510c96be32fff3a0338d4ab244653732393bb9e872ece39da32146c7891d7296cb79d3350aedb8bf0ce1add145670a9443730c14a83d839edc363f6b2d9ec310e0f86c582d4847db34fd47e7b1311db93985f809e69590c116e5e02e3453421b52ea46ed46195bcbe5ac330fc5b2128d93967e6cce646cbdb7527522dfb24d5cce602f7edc9e3eceb6fea28f52b4dcf5251fac46928ed83498f30aa4e2123818b2abe1689ab08cfa5da1c641bb5877918d06b0920d3df02e49978eb01805ce2b9c7ee864932ba883e9da094f582d99460d5e71ed238f150ba9ae6f9242b5479186445742610d0119b10b09968c940ea271590a9e278faa93ca78d2b79625042b99975527ad1718d3add27a2b0f1262cecc66c7c562c31f7d3811bd0e4c9e566c38b274c8c7e00feb7d15c58d15117fd632409f1492dc9677d14eece03b4193499c984a1be3f7cf0dc5ca641de03f4e4c2d63a64c0965e9c466480c8690931ad8f894fa84eba8f3de85c85f33d5a21bbc76257870df00ca243da4ba4474ecb172fb3af37c0bbf1de8773455b94492053f31c10128d4235305807ba48574d4f1002981824cde02e3fb98878ca8031f16add18205d88148a0605547ac7bdaab804fc06bee69cb265061ff719d1301cb9c2b65e7037692c044a08070272bdc3fef05842a716e70569b0808ab5898919e3baa4c2240d48b398e790eda93f1d270bbb220ed7b013fe070617ccc619b97f9b5ea4f2e701b06738cdab6348d297009db30fc5f68bb318a75302b9fac167c4189d3ddcd9f70ea4355bfac706cd72c872ee2e78bb957058cef4b3c205c7ed0e4bf7dec11a892975b97153e5c7132408f5fdb87ac084dad2bf0a0b353dec77205896baad0bcf9f9861ff209836a8af5311f18af3a99ecc40c729314c3a20a2e6d227282fe191840c235c76619dc747c957127057654676120da1817442a64b2c6310b44a462ce9b6b54b62763f8c921e83f5e118b60996b0cd7687a789629b332d360fc6a63bcd3f1e2f53b2da78da50c419c11e458a3b46f0cca27541cb5b90faff02e70e6921a07de901adfeb0c0c26af23cc5222c4c44c319fc9ad0276c64cd9c7e2a92bc704285c7f58f22237a70fa952a63bc089d9001c50109eaffc0dfa7388c7a7fdb57df419186ae88f1013b57cbbd0122f96b12fec85077ac4a2eca6c3efab6c1efa5ab424251390b56a89be7d8be0ac11cd6483937df4be7cffd882d20bca92addcf8c5764411aa9da38fbfc76f771ed81510e1e572ba4256cd84eb0f9418221ed130a901c268381c4033a32b9e13a60c8e415ce2069d0ff97a1f8a49de4830787990c21bfd99c465640b54b7af22c9fdde4753733e9a646820dfb4f3bc5bcd37f15145cfdba003d0b7f8b81d9247fc73f055d1cd9d08871dda7bdd879a60fae98f5ecf04356a1dcb2760dbe9f7d20f28a0410b7a92fe92337c911ad2892589597688c338c5f6c64fdcf36b478a6a883492dad3c22639edc89cfbacc8039b06965e996e13774398d593478c1dfcb0ce163197b177490ff911d9009e09a8c9ccfc7d13751168856da4f38c3a8ae757e144511e78a6216cb063ba120883390721e425e963d9debc41410d337e0e1f7238accbfcc51102d9c776ea88e239efc1d83e43de874ee93599d5f812a416367c06b261468732d4a84d81df299de5cb5246fb091c77cd9a7b57c724ead4e8f182d47e8dd210f7372e253cc2cef81dd5022e9150a1dc5657b17c195a8ba7c83cc3c52695bee362b98b6cfae156a0eeceb9141e291e575929d55867a1ca073afcba19ab065676a89b5033a26e3774dfaea842c7b18127c99c00b146ecdace45412dba1aa6fa6b2107578b3ff8734f8088724ca2e5010c2f330146a137c224c1578d2d2bb80eb5e229543a75cebf79d5827a02c4cdf48a71a5b446b7ccca8b8a315657bb384ddb72425fd101e2d6c25cc6e7b555b6478e5d6678f32120e7f3b9b29620912c4f80e8f352c000f78f83392384c2480161ad416363c6ea0a9dda3a86b9007520f16fa160566c089dd4593910d38bc23f383a0e2ec89da4751045d2740697937e72ccb323bb79970304b21d6204ba3a94e2ec9c896a2d7e69f55b5e0240b8d00408679378c2c1c6f97a41dfca8185be4ae47420c74289adf50ce37864bd193a4cd586c07869fd3a52ad0534e675b18e172706614831c665c515d147c20a2a42b7ba7e61d195e0db5fd326a035217126a5cba4ac47bdeac007cb22565adb6136e0c85d4f7868ad9c5f22cc41e731daaa62afdc29a1176139ee6e44a2684d16c9f3294c2f8df378a1722ee78db5b75c669d28a653cfb235f6ce44415d07da934cd4649b929ef6abc8bfea6f3688ef352f478b0079d0ed093d4e9750b1e1c78bc524037760ee37118ac7ebcf5ac9fe8deb0bdbe7a9838aa45a1de42d18ec1893208166e188084e4275bf2e23b2f825d3f5c73bc74e33d4b7c38810fabce45f0440ea6e1620088053028cb1ab59bd030041aceaab2658f54a5ff008061463371338175dce381a7d81eca43b2c4c14ab7c9641bd82a96127ac3b04420179598d14568158d1fec104348d274d0cb1c10a80888376c34cdb83b678c33fd55bfce594a2d3eda292f6e17232255c504904daa230bdaf2819b33a3ea21596e109ef7fb4506a028abb5607220866c960b0fbbc312a4b0c956cd83fc922b7aa400cc8e9fceefa92d2e8545ddb5d743ee793eab47d622021df791825b00fcef3e70f132c844b9faae9c23177cec141d77fdd9a0865cfddd2105ee87c7d69a3608618938461215830e168989cbbf21a4c85219453920c8784070f76b27d61169847703d90f2ec5f495f852b0be69cb4820c9a0ff92664c1bbe906675456f5ca95210b003586b7572dbb181bbb6dc82ce4a30985792996db59bb67b67bb2dbc15bda1caed1ac40660ae9365c57ff69001428245d93939a89e376551d872f4f28216385aea9354aab89fc4d6a9cc14cc89ef8cfee04d956547eb069f5a61aebbf0c387e0f09401ed0ec4e8b0d0e756f9d1673ec3a680c6207572923ef2bd2c65c856e2d69ba74ea9c8477891f797138bedab7f52a007151ce9d3110382f5b542ead290041d251b6acc805e9ab5879dd8d393b1d155482671c2c87930173b12c3c3ece6379f1b37bc083611921a8aefa7411946f3c8b8582719b20bdab15565123fb51cd67b004c43098a592ef556ecc7806337155c0ffec425700e22c2c627612402c1879a0ba5853e67ae0a40abb6808fa14a1fa7c4d51f4c4a60e7085a6c848f5c77f33e34dbdf4b2a450f01efb1adeae8237fb94371a2bc4a4167d7d1c2b7b64790520faf613e3e62c4f725978b65ed5adf629033d7985bfcfa1c5f8ac0ebeb6649e94b4a0722c7f52e74147367ad0b7f96d15ac92ecde36b03c7edd3a0ff19063eba7e353b0724aa1d83a0fcb508f3ec47e7d97f0aeb4dffe40127ebd8b85a548d8be45ae3a0f541c5a8710bc23751ea292c811759d4c4e8c9bcf94ea3c50acd3df91903531a41975973a28f4673a0f5415befdb32168fb20279b5fc487007e80074dcea7205e8f42e789129cd9f806252d6b2adc96aaa91d4884ffd0e584bf80fcf7dda1262bf3b548b0502b321526de3840aa820ef463293cf7852bc4c2ada1260e0c9160965685be8c19e0e464d6e7a3051df556bce984c18032cc52ea4091dd41f7a132fc37f15b0ccc7028efd9d9aa96121ff621c72b0c0afde6bd7458dcfd81a18d4b23a161b4afa64c1d17ad069c1891a0681f2f44f3a57a800ab300ee871266ebc934f69441855e2823202b63d9677fc27b10d3383344425c8c06f2bf477f04336708c22c515f8cf9e774e146610b84b52ee5b2919e5ae4431a85d2971e4d6f20a451286741ebbf9759696e538fc3f137b4da42d5928d1fcb6109f03a7e054646843cc7fc99bd74709d83ced1b6f3afe7147eccb95288c4c99e221bceb8aa3def5e3a2c8a7d7018991e20199d00a4335527509a08ceb3de764518df5b15aa6ea7c212a4d8b02e6838e84d81470bb0623c19321298b00b4f361131446189033aa5b8fc618a80c93c5c48898d134ec123a0a414eb2f08d3fadd8a6f62f37d2bba6dfa9b4ba838fe81a27cf52f43074e351ab78be31f74632bc98e427c84eb0215aa2c133f15a7b66d7d27f405b42310be8cf12394a353bd0e5cb0654973d96f9cd6c15cab29f251dc3d3d02d89810314dc8f10ffaf1030bae4dea7c89a6822c2505ccd6539df10a10ce9c13fceec4831fc73fa0d823cddda5ec24b9cc79be59fbff4ee78e7fd032388a069358f0ef85734c9061f0a3388879c1d386e9cab83953dd26d66c191f3d7d8c2edcedf887c85caab1c2362443acaf266ce2ef5aa767f4f41bc04e61fb630f90534f4b1dff80d0725fca25c2b2704e998d0aa08cf882efa5aa96f8edec8998472f92ef58d3f10f790668bf4b383d9660910312d0aceea5e31f9c0cf32c385acfcee1862340e98b79fdec024156d8f07ec48a80d2f4854d6924006a3a93ce7075631edb7fb6e2e2419a5e5c6c1f1636541b74fc8324e2d466a34a89e31f283b3fa70e62329aeaddf9cfac7e4f389061d0fe7cfccd1424b4d410932992791e551dbde4f53182cec63f684254d6d9bba770aad6d38bf6c2569ae6856ef889b73620775e65871c6dd3cf8d61dfc63fd0fa3dceb59cf53468f3bc30b1b2d3774c72327d990c4e4292ef715140bda4ea4c106e243c5097463d4ffe8358c73c4fcecd915a5f089a4ca6a51588695d37c229179030e1ab06136aa65a7eb2d89a406b2d7a7cca3f950d10aee4385191a34af5249c16b05539485d9bfce71a8137d5dc56eb1ef2690b0f20e871d689297b03443f3b4af4e2c359a11cba809c8303842e1fea2becfd782153ac36afa6df0011fd274743762c33919229d241a0241969ea718107607b688c61d6fcd341a070296e13cacfbf764080e0c23baeb19af881b3e68dcca432fb4040a2c1786547b04ae70d80827c017a627d08fed2e9be25c0c9086f8356799900f9f8ac0a6bb1ed9a329422c0fe29700fa0467f62bc67c6292703f77125a545c7c423e500b2b3ab99aff38e95060af17e24b4b73b1a48a2cd4fe8e610b808f4e6836ba181171aa8386341fb8e7af6e336ef39a71c8fc39d0ab303b906a7a972c74e0d86d0601fa0d2da81040286682407815ea8c44b53e31837ecc277f4089c3c7f1cd605ed5faabf66e26441588716842f0d3efbee1b444658318f532286585501c281dfdd65177f65cac4d947673958c8b4e76a5cd930576f58ecd8904ef11f3b35db81bdce32a9e0b972d826b54343875ecf328d8300e000440f7aae4c5ee5202eccf81e2ed18f86fa7838a29028362320645ba512538a633c8eaf78b62cc7bd083142ab0c840efa06a1c3bee66c858625465b12178b4cf90932ca9c8b34f59423ce5a5774212a72ece304a7152d6e107daf2fd1d0e95f1592bdcb60c7cbf4d41b961f8952c60ac60b57165b201ce6f20b54c4f0709b69159b6f61a8a2835b40717564f53103d10c8581db14fe4503c25d17dde3475d5d224aaaf9cc3c04ffe94eadd285a7a96d108e2c4f434840b828374034426005be3611487fe6e2400bba9784816fab707008521c664c1d206242406ebe8057b15212377ba91a4ad516ae10f6408e090e516b44a5e5438438de2ad20611d10b4d78d625114c3c74d5bbfeb0588f35aab8445741706f2390c50b33c294d777dab85c9764c08cd8c0a32203c0a839d9406d10276fc1c70dee4ecb5cc1649dd441322b7f3a363fbf35531a772a80d5278c373f63fe44614d65e0f5ea103b85b0ec75d2e3726ee401a6ac41b107bb13948254c2af741e440f575aa769810aec0388ec6f658ac811ffc23d8e1b5869f784e102f2650883afc16cda2e9446bcd9422c71727c6c463eee59abfc71273516949f84239cf0188cec2591ff57130b14eb7e9e1d8b994846453afba7b08e911b7b706ca2cd33fd5adc02c3108e73f4d1607be856b269bccbe05d0f59747d8fca0ff2bed3d909cb3337d6c3bf99faf40840471b72490098e055aca8419c47962db3bdde8caa1af6c45d30f68e97eb65f7a689c5bb4f7c31404daea8f398ff5f05368914d8e9ceb7255e8a719b56c3a9302ef3504303f2c2366495cb413cc10573ef240ba9087cbb1dddcac108f618e989caac21a7c1d1db0633907e8f46206c7347be8704459a1d711aa186eebfc130a43a4a83fed4d65610b16978390dabe4c4bc21efe8e97ca25922315df235434ad69a05cd083b9e6b64c2bb3cea76918a6653ab9ce636d9999c6ce57bc093504f87915686d602c82c840f1ac7a609f5bb55643e8ad962131d34722a79a0682eeafdc4fde944cb963db7a216083843ac07e06887d616af04ec40ee6c2862de2b9a7c88871f1bf90d1b71684a65a44215fcfd18f4829cf89debdbb4112aeea20c8f28f2a59c48bf254429463612de68c17a923be83fbb3655d01884e5830931140d64cb5bee5ae5e46e34f515059d93c6ffc9203b21040cf10338f70aa791071b7732004a546546f563d869c07ea440595e4871d3cc57732a7e176ca1dcc3840d0ce7908560af45a3055629d846a920d10617988fa73fd9f6189fa4fbc8a6dffec6a2a0eb7b6a292cc3203295bdaded5acdef0a52fa23be01e8c7f472840d33b0c0fca18d0b35fc0ae358c93cedf9cb46ee588b9463ce02361f7af45dd618fd0b6ad76e94b52dac9518b667071194b48a6bd0e9fb21dab21916287adf1716c3e94c597c5c122a997e89edcc36e02a59f4672c67464957712f9ec54de28b70f30f2e02b0a301a46e386793cfa26b0f3401af5a32e63685a482b7e2de12b7374474259b71b61aebcde624e1de63f7b8a15c4aa8f5001bc07506a4b37766952adabac29356292a97aa391ea91ba01fbf459e3352b016e05a2d3142e7d8f123a171a380b1042ff0b24c4dd57dbdc8e3ce4a47578c958df0ec48cba9c9dccb1a0de3b9c071412b821c8390e83b54d7590195941136c2988b9a0a88104a89fc38cc72bb9830a92a7ea59e4ba2b4b6993811349c122db462a1b0444055424592c6c472829cea78576a1b513b0da87d709633cfafe80d4927f785e9564207257624f72effc7791542c62070ac86a51b6e1b57ab465cd4861b09570a0b3469d679a8cd4827ab8daa56cfe85ddb38f26642b1cf19b67c5abe5710f5d0eb1e5f40444970a613426e50d8650a0682f51b18d219ec80a74484e2081980909e62bfb4abf161362e117124ed2f6da528169a5df71da82fa466772e03158f06515deada686418761a29eb087499cdf494ecaa432ae884e9e4a167f6a756b173f05a53dd3b6db5f2d2736846a942a60640a9dc12b90fc5aaa891623f979687f91318c0b1e06ced011b44ffff59495e5c8670685209c81c72cb28241405a14840c9863ebce2a2f705c0550bf595ce720b2967e02b63a3dbb0472c14a8de69d71b67c1041e008c969d3189a146088116deda97324c1bf440a7d4648f2c5833ff5960d837caa8cb6cfd40de55d6d11eff4d60a5e2a2e62d00066215a9885e45501e569a89d04b66003134503e558de5847de67df9bb663e4ae5767498fc50262aaa25d4fa0a33ef3253280fba9f2dd704027b41d334de2804e27dbd9041bb73ce3adcc60f8cf2af323efc28d9bf8f5af1695f775bce63d5e79f53a6e9ffa23c9c4af0387645f5cdc96b6ac39e00a2369fda461d3003277808de7c85b1e752db38b0800a45b8baacf6e7fea1b5a6c73d5d03e809523321b4035b86e7293310202f63bdfe6b7e59a8b016a33afbe0a953d1694b139ce3e4a03b61cb46fac139b3018969f9a0637e2559ff19ee9879fe0ea8a83316d03e138ac49d0fe5565e6742b2785ab5e82d15a69224e80eab956f91e0ae071aea411317aaaeda136cbdc3de99062cc21c850061157c9b80d27cf6a5c079d2be2641053ae5c1e9a3cfd5d3d8c7f6e6785afee53a315449682e236aeaead958683f5d3ce561c9234144b6d9ff94873dadb7b9b33671b25662f4a758160be906599b040331bcc03fc543b98e55d1698d633ee3490828ed07b3c3275126b67d50d0a914ca9c8aafa5f0494474301d48e4c047d80191c831dfd6504e4d2202a8051c3ce3f04924ddc520b6ceb502ea0ab5b70b83fbc427e1f039359f7aaaa371b6a06be1d70b7ab428834f6c97001633dc0569313a673931e0a73c19a2df68226e93c60f4b7e87f82474a085d29a8c6d375833f51ab397b0eecab5e42198603a74463abce4bd3f66ba5ca62a609e0528ce268da47bef58c889e5e058e79a632b2bc0b06025a33845fca356e3a60e37ab3566aadbc54557792fe7e4f52879d8d40e42a3c51c0653330d169335c3a512f18832fb0a267aa165af2f256176a8c40738ad5e9c85988dbcb93fb209f7180a4950cf6fd43ea86f1634251e651b2383ed08452c588595dd9030d8f400cefeb5e98f882558b0a126f28ae5a173422efc3dbf835fded1c075ba34ac4cae9fe04f44a8c2ce10be682af01e589d41923f6565b4f57a3b445fa8b8d00c7542236b9e1f5e2453599c52aa6feaca455693d277e800cfe1056afc7a8b38f73c056addbafee739dcb9bd5b5563f40346bcba25267268e1513b1195c59e6a23c26efa484ad9553e6c5681dc24e270d6eac43abb164ef3317b2e008c1af092e1fd4f68364bb0aea98049b23295c184531f6eee460610bb5c2ea5e3228a01712b5755e729162eade60c7b53b9c88810c1de994458314484171389cc6a553a1603d4207ee523e37dea82951d8f0334e4972dbe91fe681a26331e367aa1a7bee1d662d193e3f5b43ed7ef3ac30b96cb0e7d4770e23ce36d9007605c37cab26ee06d326dcb98e4d0cdfade562da465ef73c5bc53998c214afa0835153a7c59b8ec5e428d710a08ddbafbbefe0de4a4deb4aae135ce2a90ba2e78356fb9bba3306bd297dcfaad8b2f306f3f30542db412c7816732dda8221c2c629b2888eb18f4f808399aa8f504fd5d4a2573006c0ce940102b519f8d3344538d2f5ff83dfe0a7e6c802052159e5066d27d6585db180142f9bf009c829af3664fd21625b8c3725b17c76003b7c60543131c4eaeee23945cf57f4ab50a522de6aed58598f6f52b226b668520482b099ad6c258cf9977603ab347106058f85533659a25d1b65a219a7f954d5e17d1b5aeed1621e0ae90f22dd00de20d36d88340666497378921e4ee85c0e8248d29042f0e162bbd70339ab98f3bd7d86e83e50824dca1274470ac0e1d1a1c6c03bc82587fe5c9030d7c5b102431a26ccdac44f532650df06e4c688a2c5b159204571a888022aab61c11971b6944778843390d1ce9e201457b7922173703e50977e8263766cd5c845b12d114fb372f409bd8232932f8a3a3582a0a1a3859fa4fe6ad2507cb032cdc171d8826a2c88ac96dfc90d594e80ecb21b91ce3fbd67f4374870b8bd01386574c6d3cc248740730acb610152699db567870ea583d1411a06b7a38a6377a4e3a2d422f032e6e285d0ebd9618cad77a651a0c08d758b83815e3253c8a35ef92af9a398263cc3484b4053a264d763339089079cbae004166308bb6e5e18184e6fc804d9c52aa61e1dfd13ad007971daa9392ddc0244296df26c95f592253e98b48701ca7615a24882005d70aac43ab7ee1c876605300c86038b89beb41d015409f1d505b1fefbc961de20d4aa10af79489334ca1993546cb974d799857ed29293e40fd1b5e52357f0cbb6c18701f609465dfb326b91b087db8844424959beb77e7e9aeaaea13d11696fa7f5d90d2e28516097d38fda7efbc7c102457c4e63f920d2dad72a43902f1a77db19de519b79556b659ffae2905a78786a6aa4bab12e2f05f479883139df3632906eed13ee4489b59efde2b22e045f85a7d5d6ca402165571cd8562d1a1e4a032de4336b36041ddb904349ade6ff6e22e225055f013b2ab4830f89a69a10fd4229629dfdab904118172bc1bdb4bf5180b1aed5fb8e3065cc0a03d9b90e92196814430d91d49ce69914b0738f71f197d837b79449f294eb956aa80fec361324e97c8f5eeb134be6a3098f14644b1a1e099b9425e434cbad9f32474d79818d79f60af2c6425fdd122fcc9a41c380658ec70b0bbceffdd929c65f9e7441fae6e3a97e05053b461de7ece4c3be6a9d6530a1fa5ccc255285448b2bd21216869c4d19e6d85f3d0c0ba002bac4951b7f6cdfa85a4fecd0a5a7b9443c8906bd49051a9146c793991b590e787b2cea0bfcc2765b54441bfb2c472bb54de9ad639f8673af6f7587edd61e8dbfc78b492048d519ad1505643c4a8a3c1ada33803314414951c0889683f54c32bc2cd46cc0c66f5cfb9acf7db538edce0824488cb5cc3d8d028d1c47fe74505b961d490fb0e0d839c0a56c88af11642fee90bae6d251fc180540512f195ef38fb21e3150fee4a328c485ed685fd4bd5a98201c0a84366e3aa3c3300341c831519c97dd776b80c74f2fe080aaacd5800fd5652fafe087db525dd8bceb8515bfbdc715b67ab1596706ee433a41e373779df1f71121c8aa54288161c02c78ce47d27f966d93f8f6b1ed8b85511630eb3bfa1394f26dfb16a48a6cf06f3a007bf3f024185bdbd26bf02962f635789a20cbf5b41b2525552d87db5df2adb94bbd6195e01e9e36e387c069621b666610c2dcbe34b74dd8888309529db775a04b9e7054d4bac5be4687b3719950afc01ca3f826a9da55fae7ccdfc235c82da6bfbea1f2119fb5a6ff9ef970f715d5981dc3f823e317c80a7e53a73a00713be22c7ef16634c1216fc03652b1ac4796402ed0b1dfe7c610211939afc47d00f807d73b4bff61f71ff4a04cee9a757caa201a982ca58646eb18e5eff2328826251042033fdeaa346882456480add2d6422746a3d503cc49aef21ca046f6134261020ccd5ff8472dce8116b0559336d94102a07b8a42bb6d5aeaa93d3123801eaf9072f6791ec03529eb828f7906105ee0720f195947be9670076b1709adcf3b50248b8dc0c1311bdce46c1a734d6a7877028dbcaa1062050bd01b4866729379e418eb007657464ad210662a6906f29d1cdf7f59b2b1accb3f31f8941831e1a02243c16167082607b3925124fc8416b70b5b786c1f774798e663c1320d1db89d4d57c40c79a45e29cebd2289cb0000974ff8286ba5a01e607b3286338cf084751894e3e0a3561e7d70042847820446192b805d4d8ee42e4ccb3293114ba57e0f7172e191a6e0d38e2474df9483a0268dca946c9138c6683b1f28b3e3eb3b9d9d1c4d0ea5a3851a5d6ec73c38fe4fa800324d07738a29a693ea854b9429b60881bcd75217a8aba472ed543f0f468499cf19c7b5dca51be045fbe877a75c1e01e6e51be919800785a04f7dd7e80845c98f77355f383f0d637a4be9d51ef1e54d967e6b6e06e1228ac0601895ea45e5c303e92cfa536376c22f3346a8189d6569114ff5569dd3f131e05320212b17ea28d18ae2814b1b1fb561e669b90d56b45ab9b563d0893b114f06a137fe3760fa100c714fecfee59f9408361d7ea228b69021218604256a6f7c52d52b31da7782538f92c0d6d7bbe38018911dd6ee55b041b8bae4e8c58f34e4afd8674d80b69b6790ae6018d2820814523795ab69002a531715d669747707a3972a1983a51f26923e5f7da23eff67e81e89c3f51d42fada83ceb4b8e227a03913bc1d095a653b1e35fd4a2e69e22746177d6fe0662d6a14c8560bf225c40edb62a975145c193e17ed0b65b0e09bf0737d53f576398810beba45b3d85a57bab4675852da670ba67c81e2aca042a20b1006a7d582199b688e51b15a2033e1106a0070c629add89b9232099851147d01d6d8bd72063293eb52135f6c8f7207372985bd1a4429fa9788550edfdf67b0dec6faddc2eeb192b293882395f8e5f4589212958cfd2ef57e4d04c2f5ec01e206d1706bfee7cffb6f1cece5b4c8362996eea9a61fac22c14c7749047a126715236f71f04b6f0d7503a16be11656e35c8bdf6037744b80ba6c6ade7e3f7cf7aa70328e1927e4d95d28a7d66c83e0bfca75ad797990d7d7142d9d41d1dc4aa78ad35b58d5c6771de66a4482c48fccf2218e137aa6714d8afd01966c8c287463b8dedf46a8499192c6bb1c2d080baca4e4f5f74060f2bacc4bd95ec6fac4f85f9956eaacfb6de2d72d3bd1233dd09f996730336252a82635b12913fd811cab30e518af76e73f75f0d93002d2c4031bd5d7901e194675560bb41331210635a2d7c15b764509f0695c8dc9dceedf5e567d947702121438a6e1d3ff1511f24f858a0f05a086b83b777c1badbdc8f26322e9ae70a0fc1cbe21ac22693e5c204f11926b9f247a4e849803ecf2fa80f962fb31d858fcc8f05888ae0a88d77380e6e34f21168498451f46ae2f3b262bbc1a2ce2bd5ec622e6cf8ffc5dcef85d84836a83220f42ebe72607549a6e8076fc0657915f1d00600e06a0904d8a222d8c2a313845fe70d35154f0bad78c4711015288005f35310731612cefc7dab0bc0e8d0abb7be471e81d0107287ce4fb8217d3631dd6c82881af0b2fa311cac7aa085867cd61e04f341390c9f6cea66172ccdb89b74bb3217e6c883c9b155899e1d06180d763d3167e82cc28786266b2ee4f53826ca6de7fba538838abba85b90c343cbd04bc342e9d20899ebd8b56863f3d6b4cc2d1500558bea55e86e96759120b1c426ae8a26d07548e521ad06a993ba148d5921b2b00c4548c0584e8a55348151607e8e1b545d812e884277ac3599aec0d2ff9c40ea40c5300b1a4c380cc0fd1feb4f2fc07f8bc8b9422824d62a9a581e78703ba071236b641204d2e1d65f8142fbaefa356058d751bb1a0cd1756a57c1a1fd0eedd553047e05b4fc03ca3883a35d305032a2745524daafd93ea91c4c64bf368609594d6b9cdeddc6d1bf0e182f4f38f7ff6edf6727e30c85d615704042cf304ed0022ac140090052367b5adfc701984aad54cc80db787c17427ba16afbb7fa862ebf25a4b58490bdb7dc3b0d0bcc09c1094773e6ca724cb5a04819ca23cd2c8f2644f1c9630a79bea036ef289b0669238d768834e93f90d1980049a147424a826a363a8dc8144fdcb422a94301ade3fd9488e27862abba5d52878465a035379385793473f4496f323e32a48ed9d164a16933479f64c9f03c7a6444d7ba5b458fe811c5913cf8914666954992a34a8f6a924aab3edc9c0db238ceeea0851f4c865cad6a5be951c3fa7514430f4aad489b16caa3cbc33d9b54f23ca55b60f4a85dd475e372d59a4905df3c92588a1a66a45f72e696559c00e8c6247727c94d6b9f4a6792dc5f83971f4b144f1664265d7ed6a66d0e4d226fb230e5ec42daf4c752965278597e7621758824ec91215aeedebd9bda0a4d3feeb264b0bf2c7aeedfbb213fba7bb84893fa0ebbf0901fdc3f0e53152e3275be59e5a4a6250e681d8be9bc32472ff73cca4762abeea4d2af79da9d950f94360da0193dda1c82cd24b239ab3d22cfcb6c7574294f01b23e582288a3bd7df993e28e99e579d82ce50ba52c713391365888dd5f9eba0c335257d2973b03b1dfdd4e4abb6819a47314e542e2680f41acf696323d5df1863ec4cce14e4a3745dacc772e9039ba5a18a2d522560c83d4f1836c9f21f2ac46e4a9025a2ee56f863e9eb9d32ba54dcb9a56a900f59349b92f71bd56c8c6200b99c3da6c18a21862273f76b5c924cbc46088f27da3091e6579170ac6acca4f0da8a826c5a8c8090d73873b5e14d603814c167a0999637e1e0213a749206be6144751c82cd3892eb2c472cda3bd55a97930565f6609c62d5724b55f2d026b85a4bcd50ec1d0ae10cc326c5a7dbf74219bb5593bd42f8b3d4f94f3266bbadb217bab151a9aa4770ff56989f87adb5d69d72ce152e99e5742e156d7f4bf8fd6f675b333eaae7c5fb8e3799f88c5aeabaf77b45e67d4ddda356d77cb93b3d6a685b8a4764d9f147ea0d7cae75eba7dfd402014c7e52f72c178ec4ec466d05eee34b4788a5ce638fbbe35c9b0bbe10e89d4e14e7bd783b5abc78b599b15b24329b0d9212b54e7bd24f5f356a871aaceacb7ce68ceb0c394a85db228cb1b6ea87dee4aec3db0692d4e3e7533fa2132a24d0bdaeb92bf18ca3577b6a26e4856f1854fb660d7d799415207ad7551bf3acfee57dbc421a22ab7b7511ff596986c9625c5b999075203062470185924b7e4d9f496e5e95177e7af821df268dcb07675d8a374ee93de267792a5f9fc58a0122877aa94af06d5a19d4aa502e5f905509dfa03f66d3a69cceb9936cb2aaea882d6b4fea1520797e79b49bf86288ea5358d8e1666ab7dfbc9b0cceaa3cea333598ddff88778142e22ba1cf52227cc6af13c3af3aa7e2915e267d36ee80a44f1a88f5dad3a21d6b0c84f1e9bd6f8c7e9285c84da2811ad695a4fbb66cc831df160f331dbb4b3396733c93c327d2693299bb1cb92ef4cf327af03440588781ed11a1bad99b0a11811adb90e107fba0c152062992da235333481f6e2e0e5c64de4f9af01f0735463d5489575923c6b5dad93d2af36223739329b4993a33cbb9b17b3305bcbb07ec92a9a14e579afa75f14969170378ad349018df29cb7e14e576bd76c9aad40f587d65c5b6b972caab1795482a1a21a645185499b2f38d05adb36b519c506248b9a0a6c4ae967085b09a674cbf959e65060dfeed954a4cdbce5bed2aed9365a333fbb9a04da35655157a33840ecacb3abd50984ce966d112402913ac09ae78550201b280e9dd19af9211f1bad36a3a97c7e668c12b5ab666d96666d14a74342d6cc97c06b926727854d8a3cda2f8f3546714e9fafb2c9427f7e2ce5b1c6f2a4411ebf3c36edd63e33c7bcbc796c9a025ae7849be685388a72e652d3288eb40d4d27fd92b55f128a088a6633c9b367db1a9b977dc7dad9e86faf297f9e1743b9667b1382a9c28b5ac6691d1e351b202809cd34ece19dbbb5f58b03b154c93537cde643e5a781888c5a49d7faf57dde62716271ac4ed326cc8499075df2c7c9d92c1ea473df413a87796680fde81749867e75dd1dd83f08e8d7774528d739e73958bfc6b6016192e725d048f2bc35aab3883cda2d795e8e5c4f9eefa474b6aef6f92fe451ed45e50f04ed3de519b6120a85d83ef330b1b62dcb5e42d6cc9bc00805797eb447794e419336d35e69d7b446b6c6c40ecbb2fcacb8274bf9d92ea981fc4dd9a6b14896f768a6ee81e408327a38a2daa2cf85d46c0c2b2320b5508b18430acd0a530920182309264a35556684256c9d4274097144039f252e33aa11279ab055092f95a2401c1951c207317cb0a403625891440c1614c1440612431ee06c15bfd60d122fa0953439bb44eec44fecba0e4b93dc25a1d3751e4c9650b0c0f2281e064d0408aa130e20f113940511454d84144e7af8a9a2082f4a300410e020d60de143f5461792a31560d18313dc7640e5892774e810487080050b8e0752c9288bf7a496bccaf3440b6e3c3c0143062068191852a0a89c5117de11105f0ca18685ca1417f4078cc8b8a2f660065d7c3ed81bd45aabad2a207ae39010c2a4eaaa95171f44554ac441e78318d65acb5930cb284db4100201260882088287072070d1c31632aa204111dde3c2fc6f6e9c30626467091b78400444a0220650d8ce05267a6ab5b55e0941119d272b9705104ebc78f1801327504044c1859120ce490e44217c78196205274124272e8845a1a514c511621f11df2c553b4b1cc601104d7ea004053df140143da8288a38e26685146e58302f4050040c7cac080171c508413450040589494c285014d13f3cd183d3135944d083420a78e8b196b3368815712507ed030abec8b5d66a6b2d7137362c2c70832a5d54218a828823ba872f9c885f487901942f6630b0d6674bb6d6484c14319ec4e0085b3441848ef5214261b9d202177c7e543ff01451a312b3628a0f54c1831e9f1e545e38b1c467072d7c4226466004645263a27938aa4e7aba258abc1ffc408a794c88680e3407789a78810e8c9084063608c3a777c80cb8a12552edaae56a1229b02741a8b6e873216544193030da82d442457284222fac30959022c20858c2984274c9fa81a321a4c414e5ee7151b678008bada7198b52841068b135e8c9ec210a194c841044f36519858c25f2f81bd108b08a011b6a0032830c220c7794b57c9365ce6925682b8cd2364a2225729447f3debc38fff99bf99c7919e681ccdb306139a72b13c9c5123648d82061bb7ae5074374b5d6cac3952052697a1cd771dc950e648e23795d0e196284e193c4134490a061577cc81c278421d02b3cd971601c815484a5120618415030e1811f78d0a9656449528292c58722c020c2957a846c8364969f2a3d089a4640010a4410d472c1852d995e750343511326345fc0645dc48e4870032b45904cf01cc183144f64528ec8c009192fe082013437f59b254b92420aa9962ac90ba950f124e88929e8c91846382bfee0124f92a204520421c50e9f183060800f16895aabadedf5100221aed61e820c2350516ea09021c415f3688ca36e8c327cf0e1d6637421c4185bd82cc468b5385bad074bc50e3bb0a1c09602714a21b5e0e207302782b0821db410c1c684a545b1028bdc6519458c143461f2a4888ba02753348122a889cf134a9b18d18403f9254b284cbee87e18c210848809f1a086a40742ad961322d759bb85ac721dd77128c07a00e20ba12c342874ac1621ac918fb5d676e0872c311fc448a40f4b0f32bd7401ccc3010a5554b2ad763d7161d2909059a6a03d09638b13423cc91214f46482c10489a01f3c31ca9d133b38a24e284d50c1801a8401c50fa618810e70f085171309d5344094249258a2e403547af00209ea89a007963a2ca820d5e4a1a2680451f8f8d0811b10169a45941328f93a6b8308e2aceda17517a5374dcaa841f34a9325b936718284ea6619a5090fb99465142663d0200841082653175da8542d57e739dfba4f448f53755d775dcd2a1382029e28a668ee5cbd2854b1592304279420690db6b4be61551582dc63cbaa1c8a81d5837ab8e5b5ab554d5ff3ac7374e54931ab731dea57d8c366faafc576e5c08b626639e7169fbc374acd287b9746b9f3485dd775e1fc27270a6c1777fb156878f701481c8fd674ef2ea58422ad18a516b2a833a15d5de76a57e7ea2e69e7ed78f6fecd7bde499ee791bcce8a9442a32285e62408d9f49e985e1446c45062e2addc9f3c8832ca0a92e451d5ead74823c53fd152674031811109c5e74a963e44591249283eb43ca690e5555942f1e9411e0d91472e996fce1b15d30851d66e421ebd559940882f59d66e46795eb64bfcf9a1ff6e14878646b70851a09aa447aae527cb0fb22c373781fa35d29fdcfdc35d515911ab50e926ec84801672734df3380f44407b54acb84c903a4cb7a1bd56214b176c240ee5bc5b477fa6a44b72775df823a7290aa45001ea7dfa235b985d07ce39e79cb33bcd1d1e8be0eedc7bc84665b6a076f5856cede2de75a7b6eed2a1ee41ba7314a85d8ddbf33a2aebf068325d3a446d5488daa88d0ad1a18eb3513ad41ea6f466e3a206368ea338730bbdd12bfd3add7b8f095c4aec149e5bbaa6df1e1ebba78bda481f517178ec244526e4711ef1208f3c79eedce0e125a84f3ca9a03069cea3a39faee91e1a551e55c11a87de4ca81f3ddb0db5d11a4f4523b6720369a18fa64f8f13cf218a338fba844749a5b979d42fd933d31b55a9b8a662a338f4f6f2b8a3508b0cf5479525866f9ee08914a6a822842ee4c51b88516e324a14222859927c0151a658b9f2032db02c61c50f16244e8220b9c16ab72446438cde4d9665ed06cbf26018620428f0d1258ed02ca13401d4022579f49a4841cb90e0a0420901adcb120a92230f288f60162f8aed92d654a0ca950e4499e24acdf358b6eb0150a4d0a86422f1a6288f2618e5310529f4499ad1d272fd27c2b2fcd794d52dc780d1a22b473db54a8db250c923dd5261b9d62acbf56de9ac5fb591c8b5d2ce1c0e5eb64410e910ed41ae45740732470debedcc266902c4ae852440cca3817421e6da42b6105b810ec916425c1b8bd65a6b6d114cabd8db2c62bb2811f58432bded761115d5a14c3f7f68eddab56f9d5ac89a7a1b14ed600621d73a246deaeb04722252a2228a3365322b2d35b17a703ee6c70c648b59dc65b6b44abbea658542a445edaaafa2876f007f03112f7fbf8188984b27a2caa4d319c5b1c1a3b3fa510a5525b97e74651878691569830369535fba3407d24607d2a6de068a537bbaa6d6572979a4a3ea48aeef6a3592eb397ca4229251a23c59f0609488138228d71b5a2357f06aa20c73c893ad486b3c9548ab034c0fbf80109fd6d4f3e426444b137bf83e69c790f2a2be19346afc6b2b855a9badd91ab5e33d2bc87debf6f4368ffa65a257a8162bd9fea39c11e228877090980fd1217b8ff52be6f613367b9a49eece71add6fb5f07dedbe2deadd6ef0c7b746fbdf5f02395bab7f0d7610c2d3cd676d95f6c81424931c661e6b0c729b34e431fdd63f09099bd717a1de7e12136bc0f94d27eac8183ca2d6facd36bb653d2b4e4fa5ea227d7f74dddb113fcab24c33cd538452ecb751dca8575cbba65ddb24016c802590767d85cdf9967d8a510013cb97bee1e7aac5bb98b7714bbab3e43bf48588a124099860a943dff6a8033662f612210ed6bb666a5340e09b7b744b6c874fa2ad95e8ed64ab6f654b2fd548d472160660d39650e9f721887991b8fa4f783904e64e6704710d53b3c44876ce38d3923b8db99f08605b23fffcce58e688d3d77b9927ddbdfb8b6466bec3f126e0e33a7f9d7853ca694dc1d7f863ef0bb7b57662ee4718f2f435ad42e9b3be4913acc3f1850420982963b1c5146714150ee9efac702b9db02b997282e10ca7d987f3220f7d23da627c7dc8bb967baf1b166efc6ed69327a6705f11ef3cf863d66124772f798cf3086ee31e778788f6979d77bcc95ed92e10b9d65bb5a786c650f8fddf9de2533c777090d8e5d67e633b7a743a95b985bd5edeaf67bdf11c4de773cc7bc6beeab62302be61883edb2f7de528531d8b396fb7d4ee7d0bedc95d9d68488ac18d92db1233426405286aadc382ddfeaca3c73bb8775d22efbc663ca02b5cbde99676e4f93b640aab007ce30ff6a8033dc1167e2687f5a32cfe9d585390b26ecd1c13ca70f83c7631c66b6913aeb1dfae89eba0c775478c8ccdc0c90f3664e5d993b738d19927bc7297378c829f75b33b7b8c770312c99d695329e0d4e869bb9e59de36258dd1ff6e8ee715e8b15ee74acdb8e7551af7157a771559f7161fe725377b9940a51bb6ccda5b04314a6435c0844ea853ec21ef57d294b1cc9f5f58dc3cce273a878653e857704c17b4377c756e98ea0bd0c3f7260b0f325a3b4608bea9eb5aadcc18e7c1308d1c727cb2fa992e5e509df276f95b5abd65a6badb64a5967ed9a9cada7f54a29af44910f8ae0c437a58e591b47d62a75d831c4fe37bb27a5d5d23cf158244b69d3b8b6ab5ed623d16b57bda4a95aa8605294c10cbede966bbef79b73c6f719efa22abb844722f6640a7b94720dc31da69f3c99a7ccf375d62feff30b77bc370d7549716c7ce6dff7efab78aca53b8a99a7880e55f6959e434be00de2721d729530b5ce3a617090940ff048260bdf6790d45d2a8d8378ecec721a78ec9c7a9d553cff7d1f6b9db5d6fae120a9bbfc939f05bf52292c5525df0d52af439ea5144f78b07470ac49f2187ef525b073eadff15867393c91cef37beadf97c25f89fb2eb98f5df47ddff7fa717a2b96cb7c29f59afafc9af6d292398ea17ee29147fdf4513fbf975e8f4c16e64b2091cef3df29dc017ee220f32e3781df9b2676a87a1a5f2d85e18efa20257c30f401e6fa1eea4fa352053f1a32b2557af96cd9e5a6660d719de161ee8ce7501368aab8cada153ea7678de2cc1aadaf64cebae76ca85e2ad1d0b051a271d5a78d97fe51309ca649a4d6dcfa3827119b5b3848e9333eff325d52e037e32fa510e687d6b44b4abebe1854a5db98345ec22cd5349ac1a32b633cbaf2388d2e1e2f8347d55bb806099875f1b887e8aad6fc72191bd87b421c89d8fcd2853b4a0ff2825be7421f602ebd875ede35cfcbe0b18b72f818fcf27e45325928e1d1023c79be35e3e5ac151ec5173c86af21b3e1ce8ca9a2418258fa8cb0bdea55cf33ddf368aff7eedd03fbf5ddfb9c6519866f5a2b699f66d2ae1bdd0f8347ef06965d33b1e9a36091fc952e45d92e0ce46f24720099bf3a2b3dbc8bcb69b8e302e6a02483e7c97714c13bcecff8d76069c77cea393d038f5d25872f5d9ed42562f30bae48668ef03934bcde5deee95f83e19519e6759fe9d4481cbd6e95f440d39d192c81a526a57a1b9a9a9476ccd24d9f73c2284ea8021236883ffcc27710bc52dad8d0d7d267e35a13e92866bb02def11964cee9d7fcab7ebe2a56c9d9728a44f05179f4edcd348e20a0db3ede13737a4fcc69c1b8f33439a11a97472f4a15b7163a28b9f158244bbb7a4eaffe4d30b5c2b31673e790c4938a4ac6e6a337859010e94d18a2d21c166277ed1af9692373e932e5f13f6e8a987a7f046f07ca9a69b803000fc0533748e3496528757985d0e4d4737ad6c439347b9c390033d99199f784349952a9946c10df69348f72e4c071c59ca324e7917c8a4608cd97ba13df696485289ffa388d240e92fad422e58d1b2fe1c68d00c86c23734db82308801b6402f2977874b90c283fce7ce3f2d6bf84df1889ec94400a7d74659451c618596221a08d1b57e6126ecdf8d63c8d8e64b9e6ce1eee0a31a78e9fa21748f62bc5994bb1953a095b32098701fae931738d8b548844681e2dc093611ef318d45fce7205a97d53a740b04cbf328aa282a29e1d999d24cfd3ede91d69e87ac8376685ef83acf0a65bb15619621eb25d201e691869c87d7af034579ede3cc29bde575e863cecab945252cc02b18f109be84f77048f6f4304a06eba0d619819758abd27667eaaf77419266066d42bea140741dd8483ac4e85d0648a85d064145e1ddf75c79a59a7618f148f15aeed8ac16f9de2f105d776b1e45b9f610c128b3017614429565194a734c3e03187cf03c5db3906796a43ae786c9d087d21f5b1d6c0234f16718db75ee3e2ad81c799c54b98b77829b6c4b7dec7214e11c745ee0a716c221cf389593c52974f5de2b1946180ae6413b28c02540b0273125227e1392d614ec273ea244451c15026e130ffe447c14c43e3f1a65696addc3f9db0e9e155bd4cafd3511285c39fae98fbe6e1b87abde93777641dbf5e9aafc0d44920018f30f57584a9f25a79cbfa0d2adb15738969da1503f3d447160c2681842bf30d9a30dc69c97067064f51084dc681863c66e4d4f1f554ff3f79392b441a97ff5fdb7570c6fa65e3f3f255daf8ffd9b8f377c26c7c9cb09ee7f4c537ec1ccf1d1b78c66464aecc324c7de0adffa4c8fa476b3c3ccc955f5d9883b73efc8a8e348bf6a7ef05131eeb89e0fec43b64663a339d59caae1fed4d371d34997e0241cfc361e2511eac724877ba0c79d0dce0a95e397dfad53e59684a7c5aef7027c6368a19d5329b9469eb16e57d78ed0a2f71ebb3f5985b69b8637accedd66dd9dc21de9a5a329b38b3e963cb8efc05b1d5baecf0857afabe632d92e573e8052fefe9354b6c59172f959265fa3776dfd11bbd2c594366ae58669edce0fbb24e8774a6d3eb054f251e42e5e9a18f8661c19c2e91ce30e1cc35527f81519c494bd1e88c832078794c6bc31e93fe9312854b107c7832dd51d6646d851b170ad77573f3b175c2c794008ec2c79afbaaa37005704fb8e095b986b743a4fce90e99596689593c4c77b9e92ecfaa3b45a9ba8d699c9334ced1a081593c5c0e7397c3c05c5e98cb3b12e90cf3191fcc1d278f98254f9677c6c11b64882ca38c32b664d3a57ccd5f83305766f97a87d06cc2d2e5050379b933b46b4ab15f4fdf146300db3045ac97f3dffbdf94f255d61980ccdbf0dd496fbd3eb21b8ff4a429f337c136356d0b9aa8e9d4321416b128f63431bd87eb88e04db8653deb23e041dcb33ed22f8a4de041d004e29c3ee1e03d89737310f7ac5db23e12e23e72c2cd9514534a71cfda256b99ec48fd2e6b17f6d84019659451c6a4bd402c7d9c34902bbdbb53c948a5bc3095b46bcad0325a336bf4dee47a9fe59d358a3303ad99f73c51944424d1538932928c24239172dacbdef572776596620d426800d2325ae302719444337c1e089544fa8581eeee96b465dec4329a4cca864d01830c3654228f2747cf9fa34fdecb5d2c869072fac879c51429a5f7c414d815534a29b5e44f4a514e9957ac645b9509c52624a7c82ea4bcf75e1b73ce59a13061cbdce9bf174ea778a429c2421650d47456dd0873d04bcdd8d2aed48479eaa37cd7346e07c15c1ee641e469e00e6ad7a4f1191f5140eda27114ee1a8dd3f808a46bfdfaf38b0baa468d778dd7787755353edf41fd52dd56e3b690eaf353dd67eece9cea1710abc7b3eacf2a4c647633ec612377ef20a051e2f19906a63098cafaa85df3a94b63eda23120b16dfdf9b6d1165b9fe2e78b0b46611073a0245d4471671920a7359f020764ae99619830caf3307494a3d159bfbc793a29aa8d685be1b458e917fd9cdc696c77f7afebbaaeebbaae566e89983926c4d19b3a74e6895f7d74c9da6af5152eb2c2acafcea313731e9db37ec8bcf5162e22835be7d1e1f0e8ca5c09c498dbb396c8b174585dd68fd55967e12239b6a862079dd57974404f725f91d5a9087692524a392bb71d79fa266a97c45d44db4aab30afb40aab2b75bc7b496fdd1e59a337da46fd6a25a40e9927e528a5dd287a74c6490f4baeeba4e79d5e996fdbbadb435da508e44cdca976ffbedb441c099aa8ab8824d24f2690f46f47f8aef33c7992c4404f8f74c70b64ae2392434be3b32b350ac94252df71c439b652200e9d7d9f744671aaac31bd3453d9e4e191fe64972997aecca45bf3f78197774c853d6ce4b148fe3e106821840c72a9822d29256109626f04e2d8e24a0e09652a4aeedc12a2772aaef0874b18cb4e5251a41c4713fbf5e03d6c42bbe4e9e7675683da2c085c25f27e28d00c4a43486245df67b405a9b3c2546954b6044989b6e48992adc15620c6a7e4ca14220e58a505c982a058e25263a8a584c7c9a8d1d85a819253c7751dad01ab33203aabb9208fad3c6735988e7293a85f1c3dbd2dd4ae99e2bab6f5103d771f1407e1700f097940bca1e6b6359d5c27ced621fa47e2ae05b8bbe34521c26456f728560421cb70074c2ee59955edb27154489d4744f23aa27e8dd456a589c42dc41632b2fa7cdb284e0301b56bcef93c7b07e01dc12cbffff8c0e8dd47c579ee546c61166e32d259098f9ee84d8f8ae20a735848a6e768d3e8ec08e24cd2ae7925b8577a85a4327df5e88c521acdacd106b8811565a5897d39a59b369e617c9266a42c98604d69edf0e1fd1e9a2e4352b800aae3427be80e2aaaca3f477ba8562d5bb268a99f43a3a752cdf84d8c76b302dd41bedad6b7bed22f7bf1857abf8ffab565a8a9f0e83416b2275b2b33d380b2b33c0542eaa878e2cf1cfd569ef92395403959e81dba4e0993a7443e5d93fd42a43069b3e5a8b5b4eb4abb6ea7db54da3574b1b07577dfda6544715f31e290104755ee223c3a33bc379161c6531f6f60b115e8ac61e30a3907981add21f73f2efc010323434fea334e6152c78cd1c8fd26eaa2beb5511f956acd62142b62f97469e4eed66cc317669e336610a552452f87f9025e0e83270fcb01340ef305d080c133eefcb91368d6680d9576b5bc01f9216dfaa40b430e10383659f8ccd13a2a5ad3e1fc84644984c03caaba65b024f208863c3af22ea963d6c8170fe9eacb8bf806e89747b101dad56f41e6b1055c7110aa2ca124995dd1301aeb57c569e9f46b2bb7faa55a0106d52cf7df58c06ec20a06a0312944233b228916648df58b1ae91718c640b309ecb0c765f1a0e7e8593d381d60017d29e9910fc522a9bc62722de09ec4ae804d993265ca942953a670338a103f27641925882d39479e244a394f7172445b73a4ecc65ebb68185182a0650925043f799cb1e59e19ca3d29b52c6b6f5049503efda2b98f72d22f19c5c81554509420aec841fce411c5649547d40f0ac8eb60e8d7e8dd32d847441adeef2ef9641843d77bca28a2cc9a511c149d2b27727f650299a38f8a519c1593aee971e56415e396a062fd9a98e5a162d9e63e4a2675d4ee3d883ae20d35c43a6244d57283a818ea27a380727f444d919b35430d91fb7212e0fb885ac1f711f56489e927b0335d349d75c40c0d8bd8b82aa2f56b9ca1ad8aa05c7194a45f30b947904730a362a8d8caa7ced0fae57d15bc26ae6205b40e183b65fd0879744c97f583ded4f3fdf48fd21b88a6f0feae7ac8fd190331fc77e2ae9727b80ac2eab612c2aa6855b42a5a15ad8a68872f986af6a89a6c28b6b2a94e1f3d31483e04387df4c2c8a9a7700ea98b332e5ec439889f41bf192a2025fe3beb8728febb28de2fa41c1462fd3843e398f044d54f3761cf01620ea68b2ca0ccf2c993d5a3fb7c674aa9897e5ed6cc747330fdfbe97e3654c06901a67fff11fef4f0273cf3c3fa6ec2333e32ccd03e5cc3e886b8860d17d03aa6cfd0264b01ad03fea358444a57451447eaac8ea40e99af885c1e59b00cde55d10ec4718696674a2071f06d8636a344eaf0ba8f3431799ca1e1a3dc1f678c216b261b956ad7c41ebe511c0f8bace9df667cc0b78c3117e2e8ddfa8545e2ccd0ae481df42aef26c33c7ab7aff47d247bba31950ef897dbd3834b077c4ca5137e4411cdd028cecb5b9ca1e517bc2aa235fd5acd74a70eea1ee57e875e358128338bde741e1d16c54550ff4ef18fd34d3f9d4727dc91a1a7e73b0af79c2e6212edbb321e9dd9f7d37f7ca7d3c5d3a77392c1bb99aed4e15020ae603b489b3ef8f0358e8c46ef86afccf8b40a9f77c3d8a855c0b7dc27f930699c1919adb9511cd68cd6cc909c789e28aa5437122d779f51f299666633b3d96c3633cdcc6664b97d7e8032abe67d333e33346f3543cb7dd36528c3c79a511cefc6b1661e9e1cbe79b7b942bb5ac0c1cbb375e8edcc9a59218814a362f987724f88f504d2eadd863b244a6589e3a4e56c8944b91388e3aac8d485b6dc0787727f55b42a5a157d1e2d8f1255344a1be75d11ebe7bf0ea362ed42c9504626467918658435cb7dd6ac5ff57d540cd5b39bdecd336a15fa5c139175930214a298c79b16e801a40e1c0e430d14e7bbcbd543e278dff7f292476993365217b799a3cf31f16e312744ae097144a1624d80ef7d94917ed1d3a36228d9875f44996786489da3890c0a961bc82953ba90540652cea33ccfd9f953a9542a3490f2884fd2f4bc9e744deb594a29a59452dab64e39d427a0a19136c453f7d54e864a6beddab448660974cdbcac81963ed6172859b06fdcfda3b7062012a0f9bb3d186815e6499748bb765a76777777071296a66dfb5d225d83832adb0fd101964ba7e10e09db30a5ab7e061aba6bcd33f46b8676d100a45f1d0d77baaeebcae2c19d9ea381e220a061a0382b70d14525c82ab290bd20cb2a846c99d4d1da3abda5d4167ea1734b8c1f2a845aa7da319854aeef59f632fd2d7bf93399c29da9e58414deb08e511c143e9fc29d47adc27cdf69a4457c61b91469f22385abf02228a8808bdc3c052cf168431efb5bddc681e329a8708a4722f714f628656a0a77d83cb59279f5f973ebd7eadddf4771cc2bfd89fe54fb27fa53cc0d72e33a642a3d4afb7b0fa139e6f5a7b7f71b391e83c7ce379e038f9d3d4af1e9e4d51c271cc4fb8dd38f63e31325f114d181d63187dcaf796ac941e875c85d71e091279f5e498fa98f9957f2e89d74ea483127fdfb78e3a7e371de32e9de7154194ca4330e7cfa7803c7717eba47715e3ff5e9e7e8611c396ee0c9037abd9f6e9cf4d3fbf4fa8a637afc4e3adde68e33db1c15eea86f1ca41f73b19e4ef5c3a7ef3bd5d34da7b06739e6def09a62fa99639c45389ee3ca1ce7a6f0d755e139d4e6ca4c496f4ab1f79148cc9b7a98c6dc73b93e7980e3a44bdaf85b7954d491f4d371bc291ee7c4f1d3fbf512c3a91f83e9bdd7981573d2fba4d3eb3d414f271dc70d1c57e1de1b4fc1eb934e0a77d00739e17ba10f30d34f1e4c16281e3d1c9f38de853b38fab66c269ecee3cb38ee511c14be7af9eaf367b5baebcebc7a9db779ebdae3e5f53b5ede31f4dec0e3749289d48c034f1ecc1cab7b3755a4c90f147e336496916ffc78deb8a435a2e7e4372860496b6248279eec5d0c77bc8a5930c85c7932bde34720b91f734731c7d4eb45213e9f2e8ecbb0e9e9f2e4be446cc6417acc1d7b28939e43bd0b9e74e54de18e6cb9d01b77dea4cdfccb9d33944a8f29d559eb5013e8f4d1d5b5a574adfd4ed24ee410803a8836cce7a79419246d64a8d39e4b6e6a3758d29a1666d59cf48bd2bc0b77f00cad75f6c31ab7b686bc55d60d1e7c4e370a02f8cd4ff8bc002e9056c10e41ec2bb30ce58c9e9ed37556eba843ce2d2f5891cc1cfd2aabac229939e4eb739a765fca3a6b97a4f9f5823be227c3599b352e0b146e4ff7ab8fcc528d77c8bc5a3dc55a5d66d72793f933695349d7d3fb9376c2d3a7674c5a85e9a45558c90c336935f0844b99cc9f09d4af5ea2bb673da11a85e7a95bd6dddd6ab55aadd9b2d66babd56af5c52b03022e0c2d43e1f33da3382c79a973c22ba825d396cd9bf7250a27c0a04e302b6237b88a7d79251e6fa878a294d6067f10935a36c30f16494ab954c50b003791a23ccd406b8c6c56cc20654a04310ea2ac228b9f5c802cab10fa217f336411c9638d0b016b9070690032736bb8426c20d2ae005c46c6e632dc9101739c6209de24392b6a6d571dbd8c471048bf24c61508110ddd97610c37ee67f16d58c75c5c5cbaf9752c4671c770c31ad63dfdeeaf3f799bcbd087cc6f3ca74f1d335d8e38d630d365a5a03499dedff4b17dd369564c9a1293ad9836b6d6fee67ee01de55741f0f682147579c5d70be650d415af109a2cdbc5328d5e6ebd10de9e4ea378ba3c553c299e8d51b8b26bc00be0caae39e182dfd7a69af1b5343488e073a8784f57084dbecd67088363b871998777144293fbe068c242c07ce37d1ff23730950deb98cc9d03b35e9097b9cc2506d2ae938c8c04da25445aa9418869ac191cbdf0fd53b863c50a7ab28a36375d99779f6e63199973610f49832668d0449639c9d85c8a33c21bee77683ca73f1b1b9b005c264f26d2c6e64eda6b2613a9c3e6f949a33853ca899ba66ea59d295af802001e8087782c226b9d6b2a252ff1884d5a5a307814290af7b46bb690383ebb2e3faa583012e6307874e18ecdcfbfa058a8168ac5bacce36bb883c253bc8cb66e73494316e641dfb09e161e3d0f068fa288c22ddeaf0482e14ecdbbe9e5cc484b09376e947019eedcf829a7639ed32b71e4c9d574edfb8229229d65b52654355dac6188475b6bd52187ef8b0a252a0ced43f126313c85b5d67ab261054fe21d42330e1da2f5a8e4ec9496496c992a1a0000001315002028100a874462b170344d8364d83e14800b85a65670549608831c8761100421630c40c410000020c418424343430ae0381b0321dc8e89de45ce095c4815b1044a888f55134dbb2fc473f262320f0d6b5fcbb69966ebca6827f8072f03efcc3bef5e4164c542b8259a2af5bfcbacf546b5da9abeb66e621295ceb343df39855e3664a2df0efa65e50a078b9e17c89a8c152743a2527b37f0edc9d8e52512ea0f652e31d87d8af40113ca2f4e7ac92c61c1d4c030c88ac462202ef11ee0aa427447cf70e1e72352817f199f38fdf20302c653ae38a40051c980b18c248f00d44b084ac4e1ac9ded47663440cab2bda4772310475046217b99b1de927d486d7d190984182b92051400f8059dcfca0a29594eafd4bb0379e7abea869fa3b3e35ac5e11f266b5c2f27ab982b31f290f3146adf984e2cd1090fc8aafa3b53f6a9a9d4765abf8b7323e5702ae56a3d68f190ac099ef902032597db3812be65a6f793318c3f4d149f2a04d418f4d9ff93de99f50bfe8a40605a5bfb4011dd9068f7e126c2b4c37a6382bd982225edde50cb2548ef22281e0b5027baa6f6ed05ab21af7e863e0b1efa27b156085975ff93e361e1261d58974f26bb13c9b9524250d3fd1585dc0cda5091106d3ff346141f7721c919c480865370f45f4c81c3cfc2d081aa613d60e4cd352b9a0e3d8085c6f7e34002894fb38cbeff985131c7f487177fb032942f51e13b207bd4c43f4afd5e1a296298a73abb24121f222ee98c55511dcc3093c882ea23e1fba343b74fc39fcc158db3dad43c26435f4bc73a06e9e01a8acee02153e84f5221314807b72d43775760e47e61d7159ddd322ce50f5eee1c1b274e07977a30e212c4839ed1a4576152221c8e35276559be46d7289b8f3870cfbc24d201b9741c55da870eeace1bea64dafaef92714b00b312455919d22126e20917bcc1900ececef3a0475f09bc44d08274bbb480b56bf097652fe5900eebb82819da7c441e24a771d71ac5b3d6e581d033f1222cf2458bca8b74685d8d4d1c3f912b8a83a61ec24a29c17daf498767e45a08d5a4c3a2c21ed1d5c1b572d690e5ab40400d121283b2c1674a4e3e83b1c416c667ad4a268b97b3265519a97a46edeab0d8940e639643a908fc674f568d13c2b5433ce5f3a7547d5ea8a26a4a0734e79e7ef3f22def258edd2535defe69cb5509edcf8d83271b5070d6cfd5852f13774de9a0b5a921968f3944b0b5c755fe08a0b4afadc679ec14c48f5f6d6a83293843128be96cdfb2fb4573714843f301b08af1c4e30e11835ba4d3b57931ed2701d316cb5e1dad83f000c089e1536c6281045085b03c0823df1c33da34c97ff8101ff3e1dd5045938be9625a08e5e1b8870c8b06e2f3b3693c1d8823b239255d515f0ca60beb7ad40c6e142c33ea4d0cade65814a0aa30b134f46483ac75a910b0ba366eb843372093ded0b01d31ceb69698bc322f387613aa2f437869475ede232010bd907c2c8d8b8b2d62b7122e10defda336636056f54cfa7c0a84765d2c3253a911fae14c48f6a421884a5283e6b0928d2e86963ebe3e2fe1b0cebad1ccdfd1cd9f78f7f6a6f561cfdc95105502220cbc9682277f6c85b9088a7bc46e66c1cf411b6cf0da4797e9335cd7e0b58afe23cf6213541c6e68d43a8bade489fbd07428608e199b27aacac365c0fd1e9f85ab136fbcc95f161c17fd7fc2257346ddb3408d0236f7e6b7fe0d97c24a56de637410bd5ffcec23fba182961e5b7b3a1c105310f1909ffa7284038e1e1663edef69ad6177fe302a20c38633b263c2ec95b21a765bd2e840ed99b027e4b23a45dd36344df1ec79a3b18492005f0d563954266eec27f8da80f2f3f40d80212e5998ae4770c49ec07b594b7832052217099b0e365c0b83a78e35412582023622c951c9291830de25250ebcdccb2fdda9b6e3789f0eebfb02a092451372fe9f558cae2b0d88c5fac3cab114708ea1b55723f430c5b3e6ea9253431be35d05fb4966d98fd5e7a3c68fd73e09e394d08997bf3e4c22614ac45b7d01f1e07b00da1781c857d90c363322ba8002109c069c2cd85f4afbb42f49d32606b0dbecbaf0bcfacd42b3e5987f66935b46c8f0087518edd2f099f13058e352076d14a58a54571c7a6459f29ed26000f3d9009c98d2186d9df4cec2141d4004d0812a3e9bfe0240b621cac3848ceb6fefd7d0beae7fd1130a0e757b112ea864ead0876efb87857a86d99e4081b0ec7ce686ea6dba194dd9873d9716f10f58f5cfeb877e6fff9540632ffb6ea6e5b2370e80f95e894afc9709ab1595f8173e595f35c87830b487114659c8eb2ad75aa10180212e2c098ac8bad25d2191a1d2ce7288395edce5f7efe34c11e3c7c918a6fd00546868a656695f3dbb2849a75ca26cb508e3728f44712ccc06ea3592d4f12ac784d000fbc8aa1a5bed866f9e4e94d0e44d879df238561dc5742e1a25d6601575cc0066b84d0c9742da72b93ae0c33770146862c4fc017f231fb363f7bdfaa6abe076a6206badcad445a625e9e47eb0fa6615a5b60f2233314912a06f036548164e08503b3526623abb839a7b22c6f36d4eff2d60a033166291573df2d52580806c917d5486212924f9152b8cf715ca63485488e8d9904cc89bb4a430890a7476ee9991970a28a1610c565de5f653ac1ab85efc26f8c277c9fe65747cf4910f2d34894f0ad6b7ac9012157678c8a82ad0363ac6707233d5cd9edf3dd49ad5e3caab05a6f6011dc69234b6439df31c1e0bdac2654380f79e0d58cecbaf8af1e789cc1cc2fbbc665b498e086c8fdec7d19506954bc5f89025a4604975b668197516fa65d125beb0e6e545c8cdecf7664ad483f1b2c8c96919205da4053c968122cdcafa8aad40062d3b7baf02ef5cbaf5dd85ae83c2dd465a86bdbb8be6364947aae4e172e84194a5d5940d2b119cdf0754c986b235a53227bf4173edea4a9122c749b2179a806fb84a0c9048907467d9f7fcb3175c9056ff0a3964eba3dfdd5a521d6273271658d0ac97c9672b9a8643a756c3df0e6fee456bcb183660233bb80504c2d5442d53fd3410703b25614bee11babfc4bcd493d9dd3ee167ae5fc7621431f7bc6c40f62483480d9b4bfe09e26ea13d3abb9ee5b518607df9425ed912fa027f45e4afc84ea5e41e6800901a2c227fab1368e3cd0af9567c0002ae5b9f15633080326f2b779d83cc2c7f9930e55921146648ff77f6b756d03e41871a7945be02202082cafe72c278943802752aea397b46e75948d60059acec5a3746153bea2313a5cd9794d989d006cc120d8f969029ff7472d49e47e666fee1778ea7b3a36ea277aae40d3fe5df7cca7860874ad6628653954e56398ea4df3f8a2c6110d8ae36cc734462b0298f5576ae215efb90703da6ad3b1c629f2dda9364ebe8cdaddf70fe4a0544c00cedbf2c91a1dc8b023d89642cc83bb658ec60380eb68647166e8ec6e1b855b9bc228bc1183b7d80b750cbdceadb81212afc14799a94704539e26c5a0009001e047909b8d7fc9a8b14bef28a8959a52db764db0833b337228916d587fc3d87c03b9535ea0b98ddd3f73040593cef7224de9428dfa4ccee821431e80e3d7c1aa708a31ab23bf1458b1a263b23bfd22e82ed701ea9c262cda84f6c6b3f93f90de9bb12f26b6ef690ab60e4b231ea74464b2ea45039af4fe46f16ae95149e6347cddd702e061d277d458d90002a9c97c994cb929be0a162f1840af1627769d5d2d4c0e2699db76f8b4c5abd60bcbaec63c3d874d51d84928e11f5b292c6e0f520678b0d69758ad9b33ec8a4f9ff3c6b2a1b5b0097b684b76831a497f604167977cc1bcf6bf007fb900938a7b8192aabf4107bc69d77ec751433952743f20e7a3c211717c4668b28b25fa024a61b37ab29dfab44670b81df1c27e6a10a8a2816101c75d2d15d40cabfc6028e7196a01c8ada4179521c257bc2db840a177f82b082d65716e11ebc6bdb406b07c5752a66e9f62c1075a17d0d2c00f71808f1d3d9c570b0aa191c11b327d5cfa52922f129d17c5450dac29fb5886b9547eda0c6862a0dd0aa8ab9560cad37651c76908570223efea684edc6358c825dfb58d7cb6e2505507342c66237aca09417b5cc455580340493cb7a40af4788c0f11c6204598d08063b31c77f8de10ba1588f5c848c9b43030ad9c69021ea826ccc2c228006d2589a584df1f0301b8b748f3823321919d16c1f97da5c098011ef529dea711a4bac717552dc596c833aa03432ec02c4592f45702d3560c3122a9776d33e73520db59712d87f65f810992f895042c0fef95724b66bb874be0f328bf3b69efe2b7bff3217a449ab81a372ce3adc5b43e19a2968936572e104e1c0806f10d4dc1de4b5ee850c3bb5fdc35cd8089e50a2cb5f7503b727b4b511b6fbcd468b44bc508a420ae2360acc6ef9b13ef48d70f24c3fe86ca60b9cdf1aee8ce6a21322e00621c2ffa1509e6b6b74ddc5cd9468e75954484ed1b67088537c4b17df7f313b5ef5c6f46d23546e20b05a3d0f191d1c9ff46e29d221733b29b2ed26b24f47f0418f71cd02c15851297fc8b60595efbc6fce1b826c7288acdeb75a14dc67ed2640f11b3e380fc17811735031fbd4f93869012e9e1411a6ffd6af9ffd892dc69eb0ec80157898dbe09bad291ee98b28cbfa45d7875a041d98927606a0dc1ddbb7c751fa75a5c2590b12a8bc861c5316d5373ddd9f9e45226b391fd2541bd3a83a9d187c0e16538d0c80088212231d05d27c44a6b905e0504c9fcdcd4ad1a4023355b3d995ad75f93e143dbfc5302adeb6ca7c4f041e59767340ce4db6ff44e0736f1843ccf832f06f47777d91cda7b3499021f0bad74de6dd690312a7cd3550ad78c2ec9b2995b105e427aa81152a8ee74482ad50b13c4c09818e85a89ec6756df93cf0045a34c2847a0270f5b5c01369006c4b310858a9076df04dfff6ec99788fd7ed1ba57b08597ae01e33a9b6a2bf95a7f6ed2c6645061b7fdf8a1791ad402660305e26f9ac090c9d19d1793a6b4f47f86f9e8f12cf2c0d54cb065f632361dac5c8854f8eb847f81a0f93398fed33bba6f3a0420ac888034309e7cb243c56ff997d6d32f8ab9f16dcec1a0b309ad31fb074a007888f5d50232e923e340341f40201c61abe3974f683cae6374009835ba5f06c0f4f022bfd9145647f63d4e7af05dcfe2352c4bc7817f99b024604e70425060cd33e840dd76b9b35c73c5758586ad766236d88f83425da854dd831ae09cf4a822089cbe5ca0b5c852c10cc41f2356e679d3cf3c839d01c0b152ab4cec720b278bb2b566e14af1d3b980606913f689382cf76f2ce5202461d4d1ef621d7cd826086f495e001208c496c685f7fd17694684e0783e219c5f25491d0befe84f68b8ea15acf5cff7336e13dea76d3c4efdc91356cf5e0142dd7692ff8ec9fa70b100722c54f0ed82d46d4ca02ba463dabb9b8ab3e5eabc3306ee48c27731151fffa078186a56245e5eebd2e1ce409f9f7326b4da28d99ffd7c1935884d4da8a04231e497f4e0a4985c3d95b796fc6493474db33861ff9ea0f6d04cb9dfd4408a327c025b3cedf4b17dc60a83be5a1fd0e85a03a1266cc769d7364079e2e2080c5db1cced5f2c80d44c303887266a7312b45cbf9fe2b1ac86eefae438d5da65a3ca6d778f1d580e306a398b77a0dc7c67b49f6a72a96d3b440389197c8e23edc9d028c684cdc0311099d229b5985b7d3e2f4c0c5910e0ff4ae1717034880a72e9aac23098196230dc93a9ff49ced4c6da85b46f24b1523070fec28558d57747122ba8fc8d71c53a3b482089a5175165728c5c0fc614deaaac4718b7838ece74e35aa320a7a9ac365eec73f975ad80250bff053d0803d963d93aca022317a0d805886775116d2dc88676ea36dbae49e7b2c528196711b725e86ad21d4f55dff597c74c30f42d760a021602dea981c5976ace4bdbc6b7cb1c1271079b7cc97971ff4d0af17346ea30eba664f4e37027d4147f9289f38e7f207495c4b97d65dd2fcdb4e8e4805aa8f0417e035225c6666c221ec70f690fc0ab56247ae33c18e1921485d1838f669f6587a181999317fe9b7667899f8cc4ead1e5864ccff826062c1dda973739a537fba4380623d2f6a2c553e393cb62ddb599984273f65b160ff0c11877f7d4178c19bec1eeeaac2152be9edc2c57d585002c929209671686148752e9d8515fc964561722b0c3ac2fe9ba3b37775b063bb85991e43b208f2202ce552e07d5997d81c964cb847f287e871ee2171138148c7824ccd0baf6c5bac63a3f54f2cc4fdd9eeed7b94e4fd5365bb1a8f76831be177d41f1a8cd1052f82862f85256f7f2f45e253bb97e2604c6ee75cdb611faa4641bb7d43c7562b208f58ea56cff8c2e5e46db5eabdb25b490fa0246a9b35bc307b145acc54b9e0edf89a147ea1846a27c441550534e74c1b2711be98793b598593ae40914af969d0a9ce506cdd75351cafbbf55faa8d454d39694e87b3a67bd20d4934d0ab4852c85e7510a3d16ab9ec983146db27e5a2cd5a5bc04236c4f9ff6d59cff4c6f573844a8194fc2cd3cbf6fbcfbf9b2cd1156a5f9ec3ea4e4e6f9bb4a673c390695d8997c96f534a012f2e5f599b912be2c9fbed309c1d92b5ab2cfa4d6983f3099ba9ed5777e81e950d672886ac3e7394b93ec23b684117ef62d9e63df42d9332ada84d7f7920b84e48705598bd17d31db28bc234904bc6035622a08002242125e1f21bdc14aac36503f1d40c749b0c49b6356da30c154bb83f2848d8b250cac512532b010940dcc8fb7f3a3f1ba99c0f838768b1c7c69f3217785e60121bc74f0b9218da61831601319a7f55818ba7fc01687997e61fd3304dd342bd7e3db726250e4cb7f2330c5fbc1e40938ce894f01430a1eb072dc82ffe6a905028ab21379fa52882f0f7ec717a67a2a54e41af65ed8a7ff4a2e52341626b830596855363d0d5f302e3fddd3c5f8fe367ca1aa84212a724d9c2f83906f46f502ecf1aa0360e502b5aee5a32365e7cb0ef6c82fbd3163bc61e489ea7f8f202b2121096c037fcbe823830dd1ec958e2ee45c60f69502e37b8fabcda79c64c0d7280d9a4308000aab04056f7224af5c106510ed10ce10069ce7dd142d2aa74f01b12a38cd36d94e214d29b97906a4a0a20e490168103d45edc3df04b471aded68a98df75ec0c7eb2b01e4e0c2f5218e65bb633487bb60340efe62a27d9ce8e6ca687e86bc56b9794ed83ec90a999804c09abdd9b4dcd8fdbde0dc6ddc8296c6643485d0ee1baa382f57ff959d3edee8045d0c38cb253c45bf7c014717b1905439b3421c19bfee9994a6c02fe93f03d69c37b0fb316410f7d6bd22e508d65f83d6ca30df9a4e131d7865960dd8206deac06fdff12f50d7a7e885598f951d0867de20ae06e7154c750f6f791e69469da59eaf34db9dcfc9c12310ac5db8f1d9cd1b91d9e5ad7ffcc22a8a49d5b781e37e3878445cdb4d4e8c6b9b768dc7666e81a9366bb77b0b2a18890b2dcf1b98d4c7e085d7e479030617e87949763c070e8687eca47a645a6b8eb0b24528c90eaf6f8cf011992ba4bb43e03e3c992f19c84d1368c74153f2b2e2ff51731db3da57aee9e97263fc439e810c2b461ed48bd6be06d41ca479c1906150fd269e6f8f2eb577fffcc033078d9f92c2bfa10d80822241df4163377a591a3d035c25474cb9b80449a71edfaa1ef7fa98a1b0ebb23185f3f9c33e629a9c97313d6a404b080749933d44ac2ce8201a2a7c57b863b0f0c90d3a8c10149b1813b045a13bf9958dc6eac15217d5a8b2b2a4f9912676501976dbd91466bb1baf06d35b0355593a0a6a3c0141a0ca106b2d11ff05a07ec8ed44576c3e34c7cf2d53f5473412762bc93c67d7d35d26b36dd141f188d4bc6eebbd8cf2cdf371d62d8aa2a36299f6a5f8c5ab1d3b3ea010cbb23ee9253860ad0160459f6d23ce6761f70265228d05d2c31e3187830f0eb1142ca229d2ebdbe5b7e08caf3d6430a9ecc5a9a0cc24388499ebc389e53b323a369473578cb0f713eae8bd9216ac1c74ccb0f51f9fed98373d9bfe9276c3d32f9b7b3ba331b9cf94005c52aa1f95bf25b32f939140e4114cb0fa1686e43c80fcc39158cd607a4a3702a1beda7ffe2c9437ddce85816794e7fe8dca414b0bcd5ffb6b1c1a86d94961ef8d75c5f39dcbc29eae905a1411c77940cc3fab16641e0f7da15f419c69f080de26a4ea5a25bae0d03136faac315592a90ddd9ab147408c8e7dbb9bb5c29bc58c57643ba4b02554a7ff135e259cb25cc57b337223759603a2300cc1bad2083a14f4a344d8b5e9482a34c1139096d7700a16e7f3ec43a807585efa4dcba9e63d1e71c55e07de74731466810cfcd785a916944a7ce28aeac62f9586c1310a141ace84777056c7aa05cffa37b8c5d254a1dc87dff10167bad948d84090da253c114e3da3328775ba5d153aa0ff5ecdd19b54995ca88a7d32e9287f7b790455678926cf703e78c88ad82df6df7f593cfe6098ae6a1de688b860ececdd6be16df7183e91ba2f014dc284a8568745c88593088a727e73306eb34ff021f3e12d913a5b4990851ba36e2bec3bc109f0babd3ba8117a5a53dcbf45cc97102fc0f5127b99c4d0f7a84e82e5be191ea37ed681443d654c1fa5c9fa14973bebccc5c6e5910d9f07b97fd5f10e9c74d8ae53141a19106068226842acd828ab8811cc7f138137922d4932bf5f76e3437e3211f7f9c1c7fab3d9110a13bb3bb884c4bb0e0fada5701fd01e0d452c3ebd0016c9bedf4c578de16476ca1d30adac6758c616f88dac17327d461f485ca810e21bf3a4491609022a9feba078ddf0681873ba66a7f30c72e473343858e994662e3d83fbd6dcc5172955d30cc59cc7528b299702810012039a3d4b5f306ef1a2abfbb3d688ddad95f444a5d843c3251898bbd6df1226b920007faa0ffaddd18cdccde71dff9dd877b72f252d2794b6160d3361220771e0bd6b4f6ec67bbda0dd34133420e38b0f4a73c52957ad7c41d9f362a698a1e6a648f8bc507d2835e86872a578812c00d4aa877594c07ec04abb857f9cea0aa4c9a53f4a374fbc7392700c400506306ca69c20146fd575be9cd206d5bbd9a20319a52dc46781647ba30b8c4c78e1d8b58b9d4c2f0d809e2b9ca21d0eb297a472ed263cb8b0429a9ea44afa09ff8e7e65b9f9e2bb980a79459504fa0c3412d748e63c52d3c8464c6de87048eea07fa35cc3fb5c6e1161292f89ca90d19690a6a9abe0915a9b533824b258a752a744f6043560d0505a03f67ccaf44b5091a0c4a7874588a8f63d03b76009e6c3d2788755b7be50417b2bab276148946158611caa0bcdbfd22e7e8597432768a08931c40da8ed7f0fedc93212d5a4320b38ff38e04e435f9f57f1b137cb11c489a849611dd3b273c8c666aa44720b7f650b4c7e52bc751099fff7f79ca28fe1c5d5c46f42a8c7be1c3beeebdd7d8c67ada9652b1cda65824dd304e0ab127693bb201e44510593fe07b8e36c48b7d150277c2f4d86952864ae32504d77ced136a7b34a87ab8022941e7de55b7ee2e4905a39063c32061ef2465800c795664241aad0aa5abb9ce0853780d2c64ae9066948f26bb5d9926cfc9b41b6498532e6682f85ee676a3d3d222fd4ca8dfa80e47493fbcc2fef598188e2e2560fb0372673758ae2b00af2f3b82352299860915319584e15b325aa63782ffa6b3450eb6829d81b73233437ec6ee5138c5085a350eb88353beebbb5f7d669d3990f6144d218a97e908aab5b7d89bf712994d6781183fbf4ad2585e15aad4cde59617d35ed6eccf4028a877cc4e65f40edfc4ad1fb1101e7b07e722af5e714d23a116bfe349f682ad3852c43a811ef95276e201305ff017e01c740e2f6050b021340cae3eeb30268cb2e31d6e813baeec40d02672aa59701d674e0a8dc3fbb28574a7587fdb7073a684d0d3ebead2673ef22b06753602996a3c081299688c59e87704bc997d2c81c8917ac594a5b39e34fc91d014c48741f80b8a00109c3738028387d25e7767fb16b9e0d1c1f80e65b75803187a3360625a5f5b0c2afe2556e87635cbb86799db7f650cfc88b3c6a2dc55e4d91232a7cdb9c0a0598dedfb2d16ba53585a6f40383424927e4df612e20c56b2683a179c087581331569d34bd0c088b48cb07f2110ebf216e3c2e034f60f2c2a82218b08908d3f0727c63b792b093c82396836a2ad7aeef6c31cbc11fc472b440770937c5a721eafb262d73000479eae5f9bf3cbbf843f66e54db29b154b6444e347fa16a8024eb62c9d250ef6e4457a0d7f696f0b9e7b0e73ea939b721a12be92af0170474e62da83aea0fef642b81c1ea39aae51b6518c1175a7bcca194f59d98ae13b8d64fc8ffea731bd683488814b0bb2836a8f21d6050f39d1f2ea9f16594b87136bfa0c07ba4740ff753b1a9cbf2e7998677dedf6c2669bd921ca409ec69311028dd783049a13604de5fa92e335460f27a0dd480c26a49c4a90fec37dbc47f3dd177172867f2e567a564530d5e7f216245f51586a45de92647a8f1934bb5c56aa796072b909449615f411f935d19fad48bf6eb78082c82b8e129ede1389920e9158bc1e57d2fe00626e7216de576e7e208f9ab4231c8bf2e8030dc7864a9f18e5586cfff148d175941ad058e8d3de637e34978ec4ba58f5a71c7a1d77c911f0f36738eb22f45eb595b0d1c4f2a936a39059578ae62b80c2f2a241a076be046b3babfd3698301f0dd634fe2295755f5902a5b52e6c4f76664ac7d6baa9ed3360d634712dc626057a9cb487c16fcc7d3337fea72789ae41d8a4cd607c7af442f5b16ad28a0927147c191e259b188b16735c8a34ce0f37ba4a51812989929f808e3981c81e3a1c90053c6429e971b1bfb2d731f297ef81619079d86efc045e2f8ab410bbf292c1a6c1dab22c2946d4b0219d3bb021e1bb826fb3219a4e909217e602dad0bacec335a466260b6d86ff7ddd2468224f8d8e479ccccdb1ba2bf071b4eba6bd8b4c2828731907d76466e1a1b92ca464001c47ac604d22c9f88a2d1ba3048a90de509bec4231936a07d6891c8d1018e144439c83370ab8b8785e729f9f78aeb1242e13e9a8fd5df04931b6be9b14f5ee454fb1450ef8fc8ceec3c3f165313fac2b953a4c6853b94d7ea9109bc433a6cc13f4339e0c518ce079e65840ca56eb328147ef7221cf1b1011a23a7e7f9c7b493c31d52709b5924f5a3e821164c7b620acec69cd6a0578138f0649386c8e08ecde9984e9139cc565b459c3a8ad4b000ef071678007a0c59d15581c890aa243055c393b0d673f77324fbf88a96d16ab5a2ab009c5418e5f08b70d4e5a7aa33629f0b6651f7b1e4424878d1a5834472edb0cc05b0d4e08c32101dd554a3ba2b8f67dcdcd90f41e6168118ebe1859214d58b1f7a7998d37166af9ec3882237a763cd8496219dd20589cfd34f817017d12e977de903e044fd8858cfb70c30f3c6794ef884edd4449693d1e5504ce777a25652e420eb0f4a2b69103561a27d0b4710d3f7d1cc9383e242627342a06de22bf3d48cc48bce714223e9aa1de9c55184e204148a19430cf0cb978f298b18bf4e1a13839c057b9609387dcdcdb0e7933dc5cb1d4546bb82afbed15e40a5dbf0cdc63403befa6a206f700b8d71168e64b7155c6695f067414c1362daeaab38147c5ea6ae860d2d2419867d523e1c96f73e848c6cb60f7da34903322a1442b9e1d053d93b41ab50141595c2693d11b03a25043782859200c285413b59198ede5cad577c9f72d956f3cc00b2c87c4e3114a11e18fb6c406c5eb7337b52fa73e66535d608b3556fdba9cc6f741206318de590d988702ba7d5cc43e41ad590bb92751ca387cd6505cb2635a03f5c7d12261d898e0e377c88b1d8c1fb5bb19dbd8a53448b7f59badb8008e020a93a13eeb9d10e18a8a910e3afadcb815b56e66d79e4bc42d4ed17bb3ce4b6d84b3316f7d8720c05045957212837600bdc1ea031345c96c23fca38a46e0149c0351f9652d3d07831422da3628fa7929c510f567a35bfecbf88942a7cd1134a003345516f085842f320b871aacf0a4dc3df4f9ce980ce188c9d25de4915dbf34907826fbf1124ea9586be814574d4d869717b8e7b29826b11c8013b814c23bbe8bd35aaa8bf9d3dc9d7bddbb7fdbc18dc05ab225f8a1bdf8d4a819fb7f65a3de0c1620a24ce5fe1eea7e025218e82982545e2a6024a89383bd0dfb1cd7b065202b7020fee02b02b5ec77e8339f7ba35f2377f30d433fdcb484a926d45d16066ec6cec52ebf3f1950bf66a1934c96234bc6fe85632425e662159a5f38dfb8e5b61a7b157c15061f361a6956cbf58d78419c081d31d4e12131a8acef882591805e8fb7f9656585e99258441c0365d6f63e54a1bca2858281bfd2a1f449eab654d817b3b8683832e15cc435b314e1f30f3f67ae95b6ac6de2e5136706860127e70369f260e7f908dcb45dcf85c1357ea41aac8e61eb6e38a02da151c963fa10d9c76b9b1b00a5e5d0fdc34deb5d844c4d3cff1e29b04174a3fa1f10e040aca4a5f78d23841cdfea058e1b569f869c8e161282871103e4356404e2d40f6a263b4e201e6fc1c16f5764e65274a91281d32109c2a9a1de9406109535150468a95afb7fa39358fb6feb01423958207826c75af032f885f06306804913d37931f4bcdfdfdc07479865ed302ef32135912126ff3dba2a9223f3224db4ac7359ef3f500b8912d2ab9006f18eaa765f6ea07e1036bd926eeef669bf3a7c1bcd5d5c5598d4ef079385e99eb04821c8f07e9639e233e91d6523c6be9f48f209682d3c76bd8cfab9c72ed756ddc4c76e8f28ca61cb26b7267ec37402ea64942d7d35e70461cc58a90040846346ee528f3bd7d34b1bef277b94b813109b661467ecde4a458f56dda74b16690ad927aa80408a1f10c226875d3cff1f417cb617c35d76057436f0876f04848ebb06113d50c35e004b4a1e6bb81f7461fac0a3f66122078cfb0ca5fb649b953201f22b916aefa319a54859e9ebfb05e02914d9c19dcceff2a6e53307bc9249948de7ef2ce111f8edbd69faf11995bcc703c0fd27b0b06ce249b32242e226c57234435c113f7e90f1a431210a9981a43de339a6aba67a06cba48446336cf1e8498a2b3afd9be3de3cf9f392eb846023963c7c99ecb9861b8499c40ac5cd3d506f8783b2d2b40a158061e9dfcec3cf0ea6b4ab917795d470e33bdc379e02dd697b9e9939ca6b75cd9daf5abd1f0b9583c07342436b0a6d7fdb776c5dcc176632faba2784999dc8a55f816e23db351db7bc6d017c066f6009700f2996cb07981a1070896e7ff585bbb5a145d71a6a77a68f594dfa11e22c0244286941adc19f072230afc50013a963d0d5be8d6be8f021a7e77b8e33587101271038f56c43aaa3493b38b5d1258879fb6687b90ac255c4be352b9c08eb8ddab7bfa10ef41dd4fe09546ca29c8a845b1a25e7f2989876f5d2349d60eb2f4f1ec4e618ab2d5f1610425bb9ea7a4b73d7eba3fa3a58b2245bf2dbca945113641d22afae58edcf914e2784257c8a412c3f5e773ca50afe6a0bd22623b12ba4429f6912732c9d0f64701f8aee0587182b7e429ca07379565ec5668f870af51f7a77a96b1bba0f682cb60a513a3d1ce200d2357fefca05aef589ebfd8fc80044de052e47e4dbb81123942180e0feda9d2b10c361b3cbe0571563b7ded4d2b05d50a04331479441d6c5498550637588151fc9d16d0d73113229421839648457a911a36c74564f7cf3abdf36c1b35da6a0fd5b24fdcf82bd4c6260b46852658a9e50ff506f820edf07e5e27e44211306db4ba92e47ad10f84bab6050d0d61851f723b490133c0763f19207486aa4e818c2067c2002e1ea83bf3d2244f2e9695976f071cd016b040c6d302a5a9177336bf14e28667909afa2a96a874c5812ff74211fa1ac334623e2037b348b886487c39499ddaa24c95002b7b6799c06fa71c911cd16a127fc2ffe8b4afba4cc9f20a1cdd82eb7c507cc2d7e01736d5c7037da818415221005dc3b5ea157df0cfd6d1f6f6c8d37df41854574d9cb46192c72ad7555ebab427c9dfb7b90fdbb4c7a6cfc1d129f5adb383c7e776f99302d55f7db4978864c22c670779a83b24778a8220459df04485e2943ebe5153b60c3b9d43f3f26b4873cf7ce584d02c551c31af60ebbb767df1dc1becf04cff4657b3107875be6e0348506386b992587c3045fe9953aecf3dedf239a0543fc390a75af561ef8a70a7ce0ae042ae0680f9542d58755bb27649838fb19f4157e184c254fac2598c605129feed9d32e409ccdc45335a5638c0928dd182cca3a221157b8b8f4aa0ab96733d77ca8e2d2b4b45b2f814e22e70aad7a858d056deb2c3b57e376641e64386dd415e61b7f17507697d66a6a652a2c3cab0944b680842a9d231c42f97cfad175ce7b76ba1ad9e47d3479ee856ca82c1278017dc5c996a0c9fcf2fff71372c838b3798cfb2358cfed467d5b76ab9de3f2e27ef7b260bd3d4094d811212fd7a898ccf338ca7acb2b24489b2dce1944b8a96a8f50e90b0b32e109d08152d9e3acfe0da6703c212841a5cf879be68db23e57c9d2b3263909f04670c2264c7d860474385a8842b05ed102ce573c15adb125e6f736c3b6486b5c9372a4010fcb4c401ac799e1d9a59c4f4fc42f6f2a547504747bbf99535fdb7b0bd2acd17cc5451956be05d5a738370196a563ad2974530007fd31129b568dc24f0180832055a7074520a410e28ae681a484a962f24bb575f62b62f4a5f04b224f18346786a207ea0143ea2a90a992a049faa50c798b118bf8240f058c1ec70bd86dc13421396c6335de4b4031071c6b831248baaa34194d8091fd31831c94e55b6e8473e2e8aa92632417a07cccd0c245974f6fe521c126fa2aa683b04cfa125899284bd026a854ff320e9b11e166345aa8c3eec3b6fad7febb8c9b7ce39bd2799cf2d701f05735c1d2e98ad7e3b0b9fcae98336282d1df6dda5a497ec9b34c2c280b0309d3d4605af0eb9aa96103b3bbe719268f6a12e6bb81205eb2f815052624e668b1b7271eff5c5565789a5a90bf6419c54c3ace8496bf34652a084ed70d3c6c2796cc181702812a510a84a53368a05bc7732d3ebf0360a42e42cbdaf341fdb217775222428f0e801fad4197827e6b5fe8d730f8207ba291c14ba66ccff0b3d29336f72b390d90d118874dfae6049f47fd67cdaf762a665502d1046f4f2ccb9ae7e3b0895ef7484ec64d9e22ad8d44e768793c0b03407638391b6b8ad008b2cfbe87f4391e934b4fd110b4d39fc942780b2de1915d1ce09ffe2852d55134cb29c6a837b58aeef64a6d6096cca2b4f7bac81298b9e40831f77cf866d98e832570e26f93f5e5da06680136809500f929bdab0c8a93495468c6cad5a6a973312767f10304e8f2d0d327dfd4ba53fe3b78024929f7c7c610d589eff76f34a57ac14af783d975e92d8cf7e0c8d8c89429bf1c91d0fc6d0b4b8969f3680c8d0aa64682de5574599af4da8ac99669c41a6a2cae8c8114537dc757dc65bd4395ae809e22f10423e668a5578a9899559a0ac687ac131d080523ca3954165499f3542249559589dcf1625ac9a1d4fbbb6216b80a0b2ea70e70357e6c6ac607f312942b281b95d481612696f8542c0e99ca1bb7144994e53cd15abfef9e997a3d76a6dc339c30e77c40451cb13f89c67f33bc76337cb44d554b78feac73e20f1aea8fbb176d1d49a60c821ed9f4a58bb536c7795c286b0f4ccbff088dcb431c9313feaf916718deacfccba637c37b42bf2c5337d56f84b935c2c6392ccd4e2db62d86c44181fda11a4816f6a1988be706d22e9603f44bb69f0062d0555fe919104b65eaabd1ab726536664c662c86838462d61c24ce27a8586aedc4c1689682c893971e1fa3d909781f4fa703241f70fa203b1190bc3c5cc6ec44fb3fa9131ea54464598c4e01412279dfe20949b590062a5564fcde902d31bbde9faf5d3e3bc741afdeccd3848c490a7a668eac0343100ac069cf908407eee66dc6247922634c37d91a3c85c889b984178d0594e660807acebb28fbd568a5ee13c2371c0cd0e0a06a1549cb4f9799334978f1259ab29310d94a1a1c2f8f1bed048659e531fd5ea3c5f3601057188753f664681034bb059084ad68d4e2f904715d623856ef1763fa4fbef3447b4457421e3aa006f66062f02bf4e068c059806ba0a991ad88d73c75c1412a289ba9944d85163c30e5c55b06d82076c409ae218777aa77781b886457dea5d47ef5c1ea705bd3448a8048eb73b836a454bb089b328f25b1cb5f8794eeb4cfd3590b9413ae33336cb0eb4151425d79abe14ff006bfb0f5dec0817971b8bd58a7546f3370bbf52cbb8edc21f8c941a69041812c4399a316f73126a14d4899017c1df5190ead8c181ec9e91a6e46c65d63a59ced5bb3c6444eaea2770a0f7240dbea07e4d29e694060d634b88b74e32fcb5807aeaaded9e6ac908a28f2e46a33ea68aaf5f48a70641310903e7eaaeaf6758b515662fecd6d71f8e9fd7da8f60e2313d1ac1b34927286183eb8506ab80a32210c745a84e5660ee1b3c70ef26191c46879206411d99ba977bc2bf5786dbc7538976e140fd75d0664686bdee6687784df665c1746ebac56448a9445d2206650ee24952c990031aef5051571465c9021b64ceda55df999ea9fd0e378471aa703e5a6d4a2c74a36146f102e525463af28290d0d3c06db023c124c9551d1a7b743217a0594abd9d6102c18b6112dc34410943466995d323dbb15f67b56a370aedd089effcdf2e36b925fa205ce811589c5dc18640009d189911c4db85e0f712bf8a9be7af0aed823c4c430479f7a3c370bb11067f35fed463fd213eca800a29250be8f07d902a9dcdb312323659ccfd2d2cd323ccc74cdf7310b2570d75bb3b058253487813c72b4e6c9deead9dbbf7d113290dc9920bcec4bf28897e0f4a0805f2c5d4439dc05dc35e1a0013da2f970ca663e421a6ccd4ea11f1a5b1e21495a53719f9281949addbd9e9933cf9f44fc7b98468dfcd23bdb33c9e9cc54fb101214338c0d3e3712f9408c79d56ac345dd0760fa8b219b67a96c7c01c9ba0f461a1d9edc1a76899a447f500710a024f115c972fd5d8db6ae3c79dd7f1db718c3ce0e02453a78d0d851da251135739f6c3e8872d3a2e0314622c7796685499fdb792edaa1730a9e3d4a423f6a5b6761d7d913ecbc7c3dd194a3677e1463e73cc4c2a0dfd1e199ce1cc1498121b2175cf09fd51941783dd3f2e440ee08882ea7947f00d29e1f5ac7f578a6530fba8a13d8f4ce4295b3189ad1eb77ce19971677be9f50363f7b2a464e8e3a0e33dc1cd745d360909311ad4d806ff056a48dd766539ae20d8f74bb29701f08840034464d26ab5c91b1075e24a87eb007ea91eae041fe919edbec9a4faf035cf38024477d292871c0a84e8e8b2798ee2bd20755e251eada03ef0315e9c5a347977567bcae6f33801dbc07209eabc368c88598b0731f9cf9eadc6a9216ab51c1de93aa56e0c53b2378c93c2119400b0b210b3e747878aafa98dbe097241170097f69259046d12017075f38a8bdc469dea084cc6abc36fe55020b665ae7fa46e716aa738fb85fd16f8b375263215bcf99dc1b4a6220800ce7359b52133c6a5c9ee0e600d93da9d36df5a395e94552d2a06680664f818a112b7a0d7c51465089fd11175ad2fdb4f524df4025516eacc63fc7a11f2037f7c684cfef92dfca9eb72df84fa51d27e0759e6aeea5691fd99f96cc918c13e03e34f586651f987417cc2de805924a339d38b9b055bc01786da8e6f499819f2fafdf8605da4d15e3cc1e5ed0909d5a055a691bbba036b85784c5675a35022f6427bdbab37db62db05e7e4b1660e51654a1cea6e2acfa86fcfa4f6a20d726a430ef3a3007cf070b5d5f2d50a254d367039f002a12db2f9c5664e948a1af335aa62d492546db08e63e8d38e5584ee1ec7e531a8684285ae2cb85d083bff3554878512e1538fb085c3d1412d920b200f87243df4326f465d8a513ff8d357feb43396570c4f0941a3d498c7eab178271ad69cab8b1420b3f0073381a6731357a5a65aa087c104c5f663be80ffe5ccd6e42871de4854d0a2170879962c9b83a82815f4f63ac0f0a6ae179f67aa25d88a2ae93dbf60fbf31bb14fb80eb0a80d4f1c1a7099bc9c25c93db17418fb29ba5bc56cdbcad1657bac49a35ab2c6605ccec624e7613264a306d4692f10ee99d3ca84b446ae287ca6f4117170f8412dea870aecc8b48e616d47321a861f2e57a4a35483aa2bbbdd75b773a7fbd7820ad19ccf296d7fb54540bfab537dca3e0608ce3f99b85f5a13fecf848410a97c22af8dd6a5403f36100042b1b263e7a26543fce95893e4f4ebf2267a5d0389cb4d8a984d176acc60e7e914bc2a915ede3a774b819650e58faf52f0262d2cfc86b9d668e4cf5005f4d3e699e906ba7060647c05a6a94a4536ce815035ae3aa0ae531501097ca5c7d4bb420a4b4645961a2f20721c39a1d822bbf4ea85d651e26a798b9088e1fdc2be63d5cfacf45680ec673c8aa671f97754c30c9221f5e034e9084d594ef0dcbd4d36b2cab0c03e9512d0a2a900748db4408b31c993a820d314db07036310598adb565f5460cd95a26f0d0dd9ff89f5ac0b0f4bcea54338c1b01d2503821f1d21eff1d51d3ccbd3b640402b20189ce483415e6ca00e335c36b5b70b49d5d507aec265d065616d63a40b0491402e9ceb929ed61415b71c740c19827f61e433a0a55c4c62e6088ef93d5acffc09aa2796c81b967758bc57c815ad77a34a457d2d470b247e74791c6bbc6c2f3d971035f8c102338ce66a7137757370d49ae729316c6710ce35bb9031c05e4924d9f2aa07947222241ac32754b2d50569671e1773bef7a8a55b109110508e6a6b9afcbfee4d8e7633ef4cea479a3eb3f874c15c2b33ecd08bf9d9e4735108e55efcd6d7b151b120178c6f7f59c908fa7d949827c810b73209cf517719ca9e3b699b2a279274e64a218d684a08f6dd0fc55d498f00eaf063fa1a9f72e885526351d888b23b600ffdc81014bb566b7c737c87f1c3691940cb31757b5e49fa3af986daf20c34fa9b38877e9315cf1cf5ccd1e5f56ce87d9bde2b5d042a150b1cafc55f641496075ff1c937087ec6c34a2d99f279617ad60c6ec673b2453ed9b24b6aae79a4f21f7376f6b37da35aa824e57aa73eaa0360c568955a62b7255e55b3a136bedf628131c173d1c6295d9a35b283fe67138112f2a0d607a5ad70b7b98f59a483d46c655ac32a3d5fd6268f70b1887d916a0d4e124224e6b77bb3a03cfcbbdf00f8aae4786338ef7e8c549afc9ba02b3103a99d260ac9b82beb95263b4df8c7761b4198980472ba669e9dcf879e343d0a6602823724ec4ddd721834e88f99a3e0a3418d3772f12292de52338a965b2ecb982626fe104975aec450aa428f7a09a07d74f63b2f9d7d063732bc9a99ff42c679e5f0714abf74df1eec20a7c6044b86bfd9af7a8c26ae95fea64b45daf5ef7c728302a77774b735776b12c295fdffd594f50371bac42defe80af5bd9bcd417bff794b96c4ba7b73f508341f2d04b010553719ef582475f80b6dacdc7899a44358bd687dafb60434ce9e7a61f17dc29874eec8351fb67db2dec8f5085f3b0d9dad48e5900ab1f6c5ea2fbef3133ca4a36cc40afb7c6a50073d7870941a9f0ed2a54d93321606e83ca097a95ae8cf03f5d1f011720dc3716cf6213d59a6ecf5d836d16e66053b311477cb3f04d10688f1c1dc7e51696a4cb0c802b8f01ca711a501f840133f9fd3c7e4801eada2cbea49e4579154c631057a7516a6fe46fd8bbc95367ab0b83f7d41894118fcaf4dcff8d5be6debfc23a0c4ea2221dd38323bd9d8ead00553520f9e080c340454ff288d48997e204252c9daab81af815383225a9c3a5424040c1247ad545af41ea58815cbb4b0d31b4bd9c3790021dbca7d9e36bf33e86a01661b1b7f430aee7535ac72c8cad48eda2dbaa798502d2205c3eda48081066722b50cdf6e91312c78225e1da5f655e04b15ac6592cd2229eb5285a1f65ab5f5b16e4a8e93b736fa527754097c4658fd9d57db3f5fd8e2f5a7431072dadd8cd2eb90d99a99fa2ac6cd3a0a3ceecce12df5f97f0f4d1f718cb98fd7843fd301c97e27800b6e5447c1f8543c355d1e8246ba92e7c76106d4e350e51535582407d1b1f57f8f0300a4f17e2d380cb48c96cd92704d3320e09aa0411032c5c93217a97b25d1e4455323d0fcc16fa72ee19a0a8041e5b8a5eb8e623985501f350c8b1ab1440b873629ed316057e4dfdc591ee47bad60ebf1b7dc5755d265ad8004984847c1383cc2c60ac4bb239640d993333c19e115033c32eb7f75b9e7a3e9b94f69ecf6025358afcdd94930d3f5aab380c8d14f7b2e4f27c441c5b8c48e70ab7b918a02b9814530403dc4caf73ae7cf4700bb99c46d8a18c417c0d9469816909c364db173eb34221601525dcdb79b689a98d1520c50b22be4c22c47d2fb888a12f9c76691e7f06f8d714b5b43c071296d10ae1e179bf808d125ed03405caf66b077c9748e89d94b2027af368bbdc915bb38d74ea8f09becd5784c2149204391fe3b2605b2b2fa0b3df28a43547621b8f665cc7cfcb365a5ac651aed1023dfe0dda00a1b798eafa29cdfe46f2067b8d9c9d046a3256ecae0c73e51698cf801489588a639c74344c9daa5f98682a7d9aacf4589a5845247321fe1bee794e692d50ac55b7e532a9fb11f1e7a85c8c5b2d287eaed92c2adee74e368acd93737f23f4f805d3c24e2e4f024cbe6a62484e448fac24af9d3d503fd6dcf6d42532dbf47ac0e37e08305f402b2d17c4949165fdecc89241f6239db59665ca895e8fbe2276cf62a11e8780366b977d65420728e10cff15310507aed9111943a776e298a45c07999bf2bd963ac6a5f2165e5443becedede5933a0619a2a2292891c29c828fbc4e846f9c15f78987ce099e0ca41139f6fc36a111bc87076195122e70f841fee2de4b069db95a8cabf7d3b4e5dc3e61fe590668cc2821529453adf5d683e1c081e17bcb3c3fa795466a13d50ac5a8cc76b6411477e5c7bbc79848852645401ef32c25c2a9647ca207f1b63514d6a0c9a161d17db4701930bba88658131acf4237fae1a4f72707af9d2c6723308770ae460d7b3db4031a85130e1eb2e86e11d1259cd0de483a860e96d3900308898326103a55b434c1ee955de7866201587348dbe1fb2f0f050438f8a1d9b1968c5cda0af016aa977639b8b2679668fb4830158a9ccf304884fab61c90e9995dcb5bbfed2242dc785191cbfa5226e7904fd0a86ae222faac970a42075e3b0fde1e8120939982de53d7340cc30a665690e34412e36b8ef476a46dbe2796878772fdeecef2a5cb68a2a66c235fd210eb63f636545c80b4e5bc0c874611f63d66697fb6e4c6081735c796f2ed5ed118ae6d87e60e767fcf0cbae26757b2f31367b0203cf62089f7c785849127ebe22cbdfe24c92bf78431fc2807ef9689f17ec3830254dbec0321704972aaf44da1a6d7547eedc00595c26302c3b541d7f0db229ceaf01cba93b50f08e07a4d5d6108c2d3da691f54e76583e8f4a530bb5ecafb46315fb63afb25c042f65262ea810638d65736fe8951b47e99f8e44ef64d5f76faf08ba82f4c7d52e2988e8337daf5e4bb9abc54060f10b8c684fdff72aa162d5551634b81dec0d0c74153d211af09ac4949c9966deccf3a36400062bc2c23d56974f3300af506a010889c8c2680bf3eacf71ad41f4a6867da7608606e80a75ba638615e4ae0de2b9bc45862716edaf2ddabe064ea6f951aab285c920cf53901b356d3bebc47f3c3b022880afa7341fd0113a9b48841023bb201643f10877e44ab5092528c7ec1e68ad0a0631d44b91031c24c40e6a3e085948f9f87d1e5a6c15e75d6152b14a3be66e6ddba4795a3d72dcd5769055c277ad15b99d01d8d3f2ce16cf7cf64736b170a1c043bc406ca8fba0fdbe942359b6d9a037913ee0a638988268a1c8de6fdb5fcb15ad45988efd85d56b94a8e70175bc850d66668a663fe2b8f9210c23dea85511bb9713d0c987166dabc1532d8303d4b426fce769f3c32e20f26a1ca0791b9c9c98232331f26b6bac640b99e8150e5a3933f3b473a61132436a81aa61bb22cff0a1ba72fb9a5508b73210d680f827a5079526b30aba8a015879e9eb1300ac381fc209492392169a83b653f2ebe1b48376dfe788c893481b7975ada2b64dc9de0a415ceb24dccf836677a0023e40a14ecfec771084cc748276d4036d1ba261a90dea0c0206a2dfc9beabd571c22a04891743cc2072083148d036322bae0e1ba2699d013df86b8370700ea285783ba28fd35741a9af8d285d69ca44a4f0c95a9328f46b4bbaf7205d072256f1ed7ef77ce04f48e10f117f18e97fcad8ad47b3e9383d8a8385a79628b8f600cec59a450adee4ce719999463b4569d03cae3a013e0d9363a3b928fec6fcbef627440573c131c8c80be18fd700bc4931c88ada4282da6d5480c4326e4a3d64c47ceb0e66502bd7c6990ee10a0b2891432c07103bc3e888894c34d1b5a3ecad1dcd45bad5625e3bc3561f79d5d5fe0f51062606c181884182992f09e45231bbf6437e2c951f75ece0ca68cd8e556808982f55c6a09590486c091950cda0e77c1bf3a624e11e72b38bf6541f00d68f23179dec8183ed7c929cea0d8e23ad32ec2f75c096289bcec8edf7d2eb958b44eb5dd56ab0d16b83d2287e85de4d537b39d097eda720439bb53b8621117acbc19383cb4356b6e03255c73db444f65485d86f97b0c76cd3cebfeed99470eae640b870c5af0d117f4d22ed5598a840f8ab02ce527a310dbbaae2efa7e534575518aa4c801b4d2bebc5f554f72f02906437b1cce34d43b5d8a3314933a29f45ecb18ef3a79938d212ebb17947db0aa9bd8fbab1ea78df0fe553be76e5cfeb04f0d391804a860207d4852c7de08b2ba35f5bacbb6d98f0b85c4206085f3241fb772f7d78c9230b0ef407db6eb801f2f7c81865dc5fc34515c0b144dc8239f1d886dcff890accfee1b4c3e2041c6744cd80039338262b586e855abaa8b48ff7e1a88188da8a8abd1db71ba5670484181220764ce0a4da9061ab3a549905e5ad26c9c8f04937391019a6cbe99adf96b81eb7b3c4ee0c0669f0ba21428ae1ab3d5cf113a46e2bcbdf21642a7f2e18ca5b0709ff872a88e0a769e38dc1b438265f7959bc4a08513499c8637f6d8f75179ad958a50115dcc693211d764cc44c2b4a30ab4b17f6a3714f7fab72d7899ef149aa3ccb5de86f37c821bb70843128e133b5cd9bc4e333eee960b37d340c46a47a90c5575a118324f94688f3632b3f01a836443ef9c3fd2577699d6dde626bda6e68edc6ee909a3e1ce239cd52fd37a9b5671ca1a72809cc48556db1c17df7187bcc661c190803abd46a78a9f550b4822c8e19ffadc7bf840a0f0ace8ca4488f1a25fe215c4d7527848a139754977d5f1dadede06d1240dc2a25c52b42ed058b2d0d4bd9701558a00223e3b5497e033bea6a2cba566451f6728a8e71f5c1aae640d1f3f13ae483d1575b6adbd2b3c078552b6708b6d90a0720b36cd6b75660698ce17e0df9b93a822eb9d45a9ed2b3f9a0b85438dc261a49108d99c8c75416354c6c6c1ff726b339d8ecd843cd1bac6d3320a9c2232627876b96e588eeb42874883c72e1ecfd392b3b1e051823a50a2db070237edac531421a1d6572597d44a5c2dd2d2b39f638141aee3f3c5aa6a995846baf9a901b286570b2bdcf6255b16e497fb97d28beaa324dbe1c7566f22aa4bcf5e3d6c3d9535e9353b67fcfca4ba79a176ba0ce84ee1ec4bb48fdb9dbba56889e5d3762248aea1a892df5ee3aeed4967f39da9aa24da7951c71c532cde1433ff15f9000936912c847b5f96f871f2afb51fc221a7b474e6b9e274491871e08f8408ee43e637f142f75edb491c6f5a66875df6a393e78a6803347e01658e7853e98b5e4d423ee2e229f3e025ba9ffdb31797e0b34650620e92e513b38e733c252c6184e77d58c297a254284c1abbba42b500d81b5c16b27cc65d027badef5dab260fb74fd6f16c28126a0ca4defc70285f117b53a6d9395363b35bba9c4424404d42ec33d5019336a4745ccd385a1b0559208094e0ffc362f0b53cf69faa10a8c7bcd1821c3cf512dc28902ed61feb4b54be7b49018dc7d354d35984975ac7fc4d4366502339b981199f9be2f0b5404b47c500a8406f0a7046ae6cdc229db23945e24ea492a1895ed3106be0f611d1e0b102428aa50cfcb771baa388bee1e7b1094b6182a3376a6cc5b8fe3302bb85b3c131c5343764c12e33229bbc5438ab520c28aa36ea10fc3df96ff106c6d5e84a60bbb4514c912ad549297bcb59f23d7168420d998848076a80538024a19218a1aac7072f99562c6bf0c43c55f9c881c9fc8c5557d0d3b43a413d8ae47b8f825e053d8be3007339f9068519555d278f2695374f7a36c14fb749b59d03342937bf116eb7248b24b040a88eb53fdd9ac1a2735162c66db85a850a6b1d7870df9e7cc1910a0a3a55547c5e230fab82847d706240927c1d6cb523d35c1b8501c2da107d6ee4827346c27a3fabd8098369008d08ebb7c4a37b15f4ee93e41454cc2063cbd57a10929241c779830d744d2a6e43183401707c850d4c8803f3e11a216d130e50ab25a49006266cff1ee786d724cc86ad909627fc7d11d55c943b5630e862d651697913cf824494ac9e057c80e0f10818879127e4cf2f24efb1d582658485218044055a4598a1a99e81f7206d050c6f5e23e23b53dacf1c299e2fababc16ecc066772218896bbcd90b556e76b8bee0e9c902324b8b280cb668dc68614f3a7caad8839f9f20580016a2f59b5743fe1b23642808eeef512a3eb44a55cc096303e6267a1480f149047f95d57d66eacf7dd25bcdd216c03e96a8c624d2f0b226443d3aa891b7a2506a32bc5154f132db239f8a15583eaf724bc0a65bc1d43c90773e75a1cefd869b87a6f4e2b77a4a862c06a5e763b3112787c766e11ea859c4c6478f20147ec100e30621717567c8e032c075d182c2b6eed776add7af1b56ef4ca2293496c75a0311291226da9bb0ab6576bd4208ba8d5ba922385070c9fe889bf732fe3e97ea6975af84c8840632893d264f8e09b906583569becd18c7a0d415104fc756d0f2de365656a0dbacf20fb08e0d01cc5b554ce25d770ba10c299d38988d1a80298386b3d0cf82ee1a00fe4dd3df0464b9df76463561c3302b66b2ce3cd7cd71ca42adcd533959d3fc543f7aa524e0f6e9112fb649b852460525a6aa096ac3172920f48536dd6eb62de131dcb146a3e82e1bf1ed9ccf882a053af5a912ea05326494e91aa03a77f006f28c83f2e198aad80c28c0038444780ea23650430859c7944b6d13a4cb7914241f9e0fa9ae7e502261d4650528e8592f69631e09f0d4c95bab6145d569870cdde88c5f6277ea0de2ef9abb69c4aceed89c9d812c91fc47d4126473a38a71bcb695fad4afdb327ed95a8ecdf116fafb6343b5976da9413f7c25163d30973f2d565941a7a73585ab3270c89bcb14d17c34c05c4360b6699babfb5903fc4415f44b702b00185f47e643c9b7a1415fa5ea2c96a61783566f016c38ebfe7ec3d0463061f44a4729e11a0573a3b37982d370ba95665fe008cabfce89460e4820849d7834de7f8fda286f85a3faf4ab8309d3a421d830ac470fab80c4d1fc20c2655595605c49d9fb1e2ee1e5949694c4bf0615e881a7238d3ca197f6ccf1ef8e36fe18b34553e275b20bd01e621cd83d497fa8efcb42118e6d439489189bc4c48c3f183bc4180c48e56253ef6522585070b94211076a3c2d452a89b30a6224fc2f465b65d7bc580a514067f11dc2e21792d994a5e16ee374af8cdda1c2fc4e24bccfa52b1a0570c642c300181bc26a9d30dfcdc92f362bce72d494cc509cbd384459518c536d406bcc18ebfe47222c645a7de0ea553b838a8d7c00312e58e3c0a463e019d3569bf8a3a8c43dfb5180fce271fbdf02a322f38b73b4703d26a13f3cf6804ac0e38007b90b7a1a797dd348f162a16ffb2c730617af7a48b9f642f783c48f75ff4a5fbbdbf8eb99a97303807043f4794cb539ecd09f1ea064acc4f607a72d4d21f6978f238c188d94c1a343923ce7e330df8c3fbea9ef068c68de746177ddc01882cc48d3c61924e8ced6c17ab1b6d78fb85caf42daba10a498218db774df369fedaff83c1852ef6165096aa09bb07fe273a8168705e0c3345bb861670269eae6501bd891a78e0a7bef900eb7e27357cecff8d005f8af1168896dc5c80b4e5c06b848ff855a7afdd81eca2cb09d247a2671843162e3f54731395db1e9e3c353634c4c451cc9119d54200deb4a58c68c3dbf9ede7df18deca3d343b7b40b2da3b354292ae2afa9eea99fbf38607f75b20d2aadd0fec0e60d816ae33c543ed1bb91df714bb0fe2eb560f87d42e546b8d5af18cb00d1ee96c812ff0b1606df8886b8316b005dc20840f9b77497425ed441b3fa62784ba0601c55087abd33614b57e1f8af66168068ce9660b8758103111d9d9906427baa6f6a09b249d584ecad207db896133c2b6a7a9680641801c723b93b661924daf35cd0a1835bdf416409fe97be5728a85b6809f6ffa424211bb8613ac3126db7a644a1fe6d7cdb6b12f2e72cfaf7bb03710beff4072dc3ef35afd17c3ddbec903ab7eafc45a8bcfa35cb04eb994424d9bc6f8516f058b1d9439c73640961a583c8e214c231e07b32bd96486c86802628c824cb1db99ce83c31beee4844502d5e0489a6bfb8867f327d123a802f1eb108b7dda5237f1f4299f1a6291b2896c00ca1410d058ba6af10402ffea781c97648e14fc5696df7466645586e30a2b4d30ca6f87ea2ad952dda97831b8cf51715572d1190027164d62ae3e07fc216921dac3fd43ca3f35a518c187fb236a88af79d6307f81eb981e6d388e666b921463cb9e7940ded8fe7404a68f0251a7430bf3fa54d93deae9a339c94e4ea0b391e5bb7ccf2158782b540840f26f3d4254a2c3f92f67e3ba2865335960b59ff405247b82b6661b281231fd5c4968374050acc419948c712e0a79f893d24d7b42d8cadc6af9fb630e02eab2208a08ab6b947d288b8f22a85ddc0d31f438a11468f06f028aac86a1e3f9f6e693ea8be9abf38f3bb6a048236f28fb770c64ad0600a324b87c7c9a5598bd4a4195c18b828c9fe9f97337d324dbf3722ac0010e13e86de912e70fb03c91661ff0e2b3b4e9c718e2365f6a1e6210a8aea76a11e599d81a62068c4ce3870753bde23b0819e03a45a50d205fe5baadf97b839d03630046663991d917f0bc30be833379f1839d61957f8811efb21c829bdcdfdb783bb0119e89ce9318532dc205beae3e072956d5a16d0d51f296ebd6d238f9aa1b094b6b30c56074074b293d3c5cca0ae21810e3d86bbc991cfac4b1a80b57900660443e057de2b72ccc97715659b6b0ce660c21b136adb94d332e23790edf90fccda49fd130d9ab1ed1821d285a02f809825e0d6087cf29adcb52fe43e41cc8c715ff38278274fe6be8f07d5742d943b4e0712d9b830fa708c8117ebb6009a696f2c58660468a58026d8f19568c7a08163e44510c32289768df108bbd848fd28608f8e0ca2091781197962653ee7ba5ebcb5f3d6d8f03e14894fcd4974039acdb29f78fa737373f7726bdcfd85dc96e7625914dd06e8353641329889375b8c03d366e9a990d676fb9de598ce16de095457abbc8f2f89b9206e4e5e7a96335ff77d30d9ffdf96b1f3228f5881c0e33cb80a86f895d8e6a0b1d9481fe7c24366e2e7c3367dc658157944e0f4886d1a38cf2cf44e107347ab7efaaf488981791aee553004b127eafa5001bb02a466fded44326ddd1e38d24f977cefe467cb920cf6542df2885dc4a284f72f1292b6edc63c9fa4c8f515fc51029924c4d5ca95dbad9c449f9112d7576e7b68214b99dc86e885bfdc1de8c237ea8a71f9eb9cf26f443f9d2cab51beef998934adae928a52b0d333731bf20b9d48aba67c0a12d59ab3fd913400f052809b1f9260e8906767d241b7bfb0fcbee4b9d8fa3e2bf3e030cf7e027b6c6ad1f7f1523a08c2268579667e2910b6c2249c73840b980b0f4e9db8ce32d136dad4aabd438820c1a19597ae9c1bccd8851160d782316e2ac1bfd6f729c692b5d58c47be96b74efa7f688e5de1fb399011c369b3db91ff84dbb64d33a33135efca76607ac5b9533abd955086dff26ed6057728f55a4aa379027278cb46c12dda7be5227d1caa4c0d8fff1dff457ff959e01dc5858a0cf3bfecd55c29fdf72b286e0ecf91e4cf53c64166b3c118c9fb0c83ce6b3398196b5d96246712351d654b011dc6a3c7b2131b55de1920aec6f694f3fcc1456f3dbf10f1ef9a6c428c006827282e01d118639705e57dffefb45e40440737bd49bb431341f1e36997da11be2b275346ec26643fe235516ae468ac07b9988b39674a5546ed8e2db60534a62c915afbed0a02c66823fbce4ea6cd837d33206393d297fb67417e9c0698a42f533fcb005ac216601460ee5f17b850f8071d8e9902a82b2c814705e6f6bba4db853eda219aedff1d66a4067303b579a4ff54c4ee96b6862802dd1c90df6b51eb188866b4a764ed06e856c046a9b5c0af7d5a117afc2652baae8e7d0489001874b1599ca78ca4f4a6c4f45ec33240f1100ade896777df873a4b04c53d57001652ea2dd01c21db4c33f49e60686f599586ca4a7a674d114291ed2643c212b7e9cf4c3f1471c0de00efce4b5c99283d64348d0ed848d2288b22bada5db991f7f8da718e47897029c8c60c6f9ea136e5f54720621c02c47c2ac3b158b334fb45d04e8ec1ec692d131223ccce2eba875b22c7f5ffeca49490e78874d8f6108f71593392c5b4f4a5604bbb2e1ad2e57d3ad1d45a2de825457acf11224c676409dbe64baa6636b6407f3c895b6890389863bd4fca7099cdcba5f7a27c94e4384b059a3d329f4ee7d6b82caa301d93ae4353ec91fbf48cde8876ac6c5ca18495c31fbbe1539bb98bdccc46b24c629f93e2daec4add6e2f5ea0f43ec863cbd1f62a82a2d9d229eaf36c81ecfeb633944d9f3d7b39e0b00e5e46c37d2bea6a089979623fa47b354a1725473a062b25bb29b769affd311b63b8b0122151e8e040bc93450cdfdd799bf1ef199c70dfc3f3505a2df1359f2e61941ccb8b5449d092631ea1f4b51814ccd9aa2b46417d0013e37ee48d378177033eed6886a3b409f4ef70ca993d46d825f6e2ac2443ab4cbcf37f96f784ed13e5262c27c20b2d6d074fdfac23a6e05582004207764d3dd7d412bc0d9ba86f120dd63ed064e6bc2fa6169030d9f8a14058b598ea4c7160f8b40d5058cb2b48c6d194c70f45455ed72038785e8a604c855a2001863420ced97e011e6695633156485542e0ca76a3c3d38f72b63382319b6e15adbf4564858420371bc81761ffb6d99cd9c27deb1185a32024fa516163361128b140380a9977925ec1971d053495f77461981f6462b2b0011b67becf533a80bdb218c8908156e48dac7d1ad3b084bb1feb37e26e9881aedaa7e1e67f7615b5dabf45f480f969de40accb41d5e4b4691d0bbbc5df822fd20a4b40caa87da15f9ffbc30bd2934d61a893c973682a2c052dd229f03fcb1ca09627c58caab94caa668c8e6ce29431764b2d547e6c4abb0a1f4f9ff3fa44fdd9074ef34f553b490a87b8bc51f7f508cde650307f51a39d4ab19e77a26b440c1f1a4ee005ba92d0e353441e5518be641df6646bc5ea2e7e205ef56772e6fb7dd35ee26f9c5b1f99d693b9dac4d2a3b1a7f7af1552ee54d410dfaa23be505b24bf0d058acd5060944a3ded5b29bf4538f5cac76908e412ab62d364d5c1c10c5560821a22fbaf80db8ebbdd01ae85cefa796618d31c7d3ce4ca3a7d27630d900876d8467bbab89d78891dafa92c10f9d48a5e574a99994c0bd500d4ca1542e72b265a5cd033b1a193f235823145fb4109351d72cd42ff4980e63461989438518833d93cd01c2205aebea405c172702a73b008f6d55081e546b5145c2cd73e9880e5f6255c27a2e5973ee27298851606ab46857a53665091ab4009b9bf940399dce5ad40478f88e183b80f613684bb4da0d77b89a9fffe5b7874360f079baba277098f922a64659c77cfba43fa0139e89ce911f2069fcc6189f0c2527760ef077c6d4abf163ce5558c97bca5de1938f7511e2f9181f7c9fbb04e1ef741ce0e557d5d1cc1811dfa03480b90840e958929232d75a3b9cfcaa56b1d60ef14d719177a64bf294efc107612d4ca1ba66a1e174f44dcad95f4e05d52dd4242a4dfc7974afd3a3218df2a5d27e9d85908f7a0b3a244fac0cd468a85a7f05fa103ff3bfd73f2ae11f12f4a3eca32011ee152a75a8bc41a20b328325970d6c390bbd61d11d5579bbb6b0829cbd5d8b723f5ff6c874d6f72f7d8063f46a552ca602960fe0a944e35ef5ca1ea435174f39d31f42b7095c760a93079df378993b4d6b2816fad2b57cc46d3644995248022ef5fff0a1f06c342979f5a014bf8e943db52c3ca7b05c64cb13c5701123ab817299940fbbd559cf4765ce3ba5fdcc099815d6a653e70f37131137b35f2787eb642870824d8979ec3c3c35a4852dd35790d9e509280bd0c928daab021aa308840a2220fbc0410b0b30520a8b04f3674db17e935965aae7d1ad5cf7965493a15f752612a4e0bdc5330465a837b88b48b60f645280770e5504b770e32df91607394350927a58ba938f4a095ed340d61393b3a742ffcf22b2504300195a7677e5ca1062b9810efcc950a8e5e115f5013ca7fe742d801201508cda18703604caeb844582f5ce6fecca3f5b016753c270fa10adf9aa55f3421d2ef349f981df89631805ca4390524282fb7e22a76a08a94d378834361ca56f6df14ef3e20a016881cb756537e450e8596c9c63d413412147fa047de75c5f5c5db16e5a12824977b31a45b9e16bdda807bc77401f3d13bd343a32bfde072636f58ca8eeeffb10e9bdf50ddaf80c28fa0c12f8509557719c9af000dde2328baca802a4609f85b4e749f2862601e4d3db922056539d23bb8766bb60f03acaaf3234ec4ec2f388f1cf2f3c4deb67a70ed3e5e7bc8cd230ebdadd928e8c8f3542e6ae85c627005e52af25a53f04034ea32174ed41f259d1fd1dbb02044b891dc01f6f0fc6301d4c6030ad5128e56305ed5a803b93d8e2cdde260f643108608081b85f3c6b0eaabebce06050141c413bbd59d13006c3a56a1c4c23db79602a0e3288fd4afe36247930d101db4a2e1ac4d07a984f14b6e041a8809217b37d9724b29659229b008f508cc085d903f239c38dc487c085bfa29be0cfb59e92b110a013fc654484f53fb6b9f72abe488a92812fdbb78883fced3eaa7b9cded4bd5546daaf6252f4bdeebbc5ca2c3491bd18949c571abbf6ddb567fdbea6f373cbf825c7bb46db5c28f7193ef89dbc34afafa79f63c09cff05a2bfe70c8edabb56eb5565a69a595d2c7e137aadcb6483759eb88c6a772dbe86fdbb6497c037efdedba0dddb6dfb61a6b3d31a99e7a3f4cf2e48829e9623fa05aeb1623dd8020c5f790a44b08a50569a33fb78dd4e16cef6d20fc893e9863254d8e17de1c3ae0ca4fb0e24a7f74e7df5bfa946bfa1951932fd205e3138c3f5fabb681eae7e17f39984f5d863f1c9dff70c8ed6107dfa83f1f6ef883b052dbd623e3a73e08c3fbe19824ede9875eba8844d67e1e14c2f5c7e7e9cf37ddd0976e475408447ff380a87fe38343f5f3893e1ffaa01a9a39fcb4615bffebd9fc188b46a22cd67cd1e6bd979eb2a96813515ebb7f48a594150a1b631bad77c61d99731d96279639803cd09f11e9edbcbc2558fac9fb9aa107e98db16824ca628d9f62ca63b1582c168b491b1b1147c6fc6444965de47ec2145eb9fb6d7bd9e20467bb3aaa60393904266ddfb97ee7da798cc598af6c10d69a86e136d5a67eb748da7c8cb128ab98f483e79abf186b183514733c368b3231e5b399cc4c46dac4548e99b49989383507c706898bf3f0cfa16356fa19ceb9f2884d4cc5582cc6aad7df3ce63070368333d1eb44a302abd53de631e9c2956cff41aefb44db367377776fa2dbde57be294a795162d2b5e5dec463e91e7a5bb5e92e3c02631d519a0c4324299cbfb17df7dff6426c1d16f9c996def4394afebb2fc9e17df0acbbf3b8c55d34b12c73b80bdc7dac9faee1a73e697b38832d90095ff1cff1e22cd804e4d4cf370c98c34f3e9f532b8e71f1333c474cc1990bdc11e5e1d98cf3b53ea7b7ee6b07573aacf720f21ee07f5036fb7eb645ce7a36f21eb2e0fa858ef6c1b30e1ded83fcfac37612916822d1322016cdc3fc866ac8f3bfae436e23f953c9f348c3985fad15bd504940ca29469e337afc096f62916f0a5d06b2fc557f870e81003302422b60b99fd2497fd2bf3177c8947a2c14cb979d11350c049d248ab39624f78a7691dc2de7a4e1a78edacbad46a7422cec6f4dc63967a4926a943eb454d3346a4fb651fdf4b5d932d62b914229232ec2c1e24586222827158ab6469858f91fcc32c2176dc6f50b1a77e85c8a2ca50da346564de5462758f8510155ca296915165af9b25bebe80e376ddbaac6993401522a61e1f7bfc434bafc8c78eab1344c3621266b74e91156849f608459f8b6f6e80840ab46a7945cec1c76348d00b91f42cf89e3b1cc10e9d143d3688fad23a522e6940a4a8585b40916beada12adb09167ecff420d2a3470f22334488f49821324384488f1e447af420d2a3079db24ad85a47fe0f5a96384e7f1ea87ca21f0ca14f00426b666666664665ea606666666686c8cc8c9c73ce29e5cc11b8b69c0a907000ae5b2007283f2cb743a249ee2a5a6a327c6fb140326c818527b9ab68814386ef1e8319bce4af4a61851019c0f2575bc8143c5c8ae0edbff03f55518326b27f4784cf9ec387c3aa98c2ea55692acd8cb1d56ab572b95cae8ec562f663cc5226280c65b5ec370220645018f2e4b4f77b69c876a64cf809fa53988829cb9f620ae3273a7f62ca628205d625f7f57e4674eeb1681f5960b5ffa8af44f719fedafbb5ffc9ec5bcb676fabecdd80380ab23aef913c5b8daf7c14c6837ff0ecd95c9b4c10f8db908d06fe06f39522f0b7d8666493f94accf0371b0f9514c657bee9a22c1813b4098a3797162c864df8a9e218fbdc6cc2f950e2cdc54f705b3961e37fdb2a7a17daceb11bd165ed399f43ac34ab98da9e68147c296a15197e1432fc55fce26a73358cd9e6e244fba9d17e708b5c511737e3662b1e3055580193218b9b71b3ee859bb15aae0ca3b35a5c78d8e0063d96a8c2f451863aa40eb90eed83af9c4020415e588180fc4196919a234de421586b9f33cb9b6b636dab0cbf0ea9655099a1f26a3f7d9a4ba63073e663baaa606116d388a8cfa3e04fd12a4bc487c60793e20e1517acbd0e23c2e70ed3a304386e6e6075c0c0b85c2e1b7cec7fecea79b8f070893f3fb8fee6822e2f4b90204c860f13539b8bc2482c65c4aebcb9a07d793c003338da324a8bc0b1e2015b42d6b31697972969f8ca77b2d1aa01c342ad5516890ca18818996beea067fabbe7d040f2f73a6c0b19c284902136c835b02d720b1132d3007784afbcdfe1f97e8fe73b4c9a3a423b54df364678233b3166783162681c3a3b086f64670d9d8234a097de570807cb028fc1073eac42572dd82f9421cbe75ae579fb4470cf6152779020757fa7f31cd6c17de775843c58f4ad42f1bcc93d89fe513c37244aa2df2afbf26fdae38dec541b51f2edbd8134f1c6e312dec80e6efcd56c3f849170a246e73d8f44f7a10f7d4be7398c44079328d07de8498d6b741f7a4fab3cb7555c47d8b153c37e87d48f04f79e0f5d528dcedbef47c289c6353ccf3d129db748d8ef3c67a525f5a3fc0e950c8550b08ed15b94d7613f8449bd43259fbbad420949397a2e4aa10614915eb69490d56abf61955ef2dd5db274186f512a893432d95f34b0171788a431bcf1939c790f3743de6ffc95e53be7e2725fbaa18f4ec0ce39d9c519fbf584331918e40689843713d2c41464d5c982c2ac40ab4ad0c585f4d0440a3d076f1a86fc08851b1354a0552da247f9267d7b24c734b8af40abb8272266a10a62e1cdcc5fe4cbd1cb6f7843a3845b5a449df235b84fb198d4efb846a8f3d6891aa0f73c129fef3c111ed07bbe55a12156cb34dc87ac8828b912dd16ae16b7552293100c431a3fc9b6f9dac67ebef33640ef790ef4b9de7af9b9a47e100ca959a4c6240ad8ff7c0dfbf93ce883e14cbef555ab3e37f409fb9f8fefe97cec07923c1d6a4527afbb1d735c697e6df0c155f67c0552a7a853d429ea3f8da2fe563f72c142a735e0b86e6b95d0f18afeee886ad8421295d041da5b03d7b71bc22bbaa5e87b6fc42262517f347db5a5af9e99813333940a1791d64c0fea04e8f547b7fad3ea1cdd8c0fb9926e5e19e377bc7b040e1b1f360ff12f115ae4186a54fcf8f06649238db2f48aa97b4fbccbb2b1f0515871066dc8f1e168369a8d66a359a3010732fa243506344ace64f92fe777012cd0dd018c5e462fa3970160e0444b01e74694f91109bf5cb6d95af288bbc9282c23d9bf731353255644ad62aaa445e76675e261c554894d449956a39788baacfad94ff4bdc97f27d1fc46b300b844942f913f8c24fb975831856d6209cd4df66f5162c162252b59f63f596118dc526213539809d32aa6b04bc443b207c9fe21fc3d1011f691fd412536b889ecff29b1c9f865755f7e920da1b956bcc4d4adf1cb8aa9242224d98f8c5eb2dfd76595b892128fa534c42b95686a2dd1945ea55769082c022bbd4a434a341c873e27ca9f185a01695e60118f45c331580ec1ca703926251dbcdbc9093d0975f0d6ecddce28de047a0c79be9602da30e4a3782cf3e9c414c5a48357ebae3331cb382505c3d80a26f1d612ce435445dc09776352be5e6795de9b38a6f41e960f56f6ef3c308fecc82aa6602ca2fc6160de224a622192ecb20ab44a5ea194d2c2136234bf8474d228ddbcde30e6d6e26689a1886bc18da2943325e57a8993258804d413c266ce73a56e6b40a324e4024431d1b0c19e015e214b27bc09789e429aa06a18f2358f657b9348f4842c775091a3370f7d929f726ba3e497ae266ad4f759e20e987aebd497bec2c155d4b5f058e2b72075dbddf226e372b9b6162dbcf8a394aeb260200c84a999e2d176b53c9a8de2c022f17d29c142f8025f523a92173fc5d46d9766ce957dd2bededa27edb9dbf5497b785150b35637eda156b794142f7ec945b7ddb9650a63c36de4552a79f14ddb95709563669296f3258fa57ec903c2337dee8620a2fcff7a31b22b8473ef904b73adb837e55e5844f97763d9bf44b724b2bf8b7a634c26172eace7941ba3a412e3c2441344d37c26997f2ffef580f02c9f0340c771200a2ba64c3328635b8d5e145161b0f03fd1a531b962ea5ae1a8159471ab681efc8d64bf45b2c97585348cebfd30b3c4f705063cbf45c9a30129192c7c3a06eb9debbb0c9f83b7baf058a29637edfbb4e1d6b0bc43fce4fff77a2c525293cb0424e596de24233d95f21afe8ce84c3226576483c96502429a9ff2257c8738cab1c965026292f9c8f99f50773d0befccd863892f162694515811e53de55b18fb5263e57ff6c52ee1274761c5d47d4594df174a0002e0b1d825a46c685ffce4d0330131c9f8c94d2e932bfbdb17bb8485f1782c11241a820058380216f28c52e22b0170e30bad8331292f6f8ccbab52509012004f889a29ccf3de2197c66389f8beee00e63b0cf9258f85fa4a48a3dbdce41637870be84c481b46005ee68e918f000673ce86e1944e147d3a6f0d8961f740e9ac4f484dbb515813f42ce38859fb56512a350d1fa1c1e6813e0e51cc54478ef1e573b3e35c27a4afc828289d73524ae79c933e7409e79c73523aa7e481cd76244609365d681bc8048481343636e0010861d9eb748740c64f0ebd1f3cc3210da31661a36de6734178dda4f111e5213fc12e546dbec7d16d58b9bc2c01c3e2d417352504d2fb19fede7f17ea5a0223ba904ddb70bebda11b05bf5510ba0abacb2162a1065b73c9cc9f0a728916cb27dfde0454d0f54785a2db4a25b66f6f8814e410cd27176693d00f81a3fe28c2cd8bafd3510d160bfbb54ddbd01c3f626b3d1650a3b44928d42113938f376d626282eb8f13930fddef73e84d6e85e2e3fd8a9035b0f5bf0d569b931a0e94fa0325765858f09f3e8365060dec778a10c7685a4dd3ff88f2b7afee16358d683b0807f8c967d0c0c29752ca214144227fb1014dca32dcfce0552aa69ffc0f3ebc01715dd9efff853c75d07d6507f8c11a82b876fcf95cbdb56b95d170dbf227961ea3da1d32fcae95d6ea27f7a731bec830768d821fa3c6052ab9608db0eaa602d7774624b296e296f2c5e7629523f43124b7c82dc4872c733ebbd168c2893717d43ad02ab7cb9a601f98e98acf155bf73d9fb422b54849908e405df62bcd8ed03e4c28c3a10cc79b0bf27084f661e24d090d831bc1467204db629b6bdb8269c3a6cec49938269f4c8c66edc31cc1a157485620ad482d89478e47a3d188d422ad482dd28ad422ad482d1209d6303e3052eb13fbc83e369f9bcfcc049bb50ff3e39b602638f4cab605536b73996026d8e632c14c2d53cbd432b526de62259a98cc26a6ba155d9db243e52acd4c2b136b66728929a96a97f5556e25ecb7b99a4483137f93d962db167ae503ebedb5d16cb02b18c9f1b96e4ed2fc13f73abcf7b00e51fe1daa8fd159aca3fb44a1ff627497347f878a7349131f5183f334b08e2076a8ea149cdfa1aa5370f325e550ca8942666832ccbef28d609f98afc42fd194ac88ff817d8af88ae758a2b1cff9193ef231841c7f54c4575c90e67377c579ee77fc0ca75ce7ae2c0d8b491e5c621351f12d87f35cc94d8ecff9c0849098e40f6f56ab3c9f6b912b18493ee75b057a0e4682f3a02fc148385183f3a0924702d42a79435082888acf5dcefdc4222a42affbd083be85f325dd2549fcf23bce87b08e120c72d101fa703b541ce792e477df674692df8156393e079324265180f3dcd79098c31f1d1cff51141a46fc0f8c593c7a8d6422ea032bcd4a342656fb30330581e34ab3ae34f34ab34e69569a75ac863f9188e28a053bff1bc994604a3031d5ad2ab1a80f57297e4926a66ce9d53e405ac47e3bb22cf222bb4c4b241a209828c49660251a3fc1171a9b9b982211c1798ef3362dcea3f492322bad621296c34e44134cc6f49179d1c062b214978f29c525e52505268595d272c572fccf0423c54832920d89344b5945252c09d63eb44856e8950f1cfa048b290efe7cf79fdd6187fc915a5ead9db59c488447b01c3f7e660d233e4d822dc1626a872a7ee9a644538ac5fe44259a1c393fc31d8f681a86cc42fcc1914c8e26d8c7184fd9048ba9ad4afc556b376c82e5c8c19b0f0bf353113f7d627e8a1f98ed2cb33fe9038ba8f8317e60f10373b1d2fc24038e6b5b02293f6261e5732da594dfdd133a156cd4d4d4844166230c3535ddb365ffbcd54fd24f3309ae3b0142a430e2e39f868a4c25c7bf319f4e110486a1a10b86a1a10bda409bca9286d08bdc52a54f50aa3810a76c821cd97f864f1770418814418448c123c61823fc18a10733a0e1913f4ec6a3a53d50d52fbeee253b84f0e5324134adeb73b5d65a6badfdfeb94c0bdb2245b605caa8142dd60c5c645a32a049b54a89231fc7cafe71adecc357ba883f57c31d89a95344d92370d8cc41f19d78bcf2e73232dddceceae5e69c946a9aa6458fa54e0f088d6be8b1dbe5cf708d03d2c2b638a161cec5c9780f9ccc25f3154dabb1719b23359ac8769acd911a91ed34ed67b8c8769aa6699aa6695a85c26a9aa675c3e8567dce43fcd5e7de5bfc450737e42ab3fdf69ccb5720f6979f5abeb261f85a82e56431d52f594cb94c73328d937132a86197818d6914f6e3aa7519b7e9baefb08e8e93916a747478dff93819fc2ea94627daa1fa88f2ee3efd430b797912111def3bdf2a52e7381c3ebc371a9384e064f89c0cbf6f544c825f310a3cdfe8872c50bb9cdcb785d46096bddbaaeeb60ade1270484474efbd8791f07c4784e77dabdab341aad1d1c1b938194fc66c7860a41a9e0eee853957447987254c8602b1f408f67319195f40f72ee3af6e462c5ad3f017a7cb08f673994ea6c35526a260dff8dce5dced56fc7166d97df8c9886a93db6ff217a38770352e45a3fcab784581c6add0aa97cb7036329996ec0736468ccf6562e4974c101f7285fda0cfb28cbfcbd01bfbc58891fa156c8fc2762f2e88d083178624c16348122d51542872953ab0e6f1586c82983ddf699de7acb59d0970d9627bad7dcb0267447be1b7c7d2e13c77c39aa6c14f66f85fa771d93d166e46f4dccef0e5b5cfc12e722ec87a3706e5b9e8dd0f8e41f9ce9f5cd14394b7d7dab71f63d23d08c79c3c07c788b0cbab50703baabb1ddbc19d8873411fbaf03fd7fbf680e840a087dffd0fa0e7e098133cc3bd1b6382a5a3ec8742b7fbcf8d31799089c9958e7aa16ddc850f9307905b48136e843401460815438450d1e2388ee3f00bf7d005cae8cc61c8437a9efb64e6fe931807fe208f1f60ee70f8eb3efee7b90f5dd087be65e6debfbbcc7d9e7b4ed785f027b3e76fd897b9c3374a70674497edc7ff8ce8a40ca00c10be21df1ba2f37cba97f886b51dfe208fcc7dcb00f2c07d47db24bc24e8f20df8ee7518deaffb21bec96d71c2eb2077b5879af6cd2397784746b16858eb734a7e0ba13ccae84fdea4c57b9eb3d7bee77eec8b6ebae7dedeee39f7c39139ed0df1790f2679efe1381008933c1c446712e96f80de7b12e8bd077927fbf639dfb91f8eccbdfd3a3f3df7037a8ff79ee76ae7b99f6f4f08eeede71d933af8013bb28749dedfe07ce73dce773c33a2fd3adfa3e78cdefe077a1280d976a30ed71f96c3a3b7f8c6e839f886e8ad1123dc7e42f90fee6f6102df8a50422fdfe2efc4c4c4f372fbf62210fa15e4cdf3f6397bb7cfdb6df3fce76d687bb96d9effc80ddaf7d8920d97bc2cf9ed96bc7d8b3fbbbd7cfbdac501f3862116963404cc9f87f9f31edc3dc4242120e706e7eb077ee57cadcff1dc0f47f68040b8f3d67eca6d47d99f11ededde733f233aeea200e6cf7f1e7ebee28ff31fe83d60c7e7fac7f13ed8fbce05bde7726fefd765fb9dbfe179ee3b9ee7de63bff320ebd9de8f7beafd87f4f91bf63dffc1150a4b12c2bee72d6e3f797007771ebec179f871d8882e7370fd6e7abfc7216307e18e91775adca39c54eb20ecffb4dcff0d20774d133e8040155091115ba445466011d9f4fb449fd20d4420d222e0102b28a514c68792c3e1702894f1e1662557e9c7539fe8bc0ee8633d5c95f489182a2a1dfe4e5e257c65afafae61c25a6bfdc61306ae5f7c127a475fecd7b0eebebf1681315fa92df96b184c44f372958872cfa7aa934f58f8fe9026d2e0bcc358c3f2bb3b3cb9cd09b662ca6922aa158b38ca5ff4b23234ae166cc5701b98cd8af6ac88f25464f9c436d693382ba6221247794c92ddc69b08db302cc2228eb027f2ac025402421bac400d396e12431e59891564e1345124b296c70a9078abd5ea23792e1184d6335c4545854666b3964ab9f27c6cf81dd223f653f15741400c3458aa5d07d02b83a0147fdacfa0403800015085da9cb521e00c07f86faf92b78b0047fd29c2cee05c13d9614baefea83f628c31c618e9431a65e5745a8ef5478caf570c994f73c5205be57437d4a7f89e2b6a54f7f07d8e7103999e5ce4a9036278866e19a1e46438d060c81308393ef4c2102c6cef40a061cc1d50e4f85073d15c3417cdc50a2039fe0e35727c2829a554b6e7e2bc8bb75535a6a44a1681ee01ce6d6e2a06dbafc1b206fba40700521bfb12518e801809f0152ea5f4ffb5aca3b50ff2e5651487dcefb58cd10cf2e011f6ebbe3c6572f15fc73cdbf76f1c28836aa5fb825911fefb82f7058016b775270814116131b67dbfa4b1427b458dc6573cdfe2c4119e135c675bc922b9bb3312a43b379e0a635971055bf5884522ea241e1a1e1126b2095879c0531e168d98f2c022ca531e5944d95544791fbd1f3afbb22a5995d89cac4e5e3c3e3c75e25abdac2a101be4f30c39819dc84e6e505e602c91c85acf106672ddd70b85f5f2329acd5c27b217d10b8beb80e44a2c7dca7f3172ef90fb8516f2d47da55c0ee7613c49e22958c45d1f4a4bbe91a0ae7dc52b955264e64c68400f088fd65329ffc253a6ef6f93124c2ec883c90565dc17e4c1df74e1111b3fc9eeeb879923d6f2bc461c55032fbcf17e9819c2684eb93006651568d5ccd463999c76d2a2298437019b39584223ae0fc26eecbe600dbc82c41026458b5137aa3fec94c19b3c9ad94ffb3061b655c919b26f2da3c406f2e0746eab98da1a25b516dbcbe6a2fde7f92bb1c11d7019234cfe9a66755f53755f6690db6a5b6dab6d25800c4c8d4e4f08392f0dbdaf2558aaf9ec345a623befa2a0664a51582fa3979713574c955e2bd14b8b97d1c98bebc465e2cafe27b0982ac96431553ab98929d30ae525a64cac10ac447672634f6e32cacb91fc995c494a2f318561a5574c61572cbd8c700b968825537ad1647f93d28bc5c3461653b80947ddc4147e89f788876430d9bfe4a625fb67755f45605650564cddd827f1d4bd2cd1129687b35ab25b913f2f92bd74dd0a47bd4098111300b40020e327074090ec6528030f1430dd01842eebb22e2be445c005f58428ac8809e792fa245ddcd700b2bc05b080097782ced55290e39b3428333333334d9f88a22316dd06233333333357442c9a3e11652a1f5844c1d8ef74da01c472d77cc0550c7cf4ab574834b2cc2dd0856aa1d60702c73d775baaf760bd07d971b7c5093aa7e520febaf673defbb74e4a6c3bcaf910560849f1613e62661c324ff9527e272756396dc17e273ae5941990ab2fc669079719e7285a86e8d0dd6574181dc809a6d29d5c5ed97f87eebe5f684bd8cf30ca6f5b6b4c9d2a3e82057ee59c6ac5a37efa35fce4ffda7ffd1c4cc34fde8d6dd4b0c1719c6b8346671a357ca53b731e0476b03426d587f99b197e8cde0576a838b533bc9d83f015da031cdc8c21fb6b9ec722633abc83a3fce4ff9d5a6219119796eeee6ed8f08ad69cba639843d3016da0c6a240802e884208d797b4cace51e91772ab20980c628160402c1013332018d01545540b08c67b70960c2c88c5f98980ec3b8058bee21004036281604e0e82d95cbe0262814030f903c158102b46c3f087f11598822abf821dc13697c7b66fcd82607ce5db40302026602d6b183fc3b9f6218e2a0d4dfe2cfe2aecb3b158fe6cd63008e603c15438b40d62901d6f2c68f9b87c561f9b8df58160461f0826d66e636d4d9056de8a8a9aef179f7cd9f9be1271cb15e37f3bf2843e28ad55d3344aa91663d4b4a7570bc1969f5cd64ffe138bfce4822e3fb572c410ba600baada5dd99de5a814280366990fb6a2ab65453e2c0c96c8fea1147f7a85fd2c6cd99c92406490ecad596eecbac27eeed294902e577441181713b5dbe8f0965ac17e7faa914b64992f84b032a1fea84ca84ce8ee8635b8158afaa3036b50a1a850404803d8f28257c597ef3d780ffe9088fdaa8a54f9b707a915ec573f5a045459f6ef4256e8aaa684fd5410d0d29b10573de405adecbf81aef1be5f7cd165c34fbedd0fe60e56e81e63d75d8f651a11b2c1e122e22aba64c17e1d5be58ed950c9f8340a1b5371153bb93ca9c6c7f39fb88a2b8edbace7926a78449eedb78fe73fdf2ace7f76dbb66deb36ee72f2e6b9adf23898b47d7b1809fbf9fce7a462838871ea60bfe9d8e9e17d11573622cabfe2155d4d18b301618cb3e10bf0de7f0345d828c28bae1ecccccccccc5c19442a406a8422b82048d3364471af0b5c7a86088451dc22f4901626eebdf7f60c11088520747777774cc74018d3313130a6bbbbbbbb63ba3b06c6c47477c7c4c440d8dddded73e8763974b727e9eeee6e9f83cc42145d7fccac78d7cc4028789228baeb8f22f49016acba7f603feb82289278e289fcd6a916b5f9da8cf3caa74fe99cf8a3af3da7cd39e9b4796a9aa65119d3826e81566bad5a370fe2cdcbebbc6031c61855f49c5471b1f36e9492c5bbae92707af3a3063f4eeab0e39c1d2fae684bc017cd8b86868686c665a0ab25237ab12eab58f77af98af6db2aa6e24b64bdb84856cc1dc9ed9ad7911796644d962cbee64bbeb45715a00dd4c0695de424e4e132db26b3c96c3248b877181818983eb263892dca8fdbf6db6f2f73b2b1d51c59ca78d3c922de340b58d049d41f49c8e24d5ba9fdf612ce87d5037105e2287771aa8c772f3de5f9ee56193f7975018935b56b2fc6fa5a756d38caa4cb572a105f89321543bb7d8c51cae97575b95cae5a356d63d18ad4d8d6795116515e637e8255582d12651e9675b8d622310f512bcc57b422be22631cfe20d4b09412e6ead52caaabbaaaabbaea06aa6481adb20e0d47b5bac9464dd18b7ad66db65569953c6968271bf48bf87edd682b6dd5b71d0eb0071c12e3d71af890ab71ca0dde7c6c859e4d24f1e7c377aab21d546280a626b349b8dc9dcb3d07476c23ec3c9ebbb96462f4c4283bf339d0941d4ffc541994016f3e771bf2f2934c44b9e4dd7cc01b286333c28604a86579b7d6e6c351401c15c44faf8d666bcd4b7367c681fed42c07dabc09d82c5b119504ca802fc883dbfc6d3689cc4fb17939b7d3a7f9f582fa349fdb5abe72d2271fa40f84b2d68aa99346bd04206382aff91103597e84af358525a10f0dcff77f227bca26a0127853c350659007a71c849ebbb5f818a0caead72a7b292564227fdb119badb5c96c345bacf3ca5e22a3c0ac8367cfa5279d3cff63ca33039082ae0f254f20b26309269700a103f8f083bda30f260011597240798e40c04101edd37c0d4afa333c64128ba8f05f50551d9718aacebfa0aa3cffd9232de3e891fc7178b8f8c9e9dd7cf84906d3818b48f2c769e1acfce432add61c5a9c4ce396a594354f383fd286319f424ce7e7b5b9228a7a4250b8cd5caacaf39ddbf282182acfbb54d5674bd292fd6b9555a055496cfc6fd3b4e72a7d6ae2753a78bd61cca737ce6dfed69a9eaedaae7eba3a3fca8f13d4d52b4b3ad7e7fc283f863ef3edfc4d093055655b2ba660acce3622db13b629b6d6fc283f56383f5695c752bf8a44b1ca8ff3b5ce7ccf84b109e747f9d1a4b7ce56b71319b7cedb90c9570a3d9f926ff88a8570cce218b4f6b5a72a25defcd0d681ad50c89b6f22214ce7e585b36593a865886b0d8ac742df57b8df24bc9154fae0266e37b544d2c97dacb418f240c1cc271e748128dd89371fa56e1aa7a2a078f3453373629123b369d189bcf92db4ae5e99e3a604372d44228f657b91a45ac92d02e47d67c3eb90b8bf780f9f2bd24674e4cd277940b8c71273b29d191a2591ba148f657e8adc38ce8d8912c7789ede23649dd92c1ac61a9a077f5865b5cade50a2ff41f1686c2d39d038d09fdaa8fed85a5d9cf1d6161e8b1c8d62ac185e3883483c168a4955566b3ad7f3d526d57959ad214588c451295d8c31ca275559c4a22aab35d526d2ae23a57077ce0863b44a1a3ff97487b198ba29d51a3fd9a4782c145759954d9237441de22bd457a4af44cc7962a494ca98e2b55f59bad1143b3f3b3fbd51f35d7842d4ac3da7d10b91cc6e2e7dd7be61cc476941e7a7f3206620e99c534a49e76c2173524ae79c94523a29923929a574ce1f541b2b502d62a17dac1fe9c71863fc0aabb198f27c94c58ff143395238c418e97b4c9dd98f9e0bdb001cecbcce7706e05491bb7f021530723ec618a33562657ed2b08d597048b8be2eba26015e171db1e8fac30db40d9066d17d5d381d281248b3e8a66ca83fe81a642e8419c002a379a8c46cd67649eb18cd00000010004315000028140c878462b1489467b2d0b50714000e819e4e74569888a320c76118858c31861062083184800c88c8106d15463e259f5826066045300c43d65714003a3958b1486cc1a53735c3d1c2edfe67f43bc6137f95cd251794ebe10544e284e79bbe01753c68ab569dc0db99c64d508a32412b39844c3062702ec66e348a4cbcb01730b8a4a1c2f5d619645ed57e73927574473de0ed05b364632b02002c32dbbf5bb0a6ae67dee922c56e4f63d191fbfb7364c18b9c0fc47c6e318a96a13d54a0826d78e7155a9517aedd0ab330a66229292937e07eedccb244276f6d6cc3494ccf65bc2bb1a3635049301fe44d627dd30c1e8794602939871e9076e78ef3c0e013bea47a59721f80d033621b8ecace0e18365d13259e831cb0f2e3263b5a7a5ff639f08ad2fe2d274ebdeacc9756afbd2abd2fb4a8ce92a3803c056351fd345f411847a937e286c9a1663144c383bfc07cd1b3001069ef4424c0e1de7ca1ca8e402aaf903d980b8328fe212622a882bf41600276fbc2b7a0e43ca0f62c2d0fa322a45027e8d2cc9029486ee4603ec1fbc9a5b492e55473c2e3396949edb9d318c737641f9e42b7fcba4f849fc1ff9b3fa4524bbcfaaaa3d4abe21252268f68291f25a8a0f7dab49112d1223e7bafee0c111cead628dc5115c5697eda0ca62639f9880a88df3b78eda02a695b37a5e207762a7c9b070f547d58fe5306beaaef4b5319f7dc0c220a344322fa743de066a2d1982b6e25f25ca596556f98a29e806adc42c9abee3a2a7f82ed1245f78894e826b90bd6579f5206ac95576cca7fc973478dffdc11637c7d62c5afa38861d27a52c4058930e40618f9a34a56923f18cfe56e30eb83bb8cb57849efa799b9248526fafea8364a51642f54cc44efe093788ede2ab2ba97778ba31d154bd3eb43818c6b3c91e558652874d41103821d4550159062840976efe45a2aa28ad9e4930963461f5f08f089083c59208969bcc1610439fcbde7a0fbbbe29c371cb55b93c4f7babd69fa7a39ded572cd5cfe0f549c0a279440101665cc45cd9b319d688025fb4d947b0946f8c963ece6989b1f7cf3b43f7f29e73a32690f53c6cc18b1464567b2dcf94e0503a154428d41dfa318e6ba8973966d9e09e1cbabb17ebd2157e4098fcc87ee647ff8b78de8573186bbe59e3c559454179ad8e14e4b48e7c4a8917c46c49482972576869be8c8799781b27653d1a5185ef03cf760c8f17aa020f3a94ea0f97931dac908514af49b4e789460de08b7d296dce3189802aed4e05e63953ef443561670887a70392be3841af4f809316098f163ad8fccb3341d08d4597aad55b29cf951bb06b27b88f0aa4083ff86a0e9beb162373d1505ae3c33bf37f2adccd3793a1166c5031ffd135cc6818177297290ced5d781e86ecb21c516a16da4150eb13691569f9c362c1c62ef24f8fa655be6c221508e3a6c7ce8cd9772493c7c575d1991010717471c66409bbe04323b252a28f6945d380411419a6ec1e639f82934bfc6017a99bfa90dabb319809ddfbc02df3e25271d7c30c32124fe896e306d4afc85972f75f5ab0d87f0c7ab0d0a2fabbe71b9f2a4788fc2e3ba43f2cce705b8df6f38848e86070ed9d6d8325b3b391c607cf3f50adc0c01075fe87008e4b8b52048a0e95f54a827eee1105dfa0d48589dfd6644c7bfe093d5d2090f3ee489378d40d8ed4a2feed44e870acd7f4a97c96bcbfc0e4a2c124ecba13939e3cd2093d8eccb75214387940dda823f39a2a567ccf81c484812d0ae28c08550c122bada12f70e9f968a2555ae63537b033ef52f94b683ff747588bd2c150527caf52e620f99b91448d6162a57856eb75b775cdc40fd8789dc152ec1f5018a278b6b793c9447725a21fb737b637303d5d5d5befd8dd3363aa37ec5288986982e02c13875314a16bfd5b210609404df1f2d4013e5beea1d9ee5035ea54b8d01eb4fcad4f394c746846fe6eeabf68d238519f8725051af971aff0a5a707d6a6eee318d132e6bc19548a640552e89675002c4ce72d86b14c013515631d384b05ea9748e9e546ab2704aa805b44f4a02c5c66acf539e108fcf9f723fab9b52e1c3b1c1a3f765a29f34a0a01cb92b22f48d82805103d2d7da99434a627d5a5506b960284070ff2e654119f02d724849c8f1712ee2c7a54c10ea1ba0b2841e7262414aa2b1a26a1f50e1a86165f2ac60cad3b688632dd9c0c7518b082b1d6c950d88478a233da6edbb6fef94ce0ca86ee0c216bc92ab84abb032b48d7aa042f0a120bec78b5675f03f34c6cd57063c4dd4d2d2b5f559ead5f699444866cb2b9b5ec785f9b4c412acf4b0e2d4e6b05b0f94b2c1f11495b5797b9114f3ff8716e3f043198cc0ef2070f37fa38e29a3589f6ca0bdda18c1a5a5e0f502623743b9e9a9ba84b590742fde7439c1252dc9193e8102d5850ef5e1bcd715f589aa71a7f505451111660402b57c9050efe18b1ada71ba047c3877c50249e89ece91db40c12549631e35c8351c6a091a48311880decdaf839e0017ba2876770ebe50b057e383eb2b3383ad5e23a23327805e7ac451ca509542661ea82d45bfd5ac3480fe5ed4815e4ca3a36756345045f45f5a1a1dd2246d1456565e3c192a287ab130f47267fcecf52eeebe16f003b57263e65492e276156e382825302af161d60db5842ef711c60bf3bc59765650920913359057ddf432d62d9dcc254621d22587d36e020e6e1e053783016b5125cfbdf86c3536865a427c6d5dc4f9f808d30940fa73fc32225d0dfda17000ab89b2322801803cfcb9dbfd02e72f4a6028ddc75b33b1e0b79ab8f339499b19a9b8ec25b8c40460aa2110882417130e86070d45f683f11325f7b5df2a0ff8390e51d4eadc5e3a4557836caf8ec446f20213fe65e4720435a373479a9d00e019a1b2c4c769cc9c574c89cdf152fb1720b9844815812215eaea21261a4fa8529d4951686b12a6a662046571f6001c4c759a89e0bcc6cd395e3c2bffcbb0b0c427f346092c882e9ddaa149d185b3700caa6f05fae1d3e41391df50ac72ae994de4f99f14cd0a9f3821afce23358ba3b38c53b0f5189cd85c75e6b8e78964896b78e69d41ca0541d7b04eb38c3e8c3c3156c721f608f717cfb9b67e9113577fc7198706feef6a9421e802c5c09ab33d0eda1d49924d76c659776271ba83ba799e7fc699a242800f0e051bd9af760b32e3e9c065679ca81032026dfdd673eda608ab905d0ac621aa27f16b79e2a84ddf582100e34c6297b9fd078f40568c03cfc339f4501799e2806965192755598d8ae41c4167ae55d57346f8778f8726d78e755dd1ffaa8813f61fed1014757b50266cc44923a2f5c08483b29930aacc2ecce09ff4d2a7310e28331e3eb9198734b9b84f5d6ab969b7c7c8d5c1dc4c61ab4b58c13d8aaa202fc19da1cd563e5798d3cb9526b1c0f5bc021045e1778c9a0f388214884b88671be6028841d62943491de57055e506f47dd7896e18a0da10e05a23983a73974a0c5634c19fede14cf70636dbf36e68d47de611d84086b8850eb88cf417e8c2fffb07ba047bef02f404ad81f1ff7c03698c0ea8073e3c9162855cef4ebdf2e52f5854f516178e7364fc3ecc39d03e307c74a0c85ee9c0d3263a55cf503d035d867e88c9cadfa233d78389e5d6498f0bbde06e02d481ca9f74f30e56807ef2b18cb2b7d203c14707e6b783f6c892281134402bb07cef252a54f67262d945934136ea1ac4258a7a6efbc61c8ee1533a9487cbce2f02eb798c8cefdd128eb78f52744a529d2db1723db632161405adf9b8cc9e37883d571e0704388d599578a1a45df8db736c20403fcc57818d2b2d74edd1799d7f8b0677cc3f02e21231739d327234c100093ccd874c20cd7202b3d1eb2f69bddb40ef611097782f0644c464c74c12580957122101f91300092d409487c0bf33dc4b380d94fb3c1a6e09f17fc45c74bda9bea6dfd8a2828915e2d01f60fd1ffe469149de7f404b701002719c56864da0c5d0ac2397cafb8ff2eab60913ad27507343c0fa415cf553520b48bb11a3aefce794d4dfbfbd73c36ad87e1cc5f6f4a0f83594aa2c8db8226445d1085d519828fb894a94f07a38806b7ec09452511320b49d911fe1fa1114b8a26e4fd28f991045fc7d1d86e9edcb0057b78678eb6023799e8cc970f1bfbeffb3a2f1e3c0dfaa9c97855fe008384d0623e952d55e7eef366398c1c6cc93db88dc37d9a15138cca0d16ef45e62e2fbaece00f33d17f28601c0f073c1c0fa42e4ad98f3f67f4a91841d5b752d1b25821315c03487170ec0f7f88ce06135d85b64ac5250ceb13f76ac83f1dbb6012a265de05b9528a8056a16480df9c6467ca5229fca13ac05b91af4bd06ec487ec381e9907cf3513a183a259242c08e7f136d45279b02c97f1cbfd85a14b98cb9dd034d02bff2171ba98c6222e77ed1e5f1d112c1c26f4e7242f2d3e9a1a4ea7bd040a11e2ada510436737143f2136d606fbb239b84b17c57af574002277eeb0bc9378ba8039dfc3d87dd9a52d599f8f05ef8df99919fdcb3387bbf96649a091fbcbfe16efe2ef8012c1f27144d73103955438512bf370a66a8977c4425ba6931f2e9f982cbf37338f47e7d3a3f88dbf93488e71f00231eba524d5569613838c2debe0b12a09c17092b3f8d879f0b2ec221533d0fe3cd0a1502353892a1d642173f97931a43c4e53906eaac8e411907a194b4ca20e7b8a67b6e620da68569da35d5e249cb75c8ed5f955c9bd872b6760180f7b936114135e4730cd57f407cb02221629dc6d0cbf2b55e6e36483483d96f15c91aebc08264490a103f808e4a4251372cb10ae73fecdbcb63c462da84cf2f0b5dd94d196559d7531b84ac26a48eecd29f755427cf3feeebc360385525e1243bcaae278fa20d0c5e8d138fece312a65186c3793d2ecff3f87b6d2db30fff2a5461f27f0eef79325ccb8a90e2a2ba64ea65e68ab6fd5325a039dc96864981a7d888da84a97a4ffb8ce29df4e4121eb09e456faefcbdf0785d0fed99008bab2d67a94d80e6baf8a2092d921d00be593de6298b875f978130eaf80d1a1002bacbd289684eb13e9827426c70e233941a1b22e667f1e912b4c8079e793d1571afcebbec52c9d2e77a67c166bd45eafa8d047fe48e4af0e9f36299d0d4f2d522d4f460b11cd1ca597ad634b1202250241ef087a1314d44ee94e594ef27393310b924888d25b072384cb70abfa9426507f5353fd92317ac37813a350d14df44bef1f423d089969c921ba9f46f2d0e6999a230043d285c44af3974ea9a1a2fa326f87311cdf60748536134724f3c9f008d9efb0788b85b8c5b82136f3585691d35e1ac291c82fea8e80e9629ae948ff7267d8c9367cc2ec9c0427f3e6c004bd01ebf3c2d1cab0d87df5a84311d1edac6bee6f74cf5f59e1b7e9810323b442aaac7f81bb688252e8680eaa5756e0c89759b1c1fd87163cc8438e16f61605a2aaad8742685b08c43c2152912e7c8579d5a575a1b34a7c1f561f68e4e53583bb388e19b597afa93f12532651527ef5673b5938a9dce4c95ae76fd714ee90ed4ab820507e771ba45a434d1a7ee4667e4e4a0af036f16c01b3d7c99c89be093cdd05ef6e8ed5b81ad7910c079b5923abd47acabd13da76186d48fc4c9009c9c8d5bedc52056f4407fad69ca1d62c4366abc392c6cbe28eca11983fd16186462b167fe9d684b4e9cc8654d5bb2db437e28d30e231a569523a19131e0196fb6812d731179504be813a4ffe52db140fdf6260b1c9e32de1c3fa28af15ee060a2887d106462d290e080d9f3bbc32c30776a02a2ba25abe6ea6c687f84aef9d6e8b7bef4a81cffc4b498aa270493c29da3014de0a0f3d0deb73367d70acdf4c256e8543dd26fabc6aff139ecb8223fb4ef8a47200094a20be8b8a4baf650893d398b01744b834be0218bed740fed1b322a50c583c54daa3bf981a11d39aab98a39aa280a505401ed743e930a328f2787972929d05eeb7f8bcbdce3314f9ef95ea017d2e3d7b5421c8aae21d741519f080b27218e682be1b099c84c8f8d8f2e17df71bb56afc677fcf35dbdb9eb29d104fb7660f632363d20ad45a88d77b8de8b88f004bf9db456233ed0399e8ecff25b6ad04e262f90d0417058301254f0bda37478c204320e67b6bfdb184d4812d0cfeb52658839ea15555010f61f612126f4424b986725582dd092c8754bcb3a088306284a8131fcd7e8024ed4f02d6bb0941f6df21a6c0a9771f985c47d1164689b2bbda40172f7c9db88556be337f1536bf3c889c211921824964b7ba6ddaa8c3688852e716a92ce08e30a8d9108ca28dd75d80f48983792464ea86db25bd399cb1354e4b956a0365ef26902ef833441f3956972832678625730fbca6a2e7182a21f4b69edf08f06b316a5866e9e8b4a773ef4c385a9b1f871e3b18fbef9f91eacf5ce911397ff630d4aa0b7e0b4d1e94b54a847b35e60039c67471cadfd7c414b2a4f666770a84eaf3007b3821379a299e5c0bc7aed20bfbd902bb71e5e07c2d74c1b954ee5460dac52be235947e989833dda09fe808d42e74f33218d445f83f131e6c0748feab73433bb3cc97eb2bfd3f4d8fba8fdc8b8e055b1ba6eebcba066376c3b9a6a2854c80fc8beb32907bffe2f058b7e8f2a8c9472dae0d48c6725045c18195b4c9500b390823604f93bc15f027d5f0bc48746919fc9fd037f313440a089073a78779b1307e104e439beaaebab2e3d34862a64a3fa8c2628f306cb0362372975ffbd41103ef0121d7cd57b098865ea25cdda90a9182af71d0658c1d8a962973a5003501520b4fe53880dc5a72f2a3dd8357df9068d03b47c172269610044b1ea91589a3c8a265becba0284bb263592263e323ddd02c4a239665ebddfd5691c5ea7377067bd2b3aa0b988b7709055189249642d405cc31bca22fa3878f583ebf7ce7a72a4ba3260c043092de92135a3934921cc8e0588b0096a16ce4cb18b53e98a155401c20ad90c4f38e80a10d691e5a1c494a8897f1b47cfc8a94dddc1131f529f95d733561611a0a440f13696b2afc42bfd8c3898c0152e627541408444f66370da6863c20fecb9c117cfd320e6f44a286ef894d798d3d082b574bb125f7cea8f398a1463d3b3584c09fcd9c8566a0fd44dae361410d3459dcfa133416446f4683986e6d64b28f8b99b4ea51054af21b473aa96a9347fba0b304f04539d71b45d984740300aead0b4479f11af476711c7e8b261bcd40cb98111ee6e9a38d0b5e37268440671d1cf5aaa2b89a14a32ff35adc98442a4af761eb2bf7c13b88e573c59623b461b752883aab51c9ed70e3882804993094529a3d3f77adaf652292e7dd7e7c44acaa9d243ea3ea0177988b494292cdfc14dbbd8d4e054716f9eed50918f26a96ba1940da9c99da1e1e5f806ad805253a72d927f90e14c85410f8a808473224de2b4db02d5158eec028ab2429484b4bc7f14ee02417409a0f01154542b34e18883d7d7129159700c7b9a2a34c9e0561b609b87d87041aedf82d01863b4a21bb96340ce62227e395676ca2547c00a9109e8492dd5c07fc0850b26658442d1f2dd3a81146bb4a9ec2b17f9db138e3a78e9e889536c3f9c25446a328353e2ac08de73010d6df8fce883a3354363ce87456c79fd4489413627374823108524a37d208267bc19b8b5d099b12539a539606ec4f19eee4fadb74dc1037a342ab74890ca0ba26e949d5388725042c1a550508919836ea8b26156184039417313c8ae42928718116c8f1d79104279c8b34dfa73c72ea3b07a4c20aed29866018f758473dd4924194a03adddec9351d0bcdb346bac49d8dddd57009a8f0a6029345df120389aecd47062ebdbc5bab05c3b3cb78a1c5e1701f3f50463de472832349de892dd45f1602b99489b8a687ddb60de110d15f59357d9a6e05732468e86d428d6b011a9ccd74a3009b60d30f734605cdb14a2779ddbd310b540c071b4c8187bdaf479c721e81dc1c36e94e27d9d382692855bde3b6d093a5c4bec76252f61ddd9986d780e88ba422b18acad7def258ed1c549a40838ba92e742bb7a3e97a80b4a115741121792f5fdf83a520fee338aba8f70fb9fe1135c64c90dc59764a7e7cfcd77246096a9af6b5dfc02c12ce6982083fb6d266ec05dc8aa68b829a89214d9519c076add89bc46ea928aacc66845d5c8cde027e497ef8e5b42954e212780dc5e6d0ab3ff6088f62b1751dd882fca3fe5882e734628fa9251bd60f8d47517b3a288210a4565fe2e64f4e81763e4841f8ae09661109175bd6b680529ba50a65099af25b286efb60a4b73f2dd277a110559436e5b7c28bb46b3cc61c0fca4439fc315d22e28d50c1b03dd147c52bcd8af2da228df9911cbbb91be081c9f54109aaab84b5310011fbf83b5d65018f543581953eeca3f2480e2099dd5d8227a3803566b301eb629500b495d0384d87f5ec65a3570400b0c27930ebdc88297d11a1e23919b4211c484d00e840d8d7b4fc708acc1146e5440c50783b8113cf542d24b647e00e34a4bebde98794563746dd5a9e12622632a2ba0d8eb755d0d7332f9e27a84d93f69c026f950f10344e05196aa81d248db682b22211ec518fd81c00f205f136cd7338536d71717f147411f771f6b0a592814a162ae56cf14ce83d2413611651feca7a2418cdbe80047d70aeb99c2f1b09fb0e0b53e229310726d98de9afdf64e6afb261f6f0f774b030c1a63f9e6479f296ae24e2526a59dd1dc8e32f9b0887c15c4d8a36d67a05fc0b8151059d892667f163d7e0d50d0146e0af3e9c74ea413d01405705d60472592fe5fe0ed30fd4ce1a4533c092c1e28ff2093eb3b284448d73e6e22270c345903fcaad17ae6b406922a24759de0401befcff613add22c332649d0ebcd3e0ecdf339b48d634b6dc4d201f4d5fcf41e24bdd6286bf4f8236f90c7ea0480ee36f65133cfde4b4c686cff9f8191840d3a142130db4c8c25d014f4e92aa9760d91d69c6e88b12051d86bceccbf07957171f809b6644e8d8f2d46c9bf5557a73425f4b12d6056079fa4d4b6030c4bb3b6295097379baeedc2c15dd175b5395892a8baf18c5ee06601a6d83ffbe7e3044db86656edab2b3a85841af0ef5f9b1d965e5f51cd0f8d753d5bd54c8bf353a06af8564f6bec9655cc1e4ffc00d269ba1525d32caa2b87ec9688eac977b7fd2ffac83b1aabd78590001e89b5d29d5cd0224325ea49f21dc17688d1fa6487271c4f08816613331bb458e6484d919abd33e6ebe64dd28b2524e6053abef447b59fd764c072fb2b02fcdb5439f9d6660b3e9ca6b82c84134232a1674b7edf6e56bd441d8d085e53b805f636ad3cdca9e780010ad41aaa89a121808c8e5ad2b218924ed1ed3b1dfe6d84ab95017429832054ee55a12d5e5314248dc26ea364cc0ca5a7215f4c3cfe0cc91063117faa7862474db230311ed5fb12623398f076a8664d1896e34c4c73e3350527999da5d567e08ed1a8eae0ec78f25fe1931ecbf03a8b8dadf02c31aa25faf58653489e093f36954b0478c4acf421d6414c82d18f9a44ee37a24112ec910d8b0c097faf6a728ac8d711908c487be180298060e723f30848d471570aa0ae47e1f0b61cc81830cf25525a95eb228e4227dca0155dcf0f8654e22fa7f65e9d4e48daf017fe0b5cb11820b0c4060bbe961cb42510535246d26f9693a10772de435158685b7c8e963334e5a65de48fa7e8febb1f2335835a72eeb9cf66ea805bb0420e325bfc3113cd78b3c3adf17550e32d1cebec08d07b56d51526a216ac449ac0fbf76e201e9b46bd4df169760efc4d4d5120eb984547cb6d33f7fe2044dc351b301e1af3c099e31784b6daea51b053592587745013c42f7498f015b7ee92534a5c3c305c4e152ceb039296a602e19c8f8fa7e14c0fb89fc23b77dcc6ec27f13262aeeb6d02c54d97aa5c8a64888809374b6f52882179dca4e052f1385d65e8499b5210101cd3d0ae3ddfc07d83efc8f6787da9b488d35324c09dca3e5a0f3a1d141ddd77e2c19d58b153739ac5607992c8097d621ffb934b0164edaa4cb0ec32c361cf8bb1f1c6fee8ae8e78f09d9b4bf76419522274826d73ce4b98764fe6cc9fd78e2c9486adfedfde0142472c24a392833d78dc4a52fbe10a20a5b805f740aeefa0034533e96888511f1fc7510aae63c2914fd1c1f5e936f0141dd0ebdc853bf7c38839ebc4db8d982687713445911f15596d52b962968d1baa4c8bb6d6661310044fdc955630d462efdcecc45aa086e3fde473baa89c76ecc0c964526a430d6f7d84095c44bb384ad1c32aa2e1e24a528067e1c5c3f985fbb894b43561f4188e52ac91c1c7b52b4a4a81d402dd71e2856b55bc4d6c0e716deacf8266eafa2813dc217c9178c86ced6dc8d54a3e04df351e4a35c17af3025d874c59bfac47cdf8edeab289c9f4f38fed8c97760ea5e3eca441be3d7e534e337462fdcad4c6eec68927c849aa809cb78c07f9b2d7cd0fb5bcf276328adcd46397ddcf652bd1d684c8ed25e96a5ef68b99353ce592a826f40fbfc89f7bf5ab5697e32e161174dfe0debc70b2b213376310a6c4d1ca8e71f2cd0afa2a81bae5c73b8a97d34d138f0996059db3e30533034661cf1449f950253d765ca0972a38c0ce7123fc39f1b54f622c1ca6f24ea192cae47114ca9b17f8b7fed57d4cd5e857be99941bd86b2e87e20e005e3560241899cc8ca594a0b2fd7f08b54d4034f887e4d100dd33e81cb1e3ebd6a8e072cf1117d9765a8b9d7ad7c0359ad517f68cb4b69212acdcb6c1be26c466ded772900f4b7d6870ee0dbf5b04c658eec612da1e50dde1c06e1d79a9a5286df571b05bf66a474cb4a5b32bc8a27981279e3cc598553875d90cbed1bcb054c11023087ae0a558d0dcd839bfd42ba2ccfe258ccc0dd19294edcc535b9953701415cb4d70d934ac028ffa920eb3c69033d5bcb0fae00febb32decf16e11814e14f8f33af0f66eafb7f900ec6c828baadb943a40ed33d453d2db222be0922ed0a2364f23776c303fc173336a4d036ba4ea7379db7079358de97c013e8cc24e9350a331d9592809e272093ad1fddb27179d7cb661e678e03e41259b713f99fbdaf14829d12df440c1a321e07c9eb94505e9b143031e5a73fe684176fc163801576a7a68ce3724c8320c66d0a032b4d7872dcd1c79a40715c6683c30c8161a876e362967306a5bd68475b4958431b2ea07b526668c6715a431eac738bb07d21ae3037f25dfaaf135c6b7a0c6ee668c8be8bba9f3b12a16d18dfea646c8a61ca3aa9f5a58867adab89acc595ee08a1528e85fac62c480e93dd52d93bc887ae9846eaca65cdef6df699e2e177b0a469b58bdc5e1a20bee0468a8c58a521fba63ec6818118475cf348e648dbd74669617221e2b2affa7db0e64e425262e0e6fa2b67050f7f8660643b3e7f2778c0a741f204e70a2cc9bc283e817fe469d28a5cfc1c2855f1c4db1f029d8e0f4595ef0c8318d247be7c7ef18e110f2de3ec1dc96de38c246b69223039b267471c7883d1f520bb6511ee1506df71da334af28b9681060007fdcc6b86a1f4412e4948b7ede8e64f5e8f73176c54251fa6b9012cc78d82c76102b2e2e26aec13bf7f8d218d62000dfe097be252f5904af735ac7db09a19ad124c7cb8ef56a1b40bf02c2bc92dc0d6a0a1ab255cb69ab0fe98f3ba4ebfd25613e58134a2a7e8345c484eb3a6896f2a5ef95c986921eaae2965b2196c163f1400416917fd7fff4d702267b951a176fb8d0f6eab64155d60350dfc514c91d5774df890144e76acb7b9fac6e1f61799c488182caacbfc42fdfcd27abda1a88a75ba91a9ae50314b805de41c4ad306ac0407c8c4da3247c53db4f7d7cb735b8b89d959102ef9a3f3e15f8557b0083bb14731e2a63fbe02f263eca19453822f6f3454ade1c29dca76695d79c439d255ea842c6e7bb0a5d020e85d6f82857683e052415a1d416ef4f80f3adca628936b3d5a0521637a76006511104cbfe97a56336b870c5433bff476ca1bde54e8938af2e204f1940989f994cdb9664cc803db7bc289be17e48427b62d19202b3db4fcb1105c6dd6e3b5b12083f59ff42e17284b3512a47f1c9cc718c423588cb6f08c1cd64f4ec78862d07592d72be8605178f34a157fa7b7635e20e415c2a5a75d76c45148151f57e4741c909bd8c2205124b5289d97b125fef4c5ccfbff5fa26b8a3ab1da030454404fb476516b83369a8a82c034a169e29d7df588ed9919e2500b86fef0897423c1713cc8794254e81b4bcb6b7b42da84f70ea2c731af235002d6643990a8d5e37c9ba7ab028a86e13a44a0d36c36d5788e0b8ceae6c0e41cea9403095e372df5dee87be3bf4639f669c03181df92d4f923cb0a2da86807a0df92384604aff0483191414043df188768f6150b02b540f24c23a198ba52883300999e16c0df7e6c78cc32ccd14c525d3f2b95a515f2be188e2eb2fa5994d870628075e5732813a5e0c915005f07ddd088c93268552e8f6d820e364c99586bc7e7ce671c86f4edf57e99503006c964d864a0a059956e67188387bfa97e306d3ce6f344918c33d51d7b644decf2d6188442f7b6786a76497ada2630229765fcc999034e2f8045e5a8e3d4a76d4a8b6f2b3a71f26bac7a6ae3e280dc8732c61936fc81fa0edf58f70ca1ee0aaf1513c211e3c9ca853bc70678982ef16e1b1e03c4d6fc31ce5fb93fbda820651520ca3915578cbf88e59824aa9b66f5da6842d91fa47b5e794093d030659d603c429c89e7ac4ed964309e0a0e21fe88958b21ec802d411d2e984d4bc9e90fa1073f5949aea6f7d7cac3d9a7f27b09030f08f315b174b7c55dee82f0ab4a2d7ea6045b3c48014df074d744687391340ffa615553f793bbc7251196a24fd28b39b2a98bd96a81a6e3b42beb47d67dfe04f29028b863af9e6f75ceb8db4b75ec58ed8400c678bcc0c134ed17a4d4658aa375c6b8565284803ef22bda30fe37f3f8c550a32059f218b03f02a69d39527141d75710b6c09fe27dc41e7a6272250dfd6ec27dfdef4958666b459da66394d74f0bf6c6a8748d875ad152e76f805996861914d04b02fe87b08cf2d3cb37798b3bb948bf4083dcf365817d8ce130ba8e1d53a9e8cfa5204da13c1985086c4330189c9ef10ede90a64cd5054b99310e58d45cc97742d4256e32bf0d56e9f28431276c39cf352f82cb3b4d9d30aadfb4e5fd82ddaa5fe9552f6f9a5dbbeb5475dafa051af54a3933848064eab0282ce9d444496c899e42bf409e374cdd70bef20f0b1023192cab79b3db2d914813f08e6f215847522ecc1de71531533295e3e5caa7ee38e5e3274cbcb57e89297a12ccae8f4d79ee0115921d5e52b94649727202a1a248dec70e231c5285f61897432011182f9e65c53212d046a2c25006b47b1df7a8c1bebe98277c824f30c113b2e8173b8f90a9dcdc6f63eee5606b1d37a367fa1efe40de70d37d85115f28ef6f532de23911f4c9830d6d2c3371121d8c32496cff24b2706021109866af8ca5d433008846394727a64397a215665234930b43482b82c723dbf7458c033eccc2678d06635ceaede15945d9f3ffc3be8a336f32dc4cb70468232a757033b99bacf1826f30361d94b029667ede0bfc181e6a819f27c7a9d8043a748f941b870fb0950e4fdb766d3402b96327859b99ffac6621c9dafdcc4f9e231eda43f70d46a608e0ee4a283cf79115cd87fbadc445ce59c2baa40a427f99dfefef7a68167864cb441a0abfcbb611940deedf1ff7f1656f58055b7b11bef2a2a6eb6496b6b01b1af79bc87deed7d94321a4426d034808f852e7f8260df5d2381ca6f09f1bbfb9d6dcf8dd47c988d2bd140ffcf0d52db1ad218312273a6983dd488f9c03cc474cca0b597640c8ebd3e4e3aa21c9d1c130b73ab7491841aac3af542b0bc84d65cea45fd845e234e3469f13144f0c5cd6b3c013a03aa5a9d337cbc7ef77665caf12608f9bd9c4cb35073441fb0c320e14f4ef11138dc169c43de8753b0cb3490d019f21960e38ac45c07d7c066790a560f40c959e613950448bc162c866cb53837e01f46a294b4a170ed71995dbef4d920a6ad4154075bef5be11f0fbd9ae356b4e5cd60779fec74acd2f79c63199d1a60ff2a67c8401d4c074618830dcbeb5f14c88d4c1ef3eb701aa3d680aa8f11a7a4f9f2d2acdb9be97ae3aa5dee92f361e0feaf9b582dd9af007d8d8b2b915ea21cae1fcb73839d94798ec60aa7d2931ce0d4718b03907e630bb65cb9ee59a2609a27e245186cb76f272c719581976b67a46bbca609449dc6a33639b2b96fa8522d711a38804d2533566c70ae3e9ceccc90aeacc045bd8ef04c04f162bc525f54ee3417b54f845b99d969f53b62ba50059a3afbb3fad9b4968175a606cd65fd61538453f725e1462e18b27e79056f9b00c27f72683aab2b1368f48159232ae18e3110c62f78cbc115eec0f4414903c39feb806a84531ddc5d4557b7d64cb4e626d6a91db8613cac5ce772f7a04329990d85b8446d9658a5b6bc838d055c30b9a00491bcdf17d8751ba9a405b584f41a83aca9773dc021e3d057cd83dc5f9d99369f7a10d629563b7782d6400229e7ae081ddbbeba1480503773ba30010531abccc97976080cd95731c1561e8a867c61e39771f2e0fb1ab20aa8c1191040447d219e311f13834eca77c1f95220644aedd6a3eff99a144d58bc51beffd8359260ab3c462ad707dbb9481d51e2614dc0a78f5f58c3f0dcf83d3de9f53fd66ced84503c4f31bbb65371ed08efa29e64dde780e3cd9d1bd510bd02ba620bc0dd19109e05dcc7e3c341f4cbb197b58e3d7020f4a2761e3401aa4477c47060b81cbe4c82a7b72cfca33d29c523a9de5c54dd8ebf2375c71389b432acda2d42cf0bff0d411da01e008fa09b1d559a355ff4ccac1387b9853a1fd4c0da13e971446cad2b669f7d56176cad61b2ac56e29299a158d204c636f1ec09f9ba6921b159af834fdcaabd1ca14179269285ef60b875c296751c6975d5b21d6549731c6c288c0c19a35211120a918a63ee033ba113ccfaed7d062e647f3a79ca401687357a752e5164fe1a63558c830b8da67d128f0e3fc55543166c31ac6fbc30ece00150d70959a27b1f41ac6033c4b6ff9fa88d988a7922b13a219b36d9ceccb140fc991dcc9bd11772cbda5add9384e0d82a5009a8c0c467f228e17f97a1c3dc6dd908860f54c2d61286d7b83c755611780988551653b44330734fa043c37c31794a90e24b4009201e4883c4074dd046b9bf9fafe8788a93899453832441ca195e53000df9ab4333a4f46d541ee728443088c393ca10d1ca58ab8ad4c8a4edb0924666e423f1ad1d0fb093c42b196f233ecdbb6c528a77ee6140d08c7ce7c7b22a480cad2279528c124a733aae0af7a8db6df5baaba855ef54112babd1ad1d3a736142514e51d8a69212316104de470d3a0a00bbb15bdeb2dcb32a80c7090c928e469b2af9fb202f758276781e24737d765640514b09a420e08782620d004c689acc5913fdbd0132829d7ac5fc91ca50af4fc4377cb1fd6623f88157d891f493697aac90e2e6b7d3adb68b468b6ad87ebb59f5cd97fa53d425c3ba43022f238d1fcae48d50d4fdaf0311491b65b8094de37bc31b8d09c4939c76251a1a5060d91bd2ac99a17cf3d535e44dd4e5309e10e5a390acc275b2014159bc791c58264096312f4667bebba5d541f9786bc91ce8292b565ea7a283e498cbbe768271d12ba710a66410d820d9dd95b224dcdfe59bd5a9b1c319b03ff6435fe67fd5f61b0d581d097cfd8956807785e7d39099ff60504202341275ed9f13a7376bec2457b0f0cd6d835dcba6d72cca7a54e35d9a5ddb1b7296f470932ef038a8b478c23ce802973790cb29a3d6482e3e18b9554d59afdc2aa7bf19d85b78e3a21a6ec70e04d1c51d1d5a6a1da5dbbf8ea8fb6efbbbc4bbbe9250d34d996fe973433264ac5f070f89a049625fa78c191d4c02bd0d4cc9bec9c747477d8aedd890e2c805b25b59d7cef61b68aae0aac328544d74d696ca3bac9651781dde078f8e31e708c742be873550ebd7042a05a84c0044b2ae557b2cfca4013e146b9b547d5bcd0ce82117c1e11845b6f735c126e4a6ca2b5a5b3337d4d81f38e77f1fde73418a0008d01fc34a0c9bfe4bfb40bf600d63518e607ee6e897eb4b60c555d0dce4b572fb4fb42221c85f7f014b713d27e925c26e9a28a0ed023560bea567af86c578f0de876364ae8549bf98388d43ccf21c74e41757a540258e488b70664c23693e75047c30ba42fce2a425184a88ed6702e98602496822a3e805e34ef29c05fa5f5c57905a709476b6b1e4b491496625f1bbe430a6e65fc58be1b59f9aa2d3d3db6db35f9e075681a5904e0e0cf75fc36614bf8b5b13e6f004023eb81973a95d9a54f4346298dc028bbba60fb5a51d942a0650fa15bbe9353d12af229ec30f2c6109e376c80508dd0af8a5413260b1c20ffee662168af860128490de82a610ef13f39104b2b1fcd697c9274e0423d21d8ff538f3a81454111be0aa456d4d083f9a231412fbe6c1dc5b81505ea15fd4110a87aec89a3491884f4197d66ba3b4ef433831c35db9f0775f9642612e144f843d289a3915da0696332e332ae732466a9b076a5f734ffda48c4fc229b21d1ae292a61ec083a13fbe74ef44d88301ce1274b11b860469bad7094897113f387494d88b7c435cb45910fdc91573a1450a148e87d6ba1ed98094cab1fc7fb0ee40fc0b88239e029a289877e2c6c5159c1da380c7164c296530a274473711271c6de50bf98ac329495edbdc1ecfe4ffcea172af2837086e8cb7a2e20a2fb3f4744e1ac957c2fcc753dd9a384436441390279c3c2d9bd72938098927e36b31c7b7942921fd08579cc7c406fe705768c8da2899cddd8a43286fe9c194ccc81a69d22505457854d57a8cc1d05859094a4acff121689445dc391f4c5218241bae910c519b88eea2e877677f85c2f9da9bbb8b19a12b3f4828a99d5204bfb39a63487a12eb083b04a5863af5e7b073521d35d28b326eb899106702f35466dcd0729a2cc32dadac31aba44f88d88d28321980863350866c5046ed96cc05f4201658814d72d9104cbfa5089d7fa58b3f5aa1aa47d45043241add80de77c166c9f050082f91bf610d399644a36c60660cf3c03e159c12110e76305d39e3152906b8b88a6147eac4291023adeb145551062296cc236893fe2466405d02415b8a3be0784fb0f22928652de44d7aeca30ad34d10cb3b2b21c3ddbd56e769e338805e8319264b29322bb485ecd8e19b5aee6f9e44815200f91f0d93a929617e06441933799d28232d72943888719c07203b0d360fea7f9a5d4cc89264ffe5c8864e255b54998a6e16ffb5b9946750e60860df88b17b24b2c025da9903e7cd6821613eebd03dd7d5bafc9a29c9c1e7c505221ae1e7b025c41d1d62d95d65011f04d593cc4dc8241f5dca5e2c95280baa6261c1b7ca29a9aa70b91e0a44d79ba6fa796e3a96473a5224c73b7b6f423911e94bbaae3aab1924130cfd19f2fdcddbd43244aff2dc9bb2e3d940cb84b9d07f960e7f8d562551ca471a2a5f4a4aa01738c2fcb66c51283b5bc04d1134af0562adb4a8b43d6abb41a89790c9e244fb77254f1e8d6cba7fad803c25729cd62cb2b99b53a716118ed784e3612124735c8f0bd2b64f22e2e1da84e0e48e882c7bc88af152568aa2233c77e9507485dd52501d85e262b2df57846781131fc5dbe1b5c1287e8cbecb5257d92bd685ad917df01ec8061d6140a8de3210efd75f4a5c3955f5b31d77129b7a3517924366afd34f0b0a9b30d1054cfe432cc64fc56d454fdce66b0897c3711f6a93899e7cfb0dd472eabecac23c6f044dd02439c5d99b6a7d79b314d321cee9e1502d6b3fec66995ae6c1bf986cdef90cb443e40c177afc6f6fabed06f090bfb6a46920d67832fa5002aee7043dd2e2f1c7487f39686007f3dcb5ae9107a3b3f7f354b86b496e4cb2ae06dd45a5cb8c3feda0b09b2a91fbb50a3d7794289dc08c92174800646445a1f0c1d7ab540b4d717d516dace3cd570cfd3cd2b8cbc252c9c86e0612069c9ddacf59eab14fb1e094bfa49301bf9d26547e8adb378f484be7c33130c5c5f0061e9930f9164aed179b6007a539bffcc7c7c431b82a9c1d14b1f8a26acf608e5da011a838867b4a6eb35115208ea10bff6da2304c868b63e0f027718f0747db32e54f82307cbb756ae4c52cb1c21bc7c04558b7024df4337c5580c38d63d04981bbf9a67b567910a8e2501d14371f972e4ae454e4b35bb3a609b0478b8226119d4dc6d40867ffe926a745fa0c9ce0e12c5c0eb2194fc172d7a275da0d5ea41b51dbac5fc731f0032e1b9711aa67b1b4d8bb74860567f872c8b1fe0d73fbc336a31714c4e4cb2bae4461ef0a341963f8428dad3d8f5bb9058b19da1908d7eca768bbc7174bc1d26ae46a6c03d4ad342a0005b70623c5920200e9f1b141d539e6f3b9ea92f33f30bbcb556424a5ab3a1d443211994854d0065f808c07856f57dd29dc1fc56d9667f980ea24024e32db365a6119df606090f906029062edb4a404e6641f42c42197b28120d4da549f77e0e68270f4ada2f1b7bdaece3d731b175f654cfa6ea87bad3150f15b9652565d296523f780543d8343aa8c7cf7f72c0819138f26d1ffcbd5e650da2c7cac4c984303a42eef424895ce29903ac0a5f81df47e635d25a9607d9caeabd6289798f1ab8de60a3c66dc5cb5d398b4568d35a0d7ae78f03eb8740d393240278774480deeca10255b3e5752837aba7aba4c9d9e1848af5a156a41bdeab737b2f88840517bd552b957468fe3c163378f03606d1ff00249622013ea149bec1266be0180867415f2c3519a9df5e24468ccb6f3f3c058274c835e16cacda49a1cc558c94b31e48fcfd8ed0031960c3b2bf514f469c7a8416ee6944bf8df6a653b612109ac5123efe311685d3b4e995ecc464da3c34227c80900a12830e9544ecdb70c586ff7f083f98ffa862b4c0fd553da3516efd3671208ec7bd1e128b846f60de7184b6f65fddedfc0955032e44587b4c675c08b0ee3fee08f7114da4d7ee7c253e014ea21085b57bce8d056bf070d380166b8cfb02931c4e471676bb72efa88af2ac087581d65182d7d412de9a957f0654c23aeef469032d1e13634a8325fa9592d1b1990482db8e0de8cbc0be9b34d0c3606cb7ab30cea8e1fd09f174b3e134b77a4033f92232f4cdd273ba8d5a51118d2f4516d00cb7fd8087ad6cf30f0742f962f4732eefecae5916cb3a36b23fc67cdccb2475c99193968d95b4dc6ce78133ef50dc89e1045e27d901d54405ff787abb24b0d92a52009962ac6b32fa054715a1079c2f326dc18b137bffdb82204ebf3a0fe78fc7d9a5f145c5980cc11fd2d406560d9850bda020f316a44c516f72ee1fe224b6215a8e0580879293f4d94bcbcadbadaa4652881681ca21d2e25c7cd5bf9a09de85a7400a879100bab30bca13225518afba6631df68c68cf84d83c1ae9b491db1efee72e2aa74f97422eed96de26fabb75e7885553fd692efeb691f2b72b1520fded59ce9e43e32191b5f0dbd3f99ec4c030dadb0491daf5a4bbd2cab8824fb459290e0d75dc75f46562b64038170108858a07b5d1133b92922dd76b6b6abe80ad12631e8539e621b9a26a2a2a89af6ebc0dfd3e91638c8219ba93dcd6da6960aa1a7265af99a12e1a8adac9b34f1dd699ccc5770ca72ae54eebad2591ebce9e1c27394e62df19edc9407f776b4ce0e64b62fcdec08a2b04250e13ba2d9423e961e3bfdc634b9895044c502f1134f616459a22eddcc90c5870437486cab05d129d09976304f46ea2cc8b777658d87748062ab2047b018332466098265280d13706bace3099538ce75fc09096ecbc3d58a00b21cbb57ecdce4b08077d108539cc3b6e865f46d2e842eb660488b05c2df3302e005bdd52582ea50b98ad1c83228fda4f30ac030ea53af60b4161c592dfa4f1de4606a80bb307150dd0846020c3b4ddde2e53f0426e2b63edc224b439e9295dc67d4c9955ac433cf38b46f188f7e56a6cfd94ac141ee3199bee869bc31ff28274984dcb39a11fbe1a5b34e4085bee6f218e35f5e6f6a449d789c39579058b5ef9f1cb8565cfe7d7def6182fe7b524b996f1ef4df4474199c9d2d4455af55da2a44d42fb4d84e39fdaf5d24292c87518c5bef9b9d9930d0b18c0df09fdfe6e9b39e49cfab5b72179de78638c621d11a60b57228154f0d919b43c6f38cb05d81e2b60eb18c2021f161b1a361855751b9049799ca885993f5525bd28c1622d7ca807598604f527e0b511823fc84156ec999962bf09af729cd6253acc97dc1334fbc174e1a8902124c3b1a88dc20929c11976a40d097c1d6fbc06a9ee5ba9c23301bbb7ce62dcde5c3cc4324e79b7f655a95a45e78697f749242857bd8d9db28198d9c10b222e034501136f6edfed09f3c22af4b440bd3cca024e360ca261f4240567de7630e9079ecc91c274f72314b7a0c4de98b18578ed58caa13c45c21c26ed24cde9ca11a9b7131c5b151efdbdef64b2ab67356e50a3d1b0b1cf8d8c0631719c26f217f7568333ff05c8b91d8372be465cec2b5b79cd938310274d04b64d89e8875bd4d118f38fc8fbb5854e2d4746cf25393daa05aeebb33f3d1a22afe257ad4119a42fe1cbfd53b0652be499e2e71834c3c6d97ffef3ed8656f2b8c604a88e542354bb79324fa934827ea3de198439a4eb4a0de1f3ff5fc2bbffe5fe6886e35cbcff92b15fb0cfcfc1e83d1c4c8679be495d839d8daf592a92933c170f417f1eed72925b41d312df93b4697fc1bbdfaf1027ee6bd27e2be97e28ad5d816a789eca22a00a166aa7050525914804fd2ab6bed569e16235286382f6201f13b862d01be872fdf4ea50f7458ddfe4a803fdd16cb9c6a85d1fe80fe914dc3c8350c44f949a4085d71ca3926726e8ccd842a90255ab1cfca94de8cadcf5bda8c8615d1b48e10855d147c9db366b990eb8b282715c103f2613b859c8623b62a191a0a5d7b869c45c7f4771e013668ab559dfcecc0b1df724041d053d30a8d4736391e1289d3eddb24fd000ec70ee6e99e1f3e24f707570d3cb8d956f4a5dfca713f86e9ebebdbf8ee1068f18a83cd10d3bf9af8ce5d0502fa0d83040a52b5aee136d8a469faf295704779d8d4e26359844adb26727b63d6cc055fe994f615353de23613583f5e5b3c0e22369c80cb1bbc5d834a87bb6aeba2ffaec6195974135639e800293edf44b255a1184da7790639157180e4b65436cb04cb18b5fcb734968ed27d17ba3679c88dd6d6db40991297cd411586f23f792f8a59b0b0b09dd69979591a66ebf4b3343745abca2006c5b24c01bbf19e6e1cc66bb450eb6d9303d35ccb24586db5a1ed905fdf51bfa33f367b132af8e46d8f91b18cec85630847377c393b6a7bd23aab9c0259c46481b0a37855820da11ded73a291bdf67e2c371a783b71768cd1f0295f8cd7f6555158382c9c6a6a4e195ada6e6259848aca8f2bd660765e97a086ace2c8c72b5b3c916598b9a1013b1e0a32bd448eabec5801f3f81fad8e172a4b66869b5924dcb2ce88730a0d256063d5c9799a0439c00d0322d1545a791c1318fd7ae5a077263f52f72d0cdeb08c82c683be64bf524e2e8fc32b184e36e752d019494c2c04e8c508f4bd7cdebf0a2f524009345aa973942869b1e2b985102337f74bb9835bfa63250f8d6759d35134182d42a30b3f13594d6f65f1c1b0f98fd97f98a41f989fd8af188259ed8a35ad58074133919139a5ed94c076f2c3e61df603af308c1fb89c46b6bb2cf13cc8299c9b31a00ac57e79ed744e05e4f73b144a914d4bf8aebd2b7bc6be3c44704401901e54e5b8bb22dedba4e90ddc343b0aa465d4dc5cd80d21a6b491c2b39ffc6b65ff903b1796f1a127a13c76071751fc77fda186b19106e846c50ae4b2687937029b598cfdeece2677d13bb4b36ebc5cf00b949fa9977ab093427ba82c424b3d20425d6c5e3110505fae0e61c0c27b0dd0a3e93402f75e61c20023ab8dbba6ca8b9af4156f120a1d7b82e025f5811aa921f7b2e5570720ae8e414c944ecbf22a829a9bef649f0b92b00f76166f526bebb287e0d3ee68f4260264e4cacea98163cf903ea6289697a473810a2f4e007e94e137af96d149f1c5ac8e748274237541a71e2aff4949357da248474ac22a6dca71c0a2fc8d24aed2e0570e69c4341ff37afd132bc359de8a79e1a949a808cd2587605a477d08ddb4ca85e42d35874d8627b79c0c3f5962ff18c37135a3f9cad2e9397c59ad549533adc834bcdc4360b71ec3dfab4832c77e5be6de8907785b20b130ecc430c68cedeeb7d80f8f2de6ddddf7332d94105806526d1ad110ba2ca933290e976082f95004c548ca058999555a63512454f92c02e74540d254f73466ee414b4cd3c28de14c4886b2c415b918b699d43b091acacc7e2d26621683f230486f5ec6465c27fd6b3c07c1637e13f85c0c057152bca23d71efdfa36bd77bde1f7c2193992dfc35d7c2cfa5d29cff8860cb1f149b4fc6e81d7809e7b28db2677f324b82dfe02b00d5528b61d03e38dacedccbb03f293063a954ae023ac39f346573460f8deae9149059b9717405c0ceb26fbb1cac4cb365968f929bdb00d2316e0afe973a0c12fc37a18af7ba2966e2d28600fd08f5ec692220b639749db1c0d97e3b8428f94ca69cda261932ad8e990e70e4e0bed3b2e86903141ec10af1ba47f4af3d8751754234acd91ac6e219f4e13702a9cbd9e90b13d7beb987435e33ce03543f23f33f67b115a284ebe1d4dc8084fb3c3f0f0cc6cc2fc99b66ebd644fe98d8c69d7d4d7c649acc467ec07b7098638d12bf520cf131cd97d58b3ca024223233cc80905c961090caaf0c20d9a5f5c1739aa63bcc3416f649c8c613442c9caab0f5466e851631144dea621621915fe1ed5e0372d4c68940b022d5376bc6f7dd95bdfd5375c85252172e9a12cd2ad928ac7583bb6c0e0cfec061ee32218f0e4045c39a691a9c978d58dc7d8352b70595c7c6ffc795818d01dc29efeae4202474d1a99279a789f363242663b5e666e64c4efc30e22f22337f7cb2f43875532a05fcee867704353e499cecfe037e299f8908077411506fef3091f2a693612f43399aa72df84b7199aeb29e04cfb076e41982df6fd5d01a52e0020bfda13f710bd4943e72adfaea451e3e2b812100303c545e27da94228f2647cde39460df867778b2ba2b08c3c67f49d07ae211e5265a012fe01932502091c0c57c7243e09dcfbe2f95e651082751c76b09dff029368bf186addddb661a2b2abc493cb68905c5914c962785c344d893551aceaba6d01ca28b97de230c8c0ef3751af587a51217de4c908df2fce98b5a8f0d1489b71045d4fe213e4f2884c26dae85b0f2247226eec4f2f8eec55d47f20b8860186e78a3bf74af5f1960c251ec122ad100c1e0d26f8acc5a6e6f069549ed73c23e644bf8c63055a3ce0bce796098df4b4ba7cdb8f3f847baf077343e581c67d4bdb07ebe4d2b1a18fe546060762698f4e314d49f56c27f548f2625f136ec7d986cd1e9cba578718e85650fc343cec97b5c8a02061ae170d24f639ee6092224ce40d0737ae2dd06889fc4bfe826bd8c0d192e01437dad42940b902f5faa5eecba95b71e3286c0a9dca19251f26dcf37aebfdfddb6f31696bd4578284495bceaebfd64cb82841a8124eef4719b995afcf71ed7a69f0acc69808c4827c0e74c7abd633ef356b32ff9a2d078410c5826c8412cee081831ca3dbc0732afd156ce7100da99c929e7e31da749592d693689d531be5610858011a47747397f677f0f963d3a410752482841226ea446c77976f704e4b48363580f6012e079de2874fbe2178da0c343ce8de07547d0d7bf6db7c28d44dc8b693104fafd59d6f80bf5210bc09c532c4fd08ac840cacb1f538b2da94283f581b583746fe0108a2c4bcc06bc0e80ca787472fc272639f01d48168c86d392f2fa9430bc28f7a191785d3548ad64a35235afbcb725b4bd21dd8700760bb59e701332bee82561796b410167a058728a050a46dc74a07775481cdbca27745590a24bf49cfa94b4ddb1b30ce3749a397af1fda4bb909bc96028dbe0faa49be7a1071e0b3b6736d91f8681e31088efb7162026c8b6c0461fb5c658520c9ab6c49dfee438ca258a0ce5161d826fb487d2cdb32a704d4d69728b58e48b3a19672f84ba4bab80a9a1372187bc0deaf95a210e95495dbf4a6da86b0d5ca72c615dc7ef79115ce5f171b80d80f6cc44a4278519b4e4e980353af10d11c252120053853528fc1e1549443d2f6015c099e621e99fc85d280cf20d1212e5dbc5bcaa13edf5116336bf9a2db33cc86168ab8c25c0ac74885eeb66be7680bd6bf512c7d8087715cd813ae467f6a2b7039f5005fd112eb482a37496f727bf6fdc45583d97cfd816932043b72bc0dd4f6fe0ab03fafb3ba7f44df72a5f500003be833b987918f974266406960a20cd76e1c886be42b170782ef3fd0b4cf7a8b448fee48990cad7fa7930b8fc3bfdd8aead83da9054f0b30b69db0cc081984c59f21a94649b38fcb50a3049c6d4baec70501707da1409f46a0469948c736bc2339cd6a34922052e0f4aa010dc99d29abb6af9c74e7f1a5f7c3be595709102020b83a92916b99b59b64b4da12d27248a25d7b5be6710ceb963970225073133ce22b6e88f5f55ca9f62f082c3a844a972c2ce454253305fa6e93fce7709cdde87b5294ff8571df9dfd955a50ac880e96944f52ddeb3cf783d9b246a77cd26f044a59f5419154f05cff92484823ec220ce96460a8c9a6e7c69c78a0f451e4e6753a0d3840c44c572534f46fb06c4d9095d0f82f09037397ac9d4f50bcd6653e718d914c33d4e8eb82fbe81770e9dbc05f98c061b1f78e4f6ebec541203b4c6a5365e891b8e68dee00484ebe0ddc25b0c39274a587be9ffc4a35fc9c8c2f708833cac8666278870a32d6a2148d49f6a3e23e07db2f1552ec81503e8272ab7c77963456a717f9c08b27c3682a5076cbb01d525674cbd6e41058c89cda4dbcec53686f4df9df7edebab9ae124a8bfaecf56469d366854ea56c5c6f66adc799f5a1568c2ef28b5222a52e39a81f7bd152505da4ef6305457fdeaf947ee9b42c1eb788a4e7e3eb99ec862c001ecf77649d6e447e6d044a2e4f2ddd97d023af6ee2de56daf736658ebf0d6f5c1256c65aa9de242438c611a29aa00b372b166b17647015c9b83012c4d92054678b8be563b6baef2c913f66e8ce01556013387b6f888a2bd1f482e3b961dc6a1370e83a6b3db8b128ddecfc7508fb8445239bafc44daaaaf1e72785a3bd68677510743197c415793fa9001640f4b939c67b85e803fdb32ea524d25bbc35521f9ad54243ab967f9e376b0b1d7cad3c386df42b8574e3972510c305c45348b1e4d910eb6399f06b10494d27626d470100dd90b66051c6ae007218cf0ce2986df373a30686bdfb5003abc61b65d578b0890ac6b1fbd9060f5b7a037ea0d280b19008bd1c7d85ee9275bc9478b69e69c7f08af7ee5e0a3b061850c1ad40f98c211ccb2f96da7e76dba896b5b5415f06bffca1b734f1d289282e74e3b0a4de911918309c05766452ba7377e7ab9d73ee235feb7179490523e6e2d1669072da307ebd4121aa2ffe54f175af2e8b9c05ac82e9ff070ab6b43a6b0317f836c8dbe34da5973e7b3f2e5a67c6ed095689abd7765bf1e174ddf9b81d990c10ea4998289aa6e19fb170e91313b1aeb0a7e2fc8156e228262caa25f042e95db5c8aa837c0ab595d798fc3ae830e38aed74dce6138c25bd8c05386a0ecb6fbacc15d6bd828b8271d61cf473d9916a3b8c8597e1caa45278cbe2a767d9380f2d45c14cca313c565948386605c3fb1511a23332b8364bad7a445cf2114c5e7ab32345b926777f507864c4a0be2133d8d515f5d7b8eb1954cf88ea786126089719f2238c9e90884036913c0c09ec471a80f22c9a32656e722f1245c236bb3fd5bad7cfe68b272f22246f15c2ab3362c36e88d546c7d4292b44f2dc51ec39424ba196ab7108fbe1965d44648c4e0aa26424ffd8e34e1ff6975f8c1603c02447d00858b5afcdc4fe34366a3dcb3ad0508cf3cc50d3b4823a1beab22361eaeb1392be2e1f5ffc1b40551424a2803af46a7b5218a4c3db3e89a0c4145106626e6f82f289397bb38a9d79e81fb1c45f27ee28c0da4d5ecab70ce44b9659d3b194048924ef52b99b84f66eb9469822c767292517df67f4d811e850ee4349a8b923e1d6e4e67a9269149f338eb0441bdfc1e8888d6555bf0a3b51a66a41d5d1a6607d805e7878051770b55566366714daab2abbdcac037d47a749116daa7760194b17efa5eb4da42b62a1ab39530a81888a4fcd7ee009d15a87cb519517901b3e6f7f18e281401b3a2b399ac6dcc059c7247d9ad5a85fd080851089581f7c5a813c4f792f259c1a769dd615c781720e7855585943f7c6b0a4d9174ae35c41dfa3a8b1727192b9db4098a82688996067746a274e98b2acf3d1c0e92776d473f814cee6ca95f69a4ab6e5ad36af5653d0b5a0fcd84239aa745d32401720d6bff4509a4aa89ad7c9e268df2ead04acf4f5c0e05fe195cc83155b00bc1ba9c20ec6f2f75d18e7c067bcf040ad5f840594c36659a8df5d04fc098c621b0722e39083649c4622c621c6b862a3eb424a8818570f4ca634a8f7077f7c77211161c1b0cb88afb05c1031d515823d57c99575ac97c9d34b070c71aee91feeb55d3ab8dd891f2cde573c49d2d5838ab72ad68ea9dc153c4effdb4f21cded1a24ecee5bb8718763614a8315097a0f7d83be01fadc5da236217e540d41f792b9ff43e66e7217b91d9ec07862b926571380e18af73a32d4a33d0267998f553cb2b1c0443ec8cab70f9f822bfd63d676825cdf627a95e1de8dffdb564c07a8c559162558271441d1e131f4ae8f5a315db75021623317b0ec49d4064176f1ab939ded752627e20065aa2fe378d20c72c3285d65664c693a66713630445375ebf7eea4e0975bf1529107f4ac8c18bd3e3eec8b0f68ade54a8a0f1463c6bd7684adb47db68efbe8b6578b7e2f6ed61f656d178bacb6ad7b9b78f880ff6a250e9a7d8f0ab5c0cecdb7b2d9ef6ba4c491a9ca02708cdfc8645365845730583e25f85a46c9ae2e4ae3e711aa523c58dc6b6df643f116f2a95e50c7dbfb8115ae70c31e6cfabb24378c805ea01288eeb78254f3034e6fd3b21fb41ece32c1608564a5b664a2a464afa428eeda5ab32f76de48026914b4020580609a7301565025350c8e9e9adfe4b5d7a8b85081be829dffc5c8f78040809e1cb21f1ead71c5bc3017ecd1c1698b0278e9559b937e07c790119c268313814e4503f3eaa2027907d550f2964924dfae732f0a14a5d04feb142415fabe4e926664292c1a3c2155d552f6aa1ffd7376a13cadd3cdf42df4878f0fba7ff25e746a9e7b364619078693990764cfd38e1ed9f846aca1677cb92fa2ac0048356f4f7db45ec003588d25c3fcd8c63eab76e9e0c47dc926cb27ae762bd9e2fca0f277bfb8d3a3bbd0ebe2127e3a3be66aa548c71129ca0332d92bee776b176c8fe01d3267af8a8ed05c8e4ea4dd143431197abd1001bfdc9a82efbd920634a05fd36894012ba6f9004a8f0dd256260e7d9d6aa628d02269b56de7f0fae001489c1a05622e15a219ff0f683bf22ce89e3ccd2c2181b3db41113bec5313ddf75c151a3340d4f6e67a4903f721c8af6449e85685121dcfc7c81178a0419d450e4f8ca3e18a37be95070c419450d9ef10ddb14876a33c6e365daf3a1c28d0df4a13822b6167353248fbe07a46f5c84938cafe195ad50a49875db91375ba0c2bf955297e5db19821a863d2473124fb8ce4ba8f801feb317461800fd847980e3e385b067db70214bebf1b8fae77989b8b382169b1442591e99bbe0eee503b0a76d92291236d55e037017c182cfbe4b1d1bf99ac5645af57c96632c147827b68abc2d4b22b13a447c0fcb0cf08090c1e0882e3e45045ab42a76565c53b3ba82397bd7ef11abce7473d206c719b784e87e1583eef7db9379b42a13e30f0c0982ad50d4a863dfe8b3836e17339f4e0cb1816183a6e07dc9e8b39a35f5b5298335d3aa52f5d28b5b433703beb0604246ab7019ca78ce094b471f8260e39797cefc69de0c91be3785705670c844bafa8a87674464bf634dd8ec1630d05332cc6547fb3cfe5047c8d4f190e09be707451c6a843f088e4e8c9d2fee271760e078828267b4b0c21f131c9f454a09fd43b8598e773564b99a169a767a608c2142ff2705b41c23f92b56883acdc56653a8df4558121d3530111ffaace8e49586e00ddac014d708bee3aac44e8d06912e5c634565f9833b11deedeac4f4a7d859a2dbb6b5a8c1c65af119f117ce5a141e8b6324b867897350eadd70d7ca445f9f7e2d4024285fdbfacc5280fc129dec60e63c162ece47fa561e1c3f68c00d5932995891e333ba93d818e73065afaaa702e43453fdc5f48bd17bcaf0ae5f9aae8fd90b586c49b031259356074cbf221d33de2395c57facfba6cb306141017f2ea1be48d668b027f10029aed2c51005efeab42b7fb9b4b559065439d8c2e89a6a98568080e58262720f4ff4696fa0fa77bf342a8558dc178e6b0c2f9bfd0e2a552e71be21ce801e739bec4ac8ef561e8c52a745cf378e220b617044e73b0b703c13d913c69ddef134f2b8ad9f20d9c835a7bacd23e7f6a78836dc685b1eb20ccf3819e41c261b4bac5fd78332c52043534936cf3edbe9b2486f5f4ac7520be262372194fd5e23c112dd590876fa997e441cf8914d21f2584f3f7ae92ee9a8a3e4ef6eee28dd52130679407abb93bba93192ba418806406e45e302966644be1dd0dcc64f5ffbc2981d914616d4a5fd950853b12309815b9d2029336c31b7c3680b69dc723a0a11c61d460a550d02e92e0e580c441208ee8bfb3c872e88154ec97f963e32d552758a6b4327c28b5c5ce92260eedc9133185d296eeb223a1fff6037741208c9b70878b3511aa7c7762e50a348f918b1177f63c35693826e1dc1cd0c3c6d9738f7834bac601b67c44451d9e76115b969e20c28b1ef268e17b8735346bb898773c30474b4071ee369bfd4a921839700670254681c150b439706dc80ab168d859cabc88ae2331d9245a2abfb5efc4a967bcf02498c6f4bfde4cebed1e1bf76f6c54ddbc1c0ec6cb6145ee064bb338dbf5782384530b889703e7e7d345cceef82a3270a09b9342f99f4accb8692ce9e510303fda44b2ed4057abfb6e315eae44a7b1696cfce3402546a219d5ec7050e650ab819499e17570345786c31dca210c6cf02b62b644e886fe773957f1b360d9e281251747c7dd557a7e920eadc6a0ba1326405cda8c2bab85c902448cf5a1e9caece9dd258b2a07801ad4be6ba36125b9b13b05d78315d08d313a6cc6764361c9223652ae8d5e0ac1636beb799f3099ec7ad4b1b86150b0b006db1e8c7a56500e74be7644f33312d90dde5944c8f302f96b1955c982b4d7e85f1e8805f314fde389cdd65cbf0f80cd7f7c078764113d3ee91102c5066be126476db7d1ced0911df06e064ca203d5b33cf299dfce71fadcc0f2b8770773624cca230e4a0498d90cb78a27f5024e3cf501f607e3928e7fa1d8478abc009d11f05ba18f3d0561bbe5aec9e92c54779f88fe08c7b1dba663b39010f8d6ae0d2278ae640049156496cfe7f4e706291c3840848a2b76dead0d9b4500d08c168259084d67d1eff1d14b594119e16bf8b8af8658428ed972709733140750ad81a0bdc887577066f791c8b820fdca3fbc8b122958cb32766231ed9921a23123a38294ac97df9b2d295215ef638f8303c79e8408d544d2bd0246bba21678fc52c92b776fca42eb9b0b65d5786b5961a8f727d9a26f5347fb45aca5486efb1fadc4c594cb2dece25185b36a261c4f752e075c0ec559bc7f62a9c63a58aac20c138de4c312f25968221183c6714e7bca20f3d9b0b694bac4f4656adb266c6212e8a702017e5522188171c58f085d2a89939fe82a91517273b0c157032c2967116e102e878bbae1755c42b4c144887606862bac3e248c852c137bb8b15c6dce8d20654b2d051c80fa4e34e99425095f1924d57773d62f75d1a5eb0bc6c2b8cf620e096a5d102e072abe1fb9f47f28b433c7d709ba1ca2ca8cba2c8f832d0e2e25de427012409783d9389f839e0ce9fc4e9dd0b9f006e4efd6d37b70c485a79d323f3cbc99206f4e6b4b852391144a845ca742500517e8e03a0580f422f780da4476e02520315b497690ebf18e0682881f4a64075184993e765c4c473636b8f83cbb775b09a6d9640717a0e99b3a4f10931db8f9496c42f7a61f6046527688eacecd5880e3e3b0151245cee87c2071d56a613b043bf6d260060a9f0ce952419f50e4f312ba9d34afc8f8fe30844f5a9676474537c6a70fcc219ee749c0f84f60ad9a53a8a7a96900fe12ce0eae182b0a64d5d981b66f8fac11c4735ae25255c42a6ccbeff145a44411b3c48eba186c343b7a4dbf830adf62e2ae3bd9bb99e39d7474190c95eb649562ababd15e1a70b194816d6db47c32094b72d3e01736503e1d06d6c9c07562e5a0bb8280a27e62d110a1bd1f38302fc3bef7f1db4dbe4a6e143179e56eff17f41d3859eed6ac0f01a407d742e870045d9515bc5c755d165128b31e33b41a87cb1eb16d729e8504d4015afe98324e701ed574c9bb20eb05f06ba94968849f58ed571e21ba026de2ed77c2d3f11c78b59cd10405e019195aa87c1e40f2ac62e8ddeda0a0af1c4aa5f1017b41be75884d6a6643ba09d97b4bb9b79429a51903150311031df5588858c006f959882a37c06094d8752c606a89d4cfc70d900e806107da73cb8a31b7dae8e272714566179d08e340da452756179da9799f0ad4b2d586042760bbf6361f46c09925cf18b7a04dc83fd813ff628cc0501a2a3658f5c6abc076208504abd050c27a03579587f5bfaa395250a454417166f3aa17f40159ff1bf3bdac3f2c9622af524ba4a0f0e62c66a6940fc7136ee116c6992de4e2165affc00f0c5960946f0620eb1fe3e33ba2ae90110022b3958faa47e563ddbbaa1feb5dd5cb3a68b718d7d6dd7c422158108b8f8bcea672d16101adbf8b8ecb11e9c292c6846d3af5ab84465a11f5fed7b07769cc7af76f391fd00c38d6ff25c6fa2b892f0ee37f5128970d8e2e3ebff4b3a7241ea96ce310f5d6ee5ef9a1e14ae83237155ba1213d5a91e165fd5756a4c4980a0a82c156401a822b6018bdd44e2a281594124a81528aae62a4ca89fe3c52e3cb164d63ee9eb3e7ec39b5aa84d276915cf1882d6a37443cfee60df18f4808feb9960d21e25fb3d190105c26fef62164b6a624c1e5275225657477777777778fcd5d18ddfe196224840d1cc66b109b7b63b3e7c065622475bde2e0c68774bdc974deaf655e10ffdca9373d25a5f7a06e5b62f988ee4646433a7a2fce8e8e0da82ecf2fb782d65d56384b5adee53b2ecd195e223e4e24896d9e9695cb065aedf4a916bae3325bffa6d3442d45d494772bd892fadbf29bd7d22d2ddfd2d2b279add35eef1cd16888d33abd539aafc3ed2d8486767677841ddb017f96d1d0a843c5224c101600cc70a6e1401be904fcef3cc3f68c62fbef9462fbef046d3fb197824dbf2360556bcc65defad7273ef3353dfe1a60533d6c2af5279ea93f1f59c6f4a99f2c53fad4772c43fad4333b50853a01ffd46b2520a9fad3f2fe552880efe1dddae359bc1ffb2d44faaedd4f4fe3a9155b3a00aae3b0b077c261fb8908d0e201b0c2e25db72bde9d5cd8feda46a0d876f168e2eafe76a5bd545bb51742b4134c38be286ac266ed09a12105138e2f8a7e6cf6935a7e213a60142ac5faabbabb5ba533a5baace0005e958801a79bac8a08456eb9f2a008c37a59a1224c9dae7aff5f7a4a9123586041039e928ec8f425d29f565cf396b597918bf836ded108536dbc6632631bef5a957de83a721cc931296d8410c169198919f1912b47b65ad98ada1f0ee3598cdf7592d434dd7ff6a7954d84716ed5f5877f4e5a3dc3f477ab7b639f26822d97c93c212cdbf4dbf38065a3d7147056f35c50fe79834df4f37adb84c54188b395bb28ad1585cabec32bc2551ff9d7425d8aa08ffc733324cbf6ea52db6abd5aafa34a51f55176726c4e8d2421204909fc736a6dccc8da9558ff0cb801ceba5f0bc2f2e6f5bab109c2311b97910c44324dab1586b7a58444fd6a96ae43dd80289a0c25a84858f7fcb2c269d1f80232dbbe7b924cfbe6b5685ad2fbd1e2e1a1f4a52c01e1c891e5aa030f24ccde127c6c0756fb5b828fddbee3ce4957c2369ead458df8e73afed19c9675efacf672c5966b0991303bdfdb13428a1bcfdd785a38e458ff1f1c637ca376d712e330be62dd8dc76a9ac7fa98d496423cb1042446be51f9fb6bdd512fea03e9f2c5b09a33f9598982264389295652d5041e4898bdb5b6948cb6b0c6acbb2214ee6f30cef0900fd1ac62c465980a367a9c0a367cec9d52264875acd323d639b651ef044f4b9c7e4e3e75a70abd66bf3d55a6cabc0fdaf6777b4a68ac2da838c335c83f982fe04fe3130cea38e33513acb14904ba0c031d81228a94e846bd9554c10834dbde04f1a8b70659f7af41f4c52b03a21b324cd851012f4b278c0cd6a0343394265d30334fe195019c45b310af953606b32646336b62845139e418ff6611201937e474131b769ac81aa0c4e6265a74bcaa218977932f46c747e63439926ac4259a804494742364fd3790b2849f5fe80d07bec065b03d157fcb8e34c63f0b64a79a5373778f597777f7d90289a0746c839b5875e965f0c482384303631afe8f3abf58230d88d37c7eb9edb2384bf8fbc6bf1bc65992fd7cae4daa2e7ccdfc25975fb6dcb88c8d7f371cbb89b56ee207b99140fae58a00dbada48b2449ea998fd28afa56ab2533cf46cace40ce56eb070d3bb6a3cc20362e0ad4d46585b33dfd8e2bc9bf6db5247bba72e16b685c9279918588f95940ff58885840162296285b388bd40f9a85c8657096f4d30feea67b82a56104566c0e354275a811dcc0f6a4d3fb6faeb8e5703d74c9cc06033bc0e17402fe214db21921c1a131703dae35d7135f4501fffce975e0c33fcbf5b8cce47aa6d7f2cf2f8bebc9893038ed0097a413f0af95c8e2b4b81eebcfe570492897e35d162ec77a1fb4bd2ba1752e89ad51a2512febf4a5d2774de954229d4aef352c13e548258f5901ca7973beb7b7583c851476721cd7e25a3c859ddbb3da07cbc76ae588c5b5125e56e83522a06c08289b3dcb599e0f960f7fc09fc5f5703d9c113d10c5fc687d9b0320440f497eb0b1008af5cf80a1f044c0953b0a83597c86b16a2439c95eba73e98ecb8bbd34e6f3612ffd612f6d31906d9ed97ef34e7f7ff828fd8d21fd7569e1feef8bfd612ac5587eb041be72f35e1886f99ae03c5a19920724279c252ea337aa1651d9560c22b74bef2e3a0e7c1283b5b79b94c8e792065d233d1350a8a13f11663651ddfa53fa53e34c8c1a5501da81c4fd6c44aff81db397468ff3a89783c1b82744540a074af9ee3291f4a9fe1c9fd2674ab78d9bd4bbf4efb3b68d8b7563e6386eebb46ddb9e730e8b09ca687fe9731e4b4b9f4afad4a39ef46ef6cc9656f06502d00e48ac7f43d1403dde85af4165dd92897aacfaa75f4cbcfca1df3fffe29f67a41e3dfe337d4ffffd73bafae80ed224a5a4735296956a9a01d016005856aa29beecb1a6f761419c417df6fd4150fcea1a675afda106f8f6ae1026e2d5e5988f18b0ca2fb1e40ff5f64ff694524a84c30f350ec3568b05f002f05abc8b02a0e5dd9677592dcb2d1afff807585950ba20ab4179124498d3fdece55048697563ec7fdf500005f927e49f8c320816c0ebcf0e949d24d69fd4426bacaaf8f952eec8ea2c7490327300a1e326cefb02ee1f54410e4738ee53b824e648b6b3ffefa3f7315dc9f72caa041fb76a1652410a965b636f88c741b497893810f261cc238ba33607652f56021806829e117013da4524ce51512f3ad3d5f9aca7bf365dface82482f887fdfde6591be8b2b9b7aa21485f26cfc0bf25e9057bfbf4d9ce9b9a2965b718da9cec659d2a77671e902f944908f305f8995c551eb2aca18b39849b0990359c9b7aeed1ad75d72975b779738f7e99273971be725df9c544dd33d734d92dcb455f759376adadce389db36977373d9262de33a6fa18516261e2d1439cb32e8135db0a389c73c6a2ebd5860611e15994745261e458e8acc2316261e2ac030f37061d631f3203d7d4a8a81fde710938624e9493fb3a876a833bdf0c20b2fbc30f3708132a14c5ca04c18c808170335813190133a56088b819830a2dc775d175dceb2cc2f077da22bbee681b3a8d69bf15c96130d74759a6b88f26843a0cbe5dd772bace06416b936d7b463da31ede8efa14a7b0e75cf3be61df38edb2f4d477e4f3ba61d93ca349a5426956934a9cc29d368529974cc39a61c538e596552995396d09945b049c70c673841173fcf2c6c641eba0c0ecdcc4ddacaafb0cca13a447202c0b314d5005ebe5cd14027759b45a7537777777777b7a9bbbbbbbbbbfb67511d9a53fa558a20275f59f69c7ceea7933a3f1baab368c5bb9acfcd78e2eb663c45713aa9f5abc9bb2ca3a1ea48ac17d523374c2eeaccbc2cf3a6947e656fd498048f936a5454a71b53680acd355c383946189953d87845bdac2a4418d9289f6d519d45b5a84ea2199b69cc34a61ad38b09c6ec628241994c34e619d38bd9c52c638231bb98605026938c19c684c24473598f9c957cebdaae71dd2577b9757789739f2e3977b9715ef2cd49d534dd33d724c94d5b759f75a3a6cd3d9eb86d733937976dd232aefba1c609c64463a231a778cd33263887b26039a91d90e873c9549a4e6ad775777777777773de26e74fed35efe7179534bd88dff1e5d0e75fb7cedca25226938bda48e8d8394525d914ec74528df099b0b9c5d4a24ea169c5140304126c1823d606081988a4890e36f364f42e8b817c5e2f1c2ac932d0133c730a062a0236af985554062a02d66fd48ed24d5a7669e8dfe6a2e191ec0e41d0c62c0da514f5d27073b5b7ad365748c3ce389a344f3541b497045bfd631ac6283bcd3a7b1f44206d3f05d3f64f40826d1a4e1f90cc39bd159fad07498ca572d4b627d61f0a8d62fd354e8af58f915b2bce08cec77afff0befb47cc32ea5df9cddced300d733dfe79d33877dc0cf572508fcb0494f4a8a4d34e6dca6c5200415014031600007820128ac4711c0af42cd03b7a1480095a8034a65a548eca627230c73110830c218600000000c400000c185393350116204949fd805666fe49d042219b3aae4ebc7c73181839a930f75d7660def29f7fd7be09a51e7b71fbf1a18218fdc229cbe21dd03faae00aecb66893813afa59b8eb634faf427c8e85fadf39f8b9622e350523cb12c0ac62cfa5e5817df14aa7cddd77e909133a5697ed8b9ac0b64d1774f4a4a5ab6acfad281ba8850a4c8a93111097d0c5091b7f1a4b632196732e0cb4729827633bad3402b1e0f1d220849d621d57875866ad21cea320399e1eed6275a18292cb72fd7f4f58ff13ba5e37b578f4b99a5f8a639143e700f4b479431cff935081094be194612839bb1d33e09acd3fc5f6157350a24fc0fa2f151ebfe2975be11481d994bc9fb583f9a0e17876da55b9bccb33d503caa8a82d0ccf0123a339eb3f69fbf80a4fad7a7728664932dd5cb5406c02f4b9f1a8dfe6d20d5072b110273e17b8a96c864de9e0e87563d36cc90c4f2dcc35504490388a9500d7bed883966ab09c5af4665840e66932746df63307d3e140d1097c81a4e4fbb79691f6894e838f073a8d276d196f5df9fcd8c20622482c102ce2502d33e59fff3fe94904be82cd8db76ac1228244db0e64a6d1ee204439ee2942906337df0fc1fd6a22648820e16e94912d98b1af8db31af34d20817eee40e1fb8820e1f8b1391580311ce85318781b08a7e54a92c9be2510c1151928ca247c06022248f4e63046305f8b57ed60cf03a243b6f145f5ebeff25af951bb3a7224fe559c9d3d5e494972b764b4e4961c60ed0085d59c9e931db16739e1fb298e10ec3050e2770822482cd8cbaa8f018afacd0233dc349209b1dd2b2640810812083b7955c325062770578bcf66cfae07593153633ff198d55a2a3ddc17ecf65843e85276ec122248d0e3608dd22a5e527483444c1b6ed50e6b181c24c4f866a57b5b7d413abe4877e9675dc48af4bb18d1bde49d118dd6d56fff7afd7b469fa6090ec8b611bb66280a62091b2158f65cd3dc4e15516ac8fd2ce3e674821c04ebfe8e31422421cb9e5e15aa1041221a6728e9d95465b99a2338d6b2019481bd51d3916a69bc5559bf85915f677510f9e18761342182c4a538aabb9635ad3c37b1bd521e69aa1ac9d731bb82bf3696f6ad757e9a4ccaea6dbd64d7b7071124daf00d0110613a2521652efb714a11da82603a4cf5c6cf882081887043aea911cb55f645a0c2f298b6e7767424d6b5bb8c6e09c0b42c053e36719c06b16f982356d0e229760858810ca12d8d85c95fb188b177092d95b8150d941f61f01f598d346328db9a1e3e614f522f672b6a92e1ec421b3d9841263810735dbd19a22c6e5f9cba7ad23abe74ee6e4a77930f7f020e78692b92c20554d7434eeda3c73cd90623dd37d0f887be1f48bfbffa31ec349e0157be8342260f0ecf4e225394c80b481961f5cb6d095bbce6a7fb88081245670f7d5c02e02282c4721c1df4e3746250620390c3686249a78fcf65ba860f54ccaabf2edfcf9783b1aeb3da9df88dfde5ce8807ac78c423178820719aac16df2e12c78c7716f256114122e2b0670a3bb8813595fe51dfab04eaacea21f2f28f35212282c489c326490dc4e0287fb8b0c6b9622abc6fe22b31a40e248c367b85c73992736b0f952330581bb8555b8567b30a14a27b0811244e5083c8aeab96af132bcecbec6b66de9091c9e7e6072e9f620433d6977fc88042a61836fd2ee19293e3961977382548a700a2501c7db740b76b23caba400409baba82da7900300ad3e9ec5628985a532d97f826174490400efe4076e710bac794253fec4dc794fa69372a224838551d37379125d312a22c1904785ec87a947175a184979119439fa39cde23a69f51160cf8b7e68870cab03440111124f2faeccf53c785f3cecf61436e93f7c36b621b90e45590935a5a2ee395252c254a61273960d33ac44484205b1b8f424192b3e9a61041a2a0c77aecbed30e64f3151aa3a0cb3191fa09fd962182441e9b55081bd3987a4ec3120fdd0b466c3ad9629e98522e2f03ed804473956d545d7a8d0cfe1e30f70284a0bed81ed66a3745e323949a1aae1041e2f63fb804baaed398541d8c10cb4c106d019303897b8f23a08717d7485fdcdecaa5d4b3a57c2f7eb0fd1480199bffd1a1648820a1700c74122e115dcab8b31a7e71e891bca6a326b1474da60853bdff040ebe2ed9cbcefebba4091f39781b940dd757c8f503c7ac8a98fc919b7a6d102d119014cb719fcd6128e37c43ebf3ba907be0135133f8ae6ef35b5cd2f84aef3b3363993159a660e138a9859f9a24e8163458f131b1be5caeac40d0b9592b785a0d30c8d10bed7225887d75e931171460462d7724283052bd2f40ed6ca8a50412fd70d5f2971f9ffc5e951c5ca63be13ade10a867deff76d624130aeb426c228244b4b4e86592d04ff1ef02f92092e4dc11dd219a508659520295fedeff8275e5b9b21242e7a682e2291f530a18033aba9d1612d69c4fabe095f047c72194c71581ebebeecb004fccebd4f2b5f56f2dddabc3bbbeb2dc690114a11deb176b79e20014724a1041824cdd203c07ade000b9a1963f99f68820117377c6db55c481a1b509c4bef1a17fb6c46c2b4013f4a8c8cfc62b242248dccce8f8a59879ad1a1369c382cfec667f570517902c96cb56dc5e7e09066b322f42618cf49eee930ae4ba8da24199a548762f9f590b06dce8c0684f9db9e3917f1e5e9e6164cb02a41bd683c7d055ca80d91613c20dd6c16f90e98f10307bde39d8aee2d3dd0f93803f131e3548218601279a4c7f7c34e67a6b01ef95179618c8dc2b2310dda0de25f0950d572d12ca545b10209edd282524999523802886f71a1ec95acbf6d88343c595c1f1e3518177c5db86218e50ac205f839c000d88b2156d1798435ae787568f62b4a7775c97d9a4a406792382c4c97f0a6c80fefec8d203aaa991903ddbc51059730bec8cfe19e0452fadf8150c17ff9c8c151efc172fe141d836f50784aaa99441739fc60173803f057cda1041c28105bde55b0ed79a1e9b05415a3054e2ec38b3f430d95d73e0f009435de6b002c8df156d5b67fbb930ecba347250d215bc7d6fe8651f82ae9749ab2a8a4f82fa7e787e623ffc0657f4330045a1614a3c2a431908b3dcbc6e9a0edb8d2c4ef90495d16db3d74b8c2fe14f6264cbc8ea8f4e8cd332063f4f4f4bbddcaa95e477c83d69d2b2bf8daca3088d545574b9a1ed1de993947bd06e68de3c67d58015a4ea755c26666a5a2fa3c672ac74fdb606dc13dbcebcaa80e3a94680c7981957406e6d6ac2e1816a863328b76ae0bf0a9087a64204c085acbf93cb44d665ada6c943e3db7dda0f779582fdefbb192f4e449070f7341514cff544bdf56821f62ab2de9753501d055898f58d128772b634ae78279891cb00ee607e6bd6b4ec0890ae114490b8aa2eee1dd9d5c9ef252cc852d31a7a8e1c6474efa402b3a58d93812ff1d9c479ecbf3915d4204dcc20c19301077469ee70b245a6a1b8aba42d0691c02837498682104142c720bcc22626a08ab65de12573e06825a51a4521346eabadd847fe2d5801112496d8df01ba9ae15ed3a1e875364a8114581884a95a4839d2c6f0ffecb076b6571e50b7ef381302a75cfa970380956d037c2f161041e2e86a33128822f628dee33a8ae92e3ae62e3f4d1df07b636192d9bd7d9696d950a3db412b7f72c03587c56b6cf9c9e44011412297759a9b30235efd93c5a2f880f509f502528f7f926238db76e4d2c5fb69879f8e6c37f3702b4ad8e0c49062133bca519cbb77d38bd3a14aafd901f0e351f31e57b011f92c968c0812fd8e18ce466426a00c9ff6e7bf2197dbcbcd17f7645819f4bfb947c826de6dc00a2104bc3280e49190b02ec1b54a26015711400489c5f127f4cf1cebf73908d4ff249be75b07ef47fb8f6b881372efe00b3eea330b4c70233387f0958c32105bb8f3f3cd15a2610490a97a2432e63dd1fea5d319a1565bb1be45696dfb23ccd2f81c112434a599585f9060bdf8b811b7d11f20cac111019e25018608120ba3b1cdd91b4915d46d83881bcab59674203ad8b0ee789dee900a0ea08c208244c973283683cb1153eaf308812223c1fa043e609ac240c2a12b596404d28058725c3870e80b246c074140511478a60c112474dc7be1f939279284cc6d35e6c2d596bb9badfff6cfdfbb56b582f98d51552b6f8eaabb32006db74dc4b20b727db7368bb583bcacc388204155a5f71b0dee9eb3158cd87b5443af473340d65e5b1568c4f23e8b5c89ae93570b0b81cafb96d9f6bedbc948592ba53739590011249c4ee2fc3f64ea3c76e82dd9ef1fbf923d8c477d8f805f173749497f067167284de24021d3eb4f4490a0ed10293790e4b38ea7d7df1a6f75a44807e47338545a755f78b7490b167b0c0f22489062961ed5113cab804b6ffb01352333d1899840449018c3e31d2ed108430421a6a60555228343800035b41e4fd9a7efe7aa45f40a0e69f3bf1b351d2e06cd33b86aada26d99829b2efb0a69ef2d237528caa1b9854346f191ac8704f1f8854e3cf98d6c36442d8d1eb1fe579f3798fa0106ffe2689a794c816eaa664490d0266f311638e84199467a8ec0d6c5397c120eefb8f817de33cd80a6301ae6c4185a55435983476771450489de036801926b42b2ef1408033adc098d4d32bbfbba436c0e1124ee3fe60ef09ca6097d5d8c9617616e623b80a7bc9b2840c011a3d72a7885693002d2971e90e195799fe0a7e938c3027271633dcd232248dc99cb65b2d48deb59e83180c6187f549865283ee70dcb1fb1f1d1df8c56f5f161142806c84321ccd8bcd75c1ded9f7195f45104f4ca00fdf525368554e608c7c2158b7ab29db6e5ea725f35652c86b142fac36bff426684d57f935215a81872ca62fe8ef0ef160d2355927e87218d231bb86a7a181041c2f5d5c882cf8b78478ca0f22b9d2e0eb82dd47c1fa4f4e9cd5a3bb27e38abf803bac87c27450b852ef0b83ab1cecd3010eea46adcbb2e8165eb7f1f58ff66b47decc50cc74385bcf40b274cc07302e4e8820bf0dbd2260feaf4b372978f7dbd0af13916ea7fe7e0e18ab9d4188c2e5b005bc59a6b9607fb6294ce3697efa2276ce8585db62e6a035b9b7ed0e9497b37aa9d5b5366a01e2a70294e46005c421f2764fc442c8d432ce79c30d0ca619e8ceff4d209c6a2c7a549883bc53a5c1d6299b584388782e4787ab4c36a850a2217cb75ff3d61fd27e4ba6e6be2d173657e698e410e9d039093e68538ea4fa1021f168553deb084ec77cc806b363f14da57ce4189be80e5bf4478f88a5b6e854b046653c2bed60ee7838ee3edb48b72f12e652a0f28a3565b3134074c8ce4acff24f7f12b3cb5e6ddc12dbe9d41aeea2231a558d21cf9bbda7bbad4cae4baa830235e97f86405c23def864146d58f540c0a7bb4ae84b08384818820b152f40db74bac39b492a9f65c818150c55096a022c50e24a03b2c96c96d75828511914e983ea3944d9425c3d42701edffe6ef1f837897bee4a9441e2766b525b0fcbc9320c08c26b293041124ee56221dd1de3f64a65b499020406772976c2924a1243a5812242ee56793546ffc4314f9f560aa7e532b2a0f69e846d88d259e27315e2ef4d9349738db5099b103f700a87a1485b36983dd18ad74717b0fdf158ae265bc2441a22b51cb18a15d50248a315989a505d2b661ae6dc452c0f480c4b87229c76db890e09b96b47486bf01078be087d5d7537f0b75972448c4064ef439ca70a2f4cc4d6f0865ac3f9f6044b61dc03b1c4dddbae1b3e64b12245644f079b2f4381df8427d254162e67c2bbc41ba9bee659b4b1a39043e30e218c341c3e011a334b98f762de05984c4746c6829fc55794036d7d24a8007705cc5b9f78ffd73443fc9df2ddf4e1931e991c85affae3529663d38615ae9856cf10117dc77b7c85bfb3c29f575f3401909337ac64b82049d6f7d936bce8a5cbacc00e732042da941c4ecfa5720918c20e5e85b7791fa3fedf71253122448eabca07757053a8d30a2245e7053285ba68917c02d8c2027b824414227626ec54d122450ac9548dcc46ad4303fa3c61ed2d6e1dc0b7589ea53220912f10ed0cb0a1bc64bb4aec5f32f0f217a75499088e2b9d4b7210912dd6ed32d7828cf5fbba14a7eddc6444ff3127cbb98fa71cb910409bf376f536d69e1c81404de6f90cb0821c211046b850bf31bd1d97628a6c38624f5a4994804559e0e26f02a0d808a4c38e33c2c7dcfaa5630f7ade3377b1302b791f6c2a22448f43a582a3c920f2739a7b1e23767e11f34f0375c3b7486160bdc3e1355fb9e5252e1d00c2f4d1dc15915d82f3231f2ecd93acb675407ebd48169a2e05daf5ab1d35720376899c0b50b46b0bb94a351ed64b260948902d50ae038dd80fd549fea82abf2e59731e9bcd210461f04412f202d6186afd4ed967833dd725cfd37332f078a7efbe7311b63142587755474f7f3168e9ce591dddf68ece20dcac3e2f69717469078dc5f3120d40ab38e3a9eca95778cc4624896b5757b4fb3cf023a09d5f21cf4a277458ab641914e2578e53d741b71e7890796bb4495c73e2a5019e2a26adcd49f61f6f37fe8a324c7c7f1b9388f5901c41a5b2afc52a0238ec32f5a91529306707bd628041208990c65cdeab7345865e33ff7e8191970f044a3a0a1ddb3405950ec7b6716e2d7493725246b85d78015a5ca784704f9a21028004bb02d7868e2ba53e8d9163bd14d596287d2da1285643773405de85a59af19deefe9fe5fe56bc51cf800c6a047556a644b25c6d3a7c0c19a620b1f1fa39da95fa1f3f40101c4228a98caa0bb034266b1861bccafe54e84dd18b06e24bea1738902ee104d06623f4cbc82df073ac926367b3f0f998572f8772c148ca499753e3d4ca6368214ab500cd1404690a23c038c2a8a0701bacab7f1bc039b7e256abbeb49555b664899995ee50260220db802768068d353413d3f9fb5bd2c1510ca803694e489ff57ce7b1b1df3b5d9e0152bd59d42378d04f1ed2af709189746825e71c7520eb098814d0e9fdd59fda98075d73e06201523fa2496b1fd59f5e39fb5680e87baceefab048192f299e3243c6874cb59c97fe82b03a21ab7f8c1341b6e1b5afbd77b1955b1a507307e976a588edbb6138860621bd0a57a4b1b2bf26c9441bdbb80c335709feabc3f3b88f6b482078c4a398dc02a13bd7fb3bbf4ff00571f980a01e3805047dca38c66076cd744017357b566089e10374f58f3a0589b05816d07c1f362a2ca0a4ffd1a257324cf29b70c6759a109a138a4e6eecd2d2b43dc769abb319768c67882ec79e0624aba91d3449370cfaff994012a18dbe48a818af46bc85981f7e9d7c87601bb4300acd0d70b4d2c9b7200e87d9509e3d08977e448f934ae6edb84decdae9c4084432519556c109d23dccab6450fbcf3342c4e02102eb17b4f7c3216e2082a3a530b1ed2381508e149a7a358b82b8451995b438a152ec32ec140646a50ecf4a72f74b9975cd869f41fdd671a85fa27e0ffd1d2902a1efa8744f56b087e36f365b5a9660cca59534234a0f6c02f940f768d551dcdd7871c656c6b90963c8cd32e5564d084dac71475cffd1493b8071959b016f5ef94637de8b390bf66b606812b3213af966354528f65430b6e177727134bc537a1331992df5c0188b6d408bdda8586035f8fc3a81c1a65d5b1cee2dd9d65e4446ede0d305de38e6d54014642c466dbd63519094079371ab777d4e4a82a7bbdfbb2203b933d3313812328bb43bb8371525a1360f54b1956d274901f589dde3ebb36092e41967a84560fc018a615b2caee9a2613b2f975f40a07ae435f750912cd99d27a3b89664264b1fa5fa106725fe0f09588e8b0616b1d869de2a1da3517551f8ae735d9d1f23b7c20af42f7b8a94956e8812968f1b1ee1e0939df779ea7cc21cf4968f5adef3ff22b6ce91ad49a782b62934b865a13b2b5a62bc512903d90199f6896ca74ea010eeb0515a071159ba31b486fd50ca1bf1322fae53a962fa5a88e12bc98e81907524b91b05230ab7cf71ec79570a2c7013e22f03a0c30d2aa1f41a4574193c39ad3a8c530780913f02943eca7188b31d801bc7c252ba87c7319b0584f1d4d8377134349fca277f0c019fbe4993fc4430d955b9e747913e40e87faf8363cca4fbc80c95313054a3299cc9cb69c100497bd2c04f525baeacfe27c98f37d425c80c078efb3ff5d4d4532fb5fe8be0885253eaf4a79a20c3d377efc60775b66255df42f324b16821f6c7d03aef613af0535b2e9a70cfa81f0756c47eef4688bca3edc92ca01fa25033e31711d0df414c55d5e2732322299629194f40154df5a4225b465fa76be13ac3efa96363abc2ef913b769d17ceaa575a89ec463c54abf51c7b1cd9a39acfcc5e104cdf62e20c8743731acca42dabe3e7ad689af0217f28cc5ad87ae9125972dfdefe4ed338926d7cf485c2ab6493587dd1476e601d9c1a29bd5da4331b71f7ab76550cba9c4e441a0dd3f0e1c103c27cbef50446bd1975399f31d125d32b4f3c0d1587109fbb38abc4757294fc31713183f6a3e0bc22d53be46b87618e2b1c23022f9cf6e04d48df679699de5e5ef86646041330b65dcd5dbaf8d36c0b1b9e359889b4b6a98e8656aa3da21096b78a18bff6d61956322d237a16e41c446a0452eedbc61918c3015991b8a0d6aa357466c0d4e11e7fc9252bf831f9cc6372e998dc7695ff00892d9dddab473f63beaf44d51c003f7566de91baebe9313496ae746312175978a7f7fa0d2684789f290d4742b235ab45ff08f7394f2cdb78007aed5a332f30ede56e6a8a180a5b4485adab1310ffe3c76d0310ea6a085b25882381e5f0405dee50fdd872490a9a43136c67804fb61656cbb7b5d675ca358b228063be0dd4c94db06f79246edbbd8e8da0ff1a3da273d33a43e6f0670bd8c138aa0e498074506003ce899b3541710f891298a5ff0c6253b68088e4bf6db601e970cd2eaa216f91602a4e88577792af8fea7d7b47d6090df3ef5279208ff15a6da11637ec6dc4f536f7d6db946ce7c7d4d34f37effe3bdc30b7d334989fb319226b8e78ba2456f59b9e01160775f27067b9b942bcef639a999a62283b3a0650bdf107b6ca462eaeb2dbdfe89308b2c984809707875d04912b2dfd84c5f523a1d28a36c57a7d3d994f59d1bd6ddcfed796f72a449cd3b3b058c11b906328275276d5ed9fcf6581c74e16bf5bf811f5b72c5a660514949f88b9df16faf49fae27b273e062a448009d14fbe6142cc9dc06fbedbad1dc76680acb4460f5f28aed5e52f26526bf3454bb1d5f3154659e59d5a09d20e14fa0e62151bdf51704dd826c165de9e560b2978bdbde472ba01752a4053c85c603ae141574283cb9a4cb8e9065b293e8f3baf30118dac8bad587c5d1cfa835c46d164ecf404d2529ba1e75ec0aa783ea7d0ce88996b3b7171a2b48fc0d5afd67ccf1b8d080fee0b07a30706096f30004fe3217c042b665b08c9cfb53a442531e9f5c95fd8757f0da8c46455220cde3b7c1eeee4f54c7d8f4b8d0b76cd4580823a2d88bda01565538021e4edbd55b380018f0fe0c9fa5d2c3ade070af588b063f8a707d8c2e6573b5cfe03409d02808b80978b0accbc0a2e877393d11887c739bee83a477d65464f800374e944d35433c17f1cdaf8b657e845d530246120108f0029782f199f5417059aec8d5a09c9106a1aaf65898007dc970415b0c76b8b74a10f7454e834fb63762eae50663e466a0eb8f8371a9ac28a42cb7db8f1da4cf0acfe82c4459102b9c62d762a9e9f6055806c778c40115960aa0df0ecfb18d7da7e25b711435872e68542e28b1f45f07f37bfdfa55984e92ab0ea50e5f6bc3ceb79d3f897408ec20e552ab6aad348fb48e7ee27bea8685722727309e4894585a0ee23d504f8a194ba0025ca6d86a764bdf7613a99c20e6fedb91eb2d6d875f5380872480fbf65366909fab90df66be1671349410d524c7f7789029b1b58e8e53fc8f47205abfe32b8b4664d84e28fdf8a9f789476dde4cf7681a35cc971b2a41277fd9fe5a0f028baa32646dba9dfba503ae9463b8b9d4f48e01246113780f5278fe44b86417082f168804512248e46c738aa63d0e5102f644875a56ff689d4a54dbcef957df7f199c03c4d4f0238f5a696a79e3ff8d9896571d3ffea583fcde128b3b0351a8f64d076c31e435a061e0df2570837d54b1e63daef377b91d8b16906a4600489704ce7bbd56f69fa7deebc1d1b3ae735852fbddcfa4d710eea60ced112917292888f182b8a9f082999811238b41af44929e6229a92c1b90f9f25257dd5367b8beba8170cc338a217450719c223a153699118cd08d31e7f39cd10a1b1d960e799470ada34c17c46c8a64183beec5c0a1ae997f7b77948effdd7c7caa84568075a3abf1af9bbd56b8308cbb22e3eb81a65fa0ffc087156c5bf77ae91402614f982b50a38954da6d8fb4272cce747253b76049a9253f54b1b0102018db33d6faa2b47ad00e6c5e7da89cdabf51c7a9e6228c4e5688a98a0f6f74c41d1e8bd80e1f79ff79c3cd113eba99a083a1b0710d9af719516fbe356f967c585d99b3e3ace15306bad045b052d593a373ed3c10c8923ecb8dd5a4119422c8d165d3690f94017ed4145ee7afea315e3951ce1b831ae23a56f80720b484e2dcbaf9ec853b5d8e1120de7a9008ea0e8d18351ad20badab98dc3ba205aa305c9a24b232ba9eb19938f0a9599fad1ebf9bc2377bcaab02030ca90df05ff66bf0ecf3b4cf84f73f34c8f84ad24244746a64da9b8a533379887dc9ff43b523713333289fca949facbc5f26b7589393790b49247d76856a30f47878ecb3ab06d4bd1a375622cbca2c7b090934061900846fefb0fdccbf64685d0923842f9f9e8d0db7cc43fa2736808cfb352f17faf2349d6960dc7f5e60c6caba913f7dd714e54e17720cfb1eae15d0c0b041d829f0f6a4f1c4562c3f22f13582cfa3a19c887a2eee78b82b97fe04102664c32b7bf0cec947c3c645604391f84626b942f32be8ca917f19f3ddce05df917e79d08d3931ea9259261fe72d6eef0c48af27055d02fb5f58a68f6c9c0960d8b105fc42c1d80a6aef4fdb1c27aebaa243a47896e159c74fe78428eaf2a34eb08f8cb39c8426dfa41b83e90ff0d8f751d0363060031121270e6a0c87928cb27e32ee1a2fb8b5e03406ed1d6e1671134ae500cebaf20882d6559990839eda376b96d369b4269c08a3c16d43809156e99694ed669917d9e5351b6573d379e66e3c5f8fa71077bea6c6c2231c6e189efc9f6fc9c102d560304c15d047611badfacfd13745954586678c1e648a2c9f1db1b675f6dee07bb3a04b96f800127323d4a3cdf4e2f32020e52488bb0a8149220a35c363f4ea25eb1616044e3a4d2a308a59121929e02e8280c43de89323f6058a302b4b905f8f8f30e4033b0f8e999c22ed06d8b25cff51eb3ca78c17d3687c2222236db9f1e2a1566dc0a2f5cf67e492d32926744281b06be5601a3bab0e2e5a0c408eb4888f1df87701bbba20f01083c4220b63aee5474fce455f72ae6175e75465c9cfe86772ff6956d5926a1d84dd409509e1682b0b1a9ece219e6fefe09e3c7993462571245b76c6b6df6497db829a447978c399335136826c7c562178d788aa256e9d998183ac235b9eb502fb2297aeecc649e83330c4c3ddb822ee67b6c3368dce8f649a8351122aeea1cab595ca9d17e3393932c6526739dc82d70f8e72e1c83e5dc6be5737a47093e44ef714268091899e795d6890b76f81d0f779504e0896747987098c1fc23375e0a35354babfbd4c99dad923176600e5eb7fdec9727fdbf0eb052c3b5e927a830de8f49392a4eb1d6b64a56e4b840d01ce05a7541dd91d889f25ec71a7e3c439077362bf8f64d40998ed6661d9b24f30a7d5be4089c4a9ea5d3802417c5ddb37844fb5f80c6fa1e15327580ff633ba048b52ceda195f8ab4a69cf9946497ea0e2fc8b45448fe69fae4200974bf95487f0749ea2c9f50280f768d7389f57f1358cb39107abd459194d84676de4d57e415db23c6b826cdcf0ff51557eefadee46c05d810cc45a34ac258ddf98b215a53a7fb2699fabb5f9616ff7a1ed4a33e5efd6f95e9b18f15e9837abe25b6c037a7d2a354bbece90a8be4e5f388afe6bf103952683bbfedc87a601b0025a01861ba8b3f18a1f271e2b9d00446a106218991416d7e7756b840b2131072bd638b67b1dd93cec270d036995c8a01d544520bec150fb35da21dacd9d9cebfe4e4cb1834cc8f5b88a7536e09a4f9eb9cf23befd2d5544c96b2c67151a746277ea869610247954f46d5a8bcdfde89778cdc43c41b6c76f8c80186ca92296b6e78b0dd29aeb909e53f60c0a9a8aede68cb9d0d216be738d68f3d6cbf774d94868f0e868a22575dae7d1f0bb610cb75716ad32d5df436725a291d9dc9e517a6393d49551ce67579d843867b3ad5aab9db21c85b1f30f5f9aa0619ce2c63455c4d24ffe5121b09405d4d34ee2e8c81ce6eaa9222e8a8daeb7433caf0cf89d5b109ae644882963855d6ed9994397b11f70894d92d2bd8ec071386203036a7f413d55443b25a93d4ef607a268dbde33f855145f6dc07e9e6f3759cbfddf29fa58e2a3932045dc34bc22d4e385005df99689b83fe9db2710f54bbd5ac17050c9f4e0bea1bed0a2f225de1a60c8ec74be47fa0179a2cbf8c1f15a4ed103477baa08f7a3f39b6ae26f0477ee23ecdd45a6f9bce670e0941f0ac8dbaf6d241e425829d527dce363aad20e71dd733df00e86b8b01c3e24fa458a47e7d3401194b014027da40704f373ef83be7986a2a9b99eea440590708c46f2ac7c6893a1f8b23b2dc7a621176efe173e7cdf5fa167b2b2a4a5b4e0aecd44b018ac1aede97600f2dbf226e2f3f637362f1e366a24c2a566fc00b2d52040eae6e5ecb2415fe1b107429cb7ab70aa99ba1f99304d46d50be56d95089d2e5440c6636672a5e06c1c7914bbf29e1813334f72de38bc3def6a289108c7f093bc16d87c12ff1cc3e758219e76eadfe8a1c40e65b936c43798039ad5f1d482743468ff912d00ef3787385935ce65f7227e7fc3591f669d54f45690f3ca4eccb5d1da4f98305edf19ef8c0a172eb0f8f3122fe705cc48a032e0f4039fe7456d821999170c7c627a31b4dc41d1f8fa18de8a0d07dd8431c26dff128699b4c0b16af19003c604d02b2bae2e848ffdacdc79b804a45118920bf0f6a0e3254d3109479f027851d2a8315bfcbf23a2ed3cf6ae4941ba1b99d92ad35ce8c17d26e7b8dd63e241688c8fc208ed3453b854d5c03f0aae4b44d047f6bd03c827438ef16544e8fc570c9ff2d1db4d0d11a860694eec753e2286e6335a977605c86a45112bbfc99ed6245002e7b4a56b43588cfbcd80564269cd6cedd4bdc594196bfd656b896c828e0585a9261193f1ad7ecfa173f60482b17dc7023c7a56e308d91d44fe0d5ce55be003969da8dbb9b7d750e815f31f3d047f6ec662fa1c7671d6a937d4f406fe6d39c9428ca39ce6a6f5869387202b3b56e1bf78c566ef99c1c176121eee9d9b0e0d198a403576ea14fbb9eaabaef2dc930060b59b8e8ad0a4574f6ce5215e116196302c73e128b6ac8362e4cd34457a6be030af3715747fb29b651be1a8b567f250e641a102aa9ce0b878edf27061e4ac2d46b59ac4498b976e70960fd77c9b565d8ce4fc513f3c6a2dd24f4f897ac18e5ea27d92c806ec170342bda744867383dc6c402e122d77426a781453c311e1f2daf121be032d9013294b120111c87278bf71e6ef85484c21577f1ea3b29d30ee4d549d37edec0822778d755caf9e79162675025a84e135cc9375d52796388a2fd19e8546eff26746b1f08e58b4c8d5929d19238ea1db0d61e33cef961d62f02e8954a0fc091bdacbb652e8931bbf486ba54a9ac60a3139230cd817d950c65858386824ccd7614361a1013db7f111f566e7b32f3565b9e41fbe5456224ce7dbf70c6439a029a3bf60db9723496bbdd2f991072aa65c50217c033c236f853e6b7cd16487418734b7d6bb7d6a45a9c2a67d0f446f5b71e27d55a0f483d2f96db613a5022cf5dad972652d913faf8db175e35f2c9522d88c8649fc31c1966263987c383b7124fcb4803b1b0517c86364c803abab1fa1884d981672d31ac5110fe6a09993861ddb3fdde5b9544b115afeab1b42a1437182096f28cfc81a7f17247ac62635ce647a2b6a91bd5ad5285c4734ce1c34d6688fece8b65ecd3b19dd515a9702d3e265d2ce1b796613f1ec34c79ec5f96d62f48219e7e12dcb59aa9e4bc1f054768b2adfb4777ba4ab3266dc582aa5a3741b49f34ea92be9cb4602c6d95429867529bef61421a465a93b2ea462813cdb85242e6a328cddd8674586778dbb18c26dad96137024dc6e50c7bc0e85f24b2e02dc5c2bc1866b591ebfe2ae9c1c8cb2c99cb1b8312312fc93bc030bdcc17a6e81fee17e0083217666044501ce3dde4e2262291175faac5ddb23d2ea7abdbdcc77cf2031d16df3f7940081cd84038be1fb60cf59353e825d702afa3a3e62c603fb0745052ed3d1b7fb253a17423183bca743736474bbbf278436f499d347ef09304e9b88d8d46e9274772fed418b73aed757604b09c18338a3223fa4dacc4de6c7d21dd312d0f1c233d3ad7752feec4eb2af468ab1fd197fe6ba0af6ce5a92489e3c1cdd8d48223cd79546bd4c9f1821608815af1204acc2e2202a9bf28644edfc83ad055e22a4bb225aa5437d96bf1a170b1b014074d39cd99250c0a8bf2bbb35a88ac920f2176405e362a64c0749237f99300d73e63c8c905499a2d3a782a1cc18649c42410133436a8fbb379148d9462ae79bfcb02d3c62a92612ae000be6772f8b325776f7e961aa7a16abd7678dce2861f3b0accd0309fde2df0998afd37087b599091118f3e62343af9e7c8fa62817367dbcf52bc7e32406a264b7b5437386abd8508ee148ab6fb75801f16deb05c61aefe4d19f9cd213e9f0395d4fb46426690d514e0e9b74ba5b624eac5c2774485d49f8740ad637c8675a98762f117181cd410755f53d88086dbc1aa027c109b004ab857305e0abdea1eeac33c19327e50fc47ae5ae15daf102a0d9f20acfd844869552982427ed1235db2bc51b433ac218a5658d1cb1c30cf8e40c9fa6c402fe72f98f1fd50f34167eace63a97f6647dedccd0c71bc50ec80d51791e728e39799c98055bfbf0569e06960e7a7bb7f230567b83c090e741e4956eef7c2801a2cb1f0c41575f6dcda3fe305553009d87219105ae1a4f571dbd8240bda07746524f7e6167bc0d7f45f76cbf78e17965593cb80594a81049cebca5988c32a94991731d5f84c2439b46a05e066018a33aba191470780c686ba8f55cf4e1fc463ea4cf0573f449c25e9f05e1f763693066180f30462dd35bfd2156980c7fafed7db6a009b0f8696de6c4f4e18513c25a6fa0c0a6139c03ca90a763a8b906ae2cb0e5995a8ef045d7a499070151743ab48dc7e39f5d36ef1c3a363c7cd75e176d3a5561c8f028f17ac54545cc5c6f6ad5cb2f759d8d3df4898f942d267d08675f875ef259ab565c3c8a3cc23506525ff91816664b42ee9359531a3bb250620152235d9728a1061a616a06786add4006822c736f7220ed8d391caf7ba8c294a629c9546c823de02aa19c32d48c4436ee52a4e057487ec9d300153a8182dab5347cbd247a1a1414b31ebfaff9de3cabb4f83de2877a3c3859ecf044d31e81c4edca25133059c1f7b91b0b693a7c215fba26c3e8458308b729a287e2d8a50252ace0addac06d31d01079a55ee0a732c8826d87228912329c1959b6a2b795cf50d36ecb1e303e8ff361aa3ae1e3c3b90e540f6e9f496311f84eac96491a9fc346a1bc2f6db30e2f4950deae7d34496a7a59e9f5d8ebd31cd69635159148ff6ec556a657a7abedca0e6089a5ae06519ac0cd1b4c4f83989545e913023424be2c87fb249aba2544447d463d3559d1d6e29eafd813ad94d36ef51e30decfaeca8329184e975d1577a3d692746f2123740a8e9b4621858aa889c1e72bf150147bbe39e8fc82392200cc54178273c17641463a8c0692100cf4b849c9d8f2d55bfa88dc8a4af9836fd00677c36f62782e215025396fe113c92fba3cb2ab0925400b40a8455ed461dfd3f6b9b616e10d25dcd9bfcfc47ecb410c37497321fa03019fc0d3834cc6adf47feb1416c19cc01849381621704849344297d1c4581e94957dadac2811e6f7432df612e0843fc9ca048605523969a65c66348c8dcb2c36a6c5e569aff10bb8ac55902ccc764ca2f828375d54ec18ca021945b49da453f0b922f91c848f7c2c8cf471b1ffdea8af3e4f873c060c151617c1a1b8adb5dd336584e1efdc7bb9fca14529e596940472702837960dbe32b38189351c1b3e4973cb5d1b66f2200d3c6ea577e8053a86f29439036aad0fbc4d10688c93030073388269842f6ecc6c05401889b54232dda2ca812328371d9cdbffc97e2fb237c5b764292991efe0266d7447adb640e447cd784b4a4a4a9a6663c56be7d2f48a8938733c88480a2c0d050d420aa01fe8318198e486081db0e1a8490ae79c0e6c74a08373d455fa0310a7b9df9735695aeb57e94f3e74f3071747cdfce1c51f96ebd38c942ea57bada46d94f46bc62fe9577c8d1f7394fa55d22c3f42cef971a9ee2d528973ec106a27db2edfc71f3e74d3c7137d18718e4272e92b5309db993ecd953e1c1f9927917cc9979c98f8c862f111bae2ff8461377c4c8e8ab6c71e7b6cd94367ba662a91dee3ee01a29aa032480ee6c841961c845c0e6e0e8a381c04c1daae52556956921888d0445a498863a44c5df1d78565a5ee437cf2dae447d63665a525941f59242df2d98689a64c5e436254ca366b67ba8af757267f6193af62892624dc22eddc4c14b77c3661938e8642659e94735917a65dc1b29ca94a865dd9f4b42312e952d7590e8d46454a941b25334caa2952a2dc20a1242f91ab9c04cd8d9299aa86060a154d1389722e4b9bb49229532e0b8a92295376b60d1369d836e9a9f7194af3d6cdc7264ac944edf82adb755da1421c23f9cbdb4c944685caa834e566a2b49d4b43d1762e0d05c36e747cf75969d3239fd968573c130cbbd9f147f428339f259e2a66d003378331a8acd4b50dc3b2c98ae6b5929e348b898c8c73ee08e73c55c8c026f3dbd753131130800c7a60230680dc9c11832d54f79b761e3262406549174dc0c400870ccb03903cbce84bf2d0718ecae389a3baef7e091e7338e71c133cb63847e161e372322dc2638201124030f0c2398a8a35c180b4613520188076aeaeb312e7d874cddc3188a3b43bec7077e8e8e90e238e3a52c5c884d9d103e7282a32323754ecc8620715a7edf01766bd6010e71cf5822dd468fa58e8e60521e7a8eeb1ee621ce805514f1ff3d776799e791b6c4b7243840b6c9c738191161462470bb2b4804a0b62b06bbbfc68345d57266f4587a64bf309c9a45923ebb274f4745950a88f41995630c82463437d6c9a2691deb09d2317666d1946c23252d5bd9e904c488c4c54df66264ad3243d9a66a62348326c2fb9823dc1b09b2ec2429acf421b56d369447a3405c36e7c4ea69f60d88d68c64b51b261351b5683c415c50644a4cc81c71c6f38e788343107166d8e278e480f7258410e429c732f72e8c871450ed10f93cc7505bbaa5c2524d3c7881401c961431c8738f78325cab49f2ebd91342bb421f961daf4e4dcc70a65c4e1451c56e2d8426e92413221f96112040e364271f810470e7038018e40e090c1142b9c9bb428da1b221574a179c3c91b304e6f7a89d64598136dc71f31d3fd8e3fe209ef3326daa6e36b3429d8bf68344d73038fccbb81c58db0ec4f71c3c69adc78aed3749a36f6a0badf11b5e1451b4bb421c3854d3451d8d071ce590762e33a8af217e643db1a85686cd374680d3b9c23c281d6d0c1b6358af0a49d6dea961a8768931a35a06276fca4559bd6a969128966ae604f32ff4f704411e7b02799e6372c8990a64357fc9546288d266eca1a2e08e73e73ece13e7f80a4889cf360c9b9acc98bacd0954947439191b9d9d948231f73619735697af2a22a9987a2693abe46a7d3e8f81a2f2259d98d3645f356ac8dcf681b864999b1ba1f796e0091e00d97a38da64dd322b78148f0840c40a6cb9a264d4f7ea4b5c987b61be7b4e96353c898c15b29894a1d1b796d6b1955651efb17cd194e846558e8ca3402921f8113472d190188fbcb62b2a5902d73384b87b815ba3261dbb4658bb685ca161d9ca3a28cd103123686a83406698ce71cd5fd654d620ce2a87e69cd12830d6dd32c1d2f860ed5f5a4595a0c24349a35e9ee374b27fbcbc21e70d16ca212942e821de7446064ba3ca95b5a9bc218c4e930bcd0b6306c9c7354183a38e71c18803830b25c53e6439be5af49b3c0b0718e5a423329b9c028e2b89e34ac7f6107b584669a2e6fc5ca097d21850f6d313efb42892f8a38e7429b16e9d2c6b506c494a3b749030289038540b34280c5392af3d7152cf32291e621bee991668db2e74021b0a1405e14328db4cf2e0ba380956dd3a4b5cd1a652f6ee09c4625868a36d2992625497243c48f42448e364a724344a7e99617460ee102022f1cd5040848ce514d80a00810e0e02619224efae8628e4926e7b226e7884040ca0cbaa0924d972761d3c7a6aefda65dd6241269dec5922e904c32db157f4d3997d5c50c5c1ce2dc2433c960db44511f9b268e519ba5afe84d87b6699a7c684362a24618bf2c1fdaa850a97c46a2324d3dc37ea6338c34f2db343379ae499a06c4156cdab22bd38e3f629ab02b1b75e5583ec3fea4bb3569fe0307c06a322fea977682d5884425263ad8de4a5196706b66c36a327f5d89b26135a3d2c8d2d150ae1c4bd366b01b0dab09f14d43d9b01a8f1b4eb8386765d3fca645fe3be73cce7907f240100e5211522f266684651fdbb2ec91458a2c365a1ca2c51f5a74408bab05288b39b2205139943792854d163a1c42752cf6705864c162092c2e162f5c31c715a42b5e0700f1238c0e670520566cb1828a15af8a41aa60a30a29aab0a9c2089643b0d880ca9495306dd37c1761d8f62591b622237383c5c6613182858a3da830830a1d47858da39aa042c5c481255cc0464148142528a070841dce6d57091be92a1c7be27df62fff048684485f9855012c15085560890a1c79228b8703313b8478cf069c96513b0b706e92c93025d38ef7bff2fe27999024896142424492aafbcc5bb144be579ba645a424473a0df62f6b84654cb4ee73121acf2face6c88424c9848488cb93a2887cc77cc74695f75fcbb92c2c672b61958e1e61ffa221e225d1bdff15f7fe57220c2369de33c97cbfbc56baae54641b64e372cd6c666c18c81b0e9a1d5a486b461ce04059109c732e9b230b653238b1071327ca709acfd1a41d7f848ef57d46d2767c955dd29cb071c2887382b48719241daa092a241be73ac64940b89fc3775e0a1e0a7e089e0faf87bfc3a3e153e051f0c4071c099d8bcffc125e87ce834e85d39bee5ab65d254cc9f752b4ad45d3b04c89731e0d4ca101e73c1970cea3839bf60d3038e7627020dd250a5a10e75c8ede2acf2fecea56b569bd5b3cd3b48dd309a022042a6c50c1e29c735426aa092a3bbe4a551552ed51ad51dd2796736e09219a088273344d989161de4a75595ed33ee3be6b254df2a392e6b3ca679c67def7cb679ad4a48917b5b5894a2325762a2d4f2989302755866d3af324acbaac519425ff84a5e9e85148d3a11ceb5f446c9868cacd4d1ace797030309df348e19cfb1896917c8671e73c386c9a739e0b38982a1c13edaa8af19bce7835658969d3d38eafe29c13c239176690420457651804aee09ce395e719f69df344e19c078a3d9cf3942c1023811cba556dced5e19c63c281a08861538028a1972a0ef480259c73d581a2cce01ca8860516afbc8689f8656114d8bc5665d566e97850cd0ca8e6e9e04050aae0904c3ec3f8d4b511550c14eb9c9b649e4c0e870a3cb1e39c4767cb309276e96cf35c89b1527299efda87b48cdab8268d68686868687a98649c9651db1209a1cd3890130b38e7ae2da6c9164da6b8a52b98122dc6084b9cf3e42cc609520c1673c58c6244a58e41a9e29cf388b49f22234381cc87b62848c8c858ce79420ee4802262622a01485ace77cee39df3f49248274104f7496859a583edcbd28e086d961297274511f9ebd22125228c631b96d938e7e11a13ed681be73c7bd3ba731eed9c2be22a9e699be64b4e78299d266f978591fae5656446d9e11043c5394fe59c6702318f26623c128891404c04709870ce7996502209e75c0e3170ce01c081760dce391b1ce8c5f1cc70cedde0408f8b87e5e938e76070209b1994b8d7f11e1c3c3bc450498e4c486464aa0d136922bd619b36d299b6c9bc15113685ba82733906899b9828b50d136953b49ccb0a6d55e649526220106313936390604182439418061441b920fe704dcc6988594b11a83422a179d2ce5605b103f7745e107438e7b0cc3fe182001db96212dbe52d7ecdc024342935dd6fdadaac8be6f2a428dd6b984849922339fa46092813924e638408ee93b8306bd33e53b2c4082320207c00841d40803c503c4738d0027a1013f38018e77903f40321ceb92bd6d4fdc63d49c74f9a350d41a5cab0aa8bacd2a6328534ebb2fe4413e324a6498c0f310150308949c00c3966ba62cadc8eef18f74b92e8dc54e13ea4a47ab1d31c208f03bc9163762039e759624489911dccc0010d1ca4705a46756c140007c2410a0e0fc001e686281cd1e286406e78e30614dcb0a409191e011022001c08600e017821807f636363838d731e233c451801d52089739e0618a94003a00ce103135086f0c1862cd81004228cd840870d73d8e0019a1e6ca85283204338e79171ce838f94c039cff558e73cd5390f75ce339df348e73c11071acc804e9c00000d170cf1c018cf214f88199cf35031488c30c0394f10ce798e1871610585c8e0ec90428a1947c40516ac4006198ac851848e22701471a3481c45e678218f1788b00574812d20cf0b778c51440c90cb0305595ee041912f3e777c3e2fcb44c40f47048f17fc0039e7c2342160720140c034f920c5e788c352240bc80b1db67c8eb8190a4c4bd030030f97071a521459c30845c228124611308a8051040c4f133703839b3e5a5c1e6c14f2821d5c808accb83c56b0c78ccb0305598a9051848c226468d1e281430c29c40f1abce1c51b5bbc91658e3754c046962269041046dc37c61ecb07e38e210b659c40bed8ce8e9fdc7cd78aed8e103691697fd1732fa98df77ad8431692b0acbf882590a7d5d17abda79d71d7471a5955f7990e6917da0864fae4955377fef4eb18dbe21038f9636a27fcf2ca87e1fd8189fc1ffc91cff7fdecf0d5190a6916d625f2bfff41ffeea555df5963c8427f61225e5dde8adfb011969160a43538958c122f49e469e7b55d7329259477fb5804125976499ff59f4ebdb57ffb26efcf2df7fdbfdb6b8dda4ee141ca002000b2219536af95b24d005172a8c9ff45db3785df6fcf63af7509940cb7a5736fbfb7c57dd3f4af208439d5f67fa54ff2fbfd72aae7c37bd7e9ef110fc8fbc28affacb2fa7dbdad2e2fb2b0da21619cc24e4b3037309b966070f43479d67eeb9dfbeb4aa9c53a642145e224730a77d5aff32a35ed1633d1243f8de5ae57e3ad23fc4fc75f13e6a6090c0da56d96ce3629304a6068606e9ec06c572934855b14a5657e23e9aea9fa600d4ee5a98249ae51e2a7e5ff7d5b0ca7c6b6eac52272eefcbddd2ddf754bff1e0d59b87daf9088253928c918f738e9fe76dbabbbb5558d4c8cc81f4becefec30da777b8f210b2f2faafae5ab1929356226eb6dffdf12d20ba9eefbebd0cc79a28aacc1a98e1491a37e7e4f2dede4f64f6b43165ad80007e4699fae765ff9e4d611bf9085562eab0af14def2afb11de24f95ba8eb87f342fe7c846f9461bfba30abb246d8b523c24895dfb49c4a3420eff8e0acf3fbdf6bfcff872c8cf11a4144eed37f8ba7f4bf438ee78b436408f784b3e32d3d8fbb7e990cfdaffc4f3bdfe6b37218b270e75b399795599a4461129cfddc77d70967bff2c16f43167a51ce555db823c26c342614b523c248374c98684ca81895687e4a139c23342614a5b106a7faa471339e1e7229b987d23e897dc8c24ab319bee825bfefebde778f3b64a1a83482b969029331c9bea8040536a1a89c27aac0261a138a823914455110d7e0543a356b0eff7f506a3923a6f3852cbcac3dc27895697f59a20ae6c0f8e0129afdc450fbbf39bd3d720bf110334b5fade5f6da5be3fd584b4865de9fd6bbb5a5317269efcb362dc7dc9fc48f5608a9fc36429953da7ec98579ebedafb51d76bc277f386421cc4d13982914957359d9a65114cccd1318cfb588545d5645c2b21e67b691e493972fa7ded7cef785d1e27f43166a7edbd9d508cbfe83b089c664c29c48374db4710d4e358410b9c65da997d7d6f77ebf3ec394643a896dc484b506a7b254c65c733da984da6aaded8bc953c28f2da751734ce7d7210b331de20f2a812463ed3fff10f31dfdeeaf862ccc36adc230374d60fc66654a685a89ad3482612205e6d11a9c0a0906643dad9c3bc6be35f436d690859584350691dfe4ff6edfb7b453d25b4316facdcaaed0051cc9b6425d23c774cf78eff7d76555116e7a9461bf6ea32fab910c1f8678bffd22bd10be18b230a495485586fdaac2274064fdebfb7f4e5abd8d15de90859b2522690ffa8e5dd3fb6cdb14c2990564ed35ac9adb5d2b977f6739158c0ac87843ada5ee74eabf3784210bfba52bacc368616e9ac0ccc02881b981b97902c37d1257b414cc044c8ecfeea9e38371de3a37ed9775e52a615775a1cc0f197afa79bf986bece99554c2dc348189b294617f478b489ab584a2b6d1a7289f611ce6c5128c8834b2606e9ec054919246961c952eb98dbedc3e64b92d9efbd938638f1cff908517da04e40fa9edcfcbadbbed34da9085dbe85739975505fb0ce3b306a77a5396b1fa6ef585d762087f0c595859c8bd95ea8ace2cadc1a92e02461856897a5655301ca0dac100a5acaa6ae8e1080f3bf4500003e800bb2740ccb41caa4dc7db01e0b0c30d0710c00b08da10440d466800628649869c02c4d02f4f22e91e60288280170e10001f00a015c005223ade001f8f2bc2820000a1041e3fd2970b0100c20f6690c1e5c1822d66a870a00504e240343dc0c8e0f2584121332e0940a839c114992b64f91a1ba01b94b0114319157002802e5990430b5dba74d98273eeb347112d2050832eb38f2584d000377668e2afe0873a2400441846b8c002e600172fc041451bd314aa2e53b0628c2e5ac84115ba74e9a2052496702106152c2049974f009e80031607d862881d16216648014e1157f0c40b83c8d090a1041158518e2e516842932e5a5032852e5dba6421056a008087129c01c383a652ab1c9f0aa9870b061410e2904d0b1f307230430f19190ce04a15a4308710ce88020738413c28541e76ace88338e70141410382f45031d1c487209abca002127041077710210328e8d1240135d8a105147e60c00fb2b8c309610e0f700007092158a83cec605187cc4b0d4ff801160d5c600deade500341b60ca18a3b7808a38e22cc18648f1c38e1e20f0584c08f2d9630624b952cd058801037a84081349e08b2032645a2e0830d6c60e133a187237c60094da400075048100135f4702308479c00824188b0011f04f0410b19589516386298e286178a7021450505f8c3d7c080289ab0022d50d1470c194cfc2e70c00203f0a1c744c50fb63fca10a208163da852e3022804810043b823082d5158a0023928830c1c12d8f0031974a0250b506460025c0cb05313050d0b144287963482d04201404974b8469670e9c0b6d1882d12d0000edc8181299208b144132690c0177ce020c8c80103e81b90c1219042a2180108594264d0c0c315516001c1d86029f21f18512009420a3e4c891b30810eaaa081068170a094f1d0a190c9df702a668858018a6b8a3d6cfac8228e1a5ce0a9a306622c4132620d3f36c003174d9ce1031304dcc0047ddc80080d02e18013853801c30e32041a30c510a2c88206da102fd039438836fc88c20548a80386074db450c213556290e202536ce06216a68b21054038e766e82285179cf8c0076330d1e505007ee0d0457683b56080a80935a0428b047ea041089490450a510863f4e285168268d1e30829f86227c906e028001731394cc082820f88600a3bb010a489e8091771e820062b4838010c7cb8000543888080d9c32400931d3c2f4bc01740c21747f050461c4a8e408307fdca111a90c20604f0829cd7c7162ab0410598039cd1650b6d4ce9d2858e149c61e36ea0e10601c800a281cb75202e47381097261c880b051c88cb051c888b1607e262860371a9c381ea785c6ae0405c80e0405c96e0405caaf0020f37bc4c0390a1071b9018c281e8980e44c7100e4447120e4487130e4407061c888e2d1c888e2d0e44471b0e44871e0e44c7121ca80e8f03d5918303d5a10007aae339501d43d4a18403d5f19d732f456a28807331d05083161807d2421d484b1307d282e3405ab6036911399096271c480b1607d20286036979c381b4d0c081b4f8e1405a8ee0405a0a71a00f1071a00fbc38e766b8c1ed00fa3670a0df0307fa4970a07f0507ca218003e540e79c0c34dc0085772028480e0405150e04c5160e04c5091c080a3a9c732097430d6ae0e0406ac038901ad481d438c281d4d00ea406e640791007ca4f70a09c05076232830375200d076242000762f283033111c281980ce1404c9a38e75e7020e7021093c58162c470a0981338e76a806166a68903cd7c079a2983897308588023007680150ee4801138900392e04045f8e04045cc385011551ca8080f3850116c3850113370a0229ce040334038d0d4820351191c8812c081e80fceb91a66385284031d990e740408073a628303197134b81c0c6900158c702e042e8bd3e2c5062e5a46394763c38d686fab094e709e1f380f0b9ca7052f3594a063570d546828c4391ad0706e9279a1a14f3234c04c322f330032c9bccc508249e66586eedc24330312f72283216e927991410af722430f2f31fce1dc24f3124316e7269925ee25862593cc4b0c2e4c32307081214bc8bdc0306ddfca7a55a4081a2f45ee4b1117429a0ebdf0879b645ed832c9542f2f3c99645e5e98c14d32d8bd0480cb4b002ce05e02f09c9b645e00600703dc0b00ae70934c7633c900a08749c6fb5f612f2e04e2dc24f3e2c21b6e9271410ae72619179c4c322f2ecce0dc24d3834906ba17226110094d3244de24f3f2c9c33987c4bd7cb24c32ddbd7c60b4170f21938cae5e3c585e3c2f9e1e9c9b64ce00210173cee1b8175786738efabfb435ec92d19beed356225dd6d4b511582f4d498284d24422ad6482b26489699b2cd24c6591286dea970ef1cdff0cfb1669a6aaa89dae4b598e36aaa8e9523269d4846d3bbe8a9e344bbb34b5e949f37b926255941511a669d87659249d293169948834b2bc15af6923268a0a9589c66646dbf155ba5555d544f98e714b4fd41396881a65d8b7aa6c1269ac0a3641d974460981f5d2949b9d4c8a8d66e3ad581e15b4a1024f1b8238f7094409ce3927c5912b800801018168c00534370b3cc0098203aa28c49037b410032cbc0e814c4f98c20e0618414ccc2e696c04e2c4391748104730c439241312cf1a48001de1891a5b9134d038230528981263464c19273041094840868d739e11e8409d17cf186288c0138673ce03e502e130800920e04c00e7051c229830c4390f185fe0e00901c8e5e00508000179b8d882087938e79cf37c408b0776c802003d4042080248084f3c5a64414dc1e28a0ec4808020851546803005be4aadc1a9603c866449f7867c472d31dd15f65b8353953c52c8f0bf1e69b7f472adf5c41547216b18b9fe53c3f7eeaeffdb6b85070a594e0c71acded7abedd690a26c05773c85e44727e630da1b21df9aeb27e4a7f5a7daf737a1a73a421ab5f03821d307af7dbff30b357ddc36217bbaf9df147afdae9d1f862cb42acdba5013595b8990bc31df97462de1a3304aca84ccfdb3f3fa483fe6fec27fa316cf1232b7b5c7fae7dcdfc2bae3a44ac8b3de6867f5d6d78727dc991f24571ef9edf6e20d618c9dde0ad69884cca1c50f6a1c3da55ffb1ab21042cd460a0c8ccd9388048b219535f7d3cf79aff73d76af1fe01124e3292ba731cefdecb412531445439e403285fede397bd512ce29fb148aa21eac20d7acd1ac350dcf11f2adf653cbefff7fdf0fbd11729fd0def7bc9775be176714aa08194339fdee935f4de9d57bd3305b835355f10092f986b2def8e7f5dc472e95a0288a8a562aac75c0438449bbf59bea7f7fbf5c788690b5b656e3497fd55a46fc342d528265171e2164ca6984123f3cfbd4fbf25b410f169e20e4fae7e4f7561be3a751ef1d6d4351b50221c78935d5fc7efdeaeeba4e98c4f3833c6bed9e7bf8a0e4efeb19b230c2eb83dc6b7fd353793fddb8434cc2b2251445c2b2de335d6a92f91dfd44a4710f327c7c46582d8dfa6e5b210fb2dfbe4f8d378414dbbd2945ed20fb8f31a45a724ebf7db0e648ccaa481aadc1a98e7874905fddff7bff78bfbb7bc84316e6c028d212da1bcf1f19ee6aede5dd5baabd96de8f4c37edf0ce2ebdb55f621a18253037232c63c23d690aaec1a93c1bf0f49177fcdef2186dfd57faa764561deccacdbd353895150f1f797e1d758716df67a3dc71cace4651214d8728ead6e05499678f8c39f5b26fcae396f16319b210c69b836cbf8718d22e37aeb76aebb2aaaa3e993122ca9326b54209719031ac98bf6ba785b77fba97a8c1a9703c37c8afbf7f2f8e3b7aba63a41e1b6488b594736e1a2fad35c85acb5de3b357ffa8bf87df4b5142bd2b3c7a641c3fdecf6f3cfff572db90b5a1a80c23619a6da4263c34c8b2de386b7cddbfedb5d495ef18bf32455515aeb6f070c98fd6dae5ddb34e0a2b7e9e1964bab9f6d6cb8a21a4efea9085232cfbb37b1b8a82b9790233c232261405270a3c32c8bdd73df7b3d4527abdd498049e1864fbe1fd9fcaca2d9e14d258354f1e79c6f9b68c15c6eadfd796a228eac10abef8201c1e3c72f7756eed61ef9fdb8be125c30383ecf184f2d7fb78d7f53e4e01cf1d59da8fbb8e5f57196dac8fa2b8b7423d5278ecc8d14acefdeb965e1f777f2fc89d5e49bddffec73a9f75418ef1c2efebfdfd53685fac81d9d26a22d2c8a251785a90b57ffcf9feffecf4d7fb3c2cc8ef6dfa3096fe7e2ded9fa14ddbccd0a64973678b0fae20c319a9feb2f63fbb9475872cc4fee5493b375ea4b9862be809c353478ef357bfb18c905a0f33cc8a16fd2ac712897c8ddb6561365226c4b6cd679b6665988edc7be40f6e4befff5a5a55b5654e6811c2dc34b19e2c3c73647bffb493d7dfa5a4b3568aa2288a9ab5445114f56e1f1e39f286b0fb8f797d75e38d77c8c22af10a46a24b78e2c8dfe2f89ec513dacb35bfd87621cd5de42d2673d69214692bf35aed97afc2f5b611f0c091ed7bf3fa4da1d4f1bd27dfc83ad62ee57c974768e9f41445512ac81d63b83dd5fdebc8fdb4210b75b05d55e15ab4b1176dbba4d51a9cca88c78d6c238e58fff9adb750ca2fd2dcbab04bf338a5665aa4b956ab0a6b702a289e3672ad5772e8b58598dae89f50d456c276b4a8b291f5f552ff7e65e5b16ecad7c81e47ff3fe413df78a39f538d4c35ad12c309ff7fdbd23432ad7c4e297fb46ffabd291a99de3a6f7cdd6e3fe7e7fa8cfcfa9c1f563c2bc69ceb9be9cb32e249c093824c3f85f0ee3ee3f5b24a4b513b3acbb4ad353815150f0af2ded1622f297e4fd6fdb819f9e1dfe9bed16ed921dfb18cbc7b94ffc2abe9d6577338ebf69c203faab1d59752cded9bd69348484cc06382bce7a696ea776dacba5ef197cc7c8867da4fc9b62910da6cd34a90a1fed763fa2fa7f2f5a94990a1f5ffd1193fc7bcdee775888c2ce98edb5fb975ec15daabd369722e2d85a27ccea5338ad24818b4353855f78c20633b5f94f04dbea5a5957ad1d6d8778c5b57c96ec916cfa75fa413d6db29ad210bb7acc26364c829ad1d566f21ed1a5e986d9a478c5ce1ee1b6adeb7fdd0465a55a84351eb5868f3239be9109f533c22c8f1fdb8e1ae14fa885f8c18b6670d4ee5c41346c6fddd4fb1d49a56f8360f46c635cebd39e5f05aaedfb4440f56cf1799ffda359ccf5758b9df91c6ec0941def4c24d75b45cdaea9f24953608adc78b6c6ffdf2476b717f1162ec01419e0f7ace71ad3ad22af9a59e2eb29f75dad9fbdf5dc33fb7c64596f87928bd84107f7fb1a65be4ddfdac1a4bdea7e67bf6f9816c7dbdb7d2e8ebe51fd728b5e45d6fa51a635be79550dfe8818c27d43bce195ff598cf5a55357ab264bdeb8697fbdf2fe736fe90855ad422ff68e7c4dabfd73badba66919fe6ef4b3b37fff6edea4316eaf85055e594b6ef1462917794fdeba9299f1273cd45fa8a7c21debd476eb9d5f8efdb81fc308d7543bf3fe55d436b45d64fd78727adf7f6da2d0c59886d9755cd5aaabc9669d284a3d225a7a78a8ce1a6b376cb69bc3c3e1ca1ac3c58327d1dcbaaeb7d71eaf89f663dc1321e2af2bfdc4bf9ad7fb44aca23f67020d32df783586a8a3bee74f3f77a36905fdf70421939de6f3e6d9f470359dbc8778f0fd3e97dc7d38b48a59be799226faeb5ed9cca7fdf8713872cac0df064204bff78c7fc711af57ef87b3090a7d4bbd35dbd8fd73e6f3d52e408fddd927f6cbbfc3ce20be41dbdc69bc78863c5b0da28b2b4b65a68ed9e7b423d398d50643ebda4fccd4b63a7d78abcf5e9c64bd93605c24b8405b2c47b7acbf79d7853bde14cd736b7d6e0543915c8be7f2e2d7f16ee7b659c968e7792f92bd893ea895c65b475e349fda6f5cfbf933fafdbfeebebeffb77697572adfaf72de5df9663fe3df62f1a6e5dda86a26c0d4ef5af641921e511722df5c7b63f096bb4922dbcd34f1fdf8f9d6aef2fd4a58c23e7d8cbfd67c7d05e5a835349d9b2b474f61fe78cbbe25f71098aac35389504b47c25ee5def6bbfa452c74f512291e7afd6e0544c6453527956d8abeebcf32a79d47554ba64e544ae53f72729dfb63f0aff2fe5643398d6e0544b90f2f392c30a799491eb4ae3a4c1f2ff1072acb79f10c6af759c353855932b4bd9f7af32e21f63d75a862cec9a24a951965efb67a78f315ebe290c59189988f2ed1c627dfd83dd53fb5fc84291ce72fc765955d7a40833bf31c1b74ae67372e9f17ffc554cbd0c59386ba9da46df3e0a647ce99c586b2a3bc6b2f79085ddaa3c6967b3d70c45ed5cfaa6ca1a9c2a5bf963b975ff987269bfa7f196606e9ec0647ea35142619c89149807b38d2443d54b4e8e54cab7219d5b5b59a10f59e8f985552291e6d8f32bcac5a45e8d84c99f259fd15bde69b4df6a0b9fcf534afc60e5da5e7d75b432f6ccf79f78726d6fbc1f3fcfad4d6f5a849067fe7cc7b1efffa37f733f7c77fe754e6831d4f2ee0fb90e59d831199d6df57bda2925bdbe7bfa3a86a9e4b9a7c4b8ea19a3874f4bf8aa1cfbd26f657c3dc60d828c71bf5e4b0df5bcf44ed945c593ca5dfb7a7bdf9fd6c9bff5a5392a5db222c245e650732dfdbd1efbbaf9df22e3ee638791c3f7f6c65812f940bed052a8e3d5d153fea426a2254b1bf9bcf245fab1ad76df0ad62e8878205b28bbf5cfcaf72be474573a229225d38fab7eefbfbb6b857513d12247397fa4d843fd2fc69213c9224328fd979547fe2b96115626886091efe3d27a1dadef5a42de994881892c207245be7efbcef5fdb0e2ab39adc1a92e40a403d9c7d8addcb346ba7f973b64a1133ec2dc348171228bb4b565da86a248237e11b122d33b37be8f6aade9e4f412a922ff2f3dd6ffd51dafdcf811c192e3f7fdbe19a7c77d7b0b895091e5fdd2da3d39adf46278270d110ee4eb3feeb66f68e7841e7a4e6403b96f7a29a6537a4bbbaf31878806f2d6535e7cb5bc576799a274e66b702a8bc81439d247f1bbb46289f50e6dda77aab32c75e6a5c54432903dafde62e9f59696fa8f2f2faaaa8deb482facc1a99c10c1409698eeafadd47e77aabffe5e8a1444a4c83e528ef9c472eb4feb8f144551dca2a82e995beebfa59b53ed6dad720b39da07397c94f71defa33c64e1abd946fa6821c38be195bad6293da5b74e98c48456249cd08a9c9f2ce41ab7e69c57c85f9f7d7f29343bd976e5ccaab0eda2a1286cbb2c7ac5070bd963f81fbc11fbe7abe6b582115e215f5dfd9cfddf0b7bacdc5214f6b142fe12c3ce3bd75c1e92dfa4d2d77f6fe413cb0eb50a9ae053855ce9aebe5a8fbd2cc1870a394e88e9bfff576ea9fe6f0a795309adec7e6e08f987b68b8f21d9db7bbfe61fd2cb6fdc500a197649a7dc7cc3bd29f73f0ab9ea4d21bf73d61d758c0f0a394238b1c6dcc22aedf491a20ac95f725fadaf5bca8ff7f5210b2b92cf13b2fe5eff7d25a7d86adc79c842af897c956115498f20a4331f274c38a9ccbb963dd67effc65c76a9e98ab7d1979f26647f79c7557e8fe787b7c30f21d9d6cbe1d3f172096b8d900979bf6fff9c336e1ee7bf3ba4559b8685aa2bf39b8eaf31e7b272723051fe2c216b7c2b84efcd5d6badacff2b0873d344441ad1ec18a169daa6634a288aaa9490638f98ebf8acc411eff8e91d24efce23a4d256c9f9953c26216b0be7975dfab731fd587f90909f9ff8c38ea58682648b27a6b65f49a57e9b72313e8164eff9e515fa8d2fedcf6e8ad22a92168f90298cda5e3ba1e75d77bf431656989b2646c87acf29e79baffadbf79636039f2264e9fbbdbf5bdea98c74bf0f2079727b7dfd7357b92f7ff85610422264886ffc1d62fab49ffcf721e43a359e1be34867fc93428a42e323844ce77ffb5b4975dffeef1d84acedb6afc76a77c4115f8847f00142fe3f62ceb9b4deda7e3b9cc0e707f9730af1a7fcd58b2ff4d807597f3c217ffe3e6cf1955c42db838ce57bfadd4aabb41e3cc1870759db6ee77bf67b6fe90eea9befa383fcacf7daee8af7f5d55bfa47a65b52ea7bb59ff76e21a5288ac21584d08f7cf5b376eec975c5f7ff3e72a7def3bdf5f737ea17f9c8b0dbdb39d41acffbf4bb2492a6281249cb3df2bc74faf737b7d1cb2b6b0eb2a59deef7a69d54ca7b270e32adfdc987b1ecdcc74f394555308dcf0d32848fd70dad8f763eaa3545651ecb11cd541a2b1b645a77ac3a5aff42166e559434894f0d329edffa287b9cfadbed29c9d2087cf4c8db4aeaa7b7dbef2aaf8c622b78e54383dcfff66fbf883b7df0d6c7257b59df931c6fdfa1b538ce205ba9ad8cb53f89e9ec7dfe2c098afa99958f0cf2e3124f5dafe5516ffa7e0cf2df575bace3bdfb5f4d7f1ed9572a6decdd4e7f9ffe1e8fdcebc6f15e6e3bec7f6b0a838c239edb7a8a31e5b1da692b68efc878f70f3fbcd86b5c6bed76644aa7de345ac875bcfa768ad25ae79e5ee0f382ec23eef7cdcdfdc4524bea821c5f7cbcca8735e51e5b6a31f06941d6b0ef4d5f951bf37bdfa7288aaa3eb3537c58902ba7947b08afd712d65f298aa27cb6826cfd7dd36b3bb57ffb4158c1ab814f1dd9426c357cb753bcf5c69fd2e8c8b0da481f8f1cc2efbf9e73e4383986efcd8a399c704b8a7a5c7ce4c80fffe8279e303e2d31bd14455110ca107ce2c814be7df78e75cecee7ef210b45d5665d168616495724f98123c369b1bfbad6fe36f491be91ffb397eaf776f7fe71ac828c35ef7ec6fa26bd1e464e6168c38c9050ab6e642dbdd453be8ef5f7f5624cfab491b1949152ad7bc7f4ee5b2b6423d367379c9bcbfeaea490ae9131d675c2ab797ca16dd324fd5123c73fa5ad70570b299e1d53378decdff35673fd6fbf3b628a46be8f3fcf79979dd23d5f3d2357e9affc37ce88dfbe1cda5822d2946cd3700ab297baef872dad1e3e4e53e3af0aa220c77aa18696ef1df9efda9a91ff7cb3624bb9e514d77743164a78ef924f1999cfcaf18dfb56ca2fd4767f4e90a3bfb34768efc3dd6efe42168e328cc9929b6d24b97d4c90efebdcf6adaffe14530b3f25c8bb6e5aa996113eeee1ecf4c2444a286a67e31f12e48a2da635beeb35d5b4f6246094c01c41d2238aa2a80f1919beb83ffd54e379ad7c91a2e0073e23c81afb8823f5b553f97eef1dbbaacc93443e54551b76c948a91755c9fca8d2b2cf96ccf5a49fca8af98eb452ea648c0cf9abb3577ea1c796d32a467e53de4aa7defbedadaf7622828cedf49e4a3e63a5da724e3f61e439fdc67d7e8e3f96f1fe0f18f9fb8bdfde73736befbdfbf345a6937b3ebf94d86eebe7fc842073cb7987d0d63b6594b8a47991a186564a4a677f74cf2a43167a08653e20c8177b2b31965063a3ca8ad56da51189493f5d64acbddfda6f49eddd8fee0f17193fa9b7adda773feb9fdd6713e6a6498974d1c4073f5b64ff2c8c93f74bf9fe5ee312692b45a9c1a9aecf07328dd87fcb77d4556abd3f4555f06ac9f3c2bd2fbd9bdef77fc55e7c3c90abbcd7ee17e1dff04b7fa5cd922dc5ff696b27b7b163fe3e5ae408ed86d4f7299fc696ff5a8353e17cb2c8dffb78fdfbdff32eabadb682507cb0c8d772f8f9ad7276ef6ba4578bcf15194768df85dc4f4ef9fff15610cba703595e3de7c3167b28ed8fbfd2880445d90a56348a8f15193fbfffe35fcb3d2995b3963e55e43879d7cf5fce37c74f5314852b7823083e58b2c79cc66df58e55fbff3a45d90a6a3a1f2a32841e4f5d35c7b05f78a51218253046c028819981b1790253773e1cc8d5c31b6184cfc3f928fd568acf06329e53f327a7b45dc6be274551b882b686f1d140a658ea5fad8f6f724b5fa7288aaa3192e03345def751d8adbc33caa8e12b51d127033962692df4bada6ee3ddf283814cffa71cebdf7dbdef429ca3454ca8073e52c85eabbf12fbb7e395722b48bbe43dbd8c5262c81fc7da46ba854c2bf575da57e1f7184fa885fc7ffcd15ff8addeb3e27ff3e046b2320e653c59c8515e5d6fc75df3fbe79c58c895c76bbfbe98bff9defc210b73fcbe37c229d86f2cdbb45aaf907fb5dcc6cf63d5f2575b2b8ba42bbf692b5646aaaa1a9c8af2582163cdab7f50f7fee27ef18a3e958764c83ddd33c2db7fdc97c690853998485621537fe7c69bda1fedb3db872cec5eb4f5e52df62427077b42c26a282a0713512163fa23bdff55fff7a491862cac34425869d421ad461dd2660d4ef53c53c85c73093befb44ac8f57b157e5a45731e9553a8b43108677916c428850c01001830890200c312003038281e8fc72302b158532200801f148002448aa4407d683015c703b22807611c0641100331c418608831862006594d7102da987fd0d76b3be44e4f3b114c21ab393860b581ba261c16ab75191e56292430cde70e8327a2c8dd607ae7e0ae1d2618ce11c45ec129042ac9146004bac4dcd088fa1f6122c9033aefe179a2d41e1d872ef9f27f8ec388040dfd7d8b264341e83a41881c79ce764b6a554c2994a98bb5173b9377dcacf6467684d4d785c457393352b607863987141c9fa9a23b3618c7f2ec2d2c1926cf09849dc213390816c8e4074ac14ad2b8ed6a6c4c8215950808c3504d48ccda0847d86e667efb053e78e701a13772617c79df43e9537a5e1100d368a0053bbfc74a999c6221e7c41a25f7d66527509897773e790e6482e9c16e6129b453af7095b397f4f4bbf279843120876c04ae58c3ca4a8dd87246fc8a6207ca7529a28205b0ca8912274c21435413f4bd3136e6aa649ccc14bd5356b2689acec9c07dc48b23a5f9a818b4e1a3627b286c013e74b2ba97f09053638c531bdb032b5b27ac9b35359d8c60e49d9e244a823ff9b677c894db4a3a283cbe83207aa6bf95903a1be21e2d20c914bc4255a12faa21404498058b274d42e4e59c473a2edf1ead94d8590cb7523918fecfdbd708c7b8968db9f58b6fd42757cada68e671416302fd335b4b3c7c3a58e12ef45cb52bd248c321f79c64cdf9d0f5c92a38fe15b2973afe535b933d38bbf5be8429754ccc1aed8b7a23419895c002475bac4cbbc92cd934115e5922182cc7baba70ec93648b5f2218eec095bafaa1a699b486a8ac9f45dd5261e13b013443ee44a67d74e87c6f952b08736dcada3556a377002f45d04dee4910115ac9b61979ebf9fe1246c5bf84ca104dd80167b114a8386781890aea4f4ca40fb274be1a3d0b71038c1aa845bd448d611b02c4910209b6acbf6643f46b7c2719359955412770ac85a2ba4a178e39cc700ae0b235206b286544491a5a091244252861ca59234c90d841d8e3606d799198176c42eaca77ae501058c9e14230d7ada8fe588fe0bef6efbad3108d44fe1d482159bd3329ca530afc3731d8e18467a76ed860a75b64158a1c91da7e7ed62e33dc2f84a429800c475e786abca6000e3f133590b8ddff579592c66bef38bba25f282d593bf19aabcf1076ee2557256697e839b5c0934b5af42a6a04977e9024d76db353044f476cfef9523315ea9ccc48d3662a252f5010a58637e98c169690832863828acfd41de364e1d159dd5142943f5c86342dd8584adbb4fa87870d945d816ac07b066834166b11b80dd06ea606cc48b285cb5de8134d80108dacbe57c843d74ecfdb9719595e2be2adbf8bcdc1fbd10b3db450ff3a1947f207106c2216b715f124677208087c17ec185ace7331f9a9804aa5f0309695ba931c8a297413597b80810b1f87fdd6ba74e737e2aa5ca5531fa841a06ef9ef977bc2230240b36e221c959a2deff6817e62034d4c448a88b5ae64044a98fe49bb81b97de368d79ca0741204b7993476581f031ab59f78fd32676ddec22a3b591dc7f340760ca7985f28d092682506c2537a8259af82e4288717d4e36d87a9a188f2615abe076399ac5d8919fa050db0d361c2b402c48cd971f68b4c1ae060be1af4d0340b2e086b413a7cf64e292b0863fc18c46b89b0068e9266f6031449816e482fd0af7acb2e0022cc033ecc823c899988af1f1a425be52b268db7481d1574837cbb843485602a6cb535c3091a69a980ffb6dc933c9c726cc169711e90d01ac456a82acf70f715c845c233150255c78afa0c5463ca38cd7a9a98ec59fc5152205fef83b0c269001444acda6e7f92bb420a2911fcd037cf27b198e6aa70dff981ba3cadcff55f34eb578013db340b18d7dc7d945e4a525cb9001b50a738bbc8e049def8185678ce46cc021c2662e2625cb933658a70e6c0f946252deec9356fda6ea3f54b3e6a945006480e09af4443e45c5125cc17f0fab378646c6b25c57fd168da9580fbd0dcb8b69c54a00a2c11889c97fc0ed7883d58f9743702a32883b295a15baba68ebbbf9cbc7d3342ea7a93d59db093ce58800f65a56b1e7829857c895e8656b5b38e267630e5e852953b9f5ce8a059c63c7c5b8c43d6c61a1b41eb66c6fac26e7cef9d092cad8f73f6580d562274b4b11dc46d1121f222ba5244cc5798379d10e71fef6da70e8c48dda66462e9231a9093ce05521803701897968b4bdd869812a199face00ea220a8da26de477642e676adcd1d12e6413df8b29038038941a2eb37a0abba6e9f2d5116f516ea6719b032904cd89a33f02aa952e45e532f558935ec47c16f5c671826f7b8161852f27656d954ccce57c20066ad11e6240736755e7b54088ae2da514e48037b9b6a15147692399cdf0341cde145f0776e663a2247ae7fdfddf86d0c58d715cfd2762b1ee98552a684430d9543614483bfee6a8cd92baa15b3a4b5273a0f1b48627044436ee8c15e7e8a3785047f048020fbd2fee3d2f1bf0f4db53e1799b271db784b429e091e97909868582c9633d7230608a44c983e854ba51fc25a7d2e0ce140c314da5e0dceadc1d7ec0ef8ccf8a18d3f07d2c34347a6e502a20ef0164292ce8461e73e393952966402d2dc3575999a4a67e73305ce2a140b3d7aeaae7cb25995d443696259fac902179ffcc6bdbd96d5d8598e31df001912e2a9d3dd1ed1830e3218c8717f2212d784c4631521b5058b2ac77f685be783ee4d7db7019ceef87b1f8593a57f04076040437101a3ce416500f6c366f2eca70fb20abec3add31eb3535371a15abd881313b3fb33c0ab360d49fb32b1586e487758c123bf49b68d114a4b659a7a26885ec0b55b6022ba9b6b5b45b512c1cba16f9bf0061fbda153ccbc7abe9d8a1225c7ca33a9a099509085b00603abae0740baa18f45e386c3de10d97e01c94b70fd315b099a7b5c10755997a910645134b381d5cbcaee5cc010066a7422cf3a46bc2b193a8e0749d0d6c4d50d391bb44e2824a20dc52886e0ab90ceed4a81398fa778ffe5078c3ceab4c50509886a52d01b996537703490ddc5b7df3fe2a32120cc9a6b72821e3cf4d01c9dea5dfa890860057b4a220f87a603e41ddfbb86db08c275c3ae2262060d09567bcf0a53541ef179052d15049cd8ef04f354b154c42c8d68480a720093369f7024befe53dfc4d4b3c287b95cc49a88a1b7ffad6ff6a84bcc5da90fc46f5ed48cebf7c36bebdaee90b76637bbe6c613ede72364f43505d03b34bd7a6d88f1cf2d1c65256558b0c1fafd1d44a7117dd2e92c7b35813bd071356ae65395baca2b4267e7d717b78cbaaa0b85f46d325bc7b5ad0c6e86114d99d5b7c479778e58e6c48643c2a25133fbc655eb5cda1c0bc7a4e241c6c1ae0c49ec2d6cfb465ed0c00002e8b1941b3da4712f30e62ace57964597fc73b20cf01ceab676643b91d2258e405a9cf545579eaed8511113a3078798449959c918b1a60374cfd26de2b9729860651be7644cb15d3eef32f260facbc276d6e062e7006e1e3082ef543bc39731dbb1c6670b15b60832866f10b39c982690b675a822ac81c63f45da8078d0138da1963eea7ab04523ee69a805aaa2621c929a8ce890341adae18b0008bd3a760f8f63efddd4e373f15c749614ac9e8be3fa0a63bf7a417de53a99f98bf48f99dfbfd082cb6668b0799051e8f3687a5bbb8836c73a7a9deac8aa33c986fa19587da51da5891b272d3c573cfd620cfcd78b4f9c165f171169ced1111e560e79b7d0cfc72bf63d21b5a54ead1eac3cab95d3aec4dcd095bb4c493d37e0011071c92c154b34092d880cc68edaef8606a14091270e0ab95665370472b9c6289a56faa62228a44de11816eb6d30e2642aa2d1c348ae01cb481d3c87f7c49e7e532373216682ab487b00a9a116f084b5cb8f0274e0aecf80dc70c97d4220a2b06eb0c995500fea2dabac5a6f11d119ac3ff232f0195d10877574527420422216f0b480b4755cbeaabbd2f16c82d5fc94d79f61313c0d292b5bb1e4db8ae4db5470cd23e46b213c3d51e4150f8b1d054c06979401260e0ec67e3201f62ffcd77d627b8fbc437a35a3c8258f5413b3163cab966243236f4c545022938e97ca5d89f0deef680201adc0cb23f9d78c03e5ee62bd2ae98ed56cf97e591d1948cb71ab23df7e7c52e542c3b89b208c03088b0d4df400e4c716aa46c8d740c9a3a851e5b9b1c3ca5842beffcad593e30747665cbdefa696a1e87d53c12b4af02559ab178d834340a68dd0306b9b764077edf412a25f8930f456609de96d1ff22620bd9fb7b9624487129696d494a0c53b27976238f12695da33349bbcf442ac2496d5d5cfc09a396ad501c5ccafe80e24219da3f7571943ab560dae602dec10f8a6e13e97a6bc7791eae17009d76d6581645a2e769db2a2498cf96be5f841c3165f92d8990bc64476439e368000f358155ba2fadb750a8dc99d0c958273c68b0712d21660582ee33397ca13b84fa073344e8b1805e81f40040224b08009808b98af4a89ee1b8609c0e63670586ff04bf0e40e4af39cdd2ee257447c6cf73827b5da3a38e5cbe59264d43364867bcb0e4855302d44694734267a98737ed9a844ec6ec22763431390102e9dc92e0854bd53c7bce245590c7835d777f268e2b66922484246dd0afa4e05c8bce70e2976060b740dff085ef51e011a8268393d31ebceffda88237e6689e2316eeb74a2341a2202f0b677ace0e76e0d9c7bc075a175d92ee5d402c415a940f9c0934697931ad00213c8bc4e92445f486594f6a164e8a971cac0410d980fb3c2d043208708371fca3162a8a8c1cfcd7c35743fe12bab3d51c4a57741acbcdab47ac0eb1cf50401ed79fc02baba559b30ef136140128176067a5bfb9a9e90f429a7c41474c9283889e11d5f788c050d229def85f55c5c451f332b8f8105bb0d797b5c7a2987972fa17b5e3ba70112734e79ebcbde84e9239244a9ec3189d60e755c4bf9c456d53e4f42eb3cd6906f6a0b446ea38fbf8277b21c1ac935785a18d313c1c00936046a0fc1778157e5b31f1d1618e2ab144727756ec1383553e6b133009d4089ff69884efb5c4ac6b24cbbbe2121426dc5b1fdd84856789669f9f4e39558e24038bb91f69bdeb2f2056eba2ab52045a38864d13bf78c20b9ee10dc2c96fb2f00281066c76702db9a2b295a15682eaa173306b457db1066826c49121dccb328e1a412cb9bfd7fa5882afb9ad3816f6c27ac58dc95784e0b2e8eebd4b1964023f647c1e8c4999900469f3961c1b1faddae7ed47fcb723bfc221083aee2e9488ab515b808b930e44491002f675ea49ad99ffcddd34949db4387925331b7fa028aa67d956ba7a5e20dfa45e4f7048949dc45a0f2b937aac867b612bce4ee11888cde957f247a0b1bbcf2db934c0dca85d38a96140b803d29a11371d1cf0d16faff6a32a7aa90641803ca5181e1b273c095542ab69746fac7037c9f6b65044483baafec3d288df5f2c11abf61431432ca4ae24f17615898373480947a3121f15f11b4d04be3773123d074adce5252ccf53f585bc790b0c88646f28bf019cb32ef8b5ad85ca426238db6ea6ce73bff16cca5251f801ff662eba10aae455ad4240b0cdc9c4663813ed6bcd71a822578d0368c2bcb5ce88b4d9e1b2d2114bf65e537ba4d4754eb40606c13d969c9cc6a9c7e713f6fc92f2e00920a46042ed8f2fa07584058b1e57e25f1111db030da632f425c50881b4251f56622e9607714d0c6461f0f52c811d28ae758aefd84d8fe6956fd23b175a32b3b3dfcf4528cce422a8ecf75f86053d4e9f0eb5f0dfb2aa25e04be581037bcdb31b2a68d098b2c64328af4c6a8c44e21d62401fad718be5e25af89c80f33a184f932564614456ae6297be3fa209c8e89e405a0b9ca3852b3f7ae0a851cf7d263693668b5eba39ae63e154a02a786aebc491841e5eb4a65e2d7efaa77894088cccdb79aca7e88b9c02dc6195c9a1edd7034e6ee4c985d390708cb7aeca4b9024f0910a4350b71f8a38251cddb971f08e501d5d3b7db5c39bc39585979d2e59f17e00dc6547d9b8e6fdadbb296f94e62b543b38484836c0453bf86c5d3a4f251f19654b29795012b65bb21ebd84a2ffecd07742bfb7c605270568607d575e87d4ec6ec59b0535529274235a8a79a7fef7e971c8690868e6035bb9d6ccc66a4e9fc26771f673ab679bd4c637c5085ad9f609f255185b1b59337e7674672374b51b80d4f2bbec82c4feb34c46f8ff88b2566a55a7d16f5d18a6d1197cf3205441245c97ea4caae97fb2570ae5e6d36d9a326f00c61136000b69e0c629b94475e74a05c6d390067df6471ccc0ad8e75e713a8ef25a57287dc7a125f9ba84ffd7f12e3d602dea2984a9c36c47d6e480be595afa204b3cd53e591122bf1b102f6e2c420c618b1012c42ee34cec2284f274450aa48cc980be2268f011df440881a88c104048c4dce93e23c496cf24d408111040434f339086271dbd1162eaadd1bc11db718498bd20cb1ad338085302c922d241e4db9538ed08f1ba2d63e4116206b2d9dd23c4607b72e44788e6448bc6519e4e8ea410e41d18010b09d10a888460903a42f02f4308f2e557a39110acd84f8d8410e907144d928450684a421474b030fc774988c20d3a93109e7dc651172935498d24489371bc8167e6fb69a0e08853d4d83423a134f520712143901d26f8c19ef16dfcd29421ef94b1823665bc13d628694281beb660f39d094945221b349e1dc828223dcc1691b18d84c327f8ff2c6b2a39cc427ac3001b71ddb7d9a6e97b08dd6d1da80920ff51cfabcaafcd18dcccf0e78ecd284e46e17dc629284608dfd5f4cf2ede99f0f4087cec778c96ca4c2e1c7be98a092bf136afcef7d9cf26ff6cf1aba36dc52af785031553306a19b2201006629e737290e3d9d12c8088ab975fdcb64f19feae8e1bcb305c942c5cf1f2dc1e1549b4dc9e93947e0e1cd711dedf7e99494ca7c7b1b27968976620b6ba8139f113f9881daa7b55635207cbb9f82a353366283f37eaeb0fe6bd85b798bc6ba681aa8ef7136a26f7d46b8ae7b46e1dc583e1f5af05c6cd696ee21c6fa93636446f4c74e9ca287303ad41f0dd1817cc00736eb338ba59e4d44713681ae6fcb95dcc8853f9f175f3a581a0cec8cb193abf7190e91112d5cb83e0fe58b9f73edefdbc6e27fba6f9a8ca20640a4b5b16c328b783c637f59948fa97371d19e509aeb6b28c51c6ccea20cbf0ce07cb7d58d262db9fe2511523867b323ffc273fd70efd69e8a1ba1325fa57d56e62eec355bc15252564a0162f46fbbc66cbae8d2b3b849349fc31f801b37f9c5b1daa2eb1c49e0f60bac0369d03f8b8600ec8c1c99373249113a1ae78d3157fda58cb617e4d7564b0ebb979bcb0d283199c1b3973285659d41d7accfaea7704348ceb4e1f32370e5c2ad003cf776d1d1e25591174dfa488f754e4cf0618f0810b2799f732fc748c2f28738926e5c7391a3b6ed27b1e03d32c28a9bd9ca0e293af650d44f7394a72809eb1b2f17ab26534a0b647f92bfaf291c3fa29869f817bf5edc091435b30672196006e49f4ee6d2c871439c4ce8622ddf776d2f061957d5ab1cde26b41ace2aa03e71ea8290884f10b4bbaabd92a0f41886883476a99d4347e106ff88040dcf38e5b90f14a08c132c2b72d4c4c527c41eba2ae12c1f9bb673ed1ed44d4216d39ffe768ab85cba0e914a2b6cc2342f06263c50482d79519b6a3a00200bde9be71b3bef3ed94901ac104d6945d1aaef00b599dc4cfa3e2a40de2ec8dd597119b0b4cf5591915f32de65c63114b01e792847dab40ee8ac005dd89fc17f0ac12fe787c7607b46cc6293f9172c2b7c35c67ee209b95250a8ece248cc60d928ab28136c4e94d54c15b0894d5e89f41ce5b5162967a1e5511dfdbff4b623b6c9e47850ec1ee4053e6d73c90208aa480be198238ca12af137071abbe420cacc25872a68626f0593f024dab0a16b434d1d66bdf64f727587c48f2e2c2640d2f46751cdb1aa1cfb6e94f4051036debb5bcfcceaf8d948434a563a1095f7e57a62018f387bf1fcca99b46b44cd6d70fab1081281e2b8d226929f6fa76c19244a14aa9aac6f1cc1f41c91b4332f1c1617260134d00511907782482bc9f8e71e2ffd637a33264296c9850cc3eb0550c45edfaaf7e97244aea52a7f312fd2626e987a635088206d3a0ca4286d191a37d54f86ca57562676b38ca12e41c329c27064e68222588b32e40141dbbb6c05a59ced260833aadbac24e345003547f389899506477973b045eaf34c449b09dab863c70e79a3438ff9386bbf26adc060d8d459e2aa4accfa3f2379516b0898268a4493d0a98557a977b769871791f169e1dac96dcc946abc91dd622d220cf04bd2e89d545d836724ee08cf907fb8bf977879c41905368085a1b635636f87253d79f0c1e5692200a039e846fc617a3537ac361d87bc5f39a7dc16a57ee7d32048d9ea82184aaef6b4bd93ed0204995cc354c2a749d437e7df98419af85639e8e2f6cd171d94ebc696056e4b8cd369fb122f8ab8030da7b3f0351ff4b9ea991e89adccb463153853850f5820ebd15a971c8c07ec4d9704af84ddce0b6d4d53b610584e6fa79a13dd8724096bb1cb5d3d303311e7fdc3998bb4191e3c05ea284bd03f5ce89e3e78be0d92ad5819e64ca206817f42957ee3efada3bf04eb39a792c18d8d83b9ce6c0121ec76170a878c57a53b7dec1991a51e946b31d088ed80dbc98d94ce5f9ef9863c0144d06e2e0d894b99b2220a30de62b84a40978ca80432a01b6b16bcc0978665bd6f79ad1d5b5a0eba9d29fab6df60523a254727f1d1e2f3f4222d277e0b73a802f803fc0077c87d8c8f20efa15da3b90025d3d7f213a082324f15722437645efc010bc31a878ba896248547f52b91613707d813474da46090d9dee55e4d69bfc9926247a6654c0f8a74cd1137b1bbc2b408b7aeac951a133ce549825970d7fcc18e5e788c177ca786002e301672bfd5ee27b446ab7225b55cb6bad7c833a6720d648f1c079227365100089ee5977684906f587df028887b8ac58df5f7e7ed6942cfe313896dac692ad6f87fdb7c140f0d13265977ef09dc0c251c243111eeb370d6b755e79b52cfb9d75a66df4f1a0936d23185b68ef45d4b0d3c8ab2280ffaf2f3485cb1bd1eb9df22f89ee697801c2434708d87e6f155c18aa11f2bf03fcadb42a4fff6ff5bbcdb1d1613a6e0c2daeafd55ce59898d9b961adf50608df61548a1773893d9983872d5c78d0172b553f36cdc69b311eb4d6720ffdb8c1b687702e1f8cc1f405431edcd2b8420b2a9698408039edf12d434e79e85a5f73f6fed4c2ad7967176a16d757a77c428e1e0f3a0dc1f22877ba3c19c8817a6d081cfb169a60e483cba9410b3a3c48415e32f221f99f3d7d72177a7c80bf334387a9c707c96cfd606e9e3a07a15d471d30743706706aa76a79bbc9d0472098676ce0a5f7c3d7f5ce85d8610ff84d8631b7506b577bb3752b5f2a40f23f27218b0983936ab2081d6a1d26018b4f785d1d08aa35bfd90fe5dc597826e74e38914ad69845a822ba7d0e882db4808031429c9ae94beb706eca81ba2a2325689737b41d9f4abb7836fea8a76c243974d10f48eca74da54d68b155fc94e815483804d6a408bf1b0e0d4f834f6eba414b986480adc8c042e28130d1844e022bb3cd3bf02393c9a021ce5a21d78dd8ec5dfce36bfbe2e2dfeae2982117f280df3d533c7ee4e062667ca0fdce67b4a3f1c0a37bea46b1830abe0eacc6e82c34d81ec19c6d788905b6c5b8b669d10658886bd0c61363e58a51962f20ee38bbee39386dd6f0ea5e7a98e75cfc03f45701308c210f26bd104e15c603ac20bb104ca4b61e3d1bebce083ad8eedab65fb87cb042f6aff3489b070676f9029d4b037453884a67eeec00132f0946e94b19585037928a9cec19a9bf793e8f02e44a3c793657fdcb8de1fe1397e15b7403eec7dc4b66e2bc9d9fc0b0c38700adb062e2f2d20b70a9552cefe43b1e2b1915a0fcd54c1e894200027e5604a0b0539022c7c0fc6177d3cc6a21e77e872ca50ef2d259116dfcea21c5af58458a9daeaea921d3f8469de513cb60e89e1500bd284b0fc7fdae7e1ce975ea54500a4c017bae4f9eef0d96a425020a026bfafad415e263c7d49e8bcd8f24f6831911a16be6c76366a81801e2984bf99259c242bb1de54a4dff1e1c8b0510b63419c111127a4923aca7ae5c2a982a0d6092049b5c7be43c0cdb3d5e8b01b9910c289d64a5bfc4f3964d824c7c322c1e7cc6d4bcd57721bd258ffb05a129b8ffd140c7949be4ab7f8d790fef30e31322cece51e6b3965f15f10f3416f7178a4ff8b74f93a294334067f2ec3a472430e079199e8a86711af11d28abd7d0e324bb739ac11b0d23b1b177a6bddfe1da3a2cba0412994d50e9198096540fa85c0111a9ec30e9d00c223614b1a68440cc62e6c06eb15e6a0f1811d10d00bc539a07116d9f8848d759afbe3224cd0229d20eabb143ad90faf9517233353877d50f8d8007b7d11a8563dbcdd83897490327f882b31d79be5d911cfaff65363ea785de3964e7d5025b277720cf12c812c36f259cbc40e6f5a3d8f9470083eb499a3d00f20dff649dca7f45e8e5ef05b019a1b904aabba93a59610ac65de306896d23bffce6e375ae22dadc7d128799f052c6d5a06b2cbeb0164b01f097c8a0fe80b32057ba265216c1c14ae77fafd4c92704182045315700efc62613887e486853cc1d76e84d40308c71c7889dc77214382a6358c95966e65ed888b37741f46aa3d1dbf4007aa41a1b727a02ee124b9db1ae674e1f3f2bf875dca3d2777c27d8b65fedac496147d0fda6a906927f2c2bac964846fe26672590ee2808609039d8ed59980c9b43e955486c7e99026807ea20357a60b5449d156d564248aceb289abc2d91bf98e2c9d986d656f002ab9a1334be6bae73b3476a60c6cc81c9e0e20ff63cda0dbf9adf049e8868eebd5974e7cc4d9968b55d29de1e5a8864f310aae4a9b7090824a6330a61135685b9ccf6a0fd535188b72c0729ccf5f640fca08158ec1e1b14f3fa9b64715a02e8c923c36a05c9ce198a7b969b8f97c977bc03f239b72a3436342aded8f3be09187e115744cb9285d7293d37cfa6baa0caad30d2d6ea9571b3734f6c9f782750de59b30137017afd0e8b2b3d335180f08c3224631484cf467b68ea2dcce7bc0b9f4da2cdc8bf7a29c7844c191e25f6660382291a0dcd698ce5a01a3137d4461b334fc6d761146b85f4265bd68186bf75206d21f1cddff3e3dd1989aa464fe09f58872ffc54d36c6e06d2b13b3b3ea317952522621939a8c89c0e7cfac66958de051f0576828875b7beab0fc2d181c7f520a563d76fce7ee1a204f997cda724c22c42905eac5d3fddd0d2c5e607ad3c0f5c310ce65c2000e5b089e04a3b889c90a37053c1dad2bcc71d96a5e7beca3b878860c03e8401798fa1029dcb4b9454535a3bd3dda0fe74140ecde8ef5156e21a4b0c19c069ceb10956da03358405391277fdae29e5849e0fc3083bce8bbd1a676cc14574084d7173a69b7d7872070d545995d861e44cd6d537dad6b8b7893198e9c94eb9d19b503e621d3dba09c916b60ed19312b1209da7ea9577300a86098c8d3bcdae457a91e34965896fe0bbb0630a821f344e87103499d887601410da604007141937a32f13e0f162e31f9289017ee5f1b039c135fb0032119f8d21c8283b623930f15a957a098675c24c603433e29cab1902b1a28df4ba176f9c66591fa2892f17a143557486a8d6fce0ea47656ad83225e5b9b979d814fa44f4860dc1187880e9324a77b65cc7e77e1895493e89f74281b6d89f40a08785bacc6d5f3613bb5965b9c52ea9786984434be43383fcdf331c1d31710ea99a527098993d19498714a2cb22c345488a7825606340a8fc21059723f3d19eb5493c0c4f191db7bef6a5b5a93b4f4f9c1f2dbbe3db997f6c6e71a41f70e8aa49f4b39ac4d50a17a14f20f5f7907f0e05333d7e3f12b6a367c3584f69123b352ef8bc250f5826e67112ef49285c8d071673bf15ddb4c6bbf7c9ff3dba6b550cd469c1a19cd00d449ba6af830d7ae3d6fe6810f47b60034fbb81e9f90648d185724a0cf4b807e2ce008f6542c063b1d3859cbfc5caf33fd54e29c7e57131893a8576126e31b566714cc2755caafb54a2fc41f18cb5e7fcabb92ce4ff957e046912ecfdeae02bbf967f080b6b99c60a7a368322000c24dc4d5de152ed4ae3660f0a9bc60b2f4c50272e0e4d69effacea19152b048d82dcbf81bf3c08109c5701c7e09131a9e715a72d0b2f385bd96cc920391f86b825ac300f2d396727840058b260b2b9b36b7b84b1ac77e75480ec2259c41b6a27d6d63c9c12cb83ead9c8db1294ee950e005c80accdf8cebf01edd2872cc1ce8576fd2f7cb57f8481c3f1dc52def1015cc262ca363715281dd4b1433f1e08b6182c6a2447f0544050591b871601fedbdc13f648e143d718caddefb4dbe10dacdeaba8cd8e2b98cf20ac7527d02b934430306f887a86368436a1fba71913d994c25c8a13063fe697488a54ccb5a0f67db0e63771b20f2da4cde6cbbdff830c5748439d04a07a6d9ab047ba5808487f1b4f8227bd7cc0225900ea5edfddba598d382d35950ad0680d136133c039d795f364a5ce7a92430bcd22df3ddb0bdaaddf26f025a293b57f2ec7603869588a3e02b13150c0c5cd6421a4441e153a21651a0d834e3fa3d47270326456a8d47cefe5bada751a2699153178047acb4c2236032a12fecc30915ea51d3b650f450e0685c036f180386c1d3e293ccea1f0443cba29b72a6a4b8a0242cada434576c1b98a00ea83b711c17878224199cf2d6a9d02f29596db90afc302a1ac0ad0d848aa88a0f6e2501786153449690089bcc5b983580c3aeee1cc8bd7e83ef8a07d9bfe1fe5aff06925f9c33662295d3973334ab5af34d0380e5685d0075a1f5955a3029f431c9b2f80caf4b84ad4a82423c305d25194838664b8af034731b03049be832296761053bc190280cd29c435fba818343e60cd205ee08410f8ef01b126c10e060e3768f06ad6a75e0f00082438e33cfb14e702719b4b39d1e5807973270485f12ab602d1d80bc81dcb208d4372dc3bc29f21ba59cdf8ffe8b634f9ca36801951c3864a1041c189710ce0b2903ef41a5759384a8fc0d8ad1bd21fb8d182d2942eedb0d7cf2a53587f1722cd84134c081d84c86c04eafee22343ffe9ae9cf4857dc12adcc93cfead0278fb6506a300e5386d3d9608d1e461c84494204afb147b09ef58a6234a944d06c372c991b4a669d04b369d31e8966fa90cecc8192589e814d7f66155d32052a08f781149e26100de88176743ea0fa7e0b4759b8a6a22d84557b5fe42ba576f20fe4da7a41720472e05a0314ec51a7487f67ffb51ecd1a5e15f3763b5609f7db9dc5f7339d09367db3fa9567334954c3e82d22283bb5b3906fa047ae4e3529e260e960e55072e84601642136d53d19e4cb90db6a45522ada0cfa8648b3285d7a8638f2fbbc3b9b0f48509f351498349d5126c0f711b0958177a85eaf83a1ef29aaceb1d6612c1faa9da6e543f19bf63e0c6497c69f5528e271f7781f294cd1fec747259bf1d0325a1a949c0cebee3366a133ceb5e68bd3eec2df6e0e67d35fc9a21887d8d209c1252410058e1d87da042f4cd23bc3297402ab5e1cd441ae22b7b0dbbefd990f66ee12a125c27122b49b20f95e4591384c005dc81424ced268ce0c917fc5f9abebdc3a72407510e6146bc8bf9bb0a04eb5ec34f8e0dea20c08c04378a89d603c3413d02d139d4bc7ba6dc3d009ee52eeb31e50276b086adbe1418d5a67c21d35532212e86aa6c121d2f380b1636d088d1ba633d5028b10022ab7637c238a481d5a724d744d4251b9310d188940e8903a6a0f47a2cc6d648a14712036cb36c95aa815ce096f7596c2d25f8bf6aea04b8078c154658ea0ffc1fab0493b4acf0acb119aa23104387919188b80f20dc96c6c6ae330481b703e81c726056c045d4a8f9126ebe899cc13b4319c7643ca0b48b443812c23459e7c506b6dab3e6360a9da312241d84c521bda04a88a2701b1097f0799e55eecf1092bb94c6ff6ebb998bcd6b7c0a209a30a00b1807a3f67c68bbdf93668ce039df33e3c9925caded9509ef004d3fd0f202b362d3408cbdf032644c64874b3adf45a4be5522cbc0203103e3381daa02092a47c0dd0c3b2d797a9a7cf13c2d93940779a49f7966c76d49a6ce9cb0567da92834dabe02419f0d576efaefc6302e2e6e82dbd7c4c9722cf2b0482d8a2ec0ab169bfe53e838df0225637cd8ec7cea377f2054fdeeda8960a64b7aa9761938546d34398161b186f12d971dc9a59c36596c4ef9e0b9fbc611d7b7582dd53c13f0352100fe5b7d68e54832f0ed1ad4d620e0a3f13b47c501db2155458338d6ce71942347705095fc5977082b1d7aea511ca3b6e435105193c08b2d2e1551f55c58f0fbc6968c14524464f2bdeb2df59003698f007e7ca7e7e24cdb343f105898146d19d1f340f291fabdd37147a12f83d2d6421d3354f045ba6d5652970916eea600f4d7294d5598b18d7aa62f80487ee7a8cf0b7e70331a8e64f909b7d0606a60bb11ca748c61ced15327a5d51aeef0d19c39f7861c500bb10ed3ecba24feefda42e5a437f47305d068cf974317fb06c89392eb39d623a581e97e67b6d23907b3fa0c6d7c82a10957c0ec97538961d065704eba29a26979333551b6b757ad752d17f81964ec947a8f0f449cc924fe2bbcda764e6597526ef3bb4c546bc28d1a44be460ac794fd8c7fd0cf128adf93e12fb06cdf21c6922ef41678db68271e57188099b8e035844019c039b31900fabc8e5209f760d6b0e3eece09835e871d0a6733331d9a1066e589955091872c8c2465ee565777d5791c6c1ebd8c28a8c470edaeca447908114074cd9e0c261cf140e33635edb10aabc578ee94c8627875842215c0dd4e96b411107ff77c0972117a1ffd586680204a11c5309ef713964369aba68428e0337fc38045d269472382789f68d38c1e38e43d1a51f9e1c9071c0c1dcf9430a3508e43010fb1b6cf30e6c1c908cc721f9ef3f33828374cd032d0e55cb39085aa020412b812a611c3ce5063b0eb827129f1c24ee2e4a39c4cb56a07158ca27c00dcda4ece4a07f1723e8428c43b3fd0d16ee7b1dce38e0248821bf02c28a4349da0dd0ce0e681cd4805110dcfba87f39a2b996739bed159867741cc43782e30062ce8c773b70dc3810eee5b852ddcc3868b6b8000c3914a67ab7f11781018e43f4673f9b128617a6dfba9ee25755cba045e77532ac2d0cc63e1fa64cfabdda9e884574cadaa757750c2d0eb9c085b23880df5a7d6250e941cfb13168eb2b33ae0688052b54e3403dc4a5c6e1dab1acc0d63878041a075e3952800da83408914c15422088dfdfa1048f6b5f08f04ac04fde1d7c831378a0ed8061a17ea59f26073c186dfd2c4e0c6d0e986c9b8fe913dda07adb010fee95479f970bd0ccc2c4ca0181ca010fb42bc1dbf4b7d46964b27ec65e9cdd38031ed6cf97430abd2cb3fc5bc4f8489a66ef2b3a3e10e39c18f5e30a1bf90135cd1a198b08b275a3d40e1ac21e45c46c24a4c1cb21d908ac8f1024f47ee706fa8d97642349045b3b42bfa03b7c560a5bb233bc815855799634409800187c0096ad002d035d8afb1e0f12dbfafa1a0468b8a9ca2c06479e7a0af4d1e32cf2c2540941c9d25227908b0595ab0bf805e0c66909d3c930ea1ae0862b477f0e3b78834af953a0c05b077ea10e15e911184808ac5434d63b00c9278463caa2ae6e4a8821fe3eefc646ea78a0b93562ddcf011adcf3c217bf217cb6d59d779249cdc11665b110e1f53a011adfb9983a32911228a66235ff5642603d1a9e0f0a473d88f44d0f921ddfc01d670b9598225c21f6d37ad83c233a3d44cf280e564c7a2888844c0f113ca2c1f53758cdd36d84e104223db02d672a9e4a0f802f3c3d5ce37e3fd74b9e9e1e4eee84e105c3c702d31e629b45507ab09e13c2d30b36f0356309ac956640f66730eb414c1e2aa2fcf520820d1324a10706d24cf5d0661a007a30eda485609d00f4b0c29d43fca56bea874e03d34b242034fce941cbccf490480ab31e0ae130cd4048de1c24722db9e7884090522aa27f7bfeec79301e5a461475009fe0228928766688bbeaf4c14710f5e2c3e593dbd4e40c8c02f313d23e588167fdc303b7383d7fc7454282a787475f23bf394f7cae7b8b2d9290006ba51337b2df3fbe32f586bff01ed80b4f0f8486eff450c49f1e4ce3f4702f9ba3e83b3dac8d8f81be3f500f64a9c9d034a07aa3a78713f26cb83447dba6edc5bc6fb3ad48f21bf7f4275e8e9b28462d36f8890199379c0bc4768d331460ecdd099f51329d1ed692a507b9d6f55d8016e37f7a8865d3b93879f480033b93731d9a1ee6e41748ce3c0e6f47e9815cb502ca80197c03b32fe15ac4f480ca582663084ec00a43587a500270e02dcfd67170ea1fd8169a1e426f677a7824b49691d303dc295d29fed7ae5b2c580c0520bba26dd462a98868b5e9688b9ac0b7dd7f800245a9b3100e900d5aa603fc4d828c066f70c2250016d2d5fa0bf3c118854578c6a17f16c8ada4f3bb421edb3607f499c053c928cf67f7c9703070a0f21f1cf8217c48a0aeb61e889d2d324921e7e2999ff54011c41f6a39385a7b6f3d0c441075dc52ac87cbeb93300fd1f520f2683df0257feba1e4b61e2cf86f3dfc94d9fc78176a93bc30222449a269c8f96470813d8cdb7c04b719143cd1600facf5ea810e21b59bf20af65f832f763dc435d3a59225d6b60a4f057bd8b34b62a5173505573d5d0f89918a9bf210f2816278027a5d0f4c0aaa1ea84212c76603fa5b0ff6f276f202de051de1cad95c11bec4b035897a6897440d3c8542eb6111a503ee851eee110022ea1e86d664723d28bb3310ee580faf6392810068d2cf5bd44562fbb50fbe5f685afb7098d6be32f2ad662075e7ba559a80eaf5c3252320f73e5d450de88b43eaa1acd5e01148ff9d68a31e16526980a1b201453e18e07e520f2ccd7a20be1b07040a388a379be8f3d4836820a887fc73ba510fe24c0b4a3d287f0cc21e634a3d9c70359bd1fc730c587800ff93bdb1885ccc403bb915f792fe3984a4f30860411e9b63eec78e97209baea21085f4a58ae039f081a80e46d8f5f9964e69a7184ba89a81e27a161c615652405f4a756070f5bbc73dace920f12c881a45f6bdf47a4b943a2a472a133ed324f5a794f410f2d37081ba0b9c2abe79a07e41de3ce0fe0119721e445311b75941729415644b73e681864643ce4320ffe81d18b9667eee70c0790832d6e26f27eb011e6ee7a44236e8f2a9c71e1de0387eba63129df91428163d249ed7304fa1910b37f8a4e8c17cc74091d5fc60641e52c439cbbb3c6622fd12a9901e0546b9c55023f3d6f96dc30e92730b5264585b70cbb0ea94c7ebef54c67b43cb64f090c3d93543ec63432464b7cae8f66140f6caf7400660792d2017e80674aebf3baa3c0808d13c9021ad1e14a8d73c6026a11ccc0db04d74c3810ee2f138384fe8b8a7d42268ad87fc1ee13d877c1e78e610d0a1f86137c233710b36c314152c82141307ac874085c7ec541e02a01e0d980e7077f1406e60a22ae8b8b21e6ca9d21eae69ee008feb041850b6075a8a8adbcc300265061eb7e368833298c131dc65c80589dc4a69f3e1b447cdde3503238770b5f94086b2f743cfe6835100460662f0a3f58e3dab246c3e30c52a12b582c0d0078d990376482bccd009e794b15cf208863ec4b9d9f31f1bd8651857e82132081f3842fd82189c0eeeb1639abbc961fb0c3fa1e82e813054ff1658166aa06829de04a4edff1ad2eaf48df816f7b741e643bcfe339caa5b74a676204a4b049e3e4c02710e73cf866d8e2f6f44a8220f615d3936ab33d017a206b12c87028e0815a44b2fe18fac9c3798c8ca0fa0e88040fece57c105badde7467a00bc448ee87856fd74961c8b6a3c80555eab7acbe85dae0690ebfff40db4ec4a589c41dd3780fd7e45ec6252677d5fd9f64690ada5d284d27741bf07d16048036e48413fdc0280f0c11dcc51b89970f1fe0c1bc0c116928088dfe5409b40ff12c2dfb7b303079d67e601ff8627e4050603581f1e02bc672a7cc84c3f99f84050e183637fee5ee1c34ee838e01ff665b8419c022eb304683e0b577c07df6618331f3ab00aa42ec34317ac119063978130e501ce6838f8c0d666830f2c5115801b1e1fa8630253752226f1f1815f6ebdb003061f1fc259c507c99e8f63fc317e742181e803bea8487ca00fd520be216cafedc614d1544f7a1b847d883338fec9e145cbea9b22c2728d18f5ca0c014fdd10f6414bbe200d8e1be9f115a381771f26e5c72dc8d62efdb54fe5804e9bb7e157f03410cdf8fd9d88d39fddafcc262b867044db07c6149955992441d9ce2a38d481bf1f4878f93e31051d63a8720c80491aa67b25860be801a1428010906f7b8b9c8a99d05dca6edbe4112183aae90b14204af90127788d5214b4078afe6643814006e45e5a2f03ef8c5981020423ce01896c86f2d56758dbe981e64038607344aa0a173b44250c3066101349d39a01abd128902da1e58066dc98b1bedff2f4589fef9241de7269fc8c2bdc1d830d20b8969ea1f6d10a5cd08e8452c0ec7cf6e371851e2011f03c398192b006a63d2201c6be355098dafb67e3d60980632ae076d6d9fef90bf9ff045781ec11d00b9271109ba9edad695e002b91273e37ae2181d37b84be2ba2f3c281219b1ab0c1fd5623f7889a654be67efee39f4c120fe80e65058547c9891b282d1877d5bca5fe8887152a7b559a316828728f985e10e09761d5f2d970cdf7c5bd3286b21cc55481e73cfc833bf947c4ee150fdb03867d9ff65afb3c57ca108506e0c9dabc66930d63c499f235fefde7b8e3c3c963068e022e70627c8f660c2ae6c6f926ff88031bd3b3fb48b864e3d2d05782ce3df87d4ad97ee74387b37a150eb77cdcffbb3eb6ff8e8bebe9d183f3ffeee3f9fc7f391def74fbeff68c1edc1c3ddc5122801f99dab6fa001c1ff73d5cef314e77723e97fb1f1bd4b8b0bdfdad92e26989f59cbbf75b4cff1a1b4a1373466d1020a1487701602c5205c477d4da49c703048950913201f44076e3dff1bd9864e6f5b1e06cd26bf6ee9ef36f78281cb95f029372decb11040955729bb1204874695367f6b2728564b87d49c165a0cab685473f65bb2508122d4667041c6667ece393b481442464ca49a9f6d0ef04d5b3a303b91bb870b50882046835b751ffd760f631dd47dadfc41deda4c02c822081dd271e7c70da72dc6b929adaad5d21057d28185b57ba844d34d92fed5130de4dd9afa6b71c06f3a555155089a82062bc320aeaff11f44527b26506f5235e7e1fb22253a461cbdfade647abcd38990616b8d40441423dbae81d08ee5d07f2bff9ce3efb638f8afce8ed39f77fa38fda13da6d9901bd60418c00d1f09a5083f940ad5c890741db80d213d542a97cf8da5ddf9f8090c5811e82f656010dfc4681d9563d1c426655e70b0267cbc017939303b7389d204854f88016fc0f21044162915ad4331ec4b5bf4760711750fce62388d19b7be6f014d8a7e5095644050ccc54c38bd469f5410e24c67598bb2240b507c42d0df5a201e5a4ba6f6d92620c10d55c4913822081fa0370113b06ec75cbe003099b9b4961d09113d714fc7bf97bfbde21edf72aefbbd20d9d9615df19ba0eef41b34ecf3380d9c49fc3fa712e30e006be18db1c6b6005d07ac66a19e82787bb91d7d7e1a5cf307e23e6907de0db57dc8e16f4d500267a057c1d50c1ec8ba0420409395b2245fc6fa451fcb62ab2b2c91ad31041a235bc3444a68c027ebe45285742eb04a54e70179c1213792f833fe126c08fba4bfcf903b992e0072e7bb7a1af3dde8fbd57ea01b102154da3980e3de9d65579476fd4936e83ab31ed30a0c0c507882001ce751dd7845554cd6ff3a98148ee08eace8e70a0fbe49eb297534eb317cb22a7536184bc9596c988fa18430003970274c1c1806c1996beda70307448d23d069a5b8da9bd332a27f48429f2ba37d631b7e11d65b7284e0cfe35b44d872d981eca354490a814fc03cfed418d22256c8d02da8117ab4c10608c266da8649882c5e53dac67122a03979166049e0aa433391d9b2904a988229eee9afdfaf6cf6c862b7bef0241713245b23c23d4457677ef2ccc5cfd6152acff370e15ab6d23a4114248ac095709e609f2993708f3cc6cb22bb34d8b4084d6a0f0f6bf7e6cca565fae6ac8891fe3fc2ec6779e46280dda183b7c8c1b7bd0bdd6426850b7de71c66961db1b7fb626426750085d93d93dcf2eb2f7d68b900f288cce6dfd6aab6caf13dac4d6c1383888d1ec0d84cca0cdbcdedcdfe2b4d71bd341a80794b528ddf17d0ff3cdb985caa05ffdddc3db6a9336fee44174b94216a17db685c8a0de306e3e27b6b7d66be71834b668af65554a88fd23743decfce8e4c043480cfafcb1730f766419bb47ab03d4f3337a209fe8324f6ef0a97941280c0a1bd61a99eb267fce76c1a0ef39d6f29d2e656bd2ab4d6c491511fa82369fb3e21a997439637430425ed066993f58db6336c78a6517f4a7757d5dab0ee7830e877640e1948fd5f8354ed6ae3b17f462afd23ec8d8ab2d7adc82b67e2c9bfdcaaae71c05eb78bb20a405b58fc167b23a161d868e8d3a8c900ee8c5b7a3cc0f57f9fd6216544a6feddfc9daf13a8779d0228405fdf7aac36967cc4f7490c12274059d1257f90cbbb6aeb16d36b17d767e80fea6e7c7e7e64ec7d9b515745ad85732171bdadaec0b55412bfbe9727cd1cd773643201e2b54c659ffbe783b67d7ba9708514171658e49e66a73726626a7a0d1c2eab7417bb393ac5929e865f3ad8bee5c73ed5bd3c13c3b51501cb183ed72c5ffdadde6831014b456eb209cef1a3a5661e8090aa77333cbe7fea76b77825eb7f2c197157a86cdba098a5fc5396398a5839f65e7805e265fb2779de76a2d7636b1473b178a20c4046dff6063e6f9d5f9588636b1e57c458496a02e67cb5efd9abbe5d99e4dec9dfbfa852054854ee6e2dfd8d895edc53c6d625f283a373e40ad6f08e180e20bf3cf6771738c65674337a0d5b9ea17bf0bdf61bbde6a846c40dbed6ffb18ae317775b94666871d4e301a22a4046d1142bfaee56d78678c35a010bf9d507a73083b32885383d8c9c121d0f9804c8d13211ad0e9e09bdf3cba0c3be39f9b6e8cf3728bd00c286bd7e594735adb308e2f09ca9863ec93bdf62bbf678727e7c68564406d6ec732dee66f66d61809faf7ddaeb9dad83246c74247508cefc455be97f384f1e6901134bb75976b6533ff933bd79d06a12268ad72ce975bc42d1bd6d9a976ca2014031a659d364adb11cbdaa00cc1803e5871cb99edbbeb6e0b51a1acc6989f7fc338dec97a0bd4d9ff871bbeaeb2bd2cb5402d8b2e62896f86acad6b2d0bd4eb37e9307bcf6221bb7dee0fa76779059aebc7f813b376efc78f7d746e1aa1f7fde5875e1b3fff276d6203817d24107607a7dd0ad4becd6cd6c6587d2ef7eb4265b3b3c517f343f85abc55a08f59cdff72bcf23ad9920ad4e2d92f7a7eec3e7c3b6d624f8cf335881eecd33e4535050a5dc208618359b68dafdac4c6f91b0b7471cf139d1cdc898a111a6f83d6e5cc2e9995d203304a29d07f7f8ec197afb6c7924581fe657fed7deeb1f3c6f28302c537be975d74af17b249a57a02cd92653c5ffa9430be196ba43b813e8bb05b569fd0c2c638d4f4ecf9e17941b508bdd95d295fc4b941d6173bd8f3c3533581da66f3f17bb9a3ab5fab2234439765c44dca07e1bb6de702f9b0382a2650e79cc3f72dab79b6ad3976d7512d81c2afb2319bee646b10bbd773548950f7f27db671e686d0d6894785089516dedc387775f26d6d7a54875087e3b5d0b5f7efe5f8a26c43a8bbe6deea6dc6b0e7db79544aa018bf3b5f76d0e38d5847ca9579a2834c941d1b66662e8eb2f3353217b630aa4228bb12ba6c5bff5f756971ea0f2a426896cc7aac9039f72dbb26813e681f4bd6adad941fb9e37cd5e9616606093467d762fec6f7bdb370dac41efd6028b17ff00d3838b5c671a157de0aabec5ba1cdfeb1b524aa235027ed6d15e2b6ced8c38c7b807c7670ec487a4d6c765446a01f1bdf7fd3ebbdb15bdbc496b9114826e7c6c6672608998f4032cc9da02a02adf9e26c71c4cdbdb7ff36b17f8072463838d5ca1f200fe86ce05544a02cdaf6f7dfb326ab83d226768ff74ded79a27303e5a6e7031d447b5a0c9f94d345e917cef61d4e30fa40b585c2dca237bcb2b229dd64d51068f63adfadf69b74b6fdb309896a103a9d740d1bbeed5a781f4641e874f099cb57dbddecd203a10fbfacded0bad9664b07087d976c7e6d58e6769d837fd0795b639b239e36b2882b3fe87cd773b773feb85fe34a089441782fb3aeb6dbd0b95769a196e537bd1f73cde49557a64646a646c6c6a7e220f34487eed1175516facf237ef0d6dccde509bd47ceaf547d502ba5cd17bf0cb394b1663e689b3ee56c0d4a67b13f2daa3da87351cee724eeaffe2cac91a1324f749009027539e3bf65cfdab4b3c5db57a78799999919c7387f034507283351e941996d89eb677cefeb793d0fea6264ee5c7b58bad8181eb4c12b259439cbfcce4567133b6251dd41a1bdd0c9eaefaec62c1d10e8ffcf8e2c339f13c36647527a7e584b51d94131f6d817da18abdf66f50728e78626aa3a687d0b23fe779619acef1c8d8a0efa5ebb7e7819aef2a59573d0ea5ef1b49339c6426f7e983d3b3f3f36219636b1efe8f5eca192833ac3f9d9cdb6d967183f1602991a190602191e7490817d8532eb75d6fc98b7dbb7e51f50582f9c6c7ebcffafb693ce533da001d83c356784711e68e7b2fea9e2a0b6d5566b933fddbd97ad4d6cd8855470d0bfd6398b0c6229e183acfd0d6aa19cf0a38cd3417ffedca0d22ffe2be7c52d3f576c131b8ace0d6c297666a6a5583bc2e1c9b9694d2951b541dba16befe06c575e8cdd263664a26283becff8e657f1cb564a065d8d6a0d2a5dcb176d6319bbd5ec716646e6c90d32dd7638c188da52a941bd237cf5d6d6dee6e60c62a04a83628baf6b306327edec863748c11d9899918281f0ae91615ea141198630fb7b65d93a9c9f8ef3540fecd0cd537374dc1994b1e92da77cf06dbfe703fa5c627f3563d61fbf2f052a3328c4d133f69c6f842fe3da03daf65ee6d7cd38ab8b523010a3114fcd69e7a91e60cd53735acfce4f9d65d06eefdec37b61d7685d3f0fa8958fb58778de06ed735e91f11cced097bf237c0c1b9635d75c8d4165fd89e1fce76db268632506fdafd3be8c657c77ddf42a0ceaae9dfdf2d78abfc5cb84d8a99999f9222a30e88d11e3dbf9beeb1cab5fd0fc306b98a38d96396cf6078be007fbb09ea2f282328c63ecc6206ed5757d5dd079259eaebf4a7b5fedbb03ea33e76b6794376237b3adb8a0d8e2ecfdb9daec177aadb6a037df6eb19fc5feb3b5d7824e5b1f9b97bd386b9cd77540f18cd821aed27e8eee8e822a0bca5c37f870d687ed6b11e3d40a0bea24f48713de7673ceed5c0baa2be865f24a7fefde1964f3a7545650065fba57f8b0db856ff618551514ba8db8dbbf3b07277427a3b202e18db6ddda207c5450eb1076fe299be5413505f56ed89ff5e7b6efbe48834a0adaf074099db7ee86a793a31ea28a823abe2d4ea02df68dcf62ec7085f63d9bd8a39deb1ab616a10f9b65c6626b0d4bebd06a02fd7fcebfba7af38baf4a4b110a9d65ace5da393a9c33b689eddd03fea932b09840e543778effd57cfd730e82be2550e71a4a08df5b77e73b9608f5c7d9ca2673bdb5c5c910a1d3d5e69c74d959cd1cd621d4f57bacdd98e383125e6908cdddf9b133c8e46d2d3f1fc35202adef988c56c259df8b8f0ba12c4ae76c76ff2f67b450a646a6071621f4dd8ddff9357827abb0f260258176ceb8a373b83e67316ba68585041aedbf8db9bd9a995f9bb950d6b2cb561bfe6ff1367c04da1856c7dc996bd85a789b1168ab0fc2ec10d6dcd7e25904ca70cbcd60bcedb1f3378940df3694d6cd763ba3b5528a1544d9fcbf30b7366bed88df96ee2733bbd14d268740a3cdd3b279fd67eddcec12d620d47d658de11b677c27abac6209423be3d9626d6fe68f91b52bac4068b3b6edc1ebaffd7b6d80d08e0fdfc66f42585d7ef90ffa13c26f6ff858757656e8fab0fca00e19bcafb5d932862f4f21d028278ef8affcf9588e6f69a1b39f9d37be6bac623b5916fad261176dab5d1f329f7dd0c61c86d36fbbce4c7ae483be94aeb2099d736e0fdaeaf773cfd74a76317e1c646a646e90a991d9804c8d066a6c6005814afc56e2c7fff8d608a31e14cf789bbbac5dfb8d631ef4ba169fec6a31aeed1a0f0adfb17fdf9c7c8e3fdf2eac3ba847b7d846d671568cdd0381ca8b5b9db2676b13b6be76502971d79ed2cdf7735a5833aa833e6cb5e3850ce3cfec353a287c17bbf7edebe719ddcfb0e6a057da77eb4719fbdedc2c16da2d32e7b07cee5ffec69cb0e4a011b6dc6c73f9a4bd9e3b0abe3ade6c585768cb769dcbf83dd83636f6031aef3397bbd9d96c8dd56f0e71d0d791e1d659e29a6b830f0edaf1b667fb6fb57de53399273ac8741ad61bb4ba8b1984dd5abee7f3dda0333e1bd9bfb5d36a83c6eba0bb295bc37cb1956c5039616e98c5675ffbebbc0675efba7fe777257693596ad08761cbf935c95afb2aa195069d5566d7de8316d7d7ef56586850085f7b9ff661bd8db99d99e95ec33a836218efcc71be28e17d52fa80cac7da55389beb8a23b666d0d95e75ef669959fcd8640fe8ad914989fdfdbbaea393a99191a991695d875506ed5b5dc68925fc8b3b561ed0d8d63d97d6c53aedbf4906751dd96d7f59652ccbea6350cb1ac27c617c28066db75ebdfa632c61bd61d0e62fb32b65f36b2b93120c0b0cda1cba7baf737bafba3cbfa057b6095d964ec61abd7941bbb5ce2d999376ba89bd0bfa648eceabbbb37b4e79f1b076405bc6261b7e7f6c1db3d66a585cd0fb58aeb6afb3afcddc161437fc1edb5f283bbe0bb5a08d9d676751badb666dd50175cddde9105f3bebff7b54a66666c6cdc0ca824ee81a5fd7707b0ddd6766588fda068a6161411dfb7532dadbb03d64f00afad06138b3bb266bb78f55a646a6468646e6890e323333ceb2823ec32d675b67c432da978fb0aaa0d35a26dddd7e75761f66542c2bb431cc30db6f2d7684f2c2976351415bcb7e891bf6e9b0ab51a6466666e65953d0da1ddf9f75f65f6dac758fdacdb0a4a0b6e569edf516f1950ff6a81d0e2b0a9a5fc62cb675554aebfebb0d0b0a9ab3f398d9abac36e6dc03cf0eeb09dabebdb393d53c5d6ecfdb15cb096a9ffbab31db9fd16bf551ffc0bec36a8246cf7dfddbc577799bb5984704a3e6c3ca01b510c2e7b57ddaf736b7c5047de6b0cd9efed7c9fb3f33e33d6af7d1d9b9f1d1c13f5130eb40ac25e89b8d5d88339bb34d39e1bb815585ba3f67a1f3cc6e6b27270e68aeefeb84b3c6dc31b2bb73817c1a07d60da87c395bc6226e585f85d8ad5836a0edb163f25a8fd273b456091a6f93b2decc2eee9c9d3559855503cada35692fcc8dc9e8a063515834a0f9dd392f73f6399cafd619d0fc2ab4b1cef65cc3e6704329ac2428fc67f67174f9ddd658c22d2c19505899c5cec11b99bf830f09daaeb3ddec7eb42db38fce8575049d6edde66a67ad36da674e8565047de7beeb953863ecb39bf4c22a82b63af3c359bed7673bca18d02cf1655e6b7cd16628e717160ce8ad76b27e157f6b8f3326c3a242bbde6b6fcdcdc13645680b54e2dbf7fe6b4dde7fdb5aa0125b676fb39d9861569fcb029db86deb6fcd31ecdedb88059a33c6cdb05ff7b7eecde65d84ae40618def5996993d73ce26ac126a84f6b79f12da8e90c5eaa00e0ec20a34dad8aa8d19defc6a94d7bbd0f8de3837dba0ad027d6721f37753ce514311a202f52c6d76597a4fd72cec29d0e866b30bd984aec13adb6d46e84707adf32c7375ed7d4b8176c5ee59681973d6226eb38a5014a83b58dffb3a5bb3eaada1405bc56e6176f8a0c78b1d13a127d08e52da8cdb6d8cb91c9d40e1db1ba5abd39b59092d42efc38e6bac1236815afb5a9cb7e3bcac1f5e4568bf671d9635cec858c5ce04eadf31ba6e9de563ebf012287c062fb4f64a7fd34d164a84cae69731f71c3f66d82a22d45e36a3f5d70d6fc6f0bb4787d0eb9faffbacec4af8240e1942ff39ab3e59bd7d5d6ca804da2eeb08affd36e5779b8550fb6c85ee11e22771769110faf1bdcb6aefdfe618bf24d076dbd527ef8d0f9f7436332371107d460809b442e62ecbb0e563f9590433333333a3863db184b850af2dba79e383f70834d7f9b0dbceacedfb768d40678cb623c4f0df5ec85811688599e1762ba37533ce48047aed733ee7b3ddfae1ec41b4fd9cf6c268e58cd96f87b6d0faa094b131dbf0b1bf1d1a02c5d7dfc2c8ba2b86ee1303a141a8cbafcad9f2666f2f475c7faa06646a64b20e152141687377dfdfe4c4cf6b77ec402810da584feff8aec7e6f71f106a2d6effd8397c2dab8e2111fa8346c7efc6972eb18d92c1901f3437e62eb7ee962eb664708484407bd687a775b1e1b3ad3e2db462dc8e1b4be9727a8659a89dccb2d617b3fbd8ddfb800ecec0ebf2bd5976d6ba86f8a0113ad73cc31ca59dcdf21eb4ddfd7afd2adfc5f1632808f47eaeb5fdedeccba0ab0f05213de87d5759fcf89e75d9df427950e75e96ee359f37ee84f0a0ef1cda8bdfafed3badbd83621b61e7966e62e6d96120d0f6d95b6cecfd65199f656d07ed98fbbf36c85ab6d6eba0ee5f36d74f62699dcb8e0eda8ce566b36c0baf93f0cd4127cecd62dcb3deaede1e0b7db7f23f5ae711677ff64407992b4272d0271fabd0bec4b8ca88b18f14dc81d015da9ab318beb797bbe1caa419a11f5017dd3b19a583ec73847150cc5ace1e1d3f677f4e27535346080efa5c5f889f64d3c5c95c0dbd41efbcb6e1fcec5f9b8def066dc732dbc660b4d865b436b147fedaa02ea76b8eddfa2074ec8f0d1a7500a23f1ec80789c88f7bab12911078b248a4e504a31e0820caa2030483a80f26223e5e10eda123e58767c474a0f82c1105c1c9a644a407ce12511ef75624223c0220ba03ebdce45c473b3f2f8880c0934738d5eef4f0dc58dca34464874ebdf91d5b39d05467e7c90e397c80870288ead8e9c1438c7c6e44223a9c6ca3bb93338282756c12d11c50b08e4d22c2820394e382480e9dd18fce4ecec85edc834474e5070a10c50187e80d371c206a8356e93877ccf8c12bf1656ccc205a833219e1d7dad0db3e9b50a4461a302234cef081192dea4119f4cdfc2c6ed6e27df29914f1208ac8b8e1a1118d2106b5d3f993337bcdac45d961f8244004c6174d445dec2006111706106d810091161610e9c089280b0788b070d1154d64458ca80a2b544841676df75cbcb77a6ef93d0a289e5080c809da9cc4cdebc7e63a3d403fb867a49347393e558811fea93d3f3e0fe433daf969ad891c7ca089888925aa50e66acbcf5d6cd8708dcd06110ea8b5b97576f359afd3c217dd8036f4775e5fc7f96adbec4303910d62444ac820aa01bd9e31937e71f6ca727458443498410ca22446302219204173775b6feeb5d96d71706af49c1b1d7e6e726e70465144478c062032825a88ef83fddec97ab1b7155111f47f4a77127ecc797a9da218d0d9de5e1bbdc9f8fe2113c1805ac8acc3d7b666fb7e7b244454e88511cb0cedb538beb7db029d3fd93fdc324ae81ef4332e2dd097133338e39cee3acf9a051aab9390bd6bdcac5db6dec18505fad5dadab0e529e594ee5e814a27af3fef072dfc18652374fa632c3be762b602850ebe7fb545f9bebefc2e3436c8ae736f2cddacedaa402363774616ad7bceb16c2ad0f776b9b1c36fc66e36059aeb9cd02f6bee5e65cc3142df6d6de19bd2edb35cb3142873b55b7d08e7cc35f61505fafe18ba362baef0d986d3b8a040259cb7a7abadd9d70ce5f504182e27f4ecd424b916a1ef42d8ffbef1cbb6cad8040a5bb7eaae857de7c53f3d3b3eb0fd07fba8e05284665859ae2edf26eb7f8d36b131941e9cc3ba5d4ca0d5abb39f718631c218a7956b09d4c9099dcdb23583f35dd9c79508edd6e46c2e7a7ed967ae88d0c6b0bcf0f6b3f95abcf73a843ac7ef3adfd69cdbd8f26508adf531d9cfd52827ee17c26900f34879d28379786a0f09a6119712a89d8e392ce7bf8bf9415b08fd262d7ed0f3d776f608a1cc1fbcfd2464f24a02bdce62e6e0ecec11cbc9e6b890401f6e784a783bcbd9e09d5ca884733ec4f656066fb723d0f9cde52c9dd968047a6dfdfaf55628dd66278b406165ee1b7a9d973964900834ba75679835cb20f3f9415442d89acfb7f39fd91b47d7167aef6d871d7bf01a02cd535a777621ece859fe18d720b4de58fdde97b9e10ceb158466f66a7e2f1f4fb71f3b109ae76cb6fd4ff77638b64decfe0b107ae36dde0efe8b3e5bbc7fd0376fb319c36fe8cfc968139bf9e507bdb72feeebe63b1e7490a96947a27009813e67ed76cceddd879f75298198537169a1f2b95ca3adb5befa58bb59a8bbd0669faec6ec9a35dc07f569b1bb9ff195f239382f3ea8d79bddb6f6762f7cae6d6243d1b99172593fe7a9390d05d71e14f6d78e30dff62076b505815a1cef7f377badbb07fbd283baebdc3f7656567f4e668c331afdf4ecf88c9efff4ecf8b82b0f6aef377f59e5b7c3ec653ca87473be16f195d14d7cff0e0a25b6d61f630fdfdf9f40a0b01fbeedec9bcd0ecafcbebdac312cad67ec72f023ae3aa8c5d86166f7cdb68eef5f74d06e9773b6703ae6cee17336ae39286e1ef385cff6cced398785fa85cc4de8e6b5ede6d7a316c225078d1fb1ac12378f15c31c0bb9aed0f79adf59f4e61a66ed655c3fa012e3660e6279ad7d57df6471506ba7acb6ddbe58a7fbec1a1cb4e5acb25d84f6befb09efcd486727de1c743e00af3768b56ddb63db5c6d6d1f7383e67c596d0d1fb43fb37d6dd0171f6bd76ee3cfec95b1415d3308dfad163bd81cfb6b0deab3799c333a672f3528fe16617eb066bf6ef6103712ca95067d9ee1c49dd9e3781f4e34a8bb8ec93a1b7eacdd77b4893dc23f3b3acea35c67d08ef96668a3b34eba3ba50f28b3b15dc9f0ab0fdb6e7d9941eb74b36b3b96f1acef359bd842d49e11c6f9750fe893d965fdeb586be62ab6895719b43609e5f5e6ee2d4aec36b1997bbe784071bff60e37ce37b696d626b6947972830c1581b7eee222833ed66da5b492595b737b6350dcf3bd3f336ceb7b6e99273a403b2e3128b65de364583a8bf195f20a834e66276e67d2c6078867ca3cb90182411dfeaedf397a6496d9b789fddc3b8eeb0bfad8c41fdf62095f8bcc2f2fe8cf7e31e7fcbce147cbbaa070bacff9bec60e99cd7107145eb75d59c70899630d7241a3cf7e8730ffc7dce2bcb6a0b9d677df71fbbece62beb4a0cccde7dc7b2cad95addd252e1d50c76edb1a9bd7cadaf91de9ec341f207676709899f1016267c7260e72654133f619eb7cd697e1279b4d6cd6ef870b0b0abba78cac5e57e3cc30e7ba82bebb5c2b7cf8ddf38550e703353838343235323d3b3235323f51f08fce4e8d4c8d8ccc131d641cebc7c56505c5123e56739516f79cd65e55d0781fcf97216b6febaccf26365054e2b2429bdbd6cc5ecc5e8357eadcd41f9d1d2b5b705141a54b26ab7dd1b1161fc636b17170aa753a1bf0bea6a017b6db873fdfc6199de9ece4e4ecd8d6f60647043bcccccccc74c3bf7187138c7a2e29687c3f9b63ff59a1f486af2828f3fadccf6c597c38dfe36083066c7caacd063a20532383c3bca0a03f1dac11560b63844fdab9c3094653ae2768bbf8a6b3d3d6776784cd098a73c5ef6657e1f48859bc9aa011f7f436a78d2ebfb4eeca01cd323b8bd87aad17c7f878d04186c53d2e2628eefeec58b2eaa2cbf5d5e05a82baf9a6ac5e5f368bd8ca59e5aa4265b5ecb39bf3e59b1b4a1c50ec32f35ba3b79921f661ade10da8e7d6da8391c9aef05a0874d980be94b71b5af6efb6cea7047dcee78b13baf698942fd680f67db355e7e4c77ead561ad0dbf5a3cb3fe3e36e33a0b96d66ef4d689f37176112d43af7f5e52bb17bd9e1cb8062285dadd265833e9d4b24e8c317d7aff03a67b6ef3d82c20af35759e3fdaef0ab11f473cb8ba37bd966c3d71541a3942d76bf331c03da1177ce8cf59d0e63be170ca8ec96e5477cd97cc85e0d6436b8a85026218c8d596e59da6bb740a79493b5d7f0941dffb316a8adb5c58aab4bec8f2f9e59a01d317eafde5adb7bd82c16e89b0d9bc59a5993b333be027d3edd7337e2cf8e736e94d63c588dd0caf07bf7dabf4cbafb3cde5856a0f5276ed54677b9dd7bee56dcf398d585bae3fc7ead7dfe2c3a5b052abf7b3663de60cf995fe6c90d5270076c7c2a0e353668c003333311e6615181563b19ecf6a67313e287d614288ed1620ca79cd6fa9bcf62843ecb5cb7b367ebadd9c19602cd50be78a7bbdb705ed836b1ff8e46ed3a5851a0b9b97ecc36f86d4206e4336a3c35070af4f663b70f7a57b7ec421eeb09b4f59cedce8ffeb7f5f3145801374ddc4491c79523cc80a2a8235204ac9829c68a918820a4aaaaaaaaaa4aaa2aa9891308d054314e620c004353c51880c90be5a48a89c244bab2851134a118cbb22c8bfac3aa424a923479024d284609972c3455cc0b6f884143e5d1044d1426d2953c8ca099620c40235dc143112b2689157335b982c7213402a09c484c962c59a22426498c8806494c94284b962c59b2244a94283474e9d2a54b972e5dba50225ce9d2a54b972e5dba4039e2da72c465c865881e78cc71033deea041112184a04111219448d40b492827a14a082c766cc9e186061a6800000d32642c7ff491430e50b000d225d3706363636303058b214d74e9d2a58b75050b12f2a099682c3aac39b034f2064c0c12162e8ad4304d24e8e1490d24e8a1861aa49869aa01890413c334c54c57904482eb10da03132412cc24f5f0e4fa639aa6699aa60d971fd305c815088d0c77c4384dd30403d35a6b301768176817b800086060601a8c046060a6699aa6699a30d0da344dd3f4ba25bca8588b04f91514d4d3a545ba02b1409380d5c8b54592a449ca0954e00a9224c98649ba82a607f04059095da19c3c60aa42a3a44992263ff04083c3d89226219a26130d150505ad4c4d00105385aed0bc48344b9a4c6f504eae0730a1627e08adf1f24293171a264da423120d92254d2424124c28c9912633fc10854a931f92d02089b91071018d9218898a10885132c30f48625e3ec025c9c4c485984b09451273a4c984445222124d2ecc70716972154239b9624431493250899a4c34489a30a171a1c90f51a850a1f9798126143335f9e1858a95e4c8c585822f3157cc5548cc4b4c888a1088798991184d0628083409bd4135e09a21b406e5e48aa16132c54832d70c408868a0a01c48a6182ad71b57ca38630b2fa2b04263594a504e2cab0a0698fc104284c6aa62ae1829c60626a1699a1e605dd645a572a30acd1583846212ba52c6195b781185159aeb528272725d5524690246504eae1b241a911152042e1115cac94585d6a0b9627e080d72d14139b96242335c6f504eae981f445468ae181b98583157d0343de001971f17205720d354030623d334598d4cd3344dd3ac800dd3f4001a19b660a4b51c5abba8588b5c5b1c071c3a30d14c31a12bd654dd8144aa01060606060606060606669a981820669aa42b48ba82a498890912e90a92ae20696aed0aba0eb982ae20bfb0e0706db9b65c5ba41a2489b6760549303030301280a9a10618095c419244e748221179699924e982a2063994d0440d30d2258574055d410f906ac06044862864881bb8fcb800b9028181818181894192ae20e90a92ae20a9060c46280c9d345023d5c04860b21a99a6699afada72054936d0c048609adc042a7005493234615961596159710559565c415e94b1860d7d5cb9b65c0066bafcb802b180d5c8f5c7b545bae6b8b45c824c4c443193045a6b30305aae2c97209710b45c825c730872f57169b9b45c8250e0ca720d720d224930128069adb506033331b9622626476226262ec44c57505f5bae3e2e2d59287069b9b25c5a2870097265b906b906116d810bcd442589aa4a150517449ed0e5ca1d5906c1c28b32d688a20a950445a5cb1310e13248963bae60e145196b504962aa3245d1e509887019240b0d454946434d312ec464a01229a12ecc201d69726d9168a8231360f232034d284654019a504c15134385e69ae10a62f242850a93172a546862a8d0404a001402b4883196345d41920413616298ae32ae332e37ae36ae362e36a46b8deb094b0ad62257d0b5a5bd8b8ab588075d555c4c5c4157d095c5f5c7b545864b0657d0b5e5da72fdd15a836917956b8b5f5ba689099298e9c2e3fae3a20346bab65c5bae2d30d2b545baea9041060605165094d1e8786266828191983c7187140189e60034559303d020b19254a1f941e25285c90f1217ea0a4ca6182a866bcb0cd7162612171a89867a8386263257501319aec4b1460d344831cc204d579014c30c36c75819b018d204162c572e3e243004245cb09660156229c122c44a8245042bc81ac4da6205620162f561f1610dc1f2c31282a5c5cac3bac3aaa3fa30b2e4b0ceb0b2b0b0b0aeb0a2b0a0b07060396131613d310132fd31f95119521d5261a10aaa96603551215231a14a4245846a08d5160a8b9011212a5514aa422a2ed511aa46aa2b587684b6a0ac5489587884b8d8d1a918a9a8504d61daa3aa426585aa4ba5850a0995112a2554844c59bcc0052d18428a1018052730c1e4c50a549082128c4004930e2200010b8daa083c0e6880936b25622162ed6165b1f470c362c3dac29ac2a22264c77445280b1684ac84a8b0bca8b25049a11aa40aa40284aaa20a42a547954785477587a546354775c532a48ac302420547f546f583ca8d4a8e0a8b7504cb08d61ad61b561b1612ac34ac22585cac1c5833a88050d951d551d151f151ed51f55169a9b25841a8daa8d8a8d6a8d0a8d2a8d4a87c509d6131a132a3ea41c583aa0c0b8e8a8c6a8c4a8c2a8cca8baa8bea8a8a8b6a0795145514d51655954a8bca069512950eaa2c2a2c2c2daa292a2baa2a2a2b151556171514d51395135513550e2a26aa25ac432c292c2b5615d517150daa1958825438a890a88ea88ca88aa86250c1a0a2426d81d20295050a0bd415a846282b505da82a5054a0a640314249818a020505ea099413a845a826508a504ca09640254221420895048a0b7504ca08541128225041d4166a08d420942054201420d41f941f9410282d5416aa0f8a0f6a0f2a08941e541e141ed41d1410283ba83a283aa839282c941cd415ea07541c141cd41b941b541b141bd41a941a541a141ad419540fa832281e5064506350625060505f505d503ba0b6a0b4b09698f4a814997c3099316199e498a898a600fab1b0e000f1c32b80ca621561252159329068b09090ac2324ab0849c68a8164c140b2a848a12d48020869410a65410a5d411a5120d448c80aa12ea12a84a8109a4288919014a42848212848212748a145a45013a41013a426a12548a144a41022522152881029840429c4450a0549a141a4502052880e2984450a81b483e4014907a90312072402dc2065406a255888e608830aa585d2f2c20ba117647841c4e4886559492aab0651354d4796504c8e4ca2ca0a80354d5392ca125996455154689a8e4cd324124dd5245195655953454d9655591545515388b22ccb9a921ca924c99a28ea88548526aaaaa449baaeebaa2e005cd3654dd3754dd7355192744dd3355d13355d48aea99a445355d1505592344dd392699a5ea8aaa224694242512f4b182051d33459a10350932592284a928e4cd52451d43489a623d53451d4cb544d32d3b4806a9aaa6a9a04304dd23455d56455555559d511015833509325210980344d533589a66a9a2a8aaaaa2392f4324d166585282a8623472a6a9a5cb05c70a1494c0c964824a2420aa044a29028242a00002489aa2c0b4912cb856a9a98b8c0445a5225c09a921c99ac69c901aa2a49122b44491345858e84a64992a609c9c5c795a57a41a2ae0308200052103ab84280e4a319606080c10006b80a20c580000220418244eaa93f35c4c0c03000e9002229081d5cc9f092034a3ae2c394e9a5b2889896bcf830659a3285f28188690a11d414ca872913e58334658ae4833465f2419a3265ca14222c22a62993241111f281888988c987294410112282f2412262f2c10905c62449d294e353a55e22f1d842f2f1f99910557fea9db1a6fa53ef4ecf8c48aa0a706487670484ad3f3ea31100a4090691e8c58d76337a796983365be5c4de1ceb8f9827c7b2416df5d8eecdb0c257f1cc6b50ebda84d8dd8f2fb7bc41ece4e4e09c988373e08b1ab4b5c4173e2b6b965fabdbc4863938e7bda4d16e7e706c7c2a1aede627889b7b064f8e0f68fbf367cd5a56bff1bd4d94de40de39b8e7e2216e70eaec1f9d9be6a373f3837303f4a31e8c73c393b36341f06246bbf9e9b1f1c1198d8ebcf4a0ddfcdc9d1ca0d1e8c84b1952782c0f7eb04f0eceb95ec8f0979731c470f047e706280c9d7a737530ce2867c7002f607cd193bde8c95df4b0c067073840395c3c90cf16f756242f5ae8b8e845073aa38b7b7476745e78c9023e7fc1023e7fb9023e7fb1a2002f550c318494282f567e301016e85fa8c038373f239f97297aaccfa80743d1c13c3c373c34bc48d13c30bc44816381f0a82743d19301f0f284cee8eee48c7e2c9317279c278f74a0dce0d4252f4d2879c9818ece080728c767c90b133aa39c9b283b3d3c3c75f415869725dcddc969a351005eaaf85401bce000ff5428b8070a943a12a2f6c4f072839f1b9d9b175e6c90775e94b8b7d6c047438c767e46d8e7a6f604e08506475e66c013058f96bc24a133c2f93bd2799101cedf11d6b9c17979414267c4b3b38333eac1383837394a5e8ec03a3b239f9b91374f7e31c29bc707e84607ff4e4f86e1a508f81203ecd38383d0b949f20203c893474c4a9491945ff242850dc19894283088b6e0fd22d282e3c9a32c8cec4dcececf0e8e95620320c202e4c9231ca01c91e80ade3c79d488155e445d5c159c0a3f38403953f0c1813272465c0a1e0587823fc15f444ef045bc0951601029e24cf0254471b2291125e24b4488f8216e48df30d2b9018048090d65a473a34454c810231f209d9b9c910fceb9f921e425e109d1c3838421861849f9511037f788880b7c3eba3b394a444770428c6c7e76767ed4836d7e2a9403888cf08ae084784144841f1ca09c209cfc82684b103850463f38403943c0a9402cc0239f1b184483301109a2d346527e840394b34414c8bdf52e110182711e68e7de8f21a824ef0c755192a220866110060030444b131400331500002818100d0683d14c901545a93d14000540483446423a1c341c180d8622814020100643815028140c85a3208a832892e4419a13b902102e79a13acf16468be114f7b94649d25a103c619363dc65c0c2a3af9da40d8b153ae745a4b663483ce1167acc9f121949bccd11aa2aa0928091e0ccc9700a17fdf9e18435ed3901d37c814b56f7ac14317f7ba816cb4642ca8895c9b38a50a165d6acbd3b0be39742743a16f0ee2cb95b09ebe960f26572b794fdc2d560ae532e42ba50cb081888c57fc0c58f77ea25db0b3177e3720fc75379c78106302da236d50f25a1153aa592945eabf9d1d1d5a45db25550e0dcb3f5bba892e638b868f483329deedac6217e0748b1aeff258aa4c84548a53132d28fd4dab02a98f38091c1f54cae8578de5a511d581b442fb88b23dfb30aba08f90c2464049050638c81ca3ad0466923e2eca955d1e1baad936262f70556a7e81769c92691d5576672a86282694829dcb897c663a5f3d8d758b30ede32ad0d7fb485ea4553e669f352e1f06c9f1476a981a0030f3c21e0ff5fe04af41f0e6c4ef57ad4a826eb6a8676ad03ade84aaa0c6cb4b5cc02bc04dc3e00a714eaa97ed4c54fdc72d300a2e2d71012d9d2d7b9d456893c723854b54c493bd075c6b546dfdf15d40f6c93c01cc1f2ea304f11a67deae556b5870d9d1371e28448d463c34ce9a0f345d7e4c8289eec68005e934ec40e826d4e06ccc422b3dba9eedf1b8ba78cb102dfa7e185d8b0fb547262a94ccf5b221ee10ac5a8173d9a253536df0a2f2fc1ad663343a29e73266749cb468e6c5907121fc1a59ccc728843f84c824d0d0211506ae6350f6b9ac41b0dbecc0787270ed170f7c27595714411aba0c2d42cfc21515eb4a72d072c53018b6c0dce678a41e507ca34df3277195fbea170222ddd7b6279f546155806874f10bde192b4ac92767eb04cd02883a7a2701e36f9b8f86e6ae1581c33d4f3c6e566d3517f15c886f6015680e8e12138d8714c9d0f20dfbe4cb151d93368123e17fa65d5648482d548406df3bc5a61d4d383d529142525953488af336bd876aa8623cd1d16359b21b3cea8887f3d715b2f3197945663dc4f1dc64a8466173fc3c10597f0a72cd8337dc38912cde87b0148d5780215858d1ec6029313cab7f398d9dc89f3313e0d7ee32864eafadca08c895c4856abb8acb2e62e3ec117f29589de2b49cbe924073882a31212ff8a9f3c7b5f65d2580e7f34344e20670bb7657f7d5f2874b7454aa418120d139389f6f997fb51d346abc0cb862543848ec3ea00796fb600307c918df3c6abc54da111e18623ebdaeb2aaeb98d5455e9b038350bbaafdb7c73835a1787478db75d60448aa0fb79f40abba08dc22aebbc95cb54e867016cfbf58a0f0444a4f2207561630b11c531ef1c98a5c40608ab535c4999d1cc804d81e45bd13535588feb34abf979e5b845025ae5ae7f86a11a25438c96c9a37205c67f82b6fb6ee8d9363947063ece6f5d64696b4607ccc2f62c660e33446763c3a0d5a546d44c761e586a659d71ba963fbe686b4758f8327a5033cf2fafe964c3062bcca0030e95ee30a6b440f6abb38869e39faa675eaaf5cd194652f195f1ad0c44f727c25074e51a9119b715407802af57a19c1a09d46e6bef97c56a35cc32a0b384816bc74f62754a47023fab5cbc1f6014f1fc2b18caf17a084390355fed3dc2ea43255c248b50fc194f092f19aee21e562a1a9fb28de77c06d1ce788a6e518e3f60a699813185bbcb0a26e9aff0562571ff5c62213f0c49bb2dc5a41eb76cb7760e66680eec866a556ffb634720747b6de0a18da3bbc416128132585d6d1f0082e9ce9edf08dc6e6f80d042408a628c39683cc09d72b51f10820807c8a5a38f9d8307f305d310f76c724b5589c2174e74ac0d606952ea326f881034e3bc91caf3f97967a3ac5962026295b497d823c01cb3dbe053ae8a6ed1161afe52cbd3eca4553d2359ccac8c78f456717d3149fb55a2b42f6bb4f25e3bdd66b210c85e734ddd7296fa62b6aa65829c18bee0bb64dd977898c8d5c0e62a1b4dbce488898c4f527a417379969afdea170c74d796d3e99782660023b70b5be34a58f0320bb05308c65450841bfd6258ba66aea99983e2a877e3639e9291bec89a25702b49c91a2224bb7aea0bf2e1da4daee1fb62c5f7b9e8f23b32ca1120149034ca2d10cdab700c8b6497b18589fa2a3436bbf34f511ffaa8e95229c198660efedd498bd8dfdee2484787d3d5797a567e7032651d08a8d7fbd8dd39c25320556f3549ab56973fa679a50f2f2aff58f51ac19733553dc787d196ecf8ecc1e0dcb7836fed053460214280c11efeb3d47b29cc9c339ed20d104597247d10e214c714f6074ea281d8f56d729183ce948112988e1bb40482fefeb9e7231c3a83e5d04a5f24eee290f8aead71b9c82ea32b3fd41c442b644de0842d08a46a328a4871cdd9641d8935aa3f226be8588c8e2fa710ad98bed4b2748da65c4e7602aaeae83c67b830b894ba2ac762d9e55ca3df88183a49c1556dafc62b527e94a338a1aecb94749f4aaecbdc935a0bb1b3966e55f252f72c4103c4184540ba513eddb0fc170135d32d7e1a3d0069edde6505c7b41bae7658141ccd52a77034b0b3f256eb4a1bcc37f61609a0ec59776382a25358511bc10dd76419b6fe303ca45025a8edfa01a98c22278b3afc2088c5362ee4c14fc3c682fa318ee34a8182424804c926a15992dd8dfebd76e5c60ab4373f4a3ebd5532b89fb61b327cdb3b05eab265613c3988f4aaacdf0c9e54e291c4316b72c64ef43f4137e0b2490d684c6f07faa800ddde0c15589d72845e9dcf832eb0c5493d2c5260d166e2946396edcf7472aac20b89c7d37444e723e61cedab0a2e75103903940e863bf10aa19b4cbaef99c6906d814a4324878460e3c23c857adc855f900b2e678bb176d4a025e34f7129bdc33e633d788dc1f9cef5a10096d8634993652b5ad183eaa695747926c83b804398b8002ce4feac68eee740aa9588f54b766aa51685bd25b5124c0298318fa822069b31b9ffc02f7e990a219c1b79e08c2d3188c63dd1ebc544e35997a8c46767b0c520866fb24f550ff60d315416ea3dcb3ef567db5029787c94572b8845c662ef06ec782e691aff54e5565aaa623f1b0a23152f0f507800ff14335b9b99e69e99fd9165365279e941c2943b731dda0aa9a1ef67e890910941a7e3e7698e07ddfbbb0ca5df555cf97df4d877c696ba2710e3577b865f1ef616693241aa34ee44953e4b50a566eda7d2da3a95b6ebbbf499314ccde94ea056ccdcc731f7c61db4768edb2ab7a233ff2814bda8da5baee867c8ad84478c699072a5bbe0e2dff0593f2c9071a5471094237bfc05c46a867f7548c3fca70912290f7645fc54a35cb9f517ac2270d6b9f5efc9f1ea1f4ae0ca14e432e39bb16cdc7f64a4ad9094bd9d7cefc4712c7ab52eb21e04a0cf17b455bfde56dca04f3ce523dc841febf56fe542d8fd8384f66fe5462f2d2c8d3faedabe12bb74ac934f6538af2b91a7356844e6b1a2beb36e459dc4ff893176a9f433215e1c39a2aceabc15dd10ed0aa91b5bb991d935700e0af077c34abc42f6eafa4dd31b22ed792babe05be3657cc3abcb1f4c29757da6a13a45047cbbaed93ee42acbe1ca5a14af358c88b01552615d35575ee36fb83e9b65872b172c19786dfe718119e24a6ed40e3e707e28b0a3c8dea94a71c5811d10b8ff56ae721753c595fe82e20a098b9073b74c3b3208e46b916fc58dfc4d6c21c9e24ad45f7125214348bc95487e67ec555cb970812f4b9cb513c417e9f4eabfd83e27c935823eaa068060e33541643230dd1d44f2b48f12e6efd29c17dc510ab7093c96c0c8fd568cc251b11763371a7d10df4bdfabb41f8bf1acb9690ee3ed34bba396367f0432ab354f61f7f219b05fb32979dcc7808647e1ed8411085082df04b3aea00e44924af7d5f8c6643816ac0533a51849c88902bc3a2fbee19908606ea153769a6513fe280e71559bf4186bab099cca7139250ab91cd2507c322ccf2fd6e298ae0575961e88d0f7bb6b3fc36805043eb84c2999fd53706624752aaccb18864f9f37200af9bf6745e70dbc14a2441bd2fc7a8aec440be17e577878ff066850d02dbe790dda0dcc46a1e55669033f6bc2b08d929f12f73c0fff9acc4e0f1d35f530e01ed8721d64c4197ee2fc49471489a013e33b9880b44b71082853fb5d8f0acc23d077344415b723131e6c0516c2ad32971ba88693989d4c301c6c18ee93c2f3f63e3bef653cce5457e882c23a7787fd271723a1286b467c07fd33c23fead334cf06cfcb307f466cb2d7996dcd4553bc1c3f397b8615d438b73d43c880e95f8b593e17b850d400b45adebe47de3ea721679a2df1bec45f9d6f245d19854f5dcfc50ffcf85c38c5b9323ba569451afa48b8ee06c3290e81a11ddd0179771c95089caa36cb708a9b7bd18eaa6ba90ce7d2200cede02ec27845bfdc469bb82971348c3003a9d1c54dd118183725eabc71530ee498b6b1e3f9aaf0b8292b66d4130f92e50e2662689e10630359222cad6284b0f2f8907b6a1bc701736853621c53b5a63066748b24ef6ea5ddee0933c3b42c4aaa298d724d2b1fab50c4cd9ae273a77648babb301663dc5148b2da446d97a2f5f686438e16e5b3d7795e0dae3a1a6bd3b7522fb9f2b944a233f228b2ca81512c160d49ec66041bd67254b85740e3d61eb6db5381b45f6b8acb47b6c3bc87cc295bc6c3aa291de3686b0ac51831d858609ae20a84694a6f4dd8caab6527c464f86bee3ff9ae0a935a37a1c243533cf0d78e46c0dccf6d57a864fb4b852e88a6e80b0f7604107158bc3645d49483e9a0a8daf31967efaf8e200f7bc0f85b3156cff5ce0c9609a1e4954c1b5b8b1190c4dfe0339a7719cb0f41bf2e4666cd2913e9c52b39c7e384548600ca841f82c883e5b5059008ddf0be0927869a6ce6cc97b2039d362cbef01250bbb66d49dbbd4b482a2783293bab224327fa7a07ecb6370ba77f25cb0a558177a62f51ce2ef9a4e45463e34a3c076d5fac40a992bb24fcf57ebdca58b477a4bc7cfb1c454735f2816ee1dd86d078615586e950a2f019776e0d2fe355a70931cdb0b3de0d8715872208b2c06662b9c46807ec6afa4238d19de0824c65e8f7c4d9390bf5c85e3619447503d5ea223e00bd80c139e20bec7f9a5b699f359ae5771a4dd72aa9faf5b35ee80124cf9a61a27ea70aac56ea933f3e7d153201f3d7257bca63c89e295bd82eb73c370c60359c2c99530731a74495e562f6bf974835167a34f9b2d5f65319ad938e45f3f5503eafd020fa9434cf24e388bac1879f7ca85fe5495460333d3207a6c9f1313c2b7f9ccc52e55b3519ed1c9369390b8a1a1056255d8a1066cd828dea4c22dc685528c09451c760eb703f9d043894cf2801d2591ded2ecec10973246f8948c94b0f0a84933447d8b02ef08d312347154fd7ac374d11c7b840279447a014a90bb764b3bfd3084d731b8513f2c7cfaaaaf4ed07df02d1fa7c98547e83ba314629bebf8c8c7b5b07e16ed26b809f853ce98a9f246d1a6c63549ed08136293b03149c0c2552a1555184250864c0df856b1c30bff7ba5259a0ee27a7cba6d27ee62d737f94dbf293817cd5d4a68c3d8a8923f02e80b4131069200748db38f2684c5c381eb52d16c34d4ee0357f48ebdce76c2a43a749df6b58543e26e2e84de2cdee189a399cea278fb86d5e383396994bc4f371515240f6d2f3db29a637da4d07a3aad76cbbb15121ebf6b2efa87aab766b07a9a07d5b408f54e99d5ba036a98478dfa3c8e6dd6481597ed91194e3e45038735fd34886de2e2426366c1ec0ce4fa1a684185106e59ba3c6a637e058ccda1be6c74ea0e7194882dc4266d03df0f73ca79143540bb95d164efc5180f031fa61167177fe110099e775b4f31ac9b52a20af15d4bb29aa4daf50cf9814b028eb7ef75b5d3177d2ed7d65be80d9b85181ce5745b338429e3f6a41df4d6e91db22338365b4b3b87e456b9083b08379ef834ca204b77137205f78bbb479d8a264732f176784d9195024cb5afd359110ed7cbe2d18d860745c72490bc0de1221cfeab29e0245342c09a856706cecb9940f0d8eb79c56f3d1708bc856cc3905152493a1776e41cbba8c415b3f0946a47003f762b032ad8c848a4c9c40d3a592d115eb9071f64cfa3a82faa4ad2117bfd352a2478225de506f35057974f618f87715627888d53baa7bb4843f17f575961b3af22e8884952ec9955a2d2a1ed0d334fde7a96173094023e75683d2d4262ed541a9a46ea42e739f19edcad5673995bcf2117c4da3e7de76136d14625ef335e802b63b9453199b99796c2c3b3c53b21fcaf517c06fd9a9dbf04bd1441f1fa0ac0e882c7441022556ebaebfa04ec1aa11fcd7f0e6196937150d4efb7103a4cd4140e7f916ff241b9d4d80665f7d6555598f073e726a1c0d0c5b1a9e3d5aed6d900c01b7431fad9d0142294976b3162bf4cf3b7087035489590c677ca4eea17aec10fd52e2cd285a794257ba9eb9ac96107ba67b28463633641343a96f0091e9bf0da454221cef4873eb2773d1f5456db312261985f2a378e558a6d20895ca0c752e2fa0ad6495f510f649391600981c91189d4f9995fcc6df39f7f42bc4d6587be04d1c9c3cd03210d9a9c8920098fceec610a031e74d801871e314de71b6b926ecf295919d1b9d9a292061d0c67d8d905ce2959e6328ca7b966fe236dff698272169677fa307b597a8f4c3be8c7e321bf98bd0faf9d022470ee7744cf6276d094c28579beccd20aa920d4606002cced8364841bae078ae213dfed999fe6be70de8abf1963d6c42b03952278fd160d5cb919e1fe25d5d4018dfb78f03586dc50f5b08e151b3aa4c82d56171c589eff5078757c40bd709d2d2e04a0696df5769a9db53217cb02fffb1c9aaee41ef9a7d1ce670f812c276225bc7f3b3cd7859de3a463c134c18e2aed7864aff3b7518b4b584390052fcadfe5322568a22b917c5446672f6e37c49de693a990940ee655365c56384bef4cc549b0c13ebcc7f2f44d86f4209af844874a44975f8f732077a026614d259c1774358ec0301a07a0bd9260dd0dacd1dc115349420161f70c9ca30af8c44a76ecad0c3f2b25347be5281abf0d76546782f9f26a4f358036d4d44ba1f7a6eed41ae54ce584208e1c4e8c7d8423e87834fb14055451e845247ab5868d75c0f2a435da74aa13da9926ab4e9dd2c5230b5d111d10b754d292b287fcb9b9f76b603bb2ab08ba0af6e80a9180d3e493bfad7ae3b73d3ab3529a50b24f52c53b46a7fa90355ed3d5e7a8aa44a6d80466d8a3f1eba611386fcbc4d9e2479138a121c15f4483624d49791240a769397a96d607e3c2e42ce93b37d60f04ade23c8994de2f047bbc74f67f0607a13e32eb11c0df8df8c6ef0ed0f0428bab348b7d3af963f29e573108d9687dd011175b9902d6eac554e7d5d69a601f6284c7bdb4d989a0fa3e2846fddc84e421ef8d213f995dc144c37f5a7a57539ea01def84af6b5e9e154bf92a5adfef3e5964c3412d1a1c1be33441ddaf2c0f6cc1756e7acc4e070252c4f8277821abac2ce7c7a6c623e5bf766972f84c4af7f56853005ba5436e5d39cc31c411dcfa5310981714be116796d83c64c6426ce7c10019c418a149e611e30676fa811358000dbd46ee3493ec5e7b8f974cfa98aab69cd0990c95e6540490054b9946bd9ec791d2f09fe8701f4251685d240e0e26e3fc9195509102e5c15f56eea0159b7c7c5c3cb2a7ba52cd961fd21440689de54f3b4cb23c923e47dd722c83a3fcc354e65df53a0003a40f813b267e04c9f7939a42594dc7c155e879c3b908bd9e05f912e4550a29af1160b904ba0f7faede8a330ff4eac359f734a063942d673adde4d3e0274d8fd164f766ac01fb788365d052c615f687880e9000f9f0c7d0a8b54c0c2c7244e442f445ab9f8a9f2fdd11844a3b7c7b15a3a76cc4aef94ce8fd54e7fc8a34150fc0bc580d720137077271b619c8fa91fdf836619208683744095e0633a4c984d3035ae951f711d4e9679b56acd3906c1cf2f7a440dbf99cfdb81d283419976d12d9851aeb0bbd50eb1c43cd6e4bb510ee2de459b33d13c5d1538eea44c5326b5d82d31df4f3415602ff5964e49d0a8c21cae078483adb3e10400c23557a287376d9f06c5c6a4c97ae980537e3e80e676f010ee5e0b31ad7693a3b30ea04fc318151e32a14fe54aeba11f834d11bc9c2267064ad94fa382c1317f2a54b63dd3aa18abf3fbe0ae8343bb9300c4bc6e90bf599ab3029736d7b5e8147baa92b9efa5c71dea035ddd1c50fb731f868ca1bf6ff6acfef557f9816c7a2fb53b6d8226432a19429d784dfdc8866965c2190ebc17d4b27b4ca930185ab99a85567c6b892fb74dc8281f1d379db189be59017b86432617aa3fd7f985ddde2eb1b08df6836e071c62ebc75dcfb1688ee52e0995392bb543aedd04092e4de60ac11e80b29cdec3e15465d206581f30f8be669abccb8f9d43a4a39b7a15f05c878e768a58152dc3dd0535a328831945c5a8599a79d3f0195f15a079e246e397a32b578e1a0c22090a47d4402d6df42af2204031295a2502c47df6f41d521958f3157631fc428e40a7a4b61363f185370362044a85178d4c6cd4f7251f08c8902401ab047211d86042473c71991c6305cc1c90e21054d8711f59890bb77db84717510bc081f1fc53dba2e45d1584ffe25e7aa232aa1f34f29885216e6c1cb8294c4d92aa7d09c5927141c54893b90308d4e5c0cc0e2675b6dbbdc6dc33db430ada268fe382c57a323a2e7bd8e52222782460cd366c77286da2a3b280119a2595ecbff184fd7d9e1d5e1fee4fbcc947c8a4d90c7775d48372290932d9925baa048cedaf9c2e402f4d8f68432a9c807a263a74d7051646f06968b855bcfed012571bc515d1a6c001d2db2a04a8c40e3c10218bd3bdc0b1826647ac8e9c679ebcf5b6050016d1ef8a131241c1d3549b770493684f8fb81a6ea183f82efaefa8ce529b0f8ae037c2e62c966eea8a48a62888709d4a0a9471514f9399edd87c1e4db6c251be7c05a4e864c249063199220b8a469732e131184d83dbb59243d77c06aca77f7e37be54a85243d0a19ada31c1a36acce42f1c4f483ebe2a8cd8e99fd7f9a21e74840e9ed87a341630a1cc09a62df60807776fc01941c7fe6123d50b891c26c1bcebe595cb760add73da637eef12b6bac4148f7d7fedd8094d643652afd907e85b07c6555e6624969ee71c9e86b3e70998db958e850958d56478075808f167e215ab345bf1b5604578f78681cbcba5e10286ec947078e64884a86e883fb06ce87641ced9b3ab56666368b5188f4a2acfe714a8124b42f24f2f343d4c877b6d11f8bc4a17e59421d70217bccaca66597974616677b90db4429e8c9fc856d7220c18c565ff4e8fcd78633a70233ed1e1fd7e68925fe6fd8af6e1b85276c48a5d348c0470a0de2847700e1475abf22223dd2aadd2ceac615992dae380d863faaad7804743f31c556b110fbdb24d50a5763dd57d9e5e90a812decbf11c06708c84345057984119661393114cb10616433d5bb8b2b49a85a2426873ad52d4c924e76c9945d450c8ebe74f158033d19529f2028671f7c36eb53c81f112845a4ba5472e6bdddf67b93c44e5aebbdc0320977434afca1b151ab38d58ea35eadd8721e643bf39f2b8d9208756950dd9767f1a5946f98771c5cc08948bd1f913c596f00bce5e728486976f8c1155733310694c725a7d0d8d3e658710291cf313fd60f589af4fcc6191652d03b5869f88997188a00c456e28c36b51be12e17924aa17331a6c4f543d5a87f87a87a63065b7b07af3807597b1350b6b9fe48d2e3d3b3f996e7459c094219236a14be8461bcc564f1c11997592c393849813025b2e22539d3551a4382344abb8f5e6cdd35cf0d667488140c5dbd201e4600d36f63beb621ea344dfdd033f523297524800b885cdf139b74dc10271e624feca7cf8f86349d55c47a20ba5e0402de779890d1fd531ea0a23711cfd46d21449d139b842af5046e72ef97df22fa5650cdc9e226e63e2bf6930524de009574fbc5200af0d761426ca1c95259d30ff4b67ce3b153a15d82179938f30c74d0abb72db097987f2dc499a61aefe953cd01b51587c74838b6df33b1a1557fd7a90d33ae25dd13eb23ba278d400e995ca65d41b9b4c434541e5396efd89fa609b6e4102be5a501bbf8911f4df05eb96813f9e534207aaff6c6b42338d3d1b452d369195177b05166e97a0bd3ce11d116e44b7640e0b19a0350851a24d67aa38aa6b0074652811d30e9eba9e11a9b7b5c5b080960e0dc1c1130a4db2e37866a9fea71fd526a4aedfbfa61f9fc550338cb1835d440eec2b5ca5ca65bed1b47c204c8ff6f0ddecfb5b25ad75a7e1d777594fe347bd720e90a8ab3bd41e866318f60379acd9ca9a42ddb51152d6d0fb0a5d9d6a11a712e9dc256718254d83b589b1b552752f14ab16bb923e77f85a298f1c350211d10232c887fdfab2ae619519d6594547480fb293e09c3c65de5ee03c6fcc8fd0bafd8e1b026657324702d77c99a2cb2827569a7adc9003da7e7104c932c0caf06140522f79a6f2b3852435c8b9011068632182e15c683acb39e617c78a80c495f670a4b0aa067a6e2cd2225f6c3662abe1cf5f13b6e7647f38e09811e1b90b5c00304892174a5d4abd5289e9d7008cca349e8f7980b73cff2e0002d2c17bd510aa74cb0daeac9c724abd9b77490628b28006d2a1dfdab2f026c61290dccb35676b970b8a583be167a071c9032cb8bbfe4a8c3eda8589a8a7139c711179c20dee8cc375c25aa496923603335eb552aaa0e928c6abaf93da8e65e019254a71d72d58a8481ea41cbc0df13c05a6914ccbce4d68d41d7abf9770b746c4017aacd856044eb1fba5935e4bd7b4ac25b330911288b90b3c1b6320486b313f0f8876cd003d1d76302283beb34fbfa68ea911028655ff37cf1655e312967a727e93d9f96c552d69bdbbaa5700b0e64511bb05bab460e2cb46279b0bae5508fdd82c76775f9c1686057e3096dfde22933952f2c3e57eda8b1732d1e68d9124bab55202f87ebfe4379f109e58426fbafa0bac0c85107178f0a99e666766c00aa1da7dae66df05b6cdfa64fe11249059c0684c5da6311319231d256c4f86e9b255e93568b79d482e4e0ead0abf86c80ce748dac2a6ea05aa6997c76b455cdd26ba8f6927e793a91eebcd7f11b24d949b800720499a44e37ec42def0bc3f8af900220c966f8cf7c864ac1490c82894a185f2e90a1e27bd46b29c185be1b5bccaebd531fc5f7a5d6eead2b1663de76d134d7cafb6851075f53a7bd3436542509cddd742491ec37befa607c982e8e885d7b9deb46d9efcbbdf666f6ed370e7337e83d5c51a5fffdc11853e124ad3247324cd8010ab4278856ef3ee58a44620c94842832b6866281e8abb48ca854d3080c8a55c4748ce2e2977878127b7afa06f1145efbd0f6bcc82c3fdd9aa1f488e9f43880a428a25cef362c0913d89115f99b03f14540b8a435a6269e0773ca256c030e96cb8371f7921dfa7d2ba84d4317ee66f0d041a36fbf872e716bb376eb126669d40eb190717ce5940993b5471dff91cae2a3bc9ff3434aaaa4531e6706330ec9f7a4c8902186eab5c61fca2834d566acc48746f6b3936d88d46ac4d6597141d7ad59780e03a2f7e7a32eafa42de926fd5a0df118848519b017e122cd800fc716121c50a1e16b46279c9394432336238a0112dfba35f1664b03c6074456fbea4c568acd22f808517e00b5bd1d4c064b4956611e64ca2b07ac09a3c920965de3dea84ba9617ae6dde507ef36f40c00dabe08c516334214aa3f5303e886b312d271915925b5385b01d155b54db444c26a4e1c91537922bcce02bd0a0356836ebaf251db83d4af325d272ff148b04f2cb98be787dd533e602c4c768882178215a4f753dbf5f2b9e3966ad886bf5af824443e5faac29f84149dd075856ac1ae574307b1b0ded5b5e80397fce49081be84152f2b78f6cecd38d6db93651f142f249754f82fb8848898bd8bacc071fd8252ac6ece824898b0f34c0ae944edad67452b6f6f79fdd2ff476aace6e93da37163051493b22cd1da75d392283266496a7e897c6983555cc91066f9aea4cda67e5d83b8c6220ae07f98b7b89de8f26ec2a2ca81bd06d1a296fda6027db053c004a9dc219559f38121c359a3a77dd6d9c73d5a20fb475d2b7f0f3bd861074bd88b47f2308783aeafb767ffa951531219832112b05439321bdf1bc87cad30c7798f5c78b242419b0cd2c5869f528680d41a31554d334fc66cb57070c436986749cf9a69ad3c21d69611ce892d7acaf3d4d2f391b8eec069166c2d1c79f25448cd34935bd460fbfaf9c417e47f4197d0b250cfe43a9e0995d7fcc50d7e80f9c3d0f0e3fb4e5bec3b7db41ae1c0b6db21bef148a100f7ea02a789b3e4b7586ab164358400d1bbad1ad6e731da440ec5cdfdb3cb80c365c69069635fe35174dd22d9bee1c208a58cbe2d37a3a40e359e7b4c5fdf327aa49242681df029b61ad0f68744143ed0d76d014c53043376d630be24a218440f585cf76bdc7f45b256fb28deac16aabaeaf25b0c0e779bb4de376e4119973c6596d4d0393eb4023fafc575ad66217d80abcae241760cc543bb6abfad67777a6ce52769f49ca6d1aa1416ea6618548a6379cc23c01d574cb95add32f2d70e07fc20610312f6218a84ba91a2155cf45042b3450e0412c6e9166077e999b1dc18111d4a82fee4abb93264f4c707678e285ba74cf89e41cacb1e7b9dea418fad5d70f0678e7332e5b0753aa192fd8498e509ad3005ffe97d5730ec6f80f3ff0349886c7e400ee13a7f3934c5e9a4a514686cebaabf1f26543fa62ffd449bd4cb8e8274415352598199d26b7878c564fad0fafa9af724529684667ae2d7dc19694159d5880742449149ad2769d0a53fa6e481fa66c5b4bd74605460240ebf92419e48958d651e0ce1cb70104b57002a301f1ba8e51a847a6a655c3c2354e3668b0fafdc590d2b87381310c785c89ae499fa0136c63377cc3cc3614c3643502423fb012244a51e0f1e9891fe0819c8f9eb0824d150fba6dc7099bd1b5b884afba0b5308628998c287beddbdbc1d003da4404b02f2e3e87e0d7d48987d3ab68004e42cd61bcbef89633f73df00894b1505590fe6da1f55c73c03dc99fb123455168fc1913c5bbbea79a98178bb9e1c45a3ef773a96aec422467059cd2dbfb0739603dcbf1b15baaddefd1ac5389238125ad3c9bde6886e0cd388995c27c97af02a8769281532bb8370de5fe68c46b09de7d7addb9386f9e5770e0d703025fc3d8b50f98fa78ee5729d2be2d59277d546c06bf347d04bfc583c82b44ae6fc1d154a18883775a545239d6bd2b111552886000637ef07ec1281fb55ad6a826fc99af24b814d3c787a726d40bc29d35f5e62d49155e093e92665e8b298d616d6581830a6f1f257082910f67011f706871b0f7c65b63706039cfbb80c86c623d12d85f86a99ac59ddbbcece10ecd8718c3912a615d954434730eb423b6e6df0f274b8f988ba80ece1c2bd506c819c527abff634304a529f771914c7f306ce4c738b96836d1737fb5ca2c12e112272f97a467146d206f82e555cc0dc4f22b2359b01d1d15f07ac60559434de4cdddfb21ee17e86a3489d413291651cf1a3a96d9599b78bb2550f54ac9a9428cb36cc43482e7a18863893075f35e8b43f528cb03e56680daf6b136057249c229cc5e2658c286723e935bb4eed99b8e18cdd24f3368d6f17db8d3de35deee7e2b89adf7546c6dd7331cf93f73199a897ec96d8b438a35aa360fb48c09b5c3db0b986fd7affe7e0754af392472420933591811dcafe71488d0c13c30bb779ee0b692f97134826799b48a4e4928cd77444cd5eb916c01bc65037ad0d28f5b30542a6e0e6945f846355f0858f937fe2688a561fbf4c7f0804cbfb53e2285a66f5c285df8709ef2ce1f482aea77004d5f0fbc023feff8205c98be3eb08da34deb42b101d21cf2b507b19971e7b412e07f412424bdb4644b99920cd808d4081e09f486c50008c8fd66cb679e9e352ac83c6d9d6a7b88b91ca08e8dbfed7d3e5670b169f82ef69bf1790faf39bc82944441eb2229443dc0fc31df83b1a610421e6dc2e0c1e62db3bfa1b8c8bb44d03ed19bfa36fa08ff1ebe53476d529afeb1258f2d79e44096dc1c761efd3a4ba80f7e51c6fe916cc39777b0f3ed1e7f302d28843120751126ac01d22af4d51266f9f6c71252586ed17b2ef4e128661a8e628e81927a780ddb44c326ad8b7706940972e3656464681d60fab452995aa91867a95442e2428f07ec98fd03c36205796441c72b9199baf2487d7257a77dea6f0c81cea1efe12190823a297ce8e9174447e655980025d9102b4dab00ca8029803828e9463714987e9f28b88b092ea522ebee55646df57ae50a8e7bf66f1a6ce84caf5cc9eecfb973387876af5d918c66667ab5a2ab72b55aad56ab0c053e3001124c9d24a11c8207dc134699694f18a99e33467bb4285b7ab280d292f59c55b2196433c09e479b5cdfa671a8a8fe0af4a673fd0044c0964aa552d642a7a2e7faf60362f3a843cd5a0e9e352d0cb9c873fdfe5e085519ad3e8c0ded6112a0af9f813473f53d1c6a9082c214b0ff96824b67ba3b07b4b528b49da0ed4ec488417bcf0e3ba8ee6e28ad1f8d4a21713a9d4e27d7594f277ad38242c23ca5b613941f738a69463d9927d43f8e2f92e36ffc1152f66db2d03ada42104b584f19e806d84b70f60fe21ccd84894d2de888052b284e78850fcc283943409dc19f1a4aeb47f374f374f3b4064605815bf68d033cd6d3a350a7d5e9847a50043feaa84b2cf8a85361e37415bd23fb583e43bdc604a45ce824a53aaa275baaa271ac11a7d2a9742a9d4aa55429554a59371d6604ac8e6c290823cc3aaa27580956829dcc9379324f66e9733aa15c44b3af3e999b5072564f39cb6a939cb172c6b2716eba687454cb45a37d8792b999b33ea1941051aaa38a84118d535dd0a4b42a31513af51278aca6932989a949124fa5ca1493140a8993a955786cd3649aa6699aa6890ab98d72e63deb46398f9a814cbf716d4eabd75aaf9a75a1200e59ae251efbe4aa61932e76c9c5fedbdea110c7350ef71b5447ef008f7daa3354c794aeee3bb059d6d689b6f45dec57807779c408482137676bbc7c3e7ccbb217176d7b97cf87371e1b966ddbe7a3be63b77faab53ad8429b36b5d6bd7aed3a0781b0fffd7c5455d82917cd4e3da99fc515b2b12ea22eb6fd04d4202ecad191f71e8ef5699f70e6715c2844c3569285ad04e5ee313630590ded6573e170ae69c9fd17e4812cf7f3bccfe6b2805a3accb96cb9ffbe784d613da1562383b1311505ea36425e9b187bfd1ef879b43171bb6e0a31303d334375b4d75aabbb3bc9dd281795b8d85e847e909b5ac1659be53a44fd7380b9f31ae522df816d0b8e2b8c36b9ff5eafabc0e2531dfded80faad64485fc93240369b3d1c73c8360c511dfdde5ef7096573fdb14fb995342ad7efb051a715ee4c1d84c12794abd2f47763af4e7f4a99fbc6feed72efbe9b7c0c837528abb18b40dcfdccf1f716d7bea163efc7ce32d4bad8dfb5eb0b751a4586176aa07b4ef56acb4a2cf6d8b1265d7a4cb8d8272f3cf5a94d2efa76c2851054e077d511e6700f70906d581f577afe640fbd1483954b57185b959bfee540ba713d3ef8e91923c949f6ec2055452c872796c353258707c6f231e9363da57ffd8fc4f07d7d215f0d8b2ce950487d0f8ba8f0f58bc8fcf747b24ddbba63e2278ae7ccd30ad4ff5e067fef65f87e263452ff7b2f34b24448fdeffd29c97e9fdddd5bc843a11cca703341ea5f3a134a406d9fd3ecb3d2b4aa06098382c39c6dbe4e2dece1a2fd2db4b1b1168af6c5fc0712f9de41af5b72e36760bea77882298b05e57ccde022ca9a8295edd740c47e11eba2fbf291c363c5459afbaca32095c68e1c6d0569d934cb260778e31d9c99e929a4c0fdad03dcdf4db0cde78d1998bf37c01c3f03e27819b0be0aa09fdaa3379b3f873f9918becff142becf51fffb2d14e23d8eb088df00bf9f01bd97012949851ae0fd14c0970f812e6f03c48f02d8f230208bcbb764a04c90eff3fc930952a98ece0974f0ebb0bcf73dfc36cebc8fa505bbbcdc4ba45f2edacf1a8a7ea2b4798db2b11800a64eb84865ca6ac558ad259e0cd19d83d56ab55aadba79ba79ba7b6c02374984deb464fb5d6a1d17f5db16fc21b126c7ac57eaea64baae83f9973f42b24f810abaaeaea5e5640b2664fc6d1deb74090995ecfd0bc8b9f4123c723598c02eff52436fbeb78f4347440c407164686154f384c65c4464287d2009a80efb14d0f102348e179620896bc7d53c5da44b2fd49c85447a093cd6d0588d0bcd43fbfc9cc3411325b4d8b7df5f041a0938ca684f73f61ca8437224eebbdf4092236d4fc151874c3f03857889c47d07f26043da72b0397b19208dca5938a4afe4ac86a30e325a18647b9a856012376a2f030444bbc835793c926b9732b7810ec488084a6ba5f52d485a92fd0acad042b24f69ade190969c847dda057da7d982b4d2b8a05624a55ced5330071086964cbf82e3915cedcb0001651b0e69c9f447b9268ff44a1eeb83fd4d29a529501d4d4198af9b8221aac3bfc1233f5398703fd0138609a4034062682da0b580b385120d601a181f68c1870520100008946865efb377f086cede8534f4779eb36fd086a63ab2c781cb43e89517bc07fda0f9862308651c42b9439a7d8fea81a3f6d9770bb0ef3d2b7bdffdbd99e70e007df70d8ee0d87d7dff60b0efbdd79f03b6bfdfe0fd0ef4befb7bb8078e1e36d5d1dffd0547cf7d25d3ef72e0f290fa8452a6bf81230e9dfd9b086f9fc640ca94323e3249c05ad0334612d32906550f4b47474747472706550b24113e50653153961267eeaf89c0b52753161317e4f6c99455032e320b99b29a7842ce3e205a1e472044153d38f3900cbc0082199187e8c092471cc4f82204833ce29082811879c4010831b23cdee0050e0800452b8f37942d20d78a298f0eb062e280d02bb981d81e16dd41b3168efefe01f170d421fb6b610e9e3d6043e7fe0e06a483af8ee7e9709f8e65d1c9435a32bda14ec8f5b5c6a1a3966bde3e1cbb3f18b2f770a454c74859395092b5d7de7e8fea169481a18bac7d06d2e0bf7d0f1f42af5cb9721dfc7cf86f4a70103b9d70023b547504a234fe5b0f018f14d6e51e02aeb5d650f5d2c8fee30a44da895661fb2a7ab3a23738a0a37a6a1d644fc23f95bd8fc8fe4d842573a093da85c77a22129e4ea1ffdc59602245e80dedeeb73614818b0fa03afc7fd424b8305469bc55aa5a43f5b9aeac26dc7be9d78d55e5d6e305ac5f944a71d186e18843a5f435703c3264cbdaa843ceca3ce2003648ffd22f02ed44efa06f7fecdea172a22c6170e90aa30da928446f2c15d12c14e9a8004de3da8f0208c11a1885a72f7a0d2acaa1a2f708d5110ae10fda382cf40e2f7bb7654d569a0ab6051bb5b9b2567f6cf2739315d54ad0513bb1a299781231df65600e8b754401ed47963c8a2211780e15dd407f284175f8dfd04864ef23a8e83c4de3ef4fa464b141f6afe1c8c58463a3348b42d8ac3070cdddfbe7c3e5c3c0fd1fcb37e8997e3eda0898f694aae4978b40551ae6a2cd7bff5ec452ea5c6afc0bbd5901c5e92de80e7fef22fb8fde82dbdc97848dfbb6f3e66190bab2cf077d0129155dbe5d2e3b2e614b0152f31def4be048112a244a6041154bb6008344298d8b0b38deefbe7e2fdc87f917b0738f7a419a710d5eae6123b43b4ee37fada9f3b5f12fcfb9c8e55fc2b1062f5fd09ac822e0bbf33ddce5e5c5e5fd6d8094d2bc84ed7279ff8070d925c44fbaa87b91cbbddfdf038ee41bb64be712ca00c1df3d0ebb30045e6e292eba0ff0d8ae1690a3e2158d38e4ce52f1fe07522adeb05d2efa7ba0357d2f7c2fd87cbbb0a5ec689f8f6cc73f1f5c68c9b15d0b209f14c3f9c8de922e8aa23ff7f7b278150ce50669ee14bd216398b9319a9655adbbb5d632900be1441c71b1ce926c741fb223213b3d0309bd4125fb370a59966553aa609ab7d77ec336326b3d6fdbb66ddbac73313be487c04c9ffe494509780a996a5a19f856d03b7cddf3de36ffb6988dc3f7866328f3f03ad47950e7317274dbb66da3924277e3be33ded304c4fc18ca295005902229e6c71b09206d48313fe64001acb14a53cafefd03dc041efb741dda024327d3cf5a6b4375c6b360535205bb5c6bad19d83906d4890997749f81fe7ef7c1b07df6dc07a4fb2c1c411a1030e869ee9e9f55debefbeb1e08a4dbf7007d530cfa96ef0147320808e8efbd7245d3c4fac15073bff741a05eb9d24e77549b6b9665ef0352f3a8830fa957ac00f152eed0867e1cb80cfa5a330874aaa3fef7bde01904e6e0d5bbdf9e5ce49e1b6caaa33ee87ba1f3f659d6dfa9da242e92e1c2219debdbd0b93ed8d9eeb8a88649c4bcbf35b968f33c0e1c6d92ec6f4917f9db9d6a4fd9161382300aa1ce12ed79e8b2ceb2ceb2b0a9e01ede1a0f198fe62e0377d87e5bfb1d8e26021efb6489818aa1dd5462666262ba3ba60ccce10dd71e9f27729f31542caa86db78718e7278ce29a4193116ceb60728493275c2832b8f3653273ce820fba06359670b3c5b3f3323d337c0a0e74c2864c353f8c24d2118981aaf9ac3f313f3e5f048e920e0d14f5a14188c5bac141729d8f3ee3f87b1d728783c727bb092a9931eaae4d1963d48c9e191d27e24cce17949f9be1c1e290d043cfac94f7ef2939f7278a4b848ca2b87e7cce179b517393c5372785e3695ebe352a984c4c33987470afd3c87e7c5497191e61c9e9f7cb9cfe1f9c9e1f9c9393c537c445d8a8ffce434f569cee1c9e139a7740ecf99c3f372e5f0fc6c5f0ecf4f0e4fcb4f393cae1572787e6ccaaabe6636db70244166b9e0e3426f6a288a93120bfd211921455ea64c6191b890db40192161915b0412171e21751798736b7190a4246de02d02c99120398345da403ac504a4cd7a1b97791bd7711cc76d5cb7719ab771dde66d5cc7795c57bd6997b1f44a05240eacac17f050227520b76d9bc6321ec9d977e6366edb9edbb68de3386e733561448cb481333e906ef5ba0baed2745f0e2c6297180145d2811383c415a1679074a0559036940dc8ed8be87097006391b6d78152015b91b670894cff917cbb22c2608555a82889e35e071d65ec40e242ea3c46188ee336ab695ace5a38922067e00676154e90ba343a0b244d66e84c3712140a1299f6f0a0d57385132dcac862eb239ded7978d2f6145c623551dbd7420a046c336b33b0b3f5415f318473407b92eaf14952c33567bfdb6a56ab7f6fd75a6d38a466ee6f38926b7d9addd18e366b35f78f35df7c3bdf70d45ed3c62fcb86d4dcfd0d47bab79909770624fb0e471aea739586fa9c7dcfc337d334fa691f90ecb570cc401aea67df5ffd0ca4c13657535e9aa9bdb406539659ca23479d2ce187ba73aecafe355cd60e5079e4609a07d87710cb9dbd3f215e22757fe94772a4eefd39fbdb06d255125d482b0d919cd5df42ca3d0d3878cec21c6ab65f23d30f8601641b26410291b5d5eb952b38f5476badb5a133bd7285c4d55fe1e03909eee9270303485cf8768a15fdf24829a5edf9ad204b574d75d02e73ad6973b9b6b4d09b6e6361a1371cf77df466eb3cd0bdf426bb2010bdb15ed7d19bfa711cbd71966dd334ff4b9beaa0bf6d1a977596f35ca43f56fb2b179babb55ef79a7e3fa5d42b2fe7a276a13abaa90efa56e06e2b703ffd23b53d085b6f9bb6694d459b59d675da5d63f322ae34fddc6faf85d9679d3d20aba0cdbefec8427777b0014e7bb89815d14a70bf75e1e1490fa7273dd0e0490f4c9ef410c5cf931e7c7c9e202991487982e487872748aa3c4162e5c90e3d3ce961ca931d4eb7cbf4c90e4650b079c05ea64f7648a2678c2979f4b29371e9e75d100b4b2de2d636737dea3deab2692a8bc55dbf59f4c6e6da5e606e6c2736df9ae1ac6661972e5696f3a8afb3a43dc481196a808140a00e05aa2f545d564b569d02cbb5d65a6bf5c95c383e8c03e00c2ed6d7c01a5cac191872b17efd0e39172b14181583eeda3ea81e2c6ac0a2e208561052393cb12a30db83ec4f473ebec5b874855577e93cfc7596d4f6c194e41fa48e388c43a12d7713f807bd0165ff2054c2f0e207276e6b7f4c4d374319a4390bd5112589ac1f1d05b6216665f1836946921d11c06899adde3adcbf2ed49a5c9f7e3e3cf16b32e53e54475f6353473d284dff70d103b4ede97375843970033d2af66b20472d159bb26a1e671b0e1181978714e1b2cd361c5224bb65d2a6cc886eda505aa3ed4ec2f8a16d7c139886be1857582a26994aa5da5a75e4652fcc61337549174f961aef41e0d37549dfe1925d5da12a7e5a3eac26a5ea922dc53613b08df045054a69a1d3c504446eaabc9539bab38e32cec606aba3aeac300bd338285d5947ddd99d2db56435215bb333ffca4a3039cb23a452a95477aaa36b42a5522a94159c52a5525a944bba6cc8b5cc8ffcba89ea2ac95edaeeaeae530a0af0c8b99a7491f65b8d17b15c25af538aabfb92537c678af9bae4eb7549d3345f2e97141f75e7e97ab95ca76be7921b10f89a948497741105f0ee8037898bfe31e03dfd8061c28e1576a58beec3ebfa70c4ebf5baa49378bc64b37c9ad8b07b390f9fe9018fddd9b19c47c9031e419cab9ee74c2853273f55cca8d05e3799729e2e76aff305225fe794cec1794e79d1f3c52afd04b87b75a78b53749a444f282a968bdae7924d7cb4b9507594bdbc521d65a60b8acba7cceea9b27ba9ec91d93379a7cecc57777a75a697cb74992ed3e566bf2d33371b87334df30a538ab2c9c0a345351978acad54195c875bbb41348dd938d919744756468754e8c8a3f27abd5edab69191fd472f569b7049bed04922e1238d741a7f8e89bb0a35d1523ed93599a32f8444a6ae25e15ad8153a3fd2e56a33cccc6476cd4cd9294b62023c66a69c99966c334fd6d18df757d550ca86591797bc64ab8ebab22ccb541eafeaa6422117c35bb8c536587fa9d4993a53e78b0a7d5dd277b86477371ab87ff45ea12c536d5f6cae4cd5381b2c336d5ff428634196a93658e3d8b2776466c6821e655894b018152c6065e378679875e495910614548860868fbe24553ed377a242475d8984d88dec06996afb6273d9567732e184e072577259577a0967affd86b94c9dfc08a1855f0abc24d5e1f774c9eb43abd522e30ae16aa5548e24c584ea4bf5b7d335a562c2c58e554719c9bfcd4fe522fa999cc747dadb5badd59eaab33c599cebc6732ef029c99f3b71fccccbf09fe3659879303482e3673e47686489101c3ff37fc9990f55b0f2649d3c7a0380970a569eac8f09175debca8e955d93cbe56ab1cc7b42a554a5abe53a5da72ae56276772e794dce438a1684e6675c38ae96c15c3466afec9555719177c9ecc5b9bab254a2e4b141ea4b75e7999ae2fab0fdd034fe37409d4b5e155cb23b4f0d088dbc415cf22a41471f59697ca023ef759dd0fb046592677e067cbd88781db169a47683b8a446360e67f60eb7e50da247560a532339b3715c55d651a692a24799132a3346c589ce60d93f3b435547591969d8e0d568bc666666b438b570652c74517465374677d278fd91dd8dc6ab8248964c9dfc94eda5bba3916103a64e7e403a69b934303ef2922e7a784d57908071fc8dbf5f2a954a8158d0669c67ea4c9d297b9ee7999932254f30ed31939cfe9f99fdc7cccc505cc4e2df4d71510d93b8f1591217b7cce5a26b0fc5455ab8c536d813f0d895998b529651288dbf10468e084a20bd97f7b2ada6f1e7388c5db6c5b9a8b4b2d0228a1088d0fd7a01610c31bc7075135737b96401a2c01dab2b4b1c3870e0c08103474bc1015ed33da152aa92650620c825dbd59dedb5cbe572d1a6dce7a33957b34e3280d086686945b464d03acff3ec06914de3cf71a1508e1cf906151009fa21fb8380000d012a4206d9ebd5dd35f8482d6cf0038ae3aa1f978ba4f82807bdb19aa6691aaa8e02900a854a555996aceeefbd4ee3eb8fec6e345e1f49d656aba9c09d842dbac85d1e2fe9fa69993eac26a5aabbdf4cc037b4ae2eb42d27602da5a9eaa8f3e74acc32353070995bad1679492b78b42ddbb22e8da43724cd073a029114843522b2c3403365d74e1a2a3b087a2178258f5db63fd6d5d2345223ffbf541d75a5da7da9ce148edda9e4388c6dab2b35d2a56a9cee54d9964b237f5aa60f4b55de268d73754077dc29bc613f4ae038dde52a1b8db2bb3757cbbdf7924ed24010e9aa23908392a0816be425cca481c70b221b0d57371aaace2058499b0b6f2eeca01d175dd009a40475c9541d65af17eb55be547d06a64eb29092c7bbfd98bd5c449dfcc04af6bf3b2e32dd241a18f8f3168e5a2bfb6b641d01e0921a794d976c291dc3dce972b19b80471009224dd3cc5e1c875d64ed4e5bc5d7ac665badd3461e3353667deda1aa46d6d12d432aeca538d78b83e11b0b9534522335f203efcf6d5df0fab8e80f022feb36016f7955e035511d57884b1e715e224e0b22738497ac344cc07fc94ae399b6755324642dbc649b4c90b3b07bc3954a901f671e6bcceecaad1ba33bbbb2713eb27774671dd956a5e9c6e891e5a2bbf2231be74bf50ece5569b82f9ac65324a89d408dfb82cb1a1174c70f5a113cddbdbdb093e2bed082d06090fdc78f27fb77209263c959a82d018ff79297a4d2aded6828d094bcb41770a12569d59116440b9f0f33f078419704ad80e27c24a805d91f940444824e1a092253205253f2918da3bd00089a4983c1476a2731b2bff669a412f078498dcc97ecd6b44b5e924aab06394051d88b8b0bfe23a25b80024e011765c00254b4810d50110d549c810625cce02211e814711a7f2275e4855d6ad2455e72d1beb8b8608c5d5c6c6c2d7ba791a8a854fb94a892559265c9611e335baed35f1da7695ab9536e30da56f60df7fe9d841e758f8d46f647ed300556a59a894ea17ca03adc7f70014a05a716e902a337ddfb3712e8c89ff08661582903d44fab2ccbb2cbe0961822b79536a3611700de7b145ebae851dc4045bd0415532eb6898a4b986ac9c2f805ff118ee3dce5bb6c61e16779195ebe2534d2f22fcf121a5922a42534f27dcbbf7c91224b847cdff2f89380bf4c9d6cc104245442bd04d326b0c7a237b45ba6eb3cfdd57258d93b8d4445a54a54c92ac9b2e4308f992dd7e9afad92ac769393dde54ee96525b37fe925112ffb7bd9c4518e92c251dcbb0fa71f9aa6798cae029245dab07d0d65dafb9e30a1287bca96028fdd2a5bad033c76abd5dd9d459496165db484d054babb9b9465d92aa178524631457945b75aad563795aebb9fe8a602051765abbb915042f1a48c628ad6154da5bbbb2c9b94ad128a27651453b4aee86ec2325be50f58cb6cb55a2d2adddd65ab84e24919c514e515dd6ab55a54babbbbcb5609c593328a29cab2b388d2d2a28b56aba9747737ac9bb0ccd275facb6165a57156975e8eddca224a4b8b2e5a42e8ee0d572adddd4dcab2ec2394ad128a27651453945774abd56a75735e52a9304740ae812d2a2b3b5789f40e6f27fadb896e9c8d06ab155dad56bda2dddd47d0c0e88ea2a17021b473d47555766b4e04937621dabc746666a669933133a342d3d6a2d06eb7c2898a7cb282d56ab55aad566dae56abd56ab55ad53859c24afb61c273e9cccccc0c6d6a6d975c503f7701932add44e92b17f5ab5addd5361a1deb26581f9c352eb868390ee310ad36e6a22d390ffb3a4bdcc64ad65463e322eb15a33735dbb7565cd419ab8e6caad2d8cf527564e36dccdbcfca3a0aa55ca956caec2a76ca795a2b3676dad8d9ddd56c59f3345b2fd839e5550566868baa19b02a53ceeed7e93be7eb9c625ed759471cc976584f17eb1433b27dfb0e04aeafd38c2a20b0c27ec016f672d17d78c552f60c21523ea490a46cccc654a992d550aa65c2456bb6a0b868ad69325b2ae761bf8236d54eb0a97cda58b531f36fccaa605db46128135eab4258676654e83e1b8db3bdb6566c4c8b6263a5ce818d592b3656324dd3a49e1605ffb5b5662517ad8d592b3a78acb1ac6463f53bc3c89e8d71641d75aa64e3b9e9abe9a2ee5ca1984c26131552a0983c067b9d3b70994ca44f994ab15865c952a14e26138be4bca6e2e4ce3ab2b1f36409efdb988df5e8588d8bd6e21accd96a6b7692338d4656bf47035cd45fff471d51ece1186aea49baab9ba09be0a6232e5d61fc9c39f570c4fe34d3c2185cbac2cd42b95619fbdf53191bca54a0df5f06ff2f34121a5922a4dfdfe529a9fe0c75d4247dd90d6fdfe4f6750b476e090643b5daf07b92a437267a435525cbd66f808bb5c70fbbbd7c7db96668b1cc3e352aa52a616acc504733d42dac11abad26e7514929356c3d45066a7d0a5ca07ed7ef9acd50473d2a977d2fb0e41e2cb159226db2a56872fbb1c910cca424e5a2157d35c9b593e4da4c6c796c15a8db66f0ba8636a55425cbec276c0d2ef531d8a64a53bfa53e4b4de5fa1d0516818b95be60c0e8ee28dab46d5b0d3bb555eb22265a55a6e88df73235cf5afd8e69da9329d2c48542212fa25319290b9b94c93499cc7b192efe2f34f23dfe1ebf114fd3342d0b478cb3ef54f65aa6697f35cd0bbf907e41ca4eb9580436b2247b23f8efe7432606fcf785e05066fbefeddfcf42212ca14c0cdfdb97d942215ff8a3d2685fdfcb5e7bafb32eda9cbbf5f381bda7a42e1472bfc8f73794d99ee529c97e3241f0f7f4ebbe88fdfb5d2804771e0665b66f15e982325b1884542212dbb66ddbb60edc38ae053fcbe663080c9db9970025b9fc06f677a0d6754aeb3e9920f7254049d788fd8b4323b503b7ece27252a0d268bf81596e18a6993e170aa98f1f6f5aab4a96d9cada7fe0ed54a5d14c61932e6a24ad3442eacf50695e59d3b15f3f739cc6f5bf5e5f86be0d65fc6d988f78ff18d5e001c1b528b4396b7fb35f4336f34214be0fa42dd191fc8158bbe112cf4299dac3df9ee0d21528a594524a29a555c7fa11b8c6452eb8c8b6bb60e322ce459a80dc5dd373e507353535b4654aa97aa8d8a2870a957767ca61daf2272e9f15263d3e4ff4f83c71038dee74db9d9d1f48fac30e92dbed9f0fafb55a6bb34cd3c46ddb380eec3a0fa3ddebea616f716fb77feeddd4566bb34c6b70fb7c70bdb13817f7b634e67c501d36d321e071854c5de4dc87b84d062db5cbd52d3d061eb921e03134058f5c0b018f5ca6994682dca10f2b0c25499068428466abb62bafabea2bdbab8c62edc7c8acd8b55dde0215dd4b1f2364c1bfe84a7648a8e8df850d1bfde463c46c6d6f2b86eaa85d215f65ff0669aebd6a1585d2dd8dfde400cf6eaaddae3ebb5f5d87a8a67e55938b6aa838440bfdf2b6b1ac8794c762fe640f34797497bbdac69c0b3cbacba5f8cabda034f9c6954002125ec5954ce9f6cae226aae35585eae8978bde64ffb8a842c9a38d8d4db5c9002cacdddd7db7ed7380932d66d053d145eeaad1420d28f4b2d2b84bf4b28e2889f41dbe62a1ee1b9c3143a327f9875cd449c035531613aa649b69cf0e2d681bb23c56d30f43541208da29a0a2ec291d6d8ac83e041e9d74f236ed5a592c254992246daa4dd75a6bedc26aedc7b2f5ddd5d425bacd43c063abaa89ea1082eaf07aaa3455052da2589505bdc3df87c06335d5eeeeb6e9cf2dd4b848450fd11664b2db3c8ad94df40667ff9a84de9c2a1174e4ae7a442623fb935487fbe02727c385e857bb4c9cbbfa957b6b95f72b564755084ae34f047744f6aa4436a9008f35666336d6e40bdd3b5447f74dd65117da6cda8b79b4a9a66ab2c9808d8d8d4dad196af303fc70e90aa36672691934ca5661592ea82a58a8c611d23bdc56d1230cd8466920910f501dfe18a030218d4302ba63a469703143771378b42c16bd6931a154d389856299582613cb5432916dabd89765d51faec66cc9e539b05a7131e62527ebe8f40266a64ad32e6075398f960ad737bdcd368d43b14c75e43af73d93676a31b198584c266cd2f1914b4b383a122ce1e84cac9adcd2cb7ba552c8ac61c298a4cb875e6c38e2fae3a350686b600f26acad9870268ff5b3ef33d491437129fe93fd470a83e2a36aa5c6dc8c5916aa8e5c52aa3a7a295966cb654f3bc5beea28d4dd33340f7d75a36142e901162d978f99fd63f0c73c8e9701e66f84466e3ccce3088d2c1172e361de08a5fe3770b0621e26858f7921297c8c0a9fc2772844e661c28aff6fe0f823df391ee68be0f8983f82317e0cf338f08760b864aca18eadadafae18623ec7cb1073e33f34f27fe3ffc61bc9f1314f6f803531350f5ab3d2d8160be671fcd82516cc0b897998b0c892fe22373ee63b1402f338c222381e46083cd65886038cc9ceac95c980590c4cc1c56587d548a42ccac51ab328971259472fa111987f31c1bcb864b092eb05ac677d153942aa2d13cbc79acec32debe5b9e7e8c8e5b970ecd09aac26751dbd7415971f3b661e41475dea29527eaeb0024a4b09264fb865d5910cf7311fcac480c2c3bc0c363e263412f33662dec61b817914fe0bc790c77db3bc1bda007b8094654d189665b99802dc5d62954aa552778d70c968599645e5c54533b91c69f11c3d7cad6f892fd549d1955f4a93a2dc9e66af4e8a1e7563a4b257e378afd72be5aa54e3b88fe94ef4c8b148654ba4dc0957b9a9b3a67dc2b1701f6b85655928dcc75ef1041d654c54a5aa54756f1b2cf644a0d3a8340cd88c7a582a352300000000f3160000200c0c078402591686591088f60114800e6a88586a4c3c92c6824194a330888228c618a38c310800438c3142554402667d604954a621a05ba55d47024fe0bd834a78f4ed813b967240efe7a0bfa5acee0aa4b9339945086debc0f88526843cdf21f680dc077d784de6a06187945198d09ca198386be357674d082b6cbb8775eaef28a8cfdacf67bc7998cc233ab221ec913bcea8bd44ba2a342855d0ff5728167484796c1dd8710d712a158652be10eab3c97e9bab0587be765656a2977f32132e31e4edb0ee971763282393c8e965d63ee84d4b77c29ec25e1ac1020afd2869b8bd02da20975b0420aaf99ca5c1c466ec6fa014a4e1efcf638976ddbce173a1784d3e3fbd000fb2719e0a99ce06e86e27bda0ef3626685d8fa0df7776191f14dd8f07ad0b0976a61e8eaffbbd61a758dd9a28964cbaea0d9f8b0516c5b78f1def41dfcb9bfcf04f63b2e6729df6d5b33f8b08e1f059e24bb448ceff17407f113cb57824814e53488e2003d419763e4004f433b41ca0774d6d5b03968180e20487cff47325e7a5c5e71cf986af55a403c717e25f2e6dd977729fc3e7c132041f76e8d8bfc2d3efdaa2d7c8c374e52f83b04330670159dd495c08081dadb30e492c98f7a07be584c7f2e1f386b5d3a63d9ade1fbec902bc757800c7c532c93d2017461da4ce3baa3b1667072f480562a5596eb110940f00f34dbdfd02596b9a74f3071d7b593fa526c4162dd687cfa6b7cc61ef757cf8bcaf35d1228e0551f9854d99a05532929dd91715497b4b70313501502849e709bdf02dd19b841f96912125239442efe9485068bfdc8a100f0f565610b57c76e5f9bf3ab0d9d48b87cb749b18bffc5a4ea8601881821c6a37a2437c36d5fa913dda1fdc845fead8bcb16af0c38c5c4dbcc1f5177a9bbf0f0df13954b570340eaa3fd7073616a47808645658c5253bad855c0beabf2a3f4b2fe3e74b24d5109f6b7cd6f55c72ae519a9c2de7a3a81331a2213eaff0c78af2e9b0e89805cd882c92f5b8add4bd8b4ff7aa26ad4d3a1d3a133d45475c4b2cc63a4d14eb23763a6dcb58667fdbde1ee04f2a477b729156d288b77b1de27339195bed6811b4213e8b98e194ebe9b942df55e2a7437c0e0d164186f85cbf38a00342c74cc413b919ab430e58881616d8638a9ab726a70207ab89f56aa91af1f95c2daed8eeb94103249bd04cecc4a47b96ec99646dcb6c7a2195b8b1d557daa2fe3275d45cbc3dc9732fdec22035e347b72e70136388c47c7a1a820c095f71030131e2f3abc16acfa4926c34e8cf168e6df4a944ce47eb110623d18e806258882ea4e19233bf60cf0295cd312f68de9c15ab7b35fc28f2e9b94f44812490363cb602195017dbd07c3f60b990ba9b1eae5ab1fc14fe6846c35cb19a9e743bf11995bc65f7857018ef2f0840b22e10894c6bce423949dba489a1556b228b4ea9e8ee5ed87c592407214f68a32db2b4aa7283ae0c94969f171eea5fa8b4dd09fd59d95f0de7594b1e1f73eaa24a7caea8b1b5d02729e734c0a60ab8db20c665a062bd5b7d9298791f253eff91609b3b07f079feb43281129fd1b1e9d2a64eebea44f28c964989378b00249afe5c05c75998c700fe21f1b988302be685c9acf7fd725ded251e355a83a8105a12ab4a5d4cfb1548948c3e1e5dc0694a0e9fa592aba0f8a9cc23030387dfde8915f6e1b9ef3fc5c4e7603f2b183ab97c020db195595f0ed58a5e09afdb4d3b0576151e93a2b3c69acaeb1fa8474850a348be6d83f3cadc15a6ce5492a0875e5ea1976af2a0c37355602d6efa9290d1a417b985187742bc6ec0bf5cdf87b059816d8263103ea5069e2d7e4c79726a6490e94181dea705c82a79ac31e49ddf304a3729872fb1740f87c200994e20ffd682aee427fd67ac42b73711d0e20909bf0d3d3c7cc9c9194bf418444a16c16056ffaa7ace0f6ae1adba122ee9950268c56c5951f944e3ee6f2e78a4289631d6bfb796387efdd5aef394aa6bf8a381d0a1bf39a05a6840abf7785cef21f377654e61c2d94f130c3a70bc47a35c2c8639448abd993349a8e3bad876f9d516d0b49a4812972a05af26b0d7257020a46ce0b57f012952929822449c15db35e3580ccddba5e20c533fbe2e04da9f0e3afc9e62b97c14f4084bd1b1cc572437da96ef5e659caff6fa1e71cfac857b740dedc7991a32e30bda91f482e5e6c064447cb5cdca4533fd0d142bf0612ec983e2339b38f381762096347edd921a9573f9d2764d2a1bdba6f4a6fc02d149e59625737cd29d0e1826b527be7ab5af9adc2bd4fa45805be433ff80a4577bcc1746fa39aa9c352d721d4f9e6f905b47c509e564ce6e12c71551625dc873192a4f242dcb93522da4bcf2543fa0aa751487748ec24022cd03879fdcfd8bf5e2189361230521c8cc52e6e435aff6ac545692c3f9bb18120ee5d516dafbfe4bc72bea2d2eb82a92e3d596548bfed784a87dbe52b764f158b9c3155167b62d8bd892fc810d5a09c56cba20919d6bcfcd7f1fe0d21e1ea24b4ecc9439a0f629b39f5f610a07c1ab5d18198be85d6de256ef7248bb77b5e77195bf53823c07f1e87fe32c841bed161672bfd98fb7ee6a6f89664a32475d45ee6a4b40a6e339cbac8de599bd617f6662ef833440dc717c155aa679782774f8a19337d94d5a13846b2a083300a027a3565c9ff7b33949b01bffe352d689cbcc1a0439bf776440da8228f0cdab4fb5cdef4d876a78c01d5f73eb4e4f6a0890de25f3c2453a996894132d5be608817d6e90386331e93b1ee9ec1c19aeae64e43b99f0e5ce8323042aa2575a0cd7f4bd4728067e7991e9c9fa8a8c5f1da8d7ad0f63d4e415e33ae9b78944024fa43b96cd0700695e24556a8a2159f2c1115a1aa65e7fa101c33a504798832426a246dad472da4f67d94109dd3a915e02a88d88f73c901e08f6c004f5a4b835d6a8e3d5c6ad540a09310e11be653972c7fde71229696fc1b3688ac07767a43d3e10268f20af8cfbd82720c71daf7bc90baafdcc7711fde05a3887c2098a937c801fb2c7d6a1cf9a43fd88bf4e472a1f939608b7a57791274048e93abf60e4bb16a9659c1ac48fd256d76050c6684d3f5d0db0418c9bbf1c5711047ad1ff848f73d14920199b7036c988cd1a4581d930efe8282b65e970eb50ef39f45d421a290b7eda4eab448c09bfbeedca11b8eefb6a13d91de810f46c72e795de5293439f6e12c0917ea03ad075f5033094ed0a02ea4ba70fb4877fd0cd2f76c9d2d236322f46f2d4e88677d6b609d07ed4aa92dd47b01483eb9ee206bbf92184f5a851db419d44702fbd59f6e420cd9ec78dea75d661f2365069afc378081c06354011293ec9f92ad10e101d9f543837cd0790c327e5e38d0998c7c02f32ec4cff0654c4ef749f58f582686e5c5d8b6069938b550000110ade0c78c0aa99a743b52dcb9ded1b943c56af2e64a2e59159edd7ddc9ae4c51a8dfee10bb3fd0079bc39ad9671f3a4e2e0fd94f5d8afc2dcf512ff2e2be0fcc27437c83638fe6e3792ab14b91be9709a9cfb0aaac1dfe2204743068c2b6d4797e52c7eb9a0b52e547231a58b4a1168370973808b5c49ae3dae972ce1aae8e8470a7dc24c7fc30fefd497a40e60d37a79e777dc0a0cd4f0215fd7e135949f89b28c7ce3cf84df62c8deecfc562b100d34b1a6f0a77f0e0fa3849bfdf1cd88f0d6383ccb68b21c3cda074edab841fb33fed856bfc65f68c7fcf1af2f41fd796e3154f4a2a192e090cceb9ee29789edbf83cfd1f7ef55bcabf9d93fbbfa238e61e8abe9cd95c8a3404178486fd16d9345ea6958013ff05f0c94ef3556d768d3ae71006f0f9322e17b62eb68530e88d7318fbf9e9c105b1e5085a2c2358a5f261850af137358bdc98e583231156a231f159491fc2f20fba89df9502dddf31dacd4523ace57a1c8c3e9750babf30abdc582abe2125b8b4ed26ff3e0eef498486b1597903fc0a44e905fdbe0ec3bc3ff006c9040fc66bc3a8d70ffaaee72dea18c1acd29ad59d57fb15827cdf8a29bb2cc4d0d5a0d531b35a29d580b38dfba322c0022d4d103a5e206c60e7c99e4410ad2499e53f943602726ca3866a10e4e64adbfa8a24cb831c2ae086f633bca8dbc542da6e939a4df2fa39234653b1347d570785f6a475b843fb3abf4a18ec837189a41b5402fdfdd6e9b46c8455669bc68c862ad3fdf571bc3faaaf46f3eb612425142eb19ffa32efa50c73fd88d87371a035c94edc973a5798aa258c240f800f061d4e921f34ae9e2a2e44428e99e95a5ab9b338a037bcd8f568add1f0c883b91ddcb9826664f90ee3bc045afe7818dd37e70bdabb83b136fce2529a139b0e03e3b48fe27b5ac276e9bce16fa2bff3e2c63d8cf9a4a4cbc3d2933d7850a8e6598a063523047777fd8acde12f62e55451031826a70ed791630e40d4a220044ae8899c173754626c9b41dd64888ce775f189cd5ebe8afc11c2de11fb6a9bae45cfaf8b68ac861e425c811039df0046c088761503963eb0e5bb8c306685e9f0cc938697d123ef007e7d49c2c5ee1904d5e22cadb14d96b5440dbf62947c48ec141f951aabf186612d352dcd14d9e5c30f74527ce317191e0047cb63a44f25fbdb80f1870919d460d7de9828b70d3489d7230b563d160034616118e90e9206ae9008507ae2373c5ac102db3d1b2dcf14283986bb2acfef7520b674799fdf23265db5abceb3f772c2bbb1d969347c42ea6539ae91c5032da255cb4855bd6a1218c7240d6af688da41de8918642fc24f9736de14452eb9f3d4e9064dc51b705cbde48479ab4ccf3ea43ccb73fe82d96fc109a356c92fbb70e35a20b50fe025f74730b2c34465f3e0537a41fc052168b257f4fb379c33a72ba800bf2dc2cf2f1cf6d81f594309c1fe044760fbddca9528f55bcda4afe7b9be29e000bc1556abf50463d757fe4f3b751657bdcf00ff24763eb07c69deb66182bb4cc781cf8c192fa529c7f746aa636bbf75d9f80926574825548ebd910389216e7796dd8b763b1091238f76fea7b9617eba6bdd27f55bbc38ad36f7bb83bece815cd7398619bf29ead4787f99b58c756926da18cc171235060504d1098e251d453af4de20cc1baa38aa12e7b86ded49c638cdbfda7e313b95c24f2bd5594b991900cbea7838b151a5aa9dc39c90fb8d6943d1a8d64b6cc6087ed9238b27bdf45edd9acbfc422db24fa42584b6e85796e733b259b8b230365c461674b279dac6fc94c84b38db5e0f483b3757ad80e776d6cb29405857702e91f44bd472b938e13db278ae39d79871ca0fa6fe13fa7d65b890e251104729f559af0191cf3244192e2ca8b4489b832920746e36d4abfa9abc40023dd7d6b0e62f067b2b3132ce663c63c0bf11ef8835d86fa36d7730aaa9d7152bcdf7710ec850a1dc983ff60eb9460f1cf74aff7c18913b89fc8b0c165009a898aae301db496d76959597c56e33cc78c7b2a471be8ec9d7a80540bc5554f3e1f32c389eef1131af00fc439604c61680ce110759459dfea9faaedb8ac5dcf105ceb491c0f997b325ae4c26bb26c4994e7e9d66ea10207480744f647081f1287458c13c838b0932bd1240a8f93897fc302d9d9410804bb83eb7dcb6a804030a282ae14eeb631587a1f5566b61e8d7e22437b6a2c475fcf0487eef1244c05ca95935ca47412e3cd821cdfe5de02197103b213aa602e1a3650a8fa8263c053779842527e8098200293f75d12808018ab7d063bd633562bf34b957ef5f4212bec022cd1e0b4f8cd3786a11e3370a0f5e4749b9e6df737da785aaea1087ac253882100254095d5b22e0d79ed0c784014de0127397d00c5c4d8a5a30e4e7d9b204c5a4764c99b20c8328a1bf530773f9a83a5064f35370e6773e9ccc99a0e1fb67339b1d84b200f29d32d32b3b91e30dccba8d818281529dc44f8be9faf529aedb16e3440b9bf984615553745e7780fa723d88c3582c175a962b1ddad46320fcd808e1d19ed0418ecf1e0254877c41bc323a3e7ab8ebfe7635053636e70551a71ed6ce4919e20f1776f4d95ad07b3d53edff1e41f6f78a583b748e19208746368fb6533aa27c00edad303962b3b53df130aa9eaed9945bd2f6bd16aaa996833d4411e94ad0a02eb89e07aeda714424f292c57b2820ae3cebefa3e35db5aa7f2903fe5e85906591b000b8eca0cf0e0423a7e5baa279226d3ab880c9989f37f9b93f3c9b8ac7c44bfcf19e8fcc77864bab6e8069ca26c565344029fc092302329d2b31061d2008a279b47fa35a87762b5e6d1e6ddc6814e097ce8c5ebd75757b6fb88d69eb68390a4e7010f5451bafa509ab6793e1e96a8286ae8f8775802cad01e9b8380403dbf2a316a17ba643e462914e49b72017703d97f6cd8aade820264243d709ab405c447667d7f6f8086011b3f74b5220fe515c253a5331204cea062b2021c2885184609e475b491f8356803c4ad71ea55b3e7db7b22fe8d18ea19cac3f773490c7183dd4fa1264f3123ce0baac3c469e677752745d7820ff3d894808205c9456d0c7df328ac237273fa43db23230f4096983678e1bca3b02193238aa24efdc0dd7123862e25790ce9190483f34a795393603b03fdccb5acfe2c15a4ab18e78bf70d7e4a373235385c533e56da75fe98ba7ff65e129610c884b3a98a6436694b6eb962c3064cf87c39b3f83c10367a7d5b5af1e09d04f8cb7487819bd8e876294b642f607d894a720bf09cdd4bbbe0d5d708fc0b67cad54252826614418272585ff1c281b111ca3b48d9669e704385982ba49726c4c99e2805b8439ad40702278835584d0dbd175409871bd5ef868f7cb5f04bc5f7972729ec084d7325e44b35429b88053ca7a54e860c0b4332a0ad12bc21722bd9e334a3bccde0991515832e18f7e9cb3703d6fd54b13b1d12e2bc0e95f9a15a26e2a12d7dfdc26222edd4268dab6de43eaf8c50666d83917689f1167b4e2a05afabc65fb3d667e38d39611857caa76b25d306a16270e4bd4d58bc8e6e8e5898f821cd3b62d1db3e3eadeb4d7206340d51c1eb31327019ee8cbb74b8380ef724cdb40337e6181971524ce944ad19e3e65da3ac45480fc2c889f5464232fc35524e1cf8123e462460f128fa9cd9225bb2ac341aab4218e690b3abb1dda0f8236798af85a42a9e9c2313fa252057d4cbb803aa3aaf21c30918f79eace30a492e2c8078cf98ac80f9b168934537e440513bc1974d649c1e4d3492b529a370a2b366d8c32c4b201c6c17863da66898b80c470871bd396929f4cc9cc0965b34da31c9751f56a3a11ce33b764af6a6f03368a2571f75c589a608eca996dbad316b4b8290a6f320942154e532d59bf4129d2c62cda0090699b9aecb1a840a66dcf3ff6091ca1ee533e81c33293b55410540bca1c0038415b12021f623d83ba97850afff8581e295a841fc203370032edf08294104259d005154ee1ffd598fe2ba220d37ea7da109526de8283927413a05aa85931227c01eff8d82e210123cb0e32ed05566f4f513cad7fffa1d109a09f27e100cfc4d770a3739ef2a48b3a546a78b0d14f37513c9dffa08fef0d018b999ee180265398c218905319b7a2dbc3183c8df29496121364da22678a2a5ff0521791e5c71256f599a20b3a593946ac6d86cfa3fd1e534f28a9576cdd95b60299f6a0c0f856cb841c050535190099b60b309b3be700ae8d3d1b9d12172239ab0870cec4523194dc1c36814c5b22e9328b9282a73d82db870124154d504cbb2ea948e03a013ca2aeea4bd834a327e9a7c76a2185e5f43c7940a62d05a30c3e57936c98d606e0d92fa8fea8298018c8b405de282c5164fbd9096bf8b026d2e7d7808711119c200ed0ef1d93acaa0de15ae3868b767a6eba15eecdbd6f9acce6d67ff81c73c9577169959b363e53c7fa62114f126fb326de2c535e7590699b91ea70749325000ba9a10c0b061fab5ecdcbf1d9e07eadd441a6bd6b93847e05380267da5d0dec4e3e30999bd72a103311a4fe2bb9f5a15168329691221277246e23979d63ce9dc7d368858ab375be3c8de59b6ebda899335c4720d31e30e2de4d1a72a3307a4378cc5899d2b260bf0e314f51ab98d2a39b129cc40e428a3b092630d5c0fda7fa0aa16d7f047f6d0b1641a64d8c83ed6ed0053ced4263f80c2e25655babaab744f01566eaae6311059976baef14a438daec2194ae41e3ffe1d9fcdc3b0379d56e0f73b800fe8539552b4120d3aebca2b869d4176ea02cf4054c0d8a694de455474936c7ccc74bce5add6bd6cfe685ac5a37351e84cc1890614f3b0590814cfbb3de237cbd971136f72dbfbba0f03ac4dcc369a436cc9bd7368d7535d4db43f8e66092028682256351601690692b99c0d659bd01cd0cd1fc0c4e0167c4e2c456453b22d61e61f210b162f31564da2155356ce4124cfa16ed567de57ad78ac9babe4f28d48cd0878885a2006cac01cea792e396af3f551d07faca89c5409f00389b7ed38540a62d3fa998d671a68a91fa90f89585d6bd57b9bbcc87213925dd8d00451e034bf08a4083d19cd88ac516522a2d366056ac826568b2485c9ff81155491b0761653b13d389cff026b934f164878d3ceef020921e0e8c130879b5355010eedc772783eb0b4f34896c965deb1305d9d296957940dc38d6c2e08fb31c5443e5eec819b5bbe8f8f885acdc54d32ea8483f396c007e7bc10a57f0452aeb8023780d7c82ecde4cbe337f72a6ed46631e2d1de633dd6ac2a986d4f7f1e6faaf23caf066f184a22b18df0cd39966ed348224b36f925194372af650aad2a640ac8e02e76516b69984522552083ce14fe624f61c17e4f6659ab99cdd54527ee54c5b6ca5a9bfbf4551eb84c1d5bb5f33057cf435772fd5ba8d1242369793e7c9d749265094be193a2f0c621fae5199f7596895ac2373b1d6cf3e317b9633ed4020b0c50946a80689069c130699612ff629931222ed77ceb45f37ebbf20d11802eb25d38f6ef6e4e747e8a1c820a4b671cbe39cb89e1037c0c0ba46a382f70801c1aa1125b96e49ceb44f17e77680bcb2b36b35db4c3044a0d889bae3b67f7f0a52d69dfca3dc345f5a2bfd084869613bf02d862636953195bec55167b0264d6608d8013d1c4d1bbb5768a0673661b6d812605fc82b592b0cbaf69c888e6bbeccac9ebcae8c1d52f1ab28238ad01790b63b16aa467c1531b30868b2d1dc6549667f9035fdfea670a17e0e48b1043a3a7d153418346d85da54da3e6a5c38bc04ca2316c5d501630ffc67dfe30c639f13e37eab127bbcfdb14ee4d18451ed64b00a7dec704a819c63036d73e41de975063dde89f5661bad233ddd18b72163837d998b1c34edca3012ba896807d6c57393994ba88d3d103e40bdca7aa2f50f6932f8b3d2465108f973e482190b17924d43798b976866586993af0bc4ae6003ea429a8c8c26d80364b246ccbb64eb982ad27e68c2b0668aead3a4bf4c470c50d256bcbe81ef7701b50154dbe7f657328d9d46ef52fa8c7488bd5dc2a4129e83a1cca1eec8b0d2663670a901292904ed8275a393ef6735e9ec8cb6cd87f1780e3a911faa8687dd92b6814929dd077c6182c1ceb678d9fcdc84fedffc85d1e8be0a2beda2b8e1bd563af2eef952da3def05f400196ee96d664761a371b82c7f62b884f9a78a61794171016cc749c2c89eb4c2cd4c65f91856828a7c75ba9f33f3a7809095f68402c0ac1b62505969972ac07ed697ad3f1230d2984dd8265817a23b20a0a8693d2dd32510018eaaf9ca05795163412ce1c94a9b17bbb7316f1de0c298de67d65d8365fcb8cacf1fe8de391b04c23618bda591e61879003088498540ee4dcb6a34cc5e499d95f61b18ff5ca1572324f475a159e900b8b914cdab84ff53cbb9a2501ecfb0abfcacb4a53c2cb66594cd95f1631734496cd977c9f2cd4adbc2094f0dc60b1da9c18079f01eb3d25ea5d416ed184fca1d5702b5b9193aad9ed91cc2610249597bf30e4b9e0c02cf698df880303902ac2feb46642257b70e21902e2094ebc1f01238b81b50f6a42b3e12905ad2bac3ee7824cc3ec68421ebefac9995b6743c9421cb54570f3990a0730dd9d68a6b890b6eafe24941b4b3d22e7467240a89600eee2a3c165533462ec70c78d57c43f05c341ede2a17d06ad967a52da7582d4a16e76fea64d7326bdd49a491444bc68fccb3f90a2a86780c245b9c8fa3aa552790b9b4d2ae440c20249d05d108b7b5b239db587477add32da447b69b818e94789a6f38eae04d41333591bb043b47d6208bef01022d68d548294612adb41f96993097c77d42861c8c3d993ecad9dc9732d94e2b6dac1a513a11fda4736ed6550b61234b6a37d3cc63190e30b76d4c677bd3ece672949f0c39802cb59fb2fc019064600e684ea56294375f9b1bc38116e0910441337413adb425cc04a3cd0c4b4aae65a5fb451670c50d7c18ab283a11381abe58e46ba8e96ba29576c86f8da75a50145c54cc56eae9b8ccf29b5b59c7644b5009033c79057720c6b696fb68a56d6d2242b4bebdc814000831720019d319833d5676fb4acc6058610789ebcaf96fe1e0af89aa992316adb4c3296c3f96f005ce0badd2cee630ed4095a4b725af28e1fae65669c1cd7c337ba2fcf18e84eca4a3297dc5bd02ccc9f2c7d04a5b96c775113f684c92a49576cd00d69aaa534a680bec97b050763001013178a2b7d14a9b98eb4498c2e430dae96fedafdb290d489c6d1f69f322e504435e5985b68d0cc122d8f260b7f51c7783fc911b2f39adb447e080d755108df9c778c1b5d159496b9e519e42e1dcb004a909ceedd0788256da54959efe2ce5769399d94d45dd833bbcef4932ff223ea299402b6db7897d1cead19254ac19d2288bf8980b761bfa6f25d99943ab44ec4656df69f3da7372da89959d46112beecb6ea3881e4c95f38e2612daed2317e10fdaf11bc9da755af650aa1cfab7dd3da25aeebfd34a3b98cea9576b2e5c6da456e08f53482bedc94c73e0ede2815f6d406dc0229e96653e1e20a597007fd61a1daa1284b69e45cc28c4ef7b241eadc95ad63566dc616dc5af29b758aa4cc504bfa53e7b65efa04391d23245e1d8d7a3f971fa8ec9c8e717cc3cceb4d2c60cc3c5a814d32a4b1dc2d34a5bdb4b1ddcdb855e04753111c9d47c22e787044cc5748530d1ad305946b730a3fe62a545ef1dcc3975b25fd79f094b61565c71f1456a95f614194d2860565d51a195b671d328096a5b11c22d6836269e1511ad0759a00bc5495d5acc44d6a1a11dadb48752012511c741e0a41573b8e060f4b96b9de8d100fac33e757be22255876afaed1f24a9f4619a3aa88db0f80f5c9a56da561caaa3a2a1cdc2f7abad32faa5831b47a279d14a5bfda71a59ce0f8ece4b57f435b2dcaef1b5d94428478192777f9306728a50a1414fdf18b87e1762ed483a057e834e7f9f853dbb08ae4f021e7c1a9038adb4458dd8c07d990e6d1780c6566b19c87f347293594a5506bc86f5eca01afce12904a91b106cec8fdb82aeab86a52c3da7a96723c168a58dbf0099fe73ebb2b1fe0e1d98bfd24a3be98e39dda81b6290cd81b84ff7cbac96cde8db025a69cb84a8bd8735a86a647cb38579a073b0b4d29ec109bd05294d0c53840e5d9bc559f4347ee7de9f307ae908cf9d0ffcbb741a0f783575f38cccc2ad0bf22282afadc6d7a02140bf36c6cf241850d6050094d85d6793d4e8271da85aec267139ba457fe26e8b40f182c83da4bc1564fb6fa8aea5e9684615a484b0dad72ede3f498297660092c24b861161527a5e4bd5b6e7716e37a778644fa7957640bc231b1c9e56da7b1a351ab12cdc0a24f6163cc5f0284f83a07344b2eec09809e165fad341899a56da224ad48dce75e66af71675aefd81a09461642f0dbbd14bfc98ba2d5db466490278a12571153d93e298484e263a9a86e60eab3d057520dde2f0ceb8c9b4dc2a43bbd8cbd662344f5e5cc1a095b6d84d4f9fe7de0a67a5fda2de1d0a23493ca74167744707898616288a73b4803db8c384932db56358b9f59877141b4a3e79ea0a5dd12dd24d02187a50776166d520c9acb4ef3b0fbbba2a6d680f3683e941418c5ce5783dd8e41e7a136c306632cbae7606ac9f5f502d01ff273080e2121966692f58fccc17251790e7e6b765680806457d23c5d681385bdd48b834162805f67a89425fc4c9f38ef7e0347a46d169af2879bfc0427e8990afd461793a2bed69c15c7578a0debf17b905392ccbfd6a5282a63581ce9305cdd1a6e651a6e030a3331bce4adb2590bf592e0b5a800e40ba70098d0860478a9895b61294384460629b04461091a3365b97788a484d2966a57d9b7440180869f7d23198d4b581645ac358ba55a7d022d3c463144bb5060db3b03a7300c44d24cb4e346280f4a50fe285da380a8f87740aa6e7d78925265a05ae7ad6b77871b5a76081a7f46175c27b5bd68dcf169a668a4880b3f28cc9ce603a8d6fb18ad35d964613bb6d8d5a753a81712c6c675d9b234746211829a5affbfb4f52e0591e7b4ddc8b8d8650ca10838dff2d5038802b83a8722e23f1394609109f719ae4c474ffaf36472bef63bf1911b5b2309ca013d35794dc1c082957a9ec7a3a315d70837aa9231a9ae20ba3c5b152bbf6efc4741389cbb7adceb33d22f739e931823b11dc6d2b8a3e279cfac346f41a22736cfcce830819163e0a6c90c52c108a0aa1983ecf1804f58c0f5916c6b147b30414d38742c0cb54015f5d6b161d177ca93369fc43bd922a17e0891ccab73d7fac19e6bd340650ced964d54df8bc3c7724595fcc9753c2181aa9332e70d8ac613a83160ec574527790b8ce20adb8e0e1b340568096f5c13a127a2575d9f091f7eadc10b89abfd98e14ccbb0d9d50311d076de889cc51585ff4b8c22904760bb4f995edddea72a3d2e60ce4224e07e31d0d551c3b4b25b817e74ae712277709dee88e6633913c24341a6740d9da74f8a7e7b4be9f9bf9627ac263faf60b9787c6ace13ccc803de94c8f5f8669b88134b4f5b82085dbfeee731a4dc74264ffe02054ab2a332aa4642cc0f29cd2e8300f741225daaccc1bf8dac4f114ba8e46889088fe2805b23d50a5f15b0908adbd7b03310a2f5f6b8b3f167bdbb9895ba68f9fb3b6c0abfa940608eb32ad4826a15fd0eae36e4d272380e3f2595baca24d7848309241c26440bf5d03f59ab10c9e3f770ce3028701fecfc9446f992e2aa08d77fa7dbd837fba76569a6d20b79fd20f38362b5f5e8bba65fa1488d3ce78a49096d45814dc97d0c67f62c44d5bb127a4c073e9daa755e9b4adc8a89a369b6a60b50b80440f7d5284059b593d9bc6074d1bf710d02989addf146de3da03ca8be05409f12ba4b720197d7193067b6074ab2dcc1900516c02f9afa1609738a6aad769eed7c6a5453cc4d4d7884edd1cfac8873de787ed99029c47ec876446ba816fe86348e026594b6013381634b497db6a6225d698e0fccf9269294ea38ec5ec4b96080adce7e2f65c108434931ca0b7a627e3be37f0004b8061d215383baba3e53b4e4c554469d5534d8b7e0e2f445c25a8b1409e09d54cf31b8809dd205244c7026062da41bc6f0b752346100624eae24bb696586ea1ae4d6c2cf8207a6a1c07d85b9ffc9b329f2639ce293b48a431b7d15f8143de79e57ae17a457c89e89df2d50034244759a19c88c3dedf987942190e76dbdd4e906d7fab05891d8f2fd1da8dfb717a42206292195c2058101210868421dde7134daaf4d27007670dea17a4481249a57fbd1f0a0b62b8b6b2fd87327f48660625c282097106c0906748f9ed45a9a073a5ca1390409d8a56ddea0b063949a654af968fec2553048ef5d30f9d89ec491d8f3837802131ba0d81611e7b6597e95c7db7ca24b0ab7495b25e63b2e758b7720030056e2655c414f3be1679d92b2622b28aeaa15b45ac6ffded87642a87f4adc5a256d4b69a6b9090d2734bc605f86baa6bde5fdf65ba6d89ba6226719b58bccd8e2e72542477992e87dec6f163c61b3b5f9dcb3c45c0084b8b06f0f32cf9f289678e1385c75b9ff82a0f569df4ce7aeba426e758d6f55d85c9d3cf30a3238e9190fab0c003815bbfc3f4112cd0d36b48acb5fe44bcf089f7032de3d915eddfd07eb9193eb3df9a817e0fdc4357531fe2805134c7d053792c1cd11c5d1b5b3544bb2237f810c7d6ca69e2b15454392813783794b307734a09186da55bbd083fe964973bd18b3d5f61e564f7d2de0f1480533ee5036a87f5ecb1471f350f8e1841feaeb34b5b237a4e124adac00d3994d785315e3603d71e4cb786111b9e8c22dc4a47c604010f6db520717845e3aba901f4b8e80ead22b5dc94ed32adf9dfa9d9e6dcd594c7c10e4fec0f6e5d2d693ba1f6c58cd865225aa376407926358441aa66c6071a82ca29519debd28d4ec9658d4ed99f2475f6d5046ccd4c5c4cbb7121a09bff5dcec2c7711f3a2795ee721050809e0f25890edc45051f0755de59bc35ef266927b44bb624b46be9715c5cb7aea577e69af04c385d360bddf6dcca3ea5d5ec69913ee477b1dbb3df6569417c29b0630b88be8475b59da24ba79fcd9f355cc78e27f5ccd385e5ce0630afc5577ed70fe9ce5a3f0845bc83f313f4c80541069d91fb517abd8a237893d745aec998cc2c292a14fcc4ef746a64c0d5b5ec8e435f66cfd25c60b900bb24fa88da4f2589e77159705971abd9494012e87b6954482df127def43053757002d243b26bbaae0ae55d7d7e32ae53352030391565170258775e687132089f9b8f06c192a4086c3b2307d4cf96f2c59701841e08477ccad9af8e0770acb492390df148403465443d2c48c3bec39942c2889a76df900bcaf5d8278ade1fc3a269118bfb0f2f847d906a2b60cc7031511226ed4a57d087981240771ebd642192bef1b03cfc319f70901ac336f4d1cf10b0cefe581dee7afb3a2a5edfbb73f625baad0bb5957e74d05a926bf253656f82a932c8d4302de7fc2c276c6aeba0937b67e3a9b04db8b14d611779a6eed208cf4c51308720831da1e1776460bc4a41ed168b3f3658abb03601a35868a603e97154147c19229877bb02a477804a0c0d030ab330335a46a5de849c129cbebc676a512ca92c2d94e72b10c7d434975d158dbcbd16b1c0b570ee967ae3bb16c2a54e468540ebb18d17f1cd5e027cf89c4cf779264ac799e8d6a667364755a225e0a9172d13ce2ecf42f21d7b407de463d834708e4aaa0c97e1ed9353a39ac9ab0558d645191643ae6511296279304c30d6a159bf199318d728c615faa70f8adea07a6f0369e819e02d8c24d7f7b751e3dfe341a98aa391fd70688d062c6903bc4bb95c5f9c46e4bc2d831d075f0e63b63a1ed5658c5c3715ab840ff898a4a50adbf9b9cf4db24c830a2a2b075b28e23704a987a1203973aceeed29ba885fd49a76eaa963983cd78ba4f4b2a6cd1391c2b4f0d068abb9969d69a02c81094272eaa85768e7f7983157b3451e65f487c512f44ca7a736654839de0a14569691fd922167f338742793d76dc587aeb0d1b902852f24ec0d132ff58fec7617a74aa3f18b74d8d845f3210a5864d9dbd2a055df99afb8f804ace6029ebadfc6d03f943032d181fff62c8c2f8a9cb58b75bf722998beefb7e4401297296f52e17d03353e1ca38444a1b01c899f8b368ca0f39ce806118164aab9222e048edb7ccd94181fe69c07ce74eee247de28e377f49a7ad0ce26ef4071306aa0d7841ed63981587bac2a362c296b4a60f9b0350e14ab55610fe7dfb948e7993dd67a92217184c9f4f07d248b3571a5123a1c18e702faa843b9fa9669b528b2ee51689600204e556562e3659dba4d7be82b9edb75a678d6e3d8fc80555d1288820b45a512cc886729fe6ffcc55cf9babef5476b36bcf4c0395a58dc206ee2ae458d932ac2010de53d07dc664860ddfdddaaabbf5741298c814acdf63f87773b7f0b156ecfd4f6fcb16fb34cfa2edf4fddd644b976b3e5a9ab542b23be0666c0f386e0873baf24fae9af5453567c6b3564147df5c7714cefcc5bca25b1c470767aee3c65c31a65702967869aefaf4c61896703723189ab7630457249991652a056d30106fa5bbbf4491e73d155baec2aa7280291ee3e68cdd71c812c4a60a9627a2725069d724ce26eb5d61d36eb87d9b5f5d825a61b3dac06f52cf11acd9bcab18b0eb72cf04354f1b9abfafc5745d828c8c4d21f98263f995acc8e038f31e5b9707fc55871920651cc1e87d5fad39982042d7ce86adcf4079f358032734e54877db36fb0d68c2d9812dc2c024fb80c7d9c35c353ee180dfffe29cace5092a2de2a59839e7f88aa884f6ebf47e25b8d2f1eddc140db4f861c9e47856fb273ae0cf7dba316c8401341dc2bcfa93f872e050877d1010265977ee24e83b20447a4a1743e421792e76d7df10b2ac96fb306f4ea18b069801e54e9d47891a548140be99887fedd5e708dc73ab25cdcda3e2eaefdc5fcb5004a66a7a9ced25dcfd6d2d69c06771656d074afdf19c3c53879997363ffb7d8807002144dc672acd857d27439c6f2ac17ec9a7e24ae52d5c5356a92efb235861e8ea37d9702a6eafdbd78521573a7278953331c7ad3377eead1be5cd36b8e406726eb499b1c36d324b1ecc88a7038ac41c97dc3c8f771ee9e3ca0938f59315aa8998d446860736694f84312a83d11174363224d7f604a3704c07e027cbaab8005b14dee9b07f518f723e94581daffdad3964d0280e1bdb27b8b6e96c2f3780556183bac487a071e84a131cb6821ff9087fc318d4eb43bc1b01d3d3db4165087282fee9fbf2fb65edc47247a0dea6b0e876958c0d047694b3f5ad5ff48259521611dfd4c9872697a08d7278e6694eefe17158a212eb9c779d47793492896409fc5e644b919a5d78dff73847ff1146914168150fa1ceaa177232652581ebd9598fb7ce2364908ce4ec057d0e29544324df8afe31efdb18bdb9b4c7189f589c60966753b1b659ced1d74d251cb447fa511c5b2bda120b5e208f57a4aac9b6ee64b2e1fc80b19ac46fe144a5085de871a671c12d68d0f51b8ac0ba45da8a77d194d6fc7a6c35f44d7f9e7691da12ed8b0c1441f05a28c5f39cdc43d59a4c41655cfdefb9bd49d4d0ba3eef4311aeaceb2660a13cce408f5e17f348c00997169fda8e70e5b73847a495eb46f5d8884379d908c40f3761b150330c84054645c8b4d20aaf678e31c7a6f5fe1f29509682181909ecebb5e76e06b23cb74535d8169031b42ed55b46f7cc26c1ba9467647a8cf9314322753c60d38a79635ed332699fbd7bc632ab77f4cde5e7879890582d7c61253c346f6ff1055565b4fc007e4e13ec4ed9731008bd00c2f8591aec9935710f35cb49171f2bcb5cef99ddfd4fcf1298260892a9c0b9a4a2bbe942e0e384646d05b17c55940d0d466d64c42c3c6ce1074926a2beda83aafea8bf5247f81010cebb117c2264603c40c2589ba6ba9b2699848c7127412986a9144dd57dee856419f6220d626b70138d7cbec5e24517f501c9691ab8d40f995a88bafee014133f11413ec207829f033b95aea0df1a01e5a7d6c0ac04ae04b1d7a927c7542dc854e74a5579ff3d9ad501ae8e8533da37397510725ff0fff19df9fd3684c870569f55e99b349cdfcf30ff0500b74a94f5359e32fb9ea2dc1612472a9377726dd97693abc68441ab12e37f2ac4bd3a155f57bdaa8a96aef2f56b4568e61b54f6ab5c1a9d9f95d882c1f01e9f2a090e3db10b6e05c4d3da1d91efcc07eb70535351887706db5153be807a2cc52d713a08699e7b8eb80bdf3540ac7c27c5ac7124f79b32321011e81e0836d75d5f2f0e98ec25814a204cc6a62f173f2ef2b2ed66d70ccbba58c15de02caf6314bb2b19edf399091f2a824437892884f5fd73799f8e5914012ba715431fa836ab8a773b6fcea1018594e4eddf1ec2a97727317515c29ca285c270e7472fc0be5f6bac84d7a83107d5c3cae046f7448210b25410dd87e76993032ec4cfde48440c21810e9315792b76f09a7b9e5d7712458946bed8aaa83430efc316884453ed03b629e33280fdfaaf362f68596f3dbb15823ede9b8f69d79ae138a9042cebf51af096c1a01f62a6f68ce320cb0972285b39a68f55f72a0e1fb32526135c1b0dbb9bc978cf477ae76d54e6a3eaae7c2692e5090825f1c5b09eb1b148f3bf02774682da915c2ef4d8a7e972212f3984635ef863867ca2b0b957ebc0ee60f165480928ea226469e0afd715615626d9eec75a841579a2d9105725828901898feca29ca73df6feed2180122daebd1c4adb18f3bb1bd46244d3712d22a8e2427348ed1164c9dc46f4508485055c3a0f8cfcaea5fe27a078da4dbc4f14acd757e067d0022a91079aa75f4ed7a689381b62546d64bca0200d91f8970203dbcbb6b8f5216047bfed5b67b9a0345c71c8a9e8053085e016d898ec771c811660e26666866f3ba1b4d841be3bd8b8070653063551180f4ab1ca7f71142b7ee0970b02a4642b59468e2295908551e7bb5f8e954278bbcd6e3496bb1c7a1b82a20203e2e57451db9782e664f2e84b9e951a3bda2803e163871926936957b2389d6adef0638752eeac891c5846a4b1d961b012e0595a4befa529bd74e6b7474eb7910973e91cd31d51761aaa0f6783247e30b1ab7734b0e4c390753e22438494ce3086a377358be737418ff62c9edd18f561848d3cb9e05f5bd90fdb5e0ad4b81d772825fe11dc5320a0f3aad5f5cd2dbc13ca23efc3878d610e9b685293f5e73b94909c004e7a7f2fcfc4522d5675fe40f4a67877003fc42c910a8b2f01356d57e498f10eb4d5f01493de51a035dfc8a5488f6756c537540ccdc881a1bbfb3e2ada6011e021071209accbd10f250e4ef61cd2c24650d88127f9372ec880d654134012e90ec3acb1f4ea37b149bcc1b73dd976fb749c271ba28c0ec94b962041840eb370a09b94d4d6724aa2c7d75cec4c6329329c6fbcda58eb36be37baa993722dc9054030d4d95f7c198c4b2d88b6078f9d2a68555a012ac07a363555cbd8956c8a820e223bf1378a52fe47f60e199d082c695d8521c5152c67849af0442fe5bc5be84afce749dce3ddf678c7e330026c59067e9f5e66202dc27d7b55d34f7b99b259ebad48083d057aa0d4855775ec078ecf70553ddd23e67039b08f6f4a7d1f800dd0dda17d5da3c0ca313ece9eeb62a12753a5c213ad6ca3ee4635f66825dce8fc4f364b53479c5ae41afd5469e8df9599693fab8f01dc85ba7141983edb71585bb4b8a03034d41a90691cc343299f312a0fce12eaec271c9a7fdc72f7e3d21ac1e0b6629efb1c430ced7830f9e1541388921e4219d689483a31260ba1cbb005a89971c2404996a4e87fa623c46ab73b6e382de800dca11b343c64fe854ddf18a77bad7f19b8ac77aedda8ba704a3e5b6028ae261385ca539b1d21a08bc6b401c236014a0ee17f7c9e3636300eb615344699f2c79f56118b447b840e7cb9d57d46d409ba903d4bdee3589d21f79ae9886b34e66655478e847b3e0237213d1480ad483787ef1d1e014d53d011d299c68ee05394edb633cff5101a0ee38db94f5cd3449a6204294617f78271a5524c3c5fb8c39a0f5f0fd18e2d6bea50d1b6129215f242f4611e29b3e6b169fcffa6509d80c575005434310e24f459f16c6265aeaf0705385915a3b8df7fa55aed14ff7099f9153127f77fc0205ee00fe20dd51b11233c492610113909a0941f440f1863f524478a108563dbff7d39d4192a3ec35ec23cac96a4e83c81e6c9493592cb617511448a085885a9dcac8e87ed54e3702f62a576886b7a260d607b242bd95f24c203897a888b42a6899a6a7eda274c18533d5dc805328ee30d485a61fe8959bb9a6e67c4d688f974d393b11f2810b50d7e1278cfd74b713dc6cf8ab0ea055c85feb396cf5cc30a6445c9469f0e20ccc173f40641eb638a7df9944934c1e3b593a87311d2320f4c60f35b87338e2ee4027197a42936888bc8bc2728a573e49005ef4445dc793e38d9dd0397d7eba4b23371877e86184363d31a84c71f3e97ed80c1ae50682d5a61ea0d47d4cd0bab058650e7c31544216e508223bcc5c9a2ffa915153204e20b0887c727cdc97e9457828073c79d23ce36ac768859fed897d5a40c98d3914821a551870031cb09dfd00b40804430a6d9b447213585475a9893aa9273fe43a55df52e2a86fdd7e12ccfffa05f05dff7513d37654d3c76d32d4fddd564b237d5cc0725287461292b189321e718f6d109520921f9ce4cba8a9d846e6ccd58d721d0950c046b3f6058bd78f65339c294840e8562823ede814a22c89569e4d304de9b68a0ebc172421965a40ff0e1dfced606dac2adfb13edd17bc6c686adc3456339144363f1ee735ea7e0e3ab2ba628b0ecacd54d10ebeacda7f5b0ec4a2fe3dc530876d8505708e56c8cd01b919ed616346c8f8ec479d49ed0f0b104380d6fb7d2ea94971aca24955c77dc2be7eed9e3bddd5af9a23c0934237480048ef9441386792f0ba0643ebfa09a7d5c528d9bdd3883b341d7d931ad716d62276a5b6edd4f200c67fee35cc475942e8e5f608a2fe551727852541774be44270f22300d425897b7bd3993c9c46701e6678b5d51f7ad3bd19bfe79c2a2fc2413a08028af9e93ef4fce979be432b2116dd189779c74492672b7ae2c77bb31222722219abf8230a0d877ce89d3c07a40b9a6d6eeec14bf4be37ce5bd869973925e0ddc5a0e4cf85bc114b5c7beab349575256dff4d213c7949f97b3f004900654df95d121ba82fd2102b4020b0fa08206f1e11aa0be6ef96345ca57436cd08d6a41ec96231b07d156e68820e3179f8a0b571f53f82235213953895b2a37eb45d8208985e6ade8624bbab2cdd90f197bd6680ecc3b8205b4bf559a84650cc734cfaa17b5d10ba3a772e117c5efbade53eb90c00591f03b47903af128562c172552c972b1aa5f9d0637c5fcec799415dedf9bf14e29a04bf903be727ee31018ec2b058d7700cf5605afc8e94de615cf957bd09b718762415e04f6293235880e118c6e334944563e584145ba9fc730189500b11d33170b7e3308410ffb660659aa0f5b0c3b6215b332212a167d02d18a72c53278c6111cb46e9d8ceba066a160f307bb5b5d4dd2f4f97a75c6d2c64435e41b63f0e320adbddcc29749d509adf5be781f605489329f192f71340d864959c6e69453a28a95181a1bbd0e1234e7695d31f8e73cd8368812bbf70a3ce4e7d9cd60814b26cd06a9d2ab01720303bd6dee77a7022c13a02dbd430a564036416a0a5830faaa71ef3788558f2c9dc30e58a8855a6968ce71ead31f02e990ff61ad6137d1f763c2f2d7d8a9040d780df7020babba41560b82452ff638254ebdcfcf65a4223502e6514f09b88152499186901596eed149dfd7a3a50bfa09a924e55ac4d24cfacc1285fb580354e76f6332f998602aa40fb14a93ef76632a31ac7b93d062516ee4dc36104701b78870fa499d2f37d64588a09885e8e2bbef3b4edf4cf66deab8f4a6bd9412dd9d827223bd467cf9f34d87e376f8c101ba99fb234dec9f72b94fd7bfa2579cf948b39e3bd6701897f41d4a0d794159944f6c96b7ed3db8637741ab98f0404025405a452d930072e9767d20b510188901a644d9d4e2aa6dba517e210b3e0f1890de2d81f8080660e6e708dd8ae88e7e3d1a279f4d65efa1ae46d4c23771dc20b1f969e2083d8043d8c28be0111a551bae7198e978a4f6d52fa1d379848c957b9b72016fb82ff90ca2c293fe51bccc49164e0ca5d3babbc62dae84fd664401317e9e9908998ad2d603ec00914e5d235e0e043d76d7fe20163782e710cc6b7f84e2e788cc9afa07ebd80a45078a1f6aa63b68a5810cc93d13dfa5e0464184895b6356debe977bd400944f17464ce03ed61cb604cfdda24a974eda1a3b3ae21a975871b1bd72cc2ca88bed1b63bb36419ac314a7ba4aea970dc6f6aa9b05bac0cb0b7fda3dc5a31648091491999756c08ba0ee1a8080c80f26f37a80606c77be4a54120dda8ff50d06c10ff16168c94ac916384525db8838fd834370076272409f6d0ecef9163ff4531d30517b84f8fa3547a3d5dd3c9a548c9adb9b5d8c9ee5110ee90dd24b61534fbd3e7a13795218db25b7335c7448390553432a17d9d16d3b324e568a4b7caf6f548cdaa023eac09187b0cac9700e5218dbff2f92bddf7ea8f41ef84252351ded0a4b88f27ad2d1aea0a3cb0f8ed9748e1cee753d0667c5f6f46605950c826f962365fe3bbbf029e2aa6a2f473025d50049c2e71e2632c183bcd85064697d4a12cbcea1c0979132101f47bf8f6e462367e0cf05fc95aee2d271bf5d8ced520b774ac10fa6db2644008415bc23d3589b2b654f33965baec7f8c30a7d99b6145061dcb8c72ba6d376ddd685a34e5daec99784ebd677190ad9cd718dd88204c94602e6d61c6041e12a279f1bacbade93bc70bec3ab291331661126a032ecf9512acbf0a0815c861c93054d8043120015c8083b7db0b57d40361523b331fd612801a2d120042d50a72a44235d049a22f3d1cfba1c5a6a22174cd9337c5b3051b20344b70701323b65a4386d19b2e2e565678637740250d97b2c3ea07062ccd78735d274cea11f652e9d39b312f82924774e58ca5901501cab505b17902b644b3fc66cbdeebbcb6173920a4dbcb24c16c92b35988c4434806dc5106e37cad70b426624401277ac676ba0a4849c290542ac92fe9ab08440d258fd1708b1f80d47021748ea25a376eb3cd3ca27c42cbddbf1f6f85c2625a0fa8baaea2120d91bddeb133814df0e06ebc1d96af306eabda80f366980bd052e2d8f63fb4ad8e826a06b1e56d92819f10ee750fc9dfaac76db49f6d6105936da666a8113da415d60f129a948579a96de469a9cf32070cffd4107c8a96a15a2aed758707e189e0e424ec7480872e0bd414094850b544b96839a1e03cb56b892eab4aaa4830cc634b472e446f135476c3a4d5b7c2b18f6f497349a9618a12418861200ce23517b4594202d26f74b8fb39fb501df15f792f77f8d7c05157ff67ddf458d3383df866b44f3ce214d3e41d26fd317a14eae5b3566631499edfc1e7a1ac7d7df00a14d9124d92554a468f528e780443e4ce35000e687a5a89ef3e18ea95278df3f577fd6644efc933b76a8108e27ca1bfcc1a53fc5b8386769f61712497e4b054e210b936ecc66e7adc2e110248176cc6cb0abfcf94998f8675473a86d0709e66c56720f070a0c92bfab153c0d03f909f32c29998201cce4a4e3edb1724cc4d06633f338b17cd8e6816f5e4532e735f35fd9121d8ace0292dd0a1634a5c03fc01cdb9104154110d72e11556f94dec9831713ed0b220af8db8ad4da52c69607d4a539d86f14e304a90073aad141de2e343eb55758439bfe19ee4253b30d7dc6c617d9191aa4101699d6985b070f458fb9a207eb52ada93a1a4d313ee03aff85e683a53201222a8a49be2e630436bec42026d226124a45c83db7b7524bebd90d89e2ee71622aa536499fc8d67d506bc15f6867dd8e160ed05b0e057a45c95f1c9d5922037520ceff60c4b485622b7cc01bf2f0bc8d6f759fd8d6f1c9002ab39a05a96849ec85bc12bd853ca90f0210994ba4db4daea20e6edd845d66750695aace74a1fb982d8d06dd8681315ed0ca03b3e5a3df8704a0f9a237261fe8e73b4dc344cfda6716a13e66fdda8957e0214f3d9c11dcf9decce9fb00d5ceb07eaba678060818c46b3d2fad60dd09d86d6d4e479830634b9d142baa24b9373e049281c9bba295840bd0708b1c8f62e8385c8be9403dd05042074a9d66f0cc03c009c266ded7d93523f9d919f926ff5fed66ca214da00be4603a27afc4938905c7fb5adbee64d56a3da0a24c92f1518ec46d86ebaaf7a21cc8d3bc6c5d311b04db42e65a706244f51c6a88d6ea4021be3be6e73f82ff0d54f07c641250bfcc19297dc2e2419286638f9df57ad618bdd4bf191513892c75247676c10bdbfbc875c41b413d67919ae88183d8ec4507f86b56b6115a6663231eeda1bdb9dab4f5c071f01e823add90f96e8b103b57eb6f0a75b67da7562a058e5f9b9d8d6c53fae58fed5afab6c9220f7861d026b8617937886c92d00c506b31f60f07c842466e69fea3f5c692e8d21742e86858de0b9a433040e8a4a09925b2d719bf249fc95c8276ca5e346831a15e2404ca7420bbaaf16400f983fe42a94f032971fdc79db59f7a7c1fa07ff81f7c37fe5cffefac3c429d84d20f9ffe0180d28897a98456d6d39831b78ad29fc3ee6b94996f1a3ba88d00ae2dbd82e792063052d618fb170c5e123fd5642e4a06c1e9d19e1e38dad83ff0d91771e3ee6029c5c3085504ba8084c1557ab16e3cd18283db5f47c9736f1961bcc0a26f7f682183e1eec088ba704b55359f839349d86417fdddff8d01f8a82eafe7b3ef96eb14bb03afe373e66661a8e7a7729e8069266a79b3d94fdea697e321b7ebd1dd8e13cf9209df50ba9f685a7c7769d41b80e00019dc2f1291ba50007c400198a011ed3e7391c7e9fe45ffe9b8dad4e082a62b221529ab1326c54c37490a2dd9e2f553546ae9229b08e5cd58ade022f532023a2326e0324a80ca81c7dc45ec28a241d2cb2a76f18a80619400fb7d28a089fc8056b0ec2e16dfa2d45102cc85660ef0066e7ca6b01ee5a7a88985150d4d8ea08e2f5ed89428207f36dbc3cc91c4fe21e99b65bed31f92be1c250a2ee69f485b02acc6142a4441f144a90f594af8651ea0b9005b56524ff72922b97a096031851a45eba6f6b79e0e86d863a871967c0e175caf29bad8c13884c8fb0d3e821fceb1d038c1b08132873789294771bdef42a52268de8630245d5e8054b1cd088f34f542ee2e24210951b3ee8bf9123a7e8a9a84ad158015df9d828855f76e6baf1674ae6a735124420e5c5c2498212c9e24796fb35ee43976f32f12fe8f8ac74f91c4d68e18f6950da0a16f8db836be02181abac8fd48b9a63cc9a65dd4b4b01afea8451d64e554d0f28e5898181220b9f0362c8084830eaeb251909fe273452ff240159d7e69bdae477a5ec4c73e97ef761740290975df3b0b36bb307ac175e81d883e268978cf523ca2a63440ea9df441b9db18d07597ec28408f6d07cd7f80c4309242d29f4fbedf1c030d1e35b1a2348a4fdf0c5c63b21c0d474b07405f46605d931aa57c58caecfe8d6d590df86d1d98dbeb73b21937802be5117ee33f0573faa1843f60261e908bf33855ebc690f487481bd77430bb1149eb316ddf0816ba994a431df49134a1b770d34497b9aa0a7e5ae04cadf8e28404fbd854269de78e0fa59fffd81559600a096003bbc4312651febe6fe114e08df6f0bd2c82cac99d66d2e3daa88657ca0fbbed2245f8cda4038a5284a36d721b23d7076a857f775a61c45426d233e9ae07667fdaf907efb86c71ee3f3342db2106ae701f9af4c7467a5faa6c83e5eadf2c9b18f9bc43529a936738a481654137a56f83314fcde9995276a2710360ea926417d3a118ebf83bd19f82c49d5a156197f66743179c50a410f4897ad28a10d4207ab3f81d52b7d296e789d85283f71dbde56dd5e6190bb858e92f0031e96442f013a13b0eb52275e07416c685e7a0243042393645be365524384072f5aa4e606ef2fee7bf2a68fb661a33996c06cdb76783cc52057c21861ebc0a7c2f2e8e4b216e806730c449928fbd6c6505fb0b9ad9e149278199554ba18c755a2501c9807453559a704ce823d57daa29c0b10772551c43b6ba9db75551cbcb319419e4d4834b0f8307e68efa7fce320330663b8ee1941b0cad24dbb18fb29a9bdec83d520778e58353377486eecd87147d2b30772b4160de315d412de3bb917f79a3c8abde16af411b0a7b1d7856aed9e52e8fc0f153809e0844a38b8bec2ae8985f37d97128b782e29fdfa976919f8465acbfb53405495db8af6ebc34a77f0001ea464136af50fd8bb7affced366ee3c335550f2a5615f8b47c7214de4ad872135e792013a64c61caa4b972e27f3f0c2d8653ba1bd34dfa7b16d4c566a993bb5fc4562ca72c43dc0f62e8a5eed10ed17546d1ec22d367566b15899f272edfbe67b8eb77d02f34e57e4387d6eb298af4093963891fc0142354f2eabcb570405308692f128fdebbc88e11ba24c1fe7465aba1568b8c58bf02d99ac744fdb6d34f28e1c3ee8cbf7679507ad1ac5f67b79635bd08a80323b964e250326df1b8444ba6081d47ef6ee89c7f026adf7d68521040c46e3ad22bac27bb1153f3c6b585f5e54a491dcd8f2c43a04b169a8a6b24dac48fcc97469863b3dd0454b2392cb7cb398a693a876d73c8938e704c825004f3bf36fb1106bb781e979a90bda594694b19470698065c062d04de3056893d76144e1e464a22fababbbba9d070c16832d5c299184fbebdc81863ccb79b70f21af79b0394407b12ad8d3a78711199976f1f61fe5507bbabb40e973b9fa9ebe015917ad52cb0302302a5460c9f0b564458f2dd170844eaac6aa45ad1b5ee6ed39b030a275896880dcdea940941cc0a8c710d0844eaac1a8555affa7abd1784bf57412be109a461d689134849c3ac13279092865949274ea0276a7777777777777777f796ef592bb1ef592156be676b9789e67c17f5f5ed254c209d20f3ed1c887af1ed2854b0f1ed2b4401f101af7e5fa4c2048152ae647cbb159224aa71eacd7735ba78e1db03608bf89a788b8cefbeea60d08adcd92696002555afbabb85dddddd57ba0e0651ac332b09f5ccdfeb237430d7dd2dec060017a7ef06028d6661c12b9244ddedccce19897cfa9cb35b34b3cf592714e65cbcf35928481259b742ecd297f93d6bb6c649912c5e2bbab464cfc00cc49d3d05a65af6d96baf62316a1f49643d9728410eed8e58869f4758800ed8d352d14b8c3b47bd12dfabc5a396181c0da820711385a487d21888cf9e441a916859dde9f786da308df0ed262afc6e63e7db8d956f1761f7241a79c208df1ec2f790148e91486a961569d4c260910d550bdb4d5308c92c4db3a9ba861161bb6e89346ae15311ada9442277b64f20d5acf6a4132489eed69dd0219d40214a0c5ec26ad3c82359645d680832f8bbae1f64fc9a12c660c4749fcf97c20d5292b0aec9fa06fb8e01c7b77f40594032031d254a43a2b860271d434a22c2a955c20f4b909284b5a82658ab843f4064428241a4a45acfd62cf97ce68b108d52118d0b50c53464b5cac70c5212f1ac589b01eda5048d5311c71725a5a3fee0db170c2225d51745b3269f3d97e2b33b49a26846c999d267474b60a105c0903029222508834dee78a72b67c764101429a90c58ad120a7f8614cb34c945ad24190bb3e3e6941ec89e9cc23642b2c40e269146f7c8baed6b6540b27cbbd9421f01909599e98ae342c70c3f4a2b6a5728192e5b0ae1db7327402c4616a3d4952a603e5e682899210eea8e43a533355c288975600202a982d66d15b4d7c22c2152583dab6845322e6a5516928f914b15603f35b0a9481ea8f5fabd9a35a6ec6f1549a2db0aaf67477324090e3d46312daa804f68b535cbfe90acafd046f5282b0ccd677f0c9037e1dbadf90dec2a1cf62c88b0f6cc8c61ae2689fb0af55860c920685b6b4dab336bb5f985dbcd1ebfa89ad01954807be01ed94bc3b991362c973d71f643a1c20ac0aae099f5b1227a5784428522d184307855d37c3f60958936bac42c1359289ae8e6d01690bb8b428533ac228a26ba66d13e311d850a3bb03faa7b4d9b0249e2de6bb4dbd9dd5f9bd006efb144d7512014bdad6085de591b14f6853314682b58ac3314f8aad044b7e73a079f0e423fd735fcd423144d74914c90bb7b2d9a75cba5850c9238c81b29902595ea70381c0e87c3e13005b2e4135955533bacc3619ada6a87ee73b92976fd8a5d55d62e195adf50fab599365bcd5633b3fd14cc5b1b15e98cf42d6a5b8b31bedc6a6ab39761b52448f24d4df36124069024788c9054498a270a234822ec456dd43aa4126d642289bc42224990569803e40e3b5981d3db35807352d73a1e0cc100e9b89bcb325f1d4ec84f778c3d80f3d335c0e31a5c03e789f3133bf15a4bb4597762e7c138dd877c7515a81f804e40ee4c6c81e40e635f1a52da621b810892bec7681c6c56ee27880cb691af92415d894b8ccd27f344074bfc3df67b0b123a1d8410ced3d357908e4b911e00016bb48296c73f2f8fad57e1d563b7424812442c6cc9601b592010b54020096a09d85768a312b4f9c1e04ba1885a27714142400e42e883dbd3e6690c6cba0f19e901d5c832a944d871ed89f605a2c52283401fbc744b04bd4b3f9e731b86dd928ecdc768df180b6dd2aa9ac0a31ad92919e49020390462a1e4f72cf04305803c750e7cf020b7e709107eb320842c31b54dc880803e9c3837417ec039d0799e38e7710f421bfc4708750e4237f711ea71b314aaff81503dca9519db6213613f7b884d84afc8a075810c5a26643193b9a821918c61950c894629507d8c71eeeed3922d902d5c23da912b87935c5946ae19b62d69492bc55a3213f6a6b3694ac2b0548643e27038240e87c3e17068a90c87c3e170381c0e87c3e1d00eedb00e87160b493a4976066e354ded705887699a0e87c3e19084613fb60328a1bd612a53b3e4775492f9b2f4744844118c2a5f8ef8f2cb8e9c305e84a0092229c794a527d52df58b9772a82c7d0765e916e8e6cbb22c4f2fcb12869a3fcff3743be3e49dba8ae68e596938318f732b2377efbdf7deaaeadf3b184c1a0c06d6b7db1827af6d0b27afa46af31ff8254994f80fdcc230a9ca7ceefc5c2e97f394cce5a8921415ed14bf5fb83879395d458ba868bc070f6ea74e9e07a9bf75f8dbed76bbdd6e47aadfdf6eb74a76c3f9ed76bb19bd0812c28b2e60ee85d5e3706ee23c3cceadd4c9c369102162c4948c6f2953632e822e8a98b910fb761b75f2bac2f8f24b37cb305fba85b24f950c88e67f7edc3a9dbc1fe097efd0c1cd0e8e76e8d0a143872310488b9377dbd176cbc2fe4e5e0729e3fbf8f571db74f27ca4867c4f4f4f1dfb9e9e9e9e1ea73adf4f318e4f6846aa282447a9a56fb74c27afc90af663bca105c64986e29d292bead2c9eb717af11cfc7270abe2e471887aecd76c232315698e28b99152763cc28ee64812a5634fb1172d19f1d86bafc4638c718b1a8f71005cbc40d2e6eccc4e1aae5ef0cd31c6f8e8b4f418e3da0563dc838b7c4f8fdb1427af4757c3eebd774ca948cb77f24e1652fe7673f3c6c2c9bbb1b0f138a0c7790f4e1e6e8bc3cfc587df909f0cdfce831f8b175a626488a3a6ac478ca3d2d1d27770f24a1d9c3c5c8dbfc1ef06cfc1c9dbb004e76de6db6c8eda6cb6d26d36a6286fe3602bc10f609a1e4f44be3cb171b139124902bbcd93ea16e1861cfc48536347f049c80e9bcd66b31d99c09a7c7f1d073e15ccf7d2a53a442b7a7caf30f3ed2b60ec3738797849cb9700f8d26d70f2ca1a9c3c1bd3a37e51a7c1c943677cade666cd519284d0d73cd746e651ed6bb8a836e26b256a8e449268af7952dd92429cafd56ab54aad56b3d56a8ee56d369fc1c9b3cde0f5d76570f2ae8a1e5f961e031539568873844b51cb9a232d8edad17615725fe30c3d7618bcc002df05edfb9b699a3ca6108f5b0d42491a7460b9256394f8cc9afca004e96ac19c1b0b2ebeb411c2e307644e1a170baec460254c0db1a53969ea94d52c3d22558c17a93a433b47152cb656b0d441825459d124862b8dd6cf674711e4992a32c6a2488f364f53585470bb42423709889e404583098dadaa1d488eb2a3d9739e028b663f4192b8bade7d4dc7a3431283d6ef55a30c1fd45048922d3457d7f322162c14ec4c21e6f218ec497cdfd4ad224b49aeb696864c8e7ab7877d2cccbca961a5f4a5cc510fff9ec44014aa3c49a3830b9a0c6fea142cc4c41e2ee2281dec200248bfbf27a8247596cce8f1c46ac851ef029ff45b5504abca9a1d688471701cf56ef0ea026862693468e4182b73d4bb50cccbf57423d14834147c3e2be370090a8b2371a04039eaf5d5f77a8c98b0343086536ed41cf59af8a43f0d865491632683498e0b47bd2eb6917944f6d931858a9a010c403a49249dc47a32ab7a112976198b5a6384e9a847722900b3010184dd8edc22f48308a60d8f385a50473d1b9680ef59321f3398e0301b9bd39476d4b3670860a1460bac215d9ecc71a3e3a867d35038d3a1432ea70206394fcc90b1513aea55b413584802a60eb00519271c4c473deb33c10bc61cc81020b67076c606c697198e0eb08121644c4bb2ac21d254a27a4953726749931c413a4746790b9259560ec53869ba669ee0e475d78e2f4b3741f02a6803d6487c1b608c8e0d365d2577b512984e02d20866e3cbd25330db67bb1c71e4caa1610422f021f294a5505f9921286a09894a51648e571598026c99ba7969b39904681fd16579136aabd20602d33f60cb2d3f34f495074028215bf3e592ad2fbd03a859d6b880a11cd84059ab3731d96f350d64204a92295f4a6a7ce91828dbd635efeeeeee36fd569aa509f2026262f85acd2d6096b501149161e1a9f555ad56811327cf66542691fad22950d3d96e5b0bbb9b0b1bdcc409e09080f9526c48fcd22560de04f01d8031334caff9cdac996e82bc259dbcae27e098dee61120a59447d47c49c29748aabe74089cbcd2344b9bb7a32588207373abd5d37b3c5ee3d1557257d3f9a9eb99385d0fbde97ab9ef07d81cc91ec1fa72005fba034e5e090462dfb511c98591c8358f3126e1b12791462d2cb3babbbbbbbbbbbbbbbbfb4c9d2f2f230c63688ca05993c6a8662aa846a8c6ebdb519c7dbb0aed2bf87e6bc00063305285f60ba2917d7b03aededa761eb08d3a08ecee16768ff0a5e2312e6d675d75770bbb896a6cc0a670013ba42c238d281fa190884f3008c607086c173e3e9f9330a96e99a1e46b615ff3a39357abb9f5a412b744639d95682324a424059c3c538851c60ca42461a5228d029e437d72717e5dc6c1fab25491e178703296cd8469da69f9ddaf5054d0e810a6c1349a75d26ee5cfd515d264ab661e9eb87673a84fae0e570662c24eb02c965470d429ca350d26b6659933310319aeb1f0e2812a2af2e20c3ed4eb089ba87ecd4910c0d812670ad38a2353476589e4cb322bcd9765a92b51e43b19d28a5bb88a1b98cc9c29e409638c7f4d54bf244a5d9f1c9dacce2695172d035713d53642bdd82051279f9c8f24aa3f602d8a91e37466620e5a1d338596564dc8b96ed16a2b4a817a34d645c65f38cc5b625c6d9398dc75e667e2a1164f7fdde7de7bf1edf97ad4b2f4e657e38e27706a191f53199dcc5545c8912b875d3155844b330b92bfb7a9e460d40abbf75e7ccba120681197d098e52a8608112514a958b2741c13a6e286083a25905143e548064c450c1125a455059c3b747c7c4e298a3009e10b54980d3897392dcc2aa175fd44349565e9a2faf2abb1c8915a0b15c731ab322ad6f7756595afcddd5d66be879cbac6be591cf590d3ed8ad28515f565cb12d0d7e317235ffb7afc72055dba63a7ce0c4ee36d5376bca4daacf90d4172a4caf0a506930948c69840b1b3b423c751d311d3e48d62ac18c560cd618106c76891cb52f72637695d319bd06e939bdccfd76316396231f0ac4001cdc4990439278f145dc6a172c9f14254103066c4aca39b46766f346dc9c2dd7a976cf87befcd3867225018df0b15f517eae8de8b2fd4d2f37c85f214a39655d68c8d5805fe6133524e6e53f7ed52ca4a8a088fb434689ea88101479a2b72b03c692c5f30b00c73e7a0cc8e8e2253b4ea94c5d9f26db1c89171c6594eede28c31be574bcd5fdbdfa8b2bf4c47f79a3e5f8f588e5a62820c87c32171381c0ea3ec30ca56190e775ea54d922459206da3a9d936b990d7fb5e37753757f99cb3fd6c9aa6b9d584c7cced84561f7297a168a8c8e1afc72d2033e013bccc7078d4b23cc9c817cdfa769fe3d69cef1747dd7dbbcb9fafc72d32dda3ba61a189b8b5058d9825749c2ec0e60ed81d31a90f5f8f66763e7f3ddee9726131896bbd8e75b5de5a6db52690deb3aebba4100dc857000bd79270aa05be96be887698d65cb1a694e4a624c64a95ac8456312de43c7c3d5ab9f1e8d7a395a8ebe6d62bb2adf8ea267615855b4d2b7a736d8cd16efc74a0d6ab490a5572a7e1eb118cd4dfbe1ec12c914c50a26a4081f2f1b79a96176347b1fb388999dd7ef64b8adf9cc7626c7efd33a71e3ff61c5e718431ceb87f3710ae14b14f514cac76138afb7adc2af2b7af4531aeefa16e5564a22d348b724526c9952bcae54a90a5699a9a6e5ecfbd09f4fd35c98b92e655117aefbdd5a299a82d5a74475e32f8a645ad69afe5324bdcb7e65f1cf6a615a41ac3005208a1189d48f998f0b8e9d579bcba59bd6ed55025db06a7183007aa1e9fa50e3fc63b4f370f40721f3095c62b142423ad82bc475e0919128f36b8e086fab412fee9f7747b3c7967b7e79c240182b7effa4693ef5c77b79f08a1db5350faee5ed340de2d424bf96e35dd6e8590bb33df9da60cedcab77d63d37cdf209e88bc47527d7b258348be43b4d73e6bf71ec17b6494ac6f27b976e4f8f03d720b194682f7c837eded83faeeee6e11de6babeff61d582f42845be3c913a1d3e9743a9d4ee7b678f2743ac29e04bf24b87d72f24808e13dff105e7bbb0fe164e87c88102142e8d0f221dcbe70f242e418f323f81dc1ad93933782bbc5aac71c299e88c86d939347a4ab46274d158607e1d6859afad7a77ed3608f4fdd32397929169bfff0e1033187e3c5ef766e979cbc9daea2663ecfd347fc79fe9c7e9ee7e939b23fbde8ea4fb74a4edee9f52288e036c9c913a18bcd0301b90954c203b91d9e3ca01b4e1f42086e919cbc106c88791040707be4e481608db4d0c68e1f22c00fb9159ebca1378fc3e11cc5e170b8a38da91e9ce3fc040ee7dddd4de4e4e188bb21355c7c50081f04444b112e35e45c313b0a3afba0a0209c0705f996043ccead909387a3b1d566820029a211f542057821b73f4e9e10151e0f9411f2c255982e32aba36bf6f77a0ad403800f5dfed6b3d3afef204df2d752550581e8917a08e1687f6f2dd34261fede5bcbeebdf71e67b4b8aac72e3a1e7cd4a38c638f9327a4aba869fbe151d5e55debddadd5c9f338c40f112244881076749c3c10ba8a9a41b50f0a0a729be3e405e9ea31860ea34fdd064f5e7a9e278e0f27fc07b7374ede8716683c908807726be3e40169a5781cce4d9ca338b7354e1e8e06c905e3499ebd6766ebd93a0b32b6f97ead246440deb00432aed6136460df9e11a877ee6421ac2b561b6408c8c5c618235cec28316303c897169872f9c387d22f07e978bc0504e38ced0f532dc3a28dd81a343649b48efac7f717271c4662c4af472f518e5e5cd806828fa4d84816ab586803ad472f4011287cadfe44776258d571e1e3f3f3737595cb48e5b8fd33cba0afc732303e4c113e7290a1d2a318e6c34a75aece5fad7fbad6eda3f3ad14f5edb518963666798081e182eeb8e971f51b03a58cb5da51abec681d3ba7ae3636879d2c295039638c33cebd5d1187afc633616edce099a5f3ccd4df7b2fbe3953e8abf18ccc5997efa17ee6d6dcc2e288baf3ed3e2a3a7c851205c3e7af50a2caec0d7bc396923b7b3de4b061838d534eb362c809ca5299bff83add124a0a1996b6149945e94ec488d4aaace183c43d2a8b764539bbb3f6e90ad31715aff8aa2f4b7973701e637c4b330df5c9d31bb29c84e9478b8b56151a59ab49516bc6e7af452c6a7cd40be40eab91c7884f3d755bfadd6318a8259fafc7b1393f668c6d79cce308e3db51c6881eaabe578b98c8f1ced29c293eaa2747358c4518291534c044616156eebe1a592cf99eaf46163cc2e0a6f2eb71cce979be1ec1d449c5d25a388a9dd9b3b4cb971998afda408e567ef5b7c3876c53bd683d8965356258dc542c5e58b666e4a71c58085f8b5db85c9983cb9b732e76d1caf816bb5cbded6bf14a0c28e904c6718e1c221d4444f85aec22c3e3968a5eae14b1046bd10b9c2216600b7655005f8b6239bee76b110b5651edc49959886bb59ae955c4386c596559ba961f2599437d725e41a9305f965419e79a16aa0e26bea696b22ccbb22c6bb55ccb351c8e6a015ed48497af2caf97198ef3489aa6a9545d61e2ab8a8a890d0a152ecbd20935c1a55866bccb9d4243696a96392b58a3dc485313e3aa8ccdb2740c06a6e18b0ca00623bcd9f09973adccfc3061b83b403eb92f6737c75eab62677eae392634b3310c19d9af348a713d98b38c668c3876e4c163671d26488a6571f0619a2611f862555f5953378c2c7f7569a1bd54e1af185a20bd9081adc8d7ec02ec0af60277090babaab5a825439aa6699aa6452977723e4e6813e2cd86cd2952b7c959c6184792c7aa1506272d9a9479caf1346bb6bae9425813558c316651fb4dc98236f9bdc0ca585b3be8fc7aa6d2344dd3344dd3344dd314e8cd59b322bc7d60db3acb9949c3f96ec8b3043be4ecf33acbb9f45a69966699734fa5f257826f25ac1ab1a0e5ae1f2fa81ce970ab109ba8f2e4a212238a702de3bc453c7f2bc803ad729021fb947c16b15661a9462abfc752f36b55d5125e8babe6a8f87064119c344dd3344dd3344dd3344dd3b46a0ad74f09fb416cf250b6c2be82642f85acaef928d5289ce18b6875ca6ccad4ed9cdced50235232b269ac5dc1c867a69316b8a402bc8eee7c6877146630a87e010d9791c25b8d46e444d9370aabaf80aa2f08c97742e643593c58a52936b261eaa9e136bf6f033c43e4c9db54d9c0c83ca1bb9c9f745f8b596edcc82c34cd5bd60633176fb62bd356347d7235aaf0a5ea826647773eb4b3c165aee81b5eb8ac9dd180bd065a995b5015b3d270d7465a4e5f80b242cdd340fb1b4129adb7112cbb7165b62856f91a591578230be39ccb5c66a91b2e785da1d21549d3344dd3344d5314cda6879347deaca4649b0f2ee7cc23ecf66383f2db91390021eb60e5a4c7479a8fd592bc01f5c9f9f871e8a7224ca4863abaf3a11d905fcf55d6807a0ef5c91121dbd0a2ac59054d9ec718e3a1dd5f55e5dcb8ac5599a703296a90aae188fc78ac58e45b8fdf69a522dbacd27033d4849cddde984388363565c98358cb623f84fc8f61d4afc88c12454fb72cbbb00fae32675fed0609e6a6626bf39a3dce6e0bdf0d7956d7763c31c92fe2abe51c249f6abaace3e2bac4c418632ca4aaf6428268de212c31c63d8a457ae06e085be432971963ec3e18639c31c6106093a6699aa6699aa6698bb0620bb3273307d0d6a28d548923aba6e494759c994f31f035775ce11d5044a18bd7f13bbe207d72c126aa5c60649df941b226aa4e30a4d5c701ac348a5b30ccc80081b199336c96e50a88c0ab3730f8d001e50843798d297a99e18cf1cf7d08db48d322179f4d577fa4f9f4152c7e0531b125add6105f8b5b42d2344dd3344dd322961da7dd9b2a5b6eaa9935d7a46e26ced52ce1006b66e9f565f9a50ad3431cb3342a9cccc0e11cea938b232c9dbc8cfd7adcaea33b1fdabd39cb5d6de0786d19d224b8a5451c238e3305ca8887463d87fae4e090e1dbe424cb24df14b310f1a24eb8782c1a9ac0a8048d5ae95ac6466a80005318000083501c89a22c8b92a864a00f14000c41a652544838340f076371381888511444411403210c83300c0529e41884aeca06931898387133894f5b5514aec0d1d3401bd728efc38f11822edf8fc7463d9659bdb74c139238599ff08825bd2cbc33aa63b75dd17c082d034d72cd875794e2d5d578282d9745ad7b6416db8a331d0ad5490a0caae403381da32b23b9af0ce15524a9d082b288aa1a80ba2209f11032f17c61cdb053539a9f4d41ddf217f9e27a66c95d368ec2da7825da81ce5d741d72b705d3075f6406fe30e7acf3c6d8a211985854ecb9f77277a3668d3e0a995aee628a0e42b5a4e588dc0da4dff8abef7c33604dc280ca47350c824ecf510ca65a5edd867b8ca96a18f753db2c59fb5403189399bbf700ce19eb8a5bdf80c453cf60be202a52cafbd4ba1aa132889e42cce087f538d012b74a5f629e9d5ed32bca516112d5a852cb8acf946f0bc7b836fc1a0456dc92f58ce753c1e83053b914ff195b115b0e61bba53b1d1e32d34ffacec74a04241d4dc398d72a81fd089a96807809cf3af639f12ff564cddfa137bb01a2b00a5b9014e5de4140d3232775b36373286d8528e738f24f018132f16e5b07bd64380f4304054ceb049509d869e6e41e186d9040642cad45a659561f8a56c4302ad409de29124c7f38f7a8419e75e08c72b7683a24c53ae7ca8d320caf3ae3843ba973ea51039531e81133cd90e31b206cd9909bbf243662edab2abd54581ceaac2117689cdd7c3e0ebdbf9b52e6c11b3e6590a70716c9ca985ff60f6f8bf56306876d4a1d7c39d9afbea8991e7ee6f0f112f29205161410f0f1e9b620b7d690db6ccfd102260538c64b209b48bd94dd5e144435534fd70386a6d21982ba3959e5ff2432808cea3410eeb203631a533a44212177a7bfaf7d7d78e76691a480ea766fe15cdca5560547639033d7cf91666bde1db4b2e85654c8f466a572265168b9291286e0f5d09c2f4c38375e2fdd1ec3fa473b82113328984a6142576c549e13d1e9deb749a3d4319bfac7b14a38b764f1231c4256e14d9abc38b2afc0527ff18da3bfe4e0d9231bccb14d0cba7f9021020fe2794b2d6db8317b90e61bb973577bf8740ae385ea13d4a8a70ea65011cb3f5c80060db303c8e053ea19f1ca4ec3b1c273ed655601c2c29b4134879e156d9da1dc54cc9a055828cff23ca4263838d148fd3ee160639298991648cfb380516547e84821bfe2b600174ee20f5ba74ecbd953ba80041537c7c0435bae8a460cfc0ce0b952ba605b9a088c7c12a6635c5eb2890a4ec9f8f9df8a492e5a3ab0964557e276f6520f8cf05490d2d59589534cdf4b0161c95abbdca7998fad88974c2aaea653f37ad61f95c184a40e47952173fa3d2a04b01181aa192d08bf8b5b39ed8f82ec318b0ecdf70a7173b64c6539f015bbc2b9080f7b710ea80b025bde728e9417b901b289f802e9e175064432e06bdd90c22b1c2353a41b7b11ac2bad2c949d3f4c97746d59efb975c9c13490ca50b1426d6f37e690b2572d931af5d5bcad944b67df51f9783dfe94a0aac189c0aa601f8bf7c100e153fb5a974b43613891692cd599684c1a6da42586758a06a87ed143eacd82bac9108a25b45a0fd29ae9653ebfb3aa9ff5212d12e34b13484a1061d2b00bd3a8efbde013e4f2e84456b81c2b1ea4174521ff1c8614773f90dd8a9900b95e2e47ad042914ae80f7a89019a973a8fcc75c385c35b0ce43eb81a8409bbf655f90a6529a1efae14fa47859dcc2dccdaa522e560f79a096a3614717ffa626323e5363fa1c44c19cdd7495056074dda62cd150a400e65a2a994dab63fd26413970038a64cb50d69e25f070046dd010f7b2acc50d60660181c907f9118f7cc42d1d0c8d00859b791aff73791c7c3f8e6bfcd07fd2a84b4c0bc723eec2ad76c502d2c85136e3e3d7e5bc930fd18a6d50118c72d49b1b88f1a2347067612e5db8c5e744275ecdbddbcbc0189997255322e65966e635599334662b86cfb39bfb0600327648cd283f375ecd9038d726e828008d510ff82332c04dd0c1444720fa35c8dd9c3f975c6044297540418050dd0a5f84e559d454c8e7d549bcd257c8739dfe3118379f26d0942d26d5024c0cde13bf706dd8b10558204f4461fd882c984220412b4d99a6ecffc589f673f8834068f0c37e6b4370ba0a17d178670a486eb61f05eb0f0da213036e2b77c1b8139a69e04527c2fe121438eb2ac18ad41d82bf5f6c6cad2b2fccdeaaea7b61051f6df4cb8bb75d56cfe0248d1ea26f33fe941ca0a3e8f8050bf681fe8e346d07802e3b869c143cb1d10150c478c65749767029ba70e037be07ef059c17b2c4bd5c9384e56b62d90561e6f912e5bc714df1b7739bb7df0e6e1b4436098625ae3d38e7596890694760cf6e94655571675a2d92a98cd4a8bdcdb4cc3ec966d7cb2c075d02d9f1960568ce435ec3e18459fadd5323d9656a041aec9e8e251dd68503aa625c05383ae1aeab2eb90925c1b891b1a95defa2fb9b27dcc452b97b036ffcb400ae6839dc90e0d9b49256ecbcdd26b7a9046febb9836f181aae599e64d76dc36ea5424bbb72388275d058217fd09605616bbf052a84cdf5a3dfceabd2bfec9532ebb03b665334971e25dc12b5932348f5973bec319522122c620fd7d5eb031b1a8ef8c374f83eca18d97cd6ba6b7a7ccec32867970e352d7bcab2500afa28ec978d804c92705aabc218309d8d69e6cc3749e74a77e9c0f33dc30475878f7bb061669b61b84634a4d2d045ca214e2911fe0bea8cbf1bd27032fad8c895167b5b329e668af15a6b44bcb4f6b21a7ea25ed3782028344c7d8b8b61239e41035a8524d5041bb0a25374c58f838a0527583a9444391ed5c3131ee4ed306c0819075d01c07d8bfb9b794c6c3dee60cf2dd4dfc271f20742b9fad98893df16282979e1186a590c8de10da96f71776efee37e206aa41784e0be3ee03fb89027361c68db6bb23dc24771e8212409ef610cd12af02d2e75ff3344bc33cb3d43a1fc3e0a250f4c2c3f0668cac68f5451c4d75386c8b7cd4717a251628753b81ed20ebbe2945dff025773b876b2ee5bdcf9ce7600b7ee85721d5588af50aae42801f90dde575cfe983782ca779afab62c378a5269653c50947cabcead9020ce9f2e339ed26ff77999f1881f2fa90e4160b8a9497a788b5b1e58230c4397a8344f026f2bebdf7af8f9e63e829db5e70a37f9a7610d12f0aa02de2d2e510207f0a93245dacd9aa3a32f55490f9334089055aac4c080ae5bdc0b026ebdd6bf3fa866b3c037de651b35a25dd1782cf727e9151392f1681cb623e322ba34becd58bc89758cf248d81a1362282eeebb24098bd949b9deeb7fc948920efed38adc9360d5718c43a0e5289439a305eeaa821e5eb4a85b63d8c220cc0269b13fd408c38004804a2b9c98ad8704c775684fb14e8b0b8344c866dae9f0da18942d10541820b464dce61637afb2ff81b7a71e9e2024b22fa8b7845482b4762df97084dc753142a32fcac33c86653de3bcc35f22520c2de25c426020cb0babb714772e2ac98dd6ea5f162b99b75b5cca57d83d75235aba14106e49fbf32237fabf77753da91f8f985ac477766f37c64b9b02db0add5395de9da90ca380aeee064ae60085779ea25a97b22cf6c030b37bbab3d4e34b3fd812738be1e4c00a459af4b0d4207e03b1ef4e1784bcb9e7709e5820010d68ccd1f347eda06b36e3725fa74dd7b06dfa5bdbea796318b2d670bfd9ca8d7eb38fc4c9aa37315abfe30854c04e1ef516979ef22eaccc966a79c0219dd9b86105f8c01ec1491efd2d5e31d713dc42700732b4724c3f711166b7a7a8a164696824ed95f65bdc48ba3111f3d246df8535aed9f4e04a5b937dcdd5562e5030675e66ed6b603fa986d8696118a92d40a421d6254c9e1ec44091005c3eb32de7e6978998e443b3edbc297f065afd7f9b63437a0d5a2b49803b28f8ffda3a214b88c0011777b3209b1db37d0fe379a00a7cd01a8daf53b504abd8015609a21485fd1c659a35c21535cd0e5ba1d7a83404bdc8c1d2f23bd1e34c012d95a06221acc0585cc863fcee5091b532e5b6633ba50130bcabd21551a44d6b8a8244ecb070661bb8b89f0351f093da4c70ea094976201d8f1f61f02938ed504b8d472c0e64681c6496a6831dcf76da5ae08141e6f94c529975a7046406c4c5bc188428f7655c9e263e7db064901b07add46606aec578e970248d2281dcfa1c8900e2b5b52da3795cd3ff752b533f48d46a15306d5a562d0a0f948737b8b856067c81ee2026e749fba154c7d3a549fffa1c389a5237c7bd0dda2e6aeca871b1d6865a3b104da2f05d4fc45a995fb176ef8866e77c70966b9cee4df4264ab89e439a72c16bc7b5ef392ad9d67d73d66509d77248531677c499950700ca595138b3926cd19e9413d35dc29195e48fd02898e73796586614a5125cdc0569f89558749667fdb89329166d94a6113993e14eea51953427c152ed67dbd82f6e4da8441ecc330faddb24405ecd7f750dac81b89a4601a0fb01b3551f6c65cec7ecdb3c9645994066733e4291dbfa41671405fcca8e3f608c7580b4bea515d97eaa20c2e617411966fd370d157f8162365761db18bc5c07a47558c7c9d85c4f32dec078446a9e073f9927b808801df2756d7163d4428203a9b9684d9aadbef833e555e724bf811df37827fd910ace46379e0a3c349ec1ffa08b0a126e5b7bedc9816eb8600aebf08003c04ad92363a77168f3223afa3b8749143f68b0fac0bee5fbd971309a2ed164320cb4f682fc00318520760480abb85c030018d4fa92af4236406714ca70d2c1ef8c45f0660e788c51bfd2a4f5164315f3d8935ee7758743a4a15ab41a921c69c402908d872a9a9e06900b93a9a70728d68746e875bcc25080b42563f46526b47933bdda8c77fbe44be36d13b0975952c17b0a0bc7b5b5b99b7a32875bea10658084e8beb7cd0605025c873a872774945f097fc8ad976865e474ba73405c87ef54299348d30557c0e936724f8594121bcd039fcd35fcbe61ca6387c6ead02c8186450244c2e4f72e3cccd39b4175b5d028c8f37e372239a38cee027156c1206145cbb29c33706331c477de118384e76a1b4181b57f5875a4356d047454dca5e8f8917a95529dbd3e30e5e28ed62872c34b9f030c12f63c52dc130d497d6f9e2f99d6283eb39adf23ef2ad705a77cae41acc4d79deb5506246caf07e8736457a8a444410aa8bca7b00517e3d4a3f0f34a44b3bddfa69a6aecc065a4a23394be4c00defe614da75b9544c478616b80df486b2f7fa4dfdd2b516f36d1170d5ec514f83567635ae5330b76e0ce86b1fcb89a8b6e3f06b708c707a16ae9a16992a1fe2a0834c6b32f0c7bc849432c5e8bf5d9f6df0e5d09ae888c128135d7092d8ed119bc23c96b915022018324a7c76a7bf6fa3d1269b7e3416a67e56b1a6cc82a5b23bbebc7e3462b1e3c2c16d6e9ab8b941f4b4045f85d200c06837564b84598aac47a407b79e7fe86433f7b99e3f786e33f5b0907f70627d01e8583bfc64983fbb3f82dfeb7f70255bc347f4682881ce1c410dd6311e5a310ac291f56729c71e541c17181ef7e1568392cc8f95f614910022f99a43f3d7a5b4333be31241c5b91f4789bde64efcbfef4ba9906e7abfa52d503af4dd4c1fd44d5f8c220d5462479b7ee809dc48d46e9fb8b228b0bd3d9d9c7e6da07cd9db07be0d47094f17b19dff21f386cdfb205269edae2f84e3c395b4918156b635cbaee26e3c1b37cafc182f3022c1dfdc08b7c2590bb05b39e4dbc16ef4edf7693766a79c23b19d6716f37ba07b0b5616f99d6d021dd37dbca5a1a5ca729466ef5854878482a907000019a6cbba1b0aa76dea15a951a9aaa332d4eac738921764ce4afe54dee1f479ad986fa9f39de85d52628d7ba84393ddf158f169f8bf08d965c2071248f1cd630784116a9613c7ecd38f9f0594fdf45ddb3196f6bf9acc3b17c89450e251c71d4bfe9fcec2bf9a4270787e4b76257119f6c022399dee9b6fa5f57cf18745ed0d8516742ad20ba96f95d0bc0eb99f21009cf4aeaf55ef72444a244604fabecc9c0bbb2ea920c416c29ad8acd85f672c68b71929a71fa85669434e3187af396d566be4de247761dacf2ca00ba3847ceac953e7e8672eec78927e0443b90a456ed5b6853fd1922b95107327a06452112a69888012a02872d8b39bc83ae8970b5baf4ee59748448389b0fe064793ea3e680712b2d6aad4e557bf888f4015df8dd1ac44161623972abb25beeb93811b4c8c3d025a8523343b02c2012d69627e00ac99697512ba968e53c3eebae3e0380cdbfdab43600604e9b20dcdc40d1027cb3d841246ce75146a64298b8f26f88e52709558f8f9c694d9e650cc113e1e736e5a201505785f663df811bd974e1a9408fc472094512e93924613741240cbb5ef3cf9f6c5f59e45cbd8b90ea86b94223e61aa1df44200da0093c72f09b81654ba41d038eabbad5409d6bce107a852ac2d1f5599ca635c56011d4ce934bf5816a11ab917824d07fe3fe999f73a626ce8d8489e7992858f479873d85ecfaa8117c0656ad7616af3d2ae8f9992da81bfbb947761619e8c8eecb04fb07e32d290cbb6a0ca98825c408cab611ed72394416194e6e98ac1216755a03342530ae44468b8c0061588704a61c70164b3c7f0e6ef033368bfe2e71ed346618614ddf88d38a0cd983c46e63ffb3dea332d8a2658d7a8449793bf39a35fa55419b805db3d6fb6811a7d565bf39cc63714d334afcfb65735f15cf2074311a5b7ec0cd279556e38bb0243ed8ded66d51f936042e494db2c7705981a677475c76d51b7a76e643c2ce4d6446291d7553275486e076f38d12ed69009f52b244edb811675a335a0091301cb7ecd69522be1c1d3857bd5cc578f9355c3f8496fb0c5678a1948648d8a84ac9730712561553f18aa6a48b1e6ce91742d911380257219fb24f38e28002e6ee8a2263cf2ae751434943241c430db69f1be9d71a39bc3c0e794272c4905a81a064a4ee98df244a7b1ab548186065483f895272217a65c6f3ffb12653d3684069a4a8355acd67b3e4967f1bd0879399fc602a98645f33698ed48080e931534336d50669e13466757a566c477a2c5e20b18852f2b38663377e9d37d0c4f6e312a1aa5a56472c25a183895de42edf53987e59794a9abd2003678e9fb94ce21e66595e12763d0ee9c67a5e728997dbb9da48976fe2cebfc6488d43d72bf8d9f59c63d2e1028898fc7181b8c14cd645a14e0dc83673fbffa739c6219b98348c505befd3d4656058acf6a8c9de0188840f1d09d7f91c3db251ece9aa1934754764073b3a22479a29da088f000117456a2012ce2957aba1db2304525d1b9ce727fc43a3faa40842d2ea5937b8999068d79bb8e132fa8781ce3fea3ed98f32314c29f8a774a5221ccea2c45e8218a854de9df8448e88b485a18456406051ba95912fcef53fd23c952dba0ada7a6106af2e50f7b45b71e3300e6b79607e7ea0d94800b20318d7513f4d939442836a74dcb68cae0a9d5dcba47e900dc369c6b60d289e8b9e03d8c5f26c7788a9bc10490de66430748bd08d3dd3aa0c9abdb38b452d417593d01ff510638bb46a959bdbe941580c85aeb303030c269d53fc41ebee8c777823a1be8213770b514a5f9258ecc964c0ac186619a2b1cd722f896c944ebd7380c69f7e2c94a4226f106a0a8f68475a600f55259db6e98d2028ca02c42011e868301ec4ae7e0a7941e7b107b8421a20887d4324715809674f3219185fbce5e2f49236c4d925ce964b8492b9deb8f5b05fe71669d8d3f7206c19b31cef01e4ea4c56ec39674504620c054766d5861229f82f645a310b7821a3d727db1c8e805d0a32d601402b11a6854b23db71c2d272278a7745932f45077b10a6fc4842e03277ef138cf8be85919d08bf091e4824a0837462b251d6949a76765f7f580000960cbc28cce3bc52e04292c1353d17331225a15a0dba0698b8da9a461115d68986bf4bb99ac522467e6a898f7f3b0ca5641f93ad9a815cc30cdd49bd796f9131cc6fe8cd50e03d64849781a45b7130e032f577643764c52931c84040428283b0f431834ad4fb7cdc08fa0efb0aeaa07368096e24cfe4ce21b4d9ea914a5ad813854c283ed6707a70331552e2643fe36b35bb3cb8f7683afb690cb7ba79aaa692a2527ab049c4c34ac7f12157fa0e57db45e4db057a682691bb1bd352d9d036b7b58deb2a09cda0c49ff4d3136cffdef79849d0b6878081f3f7b927a4fe6e80fa0bd1b106d10c21b1149552dbc0d5fcba2cac00461cac40363cbdcbd92151a4d4423d83f6b1742e8a3cb5612c92b9bf0922443893c9369545535ac459d0623442c339b1f0322cd00c8f8a5a5402a9928cb07ce408292122bce9e769104f1a7c3eb03216e309a4d2e3cfb4f6b6295d50b764dac31701fd9dda390b8c4696c65c01aedc7e1ac42f2bde864ac1f981ace3bfe503b7de537af4b5b2fcb0ea121578abda55b5b2a5b308e021f45424441d1ecb01bcba9be9245314a44016f6b400539ba8fdf9ced025e2d9a97489fef292885ecd2eaec924266d4b115d7fe5e935ea21fdd5cc60e45504987602b6a2ab013eb71896b8fa7cba46cc68a34488ec8270942106e81072e8b1153e15a3d28ba73fcc417da6ac20d0a0b40f63e33b9de9bb884a41bb190363084f58f639b6d42d52c641a23e610cfc525f165bf7582017867e13234a28b2e12dbfbe97059603829c836073ac3391e8c54bbeea65f3713c61996068e8f890b2fe98ea4e78954c6cf169d6ab160626483e89bc209efa4df6bf50510891b1d724205879a3c87f3997d8ce4308f3f5494ce84d2149fa24929e2fe60d2e41a3d22b56b7cd86b32f967bbb1fe012e31c2b918e52554f10e4ed78eda82491462861d2c33f71175e2fde0fe7766a4b9f57e34734d38f9078dce98bd1a22e34604d41768e224521c0cbc53d2a89da93d880cdb02410eb0aa87681c6902ccb70e16b125cd2c42b140df21ce4c6e77244865c5899209e4f789e124740f411a113c8524e6dabde5bb77478620ad7768108b0c06ec23703585f471429f0b6ec2146c444e1ef59a0d9c4396c51914d094bb902283b07a1ab7566ea62e6393b5397d441394f6983630aeb91d9ff3715ac28bcb2074f5f4d821fc094b944bfe1a20ac680f6175d48baeb8edd4a46d00a4987005a52cf512e190440350b14ec0970e7721dcec8c42167583238635070b8a6fa3d07f0fabc9114be5f1c2e4dbfbcef2f36926a5881965803ae10f8c895a6c8a515671263dbccc8c630c3527f97c950f13a5a47b21e6acadcb9d1b92d32b2bdb20cad6a8689f2abbfe4d7e573d3a6173aa49b3323a5b63fed92314ce52cb54bf3d0bb40d38854ee1288415aa8620f5fc723b212b83ce02a7d11de7c962ec8f48c9ec244d81722e3fdd6e4508ff0c1a65e6b834fd5ed7d349705682640fd29f906ecc77f94f8e225d523651184f8fd975022084bfd1391905881a03077d7969524cfdd0516b744e8af14cc7ecea15fec9d6e8dee9fef615dc16b1d06b915067deb2ce525ff2e78a7c1e6283baea061a40ac3c915aa30fd1c0d3b719a8fcec5342545c770fcb405337e0f1c2d79451407ee59a830edca1350d1439afb881860757dd6b5e8a505ca6339dcc79958d7062e20dee755a2b526ec1f0d3c21fc469c31d660503ba005780c458c4abd070d2b7109cdb7306a47064ee8503fd47a0fc82aaa4e49f07a89527e2a534ff37f584be80befeee57fee6d231c351dd698307ea6421d71e7365e262b5d4e3c3e69a6cdb70f6f18cd24c1f94eaedf3beba54da4a6cb5e723a6df033440910c662ca7388075a8084f6740f43536db4afe8c730cb143b7cc942ed9835e95c99b32bda749fcd8b81e7048982a3775fe5fc7f9ec263bbb92f17aabc26877cf646e5de3133ac34447c778969b7fb29f7ea7cbee7ba975d576966a39cf60518edc207b649d25de73e5d616dc3244eb96f7c6d2ea08da2757b822595fb50d14d47d8544d8544a42c8e59b2203165ec4492d287651bb0d2fe01a14c0803d0d0a5ce6bae7e36b4a81c93b12ec9a3bd8c78e8f74c9851abc74ef2921cfd8939a1d521ba2031fbe94233f8019f8921a034c912f0fc073e7f2d172848e918d76d90b382b15735602f375c929effdcf44349b9b99dc20a4514707bc5579c140588ea0eb09d021fe709bc452e973cd0d633830924851ca56910166e2be96a5098d34dfa416ac54cdfcc160d5e703f395c0a1e09978f6ceaac7073a80d093383b1983884601cf958e591a782e84ba2afa3ef20115495040f00a8320a65cf833d08d4554fa7529e9239142d6c4bdeb21f1efc0b29a7bc6b677254192bfd2cfa6361f5f060b49d8da3e2a124b56f52b6f9c2e8b8fa335f0f0f2676799ecb174edbbb3c81b3928a0453caa16781a3aeabbaee078bcffdead7555759e79ec03d1ccf81c7bb3a58c16982b7a9966d5eb5395b70c00c95ac0acbcf6921bef020fbabe9e1a78e4dbd0c88d6dd0cf160112842e878c4839591d5a9ed8b74e838bc4f80174b4000b839f5a12909943e987d6001729fa4cb19cfc4119a0826d339132f2de1c515a45edbdc5675387635e488d240a24abd00bbd086f0f0e0d9ec86fd13ffe6de1956dc6324a0da89160846f3813646006e1f623f0f0c290b10106201810b3337a066ea13a44a6291f4d643730408cb0ae0538ff20877f8ece54b277ff38c29c021ca9d6c99de58a3f395a7fd12a560a052a5d567d3469727eea9eec0ac21429fa6a6e4b176bb9a948ab3e1281e0cd50e88c466950ddc5053bed81142932e38778dc7f761868cc9edbc66a53f421ceca9ee5b809d207c2550fc546d95f40294c03acec8e2491207b5595e566d08b13a04382525e076417ecc7409327e90585df05703eec1a4d2d8a240b65fddb5a0d9c26cbeac81d9a09f14b1f5eb934d4850e1c2f9373a39f7cd1a38a6074fa06a2cb5f3b5acdd1d688a5d20fa0b46cc374afa404b5a03cb9ef720cb0ca95a03e7650b7137850ba7682a09c465efb03530f72b3ddf5a8597cabe57237929f9b9cb1000ce47e1c203cc2661d29f255127b414cb3f8e7e9bf82e362828e6e8212bd92f44def608dd79c2857d005d7121a02d3fbd7788aa0b8f8992006bffc80f185e75d896e4e8e0a1832b154bd5b001bfba1d841af1b0576a9727c008ea5c24a91f89385c69d2f260f9244f2e651a6525c936df3dad215f23586e62bb91261962923f0f32becf91850ff321f3afb00d399584151952267d2c82371468a1b36d3b9a205cf85cd887292fb084926ed3444ecdbfb7a6f025868672e2fc1d5bc23d62c004559805b3098030b830d6ba73d0fc7340d022e26270617f2243b86efbb07ee2ddcb0ea55898b1ea1565029ff7f3fb1c6a680e56cce302e562aa903709b9cfa7ef17971ade47c66293e59acc3634a0d232ee5ee76d221c470e3527a85130e158488b978b9032b830cd44348072a9f646ff56bbe1463e5d17707d84b8b85323526db9cd82cf218aa0c8331a661214a7942b2e93644a5d4b0f60bdc2da35e6d2e65f6db9beaa4408473cbbdd2a7063520547364860419ab8e346975ef2e59fcffc0ab006a70c2e8c2b297437b8b085c3ce3d48927a73021ad1b9fec182b0cb6684dc89b28287848ec18567ff2df662d7098ca9c34c2d2d7ba4b76341e1e8f4c47b3586cea4c51a0129b78f9288e509e2153dbc0d9870ace0c202cc04839aa812c5099a46205f18bb1fadcafcb041da1fa67bd6f5a0e2a09305b778be7b95566d4cf0cb508a8f3f5ec8fcd7bbb05434b734ecb24ec6ab1e706aa7ba799087145c182d137c4e008c892046df853266eae32ab9cd6fec17cdfe7fa9c18575ad78fc58ff2c9c6f14502688cb746902bfe2bd631267c26a2d30352c0a965f4e40461c48c9b1f75e8083ff9691097d958c47cab312b57b0f7e61545e59b552b7749c19e0a4b449d97bd03e38ec9761bacc171445c2c946d833faf0ef59776418e90079238ffeb0deb60b17466d33b794f3090d69d0810b3d6abe3e776b8d87672177239b11c0b980b60133c6433696ddf1f3548ed56b9a690dee46f575ff71dd3873113302ffb775e1974b8c8bf85723de03abf1d462b6d0b1db97ad6e513e6e6a39c28c112445c4bdc36502e20edba67e3d2ebeda09ccd32a604ee2c255cdd959e65b499dfdb7dcb041785bbcad4c33de7156c1cfbe99705b4de80ab23aef64b52b89b8572931b1db819ee8dd8fec4b2c0aff5c6afa70100fcf4504d396376d8d0b974677a82ce3ce11251616b4ca36b1c254a11a4e25546b36141f1b17766bd2319b14e725bafa4e1013a972e3dba8fac258fd5d2eda93a9123a0468dbbc29700a92aa8cfab8b06d18d5ca7012efab0e12813cb608aaa32c9ea91a63c0b1bb574100d1e6004d909744d23e8ffa77fa6629fb777d2a602040dc6219f9ca252ca77af747d0d7b69fa44c1fe316c18fa0f84a5551d4caf8b8b0f3b2c906b76ade4f61dccc84dc63e8f96133b2e1c6c88aac5d8085de74490a08aa78f85386a6ac662d6c100dcfb41c741a3051dc00ebf51b4c77325304d0ee3b0557fa09e20a8568d8336a5060cdc146ea6221275a388b040cefc65c150d93ee5285392821ef174236818bda90d88c89f1bbefbe855c15c5d5162854789fa2eac8a0bcde62e47e12d4ca49d0b0a3be8b8c7c42d070a58bfa9b63d63c24b48b6e5fed2c5ce6f0091a32544ab95749e9818603604d220bf488930c46b6c3fadd6b4b6858b8230ed8f20ec8ab8164c713b6558d68ea88b4cfb7a79c8f7dd8b0e7db7fcd697fd12c84ffcd45ae994ba161f17eba954dcc4908da3b076c2e043a45795dad24793e41db7edce93dd73b00d60b0d17459661b1aa9092260f7620a5176f8a7d4c335f89a1e1cb800824a19a216fc25e731d12b9f08e41411c897b14280f9fc5adfee0d5b9704b1875d0efc231649fbad5c4071e8bce524e756e68b8e6949b6ac2a193d96080e088c2cca8965cb16e25b25837692a2d4d549d31678dd0a161a771936640296a1c76008df71d3d9287a280050f0d1b95f474fad0f0160a68f58c650c33586be98d20352eb7f23deb417070ef973ebe4b52ee861c0d444cf709be82e84fe77b3bf77446540b4e120dcf943c0da85d39c616825bd86b22e86d25d4e36d09230e055a3f383c5f0b11f2ce92467fa3441f915a4d1167ad096b39701d738871411dcdbca14891c527f111ed9e582915c937bf021711b0c38c3cfb92ff72feb4d921f37acd31fd479228043f9a5aa74ed1703142d4a4d86d4e1ca879cbba5aaa0b638600aa2761031aaa53a158dd330a220c2ba95055ae864fedaf64356cb331326469e5ea2fcd35e9ac4902d16d7181e36dcebd501758f2cc17dce780fa40bcbb127dc5087db092c765da8fa407b0b0db431e3a72be3be323de901f0e8909952ca1c7d7224c32335e85fb3c6297670c654451583a69c20f0983904326b0a21f07efb7c5ed7c8c6f65794c8b61d56db2b639c9c02d811b32c535a2700e97c02445cb381a46e912e878a0af9aef4075457db209bacfa680ec373404079229c11e0c1957596c91404b3c7dfca9928a667005657a235517b5a62e6d8f860529bf714643a11bd179bcb2581bf96c5aa745abba382ee07d452db303fd64863696520c1e5cca2f9086ddbd0b7f83349c4c17d994b52ce6399249493b1216e11a0275d00dd27aae31c16e5bba63be028708bf264807bc4b098aa58dbac6cab928e9c1437c4c0be62754b160e97d5cab45186d126a21c57697ff44d90c95bc94a0d5fffddc2d3148e168d1e74efed5443000d2d68beab2fb38a88246cc90b062452b222aa7f1e57b629f7a80a74b072c4da86ea015edc9c5abce6b81bc3638346812641eb261faf5e181b42f456398a828e16bdc7b823a012ca202ab54609741261ff22b718e96e3f2bea84bff32a05e27586eacae9820ed83eae79dbe56a99fbfeea487bb4a5a39deb31b1f4f20bd3ad23c65955012dc467464fa7ab8c5952b4d31c0920f399b23b74a94ee89e970fc626e13caa9e7f81a9f0d450674fd2bab6a24a5e4d72a8e389f291f32550fa66a166010aabb13e6991e8d4b673b7c95baca64f879cf9839c05093ab43a4f7c90f08cf652ba3fd93816744a49d629ac114c1f51d9f2094e3d89b0f793f875adac0fb59894eb43b95598ee34c1f3207eec07049e0b06eb2f04564f521bbc371fe83607dc8f4855af67f14070e57eccb2376ca9aeab51bc9366a3ba724cb7a110b40f6212ffcc99aa3be94e8cf10856132ffb7abe6c33ee44c38fa5be22f30e32346f8318749bcf20175f983b72b8c8923f91014e8b40c9fd44b1df85c2d8be5b0211aefe452f35e0145faf6548ef8c3f34810318f72c3917fecd73e9971df59bdb4b54703731f72353a2aa9248b192b70b7912aef43a6950d8c803e5d50d997b617cb57485219400a7ec858169e559918dfc946d642c1880fc9a490950653e9fad388601ad2c35d703313642b3f649238a8815220621072270abf5327328684e8f43ae594e21bf251b3a6c7955fc7c5a3fa66e5ac058c6215e3383764949792b554363e14fa2157829455e8d83c95b64a78d8ac7ec8cf6b10f5f8b01f728e911ae4a7afec6620fd3d1101b7b7d36e01bfc383f5173de0eecd12ac38c34f8690c1782aec9ea2ad353b271e5e07b208254ad57ec8caa006fd9fcb58616771bd187cbb40af5943bb3002e766818453d2fdab3bf092f42c18bc9cc93873b93e6066568f60ed02d6b6fbc92299cea4540efa5566536dbbb5bfbf2c532890dc9bab849a5d7f1e2706782aaa1e5756fa9a7e6a5c5eadd409bcb6e660c3da031397c6370c0f82b04c781dc8cdc25d115786d4cd756e3fe4022428b0b7d28042505aba6c3b6c2162efef7bf1925f2f75070289d02c0590080e4391246ce39a3075b5d73d5fbcb3da0f39ba7893ea0f72e9ee878c341df94fca9f6a6dba81e40baba0b1e03f0864642a51bd1f32b6370fd3652044582b140b4f99f943e6059c16b518ea7ae56664eb90f1499aca76933f640e631e0e4b13cfaef3d63319e9abeb0f39fba1e6e1b0f2d4ae144b6449f960e1c8d87b38ecae7817874bd6b0378994d1f3368ff13638c9adbae2dbd2aa8b6a5c69bf368cdb5b6b6f8a4b057da1021f8e1b2da8cd10eabdea15218f9bcc314c3b2087cf3bc4ac6aecc29275aae080f8649c4aab0931ac4fb7db29bdffa3d4daba4d4f2583f6872ab64e00887c89c02afcc5bb7932574e20275a14561c633838e03c32cc99d11ff3ff090cd0f397355da00acfca921ea47e0044a66740212b6b3839957ffd70c8dc34da270091edb7de824a9a3625eb30134ea75064e405edbc999eb5ab06edc27119c72cb1d2d0991fb5190022b700e8ba809e2a084064ce0a93c2ed7d8107667dbe7231d43d1657120e78fd8f82730044e6daade70a3e480a101b8e88dab00a0000917d05444996f8d58070a955f588e5b81978b1718c53944aa31440e426e521c9f88da9f6ae9cebde020491bdc2a8c621d1ace4e71a5441a115f10144aef80df2b61f2493b13404bfaa497b055cff848381643f7423e7a8a5ed4097d8f7c7dd6406881ae84efc899419131f47f0004dc345ded658ffab923334ba0f1c0191a7b5f662ff903ec03ca443382c71019159b7eceb50d384879c4be2498186e6d9c182a770387adb7d68336ca1db80c8c9c04051de3310fbc2e1e729c8f2d2c3c03a20f2b2a91618de248755131046f055310ebca2961a81c816d831f197d950528d9c79d1b4a1662b6f88826fb65e38937f77b2d4aa1e0b081543641b049a6ea5482210b9d44a5daa222f5213ef38ea884a3043dc2f36f4ec885d97089b163ea2ae087f9a4fdffcf3793aba92969cfce802779b399504222fd220035f5c3c54e9312b2e8a904c403612cf4020d412fe0e6ebe54440ebdb83cee498d5637bb78e970a0bc5616c3cad4fb2f7a5b992aaaad8e7634280bae63211488cc5d022e09e40119f273d1a91ade6ab55d4c7247b8da4f6f66070c1bd0efa11e502032779ca8ab832bf277be8d64d5899c78b6e6089bab902cd88e0b39b598fa98a9f03a90b57b5fd12563ec0a96840f5774cf9f7aa8c1fdf25883b8d0874f0e7347ec0013781ca02e2200b405846d9240b852fcc489f652461a3473be288981563c420136a74711952423bd3638f8be86af1067d56094ed5795aca49c517ad1fe765d3e492561d9ccc0cb2ec5678fa7ac241d7f038c313faeb0ffd363f4da2c85895abd40e4f74d5d8514b32e7bd7ceee935db7243f320fd4e000d3ec816015c3bbf66acb44ae4bbf3db12d16d38101f66cf402ba40e4f2df849bfe970dff86b51a8ac67b167d7bf472e9517d6bcf28b177aab82f56f715daf3a301b4f7a07796ba6fca9401be0ac29a1a214b768881c83bcf7b039189e2ea8dec1088a3964fa4a60a09efcbb58b49fe61472015b8b1cac7dc65e8e86df6acb8ea4a56b34cc223daee650e4446491971e11a0e31f05df44c522de31c623b85e05eb038b7f898a16352ecedf5dbcc98ae49c818812845ef582450b609363b25a1f2925e7edc38e0ec18bb658ef60eb2b3cb94b5d181604fd34caa6951b03fbd0d08a60e0d026a2d3f825b440869c094439bbb74f85ccb3ab79e011877241eaab5f8fb49a900fd4fe8d58d572cc8b24656fda3d620a4b445a6d2ba603475482e4a4a50e5f1cbb6e2a4b62b3b1dc86c53f42d41587ed0da995bf543be898fd375a9b0a18d0ce3cced2d1eca77b64aa08ab124083d38f4811afd56e2e33461f8983acca9d0690fbbfb817673944ceda880d57cfbb5a850c0aa2996d04f46c108239a72e106a5efddb4dee0df1f68114a3d5691306a359a783baf833abad400604c687fa0e160cb750629abef0ff371a16b548038590c5964d1f28f0aa6421b12cf813ddd7855423ce625afdfe59bd5ad7e56473fa9f5724342ee4ca7df5123b0fd818628cafcb40cf55afc205c564c20750bce9f2b587d2320bcc458fa03ede6e3d9ae816e845e18cc9cfb86d59dbcf249ddb44ade4d3ff58fbc7691fb385ed045c2243a487cf678f26bdb17840b22c15c6d74ad481d92095df8f33d7a4f03b33c303aeb8c21ce2271beffadbd32d3ec2ccdaa8af230f510e3985ce791207a1070391441265e854dcd06d614eb50350541a07b3a0465dd5c0cd6797dbaf71a101c1bc14b1980a0a90ccc4eeacdb8ad51cc76c0565c1dbc99299bcdd615c50d10f448f063645340d0e590a2a12cf9dd96b961eb547351c636308c43e2a14fd58d782820b348963e0e042f2069daf3e1efcf63eede083606ac05233962f4cd3822d16d2f5f2e685f53d1cb7a0fac646cf854d8846dbabb081044c3c7a743574faa21a9efc8a368af92ba754f0311aaaeeb61263de21556e217e9506fd0e9d9bee580d3be550376ec3f4dae0a2fb8739335d671fd814ec4480dfe5390bb7109bfebe071eab940d0768a21fc900cfb3d9bdc39fa584c411d75a374d47ede832ea73d0f7bb567cfc8dcdc0219f6bc9be75a629d4258b45174ba68cc27211e3366e50b04bdfc800092812f2936bac82ad4ece96cd5c0af670e50ad2e812f79c8cc85378cd0b0947c63210027580c47f597bf2fb1d5aeee388c94aba1690d6b57b862e27b78a76c1112dc067bdb89cb3fb48b35fe9830d9841b53be97e9f2db1a8bed13c0d611442b7c1adc77ca73b5d0e3e31fe8a5440ac014c92b07c783dcff6c7efc132bee34a737365ac45032faf5c373c5ee2e28e28366b9121fa5fd09d4c99f03847f863744307924f204728656eb28f0bbacc8f2363096eb7359deeabe1bec3b3e838de52a451cf3324deadd7b9a6f2de49dacd0ef81b93dca9f6b064a157a6e010a238434670b6d837ff3fd1f204e8e76ecef277f8eb5c928df31f9f35e2262dbbfc92e08206a1ae8c4a29216e0e1e62f1cf005dcda49c3a010d730500da89253e09bf21c6c7cacd9fa678a960399f3f0869601622c830d5698cd16ba202a2d8501bd7af9a894c450d08d062cde90cc78e377c9b85c10118cc520f952edefbae00c28b1c4952babdc267f9df8a70f73755a1007ec2e410066f4f4745a413c61c6d004301d8a26b51794b538034427f3e08ca383695b42783e5f6535ffb98640ed6781fc8b95c338732096e4978be5620459a9d6b043e54a6430a44c61f3a0ddf0543228274cb2923a343270acd7036e47dab43005fb378b958a1a83f2b441c4c2c5aca36693afef1b0c55636bbae9e463294d80fbf939d4a17f78947bc5a667fac6f95a68299541ecc3d7f3736dcf658a8a24243cf473a8f36049154dd4c5b44a6f5c2ecaa487c87f53f801107b6df434bcc4215de5bc21ff2afe4fae0eaf1afe38eecdab0705c451466644c824837e3ef78d00bd81852d634770b0524fa09f616a33a20962dd011cab403f6fa3484830ab4575409a5823e90343e23d3c90d30706eec4c43dab61bd2c3514f2e0cac48f8d281ee48dd5f00b9831581931d810473f6cc41740b05a5b99e01b12f9cd361f6f1d18c52f3ebf8462c0c3f8a9e8177e0b0bfaf9eec20b148e528f84413f6f8a0bdc7b383e97f1233c9c967002805f218b837e765a7a34592eeb2661e251451ef189a67f09d24826ae8569a1694e71a09fb9c5729518df9840f723ee867ebe11b0a00aee8335c9f6bbd871302c165a924dfaa07c58556e83e7fc06c78f01ea76191f8d43426b3d505e45a871b3417e043b3862f6e76702e72fe341c24c804509c1e51d54cf14707e696b046b52a59e6ba07a198cddbb27284c9054fbe7e7ebd82cbde4a09fbf9e1bb53e68f41d58d787896a9314d77776e8fad77de6238cf867c4ced3ceea393f97861f7d865136efecd4a2eb6fa0fcfc9cc96a29fcaa3046fb56d82b906ad4f2f999aea07e5f8148e92837ad3181d73034fbadfcb07d8d2f2338de650a9893f438d53506fd54d0ebb2ecf37a9bf7e1fec7715c4c9fe6d44c3dd2d27775c92321b8aa55d10bb61cbd8f9735d3a932b097cf3ab17de64277977d46dfa3d284b71315c2e3157847cf00131f7e9fffcc17c9ce4b77e9d1e6641c20e7b74d3b4c0611d25b95945ff6d99ef44a4169e0aba4b1e438225b4b0c3903965672911fb90ffd844d5a237e5164418b18ee931b03128c017bd764f97e4c8db82d2017153876b758ad9db8ef93f262714d3475c772c3ada09b2fb706ca791f9f203ac8a11af3eb80e2d0001a279a3e5cf659d7c94e83abc43cb7f29169dd6a62643cb040f6c546f9305167b8a8364d03b08bf2b90c599c3385ccd6e018ca68a5fbd8b2343cb492d5bc01271156b0153968b366a4d361f86b88cf1260b43800ef07145d01baef843455501226750a115ac8c8465a09a1e4f145be780b02f985910647c963e4c512435257d937112996f7875012720054298ecb70188512020020aa1202a83ab3eeee0af70cd95c5721f90b019bf91b6bd792bde59649261996033403f9024aa61091024409a8284c47219228824216c348d683e5e5c9162760575a56509aac4c8cac4296f050d294e446950f545d6420e9f23b9256ec62e44a112e22c7a926c423c3a01089a0d3101c428c820c01e102f4834b8e8f648f2c524b20a1c411573ca8a286503d8c78daa1f404840e1a4e5b5e14b165a7c92c871893171153969e2825499ac2f103c9881b440c7124448da33118418cf10081f6c39891151b547c30f6b0a4a8488d203c44d1c84134c4500f33b408c9d0e223f42506171861415b2f920032012afe0cf91de153440f128f0ddf8c1db11f1d311ccf21731c2c6955be44f1628586e44c682655a6239944f64317222e48e016a4ce589916a45817524a162758aaae10c37c80edb0b2f41584170f5d598296c8e2ab7256e31adb02d3daa272ccb29a422585a8c48f2850c71c49dc8062c338848505f804cb8e93b3ab312bb0265b4c8eabd5122a25c4243faaa0a87220b971c44671c8c81560912b3b44cea6c68860c32d61d8f1b4412b0ea836206af02303280c725c70c3021b150cdd84016dc27628389b604c02b008b62038f6ac1ea07280d8c08f15500ce458e0468d0dde900260c004c0761038a3193b006cb7a53b6a2b03a80a2012f063064a458e143706b021332480156000567600388b1943017662cbc431b5ca51e188303f6e50688ed38654fbe1e4c18c91bf7ee5570e367b9df234cdd84db54c1a5381be61fbc65c6d2f707def9de0f2fceaab79e5e3debdd78b6bdf8b7f6c0b0a14a5f94f30fe81425edc12e32a4836a601567982ab906d13db0eab2c81a6b1ad96ff6b18c7fcff2be9f076d68662aba9c643bf2368be03b61d1e8172a4eae7a757f329824103f44902de647c7600a13e3f7e6ca7e93305f3b5d32cc5c082902cd113c46303099f9e192f653b6d7ae2139000f2838d2de490922382c4b039576569667be5c8891029a32390bef0d081da18e3cf0913cac41c3460f6915196254e8bf2a71a636c0a93481ac1b3a6d5a38838671b63fc3c1d207eca5daaa3f4228de97ac2b8c43c691b66db61dad45675efc498431dd9398b425f2e739931c638a8f7cbbddf590c6b32c2ccd6840718bddf7fef777e21e134311c4c8b9286c377a42905d368f8d09e787cb0f1f0d090f16d095bb1824bcf996f4dfb2931109b4c7e160525ae4368e457669ea522527b6b0e85474e3fbc34bd1da9514505a98682543e5f5228f1d5a1a1c275cf216aa0e512e32b838789a61e105311403c4b90de04340388c8fe98f96cdb0ed71aefc480c668d665cefacb5bf8b1e5b93ba52b4cb85959d6e8f53ce7fdd1e5054b21157b6dcf5eb6c635f2b4ee26ce76211e5b457ffd1bc7c06a9b3bd92abad5126a23dfbdca9d7b59a55ed62f4ed561c384f0bbfc9d8ac3be59f8a648de006abb5426267d2349526ca01ae03c950464885a063139c9e848ec040098031c5a98ce9898d70087551049e4dce2f3021c4d4a15e01032c2e1cbe10820c04ab4b30af9d6a01d73dbe112e4a9b369df686a2163f47e553fa2960e8c4bac85a37584231cc249827394a42a49d50ba7e20d8354c3a58d03e64876923bc823db644282bfac80d05f698631c6250e7ee97aaf98ec451d3e4a24b9110166ec54102c19e1d70e1f1280eef5721429e243779dce5822c075972f74649c4460d8be6d4b044ec5989a2acd1c4011df8a7189712f0d091a3d5ccb5a631d8f46e3d34c4bf3a73ae634f13fce9fffb58ef6ffb5bafcff2752491e6d45fde3df32720665739845044e0981981032243573131d612ad429828408c6cf9023613235947470a4387f39ccd9257e0cc0b6c36191cf97708990cbffe31c239fd3e34fb5f088b5d0494865abba572e61b93e5da7444284f8160dd008b4c012635c6cb2312e12f120d9964cb52bbede4f881a948db1ed61a8f7c36791a11fe6f93979a0864afc3bd36d89beb2dc83a883b5d16d893a5567cd4c6296e7d77434cf02990c2b60415a414520be1f5f911f3a5f3364b625fa9ccaa0620ea72f5ca21ac410611282ac6560712662c5f275c6a4bb98df60b8b475a5c439fbf9a4c120cb966cf350c9079654b655ddbb7da9e12328d4c3a9e7c7a5883d46441eb1194bc54ba2c4265d9fae53d7da75cf7507ae4d70ed82eb18ac13ea408abeb634aa5d7532943acbd0821dc16682ef54b730e50e84f72123a4d82e82d876cab63b6b1b704d838b5dda9d5a6a5bee3eb83cd4fabd38d5c5ee002abd37ca4f871d1c4604bbad5da1e29d8ae21dd625943b35071520588d350c56abbfadc6bb837b6164b8c1a79383b3adb5db3e89f9da59d34dd01b9699eddf765846b6d5de363396326ddfd3ffcdfc5f9655f99246f1628586e44c682655a6239944f64317222e65c02d653a63655a90625d4829599c60a9ba420cf301b6c3cad257105e3c7425839648faaa9c7169d9fad2caa2829515369816ae6dda376ad3657dc2d86a3022d46eb66c9adada7438ed1a5fcf699cb6302d703b9be2bd334c0bafe97e45757ff5c6a5543db12effe9a5705a9ab6f9ebaf475a86d879877149339993d87166767fff33b9aec96432994cae77f76b328971823b20a8dfb0c1000648405d29c907f4e3494a3ea01f2e44e8b6c2b3a56d75ba6df08b99d9950f6d5ba1d9d4b6dab6ad90c787a0d40abd3c05d3c4b6157ac101a620c4116eff82867344f207c353f1c248ed502b6bab372da31d6a01d956df74a42f0cb9d06bc804892c3964a2640c0e97f08ce0308834a492348bda410acfbc826938b4904b1414bc5def2c0bc69f71ab2bbcb63a812d628d46f1ac486f7235b62d522b44e3daf7766dd7bc6eb5b156d1d76275cdeb839ba6699abbfb517cbf587afd5ebff7b7dfcfe2e563c1ef05f3e0204c83c8561578fa1b17b235581749fdec194c0540f82bf6344d7ba6a736350aa7cc15fa8bfa40ad164ad5b3ec4a6aab3133c6e256697c5b5d6146b4d509f61d0ea5106d0adcd77c7c2c2f2e24949a72251e30a13999d04793074c490f98c23c60423279acdbe36466d6be1bf59bfbb5d80b59e2dc9b639f11c6d9fec9af71fdff37aa348be66a5679b9add08998cd56bb3ed3e2f65f9792c8edbab8cde2dfa8786d9aebdfa8f89dfedfa990b5b9cbe1d459e760ea52bb60e12ed364ca4861549c50eaac552875dee55004762fd5bd5428b5b9cbe185fec8b7bf5975796eae66f1f25c9baa59c44577b308671d6db7dbddadbb095fe32a5edffd1b7ddd0af984bcf3e0d708e9ee2e16ad472be45ceecaa5aff172861ad2ade532f034b55ddb5fafcd1baf90d7b5517f45fe5e5c1b5f7f7bbbbb2ed17c73626a853dc2b66fd52c6e57cda7f5daa8aee2a28739b2786dacb0c7d5766d565d9bdffe66cc56ddcb6ef3e96fcc17b7c6b5dfa4b6ab66b085f9bb3c77d5fc6d9c4ffe6470def66079542ef58ab6812bfc56bbd7df341074b4dfb5712bfce25379d708e7c812f70ac2b5d5fb62bb63fbbc6ba39642ae44498669517bf76b641bf0fbb43dcaafd05bf7e7b9f9fb1b9e9bbfa9aee94c7d6142c0d950781627acccdd72c5ecbd6137a8eabfe7ef2e571857f06fce13009d0a55b06d500cc7756d4c84ddf4eb9c76c1e2b250d357919e52fbea5b4c79cdec057887c1cd294b305c06db391deeaf6eba8b0cbb2674972bca354e057f4805839797158c72b3704faa9ec17df54d9e477f738b8aae0d7a938ebc4947fe1c79933779c5f04506afa68aab31cbeb147eb9c2e9f086b9dd8aab516ae759db8f7c09d5f9d4e5e94cd07dd0410627743db3133be918a417e684cbe2fc9abbade6e9b031fe55058f3c254f99990121b5c2b2a999149e8fd6621c3be423ced892b5596acb35e30a883463f3d1e629404dc49f2d78c8ea6d77aaeb93e64ab5fab5759f54eded0a9e3c6ddfbfd4b50fb5b7b73bf81bcd026fd5cae8c85644a7ad38a90b17a91572e19291be4066f4ae17a92502a36cdb7ae32046aade2e40bdcbbb865a695b42fbfc986d875b47de93a2d876b81565774fa8f7a461db6ab46d77355c0450d41de312bb1fa1a8bf98fb8c5bac23654ba28d8943481bebab711b5c714df98ccdc7194b9461c43b58878b088c129e15676ec233e3be3a008d16606a02903601fad4a83d41280ae7cc588c431c8a1226d72e5733c1cddb7608a568439999b1b92b1ff3311fed01b92b77e5633eda03ac7b9e928f33291c9db18eba75d4eda739fa8364855db8667e5b6f3bc4aadac6a1d1c846edcc553e5a9b8fd63e9619eb5de9a9d1ffe4dfd01c394ff1835b583ef489476b63a3a3a50ffed4b5f126595f0f622177cdb6c12758db539c36730de77733e370381ceee272ce39e79c770fd3e283c8cf92aa77f5735d854cdd5f5d5ecee99a56b3fef58d399db5fa6b4ec390b5f1da6433e72cf435f78debe55dfd9ad3bf5e9bec3abb4f9816d9fcf58d399c09f3048a7ffaa8cbbbb69c4ecde9ac6b29d41c6a43b54da3254c0b9b0d2d51e8b244e1684edf5c4e7f94cdf636f38436cd13666ea7666dea9ba2d4aab97ba9cbbbbab6fb27bb733f95cb5fbcbcab832bf2ca786d70faea8f726d54a59f666142e3f47d24cc4e0cb796e6b4ccb5b169d7f998665dd3364db3b169bb79571a8e34a8942c9b0c52562303000000531800008481380e04310a0321a2e8b90314800849703c544824241a8d44e270281c0e06036130282c3ac4000c00310c8471100761186637bc0e7aa3c5675558ad65573ee581682ca2bed93fd42e6260025c6677df2fbdbfdcca060b2bd49c0241cf0116247f7e10b8c08420eb6ea5c3ee38ed86a2721f39f6f385573ca26eb383b7051a30380b40fb80ca6130d881e023ae2e0ea8c73aa78841454760b7a45160bc3844b2c4d03953cb625259bbc0966883b970cd2e6b8e02ef36983d81a70be4943d27af9ef6027a59e3ddf7ed853381c1fe05d50e9987830d171083705a6412583e21d85c800c8a67728822630f7c8c133b2c31e1afceb2556fa039eec221ca8da1cc0e1ce9b0861a0878ac5c27720c42c7d127791cc7e4bd04066bb5f567b0880a0fae57ec43e7587e18008f4b90ba1119346f3a399a0922cdfd5ee4a0f60bb56d4071d30548d6514c64a89e157c30736499bdb33a17ae15ec658aea97bc4584cb0e9773fe21bd24f80945f3fe71f632e9c1bffd8b3a2a406e74c4a83454c1782a8e44044830779dfad64c6dd5876bc44e9bda47d82bd46225dab9fb700d8bb876d427fb86cf4c00e7a21c127a2ba7d3c88cffdd813591ee69d94aa8d3c6261c00895db85e97c9d4876bae01ae4893aade280f6349d09a403ab3b75e507dc6efc375b7dddfa1692054e6a98a3ef3fe7770e7e7a294500b94b3982208010c35a743e7f358ced1d923700572cd2b2186d4dbb527bca5f49021fd7c21f8e61ec2849b682f1f273518b7c16e15bf0c945dbda3987bf6de140788db865459f86b43bcc116135e8a4ae756cd549d429a918a6ca560633f849e3a0bd250abfdf892a5223328ce708d3b49a0685f43bd00235883ce1aa4a559a12543b571b5d735bd2141b5194e57dcad47b4afd1a960cef535ce3cbd16215021c409780f9e90fb6988f6b537e327c48b626f56013a987d9c5ac607629af51f6d0068c20370a783371a7a266223b0a1bbece81e70a9f036222806efb9fa840a7b4c80a9455eb9adbd035097a9044a7c8b0cd89207b9f3cc3b86c484f6e0dde6c3632fa4206aaf8e5a652339682ef72adc1d83603561f5d9428899e9e02e5faa4eaca6891cd5180c404711268b8bc4730bbfe4e6374091fb00ab63a4b526f77980b837a2eb9e89c1428aa3508b2a2f1f36f8b3d196d96e717b1c4182b16b112df54c3a19bb765235763d4429e63dd3bd1a8e2c180535f90d5ca4c6aead79770898bf7395d244f8acf35fbc37bd7fb609e225cd0dbd43454aa4113709dd79e07320841122768d8662033463d7e44cc2b13c582ea8df70c680a308b19416481ea0b9926941e4b3dbbff6b69c07dd7d7b0788ed2b74c0a54e9be61e26448fc353dce04e246f7735cd5dd74ebdeab7283aaa857ad6f03853501474076702803995124aa0d0bcd30d9c2ecbd867082db04edb9295775c9f6b6b85dec246b098f69c8584184ceac3636023438055d4450dbba40980cde993d3783220e5de13156d35a1992e6256458f5f42534879029e7088b703d19075c96280299feb5178e8581cea670f44f8bfc566c5ff584c1b6dc62a58b46c571b5b58166a366235841a7b4e03898ae0c6a0e4b676c6a08ca3f16d7082010b7a29b65312708b351b579051c362dab7680acb3792279cac110c85413e0774ae0a6972d2e4760b6f4d73d0851f3ca8e75d40bf4ec7bc1a44f3d94920c60a584cf520be0d5b9ff4d290512328479b10b330030a702bee5dfa86ae22b33dd44ad45ad626f67a90a29fa49c9af8b7434a40941086ca0663c5bdf88954ac70695045574fa329562d9ad4c380d661fdd9879adcb6e7d5848656111ad0f9fee88e00ec3df69ed8339ac79c89e8e55ebe1323f94e39360c5993db05ce389d403c0ab088c915824cfb6a526f3e7eac735e8628d62b2cb3fe4d3c72a5866bc8c76c4667ce571ed712fa9b2add973118aacccb663be9bfbce4677e21ed6288638c5ee076cc2cef0972ddb0d3b7890405d0bd76a0630ca30654a4a19f40e6163e13e7cffe9f6af3ebca4a2554a46b7a72e1e6b46d17705352e8566748e76da9ef99e8b0d10658f3e0768077835a6c0a409aa33030576ca36f90b9742eb67c2e68e42361afffc73c35b991178b306b1953494728105a6982b0cd42c58cd1c643b9251792c02a3785bca3bbb4bc0893fe28eaffd45cab8157412cd2a6130627fd9a2bf9b8783f33378de3b305d0045ef70e32c7ad0d7d97078ed206e72d26a20bc9ae0adf356da2ed7bc129d545b7fc2c78e5cd8771aa6798b654fb705b88f04210c0289d55981e81c98894c95b7624f09aa45bd009bd0ffdad6bb21b19f873a244490f321b690a33973319fe76f9cb05f03e8c27caf6b7e94dae47f84009d01daaf3813726a508252b04685b99af1145ad8ddee7a4cfcf9fe666fd5991ff3a17f0a9f2a80e49d4fb68c41420e9840fbbd01e0a3bfa53d6ce36fa262b0a7cacedf7b7685944925809953e5dddd08578d68b7645852a02b76346ddfb7fabda0e3cf52d2fc629b00c691850468dbde496a2d1bddf8f21aa3afc88016dc4bd75c33ad2233e60138e3b759de7dad7715ed821da6987e31b700096f7fec615b745c2713ec3097d770cb3b799e8dd2da2377226099c13e973d335de4e31e3339e9fb18305833f36748df08b830ae6feff328dd76341745499bd7c5ff0d153b522aa1d83cac39fc1ed3ab44c29f22975542a6505158bae7f682be1f59e6807f99bf8c26b1b4f1c42a1c0fa0422b220c847a7c4f1c748c9ff26dcd862b353010f62fa87f25cd63b77f6b86cf1323efb573ade23812a53e1610ee01692329b9d5f378be264285e6209b0dcf9aa2024f3f52fba89b1307ae84766253dd1f400feb571ab2ad2ad12fa17ad7ab4503888bda47ed1b9707e5eef04ff40f9d00e567943626f8d9146efc4f4df3717cd95b23c3a11f74109c13f5c04327c60cb7b0e3617dd9763a488a1531a9a9b8b1eadaff198d4f258b3826da34610e10f1ca5791a600216e98c32749e09a85b96df5cb49abe44322a73dfe2d06ef5eae366b1de88f145b33afbbec4a473d18553574728f9c5722534cf445bc90b81315d500e4321bc282846f27de41c4b67a5ce455b0f84306cca0dcc2e321441bb60e02b77119752f71543cecd4ed1e103e99d8b760ec3ef8e1d1a6d6ed5fb74815e7b12c23ff534722e620548c69db1c700e9d68fe0e02322d1a437a5ad2ee7db3c1ed16ac5842e7a8aaa68942d7a3827408b84d583c255f3fedb720bd74fd61259a81c225a69ad3fb9d71d017ad1a6ead945a4ec65851654ca5d0df4a215004ab6cea32c1bd8590988be8f6c8eea517048bbf38973512c1730037223c9ec739f5a28264e88d54517365dff306bf91cbd68f50d48a83de6ffd9f4b0c47cffd36a6feaa345e6ae2eba3db1d0e662efac2d59524d633320cacaa2802b6385dab51b62e2ef4945740a6722462c5281d5915b5f93c3eaa2e759386282dd9db4c66bce5ddfb893e489ee92e7a4f5bdca94b0d2d4b4b68325ff1a95d5d1da8ab0ae5d2b595487adedb2af2afa6effa41287de68832fe9faaa4d6500cd5e81601bf72bc6a8be033ede63787acd525b83096157a463ce81a07aa3b32a41b5a18d210948a4b685e0f815bc6602d499fc13a7c27f5fbbf41a802d0313b448f332904d68074cba90420bfdb7a10645fd21c226333c49a5b23f1c9deeb11011ea22506c34e92c1adbc3c4f3f77fecd56272f0594fa8eaec1a2a2695dfd13006fae74f542e3cf3c1d6a4c75e2077a63e8d078505c5f16ee167fc1432420cd4467382ea0029616f1f01a270760289201b4320e3ed03401c10d69ef719d8801dadfa4c1b8d3212f5d98c52dc4a3857e9def590a501271191aab9b53bd7e745bb3a3b1dbb0403ef04bdde7d7556b2af2183cef24d4a8c84a3f6d32e317a191f39009bd2381701c9b055afb3da98ec6b530661c833bcbe42e9375742446b29692c8af6aabeb03d8b8629fdbed6e0e7c2e631dd55166d41af0a48ac7a4e27ba1a83238a52fbeaa0ddcd8ddaf891a1f78feebbe108928c38ea9580f79b1bb0b65135493294581bffdb70bbc2373c0a073e8736c4f2c181b3f78d0df2462d97586460eb02875157ed00af346cb38d55ac206f4dc14f6963fe818dbbd7f9e65652699e245c956f1b8d3d646fdcfbb0d87a96d9447c0d8ba4a4e919640ec2965f09828fb312164032ef47f2e3bfcf1e108c1dea995ffc1063bec66f20f6d868692e31ff30d1336e3db097a8e26014eb5c5938a2638b05378fd79f1fa9dfa1bed1ec1cdd4929fa59297fd2c8681787fa6faccb1d813ee9f8fc7990d2d63f523af97ef1ea802ab608182ff41f89ee79e72319ae1c774d80f8709a8becf2e65d7203e568d7fc897783ce5cfd89a5c6fa7db37b80f0c0b69135af76507daeff8045dad47eead388966c4712f08f7a84a1d434d65be2b58f126897e65198a1083a459d21831a547b446c302c5f2d459ad852bd682bef578c6f4c510b512630be67dfb391030b3f114613dfa8657fb0053434a33b3fad238c090fd93735829757052f39ed3bf5ed5d632babe156326da6f8ef280939b0d2dd8978b47c5ed5c25de049a660c7465185e27b61e689439c0a1daef9694111c0fafa1b25a4966471b343c0c01eff0e666dd5dddd440b09e3872043a301d8fa28c618d26346bb81b2ad6f63465b98a71c23e1cf4ffd9d3df331802a10fc2f1d0218d2042480cd3103cc784087717591fc01004e43efa410cc9f10288cbdc63323d5ee6ce4213021b83bec752c33170ea13bd573b6680e309cc50a56f37180a1996e162f3bbe9f7855f911e813598279fd6fca62604fb47bf1aae74276a1c069933f55ca9ad56998a9c7102960e0d843d271b77e99e8c986c66642d160ca5568f65061aa3d64b85ef42ff2b208617de858c52308fdbebc734e4b750f8d8a940e1f1ab50d3bdd09c641d878058f827ed3c1f52f10daf49be4a4db49ada1ceeda941695a3f8f9c593c4e486ee13d55f6445d9c70b39253d80c8a33f763c96aacfbd3e11ce98f3357a851296249b1ade652878fdba76e55a1f5f9fdfdf73b9bb51724b1c8c9392bcf2d2459dacdb7319b6df1df93284c5084342fcae28415ac8221ff1c542ddea70f978c2113e3bb3e2ac117906bbeaf4877dee0433dc225991794028a705603b2150d68ab3c67e82a58e717e3013b100202518140d42aaaf046fbd733b40581e03436675049c2ca98d7681b7fb9475adb6eda43011fa2b2b84abf2b8d586fd74cf41779260646126215e93a6111728c7edb5cbfedc173424388c6d36711a9c28b2cfdf19fb79d30c5f449e030e997311bcb85f0b8b759b7d800555cb2a0c100e747087cf6b19ce378efe14ce4d531a00a36c575098035b502c519594e33383ccd9a91fef2645dfe990a1b85c77d42dab37ae56c0bc8282a2d002962c7081a5209d674cb79a8b295bb39b187ac7ef35a25701d39f260443538659740bb1ce115b054afdcb8010662f3ccabdcf09af4b9ff4e3d2d498422507c6747d4371540c8bdd61a59645d682a544090dd4e17fcaba7161cc06490c20d81252f117862fbe8d07209bbdfea45be8381690be13d916c6bd80e4bfa4f4ebe2406812e96988741e22276b8945e09ceb1403cd2c293d3af9b139f97f556b2d4503b842cd1545bad126b72d4081a29bde98263fa6d166e9b2b80eb822ac0774184c9d25ed6297c34d475340a8ffd7b2faced849a3ee1063ffa99f3f966829caf1d27407772706c5a0c3706bb96f02f6baf322487c6b58341b73410382383ba799fc5f42084129c6cad894397daa04fe37a73d88f50f9277b1dea39e6e1f623e76bbb3e5e8788c098bdd3f9da28889b36766590778510e6835779339c31d85542487a775177242685a463110d9a9aba3a5fdb96dea754f6b3f610559c39997e2153111274ae199c585322ca289456cfcad4fe12e3a0861fc70e8b898cbddc496a1ec6eaf2d53cad97089ac7145c0f6cbd61451b9bfd43daea226a4472758ca0f640d1b3c68e6a5fd433a02a98e16a91241bedc5b0caa05af2762e4eeff445faf341db088ba6710bb264e44c01fd3f058c4669fa40f099839608060d716c51409726f70e8a8a21eb12d5e533ef1232842d4f58220564b3b6bdbcad18cd762575bb228267ea91f2e1f6533b7b084fb900d4cd09062ebc5390627b3cb1696588e3fb2d11f14d59de9e189414584103da07f78069000e8d88c1a27dfe6b058176c1df46998529b4cc6fe1dd377638c2f6fdb3ebd0eb0f3a71001982b48b00ee0c9d4058c162def8c039c96abc8a137476cdce1774c90f92c60ac8f805dc7327a8a7b3985a4efdf1b1957674fa513c0d29920b7ac506895441531036246061568fd356801318327affe349027b4d424b29980bbb9fb29b4e8cc32133ccb478fdca9cf88d05d4345d765e44ed69c6db4aacb04e881c5cbb5c98249052bc07affa4c80492f9f6cc0ef1a9d4a1fc78a24a68035a1c5846774254dc10cfa3edc8452a9146f2ccd5cdc62d4450adbabcb0667ef0a716239d6b83b912f8794235a960c3c175b8f44ae00814d24d822875b3c636827e66c41a811b4b310381efee42adc76cc1847a019fbe255b5db44b63d8319665797712d91d71c3380cb7d42c55705705931f32f83289fec420786d81310f593d6f173603acd2dde13aa38300e181b5b463bbf7dc647e13d23ae64777f50eebd0ad3d8baa1cec42ad83e9c22a5be4a78ecfa24fad2fd35c3b9c6871d166ca671dace6fafefa1e48a7c4d81bd896e5e7413e404edcd9ca74e2a207c20021353c46fb8f22f8da68d3354159cfe4966ab674a8247e2811fc512292441bfe67f79f19295c8cee066822a55e86879a2b7c962a8ebbfbc013be3836fc107a0cc1984e0b7cd0644cfbd8cfff2d23eb058d3dafbabec4fa68a055d53182a2cb39be0fa089cb97b28c654ff7eab4a92c8672f28044eb805f88f5048ca3aa849285f58cc7cd3d9b3617c99ddd2863dd31d402e9df8e2a11e6e068ba85d370e77f212a3996ffe4992ba15b8acc9f54700ebdf08989230def4831730a47aaf0cb702b75e48da26d29b5f64b9671978391cdc617dde96f3cfd5316a7a8bf800929fa0d749e31d9a54bb253e5790d9119aaae95ecaa1d109ad391a3907473e8968f0fd5d57f8141be2f48edc2229527a0482b18cca105b9896dba6b21fa677821e48c359347c4a35e607799adf54e5548482eab82bba71bbea4b23a8b0198c7dfe6f3250bea2e0c875010ce638667d244bdb0749ba1e896e3b9f751da8bc540d5d59d949d19fe83671560ab5e501e12fe64153b64453af86dc0cf2c0b0c47b7fc247529717470e31df963b29cba0670da910aad45a112c648852233db81050977deb7246184192084535ce5d03b05ae014012546f2ce86ebf22ab2a33e4528686bd04cd4504e043b0b988504142f084000047b907a93e6ec03c75d15019442e14c36072d5e59ffa0204c9c82dd850d3188e2a8ef5099dd812fca2e4fd1ad84e61745d1aa89cea6bcaab2d609bcee104a8ae7f58a793993136a7b0e1723947a65e4d67545f641f16eea05ec21069183b1ad4df79f0ef542657c0a49c25bf9e37a17c11db0ff1e0afa9feeb548c457303cbf0f8435503f237904d764a98fd2d9146a9447148d86c7cefbebc6fefe7df25b09e84c2c7ee2909321a3225596e3bfb7da85f2b15db82284414b2ca3fa913a5feccdacaa9f4c543199b52ac33b25686d658e48275085b0528a692ca598d8fca418836252e0b24652d0641529145c0729ec4bf928b65947af98eb1edb79ca9df446b8ea28e8f725cc5de9dd08006ea79114e9e05ace595867dca21621693afaa73eb83f9dac6b90c8a51a39155a6b532977244257e6473670ce1684d81ae2135a60927e30e8ebf5654f36ad9a72fca84c8174415d987fb48b92bb145ea835e224200ed8f116b11b25a0727a8c7fcae53434890af896f38e05a92be019691be6a7ae94baba72c9d557345b33be90c10fd07088373111210a7a81d6429e9128777595c00faddb3728973feb1e4b1aa317c1c94328160629273dda39c042777d04bd678e759397c405b287d8585641c5fec4d9a765feb7157aa52d1bf9004843c12b2f8791a5f1c166a57ce38979636e454be8ce1498b647ba2896cae386ece066eb328b35d90694e56476686529258b37c336e058776485274b57b258936540595e668777962ad98c996d812c2f6507264b2bc362edd82690f5232b7cb29492c55a5916ccf2727670b25499cd996c0bca72223b34c352ea586c936d81ac3fb28293a55459bccdb2e02c27b283334b976cceca36409617c30eec58aa92c59b6c1bc8ba91155c595acde2ed2c036439313b3c59baca664cb60566390976688aa5d42ca6c9b640d61959c1c952aa2cde6659709613d9c199a54b3667651b002c2f8b1d9a2c45c9e24db60d64ddc80aae2cad66f1769601b29c981d9e2c5d6533066c0b16cb8bec80c9d24a16df641b20eba6acf0666975166bb20c30cb8becf0ca52056cce16db02598ec80e4d96ae64b126db80b27e6685779652b25833cb02595eca0e4e962ec366ecd8d6c9acbd707644b316268b35d906c87a332bbc59ba92c59a2c13cc72323b74c4d2b5d89cc936802c27b2433b4ba959ac9d6d80ac1b59a19ba5d52cbec93240962bc10e8f174de9d46176f0c164b938eb095900c95e591667b32d98ed8bacc064ab6a1663b3ac20dbc96cf08ca5d6613126cb86b3bcc80a8d6cb56431936d81d95e66854db652b25836cb84d99ec806374b5dc662ecb04c90e5e5acd0ceebbe6646ebb7f35aa4fdc9db6fcc4b8ae706922a5bea68765766efc7ac98cff658d90b9815c3657b76d602cc8af763fb2cb08b202bd667f996ac45cc8a71b23c2b7b11b2e27cb66f672f83ac1897edb5b316302baecbf6ecb18b21ac583fcbb3b31671568ccbf2aceca59815f7d97e2b7b01b262f96ccfce5a0259b13edb6b659731acd84e2ccf9ab58859713ecb67652f6356accbf6acec259015e7b37dd6cb7224679a5d0642360d64c77859be9dbd84c38af16379c77ad55f8a48379d9448ce65dea54b534ea64d274a6ab9c9e7e94e49d4a556f940b3e7332255766c66dd21460e066d892aad269a4d28b8fa50ccb7c6dc2a28e0729cbccaacd372339c4018f4121da6faf1b64a6a3a5eecb9bd4c623a3322e91b1f43a058240139a84d2a1538d9b8991acfc80b020bb8e88866029dfb62c82b94e8a57a22d0ba72908604598cf4f0fa7f969a9dd97e34b4f110e16d528450e140bef3e1c7c12fb9d506b291380c4f1f2000b89afd4c35657af36ddea7db3a2374493f9e953fe9dfc6b6a411224501670dc2633d078dc06bcd758ac730ca2958240ab3243df90e3ec9cc1ab3b3ff121d4ffa33645c45bbd5293fce12abaf8f32703a6987d787bf7948f7a3d71f3041f398fa1709b0ba68c482da5665d5dfdeb38f8e94eb20659556a174cf881f4aab2b4dd52a38951753e3c591c86cb0f1a7a597da39c6289f00f0f5ee85d8e6023c7e7493293b5c71983a212105e9cac60c87e58de386d7625e9c24b1e6bea005c74306b2c53f196539d5a604640fa0165c6218730cb389429bae4fca69b31d2ff5048496285a13e0c8bc69a82e81b03cbb9b476aaf4a0c000042ef9bf93132ca65d9871d7d1b09508a7f77759f12c441f001d4dd520b1b813445aba36de4f190af2bff5f8c20c3fec1878f286f8f665c168e8fefd3bdc317323eccfb935c23127fca10d1fe23d6bde79a1687be1c1bedf5eee8bdb218023a35b93bc8b640a8885de77b79d5953e21257735987b994202cbab20f879a6bdd7d627f72a34e2897775c1bb9247a06c8378515082ba5cee5b0d56821f9190cfb69419ce48bd54c90d679ec7df5222d8b1f8bf3612c91f40d9d01bd862f8f0fe0329b07b4aa36267fe4b449a1a6cbe6d6981d3083578f6e578d100ef16568a3dc124e2b9688650f5400067fa32d66d9efa391bb30f8d7e9b272406b5bb2baf6d20131e6b64774c3fa0ef4f7ed090f36dc01ba65096dc8df47b82f2fbf8f5334c8687def36b78599a38d99f17fc052fe4e4b5c04a43b8d23001ae3273ab20083efb8c0e143e73996b3bda0b2200a73f181270587ad5a81e72c252619002a5635f5cc69b2f6f1b1087eb878c0679b368d78fdcd971f760daa6d80fb4f2bef68028f1eb04ae87fae969e311e09ed5897d02306c1f7ff675703f649a09f040bc54610f811fd46b34f1e8e80170402f66b66cf868228c77bc1d062c562517e5aef69b2bcf85ef6d2f1199178bc2ad5785efe9f4a4f79fc29a298133804cf0d802d864d3967cd2be4108400a294df5ce1104d16f98f9c97ad4c613c264b39e512d07471cfa0d680fa1e6469ff040fb070f2af3af29dcbef73a830bfc00a93117af2710405de686e8fbbf8a4a97f711d900d76c84d74233550ae6993f470a271518c823e32e74d139dd1cbded8ce70f03f966c4013bfd0d609b395ed9188b4e5c06ee44ccef54b2fd42d457d41c3f4c414231876a0b263e79b2c32ecdd1989b570947b1ef3874e66abf1b0850463021ec785b8a4baeb5598289bb830120ec7816be3ac3022674317676c023186bc652afa95263eec40327443e32b0ec699adf6c1dfcc316406b6420098712dc2a081f49270e3261b1e64c52028b85cb9e8de97b8530ac248706c3c20471e2c750f57e0fab5302b1ebd766efdd8a5e90284c32254823e76ac63f7d5495fa4ccdb852020aa763c1ff1defe842f3532030029b4e48db30d4f79132e8178105ff52f7cb65b089161ab0d4469b00e4c8b92e2043db100cbeee5d8db9fd17c407f1bf0e7a936f01ae5d17703b2526b02dd9bba47495fa7942e4a95480e71d479a23440e0d6a6f63d1f77fa54f5309f0e01544c2f067d7ce282c3e79d47e9be55c724b8c4d961bf6a1bed3c69843713399c358141e0ecce4029a54ea755b505ad9a6036cd12be6653fb027fe7593aa4c780147ba09cc488cd3668b79ca488253952429fcd28cd334b88e0a01ad265efcad020744400020eb35698b4d53013ca751a6feb7268a7bf36150d5e7c6dfe4b7bdf75ed9a494292519470748074f07b6c5fa38f5b2c0acf832366b7bcdf3512447e681e2d79aec5b3c1f99079240fd95fa2b8fbdf6a01cd86b1f1d46beb6d2451a6dfb4cebbcf62b39b2dfb4efbc8fecb7ce6bef63fbecb5ad8b343fb6cfb1f2dbc7dfbc1e453a5e8fcedb1f3327d689e5638a02f657fe869677f91b569ec5f3617fe55d3c1f4572d85ff9968f3432c661e4b77432e65a0f84e3c39f17583c9012189bb5e24f7dd336ae2b39875f2d1aa88b342b4ed2e4edc0839d30abd532b0885cf91d9b59ad81ba955fd159165d118d5934df6cec44ce5295b3545af1cc35c073798439a0eef32bba179e59b01e84e3f379e123076acfb2b8156b74ae7c7e75be55da70acf06a6a5c3ec5d7b43ccbca7f3ec7ca7fbc1e45e2f7d87ee53b1e287ee7238dfdad03450f24812cd3bee3f9f0bce679ed7d709f6d6ce4a4f22a5cbe25c5b3ac702b45d762936a91fce8f18981c07df63a3caf753acf35f83db6ff41a371ddd681620f50f43e3ee7f52812e5731eb7e46fece258d2a63ef6db73acacd3b82ec62dc3b15a61b5d3a1b78b153012b4459ba04dd026a40c18096666f61bb6f958232ceb32b3b28f98572349f299e5759a7ace93d599277958c245e03ec2841c0e71f7e2a24508c462c5e705152e2d295856ac8a87dbb40cab1d3aa547195146bf90d89ef7109530d722026be167a41b7909fb5595366525d997a5c1af985a6f44dac7be29991ce6fff37137cdffaa6a95a74d95bc4193eef4eaaa452dcb5f5713f3ea734efa18dbcbcede37c3d9d5558b94d4558f6a563d62ef9323e924215515ae6cccfff8ab6ab552b2011de4154202ddc034da338de695361aed3dc5cf17e40095cbaf72d9fb7e5c211dd03c3f5555ac114d262bbfaa7aa4a4652a4dbfe46eb0c96548b10607ec0ee612b77fb6d8c6fcfe198528434b4d3bf30ab7a7146e4f554f165569dcf7d793cb685e769aa1f4349effdc07b7df89880af0f8ca552ab55695c96532d5879aaa67baed423d4709d1ded3953e34da6b53d34ce00a22ebc20f59ceed2c8b5df0cd3d21a01c2a5144114514349effb4520fcffb0881c72bc2bd7338b4b8fd4c67aed991b5a38a1ff73e6b3d97eaf6a3325710d57e99ecc16a29ed14efa79db2d3cb66a7db52b82cc352224c896df01371060f7124bfdf7b88a3d820981283bb84e5a7e11b1dc9fd1a882bca88c239975d5a48e25494425228140a8542a150d206ec7252e84813aa234d049991e533c360e31126c21b4324afbb9db016cfd44c4dd684c20490a89a517298808289d5fda693db77d64e0d3dfa9c74b9099183405f954b4b58cbbd5573ea156e7fadc24cb94c9552a7cc545dcdd44ccdd052529daf8b452149f74cb56b3e81b5e69109c5a402168527ae3b3fcc04b2b7a545acdbef353deaabc2e47edb4cd17bbf99aa391ba94753eaaaaea88b8233558fb8fd120675558f508de0aeaa562eb3d524a20d6c08ec549b44198c08cc545798a9ae30535d61a6bac24c7515c24a0e024fb9084a260cf41e3c741eee0bacfc6f23f9490261ace5a78c84e560adaada4a1ba9a66a18dd494e620ff461265ec27e588b1933612143c1d2fb612acce430df46da46106534d556b39136d246c25a58cb6ba20c528b7c044ed29cd054515b828f20ca6c24af7192939c145354bb95301356326125cc8495bce4a4eec1536ef29293a48dadaa6a440d531c0dac6423c1d36c4ee24e5369ab96410b65b41caca5bd925aadfd7c3cd579de3ad5edd75239aee42eb9fdb67e2cd6d272b096969383bd48372b39a9db4a1b09081be9f6bb96206922145d273946318c9de4240eb16017d6f225ccd475817592971c741bbf71530bac54d9bc7310c419fdd2495146dbeaced539a394ddc6c120fe83102d3245192cb01f669a2dae7b5d4abafd98c9656a7098fe5aa337590ed32976424d317b0d3b6d3253339c46e634d2a29e29f91d8e4ef2920cc245089d1069d0492e022739c9497ee3218832fa9db402d24c4915481fec375333358dcc70a666e8d94e94d2496707a3454c052d86587054c21c370846c0ec28143b1bc10c041040000104104330c3408ba1100dc92524e02853602da594529f9dce0d932277b233aa8348456e6e67ee25bee46acc1aa3a2129b24c2c4fbd5192746224cbc94d6b4132257d21a29bfe9e580438ba4fc1c66a772ede0205b42a15088458c319e985160e30562e9f7cb3b2fba9f7d0bcad183f37acc70021210d070aff23f683c1ec87a9eff4193799fe84a1eac0a6759f6367bcee84b8bd518636c90090f96ca136c1fa34551e5744a0244986408fa1da547f2f2d3ce554f3749e0c2ea08138068180c2479a30420b89312c22ab0ac58859ea84710c94e472041892892f44a127e21ad151621883049490573c7e9cb35a55d5138270abb6709af58a8156b490aec06e4fddad5ab7899bfd20ea5d4bd76b94ca4f9ea6d29975fe37a83e2d81617d4f9fa9d8f47a230722347438b8bdd8fa857b49d601d0cabedc26ac7d5a3af53393dfadc14a55d7c44b72ebbd74ba82784eb90f3386c1187a91e7dfd32d23e601be5d422f2fdcab08ed39756c5f37845be7e7193b8253d8544ea973441bf7a8a2cbd9c74fdb4b5f78416432cba06958acc1d3d9ba6f25e721917dbe0285eea57f1f8c0b2dc49c344611b1ee5b67b7f8baf7ae0327fb35b64c27ebec23165102cff374f120896573655ff27473cf2183f1c470c8528ea8f2cdc0db7f353743ce94b5a5ab81b2c8539c78573588aa753797e79f8c5393c05ce61291ecfab78be8473a4bc3c1cf7801f573ec7d910990c6132a465b32edc0d6725bcf2d2f4562dea973fb0adc44b99f5ff7037580933abd8572c855f2d6a8f73544a7a3439ee867b3c2e5c55f18294ffe11c502fedf84ee9ab232c0ba6fe6c59a66ccfc7803b5f8bb27abb783a5b1bc0097d0285021f319230e05028c4a80e22c528544c312a3212ad22308750a8a8e22304fdfc3dd803dde083a647bf7bd661daab0e137fc40f344f801b9463d37ee3de03e3c650cbc416c51ad8c7b7ad611d0df18aa28c8e32b83a8cac13820103c6774221d9f9f4e8ab4f776cdf8eedd25f62ebd3971e065aa6b5d1d6f623da56c230d7e9aeb8f1882bbc5a874218363d0f1d09c881f3c5a9606e010b3117860483028322d6986ca3d9467b1ef20c28628de9399228438b3f5f2e83812d31d05d1efa131ce6711ba77119d77304582ad698d80fe228f3010b31170882980b0c5da12b746161064619f385b928899628486de80d0772a95863be3f07723f88237f627379b87120c7811cc8d5eab95c51c656b2d96e3693cb442d27fea08934a9706b6da94d954a4917d88f033df4d055eef227e268be7ce52c6f4d2e7814da046d628a94cbb747fe94d4a36f2b953620f335a7780b301778fdb12015ac362fdf4a2f960dcc32ed593c1f2cafb1bcf63e52685d0e0ee39f75452c4b475374a5f9ea1ee869bee80d2569fd980956258c54e796ba5b6b4b6d5098af2db5a5b6d496da5295083b591a4b6b692e2d8a96a349d15e1b49eea014e50e4a91372034e420d80ddc4a2d2a859a493b9992b4126da5a5c21e453984d5bc22a01d7ab4c839f0f5d2485a4903351bed46a55ab15aae9ccc8603676693dd64a6ec94a53c0b630db6fe19186b4857e6431cd1203070be5c2e578c183e5f188881f3858154b2c06ee0768a3578b3d94a5b092b45194eb0ec7dcc7a5d7f2eb90c0766efdea2cb812ee3b5daf63e1b72a0b71c6605f6d5229fd222f7972ab0fcf204242e82fdf9aa3ee76bbeb8108695a6b1e5d122294ebaf279092ba35c99c32e668e514686026589968e25a088408b214645d4294810d54dbb20150a8550298f222589a0508c924418c5a88842b1ac501cd674e811a83d0df08dbf01bef1e3cbdfd1a3e809c9fca3942b3f87ee762069228865cd3d860d50467044b96c14a3980709e8295d0eb1fc6de3e713a37ca13262317a8cdcd9e26b31c618a3288646edf8d72883bd7bf2e57fdc3b59677029c4f2775033a552455649218eb16c20854821d206acaa1d8ab51861a529326a4a29a544755b8b50f2433b4bebcba961a8142af5b9f1a5c43cebaf577ec7e34d4a2953b545f2e7959ecf7e918a5181f7fbd8481ca05028140a8542a15029140a858a020a962b3db43db90f45905637f7878d4590421f8a2031d12188c2294992f81738b244cefdea112c0851024e4209270124c68d61abb5ba2c5b86c5058220188661c82e976bc5b5e2799888349d640a4c1ef6308761a812522252a54da7100b7a329d50a6538b446cf2781a07261391535459e1202bf2c4fd06b2524cd66b405f2b95b0a0b0c572b097cb340dbfa5929ae88912e991e7f253548fb8b0b27ac4798caa9e9095e7adb4e2954e5b6988adf49a6203ca20a0e7b753b42a2a3fd31e154f8d24ddeeb62aef7c9695ad0402d9825c7e4d62a19458a85a1205937219635dc6a07c98cbef87e56037e6b6d231aa61f8e3e4945fff4f5e5ff9c8d1c68e96db34743abf2b5d0da66a19f8b70e4bd222a62fb9e5ba7497d2a57429dd7f47cb8c7b473b3e715c64ee6ebe2b1d96a461f8b96e031af800e972efdc8dcdc3c24a2b4bbacb5b593daaac1639e9d13b69519daed57ed9fed2ebf757af25032db73ae16c6501699892bc2c18d822fef9ead1474d537af47e24c2f01b5191b8fc4938c858287bc0c2acfb845a242d8bb42c5e8d24d1d6fab792cbf009dcc01f36538f503d8a21ceeb8b61db6e2e6fa5532a5cc0909c5390944df8832a88d50c58346809e1c2c931f2d242939674a9471fd603d6830a275102e37e7c72728ac252780aeb7e5d73d9091ff3315a090bb113065efebaa4475f7d552d843338c295cdeddc50132dcdd7e59f467af4cdd50c71565a2b1e0eb465230d0b0fda04cbafb0782037216157ba6ef1f0759b6840aa21cda0c30e4b404ab6b1300c8265e5593a12e77c2042a129d21ef83fd8fc60d393c5ab8f856c732304df80d8c458683249f7422c5cf1b0d0b795ed0200a91de9ee1204559836ec287e6ee73622467e9431367234f0ed16c5b8cadaa700e3051fb036f7fb1b7fb83bd878840ba51bb7d0051eec8a1b8f6c010a05b4e8320ecad1ef55500efff9fed38bee81e47338a42781a68915e8f00728c6d7b6af5e8f95cffe07f79ccd5b66936892cb781e3b41e1c44f9caaf05daa3e88323856445819215b29c1592756abf3d9df60ed67f67d6c9fc5cfb2d7bc1e2d9f7d0fadf391a64606dd87793b622ecbb7ccb48baee535f904fba17f794dabb5d63a73eb8fd4adb5fba2ea56173fd3587d178f83e7e05f64dd1717ffd2695f8b8f3da2215eec5f302fb6e8c5fbea875ebad0d72ef42ebaaf8587438bea873c1d2daa0fea72b4a83e8bae022daa2b3c1c2daa9d6c517d0474b561eabfd0d916d5a7d17d1aa6be8aee5b545fa613354c7d972ea645f55b3a1a2daa9fa29ba145f559ba9916d55fe918d0a2fab6aba145f5553a0b441995ab3fe34fbb78b7eefb6173eb6b5dd67d18e6ed88ad3b5f7236ecc0640893d2adde8e7a694c8b6e64e89713a3503322c9c11294544226d1339045d0263147871d783094c6c96956a2480e7309ec67a51342ec8424821c4204a210c964c99277ef15e7cc396fc41acc99bf1ca6698c116496f3cbf2909a7bca6142218f9cafad4ce92bfce217db68f025917025aef2d0538e6a906df8104e849f1cd530461a26498bdc4f3e3d3525125465658bb146643f31cb82cc82e26ab5fce4283f798a32cb96e26bf0d88f7f5d3ed27019968f0d6ee1c52f7e4997423bcf3979e82b4f8ac94960d2f8c94f1d2f859f628cd1b6b87c1d516ec29a8931c656ab15b322e25fe9ad76d8c964c2ea0acbb6c2f1b3b45a58a75e96c93ca5a5490dbe1a6cb0c1966d763cc5d2a9514f0a8e4bfc2dad56e577695117159b0bc7af42ee90c343858b8b4bebd5ea15b40f1da46dfa87d34dbf4b87f27f663af4b382bbc1bfe2d56a4925f40ada8738a3bf7f20c22f21f875040bfa9e960671f86909fe1209cbb3e3e24d5cd2c9ac2a5f78a16d3ac80b0d7e784a9324e935ffe3d794e91da4b5155be4e6fc7037e6cbd82297d79426a9a86cdb67454bfe8093b45ca641904583535a44a21ebff8f5e1acb7e373e95bce06013019c2e4735770910528d441daa6c1065dcc6fe16e745e5341e9cff49c208d1c482438a9990c69829360506eb575deebd35e35ab5bedea1caf51d0352c851b9fa5f0139753b186fbcdc7a9db2b97711abf893256d66f66905962a904dac46ffcc66ffcc66ffcc66ffcc66f2690d9f1e611bdead511e6a90a5a0cb160aac4a47907b8571946734b9bb43bfd818e033ef67be700492271a0658fdbcfed74fea0dc3da894524a29fd29b7969a7b9452facda2dfd4fb7638c9d624d8786ed3f9cceb54effbb44b2ae99ce8a46632848993e41140e6100b69822cd334dfb49a86e9f76c9edf4848b0f2a707b68e3907cc5b5fe324d71c398e73cc9375f2d6979f7531caa8f276381b2a0f1d7690127b7fcc935e065a6eecc7f1d91b7e3337262606873bdf9f76db9447b0fe9f4f4b4fb6c8b9de400dc4406e434915d1821c2dc9ca99351a23a591d248698c94df7fc6238f96b1114ab7ba658475b9caf6f70ca29013051791fbd11514212e53274cd3dd60db801e842bf6331e1d6c90e2b4d81af92d3685ade156921b63240d6cc02898e40cec47572eca9289344dd47c14bcdd1b5d429ddc7e0a1ac16e40077b290d828833fa3f2641695d9b235058fe4396511c8a4371288e16b97d8bb1b19f692a04a5a69681aee88a2ea1ac1429525016754297a4484171280ec5a13818b5d1be9f8272eb6a3adcc21264d7608bc01665df1c0dfcd9d39b1eb1e7d4a64799d73637b646d255a491ae3a7405764090a327656069b5f6b3f2a8d095e52c5dad6cf771986dfbcdeb217a4b23e66b9889d18123ccc1e38172787ae0e030bd02dde043c5dbc1611a74c3e6f178384c577ef63e1dfaf2e8b4c0cb79349b07ba61f3e1913a2c558172a8a878d4344f1e1ad213bd993e58b015b03d7b9899999de483e4247a136538bde97cccb0faab5e4dd76daf495d636487936ef4ba94733f06fbe912d086c6c641caa22b073fba622325b01f33f839c8e06d56e2f67b9194ff90838e36b1f1e5205804fb3178410ec22520b2880ec95bc202864c6939b911090e0b09ce0c5e58c090574789770143727a14916ce166c8ab47a01b61446e42134164caedaf488848b92d8bb03c649a60a1e68894251407c8955d28c6c81487b5f0c385e1c6235990a205d5112d10a14da813ccd115133aa02fb35a4a922357785127681305a85247ae604ae286e2501cda843661da24ca500aea88945254001fb9820dc5a13831862411e41022101d0b6de384247144241012887e76dd1a2fdb76e26e806f95291bffabecba9c019976013019d2844f87248aac1a691f3f8638ca3e3e8d38431c6d1f1fc74c94f1a8e888322b1fbfd8c23a35a43f6639efb3cc2a86825d3c8323163b91a30cab785e939ce3259ed131621d8fb3ecb9caa8785e5e2df3ad864f198f8cca48cad811bf15388767e4b00d5f3110ac12558b4287e9671b73085fcd538b26aa6537934cd55ccd13bd9e6ea61c6686776a1dc975a626aa456da4617a0eb19aa7996412e1a579c2814785738ee03658e52556b98d83acb2b99fafe6491af152a9449b941a88f91b77c37ff36c58875d2c753a9db06de3fc3995cd53ebe5b0ae735d50dc909eaf5e6099410fe7afb2b2692a2a9cbf652149cbf9af703434d64926edf05ab11b77a3bee56868acf3bbc2a2b59c098e449cb184e54e3acf6919fa3d9652e1f6b3d44e88b52b2b3925ce297114767954a40f566c544179a5f06f5111bc8a44b8582221c402958aac0412224ea1508805cb281c99d905854245da24b21466668e1c9530c7cc9a44c913c8520c61218b98434c43140da98a862da2495034a4492c55d1b065502d613f1a4e2f8b1e55f588862d6a95bb47552d12350dc3ff501555d11045c34a553151467fd8238e3ab018e8a1871e6236b5863d0a93ec20ac52f8c5399a166bf86336190d2b46c35a69583b34a4a19bc083f017b80f4b5822f3344d14f4d347c3a87918f8f929f29f7ae4a828b170eb022a854aa150b208921dd4c81cc81c4826646491500709c518a913b4097582993986d872cf148736a14d983689d2098a437162944dc45428ca22acc44a16914cc4105b084886b0899d27c1d348b09999a56429594a6649dfe3d05b2e946dc5482353527257cb2976f500e5d03c1b07ca91653f68a4b73c5b967de6f510bda511f335ccc4e8c011e6a079a01cda73cf69ff8326c33c5ba66518f698f65ae6816ed0b8d73ed2480f847dbc9ed205599c099423639bcce392e6f98a91606ef5574bbd753be5ce9ce2542b20fb7e36c2218799046b7b9440a150285488de38e8367209fb39e8a04d8f648f9ca3042d759929ddfbda7eb4e54484a734895fd4d5ad56bb3edb399fedd77d81b3a5c47e14bc3408bd098574f062542ac619a754ca19c79e76fe9a8b5a146312b1fe59f7fdb8598bdc3d89f4be1d315cf9ee1defdbe1769e52ed675ae674a6d67d1fb858cefddc3f7293bb08482af00c4a6517e5baa402cff097de7927735ae41876a9ecb0785f7694763a5c76f5622f3b065b24b1971dc5e8470ee389039b438b7a06951957be87dbb40c93130157761b60abb22aabb2fd335c8ff7cd88e1bc4f04f3dd8a955b3f46ecd6e728c3a376d1ce0e8b1046ac60070d1b5884304205977a201be4a52f2ff540f47fdc98698a32fa79b80cdf20b20c2e7d246c8c008f947e30c4ed9f432ced1bd8cfda964fe8618862f488fef4968759ac100a857812618eb4497c115fc42c0b8542f2897cc2513e914f9879ea60ea80e593387310a913b4096d125f50276813dac4eae077e3bef3f5bdced3c516d1ce6b1c0ddb6380f33eceb8086c77dbb2a7f57534c6dda8d90bbbbd76eb676ff6f1b3af408ffcb3d7c137fbd9e93a3db91b1ae0282ef79c07baa17bef27d0bde7fdb859a7755bc7755ff65b571ffbadfb71b52eb26ea683dfdaf919ef74f26937bdd875b136e9a569a2b8f7377b7c034d63cb0055eceeee8e1c75b4283ae9eeeeeeeef8a3b987d06288958848740024140a8542a894c4914fe413f9443e914fe413f9443e914fe413e9443e4126219dc4505e7e04740c456856eb740c23468c24dced2ee59cb483fdfc5459e5a7c39c2dead0f862426c5bc41ca3453306460f1e3a7ce67ff54efaf577ccfb68dc7983468ba6f7ede87c78b01dcfb7c39589f104b6e7fb37676c2602296fc5bedad047ee06b7b47c36172f5fbd2f2d3ef4375a421d0c1f5b6e8c9e1add7f2289637168c596e88557bd4ff4f175f158f7d9dbe23179b127966b6109b5a82ff5e5e5638f56bc3c73375a782f1eebb65fd17d7f5f3c175dbc2c5cf77dbe1da20b807ff1b47a3ac80b00795dd0f0e26178eaed4e8bd7d8d298a145f7f16d516b15ddd8a28fc6cb035af4f2f2b15f7ea65f5abcb76880bfe85d741988ad8b017f91e8fd6be71f80eee31b8087f92f1611c3e83f1ab7ce70ebdf68038738a3bf005f5fd6ad4720ac85006252642f2a64f8fa33b1c60092dc003c0caf611ddf1635647c3f272306866158cc6571f9162edfe26bd7e25fba8fefcb63dd17733196168d53f9fa9f8df2e553c878f28965f11f0d17dfbf0393b8a6472dafc5faa150e8b92e468bea6b9d08c6c7615c78b14531f25fa2eac371ebbba4e8c0b8d977381b3ac0640813f0566f47cccd5ee32d45276fe4b2ff747c413408f03dd39f2ede972e5ead001ddf171030e367fc4c6b2a3a03bcc636868fdc8d03fc4c6b188661188661acdbb2f22f2bfff2b57bf915ddc777c56358cb76ab55f1b4847ac4a27d7d183d6af1f5453d72f1f563d48f21d6e068dc15ffaf59108332a06fdbd230f5fb419de81ba6bed6a2934fec175b38b84c4d91162ebe3f871ed9ffbcd0a9e8665cba1968b4e8aa8b6eb3319e2e8607e08832aaf6d27d9115c3aff8f8e6c6f02df55762f80e77e32b8d3bfacad9d0c308150871ba75f41a6fdfc93bf272c81043f78016d53f4017b91b06f0665a45176f01ba78636610a0868c2e46763462743364ddcc003a1d0268751ea6fbfa7eb115ea5a2c62f761dff94e6283076ab004570b864ed27099fa800e4017af284624f3fd1646acd17d7b19105d0cbc7818fffd7df1fd1a8ceee575dcfa30ba4f74613cc3f81987d1bdf897eeabde0ed1adffe22377a3c2e85ec87458e7755d178a32583ab1dacf78ed32105d97eb8dfbda714fbbad7efdfaf9faf5eb7f5c86c6d7af2f721999af1fd32397af4fa3472d5f7f861ea51861bfe2ebd7d023d0d7d7116ba87cf5be1db175d9da988b819677f19a8b0e7bf1be1f57ab1feb4b978198dbe223d70017fff233ede25f1eeb5ebe765fccad2d9eb91b2fdd1733d358d7f22dba0fc7c5bee55d049b77a884ccd4593d09118d4004000028b316002020100c0744428118c8e22406a70f14000e6ba848604c1a48a3811cc77114044110c4300c630c3186186310424ab12a9b005ac2579bab65f8533bf8b796bf30122904d15ec78665acc2f58f450ea5fd7cfa5fd5b595602dc3a11610784025a937756c3a355c0e6496936a25e49ae20e8e9a2469850e55d7a14a2c30258b3cf0b0945cba7d027d3d4df5dfcd608f4641df86449759acfc2d4114e0635b06576374015c2511a5fb261feba9f7aa993c3cac68260aa6d57d7b304b79ceeb6e137d279374f2455cd60a9b416c9ce89e80163970ce12bc37d6f023648f1cc9e0895706844dc1aed4e2555a4dcd130d9b8247034e970ea6576b29b23225150c469eb8582917a52315132fb9d9142cf006ca48f7db725c09b1a127ed7fc2f8a5815f6e79a539c82f9b82a11eb117cfc5aff7a427bdc5f71ce6da0438fb6c0a9e7ca88ebbd818c0ad3b08d832de54a3b944e036cda6e0fa43abbccc76e3c66908c413d11a70947d125c5931d10b32295bded8143cf521053114ce24cab367329b7574440200015c7ea8d623c8868b751a2e334c9147de77aa1433d12c4c353993bd58d03ae2752bfad6cf1c26df956246c79c31a53c4b0a387843352397f12faea762c2a9d016e85843a9b22918d5a2e59b378b52f94b71606ec3a6e0a01e34ba55c6c29c122d02245ba9750f9b82f106ea0d3a62c5f9dfeb095219550e09b618b63f153409fea6e019ec62806524991ecacdcd34c51e3b976b44edb6f5199f0c3ddd29225fcd4d80a7da3bde479a619511a6ab17e9d03a846081910903cdd98fdd31e774ecee682a9c6bdfb111682141fcd6a904d09a7b5ac15774d7ad05600a23a99e6834545d1154257e65c08558b5e109b67ae3407c12c88d3cadc718d486c6a7e6b734fd3bb38a70a50105febf77889e502ad3706f5053c841352b001c11b29c8cccad05f58151f80c9f654d82a2882d51240d9d6acb792285d814e927a8d5059e1395cbee6254271d34d4935597c742a734ed64308aea76857e882e4e55852b000f8def438c134cca7e702f457aa9b0d996c6557e8216f522fda6e0a8b7e81eab04e83d12fd00af9f19c27faf68161b09389ebc4037f4b5215a5d875c299ef3aead7bdf027686851560f6dfb117b59499336c4c514e4eca6b260c614ae96d700fb1eff427984fa7ca95e1d34fafe663bdd3319d22eaa9aae9f0d3aab6cd44190d784db9da36bbb12d3a1d93f3319b40c4517d9dc9ec456d76e9e35b7a94dc53d94387df16a2e076997ef0572c6ca09feaebcde86db81e5a0f6b13cb01e271b8c6d24caaf57c94bddb2a03206d6efca60eab8a5851302faa68f4d812af388936968fd1d453d4b6d5882d38db16602dc10b6e1904c22d378ae1b6450a9983b3305879da69245966f0755475e82da97737b989acb30e4d363d18ff2164c28db0d435b1e0c69574cb397c80480a6e33cf82c58dc33efa3deb9abf6d762f18aa903d2f2cf0f476b77caf93af569d9b25090e2bd7164aa92996e21987bbdadf164678e21aee922eaad42f06cc67881169d71980f4cf9973b225fb946a86f430d00fbbefbaa75be3ade9aeb06a5942f8508d0823764ba34873127408681e22d5e0c90bb2704195a9d128c830b1e518e7cfe574da6ccaccb9bf4accdc6e641304a23eec807ff796f7f3d646c567b3cdebe0aa25f9f8762e62c091776f845c469fde781f28a3fbadd1321417fad335dbfccd54156a9537cb4ce1396e4e834eece2d852c07b80f43b431df9ae0f3dc0de1e1dd75e71ee4e33c79be9d6775a86a1de72a2f3f1342bc3c88c439217398eba99b5cd028f9a81f180405d4c58ebfb03b6209df6cbc809cbcf20e8963f9005135be84cd25a21b6435b15f9fa86672e66cd367f51f7d3cbb6cddc134d988fe1f418c228c438847a54c334ca2263d37298da46773d804570cf61cb9e79570f58aefbd4f1e9851b6c6526ad848a4fef0428700873c254b8b13d53407493ca8b4134b41328db5c4032b0331cded22609f0f223e5fe604b30c68244c133d5eb05d94a389104bdde51afd3908cf5686095a4ed9d0bb6404cf9ef1384f6ad654493b79488e0267d8538a55c69cb81a97fcbcfcdf39da5177eb17a8f664df3cdf44ad687ce73c44b3c64af91fe06b2b2f1218a23e3410fa39a76b2bc68d6fedf07c00bf99529966d17259d9cb87187c47c103b113442f66ab94545c8533938293f87aa12b19437491aa46aada64313b6d818c17cc49a28e3c659bd16626bbed77ff8603e66c035461e62eb8cf6c97b9d5b5476247872905a50367a651ea8de0b159bd3bc8f31ca13de0daf1255a9488360948b3dfaa328f0aefa740f5360eb02130db2ae8a85ac2b05943923a3cc8c9031dd3357895ca3322c132c80bdd791176f39fa092b7b9c506bd9a074a04b01e2a9ade14788f08862d8ad36f011014b442a0636880c4adde9f0de630feb2f6952ed5bdd61491356bb123724d7691d47b0cc5aa4931c4fb8dc00f059235c85d21ba022b66afb6863dc3f65ecb68db7c392644c16fc566712413cdc6d9c155df6b8b8173b5cf5ca91db0c18649cc8c35049c3d642e1ad41384540c9165367500c9725afd3346b861afd6edc8ff6caf120fc40d82f00307948dbddf336519958b5e69bf2946ad759b502a15579f4700588c64da785071f3739fe3ab5fc492d37c42c9de01df8c84972be1d2551b6838eeed2b67ec5646fedf436abcfbf453a48770fe489fc9951146b55745dc7a117b858bf876401c1585b90636bbf925af99a9cf75e69323e7a4c47ce84edd0dfb7ad73459e9c5ad0f490756df406ccc5580b3996fd521723ee7fce1bf8c8a9e43c1bada2ad69f7891e0c66e38bd366e5302628a9d4e1118d2b7ac52bf641d768b522ddef00b38e811ebcc24426150a55ea3970815327ff64a02a61a4e876e6a0c5c71b18fdf18bd266479ae1980395529c20982f9af6f70bcb6253e662d42931b963075196a7bfa1d1200372aaae83ac88ce2772220447caa57c17937899de4765bed6cf5a5e889eed3dc8920aa7454f0a412bdf05650b5f4eb9db40adc6b1ea15345ce23c30af7af6b2e13302408353c9cf3506addbc61beb883e8f856243272e7db23453d32902d4cf785c9dfd7690821bf4db06ca570b742fd14a28e9ec59ed37040028f37f88f6b7ca8135c48a80c39cda875331624b42be5725af25d960b4da821c50136f1dad58ae42dc4df3e60979ee8264aaf031642cc13b11c601f025fccff5317f713410de586627c7fb33eff85300e8153f4c24bf4d6d998a5b5d4f9303c497be45d8827b44623a904ec3797fde44eb3ec911077a3bc58370a9e010204d75f122a1189373ff4a6aef5c5fbfa10e3d6c7d1bc206410f6f039738307239b624aed26b82815ef9e9051908d17b61a5d48ff90723bd41d964cec2788d3ef84d1a145e13e15485db4ffdee45723188abae3ddbfd3036faf63951f26f9b0f5fd72879da82c391dc6deaad069d3d46b9b4a8a369eb9c4b9d9cd595b30ab3f19ae53119e97810b509f45b94ad4c9dc956f39c917333a58e5e364023ed8bc4a81705c52eff995e44a957615c52921fb2b254736503833854df0dbebea3f3e965b53ec4b554c45dfe931d66dba0da1fb98a8ff077f4f699bbaa6084fc35e19194a10b2d904f4e6fcbac23c9121dba83f74da395ab4070c2f790dac67073056c54e21b922675e6c555fc2ec3a62f0ad717c475203c29fe99d35256b5b006f3412b43be72ccbf3e39e9d0b3df6cb1a8eecc9cb596602dcccb1854ce08ffb25f26c6e4d52d90f62f7d8e2ba04a1d224466993b144eee2cba7bf2e2d2897a5a2727ff3a3fd80864e9fd2c7d2032b8e72979c876318886ec37e7e0027815e4ef75811a032ec61b808d8eabda2f1fc2bcb641f7cf64515f3a16089b2c3f82460f9a678b2d488f04279bfc0c77e280adbb3c760e433f4365e9814362d65395fb77620749a19caf813e48147544b53a4f50aa1d24c64cd3ed79efc185ef49c7c33bbaa27c876765bdf3099668564244477541e118b4272fb8218161096337fadb04f8ec3d6467a3fb87e403f4b3e5bfc591c2bbdee955620a243aa04b6a1f2fe55acd7dcf7e48157efd72078440770333adcc27d2fb0bb4beaa1463168fa770eba14fa7520415bd9f510b8c034abc970750c66d398be3eaece4bc1398e8bcffba1534432fa61f99775a08c09dd634ce257c9f772d672664b70684c370cfbc47ed8f74d5fb35456c2751579f94d20acb4d7fccf6f4b3b7259ff75dea4e65f1e6cfee2efacc173c36083c9d1456aabd32ba68ffb1006318ebb2bb112b6318e7e366761c51da72214592acdbf2a366ea0794f8a1bd483699098c7acbabcd24dfa5b2e4d3702faf8b0eecfeecb7faf23607e83496caf6cbe47113c45dac41176f109f719e3ec2c4599c68f83ab9fd573d15be963816a6c11d88f7c28c3e803043c1cde6770e758c35f83cdc81119604509491256f526a02f85ebb221284bf01d2942a5d0d80521b9304d4977ffc25d647b26b3fc22e36748dc37867df9bb7510de2dd3796bf9d6301e68485865c0ea012dca729e59f1883a90992ae9f1311d80ea0aa66218b89bd1d9371188eca6bb8dd9b278ef4737cc4b925daeddcf26307b20db79a4cf17691ef520fa14f42dab97202cb8c40539aa61ea9247bf22b85172c5def1e5aea427d634aff5416e5f98bd20f4313da1432b176ea6d856fb164291583d7251ea82550ce8a4b0ac905e82c64eeba62f400c8e1aacabf836430556acf5b903b1efe9cb42f76c16be811140dbd1d3c7edfee2cbf812ec2156feb28e34be5534a91a8bfdff7f439c61846ef8754ca63ca43b71fbf05c864d126ea0f445d6da997c126dc35863a275e2092ca81cb0c6501218d7145e2774abb8b70d9ed3640cadfc9be0eafbcfc52c826a0d5d74963edbdf9476ccbd214bbd5b87de967eca16dd38ecb5ae65f2cc7277a7178d0e70f626300cdbe74e5c0266c193037ade54e157473162d75fcacfe3519d2b78ec565f052b04a3ac6b6346fa268ea34ff2eb13ff84185a7de9b83f0d597f7f2b8f4da01836ec6c2cc6958e07cc74e22e9926975b8b9d3696ff776eb2c1853f72ba63e2b4c3698f75b803e525e015d3f3c0bddf86154e4606aa89857738ac919ff07165d06bac0c874e8bd22bce68558d44bc9cfeefbc40c6cc92496083d6836e4f1bf8996c92cfa402a168a1af28a117bb298ddf60a03a7eb5d9bc572e36af6733447355813788cea4c6483fbb9f46a7f37d449c50d2f1d395a4c6edfe41cb7c62f3fa1fe182785bf22636433f0891591356c74b93236ab7a8f8e0043fb977d1e3004e190f896edf07009066f6a016f1a785ca5f0094084fab1670114c82806c99a4848b054aee76c12e47b07c9e3dd0a6ac943b361b2df2146728ebb0728b206d4f3c66eaf2c6d8c2d4bd5d8aade1b4c648828893488cc3c273a921b13b0727656edf75cffa1e6b3bf9a068f86a5d49411aa8f11491b30e282bde7d36d4c895caf1ed59bbad699b78a6160cc01f81d7f37ef6956f71e06d5a430867097a1072b186e23d739be3db5ec72ac48568080e15e86117a3b3d73ab59e811db3990b05291a2bc2c487364a32dd05ec48327ce7d8c6a21cf69aa8be24381e1876538fe8cd04bdc569ebc811b7a2d066aeb457db2f256dfa281037f2dbd6721913bb009e172c844a9bab168665c522fbaf59c8823208ac195594b6ff3c9d04e1e53e23c8bc6f2c5039890c8e2cd2f5c208f1baf912e34b12d7da8be4db7e40ffaccb5f4ba8636b82e80a0451a97174037dd7ebe48ecbec090e48b1bd85fbff84d40d6733b278b16f6984a965e85b1a4aa9a7cca350b4cac5edf20d759c04c0739b2f4266311b20cd8418f3487144b6ebd2825fcfd9256c8d21b7a5ca97479132d12aba769a873118a3c214b6f9784dd4d8049c6f530c1f66946b238aec520872c9a149f9b2dafa1b1eeb2d91a634e7f183559096c5abc9beb87901064810ced50c9b001124dbbe17dc003bd965ebf0b29f6b05033183ec3d0bccfab7856f13cecdd965c6c7d0b1d9d725cd3019f21c2047188a28a8194f539200d4f761b36a7a1437666bb217c6be9addb754f5e5e1ac0f5ff4f5ced489d5cc2388a2ba609822f2aee30328460de9260bca97494a0629087a11ac14823a6b2c496c0b7edc75a4d9618475eb1d759e4c959653662dc4093280579b5a613057fd08126f0c5bfc4fc9bf4262ffa67be5025f0c577bc00b19ecbb579127d59dc9a8f275f22115523c996c0371b2f5fcf1223d87c028897e8b6f0081c03f192f31e02f324d9bae2b104be4e7058ec77ada2aaa825a412f8ba9085cadd3f7235011cb03b2da065097c032fd0d009e012f8729e90e46a394d106101971021f6aa0662b542e6f295c0f7a283cbe24234c930ece07cc5b080f21d4811e03be85288882953da69a6e47c2196ebac1d773d89a1d180a1c7dc50b2866b90b406d10bb010dc9acfad67a98097d5034aae54097c931e901b5bebdc8b97213f91c28d946a80b03a0ce0b2b7c1483ee854025f2f5e7114bd688d6305a9a95227d54a12c67801b81e9b1f0801006af4168a2c5e3f3965ea026f5d02df9ae6ee36f0fbdca2c662f7c94b30d2e14b03da0be53fb599a1114893dad7e6db6fa745a3c99e834896fbca8eb7321c9eca66840b5ece0c630cf75e45378fc3007177d7ba18b2316d877b99dc2b72d735ae8661df8d4976a14746fe92469f552f010c9ba8ae05f7d8ead4e7928540ffae1cf94d03e09bd902d665fd796170ee43008456cff9e18511a204e4b843b3991e2aa18be328acf4d88a4cd2f2c5aed6d50c5c7b4c5745007cfd25f48926ce48ae966139bb93d5e85102e07b0ec205e5ddb9204dc311f31161ab3443b442bad119005fbea26a50f34dc8fcb691328f2c0de2de7548b1460a80ef4641b67f2ecd8c257ec9bd0416d93a9d50726988582c300ddd27367bf3ce372a00be681ac5bdb795a1c6fac90603e05b522639a90aef2ba60ef8521487d9cabcb5c3f489ea0e372667f563df6ee5033db523f0ed26fe68bb4ce351e63706acc221cb36e38f2a4edc7b3f531c718b5df4073fd3b7d2e92677c04f4df9e981a7d5a37666a8cb1619f08d99edc13343ceb4865eff78ed9af6d83ab3abefc10cf822bd0b304bec80a747e3b4f794c4f1d389e43fd01277579a2392044434eb36dd9ad95c171561e0873f9e10dc297b2dc974b8c8a5921fb7baa47eeca1d8b188506047ca01df962ae299f17cb3fc80677e7588187a7ba7e309ac93889142ad4702bfa62f66d0874cb578b17c81e180ef1de92353967c4543b3c3297de4502426651ba9b7e0fd0eaeda2266e0ee6756b98b8d1a3f71b6527442d14be6bcbbccb14ae6b71f09b1d711ec7bbed82da058a833db443085821977324b59b658f13a68db6db315a558a73f79f3dd887e2e7e64767a4eb16910e56d86457929c9db152f3d68957ce18e570261d1b2ea2947fc327ff42a0683a938eef86a6b193e615a3330205c4288bc7cbb4cc512f56a44bfc4436b99e5b9e145784e95c744abd821854a62e95dd232c545fbaac1f945b5359741f739719661e1d8d5acb0e1bb75933f48581dc9b49881367e360f86ce49686719c08a4f60bd664c147757dfc97e4cc15b82e93fa22199dafc2e4e7cec03f706f5e35709029ea0f4e6b44be0e947e0bf05aa1fe1057e8dd3beedd0559f629c8bb1a353b79994776c868b55411a24ee21fd6639e0cb5960ff4fa12ffc4e0818cb219518ba2d10b15480bcafd50a98082ec5d5339e3ebe471af009ce829d09ad9e643aa7bc64d7584f1bf4a95a3a5f4902e346ebbc093b3025dfe76f824cebcc36885736fcf422285c9e60f5150643a2e5dc1a2ed72412150f8328f532774e91caec035263bb50c98d005663cb5709e881b72ddad6b8f0bae83b0eeaacb1abed9464b65000ea100e2b11da8d5e1e3f7339b7fda5c362b6c96c33b2e0ffb4bded735d644b9a459a7c43a8dd18c88f4da80b362c151d28badd7c2de67a40b7774cd843f8bdbf336ee7378cab02d25c36f3f5023aa88118067f314de66a52043627e5147d0d50479046a65a72f894fca36a03f6050a10718e923cccb7093fb952eed00daccd25704ea48d5c76e0a62d0af261e840e905c093a5a0913f8c043c85f6edbac925e8fccd32d8f281f981d2ad2be376bc3b47d868fc3d68df257037cdcc144181746adcc3bd6b4a7e55b29da6b04fb635d3e3eb1683e44a3b69e08004722c4dd98f32bb01decdd234df0fea4112f416a840fb7d0758911d7c279e3cfa0394623e4a4ae036841a88568748bc7058f8bd335fa4de884ad59ea44628bcce66ebf5191f3f660ac07710a627c2ef4de89596b64fd1b88605fb48466c99d501bc709ea285a5fb5cfe3c20ed7893194823c2eff597f49c1a7849d1123912104b24145198cb9a94664bcdefbb2cbf97babe6c31e56e6d4e1eecb2f496d9310cbd57dc6263a9ad9facee29d518d7705e0012744af5c7bc1e85c221807de6f6bd7c70f932f8bd4e996f44ba0d6f879b47ba2e1fa1cd14359100ed882415eff807be9905457ff29231201aa63fad061120490b8972bcc2974027419b219d5e8bb9765aaa7a7d81997a14403d8c94c78de181e58b5af07b91c5588d0ebd0b7e0274fbc16f95c82222121bfc41c06c5614e8a414d9c965dcd7b428e3ad71a524bfea934d14675e21a876054dfd3a4ff2a1812beee4f1952771582bc207d9ad72fd9b8c28536051984b47a6aa16b544941470961de69a11078f49305a8de5dbe3da5b173aeae4f7c124a46edb9cc7d454fbe8e81c6e2cbf174ba3071695e17b39b092f0c667c21c262f1fbe7472de5017a8412bfc17262b6d91a3cc054eca42b2a2fd01477d8e288daa3cbb6c99cc97bd72334da26e42af1fc64b3346794d540bbc95e4d7cd824d3788eefd7b6caff410a330e8437af4b9a4bde35ec3fa237078643a00d639d907259a1dd5fa69e6cbadb04ed3c9c0223b5eb03011f7e6522883d2652e9a999f37097803bd039b2b8d4e6c607a5298e1c20e5f6ad9b74ec3392e6756df6bcea1a5f6ea990e0488b837cc36c5d40f24ec711d49f9161951639c79ca7dbdcdca4dce5077a59b9fe824096ac44dfe7f759663277c33a6887b0b6e701e140ae340baae807f2e4689f6d1a3227ef45cf5433ad2c2941e0965190aca507fadd7cdc44fd04c4047bca6a5592e23f19211dd0730255e6cc50bbca4b2ee6eb71a7a77e5a007b6dc788869c08d4f5e466479de9b78dbc936e66b2feeebda3cdcbb2e48ef8c31409cf28a0f435ae567d278c8aef10edecb7c3763a9b870e83f9cb10c9dba989aa9b843d702c4950ead2913512866fbc6c3068c99aa26871acb91857b1d2ecfd0f72d62a7b80af7767897730c3c1ae103d7ba3d98fc7fba49857eaf75742c0639f9ff7a260e7278c84c6e0079c63f4ce8bc01f7b497cfd62228fd89c1b4c3a27ece634c39ffdb0968370963d30de4b280e770657df9cf2252b5e583721888fd49f1e378debe656659eb1eeb03c65ef95a770d561285d4aaa49f211059a74ceb36d573aba94b5bb9de8eb2d479f0ce79a6f45d81485b1c81b1b79888a67cdade794add504430005a5db9ccf73ff2b9b0a27619a0cb8b432b07632fd69b8dc44476ee445543a13aa6de405a86a334a9f63b65781c5df07531187b2b807342234cca98a4755f518325c12d12a4b4a85b15e874c16b42c5753b126dcf22ca2ac0d89b5124bf4c01673c020bb6ac42db307296020e950fa183b137ba520a7421e5494ab3c80c747d26393081d5b97f95578d7a066cc8eb97b1420c3ed44b89a8aea88481b14dc9837eefa3de00b2a31f2d638fea461b967c79d549bcc9ffde56c36ac704c144b06105fb2eb58216d0c0368e93de06054733332e3a7c24f0b9d315afb65009e6bb89b2735a1a385defcd9f933fc8f43a00da58c10797dcf7f7e0e9fc2280cb43a5c64546166c0b768c4b01431fa6fce4c81ac9480204fda32f201336479d61ba5c8d7a1707faa89d3a55e4d92099d01fafeb2a68d8c3db9030da835b2876ffd21aa330abf7be3d71267d2d4024e2faa1d5a25fd4fed1af73cff2ab43bd6d61c39732154a1600467ede0c70f963f1129604a8b8d28eb408ce72750ce71ff7ef92d6adba1d63c62ba057b43f9770c9df878abc165ad8daf0c69c1b8d800440c756106116d0c08a3cb1fc74f62b7acb9f0f73aae72e8b23ff96b55252a7b31344eb433369758655ec1c7798b80eddcac3910ba9f824d44153781e23fec21231155b65335bc45e3f67c0b16115c92b018d67605bde3a37a95af659de7b19615cabbaa9236866b536c0c1afaaa0db88d0ad7e684e6b03ec48e03cd0b03066b29eeb5a3e8275a9b6f4788e3cae019667e5bc69cb21d70af4b01e32b2e967b3c5cf95d3a9bb069840d7edb29abe59ad562517d7002bbcfe4c279e8aed6cf5789e102c3d33f946ae06b81a7f7f7ffa250ca320d23ed9b635e162a726810519cf5f69df7b1e84f10be4761e45554b1abc0e8defe6665ffd44d6aadfeabbfb919cd1146ae7f9a0a3de6e8eeb015e604d01bbdcfedf6e67f2dd26f6e499376eee5e50a3609e702330629ed81bbc051c1d2b842b9a9b088d58c6449a7fb08a663dc050deef94bba58afd9e5a8f4b04084d23620b1b352951608e115c692aa7ea4198364b678399c429974d565c9abd8336c819bbbfda48ecc27bcc279092934e665dbe45b64021fcb5a465e53d93d61a6b55c99eab86c8da7f4668ac69062cf682b5d487d5b3a764f8095776525ae172344049a0b0ca078e62bb81a0aaf4346cf221b0a6d91dba62171e69fd5ffc714e2a030ac418ca72ac075ca0b7c4b17a8906ec4580035e97a807d41c98804dbf9b0b9e194f8a815692a01625fd5abb760593d451bc507476bdc3c42e9c3f2fe59783d3f1651371048f38856b36c42f5193b8b4c09899744b6fe36f776a6b6a0a03c0c0b04c9fc7c93205eea4d8b5c5fbb78d59964d16ddc37e16ef8ee5ab1c2496b5b0d885334742036464c91a731a77b84a3fe46f95e9ef63398ae1c38eb3d77fdb900d87c52ebce3cc8bc3f1f3d70e5d8f278cc5b758ecc24e8c702ef94802582e5e1bb6eefa9877055caf10ae4bf916114ac27862e98d23e8cb154cffb569f20d21ac642d57057569d4f095b35ae31c08755f6a062f84d5a3625a546df7cec47a1addb4c9f239db05fee4c02f4440e6d5e64f6a5463481db5932604e5cd074f5bcf7373fe9ae67d6c3153dd5ca9b24da5f3d6f0925cb4c7d0dcb829a0e1736139be477412837a1119aa0ebfcf856558d27894e6bf0fcec0cab9e135226bfd818a0575ba3e37bf8171615856231bea09ecac8acf851d93d346de513d966ebbabedbcda6dabeb4782935be9711023603789f6b9b0aca5eb16ad800d15fa5c38cc49b2c0a30982154e01749584ed1a02e456818a3924e6526598cac2d0f93303e109f57d410bd565d05257b4c43e17467f0c65e019b16040236d21415386f03dfe7a5867f62251aac2959c3091bea5a4c4de471dddd99814a682c24905922e94e9b5c3fe9a856535a08d4d4b99ce6ed82bf85cb83c18218b45893a8ef337985cb23c403f39160f5336a8f6b9702ea2dfefa200e537dc36d5466e38e8f57c4c101e6ff2aef32f84465b6b3e4c6ae964d5fa1d3dbd8b95c7b84f94ca4ef618e82e3c0fc604aa58aa60c3d96749c0dd4c1586ebf5e46e1216857e7cde3af41edd3be7278d60ee5b4f77a531825d228bb1c2333e58e65a214eadec74820e052fd1909e3266482425374807d5a6ea2a73a160ebaf9c6d406c50f35575286f68d016dc8b139fe4a3b2cf2ac6c735e0e23dd0f3a1a6865369bd4a3c9ae3c49a36facb319fe93b7f02b9bb7f2c1acba0d19a41d6370e67f1de0fce74aba8aaaba880583c4f3e3410099cb442bffd356ea40718907d598d5505cde00240f079b1045776a270ea07b22f41f9b04839d502d70ed7fa1a3efacb012e97cc37470c5e061d113b44cada7b16287c545283e574547a99ad923765f84149b39b55381685a7679ed21a651cd415a02d3f00ea1a4bae5afcba004f4614263ed5124a20c491e12a4f54ed7b306a542162ac31c3e5a2980d1de351c36800185867f14371527caf14ec11955eff148199510cd64571168e628ddcd6fd06f5df0c10fcd83cb87ebb6eef263c321dd29e127bb53a20a67cf4f4c01b70850577a50ee2903b2d0a53b7fa5f9f169c22bd5de093a5f89f13492ec4c4707d49b698cbc93e9720e09731ec2ad015a82a83483950635fb034deace8c1ea4f975917c5e6970aa716a3317ffa2744712fbd93da34e4c393e28c325a55a2a67451fc0d393483cd6ea31a8443413b7ed1f4d672fb974ce3d0a9fd5f5420595b3c22d05befd93ff803f9f08ebb1943564c5dd2a9c4a80b4b2d585937d553943df75bcd2b6ff1e4af157032bae807421063c3ee2220d418cbb4a3e54c6f72bd1c92d19782fafb95f3a713aea27208c01b019cbe82ab5d901243e097544f400d67a96a609c14ee150c025e22c00964cd94e198d94f209edb8f5b18ceabd7d300f5597118cf01d20a69ef113a3c1a3ec75664d7ea6a11aecad0f56269443a23f2fe69a7932eb52bc19cd7457130810ddac4ee684c3b0497fe974edaa5f7fa7fa437d2ffd31086943b064cc391344e5408af96f3565d14fb028128c83b89d92e138af8acd1705d148b1f2cac34dadc161acb29575d144ff39ea452af33fce03dfbb642d04729c9042088d48d25f009e37407e483fb144816b17656cb07311ec5a82350edef9ff048f4bc12fc19f1280e835c87b7fba0cc0383b3d5a34408edc4a338bf034f57bdb8548d62672abef3197b6ebe528fcc4f8d4771cc71eccbcf05046faff640971e909ccf6bc632a116e9dae85edd6aba7c0ec6a3986b113270e91c042c48c99c3eb01ab38ff78d56989a217d82aa3ad45ac4a3181ae7af45f6c07b168d61ecee4c0efd9458e7974b039c38e9f7ce7fdec8e505030cc2547771618a84e93dd436ff9db28f2b6ac3153231f54da43ba774d62e709287b96afc0630e43ede631b6731bd5aa079b618a0876bf2ff901a2674c99e8342b93e5234659ec1c5661b0bcda5b80041fe93e4ac0b519847f146f8fde87b98b83e9d7242870b7debfa11e0ec8dcfa3b8725dcbcc0f5cf8681e333d10e8b591c8b366ce48a0a88f58b5ca436e94e4327087116017808d18a370a0592a73d9ba0e72346d4b71e7519ca16e109384a6c9f144503c3609e217e21d239868744c3b46659b84c8ff9d477132c0dbf0a92bcf9f2aea0c179b6b6784d783dd333cc5cbd14bf7650d78cfa3788389896b7e8655706b9d34a7d97c56535b9c2af32846b9a92405d757b144451688cda414402352d274c4f24c0d958dcf2fea3419dacca3185492e4903084aa2b045e1ec521ee05ceae6e68496b876fd79fbdc29c13539f1580a218e2e48650106838c096e6f085f919c6e5616647a3550f002b7e8457b8b3f4e00cb1e64dc3377c28d0389e8f37a00940d3c06d36b6c174aaa5ec105631eb1a1f870186799f98e2e57d866e16123b8e56b2b0ef834bcac595bbbb1edea353baf454b68fbba86fded3f27c76ee7c1008286a2f3a8457f99d5c52ae1f035324bd37762eb8fa38c8bc4530a32ae8438d86fb648ac41daf1b240c4472b94bcade304a1ab6c6ad4f07807052040a1ce556b4891f6c7a501051c2d91cf8927263cbd18e95aa9eecc158dd75dcdde2b3b1b8ea91e76d0d217b315ec1ebb2fc8aa0a7e3807ed5e9eff4af24647020078645bf8a463e1a796b59b7d6c3c7c1e5cf189f1a319f20f62a4a8c8d74578dfd637ed2f35ab10268c4e9e6b08fc352aaae5ba10a9fd3a6b0f84a235677091e0298db03e82ea55428ae72b3619a55ff6b41a6a1961426de0e4279e060216493a8ca2b162f5c7dd7c29efe28f7c25db227c7e774250158f609b60c6f5bec9ea7c839fa68a620df357520181288dc8573bbc69c59f8abb4602f9a8018814fdeec73a47b39fc2d8231ac97cd930010f8876c8db99cb2b220631e4051913a0f3fe2f385655b95dee8a90e553169b0775f7d9789a1636c5e657cd89462ae84ac1c82f0a1d2626b261b8c99b24540eb6ad9ae1ee8e44dbe9e5ddd8963cfe99c5c4ed4ceac9fd4ce5e96bc464b2010a112c71ea98e597472ee280f51ded7943a99eb1a6372c5567f825b7370dfb2a8c426a5ae27bef66cdb942b4e0ba22ee615085d6b6b60fd93e9bea103996e7a2ba8228f8cb02318a889aaee9370179ea34ad74658e932a515b6ac2856f449fb5f554489f230775553891f3125ce975e969954242731e8223d9fbb7b68736d9b7a58dce9a45c688ab58ff7bbd724b330d641dd2e01318feec8a759d3cd1c2ac931ba8d3c60579a0710db02e25b60693798387c7ace2c044ff0062fa9ce7e72bc21cc4cff0bda08e4a74f9c5b8c4d5af82d046745a7bfe3ec0aa0fa3632943772eea9fd2f1d88322e03755c44842a5899ac5cc3325a1f51ff8fcd8901877e012e0f1bad74eb6c1a14f047aa9509810c65ab00ce8bf185edc21efcad841c2921659685d6fe251ef2b35605dd8269ff0e562539ac397cca568fd566c55848d14ac4530971c0cb7e557bbc364f1df88e7d0894c117ca21b76b47f949222d451c9d2c3c7c17372c3fa00e339b7bc9d843192156eb07dfab7517038c63001fca88e9221fe89033a10507178096372c16e5b5727fb427dd31731b70a8e47d2828b9afd917fdad506662d7b3630b30568d0fe59a3d7612aff1ca4c9817c12982ab9e20a28c26a04b05a9352c05f265ff22e6266d798961eb5c11661e0362464ef19a0f5259314a96b1262f9810659260012fd43408df405cb1f7881c9a0c2207fbb63324e801519eb726bfe66128c6f24539016653682548ec0fdfe7a880285741001556baac83d37f2fef658a36aee95fdb5f420bb0e4182a4402a2dc1a77bc82c5a54367312ab00e316749ec0ea43c1e462e22c2741bf6ee9660d67e2ac236a813932f453a81285b06d116db2e5ddcf68e49eefa183ce48ac8e450fee4656977a180da7e29e0e365962a2007920b441961b743ac0691156aabb29d042998eec1ca9ee7002c0602ef48df037f3cdbcb1ff6a1fb54a90d517c9c4027f7d8fdc3bf81ec105d6cc8bdc92d6abecf4270c6b147fe19ab1677a12a439f08edadf4c5c0b14006a4ca77b930be1d7ef0048333665c79ce4259d91b65650643f80242b132e82a559a0a0f70428b8d921227f80a385425de3ca4cfea627c1e1accea1bb50c786b74d1391c54531d556a8961d1013b9b71fbb7c28ac3ff9ed9a793a8b3ed6dc01f905e1bf6e3aae8e25620f121211c1a7ca6e4b12ede0be8aa93bc1cae94c7b430806b0ca552f6ecbacc52b39f12677029f2c29d7f05112e8b0c8d597587c4119f71efbdc1e1194822d094f5923a18d28c034fa41d5d62da5a1668397e437011ae59dabaea02b56e38bd5e3e4416e5a65e5ac81bf2ab8ef1e2376d76bda52949e3902862bd3c4f30859c320af6cc475ba331acbe40defb13fdcf170ae6053a01a13a204a05b4acd5acb4aa4d425e64cd29658a5ab7071d04605806cd5c65dc26685f6a9b649b75d7dcccf4fdf5b92520a5e9b59ab929119618e0fb5c5ba2a9eda330741f28957306f6623c2264a4ec4dff42ff9a7eb7befb353509420f684498975de50e3e280efe5804854d6697628e13341c08ac99ba22cc60ac90d9d5cd3b824088c7086190fe20228773af5974ae0b1c31ff7458b9082d55595c041c6153febd7bb3cf77f327faf979b7b62aa473e3e200a87317443fedab484dd7a15f9b0561b22538720fc434ed5f004765d807f9ede6b6cb5f043fc305ba4142e53532264b86b769bea87734178bb49f6ffb4d96fcdb0e976dc8b1df3fbc62c070d2f136569837b36d811c5070068840f56c6ee974c17d341f3e103eb9b8a6eb0ecd940ef6931673a266a455f375876f3d8fe16685f40b5038bd2488e4716d16d42906232746f48bec61368ea68675922c39708ba74625afe89dcf21ecfd85c4311f547f36a18fdcf1b33517b8caca5c951559721fef9cd7630a4c0f19058650dae95f7402a6b0e67e97bbed585675fa26f5daafb1f753ca926ba5facb231b9e3f90252f5fc3721260400e8d609b13934f21ba87d2656c12410c086b1743428a38d585d194d02f595df51e8450e1dc912c340d263a4168ad55b613ce1cc1b4503e24ab7371424aae173209ff8fd264c79986a1049aed5d657631bdef0164c95032f8bd24fa18f3370e136757bdb6316e612679490a42c35afba2f313b85aa14c8c348d1b71ff6148b0b0c8b859d81b71d9a4bb1db0f7aa66862c99af51424a69ce045530b099c081a96f00286664f6cfcb998001b93b728e039f69a255f82b1a7acfdfe5092588bb43c4823f584e2317496e34b9adaf08f559a4bf2b1adccb7c96eca8c9dcf3ecd9f993a481d4a7f16204cdd1ca889be4222fc253dec997694615685eb9f0705b066d84a546e7e6698e55ce5cfd6d3aac6258fb29bed832f1882a8ddbd939fbc481a483e195112da512ac2b1dcb4d40fff674b8f92a05db0cf94090ec601cb02f04dd2d7bb3024f577eb3488f310ab48ca60b185f8e80340cd286c9dad099e03b0a983b0d97749094e959a40fc09ad70cffe39d08a93a9a48068b640ccb8aeb187ae8d9857c6ca8e99b847f82ea86cb592da63aa01a6ec322595ac1d239463a9f60899f5a02c1ebbcc59b952083220f19d28bcb9c5cf5ce89ac3c80ff09a58719bcc96c8ee737a5ecce7c03f2dd776875765dbfa417864d20b7371101c9c156ab3bba39914845ca044a2e715b8e0f669f2dbd08946cead2429c900a28a12427a0f129a5387cd2a4851605f93a6b8bde3dc943a2de8cfa3ea5705786980e4b09fb34c9c7b2854c62ef4bfea856484d84dbfc2fd1d2f9aa2b7e3f1e70e87421b124736bac77bed680dc082522b624d2221074908d589a11dc6f516e0b4f20662c056c94892b1a05976e37d79d854087717624d7229146ddbd2cb0422a91e49fc8bb745bb4f0ba3172a146c40c1d1276aa7ce6c7ef860ba9f089d66763eeaf5d394ad85606e1e371928b2945f24a7def3c8b0aad4f43d33c3e7a49867267fccd84c48ad4dbc534b5fac86a7409912a7625cc552fc5a25d9e9141385e91f81d0359abd121eec495d404ac1ae5d91132257db7e22019ecae3dc90e92e1292a96cf15f700bc303101cd4078d4b3eb902c08429d493edb116de020ceaf76fa5a7d5b315c715a2d59a102cca533c9887eab638ebdd6283a8df18a5b8db2ee33a347b5f7c062ddd3e246315e37f800271702df9fadae0176149c485dc6d428560d145abe1945f7e4aa395eac6ed2919564526fe7591828fd83c72033a64834c487fb7dfd4c32af509d97084c83a3e58e6358f6b1126abc11994278c856f5af32194e5ac066812120baa25871c5c854d511942c91cf10df768be556847220bfda29c2ebcd0526644340ff3a2138a85f1c7263dcd7ad45ec7bbd67428fd66fe70de224026571723edee5ca22bb26a4217395c51adc0b8039a8fd1d87ec1f1c6477d42ad4ba38aab0e4996417c54ebc2a8bba0d16e18eee0adb80e40ded1602592c746f0b415ff36e056c23f425795a3f56fbab2d04fab7562308c1e6205ef9fbe5805fe3c190a169d880ad590863e857cf0fb65611c217fef3ab8042ca3f353f6272e310f784c7f3d202e9838947aef2346ed05388b2eb9a0e693e5308b3ccd53b3d6d231da13051971923613d797f30bd7c86b67874c9a2e0ea99e49587462228916cb4785d2e35d69143bc32b34a98c372889684d2d8a6fac72d6d9eaf89595e51fff1393dff68109bad803c546b5ec0e3ab190583e178e2d9c22e768d83a585d630016062851aca9f9e499e37426c6b294f6c56110c34c3084e09f298e537d54f417d3bd6b96e1a5a8e2a9e99cbc7cb8f2201c0c155319cdb65f71a5867cdb09345c771af019d6c2545ef3314412d9170782e02dc7103339749a61247e1dfdd1f04d96aacc6b01ee13acfc3fdd3dc2e0b19b7047b771260fb92cd45bab22899034eca76381cea67861dcbbe9e494ee9cbc42627a89012256a052a2f51a256a0f21225eab1e440e67e3af8f6d2e322bf2dcc8784846fdb2e8a9481878c33d8807d8caf2ce5144376751c3ea6bd080f6f6b777643c4d2aad1039d98a08f6665cdaeb347ed2b81b1648947930f822fdecea23bb3c4e9163f2e95247512747096729cfb6ca08040156393fe61e505a619918d59f5d15dfbcac6c4cfbe9d24d9980cbd68257fc1dca1bfea60f66c97fffaf16a35213b6b2da4797bdb0462ae0bc3dec285e1678b01b14f2b336ea72814e463e2926536148552b1950eb8f195df3e312e0203dafb3e5b0c3c3df78f2f8a448466bbb396aa880c8e12097baa8fb5ac8046b5f61a889d61cc5ad986fc271f26b298bd5346b08c578b07d8ce78d3a9e390e1e8565f916bbca8551a10f98416d7cd97ffb5a35e76cc28cc699ff9df12f5569bb030a45b6efa4cce482b41dfa96eaf7bcbb89914a6dfffe04b5eb7cea216be3008255c804bb2f8b3a72ec9b1d8470e8685122bafe7fb915230743dde4a9460d8a00c6c31cfc870b7315aa9ff8e2559585dc350dcfff47d93b2b3a06c79ae9c8cf706690d7c6c4a53e2ca0fab5e8ff9b3cb50fcbdd9041224664fa65e3cbd1a94984fc2cd9fd9191dc5365867dca8c5a04c4947d1ed354e025091b28b4acd86e2db8c17b942b4be6bb4a0629cea002a8ad4b9dc7a5acfe0dd8f38dc55b3068919af01e5592e8861320761f5c32d258c16ddbfe298de6792a12c184c28d9fff65edc266671bffea6d0fbb69fc38973d7ddba3bd7601adfd7ddd3b6790c7d096a8a76f8475bf371581af618fc4713d9d2c54b2849d3bb83826df0e8573fbd8a188cfeb28a049d54408d5c1a3b89abc34fcd9a2c51b88a1aefa1a7ae6e40d733258c8baa940952fa1df5f46a2df0936065996e146db2c97474f34e56c5772686a57d7a91819b4055b05bceef4685641e94c9790e9713019c6f4f01fbddf77c330e98bf6fcecf1c662781801d436882469736c1603e7a6e8cca0c29a2d77497a4030626c39d065106a68cc1348fc4343adbedc0040395fd8487499b7e44cca66ffe5a9bc859efd1bda3e54e973e88eb904767b383516a6ca14f39c59e99ec7261351dd53900dbaf5348f7068422d32925161eb0f44815d5005d09e80e6c48224e8e2f9df7328b5ad97a83a0114714d64b90e0d5cc773f666bbc63ec1dbf6375e7de79066cdc11b792e061682aa2ab9626524af938a98b3eca999a6cf0ea9c7bffb14be53381f7f9f0437d7bc93eb5a14478c64d980358353ac06b7f529b5cce46eba77d74d028b2aea2cc1326744855bc2add434bd1a9ebb00a00aaea1a7879841b76ea972591ea2602d111d8139e49b6d4622375e61a1172b46c1807e740a71fb7022f2e0af3dd44f031ab141964d72c93e0fb5adccbbf558cc2259d0c2e610c2a91e6b2669f99a70d101f14506cc9236c46a09909dd7fd47b10330ed11f22700219028267928bf4d9c0fda599517638cf8c3e9ce6eea5b01c51fcf5f24c322f65f8cceff60c4870afb247bad8ed38950c19166584358f218deb2375bc2d58a4f728f10f0e179a908dfe645640084d1f285f628da5b662813f0b87a98ba3c90bec32e69964f9baa3ab07e5231b3bd45b3ce3a5604d7022b49a42d7522edc610f5f6ac52f7926b98510c678d0be044c6fd58733e00a720bc486233c93dcbed0b9f7312ab55fe9649b30a03f0baaf44cb2eb1ea2d4c2e0835bf0d8d2f0498fd718ed640bf9a22b345bb90a152a44a1c8f6eaef3b5d6dd73f44e2f89c473756946792f35bee275e19aa1a2772debd5a2dd50a3c8a81f31c445ddf9e2a37e110fa0d944a445c6723d3a80171c77e8de0bc4b59057d624a888c9222e60c94d153899e493613b0e2f155545bc5d1645075e69964346c705fe9e50530d97d72e59356d333c92dfbed7867d7d1c951c321d63e821b1e2bbb2ffa7211854acd5b3d93ccb54221d7389ebd08a5ebaec86a543de4996472e8925ee7a049c7365ef390e19bf05a418402cf74d433c9d524e973ae7322f1fca4125550f71c94e574ef996468fd0cbdb368a22c2f7703592ce52917144666a7ae73b17ccc4ab8f6719c2db51f14675c62cc3c93dc9677bf796280ab2c9f4273c597b294f74c328a7dbd170a10adeef4e5bfc8afb98727023dfa363df1f6f9c2aacc5f3d935c4d33d2d5a84b3b5e75619f8f9e8065250b43ab3d72a666bf025a1b154e5e357826b9f4f6e600bbb6b18d05cf246724b9a133b2b3a7c2e1616e244d5e22720de7996477aca53e74995835ce547077e1c6ae9aae0b5f95860053c09bc83d936cecdd444578e89e4976ca5d85881e31ec98bf98d1fb0e788eda2f6bac1ca7673fb6d1d0e1d823da8c6980e0da0b6a5079979324692fa81b52e95f4685994c291e8161a815de1839a9bc24c993ca562aed90a2204ae9717a261962e8b673b9a90cc1cde229d9e0d76c16c0e213e694dea52f913084edce71653615b41fcd9367f77cd1a05eef402692d40e4f85ddd7cc0ecfbe354a2976942c496776775951994d9120728d35933edfa3f8029ca27e205a2f0a31d59e492e013c42d8ed870b93696c5ac0d2d8f77db2d88aec0095616e9d2eb806bdd16befc20eb0b33c5363ecc8cb144bd77946590a9901ed3d5665cfbc69cd7776d2f12384b867920bcd3c8f325bcbcc56da860f8b91f166cd309fe0fc6474d11ad6c48c34ae80859e49164407480af835d30b7311a049fe5db34099010df8c554eac49316d61db181f2ea60ca24e838d988c34802297ef40783e2f24c72433ca0126ae786c62a61e599e42411aa320b5317e1d0c6ff4d079ac3f919cdf247139fc206481d0eb9b3e5ba10c11cec265a71eb806370c5201a51c25c172882aa72b2c18e5be2cd8a491d95461c471f13a257b2be1b249d1cf91419f031d732ecf181acd97bef4b0e686e8e664faf7b76a9311b5c1a3a11004f7e86d0d21686bbc90e01792639e33d07ee18f735bb64ba123acf249378098770fabc8ef03b9b3d4ec1c0ce4139493650d4244c35738b31c218cf01f94ad1e77d22d7696b8c0720547926b90d710802520cd142c265536754292a5b5d8d6e6276f9a36792593e5a43dab91d55fd4908d7636343e145a3a7bc09326c0c886737c14009b22e7367212e5f82a029f3ecd654c4886cbcd57dd16628b2bd50703e8987770cd088532f025f25e04a3fcceeb48e1c9f85ed3d84eb91616a3c31a56504445829c3e21fef03f0935ae1491a18596ab46129a7f95b0520c5193f0f51438b402f8516c2277ca61475480ba2f293601c4d112900ae478e22e83dd4fbbe600c58c2026bd4b3c92e93845360d41dee2390167a3db24bb910ca17464e8f686c99300b9bcb72b2f27caf31999540b5a220c156f9be1cb06d431fb40aeeb2cb104b6a35afea33a3fac32752bdd0387012b2ac9fda2d0b7224fdd20c5d5073bda40cb22831fa076589ed14ab022565d10d831678e1ec3576bb917c891b57583cb8a6f525b38781a8f5b004aa635880439e982e29b2a1e9c0a9d2600299d058abb8842283b5259e411b669ef85c4ab3b6b4c278333190d4c20182ffe9c84ecd3f769888010717b87c600bb98061e10c90b1efa0adefb23923f01c05fb42955e485aa2be7313151b81a08d329640756fee89ca9a599fc2f99c172cf088d04acc5a67b6f54fab3cb7441a1f5df24a147da8588591eecda943c26d493e6eca6af492e77b1c27a0cb49acbf9c374c1b0bed2f4c585f172193c3c3541d0dce44e111277aa87bf0d38039f1334aecc53f2ef1dc8aa203b52f97d4d52ac75a1c58db2bcc4fe9011d69d4ac261422c2b8bc9016e742e1f5146a0614808034f13569b31afbfbf9d5e210f2824650e172ce0625f868ffe5f370a11f29ac5f690e153d786aa6df086e01f2529ac6b5fc70a6989770e8bf8d1cf260a161e4dbd11524284eb60e6a187b5263461be06307352600ba3df34e46952aa495459dd63132d256d83ae12c2cf6a76aa671231e34b0d4449e02f4c95d766d5ccb9c37ab192df8889861d544c0f5e944c5cda50b3f7f8c9f684ec0f58ec192109e52fa35be9965934423da87ae46856ce59d21e7313423969248f3b3c067af5b327d21afe8db9fe2e436da3568afc44eae44fe63193b50e72ae0ba906fa99baba5f2c65e6c147dc91229ce725bd04a3a95948e65302d30ae84ad56fe29895dafaa082762a6bb91f88bd453df76a9fdc832430a7e613008d9e5548f571490ba89f8e8070bb8566603f23d14bcb23bc4af680602c3837970058610966842a45ef78da1f1d8b52c4df7ec57d2635b07a27c08aeabf379a8534a37d40e0c7cdb294bc854e15787132f39398f74713fdd623b8af24e732fbde607c5757895f3624ecfb52e1494a60282f0d16a145c4f3315d7bb0bf1c2d96170e4c3e49e3080b337016cfa4de1479fed0b79eca7c2e6d102bb10c9d4b92f36dd9421a89bd06a3ae47f54a67d33dd3b1da9f108ced628fa781f291bfcd46519bfcd801365f8468b6b0fd9c56e454a7f777dc17a4774ea7e4da7b48c82eb9439079c9c9f961a57696248a3f9e5dec8a64cc8be6cd671c9da3681f58e82ebd987f8632ae01e70a84317ac01025a93815260500c3aa2368afcc1a53b2ab30f49713a8adbd2383bfa4f05cb710d6df77e02b2ead56dd4596f7fea1f6f632b396c6e0aea8656305ca75f2390c34becd49383dcfe74cc9b13ddac72c71ef140f16833a1e87fabdffe777f42082184486477f70e0605e0041305f7690d78ef0541103f05b9fb137fad15832ffe378a9f77439148241279a1f7f7de7befbdf77ee3278efcc5feeebdf786f3de3b61f4fc5defde7bebbd97d35defbdf7deab57d09a8fbff6176aae638f78cbbba7ddd482de5877f546ba2dbe1b0e3bb8ffd55a2b07e17b7f83526b632b9d5f0525ddf537ef79adb57a61f832a80cf5f7734a6fe4aefd85dfebfb2d248b4f7e939bd6e656bac1bd99bb86cfefbddb0d8a805df5078efc0231bef175e7f5f40a5a833bafc3dfc927db5879f27c918615b4dff570b7d5fab656ee834d270a3ad02aad9bc53eec7572e4c33508de2e9615b1f361d90f10293899d11ead49844f909ce094c2faf4dc1c2d5bb248e1dc6a569b45871ea46c1a7250796a8f94ddc3d92cd66aa93747cb275b2daa429fbdcbde6b93881f1d7ae69cf3eedc9d39a714735a27b48768e4b61de5a440e88fa00c0326c29e352f0a43a62f4b309bfffa4182a1edcafc69220b63a29d25f3834679abbd62b5582e7767d3bff6f6d13ea13514caa69ace1855c7b036c695416daacd9e9cfa858cfea26a19316a3e17ca657279aeb63e72be909ff4b13ed6a7be943409c33e4d426d9e4818de87354975919f5a9f9a09367daa84baa02ec80dac913900fa3d4dacacdb16e811eb33aff5e9beb33e1246f782bfac8fa5551546e606b6c91c00fd9c6939bb89115a93ced238ee968693d8269b7e165d7badbd6113c52909c089ddd36da325f8d9dc7734e4cfec468efb17f5c5ee9ebfbae72f3c2d250bee65d0570b5a8395d01a263889b50127b156bf6c78ad599ffde4278719ee28698a4fb62616ea16051ab427103567128183103d57680d9d56685055412d97cceddae3e493ad3ee7ecb55eabc9d96ac92927113f38c85aadd6eacb99736eb46db6d1fa36db689b114bdb681b6d9bf56db6d166d466d6ef7b6db39d4ed6e5bcb0500108f07ad1c20bf282bc216fa8ba780d616fc81bda347ebd3c265e90ac3fbca4b472abd5ca10ada1426baed01a2d5b729047839783a783c7646ed0edf044d0e9783e783c743cdd8e37d3b3578b57476bc96ea7e3e9ac8f9d7556ba2cd5859d5515d4a6aae576f69a511b6e677c9b6d2323e8343ae3b8a7b2aedbe2e578b294d713b4cdea16995f04d9d9a63b588673b0156f689bd95967c51b9a6dfade9047e5cb416272a91d19cdb128649e9a2f67aacebea685c6505b5405e5399b66f0d59ff68abd92e59ebb7275de214e8665b34d2711b21a131e225566adad574a753124ab325995c9aa4c566532ae9375b28e87d6e4062ad35e9993f3915babd96b520c5b3f37cca69c614e285aad39c26cce11784690cd2d9372e9d5c6fc49640bdd82857aefb54786dbf7c8da336bcee639726a4eeda9b29a43b7d015e88cca6614f389c985e6d09db9e5cae6748b95bb736577c75ab15cac582ed68ab562b96021fa636e9932985ae81639040f1376d49e217898907301ba8508f9630397ba33e79c73f69c2073ba856ea15cac16d9aaa1899c3f5821ac103d44b81a76367dd0c464539fbc67ad4c6a23d5f8ed7d0b721aac3d639e53674ec6e599659631cd855955a182ca24142a85eb91c9b82b455a2678864fba7827db52aa8bed31373464c50a8d46c3df04693c3d32c982861e54daa6b92c55454f4783429f88dec3a6df2286fc1e1fb4a995954916f56dac353ae7fc5aadd5cebda8111a9d4916f7e9735fad88b08d525873883535cb01dbdb87c0f6f6392d82d59bdea4c6504e205950acb18fb6b2bac0188a64419f7ecde12f5c5f39554596cc6b7050eba71b91d3d630e5ecbd569393162058ad56cf63a787c54e9ffa15f89cf43433338f23da332b168b056a4e9540224589542af53c467a588cf4a74f69fe3dcd73d1bb542ad573fd3cb55a3d8e6aaf6834a7341100f5703a3dce6a9f9ec7440f8b899ef4aee7e0cfa050a8e7e3f3532af538aa9d72692ea7e891c30e2412e9790c7c580c7cd193341ffdcc739a57bdbcbc3cffe7a4d3e97154fb34a3f908523c61420f9148f43c46f3b018cd832f723dca64323d97792e22911e47b5492320c1128413107c9cd5069fc75c0f8bb99ee641cdc5473d9ff917cd6338bc5dfa184eb84b8f23daa5e731cfc18fe1a85bf4311c718b1e47b54522f02801032d343434cf63330f8bcdbceb695e9eabde6432994c3ac68be620b8204b0931b85caee731d5c362aa9f7997e619f5a517b2667ed0038a184c313333f33c867a580cf5aa9fd17cf4a6e72faf5bc89ab9157902072d2a950af52acdc3b1542a95f42bc90c5100a1502894e6e2afa02eec10a4049f4c4dce791229c1861d39c6256b660e9f1656301bc1bcac9961188620650912ac207cf9562bfff7bd288a2208274cc103c9cbc3622fa2e959a9d1e787c5469ffffbbeeffaf0e4c812a687c54cfff225cdbf573d2ffd0a8542fd8dd4466993ac99e18f1e160b7ff439e7acb94af38a02a11da1979797e7b1d2c362a537fd8be6f451cf532f2f2f2f3a67f1c387c5c40f7f341a8d3447693e4294216e80c1647a9cd5363d8fe587c5f27b6f7a7e1a8d46230d6edf8b0f8b7d2f7e1886a1e626cd3520838e133e944aa5e7b12d7f49f3ee47cf496118869ac3dff7a2283e4ecc16351f69befd28e2c7093be7c759edfc3c861f16db1e7fd69cfbf0b94814c5bf91daa2b6b266c2e87b0f8bd1f7fefbef7b9c98fd691e6a6e892479c16c7350dfdce048edef7170fbfb9b1bdfdf48ed4f4b59339fc7eec3b68fc570b6bd7d0ce7b4b7c759f1188eb7e9c7704a9b3e4ecca61f8379df3d8c7eccfbce1bbb91938f47d3981a5bb4e606d631330f10c5f28831a7f0d8c0040b3c3a0c448cb838059c90fad3093125b1e4043a399030431453a886f0274a10426210a3ccae0c3edd8e1abe1d78876916993f51643f3d44d1c30c64481380ec0fb20432810890902e784b202154f2047e9e20e124c0b3f70759fe9ca0c996af64732e8891279d842736e8d82d7fa038c927646ecb1f284cf609b9dbf2074a6dcf05fc00d9caed67a2363265e77ceea7f7de7baff55aefb55eebbd368a64efbdf75eabf55aefbdf7de6bbdf7de7befbdf7de7befbdd66bb57e4be8bdf7de7befbd5f21bdf7de7bad5f21997e92567bf1362527769a67608f5f9ddb4637d89ecea7dbb66d9bb6dcbcdffc8d7bbe6ddbb66ddbb66ddbb66ddbb66ddbb66ddbb66ddbb66ddbb66ddbf7ddb07bbabe71d39cdbdb7fdf7dffe1ffe677bfcfdad00dbe9fdff772e4bea75a7aba9351b9f95bfd2dcb3b727b81177bbecce00c4012df37e79c73ce3957bdf7de7badf7de7befbdf7de7befbdf7de7befbdf7de7befbdf7de6bbd56abd56abd56ebb5de7befbdd67befbdf7de7befbdf7de7befbdf7de7befb55aefb5de7befbdf7de7befbdf7de7befbdf7de7befbdf7de7befbdf7de7baff55aefbdd65ff9bef59e5b6b6bdd6aee8a4f866481ff8e5c3ed9d8b4737e5073d706c57bff7b2fe420fcb09bb684cc4de13877a636a95034e290d9311ddcaecfedaa5935445f5f147e17d2b85f431d86e1bdb5d65a6b78ef27de7a6f0dc35bc3f0de1a86f75e10ac1e08067f4756e949948ea63f8dac1adc9b9e7b93669574073af6e85935481f3ee9c30fe96f8f0a155049e3083572d5467dee4523c75f35d55c478cdf34fe36b0861dd01af4eddb989e22f783a527d49f58cc97414f6302680d0d0963ded106eab997811a6570dc67c1d6f6df68bceffa6698bf456d3823bb7b568dfbdd93bee3f739f720eaa564713a8da891df37fd0c3de89edfe79aecee6708251bffe520ff1dc56f85cffd94920547bd7d2959f0fbded3d083ee519a731ee0ff44a08bdac80e746cd1b7f0e9fbd3c8ca3ffafba59741496f1a4b23ab067ed2e32769567e568dd17f3ffaaf013a73864c4a02bcfc68147d1e3bd0b145fa451c6d84f8c1d1c6a7e5f6c617b4a6d3536ff66a3967c8010dc9629fe8dde1bef5f0bd2ffe23065edb86fdcaafb6e2c87f8bf600a4123771f13dfadf9724f7ae9aea82f4e0489a9fc77f89f495e1c8f306f51df3c53f83bcd1ee9af91878edab6d585d33b5486ed41bb58585a49c73cee9a2b5c242b2d56ab55a584862217997c8bb446221496da8b5ffda187398c3b47ef540cb3900fc74b45736b5b44a4a2b1e6bc8c1531baaed936fd2f27c094acbc18f104378ca506ba56555215959ee65d108dff4210d5c050fe129f66bfdfb9fa8fe776d48e3d2787edfdab086fdfa958634e8dbb83a6bae4a18724b163e660c2c5a52c92c62d2e962ce39e9cf492b9dd3049fa49fa4dbcb16f5d9935f3c72fca3ef46de3deab7919b9e6f9fdf1bb9f725cd45a0c1044bd060347a9cd51e3d8f899a8f5ef57ce65d2e97e979a9f43831bbf49c3e0af5250d3851850727c230143fd43c7cf0b9ea6968684a28140a15c20b4e5a3003511445cdc53f3d47bdcbe572954aa5effb40e011451728be3f3d9f799a56ab9573fea08a911d5976b158acd168f481075cc8426494229148a9d56ab599a0c80e4a9c4422d129954a89a2b82129018f2444120882a7d3e9fb3eec64042f60e223914839e73b8509223ee487793e23128946a391ad010c8440c1e8619eab64646440100cc3104a96156840a15028cdc387798e8a8989a1a1a181d1bcc2f0f3440de28fcf615ee6ff5d2ed7f77d14071792e8e1fbf1b9ccc7cccccce49c9728428a0c8542a134cf3f3e8ff91f359f51869090c2d401814f969797171db4da0c78984ca61c9d0a0f92164f0a825660b55aadd16824420e331c39325ab158ac300c4540418614b284a9d56a258a62083e32e82105e229954a7ddf1742912e3fb8f0914ea753ce198421505ac0238f46a30f840441418611281289c230dc684852248790060441511471920f5411426c3d77d1d0d07cdf7757186261c8c77a3ee372b972ce5606330871c9abe7aa9999199ae5ca4f6d947a8e52a91e47b555611852124c29c2233c3d7f41a11e47b551a2284e179000818418f3a656abf59cf4dcf4f2f238aafdf27d9fcd0776f8e1fb7f0ef325168bf55cf4bc64323d8e6a9b72ce3996b4f0020fff5ce65babd5ea39f85c974aa5d75c841b72546042e6613199d1b79ec73c2b954a3da7793e6afd38aaad5b9a6b008a23baf010f3b058cccb3c0ceb39ccaf4ea7d373d7f31fc791a5b90672787c80222323f33c06f3b018ccc7bcccea79eb532412e9f9cc7399ff5f691e82131e78b0c4c4c43c8fb51e166b3dccc7a49eb3fe2412899eab9ec7c8c8c8a43407c1c9132f00010303f33cc67a588cf5ad87393d5f3d0904c1e7a8e73031313127cdb71baa9c4044abd57a1e5b3d2cb67ad6b748cf532fa2a1a179fef2bc05030343d2fc1ef113c414168bf53c967a582cf5ab67899e9f1e74b95ccf4dcf59ad564ba4b90d02881f014cf6dcf3e70b5970112618068c0423c13cb7067977b95db4a6b74bc645c0d293ba112e828b64dc05b7307dc23ad4257b3ebbdef7fe76b94de42b525ce4d62672feec511a2e92b10fd681bfba5c29329e5dbc815c5dc869220715c99885bbe56ec14278c810152b402c5cb9582e965d5f4200ad1054643e2e928b644c04efe4f9aa5771d55ca5fee55f6a0aba446161468e2528d689652a7d49f5b01858bffa695990a10543ccc8b18434fa5116bd486484080c3accc8b1440c3f043f510d405790ccc8b1c4eb38203eb47ef530d54b9b1b580c2d2dc2e743145dbaccc8b1a4be8f9fc1d23996d895e673df8cb0570f53691bb0b957ab1187cc86c5746cd5731d5ba56f525ad29a17fd379a4b297bfe8d49df90b4a435237d23d23737a096b4e6d337ddcd0dd63756bf5a6c3e7b4cc8f2f9eca1b415bd583e7c02de8175ee1458070b6121b804bce34e8181609d3b05d6c142f807e6816555ca1bd26ee649b1376748a9ede69ca147e946ad47a9ed3c1ad28e8259dc28bd145b908a5da674cb1d2776945691d775d46e1db553c4d7fba2643bb33079bd9012e5932e4ee3b35d3d4a9220a1199911e9c13a7807168285d068b804cc53831797434de48be57ef8a118bef8e2ec11bd17357f859ad644c6246410efb0df053781cd8de36efb38eafee67d224f8d85b21c61cbf04a91e73791b16470df26f2067a2e97fbc47522df2d7709dce36291401da05d7192c12d81409073b100b1c0e4d2e02a9125100b4cf08401490780fc30b5649523e611754b209e219567483d920a020464470201d97941c7c81020203c241001da916403ed706173126807cfe6608f3c7b64967c706f9b25b5942ce6cb19267cf48082c7657df4b012df5a6f8fa0233b7aec4ac2b725504e141e785d8c69adb5d6fa3573034352f66badb5da1ae4777e5c13b89d9c1fdebd3a588674f8e2203a4670594708e3cd9a4848e59cd241c1093a2338416706998e121e3a1ee8a1d3011f3bae209693c1f4a1c515c447142570b29e6d16041fe971651fe0a981a77ee69c440192b5c065bd2d8148a0c193a20291263d8052e002a482ac853c9f065bf109e054854a046e113744910307809022884aa5739c437e5451c2b9a0730440e69cdd6f814feef9d5b9410963a4db67e3c061dd212861dccca18d0314ed06b36cd8b671904250c4814512c6cdccd93004ecf93427e7ec4945f0c9dd2f20b3a42ab88efd00c8bc66bf6a5ccc192ebe62cf8fc1a66fdad2e2add6b0ef7dbd68f16af1e2b6fb2fd76d815fe003572494ecfb96bb375b7d4da9add6235bad1b466205effae0f086378c840aeeaba65e2daa68093900036baded79a19282b5165f8c31b6d65a6bedc5f7de6badb5d65a7c31c6d85a6badb5f75a2bfba112826d042fbe496b0156801f238478ae9bdbc5d7de7b6ffd7bb90ddfe7ee0f0c52b8b6763c3f8f6f2281a1033f46fc1841c50092e6a70a9158ea652a69c969c4036a56e4d99a435f6383921b5c2003270387670d028bcf0b8ec82b98809c01fa018726b09c10830d33ae0b8a8822b361774fa408a9224be247b8e5cf1427b6684b20124880e3880c901f3f2c68b239b8e9940decd1963f53804c7981029f9c2a64f94344ceb64fdf8a5ad486558313d1af2f59346cceaefb1389b48688c6ccd976861dc8273939db7e0d61b3cb780393597272f60dd2f6bede0065e84106b6bd81216053bcf10dfe1b787b2fc31a15d816260343c09e92c59572c5d59cfeb5e3674306e8d04152cde7be237d192e40c69672c5b78177b46fbfd6d1fe27431af6a9fe4823a575ec5ad4a6b3cfaa411fbfe96d49a4239f75e4f43ffb9c3eb65fb9c72107a5afa3e8e998bf456d44f5376aa98bda4819b4456d3afa370c94d4a8e4ad77f5a874aa06040200001413180000381408821c88811c48d230b6071400106574325e50369287a29140200cc2200c621888611086a10008a220061929314a23000478f44a72406aa82c229e0938be53234b1cb878d248d61b40f894209600747e4899a02adb2a6a59d633ef56ccf4912037b97b6bdb5db83d55a00fb33267d1151955d9dce29af86926f71d325e5c7d8c1d26a22a9b8b78a9c13cc8188a00ccc74b301b17ee3e39beca039859e951a182943a78e236afe61b8845ce1e55d9051acf3b5cfa5b8b3825dc802e6620719e2c0d4007193e7ec712f47606d832e9028bb39bdea1fd89c5aaac306156281c55d93ce5c37d4fe7320bb33d5594ece9c32469826c6fd6b4ddc95b86836473a5859e998e756510d1be8ca7a5e31710f7eb41bf6bea42b8e1692b89aa6cf7cb47e9c33ab68f4be332b9513705042644a84b897d693ec346340eae050750955df4f81ec912700cb8f6872ef4c6050539aa6e11fab054a22adbba70e88dadec3c0c901dbbf4260474e89cdad12511aab26d91656ea920dca7bbb5fda02a1b52dc914d8b72e562b17df05f0dc52df82ad7e0dc396e3ac2e370614a799fd0ef262cecf03e69807f80d03a5465dbb6488f4decee0eef8c9a614a71d49973f3e1f6c96f527580758bd79ff8c80383afb80013764051a971b3a19605b2246baf4a1f77035465177f1c6092688209206d6664b1da7c5b983350be709e1f46afdc553850e3f05c1197ce454755369a1079e7e5c29a50d14ce7c5fe0202a5957b4b26d3364d4755b6215659f2ba48033fc07a8e9a02a32534a955056807212f862e0780c69ec15fb6c2f52c2c5031925195cd4a907b82805ba90a07dc1e06901f8dc74f6389cd8a323c998374d1bef3303a590120c74623eedcb2fe91148d39439060cc0e8df384bebb05cb3cc520cb9dca4555f682ed2f56a78cf9c14224adffb6bb31a3467a04b4fc7d44a256a4bd310555af4f9c549f150da5aa8192d8f470a85303478d69762b69151689aaec65545f5d253c8b39837e530a783477dd5886deb9a0bd969146c70bea2794eb8a148276a6ab0315c4df56435a222c31bfb1727ade50e2055465cf1b32b550a8c62994c5751473fdd14a0376f72007d645ee42790f13a1c9984d1e0e84a87f4951955d9c7fe4ed5f7fc0e0adbed76dec1bafa627b9fa027d4b5a88d94e16afaf64c02a58ef86aaece931985095cda68f45a37b58a25395d35c01c85bd29a3a386e08a8754535236a671b32570625afc068dcfcef57d94a9827cd33241576a3cf4dd93a5dde53d3f627e3f277e5704c0bdc028a5fc5fbdce0c41b87af74a1781b880f7aa70fe53c80e65f48c4c2b28a6b4655b66b20eb924050785049c64a9d61eb0b932e9c0a7c5322c3457c429c06aab21d86564542519179f71d3eefa8ca5e6e72b47adc5448e27758d2af63ee1e9c38efa1af06e8c906110cbced40b9c8bb756c25e057d46e052998906f03a46eaa80aa6c577f4fad0297f03306269fd2c900c068bafd74f03f224710f52e74ebd799dc9fcae50e879db8fcdc63143c7546a1f3b793132fab7e2192f15c889df40e31caad13c15cce6fb6ebbb5b3f8b346144ff2ca038262c8b4fb7be93de388b99cc912a9520fa5757364c61badc37fcf89de90780da0f17b8f53c090943a1e3d6b87e7756a8895ec43b474c2e6234f8036b3d4e4a25ec4ddb94402031b7265788a65432053ba0f5bcaab9012a5db6930139156c02f7221721f69c31b58c2cf2cc23428aede12d6ef54edd2c4f8bde3083899745de6aa3dee4d3dff2893d23fabf35ab2a7d58f5adb8445a6bd9d17ac36ea7d3328c4dedfbdf24c3613bfe229ed884ab4c91c43a17efa8075eda966b925155e5011acbad456b237e711f70e67f433e402a8c16cc5d061b0ae8e7fc45c950d83a609abd4b7f95372ca8cacea9fc3bba796dd8920650f3c70deaf7dee50fee69cfd7ff3e1452961aeac49c0a0c0325816ab9eeda60ccff7f3cc17d73398bbd780822a172f08b8513b7db3f75ed2cf8a492736d1455ede766e98f5be30971898c9a9c39c8b1ed5ce2d4f9520fbaab74cfb66bfb2ab6dac625a99e2ad362851872e137769b75577af2485567e4a8f3b5885061b6f29478f224469c4a372f6c5f85d8c89661b0f6f579e2b7b355a78a21d94ab04a76e8cb610bb1c92f435ca5ced9a75f0b215fa844e107f3fff5c0fba79cef7a0e8aa76adaf9cddbc6dd980385fae485584a64a192cf8dc229ca4095fdeca04b7136bf6783b573d03a6b0dffc54df42bdcfa156a5e984dafb39dda7c0081e13b5ddb8bdf4fcd7fe025af72fffc39609ccfc37f5015fd0a87bd7eb7641b0a1d2c5706f5cd95259d16aabe33c428370d3695fbafa856c1968aee89d9354274182eb989af50956d1f3b41a9163b2ec628bee770a8a750aa16da51edf5fbd80214d8114135de2006fc0ebb9f79e236a366db8a51060b0a1bb09b4a1ccb7ec39c07242170eb0000663e795376fbe5e97c889997562357f690b4b710767342a04c1b19a2d5371727953a5d96842b19406513eb6457a45434dba3f6d35c8e6825c37f7e8c3248597883b4fbe2c63bc4d6a769ad4e4155b67bf3aa09f459969b21a32abbaccea4539139ccf72cc41d81aa6c118658c6e42e950dc961896aca00d4d04b4392a83e70812506f62f459881b8b9bd33ad2e20d91edd3a33b90d3e108adf8de8ed42f22713737520aab297ae401a1ccee12e94397a64a1582758bed7973b0dfeb0c16cefbdf9cde12bc1edb0a6ea5a260b31b7a8ca762f30673e87065452e52e2583c0f1801813af09a36c786306ba9d8d4002807527f23eb5ffc54cac7d2eecd81cf4095b95a28b5070747706b259a1ef72843d0119dac347c13b8f5296144d40f8b5cb0550956dbf66c89adb352720588658f1e0fbb7c20865a89348e22d4bcd251b74caeb67f524bf48d6370b890add70e67ea77116d6ebc7dc444705e9a9bed95d561fa3d247ffd731ffd250956d23b7e9eac35128ff936f817e0494886fdbffee198915c4baaadca5828b45c0b8b052f7e698050a685a0080aa6c1b708ce0fa81c1d575a8d098f93fe6508510bf64d398ca100a91afbb0e02d8fb90578156bbf7745bb94256d1703317719c645a92a83ebec550958d7a8ae7968270fe35aab2d1f2d4ff3750950d916ecb2ef2d071bfbe4195e4d9ff21515d474393b8d4c522748b5c54658b9328e30e58f41ad57f0b53c999ee21e9b52ba0eaec6717b61e0d658b367aff594455b6fe5f69666fc0ff312c380f1ba18ef7eeec55872c8f7788e8cdc72373c110d5a1bcbc87379594295e27eba78e654aedd91de2d4626a04e1f4fcd342e583b44fb50a79acbada471c7200c6ca9ea5751cf6944e72a673f76f5a74ccd2331faa8d208c2aa0f1acf72822e5027150923e58eb419aa273827fa564b493fcc64b9594d4fe0e23ea66d69579641e117aff6195924a94599791cca256166c3b79d595991497568955777ce2a5400c25cddd27009922993c64299e34938cb81466c1ae558a78d80f110212930ae4c1cfa5ee9fb3588b25f2db25b13f5699b22e79612c69427a36d41d2f5bbedd2437f2f08f820aaf0de1fdb333fb37d1858e4538a91d7451297f0d7e9261a639b9804e73b019e16001eff0356f3e8af7a7e3ce3325b85664cbcb8a0234f38c9f2545cf1c2fcdbd8c6bcc4ff95e575410f4f83e46845b22f4cc8979511a0fdc9c3cbc78bf638806e865e5d1f6ec829aa3fca5def1e39d348850d2b4fac501264fb7fcbd5fb205670cc07aa1ee96d92ff08092e0538770302b48217827291fff078d891151bf9fe809d5fe9c18116e3d0f7abe26258365d2624f974919db1cce4f41be747e86edd8065051d7a7e1ece4872581859364d44d44b3892f585c2531bb2a4732139e050ee49b7e293f169d5f62b317a20ec4fe302f0b20d6b1c8135de8283ca029a408b579569e1d98f6b20bd65e76c0c03defa3422973681a2a0b6c0e3c6fc3d7a41f38ecaf78264aa84f7a623bccfb8ea3c672c01ebda90f381586e2b9fa19780eb3762df7c70d3d2b4083178fb999a5fe450228294c8cf5359c417316fa6037092099fd8f09e9d6e24572818d25b7abdaa38b8a698340fb20741cf6e6b611413431022abc2a0e585e256aab6a8149523bd8d0b4ec1662f408dec18d3e3cc9230ccc17017429ca34b14559baee6d08f8a6709ec1c30e5c1326e604747e9776d7f2bd86ae5eb3d954af92c40e5cb1d1f342bf3d760e1810c2d067b7e1f8750f1b0568d6a9f20036b1f5db4d72c52acf323773ea666b31471dbef2da88680ff2656fdc85f815fd47f8a1c798bc347c19c06bbc9e64eb83125bb173ae1dbbc195d0590f74bf25a950b5f1f28fcbbe40dcd3d64487f6e903887ffb86a6aee424e545ca14e4d7918c3de25672b67caf8025e2105b3f4301644ba807b0aa170aeb987fde8a1b88f264bf08470cdba32e3c98f0637084a88e59eaa40e2c7ca1ab19f15f856b9905f7401fad77a85135ba292193c31dd983d602e1d96f01b399fed42270079f8b55bff5b11bb819a45db0c6ce43b0788c3a5cb545bbd3da81c42eaa59701edcb21e687daf322c18d127f81ddd4757b090310be96259b137c4b84eb10ea2a4f307f45f9ff37c714343554d2b6639cd8c25f2f108e461dcc1ccc472f8238fa85628e903a533593f389a8a406a919f5fa75989d86f5f0f1fadf9038515307e69c0eb8b084713aedd1fc37cfbd8baf0e4b54940f537ee125673045759942104436924f3dcb6c1ecc2190ec0d17b8050741b53141f2d6fc3c4daa3a126be5fd07b9e1e0f4e89b95cb2e9da1e056a7c9d16b5c1be915b239b779c856f09182bd1974871c4b42a660ec719a8512bb6aa8bf73515d7bf5d60c710b755d5e7a5f02d35a299290113246ad45427e34038728c0eab1a999218486b5212b14c54c569f02b8c3d0fe1a75fe488a902e31a904d40ebf30e7c82f8b946b66ceb16b364027245f799449eaddb1d89aaa8daa5c696e976131da6cd405682189efc6dd412a9b5617d141b13451a0f2c57bc61297c9edbaa8567044ba0a40c624f5f66867607a84619efeeca39ca0d04916bed8e5cd1ae6a34bffd1d4f0d948b8a63d58bdaa2811dc89ddcec2f3cb0cdeb63d551d1509d6deba626e6442e860aa6920a61a25bc59452d25c9457dbb7e534c8f1f73d80af9cd94d2d17af8757cf3d3ec27929322584f9beab2c51fd6c3f4592215e3f64953a1952de8cd4d4003d06123b2fc512842a48f7e6bb08ea317ca4bbf90643ed56b194e6a072da81e12ca36723de3bab9433063b7ec6efe323a1149bbe41f0e9e215af5ea46a6a3214a9a4a08310d5aefb74644eccbcdaae711bd8c21204bc1d8a79195f374a09a58053a3b91d3143b7478f2d0a0c953a37c29b18b4694a1041570f138a3de830198d7bce6921709d757246c620c763e65677cf703c2f77a93c59a423fbf731ef05c6024a0a87fdb2ca4e77c28bd020e2595e3ab87d5455202d6d61f943807904161e017f0b29ec6ece092bc0819ba04e8103dc5020451d28596bb59d09f840e8c5418eb1d9155d8c4fde1024f5cd738973a04ed1d8351672184f45b4b3c340d9f4f6d903cd157bfa459da6570bff9026d0a8b84120eb42f2ecf8d73823c496a9a86f6102c46254261cdaf44ce5bb323f0b299b5d47aa3f8ae94fb5ae1d3fd0b0e35ee332abbdb4c4941c76587cf675b198973b069bfece92d02f35504e67e9c484e2732cbaddc49c584c7d7294cce2d5d42ea9b2ae65173ffdb2e4e006dd2866c19a60eff5aac832ff3a0991953f364e38849f1cec59e37b22c7ad613337687415f6c6431e4379dfcfb32a29a82cd26855dd0383d303150fb053dcc7c5091cba039bee53fd69d39c161ad76f90b7adada0ead769c10d89221efbe7779fc0a07064bfd7faa4d5e3e69e552a204b4e5717f6c1a25842e0157d57c27971076ffde0f65369b9920c47afbeba2ec47d8cf7cd5b4728c80efb569926da997efd86d88eb1b2ef59ec41553ae90789ab4ddf51b1dc739b97627ff24923d54583bf0373cb7634229fdb44c55dbe45f4510af29dce3f5b944b5f1a30bc67ca0919f82cf70ff6de8a2eb79878019df278062dc6bd04cd99ba9d3b5586f4714a7a7c0429527cd0b56d4731531e8ee5875605f06b9ed1f7310b1504a60b8e5076f7111d3f59dbd9b9f624f7159dfad2b84db61e0a60c40f6bffdb228cc931f7c1308b4c18ba6442f9787fd8522d9980326b8451fe9665ea2d4a999872febaa7643c403ac035eedddcc883ca7d517993126db8cda72ce290f1df79f634489581c70fa55063b363afc7f9bb7ea192361e37ef2fd96b6afaac839583cc79dc8ffdf38db80f0241e64093aa474be195cc6737f707733136a6d293b2dbcae037766b9621ad1f3b2d5bbf28ae1beac9548d49b0fd30883e62f1b8b1de159634a36e29447daf8a6d7555020e72cf5142535350cc119afaddcb14fdb58a71851f38daf5004997ea274ce36928a575317dac28845d10ddc1463a12998757d738b06ad98ab55a5668b5be69bb9b3dbd8ba76d014a8cdf9f34645266995255fb185bf92846026d580aa7ff48563d02a8531b1055c9815bf8304a54cf64a5400511f9eadccba22d86fc61f7802c3e6707827e87f858efeafb59713427d0b49dd55151a1c5839295ce87a160f467ca2c81bf05815b89ef10f2c15d45a7f967ac3d4fe93b051093013f4a232659210879cd189a03c7d1dc5d160ddc3c0caa025d61a2f743e4896811a5fd1964ec721bb46f1fd356be8c287acfd803de56296086f93c497cfbec63140d20c228a6b1fd0cfbfe4d66468a031ce14292564c7b60b2f4c368ec5ac8071118ac99eeb1a2e0cf71901177180d154ca89942e4d930bedc09f8672715410e700cff6f9c79d09e32f5b047a3ad0fa1cda8566cd850a71629ab26a4a911fa5e75930f7b54affc2f38c313927ab2fa9f17961168d81939c95e84e77ba75e52e5859473a4c31ebd83cce53898cbdc936b20f5ed1aa07a07608cb64b79366245aa591912f03572c86e7759519f6d129b89dfdad0618fde7e7be8118b5413e0d623412be2d1a0461afc2989d0bfc2f22b181c8cf1aa8556a9e681aa657600a063cf1b054e44f302b6c690c5f76c013f518883c32020735c75bc450b6415792139b2900bdd08af51910b135d6fd0df79d5b134b6f83609179fa5b8d57aca7261ad099d47c7139a3a177026d6cf55003cdc0a8cfa00f68e7ac280f59c818ec4675e1239268e7252ade81e5f26407c93a8edb249d4f58111de7f406e947230586af463bdc504346a9e830202eb81f87996f14b3ad131f25ee3292248b08c64c7ac883752494971fa8701769a9fec04deb6f71a23daf4fe4639b9a06a98faaaeacd56dabc465cb12be5da5f884ab501916cedc0e378dfb6152d76aa993d86370cd5e05ffdc57ee01ce81057b3f71e87b61ade06dfd429d4d44c874c9dbdf738b4d4b03e6ea6d6079d2d4f6fb5c3f4d19367ca229d7b354ad45dbfb5837f7d4b381f8fa56a90e2747cf741138931255aaab936cad00027ba3b7af6d5dac057a3ecb0ae7f1f743a7ef69dda152f9a3dc7e096f76e3f9114aae9b45bf59cddef61cd45535714c8fa223e722d0c1205cbe8cfde20f760986842e0ca47a65388307b77ed894433f8f1a4e467b2a1b806fd8e4c89b3b3155d5bd1543b06db3ea69b1c8533045e43047566861a87b9ad9cdd8d4b5b0a535221bb1bd76ab3e19cd9151286cfa0f2cdbe02d9e3b567ab26f7da0a9cdce8eeac658f6f86ad1ae4ea113878a3d359658fdeac366ab2af97e1089d6e65951d7cbbdcaa41af1e8f033b3a9a55f6b4edb3a1065f6d074eec7434bbec1b3ea5cef215b6be65c8664917a3c90ebeb56ed4245bedc6191addca223bfaa6dc52836fb507077674342bb2e7f67e066ad0a9d7e2889d8e66bfecc95ecf200df2f5081cb0d1d1ac943dd9f71922d290fa3f472dbfec438bfa474afbb63d25c8f234a7a345f6afa5facd4e7de8ea732ce75c7f923c3a21c4f6def27c39d43fad0fa8349d251f7c78d8bc2d6e4c37e357f3d7f40d3bc0296b948df8a201142f05e812bb905245d9de4194875174b1749a2ee4c10b627bfe2121c1bade538e2482c7f0a7c8020b7ac905121990e7ef010896f59e6aa4202c9e3f451658d04b2e90c8803c7f0f40b0acf754230561f1fc29b2c0825e02bf6ad804e5d03377c1935443f7856ec0c0033d153fc02bcf403f80d051ed8523ad2d0b0341ac4f0e1b646abed00d1878a0a5e2c32ba131c192d7c3a829a91ed3f0c9aee1e5733c2d3c94608d8cc6eaf320f61e8b405c75f26d4964f2707738d776ba4db4da3ce891f81e80a0592ada1c97c26b5efc6d1126a9ad8c300570d3f0bcebd4583ed74c49e96cd1f7dc06359e355a13f67793eceeec45588b015bd0aba7600e6b9c4c9e14d8c31aa9a9a48bdad1f70cd66c9e4a4d76ba04a4eec4fac0b5120de5393ceb95f9b27459b26cc150378520b444c5d224d832b7f1a1591f89532c93e14accc6f28c95fdbe762c44358d6aa615ef3d07c612b6771b78c6887a459bc87a14fe3d98c52af985307f00c659ff3f40ad1a1d831bba067b7b96c3562916c429eef655edaa370049fbcbeba0d416a62612cdedeb66de957742a3c09e9bc7270e256d96afa516c48424df6a35a90ca8bb1901649dc80111231414a6f7d5fb9e3fb3e0b2b0af8fd2ba6f8fd730ea63453cfa73423a4456fbd85a1280cc539b24c0181c91b66a995cc1af1cf03d4e4a141356abfd766f599d6aaaed76b9abd3bd96c01a4b8dcd7a5b5140843ebfc1eb7f7de35d6b2a57f94469350b47271dc2ab715f0283e5ec29ff3dd415a0b847c4df53f5aafcb214859ff2d391c9a4b066a30fe59e4cfede5117c26b5cf301eab88408b2e8b9d88d060b1d78e456686007c4d686dfd82ee8c9f6dc6d8d0d23551039031b988ce2b5371823cf5bb2fa0696a8e91514f884a11123b92e15becafafbc9f0be6831000b1d9e33f6df951c0e686f19d51ff93da2574d73a4ccc07e03c28d5940a7bfc45508c56d781341bec201878f7117fbf58f00508735ae843585155da49bbd7fd9bae79eb291bf4ad2a5a7815d48a889b7b395eb204ff430999c4b53bfd8aebac030b092b8fb7a2a1a8d65c205cce38c2d7b416fe0cb5ee2ba70be7d650a57d6964b353b678e22a6a25a07be9bc132601f6503b15da55e7da7875440edbe8b6c619c31b8e49175716ebfdc786c5b119dc3049f82aef0c206d92b61776149eab8509afe388ece2e2eee053756bd2b34d218db96280f47a0f57f6c7b9bab5dc375ecc73ef6b119fbd88f6decc73eb6b11ffbd88e1d8186058f32755213bf322e18cf4d130dec7c0ff4b2a18d222233f05145e9a6aea53362536e6ce19c65c6a846d4ff63da0b22d81907ec2ab52f54d35d423430b28abd322044c80f84c81c1dea24c013e8af73dba35f55b7af292bc41c406f7708aa349a21ea53ad8af17d7a4d2b8c12357b805070cf8032cdb4547264907e2314407b1006ae61cd336168684480f42ce13e20a16bb419c32279b11fc7a8aa9930923b382155bad7dcd914dda9cb739e2371cfcee21a131bd9441e28140dc9c352e1b2b0dc6b81f93860cf133b8f0b7478f052412cebf3daeb906230abc2db3984fab8f4477e0e80fd1afa7459c208222934637668d91845e002db9744745f72ae683ffa603d9751a7fe7044fef099c6c60e0343b62d93ae3e5bdd12640e4d0f3f0541ea51a6b9473163d16bf6cff1e273a3c6f84e6b8b1598438ecb8b1842c79e1edc682ed35201367543e61ebd37f46d4c0910fb50ed60bb4c04dba252d314fc83f01c5122691fcbd32812b248d6ef4f68793194ad128da8386570db1162712a0ea6c8acd3aa687fb467711cab78183f9b60b411ebf758eda508c12cf688633a4d83ae8598a37c2407a62a279aa46dfecf979c50506954df35881a96ca4032038e90703a8b24e9b2a66bf390570188a5291542c009d498c72fba926cbc6c5bd93f42332a59131f13f792ff0b271d9588ab01225e5aeeb0139574ce8c6aea089dbb58bc17680cf536c4247a3d0a29bee214da22aa286df4774d5a0b614e79900c9854be6849b3f90ae5fef69046aa5e8250f9910c73484e28a934aadfaa23153146872e14e7051babde6110e6eba232d5739cf22563f546edce41bef2910c98aebc6892b67908e5d6de562e3a7711b82a88581805450252b1e88d11691c84ca8fe4c024114d09459b34cd5ff85ee1ba3618dd9757d4747ee59eb7c9916f57ad391e2993059053aa8efc7df62dfc01d06447d7bdffc9b7d46ebd027dcfb593af275ac76874266ad5313b661aef6e517203a2215783821981282914b2150c5a49b70ff4fc0f86f09cbfcc9ecb9536e5acc6dca7eea1b7f7fb42fa9b7ab0be09992c8688934b11871dbcf44ed57717714caf923a0e6e369197b884d8c9ac05692f86f1b40d66bd36695c8dff84672a1d7860c715d30d4bba81cd9d94806ca3ee830ee74942b81072d1f47869338e8666638781ea5d0ac4adbed50b944232a92804c14c874ccb00b869503742e2c3a5ea9db7137dc5fb323dc50ea5477313f06b28378626e464bf1c4643bf86bfc4a1cf903db2f692530093ac8e703fc28382ef5381790dd5fbbdec80ea8dbf03044ad0bdb78702cad5a68f626f4b5d7e81f2232f4ba98ee0aa08845db0b0b58a1e1c5f8c7c1288c4fbda7464a4ccc55f72b8023771f16147cc60e615ca390a667797f00790dcbaec187063dd39eeaaf5bff51de269f950197d4d27ad66169876d2808a1ec1064525dd76d293ac09e1905832d23631667ac9d0cd0a9592b7fd21b5408357e31b667ae0ff84c24e08147652c9eafae6a2889a341cfa3d3163282182d0fd898093bdbfd25e6dc8642901f2de7a879b7a392eb7c101e792c23dcd5ddd213d6b5c722a00a25fbcdfe7de4802f462daf8ee525547e060b2d8f12a10215b610844912249f2d7ceb511b4bced8c9a5e8f4ca8ada1116cc38ee11af40fc4fb8b4c0159345c6a5b6d09cd30c83cd186dd68d3b27c888ecdfe770db2f83491ab2e1afc869262a5e76d0c9ac83fd6d00a1824b2c97075faab8b030a5e5c1e7e393a0da8e20f3934da798a8773b1b3f20a16e72d8b60fb95409c699dc847528719966982b88609086076af5e0d6f5162810499d9d0dbb6582022e5a9a62b98a404efceccdbcfd68f2222ccc65b8c0fe5f43298453b1bcb9985d9b2f5e14ae8bd14672a502d44b57b5b867a892ca444c1c6f9fe86a569f67412b485fd952b21096e214dc8bc864b9b44b4b1ccd8d5c5f91d62aa47ca1e92703232e00b37d8c2627b96041829df3e404910a5977b52f0a4065108e758952d4869e871a91042eacd1e394a638168e98fc4c1a2bca699621bab41b58872e21cd6b84bba3db60e28c9a56f233b633345b6166e64118cb52c1608cf8c88161f3e6c0cb1fce2094d94c75f0a5f59505f4e0423c73ba74cb5cc77b8680ab1b884fdf46b0015340aef1691a0e9e80c37985ba2c3ff15f59d79f50cb847708812f30629eb519339adf653540d979c9b4cd36aeaa7502569aab0be51e6a04540f9c0bca4924b5acfc89193bef06a5c504532b9b7158bbe1578ce3ba77bb04ced5ce5115cbfb893a8099e2a47e6779220d8bee5dbb6e3e3a8dd204d1e920fabb4e312235cf045565823e6036b7cbbcb8e1cd687e10a60d6f4c4da451333ca0c61e8c7fa9ab9541a77035ae768081efe680a3705170886ed8ed3438a002d65aab1fc6fbb949058d542de7a55bb2dbe976a558f08c48515bad86932d83de0c8e78eb919bcf27ba3e029f9f216287e165f18ebd89a2df20ed5149da524eae99397834290c5279a881c10fff97d8bcbefd80a5cd8a8186c6bb35e1f468942639f251178b052ed742e8ea600a8602233260c154930e4d293b700b42946175ca37b6990b7ae8331cd6454231a1c973ae25f208a4345c4ac65ea8f05232366909eb8b08bc3d528840d26ac38eca4e8baddca21f9421a6262bd96bc1d6205f6806a33e1fcfea510c50db075337d0e1a1c66256fbb2ca8c593371bc2509963f39dfd5067eede4618d63a2d4d90c3a130471601da1246268b795beebf197a6d906542312e16d26cc7a22e9377e5c1e0cf58cc753b32675d3c5316eca96e57bb510ef661e7266ffef17c6aaee8f648b9da299baaecbc33b9cfa4431d9ebf001b8209fca5627f8c1d9ea654519b6e5cf122f8e538f95363e7eaa98086cb9bdde3eed3e328faa8ec3a91b4ccf620b410cbe50207788e08ddee83eb3abdc6be0a974f0249a339392d39a632a568d6e96a64b2a5b10c2d8acd016ec673bb813df47581fb38b1f0d43c7706811c056c00eff69059ac2aa396fe52a8a37ad62063ae40c3cdddc24c4b153bc22aa549eafd29aa14577d18f2e287041a2e2a8180215a02cee61ab9b5add66403708f473c3b74d252b93acf7fb0cfe3c068b8959a346c22e998a87d2dec4f97155a46a78e4396602e82f80fb06cb2d8f2b0c63ba821fa4d367cb12acfc005c8c14c7003d1a1435d48cc70cb568a1f4b184289f8803cc3bf9c5c60098fad2461e5bf3ddc1f7f7614ddbe3a6e827bcf5e809c0a1129b7f7fc6ae9777b35dd429c192ec493f95fa6ba9868585d75f206fd0d41f6e9a4888503cab46ea2f87231a85815d2cc70cd056086ab1b5f621b9cc09c5bbd19ae18915d2547fe3b3bc96a5b66fe1eb81a7f40e1a535e95f1aae59d97073f6707655057154cf69fb1a5927dc56a254d52bf35375f130ee72737898e1a9fbabdd7e1c7ccf1732e13bce03785cb8866d5235dcac5117b7d121a0baba86f97f6476e5b85ddf30f9ec18819174d46cb8423d570ad500882367232b93c4c59761eca230323f411e6a614acadac0d0860b31eb005a840eaf10cae25589365cab0cc982496d93f9c57b11e84c319ba7816fb95c8ba33647d188cd223704f7e88b43b15a2846604517c01f54b8fc5422965d6130d7ba382606c68fed654c6876e005a1e4d3724579c9791590edc1ad26f4ce3730115e338b09c0388f9d9d3a81f772921db46bcc7a7d322f0e4348ac6dfa3ddca5abd9d189dd5ee14f8e4fa4410f015675f9055132456b3803d396d722392f40b640b8fe77681ed5a6383b2cda3f4080ce4ad6706379c6e513d7b938db95e4399f82ad85c54f7ff67008566f03334f86b359ed8475c9478951946e009f82eb2526773fc6e91d2ea17b55dff189c1dca2e6364ee59c2d28d4bcab1302300437cc05d5c009cf832b1340a4bbd5e153f01c2668b5fb7d8951490f0a27ff0afafdc94b8509d5b4622ab453990a0239c9a033ee79cf0933fe62f329d8014d1022d2502c18aa070fd5be218ce7225828a33f42973fbd7235803871e25f9b62c5ae7344973f1b1ff7218e341a31245f11fc762451ab2f41ff204927e1947763e2a9ad9f723e0597242fd8be41edd9f058c8b630bb20da5be6ccf1c5a8042797a3bc2998b57811b6b239b41defbdba3daed5950ead82929089de123d5a46f83af69e829954f70d8683ab56c47201ade646053501d643ee128d060b0e8afd1055863a07c5485e6003e8b90a8005d765b2d901cb8aa63d4123ccf1affacb0af5ed42cd14c64adfa7401281681c811915475bb36b2d6ec497bbb7b106884bf786dd11d4cf7b724594659a363d3efb14466fff98fff9341b33352cf98b2deb9c9acd9a0d97195bcd6655a7cb3cff4dd99056c0f72ceef133023eed6360a1e6110cde230f6aaff852975a080731c12ddb057b7925a760c7f0a12463514ff3b7f326f7148c5a88dd93f9ee6235e52b1c394caf286ee329186de8187714fc0d50f0757e269723f7932ddf77f8b01f4533c353f03a2a9c1f75be9996a5c82a45d4f038f49d03f99d5d662596f321f59e8253ddab930e33028968140aa7c0375e1836df00062103d4daabdf11b047596170b7164e0d9c3534b4af4bd1f81380cb18879f82f98d997c8b8fc24fc15d937823f308d558ecc06e25f0511d5a2e8b50a51af95c4ce91680f990a44f19e5f345eae72989930796c1b3575ceecca942887ffe05cc5f9a833ef1710e7396140d7df1b1ca889ea838c03db3f25c0cdc117a81d8fc15990bfb9543eded2b51c6eab91043e7ae42b768488b88fd146cfa903f0f0513bb9a5f83a11cd921146fefa64005db3e9432203308fc07b43b589e40055ba23ec01e32ba66a67bace1310181e774f15174e8a4d082b6c4d31f1e4ddfb2af7381519ba2fb635893c57b23e090811e892d31e0fe0243be052a78a2522a81899d743fc4cda6de5bd0e78f3902c6fa4819ddd0f81b8bb2c60caa574557793f35ccf36c75d221a860a8159ee05645d8bdab305250c12842c547446721b94a113ef7847179a39f320154661fefa1e7037d640a2a182aa8ceaf73f862e05c7717361135cfe5c98484c801287e0b2a1875154692c7436ebcc84273edebd0ec1ca0a127baeb9cf687775b6afc08290d5050c1f60ecb1406d0cdd6084a4480a497648463059a8bf9a9a8d9688ea2525fdd0415bcc4457294a1983127b84e5b30ca3aebe594395fe231803c70c739820a46b796ee7ddac7cd1d814c19a28080ec2ec036c53df6f539be04e45699ccdee5e131a7c70785fae3f61906847139af88cb50db001754b0c5d17f6f8bac49aa4663fb43fcbc94f009e00da5150a8421c60b6c0bbbe3b8b4a77171e330918af614ec7d5d0515ece8171d18276e28e2f3a0708b0130cc988cf2fe59cd4a1f98e0c9a3c0748701968dc89c3d5156aef4b0a2df677422d84854ee8aa61154b0e39be03262fc260f4046f5b4d67cd420f2f409cd8aad7c91d74a650d6bee71f1b04a4de902c6a084c3c81bc826393bd434f238d33e71deda722dacb8240305cabae23b37706777c81fb4022cbf3ef4c76e2c177d8775884702dccc4fff857cad025800af09685fd365cd6674e98f677e36faee511419a4c569532194ebb6085edb8a233fcaea9db3677171b8878c34df818553724a790057ce3ea0591c0faae1f502d762206ceb5ed888c46ce2308f5042235fe199bf2c1efe21b907f9b165570ae49c90b5972f450be6e617e4d7d5eb887b87b1c5f0ee0b39cfcd7a7d23a021adb4c7c0c5f38a751cf4c0ce77d9a114ba3940391813466f508a85d8940622f504ade35b249ed1406e9319ca02ec363270690f242ea2f5e42f0a74f0103a754fe35343fbee66e61e38e4ebf54e63d11be6a7e87e07951f5604500e6efa49ca4bd6b7c3024eb1f70c2bcda0bb29c5e6a7afcd6c1b1afd828e0d2cc3b511926a05b65dc74c39b93028b26806c754fd6b584b42a219e94d73b4b3bd776c21afb31b8d48854dc1ac0cd27dfec4fb833cfd12c4c4b5e756cc3fa1528909d3095f0e5ca8455369e11d75385c85bb0f1d442f5ede010488a89e9e9c63af1f226aa2f0e720de18af6738bf4fafc939191ebde3a24b11ed8efaf6649c2cc37f62a1d3036dd30786f022166fa8660422cb8a424d2dd54718318c5cbbc6f6a43b2e0d1886f4376d51aea1ed6da9bd3e8c9f8592034b46d9725b2b20fe5e2cdc55a502eb48d3b6b24116a6951eebdc953e0bcc08357bd12deaff10cb01f0f0373289752f945ada69007918cf0d00e92b992d84d13c043b108d0263067070f71c0ae4125d94ffb1bd71809dc878590ba4a5017a3581425d201232a30e55959fb46f7277a6329565ccaa8a9994f591798a2d7157b1b6ee24916865eea27160850585487bda47b452c2886cf661499a8c84404a9af180bd0406be8fc80e25d79a91ad7d8ad49402d193902be150468c1e63e16f3b056004d903fb03355bad56a3d56635592d5683d55e351eda8d66a3d56834da8c26a3c56830da8bc633bbcd6cb3da8c369bcd64b3d80c367bcd786437994d5693d16433994c1693c1642f194fec16b3c56a315a6c1693c5623158ec15e381dd6036580d4683cd6032580c0683bd603cafdbcbf6aabd68afd94bf68abd60af97075ce752484c77b6f0c7c3002e39fe0377f781bbf7c0633064c7dfe07e7d7e7ad1bfc1fd386da644bcf43fecee3c5062e655ce4a988ebebbb894f19275f71db8bb0edc5d8abb0fb9b34088b9b35486d8e1ee57780edcdd0a77afc2dd71e0ee3770771b789543712abc061ec5a1380d3c063e03779781bb3ff118a81461a242040f2e17e9021206240bc815902d205fd0aa221d407aa0ae3c5047239e8419cfb1ac0e9063a9a8b458bfcaee3adb070c3913722a528cad286407c827aa4fe95045260001a4132aafe2aed2a28274b2c2f127554041a4cc00c4030d53419c9052905424152905b9845c422ef129214c5a50c80c4c154122e7533a549150905090509049c8242492ca7a9796a7a9f19c0835999523bf450d006a666c52137221bcc3e842b0d9a44ccd1e732c1816353ad7c37c8be55f6a7afc0b0b0b86a73dccb5de860a8b945cfd560d0836562c3e58b96ad3b4cab1f0dccbbb4618d7ea5d567efc968f81b1616abdd830b55c365b251783c5c6c58689c5a6c58689c5c6c730d783456ec5a6f51ea3c5f42e562c20e0cae46798cf2deff24da2981ac2444a1555406e980ac2069209f2042d9855cb58c715e9328e30ab15ab651c471897d56a65c57259ad582d2e2b9855cbeaa5c6acac56ad15c97a59c5b4d4d56aa5b6b0c4b4ac562a2c5c5a5a56ac9596d58a35c6acc855cbc5b57a4991499045c824bc87afaca6d428b20819c5921a734556390a54959c8c8d8a2366e845c86505961ba44e250806c8f5936b596991b1f1b9e2f81c33f4f945e8b3cb0a9f596e7c26759f55823ec3007d76fd7c5e69c9cd084066565588a9f142c305c7c243de546c3035166dc5b52280990a3568e0786eb6da67970d8bd6c267a647e6a6ca62602f3b2e3a2c39640a2a335c2f1ee7c50b16cc8b67fd0b9f9e1bd967d88e4e4e0a9f677cc6f1c55e25093250805143c2b8781f2e974bc585eb5fbccb850b9b4cd36246a6c6bcb8b0902a30234d8b19991af3e2c2a2428e342d66646acc8b0b0ba9d2a36586a8bab20059849482b440146901328aa40059843482ac000c8c1172022411ad28e412befad6149f32fe08f3e3c81a5ffea5c70acac5929ac2121353bf855482248234424a411a71424a414a3115c4c928036b1ca5b8481caa4f4900091c6a8b8a964f4555e5d0d7d40498acb8562b978d4d8fd18624527bb4a05a53481c5ca493292c2d28262a36d209596d7adcaa148d5339694139f12653a0a056e40ce411e4115690389045905290459044582c1baaaa9c4849d930b66c7aaca0462275f5e38a0da415e38f53eaf8636bca480e410e410e3156a9d858522caa1b8b8914ab0915cb091310482224115208d90329841442f6400a217f207b208590429043c820c82048285208f94390e7cf28a2a8bd79c6d71821e906f04539a1a447d225e574482bbceee793763a88be4cef107f3e893e6e7e13c542455fde9b7fc0f404a637e8b4b4d39fe22fa6b92ff5d5d6477c7de2744946455f16d114efeff5dee6f48ad9e69d629f79ea5eeff5cd78eb1cfdfbe16bdabc5f5f21f6bd3e7fbeecf5346a89f885eff57a1fc3bf8fdd36e8738e3ee787de5d8ff00ceebec6df8cf7eeefb0b8ffff0df038dca343e1f98fd35eafa77b185fdaff617428b44f373dcdedb3d74cedd69b88ff874b4dd4fa7cbdcf94f8a8dd78df0072771c5e7552dcbd9421e371e6c9cbd1bf9b3f6b1bfc0feeb38606779dd3fb03e7dfbdf9a78116fd05bd8c1528c8e247023e9fe383b33146badbeeddcfe599385c12fea5a70aee399f263e47d29c0f0d3e419fa1b4469332bd4d356ca871d423a507c8d5f6669f134651fb1ba7afcf1b4caa3d349c86d79ede67fcbdde03d31345adeff30dee53573adda09102770ff24a03c8f913daf46f3089062e5e1cc2bb4f7d817678cd12bcd2a8b8275ef2e8e18ee0800c7142b8779e2a7f3a7f371fdd68bb5df9e9a989e98997ec3be194096b7b91bef4dda1fe6c51df35bfb8dfe646d3dae6667dfe8db6dbbd79b74d81a7bea6967157f8f232e1a6f4fcd4faf4d576c96e6be20f6a2b54e26c9d4f621efed6d744f1cd0fef657abc5f03d37338b4c20f6a1bc4fb4b9c4fcf9b1f4efa9d1cec38d919c14e087692ec24b1536407889d1a761ab0c3001b2088ec94513b483bb7524ab944091cda6d837ea9ef0e350e87c3e5342006060a10d4e478350282bbbb7835b2b28324a2b8c7e0ee42af29cce0c5cbb4a3efb0b88b170730e770cca09ab1038f1d99003bfea63848e7b049dc991798da2050f1e2304f93b8d3e1eedefb1b4c9a71e3d824eef235d3192da79bfa24f5fc8c8644268c739838e81455f2e8698b43034e10c7a66df132f1f6d5d824ea1b255e6a1bfcd767703fba643fdfe1efd49ed936bd7d9d9e76a7d806e63ebaee8f533fd91fa736af897de9d5d9e91516ed70eb0b3ccd74dbad83da0ae56bda1b64f2dd20d02b16933d5d331d32751b256a9716162f8143597128bc3dccf707e348fda0bbd7bcc2e0f9be9a773edd9a27fafa528bda2518275b234b45c6dd815e4f70c10954eebee2158927dc752e7dfa14eef8f429c4e170b81384860c60c70e77771f5737dc000408ea53ab38ac60081d13281c5eafd76b090e99284d2e2001240598e995a932363eb881e945ff87fffa4e547fc6bf9d81a9cd2d2cbc85e56ad4fe2e316f77576119c7293cb0f7f99c89be193c3c371e1b4f8d87c633e391f1c478603c2f1e9edbed66bbd56eb4dbec26bbc56eb0dbebc663bbd96cb69a8d669bd964b6980d667bd9786ab77648d4101a863c0db9e1eebdc7e95ca236881ca58c7dd16d6f066af4365df4510b4c4f278cfef23553a20b38dc8e6b0610543a972616eef86e13104240e8388f57ec1573b248154a89a60a89a20a0152852855215f7f78527fd8f5875a7d80aa3eec707f9c0fd51f577b60a2f60043ede106a5f200557978d5203d505283d4508324d52031ea0e55758723750718ea0e42758797261508540532ab40bcea7043d56147cd414acd41aae650830e04bca83988a079e653a9b70df278bc2b3cb710e7a1d06e7dfee3fde7308785dbdaffd99de43e963963e93eeab88f3932a4400626808470c96073600a11e89bb14fa720c3cc01727000a99c71068eb398c24713dc751083949b0df4b88f325c3301701f518801c3a6e64fc82d9184120ca609ee630924c040f3c2c538020d1150ea8f2a4468310260c6a384508b42faa906eede82d727203e3cf7fdf1ce55141952a7aed24be461eec9ee43cac70c413ee62003870f99fb030dadd0bce8cd3b1c0effecb6412308d805380a0ff19179f2d2aaf4483a4c6542286150f8a81314081a44ff64a2c2ddfd47e0f9365d6d8347e9cdf6486f8c918634d2d5277ab282408053cec3bf14384402da00de005954f083fa35b9ff6ed58dbabd7bbbeea694f964da3047ede4ebb9eb9dde269f6de98996b114b5d45ba2b14cecd0de7a55bb77a4344fd436f59ef0cd3d1beecfab7ade11de13ef56802705d840cf3c0b40e3258f5e95940d3c7ace63c6836587133b8a8801821d493b6e3b7e871300ca0b3226bc603fdd74a7792e045da8e6cd3e9dd716a4f2dd16bd79ddc2d086d7166e4a9cac4fa18e2b7444698cfe0e02cfbc8918989e39ba77c2e85dfa4d5cd238e874b38ee08d0ea15247ad494c10b53e9392744dbac3e2ded677a657480466fba84dcf1ba59962dfd5f7067792ef9ad49d0d8e83f76bebb41b963b21c7387f7129b7ab4ebc5c42922a37d20cee258ebef7f7e545c2b133af930d2699578779af999e3e7d9186749837e36da677a8893bf3a699f863de9d9e44e60d6a8bee9c6c3683fb7421c8bcdb9e79dbe14532531d2c0c59b0c1423da242edb9d3bbf57989e6d151b0e8e8e6c88d98945e8d80b897bdde9bf7fa9eaed170eb6b1a795193a228195e8b9e8a8e4a1ebda20f6e7b4d1e8f488a3b1115d10e431ab544f36c3acdf47cb244e5159efb8b69f0c912a5399e2c5199e2735be1b9f5cdf89763a6f78be8f69d79ebdfb8e8cbf3e9fe70cd4df16f6d2ffafb32596126e226fb7bfb3ff46a1cf4b89b9ee80bf1def8e74b9cef8f539f9f89f86cb2c1bb94127f5f60d10af5fff0ebebcb44acffa2c3bf4d36980e7d99f1f6dda6dfe1a0cfb88715befd21f151f474c231e9337fea843f1371f1b77dac1f9bf9365d272cf465cfbcbc9b89beabd3b3f73713b7bdbf4fad2f07e7fb232af8d4e8a181e3d12dd5967cf7775b8ac17e771633796eb61a6d268bc15e3ba54e4e0a33706e6404008518306c6a7e89e7a204125eb81861041a116c5a0060260419102a8b9812605e5c2e335a4ea110fb6e5864ac3c49422bdb8bfa5eb04650598d4e3e69f9f0c378853665b57c88c2dde55345aac8b95722517855622616c3e5534598d4a92abc4ef1c0ab1216af4a68bc2a81e155098e572534af4a725e95107955f2c2114a5e8ff8793d226d0286d7267ebc369100243faf4862f08a64ca2b921f784d5282d7242b784d22f49aa406af4986784df284d72654bc1a41c2ab91245e8d3ce1d548095eaa128d57251caf4a34bc2a1579556ac1ab52cfab52ea550906af4a0ff0aa14e555098957a5255e954ce055e9055e95aef0fa42eb5584d7d711afaf255e5f28f0fabac22b0c041d02bcea6af0aa1be2558784579d06bcea48c074f3ca24e495e905af4cd82bd302bc3245a0523da9547b64c247244b9cd0b9bc264e61a52d56be74964c9d7be66dda9b8f6635220eb7a4465d9283f3b8cf79dcefe61b278ef88de8bb2de873988bc9884946d7c429ef9e79bb8f8f3245fbee82b03e6da6c41b45343572c2e8fd01da57eb5c7a7fe07c8328478acfdcc6451b6324d4067df622ed5378e6c0453c740318daf18274414640453a1e921112928ea7cba123c88888a79423ca389cd5a64fb7d3a1182fe5f001daa423a01de23c2ceeb3e902538c6a5ddc67c6671eea50ebc3398676b828df1478ee4cfb63da1f208da475c19dcf1fd3fe5cd4eedd8d2314b54038d2cb8493dc4701b88f43eece12d2449d5e9d62a015dc7d44eddde17037f20d6ea3a10e9d0f10a319ffd2f3d126333d81b6bef757b4c37da2e7924d876e266ee26f13f1ebd32efdcee7d2dbe06ba20d3a09f1d644df7f6aed9b1745ef924573a579b7c5290d2dbc7b08b5441f37a8add0681b83bc2299b1f9daac53620a9befce0874535c74857837ca68730868813649059f1a2dcc21f75106e7c6617a28f0c45d671d9e9ddaf4149ed9a74fd33c51a1b64e8f8550bbedaf6899b0f6f1b9117b7cb785cfe9b1db9a1e6546ab596dfa2e8f198f980cef6131fb70b89bb18f37d431196fa8f50e46765f801154d6814624b9ce6570dbe14e71dbca980efea5a7ce45ad4fdfa0e8ad8948af3fb8edf0513487c339cba6e406d8ebd4a8f1c1f202cd4b440e8f52a3c5848a482952745e911df8ebe95564053a3e1ae1eea7d721a8fc9a2b14742e8788e18e733019e5acf3e993e8de1b385c25424500271f18e184049c80081e5ac11a588841924108232b703d290e320680472ca047cb1440778fc9883d40381cfea543433f4e9f1e5ebec3272bd47649fbf4cc7208d193a5426cde9b6fe070238cc6ddc7d778ef8fa78b76a8b5457df8970e1533ded64c2d116a8d502bccb8486b8b02e9a23dd2f7055c84c3e962901fa824b48936b163866666000880200803160030782c168c25311025598e31443f1400043a763ab246542a954666c11c0a611005310c83000883186010310419e71cd2a20eb4c17d9bbddbc1a2a8f86d8170a0b9335bed0c2250d671a16e2cd303b0d604524d6aba1d8efd4b000ddbd0055a1a47df0b913950a024f31902cdf6a7098e1f0204f45b034daca8f9560554528276b806dab0827f8cb22d538adb30d088daa419b3826a117ac6b893e6d87cd20c18de0186740b6262693bf5484a14690b34f894549a4c4895268d4045249789f0afc8dc028dd419b2fe38408388576b746cb87ea07d0311b1f7f085599a2bd268fe0b6662a05d0aa8a2973423c205d0ff6d6986821fa0eb891b03ed0a2d97664cd05497e6a95eee9497f627359384b7822068d7ceca5222870cb3c1df7e45c62b7564423bfe4dc3ed94ce235fe207746e62ff26f719d4cf83faa10ada862776216b6c67c6302943fb248994823c68fcbc9768e3b73e17fb6e2e5e704b71cf41ba4e616e23219620fbadb823388acdef9a58d7ef7eba655c93a37a50596d3346baadbba105e86c46841ca25c8e64b2de429b4abd22530c2b0aa5e5390d599ce5b99b999cf4fda04df05991932effbc53269dd884ce9bf4e239cfdc5a3f1faa83b61a943f2b483858f3dccdcb76d41397303f5bd0b1fff13ac0be06847a6e1b4ed3bdefa43e96576492c386a7557b7441b17793ef0f775aa4c7f2a491c8fbfa1cd040f462dc40637c6ab356d20d35a23c7639cc61dce057c6166e94a1624f488d54d54b42aa82e88c1d04df85b23f14ab865aae77dac2d8a05c21aaeab59bc1198bac273e4f5ebfa01a3fa9422bf0315a04f5c7d123f8bae01908dbe1550730303953057438ee117d430b989aee9979c57413f4246c5842e5618a72ef9ef578e75a5718bb4db82ec0cfe57426d801e3375033857d0e09619ddba5ea9848b7bf67afbe1a6bc1a037b0c77acfafc34385e6eb1b602e4d89744ed059b7e5f80b5c54b6fd1257d8ea05f348feb7efa6e25f87a1b53690907a0b26a1bea098eb695bbb2bee696c44434d92fad21531cb9ab7e2855071db9e2f94aa39279365a1418928d2194bb469c30121946b8bec36878f68a4f80a7053677a2cbf8371c16252e116cac6bb441fcc984efe5d600fbdda660318d2668d54a122872b6054ce128d01c7097df9eff477b0af4eff48a8bba18111ed1fba238b22a8a4f5f8c8518545f48c4b8add12c83ad774f740becb94d536da4146719d51098601e463c2a66cc6b087cc72aec9f69c5a8a584a970d2c0b065812488ffd4d776293a84398d58b76222132e05b404981b1da5cdfebbe51aeaebf80033d8187745468bf66e88d80f7293908c0b0e0528938940a38a4e3701f5c3d3ead73320eaf4f2fcc6ba7a6214b63a51c479eccd96eaeb185f4eb9f86a9ed5f35c3ce18d59403c9292f1c09779b5183f23a293d518af50956e3c59c2371d5e279af906ee436653ffab75750603f3abedc833daa447f9bbd2dcafdfc8afce82e1e6a4293eee84dddeb2fdec8e53711cc47ef88ef9a6b8412301f5de261fb4d321f3d52fddd51a66032bf6bc4436904bbc4925d942cfaa508f8781454aa9bde891542b81b481e23a4412ddf7c8d21f8e6cc079601b509c90fe7a6a55dcd0c10de765a8ef1d1199afde8d7e7e92cece56b2f81d7bdc7d6cb10c397a811e240b82df4346a552e1993a37cab5ad4aeb7e42d19dcd2fd2b71e9c8f687ac3d86ff94ada181bcbcef4772fa5adcce7c82c1ac5bc7bb6371c27e7a8867aec66ae36f8470549beaff3b8f8ff17e8d2ff733d0a1cda64eb7d95c81da8d38b0c7fc0b74af4df727e5d123c2748b349806e7dcb19337ad588746c534e99e853f008d287e97d05116f4bbdb342bbe0e79d0f491107e684aab7412b8d8ff749a966efd3072918de0d7f25bdd4a0758c8ed383d341a5419463f0edae72d189b954e7d3fee60098b3b206c082def23fedc623785c65d466a08c0c0d9a5d9b8d111574f78e98e254215ef5a2de1e839d8f84f8c017a7a1a32ade8005f95e0f96c31512fa5a3c7947838ff81e4e1fab1084eb27635d442c628dd7aacd332330736a9fe85356a5a0439a853b88497f7447e0b30705a29ddf51ae0f1c90693a604c6e234705be0138fb50a3ff4d939bfc466f373077afab1cbe360b6dfc9c1e15070be93f580d0479de9b93e5d4ac72bf7446df25afaa9de18c996cc21b8455646f1971ef827f87b2f1ce5afcc255a93114ece72791bde9c864524cead891fa743613a7076f6eb84e93dee7982318607bf4c38987e8573e9ef34d1d2c8edc18e6a3f34bd233dfafb05601cdd257090497caeaebc89046130d32f8e42db7c0f2ef54a200c8bdb3c8d293d53a0e557428c0723e6adba5c1d9e0e8459f6ffda5c73fd8f41817165a73f5dc16fc8cd4f56a38e689f14822c6f54463ac30f8f90434380375032f0c5f25e1559117dacdba4b8c5599dffecba00abfac15279c6d83d38b8028958b23a178b657da6eef90f75eabcd0f1e5e20983092c6180c15c4e644bf7c47bb9335818e22156ae8d13641039f023346e9841b6f429b5b1a59f83ebec0af73b6b9da32f4e429cbbb5f480c510282878ac8a6fcf8029dbb3978e784dbbf365cceaba04c51d6797e157155bafd55433366069d9a55b5e9e3f5d97fd10833f8c71874e72a48f5eaecef15afecd7d1c926eae055876401af6d8785626f7485b884b27ebb2c435175fbbf82a9acd61499101759bf7b240a9dba6cc62c18d0629c4e0fda52d040698f3e5564f14441860ee53cc3d832492713bcc869f2f9bbd42cb0c0384b9c42e4269e4256287595292e5c9d15b982d251855cce1fc1f05cf88d63ebd8cea2102d89dbbe5926b533ec1260ba71db1495d03f48f779ee46b4ca93d5784d12a26ff790acc351cf6c94806964b6772118d6226ef6c9543615595198beecb17fb2ebb007a7c95593670511d2f997380f54bf5d2c3b259cf3fbc959b9c4aacc7e84d99dc1a5135e83365d3efb47746de2a33154cc80255990bbf41139745bb5c9943cdc63c4098589c9f329bb31eef5d1ea45a2af1fb9b0702e75e9cc460d8ca1c1e418008cb3c2f2c9dea2b089699feb417197b655e3729cec6e6d170dcaf7bb3fc005d998b73e995f1a0fe7233e0215d9969ffca6d63f3c1642404de0dd3f3c4d2df51d515ef1dbf2ccf54c65f6cd6c59b8e268df0dfc1eb135660af613868cb9cc39e99afeeb106e6c11cfb85f59bc2cc46959358936258fb87dc10e9a0a65b7f089ac2cc769d43665639a3f919b286be005c867484f50f05bf9939f3b2a8f247f9f865b9bf0bc272668996facc76a86f99d6f76928315345bc325e24971989ffb3347e1c03bfd0f410e8e798b40f19c0b50eefbfb53a687483abb4bed321173a6d1c637b03cd8b14d88b29a4190fcd216b1762af220163d877f5f20cfb76cb7e56334f6a6e0a1d37760c606e7e0944347be00cb33406a02cde65d4a87caae0a699b40a709756989c01b633d2f121a6a3477d71ac3b0477ea2fc49d19b7a690ed4c0d86bf36fc73a1b441e1ad0546bca312c250b3820ced1c58034b7f49b9e109ae000d5d06e396aa6a1a9d8f7d83faa4d671cc456fb82d56497921995226e9616ec44be7787ca437ca40c4f911a5d448cff4d06065c9b2a319a80f31f82f81798d6b8d8efcd0ec1ef568e78d5074b9acd3d332e443cfa77aaf991a0667f7b44c23a2778cd0c03910f2a105100ab775be6737d84348871e19d834a7dad4e7e08a7ebce1ba76fd0c1efa713c10833ef4f2302a99be2d4a68440f9a153b789b4e899d3dfa78df6050875ee707201fa1b38d7c146586ab79a1710e833e749ce3cc7c6857497bc7ddac2581fd900ed3dd481f70122627a4653b2f28428ffa59843735cee531edc37e5c08a4758b48e41b02d2d170f324a4230b42fb23e1467cd02c216d657d74ca0e8f9e811e6d70db9028065ac226ba5f4f72b2c28c703f9aad0e08d6ef4abc7ca230689c81413aa0fc823452f332bc24f780048a04209854ae30894f50b048d7914009d9c583f4ef8589f446bc096b1d74604803c63ede7af0e96b566fabfd68cbe0870369de3fb9166cfde8121efbcfa46a468db4423c42f0e17a2fae928012e959ac7c9583481a01124967ea99de250220916e1930900e4f12d359d79067e36a41f8f9e6c7d1a2c600bea83c212993b55a4a4c327717e1d1bfe8212d8464eb5d28261e01e0205d2db700a21d5d08a0faed8ab848a6232cf83eea833465964042fab64bea8e3d69bf287ac449bbcfd3a06e86a769cb940668498f7f4eed750120e97a772c5bc602d3b8ee050767d28b8c4081b4c3d963d5cbf9149bef4760dd2a164d4799b44833d228eea2730e0d289fb50e3ebf7d236d253bc386f4297ba90f54b240481a47337351290b8e230b205fa11f4dab07d1a7ed282c467834b30881b496a0d8e73287516400475badd13fc163b9aca1aa124bf91d980ec1d28466b7bac68784f421329e8d49da34e0331a84d4e817757a00479f3c09cd56199b586a50484f2cb9f43e19d2b6c10c8da8ef3d0213a4ad0d9727d3bab8b0cbfab8a3432e64d61ff4e522ace39d70b680a8a6f9d835eed28d5ab65dc442d16667d031fa9507f4776c9613d285cf98f5b8c6a75dbe1b5271425ac9266cceb610c5bffdf09963a16bb9e98413d2a4d221bdac211db984f4f7bb31b5740d212dfbefa42145da3fa7576d7097b3af690178d203b734fd8d80a0ecad61f523d9632b7fb894614abf826af789005b205c2adbbb79e788496523659c4af7270246a0d1e9997245490187e9d8a40fd56eddfae517ac43a7097b079fc80ee6a45721cf93dd7afcc5323a5aee5f80f1003e6068fe631ecd9219964d6a29c027ad3dab9a1367d56c738706309c03e52468a42d862c86fc183bc5f6681f40725f1e65cffe5bc3e8315d75a6b55e135de81815d45a83ce11047fe21d82a18b7e717af9a66c03396339870d27f7327249b090f6d0da3bee07c75dd9e22db982650a92f624c34e9d76ee919a65b39ecce8d91b5922c202311a5eabf4ba9003f614c0208d7c5b349d4c36bca12eb55dac7e19c03d9ad0c38b988f8e2a581c4ed754ee79a2094eb7f99e983dc32db23d7678c71146e32622dd26848a8eeea06cc275a519edb10b4e32b02a3b51c018bffe82fc6161e3e93ca448f78b55bc489bf52042a44162862669d01b9f075ba4293d020cc42f1714743a032558e5984272c3af20387622f6f89fd4029f40d39eb92f8a1892460520ce04170ed29dbd0118e90434ecaa061048909e19fddbaae84d2952a4b5618a7430a9486fb68ab429f3f3d22f5269b1f05091e6d2862569fb6c315a9e93c71459084143db490198fa25dc08b291340d3bca580c1dc9168a9f023743d8cb8ba7fb89c0b05962cdb6079c9999dfc57c9220905e96995021ab032b9cdc2d96c48c51a6298d198d9145a48b2e4b51d1927541d5fdc59f2744bfd35a4744ab747da816d0222663a1ab58ffc896748179ec75f5e183523379bcc8d705a8d04db0b8cdf9ac40ff4afe9d8b4d3e4da8d2208bcb24e7322db4ff0f1eae6e38592f4dac23623a6585316f7824fe8458d43d180f59a3f6bf4ba450782578e5b6a0712b9cfeb2320f118f21f75d664cf17f1cd93db256584694950afd2375a6dc8995ba904f587c694466ff948be3ad399b4966e8fc862ab871d6c2fc290830ab948c4fd499a0577447f3d2fbb5f9d1f0a307e31c134fd48bf3439c232505b8f92b456ac08f8284d40dd116ce43d3e6e9440f2ca2f0aea66f9826091db0e1af9f8d3f4cf60b809f8dca49cb9b6e5f4de192c932621f46a0ae19aca5dc957092a445c4a32b705ef70380044b02dfe483e10bc985783cf1aeee662c1d90fb7fd57fbad91f2a29e74fb411f6a4080278cc5d2c0d135166c1177020f7ac17066e1e37df102a62f73f0e664421b034f07dad7830a27b2e55c8070636a6aed06e39464bd40b4ce9ea54ada6231adaa75d7c0a211417ed3abcd6cb3e67aba0b6c7bcdba992b5a28b78ea53a6f0c43c2d037193eae5241a8755b525d2ad660d7c2442272c96da75c2acf6fd56664018c3f01f9c4123f2eb7dff3c9dd654afed2562490339c017a7340f26a07a302352602e5f5ad22630b9575572617e262e5ef34b9a45850f26ce8d84d2227b2271f173929250baaff5cb810e0d0c8a6f29bbb920a1742b6142e9fb884569994a2cdcc1c5daf9734f1ac1b950fa35cad272e9ad3cada1b40337ff95e809a1de5f97534709b6fc394930278d5149149d7401d3260dddd4188f4d09a052734e1812a521233fcaa014a3341c3394ce9021517a3c8f8f1bda5c71456900ed19f1faa2e9df7b22a274447c91f9879a873349a5e398cb1a6fb99128fd2ac6a4f4dbfc0894000ebe28942e710e86f1499cd5406d384ac3ee196c8c84d4f163506916a05c95b6571b684a8f71d738943eb84f4f4c69833d200d1834a792d383cf3d92147bca59f0fbb5bd6745388856afb24ff7530dba95229938b7af540c5bf65edfab8373a60aa81cd87f784c56c137f87564d55cf26d9679d2c982a24d38dd74f2c46c9634cdd873b95125b73b3c7289c3f1cf7244969a853dd81dda82174869351ba5ed3a4a6b356d49aff85aea4fff17384cac46245b376d1898dbf49a9458d1294ddef8b350e6e127ddeedfbdf27bdba20222e3b85d264257c912921180aa7a2424ea3385e3d6c3198d7d7a70e7f55f0222ba3534386bc09f2581f232c56e9d7a4465c411bc79d8e15594342d18c66fc81020a1a1c33039292040c0081fa8df6a6dd570aed941f487eeeaf1301c5423736670abc4b42151adf53892d180ede18b6afaae6c12f1b25e704c4695d48121a23740f08d2386bcd7db13ed11cd20c990a7e4283b42900319d378153c92da62ea017ce436b6d70429a29faff0dd55cb47f0849c4eb04d67322f74fa23525a96b1c8f6b1078c745b44b59b2d79b095d3fedf9956add6e8db1b11290d0525a5f7fb517ab37069ee8ba4f48949bfd8c4130c8c00ef321c6dfbfa0a9c7694eee2c93a9c90171ddbb4d800a574e20c2c0b94d2527a562646852d79daf9b8ec7c76c85785366977451a8077122211357acd11dfc11bd36d93462d4006ba1d668066929248b195829318947aec0342e9940d251465d374d74b6b31477e322c86cd71860b1616791f968d81ab464ca0c451760fa8c443514269126e53a27448d780317c740fd380a0b42606a3f4c82120e5d045d138072d2a51590325be43bc48b20716932c682b9f441126d4f79b991c02be64fca551723d70287ded896962fc8ac171fddabe10f10a76178612ffc4403e7e838761108f09716079a51909fef801dc727c84e97aa634af8644dac23d53cf408e948da301aad234d30eeed7f299d8e2c9b2df4a832dae74979187d02364c49d5602947264984ead266938ac5e3098a0951e6568806930484d1a6709b9d2f90f59e9e1337af7964ff383e7f2696dc6f319bbe378cdf44f46e05a6956902b925bec4f86c710acbf01c40b31b231db21cfb86950e1b869b22669aa6e5bf049066aa73fd93bf3c4ffcc84963c73d898953bfa0a1ac835a2252dbea7a3e1f7741ae012afa1ee7b7a882d7d9ad884e523c8a07d78952934949e48d5b7141ca84f0387f84454968fc6dd1218fe65bca6d6f9fe8ead081ca81d71fb5ccd811a08d5c1a142f9bae082fab317012c58207acfdb8d4a00d64b47592020c0b1f77371e07d1b18d4e9a7cf9b18d4729c4d7cc88e01672910a13e0009cf6aa15caf2354f6db578567e55c87e36078b4dca13f1c47ccffb324f1b6539b9a03b97344793f6e825e2f0cb9a8066e15586fcc30f2be174d512a9b435facb72a320413177a3acb77b40f3aeba264bc6027ec0b92dcf8192a5091831c102afbddc84ba902b944798f4daa6c2c9bfbb59b23747f23ed5195cd82ce0c6c5acab3761a0ca8ca465d9965826c875d1419ee1db32eb534f66dd9bb2350953d6186b449383567fb646dc0f0b4896d5c0dbd941fa7e67af522d04def273d5dad3dafb4c21d2d62ff45114bf04eb9ddef607654beb7a6fd32d3fb103d1b6e65973ab044781c78bb673e96a2b039a8cafe940c5539aab20bb721125f27a842c3e04028ac501a6b7e30d2289ba7fcbf26eab4693b09665da55b2f7595ae3f360fb7c87315931441ecdf5013c513705405782d4ab829b59bd13a71c13ec4a5f5c12fbcd63cd4fcc32479a555140b5a98cc0c0798a36ceee1b106ce63c1007946a00fe72695cd21cfe4f5dab7ae2ba3c34a68ef0857a12ba3975217d6a0dd8ba2d732b52428546308b66787aa6cc2c6be4f1aa7d347a6ad072622fe43e57f046a31443699f50f10f30f62208b277270d702a8b5842ad322e0c2a02afb0bba28780fae390ce417754eeabfcd4d3c074f4fc2d91bed6843da3d43405ed8c9c27405921b4d2159ad448414bea96ea0e395fc1b7e10f71f461348eed7635465df8608bec39a1f7cc4f92c84aaeccf6a94383e5537fa9b12ebb34aac068047ec3e54653346f076465bf1005aa1fb8c168c52a872fca8ca8e9a6a522def032a625cafd9a9846a95795fd0b2feb467f9a996b70400b628d4db04b9c036018c9950955d447450b99d8b07f51a519dbc096316c8a4029028de89cd7f312b0939787ddb08f7ceec72421ea9f91dd9e893d1e9bb4d44aa34983f88acf52766ac3bdc5b845b5b8d815ef7c4f77d1191a22a3ba75591439b44083e71249a4455361d7f20550d9e74bd300ac8bf21f1f3b6f20898527cadaa21a56a12ff49d81ca8ca76e1947f997cf3b94170f88526705007f44382b5e540ff8f6f3eb222ec189e1a9d1866494ad957d69910d6f309862e83fbcf2bece833330f8edeb5f9c51d9909e2277f72cae5af6e4334932f48937071d52a1d35c0a4b146e79d6f9a0b2ff84530eec3e2a93bb84ab67f640c25cb40defd960fabda5f2d0ad8cb91f9f0e30230616898779f8c46045c578d20999745bff1f721ade9d97c428a3d1b8c316116cd5fd780fb24e69fdc30a62c9b202c577e0135eb1e4cb52b9820010141476a46e47485230c9ca48d6f6e9ba6cecd202eb00d03c30d0d07df42585b6cc21d6eda8728579a08f3d31272ce556ea38122a19e8961d31a367d5dd7a75c1caab293bfa0a06801324cd01ff40f3d1f3ca4a1d037d15f27feb6390c947fae3ef75d4689bffbaf9541bef90f25bd188496a1e2c8d00aa7b70070b6a54605d935debc4d3663fa3155c98f7fa114e24650a86bcd810354e7122d7d58365963953ad75aeff71532b7369894e9c989255740d9179c69d366cdd03d09d8b57ae6fab58f53a14207f309e718fe3fc6314ebc23369643ec2c74185494ef3cd9013175048c57781a29b6ec4c1adc1d6260e109f16651d9feb4897ae50b1555a43de27fb14cf2a731f082cac6a3168ff99d2716cac01c1880522ac45e4b870acafb2c9c92c56b6c7fc7290166735ff156f21cdc265eaafff99692afe4150714e6c66c6286cef2fb7c0021a5552cfbbc256ebe63edf6d8246043e51e78ba06cf399883b1269c1bf17fc58f91811bf1958502217ac6d40814b03856b94a66b84d80dcd42e5e71ee7dcefa452de345a03f150a2b1329c8d130a7615a5095ad06698cbb27c4c319eda3ff02e474d414f45ab547582d08cc8a1dc02fe3a395d6ea09a155a42c417f3ac03dcc284f56ee6086aa6c8af6e6dfe2b09266263a9ca197f313baae8165cbecc3b35415f8718e1055d972edb45a2e00a0cad6abb7d5caa8cac6da81ee3724a77d1cf7bcafd187d3d517a8dbf6630e55d9d11a65e842aad9cf70423b1742e5d729b5721a5465fbf8d88c5419e27b2daab26f08969b1f6859791032a7189b814563518bc5193454658be94926e4ef2d116c0d6703e58910d4948c60a8cab64b6e793c6b07501060f72e19884a3bf2a5244ec05a9865e19f42557669cf62f91180b84104f86f4d23811cc45d3122013849050b534255f6ae7bec9d95cd20ec4f0741a1b16df0d8aa16eaa8ec058f0d9415a96e9ef4a8cae637ca3e7937515a6a7aecfb2d1189aa6c1b0569b6229d924349280090473308b5485d273d669f258895c3cbf9f8c4ef4522fec657f4e41e87e8c61c79722ce3b205e4c2cf7a8b4a8cd3b47e2c851ba3ef89ca67e20a5dc565032bf906c61fc390313d491aa03f1763f82ee676cf16c1bc76f96866f07bc982dffc1a1d318ea13a30af9d3cca1cd44272f037dea32ff83ca58f5de5662ce633d1244c54015e523ce3c3afc0cdb83e43ab3119636d90ea0bba31e1149ae3993d4306ed5e917f190004da954bb3872988b62b4bf30b53186d5796de10a6106d176747fc938f3e0512e705ad56da2ed38e6f6557da6e9d079da74ca7500efa2479bb0062a76820da631b5fa09abaa5401cd72e46d276c963dd2e6e08dc25d33796cd93b98be5d25df21ebb8b1dbbbb64517a176bc551c0d5277cb5486f5b5903b3c40bbdad14fecb7e38bdad0cedbd7802c7ad1b9baffca4e3561989a17aa4e3d614e9497490e35680e3427d0ac7ad8ffabb0dd571eb4326ec3bd708de0a9d0d66996c9d9492d8e38e0e3bd7c53a3eee5252d91e7293432d4e2df255e7534136eaebb4f275b5bc5baeede72250b9f75f8e50be18d1fcfdf9f0bc73bed4977a397d6e298515485e21bc7f81b9f7d46b9d16dc440ccc08c0de9b0f14cf6fabeeb78e1202ce0a2dd2baea086473b42afdef3a2d332e59b9695489041a0455d94e3ddfad8aeba5c7b7fe2f47785ce0fcc963565e67de46de61f4fe07aab2e36d0992834a2257c4550caa1c9824b061a5d7d1d0fe5d6f2c830c53ce5bccdd6402a2a07a00daf1cb2e29077207630983a376271dcdb059cbb5b7c789b40491de5322dc529ae73772951580a9d6ecd26db98417fcaa2855db2d060e10a339e20482d330a13376115cfc787070421cc150da533972f2572b2a1e38612217d9d267ebe0b6f6f981d74e126fc02178389c1cd96cd9d07caf7c101641da213000e4ca4a178196af82234c02e69df0281b2386f4269bf9f92ab8f32562e800d01843b94ee851ceb6251d6b81c7da995251e56e073626894e7a469f5084c3be61856fcf8f242d9a7ca6d699f82001ac9ea2c1e244196c6d0455d9f54e4a376483de4055f673098765889592971dea47c3ca5bcc4ef18e11eb45ab3d8cb3b177788df8f650952de2235e52d5826e41532d21fc9dc3325f40f7a8ca1eef70778555f5ab00f923367682ac04483e7508418daa6c0f704455b63bec9939f762c3c9abbba3710f3015de8da0d2f6fd80cb68ef093c8522716d675cdf81937bc38d7dac6533f80e0812fcae524682c401af0154654746de430116509297e071081424c37c2070844cb9af3498542826588f709442afd52dc4130416f0748a194c6a814f0a9ab3b940768981a12a3b01760b9443bf361d8725a10faab2190e4370d1c44733d1cbdc0cd44d00418b882ae9547678435ee4659bc86a689f988a9b0c5765efb5cbf9ce8de19cac6886aaecfb9f514ee924cacc275846428c92158098dd4c8c9241361387fcf0c633ecbbe608a732a8caee1b96bad1baa1eaea6cd7ec6d5da8ca26291d5353eb78113e0873fb1917dc58f49d0210c83b3245ebff24ca8a0355d964560c4ab5b5eba0b9e3a00524ff97c2a12abb1c3215c2b284184d6b361927365c80580f684b2dedb946578113d75140cedaa32725fbeaf88d397d3c3de345b00ff720ab831e00d18c3cbda5eb93758cf0cffe77249bb18b3454cf56b29f0a01ecd0e5c4a38f471da63805a9fae605f3eb261604b0661659927efd2944e8ef967989396724ada4ed9bef9406a6a17fa5435e68f9c2c0f53c31c1a0b15fc36fc5982e771c44b388488946fbc5c1c0464a8ef90c78ad1425053d66565523b27502808a84e64e75c7e1656de2a230f2818d181a46bc6cc4cce198d9ff7e1550b6f11bd0a8f37054e5cb09983256b5a0db301a0887a2b06fae08a02db18bdf29b5a528e26b47bce1b510915e2bb51ca41c2f9cb5551e7f85bc197bef5a78f06a4308836a5ed8f2080946887fdcad6b7985aaec2d72302aa96270bf470e3ec9649b55f749ba4e8c7421f8940fa91b86d5ef6777ecfcb6e7b51d5a95970629efbdaf31589b7b2fb76294cee2489f23b8de28aab2e9d4700c98bafa83c1e53afbe90f58dce91dffa0d3670a57f9c9f4a13759d2a69680a04c67cddf4816866d4992c132f4f019420b5630c40bbb33ae87c360cad9b85a59b8f3442913a626d34d7fc990eca1c9f0f994e16e415465c736acefd25b17d846b60a59b4eaf60cbc254047a78e1ca97275a09dd981fdaeafff0bdcd131775095dd2b8e9aff344ba18112c340ea16e00641d5de0c73b93c88ea52ade056250da0c29d7b5475b30b27b128c755d861672f777c61887ba976d85ea013520e6a10b9e61f824c083f0007cd84138adc2adc16889c125f88045a2fb2a0d8850236018836b5006142a7069d3826a8f8eb547b93b80b4ee28ecfd0b23ab3dccb12592ebb863f88061ca8ce18693ba2bec4bd8194b0a9e2ad2bc90e7681d7c338f4e2efd65a03ddc0434155b6184377e763c1a02c21f1b5690abca76553f96c4cd1b4b10cf3e6741b53e1f317277de06709788426780b674ea7ec6aee830db88c79f590ae1a5b6ac0ca466fc005710afd5768620d6d3c05cc7a529c8c7d86ac32342de135da5eefd8832a5e50c8732638e32051e4929d4d9a6e8ea2da0055d9d150975e8623080a1be92b68f12aee69595117872dc483f3b406fd23b785d991b38ec2a1084486b5549173066ca9c4365014d7783844ca51a038156e047516db9a8cf78efac50a7f54cc5ef98cb818b188e13146d29bc87787652029cfe48f62f9fd36c2ffba7f6846cb7619a786038d54e8badc92dcc4ff49420d2a3d587b2953005f10f8c6b887cc34a04798789a3a5d935a83c581adbd17d925380b36061436013adadd5147409693a403830e3ae8405555555555555555555555555555555555f8e08c111d7d9ba44c4ae691471e7934a71bb0ba322599a44c49a7f86e2fa460e38c55cf8e006d70641382f0f604bd04b404a7e132879d121d4562a1f7fb9dd6a93dade15a8e58cf3a196b8a18555f5b8b114b25aa8388a17610fb772c4510b174fb39f59c6287f5b66588f59cafd135b774cb5c2d422c86fa95dd9362ecbbd312c4e247ae0ce136f6ef7d2c402c3eac54b7e71a3bbecc2d3faceee7506bab9b27132f0f2c3e2cccd64f4eb983a92dba302c3d2c6c6f0e95a64f29355c0b0f961d56526c46d9fb8e8f528b0e0b5f7936f4f49a63a99b2587e5aaa5845827e76c133710161cd673082543a4aebcb9d372c3e274e9e4518bcf104beeb852c8383d9ee60735afb09ef27197ac545b61311f6444ad613b693babb0e9e9b94c0715fbf6415b99c2fae33ce523567eedd42a5258e8a9eeb04cc89ac959250a4b1d427ffe1952dcc95f050aebe8bb7dbd8df03dd55a79c2ca5648d9ff33a58cdda93861a11ed51afac56587d4559ab0b8a5e6de418acca9e75698b0587af5880ae9bea4c9952528619dde739a724f8f9e6d5d49c2dac464df1cd13a3b9e2a4858e8d7f3bd3dcdd526849523681b61b9469eacbdc6bacc678bb02a44584af1622fa673956d7d0842084205088b9b993bdd58fbf7430fd950e964a556d8f9bc3d3584fca0202a9c2cd48d9ef27e881919bea470a86cb2d021759a93a74fd6e8d3878a26ab994bbdfbbb28d9fd698113b1874a260b9dd3effb9f933bc89d0b154cd673a4f01175fbfdba6a81f3f392a5aa7255df43dba8358674542c597ff05b6bab1e15a3de3d2a952cc5488f2bf5d273e728671e154a966badeaf9b4d71c6fa3ca24cb69724d21fd4ef694bb22c94a8f21855a3ab68454cb4a240b6df23bbecf552954ac02c9d2d674deb14cfcae0eaa3cb27a1bd2d49e2f26745e52332a8e2c4e462e4f37f74d39f45e0632a5a834b29013b7ff67b7cf3a4f14c688890a23ab752785da619eda3aa4ab48659175f6795d4feb576af328b2961f7acbd6a1c794b926b21a6653dd7d7e3a31459ea282c8da6e84feab5a3aa94ea3a072c86a0d6da67bc61aafbaaf18b2dee263cd18266edec44a21abf563bdacaf9c16379b90e576d16df3f7f976ea5406d9a122c84ab9ff1e43cf13b12606b2523a9ea618a1478c7d0364a5cc54a86153c5a8ed50faa3e2c7524e9b3146cfd0b753d54fb2d2c7da66dfe4b47d73dcfaf858a898905d557a2e11b13dd67199ec9a25c71aea7c153df2584935996de3a7d84bc835b0176a10c505b4810a1e29292da8dcb110335e64f70afb28f78a1deb13c264d9af0e43e6af52c742ce38254d4717b3a9afd0b1d225f798234c6daa7b2a732c65e91137a6ce99da6b458ef58dafdf2be74c94ef54e2584d25754e4bdf14b59baac0b19afae4e63e6da66b4b7582ca1b6e2c76ddd98e7322e33ad6c64ac5cede6e93ffbca30a1bcbed51cf1b6ac9d79f4fafa1c6ca65cc79feb2d486184b038d33d6b7c7479f73131ea7b462c6eaa472db3756efadd957ca580f1df616b12167ffde2b64ac57281d9514724e9121551963addaf6fe578fd843c855c458ea9e8d13f3650d1b56c2588775aa4a8a9c7a8d2d57c0580ed16b7a08fda797b99a07042c786281a4f285175d70b185167ab2c0e20a2baaa0620a29a280e209279a60620925924022932b474431a2082286102208207ef0a1071e76d021071c6eb0e107a9b5047cd08314f060073aa8210738b8010d334491c10635880106a5c10b3390810b2d40f9e7bcb1183c81c10b5cd00216ac40052940c1094c5002128c40048b7599a25427356aee1402107cc0031de0c006560319c0c0ba80052a408109cc20cdbfd961ef5cbb40b15429e4ce4bfe52793a5f9e5898debe7618192596d2c589d59e726acdb5e327debc34b112d3e6f0bda334a5ebbd30b11e7a46477850d2ddefcb122bdd7944caff6c9fdb5f9458ee51db3dc89e5e3aab249673ad765d72a4127b7541e272c45a9490bf537a1ce74364c429828821167353670d153a758cf545882096aaaac38cbc25bf7203b194dbc7de22bf474f643f5c7cb8f4b058bb7a875d5af6a9ea8871e1612d6bcf1aa67a289bf2de6135372fb73a9cc91475c02d2e395c70588be8e9eda4b67e7ddae5869508592f7ac7a5a3587d4a0aee70b1619d93edecb2cd861863e90a5658fabffceab06cceeb5c15d64bd88ff8b9d37bca2d15162a6644fefc0ff1999bc27a5d964e7b6d8b14561f640f696a89b5618902761016282c952ff12f72c53de8a8272c4ced1e728698a8ac991356c2754e09fdb8bfcbd40465c27a7c448c6d6b729bccf107cb12567bc69f34d3a6c6969dc44a58ed5926c74fb5793ac649f0c1820466cb119637a70db14498c78f4b8b11706029c26aa5eaa56fa7b5efbfb410611dd7678de89b532735b70c6125b667e4e5a3080f2a8b105642cea13ffa9a6c119f25080b2df7aa737264dd782d40584d5bab4b7f5052beec2d9d2cb6db8c25d7f0b06e852c9cacd73c65a6769e99366e964d56a6d6f6243fecec284c8b26cba9fbbac6b69d31e56cc964a1e67fde7eab552c9d2d982cd7d0b177e58f8ee739964b9642a7d9a3529429151f23164b2a59dee89351bffe79f6c742c952e835d7a7d20ff66bc832c96a0ca1e7eb7b3a15a74592f59b7a4e53ef386daf9b2592d59efbb27b7d0a157bb340b218fae688f88f393aae9647d6fe71cc39bf7a271d398b230b5f6b7ae7f3dbe1559646564b999039d41ca654550b236b998f1f6cca9e4e62c9b2c8527f947a58b3b428b2d033d6e9b0d345d5a79644d69ee77e4ced796cf1210b22eb29ee748c8dff2db3590e59cf8ff2bde6181ff73d8b218b5dd57bf4fea87cc8682964b5b30d5bd2f39fa84eb310b2bc9d6af99e25775822b70cb29c2be6aab973f6179f09b21a4b85d29572a4d6a5478124292c80acc67833a964d5ef3553cb1fabf928b3962a61ebf694c58f852a5b553dc65a9ed46ee963712785dc7bed2ef33559f858e9c8ac719d6d7eea66d963ad62b74925d6f4476c09098b1e799ce0c8c0728713163bf2094b1d2b7ffdf4f366ea93355ae8582835d4d727d9fb76d4963996532ed97b86fa1ed39b458ed5503e6ffe4f8e33d712071ceb5d3b466de893b733bfe1468aa50d3690126159a3d5580ce1b7ff5d3c681dd3587a7c5f557b9768209f618696b118d929babf93af25e5c858c939a6669ce7e873ef59c6b088a1014b18607cb1d0a66f1fef86e9a5552f96227de81b95e297cefc89a50b2e963acffc9cc707a5e6ef962db458fded9735d4181db6cd2d59acf6d2316397fb9f9c2d092c58a4a4281b2c572c46ece043d6749d63638b15abbfad73eac89e3e3ef760a962a5d275f6daa547df1c42ca86858a136c3e6af692624c9342689162a56bff5e51f939d88f59a258a815a1323be9baa9d7162816eb3b8a257e47e122d69627564a2d912794e8f126528b132b5f1fe7d38a291f7f9626963373d879d04be4de9b8589e54a954bc97135a94c6c5962fd7956cfa96e98d0db6751621d969f5ab293db98492d49ac871b2fa54a98bde8b862639c5828353f56cbec9afb36a689b5c89d9263d7e9ca35856162a96ae4c753aabf4bec6196582f212a3fb69b8e72324689c5cd1972e8b5ee336f864962a5a6eebd7643cdecc720b192caec4cdefcf6b4863962e1ab42ff526beeb0c34835e9c018b1bc15efc3e47f923a758a584a59e73e6a09d37a630c11cbd9e24bfa2af5f84934c47ade5e1ea710761fe45688d50e4aa5925a97b84f530fca09623954080fe2ebc6e8d23140607ec0f8b01e7ba67db2dfdb7f845c48b905a687850c653a2921975a3dd57858bccbdaa5f6b38654720b9c4f5809cc0eeb7df27f9bed9e3b394687c5caf224751822bb420e93030687f59e1b4b9bae9ce16174c34287fb98da86f89bf6bb01c686d5c95cd2e610a1be94baafb0309dc75ce17bbf58613970a9c2ea96dc790835a1c3ee2915962b73f2d7c4baadf92f5358085d7a9b6e59a587ad2f5258ff683d3ddc67dcefbe4461bde641a5c9bced6bec07b94061b147eb9b9e929f74eb9eb0969de78af99d426a4f5f9cb0942bf4fa3757b9a3ef2f4d588ba9ced4656a84fd9209974eaacfe5514ecb09908b1256d2f4defabaf3fd5c6a97242cff73d871acd893c27e17242cb7dc48a1bf7589fe7d39c26aeabb9c9b94b53362232c6dc4c899f2bd7bf5e85204d44984f5da6b23b4bbe918536f08fb828b10164b8a1e5d9b52083d3308cbdbb96596fb68f5390361bdf79fb87142c89dd3b493852f3d6aea12b1e3af39274b99b2f48e73f62a95b54d164b87652377fe970791264bd53e4a5489ae29d693c9fa3c7c1c53759b483b61b2d2696ad931c5d4fb2675c9629ba8927f7a9efcb92d599dc9da6bf7cd3a2dc24ad62a3bc5eadab54aec1e25cbf549aa61bb83da1fef8493ace6e934fed7945e2459bfaab3df1fda44cefb12c96276aef121c67edc9f7381643d84bb9a94be7f089d5e1e59ca394d77cc750731e2c591f51c1f852cb1d2830e93082e8daccea690d53645cc57f58591cb22ab6d22ba76e8b057eafba2c862cae99c478f34b339bf24b2f2d373df88794ad6a7071159c8ce79f9d37a3bcc74c862b4fb88feb57745f4d0b818b25452bf2f257e9d8e551642c48590a5d499d557e1bac5dd41d69fcd96d4f3b3aeda3b410259f8cd3671732db93fbf00b2983e6df5c4f471f78f757899195348b58b1fab4f426d87e9204446678a4b1fab3db2e4c9dfd79de7cec73ae797bb5f226cded0397b2ca48e8c5baea7b3bd4c0fbee192c7ea64085f775346e5c82e782c75dfda5bc5eccf3ca9cb1d6bf538c58c25a67f0f79d770b16321dedd869072aa52b557c75a65fccfe650f2e32ad1719963657b4dbd357b7f9163216eec12a5b356ea39c691929292d2c4058ef58a15b7847c1b7199b97179639dc447d579d173869da8908b1b2a8b4b1bab6c2c66e6fb2ca1bfc77ace1a2b7da787c9b0d96b26554331714963bd6a6ddc842897511d1a7939c30c55c63aaacda9d3dfb47d263ee342c6182bfba8233afd9a899187b888b1f03c3b87d3d9d6d68b2e6148e002c6ca4fb4ec51f384dcb2f48517cbb5cd64e6a7bd3daeb38b2b2e5c1471d9228d71d162b5f6a95de6a7f2e3c14b1689b1e82bf849b615ab9d5bff7b49653b76ef52c5c2d74e9d5b258794f2d4c5858a959095b586e9c71d57a9a8b84cb1d063ed11fdaa7bca18a5f0e112c5d2448d030703112882021511545282350030430e1e0b304071214a001e10e505d66278010a0bef85c666a0810605788025ca93191e1419d80c058000001cc0c73f45595000932106f730d00005700aa66c22000a0cec056f1cb0c9c2220b475115f0fc55aa7dde0005d4f0c20c2d40710106163025392519d0586a682c1000003344a1810498ca83c2688002037b21009628323ca7c1c520430d0450c30c05804114176ac008509922d3498693cc26194d32996430c95c92b12453498692cc24194932916420c93c927124d3488691cc22194532896410c91c92312453488690cc20194132816400c9fc91f123d347868fcc1e193d327964f0c8dc91b1235347868ecc1c1939327164e0c8bc917123d346868dcc1a1935326964d0c89c9131235346868ccc181931326164c0c87c91f122d345868bcc16192d325964b0c85c91b1225345868acc141929325164a0c83c917122d3448689cc12192532496490c81c91312253448688cc10192132416480c8fc90f121d3438687cc0e191d32396470c8dc90b1a1b9426385a60a0d159a29345268a2d040a17942e384a6090d139a25344a6892d020a139426384a6080d119a2128c56c84d000a193869366134d9a4c30692ed9416349530996d150d24cd248d24482dd0d24cd238d238d348c348b28d224d220d21cd218d21402a521a41944902610405633f237670fb3d1d3f447e347d347c347b347a3072237793478347734763475b8d514a5a1838a660e399a381a389a371a37da606329d4f413b3f7e3ad2ed768d468d268d068ce68cc68ca20a319a311a309a301a3f9a2f1c2074d17db70b145a3459345834573456345534543050dcd1452345134120d14cd13dada38d134d130d12c318346892609249a238c688a6888688610a209423d51a20142a5687ef0a1071e7658db8eb77fadacd121071c6e584063830130574800c60a5558ea70d93395daa3de1e2a4c0123054c143050c03c01e3044c13304cc02c01938485fead71b2c3d4cbae3148c01c0163044c1116eabfa4cb9efac3570d4304cc103042c004010384d592a7ee4f7dbcccdd309dac576c959f7bc5d9df8ce14411911f72e56c295136d12493c5493145d4cc1d1e184c2eb10453495f00430966128c2491682248308f601c598f536f2ba5eaa57a3ea6910360185989bd4f881b65faf2a74516ea534c5d76ccc7f98aacd689879d93c9125948a94ec8fbd9fab5941059aa117d52773471bdd9210b717b28b57d8450b3b386acd614b6e47f6dee5e9d42967a7e0c69be94dc31770859cf51faaefb6be49d7c909556b9668abd558cad2bc8422e35a5a3e4866adb05b2f0203d8f35c79e8a9e184056e7a2938f1e913584ad61c0fcb1dc51093ff7343f8e9d291b183f307d60f858cb4a75d91ff64e4a658a1b983df4c88300183c162e6b4fc9ed732d39d53bd6e3d39f58ffe4c9d38db163f9e1f56fc725e4faad62ea588f2c2577106aa92af360e858dcdbae714bd6e4beb5933cc772f75fd50f21faf71c16829163a5f397af90b59e44e761e258ebc8ee25ae3be82533068ec5daa6e32d256eee24b63716aac7af0e3abe7d1abd38306eace4dc289533b329d4fc553de3d6d8393d4831cd03c3c6528d1efbf24bca9d9707b3c6426e2775720e21e5741fa3c652a9946bea61c6c71669364c1aeb91f55b3bec8a1b3f1a9833d20a3066acd78cc7a9b7eb7f4e524c196bd151e91dfec3d221c652522c70d400cec090b1389f424c8e111ee6148eb1d86b57af959d31622ca6fff97cfd39f2861ac64ae59e72bac7d43396b211c180b11cadcb74578c2c9da726982f16e743a6daaf7ed2e4af05ce18667892f9c48bb5af91d37b6e3363ca305dac87cacaa7911da5c715868b85b0f3bd64668af9694fc26cb11aab4647ab5a3baf3c69b194db510f72d5ef8ab52c5626c5ab32997b4e0d252c9672cf8bae0c1de53b0773c5fa65e8bdf7b9d702672f148c15ebac73eda073cb5a539a55acd3103bfa7cf4f25b15150b553f54af3433954b8a990223c5623de97b9463a89d1fa3c000068a852d1d6ca70e363c8e7962b586ada8b3665a21822008821042081118f24a6be315402010080a07c441b15830cd6304f9071340014302b140240a0a03026190200a850161401806611806411804612004e3889246d1baedef3cda588925709317206b7799f9cbaa82f46bd3ae39967e7639b1c633deb82d6d905b503fe9eb05d0a858a95623b8a74054a589e393f4167062a70b7335d7edd073ff4c3dfbf89bb4b42ad6659ca28eaab42f402956cbed1183eb666da571654c44836ac72bff7b09af4b9c760bc27517e9d90b4556dbb0388fd5a6379d24115595e48cb826351b81a6ad92e06ed172a6afa608a1594b588f25b2c8ab59b49a1023ac8becfd450cb3e0e2691b909fa91aea9f4f4c04f515e041bb353ab60020585354874839aa555561988c49adab02231614ae5c587b4142eb2a0a0206dd31c4d0dde0e2c01f7b6f95bf365c3b9b27ed7a7ec4e60857aea5337dea57a7f0514c65bcaa5fc0f2e0d986b5e6f02c4759a57910383bb5bc169a797f7727f47a19dfb8e2d521144dda659079799bd7ab322653310fb6d29fa1e26fb25c29ed38b6556cb38069da62a805f0cb45faa0605ddd8ca9057358391f978d7ca53d2cae38985a9acc5124a5ab7775068a117ce643789b43d2db09f45137f3e6a7d581dab8d64607452dd26fce922892aecc6ab0dae4aa627120e2b93450bd005239183827cd52a39c639d9c8973a6f438e7a805e3c80d5e6685a90b9db49509583f8d97f254c9f6b68bf65d1addf4e884d8566effa285523e57a0f1b38e57413ad0305915c053ba58596d545d14a018361b08a42e0d0b4f7edfc80cf4e6ed2c2c897db9e905500e810041f23cba202be1748036394d6ee4dd4f3e1a502fcdf9942522d4133145629605982bea46eca38ab4682e101a8ebae5f50cc29080ba2005f5e545613d4c4714f874a0755ca638810f19d8a05aa728d7b9c95c27d97c87cb8ed9e1fa7168469b2a98cdeb162e49de11ea13bfde41b928481a952db6c3c2a6bd4a92c4fdd7bd0c44ac6dff8ad4c083dd404d6c6768d82fbd3d2bcba0aa699442a05a94fbb4cbed3daf11636763631744c21d5544d76f9eca5ce0c8eee5ee2513acb2d3be6b45bb2361b80e798cb3cb0071f5b072d4b38b9213fc61f4faf832de5719ea536cf7ebf9d4c427e6eeb3beede226a4c43c46b2b8b7af10be3e660cde4d3f062f2b4206ef3d2393c1bba823a1410ba27ee57b0cbc224b06de615d06de6502f0df77231e00ed4b6aa3361af45d5b568fa2cd08f25e69e05d2ab494ab12f0debd9d25157bf8859ff09a1a51ae2900bc4e2f5c5e358f0d8cbd99d8f77cb5461dff36fbe3ef310e37d4637c7d9ceb373d385cba77cae592f58474ab572fb3f2c5b28f908e5f1f7324eff27d9277ed3cecc5d4a9e3b56fd7424eb8572fd2b886173d6eaff3eebedee22e57816bb2066bb1acbbaf0243bacbe785dd9d731dce07d546189737d96b4651ccd46abe8d2d81846c7ac6ac45e8c3a3e4bee19b49a756bcdbedde6c9feb10b6ccea8091c6326f4d6806d3a7a31d6e21c0173fa6efb5df52146da5e145995e94f23bdb29a63113d31635a257699f80e5629c30c2ac3377383eef08f699472ba6cab2c04c66b9844476455dd2b61306230862d8efa5d7298552e85c6bbe0e6119e42732028791739d1482aeb1807dfb98c3dfb9f35b3bfa728e766691754ea5c3d441697830b9afd0520cba6e0b6e68397e35aeb984958aba569b70fcc7657b2076a3f87fcbeb76545f318a01ae79c91917b4be728a1e9f6bbc2f911319cff98805cf6842c38fbb128589af5fca89eaa5ab91f20bd7f85bbb7514fcf557da8d7f46140d6547fc67b39d820aa718df035ab9c4df9e4004cdfb26e0046e9896e0d2add32b3dfcd56939facd4ec52c7171dafe9dcb7f4a9bc3c5c9db10367b535ddd721c998b379b1c98320046b8b6c2ce9caf239bfeccded48135f1c57b1bde55def4c54cc06502885f74ee25b4e67f030d584847628e9b28947073ca70f4221652ccb7212d3685ffbd69a969e6f7dffb90189bbbffdeb5d8b4cec77cad21deadd050dd9a3eb8be10a8b4ff5240b9d2aceea757abdadfed5b409b2089a41a4910de3da0f8097317bcb1f01e354dd45bff45ac1969eae6cd6415b7aee53ed50ed829644a0b115cb206ebc96fa3f6baee45a36c7b4d573504ac789209ebd55e4141b5e5ac17ee2ae37dac17143153338fad47e0f3f6ec4afdcfe36e480bf9d301b3e6ef1470e8bba041b2bb8b940326db46d91735a77a56e45437255bdee92de94c9b39ed3fc7f6e3754d4269f2f743e49c2df79bcab47f5e9074438dd2a517d2d1ddaac9d41417dc5ace062c655d14a788e832f60294abbbea672140d4fc83e9e2226491b4a33197d2c09cf315dc3c1b2d086b28439c58c0a46ceddb87e0a690d6730021582837ef7427c28b22b91af5343a7b796ca1b80030bfae350887c630bda458331cba902d5c778460a6f42009ccb1fdf677a670817955041138b5a415e1bb1e625efd35c1327f5b17feaa2ef01611017d7c3e392c321c700e81a162039ca192d83772db28e00777de99370ee86dc37bd7ddce38abd4b78e2678af352837f54d4844f06cac8394d527f8be33ef0440f495ce0b0ca80de07c4e5c59c79a18b0c55da5c235cfad7db28055babdbfe130b6494e2efad234b88d73f3670135cb88975370a45c784bea6c9cdc5c5bef6f971c05ef4a0483b56383fc9208d676566fd882952c87e2762700b83fe3cf4fabd135ab72f89a2fb58e158cfd186dc0b2c91b52bb53b2f354be235f339a038c6f7ef3d43cdeac98c86e2ce01aac4f8a4b7dda437df48ffaf5af066f6dd24bbdfe7d1fe6510019a5b23b7b1305b283e860a89e13ff1ce3d78bc972e5db9ddcba1ccdd9067232e58dd17fa1c5e9d260570e7868baed76e93943e119b0b6d007ece845c182b4b729f2059ae869581818dab05728dd700d18e8ba530fbd25f1899d9d3b89bd391a978b1a44802f50165ed7f7574c048925e3e12fc117e6500c3001e6a1965d4a237a40b5cba3c90f3719c6a65b1a6d63abf09abb187e89afcfb418cc591770594122dcd71b559fe0e768eb0206de6c0dca6b845fa41e2230312774a5d616f0ad8559319440f5e6cac75dced40bd5eab1d38e5e57bac6c982cfe8cc9541103c18d4db805608980ab6be1d9a57937f2b9c589905f153798015d547ef1c4f68111000baa98d215c9426197976c5ac9ef0c567429d028c95b25541991de068c01b27a9098bf9d85c7cc7654e02036429346d5e959f3b3ed38385ab6aab565aab054fb42f4caff4a520d71bf0daeaf5cc52b8eeade352e0f0445c7825aad3771f9f3a3d313bf3a44085bfade1b89044490119fbc7df14df69287fd30c09699ecddd946d4f8a8f507dee7a8b3d8ba25ab44267f26c82f2d8f22f77fb88baaa565fa0508d71b4b26c702ae25a2bca542611ae26f8f63a16599c3421b9081648d6d893d5d1f0e3cddcb90f4bd256f21a2b7aba52e341ba007b4adbb052c7931182040575681c4ec6ffaf1116baa1a051d3980241a5939911f26e0365c0f51084720f79be5ac428a9d6c6a3acc57d2998e1c32da2ff14fc0e6e027e11804a69357a468fc0cc7be32754904f151ef2aeb4127f7e9ba9db383a78a88108aa0960331f73737ba4448c3ee79379deec80f38d21e876bf06861420cbddc85b484d3733debe8ce882dbd487763fdf6074adc93403742a647463776dbc8a6f35f3ddd66f6d5ec2cda92b28607f12ba8fdb651a56b8c8eb9cd65ecdd2103e0fb9bd175d3ed8d882b1f09950aa69f01adf78a2752a06dc51de4eb824aad39484c2df82952f78c3927f94a39b8233d786b4705b52b1298e3aef9d35c4f89549e6b2220020ede1b33a8d2798776a01c0d151bb3c4c5854bdb7c3a0ce6bc8e7b8b024330209e16458bdea687e7cc98619d2e9b56251d31babe2c3de40f77127d68766c0c585e346c60c796a2e52863c563b0571500bfa5ff1732452b3077473700e110011b4ad0beefa423fdbcaefbbe89dbecbe3244b33789926dcb895b0157dc5a10d8c7d8598a0ea8a67f48a6088b70a9c9ba1fbbe03cedbc97e4f87f7978470b2df296a94b37d8bdbab04d77d97cafe108f5a66cee5bad9a96ced509e3ba400cac007b4b93560a112db1d7a1d752a05078b1bd1630b8d4237cfef15295f79eeb7e05c32906bec5cf5e921eba1a3e16a0819fb2aa8b1bd5abe28b605e7c74c5613542f8a7c13ee918787ceae448d235e542be8a657560699122f97824211c178c0cb19dbe9ba7106c90c483c22780753e8716cfac7e590357e357ea856c91094bc606707b3825847a985341fbdde9cb54ea7caca3911247375266a9e36db45ba4d2aafac468e71e117b4d425500f3ad571395b9ff6dd15bc2ebc2efa183c22fe3ca4dfd7cfe220f257fc113efc117026b2267029315630fd9e1ffe23f217a4c610faeb875bb1abfae4c9483dc68e3112b4c6a017f3eaafb0c29abaa7e708aa8c7bc7ab84a0848f58859b489014152b126a922e14c531a1ef575437fa65fdaebdaacbe7a8ae5745f7d59444c8ee50211ed74971083a77a46ecd92e73f001a0b72e937fab1481fbc4595e61aac3e2f1f280db9068b9a8b9cc1bae2fe2fd0328f5c860eaab97d8318163f953b5a7d7c1d27c0a449cca6a154c86527092f4b5f4057cda8dd4c0cb2eb33c20c456459df051c87031af0161d0ca80ec4cb341305bc5c1df4ed20ac09cd5798ee90f6b3924566d06ce9fd0665b517f79e05c4fc0b837f355b9ce3b6f8c41922d9d24e3f554c6d3f3e67d70749d5fd948c52ed6bfe329b32cc832a0255776b8ffdb11286da70d93d1ab188ea263f5a3bf56e5eaf5fb61f2b4aab11d23ba43a8295f63023e6fecc0f88ed776d4ab5783dc1fad1d5be85eac5c00190ce2a69f925ad9ebdb3bdd8fcd052214d73e420ef0028c3561ba1796e3432e44dd65b4b11fe80ea1f1e85e6c36e25fdf6b311f5ea46e8104801ba3291c81efc1e86884645d87bcccc66dfaf65d19c77c878dd3b488c99040ead636b8cae4fdf517e4607250c9f624326f37d633b2af0a1ae01123dbaca8eaac5b5d18659db0bd0b5985f2dc8e09451b7e960cb1aec0f81f79c2a8f326d81d1adde7f7d71d501031de374689b996163e10b243b78df36e0e395006bc183ae7e93c2bc099985ed32f013d65e4c414ea58f35625e44823a3e0153a02640d51878804dee6a04c689da6449ad0311f005fcf95162d19ff665a4475dc9126e57218f9cae0b178c560d0065747506f6b997ea72c09b2c503be6cf8b4813d05f1b5fb428ff1aca4595c4658838ba61f728d577055c4c472d3d8211d6f581b5e4e6c167ef37b299ff37745fc7208e6d644615edce5493f68b3e634280ecde9da3dc5ce4da4aa7001b6b00afa4999fcb499b7f6dd94e4836d8b9070c116d2c2b799c61804b9ee399501c62cc27565b00530e54119a5de57581aee0a8a2ed368ed4efee395cfc905fa0cc48840df1d44a173a5e160b06bac3f7d6b7035cf6a4e236bc11203908f9bc160070471cec16062fe32d551bd1a50b9e2689f58acd9b097b818db81646fd11e4b4076ea75fced93a659cdc708bd59f056448228c6d01b6b5addd2ad2e966138559afc8e24414b1a0240113e18c9a485da789c42a49acae175e5a9ab8faccda2dca729b88830f0f21c36d4b154247fbc222c6868341168d0a3f40cfbe96004ad2c33630d52a99a30e02b0281cccc0b955d2ab52d63889fd8df28285083f44246618139e0d0e267dbe76a5b678a0602186e83942d0510b620c1c0ce18cad90c60acee8b5d5f1665b7946b2f4dcc4aa72b08d8683a14e06efd2de06dbc1ae9a1b0bf48816017e83e56f0eeba538a625aeb1f8062364f494c1c4c8a4a4aeea0de6dd58521a1369ceb10f1d30c149be5947159b3e68a20803e1031bb061ccc1973d617b99161a93cc1c4684807fd5b5b509475c2049079a5287d669dadc3ed73e2bf19e5ca26efb4e0660660a8a78e725dc6e6711f33ea5d1bbaf188c04a9473eb99dbe6fe3fd712f205b3552d62fc61e523c7191ce672444b803dc5633eafacd9f753e8696fc8b64881243e4ca677e81adbd1e45aa22443acf282d884cefce931dd105a80f900b928ea6155dde8309c2239aacb56c2ead6b3fa35df340877d8bd1e2e765739afc19ce0af660dc6e4e987af1bd606cd6bc73ec330d878ae796ce868843e3ce5543d04ba12d521cdcfc1736b5143dd5c0da528a5c48375834a2e77433a84944cebeb2057bba06247ffe5777262e330274d1ee043f2f537bf7faf9806b0a070f6a6cf75698a94f306e3cca64348f91b7834806dd65f325830c2e057419202d3f4e02ed9ec5d6a892fa178325fcace44a1fd3df84dd2cdf810c67e43aa2dd095ca0ed8e0bb468dd99fafb18b420f337e687874eb9403bc2380b83e6023d6825e899454de10ca504878ba24cd2f4dbf0ca6408143d0894af14ee99f1dacd17546bc143f0ae4129338c50f8313a39054266771e80f97e3131e1bf1e540e81f2096807f7357a6af7c44a0609783dfcf32c1a4817e8e4ae8649ce28c4fb6788f8daa3342246f0181d074c000008010100fcff3910024c0000088d0100fcff3910024c000008080100fcff3910024c000008020100fcff3910024c000008030100fcff3910024c000008060100fcff391002ec8f005aa934233b10b036393030096b6e545dd73846f00e6b1f04a87b3088ddda4eac1129e313a2cccce4cd0c88bf3d3d9ae034d9b22222e40123fba89aac8fb14d065b023d020202f01454083c0581b21406664b2a982d29c16c690dcc96ae80d9121b10c2072280102e00ab50093a4961029ea484014f52d68027297ce0498a24f00404044f4013c013d08427202278020a034f4047f004f443131b98354101b3263a306bb203b3263d60d6a408cc585e60c6820166ac0e33d607333c3bc08cd503cc5844c08cf506662c2a60c6f2a2881298158902333053541766aa1760a67af3cdc0ecb381d9df03b39402598a0698a5d0c02c150766293260961a0466aa06bee081d9173d300b65cd942e77ba6c01b32e6d60d66507031c40810f98a1d008ccb800c18c0b0430e38261c6e50b15588508099811f90033a20f665dca8019510b665d8e20844010c203a640080fe088ec7044297027c00180883bc18a1127a38d8448b022d45a197923dd0ac1f5b95e47fccb98a3a1566ae5a5565e08af97aba5e24576b82d6ab82d5eb82d42b90f844243b98ed0502603a1d01097833813e2785a8933e106088586baf75e976aad58ff23a9bcce1b03392d7db47c013f2834e4715a362834c4ea2da4cd65c184cb5287cb4286cbc27158f27058dc7058c2705c231c5787e3d2709c97121269e91258dde72189e9babb02cae7621d759fcbf5e2aed8111af2b82b6aa0d0d0d7f24657bc7cde8ab5e2ae04412834f4b9923812f024ad9070f0ddf7721df9174742980f392b7da0e7f99691abb7f4abbb017256d220f5ee73b13cce4a90d7b5569de7b95f1d7564b45107b911e6c0322fd7e7ad542ec88d5061c76269de31e48628e93eeec56c5787063774861b4a811b0ae230161cfe382c00b7e5e13616b7556e83181184b0057862c00108e10c90bb47c4e0e515ac6f237928140a75c78d6c37d79def2d564d75e5d646d69a4a6de35df39af7955fd5959a6523637d6fdf7ee35fa78e927b96f73430712ab97a6ba56427d35ba5ad54d33ff28e6964f9d50a5e8cebe50585921ecb77975137e54f283f6be41ba9a4baf33eef167def9af68e25a3505e7f69a5ee7fd448038d339acc28838c31f2e6bffdbd6a5bff54efcdbb322f6fe44a7d2d975195d3166d5a981f31f295757e1b7bac94dfdd574ab60e9d30c0f8c28b2eb898b38516596071851c2baaa082698a3852c08922fba969b56a29f9f4f5f66d42f184134d30f1660925dcb4596293041247185104116b865023441040a4f9c1871f343f677ae061071d723053868c52528eb86a7ad378adb775db5b75e5f63f24ec7d2f9fd472f1edf57914e9f3e60b872357cb883546cc4a95fabef3ad6fe86ca8210c0d33c81043eed852fee38c367e8977545df9d22ccd3d295f5bbc2df5f5ad689bdaad6fa965e77577393796b356ef31a65fd3ac16b76b65bf954b7ea308196bd2ce4b63e436e249374d729f84022a04103ef0a0030e36d020030c2eb0a002210a26902002092098be7bf92417f7afae9363343b8fb8f7ee030f54b9c0810622a0c240d0021b2820bbdfa614ea0001d9b53fa08a0105c82ee56275a9d62a9572b1aa102054a6e31b0cc01480197b026832024333e74eb6e50eccbe200c0ac0d0cc8983412c033d11667a32ccf48881102640801c3b30938307cce4f081991c452084044008a79c890333a5006046070e408509c28c09029831610033a61160c60406664c624e4177029c6fea2bfd917f3bb7ff82427975c6c99bae3e4a3f37ebfb9fd3fbcff5020a25059c28a07822cb2ee326bdae1ac6d246e944c652b352dbaaaba5b6528c359175d491cbbb79ccb5bf7f6522732d37aaaf97bd62dfabec3ccf5bfe7f571cec4dd634bbb73963d7916f73db2532d695c7adfab935acb5b88f8e348db30da644ee784f7d374ff976ed8cd74dc65d5b1f23e5126b335edb26ff1ae7ddf352baef76b1be74296bcdde3fb9bc35b2c9ffde68b78fb54ab7ecff26912397bc6b986f57d3748cdb179541a150a8975f95f9569d3eea2dfd4a6124b023f2fd77ee7eb5af37ce1fbf37b32aea2d2c1e0bb37bff3b23b29cfa6ef46ebea3ae122ba2ceaba59c7872faef0a33741e232277add1cd57ac4d8cbfad76ab6b32b5925acea3ad91cbf96be7d521d408110406049606fb01f30143839d1945945040f9c4934eb2efb4dbdffddd9a567f9d9c6ca2492698e4efabb4326e71de5f759d9758520925934812491f1c7f2079245bbd2d95136f5ad6e97d2c24fd7def3c6bafbc96f73ad5b7529a733ad208238b289248b6d3febe71fff3726c3522872cf163c84f213f840c2248207c00f9c38f3d7df0b1871e3df2c883c71d76d441c71c72e08923d379b1fcd1c6f8b1ac51f39eee3a6fb4fa5e3ac952d50f1c994bacedec1bdffde3e59485a4821c3f6f64bb61b935f7946b714b1c7cf771eb8d5660be96febc964b0b0ae50388e43e35be1ae57b6fad564c5b2badd272488eb6d2baf9c875c43c6269489676736e7fdfa4e59bdd3637582179535fadd677eae835cb3542f2967a9bf86b5a6bad5e3e4f186413244baaef46a9e594fa3aebdc02e193aba5dc7eaebdc75cd37ead9c182079ab528bb4cfbee9ddd3cf3f72b5f263bb456b71ddf08d266c9ddcfcc876bb14dbddfbf62b955deee923f3a9fdfe2f9e37d2d939b67ceca1478ffcf9dd176b337ecbf7e5dba67fa7bdfb49e3c65ffb79b216efbddaa6efbe5ff2aa15e19135b7d7feb8fd767ddff4fa94fe8a3c961fa36177d851071d19477df5a79ae6f1ca49ad0b2894ebe5cdb45c2d14ca08a92583c0e690030f16070607f606760773036b0363c30eb606a606960686067646936646a6dceadfadffb46fffe35946b674467af9f593f2bfa527236f8cf5a4585f7b55577a5d99ddd139468eb3df89ff4639fedad55675abf4fc15234f0dc7ada3ded6fbcef57596d6c95d52eeb56e356fb7c69debebb84fda66178c4ee6bd4afdef7627575de9cdacbc96eba5a4491c061859ea2d63941e7b6cb9d7e2175e7441c4053607db420b2c0b2c32f553ff7d71fc1ce3ad51ec0a4c4eee1ad55bd4fc7abde5af347e484560565491b9de5dbbd26fbaf6d5ebe59358f0a996fe5274e1605464cc35dd7eebbc777d6ff5fe67614c0b49a5e55b75242c2814d3145906834ba8924aa934c6909111111149498603d20a100441408ac22048114304b90f12609048204b410cc4300cc3300882200882200882104208218410832c83ee4cd266da5948a4dc3d1d124386851a6e92e070cde0ba8c13f9eb1fd0d2d635558fed20a117641624ee759679dcf18127adac4b4ff22fc8a3207d5df3ec8ff90363ada5d8474e4dfc90c876ac5268346e1e313666a08f23ff5021ee04051b90f08f2d7c19204ed56dafabca5f1be023d3e4d269c2a8b216d9464e93ea66c9100552354e8b2c52e49d4f2dc462a0648cf1d7758b8c9d094be5d8c8c295af5d259aaa2b1eba4515a12e5cc415ca9d938644dcaae1adef8f0bad9ef8c26feca6450f3fba0fbad5374c48a14bc4b9194990bd88f342d7ac7026ab68dbb91f74e5dc8073f38ef4826db9ec9296bbf4c2f91f4fb137b9e70042d3e95553346ccac7101792f0f411ca52f847cc03a7bbad3a1a2fc4155d701c62fd3f1d98110de7ee650d93e8309bb647a96bf072bceef1a005f9c8f513c0898f690fddf47ae8cde84d3f1af6f5cc8bee903cec677ea83bfc724b04ad930375bb35577cbad2ff81dbf2049730b9a8824335f91955e3f53772e4492a448edb838ceea11bf383ae585dd8c47f8aa673552d70ccb9768b50fff0736982465843fe2f47838fefdff485c4eee74b3a5dfec3c6e005b3b027f98792d64f77ad0fdfe5c4e0f22388879d8af87087b0b1b5f5461e07d2c3a17865e590e78579ce9635ebf0760b154e9a8ab3912e3b3baaee628d92c85e9d571f3c73d4bd873d34b57f799dbabd84eebd6b98f6d7423d95e0161500cad3abf52d6652efbad7c5db3d360757e15a70bd1e9dacb49a614e3b8913f1273625ad2fb485e580e5bfe1fc9cc915100bfe4a089e0cfeeeeaa240bb4db71407801fbcffa41c38cfe9b69d31f01294dc5dc0f9ade5b6ddfca0095852c8ffc873ba62ce9b3192710ab62247383cf5d257ddf38aa8214fdb8065d7e1f6c5c7ef5a970042ef6d14803c6a20fa856a54c6cd8f775e55c076a1c483531b86272969a0bd973d815ee65e1ff841cce31c794262a957cffa3e1b27729197f75c33c98a4103dfd7006ec8ae3d893d74a623b715232048817ea2e9d3b9e4b47a6e42970cce23a1757527f62c9655461c61f1fa1eaeb2f8b707e8d3fed6c7554b05090e1a7a7a157bede1d85ed1114a6fa2d72263b9ee535bf5aced3e2a05cb70e2db6ac2d80cecf4e3b9afba90f45660d60e5c3cfaed4c7e1a5be6509abcd523565706067f4d378934471754337a25a991828c9ed79ee76e0ce7ebfbf0b2b8f666cadb02b64575f3d0136a8925ce1f053650ba1ebf4c2b3ec2d340a0142176706a961924435a3c6b916e5848d16f82bb02074b8f2cf780179700057c4941c98e403bd818e418ae3d7b8bfb5bd7245f193cc26ec577a93e80d5dfcd8eef29ebd6ea0cc15d553974f188e110b9c2b72b40186e85f98c7f5f0ddc1a0c5b871a534f34ea5421615d2caaa42b57b69d4e417493190cef339007c0dc7b0525a798171a041edd27b202944d293042375c302d28a8b0112899654b4220832463c55e142ae492d2bd7055e9c6ef89a18e5c8167a0034c4ba8929e6432831b373cbb9009397116409cb98fd5c8bf8d66482f982e6b87bbe8cdd5722ec05b34392dedfd8f5a70bbe25082cc189dffa9fc6038fd3faff931d5bde16b41b2dd60b9a3f853e1f508ffe4de71c3db847c1b15f4ee2431ca8a5430e5eda8742ac8f777d7755b7c6c17c25d7e73d067e3e12cdd39fd070a94cf072238a5615d307eaf3f036c322587cc086ce9b706763daae108956bbac6a9bf6fce8a0399331f06169c88f97de8a390cb27095ad49b683626841aee053dd2f775327cc425bfd1d4f0ea4a207d34015be67674a5892ed503f307ec563d96c970ab72ace3afc749fd3e52774dbdf00b1d6c97a3c7ad0b42c605d96a72a5fe6f594c5216da3e09be9f7afc8e74a2efadcae30dbb558357a3006420f50f8d511244aaa00e1916ab1f863f118f050819471a3c79252a5ff1945f3cf5bd484ca59b37c4382772a20441e0c499c826190469886583e1376485e56d600d8667e0468c02dbee8b751739c3e711898006c36f5a119995a165f58faab91e8630e17aeb3f52e4189518232340b9850db1b0b5661b60de4b06be76385f9468b4409efcbff0ca748757f8a7656bff94cabcdad96f864731ec00fce00b879aa1f401c315580d7b880d56cb204ec973e90cf5fda4e7657a6a720680908b15fd73208c4e0420e085d24945cab086e57b886f26187e4204e0ff0a5eec58f23857ffbf508a673a8ddd34373140f617de94ffbdca05bce21d8653613260d310253c52e272f995b19a04a01f1a569e3e1e978d83693b2bff8001fa7c2c7fe04083ee9d71b23ea3ac5ce5358a3c793a14ca6b5640ee59bedf6e76da760630b6700088e5c1362a2fd5c06ae5e9b2fbbd9ee5f516fdea1b80720993b195c7d20d9210fb64e63ff2be627be15c6309534fe67ffe5789b4bc6f230c2f9c2c6ac71a0c258efcf230b304048961b8b23c0cb5dcccb3c9e13fb9ea91e1ddd0ab94ec9bfd22ec82cc2abbf085fbd77a86e537b729094cc2299427403b5f78321fae4c69e14720a5f219c80851bb6ce357225dc0771e170eb74426a05a0c5a00862372f279afb9e034c2d9a997d3b4028d3ecb9e98ad21ec7454f4084acde652fe4e59f64e6c362eadfdf512b75a7e7109ef931f47c3de0d214809767b2eb974c9eea42520f8046479103f90e1bd2f4a456fbbc7de33e85bb0525c8d5fe83b8f950127f6b8e5bb7fbca787f5e553a9d1b3334b5f164d863d6704be04c88f07d3736f71439a9d81dc5b2c74ff3da9df50dece01cbeebb321d6361fcf95b396cb94e4c06d559bf2c4ae4efe2cf0375289d4b2ff26a50b8366e7096f1899df9293d25cfc8899ff33d5927bb0d86d7051af6facba22ece69860744827143800da89fd84136ef3688426c894e7f8abd6e3a46558d3910f63d9e6884073fb633b921db74838b40da8381f35d3eadf44e041ffe0ef7b0c382e8469f4e5eee87954a186ffc51c4bdb6a7f8b8d6b0c45f49db53df5be6c5de9cadda010ec19bd6fd03c826203bffd6cce50fb2c3e82b2e9174155936ac3fb1fe20e4858e9e4acfbd82b70010665c150394bdb85e4bfca5cafdb243313cc4161bbbe3a00f8769b3c2823c84b37cd10ba04ed3b90cb2d1a463de071bec76e2937d467e1a67e08938474f0d67350b77c8360bbff105ebc9a5bc4c9c43cbc46139849813a16a132f1f097be063b0b1999800d0b356311115c401facb02783d50f024c301f3ffffffffff5312d565fbfb4b47d1dfdac576538944c8949292e79cf9301827151b5aca94529229b2043a085dad5000000040db841082559f070a070c076b5fb5f6a392b55781bf0dc771a3a46da820c70d1634efe891d76614e3a23523846ce0e0efc1c3060b7078a1d47abce07be4d0514305396ea07bd79103f30ec91aad35aafc17e1516a87a4cbd18eede25a455f4101a40e091d333b67b974486ff6142ec5669d28cf1cd2aac34375d436da43a664ed8c1c12ab9a2df44be334bebe001287c4066d2b74a94ea3ec028774d295f7717c57b56c95ac0e40de90169a658ade2a43e6cadd90f6d520f6f5de5ad4bc6461b0a3078fef1ca9760069432aac0a525a969ac64c16d858fc386ca07d60f1635183460f2f404042b2e359b083b978d7110292d32bf600c286a487cce6f25db5cf776b4805ad477f8eab3c01881a9232f25c088bca6ef5260dc99c1d5b6994ddb94b962c1e1a52daa31965b06fddb5bcf13186cf89780b326648cb47f3cc542ac4b6b20c49d752cbdcdeacd2dce78c177b00214352ebad8f911f5350b99b5da624e223b271ae41c490fcd5a1a93daa1d17526148a89c826cb5f12ea5200586e4dbb9525115faa29d67995a807c21b93aadd224beffb93b2a807821f121ecc2c596afbeaa2e242ca8e7a7bfcd9bd903e14262d568adcca777297c5b487887547e6339b868500b497de21f3a868fc9e565a465a96ad4da671a9a9391d4e6e1624446b390da4eab854c95c260470f5d3f028385b4905a174486f071d1af900eb296b28cb7bcfc151308102ba435637ecba72e7fcb2a24b3538ebd90275bd9a4b1c5066ad0d8028b0d9090502131eea15b89ca66eeae64ed7b3c8e779d42e2854ef2b6a32bcc23cdff3540630b2c68909090904821993acc7585ef48a1e500481412ab6c652eb80a52bfc52cfc5f03c676e8b0e1ff0b0d0a89172953abcf52d4a8af14e468ce2e3f27a46310759a47bceeb35ab2f63bba38c3a198c78d0c6c69423a6ad3cda4f2317c5d9890ca9e3355bce7a815b34b489e5c5ca9f45e9dcf77811a2424364c09e99454cf663611162d658c847bdad59ac55810ba029284846cf94ef7da5aa7a82121691f2d66fe19652e2fc811922aa5acbf7c5259fb3142c2cfd267549f374fab22245bbc738cbbefced102428464dcfbeec8fcd0a8d32124c4459d82adb8ff785708699dccd57e75709d71d312012a4f000942d275653659d8b8e12210d272be35caedb8949af383b4cb8dcccb5156d417f741e22c0a4fb2ead9bfb91e2455d5955fdc20a35c8d0709ffeff429e666e696ee20b17d16e4861b911be53380e820f5e241458f5cd59add1ca475ab8e1bfa418ee81a448c74a9caba0629b615833848a68f8fc7ca722b7f2b8c7467a67b5dd39c3562301242ab78ab958bd5a1463748abdc9cb5f46ea1e13c63807c9172514db985a9b9b61c1b24e5abcd1f54ec17ad550dd252e38a907badc772a9ad486668912e9a2344636745725fbccaa82e6bed921fab487a909d31a85695b37d5491aeb839251d7da1f0918a848c32d367ba28f4594ac91a175f9ecfd2ecf11449957587780d2bc38bde0573614c9114732f7f418bdf4bb114a90b7e1e84a61c2ad3fe20453ae70ccfd621e557dc3f469114af95852b173adfca1fa248e7efec8cd0d71615ef2afafada784cfeb27146638b0dd0f85ff6860f502447b5bc1843abd71c1d07ca181f9f48eabf11e12ab416d2933d783016e889e47ae5ef282ad887eb54a0634716fe2db851d23b2e4042d289b40ad9a33dea054b29ca896454cf21746e195d753c746451848f4d242b68d097baf147aec78143c687265296eb7373f88c4a6d494848484e191f99487776d3fba06ea3f8f0fb6f6441424242a29848a74b2a478454721eee2592f1e26986d0173aff82c00b1f9648c7f428624b53c8cc621d8b858f4aa4659a0bfa5a546e2156256b2f78cf71c3c6b7e0c68ef7639448eceaba1485c76d19ea9235177c0ee31dd0e254e0631269591fcf6841f45d872a89746bb41cdc2d170213d8e8f11189648c79ed9e667478a997ac75c1459b1d222021e9828bfe8044d237c6d516e56bf0f5116915cdbec6a2180213d888c1872392a3bace33ea6bf1f41b913a51712e580ed7e2ae1a24242a88010b18b108456826021187304421083108410402107ff0431ff8b0073de4c18e0b1f77b0431de8300739c4010ee8f20d6e68031bd6c0c5871a8a15bf850ab3ab92b515d8d0d123c78d633c7af0f0c20398860f347c9ce1c30ca91c5b77add6acbaa8feda962119446addac53527d9779fe20c318c41006307cc10b5de0c2163e38f051c6071909f5f48fe1d134e5acdfe1584c6b7c64e1030b57f8b0c247153ea8905221b3e511a1f16347021f5348a59319219ab951c72b021f52f888c20714163f9ef0e104442409c147133e98604bf850c2c7184940c2c711547fba49b783ca16f588f514368b4e848f217c08e123081f40f8f8c1870f3e7af0c1838f1de8e0438c0f1c7c8471f801c6c70d3ebef8b0410d5a91fae4abf65ae9b25bc2834b949d08ae60c52a92f36561c47e6e3bfdaf50457234d4cb675a21b5475d918a74548f427eb47694995f818a2b4e91f6b432e8cde516dfd415a648268d1dc5eb749d59aaa805579422293f4634696a29f25978b88214c9287ef662eeda3ce7198528d252a5f4a177d1de6323878e1b360c6628d25e29eadc22550ab39ddfd05102b5615c5c018a4f78a2139cd884263281894b58a2128812894f22df4dc4bcb6e62791cca872b4b02b457d8a4bd6d25007ae9044e26d94c7edeeac66ce119cb8eef211853822194d753bca18e348150a6944b2346f50172cefef868a144218911431ff218316f2eb637656177357ea8c2b9722d26ab346b1d1ee53ec1fc70deef1191001090909c992212411a92c5266965a37688b1722522eb59c55cb994b773f44bacf5c8e6f942fc43c86486afd2515334fb22aa3011a350a9156aa5d0b19e4a2b494561b841022e9c93f3f76f3c2993e88a41695830a9a31bddd1c2288b44ec1372bbc98f6d72181486b6c46dbd4aee93c218048ebc8eda71c5785d03de40f0915e63f4468b8cdc8217e48c617afcfb0417be537a40fa9ecaada55f251df16334b08e1433aa37efbfb7e5ce9e51e92eaa3ce31b6c83ebd570542f49054ddf8598bcb59d9837948b9aecf212ac8dca62a1e9241eb734abfb29b9e127287a48e2a7e65d4e6d48e0d21c40e29cb2e4dfd633733df3aa45da791d9c363e890fe1621b62c8c27af5cc99adf407a73487dcd6cdcd84d0ec9a02b2a34485d390e090d42aa15db76ae4585433a6910525978d3d5b57a43426639b27bc4050bda2a6e4807579563e8e462530685b421f51bb2a9b11776e552b2b6c506689090e0c0c1364aba072b121277262141b7a3471757e821840da9971f757cce3acf921fb286747bc7caccb051059d5543f25c83704fc935569669489ce78b5aa86fcc70321a924aa38e6237b856d7993324c656bd9477516648fbfd8eb9b0187cec0d29433a47dd9033eb1a730c87902121466dc554f3f2ed3f216330b9216248c9d9ed5c0e5a8d67714818921f85c6e4327af76d170286d4eb5aadf35bdacb3c9e20e40bc9ccaf9cedd5bfcc311be285a4a8d57bd798d211d285542c71f91ab5abcb6b5c487eec8d42a4eb6c74cf16d2ed216db58c6131ea4606215a48a74dd7d439daf9a528a48cf4c7ad7b73f5a965de9091ccffd80ebb2a6b759d85d4aa1cee3bcda6fe0c6121adb1c9468cd47f79851a18018d53ec0aa9ffb4a732a4b08f391c6285a407fb9742377354fb09a942e24c83ae2c1e85ad1243a89036d521e7dd3cd4cb66a7900aca56ade8380a91422a4b1532efde7e28d5512f8444213dc27358d5b36a9fe11a27159d52d034ba37d84f48a6a7a61474a6d78aee8a22843821e96b1a744e5e9e34064710d28464da79c853a947f62f214c48c65aca61ec46a76c39640989d57efdda19db2a969235b41c214a486990cbedf51a93e8de6c8c903152e12b8eb0283db84c51256b5cdc601c6d43879f2424f4828cf522333db848489f07b142aa9af99cc24748a61455fe519db35f65d98518211daa69ef755ace3dab5e19214548ca895623a347b7554a0811d2db76176475ee1b8d19422a98adaa1c1ee43684214248dd656d1a8496a372565f109297f36da8d15ada680b10929dbd3c2bf931bf977f908c3576a63a1f5c2b4b880f52333275af5ef52a6d0fe9413aaa79d12ad4f7ada67890eccb3a5ce7824aaecc0984ec20a1f7a50a1f53ce314b550709692322846faecd4ae720b9ad326a3ec8db8eb618c919ed975f460f65f2c2417a3f9e4615a1b530349724b5962c675d4c9d3a9c8210305239e35ea6adb49e427e8364795631bb5bca3aaa4b1342be48bdc6767da139213648fa9bbc45adee4ec5ab4142ca50e39f299e6ce65a917acdf253d4d1437ffe5991d850396e906b51e9bc8ad4a6f4d16af3a98aa4ba7ca559aa742a52269f65cc6af3cd66a8489687ba4b49956b68d72952df329eaf38ddd859c714692d84abe7ed94fa63598a848e88789d47414891904a43e61491e15eaa0e094046919059555aee2015454247d1de7536a36bdfbe5024738a4afbca32c8e70514a97cae5effb78a425ffe446adc82775451ea565155b28686058d1a3446809e489c05d98fa1456e45da8984aa0f52b3cf65d6a2722215ff2ccae5ac9ad2b89b4879ae98dee3e8a8f335209a48f9ba36d11402c944eab5335a52d172bf1526d22d4557b3f4d542aef45c22f53ae598cfe631c62593398800b1442a4b9151a9636b05e1815422fdb265769059ef85ebe08284c4060e2e76e8a0443aac988b516d56ce159c445ac7cfcab3502d9f37dd838724523933467a77d45a8f1b89a4cf8cbc0f5ada1b402091142eeb47eccbf07fab4724bf34fbcaedae18cda5ccd6da5b1d0d210469443abea80f0db132e80b841129798dfd389eaf523e4116917ed198732b9468dd6945a48318d132abceebd6c992b5925b802422f95286f3761d9578d65919208848b8ab8c165b686c2a97db2192aed37aa7771f0fe3952c8d2d3690811e208648e74c29bbcc732e5ece61801422e196d58e6d36d1971e2112a751758c2767a263b2044013208348578ee7e1e26be17b44068820d239e65e7ddfb4c365410291143e23bd55cf5c6b8a09400091d069edb6738c95cb5712123140fe90bc981b7bcc2dac97e7fc909c8d7164d4bdd71b6e1f92f76d5f76ea76bb618e1b1fe002081f9277e1efd33d5cffac5c7480777016b987b448cf31c6a818761b3afce821f1c9b363f8e02945bd1e473e481ed2315feb6c7b949b972969ea6a388aa472115bd99dae3a3d1151a4f3bc7b8ceac63db9da46311c1009457263dfd589c5f032aca048dc7c688ff9f77a56cb060e7e1e3678dc30f78994aa6f0e2aac0a9feff54442a8df86f2f01d8d2d3640e371a81b3db80b1ed689d47ecc71c99567f47d453891d6eee822b75556af57229b48ea5950ee35ea68413114d144725deff847df30b23a256b1610c9446233ca941b740a6aaa2c59e37163ef03229848de688b9582ed868e1a0c442e9156f7eaf1b162a30ef6f0a20b94442c91d432367d8f97ab4cf99285c18e1e39528f1cdc5c827330d8d123c76717cc85b1215289e49bbc96b6514b89d465d7ddf1e5fe33562293480aafd559fa653596a34512c9cca223b482bb50a12f59e31eec367abc0ace1905442291bc11e92a8b10a9822f0289a4b29835ebc7d5eeff580e441e912e2d3717326b517d1747243f85cda954e558336a445a6f6a8f457b29b32d4624339ca8be90179145a475698cfe5e57a6fb323b031145a4637fcc6149cec4b31291eeb1d798755718fc07686c81050d44243697e85651f66c9e510f91f8d42b3cb58e21d2d13ebe4aa9c9c3ed228548d8fd45b1f52c97c24a841029d5dcb722eb3bafc545069196a139a8a84925888406bf155aa8729d342610497d79aecc72cb942f0191963134e76f53e1eab53f0e7e2dfe90d6c95df6e85d65af6f113f2444ba9cafa87116f3c5bc20d28794ef8d9af55626ea727c4889bd58792233555ccd0335f690ca6274a45e54f1b5183da4e3fa47cf36a3fe6f9487848fd04db15310cae3ef857f496b41421205113ca4379d6edc567ee59f738784c71519a427fd523ddb213daaa2a5d8b157fddd3aa4444d2f87c76459eba343328db6a8e80e2b74d0129943ca5cbb46b932fae8cc8bc821ad5c279bedd597469ed7aef6f8eeefd25d178143ba5fc66479f3efe6a025f2868494363a558c2e1137a43b8fece8f50e7eaa136943525c6ec6b95f45d890f24ea244c85df8f34841640d49b159575666ab5d834a0dc9164aa568ec55afae4a4352797877a9f47a294234245b27d93973fd1f3b7386c4081de30a6da542885ac40ce914da55e8173a55565a19d225e3b26dd9bf5e3d226448cbfc290531ab5c96996348c7ef7e2d767f74b28b18d22b47fdad0571f39df70b9130a4a35ebd697d3ca613a50d3024f5fbcfc9ba0af51b897c2199a55295a277e7bd5a6d581944bc905019a44a39aa94cd39de85a4b96519b483dfc778b8909a95d245867e8f429b225b488ba8182da5e5501f222da472f7ab766d1e6b85ce0d44ca48f75cfe4c8b212f2c49463aa379ce31990a378b9941240b69313a55a6cced479fb1907655bb1f63bff2959b2b242edcc9f76f8e2eea16b142ca538e76a953ac96592343a40aa9ec4ae4c3db679d5b49858445991e63f7b7ee164e21f9abf74ea4a6a5907c31af62ffea3cf2cb282445e64ddbacf95dcb2c14926ae36edcf1ae4f39eb09c9ac3c684d8bf19bed8fe07be828810d23838813922ee73d56169e8346151a35aa20d284a4676acd0a52a6c5e48b30212d46a75db5eda02e2d224b486bdad779e5ff96b18b2821a16b7ba3ea706da9d52263a4754c3fe9eebcf4f7bd0883481252aaf251655153dbd3459090f24dae5133bb54e6799123a4d4e26bca9baa8811121e5f6695f573f2cb4a9122244d34bc6559abbfd9224284a4d669c5088f425596a7c81012af592a54fc56d432464408c9dbcff7f43ae498478904219d665f54ac6d16faa5224048db6bdd9fa27ffdc54be407699979a38caca442638b0f223e48fbb7278d8b32e6ce5ca407a9e45a859c151d7a74478407e920a4def3cb61b3f215d9415a3c3b7532b918cff20604111da46f83dc94daf3a3544883209283d46a1d633c2cc77a1513232d22947a8ab6858f9910447090eebdb86fae1d648add29824818a9bd185ccfa2cca4e18191dcf06d9f550cfae72b088d2072838474f12aabcddaaae4725f24a3788dd5ccba44aa689c206283d4ead1dc226d76547fd013446a9054aa72460b99b2c5ab0d1a425a9112d35099369489e55e59914a1e1fd4059d456d1aad22dd69a5dcbcf42b55128f2a92a541687efb72951e7452910c5ac70adf4c71b66350b1d4d94a541042ea14a9951b74a5cdcb324d39a648aad1d6518cd6ba513fa414a9f71f8dd756515d142245623b47db282f7f6bdfd128d2fa2dabf151fd3b4491ee8f69d36a191f2124140999a5bc386e27bbc9d3025024ee5390dfc9338984904fa4b4ed93ed8acccf4c3d917a19e5ab113a87d7180ce944bab36745993387d76e877022ddf6daaf4545b73357c826d2c265e6b4b369e743a789645ced5953f6143b3f9989b458f7dc283e72c15c4c24ef75887b4e2283acbc10a2d1cf6fc5a73ec412a9a4ad2a6ac7ab1289d1bb51a6a06d5f3b4589b4eef915e63afcbdc993487b1ea163666f652ff592488bda4a192e7ccc18aeff6bc0865fb967a5c894ad29f7af01ff1abfcc5d210412c9ac375b2f5ce34b5d431e91dcd0b20c0a400028c2124bb0428d103fd020013a78002103a26880125670003a2c200402ad884424e8f0851853788209b2c8c28c28cc80c28c27cc70c28c26cc60c28c25cc50c28c316624610612661c6186116614610611660c618610660461061066fc60860f66f460060f66ec60860e66e4608618337030238c1960ccb8c18c2f66d860460d5ac18a55a82215a83885294a418a51882214a0f884273ac1894d68221398b884252a4189c92426929844620289c923268e983462c288c922268a9824628288c92126869814624288c92026829804620288c91f267e98f461c287c91e267a98e4618287c91d267698d4614287c91c267298c4610287c91b266e68c3840d38780d13354cd23041c3e40c13334cca3021c3640c13314cc23001c3e40b132f4cba30e1c2640b132d4cca989031c9c2040b932b4cac30a9c2840a9329b88dfff58089149229c8d9f03ac6a0baf551984061f284044c9cb0804913043061c2121c3051028dc9180a982481071276e860c0e4083831c2a4081322a455abbad14c6f62ea4d863011c2240813204c7e30f1c1a407131e687180c90e740081490e2662f068c004078d804918069880b180c90dcae40b1eaf821cbca300131b24605203028cb4420123acb071a38b0b6831809155a8c2c68d2e1e30920a549cc21489330bfaf71b7f9fbb52a47f5be7b0a11fce73861469dd5deef22e8a0ff21d85284291d07951dd5f9671b45a40f1094f748213a9db1f719b53f81c63b6094d247b3d44d86bcba15c9948a6a60f1b8550ba2a764ca4c67f4b54eba7975a76c2c8259269d35e7a68b59be55922353a66ca3a7d7efe7b5542e1b51fda2f0751222da6a73d52ca9472f4c43032897416aaa5f7add4bae22e89f48996b729a71e5df54722915039862e1719cdd31612c91c425f149e52f8e71d8c9147a472ffd9b7103a736ad011e98e526c7becb81b2aa81189cff698bc7ca599691891da5d15b56e456f74e5c82212a2b993ac87149152dff4f554f1b02f4b44daf663f2a06d23222d4ea3142def364a738874d4fe32888fc1fc7366c410c95a91f2f26a14fd2d8dc3482152e12db7bfd68e6a1a2192e71794a78d598a396d1089cb1b2a8bea517beb12443aff07951d1ff2c782238148a7580aba3c47dd7a2c238048abf5ace6460651fdfbc81f46fc30d287a4ebe6fabdd841ab7e7c48fc76a6d74e2aaa22b487640715fe5e7690f23717c6881ed216f48ee670bdd92e9987b4d0b02acb6f59ba55e321d9f6b66de6f22dffdf21313b52a38e9ebdc5183b24f5bade0e1fe3ea07691dd2353275dccb7ef8ee237448c59cf2686d4bd9cc7f640ea9b4af54a69c529497fd9235631005237248e70ad310d563492bac46e290fc961ae7af6ee5be76040ee9d49dd12f8adc30eac9c2ce76f4e8c2cc90c4c81b921aefc62bad4871fa96ac798e1b2b2fc70d0d9090f0f816dce87103d915608cb821e195bbf27f90fb18e2158cb4212df73979af8b86b41c34c2081bd2a652c58ef1e366f6be8684ce65997293bad4148ea82121bb3f79ca62fb6fb446d290702964facfe60b57f9398ca021fd155e68864c2df1cf90ce726945a8dd2aefd08819d26af75ce6c6a7e98bca9050faa9bdc233428674db7907195748ad7f1f19435aefefe8f0975fcb2c8b219d83b0156d79b4568af560240ce9fc759d5cbd70192a0d86c4e771bde2adb590392a5963810e1d25361e87dfb83246be902c917234e4a6ca392f235e482a977d5d9eb3f81c7e17521e672223e2a262fb235c48e7f0b61399c9bdf71ed9423274bede5ceac293d65a48e6cbede0ba29a9da5119493dad24d2b559b2864516589c212321936a9799ad10327aca83912ca4826e9a958d4fc99a5d8e60040ba9b8fbe255fe98cc62ccc8155239cbf0d4f24a83f870c40a6973dd9f57a377c87047aa9090222aeb5ce165f25447a890dacac1a5c6dc5ecaa29235b529a4b278f41ed34a2efa4585112924e4fe63587d36e2356b1785b41ab7a8cbb563761d4d2824b476f14a9fc2bd5cf57d80460d1a864379a12303a80be6a25815469e805fce6a35ca519d90ba74718550aa35b45b60b0837bd8388783912624548392d559d9b5a53c13129a226246a4b82ed1594232eb6aeb96298efb974a489af966f750d51d331d23192f5e55d0fc2fa4b49390122984fcf215ca44d8256ba3d0a8418386a71734ce1c2fb4e8820709497f0b78d42021f1cfa103477771c30424245ddc8841e225610409e9b9a829683e753562d30d8c1c2129434555f9315c1c597f30628474f0ee14427ce348b54bd6d292c7481112af3cbceb6b15f39e4f042e4686a0b87e7dbb17a54a0963440869d7e71f2ba79531bb53301284a4c75bd0718b59088d1a014262831c5b4fe5a3fe2bba467e909adf1c3dc98ce96e0e0a81096ccc60c407e9bcdf570ba23528f37fa407a9a8f2670a7dc945dbc3c0080fd2bb15bd44c7e0c80e52aee731e5ca62530abe0ed223afb5a3cc71d5c69c911ca43c2b2f17a559fd7d368c73ec10c17701832d5ca063c70e1d18402be91dfc3c34008318112319646f4badb25ebb7ae1209dcbeb2c4b5fa155df236124cc5fffcab8d66bb5d5a0514410822463048c84569f9f5edf0aada3bf358cdc20e93a3aeb3bf791792484912f92edaa32fde8c7d6acd9201d63c37894b3616e46233548665cacdf794fade6d38ad479bebb897df01bb11634b218418d1a596041c3fc41841569a5dbe7f9b957ccb3f2ba602ecc2ad23adbceb67fda0c9f5745d2750afa7396fdf972bc87482a922a5a1f4e9478d610424532c8d49572aa7463b2f777a1c5165a889c22652f97f587cdb9e5eea648597875159e446a9d572992e9376cfdfaa6a83397ac9d06444891dc0288eca8e4efc6e548140a050261108601180cef2600c31300000014128b85c2c1803ca40909553f148004332e3646362c1628161a201820168a05e26030180a05020141181008044381a0404c9489293da5b87ea0a313d313118d348c006becbf4461e4785a5c925c4e1101ed2a5515aa2e4804581b23906e9d734b7bce5b3f1575e59b2acfbe64eeaa4db3ca49cf5ad2a3aa34aa91ed62b952697a2a4ac31aa6b87ad2b976551372f34211a9636cabaa4c14a49d23fa5a0e26ffab3d65b1bf9642944a18dbf66d6c98bc6b0793e689a47b22343a2f545f2629f74a875328ef7cd43c5f3a9d293d979554b7a6c029d3d099a3fbfcf4709ee97275d2dd23ddc8412920b16cf112b9209d9306940b15de0b1893e0b6a4dc862cdd449d67d0e8eee45c9ee46e2771d7c9e55294732e5d8f00826f0f4d8702b8c732c99187903bcda2b06213c6439c13c67bca50bc7bda89554ff121530c055bb32e16ba4bb7da8cd3ad2bb29dc647f2f68972d475b2390e38305aa11da70b03452e356a84660331ba18f17140e34fe8c55b06b7fae3570a4051347a3d73d9cd392cfeaeb8b7553ae9a081b80bd4e4c523b755b128d70aca4d03169b2e556e2c64e2ffb37cd8e1873b67c7148b2dd1ee472831ea873d3586352c34a9bc9cd6d289427ff988637bb1b130072c63d0718b996661893059f3f1c2dfcffccd01678c462c9dd31ae33d0f30cfc1331873f6f273606a36e06db1cc3e53e87df436213d56e2a96e9023f0dba990655165f23126cd5882f37770cd38eefa8b4188e4d300da35f260a20571cf2b614528b2954e92c8b9d7f56c1db3d192aa52ec36bb31753328520ded116356aabe4f180d3499c67dc7ad00a63072a4cf3614e7179a74f5cd9f50b3f20bebfca1bcc55cc8b4ed29af00fd827ddc074ce235106d66753b6b246c3d7a61d0f8a3a3a64d7b6ff5896eb958f03d799a562136c8e78f52107ee037eb876e703a300db537a66aa10979b485c0cae14f240e09aadf9ab4a63df2a8e0ce6cd49f5075c438f25884b175ba03fbb7f25af8eb903cc4d64530213329f60c6b70298193a18c008f27d772d133bcfd924ab05a8015b98d339d40331ed123e2ef6e1c2502d51db205ea15b41c3580f463d252a0f5be7e865ec0e98d7a4d816072899498bc628263df0ced4292cecf7f954a2299499a148489ae9dfabf46f127337c949c136f49d1bb46ac73e99d0733e4528d7b564d708dc5dcaf35012e15cc2e6013446ab9e15536413b1ac6aeda04116809167fac53f420bff0ba476a909ae0ad2e484aea26e87a8701c33721f88a7d21f1241ce50106de0a5bf6d308361878036c24a335a848ab6e1060ea1249d4f60334e0441a7d7c4d649783dce110a673982b7243244b0928622333fdd7c9d3b828d73ee12044d194c7bc2eba346455c6ddbcec00c59fc8e77e147c987defd1da845f43f79883262e2b41f2c5014610afb2f3c8d4db4a1a44bc4ea9771360bd406ebdd91a7b02f1fb63bd575c374be885d80238692799ab9dadcd33193b81ea7f4e72ad39ce61cff11c861b7d1fba75dd15d35534d3d822c567462fcf64f8607b7e8bc6041903a126c9f921d6c4b81c35012901081795cdbd0a32aa9a805d76000f8da9b80c80de87fdb94eeff6926a644d2c208e7200a33f80fc2f81a86a98c0136f05c5e6bd85ca147c4f936461b8a719f31501d8df13e4e4f9f62431254fe3ba2940b8ec6d7bc39359580f714340008676b899a593d37b4ae9d207a5f5830ccdc38c47c3959dd9fc8b86e5e4d6991190bd5c32ff2b9eb200aadedb05d13181300cc9706cb693c70e3d26ed06fdba368c593b45d6f3bd69cae376bfe34a6dcc6275247fcf844b33a4cfc6b9b9c701f07aa7ebfd5a070584f6d5fb8d9197690d8219de40a5819d72109842dfc54da134c126b59f0a84c900df7c93b5150491415360c7003348a8a04f9fda1b8d42b8deb82f9539527f00f01cac4d8d22d7a3b62380438853ec16ad56be53cc69f8b364c6caf9db592f8cce71968f455bb062fea2ad482fe79aa28e6b4d6669a02b4f321a8bf3b577d70f4b202607791932f942f72fcf2d8d23cd3e85b4e943dc9c74a51150bb6c1756853c1bfa888582e2904b4088a06f32e65c120caa6ec20753d5a9d2abd24868f76dc00bae52ab979cf41c47faf9e43ad861319fffc350d51ac2e2d83666e5bc33b3c8060393a8e31b5f9e5591cdf6eb5f42614fd949420a11eca2e7398d5feddd79bc87ca57ec51635c699edc1256356181da921947fa890452c7ba857a393c28ce56d0069e0f02d4e856b64bedeccaf809c6727e9f73e05a3600730719834e5a197bfd3616db1fa3517b3dc12b4f1f5ea0a09fc45d157a3c80e2293cb3ef3aa001842bcd59f0a0504200f0de0171c2c3490d6e3920ee6800639b0af83d20599c0e6dc0cf5b2641f36566ec6c5714ef2e8ec1265ea7b3f6f2cc32f80ec1850086b8de5743637bdccd307e7ece2a1d782a0cf9c69d3d69dd985ba03cbb272099550c62c24c88eeb465acf51d8b04929bc89a5e6b530d4ed0a5c4396b2b092f4817bcb88e361e9e42f9eda4df91f03422acf9f939e94c9548307d8b001e223e71f8caecb0d5378d8fdd931f998eb5931c4bb200ee96d3281e4e27fbe0f51f686a49a264c8e5bce61582719c5c840c8c84385dffae2391897507e8f1c525a0ea1329e13cdd742995dbf36803488963e914a745eaf8e60c108de8f800418d5d015fa08d00b75c6dd3be1b4e6826eaf51626cae829231f9dcc437b9ea45fc4d37d5e014a46e9a7dacfc928b52f508e35be0585a39fe4afaea5fb67690eadfb30cc008085e58452ad002b266ee12e41f1527a7f1ec12fd250900c3e43a9fcca81061f00dd1e5eaeb003120374bbe585214b320f4f087d570447a30dee4a20e778db3800bd3067f6f4846c6d3491a0e42365beb166f63d0a00ea66b5a8727965cacee571e84af18484e3b8b7898bbbbfe2219d1a7897616994727c07e35028e91031059087d76b4c024cf734fcfc7c8c6b11833ee27b311ea01df7fe76fa26307a04d4a7e2b7baf9dd873d4538cd15295176c4581b4c334daf7d52b24a49148c01f9831409d17986554b182d95caff0ecb1c68a642bc34f853d353cd412d60f9756f6d36706d1172251311c030f9c07983086034acc0087e7eab9291a4445ee566fbe2f5e9f4b7bc1a436017df682bc8d125eca06a180208030c1d5c807951aac324fe5b83501ebd2dafeccb367741f861df15962ad44ca71924b8e1c3903f020a4d1cde019f3d26b227d42d77335cef5f2bc48288c92b9aa6a322c7e1a20ff2fd39cd54a456830bada34a81736c42eb415ace4f423e42f67fbf5a3e4fd61a816f1d888bcd3a0ad7e97ff299a02d968f99d354f426c9f758f2925a6f2419a12be3144b3de98136d962d86c3085b9cd716e6d6c6c94dee4b48889aa45823dd93b48e8181dac857c10920f0edb79d825ac516e486a077c40476a413aac02e8187f10ceb9e9b00a660265dceb8c14cd575fc586e9f7b2189318ed4ac16f2e08a36be9230ec2299e47ad6788a0fc6f91ceac152c5f7350cc37adc828bcc830ee7cfbd0c461e889b8ef0808fabc7d50deca2f22114573260644d8dfb182263f7074228532d41b4ab77d05a78286c7af0b4dc65ea99a81f0d04b0b6803f9bdbf265676794544c977bb478724a2cb62cf3b5c774f16b5331c5d45c8c9b11950a337341b04f8989bfc4d80460b3994a100587a1f8c32a88752d778764e8f2d7aaa6bb80d2aca8b75cd1233ee025e32853a60c0d5b7e86ca4012a9389a70930bfd273d4808660780cfceb0cc3bd40629d7f66c24864b696bc3fbc7a6aec75e68cacc9c75abd56fc8f5eb09198a345dba33e303843971817d739b0cc7990e67119e295740e3041bbae5c468949d3d025bdcd7887acc9bbf5ba9b1211e4e3765f07dce4765201640111bc9930392d1f28463b8151cbc92e9fe3d02682bd45799b360d6cee41c1c7665622003ebb062786a3109f2116a5d4524f1129e441b438907ed6001a4d8485c6c40079a38101df259cbf4c17df8d4de7852cb4dd47d16e0a42172da4f8ea3316433e7aef241c70d8b9e9581c2fc5db8306fb8060de24b996d79782496640cc36815102a01531e717b64e85efd09e6cc2b206699c26e298de8a42f719ed845ca770c42c14245e82d579f346ec5eae8e3f937365407742b9f28e71303f51d11c9fa2ceb16cbbbc44c4149363f5780f962191d2778c5a58c2053671ead99f1935ecd62b8b5c6db5b1b2702d1136f2fc99dbac54b4eb0b33cb39233d8f090be31722535c8396d5f72a30030e578e300b73f68b4f18008690fdc69306459efa835e06183b8cc29c883af5335dd8133c37f9f7584eb16f8c184d3bc507e740aeac8ff67bfa3d9c004c8d085061e7b7831facd2bf159813c4cb7923ef506e952c4a6e183d98a6b3716bbce5ad8d365c8583a160049d75a8070df7273b3e8717911d7204c8004750199ea229cf2101a1d9a76ea365d00ea82a823cfdeeadce77c0c9079a8c00bb4de3c16d390481222c7398f3a55a13f737866601b538295f06178bca2bb21f2691fa2738d898ff1c848d2e2ec8a740ab3bcd093644a569c03bf5dc6184fd508b6a3d38d51a1cb0400410b93ae86abca97da00cf07649ca9150b96184f9488872d0d0837cc5baa2cb2471e69f6e30ab8fff0f7f8be93cc7e041abc0ea72b36eede3ff1687a08eb3351f21f85478e635e3691ff014bfbfd209606fda39bdda272a0a134e1c873efd4edb11ebc427aa97bc1b08177287ce990c3cd57aa2d41d45a6b6d08e690a2a745904eed6db1f5dcf72deca7370b7a178a8b5087ac27f2f0eb9b3c4e96f6edbd32405de7853aad666e7855a118a58697a2ed31bf2147f5c1a073b9e3de567f5519414555599065caf3d68ea9f385b5a0c36b43a014f3e2f969bc993e2125d39d095f175d0091196a29c96d31e1eabba138f90b945e5019d1e440c850fb54d61c34f5b5b6a507bba452ee6e82c64a7d56ab88d59f3eed595cc0aef4ff17afa3800eeb353df69c07b55cd2ddd92f2995ae4f7c8b6cd4dc27b416bf375da95dd2c923bcf942eaa935b247286f3a70c597d6fd19324dd110d1beab0fe72060a5c5d5924f2e60120a82a73b5b4c609e7f82a2490714380100de71a62a12bc9ebe0a8b0761804af75a30de85330ef51370f12bc069419bc61bebadd75807a11de51662767e9e63959c5fb41f1f58270774f92711b1ecec166cd74a14f0eabcf5f4628ea9199e7632e07a1498a1c764c0d80ff25ddb9de4c0c4d3f0f34c4ea1439582a92b3ca8b1eb4679bd0dbd29b7f84c9f80a959547813a81bafc30f819d019e1d736f2feadb79fff71c5a2adcd4f25b92de497c0c2363c8649063c94ff0b2f33a2c2c84aa34b2a022e187314c916d46518add0637b66b03fd116bb69a563b67e7bc86aefd949862dfeda43d4f81a9e6868af9b24472f879ed32bef113e72b2c6b7db1d0a6154f268ce1f62c9af2ead8e975737b3e0c3a470415ebe623dc82aaff03b296a47855b2b7cefd977361c9dae2b7c67c674e7590e96c87e072ee24c7698e793847696c30724d829a87ed097c637c808c70451666f58e5c71e383ab8652d51ae7cae367e6766f75b2e513227a893ca23929d7b02350324188772536b874be29b8d8a9a3abc4d7bc03e5d119b4a48be765f0e10385a2450155dff0500e97d7fae1603f1291db1a33785321fa4d037fceaf768a27cc431b34368e79296135f8354e0fe46f96cafbd99ef892dfd94b31dc3bddff21a420118a98606f88cafda02aa75d5e7c94d3cb447552df2f763cef250c1a74ad084cbef84e3c81179f4db156e3c3c25ea8e076c5d780bbc1d19d2b179b39a72d2631a88ba871419bda6f25db75e3c75e330c69ef3f9a603fddf92724913c83821fadf276ac28817cedc7042d234e7b8e0b98eb77e028d39b9a963073655bf0ba5c4a2974ce02fc1940ac931a4fa2eafdf1bee76f01092d010f311d4fa9c38bc51fc2740992418978e6154318e352e03ba0aa8bec7c438768438048d674616cfdf9556d2a758c3122e0882bd1f86310a2e3e0806ca86b6fee048a2067cf23bf10cd4c378a83fc42caf226af1a181779978638f73c06dc863bd58cc9cf68181d0c27c3b23e5ab95f2f31c3f5550177e8be6278d2a0ff6050a06b235c08e78b1451b90c6f215826b0f0c3fb7098c70f5309007783b84bf512844b08f567855682c69d6a3a89b2391fd4a957e49ba83817d33129735c8f0ea9c233f1190fbb1fdefaa341e70dae7a40966f9b9269d7ca6a418ec28c9762a270f1693ef3d4d81706ea5d46b0009d5e103723555dda26ef2f95db96aab642b8072232bafe120c801c401f640a797abcc579eeae2ab0ff814fa6f3819cde141f2fb903b9c8b17e2f658c72b394277478fd4089058fb804ec674cf5573dde10490ddf35012e21e80fb6bf89d82505395af7aa931e3a4c405ab44bb07eaa09fb2aa47eb1e7abf1fa27acbebbd07da22172d7bf91673923a6103c39ec0071abce8eebfa9d4496e0da19e1110d9964bc5c507fe05e347983c93a07840c57482226399029d5d75f0c09e1fe2f01440031c882b4033b5180d3ebfd595b83cb23d9f77a5891425498b73e66d4dc9350ab6fb4442e7803eed2f2bd5a977e25550f34faa221a1c47b649dc008419abe019730d71239efcda795b838d8c0e1a4ae7186dffffc5d31a5506c7b47b9ea701efa0f728d91bbb21767f2eb1436afc0ddef6da5c06eef1610bd8d83310ce84fe307184ffdac8ec39be15253bb15d1d6857fe00282c05e77a1c58e6d8857610f32f7199d35b724060f585c9ad1e278862c29e821e439e90e7c4bb8328b4d0d5ab3142c77b3676c50bea804a4329a1db42e42b114ad7d476399bc21bd90f30a36d497765a2400947e63706f7ec9b0c0f51253b89affb910935f10bb06c077cfb8ac29bbd98525554e4308e44774a2ce279d2a03323ef85100ae1d574339bd426108b41a631be6ef1da299d80d01eb62b6183d245ab937bb84924a88b05042ba003dd8817172070e5f23034dff114b4c67d753ba588037d1994af97a45a5b041faa7cae02a8e7ea77f5a51d6ce6f37315e52039c00eb88b2f6d9a5d2fa73fde30b137ec898806daac11f8a9cb1c4954dddd2d0d681746484598d3ae658187fe4b3ebd816c6288ed9f10ee943100025873fab3c5ba538a780f935b45337f9bd4acafd03650e653fc2ffed0fe81fe5928e406d4b21b60d41920b828661937d8447032717acf118905a88a301c65279a1c63b6f7b56b43fd87cf702fadbd3a26b6fcbc2780ddef5ef7cef905be9cbb5a775aae1ba5c3b0a300310f984982ee83a5ee095c9d99fe2832280257774fd3cc482b7a3db04a4697ed779bf05507578f2788bdd00e7cfab843b14cb34aa35f9fbde93cfc837f5a7a9c81abfa8e96050e6fd95d178392474078bbf30a6512037493b6aee4e9cfa6bfa5379a15c007490f5880f1bad55b004f5a314f157713623ff1c6baa727d0e4daf94c705f77abf234f29ec7957971b68d10ceab53fd7ab810a22b5ca00c5e1294a1be41287898745d72cc5e53e189419d8520195aadda377e4788c464ba4f769f841db86742f46e8cd9c11e6f2d5782cae4e5c58d6c97c08d86b5c461f888db3301ef3cff719b9cc4ace32af3f4fb0d7e77ebf1611eb375bf89795d4702ea76259093e99d282a14a3c8c5de05282326eb3bb61a22204d870c5bb234b8e54b6e2dc1eab3fba337098dd4375a9cc06a106967aba6ec2fc2fea89e470a61a90b532d7ceb05efed9034a9bed2bf814f0a5c6f2c1ad1dfe20e804078281a9c2d5e5efc7efdb4a0bb8ac979d5d4c8815d7bd055f25fdc018953ea12d6eeb26f61adbddd8d6f6217b4dbea4c92491b74f980bd6660aecfc71ac55a18788c0570ad38fd93c5a535f23d4b244ed616c7b5e248332f345167249cc2e0400d6e1f16a36f8460ccb5e2401ff15a30fab8748637a89c28f0c7602f1296a0c7d3f31a9fa8f67a314e60fcc0a34e91211be2a606449d86f960e42a5751c4e8e07dae8aea1b54c2197010bcfa00b0d9eae03d4b0adf0f99ba5de094efc71faa45d8755b98c45b133153aadfe5cc00823fc7d13d646d86e1699294036c3b1e2e5982184ca180c682e1bd9662e8cf9c4d99e10f8474d807e9e365314f34d267546306f9f94dbe35738cdf58577c32597b45450a023219b1fa01b50758a3ec50fddb9e713cd26c3bec718020b1a774ddc3437063dd9483fedc3a0f28793b5e8e8d65869503ac8e67b1df545239c8208861c9f3dcfbfb6e36799743c40823003fa74f21f9c2d12d83bf7fe4ba843eebcb76a603a70df052a6f1eba458b096f57eeb251c84153c941ebef756d75b723c7344876cfac6f75e6b99890230fd27168e532a30ee17b7c59f7b83a7bf141b4dd874b33bf36f359835175badca41ed8c6b529f9589518a594973f6e84cc013bc0278149e9c0c2380432a50e85c990be8e0a92c026515b02307af41124f7dff250b2746f3804bbd90caf4105bd792b96e19907c704f7f15d3684bb48ea46a30af2bd208659e3793459957c20c665e56df047974738a63c745f8bce9ff241ffaeb007e8b32df4b27e5b1374d876fe5b92d90163db880af32d21859e573b19d8bd49a277401cfb88b47f2d02b3615b9ac4ed98efb86679a51a3047cadd72bafaf14f6b24ce6144dd235bd59d09c01225840c613c5f19c4e9c2125f9e4b1e26946052958061ec5a69fc70bdf2e664d18d79e82cdff7da7bcf274be77f9d561bdd77a77c13adeda94b4a0932d2dd045a9914c963ca62f794e394cbccd1757f5313b0a5ecc57ef794bde1f17a419c0df6a9590ef32c72823e424ce37d6278e48b483f73bbb13ccc396f8ef05833e0955f6ef0f9fff9f4c74c13bbc75f809dc9c7c9e3edaa4e2ecbc45eb3eba6008d6f08613ce8c678586a59d34348def4c17f217b7feadf404cf23c1cd1d09540692c34d393596246401fe2f130f822c3e5c7039ce9dfdfe3a67eec7e210af4c00a02ee6c0915f03a8e41dc2219f7612b8336f68193a002f5fafd23a993abaf2befed08e0f29f84342d9fe37e1c3c5f2cfbb5effedf446e7cfb670d1aaf0286b3a5c748d4febb88bf71502bc076c739943f001d357aa29f320b361ebdc2bae055b0c69c2cbf54eeea99393b3d431c9e42ccb32f912b6e234a852babae26b4504f8c482d5e2ea4224fe90ade27e8275853c0ec88af3e58e41e23906e2d30b8bbf46cab53268715ea3009e069435a446997ae022ae78cb96cff9fb0a7268323512953b3d506bcf85a4eb39f3bc519bb2e7f92fe81fd727fb341b72395a2c21b1ee45ff72a32029deea996e91e418e1313ec5ea0732682d912822b44fb9ce89abcc2cd063b89e5cf7adba2e011e0b9f9db8e73d89727bb52c024f9ac310c784e278aaf66aa0571dcceb4abc822efe80ffab141f8287f4f22b9acf16cd9e51faaf908854f41a8587bcb798388dd6eb2aab7bcf3ef766a49d31e706a45d01", + "0x3a636f6465": "0x52bc537646db8e0528b52ffd00584c4205fecb462a154f10785625e92c062892b020608682808d0eb43fec8311cd969a16bf9c0cf020b90aa6fd272ceb4dd504f7aee26151bfaa0f70bdafbef19bfec35f68e437330d88a963db5ad21a2184104236d95b4a19231671140a15da1678c0056a6533c81a51ebdbedd0b6c0832d50eb9b8c2603effa52ecd7af6fcc611fd3edaea991c0b3aed39d0e8c5aef26748140127fba5e198389c6a9a742e358b4ee18f1f118b63067dba67a34be7a74dbcfb36ed2699c8a29d138d56ba271e4735ca07176750326547e038d13a9840b85ca1b542e15a88cd7e9950dda40a59452ca6f8d9c40f6a8dbb0ed013cf8e668fcae92c418bf35114709e5527cfc26b578e30f4837e06709dcfbe3731f903e1f7649f4996bce81b72b1db0806aef27c0dbd5174ea846b96f1be4b84b02abd9816cd7bef557b56f464754a968f74821ddeefd35edaed3cdc58fe9b6edda28dd7a7fa497bedab143a24f9a95691fbe3b24fade75a0f7cdece893de27cd6f668746fb1aed29b336e0ce4295eb7deb9b07731605df5f4b9fe04b277dfdeddaa8dcaf6e098d7297591c95297778ab5b62666dc073538644fa5845b74b82555ca85ca73d98a33217dac09766c5e8ca03e96baffdbd759d6ec0cf12344dd3aed35bec94d0a1bb35aac5718704bf3b1d7deddb214181686b037e5b1bf0db21c12aba6b037e0b2faaaaa0dde1b7ecab916e871d122b864a45bbd953648f542aeab3424bdfb591f5f870b474d2b75b8248f65548b793be9e2209a0bd36b6fb484afac65cf6d5a6dbbbaf87741f494bdf6e070fca5da74b5f111a943be92b9200ca6b63fbc65cf715e129947bf655a6dbb76bc00fe5e66e8d6d6650a7755afb9666dfbef9fbe6770b55aee9f549ceedd3a4d66ce9533345c23fa4be5cb019c0e37bdbc65eb7b330db4e8f8632dd767a3194e956da9aca47b40f2b47170b5d20038ece0bd4b0271a0a3f1aea86b5d93a60393a2fe0c3da2cad1ee5efe2d05902b43696c650f8c550c80dd1ba46dced6455f0b2265effdb6546f0f82da3c9c0e321bab4ae11eda9c9c05b23bab48fa6b064c060db6f4d6595141e90fdd2caaaa61bc616532ae0ed0a074e28ab1cc02a0a676515dd6e098fc6c3ef48a47116e129147ebf5d1c357e468746e32c52a2f039f486d69d42ebbe4fe1b76b83554bb688fd6edb118b16f991488b7894666decb7db7270b6d2111e1be131013cbe4eef69dbdeae9697bed0060007c00f7380b8035dc19ff1ed03c17ca10d11278274a02bf80b6d6abcc64d3007a834532ee74a67395077eefb8539403033e59d643ad00fd7bec7600e509ca9c8cd14848f33157f714f713305e715fc143ccd49076299a99696bbcc14cb4b307779ca65a65abeb73ce5f2eda5bf7cefc11ca06ca6b2775f6b99291abffe9af7f596a7fa2d3325e5e34c658f4fb55c3b9075d34cadacdc9b290d9b29ec30da5330d7668ae39ed21e739518bfcd9494cf668a9ba999678fdce353dbe34c4995a7e485f87c2a7eced4caca59668ae5d7759a995aa139cbc5f2f9d4f53953341847f314f6cd2b4e2a33a5721696c7a8b0b0d0f8b3ec343359a665180c4b8b0b898b5763990b0735165982915bc31652a921cc15b9985d2c9adc5c5a5c204c8924330ce3b478b190b6e8826d2da4ab61672518c9c24996160ed60c11b52ec1683f91665653a3d2a2719810423cd5174208ccc585c68388f0416c430cf154f6218680b9aed2695c882dbb103288209e8279103541c0124b3c8d0fd142fa103f3de5f29310423ca55d8829c44f4f61b2a64683398d0721591e44d7d4d40cf1d4f52166aaa686c4fd34e7cc53db67b0d3b810349fb9cbe9423cd5722182080288cf990ae29f17e2a9ec7f2ad2f8aea2d22da7f19a99999f86e6319ff9679e227d06bee6364f956ec337323f3d55fa89bfff749ba75cfea7e08508424686c66584b8cc533097e1a7b4cb7cc6c4fc343335335333ff63681ef3d4f6187e4a7e3e88a7e28360206a9eba5e335340d49cc64c01711a9a07f114771a4f61b799a92186f83753313315731595cbcc94c9f4989992b98aca639e6279cc4c99626e7a6a9b3a6bc3ff7efae67d66a64c3365faccb7ed349eca4e63a6bc9fc653da24b2367cefa7a7b239c5daf04f3335c4bc8285d03e672acbbe32532bd7e6b5a7b079016da632ed3233957dc3be3d053399581bbecc532c5389b5e1073153352c0762a668cc148dcf6fa63ee334666ad7a0040f5498328339a840080583052b5870853cc0210640584001c15c07daaccbdc1fe6429bfd8c7968b36f99d8daf06966602e3353312e37cdd40f1286c08622283ae08115908082f9910109bc90022674010f506a8082790a66a64ad37b9918b4d9bbcc853635663dd13d699a9ee226146bc36f9929967905a380b8afcc54e92af38a1b1410e9de4c71dc4b33f593032ef8c0450ea4d0c10d714091f60b4743c0410a642085097840919e22cdd4356fba6982367b6e2eb42162d61b741fe78d9e4dac0d7f9b296d5e714201c5673395c30860bc010874d0c2510f50d8bce228201a61d881084bf042501ed88002ea5f4f5d3325e7d7869fb2a6076df6712eb401c0ac37740fe7696df8fb1f8864880e00d0b69fb72b12b4e18dd3ef48bbbe6645823128a4cda78dbd6fa4d8f6fb71decdb6746b36e6578e3673afbac55199c29fbc24e2c4b6e6f88bf48816b9e89195d20639fe20ed8e486e71f4b0113dc2517e9fb4387a58458b2480f2552aee74782acae75494d7eb316c4bb1c6a97df8edf36b105e1f2ed1070227d6a77decd34e1ddb7e5efc4de354ec46e354ef8d63dd88c689d4baa971360c3628a1d6691aa7a9452b47eb0db5be9dd3a8cad16aa2d6bdc6e95b6f691c78eb58e3ecad738dc3b7be35d604b22b56b2f1b7a6de70b14f1ccfdb2d119390b39eca63dd2d54897d9ad507527e76af71b66bbb346d56edd9b50b6b9cebf05ce36887dfae8fe9a67ddba7ed1377ee92681afbc4cdca3dfbf52de53e1f48b56fa4eb5bba7d4bb5afc644f9bb36e04d1ee559e5adc36f90597e4bb30f4b001ffb7c2ccadf6e67dbadb9ede4ac5350f9fd2a06bb852afc2d761b55b83ebd4ff0d769fa74e9b40edc2f7e9569119e3265ca145a7fe85e7e3e90eef9c3fad4e76e6727674daf4f8d79348db387af699ca5a6c639853f2d0e48e1b7064e20371a5b3cd8c6a918ed1c0cdaec0f9e24c2db55157ba0bbaa620c5a4db44f00baab2a8868773b00f0f8bb52a9686de9638d83bdcf358e7cdfeb6e079bebc9cb6fcc31ddb893dfe4e7c34576629fe27578549e3b2596ca6fb7b37daa1c656bd61f6a6112fb6aa435de07d2ebdbed58d7e96ddb0ece9aa2f0d8574fb1cbafd65a251444ea1414fbf609bb0e84df358ba428bcfc96625fa5a1f11b73d7b7547e4bb75b2252687d4520858fdff68967ec13ff6298826e0819f6751a769f1fdfdd0ddf90f918e539b3831fcf705686cc52d82a06bf8f8dd3df6ff0b3966eccc14fd2fe98f2574340f9db7237a98e8032fcf8dbe9b0285fa7e117697f4b7f9a796cdb38bc4cf75b691b67e91ea3fbb8f1b75e7fdb9a630f5e4623f2e2e1f9ddedf05caf0fbfad39991d2d34591b4bb78b53a7b7db897d823acd5d037e68ff30f315b6ada9a7f0dbdedbf6076ffb5431ca1d1253a854aa2a287f6b6e1ba7df38fcfd76db27789de62ff6095e08af7a14be1f0fbfb534ce52f88d39af71b64f7bf896c6610a6f6a1c3efc763bf13b42831af9c1681fa33d6776f4e3fb71fa30e5b97daa91eeb7d3c1ef59fb7c9dd6e9ad81cd4c8521ca372d8ea57cac71368c3548a17cae717665832594dfd2387bfed6f00472ba40fc30d3cdc7e36f1fb1df6ddb1f3cfe5edb16f12a46fb5ee3f0fba6c5c1b48f35ce86b10629b4cf35ceae6cb084f65b1a67dfdf9a9e404e17881f66046cfb79bb5279412b46f75ee36c186b9042f758e36c18553ca17bae7198eeb77316555be87e6b7602395d207e9813b06d8d573dca3f354ee5289f6f6a9c7aa27c7e8dc661caf71a675755a828bfa5719af2b773185569289f6b9c3d7f6b7802b9a10bc40f7304b6a5e1edf7d2ac80400df6a0c528110d310dd207b2079207710c918cb885184624421c4214420c426c22934820a902b982ce03942251208b803da187ba04dd827e01175181440a492b24934824b1806690269025902790413205724866d172805a403b4030c0304028b00b500bf0098c027c0234022c02840244023c02fc62889028a00ee00ce0103c01cc0206c12f402b7a0fdd87d643f3a1bfd05d68303417f8084d465fa16dd0447d839e412f61297c07b603a3018a8167c05d30166c022e015fc1421c64e407144f30118200a91f70a207ff207a51800114d1455209ab7a0260a3c608b02db413ac095818d80a5b02a604cc09460578456b81a5000b6a2fc82bda0c47e0b8d0709501e201aa01d6a1a75c60683a5c5db8bc0097c0155c5f8029b8c20051004b7089e132c3450658c555c665748d219a81fb709de14ac315e5827291716de1e2c2350694c1a5852b0bd00b17163aca55048ba015e014ae2bc02c5c568044b8aa7049e18a420bf515ed8246c1c5842b8c6b752de152c295042ee3f2e21ac22504c887eb074c868b0ad714ae276d820b0ad7132e27f40ada08aae012e36a4234bac0b890701de1fae2727219e12ac245049e7205e16a02ddd040b8bab87c70f5e0e2c1b5838bc9c5c5a5832b07d716170eae1b5c36b888ba8cab06170dae195c5af41b2e195c31b860702d8173b85e00af70b9e06ac1c50288836b055075a9e04ac13574a120962192e1cae23ac185c56582ab04d71597d01574015d4aae241709ae2a2e959c22fb20f920f720f520f320f120a5c83b483bb410641d241de41ca41c641ce491844333916f906e906d906c906b906a9051641a1a06120df20cb20c6906590649066924c720c520c320c120bf20bd20bb20c9905c905be814c8311a07520b4d03990589850e428f4116492bc82a482ac8294829c828c827120ad209b2099209ed83464337e936f41a201a380abf818f380e52093209500c0946cf417e216310b99039b0a060d5c09a017c411fa1b9601f740d2216e20ae25034012423aae01e601ae01da01e601e5a0b500e900e300a2c032443dba1a5402cc02a402ac0204027402790069d057803680348046b0061005b005d00c700812016d0040d46dfa1ebd063f451c3a1ddd06c683cb41a3a0dfd4523a18900b7d06480528063b4173d844e42ffa0bbe81d74195a079d83de024ee918340ba051aba065d03de81334165d050381e7c0726036301c1a0bdc065e03ab019e81c1c0636033402186c26430127807cc84957012c885084230051120201a36a6cb1711b2863c467a788007911e3c50f0e0b1317442080f0f1eda324f100ff4f01122c50778f8f8e0e9f9e184901f3c78c4645c40e1f384109e203a581e9e0ff018e2c3c3078a277ef080c026cbc11a09f2a3870f8f133c78783e304486831df201213f7884a087478a224278a208410f269edd60797c08192284470f21431ee023448a213e7cd019990d9c18e283c7091a19d11a09010f101e468c8480678790213f8c18e191c097d5607b86f8f4e8e12132646634582351f4e8e94184070f0f223c7e10a13c41767a787c48e1c4901e265005c866b03e3fa2d062a1f021c2e3048f2784fc1022450f111e3c3c3d3e32f031c2e3449021cf62b03d3c1e88420a213c7c88fce0f1c1d3c3c3891e3c50c06067644ba6f091c95eb044a2e8e16384278a1f3e2d990bb6874f0f2778f0f810d2c3c788901f34b216ac133f5c32162c8f13437cfc90ad609de0e131c2e309213f827ce0035240618487919a4c05406429582341a4f88011233c3e7c48114436b44ef00879e287112152f0e009e28410293cb0802f43c10a19f2a3878890213f2ac0d3c3841159166bc447480f9f13ac8f1129aa133d783811448a2150183965586c087880f0f0f1238807a420c2c3674810222658233d3c4ef4e0810288ac043e4278a27882e787ec8af531f223c80f9a4c88c767c8912fb3627d0c39f2438a223c3c7c7a8610e1e9b9c982d608cf13427af4cc64406b84c788111e21510c7142488f1e1e417a786048902768644a56c8901f3e3d7aa4708287cf90204662b224db33c4c7078f111e427ef030c2e383e707111e53f488e219099647043f8cf00841cf101f233fa0e0f18308e5f1d18388110f4821015356c51ae10912a4870f2732d53e21e40711223da2e03184878f8f1e3f8850233e3e78aa079618029bb220f84184f6f000e9196281253eac0fcbe3d3c3891f417a1ce1c123058f14109880133c4f3cd1630244607c5823407cf040e1030f6bc447084f0f0f14427e1c9322e4c70766303bac8f1f4684fce8f19982874708821021d283470f8f13417e488102e2634810140d5687352283d1617bf0a0c1e6b051f0e8e1d3c3891e3e3c0e50c1e220821f417afcf0f921e4870b46c602f1e183670a9e158c0bdb3344011c0f150d2c143e7c7a7880c74c065c30e05d60c502fb8121437a88f07842044078f0f84841248a213e5e26b044a4f0e131c2c3091e1f2352f4f8f070a2c790202b0e581f213c513c2102203c86f8f0f0c090201e78418077826be5042d0481eecfb62b958af20f8c91300d300d4c84af185fe24c7c79799989cc7c710b665956d7168eab99310fb6607cb565b298b96beb6acbb29aad6e086164c69a17b66559dc10b265b5d510428ed0b22c8b3b4c4ac9d2629692a5949225f72525c6cc8c752fb6dc1e977a7b4bbc0b3d2ec08d0baeb0b5175fcd6df1b60579d9ea66c871176e4e86f13264be1a5e57f332372f2f2f7fdccb0bd96a8670195e8ce1b0c519d61072370d5b7c7137d3b00a29a399e18cbbbbf42d377337ab34c3121f6144f3b20b3713800790356758112a2a2a9df57243be7ec82c76e96cad1bbe38e3ab9997979b5963b69899635ae3665ee6cdb8336ecdc5859933ce9859db184dd376615fcc0cb9992fe686cdb07985612ff372f325805d0803d0cd0bb92f78edc25dee661821c3b5c1bcbcbc97d5164388f1eeee6e37acc14470103243666686bd1b7b77215cb8d7eec25d8b99b3deddc5dae25e86bdbd0c7797f75ac616b33808dbc4dca56dabb997d96a666e86f0e2666845083119ac2173dc18b60c006c4e32178c43c0eb8a57843042b84508216cd810c28510c66da3c1bbb02d8beb2cde9ab9656b59af85d8b69999e3d66d7187b1c55e10dd5d6745b80c21bc2eb8310c61c422335bbd9099dbd5acd0ae802bdb21e81912054f1492070a1a980ff848c1c347c88f1e2233e40e80c788119e1e22510cf1c1a387e7c8101f3c3d3c7a1871c2070f8f2280e01c3100223e78726a6406d0630408161e203c7ca6e011f2831138338cf818f931050f0d101f3d3c1024c8901e0070510cf171e27a7af81819e20528e2882306e0040f8f213e4442d0e30388d3d80138c1d3c3e344cf109e1f3d3e0020e11c31001e03e001d2238807cee2a38711213d7a7c78f8fc88c2035218e121e4470f287c7ce003436c80e8c1d323c3f244cc8a1342788810e941f3c3134382c4cc1832a487078f4f0f1f233c8cfc30c2e3d3a3874708cf133c84fce811c510276ea690213f7ca40832c4088f107ce0470fcf111e46a4302284c78890213e78f84cc133c411213cd0b44504e139c21384c7143da2e0f184901f4f3c3124080f9f2978681c11c20359b688287ef80891a287870f233fa298a42de2c6008ae031c51010f8f07842c80f288cf480e287193b80297e7c80a787c85cf1e1311203d3d38327880f1e3c4ff4e819e263646679787a3e407344080fbcb6081e4286fc30d2c3738447143c7a86f8f4f0312448901e3c7ca6e0f9e188101e48236342ef4ff683358104c9652141820489d5c40fef8ffcf9b17eae267eb8a5b4c11fac894582040912880436818491206924487e6413fb8304c94ffcb99a58243fdbc4224182a49bf8612448907413fb8364912041c24dec8f6c62f7e707c9cf8fd5c422f9b19af8e11f6e02c94f6ce2877ff8e70736b13f3fddc4fe7013068057e0dde5288cf4d8a69a0b31eb817810b39eb22278345ea313cc33d5cc7a5aa31320663dd1976fe9fc54fe7d2cffb7721a5fe9ddc72bfac337e3ab4ca10443e39ccaf3777a050b68aed082866f5a1c318be30826b3388e78338be388896ea739cde22ca5397f9a0cbc1e8ff2699e753b34733d98ab740df8a13097501a07660661a2d4148d33737956354ed6edcc0481a271642e4f04eb7664bec9c87cdaf69595990fa3321f46a18039184a9e48e3ec16f399ae775fe5cf8b2eb332b52e6bbc62365ebd004823eb2c0f80c9c657e3b3be2662f97a89cb6b2fb13e976f87844bcbac4c21cc17e64427d0469e835fb9f66df0e3a13ec9af7c2cd427f91dafe59585a86c69b913980399401b790c6656ccb36635d124bc06f4497e017dba8a461d5ef7ab28f7ab4342fbf6c83d5e763bd18a97468d13e7f6499efb5cbea52ddfd2ee2b9d3fec2c4d04bb1d96b91e0b35cecae5198bc6b98656beadac7cda7515159e69d2f531c5a8f4ba5554ba558e753bad4543af55cedd8ecac55d90f4b5167de266658272d7beda448db34d59b597f85be9eb257d92e780b7bdf692245a8baeb952498b559f6e6c1f53ede321da7ddc5799a0416e6e484c7b496bc15fe9b0db29cdf5e28a62b446274c6804a34f724565748231dd20a7f261d4fb96368d3734d22d72d8974da1fa2a47b7cb288d73cdcaf43af79aa2ddb7736abc9b753b867d1bf0ae576944e537c9b1a75d763bdbb38fb7edae597fe875fe2a47b94fcc9f36a5519fe4b7af434296d127f9eb3af0f3a8f6d529542aeaa3b2595cf6451aafd3d7c7541a350e767959c675ecb1736a1cfbde509daef14530da467ee79ad1499fe4a393eb4888ce59c1c6d6374f5a60f4c9b256d4b29af4c9b2bca096b5459f2c8b09b5ac257db22c2da86561d127cb1aa25603bc1aa3500b5e7ebf84175f21146a359935d2da4fa815a378963451cb8b3e593d70729369ea9305ad5bd252412494800e26504277a5240aad110a9511cae2602a7f0d51b86ae2c5164c966841a5c4a24f520eede2e82be953124b2f256b437ebb382f559f647f4ba957a39325528c3ec9c329c1e8937cbd54547e09cf7a84c247d1c96b5cc9202a5f63111c008679d7179a7800543e3e2e8139d61bd8463e9bd5b203d6b35a7da0f271495cb2d3b7a2c01c8e6de431ef9ad583a6fa03addc0f56142aa515a537a0d3dd0e7f3ba645e005fa24cf1f1ff549fe86176fec932d8270db9803c10ae7f0d111297c8cf41421324448144180d41f503cf1011e277c78a047133c3ac0810d68200318b8c0e2589949e597730040e5b5214d059e4ef7f9487a171f51f90bc86bc89bb2b187b1173dac4fec717d6266c02655347edb8feb13b7691976f50ae6703316419bf888691e76313789459877b2b660b2440b2c86a2aa4f312aa111d2014aa1919bd07824bc0a8b9ae8f062131abf44118dbda29105b427d21a8b687c7f5e9fe2ad8fdff1ebd1f4299e46d30daf5f4d3cb13ec507787ca9826d590125ae28f66d13a0059587586041f958f880c2c7efc1046da04b57763bd907bf7a1ddefaaa76ebbb4d44d44d5461138a61d8753ceb3d2bf73d76ab5b423e3b5f07c2989d69760a78db81c4c3d7207d20d9f995cb74c4c353c0dba60fd3ebf2d6b5e9c33466f30853ee1df8ed7630c52690b88253d84334e24499b28962f40c83d1ad249b5012ccd97b71b94e6fe3f04aeca2e5dbb9ebfc6882f935d7e397738fdd0e37d7e3631fcc76d8ed6c733d8c6e1f46b90febcb901ecf33481351ef4b78cd795ff934220f5b2f5319eabab38c76038f8768fcd66db306e121ba1dbee320d7213982463adeb16318773d9be2d526b22286c19c2eba53c0dbde7f39d3eed9bbc3cbfcd0788edfea14994a1a5945b089cce4ebc0afc81454057ebb252e5a91d08efb8a5c54e5dbe968fee063b703bfc16f3d0cfbecbedb7dfb84746f016a431930cab67a5204c5e83a51fe4e4ab0589b55c2024c89169e922d4c4a7c70255e9c9480716304e5cf088a0518b0eb7e74df4e47f7968cebaf899abfde0e86c382f6371a6841fb1cf3199a199b8ce93b63e5a7f12db4a199d5a333b35b021ac9cc8ad1ed31b362a6593dba9d65db0ef36b73007f9b47e07b7c985a3cd8020fb6408f70d3ed45200ca8808621d0234db7d9e313e9f6222b050c1aa0801e89749bf1833917a1412bd327fadc577f68c35cdbf661943f1f8b367f7b8e2028ef8a62148b28b4627d0e1a03c3600e2ca36dac5bb00dd47af5a8154487eddc83b4a0151ad5b8715cb7c3df6e9bf5876edf574ee31cafcc8a7dd835ab778fc6791a9f89c6f81f3e1d18bf97f3579ba0f5e59bf6f2c9c767dd4efc16bff5f8f1db66dfe5ebba06fc509e5db783c6942953687f7be1e29783bac0c805515c70e40229aa0badcd0eddd05eb2a7a5590eca5f8e17684189a0cb84368c4137c9a4712c8ce3597dacad3fc9a44fd6e52789fa647dc7eb57499484dca24f1616392d0bcf0545b148a552e500657d636f8b17f8e0055ebc000c31d6260a6bd3df82a00e6879774c4029d0868985361b6abb08308a75607f4d5912c92d3ae72a958a0428eb87394d046dacb3bc9ea8ac3754aeac1e9518b536cc33b57c3e7da658b723e77abb228239d0c86299155b99d5a34dc44673834610d2a0ad43de87aeb2684255fafba19bfc629fac6fdbc509841fef7d956913d11fbe846effe18346d0c67a3686f7559e337ca884ee0a680c22e8ae6820068546b08cce81432a950a0628eb3270d23258b50c9eb40c8ad6c6522b584077155406ad92885a1782ee2ac807dcf55c2fa6bb9d8c0b1ebcb54634428ff40d1ac96e87f48df4add7cd100a59cc80965eea19a48968e9a56e078442165ad052e9ba4e933e8c6ecc794b4911c8f67e770cc39e71af18dde6ccf69b0e1af5c9fa0d8f5fa111b50ebb6deab8a10da3502bfb967deb6d1b371bf04337eda46ec79585164ea8f6ed76b45993584ae486f62546311d3f44b43e6045e314b24634ce206bb49d0e26683532a588f61b47defa8e16b6681c3985dcd09e416e687fa96c12d3352a284119b462944f8dc367662ef6409919e7941fa58026130d7c841c4d42029ef5adb4358cc238e7866dfacc3671c80de71081367d38eb0dce89531bf2aa40c50f1112451020f507144f7c80c7091f1ee8d1048f0e7060031ac800062e60810a5060021288000498581caba9c0ab5bb4028f8875c47d2660cea2b04561f018b69bc4ab7538f9b171805873468775786bc2f8717d62d4763c14fb12da7662d483d83b186ae4875ed8315ada9a378ef67d4de390be3fd5689cebfb1b236ee4689cd2f73a0b689cee7b251ac73a15e47e028dc3d8904aa50a0355170add67b758054494cf6ddde71d7ed8bb976e753b25cff38ebde4c1971e1fe1f4b12856fab83e65c7be3157da0e9b95e9f629bb4ecb68445e77eca4c36e8734d7eba68f45af538c923e8c76dfd2633f51ec15bba1d8b959bd1b149b589fb26f339b321a9187fd9a41629f380b2dbe9073470b5bf469295662a9a471e21b477ebfc96f69fc30cacc595f3d95b3329567b61ebf6d04bc5d25d9038da1bb4a5244378c632f1eeb76e265b703bfadb9f899fad48780275f4d37358ce82e099a3ef5e54f4cadef14dea0fd13ccc1e2fb349de3a9542a25a83e8cb19a689c71aec72aaad3dd8ed727ae4fcdc40d68d34c78f506e59ca85209a954a8a63f164729785b090e7dbb9df8fd96eee690debd62dcabb7bd9ab4d7e764af27baa4d92a68030f396d9e5626ca663dd1ac089e0afb89d656794c873e4129dd063018158d41a1c762f409f2130aafd3ec59d6e5fbfd719423ebdded58495c651d7e09afe1ad0feb13fce2b77b800787e8028144fec8b6804ab005adb7fe2de26fecf5b7db59409fac472e7e492c5dc0dab0be5d4f9d3e59d4ab876f30d0f831684cc2b3aec3eb5f45f7d6f9d388cee76e87b9488a0ea4d4d426a2f0dbddfd7d64e6fb98b018e37d4c9c6559f7317952cafb985aaeebbabe376118769fd32c4e4fcf1113cd7e04a3d97b7c305a04f64145b3fb986836198b631f0b7daca44ff0f263559fe0ad2ff54dd12778fe7cfa04df1f91ca46bd04e668876723684421842a0a213cd7c163caaf7ba4c11bb9b15db31e8d689f122541182a49498a2ac884d2ae24e884d2a6922088e2ae3dc800286e76d1df3e254a846ea0b41994a1b427817d50a18468a0b42b4972ed41a542099550da9394a4a8542a5410a3b4c943d0865534ceda73d7466528149e67e52514ee1185f0502c8efefab3480268bf16d1a1fd3a78d6f9f087395d58f388a4fd1d09a03d046d96c2251811b4a12660026d96c64f9381b761d0a5f5d444748140027fae9675d87687b7ab2b94504c5544319551d11ed178f6ac0f1112451020f5c7668bed3ef1011e277c78a0078f0e7060031ac8000676bb052a40810948200210d0863c6d055e7cdda22f130cb01e0f6d2251c644d5045339a156c5542b6a61aa27d47a56040f6698dc15dd273deb0fedcbaf9ecaed15ab268a7d37870968138fcd2a7f1d7648602a222a9f0026600ef778041c2087017014409bd52bbdf4e5e01c610401065004490001b051830800d8c4ee1b4288206a8098df17c7d278ee3bb489f2fc63d144af4f880e96d01ed6c6faae69e58a5a457b8475b6826d6b9aa0d6ac4d502b42cd3abf23243dfb7f98439adde466f5e8364d54cbc2eb67b35adf863ad0faae2946116a2a2f422d9bf5347b767ec45e31aa554fbe9aa8a6cd9a7d618e0eb4e9f7179b15a37dcd594db44fbbdbead8b07f98c3a8fea9bf46595b5990670f2b6367b0058d5c77cfdadd1257516d0c6add1263bbb8dddd9f34ec8475a578ed041e11c824ed6a131168230fbbd28cdb11a67d1e6252e91a0abcca435b16474598f6559487600e93e0599e1ad0392c9387aa77ca61995b46e52112916d8faca3ee88ca6b2a2f62f1d5c3a2765d8592e7252512a9f4d5d3d2e3574fe3af61e19dae65e1498cc336ac9bd544b3f0e24b4a48ede20e09d2adeb409d2e7dd949dfd213ccd1be322ba632abe79da8bcc602afee13ed6a4c090f7b76558c5ed5a3d7ab895eb3f6b1f310cc7999b39b2c73bb7602cf3b7cdd27a56fb08340134c2e006de4b78bc0429beb0b6dba6f170125a08d3c0f411b799dd65ae079b3f6e395b866c54ab37aa427549e87ba59316e566f1b4242bbf5ebcab2b9d7751dc3ae6f8869e420a484626f3a50ec2f569441afa22cb7ce9e3c7bd9d9d386ac634b3c6a756526b4e711e065eff33f25fa14df5f118ddfb6975999befcfaeae975eeaba7dc57be7abaf24d454545c5851b0b4f85bb968577bddea51fbb25b0bffc300766c2d932575cb85fb86ffbca27ff322b6f1cc7715c642279d7b2f0e0eba995d352f9d7e18ad52d8121d167e9aff48ac1bc7a54a5e5d54455be30e7d0c6bacaac3e16657976ee967815b43bcb577f68f7c39c959726cc6c992ba649f2ba2781a95494673de5ee6e956b5978d9ebae54f85baa84a77dcbe1ed4ac80bba2ba03268e32cb5be05bd8a5e3531baedb61bc66d57556665aa72effdd5d36666d6e0615656565666ed67e722ae85e5da093cebb52f63b7539b50d115211650eca46f1a073b1d34a6d095775f65baf2853934ef578cf6ab47fbd544b51fe6d04c1d68637d66564c662eb47989990b6d5c5e4db49e5ad758e0d55d9d8b600ea32c8ebb4014268cba082cb4e17317011d686303336bffbad6020f5e07e62c8a67c55e76e5b22b6a9d8b2cae65568f6556d3ca5755de7dbb9daaf2924aed6ee487ceeca03185762f7d4048736607f6eed8bb77efcfc7a2dd756057315ab9885adfb6eb40ee76b66b8a11e55921116595d0105c6214e548caea49111422264d9c2c19126a557f6177375fbb0e84dd8e967d9a0c96f6f95b6a25e1612b068dbf72d078f8aba89c1a9187a9543dd7c3542a9ac455b48b1aa7f9a8a56740f1b1ae52a97cac2e6cbb357708615bd621b422073ffe4f331b4db88078cbd438417888c2633b3e90eab8b2d0e20bca8f5f101e8a941fcf5fd8767af045307a84861af9a1fd527f6b2ac9c8db6fc7991bbc2c0e5eb58c685cd14c8ab7af1a118d1b050addc1db6776f020ad161868fcd2855fba3bd78370169982364f1d18ed99d5c1c3a8050636c0d22806f80a85b4e0f12b3fe96740f0321e784cf7353e11a29157fc84c68d4223c9480d5a38a17da6da10bd1e17477fdf1fca8b7145af67607890073a9efcae960851999a79c1ab4d44f9d9153ca6d52a92b95ead221d4dfb3a6dc1e10d6e68031bd6a006ec561ad0708632cc5006325863104318c0f0052f7461b55b6470610b6368210b58581cbb38965e5323f29ae87a2606af5574573058a2a5c0b35ead227add2a82398bd266b5a0d0cb32a21736ab15855e4d4497d6eb885edf9a6b02d186e802f113397e61db9aca4d28fc46e38719343332312698179716961515af44eab84dcbb04b5a11362f8ea5f099185eede9f71ce961dad387e90e48fb3d8f58ef5bd3a7e98e12ed6b44de9ebb2498f6e3c7147232cb59abc098f85936b288ab0058185914342c6c5de0c8d0a9811487d2e2c1ab42e58a9514b0c0a0c5062e3b780902cc17a63062a2208385992ed09061861a7e581bf0f1e338d0ed7ad2c003d552e0f531c84db027db7e1e8ca7c6818710da000c14368510c29e27b4df50ba0995cfa675fe2a0f513efcea2964a20c0c4fbb8c8e07cfaf1812d9e3618744f65eaa7dcb842eddeb4c23c71ef6d8ed5c676f3b7ba5675ffd0f122a5223104108a600c111297c8cf41421324448144180d41f503cf1011e277c78a047a5414bd7823cecada215a3f2d6cf448db35d9eb7689cc6295d764968b332d5ee9dbf7aca18b4915ff96e8e0ab4e1ded1f86106cd8c4ccccaac26981797169615159559bd12a9e3362deb66c52e6945d89569362bbf745e020673582ecf4a4802184838c2178b635bce4d9737f6721296fd253b1ba10844f06208420802e92ea433107ed0850f7ac0831d2c8ec5b1b4dff22db4e933173ac8c11638b8810d16c72e8ea5f22c1f13411b792d055ee5c33311cc5954cf8a9166f56865225436ab895626a2f2044e687cfc7649688fdab7de37b383a975a6d6b52a3ceb959750f9edbc84b5689ca5f2ddedb4676a9594a32846508a9eac88983471a2121ae225528ea21841297ab2ab1b37a7635e35d1ecbb398b2a312d7dbb9dd25c2f9b3e96ccb66da7cdfa43b5675f5d23badd8e469a750a4a7af655a9b288e2ca08aa9a886697a9bca2d965b2ec3a30fbb693be225350eedb4e2fe3b26f3b774b5cb49b1509b5ae7d452ecacdfab3b35da7b76fbdec3bd9757afbb4e903a98e9fb1c94a4ca4316351fc6106d54091bed8bd1546ca66cc9c86e599e9a5af10958c283ca9895e8e3d050f8760f699d904b48187992926a00d7ccb4cdda4ba9ba96e0289826aa0ba6b33058fa00dbccc8445bfb9623213cc4ddcaf96ed5c13eddb5330bbd62acfe090ca3453d76126b3cc14116803bf32534c549aa9364a3511365370f532e11a114997ab65a6ba98c0ca599e4a753181ebd8534246a04a57aa8b09902e7bb5629929ec2b935733c54da00dfc3653accd5467330555660fa9b8c96a21097818b23c6ca6940471a8d24c753101ec968d9011286ba6b0c946d006defa35535c9422cd5eadb86851714e240d052f82a0022cec4106286bf2117347459b511cd256596c62bdc22651954522ee151a59f347db2b24c28eb45758c4cd37d9a6c9287b854328ec15aeb46922caa65784ba5ea10a9bde50fca2ae89f50a2527066dfad644c5b9d0c69a3fdc2d64d8666866fc4083a57b90cce6203d4914624191be6f71798131c5d04cef4246904a5d0e2193cae610facae6103ac9cda1244909257483a27950b7399e4ab25a48021eaecd2114515c0e212edb1c422ddae610a2417139846a50dcf7dce610aa81e2689e44e6c10977b00211a65005aafb9e378710d69b43c8839b43c884a2c92174144d0ea1138a2607cd4cf11233e4200d6470e1065437ad48008a34532995375349ae2928d2ad4800aa34533f3e608215a89415094071331502a0230805410a5e4c41a5b85b910014cd4c214983165e58c204ca0a5034dd49dd4c091981e2662a2564048a66a6b0548a7b8ae6fb1b98d34d6bc62640a1f5068339178036fdde66c52e6d564f66b39ae042612378bb0aa37f037384224a09477a1086ea4ef33e56ba112825a5a924e806e5b1ac5ce5413750a52b09e2502e0faa816af985612825bf92a0a34c87f9cb4f31330fba41c93cc884b2b99c9890875212740335e34a823c148d07dda07e78d00d8ae68cd54029f90c3aa13e201e74839a0f6a41fdd54b724d4129093a4a89100fe235422d282542cc200f25c49504dd409d1e64420df138eb739408d1a094d84cefa8963d821f5483322d01f8709ebe046c11fc213e03ec117c213e1c5b043f88efc612805ff319b147f081f804b045f0e717802d82ff7d36b608febf9b3d824fe393d923f83f7c3f6c11fc191f8d2d824ff37d8be0cf7cdd16c197f9485b043fe62b6d117cd357638be0c37ca73d82fff20db145f05d3e6c8fe0b77cdc16c167f9ac2d82bff2c52d82aff2ed1ec1f73eb945f04bdfb545f0495f105b04bffbbe3d82cf7d426c11fcc38fd65b095664e4e49440151fe3b7e76ec78cfc2a11c250981086babe5f45328156a1b0675fd00dd4752452eb333a98885a73464e26ae2f9d8087c2a49c454ad49a5c605f32e80ded76f63a905514bb3eab1b8b9c18c44f28a2e2e137010f15e167746814ce2225ca45fc92d1cd3278c193e6224ce1b3d8987737666d346ce99821ef675a1b7d5e7df184562ec6b43836aa702a74575f40a12dbfc30602afe98601866af3f1768718b4a95506ed048c419b66df7647d3c8032f68bcd5af4634ad3948df7bdf9b681a679bcbbebf89f2b348dfa2acebf40fc5beebdcf743adaf329dd961fdfa923e25a407ed1651513a90f42d2a7e4b7b51dc59e766766cd79a665fd3ac5b0252eb5bb7edd0b6acdbac63f233dc97668fdf0c3791c09e3d9b40b467b3b2f6c9631fd358997b36e1b35984a76487dd124db909a46a8f677a753b9866b33605126fe487e936b3eb408a695b78d7ab75f81dbdf59a333be4a33567e267e2dc615d4e1d569cbc362012fed15a5e610381c7d7bc2168ec5d1bf2f1fc5d975fe5f7618704ff9a7c6c6607ff3aff9a7c8db2b57dbb3664b78446f7dae2e8a9ad8dbe54547e15a3dd55506b7a4378cd842de5f12300bc8ad1f688c0a07daea567db0878f1af69028a1e585ad606cb825ed30e8915431eca2fdf47d23dd39ac6b17af63e72070fda97fde59ebb3518083c63dc059a50512e835a3e6803959f679d98b840e354d33e6940e330b57ed338bbf281130a398bd60503b566e4e13b760cf859024c02c20a7f7dbbbe3a022a9fa2a231243deb0fdc6cd63e106c56f87d95f250079c54c8fee037ee1df072eee0f7af5ba789673eacfc967f7dbbe2011da8fc2ceab56cdd35800f7ce8431fe87653b6c65e7e3c856ea7da1aadaa82f21b1e655bd8b6cd7a7f46986613083f7b175bd4eee1b561dd07a345760a12dc35ed9bc59d7dfb6d77c4735d7841b967df20d759f6f5577fb8ee9aed88e7ce9d8eec5c12d7b7f3b73dfbb8c76e07763ecf5d1b7c9de6beda93d7063ffbf6d5d6f647f6d7577df84772ab615be6c28b875b533dde2fb6a01a6d29d42283c66f9083dd0eebc06b20d05d152105b46b4077350439d013ddd5106e40f95be4b8631d78900974574030a22c06ddd50fb4a035e8aeba1083f237c9698ba3716874590074d9067ebf28421b40e70b2f56004be5944b6cb46745428f347da287293f6bd1bc8de3b0ee48242d0e31a0708116299516c7f281c24b36c0525825959d0e49ab14297842158c68912690d08e68408b2021d1ea530631986a40ab0f931a9481561f1394c1a2d548178840c4118a6835e2a468dbc310ad49ec6188f2b9d381a95494552a1d3b85f265a7e3b4087fd799bb1d485051f9fed52121df3ff42283ca5b467ea8fc5564a74c99727d475c8ea0a24ea2d08f7e746bae3f1af4fa2c328eb8c4e9d33b4efbf2d607a4df5d123c855e734647fcf524e2afe9b3d1d5177ba03e4dad59fb3ff4a3d6f7d1f6d928b3155ab562ec14892ad51a452716186419cb06e02860a0fbe69c45ed35364054d1fd7671b04362c170611886c9c630c818669d487c6f1363038117e9ae72c007107816dd550ea4ecda0022064cf8e20bda720484f01383f6f904de86e1044212dd309c8cc174f89abbb69ab1b571822c628ba38c6db3c5c19417674b7907f076958328b4575fb401e30ab02d6be155ecfa568287104208e142685918c5d80a6f57398042adeb4029e5f5eb9d831616e6166e6db49ce5632b3c96afbca32a672b3cefa593de9dadf0b86fd79e9dadf0b0b31519ed96167e4bcb1986b6e8a1542a91de9dfbf652a9542a9d61db36eddbb66d9b17b65d012d1267776be3e2d6c675fed80a4fde7a3cbcce2d8efef5ae3f8f2e10479a168900f0f82c5bcc56daf8687dbb1d32fe9a42e4acf24160108ea83585ac15e2f9f2f05b2ba080cac90566bd22a19bf55d42d60a43d47a15019597f59aa272563e14720025ab5211132508800c26cc3a450e9a501abaab1ca8806ecd595f69ca94295aa0322e54334e90031610f504410484272a1f225b06e54225003298a03a720025ab2944402d126c19a86caab60c6b72a17a11431092a841a542ed4ced9108a1810dba50c51e542a1436554a542ad4be364e9c95c83e7ef0dd6d570115328841077d4832650a6adf42ad965d0c0d41eb4ec6a24f8c45e3f4dc502ee27f160d87df38ada924c806caba100b0a8bc669a15d8350c6a24ffd1b5a5b68dd3330a1c43abc4ef30abcca589c81f653f11eb4a9831646a881119a18a95428eb10053f55ec41163820c10d928052126403052fc4828a4a821a252f840014bcf509210095ea6202f02926e0ada7ba9880bc355372a6ba9880753853d6bcb181af5bb476b0220a5cb8c10b3c20431670e02deaa7055448020d6810061421cc01b5a8f87a3381ab54288845e30c0187b8231064b02aa02d7dfa613e02c6f85967be2c4b1efeb22c4b7e341dc3a04d603dee14e129345e4e9a3e597323ed2d6c7c6c71f00c630c2a80c71607fc9ee9ae70b084b6148994666d705c1b492c2dc253fa07327b01bf382cc8af01b14379782330090fe52184b76876da05f13add33f14c9bcec416c85bd7a4e9939c9169fcb0b5b1df551b6efab07190d7a41cac6ec3e3a08e239598728ba3b9c6d93bc4c521bfb71607d39b3e596fba2b1c0cd11ab06241354c30475b1c5f1bd8ad9f1ac7eb1396ddbaf66ddb603fccc160a8f596b6c16e7ddb40611607536bcb3e9a3e618727e02950053b3cdd30d8a0a2a63e61dccd5c87b4e9cc358bf0141c08d15de1c004b4a54fd8e5c7d9a4e9136645f9318540d8e48e76eef1d7d77d17c776ebdbf6fdd0ca5d07727dcf7df5a2bbc281121ad786d5fbf5bbefea63d8bb0f7bf63136eb1efb7a3b63d8d7dcdcbe416e3feedb25a171d7fadb25c17d7340c765e72215047ae0c3146a648b98b0a004746fe4279b95dbb83a05dd1cd0cd3a05ddceedb95b1d12da35201a12da57fb368160afd88e3ef6ecdb6fbfb8716c02840ed069107871ba6c00f0b64f2f1bfc00e0d5dfb8d14a344ee54e6444fb35dcdcef30269400512106a0a221202888a10cd4421b208a0521ac800a51f070873050185b15a3bd0300afde88343a17eddf689c5dd94088f673344ed35e31689fa671ac37c793a3bb229242e36ce913d3223803ac9e6a344ea4f05e0ba4a1f098062cba4cf0410f3698043c2fd187b594a344bb922ebe6dd9b7abeead39c865df1aa9acae01b15b025278ed5b546fd6368567c00f0a28b6c4cd1e3d40876287dd8e2ed1eb1b5ba48a64a83b257438d829a143b1779784105a04890eaed2a017d71d037e6a40b10e891f225aa4098a7d6bee25912a12a2dd1a153b7fbb38d95d18a76133fb16b5659cf62d2afb16d59d8ebe9c5af342524542776dd45d31610195f7b2ef2a954aa5426dcd41d82d110f8b4ca1840455a8e8f649ce0abb5b221e5220f096124baf298589fa98a884670884df8787b38680f691f48f6ca9225d61a3bb221283d26c391076b783557467dd8e44ba8f9f0e8fee21dc2f19f0fbf978fc2ef6dc1579118fc249d3a71ec2b6bd01c0dbb7b06c20f0a2b72d54e1fa14dfb295745cbf7e5da7a38c516ed7778469fc8e30bdae6fdd5f1b0b447380769a2aa66cbb41ee87628f5a8dd8b74dcb308cc66bdf25adadc18f5b8353b4afc1adc1e7f3f91b6bfd6f831836b1aeb14fd8bb438229f7f8456cc66f77b41ff16890a8aa8256ec45ae3d543125fb6a77f8eb0362fdfae3fc6aad158b45302524a882f61c9134fb918b1af9a1d98cc77c9a920e49b308ef815adde7d3d43af71581d49a333a78452ff86535defaf51d690abf755706fc2c81f2d6c06e69b7beecd817bf47feb645d89529766c56a90325a4d5c80f2d0229f6ec3a1d976a13083681f0b35924452ba47c8f76ecd3be05cec46f26be7f7d8b1f7fe3ebdcbf1e75f4afab084fe9f1e1b6d341444713143b36776b20613d26f1ebabd881c45fdfb098618710bba6c5fb48aabd768f8665d7692cbb168bf0149ad1b85b2376485872d61f2a1f3f8c5f99d63ec7e5b86bb26d54e10ead6fd6b7943bf88d3bb6905831505b498775eb96f6ebdb2181fdc2ae2ffbacef08d3ca47985ad6b75ede8e246d7e6dec815cd7bea51eb795986e5e9fb2df50ecdced00b9be7d7130f77d6ddcd0bdf5797d5a8c5a3bae6fb39461e7ee887c36b74fd8dc6bdf8c3c1174bbbe6dbb6cd61f9a5dfbb0af32403bc6c7be2e9b45201789d47a8d97b308536bd2f469ff8371ecc306bf35f093c203023f040d630d521647bda1f127ead0687cbc5ee1ac48287ccd1cb066a07172717dd7e35701019011c614d41e7e354561b51ee4470b2a5f91186057007557389002f5612aa7902d83168153a6506b7291da23814138425d53555334ce0a5f33da43d06f9781b5c2106a87a05677d1b63067013d2083133ad0000d654882da633087f37002286394810c218081daef73e099fac4f7fac4bfe886d1061650a670071e138fe3e7681c49f9af41f95c926d5bee07ca6c9fb6b7eee039100612b6f886365671c700192880c710c7894df8c4c6e39536f6e16dc7801f1ae3c4e60ff3028654106e4fec4b6b1fc8ce2248e87e27641dd46088ee8a06478c350e6c9c662f760df8a13f544eac3f8dc8831042697d33483095974bf9d6c7d46b251b8f07f9159e3fed068c041116d4a2bbaa810fe8aa6ceb83a3916e25f6e4b9273cc61dce20d187f2fc08043e5e7e97fb616627dbfaf0b6d236ceae6a4044310ef3401124343e9ebf913db06d0dcd8c4c8c09e6c5a5856545c52b913a6ed332ec925684cdcb744fe38719343332312698179716961515af44eab84dcbb04b5a11362f0eacbfd786bc7eff2beb0591c8ca812b6e146cb7de599c000b1394e00aec92a4afade8a0066a259da449d0557c53fac0873de8210f78b8831dea408739c8210e8b63b7e8c8f24aa48edbe00ae678938f4aa48ebb360957d174d9190bfa642da196509f2c2ca805f7d0274b452d78d4270bd2815a65f4c98ac2453007aaa08d75216c885a7009b58ee0fb7045ad432298c376603e823932cc2f1e89885a3f50d3752de371cee1a30e7060031ac800062e60810a506002128800049858e2010e68c00e06e8502209247616a00014d5591c4b2dd2cb720e9cf5075a65a8756da8dbd154e05998755952c75a611d894841e0c2075c6caa63b7c0832df42008e785ed3aa2f21b773d3bdef9d7c774bb4d3b7b98f6edb2ebf4855d63ea7dacf275d9553eecd8759aa4f2ed76bc0d183131c602f6c98d1c356ef8bb05e57b2be76e27e61b7b2cdf6ec7241364e6dbeda4faf47dbb1d9457a3935dc160c9061cb06550a35ec29739913ec515c5c6a04b9796400c2bc4a0449c88df2b010b28cccba02e77a103bd420cdaf296319aec8079fd19ea80b7ab2bbca03067ea05ddbe95401a69df6638990ebbf62dddf34ee95b0cc75f03bc8a958ef5096be976fa2cddce36066d79cb37194efbccb6bdfbea69a7692f35da67be691fcf7c5368af2b25d52779ed3afd5203847568fa7e970e093e1127d238f2323588cc37ee93f9a05080c7bd6e94207d92e726910c0c2f4a239925ddbda02e77398debf46a89904e33b5be95c3ef7b64f96998ba9d0d01de7622febdaf722734df88f8b6382bf389f20d6569f402732d0b8f65c7c5ef1b73447c4cbf007c9f897e874c608e006674128089d9989389348a4e3a4e935160cea2605ef8dba6a0dcf963666666666666666666666666666666fecef1c73a9a6ed769febeb3743bdfb7efdbbeb2b211f12d9553641ff8b0073de4010ff20ed20eb20e920e720e520e320e120ef20dd20db20d920d720d520d320d683843196628031916c72e8ed556e0551632c2a4d1f76194011ecc695e59a8044a68bf7fc516b44627120c8db330e76ffc6d44b4fb9cffbe7afafd5f3dfd69d0f0aae9248d66658212d15dbea5db01f3eed24893464148a31a690484348ad2686a5c03c4bb7b49134ac45798e825bda497f4928fa543e2e53f609e898588b8d7ed8079fd6942bb47325808e6d4b87ce4c216c6d04216b030c4ac1815620a09e041cc6aa22b80ef0a56a80215a620852804e08b50884f884e8862c4264426c430b8dbf8e212949004309070842f16c72e8e8d4e2e394da543e2e5332ec1d03800b8b479c54eafde1042bc9ec6205e4f488c2811b376a779a9db017300ccfa3344bb93ba1d4bd08ac48876874ce46d66c54eb37a43cc1a748ff1a5f52aa594524a2939f6a92b4731c660b091be1fe986f46dcd0d53f47a966959a6659996f9743b9ac61f334352ec2c4e6e97866519a65d9be4ac2e9260a93d56e196d4719b96612512af8dbdc554a02c696566c6aeede2b64ba2bba6767e1f3b7cc6d9adec9d65d9b36d3b7f3b4f1fa6d936abd62da13dcbb42cd3b24c634bd3b40bbbae6fdced6819479c08bb65a6f1941a5b9aa65dda5bfbbe36b873579665599669d262e6abe37397dd0eff6366be82d7bb0da3252f5e8cb46b634f84665fedab1ed5be5d17f3f5cacc3d4cfbba4fd3eb1be498af5766e60b5ed715a9c617cfcabfea755dd7755dd7755dd7755dd7755dd7755dd7755dd7755dd7755d3e91728df65d7bd69a76f94dfb6ac489b029b701b6d6de3ead7d1787dfda5bb3b4afd6dafbdb278b99338c7f714386158bfcbed7387c8e8958c3b68b13236c0374f730c5b1afdd5ddac5d9d77e3c16bfedee7e9cfd61716233f689bb1b3224c1c656b8c2b66da71af0ab1cfb14cf31d3b26cfbb45983d4d02cbb2e6b8b1d23af45dab511afd331ce1ae4c6f649a7f95b9884a5216197ec3ad9c90ec218638c31c608a594588c31461fecab1cc5bec51863f7ae849148a4c7932e9294b21484a31293524a29a594168c316231464f8b57f5b13607dd2d5679ac7bc530c6faf251ca186394a45f1f69eb4aa552a95492524a09638c1886197135606db440928cd1ca628cf1188df1a5c7e9d3e9882fcd2a1fbfdd12f240e2bb1963d7c5ae8b5d17638c31c618a39452ca28a38c324a29a5019aa594524a29a505638c588c11424c4629a594524a29618c11c3b04b29a594524a19638c31c61823c43a29a594524a09638c989452ca18a3c4628c314628a5c430eb5b8c51c6285f638c52ca18e56b8c31ca18638c114a2963c422c422c422c422c422c422c422c424768e381176378dc75e638cf18bc569c518638c31c608314c6231cad7186394504a29a5b46094524a292d18a594524a0b4629e3ab94524a29a594168c3162f15be47889cd1b7dbaa43c63af52c6cb78203262f1578cb1446b8c11c259bd6a3dcad7683d9e639fa04fa4d6a165cdbd5583ee990a9ecedab86e7d75c5a0570bbd3cefdcac35942341ebdbfbd4ed74dfee5a778e56f0aa47bb3b53af71ba7757a270ceec281dbe74387d3a1dd6bbd9755dd7751042082184d0b2ac8d6459b0eb2cd87516ec3a0b5a9665711c8c1cf73e719c0ef4be1aa486c27327eebb388ca940af859f247dfb48df1eadae542a954aa5ee83db577d20ed1e6f599665599665591d4d0be9ab37e8d65996e5617db22ccbb262fcea0ddd8e7db3aca6d0ea610aad1a7ddace568d6e621b94742dca9176e4e20729b4b8f8358dd2ba648704fc5ea438776dc08dbb9deef11c7122ecc6e22b8410c6ee70621042c8db7527ae35748bd67c9fb668dd88b5b159c7224e844db90dd03553203d4c7d9a5addadafc257cb8ad4da012910eb9056cbb22cf8ad06c9b17d37bc71d6e8d3657d58e3c0a95d17fcc55c058f4fea0e7271b334996d1787354e9589af96056f2d010fc4622a780ce717315ae137058fb1b30abc608f634d8d1a62703784315a96ec76b0ec8bdcd56d9faa1194bfbda54fb1b28c325ea765ccae03ad6f69a5a1ccd8e5ad1b196b6a287c8a888f8946ab5ecb76d61fba875fbd41e1e3f6a9fa503845f4766a0bd56636eb8d1b7db2a6fcb57d622978355ea43a05ed9cb5380a5ef79cd151995a3aadd35bf5b16ee408b2451c738f96f568dd58b7669dd1615dbec7a706fe876e168d54d5743b1ddb279db698c26f46077c7c84b327d2203782ac18f4876e0da325bf1aa51561f362a43a05dd8c4968d8b6a6ce28a25c2a915e4d96cc12264d9cc41ca984863629745761a8a2508cce209272346349941943463384a0cc50918e9e90a2ac48464e48509a908a9864d7aacc8a46084a1327ab2745344224262415b46152139210b4619213d210b461d28ab48409e90989685762a868909542b9579995120ba7d618ec18b031473067e50508293364543047e5071921161a43ff5e604c4d4ca6c7c8389191f90ccd8a86e613889a0371becc1298939a31831835438608e6a47e98418cfa418609cc49d198418ca221d304e6a43e8318f5b79c2fe304e6a4be19c4a8ef4f6266683e6b268d1420264dd1fc68683e9aa3998f46e6a38942e384c688a609cdf7cd783283e8df8cd58c2534be194e660cfdf0cd68324368c63783c90c15b4c95e6730a1dcbdce50d10841a15c678c28bfd234a17c1aa195a125442a7c1a262a463027253365a2c44c9955149893324d99239829f3e408e6a45ea68c1497295334236546c53265a0d0a856e68e122dc253e00402bf1486e155922ac8121e85e7be234c8b701f2894cfe2b72ab35282299cbb35b8095e0c51e9235d3186a8c3be7a227da4ccc4846f52c19c451d453182f264e5a489106593ca44449914630c91f698273067851f53b4a20285c508e64481e1c710c530896912e32466957dbbcc3723046df8319f8c11b4e19bbe1915b4e1c37c3250a00dffe59391026df82e9f4c11b4e1b77c3247d086cff2c93c81367c954f260ab4e1af7c322b68c3f29297bce49571189e366b7c25d5a88a27995d5fdda2ed8b2152416cc6a85282075fa3aa09de0ae6ace93343325160ced146315a28f5e6f58627b3a22c4352b9ac5a8858542a46de2a32a19939cb3ce6fc28b4727e1c62399b0e737eb9cb632e73a37283a6e54960dd158d69e605ceba52bed32eb4f126ccb7d0a634ab69a10dc9e55b68d3cd7a964fe55bf96211cc61628f8ee2ac1b25ca9c97afbd6ba35a535e46e5eba2023b05b52225c7caabc596e429f1e278c96b5e37689c451270445a163364c89059b5716751becad78575f9e9603d50e662e533d6ac4009b5f2a54dd0caaf245573dc25d12acad3faea0fb592306a65a6549e84066ae53abdad7c2b9f12a12eaea02e8a24805a97d200f49a451240e57744525e1a5530673712a97c8b32993c2faae8d24a52cd28ea7a003bd8b6a69a54bb3f74d746bd5e3521d6b8095ed55e8ca4684f28c41ecf4ae0ae0f015472dcb695cb8a099e0685b501ef12e505ee13bab4be2ca1f02e2faa1b379867721182391b86799ee93f9d6e6eea7683564d08fb6acbd8913b02b859a5a0a13e26ca7dd786bc9c958114e123ca4d4c7edb6a6dc063dfd21595b3c6a65c9b565aa444b963dfc57124526e56a6db0ae62cea491114a328479b140a3515addb0a33a21ce7128504ef724492e2a9c0bfa85656e05f845e5c56a4c3bb3cf10eef52e40205e6a45cde72781723989382f9cbaf5b87f96098bc7c30aa0f86e8450acc92972398a1972830422f46d006fed544ab47e531b95ddab1b312320ec3eb66e55eb715c6d59386d51376bd18b9ac5c569811addb8a45a562e4ad4a442455dd5614fe26c674c8f215d25b4a7739fc610e7f7af9ca596e48375c5efaebae62544c2ff73029302f2e2d2c2b2a5e8974010cc330936a6b162f9a5026b25e6114594f545618250e45239893622ab6c9072c2ce188484c362ab4d7d8a499348136ed440aed5e592ada8406316a7b4e4ae53929ef3929c95254ac1212121a1a1a5a32a5972c813636cd444d10a2b59f60fd444b25800f5740919e84e3565433d5f2fe8989b34c254c1ecc49a21d288906db8022bdcf4c56585c562633015a69e9ba775f990bb4e2d232a928955efaca5ca016a024da573ea9f0eebd4565665f141050128d6552c1ad7cbbcac49e7dfc850727bcf7b1d1c751f888a17011b431f2436114e835b9669c30cada6055b58458a5852f6c108333c4010728526ad7009404ca16c2900454976a3cd041072a2b543b4071296805276898810a0f48406da97e12d4863b94c00d5350dafb9610ccf1869ef0018c25454450604eaa8d3a4a13e080da55182b5afb8911ad300a8c0273528c22cd9b2398d3cd1b500acce1a68e0ae66c53092198a3cd28b45f6114ab09d62a5b2c893be7a42b396952ea9a409b06da5e02da9ec4fba280e21268d3546cdb8c44cc45523c152a803cef5dcc5b8cbcd2615eeaa800ea3ad24d277140dc936c07e29ea2a2eb3ef3ee2f9f5400a93cc9a62233a9e0b8cb9ca342650225f10eb43de6db5d0e749aabbc8758088baa6cc68c09a55ce56b29d0a64ff3c1a30f3691f9a0930fae3ec8e48344d8938e02e3a1513c90ca84a2f2249eca8445bfbeb8040caf8b2a1739a1b5554737fd9602739a09b4e963989749c1a4b494be667311ab98344381367d8f09336129b4bf04afc2278ceac7f7119427b45909fd1a9770918a07a5f4961623d25958a2c09c9595737f51f9a462bb8bf74eb54c26a00dbff47e2482392996c99109cc49adcc8536ddfbb1493f3a5968b3bd344f9074737363cdead1c88791e5276b4f0fdbd64c0163e9418c8a425610a3ac20465d41bc24d35e3e85c7725699bcefaf3136b3121492ca578ce866a5672f33e5324f3b532bf3c69ba9d2bce1419b4d7153c7046d5a897968d37d823617803929eca6099893f26e40017352a615119893ea5f1f0f7dbce4632168a3faa680365b24a59e68f389cab0cd00a2790968e6a4afcc3ba098d38c9901995e9aa6ef6fc01c20989326ccf73a3007e8e5dd5402e600b99c9b2edf4f0173b84d0573804a25ef40245269492adff3129883a94c2aba4905f7edfb0bc09c96ef9b80392cdf43017356be27027354bef08e5cb408ab68aba8352b13651f50969de603a2a139f6990f6866e6d8653e201999980f282646fb8034eda60fc8643acc070403f3bf7c402f2fc7eef201b9b81cfbf6016d5b11c5def201b5b440a1d8593e201696635ff98056568e5de50352513976ef03f2bc4b012a9554143be90322918428f6ee03ea9e64c681ba2fb4e1be19172fa1d8acd6171e1245780a352269be45cd7c8b92f91615f32dcaf42d0ae65bd4cbb728976f512ddfa258be45ad7c8b52f916e57d8b2a7d8b227d8beabe4571dfa2b68f51dac72854fc6a1f4e296850242e3fb22f2853c09cb8dfece5fb25a92ceba5fd7a7b5d57f9ca1ecbf6dec6993a9696efdfd272972781304cc09c14e9f1a519c4a8d23deff2758d546610a354a2ac1cdb9fb673af37dd595e6fb4dc6561262f21026de0dee583e2e3a1af898f85be0b7cacfa98f8a6f838cac7ab8f8da08d938fa1409b26a58f8b3ed2c74fea89f6eb899e604e0afe26c65b373a1deddb93407825600ef6ecf2d7bbb9d0869b98077352daf4a00dcc4961d3046d604eea9a0b6de4b4e6696250562ce571c259570a850fc3abec950ecf443027a53d7bcafa9692e752d849a9ebdda9c8aedd6cb76e70974f02ebae5242044079a4639f292aba5faffb8456260a230aad2b450ae9337ddce76d1ff69dbebdf609b4b1be6602daf48f8ea2443132aa4cd42beea73b4ee13a9252dab45f783dd6e5f71ae930cb9ea2a26b4ddb261559fcc21c6e52a131c75f7845985e4f5040dc534204409526151b15dc25a5482930a79b405d37a51468030fc471f3493dd0b6f14a4a01d29e043b90369d401b782905287b126c52b128a08c7bd64bf585d723df672578cde409935d3161884a59c44c98c01c6ca6b02630a75b3e143981391cb682399b77787e0273b46c5261a2220147fc8517dfb37291d86706c36330bc7a114929f52282c24c9ad6ebc9f504e6301368038f619e67ba9e5078d545743db988b60c5a659194228b0640ab544926526535b1a0584d5a688d46965034d2688d43d1498d4316ad7015052e81ab3e824b9ef4d11326540a93ca526e585531ba506e2a46212bc14b82c79409f66335098b0d8339a924306af12bebf1dcb63ad6ab99c2e4531c9f6a829dcbe00df43212d1e669459c37046d60516a7988894da58d9a98293e3a37297d511c54ad56dc4d76d4e4a849f6ab8dd6e84dd47d51d8893cd2eb7aa579d2c48a3a6e9ab6a1cc5484840575f150e9875babc2b635bf24cc89df2781b7bec72f09bcbe541278ec4b02618e8405a524a843454e3e885132c65b117b10a3302b5beb418cb2341723ed418cd25c664a495087825122940094cb8318e5023353dc2488512e33a5c346418cd2883411c4286ba6b8e871a67815c4286ca63c269aa90d62949c2926a467455ec52279a3ef91c54613090bcafa4e242ca87856619ffcaccff4bd06b6fc705f455b8c005049a0118d24700f4271a67308b5ccd81c42343f6c0ea19a4b6800a8241dc4289843e872d91c42a597cd210403b3398468983687d0105289900d54122845a552a98224aa851ad51aaa57502d83ea896a00a07aa6ac0b1100052f94d00daa1f0451d042c10e055d5070060a06818233052f440054777777cf543c1216d475b594d73459d693c0e9c1991222000a3e091422002ac5828a339504c289840525440054cf432492e3ca4b8147e38719343332312698179716961515af44eab84dcbb04b5a11360abc5dadcaa095e3d8069792eda6051ed7f06a34ce6eb48f85c1b5d0d2dae0b30b15ca54ac25b45f63e89e37c7527de12da5fc15e1f3171e1244b4cfd44202184950c2128eb039ae896143f08208453082932f7e008426411042179be3b2361d5c0fe262730845269b4388dbc1e6106ae1c1e610a2e9810faccb9236d81c42d80d3687908783cd2164da6273083d07449be3ba2456929b75494da805b54916ce8a79c15ada2a5d3545330ec4533de3a94ee63432dd415c88a74a3f7091cb534dcada530dad1033557a10b30968d3af9929268098299e3153373433c544323305e7eca19899d2797939cc4cfd9b3cc422f3e9d198413550dab7e64dfb61ce78aa14f366e1fa5a7f1b22e21933553acd6423d34c7191cb4cf52a95cd143769a2ecde4c4515b4e9cf74b39429c5cc541713705979aabdf6889a74cc4cc99b661ba59aa58f52bdf56126246223da0d57d88b9ca9d9f2d476890919816a99a9ed2c131a419bfeca4cc12268d3fd529f34611368d3dd6d751b37adde6634ba9ca958046dfad84cc526f008da745f7d65f1081a79aaab6e543c05d545bc122b067c44d3607908aa9294240bfa887e500dca5ac204e8576ea2210b0527b84159596c11fd20134abef635654a1fba4086146440843de806cab2628be824a5a01a280b0b78c46fe08217cc5083275e402deaea2b0b2fe0c2175654c10ada22da02da22fa4a9294828eb2946c11fd1a8f68dfaac1e288ef5b2a9873f5f43c18186bb2a5a2fd38696c0db656b067bed8b6a65a2a0aff542aee4d32c3e453d89358d28ad79561968c97d70f271d5178a1161476c98bc64b4645d274cbe52617f99738f4b3ac9a58403c66f34078dee75334f7acc326319f81df63225154c5ace641c0cc6839ccb63cd55de588c2774d2824126a41c5a7ba98c011852fa2f041cc54f69a792066ca9b33a5e379a799293833533066a62211b481ff665499666a5d5cfe3253712806a846a82469d7aa93a19a0499520acdd00c260014f31500504824140b87f34092f4f60114001088c66250a5ccd42009520819630c0160c0000000c0888c06200192e75718141ab9146adeac0040d82cd8f94e4ac651b740c65e5ae0949f25106b42363d968bc84a741d14ad537cf0c62367d72831d17196f1b3cd4e42f2eee6eed2a93f087191710e2b3b4429bc09666882db9a46c193b6c6c79fa6dc5d26e8ff8c76fe512f36c87ff419b27397d444047df38100ba6b972de7a517907bfe1458210433bcc7a380a09094ddb0c164a3984f63cd27f93fd99aff940f7879f46530337ef49ffc61b350c6ac94362b656671c959586e564acfdad2b3b2cc2c289985cb67cd9259287b16cbc7acd19572c86a66670a94bc98b87582fe8711df22e449f6104cb693c688c6f7b918d0c107a7d961cfaa0f37f362994158677df21130e9dffd0dc15b7f41023a480e99545b3a71c20b3152d26ec2cb2593f18291cad89fbeeee954f7cbdf0abf8f59151a6db7fc24f0b52bb9cf30949d70ad3a2eb8378262eb39dd8d2424d48259815b34bbef1179189934782e144b38d43d17e93d8edaef6933b08b769b6b3c03013cc46f0d9e94c090a5b9b9b03831727bd3736f462ada75ba3056df581b089e2a7c00d1d27d6255efa1b29a326d80db5be32269b4c481744ed600e9646905f5bf12a5bfb212cc4a079d69cbb2fac3a1757a66b9c092134b611299d6f589528ec384a6e9c6df8a2780294eb78a5c1c663a3b1ddeccc91e1508e1a79f60e6116a202e44bd9ee33ba07b1b98ac2f16874110d6060e7c4311b787f37ee64d70f5844192ecd4a1ccf4fa5a2d9759babf054102616e21a86e01aedca1f4862ca852c86e73ff5a2344e93ae4c71367082a49139597ff841e0ff4aa994e8b14b8836593b17747966e6bdbc85cc2e657d0b03c3ea416a29de3d0e12093035f71c3c82f40dc13de56edc674c66804ac16a992dcc75d81bbc778525b0aba187a371d251aed9f4c31d23534e49e4d6ea9cf0955ef494512e55ce324a097b9f737f6df8b7241209c4ca039c62f57f09851b11603195a028505f845d379bf46bfe89a3e9d3fc00f492ec4c73b988800aa3de53de72177f087dcb09dc46fb65990cff061d4bd02fc96cc60c2b5c428dd45390bdb228a51ceaef11b699ad4cd28512c022d807e0b3dad7ad863cd1b5f0a23bfc60704b2b38b9ad5aaf72f04ddc54a9370c1264698edb9b92ebe22c94b4c4d92571dc681f57b95f67042c40a217f27c741a945502805ce49462e24afeb0012442b641b16337aa585f5db64d0fd3bd36e4f40ea9405b553ab12cd9d2ceed9ee15d1dc7a377c7ae69c0b9b3244349bf0e5471e1c680a1a60281cf5b755d0535205b487c3e909c64f419bee9379432416fadbec327ea67ee98be8df741498b6161110a0edb5e30ae15d7f397a7a4b4aa9275494c9bec729e8963f2acd7488927bcd369d51116a1c68153038a5ec218dff0352c7058116d2b12920a2b3c6602b12ff38edad67fde2f2f58d52fceaf34209c65a3424eea52180fca96ca61a53d921da478184be0cedf5a1379403b4eb3e8cedf33f28dcfb9a06e10fd3f4024829e8d8ebdfb4118a192fb2d0dfd5cda9c01db14cf9e2a5fe5dff42ef069f7437dfb9158f088bb5fbe556dfae77a68f1e29bdf17978ad386691716439899f4104954c321ff523564dfd820409232d6994b9526b697e5879aa620b970be3952497df8173ea2229e58070e1210e574c77437affadf883e7dfda9f2dccd6d660097bc16f7d1fdf0808256febd04c407955e71d6de2ad542f0f39ccda6317a0d2e80a45652d9cd7405cc9fad04f55f24f726aea31cd5dbd863b5536a43e975183632ff7a0358f9d436adb7a90920a9bd3adfb1809861e4960ff8f6e48712ad75a594140b30ab7286bebb77750efacacf4aea404581967c01117c24756db5bcc91a0b7660f054d8036f034cab638d37dd6803859c87a96ae302845f7fa48d41a9f1be70815fbf6c1b9f943733b7c571ba2e32754e84262a36818ec3c4cc9278a667c558cf40fb03dcbf7a28deacdd61052447a70c8e7024d3b4c5155c2ea6e05712b5b67594351effb5173cee47eead201f6cc656a0596d6dfeb0aa37efe8b5f642886459967aa90faa13927e044567934846bba84f8fd243ed94685fee47aba90ad7ef2f782ad5d4c1c37fe792781c94d28405e8bfff7cbe98bc3511347c7e63bb4e3827f41b8210ced194825ebbc052e0c46146aa4362a442d996242533c676cf4056eb7a45a350c539c8360e784b9c455ff8ac1f9db960270cb00f25dfcbc1f4e571c367824ddd7b5519a24d9ff915eb3e87bfd065ab0c3a6a1626c05cf3c1f103c060e87a23352a88d962ecd0d92a50ac8f819efae5fdf0c3f77f25f7009ee41fcb93ac76f1c3672a560cda71854fdaafe2fad1a2cb6e42cebfb8a1781eb615548ccfaf9bf2b0ef6c56b18e6c4faa52e5b49b48038c8b45178af0d9ba2152acc7fbd903822b1e03dd819dd1f2210c4cb6f0573c2ab8c56f920312d1ca44d86928b23ae53e442397871cd66ee9fb0d1567cd7a99e67f81c7fb7bfe4841d924ee79bd8eaf4e216695bb5d19b3f89ed8443341cb267861f6714df57170143dc46712a6cb872b1187997d640ee763ca6daa8745e3b21e984335540ae4917d0c8e7056a08f75c5c28e2f867320268e8281401f67791950cdc0a9b3f3e30381a5f7c2884b96d54c76e439f1b09e40d6b348d51464da3618b5859babba6cdd0399c74ce4858df1689daf1873d28e8037086ba40f7db42c992ee9f8fea97e3d2468269f4456a510e83babca37089f7c3dce6f1ec004c49909146d9a8925dfc4d2c4f8d1026bc5a36a5e37aab9d46f41d4ad6bcabae9161689564503a30b16c41ccaf8dc36ce2020f4e040cdd912469edb14834b2df1596008d4c4a1648846b6525b97f3b75ebb29df4515d755f1e39043b2304140b2d95b35a4c97607d4c123bcc8ed62cecc013cda0b225192ea164169ec78b3eb79268d6a5b3575172d55d9acd438a9d8e77cceb86a36767f44efe858ce610f965f467e451d67eb6cda553c78e3870d9b91337f426f68ed6288efe8ddffbefd609f42b4574940a62593910f120f8dcbde33f64ee33450273dc0584a4c7f6048ab132b2317ecdcab650f7eea4e3444c92e00ae9f68decdf3fffbdf49f1ce48a7457cd039d6c5dbe0922c4c5e74fe3e3a5a064adfc066ccb0747ba1ec7eb3583d9857f575ee88a4a76c5bc21dabc4aa6f833297f59b5b3b1ea099bb41bdc287a2b25ba2b596c0b6c248f8bb5b44a1302312c7791ec04187d875f41730700863dc49b3ca847c5147bb35ec642d9010e69ee1049c50f1efff066e1e53053f1f60df0773b7fa2e0e9d54a38fc0030b4d6dff57d7acc90719f13a805a3624680517eb6c6448985025ea0bdf2001dbb369e68e8e60ddcfad6e47950581743fee60a12d6db49ce4996ec3f79c43ebbdbfaf224b2b825971a6ac60696976ff2cccee6b1aad0f8004387bbb412379a7c782778a71ecdbc57f32f4b81f21404d3a3c4826557a6fc6a3f5ab1dd54f84504044c583ff069926594236cae7138cc6e3ce9127852f0c91da3fd7ecca2bff018bc3c8276ad03ab9f53ab04452824a9556492f531534b9ce2a7bab636872d07025cc82941a628e6d07a9ff7e29bbd7c2c716a693c912e7f231930974314a5a9cd6fa5321167ce5c94274143d870e19589503773998692af3cef9d3300c60430bb742e2e5ded7861a913295102c79e5bd967f578ea2fac12492cff783468ad1d649343baeb132bc63a2a47e440217d4c0d2a99823d61bca4dc527cff586709bcc89a16a8e0925a9a98eb427e60b8fbb5c943a1224c04d4dc7c6cb367a4d9dc04ac590565fdce78666542ce8fbbe011dad179fd96d73a4f7a124af4700a9a9eceaa53350fd4a6e0464aa1153dbd72554fac4cd19b95a8f574254aeaedd1fbae584934bc1d4e31f9c3afcf43e5c3619cee401d9abd3408eba939ef186f32ddc3fa2e07347419411695af61824f087f64b77bba88a2d0fef9c284be53581040d56f05f60651f11954181fe348246be332334c7e1b66a8c6dbee17d6db37e0ffc5d842606634f23ae615c35db3a193f4c0dbc368efee733f399b1d339ca95f9b2a6343db153ebc63529c47a202312c5f522968493e7012bdb0cc2ecefc0bf3a46b23f19a72fb3f9bf25c93e79489f58bda461aa129bdd344b92829dac210d1646336d1bf6176444449c2f8e85ceb6997a580d8706e675dbc0bf7b02beecc8e3eb20539988cad28351e7a6b21ca244a121e29a7b50dd565722053429794ecabf02e18faee5e5474032cb12abfb71db29049df1fddffbeee59b3b6e90a010ea2bf702852905e17b84fd0ea32d7e6f9270b9e3a291d1298005bb9a53abf8378427d2cd44dfea086566746db3f882df668702dcbb8f9ab8daa9a0de75d417be115f4fbd6c10e45315c9dcdf28da8a0c73408f78c5df4023102fb9b7304842f567be186e843a530d9dff581cd761d741191cf67e4f59ca078f2226a349ecca8d19f06031bd6a8bfbb727b0c7b4c68312e99aa97d0f0379abe239a009870a23f458426c85e1d70d7304f6fb61cb726dee003272ed58ec54eecc4864b5f7f79730a537259ee4ca4ed0477881844a93229c93abd49b235661510e8920ae429aa9ba93f201a3038e6159ceb1c92383cc3c47a85209cfd5f3573dca4c15f5826598ff675156d4c48ec8b5d4c22b7072a5de67bb8844adb7e0ff651e934c0cd9e40af44a52612aa6764d83e0a884e2b2157d12890ff2dbb56665a313aa42a65e817d3e11eeb99a03efd97efa4435db3ee63fe5a5e506631f137d321714dab888fb55d2595dc05cd338e5340f0b0d59ac7057b4461cce8dd702d732d3a2a3f8e41861bd9403fb2309c2c630a11e91067b51c63e20ff669048b4761055a21cb30d1e8fcc902cb19572791465527e7988a896d44ad441e9eba48846cc13688f7913fed13b49100667e012bde93f606f0b2438fe37f078a86e3e844784f392606fa3df8970ad0d996f29bf65d3bc8dda97f4a4aa090d48251d9322b4c999ae083a1085b3098747819bfcfad195d8d00adaf14b1e8bafd9ea18f4d9f2b838417288a5721e35338dcf0fd41a8670d4eb076098e49936570d9e49312351edd6260ba6543670d42bfc52a4b7810fba1821550b570b2e915c9d9f8b4166513276bc1457cbb24c0a30faf847dd98d36b452f1b13ef1822de15f145e6ef16cc134a8cd3c63653904be82dcb1c9b064af945f03333b976c5caaf80661a9153c3bac4d2cb256306bba8eeb69ac37986f5c3047ab2dcf89f93e8aaf324c85b7925c201a67e78eab55ce72e7d225a3407846b9f6f048a33b2b8fcdc77462efbf46d2cf2157b8a0e518aadf5322b867e25f0d868934025beddd7eda4e308a48859e15cecfdc56999063ac37b3a877010485cadbfa94340f1fb7b966a2606b5a61804eb2466f7333d6ae44ce1bf2708b75b1f027dfc23594d2f0635b13d1a2811e85e46380403a90e7b830cd5194a404c7c234c1648f05c3298aef9cc748196f33ed3872265577eb36f7fcad7227264c7a12d9aab8a82f2eabd60213435ea788a6cde19962cef02f40d3bbeb8a00288714e4b77c7c930e3f2834df58c0908c86e130c980985360076bdb257d78619d5b2673734b467b16c0e8b43bad44066478d7311ce1d13b4dcedf8a8a7870bce30d0b016fbe2dc69d2dc299860e89a02f1697d1d2560ad674fbe682714b14301da87a791737afd766d70ec61902ee455f5e9e14b22248ef89b46b14a6863dff12cc23e84578e81d129e76cb960a99c773f22e23b510d12c9ccfd20b4dffbe4232cfa11d2b1a617ad32b75495595622b40f058b70579711236dd38a2c99b35d2f7089c4829024d5e736aab397e8122a80cac458c9585784c8f148b401bcd16cc238cbd9ed1afced50f61ee77c81a81da044e28a542dc81ecb6a4379155628a1c2499fa40732d2bbdf7cddd25ebe033ce8a4a5b6b2b8fbbfb6451e8f15c7a8eda041e118e60cfa17272f30715fb68d7ae75168504bac8ba40d04e4f30465d7b183627ce503517ba9779cc93f23a26eb3990a2106eb14cafbd10e7df2ddea0c24420985025f9f648c1ecb39c814b592e50f6606f0236ef4e289f77c6b9f601125320af65df74158c7772a79f740d973c5be7923c6f38f90d5960009d31a88e6e528e72b9d677a9231e9aa0e140935c8cfb15e82a0010dceeddfe5c295ed424866a794bef470ba6caa4e3742fd99bd22702bed6725751ae4f6c77e5608b00f7667786db407b7041ff70534176fc48ec0d7f917a32ee8fbcf373c0ce3772ef62815304e8c396f4e056a090933eb7c47534960eabc8ae36bb53a0f731f1fb60829f32c3bf281b863bbad49f0fe35e47e95707405f04eeeaf8cbe609eab5926c501c7681e99e542bb55d637668be188af2f1e848f63371dceffe81dc8d9aaed457c0c7d6731c4e685d48836a4e1368ea695e583bd1419ae2c271201fd01abad60a7f64c7a58b6352171beeee74a9c46ce031f106ffee62de837c1182254eb6fa4ed65bbd8dbe2d2a8e9ee183e2e1c702a34039eb62badc610c801fc38f980f3fac227ef848fcf059f1c3cc341b980a3cf8954c5db00b8afba486b3f470c40771d2750e0b9edaa07277122a3d5e39e3d09292a2a7fbd06786aa0aaa38c3684b58efffaaab456489758b64f6f0e5716e5ffc26cdcd583f4e8750d467eee6a85da81d64207446caf597b0df5e43b1183a377866af5e8224a17d7c79ecd1371aeb3646f9004ba5dd3a973aefb451a3ed1eee4292c215a85b24cfe2c7536fc19941f702fc9a632fef878ae83e635255ffadce6fb88c1834036a1cf2ddd621a6fe79e707515e144a1ed71108f9c8e6c9ad4ba8d9002ed6dd318a2110726de63b4eb28e13d760f168846294fb7e61f3c2fb709f8288b0ab2393825a2e5b343708810c099829c8213aa3cfe3b588ac346a240c5be1605ca037f9e22ff518c6597841fafa66fcef08c6ff9405a99a81095314abf64f4a4c1ae09af379009b7c90c0029a464191aec8af8c5bcb6fc5bcf963fbdf43a3eb8b8920a26270a733196b6fb49e1c2d598d6652dcfe8ac11df71c3a6ed57e3523f259d5f799a02b0c0108de6c8c73d4f885bd19cf76671a3efacff213a3d578fbd6fe6387d790d20f78f3d84c9c5b012c42a8d61aa9b87d936f1d89c4c790b64cc495acb5fce91634ffd2594c7cc858006393f2af01517540302efc949df7791fae3f1dc05a2545262987c7c0a2b6dade8869302dd58ac676076ad995dbf91ac7519493ef3ec76b70cd17b79adc095bb514c4b2bb3bb0a458ed171a29c5853b4b1cd417b04b9585b88b47f24ab9411313c0af882675e355e5279d746931f3f93e219db8de124e701f8c4e24592824647b9e68b3731f8026f22928ade4f58a57caf9fc5cf1af949830e626030d1e1878f6ac66b0da2d4e54c5bfc1b07aca23ada905609d18e0632341274c8ccd64f717cc4c7a1f3307ee6eb400cff1951f159f4a897f83c514f24e77aa0978fe726260895111170725b71ab1426de5186608a9be1b0f873b185f7404535e26ce7fd1878115476998b3e533b6d2cd2ad29f40cf5403ba2d003bd493bcbfab03d4f7929ae3c1a169361fb655e5606c1b6aa56e9af2b4c527f5ffa4d4ae9b48955eeb3ba17b0c20073b7752e697f69e6569c3f84a781580f654ea37f79aae6880d8504ab0206ed8004ad918cfeb0dbbcf020df12a9d0e6e1a4883aabeac89c1181233c51faceab3171a8406a32dccdb3704c40a2966379b2f0e6747373a6a0b426bbc109acc31e7c33d4fad8cae9655ac99a87b8485d4596e10975c06a8385659226142fb93cf222c80626b198350a2e4bfce5f4e413430c5332e4cde1c61df6b533c97b3ba851069fc6725513c850f8e0d19aa98f260f663501e500f2f65f4a2995c01d8c95eff29b7a5e03b6a6efac7cd87cc8d3aaafb2be8937b026c638e77eb94af606b0de426ec93a036c9ee3d90a72407558438d27f04445020e559226d81ced8b02854a3d39d8c1d70aeacc0dd3f15de293a84c1d5c9bea85269eec2959e036b9b9c682b77a3099036dea5d5d8bb3fefaa18e6761ddf07eeb76e8d3c8baa7831db0f024f825276af3ad8334adb9491162460c173b8ed0fd95fa6bb83946965f602584bff2718635e67808fb6232df392f94cce0e5f3a1d11f3c76eb6474978897288d360a46de64b6f0757518e24beb3cc5c31a66742017c5746ff1baa0eabe66e30d90cb51bad3627ccadfb3796b37aec43e4c35764c3131e51b0030b5e8343d3b5d44a6436f1552e529cc4258befe5d80251645669f06b1b732bf0b8d1f80c117abaed850f9136f66a57872fd67e7318eb87c6bd63e0e827e93c92bde25914aa8c0ebcc2a8a30c2af112b40e8130e3925a9ed56a2a585749f0a1d2eaf34bc82935e65ad2c468f8560ce55fd02be58ac8fd10540f285a2191b74632f7ec285b6d5733c72745acf891b5edb35c3113ac473fe31de853f86c3dd0a7c8998ca13eb5c665fe615dfd71ecf7d5822e67c0cb99cc7b7ff8e66df6cfca14bdfbe530580a53702672e0d8d36ac34538464228bc69e165248d92630ea2247b4723c308d5d05054789ff484d8bbb2263918a27a274ea7c89c077b9de68f38352f64da64404ee0f6bcfc3d775512c95d9a7ad13fa11a133f8bf33c5e53d10858a31a077a61503fe652849363d190dca4e609e14b2e4f06710d6c925cebb81d7aa4b5a48c34459943e4dca4c773dae2779ae4bba89aade48e07d228f261490b2124e3429dc24adab805fba976d7fb52e46917e09708475bdb61f9a9423997fb6a86f19aa7be8a100ff23c3cb182b7c7a81dee9874019cfc9cfe013aae16777e2594be929ab89a3303b2b8208da99bcd5eb6aa923641f8b7aa053e09218119b29cd32d2663a46fbaedfb8f876ffb45bfaa1e1d2327c7cc73ed2210e437cbced41c30710fa7498dfafa585c994c722913ac2250b629815b08ff44fa4cf53cd36e9f553c7ebbec326bddd62677b0485ecac21e48e6deb7939292ad896c852533df0020836c49529d178ad2c0b060a93a843d187eb3313aa141caab0475c5388ebb8f5d6bbd1cb5355d9bd73fd17d3c9c150c77bccbdc578037b5c1ebfa9a756cbd8224d1ce3d723c98149b17a0e5c61f03026522dc7427467d24d92e5c900322065e25a254cf47c6f8830facffa26846c919103b9d7a4d25304087106175c774373495e7552a8e88891b78e6305bff91f8966799660e980633aaba238e16b481f488305836c84f90649dff662e27b3fd1a85a8af0df49ed9e7ca43f8ec9e02ad048f4f9b424eb768c1c7eccbe5cd67d9742cc3df3c263253143697c4eb9b9ec49977416ba68bcb4a512e5a1e509a4709c41e876205f0cf3e1c2e1f7e59e4f2111dee24e71bf7db0f4086294aef6279028c090ceece3b83b2bca057fc673809f5492e2bd51e383fe6e59539eda6f9732a3b3637b2a70544cfeff4cece349575899d81ca5e17c33f4c885b97bad888cf09c2bca27ba97893535bcfb52d62bc6d5588070b0d3dab4441b82d89b663a27ad8ac8ad7bc01d7500d0d0d05fd53390a117cdb04ab3eaee11288c142f4267dcac248d83584c1f8db5b35093206af5b60b8337d1a7964e2e179ebbe1e13a2292c63895e42ed972406a522ef7917f6b3aa235069e68f3037775b4bc42af9ab8ecd78079b671830bee96535da090f5b2bc8cf22e2009ea5a87443d65c8f7c95894c03f26a77bb22294d8aff9d4544562e90555c4521a1b22965a58695fbc93864c5d6578a4b844b1e24f5ac89110af03ea85c905b0c2729792a28aad668658aeb8732e1d9c408f118627f83627282d23f129f0a439881ef483b8690048d34e9128805c83c10da401844e401d1d50a22a3687a60010608dbc470732b150a647bc35f040e8b8faa7bd2f8eadba7242b6ee0a27c0f40c47579b6e456c14cfc72fcc7db1675def40854a9448314cb7d1443a2adca1443122cc96b0fc0b64cc6456694ef47f50316e721c61af27081b9abb41091a9f60dcc51d389349a15eb67dcc127c695500b7c312a7d99b7c7f589cfa60a4a53f1ad55437b7193e9578ed0207be27508d4868135cf6b193c52564df87f7a57c96b08310497899c47110a1f827ad0c5b284360257fd96806c6c11019db8c41dd937840b49a31b9a04347f9f359e954f39bd3cb0da0f5625f375a808468cc7aed210b2cf261e28a7c4d3ceaeb83c449cefe7be7b92b343b5c0e9cc8f8b7b952208d01ad2383390526d9adc41f89f8c2b085119069944b6c3eeba332aaebe109b78f9bc95edb424928934d2165b350d0a3a797ef4bb1785e6e6b5419cd1d6854c6c83c3a5d54a67f74b7c6112f9abe4e299d42992a27a29e8e39c57aca38a1bf5f2f943cd1ed45c1423cd551f1654e3eaf2b1f221b0166da9740f62ab0907cde26292d63c24952edcebec48e8e233441d0e8e4723fd6bb1f59e05ff218b94b44c7210633b8b335e81611b8f2c39ef2188fcb625751017ca1d5fa0bab41efe190412bafd9f54a29fd7eb68f35f19192ea311c06a1319e329ce67927b36bb145aac19285f0b5d74bade49d55870e7d0d7dcbcef6ea5e338c71ec66bf9bf6ec83b97f243a08ca85d65ce9b6c6b5819250dd280c6cb37b81d4ce74a333bc0e9aeab1eeffa25d56f7cf524de52b84f74a2134ff0841331c184263ed1094e6082899f78c2139fc044269ae0092770a2894d78c289c604ce00a503494177cbf9f0845ce81d83aaeec4f33c0d6aa5a7b61ee014b0fe2b80437472405b2cd8f2c819a21aeb51761ce20e2aa81345c2db2ddf62318b74587452d69b710e8fa28573de12629266807482ab016af5546bd88d04f18e78b87ba388e49c5b683a38ed23584465cfbc8a4f4bfd66cba0dce072fa78be0b0b2be124bac32c1ebd7dfd0c3fefc92f97c1919e65407e74c533a9d3540fbd49056803d95a82524dacb516bde01cce6e9c36d032abe58b3f4cf9abc7b7c8f920ead97e7f81f8c531647b08610e365df1a25f89f58364e036d3d0437803060b4b1696113f8f28bf1bd1b4a5294130874f84fd99a29d180d429835f21042c92e0ff6cc7a18cc409467e491dc47cbf55f665994e13983188097223bee7636070e52291076de8df2b73592d8a764743f763470a4f81bb2d0674994558ac1d66a7126f21e28daf0f516d6ddaf48ee6442b4dfac415ba0bb9671c959a86cff8a1b93d056b3c78627aae2c9edfba5c31262053d518a101db8f653ebee43bbdaabecb86dce38291eaead766aa5a557e153ebdaf3f2337db93d9a2d099369cf25b1769dabd3aa8b2848179698f2678af9d8a4e9f83c55406e341cd375813e92472d2a4f49706057b71e28d92872291da80a05bb3a96f0c681667e3f1d7771cac88ec0781919232c43a4199a5598920cf82c8054e3e72cc0fd8362df0999ed14e1d9bda2077e8b6ace8021fdfc22a071df4a454899c19cb730b50872df41d3753e2d36e3e06ac039b2831260d09182f35a91f37627a47ce82f1f90ff24e03c8c3d0988d62efa9e0215a5784fc75e815837402e09b6daf932b59914013182a14bbe17cf919fe865ff722e5680995312d0965598643bda59f70c894fcd25252809d91936683b416798a3950d918272351626f7e85f191afe6e3a2e2939b3c9c818d3954bdc97cc544635b3fb823b0f3bb8ab8c11e2810684fba48da700ffde8dc97600f73e66c41d37bca584d1cff28c7c626f10a748a29ec94b913119233f6e36c04216e1007da6fde7925e4ac308562c5da914909c39918fe799e01a312ba161f5066d719c1191eb6db0a6913b75df92949b9fbe7401512c1eb2cd8172aecc8400297037f65121622c6998d1d0eb1ebb92f2b96541d37c2e61af074c9d6916d901d50e93f81bd30d2625246c273e72105745e7da9f70e039aef264875ce44aa8282a863df4d9c27306ffa36da61a453e00bfed27dad50a524560d984a393bb048034661c94c1a5868b10690dd1fe782e7509beaff48e5993364c6df5dbd278bfe791ddc59763588b5752c982aaaac931d9e5f2abbed0094102ad3aba38b17c27953cd25c74d4a1e19ad092a7f67eb5d1dac7990bc82807fb2026899fa68cddb73afbdaa07b0c29a28a8a5f2583d591a8e91b3894adbe3b0d9b3d57105ff49cab3d727b6171622efd21997033105b6cf097e513de7194d815cabd8fa28865cd3e9dac07da143fb1dc01e07e934712fbdf501b1125d10be3b79e34a0e4316803d7f085f92c128cfd0f44e8b86d64cb0080865dabc7ae552d37ce363bf5fc88bbf60cd341dc3c4e292427045524494bdc8570307956bd4e9effc2babafb53f1f77e696290c7c3335ae04c90530a811a92a1b60912a0c44661e0ad16a18ddcbfcc4e1ba4b77898b697f0392f8600a009107f88328505b4c5535f8358441c47e5fb35317477eb762ecd325bf04b9ce6f416056191fd061b1df9b0cb0c0ef4691d604fb9c688f617629f7a9d49690f8d27226a46ca90406c0e2619d31659df2768501618ffd88b12cddfd4daa035f3da48e0a5f21de786d6ed456c2f502b78eaf5dad95193d746072e95bf3e2bae4f3bd526f87614a7ab3ca2ac5a074098b81fd145d18045048687adc2aa4c3555edd18dcdf4848054dd31701d9a5174b831d7462f50bd0b67cecc7a11a1d5cd55af22882ede896236ee0e8820820ecc09bcc5b2314487e3def8d283610108e8160c24fc80d994a0a13ff4a08d2ea28bf511d1617693dd2a1a60b2e93fbd0a3764f91e5618588769be49b032d6ed430d74893aeb3d2d83b228a3750afedb29f437272abdc53e37cd52bcfcaec5ba8b9f13be15a7ac2534617a3642dd3db058256985345d870eae8bde1212e3cd8587d36b20a87e12a1745f339c952c18799839097b571a11ba6af4387f270ecb274ce77a3968ea41116f20e6e389c2785c0fa6311e669f01e53fa7e57d6d66ad9c1840820d5f817d240f548950abe2d5cfd2d07d546f208a3e49fc1a5b1582d20d8adf037e42417788df6bb8896660bc2ba35f8cf82b87574307c5533863c5d3af296fe56c3b6aecf27260c09440db2e75426d2af2f05d9485da5640734358e07405f572719762ac4859a30af683b09316b2792483933a219b8560f0e62946e660fc95ae0b764d8ee1a17e51acc2634c978655b778b45d6353c0ac51577ec9809fc38d84ce9f3b99a1b6a84fbdca7c10e853c8de09003554457bac6b83c51c856a572084578895f2a75a21b22b146287fa60b56a907f887b9eaea665f9f0bbd8968c32c539b4d485c2273224e980e16b47ff5f578b94011338a8e42b9560d71155ffc785138c882f2d2248e5b5752df194f8ec277b1310529e5876f4e8b454dbab6d5749a6deb1b4b97b62fe32d2e33b99e39e67d58790fd7998d81352cd48845c3d1403471f6a2e701d083973a1f50fd9e0f7f33c7247dc70d3f27f8531cbc4d1510b6fb2eb439f8c0e4bcbe84e93cf4d077998cbc8ca9837bc245c2c720069d08800641bb63baa1f6a39911f9f1386f07093aa83dd3b19fb551ee4f78a9e1141c32d6b8e3b70ca677e9bf8e919d4242bf98018128eff778cfb1b8db963240cc6663ac06d84090c013a97f7f34f240f54c48086689b21883aca6b51dcbac1f56910d95f8a66117a91c9fbe818af374be48709eb69b8754b9646101b5fbfe7382a4d0a38695ddad1048d03f0e6ed582d48597a94187ca682bdebbfc5163d02058b34429857fb668fbad81cc7d846222c701d70a7500f1ca153007dac7609b03e18d9a237f038d150def79d31d57794ed6dde71d734b8f62498fd229e63e751cdb70943b610bef1fb6484e5c3b8f15bd4eac9a7a3861a805c27dd7beef3c4a7da744637bc5c4b3c3514e30487b49385c8fc53f5ddbdafc87f2ecf8e8124eee6b131dbec470cd1d78e4ed5729bbea07589d97653d6b5497d0eec6be59a660b33584e948f3343f421e34f07e59195e95603103253f8315f181d62829408a53c14fa277fa7ba12d7af5cf3641b4e8afe42602f9836fc2f0e7f184573c3ce4ce98932024fa315e44581fcc7dd2db4825fdd006815876ecd2d2a66ab01b6f0048c02b3413f9849707e24b7874e50f05f42cff2895703549abbc1ed27276e621b3271ac1d0f4433ade854bfffc70d6d66f406986a413189c613b3c24143177fe79446468efa68a87b9b4d91c08e38ce0e80e73749b413da9e1a1b63f7065b6a8a14ec7af17c8360d4166b252c09380a7530b75a9cf832a45a5388499431430fca3078024deef7ff1db28db83a1fbe5f85a1e8ba3c9706328e26843dc8b496acec4fda5dcc0e393a9d617c9a246904f6f59933f4219128c5c1b254383be1c724b97e1c22f2e0318cd35df7fa01ab103c5f810f4749feec93779f8d84b931c01799996be7479abdcd432fe437c40a468cba87ae154b7b464f90afa49752aef4b64d38627111e54f54d6141ed0eb42c494106fa3d8d28759ec24fc2e6f22d1229614c90aaffc7eb47a00c29a30b7bd7a1264b1c5c9f8b2d45a8c6f558bb8da7ffd86f8acebd089536782f666dcabc76e3bc8ceaf04e68783e443a88cb3897660e72efbc9e6a96e0c2d396c995af996901454d793537bb5b41230f492c482ace5b453ccd28706379b56e1dc4ee86a3f270fa308b9293990629454797f4c888ccae58fa9e8850d50dea8a98698995ca1f575f7d497494518dd934864be439e717faec2497137aa3efa5be535a19f114bba9545a55b2634a0e87ba0f07f9b3763d5e25c4df4bc34501f971762ced18ca1f5f24b0ed6606baba077763590fac6d3f74d05e67a5c28bbf94e3c147454876de094ca89b780d86fbab32eb200afadde890c41b5b64cd41cdce45394186e8a55fdb0dfd8cf3fe2e9698298993a543ce42c65d29fd62607110574e42ab9d59c7b21c5b480f10b0ca3b6eb63c9ce8481d9494013a64c8cf612faceece50a4d6b0abc64e2e72aa27432730d89333b27abcd4113c2fef7e23406177a3ad501535db7fbef1e0ce0f19823f8027282b9c64048e235220cc24701647b26b4063a838ebd165716ba983c19b828af4c9815e7a9c337203f4c05efd8921882f68f79d446ecef745566c0492e49956100356454b7017213c19e2bce47fef570f3782a7fb625b8fc2b008c2431747f1f00030087feb2901238227f51ac4d481e1f7ff7f79a5f255fb75d67391762996399c3c65dc5fa0a07374b740cc43aa0bbaf4b936b4607292e6c1b9c801a48d683a1115cc43d2210bffd0be0aaf7ad3c3a8e9e1184c3bc97e3e033630fcbf9fe33b483b2ae49f26612fc016fab82f3cac5b0cf3dd70ef66ab428e05e675946de1665c1f2d6f9fb5cd2ed957c73a169b31a3954f7260effc17d8785500141f46f76c8d9f66ed3bb13938f9be2fc29ee5f2a5b1e1064c183d014ec3f5984cd783c9aec2be032bd7056a37893f71cb5db65127ca97cc81be93796f12e799e01016d89971fed3f2be22754214aaf2639e1a098ab5d28431a6528be64d7080c663a214b3f5b8ff7c3818f6e7b9355deda9fe220b843f4bb57d563e0a2c271c10d3b3dd8cb6f3a8d06be38845b7ba33aeff7b5c038a6b2e9307fd0a39f907e9a798a11c1955ad1cf03ace46fa32f3868154f33daa6402baf860ecf2b17f2f2234a6f0b92a2dd2f5c02cd8e908f9128f90a402ac599464d9e5c976c1037ff4b7e498bc8d5d007204b19a071a68122634a93caa1b995c27c8518754eecde92777aecee0757466dd76a5e73434a2b25c8d1abc84b33aa045d3670171552eb28202a6c740fdd578f82c21e45f57cd48235b925eeef4c8237fbdbb87614603327ae44451f973670941da01845afb4f22d1b87ea27d07aa33cfa1250c4bca30d0e958d52703e2eeccc61b18e46d1ded155d4c31032e23635e0355326693fdb8c0032fd045b8e974778ab272ce25e30ae4f60064d256c9e47010944808fdce052ad4c28a2368f93e498a5fa5207e66af9a5ca8b7326a12423cfe6002173ac46e63455f306bf06b4cf7835a087af012fc380e01fdd9bd1eee1e91a2bf148d5dc7c9779bd1f8142df9aaaaa6c466a40c520169b15f78ed207d992e26f5a3756f05280f896a66c49b3733a16ce6de79ba6c3bc9dbcfe04b5d2eb57a5a6a4ccfc7e1aa5f2bf9036cc0c96a8093b8b9669720294b598a1b100f0592cc6f5f974e9520fe90a2a39872d6aae5610463fdd0f409b247ea2d8a22d99620ebfd4dc2b16b5fd1c1000d056be8a8959cb86d38c6a29e0aec41bfd0810946d09b94be9302b6be5214bdc3a2e457dc55dc6d20bdc53a62cc0802c84cd07a0274125bdcf2492a00d130b21ef7e03cd108d1115ec23eb94e621145e2651a2b4a43f4c23e082a27c1fdd4a7ecd839525b52b730cd87e0980eb4313946ef6f368523f36d82f27e143c0a1093aae9549c3808a75089199e88c26b7eb15fc4d9e32671a5bd186d1c2173cd3a032a8da97bbbfcf132f814a50bccc09e3fee141586bbb36828cbed0a1bd456d1e7660e571bd74548ff01ccef30edcb019103a4ac62a68a423679316630624fc4a8a10890291c11e51ca3da086774221733532f88872ae09a541cba86225c715636eff96629ffa21de67e7111ab450ef18516651c02156a8223ac0da32b8a42851e78de31459b4cf2dd1ea01ea9ea33c0b2709f157b4a42bff406bf74ed54ae8e9198331fa5b00444ef422b70c1c71f99cd7bc0755a51ff4cad57290fcca3f2d5a9a8520d85ac68b5dad6912a231bdd53e085c56255896a35724857666e31f8ef3e9ab2d81ebf651e06b63f2a40a981b58764954ba8b2c6815695d53ac98c4d38555b86f5fb98f4eabb560ccb85da585b03eeb64a63ca12a909d71eb4dc591d03ed22563481c2f5fd983383ee77bc456d1fba79ebde0e9d386821c8f97b5eb617305ac23c3e10b6ee3d63ad52a5ec52e019139de3eeef25712b9137c9ae43caea53f4ebcdb07d48feea22060e80c3fbc376637d570849a70b7712d082e0169a194ceb314aad7f1c99a28932546907d99e3ec7f6ae2ffc5ee668632ce01dd538fc162a80017ca18aa7d8bab9440bbe4980d605781a15db0c63e8751ee5e5b8e20c493f0df703600d9240733ab51e7818f9a88e4056e471b0d796a4b572c4e99740df750ac5cc541db00fef41793d4a8a08812498c1633ef261759080038d8322ddc676c1b8d1f7ee42a307495aa4d20a38ca15720176ae70d5cf13d2605502d8fc24ce86f05e1f417904150bb4fa4087dfa0ca44c4726eda3abdae7a80c84e94c47f3e0fcc20f686973a7663a6264bcd1b44d0917e13c2175a8c7b96af0270edb13138b1d863c809ff337ced1f93a8fe76b73ec008450bc9edf4ebc77a94a26a956766b872cc419e438839642422b4129892d8942a21441d8a225aaab1283ad4899b73aa901078994884595fd69ce6485824a5d3f48ac347c7fa41d24cadb84bcb104780c3f9800295c6ec432d62b7105831baa9d722090464872f8599b431d53de9141a081ab20ae2886aca3a41ec77d5aeb2c4db3cebc21550de4978dec2530e1a1f59d191214a49c87367cc773ebe6445d80c634be93adf5ea8bee627695a1373b683442f64a8a96ae6416f28ac57148e228ea71e4fd546e15980cbb66c2ad6bf3b297f6e36aebd815a0fcc68f630e9830815bfe0e0a68e8e0bfb58eaafcb113f9ca624a1ac5e9a2621cbe3d1e16620db581274b96a269b8e7e17ca72210105d863c4b9ed0bbc1a9a1bd1f6ad552592f89e06b0789d004a54a596d7d33a11e4a839ee8d5c7ec612af3ee9035e651e386f3d9c0344888aaae5207624b19b8582279cf58766ad8942574b762d559c20b3df2ce2dd4cbda789b91742262d605748b71f5a4b3ccf0a4b7b3c3ea36d0450a51fea1fa00ae007cdf34f223f174c8c1b3d1b7d8b57b54e70a7ed7684cca7802241427c6e2622387544a57de7f120c59b0af55f60275ed6b6b09ad870b81a736743a20c694e0a44d76052c927d57c41bed78c7fb28f633ecc7b0f14ac028a431b55590fd654519357fb669c0f1ebfd0661a3b47b3a97db2539fcd0b1f6b807506131f375219be4026c20df8ee6f1ba0c5babc4bfcdf72517aed63137f50dfa670e0b1d68e82a6a51e6ab19004aeb35e8960845ac8fe4404220553ecb085f109bf3d2b79caaaf2b5ee10a21c622abfc3d1b6cff5a8dbbb8124f11c1a352c88c1e1bf0bbf8b2d24476c560b1ac6c2a5b6e06922115dccbce526d64f101ee2dce9b69c957d3340f7fefb49a6de9cacd6a34a608531332f165b9442dbb0f62c17f252dd6be2b4ad0efe2754f8c15e959e8f7f7429aecd403c18434927a55ce2bfa5de5c1be964c1f0a43e0c28c0c055f1236f33a783b4e0f0f0d6c747c3889977fb148d2cfbf860019f04ddafa763a632b51fff6eb539d974e3fa250ad0bf3e7f7c4dc637ab02cf3a4201cd831570a42784def66aae2725907ed697790de42a659afaf19bfc35d3b829b78317662d70bc90ab9a08f373040fbdba3218c4ac9cf4a714090d03f6fbcb82ee6d80f0f564268ff6305440f08a8e0972d2aff12e82c6d0d333ec3d1325c106a42130632526909adf5c2d843381ea1a345c0813770c71f54cce80125cf74f3ad0d5e76a9f20368949c40937b937a261a82c7a73c5f077c1fbb791a0c33529f9467efb8fc0a4cb65dc83bc1dbc83a25a0c0cb94ab2331b92a9d3261764c5bfc291cc50c84dc9191194d2ebb0cb694914def14f7ab7bcd6388c12b1b34de36ba70842b78e0e5324ee2e0a50baead4f05e0e8a292b59a405fbaa1e6ded6c0b03ed959789965e3e4c8ab75d102a55c065af25a7f7b2f2d5b1862f894db6dc902151a4bab24e4f99fee4c332a775f11772000df22b8e114f7f2bc9b7d8b99832f0513c64c99c696204dd55fbb706b2fd1c546cb0e7ab1550a7209475793b38508d864284c6302a51b89c3c7855a94ddfe878f55639b129bb498f3682e5315cd7839832fd591d92f309892e0b9d3abbc492b0fd9a763ef94b077bbdcb003dd2902a3c01c8b2502af60820b07601ff8fe714a27a3e4a4bde3815ddf36f2e2257d224c25b96c75cdba19280b11ae123a808cc12cb0cf8876379b793d96cee646cc6173134006ca3750f3e09ca6611b894b9fcfe064f1e4c21cbc53c454f98e9813f2f859a314d9e29f36ca18aa3c86d83169dde83001b9049774e8643e16eedf796767887e62a3e24243c63b650f82106721359c8b379a751f6a4191c9ba76a1232196bb2ea71143f00323438e917f576f16b023d0e9f32608ee636869f90cfdebf39e1ed0cc272d02a198461c0926c0a58385ca8924fb90245b834ff4055a3c8082fbb36b199dc0f025f37134d8b2630202ece3893c1860227131363f78d06acf4f502e713cc6663dd69e75f17464e4c4ccc547640853229f1e6d04d96c3aba8211fcfb65da1acc2b3d70c9a0a71fff26680436842cb32c65ce727d6817f325c734d2a993ee4a2ec7df444636fde9d4280b14d424897cd08388cc254f7bca9b7d916e0552eb222c28e1f13379a08459c99320b5131191716e2caa2f31c09237c8149406d6340a0626da7f4cf1589ae42a41c2a5aeaf65b4c0f4c45cc2ed1db6277297dfef211d89b3fc760335bbf771644341d4c628e875dfb53ae688174b567d6dab1a7e9890e17b275216126b44ec81077db89a5dc0e972c5e5ba0e34398ae543de88caaa7f8e73ca967e2cde27f1c91ffc55bfa51bc144ce2dbd726b08c996637fa0ac872cbf68106b9d0cd30913242a59ae5ea58461ad59179a1b49b41e7e8c41d38f2d792aeaa1e3e3a4c3974e02838dd8fd3400335b14a5491e61d3b1761ee1c92eb44b6678b2045ea13d0607dfa1e994ebb5351ac4f61b4b11cc26014d3d805827c62d7464e880a04640bad9a8571e0448e76dc8abb1196520dca4322162161ef1aa110cc2f5d2188c50de6bf8b77095ab57fb385be2d1bd9e1e11ee0bf7c40834a98aa414ff64d86a083816ec969b3d4e12df0ee60b42d67e925848ba171b2810c87598fb1bbc966e48350252a6fdcad82b681686436b710622c7599beeaf6c368a41a014e1afce566f5afd3956afc107f17f14f271aa3f929472ae2f5938d5c0a0aa81d84e95c75757da1899b17cc8a224796c8c0c125f83eb8678044f3569851f09b719f2bbe534743f8599b274f30706f01823a06a001fd9b7dd78e2cf4fb3c223050ed0846381b425e7b81f4dd73241c96c91769946a185f97c5ad8ce24c6cb84c274dc6316d3b2ade3bc05451899c0ac845287be33504788a8530bfcd5e48294e0cac40b76de38329cbc739b5a07c041400f8cfd257f24080cb2a505c726586ba9bb13800f4f4b2b9ede37994d4f58e936b931436ba081e5410a3552b31fb8af346a76988aee00c4a6dbeac74718a1f537398722044a42765698e034e5e35592e206152cba95e965b33a0cf1cf927c16b813f0151fce26fcb269c759c73763bb4ee3debcc2f8872e2d5193dca8fd19aed09d37c0cb58b277e142cb42b79321aca416b434951fefec851d1ca1b7d0b944176c6ad127bf0f2318ed5df1cc77071dd1684ba19fb1e05ac9e044bddb9520693a46d9bbfb3bb803f229bd76876b8ac63aa6b90919fb8c2cb71627b07eb09f274d676bc7f7b7898d6eab028a219ae8a70f9e1ffb7ac763b189fd34f93af2cabc853103e61601dda94bbf4938ea093470443143964f0fc7a9527ba3a625cb36e57a168456cedb6a8cf678c6118b37ed063f18d2b009bf83ffea8e2274b40ba47c4b2187d16dbfeaaaddb8a463559b253eb23f442c67b7791be6f478dd6f54c772a2b4405c461d855000a3437d6a51fe8774961533f0ddb7552ada9bd71a21717614513a84875eeac625e9d520b98b1acf9693b332567b764b2eae1cd44817e41b3617a5cbd239b75dac6d06d94407db3ab71210b39fad765621f9aa9fe35abca2e130544f5dc5264f1b40ac18af2293a34e1e6f6a0681614971e6732ac7ccb9e8efc4ac98d02dfed33d9298c1596f3603eb730f31fee3514f6c74d392b8c3429d4b47b0ecf5007964428055f2a6b29a1c44d6da8b7430909523f65424e8f8c7ab3fe061abbf89dcbb3103f3bfe2f6083b5e36c826057e0d2d0153a0888d92dc2f6d01d2451c67955d3bc2e7a1ed3c0dd2279a228a0f21f58e9d302372515ec7064aadd7c6c62d7bd58d54cd2ae9ebf14242aaa41f49c36167a5398a6a8e4295c699bce090ed03d917cd0cae63a9b5d7b53020ef7436dc7659083b5aad5d76d01b199b0ab134083282bc70ff3631793438159254b7bb154f9983e58a45060ce846baf131de82567431f6cc5da2368b1c6ac445e08260ba1c40ec771612f182b2c9a3bde77db0bfeca98183061418a8f583d0a0fdb13943020cf89b86a13a2137ac3164a641a540fecdfcafcd0f7121476dc0e01298a854aff919905a17ea50cb28b2e07f01fe98357fc343591970819a4507f1715f69e1dd250c799611317be89b9294adaa510559bb2f57cff0e001fc70d36aa111034452de0188482dc410e0837ec26ef6ee8040dd00c6b5f16d71291bcae5107155bd33e4a9b00e809e064d627a0740e76441e6ab0ecc280c1d7d70e51ac422a8557cc6baf01865e820ff629d43d19889150dd0ab7977a0e76f00252830709ac781f093f74036f6031e1c160382cb0a81d1f6fc87fa2c0c741b079cf73a7624e4f11a3fe9ab8e8316f19030d2cc7f397d8a2608e9406364ad0ea2ae3649603190af03c572e9a5814690f211cb95715983a18c3cd83f9d05a8a26df205359de0da7aba27cc4c330a61177ed09fac0b234c85d5427caa690b824c267abf69ab649f0088124a850cde91b613aa49a72c0e37e51cfe37df068ab3d652ffa9d4a7cc11fcb25432423ed31a2b4c2b3127a6c94fa0a2d264779e3fc6ee064d323b3ed353a4f5814cb6f378511f72b58767d200db142504c7f9e08e90610781d8e6632069f0368bbaccefaacd0955cf36af09d5e67ef267d520cae9cca0f6121c49620706dfd250925a7b87516179a9833a05aba823dfac9b518df33a7e67cac158ca93dfe048d6601b3fbadb3c6d3751cb0c0ea32ea2a85cc0dc14de1d2453b2d824f2e08a927b4f5e93ed5b6cfa77c9db830c10af6b274d1ca569a6eb9ace309cdbd6b83e5a2dbcae43c1bfdbb402d6dff879e81d6d0befe6c7411bad94974101aad49e1af719381f92e654cdc7bf8360df6f832f574157beb08016910c95e8658a63afbe4e5f58bfe46e50d3bf202ee6d1637498eb86e41a23fce20416bb5428bde025a2eb315c175597241a21db3db1cfb8aa6b092676c785c888d0e72fc66c88d7dfbd96fd8042cbad2330e7ffedfac0680f0f9d2e20ed979cd2fd5ce128ac08aba3637edd2dce34f862cfceef2ffcad7d2b6469436398ec8dae051e55fea93ee486029140b2519c34e6da091e8c1897664d4a660d1061da352c9917cc6fa3e17faf83d8a1c07590d64aa984266ee2dfd2aa47c7b1166c42f6136cd49b3ddd88a9843851c4413ec3a010c9944143c6c8970e76113d46c4f85aff493433052faf4add56c6de8a1fe8e662a45e0a9f69411162863df5f0c10ab79ab643f5a95df04b06fd4bf21f31278a71c42964c90b78f374410611e0cae4df7f336b066491fac398cc06a338e69ed92dfd5c4c01ec08b730607f219cb393af071548b2cc1e9a30da70933ee0e555e759c946d9a0cde644979668b536f75778162e459e4b29211f43351dbf83575cf00601fe6032a720d68d156afdaf0b6964a23158a30b707c971d81660a76f724a6c1a5cae362137ec984b10e8e20657f7390af79ab96339a7f8e34c75619592753d5b335cacb76d695acb33bcb251cbcfd0d37c5578c6e39a10e7079427cea7e171e3a84c81ab78122be2f0f6ad909d947a83a1c07b86a7f7625813aba8daf35eb5d5e13bdda6f4a580667c048364d8f4a8cc2ab5142acbc3de5df84113794bf7851bcdd0981722d91b682e61e0c2e66c611114a0e33318dabb0de16fe70f8addb07260b582cb83d19b6a4cf03a51df92a82020ccb8ab4e4f09ca30c32c874560b50bb4fd18c9050114c88e118200f40699d263cb766f5f78402fbd6164381eff7cef12c1da5d4e550007e889c4399402c29f5aab1ec5bd638fd2a00bac850a00a0d80a508380d7059bc3be136ec021d9bdb255aa187ad97e8189e68b92b768e33027855a10bade442a012f6ab873508835d7055a9beec105409e277308b8f4d8a300018bb84940f892a432b39312dd39bed2e8e03bb9997c5ca2a6b078c6ddb5a7ca93bf30940dd943a4a9e49ba57ef03baea60d39db7108824790bf98f0dc273357bbefea07af417bc463ea1713c42e0870e335e700073ceb4a8ad8581165947aa82d61f1f34f6b1ad0f0db1654341872265d1e5e200d2f044ce4df96c2776a2d0bd1c2a0fb10c233535cfd7a209a573820b2498c6631a5b8d104819b852d91e93b64cd2268878d88940839d9c2565b8ef4f12665ab388a33824b8c3cbcc68a7bbd87424318ed5538a8f6362e72acf6b4bf24f5108b5f4b5f1de7ce24dec63e48023b77a6c2ed308878cfaf94c9cd52f0bf12db5a0bea5898ad9646c4aabe089f26fc24c71013b918230d8a944ba253d42bb80510d45b7b41ed4d0a164fe934b082839f064cc8bec59211fb4d3c06a00a094219997f01238a5ca20c9904832ae688cb88dc4602112d8c0823e754db640cd8bdc12d9e024273291d7746d8616b33a8661a99f27a19fdc19cdc58f50993b06d03d566baac452f13f172b1686988c818947300e083ba37da3802b174284e009a39b95010e6125079df922dd3909e5cb91185c0a46d7e76ab71045e8c6a914469e2cabf7e450bc4716adc33fc1ba9616baa88f2de7bf852468cc152d8d979acd61376721d835cedb66459ac4f02dc29d54e1139b67e619905f84ac4b2028f67e3bd410fca76c21264f82534bfbe116c6e4b05af7e51fcd29632b047d153792970647a57e5d17447e03ec43eaaeca030af7ac165580c3e930c6bba6ff76c76a1505aa30dc5ef757496482a9a3d0f09b4d1c6530fd40180457200401880018493f0445acbfd8fe2f5a260436925049180f3651e09a702922f2299a18b8793be45f15f2be44b6de90e12c759c34474b13a0f9a20e6a624ccd70d2441e9f38a8d9062b9927cd7faaa0e655f3ac3cdf67ed24448354c0fb4b9d64c5d7bff20420ca4d483d7af630e5d955615928c0309d7482b6fb46fdf1fcfdf2f7bd571c76653068909c23ccc8db55c6c1562409eb1e3177e189b4700eb1ae61b5377a452232ff51845ad0c01b81a5a3c5f7e98272d5cf99610da87e988981a27db219a573d3b0593b9b1952c490b82db8ebc784f8b5dc07d7c0947d9572aac4458299189fb28161efe0b78ce50068ef9e7b8d808a3e729b36d35a124a17598d885803e3857d22d6e8aff5054cea934891e6b25be426e66533a830ad0887c1e666291920f0c4de65660ec8257f76b0298e0e0bcfc0abf435f04b543560c94d2b2d6db20a17d0d506db8712dbb28e9f73f10659b9a750437b41a476751aa1a6c0a4c3eab06f8f3dff930623a61eeeb6c4547300b5196aef2275102709bf86ac757f8c5fa9340eb796638833aade9a8466e8d780b69cfdd3fed64b08981d912a13f5970eae8b78dbc6616829671bea92dc7bc5560fe652788cdfbf3ea69e8b1699348ac3c649cafba9d99a024f53ea94608085d8b36bfec1e69e284ddabcf3577c1319e34c8cea58ef8d2facd7097ddc1ce980479282ba6aeb2d6921c9075f9e2b3be40b84cf01dc1787e00b6660a60d8a0dca17c8614a8f3a009788e309d831ca74285b08af0051df84089581992e94d7d700c8573c38ded9a4f9961d674c945848d053807030c1744ca5fba670c5025f4c952f7551392bebb18733bc733b981de9a0ee7c2114fd8f1772dc70d88d8eeddaec863fd676639fcf5122420d94bc2aba40a4972befeb1c7a2e7338fc88a8a084a588abacb6c84f14e546b52617197879038a9c1c6f0631505c36ba3999c46e72c686381649bc9ca5e4ecebf087bc868ec0310b6b6514ef3b4ce35a51843acb4b0d73951086d817196491dbb256ed0251b2c3002e41327633f585af0fc19c6de6f7573e806f90b89649170915a4755bc7385ae145061251bf58aec829a10617fc0d41a07a84e6bf282833c899ca9aa4bdd0844b0121d57897a0973fb8f3a712ee4e75d0efbbf5d2afe869b8de9b1523b6b8d8d089fcc710ecee42313cc309b9deba19891fa8483d24e0b45fb77495dc87fe8433988461fba88719b420a427ece780622180d5028a37cb04baefde13262c244e49a5427819cdd1818efb24f6cae7dbb767c1f7a27558ed131577e67ec9f5072aa6b306cfaeb1caf4810534303b4f57763371a45248309bbf08b52d076b086f649389f66064da0cffc0cc008c2fce9c7f260fcd25e7052551ea3d43989248282b9f1bb964b4cbc2c5c6ae684cda308feda20d6a0e0607f11f056df5d971b9222aa825f8d42d5ef08df50c2fd548192a9caaf2daf4c7362249129d54ae80c7bff1ed9ceb6ac1314997c69240a6aaf4c49c2fa69ed01b11c06ad716f918daf6a0db5bad4472b3d4285ba5c0687179cd018a6e0baab11d86a988eadab32d739de211bc0a92c1148207576a596855581cfd75245b1493e2ab9b6ceba78d7e97352f705834e015fabb4a29cf3a267acb4d92265f6fb20cb15df709c9066e514ff9510744f1d9a22aa56a70e0bc82a02042c7a07d9eb4998f9b6e931b846e30a7217f6d0c7f44b02336e1904609798dc42fb937d78360b207cd70f03c76f8d7d34b6038d90d2effb5b804498fb7997850ce5410460c9ad0e2f1f2134594c03b01a59c601f60028007b309cdcd01bd2f1eec2bc28b191a5c7b7d7e74c3e56bbbb3bb9c3713ffceb990aa1cc81f2a3b567cd0fdb3a1973ee77d938a345f58390ef0e8bcac6a8b74a0f4547044c9669d4b8c7143f4f5c523260ebee458915812590b8ecaf0d0011276303431a67a25c466ae948837a6b860abd12314da3a2072937a814cc6b78b8daef48a64029c10694004721385c1eb12745940c223a5502901eeb252c9a589b33735ace96deacc176fbbbda575500266bf53f7d54ad1856c1ca30fe861b194a438bac13c979d2df87e86a185dad597138c3edcaeffe0de1f26b172883323897fc724f81f53a291dc9e6fd2c9fe81819aaceadd338e79666eaacb6bbf1d6cf8becd5abb6c382231de092286ad60a32405d14a5d3e1936aac99a10dd8f44d79b871d543fd3fcef95f6607864920e02abd7ae0b8edd4661afbdf685631296e7b8f6012e053f4bb71173d937e3e4940f09680fd9f8b21dad28caec41b163aa8c756a056e5591292799948e99c8bbb04bdb309d80852554560932b6384dc3cb2deb4a20e4f90e9443f29334b34994997944569433ef331c91e58a17a1111008b55686975eb46c4a6ecf9afda9178d81105b3779e662e647868c2bfd8186d3a814f3bf92069686c4088faef399ca5102c1cd6093cc7526a5c8263768b59da1a612ab00860c2f3bb336b9c3090792464f0c2378e1715775c9bc65b4fed95399fbfd38715a50db325bf740c24fd119d3d8b86d4c1eb8dba17cc65562c26796d14eb5580a2222fc595cea07346ba6425efd0d73fdfeeaa8b6ebd6959ff30adea27b289d2fa5b45eaf1a4df11eec61b80c0a211fa5ba7f054dffd22221d65556dd0e7b4d5745c959ab6c480ae8ad00bcc05d679d43d1faead3833b693e3ee3c3fd0d4ca95f341e7d6e7b194eae5b0a16456c3c2ad47cf132d9b70076450fb35a944ee0e4e10a0864ea1635a53fa0ba926a591c7a08f8c3259748224b449a9ab5c95a8f10bafeabd1f75276082fe04a00c1fac65066eaa550542b5d26ba7b505f0ba879ff86c3910471d643dcdc702d79e10be7ebb22796d655672c6dd7ce61662b9d4f04d2bdd60f479ef5ee78b319bb326b9db56de3ee8efb2ee469111aa2ba8b2858c948f061bd740fcfe10ef7bc581de296c955470059157b9783c9458ceefc6f07b1e70be1d4c40a147887c1a9615016d394c272153975e3838ab897918e0a63e9d0960109b6bda0ce129e4c78f1ba3b84e3bfdb266e8eccb5137bdc108bd63bf2f9156bbb1d547875976a121e0f3f8c3a5de7e52d15f07c53455987e87a0dee17b809d7570003bb31483f662d039d5221941cb1c877d46836fb217f1036f0745fbf0612e6fd0121a1ed8a07fd6f64b870f2f4a436046e855bdbdfee7663c598d5001e7fd8e17d15dd2bcb29dd8ec5406059fe695638b7d364788e7aa46b712061b0085cf8a4811be35b0a2cf862c912076e914f1db010fad0f60c1fdb9098f9481f5464d00cbbc02e6d67536496a08a608175cbf9bcdb3381d5566e38a63ba00d92e77e1504fd811a0dab1d352614c9ba969854f7d7a403fafd96501799716ae12dd0836e39f720d027f03b67a99e27ac9e702e80dc3292bf5b965f7bd1e28fe681f574bae0367a545461d0aeba815948a5911a6cc255b8920f47393c5008a2c5768df1bf57936908481e258e108154a602ee9208c0fff8204e7782d341cf7580bced7dd59a41020b9c261624f46f315c59f04fa5edf849b78fa39a35909e4afa9604c0c881ee406a98954fc16718be13d6edd3f9358ada1dfbadaee03e9f086176612cd30e001e4ea91b821103acd6e6af3674cce72ee4dcf9320a05ae7a88f37253fdf73b8fea65e950dd362432d279b4bf378607874ca768ff5795cd2ec7863f4b13416f850443fcc010a96acafb1f3f44006ade344ca3c295652dec56e99cd18002dd7629bde77411593dda815f1254991d357b690f61932c1df3c0478b8f67a5ba0383a3fe7c3f475010614eadcada48a810374edd44bdb4d82f8cb5fcb8ee77a092cd1120cfc0dd3d84e7f743c6c6a6a7d6aa4abe91a73ddd14d923d99316f4cfb7c7ef8b28318caa7c436e7bba51a4c7e855cd9b70dad1cd4538b6a62a6e9e6d8fdf17416208d5f9e6cc7674a7088fddab963761b4a3fb8b744c4d55dc34df3ebf2fa2c472aaf3cdb9ede84e111e0faff4813e467b7ebb488d4554c9e77f5b113ed144cd8fcf85310d4bf5eb7eb1fbe5406cbbbcd673f1a9276d067704b9dadf9564e8fe676812cbede18548e9372bbb0ecdd3fc87a0212edba7f729522e4e7b62ff3b0c1b09fd14df6e91721128397419ea15178e58ad5d9292ba87e2b6b8b120567df2218d4f7f21a795c33c68d23bbbb1bcbf3c331ca007818f24af92b01999d6c8024c8b96408f1dd83da3cf2ca6584aa7654fa56f7a51765afd34ecff9a16582036ac5c6dd93c22310ac481610dddba68b82610a68c779ecdd3150324448f3dd65d27a65057681f1e90c529a53ae5db9cf1f24af8d05b1b59a1ce9ead5b01ddb345f9f202e33e1ee08b949edb7cccc9800ba2c7be58ff78e89e737adc525f7a6ef1ff2dd87fb795e20af4f8eeff3a98fb63a07515e4da398463ff7a454757c74dad5564152ad34400028c2486e88551edd30eeb283d1d8eceb8cc2be02e7399e44ade593db777ff22914c98b302c4049a708b4bd34fc16fea07d99f60d7728b53d55a1da49c128bdee006b2084b0c9c5ec51f019330fb0bf9cd4ed3a9abcf01bcecdecdacf2b442addd23312be771dba6542216e49331872d482215dd485e2afef8d49626f4ace4511144fe829e67159de78aec5b5f71450fb223e680da1d04da43b4df7fa34e7fe1bff2aeed1b480c19a43b197d7d4ee8278402f52b4cd84b0bf430db6ba03fbb98fe242d8ce979a377a5c75191ec551e9bea464151a0789cb0d627e6aad46034843472f1dc7901bd956b4b5bcbc2bf5f29cf7edca92991bf25846d755329f4b51245c0707d116901334595fcbcad2acb3c61a04ba3b4d0deac5b95b416eac664e0b131ff3cd5fe99e96bf00400a0f5bbed20a48de65aeb8bd3ff8d613400bc479301138d98e446f3767b117c50905e5a117ad2972c8d847b66c24bed8bf0bcbd82911fb0d22a0bf1c635bd277265e2e7771f625f0ac7339d324b41e699ebf941c97856802e539b10ee7f3898f971206b2e42622b4c23bbd5c4e8d3042a42e11041deb1ff8b3fb0063fd93c07ba727ec7ad0f0a35695eaf0b128aa82395014d35c4cf5a5d253e8e433a72ac1b94bf28d543e4be0f351a183c442c3fc45f350a2c217718ae6384d63150b858350490ab4454724c61a56ad42f77893caf1d0e53b48d62f3056912d9ed1a6cd9c891a6b94750288e6d9606864593e79911413feac009f9883453038bf29d2e2df29bdd482225a028d712df4b51c0df1b4ba8c2f0cdaaafff35442cbc43294b1392ff20d0524e8837f4a827c6bf2ad0f6f212a75ace3f49060861b0c4b7f7c4ba3b37cb0f812ed30694a10515cc2dba28d715e48c4a1a00759c109c0e1827ba897b6a3453cbee091b7b1a4ba3110d3e25e7ab9b0d452f20bafb78b0add56c39cf46ca32fa2d04950233bbfd75abecf0bc81ecf3df349affc00167cae61e456e23c7bd285fad77445f199d6ff43539d4a8f6b5acdfd1204d1b52b0318a5c2e8d0459f68f9f68cd2f70dcd00774b77e97534635f6b7e3778cd16cba816f4cc640fb09843df53d8d5bbe7301eebd957d230fea5cf5b5722de42dff92fc1d1c83ea6e96a062e9c2b088352d94b1d82988e01f0cd6fbcc5d8084b09938ff2c8961025e3673c4d5eb376007cdbff3c7fcdf4cd80318f9c9c103a3d4a29743cdaaabc0975f3a1229f0678238de2cd00934091ad8a7ca2ec6913e1aeaa8161c5998d904854173b48cf47afcef13b08b866107a0b5fc02d923b029502582162679f5c6b5e5060db63dd466cf11df7b5a7b01f21b9c488e6eb44e3d20b8e7c913edfec0ab19029ff1bac5cbd0e5382a413316c04273c0ddc7aa99ffa2220de699d60845900e2a0aaf21d999c5af44771c040f968802904c7e8d0fb4d1a998ee6c90e95edbca3096642824d3e6957b70f388f352a3ea2c94de3a501a5f104e17735ada7378dda5fe09d20c00fe8380fd91f252f788c8ae13354d3ece7b1ecae5fd41ad6d9d4f0a958afeec2d45417229886af658109fc80e0975869a076e1a567db8729080ac18e446745504ce69c4670e5820903a4e3a543cb6807777c6cb8a82c75d69c52bf96377bde22dfc6ce3468c8ba22b5bb26f91d7fbe6d10575546dac8ad8eec812f9e1892bb3325904f3b198621fafcf96ed0dfecd10fd476bdbd41a2144da2684ecbdf70e350e370f310d663cb1c1ebf57a26d27911229dbbfe523db78ee2c183c733cef36b67674785b356c6d21660b85cae67a2d68b10b5ae7317ead9e61f0c067b663dbb5eaf170ae7ba050d9414a1a3a3f34c64f32244366f5de77b569dc78e1d3b9e57cf3a2e97ebc379ae11c498355aadd63391ea458854b7790b67ef3c9e5187e5e4e43ce3e7968ece5bc8691d1e384f2a32e812c6c6c6e69908f52244a8ab6e837378d8f3f71d373737cff7d9a6d57a0b39dd82e11ceb90c1892954aab7a0d3aa67a2ef4588be9cfa8e671ecfc1c1c179feb3cac6e62de4b4cd0e9c91d0d1832632a050a867221e2f42c4e3df51b0dfb058ace79e67944af516725a753a9d900491c616b3ef7b0b3afd3d13c15e8408761eff703efde679c77170265241d7ab13b500f6ea2da07af5ccf3fc9d4805b451276ae1d4a8b790d3a8234bd638e3060f1e3c9e8976bc08d18ec3ce03e739e72c168bc5c222e0e0cc8232696ca80283c19e89725e8428e73b0ec339bcf94a28c6e40a6488638c3a76ecd8f14c74f3224437cff90e9c53673de31cff8831c9e1d08326dcc8c9c9b9790ecee05dad562bfc63450939badcdcdcdce07cfa07d387296a88c2eb89856128a1d8a0e58590071663d205a5295d4849ed3cc62408822d18c306145d80387fbdc27bde4fa7d389054fea400a02e74588704eacbb5aa9872f42947a78cff33c2d0b2f40b0c17a1122d671bec2d97bcef3ea3a37373737d2ea1bcc8a31093ef52244e0530fc330c43907675a0599233238386f41a7719e89562f42b43aeb37cf2d1c1c1c1c1c86a7832f42743af8542a95c2f906672457d4608b102c16eb99287c11a2f0abb370eece7ab649a55229fc71de4f2f42e4fd741004419c5938bb008918e0c862b55a3d1371e157389b9e7a5681200862bb79de4fa7d35be0e913ce299c3925612879d261f816743a7c26da5e8488fbf610677bf019753a9d6ea4d5275c634c1699ef5e84687ade5be0690f6710e70ac58a18523a7fd8f3bc1b69b587638cc96722ed45b8136dd79e895ae09a3b510b36cdbd059d4cd442d7f3442dac7abe059e9e272ad2ddf422f344dd345d7bbfedded66bc68c6c3be4085778b1529e47f968e2a1f3e8429dfe3dee785ca900f018be851fbf820b02ceb64138cec518690002788fdbdc8b91f03deca90b80001c008f1dbcc7483d3eb8cdbdbb0323c1fe1db7970746fac0e60338777530120078dce7db75e11dc7ffb5fbc2483aafcfcb839178f83cf69c8be43a52a43e39ce6a70d220f09cf5816c87e7afa32e120f5632001912789eebbcd3c14a4eb29ebb3052ce517f6125363224ee3a6f5da4ce75d65717c9c5faeba7d74f67612554868473d44d17e98595f49021a5fe3abd7bbd4827ac24013224ef3c1d56f2ba0b2b61c9905caf575d2401f4c04a726448f63aff002bb13224d7e7e9458a01a9483600fcba00b0924d86743acf6db012950cc9e6a8df5c241facc42543725d8b6125301952eba807e0df450a0056d2c990547f01002b41c990bef39c0756222443daaef3f0225d185612001992ebf4c74a7c6448374799fecb8bb4032b998f01a94886b192116448a8f3602413ebabab9e7a782552c6f38b9504c9904cd7c1483a572265d7de73915c18498994b9ced37de722adfec248ae9cdb5c8994e96024242424d441b848943ae7b66e8cfac4e3dc14a84ffccd5d01f589b78967ddd5fda13ef1aacb02f5894f5d69447de2c378d43d5d21ea130f5e0ec47b5726519ff8ee9aee10f589b77704d42772a13ef1dafd35e104d4277e5e2985fac4cb2b95a84f7c9144d263da2a35c6b72610cbc64710d42d7e19020b0e9648830a2ad630322d91a313b700f3859935a228f3c611228082e5cb0d66f045161dca247d33253fac728a922041850db6d0a10d38d090099db1371d674a968831d96d4b52476f4c64dbb6516bb7ed7107bd2d916d67cd5b7acfded68c59bb6d58c0e86ddbb668374ec90ebd6ddbb66d5a357d1d9796d8416b1d97b48cb153bb81b3b16e5c4c57bcd619db323d39fae2088c2460de4842a58d2b4b48cc208c285fbe7128e8820b18404184d21331c098b4b83853d68c31458b18265c9821133a3303d3865aa2ab620b0ebc080b0abbb695307d63e58939bd84f5129c57546bbfff64d13cd971398ce185aeaf5dc52c0eb7703863f27474adb5e23215e55dd6f44923dc3a2ec100478543a35b17267860293ec2b49d4941154fa43c69c20c3040247902269972b289750091061d4b37c09184925992184e5a3d63511d6733b8a1adf164942174482d1447b0eda11ec7c4ba01d12a8b5c4cdc2bb7711b77c5f3b66d5b4a5365932c4ddbb47ac656cceadc6afa04126328894972844696c3a630a0d174043251b29835b1828a1ac8e8e36dd871298d91d625dc22cd0098186a4006145ac6849145305a6bed3388d1dabf0964b36aedb19f9006ada08c1a4b3b68c9411719641a8eb1a54cb23ace6600d35ec7a52ad20887f0220d3a32a9c82089ecc8fc11241e0fd228c9e6914429d26491cdc7d803199238856ce22b528680eae8450e293370e93893414a8f8eb3199474051381cccb6f695a9a3ace084cd9f61e3a9b3a573075de2a26f6908f20f57ea43b771378164cff1ea44af8a1a94aa17efa09bbe01df528539dba9f1e6529af5393da8c5a5eb52549a96c701ea4ca8d7754f713ea27d4e9dba4749b52cb7b1b989647859b939607372a1b97cdca967451308f3a611752ef1e65a8b3e05ac1fbea2bec82eadea3ecf4126257d657a9b31e4116545f5da372b292d4f2acebaa67bd48e6cd8b02fa158e9cbedd7e8523a873371d054558b0ffce82e9e1835401ef499085d4bb4b9005d5bd148eba7befee6197761c4d4975d1b47c2a8d8653b8c15c5ade0683615d332dbfbaae8a5310d3f2da9879659bee66af472f0a8a10c92e52440251e65d0251a67a11165c2bb8703a0bae154ca89b1e65aa97105b4bbdbb27c1154e4f3d822ca0de5530aa5bc578b7bae8bd17c9eacd1b1a9085130b280944d991bde9f3caf624b8c2c60287371376cd87683427db98963f5dd7c42980b89ac1358d77e5bbeba23885aa46336af9229995ce930a183134c85e4a29b3522c76c194a652b1548c1a6a449350252a85fa5030d4278241a8931993b2a986fa50a141566652f70ebb6052e26e1ad70adbb973d805fb6d8269f9288b324f4e2e331624854985fa701bb7ddde235756906a2c5185910c06fb23487cd460c9486664d4c92c868182a1032846322e4daba1689a0b0d52a241dc5d2b6c165329ae15388b2915ea439d509fa46824453af1c20b4a32e9a253a9a58be2146694e5caa5e5a913293408c80e5558513292c922993cb5429368d0690a1a54e1840b0d8a4a46f254898241438380a2b89146263fd37099730c15d3520e600b38ca2419c928ce53a967b066e23cc16c693aee40a22ad266ca4b972ece48220394a31d1d67486c344846a4a2133a53dbca15308ea2d09183187426c6aca96dfa0488a6b4a9aa2925018b3469da20824c0e8890099db1361d67621cd15bc7251a8eae10520541c50b84b6488ba69c49a2891b4a697041872cb7c0b051d45424c3431c610841441175d420133a53b4858a1e9a442146091d6edca079c9220a186659e3030facd082c51a2399d019ad02522c61464d9729399881ec0821babe2ed170d4b5eb3f81505d1fa33f210d2a3a62872ecad4e0461425a0c884ced8afe3d2181e9ce1cd9ed825041775517b52ca212aa05d8505f4a68ea00ad5c8a8760455905385a824a37868ce186cb456a42dba2a91d53abb6ea7386cb158b52281e95a83ac56ed51b39a566b455aea2a83acd6aa55b0a3972ca2d419602f2e6c904104666549c75915295d808eb321cc6869248f2610b511562d77456839d36d35518a7138632d5698b0be6bd3bb02eef988bd0967faad840db3c2135891a6042333a6bdde7e2d46fb098c68af13e8adcd2ac2fcd638f08111c8108c08e36c0832ba5e0c151ef72c428e613a462e3a7e065959bc17e50b615c82818b4e755c7ac14c7e2501435095d11f6f351ed1f4750649232323a31864f42c2ccb8431a44155261f717859d3475e8611e2745c4ae3a46bc71952149dc3be132fc6202d680be26e395a2fc3f9eddae8137d26d69054b901edb26b50c8f2be8b24f4ae53a929dcce594d46f0015503856832ce535763ec41efea6a875120eb378128aef2bdfeb3b59ebbdf04a2b55ed33e5cc3a32bdbc17f378a9111a8a8b7304620917af8cad4b08b5eb6d6af387811e6d1f0282a15cdf0682679f3a32e8a49984d1f9b40b34d463fa888619d9ccc8eae38b2d2f9031e9d7f6216a1239d1e9dd39b32ce93c4b28b30ce30e6afce0c06251fc2f9014f420925cc7e71a62c10689a9ec6302de4001126d0a9e9ec87399a1e06748a0308e3cc89341d674e9869103ace9c48ea3853f672a66b2fecdbb68733a6a5e28cd919a3745ace74593336ef175aed4ef004f96dc8bc14322f71386314b7f08cb1ad764682429d7502cd790a3e40aee98985a40f7a0ace2de16ca1c3784420dba90a269d32d6938c3d66d3968f749eb80f4dd9b1c7bc8d4a538ee8a834858b6b1e05b2e7e7c455ba6b99d5f496fe9b376c495c25c9651dfec2a32b57a6186e724cbc385376c63e63f11fc85438632eed715643524b97864998adbd7e880651a5781354e00091a41cdd38aa46633a7f7d045e894b6aa8894b6a80093b473453a6dd205b5899b1d8f506d9c268c662cb1b648ba3198bfdf31f1308ecd845b2e54b902d71902d8e98b1d8451d63b529ae029bb130865e84abce61c71894e855c74758dc26a58164c0d20643d2bc619cc51083fe0b607afe05a31ead9e7cb554e221f4960ed18fd23963ec61c2db91deeeddac9d3b0a44455d696f7848bdac37e4aee522343ddb364d50887613ce9a76f921f4f6b37e6872ed696010ae6e1f9a42b46f380fa1d786d06bda1d526f6990a4d4931b19737ed24983267d5461de5e970af491fab8eae553a838025316a98f44228be4c48017675094452523a3d80a399c6d6f31de142f1f3f4456a04aa79c2144296517e5b57bdd87a686bb5b3b5c676cc618b76d8b36be5aac375d8f5aef03daa8173fd3cd426dfad0b30f547edc4cef44109ab1f9d9251cc18c09893063f329eba3edc34b30506ffb13f8d58880b6170526cc5b1b86ad1c82e96ebbec10671f3f289c633edde1fcdba5baeb2e6350d7753786f441a8091b99db89089da00a828a1b7ac3ae137ac3aeed45fd3363dbaded49b004db164b2bb1872422facc313df4bc0463026dd7420a153d9f66968409a944cfcfa5f09bb16d9bb33087aefad81c9e2f2176bd862b6e9d05936642a9aaad02579d268b67dbd77bf666dab3bd3863f5d624db5404892d229b963065a330edcdb56da558e64a6f0e9b7e9fb5b902a9c0842dcef4951639d2b3c8ecf95b7b72b20ee149893e918ab51226b55a082ed127760ba1147bc40ed29c18191911218bff7c5afa34f9120f3cd899102f2c6142836e61403de3e9d08c3f4233219cf4fc8f09245b849e398432062f1e87d6fc9c73cef9d8015e3da7142f280cc28daa01cdab12141281c4cbacd5d35350c8bcf6211aaed8d20824d6398317e7024e884a3fd59326adb34c9a6bee96e34c65601504ae6e1cb7a4b9d91cc7719ca9d5dc8fe6b8ff84dca65518085ae248a28c3970a0a4c50a598e35fdcf8fa67f0d205811040e63344163ca912c2a1d1603d216c5cf669294cc1b4c60654e4607357c6f91b9010d1e99314a3acb91e1025293e5b41e3cc1c189244a9ce1851364725019204d163de0808e284efc2085acd2a4ce465b37317a50030f67aa68028e1a78812ac00c8c90810c196190916526ab54f302065cb815c08c1f7a30f3461c5a7cf1224c47001676d84109144e1c796105d5bca8c1c9b6612f8c6ad0de0a596b3ca9d7b487676c6755ad0a273c98610d3874a0c14c1730f07ecc90618d1a2fe8f0248c2a64956e37a3646edb3634df05174b241452906415467fd8177534d8f93f2b296ca87ddec68141a6a9eb21874ff3ca5830d4279a2e0c89303da0f1c2182d60fc206643a207271f2a00030a1725d848e28b3a34ae86b31e96d4b015b25a3f58d1c0201a77373b65cd6b8d8da13e60102dc48194cfb015b25a3e24a1210dfa942fbacac7644c0cf5896d3f858ad02e993e910a141b7634d3051654cce0410e2a5abae0a27d810504c1026520f1851a63f4c08928b477c96246935db1f2cd71036f9e665f60981285122f573469db713645cb141f6c404ac1d91a38daa6e36cca92d913769cf13087a6a93a7ae121a96bc725a459196bd4a0010b397668528331e0c0e97102962533ca9082460a0cba8e4b4f98687463c3133a43012d66e890c40c92baa052c6b78434fbe0024a88a981962474708154c5690c284715635ef0c10c32dcc8b2e4848ed41326dd00e218579c20a3c60c3e3ca982ead8e50c19cdea38e3414b1d1b8c96a0f64ff782a9a630b71af463646414439dc1c04bd77a5b3b5311a1349a3e31890d6a1e9c4c9fd8120c62a9f06085d3b4975942883359f410c40ea2e0410a0f31a802a082845299359698e8e1410c488286fac4a6f4b0e9232fc417578c34252d69b624296a12c61166d020ca145f8a4803e503429233608a68e28a2fd0c8e9383b828bde3aceb4a489b50c32a469e30b2561bc1143acc287242ce22073c3972ea21893648a0cb2441983070128a2c18a21ba5cc18610499290c54711a0b159d1aa4c8a314a90e10116492c11e3cd76800108800a5439c38d2d96ce286551e919ebb3032cce249436bc7408a273eb3505032cc474804224d6748827959041288f28809430ce74c8b2759ce98046c7990e60b4d771a683181dbc3ca06e4db43ad3a1064a29a59456aa668b5e759c495143b3d022458b972de4a9e34c8a1452d04889c2c352593d681e944d0a12877ac3aa3acea290d1f29ee98b574209531d6751b668792f76a722724dbb8474cd35c539056dc3778128e8f8e2c40d58a0c4606646142a1e33e4c08a247048420b3349ad8e5eace852061a1e36ad4b2874264bd757fa5887145066543499a18e1ca21c616765a0a93010aed8811b3aa041828918cce450338b4225cb9825625e3cd886b429335159501e25ea09088da7e32c07a4ed8b57f610c6591427fdea39b7fcd0ce54812c97431bbd6ddbb69970d862d18aa9e56ad5cad86859a02a4b091e1a81384dcca23920f1d07bdbc65d582cc4e18cd7b6590c9bb12b7258d1860e463a1ccda218a176f8748912668d21be70a288d865f1dd85ed745c522383ff9866b8048b142c6a7008c3034ec3ca24c1c3cd0f36384061c2c261061b5674d0a06a8386949917845dd4809a41395d810242e1e18392c453e3a443e3c4f485f58203b74493ed053e40e1624317276278c1ec054b70500305074f5a32780165861bc82cb9410b1aba20e1449f3a7641a20c33402f57c0307bb6581139e34a16a51e98a9230930350c8773ca24e1c30e4fd09184962792be1e5239089d29a3a4d62a74c6761d6761bcd1a78e4b4cc8a029ba01cb0d96d024d5c0488c253aba70644e378c9231d4e041ca95274b6a93344d5f29c5e938bba1093373dc004494ed06a4294fd880f2a48c253ad861c909309a2c3d81c4c33b2ed1a1845bc363c5cb4b9c67c42e21b9b6fce69cb5d65324b2884e49457e7d18a7a031051d4a9a2c49f202997c8b067d00c60e374c31628c338490c9db8ea08442b3e2ca933030d8908619b3275e81c494274b5d3ca90119597c0c416ce2464be80c0c4a4484e982c998376668b204a709101d0f1470d401c6115e6499a28d334dae84426750a1334b38bcd17521e20613ab0359e8e08a94255a9e7061d284c7440a6e274a81148334da78422509077150b1583c092574d2f152c8804b476c64767ce4a16d4fa4a0022bf3848b0d4faa3c7912c5c993244d9cec20072738a8c14916529c2cb183931e7a3a2ef5c08bce069bd49c3471d235ac0c1d3798caf460ad7801a705874d88275a132936d4264a9a508d491a31806d4cb8d041abb53289a26b0eb25aab56399d8e4b6dd0d05e0d22109a8a3d2a770906e1641881cc67a11fad33059d0e8b7d101ff09ab13bbbbbc0832e1aab1d36d56f973563b53edb70c21086510cd502cb18d35cd0f35348353252c144818f3a2fe5a7c428d86ec4b68c3db4470d49cfcb07d0deea3deda337769db54ea08a6b9126a70c6a9c4147dce32377afd43aa4763008ab5665da955df1379142f96ca5151af06eba171f7292bede2389afd8879ee97ad7c9a6d777afe0095488e91ece1d0c42fbd8dc2c0832bcf959d91114626a09721514623fc46e5bdb3b63ac7e0385d40d44a1da73e00366f4516fa455bb6a5a7348da5e15cc2e42d7ccd1f61614328dda6214d81bb1cdd1e6ee8c3dea2d48c29c32d27a1a9aa1e9ceb6578224c828e7c97e6876ec515dd6657111d9f528905d5f3f7115f9791b4e4b83a28c527921326efa1c42c78d6379af8ea76758c7e798eaa887cf3f3af52c14c2a30ffa8c808e5286337c9d9fe9ab5f04a56c5b45e73306e354b78acebdd48db14790d78cd18737c658f85678a4c3d30ef16bc6689b70368112288241d20b6de430c5952ec490c5e9a3bae9e62f9b48307df5f0ca4eddd8ab4be46b940e864d1ffad9ddcf180ae7a2463d3681429c6587a7aa676ef5bc35eb3502b9b1b99d40a99b1e23909c9b2e2390d64d9f1108ce4d3813f93a7c772fbcb17b19c2f0f91d7e68a64ca6d4e9736eebcad8c3749c3b630fd36f6e8d3d4cb7b9acdba6af6e8c3df2d6a6ab6e9b708b04db458e74ea1314623b855f33465187c5c230c444be36bd8227c42e8ae8a2883699b04b08eaa6a370c526f8fa35631429ccadd3b531d6bdd565236d3a3d786b8c75ff6e8cb10eb7bcee7091236d7a0485580c8bcdd83c0a73ab27a531841bceb4629c64103aa79452ca792927a5f4b52936227b6229851c728801a28b28c6cc70c61135d4970b6280c50d4560d1c48c334661d7b10b133a804197a4226260d2c411932d31dc74ecc24498e63a766902074aebecd80aa50a6cd7c8840ad7dae35b3f976937610255da938993d6fe4d8d8a56352ee22cabe878edb009e47275fea0e525de6809aa9655a85af3b66d8bb187dc360926f698d1daa0522a4daf434738cf24a929eea884524cff80408037aec61968eca084328ac835edd509c78423f6a007424475883de8e71bb187a6d54b8940a4c42bba4a4ca5c41e7184aaa652e80e1148946e84f49b0cea254f441f09d44bbcc418d5d2b1b3aa9768893119422f6922fa884de5bb62560318a031605a82697a7aa36e0aa220c1343d417ea118d6f2a887904bd0b404d35e947284716683989ed990a43337b3014cc89a415136c1c8106247e946182fab442044f2a86595d8231e08d1107588ae602210a2fa187bd013e497a697544420124cec111f638f78594504221f81505cc4b6fcac48b3de353109b3b76bff614508a74f7c8e5e9ab2a6cf7cfe209c3eb3a555d9c5f462c7dad94de2d3b59bb583f75237dd6cfacdb99b59cfdcc3d5e7cd2c9c8f6091828d1da4526f41a753cf44279c53cf79de71180cc67a5eadde024faf9ee76f6ebe72011c667c810304c1d3419cc17fcf39e7c183c7eae6e6e6a6053fccbed0c1e9743ae17cbacdf3cd6130186cb55a799ec7022439d6c4e1dde679c779bc5eaf300c5760460c8e92843097cb954aa55630840f69a0a45a2a95aaa5a3a3c34981c3146bd8a050289b56ab753a9db820a24052e3a4fabecfc6c6c6f3bc6dc684186d782a952a0c430d8c36a064117ee779070a854aa552f58d335c5491face734e4f4fcff77d20088249a303969b9b9b1b9cc1ef3cdff0f0f0f0e0c16307672ac4520f9638fd3eefbce73f0c06f33c6f36e1831a61bcdfe79ef3ecd8b1230c4336c21893e4e6e6e606e7f0f799e7bf38cb2b5e00430e32862294d2e0e0e01451e1a20324168be54216329604f15a6285181d5cafd72b954a1d714209208048e9b85c2e10048fdc80440e69c0968e8ecee9746a81d21961ac38d9b45a2dcff35a80c31a2d7cf0543636366118b2e00560be400a53a9d40a98d4700312a90f85428120c861b1828313208feffb4ea7d366850833b838bd9e613c78f0f03c4fd3c1cc0e2ff05ccf3b6030581886f50c25c8cc11ea3ce7ecd8b163a64163894baaf57c9393f316723a0704c109051838208136cf38373737a7d349fa10040d7070e239ebf57a3dab9e5938386f21a7713ccf0322620a2dbcff79e72b97cbf58c7a5eb1586f21a7596118ba7065ca0f5ffedcf3978e8ecef3f78c57abd5713eb2c5284a1b3d2f42d493faeb99e7ae56abf5cce3f962fc16721abf7076411c65acf9c2f322443ceff98eeb79e73a363636cfb0e7df7b5d38bbc0684916607a7a7a9e89765e8468e73cefd1797ebda552a99e773cf7fcd7c1b905b32f4bd2e0e1e179267abd08d1eb3be7693dbb6e8342a19e739e797a7a7a5a38b360d6831f68b0b3b3f34ce47a1122d75fdfc139bccdb3ce55dff7166e9e777878786c70e6b604575238a2de912b2a80df17e9771356a1bb878f74077f7a3725dcbc73f7bc48a5fcbc0af2735ede845568ddc347bcb7f01096f8c871f00d3ef283b9b3283e12521fee36b8deefabdbfd74417ce48a2b02f5df55a8fff0912ba61f61bdde845558bde3bebae4c0bf7f9872ff70044f710ad487fb119b0a553fa9ab1e65699a939c7c9646d55e4985fa704f5dee210a1f91b23ae5957bd7c3875d387245025126abd805ed291cd1cba3ed4852a699b9131f9162a84fc5927bc547aea8204ff111f9235754a097dc69e5de0111cab847193d8cc343641a3ab933bc080bb2c511edc9abd5a63ddbab9fbcb29d80d271d684931f1d674cd8a0bded939b56e98c1b174ea3091467629274ec205b1c4da038cb224dc70eb2859509e492b7d21116a5175bb86cf1228108e53f23c6b4a9e3cc88301d67463cd1597634c2ca34428a1134f49a96b773d57156041a2dafd4218cb322c0e85cbde0c04a5884988eb322943adb382ba289228a68f95a8bd0a18b8061033bce88e041cb24b6503962aa91a731f6889f77e33cadd65a6badb5d65a6badb5d6fa5aeb263b5e521181c8a9d452e27a4dd3344dd3b49be68619114942e04558b669a454ea982597181f63944e3afe501f598e623ab934d1fcd020ea24b43fd6fba1499d270e3d4f9dcc96b5da4433d1349d4634883b9596943089b561d8e2c6642ba6274d1a63a6271a6b25894b42839062f88e149e7eb2824a59a19242519172a42329273408097c0cdf0973e041cc39e19224e9796e0c0d924172666a1234d5491a1a74e4f42a855353a938d9cca091e2844bcf6f4e6810176e52b8319b1327463dbf39e1c6704932ca6ead58694d4943a3a149a5d19492343560b8188951a23e734b32060cf5994f7162b83156923a8db54283e61153942963072655c8e66d120da238c4314795227e5892cd5b2e3448ca50c3176bd4acf142366f95681001bee870668d0c5e64f3160c0d925b7af082243cb8c148536a29bbb161d1a0150d4a7dbea6a141490ca0c6851b5cc1b86083ab98b3701d437da6e6c48515ae6652b8a2a13ef37372638c384a6935eaf95cad7448659b131a84da649f141a7492b255f49160924fd68a3ef2c331d0e8236d9a6eb2b2a0415196c61869d0609146d01250255252287710204a18674278b15247a73aceaca451ad9409512789aab3d6534a42f432396dabdcb7ad37146c5c2dd2534401317ea00d99aff750af09b40dd1fac95dfb7aadde75c2bc6a33715bdd86a8ce8124d821eacdaf27183e824158af096483a47073f30806b9b931d85c864d034b286ad3b58a8af74c9f7685d44f9cb59feea5ee3c6c0281e1b5eb7ddeefaf09e45da2b07dbe0351e03e710651985f815f5d57f8d463af702eead55559360583849f37f66b02a12e670fd5bbcf9b55287057615778d70929f014b4790796a07ddb9ebaa6879784a2361d758780974d4121f5047e77c8cddb356cba261085fa8933b75dbbf5f4fecc98c4db6c082eaaf77d122c61befef498a7965f4def8c22dab7221be852e8f87a258e12d4300974063a5dd44347313ae2a83de2acbd35cc80192beaa1f9a169058c968f2e20a915c7d3ac69afb83e6a381f7191105f3f24bec6d71e9a33c622f58256eaa54d779da07d755396369df52182e84dbb434cb71f9a40dae54d7748b31f624112ac09b1070386664c5e4804f29a40a64bce72f533bd2690c5d98bb187eada555dd6cdda57f73a1085eda973200945ada5beba39822a9c8b5a75d6cdb259d7b2ecf031f6607dabfb3d82423ed5459d754fd7528841cab69f6e78f3f7ddd3be596dd470565d1e75babdd9bb65bda2603a0b677bed2088c2f60e4441bbeafb044b6069ef1e6ab7abb36eb62bec3a41f5efaa7fb1376b7128ed53b7d940144ccf5c11d95592c448001bd5059fbad908ea0ef92efb748778df4e41128a1ac49e09ffb01ca672d293a6e18845283f8308893de457d394a4769ca609d19b40a887d44bb386b3506bf76e7e7bb28ea07ad08a35439cbd774fddf925fc56f874d455e127c113ce9a174e4f3bc185eed63671d40442ade12115d35914ce9a64a41aa99d46a5ebf7345ddbfb3e19fe8041e6a71461b6b0199bb3356333db0f24c1b6055de80ec4f948b4a690f3fec51a8c3857fb852d2f7e18c4f983e69e853ecfe3ee71dd411004412b20cf737d3dff34883b0c822774fd8125a8aef397ce634eec9c341328e75df73a77b7d56d6e705add5d9f269c430ee7d687f3631dce3e3ccfc4711c67c4748748307510348137f5fce352a9cf7409eea090c279b6fc0eae69fa73e1ecc34cec0b1c9cafc50dce2d2a6cf00a77dd77eea7bf8ec3434c975cd191adced179335534b8eac666dab86fb5a6f9f1b9394929efd2f34ee407911f3fbd99e427b33003e60b252db85091346b0f01ed6502b477affbc6e1fa00f91dc459f6600ee7da1f76e158fb8adab9d6f3d31f5634866627bf7957a98e024be8fee121df6d7eea3ca0e31ebc835db885c7dce0ef1bc8fd46e26e03392cff81558def127be14943d51b6c3d8d4adbdc7f38a6d57d3d7579cebade553e3adb1ceb77b6d9462a346804b645c5b5f3eca3b3946bfaf511743b38fb88b9708efd84f35bad0f6710673b4fa68320ce3fdd81273cc4f4efe0e9defc7ebaf54c80eeaa1aa748c687877c3fbd7baedd9d5c5f778bc17bc2aed3c7501fede3a1b5e039223ffafbcef34f7baef3dc3863aebf6e8c3dba5bb084ef43eceb1c88c2d75ff4e93e632cff04f9fcdc58ce536dea0efc0eb61fce44450dfee579e0e97ee1e9947fb09e85ba1301e7392addd83c4730dd695dc7451cd35d04a3a399eede9a403f11c8eadd091081b4de3d56356408354df53cec2a817a2f6af0e6faa3bb0c9efabb454de4479f705543fae0eebab976ceedd5c13938755998b179d53533efadaeec5ed148d3efe8450764a491d43f1dbda461d450faebef534adb56c38d8e75f4a24698f6b2c6517b0d1ecde779ac3bbf84dde32bd7720c0db2ad6c1f5bddad754db1c7fcea6aedb13c9b2f8226ef1d96b2825fc71dbcf5decd445acd3af71518a4ce66bdb26eecd5ad6dbadf8cb1569776bd556e78f1186bc68ee9d59d5dbb7b714012ecbd6f687a1ef7bdbb59a8bb58630d7e9f7753ec1b9004d3c1cbfaeef69a00d6434cafb0eeee452fe78b6009adc719041be1def4781f53542c1882ab8333d6a970784fd784f3abbbc3706675100fc7eff5b2de742b66b52e11584bdcfa56d2ca8ccdb3ae0c62c62615619663e49809d41d9c40644ca04c44a8bf77ddfda68d3de6435be53b9cdfddb71b82b6c10f889b5fc22cc798a141f793b3d3a7fbfcbd5dabbb04837cda25eaf660878dd4465df551ef1c0a0fcdd8fccd9d317b1d3063f331a6c219c3d9486d6bc1d07b1df6ac85ddbba5413beee1fc750fc113ba06516009e1b5873576453381eabbcef33ef01e78efebee81f7be0fd1cf7487a08ea4c10882dd6a687ef7de8143b6a350403d25d174975a61d9286ffbc06f471dbcd6b9c3b98237870d72454790805f76a1bb7f384b373a73bf43c023e9ee66dadf2b2884f6f622eea6ef9d440317a19de5d0ac200a7936f84fa2316dcff69e87b344d3dcebbd0d1bc1b96223335baf3b782fe5798fe009ddc18e0700501f063bec429dbbf70e6721e0bb7797200ae03befdfa5191942f70fb3ce3d4b34eda9c012be777848eaf35878e57d9eb70a3fef28ef34a5b4e9761775bf70c63a1083dc55d73e754f07c0859dc7dd11b14ceaba0d341dec4070f30e9ade9d9121642353a7fb21ec9e3b9dee87d0486d0f0ff96edf81384b29c4fe3b085e820ff0ba9bf0f70ebbb6734775e7ae336796591a853b2aa191dae0b391dadeb9dbefb8a8c3ae917aba5d96e6ee8125801fe261d33b1085af411067226b6f0283d8eeda2f00e127c46bfba030ecfbee9fcc22932650eceef28c0c41367e7789a639ee9e06de03b1cb15817bd857c0df710944d911d23d0c8347c2df818bfa7e17bcb9fb77ed2358424787e6778bdabb32a9bb1bdb627946fae03e44b95bbf5d0de31ba7939e49c214d45a4df3581d95303c98b9530d0c82ba87ba310c51b7d6b08637364a63dd68e2becd73b2560d1b99b3cecf7992d407cf8bb16edb5739593d4a29958f934bdc28a554ce29c948201ef83d6e51eb3aee765442ce9bf44ab9d12df6d97038dc3ecf3b5dee74b7d3d5dabb32f690f7bccfdeef3adcc17bf33b38fb3b089e20bfdadbe9d2ef9eee6cf0d6e89dbe0886381775787b33ac2debd5dc57d9a638bcc2deeda884de5787f5760ff43c1bfa94479ff236d65ddd6d53a56eed1348823deabb2502ebcf036f0c398e62142602ebef28f084171736c6e8ef1eeafb1abcb53dd477faaebdad29c2eddedc3e66dbf6e6c6e9c379ddb749a31257bbbb054f50c09a356b247763b86d42a4c546c013e29a356bd6b4567bbbb5276b765d18f1808a96ebcd3f9d89fce87ab96d766624ad4d4a1f418fbee2287d6c9fb7a2d1f31a9d9faf1f9a31ce39e7a66d41e82cc29f31f9841761dbadf5c66db3b6de216a35ad72538ab09ebb5e2cce447ed46df3b4349d6bddaa1ad2c7dd2a1a5d3fc1205b5543faa8b72bd0eaad6966ac7edb34cddaab7155d6edf67ad67af7e2469ae925dc3e9c8bfafbb6ada04db796b3f62613783392367937b695683a1b99de76edbd08a220cf481ff6a6cb70bbe946e9234b33bdc9247946fad86ea22b9068289a19db6eef108d5c7b9e690b4a2f7029d5a0a314438e1cad3670747033860d19d6162b2b545d524e845850469c800061f0bdc09b410db69bc191890efb06b7c68646bb41b5017d183b6c8b19be15b234212d4ccff970ceb9f59c5a9c330a2f3d5fe7fc4f9d38db1a858c5914593aa7e3ec89a4f65047e45d806105797a8a5d901d99a7184c61a28a6448a6948027a5dd62b553a335d3298308e9a7f62c25c6b15abb4521eb8cc97a9a5fbccd24390a050fad69b01fa11f657e7efc584dd3344d3beb2706d3ea0f2cf433634250b4b0b25a1ca55a0d26ae96e128bda641f182a6699a6639ee070a2da91f5cf17f5a3f3f5c1d674f98d15dc7d9136074fe894a272388b00ca043181cb03020f413a51b94524a29a5544635697a0433163fb5f454d7ea3baf1d9e9ed7ce5d0fb2c2ae30017804c033eb741e87f5fd0753298cd6866112fbb3035bcc73b3ecb07bde33bf84df2ae5daf97c81b0d7076deffd68fbd6eb120cb28377bce79e0ededcead77ffa95fa6e924c44a8797cc7378b8dd4e671da71d88766a3ace6face3d1972b173b3ec9d9f31af7b32e441d3af9e1e9e4730480f46a35faf4730080666ecb5f3ba7363c7eeba26886a7a487d2c7600dc2c1b00f7798e5dda063d0bb57d16a1ed3b862093441ff3b60037383a3d3b0220808abe6c806e3f14810ce01603e001b8d77365ef280084a1cf1e103e347b7cd0d3d3d323d429d67758dfb9bd3b7fdd2cfbf59ed4aafb6e7f1b068d70cbf3baea27a04123e089e38ccd2f61ce730423972499403c326902815926d08acb1313e80baad3c7fe73b1daf56afbffbb3f7e3e889dfaf0e03863423dfebab17b7a3c75593d6ec1202a0e76c2112e6c8c214653d5ad8d7365eb00f121828fd8af1bdb2bc0957d13c27f12f09f0f4dcfe61ae09e0c0ff0a3a7a7a7a7a7a7a7a76765faeb757b5f6fdd2cbbf59e55b55fc86abd2650eaf6874da09ddbc72610cfed3f98403aa8dbff8840bedbd6c37b289944e7ce2fa1ce117082151c9941afe9633f8f801b9b3ef63a5768c6ecce9d5fc2a32b3b3c9f97522610ea23742ca89082034cd8b996e77e23dc70fab486c0cb000c7020f6b0ddebe688e6006fddd83d374ba53ec057371749b13fc03930488863d8033aa0a8836ec11390a44166cb96b641af1d8489001de07e60c6ec7fdc11cc987d0483180063c0e6c62ec08d4d805b7f6ecbc7fd01e19ad0e3a6f0c155815e1606704f301402100508a0de1cd570bfb9d52e8c82ea73f36c2b3d9f7393e49e739f60900078e9ed153c01499319baacd13d9848541380cd041a64651800c08d3d3481ec0823dcd8fdfcfc0711c8bdd0273681500fd971d8f377e06758cf7bb0fbba096d0fbb59a861b00f51d8ddf1d7cd1613116afb1d3feceec03d17dfd78cc9df0b8b3de485ee0897d224c24e059ce9bbbd9ff7ae7b8e64e4fc39a201e4396c043cc7da5a7b73fb9f0964737b132610ebf6294ca0d5ed559840aadbb330817a6e8f8109d4ba3d072690ceed4f10819c6e6f6950026e7f1a24c2ed85685008b73813896a7a3b17f6acce738fe75a6bedeb9a40a8771e411278fefad0e4f9eb3df7757bb350db9dcb9ebf6e16ea9e9ebbfacecd2674cf57e7b9b9071311ead4578f6090d48726cf5ddda357c22c93f4fc5deff9eb756badb5d65a6b793e345ff63c56362f9dd019d174cf79de73bd9dcb466075cf73d83d711ee075192e1b01c7e993bfeef90b67db3d8f13a884d8aff75c8224cc7ee138633d38dbbb5e1f9a3dd7757b5de7b97907138968fa85573063f62e7c8219b3d7b94466cc3ee71a99b1560b8f60c670eecd6dcd98bdcdfd99317bd63561c6ec57378519b3575d1566ccde3ebc1898317bd4e5c08cd99fee91d8c33e01d74e1f7b11eea78f7d085768fad803b97122e0c62974e3f4c95109fce8b722a336c2b566648493d6622251cd09d6cb0f4facbc3c55eab80389a90868e22a9e27c3a239e73c22a9679115698288a6874c2c8b9028ee329cb325ad26cf9a402e4dfe335d3e946f492b3f19cab7a4099fc2a32b33c6cf2bf3543627e7497e932e29ed949bad1f6d55497299c56018fb288aa177c2f364288faec47980a32bf132fcc79453a27c424a82e89a8f5def2ca212039e84a1bb5e8c40b5d219c28c281973bd16351c238ef38d2667c88ca1c50d2c3960828b8d8b1b5890000b0fc228830b1d6594a0c233e2430d4936f0a1c9911426a4a865bc7045119639e2d0f2c2152f4dd4c184123bf251decab7a258610d2f3e2cb1c614693c09e38133664749b27871030e597c0c812d41a8710ce841491d397062892c5158d1dbb601b103344beca0c50a2ac0906d5add89828a2854d840c9972e321ec42a6078a302664809220c25b680230bdb71098634c2a42031c8f8706609131fbe2c6989416562090f2a5000420c34ce948902c50e32a13376c684517f1d675cdca832e342650e2e679a4a983fdc43b65c925adede0575a394524a29ad94452bdd528712633ac79a4a3a43d3ac949a2cf5a1d7bc7bda952d9ff394e9367d0585dcb65a8c3d3cecd27e4c2097868bc89697a7b80a78fa1f21faddfca3e9631fc81fa10964416c0a8fae6cf2e03763dbb987349c316ac30f86f02620b14a21f2f6166717273b6bbd49ec922f6a89b3d6451d2350123b3b1690c3888b163bb0810c9214d5521c47a0c08c008da52f4e749041971c6cd9c1778129423061b24406365469e27332c5973096209d210286285c9ac884ce5855c7d9163368ac69cb152b696b35d16ddbb68d6a5d604882eb409422de78410f38545162dba6688115307598b125cb9821a4389a4163628bd2e46ad5b634b16d39e2b439d1416fdb96285ea4a669b32d505ad36065aa93299478b5b68c61ad809637344dd3344dd36ec7a5232288d8342d4a60d8628531a8b5d6ba044b2adcb62d6a71522b4ec7a5a31b7a28924aa0f940184f74490a20c114479cf183165dc0686124b516c699d652ad49d19aa6ad71650e3ac48cd9b2268c30fd759c851184a6694b49eae86bdc56c5126764b1b20409368a58c208e50506634e5e8a92888112646011c70f3bc8e0081fbe5823c6145eec2087360b2388af8b06b01801654b0dd238028306aacc890a9b98e50930cb11b56a34f8f2848e3294c0d2844aa5238daeb5d6a51fb84022093496ba58a20b57c7a5a32ad6584292628700bcc77b79a9948f3117cdc73ba7bc472f638ddc87e692198b5cecb8649e06e923be4e4983f42157302f97c45baf5df97ae72318c44aed0534c28eb32c4ab0cc512516343adb89254cab1ad5f27502c948b12c02cb1c73cba2a4b7aac968abc5620525c465065e6cb1861967bad8b06ce94dd5dbb659a51c94f1841739f001ca520c3018c379715b42941168bebe6547b0e2186a4d3be04558ae4a4d6dd81ea64a1d3551b138b65a48e827532529260d35d36a85f8272c926d8f4062d321f2d2e89bcc33e8c81589a534fd14438b8c7a336af99f30caa434920db9e6a551deb011ae353c24c8c445e29a9e5701d7f33247304a3a06e100c70d5664f43f34885e880655256d6a4878f235d76ff76aad5e8c40b5d219c2d49e351923d0a66973c659eba79daf9282a1b2fac8da510a1a8ca084758b54d3344de33ace94c04209a5572e6e5a163928a5940a9d49ca829a9a524ad5101104115284a82861c30188e0424cc719114a1d897882882c2dff61092891643bce94c8a1e53fa124345ac75916393ace92c67452164fb04040a98a0970a8c10d7e88e2cb162f37f4a0f403163bd0c284145f685993f4a487fac30e64be2439e1258d3a68e01450c4c31553b6785186135082487a614a123b982581832b523a47a5cababcf9d00c9a8f4333566fc28c5529c313ea607c28bb8c361dcdcb70d9c457347b2e0237ba2c46028445a176fb1c66ee0cb8069e803af80a0ae10ee2ac9d3b875398b17a143e5dcb1dbc37c1739ac531d4ae69da060ad13e043c774fb3db16d3aca6dda4699ad6264ed3de6994b6a6bde352a807379004d9dc4d26d33c81294c2009e4da1c30815c9ba65d63c004d27095f97a13261077fb6d37c7305d3fc4001352307113dbf0e88afc0d9eb7f9d0f4ec04aaa72d26a5b5379d5a1bceb7a813c86df2e643d3469c96c9dad6d58e73a9b495af43e46bb651f59612e7bb6db88214e7b0aa5027a5d6406e334993adb54e31d28786a5bd94c094dd585c6deed1cd6deed96bebdf4524179cb7198ba6a3f63926fa6897f237f74a779b1bc309589726ec8ac094d9dc95820d8ed447c3ae08505994595a1eb54fb36e9d3ef5592669f9acbd4bd2daeb0c3da456793355937a4d7d68daab1dc51ef2d6da306cb51ecbb1d58daa57d55343a10a67d55738aaeead335655af4354295cc39b279a96df4004c23aea204e0556a0800a139040046e5080c0031c70420384d894404210062c40d643ac3b34c1d4ce64e592aec7402423a2e1c61cf2884b8d26bb811194f3d6f30f9c67116e9ea3179be71886f51cb9c8c1432d1cd34f3887375e8dd5da5553b5b54625232318ca90d50b2086a0c1806350fc63089a91f421ff562b8c31c8461ff959468793c78c0822b47cb43f4e2cd150049838aa3c31869831d2e84630801070c491848c1034e801ee381bc38af63a7a0983e5c79ab8aa6db18836babe628b6625f418eccc453862a38aa52e39b451032d70664928d14980086a1891050d60f490450e54103a1842062fe0200c354b282f61b088e0a364091990a0011424ac9c9141b869480cf17942482cd1093535ac2fc87894ce9090a31bf36b714bc33b23c6e9cc0b5a2c9124c6ca9434b57a91c18a104690410c355966668c80900969dca9a317181841c70006d083b8692d35bc40d1a48d1aaa3cb94245bd72850a481e82073064f8f2020fdaa857969abe524a29f5528416adeae845872d590b2bd890c20b0dcc286396b405011698030b1f6820832d80b0410cc4d0620a0f5e5003076280b1c1159550912b5d8c8942071825634c1d9776c0c60cb810c38c0c96c4000a2798ccb620a182624098b1048a1cacb9b2c4152bdef69e6d9b48e66cd95d29ed049a1a5739ee1cfe691f3d84861bce2d133669b15a7dc73a53cbd14aa9e5b87b3517759db1c94da049a96dd9d372db6727d0b4360c23776fe3deb227b5dbe7ab1d9a1ebdb865ec41bb9e8d80f6ea676a4fa353462d6adc69c331f6885d6fa7f19a5c5972c41c07083bce92aa30c1e40825921c6145c9115f1ad571e685174d9aebb8d4046966049a36759c1d01032ccb341da3f1a8048bd7a913398c41c8d00c30020000e315002028140c88c582a1300b74751f14800f94bc464ea109646914a32008c220438c318800020c3044606668866aba51ef05e8d56ea661edf61ad76eae71fd468d6b6e69b4ee8646eb6f69b4fea606ebb7685cbb95c6b59b6b5cbbb586f51b35aeb9a551b01b395bc085faeb70766af4e8baae1768eb6f69bcfeb686f59b685cbbd9350433bc393e9529a8039c82885874e47dfba6a2780aa7a0cc0e063a95c0f342c480207d69c7204bafadd5eb86bb9e5da0620d417be6b4215177bc7d489e8c531f4305523613484abf5ae122c30536c29d3407ff0165d8f86713340682706587c3a1b01a02fc838fff1f50ffceca15124604ed7acb9377daddf1e1878dbc4c2b92cad87bf1b461c2c6bdf1dfc4e06593ac3de264da346ecd46d32df7885195235cb07cb5df91a56c2620aa83e1a646e974b3dd70e2c9e330dd5817f350fbdf1a24d09741562e2461e492276d427e09b6835e3be400bd46361e08b42a5f2c9b8c39afbb325cd320128aa8c6f65a6b2701c243358c0452afce3600c1e98cbaa3e7a9fea06c2570440b45dc5ea3cd462effb0f7ee1e07ec9e08b0b88c8eb737adb41bb7ce6cb3b9df7b830763ec94988ee2bc9ba1614fc8e843b5ad3ca673be8471c7d734bf9cd6f975782cc03c6431c86ef0e14bb588de716183a5892857dff32434bd3003ca9d5aeed5819622a9dd8838e377ea9905bca1fb7f78cb510f38a3bd25465857247a411a3b0fa84302281c34a6eaf294f16790a33e78542ad7653ffd2278901789d83b1402abf6761e31a999d16df16e2b28a6082a736ba29190a9450a01b7f40142b51c8c560c656b8fa2d987770d9acc4ad0a36a0c35f87c0be8edd9f2ac3090e52536381546777815efa0a3de66930f3b50dc0788be03e52f41864b5a379ab9390ff65dca5ae727a449b14923449cba14ad53a7dd501a9ada05570fe99503f4b998cf3bd68b3e5028c09594165d38f5619676e1292619f0f8a5580c7f2f702ee8070a80aefe059a1ff8c9aed132c2987dc1ebb8acda7a03df02aac0ebac6b14f68470e7161712923ab79ba95f93e69b328f33e6d87f7c1c59192a7ce329c065c20342d4fea81fa47a58724caa6be3942a2a5602b6a3c70719f2166dc7548b2b1ccb12c5f68677277a6df29b380ace18bbeb6c93715c2fdd3d51f3beff240175c8d3e850f2e0909ff64429e1cef8a57a3c099ebde312551ea2c373ca376369e481332ad70a300402530b304f7fbd14eb6b574d049ba1cd5d5d4e0463296c53fa59b0e16d1848146cc2090ba4b816fe977fb126960952b8d1611d82876cf0f29294b930831eb669aa1e40373d985aeb771189958c14a6bc5bdbbdae82a7c81dc6fc40c721a87aaf7390ae2340668ef3259ec141ca5ba222498106e8ad6d1adf97d5ef46087928178c68d8f7cad65b093672a6d5e3193797e748eb755cc9b72dde0581562c195cdc972fa44ac4d65b0e594851344b0b51db64ffd05718252ea4c00b0c7941f855d6c06813a58e4a09f37d1441fecca2dbd512722a5f5213611af32c682bad37eb85ccc75953fc2dbccab87fc66aa8f89b8e2e89a1a639c8e04cf4a84d96f6510e501b6e05dd67382308a328094236a552fa15e6ccbc888ae9ba62ba5fdd14e72f25470dd5b41cfb898860e295314933633f188ef3dc5b324639731698883185970b9da266d82ebe875d0d3ed06849ab8ac78ee48c4002cb1aa1a7cf8f640dd4eb39ca430b2acbd2470d79e373484904b8b6cae1d32d3ed608d100e834f8cbf746f31ec0a3202aab356daf5b478e95850e6e8314e66560bbcfd50ea2e3fb7b3f8967a71248012c9905782ca77a8a2a02cf429958f05143fa05965836a39c999568dc2c8b7abd3c541f8e94da30f53dcda5635e1a7479c48a64ff73c3ae3295722dd3ca05f7d52b1b2564fbecd6336760c4c67c4c1e81c7feaf537760a316b29087496a31b731823b42d281fc2196cb49d63078de214f787b53ce69ba596bb12681e854d5a24eaa40a296e217d15afd4725d5507955f1b6637361e4b869d3ddfe53de574761149f32e9024306df054c55192b070bec26504d4c46de1b202214120aca909d5d5219a5c3cbab7a880168348d1fc336aeaff397c918cce499fdb93bfcf45f28ea8eddf9d4a6ab667074b702da42b7025d1744aee26ba097c4d2086144086e29abeda9264b75049e03d52c3b4adf3615a690b2bb3cf4b45a04a647d3d29e78e4fe754107e972226671185b7ab1add123ecb4c7cd9f5f89b85731ca919f13e8c8886fab826d2933d40729ec8967cbd09d5112d5677d365194afc1dfe855561858af8239f11f8cfbce995555849e1f857c4885679ca69f53e11fedd10e8f17f83f9d04a4ad50f0905dd1d46e7a99abbda25bc48880b20d742ba710647f5fda81bd2dffab7dbbed9450d80641f12adcf1ac0d229c9a1f3c6ef11dc94e6579ec7f8720a864f612a96d48eea8cd4631ab5b86d646018ae3f294c248581c6a9ecbc73bd8e22779bc8f46e5086442debcc42567c8426cfb93ed19458d092b17a2aacfa9c46c1f266b1667fb374d587e19a25f92796a551b2d2d49ade9c03eff574416b1d3c5ee869787a8ccf20597809228f55f7783eb9df40f9b2f6272e984c38f31ccf7b9d57d7a01e158ec0789aacc468f1c6a994ba349f4b9035a919f6c122a2c76350b974214645dac0c2ebf2cbd45d7c3478a57ae63eb56a3edd88b3b4766804a2a94b652e8b111a38e3d3691a9a5cc187b0ebba59468d36014bd354669c0f30715c1b22c964e1f55e6adfd8eec82b75256d8356506ae2c7d6ac17ca09bb85797d1328e8299f4526843debdde65a88dfdc07a8e3e38646728c382b89f2892444019175d60a26ca98540037ac56328b895d12f14c401096187937ee1384490aa316f5758b1a6670b34315828c5c297a122fbaaf7b418776bc05e8ca740bc935faf886c685edcd110944712059f763a07a14c19bb9d4d6c88ab72a1e4a5b2f123ee6c3790fd4cfbf470d5b17d13fc42280d687114e0cdfad6eea18a8dfcf346b085eddf8802afe14df5231c6095f38025e9444a7fdc26de461c7cc07db83b20df93b3891d6626f4a7ceb6b50314ec7614fc17b9c90abe465531bcf516097e76345cc6df6cd2a802f762a99447c76c5cf167969ea847fa008e22a49a7e25f71a2d44d25743081eee33972a7e6036b1b2cee6678cb96433750e8ebfb1583d8eca326831ad4f044ff9ea69b2c56476d804504aa3d79020cae86abde350aea460e1432fd85c2deec9043eb5e86a41cfcd8d5cad48c06971ba68241a65b7c33780bb50dc5ffd4682566cae4a5a119b0af957dbdb452b8eeaaf003625144d4017f09d53333a20384b6984e83da2dfe0b4b72bb5ae4c3eb9fa3f993b87e7936ae79ea4ce785be48d45d96b27174c4fc2848f32db0a555f06a5f61d8abe8125e44d2b6ac2eb1ba61c14b1b6c405f55263ca5b5bb57ea71610e3feec5ccb56d42c0818f20ba45a6ba78263af888e3bd6a905a9ab364eeb23d02794039171522634eb0038c3ea30118f7b732b12396e58c895ccd609f8fde6e1d30ad0e2998784c730d7e9338f60cef4884c47c511ed90bb2e323db91a69edb6c6b90909f45a92e4b82344b4be6d4fd0bab5d70b7f09fb75e2a808419f12f6b1cd7a725442992b198dec1167acaf26f11a6e7aae23eb7387e8fb4dfd4791d0ae05cc38f235d5da7dd4b7fc0eaf38c86909597f54d61e39b316fb11698a196cd63cc717a674277908f5fe0caba503387ef0c27c25de0eb5a05f3dcb64d92d3a3ba3c91f62960f66d11547e2d176b4e66fe2d1214b44b912655adab24cd0504456b3d4c4ae0a827526ae275db1634cb3db81f1a4ed0050c4e266e33e2ad6e57af830eefb823c7188a6024ec693ffd9e65b622190c4ee25f1fe6f44c66754f1c71c7d197a859702cbf4e18f3f5a0a0bb29551fa223b5f1edd16c1bf16b411c410b0bed4c9d9669ad26ff9d546f1c2bb2554d7fb861a8de12419abf97fcbd00185cc1cdee0ba66e1ea5ad243948f146e8e72d49e158e2581c52cdb01b6c202319333eb48bdd0855ef03c0d5bb541de7b0ac6dadf2f5d017e4af458ed1d9fb3930011f096d8b01d94417391f0030802da86ec17a120845bcddb708e4f8d45ba632005fd4cb1c8749fa9e61a6371deb0cc2b9da8d51b3e652799742b4039571d74a05a9042c164bc6267ec3f0a1f226c99d7c21bdbc59fd5572be87fd85e2db26656484d6a47b27a8d41842c48c46b06110fd9ad9dd2c12cf3df4fdbc837de3df8d7580c28238a6b7fd355db9be4b0fc11e02ebe326b7c9412c20bc4050cce4a36ef112a8d88f419904c42cd96938f0729ed87b7f10f5ae3f5f3605b6fff520e96e844da0c18f0dd19f556ea3461abf0003438e2ee2fecd656433981a179432a366956c5c9237e25fa43e4e95bc276cb2cf3c3810b7e1ae895826e090141db81d46e41f001acbc4376885d6ab4b0f82dea2a2d231a45a28df459cebcb56bf495a62116a6aa3b617a78d5598a5b6d98276c50da26213c2f6235ad2a53a0489a1f6538ec24697095d8fc065d82b5a31aeeb6b6a8a01a551b3a0e018d2ca7a31808a99fe050ed2265ced894683f0fe8d58668c3a19ff3acfd10743c239850acd4e3df6a4dd546008cee8e802ff9d90bac0c4392db606308002be25e62d3385e1876be6bfd588417b30ef08a86c4892c68ea76db97c4b1b563bdc57f1e3f8aeaeb08c914054005829876908fd76a3d15263e5ea569f0028a816a77977a2e11d19cf8840f01f6c1a2f0b55c169ba8ba4c6198f9de609b2406298bc12bae6b733393bcfebaee314c857ca5824483163b7a7d02adbf1ad037c9ebc3b8dddea33d5498eb634ea964cc25690c4d7fe26d3b4221985f6a2fd5599ea6d4e49222991a64a0049bb5cb19ec1fda3cc5c24f1d215bdff5892addffea3ab3d3ffcfab00da274f80ba0d2234caaef3c812cb2aff075fb1c89f62d71d15cf4ef093c04fa39a22eefa021d09b9c8e3424183923956c553780e6203f964bf1b101ed8a616391c504e71a52a4bac0ef551f94d301e2e36a251dcbf841c6c45c49e806ed75fc355209561bc21a3c693c1d8955ea8f19ef46e56d1b5c58d600cdc887acb5158318c9d402a2bc7524960978424bb56d1b820c355341ad81fa57616ceae0d9622ad9e3690fff97628dbb834c30d645c5d55442c0c77b63141ba1b8495ff2f256077359ee34a6be2042bf3bce3d8e91308b1bc42a6935808c6bfbd5e17d9a698f5e8bf41316beaeba40286673345885b3812ae53ee1489bfd5a5d9bd41b7d6dbb8d00c06bfaf5686fd2ad03610c31cdbc7c9d40256a947b7eb5ae3ddc9f221638931080157124d42c62f9f270399f8b001b39c036a385d69d3386869aeae9028ed055548b513c46accf7a091765305a0a14b1203fe3ed2748322d8bcad5deeef87c97081fb1fbfee434ed33703e8e674567f93c76148625ebc596419ebed42676989dbad01d002766ea0c0e559d3d00dff0c9badb3d8681d529c1d44a2cf2e30edaca0eb33e80c6b24b82bab87c142f82ab648744ca978624400a7d2d9e909897ba297aba11ced31b8c1bd045456ec102c922e504c1c8ac88196e06f5332153214900768af37299cfb3c993d02f485e9726dfe8ef29bc581a6c74a87122d59952283a0740d4d0a9afc01744a07bb80dd819fe2cc9ca943c60e320a1868ec13b729c485d7abeb493d531bb295957c4c2426e3811bfa4c08ea3dc5fed224edfd1d1b5d20a696438f7cfc9a0cd146d6e7706f04fe3daa0098143c63a9281df4a7b442819e66e33ac3b215487251ba20a228b2ce61a7820560ed1b3bec63123691df644a37d0643e8a03ef80506432e7224abf25bbc3bcd7e19dd18af579dd127d664dc84753a3092c47fba08dd68a1997a926edf2dc78e33b9e887946c89287254fd011e580661a35892ee28b50c69fd0ef0b8d718111b905691d017adf6fd1eb07fc07acd4ddceb798756c4911f39b02a9286cdcc8399c3aa0a468a7a22c46da74fc01649aaf4b192728eea2c210d4bf01dab4f03288645514d90d4171a6debe4e4219b1643ea3103575d8155b71d3a8d9363c2607d83e908fd45f3a1fc89c26dab78b7fb442c27df8d0fc2251620ff2c95653a34a3c98df3a078c7d6b1c3ec569b30bf5b7954175e49fa4ab8013f1e537ca3adb9eaceae8eaf0110f50628ffb2572398c2cf5019cbad899b162bce87d3d3677abb664140ff41160a2a0c2ca2ba9447403c83f6cf1e65629cb513ce0be02825de69e3818ad3d8a073c8a9f02256f857f5c15410c96e89aaeb57ca50093e1366cbac0698d00e9633e28502269ed096acd28e620bb88244579a06e43c403a6243743349c1a2012f309035eb9b7738593f557af7439f2977db89c8623d2f973537afa0abfd111b47ee97236f922b24752cad1f1d81d17bdfbaf204db650db07c0d65d0087d906a2bbe28b074de1dbf933a76f6313ea3bcdc9270bfc1f23d7da61538181ed5fa36f0295224b0802ec3aa3d24bb62ec74dc22793cb4077aec66eaafa53f3f08a59957f19b718bfec79ade1b56387b20ca15b0088d5f2fd76de281dee3e9fb05e1dade40301866cec3a9f12198a0eceb24a26a7135a51ce14c937bfcd791cbca1e81fc981fcfd7d4e29c9be6f83fcf2569d82bce2b90b9df80357607564f121c11061646b0d1624b4d39e16922ef4f7862a78423827cb3843c19fb6f44087e939dc184e839c8e926e0290b336591e9c0f5214dd228b23863d89bbc7fc40f2a5b98da117c66f3850b9853c0bd9cd686b2541ef5b34057ffcfdc277ad41e08558831d3a04a818c89581b760833ba45cfe64e6f5dddf5214a1c861723c49ac111a2db538c967b36b2d86a9df33e71bc0ed85d026f4c9bfc6ebe4c55f0c5e143fee093887916c3ad3780713f9c6345f80db0a99c65b889de52d15e30f8139e6c798c7c03078f67638b0222b15a6c63b2661c5c21ce02f53b837306762a6fdf201d3f8313e40e012a421423418bafa1c453a2d51ed035088b115d585148ed7d46e6159f5c597cd060d91d817df5974047c1a384ffdaf444bc10fd1e061d532ad2ff866b61f7e063bf3ac9c6cc5d7755acbd73d64f786c86b3c977bf6e178e09bb48e3e1de56d31ba0f42a355068aa4c8bad7e80e3953a06a800d5d3004419f3c9bd1cbbbdffd712b86c5069dbff385e6aff145337b83a15863a52fd8865f44a9a491c026ca4c9fe96e4c03b790b2d2a7161cb84ab4073e14c1aa59e9ea3522115cdc45336e43189d84a76633dab136a37e883fe5d0c983e0cab07b8b788bd8ba7a5c3cfabd72e3d33f4ebca6c22d4d89c23787d6678dca26127607e4f0c534fcb66b7ec02c092a67b0b0e608ccd63663b9746e217ef1823c79a0cbb2748824d8613610df9a578c51884701d514f2d8bb2a993b37099e2f86b93c48c695cd11cde651c328ce3fdb4fb7d2ee164bc67e94797e3dc7ad191acdc696de02cfe1101ccc9d07fcd749e726b923b9dae06c69f0a7817f0dcf1d2d7f2e914786147c54829090614be94adfe309195d477e774fd0de581cc4fd762417914e84f5443c4a1311830f3fa40976748e5130bd870cd19f314ed64ca05668aca3d1f09b4049f52fe9cdb7175936a84a9b9ed6d9c05e670f805f782ce0b67072d46eaa6226083c2356c4975a8bea1f01a9f16b098146cecc93df80e12bc653480db759a4857c4b18a4950c3662e811671518465e5f5a4b9f0c2327fcdcf7f644ee59b50c8f6ed6954fc3671d3b925507042e129b13553ef8b9f0170b92ee20ee1e7d163578421f103d9af300ea0bef05f4b56264f37e748c3d7d49637d399ea5d1680dd3177d1c16d3170beb22daf140f8f6dee7d5c8e3226cc9ab28941a3c9abcd91b59ed268954a3f73c783498aa862e08c5844ff217e290622116087a566fd6baf132f40615583166fd83b4c6420e2809da47c455cac4765eace370e8754ba2c5cd0078ff01052cdf39042e48d90e1a369b1f2edcf51d0ab00a83bf0aa631a0d0e64b28ed0e5a35bcba30ed424d20da3bd928e740aec5c613f3b621439d0f27efd8b7681a7903b29a5c59cda9cf7e50142c6293178d0b0e8c6900917a163af0ca37c7b1a60569a1af1bb2ba01ea088c40899824b2dc96e997aa2ffce28c4b492d47f4f1641ac66902045a7f8ea21635145a9130b9b6e732bd660fb8630df497cc5ac95d4aa40d4715d8dd56062d9f5136c4657fae4b532a045c0daf799aa351651eb7801de70352bd774e0e21d4e96412716fc8192a56b058af244789229e925f499d699587710e3034a64bb998043049969c564972cf60c28d5aedc649311a15399ae35cbf1b3ba72da49953fba3725a929c8d5eda49dde347f721296dfafc8a68fae98bea82f8983d73e7d68ace962f415f56112857db0e692401cf1d1964ccf7df4b8cb54b99818d2aa4170d7b0f711ce5d8b3bdd500f2a24c52ebbb0688642f7f7d0740afc81678b172fbb1494a35d414545529696145224c8ca5739ca404cb58f47ebd6a7f33d9ab8288c85c763b9f86fc12cdb6ed551bb6bba63027ce672a20a855801b781190b106e221825c5c37bce7610a00e30741cfc60e571582a8f5928e656d20aaafcaa09e93e36edb96f541994f8092d4e093fbe17ce655d8f1af8298756e57081b2109fc1ea93b6a998cb9926ef74d09321c74957bc10d42d14b25b01128505dceff0b58cfb7df892a6b5dd702cae6015b6167f808ddb2c614bb1625e0c0ce175c2123286a6fef8fe01a68dbabebc89587f6ce5f5c5a8e72faa0f2a432577c9e320aba29dc0c46d132480168f7482c481010c7a92da4f2ea4940b62dd39b91cce50d0a50f183b684e0aae5ba49d20030980e7e4ba27c97efaf57d0e834415423bf73b3938f8ae6586e4f266867850db34d7f6f5775a57fff2fd0b8320a130f046ca3ec8a7333e700f1da1fc1c326e8716126f36d055f1a4a7f25b3e2492a49401ca4f02167f07e1be67b8f52349ab8851a81109c48c30ad16d37248691051c7e15b9358f37907f0dc15c02eadcb9115cb6f67f4a1075b33fdd06158432a12b3fd0d3896e8ab72ff947d0b0f308e71bcd1e3df41daa1012c12b90716ffc6680a39bbe5820a4b34a9e9da2a9139f2219ac9478b5a2606761ff5bc522ba864d69aaa06ba016962f0cce87163729980c88ce6fd5bd6cf46a64f37a08947d2a120c70b2c3434edd65fd376814c914315df514d8b5f00f3bcf5bd31b90e87851383cadc997597e5d0218efcb12faab05e2b5cf73e8c06a6ab00b341f52cc72d5125724e62ee0f884ad1bf95712004e34cf474ad87817ff3ce0485bfe5d4866d3238cecfa220ddb1eaa3a78fde1465ec29a73758f185c43f97813c6bfb75ed96f68d17aa7d6e8cdd5bcd480ad9007ebc450818f882b044cc88213772ec3b07c42240b5be118b2ababb09a772d359d06b647aeb4a4252bacf2136cedc286742f8edf6e0ff874d22339b5d0105b929b1f78e19d98bfec1aa809ade5e009b4f25ac87f7e3d0a04eb64f807587f2bf425571f1a610bf9b9c117bc89f2c95e873ed9a20cbe406bf8c589462fe50202427411a0fbfe03fa61b16b9017066080dd23c6e8df7cf5ba986507f622bec639bb37a9d88a4cbdb14b15d3836384baa0afbdd2999075966f5d862aff1291b3aa1e4c33c2ac54ac27fae8a210166e1bbe66730006d22817e6017261b5e818268353cbe541a1666abbc57234a5c3cb5c458f49ab8c19747d81ec8f182a9012c0eae64398c76df257e1b0ee2a22e4613683ef300fceeee0d7ae731b5af56cbe1ef2156f9e402460a309539fa009135aa379040e02480e58efa28c2b5c0874706671cc42cd283b7030babefb0218fe2904e2cf566ead2f691389b5320382c1475a8e79f40999ba9fb42b6b541a169003ccb001086b99b4e7ba2e640477f152cb1706ae7ba603dca086a6c19f01ed5c310c9542728cea7b637fab1404b9ead2f1b07cad198e426c05bbe45b72f3c7736c6a5cbfb2ac6b94f5273b63ace59b48a6242ba4f4205919b2ec49e57976ff66df55e8280540da72e7a902545d537ad0c8def283dee09f1e3aecb593a2c5a72fe1a8a28d5647682f440e30731338de92b49112e3f0cb40422d9f98b25a0bb0fc730e4177b0cf5daa2a20b709498c15214f30d18f1c1991736a71597708ff9174ccfa42897150d69d739c2ab1cc4a6b9b97dd577147e0321cebc1738b5a849031b0f233aef1b7198ae44a684d05e5c7dba8954e504619440ded56d2609eb9b068f6b7903902b544eefc7b5bbcd4f2ff0dcd9b8354468aa2bfe1e7feedf148dd6310e0e3ff42fdbcc6cf3f289bc8034a921f45e72cb136c65309b2227911a8634deb89ac1bf0b3d623381e8f4ad03bc0182f01fbc8c40dee1ba9040fdb5619b538ebe989e81201ca1aa1aae23db1efcb31341f523281065f746e47b299730f62699983cb3604e34b0fac34905ee608ffc7afd4a02ca6db27d06512d4f81df770675826643902bef1117dd1795804049d6bf50a7378ac599dae68c96b4eeb2becd17ea4ba6c46a1f21578531403f43dc5ff21cc628f29f2f0e64b37d3c3c940df2bc9c2bac814b90e18a1fb57b1c7cedac422cf858ab8e07737758b38e768b81f422030700c7d31cf5d5752ab46994ee8efe2b958a71ca82f791c64f4c274f067b7ee851413fbf277e0edb57c24657e9981483c45023229a05e1b14d7c9a028efff0cdb4193e2713c07cf3dd357d1777f02bacf47b1539235d825364cd472bf2216a874525b5711c77940690bb8905854e1007c3b3407198cb504bac10c1ce101ede2f9c93b2fddf9f75afbbf0e873d0c2da23a6cddd7db4fbba6985524f093dfb736a0ba4caddc62da2aba15aae04d964d1b161118fd1beee494c5f708c5d5c35acc6f209d61eaf88373ab3152795e0cfd2151cbbc79f315713fea095b7ed1b39039cee592decafb3fc881c03b67b8da1218a2bca0f3ba32aaafd813ad04fb9555ee3c1f040e22e06226ac2d462ac5c954329b66875ae85d1c3b595765c125f499711f182b118444b593d7c150f875195bb3d28ec35c4d84075740112f978193ce41c56f2f2c721b107e390c3194df74b0371fed585158d70c1e304d0b41a1030a90ef8597991c3e5093e738374279ffa59ed4abf8c5eb3eddfd321a13d0d77bddbf43d51f1828862188cf874f0a0cb7b9ca6768641cc1521ada85d70ebee90aad953cdd333222a805d88674e82e717371c82cda035b6706c40e4d6a7c59db0dee813d3459e7a32aa75a82d521af430f31bad91565bad611b5388011ef3378359b4fed331ff923d67486e89c858d717ce47a308778f4633b93e50e9a414afcf4a30d38969fbfd71db95a17045469962e1adae4b1d5a511d1f913adca7ef54489bd41a82f9add7573c99ceeb54ba21d80b836b14a59ecdcc2225ec50af079b7193f3ccaab6de3234da41a564083ec8b83fba02958ded9593b10b7c104ab094e6f65f895b79f3b253d55f128de100d0ea98e2e5ab141d5d5d16f1e14671b4be9ea5c84d336f1f243c474d7784a75dd7306aab1271b4bd6f66a93f4b9143d4148ad4994a5789c5809b59f0db798ba3c019dd202c605cd8223e283aaa4047d939bb5062605d70627cbfa918da593fe69fbd3751d80e072c6451cd94de915b2b0504b4b71cc43461df75fa2bcebc1bfce668464b718eb69f9ed0b697ad40f8052aa7376ec61ecf8165069e491885a554ca9ed6ca9d679762518a5b87781dbf810557e9b312a75d5302897f8c1b8de06d41b85b2b2148146bf733b9f5b3ed97a1e80730324f0db40271f38b0740efd300812db50bb54406496f234cb026038140bd4002dcbfcbc3c3dc16ef83618b37cf2df802beff7429db60a53598dacbaf3e45484336b07e65587cd59359e3f69d1ad9962b991a156091a5f9790ec3386a3b8c9202fad0cb9ce0a943022b4e111707b2c9cd3a501d2e154ae951845a73980237f9fe9dd08b56a98e7ba8639f235bc83b45cf48524bf4a33f8662b3dada4c4d8d4e96cafe7f8dde6f9feb49a5e57ffb7f8c2140e5c45d211097eda3f802cf90ca98ea6f657284adc054fd1ecc6c0e262fe5c6c0990d01c2e7ae40c2797699de0723ba1e9c71644fbbd8e60a45225ad3e07457175502cccf887c6419729e5d233f88ce925a6e38e883b468ab159689a9439be34c1bfc30731782e5b61007c0c03eaeb93fee001b46cc86e5500c5250c609d037cec807122c6631148cbbe90ed04ccb002b1bb68731d3997e202e5c1e3ade9e085b0cd8a9f84c4b87713cda57e9d2d84b533b02100daf319b931fa324f88c61be9339cf9567c43e773480033d2f2d8848105881e5caa16b1b97d8aa4f0365e5347572223148cd3e6c42ae216572fa8da626e4afd2d5d676f591f0d6a8078b0a3eb0c8e11a2e1d50d7c2f8c322461dae8e28f158121e16a216e4dac7b8146b34364af5b8dac05c5296b63cf6885d0337386ae057287416714a8d60bd31a7e8fbe73a44d64a7830b03e4467904630db64c1fd0dfe8bbf12aa75278416bb7a62379e5908af7fdbab19677e3e574a119fe142c348a0ade6772e382eb604fb2d01cb4ab0c1cdd70922a0bf3dd0d6afe006515a22364fe03269e68c7d346c14ceb93e90407c40c30240f94d874b00c47d042b558dc46e78903b72735c1a49e00f4ccd32bd118e07df54e4c03bf1ecf404b776dfa655403f7682a9045fb35aa9f8d1bc0847a26dfcbc885dbd4fca5ff3c0b06aae975460d84bf80b6c38d2412044535d018128f80d6a8b448b0d54a01737e30824d40d2449e6ee71ff13396261ccbb8c22a76adba94958059d1f285c19cdcf8531f33534f4d2f48709b5aa55bdf1c4f15a2f152140ff5ebb288f4a7cb1799e8a38c4fa96887e9ee0b33702dd434dd62aa9868dc20830eed0fe2a6911e3ebd72b923e52aa780bc91d8fddbcbf9827ec971369a1c84303580d234ab38c2ad01091a25d981233c10d4e257bd49d3c0819c6857d7a935a2504e36d90cf3d4e19e068d0f1313a2d8fab37464298a6c2d150d24077ab71f7ad7b1fa4354a9e25775856f83281a91806bfbd352046f590e834b2a54dacd79656845e6ae602a583b8c753a66099c566da77bce2294d1bff61a82877b6cf66331084d6a0fa0db67931d18b424edc8d5228914e6da591e5648a9e346b1954231dc116ca9dbbe42b3aee4d10794c7443900ab943deff59fee0f96f25eb1be5109546842e48d1a937468d9e594da219b04423a645188943b962072c35387e2de27d98057aa6bb8242ad5575a43bb2f3253508f3aff84208b3d115693238aadf0dadd504035acd5c718bf42ee4ecd6a417588eb63a8af54480cddd3cbe1421916171acdb4f00d8dd10bf9970d7ff82561c3e93c51c04be7362e74f34bc271ed0c71f00051fa0a281f0ba75b5d5bcd2a9906f17c89945cb2216cf2ea931baeb938404b96bbcfc06af825c0e3fdf807d1379fe2825008fc0933047ca6f5fef0af2a0d26170ffb02eb65c7c0efd9cc0cc749645b21e4aaf0e6109c36c858e16a854f0e06130b01e21a3d0f40de0436f2c131e60083a125530dbaa972e8836e0c249af287d0c57c1353a47d11611732bf155f6ca888f43b3049841e930c2f501979c9cf1150bd0e9cb97f8826461098e6b4917e4d9c58c16b2f057bdf8280e071451b9a02b1efc1f130753a7b170070096b615307eb7b05f1a5476586d4efcec46ade9f54659a89c7bce90cd6cb8e74b35d123ce3918e56e257d97ec34f2bd2f7a49030a749793b5ec177c3c80ec25b8d4f3f2826d5842b28b124a5501de4be5beba1e2f553f6c732e5c216d44213fcdc569d8ac4508ea0943cc97342dd7c90efc61ea5502958712fa8f8ee29ba560d85ed26c4ea049a10e5623bba45676baa20651a1be5689b713d95ab659546f275c6e5701299da5700b0fb8c3607006e9d5299b499bd3021692f222f8f471f7fa7edb30f9aec7090c97064104d849ba94ab1e2d6b1a5a15c61cbb3ec713a3a96b4132e64c21b78f96f7e8da9c8da5b623b9173c0fab74bcb3110d0e054224d8775117d41fd69a7c267469139bc31398a84fa004e68f4f77c738c0cba4e85a3df53fac02726c9d5818e75d92b63f6b16e708cea50ea0cb18ed93088a0443021f1a65cc7ed705a1f415146db490583ba6cabe656e093958b76006fc92c65a1d03c9fb392fe7ad02b217789624966f5290a433d0b020898314e4d7887127ec3ac380224d89ab114b1cf12989c5be82f0962239370ca2fc431e31447e389b1f8b8c9c36e5fc2660878625fc8fa20c1ab15b01b950bf290940d7438304a217a4284e087b278287a633206258a61cddb204e39eaae550a66069fb417c1ebe81778116eb22822e1a043d21f55bf9cb5c2b23ed6f199283df1098bf61627015e390e1a3ee748aa99359d1407204c0486bff14ba778bc1d7ef240e519331895601426e5bd62bc71ca9a10afe008c69b56563939c464f135610ca29226286f84fdf782037f06caefe002a803496c33430ccb7a3509b11c03899d02707108c588fb92fd2b4239a2b2402aab305947249b98d4424e988191471253ca660bc19fd666b1f3259d2e44aba5d210a20c7d2e74085fc029bdd5a2bcceb00df0e6399947d44144a8a8ba6836d59df02334a58346aef25e3e310784bd6488f2a863bb23f22886ba581aa708eaa6a6caf91db9ea618ee675c2617d222ab419ebb381cfd2843fdad7dc1b4e517cbd4ce5d073cdb855e6b2b74bad18a5575fcc12d6ebaa20d335ad4a221338975d1f2f130a372bd920058f71d71a2abb32aa5cfa94589493f7f8d5324307f1c41dcb0f4d2411ec1d4eaaff88e978530f7024e89c0941cb03640c170567daa1d49c143ad8f946772666a1640473c45b2c1d014275940d3f296d4ef786ca9e22471bea1d64ba93e371702ca6d90e685fb586928e0b9d2cb753190730daea2359e364289850cbdac2623630f87e7bbd614fe96454043d768ec08f84dc0638cb09a67906dc4db41429cd026a70e3df48f689bab25a771fae402ef19ad7496c78cb9041e9588695644f60e2688f15a5e3f4cdf6e05026e88526ed7f153cfd903bffd344c2ff3f22f162af00917a4137c66903e33ba10f5e58471e3ab4792428742037c17d6f071c1a87d741d057ee5a65ac83b98143dc654041d1eb784256a0860c52a6f10f3a6bbfaafca305d8d2b493721120cb115c04c708c37848e110ce7b8d3095027aaafdec8e31cc64afd465e9c90478e081e7d600b76bc71359999d0c20bffbe89f45fe8e5dd3b366a2d0988ea42f0efe3a50dafc91bca61199e7f55fa7cf7e8f50467d591a2b063cce2c13517fa3a9ff0462ec56cc55980842a4d3038d22fa580c498e446f6ff1aa614f5e1c1fe1a19f16d55ba4631ad320d97035c6b2b83047fa3f8c7bdb1d16d9b92ce229279d6d068709a5052824b9b185d992700100bad3af02b79d7fce7d5ad4f8482bc2c52ce0a7454eab8413e4c36a1920a8bcac287e9315652687105aaf5046c2ae167affe97da9deb4fb4730692a5190f40c634d110242807e33002b3f76b0914b267f48775795a319c20c462cdc391ce0a0c916105e328f860c1d62935b6084a2d0e3fe255e852e501c08bd77e80c63d96608bb80d9850927aa503492cc141278e560dfabd6ca8e168ec9357507e457126e65d00087e91706da8cc5db1eee5c15ec92eb9dc27305c406a87c615a373a2ff3f50b8b033572b64a2554249190cce25beb4efac298c8999d7f74abaa97c72efeba05cfca82e27f6d1a349eb37e4f94622402034aaddd0a2b1bf70412c2a54d63a47e850164f6e1a67e360c03182067f5fad0a8af94f255054700d6b5c4bf9f14d11ede0ab59eaa84243c47ca3312fcfe90a65d88a6a02b405fb791ad056ac69f219b2b3d940ba0c4c371c7f57f79dcfc0554d7678417071438c706816f0e3a438328428e2c44be35f42633516cb85cec5bf697c78f2dd8aaa7b5f4270eb9c8d3c928fd30d199506d92913f6d2f5989ab6f39b14e280c12ca0c3e894bedc1028898b5fcbb7c05b9cf6408e1ab645789204201f317ebc83c7ad4823b71f75827d38074f0850783796984777dc352191b02d8a7f5b1092b2cd7012c8e665738c103d452c4c83dc95085bcfe2af67d4b7820baead7d88a583a52d7b4ab3fe6ca1f78ecb4d8f3949d7f4000a7c84f3fa4c1e8b5c932be04801afe02b1a0f5c5bd774ebc84564c90898180b21d0450a0c5e6e6580708fcce6079ee04d47bf3d4cc38d2b52db6fd39505d406f22c8c6c0a83c84e2ea16c4332b61b3a1309e770eb12bcd412bec8ea430b25722749a2da71b8e99a9db6dc40cc07694791bec3eaf0e10c0deeedb33b3492d8ba78038021160c9292baca305021e6090c002efd57f87567b2442cce2bba2ef0727fa18af2540d24094fbb9445ade26181f1808a87763d1a701875f14a22791bea892d31395111c63289d15404f02e195fbc181fa1fd9cf18764683b39131913ac5ba0f6c0417acef83c244c6dc1fc18b2649d9f4833134fedf31a822b3d1c56713d1e9ffafe400754820434b5ef5c4b15875b912c6f266a3011e605914e4cd62342c8328a8bf4a70f0d1b46a9e3db5585e355a1c795733d2913d747280c415ba83af6fe58a558e68991243d48e936315a5f4e108e3dd2bb88fea7ceb1fc27c8948541a1ef560268245ae077a1d3eb7e22f58d4d8e04f65897de23728799673dfdb553ae194208d0f3be2f4907ea6c7c845fc4d85b770ee270416fdd15c3cfcff161ceade7f0e0ff03a4cc6e40c0141cba562204958ac2b41cbc4aef7536c82cad207f8fc6554abeec95aeeb792f34de8b81dc1011ccb48856e1bee86a376c6d5c11930a79737ad69dc22634aa4fc7bee2d8ae8eec92c0bb344471a5003958031233b725bd8997b965da44c8fa518b7645f30eb2f453046a60941de3e16e344ca658bd7fdc8d44b16438d6fe1811686c02c022028c9c5b645a27046e4f34d51ee82e22c7ce60ff589c38fce4ca6484fcd761ac6b7ceded1846ee56680b789854fdc0f22662c2288932fd5d044257293fd00f11974611f821215a5470cecf40561b3b8ef51381bece1e37656b4b2cf7d0f4c7fa3268b52a17d64c55d80a50a138b2dc83858a08a5f2c22f364506e942336cb9df6cb274140f8bd4c53d9a732757eff427d01d4ad1ac34c54f9d947cb6187289a64f2285dfbcbc1a7e2f145d6eda48f0c3713f4c7a9a28cf63ddadc16253ec1ccd6476d62c2277cea4c1bbbbc88d786aa6c56e972b544c7e271d9e04b08487ddee513b0918b121e4ead356a27618023a8d2f304cc6589d2e592a33f9492822a101768f672d0687aad7c2bb14e7413bfdc10e084191a6dac90732daa9b204a1950325fed55e26b1d1aa0d3d260418aba0e3bf49dca8d87336b3aa96d030f8690987b9b817e63cbb5fd069801be466ee6a97203f777df9f197a4218c9658fed957326b668320de095305b56664825394678918ec1fcc266d70b5c8ac7ae8623f804c6342994808aaf3b9b943646dd81a81bca9898539124dea90f7b1feb39b9459c5c5e9dcff55680b9853f0dbc8afb057cf9b251d52ba0df52b77b81f96f50f7e6be8b5c1f66d69511c8817c1790ef4d9fe0b46efb134a2afd313534bcecfc7e8bd5a09a8fb66f6cfa2739a666aff78a794773ba4a8b93d17b4864aff1f4107247304e8cdb55bd37c25f1198bb051fecdb9632da11f533ba675e712cbe447f2091114242d5fcb26cc15d67adae06d713434b45f6d2cbc7d30ffc5b1f46bd77104d9667ccdbf049574fb3d435a96de2020d4be695f7c18ac5c0eae4aa751f4f584c98e22f87058db69cbef6497f827a8dd83ca3291e9908bc6e823e0c664e00d1e3f7c300db4c0e20c20a49aa21c8c23f3fa68f053872de21a75d5004fefe34a544dbec01a9305191508a91b8037de868ff320221d9a65f6fdfca6a69b4c3e5774159a28c144ffa781b5179e98b360ec8623bdc623bae1eb1cc2d8bad25266843ec66f2aa5a969dcb7aee04769ce3aec9fa0703492efa231652ad71a17603477173c12f6ef1905a5d642b715309f077635daa1abba434cf2b61930bada3322d1da926160ba3aa4d33f49f2270f44f8a8ea6d5338bd5c95963bd18f522f7c159e1c0642e4346c03bc48a2b2b25c3a7a044e2be30358f2751970e0985119bfffaa0bed41c9a8e7e1578f4d0160747cf19c867750240cf5712c1b6c69bc1fd5e47cb3c8a549d95f99511bc7b0b97a41d3a79e003a0ee861e7b1521a2a1f6a9218665afe0b9ff8be8004f6ce6f756e51f09a6f2cf0e5c1766a5d575dd3b75c4ea7e342c608501735d193281ac42f3efdabf691cf7f121feac632fef1655703e34322a259312fb754266b6aca5e3a152cc88a2fb5b1365c7281d7995123d6abd1c75363ec5752f14fc02c483b60e14a17f039334314475d5814550d5d4647d608b39687fd287023ec98865820443d8a11b4da60874c9c9ecec2a71afe4f68484fe2748ee82df31cf9491bb17acc1126421b5fe99c423eb21dde10dfc6a3e30945084a66095130fe79106ea0f3c0fe54e1e8eff85272683764c0b26173397d339c0085002254109c75f6aa4cbe22c6eee8e9cd8bacb63cfe83d55e4792cb5d5e856cd7dbf91c9f1d1724d54f6061c75f509039e07a76400b253a568873e2e5b0785f5e5f993c1325697d48067d70037a74498705224c85153cc424f7066a92614f52452a9d49913acd437e2791082328c90871529923638e12992548366f15d3421d5c24e9ec526f47a7b648d11e90c0591f3569e216bc25c692b807c76c0d8b702ffef996fd405a91c60a55fa3a9eedb6f9d4dfb1c03ea6014a4443198ed680346ca3dc6dced30814b0995b893d8b4f347fa7671adabad2f9ffe2b2a1b2f571707c0f64d8490f89c554dcc1832b2707506702c4f81a778f45c6ff8205a80ed238d39c0b94c4a47f37d39fce40346c09441b5d9988cac69c82acc5641f70a821cba540f22ab0210b9187128f45e48b771570ffbdd22d8977aa2a372cca4bb0d701cb1d58499cd6b149e68ea4721eb5995456c1c786338eef7a301bf069b596f9acd2bb13ef6c76b92a80e3d592f89a144ed79b27d991fb1c29dc57488b8093a5569327ee030bf40fe6dba533c2d881af14ed20898caf6ff0fb0507b7d842e60030ea75cce25dc3fcd042cd569696ffb0944a19e6251cef2e98b83a1fc623303bd1da02ac805b4d68da75192d12a03418d70d37728278e4f1f616f15e3bc75402cac58527097eb02b3846d0f85220ffc5540588fb4634ebd1efe25762aaad24050d28305afd583a0ebd0bb84059a344ab514d384ee2d42045dbc3560efb2199968d29a0c066c7fb7086684037629260d8d323062e417fd3ff6a0893a0dce3bd3b2b588ca4d0f3b49b0b2dc898a4b159d8ce15adc520bdb1a9f89a09a83c655f3b647e43d63fb49bd0302914b014c85ad0964b89de54ec0ae40b0a176aae46cb4d664ef2f6db723484237d4e0b25d554a0d776c539d2528211adb3973a321e658b2b6823b1a6ac11cd0f808afb2aa0dda23c687f1610801265fe7c584d83d8e2ef1270a5f1a346c55b73521cc0e1fef2461f26fe71da81af52fe72cee14630178a2b398631a339d21aed3d01f7d64f94373e988b171242f2e0d07601da0c53640a2fe7e57c424d67b919b75daaa1a52bb622bd44d03b472981c841a0f207e4597804ef928d1421c24150260f2e1b5943329b77e88e794841a4e98e995227d470ab47f4c82092c8efe6638b7c169d6b0090816fdb5845f9611702dfa8cf887d4d20dea865af50ac119777ac2c8044bd027923421c51272834fff10f0001313b816131f7ac4e263dd5f394f19afe9cac9dd91651426a8b664dde8138a5f0128ad092f7aa94bde5fa842a955f5d3e66a95a70b4c26aa2952742926ef83093caa84c2279a4579554f79853e9c0a0b50970b730c67a9d48a11607cfee2bf9ffa6346929ebe13773b84bf17492e6a82876819dfa2d2f9454df010853ec941c645d057d0c021b4eb85b71c3c379ce8fa0e7904c1e34dc89fc188ec69fffcf4132f2ba7f23c460d3adb5a7dc061cb9e5356c19e33d9234a226835f9fd3fea5893435bab5c4eacea7942520b21a1c663cc3030c5acc20e72075c880d587cf06602c67b447e85d5f1ef036e4aa5994c431abd0a284a51401e4b0e11552beea280d230f2e578fc284008547382aadf59e76b52576e30e8bd15c0230b901c147320228ad3c5feb051dc69194690443186387f18c181b216c0b4433144754013d421f33feb2370867af831c515c3dad1930d568ee57b889efde1a1e05ee35535989f5c2ef6a8d8e513cdb9ca0e9af3a5c3cd79f941f3ace8a4395f3adc9c971f34cf8a4e9ab39718c7ef467f8580092393cf8b4897e762fca87c5f7ed28c2f394773af578a0cf3aae3e6868e9c231a335f65b2201e776c9edef557e77c064eebf0ae308563d81afa36c9244cd784b76297794177d4b262c991dfb3d75402068fbdc79c0aa32686b8a4c49b8d8095cb430f026772d6af2e59b1a185f1463717b7a34e83ae82c2ff67e20f284d8b9bb4a4dc98e06ae5d6df32324abefa23be184fa32d0bdc69c7e7d2b009140feefdef77daf493f85d506ad7a30c39426cbdcd632a53222d9273b2e213e71ba41a80646710aa10544135fb8c7f124844291df81aaccf391901a77503529a1dee3a4573737ee03290c7a9e87cd2d1f9f4e3de637e4694da56ec625b3b5c1306cd9a627d83765bcb48632cfbf1e88dd2362ff15edf6d275d150a86a26e3b5081748bc602cc0703b15a3d6d4a5e36cb16fa96d2f6d16f9b9a8e1f92007a022c0de9c18009d24974f7b448598ce4e15f7488736c04442ec169af8db1fba677abfa9b9231b839b67a60152f601133ffd0e6058d44e88f6bd6e8c9283e84442761522abbc0192107d16d52eb5f8b0f38cabc3b6d0cb2bf0a963e7ef153063d007987c3c9a20331319b8078f183251a01762842d93123679c8374567e1b648891e03f48442e29055bb087712023cff6b80af8b8484b7d90426b18c97661b05a7c67d85964bb13c5b27d237f95bf88b970750424e9cd9e55f509f22c15374f2a62be74dcdcd3d139a5317348a2cd9f449eaf89cd63c72e77bb3944526bf38dca0fe256f473e4cb40c7773caaa07c727911d9f25c9c8c1c1346269717902ec7162463727d775021fc696b915ed585d2937238e0e2a16fc8ade0e43e9509fa30d5585111710f2317661078278246e07183016be444b8f936a42cd56ab371449a1a235b5b7288383f1f68ce6c4d883d0bc6019cc028640cd9a33b8ead9bb561e03b78da17774f280c8a82010198f0b694660fa820dfff21a7875aacbf3851973eb3d0e3bac3f1d58f0d45343c1d55b9a40d0ee6f9d565793fbf6217068775230acc17cd3da9a7e347820cbfe74f379655bd97a386cc35ac64dbd3422300d520c8559ca54be5cf1aee61a74e399116028e48e057441858aab03186f94acc3ea70984f430437ead796cd7bc20513d88196d3195dd52976f226b54c2a0c31fb261fdb953615362c57ebef9c24dbcde6867828694feae1473bd4c95609453ef5b6b02c3a1a4687c8d2ef0d58dd8ac0b9ca81e2b6ceea6ca028ac9acdba5e009bead7eb941db19c40ac8f84b648912c6cd2bceaef22483269978fe086f720af5a83c82c3416b7b025aaf6929d12f9d14a5c90bffad2e97ee175a5a802022770f329d1eb3f2243f81984b1407c4b9dc5244d1c790b185cacd852be1eff2bda85970460e0f0b86a6755bb67768e0a7b804135a140db75528b7f7eb658ebe4c641139583e1a83143cbf229591f6b0be8d06ccbf21833e95254e1a41559fb3daee156a295930683b26dd1dc7b22554cee263927d0496c7bcdec6ffba2bf34fbc58dee3ad5968735f0ce6a34706f068e53ab0b4f92d0a605da06595728f2fb07c6ebcb592c4956446c993214f7329084c79af7ea362b88542228b428d250d843ea655c4e2f13a3c3de2c9e20c0fc87113f0cf32ac9888f5bc64515c8c0c5a86401045a765af4b4950eb8a61d4082580a88e40c0c4c38602c2076a2a4f33712c3e041cb8a7507479b2e57ed02eee95100a5407593944bfccc28d05837db932baec9db993e89f45c59bfbb0f122273f9f9742da1126848fbc8f7beed51eaf73f02d085555a87750cd0dd2ce1bb8012608a711b1e1993a8a4a7e8f255ed8aed0f5ca232167fc14a0af8621c75a9214f6dd2ac0feeb5e3dd11b12d8a2a0287592a0d11841c8e53e7cff71ce92adbeea6ce05936e1c69af35d962be45dfb40bd5d7e43ba7e6a8acc2818465508e1fe459c2e169680eb4bc6d07706a6ec71aa36a024f95164b751cb3df4624cc75ae7261801ce072309297426710d39fe2fc186aa2138e3f94e4d919b9c0ab488ebd508d80f9bb76389e1cb550e38cd5f34b29a1f566bee5e9f48109b98ba7d4e4d86be72046222d1f237938f5c0df5d1de61b900e6866205d5cb166ea0f858a81582daf6059cbaa39522f675acf2bbde4154a10188ede31645aff9eceec3959a15ea0ddc47140d316502c7fc08eca90ba8a47e029b827eb849035d5217b1e76fe2cfbf5d94e2838518def8005095f30d2ae0d738cc212b3e827e5382a319eb7e72766a7eefc88a08abb1ff5ad1265e9c02a57ae99f9a1c6fa1d021561fcf63ad2acf361d66572d71e71abd991bf9922ef7e1223b07a00743467adeecacfeb0a5007dc01672d06797c059b9fe8dd00ff93b61cd798a551e2ad39f65d8d103bc73b5c4fb0981c74f4bb6f197d3cecb121b1326ca5bad1db48bdd123d2e25140c5ec953bbbc227bc3200442e1c9f87fd83e10b48fac1b8da10bc4e0f2b9626681f11f38e2f644876db0a7ea0a012ce9159e73c9c49a3bd9c0ebd17700f9c6eae142710c1cff0a442380e0820bc6232a598b3ae0be13d42d1d3eb1839c703ba1587eac279617eb41ec8536c1f9882237473aaed9671514fa821281206e601d31a621f0147553e4039f8ca6561138bab22f06ad33a5e667f911758200529cf166b6cb85449750685570935d46b1519d7cae67e89088c50da95083c3a1b99711668872bedadf0a65fbe3080f82a06e475a3ef646a8aaa20879451f44bb75ca9f3e25d17fcaaa625c7d9492b13f35b8e730db742cef271c0ec0e6e1d03748e7866d3eb80aebe4076b883125e1a7867ce9c47c9d3c7088822a39a24e5e5161ca78bb41f4a84055a7a21bb2e0f3bf83728d95edfbaaec8f1364d1e7cd8fbccc7651d42c29daffa467c74c34a52537a5eb73c167b2fe889d67055382d27827153ef63fad8b2b8a78986109fc1d1a94b8d1874feea48c28ae0d5f82474b10194f120d446a8316405302c2470a94cd5aca53d3757c2a4fb7952fe573a175ebaba0aa25b7202e1feab2503cbfa8886ebae332bb8abdaf1e3e29dee03871bc0a4b0260b7b9de8a9a810d11da7bc077c90ad0d29f602064e421fb30d6f6bed6b669247c381988ea9088cd1f974a8bc0e227f609aebd4aa9796aa746ed30a6f171c88a4aa8dcb397b3ab366a7885ca9b8f122d1d4f333b50f7e2aca679e8cf9da2c414e862ebecfde0054c0dbf34ed7355a2931346ae766ee0f1d4d3efa18b5463cfcef05d3bd7753e17e7ce52ce9943d2719702452471c196478d0ed0bd9947d1d9fbb3e373121135cf6a7912d7a4fbaccf1eefa1d1d1f85583c23cae6225126aa30b8a517776f1f270299af5803de60f120b4c0892dc44adce4ed42e6cc168828cec2302db09ccbed6519fd128d385d1790c02555ca6d811cb7676c058e6349a7c40b6e8079d25f694219cba3f45e671e5c056dc7d5cb3378f906137ee1537d9995304c318cee13e6ea2c6c437dcbdd9e3965d95b278501336f88cc4d174715ff698e418aa0605687766b574ee7ed94b4a7ca89a12107accabd0ed3db2e792f3703538a12998e9a18bfb64cf498ee16a5040e5664643e7ee2dfb2e50aa4ebc4201345f0326d2fdaa65ef34a9a16a2848e8330fa1e3f7c84e6b2ec3d53494ae6066842eee8becf972c7590dbadca53352a2735540f6265c7e9aa64c57334614e8b6aac89eaf3b9f09d2807b62cede2fd9e975e5c9a17da97a6d6784690e5529d96b7af5f4663dba3283d1b93cca7c45db7d7bbc72befca038e951c24847deda80f1cdcf138dc119ba5d7fe63227d0ecd4717aa45034c9d4864a7799cde29fde9e4e8ac3ccf79d2e2b6633e8c13197ca3a5f31404351cead4b2342157a46010d4739f7967044480d9a9e918111b753c8737d5c4755f5a534fa693bcdf920d465884ecf68a063282757d211213a3fa34003a99c7c493b22a4a64acf4890e86cc3aa2f9f97333f992c37f6cd7044f5fdd842a672a8e4e9ffcb579705f49deadfb17845b28c8f61969ce385a8bed4b7c5ca7e1f1a92284c1b2de28f360085a163442d19de01746c89e836f21f3c53bb3235f2fb15a885f9bedf976601dade1fcb355109a69308154782762c54d3ec4f66a82e61630d2beedd16054610cc035a13ac69f7bd00eec7c15ad6e2db161d367f7fc05a0e9d8b72bb2c49773b65cb5ee5465a7389a42fd5e51526ed125fe1da29038808a7d15dea795381bab62fc9b918792109fe9d56bf891ced9c5f968c131e73fb29e7eb0503de1c299d8476560ce6f79e910385fd8a59afd8562936d55822c929a1f699987dee61923fe477ccd9544656fb5d4c86b522a3b122968c44ec18f29eb9e5a5d60854cb445943538f2fb9c77fcfcccabdb381549cf39cbae79ca74118b3ede91ca2c3e6d99dfb315e2ccd2f7746cea28833dbecc89db23ce1089723f766bbfb3067dbb48e13e44718953cf666f1bd3dbac5b996ce4f57c3d1eaac4d46c0b8904a73b75bfd6adc78b0ae588bfb2bc67e77e0288227e901b4b6843adfed7da8a501f3b56083ce7faa57bf360b7c7e8afb01c9fbc3442fdcd0cf5f40d30bc44a1fe23294a1dc46b4bc04998fb0bb29dbd43e6aa83de36b1bbf266416994fa443e5f794c3bdd1b7bcb04146548372211e8edc163534680d6f29f80be7600dad100a891073f9e060c01d03961c216e4f4a0b9115c62d032e63faa7f8f2a17458e6cab1b223e4df17b3196bbfbe936ff4ed987e1b09bf2d3414f0122744e6f93ac4ee404e1956b6d23d61ce86d30e548f9af0138485042bf0d37394e4db5e3ed768dbd47a0a5d6ca5fa41da422e93141030733c0b14bc2d149ecca0a4c5402d734e0c95bb9f86cddabddbc87fa1cd012639d241a7aa24380c48aaba54b59a96526c24b1d108601bb91863e7cfba00a8afff5243e41009d5bc239261accefd9a4e15cbf51887f4f5691a348ccecc16b03b4cd0d7334ae5d0888b6ec5fc3865e86aab1ee90a792428587cd176c1af007ec5003ac1754e17346ea8ac317df6ebaa599733d5cf1edaa937335e79b32ac4dcfd4dfc46a854588c19156d6c2e948b03aef69aebf0a5c883475e8ed4e5411ff4928eb2d18d42cec3443f7deed099af1dd3802e0f3838db3b662613f232bf5ab0619937bfa84ea6cff1cdd60638cf7896201a6265c2c3754b5b1c4467f799e6a55e5b8cc8e5e9daea3a98be772f440df0e188767d4c8491ef4113e86a7eca34d697b2b49371e8d98f87bc034092ee88fa2f77e4da59d4de8ab4ae5dc083bc35028702ac728ae3939fbebf517cd17b48c6e9889f1f22b1cb04b6280edf05094fc430a34c9d5af61d32b4370f282067e0e483a1896d2473d95a25359f8476b2789a28291d509b4010ebce87e9f06761011b0719fccad2cee3a256f0d65a112990e8f010a01c18d4f06fc49741df0178a1ade44904ce7f0f2898e33e9a3b8c80a6c46a06959b1f5c393da333ee1cf8a1c994d8c27cedda39be634ca8310376bf84a6339576e5560ce085af853d5cf24c804092565a45ed247fc5e1e5aafc6d5b6daaa4e911f69c448a8e5d3f9861284d9b22d5095aab2664c950b68fa4f1b5286974254c5c9a597e620a211d38c0b870c63f98acb04695e26e671a67d47d0c6513c88ab812201dfb6ed2e865ad5937775c301d01298c5edb17b942013533a7a2fab02f2e9289080aa0675cdcb858f57b6c1abba7f50bcd58b6a4bcb8e8226dbcc1505a7aea01920e44bc4992e224e7e08542394e52ee8e1ab6714785f4f8ec4ca1da86f94f68c0885fec88a37196df6d1f3dda70aad240d8b3ca9777702307f5b3f88faa2006fb156e547625e43e9930356a340b3b334491bddd3413015f2ab8f1e1bbb85ed642380db05d4ba68d102965997fc713404e5bcba0e861257d721e3592f80c881fd82376b6b1fd1fc67d1080a291a408127887a9adf62b2a4be42d9fe523bd31da428eceaad1248ed13651ffab9b83ee8ab0d2578e5549142e9165b8320ecaedf7719ac7b03fc071f129595e829fbff4f5333e662d7132371485f4217ed8d9af809dbb2320df2e6f95dc99e28b972d6c324c9a11a2c0c4f6dfe55f2c28a88a60d93346f1ecd3055664263b8a927a89ae1674d5d2f685b2a1901bba079b56db1dae260fa04a2052b773aeab0bc07326e5c02c7a481356dcdcde10403772bef6f6222d44c622d78c0d7e87096de7b01cde9719e01723c7a3d64a2af7677ce1093a54b35a99212f8dbd7eca32010ebb2f0491a9db2165d466ce7e335ad2ad2f96a6e549f82acccd3adaf74ac01f912d24652c6a023f0be7017cf13c2ae1fb38698d809ffe5b97db801eae3c9cb0209bf05d78877084fbdbe1985e7163b45f6004bd050e6e2d814214ccb886bacec0a0d974a7caceee9880c7c6954b6802006716c350ea2e16dd6c91e28eb3eb30a0de2bd2ec89480a07c0df05ad701d5425371e46d9ca9f3d1ee973e1931925a448ab1d4cc648c14243f20dc48fae203a6c3a86e3d7a91b17ca88029281bcd6515dc7cc5d023e6468048007ced34cd80aef49d64927dade5c8130f4d39cc11433f331f06f814cbe57756509c3db2cae920a365b488ff77f529feab08278f082522136eb0f614fd43eba85a713277fcd96a704698e2a9b24ba49a61da602a2814c7a489b825e2232b0e38c6ce9d0c8d8136c881a78d1d4a1741c35a889a281e298cb0623f74ff43cc3b7788404fce52ee0a3ac48cda53920ec8b22f63086e0ce972a04e8b3f27025a848a81392a7554660fef985549e2b71d72df15e5219f1e481d5e8b61d7c396d9262a20f2f4299e07b8d3e7bf5782562747d0a7c49adb7e260b91fa3ef275180976a776a5723b480f54364c6341979e3a8f45774f5a22569346bbec0b602efb8f0f2fffb90a349a6395b97ee1541288c737c8046da124e846786f70de13f00120247ac192daa5fbbc8e259c6f253f59c2a2e149346b175519c6d46579ece70133a1fe73681c6dd856f8504b81ef48bd9eea7fa6b9cfde6420638af2901436e6434f052b35be99f91840fb80023f509fb962b694784bfbcc722de957c515e2822ed2c1e661c85053001e7601fe601906bd36a60de9d55e5f1f7c5f616d6afec9396a839f449a43549cc697cfd42c135cb88f043c60a13e6e1f115d848bd9ff78bee8d1e2969cc9eb866e7151baaf65cb7910ad020ff4f612387c6665f145c75fb1badc0ed18ed498cb3d1373ca2399957b4e7c9d571a224d24246014db59a0daaf00fb4d9287b7be7777d079da034311ab05ff62820578a984ef4ccb1f7a8e1e359e93e3552929b6014b90e8c23bddb630e1b88fa8a54a91a37e86e15a9366507acc4d180deab18cc2cef47ac1be6746761dfda4e93c4c9c9360f28b37535ebd99b2843bc0d6b6c63ac1652865784c215800d72dd00fccb9316c829b6e6762ba7b553f25a8412f1182a297709c606063c9d3b8fec07606e4acd59a14d44a915844d29fbe15e6d359f1a327abbff9e35ff3895775b12323f5ce55df4244f63c99366e02734bcaba02456866169aa6835452575ce29cccef2c6efbab94c1751d3900dcde7e9188defbc3021d6a4d2fec24dea49613230e7ec0bd7d4b847ac3f1234a4504320fd84e7bb240ad4b6462b62e24fedc9c586ac37d6b7b8b8de29bafef29887e3ff839ebed54a39fb90016ef63ab8058fa6cc9a3fd8081ddf86ad5d4131e52cea6d062fbdca024cc0f85766e78e720d12d7eeb92827583b2126d0dc3603a861a610c3a07ef1b13b3640b263246a47bde44c63f3dc11bd7f7cdbf4a9d2cb6d10f2be8eb76885abd6aef122a40c6ecc67f60f5c27164d33debf69df4f22c4a932600b4f2778e7451a02aad82e8ed7a36096f959ca4ef89cb74506870116a629568932b1a597a4c579a250aab6a62ff27bba41a130d518e5bb0a55cc20dfdcda6f7d0bcda339bf2c3c7eb6be3f8478689d1f44454116bce05bc3e3d9863c45f2b129706d50469ec01601daf24dc17fd797813aee415a962b5986c6d62361b4c2fe0e345c5fdc0740fab7423dc705c90b1e37199f21ccfa209349ec8abe1e716016aaa3585a9a86c6622eb4dd53562dbf14625730e66974a1c1b2f66acc14eac8fbb0e794961e6b03b9af0920c195dc89c88c38da5845538cc9b31473f1055afd89b864626ba73504cf5e0540127178e3cf608542a7e13da42868f1625c0099e46b76debcd66154b4b193cc1385e900d7d80b53ae2df3d82df3a5d5a3e819b831576f0b26be5b8112aba6f2354fc0d193eaee7e793aed52f3d0c3b1d6f4349f980e8251b32301f9a6a04e40f320af66f916223f09416105bf2f3f14f36517a78effed1c1381ea19bd5ff77df1e15c13075401429ef07bb13e30ed7675004ba5edd43bf942d74a86a7481d2a72e52d2ad34202896c900420f3b23b8d58e218c9e5a06220ba87ae01cdad1760d92cc941250aefc9074764f6399e160f14aacf093f51674b6c4117c9adb1c0ed0ea84fc583ff4d8215281ee7312d2c3121dc8dd4a5890bd10a7a4a92fd74769795add148b2f2b23e8a6cf266862de28f7d31cbf9b8dc79cfaa6b5f1eb7a431a1a03b504a2a3ebcd7aafd1cea4b22a0bd19a2c95f5020a7307043342a9ae15d82f9bfa6071ab6df6935980855c67ad2725dcc2f6a58815823991b13fa491d646b85fd460b1b22e6c659bced91c08d235366dd08cc7760fbe3ff7e8f6b023734f4ea6053c7bf9e2a810dd341a1e2ddc33edd9f861c7f85029a2215510e0746c4484e703cdc5403d2108644191b034ef14f0e61c2375ebca180d68af4d30a4110249e028a3552725720cec24a075d4f3cfc3c86f36c83df502ccb825eb99b04815e1f9ea42d0b690b0c0c8be8ea551e7cf297992ae260409403152e201a62ed8869af14e3f7aa787ada4915ceffee758ef4108fb56a76ef4dc8de5bca94520a15083a0775061f861bd57d210b59d048ffe646fad999490f296cdb2a1edebe707ac8e5ed1ceba11e6f67a51ed2e12d6fcf51851de970243d5c1b685ddf91cb91f470f79eefa8c791f4f01dad4fa9e5da404aad9e4fa9e50eeaf8945a6095e83b8c74048570bc6dde27647376ee8803602edfe112ecd7bce53a9ce5025df07185f5380feff85b21eb21243ddce5a1917ed9f123e280e7bcc777c401301f6710898fef00152cc22f1d898ff78060d821f1f156071ae997e00ad973a0141fb0859673534f6efaf616181ae9dfc015b2d7c0d01b419f5eba10293a3cba10e9eaf4eb8120a5056d201622a5851e97ebe47297fc38f65cfcd4e9757c2d6803edd7428f73eb05e901b706daef01e73abd7a45415a4ec42db0d540b18fe1e0d653a66daa410e1c3c376cece8e4781dc75a69998ccdabaace60703125c667af5056cce01241bf3d04654599cebe2c6307b616064eb88091054c28a102149880044888c008218050048107c09e4881b070981a597ed1ad581bd5431dd84e1ca8adaa7e302fb5348eac7513c7a667672b1b335fcd57d07e3d0a59d77a350d1422b595cead691ebf30883973492d03851449293d4ab0999999995963ed084d86a01094e0cd13229060b3868b285369e4149bad8c7a29628ca72c4bac81226a83d7a7a9269ef50a55851755528d9beefeb166531346cd166032af81e70945430731a2c4f172059b98941aa5318428020c2e6cc080a96b0a643219c9204959a287316fc404b1640a241e6c0003260a20b2b8218d7e7ddae24dd50b599665327a9bc9617043421e14608b25a00a3a9eb6480ab97bd529f8cd34cd373073ed53e7326d55edd6599a5c81edb3dddefee4b7d1933104752da8bff1ab57888e4f3e40f3460cd46b4fbc3e9989fa70d32731535ebe72c132e5016e974c977af7dabb1454f5b1ae003863c69ee1e28cd4192f679ae4182b6398c634f9f56e0c0d6362ab1d325867a68801835bbd3e89e9ba5fe7bcee09cde926dc94cf71e60619ce1c49f213cfec1035cda499a96f007c777783a10a728dec8ebd6613d3e449cb0f3398d9416ad1cd0f2f68a192450c25519881e2b3f9d99812b8c0c90f57d2c8a204cacc0d5a969951d21ef0030c3838e9e1891a25669a886961c919687c50f205952fb04cc632555d7668992f563fd67c5985e159b3e5c79a112011b3c10729e034cd20e5082d7a3011218514679218134499244f65967cbcf131c6f863cd36e3684e324d4a95a1f493468a8c18a4a864902223835494a6d92023440c5e60c2822c6f9284d12f46a8115b9232736587965253684d98f812061218e23051957997c5675986c482a43349dce890450c5d60998cb385841351b6d6dddd69be1f2d767777c7ecb5524e944c09c638bbbbbb3bb63f49255981dc3a933a3203abd3c82a25ab4c665946a64d926db6260f993459a6f174435901436bb6c858814346460b0e64b0289139220622903c9111420622b848da9ec8c0f0365eb71cc9a22343371d5335a60b346e64f84983464d0d68c02ca181a2610b24689a92a0a192040d53929fd644b3e4270d9aa4a59f38a60aa926624d4e4d55b8962a8ebc105fb7c03003503160420e4940e1f0c6062edc606114068b2aa0bc780283343f6ef802ca89274624f52046e9a598243a51494890c90188189527699e083185e3767216e38c2bc417b22edd8978a8630fd675bef4211f7ddb03219a69224a14af1d9b3dfbc2081a89df1ba7bbbb7b3b349a4b9711b8a9bf140811f610f45fea635dc39f5f4d9fe832ea9060faa3f9fcfcf8686fdaa642f79b4b0fb7cccdb30d547e69a0904c7e1b77129c464d712d4864bb3011a74b139667d0087f095a6f644ad9719aa6691a38277b52154e8bfc528d8b1b1876bff9a639cbc3ccb9d63cf3d6bab58dbd22e91d65465085ee25d84a703b595959674a808bbe5f64b32f33c29d7559ab5c997df15585b42efbb28c9ba596c9b860c4822b624599ed2e551621094eff045cc79a491b7b30d9037665a010e95d00336c6949fa90e7f983b0835f6730ff33af70fb1a57dbea4b40d0131832dfaf5bb0a8f930e8b5ec0ab9c6b3bf7ebcb5ac5b82e9a2c67c6999c195382c48230834989c01e606386090c860066694110331ca58f3a60c0ca25e2045550bc850c20554c680e2c60731aec0218c2b94c05883ca8c2fc6f0a24d1767da64c1668a354e5c303165849a15a4f9610b2568ac50c1192b5e3003a70c19525e90d9628c1662a8d0624b9826b2b082859428276074b8a28a24565471a40a34a878c117aa29d47819238515514075c90295041722b6303df1e044850d505011430be23cf1464b1859b87042aa09304d5130f1c412589428028b10577a48e2cb12125f64b0a2c6113130c24d153654cc1481050bbc1001c59425a4541922ca0a9a44c901ca14330831452c081930b9e049174ed00011e6872f4d9e7c68eae1082643f000c40e4b74f042c3122f30283923872a1cbe584a7383181baaa8814b122768404205536678a2b4830c52d480448aa418d24882c111306098da17c86cec8a35baa8a1650657e2b0208d20d06072461437c08902890c666046193110a38c356fcac020ea055254b5800c255c40650c286e7c10a30b0e61745102630d2a33be18c38b365d9c59b509c3868a355cb8c83275454d1169a06cd1048d9233503498813a52260da93764c418c346cc192dc284a1220b2e586489ba02a6882ba058d1a40a255470a1e10b972353a4e1e58d146244c1a6cb19a8305ca8d8c2e5694b964d9dae38a08806406140930f942c600b0d40b61c51401a3fde0c8921c4c68333090883002a0ec0c5005982ae14a0080240f1d1a403250378a241004f4780d278bd0980181cb0d9e0cc4f1800500172f9b2f8951e45f080b2a389cf539cc240a6e5585b69e2556e9658a2312b716c9d939663bb4bd543db523d0839bfa90f1c66fc5c4158ee729dd065c0561e6598ea0a465d33158bc55e10e25f97000b2997164c2d5709d1e6c30e7ebba732ac7cf8e3f709a50f15eabf59978a85d6d70d0b6917aaea21f0ab74225ecf9236d72ca0b0b86ef8b5af4ffb16c6fa14b682699fc23258f406daadf27864aa874bf5eb91979abd23a473eadb2e80639c145b3de45a6fef21d782ae1274dcf313a20b1374adebd8d8b9b1b3634347c7f79bdfd640d2bd4f1b28de30fda5e772bab4e132036fd8d80193360a8a0727bf737d7e9b0229d08272ea80491bd32e31443dc79d8eb774be21ec81f468c30cb56a080b690d53612e96f71b98cb683fc80e27626e8802d1f7717938bd224d02fc9a495536508420ec81f4a42ad9e631c984f56820e9d2b91c9fc2787c0aeb8114e35a2da5dcc069642655c9c021fc928ec4612cb0075a05b55ee6ea05d1d97c74368ec7a7e33d3ecfb92a26282c2986e83a1e43bba7c37b7c479c61ee19539fc660fa4d8185c2160b2c14ea943eb949f2d23fc042dae6a50f31c2e6c3eeb9b8dbea2111da0b084aea250b52c15cef787caef53adff1294c3d221de8623d1767980b42ce0f519a5b44242b2a92390716ad64982b630cb3bf482c2ae26281415c3ebe794432b396ebf0240dbcc757690a0b3dd42e8730492f849c17417d488f314c76f90ecf808ff370f582f470224e00bfe4900692ce63474c9a3f8282bc22571097cbc7d57305d1717da32e03e63911fb7c2eb47beefa5ca892b90bd1755c3d5709d175dc28ba8e67a051ebf876bce79bdefa6eb8069f0dc7f1e5788e8fc7579f090a4b4abae13b9e64c3a76f9f2b888e9fd06f60def6e9e7f81416242929861ce7f1a4a41b9eb4e33a9e64c393a67b8e14f3f9586820e93a736749fa0d9e9c0f293624264d07e391b9ae23c2d0456f87b1d30da48d6f2879083010049b306eb23001478b1739ac512b9e8000436506339c308283d7a72edc6814fb7631f5bc61bb2e9365daaaa2a464b93a0a2948099b0405f3a18219c2420fb156aece826946d4605ea35edf0bb2ad38501b48672b2ae386418cb18b0f4c442991451250a2e2dc68b365870b0310018320a0b8c04b0f4d4899c94c7a9b3631deb8820a2a25563c718417282c4936a09c24b133a54f5684310513116a70809a523a076ef8f2450c90f8a2ca09d415253c3650746ae0bcc9224a89ea4cd415588c327aaf502ad0413be251d34c0e0122862606589690e143b709f3dddd69748acacb12698050434c125b9e5ce162afd9da6cf1accd109adc18234f96c9364eba3b4e9e36553e9c1ea5ac9208def000e58c38503b9ce1a48d0d730b272a48628a1ed478820b34db2b141530500347caeef5890d144f534a454872c042aa4a0b1d86e082a58b46f3829817195e30032a4d90f1275f9c68328ca1050c696a0862cd19026c01c5cb13668c908287292360788285c91731c6b06173c34b69660144841183050a0725a0ac3123685b69ddb2bb9fd640653cb18c92081525889c8efdbd3ead11b3e64b150ba70ba98db306cbebd39a281fae15af4f5c8cf9adf281857e64090a63f0688d365fb9bad6d9a5bef90a3caaa2209120123c5a18834c8c5688c18e24c84b0d0432b162305e9ac2d4404dc66c77cd336fffd143d2bb7d1b61bd18699b1760bc5b05e7e38f953ed709ba06920dc68e048bddaa1ed5d54ae8abeedfaae1c642a7522028f4d0c660edbec32be80791084132d0de6a84219198351c38fd0939f68d84848404538fdedd7017aa1431627974856519782457be691e338f6e343d731678e4815bc5028fe2e647da409a1b791e5d4a67b9910d97ce59c1e19cafc0ad62c4b34b2b9fbe034ef028dbc0230d3c3a62798cceb9c7b4e39ee7801b95e336c0a36cad1c49f028073cf23610050d3cd23cc777c065ca6181471e18a48ad1e61d78c481ac0d9c3dc4410906adc02aa7a556d09495e9cba455dbd42939350a8c2d6f4738fd093bf68dd443bc4d26aded35a71aa83f89a4e53cf5e192d04f42737ca2fe8e380006a755d54335d5434a3d5c870ed0b56d3d600b744e4d98627a8e3bef219d5babc67abca52ed7e12ed0c3e9f2d07980441e063d711e1eaa538fef0061e8f196f3d0b1792528ace7736ab2f2edac85a15e55d5393dc1f3f89e73459aebac3e16be8799783d745485dd06c79f0e1e068b18ed70971b71e02d5797f3e000d406da011eadbb409e1c5f794e8ee7f01ccfe11a21c7793cc7799c88a351cb75f87a462e6fb94067305c108706ce5f385b5f950816316a390f37dae1ad2a458c7478cb77803c5c6881472dd7012aa82ce78fc8feaeb1861aef1aa1f39577be82c94f3bcfe13abe83e30b6f8cd0398f77ce030ad15c3e11dff856aa87a6a250f032c4e5ed028f76c12900fcb8c27a7a03f67c3fa396bbc0a3ef0809d6e3ecb94a7079cb4f70812dd7c0327d44ddfad6e9d3f1553971d693a930f796f790107fc130055d2cbd7ca407434f03ee2d501bc8c6f67c4830f52a207fc130c735d0f3d5b70386f285b06f3ebf11b2f77c83efe75ba96fa7bea56aa0769d8f855aa88f6ed62047ec41015564f2ead186b9f1532132f9f69657d49aab96c5e6d1c2ee35cbb600ea38ba1c1acced893e487de023fa307d981b7b98eb5ab65aa98f1c5adcf68c56f276c10c99ead579a532add54bcb394e8d9798fea19cf2ea1c595e51d474ac3857a744acae20dbf747dfa68f2e31af65b4f81444bd3ab3ee6c85dedbb45e666432373299eb2a8010e95d461a8c73291c789402180bd406d2a08b3ccc56a72cc4d3d3a9cbc86b9d947253a17b751d3e5d0a2f5dbfb0f51a5d8b1d5bc3f64cd3bc35234dd4d9a7f253a1f5ea2eaf48d98777f0e8b447a72c14ea7adc41a36f88f41bbf34e4bcd5a6b9f6110c4bf00d060960084e7f82de0563cf400fb91a749590f9ca4f5857d00575a18a91fa82aee8c27a06baa267ac15c7ad58198b7376226eaf5bf9b729900492a09c99c7afc52f6f0ed29cfd470f6d432c676f9063adb66f6b50ce4cbd20491bb997e062b1582c0ac63ef4faf112814887828274c85d87a64645b1186e59b0d3e92ec0cbb78736da43d6362d50bbaaaf0291391cb709de260512bf178bef9de27b9f3e6a52d378296a4a93b18b5fcecb6fa5167eb504b7895fedc41eb42755d90f20a9c04259a8ec496fafa888f48ca5b5bb582008fc2c5f6d0d56d6a98a95da364d4cdf0bf5bd68be7bdd7cb3569aa6691ad46f60e8ff811454e057bb746df1ab7de391984646374a0477a7eceeeeeeeeee925f26abe4a42ac806523012b54ea16ac14dc9808b65426a3fd42a8da365524a29b75bd2acddddddddfdd55fedeeeeaec326b8f16b5b2b549cfe84ebd4aa855af15ca44039cfeddcc5b2e05ad9a60ca0d043734a4da92935a566142a4b4be5799b9f8151b24741aa2535a5a694fc0c3410475ec3e94fc84ccf4b78895fcc843d608f49a6083db4b056abd5fa616311c90cd50bc7445020ad5c3c6b99e74f3279f61f9e7d63d7d85b3d14a481d867abe5add6a72f5b3da4306616011693660467640986d31ff5dd19f9c59e7a4571638c313218baf03b778a5fdbc6a7c85bfceaedeeee8d52069989a7b007d3f5e3283a4c261662d6f8fa488ff49c162a6f849ff5992f1373eb81e0daff3e84f83d1725d273ea3241619d1fa913ac05ce5be87c27c662d1f539575783413a50df489d601c884203adf36ac74e3fedf29cecf4d329809ed312f00afef06be3dd5dcd72322d418e37d27acd0321e789ec1a5fc66bae65b55a7196e3d22ff29977c992f4fae957c61be16ff1cb00cfad369edf1ce93956a79fcbd5ae6a5ed9bc76798eebf40bf7f3dfa9a9608f999a23fdd40c9d997b35cb69a98ff5d5c66999ec22ab79d5cb89be1ff5e9e5ef5b51d5297ea77aa7cee946ad163cb45a18686aa9d0fc52f9908785a26fe6eb3ede738255c2c942abc9f21cd664b9f76d0a04c402e5e466b679f6692e3d4f734e5b4dd3344db59c3005ef1ac10343175e3d977ee7e54c67f61c66ea218cf73a0ecc3e6de2977a8c1f3fc7fcc3af96b94bd3a2cfa00fa6e7042701bf4e5acc98586843968ab2599665ad2feea89d1389580ae744cc1f2fe1d7728c5bfa8df9c261a190adc461212bdcc44eec65a19a482d99cef97a6bdd37c73b92c477dc148b6db0f97d4e0730958b1351af5b88b0f254bc6e9922f51a2890e8ec397028906c73761e05a2397b7422f63df51d0e89c5626fa4f51bea7ce83d7b78e33567019e1640e7abf7aa5e84c8aef1d28bb891ed8b4467ad3e0e21fe066e600892a07f5f49e0dfdfbcdbb74121fbf185ecab0ff6ec93ea835d7e99fa608f9fa63ef6899888c3ed19e9f7893852e13aece0dbb9cc9565b2bbbbbbbbbb3b937195bebdbdf8ee18a387b01fbb1fae401ba440eb4422482088110b693e15683b7ded6b5ffa52a7209f1f4122439e9fc851dc0d6cf65d92597cdf835cbd221ef2fef1b0ddf9c5ebec1b3811bffc39f095873adf618fef1c1d1ef2e03cf45c1eeee87c3c0fb91d1ebabe43160f0f757caf7a78d813bd814c0fb5770f35d8c9f1f21bf410c7b7f4e6f90e1b001edef8765620996be0e14e0e0f6d7c6bde3e1548cb1b0c39f0768e83efe5fc62dfe0fbc961faa3f0ebce42ed1b78dc80834fbf3d0920fd06ce6db7c1cfb7b37dc3cc70f2b0f7a6400beecca418e36d9b535b0a00f0f31e3c76f8b874f4b434c88183a7cac9d4ef6cbf6163a77db6ebacbe3d87f5ed1ef7ed9cf7edac95ceb7fa501fedf28beaa33d7e9bfa6850ce249d42b2f41bec9685bb00122c22999fee6a1b9001c0a880df247eedf27a5215e5f5570fadaa968a8af350a53a0ffab1498da2ea21065989631c4b8aba8ac4612ff6c0cbf03a27e2eeb803cf6db7537adc6d993b7232548193ad2566f792732e7a11ec7cbd10f6e32e7dbb845ff2636cda962c33d97e885b64a9c0e3d27d144874e9627c11f945e487ad4da23eb297bcb4622651b4b090429989f292a162d50faca532576499241f3296007cc84decb4758c71528c31b22213335c380b6705ae749d257ec925a6fccdb58120f06f0e54257d97a628149a242f5b5a5ecad89297ab2a24983e5c262b703e5c2aaf0f5fbf756c49972f638c7166acad12bfa4f3d24b5ee225532cc69103a72ce5fc38e790baae38fd09d78ab2bc73757f39cb8c24719e5889c56026304c73a2754efb18964d65190a291849b24ba6e06cd22e6532080b85af0c4c319252ca8575df4a8162680265ced9d447e4a274ed5bd8f6ad146804dfcebea109be3d7ee1ead9370810f5509016b4eb2dd6aa88e74c09e75d6b6231b24f64f51788235364bc7a4544d8ca1bf148d85e977f9fe85eedacb27aa48153df0e9e5faa9471777777777765d4dddd1d815fc1cc7fb2e5dfa52b38fd0935ead5a98504dbb90be089bdfaab4851a432fd7f10056dc18206754a6af3ed0d1631394a679f5ac6533eb4e065ac62663741cfaf2de87d6a5050136666666666666666669ede0d4ad1d85d6316f298c4b6753cde4d9ed54aebfea4acb48158b8f1d1232100dfa094163667cf23142bb76cdb78db36e74d82cb37e8a8508ccddddd45f6b9ebee36c22f656bcf1564e39c5b299d6f3dc4029390fc806dde814a1b8cf315a8b4c13667fd58be7d2b292c50c3219a1023fcb11d011f7bb5790b2b67cfd55b6fbedac08c250fdcb6f15575dbd5d2b46dccd629ebce5c6659e61ab88a5b8caf8fe02eaf360de457100781bdd1658c31eb82f3545595b966c5957125395bd5d151202b2d2747816c9be729106dd5b1b867209263b11448ec562b05d2de96a3690a64c32c6369aaaabac995aaeab750c72f55f5d1dd1c77aaaa9bbaaa764ddc2ed7bca33e5481f02e109dea4387983bc45cdf82db2b5872e050f8e8eababaca44ed1c17ad33730c0d2bbf5b92984283e9e90ca75fa830da7cb8e9139caa6f679552caa84519d7d58bbd0590f26350dbf599658cd2a5dc2feaa8c71edc3df6aa40ead1371ee6142b4d4e5a196e5e7d672bf5523369a6ecc95cd79e7a75aa2a381d6326c95e388aa5d4c3569ce7296ca5c9a9bda2a8e5dbb70a0ec7582946e72dfef81518fe700a52dfc0f035a5b6a9d7a57af5a8a0155574327dfc67e5fa461c83b17cf690b6edcab72f09c90fd80ad45c6983b1c06ce7e5ea53fa01db9cf52521d9609b2bfd80ad56fb14b6d288b0f0110da70a684f029d6f9744b48fa0909eaf1e09fac52ba865de82e6d2f55c9ab97a2e058368a036d067913b8ae314c7b287eaca5ebe7efdfafdf586df7bf395194eee9659c87d7834306c972af0bcead3475fd708ebd22eaf50af5b3efa94daa6265590fd11047e1f5d7f7683ed805f1a795e7d5e7f5e3b05d26ce514a71188794653e69e063806cbd0587a42832736f79014124110604a3fb26f530a8249e764a77daaf482498f1e0851c961f2d5b34fa905933e61526983c95770857e5dbdf22b00afa09416a4f37a461b8bc1a4cbe6fec2f1860c82b882b952af1ef5eadcb298bbdbac98a3cc75aa360c14bdeeb6383599c9189b37a75b6d5ac6eabc34f743ca98b5c6add5d65b456fac5514220b21e7557d4450eba2107389199f5963dcb2a9b3d2ee57506cb5a2a6f9d6ad58d9c6b3bac1b2c1ed74d3d359e5e878b3db71ce06ebc68a67c3c1cee5e876c5510278f565651ac856ec691dcb2e5f9fb96dbb83e7868d9da9938343ae36faa6439b47308c9f6a64751d7677477eedb64d1ded9d51c66ca962c7186377f76edb9ced3d364299eb19b7775e51745e620279d263e772ba5577b38b41cc2844c741ccf5256c48cddc85e72e6e8cdd436e567ae44f9f77999939ba8c0df505d507aed8eeee6da48fe00d8fd3e48e8ee7e0981a802f1c60b854f87503b4b14cbf4bdf5e0e18ee944701ec3816184e065fe02a95d09b83a314ed53588c312e6cf5a92e284563ad5fc0e9cf72af72f78f0fbaa8ad2e36995d005e8e1aa5f8e81b7926bfe207bce57c74966b729dd7a9a7608842ecbc22fd6979ad2eea44ede0d579b61c9dee8e23f4478f1105bff532d7ea913ba3ebf08aa2caa8517d74174adef8c364ef4d0343d057978256b4c5f2ad35ed5255548d528d1a3bf856d5bc1c1d8d39caafdef18aa657a4a046a5578f4d76326d5bb1b8ce5b65e58448df7176adf1fb7ba763d9b8c1e2e970741c8e8fcbd1d246177998ebe1e41b46e4eb0d1c3c619810a8044c198a92542a6524020000051316003028140c0744629128cd7250f00714800d80aa3c5e449307c3b118864110c43000c330141118000030c410038c31321d2e1787fa84e5fc899d47bf38f67b1000ff0f2cc3293691c87ab8334d6944231b0b4820f3964cb91913aa3f0652b099ea12f4ab22fbb17d775a16860d696ce392c4fa79bae54d36bf717939dec0b126de734bee6fc71fdfbf7486812d2e95000dd12f28a144163a992d5368b5248dc1c6d330c674342852a53f9c04052e1b1d0fdef420b6a9bdda06f6a5dc10ecc9ac5cc0dcf2f7d064e657a53ed1eb546e4916209ad116fe80c1e27b7b2c349f33670607756c3cbdd08639db6bca1ef999e871a820443ceb6777b542454ff55e64db7e7b9f860a2dcd8b255996ae72bb9e88a1507505a17015871252ff2100e452842705698cfe4b06220c1aa04c9249e0279a938bce8310da5659b152d3859dcde7b3d8d61207037a81fd5c213499df7cf99b3c9f67488913ecaf320562f38809922647d191140f353dd44ef109bf81f50aadf8d0b5890e4d15c93f706d5d7325b1e7602193cff4e0f1c3b3035462834a0755b03ca15ecce2f0f55fc03a48ac320cbc7abc712b32d192a7a2b428add842788f55186acec2eaa09feac60834b86258538056575372038a84d44f097c4c4d5fe32aec4e2da113b5a5c70ae84dd4bd29611be026b2e2f1480daa31e83f935867443d3aee5c2ca35ac498efcb20e14f2117f8d6db2ce1c6869239395e0b4748c00a0e2939014d15ae420e606063c8827ff5697e6a7eff2a4f71a55e154e1998f083880da1de3bd205b88644f95c39a7637f48e0428b0f47e1906faa36bc2e46402ad841cd89fbb0b2a0cc066bd9070ec8c96693119b2235259fc598e101a1acb676a312cc4f8ff3b072586a2156b492eb07f3b6a05106fa466cbf316e19ba721ac0665bee43ac29da47ba6919801d2067650f555ba96f19967f14b8b9c257c9b35d733b7f0be3cfac7203deffa558ede2d4a4a2df151734dab8b73d79e7b0566dbdd28499d500a00003321a380a66af7ba7b80e2960552b3244cfe2e297b322e9c4bd4303d62416c031a3c385cfd61c4ed9d7494ee296634dd0ad4291970a73266582c442678580c486ee77e21e90e4975a70f64e52658dc7e17ffcb2516e19903f1c6ab0d428b910d2ac5811bae214a29afc93d92713502ef30e37405ce5374b0e1e5d2fcfbb1b21262eecf843fb8070b3c18019dd2779be8114a08070e9d3e50dcbb54603c428675e03207a96748f90a81b3adcac7baa471d84be9e41fc815e4db62b51cf83b600fde94ab9e3a5469ff250e6ff8ba7c0aa3cca3882046cfdb0e7ab4bf29fb550f204a9f38c630729bd955c06bbf420617acaab4c8f39633557dd047298151189e11426fc9eaa34d6f07151ff0b588e43586249b4adddfc0abdbc7308b604e50893d52ded03782478a6a312d6b8b6120adb04a3c86d2db104d4f3732b7018a086965df9b9dbd57b7ac38a41378782155a2bde3b4aa0fcdc0c02e087f5fbb1d5cbb9ac4c9cac55ef11dee1624808ebb370bd8ec5ca80dd72971ce24f05230e5588308cf8a185f50eb3ee9d35bd35fe104c6b93c64eaf6d9e671be80117352340f58258956171976e5ba92228567b997ca05d560868be15a21405bec1b36d8245859de15330f131dc820e86d6bc9cbf569e3f00fa1d2d5040ae49ffe960395187aece3e56b77e1c06f84b5b04d7cd593d22f1370a932d95ccb401e8085702eac1af1865be6c0010bed6a878d37b4c465360dd3b9b51d9874a61e5e07a5fde2d26b36b590c24c54903feed5a1517a90637812330047299a82c0dbb26eac4420f315653c97e0815f211d8297d384127f56db30f57c0e8e8c17a08f0725831e794add3c3a2de32d1c1c4a2da49f6092f82e554b4bca18fe526ad197dc3e9f048ff1386ef31e63cb5bf41ca95265b573b7102d7081603f052b7c588fd805f7d1ffe973862bacf51a3e85614d971dc548385af4e21ed4b58fc4b9a71dbd09e4a7a0facf61bd6082b0f5af9b375c6455bee0144aeeaaa090b90ca8537cdd5f5ecb83985b824429d92cb8d71f321139b1bb0c02e7440c643997e2e3ed51960c4ae7a882342f7987803a5d9bb724fb9eb3e2543e0a80b7e4a8f392a2a0fba05067b6a604291ffc4095d76f1aa805bb5b0447721b4c91a6a089bfd4601c5bba41cc1ce17556cd556ffb0b98e3a7adaa22e33e30850191395b2c7dc8654fe1ff9315769ad99cc880c50d4ebdcc5736d6e53c2a6a033da4c14110a5d2be13d84daeadeb9c0a1f33ad118a1324244e29cd75d9282d38c2b393258336218af4c616956fe2ac3f2639821745ff13b8bed8d7b1fb4f96a14bbcff848317c47adc4286eab9c73c6ad9772da3d7b8bef32d5874a7ff20749c29e928826172f483811ecc6cd96d24ca98dd14bc6692b3d1879e45dfb23a582befd10ee9e43310faaeaa9d8718d0e134e81840a8b2c81b84bada5f6ef1c65367ec8102e0d2cbd6514bc1643c3f1fe362fd7b89fe73f0efefcfac5442c8dec4083cc258570ff12a08f524441fe96f884b7ecc75559c1d112e5afce048c2a47c17d8cb31e1c0a5568af777d499b464cc10f4ad7d769d9f555575703992aab864bf0429b1cd63998bed41a49199127c280b88eaa18eb526ed178bbf3dd0bc6a546ad00c7ff4f726601c45c795a24b0bff6814303816126e4352fd1edfe44ca16b2f796455ddf60859fc6d9a1f331c919827f059b4aa5e4308c906157356c16028a158518f2660347467a0ddd852dbfb1a570f1cbced5ed24c78339472f90dc778b39fe857c7474a9fd67510e69237c6ebb5db346a8138afc5d84ea689b7355879c6b297242736e0cf64ce2ab3ae14fa8fe30bc4e3170a1406a8d0fb4a78d307812553b629314039dd2bd5d7d568f6c84e22d332e4756a989d43a46916806542bbaef4608bcf1cf240cece3dfa9f976b16a3de3aa151db228843e1c8e90839e0ee4e4ba8dd2d56f1a210a36e079565c52b509556a56fdcdbceff81403b445f024a0c65a0d857131ee0f5aabb0faa70c7b6d3d77a04988945fff4d5c7622229a84278448512aa3494a9e9fa6c8f4c53e266b7d7294b6f72b7bca88f7502f6626d7629e1db1d58ddce67c3f4bd70eeda4006591e4e436b4b34818c602e141404ed91f3ab783334c10cf40fad42149ac099fa3ac96e9fe05c162eeda61f739625324d8649ff0eb211e92eed12e97b554ad8410c59699234775e3a600e2b9591f9d64fc8c38d00abae3afdd305381a8915faceff691c6b14db43d886acbe61d31596bb6cc0e1b4baa2a2d2db632c6523784c4a7d3920b8ba50b301f20216403c1f7a9b224832bf685d583efc76b71695fdd5d8927242ff5d755304df3bd8ed183f1c5644005aa8adfbcd17994f98b8194d40321efdbee00527c8e5f9f9fa3827870aa65bfa5081befba54ecd805efd24e93f323db8999b1d1cbb72e9221383d1ac929e3f752b0fdea6bb2fbb1f0def3f2ba6d3429884f755f89ad98f85e1f28747546eb131a838d52ecd3b86e516d2855ef01bccff63b5178dd3d689dc7968ec4bce1b037188aced4571f7be21d5cfaded5e687aa1d08494d7ab654a303cb29ad234fd8e716a63680b7a744180904ad9d641fa61a0adabf9643519d0b9c779bd7eddf51d4cdbfb09d277c735ebe8d9f2e06364f36676a0f1a299cbb87b183f5120a3a635a6f860544f85db47d98251e673b872a765f229682fda92621c046708e664cd28f19d49f080ec9054934ff6c21c0001b8f5a7e3614e9cb4c6c5bbf7dfb9268a17b59e79ee5e551071e7b15cf9e3952dcfcca438cc207977d9a3a56b66f9b04aa725d33f1ba629c961c25bde4ef519bcce366189fc7a4cdfbd660354b20d55285ae863e83d66b71ee1890dc693e2ffd9d428193317cf514ebc6eb232945c17197d09dfd4e91b616870c95481c3b54031e4c1630b2a9d6952883fa3d7d77dcd64603eb47fd4ef9fe6a134dea27984fb25387a9171c3edc58c44638fd553badeb2a8c324d5b5efd9dcf54a83bb42f998c3e6ac6edbe434e7cee7ab2ec10f6d7b346c1559e7d460cbbd4230b8c21c4fc7208a60fff4f2d5a537bb5fe2c91fce8681965f918d3d5328df3db34fd784667d48a99b01a94a60580c2b13a0157c6af00a6c0b2a7f85f31fb37878c7b9f5e80ab7ceb1e38016a594bf92e6da245c02c5c40525a4889e627d5e595994b15a11cdcd6c775c7ed352f33c147f4771a5dd6cdc45c2f9b385efe18888f71d5d320a2ef43c5019a336d9f9890689501280747527781f77d200d940c604797d1e34b6a009348f336077d29395310b248db24e56edc4e115447b3400d370df4f6eea71b05c92e2dbef909b6a74b6593a2033e59e9033682ef7d0ec06becfa3cb8d412d14b8c80a360d5984cf920853d449b7c5f7adc119f9fb05e3f06e5123060ee1999a567e0a974f4f2be785830f41088bfa590a060f061c865f50ed950d139e534b39bb9a364893f805c9352afa2fbeaddd287834eefdd8e9d6ac2adb16f992000ccb3801a156d09f320a655ec413fae13567645a05caf2b72f06e4c266137a8c279685d90431546a3d01f68b01265b27149f95a9f08921e19c75c855a7babf9b2a03ace41fc8067e6a1a987e5b5ee3a70491663991f0489bcd4ef4bef51e3c7545a50c5190e7fdbd55c8f6e5411b7bbdad4781471b8b5c8f78ba3db146836e011d1b36848982d9a76dc8f52248a0430381462175d28d052e14bba7000e89b8c2ea0032117e7d076e507ed16a365d824e14bf0e17b04613e01588a2fc826d0cd9fe8920a8486f127ad5b20de7c0d4c0e897c78ca84b6c6c510c2857e1924c963033d2128012abc84139e046826f5048eae25af9a960f9267f9d9ab96f8de04c1cb70e9c9f689c1e9cd299794891b70a1cfe16cd338df7d7ba9d259e5bb2d25778fb20d77bb7b8475f93f11747bcb96dc263d1790e6e8148a8ce4cda284f08946505057e38c1fbb4d6b23e2b14c2580de8516d0912f0ac8f5ac2b636c9719c9389e0c1322cbe541ffff28fa4a78a420b281897fd9d13c94be0ec468d782a0ac9878571245e7acd02400ec65fe52a0256ef54c31e2fb98ef5d780cac5dd036b27fe22580b0aca1fb482d94d57cca69d984709b4086120ec1b6686aaf3d8d58780a1fd3b5507f7527d28d973aff8c77300924c7b54253657d6c3ffdd1bee03d6f82c43f835725760f329327aee721343c328fcf3faec54eaed780f8193d8700315a50b8065a62568f1acc4669f7090df1324302ec428600e0103fb98a148f631ec43fa249a4082ade28255f9692aa77b228de131a950cb771354f8a5fec6287c72470e6e82935fa14182c22078ab54fe96aa1a87a03b01c0583e95f14801a108e3424025396bc599ed00c765b8d56c12a72a96e67fa3eae4a3a420cd68259d32aa24337f4896190bb92461c73e2a6fedbc393fcd6063b03b88d251c5597c7a6098dc158ebae7ed099fcf2e6721bc4c27de25d759f061be9ce2fdafafdd1095e49ae9041559c39f288885a5beb73368696089d83da468fe9a928f6d85d9a68c1c7940f05d55173ff86267d0a0023ce4c3cd3a23042bf3cbc5eb393a06585f943bb322ae39b82b627c282b886bf1445958b479ea715d74e777c50ccc744e1fc8a27023354758382966198905b4837ded16a9f2c4c2c7b338e4b06e74f95522e231f2a3746322c10674b38a7ea6ec83dcc16d857baa047395c994454794a72c1916f4ef6c578862bf731f207f198c4629846357b837f488510777418a94b19a6b13db81171c0a4778103dc948d895f643225b0f6b920cc2bba6229d1bba15bb58d13af81ac8d047b9f85cacaf139d2acf0990982b309770952095396e5b2913f06a88d20e25b6e08cae4712959445a795a9901ea180f9a1389942a825e825d514ab34d444696d7f2e78d915ba343426848e18bf90d8fb14b15e49b01761258680a5d35c1967bedd932b8c1b471f7d51b3ea8ae23e7307a92f1c0535b6f7bf274442dc8c6e3535f37023043d14ac4ecfee94ea8ef0122d3ae17c8bfd81d9bb4b5e97c216bf086ed10fdae3c3d3d9d3a1ab3d6bc2c619fd55d1ea0ee945ad4300367a00c8f63a9914c5e5561e14c2485f74a4488a68e15ef5f5ad6d17014a58bbb0a4b36ca11c224df7afdc85227dbac5eaed0339c6c5e2ac66bbcac0f1f98a91de6072386ed4ad4db769427a5c7e1a332d08dd2502fc096cd48ac3c114c8cea3f5a214929b247b2448906ac2e04e020e0e234d5665eb8a86808837178845dbe814be058eb40a5eef253078a45d396898367fba680b4c07f53f8d30df87d0ff13b815a84e4f0feba0cde19457b06900e8108467de59f3bf1d6fafc9b60255fd1d42040e7f492ee4c624ddf749c3de903ad13d914d93d6a4983ef59b9e6f2824067ec49e59b4bdf03647312c00c24b437417feb22213a14defc10ecc3ede892443dab028782bb44d5b6474c81d469a714155cc06cd485367cc406f016749317b66520168656a060fcf5683fa830d30cd8216ef187023913c0c2ace468464c77b064b36deb800f2930929610ea17941d81fdb7e7ad37a9ee83cccc5ed8442f0860c33419fde2425ac98fdb1cff7a0c61264d43f0f43110254d2ac5447d121577fe99147c8ecca38c0839f39eb7e073e0e9aec301f84e282fe3955ca663160290b591e2082317e3eb95d2ea8b57f51e314d72ca4caa7775b33f397c3addc2705ea2cc9dbce6817711a060f1f52fffd5ea40f4875bb55783a2fe876d76db72d89367a2d36dc2445ecbc2911c3763f84f1e42f2583f94e9d0f34c721bea1d7dd426c6c1b704eeabfa2dc2c0a354c5e746ef813f3044aa370cd3c7dc14012337417dd2ff5069bca88b9f0e762fd0969beaf6709058e484072f644d0df6a7595ee0134fb5bd28028b7a1f2c29ed1094a47714336c8ed6453bd7eab2089c78b9e510529714af87c0897b95a05a48a96f00ff3cda53ef964b3bbcc5d04c2886040ba57bcbaa86e55c5091efd20f129462bd0c5a62361c7ee04c32cb06fd7b53b5862e45c2d9a01e6695e456c04b563015bbdf54fe408354fe520fcf55b8d6795867523ff929e3f0d7b36d27b1c5056f4884b0dc07f4b60c3f1e2e92d64d501e6486425d865d02b58e53a2b7d62f6a41109e3ed25c3a04b1c71a43c41d32e778c9d1d82cc1b80fb7661a19f42673b1c100ed08d0b197e663ecbc315ee8429cd89e3de046f28ba196a55956b4b3ab300fdefa0a8f9149760b6fea803228767a9f1d3d7dcd6dde15d684511ed937e14cbc9f8ee2085b3dd697e3e6a54fed84babe5c1a80e832a0fed6bfc2ff19447b0a541a73134b6e13450184d4d3a38fa828003e990ddf2ca753a3aa6ebefe37b06859f804865d1da90b01342d62f1150d9067fbab1d0f55e8bd26229eae1da89a0301d37451fe1180887be7cb29094f753b7a40b4b217f97b21ed5f27edfbca98c6fccbd6799b03836f7428fe60e51289905841e632d8e21abd00fab4237589b5099fe237965c12b3f33a9b5e8af6421c4ffe8e5c058338ad4e1330734cac7205a346a5637e834d3d046def2957e1cd91f0cd7a033daf7549c3dab41f7c83a08debfbc96c0f0988850141fd9983f0f0fe817b2424dcedb1543272441c0120a2b04f629c5c987acf91c31ce64643adf6977a380438d4650d9ebf18c0a7368b8f29a08ecd02f1eea1629fa1a769f63d6976a25f164041504fc53149fe607a71b451c3843621bcf08e1bade49f52c1a0b2f624199f5311dc50b2c7ed8d36a75c06b972d05cddd5b1373b53796f20416f54a9ad8cf35b42c429548d70808185259d47e8bd3e5c1f6b7735acc50141d4f40819d9ccc06d13e4d4d0e47ebbaf141123c622005d20ef77482f34b2edb048dd1b71c668241c3eb4919e86a62e38dd242114e420f9569bb2aff072e0032f7679e75d8804c9f94aa4e42cd62faf1bbf1701f8df56a8159a9eae4b6490f35c6c6aaa6baec6f892d9f74f84214336cb05b84e182f706ad4a7dd0371fbe57cdcc813089ee8b8e886201ce6afe7d461277a6b5670897a6be13aa3b9d4cc8d8b5a2ea872e2ba2c577af7e122659427c30c2e5bfe1b046516cfc0033e73a3e30617ab776c51a97c3af04dcbcac65ae631ed959f686c1d7578c98cb9507e70741e70e7e664ccd3c6906f76bc667888da8f43b6c1c81cab5dccc38f5314c890dfddc64866d50a49a1237e7d3b95aecc1b8facaaa430df28b552c6453f0f9ab9a1fd3c859ace1e39456d848f782ac32982a80c979f4d80e5b450467fea691fd7d35cedb009bbf21348832d86391412cb6f4bbeabcc579d7e492f5ba5a558ad2cdb2379a196c8c6e63b47040f5979e41c7d4ce224e162588164fcea19eb428b486feac592194db4173dddd380f2c079be256ca6327bda0e5ed0767ac8e2d3a074241d74b4e2f969b9608524602a6e6edb101a28471f50f9e13c9d3d06bc6bc6738a3917667b6b853b80d24c2c84702fb4f66a7cf149112471043979c274ebc79847571f29321fdc3611105a56ae7681bb343ea5fa2e30ff1dc06e02ed31c3e943d9f2f0afaf5770bea0e05abe374e9963bbe98de31bcfe418819ad90c1499d1b8fa533286ba4d5df2034c99472485b8dc34924928fbbe61fd5fa9ba1f6741b157356d452e3c2c24bacc601a84c2315f663a638e4292410924e25ce614e07812482987a00485b9e807c34576a1ce5e72a956534054314e6af364d5934248f7fda8b8ecdd48f504d76d9010a2ac8671e031b68c2e88c19c8d8562431b4b3808282e9e1c9b211fb8608667210d7d4e603053021fb1ba023704a658aafe864b853c0d20c70c6a760c50b45034834362cc0e1e50967a304db26b55f494b7b251430d130b0b73cf0979c79355d079141d4a3996b3080a139412bd77a9a5088bc4244a3b560b84968e5ce03908ed58a191e220141a9769dfe0c0f9851e103ef2669c7298160fbbfb8967bfb56bcdf2e248aab0490f9b85cf16c8e05b03dbdb5020db4e9d9b30ab5e43aead4e9ec041f0a3ced3d909089452ad4f75d411b519f4e956894313d60e48453f38b8960dc1123a61309a653ecc5490d5c36fc3e501a20666150b2400a9623b922b6cf14b45800f4c3fdd412d71fc3ebc50de95cbcb28970bb2fbaca2f89b0ccf1cb6f1e509f51f7b842d7df9a911d39e59db44ef2c18df65c87e318a47bec8982e124b8dd43b3ddcc2c2b7128c5759d808a85469c1a9737a465f0b0231e56592bc23196a6a91c9c678aad795846da788d1d801039012cfed252661ede548aa531c2d3ff0556b558a7e195034cd3e6ed6962cade989eb308237c0fcb067a70ad92ae83583fe0d9ba98a5ec43c4013956875bcb75397d17f955b779707c4ab8ecaf639cdd655fce49dee7cc3d920f5c972186f4e5da90f73c71137753a56eb147b6352b24afa652fb42fd7611e43d73ddcf43e93d0a38640c2eec29f266a702a4c67072a12b160231f145ff907907f78dd772a1f159641f483ba61c6750309c579b2f565f419bca3c4fe63d369aac9480558a0f290bad517c180fee865540f1bac76b5359221c7c45bb1dc57ea1aa4d156a8397df58c72bfaca42bc54ba84ff1d16d3bbc18f5926e44df65630cf466d2cdcae5a6189073d4b62378b1fe726ebdb445465829e9661c57f2d97bc93c8c9aa848d13d0be8500813ce8283c2220058ebba2033cdbe34a3c72a80edf52ee2aa59cd0855b8aa1ecd718632c2fddf82e74ed997c414a4d53df24f47db01bd4d3426fbc8deef1643b21b5bb704148bdafc3565b93c5f18aa78b5bf2f7c75d90a95df9ec597262a528ba82ec99ffb398819e4a7471c5ff287d8a07d6f5184edf24bf2c2674920ad725e8505d6837f8fb8352d0169cf50eefcedbf4111281336c6786725e985f9558b4ceccd708d9b6cd42b41d4fd80dfe2a7ea59e1b63ec7883bfd74a2eb39e808018215d168a4c1a15fec19035b4be7217462c994027a4efb7136c8b426855b759608b4ff0436b712e7a7cbcedfd0e9460a930e2634337142a2bb617446fce2263b7b667b84a934f5ca234da04f77e8b577d0e87a2602f3ea826f15feac531817a649fb5d1450a56ab9fc88c318769209dfa42b66fbf0087242fbdfdb975cc448656decfca478bfb752fcf18e69ad1acb8d2ef2c2718285b4b9c8d97af1add94f1cddf9e840cfb6cd7e85b3cd6ac2d22db8efb2be59dbb62cfd42d491ac2425555d75402c33b555ccd27ed9926e306ab3fc2a9234406be6da94ced05c290d8a01d18e448ebf8f22a4f350350786569540de7cfa18a00aa37ce957d566cf918235916e696a6da517a295f1934c24c148da036736407e48c37d6a05c30a478bee0e3881f92240b83f94603807e769aa82275459ee3bab2b1e360211904780ee8912bd9a842a5f68d176c597e554916add5329517c4ad195cf9364e3a4b70ce0ccb16ab203aff14e2317f7a07efb01b027fa368d14803515aaa85af6f72ff982600194fee09ae4d4df08ea7cb57eac1e324ba3d5122123718695807364f8fe59fd04c81c0262882316f7e955a46ac4937b3c2b0703d70dee363e2e8eace4b38768cc57be28e1ba53378cfa11089e2c465b1dd0f12a376f806557532330d10039c26a84ce6caa6d9fe932bdd726dc1a28f89929660e138860741ddd4b362fa13fc4c71a0c1de9f628e00ba2a7e8d17348088dbf3eb23ee5a6d118566af42e9720c3a6ceb0ca44311126ca9596448cb444ff83daa32152339bac245261cd63c626d2c0a07871549fa3b76931dd4080be7930b635791a03822e330f08c9b38819aa8c86fb99389960bbbf686d606810b331062de57e991e30a64d9fe94103ad47c28f1cc5f79ab2e5824a0c0107ea299521a0936fcfb249409d69d757fa8964ea95107bfffd790e924480fc1bd2ab8ab505115b507dc520e207077e8a2b8341a542d0f96ba95ebd8eed193d14d42c363095ff0d69303fd2e53dc7a669b6321d59773128bfc8fa2aa935b2fc38426e5411d35cd547345a1529c93f53bf6133a89741912384cf11d4968ff1bfa8b441f074a620588e29e6116208b8bafbd8a923eb99361acd1845a6889bd13346c3a8638d5ac474c3573036fb43377cd502edc4dcf86130219f434a7d3cf798cb836afd0f9ea289ac1c44617e67d2b34a6152f34918c89cc98b6fa8f923898db9862121b899551267206833ef55ecf165220e25714e4c1a22058ab705d33228bfa5ce09173351c4582c26bebab406eda0eee4e9e45fd32c0c92c52a1a2cd4929a6a807410419362006a70eba79980917584da33418f2c06f2ea0276de9b8eb21e06d39e6dd73a5d3293839daac334389f09871fada91b2009b6c8691377c220e9e391a0a7a658602caea11b8624416a2471ae8ddb58353d2d401b883aaec49d168285879adc1ec81218dcc96f0c65e4727176f36525bfc31e47bdc16c64091e0f2f65ad6b14fb5c43e3a9973946e329ff09db20f4bca81737c58cafc40890d2b16bd6df6b48eec292eca380df109b4f13c00f7a936a9f1f2222fc3d49a41f3bd71d143204312538ad499918e79dc8a99714d6156e829971e27722552fa270a12e55fa26336d3eaa1168b0cffc54f01f0f9856c45df85e23d93f9d3926d0f2e3bec14facb1f7f4ed9273031908be83f3a95b9ecf792a548c76d6853d1bb92dd615064fa18000e51810d826e7b82c944eb1278c1602da083de97b8850144c92758099051f047a19c456ece9eeed585faded67c645533ac48fe9cba71057ffce74d600b33294e73242b90183e04932bd414274e9a9eb21b38cf26a1c6163cfe9f6b8c4190a58f3e3062bc966c1ba8603b8a830a2c4287b469f6ef0a10a18a302e7d8c8e99b327a03fcaf6238bb04c29cd724ebd978992535ec104c40e21b4716b4aafff85e5383fa5c4fce2365de294f4778eab40176fd853da90d46b6d8797f1195020bc408b8030d55aa2fa16118633dbf859619d3ec526ea03a08d8c2968b45808a9cf2cb6265209ba8252d50190a83d88449f928c9a5963d9144a20bc82784a1bc5e202715cb39b91703104e13214e9c652cb095a36b4305a2d9a12a4f5fbd141c968b947b45effdcf33e0e0edc6db410bec6777b0f5df5345afc924ad501f5489f176d76bff89b8a61506e77e30cfad3b4c29a202a0c0556f285175f45512526a993e6250054a2842cb360c2a8acd3ee089ecb836357d86d39bc9111a1866e2c105b4b75630906cdb9bfbde5070727435036f94201da6f05efdacfefdb6d1aa3ebd521589ecefb7119e283720515691e180b8dc952ae4731e911d3bea188c4f3e07295003a7e13199c16694837ce1f75f08da38a03f1218ad2073e29e82fc4fb66cae35911df529f14b1269336c1099f221d29e24b3ff56fc8fccb526618b2b0b9879524af9d110644b3aa4c42ca71e0853ee9edfd1c82544e7342ac0acdc08f0ddc59c302984c9b8729f717cfb75e5701b69069b2288b1887a5ae217a1c4692a523ae374a49c8ccd083bcc8b3c7a00742a1b04b31a82a3a008f98e4511d14906b500bf1b1f8224a73d5ce0c93d81338820f400f5043702c2c62ba1c95eef7086ba679fab26bdf1cd915999949ec2678a398bb98013a2889c37ac1596055491f18af8505e13e0e35cbd3ce2bf5ce6fc0442f16cf5ceeb6ccf79454f047452d2a591222369842b8683d435a6dc3c9ddc33c8cec8671f9b4cbf44c6b3cd6813f0392ea86f63751ff34ccd20604fef5708db5cd714f87db6eee04e353d78681edd5ba8b0c305611e5cf9230bf3272c2406f1f88201da67bc01b2d3c50d6572c567174da66dbdeac2ac86f0211f19b14490669dfb77bc2338005774eac3a9e23f9cda1b3a4c39b45a20e8d8caa29665ad113b0e12b43045f0a098e17a62470140ca863fa27f4e139493ed6adb69dc0f3c6a1d2ff55fa7c96847e82d23f0ff1504bdb202a5915acf57c24465f8d5b9a99b5f7fcba192022301410626134c1a900410293852107260b2c0a48048019182910225072603461a881480143829503230b260a401a400498193802207230b220d38481e1cf12070560099bc587111173d95a71baa74196962791d2b1e8e28315bb77c02e3f3c9a7d665b259b4772164c1433eb87be21468a3158e1b6193c8bb8df928028ce2c5c98d8df3f7d18cdf002c87ba2b15f53ffdb60a54f74d80313b0812453bc92690990d120ea888b80c5f021cd23dd9160fe733ca2cf9ccd96c1c63eba847c140855100263d295dc322a371b563249b307b9c624a9c85dccc19da313890493abfa5d9d4daa94ffbaed8a31744aacffe8e0e21d95509d0bfb9b05956eb7d5a81f358532c0383c32484766c5afb68472ce5e2349112f68d5afa4b70abd0a60286edab5c6f4b250ad4dd5c3cea64316fa084a76ef94475493a08e112a829c87e95a2ed778829fd7ea89c194772410dbb08dc8122bc39f0f6ca902a8ee31d6fac916b3f4a1f1147469c5554ff63939e02f18991149454c450f08def552e55f34204eb07f0b9f9bc5091386b869eb7fa8792e8b9d400ba5e6b2e5e04e4163e95fe7a178b6b5ef04fcef472643565250774c4b66c6a2fa5a2fcda5ba98fa9389ce629cdadc7ab85dc782f2f2f76d75f508a20cbddfbd42a2304abc14696f396648142fe0f13ec7ff68e13cc09f2efd1140e1a7bfb3ffc5f8d3a0b6e5e40b381fec183898005a3215b461bacfe7fafe4ec9a2363fd795e7309015100e05411044729ea4eeef966397f6e49e05cc5ac528088cb53010508463da50d139ecaf8dfab5d9fc67747da97d53bc0302ffd408b8e593a744de868c93f383bfd6fb0300294ff2680e0fb753d7ffbcfc147ede2a0bced7b33bc4cc20008e2d8034b149a5e83004cbbfc93c9f44c2b3b320241070dbe62c80bbeef7fbf929fcd3f12e01c25f8c94665fbc5111732a10e106577a750f4bf6b360a42bcad41401232594ce7fd771f8043e391daedca10129df58d5ddd39cc07e3d148cab853300d815cece7f13fad65a99532ff4ad59339ed5e06256d0cf023c417e5be63e1374aa0dec76da799be8d3b8ad99bad0d75201cf38132721a14b1fa081d175e259b5e75e5f810ba80f70f997f2e190f270a40af45e0e1abeca0c3d36accb65d7be6dd8989024b60f92c192483713235b1930b24a2122116435973d014edd843c597aa527c938fb141e0dd079833d340349672292ee5da9de55f70c513c0f0a7cb2c1516daf27382469bc17d407fda511e0604a331bdcb80c3723199fb9b5f47c5c008395834e72d7632f000ae9c9b74636da420d3fd3c5d17e906e199c5032492bc180f1e544b4766ab7720a2b289828b33138018bb6e046a77376896325bcbb823154406eac7d250dc3180270a52937100da792f1b59311300885b28a08dadbd1cf9de6e9ad2ae0a0d3e750e046fab4e24361829485bc005c89c484d7dba3119bfff8a6525fa2c0aaf5ef849af5e81a283c9c877cc381e1fe8039d9a1823622681d575acd2ddf7f59a18891cd398c99fed64e83b78f162317b32b0abf0a938a1aea976589bbacf9d03148ee9a1feabf7c6d0e026697755336d691290490541fe7ddeeccc4b4a330d743f156fc76623f62732aece43e1c0dd175aa7a303c208e2e6e0999c40d0a6d6512b4c79e496c12fa580efa90273da660e4f79a309d9400aa61bce2f6909ea73ac0ffec848458e7ec07bb7f288d4a84b66c11d17fdd77f02451ebb65dd4c95341ab97e528421201f9b6f752dd6974d27f017babdda091d2e45c7c9e4b589e7cfe6471e1e4e9aa776e687e65bc6a94133d46fdd1b123daaa25b8541ba75c523c3e191bfea161e6ec67a7d642746256049c645188a37947a9879b0a3c0c1201aedc7b8cfacd0600ee443ab31b6868e205a88aa03a77ce590a964b7dcd1b18a8b7aacc41443acf664575cdec6df94086a6801765dab5011ecdf8aa1f931aba86fb2c4eed2fbceb802513481a4cbcbd57ac96db8f6e10efacca0c8ec5b319f531c7f3eb6d641ef601982ddc065fa297fef0d71183edb5209e3a626756b2f37a27c3d361aac56d5a954af1252a1a5de844b4d8dc0cddbd7eca3b0c970462c94f5f8a65f625d8461482d689786008f4fe618e75c809220b4ad8f3edd7cb446a01eb38e8ddeedaf594cc2d519406a2d220c69ac9fa9b981b26f2e4daef860adbf55646d5fbce908dfc83373b6f71775d012bc3ddddfc9cb5488fb76c47dd368744aff0fe42a66e9a47c9a7f83ddafd06a244d7c1f86be40e75091dcd18f2222a0e6babbfbe232efddf54a2f5313309ee55d8caad2df6227619cc73a49611470a18217513f9cf039a639c6bf621b1a789c7512abe93d21fe35ec30e6243877bbc5fae8b0cf875a5f0001efd5a72a4a05df44b5dbbcaa8bc2d70983b2d39f278c85722e791922b8ee388c4628c86b5cd84cd3a54ab3fc61ddff0431d36975499a4913fe2869c9a4bb235c20ca53826bbe370090e596d74e23b098198c28d1bc63dbf3aff7927111e40c4aeb0ca9dd28f4c5e4565f9c276d1d494a730624a937b50216549b9776752a7d7c107db8b6a811a5ac25c688924bf042833c27242995a6b26ae392c6facf39151e49690613e5a0c60020d60d83be05e17f1f52cfe9fd919426c88b2e9841c0783788da2ab0ce6cc3f3144571abe4e9d13f7169244929d9cb4035e38b5bfe2d886ff59b3bb64e681605f8fdb3f1200d7a8b2b664164ea687d5ae7185d122cd66e23a457520d14a4c15da9d230c6c9679b80a39cbf857852620d9bbfda0d324f0fa35181a62c3f8917d2e8be7f7595de9117d233039101616352055caadd3fcb61f356187c7d211de705118ad5b61d7032595f4a4936ab8bd9bacf4b8d900214ade642dddf016e9d6deecb133765b8cc76ae5468a972b0c037836a2a2562ed06bc7ec5635fdbb195cfe131b8a04aead25809d970dd9e02450fc9f8ed2f943dcb29d44c38e4509e9c6fb462f2ada485b667d3a0c620ad8ba9a95f9b3185e7474e8d8138c0e185ea030e419cde4f39357ae10c27701c42ed6512b77033dcfe5d2934390e422d4d5da10a470aea449c07fc374017595302b4f416ec6271eec840a851e783e2e631ed8fbdc1928b7bee56c3bea5b0c4fb661c690c6908481d9322ea3b787118c00f69cac3b5b99127009f5069f856545a6600d65f42b2711a0c938d10c28db3101c6f15c5f4d81294792f6af6598006e288c238b65943bdcc1f54827ce79f9e6c2fd4794976dcf8d232f04aa8e32c12770f556b263782a737108d6b7e08e4501c1056c871234fc1d122edba95ff5fd4ba547ece35931b1f8f4290cb46a5a508e5ffe6664c29c18dfbb81729f78897d3feecc24ff0176bfd0e9e43146151e413c24be78b6f696b4532a6c5fe46298fcceecbe86a19e59ae898e9a5340955fc5f3b513c72ec3819afe082347e9b0a7a09745886c5efa620dd07baf1e0878b9a1a1959a9847c10c0724e6de099de00df33828d38745a6bd66856672493d1b340af3c92151475ace7ec74880544d461b83c1eeb52a65548682d625f469fb5d933a6633204a411bf7ae7f4c8073c74e1367597e7e5be82aa690e1609fc58808cd3aca112715c6470564d8ace4ef3d22d9396b232537f13ba6ee576b66232224509a5f08eaf89fed4942d32620e04ef9e30f9a92e2f3aa93ea34c8e469b503297ed77dd3f81c7594ba0f2683ff2758b91f59c729091416cb2c53142a56de313b9aeda3dcd90b9be4ea23403738dfb69871e5a822f189aba6663c9e92f561525c93a1a070b521a395d599ca5d9be95c6fbcb2bbb6349a3ebc5f6b8dda740c6b24292765f99e65405c7d286378684ee3e3098290a794047f2e0f983f4b9133d13c66c041bcaefe4d686384d910e25b8a9f65531650d1ebf6bec41524456c2f6e871914124b8d02637eab4a0e6c989d6f3afdcd445c122dfedf655d9a778a911956d724b43d620605d1e4e6cf02f965a53ec5072a29a0e58d9e8ace67dbf0e57c9e7e11f819328e7b935ddca287586e3bc6b806cbce4f03c9405497e236841cf22b36902fb8c95ad5229af21d49fd4603341a9cbe932f5bc37f741c318c3fdc4d8e08bc3c025dbdb27dfb7075dc61b5f1caa9198d51ac539d418501bd29504c9513cbf94a76f572675a49866cc1b760cd47a19bf81321009e823037d3015ea585a2dea62e53ecc704848ed7a6a6cdb7d349c79728f2970135c4b59439f9089344795b147f8ac3acfc2daa14a1929b88da0f0e8c9532a3d930015ca5b4d4c15c8b060c877409b77ec06c8d77d698773218512f3dd73c090c7270232b9c110b70c8fd7b907f5d999171bfd8247e38a835a1eae7032760364a9d133da0a3e6352fb9a67291a25527d1ba0938a29be186b6e2b6707a75afe9e42974fe61075ee83b4a539e8b7069b0341696bc6cce7bebb74d2178bd09afb023cef11de17a6d57687fa4b61d957ef101610a54c9fd7180d55470e44c8192d97998605ab9746c883e46e9812410f6de3c3eb78481ec02f885af7f7fdb7113052e21248033250779f3edf3183922b79132443733f9fc98924c699897272f7bde6d994e4a261a2ac649ceca04abde6fd75d09f5b071e0405fb393cc3b24915bf345046248492007d508a89e1b329f99225c1652421bad4be8f743c777b5d2296d7f9cf7f9dbef413630200fe1280c40b0ddfd94f606db39fe0a00001fe7e82e45b12b1ecc053c7633163dac4d30125681f7abf9012e20439a31df2f52179cad646975a383a919e9258985cff31cd44d244932032764a499600854bda1d4b3e8e91672a3ae770e8d8d017a24c8e54e505cd1009890126b218ddcddf2822a199567e53003dacc9035f119f2339636c352c6878460a1df18f2d94f93371e25e17f0caf6b5a32f2cb60d3645788ea1a52b46b91c8df991fba517dc47173c8ea8f9a2cc663b8ffbccc6cfb4f7cb0ac69f4d84395089edddb3bc61b55c001810bff8cb5ac0b3b67f2638e7d7825128c3fd4631bac3e2559200dd2ff00648ffa0a1616727ab4906a9cd1b49bc1cad0ac98a465d40746d28f49be59f67a67edb4364b0e82857426e901ef07f77100f6b29ef9b5d8b5ffd9d53e96cab2e7229edb15fcb4ecf51bf638bda6a2324c304a28aa6421eebd701dc8394003e3ce4b3301c283c5fad206d47ec1ce9c1778c96d407395dfc90b68187710f25c678d5ec0c3a44b9bdb9b89f92c75a1bfcdac08b27f914f650245b8bc8dcbd2723d71438431f4ce420a1c4526f998415f8b591151e9764d6389ef028c070f8f908028da650f47f74130c5e281467b97183ca35b0eab52c4e987e55682b45c428b87e296dfe035be365eb20a279930052caa156ad2c401e53daa855968cdaf2363fdfe57684a9a53b3bdb4e7b845d257008cefbf829f8480edffae2140b34bb8de03d3da50e1dcd1f4b015101df584a09ea986afd0fd5d300acca5ffe6c60772732f84e03a3fddddb0c3b6146d2a2a9b50b89593b4ff6ce4be8e0ceabf004de2f3d475e3ea9174b67774275be068a26b3ee617c8f292d69ed6adada6b99331c562af04864a7fd46f7389656fb71949bff89903c887531cf1afbc107bd1218a0b29aead21a1c738690adc167fa4e8782dc340896de14d7d890a03c4ddfcf6363fd3bc2450299c323112aade9b96a181d39a4d1fe06ad851018d2e7ef920d9531ba66e9faf21b53de335743863158ef198bb42096cd7b66297e31cf3a7bfbcf89e5085b803996137130628019f1d2671ccd8419d8091346d632985fa081bf7d896af11091a75c4e073e17ef3d85d19fed40a2078d1aaf9ee9277b4151480848da06a75119ef64bb700416c0e7847dc64b698cc9e083d3ac7382244610462e7b1cfb0423cd4f8b47e004dbcc2a324b2c60961c554b8a6e594904994621173716a0ebc13eb117c0b30e08d0c4f50f38700b1221d78990ec746ad6e68f75d3e15ad16add8e94faa15b5dfe5c371dae95add6edc8f583be2e7f5e370fd74aadeb7684f5535b977dae9b06d78a96ab5b91533f74ebf2c7bad970ad6cb16e47ac1ff575d9d3ba79b856685db722ad1fdabacc63dd3cb456b650dd8aa4faa1adcb3ed64d436b65ab753b62fdacadcb9ed64dc3b572ebba1569fdd0d7659eeba6c1d5ca16aa5b11d70f6d5deeb96e1e582b5ad76d91eb877e5dfe58371dae95add6edc8f583be2e7f56dd34b05ad97add8e583f6aebb2a775f3d05ad9b26e8f583f74ebb2e7baf970ad68b56e45ae1ff4d5659faa9b0ed6ca56eb76c4fa595f973dae9b876ba5d6753bc2faa9afcb3fd7cd436b65ebba2572fdd0a22eff54dd7cb856b65eb723d64fdabafc61dd3c582bb6ae5b91d64f7d5de6b96e1a5a2b5ad62d11ab9f34d4651eebe681b5a275dd1ab97e68d7658f75b3e15aa975dd8abc7e68eb728f75f3f05ad932753b42eaa7be2ef35c370faf952debd6aaaceb81b4ce9258776ed7f28ef569c17a61b5ce4e5a776e54cb3ba53e15ac97acebec8475e7b696ed5c9f0aad97d67596e4ba63b79675ac4f0ad64bab757682ea8e9d6a59c7fab460bdb05a6727053bf0e9e6e27595da78cd8db37ed4d773ce75d3f0baf2b2668d5c3febd673e7bac9107585abd5ac88f5537d3d7758370dd795ae6b56a4f5b3be9e71ae9b06d79597355be4fa59b39e3bd6cd06eb8a8bd4ac48a81f35ebb973dd7cb8aebc5ab323d70ff5f5cc1e831b9838183d8818bcc237128c1f440cba02350266be303780ac297d5fffb05ad74b5eb7aeaed32b539dd52235fd24eb56d575bda47556ab75fae5352b9575fd64ebd6ca3afde57556cb35fde4756bd5757d9275d6eb3afd65d5ac54adae97b46e4d5da75fb2ce6a5dd397bc6e55b5ae4f5e67655da757ba665d59d797bc6ead58a75f5a676d49ebb5b316b4e404fe5ac49f0d5930da15a70365c8adc03f91c0cb2bf8442ff1ae0f983b993345a653cde1cc85eb31bd9f6bad2d83c6fa70bbac5c002cbbc0851da4d02df48032281b10ccc1362edd1c90e51f434a40fe2312c9d89684b4bdf7de726f29654a32520d760dac0da31b54f65537bb267a0833ad77e4f2f6b3e8ade8b2a89ef4236fc9b8328c5ef4ce0485423dc9061b9e7a3d44f6358f001d1dfd4884dabc1ea207821a3d27128dbad8c2d67a13958b5fface0493fe06dbf234d1864e87cd8d7590e8bbbcf60470796a83850ee41fe9576cd4b8157a1397a7237b392035dea5c6d3a7f4b2d878d2d3aff1345ec38b8c26d4ba7c6ef990d7c3658617b9bcb7ee153265dc4c9bf48ccb0cd79b340ce95bde81bc7aac161b355c9ec6adc55e4b4616039a241b846b30aabe5c462397eb4d3ce82fac1ef45a02c4e4ff1f65551e7b99fe454364398d447ae8f5307dcacd416230e966ed8d682cfad2d7606a515e64514e36f70dae6faaf7f43451c5ce23febd855847e31e16ae7c5849c3ced8ec3036fb0eb60879ba72c7bff934d82c93b0505a7eb631cbc2d5cc99ad1b57cdd1f75307cf9f71f32482278d4fb9193ac1292f8be0facf3486a669ffc2dacd1a37b2dad7aae5f0d99fe0f8ec4e529f3de885fe88accd8ded4f0f880df37ac878fbb3672a993df38ae993792ccd5b32ac5e07fc32349fe339ee390e6532994c280b44853ebc948ae8e945a67b819c5e05a5c1100075b3639587b9d9f1e9a70f16695a6eac62fa98cfa88f11699a767a95d73ea34426d2d4c2743299488ffaa90435b120994e17f5249537dd3c7d30e98538d6e89b6e3ebdc924e30a9958c5f4b9ca6092c1f432981ecaf02693c9944fa84c73cd2815d1d393e9f4a2cbc2c393dea4c3cfc8bc8e1caf9a3d53090a357db0c9f37aa0543e8432bdb7260e7f43ccdb00f32ba81d26944964427d357d6683bd4ca81934887e070e37e68a60b0d713ac6279384d25f569a20c19b3c73fd2d3780d0f630d1b3bbc0c33bfbaf9d3f178fea89ee6e61c314f613ee3f03c7cdef13c5018988f79edf38e2b64e21d4f9f8bdd6773e3efe715f549f7b33f91f1d99d4068129d50af3df779869ff199869f7181d0afaf7da6e1e6c733749d81f3aea52586fe8e9b1bc3bc66330e57c8c4304f2f4bcc931e87cf6c567e061b9e861b7ec6c3b8c3cdafc3cddfcccd9fccd571730cce994d8eabba3907862fa99b290d8fe3e68a5f72b819855f6cfc0d37a36abc0d77e5667a0569e533fd1b70b89babae5c2113afccfa22afc7ca03a1367cf508d0e195cf6c665c1aeedf7067b899e2f933afe899151baa8d5be3661aae9059c3ac3ff258350686d6a7719449841aa146a81fb5d4961ffdbce2b38d678fa41d69fa90fe747af758a7e7a4482412893e633c22523569f38a86214d1f2c714f1f4cb2180f9604ebc194f837477fb2f651367738e5319ef8b7b6cc9d0ebea47ccadf9b51292fe3a6bcca6d69465cde9a3b299f857824837db1346c37b2107fdabba68ea7a00c9a9f793f600f802b97f837dfa5003d5c9bb86239008fefe17bb8436a563c1eae783c115cc25089079ef0f0168fa75a7e3e67c475c4a3702938f895f4249b6330e9a78da750660f1f7f043699de8785f125e57b58968551747302b0e966d29f9ec3ba1b5682219f9cac7c4284ca22fa1aec3c593ee921c1788ce75137d3d1cd35e56694bfcca7f4217d087335bdc874e7cb9394ae27f16fb24477fe786bfea0d8c6240b5f98da2cf3fc89994d66239f78eaf4f3251836a7d3c378fa8faa1efef49fa7447f3a3df458a7879552d21512f10f292f40020cb0f6300688941720e10558bb2c4048acbdc4da65d1be066bae5654b9117f99df9570f6562b7bcbddfd6957c279fee4169ce70f8cd95dd911d1cd5028bee1b936849ae5784abb3d2076798a65f410b7dce0102992b53c35faf999114fd99f9f1df1146c716ff45c4bcbd3b8122678700b864a9830826d50e983297dcff321c6a7dcfce194e7b4f7bc207ab8437a7819b6e5e6c6329e7b6b6f6efc3fb2da89f427d2b368a0308a6e1632aff6210f880d53cfeb71ff47106b2d0d7bbd7c33e82dbd883e893e49a43d893e49f4345154b2405a3e094c610d946a5a0da5173d8d4b277a86f41aade1e9438f00a59b1db77c0d373b46791aa7da537ab527913e53aa514a29e90241f996a79a7673cd10ed45d484b33c42b240e827813511ca8bacc4a62f89be248d6013c953354a6f427912e966d9c2a617e2a4a79eaae149284f22a15c520d9f3d08934ca42791480f3d20b4a7245b7af96660aff83205d0a23dca5394d72e4bcb9b9ef4de724155fadacd3fd0d7e86ba417bd2cd233da8b68228d6b2f7a1309dfaf5e0f1baf5d20da975e648364832422916c8444a4f74424d1d78728914be7b14e1756e9834bb60545a3572b824d5fc39ebe064bc3f760594f13af8558e6f8677a1a7fb9997e37d71977c6d36b21a62fa28fbe5c20a29ff1daf7d2899ec98d4f6fd2b49b85c8aa4d5c2f10faa7d7fee6ee1f4e4f9f92be42d5dc892ff3b58730755f7b09532daf3d852994d7be83a9920066d0ffee6599f1a6ff7efecc9fe16614ea65b8b9d2b8da9b7e85d27819bebbb9aa9089e9672113d378d39f9e6569b0d4bf196e1622b30361d36b5e0ffa4068c8f0d4234087298d9ff4e609d460ed65383d8d77a1f1281a370b99f5f499c73a6933e89ffeb6a094481785f1e0b710cbb08da16b9e82a377a0a8eae1472f9de899c6a36fb18dabab309e97399e8278f4d6423cfad168f41c4ad755e5513cd68ac966218e62730d0b85f4a4cbe20362d2f7809874359b9fdadcd93b6a4f0fbd1e5a0d1659ff295921139fae74a2614c4f135b9862f7461756d9c226eb2deb468eec4415eb270fea3f53d6458d9ec64d76f428f6df5b29ef7251f5b268cf7a1e0f3dedfee0f1ac3ba487e7d1c3fdf892a2f2322cc4281b83beca73ddb5f0a0cf622156b114fb60e1aa3d959f277d9e4bf07cce078bb54c176b49dc696f21ae020b4ce60e0e6c12331b4a295579e8b1565e7a04a02b2a120bd29d5a40c1037b897ea285584e5163a89353d4ed670b1f144e0aa1725be783852be961af2454fada676cc75352788a5eac479336803346d01b4019235038e5e7cb1d2905d481c75350e0fcaa879f2fe74ba0a80a925cb88af5f3651257612faa04cf57b1146341120b2df07c969d5af88be9398d0b8949a49b834027587bd3739a35d9f91384aaf5985a70814b1e4b74bd75839ab1164d2cd922e4fcf194e9e74f2d3c25faf9f3e52998792cd38555fbce09167de701a13571040858f4188f7f5812ffa6c94a961fe86b4f6f079d60cc8847532c143d3cf68aaaf9135fe6535a5f2f3cbf078b25f11794e738e88d6eaec1a3c77a3c45bab931e9e7e983f40d47b2588f7ff3512cc603844afa8cf160920da6b45614eafffb6262728ebec15a126060d14fad542a993ea3704a4a8af625d3a7a05037d718814c4ef6e1a7bd9b4c3733008b687803b048bb58cbbf8b19892936c31e9cbd95fd099e3c9e42f9f958124ff59050b8bec1da731e101910181f4019bdf6a35bba12e81b8c19c940cd580bcfaff6839ff7582bffc0da4ffa989104cc1fef51a85a7958085f3c91e8e623b096a7e89d422ad6c28c784abb8e02eb268030f343de8a56d42c5d920570070e5df1f8f9d2e529efe7cb235046fb1d703e17e09963c5e3b384816659bceb4430143c6e0e2b5e20e2635a277d2a17c455d1155fe6cf197720182e18d444f07cc983da3959b6e32916203098e1cc4e512546e9e4143548cf380e9ecf69f27d04f0c6c49bc78a2ea014ce636d473a97b7fcc3720721af47bcd814b54fdd1435c3457ca142255bdce0c6d95b593ec96cb21b4f752d30f07c3732fd488c31461c3d97f523aee35f14fe4d0e76b6bd95e17837b3f11615998db4a9281be79136f4073e601188560a848df8d78237aea8538b9da8ca6ce2cbcc6c76244fccb227b3913ea8f375e78f7f52c9cf760428f2a042ac7d8a46cb23bef6994d54f1b8deea3e67ef2dffb2cfaebbfc9b3f3fb3f1947c2ff3429ebcd03f1a3d96b6759d07c4113636364a607983749866c7c1992b527a45f5064976bde5721cd38a198dccc8c920252c6527f16f768ea7249489ad84b7a27523f0c6f4967ff3aba8f2e3676fd1ac6687b70bb6f8417709155fe2a0e2904a2afc38a515d5bfe3072961296dd41e70b21b6287df5dc8e98d7d144f9af99d72cecf6e0ef2e1f872d22927cb0f45482cbfc3f206f970bc3538e660c7958109738cee98bbbb7be7d39bf246b7c187bbcef89ff1ae9a363636363a2b77c1ee32b07b0cecde829dc3ce827dc3be825d05bb67d84fd831ec26ec137b0a762f7d2e618fd849d8df1d057b8715ca9cdebf3f0c553de3c24af1b5ef2223460bcb8a0aea644a29917a50c004f61ff9577f917fc8f3efb84df3a7ed12de8037dc490770cdedb905f75d4b98951e3128e84b2bbd1f34d961b67136a39c1e2b36fc7a5a20c28ffae7fd99c78a5dc43c56df8a45cd14c21bfdb2831f103848836b8f7276363c35bf7af50f1554818280aab6892f4e135fbc07c640540ed546a681bd5dfe2da1b64d44a1a20d0d96ff18fb060001613f6de7fdf0585e493380427d031ec7db3bd811254b8ae82027c9119b86e7670dc35c1bbecc97f71bc7d8c5f9b267538934c983da6917b35176dd853522a066257ae8b14418b38d399bfd663bfad163717e83c4835ee7369cf59bc6e94a77501dc76dfc933ba819c575b6719a8877cb3f233aa8b9eb304e3fc173d6d8788ad2cec21efc9b7252ae8970b7713a87fe12bf12bd4c52b3e750510e443fdf5bf48da898fbec28c0f3dd047086fb39ad115db938433334b59738a8b97172dcc6711cc77c4945752e15738a64539bf1b7e7386cb33df887d344240e386b3a387ec5b08a2bb0b2a82ddb6fae9176e4b1b22892859a650f2b8b229e2ae2f2947f6665d1b2ac2c5c4e2a2b0b23d79ffa578fe56db522fec522fe419c31d77904c8c260654104b3b230e29a0b177195d6f297f810b3b2c8c1ac2c8cf807b1ac124fc75859b830cbcaa2e51f2b0b229eaac110731e8423561638fe419cb516ce22c73f88695c070f882c8c30c21803f6cbca82884d11d983fa2f06e7c05a114f654dc3d172e8e7d06e8ec1d1a36b3b0648c2411a59bab050db2574bf50a2a41715eba2ca16867154f20fde70bda8742bbf858afd6ea7df20282cdf25205b18088d38046e8b1ed8d8e82a6c5084a78b957f4461c2a487eb62a57dcd6a484bf1a40441ab24b2267056fe0117d8f4ac7a891d9d9f15e7104b96fe78e402608042cf0a122167a5599626821160b0f27a782442ce0abe842bb7691a043dd1b39a19020d7a569c3774f749849c15372d87614fdcb86e9e10824c7271829f4ab50c5081071fd80110b6d75ebb4376501105cf6afb9a157cdaf0e10d7fcda26cb5428daaad59f1390ec21b19aa0a81e3b7c55eda20289c3d970448673564fb241c03af2cac90ccaf59719addeccd41b8f658d4b1fc18fb43d336cbf263835fb3aa59d1c4cdc2555bec89488288962bec0a3507912d3c6fdd2cbc22095e081a923961954409062bed373b44fbc1131c4dfb24b0275bb862a55d1f4ca1c46705b3b882177a569cec360b7faee80267d5c4164c7a569a8d9162c56113c3b450ae81af189ce0c94ab32d1b5871d9a6691682e18a9b9ed566512f58d9c044117a76e460083dabcd7262587152ca2eece8c066b559162a561d64e4033dabcdd28062c5619db48ee3109725ab244830586dafd9216d4385259eb06d9f446bf192c213157321a75a8108f62fb56014d2501739e881cd6ab3f00856ac6407a30a6211b484271c1256f06bcf5058479b1d229178e15a2541a3006353a17e2c01147aee153bda9016411874b64fe2861530b0da6e37410340f881ce8a9bdd6687b41341af5512ce457706bbd0c2919d9566b921ac3878e282523a859a69b6e134bc25462c70ac5fe8ea108ea07f51c64a3b2970cbee156010c6eeb7e12ab8823ae01c52981440e0842e54f00b54982006537440044cbe5879e7bd859f7362d2664e2d0001053ff080089e4481011fdc68007281e79c4666708425ac200b3af0b1c16aca287d80810ee010863e50c209cef5a30942369881a10f2e106482252ff0c00988f8e002449af0c1057c7c70811bcc38a594524638e31de253e7374eeb782a674ecf899e83ddd939d1678c4da477a8d834ccb34072f69dd53a1a4559331ab5ed37ef6bddba6e5db7aea3517d9a58b7f72c10ee21eeda3d57ebf65e7d6ff346a3a7f1ce7bae8ebcba61d145a16e74f304aa8bdcbba8f8dc7621101c166b671a70f224462ec62c7c816fc05049167a627c2e7e96612ea31f89883893527ec67119c7c59716c8ccb2eca56c0148eee1430ee33e0b3b59c0e1b84d05d863db6340b29b5beb42a2cabd88fbca719fbdc8721fb2dc7b96bb59bbb9a6d46d9efd68816bc050c91674f0165ab84180a1122ddc60167f88a9ecaa65b7f49d655993b227cd2f5920797bec93c0599348d9ccb2f9421c6302c09ecb127b501015407b93ac3ec9e68a4b2552a9bf447a9a48cabe5a20a187b849a59b6b70a93bfb4afadad90b715cba44445c7a1a17d550e98538aedfd99cfd288dfd2cd50ffdcd2fba4d3a643d0e73376ff7629f65d69b344cc9bfc66a469d2d010b5ce00fc31e60c147c6b7b9067710c60143254ea4c08d73df2cb1cdd5bbdc98f663f1318c5a20440c89de0f11cf6f98258699932398060c9560010ccc651d96d94c45376fff19cd68662ddd5c75bb4226ceb01ed905a2c5fef811cb382ce32dbde6338b209f0a164da4f82454951cb3a8540df8f96789e7374c7df36271a7c6f85e03a666c0cfdf31676f9418c2c6a6fb1970b339f8e7dfd91c8ec37fceeeee6e4a7f56ff26ec769f169839f88bff8c0b65e8fb5b28a3bdffc7f8e7ef3715de98af7966b3efec3989496f28a58c5a48e296d553188a85c920251c468045133c4b9a5312945e88a4a1e407513aa48e23f24072d0fb8605ef109fdaf0bb5cc29e43a99c8dd38d757f4611b16212f1585352ff7a62cf89aac6691c89db867ffdd21b07378ebbe6169c4c4295cf69da671ad434a94d0dd32ebdee3d00ea86104e88799094d29bb40379130ff220ac2514389945cd1d865d7bfc935262524e1fff248649ef7702cc2b1a46cac766cf9e7945c3349e3e526272f64febb00a1a8de7b20b6513b210f7d9a59d136a86409456b94505b2fd0c7d7c1f9e127dfc0004f123019eead073cf3df44299d75cf6126fd79b7476633a9b438e981c7278cae1cc9a30336fd230997381fb898861842197540c2887dca276031ee029eee30be1292ff4f187107284a7ba8f3837cedea46142b7957881135f8806780a2af1c206c77f40845c40cfbb44c430c2e866e67e023518fb9c3bfb9a7dcc2876a9d75b0fe6cf1f7122da734eec85381039b73933aca5077993ad1b7b218e696f17c867cc03823e7d6e3e37a553f99dd7a3bed64090d2f8f4398f454b2494ace9b764d2124827929fcd06b27d97fd749af2dda7dcec78f3a0d2a594de6efbeeb3900944372f0bcaa6fa90279fdefc837cfaf469ffa43fabedbc1ef3e90542bf933ffb3fa5747325f5cc8064fdda9cedddd01d5d07a21e8beb2cca667df8e712bbf229f622cb3d4dacf2b9a7977bf9d542dc9ec426ad1da42f61aa7b7a433f0abdfc2c640231929745f43411e5c67a3dfad8cb91f47a8c1e88aca3a7f1bfd87b7f73bddec481a8a5e981ebac84147eb542fa903e7dfa9462d86fdb36e79c3598dafc9866fa18473f8358da1a9c7158fccd6a9766164a5a6a534f0c8d6999659a5643444633cff18fde0fd2898699334e0248273e4619456ee777cd894744b7b2e55fe71fb535b4271528aacb28bc7d7ccf7696b330aae2cd413e8cfdac4ca8d8e7fa12ff338a66f74b00cebe69f65d4bd863377a40a860d1a40694e587db49e0c3d23fea9fec80cc324ea354d3a8a6514da354cb7e7ec6c264d4da43009d684d1c090274d23719101839b86fb6e0bee83cc2768f53ca39e59c724e2967fcfed90e45dba8e0e567152c3f8f30fce2cb971d1b520fe8474a295d7086b1da3941d188d1c19dc8873d07ec39b06353524fb9d3c64680a281a3fc1286dfc597118b31c618638c31c6884929a5a4f9604f0e3962fc8b1f8ef1b6d8c8a8ac2207054dc81e8310c26f20d063cc329a652fa02087524a1963b0a8fdd946966534cb4a2ddd2341c61c28a3e1d99a8d2b0a1e2537383ec402c7f6c1b17f70fcd91e3b1cdddd5b38c6779f7388a7da55dc4314844fa4ed961b79aeadb7dca5e27ede2c44bacb5bf2e52d37123d96663b677611ff3c65c45dedf3b3d91921a97ff1a9f458d873997b9679967996790e52c2fd52ba7759363d7a08c21b9d139de5b78be038115771a823387eb73c253f621fe77b8bb3f1c65f22c7d9ed238ef6d255dc6bfef439b71127daf8e76883e30d4b3ff7db6df19788bac96ce28da7703ce59af76b4dfbb2fc90bd7f764b57021dee22fec5ca04b7a0628ea78a78ca33ef7a24b5c1f3a51635a378a878dc20cfe333ea7bf00bfda56f504de4b3cc89c4ef892eec3defc22a55fe30d3aaf21bc4bf0003cff71ccc15c1f3b9eb443c56943e35770ed7414e4e51a59229e844d7159430f9c2ad80a18ccbcfe7be1cff6690084015b604f8327f6250e0029e585057ef358f5544e88508a1b2ecf837a514a5871eeb468f10d62ef68237e673243f325f4d5a387a2a63ad1fefe161159ad8c42ae0209c3d0a2d62ed7b44ac6946bce5e2317f5a190f9bf57087f4ca0791294f203cbf07173872011cbc6242cd27a1aeabe8431ecbd47941b88ee31875ee89ae1b31914426ebae23414a587b4ee491dc887fa46f4ff44fe324eb2ed1f55666136950b520259ce3b1e8ed960f3f1fc5fbc1e359ef62239647a8593e69299245cdd385440fcfe3471ef46fc6bb58893996edf11c07b994eeb310cb23603a9e92f1d345f4a26f61397fa68d1a0fbf86f72209b6182af1a285395287e2f588f1a7ef6159cfcdd0b9d8c69f6da8442708571c179e9fe548514aedd8d8d878b1ca25ece5a909a9e029a8c4055a7438cf1f2951aae96f90b4dc395b8e63fa407dbcc8a7a8194eb683ea670e4f121bff6a0e9f290f9feb8ecf28bcc343b8c37333b8d889a1a7801ecfba437a3c8dcb27303f55f463601ef60cccccc33ce79e4df99145f158a3e7ba01986aa8871e4d7992adc11475e71523fbf2295686af1e4b86e7ac6d3c83cd357886e75aacf6326caec132be6bcbf520ff5a3e7a2c194fc01b28cd462300e9c28621916c762622d16b1a1559e7b9de436b8a6ac810dea471d07e08a6afd94b7a8eda8cfa09d460da94888893c040eca3449ff25333f6049e9f4251ff049481382545e5b9d8d9f923b188947299dc94a789282be3536c8b8acd11cbb016e29696ef5ca3f0d40c99e299c78ec09eb181869fc1622f163382c9b050b05e060bc50f3f7f563e879b295e791b37531e6eae78e56becb81985576e8640b87e0d3f5cf9e4668a437c51dd5cb10d37d71b6c7e9cf2dced3e0200e06d70753c753ca5e3e773fff3e791ff4ae3bff1bf0edbf8ffffbfe39ae346a4910b49441ab9c0ec41dec46534bad983462b231ba31aa3d1e7d168347aabbd03b5bc336969f1a8bdf47ad8f02a3f8f786afe7469ff103ff4204ffd8a8d1a35439270206732f22fec0da391033913e7c26574c305e2f2d69bf44cda43dc2919c6b958d1cbb0f53d6bfad0b48dbd0f7dcbf806e00d2db4ca39d02ffe28281bcebee1dc4e301d97eb882bcbb20c73b1a3976151be3dad9d6401aa9c0a4dc3b99df0389917fbf9f3caaef3156017ac182d753b4446e000b14c55ffa1e550dd536505eb949bed6f96a0ab25ea8a748313b322fd127565bb3317199ee9842ab9946468597777cd6a67fdd00ba23e8dd7ce527e6443265bbf64633ccab6a47c4864e18ac4c94ece274e9c7ce1049bd3cb204e7b72c3a1abd05b8b5357294fb2374bc4ac521ea7ae420f3d22e465c19040f243e5511e891524541e8588ecb5ecb5cba22f6a2dfa277be7c99c47a489325b04101149088c10068642f407108511461861ac44d70649fc24e2922b14b15921e96f199ddfeea18c9651ec77d4cf31a2874258018622f460846e7fe124aa6e90687fb3445d79bf04cdde6fea4af4fe6ec3c9e039701efffc5b89b65102a65a08b07ddcc753ed829f10da1579ead788fec748748720e9fb43f4f50e41a27e0809244888deab81b4c67ae3363b1885a59ff43ca3af7f80d1d78b04e9455f2f12487e902e12a1afa41f320409d17b8fe44768f470451aa13c0c953c71821f96fe1fa2f7fe47fdd0ad1ffa256a761e279ecab0bfff84fef592c1d29e656927e29f67d1a58351e7718d76e24b8ccffe84f4d97d5cfc75faec412e3bbee3398ee349fcf3779e1ec7e12f9548a144b03ff5b4875e1029cfd24f1f4bb113b31cc98a7e64eb2a5b6da0c50177a209ecdff5a00b57e7e0e010f1eeee9da872ea3beef2200e072a0e76af3d96f6992d027bedb274e8375073ff3815f086671d07fd021b871c6a1cd9abc058bbce8393b17a021dbbba6249ef62473f2dc421974e6ae027c63967d6ad58b89a0680ab1bd49fdec5c215d7624b1fc3aa3cca9afe64537ecab0bd323de96f527ef4588ccc42dc62fa14d28f445f83f07e444a318d32bac10da586b76d5dd7853a8cc290a8c29a59c72214148a6114c5c33eb31ac62231c042bf06d38ecfa1745946a976a3996857e3c039b55347bd1e8d8b60c16e1029a1efcf6c110680ab9b18df7200d193b8d0fd9a558af7a1ffe17de8b30fdd2148b2fb63f4f70e51f9d1dbaf598981498fa77ac00511eccee3495c499665194b01bc4ff91fdea7d83b64e5b264de6bf7c7e8437788ca65c16e01444f7a96ecfe103d89e5477d94af34ce91ece951ace963d8d2b758d4b35819ffd6e569e94f7f837a93e78de00ae5a78c77f99b9bd2df9cdefbd1d7d8f4c8339d50251719ab9227e326447a941784f7a4114a085535dada9431ca18639c1aada21700205ce94e274dc394ae746d398f357f2573ccb574d5b68502e75b8934ea4308df96227bd1572c4eecb3ff60344e5c2d4b26b2a117fd01bcaf1789fade8b2e12487ed4cb12844854ebc72f56f5b2643f42427459b2cb5280fa287f00d18f2e12a3173dca4502c98fd18b1e0994af0f57a18799178a2f28a21a94d9064c0f548861a669daa6699ba6691ac5e27c81716969912143c6fbdb0b6f0e3faf181ad66ada8c1933b09f2142236c7089f3ccb03d47c3073f0ca3246fd81e398eeb38aee3388ed3300a7fb4f0b81a649081061a68a8a16b279eea3480fdb91abacd6315d1cfa2dd20462831defb9b16ef5d3e03a197f110bbc4b070d502318b8b35bd0c9bf2312cea5bece9576ce959acca67a837fdcde953beeb438f965ee56f6e507f637ad1df9cfe26e5ebdb1a9b554f7cf1175918fd536cf43fa1549c4451c979e28bf3dcde719edc47e82d3a8b56424be1a5861bf006e9a28c80b81bb81bba6ae10a0626d3b8ae19d68d757336d8e0b1e2dbe0f5703c5fe498c3a1a3160aefabc5f955fdcc62d6888ab5db52dc2cf1ab5a717ee5dd1d221562ef439f9de7c7710065ac80ced33310c2f4cd37b0e7003a0f602abe7b387b1e1702f6e770c8a113e180383a86e6371659b8ea9f9f899bd2a79946a9469f549dc77928bd8d849a6131214f9a6a3837420b2157e32c20011dfb04d8db092b6820ac023b0d84f101748c945b240012c1079499b8710206e023013d43d330036855aa07d3f44ce3348c10a95649c0050278c35f02ad828dd3339d0208e34df40a707ce89cd9cd9ed981da83755e7b8bdafd78bbe28b3fa5b5a250ffedddfd742fc7d13e45ed56d595ffac5b54150c95b4628029eef1892a99ef958e8c2788cc25832a63590c005735ab6d0515aeb6155ce9f85c733c8d4f2f881d76fc77e7e68126aeb00ef726e63c11060d0f33d77319a38c71478cb79150e70ef68b322ab8e45e4e54614f42389ef21c1d1c17f65ade4ee724aab20ca8fbc95c4fb20ec6f9f06fcfc887565c010ccce19c9e99570808e32f6fcc8541784a39a5e440ed9b29d69171fe743685e81828239d10a2677c348cbf3bd1aa2e092e6db6930278c3bf4b820eee996c0610265341d72008f00a423891035ffc3397066ac439734520fae3638d73e3d4cf8f3c7ccad2f8df115f26ee90a33d1f1a7f5fdfdc413b64faa755051e6ef4622af57134d69b9ad339397690d9f1b98376c8ec9083d3ba23743f590b32978c51c6e81e4b878e4c053864ae24f48b7ffe54fd13bb93d05d12ba1ff8a26119a38c5147b60217cefdd33ff0c53f736547329d9ec1ea8e1f7863033573653a5195e3553bc8642e991d729ee8c13974ecb8486ea44de682328d77789779dff13cfcf0b0c3818c1801cbec60217cb950ebe2954bd451e9331502c3b8ef9f89812a9b40420b2e80fd3b2ddea7d0e9f05e894c8eef32cd35f519f5dfcf8fabba9f540edb3e8ec3bfedc4a93a629d791d58520ff1fc1c3b78a07949c3c3efc891ea7e7644150fefdf0145155ead30cdbd893b45c03cecc8f1d35b5a53111c9fbbe5f777f77aac7a11ee1a3ebbe00ee1aef159066e0fb78dcf3170dff8dc829bc30d80cf2cb837dc309f57706b38e6299449791932dc367c3ee1c670dff0d9841b87cf29b867f85ca291c36712ee772873faeff308d3f0190577f75728f3f27db3ea53cfa96cf7f2cf3f65bb9f4e8bee477ef7e3a9d454a5bcfbe95e1387ed9c2c6af7d38383b5e896782a74aa3be480c30d36c4c000e0868d1a35bc7c34cc20439f80063466dc7edbff2efd32fa63b478b89fc5ae7477dfe83b6b8e9bb912e0a517e9668a7273add45f87d53c1f1c8fe857db3d16b349f00ef6a66d2c9219abe365ec0da6e322c99d9383b40ff558f3b149ed676dc4344ec70524c0bf1c0f3b670130d556f4f897e30aa12328a68b344c133180af747c2fa17229a5da39f37308778fa77cf867054c01013f7f21a22ac7fb03912589aaac8a7ef1772ae097e3663a34fbe99f2c08d90e761d1a8e9ff5643df07c9060d4dc3a2c5c4d0d541dd657994ed6772e5173f783fd9d4455fc892f3f5115795e3d40d8bb20ec8ed3c33186f54fffc8683fff72a8d53f4136d8bfb5f0257262990e1d774812ab1c37e4c27046125c4dca7de8809320f803573560ff8c037c1be0cc0761fce15f5fd5f82c4ea140550c7cf19f314ee8a9a8a4091d254db8b07f0e3a64a0e6182b82a270af00d8679705aee8bca999b671dcb643022634293faab06b23fa59615f3fd39e7652cad7eeacda7691e40f6bda719bc6b5f7634816b4d282d02e2abef8bca93906fb775c8cce4fcf87c6a69a69dc7bc7dd744e09a8d8347a6f3ac706fb94724a995d243926464a78a31fb330be7c3fd2370ce0c87ee939580e1344709c09cff11c2738482363d7a27ca4e0075500e817efe4e719aec590d492aafef94782291ef0731affb88b9ab1d1301df69423e28b7f3637db38f1c505f0867fb4ad63db056f6433378e7ddcae760154750ffa0743b17d219c3f3c84f380a909f8f009c014849d02f879bfa08f08350da693f8e29ab26ff7c01bd1a2b00e94710c57ee458d58c3b019b1eeccbd7eacb1f9057901b901519520c0fe7109104628c0588518b83fc72c60a758dca48c329b339b2f676c26542825ad9c94b5ebfc08b88910bf23ce31e2fecfa817fcfc7b53c150ca25542e5a4fa99c774eb38f568ba58ac24bfc0d741c9d6519cd329a6559761b09d5837262d8c4b0dae9a0b23ddc3ec7c070fbecc2d9e9e409f6ef2954b9c4ccb9813f544881a197cd99cdd911f366b41ac6b0d6344d7a51fb73f7701c18fef93359e29ff7cbbf1f1cf717d69354e803257870ee176edcafa87227fac5df8956459cf8e27f430d387b91cf6ebe387b1194c7a0b6809ec0fbdb7d35c0567117c6971b70762260ffccc370a22a2ef1177f26395cb4be704530746e2411ec1f5ffe29517f3ca585a7a28f7ffe4a3c56dfd8a344c5ea766f90cc5fe2bb330cbb1986350e5167a14c2fa1a654aebb8e51c3281d8c2a9f18a839be62edbf6957921fdcaf79acc6bab1ee166ca10cc41cfd150afb31e09e5362beea25d45225d598e30b7b7c697813408f0163363135e896a7fc53f021869e1017e23037ee255ccb77bb7bc728c3a8f039111d43cdb44a31d439279665946adab641c8715de77934e3441d18155eaab9d6504a798724b1f258251a5fe3a2ed36ae7a30d499a82ba55e0fc75fe14b2c5478bb1eb1db2f853720d45a0bb1fcb0e1fe0cf7cd14c0d1b7245491032c5e3ae881b1bdc041e1c4d8ad040c3a5c28e92208c32ab8900285611557c0c15d3cd176707c0e47186a963d39c4c4c0b8c0600318626cd8a831779cf8803f10c8fb0bdd734a396f7ca1a59c524a1bb2bfaf3b9b13c3300ccb6646436b36fddd1a8e96235bdddd7de39397271f0d1a33e4172829dfa7bff4cb2bbd20831768fcbbb45e5f863fb365bb10638c31c61863ec5a5aa48fec6171a172c47c5f312ec4e0420b0a75f2a194cbbe50f902552a91268e0f8eff458eb6b690b28552ad148a5e2bd20a925c682d97a77a7a7a7038ad935aa8355c8d0aabe0e20886555c61275dfba1c7f23c6fd2a0728f4436e9de18ffb9386750519ebb8d83a87db99ecbf1f8b77de678b6a7f12dbbc970623794210c772d4f651ce8cf3f63c208904ed52ea7e3e27ab40c2afd15af31c7d2b5dd30f43a084b01a4980b2a36038c0aec318a8ae96031a82896459b539b93bbd1c5a0d371e1382a2ca5b66beb18ee24fe713c486ae6e8431c3f7b2e2c3c357f3c25b5f0d4e6e270ee20da1e021f2c7c5c9ee7c2340dd3b4a781063a650e6e860c3426c6766a0fe6839b5be24198c4f2fe9d1392e5801cc7cb3feed5031545257d29c8f429ffe3f42cdf36c3d0f3a1634718d0f0580a8042c51f427ad4c7fb43e559ee90d2ab7c5b8a49cf624bbf627ba77976e60b825c2e1f4cd8d4053971416d4a4f16eb892f980ff69fc1618e46d716c3f1661bd081a2a2505a6b90a473d2fb8aaa94df5e73d2f85223b702cec5ed00733c34783dba200d0ba1b8cbddd77594324a8cd2ed789d4e0b6ac63e773a387b4fb0633f181016943b1fdc57802ffebd05ecefea3060f75cd195e800fe1060f75cd84be0fd743fde134f496902dc984ba354a3747bf58b3fa5b5a250ffdf1713a3c2795351ba6d017580fb7374208653e20bc36f016e57809b14b0e40113b07f94244b135ffa51381b744e3aa78dee4657a386c7f2be86c79a598c630d9b2ca81c110ee70b275bd0c6e4b52da91b8d632e4c67cb143b72a49b2fb1a81973bdb2e8b1322e67390567374887b99c78b71acc75e5b8235c12ff2cb724fbdc5c7fe63e6fe75efe71dc7c1ae7803c15b75831177cd93e3eb7590e88e3b817102eb89f5be2a9fef8dc8b03f2d4e57a381dffdc722e8ec73fc9bd3c85dde08aede5db92cd7f63e2a94cf4996bd5bcbdb62f700c47e4497cd9b60ebb193ae9c1f4b2600f338b1dc1e2c35cd893981c22ef49e806612e0dd4ede5673f82b98032d30bb88822e61178a3e36205b573d205f9375550b5cf5d50ebf817850e0aa9f4184f4a898482518a513ab56ac3d4e988d0f9c417ef747a867b354ce713555d507ce988d0aace8b4e67d3b44dd33ccf0b4fe7d533de0c204c1714559e0abc1a60ffcc31013bed70f052508ba05808c5cde1e8e4129dbd3ce561ffa0204fc9cf36e2e9aa1973b1c82fd297457b288df02c71d5369fbecc3222d8b31bec9f313032f605f719e3026382bd48901118e00c431fdcd8e0b8831076c47f74338783ebcd9c8de8e60fdd8c25796152607feebe3016c50694a28403252c9ac0244c0b12602e78c3b19ffe1dc15c51458ad84e54a598309729a5446a6edbb86ddb36adca2c966e889d4fe7d3331c4fc3bce2cbe6041e9f4e089d8fd702cf157fdad4783b1d8f52464f7e4bef36277881797a867bc1ed15551dc4bdb0733cd8df8a96123c7117e4a9dce52e880b4f412fb03fe6f214b4a29504fb6347b028b063561651748c31622eccd5e9784a7eb4b2e59f3482fb391c6ef07a843097432725161dee96db0fb63ed85f0a9e4d07fb16858c51c688b9fc736f7b6d4bb626c01b1b17d8bff3d9ba684133c19e2baa36276c580802f69f27a81973bdb06fafed05258f6cc5977e1e9c1dacf304bb7270a639b5a67ae730c1411a9b85abac6b186f27b4cad475a09dd02f3d4bb5eb1917686a15ecebd2af98e3a98ee65a5f5f97637463a2877070701a2701f025cbda532a0739181b8bc6d940b43ffc3bc23fcf3497df28c14e047b1870ee6ea86b054eac6009ce0d06f6ac713c95a1c32eba7170f6fdd33efef98f911a3f3716fd23716fc0497720e2de009429a2819a0315c7087921bcd13663ff1883116ba2c21e0c71af1200e10bbe62f790b8a3156afcf93f3c262646a354a3b45ffda2f48b2eeaa2a884db0cd16e63c4102d2d3d43d342c3ca9e835cd7cf3f1b4d5429a5c76a9e7601edf0784eabfe1441852bb8ca9ed33d3ccdf379631f57052f689ea842d9305442022d3eb73136bea86a9eef8b719e1c5a214787d0687a3e9a6e418f0f153c2de801822baa1a074268cfa505005fa805005f0b172d417aa66ffa861bc12e0c81d2c1e746d6575bbcdc09cfe946b25f4e784ebf7a8646c3f87ff1c59f46bf68f44c900f00ad3282466b036d444e909ee911400e94007281fd7168c675edea8c76381ce7f537ceb4e20730950901aafae55960af02cf1d134055bb443082223dd3d230ee390bb03f6da26fbcbb821254eefd03104457ee3d8f157aaeeb6ca24af7580170ff49821c4a6b45a1bcbe3de2cb779cc71941edf71b6f1f6ee33825809a37110298c2dedf9f80a94c07b6f48c0e0da303100e02d99efee5a057002e1f8181088938fe2802212209dc3dcc4934ee6e963f811a4ca96caf0030bef48f2096f206e19f0720c45d1fad9a3de721a4f13ccdf6ab611a2793dbbd2f9a793d1a73dbc66d5bbb5cd33c9cfb66f60df6ccea3061f048722ef2336288af67dc6608235ad54cc86fdade813752c044ab607bcff40c208c7faba0061898ddb37b44ea46fdea254055a9bf80bdb380f2b9ab40fadc50c0a54ba214e5dedbb788c6b95fcdb30428e320c879e5e0207cf4c8a4cca494928eb851c77595b59b4dd4d944759cdb558a2fa88fb3eb60044fc831d4ec39b4817ac91335f76b528f359dc8813251ba11c8b94f5455d789aaf622392d3a455059b41fd2ab94efd5904afad2c3950f8d2359b8f25411efd7b66d5baf4a36c552f8423111479002e09f8b745da4ec690f9ecaaee3f8e76e53a48e3ebb0d126c86a0669de74b68a6af799fb5ef977f0d445f983e10ed813c157aa7b456cf812fa1d79e0bd906ea977f4bfa45b5ec372f0035387b4555af607683f071843a7a8aa11214788127ce9ec33d7d6eb3d96f1e026a5628cf75b48d72bbae8d533c968423dc2e2843dfdde55f0ae08c8300c2ac00ca7808e00dffc628dcf522fe39ddee0e70b08c2c1e1e1ecd3a08a00dff95956d8331ca899d52bad944a58fb953d73c50c6573c9606e108e229977097b7a28fa738df9920a8d973bc89ce8132208032d853125415f80bc0c0427c3b528b701b7133a155de44bff86f1bca6b6505e77e794eed9ef9813afa4dd3364d1bd9efa88669d69d75374fcf388e0c8f259f07ca6454409583208727c7f32184b3eb39dba8fbf9a36f9c3d27b38da1a7032741a0dc21bd1a5d165ae3cbe81de5fddd1555a42f9168bbb440b114bed01fc11f1edcaf7ebde0a474dbde475435f46952cdf11c4da398843302853c881e0ed2c81b86a2287ab2bea2a73759cef4db89aa682bafa2994ca6d39c2bb65727eb2b0df526d4ab58961f26531248e2d7ac6a54994c2693c430fa18aa5137a6255c517a9a9a1634275b4e673fa7b605cdc9b66528f86d748073095b21e00d87c0130d60cf02f62f4008cb2794d68a42f90880d36082bde458f864d8bc936218c5300ceb995191694a3177de4219d4c347f9fcfcf8743aed788a068dcc44bd54db4261fa93c5a1a73fdd21a747455128e5bd397de8ef7e5a09c81606c261f4b9ccd3b089424e7edf9365d15ee56b5626cb22bff108bb488439ce07bef873db8fd3e9a5fd617ad41d827ad3a3547e65a250bf7265d09ca847cd29310dc3b0a9c95a6b0d854aefc3533396b0d9d2845044e33a338f15b9d9b5a5ef5efccee620b2d599bcd9f44e1d8c3ee69c62eef8e8999856695d8889e91909a475a1559b1312287626eb2b21f89853cc1df8e25e8f106e2bc411998500bce1bf39d13315c8fde2300c51c0fe130b7566d9cc32f70ce02b1f5d502a9f3494b1b139b139e7cc6ec0bd32d39f67b818753a9d4e31d278aafb3607b912f7bd3249cca5742a16d5ab156bb237a657e142dc6c8d00def09567799695cbe22a768200e2f037d91b1cf21401f65f22663e81fd6320fc504812a3f807760084155c99fa555e05b5a2b2b2b2b2f22a2a2a2b5b8fba6dcbd1525e74a97f9a66a46aefb2bf7ef65b4edc6e774797ab3b9a4669ad5ee84bcf9542a193852bac57293677259ba72b4f1268b4c4853c201a7fd6d4cb342738706ee0febcd96019703f8433d97cf82715b8c3f42b53cccaf4d905cf0b145f54a2e624be7c96d9952ad94b2cd42cce197b65b237374bfc4ae5978859997e65c53a00e2701c329c02b421432a60ff5805ecdf41fd656805ecef433c815ea02ccb0fd4abbc0aea6b561cca6e395b2bbe58961f2a5bce65e90fe24f96e587ca9f5ee56eadcbd28fba28d39b6e10f2c934019cb1d13062802acd27be3c0103ca4c00a0001523a7e02c9f40ed6727fbbcc19e3b530a7863da00bef86354f3a1720ab555f2891450a6610c7a730ace73c7c379ee74f76375be8f49e915d51bcc656363835dd457ff033c68f0440c9ca1df37e09da8924f9e44950ff9c4473e79c29a17fa88aa4969ad3ba1cfb4c61e367a07dcef3ce0fe0c8018ba9952ede63a6f8e11316f98eef95c8cae4f16ae5aba534aad52cea79c8c0e7a3db09b656b08126280e2032bd487ecdc813215b3fc30bdca9bbe66c57dd775fe23817a538c120b355b200803c17efbce1608c2dbdc19c2f263e54dbf723350b35279d3abfc54e2a9d0fb867dba78b0b3fc38fdcaafdc212b7ffa9a15a76225900c8a2f2c3f5824104babfc8a65f9c122832e4bbfca9d2c7d0be02b9557b9b20be87151b3e6aff96858a02875f2218fd5df9a93a8dae8e8662ad29ce4444a6be5b69c1e2b56a8b208ce9293d1750843d9227aaea042677d8a98386b3e3170cf9d39037863f2d0a03f7fef99a2612613354f195ddbf9270b57a6f89b0d225b10092fc0b1f1674f3dd6dc993b94665867226f88354cffb683e18c24b09a921bc00b8951257c4828283531397a2630840fe1a923fcf3b780058e504208188ad06b160aef33ef310b054e5d1521e22f39ee36fef99350befe0150be8e4628238b2223cac3d508c3324c06cb8a4bc86b89c162e12ab432b12cc3322c0bab18a8842cf5a551cf32a666460000009314002030100c8804c3219940d204df0714800e8a9e5870609c874910c39451c61843882102000020000048d30600ebc1bffc2a58b6beb5de4fbff001f38e9ea1f27abbf5ed7dcc07c92762ca0a3c3b876976ec061b5f744206bbf86a4ad4c1c279f1f85738f6cd2337cddf523f69d3d4c4e85367ef611e7a852061457136ebc2d19857ce717341b99a80edc6c3a9335b1ee51113ad881d4ba6dadb00c3591d1f078ba9b7441e233094865587bb1f26aa2a751a0be47b88d0604ace319bbd6c69425060d00c308be82e308c403fecc02b88a93913278c96f02300a8d5ee3902980f3a92bf91f4c3229e154c7925959d01cae6a9a73a7794137150a06b16a4b2022e16a8665c288a0ccce5cd7b99909685da5b19edcd11c1c67967fe869be2a0e21e7e70c0c86be89cd37b8c9f64727d1e22ba4e5ae7ecd00c2d62c155af8e4e99953e3668f7e715f6127f50f2a43c3d4ea648a9b759320d8fec8eacc293e2e5378ba99d6b9d0ab40ea36d5bd56d921286cc1891f80e2b0b206dc5772e6c0d3715a508b4e3901ced30f71ae208d90f3ff8ee8296f7dfd154c9116ba46216348a5b8bdaf3c69ae03e3a9ecb1947068619b421195c65c8fb5d5068f70a8c928dc3327bab065b517ed03caf701f5694d642fb4f771fbda3e726f83986a3efd1f0bfc9b4c559de9c67aa166a5596d6d5a75cbc283d13e81ebcc49d461b35ce3d0868d17d3c6d79a6f3e42fcdb8ea9d6c38d96b84e3a63b73dd33f1dda8f0eb3434f558668ddf1449962764bd31d62665357881d6c2b109bf9cd3b68d142b2bb44da2b98873c97e1cba2d5cb2df377973a34b7cddbeed2e97505ddbca51ccf99542bdfbdf6dcaa39012d51d8576a50af5cb01b340b6bddcc7465a3f1294548a8bd662dd5cf673344af32ab0e4277cd97b98a4981efb8ca4132424eaf6a84f4d1b995bad5ee4c90cce8d30324b23f1bef48297f0917156d48a654fd89c0522410f8a89d081a3edbb4c568e61a2efd0b620605f6b357b588937a2ba8b87754523ba0525be206ab6f65fdc1c334c066183c7612ed3ea103ad9748e0c08067d1b0d862cc9798db3bafa8c729ae2d03a0b4e14bba9641777c105bae87ffc5e2c0e5e10d490a30d35c4060a9d104785c6fffa138af523d6a3775045782efc98b8566b332c9071aaabe131205ca8932ac15f82245794053ba79779a1f8754eab4d30649aabf1a3e05111d8e69a76542c0542c2ecae53b8d2e947d25a78b755e74ed371bfed8ae0c8f561a082d11359f96d33cf9af3589ba4ffd64e2f34bffb50d0f185c664c87885bcc0a3ee501538d97054201d6b3f9446a06c2262899e90858638eb00c13f25a19382389bfbc43bdf9e466613edaf77fd7211071a3ce08362742f4107a783496c46e73c4e735faca51fdd0fb3fbfa482ed7061b92ffd151bb67ca925c4c0c5ef3f4df04c6ca094f7735281444c3537f357bfd033011764e9915c463486b690807d547ade4d25b69fc9aa71cd4cbde0631269583c6b139a72c7360196e817628f93b1a3d3df2e9572471d1284952411dd8293083c66aaea4d0c425779984ceab066d0136a5185908124a48cd80d848591f9189786a02de24be7575e664ab0f93d002ecde6d4f010a64c35d56223c24ebeaaea256e6d1b66a63fb8496f6b7b86c3927b54c10aaff847c36b023c86afbcb1eda8ae139edf0a78ba648cf1126920149b49817075521d749f4222b0cb5869212071c8e63f320ce14c75f78462e730a6008d369e8387016953e19803ee190ab9a92570c05a6d52b2e791914e9218cd80079217490de4129b805583cf24c2d260619cce0f3b6d65a06ef73a8024933be0299c4134ebdaccee3faee9877cc0ad291f9edcf2a9ccf0845a1a4aa0c42bae08d6f7d0c2be683f1126e4085e7c9eb711b8b551e2fdf06ddf0f5d15780c46079b4bbe090263482b4dc083598204234c459c6c9ae86901c4b8b981cf51db002cdab4911e2255673187c8b74542c688c2c6f344460b5d62c5ba818f064f687c9aaa44e2fc8cf2b71f9db5c00b488b584d0719aa78e82275ea427880a2bfeda110fcd192b4f579cafb18bd3836cdde72f5b94067d785ae9898cdc58a2139f373087cca96d3ddbaadc6620ccdcad3c4925dde6bd90936c76832fbd2a122c67b8c5c726645485d615121223042f2d1eba80773288dd594a1c5f34bfb155defac9558ad26a4abccb947005ed905e1b8d38085d42a352add230f36b9cd566bf2c308caee02a08871c00d3293dde0cfe6eac4f8bdc0704a99127b220768825d4c400a90c999e87f1aa00a746417a9bdd82db84d2e479f078b6bc9b742d8aa9d6aa36df74a83643be2064a1618ed37b800f11a71c43fb2fef2ae1b71d1917298fc5714668713b3a952516e35e1141c39f51ef4695889e925c334f5bd4120191574fc2e82ac11a60475b8da0cac9336193f12e4854eea71e095c3b2455dc8f22ed55b634b7c19c4ec17b56e3f4eacf3836971afa720e5028e08b13856836bc662bbf65896a668d35000ff8dd2afe427b1c330db4d8105b3070feb44d8c1016a1a7859b67f821717fe0c57dc6ce83335f47e3035713819a7f223aa43dc35a10b9315579f9559213c1fa5e32c93b947cfc8615e205a3baea7a6ada3ad1d3bc1c335363c30b0490862bd8cd4fb2990e92f09596bbcbfd17e0434708e635e83354ada18e5e954a29a2502fe74998905c9c9340136743ae4744bc7f70269a19ca9d1502d03ce0f813737726b6e32ff83e9a6667c7a05178ad32fc18f0ca9376a960f13f2b566c11445536f2854dcb49fe5c376e3d2b9a20732b2e1ce07bc8b265f725da389e0fa21e305fd660460cd6de6fb2197c03237da4b6f5ecbcf347796676af8b9442045663e6d94d1b395eff3bf4d59ad7fabfecac2675fb9522e0d8b3f7368ee69d881ccd1a935241362a8623779c19365ec8bbca673106de940b48bac5d678d1f6e85ec730b0f2ab894fc79080a372495675c6629294692c1187d356028dabf2f45e5b79ba944d195028b247357923b224f1e078f07d2817ac3f946a134f74158fabc2fb4780ff58a80b36693e05d9b3eff6f30dd32d11ecd47d964249117a0413c4c2c46d6bba7f8b1248252b2272420108636d46278d5693a8ddead0cf8e0607f5d4b757f16cef80d3220ce0ad34c7678025fcd3b11ff8a402d5d61630f21ec8144702b4bbc87977aae8d106a8f36cc974dca341f90f61cc70d335610599f0bff96a8619ef3dca0c23b9c0260a9f8527b04272ef21a82d8cdcad2b5890b83880427998b63d431044ae69269fdda5e19a4af5677dd06603f650e31995c2ef83a1f5e6f95c928a86c967363e97460dd324b6d0a554800e7c7bb3e5dae642d993ced7fdfa8e125fbfcc14a79273b734b224ac53f10451e385a266f20eee64d2cd1885071db1e93331ae5addfa9e6edc698def3d2ab0077e83197663385e1b4caaba103615bd404cc5560d365b05adc71eed72128a2b8012ad1b75b46b88071856d1be5964d24e11fde25834165c63d29e7fe542739cddf334fa76d99eebde24e3ae32582ab3b5e1d7ce0b97867ab43ae5c02c4ba819658dc0b45c07ca2a18d3983eb852c308aae3be51ce121bbd67928af065803b6c49b9d05d4b8fc360a421e9ed86eeff9cddc7666e3236d0462f19f7950c65cbb3919c233727fb8750c275f6e6d232c9d05f9645175cb41fd36eb417120dc457c609378e27dbf13e5536963a927e85973ed3649d1529144b9e069153e6fc17052abfa846f0142a742993b98bdcc70bca07a4af98f4847b411119819fc680a700f833d03dde7f5b86eb1bfa47e7ff0592f07f99ff168f32854c192033462eeeb46071ac2aa0c394dea14e1cf46349c1ab1344aa2c18c0f1aa0471f1396be05e3d4b8355681e53c26703d27509b963b66eb02ed72644163b073f8afefbd69418db8257d326b65a48b7822367ca633b7cde9e10d00237dac4fcca0cd58bd79abaae1c97ea20bbe17833e140be99e2839b0c844b04622175aeeb3a22b5ae51251d0c16171433dc8f93ffb9b053e45c449392e33327b155cef772e6211413d79679cb9047ef530676aecfaf7b0beeb60019f54d60789561850bc968321141cbd8ca133d81541c0ff9d1a8cf850f9fc167c8d206a946dcb328849c967245bcf35ed2e391898b9b19b3f6d84f50a907e16c16fa9b1fccce69309dcf3a1d5c3bc24794f818747c7037e21b5292d40d446279fa31cff0bcac34d583cdd4978e0b57a6b4b8beb359e9a5a71a0d38424e46a0b0a4685c8014b80b65454bc83187f94b471388ca189c7570040275176a03b558045f40dfc6d629e4de35568384196b7e9356fe05ffaf2fa062b0091fd8cd5805bb0ad4ced1326b8a9319719e3d8618b07575f508a2df6fd163865e0075b17005a3a3801ecf48b6996236db35c71bd1351be88437c15b861603b223954f271991bab0c7c0fc27a79f8e101625740f4d2d817bd2b193932ddaf66da606136d48180c0b3292739071157d168045722f91f84537a33d2fc057331af4e15700646b92bd2d0ed78d210d5c5cee0966efae50ba163d34c67a6bebdc2bad75157e35e202b019c834f1be80f388e2b0aee0ef1a6a20afd867937a2611b9b190e664b6f234ae25e283fa4a2b5b9ce29c83de3fd20ff19c0d5d10827b1ff3a8c099097800fb90cf2a7fb9a8ca23876b56b61e517bd5ab163672845b996474495ba0347d9b6a52e748d7735b0de22ac5953edba1ad1504627074392d99ea832a4781dbe54add2b391041de158fb50127a2cd8821811b63a0de000c626203c494e8bff26c8cf5dd72ca11ec87e077373ddb9db6ce4100c3a1966f00750356cd8403aa070ac565a6755e013097a53bd2ee5a4f9e2262edcfd3b87340f67e742bdf181daa84d256c4e9f94be06b447f7cc3e1cb05952269e2e022365e7e2289eece784f2c021fccd2de6730fd4538f982d9b66e9b8a216e80329c868d9742aecb981919be4038484bdb10bf31c08e996d9b4cf9e72a9dd752af537c9ac68a31db01409bdd66e961c3e18cce89e209291f584a9ea0301b05a17d993748eddb6330370dc5e6544e48f11793f5448743da8b832936acdcb9e704d24eb6c482e4925caffccc2353e1d7f40e36b51676f7571adff6c0ad1a24d3320cdf3e39c8809e18c679397bdb82bafd332a01b7e638d8f2ac37b41d37b6175c8bdad4e32df19931e9582e330ff2312caf1e8d2d8e83ad2753d9c67cd623e9b4d983ce22d9e14afe7f1e091770e42016f2cb486d2926c0434b52774c9c308e37fc401e87ab977306439e507c7602be21e822de5ea9fe155a779a4005b02b21dff94a497c0301266dc2af5405e2ef2bca875f09b428992131c483cbb271870c2403acbbdfd485a8d2e1e1af230f100972259f0bee50cdb4b080c7f6eb5d57ac2b8ef0492a45d986b069887f284ffba0084f42bef82840c0405196ccbc7778b0a0a05564fcc21e713b5d288edeec5e1b95246b8d3eed1ee242f4f15cd78746ed72acae1b1bb10d4e244cb5c1bb6b0a3b6f076d32719774ccb4b5807fc03c58e019c02eb8a3adf7aeb0660f7f41aac1c33765ee2f5580492683399ca22510f6ab778dba983ec35628ff4827805ef1569f128dd298d768f9eff3beae76f7c03a790fae2e426e968596f4e899f00384731297cd4f9a0adf19b0e9c84a77dd7e337939acf81bf7294f795dd9cce170c389dc517134d1d6ebe167874db9f5b6cebee297d344dcdea70d09db6687ca3675e5784b06f6c589bdcb52ec4e52fabc02d7cdf1b7718cd826b1b9ac8377f1de10b2c3c6824f8d0e0ec12eb3ca4c91c06d079e34c32a0fde740322880280c03e2e2ad89fe43c008a0b50baff2300ab9e1282679696c0762d7a805d537edecd510361fbe2abf5fe15041d948e1b224bb206193c22ba3f674de1ec8c218439db4a302ca63f0f2421fc96af4a160721f12f9dec66f0a8838d2c0e4fb8fccd716a553e6e479ce4fae54f72da8cfbb0421b393f05ba388a261834d7593d35ae8452f52b12fe248885ca89ee4abf142f3b8fa686e87534b64dc0e73e345072608bd9821b56df447c2a501366ff44c1cef5b448574f3409120165da52835a96484e280d5dc1f0c347e17cfba290f4caac99acae962c817c212801365a0218c77ae22eb99915174b85a93fe76a604b75c146bd1c734f568c160a504e9c092dfd44376ecd91f82290829b60de8156885122940d42873180f00590fc078c7a592a8dfd5b6a030fbee850408e32b6aafc763e92643a18cecb71c0361487fdbb3cee5e557d3264cbb4c7942416b7cf13b9e65f069d2494cddd78e26b47027acb1b213d2b199dc099a436b09992f72803d369902e135916f9b0513aeeb1f89b44f87a522bc0f049f110ce8e7d7c28a676100befe6bfe6c6e43b54a3d7224ffef27976f9706c5406f7e0e7d5e4a9630d5b96dd2160dd496ea8bdfe7e6d202bd1c379aae206d5f3cfe5b037d1454075ee281ebd5e5fdd0b4601b251640b34583d5322ea8c8a6a42a2c22d0889f35c0b492e336a2b76db75e06201b2c5273afa235bee3d7c4a82b1beaf8251b1ec9850e045464e880e5db467e435fe75a103a7d10b6e93e3b1ca60408c9d68137583300ef40d8f28076de13246d424422cd98c79845310f58d98347a8fd51cf0ccf16226754841e4c1f7f85a3a1845ccafb08cb9000fb34744897b1a5f0c195ba9236479daa570a2bf0bf95c37ab7ae889d4ac9a339ae55da8d16a9ab31f53d73df041c57b1db6fac7e90576adb039056b393044ac3a2443565ea5ffb8697c1695661440d0d42ebd7a2cf100e1121dd431c8bd520a7e21fd23346e609b4990817811dff8d0db9181f9997e0626e71b065153a1cbfbd09990bfdb22ae5b569a5f327ca99fc7603429cce5d0cb877b22cbdd0790be5e3182d03e929fac17e0e88fbd9495ebfb0616794c5e8546166861730974de4c5b2ec149106c699ae272d1943614d944f33268acfdd4db43b89a2e380c23bb8205dac3901d1c1f4513d054ab2710393c6c7197663177c125d32d3fb67a304dd50781ac1c707b5b5c95fff5f8ffcca5fce886112aac842e9918abd787ba919e3b85f3a80685d9f7927ed81a7b843cfd82ea570d75d496a351ef406ab1a9ce0fa706c27c4788738c66e3a0d6693e3f3087ba7f2d357a0632488bdf9e741fd0783ba9d7a8548e82777dd7af8a4fb156817b04adee0d0af2963588a4ebf4a456ea334891477887020ac0a5c61d3143bfac0bc4c2bc25c85bc7e98467cd96b4aeaa47ba8ab391b680ef9d114919eb40b396bc222199a688ef4d2d382fb6bc3e54836b358a1fe654227b4fc66baff89869a71e76780acb002d40754a332a74b436af5002b524c72650f35c8fe8c0ab0328d30f4ce57f861e8951f45fb73454ba885deb0cf2e7ed7065e036a44643c0c02c93bcc02e699a2fc339cbf0c9c438364a5d613d2ff42f57e61630b46a539dfb2027acf730b8a4d5e05ea8effc86c00823586e1a330681395f2d0dc58f2e82b032528c0024006937be79c59dc90785941df2472ce4eca4c5bf56b5af0f188818101ccdf0707744b7876a92361e79310eac8e7c3a330ad62a34c939401ab1844a42d1302011b215f0ddd622a6f7cce152636b690f9e0b15c97757bf9e993c1ef5bc759722cc061d525882ad0b89ad0c9bee75f3b43fe303cf03c1f90dc6fc9bfd7e4886901668afa57e5cae09543a19465b3b5b0f86f94972cabbc373866387fedec7f5a59e33ffc9661c100a10e1352e1445d2354c5ba2c829373efa44dab4c390c086d9db03c936090ab905a30147cb59206fcb0ce71f162b904121cb7446be71e962cee60eb635348119225d853b00a8a07fa2521890e52c8adc13cc10f23614aa5704a1abb9a27e4cfafec2247ea5099a15aa338d5934218773a8c7860a91cd3090cd3250bca35d3d1dafb0f724d765ee0c34d5f6c0a0deb1525cc0a0502324ecf771e6383c8fbaeb5ce36de077518caa7edf2146309771eccbb132542c3c95ac768f637c8c3fc69fd3c68ea6c1ccfdb2d583627209c2f700938e5adc3791ed233538a57017f594200355ef25aa45d3e640ba7622a9fb590efd4117142723b044298b27501930487604cd65086b0b3e8c25006fabd0976a5440e182b9d29239dc42768655e6c42774e2734620b9c3831926e80a526b2bd0dc869f020fe36472086fb9959267de86eca5ac10e00be9dea7ebecf3ad1e1640bf5cd46aed3ca0fc576ec5accba2c782c91a64493bcffd32fa8f995d6e9d6c1020ddaf2e940742228dc7587353b7ad7d6477c3829b087d6838de085791e4d8bc7126bbbf41daf4e577e39dff18afde477e8b628b03be4bd055423c7706f524b8f9ca5893115643b1c60e3f19ecc89593b6b71fa39a0ff093eaa6f49b063d7e9beb3f937ea60fb788e469397bfe1c13c4c87d5f5c948e6c79d8b2cf4599763283d8d10505ddb9a014807c32721d73f8da616859a46368468ee2ea3111085b77c81fee04d39517fc9c7bc10a03dc1852fbc64d17ed20baac48d0beb6638e7d6d5e2272e971c12c1399d64d7473f9be13346df710bd31d9ee1f0599d51cec7d7a23372b73f21adf67d70767b0016d7c42a6245f005cc476f6f9dda718b41a3f0c30bede907cde5621d8541be060df533b213532e2cd23d8faf2af8a54c56b0b4d9f5301db6b52f4c2ecf5811aba8de85f3b9a094c3b79f7de61300dbe4c9ad672cfffb8ff363a04c962f2aa30c37247bb92c9fc5b6f986911bd93011e4d4c15857b81d1c3791bec16468c121de9e536727d0ef3a074506381b0f66113621c98184728e8c2cd826aee2c1a96242c9883b224a4c884020ffd542d54d6388911f6f3883390453a931574e3c5257ee8177d1bcb387241152c9dac1ddfc91e50faff4cb56d68b602c5c5ea5782c11c670c1f6759227a118dcb183c81bb2d6a9581ce89114f8544d27ea099dee9d82c4a3e48ce4ebf523ca40f9deae0f9ca394d69121df4d667a73a907b0d7a74f78bce2034b862315ad58fbf76aef27c1c7ec6cd2360544b2534252670f0757655c8c0dae76f08fc1f8a33485f0eb5ff2471b678112914c11e0945c8c41ee72f2ef3f2a6881f82d8bbafe1f2a000976fc5954742bb1a4faaffaaa18052ed96ef59a74744eee1ed76d6b94dc6d69d4d7426ddc45d6cfd194567f8cd2e3199fcc993b7c6a3546eb2b2c5b60544e8d4fff006eecddf472434e01821bca23c97e394e7a0af096825076026aeba414734539ab579817847c8bcc8bd3b68e29fb8313fe092163656087ed129958c3914c84ad7f7ccf4942f1c23c39ce5e5f36810122ccb3f845a84126e84317b6e7fc7cdd6493c8bdbe3c33db1249b167fda72eb44e5103411391151a2be38a46ca1c4efa277dc5f46351a8cb975e1df1d16e4cc53720954365bd67b1445fe2e6cc6da22ca7d8177b08432ca68a014ca905ad9a2d0581c4a0ae4f5a33e98b8bb90a69145da75116037d6b0687df545c835e114a2335e0603c5b08346d3252ea8ed0cab629f69cbf17d7f6ca50fc126985f38efc84bd6595aae4671e82ad5c4da8e62299799da879047305fce007c2fcab504822f12ad9417cd62ef0d51e0bfd2fa1f2a5f1598c0c841829a411e45825801a40cc47a93acf29c501f7b65146c8083c2c1fbc68510a9f1790e479992ff0013d4cecd1f25c2f22257bc3b4e09f5e89a75c960fb2e57c97223d459b7c55aa31580d9eaaf71c685e226b734e2cae890d3dac39979abed6c6a251c5ec8b246e5bdba44c99a07d84e6cc02fbcb56925d43607910048864d37aff7befe246d4bf0e8214e77e20ae2a9630bef20ce33d08716a49238b3098393ac68194ae15984455e5855ae4b6c21e9485ee2d132b0d90c3dc9d23453518737a81f6c21912782bc0184869c3004992f6650c6e51d3bbb5465f5c69ac61c3bb352fa5184d1eaec8ba0605611108d9fd3ff74f7f2f4c96f2ea4511c986437c8169b0f0f33fe0354825f0203c7d269a5b54506588d2ed0a82bcb925f91f26f4f68784eeb5fba77f107032923a169c2a5ed94e2c94466c4aa089f66fe1132426fb0b36b05dad1204f94162887962160f8f740a94fdc176081b89c7c9dbe8ca539d045f46db0e2185b11db73b8b1f15aea84468e6ac17e1555ee7a8d6a933b43f432eaf74e955ffbb32bcc8f70b7af361013a39621cd38a4ce23d3ab3418520396195831d37c9ed27ba7cdd54c6fbf03d098f6fcbfd3609fdcab46756c1b6f86e0dace75560e6fec925de7cc3471f83a92711f2fbf90b35007e02501901e90c64bee4d3f49068d5b808e1014e712ff89808d3091789950df6f8f6256a2159cd63a0511dce07f025d140edb60f10181caaa933b1a5a873dae70d48284ebbd4244a42a67192a91595104625b90f55ee679eb42a489075fe7b9e22b93058308c92c1261f4b93f95a560e11c694b13298a7074c302a5d801dc7fb74492d7bdb1830970307c21fcc410a5df6382dfca2615a01802d98bd5ded726c2961953cedf7e99edbf51bb8eddb562bf82c382010b496ebcf241cb6a30f909497db310bd1147214e33fcf2b1e5f99ea15e0aaae790f33ce00521ab25971ef7d9754cf784dea33e2c40c8fe754894848eb2423ac8f01c81a0cf6bce7938cb2d8ec10c8b588a19d850f7893036c82c2d9a8f12f2b7962d6f46bbb8780403cdfbf5de38366fbac4ea3634af0a440778c896543ec6aafa8265b874f5737a44d6595b1e08bf67b79afe1ab6b9e98584baf10394991cc8802b45f9a5acb394b3a64b1e34325bd45960dce2216215ddc8f8827303bbb4bebd6256817dd8111013bc4cb5c51bb09f83d18890317d594350754a0d1934f922b90a4a95542ac75ead5e0261f62811d86cd27e34190a11c3bfa90b2ab9bf16e961146a15b04eab44de9aa74d80ecacc345ee09e00dbebceca084750111b34508faac4c70810d3641c998574643a477e25c428ebc4a0ba925279414a43bf64a30ac76ceaa0eb41127acbf207b594a9807e4ca0055c8bfa8b350d9789efab4c2629f16d1189c65c106bfb438377a0620ea505806b346267fb0ce0d46ca3b5818c7511f1f0e56d74d6599e18b3b61c463991c3e8326398ace1054166e45be1d5bc873cea2e60e7fa5c92642b34d6c26a31f8ac67273bfd06323da9d45835b5b488e81c9ee2df626413917c33962ba51a0c55952cd7336b6606ea120b17ce92c26c601b90d5a062676028c27f491d3264391a92e491d934c141ee5b7a4c4fda362337fd13e72e9652c6ca7e94b7c00ba218349b34d91faa338bab9f03ccf139f3ec7307106ddc6194e93304e39de645a3d2737b8767d10aa997144243b8f8f3559643ab24f7ae69a52022c9df14bd6df2a65b0a66e9f2400cb4acf1ff56702a8d526416c86abb9905e53b9c4fe01a4532da9b5da958a60ba081a9f68cd3593ff137a98182c55fd87860d5e62998808a46c7bf0386b18e970e4d8215985856240c730d6336fe38a9b02b71265a7355b6a0d3ccb99068900fd8108f0329b9fa9473e8cee5fb443d93ac14a1d218bc29555a419ab0e03e1dd1333dfa77023d8deae330cfbac77c6f21bfd460c609e8cc1a04803f6666b6031587ccb460c7077d5f0261b1559493cf47567c6ca6e9ad653443f8ca1fed94f3f543d66945fba7e0703447092f8128c7faa493f03bbea94ee3e05b084e18058876e5d00818e61839616e10c3a6d2a320a74a7c571cffea8357893faba439d6ee89eb0a100eb674acae8d6b6ee41298636dc0521353a9e1eab9ff7070bad20a628cf3d3275905d44c365b20d27dbb938a6728b989da9b3e19a6b2d077c41e794761df07dd5b6358918949ef33d28b125078a0f5e478cfad03a44d9b39123c6987925f896e6829fd892c9942bf13e18f281a1bf60ff37ca6894306448cdc6c0ec3317b53f547417faf84c69b6392f88f3b759be36790c39bd9e17ebff66ed2b15b6e1101c3200961abc3cd7089dbcde0b5265f193d1395442986c1f0f6d0b747fd7414b2e5753c87d2990fd315aae02a9a3125c0eb86d038aeb05f4d46a08df3d8ebbd8a2564091ea44422369e68a377cfd7d585230c9241b9898388c0be90fb21ea1bf790c2477bbfde5d61a5caffd60d9ef7aa187f13dde302e8ec5d4c027130974b0e456ea204017262b94a6141791aa54db5649ba60e16583fc99ffa0afe532a81afc088415f52a18b7055fa4d24246942806c095794133641880cee6092f49083983fde4b6ff9f6b2086c6d5f8ff79aaaa7e559b73ae2157244e6bf8b017a892c60a90c077aa7f66aaad244d6c99fbdccb9526f37fdce0ce6d4ce1fd198491c00366be12eff5fcf3271fc190669fac944e90b011d723398415b95187dec15cb0657fe1916433394a0dae13d723c1ae1db662be2d7083c515cb037da3b563b2ce1725462b47848fc711ff267eb5e5adefc405909a09e9fd266cbe3de9b507840e9380eb796dc5ba17ff086cbcd01bc57d460cc505e144c01367043c1e246e6603dc732efbf0f03735a8ee73d04161de7eeb7b236df92d8f58ba9229849f61b876d987556645d55355c255bead36630ac554584d2208ed058a1999d741d57953dda14abd1a8cf5b959e3d2c520f002f1e7dc56d05e3977e054ea7912593e444a7b19ab595db88fd029f8faf32ce8cac2801ac21e091744acd0ea1c1cff2ab313676e75e9ece4de61a04f9e284ecc3ff3251f4305dccecc28fcfca3fbaadf6a25a0be62297d3c849b2125ac848f119279c00c7fbc71fd412459fd915640b74181cb24dfa988569b4cf8828e03adb22bff5951e0c98b23a5d83ec1f202b9ab4b67695dd07d158e00ba89ea4e0932dd03dae01f06e8e31383f529a382efd74dfc1543bb0612a443ddfdfaad89a03d100507274f17b319d08734e0fc536e79e6cdc177739e67a1a8ad43a0356d6485b3f24b82a8b2ed79bd3d45f3a3fe55abf1360a1c591f685f76dc47d2dffdcdc8438f800f39b1fbfbe5c4fc7c015d79ecd10a112dcd0f7277d22f0ad51d342716ee5b6d378fcfbe6e8e4e407469d641bddd436693650a2b2585308b144f2f3fc552b9a65fd9e7f93aa07a9e9670b4516f7926883a0a94843ce77633a3cc20c2ca8763a1a21f20a3976395a9dd6eaa0436e30cab978f938a08c65415c86703a908afd13e3918532756e2d03028ba4b241fa3923e7b91d2d1c4c7d432cd671b6bbe5bb9d3b7c44ddf11c5fd791f69588ac636dca2379e2701cc42554d41bd0196798c01ed12ac0471bc7e3bedaf610bff06126ebfb7865ce853a8f77e80e34063009afdc6350198b7eb6d9f9ec59930e8020d0a9973e1315b5f6989977bfd6ffc986545e8b68e1a5174ee4e095d8f2b610b95d012de4ebbbe1b1e07de038f24849b59add95cb77fda1950b75c0211f6a6a26b3fd168dd0dea8910b704c406011e4d1b009b0c306438da074d3908a2c20a8ae02008db9d28745a75edaf571ffc9998ec3406c5653da21c67388d64c722c978fe0ecac422b99d9d1dd8fba9a4acc9de4dd94b76cc4de729da281081a6192497ddd2269e1b40f05d95eb3949149dfd95408c1fa76eb959229e55b9064db877afaaa1978bcdb4ce632804f09d39d468e6a9725e6b566fbc3952042ebc934eaaf246551c72ea94a0321def975eee3a1604719e1a28a193629e6af050f76daa2d15decf0eddaa036ec7ea71cbab1edf7946962cb40004046994bfe7ce3883c36047dbeb1c51b6985254418530fc3795cdbc2c0a05b28943a28a5ab2711721ff78771b073229379cbad06cf01b28d82a79397035e8e1ca09e8043eaa2c27d09f463f5f633752e3318e47e8b5e9289221248083bb20964f90b13f217b897d6663016882b2a82310520cafdedbd544812c498375d73f1d295d5c57f963d33941ed74ef61d4c6bd72db9a968dc9d8996e0f20c66859bf411ecc4cae07d32222597e0137625b43be3158019d0698c5610a4dc28c375b376218dd48d6873dddc2b4a2fdb57de33e6c9f163b3c76ba7cac5aa9768a91331d9b3cb6ac49da02e2f9910d413a945f6d24dcede6f9f7ccf4db6fc7343b3f806e4e8acedbd2a29e845cde1ffd8913e85c7a4de274400a1dd0a1c11b2511b01e9c86b9b002abf2cbbb35412dc5001e18f9fd63e0587a33474c83d26f19eef6271c15372ad740edb327e3c869efe80477dc8ba4b1c1574f122f0b0284d9f8b6223a4c4ea924b48d4592149665195225d97e9d3b43687c409302ee04ee12b936102f791a34b3e05e94f624ac800bd0b1dbf4808149edddd842c721de73b625c7e85deafa17db98f649577dbeea16301622c4d9183e02b1925201affa1f951407beebe1974dfb4811b65e6a5509c9de1574712e8a25ba8e9f8c3a27c9bf91190ba3941af9d210aca62ce312218528bd86bd6a5bbd5dca154a8147492257c92f0361b571cfdcf9dcf30b1456473fc5be7d734d7956b01c38d41f64654bedaa3e4c265c3bcad144446cbcaa0836c122f06ab36249246891ae7723d235997a0f4937a2b86dc803b13a62914915cec411d165ccd2f2c94ac95494543c761619ed04205534a0d996b48f822c56e2597443c373c348b8bb0e40785d724c2600f0bbb6580a9ea0ed0174dc1c75ec26a9ce415e7830c1bfdb8138289cce0446ce6efe2c7a907fc22dfd45b12961648cf187977c6e1292d13218ce949f80e23163a6b9d20382edd10e6c22f159857c0951504def0832bb209088178d12980f0ab79a4c620522f19d074d3a28c302329c7843fba85180d572be22a2aa402560c53b7d67e199c567083e3c8589ee249eab30028cffa2ada9f5157f70e79b23b104e130d84b55cb97d09813c39c35d0ab0626d5a27cd4d0cd8c63c21a4aadaa31183d43e40f35f02dc05905da67ca77a151b2852f5d96c0084198555066589f1d48eed4fffa96e5b6fe150c0567df1ec45bf4fc550847c8400e704cc4a0cc52e8f8d366df80498a1ccb7d6ffb9ab56b049ab2650188c7cdcee278041d62395ca05068d153bbebc7d6f467bc7cc0ca14a485c3c46bbc005a8513d2ccbfc33821f66479796bd20949ffe4ed7aa0812b73d324a19da4764e1ec87d28dd362bf292072b3282b24642043f5f50a3cc2e063f310679ea95b940d020df379358562c81fe4709fa312af062815f5a6928322c5d4f4725e6a4010e0adda5145f7b91e34aa7302450535a2ad5ac5ce7c5da56e2598bea850fb53b38c88b9dee98eacc733c833d431d471a54351b658bbd9c470b9a2a4d13555cc570453f75a5d77c2056bbd56b9f4ec957401d52be0d2f7f997fce53e6736272c0be6d6c56c72aa4a63d45921d63e00ec8bc6d97c68dab89c19e8f09953c7223bd9a3a032df364893d4bce2a8ee8c11915e811a09625e9a1a040e5bcbd69f243515ec2da73b006b5dcd2bc783b7d39ce5be8b97e21dde42d0603b9f85f18d3f416e19149fd86bdd76e49129a640ad46e4de2b4db727120e933a3ae4a8684138977e280da7b5691ddbe07ddde1823e091ed2b7141aa9ff0eb212cb51f8e3d32a5ae8598327ff9cae4510c7574bd48a4ecbd7aa9c34fb01af02e99065efe6942b9866d012330e39f76052c0db8f76867b6b672fb35bfb74bc9a82e76ec8b4986f08fde78ff808b1d46f68cb35a8b231567b027e1323841d5d4df5a7c62080a9575ac82ac7d79e59f428dd066292d30a37130a45ee7e5ee0299ff6c24b261dac55a724071771c9b076c2468e2237506320a0343280e16c71d5aa38b0a204e1c20099d8f04adf2bcbc0d53a3cad94b2f048bb3a5b35815201d8f4ce5d889628276d51317ce1dc35b3988fc3e4c48957bf161cc7375cc8936dc0bc90b235a0a14c734ed298c984e70b28dc9ab7e43b2e7a02601921db375a63c3b7c70a9a25230840628bb29a58a1975acd776c7545a49751038c76e20eea82ad30a488dfbda2b6d6dcdced79c9c3b902af0fd4a6c62c461ea7824fb1df296edbb37491785aa8709eabe101c58d7a5ff9d1779e67ad07997cb2493cb3bc798e3a981337c1da2e9a75eeca2b8e029a3ac96197097b04c765717d6227a8d8846fc44f4a9d404736d278d18a59f39102be2462c02c208bb809d177a79e4e03a453055955d8e73d2f3cb7fa98e6a0035c028b86b52c5bfdcaeed0950f8028e85079858a65d3c608c9689ddd8b6cb8dfb4cbe2e0029b5fbfdd9989efc20e8031ece53d7e4c8e193dfd138705a1e41579742cb9d8f8e4deb912ce072d9c15c8a4746510aa947b98e1de27f8c14eefedf9c39a06a468fb51fab5edc0d4be619cbe7a914a2123ac2936f98d27f3a11024ea16065ec97f4ea2139ce5b5f09b482b8c0c315ccfaf3a5873e8a1e9a152449e804b7ffd67be187e198e5475ec1cf94a0986a2442714bca6e9c948da16a929db9eaf2f2dcf9eddd4a917ba84b3251e35a4d4fb22565e589f9737fe91408e17acde8a5c68c8fc50e433ec0aad3104e500070a0f313134413ae28c000640fe462fafb6350249add7c374fd162b7bd02b95883ba540b541aad20858550b2cfaa1c6d48758002a2057516e4188a6416a1e8cdc1744a3d88d544a2a8a96a1e50092a95e353aa7b44d5847affc4f26e39a8760de165b800451ff2a6ad9494db3fed5c0f6d4fe2101be7fd1ed25b39d1cbddaa5fa88b13b7eb8ff35125b1de521ad17df0a5787a6e2ff381ff416d05a394c43edc881a777445fc0ea07f7d54d30df45199326022ee4c14b8039592d355547200fda69cf5a716d45cda625d2d1491446f2f1d87408898be0c7d55a5c0b06b107acbb803f58a21d77b6858de80dc0c996cd065054ab604d03ca2ab761b256f07cfb5d664c294ce56798ccea2893f0aaae629867ebc2c809951d1403bc31d509a5a8a054626f54634216a816f478684dac9c6fd3a572b029017e07440bef38ad032399bcc19402e22599133890c953b65798510428e0452eaa8093feb37693a2e706ce6025fa60bfc3ccc4622510bafb8e516d18272c211bf66e13eff8995138d6aeacb42ae5a2c8e796c1464e94bc8b5b1c78465de8a97e86e541686a0a040c4a62128c590bb6f70ac3a9395e49ddeb94838aef75933f9ab676d28c62015bbcbd7a46b5845026fcdf7a0bef960d4d585caced69a10285d03926e455c3bae4a2e791057c7ca22f4f29845bdb8d9c739354b37c05caa3d082e964e7e00d81dc3dc070a5cf6f4756a8881057c227cab1162be4b3e66e8ef94e71fc92c5077c4896f7006112c1bed5dafd8a81d6171da9e84f698c38155f3960a81aed1c449bec1f1eeca6ae8633215942c8e1db9496a8bcf64eda868de8c726b817168dfac3fb689edd87510e4df2aaf42339901f49b04dfc68d7d496025f695d56ff0d82e6d36928a27e3215ab9af12616ca74fa41997afc1dc6167a95b08da2395112da6ebfcdd8137038a59054c04f9bf39fb6d1db66bd4901e7ab433c5a4b75361ea94c2aafa3fb0bc136b5d246b089945d59e779a5145e70d19e3ad1bff50f627993432bbbc3cb5a89e8c30c1477108fbd5cb916b3c68857b987f7f273ee170617e0cb6cf685a69e41bc55a82707ba67040a32e112a5f2548ed36e130b90e57b51eab0d70b9870e3535279f59b30b84ed9dc18c5c315a5555e7e0787e68a84feeab6f792016a7dc0dbf6572873231db26854892875272a0bc9c1d443f3c216ad411160a8034e50657f5e4f355d7b35fb5915f1c4414a42a6639715c881bdecd3b706f5495ad3a61f273cf451ae83452c86bfa708e109f0f539642f7d36876317b7a7bc6ddf913b0b62f120fdd349bc3331450e2e7a8854bd1d696b9547899de1ed896cb552773d69b649ec773c08d4548fc3450ce91b5e2103f326e47c8a6895cdd50017c5d03ce79ee3e2fffc49e38be0f2fad2d1350c031bf903e0930cf8900c02ab9cfa404351d2f5bb8a6e8fa2aed0d9dc21d7c1376088317c4493391593767de5e174b87919d043a0fa8df770957cebb8fd0872164376ba2b7801e9a04b6373435ff73088dfa0d95959e2f8a91d832b6e5751e5af9804a63c99a755ae8a8f13bd544883afe6ff8a6059eab3e9df1733169d72dd771e078d434d86876d1bef50ca8b1858b379755fa0e30cedcffbfd2ae0a820f7014e7bdf379d046beecdf0efaea1e0aa9aa9acde0b447c17a31e728f7050673acc81d66edd58f3f800814c9c160ade5b85b10a72ff36f0577d95502f666881fe80b28218405a84bd8d8fcef5ec2ed534c97beeef547212095e92403a8f2596b07d574425008491122f908f8e02dfade2eed74457d298e4e4164a50ad4ffb136cdba23ec20b16e36077460303b35fdddb568680d94ac81845e03119843cbaf20e782d3a18bc9dce30860b1cd3099b099a393c86589f4304ae010ef1c9c894cb39a11ebe9c8367265f287ce186e1ec56e05fcb6070441c61006b6a9773ee5490809768690844da661a39dee3b06d41e42c21d220e5394c6ef172607082465eab1cdf10f27c31accd55db2fb040a3732894b51b920c09955f6a94167af07493f23e7ef958108d0c056e1e4b093b5a955f747cc4eaf95ed0939b1ea1c1168dbcf85e0e8ad4a53cc89f968f514f1030585863f634ff90c4123e8de3d097d0ef6fe99853c3007244a46470a9fab319b82cbb047c97b288182053dc31d82a03d25cc06c4e107da0b8037b04f47819e6b147f41c55ef5b2e1787344b91cf0bf538b4f73809e8905b3a5f7d755db4c4cc30775d4cc67e37c69e5322a306f9fadbc15e5d975aca91147fbb56698591f9395e4697b4e0f1fdbe0ee3c956b6215ec7e38cf21cfbf541553df90005eaa03c3d37fab097ac8e56f04ab6cba02c5b9d51e9bc26cc22bd3be1c090e7e0f83fe04e95ab40694172ccdcc862da8eb023e5de5a714b8d7aaf68e3ad15a41e2ff125642d649012d3b79a093c63fc592feea1866ef057f123b0a07f60ee17c18f48a3bf7cfd272338da83efda4554c298aebb5f73856fde7d509440e97d2cbb4406fa1e7c82a8d66a6eab673bdad47ef3e3d37b956e9e08b89027d6f18708b7d8b1b49cdfcc08f64893a8438613c8c862a0e7e77d2202e0059dd6f50fbf757c97a9341e86fcea2d8316f204efe17a108cb7a632e057f94e9dd5876f351534438cd4741266e33181b859c1242f2205eaed00a7d91e41b467211d0ea2440e4e1867a7815b11aba2f6322c26f410cb05951c534e8eef2ee2a3ffbcf6d7114fb3b141a7b62a0cc569fea895f02dac39f14ecff27e2d165d372b9119af9785c5b391ee819dae67167b40ee9e6b1e8bd7a53dd2268fbc40e9f97877e9b54ea46406b9c53a6a6c228ff8bd40f63bb41941affcaf4da6e77eb7d4bc5b2e2f08a4b804c5c2c4e5cd5b8f8d276021703ce976a94f9a1619b40f6ed4f16266d73d5446b029363642a54fdf4d535d1f48aaeb6002ed56a52c1973ee83eea7fd15a18b61b8652f457b9dea86f430f21eca82259a3aa0c29aac75c11dfcd221fb714cba74769af9a2b36c3c6699d5bf2bc0986c0e1dafe235e1793c56ce97d1b730908e9b6405a4b51d111c4be33bc3d023b066a6ca5c889e4a99fd1ebfc878a55ff5a1e4258e86dc18ca4e7f34c213ea9dc19f07a68cff2418ce0e6193ab3c6b6d236d4ff89e8c2b4dc2096babf4a7a51fd4818ade416e7b6c3314a3d5eb5364d65224ac4148f8c7bad6648952a23ff4574c2b6dd104b997f25e99929043e573991eee975e8dd83c24e6845b49a9c317e1eda7d9de88382dc4522cc9e5738e1e347011b31bec51ffd9818518d55567ae552d57f75d6ecce8458a0174f3f2e8182a8e97851f2df97cb32862a512295f6415a1cad53706c7a4c06b9f10d2f56c8bdd859ed20d08a7ac65d51f87268cf333556154cdf0fcd0f35ef6cf9d335ebba36c930d6f2ae19f0e140b374b413f9a9f3a245e81f464417f343c4741edf0abd9715657f1df1d5488bdff34d4ad0179616c1121b359268bc50921a6dc378815b49db92b0480894d44a71f10f0bc8c9f8fd0d824635dee30657537eb37f0da4d4fe698deadb1032419aa2afba01fbb47cd2f851c9f6b20ff884b439f02850bf880e0e6676c46c97e413511be49b441010c860e2d261e462f5d3e4223b614b7590e29de598d05563c3febf7aecb1d6c2113ae20c2e72c93141ede11105382929e32ab752065527bb29e8d26487025bb4ecf2521db6cfa2e4a23f9632aebb1bf2296862b4b62bfa7493ac3e10c8e3529a0060b99f76565b0307dd612c85b99c1fe866795fff8bd4198062cbd3f5c14352b92717e19de10bfd5d5dc41f035a96693d98aefa0019f2748349962d36f5214df685fda61d1803c81b3df929fddbfaa6ce17c00cf857bcff075e183a67e6c696a85b7c0b56a2764f023b67a191c2ff13912b06a3d7eff6e4ac1bb82c40220c32e5cdc933cf3fe9897e672e4c5906ea681c6fd260bb84fc51e5f426e44f9caafe370c9f067407963e25f1e8987bb430992205965bede8bb2239d1240d912045c2205e46aa580dbb32c9f1ab90a1e79cceb4bffe7fb59fb3396cd53458c71ebf6616283fa53f0fb527cfbe47cc649f0cd233fbce2ce47f5ed7350a522753f09e550e3006c022055f00fb3e51f0ce37d7636dda4cc58b2c48da8c9eac2c43aa3a53fe83824569095052ef5fa92c69950678450d51bafeff6dc02eb9434040f11845759fda250e614ad38874c7bb5a9fc410b9a559e1afd12ef6083a9018343ac4f8d8624c261cb85472108e89bfaa72a4229d063c6415bc1f2c2f7b0c7525afae470026af12e0b0f6050d8d33b1be62cea614db0671e838f9885b79e253004f506e02d704a7f3d0a22e340e4d8f428f4fe65e9bc49ade6e3142275609de0e34da7070cb56764f7beccc4c1e52b4557f248a7c407fd068345d9e397d77a758bf8955a6423d20409303e5b077d28ff8dc7a95003be4550c225f5002e6f79be10bb07d817839700a02190831d8c56f81fe7504fb57d9fdd110e11c5689e6888e410532799d8dcb506b3a91abf54dc0a3a3f5e14581e282f747566cef6aec8329feb49bd1a0a6131884994cedfd24ba436f7d78bf6541ed3d2b2327b14609d9e2b21b389352d6275030906d5137f860f415d845546a1943b7d26e5866f1f767976438d6d640f7cf7665b7fe524eb60dad4f33ba35735c9a3ea03fb76ade74e2eb6ea4d447e38044c40247ad371155d3348bc7b786bf1a740608815f82e28fdef116a820431392ccfc90e3fb12df861764fad4bee36c02e7f0d4ae13dd936655670199820ea081ca65dec8f6469489403167c8bcc325d39ba43ca2e94acdb1ab797cb0b0e6d151b2b20029d9347979d2c7405748c6dad25b868b31350749ae0138e7746310247790fdc087c494f86f0c99edbf11679080cdb9b818e28e59eeb44cb104d4b8158a2c35d9e752955fbc9044ce0be223f5c2ff3742a27914ba971664b5deaaca8343181fb59329d969f18e3cbd9bc2e614d3264f4506e54e8a3f5b3de768d2001b7519d6d12c0578f47ccde52cf936f2a49b13000fe9c345e68cbb54d400f1abe1ded57b3fb43db874fce9cc319104af2a8d6c8a911b18e35c80acb8033c9459e378d3c77147e9ba29a64a39ea5d66f400ff509b4de27b6e8979e7a6db29dc7147baefe9870e11d61a53f664742099896bc8a79a2119312d798fecdf2dc096bc583bf5861c7ba2f40e029eb203f3421154235d8411d73897db444b9cac89925da14f9419be21ef177d7a39027eeb53387cbb1f742f66f7ce7ed83b43f923655ccad97a38273c0f3fd7a781cb0aa0f3aaf158e56072840fed5099520a9e1ec9100b477cbc10fb670a8260b00e4de65f3982481dcaa388981dbab53feb18372271891d425a89bcfed081fe5c9ba11dc2e44a8cca1dd2a525cfce0a3c54adb959138208f1775c9d7ed334c8e2c46b2b19278c0fbfe70dca612e01a374d17b3b7343c96f5a6ca85af6028a44b280dab099c50c946151f0398ea434fcc5013f2912281bbacbb09c181ea1a6c54cd4f8288f26d052b8f333d0268b013f42130353aaf24cec017b0f2aab8ce2806bb8a416f202237419be5cea9fb64aa510c835b276d1afc96fc3e50cb17748e5a5824d34c49bed864f6838caf1fc7c5ef22771660c68abea259205f35b264f67d8258ed34dcc5521e741143067d957f76a6b4529dc3513108692a1c9d3b01b1a81fc2673aa70518dc2a90ae27d602de4e8f0b48a7fd03d400e78ff59b10d8d954b771e65d8ebb9aee332e8fca88cb585dec330adae2c8b16809d7c09856ef7d9c1c64a40ad386d7bb7dd916c964b5803c5d4aea99934b7334de5fbd82ac76c95b0623e2892b0352268fe1764d863cd9261247372f65736ca0bccb3f6b6886bb8c92eb3fa412fc14a0de192b8150585910c1f80fa7d1acc1b9e011ca0e26746e53b61b9dac0f75e812817d8e64192405ab9cf65780bdb10df7e9b1533848ac2faaf45edf4b11ce294bb0a339536ea94959b15ba770ee8ce1d99c043fee60dc0090ed19089bbda769230f3e6427868ec382a77f6a9c22fe3c72e7dd331ed9d7c7bc3774dfb7dd12d376823f8d385fe5e29a50920e1686e30c2a357dcd38003593eca2e386fd764f7ab6421a67ec3361cc5d78aafd325af5f1ce2e484a463d4f0fac79c40dff16674d15b7b4ab8fc4961a2ab8bf1b164a3b5e779f401f88782f894688e5c2b48d6d5d9212ab0ce41727996b38ddc24bbd3ca53b7d54a7a745dba41f81c5a06fb12fcb034315f608ce7f9f3e1339cf209f9206af5f7213dfb9920ea90eef5eb353f4d180282c5a31ce62e6fd71d2124e8db5da7d18e983f7a3d773804803c9bcac1251199cd030cf99df47fd14f3039252d44a853e882853ee7a4c108728fe37ffc2a1dec81e0e45f3be6a21988cdaf4f334dbec05454c360cec1859411baead502cc8920b80b9252b42a977dd2c229392410efaa3febbbc4c9a572e1214e2406dd74259be119529f2b42b037fc04907f6f195a9fa568123c349865a22b27964a6d655c164fb743d14109ac17751834e09764a55fe75a4a6df87c56e4ca197e81ff180e83f20fcdd91a98252f07176636a4ca654b0668b190e3ce8b0a13610b10b7c10c8ed611cd023f6f0b1cbee763d4802c6c6415713b3533bb15cdc1c6da0878caab997c48e61029f519a162d0d40be9b530fc47075f373e67a85e0c94cdb4f1fc13d045ebff98864b4d9d5ab24d620983726368289e2516c5a24688f7dea9d7f62650cd54cf2ba4069685cd16e841da2538eaeb69bbc4d10f77dc1ea2b1c3ac23e69578e6ccccfc5f7e2186a19b7d134a7a5c7786d6351afe2ec5c4fa1bcfc54f0832ba0a1b7fb90c12f2501376016f83592f5ef1c1b17ffbd937da90de252344e0cf8fe71412df0ff23b38f79c7cc4e01d16933fc30eefd3108aed80343c67bcbe33b035991a0d54054ca698267045933e98a2ec89c1445ffe26d01dec451273594092be92fd4a8d85d6b5f846a3b688e89c1dc46427c912105874bac15ee2ac7a2fff81768c3eb037e67bb5f905e92cfe43b25e54dc32cf46dd98053b8d3320fcc18a369a0ca0949d2e5a9702a2456d29fc0a6258350dd6cc35f8878da8fb2fa7c2a1d77c8ad0ef9858d6f8673084faf779c64a073ba83014f88e054e0002ede4bd076bd3575642f9428d4802046e1c0ad28d8e55abc36f3d5115d71d9326a95662b924f39731d3f13ed5ddf8d602e1263f7b499566e49c08a1fcc07247b432655aeaa861bc624d924c5d4dcd3a37a0e2cd041d17dac9f4135aaa6c25094512a4f1ed679f17fbdedfcf779b1294500f50c4d65b866188d3207d7d06d628b17676432173643046a9e040bc43f45f0081ee0e46db36a241901133b680cda355a40b738e6598ef474ac05488990ab6c9181a006587a093798ac3507082e00b34ec221c47ea4da44c8d8e445a14cca13e254d89e24f78d16499e97ce2dcc04520649e49eb06a34259a9719fdc086a9ef7513bac312e57d881c5630db2cef157eaf79d040489660de72f8ebd68be570d351895ff492efb8085dd1d7737d49c85609fd28b6a1774f234a833351186c18e5d0b5fa6a11f9623230b352d4aa4eb8163bf8125a6cb90e92b642ec3710e6261ae002c3e9023db4c3ad36e9bc8cd295895a3ab21e9ac89a43f626cc5dd05ac795619f349c5b7cd3009f861c76492d88c6b7cd8ff585bfd176d86fea97e7487e592d9eb1925e43005be804c3352a06d9b70528872456b6f69f7865338e4a62ab72ba4a5e38526c2c2a5d62e3e2964adf0e7b0c393b211794dcadf277eb939b7e1d3373a6d6b6768e51878fbcbb9bd4a8a1c31d96933975fd84728f9a630418c0bcb40173057daff9ff65b84e16911cfac16915e79e8e262de140a12d0334e860202ed246e80ec3a08e7003ef59289fff1ba1e2a22a0a38bc623cd8dafb4c63ce0bfad6b25dac4d52384ddf320a26ad06d807e75dc082ca35b369f86b6024d43651b6bce6edf2458c13ab1f0c7561f4990fe977a294123e63018a93a6af83b4af6a18b251553f397d0423ddd9667ad795e6ec2a111c1d9e9488dd86ccf8e3fbf8dd35b082413f8f1c994be2b3921ecf94307ad174b3f115f37b2011a2025b8bb265e903c213ea0142027796e969b1b3b71f7f60b70f52378cf77419da08f5a5208a7f0f689ff5d288182c61b3f235216d260420777f23f76ad051927e5e81c1e27599383f18c24a0fdcb33909a43d1b384b2054d3c20cad80e46834b766cb783bdd8ec96b995b18e0e0be1033f9f3057fae028735192321f6fe0bf60d8a519c37e0e4f502e3c4bd99b9b6e5d5615579a3d8e45a6ceeb3fac130a5e293c7d19034117f71608f47bf5e9c870bc96e49ec3307489233bd27e1c129bf706b771290895de86e405c1b77006df42acdc70abd41c26796b5192d0fa93259410af0adc9c2295c3a1c3ca1183a3a03cac4660edecf52492251de069cfbdc632f6775904a4bd273ced34dcb4ee80699daf3c1d3659ef64abbfdf24f7000ff0de3c3b1607ccd7b052f6e61002c43b5c8917b259ee71d45b8313ec45d0fde79c9de07efc31d97128a2bd80647e6839d636b2f7e7619586203c427a909108c7e41607b655d89743346d3d23b77e446dabe200f1c5ba545a5a72196713d87add155806d89a7473943e8f7370cb923d6dc3ea1f6046b1e1b1abcc702af6a1408ea15e45dca34f47ea7e98a44af1b8fec3deb0ca89e2079002d97c0fcbf61cea46ea1202e390311aac148194681b23a40eeaaa1354a34fd5caed2389d0759dbf0bb33722eb5b22fc5a3376bc4725df33cb883164a9ecf5fc3692865d0c39f314e593d593628cd312680fbe2293cb33d9f85dcca091f3fdbddd129e45b934c3807455376905f1e9c7aaf1dd7e88a3b09beefadee32847ab4f42e60449f8079ec39af560aaa4827efde2606403ca452eedfa33c8c41090503c71fdd79fadfe86e79ce9d6975988efd2e057c3291fcc1ec52a32a68b7d9b0cf24cd19c4ace192270ee097fae8e6b31a86d50e33072ebb7c76768ec01dcdf8dc446abca94f21dbfd675741fe6f8d7b935d7ff0dca77959299e1193cc57a1bcb1b4b2956b9737dd39f2131304ade092723ffbe36dbf7b5f2e5d3910403c868d8a2f6d9b6c74fde1816231aec189e32bbc1d1cf700228baeb33ec8dbc461b0da4a2c006684718fb78f0ccf96c7bbcb0fb6bd27d58ab91b166a0d49809da3e8348db608ba26cd81402cf59e57626a690d0a3916122a51ab36aeb4caec96b41d9052f5276b9e33eef33f5957749b7fb4b5fbd794907540904f0462f19e2863a663f13f54c13bdbb005e5f055ceb11608c19d7d73f932c78e200ec78b0450eddf11787fb9306d5d8126392d840d2af70eca0e43a6b2057ad472c117d5c714576d643952d7d3f833086448c1f48de19574ca0711b27309aa7540d65a6ae9f1a1aa23c14548482420cb6618c4a6392d7ce9dc5217ab03dca88d9e3d8bc0b5520a527e415b0a4be2f66f62113740ad23485ecf5960c87bf7e0105e813e57292f1b134e6aaf8c4434e0d0680c8b2ee6081f25902b7dcb1ba489fd4aed8ca77182d5b18660e8a6fe5fffccf20f8371f0e525234118355067b7591273158128345e51c5fada61b7bd5f0c49cbbeb954730c22f0b74e433981d1b328bbc68b0d2b5d8ff17a01b5855d8f470e3a2650279f713ca106196d141b1a52f13e3765936327220a8d36323f62f847e1c15e367dcdc88a3a607ff3d6d57f482899f010e08c3c8b0255728510fb2c23ab301cc425809541cfda9807cc82be8af24c860794c3167fcfa1951f24100b2ac876ca0ed7794ae111d39e5010e6ce0507facac701ec15aff103fd7cc864a21887aca32063b7021291be984fb991f47be2df06e88c4e0507504a51b6f13cdfef61e61832b0088d8fcbb11b459c23ae6b7216a59c1ea5969b4b1982e43381b9a65a175e831262622f18c7c83a8042c3af11b54ead1846e3431d688d5dacc32deee9ab670e87daae132f4d872bfd555d43fe2fbfbc9652bc921be608886393afb13faf1cec453e3b211b9e1db9790d5f5e88384270a94890f9a0fcd970af8f5f3e5005bbd73ea2181a1820b8a74636601698ca209d87ebb6cad21ba10ab25a0646619f3591dfc73fcf6f6ea465fbc9acdc9cdd80d2b77b05c30a13fc6b132f42a38560cc96b5905beb12284f44f05c0f2bfc5d1c8c387a71501f612e1f69bfad500e7963038634c97c6fa079e51d53b2c7e0b8174c080ac4b769ca38648637812b78e68fe5ba81f6c475f665c12fb65d0bf1cf35643c21f69b9e7d63c067e8842194010e565c598e67f8939424142607881e3b73f48bc8df190152585446b3aa9d31ac3e8a9baefeb3f1959253ee3f31cfb4cafb7b62d3fd9f7213983b04fec79a2a81b1b60c45e67fcf330cc50d7dfdfc9fa3f79ccac5127137004ff7ed54cbe05372b870b6ab34ca6672218d4103c0611626abd55952c7d11c8afc2ccb79d941268569cf72917c877f95a674e08eed0b4d77cd5408ec8bfe9c4dc832b99c445a42bc4466202c4499d6816a9f911047e4dc3a0741f860f2e83f7dc880bc57f9575ae2239e4961a3dc4fd5aa50f05c3b7614480c3c20f61ef414369d40af47250a2389172dbfc8d951003734e4d183e300946dc340acff4420d4fe4b0253546e64093c9b6fc2c4c18377aca364c63bea275620461831aa56fb24656e65601f15da9f96c1f48d2c67128f7ea1d6ae901b9eb4b18f35188094d094e33b1ceb1bb5fd4e68842b60898e4da686810764afe6ef9cd0bb33b664245688f3fd24c173a128404273cf9f14b3a767c4c9a67d2ffe307949b4929030f59fd0d499361ce78244728c80c8d8d45113cb02cb0916a40910a7d720b9d4b9f966da8a60b12e8432d07f5a45850a69158d13089b17db780ed0ca4600d1dceda2d4bfc47547144f8b1fc9463c61a436a8398ba4217367998b1581aba07c650b943cb0fc8cb33ade57475c8fd9173804f050470652000e5d0099ff0f558454a117cd5a883a6e468b2d3d14b3ac5e7e59418c7bd073aeee9538465793ef94e94d28eb2441dbfb2a99c30ac953a875265d2c058d9dc3792c8f1e19a409a241af7e7eb9f0dc764786a46126d0d8cbb6ade1aa3641f8ab50dca40f517a741631b67342345fdd2649ce30bd2c6ba4125bd50a1fa8b475cf11636a8b153abe75c0db40ff18425937ff2e8110ae4a41ab6de41a6b9ec12a65e47eb87c761f1cf55af40b23509f34de9bcd7e6036be009206366915746621ed4dac1574e753f7608fcc1cc47017250369e58a4c7097ee55dd1473db6583c0f0a8c6aeaf465b929173732328ba1edb6c881e98af4d6578fe4eb3346de29fe86239aa6ab369638e4298f022d312304b191e8b800be9c1466328654411a4f3c0546d7c1aacc4cfcb4d58482177148963f8f4980f13fcc9bcdb722612ee7b977d1958fe72c336c77bcd2ca2a6276fcb0f3286f7beb0e961b21d4e6b7da63ec1317f3c56fe766991e0a9cff08c2fb597a26ae9a9c8354cde17410cb601450a6be68a91190c22088e5c96fd7468c5dd100d0de184de4f26a3ba44cb49a0c20ce80fbc9a093c6e234044fafc7b039e97ef437a01bfce255be1d04b4b87c7d7d93f72475a750b2fe0822a2bd360345006ea3f8975bf60388084bca61a828481696f503c6e2b76ce292341611962a7d00a8135b6b90730922c94d60ba2b65cce33ee80bb433d5af1cf8eba37d1a84cb54db8225f79c327acd7c688fbf34fd98fa75fbb22650c2c879bef6905f9f0b91c93c9a6274452922473ca1925e143cd793858085dfd2506a7173bd42b64d68f1fdbfba3f7780fd2a7a8d103e8a30086413e31c0488cbd810b641dcc001e85890e14a1f664b3d6f96103cb5a9aee620e678a7c48829a93d5b72b433c01767136311ba6874df22a5612083e3910333b306e8e2e4c4130041e0896fd4048b0cb93154d7bf71ef71ce1f12b4dabe8ff6d88ba92858a1d3910b2404db0720e8fe6b7113d472bbb68f315cb21c929c9a7f7ee9bed37559beff2b5359e1cb128bde4f7cb6538e62c6e03a38b0edc6ac28f42549a868cd850d69c91a3655978f6b3e460e09559c190e4219fda7f86220f598ed80b3db2d3c8534d7ca1c2ba042a8493da84a3474ab4ecc6034315ccf0c49b83fbfcd892738f967c2ea8c7106e5bddad4993ece92d6ca2ab7f23f60120fc3c1484a3c6a69be83899fc02e389eaae8e9cde244257556c326b265b546555695db9ed5674ecd3c1958f5cbcdabb243e61f666c1205a5274d1aff0b25949e2522a5c6b21684f6c1b4e72ae302e1520d6d3c0dc37b6c2c102f8350b3499817173c93d292a5e55983779c48a6c56820e01b904c0f2688cff97fcf06bf99ee5d1487fafded793efe1e7664f900d0099050cfc0a61c531c2ae6d8e8ef678fda664d99ac824524a12b6801f9fbb8a147311d10801160068b0fec9a00be10dfc7ccc0d50804f7a92391c25746c340387273f72c1f70f00b8b62e9d9dcbbdeab74a7906cb3db76c9ae7254dd5827f3b75a34593b0ec9f53b01d50e20282074a825040c6c3479a187d07121e096780205e035dd661adb73754af5fb63799041328889b7377b63d2cd024b55ceeb2b6c0d71d87c2960171a4a26e861ff7c144b3cf548dbefd6e59a2e12965adea9ceb3704409bb0fc7f40283a73cb71ec913a96bf728887a272c692a008198a2426e3b8758c3fc50640eec2f9efbdba18139d89b02c20d572e79cf2351d82de876f26726697287302334ef0aa6970844fba46eb06017d633eb5454c917795e304f1ef383495f6cf38ba2671eef5f8cd9caac82af962ae4642b022f09200adab77e191c172d76b0d7111bc0d436be49cf8a334442a2cdbbb969152a2f5e1437a420dbf0a21ca871549cc38e2fd73a73ab2d96687ec7682556a90fbcd636d8806b2473a6411bfb275904e71787dbcbfd62a0f5cdf1fce22e6c2ab6cf0f78ac87bff8b934f209b3a0e6b886524383da72de6ca91fb1913c59cb26f3b43b52d5e938557bc7680bed0ea1194fcd4ee3cc1e4f0c23f7faa02b7b156e91709b1d9decbfc80fc4d56efb6a1b2e09b797df21cd3fbb5b98e5a94136ef94e24f2e8ade28284a989826829bf686c6cffddfa4fee02c6a002541b606a2a0062c4d403ad4f55f60e1fe9cc24533154102217ecee002c93fc29a576ed2cc55306b264c01c52242a6fac3e9d5b27c047b4c10d9435ab8ef004c5d2ca6411fe6019aca56205dcb5a69ac88bf6ca06c6b55a74cf1859a288a5d4af4c7ae42ddd0829390c263b392d82af8cfe9220a9fe9ea705059290d0f6cdac7d7fe8e28763401f95a72b3c39b4a1737b98ba72b5ac8b4abbfa722989e122f15eb2571296638fdef3608bead060a1cc9f151f46b51fc8472fdc1f28831211ef523a45486cbd598e0cc3c3eb3e2d59851f7c647787cb27d60232af881cec4bd65e7b5469fe9f8c77d44ca98d32a822bc25ffbae9204e5dd1ef5a96f791875f3c6100e49fe606b475c6ab4d58c77fe435577387089af51ed6bd6752a4edf2ba39328a9714591fa73387866ed24879da249e6f22d98d2ce6e3852408640c81c862f0eec37f4e6e5f3349aa01f5e7190d4130219a239eb3da0f0d6becf2986688047b1e0607e91fd62f56720066e2fa097f544a4385ddc8d12c34abc204aaf72749334d0fd7e33be3e852f0cb847b0d6b9f8c511dc7da2f9f8914be48a2ffbf08f2842b6134382135bc557bcfa67a643361e315a35a8633b62199a40313a6a0ad84e4ebac939671e790d87214f8c7e209a286035bdf7b9622555ee83927c2ada718dee80e16ceb31f2032c51d1c777c32ecf170de1c7b811dd30581d05a4d2bbd06c355323d16343378b8088004a99c7e566d38021a9edf085528f3465c82269f5d23f7522c13a1624b19e97ceff86d0a79c20b93882549f1905427f970b11fccfa56ba9a01c6379f39225ff713cdf2e95c5c2ac0714b27da62f7731087bd1597bba805af85152324591569be6d80b6256b4099b34a7ed4ee95bacb540c5f379627c4e00c983f8dbe6f11afd8b0dff3130564e7983a8bbdac57731aef4a20944d9f60b632451f0c0fda4434eeaf58445b53fe23b977abc69cb4f744e38db176f03278d89e01e06174f6b4ccd4a5164688961fefe5a941f358e97a04ea6e05b7f07c30ef0b449871464fd942aec40e82b00128405d6a8463d6729e6ed7e71807d365c60a785a8d343f4bee1340bc5b00e71255746d0416800dec11e48da3ce8fc6d0e9dbe26e791fa9b1045151eb36c16f43724667e31ae90298c8aa32ac9edb5db030db382a60fb5749c409fe0a71535764b190a5f9347475408432b1c865ec15cc498911071a5643e4e01cb2cd4712b3d2cefb5c533a9dafa3824ce6e84d694b3d11890d42b2b6bdf7ed1c1eb410870fc7be009fcd271ced2c1567ccef3746373d3f5a90311ed76062a201d0bd14a747c514b9a944447af3da26dfe2ea8f99f6ba1d231c8b852e44a240504009af9e2a7c6d9e25a8c4bd384ccbd3199609f8db95cada83fb4ac46ce9472a10dea481701e5b80e875d1a8a22a7381b070a8de739e4b585e6a31153ee2e757e99da2b68920a122007a5a0470b413f87ed0b30370884d2d6d78e0ae38315518baea6627eb8621baa03b80083572cd142280e0b5af35952f611ea3d3031566d5de647132c30dbe2a6c84a06413281adc4ed09e6bfcfbcc064d26bb5001a874e96bcfeb1fd075891a5e7409a7a327dbe2545c8ab10998d65651f9e4afbecb68d7bd81bfcfab34da367dc499a57c57462c4801061db77decdeb9847f89220539f1cdb6a5358dafbff62531e92ee9a52aad260b3bce2ec2e8bbee29c000bd0c66963775d47296d5af889cb6a687ddb9db4414a63f3e4903769acffb16a8185b2c5e1d5249a776e41934b91f7ab63f2478ea54e39ca589a51526a83ec9972e3ecf1932c67e3644ba8bfd923d7c7d2adcddc71b926099bb21305f78476aefe04fb0f30961895c3611507024a0355aff615cc142a93cf7df46b2402a81fea888b8a4524e8a4797d778b3335a04712603bfd86566f1f7cba129cd88ca0968f395809494d3d2607ae173c268adb8e7c616873df30e1f6a4228f2d07fb08d325c653f19bc5bc438f8a2b9511a50a71760545ea8e9d7f74111ffee8f0dfc395d29a955637b4301c3da902431d824a95c6fda771e5c17e30004cd818e80af1519f13b0390fd91702de28d4d09d4007c46e499aae87eed35a772c40ea1a0c25158a5a0303e1326e37e5c73ff94250016f4e28ab51bc5ac785a4ba63c5aecbb955b1f12e34db4123a4fdb8bb89418db3c103ebeaaaff44faee415125e1963adea186d634f0c51a679d7b5c8004badb0bb4d086b4f812d805a11b8451f93a5065f207ccad2b94fe557d08ecc361d31539f271c3754fb7692ba208f81361da01db154635e2505d39c445c77d251d75ec05b7ae8f2700c0fbd6e792cdfd05cdd41062510fa44e46d333a73f65ef7eb1118705aee8c5042612aa205e03908547c8fdf0e63a373682f8ea89556f64e3fcfac581d01bf7337a020500590b0bfcaeeebeccca329b217ea7da2cc4fbca4d1a86b38d51883669fad0d79596115fa389952f40c7546127aa7addd19f16e216871c2c38f70a7a1ab26b8bda43ebe440bcd4fdd954241b3d4fcf3f7467acc00d37c04900aabd7a5cc402f5596989a4bee4d7282b3136342d68be8b1ad16bbed95405606a57f58a33dd7a75585909663238e326fe503fad27c8c5b991d420b88feec502077c01e108174100747679270fc130f727e40d3fa8346f32d71220d3daf9171570020292462091221b8c38ac45a091585605d20bcf901aa3c1d579375ab52946c3485a3385145c9a1c0169c1d92f870823803cee6dc25d33038023f0b4739c8517af3fd15d7920eb5a6ae3808efc087f01370fde9c44653cced60e245f6e365bcd882d86369b3018068332d9e04cd853268c095c22dbce8d35011b716b3bba9d2ee94b7c278e360ecc82a7761890cdf149ecf32e7606997dd297f584a9470629812a783447faf279fb2058197aedbbbaa00a31d550d24d5d01208cf475d8485fceed72342de13b311ee7de2ed6659dcd650c7793f081a6ccf3e1b94c13163ce15a7d9bd89bc2cad2595400692e29add87759625cd0bd2f193034020b02203641a0a61a77d7c92d7a0c78935773abfdd9401986b4ad1c29cade125b804681bc0eaff2bdcbf45f42478b8ac30745635d0e12d232d330bd9806bf5de26730ce282774b5e580e7afc3b2dd19083fd1785bcbf3e24972df6dfd832e1e8b822a087df69f73abc8f5bbc4dbc22bb3fae78a54e380004ce372bc40a8952c5a65f7b3d6539b21b6535aabff2ecdec08ebb2603bfea69e1120485d7bbf4f605a4b3940ead3619c0d85bafd7c72d174774a623ae367780db0be93cbd00e9f6cb166933b32de2d71e5e6b54eacc493e64cff994089410b554f6898acdf5627089285104bef31332744e2089d36f3c371c972a1d344abfb5278444c36cf9257a434956512db01b6144d234b548e17b5d507988b6e2586ede99a305690f019a08b0e5b59de7b0cc70537cedfa1428875f123aedc3c69a8e51862cf0a2bebc209676c482c602a7ac464321c8d12282bbbb7854a58b872f29473df1df983950b93fc29f338cdbfc523ca288f89eea2c14463b8a297a17163839b9b5d304bd4827671ce257694abbde0b76431bfdfabb854d2c6499399fc339f5f0f275d2e8c4cb74efeb357d3eb845abbe108340415466dbf2965d32430eebbbe31a1a792b26572268a2d426ebf9825e51c97b3e985c1656fcccd0c4ad90eb7b4b54b15f63f906372c0994a0c56bba7e37acdfce7343757a3b897037ab4c7d688c9c631568aaf1e4f34478529214656099cab723867c8e400c47ec5fa92516e05822f00a2f1550fdb4ee9a954a298bb26a4813fac027905d04f2af021f3b2de717f2b72853c58f1f8eacf752b9d08a091d7ac2889aa94dad906dc0032533bf2d517f7092bfc9578920901791bc4ecb3f48a5e6c1d7c492390fa843051bf7e12ab87445963377a81a3c0f0f25859f07b69c1855d4ea56056e35e1e229e1ea7d373ac90178f00e36825df002771cd7565805c7a31c355106f489d2ce88dc67eaca95791799dbe3a111952ed4c69d0fb3f6012a082d93c5d6eb89d308925174d49b634501b48ff13ad73e114edcf2a18521faf5eda78d0971338d037dab74f593b167e924539a12bca9307f2089ae96a002eed24bb60f47eeda88377921dea15547d4164704ab236091687136247adbdade7959dde85babe913dcdd52845b32450f351f16d3f4f42cbb951a6a030b466cefb41153d508c37b4f0373ad37d7889fcd9d469a9e7e68267563835a4951f1df8cfa4738abaf259b2b8ea577b92cdfe995e3b9f07eab6084b9e7e01eed0cfd9e48b082c10a4c23b9c238823a8d37118c0f79b5bc2918c008f4d68ca8c41ca991f14b2bd6161475941d76343efc6254487289a26f608579fdba432bade8dc058e602bd0de11c8b35ebe5e8e5287fac7d9aec2d0242d6b794603ad0717c7e75dc3fa73c94f7634c602561df80ca840ba81cb7661a446d96087d0b57ca7d8dbe85b358b8cf0b31911a21a74b78a84b8bb49cc0952d0485debc91c67e9074a4d25a5c531168df76fad1d991d797afc45bb1d99a60c621666b5a34dfcdcbdf90a1e869c98d44ee1ce7457d645602af305c68917bfe861b6ecc9a4311f38a90246566d8b7b5e2cad91bf4e1ea762b888bacfd575c6053b5f17ec80c2854b7923001549ed21cec56d3a0f0af4db101fb78bbd88ca50c21aca71c4754ce1c546e2f89fc2c0c1bf84e1f9a0313f0664f935ce1451003e92532762a68d2f9addd522cd14f3e4888d3d5d079eed134dfd992471123ae05b41f9786908fa321e633fd400002e82e1c53270056188287734285204372add7994041413d30e84670deb3d0a64167c0146a4d9ecd27f0ed2b9fbb621d4e0473a8e92f2722473cdf397e8a039e86583c208558e8ee634d7b1a512d8aad0445e9ad3a0083e55784b33e578fc45ab00c2f3f655fa46b9c5bb27fc12e13d8b00795309d92f48a147cb02e8a386b3c672bcb3216c427c1bcc58ad0f730535700331b9e968ac6ecc45eca7ac2e93882f986e214335db790a858839444ed3cb0eb024235d7ae5d9cd9fc2918b5b8350026c8e5d8bf207a05408d8eabcd411e292898dd5618a00c94616c2d469541504fea9619506f153fa3fcf73c676bc48410268f9b33183a888e4af7f8db81dd1e23e5e40171b784f1bc183e858b29b08a8aa812dd13114403a900817da77c1eaaffaa142aba5964813f7ee911075d3a56c22fb910c6fb2355af51b407bc412b9305a734cfd13a0995c152e7e273122f4c680b8f1173beba526b848aca750551d8a9ea82cff3e86c35795466c43208b3fc5d4f66b1270a79364286205f48830bd2a2b0bf57a1a71898bd11542a14f638b4dd78e104e48201557105ab9743945f218d73f1cf187e925092109b1b6ad83e2a7a501f5ac18418d8894c94fab9e62a1290b4fcf817e2ac0ec21f58997f3fed999e846172d4998b31213e01a1d2e20232465eee73ba19c42d000ac55712141014cfa734cd674a730a61492383817da7a3865e18de98225b604241a0c0e55ac261014d0e8c019b683f730f8c4070c820d80e2c762d0bd3dbb51458177bd7a22f83a89cecc178096339d1e116664046553e0ac43cd53bd91709fbf40fed415a830767813aef958d4e757b2e990e733eaa7c060754a07ce2dd0f264de1c1cf40e44f1255a5132651aa962cf2f637dc9722bb4156e1b3dd2fcdb8c6254685f246867e055a77c0598fb2d3c735a82130b5b8d03201440fe7ae9a2e1e01bf6c19d768f88b148e6113116d4482096a8aba80b6d9c4865032e2aa33d366eb10fa810d0748336645b1593b50fb1271eb2ee402f33e8b7efa83dbf8ff9c6b655ce322f2330e4c5fe2dee008758e89b28bc440e56001d1be8c62f486914298151ff868336b40c6de75b800b4bf4e5b99608ab17eac387c6fb2208a01cef07bae44b9fb860cf2308a9e36644486285c4928cb148712ea4726616bc800d85e3461fd742bfc459f3ffc18c84dd047e7860cc8fa8abea025234564f83140b4e4345d23135aad42b75ba239a5a0997bfcba2c265270f17a5c7bce19dc08219b62525609810e0576fd9737899092396db734682f55af2e4caf404fd66803ec472ee3c4a23184e75edd9e7c493f7c7a0d197ed498f1e2c1089fe6883474a798fcbe644ae1cfb6399feac44141df14a33edd226fca1e792551fee92f3b25b3e84de011f89a0d6271e52c5f15a9e9ff6136ce6530020e4e342a3c208166ff430c1f8c1ae9b853e281a235ab5fbb92d832f8da878af3e3d10cee6bf0a4ecc4d8d9e833b8f402e13de670b0a810593ade5af30c2cb653a17f716d0c942ee2f4a499720e51226775bd2fa61626c0278675b4089937445fadd3429a1242b75bf00ab287d170a8c92b980f01aa2b426194440913816e28d1565cf2260d5b539ab2273f736d41e2e1e95dea4ca790deda5bc9c29091a8c65762ee3218673f3b3c344862123c6837c68c737fb821fbb3045ffb9ba8d57d7df40f7037aae67f8a77936eb2384beb61c2bdc778cf41255497e8ef0b9e079031271c09d6ff20c2138f8c2290ee162720354484c89b8ed1995fed83ed7841ad2770db1d9935e28db4ced3750600236c07308c1024d0b4e67d8239b1c3d8c409b546bd79db9b2c08f6b9f4387675b8f2842ba771309a71fb49d2c78a897657a6b5273a09790d35f1edda1f3c6e64aa4290030146abb1511909931b402820b55d4425bbe9228d396c5b5537d6aaef46b9abc807149a21ae9b81679881709defd5ea678b9cec49a8001acdfa1a88f1dff37c0020cfa6443d5158ef87fd97a604f28e7548b801c5c5452f1af9ab44e0ed042f10fd2efc1a9b9f4523e37e2dabfc6d4516b4d9fa9840c193c07093ee2990cf4c737b43c44034d39a57228ca2de63ebedb499857275903c136e7f66ccc24f58d9ea00c785e1c7d12d04151710d26ac10f1e8e218b4c2831231634d2c01787634b87a7788c5d69a8b839e0c14156bfc121492b7157fa87ab873f3a0f086f56fb104319161fc8b63b0c98a434a9de41134ac3e5085048cf84dee7d1d5879c7330379682d19f9687a8e5b273f0ad740f96b201c45d0c0f08548e150e8fd0f6013bb7264042bd26871f68284a9ead28626c179cbfce3647ab13b5096a9dbd69cebc19537f3679408738c75efc25259852130801ac27051e98c4400e57301a594d3ac9007f45ae8d7439e3ce00ad476a95b4ed4c5a72553341dab6a8b364ba999172850fa18f13fd570b045de4ed70318d960b3ae869bde06d895ca029100cfe88bd30c3ceed14add95a4b0891b609d97bcbbd03400e530ef70ddd0981235c8187ed51d9da13db17f3ea46ac28f7a3d9ca8e13d252e632c4ab1bf0a40c3190bc82079221359215b6fad3ceb403602007ab63a42576e713e67c86e7b939679c5c6862098f8e119a90b0ec61c1e243e5a9e5193f71bed504d10774ce39a7a6a1200bf886ad862a0d359023c511aef463ee9652b6e584e0d393031ff444f9f81450663e1e05cad0ecf12750067b7c34d5f8ef54ab468249f0814fcf23f1a36624245c9939c332c33d656318fb31c7ce285c899f17cbe04accb6e3072076e882afdbb3e3d08e611cecda338c63c406bb769cecdbb1bbaac9be5ae1904d5c1812373ac7e3ee5853ab5499b1bb1a1d79448c22f75fb3bb925f51bc2a22cbb0578c538fd563c721dd0581f6b46ba5cafc46c2e6ac5265eed0d1de9cef9e29c0a04c46a3ffa568cd96fc87659a25ae8913c388b5ddb29be5d9ac6883cd0f58b843b6b0d74099ced87ba7595996ef79658c26b1ed25c1c24c1fa3e466b3b24310e46dc61bf3263b9aad3b74dd70a543d7ec56351b77d8ddcc6b27619bed1cbe2140b7dd55f61c2eedae325c6363a6b16fdd65d782a0591a0866b37a27c36665a50f4883206fa49b7d8bddaa08eeda17c05dc3abba80eeab8a574568df6ea4fec6b4dd94be1d882bbbf40823a0cb3e235d8c9461a41aed3846ea71e6b50de3c867d9de66dee20ab38dfcf6ec66580ea9825dc35e321965ec1d760edba0ababa9912a980bf6dac33eafdd665ec3abecd085ddc6b687dd04f6d8b1e790adedd875c816f70e7bc76db74295ec1ab545f48c21c69651e238b377cdf39b877376a4f4b3567a6b9e3567085b97dfaa26c336c7bcaac130cca73cd3b367156098848819c61b46ff0377f5c0438b1eae910ff2f0afaf6aef28b0f0dd87d18ff84b797f4bb96f1831c286f10923e5c22c611c06b6edc5f370eb6f5574c7570cdad0295dabd0dd31c638821e1e552929aaa7a8527af84cdf071f2ebff9707bb82d54293d5cf67061eee13de0ef3905d7eeaf7a2aac4e8ceffb00480f312b4a02939d230839424fc33692335de448c722b07e1149aef9abb4a3813fda8b28d731428a3fb05f2c128bc85aa53cca35727fd05c61274f3ed3a91792acc961645e1b1bd8d24daf69160962d025a661e2291233633cb0a767ffa011e97d7fb4170ff1e76518b9be3e3e3bfc5588bf249a45c291f4c63eda4b8244fa0f88d18bdd4712f0330d8d6a7cfc48e2e4c62411c8a7bd787be312ed15e90c0024f7f032c43128e6e4987334abce3927fe48a65b8a35476cfd078586709991f51942237852d32cd9b211c6a16e20c710e47804548997125edb1e44f9c0ec061f9134ab84bf78ba31abac09c723df334472033b6f7f62b3be935a353dbccce3f35a3a21e6e929695e02f9c0d27faa988488c963e255fd3c09af2ab68152e5ebe165edf2294efa0562d6e8b54b1f83da8b76a2c83aed44b9cf301a81e2e34f7bb1487b7189ee88983f1d1962d21052ec699878ac0796a7a666f8ab1cfe2ca6ca14f3b19f8b8b6cad78ac560555220ad6b4cfc84e7124c7586489687a7c048a48724c925f24c7d57cccf3a5bb9af3858661e381ad59bee69a4935edc58ea62647b3ba2a5b3e26fe7a78195efb066f8eaed18285369f691fb255a1cb8c9f8ac39fdde297442691b0f6789b1c1083a46324123c9e80975f3c10eff26293dd97157dccf4f0ae287689d981cdd15e7cbc115b86212859a20a55088119dae08a4f42b6601a82a0851d2c610424e8c21b5c513ecaeeee363ae955109250742477123324e9eeaeb55b726183303649398c8bd61eeb6888ac78c64d2c23955a2bfe01613ad54a534ddb8d99373c0fd0b9d6dbed7ef5f6b113a25ebbe9c67ceac165223b77adc027ad62bfa93acb15f50fcb35f58fe68af25aeb239451f1fa8632295eb7db6f9bed0fd86dfb4c6bb56a8f575d0857ea55dc0857ea53dc862bf52877c295fa93543daafe544faf27fc259135cd565247636b8f6a6bbd097313e0b673df8fee4ef8d5bc456fd3b69b5c55787a8dad3d51e12720841042082184b075668e64c2babc346b7231b15f2aebab91a39ca75761540634c853b6ccc206b6213d19bebeaa90d92324c6443760bfe823e30d6277349c955d104e1e65288b389a63239ed8c430d910f60a5a7634b1d2cc0d52d971963e20f9049b8c43c02651ba6083303e4cc2ad4e162018f89b3d4449e317a2920dc720a9d254c82862710eb659d14793a61a2c3d86cd0df3d144038a710ef1a83da039d866cd40daf1e828c632d82f0225018a4749400254c9310b27f98b40fd9263d7ac67a9e3b69e9e1e52670dc3340cc33052966559d6d1d067dd104d04653ac2edbd41160d589b1583e565abe634208b07f4fa3c5a6430c41dcd8a59805e1fba8c84cc80bd781a265e4c08107a3021d8eb39ca3c335482ce121a441db08840168d3f9309a2482465495322077b1d1d75139b4ab39b39312723d54aaa75c399c428a9db3419d35e5f487a3b6a249e69f92f474862186fe74439442fd601c87ef188d21813639ab5a30fbd0af090238ed93103618b3c823250443ac016f692a6fc612f930788e0ca178c64108126f68a40d55a1550048a49b24e53a227c601aaf43700d421884027c8fdb89deb62042add2ec6d8d3d3d39365f1281e49898166cc60c6a02883228db824b6c4a29886b8240d91468700caa14730861807b8d27005b6ba07a48e4733065d011a353982a259d985005b208964cb74d5149a80843a831ef4916e750f989047ba654292e394b7e6ee019489b77db06e27640e8664ab8b94b05f17e53ac4a459112ba2a11d2434632c998e81d29ca6c7896b4a26f96642e30131d4acaf8394346b7583e6799a277e913ab05f0775901346ed15914b348bf4bef469567d5ff2c896a9f4d3511b2631cfc9edfb48e7e4749bd44f291c933a0adfa4708c54697a84981c581c1269f48e8da121a94923a47747d3310db1a88b228d8e47310db115ebd07d862e2a82dd02d8ea9c19e020770f72bf83228d1e8a2ddd3e5225d621b61a08dd41b97bfa0440e81e8a34ba065ac85bbfa811ac10b2b0833184e1074bd4e0924328112c17df2a99fef59021b26733dd76c95a2b465f4368cf0fd8d8ac52ee3e32fd93403248f2a88a60bf3e8a47524228d096838c411f491e8cca6dc32846355992df388e3bd7715cc7711cb75113d7752513c7452a042b51a88e464a1ed9d330a6cf2b8720b19fe4c97dd2b74b1e3944f64c8cc4cc3f68263dde2814871a86087408b049866dc8500c19be21432619a221433664a8860cbbdb987ef2f8c4494feaae22ae894351e8a87453375dfbadc4c5db3b197634ab224aa593971e793ed35bdc7949954b95eddbb3936727580329aca3d9be751989993fc983b7f8d32161637a09dfc42238fa48950d4a9558e446fc67dbdb1e3191d2491d110d98b0917923f1b5a399783b696fb31c15827decb66f317634f2c4c9570b0ea35aad5aad9d852bf1db9db2a6e0b668370c858b71803251dece2a547028f1480856e62f1ed1ac8a3879ea36274fe155b44922e29a53ec90b049fd04df18015d3ea44a1fba4cffe0510a1ba97d0475658fe429a263fba77d244fbf4e3a4d89571fc94176e0a8e7003b0ac8c23e2f47a0527534d8b71570459425da8d3f0885dc09715bc618632784cc1d8e56b09c69bb18a9064ce2a26a1fb40fa5b413424e0c9b9247f2d898445cb708d9208caff4cacd7145910617d4f57437e07450848b0217c4bd80e3911c0fc71369c4211e2e0add0ce08a4f2744a536b05f2cca36236c3f1c4f6c91ad6d6833426c6d5de078b62e703c9c0b483f3d3d5b147a8268b06d44d87ebaad67eb8934baa3a34d1ec9c11487866cd442aa3b9adc0ebaa348a3238a2d5cd00e628b8b4247d41d7573e88eb823ae0c5c1438a248838b0334c31cc020315744421d7e435de88a4512bb01d6138b228df8446c893788add88527729fc62279379f6d0670652b929f8834b61ec06d63e20a1975db15cf108bb01b603d71eb9191b4116d454143a832a7d35ec7d229103853f76a8f48b638ae88546920d962a17a1f33128215d57a5519c386308882d2b093523261ad8669183667f7ca7d0ceb82601886cd6ea73d0e8a58e3e230dbc0263f1032859c1c17cae5a5796bd451873fd185f5d4aaadb88bdbb0388a769c93a3dc45ea2e5277719bd45d6094db9c1c05dfe46800e52e50b0917828555435069a0cec8ba39c888b1a1beb02cfc474c1aaf80ababe98dc2aeee238563a2abefa4ce3fcf72f2e8e91789c17477944b9cd0bfc43a982826f8c4c002ec93d8e8851e4ee3a708d0cba3b5ce2fa5f3ccb78391e2c8a9b9cbc5bde384eeb685645a448317f739ce213dba87ef1cd0bece3aaada3c1be9d5e9b89835dd6d16c24bcc2d1e22837a2c5510e24cbfbd52c512e942a725e2039fe9879c35d82d882f964aceb6830dcbdb8298e7255f67e9d907c8322ae882bcaf0e78215912a7d9463f863b538097f2cf9eb7a5ef1d78311be0e083d3b78e1f5d002b3e44f1b6275509472ba23eea6ae4627f5936fa76e55c48ba76ef3e2297c6324466cf39fe09b93fff2d66cea6a50be592e76343528df52db49ec135922d2e2f276b93b1ced6a71ed764bb8a279f98f6bd2e2b6d6d3acaf33cafdafb493fbeb7a3425da50d7536badaedf0855e45fdc539e10ae48e822d2826352d4ed825d77241fdf19356996c45d517bdd11b5d7116d5c1094c16600579a005b180d8410e4832c642c0753e851b21d49152ec38e488b98b3c38d3b2e7234226da83daa8316ffb4a12d3bf616773b922aa7f99790ce74339dd5c58c302115477988a7886c613d3cb562ae08c6b82225cced70395c4eb3beed28a3683c71475e15333229326a18ec48b6501fc2432a4a29fdd97eb61f2bafa2e62154394a558c72c6211a399e9dd891aaa66955ab9aa6912aad24520d82a59de934c79377e2d094282952d42a5b64b9d248aac416ef96b7e6e48dda90464449a740c84410591c4f7b39994e673b50260450861b92952016cd1abb1cd84f7bec912abd0dc916ea6f5557c7dbf5b4f703abfdeb7a3024aabc5126ec873d3174c47edd8cec7a9a05d4ac4d680924cd8a588922dd919fa0cc84dd02ed6ddbb94b91606b8d8e76d237ccc3929a84022d3031c21242baecb4e1ab251f3b667855d33f511cd043185412f5b0e1ab5902f30a18fa42cdfc8d29cc6421cf07015bf4529e5e17a9120fe763a0cc8e079127fe6a2bcbc9c9c93183cb73919e0e339821cf7463c148063f3a1c0095e4c8a1a3bd96d711b4f34ae2f52a41909d12f4eb55ad95d8d235d84fa56a41f11010089795c49f46f6ab2750ca1f334ffc43668ac4546589bf1f33cb164080641764eeb08ef6e4215c81b1f4ae84616c299dbb9d92984b777b97a33d6ebbcd1d760970406ce1b04aaaf43907c419ddbbf74de6de5d5cfac6ddafbe024032d73920b674ef3e23b90bf3464bd827fe80746ab05fd6dcfb1994a1b554c22b1cf1a61b116fc2407277b7fbcdd2fdba67dc2575d7e076a192ac65d995ff649e78764da1d0f3d568d9f0808091390ec7d0181b248ccdd7e7c849e80405198246108a9cb8135fd5464db3be1803c8a039e78cc9d2c68cccb12389dc807a0973c52acd500330fcc12539d230d4801c68189a5c8e2739f6c8fd38674b2d0382c19a317819f558817e0e4e64a8840c9b9003112c3667b4589d465046da7a26b6566ba79050c49a4c4ae3199ee8569623a714ec3785b21cd9c29e68158a29d9991dcde9b3a3b1476d20cb8182c530768419b5479dc08c32ad2e2cc8a73d99a38a98ccc1640e137648fca84e46994639981036d43094e6cca30e4295c8f4b21ba294e3ad997ec15257df48bd74e9cc69343fafccbd24d3a278671333d8399b34eb48eb68642657dda43d0a234bdc25b05fff00c9f3a25cb953065bdf4de834822a46cd920d85aa7d8ebcfe91b08b328d94d20efa1aa8566ba12a9f66baa34a2c06208f4c02ca64a7779d3c8620d3c70df8c422947a217fd3680ac9162694c22a280f2074d520d823482660f694b18f94b14348a487f27c1ab53021a942653a1a8c0d51859e4e3964fad4a1a41cc8f4a843a8227f98d05c035c7181fd30a13c8532520aa3f08711658a3dd15e9439b235d70055e8671c763690e96908327d8e6c41d7ce2b4b9e693484c298509185285707051bc14e225112469fa04297962efde92ef5a14bb447bfddd9a43d7ad41d8d46e58ecc698ffe931e563121ec1fa624d3a2d3b790395287ca9c4c6bad958489a0604fb447a79044c142744e23a14cbf69949934eb99721926194206ea42b90d75a160286de019c28005255c81072827c755259629092ccc710137405cf6c605f26781ece1804444a39c9c0ca39be62629a6517bf4a861e8290d6c863f8d32cd328441318fec659b451136fa9510a55cb32ad32f58f93efc6a9ef2d96de46dfadcb3e3e09e611c9cecdc716c279d84712ac62b976ce2aaf5b289abe215865745d467c75149cf8ea3bd1e47f6ee1dc6213dbb6ba6e99579e3485a565d14caee2df4742108454135da9447db1e9c32287f9af27c916729cf1df2ecf27491678b3cb73c5779b2c8d3fe23e5b922cf5728433f55e43953e43951f2fc8432d8e7499e3395e71bca649f11cad4cf134966050ccadebfea83e703fe2c7c4a0a0c1ef0fd8b1d5cb458b158a152910265f6fc9420473b7f929a479de6edbca934576e9e2bda9dcf6ec395394f6f852b13532b012823212ce980c00e094019ea225b5bab53002c7de106378520a04abc7691903da802611c7a12806520022408434c1c035762be1c42c0c8131f7193bb31911aab0468634364c003182da092cef111736e62901f49344b67a759dd91f5454f1e5e891c8dda939d33233ba759ddd3ac78638e1da459dd58ea08e1813148531fd80f1e4dba7da6375cabb52ad5ef41a3988e4bda93a46e7b51c310e5c07e9df345a22c3ba7566b2919acf6883f99c99d86913f0582a544ac76e89240320e55a1663dd12caebd976c41e943b65c5a250b5006cef6788276629a32613f9824d2d478ddb76bc7ba0d439a63932d474eec46a378d430f23bb05a4e578b95b01123d9dade957e79c8915eea364d4aaa63bfcee99cde79bf64a9e3b04e3441a63e9662497960e33f950f0eb625444e0071f0b54118f105aeb8d0675392e6330cdb9335933db88c9de295131810f31f76f9daac6fe648216465794e9a510c53b507210bad4716016301d081a0195649d72ceaf0360cd0acedf03a20d02cd3e17f34eb74f8244e867a48e8e50322c31dddda015b31f27421f4521428478998b8c4517cc521b1089d582dca128e81c3300c33719c3d11329ffe72934f27f89b39855d50d6746177f7a8bd4d3e87fc0ed82cd925d19e7439bab931078b9129b932206357a9ac2549af6a7fc9406e16094b17970f488e39edc997f6e4cde7e202e305e52840a8269d01c69c403939394ac0604da32470a08703af4e81624fe650360250a6f847676c729b46658dcf60842b43cc3c7be20ff388971966196b3ce6113f338f985d8ac195f8b8b5b6515257994d8c526cca8ea49a69b3694f29a14c439978448c82ce31c43cbf4d8c623393b54951e354965e55feec0994316f9453cd49e7b779658e9d10f108c824ffc01e33865737b04c2906727cbc85628330be4b394fc5602fa4c18f0d7ea8c51b660c5a52fb0745852473289222c3263a80a463120923cf29948f60ab2bea8a206579d7b3f3f2c9aa1f29391eaea761381e2c47aa349683e56cb5f2344c9c45b01fd6735285b45c23a97ff1f5c55379b0edddd530c74309064a4a8a1e4c2b153ea8bc152a590b163fd81d5cd4d38b47fc6157487dfd24a59c00f84c03515ff2939f7865e5a99b566ee9406c3ff916b9d4bf39e759683da97317f5d4b7968f39e694c427ed451ad42b0f00ae6def93b8f29ce0faca706297cf528f76aa5ae4d451a866a11e813e9be751280824693018278719f5d46747935aa50e33c6a297f5255bf10715cf871e5260f080ef5fece0a2c50a062760b142a522054a89d3baad9eac299edcda5e952d19b2f5f25ac4e545467c4b4c5d7bd20951ca5dd10c6c2948962b792844755b549efa522d898ff92241234f138d68186ce5a92f30bc680f8252526679831dc713638c5d517df5541f93507bd574967c91ba44b3243639b1451ad389b03ed33579a2b2fd8275b98ce3ccf88bcb65dcc605cb38866d66e0faf2993eed28b132f00bbe54e9db9dfa6a98c7f85767fcb32eff542fff7e893f4fb660308c819a61ad8b4af5824f224b95694773c2ba5548abd89df6dade02e5fe6c50e5296232a45bedead72aa459524a294f88ec671a1a6a16866d1093121937c9c050aa988a4c40499a25b1f5a15eb0d95b8e75a69d10aa9c5262ca5be4a2297557f227f99437c9a5ae2ab7c5987491d10e64aa0bb6c50669afedabbd1d2ed8967f76c7ee74452f6735393215b5d73017a77598b32e8ecc599731e332fe72718cc8e3d0f80b89c65f6e43e32f97d846e6accf7447dc9dc44a6c8cbbdc16495d53861d8d2df284c53162e37299e3c4388de3b85ce62bf90504f1185f40cc5d3ed334ee2a3ec683b8cc5d495c448c07f155c43862e020f08d119b188fb9cb63bec2e1f298bbe0187c53f318d8c5051b899f8901d0cb59a75bb02d8fae0f12b918b9e0247cc838cc67bcf51997719bd661641ca6754b3376507607f5cf66d43f558e5ab09fa9a848b6ba920e9489340bb6e530b7125d197fb98d8cbfc8c011dbc8380bdf5419b80249955ce390ba58a64566cb3fd310d6dbc42b1c2d9771235a2e0343a9320f24c7fb558c940242c20e30fde49a9c68afb1094a159e883b26ed0d592466febaa2985ba62069126a926117713d623f8ea706d5a1dc45429a25a7c443c0ec33613605c956c7a46b22943b48a82b7a8a0c93f0f05421edf10c69cf88acaff6b060a3bc425734038b4484b0b3d287012bd8ecf45fdcf1417366625293d81d8ea75991fb69d69c1528f73925b82315093784ebe196e07c66fda94b704338aea761fad4073c5bf796bf64ab0577455d91b5aaaea8bebaa2faaaaf2aa3ad3a343bb98fdacba0c83d03bbc282e41a247f5d51d6d15025b929516e2a94fb895c741424c32f64d8041c8ae426e0c09357326ce20d45aa3ce75094553244821c8472899377c5a9b229d3276c7d995c1ee3333d9758edf4181767c663dce5e52edf4e9cedb46f926655c4cb5d6ef37297476c33e3314eab605b0e7319b7acb7dc86f59697b36c5a0e836f66bc05853ab99be460778243c65b6e848cb7b49830cc8442957a50b834a4e5be1ce6ceb88c0ba54a6948eebfdc1b2336323e03dfb45c068e2fa9726ab9b1e52d3df115831e97c7f89d00e9db89eb8aa860bb23dd76355d918fedb0c968c3a6a2aec8c495ea4b0b369e3a26455fea32755357d419a5baa25467d42c89bb565b5f78934cbaa29434c25874459d51ca9ea48edd74bb447b9d4aa57ec27689d3e9d6da130a957a7f435d2e15ad3d0bfb6f62eb836d11ec307fb648ee1496d27a2cf6d44ddf6a47635a61ea8c52f22727b7a7a71e4fb41ed4e59d8f1d0a433b597436609e2757ae3a0300c931933a9a28af7dd9203b9d51c7a4330515352b6a330bb1f4b6884fb3200c4e505fdcac82ddba7a5210c909d2139734445a428a71492e970a998ab2a9c854642a3215c518a74949d7d1446c1a22ca9d6948b6aa901e4294fb1d4a47d409754f9894c425b9ffc41029a83d9213768922edb54fc3f4e914ec575fb608468a442620966b0232fd7c5d514692fbd10454ea682636fd08590c9b884c43ed359582fdec4e14ecc7f1ece41e327550b01277464ed80c7f1ac8c9f1f429e2ab90ae2877cbbba2965b791aa62f6f7d3dc152ea047bfafaea82daa31003e28926284b11094db01f0684693fd428d32647392c77e7a708908f8d38a73fe36acefa922d1805a2caa3844f45d22c98040e30c9dd15d5269ac351feea90ac9309196da14950feea91dcaf5a83727fcaaee88b414c9a05d500297502aef463902d0101a28d004295046827269df2839f9562ab3a991367d88916d98c76c240e8020bdf31f82394c96a0f9f85f14f95610ff8ab291006963ce0fb173bb868b162b142a52205cac97dc0190f628eac8731ed7d30c926bfca32acbbbbbbbbbb3bc3644b2925045aa575b4d7c75660e53f18b4244b5cc300cd9a9848f5a4771575818f12360c079e54819752ca2a1b722deb94524a7879d9f25072321b5e65afdfe6249d45497bf72ffa64d2514eb677265c4fea86289d87662a95b69b48db851cf779d2ab6cc96fb770a74b1069c4bc1dca56bf2af7dad3644add88f8d481e452c9a62e942aa5adabcf1aa962d4d42923c4b7c0f6e1bfaa43c6c856b5ae7a7348956865cba5893af0b8a21109bb4895e8b2b215e382f1d8c615b2c0c24b1ac8c7f81823156a2f6213c38e4d9ee9138fc41fa09824064527a2d0a907e225adb2116191a8a8591006016a214447add33bfd92c7e89c6996944404804073ce593b128e2bb05c0c514f133590942da93a6aa32e520d5921a2a05ac4021daa906eba24974caac9dca5ec91393d3cd6a5c753a9644efdd61d11a65c7a0d1d998b694fee70b8467b72eacc9c9943a423938888708c249245ed4912aeb1a43d298954208124109edc4040d92500909f0904498f54a9ac95f5351a206360e47895ca5a08bd485fe326a65913c7342b9a4c4227f3c57567850844069b05414ed9307d286c7f421b9d8870e0d93eae155357b516f14112f4c48e925804c809296b6cb953051b5973c5e9b2494e5e916192362cc95be4e6162c8f7ada258066d924fc03145f7b85a4f107aec89b6e3ce2d3de0e2ffed9fcfe7d7177b850aa705fe3ef06d3eec6ccddb7aee22364ee3a9aee4dd4dc86b221552249760988f576bfd6eefafe07a4fbddd174f615ef2559b6e2d98a2d7737c637ee31d890ad1d5245629728fca92c274d2a4a2e4a2d4a3ecd325d6adfc102b5ba3ce9b5f4b8a36115d8056ef119a97da6776cdc591cca55e9f853e5ad54c28d212c69a61db27e15b7c02cf0a7eac71d89e5b699be755dba3c84b0f111318a153f5d9867e7d2fda210ece5911f543efeac788f61a6b10dd898b1437b67de99d1a2caf09351aea20c4554b0b88bbb386cd6eab0592dbe8207e9da49af6fecf528d7b7282a1a8a3eb009267460474477eda4db914824bc2abd2df02293be2a913e1d3ab2f6fa959ebaf1c611cf176091bb0468279d54abb511af3a5c0020b984fb7dd223e9d667f72b7d3bed0cc0bd3bed6cc4ccbd3efef42d8b1d026226ddeeb04340cc1ce91dd67a2c0927807bc53cb87798478bd7dbf773d1e2db57dc6fe6d5654704f6faee6eb4c0b33d17f8280cdb5b7db6b73a40e32f6616076071d367fad34036f5637743e6ac23e2ab3a324966d301bebecc2cf0875339d3ed6cea571f99843fd47fc86c9a5805fe8064135671d4bbbb7155e02f66d36144a11e65361df5f814f747cca61f339b9ee2a66fc0ae88c8f58d558f7875e38d3f2dab78199a6420324c5286a0bc35d797878aa37cebee8696ab8a7f2a5e4f0476946fd0011626290aca2857a123930e23fe5ee4f87ea9f1f762871d5cb868d162b562c162c50a954a858a142950504e4e522914ea74b2d6642a95ba8ee3b64dd34839927273b854c25fcd31ba68162ef087e5b8c2190b9cadc49758a547fcad38e9ed35fee6b5eda49bfa8adbdd0bc45c89c08e8282bfadde18bb0200b99dbb13a22fe9b2b3017377eedbaf366056fd7b56611e2aaebadfc42829aecda6ef797bea7e3af276ada341417b441645145110e51ff3064ac66e6f8ff69af47abfebc8da7dc422db7677e4d858c4f568af88ec2f9ebb5f7d169fb9cbe302346b377a47b3b696959bdcb6c3187774e4bec42e318d5fda7371315a350068e0cd19bd2cbd9eac995f423c442c07af22d4dc42595e4a29a5942de193b4278182fa0c56c6dc6a1ff913440a56fe6b1f1fd96a9d203f3e3f50b014771178a32f36c9a7745e21c9830dc2c8ee8f9887a89f314b00e931cf2ae41863777f08981b6b4ad87fd8e3b7532099ce48ed9e44c1367618094084952d18ad222fdf9ed4404eaea750b0d4093b1f619c5dc2e6870002a37242acf7041bff1d0829ce173c9459ecf9ee969866f371e6b41763625c5ce46304ca740099071562fbf27275431e3b868164da83dbc1b07920799355c68cdd98e9bd213f711324b8fc83662c074d30110404433244421d80327c97611341883e20831c046c13b674e83f505d279d9d18d749e5ea8e5c4be70331aeeeb0fbd7e5eedfa9fb979a5026be5d1c1e6222a5187376f4bc0f29ed9c735ec70875cdfb90ad1d3e2355e655cc6faa99f9b943aa4c95edb1a3bdf90fdce5a3618a90d0533dfde4f97ada6ecc2e5a7cf5d3513bd455ad14f7ccfbb89942e69c4098b3ea68568e19861863942dcfdba916ae4cfbe2caef7035bcd2e895005c998f2af30dd990278777c09559bfd56f70a561ba43aaccc9e22daeb3e2ab6ff29eded79e7493f08095f983453ba04c29cfee2e8ea3bb0bbcaa7771e8c251faaaba388ed35dd8e3c89f8ec3dec55d609c6e813a8b8bf215f7e42aae09e5e4a8d3bbaa399d28667a8aebe8a05ce7e43aa8db4f1f5265fe348f9a3f9947b9f3a60b2467878d99f6667c8992c0c60c737cfb9c886430946559e568265f8fa34fc238a4f72bc63182532f6bac54a19f69faaed1f140bdbc0748ef1a202ebc9a784e20aeac77329c20c8f0b2ebe56dea25be3192fd46be3ec336a437bee99356d94987ae7a572e0890aebd35f5524a654f11e4e42cbbbcd98c34b20cbf7241edf2383689718cd8f437e8fa2c092c942a339d9d2ec14a8c63841e475e7b631ced3612afe6e557d8bbcb6ba7d8a6f16abebf2aa2bb4d87b9f75736dc2909625d917ea99291708d4aaa64cf92682f7bc53edacb620e0db61f50ac0781717e38cc83f8e130c709e22c1b340e5d2718c4658ee387d3c0383038466c60fec371580fe238580fe23860fe4310671dc70f8731c2c224304128432e64988425b0216f92c32286d1a86364841d3a638c5176429c408898b3471b571e6fc43146027c2a1a27bdc296cc49f8a3c730224c9946b541499800ed497a6d38613d1b74e5f6ab61e4639f2a61364c41951081785723f36d7ec0e698c9b2bc8d16ed51cf65c6866cb15c1eca9dd707855aa7f16f2f352e74d1b8d03563e52c17886fbdf37af58e6c41d78c5491c72a02b4273fd39e8d8611c2f29966b918125a8d1be33464560e44cc5baf7183388dfb83cc852ed8c984c0425229cfc015f9b90374443c4d7d0ce231d7f9e1ad6f188671d0b8c958cefde11a15058157a4d3f801af8aa0f120be22611c34701097f90f5fe190f90f97c13f7c46625064d20f17bab01f2133868ff88040d716735bdeba2c67dd1887b92e9f7101f0972be335c65baee372966b7755b37223a06b0588980b5dad0b5dac0b5d3017ba5e6006c0655c4727c6755abe721d97ebb01c881f2e74cda040dc95cb72a1546991312e942a008839322e74c5b8d0e572a1abe54217cb85ae950b5d405ce802c0059233235564bfe4e6b527bf972cb76cdbb4deb4ccca2ccb321a2424060213f9e1f29e6ca97e505dc19e48fad16ff4da681bcda2589a327d916929d31d32ed327591698b4cb74c57996a99b2c89494e98a4c5fa18c76aa22532cd31499d24c5132fd8432dbe949a632d354a66f28c39d9e3245654a1fa14c777a0b657638fd56af8df608d09ec43e438066912e49f5cec856c4bcf67a2707918f16fb8c0d0c9fe825a594aa783ef4900283077cff6207172de857f42c28ac438e967e858a5e057d0a9413fa143dead4657a5bcaf4a64b5feab8db7005534b6ac128887ae464b9e4d404625190288994e2d59e1359c225599230eac9c32420c90182524afb1b5ca124ec336b4b31fc43461aab0ffd830b6a375fa3bd9e734e1f373b42868614c59c202f1e1973e8106ac0508c31ee68af310cdb215b295e373b30090d94884366d084fcc126b985687024c72059479ed823634d133c6043ee37c0a6bb1b332ceee1a32b46b94799e36dc66e2a3dbea14cf7187dec281aa2477bdd2ab812577c1138d99ba90cb0c354eab83b3552b539b3d11e36c08e1ecd9a188b5fdda08fa798c317a0d900355aa5278dd79e124aad49a1892241358820d8ea8f9a41a024f79061135a38a20525728b0c9bd00208729c32de982402d5d3781f49c4897990b86ed49c471d886ba394bb3cb1d0564b794c609a309d978714e27224d45dd1a31c88eb745714757a14be3142b10dea28f8e604bbdca47e3a1057d60911331237279e54715911b1f19800fd8a88c803b6875d97475de892b766123dcc33f2f40c51a26eab6d032262f2c526b9e392dc45d128ca9c9f667d1d8fb49452663726692fa87fbabc3d51e1af06b5476349ff2210e9316bae0d758ddce89c7c848c228a95121246e46907bd130572b78098939393d34115141e580755e4b32e078cc2754271f180ee46e564b77da31cea1ad1b80c470ae3405d1b628f8047f6b028037101716d8f475d1dd46b744e0792b797b419d823e051862e08639496681674a1be99edb58e8819d9f42de350d7c805ba1b3327274b8c84e948fca8b9832df23f54d97e3eba1b72461a63c4ba92c517e86cfa26619c26ccc11559a4ab40be9566ebf824e4fb7189666df8bbc9f1fdcd2c712c1271accdca36595737b0cb6397f80234c725300c011d7148dcd9e1c99dd32cd9ac8893f0d1de8e1eb0e8843a4949d4499afa64091b468f611886517aec73524a29c51fa5c728ac720edbc4be6920d7cbcb55ef73c9a47f3199544426652633cc08c9439ed2d819ab15cacf22a054c1e625679160e3651c82ddae3dd6e86c18c6f74f7ba40e256c5f85c56713d7b983ce1132d229823036c8e3747bee15853f0d6414d0175fbdcf259bfec564530a9752a55409f328fd8b46a02e8f9210a9db6f31d76aeda7ca2814fe74e4d3213e22661ea5d44988d2adfde9c6ae089443a9723a5deea50b338a9d4dd8d3b9984fdfb25cc27289e65249e6128432f0a5d21bcaf44ba5d3b96fa75b696cf7ed94ebe9c2daac13be00cd3cb897be6ddb4d3fe1eff9f4cdded44bf77b2e416ffbd722973e9b4b5f0159a5d25550c6bef42a5b2a5e1a42daa3dc93a7b8da555cd2535766d453d75e1e36fe56e4d3b7abb855aa9cba224e8ed20921330aabe0caa974b99f2e77fb713fc1327a234820f1c3e6236214f2b8065955d5f901af1ed60959ddb304472c07a49c2cb11c3122325642c89c5121fac43797640c2352820de5daba2b675d96bbdc960771659c56c1be3cc699b039bae0d5f6d657eef2896d82b80c7c1303afb6b3cef2203024f46e99be7aa80f5d621681a2483bcbc58139cb572ecb7162bef295fb72960bf3ade3b61bf33cb53805825541d9628981924245df071e0e03df9fa45eacc0824cefba2154318f71677447b32a62e52fb759f9cbca27b661390cbe81394bcb636ed3f29801c4f80c7c2380c79831352e675c3ee6d6a386316aaf63f1ade90bae7ca10a41d7475f336e13f31903788c2be618b699f11af846009f81571313a971e89a717a51728d3b6343aac8015c01b87c06b652459ebede7dc522061b997f0c0ef3cf25138989c13aa44a0e385485b4cf66d2537085b999cf4b4db623557caa8f125026dee7abd80bb46e0855460214f3952f00e62c2d17c7c83ccecb5b4e326c69f97c8d79667746c6ee4696b52cab1ac8f503926b36efe9b176406c99c71a665956634773c4cd0ebb2368b26fb0a337879c299f57470a06bbecf55aca4cb9f5a8364989d94800a743f60ae0d69c8691addaa39d92c1caf8576bcf0f973f9cd69e5a64aa2e6bcfac469a51edc9473097af3946464dbae5e272c9f3d6d7ad5eb03d5c866cc1907e925af11973988ed1a634694fcaa63031303bf40b08408d98bb9a1fc0037098bba2b888013c005f4d8c63003800f8c6884dcc6bdca8468d0b00c71e7cf37a0cf601838dcce7489598135f93080c0c8e3fd1e7e533a2cfcbcb8cada59579cd912d1c23da715e5ee3f2d9916ce1cc7800620a8bc38e088dcf7476f4058b630488e3c43c1f07e633a84c95d8015c008f79be4dccf381c036309f89356ef3826f8cd8b83ee350aad4b8866d66e01b231f911c23a08b0358039de3c20138bd27391ac51ce65fe7bc785e2b6779cb63bc56de721c2c8fb17296cf74762480cf1c6700cfc711c0677ea47d01333e802fe0e502f84ce7bba21fc0677ce6ae345cc4003ee32b8a710c00cfc037466c66fc45007ff90a8700fe7201e01eeaa0cfc05de4051ba15789c14f07bda2ebeb21222f2fb88da48a2cea826d798cd77800def21ac711e30168798c005c59e37234b0cc912a304f135816b81ea5e06a2473aad196651dcdfc06e3298585961da5b06091f2eca7599d251c7c88f0b44b9e859692931d6550549d667129292929382c6c824891ac3de55bc6d1cb65d9d1d4c05818dc01530c9a71a3d04b0ca2b8e664540756c6bfec8874927a774640d74b15ea00f0d5612e8da12f1618bf527011ed7ac1d4a79e6a507b3c52aefd4b7945d2de8d145c7f704dd25ec7d32a0549b3e42a050bd1392513b244b36013394259ba41b674b89c31e4e8d3ac143760f2039462e11ab0ea045c91d94eca51291d0ddd289197cf347d912a12a02448da931528455302d79f949b05696faaac4e45d2303249c30435ab569f7aa4febcdcbee00ecf4f39b3d74e7b32ba55112f5fb9cdcb5762fef2896d60ce826f661c06ab18066769c33216e443076545ed0dcdb85950cb8db92f1713320dc1c03ce06fca638b3f9b3ac63b60432bf0e7b9c09f973f6ca805c6804e18fb9181b11f3ae9a54274c85af94f1f4a54295196a74cd87ad82c954fecbdca96cbbd53266c0a95f199bd789af55996d6ca33fa9aa7f4946785bedaa33c54487b12531e2a64e5d2ca864a29b6a2182b7297c8f3d829c48a7cd3892c1f31191723a2c732c54032a6848d8f817964ab0543a9e25d1e2bb293319f1a5827da933b4f648e1a65970b5d417c1951964f8172bf0ce8e3f20f178949ca98c85c9dce8e308a519c617b524996a74445de5dd5acc8c354869d4a7b2b7848a83d2a94257d513a91cc9f6c2723c5dc5ab99c4836ab135f0e616ba54e9f964b974b1ac38587a78545c657b29d6f06657919f7e5c21efaa23cd9ce906c518c054bc2f4881a5dc1f6f0f88f1ae520d868f3ecf780bf4c6629ffc0bb21e41aa04c2d62d22cec5c76a47debba932e46aa474e554868a8e868b337fbc194102d6996656284356996c519cd7cda439d444dffb021125d79a9fee0ea831dce52c532e966454cb2a339734ab642a991973ffafa3225664eb3261e02e657b32a3c82a2593acdda09d22cec320b72b3d7cd84b49d78fe4c9f1fd8d80da1a2798b3683a23dd9c337d8d12314c9c4e80f5d4208d507247743da93aa8c0d61440d239fed6446d91aa0cc2f9f0545562dedf017a6bb581dca14d5492a5e53fcc41eca16e5647ce53632be826f8cf8f01b1c233c1c27c6572ee33e609b97b3e01b1c97b7fce5f4d6185fb94d8caf9c076ce3f296d34bcacdd152ae47ec8ceb186189b97c1d92ad202ecf72ebad3eedf9a490eae7122cb45b1501f3206e03f320f08d1195dfc438cc55b00deb31f8c6e5ac5322adcf741037c663aecb5b57b22ecc9d2690f7700aeeb29d1887325908e08abcc4ff54e48bf1bf9a2ffedd812b75a80ab1fcab424540974e0c97bbc8181248fac440938114ca8ce08a3cced600578c9a05a357ba7c81bf994bdf017f33bfc890e7de027367818d52f05757e0afaaf0673f950afca98e82bf7b29fc79f8347d2c2e62b1c9f20fe381f168b7d320ed12c676d865dfb6e622d112226c069324a4bb896591644203fb653b3ed566b2a371b0a467cdc26aca49344910e9a6e00f0829c35d0249956043edd10c499643d3a75993fe2071223b92e5919f2433a85973cecc275322cb531f586cae64473bb2b582e9eb95abb52ad5ef792e2ed90e0c38696fd80c5ad13569a43d3b4398926e591a071b77625682d89261fa233ed369d89944d08cd14facd1c0ceb7ac50961b7da4ca9c53fb1159d6b4cf4b83ee0603c3f67ac01f4d92e54ddd750289ce5fb683441ccaf2a5fb656cc8f2332e4d0d7d49155973b2a3f6e43ffaca8eb2bc296f949bdd767a4f79c3388a61d465ab71c9f4ddb1bc0a4923236ca85d9f34caf2d8906cc578fd6c1e8a815b6a65c1946694ca381119a79892f62446840db547b9605d869eb02c8ff16f62433a2c4a88da136a4f3ed19e7c8c8bd3f21867b92b673929c38ee614dbb43c46f591815d79cbab4f969f4bec87cd9c2d589747d7378d64ab566be1ac425548b6a68f8f1350264e9f9a8595b3dc66e52c2d5f79866d581e03dfc438cb11fab303ebf26ffa643f52453ec6cd82a48afc4acbed4e0899b335c015797ab18cf5603ced5122d605e3e9ecd9ab3d9cbdb21dfaca7632a02c9f72bf4c28cbcf4b5fcde269564fb326ae003dcc7235311234f4f3da850ca14ad06c277b6543b222d991e99321c976b29e6c89cc27fbc980be3a7dec4f7b72fac4c07ed98e4fb6c393cd099472bae22cfed121591edb6ef08cacb362f80899ab3decb2d3a90485e1897d66f88bb94b0076e973609462a78d5d9acd7a49f88bf6399a65ada5b7974d6b8ef666c54ea4e51b970579091992f59076f8b6c1ec4ec95128e6916cd24631679849c69ea359443816b58775ff62f60e671897ed948efa29750ce5f6b05bd347aaec6499cdf0d7832b653b275fb93fe4f439b93cc15f0f0e059faed66351b8079751a69f6c3fa5f00f9951ff7e0cc1a37e6614e661c2d8b9dc83cbdd4f93e6f9088648a3847974c7bebd3b22b0cde20f4887e58c60882da46797a638ec685e7ca6b34c85959edd09a8320feca56f9263b92b3fddee2eb7e5db2d19c1f29567b77bbd267b3f55b61572d88ebc61eca6cbb55c97cfc8206ebb76bb967b564915eca70bdb73f1b6585b6e8cfa2258be72bad95d6e8c9b2e57dbc3608c6b5b05fb7637c96db774d3e58e9de36e77b9f6b6b75cdb2adbb1fba9f2d6725ddedd1376b763294eba306b5f0f558e0886a21c73ea299ed22447210ca25cf34ec6955257a9cea1ae9d4e6e42c19e1d4b1db3d92bdbc982644248cf8eedc89508ba5ac1bc6385adecc8d961de9167fdea74fb2425203bb60096af1c3bbd9faae21509dbb0e0152c0509c35a8f0aec9230ec92beec24acf5d80cf750a9c0300f7bac872a639ff7cb700f553e9de2af872adba7388aec88481dc3b3bd13367db6679a58ebae75dabc869d669a463bed254dc332fc95fe4366ed9b14a561d44ba86b57e34ef1b7954aa7a5d3b7d0a8d6e21a0cec578db2fc2a66ec13778f787523f5f9d427c783bb0a83dc559f69d5ddb04b5357a9cecd8d345b308552a5fbbc5f0f55567df50c232275d5617703bb0a7fdc31fa0d76432c005bb92c9fd766e52c9d5dbc3b2156b04aaa7414f3e09efa26eea1ca1c563dc567648b6b55176617f773c929bebadf8e9ce25c47535281a1eda1ca178839f599ee6ea0e4d45fdc99bad977b8306fd953f307ec16cb31fcd1a7f896e24e1f38d8d4bfe9338fb4279ffa8c291879871d2ecc2fa64fb3525c7e1e4991e25cb7589ee21012e59966b959905691cf76281154999fd197449e376a9e983611d2cd577b921a51a366b1c054086dd2ac1598c8ca2536b482a9c6cd211839e51f3694e5ab50b3522e5f9f68168cf9a7a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a410c54009d20f1d7b9244aad1abdd4d4b420794d1787610edbcb243a13cb1970ec4359f43b6badb70ef8ebdc33746306cd3bd846f3ad3b7df7078550f5d25ce76a75367b96a4f477d6229547722dd92ea7d7b9e7cc9747b3ad90e6337612f61778724d241935898b1dfc863d846fb4d5fc32b8a635c3ae677ccfb984794d2a901c11a4b03ea40b9e6d2fb95ab8ffc6d8f2452e9156f1f874b5d37843d8599c2bc6ddb56c2a6d2b5d2b5d6de414ad7360de4123c954adba699ce5dfb96955026fc75ee8ec25fe7eceb57eeb652f6eea5fbd95caadbb952ddce957a48feaa767994ae81bc65f5266e6b21f9ab5ae99ce935abfdcaf5d7b697ae9dd3ae11b1bd64e2ee17b38ecbb4eef55ae91bfe6e94be7d7bec1250faf6e6de41228ded9c49ebd16c3704ea1be66142691aa7a1b412a7bdd31a289bee7661b7957089f4bea9cb8bf2784f7aa754dab27f3fe6b7957870d75e7a9720d2a8f8fb31bf7a0d77b0fb4b8fdd01b4ed26cc3d0bab8ea8144cd4c6c19e754cd1400200000314002028140c888462d17840a6abdade0114000e96b054745c1667410e63c820400821000200000000000120600044446a25fe595a2f7bce3f629c1b1dd69fe5056ff931da594f0baf24bc7e349f84653530bc8040465a001f1740c25b656cedf2b4bc2ddc422f9311847e74f0c16b2addd21a5a31cee472e9307bc2765c7e829cc3b34f059047ada26c9f315b5bd24ec5cc2d68c1ad73066c1435a23403004d404f9c85f97f0da6f95eb4adadd234a8ab9fe4aa247a0ddbc96c6a271a7944610142e72ca6442106c9825de68461ead32e33f390d6afa1bfb77e6c4d606517767156ce2ffd94c9df0562524751a96f4268e1e232dd518e5b1e1009b8cefa90fd5b325e23013e8ab1ac6f8cceb251d22c160b4a1e502a457e3c49fbdd33b69c6c2f91fa11c4134008a57e3a69f042c5475e33d71e4a871a3bf0827086d1dbfd10b22ee5f9b26d88d045adfffab9303e70cb01e81176dcc9a9cd84e2d16eb43fc703eb8751bd898f5eb522481fd7933c5465398d93c320ff3c26399b21ecbd2904944625c6f9e627acfed4ecdf86c11d75e26c2e7ab86f123116f6ab266fddf3722f636cc8a609195f6f9177a4196a9cd9ba256802464a1d7fd1e33089b4694014f663f80392d516666f18ff15010e5202f61b60c3f009f7c5e1f87f82a1115ad7737db4c5191c11d65f9932dd828ac5b32a2c2cb907971045133f69c3b30d97dd1b5436dd60cbfc1b179c7156636cd0bdab42a84d1bc62ea2c7d5848532644bb1aabf3f5d224ad9823f4f2ae4e0db64db3c52c86d159bf014985b46b7155a895cce1e166a23259fe88919f34b5ee482bb63a358fb28ef58e7890437f305387ec6c18a7a422a88ed89dc0a035e05e5142b338a048cfe481d8e0c7f69f577a2d1bf81fd51c13f91c3f9cafc88188e9c201a48b90f4fdafb1f466838764ee652ac92ae068757ad5a2d44db285ba0b92306dc9162b5a13a97bb93049375762658eaf740b2e2ffcf137c24b8bf2b8bc4fc5a22d0ae29b656999a88291f07a4ef8ee18deecc3184ea81e5ffa0d44d5a1d932a4577648b4e135c520035ffd40e1e4415f114cd3445442e8738aa7d5678cd0338fadadb5d35965f6ef35022105700d71cd3e84f88e57778de752a15596444cf6d21894a499a4be326f05b91e74b7e9f21aa7fb0002dc5883b4fdc4ba821e0c6277fc583c1f448bd4cc4cdaa687104c27e19621ad6a6f2d0521206efc95fbfabbd12a5bf025c37936dc5a777c1c893168add6af2fca547ed7e33d3ae86432445c0602360ee3477f48cf0c996d708a4dc971801d2d1804660e49c3599db96ad9d9b73b6e552d945405abf02ee90b51081b329afd4e329b096b02e62c22d6719d69fb41e7b7331bb226cea995a7e03152fb182406ccfc1cb70cea9272376591e3e2d216e10321f586d1fba502e2f7e0c51120089d24b1cc7353e67901aa5b93e271767a04f7094f5371ed6531d21e90f0cea518fdab8e4869a5635cca429d7cf80209a2c05317b523ea394e828f94fa2d63f2b26409b62e4bc0d898db038ccd9efc5a41420fd312c2f0ad3583d1b74efb7dba255a114197aab87d12d02b6a61b3cca9796cc9775f1976fa3b98764c5c09451daa5d12ff99252dd9270855474db54d5ba662dd70a0f33eaa7a3d044a96a78315a112bca4c3347cd20541cf9d2cff1450e18edf61d5d6d6dac190367cae222f202f1e689f75c3d55f4b652ca21355f4e552d8dfe4b0d82758c259d4b4d21a230d8c782178165fef20454c2e668995d9e6fe8dfe4c61b7628f893175b9ee40445e811b879af6feb33c412e4d3a2591b8e8ec439b300a865f0acf227e46218bb486faf5d3e63254b3d775b9dae4bedb3d013ce29fc69189559d8acc76514856ca47397600f7fcd2339c47b676919c49f59909bd82f24f658b7cb7cd20c3e0591b73a08343db16ae4c3db80f8c2bfc1b465dae7e50ef7812ae1022266e45ead0cab5fd175ce5a1aedf89411b2e25711f9ffff5226edf30b781cd9d027cd8f819a7774376355fa4e46d18ccd50d5a023bcc9064ec5d398261635001351c8c76d2169b143e097fd00c05005b29647ebe140902d3f346786714f196505460862dc7a249885e9a0c4f3b284993c7f962027c794c77576cb9f57dfa25ca71c7698cbda31f9cc22f8b6f1387e711851418a29fa216e027537aed9ce30ade812e16aacc039ee059e4d3ba879c614189b11fe0d06618f7039764164a6645eeb77668ae013aa2f27e464030f8e42214bf0a929148b763d786b01602956e33ea7f7a5cd3133d5511abad2bc4152bafd5b406f74b02d759b4f6d8ef6279ef7431028203df569bc0a079c8f001c2d2eeb4400025694fc7d884f1e4103cedc183dbb382cfc852fb2519f3c47bca0eedb588e596da6639bac8c723537672db11e7c961d459c27a86059cb8b2900e9f09825186cd297e98aa48386768b15c95af846eef4b3d013392d3dd2455d9598c3364f6f761a67a5afaf0db8a4e237b9ed4516f32d848962321405d8565f5901665c75c23cffd7602f6d45c6599987504579e43d7443ed6aace58d74e4932e6a8b5bf460d86fa4b2e50d117847c0aece9231d19f82ca1303c78c3a888530a150cfbf20a836f06d72277788dd58d939095b84e0cee6fa55b8628ab67fb645dec26eb0fdc104304c04aab97375761cf23db321a3d189d7635f5b005cdfd7d48dabff447a7ede8bf185c538ad66e0c7892ed7fc219768aa373fc80b8ceb632547c3c98df32bdfa202e06b9ef4bb7d7f5dc21cda5510d2a2c3a62174ff414fd9349a7d0780613b04b1d2958f758d80c1700437e3ee596d66288c437f4cc130a6872bd5094313ad2001e2c4281433f9cc53f65ad8266c1367c0ad069cf8e805b4b06b0710793e3c12f227b007eedbcdd9219a1b592322791488ab1fc977fa2f53724b744434e63939f9fb948b3edb82c67e652f76b786331932d60de8aefd34dfced281f0adee45698dc03533a47165b9fdcc9c94a9414280a756b5800462eaab15320efceaa8eb7ac916cc6226e8f88dcb058c33bea6e16f01e1f10450b37069f40997329989712907d0db7470c31dd4524824ac7cbabb963646f0b6a2a712b2f7897476415615c11d81bdf777bea17bc3b7257e34cbf875fd88e392f95ab5477394099437ec32baf25b0f2086d553247e695d88265b45dd782c7efdf13b9f5233350ad1f5768233a6228387e00e3d355c0b60971ac7bd1293e357f1b5b44829cdcc8ad660374d6e1e05765e6afa0f9e14fe395719b3f62ae4dd8e4d51c91c5523758d213800363b2550a5b3cb7e6702a56b32fee1c108e0fc528f2d5283079870e87d1ba28740520010228572778b262a4d80de53d5f3ba0021cf3ad10a0dfc27adc9107e0a1a3e332435500e54a7ec3cf0419dff9d9ac3f5f2635bba3e97e24fb5be753d174fa895725144aec624da0191c0f11e969f4143f94f01e67730ee45a292d12cf0b3ef57add65e0f95111efedd73ac267b7ed9df577b5e8d110bf13bf6251555054c3df7988d7986a1cc95069dda7ac88711adcdf0997eeafdb9edf72ebe2075686252c77ea6f185e10bae78f8cd0ceae62183d2ad3f4249d7322fd50a920353758185f9ba0118e277e8cdd8029310cc77d34882e782cc6174129293a95fd914e44ec4bbcaf425a30b0c2f9155401608d967259e0e0f8ca90918da093e52ac85c9e01b5e3a710fd7219193e8e618baba21dd0b29572f4ae63cafb46e78eed8d1d9dabddf26b7bbf19fe7e04fad65f82c25d60590355ebafd2c06f736c990a56506e1e727408106910aaf36c8b527318a7be17699fe0e53ed62a4ef49b665207e044e31f125c407ecd804612eed06458aec74b886dac36382acbc41c242ec8f2df665466d7a2bf11c3aa622d7c70a633c6cd598cc511ae05493f423d14bd17ecf6156ecd425afcd15e834634cd2c379c957e06b6c9ce5fb210f3b69074bfb535128e3c377cf988e355c6f54137c53eb7e77ab553d38eef71cb2db2b7b4d8871b174d686a447186b43ff9e1d6f9a66ffca23813f3be95e27014377d93f0a1d2db05fec1cd21bfeba4a1c6920c65f58da86bcfa58c50f83f1b6b9900ba1bb163ca4c9cc29f6783ba6786b56af0d409ad980991b3e7148fbb01e1453ce421f7e2c0f9fff17630d1cde46b87ac15fce2153f2e57655ffb44641546c8edfe8a7fd03e69cd2eb88073396c08ad03ebc287459498389729c39bd4933b26f60e55f95ea54688cd9c279a7efd7b0dab34eec7f7177d69e718bb630f15cb27829312751b073926f8a9fbb6565381063794d47b6989908770f84edb671c4080469388f001fab132d3324275749de412e9e64566dd2f3369748cadccaad185161a2ff0471d30591c6d403fce8bf96859571edc5d3041a3cdf15c4ead3b44b275afd8e4c29e337fad85e11581799680dac5074e38373695be4eb76a97a38078346057be7df28bc6fcbe255f6c16ec954a5eff2c28b51075598e27719bb04f55b06e188418b744d471b9201d8aaf8fa1a0f104e8b90eebcb9d2ea13640999885f2b496692b6a14f58bcfaf9bd82225eec4396718890b90200cead123f0eef42cf114444945376184feb7d15079fbd2947c30bc8da2ee76d41b4940998b5b2daa892dd4a43e54edd8cf7605cbdec3c7f453f0f5bf679e0bf44d0648be51cd42c04899265bb8ad8fb832c272a13f8376c5548429adcbe263fcd63f6e637a347be02c3f41d42f47e26ba88a13561870e7b0ba177ef02f8b9634308f1cd222364297edb9a5f7ab544ea37a6f0d2c7e4b1e98818edfe2d8c07d3e5520f865d26f5dcb6c912b67232931b8f65af1bf99b3dc7adce82520156b964908d5e469cf24c4b1918c92d9b4c8e9dd3211ee0519ef293b7d4d8d3023f1f8be2cf106c5b93c90df19f4dd714313c4695a3a033f81249a4a901fdf5ed628e0a52e075a26555279fa94e12677ccbae5aa3fff45e4e6a31391bb8b9833c7616040139bebe7a8a5c12de1114a75c78254c056bf2a19b1a1cc1a72f5284718118985f277b9524ee3fb6499faff1adc8df2191afc0a1093dba5ecb9b87a4d8dfceeb285ff69d9a90ab5808cd9c2ff575b8dc0ffd370c12ba36545fc551062d92e78b7b84e07df889c56c14b631c9112f94bb63b6331108d6ed1595c4a108011cc42ed1b84147fd4e4b54adcdea10cbe1443ac363a7276e7adbed0e045001ec7f7af13889959fbe6c64d367a6221e1b15004b8add9e25651e332a59e1207d556f893a5c807fb309e60ab760a41903ca82a93a57a3ee442b98536771590711d854c1c69198c7bb946c03020d1167d62287ca45c0545c0a665a2f36e4e517ddffdffa075a6330478cb28749558bdd9e181c4aae3136b170fd8125cf75fae2c637ea1dd32f831569b5d6d2ad929dd103d0c5db530f975818dc0907a64403c6b75ae3ff881d8e9321252ae9d4fede9daa366baf479881e813051c0c2ac3b7e229496e6c711d3e469ba9b616009371e5e1f4898141630053cae2e1b11c2e086ecbaeb0a0a7ea662d63ad51891ba461f2d3429767ab6ddeff30eb8c14767089818529366c1cf40e94a29c4d2f0533f9a880ce74ed749bc004ffa05cec249bb2469fabefad1827d5861ef242ffc42413f4b6bf4148871586ba8e43b69155997fac89891a67db8465ba088621c0312250b079518b9a496a864b461a1c715c2d856f958ea232d639de0879ea06c0b61b35d6ca66449770b454c3cf2d90d87079cc0a134e685cf87b6b882abb042379e59eefcc0c77b55e5a0fa21bf8c3badc968c41f92277edcae1343ffcd07faea7e1284652c9fc2e0549ad4b3d4ecd0c52529244bfabc0d130d25d54fc1e3a7e20ebaee0ed6c3622217177a7e2dc8e6c8f3bafd233ca7c47b160a47b84695867165f2ee8ee0e40f61903e8e74d55150cbd921d27e15734d80d48bd5925527bc88d5b0ee740dbed49932c169638bc48449d3b8c672b20ca599ccd20ac36405ddb1e7f10dfbe1e8ca887d68f104439e4201936588e32f84f40cdc60deb959f5faa60d994539b0815e78e09d7a94eb4e2c09fa574e08ce8c97449f91827c5a6151d6529307a0553f1c1db3f48fc7082845068b75765ed06524a7a921bd786eabc84b043f71acc83696fdf5f313c2b9eabb59853d052b27d178378f1fa8658c0735c9bb5ad19cc28cd4e130bbe7e154d140b9ec10e47d793127fd2a03be2643b6ccd2fc1fbe8f5e4e1f24f7ea6a740bf21359a09a2c7e409027cefa086995cc3180ff62f6a0b096c005dd58029c78b07bf9cdd660a4e365a9fc1927dcf27a5da277705694314d4bfb399c8d0fc64a7f6d70c755642a20c5efc16d852be06ae0c384d5eb4f168bf6d53f3458897f3c130e0476fa0a3a3467c1bcdd44a75ca1002ff32b4c238e853376fa53f5cd9ef05246afdfd91b79bf576e83ebd4156d4e017623c10ec0fdef4ac922c370c35001830ee2e385cbb55fa114d3822c97726e66a4456c266d3884146f21f3f87fab1dd4f11e989c1d0b1eef7a96d052fdd4f9264d14c47c62043a743bf2a47bd3bba90d2ea49a6259b62f76b543326be780a11d5ad231d5ea281a7e6aa99b8d251ea463627986de17a3ad537c5b5507fa0eb77f5a3fecac51ae125ef9a38d301567f7ff924007ca494adb4e2e5cc318a0fdf03584b2d07edee55afbafc478e629ff0d79cc243a5fc6716521790ed86bdfc0713d9a9b54ce386dec1bbfad6d56654885167de379345195a18e8937b697ac501faec6d362a099dffd8d998b2d861684e4e6b0bb900b5b62d7c8dfc779961df1e96ff0641466c21f04d7d80c479f31fdbc5eef5dc14ea7f11fe5c95e72f6b168b26046578e0fc3797974bd52a43b1483232834793d1ce3f596d00e019a6b02a74165a5c2e69b311f38f8a3f509ee4e27f3aef2f6e057242a82470989c36530e6bcce6fe40f8a033dd6983eb6214ae838c75f242644e097b65cdc134e5bfe9c1291eea244519665410a1f4eff1acf9c72a1a99387b3bfa12ff071b3fc22afa8b18c7988ea1521daa946ecdf8b8a889df9fda7143f46fcd87fe8971dd30a7e2667471c7b430611b226d8ed8df05666dd920de25af3a469fadfa3ad7b0e552c4af3c30e8485630bab9f25c1b0f6092f1db470d689060fd151ed8fe72b6ad62802791605a37328ad11cc572652a372315e5e804c5c4bbd5d9d5e3a1c5c50b03a3d8e6813ec8d805f0d86cde018c3b32bc1306e05d1702e1fcf25953369e44f27c1e2f7b50e0c561b5fee7690bcaec7b9ee01bdde54eb9bbe82e77cadda53edd4bf727fd79ae9c5de2f3485e9fdd591de36d211f6bc18bde92f0b708ed05364de1140a1b540f2f6a93cc2c2bf3ca8363de65b4c7da3286b4a481271e9958c4ad43c12c013c89869ed28ad992c013b20146db0e02a93ecddb7bc3ff3ffb44e988faf7f9501c5ba249c2b27103b60b3a3778b968d1ff22acb8665dfecb63d2fbcecd5f63e6767c44fe4b5c0c7b7e26bddf638332174c63d7e18518ee53b89fa4d7afe2f15736baf324eacb5694d599d3a9c1c6532d052e8d02cb674f761b5139613f0798de23303fc95653c62d0c4fe511f94c6ade1ccf3a4f17f4291e6c7ec4bde33d4a61bad617a5f58aa77845f72818878f41b334dca358437c0509cd05a2f9cb36cb57c6c8081cd21871e52fd583ac563b8b9818d81ec3c3fdbb5935c051d3d052ac2743ea1af16ef26ea4e2afb64613b13dd89ace0bbfbf0496513f7193bd078709b5411fe48394e116c542c92eda6bf5d013ae80eec33a2ebbf69a49ad1ca99ae742dc88cf44d82e3c9b4f11c3acbce30c2f5e4e1ce31697932817548308d3189d990b6ae6e98a0ec4f3e4d9e112b6af051947f5f114551d72364651974efdb91c86228747a0cee3889e13dd5208d59688b606ddad87f5bef718f729ca9978756837810bfc0cbdb4d637713eac031c71b3c817cd53dd62d6050c944ab78b31d46d8a34b323e7b7be595ce0851b4ef610a5925e504d323eaf21c0528224247e092fcc61529d4c4aafe887ec0049a8a017d4a0182dfe871612b9963fdb51c5bcfc343afe8c3901d950a981c4af9914a09a4cc4997379731dd3e3afc3bc64a802c600e3f23f822a0ecf762d277ea60174b8b1d1b958062a11c5e1a33e22dd3f7dde8856f9b3a7b77e98e6d145c753650036ec6bb8a63ee2c5d6a0dafb779d01f4ef2d6420c647621611dabd26068054c893f553acae9ee1a19b9caf359700aa132a0462342b661bca60327cf73c5ceab711cd9de8a11cf682caad0f7da1f56e1def9ae3d402d27221483065001879aa0c743989332afb0d24d064f898694aea8f71882827ecc6af42d9b042681c53d5b4a0d9df2101c422c72622c5e7ef1d615c53e29a01b9a6e2fcdc86b993b43933dcacdf6bcd5300f25e3d4f43dd00525b396b5a81312a169906d55efc335f5018e72aa842c782706273b11960d3c21b408ad35dcb8ed458eecd5ce9c02c10041c6a18882b99e92a8213f1be610aefa6f548e10f11e2e01f1c0c60fb441de06e74fc291e1afba5021c7d611f31752a8716ed312e1111d282b0567653eecdafd4e0cf440be6c08023847d4628c3d3e247b7dee5dc70744f79ab2f51f8750171b8ac8de83837fc898eb9999f7b0066125a58ba2b82761aaafb1b8bc9e6df2f1ed5ec30d0d2368283c424cf5f5f3442e7db62d26ff448d7ede0cbb70c2fdcfad8875c57928e29b17c58d3910eb7bac54642fd2ad23bd7f1ee40087fca1a6ac4ce35e3336d2cfb2709a917a52d9a8d49fccdc9aba771e02bd900c901545b6ec452abf7453574343aef51d6f778b6998aa5ad2f4d8bfae0c1855f5022d392765226eb1c607421f2b025e1c15cc6b59adb428170db38abdb710f67dcccd32b6d0156d512eb7c6a294ddedae26e7f2a9771c76a638e0ea77b9f04842acbc0e9b5779c22cafebc8fd20d5ed6e55a8b28f839387744d7dfc44d77bd3a0344c410e08529c930c0f99cabe0d2fc14812226248e912a112a25d9fe19d5d26bdb9ba9128a8bd73d4b93c02fab9ad663d0485a876758e0e434ae1450ac2e303afeff0a5ba23718c4032ddf9065abf8223464defd10cd5303fa22e6faa3e83f4c5bca1429161bd9d9e06879663cb1519c0488bb90130bd1e3a2e5a690c1152aa8d8745826140c3568bbf9cdd6f169485cd04eaee2aee789468bea936c8f1b4b8184c1e4bdb9bd73d2e8816f9487b3be6397eab699d67828a43edd2e60c05e7e8ffee8b787681dda9d93e45653d365b59eb6d4cb1fe210709c2191275ca72c7ea85c2445f6d06b1bd5781cccc8aaca84bd49d719fed8ee684216b89ba30d973500f52822bc7c0a9ffe39d703fb2ba830b96750fb632c558e9e9404a88fafd64f99eb8d8114599e12193cffb383f458136449725c1ebf1ff604bb81a6994f942aa3b603c70cfe6624c7b593b95efd05dd6ca24ee0bab9f9ed19f3242bac505b10d34c3ab3834389e119e9042dab2bbda6ca38feb019627225374ba5240e80f9ebdaa99057527b3227a72fd807129c13b7940ab5db2f60d775ddaed2c5f02b8f349ca519b222079ea59c1805172c75eba28397853a2ab467aacf21875a751ed6fed58ed6890841abb348d5586bf9c3e5df8999811fcd452e468f1edbb312fa25938e07b32a7c43e9e75e2560844780d50941a1646e7445b3a6c649533f6052888280cf4da1b57d923dc53af611598e6324436901e3db71bd63ea7977dc943ddbd8a5b776d6c9ba88e928db4f5101b8d104e87f56c9bcb8ea891f1f0bb480b7112e6aedf6009a54cbfd0913c67335f533b4da3c92bb987e9866af40cb579788281a1501ceffa48f8c43bfc059884b3cfc986256027309185fde974537db01d83ceae4ba1f375828a5f76474d63d32ceed2da53fec86178265b9527f859483052529d8f65f12ca33be893fde2bc432f6c31350b04fd580f7b22e8b1ea801f0ec9171ddc1d4895ad850a9cff26967f7cee3d0d7b91bfd91944ae09ea32919883f58f238ab0f6f33fc7e66d35ae9216e7970650013f5b755a89b0c81f1de0b61492cf36f0e4f116de68daeac6f175c0d4b02631d2fd4e0d4e48ca58b33f4cf3afda123df7593e5c729ada70a6e3cecb97d720fbfdb61060f99c41a79399905a5711e44a97b5c7abfab15c4447fc0b568e8f0201eddf4d7611ccfc08a9ad30effbecdd949e65951607a0aa7b08d9d57d4c13a8f2b20024f0d251ab3cc813e2a3f91407e83274526484ad31ecd8cd94b8ac3edae6023dce8721166d5bd27e0907030b91f22c261249ade82bc330f5fbe2735a1377ea0cd4ee6686518d21278c34a23ef3c85bab085f2d0a35be1c58d06748f0ec0bf3086ed8e6fff57718baac148dd268be689242c7dafde9ca48843237ee9c4d56c273c6394e0e6dc24235205ca26a80dd96bd3b602a6f70cd3a625580423c748d2be8fdf235480fa73af794924f439aa8dccfff69c56635c03e780748daf9a3e1e4d4227676ec286a6333d695cf5cc922e555e92d347bb1ae801bbd30ca47de54fa30f6da114774ebcba9b5198f629ec6ae3b30302584ad7af4f4986a8c675bfb9ec89223120d3cfc0586c63d623e64fac19d7aacd4c8aa6e7963e1e9b7dd60ce5c0be078d187418262b34b700b51bbc8f497ee36c81e30406603cd713e5fbb9c35b8f6fc5cfe776ac4b56328373e7cbd23448b77edf52ca8b7a8a565318f1f01b85f61dfd324ac9bb3ee9caa51151ff38b9988267def55ee9c1332d90b59d71fd636c32c7b6c0c7a08523d0d042b1e1cb7592b5d29a71e59822f3c4d8ade44dad961447470d040bec71f4f4da23dc022f28f7526a969ea20d307153c28b3dc2bf0511c58ad120b4348fc207a121cb5d84dccb443cb6fbae861b74d6761af11b6f0451df98d322deb67d777ec6f62d96093b11f595c81fbd863055f113591adeb9eb88886e8eba7a6de876ebd95993b6b56f98b8d32c913c691f91cb8a7c965cda906234e97bb356db82ddeda6b4998f84b66e8baa5426875efa7028d4100b12dff0ac41b11d6088c04f1fe83b193e1813a55d4f1a2b5eadf91c0c7013954f8ac2254a3e29869328f952144ea2f24951b844c927c57012255f8ac249543e290a9728f9a4184ea2e44b513889ca2745e11265e067851f46af3cf48efe8240b5ee28712b7ff2c8883991c42a469e0f7af6999b1108346ec2b5f053e579f03b24f33033d4e9747a517376ac6ff984dbe67c4872ce50e0e93b881ec5689bab8ca5fe34a1223e49268b282d283584a391ba8c06c95c50a84824869dc12a4279a56a8ad500657fa0ecf82b2f1c24d1d379225f4ccb4b3dc2ecd71f7cc028e3342b6133208001c63a84e29de3d8dc2a0b212c7c6762d53c4b38a5ae0766b7ac3daaaa3ab0af9ff38b1170580917db5ba04472416f2ef3d4eb81a4d2370ec8098d0ddc42b926b636efbb66c2cd572ace53a69bf877b1e43361f83d15d2049416069a6df34486b73507fbd0400c22d0f80b4e9bf38c65590e05d6317aed8b4c979c9fb72c0438a673a0efe39ca1102f550ecde4586a8ba86ab3b35aaeed1918675d3f280629befa47ce8460d4f97ee48e024bc5af65d75b8f5893f0e5f62ad28bc165e4e1b826b8e9aca2a5d02752853e58ae118764adab38540cfddd888f2ee3dea067f1fe1da56e98cd51afb0c231b462de732074a09cf4be41b81d7a227fd7c84ed0216f813b244b407a40ee90fe58acca027f40da87746e09bad391fc61b4d63b545112de277b2143b54ced10053281694db6155c9ccde3621b95c8ae2480c66cea46c178150524f4d691fe481f7563676d605cc582be03c3b201ae0791fb79df02fd6825352f8722a87b1c74960269f441209765706f93f3981a914067b16a7e88656d1a14aecebca1d1d9e9cc7289822425692ae8ef2d711301e1644122388cacb898d83a8be88810e7f8746839f49b35a0375a8a656f8085c0ab09272aa9f1210090c16e02e991aeb59101b65ca6e21001565ffc86606eb4dc96a3a398bdb934600f1a072a42dfcb1f9a0a65ad82f970576ecb312aaec09c5b948f2e7b47c4d928ad55d404531a66e51bb38c2774cb5489c63d91155126bf12d0b82349419fcc131a51682da509d76305594931122a0c34fa306252b389deb173e854b6962bf19c9c4c963e7673c9a5e690156a37746497810ef0d57daadf661f13811ea4525a5f835851b67a83f16cb162d4f11f05971701b94d85bd68a6e41853f938de690580b115fe186c6be0142b4aba4e5dfbc1cafe8d8a2a9883fceb6a26b82fcfc75945d11830f542b1badadeef6cf078a1a8cfe3a2edef62de00d643ab6fbc6814c2bac4300664a240733681e57a803b1d4ddaf2084c2bb6ad2199b8f3babb4143a6e57267bf68183c83d3e5a828f8c8d8dd532af5697355b0be87d1dafd3a48bc1d5b9651125ff4f763f5402607da14e68b2fe72e66e72b3b2a3254212261f92d3b7efca0c6c4134ce3576dbf0cc6ebc3336fc34f2470c05d2e70c59d1e0020746986d2bbf841ef7431e15d87b1491f0ca5a074acf48abc748901e9db3924827e1c21c7865601f90563dd90c82b4c78009e2f5fb59abed7de800437704b3baac1025b51c8db97b230ed0f012b5ad05f18923b48ea1ad03183645a7859e13a237cb572924faf11f2e32a8267a6473c62c4feb6ffc00085ac00202f49d6f272dde6d898a2369972e5355f2260b723ed0d34371eed0df2a60659948f99c0a2014232981b0c111667d4198bf6a8d10f0cc0891cf860588ffe53944310d1f1cd4e047ef270876ed100d1d435b520e6d6fb2b1fda6f317b37650df1303c2049de3dcdc9c85bef6915c3047a77ed993a445b5ae7f22cc851540519f8a99855dc108ac5bedd564d29c5c000bb8d4cd88be7179e52f34d303090d7b44e8020a4500ef2f3a3b0868167295ce2039ec464968f17bca975119d1adf7d762d5607f8213411d50dedac10022cb22d3da1e01ac0940b4c4a7b782020874ac6809701c52e3bae9364d8272564b43f1a1e78596a00065d3c1ca968f3af337c309b3fa4993f572821a301b1696fa73231ddc41b02a4dbed70dd00b3b092b9af55ee458e46abf0406a5406873594ca98ac305efaf0e060b618dd09d2452364a805f24ab633a4275dcd943a3b955db657bc1f6290bf19016c1fa4309fab44754600cac6e8146e46806856d7f620f23f3838a20910b599771c9301e80b45ac43edc579cf3dfd01a8c94b59ec7704fdd17b24e40a96b164ed2536defea8043addf17e8d7632e1a127f18323adaa434edc9537c0359648143807e0b26e2b08075cff7fffd30d0a081d685a80e64292d38084c0ccc03e797c803bb98898a801fdf491e9fb7e999bf84a856f349c3ac2cf3b30389153c75b03ea6006049cb46914f3552b1569948f26fedb301df79c1083bd0517796f0b06dea449c3af004361176b9896e70d12aae7b9d8671fa504dd77f8afd78d0f2e5f543e312b7ed82181f08bb1c89968ba032f4024cc63eed51252fd69c52f4db2f8b90f2040a151e8f083b5c5bfc44ca2f7d1ed22543eb8ef18c5ffc2e8a22fcbc6aeebbcfaf27f93d691d1021fb6d5bb8976e29924f6400c4cda7ef382f9c6a00d72d01fb3f29cf6bc0afb6500ed1760c82b7d4758ff1374f929a37842d84792444c4938b11dcae885650aa62b43565544275239eb01b4e07d55a880dd4cb0602cefef6ccad4f81075d4545690c74dfdb422f3364eb81b5dfb2ad0801d8813a33324ecfe430784e07a386a9866660f0cb6a04919030e37f8dd186300fa245acef9eeca203425e0c8b37a0e39df9dc868c373b28537a047a396d798c66e476d3537e58a5fd1f741434aa9828c507a2b92ec97adbdb13ce5c7ca744636f38c8a6721498fbc97cbd87f00be78ef4f847ec30ebf9f2830891803c0824378b82e688ce87e46528b011932b132a60bd19f9f04b571d554c8871d9956589093950247a43eb74d85654355f0fa6b130e0bee7a130620db1fc7ad5600f20e4701adf687b9b7c42c7be9df29ba910c2605cc377c7c48abd40ca5f53dc6b71125c77f2a1c774f71026712d484797630d6380a165c3ee9f8571276ee86c81a99d0212aa70d16cb381e269065d736cf050005040817a21b262705709189016a95260d37e38ced7a673324e28b6e8100a308cd6d66809aac4a46c63c27a770760cd83384c4e6d95a665ce7a8dd03287afe5cb20c5242ed9e1cdd6dd068e62044a6c481fedfb6652918130788354f6d06aa8eebd9c67416bd7dfcd39900e75ce8f755c8746e10753c549b339c1015fca8e39fbe5391e10b40ebb88e3cdac3d81c1f37b507d5f1a183c718352ea39cff38f1694b7ae78d2533a61bc212f90bdffd7b495c2c4e25421815ab951bf774d52b4616a5a5a96e0500203fdaeb0599e436466e7372e2f35e1e16d05fdb50ccfad8683e5d5b0a477bcb9e800441548b946404126fb8fac554c4bac36fe29f93d7d5f8bda23493f8ef37eba36693426eebd08f234c6ef0ab918d91449545e1f921dc3b434fb28f397282713fe2035f1915d0c6ee332ca13f58909be9511cf2a4d8d1feacebeabe3464b70b9684f7b98cbb635c7fed76c9be4236feb180503f690145abd8c4170fa8023a3ba468cb6a9794b1d932de39f4ce3e58424cb3acb9ecc738f1b15c75ca31995f353e73e4f62273beedb5499a867648091d0c6468c8346d6283f4c0fe069f884343b54519995bfaf2f72d604185f6a7fc3bd14e099fee75bf01921ab713d95731eeb165ce67383eef56f00dd79981ffd8e32134f631b1fe112b2ffe6ed0d31e1d22bb7060380627f49214b4ed7b66f28fdc9a0a5429d85f60184ef73dfecccc3545d8f4204083aaab8c9d1fd7f36f019d1a5671bb6fd72f04cfa9e93ea96e75e60e00bc036234d24da37ac0d205456986ef4b60224e87d442bebdce5734d3ccb00f57209f03d97d55d63f26c32e1b5cb85037bc16cd1aa32f994e6a5f86a3bbac42a3e63a25ec9bb37b13d136312ad0dd26e7632587e4547afd9a441cb21fa84ea5b66744082b839a823285de60815e94684751eca1b3866fd6607acfe38bc97475e05b10566cb5eb7ab8b8d61c3426f0c679c61057d6bb09a66e217c96fefaaed691e620b8ad9a7ccdbe5e8db017303d907db008cc0cc2314882c931c203e2e3c860f8aefa6cfcd4fabc917b4423bb5d343409f7c67baf58c29d478d7a17737bd21ef5e5a754c383406cf9a3d18c99e491599875259bcc082b78cb5932f37506b6e8ca8c458a3b4acd626c0f35eaa8d01fbaa87ebc585156942ae55a30cada02cbd6c45e871aafa37a4be6b46295be15e22e8c866d55766d22099ae25ea3b6754324ee2c12d3dfa505409b5280094750194bdcf5ba05fa43aa165909df1bb2124df1ec1aa0ee3a85ee8068ce113792d09d3087d03d04c84c18f810fa167b3115dcf5ca36d5e1b436f03b92634e2019f9c19480b6496e9a6e99258533042bff455f2c4c107217f6310dc3c4bb097d5676fddca8733255108fc0ae0df04974efd849034b44ab896fee3cbd3da3bdd83f867d46c78aa4b35061495ef06eeeece4376c93a4cb5565049572f67c5efaa78673f96d607b57d96e9c32ea76dbea1d0df4c8752ddd25031c7f581b872112c9fd50292b99cb0bd8b898ae0e0a38f8c49c939c69f44c2976dca10db553c2ce7e66c75fc0fd9d72d68d1d4308f41717982294552a194b1229f967e5ad63a1f26f95c707af9a9db243c7b928ea460bf03a2487345a7f0def838a41b6eb4f17b74cc892aaff214acc524483bfe4eb4e5652dfd8a05fa20cd238234b9ad0249b9ba36531b2466da5a4b48e5b5ccc4051d8c1fe47ec7b70a78c0c56a2ddb100a51fb6f4c46be366eea3cdd495db96419b9e2c28b16305a670965b4a48000cecdc9af0f8e78394ead303edfcc565c097591ba13033c3ba36ad6cdf8262dcec8bd1a6e3d22281b2a4a6ca3f694d48341bf347e40120130084be48d58743f492ff7bf6ee8902828bfb918188b971e6acd6c9204f578edddcdb6aa17a9d009ba5a2cfe679a7626f8865c9c4d17e233935294fe1abf63b9f689853c569c7b99c170afc2b94d837b2cf3bb9ecd7a9c96c04106f32505ce1aefa4d7cf0df8438a61953495a09d2ef9bbc350fd9e2cfc6caa121b26c3fc0f9de2e130035f761ae86b9cac5566219abb3f6e178f2125d64dd007dba771c4868a8eb5ca6e92bc2f47b892f03243b53964109fe6223e1a13f6a34519220249d508f769a4ca5f77de73c9842025597146dc588cba57567b4ca426f6e9aa8c48d195739e77d3d5ffab8f3eed3b8fb8e1239c6254fc592b9608d438712933bab55ce4f75cec9e991be9cf3f675ba29ea5c6ddb3f2928867718a37bef670e2c81d43f72f9830804967d3afa0f84c31c1c66ad7261c0020eb1420ea5a18e5dbccda862de368fdd475be534cf4ab59f940cf570a90dbb73f2c865eb48b44d09f70f70f52faf88620158d0d7b992ed499560d1b28454e9864da8646173d9996a4f695c6d3aef0d7d31ce2f873f1d5d73a624e9e181b4ce49762533a651bd8507ae1d9d215a88937b84e721c0db327b83a76bbe70fa2d2a4224243e77e74e79669a8c0ad43431179d4c068debe6c347232a534f14f7a0f211eeb01870e64a93c11e33437ebd775d5426fed11c3f7b5ff0309a029a0ecb1d610da2d0a9a867b2bdff2de0dfe408a7274be548cfa020c15ae38f29763841acfd021b767028a9d5b467f5d3adf190ea18e1e812c82c6624af29ebf9bdfc022d7716984e6c717fc2d2735b55e9d81559250759690f1ea2af92e7c9cc90e6b2265f0557d48d281f169cb2746f196046a05f31096bbe046451f1632bf55462a65cdc4a3973397e8e606a0a3e4f99d1eb69361ce5ab56efbac0064a347f69c0170b1a2d092cdbdedf2438eb5ad478a1348052b3361546010ff015cfdf2e0cee7b3aabf4abdb1c393776c1f9425586ff34b4c1a54c08b00cee90c24870128a5ef0dd21816d2dedbba336bbdb23e12c81f0060bb7af084212a42fb75e2024f9199053c9facf6ab21621aa61a9fe888f1b1c42df346bb087571170eed47b7e9e1f5945f258afe5db5bb3ffa1390aa725384d5824015a4063383d4b7861a92931278b3a3a9b96dac4862adcf16cf942da798a9dc9f9d739f5839de80e7fc742fa714df790a02f619efcf9ecad1dcefce2c81c2788595c2a4f4d2abce132fb9758f84c2f20d844037f2e26a30a43678ca871fd4d2d488ec73b0d4730a3981eda44a7a0c05f03cca28d1e57666b9127f318288b944cacabf517d34071b28a57c8d437beae024bda6dfaeaa1539a4e627ed903eae1f61580d1213c5fe89c44eca335b2f989516c0085c20a6a49ea40f04638a13a4e456b68d0d47da04fbf4af5fac878481853548f6a63d3d1ad68f8277e3173ceb2d04100c1979473fe9c89586b41dac43916ed60144a1d3fa3bdf318aea6c39ab80bc52a6fd659777fc6afb02b1b44c695c912a25469ff08271f2874f6ff140f13c5bb954671c8c9f706fb3b6944ac42ef09413fe8d4b013e38e0d91bb6954c7aec9d6fdc5a290d859bfa070802969ed51dbae3790b0d28f233bce098d6a47b73cfb06726593538426aa74c24f72f4ceb9386e80b01a6005d0c700a6a0c03bd05878c1af2d25c8e3ccedd07cebb8bb65442f81039865ae513e3900c101b8c31a3de69762d092deb1ed4abee2389ea07e5b4cb573297099110a0ae657b811864c9a3ae07f989fe368e240cd8eee600835712f2fb5e8086651cd1837112ac02c0b458313e1b1098750c1177023143de5952a34975114ff1f9dc34a94a5452d504844c814452f7bc82f1533c878ee3029aac803268d9c2b527d79257eacf21c49fcededcb2ef2fca40045fca60e28f2325f7a2dc74a18a7e5b228342a8b6625be780f5fa23a1d3d42107fb7a96ab6ec3804874acb05de700d5ff98366c1af4d377b1063253d344a1773092c89889b4e9438e103bb7b998d883641ff721270e068cd2eb5e2bf15290b98416f53413cd63a370fc4c78e314184b4bdca1ee182ef13860357538d7ad00a9b7cb0ce48e23cb38d82b83d00e36434faeb6d4cfc8a4530270b94e3ed591a6ba60683763794fc92814ccadb2f7c9a04970219747dc1158fc9945df7cb92ebe4d7e780a2a8c4f70479f54587ab4f25dd3e5f534f95779dea27bbfc0687ca6ceef40b7306921632de9cc577c5c4605297dc2359ce2e73f2975f0094c2a4c152d032156a64adfb44fc796775902a8ba54f27a0e0454d44b3212f6f4c916f16967c99a0193431f764d6b931adcd221361c6e0d07634ea1f00a4032e6e3bfe3c60cf43cb7fd8171fd05855bfd4717edad58a4a56eca4bb3b4024c6e31c602c748a72c7dabbe18ab0641e7fc9aeda2c1adf88f7e8c4540eeabd090490a8858f13ce19c8c836365cd092b4475fcd956089b432f0e2f64f5138e871c0f00a185bd3d1b2ec68d96c033c2adcbdce5030ca578303ad1fbbffaac6dc4ad90474d64f0e885e07ce1d228ff31cd6728ca4b00b12afe2c9931fa0d7604a3ab7285ed787d84125dd3f16c1c123ce5049dc08045149791895549ea9f1a4928c5e20c5b6c3cc7d7fd32a29f4b84aa2f830fccecacfc8a38e40d4e25612ed90918905f33e8a4d3ce6a9edb3e407ffa6efeffb95f053beb23e72d8913f3f7f117b7acc431d3d6d051524814ab900b8f4ba34b9a947580e9b5d4892cdb4b2a32baacb650eec46e3f2653da70bd730348d591e8c9d603e39e6ac64ecf2ec549411415d64f49cea5c2422834ad7905e0af3e02b43ae21fcf471f5400453a6d2fe3096d2e4ab677b0f99a70482393e31659a8429aaec172209a6bc85e603e90f9a1c47c77b6516183790f810ee97134d65385f937900a98c0a9ee712eb034e575e4a69b9f10416c3c67e51a63d888a9afc96f5750ad0a3c530a260b624d51b2a01168b36ddc4f642cd5a6b2904ef7aa3afd65eb26c8dfb3a3c484453abe84091cee08d46f6005ade1b5582ab3e75efc399ada951325fbd00afc611bd5685b5152e303c290d152eb554063cb80d626b2bc1ac55828329a1b7359f5b5b72df0972a4742906132e8f6d94eb3388beb02d2bb59f3b16c38aae1baffecd173fb593da000f33be7984a272052293fd381ffd9cec57b17436519fac042a96878fa1e8879fc1ece5897e51102b3002972d14ec3dc0d7aa3a23c498e099efed084683628d5db955e9a0a6df91ff09ae1face3af5417038135bd5846ce1054362101a32436144fd755f9c17467c354d6e0f3e7ee6708097508ebb557e144c7ba9388f374f8673646cd69dbd8c8483bd5b33b255f833a3073e992d467c711f29f4a6457503ba3eadcac800fcf1c238aac8edceab61b424367411d7227625c04561040db2a5bfd7240a8868e47ddbfb3c6710a479a75640df75ab280070f129313c58a9f4293553dcbda511b2cc858296a1fdda97457ed211056060e2809246a1140edad6483a4fc6ae2e1a4b27f29bfb217a8f438aa4cfb3f3d0c0d3a101b083d7d69370b6c608b4f3dd515e8148329acccff32cb9f06cd3e2574c4aaabf1a999d5a842905a01a283d851e0d23b89b771328505c81ae085ba5540c39a6d961ea83dfd6c2dbadea2e15ec9b1ab3c669cfef5a8ba88b837092d09397041807fa1a4700b92659265d93a2c2c044febb2a151ff8461b540be7eb64993edba46ad0d6ca8808fc87a41f3f2f4c4d864620b0a35a4006ca65fdf1ee329def4c74f40ef09fe0a74eeb2b41ea61f5e6f6890b6a975116bb9f5c3aa2b8ae7509a21e00ec69dcd0f13d1f63d050fc3880982bbc66d57bd30aa9e46e46c2da868375bb8c91e2cc91bfbf9be791fc33318dbef08c5d4c859f28bc4f407020771b2d01b828c09fdec4864b2b8be52522671bc911536bf78850a4c39a3016103ef9e527c1fb49db32710e0ec26f6e796865c345bbca1938017c25d912a68666097706f6213a650aba82598fbaa5bbf58709d1e58e925374980fc889d12ae542602e616dc0b3ed6b9fbb98dc3468e3c58f2ef2805776e2a14a8e4129ec8998b77e4dc3e1c04566fb5c0bd87795d66df1f2f1b83fd7c426511f9dfa9ff79ee0f4fa7667d6ff52f1831a90940cfa89d3d5b116b4770fb87a1763e5d0323cb1ce9da11877cec0d6534020b2c1a620d114e5b5d79898b9a465ff369da6065905d4df74b159f4410475b105b0f67a2590402ca7708822909f4a266ba4558819b4b2a14c1dab2f3c0cdf761be4eb82507dc1eba397a5ef0bb3aeec5e45884e4f44e2fcaf9b6dbdbcdaffd67b4ff4cd1e0f92b5800be4c9bb773f4012a0cbe223a7dabd8064628a60a52dbaaa3492e22d59ae116530d3773b568a91e2b2bea91c50eb6c2cf56aa4df09779d8b212808b603d3c12c58e872e69d962a82d1b699fc90dbb9da58782489933385ac55ce8f6787900670f2a6e0c946f2fa8521655a2e13cf43321ee485940597c1a2a770c8b080bd71555df55c21d196779f4edcafaf602ae80881f8e924021537fde5d99cc14fea3df2269cc1c9e2aaee77dff1720422e9efb1db1168445b771e66eaec684a7534f37d56ee8daffaaa3a2984dd4f52d5c9b34f66ca14b746c0f41a5b532a1c6ddb28ec12bc3e4e76ed41d48ca4571e7e688256d6680fcc6507d26f57987b86499037d09444a4124b95a60eb0ee6caa55db8ff22031b0569304ae56f8f35ad0881a2a852213c1cd7f29113406c73b794157dd08acd46c2b1e00b8224ccff8558333aa3a0302486f39fa4a4e323a92fbacef6ffc61286b139f5ff848d3bfc2a19d76e820bb69c55e24ea702be5a56c23cb71b211e9238d4685c18071244eedc7f5c27b33de249ef502e6fe9dad9586547d3ce1a780001db0335306a6fd7fa47b3b0d881bf1ec76f49b8250f9d28f046035dd973da57f18a9d5878b7d9f70fe747068f9dc64683a85e8abb35d8655b5948ec48f40b80b9854ed31d1ada0d6ef963f4061494c4aede56665856fd485fb636efd72260bb2e9a5b2c84d7af8756404e42a12d85ce88a918847ebdebf8048bad6b9bc9816b2708eaefce925bdbfcf7d560f6086178832a6753f5d14d1b2b81bee9e53f86f9a63dc244e5123eb4ea3d90dc16d8b7c715e56bc85c8f11c97e7343ac7decf2019fd7f73d2783265384e65a6064504775e761478f3a1fed5fc035bef45a16c603873552a6e860547b2584e73d65c65b97197b7dca9e7aa5a92f148b8b511d35f13fa49050f990292e869ca0cda42184db5ab3f92172c87b9363d07ca6e2263b98e6f3e9aa76b0aec99b91f7f0bb1f063b8eaf1ec669e813629f1853391858d9e8524d2a0c27190929822bdfb4ccc7baafc22a5499a9d4c6bae0655ffa3512084e95cafb1e468aae22c7e40c8ea305071da33b478a94dc1c294717d1e54839bad4f330287d395135d9d22e9de47c9e495905a1358d0e53dc17ff13d1e0cade49a30b5714ed2a755221db594555cb4192dd674757095dce31060685362f7863ceab0fae76edc3eb6250c364e50e2b3672d8af1ac4919ce31c41e69dedc24fcbe16120f0d6e4ca1d1506a27beeb6915bc8b58b6592aaa19c0980daf3208ba2f27a79a6e67e05722b8792e67ead1c044957c904760f114332e502abb6170652433838b0d5a3d15d866a93277ab55dcbc73db45627fc31c5aeca6e03cb2d817cda3db91045663ec9ce9e248a7f7bdd9cdd513a8c84c10f5bd5a840da5c7b0452c808890b0fe88c288b562e98d15e98915849304229668c279a3cb6979b640e4e4f59e6cdaed40e18a0cb4af57fe4b8eacd48cd0200e896e03747960b9f734ad391b7e89f0f44f3a1095bc3090c2b5766e1b5f370c6895873665049ea98a9506daea77a636be9385915668984d6919e421a7d014a46003542e45069faa372ad31dbc805b3ceaab510f034325e6614c9056fc95613c81c00decffdfb0e2b5880eeb8e4a552728300e70a177f2b2bc46a10ad95b8573b4aba3c8bcdd00a2f1ba433b68dc5f19523ae05b2d0cfe640d2eb6fc1760bbd7f7aa3275d6794c852c57c27eb5878e412ebaa9dc6728aa53d4a7a7b1cf338fbec2e722d4ac9d67e2e0ad7ffa928112d0363beb537550496def73ec21a44dc51827b968489596da28a15662e04a2ad4fff7bc7d1f7eb21c3e4ecbe5f7f38f951615c5e775c5313154849723154627bc3e4bdb506f46ba535835180504f860984c764d55406c44b052cdf4b7e22dab29e31a73761f91e86b741e1e215396ee81d3967e81325ce32f6677b6482d423bae37d43f222d4b80c90013e4ae0ae60cb5ad50257be5551ac83884e9939555be2b9aba88fd0d9168c8e0f5ffcaad39cc59f124f787290c8e285e10bc2b54b29c25bcc78d05c997556b0f4c131bdccd1b48e0ad61043e546a229aae098f56c24e35f9c5bb5906caede026f778c8e3372527d601d3d9ba75f9ef04880323620ba352ce899e729719d43ff77bdda40241a205545d70201bd78d42f254ca999e0adc27ecd8c251b3dc6b5d9e346a440e6fec58df38bec5e6c62fcae86914f9c10d4839b1333c999cbfda171f562f6bc4121153368a6c11960d383d48c98225a5ce86a7a250a09f891a989cc70f9cd1da21fc05aba4a87d1dc1a4a76f6c7c215e92906125b17ae38498b8c26b7d719ba415afaaafb6651ecfcd0e053e9d8ed4db80502b6b53ab19e4b0cc08bca98fbb87bc164cdc64ce2ca7f25d87f61c39092050bcc7c44bf4bdcf18aeef2335c6546e03077ffab135a81e11575655008dae6e34b6fb2b26a67a43639c763e420836be16a1403196a5c434fb7ee21c9987ff7c5307cb63535535a75adfcf5184a7c05bd208845991b8c42ad08399e5622054c7d2854857e4399e6b884f60483c628953dacefa0fb59feefe7535b01481f89ab63e60b80d0549c9ad1db9bbfc6e9f10995ba884c5e0e054f679bfd7ad781cd176fea88c671291414ffa45cca4282746bfd265b8eab6cb258fa86e819025a7f85404b7ef581d6687c9993b67173c6887ff644eeb43c45b2182188ace92e178e0be2581b49eb2d9627fa24e5771163a71e65e743139ba6a1f011071434a13fcab0a91f889f79b217c237afe0d24a9272d48963b748064c5652fbe9659e4d00c929323f6358c30532995130481552a757c220da28a16efbcc2ed8daf6041e93f444f0c8768d13ba760b7271cc00dd9511d4ff1fce4b8db9bc3aee7700351cd2c08727bc16a3ef245fd8ab54c9fb00e3d77e0b1913a2c4149875a35d68987adfadc1f003cb590a4c34ee596d062ff0973bfadfb90c17e2a6c66a60612484111ad02ec15e6cf9953873948c6d04b6dbe1e89dcca42691410f6e63811e95f6b3132279b81122ba491229c3da86b1a4308ddf2a1bb04a11385dc4d46a1d9c5db1cc0120d4d2ee700152b9c83b3877de251c90adabe8816843e6e0ccb7c7cc10cc95c2694aa4904a86e6f2e021c919eb25a6636d93bb7ad8854603cdc0f377dc10505f419558d6f0d64e181d7fdaedeedaeb8354c13b0d9d0580b914eb4626d60b112bf8eb5a7a18e6f04c80280ac920388f9c2072ce20280f502f7770c973b474eed98f84d0280cabafe5f5ab9cd9866316f9a348cc9bd6b76131ba30ca904330f790e05c2f454e400d1195a2f4f95333d1f54f7cce3feecb687a7e883274af05c51a28ddfff74558cac2f1da44e690225aef417bf4407bb4817eb481f6e811b41d2071ec1ef91ee590897cb3034010b1f2130fdfa4700a0ac119f3a01436d4ab2d9a0f98a9a33dadcc50b28de2752b85f6045c430c18f896af177f0b5dcaa76ab506913cdad347e061df856f816fff3d9078f7437eb9aee324de62ebe65c8755bb778f4666efb3e3f917809d68eec1ae69b9ac7b22414c59695c2b5bc700ea1c2a296887571f8ef30036d74228bc521d8717e7025628c7cb42ab1a8802929ab3a0be8fb4a7fcee1438e71dc053855fcfd8cfa3e9bb882f899d70a46ec1bbec37de4fa13d4935bb5c0489114c9fe469647495d9a115c6c19cb81be1e08fc077fd3510243c6c1b1981567b87766f221edf78475708f57a0d7f77434ca898d7f83cbf575033e5f8da29182e0b6ee40314f5dc22e133598d02d4b9998ddb025933b6388e96667ed905d00c03258347e1385ee7274875e64e1d6bfc56b388b75391ac6169b61aad4d6b83c560d12c0c16838561d1580c16cdc27009be4e70ce8021ed36a03c260fa1d696af53d5d55b749582bfc18f665aec82f3b58f0c1dae25d4687cd100ea07b3751183a81c1a32f028799afc4d5cc7e759677f36830e77cc63d3e58bf7f52489887c1192338fdca304211b9699cb2e899266513fd6e6a4e7626b6b669a74010b36eb0a1e6ccadf6209612581d370a4aeb4df0a517b51a3c0981950bb06342b058ac38444759631368439303f831f656dfc544a9c487505f13527f61f1397b365db82c74cc87f8391926b74564c473174a0ff392580f492803f492051f4114616e202c883321177f4cfd8b09e42109159605ab2329788aed5dce63628c5ab13b3fcfed69e800588e50f7a5c1891db414bce3c5b2b50dce3dfaf76235138ba89fc34279d4fe4e74adf975cbd33eeef793fde9eb7c7fbf1f6bc1efa694a16a55878462946a5aef0e59be09cde94df443108dac540d7216c96b2aa064f83730a4a80e9d231549e1669b684675926eea432f4443c39066d7d287f73aff4ee4b54b711404a58787c8f502f03a263571e16aa177d2e1d3fade0ecbfe54f56d9dc8164dc35b396ee5de46b30cd496bf172941010b29d2cc2bda96abcba1ff7f595f4f082de2042b3d145c2f2a3d9674634dc034ebc755b3925ee78836227e7077fdcfa77ed06c5f4f2495f140a20c0b4724a5b5c3dce3e2653ec5763e641138375f77edf6fc9fa99d49b8571a112c3bec64b253053865238ceda22d1f29292766a64874bc0ee2babdaf5a0bb4724f81cf99aa27cd18d9c30a1bd3e27df314e8e431cdf4621175aaa937415ff3c5d3fa5a43588b84357a086e4f5d9e81150b4f202d97a043400c4dbb13ad954c86c6a347676504a7f57e9fb6c378c2fa0f16114ba37dffaeb49d67e66609618947549e8cbcd2d80e60cdb6b553f9d670e1a1618e5ac0bd118d9bb834b0107fa53663b464da8cf86d2e59b30ff4f63c50037b148b42cb006911b41710ab0019601131f0bec56119b19a8502a56dcc0c689727554642cabf0beee2fb4b4ad623013b694b3cd3028f135b4874fba6e5d850cd2214ca8089fc778e964bb447c29e681cea94a20a051f55a484e45e0d8406dc61ed901e0dcdba378519fbd8eb2766c1800b83b47549243c49696149cb29468eb4da958305626274eba5b89465bb71957f7fa6a03621884325e0430542a11e0bb6ce93a9ddea4b264a17ffb40cc722e5645bace8cdc502c8d29e68cc0d3a10862b131f043592285db3269ef360385beb442ff1759880bb5322a501a6ac1cf5a006d86d97dd96d303bece44d2d16247006e2e84452d349ab95cc39a51e0ba553a40b7d0dd3fa2badc6859e2f0c1d13301d0880c0d442f225bdec54337fcb985dec87086678253c8c0ea5e01ed4432fa16418094b9d8091ca17ebddb8dd7d557a510580ce4d2113032b6e558781d1a3653b3c96967f52681465c5f39290ff094455d23ab650e27e793db8f2c3b8e6d7bb8bfdd031df39202972209ef5e5a1cbb8f3870b5d95071f58c092598e54c0968b18023b24249396f6ab728f586ad69b1ac5b1282f8b15aaa2837aa3fa97791af6b44083ff49014c23b3876c172fa4664f8767d2d2d6d851221f6d6c1c5703fa6e46da530447124bb70d286b685fb4c03c17ddd1a90c8501658d0d7cfd07fe896860b58bf8059f8b41a7c5c6b3c22a5b54b170e1adf53d99770fb1558cfdf051ee2c0609ef0de8e4402b9466e9adddd032d16fda3f277b0971c17d995fd408392a691322b44a6ffb0b90adae8543879c394b2d9c203bd59b3c66bdbc0028eed9b1eda60abc8f973e2fdfa6c9a64a4b26ff7c6dba3ab8b3ecd9638bd9f61b4b5937ce665f575b37691c7e30480f40478202402207fc3082a4ae26441412edaf1705f25ca77e1ac63e2c3559233de7edb7dce35dfc1e4f444d96b374e353a4123aff3ff2163c81778273ab297fcbd45cc642f50c71b0327d90c935ee6f2125a023a1dd8cea95b621f35e1df0b8f4704044764e6712e226f0ea5c4ce8be42889813d6bf6558958b39c30a70f894ef8e53ab9c125476d363829f184222460dbb79809830607ec3e0a4fe84ecade1d60970ebcd9c7a3344369de4d8747d0d239c65d1c3a28abb95188f4b6f02c7f81cb88d126893cc4683139140490d0b4f31a03f3861fed23f29906b3335a0e65e804ad058be9f3c9866a846759d2fa540c552560414883f72d131f000aceb4fae0ceef37052fff05fd818be1708c00fa74443f5f5dd9caca25373cf39a1d7704ee51cd65718bdd3710ec1ca8b01066b8f7ecce4067561637f08c1f3b50fe5f86f084425326dc78ae4aef01d666324cd89f4a41174603bf4324f293b23646ff3243a138fb3e07ad0e135d14f1c6f4da2ebb5e56b4f3c0950369324186e1a5ace15e7911508ba1055acf6f4f1419308979acbc7f7dc907b26cc89ca5842eb93985a23cb38d7da9ee812cade008cbf47886d1ceafb4ad9f6c2b318fe62179cf38fc50ebf391d3e6f73ecb09ed952c48a8df910a1ec93aeac2b4e4b9c36090c82ca4051745b80fa42f3542a9586c5fd8468369f5f4d48642df44ec17606c9c46939767eb0e812cac146866e231b1904ac3f39f4e3fbdd2bb6977618b1345a89f256ba08293c055284e8a1740f0082ae4aa4794407eb3623337ab5a9cd2142454d3d04af414e925c172c6ffcd114de0e15a71b0e3ea71490acb69e72b92ed04755a32bbca7da9a0311a0a09bfdfe0d762a816438a1ec44d656baa082451bce042e9bc2032e21167937165cdcc5e323e8edbb65e7e6a89ba9ae65cea8c36ef1c7ed6de88478211f8b1fa4a8877c032cc5d44fc8649e8cad4ef881836104ad159125838ce8afe62eb84d1fa5711502bbc16d275e36fd0a1afe204e8c1fc09801913189994cb8047333741b4dbc7f6dfbb4bfa465e83617d98a7e6f1381e02c4406e690eaec6fbb0142ef061a05697e68100e86ff5bb8f4818fc82e9d7795a4259c8a8abcc8138717c1982e9014db8d4143cc095b4406a4f09024a7606cf4a3d04c0ccffb3bbac2991f42a0cb89a6b860df4a05bc5941249ad5e8cbf906b88ae09a3d769d77824c24a87b3b7cfc298cb80795dd6ba4ee739446a690cacb88f28755a3723f34ae2246b403ce09d6661497e670e88a397b85a0d3966add698077dbfeaa221575146cfe0b8a99512d1e3ec567890e93a2d63386a1418e9116a6d27c907ea749f01698b5a46f791543f67eada56fa5dab588fac6c098262f28e746d17695c737f4c858dca41a7cb4bfe7324272e5802d1883c25d69a663968daf13ad0935d795cac8ec4ae086c236fed47e26d9de115d314aa84879fa89a068a32fb5ea641d242aee7bc2b256703ec707745d8e3b0fe249a6518441341d7ca3f143b45d262dff3a9f6ac106075886519014661460084edaa97131f58f32c55bac1ab375083c6cfe1e1fec93d8fc23fdc9449757fcb1895b0e3a3f6865a5eaa87b69c84fb560226fa4c1c5915f9d3a3caee5c10f3523c2ce971e860ecc90ac500246428028d5bd3ec7336e4bd40afeae376a7c8e33186ae7f8024d634b2a5252d95fa0a690dfbf122d4f6da3e7d0de7292b66c4009cfd38a190f8d0915b88e42862216094965cd2035da463ddc888538ad865ebddf3b4311326c71cd6b4deb93191d5182e4af46ecb23b64141a308eb0cb0a1f682c66d12e0dd18bb5f573bcb2cbdb55c7f07380f64a660bf9ca094e5e093eb64e0a80c7c3cb900cca88536d404baf6556b40a300950232c73c6a8c59c24716591bb2b508acc9ec1b9b844ae42632cefe651cb70102b9817328bcc52a6985964965159edc181854e695dd5739117f36191b285d4922975717babca1f345508bdf7c3a3708027ffa7ebbe08829595b7f9b1f2cfc0e11a0cd9929a251a2206054fc810102c3b8da278fc032d3e100b4c2103ae18ec1eca8ce22c50a5233b2a7862cc5c42c0f174cb791c4412ddba1d01ee9ea11ae8973c7abefae54654574ffc181300560f34c51186df9334335ab7248a815bec3c7453919de113a8378e2f47d73ea2c917ac766f20c3547f9fa17e29e81bdc9d9c2a9e516b6db08ea51f6b96a1157c17ee32083e1620cf2d3f38e1ffc30ebd100a50f108035786a25c517ab1ad7d3d059cfbc64defff5045e204c26fe28cd70c02473f5214341ec8618aa5ea03eb2398737bf315523cd22c8b95a3352d7648f9734d9c90544b5d2979247efb11c389e418740ce4ee2157f02b40ebe7aae12b05bd937bf368999925f6e251d0421cdbbdabdc9f15e0d4031c4c615be3ee2acbc01265dc812bbc93bdf8f8b90d9487693120e40e27aed0bc2dd927afe116bb08c005c8c5e29fb51a73e10a7e67ed24043cbc9e791634db731a64461f0c2bd1e5f0c7a4767f6075ef6fc865a21e7b36c5d9aff6871ce5bf5fdeea4ce552fc681aa3e9feb839c093945725d7ff944acd9ec8fca8e67112cc634f7014f13d23afb8210bac4e32ab7b0f2a212788a47c53a1adc2ec30b4d1063ec8c127a7f0b9c5e6de15d8c3afaa7769b81471a3f5f60b44b308ae77c4ac6492124968626dcab7921d84a7bd54479601958c6b66471a963e77d003382a3ab203b16459c03e3e3952c14cb6180ed46a8d4f877debc112b9d258ec291b44d5dd681c9d374c1bf11845efb12bba787bd50cbd2cf77def1cf73031065362fe73bc20af2cfda5cb8375b503f7f9b1a6bc7951a318108ccabb076bb374c38493896fc7bf848a087840f434651c57122ac434bb24b6aab5cc1b9bf905139972616dd4633701edbe1db5cfea9c4afc0cecac9eab23a65bd101d2ddf59d9f6ede38ca7fa7eb512087476124841e122e3e59723da3dc0c7d821ff9bff9e5869866ae491b6c9c47bd1594254314832695de95e2e5fa0d311700949eadd6856fa8397f2b9a8268de90d9af77d698b7fcf690af48492fd137e47bbb9cde8906142cdacb2c0c666ec85cffb0a690379b1b306f2801dcf974cf268f43e68b9b374c4345c8ad776352acd1c2e309086ea7ff24f95f250be80d5795fb107534d7388993fe7a439c833f19a843a00266d235af82d4a0f1ef802c18c849ea98a1d644b8f9ef80c2ba57af37a53758bbd8d2ca1b68feba1bf6629c02dc33f91d4833643d0c1ee1b7a09cd667b6b33034c2053f708652a631f81fa942d27cff3d6e451ebfa67c4996f5e37c226f52033aa966f33fa10541c66f978c28c1b28cf9614e856c6aa9b41dc8882aaaa8606ad9338b1085eba70d5b0cd3a73284df87757432511847882e151d644e731943575d2b9d712ba6d9528c1a5301b0028c0b03f6cc090b72b874a1548816c949321a21e242189d926334728e208dcd9a78da34ab9e59519f02eedf93f914cdb35e565e135f9545f35052925a34372c135cc0616d03391f5717890284da1d28332feaa7d06252d4c6b5386a767a3ef8da455fa0b7ffaa09e47c3619c9540aafa900c95bd5ee7882afa090c8c25aaa28dc4106c370a5abeb43d720fbacee971bacd4dfe50d6ad11882da5b1cbcd75801e080ba2bdd1dac611cf4f6fcadf8d76a9a5ed62fb5b48c31fc6faab7f9c6bda6e3df0e710fec3a6f07491768b1fb34deaaea5e1b38f20756b0fa8374524eb1615727fbcb0377d22a4f7c6381fb23c80ba758e441cd96c14076c6cee19152ccf18b0312639c789de2895975d2cfd59f9c6127adb761620f0ae49155d87d07cf9349d32ee63cdcf942c935ca31d8379930d77c9d1b9b8d77ff6e811234aae16f73025b1e1a0ab42fc7728690dbe5a719d148c503ff458380ed1aac61eb4929e6c804db411dedc8d744f7e07a7898053a93d0d72e277db377886eba4d8c788736c3494247534c3888b2cc27f23827fa1e866386853a3a3d882dd4d61972e4f9c014da98ae98bbbdd7d33e416ae50f609d532a48b30be13a14380f35b6062848a7a588ccda2ba6911bc51f6ffd1f766922325c5c691c503015c362cdad24d9493c0060d7bb99f94af7c8e88fe64b0f7e476513fb8c6dab0141c54e9989aa19574a0df176153bbf79f89c5956c9e005e205f6e6f90659e0d04cd29cb49013bcdc231cdf89f8852b7d3a0172917c4b915efd89e2f9193d0db430a927ba7e02506843a3a74a2051a92fe90264b619bb6a1b181edb30e717cc10db9421996dd6dc51f01e438a0c64150ae1bedec197f8f7a4d30490a40dfb56fbaf8abf66b9240e696c87e302e4de8ecf25bb3b00f0471e981a621c2968409ed17cc07ff624d327ac5ebcdf2372bc0ee1c57f0bad07db46259b740b88bf4cebdf5168c3de678a7178ccc6dac4d6a6af4505a7bd55fdaccb139f0ccab3b4491464a5043bbbc70545f9a6ac9e0be188b45ff40006fb93bf7cb763a6b0d0c4f273427e808f806fac0396f5ce07429c7752e8d80f8bd603620147f4dbec000af94852e90a29f443a601cae26439da48674b37e4642e7362feb2bb8794ad47a6376fad8699222bb3416133aa140344fd869a7446f4fa5f450d7bbb71746e983664e759b7bef797d2475d1405a272ee07068b171d8c0c7120a6efe484b5dbf9d7931f0a975b7ef1c54d9f3ca7f95fbc046ca2e469973a9335dac82f99caa27e926bb1fed0aa12db3f84d4cd9e6c6f389dfae032863370622c0f924b89c4ea6a8d91f73fd7f15c6bf6e8b03a298c2d3c04fce26a33502ae6910b8dcae0baaca67c6efc077fac69188665afca2bb81f1c69a457c28cca057d0bd7f27c5beba49cdff5e056599f07c82aa9ce3fc2fcf6ff23e50d28fbd3172905d48cc20da9e6c9122a5ede58ea67b6e7b0203feab6d3e412915ffe683ba702103e487065c982c48706caa891b94f3e22e9e2203e72ab0e16e48bfff520dc08cd2b65ca083ff13353f9574e1791789f03b688020dd6bf6e4556284e07a4cb3fa8496e603e673fe2374a917da7f0535863822d25b9a87d5f9e5b0a6e5a5ced23440ebf41e24e3393ec2af5459f184bfa010302623d48f21707180060dc2f02d5fdd25a0be9a675a774a8f850e74cf1f55539a7352813553015c6576b12713bed1f4b9101a1da3a0f034d0df9290add168ca27d60487e40d9f948fcd8486dff1d405c6d44e83b49493f9cd7880a664695f307d0f4d56edaa8431bb1e03684f9af49d89e73881a3d837f898d934526f7de3542b3daa4b49ecaec7ee82a91a521fa0a477112118296812b1ba61282cf5240801532927bc772b2c466bc483517e2bce70ea2fcd8eac3614ece17abfb81bba71f06405cd4138b279eca90d37f8e7f5ce52166d59f1e9f6b113e95f62fe2d63ce8321d3c0266421d52c4826ecb56aee1f43f20fba50f51683c3aaa419aee170d6b0cc8c4a6c566035feb038031ba18613bdef55499d52f313d0e3c20efd48b5e19f6912a859b9c8c91c39eb77af4e66c2dff09e20afbcdcd96b8981782279d5d358a7fa124e25bcfd76d3cc7eadc6d51dc7ba7c3f55ac72533bc1e1f63f8bc49d6663ec66d374819a44c3f34dd3539b4baf1e28eff0c415e5d00eb1befd7d23d30177df88a93440310822fa47b104f81e403f369f6d26160bcdb84ce04b00bd632d305c864aabfc96ce55de0ee7aa2fc4026aff6b39a1be872157b020bc01360a1d3c8ede144a2b4d85c98290f3230e592ea050e9dca18626c21dc9c7709b97377bcffed725b304b0441e11475a6dab82dfddd5314749066266f293192c4c30cf23fe168e9fddecbc4df8d29036c4f79f37fa4b46ba431f02667a65e7cbb1f140c8a735a2b0fb067b9062905d6ff20f3e3f8b0506decc85b4a00046688c21f0822b62b3b898dd430e604a93496d0f9811972049b7a026e784f499538d8a5a1346eb88aa0cda3839b23ad6a24b7e68708a5c48d225a8337df75b7e60b81db7d206e8b407e80eea518765e37987191d324e4a0e1a065d622bdd9deb9d87b725ba8e62a110ef2231a039bc3d9c6d21836e6ca60ee9b473fc4b24c7bfb019eac5563c704d6bebc436c853ca07c28754c7dfd6d81a80c545183134472de72b50ce4af7bdccb81a7211a464997b3b3b7df42cf62763915cd0af07244c6da6f51e64a14c325cd89ccdf5020417c7f8bc5ca34074a0fda116d074073240bdfac30e4fb85319655bd38153da0564538674fadb685c51719b5ba98b0775ccacaf6d2acf2b7c2a6aa4187e959bb369f16423002d58b8e53647ab304ed4a4d3f9c2f4e9e181fb892a615b93fc83d62ecb92d286a472dc5451eaee525d2454a85424a979f5e3cccd6821a0138db292fa3b27fb054efeeba9f5e956cebe4584b2e796360bd356fa1d0376cc157cd6aa09f943e26bc0ad6b1eb428bae78c42616d2c3d20881a152456f1d4555d076ade1024e92aef9fe7996414f8f5b9e6bb31deb8a6ff3b793461732096a968987f6217fbeab9e9e16f1b06554bbce0c773dace8e98561566a71c4b38af0e5fdbc19c32520caa6a2f9b2df18ad0bfaad56db2387cd4d1384f9a0c8d8a1b9d2924a3985a791691bb11f668692e11250092dd48ce9359bf859601a7e1779427e7a864f4de98e7a8b1198981098189018d89070b1d965873b91075b44731ddfdf9a145f98ebd000253dc3ba4bde745921d1d1bf6112ce9e3e4ab274884fbe03e845c3978eee8a54d11a67353eda55f3a095d430118be9c9ebdb05853a81ff0adb37809510d4b17cb8d57bce45b8b69b19d73f196c95829231b9be88a4a7ce3bb2ebd301b1479eadfdb9a7522039dae15575a42b5eef1e609f30eb146d27b68035dcaa4af3db15b85f12e95fc564d01a6cce404d5d1cafbc566947b11ca6e58dd600262674e8b7421fefa5709cb415bbf1f88728f062e7599159ff727ffe4363c726ccaeb6c4762c539c08c099eeb869c5f2b3f8055bb5b076ea0aeaf70080bfb80b1655cc0351bd8854be812798c52544e239a6cdc2fd03e74dd70910c3aa40cddb4c1ca5f78cf7a2a4333ab8d57aa6a54bd0e104730514520369f3a5e0cd11166b6570f155e4e04798a113994a0f0c08c14bfc306833ea29396c23eac7cc2afcb4043c265b8dc90124a4726e02590906a30f8e7c6ca518f8672a0b05e9399f822987e57068a53cc1f510081fbe8c3873d3c14d2ed2a92f19504ab4a39d483daba139a4706ecad832e44305d025ca90450cf0fc77bdf2292320ff8ba44033e90d3c206165847dcc993de171e8c3bdf2c3638aef083dabd7eb9a35fd8087032266b7a2ee3a430ad5e08c093f895d3f15dd8a014e7b08321c5b3de71cca6114ca99aab0ff4198f87b4545f2487ad6de350bc8be377e4192b5095464be0beceebc297f7edc23a016185c21ef370ba4a2451a820a5f161844888e199492cc5ba1cca594478e6497a8e25fd7cb47f3aec89e3762a61fa6c72b9bb305b02a730ac613ae2f244e6b95806cea543e6fa02a68c9e6f5081ce9f6db11e8561f964f4042274959e88d50c9bf1b198beb3f447285a395f23f3fa4c25f2138214b1a6421b95e5c66d1568211d0920020a85ac9acc7e28c7327e72315a98b775864e6e1e1321c8fbf883d985dd08a19296c4fad9b1d3f028389a195a91667902740471eea069a0e53f133d86ab0badbce1a34bdb99e816e881ca0caca22cdf21b9944070ddc0a2b038c9c2b84f023f9a807d21669aad163a50e1149941c3ba6fd1db0e01d6ed1bfe8beb5efd7aa8c0d6033e5672f36068c7002bbb95a291d29bc0c2ffb615019180ffdf99968421276b34ff8100d5b092a4be3acea73aaa819c3f0d803f203df5cba74a281dced057301a629005d890b0917cc4e250bf216efa74b40611ce5f545fa4e43ee5ffec803eea6348dcc480b48ed50320d80add82f1aa9be285955fb557680c8d4187c4dcf8f74650072e752ed1fc0855c4389268d8f3ac076c0b4b4c599edb0e8a1de09ad2a93cb714f24583b0a6ec5f9fd0b071cda70ba0ebe3fc1eb8d68cb2c4f7efaec3f9f4d912e328302599772c45e1057ea7446dd307a51d807b8da0609bdeea2a5d36558b04a75a770e7306e9cda1e7b6c98d82f0180ae72c02ffede9ec898dbd20c11a76370c5a30be7b1a09d173eb068208cd10cbcf8fa3272573fba386f0599fd3c3c918dff9d4c7e9cd146d682a7c78fa6d9e834ee5049e501529ca6140c84716ae35be179a86630122fd1ecb375d167bdf302c696161b8da7a599f4e067b16112901187238977769c5e31de1be18ea1112321812ceca36054a74b1420f7ce42f21e1fa2206151ac0746214d923604272c4a2eebcd2faa448610ebcd8d5e6ce759411a5fd82e8753553e2b78f8a8022eb01a0cea9430a8090d651309cdbf9e47277e93cc0441ae8f56dbcfd38fd6188d504dba80d775617d34880922fe83265aac73b0b6ef6de95b684c16c8705f703ae691ec6864643b703870c99d0579ace4e2a72a09aed338845adee96f8ae15e712d9c071966bdf184b7bc560e210300af122686bf7cc6fe285c0886c6e7ef0542c32565ea44c4504c218ba7f7999582ceb0eb7f4e46dfb6abdfeb192ca5c416343e54ab7f37a7b3730431ed9db238ee3d0a85ec68301a933afa1b1e6970ead819f8a2ffcc13c53a560997eb8e3f3f464ae5c2a4b86cb2fbc62e39a6ecde482eade6a651b0c970b3a30433dd38624582ba541de3590565448c92c176c470c3498901f1da91322de4e009e13d732396ae57054469f16e8b8179ceead926de3dccbd12dc12379c8d4d94f06a5992cd577d9e3385722f817bfe104e1d6f33a4b4b592e5e861d1c55208295b9365001c643303ae563cab011b2113a46083c0f1d0a89ad898147e4cb8ad6f56e7bfdca2ffd2e08e89b4700906726556daa15fe34a5fc404b306ad9c133e176cdaa0ea872401de3540fd6e2bf3c7db59415dfc366049b1f89710c35517b14c1307dc19e42b217afa1b500587f7efc175318306769617824e26ff59c6ae3b637d90c290cd8f5ef5b74c8c70f62f995ceacab678bcb66cc9022ec10a7512aad5ac3d3e46e3c29c451d7972b17891c66099a163910544698a513728a3b30580b9499898aff3f3fe301155a215cecebaa299bb71bc9e245bd1061783e575d545ce0ae33bd2d873b2dbad91106082618ab73a2070a91cfdd0fa9300f273d376c3b490f54f503bb620cf8e82460a7b9d60873e80495b5ed0f789f327270fb07b0a49a32a4e3d9bf2ecbc03eab111d9de372bb3a12d446347f2509912ffe806e3ef3756b1b59903e80cc17d3d712757386679d02ffbdab48a43ef9af6128c4f927945b8d23a5f7a5e4b4e3be2e723ca6a85e7bf34954b3b5ad0609a5aa0897da5e0874440393d75c5010129cdb2996492a8a7bcafe8d99482a100b4923ba9b8e79b2359d523d74c11631c3185bfcedf00277607b6a332a5658ae5bd958cc30f94753015a1a07d9cb7e3a616ef4d89a789e59009c00cd3382b8068791894f53065e6318755316a6c36b525414dcdc66a94d42f1691f31266a31e85e66cb24ac47a303efa582a169e880110c02fe28cdb5a09f1db00a2e06bb1d16a3380f6cc4955be026cf529ab81c5a6790d90b0e5cba23a1c5988303bd9d3558193b42e0bfe65cbf9da0453990c2aa08521d1043f28b64aef1b47156975865f7acfad48b6c1b1c0df784169b5f0e785be96abe7d6ed4d767ba223992649b90fc287877b70a1eca17a96dc92e927af7dde97f8a9b10d74210d92c269dd127d481ab9f42ae251a33478c8da9a6d776acdacbd9bcb9807ca765837d0a18b4aa14be4f447f4993427f3cd3686419e5398599a0d3145275e9a0fd45eca9c3325816857b33d56d06a11121b79f108e53e27fb6b8b9c3465b9c85836a22bd2d0b7fcc2ebcf1e0c5faf715d96e24a369171190e125891069f5505d8a04e5957e2e501a33f5e461f57e59424ea68bb396e4a9ee8a2c701fe95cff949b7e9fdd78abfc0e0007a90cdd9ea2b7d03fdd05ad8003984dbff7ce76a2001f1c65e3c42bb306d367791e31f882ecdc14d6c39f3355da3065b98553c3bbc573dceab6a9e875f048dd6ae2870405bc02e7740b6cc92549efa76d398a67e1a8137fd8c1c0f118adcb40e580fb20a15569d3754785a2f31b9780ebecec183e41dae1e1cfb9ac3d78fbda2e65f3a63e203c6b449d127c2e82e66815483ca9e018236378068055458f494b308a2a036dca08010fb92efdb013657fc53e05745aed46895ce9ef6b7dbf1842af368b209cd4b760e00e8dda9c21f43b568dc773077b6622e881b1666e3301ebfb54f2407013218cca246c364d0a1d9b01aa2a2b1e1a2556e96af90a7ca2d9f678b54e1619d77434831042c89b676f56021d17293e0a8b4bc2bd8fc1fd53067462a8ae4cfea20d3bcea05ccbe43a716a5b884181a03f0f6958fb433b17555ad3baa1d93beb23f35cca0fbfcf6acd979c7f438044ee2d9164a42e01d916260188e746f4f010c4ac25f1c6cbd3fd4800940511d0c7b43ed89462ae107d17470471a99d4bc120f09ce1ee3aa1482b263004084c162d6e7069b4ed4390a98f3a6facc077a78197152887ef215ed618ac2201e3c73ce1e19e44ba27fde208ff5b3e55f3f9fd7081135466f0f0eb10190fb4c3537190e1ec995558828dcf2575caafb5ff8a7b26dd6d9718bcee419851a02d5feec72af4052e4320cc1b909a7525a5d59046a25b256a47dd5827f1e06a00180b78ab07b673eabd095c08ff4a2a147696f681d9da21a2784d593ff20b19b2d77ee602b7443e0673f98d860e988fee9600e25b2d2a4ae8b2496fbdd2db226c64ac6edced744d6cfd817b91d6e34552647c3090fc9e518240bb082a2fa3d2cc093a698f1fd5a0c0d9a1679f18e8cd7f2693f83c35642994d827861b52da0703b756be1eb56b9fdf040163cbd321bc7167d632e830270760613862d2993b9647b9ffdbd2cf29cb369e51a53b0ff2caa1f9849aef7093f95629a66dd87dfebfb5fe0cbf5d54d602754286a5950de53ff0626c5fde521fa7d5b0c68ee03cf4853390e738e0350c0fef0210fe1641fcf64479d6363bf19489776c9dab013c35024001537a4d95a3f91505a4b506829dd020cb3031230785135be55d03d689c2578ddc499b56a12cb2e8df7446b3889d6f19d44f5ca8441a2a3241a0faa590d5689bd30956030739b355d6113e399847086e170f20d281ba46eed90a7fe983d8b87fe63ae0b82f9d6d8fae1757141bb44a76a8a129ad31324d9f30025d90d77be69ae0b2ce6790167d20f187f9be24b043b19e03fdaef66da47850cc2a5da66e6c7de4d9ffc164a53ad7e71b7313f88a02b0be12974329410ecb3ca0924b504a54b5f820299576e4a2633c5b5bc94095425c9fdf9714fab112a4f2151070236286c94d0b3b6832c0b4813928a94148c50714daf621f8f8b10f5dedbb2bcad90bc6aa20f75b221a3175a000cc35b763f0513e25659ea2c4f7be7a4bb69c05d48cc7410aa1810ad2c479785457e2dcbbc048f2ed7c29a8c1ffb60879c619f976708aeb62c35793bdf35ee984d7c0e94bed309249f5f289545262bd9f097eae89c105f5a0e6737e2749e40ce057681a6aefe74cd0c59ba09ddf0bd8014126881e29622175bcba88b2bb94771f3a604fe9ef83852ece58586647aff830312326e66af536d1e2211e2f28000da80fa7ff9a0ba533be441ab3a7c9f910ef37c861a05008f823a6fa1f4e507c04463d3e944afeafc22609afa98a46d850f717adbf0b14129e11b84e3981da33c8ed44b59c6e50e4653a225fe4ce8052596f32383fcfd7e5ffa7316678f5b3bf857b63e80a068946cd515d07dd4c2d6bb37b1d0b4b41686ac00e3be75fb4bbda78092ad1992c717d7b004f0028440582b0020ba6b51073b2ea0de63ddabca8749eeda5f303538ccb6d2bd0b01ae8532826619cc15f7d5fe8e37b5f5022f43a178f5a6b08d3153a6a146c308465c5f434aad0c549835e75ded703a2fada3140c925d39683e127de0683589b20fff050a44a17e41cbc0919d857a064d689968f0605e0e2f2b391cd5a3e69105128f7212948eda5595082c63c8df7335196e22cc5960dce0f226b76f22d0dcb63bd4f7b20d20b042ccb05630fa7e65c3b3dfe855c7ef7fec23e9017a6933a209ac4ed87c71a527cd1a931fae13b6fdc281d1f6056d9254b08960444020258eca8e259431a960c90becd2055a7a0dacf781748fec2c1919d354580c814b6308ca00b4028e12492f817940b1a0d7f70ab9afc96b86d96ec039b97f37c9f2469f957b01e1d1959164cd0e7dad01955ce664adacdc21c82bae4c6ba9a9f44088741d2d519a1da71db18f2583ec3ee72319b62329250894b63c52bee21d638a58b81781af5bc04ab9f3b54e65fd15173e11d60d580648bc5103ce86a22c8f7d119fc10d72e8dd6f7cfb575f020406e4cf687008bf363888a301fa5397026b1c1f8e0025ce3ac01d01837d4c527279dcded7b575942e3c338e370f372a2edf3021c457b88fbc97ffd02a465596ebcdef4f7479ee35f1dbd58e37ac61a87bcf0140b14e76113d23e631885859319172a5cf96bc5fc3958815ec0792df4750ef4b6f171b3b12dbc57d6419c711984b5d5d2092ac20fd6678b342cb0dfad952b76f301132ecf8e8386bc2ff8cc18f5940b00898cfbcb422b725f24ede0a0ecf61f536980bd9912eecb5c5e740bf2e5cceb0fc54d16849a615c60421fe2376814f012b9f23de846bd23d49fc565a66bb08ef7917eee155cbe602207d686c6dd37c74518d89c93b2cf487448587335d1c5175fe21912fbe70e30a1bf017894f601ae6084dacb04ff2e251f8456f20ebde3ad302b48c043e0284a00d531038c5d57462642293a25ac5c1172fae4b9567c99b918daa02ab7679c1263249d16d1e5452b035c8b23cf588da60a2079aae0b2535538edf37143766c93daff01fbd9fb3442312ea256defb626b7945b4a2903760c360d070e3a7cedb6478e5ea34445b816e1354a7484a6855ad45a8b0e3a95fac8bb5e60246dad8c3cb55aa017b918c2e885760df6022f55548b678a24eb7475daafb64d5ea1156d53d76b178b4038918933fae06e4eb10e4214808a0120e083d75eb52653417fbd76db745fbfd8238849b503ed2a2e88a37477e2c147d3c908b3a944732ec264aa9184e6bca9443d782553509e4624e43cdc44d3dea81d680f4d0b85c3226907ad8fd7e5699b6a07dac1a612a740dca940f4dbb91b1d3bce39052a9af30be03ea807eb4c1d1c848b6391335d2312409066e4218a1c74a6eb4c793c02f3250a611402bd66458b2a8a2d08fbabb5cea2c82d91833857009dc89401288329a1cb207b91db226791bdc8c393056844bacd6b5e5ea5996bda6d2cbd62a4db8944b3a29731be62a4143e0cb32983292cac5f9781910d8483a60cec6944ba91ed64513b59806eef69449e13c80ec28dc2f302d941185d00f4d041e4dead596224904639fbea969c008896d943d0c36dee99036a0d3f73111c2b3a432db91345da0a70b82fb8c90958519c9122d06820bc92e30862bb387372cbabd3beaf4eeb9c59b17622b362a4228d33b57f302bd63ea4f5da3661246dc28babd39edaa6fabbbef1ba6f3fde38e79c59f85e5cddbde3364360c29d6513b0f9223320045e47d0297ce8579c9918dde6ad05d03058015e703fae48d64710dfb2e0f58a8b6dbd355b3bb09edeb7f792b576607d047b8e105ad7f98491dffa365a01ea19face5810abeeeaeadea1f6505beb5757dd626badb5d69e18906de6f5cca05bd04a5dcf67bdf7daa69e85b23cb07a9acb1af41162f705b67a5d7510bcf75e2d5f978a8b1dc4d531d6d8f1bd77e3b2eab3a6d8f35931bea6a5babaea33b831c24bab916a1775755185cf1ad867486a609f184c010606af6d73730e7b9fdeec649dac0dfd3a85380c67b71786618721d177e843661886a78f34aff9d0cd2cc92dee190cbce3eeb83bc018b59bbd70c8f201f89a8503d38b3651cca0e86939f3b0badebb2c490d98f0a1cf7c9bf6454d6aa062a4d98982dbb43a0a39eb2aee0c708e033750dee4aed26ce71352ed180449720cf5dd339f912449ce685edf8ee3288e2ecec81a8de623295e1b29ba4d9cb9b0286a78a63a7fa07bf3bdf7ceaeebebba040b82be3a0c41ec7a36d3b399ae612780daabd68e2f9e610795cc666e4913e3ec20b2a7579fa96fbccf3486c68dba4ae81514b73ecb182b68b7d9bc04edb61a76423af3ec33786d8a0fbe0675e83adb9c364beb6f4c6360332dbfb45eda4a2fa1ac6f6d366bd6bc040b82cd6bf64696b5da09024c4bebe499da9a0f9930b076d0c951a49de9cc854581bbba7ccec0c6a85d7d2667f0e66aa6e51d778b5b02a8c10c66ac4bed9e4d9201698c7d5ebfeec282109e599f2e2c8a0c9ea9757cbab028ee89f30203bc4db7f7420a03e71c6217d5ab85b52fc019bbee5a6bc5613df30e3346e2537eadd5a8d62d9c7461106b09d2ab3d2be8a7be15b7dbf34f9956ab25b7f26a65fbf88b5e427722c903733cd3189514adb7b83aeb429f252e575e2530776bf6036a1716c55899ddf629edab58c0080f2081850b8bc2552c60ab92b4ea359b992e2c08fa4c638064fdcdc46c32e92af5acb8c2a9026b4da38125581040b716f419786aeb2d4a7831336d1ac3ee2ccd244f6de2bcc555c239e825b470f1e22a81a00b8b42d3ac8a6b4dfb2009926efb9427ccb6cfea6fe77cb4a45b130ce143661103360544847015d80e99d62b39011167088b5a53c44366910fb98a2b0e99218a7c68848810a688113ec2bce8500b1716849a86824a6c3328ea92c46026d23e739a5b13d47bc4957bc415b9f6995904ce3420c243e8d9c942c4abf0d68fbc0616b9f699064478089fd14e16223c848ba07991991e7958a469a08f45b4a2a2932655ea13061e6945fac884815fcf4e18180c89b0ebeca46b222232e79cc91938cbe40c3c53127b70726848832249ba25dd5a41e5cd717e3bb16b509b27801663109cd19cc84f80819fc871ae3d849982fb168333539b690aafbd167908735634f31038a7a530703653404474b6c05eec37bf9d29e8d69c597b7a0853846b33dd2c42b888d766aa2d0e373b4f001d871f3c6f1edacc3405153e2447b28741ae20dae3c63e33b79276d0c340a51d699a36dbbfc33084058dee8723b98ce573f896565a6b7d756f476f476f476f476f8736d3182f8aa2c57925ad53cf7ddb5002a2d64e5a7b8d81af4974a6f6711efa75c2e1fcf6c81dce2ab4a2e878a90409a71db9481bfdea9c4369bdc455f2eb7ed3dbcbe992621cdd1de1289e22cc12ee2609bf2405469c474ea2843982d35c44d7cf7437cf12a6e924cc33e934696ed25c8421d72e66114ec2f49c0833e9692e82a308f374374d2f619e4ec2345dd32630e2b4a83e2b36cf8d91684e33873cc490d35cc57511a6a94d4b8a30e43417af9310234678255b5c3484871ec2bc28cdfc1485dc6ddaa1e2ce72fed104c9dbcd71453e44e4431ffc03ce73ee01841b6debd6d4190418cd43df26cdc54a3a408be20ee147fb6411e2c8bae8366b6a14b60642f8916f2c1ad14e1621cea373bb75eda2cf704ec3ed93dc266d6f9386a379252580f37d9e8073da79020813855cfac135089fb991870ce204afeec3e9350f1eac25f221221f221ab2444343dbf5d010d1d0d090f55d4911b2a7a02e1a3a8b8a7cc82c3a53fb438e733da4dd96b59a6bef60c2b03f34e499ac347200915bb7b813707ebb795e81f39ba738dfd96f37c7e54c788b6921f429da8a9188dcdedce661f6dbed4c715a03fac80c814916471ea2f44bee23227d9e80f3ecf64421f7b8f3e6b3f287ca99db66bec915449f7d668ee651fddcd3547811aef599d23c07a83cbaba2b2284a9c55dea7d862ffa832b7247e5cf66bef192089fcd4484306b45b226bc594907d83eb45e41fb15c40de165adb55557e7654dcde2a299a381b430c47ec91d18e6bc77de19d4dbc1f47e651004635c306bf3675dc19db59357d75a6badb5d64c7585abab83729acbd947545d537845aa61cea1a9c2d555adb5e7ccf4bbd260d4a0dcb8a41cae87444d920da5f77e3fcdb7288aa276f3049a188aa216679b965d87bbfe7eb6f7765a1ebd0418f7c59948a39d2e48076d8b122c082fae12f69928a6e5c75861d3b69730f39dd6b03c3353fc34375b946041a0794eebd7ae9d2a2e6dbb58a3d1ca6cf332acbf1777e8364f6188a70b8b423c8d6cb433b5349f9de90a6f518298b3de4e9265debe4551a4cdc8dd78d6d2f63e9b2e2c0a70263eeda4f9ccac1645cd1cdd9a37578149171684d0694ed2ce1657a7dd850561269e203aed746151cc4ea3ec5ac575614198b976daa8697e42b869eec282403bd315c4706151681f470fc9dd38bb3e9b790b171604fbf5977316c59b53c0faed8cf13373e6dac319cd8cf13317d9b45ddb95b8afd2750f452fe2f112bd088e18d761688f61f9e26cdcb61769e3acf6a238d2c817c7511c5f24c7517cb13692b4d98be568db2fdec6327c7168bce9fc226eec80c32f168d4445a40858cc8d1e4811f0f5504494ab5d9b9fc08c5500613029afa721bc2daf064fbcf5edc15b0f8feebeb91a8639675771afbef7de9bf3a9895e9f288c152c9f462b723e8d56a4e083b307cf8d9bc33bc2d340782594c09e1134a25541b8add7f1c445d2be4da46aa276a04f5d76b0c5e8f9340a3d7b0cb405e9e069146667317a1e4f16a48f3e9e2b804ec6407558d54767917d3c41cf61a4aca3b46f1fbb0e69981461b6820be68bb3b62f7e6b5284998b61288a6348f31dea9cdcaf0fcf2442250ecdf0c3b74c3a8c043295b6c9f274bdd008c6d81d8524db688a3aeba8526b4f22a14c2282e2064a928eb12f2875626fe0ba0d4e9c38b1c106672d410dae181740314a580d45bc7e7b5bc99d57390246425be0bd6dcdbd6324eb169b3684fa4191f2beb1bc9ddd3192be4a386bac3d6b6d7f9b5bdbf85af152368f2e9276d0ac17099b2ad8ae0218fb3fd40eb4c3281f8445a1fd9eb9da81f65ca894c194ed32c83e7319801e669f398becb3739f1b23e93825769ae8150d4f16335f81f4d188049ad76781c75072e6346731735af69987270b9a93e70aa0d36098da69a6d176c748a6d13e495021851c06ddf2f005ab88b544dde00cbd9714413b05f00a30062f089213b0e98b0f45c024056e25f70af639018ccece0960d43a8c5c7362ddc9dd844aeca0f3b66899b6286eb73c91b6552ce00177efbd778896652ee7ae4b4a2261df7257674fd83eaed8e789bbbaf08ae158ed2d74a3cd64965757028ceaa7c5550ac155ba9e820a57a9e8afafd0340beb9e300cc3a3da819d91e0db419f991bc44e465771f7cc43ed23de618b3dde02e06e016c69faac14ed6e39b56e125e2b09125e49f0f94ae27e50bf92004ffd65adb5d65a6cb1b56309033f3eb5b4d65967ab64bf2ee022912af22c05e48e3c6bb9f3e5bd760d640004fb1f5eca3e2b438815193f648a1efb2ebd1e7b8b5cd49a220c60f981ba0011304516b0637d58e4d004112b15180b4201b1214d8626d0e785388f9d841cba59b3a5070b1cadae9fa501f5e746802b1c56f454d140c7ce4f676909806457a9f2c1f3d841ec111852652bcdef8c8f1974988a5c15bdeeb23146634d953b314080dc692c3e471e007503b9e7317607a0c0a40fa01cd690e52963a1481da2eaa38167830c6db8f4d468c01edf8a9ba40d0f395abcbac6d819457680f0f286081e305355b4a4d411c89dce81015d38cc43d418bdf65debaa99d9e7e30a954400a128f96ce2b3efc85dc675ceebdf95db6bedbadaa9c52c80dc8558624c145005811189e1494f1f1bc854191e1ce953c180f00843c64a9a2e30a0da7535f4c95d28a6228744e48c094043e2b12380863e61659e44a101c8f2a0a808e9c58143c62566ac4c3d801e2521845848a10f2108368f1799c7fe8100b8c4e1e180238e1841858a44a9ed8c08212406500d3461728e9ed494f53c5c3478ec06c85c6a6ec810460d949134848670193a5145e78a0f4a2f0e19abfa4192ba54d127566a97b78e4786143924b22377659bbbc2253c631e3ba8b4bbc21342d688e199bb7cbe026cac30b0c70e62f7a0cb04bc947dda699e84694777e9f22e92759ad7aba7397895c8a7d16834b1cb83a31bf2ba4d168fb0ac1ed6ebac1e445e3b011c0cd53e0001a4f0f9be968b749965b0fcc3b89664c33e77f0d95190bb8cad1799c2b67666b073ef00ecac1d1d903b9c7b208fc7a3015e9e9707afd3854a3385f6e98df202bd827ea7caee5216637a90abeb47e6c12f13f49a5ab007dd8a65dda5fcb35b36ca4e1979d04a19f4a9b59232e6e505909f2aa7de15373d1fa12b7cd28441add35dcabe8b641dfc4a014dedd33a867bcb7babb7cee22e65ab8b54e2413fba4b99ea22590793708aab04865006fa96203218010b4333037cba6327100d606357502e826a3840cda16347ab862228e8a32907979aae1b6c5e40afa7b8ad4f8f8e3e2db18586832d4068c6a4e9f1da4fe8a4ee5bda2dcd6b37317697b2549acbb69afc76f02a99bf9d832d95a5de7a66b264ada0d691ac7cdda52cb63dcd616ffd4c9cafd55c47ee6a672db7ddda01507265afb76e86ecc3d0372077612dd06bd720ebe62dace7e0b397d863b8a4e3f17833ac783c548b9118b3dca5fc1bdf0c0b1e3cf6f367f389a9badeba0e23da16ca6cb15b5387350f9e4fa3156191874443dec1b3db3cc6c7f85a4aa3d168580c83d17e46b96c1a857e33ca4e7a8cdfa611769ac7786d1a69dfe907f7f0e1c3872e0f1e3cf83e68bdfd5a68ae08fde6d95c919d746caec04e736daed0be5d2c2a720f5ee4c18307aba2a2a2aa22d3be074c8591525c7af3d04933256920afc8b42fd66a35b2b7382772a23325721c111111140e87c33d9c699f88481ce29159dc99e2bc86c3e1c06ab59ab58febc248d6c5dbed86c3104bbdcdaa8a0a23d9a930947a288c64eddb4cfba2d18ad06b5ef3182fd66ab5300c6b245c1e4992d7479af6c79cf3d5a2d168a014c6180a23edbdc1de5bfb3829c975d2093661241bca11be1e5eca3f8c64ddbaae603fca7c5a8406e1b181a6e5eb4045ba5470644aeb89c9052e22a8883274426c281872d61e0d7d3a3ed6227b0ce77119358fdda804b54623240ad16bdfd67e00c26a3579ec20f60f317680c153c446922475bae49045048721a81a7648c9a1c5e408966a6dcec2e07bece6b17bb0523c1e0f07c638e7f36dd1628449181890a0699263b2c746ae1e632fb1ebf092120f2b439ab4b1f1ab82625c44ee7076220d2ad79a4f4bbc4e4f7810421b8d75e475992b2c3b594eafddb37eaf5d37c6ca6b4fba1a83c36b5741e6cb6b1f0186de6bc755df101c6899ac03b9d3576243623c1ecf062e94a786a01a6354c2c480b2c018d0638cd934c1f204890e292b3a50ec2f32be913b3cc2f029ce834f8f5e9738f3e9894fc0a71ebcf68af55afb2eefbcf6dc95bf1253e7f5d59595d75ea6a876a43c4db92ab306ebebcf151225bacb9a1a6aa0c830638a05ab3dcd3fcca4ac9f5e9ecdca46088fbd26260b6a0e0d2acc9da3c74e5eb17045e731cc93c70e6217c31047b0c82c66f396bd4c97360323839ac7bec18c138344cdecb5973af04bf6d082c9b2c163d77dcaafc7bec79e411d6eeedc40e8ca8d1c33543f55e2c790caf1632ccad5142465ec0bbccc83ba3a1f3b089ee50851465efb02b4bfa81fd407c1404ff3efbf32980ba5f5fae529008f1d83697de20c922f3c82089903080d011f2e389cce2851c385b2783182f5b1d79ee22ad53eaf5dc5efb52f80461e2f2c4fa0e03461826ad7e1251042aaecf1632607a028a83e53142ad8e73383fdaaca6a1d74b27ead7815d5b29727f576ead35bf5d6be17191e3b78953ef8fccb60bcd752282e98c54b61c538c06658ef87af4b95035771375efafd5f3f219a30eb9bf0b4fe66486e9f7c26663313fe02051598b49c2e869a2199d095704d98306162ef13a713146e2ec044d2be485ec91d0bec1bc9d3bdf7760e5cc535c1ff845fdbef11bf6bbf45fc267f87f83dfe3efa2dfe36fa4dfb0de2f7ecf787dfbeeb0733df1e7e17fdcebf8968be71bff1ef0e2ffabefd1efabddd7a593f08e1fb4c4fb809174f98264c0ecc10d49f090efc84593f247726ce5a72c08145af9bc0c1d9e2ea904c12aeeeda36e58bab94b70abcfd3ac678eb00b0810625489ca68f1011e2c808c48700e43c14116dc76defb07d68fb6d7bb9ddb6bdb69d1c45daccdcb5837de6b203af570907c0ecc0d4663aa69b14c1c4adddd0b983d6e6722e95264b0860bef7de7b6fe85ae311d99af64c891d6fcce3f1785e50ecb5ee1a02c65272a9731000e0920e23811b78dec001b0c1067e42f6135707ea3ccdaebbba24ebd99344a3f1880c5113611b51facdd44543670712b812a107220df6871c6d06c27392a9c33ad20123b083d9b4e806a75f1de83a130066eeea40dfc055dc5c8a14f84cade7537775e6893360d2d581bec179e2ea40d79dc839eb1ed45da513a02779709572a00625489ca68f1011e2c808c4879c87a2fca322c27518ba95b61a398ab4d90e75ae56b4b1cba40188754c77ef52ea48d99df3245e6b5588d7f1b9af4e050cc00cb07db550a268cb5a6f3daf0d8158e2701d408b73ced9e66c6b05c15c73b65b438131768d8f7d05a2d18a9ae218a7d10a18590523c66006f39b299efa9ae5ab5bb08bed1bd1f1d245ab8b3647436dd1156eed540925105b1991e35de2b6fa9112a8a5a4db72290eddc0b1045d04c9dddd67693373ba8339645615b8669d34f7a8ad8be055c2b7e98220cd044fbcbb4bcad959bfee9b6ab71dacdf30985aaab7aecd0c82b5abaddc7bef086a10144117c9bc49332d9d9c9c660ee39e40236b2449fa288aa4388e677a7be038a630bc346de34c8fa3985ab78de2ccef8ebb2383f89257e730de71e731c60ae31d6f94a669ed348ee3ed8de30882a3674f2fe9e3a669df675ac3da4b536bbf91e36c1ccf543c61804fab9d3b70e378c32ea3eb22196305d1e6d749bc51d662d14cef932d7baf77778831562049bf4ea438da4a9bade6d7492cc791d4d971ad063a266f616db4915ef35b8df4bb6334ef0e70070e8560ed491809eb32746d866105b1ce272e52e8d9031560a4da41e830cae7c0a208ddea6a07e1cc65a07d7419e4d9c922877130cd06a6ed93c5e82b903e9e4633af79456995c5e834eda3efec34afd14ca3992761a414e0cdda69ce22bba849577143a3998f3a8c147ac5a157340c4317cd1c460ae394bd2c56c37036b3609606fbb36016cc062d56bc41310cb78b349016fa08d62d863a5f5f9218186a6db58ed119581b03b164d2b7eaea920e2355c7d8c6cd25e1255ddd3a15de8e57a4a0b42f31ed7c42887e68ee29d74164cfe4ae48093a086af0e6730578e242f9da3efa2a89b93067d72d94d8d312e77876e67c823bd03548ee34de6a6cadb5d69dc19cc3baeaa5acb49e5a3010bbb62ab52eb9c3ae5c96b99cbb4e9726a5291e572b0cba05add679a6fb9c949bd214bc24dd6c57adf50982d9a1a4b059313e53eca1761067fcfb9acd9d416c79a31adfd6d27ba3af574c66deba8a5b75752bcce9ab5f295f1d7754e2d3ed8116b14f43d8c2fbb4665d195b7c55cc16aa2a264bd4a7b8af7efb7ae584e5ab182dbf4fcb2dbdaf62b4f83e1daf987cd4ab8b1126f6fb3221d69b15a8ea6d5faf7a6b42e06d2a1f448623cb12d49415088ccc0bbfa20283917fb4af5756c4befc7a8503ec6df52ae12aa5568aca6d165b95a2fab5592394b8131e84e0fbb466597d5ab7aefc3ead5c7fa188b5d6a4eb454a5da589cfdb14577df59b84bde8aa5f1fabb6d6a747539f96e8faf4c45fb04f3dd012a5507d7515578ac92b49b9daf1e3eb1596a82b1d3e1d602a201229ab1842bf2a86906ffc2a865096af620831f9af6208497d1543a8f7d5f75731849abe8a1944f6e99efaea55cca037532f43ac77cb6f109e04f89040a925b036d317754656bd459dab6403623c8cac227b94ec607e9bbb44ed63bd08609a523a538d12b52e3a538d2414f4a612b54b252e92f6ea6ebd468982ae5d07eef2168271cc1e7a78a67ed625d1c7b314dd3ad9de5512cd5a95680e3a60b4a3699d467baf157d5717b1699b2680516b9d7a8e4fd1d36d9b4cdbbb3adf2a67ae5d0c6fe68babd305d05e67580f39af1f4bc69aa0d76f90d9c0e10acfcc1d34d5bd0b262f73aac044fd6101bd587caec48cb4b0850c3a8ee7388e63cd8d23fed1f7f8c4ea6d36bf55c89dcd0a2f65df89a47d7435038edfbf3db7f7b679f97e1cfd522177a36dca9542eef6d02ef77ec1d4949d3061d2f8d181a6497b6ff70de5b7eff7f672d390034e132435fab80006ad5757de2836bf5046c7fd781507d08fe378e505f5a3df2739aa916aabd8dbb7ed4e8d4336232cd476e9e2689af9e72aee1e3ad34ce6c4b7d4c278a6f687b66def7d734498fcde7b0f95dbda26e46e57492531c95278c95acda49b5e5fde914ef396afcb2b8f69af69fe65b0d79ebddca52c2696b33e789a9fb4672926559949559eca54af3d33dda5fcd3a0d70f4c10189679af35d96b07b7b49e6907a97a6016b04a5b692b8dc3c4c8945819f1292e037b200f6c7aedd8eb2e652a4d85bf5e7bd0dab1551234afb5c65ada31937d4ae922ad1d373dbd06a1b5c650617729f77a77ec3591f6eb93fad2e1d3cb75c16e97f69be52e655eeee0e975d248febcd65a6b504c4c0f698da4ca6b9cb669af597709fcfdf4913caf87b4d6a006b53e22e53591d61ab4ba27f49037af3f68bd04525deda0d65a6bcd336262e6c7d1ef1272376a1e5ed2bdd1adeba7abe46f73b9f14cf7e83ceba35f25fe55ea9e1113210f0284df24e40e84ee19e95e960281b544ea3f7cf08b84dc7d101b41888d7e8f805c69f652e27bd141d1af1172277e18d3f2b4a6468949e8fc6ce6b708b99b89f50b1dfd12217763f69284cae7467cceef1072971b67509b49ced32cc5f71e3cf81542ee3c9cb5dc636ef45d97323afa0d523ea5394aaae98b0af0457e8190bb220ffea3df2772373215799a9d90603d11019ec8ef0f72473416d17ef4eb83dc8d637729ffca90f0be83835709c577f0db83dc75005b184bd4faed91bb9117238c75f0ab83a760d85b3f22e68786fcf2183b8c7e7790bb91cbf7d6b73628f1db6b7ae2b77bf03b84217ad210f952e4c6ef5da4caefa8de6fac283ebf8db0f9ed5707b9db99cc290bdc1a12e5cbd26f0e7257ee51cceab75f1c59402f503f03bccdef8dbd6d5e7ff46d33f7de7bef6b43f75e0c2fe59fd5bb0212c4870f6fac2a4fd5f8440a6a280156a2ae94e06143c4e9d6b834cefc01a25566100e1aa6e41c0d229b83640c1a295eacfde032d9cb82190f40902b33429c84bc11f2e7b7df195ead86183942a72b8b1f1a685a3a292208f78028524e6a5c70b325a35a7b6500a1c22608efb75fde115e5988101d1be06c1f557ed3f0fb478fdf3ff8fc7e8233c85330488b8e18b2d8f07265b42df4a8490144a6098c4e8fb03a369bcd56065e41f887eb3df5c67e7bd9832b50cee2a4be80a0520e2099e581070080ca9f950e2e4ca63cb199b36d4d8ed819dd20f1b231688c0d60acfcf1c3c3eaf7d8c63484c94802a68c9f3c96896f5695f59be2c2172c400a8de338b6b9d3e71a6087931f0f1b7cca114da0242c6c15d12a52975c9530e8d9a3c64b902d476aec11dbf103a727cacea841b13c3ac87ee3d93f8c7c75c92145c50712254798d4ce2c8193a62c6c8caf4d1976c7ce5073da0247870e1d38e090fb400e0e5a3d8ed0c9c365937cd5ea1e24739cea9029e2e7064b2207d676fa015652ad81018c8f365204c5b831e674e64b8d979f302924803c841864c31d3d397a38e151820d1f198d2e787414b253e7a6230e2cbfb76f1c736c28c9761128a8fc01eef70d2037ba70f8f8ca49f11151834dd1246537cd4043e99505480c787883ba82d823553b860ef0c38718201d63a8fca1f3b32165c9c69c23309b1c2b3dbf778d25bf6bd43043ae94b387cc921b0065f9683843a4879bae2a74eea069d2b6198992431bc382942e84b6b2b4068950266ccc8e2c53789c4aaf38970692df322c00caebc61cada91ac46c45905479a882f4084a0235864cebaa2b06382c0842c3a4d5551a208cb72515368706b26ab344905499d5ad3b48d400491303903b251cfb86dcd9ce5a5a311fb8b1f96892640c103f6cc8ba8c438ef470317894b113a62aeb0b98172edb66ac636e6c6ca278d4c6738dcdc61d1f952a2740eae050a8468daa425565a02c94102e64721be043e60b962d33f4f021038b1a2c7ec254b1f9ec5843cdb5890063074c9598383f29a30d22652b816cca0c3ea8aab80983ea34686c1b1715651c476d3bd34cb6c54293a33376db3082c675e36866b0713c4b6d86dce932e4ce36634c005af637820b415ad863e40d978dd106448a460700f868b284f7233287e7a56e9b5b18c89d8dcc03324af6183a1eb2f6e8e50c379bad748b65e5a0f971747b45eec65d4a31b2678b8f6b2b8623db9f90ecc0bdf65203555e64a07adc112355da4ed0058b9662b2e414198095cffa89bb04a238f70087bbfa92e171381c0ee797493b8501c1903b5cf936860819bf8027112eeb8502839ef0c0d480c5891d344dfa6124906e72a54f9d2d296398be9c2fe06c2a1894a56a6b09123b61d034e9471f5255d58c9d1ac07050f226900c17ba6c5b103860585e6e08514133f69082226259593d61c10b150f1487b3558d6eb92881ef48f26c1b6edc62b75b2d374fbadd6e75fe76bbf9bedd2cd6152f360bb9d37abb81f2da2d962b29acac15797d3c1e0f084a92524f924f92a4d81e71257cd55692a86102f8b48ed53226fb6499a8a9f2c647c3d7cbf2d52095b5a6cf6b36586cb2d8d0408348561b393cb2b86ac872e342d61b1f56a63255157247ee176cc8e8f32443ce1a1fb6178505826b0999364d60805ab03717b769e61f1552acac1765901029ab2510e52124cfed053bae604139f3d583b36f242936e58d0b2ff478bc29e44e53e1a5dceb5165e59c2f145691cf37ea52d9b29c7139bbfd11f94c96738eb25275ac149b73ae5f292cf9f0691db34d64399f48c229047d0ee173ce3a3e3b98cb3b67a92111b7ab287fbb5d0dfa9b5b29596a069627c38a874e312abdbecd6f4337b7514afbb431d51035657c7e1cdd422177a314531302d024af71d11a174d3a4b8c64fda6d18a916847ca8a26b9f3aaa02e783c34f52753e4042a9a745e298c641dac528e5962bc3c0ee7d6c9cd08e7154d7223dce964005e5101f86d6c81dcdd0660266124eb0230536024eb490418c0ed76bbbc9bd20b79d241d20acf936e9b903b929675972eefb4da3b4c92df3b4c9fdf6e99d434bd2c459f8e609ab001036849792f084a6e1272973799e3090f0b903f2cac7192ed8eb29af554664694141e2a48f2efea321849ee34d21724337c2943929464963f466448075e84c4f1c2e7c8de365f9e10afa1ba9d74716fada64cf224afa8ee0529352fe831b26f7bc8d88ddc35aa004f9f5db8f3d96d91d24a61a95b18ba2d0b43320cd3b0f0a1fd22030bc542b17087a1dba9251f5a59aaf017fec214d87c288664a12ff49d48c2e1968d0f77880bad423f0afd8520431f8661185e263451fee6e0cd2d117277bbe1ec107277a3ca655b333c49ba85a2226f545f4fba1542eec8af1c86b5c5e3b783db6d904d5a2020d7991f0738e37bca79009fddfe2077395b75bd2111020c3f9f1655991a5865e464c13203e7b55b1fe44e97e5588f1eb90b1fa047061320397618e99343ab030921177bf8c8688a0224489a53d4a4d67bf320777b07b90b7d9fb35b1de42e6b1c58b27a1441c34347d87682928fa03cd570e347863e7850f2cc3f30a7ed3607b9db5a8c7024dd406547068f407e7e689af439feec1833b0dc58e3c296153d36a039e77ca3098b8c13d2876e6d64ad7525d3d3a321e6cd1b2856a4c581a42bbb0f0819345878b200dafb666bd048c731403e8fc1faec96a9c4f996f30c66e86982d2c29ba2066591b3bdf139e7ec230d9795a63766682084e6300cb3bd9db5d62414b52c906e67581a79c2d6c0605ab9bc5ed7af1af69ad45a6bfb64a32c9338da6b6ab3bcb65e5e7bd76bedbbccb92e6986d79e42c5082488c1e1b5b77841e4b59b900293d7ae829515de5595a61a5e635928a9abad29a9d75858825ebbadba4a152b6bcc6bb732acc870888d72e75f26cf3493595e891526c887a1c720776126c37c24e40849ee19903b0d46ec737619d46a356771972eef4452cd53ecf95a085fabd5fca896e66b5ff3dc553afa9ad79aef9a975ff3cb749d62f89cfbec2b90bb9cc35d6350fe32d594d7da6140eef42f9f56d654a11136b55fa04215b34d9e6e163f1e8f5783dc1c1c29d3ae0bc3307401b8bd0516c5a7b83f4a4bc8f0e989cf5e26ea73ce2af3731e9fb3ccd0f9ec2c48226344450123544849d4153031aa345172854b90ac337942dfb6c9dae0425554e9dce0fb8531c2030f0f1302c928c304cf9b395d722d67120608341abf7d0597cd87663e741590bb30d3be94e9f363861e54905c4331b686549a38533f30206062b08292b59d82146c9616ef737614a88097c09f4d412ff0874126e0d46307a966c401b33c069fa21ee32c554d7016eeba4a1d1c3bfec2616264337694813dac857d200f647297f2ef87a53ccec27e7d781e5fae10861cfb1dc3797acb70d3d6e34fb1d3e39be2dee39be5e27aa1ae12f61b75a9b015b6c2f63768d0ed53fb4586a970d4d4162922b01496c2f52b85278f710ff72e92753245d7639c71c6638f31def832a5d769c6922f1dbc4a29bef413ec9208140bc1be741390bb1214abe1bee632b67cad56cb9221c3d71c057257ab95670a92cdbee62790bb1a8fcedb1cb4794aee6c20dac14bb0bf725821413f3a38ba09e46eacd968680dad39094aac424c1e87f311ec8c0eb908f6013e1d7f13daf13b86df84ecfcf61090bb9dc56aa0d1e8f5715edb0e0272571b71e603aecefa53e936c9ad00dc0ec0ad75020c006bc890b765cd0550f3a45a264b710fc28ff9ec60f60df519ab2cec33d6a0abcffe0172977300c4d0ec1ec8549fe248e4f0e5351b1e5881d8bc16f4e3b5bfd00129356ad1f4f2c86af8dbcd3bb0f776b19fee5216fb74fcd06b8afbd0ab8f0f432c405b1f92f53e740ee46cbfd75e02989dfe5479d241d237108e9190bbb2c4db52bccd6dbab725bdadced8db6c3677406fb3393e42ee6c46ecaf8b078e22771fb2ba667c5151515191cd8b8a8a1c0e9bb715d9610c473e0c432243522809f3a2e8188adc8949b03c0e872b1d87c37912c62991f2b80e383f386f5102ce86c3e13c47d4d7182a235d65b8185a82945d01ba81430e1e9cdb706ff3246ade66b379e9e76d8e85e48a92687d5191e7ae52882ff25de438885f85b6302c71e2430f3efcf2a183a1ef191f7a99f5a1e7bccd87ae0ba50a7de818488a2e5f3ae8b9d277e9f889dc953fc81d0eccdf6e637fbb7989db8dc80c7fdbb73eb79b9770bbdd9c38518d4d91f2070b4dcb0fac2942e32ad010ac33e8cd86195e1884040d9b3c3d6e33c853c80a949a5f1c2437dc55eff7389c6f1cceb18f300c718f1eb9bb89f9f8d9cc318f9b6b2f61aeb17cbec5f984a48ef52c94c6f3c184d572bba501102d564bdb9836d0346df7e8d20b00aab8c474916bbf633a4133c753980a495bb9f0daa64b680fae1d7f71e0e7f590d60375957251263415d5eb0e1aa7b94ee440d4749544a70eb2bcce69ad03c01bb2793eb8f65c7651681e80a86c20d2048bc9099f2335c0be2c1982a655ab92593110ca9f1a33ba60cda085823c3890dc70e34eb5b8ea31252648cc1629687abb8ad099c3e4bb82f3064def0ff7301496165800bbf1a68542680af25ab421e2c4e70c8d2333d0146caab25a4364509c273b2ff09163030e63d4c4d953e6c990ad4781c2f10e7287e2c3870f1f3e38d641ee3e9cb5f4213b3e000170ec44ee0270d67243617d071d38ce41ee3a104551141de32077e215948d3f71c2f10d727762369bcd668e9bc8ddaccc9b30e1d806b93391cbe57239c735c85d4e08d373c081631ae48e030f1e3c78f0e09889dc7908b2f548488e59207748672df75510deeb748e67903b5d51515151916319e4ae48eb010000c73c720780b22ccb42406afc061bf825b46d369b6dd01397d740e935f05b46ee34c0e1709ec309bae341a0ab1f3bb07228f1618a0f751f267de8a1efd02f19b90b7d8079d3f40b88dc9944d8d4e93a4265c5d4e5ca8795bfddf0fccd370b39e871dad22284defcfe2177373f85be848325fc8e91bb12672d370d4f14e289c29e88c84b5c2222df78a9036fca1e1f1f215335a0445d7ed028739244c60da2163e0cfdf62177a18d28cd674f8a2d61deddaf18b973293c1ee33b8f719114378f3be04a08d72f2c2587c7365c0b619ca30a53e2532b0507ab65b7ca1e13610fb05fde6522c275a22e15ceb15f2f3320e325bb4af5452c497078aa7ec05937d8dccd635c06f629080546999e824ca6a8a8b2d8f914f4815d27189fc769e635f5d2fc2445f5d886ebe08d62cf5a57a93e2e814fe83969a1e90326460b3a022fb02e2f7ca94148105cb52c8f0899374cb0ec509235a48d1f1a51bd3f398861b12b75a76c1618d64025f173c3142ce54b8d2e235f78b2a0297693830e9b317fd86c91a15141c0c68468b1a2044dc1a63645a69a70e192b5e7ca932e83ea08b911288b0b9a823845933c5a6028b485cc07dee15073074d1b31395dd8b3b6ecf81225fcea217725b2b4643d09127ef3903b1259c2fe3cfde22177e759cb9d65c89ba6df3072679eb5dc65902f4b1bbef45dfabde358aede1d74bf38903b3f6bb9cbb7d96c9eb3f9b6f9bdc13f7cf00b46ee3efc7951f46b675f51f2b399df3afb4a8fc7e1be1e87f36b831351d5f04444bead543d91df2f724774d6b2fc40924256614b0015b972ebf337f16f35fcad0ad7192357356ca0b283defcd640ee6e31ace1623334a5e9b59bac293350d952c54695389786241bc69312e7c918413ad0b4fc2c1a5696860f0141d13243aa2705840ed8e7727e7fe42e972525ea3dcc8932e78b8afcca217745337415f9f224e93992741d495e452d7992a4437a8b12c890247d93a893b01e5d7f5aa8e323c5d49173439c39525348af631f867ebdc85d58646da4ba2272e25c112174658881dc915a3f6284df2e7237a24a97efd0a183f60e1d3a74f0dda1fc0e5e6d3cc67ee1903bacb5d6daef1b37290abd080745f8e5227722ce5a6e27777e68e8f743ee5709fb9097181af224bc647b3c1eef063a444310103966aca8d1a2820e7dc998d3a30e1233625ad0b4fca118d6b41951b398bc0082899b26549a146a814d560b7b9c5cbdf6db86dc69ad9aa6785cfbf4b09869f2c448211792aa0f6b0d95398fddab30b1f2986b861c84ccc04688980c28f6cb86dce13529826cf923078ffcfac8ddd159cb6de57396137af612377bd2930c9f4398a1c50d4898cf75cccbf6ec132e8893b771de6ad92d9b1a2c60ecb860f5f52b84e6295c5a202287c94a0c685ab2c1d2ab42434b1c25d98a2029767ac059d3a5069a5a5e5194b1a72c2268a2646d91c1c14405ca58962f0b089bb7d9fcaa2177b6b44492a779127b1cce2f1a72872b9fc09e243d47fa26fd6ef9931588bff93d83f1d10f2d8f31fee17bfc74e4b15f33e40e73917d95a93295c5a34cd60f291fce3e94e10db0270d9a1f5ac29a68a0a1df32ae657f39d8792323bf30903ba3b3961b87b1df3b86dfeeba30050ebf43e8fa9dc29bdfb70d676f74bb858ab25215284343846c0e124159e86602e4caefce93b01f35760729a73260ca58e891edea0b03058a4813d98c16360c9e84452d917292b2c4c40c7eaa0a4de1c346ce4e1a849495430b8ffd92c9e15efb11a025af35a02d321daffd8ec9d96f16b9cb5980781f867eb1c85d7845eef69f2c0fc241107ec5903b10a1f93577bcb4d1da673ca40761ed0f93af95350f6a5e73fb746b35dfb5b2d66a7e02fdde7eadc8dd8e9124ca541c2a4a70e81208bdd2f1e671170c7fda68c910c56a0bc57ec3903bccf5e143bf60f01251923b3a7ce090ea2a83a6659118b29b115cd8d4e971434a203154fbfde287aac467bf5ef60be4aee6821476b192fa4c47f814a36b334df135c7669a22a599a3db52d7ce10e6650a71cec86a5203939729385ed052e3aa6434ac06058ae18aeb4c17206b8c8c792384aa081dafa136508ad85163c58337e44f5554191915133330c421cbb181400e2eab305ac4a662e072f4d51b54e549948d3d6bc4352de8f3248e0e2e2079f46c819ad1bb43e30a5317272379683e0f3a60c58c192837705833480b03c8b891f1254c900f31477a6a88e2d4e92ab3030b2f4f960f8429e9d1997243a1ac2347c63436a93857499c0685a982c505293358603906d1a98155438301385456c65c31b1e27565ef10a79e2689a069827e99aece2ed1a344cc1f3d4fbad8c8469a6ce15e9872c50a4e922d5750ed7eade83429574321c593e76dba3c1b657d7be669679adb6c9c4831c37bc293426b27113e615255624832c40bcd67ea5747a05c2aa6dcb3e59e2db589fdb591fdb5655e2df36a56b51a59bd41089e3a3c2539de804153dbd61732345e48e20b84a6b65e1c2a3d2c6d9a90d480a6b634596e18cb1107509c31686a9b5ac11f3d59e638f18913064d6d55b62c3d213f8c3c1923034d6d56369b2db58199f9d4a655e6539bd6a736281bd35fb7f1ae52ad4c8c142333155903abc1f0698dcca7b5319fd6b4fe7acd7795b6d7c03eadd5c2fe7aade6b587cc5314b2a6294f42d0b4d6e404e5052708121a8068a169ad87c5648d141b253e252ea069cd43982f1a59b83c292143d35a0ca81f74ba72d0f00ae284a6b5385d595b86946111f142d39ad5df4fc932f03782bf311dc5fe8e642449a62498161509f59764faeb24ef2a8d657f7de48d599f8e589f8e573ffaae12d75db23f1e8fb763f4fafb35828d35987e9c89014b0b84d2a0e9d8f477070c386e00293443109a8e3d12fa4019c2e3cb531611341d6750890934688e101d68d0749c8200192d6345a8fc9961074dc72a245498ecc9c1862b47bed074047d22e813c54fc5540cfb2b8e59d1ac683f5a4ae3f1fe8a4c623e15ad3e15a944b0bf2efab028fe9eb4085d197be38505bd01f9a2d2438bcb141d34157b2d2872674ccc878f315fd054fcfdd9ea5383051c9ce2a0a93895d2668540aad920df2c9d918191137635a48c9a2b66d09456f5f707d4102e41500031a129cd8a46a3a534b0309fd2b468507f3fa531e5f8fbe9acecafcf78603e9d7df974e6e5d3d9cc7795707e7d369bcdd29990321c7e640013c58a089ace9a50c065e70bc89524bc22683aeb75a02c8c8ddf121950fca0e9ccd728d1c3a586415166d074560b4db9f0071055982a25683a5353c70c0d58652fe4d043d3596ff70afd16db364ff7d85fdf53fb854fb70b9fee2e9f6edf55baf9f5bdf7d71b267eb28074b141064d77130a5f1b2e76f6d89901074d770f8a8c980d359c9060a1e906144488a016e288956183a69b8d178d2a2971dee490064d7795040af9beda24a90233064db795e65514837458e8c332ab504c8b692a9d6ab2bf1ef2c22adf55223dfcaaf26908f6370cfbeb61e8550218acbce0240f968e1c681ab6a0e6490f3139be64bd41d370ea7599916c244b652b45f697cf1b23847af0902a8432c0c98c3a4fa668d85285a67aeab5d75fd75ca906d39acba79aea2fd45fcdf4d7b5982ffbebd997b77c9ab57c9ab37c9a7d99eb66affc95c17218111e4c6c02e5b82266079ae6a6bf5fbcd6dcb03268480b689a7baf012d4f5a605288863f50d0344b3d7185e55087cb851e52d0344f0d80cc4b1499233a721882a6b9eaaf19197bd8bc50e30b0f9a662b22e02022851e2cfbebf5969e82634fa3d05f1ad8366131cceb0299b0dc7a1df4815ca0d7570a2f2a65966cf9e2840c4dc13f639a6e6042b64407d6c57e2e0b2a8a412a90b980ba3a1295c4e724074db1541e2734656258c6ec4882a6780a77e1a56a751dfbf0d246530ca675054361a6bf8e7973feda500804115414d6533bc8048c0476794c563ebd50549fde2ad7f74543ecdeb0bf7eb9ee92a5e2f17839d0ebf522204344881931619aa0d0f4eeb0d1e6ab870d5c7c70ae1032277072082406054dafd45f1c32282182240d161e374a1b29688050213192a70b8e0b31e400a7aa0a1534bd566fcbbeba29f4d7655041b04045617d4513141d626ebc3143033582630f0d6ac0e6f82882a6b6f7d77a85fdf55a694ec5f2782df00af5830a4e9112e5af93c00244efdf1afcc089f24428072346e8d82194a54c8f3b7df2a08e975cd0650a953b6401a71da8a42bd7aa5335e8104433030000009315002020100c878562c1609e699a5c3b14801077ac58645496c7d32c8a721832061944081011810101009099b0011304a85f251ec775362451ce599b526cffb3f6e3ef4c2204875e96f53a8ffca3803683739da716f90e547270c08142a380c55538638b43b40d16e1e5729a16c70c7bd8bd118886dc986c7b18354662a316b4188ef231ee022440ca906132438bb5f3ac54b90dcede056486a7c74628405adcdeb727c72b56260e41b99c4a4c364a6d805714e1c6205ede247eed51251d3c48ae26af3188e9f43191e56f67e46210942cd2d770b314b6ffea57d0c0918045ba8efa9499540015ce8aa4085dcc4bbb57b07edcc80db242b6af06d7e04b4a0444b644c4796f8e8188686f8d30f666b7736b0d568dfb83e3597b478c82fe9449b62eeb85d02bc284e31ae9831dbe303c43a11d20a87145477b0ab8330e5fcfd56363e95cdd9acc2e4759014e1c1fcc8fc124c0f6bf5eb9f19ebefc0ed928c6962acc86f17e25d00d5c6315136aa912a9570c19343008541295d756c0a42810594e31b186662514e1be7ab9933d9554c39787c04f5c508f39677aa55d637639c481604a168b6d1c455f6fc237d2f538bfa6e5208a9822c1529a30d050354e8ad87679700732e985edbee4c18a43d407a33d4e725a16e4753904b02d71305b5c8268ec9380d2ad2c3a594457fe626235320f77f5ce1614d3d21c60440a8a358bd28f63c8a03702b214183889f5e7b66b451b43a02157d14854e5f63081a13273bd16543a6736f4b436d0923156d4f984988bb45b32c88c3710b1b1c610860712b8f9224a5b20430eda82b74c4347a85622401661a08c488a9197703c3158bab60894381df59ff4514d14dac3da797f2cc2cdb6dc845b4d14aa1a9e2425d8c3a15268a2bc595b8296f74ceb7d1ce1eb1e11811436024a1527e4c731c0860b19eee5d03b9f8aaa2f1e21192728b8ec6e03451d6594389466a727b7464f47c92a22fcdb3a88ed15acb560800109c44e30289b93427ce1d3f30696aab4abc01cf676c6ff4742c22a530fe75a656626d3cd07270d37bdad4a5fcc409b081c72144ede562566c2baaace1b0ec7a29261dcfe88a08fdb9dd870b5f96daa346706ba8b48ce289e9ccda8e8e88307055053f23be0ddc3dda62ceaaf1ed3fb9088249dde031f14d83bfe67d4aeb38dda3e370e22d77678b4566a0686c864308384a11db077c10b01d01e65106d76432d0cd6474918a62541f4a40914a0852cba2472cee6e2bee218ae5943b45700be7a1bf5571009641eae80e77febe037a91a8608fea819cb25479b4fada844dfb18641975f1dd22bcbcb3a7fd22770f763a2b1b03807e5b5e216a4ea507b01873bc8ed54432271be395416c0154e28620c58e1f02120e8f61d6daa2a3d75d5ecafb11cbea5784cb831d96157673bd780376f1fde199b43fed78aacbce690cbc51f5614c5196cb958cf610483e9a4c1a47206b185439f456e1d49735fce642ed5e8e4c5453d231c42605b96de39e3d184c26fd6241ee31d4674d8a22774c51143a66d358e789c5c5877e556f364a015c4ad0e78a3c259b7d5ec9dda09c8d1823eaf149a06acba534a4c82984bef54e2dfae9fbce9c3d3f85e258e97059065c1f9bf053c9e389929127ff31a74faa0f870d3610665c061a1f5e6790fddae2849f5c01db7850f7cfa82fc835c92bc639b2b0dddf143791a7fcd143ff0dc267075b68a66db4fa79d23112d81f6b851d3d87db1b475759d408bb2d02458956c1b86b760459d7e21d0e2f688ef79559bf9141c65fac001ed61dfa0e61bf5a039cfece8d400498e052c23bb4620a21884a009ea99c22a6ff999533e19a2e0057845870755f679e9023c57c9f75656e3223739f24c38ba8029f7c34727a88a7390f070265f929eaaab280afdb5205475255686dbd4e8e506ff82c98c2431823af8784a5196623cc24bd2d3a17a7ae291c141f37e9c7ad583d1119dbf48bc2a27503bcfb417746cfb5d0491e22f2d0db6e1a753633143ec06ec25c12a64a198948bf19fa01d96d53f5f3f73a8cc217be38eb86241be29c971b4d158af49773ac0ac5d6e6ecb84e51c3113aa4f2bc55b2d6c580c03585c2715a51cf998b3a58fb174d2bc7c56e061129c4bbc4d9ac74badebd19d4caf4ba8f399198afd0a05f11a668612098e9471804f1386413f4d02d686c8db15318f02340755c1c86d6e74c07b83566f920e0d39cc916f3f0b4e0ad58fba87b13878a727a6cbab965bbc9f8d6ed01b2b3b1f90e5097203a220a8d01af228e6624bee708a3713858a281648a554b786bad2280b187116b7f0a457f7a68fe8b512a2f3b1a47a41458c0478ecf11c2e5d2079348a3ceff30c126f1948f5b6fb3edd1cb665951e4d67b117f0cb50410eda26460bb715e029728c00c26515b6717b37636bd336c0d5045407025cccd245befa934e91264902174182d4ce87e71bdc5fd9ac679dd1c69840191c2e244e2740309ae234254f716a09878f98a17bf046a13bc8253319e89691a887f5f21f74a5bfa3cb28e6738c757ef022c2f15e8ae2c1a392486d81fa2a9a0183328de3a1382f130c18711c8abeda166e76d610250d84109c1f3442774abb0491d8e43cf00a5cb962f27cbaffe2e8addaf02ce8d1b6d5058ee00d27a5b2f9ec5c55ba00b7592806818f3d89c15de9a113143a550a68abd8f2cacc58a6172648aeb6e6a71a1bda8889a784d2d2b2881767c0b0cee56081c4c70e031b989efc8e328ea30b471097b998fdc310a8e380a3d2fcc7411e66b50e903743ddaa44eab1dffed4c40e848538bc4166b13fc48f8e37b213d80c0daec86d1cd6794851395c3aa7e08024395c2298bc22b8a04d214d67f9770a008088757f6e05bca0c824e46eefbbdf1865396740af849509f6d853815f0f1faa4c0e88a0b8a37eb94d149220e9c50d6d9f1116f48ff00b49f69bc9e84e217d0fa4115f5f2a9b2a46099a548cde5366b0318dc4b8dc0d47fb0d049abf12dd731f69b3e44c219227ebdfff920f91463a8ceac03bb0c732887be3c1ba65adc7034438ec1829a40e6f146e11295b4edc8b85f66ccf9d37cbc6d2c43fa94bb602927263e04091c93ec2e81fbe0dda379b100aa16ce5d084a2979a638f741e3a7b82340cdf47bb43feec1b0f914b16ce313281114af46b68528d8bf6ec1adbcd012798e7f24391e65dc09a6733162295b64387bf666381adcdd855e9b197797b7b6862a9a30161e26e94a74aed4295fddc4b954194480e2131b7c215175080ff0f7e0a47b7529675e4db2b46210bdedbe7541012ae2dd6ad64e2f6f2afaf0ad16bf6693ff0befb084abb689a100448174676a23b1a82e92d84f582b181344322e5336b4349641194bed13bc6c43b36dec96302492138417af6ab646308eff5b36d6e960b3ada44eadd6bba93c88c3c883ffe06c84890bd11eead57e00a04fc0388a8b58844d9ec8db10112981095a0af4da4be5fba0214085308af6952a9b541f62b004fef462f16bd451c7c41178932b6a19b133978f64b3a4bb5527a5e118b747facf0b334b3bf72b1857f761024c78cf0dc410ec67ac9bc662e81ae82d26e02b1d98351d6f83a887b0e728f202243bf88f22ea7fe325c631b1fe211106907e81797c57c9c030b01b3e2e02b05fab9526e8988aff6a6602e568a3572f542d9b586fba5873b45e125afdf4eb75c19c92765f22087fe3b80e846d842e743fef95fd147048902f79a987957571ffa913c6836d5fa2d72ee33cab14ca5bd352dd4c64fc0221599aa79689b3ff33e2875fdb1172fb02d4cf52a2cf826320ab778c67b6db1b78d97a3b2b500291038fac048892a2893dc6be708e8167b4d67ade7d0f697e1a8bd7d6a786e638744f75dd1717b096e315c17c6986efbd72896e8bcff2bf5fab0d7e78d7063ea954fe7d9d142991d016990a119a72b3c1d5d4d2e3e19809d3a4e74eaa599cc46c144e503a802931323f6b0391138addfa2aae71d679f77edaa816fed45835981efffea969e7c8ce403ccd370b2feafc6d08fde08d7d51b7ad27b4bb7a1e03380d7f141967e20b02c6e48767c8a3fbf6809c2cc4c1355d18838c8a24c6f8c537b2ca08bcb6e5c203bf6c3e11e39824abea0e38cc02f0618def492e9bd96685777f861cc6a3f1209e1f1301eb688f32d72c25d8f78fde3fab82970713d1e4fa308bde1d345d99cb2f19187bc96246acc9b768345ba5e5461f066026ac49a9807219682d2aa4ee14b0369a2476c6bd4cac258af39f606f88d7563e9257d5c253e25db4126268372dcb12b9905ab321454e3862b8d78ac95e36f35df91fcc9adf3987903b877efbbc56edeb9d05b00fa3a35048edcd412741dc9a9ec7058b2a7a8a0e1fc1fc48e8b909ff13843722cd6a6cfd17a4696612cff42b7180efb3ffc39ea1f7b351ce069b633e85c17ca7403fafa61eede4fc5b23d57ddb04abe5f1f90afbd39f3f66fbfffecbbdeb132ead01895a4a46dd4f3edde1ff3d9d4e74149c7b725ad50b721a01664da4e5919dba8d237e5552583bb6f70535d232d7be801a3e0eaa42ffce074cb2d7dced3fe0e9cd39bd32bcea937f3f81fd555410ef873aa0369041deb85d91db273d1282427be6027e30d66434b32d789d1e2ad54179f36afadc6880bce827c17d85bdec109eaccb1be8eb86024590cc20679b5684cd14e28f67dbf564bbebdf711908e4c5bf308290ef68201a3f5624cd1b80880034ee6b09b8228fadedcacea8cacc291f4a789c5a07d7f23c052fa29421d31da2caddba91bc20d6431295658b8d6a52e52be02d00ce02d187f631454b2c3b18936fb3b8b671827b104781df59cc5fd0fbb6343f941020ed391d4eda5b72b84f35ec5cecf7b84a01c629d130ccd3f0c7563402989b92a74d45f0108ae316daecdba9b741b08a24188ac00849f87a78a1eb68fc97d6d1447c34b46ff7d6e5360d3314acacba191c52a124f54b43349a097f529882322d802e658ddf729c0a7c5e7012baf198ec030ebbd6b3963d35703ecdc403eb7dfaa8c0d564eb89e525911e5def7dc873dfb4e0f414d50115bce339a58cbbd528999f0dfe54b94fe9b23c3ed6d8556281814880c1659fa2a061304bc43cc2f84a6b3f6da335b8e311614cbea6afe625b2e6299b3dbfe5301193ae9d4fdf88150e5bcd2276b7c6638f757a0671da797a16aeae95493f61bbb3d322145f1838e4014f59d451df49195534cd76df83c96ff7dabb49ec55f487fc2ca5d4ed698c769502f454d7e011cab0edc386685dda1ad88790e238ac08528328eda6273fa7df89958d385792f69d71cc66a7ef455e81dea48143af39bffaa8939a7d0125cdacd335d2e7fb45ce2720e7211e5f2b6772bdc6d169a95f274bac01105c0ce58caceda0e25b11d51bf7309bb2e417fca9c36e5d043bae8943fe84ac638b960e3c8d6d203d7486ceeff91c56f7165d61a112ec7bac39c4f2019b04220f6c4041820b5cf0a9f158caa9e6ac4d06bd9756aaf054519db4d5a16b8f04da82ac95f843f4e1d6c1e8857808a62c2a7a26d9a219dc9b7e75a07dc3910447623ec6117b2dbb497835b63af1ef0385b01f17d13c06ab5714eef039aa87406f40f5cf46eee922934784e04cc0f38eaa0bdd1a9da39602754b03208a1c2e61c385cb31d994ef5cb71e89688029bdaf013805907a55275be5c5f716116f582acc001c66804e2cab8aa304d1502d15a48b8f21d8f483f1d37e35ae4c9fb886f4b16c58acee77b0cae13d4f8a2ef04db565cc3615b79806df77d95989919092aff2d112a5c0458b1b211f707ad6973eeb4433434e65c4c33e7a6f166badd86ebd8bd4096e6b559dfc222a0ed018b7910407edb25aa3125fa30ea62d8b88ba7648805aba65473e12eba8632061894245224666ca36bc6daafdc040fafca7799ef6cdb0d056a23bf98ce041502dc594943324df822a58d9c1041fb5255a7bad8fd4e596c0057b050b80225f18ba38da61041688fb5ebe2f6e3b80c599ab4d6add5e1b90269b8f2f025b2ebbcfa4ba559f9d433e8d05eaf134949f8a234dca8a075128b3ef5e600ce13b1fb8f817e5522669610b9e73366a54101870fa5210c059f924d0523c558e5989a22a7acb29b091bd639436c883ba07165420f7190b3405042aab1074553b52cfca01b2bb81d5a38cb8382ad8a9333c371f9b3c84c9dbb38b749b4969e3383ff9b24f727541bcc2afb5c62a809a1d70b9bdc22e049fa25cc8e82287cfd5d63070d7d8d5a3e7eb3e1f9b05fdae545eae6bc4aff14997a060d25d6346d77e692eb85a6fe84d171957022bcd00c23e4e0f64f90856218a8bc9ba0c43734919b3b26c7b1903b083989b5221409c2bbe1ed97846cf46a1f019026cccd2f95f72b5493344c84db4f257705901af192e391d18b31b8a09bf90e34525c865457e3a91fd362350a81a54010620043a2b0d0f4b92df41037a7f8cfa4a4157a8af5f4b6e5856363478b834d2cedb511c8bc2f06a677103242b90906b5f0055f9f50543606f426e9a7a865ab2962747256b4a3e54190f0a1b1baff2777cd275b69fbd7c9e9e450dcc70e853e9c04951552dcd6690edd0e756182540c30b278afef4d7b05472466d242c20a425d2222d3bad26b37d2e717bdd5de7e902fed3e5c9c397882a22382f85d280612ceca9a26aa9ad364b191b5a89121f05447cfbab60ea1a12f6f762e8992eb50afa2caba40287696ed93c287f85410cca5b220d037687689088b29ced163e0c5ffea7f0e1260a5d3a15e15fa927b6288fb5132a8f47605d1e286d8c0e839816c53c06def999a35455b6c53f062ca47340d4f22aa241c923acfdcda4a3130839c3ea7faa1a85cbe93a67679b8ab01f2d415c70d10a522f6f1270a10d4e18c3652095916ffa7ad622e18bfd555021b3c1012346c6bee4f187262220576a6566602ff35c35814a2a69aa93f9209797389f9539e71f4cd4e485a616f08f43fe094b0423763b1b62b8550862ce5b0eab89a6c576675c8850a30432aaca4a003c360b2f74fae3320065bb7bc897293dd84b39ee6fa8429f0409198ba12791b31e4a40410f66442b72237c6a6b23377222dca888543e56ea9cc32ba7489498664b200a21b485bca8dc1014c65ba6a640d4023ddcd4e2d64c0a0c20e9672b7b86419a3ff678d9a26ced4851412832758e06683026c952084ca228e2e210b43c16f85c2a922021c3c009420278bcabebc16f6a54c307c697edde52e1e45a544809658009b8d791c5322a02f73cce1dc23573c04c8bb66ea46e0e190edf1c818b4cf4360d1579643685ba2bb2c2ff1dd116d63febfc6a9d2b0e1fe12b9f518b33f6ed9c234b0c6402b3fbc03419250eb04e177ff36e2314c0d5c24c8db0c06e63ed82c50536dce088da6799838014da95636d78e095665a2a6f17b33f3d91443d687e810350a65c54e97da0d2b702f28a014dd72741d6f5ca5369a0542e61538282098562797968c4d41e847c95e06117eaa0e0930d451478b7ed6b2a5e937db6868dfba831f07b8339488120f2fafeb314cbd2167ea87d228e296b22f10e5f729e170dfef5048d20d37a323046a6517eae411bab4ca6c5d288e5d2cb12559692c312e73fb53ea72144991a81298c7639d450e0b5b60975db423d989d10f4bb507354f29e8b3076a80d8cb811767259f584af565679cdf988bf28480e1e4f7b5a0449553f368f3f444a3d0b0253c4216baa6333d0f1970dba4a3d137712bd08a0749c5dc7020046807292c6636008336efedf47902e9848fb8c0c9087fdac98f45387787d11dbef6c5367ce7f7c874c8a541fdbd02f47ea7d553b22eea98b71ce80b88855c22ac428499df58890dcc51d4f117e3095ea8917b13de44b297b417e5894e947768df11486002f6409bed6befae19d603ca2afb90751398d0c6067c555ee63b1db1880a4dcd388cd65ce2d3024e3311f445cde6ddd1ea9de35970178f6dc0825f034f2fc02c2b15dbc1c1fc6b386d0cc320406679dc0adcc67744bf5c31f08aefbdc046496334dc3c3a00f0d03b257ff16d95f3b3cdec9fffc5ee3d3179442783808942cfc3d46c82369850b33f6b82f2b78a9732b200f49d63a3f3773033ed8b5c64272342a211843f029e63d9d0c73eb856d57225395210624fa6b50e860e6432a521997db125fa60de4f31564e37114660d481d834f1c54db1d6e19a5472ba1c91567ca5095688bad82d5bcb2147402da140776e511681b3919cddb79c9641600c9093b0bd490066c1eca2eb6948a107e1bff2374163b4f16009caef8e9019cbfe882d026b19cc2f9dd21bc543723a9b4b4d29a2967e205d0e2dac42b6eaff3f2bc3757a89ff79c14a94f1a74f32e0a46042174b29ea68fca87473e7d4e87ed8c92f4b1949b9dcd33b6e673f9fe68c06f502ec4771645110d66b026cb914939875dad3613fdb6d2fb1e4778b8cd4d0af80336133111186fd39a73117d613f57376af2eb8f995a52dc4f25023fa1473889b7c52eecded23070139a1dd4db2c1a9f027bf757f4e8f1e1313a04e30cbfc985529cf16868a58600f5696d0cf92eb48685f360a99721f8c505c1332f8e215a3389e64925277892332a26d8c11d8ce2d9066f9ddbe1ab726f601ba1557d029a3a541bc5b35bc5a3171a3ad524580c24f6cb7c8c95672c70e6ae8185128e9b4c2601e634f706525080840a391a0e613a116016ea882c1ff8a81e60136a21669aa8e0e4f7f226880c8a830ec1097474eba5961368df4e566ca0b06a5554572515527f41fd941304afb69014e1f540b54989489a1b452f4c7d69478e124ae648c2aa685020ca92ba4b99a2a2bda29543c2ce304d258e7a51b36364f02e12c90ca21351c8a9ec958153656534a19adca2ded2ff0dd9df03de1864ca5711bf3ae9d5c5b9dd6bfb1fc451721468f82e0ea10ceda28687430881176aceea8e842a3665abc25b7a6742461598f2d485b15b1db26a2d18c7a66f8142bb6ba787049d88b68300f2d985683af9da72512d2a899b31b8c61f62896d1ea3a1892fe45f20da1a7bff2c557b7717af8f9b3643a1862c8635211ca5e79b16ff58d8ebf7561177c41568d7c9b71633c8710fb31ec3b7ee8c92a02d74b6f9935f35d8120cf836161a2c7684a6656f933b1c8bba137bcafb5654fa46075c69012e54973d2c5447169677aa530404d497f68e781114e09279697759a3bc660392dd233cc286ba8dd817c7b50b28b11da17652b414376c70bbe98f36183590ca8226a2d5dc039d59964d151d7f659a376d7f789e45553cc344e85316e02b622d69b3482608ba578cd623954f03cc4519be6a76ffe62229bbaac3517384e4bef02f09c69e0b7eaa46c5fd55d18c2a4076dfce4172a471edc193e3239712eeaef57e1b8318700257ead55f75e4a028c4a00b35135972e42e0cb220f13d28ae132dace6722114044791183e1a4d5c08eb7aef051b6da940083e439543dda4b088338305d636d06bb84abd90fccb284ae0e1d00f73e41a1366950dbb73300250230f9934355d46f43eed565fb10df94a0f7c722c4e37120641ebd3a74904c5d44c32d4bd76c55701404b932c43a3d85a377e5b8ff388bd05c84703920c45be05a8432b3c20c7a9bcb4438e5d4c44207aa4859296cf1babd2fe1747b119aef80a9663fae304ff340237137cb9157c7117bd46810c13122043818bb7453844c1b41b1ae642014379d253d258953a4c127aa7239dad6b904cf606ac14f163bc142b2be063368030f3960fe7031ba7d0d8f55f89075c9ec0e5d713ee0f3aa83e5c3483ac47aca3a62f9eaacdd72d80a5c67b2087b86a7d6d6ccdbaf7cd89c0c20d6341235d8a01832278827709b3b17d9b9630b80e7edcc839c701ea9e65179c0415410590a61a70e14cc5b28ca74f0b52f7a5b66984067d285328de79f161e677b864b29419ec3a3921d66d3b3625fb4dcc54cc79e872452eae7ddf20f6318de735828fe37e53707f1a7210d30698fb0d62158946d1f30b54c82a02f63f26f6feba1605968869048ad6a6c8119670037993fa089a45b4848bf0a4466342ea20e0196d373ae42da3a98e281f5b920209b89c8d409ca238df9a5c67874825d34153158f41c5afa28fc15038c1d310c67f47c14686c2f6bf129b01429d8c785879af8c1000529267d3f52f0a763d4210800192467164b65c2a881f90e385a953fee422618750e890ab2b148a8f0015cb5800daf968f226a06bbffe904fcf13c38ecf42f7b1c0db32c1ceb82fb3007f9e4107a4b62382c65a6febef43bcc2dd36dbd7e5b2a2868032db17014ab401335a1405b7c347b5b41760150c93b4e6005dc85f6ae20297061fa9b7525e393b3b8141a531a375b3096be10bb8499b85f30550556e7a5f1099205490c9b8ae2ad76e48564f8de05e0465bcc8cc570c22ce388fda064964d2c1fd66a5885e0b838d2d5d45288662ed93413e68e91844d306cef899acf97d138a6c46f68643caa01b41f89b9037d254b20ba1e29e3d753bdcc5676498dab1ae43384615b4193670ffeeee0b237397a06aa703bdd89cd8cd2a79b03a9d84e5ddcfed2d45cea8d8f6d56a8aa8683bb501e958de194f9143590c9e2f140c48441afe8a370460a4ecb816947f21c1c38134fb00c9ff1e22bb2ec2bd408edfb7033910554357ed022c1ea80ee34b5155e73c778cc9710d5c30e32ffee59ae7f852354c3ba08544b3bd1aef9268597a5f6367c2e4844c1ab19c245ccd145f9d83fa8a4872f6a1270281486ad5772522986ab0bba4cd0ec60de285ce64d51af7cea2f28f5839ee1e6546fd08c38613957857083e001bda6d66d530e6724d6b817b2eda52067a4e967e43b34122d5bcbe8a623d5c0821665d7c2d9256b4315d2b130c83b3b54e08228a21d3edef4cb7544411588e5512028f5f8653a701b8456fc7413a2be091013275d8ab3477fada66652b71de3f0e58bed600651df286d1883cce8e76188b5540ed2540c1b58a28dbc4cf89e1cd0fb02fd09fd154d8819ba04ab97586653b5138a7b731c4a57a94b5401876c056382646a31c5e8470bed45e59c99a42093dad7ca995802c7df584e5a7a07bea72660db80401f4582cf9ec8a6837e265973cc9b6fe2ef96ba0c7f2f4c2d7df09d16319382ce7437f12ac41800ed6cb8d996d317675f63430a51eb4db9146df9812de6acc73b4a99f577b2646d8d4a8902d7c08982f620181c927f05f3e3ba039d20214b5b54819721d5e1c67151e20bdd2dee6b47397a7f65c4c79017d69e416a7f433ed38ab3ac8c339cbe25cab8477b4d5c22bb9e505a6714e0c5bb0c0b9473ebd6570cd15f8b12b511ae57f2c40a5695a5460c11f59bb6f9ca0677ebb49d7f08a3b7c6d3570a91c2b843d2feeaa141f028f7da66cf1b421d980903911c314587e29885dc44d0f8563dd1844a3506bdbbd9fefa9ab260e5ae692dbb66713750edbdcfb6b2af496d22b302e9536c32ce70f589e1bd4f0847a8563a3f9f883aa6d146d98fccf2e5068080917ac60f06e5488a357ef57bbec0ea6a7f1f273e5fac3037e0bb948ace5f9553c381dcf66b653f66dbecff817ea340d4ef356123aaebe760e237b2b7155c0ea3c23e4915a19b502cb9af9aecd10c0f2395ce62e328d6f65c9ceca92b4a0efd1ac22cfac2e758e296183151e9d10cb20875d163fc828dc8f025791f5c7951c0fe0e3aee45235ed47a3a6cace2d0551e177b76462a5b2ab8fd423987df65e16e33eefe242626caa01466aae5089bec4f46bafc342cf68bab54898fa98e006c63ab7037d9f4d84d09a2e3859dfc82aec0880d4d4baa127d4129d53a5d43aff54887a0a6508fd2cdd3174fd696457e9aafe45350910d32ad6ac064ad2c94050cf3503a04801b6168eb4ca06f69aa1df4d21a31c941029fa0bd3a996b38bcd95546ba64218a8c24fc1b0ec2a7aa4dd9abb58cd5c838d0e53c6da4cc7c51e63c093066afe177cd9631d0f6f483bd816b198545b99a9a6c3b884f3007eb5257ed13025cf3cc2e060ae9f7274e5690b7fc4b2bf35a7f53e3b1865857f9486de12077f92f942ef82a761e2dcb65e81df2553ada122e5b545e6ce082a5a6fe6847447712916d7c6fc5dd06ea546c53218dd79846e7033403828c94036cde312a71d12fa35f9fac93c0c38a75e4b1b9c605602ce618f12c4f25e974101de001dab3d424e6c5758204e078b18a22377b21925bd0186864d9e628225fdf9651b7b44698b1cc86575083a3840c95fd872fbb5dbe19ff1db258b462f60d4ca56f6f8effe187c1427763f1d2b4b29920476583e4bc72ace47823e41142ff9df48df427c5966f320c65b6766cdfaba158cd8ceeae0acd2d6f83f7e2f80103c5a9bb455f31b98fc6e8262d176ae3a891466e2955310aae97d5c57fe11d2d5b5317eb7a88c279de680453e7e602bf888ffa6a36f97e8ea1cb9aea652cda7163302dd1689a740a4a273ada340edf0eea5ed219627322228d270aafed51713c76897f8b9e9b977952e22860ee1d72320430d3f73e6c86b91ecb3672ab372695c0c3f32528550f7bfa6e35cb6d1cf737a4da68270f2030291e10cf6a3051410b5394357fdf009ef0817dbe9681d1dc3ad2929711350cd358fdd7aac2eef62638b37a3615b3d7e54e3e5d3bb045162d5056e84095cf1a4febb3f6ca0c8a64bce036286be63996126bc3b635c75e76d9b46b1eb3f6c9bf8308eb806b51b4705e9c61c6548b00a986e81461ec21256818ccefad27d08f266fa6c403051493fd995052a032d12b3ac8e8750308a52b24d18bd479f5eced020841c22fa2de41aed8bd595cd3bfb831ec117828e0fea9cf5a2231cfca2aa486dac1f2ab3e426c4ec6832a86e44c90d46e916c8f065fd337e7922394e006941c645fc4f1d5b07b3de752be2189cea3b55d658aa519d5d8bafaab900b6587e8febaca229050c383784a23676ef0ca40aa8a2e7dcdea9ff0963de295534b9476b821f0e83c6ebd598d4e7427a9d79542626ea306ce0b4772c54822526f04e0aca5cff27e649aa18e99a465a62ef3a2f048c5f3316d03add59cad532b5e99eba3b827a224a08693ba4c4207c5696e191f99b31d05b066e96b06ddd0f69ebe6b7108bd207dc124122c60bb035b2d51b21a7291d586188f84a837631ada3956645c255cc64aa599305aecce9320819728fecba712c512cfe71b79fcfe1d18835b1f1bb6adac03e1d27b99df35a4c5cf0a9bfd6f53252113e75290589bf8db55908c77aee8f1a0fbd68814eb277c370511dc2cdf072f4f490f6168acf68fddc4d7886ac5ecae40aa51a36ee860a3bb124aee45998c383f10bff5a80a5dd04237904cf421c1c330bb6eacd36233ba489b4c3eea82c5841023973991789efb027b78a51eb190b9e8f2fbf4d905bea32b7d66708e8efe0fa3e098bf134246ccb575a9d1e5fdaa8e8b9dd2332dc4c0f1f905afb077d68e88dff7362d34ab03b6bac9230ca1d2665b19cba9760c921c978a6adf9e2f50121860819f272fdc3474c94fd2012709fc7fa5d2c6e9c373ff976ea7ad11b92fd3773532a422249044a2bc48bf288a12f483c4af93cd545af102678936897c095c136a300c5714319f9f28001f8914459fbc0b72957c95612248e4f68daf6a10811af15d3d2d84b61fc71988093e683ba074c694e1767cfb8ce087362cd144029493ba491dc94008c2a45b46c5dd28d145dea260c7091f9541ea3e72dc0895bf6e34a1e6c7eb7910c43267a665696c004084a4238bc289089119190432581322b4444c76597764d7bfca011300261a779c66df350fb839a12674c7c214ea8e9d0ba1748d13adaf72c805126b594d39e3e9f6439d15a75aedac7a2f5a1c90c652d3e0db40f9d36ef99f10774f2821b45885112c9631994e8ebf073747946a27369ae7c1a2964a6a758444dd72fd0a92072b5fc974a54abc27f54728b126807ea98b4f501106ad4f68498df6a3e879d6b8bcb761b6b5e04aabab9ca136164c6c12e79a19faf77118f235e175b7d6c7765497abdf71ebb4e6e7f68ef3253343c55c89ed0d33f36da31ab65efce435a6da286cac3a18cb7ac786057905c1ab4146b17e76fc131a79a94da4a8b994cf1adb9581423dd5d6dccd3c62f716db06f980c67060446abbcee4f7a1562af29cc8145412909d5804a64ac0d7c3da701b55ea2b38b7b93e458cc40dd828bd1ddf7cf31bb79ec26a53e5661cc9036afca845827c59d2b9aabe1bc14f5b9ee8282068f3cca79e582b622cf0e4425a2c14860868e9c14f306309182c61e55efc06377d0cdbf7f02fdf000f5b26110e660e4ccf830bcc782fe83e48e85206c58652b7c925c6a1d0a3d043a7d54ce21dd637bb436e2d5d3aafaeb96eed86a533f3ed4fd1641ae48eb352237ab1619c96df184a4ce126e9bc95daebf0fcf7ea13b515fb985e3cf4e92cea6e5f0d6dd52da53d1a7f677ff0fa5fda6515e8bd29091c41b2b3fc260fa3b3ad529ba432cd0cb647df86a1bc8972ea00962b5772424158393e86fd4323f9be6e11c13334ec06342b6d22f66ac19affde7b8d56e4b7922121f48dc42b72b389f01e4740a96641105f7e9fceb516fc83731db0963a63510ac5a1cc975ded9c129ebc5090a0e9f5ca52f6945cdd044ba9ba41ee376a4911981455d098588778bbb3d5cc71f5f1a1d6d05a020382b7b5b5400461905a93c422b10618895d8895bad5550b35d03c4a7292c5e862c2361e9eeb17e5fca3a09f2bfa9f4ccd0c4ba9adcdd901ca4d988eea64af9059133156570bda8343876a10b45c4eb7d9da787d9bd8b8ab3a929512249e3605abc2bd18addfd41caa4c7e40fe4e8e96e076d0855fd2abffbdd575963dbab97ee084e9411adda44cad110cfaf95f9dccd4479e1a1c9c393cac00c839b764ed4ec8e4711968eccc5d65810b5887f5adaf023069dfc2c51e4fa0f39e43110f088e8e414b390717da599f2a67312863920cddc000667c67ebb7a6f37110fc114f1f6c415daada3a55c38d4516a1600831fce6b6977682b8613151761a33a60418d4b8e984b23b0b50187f19b16c70f9869f10bcbf80a02c34ce8a2bcd723fc230ab1b26491f396714ca9000313b2a3eb363781b903e3148941a172723c091f36816d500c4b85f1c199cd57a92fa3adf685366df037fc8919710cefed10a4037eaca4c12fd29d65ea3a9a4f43d04c5c9a5ffa7c385047ce8c8c5faf0145ad1003ef83c357d0a3ebd9da043623c34a26c5ac687f2a3c78dd45d7122e970c49c5a2a2c7a4590de5b487cdd78dae551488db3f1ae0131039a09e66767ef844100c1ec76193d2a1cc9348faaed22eb300f12466a35f69fa85511e58fe30f549b1c8946286c5f3c07e6584bae30334cbe8e90db62374f4b79d5f94602465c1ecba73ce09a12a51df555dd3244403897d41c77ae5ba3646ceb41302a7e180579bac6d8dd89bacae0b8381fc1d65c3d7a88d09e821f0c6ab46b7d20153c116dbededac13fad401e0f614c4c6ef4b1c24ef4fcc5f865600006c16b0b28128586fb2196a2cbb912f0c6c5ee4e445f3fe55a20659a88cda7cbad3bc7d6d1a945cf15018a1ff06a92de692667fd62f1679b1a05442c874f901e9c8a96376145b80cf00dedd4886899358e0e38b8c7418819251c6a8caad57d82f84061c9c46631a975474c34243bf67f31ed0e06caee4fc4087362fb188806cf94ece13a8751e123f57d9c590bc3ad7bfde09ab3672604150d2370a4691c64c6632664c5b60396d828f0b57550ec24b931ec0f0f9f4c9a72eed3c3ce19bb4e14ad24116e97cc2194180b008e5b8cbdc2d8d22288aa12b982de7248ba186748f605db71e148d20e28d7dbe3c60a8c5f44b9c365cd5e500384e700b28b286ec9592e7d7195b0fdd9542ef134d4b50400a115f89ca38d2c051bb358f72cb982026f1ae4efc14441a36d3f1a050123d4567c7829f278e36003d2ed3e573464e4c0959243124dd3ce1133f18885495b758903a76809af4cf8a2d1db342ba3a507484a83a63d9577dd217a213e0539adc12a813890691fea5fc40858b5ae4e40cc6b4d24289421a2d7c23708db40cb9430c1815ff1dfacc001125a9bf51af2cb421588a4c568d74be7ee9cf16465684440b1b49ebdbd99631b2d4af3d9e27e6e294bc2f759a20b6fc92e4d27382df488714f6252edffbab1a242fe2be6eea33420ed003b0fdf395a458fe7c654a4593c82529f5255b981741715bf7420540c5b216123b68883860e0d43361a63783039fd81893e207f614bfc6e0c369f6c309284b8dee4cddc9ec423ad44e495b8d1fd756b0b4fe67abdccd3a1575c39a1f2e1eb6a222706426ced1629524f92fb7d5b47205a31570b1f4187d509d2895e400869bd66029a4784a2f1d19df325ce788d875d07e1e45c92b3a8954e8735123ed6f2497219d22e4a10b46835a74e83dc2a28d6ae465b0b6ad587f9d7e0c1389628656fcd63f339bf44016a9060e0caa6e02aafc33c9834a9eaf3f3bffd5ba505585d665332df42dc734ab9fdd8990aa6de0b3f40aa28718c511444bc97414e1409e43692cc2691138ad631439b68eb99ec21370a458783da3c62179b1f0b2a5291158ef5fe13855f04759ebd820fe3675088f30d8a11120b4469886972d65e6260603b505df9bac4c9f72dc87e625780e250214c150a3bb16a241d5d44b1f7e44a33580dfe359202c3fa3903aa8a2cc4f106f0071e9072ea8a88b642b252745f39b85dfd09589d8868b5bc80e1f67a797dc3ca6d9aef2d4dfd1f0a3ea50831d2607db3f0ea6b8c9a41c6d321c1a2cc803a0b836bde7430ebc74791f41cd684d0e2b8cb2d60614f9d5ffd9d63b599734bf599dc6cc7abf687b081fdb4862da6c2d53451aac44010f22dd0d3c3e4293a079e76c597d3123755e54b29d3725acba0078f2101d360dcc782e1a939a1129ed584dc4b37a09e2406741692985117d0f2af1c3e089bc6588f053b61e9add26117306981e2d4b96f71e34b1bd17694ea0bebb2d6b7c1fb3f3f4d06b4aacfdd80f374d6fd62d5f92788a85b1d498d538b8aa5e65d60ac42ef7e7d6126dc9a911c670c4758195c205f0bd2d7d08eb103a74d47adc6ebe590fbcff3ee9847c5ee786b03697b5ec46d3bea84fbe8583ff2d425dd8c0998c57d0cb6f17ef78d1f836a20514815b42d60c89736b1aa400287bebe3fe1af2fd9f5f3261c6b72ed8369cb51a58d72501d2c91bfeffd81a1a3d34a8ed1c3bad1e080b7bde769868b779abeb86624c0e36012947c0444a2f8e0479dd9e0842d9a269b8e5e83147e57334cc9901c3811011814e3014e6928606d94b59214854d38aa8959c728194a0360bfd9aec5982adf3f094f5db8b46e3d7c44ec8880395d30585408ecd9ef14230e4bd3ab2ee2ca32ccffc6fc9665a8c224866a7c3bbdf1d206d34f751996ed740e39aa1212878c0e4feaf21274c23cba1fd8c6556e8b1624a1944fa9f6fb300e2911dbbb2424ad44d67c4f784a892e034bcf0b974867ba1ce394ecdd10155e4aa6ba7aa75e624f58411509c66dfc1e8a302d169d4b44eaf12f2e9c2b657e37cf62a5d9b8313de59bbbceef5d002a08273402b458b22bc5cf0d48d5c784471edbedcba7e775c4accac008d834681c812a9ffb87a1aa24f2723826510052e554548701d4dc50811e5c9ac3d970d90e2b698d12eab2263a101259ee13ba4ad258130240f8fea7287e03c0da880afb731344d3743ebb1b1cce4785f131a81404810552a91522836acbf258e0b2a2d2bfaa037be4d22271399049823c565c74d68f63069023d4ef892798893cdbbb192457d2162910c7bd68cdfd402e16d420e5c590104ed6407562f5a22fd558c621240cfeceba86c6643791b00fec546566f0242aa60a03d27ba7201e2fec2a405ab83ed0dbbd81216ba080bc457d4d1d519592a1d6f7ec80c466b4590f9b746b80210ac349bcd3b8e8621f6ad0278ccd35ff84b284db29d8339620d66630d73fae96da2208b567b02585b9f0f842330d1ec1fdebe94fdc869e95d722f69aee15e541a42689599bbad77140039c8837ffbc0bfdd529660e199d93df2fcd8c3ee5bdbc79e19718f32a09cb4dce5d414caae909399b3cb0fe913c9cc0472589c2e1abd1d1f93b239b5061208af45a938aedd9d1a9617dcd5ac10b3da679fae6a40471c293855662c357f1ba924b52df2387773a01a6ab7876f12b49800cef5c806d79df1acb691c812af63d1253cbf621007c9f55d05426db85960375a13e8c12496c130cb8d661062c1903af0c4a21e541b61d4fa7cf3df04c8d26d90ecf38f8555bc968b382f10924c58a0243d0d86d0c3719d0112d3b28ec8ab9c5d044832c3e6c377063023d8ed2abf712541a5c6e35b7801657b54fb98d29c50b1e07df89e8ca568cd24b4f25d0ed3935c40eecce754da4a86b6adfd64ba31dc7a1211fcb0f41c3382a15949e1128db58613a5e9928f0b0ab40037a981bb51c262f682c8c256c835cc66a7fc38c6c423b862449ed68fe9d0f780a405d110e1bb4f38136b100af746ceb53b2e270373a1f78402fef943083b3da3ecea0bb4677b9754214eb418f638227fbdb33a5085d3eefe19a18e17639bdd708ed2f25cb607b2487e72af20e174eae92b782d426a490bf63fbb14e7d56b8325a0657f6a8b30068772fe86f35ef16f6c28e52bd55e2bb7170c32d77bbe13653679d1ad541df8dc76a64c76b26a8b65a3ae8d42dcc0552fc09ffb55ad6f40d424b876ead28124ddb68154a0619c360d7d66740e0a530572b7fba3311da5d0ce7f2ef58adae8359019a7869d30bf4911a5c6e74c42aa37e2e4e7cb493c162c6f2c99a992566ae5b33908f5de6469a9c6b1b1aeee6e94bcae61d6724910cbd8efb500f4825bee06024fef9f4b2602613228a534746f569cd8c46d429f571263be98e7a931d3df2b25af106c39af52c0665b4a9541c223ae8b6b102441f63935491f6977eb048f522b34d80fdd7c128521d7c3e193c69512adaf3a6bfae09c808ac373cb44ba05408334d400d67f2e4314cb080f81e15a13a0f1c3bdfa98dc8a7f831aaf8e202735865162a2c2a748452b0d330da8a01bb189d0345d5f09759c0c6af638705841c8a6a454a01058a50ce9266aa5aa43424c8f008aaa444e66b421e4fe3b5237103ca91e650e18e3518a60d7ef19d05b4140499dd8ee40ad97f499c085f6ccb0ae6e46b82c19569024a67c17b8c28624a9dd8dd2c38894826602f34eec9e47c688d4781f5d1e1084aadebb64308f57426ac80448c39a8d4ba7eca0b4fdbfc9ecf9e2e95b93d57d163fdde34bff910494434508acf7347b4449632a817c358dad3fffe92348fc5e5ba69b91429064afd1359fe32d627d4b4b6e7e8add3f55a23dd153ad10384d595568b2a4d7f0ac9f5578b25426ebeaa8613bc2108356f985d8b551bf8e0bad099c0160bd562f73674f99f0e9c97b7175632f91ac0384d7202e5321ec2cc9d6ee2800e8c76c5cb608d35cbdc825df7cb83cb2dab59bd21016d971cd526b3c898aa9270b7c54eee8a89fcab05bf340fc8ec8257ba5d2a5e12653c01203929831e19ac49ecd13f60cdaee7c857dcafe62236bd39f6cb561351affe8dc055b39588564da0c70d346a35c0667bc97576b5fc1cc15c2f727fa5e17c60259811a004d59e30e3064c9c9fab2bba7f66ddbac40b78a87bb5024ab2c16c9b0328cf5f6f7efcd50d178800e70ce003d8e4a707f0e77b810b0d199a1aa23537f0d7534114a323d6c1b0b3f24a42017ea0551a70b315ab29aa0e5a672221b4c03d93454950e4030c4a8da04855421e4d85b7dd9bdc37c1b3d13df9b5540b30dde0db5e47df6d2743017886a24eed0e1ca165d04b1cfdeabff0003bb2651f2143c3c8f5b6a732f840dba5d73649e42b0a827be10287445be1885bb361a7e48d27e1e7a18f25fc824e534c622ee0ad8fc133976e73fe7b5ea1e23bbea460da35a68228e7debaa1cc7ebf6716be66f5a0f068957cb0dc3418b17e9103b3d19ee2bb7d8ba226833229652e8cca93fe8935c07b6c172acdbdb251141575ec8007e30e60455c8e631e91aca83c8cf2fa08ee673bd734ba3635d0819dcd1706bbe9bcc44868409aab5284b81e8c230dbe893f17130610a2dbc6201406983d303fd3681e09041d3fc04ed01052c7f8d8c14a1258c4a4aca08b08ed6f871366a8c79abd7be7e9cbdead50aa3015c2a3ef591883702adaccb18cc822cf022872f665f4e872705d2ec4362d2b9a384ed872129d2121eb06d27ea4ec6bdf111624ec0701adf1db7558901a9a66d40499a4b99a49c22d778549e94c9be8b7405b635308177eeacd3011fa2694b8f6099641da75198c61c6f1d9c53cdad7c76791556949a879ad2df539f509d962c21f3d01ed27a80fa310d0550da4f89be6aed490a1ddeb92abe9e43f201a548cf9d372fbff11a1f62e2f9d87c0a3e350951edf6c8fced5ac5068066c06644d387805b637ad06549fd06c7810cd268b1b946860185717638f6dc2212ea3aef56ae02e2aab0ee31888907a6d6fd6f242060ac8cf7ab3a07304fdf63523249306900e8ee45ae84d93694f319ff0d578bf93cb2b1c58958bff5b19a68f24c212f62c654a29f0027692e9bc06478016594c68111a1571f535cc3217a2698885c7c5c1f89d7c09e30a5938c5e2bdb7a86f03b3ad0319e39596d9e29bfadc1464d21fdc9c7dd74d6f6c185e2d205a89aef9729872c0a170c5deea073c4b3ebde3d16dcf99fcaa125c3753f4a761fc1a3fe9578d1e4c0e7209ae800b3fea840bc4138556b04b50104858723e315a9cda592ac653c7fcb5126c58e08f5b63ab8b73c1a090b49f1210b23071ff93718adf4977b38f26b25cb0d4d31841c6be5f99485746ec62d9dfd0fa1f97c6d1113a5c81fbe71d43a78d0dd56415f16b46e31c5c5ed4af82b71f4377c7f4e48701c44761051d43140a2c396862757909527063717340f36bd00f50ca61d4f3a1a4fbe3772853aa09033185c99f2ab01151fc9743de2d4379b737dbf36f7b5a04c4f8df663e67e68bb7b468292c75c4b1527abb736ee525a64af8aa7aef3086e41df98a75f613f69ef9f498e838eb57522784b388571b4e845547417cc606c3a0f9ea5e3d9f107b989967aaa8720d3512c5f86480fb03d25040ae7dc622f4737799b903493d997d6a87f8553809eb9b65102165ccb54520a31fd10b2b67084bfefcac04e127d0a46fc478c7316769d65c3850ca741a80c070b0aa5b1d69d6037741a18d32e004f7a683d8f54054b470502659e094c3abd4ba1187d15ef815b790aea618b4bb62ffbeead921f0d1ff8da9093013b1322d287c16db5cde6a332bad6ad724411f5b2be4e004043e1143a6ad36a7bad9445ed41bc22e278f562eb1c0a5ec4a38168babe16e0f510083b6c018a936afbe61304ff257583046507fe3293450bc8033796510ee5ec3e1fab236e792dfccbaa2b8d70f7c55b8e4d759c0154edf9bdd4a95ea8aadcfcf2b5226705e60985d53b28beaf3f3e70683c03764be76c543939cdab7f1978501e969718f6859eda53616a1058853538ab44311d96aa13df8e2c0c25f13235fce241a027243dc7812f8a27316640f8cbd0c86e21f0db630e3e1b6750a51345e5ab9fe9608c50d91c009b43b8a0f85a41d1a595d79807476d2dd09c1568843e75e6ca8276a7939d96ba8bc255a0b8c1ef2f029f662b520bfcefafdbbace7d029bd6b645394329dc3841d3be7871df1eed8ebd96d49c5c8c648141cfa0c833e36018e1e55a944fc9c76e501b73a8a26278a3f8c51563b6c49690d32598391287bb346eac498e761c2db30f27dac9352d085349fee73a851eee3d96896ffa66f02eba770faa81c69855e6fa33ca55a244b42eaaa8d5862a3e6700021c9dfe299536c57b13e90c5424c20a36fb507604857394791e7a3da20d4e0d9aa0a6f1483413ff37926e91515136047e54a8053a88bcad2eea1c27e41f27090deba04b2c920823894aaee44707823d14b921669934b8df68844cd9ba46471459b04d425eb5978d03d9fa664a1f41ffcc1e7105657b3b95c87ad59ede8ee31745aea669022f74e62bab233c2568085984d7984f4bce99d4aa41f06248e787f148744075e2ef2322342f21916394ead0f39691ef72d81ce8b29bc94ddc1884116039a83199c8101aee40c085e40ff2e73731046f63104476695b2c3c731ff6a431116917ca16d4c369c6017692d9d1b57a28e04965e4d418f7e61c18a2fa2a43a54b8e3b152a066cea44673e47ab3fa5265a45609068da8b9c610720bb5b6183725cd2d199b614039c5fec3649a3fc61e87c15b77914cc06d2647ec08ee6b39ed3d5202d84699bbfa68d92c78c689f429b6826e4dbf22538efeabf4a3d7d141c6e9ff98d8beca9a24a873fdcb6ed88b15449fe7667a8806a26f5f0b4d07fcca93bb24d6e52065a624d42169bab41a51e2977ee85c2b65eaf94e6bb1d403872c9f7524c673630a0275f1a27ac0e423e95519c2d8dc202d8d83803393755aba47c3ca024a17229f86758be780883877e0ba7c0ddd928f1b6103539b8cb1f410f5b8ee55e3a6931f7df69d8babb045336f17a1436285c46d6ae332543ee4852005cdf0b77b0877b2ece2480c8e04a99464ef69afef280f2ae413727f9e0f7af315849f4600a78364248bd70f238acc5eb425587cdac16f585a96561ec29beac386991049d6fdaf0522030adfcd2ccc3ea62a0f4c216eec1ce7f5276657c7751b0d7542745b8fc35210a915d34a5164d1f36b99dd381de6cf2bf4b548a52deae96b9b75e2a5f66bed861d8057367a5eb423f124ec3936d5a0866f5c745a1a29fb7747ad4a4d1c72feb25c39409a01de253b0ee518fd06b974068c1d3495d6dbfdaa8d6a8a5c295c32f940d9fedbe0e1a9c7fdb368edcd29040a116a20a886fd5fee4dcc557ad1cebde1ae445a2f221835814cd2b88ba3b1840d4acf84004f9a84046e859b7ab4661bdb5f1ca1741b7648f13ee716691dd6b924d698f8d85f5a661e2369e23f360778fbdd95207cdc51fbddef12be48f36865938dea90e492b93a7d061a8ba5f74e2c7f9609c4ec3c325070296590d7caf3590e65a31a148e8a0e14185bf5fb9ad93e03c20f9a14e4b816eba8ffba0c89a69e36a1a814852948e7e822f3b724bf73304ed2caf90236d45a425e38028b2a21a8af7428747ac1e654351da70727b1270127b689d7e9cf7e39a88a71c2a4b6a5e6855caf3b7a2187fceff79da5a3313444286b44e14e63ab13364a83cf3e795526f2143582ae89c84a610f911ed7007714a063d9ef4ea6a9c7e5b86034978b33f02fa61f7309ff814477e777adc213139ca2ce79aa70006e81672e51629a6f020f8c9e63a5b781a1a926caa6cf287a054c14417477295143f3a2758f8abaaab44343d9ec59a255a5fb5874a3af8ea877c479ade2c399ea512ccfadb133cd2b92c5f183b9930d9a12ce2c2b2881d9124fc02c23557a88064f14671a54d911ee850f3241bcdf818d9d0e3e7628833f3f64674012561cc88c7a1417df5fb49b160d1a8a9d20ec266e7647e19c451429d99a154bedfb03bcee2fb14fb5fe38b0ccf068ec65c90fc5d44f071421f381f89c008d5c066dd001c78e6eb51c986668676b6a18b3a473382e063e86a5d9beb194d0ba56acdccbbd2f22433bb674286914d7d9e067230b55954b2d115d08dc4e43873b7e684af35b0a4f0d20b18a85432347c30757e87ef7a1f9b4e7c684ac82fc6093365488925f4589d9dc925564d7f9644e728b4c7a0d8f3acbd0716b119e5c59b9611a39933eb1bec9e89fd115fdb387c130ab9d32a03734f3906c84a7d95971c04ec01eb46abf166b9401251392dadd596a23bb4ee1337014af1590f0750d4dcfee70ced3148c8316905347c17bcc7e4f121662ae0c143b5b5300b35d03cebfa33014caac8a2d5a4aafd1b5d468db09249b30ab1632385b357865b5aa44e2ffea4702a170600c99834cf39d99825f48bc40da104445bbf3369bb05a7c8f82d105847b1d3e54944c8e46144a8c1ed4ae195fc95cdf94eabc2a13cd79e45a514a742b510089886bb3d58a150a71b59e2f4ea912c6701c5d430dbbfdcdb9e2d89a163fa395579683326a2e9c11d3c1cb1e52a380ea50d0b1f65a0b6d781ed47911c9a4af665d3643658c40aee9d973f99a95c2b831e3536ab079076e099bc002bc61dc8e9a8518ea715243b0dd1636efb3af3fdd7cc7bc5611e58e8854f3602879c957982bd789d646bfc3c20c7ba1a29d498dedbd3fd3864608c45f3a29b91f416a5039b2724f64db70a7cc88142997ccdc4801aca27cfd1c4fefa65dc20af0a05fc01d83811f4485ae18b617e485a2edcb01df00537a37a82d27b6da8ff4d3a01f964b431155de19815495337a41d4046cfd0c77289970eb07575952a9ee037441f925a29ff243b32dd546d0c76e59b5e6f3f6648c4ed690fd45fc76c6bc9382b0e32aefd2021ebac20a1a8d7b296f653bfd1a99e62b5d15c67781be9ec632e115cc9654409873be1f055f5a64fcf635857ce12b449193d9d47cb23c148b5e118ded3e74033f4bcde88d7b77bf82132f77d1af5d5c4149a10289b26d8260128493ecfb2f41e4af30c1f69c85bea5c9daeadc92a94dadbf9caed129fae584eaa5ddccfd9db03c1704110d4183d1584264074cff214b4c412a9ac5c4cbb094a8f40844cb391bf7a747ffb0d4df02b517a56400f986ad81d11e8411f003682c875684bd801222b0d444a5d5c6d1771a42e5cc307a756590d3da0c93178ee5495df28d085cca272c87f602ca07c3cb85addac39947bd21e6977495fb205bfb5316e943db99db72b45d8d8a08dacd40b34473d902699bfc7a7c87b0da7e4c9324aef0a6767713624681a67ec11580c4f9bc1779f7fdfb82f646be1698b67b43f278b49f9eb418e21336e522d81178d20b961feae5c827d153336c755c03b5eddfbcf6a81165f5e3ed4a68481382234ee32a6a9b72f55c602b64977d97defccc9f661716e2b0e00dc9832e81a86dda566a031c7543eccb9dccf59183c2ad2d2af7a9a6a4a8ed3cc638b0b7e2f7c8e3dc69c51d8fd9d0ae558ba27ac5ca640886e629eda01d3b56a0dcf6bf5f6e17871eedeb007981b5da2181858dda2a136dcb6871af78cded47d3498bcc9bdb84db72274944fa3292ad763f442f27b010acb8ba459b0318f2350b7c47396c039c5cc1db6929b67021c7d663fbfaa119eff37f8abcedeb518bf578f24ecc91c8bdbcb795afc5160929fecabac9029c84c8c479a3347021b3852323038ad46b6403479761a9e0a1ce6f9b754d7b73a7bb44b714b7df8857f54ad7e98517b038a5787719a6dc5ce775d65e331e83e37ef0b4eac98d7a2cf0fd170e6c49c9b4091021b59b15b446076f4c072b4b1904c5dfdbe3fe5c8ab6eff4ba3af2b724eb6dc2153d3ce0b593648fa4edb65769e9c586dc010a7291902a01d0677bbb130ca0f7f6233bc45999c417ded3dfdb01a797050ea3e5f88cf4099d5c8a3bd11ebd41ee2f6c33beac69d9f1edd0297873c85a2e6ff404767ecbd0db3ebebd5c523db220247692fe04fc3672d78bb38333954a53fb1b0151ec9a63d7a447de0429d865e408e3a824e424a83110f354b5d0d7497d4abeb4481e9d990f84297d9321dcbe2395a142166931e2ce01fa762ecbe3aecfb72734fdcbf2c13def68f1e35ae491a699a26f5b964a2c934e253bdd49a0cb2659e8c49f10122be4943642df36758f5807509ab1b6a1e72851d55a87b4fb906835703d095a4b9817db2d5e1c3b24903e4ca93547c90ec1b80c2fc5506f2489e0956587a03fcf24ac36524eb70777fbd41c5db81d521abf07429d38d7fb75f23a7ed5d4cc1bfe295cf4295de007a0891ae04e96f8ba42083d518e6a5f5ce35db51ceb4b21a2cefd790d393ee040d00279cc382968386efa98ed603283618b0f002908bb30a769bce0b39e9a1c02a8a30981ee5c382dfd965500ec985ab64890a62ceabc70ffb8f68027e62c200c5ad225db383cfe4ea228fc86a68064746f858095f0035286cc8b5335c8329b48463b14a3b53d6c428967d80f46ed4a317db6b61be46c6ff18f35527855471f053090372bc6ad743b407fc81fd2cafcd1434868e258c399ac06c63e380ce407fd4f5f11200035ca98422b6392f6037940a80355e7827c8722ad978446b058e73e432bc9ed9c86c2b95918d2a46780826eda80bb6e4dfff53a769f3ba2a1540815c1f8218a02df4020c90656841b254ea3596755c402705d8d533de1b8ffd2cb1396d60f72112f684724352607e24931852862a5ccfc4d22d1a7235524c0789d22a770d7aea32a377489cc718cc6f9754a27409ec223ec0943e3f70a9b2558e3e70a66841ff4b4535db669cf9cc2f7b86bdaa899bda06b5a038965d9b63b09e047a9cf416346bf0761c0a7abe7893e84ade4ffb2252bc44d0066f46e802fd2e58545690298f620ba84dd5458fa42fc50906420a8d645f8d896548771a8ea13c2536d7492c096ad5aa1b5ef521b269b930499fb9874401dba9e049720b139b4774cf7a3f572c9f4172f2512a1429007edfcc1117d1a2b9be82e05146b9f86232a46a8fa3d15c685c44c3895f736babdd31728257fc7c910227f0646263c370c680817a872cb849f5da855f5f34cf44c2318cbab1a2f64040a6b073a001ea342ae83a0dd66a913931070d79e8b415b0bc4dac6a6786b6a569f10a00f2d0dca4cc17820de83835ca64574cba9e0031a4484ab5e9f76a05f104a50283a3de81bedb15191aa0934044e083e9f842830a5a40db226e002ac89ac59e22a879914cf595b2e9d8f6eee99fb2bfd6af4bb6c9931faf03e4ee5938aae8899520d96ac4e76af645cf28eeb856250eb6a8d807e93862c680f23c72e95ff3ebd7040bb518fb76a0e5a3e42c74ac92f2b63b37fdb4492cc8e302863ea1205fd08d4255d94fd9ac00a53dc28779d06a47a457920764dc8903abf908327b81288d8865f48d9d8705023827516650f8d4de40a4a2e8df2b932845e541f98c96d733e720012c370d4f71b7a470ddfe5396311a251db9c731ddd7be286a93a81268414b75a25bfdedb03e5d2db0cd37cf0c9088f371f8ae94ed72028a205c5e0108a8c29a6d10c38bf1682c71ecd67f76e32f3cbafafeff3355bae6d7b59613a81c433036e8ddb186f1a14837904d3041469c15f321f6b6102d161cecd37c44401989d9dffd2ecb4f78be9ec74dfcfe66b48013558654658698952a8f955bfc22580989dc672bba6ed1bc528f16befd3f03fac9b80b9fdc7c8750ee8108f0e90acaeec763d2336d5193be77a65798722b344a80403ded983db29682c54a29ed2b96591c3fbfaa9a8e63d8cd3ef7280585c285d7b8411515846ebb986aaff08a875196961878fd265557eda77290fbb16ba4ccdbeb85a582b3b864120888ef5bd1886f944e17ae5d197f231416880c866cc7c4d94d1ae1ce7b21cd7327714b0a61eb3fbe1849589f283108d97200f267afc0d80f3a93448afe913a930016a7a29fc2575008f59d307f8d344f6e0ea2916480f5f152fb7f222ba8441cbf40f87715df31488ae20ec050b370aed5cff7b79213db6f37d0a80cdd37724d0951b9a6b2953ac7c5f48e9347b7b0288a3bd349018cdb49fde2eec36f85abe4ff7671cf024a1cf4202881d51b96486cd2a60c988ddae066480c922c7fe81f0b45eebf7798e0daae7511621b8761ff8d086d8c780a351660851bb4f5285feb7a5a0dfe26e25f0c7e0623bf097a48e55ac71c460580bf81102d49eda8dd36ae057fb971c06e2dcac7267b386f64e0a633f8383139c7cd618de3756fa575e4c2caafdc3fe3316bc8fbce8b74a7ecc032c52a0e4cbd05180aa86039ba9a290fb96ac91f6825f5a2fb32c000e2df66fd0e83642204991fa076b8f6fcd1534c6f2689f79460c2038d93a97cc71322de89f8db5c7f35493e1cc20881f7e871dead403aae82dc8e96145d1014c45501fb1f39368a929e1a1db2e89c6f88d6a5f8b55a36c84f1f39b03ab605a90e16302f3a947ace6a8f6f7706629b8e20686ce03d77876c02e913341f5879f5021a151d3a9d605a3fbcd6266b021c96fdd48da1426c490e1d46293810f6f7bd01a1e676773378e11d06cf80c7d4a9228fea7f72ab3b7a3ad609486642e975a2541385a59395d2fe391c3c627f3673568d2f2aafe73f71a0ec0dd1e0f3ddbb3f965174257f65c6a7fae99d68bc0ab5078a01c15412fc7968a1177bca7ee8594008ce1a291382ca50002ed75dc2e275e21a5e3ded939652f617e2bd2f0e2e1b6a047294feb7702f368f4e5223827e3ee41ca73202138b42949bebf4132254298d3e3f5eab71e8b19c94f517e7cdb4beda9965f8a17989f2173660e17c47aa8b430d8dcc5917f654c2b51df1f2bb22ee23f51244e5f1dd6e37481200e22b11ecea9e4bb23ce00580f4f538c857da3632b98918d61a71dba9d4d1207401a18d958a8ab1c605a083699f0588f9fbd886eb404acb22ad66382446e7ecd7bfbce7cc2e52184f1a14b3507e262b69d7e9e7801f530117503535e32851029d6e3531cd2e8fdd50fd6fa42412799bc8e077d623d8e901238ec040f71a0ba623d465a7802c9f352b11e67cf07702dfaa0bbe7d1b63ed086a041ceda74467c88e67f27c8f6c4f6fa39d6ab6560affe9951e3d4905f4cfa85cb49ff7005730ef50ef17e96f6dcf04dc9dc7ffd6ed66355f27141979d4d584e3f01ca1c75b4e6a2afbe1831da48154cc6c3d301cd6aa0fc91b67c4f3aa9dcd02b9469821bad2d7b15aeb31e84cdee552f3cc5dc045e85eacda22cce410a35c5b58bbe0a8f8dd50eba23bff24576656262d6235a971448bcfd8feb5e85939ac53fcab21e170c84b04d0845360e77d89bdc9fc164a7d6b20812c71c309c2f450c3d17de07d299be7ce97e1c0b97117c859fd9bc1654fc62c957c8ba8a8dcdfa23f5dabd088eaa20f00f61c84a6f5069ea8285b64a25b8400be43e444d71c8236856a20d704b0311bb1ec6271c76bb63a07609b41e294e519261fb16cfe18eeb88f3f2def9059891e62c721afb6fad13b8e0f2b6e13b0167af1fed35a411d930c749f770a83d9258e061d0f062b461e26b92d058a397c6c5a3499a165987d0de5c19b2e5ae9c6606171a80c0e5dd9bc397d5cb392eb0320d1083bc73bf41d71ab30f8e76d711ed3a4f3847215b639ead0bc66ab6c8d1c7ace20af84aa110df401c592d824224086eeb032ec0f6a468176794425735dea01a7dedd778d2fa8b93fe74351ddb6ae11b715c40aff46d05b99a6787a50fe703d84d15c184d5f723f5c2d91dd2489bf21daad26c4292aa2418056d3485c5e66a2527bfd0191bb52c120cea2b02e7093fee705d790963bc8bd134aeb8fa3a97e83abd2e0a43ada686732eb8dbc4f14562a173d43f3713f974289934c3a2199caccb12514da16bfa6783a23b2fc24e249f62003e0bd31deab429847d682ce1c0a03ea81635ea53aa5725b3e2d2962922a392a5076de6cf690a36f2e87350bc80da3fa4f66994285cbd47cf38dcd11db2a8a2798fc170c82f6ecb8c60806505bf2952bca546168b1660c36cb24f29ec320f1c1f17f23a3ca42d04e8f0646ed5cb2b252bf474504f188ef15acdb25cdc92ad2caa02644a9e685449496e6af8ef68444fa810dbc29540bb328f15c0c6cab0bbda77a142b5b73400af7c06c0c3fec71bf32b8eae408efbe14d94101e51ab163d6304ec7dd047fdf5922b9420a56e8957a53e2323bd30dce3055e490c40b4a10a3b0f3ef7e540329c2fa6415003f736df0d38dfb19cf3651a60b13d545f7c16263e58d2343a123da3fd608ffdb93dcf19e9b7ca08f2c4e98adc265c4e5284fe43345b1e5519514428f69471c4d7c34e6baa5471ac8bcf876b3f0d1987f0f0558daec166a627d5f0c04d88295f0e2bcd44901099bc5d87704735f19a9fa7014d625afec06779b7e37c0b1c351410ee6452e41062e4c21990e12f982373b1578e5816b0ee78e2568e18c1a7f2a145b841ae75c8ae3593f06fad127eac0e8a412a462b2454759862a24808d3b2c23a17a5d9e40f91110feccad03d8df457939527bade1c3283b58192977164bd3a93d0cd9ad8abd6a3d782a5fb3b384259068e81595919cd0803fa8c385c9508251a6a2c96e4fba7e3c9433a3ea2c610bf32931cf14b9e1096d112b1d915ded4da3f3f1eb5f9c0e1a0f6dbb57ccda4ee2313bc3c6e45d0e10c4213d8eab1c8223a5dffc3fc5fc3606a7df468425dea3302d2209ce9d3aa422372f2267a16d79d98d04484de6f674617d5162a453eb21415802b0f9d206aa16e4d430f1116f4c63336762e9a8679f4f7e5afe003a46e0ce2df970b9607aad5bd94cc8f28f3113032aa90bf492b02dfd1f5d1c6b39ee6c0957d55586895a9e988545f06e5e10fdd530ce8a00028c236fcda91d0c330557d04fe637490bd619ea6b9790f3c72fc8b30192e2a29650ec3162329043d9cf252ab2231018fafaba3d7cb8469056e15302e71bb32426c73e73209bc553c443dfebaa90cb52031c402bc06fa761803b90ba1d33c3b8b0bc242ff8e924c54ea4edfdf5412209807faea391eaaa63ec202fac5122fcda08d945b652281931e2df1e4ce95cfbdf94e70af751c9c52df6f6692adc9d6631b2090d93d1bbecfe68ef42eb988c7319ae1ae92dc4a799211c26ad9a017d2cac76491f020219982de949c7f1b3695c0647d521fe8883d0f1ba11b314c3b076181fead6bfe24e1491d3264e9999e450a3825c3d618b854d0d6d66470d9342743151380a6627aa6e0ab27ec830e528372fe080f62b1db9aa236b7a638b8c6d4c290dbcdc58c188f8d6e30091947ee0874522ed807b68ba3ae626c4a703402c5f7bc0b3bc4f74165210cfb0c5b22a74fffb691e6e8e07611fa88d97b7027898ba969a287d8751ccdc1fe4d7657e0d2ab5f6b5e4159f4f93dce449428f71135fc640bb123406768523c52af0e3cfc811ede0d11c3b1c2611f4177d4665e718093257cb0a5a81d10a59a062f0fc5e4f7a56162b6d03725ca3212acaf5294f9ea7a793a7afb74cf6c8c84a528472a246d48c09de102687ad14be20e885de376755ea38b4a6c55d250174ce82a141db118d14180d7ed04875aca7a557e8ba0db59d373200cf7e76a261daf634ddc00f57c3ea5c0f302660542f50e1e05b4b96e8deae2a5c7618ab9aaf5b50d5ab3bc33dbe35bc0077b1752a8573d153f9e95f02ad671a0d3ddc63af141409e13709e5873e04f972688121d66187e3a55499e387df44e020ac398481b9092443176d4c3708fc4f333b9b2241f102feda8546426c4813dd2fb42af485b1a5c140783220a6b2ced91efdd50d8687eba37bce7fa586a49a44563c323d1e079025e617e297ed4b550512c0d27fc3d6e8d6238727dcb7962a7e416752e99d345ca4d097fbbde656a81cb08329e8be7f09cb6596b5b68d52441c6c042f3d783c54aad6474bb043dbed2c69f2e66c177f2a410908039d913ab7e55a678671587098e038ff91fe062e336819ebfe88430f4a560671e55502d522d1303b9a0feeeccdb0a1bd284f558d927bc667ecedaecbd671341eeaa8c2c701eaaba2536bd1a2ac392d0b746b1ecb64a61c01d3a98a2e83ee4e0c7a75c75a9c89467f3bb83a944838e8821c2a959c28db808c8a2ad9a9388aa03bb66c118d6464f0ff805987d8c3f517e2dbb92eb9b1475f6d7d2946ecc529bb5c02742c51ff8ccf1dc4099c0d1b6329fe8aea6be158ed441541baf5fd77317dc68555d381ac1398fba3fb4dddd03e09ad549a03a0dc2c0981154abeb42a31ac41627346b8cc3508d41057635e9075736797b092b105e89cd3be6a47789b131cb1a1682a13e710773c595a7b7a052ebeffc89739fca0004a6cf8bac10d941623725c1a813b43c8dfc1b5b7978e7316382beaf75975c5b8f6ea420e6532c6c650f38272eab7c48e7511a5a184b84aae8d956c20a9d0e92f964e95c302ec56cb46284ea52546a9128a49812394c088d0cf267e58923b8652d6f62f440947736c53f018b3c1f41c0882ae3f642c208852e2c732c83e71343f50301690691384a233ecc24686ea74996dc393700d583797892f51ea2d8109f2aa7146039e2b1f63442c791cca8d1588eae8e9c3b5e295271c9fb4871c3c0e38a2928d47a677bac03f4cb77fdd73b49d37d1c3129f58055fd68d78312d4cb3e6eeff3610c89be95820f3e11e32dfd01887c97c992d28aedef3d9e0359e88b3b4468e6cdc2201066d7cd9d8b9e981206b40b3d6ad46a12666248de1c386b04d06bc379a8565638a519451ab2227c2f9224f8644d262c610d7802d52c02088198f284a36f2000e79189279e83dec05d53380df6ed14e921b915573db4d9600ade4be6921bf5cb29e01efc384130617c2836584dac5d9f431087f0c86412de9d597eaf486e34f6f82e7e183f7dc8f652cc601889addd3ae8c5d4d3987745e7ce1168bebc99ebe65117583d56530f1faf3c4a238bd8c2efc305258a95aab6b34bee9673357d2e896b6881dbc3b108ae8c7bb01e762ec19601bda8b0282f3a872435f890aa091068a7a6f947d311a59b4d7434477c2dfaf20a84584dab490942bd3ccb5d52defe2e57824202ad8e9625a3113f7210d06d682989b894bb25c7d62802a5306a7b90a87d0c527df618f5246b1fba96eeab27669f083aeaec87663cb99dc8b68f51af4eeb421640bd4cec8deb9da706d6836a05cdd41ebda6929532a74930b9b45f4286ea1d1e40163347740e310026a2be896a1edc30f5e700c5bd2ff34507ce17e8c86ca41ed6f8060199a1e82bdccafadbb0ec6273a2b085771cd71c3e9d39a9d4ae22e0a49bde17c2faed1ec0459a0bd2c5b1b07734b770a0cff496cc52020a9ca15a584090184f07541c560f0149c50bd1a2c38ed0360110095acdffb85a50f88a4a3875a5eab0c2557f487d084dcda031611613256f6c5c34fb3cc05d134114e54592506f50e93af1e11688e2ae934df03111b2b74c52cabdf70e7c05960579053d5b7942351017258b8b1e424948a3361dc8a9b6a34ab5b41aa5b780dfe9975452bfa4d2e9bf8e2ea95c32d6588b84ac21a01854aef5ce40ca437a8a7f3890913422ab2c66eca565685404b48449f26141e2ce2ad9b51416836506c7163d3c1c7d28ab31e208064e890944d1ccd20a515114ce9a905bd71a08998a161b9ad1549c4a0d38d8d944017d1dcf589e54b042a9aa040f95d615871aa5cb31e96bc45b8e08546cadc1b5316fd4a8292c4604d1fdc41d6b1c394f6f6f48e8a3f7e11fa1d022e54788686506da56c71da32841a178a5ecf0b0a118e211e20a4e5c357842012326b9b5322027db90e8bae52d85aa4864b8ee6accb0249d5ce0524885508911fa69d0a24db9669494773324be546c99ea46cfb9070c8a9ebc9827e26448fd080f4db7b1a8d2f05bb0a08479c1a26ad1439f7580809e7234e53be56f8fad896f5fa78c02e8e8722aa67f747429852723927210c2f6ccd38cd32e926ed90de95063c174d24a79f480b561c9b07aca5ca5781468e931e553830c6b03cbb9a7164e5320aedce3e3c78f1f3fe64461ff93df9ce5bdcdee8da28f7f84f89c4db508d6233f926291dede9bb715584b9e1359dee37b0568b36bde63539fc81055c0ff36bbf7deaaaaaaaaeafe4688ae4f02c770c101260d6000086a88c8070b508007094040091a02da7257e40006280009014644d010787f76b39cb8798fefbd591111d20f9ee5bd1174b36c4bdc419db8021445ff418a19fdac413ca41fa05ca37c8b104174f06f033a027203e2018b80143348510dd6a0058f8a648df217c15c8be4bcaa23fba7fa96ab26be2a5f551116d44ceea62d0c27c6516e98475844b076174505f4c48136c42331584bd2754d5fd61425063b4f9f7a81056f57419aa2cfe05db783eba908d2e27656bc05599518124f7a2ae2272f0512cf0de7305547dc94a329df297fd3a8ba1665cb18cf16c3945760c5608214564f51592f2f3dc3948f20e5e873ed004257798a62f8e098ed18438f1339e858a4634e2ce998bbe8ea1b71bbca8eecd779b301c8003b82f6f4d55504cee855dfea05110e1e1002025bd233174131a45ca4f307f414049758228296a43caf23221dbd72d5951e16710212e42f16b172fed3c05699eb5811e5280a20a0424b4a8946545657ba03a5a36936619c9454902c532f6d67adccdf256e95ab6bdad19f0b34c77a04f31af420c6ebbaf255eb00e41ec6d85d4b30eeadebbad79214e3b7dc37cffc87470290def0df28d63db8d7330c4cefd39a76f07da920564a67a72165e0088a617aee72548fa8b64e74f936813a59b72312cee4e6707bbbc22cd637dc56736fdeec9bf31dd4b19bbe69ca3176f74edd8db7bee9db4d395edf74abeec63b4dd5d47dd5574dd39daa29c63bc5c6d475dd2c14bcce4147972e9a3bc52ec6184d779a265d17aeef5488d5547db79bee176367df6f8a539ce2cdf74e375647b8ccbe5337dd69ca3cd9e946e95b07f594434f39f1001de5054021a0a2552440fc3857e4c90d89c28e2e8138107d95fd2059e0d989271de51be528ca49d010300b4eba0ab805f542071ce5af8b7211d09b21115d7694e375fcc131f7610e542f008063feaa9c24e841c726271d77e8d887b73011f5ea182f8d303aa6809da89b0038119d4b51d03a0ec1e9cbcc003831d5c13c0d42d1718bd314f3341987b752260a0a0acd9098b6e0ea0b59c71470ea74eb389d4b9f28501db758d529ae75a25ad4b1714985529343635b2d3a56bd30579b5a1dab6a1d3bdd3a56e7305f51daae3a5e59d575a6e35567ede9d8aeffeb00e1cf49fef9c94aff90af7b97ffffb7edf4ff0a3a3d45fddb9afa4ff8744bbdf0f2e7698b27ebeff4c2018cec46116b48744f90d5a3e6f5f26363c8019e979d23da520a9a9e28202f2ba30d1effffefb2cdd8df97eff7e5abd06fc33b82babc4205feaa17407a05be2bf03588bbaeebbaaeebba6eedbf1b80f29590ab6173f612ebb1cd6c2f631b66f35f49b6858cee12db511ff2f18d34f845775833c47866951cb8aa117632c0d8aa6ad664f87a59d121174d5f39aa1c5203b1d2bdb8b6d55a277b2d89989c75cef9732fc38d786a1a247c5a3f89106b448f9c8539bf194614aff06ad8b0ded65775367a075790db8e67e189d0e424b996a06e1f1a6b50b9d990c1341985348ed5744ebcbee4af280f79463844ca658e1e4b8f0b20d650b048aa43eb4992d0996e8bab2b28d8254700503d0848a0e5ec0975d54421a27bda20d5c0823409d2c1f664c5e34887528b1c884b8a84e26fa94eaae76eccca8a2e68828615e72b810586c887131e149a08d1a48432acd2a630622b90b1e7bec03477d902a69b743ed89cdde607ab614668619efdb9efffb9e6da5dbec04d7061923a3c4f686f5c334cd8c4b87c2c63763cf4ffefd1a4f954b5e59dcd0d5fe7ede4245cd836f7de6a8c1d15f8ba6ce126239d73ce99b996eca287e25a82ee33b1fcdc3d5ffbaf3edbd65eab21a7981344d49ffbfeff45b70b7c3baa44a9c151ba6d8d42f69b05b99aec6f436e9fdda8667976d628dfffa2c9eeae9affddc5a2bb64d61a5f7e81fc23acd49ffbfebf4da587b91be42441a34653ac785bd280b98998e9dac95d3cbf9db79da9391a4476623c6e155697bf2ef07d7193b9da56b91be424c127c62ed847eaf2d705be4ce6da85d2ff57ae51e6151bf33fc9b822a15530637f3edd0b4bd92dcf3e96dd61ccdee7e00f7fd5a6e8b91f7e5de02bd6d4ae8d95bb414e120c33ae25687e7fcc4578d61f85e4440d3e270a4d4e82b070c5e0b60fc6ecffac306559961d79c5926b09bab23c48c27222271141e563461f634f3fa11a1c697fc475c1926e500c85e5ea6f03bb454cd460ca3f20754653642b3183ebc59cfd5f8caebfafbf4effff2f175b4e495e506243c3cf180c293411fa540963fb7573eb95b27bff36a8cb19ce6e18376b09da5d1351361af77fdd0e7cbdb6b489a11c9dd7cce1d612b46b9e4db0f8a841e05b544bd0a01dc3e8bee80d9e34986eb017b09bf5df66f88ff60f1ad512b4e7afa35a8276d55d31600cc3aefda2ad0e172dd2894c1b0e5e0f93c753ce0770683181d500919cca20d77674e6d52326a7031794d2312ec51017597e8d3b00759c75d699875cc718e3b4ade4a1d601d051258f15f8a83fe79cf358ce39e79c73ce394bb0997b672ad810b502b061726356744d8d8faa9e7eedb273b8a60588ef5df9ae61921007e427c2ddd15fea9606e5cf51d4e1a6638c317e0cbca0984233da305d28731c63703ae63e8cd331c65b26d23adc84e1a94c0d31ce584cedd7a2b0af2bd37923024b5f952d3869905c9e8ad4e5eab12e4a58da32712cba80edb84ba2b3cbe939f36d17d433f7dd784981a1d89d7d0985d891079429f6f44d92cbceed58410128c49d93d5d159964d004414d1f2963e4a28a95a1301ba1760349492748286c460cc0c103444585eca1143a290ce29e5a8890d5c384f234ee0a8fa51695250e209050e302d379863928a19fede71e8059d4bf96bf51e7b34f76db6a358c79cd5e5557beba5699afeab5ed05967ecbaea85546f9f8b47d0ee82dc5fb07634a9eed0e809906ac85662bc78206b3ad36b1f331d630c06f32125870bd91ad1106bbde2cb1b4cb073be2049d554f1bcd4e8f8b0615165d40f3531423a4836a71eeb1863ec64f4d1942304679d73ce09500b238183cd439a8b21f1b53961b3d57148c7311d63fcabcb32c122c3e6a8638871c659f836c9e82bdfbba3584d307e50af6f3670f2fa704a0386b0b00595b2c3839393034e1e8fbb0e60ea76ac79683a5a71f5f6f416b09cea26601d615ae05b10dedc689d52ec2be04ef95b423f0faa1d742d099d73ce198fe5e02b250f24976705e69cf3dbf3cd4ccf241a88ec2bdf3c60faafa34a3c3c9f4c073de5e81689f2aa73abf972e1f1c2f3b482015756d7228bafb1e4b5981010d545edce053b07811bc911784901674a197838eeb0c9745f14ecdbf66939e447cbb2ac8864af8714621351487f5aa309fb28a8952bfe1ef822d99f5c8b044d12845b4bd0ffffd7d98da30bc92ef035a2b02cab59cdfeffab85601145cd62c5d4d1ce4ed38e31385d67414408ac9027e25e5e787cc83aebfcffffecbf16c6715100be47cc2009ff679ffdff1c37554175f17662e1891631119afcfff3a04feb382309198c6e1ae05283058be71d5b91f1d8339608aa46275c3c7ca92145ec188a2bfefe9f67301a7f584854216faf73b00036b4afd73229fd58b6a775cbee67fa00dc9935f9779f2985c27e97c532d2f8357f3824e88d9a856494e3fd44f331bd7db07bf7dad72d246cbc7bc267f7d406fa4df6d69ba70396bfc0b7e9e583ddfbb1965a8039e757b2f3e90c4c62584c77bf96ddbb69a8375393737e96256b2b5f26a1c908ddde2d93657dcc6fbb519a5b555054968b121f4558ae78432a4f69662db3ca0f8cb7529076e379d9a10587f601c53881c8ae89f922eaeccee84af95617f83e33ca1687a2030d1434adabb2107528e9e5822c0a0a2b893abdc6db8847f0edd75a27bdac25685f59910118ad216b88a0a312c35252d135f70975adf5481e1208c411d34969a8f707b556c1e95a7320e719909a3c080276fc7f2961cfd7e6fc206ceeb52a0c4f31e79cb3fb5c43d18d72e84ee3bdba65b7590a4fee69ad75d34d2d41e73434f17e7334ad5a904fac8785eb65e5ecadb6e9c3a7b1653b2034dc2e4bc9675b7fc3034633ea309df588a5a3416deb98f31a683cc98a6634a405b96fb0a3cae333e46e6f16bb2fd0ccd53dd6ac8e006d89bc920491d9ad815c5577edc8b2f1d06d2a7aff9348876c45fd4b7ab36b4f9665f362d9cadcfdcf96046ef0f39b55d64001ee6ca6916b09fabf0dbb0da61d119aa4d9b8c1f2bd371d06be62ba5d5d1b37d986ea02df27ce799ff5d8c7bbc6f1b5d66cd63967ad743241be06536daeecdedb069e4ff86c6fcf369773766e5950e3b96559d8ac396fa731a39879b1a898b6a49a91a6edd9f63e7ba757fcffe7beff6fe7627a184a4ce7f5d663665996c7b838f298eb4a015106e564a1e2fa6fd05f0deaffef41840aa8113af8d4d918feffd6756c665517f83e35836e8e1abfd4fd0c502fecebf32523a5098986a69487975406a0024da0cec8a81c429b31b1ffffaf72a8e52724890c184b24132d542a3c512d192b4a66003f1dc8c44046ad60d2c27b9336c0d9eeb37aef4de2d8f7e6c03db2d1a82d74a3682e8f2bcc39832125e430a4d61096d45c5cab8ffdfd7bcbe7be5e39ba7dca23a4f06132fbf1dba0f670ba6eb50fb323786ff57eadd377ec2d5180efb34d5164b56e368e10bd97cdb5047d6dd45a6bad5324b3d658625d6bbe81bc1d41d5a0d91289b38ef97990242dcbf97cfd6df8a516d2e781d653d580c52c9a03d6ecdd630bd99aebd86b777b5523b91ff80ed7c458bc1fcc6575ce390799450d3784e22d66cb47c78cb5cb27c407042344712d914c755ec3fcac1608673a4bf898c99cd638e1c50de6f978e1c4faff2a6f85428a6ebc5f24d72e0e3e21136eaf70403703577367971526b01ecba54d578dda530219597765c61c523a05d0fa5a49a6ada1bc98c961a51b4035041a4319b602a5eeec069964001fd7ad00464303b5d6cd9b1e85b64c4f18436ef0b525983d812f42806fd904bdf214accbdd20270992c149486a1097bf2ef09de10c7996ef07436e567ff02027099a31dddf06bd3e7bdc3f5e04013b627dcde687508facf8030ba15be03be6f481e93c2bd6ec1d87f6d9560b46f38f375a10bbde49d02ef0352b325b6273c69cc6cea044d4e1a11925a05569952767068d9c296697d0d9306bfdfab59018ec8fffe3f28c9bd7ba068bf57ad6ae19cee070bb954ace95fd0adb39838c2dad5b13a18970c5c0add4208d22d65f2ff6ce394c8ccd10d674692cfdd7d68f15d1923e2ce633dfe1976607c444202440646cb8adcc150599b0093340401c0383828e79f2de53088e9e594ef0659d5182dc228915c79d156e562b6d59a89b8c1422bab27c7ed4f40e96ae77800021057ab278ca7877bf85e78b1e858e2a9f3dee9f80c5a1c5a811a3a565993ae1dc448da0611ea56b138f41c1abc81b58548f5c0d070e425d2fb1d4a6381c95c5c091915a73168c9d0692e5594dd98180d3ca8a59e99afb945d6b8de1ada687ce0db80e36439d71ebeb6816cc089dc88554bd7fa12a9dc0c20984b897b699dd3e33ac6e31c62178e0a1f474835414e6b3b3af2e503442584c072d9ebbac55d815c53e3effef83b2aaee0810ff7f10cd298af1b330525842c51d29827c6ab20447604cbc1e4a55743ab3ee89f0adaf7c277bbe7a54742217fe68584c4ce25432c62830ced803763a5a9e66c8b25cec505514a85ddc89ac2615a19aa7bd949231c618a765f58555285640e5c87b8c813c983c116c346cbcd5fc8e6a650583694e864354d0d892d6553d6ad5cfc70aac2a15153548c11154d394e1249a1239c112d32c92c341e4e4fc224e94d3b8b503868d18d584900babb7a2d88c992ff5987274838080808080808080e8602965ce994b26554bc4901243ed72d6397d4a0ebd48a211a5204bb88d00298713d6f1276b476a8ac6ed68160799fe1dcd6a59a1f3b8a8f7faf5e79c33f741e509d1b190e2ca4349cb59679d4f846f614247975c317ca3bfb2c09886f4341225490d892f57d18f6b44155a4a5608b312414c54221d5d72a9b8d84145d5b9c05a04099d35dd985a549ce5fda4dd780add219117c8421c3129419ce8d182668f3237185e5978ea943aa581a3104f27aee07aa86a80e41204038d48cb2e0f68865f3a554a958a51b97a5359aa733124ba5a7533d8528a4c2762dc5d5d4545f50724c108b9302331a68304662b5148aea5171d923288f1b4d241c6e1040728e25c9e178c10528ab7acb3ce4c4f2678a45620f186c477a6d9f1cc1bd6530fb6ae0e393a0841a57035567ba62b69b128cac9d603ef4e656c86132e7d496f8c479604099620981706b0a90c89808114614cb6e0087b69abd9dd02a4bf35cb24461d731fc618638d31c6b82547893a22d812829b61ee03aeebbaae9c8bd064a9d1277454c902d6895cb8914c4c74a04db56886ef7a9fa3b235b3ae40e5f234b1a2c4535c0eeb0472144981236d8907aac418db9607102daaa43e6025ab8e55a70fc4c05ac4508830f259a262283389adb9958c72957ee64fbf7e0d95b39b16c472e5419a7ec939679dd5949e1d7de53ba4a34b1fa04f6a0ae29cc148add470b5099b64fa9a9602843c71c2e867c9a432a36217eff775c6a9cae4f25022d178dc286d8c8034c3ec59469598f920f918a847030da1753f3a403ab44f3967a0169fbad4019d3526a9951e2c2d00c870268d6ccc58bded1fb21fb0a40c14ad35569558350955435a5190a582e748aea8294b0e4497d88a9d95d5f0c2d1f14dc654dd5ddc90883a41b0e2c2210a0dc70b9b21118593b3a186908b93b3eb2bdf724ab9638ab115339c8ea9bfe3a21cfdbcbfa5397ea46458a7651867fc03563613d6d71f132d284fadf5fb344047954f357aafeb094d6bad7c32e133c20c9e9fbba6585c901d13d4d96accd08562c4a24c6a4cac44eae746ee001d5542d9fcfc20a0a34aa8b4fe81e541479551333e4627b8a3f8838e2aa3903f49a91791ccd27389a973cb84a2ddaa199b792fb7ecfea8f6ffffbfa9c8dea8187abad1f0a0d2c46c92d1ff8f4ad4ac9e6c9a34cee7331df3ff7f8c0c9bb676d308ff3e954da199bfb22c9becb55cabf8ccaaff9f04b73404d4196a83d4550a5add17e8025d65d2110f959a3a4fe8e8559dd9c78cacff9d4e9d73ce6645ad7166992f2f83d35b216663fdb9efffd7bc9d5720ac4e5de03b344beaf50cc4ffff7fde79e7ffffffcfaf512d749ae8ff4f32e29a0dcb902a5e91db1015d857cd8269cf6fd9349de7346e72ce39e79c73f629d3508069347adc3321a0da81dd5bc5c2f797cc2d4b1642e79cf33306ccd1c487261188211aca0c1a0f019957a8142eda7467082625002413180020180c8643a228cbd3300a5e3d14800731c86490a05c644c288f04e3c03024475118835110c34000c0501484a09212aaf254932d605e0ac198fbf12090ab31e6a281b86f9e9f7b342c48e804c3abf5b218c0a18525e8c4521ac468144ebe316fa213db56448336554afb610aecca46b14161238220453e59d83c61f9bc56a8acce91671f3c51dca0c9449c34024a01a8c3e0b40f63b39b4b7c0974e25ab67fa1c9b91732240a77c49ad1c44fb65a153ad299fd315ccd2b0e2fcc045eeb84c6954285f9f5563020e07f0745b018fb198845530916287f9eea2429260bd6bc80462900838dc37b08aa433898f21d149ca1f287bdb524a7281688524dad1309e33b52bf501a91090c66c0f1e16fc73aa53c58ddf2fb797824cafaf53bf4f431a1f95a77d24ed54d01775744588a890e3ca40e241809c7ee97febff6b3bdfc093d3a8c4eb3ce29cf3a343eb2189e9ed8ad4a5b89b7bc721e64430ad8122221e21d6930638c719c97ea24e887a28046305e6f5427a2c103ae27be886dd2462930c98d2d523f9f66e7f89862aae233cbbf7f9a4da642ee4bf958a5cfcbb4b672f765dfda5625bb866ac7c134457373f5991f5a0bf77495a5782628af88f35d653d9f0d667a15e66b95fec28b1476c7d517408d050c9f165590596bb22c6403d90061cdeb49231734e933cf2d291b554e69694ca90c4e04934ba68913cd32650668a872021063b631b18ad9b797f9833f1d15adecb8b99e623d4cf2886789c5939b62f66ddf023460061ba28afe17dfa1a58f0d0a3e55035f70859c665d9a718aaae0d03e5ecde08a05b9b0c70c8bcf5e497c3a4dd4c831dc513a867b0c6c09c31842c8b0b59ca2a11d73bd15dcb60dfa74250080ae7c69e58e28524c5473c2f78d81852de2090e63ef014cf210f4b1c9c3ecfe65acbbd1eed74dd4ea81ad890d34bd7c80af22afdb7d11df225126b31a23dc34b6d021babecc4451e077ef5e05e7a0ddd1f446d87aeae87f7523717c6a925ae16d69af9a4637add0f9ed4ee1ed6d58fa1cf44699de8cc2485bb3cfa8c5a805bc40b48cda410e80534241a596c34811ce991b210c7f7a80e5938683c9928165445fd8169c2cc3c8a09b63e8cb0e340ad070941a9900015786f39484fa09dce0ae48f43478e541b573a58296bab07636bbebe8cfa77dc52d841992f6ae570f21b6cd77b58d0144910d7b288b8e1863aa7e5d0bfad808214eb786e6238554a24717298cc199d7dc53df9911e7549239d3f4cef8a2399a676ace61dfa3ea551223aedc95516c55a6989c77c37eceb1c6c8d6c9d61719f1255882dd576958bf8611dc7a648b350ed94150003572a1d82952eb0145749d615d9d8e955f179453782f032ab1eacb70949df8e6265de3947dffec020adafd98270c28fac883e239d70299b9c6536a2140b4a111c3864a184e34d5319ba6b90ef70bf379501d61d4062fe5398f10e518abb8a9b05308d5eda3bc3fe45fab80ea039e242af860e14e5870d2a58a6dabe3f36992b9f48fba02d2e212ad81605a0ce8778348d4ebe80ba119b850a739ecf19b6a7a9b1a3a539580d3cc1951993ff3e8629468a83b0fc56488b4e2d33aed63867f8e748c4aa4ae42b28bad3c02bb758c3636010f96bd8c839d4449db2e66327448c8ec313353307bb0b825a98f24b2db414b231198b32a6254dd3c6fdd8eacb4251bfe4e19110e0d5a5981948cc8f29203c32cfb90d6eae922953016318f6943bb88c3333fab41172e20258cd308d663b31312f74c38ab4e7d04422dae70638bd52befbec8d96be6dd0e0ebde5e20c533e41125c02c1be1e3ce02d624928a1c555a0129ec3ade788abb1d21d63008c50083b75e2e909bb11d897781948ad9978794beeba916b7c3da8c6fb7e887d1a39f42b47e1c7e22d09560ce199631cff67ea69390028760328c9270b27ba91e1f34667fbd97ebda7653c6060f4017ff6e6f3257745b26a36fb7b3704a4a109249f646cef718d7562bff220427002660f63475ecd33c0360c6c9d9075e0757ffc7b8f61e9dbb5230f1f2b0345d2d34222eb6736404c3d8bb99b901ad3025f8421a10d0042dac03404d69ff881e374ccdfcffd5ee47e3d7b9e87f8a87480ea02988ce578e78374eeed96b5dc8e023f1772485b0c33e1830e1ed051eb02fcbc43eeae0ac85e4e7e23b5cb4577101d15b4abc13af7469044e6819de08d12181189cb0b58a44eb9f413f10195a9e35dd41cbd7e83bef2d16e3a6098569a0529fd40c021402968890b1eaf05c1f2d216f8774e331a8ca3e1c4e92ff65ea44b8377ece992454055c2e6078ee7e8926c984b255ca2f709f34120fbafa3645cbf2c24e945742a555c43a22f3587dff4232f781801379b2fb32e3d48ae9d77c220ceb124da44c3268e9400577486bc727f6135f47a134b7ea6e1eae5e8e4f3c2d61e22232a8ea9db8e29d389e71e78a1ea52d4258ba9588a580b7a2f04ddb39ab675a1a2388f4aad2a6abcf5f1ee6451f9c3ebe991c43b9b2bfb468644c6ca030df2e0cb4fa328367b1897a542f8a0951ec163b542aa085910c7d7c885adb416af75eca5de735ba74aeca8b2e276756ed24aabe39ad4f5dd268c7880cfed012cc51e6601762f584cbc9dfb214e243769ecb3fd3b2e7e5ca5037e962e809c288428aced9f85dff12b7b86b6884f1aa45afeac057210bc133f0f0ca85e00a5c62a026997de151c2b19310fb6c2f27b903269c74a07863e70d2e42c0e2af0e580e0f02d25e24c1a242d940365c2ce985921eb388b85cebd2b016728d3a09d2dc1ee58974b737a6d1cb173f2df6ea869b236ec13266c83b6458c2fad95a623fcbf40fccc6eb32b019f3636f1a09049d12146104b8eed2e98bf76615da8501f1646e3e2f361d701f12fae5e9ef9ef7a5738428a0fe19a5ff5b5f990fbbbdde8772723331ea169b3f065460d4910a21f8cd362c0f04990ab33e933a6679044e318819d4a17f4cd3e2f40b1479c1865120dc5f27399c5947d1b0fb5c0d79ba3f50b318b295c6e1ceb13d61f4ad67245c098b65d42e74e703438d0300667149b80cee93f5cb27247b0b59e41c09ac1e54a156ac121d2980bf5044ea2bc35eb08c94fea3acfff7e55a1e9a17795a33515429d0abc07b6cc2408652a2d923dc642ab6e1a2170c5a4e81d986078575763dbd2ee71f877894c3ae2d95ab9c1bbf2fadb0cda821e566ca8dd0cff765195d077f3571d93c235908770f63c65ee34bd834b75e7ccf92b2e9f7805c33db090cb565c21243c1049230bde5514a106e0ace8a15435eb32ef9ca11c9346bfa3337c67700e1ac6be31590919ab43d2387c833b57a1524680e7a9217dec0e37a363ae8d989b0bd34b31c601f0312fabcb3500927009144401c7ef3b22fe1187c2a3fc52afbe6ab5cca722ed751c3c1d72de63b37cad0fcdfc3f9bd87f825cc6c728d89f5f43708bb2639ee53a106644319ddd9495b7713b368a753b130a507ca700bcb96bd07a65b985e4c4517b2843d1a5dc8a998bbe16174f6c52e5b400107c073e545d29fc36e249586c5da4ef6f9d13ba826cdd76422263034b3085376dbc98084adc640f908971fa62a5d32e8ae46dd903d732d96be2620a418c8d9da7886f3c95b660c3f628b84cb3e194878a73228ee3e66de8c91b9813edb6da88448c34f35892224ead4f1b8025ae73dca1fc474cfa0272ae2d645ac75305f5da58444bcc76cc6dc7042a71b646c266df31f20b52371263610e2e6e0d6cd0f831be89010126e342c79aa427e129b35e5e3dc415c6b25b790fb3c2340f7b9acd95a2d95ec76bdf2912e9690df8bb15f2c94212603c5f30408b8434b0b1eed9ca2553f43b42250d450a02bd51518a820aac158bb1d1133aeb5a0f405425c80f79d6a9a75dab1dfd62b145e786acdc8a875d4f5b4d444f3049b5697eeb82feb03175e071a42a5d1009104c736afeda069c9821fb010f82bfa0c4c2030bc316a5a83254a3e20bd75176da31f3c5c7535290c4f8bd16402273308aa7802c0f12b76b61c769c38fb60af3fc11bf4e8cace3ee8082759d38d93478390cba39639b4c83ca10cbec2d23911475e0afc8fae887a9b525de458d72366a18363675c565ec1f43846b5cfab26da7b8cacecb0749a9894c2a742640906540c9df8f2800c4f2f369f0bc3205300f20410fba3eb06b11c5c8550334113ad73e32516226e10511bd58c018ac99c4e859838692bc0139b6095df93932ca043e26c1b4f3b754a5f9b3392d88cbdac75c5d3a3472cb9223b4bab886d529fe8509ac5af07b8dec3788ac9de2da27a68f86061b6409e539705b55152f866c1cf4789a589e44e68f64aa338bf1931e81a050b45d1d53a07472380196778b01fc70fe5b01800276c4a5b36c0c6b58193637b44c4b189bb9932460271e22ca1ec0b61fefa6b8e79a096056093a03ccfd1d528bf333bcfad1132bf24569805aa9f778728f209456e28e03d5483b693d79d43bf366d2fb1b3c0f38675bd8f512ade359868832c41da5dd34f0e49bf2bf6d7135e9d04c7f55e048c0ff278e6586a3e2a1cd5adfcfdd6664eeb46f11c7727f04e5395e9fc033818f78b35d4ad53c0d7f0222350af88a7e6790a0a541f31efffdb1dd6a898e6ad521f8a8d31dea06b12a4faf15a79455e31f845742addaf70d55e417142897966ad509d59b9b241dca0452634121880b62123e7cfb2609a8047c4faae5a8f481fb652abb19390678c3b083eed78180dd8c6dfb8c5c67e4cd362e4eeeb7fd074a070d34505fe6c0c5ca605ca28cd9d3d92d00658d8b1ea8d7018586ab5999bbc0c4d709df3addaa282c08f68c370e1376af081820c26f126156f50078c884eafd8039e88b465156c991cdbaf7b32f8ee764955e8df0ad950601d65ee5baed8099346e972580a902bc8f71ccd51bd1cd5d78ed916f923374de5c10e736a5f64a03865157971f1b110bef68e75bdb39cf8727fbe4e57d6b91473769e28a59d1d202f2eb3073ea9faa301fc0892b5a4ac8889f1aca54c099fd1823d387f2ca6183d045b57c8891288cf833ad1096623680eb166798425eae635c516569f9307064d5b2fd44e613afd1fa2efcf723946fd25bd8ef1cc703867542be40312acb47603250965eb31e94f0fc689910472fe25c7c4d0d1ca01cf25e5ca74eb9a88eea3fd3b8591cf6795fb9e5226ec121585ca2472f32cadf1a32927417f4f1352829bffb575775653d62dbfe4dff28c69bf4ee8571d39735c7e386f816038557a2da83c137fe77457da80b4d163a32c47a48466e6ec1504595d1f2537e3a7d6a29fb19e42894e04d513a00de1a1e8513e139d6bd315842408f9869b50811973b6c31b01cfdda752754f4e8c645f5a90e95416cc2f56ce1770ccf74b5456850a11de4c83606b3725292ab61b091ed8017382d309aca860185418e96428655e3cf5c01e58de2294adf8375d50f2926dc9304c536efe4d68eca5cd56f39335feba7e34786eeb03584f1ba7f6a735c2736ccb3e7a52bc600245b9bee0c5aedee56841e2f47131e4bd642000d9a2845c35c1b07cde8613052667fbb7e2b693e7b52cc1e52c7c36c8ada878f9afdbd8f4a62a055a41805464e998bcde3fba96285a318bb20dd633f3fb4af30c3434bff3c11733120c821dd31a54ea1fd18a3b100dd7725acce2d713d46822441d54fc45ea5e74000096f8054c1d7542a2b92532ad1d18b2bbe88d1d75c56be42c31272c98398cbb98acb3a29a89670616944482072113439f9df4c8d8363b804c74d002bc89bc38100afb25cec471984253ef8db553144a14cf2738a3c7ceea0a72c8df2138a58d20051d0e48247299220d11560ebc63ac5fba2693d516a1b1053759641e3ef157b418e87f896b43ffa720d7d7c21e3b9d3136518891071fee004a71655d5f77a3062377125c7503f2f332f78030f575ab7692af89076ee37e54f7eb8994cf540e18fc747e76e0cba5e44ec59f42277f765354e766c9283102e9c7f08791ce88061b61aff6bba06194988910084860feb2092b86ee5c972921969a0cb5335c5f963058167c1767e81a73d8bc7fff7b3db24b2f054b7d0cabc255e5ffbb5a272acb3983a66842b61736cf6c47c4e830c5ab336da1dcc4bf8dd53943deeecf7eb82c11974523a97eb497721e479f278b59ce41b82042a7e0b7f7a432cd572e0f362f5beed9a73039bb4e8503ba3947e9027541fbe6e307a0991401a0c5e2ab1e3de1c946f7bad46d6a1861687b81eb4e9ff8cb2af0b654e6dcd635039e15165ac8150aa82b8cccf1bc3a1c085805a85e60dd74ebad7e479664f049323cd61d67f1511134cc1e1c96032b202b4de9aac4f78c6383cff7d260aa9734701449b258f7a91b50b5c676520bc2392a6136eb0fcfe9ce7f0babac4ba2820a66591a6b95b79563fb381644b4845a3d2c9de17bd7fd4e53665554e23962af0f6760f5f12ab60bd50ac142bb0431e1d2245c40362ed0d8abfa12584e670c46d34673b8c88eeba7af9a992f98697953eb9e33929a22a3e03febb69b63325cd1ace5536b13207511b830263dcfe4b5f158ae0d3dcd2a5a266f654ad84c8bdb2b13d14aadb8d97fdee159cbc67dc8e497b742b523643582790aa50796d8b70316724c47b21630446114d20656fcde297cf84edfc276390020ebd9b11eb38f874eee50ad6d7d1520310d1f7a5e80ac5adcb73962b84584d71ffad7faa2ba2dabe848631dc00ffb73ecc2f6c82c78c556e06482bb57208fdaa260b1071f3e5c1429b85a071402dc52074c1aafffe3ad3319df4e0d335a6c63878982174f1a4f43eaf8b76b64c8b5750aa1a94639735c463e9ac8e2795cadbd5fa2a624963e130a91c72447dbbaa02b1352f67a79a88141d3f3583aca12398b040e3b2b31c6a7854836980869b9f55c52d67d9792f2a79b1b4bfa603848d9a4ded0e6243d3352eea19641b15841b78243fc04a79a719081a1a54c6eca866067ac5aa9a010703d893540e039c8bbc2a6e4793ea228e049f0e9fd5ef75799b2caa42f2f9029e5c28937efd1ff85d5365b258a9b206a96827f7ee732d5a488aaf9a0f9d532747cd6c59b5287f4e0b903a4cdf22a443ae5fac58cae6a483860a290b4d851a1620bc1e33d91c25222a13d40011452853be276e107c0022acb43aa7268e9912c77056b3f61c9e000a211b635764f1aac8e71cf7835ab2a19536fd1c2ece725535fda6df6e38f3b714cac9bf588e3457d14e3ecce1e59fcff558129d20184a34c596d9c3a8f615582575f24348c830b9a89d3e8cb88b66c1e24bea36393c0b38228ddff322cf62d6ee84ce6ccab981e886173352deac172dd86819e497c8ad04d2bfc334926139a82f0d4137a6dba5c948973293dc9329b2e340666f378b64fde347d417b11470394bd6be3f1793e5b4c58f57efdccffa79180192156c827f6079d2aadbda14e60373052f004416b1f2947b1657d5540d773ac3cd3415805062784cd46dd6405ab5508c1bbef311f126b52cd46bf89c471225710d1319229ba71d688779425f1b34af4f065690f464e1e43ac88cb8eedcb5010920253a9ee1880b6de88d54e3a94db574019d3462093a607ae7a4bd4cb45c1dd03f0f0c654172647522a7cf6e84114e675565a345244853b01a874b349a941d7fb1c74e7e75b8fac2c1195f87723f9c9c96ab50996c7088968dc1a4ea3a69dd42984c79a248a13bdee9a1bc7224b0925b02391c3475c088d4c5a7c9b62e87a7484a7dd7765bca28c43cc2f59eb0e1339b9002fbbf2f3ebc196aa08312d16180caff418d256a06c6ab333d40cca072283be5191c52530e6bb83d377abb9722ab34583fa0f4458de44af15f90ce4bd04f8a1526067730ea4cc9433a28ba2844b6ebcc412d5d547f1c2035a620885dc2bee746a83f9db7c8cfd26ab8c4f7d4096c6021ba5520731c128f7cdd71b87443402e74841f0443e998ad4ff9f2cf636cb41436c93605d1be4263535f65380eac7858157746a4b70eb03b5796b41e51d519f413fd63e339c79d27a7b3d0f450f7016927cc8baa8325c65749fe3f300745b238f7261f8a4ffed214e8eaad9e99a6b9071502fc51a03a191d4eca73a377c340a26b7f09dd23d8927d75a084803fc2057358c1c85d3d900315c40f25218fd1f6bbd4eee53ecf4bf1db319e6933c36ca763346b1150e0d0e484048eb405d409a0bbf3d10b26ec9a791d297d734153850ae804cf500aa4c4d360a21367fc1fd18756db534a69e06321d12727a05fea6d2783b2cc92b7c92c30886cac76f9317efca6463eaf2dceb3aa5966857683f308308a50f7dc71caab8fc63784dfa41ee75b0fc8f84048c49a70ee0cf309413edda1dcce9d2ae6d60496b3f621a5c4034b97b872e7a40766832ce9cdcbc914431e1e15544a74ade246ed45af67de8453f14df74846f5ea605041186c6e46e51ffd79b21a4d19dfa0a23426cffab675683f556235683a68f20c9cf8cf12db6fe19de3f4bc3ceed1d2ac570c64bbeabe00481868340aadb1aa8831bf10db650a0c37d2f06f23286a43c0d52fdc4ab42986bdeecde89c4f0b4dd4ff17d796e11736ca3ecd9c20383375e55ed41567ef644a589a74e283bf57f8139d6dd65fc31b2ff0ff31bdaaadf37ce796517570e7b0fa56f3ec16c022a1e23b3e715414120899fa42465939840e4d40e8cb656c826bbeeaaf4f50871216896370dc4b1c9d487fcb1845c0f0247a91e85e98cc953117f5b06d78888a4b94c3a922d30a7536bf32b61bcf753b8fe02cdaa3de43c9cb6db4b769b01d08714e5724812480a374b2a28cfad8bd77d13f68f25e99d279264f124ae98282d00ec040b12ee57ec0ed27fc6f2d54c631102859eaa78727a2a98c10559a7c6436fb3e1fd1b894de23747524a48e81c6d1a70bd05856d4a3934c5a0a3f7378829f6854ba29b03cdfe94edeaaa2d203101fd6239d5871feeac9c19e7f4001e774722cf06fa828660a0f530072087480e8f30ab00655dc2cf40a4b47c96a0e37c6a121b64ae1a5ff75855f09999d4d531d683deacfb242172c9e8dfb38e57a38a0f66b1ec5ac360e61a182156d39a4cda95f681f21fa6f2de2f68e69d1a5d51aa376685505b6628082e5548310154c22dc29342d1168ec2fbfbae426499be4b76313e2d6809061893fe6c01256c987a37a2938f43d8851a50e25081f19b105a81e61aff6a09c38e2f5301be4e8f7599c060a0b22de1f585f34273aebfc7af10bf03bc2b3c754c55808444876f4510d7daf48af6e7880b16b95749025ea433494577f9d2b0a34743977bc7fbcd5a6d6f0ce0375daf368d5f52e5ab26575b19e54d161f00bc6c400956855e0fe132ad43a71ea80a7c36c20a23f9b155cc7f881486f2004c6fd981cb0d72442ddd0e952292157f7c0383d4d7e957f60860ded8e43a4e78d1dd6e9e1a1f55021762144289e1ebd83c7f61ef519e119e3747ed49942df57efd6a82265c58024e3d398581138281751235dd4c8dbe8ebab928f1650e603c320d842ebd8c46bfd11906b1578cc6701feb80cf8f02b4d0ba638e52db076cfb9e226f52a823c38b414b267cb3b25c838775890bb7d9a21e458796ac82f9ea50090b36387b3c52656a0e7bebef9a10b92235a3829ac0a3b3059e275d378772d34f1b96d1ad7622e334f4aa4efa8d9220482309598e79cf1444fab889ecae6e068b155c43fefb6ac82a311ef6208d116d384c76f6eafd190ca18070be71822c5cea616c49089a28c9cd0e6e1aab8f8e54dbc4362509c5005ee8f20e20387db577fd1717a9ed6c5b822586b7706393919d57dc42d3e82092cd056807c3ae427713ad5f23cca33a547f723ed079f4393ebdb881f0b4eba74d7ba74f89e460f4426a245cff11d8dd4fbe11bf527591094ab8ff350af9ac04799a04bc56ab0f61aac26a7208a362867172b88676959c9713fb2d2aecab0f4d9c44b0406433e422a831ce2e3abf4ed401f455736f3ccc67ada80f04243a35d4947b82f6369aa6147b5395c6c73fc27dbf27bc83f3957860ed6216717fd0644939a50eabd4b43eb8ec3a704f1cbd4745c2f3e058cd48dd0982d577076025b1951cec47359a853e77e8b4af58bf976eb89b8fad48c12005cd7d12febe3724a736b807a18772fd4e191c652191f69a007b6744174336800f9302066b61db761b6864e98881c72687a9128f0b6f104270024f2ee2db421f50bc1eb57c6bb519a53f8828e9ac94863052f046fca3fd1acb0002b970e937a2ba06b05c50e8b58d0f51362dfae9abf4f6987d472022db7381a3d4301595ce02ee753530914646448aa331d8daf43ae2b448f5c2139b07f583f39f5d032184af4acf11e8d170e82d24bb40ad116474af212a2988c197ac72fdb18a380d8b0a8ebe5cd8a7d4a762c12e4c39790032f82d865a74df0d0cb24e4f781ce9cb24868574521b740b817b81eb8a8fc9a29b30e48046f98028aeead60af929ea680323b827ecb0ecaf309270b962fee0e51b533ab8de0a2f11c539d7a2f42f78e2ca40175b623f6183d2f8632a86eefb1f93cd54f3f5b9ceed6d471546d1d70f5ecc1c40826b44b74a9ad6b160b7d09a32f0b7cb63414ec7c538f5b617dc9c3723e4f9180dca1ee52e34b937848769042507ace3347252ac3ce8400775b38d1bf7668c6690ee0573ece3fb203bd6dfd52dd892ab52d52bfa24b8e63aac73cd32ed315872e62103c8f93cc2a941192ccd4f59758abaf347e800d0772beb9f33b055cae0f664c7f19c6e73c9cd2285cbb94a8a5fd37d10dae192024b165f6354ef3e25324a98840e7dd1a1a12605fabe7a659b81faa6e1a982670fba608ea670e4ef1220ff55fed140aefc7b559fca106595953ca126f491639a1167401b231de87f076dfb0a136257c1cc32781c570c2e942806d7266debc34619163e9ccd8011ed5e46bc954c01ee1635d0fbd9be3b803e53bebc8041d6e46c4d979560ef8cb9444c5e15d3bb7f9cdba40258929b7e452401280304f8763272bc5666d6e1c59bba2c06f620023c5e329bead09568f3681cf86de2100fb5c56d4c32ecc14da9eba88113cb845105fa8982f36fed227607cce9d1f94c5d838a6847944e9efe5f416b4ae183d715e2cf4c27fd52830ae35c7bf8f068c2e37364d1922b4d64152b26ec01449d12a150bff3ffab764d57e480e9d34285aea38f7fb201f893c367dd827e37a9b4b95d74ab2ebc71cb86dffcbaa3921e66e709131c858eb37f732d0c2b4391ba8969532aa98cbf63b542a7c4a8d64e8d691fc63715857f42dcfac43429e8811570477fcab92cf84cbb86dd4a015b227e4d3096b43bbb50105444ad438cc27e562660d506e53b146f5f275e3eeb1d1d7aa2cb8b859f29a5d665c9318819e695e3b78418fa99aa52f646c7c59f4e6c8e63e2c8701db5343fb24d9def155d39cb8eeca5188c5ab1d53472fbec53daf692e1f086781e2ea1548c33b7f3e09c846d0af6ba0b3dae4d295e93df9d6d8c50f2b6187b88f65a3222b5ce36b509187cea699ca1da46a29dbc94f86860771bab1c1abec6810e37fb42e80ecbfd9bc1fe87e2c54ca11367b7567ffc1fcb3a789d0cb12e21fe77985f8479c4b73dbd9cd12a713bfc0c5e69bca58544bbd1a2b1bfb70cfd060f796f5032c346012d0ae2c8a1e0d3adaa804a1618fabe664d1344c4b12a774ab5cdb9a01a2f7f5a0e3e11ec282321594b15d6c76578b3f23ba563c715938efc8a162cd084dc93fcf161ba43cc20e482be543e09a16872991d9799008d74ea8c84a7d44d2caeff96106e66dd84643b2d7412bff620c47f83ddd58d1aa30c11739084911cdbeb74154a86d5b211a17a61e58a0b6de926507a076f6e804fdfaa64cca3e6e86f637505c90e20c8100da502cfa224134d1a5fc0705bdc9e140c8ae434ac8941c4bbe31567ce71995d1df23960b98e213cbebf67fc3f2728ca64dbafd34d336cb88540689f6a3605e675177743a81971e9efe8c3db099070ba1bc64903f705a232b9f0be283cc07a4f1762fa76f14bfaecec48236259f6974f9cc300b92b85873c08c603267a919d623b5f06c93a8dad500a2c4cfd101345aa90e424b42258672b1aff69477033bdae6ee36d19d412870dbafea137af43e1b2ee90bcc8fae91cd3d9ee94bcbf5baedf1155513817e6887377d2ffa6cef391ecd62d324859582622aa7f4dd1555fc6164723d68825eb0a7a312fad5f86dd6bcdf5824cca7999e7b6e205a2b38700b3438263ab4c841297a31c415050f46ee7e6717382eae7879212f67ba68590ffdf36c3a00a9137a5214d13593d57d868a6e2a24dee2e964515cb47500ab8e6b7496b49c036a8256687de47a0f7a27a78035d72d513cc1c322399e841a900ab0b8d7508879671c2ea343cbce40b276410937630207f2552d4da09aa58305e04e376aa2bc846c590df42b1b41e3e47f513dcd0577d98282e74c2a777f4cd536904b38100843d42c3294fb8ab13ce1d48b268bfc4b168e9a0353985cdac3a698b3c77d6a173cbbe32ee312d3a0b18f13dcbde762a0f2464081a4292de9d4ad8ecacde865553a80db36312ce76864420f309778056e736792aa54242e21eab2f43ab0031235d4f88da02168afa31c5e74d00f9e19b4351883d2dda13a4c378a71743ac94cc2b59c898c0eef1fb61e46579dc6ad8605e21fa505352a7e0d152a3b1b78d15d8efc47feb26b20348b418f19b41a276cee6f2f63f5c45cc58b0de4c3bec85facfff3e3a652bb033b6ed4cdc8a028f9902026d41c60f090dbe4e2048263eae781d9f9e27d2188bd0812c806cbbab9fe3abff282f30d324bfb5f244fd9b8716c5c4adc8aa8aedc420cd42699189785ff575edad52d8418924fd9768b17e2cf7f6b05433a8946ae5c2ed55b6889f568db291cfa62142df12f123c721a98fed07d393e77ed90b2010c3af6e56546e23c94cad03c2e10b4c10b315a08a2c1634b2bc268e8dc35eab383c10da8a8b5daf9bf96231f2e446f7458756fbb8f0e8894c4501758050b6ce448b56ef7a83d0f8ef59b39623dad30a3788d268497824ac24238d72c967c3ab37a5ddb3fb63047d82824521fdaf1136a720f7b07b92a7032bfcb327f20d7269af96ad9d037233d8b802446371eb71e6e285bf6ce91e2dd82a501b914749fea6ee08fdf17fa941465563b408430fed81e245fc6d58482bdca2d1231215565e5650a32573ab116facd40ae4cb4f4a4d1c5a79a2c92b81d92d16e698aebae9fe2180ca22fc3efdcc41679da9e2cd8d44c5aed35e337ac41a9b16db7f2c7de666260eb9a7894f4fb7faf01dd19c54e1c5e01f84e769ae5ae2c893c691eabb87e368bc79a4f3eb84172588e07e23d6d0f7b12771db3c9e4088f28edfe44e427e3198b80ff3330dea2eb99dd54644945c2af43cbc94dc11e6068548b9cdda2fdacd12854b88a645d91e2802602ec23a2fee619373d0da3ee4b997579975b6e9818519b50fbcf4de48d44e7741b78283f4813bf6781eb2f609cf486473a20bcb4dba1c90875a05bd3921b807876e67c54e4c110c8270af491f736c64192c2753f358e66d0b8ccb82097bea25b6b6f6695931d56be629050afe148591bba45b2fb1f1bdd49191758b3b8e41fe7ed49ceb54942cdad98385841c4b272ffcac87516574c4fd0ff7258c019ead7008a0b994129fa1445c0b832bd19147a8b198dd03794bee2ca68deba472cc850e74eeb16f8051c966b1d8d7973950684cc9b01eeebb3933f29776e51377987a871e852bc5744eba1e8327e767efe8d8dc1c3cb38a936aec67ce90c33740fd8afb75857b8f4d205e358b246ac75bed9f3b4f3b2e7c57dce01642562f1a4557d8c8cf9fa4472d429e0e3f29697fc90d9f0601bef14533fc15084282ad713e5b8e9e23e0c94782ca48440ec9936cde7268874143bce8dc67ca06d46a75654538c7ce00b3ad5baff83718bcc6925eac3c31a272b0711fb44a8ba17b6fbea104258099f23be825974f188d4515083d98c8cc1823022e2246df31a3ab51b3fe22fc29e11c72308dac6559384309caa400d44f0dfe66f266f943a24ccdc1d98ee85f12751f92e46f9951d2fd43a313303d1cb81614e8abece042af1ace614cc301a9725b0d79e05bb5eb22fbecf703a6a561b92ff3f6607ec28e68b4944a1543e285968acb8ddde598661656dba1557b5327e425668e747363afcffe965259952b3a69004a9a806becd5a73783dd1f6d9fe49ea740be21728792c5447b9cebaa290a62e16f3cd8408f49c4c3184ad8d1374b85b3eb7f59c770631b536b52e4bf32fc4f903f2e90b6714342532a6514a1a428ad4923149dd70953b4bc283911fd3beeffae2d7ac4d3b0310c605907c709b889d0a4cf7d44aa27608ea99ca9d94399e0a231319d8cee89fa85429289417ed8ce849136fcf287624295d2f92c846370aa26501c4a198c200351995779827ed7f5379cc977bc68fb30cf83d8660a070eb80f7522da17bfcc9bcb84033e2f52493f40594992535857eb7127d27d034874e0d540605b17bd191a1faf237983dcd7a442c497a24081ebe6c15215932fe7d7538036f6394b479ae1f46c4d26bc74274c8cb3037f802ffc82d63add1b308424c13ad76fa5cbb0763203b43a8b2c9728e4204903bc2340c5b5362ee89b36a715308f0a9f1c7ff9b68fef8ea2088e412e1615cf4a916190790d59d8181b01c71893d9a96ba4e525650c15188d7fbad51a9d40cdb14a13305c2d392f4e47d72228f00869395fe5b34a4646db5111bcba199a2a52e4ac4ad230cf3536cbb1980e9f6b401240dc317bc7dc8b1b59be9810ab637b58bae69defe307209d1990f67828e14f4016f4b49fc02c76d8f879d1557fd3826d972a4ac07b4e41ffb99204c5a3c4c3bce68d5cbdcd1b7722f8b5c87211c73355308f5544656fb22bde734e6a1fd942decb931417fef407903e4351759e1c487cc508ec339114e5cff78c4c8c3601a4a0950dd5c0a6f98b33534863c7462bf3a90bd5a2e3105b911875525b07dd34c77fa98eddacece8a1f7179b5e0494b1f8fec408faab1cd213ee3205842ef81e85fe41f5801e5f1a027f21893a10324ba0f84008409d0867ce1ec2664c45d92422af6d1fddf2d429e1d17f2c5f33579d6b31a842196bbe5a210eaaf66969341b7754407e62762fd553e24aa27862bd0459bbcdab24be058b1aca71ad6375ef5093f5136b3af20ea145c96925543afb4451a0f14f046c9825199ca4923ea9750526e1f0af7c5347d5d096a58f0ba63a56ade6f988962c51685e206c57ed59de0c52deacdedd4bc96e84f01c4702f8cc141b052add96264d8d73f28b5be74ca20792aabc11fa220be505d4711e480fa15468d71a5d8dccc2b0bfc1516cd811a9e804ced528a4f3b16978029e7d5e1dc3181f126bc3a50a54a3a8c4794be0a6f1cbe515784861f7216fb434d289848c79902e232d14bcd08e4126ab6a8038b41fb2ee2e7c84c94394ad763cc1daaf0e9e0e9fa421ec04df7305f2926e6f6d2f00c34d1b889d50ffee76edcffb7a1e1f72291b16dc34f951727a6292d283985cdccdc1c8168ba6ccc78e7c0a369f7a0aac88f02bdcd1e81904b918c7a14693c01edd31f1c45247c965973974c28773ecc8cc525516976557df0cff08b427563884db57217ebeeec5cf64039c1b11a70c945314eeb1227110f47c761514c1ee5afd27409bfcd07b5b7f961a75bd3492a17deef06a86acd3293e9b45fc614f2692a7331896c26340290b9e80aa5b22e5e64f1ca00b5204df72111ac60e9b427bec65dfd8045de53e9f0aa0c9120abb5c2e20e8fadc1bea98e41e629a5f10a519ce29fecc89b754301b22d9201a2f9b15a7e9edbfa6249ebd6a4082a77c302f173694f989d08fc56e9d25eaa3bfefc30c3b4875f23dcfe4783a9758dee9696ff30ed786768697904fdfa0fd3de0b918dfec61a44ce8e25e840fe1f5d17221bed60ee29fcbe37496afd9946bae175d5061f1a61da4371c71281d9579ef941d7831f83affc9944221b0efc6189cd78368755f39ea63353f4f552834b640cf91f772c86de99541cf63a06dbb57bb08219d81a92f9a71f3cf17d79435b094bb9ab45ec40e4bbaf2e2ca8a02d51a947c6b65ff7513407e3fc70e611c1634b39024c3de11c29c7a5b474274bf8c710252065b0bfadd97a3bba20f123476e3578f4a063a10ece40e438de07b0c09639addbf628247d67b19a1975e6e9a405e1c22b843d366aa7e0f3c6a06fc1be2f95a93fcbdbf6bbe7016a0070e981f8cbd5bd429d99390c5412ec8dc2bb78292d2390ce29e8df1c02a8d3c990d9fc5777461775720ce158c675743e0857db1a02719693d2ff6b226b64a244741d7c13f34a90c567165072c5e32e1352beef78cc0ccd4835e4b85353d4f73c25efd416a93948316a7f2423b3d30f2ef24a1b744cb04c26c042bf48eefc28c231a3956cb1fe68c80db2576299a31d6cf44b60965b40f4860afee439273f123c576ba46a424db01c20ba91af20206c0b47152bfb000eb98c0e7f071f9996ec66007a2a2e623991b51cc16e3c838f864aa03281e8d490226db0657126502b983c3127c765ae9aca826a16b204e8c499b2c0fccc4a29dcb6616b049bed640b7b680d21d4a3fe6a50b7e7a14da91ed06caab2bbf75aaabbcfeaaa4ab441f572d0b87e968955926d9a4a405b0aaf4aa1f8d6809f568b29d539b8dbd09fa63af01c93eb640ce34a7f9cd92676281f9abd4a89a30cf0ff950df80072c7217bf6c3c20b51e1930bfcee6d86516785f2e923086d3f4089f0b77a111305016f3d588be5e40e5615f0736ec5c73c2b7a87dd47de039a513bf2639e1051376cad0af4437c8d89a1eb44936c2a5956f612c1ad14e02649dad195ca45bbedf050909f1fab82a9e66f3f20573fd5932fb84a23caa7aba5d741ea571ae7c78b411856191bbdf454104bc0ce13cd286e4df263ab0c4f644f5cc12453f20cff995f7b3adc239ffcad392466112ae15c9eea6114495a4985e4d0920ccbf352e30bd299e05a11cee44cfa9ca27904d32be217a97a8717f858c8288842199d50b44564f1bd4c35054678dfc409534adfc94a767e9f9a53e4fbdd975e2b2e7084a7899309ef5146ba086285a36bc7647d32aee7d860adaab0391e426f8093fc4f5d4430b47dcbe40008713df69a79f1308f188ff3ed45befe2ef4fb1307740eabfee32d66c18634c72a91fa7b8a0f74add13224610085227143ce590a100b53bf89c10d0f2ca698a100b54f63d36d81cf6384305c581091a32aac3e4e6a208bd89259721fadc7a5c2aeabd17a285c12cde0dc8938a5070e179f0d98c17303e4c4441fd2e443ced9c59786964056dc7e294bc0746fd9f2c9af0fce2c7d2d4b4f89a75b1ec10d625a1c378f2f89bdbcb88f11ced2b8b23377204a52fd4b858b012fd220acb22a294f86625a057c98d9d13d297500e8d390d108fb4ae528e30f86cd92a285a111f0907410d4fe008d8c479fa730ebc193e5c35330bd05e8c04341cef07634cfb9d4c056822b8c813fcf530d70233d370423d64dd47f62b931d58aa54a4880806024073b8eff633e9fee2e413118386d6a6f2c86a16cfb33fd1439c1f74d61c40b44fe3901d5869d241e1c43dc7f2a5b8625872196310e596e049b8d97aa60670738e3a4f8b6d7a3638379dc8c3fef8149eccfdcbb9d7c1f18174e004dcc5769b66c89a48f6950c8eb0bbd27f68cf1614907aaf7826ebb104ff8783b8d39b5d39426730aa863e18e3d7c97286498df47f50f16367f0647b846bb45b9936e335aef881a808f16148928c58eb498c6ab3ddf117560df2c0bac257007191758ddb3368b7caf51491b7470523348745b63bcdcd1a0736c66d7915ad1ed1891580ca0e7fea4f186332c6e5034ba426535a88c341701cb5596bed0b8418cbc2922f2d2b95165e7bdc8cf4e6b3cfea2a08f7167f229de9ca166ef074a4e8ea1316d31e80101c67d74429531c22b6d720034f4ae2f02beb6550380323dc03190eeb163725e185e7fe20b2f958190873c32bf0a7f4a97f554e7af64780acca019df57d1f810cda28a7bb2f5b6fb582780b98c5f93d0277389a61482ff9fa95c23cf5eaeed4c7e41c2155b2790f56a26f73763ef16ebc1a25085b07eecc057e02fefa7afc42b5c55bf2aa91d9d9f4ce733710f75dce9bb1627e2bf91f92490329a27bc6107fe9fe32b19de023539b049dda9ed9cdc1e6b3fc84bae4340f57f8ba67a507574a5f09c6e386a1bcf46a7a912ece4cdaf98a4eb36f50f0e445d791e4d999aa26845ade7795e6f6a2a993914beb408b1e6e86b289004f874fc76283a105c6c651250c24b1623501c8cdb991087c2268298f17af3140da68fe46a31c1d0eb450f2970ca1202871ba533d9d6e675df72b58d80056e8cb0eda20aa2d0d3e026d9c24c031485f10c04b3ea843a0bd28be7a6e974f6c8d83b49dd1752d2f380ac3197fd412eb7b7ec218331a8814d4c178d64f84dc92050c8221f7899b8ec08f07004c01033f08bbd00bdab0e96a993c556d1e948dd5b295c4c23bb69ccda447f648f1ff4808af491cd25f8278a80a0a2f8f77fd120ca84e4d38ddfeada91d046a83736ab1bd360a7999023439719c0e789bfe25c01de28bb79363be7b0aade874af666ba5e43d5e37c05408d08d4a7045cac04eace87bf5930d8554d07798b1b1b8944546f39af885650aba0c4591287e9c83f37a47f09af018228415548ade073f2fd60c06047e4c1037e1d3f3caad731c154a21134ea9e60814374a3c520d7b343d3a6ae2d696defbdb7945b4a99920c8c0caa0b990b61e0fe1612c2fd375a2ddcd282a2acba56126cee962b7a1acbb67ebedf1a418695980b7a0c5bc2700a1c3481b5a0e885cdee02ea5a5d2ba6ec5b6f5503ab602d49d7c2b028856d9c575eb8575e6e337ab24224b18c958bde8637b851cefe7c2d28bacbbf39af0ff9f7b536bf6197a3452dde2c9fdb5e8eb6ef7837ca8d3c49a34703532fd3cff3b9e938dec4cedb9e7a905361f8b1cbd9e047977f1d9df8d75efc89a87ecd8b50c4967fd11bc5253daeae068debee01f4e56fd0b39089ca490a135513dcef58c07e2dc86de46df937bef2729b785b6e18e05f7f2b5a21b7914d6f74b962caf6fb2ba652bee7a5911267c4b731eb741ab35817e78ad15dd15dd15d3ee42ec78c58ecba1c0bb7196a1e1ca59416b6c469ed4f7b6144dd788459c7c323e1de01dc21bfff07dc11bfbf79d0369107fdf5f767875720c23d34eea171862e77c1999637ee00cef4774de68fed84ba967fdd3f91b0a4eb83e1e7aec572711100091b7cc9a42fa6460f5b2f2c67b92789b0e4929d65029be94f97b94d8d8225ce9a3701c7671285220d8a12d8ecacb6e9872eecaffdcc4782f4da4f4c91ae275102349d4564e32a10363b4b4b62f35712d84c7fbe6f04b2ab3fb067e03e43a1cf5a1838429706346ac594bd2b9fdf7e35333eeb80ad4be3e6ff6e8dd521e461e0f89ce7ea7e4adffdb9b986a54365b3b380e84f145658763f9d12b7f1a1518b966133fdf942514c8d6e29a222511770078d4f4bafa1989d88fefc8c5a605856c489bfb5626ae2c4df8462aa71a28613254efcedc545e91928910fcedd4fa78aac989af1f5a5fda836224a86a547f40c324b1f9f9904ce7476564c395144f5cba2ceceea388463f61f3a8615c283633f773ff6bb933824fab9576358fb31656f4fc5896058d285117544e7e8df21a6b41f884a62be96049cf9813b3830aff60367e2974a367661df59ceda669054b57e7376777f0f8e9fb94c5ae14853245544c5e7020a49d53dbe05175b442524554ced40048938922aa648ac888a5fabb5aaec85a88c4eff26d23c8730de01ce78c13619968421132e926088c7b0230c9970f104ee7eaac57ef01c82a8fe5725b2f467461152b97a8668176c7f1eb5b0274ee0ebc99232709096c0e8496fc3e8493a30e1c2088641c09009149ce02dca40b585bb1c0bc841b769a1a1fe5431620a49dc555e463842b791d45994f60ca0904e5244ba888b2738bb121ce9eb0a2dc0d983c02082b337c174b6d522e57588a994ec378c23791be5481e0e5d065f0a3e586a3f6e934b406e9369d67e34256ee34c701bc8440a3d38be27894cd07e6ac783dad0dd307afb374e7f62cade1ff149ac98f29f888a6f493f38b2228985e34b16176c7696f5cf5fa54ab49f98f2194054fc24809cc0f17780e367ad85b59f988238b1e52c381329d0a53ffec527b299e7a7d3993ce84f1f8ee9bfb80dc535be34c262c514e9e3fb4f4cd98f333e7a108e9f32835adacd21ece84ea13b5dfecd1fdc1f9fb4390acad68355e1d8421a07fbcdb9988704350fecbdf15c993d56080f0ef6feb0fb81790a5c5ae9d12d587f312cdd82f59bfb85a9181626d15c9da37fb26cd08622aa6d983fd7551105df61bc79a73b1b208e46b560fdb3f6da51d15e40507b692feda5bda863574a0914bfd67849dacbbf26f202f404d29e68afbddc467ebff6c46d88608b0ff7df51c19107478f57c63f88575dd87a08e243c5f33d1f1af3a841a1d85c676c1f659eaefeb586b78971b372199665327ad6309bdc083eb735172c64e285112cf10f4fd8c16dfa85b88d6781fb752882fb33d02df17c1d89e7cd418212ff20e6c90932ef0cc2d6c454ed8e12fa28fb8021cd826d5c3d0f541c8496f10515f64bc3b012bbd742c1b0f021762c7f7a11cfab837f3bc0ef1744411d45517c6298778c31426c9487e0781db76a622142ae677015eea757b0f9714d8d8ef952cef9f3c62141920636d7dc442cd7c45ba70eb7a18fd544ef72a40eec3b073857a363de1e24de6921cc836f3c05a5e0c41013268081105d640127be8a5b21be845d0767fa254a1e788105fc7e23180b5be00260d8040b49e463bf69f2351a2a73debc5363867dd2f76d52478386e7a8d3d91a7e43f8fda4eb72e06d810f31c66d0f576cbf9cf065bf9c7f132710fa4370431bdd10caee697dd836aa8d1b6f2ff7130cfbe69d97ddb0bbbb1b4807a18c3c4222fcd94538c7f780f40fc170765efc3abf46d93f9f34174f307cf92da594196e21a594df70878d12cb0db8c305c77753efb6fcc797d903fae1cd3ebabb1afaa1fc59ff26d64d07febc40e66f966b4fb636ea74fa81d4aeab81c3fdffded2cb38378237efbd97cf3fd8b5d3d9fe63f0b487c19bf1383cfb2e1ee95b46cfe2a97cc9a3f136bc946f2ffe4ddc3c88e15db970deecf30e97279cd905525ffe940d6fcc3b5cdee92efcdaf0db83a9fb137e773d785bfea3e4e0d558d68788650d151af053e0cff0acd770063ec97338037fe44938036ff621e24e473e90ee66e9a8eebb9b7738f8cdc5a6698f7539daf432ef05cef76073d139e25f0ff3a097b2f0099e9f43ff843fbb9f6009ffbdc4048727af274fb878e1c0c59327104e205a6816c1c409704b2e8a7f63b4907fee0465b3bf7adc26cb1e5cc46d7ce8f5c46d1a3b4e7f8c1205fbf5271e6ff62f1ce2407ff5205f3a6c6e1fafef166b9f8fed833d88925ecd8f1a1cef2abaea5709a5807306a300b4051151ac20095318014ec9bf1cfab9e5064b09570f585c3fdbc050057b20af60f8b506dc512f0ef8c5873219003047f670748133f13ffa63df4b5a31f545547cac591b367aece69d16c2f54b5fd8fab9a4e3e25ffca235c10f7b549e00ceb6df246c1ff97d8133980963dbcd1698dec30fbb96c70b8fc74184e0ec7d8535a75ed86c8730446519ce3e80b1cf3096a944cdcb15bbbc944234cc229818026318f6f4721b6821ace25fb410155f0583d9f6932d6659f63a1067cf837fc098cc3c2d099cc20a4bf0e61cf5667ceaf160cc6b2ebc0c87549ad7294ca0fec114524ca0a882048c55d1491db804817242b8000626aa6deb110300ad99a930c1c5073fb44a20d4e0411329b4070632044d41c22414181db8ea4c420e86a8943a80e189296d548926f0c141951e65e5420c404134c1a595047105ce5f8323887ed85f311d5f5111aa255b60c560045160b284193c78220b299c50050f86e0c5d49a4a3ae7ac45c0a6c4a64a562986614556600cc330cc09b2685534053602223e00c414aca842d015aa3094708227ca70c2851e571128a86004c0e6b685103920c204319814318427a3303c095098a08a1700d9a00a27c09c14a59020862174a1230291490421b0f6425703127001ca1642d842106a307262028a85919f2798445111a1c2129c2461c614b0f496e02385102bb8c2132d38f981158e04982c8e4c210c30825400c6130770424413272f788d3a29e5949d8e2643d022eb11f4801406c55c1d145c098648e139e784734e1b184e410615d84a0b55d32ca542144544d48088152c21053648c11347a00011295450848a272db0c18a8c1944c4a4c0e7b389cd6a53a0652ec084a8624588278c84b0820d218ad8e21073ce394951889e6022c62b0642c46086104cb45c91851c1c61f9600425b862082b139b54f484b12971e16c8319e46009158c7042122d78984862c50ca6a045174b3091a2084f6814a10945d842e5306c52842b8c60049c4b49bc82e0e2043228c3082e8c2420c9828927d8a068c81316a89a6ce104105514c189232e272b208cd0c1162efdb0bff69752e69c73ce89cd170ca94881162990c28980bb8b1864a18355096070039c8e02284a115430818b090e268553206105610747a8d0821190cc7062ea42184c8e78810b32806208655c01ca17494c6105110a94802502b01c0296523e6b0942641021dac20e70a49c12053f1002420c97e80499d51902244f74e182229878422809cf8a1a9481852038e1451288a0c4c4807892a2221140441324505286149804210553154d94d10529ae80018b8a160071849486598d27580882135914414808f439214c292d810c9a28020a44c00087624b566aca09d60e8e74410b5eb801a55410b102d3164c85706550440b084268420a2ca9e1fc359a1899d6754e8a65c165567ba8e869028464094928a104195f10760003297cb8008524304108b6a462b17f2e366931ec31ec25864d942042b582844fb22a5530451584e4ec545290842f8440b95515be68a2dab622b85034c5cc64114574f1831f5a5588a0c1173d704d2851104514d5ed558945aab08213536612ab27d0e20a4c4c19c4aac88b25360c813084145686ba2812bd865c42ad20a01f56af78d0e1e504e72fc35686431916e5eeb9227710ee87b9e3cdadc2fdfdb6fb6b7fa9bfa6bf47bf0efd3ff4f7aabf5bfd3d5454bf80d12ca26431052e661106c604124c2db689cd2cb4d8b23042162d1a038ad998d864628929b4d12b301c37c37ccafbdfc83e4c9c72696effa82ccc4394fcd3e9e47d1fccdbb001f32d5d0eccf7aa7dbaa557376e7eebdfe9661df0e94b6e03737363986a43f339621b99cfd426e6f386cd305fc27cf6262f3f36fd0693c1c078ab3a12d830877c1a2fc24fbe8c47e1273fc6dbe0274910251ff5f0fb15968f0face9b3fba05ab96293d74d7c98587e767ad8994e9e8f57954cf24b3074df4b24d8cff4dfa3bccc8351bfd2e5a04ea7d3eb407cba3c58fef79b73262f06c6e4f16018cf878963bebf8928cf55ba9cef67112ce79f2391e3dd9b78f6960febfbb0fc17f92f6954660d6c85daa8a58c45bbf191b616cea5c301634730a066c4a4c8d078f911e2d3cb09030e97961b2c251b2b355468a4ccb0a451c76d5a5629366964625030dfe636a61a07c683b83b799d743e60fee47ddee9e59bbcdcd8f4ddf1303dccd77853dbf06ea70373517ffadbe59c6e8be91b9b5ec56b313dc430bfb53ddd380ac6f32651b092e66ffcf3967fa797f2bdd53a3d10e9428fbf7729a594524a29a594524a29a594524a296ffe5efef6b5bcc9a989db985e7e1ec42ea7ff7e6b1b236351272f9fde44e37993b6289a4b43f3a8cf683ced673c972e47e696fc93a63fbda939d39fdeff06eaf3e9f4d95ba7f726fef9cbfc0d99473d27e3c53cea3bd3b73446798d6167ba2afec98f7917729bd3cd129bde633c193ceb5f365d87b9dec21067379d7ed4e59cbe373da9cb3159986f7b2ab9c03c44bd95dfcb97a6ffde7639df0bcca7743930175a797a1a5dce09bee955ba1c93b75c48aad048996149a38edbb4ac526cce78174962832fd1c62f7e5facb9e91153a48756870cb84d7df83becf0e0c30f42dc26e557b4898ac6f01e37e2eeee839d4a218fdc1753347e6a8dcf0e097d3684be1622f2641ca5a9c019ee21ae8139209d67e1c7f90ed6b88e86c803d6b877aeeb6efe016bef1cc9b311e55a1d798f4469082be1a755acfdb0690f9354ed36cb3fafc6bf24fef9cbf8f7e56679e65982a7d0c32f3eec2439f84f7efc337df4feaa51ab7a255bf58310b78997871daa6039e7a24420d8baf9e1366ee339200706f4b80107e858b8aba56595d277c514ed4bf2f12fe68033fd3cdb8ebbfb6370bec3ffdb45ee82adea63730e02908ef400fcfb6b84dc483ad23960c470089ecfe3d5c7e6803ba0cb4b09be84ad9b1e3f8622507d6dad24b39124842bc907574c8522f8842193293c91af97dbf854795cf2c51831e8099184e20f850b6c0ff28565941a2a34523a24521e28fab76d5bcc91d4e9d8af5f492b92119f91d0463dfb9447c8101c9fb48a2f23f40847313a129723d291d8917ca47b9451facd9247883f8c993f8c999404e70cc61f821d6af0692621c1391bd1cf3448f2c1d9cb87da95a4971fbddcda0d8d6523e70faf7419df6ff611df9f64a467f087d43596cd241ff8d967920f966f75ecfb05e2cffd8cae066e06b69211c6cf3bd6763af181c09b9b142db68a722484398fc83f8ff6e9679effc8db3e7ad9df449ba1cb432285b4f22f8b40f6b54e1bbd66bb233d43ee1b7907be2e102def40577ff780edb99b1b6bd9f6a7e36b4a9ff5f800abfde8e6c6dcbb97773aedb6749fbd0684b37cc9d7cb3f7bcd7b61eded67bf4117d6de3ee97365e1ed357b73673776e02b4720dcbf43bab9b270f69aff68e55eb765b946212a7a110dbd5c4342d81fb6700dfacaaa49949056a4233d436327f960578d8eafe6bf92ebf5a405365b0bbd924b4b478d8eafe6bfd2dbd883c4fdaa989a433ac46f6c15d4e32ad251f35578e54bd2f87e5914532adf3554240d2f4546efc70dfec1c75e33dc44e408cb0535e86a9ab0b9d6927b2a7ea58bfb65c186fdf65be42e0f10ce5ed4db38cf86d177efdd0da3dbcdd7e1e68d5fd8d8e2837bf93adc6d610a3b8e7b1d88b94b1fba70bd3c2c0c83741918a7f37ac4fc587367b2c197aeb01eb1d9dad27f2b1f316a78b0c197ca02db0f1f9b2f2a64546dfe9b7b10e81151f07b4454e3c0997e1c38a373d339fa6f3a077cd8ffa3c7884fb3babb5b2dd4531675b79452d2f6a9466ceeee220d857eff10a5e707ff9a07b7e9f7e1474cd1ec2191bba6e0aa09c4b6448b7f63f8e29e271feb8617484ddb60832f11765037c110a7b6506d28df2fecee9562d089dc716eb49017b797f8937effe99f0eea1ffffce58fdb4479db3f16492a36f8922b0bcfdfa0a7b6168aa9ed624a1c355f5b62a1c0ee10c29bfdb31c6ad192580ce3aa8560f37cdacab656d0960509d980609c3fdd7c4c48cbae08b2d6a65d1168427a0680c3fd7645b061405f44cdbf22f8e66f5e0b8b5284b962caa76845d4f3520d1109bd606b280a8bfd38a1c2aa2d65ece707fbc1300402501730c510084059d83004021011f633643104020e88605ad433f8cfa761c8cfd84f5b01678486f0ed05dc81fdfc16f29fdf56785c45d4fc164aa94424a280e7572fc2199710955d281781806e02b823fefcfec2535515a3929e818ed1457801cff9304726f0540267e647213c9f36c1d81210351f4b02e6983f971481670eb01bd02fe0f90367e677909559809f1670663e1de3a7dcc251f3a517787e26e15c55583ec1f373edc1f3e1cd3fe3504c3d446d01ee88d8cf99c24203783076150065fc6f1cfb9143787e0f12cfc77efc9b95259da4840a70e34baa2b88a9a8021c8f2a70251a8c50cea6ffd54094bf0eededfd1a2ab2aa375602156e41823ec4c1522c167c086ba6d559b5d9d25f833f9cbb0571ba1551fe5cb0b95ba58fa86e61347b8f3797b096d53baff4da27a2523e20caff8a9f2c80a0205b7eb42aa2fc4bf8c3cdbab925487bb871fe580d8bb07f55817595bb8cb2610f5fb27c610cebeeeeee283d29638c3146f9f3654e5f8f078552ba94710567fca9176cee5fb93cae62aa566b4ba5ffefaba96915c674f0b8f2f102f847c9c47e5cb98d34e23631c628bfd6fc8fe3c7ac03fad783c4b9e28e3ebb9cd9d5005b38835884de7314ffc633988aab6a57f1c6554c753402df0c57188b5362cdb964ea11d6ff87a77e38aa7f6888a853b0fbb34b8da76a1cc539aadf83984070b27a867ef8f3889e21c9fc8929fa9285a1d722e850a8e52958a185a51b78c29916024bfffc6f48564f5cf510c51fa218e4fca8335861f748bdb0d2b301e6c0b0cca304cf1e300776041c64c88f7a1b005158e689020ae12043f0fc0f7b77ecc33ee3506b53f9039efeb30b422881040ce1273de9b5d79e4015052e2e3c03c3ef14ac641941fd22e309142965842b2f97db641a34e436590b1a8db0c0bd056e0821ac533ce18359309c02072abc492e7a35b20dc72b84cdfe83610b04ec93fe067b61bc014654b7cb628d06d63ee951fd2a4fe351cf83d3341e763f663ce75b7b3fc18d84cd56c55e2b1451fd345e284619638c9186b7f2aa31be46c2f3099b6d14e95a50d858b4c19e2dfc0bb7813688e086f8896ca8fc6beeb7eeb4dfe60637c869de6b3f1a7dec7246bf450990debe0da4b7cf83adb739373d8c07471f24d680462b50f20a14ed07ddf3bbcf9ff6b9066b3fe894dbd0f8ee661a9cb5a0a7379f70d6827edeac29a108b883a0f29d5c349db237db0059daa2414dd0255628a6dc55b520ff5a6b82fb37eb350e8d57f16af8f8d7b562f7ee7ae2453e0611dc0d05b7d6d1aee53699c6905093a694d2ae5583c53590f8e75838aadf0a357cdc665e6d490d246e232f12f6fbb5a0985a59b12baf5682953486686ce136f2d296478f0625b11ebd0e6fdca665750b2d9890c590bb7874d79a338a95971270f7ac6a14dc4d14a189209cbb1615420d9f959750fcbc12049b331f2b94e2f3039cbbd6ca4b0836debcf2a2415334f1841258c310084e0481374e25591c098ec0fd9d7d480bea316cc4708a269eb822aa5f63d9a8a24134866ef4401fd6f0b9c1a22daf991c595e2d4b6cf7b986cf0d565e7941a1fe81a537dbe8c18f6df4d8006a1b41b86dac566cb06cf814ad44c19d575ef1e6152218acb830fcbc22658c7d83d5c4e61b293e2d9b6bf8e41b2c979e1a3eb8df65e512858b8fcb127761e2d2f3e302d4bd6d20d8dc426308f7b710459c9620741186d3e2c45b90005f34ecf7b7b4628ac6657959ada585fb7dc86696176e82062caf9882385d47375b8de5d5b1bc70dfe8c17d6385fb860feebf6185565e19865334a1054e5975518a0a665d4ef6a415c9c84ed39f94de5a6bad8f753935f39056a423d5c71b7de6b1dcdc9865341ad11fbd7739a351e6e555ac9774a473f4976e903c0b21cee6be721bff9be79c1ec93e29cb1f5914512fe802ceb87ccb77a7d33e449dc3eb8feaa590a0572f0f09439e438e03037d160fc2e0394e8a97e1507e172fc32819ba7e6836dcbbf6f6e61d8d74e4c6bd6ee18adbce5859f969e347a56ff916d2df78161c7323c2e1c70d5ebdecb1ead9a737b7e8f4cd2df6f2c0435cb8f6c3c0e383e9f3e0fecaa3024ceb90a2a25a5fc7f6579e15a6b5d621435c983e8ddf30aebde9c37eeb7419389b2dd8e5316f88e161781b62b83d22aa3e0c9707e35c1c38d3596df1817df63ad8bdb9379d23cb321e8cbd4622d519b5561289f4d94e93eebc2eaf3d0e96cda5a5f4293758585246a3d26844bfced1887e2d8d3e6534a2f3e694d156ebe8daf8949167a3bebc794bf1eab74df93afa94af5f635447357e04039b690ff67d5b7cccf92bdbaffc8dc395152fcf6cfb95959fd4eb872eeaed34105e791a9f6dbf3233ef741a3610ed6ee8a738c04d75c0ddd1dbe2c33e7d1d7b61e7e8a740b8297d1d88e9bda13e22ceb60af48828ec71e00cf67dc3c058bbba5fa7de9bce817df7eb40dc574b621f086b203cefcad7f02c56d19e869787b8521a68db9ef318e0cdec31afc71c7aadf1cd0becf619b618f073e8dda7566ba97dd7a1a3a6e6fbfe3ff372fbb0f61ec0bfad8130290a8d381ada6b7cc380f6b487b3859d35875c34cf213a87661467e1faac920e5b3387b077f607d001d7a75747bd07f0cf7d620964e24502867718ae9754e8cac565f8c1278912ecacfef1c7a6f4cf353d7ed80077d0ffa1661ab671dd0f590707a3e4ef46a95ad82860e8058637021093f9c097516cfe77bfccf3e347fe64ffd7ef2f23d3b17a57a0f628396845862eb8755e4394fc1a533db89b6bb49bbf52bd7da3fc0086e3ffd821c7bd80fc1e42f15baea62a76c7f8f523fc6f0ba5fcaa6119b7c59e51ec28755b03dc0153de62597c95389f860713808003ccb0c300299b02106000020840cd0cafc68966fc5c21fcaf49bf4d38e78f6c0fd118ed255d58bf8edff147b7db5eab8929885363e9adf98ee81cf067cc09e3cf2827ab73c46f6659ae78c667f959a542111531793bcbb2093483666bfe40147cb779f8f2be489ee2c4065f72eb30404d003e540a15006c000faafc6bbc5af924015ad264f50345504b88a87ba3d8cfef7ea48354d231b235ddcdbf5d58677bd83180a3bc0f67fceb3711ff9a875aa4e26187d6ce4d8f4d73810eb2fac21000432a0ff5da831c582f27b6b6a569e9432a218615d3f62231768ceeeede4cf817179ca9e02c7b293f831da519cd01675f3bf919a5dbcd9efec8938ea20fbb1a72c0f425879d174904f973e745eebc68e1d2877b4c2d21e50db200330413fb0d9ddd86a899e1e919761c7a9608a20303f9300f4e563f48974124fb209608a203431880c8d33c7820ceb2e3f9eee52159d240a321843e47f47ac031165ba592522ee1010f1231c6e357ca21e48be1448c252d31155a40821bbb3b014a90932e48e30cce78ddf0acc272fec1a118cfbb9c18948c4c0efef9a3bcfcb82f0e1b0e31e54ee00b071da6130b3ff7aa86f434bcd5226c8643f167a725b1a6973e31e55340947f15ac2bb07f16402d38e3edb3aa2b6b6b74363eebc0feb5086b0088e10e0967e4bbb832ac025f3805f6efbcc361246a90c8f138c454cded558e95c52b1f7a1797ef518fc3e53f98ee511fb3a1be16b1dd436c9231a69b61f8d3a33ce8e32698376d464e0fbb0794de8b7c1bca7b7cb5b2c2c2b2e259cc527b7bbb329d4cd757d77b4c0fc4f45ec43fffbedf3e0fdad3474f14e24fc2dc0c030e5fc5c49c3c888a39359678c3381913f327af9d6cade3729b1898cf1fd3428d636204f00e7373adf92f007f6a9904e005c0abf172782f39c8d0c8783b2f38c6788dbbe3311ff52de4364eea099318e603f30ef39f0fcc9f7c60de747309e6250799975e0ccca3aa972bc6f1d3bbb5f45fba1ff49ed5e7e3f29d84c6c5054992152b49cccd3c38e64d5ee6b009a32a463d741b998779d4cda6a7f99397b92e07e637180fdaef433980077f777ef234717c8ce7f226ef72687ea3a1f14cd7013c2e1f3b1a601294488212d845763938be6d0c00f81bdf70e0682c70782dd44e4e2c2f8d05dc31b17f0b4929ebe9e61ec21acbf49b773956ca53f7524a68f291dff190e1bd8f5d0eea662118d572ec2e349f55a494f7f3b2c49f0e8d8fcc2d22f311089b1f8f686872c5344f73f3e8fa4a5eef799cbd47ca3c842999db827d9723e3ad58695ee67dc0bc3f8495e6666b6572c9f452c67819b775392f26d389e88b5f59f9875dceca6b3dc60f6ceed3df78f6a6c69d0fde4591c2caafeee3487e645e5e57e2363017e673097fa80f7ea7a7d7932839fdfd51c2721bd3355522acc92463503027fb26cf595e966f5faa6cf7a60762baaee4a77b88b3fb6c91db6070f5a4bf4edd9b865e435bbc4cdee9f4ddedbaee6fdc249ba88b282d954edff84429a527fa2914756160fefb62625c6272099b4a5866150c93f929132323f37d4c0cccdf4418cffe973dea74fa3e7dcacdf44f27effb0d763a3540ff5e7a3011c6b1c9cbd9f7a7ef02a1df7d464b9ec52e1a347591fceeddf479e765ebbc2ef28fa88895df7d6ea21ae405d27d7f71f2a47fff5b732b2bd17a127b1ec49d07f1f5328765f0806840fee34d72264fe6d27b2613c7f2266f031cd6f1019b6ef6019b7e85e5dfe4651fb07c5c717c855d0e8e15d94458be788dbb0734ee4c27d37f2ff3124f178ec5abdda7a43cc63d0d7d9a0dfbd1672420dfc3fcf7a7979ea9fbd3e935226f09b5bc893b413dcc7f1e8ad260fa4edfe93be5c7a7efb6c83ccccd2d35c4fc07f3f266f95f0e18e621ce01cb3fe598a7e1996460feab21e6517fb2a7cf259c1f9f6e8bccf51173a17fdfa3be9f5e8e798b3d0afbd3f7a69ff179a8d3e7a160bcfc3dea6a2cfbdd9d9719a70b047bd405a2fd29c6db79f94c6f9f94757fd2b6d3cda32cab34f469288de9379347737ad34743737a13a5f94a43c303fe6eae0f3b1edd6769e2682ef7957b1a8fc6446332d17c7d138d8986e62b0a6cf6f7fbb6f8e85e7e87619f9241ec53ba4f49790ce6661e0cf39f975ff0f7272fe7804fa62b1fe582a50b36c9c85cd4c778d03fd4454d93e9e5bc312fe341ff622eca83fec5c4dc5cb1e966ed4f8ffa1c1e7414ead2ffec9f3c1aaf79f4613c0f34ce3efbee68e83e25e566ec33e752bc8c6d3176354498c6de0b36bd773ee4436cf2327d96477940b07781f9cc87bc2ffe6d300f738160df6d2f18bb71c5b398c683386508ce299f615e3e8bcd01db47753975e7057ba071f737eea306eede7ad03e0cbf49affac7f2b5882dbd7c96875d0da507226ff58f85eb96dbe0b8b9318ef7d2975ee27896df7078ddf20fc7ebe0d0690c80db430ecbcdc171bbe5795b8c27f330764fb379f5633c99a7f13287694c7f3a992ef44fe637939723febe9f6ff26e7ce381ba59e64fa65363f92699c76495d5244d2ff3d2cba6ebc32731ea27c79d6c3cd05862d3e99a6e962f03b10c22045794ec7264643c89a507a19b6edee1b074c9cf2de4c4b9b6d97b97c3fdf7a6979ee93767b90deaf363e9a7779f93d74eb0a7cfee83e43acb5bd2bacccd259a47ddfcd83f9a97d937f771dee7e5c83ce77913ff5a5beb608f92b9b9b1ccfb27e3ad7a02db584647c66b8cfa1bcfb287df9f4e9ef4b2102cbf63cce7a1bc2cb1bca8bf89db7cedbbcb4179da635ef641ca8fb99acc3b3e3dea4d5eaed8942596df12a4f177a17fa66fcc8365cc4b4f43794186e0fa325e90c6f5ebdf38c4f36bf5dc87a6d4799c5047128a2929f3317ccc6f2d1323c3d2398007cbfcc6a504f0a88fe1510f03ea6930d4cd8e511ff3272f577c7ae9994c2693290bc1a62fc7e752cd67fb3df49400febb39076c3a7dc6019b5e005e00bc1aef269ebc185e7a348f1a824b6ff2f28761f847cdc7bc200d030cf2969ee505979ea5a3c125088c28e0d2f7bdc9cb129b4c7f134d5ef6c1f1e963407da78f79e965dbd26b8ed874f3e9512f63f89307718c1744082efd0c1271c9ca5c1f1c97fec6379457fd1bb97439a56f2b4b013e4ce0b6d8d3c8e4b4c48738342f13572d2843c6ebdac303e94584aa688f0ac368119c8153e04c59451d8b05a8fba1acc62d970b8ba214ad22bb02fbe71938d3a22c3265751d0b93d2d5564a19bdf0a763d422e00e5889404191130c2144cc4cadb5d65a6328a594529a83524a29a594c6a3f533a554c60bdcf304432f57df40155390561f8f366575588bd50dc5144d47540477a400a6e80c5c80bdce007b122ab01d6551165cf5c0d69e1a742eb7811f89c88e05638cf4694be6b3fcd90319af024594bc3e6a8d8262e5019cf11fb53a57e78a281f058d5ad11b2d190561bfa378474b4645b84644a0a0c809861002ee80b85a578c3732c128885109464446408c48301a4157c617c818c30b5de002dc82185a80928530c0803ba0d715d555e7414b3c25592a95ca0b1cff8733d4a0cee18f9530e805ee58dd4f07d4b12a100fe00eca059ce9014c7594a09e01fb1a26ed1a0212e8ab73f8d7152de9a8f95c7d30a5f2eb0a4ae1a552a94680033112b7814caa1005bb2b09f6da83bd1ac15e7db05716f6283b16c6c26d3c0b0cc35ec731e678066147ab98a24411155394c5627545ac12ecbaa222b7c16a10762c7b88e953286e03e91895484f912e4a4b76bb22dc41e9c6f0cfeb114bb9803b3028708688be7a06aca873f8cb20ea1a12c22e5b42b55a9b4bd162495427b0d31d607f3a0388f24902db15d12e8c4ec5bc0791e3731d82e6732501f6879d92f94cbb80fde90c602ae6525544b1e08ecee1b3039a4b9d90b93409ec5db4308d1284fd29143a064e4255ac29840c4d8e98981cab168d0c86f9eb8aa72aaaa2aa9a2bc3a5c911f32e6f2ee1991899db2cec2fc3cbd0e4787f2c26c7ccd3c8c4bc0c1e16a55bb48816c9bcd3603707cdcc25d2402db8424686984b936015c36ac56ac56ac5b08ab52ba664787f5a0520ec61c8a40a45b094e1d2222d58ec332dc23e2f65f9a7427ffcf3263653d6e8f579089428b905421214bbbacde8ddf4f002c827b210b69cf30913c3a277b30a013eb79957be8ef9e29fac79c266f8da322077709bf61dea8edb64c06de6cddbfbd3cf5efecb277fcbb21d9598ea5e7e8f1f9b251971c4a87bee7590526e37cfb0733e69fe68460ba48312d8f952ca8c01fec96f3bb7adc78d7fb224e7ec66802403a2b4801385154a96086c71770922ae8aa209f8468995ef9813e35bc6886118866155898518d61bd8961b3821403c382d376cdffd4454b7146cfecdab4a58ac2661fde5938080c470424b0c305e89db48259dab15450aac45d443e42f1a0cb9c4c0c2682b8a2fa023bc50593438a2daea54014539810dc96a4d1105091488088ca099a9a0b0156de10746c50aea80a84082094da460aa589404ca6b055390585c473c7155b97a11415d538c9164884e96546541450db8f0044b6a154d51c6164a5054492e1511dcaa0b23aa0cf7538cd2c8a29262b4dcd522c2f6da021484569a46cc5d5834866158fc719bc6700fc58f5e34e25f472518fdbc8a3ed8d7106f04f2af1f0876a38f91f8e383b832127d30cc5d8d3fa636ae7b1deeb2c2129c510e34860084a816fa994ec5dadf38d62f71e55fe78804f76734cb6a6cc51fdcdd2d045d598d3f6e933d4a04729b1c83a292f84323ab7a2e5d341293b80d7691d8be63b7cabffe7e8fe2363ff4728dba1774c16dcf752312690414032a3aae1b91be67908834cb055d8cbaeddd72f72ec17dff1753dd8fbe0adc71dbdda6b765158cfd76f3ab607f39e42e20eb3a34b0d8e7c7647c0c6219254e4b730244b1f98831469528dfa39c9d6118ddbdbb2261bbe58d2f258f7908f61f36a2e0b3e08c73226cae250804bc6196f2d41ad82dc390b0190ac9959627572b84d73915c7794edfe213db1509ebb78547630867f0c53c788b2d3ee03b86b722612107a50f06216cf7615a9fd86ba8fb004d610b7b8cb1bbc5068883bd10d8c201c17c10603f034339b1eb5ef2ce5aaa7ff1082d3fb08a1b7b2d3eba638c17c987bd7f4705b7fbb7cf79850cc169d7709db8ba17719db74614cc38f7b2570cef0ee7f520f14e494e958a379835d4fc29f69b3b80fb4ac79144fa179bebeeeeee964050878e9a9aeffb97b262466c7f8d1e8ca85881a4c703482965e9bfaa623b461c63edeeeed9d5c0a179c33892dd2d8325129b6be5ac4ac9a525c28778aeda87f5438ba2a830f8229a92be9407c0705e296fe4c0e16df121a38c31fab460eeb5c889cd5ae517feeda3a594de947ed30b23eac6db47bfdf0c9d24913e7787c32daea5f1bc3b1c86fee159a4f48ad1a7ec2ae017fffbe4f4ee89a8f8f3cae0dc3ef3fef0b62ee18fbfc1bf082d0e2ad8194086129b040944f9cb979eab60a78181b84a09277e97b0905d82f341a2f203071d626afbe8ee8233448c73b8a385860cfbb7f0a0d83b80e743222ae091aa65ab806411ce3dda1fecfec2f1095162f93a124bb863f2a881e79574f234865549e9adf2e68aab0d5a104583200ae25c6d2a03c8008228f8c3bf58c2d2060622ef8f1baa98b506b6ffc61b89db94301940fd83e35639d83368b891b0fc8b323a86d149a98c4e1b52ac1bf947d9f4fb6ab09b6bfeafbb7f4d30c47e732ff9115171c209279c357d71f8e15f948f0387e702ba18821fc4b92ea00b1744c1c7ee0f1c6ee0f07c20f3e270837ff15df6c70d9e822e9ce8eac2c5390ef62c5888e5ad7308202fa0349cc103af7110ee80387f18da12fc0fd265d46ce2a85214639331a28b053877925a44051838c0b9817a49b75aa89de09eee3438f6d771ec55b57130a65c8503fff3c932183eea73fbe0ea363a96f8179b04b104c7dbaddb4d74f408f588d8f7e7eee91eec3612ffbcee812d9cf8ee795897d3b97d7088a9ee63161fc3ad54d26e4c499cd8eac691091590e0f88dc46d5831c5831371b2c56058ff1b971d8fc65365a5e405888f396131209bfb6657f9e0f882287fa2a1db33c008bdb3cc47d0f3e60e6079fb853900ac7888dba347cee394d13b4aa7d3b16e4cb12923860d7760d959f437acdf013cdd7026f64bcc83f57461bfc1b7d255f074547c8cc31827bfd2c0e6f9fdf4e78e8afc1d7fffd6423b793d89f28aaa2863b4500b8d118944794589328a31c639b9f99c578a65da6bb1e3388e03b29138aeebb4e6b8fecdb9ce3bed6fecc451f723afbbf33bef22b771dfbd779c463a423a8229115bc4628cf1dd88537749a9479ac4dda5bfec4c29c9c729a5b5d2387abfb9b39c77b8c86ddbe6cf3977c4e8eed0aee3362dbb4754b8ae2b0c6690a4944f3222494948524e120989cca4492d8f1012e94946fa49999444ca14294956bea524d2df78ca68f49264e5b574ce98246bafb597d43f22bd7de959d26df9a423a423a423a423583f24357db558497af8e7007f1ea0607f1f1ce0281742d9dcac259ee40b3702ee080267bc7a8ac2bf3fb86025153c2d0723aa88071decf7c5d7e15bb2d5c214c32ac90793b5c62a6b90c664acde8b7eee3eae32f734d6cd3bf075433b8244baa38c692cdbdd1df8c2343e77f3ce867da6dddcafcf4847484748474847620b33c27f7a7923fde61cf77044bf665eb765111061ed7b441427022eb0f61bb789a0c5c78cdf5e6786085e58fb8ddbb6cdde2c0216d69efb9bebc3f9a31c9ac9efee861e11957d8f88c28133d96bda8d5fd8dbe2637bed75b67bd339b2d7344dcb6e1e72f30e7c9eebff3b0dd44018028067d4d2889e444d28d235d0bd9726f6ffe58b40587e7f8da9897d972836a5b78f60832f39764381fb6f9591732320ee8d722c1b55511555ae8ac402a93f718e2abc7d7d1a7b6291b8f2719b491f765b935675de6ef9175ff31af35aa8e536b2891094d3083949473ac7bc48705719e4760921b14d3f7e0ff5166e93f513b7911f35d291ce91dd5aa38433537a33ac08d3afb9b230bdd8adfeb50bc79f5ed45af3a23dfa0e37ea65afb977fe1bf5ba9cd7b4ceb381d45580748970f6a3bf71ec75baca05ce1eeb6a0b67dd6df1d1fd7c9deec2ce91eb0b673fbbee7520eeeecddaf7c7ef78685f9ff332acf1e0ea5dd291f833fe487a61d01501b03fcbc3e77c5c3f622af2206408138144100a8ca2aa6d5f6e9369cfdc620e75770f35611b531688294b4ef7b522b140e64f9ca16be21cdce63340f2f9a1c30ecef2edb1788f7f5ec41bbde6919e243439cc83c1b39e1ba9471ca95dbdecb320116701a98ca8c4ac35b6452d99aa190100009314002038140c88c4a2c158304d8344f20314000c8faa546c5a95c75112a31843c8184208214000004044646066c200406761cf31f8fc456afb4ec31b7dc83c81220ed890c21e42c371b3a63667b4bb2d317ef2da8269cfdc9edca4a30f9ea4566263b2d612f7f29277fea827a5b16cf752018da3176229dc4ff91a6ae5ce95919b22f16662885fc8458926f16bb981d8de70a8731b8d273c2d1f01ec91ccc87c13e2caf249487853093bc53739b78d1a3adf1f9e3905702208b7e377a1f7b8dd2cbe83b102b0bfa30869e0c36d0d4357f9909db66e44024819c59c22716375f5363d6f98ddfc6f0bf61a1865a2f29de9befaca487de8062ad1d46bb66490fd6f9104cb0c4a2e0e8cd0f81bca38c4c53a6c663c64e6bb3f174403cce357f8d70e6b179ec30a9246330c87bdbc5106762831e70b7a545ac729a6c044ec8a283f55572462fb545587698dd4c59d6d929271870020d92c417af825ab3ebe90d2649f79499a17f423a7483702222749276415b26fce19a1f0a8b0e4103b169036db6369c09ad2151c7a3aa023179afb959c92e2e6f136ecfb00e0f0c7b0b70c8867d83a21afcc5a5ae97eaf26fc955914ae88403b93b15e38a8eb268effd153fac73cfd91158a6b8b93a9dc7ae431fcd2f279d3560338731796d4548e34944e71f6ef3d48ce9dea8ac0f65f10f8b9e8472bcba4d1ea18b8e2e3131728a64329d4ed7cb07397c322283819b0aa1331afb9f902fbdced014debd4ad591026bd2e06a8552816a244f5a041080a613160dca280d6b952168a86842338b7e69e30389c2a79b31346884a4a51c83594467f44009fc772f54e11794335b1a382af6b84aa4018d62fed23e5c2d6a5f8ccfd3266d91c0729ea1fa6d142b25d9a965cb9587a78c236bfde6d166643ed6d7dfab81c0725f963a989f481e29963ff1649244098e3ddb54886e7692a0384e77ba518a680c91be43b78d3317808a190dddfe9248bcc9e547ba9c02d56d7878353acb1b8edafd7835aea89c372c32bf801952e1c4a8e85ad3dce375b6ec251308c35e1479cdaac183450e0ac278b64a833da314c5f668a0ba0d7b7e7baf2f99403030e61d31dc462ac1217d1443a6304bdc0fc3ef688081eaba44956dced5828050a8b6eb9065e4f2bea636201ccc9c86cb9d06079c0cce3de2a521dfa19101c273b2d13b0be0f060e990cae66db0f7e2c6de9c0c6305fcaf381211e7e5787f0177e37c1b51e9c5fd5b2d812780c54b1e2aa87e637f0cf2fddac31d979e53247ee53c44c58f7981973e84271c19452006c26126b18f54060a4d8e4bb0137673440cc3749d82c6a19f59e21ef6a3275946a774fe1489e4487ba2769d5805b9674aba1540ffff8589e2587005febf122ca56145f2518b903fc9c0743b947aba944554e24a11c0425a21545e08267df1d0355b8589ccc76052f6468299090a2b8d5312ad0872b823df662f3f3aee877577d00e810876f31eb0cfb2a15fa89a2fcbb4513f103770479e8b301d69f0ef48836f619d176b95821172e81a79dab4c3425725f00fef1cc6b6f395035bad091b605eb9cb98ad76333c6d26674ddc73b9d8a78476366afc8ff6961547fd3af9e3b7c5348d277b25c1ca2eed5267372badcb05f22817deab04d743c7436ec00b4fd298ae7cbecb46581a93746f52c66969524dd16b9966685188d39df82ada6fef43810ef0db0f57d94886bc088398f4c477b2b0a67a7c18c1049b898fb4dc4348c44276510713bc56af748fe23e39d7dd89fd75fc9f4538e450e10d6ef76090d23ff6f4b5f7c52cb10f9fd14b50ee1c7c108a776329f2c62a25a83a29f8c48067512fd517e1f9f03d41c9148e438316ace3108e02317b04d42e61db8f1b93ab16c6545d396f43d39fcd8a5410694751aaa25200aee79ed81fa3dae0fda51829624b0df91c75650dc9b015da1143f9d906080d303de4320d0591e7a26cb9129dd3f6dbd1a60ae5ef4f25343eb69d8b34d5f21e35fd70b11a8eee41e5cc8976466bdb202fa7452fb148c53a9e34badae007206144b82a14444ae981a0033b6db144259636c62ebab944a8582eb378042f72615acff49fec004597f88b03190fdce48555f887fdc4fe3999a28688627fc383ac0d990a3ac01e99dfef82b16fed267ce6393e3b482d9e5b3b4cebb7e8464b4e3c48a03a451248286f40c8190b7d6adffb7c24592732b4ff88b245000842e386ed789749ac670c200cc8a0b2b52be348e516ac1451032b745e581331e6980954ed605c23168353f64163988d3fa68ec7b376eb1d985238f6539820890013b5a7de9c7d354c8a18c3fe8a9138c01832c48bf0d53c3b93b400bf00fb408c271a302f49dcaf6d9b354ad40e1173e2a20012d9e25fceb823055381f399e9d7b6dbf79e9c17380a621ecbef1d4782e66a855f82c2e021a4a04b2d51048cf64987d50126cfecfa7b3c4d05cb2a8919b8a3f012a66a2d923864598edad5f258488fdf220827a89fa058a0444275b59b6b939f27c89a7bff427c283b186c2248b594e48141d59cd6de7246d4df6811eb9bc4771c57454978797169fbfc2df7580fa33a57e1659ae387de5aa6b474f513ae96669403de24e2818d28f26c79c78f4e7f7b1f602ac9d3a229939500a42a403f46ae0872b4b05a81f0a339de0946c401450a60f56f19a30c30824002962d8f92aaede514eb26fa01299831cdc7ec93487b71077894092843ecbff20b41341dd18db5212e3a177c6c9e808bd60e9d8b36cb7890f3b82627387f131a0a40dc64fd5c12dc3c0f54bd74cb8ecc7f376b1a9411b445055c51f7b5d435b41bcc341e4f68ed0c7bf142b33f019b6b61beeb7063e04d4d4b988d03b1ababf24a2f489d20d8bd0a93e7ccc164fb8008fd0da51ce07c8e5e6ea784d740722341d0df8f826a7672a5d754ba45e47001f6e94a192bc48691fa30c4450683a18fff14d2854670a3e5f36086d07800fa23c1b7d07a67c70c779c24cdf886b8362cbb267a073306094d49714d252b6d98bf27989f318b154b9a4fcdd9ee10713dd22e59f12fd86618565fc07c745c5a81da48a3d3b378e988b8dc2a3bc8dccc89918c46142e5e63723885436e1067c32cd90671c6d116ba34aa06248ba3aa070589cb3d2cd6803976d21ae6df7366374fa6daff4c2b0b629577f7f05610ba041ab5d5a8e47a44ef65223a23e4fec0dabf9c6d9fc486947e44186fc4493f1e5a696bb2b4c162aaacefb148035ec10b6cbb8d95596b4b4265717655a66aa740ea8642af8cfb8d62e8e9ca577acf5843447050d62496b1480a4f05bba10ccd0404e16477ae10956379ce9cabec981228ec30d8e7f176809c6912a02f39a51d6a0339dff7d43c341fde49487045f9ebaeaf88fdb56b5786dcb2cc581f08259241608ab352b094d6111cb57ac40485b15ab253c3ab5ed0798df15024212ac7000fa8f8879000db198db1831be0846d61e5385912445da4c4df4336f7dc2f476f9651a4a2270446353f6053da0926dafe6f543217798d2ba6e0b9abd05be84b30a851162027093456c9146f9b2c01e10f9276bbd5ba70b534cf3465f6a503d91e039f3d009824361563304ad2ea994c4100f4379752622fe5c1580ca7d472372586bfc1bc9b880de9e7b413fdbda9a3e2bf4519d94884cd4597d6d3cc948686491454e8bb4e4d20d8cb560df6cfb2163d1c20ff483ab6b9176afe23d0e915700abe1878a44619719286261c49400324f0832490067a50bab26917940a36396b4d9dfbe2bb1316aa12058f9a0913a3a9c75b81d493dc3c86b15ea2df9a4f2539963ffc7e645e762728310a32bf44368bc4701883f41e3b1ac8c8f479d548e6f84b0acda8a6fe8ac5297298dc84f1d8b090b97eeaa5a3274a13de4c3e2c4ff9dc059f481a986b8392a729c5a53f9f193e9218668cb35a80a61abae04153e3b12c31e3d2a229314f2eff49b77e11291b858acac2e7291a27f913f2a090d06ae05d8404538a144105d605317884c85fa2407b2f6a2334290f5799cc11dadf1a1ca7cdf13738ad41ff91abc968006dc4596a514796750caf761fac62431b1942df7f458df3db7f95b7b7ad63a3816bef92d114a34fac594863b4aaca54dbf87bd4f464db4abefb783c4cd82cb1878658df7c00d60a8f35c27912a2ee33886b66edc0e14810fd787d38923409916778d46475e125b2c8284296b82aedb4c06c4dbd05ec1f019b1636f089f1459ce83e55d0868326eaff422775a10ebb11d0edb90f758c90d0c04b17ba2e27b5877ec3bfc3f68e0d2086f10806903e4989fd2f3ae53eec7d3a15335ceeb283ddd8b154402730cedc80a827557ea807635d45429b99879b9d01d8a97929ad24b2fd0ae564ae4d1e3ee3c621e4a701e8110fbe2a741969ec3dc7ef22353e6434c40b79777ace050a99dfbe3b89fce2c5da9330957a54ae9cc2276c90a5fab57530c68003cc62f0c79c3b928644c7781f2e55d693a42682f929fc914a9257878d58615817bdff61bee2e4957646274c1e414ebb458f1cbba1ad93706777f093ba3443d6123435af6054fd7661408a6a4ccb6c7fffa3bed7536014b48bfffac2ff5bc2ecc81f4a09413957b0e4a3ac58c3177a137a63ae3fe7169afcd771491e9c689aa9ef6c00790f7348295b4c3c7d8dfaac3378b96f09f555b8f4f625e7f243b72bde10f215e60b71f1193eb7414f5ac1f31cc369a5a16ccfeb03f15ee52aa117bd32204d5a38b44161d122a77d4205c3d280408cc6de0741827f82d1e6bbb8a5aeb8c5816c8d8365e3409598df74d6cd069020090937399111c166facb14fad472082d2f395471ca59a4c7d3262c4415835cebb8031866b0c72bc2f0a36bc954da28619df381dcb2f07803455c0fd32be726771613614bda0c51c21450dda2d86848857287fd39de2c75fb4a31360c264bf1cce080c939f498a1a2bdc9a62479f2066d980b47283460c67017af552a2b99f4ddba339e77c930c9085e5b7375288fae5f6c21073f74976a5d188d853df90be0758056d62d5a1da8ff8d62c88f427d7fe0e9bd569fa3d8628d3eab4a5065e38f12e5ffa09bca14dfd5e4231951c5a9241fdae82aa9ecc469524629d64b0b05c0853e8e33580dec6e33ab6a97e238594d87afe0ebc0cc40ec3e582dda1c95d0d43e14dafc5874b3c624fbbf3b0901ff81b5b4b461ab80f28db4dae29061269107a7044de47e4683f34154c2ff6543b084bd57aeada086decaf35144c343a2f19a453b11bbbab43e6a196f6de98bea86bec32bb76eb6552d184d7806f4388a4dd9c87e8ae958fe035d03fb35a905288809da300ae6a7d81a758842a2b30e5f063b2c40ac219feca0c6043bda8c8a80451e4057a41ddf8d72129c852c1c9fb47cc32fb6d60d26a38ac77c16448566f9fdacbfdef22e5937516ce901c0fc846a480c0e6785ac237cb0a7c804c55a46818d9ef964c1c293c2d52626109d1d0d6646551a80df65aed0900a589ab0afc88340e4b8ce4aed4d2af51b5f9a74fc5e4758003e9ea94d43a47c7024fc9b09fd33c8903dec467d4680614a539a7f09b391abaafbe688e19dea12dcc3928b1debe8220c0f0f61d0b2094daa67d7e40bc0f187b5f85a41e24c01346b69b4aec3b1437944a42412768d93f3eee48c0195c49210a153202120c86d57c87f3c200ee3050bbb6b7bc1cbdca4a34ae41cfe5faa44f9826c5bf3b3227bc1d8bfa345cf3f55520784926aa1e2f8d250f317a0f2349775ad3e9bf2295d676f611c9c8ffe7209e155fcee6019cb062222a522173c38567c1f9ef17bae28b4c173171fd14b03f9a9ca229d6dc8000c6ad351062f1551ee078f6b42132649a7f0e881fa686495eb0fa150fb64ce11a8ed8ca2ba6a881472b2a66e6173658e0af6c223f4aac822a2fe24a0b1eddf504e37ee74dabfd0cfd228c54f0dca2a536976e2fa43b8159265927c6004b7b4c5e0c019263902c1f4d43ae66e4ef9933654a4b9f759a72bcab226fc585cccdb508a66bcfa5796ab749e75730bba331a8f26def11f11b454e669befae5170a25da0df04d91d6e891c3e16cd41f29106624ad2c1f47d5ce9f8ad2606fb3148c0e93362be0fcfb584e44ceb68abe10af94e63203b083705ae32e3397075a3bcfd621796bbaaee7c37d6eeb40ce65ad23a8a733c637e1544be3a56a8d942e4c0a85c83c7dd3a5ee07ecf303b82be370435b179a8dd9f0275e1b22f32b19a1a6ef02dc98f6c931b9dc727d9ce581dd61161ef658a490aa5f536a2c79d8469338210115f7c69ddeb7271289a5d83acc149e6c6f2df37879241e2992cf9169fb560d38cc153ca5022e7e43f76730bea4da486027bcda5f6018f2262762a42718953ae4bfa1358390b47582846cb84180d644da64096905489578d5fe97124065785f9667c9091d4574fb3ac62d9ad2a46f654c5781964d0cacb21495ad1abe51e979d4bce928d20458a8b225aded06f335f3b9f481cf6e4317e177f05b49019ae00a914d40383b668fc5a42801d577cb72d0b8e2d0b0deb2fb00806729d2873e007f05833a755018988ff88d91725c6bb5722c112ba09b7c0d3d8014cd9ddd3c8b8666671052665e52b511973841051b27ed1de3a80016fa8c9e40d77998a754b029df505c23b0893024939d833f274b39645a99cf81e40c1067ebf7a750fadbd65e1a98fbc08b78411e3fe23b9f72c55bd1ad9c92012e67d152114c3b0ba05e1cf2ce387ce0b9c271cd65094d54569aeefab6a04a1bb02425af88297b8de2fb7d6c0a67c9b7e0a578d1b7fae5a11a18a070fb5771fb33729353e769e90cf59490c40de7ad0dfdee1ec64b85c1720b23c1d19d74defefa8e591bb9b342b7b4f254b6401c56de8b998b095ab924580a60e55aa19c081fd710a7ab8d9fdd5f7bbbbd2fadd3ceeeb3560c81eea8b68b553cfd260c37ad54a539b599b922e7879646af5cee6164a784e621e01e21f1cf4163fd992f7b8917e7883bc346fc7512910419c6da61a5fe96c49296100fdabe2096351d26be7ab1b63fa6f2890ac94d72164908112d9eee316ef710deb669d08e32e8c7ee760aff05dc57a307e886c28823f2efcc4538ad1e439ed9f88c511ca40d39db7e73436af4827a877b9dffd2589bc536d043be91533ebae2c84f34cb757910e1a89fa4a1513ca1520e13dfe4b6dedf05e91a7a5010298e112abb5b97540e43de5e94615ebfa4e976ad08ea342a310f997badf487b4300ad34f5c8e056cd458136c7c8cda3e8215f3fd773976d5fe64f1af88fd18f223bc2adf8bd8612be5f0a56f800f27fcddedf367a3b83349c4f423865736a971bcafa49f9523222740e374500cb701f8360d914e4b2a5a001eca36136487720a7e2fc45d2e6d6d4da05f32e48ffc0c79a4cf8331dbc8d619d773a42952c267af2297186b085109140e2f41aefbe7aed68e34517235b63863d1294b6816d8b0ec938ef1088d833e3e5b3ca7aa8293231149f7ed7cb45c495fefca3b1636e18f440c892bc8615020a18ea333f0cdb55228bf0df15b4786bf64fb510c86ab6036915b148063cc5d1550fde0d4d5992b4d742fc86d7c1658b43aacccb4c044ba989c9e327e2b6bb7370351107fdd2657973976df28e3bb56fca123a3ac002b803a3e2926b73eaa98954ef24a41cc123864683362b28d5943223a1efb8867b389d9d7a0126b6c0017334489246ddedf9d674fcd1a5f015aad8ab878d7e845d1260552b227ec1db8853d554d6625a99d9a1f3766886db0005b2e5ad1dfe6d044f506f1cc535a956121df648828d657f9a1f4903bcfd6828796de82bc9dcda002eba49ddfd3741d98b40489b17ad9ab81ad7f284ba15d6bc50c2a8385ac4fee102f20543158c6b1875b280868efaa265c59a04e9211249f87093d2c9f3986897489f794dda9a08925cb0c243444f4a939bd75baa4148c260790d8148269b9def32c87bb0b8463e7bad2b623e0c9996005d558eb12f0707fd71fa24cc3dd2b2d68cf4972daed11d7e1629f49e1af11ecf25144fe3c2819e10a238e5fd56286eb7ea97900358d59eeb7e56e6d653b11a89b97550102cae417d1d50a375c25f9434e6d80f0d64ffd6b8fe2e22ec5d4e3c0c5f2df4e3045235f048ccabdcdbaa3c5d6688f4c5190a0a7f96f5a4d3a6c60b7f054037c4d6cdacdd7da268e26b57142be3fc91ab310e399e20a23b2f92c4b23598ed2483c9d44a3552b8d1ccd6280efeb6866425b1764ee9261e6c263e7071943d18882c0c34ec9ec3d614df2aa47ed796ad21f4e7cf7142aeb44e734056772c1d5f19beebd2092bbdfe7e8b9b361b699f75759f13945205d77eb68e1e544e1b78ae656b80fc661586921912e2295387e5097c159b43749d275c6f21a73b65183e0c335401866fb3aa0a01157979cdd5c0eb43ac703ebddd2fa4814b0948139db8b5d62985cf80ec1a89af94ec37b701553960cfd6196236731308c91f950336f221d81ab515439a88b1352a7ef3466f7c9418c5b8e8c7d79351dcc4fee1b1223ada9bac4c35a6a6867115c04bf983682d54b8817cbd38a765c4ad04b835e3469b740ff83987761c27e03f9e1d54ecdd5348b9e81acb952eac84d172f5835849c5c2f344676a29736af22c0f21519f9333d651080210ab2ecf7868d20c613324b25273da8364dab71884341ff3ea9fe2b7d9552db896a78aa56e9e176734fe11fab7f34699a2eae5f65950944b47be3c4beb4c7dd6ba0ad00c8fa1e44e7e6c8e0302e9542101ce113c5422fb8dd136da1865522c4575a22052a541d01ca5d142882fea7fe870bd900c8a8aedcd8c534fbccbde135b997caa38048e215da820353840a849bfe8a2a567626fd8eb66601028dedbb23df972a4392f18a18afca71f5be4de42280a09d47ffd5f110c5295f90c89a59ba7a3bdc7cbfc916e554e9b3b4275f02b0fe0e9d3cf7db202116fcc247d48754720e433bb9e9269b33db3e57995dc0a719a8b135350a4bfaf5c5bc3fe03a6f491e47e4c51633b9821a57c8bfd44a3867ab8b88e3acc424560dc20bb9a015d081d36d4b03d644dc648203358198afe1ac5022b937b11da19c1bbdace81615da2f7e03825cc21848be35c7abcd3c0f9acd18dd4553d06dfd006e85032aa131d985ddc5b3346b8c9a6484ccef8f2f6377fab8c259aa075833e3bbcdb74e2371961952daceb7ff594b9d3ff22deede30c4e0fc03da1c92794e9916072d451093ebe43201fb8fe19e515737bbb078ba735907ad896ba04d74b586af22f85a95a0b9d287ef95b82fc3b111b8b4e989ec3a887bccb42edad6a7c90d9f183a9472e433be3482bdda31d9122507ac8db4f9befb74b6bcb286005cf0f1bf1576ad85aba06e286eef1789a681ed294de4e60f03393045bae78e62b14f6bc2bc4bd3bb170df1564a0ada34885c9ee1afa6a1d5c0912709ebaaa34be3a1a9ab3093bf6f7de549890618cf83bc558bacf5e07a4006e75744cc91a0d14ad8e20d95ffffd50864444e3eaaa8e82a83a727fc16ea3cc79aec2dd12c45119d5d14a498fd65e0eaf23a662d29d8e8041c21f973a5a23037f2f5d3891a4c0fad29a49eeaf5694fd8d5020a242f27640335c443361f7af8bd4212079fa0d1dc52d6a5f804d60297c81b3d88f098f50454f71de0495a922d4f552a81917eb98a42d7774e4f87c775a3a709ba18f02a0e3e8025b897f43981dc31f1de136ef94e88cc0e179c8237d7274349b914985b5303224f78f10e4f68e7456fd0800a8d8fd4d26191d7d4ac3d84a5270f548cfea9c39691bcdfd8947bf0429890acbc24f36050397da4ec101708160c36063511e3852e73b87f5d239ab37b6a801132e0021b32352c475a851c90945329e44c0ce1090518d8eb2e7a4b73220992ec9978e76fc1e96c2342dccdead2e21c49c9030083012643d607e8a788393fd3d5f34c0601fce5bea7f2187124860ff66dadfe417c4cb6df74c1cf7d60194bc0240df749c8d4f57e131b0919150a994bcc928066c4bf39ba5371d97ea517ed73dff90a51c72c537bbb4d2cabfc4caf7101344c34dd2504bf0824d90e63b095cf4b08d6cd5a328294f78bbe63f574df99eefdc2b78801ae0a21a3868d202af1621883e2122d1428e95a6d2eafff7d1f92a3b65fbfe3c7f3b9520f0c3257c448b4ebc305df6571d9fae5120dc4b40670d82b4ff16098492e4f044ec7184a9fc8d498e590b70f24f2a378802e1a5c47562196f8485f505dbd880514a4449db6fc5c38ac79db12b80f8e53cf2d5d27cc35029340a73730024bf71c16215c20a325a5325a85a50080ede45ac89644eea5dfe4cb577068052d37193380d1a6e869c3d94bc13cb44a2f09fa3c36e44cc7a0f254f6511ea4523d32ee380f2125064a9c9c8944ada7d6d143e4cbd61621ebcbef9c96acd1f0581b94db0ca729dab7b53f114007db015e1d25dc98bb05de8703db983470970f07fdfb15811471e85835c12129b39cb5b31f21e021146b5f41bd38339bb0b656826001d0497a430d96cac76fd8b7d42ba52c1ff65078962b6f585a8bfbc7856596ada8c6ed72a516c9313036b6b99964e4105c90482e3381d2c457100f1af5b7d9d781ea2524cb361072dccc81256b94fc15771ad664de5ecb7f7c57904dd14c6471b19b3daee1905d0fecf8aeb81bb076506942883901d8f9f8630caebe50bd5485b3a7d52779cfcf279f6bd26c55072bdbcca49ffb4e97399a6a0bce62225584a716f353913ff9374d64741ce4d036721c932858ba4d7a5862cdb7a865b5a4f93fa14ced89296b717c96faf9c9ceae0d366b587217d11e0f457443d85aaec206fb3205af037c59ce0a805aafbfc248676b62dd09a04ee3fd9e56d95d331e436a7327878e09c5aea9cfc04ba8917378d02db9416e12c3fcca7842822097bcd488909eddeda576a5c62359e39bbeb9f52d4d86fe325b13789cce575f8b1990d6e1ba166edd802db2cfea94b5431c4c2d1bfa4018d0c0ca399eb77388d672d0b8d31a9f70b494e9150569c5b84e10c4fe37726c9049144b29b56a2a0268ae6089152af8a04ce603388fc357149b99b6e30515925a9ec258a1b9420b455d680955f354f23a5b6e920ea4d348ff290013aab8c73093e59f3fe0e0834b440fbb89e8238af9c802e6902ff3213bf3c8b0ee892ce37f67947388c287bfac8b3c0670655c0ddfff2ce02c9762e92103231b785f11a7866fc6024f40704f14494d35f1ad27349d9a136eef21e0c41bfc303ec7349e54d4c5d486e0866a46b48f22d949198918036f2937236dba71baa54596ede0b3aa27be2d9e5c4c590cd4d2aae9059921b24d7318622fd0093d86b451e81f8eee7383123ca7a7ab89206787046c1e065e45bdb7737a9307ec3368a53d928f6bc9762e00ed2af6919f7989dd9f300a9c5166ed8ebc996650fbf497ae417cf0b036f18c777030c9c6659c1b70cd8aa58cc6b32d0c2b2be3379bc340a025e9dcf8f38ef7a7d6101c6d98063852130ac24cefd15e547d8f29b9823bddb5dfd2c33b9508ece36f2b79a2222a91d01dd95ccd87b163d13890234300b2f5e54e40e147e8d8fe13fb4f6fa582640d7229395ba26fbca2493841918cbe1691164eb11fc7aa8a468572e5ab9a873c4360f33c92829dec75f89f5b3ac2e110b51cd25818a006efa0b250581b7998301211b41bc5c919a032480ae05fbdb9fac2488c96e50019c593e697ab748880fa47b5a1242d6979248af5e694394747eb997e8f95d542b51424f34e3a5a6229c4ba61a1ac3b43cb85939b8b8349b5cc70d44b9fa436cf19bb0014f95ea5a5ec3d3dabd1e0998151bd3558a269a27407c26ef4be5669ff20782a13717fd2b64091c056039fa986121e3a384e63144b2e5af656d7b21e6d6c66fca36a75af5ad4825df90691e52788216c6d6afcf890329b0e2adf4f7038f1dce9a9d8c0ae8ad81260917b797f2eaa2f6860339531bfed97897e38ce0c2885c56ee5943ab555911b69a3ac974432a42e725a2340ec22cd9c9fcbf3520327cfe4b63df4494ea7742fd831ce2d04ebf7fab38b86271ac8f5a1a850271ccc5ae58ad8e1a1d7c892987286caccd3d637f63700af539995f215a956c7e1ac19d6a08b17b7f8ec4ed56054f306f86d23ea139f2aab1983f901ace93e6b03631cbc20c64935704cee782187001229c0afc93223d4634721b48a40f366f3209a19e4ae7ee39f253d338339903b9ce706c0ef6b55dc0094d71a86732dd187ce9cba21e184ee53c221bfa382692f048b79ce287f453ed648c630d0f300358d8acc7d186cdc5cfa7817aea6833d97cb714ed8adbca7a3a76d0ac9e6b74d248b6035cc6d022fea11d0c6086c1cdf16d2d626459b1664d883811463aaef97931e26881ab092aeffe8db4dae36a571da9eeec047a3e89e007c9bf12fc7157ebef5c6421c7cc3ddc0de6bb26bd2b28ec0510e3e241db187171589c4e433f7ebc5f14cdd32a1904abb2cd91a11fb8cdb6b7cf0143bf55f31321052f51d1eb2d136806970c5b88dc2e0ac0c7da215bb70d2675ec10ebfcfb9fcc04d5c2f9bf08fe6d44dad12050deb121a09413dde46a2b76089f28b30ffc55524f0cf2673ec023c539148f69952c3e1df4712c6747caba0f769de919fa75d14d978b2831bdac332c00b79ef64ce7c43d4a339d2db96d24ee80245873073dcbe77f2cc4cc66e22773d96bd9edb21db70c35ece1d6dab9fb2c200bb0a297f6b93cbca07308a73cc274746e89cd17bbc4b7aae085756c661da57f5f6a537037dea5fd4ebeecd88a8d868a52564a8f25ad19fc4e7bbd871a04d4f5a6391a05e1d1fbe4556db0616f28344df62a55b4a43b58d23b855419730dd895c6f31f00a2eda2849f142998bf8a8c935f19d608a34574365b28f669d7ec9ec426a89f0f141c6ef7c23d0b7cef8e4cf5154d02016d492ae9466a33516608f811c3cd769735d4e3e037a67bf24a25573a760691083d242b750505dbb6d75e727f78b090c8726aef97b1359cb526b8c14b642b913c1c50101151131f53b42e46b6f236d942d093af06fe16518390e950499b8b78b6f503d8c607aed5d5288c9b3350731babd781c6ff74e169de1c90279ecf07f396648ecf432f0920a303a811606a01ec0d108110c16825097db7ed026bdef4dccadac462566b6af788194ae05b0af7efe070110b219b5fd68729005fbbf5c638ec80259234b4d77fd228f03b0dd2992b877f74895948f7668a1121ac11e062aec38cb764005ecea0ca3162876e8d926948293d72b99387f698c1fc0a316e62483954607a2f376267c1a348d6d24b8ec6b178ce36298c55cbc7641c0b36bb0ed9bf15309dd71a40e057116116b20c5d57d672c6c238122e4cbaacd2f18f0721c396c688676b4f7f09a62f59efb5fecad37234fcd4c9e53d79ee95ec4061251ad049cde01e751af2435456cc2bf95147d9e3995db45f54bca4a1e93444c3960e6ad2f88b9ef15b2d1b372e5ad3dcbd0b0a622602b55b36159f0e0766f365fa955bf9b3e93f84b6728b14b75a2bcbd35f6809ba2624c3ea75df634b0aae76aaa8018739b503b09ea04e988eb6504045c0cc031b367d7702728e1483fb305921858d8118d500958c85c00203b3381425700e1dc964672b0491e13018e9ea5cc8b8e93c82d107bbf2b4cd09b869b6f8d4017c9a5fa4e603cdbcb715826789375fbf8072ba8a3544d4c6e1a5089c21e043687c54f65d73c483b61c1ba5188ceec744c08461563563921227ee778acde251a764baace003b226f3a1b003378b9db23f11148853ed1dd44ec41b11c5f54d1911b53dc32986222c0f9b46426212619ae4fea1e529662bb2aaf13a88dab7eadbe2378b16b6de2a81dd7aae6df630c9bd9fa01e38ceb6424a85c518b5533bb908a6b53fb52bebaf4a59f284b138b593bdabdd26c52c798ced308a84e1c2e4530964d83553e5ff32bb828b16bb6c65ea8f578a24c6a8cdae2b612fad9018657645fc7d30ab3c9c2fbf58515ac00ace25f08f003ecd5955c491cc2b2198018594bcf482b349716b4b03cacc2fba37783563144b8e89bed56fb14d9e1a9290f329021e59b1dae9658ee53ec18b06f4ddf5828ee0261b7be0f59aa8a17e55a31b1da9072c6157719fc970d997f8e22d1803a9ba459df391029ba1a53519e0e6397ef11af6530a6ad082e415e4effb6d21c62e9086547f6c00d40fbe8d6d8bd1088ec69da1210d09a28b10efa77d59db0f628fc0a9ad39b0ab82226368ee5ed14056f9f6d63417ea63d7c209e1c4701157855772d5969fa3a600c89f2f610969ada3f2b2dc7640340fc4457182d24f981f8f305e0050c8c1a51ba19b8affca88ab15565a386ca53856bfeda5f53fad1ba2cc9c7a4e533e57b43a41aca246b2232d911e0b842598f3cb0dd20c55e62854022167d2db8c5a29973e4a3f355506df21385c1f3d5b2e4179fad5be1c8f84e64dcc5d5ddbf3bb1fb2d8e636a2b4a4cbbafc8ec3449ae476daeb22c2861b71e1202b4ecc4a8bbe2c1be99cc2851393e8accb835db27180e0de1ea9b3aff5d5b93a11e9c78a6ebb8461a52952e3bb1aafdf6f0ad99d84233b0811bf84297fdd8c88aa64cc31e4e705505d93b5ebcd84b9e93c0d9bad9fd028e0ee2dece3c7a44f7b21b968a2cea92289f9efefab7a7675f5cce524400a7e5a4b6ad88cca4afb2ea97dfc0c4a690c3d8fedae75a7168618458f0b400b678fe831560ebd017c2c5ab0f1a8cc2d96192b3c0faf1e0bb0612f022d7d13e1067741fa63bbe904d2a7fe708672f79b910f3a991c7f4183e1817613f269c7c5dbab4081ee2440dd1888b7247b1db2b642c488381298b33c118f7b5a431802f04b91d8fec19e6c96371a3160bd78443b6cc9a2afc17d52cff65b472cafd93d553acee96e42aa8464a43c1c2753bc85e91cb5b91323df251993e53988835321002f802d1f48a12d4ad4046a426e724a60ad4509f4453207e863b3d42026f2ec18cedeee4b606b353843fd13703a5626b32f1c3543a66b9e0e4ad6b531a94a828d509278048a0b18837e9439773dfe29f4d3c9c69edb59b273993d3ea160dc92ac75dcc32caa39d12cd1008c5a870fc02c46777471d613e173a320c09c8316c340ebef1d976d364863410c44878fdfa737d1582454dfd051c07eb7a289988f795858bd890293234276c918921be8833fdcd57e15f94a0940f8e4fc9ade4ca9c018cd9a17289aa78ae414a5fba894d1557988959e6245d51a15757e32a02a93c0ec7a1a30ed9f1638797a57c1c1094090e7fb7a04a0793f83c3cc5117d400394e30c9e08a29bd30814e21afc2de8c903237cc8368ba63df8885e2a79907534028bad1591d13f0f242ee9f113c370108623cfceee83011e6f9b958bdeb192062b0ddceeba438f14dd4f5905c7a04b056ae81db495034a77295be2918a1fe54f8c59fc562b5f715bc095bf37460e4c7c5b7147abe62c9183e721caed839a42ffa8599ce4388e1b4db682feab6724728b2d73f0e854bc66051c3035b4ad441c1521655b205fb805f3595a0a111ff474458067b6a67f090d5190c1d71cf3ad87c32f5fafe138c5a7b6e810fcb9d8002018258c5d1cc55b307a70dbaccf2d42a2b48e7cc5aed077c9732c3b97a8b6332fed5e1a0cbf3eb5a07707a8b73e80876cdf42d51e99891a8c656d6abe9b74cece280fe5dbe7238231d2f0bd47388baa1ddfa850b51416af29f83526c1b2fb10deb73383ece6ae89c9e523ed0c8053d3e124d2867e45c61cf681f20ac562d09ad31b3c3f2a949f1b3d5866addb151ebb107a04d4f87e3142b1e9af4372d204eac7e5933129739f2e422a6a25494419cae05d64a5827e3c6f1e87ebc669a3be52c2db0636424081308365e5d2502414058503406aab6c3af125c9e92aa2d1ab6128b164b5c05d7cc285ba8f5e204d27d4623a38c8ca06310c89fb252bad8676c61f7481d8fe619821cba3a56ccddd8e0436c74e9ea335a552975bd05ab7262ad1b263ca7e1dbd5df841ffdda97300f11d3dd996520b877502aa7413da67752a0b8989a20483ea46b849cf209cb997b365e7c387f7e935149a4af32c2ef5d68cbed9657187a3f7aa2ba0edbb787c33a6c6a84988beccd3ba046b2fb9b3f7974f8a8d800303e6eab0b57e5ab3c49b8fc22c32b072159cae3ac04242d2d8fd9f252587506e058f8f68d057e01d9aaf9388e1e3d5070b6672cf979c64b81c5e4b6770083dcb831dc6049b86197b915b27994dc404c626b8b656c8fb99b48b15fc038ecc2708984dcd566c935eaa4969c74200463357bc13ee0ee15aefe2ca2d61e4060231a0036458256315c368ef137d57a8d446ee01afb8de8a346e18c19e67f193ef937cd0ab8f1fef0f2e7bf4ca2b97f6a894d400c8c1954c441796daf182d3ba121828e0299c1f74012de3b3283aa5329dcc372a0d973f53cf1f24d7f09cb364558686b5a0e1e8815d7cbcde99481a2b5c55427982eae10e391380372121f479afa2277f1adabe96f709482f0be30b18ae4011bc1ae7d2930aa65b55d2d4176540015d25533abef5e15c09ae8db3ee3e9ea52011de3a4e0caf4985b9c38199c1abd0396122664582cf7fec2b77ffa016d8aed292827027bd488c183e503c0059dbfec290657ac44148989b709293cb90e4831bce9284a734ba3a3f28950a4964a866065c3e20f8c316c9ad140dfab318280fa90b256a23493ac363a640d812285bf753c917aad09161bbde23118b0c56552c357fcd1c9010986379c11044ca24fdd536a90489c19750882c9c02693b98fe9d8a6348969161fc0ae0384514c29cd691862e94981656c9896e96e6797b6b809ff2145a55c6f61adffc69e25f84df419512f5c2ff8e8fbbf82ff084997752e306ece61fd510741d2ac4f6c100a106e8791d7f3ccb2ad8363fbfc4668d3cf8172788ce81d3863a219d567831b66a3220d08754d8551038e3ed98401efa79c6c6efa19569fd3b00ab8657d68b290f8e1ab254f6b30cbd1ef5d8c8e0bf02115564a4d76bb28200c6be2f535b9d2374c55bc00497cbf966732b33157530ee7df8403f689903d3275f8c6c4e81ce9593187a132b4faae9e5869849d51340141ed4989249bd2bf6d8b66a389e9fc4f93ba09b13442c36f105e2062a228053fa6e90d78dc168f9998510294517659127328435ff39b1d1323eeee45fd6523f1751886c44168579fee9e3fe8957705f24f6c25a7e562caa54e353e4e64a78a514ffbb88b144a62c9da35cca0816d59ed23f5b2f0c80975383079cd23593be51e0d7713559ccbc724da52216550b8aa96266eac0e9c04e6f9d5d28cc888982f5e5890b7a0ec75b59ec293570cc8fac37d1c82d10f767cc973468e7fdc2cd60c4115ca572a1ea68a580ce0680c9c69b24495241148ab88555d392559a7db7a228983c6e5f40200bd5a1a899ce9d5a27029143a8c81802318c01374afd134db4a0591ac94e56c5b0ca28a5877c89322a970f3051544aa229601b534b56b2ba7a35fa678ca3030f205604662f03649009c4c737f2ee18c38bc8c8fe3b7595c95fe59c7ebfa8fabd893f84854f575e48a1db10cfc332243792b55fe041bc45e66f4889875f497bcae2bac9bd6d9cb354135849faa45ec5e8666f844e51a255265ea5650ac7e5fcd06bd0d6d1ef724669ec8ab5dbc954e0011dff5b58377ea61927c090d6259cbe6355e5e65a73705dc0fdfa933a2659eb532fdf634f850c488f3140ba6ec158b2e333bd580cdcd8e1515775d5d222d913cadc673bfdc35638a0c466628ad4eed39afc0085de7787f8ac4583767d82305928776ff96aff2474e1a97616e4ad33f190982201504fb008d5c82fe9df0cd968ff63355f58ab2019ab82800f655eaaf167d8dc42733bd35aabbcf245eea6e509c9827753da85080c6a7b37727d52923d2845c71a3008cc7d0de78bebc3ffb1ea21b2834e275191d1011cea60ae20dcb5977d7833791991fb2516cee3b1387760a29e1081a699835c889a4d46284f48462d62d8c2b5361d75015b0f6aa572fa181942354e19b5a3a8c73dd585c174959345da87b25a607f986155a67b071f638277a2422b08edba75b7a6fdcf2453ef09e991b764c2fed999320f4aff92f9eb850c9c9ca76e0077b28e14fc4e27db9d76eff5c1d5907001b462c22969bd6f701d721f2e524abd50332189cd51d1271d2380446a108ce0cfb28adb356889d379192683205e50c848d28e85c0b6b3fe890a2d4a9d1224b5b250d85fc83629fd6985c7c57a062dc083a14cd2c17e4b339a7fb53da4de6ad62717b885866a5d2c91b5f1a5133afab07dd27a5bc25160d9a39143de8a5d2d4ada030b34b86f56ed22ab28c2609c2c0597a762b6e1fad5ad0a96bb106c623d3b6a810405695cfe182600053cc7bb54397dd1e05bf2ea09494f46f66ad811a2f3803cee44448056357230965ef6eb8718e155b533e41c4d0a201a85639c0aa1538d7b519503c09be0549cf44ab9abf9256d01eed1d26c2f9f21497fd36d4418c24224b3bc7da28bb8b70505ae121df68506833c9911dbed62c833ac7ba4ccc1a5f18d54f3dbf5682fc97dfe194fb41cb2d9fe5ebeb6a91bf12a10c4eedab85d8a092fcf527bd5ebc282063ccc0e529867a259fab4785ddf4d5d80846aeaa8aed9e07bb2dce63f006da1788de2099509a99a7f9207c4ac2999c4a43c15566d4044f84424ef92a0710811f04221840048f431c3ad8438fd2a7ec7d0b110a5520e0ef01bfea36938c9dc910f2803736a344202d47eaa9afcf8c7dcc1cca4b501ceb104699e29c81648be3b8669f27b31f99132d2544ccfff41baf0f10f64d19d9a5fa42d3fce6a6bc50462d34f11103c5273f5d3e8b83483c29960addb997412f9cee4e767a411b8d0583eda7d2687f64dcbc000bcfbc68bfe01d88128ba196bc9661cda8b46e7368a029dfeeaea32ab845e96f1e8ea74585ff3fbe422214e6fa4ae18846854ec5e3d6f1c0d6e7524b8381c1fab9579c8c7f64c88ba893069d49bd2b2449e2588e0cc9ec16a5984f528479291449c2d2ed7791e2db6e2396cbf4e950b818c24b9e2f7cf5f6a93c265885ec09524792e02bf4fd1ea7a46a0006d3934ce7333cd433fdcc2e61a598d95a4131432d91614984d2de348255fcc90730c1729d235761c566df9bdf9e1f647fb7bf103b2e7f9fc8f7ed8c40219a824da0e347ea936cab17829927653393fd8d5dc0326ad10b272847ce1a2a9f91d38e559daff815b588d5a02f59fbd1dbc1c4aaae7a400a4cfe246c045c3fac213d952e9ec872f03b43c6aa3fc02a33e179b2a141403afa0c9b9c66a457a81c1b07b1b548b1f56a2241cd5305cb1d2c5af05487d8fac4771c35f0259ca565d834f291286960bc10121902d14969b72b2e0aca102e6f367d94e99221b8ed301e669444312b70c47fc20ab015547284d1e020427781e42bed5215e81656614f5465fb331899894a939e4190252a5fddcee0bb8bf9f0ccec9c218a7933d923f7b1c025146e418c11c64fb2384640de085dcb78d694cf5120944f45376f44dd235000017a2538a095d1a85435e38ee8b6cd54a241d6428c9e317a94ac7d24d39b9e64d49946e5954c903519901db00ecc0e68192d19b60ebd32154e6dd0506d54d0d081c8ed9a3f31fe5181ac9a7632c29025b32d985ad1388629f43797b6eab9c4881d204a361d5a6058a7558c847636dbaed382ee83b7001715c050279dd69b230edabeb0cfaca651927434f2ce80b2e570535308367cf23b5f1b1f8ea74a8135b43b6b63020f5b07c57eba162258e3785390c901e405ee4714e804e90b4faa917902a93043f0f412fce6d555988380396be07a5484ab67a7d1ada2d38fdd319c4c82d8d0862c0157cb4058f702df8ac66c630fa6ce58eaf28800aadcbb9e83fc47e581f99add5086730e288ae314fb444859f40e4e3c9d91165964c6d4e68aabed3b82d77a12ab50e037ae78d479fe9e403da0253399b7834921979c3b9016c203fcead16afa2d01e877005165f29ce2731aeb0944b0b36987fd1d58220f87c09fb1c75bf47522f7d05fe657f0ead3cc13a2241d486499a7542159b916525a1a49b8e2ea8cb7700d1d5883be4ac481b8b70970d93dbb760e5b6b7cf953b4bf6b1df44e21ee499ef4f30e4ecc162b2e8d17bf3e8155b444416915b455a9c748df6dd6989e5653067cb29ae1fc94a2325d17c5aff6f59d66bbb95be26a408ad159eb63b2bef115b6bdeea724f663914b3562e6f9963179aa4ffe6ca090020d484c115a6c5aa098742ba2d92635e5e8edfb9c83627becc18d01728b3cc4c9ea2fcd3f11391158c61eccc3081d21d164d215ce2e53c23aa2ad14d4799fbe5c5edeb6c4367175c21d9bb780bc7886b29f07f29e78c4a2ccd1c384bcbc9b4b37ff651336972b2c155f38fdaf7f930d630154c0c77db161bec3287d581580f3f6ddda3aee7364c492e9764cbb3748c34357a922a14709c72fdcfb16a7e39b40c0ef9347ba543aa37c7126574802870a593c1a162c40a30be2a60ab26b8137f047f3b9871a0ca213ed6954fc5a83fa211df6f934de5b05d80c15a98b63412c4afdd7c45d454cb272a32509d941945ff6acdc22da21e0094f8275203952a98b5d416a216a3cc035241430928cb88d9201aa8c93c412e97e7612ffad27e4750d2341e9bd5301ecaf0ee607781de4433b257069837747a6366c17044c91c3d3c92fe4feebffb79a3a1a84e53ac7e4657d2c231d41a7b33e8663dc0c1475025b69b52a14d739c968f271ba0217f15877c2f755d7a9e06466f08c8da8197305c341e687cd76fc9e781e7a573b8b76042d59758beb715fcd2b61266a2b5a9a27023c1a546681b459f46ccb8930ae7dbe6a8dca370d9fcb3726c9fdbfbc447846bf5657b8eb286d818100a50fcd821a66ff4eae92da3b096220f0c008182761d9123c3b6c2124ec8409eb12e64283824262cee08f7986614f0710ee853c05899db696291957e68dcaf87feec041c8edefe9bc5038c4d145a413ede6049a9aab1705301f70054c72b2e548237af7496008a29834664c7e08329e7cc03dbda1239a65971d21b0c8613eb238d15dac4d41d017eba71d6d798e86e23006798a7d44490e0a6156c8d11311069164f70ca9ba517ea08889a6b2b286a4b6203e119c004c7bd547977e5e80654187d053d0cb2bcd0f0ec66ed7d82dfa5aea24ea7d66d265404e5acd1a1511cd716b0833f5e4f376c160f2e6b33ec8f73f49509e6d26b503d6fa5fb87f284aa2ff5d5c9cf1cc403705ce5d3e37110dc4359c1adcf128906be86b817d10f1753221f3a61e4cc9110227b0439b52556e6093778ec35e01dd04b321d800ab4eea02160919017b85187f42958215b4535f40a581bd82fd58777c2edb671df60a53e76b0817540ef75ba7c715de8337466c12ec922bdf641fc115b434c96e806aad0209ff13754095b7ad4a94f99512671f3e537c8623ae750c5d9798fc0918616a8fc22dff98efb6ab5300fb0001cd458926cbcc57d80de3977b6689d3529b8a615beee096f9c3544c7d5e6a5946cc53ec1381ffddda9572960db2654aca3e4069c6d973eb99f7ca94d2d62afd593d5bee4cd145e0bd95ba71eb15ad5f69fefe0229b19c3dfec141f6c4e4dc2e171a0bb8502024c0e02eac102d7fe21d01ca4965136dca7ee991a0bc4b33bda410464c843e071206e4bdcc6d5305481b8fa87655cedaa389aaca5282808567c488857c7acd5515aee1a9a9f8b8df8504c8a95c0be48b49eb944a10895ac97860b309a55ec772371aacf0d1e2f0b52220d52b1d74b6ae0e0a147b1227df211b12b4185e6f5a9496f4500dc2010d77a416aa7fcd9e200810f82d0e4f3c727e434c2e7179095e17514489aa4a7f60671720c366b21408261058b152ef982c6f01cb5360707b3898e4c44271240e34787408b53af674eb1153624af87f7f3ab66c89530d029d6e3143a87acca6471de77dcd09a6bf76918778a8c0d5ac48be9f94922207c673e7894ccfbc63bd64b08c2c88cbb33f003d2212203d9217e2a509ae0387a25f075b2a6858460eb65ce9332600b55a1850aa868e3fbebff1eeec4dd16b728a3237075d5328ac262a490242cf759b831efbe95a6c6013d8eb2baf88b6bad06dad5c453b102608bf12f487cce2796aa34c418ef4a024f3f883c2f02db883dd9eaf740f54c88de17e834ac97c7c74f8f882def18d55c64b143a8ac513f284572f6cf254f75934c480c8ccd6da3e78bbed31e5d1e440e0d7b5af4b995f302bca8ed7e44347566ae89e4b3e89bd87d625fce656448a6de43bc5bde275cedd410ba1bdfb426db8d6898d97c83bfa9bcac4bd3a4883c3830151b150b99a0eac50b688584ade388decd5e2d6ec3d1a2096b76500a15c5ecb6cb0296c598b76e1118890c8e7ce670bc6b360a5ebef6749150b085e9d9f487e514175c59eac873bd73534806d86a69a49c78f593d579a1c731982f4ad21cb56db74db828133f40934bd66c6e9d4919798c29410d01eab684d5489ca6d287750bc59eb76a2c4a1b07c28c91d4e7b2c1896eb43272fe958bb8f3ddc3bcbab47ff35efa342e3f0c23d342caf607b403451332f0b5260720317d3879505424a9182f5d88954cc9606a1f98c28354c7c1a2805b0eb3e6b4cb158379c4dd7349ff4cd79e2720bc89ef5ae482bbe4e7be238bc7e0aee464f1a4076822ddf1f845ef2210d1d1bd5adabffb693d3bac7cfc77c0e4292eb4f7f4075262a9717506e292e59a313c577b27217683c5c3192feb6b33cdc282c5dfbabddc0190f172929540b4dc10f3ff6058cb8f66332e64f2e26b6408ac1c35f5036cb0a36e1f1ef032329e278281ff96e5a579333a364c33b3b25c90a97f6e4aa777daa3aa5c6a21cd8a6cf95c697843f21d289a3f2d729009ed0b2620b8b9c5231027d1230b11ae83af7f541cd8b6c3f017afe9ab40759bbf0e480a7526878424baa4cc90f85e5d98f70fab251a6f2a55f2b8b126239acbe50584ddb4c7da0d0ddc832f524b66623de4d68804241124a2970591de716030d4534d68ed1de21982cb72ea40dcb4de268136fc567482402450d018c32fc3a5553902c21a35db0ec122d2bbfbe6e4976b12dc292549374f9d31ec94d5f4d5691c2400bc02e6d508e2f0d21221564bfd4889512dea6b28a37a9dd3934e33fcad8a0470454a0cbf959c20319a9efa15d33ae4d77177eac10436174da1b0ebf6bc9561b71fedd74dc9e377f9945814f3c9ab5e0b7bd8debc4f5901b35da57542fc375a44da505638c2fe5bfef28eac3d78f12ed5834c9558cde38a7f80d67b4734a4b89fa0660cf2885ab264e1d615bb5ed671aef57ce310ca30df7d1c321c16cfcf67f0c4a30d2be6dbee77c8aba26b21c710d30ab6959d2a08a778b12538a395bea1f3f23cb0d51c08be09f5ad18da3eceacd82be0e7120e58e536d0d24980e017e8f88a493f8e06e36479426e2a042bb75a7209314f9ed9933d51a54e88ac1fd6eba75abc2a0d87ad9bcffd3ef86130931676ea004d51819b19e61d3287c126de31ac18082575f3fde88bf1b0c89a241aa22fc2350b30e31980396d3e934d8c9bf73c86aff0e491bb9cd3d68427203f14c4c791b6065772ec483b8fa9346f94db481422a1b8b912b37b8ecb8aef69ed375636858c6b693953f4570d48ade16e63c68b458db117679bcb39cf6ceba420ba70b6cdf867d27acfeb206fc96951728cd1dab52d545a8651e490b2bc42198cc2efac7c360dd6a44ce3385139ac29631a52178025dc43d110e1dc49b442c4078ba019cbb01c0e1224632dda08f0ba2908e73cf96a0f52f779c45886dcfdbdabb24f2a84fcad80a99c7926191debcc28fa720385dfe2284830b422c26da9a7463a07765a6fc0223d4a399f36204e9ce39556576031f06cfc450c3a21ef9db01e72457bda40d58781ccab34164a2e6d63daa3cff28c38425d90e72c234e64ed4d36abd6cfd12dd5df473dbbf2a3d250fb7ace85cbe5762220bb0021f761dd9da8a5c2bc255a39a1dca9d707fb481f4b27ebfa1353d4d85ec7bc85236026d3a405bb1d348976967a9a13de9b5becf554a4d867d0e4aaf483d80baa2ef10d6d6ff15661be9509b401e082fe25f57449b7105c5e98eb3c21331e7c46fb82a2dd7895ee3d56986e02db688504187a835e5fed8b6bdb63a918386934d8954f0f1b556135b4cb8c1692bdfd78272b2fa575a6e8dd4fd7bc9567033628d6758ae9837edf2adf9719641c6885ee76718666be3a6617d30451abb09c95d3e6daaffc8d456a7be03d335ed6efa57782727488d052f2e291d9104c04ac6de7bdff9193b8e272ce2b3119760e32b905fe1daf34f16b33d82a43ea8d1fbc628d0bb30476176078a3072e85049915b83730305f833561c9aa9056df3eecafd8ce48b8e78595e3a06b3c4650b52f84be504679c9861b37c16acde7c6547fac524f0b6ac7cb58ea9b877d6432e60e04c4160c9866fae5e7d492b275dde3285300125e06aae331547023ed28c09dc436c36dabf637105303e63cf04233c15efe509015500147aec5564216b7fbf01547badebcb8cd2bbcec8b58e15f65898ad45448ad867f9c199f8a0f40d212d6a88a595409e3e29858385fdca8f69c3b8a5f7fdd6d4282195d56de7f986ce1eb2291baf061d7787866cd605f35e08cd5102dcd879cb3c0465e1c73b48816d543821b9b3e1f7a607a9970957af43103ddc88024bc3047fe6c8d090951831b6e5799e55310a7419de993c177ad5c482a29b882d9a85c5e23dd8feeaa41988f7e0a2946c6fa65af32893d88827d95346b8c2599a13d4f43cbefd7479c8ef24d1f30311b40a1d54a468bfe2b90318f9308cc65b284317c380d85415b151ac7071c78fdf6201341e2ba2b0f31fb6de37238493824bb6607e22496d14eac20bb1418df5407dea1298a90999c86f5d7ceb8fd2c22d4ffde5dd3175f061ff04006ef7b796d2c421f51eebde51dfe730bdb8fa1972d1b3187d892dda38177b7c91a2e50c8d49ebc4f551c14cf0d08d0fbb5dc123912d06590c3ec26b3191d9db29f8cd5749b690d6e4b4ba2558e5b47d8e7af1e063eceadff41b98930ac46fcb80c6280047776841f36ca53169f8823c00e9ae50b7e54b603d3f78c9ab98916807c81bfde17d8c237fde47ecfb529c993805ea8ec28ef47e4f56c5004641b5c93f551b2cc2c81eae68e41bf19a64e43fa55ac7ad6aa53a8f4910090c97a1005a80263a8942de421a2cf77f644f06920a88a23d04e1632c1fca010316d8dd71bc6f6c3fbdceadb25424841cac1e064a805d80619d6e3cc247590c9538f1751560143038b5a951c2ddc56fde7ba4377515ddf5d67ec98b1c54cb04382b68d84cf788130981195a3cf24341f33a16029f942047ef874feaa97fee5c3124eedcea240d00b2941b7200e0b658ccd2c854b9b8fc412c552edae2f9c93c99693da14b470118d82fa2193f100d6106ae9e0656131e985ff9f9ba7b665073c465e1582703edc8d3a8681de0e37fe90db45f616e42c4151be70cc6f99bde94e8bd7ed16c31ed5dd4eb99bd7c515dde03f8de1d516daa7b23443ac30513fc040b67f74390790930f77b07797fa9d005d22d0410f5f8e490ecaaa6a21ac84ac18ad10ea1524f3e06c4d0a6256b60bc594b28ed6b3c22ad25626451d14446c84c5838707e1ec7ea7611db9e844338592bd3c24006ce13afaf03ccddfc1083e8423b520704e07a9e5e3122c94f043c9f131a20fb986de281d21d3c7517eace743537ef24c352291f69e389da18792e1a7e6a941c866d92887a0e55184514e6456a3047131002680b13de632b2c1d57ef34519385abdc020606c284b828cab113cce3ba2abf32977c58f44e03e2627701931d8dcdd851176f1bc24ffa9a14ce5849b31535450d01c8a2d7f096e627d194c902ec5644232c0eccaf00d09f530958c7a40a2cfee3417cf07885ca9a7e547b577306d8ad79f2609449d60e6b44156fa7d2fcc032ae4282ce1b9526ec38b3556b48751d279de3638b134a0d77f2d01dc8604ed04bac297219a44e24a61f8a159e032f436f53ec013359d453703f35160542a49805ede08344b7573f56476ef529c339d92211fb0ca5d87cfd1869574db04cbd2fbcc23a02e8b213c392989c56a2a7f790376d6a22e80f006082a3d0d8b9e62362386ff1e7b6ab96cbd33d082d38b68ee9cd30faa8da710f6be4e0c4bc3eb4b005c4584274d25ba2888645b149c2bd1e45337ce4bc75e5156219625fd982b6498d9c2b10d63ae89da2aa35ce6d9b0a70b389674709813cf38d6452f99508c9d13c3698fd5715b04f58ee4eae212f865d6682c67a71549890ff647a89ca97a3a716b2b227dba99d97b94d7404c3013d030d48d1784d69720a6c8a8031639e255f9a6415985e084a1c4f6d34d37ea92ab5924a67d813fc8e2dded595afcb633991beae69726dcfc27a49009331011ea62349bebec0f044c223af381ee2c1bb4b60e32dd0b22b49853e9198d54c58abeb79b17845f04bc5866533fc786c4f6e6e2c07246869c115d1a240508e23b1b22ae5078dfb60ae90189337cf783c928a5b01521534912124bc2335fa8571568cbafe062d9fdd319089a5669c9eaa60271a3129afdb31db6db6d5168ca3aef8f1083c9b4d6ef9030ffaf12d8c613684bdba63c36717c57a8097888f43020d36c010c2a64738fa1a6b7d921f2057c3985e162bfae8d51da6a6f4690bc5240e2da68e9d3f4d0aa8d6a31896b2d2f042c80bb1ce3483c4490caef46c91f1cd037d33ba196063e3c40283c1a1514fbd6015f9cfb24568c3286cdfe155dc31ac0ad5fee01b5c12a66bb11dbda9a88207d0fbf5bce4dc14cbb8a83d702b96b118d92acf79deae054a197574032a0a113ab3beca0c02894e297e33e9c961dd10b6659fc01ce583c5a65c79237799de0b101180e19b193ebc70a82dbe1d3b665c5d378339edbc6437b3277145341bbbe57e8e7344535c236990c3ca4b36768b1dbda56cef83a311f931a94d44f21d74334e13e5ec531fd22f7acbd9439b96b39a9ee8b18c6369656ab03000398793adbb6c07a17844490eb4588752ff37f6ce93e4d25fc9b65a3c72325f45c187454ff5abacea7f5e2144246ac016b262ab652f60f683f7181a2025cc878e864b7912d51e9d539911dcdb11fdf07f7ced0f8c58ac3d1a7886a050948dd17dd95efe1b00b31269fc6eaf599068451b5e5888ca74d4623eaf95259a2cdfc1156901363cb7854f9146fc72422a524658c8ce4de40021e0901625a21f5ab7274bc17716655bdfaddecb2dde51a3bb8a90dda4dca8ad0163028030b8f21d2a20343e6278dfff0d424d944249499d37927a1c38c85ff016516b2d43652a38cb9783d976e6206f2ecb85aa3b468cdfc6f17210787e337286d452eb0e210df34ef772e58f5f76bdbfd96e675b4a51ec1ad770bb4dd2f734d4ec26e9b352e047bddddbee663349e6899f76fc3dc1ef36407d5d3a8c4b4300da7cf0b0f8c17538cdce54b6819b4aed54dbcf3811b8c40cec1cf9de800f3588a4622d35efde614eb8db1db899044288a2b4798c1e576231ba627c1c87ff3c94010a0d88b5078968c6c7c5cf5b4f577d5005e33ec1bf5c05fd3d05c6fdacab796892997447b4baeff47d2123ac55ca3a19748b6537dd82436d8f70a545ae93a407ea6bbb06a3c63a89bdf4ede1f856088adb52c4253c45d2d03b801f9317d1e075dead592da4833393dfa307cf067bb1e6a783f52a992129c271fc8ca4a931c89088ee32c4dcf159641f81a65d36c3577a62a2ec8aa4626147eb910cdc04f7fe11d6e2417b516ab3b52f28409aaaea9ee6bf3ae5cf8d7e53c409affe5f148052437f8771174cb2c683bbe45e1a6e6e4519a13506b8a5e52b1a292ef150969c3d9e451d112d988f43a235b3d1eb5256ca7e961102aab19412460e7b0a891e942a4ee63ce64bbbeb0de7cd6e7927d2c11e44288004ebca8000f3ad0ab090a23cc00024bb7f1f4087b2f5d89410d5eb3c9902da879a3e187a2d1e3d63bc7d566db37e0689fa1a93f64b86808e135aae870343d3374fa16c3603644d7a67630a0647ae84825e7f5e986d0de2b7ed8f3d64a2dd0856b27467efe08a3d4b3d734bf7052121a17b25d870cfe9916cd89bb420ee64fe1c448655a24d412da45e34f40e1ac769dffe3bcdf378c169c1c98427f50d01c488d0ace0a10bce1928b229b1d26f7366097a2f83c3ea4d04793e0f803d9e171f681181e2294f8c97abdf88ee69d8a3d886951eac800e283543230f5f0b760bd278ad3a494c0e7990ec73fdf00a5ceeaa7f9c4a61bdf2f9265774d8639281e1ebe00995209ddb219b67aa44b8288ce2d19f185a60b89327a33575822bd93741050959622460ce9cd9ff6e75b36df61274607523049f9341f3826085d051f2da0349da730875b439f5af2810abed696cd80a9bbcce94f715bb20b46deb5559a319198d6a6345377573f45843c28b17c02722a25030d7dbbd84c316cefcaeecd2e8ac6ad780e4d31c756588d7e5e7a7e6c3283752ea6e9be197fc992fc1b57c406800ccc59ed41d63beed2b1a92d4cac44e70583ed0652261d7c09bc1822ec4d63cdd0a4268c0591004d793d8aa200fac040d6434dfdeaa4854a36449a90aea1417ad4279454301a8bcb83bd4aa7fa9e3fb672333cb36d0427150fa8b505cdcbbc4c4e55efc426c1af439334e7568e81e4830ce345402a45c9f4f24544bab37a36cc19f01859169195bd5f4a592791b28be95d5c20ec6e23c6d4282fb734d7b0f4940b8a4b32f85ab2c6fd10029793317d732d0e26fc3e70ca29a241de0ef634315a86d1fa6adc8729a494943051cdb7ada5a7b1cbdf13db14fcd87fb442cf326fd0f09c0cf24ae56cc407c832b3b51fea0a9d7b2a7b0d4900785ea4b1b68f3fa7446227f0d127acb453b4c5e881759c06d6dfcdd261df0d17738ff154a6079b0d505954a20795417d1b5dcd103f7157eca960bc93b3998a1aa82d50d46bbf424b4ce48bf35400c611cea9033cd2c6331887f832b6b77116d41d0a44f7d2d278d88d6d69cd07bf45c0de50b9fd6c3d8c76932e7a2aff43ca21c1b74ab4eda3285b58c90fe9daf8e6e2efadd33a5d4a42f1ced7396d371567517e3ad47bae3741181cc6be064881f49f1c1f6044998a714f817c777d0ee21866ccb3f8440096ccc7e227964e590a5033ca44fb54ecc45778730712534827078031bee591bb27b3dc8c88ee44ed07e61b2992c78388fda855b7264ec809b3b6f419ac50e817304c451f7beab518a4f0e3cc0cf39dca247bff492d933aae25251e78d322bd15559f93cbd14f4db9003a3a871d6054efc8a507642a7a0873ed2106cdf63f8bc92c6b6a62adc246ef645b1e03169e5ec147f85429a31a5f65914ae8624ac6a30d2dadb7d65f13349d5afc7a27188f62be594f5b3cdb99ae516453290761b07e0fcdf09cffcd3884b9f38940d02ca33fbd4eba3b7c386ea24eb0e60d2c1cd28c60ad9891ec0f4a2502d2016a33f9f94965c804e313deb26ef052ea0410ece707b6e0542b97ac2721452851f14ac99d3294dbe0b4beefc295c2731972571223da32f13e1f2d89e91432043b3e1a314d54a1871ce4f991a806301a74cd2e0f4d2e4484e0dc9e054fb325252529b38b1940a997aa4ecac09f2ae93c374a8af60e2a75a48590812509777ac61cc03789b5976dc3a59aea02ccd0367b378145eab39d8c65a21d238fe845a786b818ac8e6f2b06127f08418f798a224fec034e92bb9090919b4316e1dff496b140a84eb1317626856bc348c3b72b148cb10af6076fd4c578b916f5717ddb78c6fdc0658c7b904fa970b21c10160867ff484375cff6615f2dbbf985bcc02a57834bf0df726afd9ad4b08c332a5efb412c8c68f882144fb22cd76096d27b50f1e8ea3210cbc3cbc1e73123ee6176c742aacd8f154d702be5d0345c7094613ce02f04baf0426c3b60e4deefd931846279d26b4461f3958f92933755af25494cb0b6c0464064b47300f5419f7c4140c9a5b3f9362c6a2623106953d8f1187fcb0f53f9c6a1910aff64cd0177579db56fbb537bc25204e2c424135ab1c427fa2047b9f9cbacd883a2b6c21213757377445a78f78dce0121c7ad885e02f8668393e7f373b4a7cd3ef2959dd09a60fe3d838cec0bc26f6551cc7e0680a0247b80e6c26cbf28e48b47db909419cb4bcacb3fa16f4dc06a6924ccbc66db7c0a43c0efc459346effc6aae4e7b3b6ebbd9003041101371bc0a0d3ad3ec274ed3c9fc944ed465b607fabe8161d41feb98e9101ad41700cea5ac2e409697840d2c472c88a10bb199160cc36e90195a692e709ab8d148405ce8ad14c8cb9d496b602edb93b607b2adf9d28202596e51194048ee4b1e37b6342655336d46a83b8c4d5168735fe2db18b861c49ea0142c2a8fca005aa138ca0a30dce2455377337ed42ce7455c0f967f152af123d50ef047aeed401ef1e1d4c984eebc27df506f852ba44a34e52c37665a23a656fe0f7f4605140d206e1082225ab7682d4c92f464756848df9ac827f424a3aeede873041570a5f245b50418e35a846cf448a4d186a011c5e30f3cf54eeed43cf21d19f4cd12debe5e616dd2cdc67e84b87a8ea4128342135c98420ee909fff203bf306bff852c18785e04079816a8ccd9a38057e491adbb6a277c5692c9fe69bee5021dc2fdd1609b0d2101a8b3e26cb87d06304673c3e2726fe5925e1408bfffa5c42b2ea6e8ea1e912ff17b750f6661093724b027e8ff3f7607477ccb6e224ce13547b2cca093c25e05f325621eb8d0aa5074ffe89b150585049506cbd5963b9ed9463649b43218b022fb6d9036b506ba1d9046868ea452c01d2f4c38a6648d156aee70f19e2aca2541837e73edfa95ebac7b9ccf10f718f18b290bf3ea27e9582775b365775ed26cffb9ec3803af25276f5e03f849f3411b69d85c54e643c2dde899cab2daee99b1776608d8af9229a87fe77b4d66af4461631efffb7281c92e20ca9c386f3562425139b17fb509005f76ba66a107e4cf453edd4280080ca1b36ed03104fd870456084f80b7c8a9691654a13d78f31cea54e4d2a3cbc52712e588db00b7068e19568836d47522febfdc1d22ce5763c1e762a8ea44ff27c5f8d1346349c8cda30f991c7fbf9441ba953ec892ee143444cad06ce6ff5c6c417efe95389b7b19e594238d5afea46ec294cdf9b4620b90ee66d8b280774d46fe3e710dd3403013a55b7fc60fccd4ca6e1f47cab11d2d420ee976c47c031fc897be374aef4261276e2058b90c943b5c814e1ef1d90b0cc3f8268742ef992676825ac9e6531eee1b09df37c08694e7618dd064f3f9f4b8f554b9b40c741203bec132f7b040e204cfe31896d60462a9d9f670fbd6b6332cc3277450c2359ccd2243718d2d7bcc5c776368402274285ebedd28080677c526dba77bd855d816373a510be53773f0085ff5d71a4f8aa979027b0386e76f902169a41d20c14a44a90440a7179966d0c2def53da72866d81a812ca69bf541a35c57c021ce0bbd23158056bfc4f2653752d85c105b63c8c74ec92d7b37b2889f6ba96f3300a86a036b8bd2506cf0c39d5203f48ed27c97d0c84a8a614c5b60262e83e4257e1dbade77b84071742d29ccc12e878f266c080b01cadd252123f7ba6458e45dbaf7d9102d3244b468b4bd908c7578b907075f976a6893cbe5d43f288d3741a388a849c5ec3575192a2016a9c9aff1e33f677f6128bec4dc0de64460e8bdeb579c0b050afdce1c88b2f4dc45f91ad0bfe3ed4846650fdd2431708b2af22549803f978fe93ce68a9496cd25c8254aa090d1dfc39c0bf0e5fc997ed14ebf8ef9fc26e83ba796c0249274b9b3600c55bc11dfd7775b2f3ce8bc156b459aaa62f531f02204c8132c0c74e0e4e95e985689acd5a9db6b1af119e2f222207e65a1cefd60b13a138a32b2fbc18f38873b804b1accd269dc8f78b9e2b9d703959515f0da6b0d94dc4267a6639135f9dd608ca02dada7d1b2fbcf8b60689187d32d89686af65aeb0d4a9c5b818c6a10076a5f41e597361764d2f3a53df401f457aa63e9b2d241a825dfa64627ec6b5e53951e6330727e60aa3da75c88ad7b3092410fc6d52aad31717da84c64aa1f25a08e5deaaefd42715d17d61eab0c20d3fa2281d1bddcc2d222e60aa162980b45a5884f2ea60d1eb39024d12d383eb289b21c8064186a832e329b988cc159b13968b635b8efd644c66c3471e773e42bbdaac0d078a7e1892e128053c8423f14581868f26bcfb9249341ed7c0e8602aa4a6442a50f446979b926a5861293e8aa94ed55ad292c957d3c5ec871ad800175d4f30adc80ea7f5d05d43ad993c37d26649918d1ff466d3fa9d16cfb96f75a1696ba908148d7be25e9e401d274385934a50ead42cfdceea9a1bef13f0f7d6f346bdf528b63fc4f7d5c68116c8d62e257b2b8643db2d1dca93157938ad39f34385aece28c370beaec3dad26220c986092ddc794233854c9b3ae590c28447290c36d970e3fc2658de2087f5c437de807c3ba35b9a79fb4ec07c98ecd389ed7e55c3f3e04890ff6dd69917b6edd3cfd7651c47e76ada97005bd0244ec15a8f85067b1646de2f503eb21e564c6a7fc2f92adcd2edaa243b4fb4f59ac0159dd22612534444d9c1041103537ea2edada4d125bdadaa2398c1a41369f332c2c32ebca977c0baf49366e1b1143c0d651e407b1d3f410c6c90721181ee48548874fddae03c73de56234f5e9a95a5097077ac2d4c1365b960a2e07ff53eb2f3b631153f88a32690f245de7cee206c328cb994ef1ea96f47163471945bc8459e7ff7a22cd5c15501baf4cc01991ef2c4070f5581e03ef50cc4106826a1c1d8ff3deb4d3314aea0a48fa47945e185c723993be82d1f554d921bf18b264afb1f0a092039d1f1b746f54aa1a1d88ccf4dba141532152146a26aa511f6c26077cad7d12fe95aa2104006371281e7f57dc7921272ca24dcd97b190e406848ed2b8c6b8d8687a8e6baade6b14e9a29835d989e8db4c6a13b57fb3f9ac72caf6c0969364b26555417b5bba9dd93404135b665f7ef658577ffb270916ac0b27613a52366faf4257a045180d11c7f8ef521609b80f83944e9ab6dd957c6c101d1cafb4f6cec07e93c6c2a61918eddeda10f8c3ac8ddd8099166b20b6e10b3ee1baa793455e6410c4e29b5134dd033cd23c4f4cfe8afa8441add8a21bef087ad756add36c8c8b826a6812c546f7e2f8d9aeb955a88a5ea1c381d25e75752f0d81c3e1a26ba0573a7e12ac53d170a198f2b99bf3c96c5a64fa600315cb36a6136d90b748a51950e2cb9b5a7861a0ef4f4f69e50b0ea4f080f7ba71e1a07a90fa78755d2328cc429e5558d7a609854a5a5b5a3274eea04895301f3a50f1817c279d95225c314af0a188236e2a2270672804c2b69595952a3ae45c49202aac33ee9e5de4e56b286b60b7d558d5a351895a9a333d397700a24a153aad2256a2e800f90a53ee863a7ed1a0d8a068a122107dad624581ce1f0a29a4c60e1a6aa8c0c58f15c4ca143060789f4354681745165161ed783463c157ec508c0ebfb22c4854c9f57f27a3a1c73ea603f3224341a26be4ddf0da9e509b7171ce607ee1b17040c040d5cc72f116039827a08185f057888aa685ee330249078712142d846674a2458585a0c81e3a81a2582acb756c5f89ce5162575095c0a8ab57a06e3f3ffbbf2b1691e4150b005b71cde6d88a0aee1298fab316225b1d2cdd4622a00616511f1f5b268cfa3474e8caf9f20233ef5fb0ec6511991d99dc9766867873827e419e11d5f92312dfb3ae7af448a918d9f89a550c9054d8a79ad68fcf50812022697a397abc7ebc79aa1034b7f59bf2e0f08ac151903d0183bb8246ad0440cb38714e0f4c0c286b932eb8a11085ecf2031c774d89cb6f998e7a7ce1100f685a163740ac86be779d1f10482fc032acca5545f74e3bac187ab99135d3fbe3ad6b446505614682f747f7bb486b28c24c97939a39791fad1eb6537505c631a26300a5a2c805e83f440b8db861f21cc1e19bb5feb5fb5e31d4d83f7e81c9296cf7f3b7e6a20319d5b8b7e19a5e361e61a26145114a0c1eb7370d8e705bc764b9b9bf3ad84488689047bff7841f0af77cd1d44e041755a2efc79144a0590a58130f762bb649bdeda19366ca2163eed835afb6d7209b565dc06782c05bfeb15000729d010583600473676f1aed234c1fadc4b3bc5aa9238ade72619828353a903579997139ea1fa71760264ae2b0db534fa9857aaecedc71ef99f3314563602376028b7cef9c10aa23753dd1b51db85391477665f9c48b408f5be5e0d0032efc2c1f44b669ee8f11c7ea00454f64e8aba43483a82d565fbcd6693ad8e7c6bf665718bb3a9357d8481a678483c8a356ed2b6b41a608071dcf4f52244e25a0492d73f227137302a1322421449837e2d4a3c6f71befdf1461e650649e5547eaf83e026a6d13cd44a69fb811fec74a07dc387a574cb399d16064ebe5d2f51d801fe73f33e9e83e379afc0e48d16ffdb07e6f209ca45bdd34dc853ec2de886f8226aeda21fcc6321e65c015bf7d7bae881dbcab7e32146fea75f2236f70a4c7577c7da098f061c98ce28dbbaf3c0995ca7e13cb1b1441d3611044c140e06bdc1c5a3f36d0f465e9fc0804fb37748589f8129be7997e837bef79b2faa389e34822f243a17a9f156b5f69acf4f521b4b9fc598ebd8138b6043987c67f27c7a6c68e06e74f2ce5b1c537c903f9767d0747ec043b3cb6ec09ea8dd0f3cbf8a54742068fccfc4919809d7c74180032cb56b12d73899b33f4d1dca4b42013fbdf5ea9db04fb42bb50b154de95b7838ed2d4c98dc25b82c03434f6d92652cba9bf728052b238d74811be5a7eebc87a8a52b27b9c83cf17d56fd20db30a62e50f3b53a54ef1087892873083ca39139fafad082233469df0e76eaae6ae6f9b1ac33be74703c2e49e9b7b20e1ea4f011cf2d272a2333db9f9fe28a9a05dd45b10ca0972d7eb7517265649dfc3878150926f04ba1728b12c49ee19f476822b531db3023e226ca918949052092536763de55c2eb44c07f295dbbcb36883808d631278e266338675fada21319cdcb288d7089122ccb223afbf7de15f43b66f80ebe4c1ae9bd0061ee8f1ace4cd9f96c57e4bbff10bff80020f79bc3bf0fbc91d1eac5f709285ad468f1cdca8196d393d07d4ce32b80fd673ffb78d32481a2909022d2714d3555c50258f8c237f7f6ab6d2c04f8286050240ee2f2496018dc915721333f930fe5f0346ceb4c9d8e6ccd13c40c9aceef8e3f596c51454417c964b3e493c08057448419e3695593c8a3dfc707c292e400a41ffd55eb5b9776e84387dae949b124003b167660b91039923bc0179c04d8f1e5ac6ea50ceda02d06093da9e06e3f40ba8558b0a71afd118a092531f6c0d0046be04cca8165f7f945f4cfc09e793943db57ae7015c0b7f8c53f7ee35f91d7293f70f0f665778af5fa31c7132ecc10838fc6e0088c6ed1a2f11dcd8942946abc9274a702a9617c7b6d425b7728a56f12a438b9169086f6b7e3ec8792799da511cb9aed57a4652080d42f0fcb551c1c238e34952fe55d73471d263b942b51fa921eae6af2d20794950af7b702deb1c9e27414252c8037f3a38382017d51cf974190f5776dc44c7c567f0348cef623102ee623f8ee815e569c80dcde28f2883fc0396f1c8e9eb43ab5239366aed73d796b10095050a2593123e9b7c7b7e925c9c0c28e4344f22dd417ad0176f270e1a68c5a9000a8981c652e117b918a6c07e32b6a23b984d093e092521af0ce55e42990a7186504800fa0e03d13150a004db56c45a8f660ee5015c9fb5b81f09a56c43fe3acaad8492d1151920f4c21493518ea3faa1bd3b9f28650bbd56102b595480fc852948a31ccffa8776f74f51ca225a7835f4576e2c7f8df1eb347e3589b9bf48113c05d6513e6d0c065d9bc2249fce6ae887ad88953123bde771f18387520f06953c7caebeca2178e28094dd1483e8a0558201b28201c50a926e430394161593ce7e01778b9c459b96adcfc42a552f5425358104d154c1c27f51d59b14f744a35a05a94ce29c8999618fc0585598b262deeaf6c8068e2a4cfcdc4b5015c0f38698fcd910076bc51b726056a051073dacc0fed889fbd3bd2b73fd3bf2d87009ec1c39aae308f9fdc51924e4886874d1c433d3861b5cad97bbbb3aceddba037ee4a756dda34816551efaa40177e8b3c7668035265272e8e6bfb1af703ddbb024d944f80d7f0c2ede594ae5031b6bb95f21d2e3d5d27d47d8aae54edfb93a1e6398e345b2c0174ce178c750f2288f1bbfb0929ae6f41ae52a8b14a97f54c7e53f6a6bea3f8a4dbd8fca79dca3ac9bc9a326afeda8bc7b7494b52147b594d960c1fb864da5d546537b3514097cc4c6136860dd0a0cc4853cecc2fdfbec1cdb6b9cccbac6b5529795e016b52401c4b1b73391949b8ae3b41b8eaaa55929a0bc622be82b9a28b01d4f030de3765c7e299becf1d0caf2e378e94e9dfc8bf9ca84469cada158147d674d3043ca9017a66b00595e1757ca0c95a6d7f05978d1bd1c4261379a19864dfcba4a7734a08a1920ef39a07b22f335af44dd1e1f956cd4f2fe332b432f162f2e7cae475bc49d8b4778515e08e807a0c734ed01ea7afe1679b12d1a2dfcf65b17fe512a5bb8b20433d118b0e48478a10e1ce405fefc84940f55201e554d3ae9cd3275b7da698477c4f0068c4e3689ce50998763da5e99f812c33f5a1f967e412696aca00380854552ecca88f6af2807ef146b556b86b4aaf35eabf55e1e6fab7cbdbd35b28d10696413b2f7967b07a90f710f730f72e220f833ddb7126995b43b18cb4b96bcd5344d8375fd91af534419910c59be27ce2bca981ace5cc9d75c090104001ed2b3852f5d2e5fdee2e129b778e99c246417dc5920802ec7f8a26ab06caee4f17bb85c2eaac6c5a67bdec31547a4d8aac6281af3f3281c2f2e7f7974a170b4388bb3c03cf05b3cbaa2dcf1f5fbe69818652347c54c74ce31df340de679a3913410c92e37bab0064639bec545e1c077b90be6c1e2f8d1f572513878bcdce5d115bf2350352f6ff116d8a67f5c70ec081641a81a97bffc05dbb40bc6b8c2a61240eb731b89278c28e1260391a39124302177a325fa358132fde23def1fb6f9ee6154b4f11eeadec3151a71258e1b85428fb7c6bd31634f271a95469ca80b799c0c4826f24e3a8eef1c2681e761728fe49dbe9494efe48194049e52524e20e9a54f9cd3538e03049f02a69c07f8d3e904a54445a504e5e494727f3a9df229e5249ec894939ca00997f0e9b1f494e330fd84799c6e7a0ae631a4e6741346491e2a2928a78f287d92d2f29a6e8cb9a22fc9944cf124e533953c1aeb20e87d008b415078a79f3d73fe943ecfbb6cb63c2cf149bc4926e3619b2135254fb98d0ae631840778ef283227d86648cdc9bfdb80dec1146c73c2252794c6a12adb9030ca0810bc87790ca931c128f9935e3ae925cc83c3282342f78e92b82674affbf7ef2738e2f919115d134707c4e14a26a7d164528a9dd7c529e314a15097399e07f7efde45458c9ad888d2bde31852f39d3b0fefa5f318d2b886fb771ea57b97b7a674ef064a82a9d3c7ef064b7ca255741a69159db256d19e0e825ae95a091b67aee85568bfa4cfc943f99353dea9dce86ab9d1b5125d27259d933371a8c43226614322fd111fbf1b26972657762dd7e42bd7c472873020ba6e504fbd931df526ce6ca1e24dcebdc6e4dce3b9d24dd8867be98451b187cbe424052525e5c4c4e4f122d12afa9389b200349d4e2f7d66ebe4b431ca49cac964726366a1276854b74cf61c01a2825271848c24b78c92a759f4724712913b38b33565166c59a6ef6fe5f1a321ca12166350d051afe5a2be725367b9a6cb347013805b5e82661ad40d547f28896f989c01d165721c530e2e939445195ba61b3de54e29a50f6550beb1826f6e52e88732c2e4a8d7981c856d86c4db946ef2886b4c4f611b0ea3e2518f2ed34bd7f3bea3308fd1bfd1bff310ddfb6edc90a0e42a293fa1fce4f18bd347abe835b9b3b92ab937ba7abc660e9e38ada274042a5404601893e412ca08d1bd1f31fa77839349e68a7e74d17bb8bad115dd192abef41eae2054c4282344a28f1e23ae19bd846de847f43634ba46523657148c314b9c624c9f1463e443ef2efae831e62a82378eaee8dab91a457b5135dfbd7f5e6f378c3e4dc45b7b0ecbd43b81507ad456e1c43a35aac5192d089ec218f92a1c95c77cc51687c6a35ec3f1862a592f8fcb837e46d06bafa89a7a6c2faae6469c2b89e3c431d9d4055d7c09e35b2857fc761c7d8979c87e8c21ee12d4342d14c1ed36744aa9dd628c3e3d862ebe84f55587b8549d661f4a9c6c65b20c4a7b0f173857f6a18bb2efe11a03185dd185aae1de2b7b26709706cd95ed9f6c5f5fb29ba78b317e87cc40c85abd36ca6f882df723115c2c42b784f7caf4148ca16b4b00391eaea746b3ea439df77931c6f8e100e72ae2783c7568e7cbbe5a72a7f3be6b384ce5d004e294875f72187b3a0c83230603a46b0447c4b9529d788e983ea89aefa30fcb9db9c211e7eaf2c311bf4f3b57a81acfc37174af87abf3ee611bef236cbf9ad1c82794b27923c232f8345711e5c98baae1b8f770753f33273750eee6699db96aa0896fe8dab98a72470209c93b3acf5a31ca7a997ba8bd2ec4dd1861b6eeba3092f2b6b0aca4502a2927941313534989048e449fd78538bb6935c674c7987e3fc89c4ec81eb2a70c7c6ef084f8129abc64e89523ad020c473e9d36ede6a9441a0363c464ac0555b34563b167aeba67b62ced0169cfc9569fd87f3a81b15cef63adb43d60bd9cf97076b35b18e2c9da36fa694b375a473fb56527f7160ac166bda39fd19156f5e8874ed12a8943caa233f4d3aad1c8a71bfd342bec19239f568d7ea4c4a39f23dfa5ebc3389eeb7b059aab3e4aca8fb2fc70fd8975b12823fa48019c1ff98c8e8c7e6a7d8bbe7b40b4d1c7fc5da2367c438463ae8932d787ebb6bd6e324b1b049ca2f7433fb3255d4c5430c819f51d52829cb184d80a01c166ab7b857c7287aa903bf484dca19d2e369bad6fc4335b1f2e99810f2b196201c0f723f670588348d6968c78727fe4335ba6d75c0175af50f7e2ba57ee1c8680b21541be8317e7e4fadec9bbc40e309b9e004584d137d2ab36c2112974b28e69271a61ce4f9391569d9864a69e0e62e220a89a516892d980e72182ef2046e1e0313a8887a0e2fc6e883ed32699c9d463f299add265252512687acd96293657fdd309044da697c98a569962b3659a82cd42ee9bbe90fba6d86c4597054d31932989c4a620932cf7eb0c8c393495cc664b079425331811a28c1ae425c41605125752cea033883064454264cd0f21cb0bc9f2617d42ee2a40e992794691435a244b588c79a255f2f3ca16b5cbe4d5b5ca0a663e81f39e24b639263eb54a0a30044f1dca4fe949016c2060cfcb38a3f6123b680ef242e1902e7be9b218c773d9c7398faa9719656394eb47b9e2b0470ef2018b67bdd639e869c822cfdb9652969bbe69f74b8c99f701d89f563ee6392ddea93b79a6677ac3e9e24b5832c1578eef3a2484504c86bc204e6cb6c013c455c384d082d8cce621a158b32446d956352d01f8733302b987fa12802eeffd1090904f4827b41392857a425308e520b240590cc5a20ced20502600ce5da387a12be47e880ab200a30721bd74bb4b7b355f49f72e0ee8221d7c4264c556959200cb35cb9a159260b9a75961e9a75928d014a348024eee5722a09166895aed32430ebd504ccb5a0e419cd24fb3c2d16cf47ae9e7952f5df0dd250d11f31231c6a0260ec19706e41e503520e9a26a482fbd846d6accd54de9a3ce678ac2502c143b95ee280db92fb30086a3d9c80c72540639029a8d82a28c111ce20c520e220c524c0eb145da415cf565647cf0c1c505852ac921095692c3d18c3ea4558061282837135609b95f79248c8f46bbe4370412c079d9c81e010c4b3f15a348b0b9a2548021c98704c314974868004b3f253194a68832e84f7300dd904b6890329778660be44a3c0d26992d52121c3008049aadef495e39fa804f88ad529401459c119badd28f15727f0bb9314f152c18cb205e620758fa992d920f29c96c957026cf6c916061e9a7f4f3939b9424376892c3120fbd2822eae53bcfdc69d6082078120d3a048c3126e443f29130fadc256921c690b61057251c933390c2f019d1ae11ae3b21005174f493b04d9dbd874b3e24f9e40ebca3fb83a227bd87cb66343af89a83d86608c535e049d8a6daf86059ee4e82960838028a31fd5119624cdffbf7d1c827ac3ba5124e29c70718d69dd2e896763a88202bba5522c1e66ab64657580b82a753c9c72dc1ea15b95f79e64abbc97d18aceec03e7bbc6024d82cc172c374767832495677e6aa1f5df4062ce594705a55c2c9fdf8c5ef46f7d1c1f7abacf6e47e89244792f324c87d3442b4aae9e341999c4171dd01a3883224ae448831ddaef80db10585624500e9675a9e06010ceb4eeee1ead79f28435659ac38ac2e89c3ea93695822803314d42a7a6bdd89317d298c502afb8931430043924fa827f493fb5e0828f7493e241f92cf89e4d3e1906caee88c0d608f4f6d5587744231bb03a2645ad57dfa030473281343085096c46c75efcb72dd0165b2ba03cab06cba3a5c85d05d433341287971cd4208f55dbd608c3eaac8923262cf38d376b6b4cdda0de847ab32e8a45c0228df6f62b6e29bfeda19658c190b82a71823479bf82c31aa86dac853dcc33571a8ca4a00431beb6e3dbcc81cc515544481872972473f1f4a9fbe6956f8cdb6e207896cd649e3d8f97ddf1473ce693f4b3033a7d3113cdd7c272626e9237f869cfe8a0650e52d179f37bde4b8648934abc51669d6c9edec921ebbf5891e3bc6187a11b18029a8d44cbb7ca67de60a4f6d96fc056f56f4aaaf72b9165f8b73ad906b51d7f2d82229d7fad823ad52c15b900fe9e2d066d269dd0178bc9df0f6aa3a00ed35ab63816ca6bb2529b95be9dad7b53716c79e5c9be39d058facb0a48da7559d63de3e9cdf84b4aaf1a68337229a2469409ab55d617fa401d6ac9398cea49a3c52354dd3b62231660bda4e3f1a3a7110179fe9a056691b11213b2220398c00053e305ed8c00a42b69db6d7de9b15adea6d13d24110e920fab1d0fe08ad90dc0fdd3095c32dc8cabcbb04a5407a67769721f7b7225186cc1a7dd1b4148da4699a36d2344deb344dd36ea38c53d64adad53e0d6b259a8b66af996826ed45d3344dd354ae6934bfb8e0fb169695142a45e5846272726d8c992f2444c1a4bd44fba7bda41dd4de89b48f3ced24ed214dbbbd34c6689fd7c6180d5730054972349282998b1c8da440043980e168e1cb428ce9fbe0c9d1880f1d991c8da04007d307301a49c14f8e4652d0a392a3911408c91b1ca20c7a8d8b315bd6b0e50228f3170b453c323a76e7a1e5f97c60e04e795f06cd96cc5f580b13aaa28b1e91dfe793a50fca5be578fefb44a2be48f4a35927ef8b9e685689e90b327908448e797d0080b02d561040044000b2c6c0700b42d923e916b8f2d0027db29fdcf6c8054dadaaa473f6a1db1b515b2296c716c9010082f53eea2d5610f846fa0021031100016009ce5b1fdd8a7135ed13bd3d0442a4a3f39a2d9114e197b531956ac6be9890dcef822ccb43303c7ea80a65c218229d3ec641a85f8cfaf1a90587279615994ef6413d853f042b722a47280c218752e903ceae968a7a724b1f4a29b560472aa1bce33e1b110d3905cbc418d40f19b50099fbb842a12ef241bd6fe494379853291c229153502a2928148c2a948b7c5074646aa9127d1828a78b8e34eb8482453e2fee4f2719952a4615bdf2478a7c4a44b7a454e5912bfa9fd7ff64b315e7e7d3321f1f9f1180a1c827f7453e221f2a7f44475ad53fd22ad1c41f90561dd95e3d415234eb5f12d14b8423ab011eb46f0810680632d0b62d060f09a50faed892bc7272dbc186c09e000e534a1f60eccc20bf80891fcd16b4059580d36996d6a18dc52f08c67bb8fa5f92d94269186504cc5fbc06e62faefd05b619a2e19a1787816d5ec41cc66d605c3efcc57bb8607e9009808ccc0f3030317766aefa3e5c16803ec4fcf0007c0bc00f32f846fac8e006313ec0b8376e1130bac22d96b31057fd2fe42ec31a62d2a70aa08fcf919fdc1c478a7530ee438ccc4141415b0c8449028917188503e62f8eaaf1e130f7e130187523ce558f170f23d018642e1e3187f1e882f9fc70f88051380cb0079897a05d30efe17a8171da1573a5ce5c8131ae60f0269bab988b92391296f3181f5ec0fcf0fe82c8188e8c0663f8018b78ae3d1419c9fda03a653712c81654edf66a5628d211fd6c37db6b089b354071101851119ed9fa6430f893f5453a2221cd7a5aedf1aee15adfcd0b6e6b00e743ebd59ed9dac0199ebe0a130318d658ee8f087b50db340deba83bb2095034a1ee848298d0937ab45976f4789a81405946267cc9327315477747affadb47639568429482a8a2385eee4ef16d42891d703e8c413b240e4b8e60e6d1e8e0e50822ebca1fb00ea2f328a5b5d25a69ad94569b434ab4aaa5ec6eb78ddafde8555f8e20cae8de9722883242efcb1044195e94f1bdb1cc9902a4af20f8bc5097638f10d53e226cab76348129ed79940d8ec61bf37402c139ebe7761919996d626ac300cecfd3294e8a69abe627858f294729adec9ea1a5899afc5422c624160c310912a02f80d22747971e554e1dc4604730821523e98a2fa1cdc952ca1b637f34a1bd4d6419ea5808c80a7843bf02a6c01b098493230e65704c480e3ba6134b0290dc6f202d24094572b825e988446eb3290397d801e66d0b31a6bf6521c2e887a085020f1053de900094c32d497e02127eb2bcc91d3f1a2969bae79c1c87638c7c17654f2fc6d0679a3bb2b2f9fc7410bd25b94236f534fb9232057e5d7351a35d45dc673a057eef421e7767de362ff40d313b8fbb9d354debbe213a73efbc5aabf7eef3b81010907b6c951d2246552855dfc7bd137131c6440e6fffee4dcb7c6290afdd7c9a25715b2c75a200c34e02d8dd0a01fbb26328ee6b296a90c3f67aadf22296524af9d190d71e2f06ea4ece313fe093238d51deec1030ec984fe542df044f79bbf3de953fa414414fe049b225914fe009da4ea30199e376a597bb6b40660dd09039c8f79acdf579b9eb1810a221e3a3ac5847ddc93447b68cf565ac5bf2e46efb0ab72445e880e197a039ec58eb74ac27b7102b80a1bca1181893b4c46d7fc0b78e928f6200bb46e940e1878f86c28f9bdc3725b86b9e0601046cd962002f5b3ed1c517cd83a13932090e6e68ce09cbe4f37336a9086a56e9f3f4456f288e0f2bba557778aec8138755465f37f4febe77740f601560c8c53c21adeaaec3df8ef703d6aafe3e1f34a277ef3017fb8ab48a27c6b4283657fd0fe7f3f1e57c3f3ed8a743ba9f906fe723d2aa5c7738aeabccf3aee8f38648e4597b40fb50e49363ab7a5ad534b63c4f0497270e39c0c5a228365b28ff66b9586e9cb99acfc9f3223cffe1790f872f23a60b05d7d75c85b0fc9ec87dcbc5345190496f455e90e0e479eeb1555ea7ba5baab8ea18fd3015a4fb640358448df87344b342eea11cdc3f1b1c461161cf9de338996d90eee197a0b95fe3e2dcd5bd9bf74611dbed02361ca47bd8440ee1226a6cb7dbbcf65edbab19ead08d96a3adda66a6495621d490f7c6e14bee49b7779f8f3d677c12d3728fd7ea78c96f15e974d2f192bb271bc0f025f7270eedb9779cd502a83d8c9b17ba1190e02965ed5f6844a055f5499cec7dc97d97a0a7d98a3157f5d6c6382202d50a1b5e47afea39ae0ac15daa652668ced19f780623a05535892c80618c19ad8d8066853b68b645346b82d66b55bd298648a65651ec937774b64084a9f732cd1f8dce49c4983a6b0ea87d46408869ed63b46aa6555563595cad054f71456fdfd13b13e30ad1aa5a635cdb626848b4aa1ea105d0e618b3f5bd76391a89fde0942b6dd61c621e8c323a2465aa691a57eb75c8000c93681dcde25eaf44b3b8ab6d5cee364fbe3f1aad47ee344d6bcdf3b2865136342e6b182573b59866be03a38cf9a094ba4a82946912f37402c138e91013db560dd179621004b36c9f44abeabb4f5700867196ab8fd7aaed36c66f57e69a698e587bdf06b51bc9b4a79c71f667b7280441d6b286515bd65a95639ac3ec97566fe74acafa39cb935e34f064948dfaee91e74fb3b57dfeb365395bafad31c2b46c0573d66b8fdbd5eccbecd12d716045ae3b999e5601d25358a6dd57e8e24b174306ec38bd66c923a057f55264f048ae0fe1f03445ae48f2a9d030a5f4a3a923e88b805ba35575a655b57e56f99a3e643e03d7862ce520c31057d6b36d6a95045b25eb36f1d4ea7c0339e9988efc6bc6d35cc91c9923615b8edd80a2d0aa0c085d679b352fe78c31468969a5b165ec41e5bc9932eaa046481cf9f8d2a5d090b904d2381357f4f15fc0ccb20979658c993789d90c8fc01b9a439f63eb3bfd4c94c13d7e216681e2198f76cff45dcf5d395b1d57f12a39dee2528e1ac636709e224d26d1acc6a8ded12c54630dc81cbf84ccf11107099d5e8966cd87d18a4c9f047deb5062b6a26b86302ac769ed9ce129b69ca21863e273b624f1c2ccd953d6398b9c9a1ac9f12d35fae590524ab7ed4441ceab79d03adab631c099b9a21ccdad9aa153f70094df4783e6c89ecfa331c618639c94525a6500ca73de490a758b970aa0fce43a24ed1440796b6d28461cc6cfc74f013b6a8ee7b4185ca4402810b0818c7c004ab0da1aba1ded6439ac3f395edebe0094ffb77da63bdb11874ef0847407a03ca54f78820492236db316db38e1da70c7d0cacd9b2750fbbc8f260e71a2d7aca6e394e32915cd11e8f511409bfb24af8f00c6d37b71d328a594be44d1c5d98a11e41172e4c8043a46347229e54731125f006b346b62218a88315baabfcce12f364241861fb9efdd3611c5128ae4088515b11c7a3f591e26c7289690933d2049a32c866462ab3bbd805e6c699cfde16441a1200e774141bad3a02c3b08ce5d1d560163cee920e4eb0c0c9d20419ef28a3c314a9be9e9043072323be7d63da479729c915ec977c845afe4645a10c0109e39b269c0eeb95dc7f6efa321c97b16c806d608184a9dd86c7150c495fc1474b2c07d21cbf76c45974ed676645a4cd3d176b0e8f3ba6b17044723d1e735e87d22908487849c8c937939b325773c1810cf2bd2ac18851274809019210e5e8ea7f392432f274b8fc79365e90abdd93a3e7672787ec866d043039f1af413b2bd202b1159459697a13d92e565c8b1806381c82b62e4e5081039943a48a89056a8417ee1a43aa93a9cdce570326e873bd2acd026b155c4a811a327276b31ed355761eda93c59bebd808f982bef49cc5574750fe30c87770fa366cc85d33f73f544d7a0099b988406f5d5b296bd6e5e9dc7fd7477cf20cae84b243988f7f83d6002ddbb2f19f47ab93a2c835eafdc1825717ce074de27127df7ba1f393f72c099037b0225631248abe4395996e7e43979ce0787dccfa8bbbb87a0b93d20940e3a29c4eba61e9ad531aa7a01f145dc6e74cd4429b2fc4808540db24c1f1fe969f4efa9d77c4f5d3e856d86485c93fa08dba83c95ba0deadff71e2e7ad18d2e25664b048e48a3d141518a2a315bdfe5cb6212384a7d22156ecb33a67260b19520208aa87143892666ab7f9a2b89932361296d0a514a29a594d24a2ba546445762aee8ade87dbfd0903993a094524a29a59452bb51da7257dedd6787515c0dd15008d36c284a02909e964071f8c64abd3dfde437283779b7725b9eba2c47dd7995db0fc25122cad8749ac881c5446f798de82db3e63b0bb6e97fa2a7eef714f9a1b6eb3de596fc744b47b9a49f5cf02677f4ed06754324fa1e3f0ddfb8b921418f92dfdc947e035ef41bd26f46ff6eaa945e340249a5125a023d4aa9a9876d929009c678a911b01fe58c31c67bf232598f3c22812415524a29a5d6389288a494529a20271054fd3164646acccc95bcec882037e60a05602875749e1082039338f2d5ac3002c91b2492502249e7b42104733bd22a6d06207dbf3108aa64441eb7bd8b92d4819f443a10ec7ef0f251c1278420284b0a8eba0dc92ccb871b50dde93464f98a44be52d1ac46436e2459767567b6b4aeeb2e8a86cdc9f98101b91c9f012e75f6729733e0e52eef9147ef6e68650e8ca7450b6c63d8ca70bc1c3f7e46bc60fb11d1edfcf000b5f8cb19d0025b19aeb3b9920c70c13528efec7c6787bae68bbaacc55dfd712222710de92e43a1cf2070c7666d8443306b3bda4ef7f8ddc09f69110ead05f326f136db991b92667197df809ab5d544242e8cb18d74691a0ca478fbd97c5a256500cad7bca25572ce6690a402076c4c5b251b358934c5343afb10418e4eb34e64597ef2cc56bbe4e96c0d477bc1214bafbb3b92b69e56c9e7989f9b9196626e469ad5b73e59be48aba4ac5572d2faf96da755156f3c1367de14e92036231d84bcfca6bdec9d4564537eeb69569f21cb6f52cc8972d252422aa1dc2ab93b25532c6219b5802f215d533439b96f615949a154524e282726a69212091c893eaf0b6957d64b5bbbc153c3e184e5c8e00d6d99008636cbe9438b97ee7e7159c5b8701113b382916721c30266e5c2c52a0686450d979e16f7e161fd893ebc5d58c0bcbc06ffe5fd9797c3609b1798db608cfb1e81c44fcc0ac68b17305cac6230cc55e2b2b80b8bbbc89f9d8ceaafdec385ea98d7c03ce6fd186c33a4714dcc57d82606c657b78171f198f770c1fcf022002f5e5c8273cebe12c6952eeecb050c4971007e7801c305cc4ada22e0cbb17cc136436a628e6f1380ff708c6d601cb67a38735c5c5e83792133610290f90b98245831bd683386c5ccd88d9b1677f9046ffa85c5f1ea362d30b6f1e1f8362d6e33a4c6e518dbe0bbdc06e62c1e13f317182e5eb87071182f2fab1b236356302e4ff10b182e563134376e48b03ac636436a5edcc56d780ca981717c1e01c071ae60ce63484dcc5fcee307bc3a095eee02dbf08081a5ce0bcc2306cb17cec5a31372c11c3f943cf10a39ae1546f5a3eba7b1fc71c99f9798d5a58b55cfd80cac88799921882bf913d816643967106364ccca050c0d868b55cc0bbe1367c2e64ade870b73e35cb168b1f302ebb4d05abcb8e0770d4619e4f2c2e22c5ac8608a976bdb888f2b72385fd38715597edec82ac8fcbe3c35da9db9eadb775b0889539e6669599bdae4e604577781aa7f790f97c477790dbecbeb5d5c58fce53618a3eaa3ab0586f121c6071f60307e956771bbc565410b163031303eb068815f6ec7b4588b6b1c6e815fac75c1f6f3bab8ab7bd3a1bb11f9d9765e206abe479e495ab5ed0cb111b13be1098c95d3ea7c6d41cfdab51604ede5372253da29ed947676d2c6e3ecc77e8fdc3ead3a9da6f652c11568f6260430ac3bddacc643c4ec5389549e5aa41ae991a24e015491640d276b3e50136b2fedc6c660cef8d59ffaf3d9a047f54e6e223b2d5e5c30bd5da455b29ba7718b171f097677fcb4d7ab595d81e60d8e0fd87ca25913d7295a25e712262ccbb7789973ce1b04bffecc16c6da8d8f2cff03f49aaf39e7046f36151e02c6536beea8e28c91677a052c7012b06fe8ab7b4bb225d9823ea38831b2b104e34ffd992bf99aa45556c8e320ca8837b0c11335a0c10ca28ce8f2f3f293a3268318c0e0c70b5cd08297abb160052af09102149c40ba5ccd042520c1cd084410658420ca8851467cb500d41e6a12b4a20a2ef9c719532661c8f7c9be621572e5a9329f34b44ccee8cbcf28a28c9ed9c2b1d9b2397687db74b2d4c2c477f6ccd5d4992b395b1367be40f0c67ccd150cc0507b699aa6b50b6eb0eec4f98a71be264e9492c87c4dd8043275e6ceacd4d62902a2873222d143914814cbdd2509480ee71537315a6373355b55d6b36655163a2f3a2e3a16e3d05edc53714f4bd06cd5d95ca120cad0443071e40ceda5e1b4aa674b63e9a05907e5d4ccc9d17246399c3f7367a6cc9fd3fc41c13f3aa7a93377742c46c2072a3e225a72e7e29ee6aac11004a208f0ca44d5e4727266cbcee68a0be9e4500c76c20143af24f607045aa92eb793c3f5f8c8e4e4dcc8a2cbfe881865f076d6251c9e48d8ce664864d1e54baef51159296c4f07bbdd8f2e2708940f056d5bd016b40501f5eb7545c82714bac2899b4f4ee104902246244f483b692d211f9f2af3a9329f2da8026d4992d4d996a4bee40c9b23618820cab02e883138cdb2300d27b78dc57272909c6179422d0eb95f672b743a8160ec046a3e3c4ef448981333005c991357f531e4335b216b41d0c7ca5a657b66cf8853c266914818fd2d498e0bc22d28921e8e927021f0a66ba990e190bbc93db365dd105748e40cbb86e79295917068afe899434fb66d88319d86dcb318d3973c60d8e5700f41b0cbc97d2e6784c318221cca7c98cbf90973391b9793e344502888e342415c28880b05f9e4ba13433ba19dd04e6827d71b4a647a6ba7aa6e365aed7672747142ebf1d22e52c0a7d0d61080e129f7efa348a673d68b6b273d8a353053f7f4f879efdebd3ef468a6af5da5f4ce473a27fda477cef49cdebda754cc28385dfa6856eaa7cf8fe68423288b9c6ecaabde9c375d931b733751f7847aa64b516e90bf9b28578483fc1d4df7967b59ee4faf09875ea6252c439ce0202d47e12017e3dc751c7b6572bb53ef342fba28d464a64f9e724dc093946b72140ed282671ae50661c1b45774e299a6254f19a2e426d10dc2f213964b7b657ab779a766a5de4f75737a35469f98b0fe2133ce343d943e4ef75e4313ded1d9e48386ccdd63b76a5493973c362be5a2c74eb927274f798d598f0ac54013acc3cb26a7a7e09066ef2597df1039e86936c1394ed8e43abc6c7a090e69cdf304e730dde4defb23c2c41399dc8473d0d73cbf05d44ca7090ea58f8c250a248cfaee72af377593c9642af9bc18f0720ed34bde99ee7c7f2638b6ca64bafc6894dc7433040575f9d1987c3ef57965365d7bd48d994b5da240ce8839f512ee164750fac855803273b71c0665321571a69212ad7e7e5ecabdd61a451cb951a38878c4e4ddeb35b977c31dd98b1f11d4439938d092eb51a68a5127f527f526ac32e1dc3de61db9bbf7d19c4cb464930574afdeeb436bc2280f27a04736c12893e730ddbb89577f7243efd65471280676a7ff4c6abd26dd0dbb9b601dde57710eed269c23f5aa43c31487967b15bdce8b66494949bd25f4b52b29a925179594d0ae849b2518e5a2928b52324d252517bd9e54524b482f791520aa74adf469ca61a21c6732dd84337538ec9177e4797282bd9bdcd82aaf9ee5c65ed5cfcc5afae81d25827be9251c9a6e92801ed1e4de3df9bcddf49e63bebb373b1c7f92eb0dbb8326a728fa1c35040434c1394ce7de611d5e36e1d26d049fed8e6c3d4e05d32afa7377beded063cddb64ef4600e41eaa60be75b846aba6e0c0dccd1055c14c96db227ad5a766c5896bccd3c4a7fa63e8bad3a6f4656fac0d8526d0443267d37e06d157b36ebaf5dd82f6dfb5a1db97e79d76ebbb874338f6f5b237adeaefd29b5e7598bee8abfb4c876c179a33c4dd9eb318a85548825a750515d60da0ecdb1d578cd165cd30811bb326e9e934eb27f76eca28a7687b3bb16d9777bef14d40613446737c68298c08db348683ce3441103c451ceaa0d5bea1483ed05c82e6f0a0e94461561839834761d6fa982109509224403d40400d14b739e3bb18638c31c639bd7ecd96bda6ddd84a62ae3ac62863d01782aeb4422669556319f4055075c49398cdb406a26fd06a6805411053b3d35e195753b395627b6f2c3df739e70f9346d79c95523ae7a494d61963a6a5f45a8d99386a4d7f9c5c70e1075d38bd842d4179e589a01cf68968405ad36916acf1b000e9aab793c32d26b2afd4e3b650ea2c47cc56cb6318814a768088f13d5e082d143f53529253f28a39d4d2e35942033b6c36bdde7aa0e9aad9025f8be85e4f7fc09a457a3d7da25931fb84ddb1b5aaeccc5557b9335b1ac9c2c098055f12e73403ea5162b6b49f1bb3e501c5982dad147b577263d680b40624b705adb5f69b89929c4e9d5722d26c9441b9b3428f47400d991298ac1245492c25ce509179d6f2649b3d2f75ab4b2bd22d959de689dcebab0e2a902843f4faca0abdaa683f477285e5708b551ec49657875423d4abd4d003ea76be59e8355ba2104e2827041bd920508744da6232a49f2d16e3878c0fd576f32b4e56b446457b39d47ea680844c61d9669c6c516e8c60f40dd1260f3cfda55b2c8f87396143ee87dd8c939984713293337a4786cd72b722bd6aad77e48c2d0771db418ce93cb7d896b59490bb1169d526d372ea6e3ab44eeda3d1b6fa93176974224f74692e8995e84491fbdf47a3660972177d34db45df109de97788b44a74675eb92d973b4d24c4237abda959a37fafafb7b3b5f28a438d87a6779a08cb6d587f413aa773be6b6d13a3b6c9a1d78b4213bc61c76a13699e101e4dd1b41759940deff31e6e215febe8e4961b3b88b07df2106211628c888e461fcdfc88e469e03b15999cb102932ab2cea9dbaf24ed853bb2c87e5644a36a4447d76cb2e89a6ab4715d24c6f43b50a4d99e15989cd14c88307c9cb052c1969144459fc9ebba929cdc2e961b8a2bed2d5753a180c967033c59b931944d1f8de9b3c171269f0d8ecb1df5e4b5f9bbf1db804afbc967839e6ca995f74b704a7266abe55d5575fbe9a3b1b3dab8e2bc47ae09962b81e6aaed4feacaa0b99a75c846a553f1dd80a07c341bd65e8293b573291538a54e357f41fe948f888824db28288126df207e630c2224008d84428f2598c49516933516597b104454ed2639523e1b6096b2a6584f5e3ab9ade4d5ac4d678aaa82427d34f2cefcdd98b7d816db6eb5d36f96bb9b0edd807c34d52bb9327337c8cac115d82624778b57723b9b82b01c54d9992d5112d4557656601acf6c9178bed9cf6c8d349e9487f67413ede7e427833a5acf6c95625dce0928b7d603fba1a2774aeecca6cb84cdb6da959679160976f22bddeed5dd74385d4eabbafbd1dd13b98f4ad247726885acc0ac7de9e4c0665b112231d86c6d9b4c96e41434fbf1e9c19d0f37c4348045e53e92cdd624aeb4af64ed2c9f8d875840fb968fe68b6d40b6968fc6a6c4d585ad1cc075c0bbb56e2df76a08c090e4f2752fde2759789ff691a6ddbb60546937dd09437b090d31a504345ba6d63ee9b548ba44054f09880a503e2c01813aa00ea87382acd561041bc146b0112cae4106a17fb36f16a790b54f24c495036e8d2aeda9cbadc495f693525eb95940e09f8d5bee9f8d3adba24e2c4fea9e0cc272ed066939c7f2d07735e0c42bdbd993c3cd6793cd556cae8e6c52acdced67ae807ab68da70427f7573e9a2ed60690a59e945af1e2e9064456b9c20246195c9451678b4546b56d427ad544b622346ade6235db31ac4896c9cd496ba4b4e34088d210135c8cd1ce554c3f1b1ccbdd8068b1b6c87ea6278f4cbb737dad5abd6499f156ce08c919da533a42363680b155b352fad1c8ba06504e6dfb6826b63350de4e1876fb6c74aed5a31b904d27a686587d8b173b99f2ece56c8f4cc66d56cef78a173ab7ede8e884b8cde65ef1bc2d537c4245afbabed68f6652d1aadec161d57ab04377346dc63abd928fa69a98cc79da2a4dce4fc662b4c5b334aaacca3e74bda8b231aaecad12d95eca8dd26fbed61cea2c2f7b485beb37af5dcf5e2a7370248e362b1767ae7789faddda18186b62aefabf9ee89e121e9156f114699f0ea2bf725bd69fddeabc75f1eced9616fbca7283c89038c2d6f0e49be7be213a6bef5e3c7b65de42dccabdcb84cd1a0eb2f27a97d0768025b1d98ac9cc553f75c90016e1363d99cd5617e9555f8adc6de46446a3660df7ce1842f5282f75adab4b79a9abb9349eaa7d20d34f95f69677972c2d1e69748f67b648495a5470d8724ac1e1098c281e4fee93f0105ba5d30b722c0523c82d4a325b25f6048716348992b48a8cc4335b25a09fd92a9d4a70780241124f47fa01493fb29fdcdf430f489ec0893a648a93291695bc66eb24e87552f242c1c95df24a031a280e4f824e6676304107228cbeb1528713acdc0c6c55b420d30b4418da63892b01712520ae04e486acf57881f7924c2693e57e8c56e851849806b0e05e8acdd309044bb1dc878006824c3f55da76b98d602d16b7781acf6cb1bcafc966abe54ad7ca95da7164b9d21562a2e5765c69bf1d8eb245edc43f1a0b82f7a3018578a93b5d1a8f56a45ba0905ef53750a7f2844e256cb654282d8961ed823badd2d9a800b587a00e28a455ad229bad15110e411559ee9fccb82bf32a7440e8b2882a0a722c401c4220d717ee91de4715cddc57602bb0b902eb1e9ec49080f3b53f8e9b5a682da8d3ac4d48b376ea7672422dca067eb9f752b75d1acfec9bbc04ed5c3c09cec7ce00ca838d93f14784cc2e15d7a7eee68a2b177b76b6528fa93643fda4137b4962ae549bb25eebf2d1d017efa3995bde5eeda38a87b6aae2d8445e3e1a8d058b8f664e2d03e064764245eaaefc24a895bac5a10eef24e86476323ba1227551da535fc14da4574d843d999d507112743a791e8bcfd6dce2a3a12bb0959598a9243657bd126b55db3280f3e10a2caf3c51129badde09e158ee5527a36a05d6aa132a4e825a75323b99b1f888b05f81ad3cb112a3cdb2a4141da7ac3de523c205177ec0057aca2d2200ee54693748eaf306c1b92bc565ad03a9d56783cbf4dde6d52bb3769b08cf474371efc456f950af55ed762e9d56bb8e76dd6c291269d75a82545a9a600addf6f810ec62eebc6e7a5d0dad20088286e66783cba12b6b242565204f1ba43c514678ef7e84878f8821dbef4279133a386fbac7b9e24239d8e1f2e80ff4a331c353ee1a767682122100193bc6383f91c54c7448564ae99c43b4a65ee80ed9da76754247b3490e13597bce185bdb37dc0fbddc788aa8dd4c2570f3cc9d56b57a832ebe84a19cdc9fdf3b5a05d830fa44ac5945a28ceef2f555716a4ed5a9b0b0c642c9d362020e911ce54b488e3206b91fd21ae4780aa45b4dcc20ce903f2ebf21ea5144e4a0ad8a314b1efaa3faf0ccea0304ca372167482212469f48577d7888786f8b43ce8adcd2e36677bbdcde412c1940fbd0befc0f002fc24ea0704897e8d225c238d475237a09ac6bf4ef4a97fc6aa80bc42518c1c8257abb3a74627465fcc1fbbc10fec1b39cedbc47d184ccd98851c8f6993162c8c8a854bff7e83d42e184c9bdfb4c7b38445bc551c105b58a9bd9318016c7da2ef915d12373e094779cf296e786238c57736a8fae3b3d4c6f883cd52eebb5500dc0a9552b0f4aa04ed3a88c2aca44574a69f72b4bbcc44669d5b45a638f8a6763da4ae8e24babaca6699aa6fd958255276b5acdc901a09769b61e0a0d6815602cbd52409b0b62cc962361f483002a21ca9018052661f42546a1418ce9e3a480429c4d01a1c850602850a0c066338b27f62410307ee2441972e50491b552869595ee94025ae159c959c959e159c959c9c97dd10a508cd972567836d816db74b69d8d27caa0f4fb68c84c0320f2f123822bf1789ef77d97011de743882c1428a2aa516028301c1498c44191fd00cd82648b2cf670c1662bba6e4e942167b320803b51464f28401c94188a0eca0e0a0f8a2ccae82c3f8997a0d180ccf2343acbcf443942e1a68adec93be6650e4bb2dc256fe6cdbe161cc79b79b3e31c27b4f1fc000c49b3f31c75a37b0f970ca80c91b5e54455cfbccfb717fc9312257fef36df4536608fcb883eb28938044b0f65aa2bba4ade9778090fdbcce0efd185aaef7c3e8caaf1feddc3a81ba3a36abc8bee5d340403f2f3d1f580efdd6b48075f0f7eefb08d747d27bd872b8cb22cdf93e5839a15a6803efbec549c8cf08d2905e483dc4f2169560b4a5ebeba83a2fbfa6e9830aa6674d347983361140ee91a5dba463d5cde05df1dc4dc0e0e1778890630dc726c4c8ca297bd3ecb099a2defa6e310bdc33cba8b6eea2ec2a8298a2eef6e399bcee43abce59460d42c61d4c435de3bef73eb790f57bc77316a5eb479afe9ee7d4e5ce35d846d3cbcd9741e7dea0b98342bc5523e38d533575b4ecbcf5f2d3f0f81e7b5fc7c2d3fa2969f51cb4fcbcf08b45800658b4e8bcebcd1d5b2d3c2d32c5b44d662a4a567b6f8441932db2b80618f5c9fed15c0f94dfb8898afa7027523d31bf041f8b35691663324256979cd160a4777ef1ee6e1bd7b92961ffd444bac05a7256712013d3c04a53dcefa1387a5cf9ab069d5672c3d3d3e3f40b32016180b8c25c6a2b3c3239badcc56825692b0bc5870264bce84025c015ae1592943646d498829a0d9eaf09673b230e10a8fc8da0f04bdd329059427de78860086a4d973be739cc35c38251c9cfa89311d71584af5e43e69365bde6c46d28c3423cd50603314180a46f166de0c65cbc969556f3f36582865d60760cc34879aec66cbeb2d47f4799d26d3b49ed3490bf2a008f2c91d6a40b9b71c19cadd60cd0a5160284f342bc727f7b71fdb96d309e9763a9d18d3d2937939b3d541115be7f160b3f5999785dcde14b69c9c1afb6ccbf1663927b3d963b09034fb2c37c9e3a93c948727ca47d20c3cb969559fe0e43e79c5985ec0233e4e88029ba5c2a3c072e719cac6b90f7c635c1b6007a6c79790fab4ec1d44bf74551d84eaaa4fa96a56bf552a8955adda31f388d2b8c5784ae99dc8337effd78d70bc1128cb389a4890c4efa3d1fd2e6b554bd1f58c968226c650cb3abcdc4d599655e854c1d3d3dd077cb2ac5aad3040c8e418d3b219df1f8d8ca7b2ad0a303ccf8b0a46068883f3ddbc118c91e239e5dff0f386242d6bd96cdd55a779b293a0e8f1a321d95cbfefb1278ffeddbb36be8fde75912239f2c0381918da8b7038f394f77bfc8c8873057e8f41ba40b44ae6dbd8008512c0708e5028814efe6cc5a01d31ace0086de0c14c042e991caa248f91a6322a931959e28852a4f92f0db3b9012cf95c416108eef4dda5b79ff7ae3f234a8f1f0ecd55c2364eb8c0b9921825dfd1f86ec451bae9f293b8a6741bc9861d57c94d17655bd5e05c996ef2139487504e4c4c25232044fe3bfabe8b44a239e71cddd0cb23f03b05bf8f66a6487be9dab9ea86f0b2c41f03bacfcc5bedab954282945e2fdd312267f0c84ab877a6ac599f32d567f023f75f60a415c0f06fd64d0e254fef748b1a9122f794592b8061cb72cb5a75072abb228753269b32a9a32385501fb05384606a4b7558b9ddcecccd6e997e5b6d798b7d440ee37598de743099c01f5421e91f5444e9b4c1de447227a5f5e49a3c7ef6344e11815af7d3e2b0624a6bbdd41ed1ac482912d41112c8c4e412c9ec1f27131fd1aa796ab9f79dec202c4fdd2028b7e3bc37eb0485825293502b665053017444b328109256d194871289294cc13b3aa7bce28922533a5d943abd89cc6c8c431d5ec9bb8a0a0e77cc1a2aefab6095874231f0847578f9a4e25d749a3a99ee7d9e700e1315a55c34534a3847ca29f54cbca74824b95e9a01f57a4f3ed3949a501e3f1a282f9d5e0c98720e9497de512f754d38c855fe0e87a64ceb4d991f035a7e4f3f9a144a3f33bbea896ebde9a6e8eb8d68f9fd4c5394202c6f51c1b4d3bc941b33ca2d5d7453ce728f12e428f7ded82b94a75cdb2a94ff7abd424169f9efcd9014fd2977951b33eac652e8dc894492673a742e34432a29d44f273674328b2103841028b7af1745070a08a698502935d4a1235bed9389969cb2009457d0c328149c801e3905d76b37f4cea1d81b5a8b8262ba3d8ac53a4c26d351708e1353ae29533e39770a9da44c50a7d3343131a126a27a6a4d44d5e250147a48a98a8aca4b5785524a29b5578061fca99f27a1cf876a286432d1d04924141cf6c828f7aebda18e6c276e159df62929d8843b991ca512113ae9241c9a4eabfdb43834e5f99959439383f4d5e69387a67c4243273734c13a4cd98449e7c068ca9c8ecc9942358a08856e346beec836ad965b1cd61a7800434314f1e979d69336f4bc5dd9c95ca308ee5eb75aceb5786f968cb575de1f548193019023146e08aa02069323146e30926566cb8818a37b7c99f76688f6ee524a29edbbdbc58fd287425c8d7879790dcfb4aa867c1865111f218f8056f58d90ed9b990ea2a5143766105063668a373780e111305ddbdd3e04025ad5f1c3318abd028a693680f55b4befdd3673d96c3397771cc23566620ea30cbcf6067cff082446222b373918c9aa1ca188031ea090c3911ca178c32cc7e408451cae906f18115b323cb02048a10646d08215aebefc88d8726cd586843b0dbd7b8f1c6f689bc872030242118728e4ae3d4ed2733be6b78b5f6690ee35b04ccbe41b30a0dcaf99c20d602853d3ab9e42e60e200252312874e404c27472df94da5e344a29a594d66b75be244e0771d32c29e5a9552da51051802178bad685382be50b45dffdb7d7d51067b1f564d658d075b79421ce6edd8f51ab1de7d999bb90c77d34fab4f3421f8d6edbacee1e53523268df1e5fc2ee95fbdbaddaad3db60ee01232eb40f6344be67e9e9f699ab72c4931a65f8a313dc512ddd90e01b549270e2b180ac19615c9fd6aa44a919b0a6955ef64aaa33d67b660b315eaa939215865159643b0c642108755a7eaa8c8341c9289010c4341322b6cf7d266d0450c7a59ca0067089dd6d2fe29b63c577bdd5242cad34146197f9abbd1cd1079d73bd79d327ebe885675cfa5ab46b3e49c2159738c3d3762406ac4e089dc2f221e690dd728e2462863402dd914318ec848a132f2222722d9ce967c76f1873160b4d8b08681f8c4e17dfcf088c3d34b4b1c82ab87f20ab0ad05c1d3cc99306e4a4bcb613c7e345a0ee3330de32d4fb92d294fb96d96ca53ee352bf49483cd4a3de5a6660de0293f356bc6539e6a96009ef24e822e315dd7755d77e21de53d75c318b9fbc90d6be493ef643aa5bea262026e9b47effc3173e63479bca68b6ef2928fc644f326fa771350442a958c462396975c206460542f26f7adfa3c97cee52728978f3e1a9550287523d8aa941737e67aad4af900aea955299f714fad4ab9006eaa552977911f0dabe586cf2929b7c559ee12f42eb10283899a73b4380068b438003ed3306e8bcbf8608981b8a1cc403cde108c5b940288f2b067b7a500760f7b46c56ca6e494f2a289f1e3fde1a91b9eb24a264fbc0445b9e173286759478cfc72fceea3f9014750e21d34bffc3004be0b1037e600b40e8d40ab26d0919f18b7243bb6ac6d39c7ca7d58b90f3e7ce5f2ae7c7543995757409c21671106ccc388852ca36cc64d24abc47412b598204096f983cce58168168ccbc710a259322e5f4494f1e212afee423b800010f01640cbe3471380cf748c31c648ba76edf26a9f317214bd5baecb0dc7b94ab514c0d3c39e492a5ae5baf703d64f48f9947717081918d5e7aaa5e5a21bd6c8f22dff2229b29cc402b27ca6f349014233ef985957e612031c887c20de7a27c1013c7e34313ed331c618638c31ce509f477d9adc506693c75b4720e9f2a666955e22bafcffa292976996e9f240e050e59de964e624218010a656aa097055bd923f411142c643910218ca9e6d2e94927b4489746f1431725db057f2a6efce20200248c418898263186703880378bda81bca0fe0df47a38223184b71c64bb33ce39df4542ecd2633701332ae8e56c90fe02ad12af91877470b271133ebc61cc4052224805be346abe403706b5a25cf727fb8116895bccc456202ad927f21a53c026e8c5ec91be0c62e802acb1fe0c68ec12bdc574b50983b6b9cd0661f6eb863cbaa73b71f8d0b91eaa28f089b341461067bc827efa4e7e2d2dc417d4577ff00b5cf6c09f1beea32b1e5937700b826a7a3cf4c8d899a738c0e80d10100808fc0970e7e4fdde4a66e4913d24d4c4c6ef22e75a7a6699aa6c99a4a9d6aaf37acc144cd390ed3a15cef9df46e18b1aa5513bf55f3a2db5d940b04fdf77ab5ef2913939b2e6d95c94baed72a1353af4c4a384c659383971f0d09c756997c74c367133c1add16072f00e45b00e0b6c0425c256e0c16d7f59622cab86f215ef05d1e1eff0f53f9e4e6e01e7ae772e7bb1a59dee58631b2cbe54733335d2ec63a6264791c3ebb5c8c91b8475c1d31a62fc4ade1ba37765dc7c4963dd143a18bbc0efc11cdc2408c9c03e5b4002f799c2d02bc74d2936856eaf13a9ac5f278257634d1ac96c7db4419a6c747a05b3d42a9a49c1e7fa359288faf69d649fecc0d30352d060662e44dfbbc1acab71bd6c8f328a7379c58478c6c721494777308d822a594524a8a8138cb39e4a995f3769b6b4e171e2266ed5debe5ada7719635dc0456a255f12c5747abe257ee8e56a5523889564594ca3db52a3ee5cab42afe746bb42a1ee5c4e41e716d624c7cbeb657f133f7bd8a37c08dd1abf802dcd8ab124c801b7b55c242dcd82b128e40af2288ff5d7e34232cba5824badcbfdbe315ca97c43bb62ccf498973457906418273da4825f28e50266f33ad3d41a7f4915b0a01941114d12ce5a78c8ec1858ecacf5842e61a48aaf6fa226e34abe21b35628d1bd5468d22344ab32ca2460fd80f638f96822c50c10db91f83008651430218c69e18a5810c9ad5ee68428950024924414d8650ce7284020c52944629a59472cec71bf309d479c5010cadf53ac8444f76a3f5f15b6fdab6d96dc36dc3abf4e6dbed77e4bac9386f6d7d778ec31b0e77e8f0e8f47a74b2a500b3c2081258b793dbc5e793982d1f3e2f5f1065983e2f8b1065e400e0d3fe4c51b7110db14aae7d7e5eb1523d9c3e7946790324c7d609659297d007cb591522ab672d0f25168874ab8364119687f209395eeec81913274e144822e4780984c89aa9875208395efee8d6443d944fa83c943bc8f14accd6dc895860418e4762b6e6cf5cf5e32c065d247ab34da8442cd5a6518e3a453310000000002314002030140c88c482d1783822cb62d20114000e8dba56705c17a8499053c81863880800000000000000004000f428e11a3b67523a62b09aac0de8cac79823a0fda4356f26de87a99521be38f3447b5582e5e6d4f5091958c73920b008b735db49dff6e8a8578ab787911ac45c664c80a8b604d652deb58297266ae875029e569937b84cd1f10ca33d65e6c986d5779ff7603050348fd0ce142c0bcd69116a5876b105389902afe5453cecbe7a480965d80b9c44adaca0271bb835103509d6f850f2e2fdaa6ca61f3e5e9bfdf06add8f7b4feee42e5aac1ac4af21ed925a1510ee895f147d23131852f3b6708dd6efa7431052155b572ab8f03c4bed81cdc6a9ff23b541932a43b4cc870e5d5af00de65f2895d6fa23ade5854bb582db15b45c311248acb10a082a4fe4f2314770cccaf8bcf701d88f630e9ddb7260879f07aef731925405e6c916367f1cab85873c99b459def10b11d937d3f396a7c3532609911ae398de1d3791d2095510e4bf16933a8994c5a4832fc38154b5c53764e45b8270ffea322fa0195603f13e1bee8a50611552fd2c375363b693c9b5e4b11046af3e7b25e2c2b39889ea329fc3362957dfd8a4e744a4c64c8ad4e76a4ab0b9b6463dd8d0e2175307ce478eb3e5607c93c783ad7b0045443db1fe244f65b5ae1cafabd470394533bbcbd022af048bc90dd90a8201e315422c30651df1889ce20c304697ec7346abda9940ace413d82758d2b010a760b194a5e9eaa0c4378f9a8e40a01421adb6feda4be93598dc00bd3c7a0124b15c6e848800c2c2d63b25bbb84cc8d61dd03068e91051198e3c283962dc21b4b14b275b11a96c9ff1bcb541caed4b1974d6baaf99d67ec406dfa48b0c95b808044459d7f60660778be8e131cf1c4b0c9b992bf91e0a8213282c594952e0db22ab1532584c625c6cfa4dc52ade798f6f521d2ec8810085279ac4af2f1a4c361bfbdf58ca5daaefba5de55c2b142cc28a68f1335fee9a8bb57acd784b2cbfce869598921036e6daddb3fd437f51bbea3ba3509d75135a620003f6d99ff479880218d6d8a95b289102ad279a0e6dce2af1bbc5426551886ac973fb65cbd00daff7233e7b25d3c9156a68bb2b02e41f546ec30472909540a5d19e75eda947bbb2f41d4f12f6e4047f95ab101c8aaddf691df25504b2a92d26255aa4726f7a472f5844aa3322b865f566164f67c6f34c874a804423a0767fc484b87ce1a1cae2251d8a2ff8e8dfbb41666fc7f3a7cb3a1d6b699d02172479bb43d93a2987ba2be69e75afcd1e58b480de4394ad3e642736562df9d27da98d42e6e36e6109259c6156753c511a631935758a12cfa2dc559489711cf6cacd0faf2ff65ceafa5dea9c3e316b352a8e8fdd680930e26e89a8a110be33fc038c3fd0ebd6e266e84fa5faefa9c7bdb5eff3624ec0a49788fbf57ae62f32f9d02d59030b7626cec70f11fac78bdd18768962c4323704b42dc1b5adefee703f5fdddaf078bc78872071047b853f20336e957c739e0d2641ca205c152d2a3310f375c94699bc5d881954f0fe443f3c91da756eb4c3bf9cad0ccdbde071014cc87ed7d47528f16c01632143b91da4129d45b8da3c9890703aebbdb6ccc1f8bf126440e7a378faa3d93ae52619b12550cde5d7213ca380e5958abce65c64155eaa14b3504b50d3b493718b25e74685f183a742108670ae240af77aea98c459114d56ef735ec744e56e2bac68dfbe25312c54262c97e6d6e2fba96f8f6fa375e0aca57ceea5084c0bddf54dea4a73c21875bac7534408248f77cc8d5330e9f9a0975b1b88e4830a5ce0546946bd45840fdf5ef3d8a5336f1ec28b7ec04453557720c9df4b5786342ce23e9f6285b9a17b8dcfa59dd8f9101a4c6a77a6b4d3ed95373d9a40142831e7891522b468d2489af7011167df2b99c2c65f11b80a6de71692dc31f6bf8f8ad6114bee94139e5099505335fd9b181c8bfc3212b4e03861c21a3d3df1f97d536c5e054185726b1d5981df2d0d1ae7b322160937e5688061d4f09d857b72f605ea48c46caa84e58ead2ae1de35b0275f57afd68f745ea79e853dbdeaa5e8f4d2454e451434a53550787a49fca48cd6fd9bf659a49101e9ae507852c6a1f168afbf9a3a76300839f2f4b754ef7c437d042548209672b51dd15e6c25d2fab0ddd89ca596bc53641b684b76f2a9ac15761226d2b14ade7794b9cfa6690ff98b16c561edfa4d16855f5f5d86b703c7180ed78434ca7049fc847f051c66f55c83bb9e1dea44465688feb0884205c9290c52406c8244338254284026c0c13344a00b7f389012a957ef91407b785770e7891488de3dbaa01c3be4d8ba03247a62308f9caf03632c2c7013f3f3161f87845780d320d2b36140402128efede5d883bbb02f68dda166a0938c2b745db625e97aa1a50dac1ef3dc1b06f58083f3444844b6317877b9eef96d516a5ef44b472fbe0b3ead96d91ac82a8f4be5bd59e5e158f975e163d54bf618bf171d541648059b34afc24d048e579a61e68e0b28ad24baa8458227a4070f70ce26e4b4d7ae8d135ad4508e8b380dce387400beb2bb0b3027e26ca71bb050c5a04d09ff59454db8c16c31721a2b1965429273dcebd42cea3f5ee665e5cc5f095de4e129cd5e5e7eee04769339256490ff575c16a273777656958f53221ddcb5e71272de3afc67c4ff92a613656bbeab0d33add3a803b296c93423854befd38c00fa31d5d117847496d8c198f85483df506c4faa97d2f03338383b25d15c91bf2240a9d9ae49fcb69cb42d34ea0fd079cb17bc6eacfcd2f408f2a541708e2ba9920d555999000f68721842bb114377d72fe3b570ef7a8f5d9ec4a4506fe6f8d5c5ebe639ab5791fe7101d36b5593beb1f76eed3fd1d36dfcb42ab1ba65a83c0cc7d32e77c7e874d3083818cf7c2ba946c7fdb763fa2768ee50ae5ba98fc925a2dc7853ea023b62b3e143b6f6cae84a9217247cd8a8c19dd852c06a146c2da9f1229a3ceb2d16bcfdd47474ac0f9b05f3749ddfdc26c4f24422791ef39d9a834a2323176f38813b0aaf0bf8c727468094466847bf009ecca2d0845735145fbfb8a422cb14f2f86aa320d6c3ec8658d35845a66850e96cd4f6968497536996bdbe8c8844b368b2fdc3cd77bf85e1d32258f90d7669026a202ef934b7b5cfdc6fc39e59a957683a824e5f6653d2991d2cde7bee5936d6b8c2002118e9859f79b2066504d02792fad4933c184badd5b3c37f36ae8a22af6c92808fb73a882f9c90889651ca2d2e33b5e29bd24ce0ae82ac54e19aace2a292e97f0a39e51cab5f4f24f3db142cdbba115bf9548cba0c896687158dd41b385cb4db8dc8df22c3506f14b8fc79254246ec20f0668fa502d18bff685620b4b6830e9060a1f4bb4b7645fa41389e77ad78e6b51597ed2d6e024eb87ef316bccd97f2ff5764778808daa62adc25b6f7fcfad259dad005006e8141f7be347eeda1e491f3ec7ce1f99f0aeefbcc3f179434ef4a306ccc33b4b9e1d07c8100932b0ab9755650ec8a399ebae4ceb91a174c00793b90169ba676b861971fe6b8d44068632ea273ba27a7fdd3f8869e24d31338c24c2a17bc3c63ee54f175261c52a3afd5c8d2e7ba3933e31da94d4bb34374a82ab562cdac9798045a78ebff87a9ac1aa265b88d96a4f8feaeb059146f140d8606a0df305ed21bcb14e4e71ba64efb17cbf5e95868637b8c4cc22186922c2698f533a011abb5d26e28dc8d9e271ef918494d04a45078716d2da7cbbba64d98ce410e5f387eb00a3ed5ca904e3775853b726975cfced861ca41d5a7d569d4f1da918ad691c334471b132a9e27c10fd735d10278c754ad48e083507a5535ad570a06876d165ddbbb6344bc1ea7058854f14b2373dc5f9c91e04f299b7c8c988e5c2426ed0c88155b1f645d7198bfe232979636088946b4976cd0bb5e43ef252292751e3597bd26bdd705b9472ec5a4253cdbacd5f52ce04b4cf700a3a137a808b5562413724941d2566dfe9f15ee7deb62dfd53751d8c549215ce326967e9fe9b35122be6a2476c251d2a3d4f2b0f272722080849baf8ad0fc8e2a2e94760de1c8ff08d0194badbbcc0ca80360aa596a7d77f1d6c96b177e708ba92abd7bb23b3e21defdeebdbcdf2db3c41a17852bb5c60df0756f6871313958faaf0001618ef3c09a059bfc2641c872a028bc052690a86f55bd331a67b0e0c56cef100c796424fe44630a437f5dd47841373959173ff99091fe7a8e30221466f5924b7c693826d05dd7415c6988c6eb16ac4845483143b075abae1c1212537529a4c965ead5e4a5d6938cbd04841bc299efab500cef42ded8b200d79cb3b2c42a1e740db3baa22ae46689bbd5a6da815eb584981e40865718dff1b952c16d59c036c3cb7c2097ea66b437d5e92bdd7fd44130c7d6ceed0a2cc57226d0370206bf3feb0094608722036a68f49a973fe35ba7af92bb6bb9ed9638eb851ca5d35d8be2d363c8df142081be70caca7b6adf1db21b14eb73b4b1e95c7678c93d33d930ad2a862be05ad9c3c13c612f11eae18fcfb3a8f8fdf6cd284075e062bbd74225170419c8d311544130ee81c58d339c0ec011b069e6deac8766016810a7b8eccb5132f9edfa47bd511f8ec7c772a577b386850c5a9f2f09f3496d2feb38cb049aa9300d4cb90f5e78cb5923575d9fb298e52f0c687e026c3505e26c1d0cbd1a47cb94ea09d9e7bd46645d91226434cd631230ac3b72dca6e1a2d2f94c19532bd8484379b38c0c35b5b4fa40cce8ec5b3608787cd49a5a51812d08396ee8cb7f88cfd5c00bd79b5adb73d7f0681792d618c4ea234633f8619f5d4d35536b86eb1bca5b44941e13bb5e9fdf03963abfbb24f6e1dcf7181dca5b9a9cc251dcebf3fa705d03d43215cb8b12d893f7468e2a052ca46250cb5d75a8393e9f0c3cb592ab48f6afe655130a7c6d9d9be1e54933fa05bf53850b43d47a4374e45af5f0b330436b65dea59ee30328e756601a38eb90512db4f7a5f8ebd25559f53eb767814917fc2eb00fc85d6905f59c0e48845bdc6e2b11873785ce871379489d120af38228d652a6a73d49bf48724b3e761479e5a89ccc26b7e04419269bcbaa2ad3c2047e5200a9be4bfafe453f1bd8de15aacd29c1dd70ba9e63491dc84cbb8bce592b53f8d50ab37508cbf512fe57cb2cfc70767974ef456b0d40292800193f3d46681991c0d1874258b5064360f998ca837c755eba27ea5a187fd6910c750941f25937a3218a2233d7e008f68b3d63f3acb7b252bcac059e62cf157a0a9db14567beb0a28e4aa645ba3e332eabe470a5858a23c0719c246beb72d82388e24cf3e5dd9337391fceb1ed4c24fa0ca0fd066abc695a4d8eb1e46d19ac1ddefd283df73901ea7a85aceecbd2dd343c9952f906ce3f3f406399136b95e8db577b1072ec3c859a027aad573e72a156547e9dc85b61e899220127e9899220126def665ba78640a065a2656869998248cbf05502dbf5e8d8ca6b86a90f330c77d36f98499d0171a06f1e429eddd57b7883f6e58d844c8f06e5945085a35ecb89957c81706062a3955784bb00cb5841e3670ca9db108d2bc4b8aac85b95b518f612ef0e6d8abec456eaebfba8dc782fd5a097e48d2856f5380b3aa4b899e01a92fb3726eeaa3d28b9f1530ff02f449b32e90ebbd8c07a5534d18418dc876c90c0a8473bc8fe4b2488832bfe8548aa49e8a778c383cbc73169d8e5012c89bcd5db00da37f168afd456761a4a9fed6136cde37326fa6332967604bb28384ceb89d98b5a70335f30fa91cece6936510498e6c5bddaf49d7d41d71822f7ef1619bc24eb58bf6a669126ae69aaba24b42ad309cf30fc30d74928549afe7aa855907f2b2414adc8c406128aadca41f468cc626c2e30fa5fb65f8fda5781df9880082aca2bb1bf272b26b45782bca9075311747cf195df9f5e83f32c6c8c04e5c9a21e4771da81b0fd822f742100805d786fa7c1b1930f8fc6b88cb0e5fbea134f27a7c6d3e0f1b8c9613c15ad151d73069e1fc9a34c06bef8e20d8794228e7c4774e541a3e08c8d7f86b50d0e2d5cdfad2fad45d017e19d815d48a052f9620e1487b9c9f3f9bf21712fc2694e46d9495e57647628e3c449e5102a0ea970838182884367bd1dc53c3379765747bebb26fa93192c1f694017141a30e4e9ca646b3b7367b8a7825d16fad5272fabfe01ec3d3605630f7e2ab4ef32fbc7291091db732c8e59c09374b9487ecfb0fda0d8b72e968ca4ede95830bd8f4dfe7a910f07ad5954ac4b4a806ed0c647c6dde493be3c03c53c877fcfe8edb1afed40e587acb616edd26f7a0b67d169913fbe6720c576c8a01dbd35ab074ce2ef417ffcbb9d94c88c393b51db8de141a3405b3221812a6f9e84c5c08601d13148b57cb92402d853df25386f78398f6302d5b9ac1db3beb07e45eacceed62c216b364a8a746ce0a0f50e534a96a8c0bdd8efb9281f268dbfb5b6a8958d245d77198e58b197e938847d1f09c7031eef1b1d8169d1db2040a908c00dd25fc259393b383d49de97c7353e97be3e7924960b99ee4a241d842eb7b9e113e4a3cbbb285ef32e74c0b97fa54aa836c11f3b231325c996d127bfa19f33f6f877838678cb48675bbec9114ef01dd396e5887240566dd92475930d109bf651812fd71241d329e120a7180a57e56994b1feda0998d0a2232d0f2ad1e9a3b332cd0fe311b11387dd206825f6a75022a9b51e2cb5a5868b24a3cd4ef676c61778f927c840ff84f16139acaaf5dffdb147a7a518bbcfb3fcb77c0a64fce0f80813c63d07c3af587e0375ba88233148b042d36cb32fc517e2f70c69df8bb0d3bc4349eb89207d8d4e72662bc7b2372a18e5f6ed2ea357cc9dcd6b43d00aea8a2964f4a9f1fdae4387bf934b4c8a4ca5e5b7e3558ec2cb9ccf2c5824c4a53d12c9df32a9560a69dc0796cc13ac51621c95f1ba9cfb82f46eebb0835d3024d606fa0740884c375fc179dd58a27456b598b5493090abd8a878182a52ca5a147c7a24cbf8fce64dc4a2abe262324413ec9ca62a03b7bbb52ea3c053f1ba761622d48ac23bf694659d72930cbf273d5ccc4dbb68f7488452cc3bca1749e53821a3031f782c86eedb767373de3fe559c88b8ca1910f03235acd16a7af760f11d3bd16ba2933ce9ac7a7ed5c8575ce790953e9b99fdf1b9ab05b28ce4b6a9e10b0c0415a1faa9ff660e05bd119d636683df671856cb3d613859c51ff821b5d6f12842c8c2b24c78499ac14381ccb7979d30039093ce5682ba5fc56f4cd3fc07e1006de8b12833afbd7ed88fa0691220521f1022a182207b50426ee4f20b8a492dfa36f85a399b6c2a45f90a51234635b9576c36b6f2adab05e43436f0b6814990dc0c5023c93822944186f5608ac17d35a22c14726d1a17e8bacec8b0c422a115d8e0803343530bce4dedd10feeb03b41d1e23248c1817e7d7ff12eb24bf249dca39679108e19d5635bc1591c69c3df1f08ba5274090127205242d35f2a80d63b6789ecf39fb24a9265d3d1e53622609ec8205daeeac434b093572336b5c702a638404a751f41a1cc078c6f09c2b1096d92e7da7887326332c4240e177356fa4f1c30758d6e6538dbf55a25b1a811b041ad2b1fee18a40e4d8591a0f5e25178ccf6c0ee4efa797c318cac3b8470eace563671c722a1e23fd06150c3b8380e569702d9ddd070f19213d82d9fa8de64424cb12efcc3421265ad843c829d89079906e779ff54bf41e4eb27b00382674c9b6b97e70e35fb29a54c7fdb72cf30c1d223ca0e1132b7469d4dd90bd0a85b1543e245e81e360dc9a22575fdb20a890ad6764cbd9d9c29cd0681aabc2ab646c6ff86c3b8889487259b5f8c9fc9aafda525c10fa50d57087503192d97a26ddfa2e418a09c8165f70a81dad2c6c3cdde19461692e2be73954b1e0d0952cd170072984b63c5fbb9ac59617be82cef0adae510c047d30c936ca060d893a8086768cc25486f321b653d4c64f81c30708a1c7bc70e8bd42f0126c9715ed6ec6f048346594e4e35dda005d31fbd1be147990bb8bdee42637d5bcac1cb801c8352ed17a4d6a009afcad3b36de6b5dcae71fc0f833c3609c51546192f41613b65e01c69f0448466ebdad5933a3d11bf5fce24340029999dc050916584da02ac556d6ad5b1c4a13539ac0d53e69e40242ab5d4a188869cb6a0268e2b49653c1672f3c077945e8c0433555485de4948a46a47b00b9d7a8c3515d842d9e0d5521a50fe66697647a25a3ada5c783dc0a3951e7d107170a179408ef5cc45490cc6beb29e61e560cc0dec21b9926a945b9c77cdd83d5b88e154d872b87648f01dbed48cf713f018a14656926ee793c158902516977c1d7f09d1605d89c97bb8bbf27d1439c815176563d0700692303166a7581a638cb2388fb10f5dca23448aeeef1ff4c072bf457286f24c180dc886b1d44b2e6bb7409b01f48e4016b28b308af57e1a93745b42c417728a63c42c3d4fc9a0fc022be11ac5278a57c1051a8461a45309a9c811225ce6b2d71dcd9dbde4618be3dd3447d6284dce037649ea522272a3c5563352e2417f1b579eed25358e53c6e48013e91b634e79f674e99db73d1cd4a69b42867cbffa7f18f406756c897d049b40944f00e203e2ba3de2bae8714630c28347c1143cdf53330380218180d8415f6d8bace8e9949cecbc9705242d000628013c3e607e0f83773f83bade48646ee96418e0843ff61002745a4942da905321e6513c492623db0eb942fac1515c5387959794c51af0f2edcbfe399b8eb821d55fa1295631fb019448f36be40382e2c5284785448ced228fdd3379135a18aed80a451e4b21c5aa94f368f6a4872fd4f46d4d8787ba24f1db2e6873cb3d72e03053b809c0d10fb1d6c599d93b66b080fdfa497f088a0775e81bae80917123a0d1e1773a269a5b5e7ef0cb51719c4d59c04f37128d6f8097c97883b1802388077aff86e3e67f09edde9fa74b6a21fc68d9a4d5ae2c7e4004611b4bf0b283c72eff7c41a575b109c60c05b3ac5d684da34d5322a1f14d3433dc77d13c82b0d426c931228ba55a3685bc459b09b312c2e0a2406fad8d70977af9955104b8c10cc60191827a840f9e781802c1ec75526aa9472924dc68bc7c3d32c1b0654eae5d360d2b8e88495ed7cb068f482562750c4a20eb8d4c8695d4dae0fd67a90da7b9a2988a7e32804a8631d3d64354c5f6880b90c25eb45d08bbe0d42feca61bc59387ac35c934fdb29971eec2b56283030ae7255c68493510b90b1f53448714bd646323b83585f6c7fe19ae6983e70fd3ae9cf9921297c8fdc0b7cc167fd22aec599cda005c3f48af723614fffa464c1531bb33ef0b655e9c7c46c47e56a53e80735bb852df001d741f4a1497b3907592b070311cf555f512152f875dd62ffca0dfe52afdf7888eebe1191d06212c2848940e437830a2a44484554ff01a1b2f16440b088572ee47da9e93138a2011e3300cf296a41afa2d2bcec243c96a4e0f4d91187103e2f0c55621163713a65065245e9e28402877074b2e4a03b18543e5efe6c0a98fa26cd5732aa40949d985188282315b4ff01d88c4e9d92c7f5c19fe147f4b31a0996839b64557e2488c30bf8e35cd631c7bfe87e42f2d71aa96b8888273f2a348b352f4cf9cf10b515d237ed52852559e40e83e27b05da62191ba4ce14da27bbc68c53f080e8e8c036c7e4092b49ac2a6c8154b21c92250b4ccd8ef019c94818cd068fcef3c84997b1ccf6171d941d405b78584b913b3677bf8cfe93045ba2f0e8dfb5de9c63e46459884bfd9af04b55ce89d6e3e2003c8409e2366e722254efc16a0f32e401c64a283dee96070469a16e28da1435ebb059f1275b35add2221b5836c5381b9a8876bb687a2448e92f3c01eec839f188a8719de45c6f2a3740c7ef6a79d250794fe4c5bf79dad2211ff61ef5b9c72b06b98f4c47367f75887a4f00f91d5d8d42ce925d503b43068e947e608f87c25ee06f161f0a32a9b686373a409f75e04739575731047f3de8caf46587143353b8ec9276a70cc42a2b57b87c48016d4571d5be30aa6de0c18e0e51eebea073165e3f77ab647b565aa14e27da9d9aaa03a123b0e3da56e07db828cbfb31fa6355cf105bf849e84408b5f01db56961c419f907f57b28038981d034ae80aeed6af908fa08f4045b91ad6b85270b976b68c83f16649d4728c09ecd8efc08275617b3815782e4ecd02db2233f4115245a44bdad5792f582ef7c36cc3fa47de14291d63cbc2f55b5a612d0eb5f828d46ba990dda943417b0b01f9e452b6f01f04309e807eb139c46027e56471a39b4815d610a92602d134980073c583b46f2baac672ebf30e66d8829d6f729f38425ba114305930f6a35427ed01908c958e45749a295a44ce3f7dbd26c82b50b1c486b25db659ad584e8fd1103383dbcc0443fed63c563e9b9e121b3e1bd1191b6d8c2b3f6a59dfda95c2fbdb84a3ece5492aca7e43f1b39b8f8b4ffe24c491954f8e7ac3d53e847e5df307eb453fad65c3746151acca9427cd06379858e81eedecd994e374c75e3b91fa017b547f02440d81fe091b6e2719ade637e12a7fe21a81962373f9142b522026e10030ff48a003dadccda9abc5d321292377b7ab9168df0add2ca69e41338d807c206985cf1999fc0dab041cdad4b257d289f993b4592f777760e6bb8f4a832135d9e30ed6dbf66a2edb94feac4bcb42a0d8cdb93f227b88b9792981295902f407537e3de9c8e23cc954cd3cf6dae78314191e52eb9fd3cc940c9c608bfad7a91d711baad88725b2d23f78d4b38a6895862033c641b44c8c1a740abf9bbbdbb28d0e07372365e7d29054fba8e4f30bde3bbe0487687e42e7388bbee3921f5faa30ab4fac76f85a309bae49dcbf58887cb84c023740d9ea73d320d90b60f590e4c62809e93961b3e4cdbdc2312a1cecd1f8b62493da7b9d70b1611acb05c70dd55e1700f7905fbbb7c5aa7b522fd2b9f56009a69ab3b3f5079d918cb1342c1831b67eabbcbfc569c0bb4c6d0f52904b887aefa9466ec3b787be4e35d8fc53040c7cce709a5391627b766df7e52a29b397d7b4f66b7543ab163cdb850e6b9b16e34db034b914733c5a6b085e102fc0ed3c5a7a0911dcd222c831cc6f6641a895b4684812463522cde6a88a030c4b8264f892da27aa8fb03d7ca7dfbe26cfc2129d947e7527341acb86b55e6e23aacbc4f8bfb41ba66a3c280ab53045b98455624d1699a583586216c5eafad779de9e7f192772bb3f51286e4053766ffd3bfdd7091dde1e259a3d58fd9ed185a533b037a68c5080f1d07203470ec01f6146a0969971215285d7d271e1e0ccbe483bd8210dd5d60ef0a68975ef5ed0f5a37d64d74384c6c4fef9b2714df09818289394890c9f87cc5cf2a46cc895ffbc54cfc4b47d68cf08b7a41d1e7bae89595899624ee2c61c384251e2c0d2e86b453358bc9480f0f44f7a884fb38b2661982aa730dcd40be57a73b8ce9c90860294a023e6e8f5e7b1794bbcc8b075908304647c90e782db8e226555059bc22e2d08dcccb2bc02fdb772d4487762b4e188af24db4e0490d7477243d038141b78f8dfda8a589867f25515f65f0acdd253eb876d39964bd8366fc04a5287207accaaab356a7cec8df28f701b465723d37beadbb9358687c6fdd80a25deb68c14222cd2c5d343f5aa86cdc69465dabe71b4bffc35f3be0612af0b787036554cd10c00f551b77ba655025bf3ed6318b129407ff1a28c9a96b5d1682d8d44cdde8b44d07335fe15ccdce882a56694ace6658a5f887a423c7111a193c6dc9ae97fa63a684bb40c43557394725346a59f3f87a127479da811e20b5a87af61821de38f3822d50b148ea84c4bce72258be655a8eaee2ecfd38b157919d5dc98277117500c71b2a95ff5e6eb4d4a9997326f035526e5bba4c55ce84608d7b772ab514f8d27e2e83d3740d6dfb82332768a0b2abfeaf58439530dec48965ee74d0250b3302a8f8cf6643192013552ff9b1796a06d9141a3116fe8e6ad25bdd5820851ea58b2f59f9da4d936312a02610add42700864cd49d354a04d6405c72c28e60a8c962e99adf7832de0b63000b189ebd5640d216c4dd3b544fea7abdd8bfe3f5436d7a7588a9c67a062078adce88832f84da4b7e26a340a288ec82b267c69b968a7d532d1fb99a359fc80aaeb1b4c906dc41eecb26ba68e0de01f0c8067a3da37414a341e9f0de9eeb0f65f3e4a9c7927b0443968e13d987739113ad5165ee78717a7ed307a2f6e0b90c43d611240b9258e5c7c1e002b261180d21b161e97316bb030c64f0f23bcd3d8097073b3bebf8824d81a6ea48835238634e16d4810caa6dc92094538a51821a58c9bda9a307eb8997b424a53c09bd30299c3067ff8e78807b5fe6bbba1fef812daf3a641a1bece7b3d97220b046ed7982a6298a7d1f2247ffc00e82a7acf01f879f12d9d82ebc69cd0469c454f0f49c6acb32a3acebcca4fe384c2ef3b1862feef9287f95db6968f59d70fb7a8b8f4a8feb4aa283fd5dfe9a15b8470a5dd1f5be314491cea35399b44bebbd09574d0aaa83015c969ac666aab9d61f3346651fa712cb668250ff2373f604935a14fc3cb540d47c24bdcedc2074600cebd76be38ff9c4054ff3d0fcc71798fd3f00d4b10a3ed4a28474be056437770f5701716df38d629bbcc04a7b82163cae02ba732f05528227edae3a871c924eb8770510bab158413e0f57c151ab184f79f9f147b4b2bafacca28df085538cf3b1a6323f847810d70df49bab743bcef9c3f366b0bd3316106be160089bdc22d7ba123fd79150ecf36bd2b2cee37567a2fc27e37af86ffa1b6ee78bd4491bedd2bb691b2bd2084c1595c1bcd7312fc28258a958d31adda18f7979325be074826c4b635e70ed19d1e9185ae6b6a03fb8a248dc635ccbbc08a1375dd01644aed821a033352e47bf73ae8a754a59380fa5538fb600cd62c1cff5786005002458b405bfdf3a59568ac0bf7a0de766898c7979c66f1af0d04839f6ef8aeac48cb9c6ab5b5b6cb65949bf2651bfdd50c1a676fcdde40d95258ec76d9a94dda14503e6c2f790a65aa07392260e7b48baeed204dd6f2ca6e49f702ababe3db9475c8a5b54414759de2c879c99e2d5cbaffe9afa9c552b60079929b277a8d83072a0ea81650dd550f9d08b634a94638ae43b7f018e4fc320aa8daa156e4bdab74a3d78b456f059bdcebebfa0b4400bbdaaab69469b7c7398ed2a922503dde1822edfd54dbe991c5f2a77a9d2f3b6144ae0c1d534441c608b87662d5bf02176fac88e214512785c26c402d1e056047b5c83ebc40d02578a0d722e657cc0678723e0c7994f91e890e98fd8d082be87fb58978b57d9edd64c553900f5e4ad95bc778456b4dc3eea05824f3fa16057d0fb067e5e0ce0ee814b80a81e425de498bd0fc1bddd970b4fe3a889aff64b04b6ddc0d26b1403c60b2b38416bed2d70513b7e901f68d2df26a3f91f347afe5dec4299ee6d84b07877e7465c85e0f6d130f51519027087d85f4ebdcad6daa600d9afb4e319f4a722c1c804e12ec151e75766a328887ebbde4f80a8cc09bab504cae6e252074dbb2c1af479361e9d55c15be7e6ea9256405a1ff50b812c3dc6773517c3e4ba32cfaeab604c410988e8235e1e243fa8312f903ccec30a73cf2b3b6283e2dd4c43b57aca9bbd34d2ee993048dc3ebd3666675dbb5e172538b4ff543f6a643941cfc4a9aeddbf821c11c1011efb2cd18675972156e6752a65ea039155c3cf85c39b39e98a7f03704d3eabe9d17bad4261b8d39a6a2b77d4d1480fe778fe7880a23f461a85d968ed1e5459140026070652445fe04a5548e4757be8b4cf2e7038bc77e61b3aba550b90c6f8d7830ef13bc00fde103b428716cb2a48aae8ff0dcb5509e163806ee14bfe4cae80bcd2f7d04f582067c7976522b36a5b5097e45e7a9a68e6994a65cb4799c4daf16be6a32883c463c5ada587d23e8ece86280823bbb33b34d46cdd2e0ad929e039e48e0953dcef4af7f99d297578d7a1f96225f1c35f6ecdc65fec64f1e989f7098afd5dfabe37cdefe4aca747917fb79cddc5b8e4d9ac0bd2bc786ff793a094733a614eca9447d07d38df07a30257200c76e681022f58fa86faf0592de43af03f21857464424e8220ff1931810e493eb814abbdc9c235cd6b1ec6d76707d11a05d38f8771a597639b4e7d9531ba219cb8574dd59b0ba0b7fa9733d6b027ee6946a32460b23c93d50de4afea1f1f2b1c07b2026c54e732163c02c07ad73c4440fd0a3cbd4f1aee67c5c6c03456b2b76e2114e5578ed6ae3e6ea64a184c6a51363320799bbfed730939523f369c106186ab2efac11fb682f551fc04a5c9181bb489e89e23d74f3c80fe1fdfcd825bec8f8ca52b8fa3e42ddd5410c3fba4d2d4fad1ed24c8af66b16bcfd19c95d85ccbc2a1e1e788488752f71d59470bc1a48741c975d9834730afa13fa42552bb469faf9ba24fae4bc91e9e426eac5c3d3b7bd8b9b4c71ec6773f87e2b48efd79ec61ebb50c650f98f93b662050f91c455bde770e704b86f0b6716b14c9b1079d279356da66468f19b9afe831d4c68c869f0c7f3b3ef5c641eab0077e7a2b3ec9554b23a020f8154fa5aa27cb15bd9432c4d61f7a7115577fc56d43f2530f6f28e354819c09f450af073b964190e0a2134aabf8bb0b4c70c35be04d5114bb9209dfc1bed402b83051109446b91e84d74b83e389e7393570ec5454a35fcc3cdf86a157732cd0b1db53b9d339126a3da0c69a6722b8e699ca31939ec2acec3e21c6c1b15cbab8dd01023498900ec874672ffdd94fc8368e60fafdbef5a10a15634183fd04355b39982006147b0b2dfb58c0d6f5568249e510d81013c90f7fcd1974a5e4702842370056f6a3441cb00c8857024e30a3e47209cae4a5b4eadca1a7d4038cca4f8ea571ee81a8ba143e1dbc091b79c17437b3ad7db350d8dbacd5377d53901f0011c62df4e633714a9d87efc8d00f7e4d7fe2d3a54656d7f73233415c12fd2348c6c302b6b48308ce5f63dc0369be9bf26334011e74198ca4f388ab36b8ffdf6128aca64c99a1be12f108f25270634d06291a553a26ed91a7fa49ce5d4ad9cbbcd2477aa323b4a3d861ea9284091b6e27898f07bf26c82e15a428e2c41e986b2462a2b1678a3a89a8864baae74220ee8a5bd9027416643591f13b0b1321ed3e38964da5c5a9c3e9982789f155bc9b8a2ab98d15098c47f80a83c71f256edf4a369e09add5d56b111a099645cede774f8a3343a22796b25fab1b8f3496313302528af991ac90115ba39c080e8db949281b0abe409cad3daf02823c504e4ab327d66736e86c6bedcf7f0aa6fc290c14c2466cfda9e1e02ea5543b39a45c996edae986540755ad697f0cd8e48217259e4abf3b14c02c188488252d83dfe9354120b86a7cc94843b85ea8e930dd7c0797831bbcadc8a79142df3b1580e1357d257945c554c65b1aa9a2a63dde8a0d5e01a5e6025f1dd81aefb40183b41b13feabddc4868894c7a29116d000584e41f429e2ac9508d0f7fb003003f951e0e2d74ebe2f6555ec277804db2666b93d032f0862573e744e1379e27ee1d3190932cac8dd51fdb022a3a35d4fe911dbd7ad0ca112fc75838bd37088a8657cab5df602b43f61cdba72c0413c310700371a12a8d06939d8b8012f86359c6dac015cd1ca4f974b0844bace0287aef255b7da1b94abc7bda299e45eeed5993a6f04a592ba0209359427f068486f901422b904fda31c3537d5b417a3b4b577b123acc4158ee23d04b590495148754232a741a684103a614a6d8d2374e2f0f47cc5a847b454729a7c47aa9d7e641c73e11c67aff39d90125cabc37e5b2ee4ca5cc723a62c3552745f13804fbca53dfc6cc02670a62c0a03a988657b452711dd2119351ced8565451e01753c08a0b97b6c381ea41af9885a491b99f5434fa54fd7e800eaf3c752ddd6557b1a986185cb8d4308e0a579d74ce0f39eac64d1cf3e7d238ce950534ba87ae5be15f99388e597a18912194b12a4b874647856d4f8a9c437367b859fcf32194ee6d0a8c2fdb20c6b014337c58fa9d56df10db678b51e28bef477b3b90e2f37f05888a3513aa0c8c52d8500b045cc2df519c096b248b6565c65712bd082ab1f1dbd94eb0abf8ae96e0f36031b1f87bfeb606e220390970b4487c42cd95a2cab6feb2b1563085f6d0225fe039cb3dc7d86a73329c352a423358ca78e62a0dc3d648f40674e6c9810fb9ab341aa94aa2cd71400e3711b7be569c599c2d343eacc4c4ce4194e1e6c3712719fd060325c51e93ab9ce695b346401813c1d7759d0fd30f5794e0867a6aabcd8ba91f40d4feac3c9684ba03721eaa56f71edcc4c57ef967fe1e59c2cdc7f4e16d4fc86fa4cae3936e4eed4e857346ca24fd31496fa3663131b5046611912fda6c4a2d5f19a16fdf0e0da47167448c6ba7777615307ef3241a0858b0390b1e6d30f6f17005944155a91c113a080b7b26309c927f81f0149586ca5d2458c528cbb35172bb61e5e1dc50e531419c397d4800f49a9e3e710b8b264152ed58d49b13baf3c10e2ca25bad2a2f1388f038d7acc3d2dd71f7153d95d8d86efe4031cc2fa4b839d2cd42723ebc91d084921c4975c981682530aeb05fc12cb3634bc4cd318974c60fd6b97bf80eacc53e8958a5e70da64859001d96d67f3804002f00fac56837078177dafc880cec320ea7321e1ef7dee6b617a05b00531b2f79e32be7a3428263b45f9c4fccf40c87dcbaf10a0c2116f63eacb4946b66c54a205e0806d895c8aebad555565ff8953e23d611b7abd19279b35303890a37f6d6d064aeecf931931f612010ff17930a5361cac66e82b7c4004c148528813f86e64ba4aa2e231dd35b49ca52749b4fd68f15369a52aadda89a0e18a43e4e3510d90559971b705404f3650fcf39723a09ea09cfeeb83914be4ea925169b0cb42412cff4b48b2565262aa71f3f850398e50d36f873df0f43475bcc3337466210de0d0275af17a6680b0ac62a037d20838f4c87e43892d721e2cbbae05aa655056ae875336b39216d1ccf49fb008fc01165c30452c5c98a3ee49620048d6e29bcc87e1d35292eb824aff9fe9c90d19d67f238658d0e245aeb1cc719e390446718906210e86a66308c9b10fa9f2652590cdb9073cb59d8404f4b5c51932a1b8c791f0edd9942381a387055f4262cf9f42f02b2507de2f9e979af72141d61700718ceaeb208e421f162a4c8c075e95abc863160dc09bb8d2bf01ceefcb3132e2a5127e317a16ef29bf16714936ae86ef85e75d67be71d74880d865306f683278641ceffecf57403c3321d04e649ebe8cfbfdccd9a0acab21870372f20796a60785fa8b313734e93b39e54c79c054647b31aedfa05028e8470202bb54c117e22a4b4b01c5bda9c4758414c81e35ddae9bc58f2abd3aa7ca41a8f98e2b2bef824263010714be9bcef7511a6170e7a592a76a43c5c0dd5f16171adbb16e1e6068b74ec5afc24ca4e0d2729790b1c1feb9497861f72a7ee099ef092eef9156e5574fef5ec047dfef7c7ab5aef87155d4d01e42f86412db6792720729f7011e877526d95af7497c669744746cc6b2291a8e9668b7cbde2f1451bc600e27631022403813bac90651488ffe5139d63ca5719f374514964536fb65b48152db3319a9e6a8661e0fec9167191f53caa1106c979d58984cf40daf47e0006ad6ad1826abc0b41f9ed6033c5a394c087f150803abfe363ea784467ae8918a6bcf410e949fbe9d1cbe54a17e8ac8be58df25940b97c4dd81c882e654f795490c299114f2033ad93d55c5cdd3b242f212e0c2ee6538627026e77980ababdfc79fe2f7476e3caa2972a027510371a5620c3a2363bb682595e35f7ed3fcb31b2c19be3f3be0e9190e356a63f961c114d98886b94dea3bd94ad00e4bd2f09b8cd9d0c6a44e6e875c7ce58fc9b6212c6f773daf6487885f2ceeebe9d8209f6a1f34869d3876f88bd3cb3ff54be3acc44461b65f257c4bf64fd7323882859e924c13c687103e554fc83c1e18a36e0e674c29ec2ac3c982b9526bc009e3f00cf9dd1f026e61287ef5f60f60388301b7de59101c07c8e464d5cdae93c0fc8e817b34aab79dda6f49652a131ef488645d4ed8af707fc4452a9682c5839991a34d80ceb9b8bc6d4e41f0c4342d32c4767b7037bb74f71c3ba81741b76a01da7280a3e5fb340048f8afd65516ccad6516ddb01d00bf0a745f067e860ec6edd38251fc5ac7f5e6c036cae4d8c2117220f8d521c6c25be4a13ecbb3dc6bd39c69ec09b8c446e816f79098b4c64500571978055e8fbc9c255c9e81805f766f7babdd66f7324cabf52070b044744545057079f6fb3ea2ad89eaf085ab1493b8bd89d966c8ede4e9f2130a717984b7ce730631c8841dd73873f976ea4063b7d3d5172626417b7313a5a1a8770c4ce4e3799b492ef4116cc8fd6da1f8cc1d3a07b30516b0bede63ca17e91eaef962f3d45bac10d0f7df54b1ff5bf2c1e2acef482cd0948e7c4c7d90bb5b1326e52294e1884e34cd0f4477663a557bd44d46c2c1d0353f0a9ac7a84fdb62efdc7d18be1ab3c8be4d0f65024972d4b1341040334d81ed6b85bc7062cabcdb7a27321cd322c53b99d331e866bf2f50e9920558e7331421924e38c7c1a4996b80b2690837ed0c16bac4b80bd8cacc12f963154431bb6e69ad7ef94ab0775e43b4521a4861a642e0be8235e41e887b7a087b193e048cab5f7b3743c2b853c1ff51810de6bd38e95e5a37c32f16ba56b2c8b4a34115543448873f1e79af2d8143d898620243446ee1e9f07d2819dae0ea771d148843812f44292534945281805c51ceb6cf54fe807c7887500f86c1ac50226a0ce5871c87541f4f8990831e221ca5f57260ff9b8b050f3484e376b259fc1ef016705fa5804f2320032351a97e4d1f1581579ee0af6f1aaa5a90f6e8d48291e9cfe1def47ec1b2c8666bcf71d859452e296fce0af8bfd306228f1834811f62a4d5a3cfe399c0de83cb46e67def642742c32f0c322be04aacd6d6e66de5d373c7283070a9afa720d1bc906cefd418ad875c187645492638d3a8a8f9145dd7b746aa0fbeadd70cb39d0b46e050bf9b6933063cd3d34e4805721bd064889df4b15cbeaaab5aef356526df2a2c34d5a05081a9c93939f3cdb35f55557526ed3b7cf3f9312b989a53d0350e7a57f6986d1c72c03d33821fb4aa94dfd4a97d3744ce0afdb2a273b9b77725ae016df730f1c94825a7650b139061720a73e65257ce90c7f9fc02a6219b40de4991686517bd74e7f7957c24838f8684480ec9da347962da4187fdb0b22c234b8f930fabc60342f0b9a39817bf7240ef195f19f0f06bfebbe868e4c3d053d5f2734b361bc2cf250e5d479e738dcac10b3de9f900e6047eeba223305a180449e1db594c17fb9cab92d63fe198a994263a444078496db492a78deaefadf9086a9940e3351120dc1338aa3ae3f75085be0c4d89c2d3285494e8bf454654c1879ca062878bdfebc05082348495069eca0f3f7d8aae1ddc6989069c05fba25212df98e2843b0cdebe6edf56c98c5ca3f05e9a0a69574c8b49e274198c68079335e0dca6679800257b0771faccf16680075a448596bbe45c6bee39d6fdb9457e5c441c24f8245961bebf35ce365d1477a6c7ba9e8d011258f136108d1f9cdc9252751029e81e099d4c50033556cff0523640d9aab457651aa7807fac35a682eccfd61f6b5a63b1ec302829eebaee50d268267dfa7609285160441f94513e3f42c9dbe0d31438cab61b73eaf40bcd0765e8ccce9a37d42838edab0f2db60e5a89ca6cc69bca8063ae07803ee3bb303db2b4b0ba9620e3a7fda4bb96bd60938735fd35fe0b470d0da856f21cba672908151e02d683aee0bae1465d2be06240bd6766b8051ba81aafd4b5f4503941257031df6e9c39a22673c4eb7c130a52d9bf0e0a147c87b9dc70e739818fdaf23fe0c50ee607f96f764a4252176fca3d4e89db06654c8c404165fc02b8875ec46d4b72b04b07429067fa8327bc375e549cf8d5861b3e18fe284b5ad00c01cc6ea8d1159ad8b3b403212a55462859ee04b47b420b46901c177582ec1ce407f9f5deb96da125c4a2ec8028436855109d5768501996cfabf4bcd5b9ccac09060ef2130a0d37888e3e8de17d82aa294308bbbdeb41131dbc831945415f3f336c195eeb69917841ac39b290463de589c0f3f5be28111fcdddf721a4e441a2f535709ef85fe38d24c51d841ffcac0d851945093234ec25abc1eebea87b517224566bf4c2821a0506648b6d95af002d12cc3be0d30727595b3c65a4b38b181d61cab2f0a8c29042cee0596d2573c0beaaee459b0fac34dab6ed9b869a3aab65fca885ff2b1723b920eff07070fd41670a74fa3f9c8181862080d7b14237aacfda469513d951b038cb3a2c19830a20c4bc1392ec9f68129d843b16c838d520bfdfb7ee5fd1b8655d49b2d84c3d8627702ba50d0a53595af6c66d3a8df5e6b1b94b0ff1cf47e8a567ffd2451478a3d59b9a32647c828cf9d54e06044e27e0d63276c4cf7975af335fa10eaa2b085244db16710286684d3823264e34b419cff2be1fef4eed72457f981452998b1f83e2664730f0b515ac12d6d481751d60aad094db31348b81a970bc84ead1e146df973899ddc8be3c0788525e5027de2e0917c784805aaf59a6e8963bbb64cfb422910bc66bf71e6bdb003148940a405e4684e3d777943c100a97674552ef2140ab4951ecca5d86ae21b207058545627e4bf5de609de8615be7c7dc17d1c58ed4557e7a3b75ce06db7c3f5e11e2d73455abaccf9c62d773f8926fa97b08a57903372a4487bc1da4c7f0c27eb291c44817de85a98412e858af8092f219715de127014cc49c5a13c15a07e3866f3b044fe9aeba478357ae1b54432969aed24cba9cb5a2417f3c876873b7e84147b4c0c81c78797afa8e44dff0eefde7bb1fb2149cf1bbd633462bfe302dc240d2fd8b229b56530e025e539cc75301c8d467e388617284302f1741214dced48b65a76eb5c840ac6adfdb94d075999647d2a3d4e7c1c2c2fdf11f52333baefa780843f1f614e3d241030027445cf3831c37562e93d3aa0612d1988ef4ff96cc0e398a22de77afc7544b8a521e1a7f9cb5d8d690f2e2cddf74495868bfc38da81664ace3bf9bd3598aaf5fcfe203dfbbe975157f8dc066fa1b7b48f911fd9635252ca3aecd32503f6293b85cc03a5e059564ea5455118b9fded6a18f5ec55eebbbc22fab105f42a2e26b51e46ed6652d8a39d6d98bbc3316424077c37e3a91ef4855413b70107d399c09ea70977e5f3bd5416642c6e06a4c9208c72391f00c0875f98670cdefa4084c8812f9096345b19a2a51df6bf2571f0d34e1508fce3a7d4bc456d241edb293b04341f9c2b630a0da9a6512e7d89f107aa6cd5103c56552edaeaad809ff10d5e99cb918c7f24259fce46aae9ab073e826aa3a57894b665aa7aeaed807d14d8d5febddccf42c9dae5c8fb17ee1bc51922a303f66356d780d4e219a2aa869b63c20bcbc52e17d65b433128a2e9239227da42c39594554e2c96bd5212e1fe2f69e38501eb44b34ecacce854f9d1ede9f2c4528804c67023d32b1c5774831959939a1718c88d0eee024888c00a85a8b18839a1a0a764fd2539a4c682d3f7fcff73b343d2e28b202911f65c194736c6c1ed1260548d8f06a3b1c178ff02e3e537b4bb24c3109233d61f74954e16171ba60e1b6fb07520f217499296784b72707d828b2ebdf5bcc52b6cc562908491bcc78abf7d5245ec734dbe1ea13a8f4824f9835f2646a690200522e6b9ae139e7d7220b6e6f0649bb162f9315c7bb9baea0a6312cf80d9522d959673ee81b8de597612bf45f4a5aa9447a1e516b599337e057c12b95a5eb179df84678c536ee3d00a92f22a4ad951139aa9cd6e76ad8705ba67cf60bb2e4ba83745ec86770963a9ff3e066cf00afdc378f5384adc06d00f6efb4ba179b640e2adeb74fc8ef6b073d8e68768cf20a38de258b1de74de4d65a338a8c0aaac80668e918a35ffc5df58e336a7e7752491974561a186ff35ce794516d68fb0346c65b50d95a2d2a76a93b1ee53a0d0de1e45e1e10c721d75ccb82e4ba962a933c05fad776f905e8a20725287ee5e88b3c8fd7d0465f5c5e1f0c563b8440908595ba786b42d126d963bd71155547a323b7f830af4755394d5eda99fc5144729d56d218935283835c20581a2750b665c687ee5b7722138e3f564b4918492c8586200838a979efdb486231210cfcbce8865381374ced6549fcf672098ad5bb2dc0e422da47c58d8a0240c50f9b41aef9960b3cd8b34e60f5940fde3897c382b35b3de79c6d168171d4727a626234ace03d67ef11783c8efb9738aa1dc6344d32a157a49ba1202076497af4bc556dd685cbcdb7af8935173d2928d2907fe04efee7a88bbaf45d440d1a82d7a0a148e5b054038633fc9d982665af0ee7ef907f6f004612681b00e54744ae6795f58caf4bfd3227bf81337db37d1a2596680a2aa637833b1e643350ab738980e3eb925e15f53637d476e92c48d58117ca8a82a0240197c01381d71fb7ffc0958391ac36b44b61b3318f3002e07195e5c520c51ac2628c72bb1a6808e796ff9dadf0811400330e25680040589c0a8dc3b1ba74a37de6cb6412c4e366d7982e00084f42be37f3ed7b65e9f7473cbf5b89650f278e715f45796ffdb370bb5e1db4e485634ef0947f40c1d8cbf740706988d47176eae5f36a2a93be1dfc6e3c7fd082e5be99e0fa87eb60b45dab2f806350cb24091bb1a6f9ead03dd2c48ad51c20cc6ff22220e7ba020930c0b808bfbea8b1afa0e16b9faf24ac6015a49b529b31cfb174b4d9eb29e2966ebebded98165f2bac21872541ae705476530d2214d77c46ec0f79abd702474c296d5c07e1bc12ec1c6d5893219acc754f528cf4440367ad8d2f1450e89e0d3668f89fd6921f141026cb9c8bfe31d81af39b9c53d72eb29be4e603814a26453554c6368160f21ceadfdda2a651ffeff989961c50451ded1226ae4cb8be4fa5cb0184894176d0cccf800f9875cba814ab12a84f365cf6545c36a9f4a05b20b92c1e5cb2b174743af0025978177c48949a0fe0554c15021872c6e99abd0f6bec8c4fd0e9935aabb54898c592f19a473535e598f7c96666f25af2db1d6939557a9abbd68b91dc3bf5d69767ad1de7b7d51af0d5d65a4a82158d245645b742cc87b94920a904b0e7f61a875ecda556420ed6ef36c5173b2cda3b931109b50d168a57ba8d2489ab771ef5084804c30c24bc5ab2f7c5d3c06a18d98dfd2380bd2be163512b524628353d786c7d6571f3c351c6f866bb25c5781e28ec655996e81a29d932bdbcf53b218db3cbcc859cb24da883bda3c8b796f465117ec5d8106c2b7342bd845cbe5f626a90669aef0a83e15d052dc61d589b190e8dee265c1ec8f81cf678355cdf4308e8fc249e92f1a16bdb769d6a11c54dae6a795fdbe81487258e8607f8cadca656cde8507005afa2b5fce50af1f71566cb0289aab6fe4deac6078590573373b811b885d454bab8865611345bd22dd1e09dc459b938c570db01edb349f36e358090a6666a4056139a32fc5523d86e0869e11d4d56ece75cedcfe7ed912081303adbd2a216e20fee9e4344500611d072f15d5d412246995d34fcd53814e28737c0c8e1354f272c0537d969e313321e3445f8b2b34d31dc6a9ae604731a9d11bd7b475f6670c106d49fccf795233ce07d67e0331f80c7f66e98d8fc5e4454c5710cc9f979150fec26cb0576330c3d4d17010aa7b37f6e14944528bb5b1460c019003d265a5b83cd2ec2de29a05210682144607c1b5edfc4810de7c2bdc1a3de30581e392161ef6dff2ab2219c48057ace97ed16b0927078ff43e56845a3ef55b74f450eab7e2bf41aa1342964c3f4810ad7001101c401414b3c9ecef1f28fca8e62564983b5f7a9fe21520d845620dc0b7f9b3387c4ec0d8ec32df0b02697e878056f3ba3401a214e11716102c35b21819fb52534b890502d55b6a2011a543f6236c7d0c910900696b998411428982d09d00c1aaedc7ea10ccc69fa3eb6e41f36812a233e4171a28b398d5a59779a8df512c99e77d955b377c86318917dab99b136791bc256f6241dd9a65a6ae8df9b15e4f67dcddb838b0064c1f3049f9079c004365a9babb3a23cac228f0b7d8dffc3a076147036baacde0002b5b369d3de89e447fe8cd7912ecb4cc0d78556d30700f33c0419548a0ef7db45d107efc3d6c14b9b1518fa83f70693192733756c4cf54ccbabf61d8e1b011b6e1988f198882177bf3397557ea1d22172073df770dacc069a3a50b9b0a30a98d56906283b83ebd1d7b0a437be3eee15d76ed359d33cc3230ade9772890729953468fc622936d9fbb4892d6290acd083044ed24172efc19bf6b148b1756c18438d6b10a0ed8c79dc06a2ace372e6181cd46256a2751ad05080143c25aa9a7f9d3014d3579cd263baf3221ebfef60a71d36badb87462c4c0c248904e9a482200c71c1c3f57e88925e963b8b404744a5889fb74aeca4cfd77c4f4d5047fa747620984ec47857d7ead36a2e5f815ad2e4f15090c8784f0f999bdea3870e632ac04fcb18d52625f702d7880ef83b4d67ae8b8d441d41e2564da2f5b824a65f99c823ee0e79cfd575e0b04b6ada0318e6cd3d951857c728d74150f14ba647e00fa69cea269f8ea6110d315fc7faa97695be443128a17d7c5d4fed721f14844a5796ac7463e23646c75aa2f0206048eb2b52d34b84e9a590da5226bb356c5cf73f26cc35ac858bc6ee4cacc281b8d6a025b36e8d39a6bc2c4d5c2d20bbf612ae1aee2a082045b78d1db57b3a659ace1be4df7050be609b9c7b21ee6ff2443dbd042c275d3420f912144e3651fe8b651a7c4cd1bc160084653c24d2f90c972050a1424c3541d587de74b862a9a9703cc181e25cce93d459defdd8467dc14b17a00ea52af6d27db4a950fcb7a67921152e0996978cd9bafc919a00e66d4ce01ac8e67c86dd5502a2db084b403c72f54e8146f8710751ddfe9601aa933a19d8cb339f6f7b439b504f72d685b8880359bcc10d38ec501af4e09193ee024d8036c978a8595f61964973ad8ccd3fa45c36195572c20d729fe9226b7a4eb1ecc3904f6867cdb7c72ad56687918d31dfde304a8ffb1dd03dc19b10a22cdc031a42363c94a94ab3af405ad9b411fd627dff878d2839d43191c8c448cea00b38afec3e9b45b11b345bd9c5758b727b78213a748d3b361420d662ee58015826a08244b0be0036d109d75194d46d69ff884b9701bbad31c23801d21c0b15c6a3b33720604d7f64f891d7ea7155364818dc09ca66c064279ee9cf3d3778c3e1c88001dc02257e17bc1ba436386e2e00c0a71dd5f815960565d426b54c318fa3b9d367d3045025702dbd9ae883be8326dcdcbfd340e5947d382cf504e92075a6cc892a6764e05b3c5a4003f82b863bdf1fa52b6eb6044948d82846ca6ed29a70dcba92a4d17cc2322d0aa6813d694437e39e44e435434c4f51efe7025cc515b34542e2aafb0477dc4da9c5c4eaa538be112852b75fdaf98be33a32f2e09e1202b33dcf88eed46f96663dee0d672edb2efc9a52b4be9d562ad5b8771b2ab07e28609bdb3eff0f55814a254e9f20aac28f950e500419e2895398e39297dfc2dfca574e402e2d056bfd14c630b332c7de3a8dd06c84f1a809e6fb07f7e3a38d7611ee0729de00e30f9e3ea3321ece91d24c07aa694d9da3c73989a32ee10a5e193ebd8037a163036b38feb89dc10f3a2b07176e97a2cb78f91a74b4304287845f9900fd0f90615170fc71224ce9a720cd79cbf0cab932ac86398497a047204c803b04d2be888f33e6b76a766f1ec9d76ef596fdaeb91d99566f916385038052300b05a07e90b76203607957de46ef74634ecbb5fe029a07275933d26ae14ec2667df5bf7c2d46b50443341078b55b99dd611038d599112a9d190285c936ad3ce071577f62dc13f62a47a7e17a49d4f64d904fb5bd736c79e5e28d58eb4921bbfccbd7d598ea1b762362da769a707d9c537bdfae4e1501009b6d4f01e5c75b326bf1853cf212ead18bb48407a974cae2f6812c899d712df7a479b702e87b58e2d150f84570e6a8bc7565651ce50cb0b18490a5167b53e7ba4b1512dd723dd3f7b23a08a4859706ab0223f650f095aa300a53e54c4687592216d721c7bdcf1014ac3f91ffcbb644c6ea1bde4d868ba9fda109978e96dc0b9a1d8222a1013fa6bd64cc8394f33dddb452f5305b54b13555d8e9d7ca5fcbcc9c13bb7e6f7289e8a688907f5dd5c0cd7cbaa53f0e5702910f7ca475dbe12dfb68a6855421b2473ffc535ce0530897e9fd729ea23169603935826b84ff623d7c6b934a95fd8b2639f3f8bf9129032cdb7a640eeacd492d49e5c2c573d5f89cf682a998551d23219f61b9bfc90f23439326f6a9de19108f5a0166f550d5aa0c3298bf0e9c16c0a2c580a84cd6391b0965474263b7c99597b8ac4fd75d83efc36ce7ebd841222dcdf9f7d320a90ecae6ecd539555fb6fd3895bd8489cc323136ca9d209f86b3ab91e035a31ba17222c5b20bd198e4529c6ab8e2cf1e823f79043317cdcfab256b954da09241a4b9886001bc8b0c7e4e561db84196b3e44f5d408ada5e11ff4433f9f512062f74f593af57cc28c0a0d3e907b3ce18017afd224cba95fc0a8a5e2fa588e6006b5aa41da15a04502580701d8f27f9fd82d2e977428d19a7e48f51549d7400667f8e0a979b1381760863559ee89bfeb03830c5809c4d4d9f086a631482864cdbcbfb22780b735666a6489c442c1dda1871bab93771c5b2a35205b4a6201f38296088338d1f2565b31e4d7c3e7c0f715a215ce0e122c4157004c84ef964f95c2cfc4ff9d642944f64aab60a0d7961b4971960f8220e1313771d360bb371b3373675caadebce6a855ab3c009a5c571ef370d360495ac4c03ae179067678082aea24c639a0599a26d25c348d44a3f3489a4f51b1cda79a5b74c1c02e8dce9b2218a718c90bf03ba372ec58dabd06f06917e58a6552c84fbdd23cb6ec980e5dd94e91a2496ceed3559bf264ccee224b30549b78e2ae388844391c1df41403e32e5afe687118116a6cb30658942a383027842c9af6e21c6396ad99156efde860a9e5accd75cb008a547d83637a7b92ee61420c9fc200856a0beeebd3b764f84ff99b0a664d199979e1980c709d9c1e608266b02c16826b67f2e9f2fb45865e96e37625a444fa63ce004b7d412b0dbe6966337087f19f8930c8e7cbd655f7d234dbd97f4d6b24f50e02395524b7bed5fe4d6ca13f3d1f7f3f94196ad98dc125f142a6883482b97f13c2a60421cf70676531aaf7b0d3565ea42ff044ad6e27b25f60d6e5b3078048e83c2d2c5222cdcec60e1cf63f61daf3791344e47b4d7bd4f2b70129646fa4e350fd17d6742817979f98d6d9442c9f5e3d6de411d071a0aa6ec77ee9fd1cc61e06c41dd20ee9ffc9d7916602eb0c205226d3dc5616725e9b04dfe92f7f27ae4e056788a7c84a6dc7a4b08d126b795cb9c37cfe98813de099123166ba62e1b1d117488cca97116f2c821cfd8b7b8508270c768d126d7d3582ad32494091b05550e359e1cb38e54e68576f80077ef97097f2f3436b2a51bb2f2aebbc5b0017459b474ba1f53d0f521ccc9cae8d460e0cc42e1c32a9023341887b4c2a9c50084a27259ba6113d5f5f31a833e308ea23ae674e1cbc374ea2b7bfea1bfe93a5b0ebe3ad0cb910647e23c26c6d751ebecad8c8b8089b6f008fbfebbc56a344fbb3cb9031e1da0e4b5929b91b88baf33dcdbf981bbeec76a2815075568045aeb4a1f422ef892c7eb03c285af19c0fb654bb47ee2d39c84a301540976ded749b907f3ee38ca8399b22c3406d83c1f64bc12f83a5a2e149f60b32594762d35829e79b8430d954272c085c0bdd9788083ee466a876e40fa83f3ef0bfd3cbbb790944440bee1a04ee0b8b57c4ac0d26d554b21767183b181588ba9b71073daa7b8fd3063fa87f0b3bd03382cc5771bb0e3709166c5ea3d13ddd180b0ceff9e6d5630cfd4cbc5a8788f83ae8ee91ee774a661f5dd72208a780991b534e1a52aead244b70350b54e9afb571e90b40f7ff5f9d69347384b60e5703fa7c5ece1c24e9ae021ca019a0c4ecd5221e248879c9e8f04d027ff8b88e41f25c5c253a4fe6bf4171e778cd662049c6f52ca2d301d4c83205c005a893fc82d915b2231e4a488ba524eb1703fba80459df83a5e799805e942d1cab56abaae76d6082bb2ddc1e186bc4d70b660b695d6de876c5b20ec5c9156c54d4d1dc29e8a6beb7e9987a16a13e7335c1c8e2a17a8d1978aea97128f11089567489f853facc990ded2dfd2c8c1a24438577e089c3c69d8f70fd72cae058be295d28a027addcd1feec41fd8b0cd439c2e0a557aa94350469858588d0341a8180951d4d984bfb51245188177dcd7cded9fe68e78e500f2d0d3d16a20b52e6eee20e5dfb76a85f2340b228419288cec6fea453382cf8528f46a55c3f8dfb2f5beccb6373d4a8378234c98b42f83b27af1de3358848d42be85f72af427008aff42026286d277f3215178eb4012e16f0e683d718a2e41e426ad350db7244463930d734587685eda376f51c00423fe06f8fa5f2f4b4b2507aa315e4f015116c621a13f32213e99be0a6a58eed230880a7c774545d56dbbfc68c40405f6be890e07c4e606e89005741bb203c24a0d7b8740aa4401247c65b90a0ca1aa9c6dfd46f8d0423e3491ff1dfcdfb1b2145b0efcd3067f92270d7a0c076b896ed418718b387f54d8106ab7bf4ca8c842e1d1202b84f9cefd5357e1a3dfebfd4adc2ae96c9a7adfd43a3512a9a1becf4c75e1eed5c5e2f4c4228bc39e5a744fedfbb99cba5f0de5901ee35839974af8d4c787b7d8d975f74b6408811b61c1db859102bdee6c07f77c60b3f860535d940bd2990d037afd89163012156316efcbb443e3da0424166e602bbd82ef6d98978ddc0dd1aefdca5408830d4e411f7ebb07cdc655cae333899382f82dd5af1ebbfcd1928cc5d7a1fb33dcf53a83021b991cbd4005b90b5bf2987ddcc7cd33358621774c1d10faed3d6de89d342c84b54f798fcdfbd5b0ace8dfff25b9b68b37c925308b8bf96b1704cef95ba242b9813f73774da09ecf6a1c30a0c22f94efd20b8a891b906a7fe11a3afac64b5e5970d4091a41489222ca62bee99b45115b55f2f7731891a90962107987c4cba3c4ff0d0d56f48c03e738dc64b93b4e46c0d8493493de6a09d254e340754d741b193e4d0b77691c61b47544cfaceadec3dec5415adc2c515c83c5f3172d67c875befc254622b9fdf08b4546a33116dd4a940c87ec8c2e01a60b38ea24ee29b00e061b01c730af8a2148c73db6f7e95deab31619b9363b83ea9ef803ee6f65b26016b4efc054063702f2ca79be8a23fca02487de9df379a4880ba86f0546c6b4f75e58518430689407df713e89edf3434041f22d72814c2b1a746069917b2661c5ab2b8dd3e570a6fcaadea2e91855b915e4af6a6d2d95b1e19a13289b104b7c774b38eb46da1c30e51f2e77bf08c146316fbab825fcfc9200f3d12fac257f8657dca772ce7036bf88e871381e77d1595d581541669d21a024b2f282e6f92aab578c2e3393b94ecd74cdcd47ab990b93533fd3bfc39ebb2d805e23961ff6197e74a3820841e2204694d98874f53ed84144811a4c0e09899a620d1e1d9184f80a6e78989310f032cd0716f6d9a69c4a65b190da6de6be5470ec0eb7b06cbf61ab3801ba724fcc278172434d4f927f7349f500b461eeec6f50d510f5d5615f371dccb5b3774883c719fb782684e2a69b19062214146694c8260ec624d271625750033b36d287b1692caba1fe9441c28e0660c1227e26bfefe98d9b6761314eabe49b3e7aba5069af130d295bd70b1de44f2a017f358b9c0ce07cbb223a20b94feaaadd40afff74e4708b4450aafc7e89dd2153c6f2cf01d98c4022c0e228737afb6259f7910eac0928ed4ea8da1a577e003ea0816fdd819315c17db2bf2e4d23a89f60c1e0dc5aea49b2044238742968c5a24807fffaf132cfe7ba941b8413d5c161758086144242c030878c3958b60e0f843966866ffb5919ac7cb663ab98c9b2403c13b0d4decf67b48d825bd5139d1440f071543c45bb783057d8df1598227825e7384684d7c1ad8a6abb5fc6147eafb6fc6d22292098590bcc0e8897b606dbbcea82a21f2dfb8377b5f103309f3746784ff96a0eb4d3c1e509fdc3b256170b98b5023eabedaf94d821f40ba614e0195c1e470c8932dfa0db404cfcd315b44ee58273ee1f1d30d33debbafba7c43f07f606881c4bc52fb63569e06790240eac77f4a01534c16624148082bf7ad251edae4e64f07a372c659f3c2f4cfc373eb4b21ab17254c4113b29476c1f6b146fc07779318230daf687ab0ead2781fe14410b25b4219c52c41412d08ce9b3a1dccec4b37577e9f3b2fa3be7303c5603ee8a3eb71e03fda768a61238b481882950c8885e82048813cd02c85af98ce9b1819098c5286678a36e98fa3c2d879f8221b573631ea113763ce7b861062d723d2cdbcb6f7ace4d9fadc27defc1659b68826ec8e6137b394e704ee03119622ce4f0a84944acfff58e5ac094c84510e5920d343c83164e9f07147a274f3be6548a88097a06f0ce912669a319fc28cc013b656014339f2d1fdd2219b1910658738b7914d09f19ed19b4e60da2c2ac9740b86584542e437cb30c9971138e0b6890f51a8b7e6882a4cfb91d795bccd96b41c01eb7b20e93ad0c50f240d59981baaa58f0245ff521141b13f5b9f4d9892d4b481d96117f2e1bb42a0b64b42831aa1ee9dce3d41d82390d8a1942db05076ddda3e9675cf921429a8f909841c65e9ed8a5a81416f0110832a33747f5710132b9da0aa1e91dfa19dad7cf6ae8e9721efa6f6262d15030ab17b9cb6c44f2df4408339cadf143f8cbe8b191124e1b35335690c009b776bce26a0d88568a34f02d58cc040aea6fdb3447cc9638b9954b43d74f68d0452d51101c36c66d5764694cd8cc27e96587321b9c64888165f64289bee83ccb32592158a584fdffe1becbb8cbec263519bbd528d665b6c58e06a0e03f1c009f719d0e4800a0a58de8340f4761ab209d18a5645c9cd54382825369c879b0f427527d05b078d2550bde323c73f4c05287aa01c0f6c262b8c5657c95c3b8fc2d7a95330f4e9bd24175b464822bc1375af5c6a015953d5b3bdba156baee80dcb0141aa19f1cc2281539aa2aeb1eb2e6af032a786b0947cd64ad371d5b7e4343e729ebab7db041e4547692cacad76b5f2ec39f0fd7d4ebed7dd7d809d597a7398b4135186c06f8104416489dfd25fb937b5f5fe688e362ebe356e2e7c14c27619144c643bb354029ef666559779bfc7428f0aa9454e677bb012ddec45ea0dab82e6701ce01c2981080411824365aa9afe0b5e1149ef2d84dab55ade1c372354521a22c5810cccceee28f5036e8df4211f79898b0d12ff4f6626020008f8c5b663bfd74f70a878efee73a195071dd0e4264d35c79cb2347cd89b2c98ba8022acf07959cf8bb96893dd5ee39e1efb9477e5a132021bc37726fb68f11907f494111f40b25c9534572849af3ca1a3700e5031897a75a610e0272b36a2d29e532f310a77765e9179f9f470c0619e2c7674bf5e193fd667bbe03149e14e58fbcb6c2e847404a47e00ff82498d792293a291b696f4b52c3143290894a98345173f786256d6d7e1918a1d88cebc26cf49629ed1ad756ebf1f5bd6e7feb70fda6595ceee4127273fce880bfe54c430c97b8f29f2174b04548158cedf016708414fec6d964b8f21a3e718c287ee5fc850c68b6096f803bcc40af56e98ed91322d5667756a37ce537ee7bd71d39ae26a5a8b36072b62af62308bbf0e325a5ae4d93c19d5806442d8bcde31077d65a08d1400bf04caa8b1e82723e60fd70cd39733600204190d9280c9a921af16e42e404235c9acfc93b489011fe1448eab83ccf796a1b5bc4a68fd8e5527f4b0b9b2aa8ebd0dd901c3e032b78f93a390bb06616c91fc6e4f30166652d1f0df376f35eec1e612c7820276dc3bb3337780603f60ee60ce526ef4a8fbaf4d9c431748abe16b958a015f0dcb9bec5a6e7b5b0e68696a267feed991e0e5cfc89683bc15641bc9bb49b43261a9943e706ea757efcbe693d77bdae73aa41149836dd78afb925333aa99b092106e9467d6f48f72cf93d6167a02bed0d8694c17e029443a16ae53bed1847e97692bd53ad53f3d28b18dc900aac10107818789c92268732a87621af1cef468790c1540021468d1f7e1ae4e9d11042b5ac3e28cf5375a0434988872d1153046cfabb1a17ffe353fc8678874108ae3557c3699e14c507d672926b6eb378fac3f506857a447c9553eb99c6c06c03ffbf62f0b3da5824b3420c6fde9d3800fdd7edc767f5d4af11600c7f73b0532aa2684e614c1c593ad6036c9325f44964fea9bd9863430c94a41870f1f6c7168b72b85ffec27f3abb73eaa33b8ecbfe15ed799603b8e98fce2faa8c6865c53123da6643815d027a182ae4a93e25fda9e80fb8ad7e9d3963876a81a7ed23e4f1b62054ffa436473922fcac6fa901560519cd34b0da1853535a200993a95435f0652bd8ed7758b3739ee71f8d424b218ce732502eb4b82c449c7f34504466abe0f6f609b124a2afbd2c84dd4883c16b90d0b183071f1954e5c77520b5982c203b3f7a9df3ec6d75aca74ffa37ac5ac7ae3ab19af81957b645d2842fe09e26833992165f5f2f95fde31ee113bc5042ab097d674d2adf7f94ab6997cad5ae210da051e214dbab9bed0a7dcddfc6dfdcb7dbfad39d4a888caacea15474967c45c69602e2b9b3c769c279fee21597bd0b760a0a064663ca79359e4472e8c355e732ef06f87386a3fc79dde329c99a75826ef8d4d129b38b9eb1fbf0950701a9d9c1f97e9a06d0b6583521bebe0927096a7afa0cc416eb53d3cf75728241393764e9e85ae1bd35c869f53a32cacbe2696e95914ada9724072e31eb9c09a25c8ef4e76b80a329d760bea740f24a3a0268bb205f9c22c3a00dddc9f7bcefc8e5526910d2dd4b4be30bde4ae30ffa06a6c5198629bcf681b9ac4d79401e19fcecb0433bf99264c8d90dfe680196855b501e93e00f79c6fffefdf5628218fcd81bb82d1ab1063d6ee4f898875a97f99fd3ea74ab937b29467936023515f402c1632dcad4e3a2f8f2cb18c1a0e261c2ac1e0fac0f32736a64cdc20e8859dbcebd9e75ce6c04e9d874798aeac8b08111fc5e54436e6930db1ca19d8d5148b863a2202231b9e16c3208a883e7ac024f8899d44808ce3abeed32321a09ab10ee02486e3fc86d48481d13ddcee547cf21000cfc43fe63e761b5a43aed8f6f2d4556359af457c92c2b0518c20499d6c80cebb9bad593063a70830a3bd2c612d52886b5231229503042bcaff83aff16a684f42e1330e96f7af21416763b630ef0f9723d168a00b88cc807135bc6d8189a09c3df8d97d1b8801c07bb3f3fee79e2dbac324b393ae681dc429cb6b94eae471399a87f1ca333f03f0b4c8085757806240fa3616e009390e785c67dbc38ea3715b0c7633c50fa5070301deca5a1c748e8b3c4126f895479136965389921240fa4e2b3dd80423fb4e617a341bdb6de24e9b9b19aa3cb1e0fd27dd232ea4fa2d56e77a09497a26bfaee86b9b2c774bb69cbf9dc75a932734a0cf59a1d6f054a7ab0451ef1c3939e25f3a4379f4e16310a52bb63315db5f57b19d1ff866d8c7c416fe5a2badcf0a37b2b0bbf0aa4d640abce1453ad130b071260f62e0e717456a25dfc0bf3e8fff1402d25f7b2a894432237ffa76262f03efc0e9c41eba7069988525fc512e4a2fbf05963b8093657c149d7a1cba6f95e9de10cc5ba4ed23ec61cf2f411bc2427a4deab7a13016842293d1828e7b906690ab5ba3fa4a99d8e5699a0ebd472aa518c011c236ed8ffdde877a0abede31bed59a9088917a9a8a3240d7480ad071f23cb71bc3ee9634666de0a1e190063f18b4421843b07551063cf1f000912f51828da7fef810ee25be4ccaadae2b23c29ba4a9849fbc10b468a11021934c5d3ad589711e57e2254f34a3f568c89a7325e7f9038aeb3f40209ee6dc79cd2714e7b51190d50d0cbcdf7ae4c82a21a0e18df74e3d4d82dd5c884b96fb04e3f540f9f3085d0488038f5ad3206543f6c258f6dcc95407ff5154f8e9561922af5b05f4a7c861e712242ff3d83f0bb28761ca5ba60ab1aa79203073a6b99f3ec169a5706c2e3bd5fa166badc1b0bb9c4ea17958f8ee5b38d131ff4bc57ba0310f84cdb2a0a3f8afa1f3172d1a7dc3e2a4359d79bfcfd8fceca7c9b343df8d21f2978e1a2a8caee376f47e66a68feddb563d7f558a057b9bb7fbf484a18aa7eb4be575aeed2f4f0d621659968cd15492ccd84d8768e630593b1adef71658d58fff8f827323d6f93e309cf97894df075ae50b01360ffd251b33865e62428704817e4b971858a7cc74e744034e1cf42698fd8f10912e6d811725ace6e7d90bb359b66e4fe6def66d3dc439d3a9da8f77e1c24583e7e085f230bfe036dd7381176a65038106698c004445650c7e69e218e60a02e80e09603202904c150aa9a1ced015a984c7b8a9c34cc9cfb11199fdd3c9be4bbaa97027829739f8a09ee6ac204537ffe15b8467e68b9bad8c529a46a9975a0e19b89b3757982135148ec999eb49f760605b84bde8c4b312c78786c34b194fd2a276ba830f1f9c248912da47e0aca2fffb5f84eb28e066133f484293541baccbea16778b20e6bdb33f51d8cc86bde32ac1c4864ba6a8408a0da70de45a49301364cafaee31d2354a04004ab57206712eac72bd1cc31309540ee3d9b1ff4be9404b1129390cdd0f93005bac5f059c924765870a5bf3054015b4be322d87fc3b08aa6da3bd2fce0bc74ac04a92358ec7d83fd272b3251b8feaf7fe84c7a4a06e7b5cdd1d5d7b856b7233870998a00c9cec8692b75b0aeec2a71c54ceb9dfed8d638a8278133e35132f4f138935e17716b7a83cdfb34051b327fdfcdde1790139a490e3c5bf9ce2e69dd56c274b8407567da58d8099ecc42b83bc47970c8b761837604ba98ccdf3bc2ab78a2c4efca278b784e5c5f31c59a53adebfe98ac77fee98b54658f9821c6828009b17e4ac8f4bdaea8eada1bfc25ebf1c85b0c0da81523f3d22b23a79617a3931c92efdc8fd17a84052d79e44d1870347af8208eb02d0f6c05e320222c2ffd67fa85d3bfe9e455f05bf5768cc86c1e894a93ee0584d6ed00fa2530c0ed30ebf826221f3abba710627d368c94d1b2481df4c29a113217ca767360d9417093c6508d58490ef6a88e98d88cf7a2f69e9adfc79df71add492c8e949eca89008ccb094734154b28a41df26c6af0c0620c6d70367eda0b38e46dd43f86d9c1c21ef6231fda8914e747cf6d15dd9f3ee6ae290ce62cc15095126831d45ba780f4fc1081f94db94264cf70897b5f68c379a8a2ec8388bb13831d5520987312ef86dd12f0d44d13ede83723e85e3201b1fa10e411fc18ff551243e709d6560c6aa311f3bb774756e43b2837257737f657e323ff14e66b7f31655314f1ec4fdcf7ec5ada87d38d1dc454fd7d9d53f83019fd85cb86718f1fc638bf32d8ed289f669f4f962ee287d6fa45aa3c76b89bf64626b00538e7b17a3ea301caef48e54d29ee7107013dd97c2a860a677cb4b441f875068d2088830357375734bdf23cb026217029d0110a471fbeecc4602f60751218608ceba3c019fec140e68c3ec03307d0e700170275d8102a90939373df0ad8213bb6a85e837831f01928f1b76b47b4a58e11e0f754d82751292830a8837e013530e007e6c7b792f3b120909455440d6be178f16ebb665c5dfcbc2a3fea09c5f177f5b70e546718099a3354cb4e97e84360c33357865f01ac796e7f632c588ce52e04723cf4fd2c4adfdd92619bb3d5748085b7eb706740869dc6020dba5629ca78dc311a75349c4abfca97d2af036793f16a299dafffa67de56707f7693b2d3fa46e15c611bb12e34a15f428653fb94db8cd294a7e44e6bf491c1db2fdd535f48327599b867751e699a3be216532a092dc9faf11769a9067417bce8ff1e6d0781dff5526d2ec6696bba22ff63c76d946cee6d96cbc19debd160b4d36e18a7b1de222af01ee5e2f0111fc37b281fc6b6eec8d7b9092f78170879a627671bc0fd751931d340610d88944ab023b9c2d933a79f142ff9252983cb6ca2edbfe2b36b68af4b37437bda19d611646ff2c73f2c3ad4147108e936329f883950b5c9df8732299598cdfa986095628fc5a71e5ab14a758b1d88c23f0561d9d74bf18beecbd80d73694dfa00a3d70cf75fcb0125bc4935a17bcf91053ab544bc539304724ed0c2eca77a8b770e57c38d86ac55eb2d550be7ffc5c68fb44a6308e2f678fbabe4e5390378a9e4ca632ddacea8884e2c3a07ccb81f22d1ccfd7d5710bab2561bb89fb346e308198530b37a95784a103063327b10a8b99ce5433c22d8b81b34c123453bbc068784e5211ddc8fb02be45351f9d5f7c3b87d9bf1a6f7d743b3699ae3c8913155f36976b0ac62c14b9d2d11482a6419af10691e0b4afdb7f4c4c859b0241eb0bb163a6425f5bf08d2c1b214d8e7f46116ce15ad446c86592662190eaf350e767e8d7aa0339aa865fe510b1c0c17608dc63248828f3a7f907fa18669fbea6382287a7d191c0651db7b3238ff58c4c016279b226758f5ceaecfb3dfab866e661685cde02523cdf2ee7c3a52ce6470ad79c482d1e387d15040c3b1170873f4de8805ff2edfb10bd17a32ecdff8b6d8b3f539e84fe875bcc3c7051e26daea68bfb01a92bb81fc49ec15d42b5306503bbd1758c8adb016a3a8707fbd1fa04a554006fa23e412bb4f62b7bcd6081b672118da6c960b5ef68cff17663c5f2d14845d23cb35db1c8ca3ff8276748d1920b6bd2dd14313fa4abf9d9631f1795e04311be6ec768bd5766b4f63a0f6fc88b94f58c1f0c831b68d465656c4052e1703b6e19eb3dbca048ed2999af3a3e7c560dde9cbd4904542031201b818c24a89ea48ec6edc43fea54ddbbbae7f77717a785041b258d09d0b034c6408445cd095efbd0bcbf75a74e22ccffa5c3ab4cc5ffa72855916f9f7ab56a46612624ccf73be0686a7055576f8986f30559897c7305c4050912044d2d07eb6ebdb407af480e1bc470daa78dd6479657a5d390d3aec917326b69e138b6486d1460ac599a4a10630bf6a49ba72304c8fe62c11ebebbc8953271eade189ecfc04169021f5464f34d86657274279a14c6d65ada5331846183b6015c16fb6676638022c795db22f97c23652c7ae2142717ae36664dfd6068ef75cc111645d8853eb162b562be6cdbc65d97d6af5978d21c482e507f4bb0af2c9c9ab24c9bbe4d8e0fbc61a2018e9ab962d3eec8962b7e25cbd0d3c97a3578f2e97f1f5eca24fa3b94a1d88e78083a7818b0bc8366e962369cb5678daf13d266a5cd0af7d14ee216fbae93b46a2d9838c37e97021c950b0035bff2a2f3bd09497611f99222e3f42a3a780185c048c4637aaf637cc6a37aa8608766ef17fef25d327ca66d72b06c654dea8d9090644b5195fa89ae39f81f0b3123d45177422a504ea8e979e7858e8453e515c87f6b921c1a229c4c4fa5fc054012c66139b9d3788ab96a304990b89a0408597470830b746c98fa4e3e4b5dad8fc67829ddde24c5fb65eec5bbbaf32029cb3b790ed0c3d33d88341c568cf244a0b742dae4641a949cbed6dc88ebf3b4556b0d8a8247ba49697892ff1bc4095a240049ae511d6ac127cdb20b10114e9cf35e2e03a01b54caa0ca3cf1923220aa0c78922b9f71648b948699ccdc09e3f7357c89bcb70e570d8e75ed68fada9dd28d24d4ea6f6a986ce4f022f177606ecd9173d673e554d22ec25965b355144623a96a2a6701b33ce75a43cb50a4838617627686fcab7f25f4fc7c44cbfed404a75edf18f761c02dc8d23a2274206953829207094961a6743825171e6743c745b49e1811c2a73579020feee320ac87234f63d7e548e0ee29cba38ddf29f4688d07840d57e1268cb23fa2db8992cc37809cc6094b4b4c8fae43855e7bdf8dd913fff493c539805c84f6aafbbc5b3243392e383b3e30c9f22bd958d77e45481f1c4dba2a55d010e783ab9210046dc4faf9def60c0b91f9c3c19d94bf47628c80117b496682200ec05e5a8e4b6ef69dd4e71324deb1f3ef613b941ffc82c280ac2fb23f8d6a78d7eb7931c3814c6378bde96c8a510d75e052bf8fe9f92068f4d556ab51a27b29271774c9dc48f4b15199027bf40e4a96ee8f562644700a73fe993bbbe94be4661e76d09266d837bbe014c21081d830028c7103444569ebd057c96d38bf0326eb60ab8dbf2b27439bddf649dbee9a5f7fe5aa93eb741080c29756e050cd48561d1172c9397a5ae5c9a0ffb15f39c9adcc77068875412231ca5444ed054f3394ddab6f7902c02e46e8a534130dcb7611af34f5a5e1c7c26e2a6bb51cf62f334632f34c748e61894c8aa34400994ec7b2d3275c9c1cced7aafe303259ada830db166a2a38d288b2a2a5fda1645ee5202c745ab37387cf07c2a4cd4667fadc2976296e9fcf5f31e4f71a1fab2bb74cff783cf0a655d03c5440a2ea2f68e2dd2cc42b6726286f882b8293923f5ae2c730ad9a2ddd7ab56489673e6b8364e5121c90d0c57b66437469f20dde4bea962047bdfed08c6d305b12e8a1c08c662b6ea44981db62e99ceba3e5d934b4a7e63ca076c3a14f05efe2da4cc204546c8b4e4aef8897d15ac09440c12d351c1d624efe1e699ee09a707c9d644a5948a0261c4ec166494100e1c35e6fda3dbccd9f103660db43d5119e9e0d0bb0067791d1420f38ae1730017d88a2341b6a9f0a8499015168828d24247d5b9f794f3c219091a6c42aec4e3cc3687cee22b723266fbf66c4d32bf547cc19c1584a0070e42112cb4488bf14bbe8d88d3e9a834bf4c3bc19c8d3ac7c7f5e69c40c12ccce73c16bc998e1a15be59437df10a777fe884315142650a34a75b6c7b14e7c64878e4fd879bac559f0d5a41f2cc4b9b50221e5c1ed319bd9218263e33184eb516c91a4fd5b6ec34bfd1c0a83efbb75ed0688178957c0bb11c9627801a8c6cdf68f1ab9fd60108c4997c32c55277c29090da3fc17fb9e2699b76c111286e7824a481fd9f69e41bdaea5217b64b90109d386ae756dd7293f0227e1704ad810461c342fcf863a3d2b8c144eda5528c591a58d308b52e4445dd0a2591517cf7cbc15f696a012f8fd0ad8b89ce0e2d1228ee74e50dc1a04821bf4367781fadb48263ed4e25160e2cb8f49781f145c7a05e0e13c7270ab6c525b9ffb06264655e72acc34cc17ed86ab1d0564ce75cc6db761f57824e406fe5cdcf31bda9bb10ed51c6e5498aa096bfcc2ef587bc382a3c789be6334a908f2fc5f8e7549dea373e031fb8dd56dc1c5f38efcd40af0cc769d5896b93af661a0b3ae62cefc550cafb6a538f8dea77d5ffe6614121f63d2cc7d2dd029c30cb0131a67c7706c95a9413bb8d25ca38ce3c409cc40619b2e07637956c10c16a0c30cbf773dd4997dd092f3b312eefcd10d98d344cc3c08a67c9a12318461790d6ba683151d54cdb1de10a6d2ee041a3605a5009321780dd8e1938a9accc2335fa9f92b83c940e715039ba61766a8e1bbdc0df87076c98faea348c6bad3a916a578db85e02c54c284ba3d1e20e6cbf3be684b8eb5bd904599b5c2a6734ba8cbed7b05b14650f36ba4db9aea5903105a32c0ccb30a18b26b9fd8981798faf3ae1312ff7432c0662cfee9f57cadf7b5c3f80bd632ea9a570f2511cf6c904b2a286ea00f068c0b8b1e7943cb5797905681d1c604d586049a84f9f5561e14cbb4169ee58337f9d45b6120cfd236a33ec48afc9fba2fc16f7fdfe1941f1a0a87657b5528169c7f2a6b65fdae49c43e4bf41b2e8950392605877c0ac4de8801a9dbb179380993531d494e3db605f3e944cd8d626c1e9fd3680d3ecb5e7ef5d25370db29132ab98ee164f01d6213746d362ce88cb798d86de0e7560407a42ec678b74b5a97a4247d30e7da47cda9c8c45724c8925f6b1ee1478f8a79271efd9015a52d9b849679cf88a38f343bcfd0b459a73e446a5c20c3ba663edcb9214b99a923f07d96e37a04235373656257441ed98263fa2d94c659879d04aab6a29a2344c5d1e4c9141598d9c08311850acc3ab2b0ce95a11af2deb649c75dad12f9ee0da27d5ac4ce73db905657b24f9d1e9489ee7a6066ab70d62a1532db82b0c8291057797c1d3fbe570368c7a69ce5521c2727eedfb21e76284784cd00c647a999d776a6b96f3e639b1a3e82bac930848f11e7fb1509d5a1d4145ef4825be6077c278b35e0a6803dd8781cdffd00a05f0206409aaf48392ee488773807b18bbb60559053df0d70862feaa5da6a9391a2bd6a8c56b50ca763b81ed96294b075bee9840f60573cd3afa04b1942bfdc2d6fff20d8efabbbbdb5403092af12668dd5e050e33489ac17cd018283e12fadd71b9a99dd7339e698f18b045d70f69d3b6178744ca6c302e3adac9f8c73f48186384da17894133407af7b1ad6a584aa71a3d1b24de2b49885566a02b8836505fcda909c2e758f8f2c1dbb48dd06416c8110caf51ce9e16fa593638e59ef9a10c833f5d22c0b10efa93d216cb7cc22df98342565b4c9234cea7ee77c65c3e2ede488358318f0c723538576d65268472900ede338992041441074f3e5dc54fd35021e6c4dd08f0804aea06f2bb36813f2f8f50b6d77aa60abc99ad1391b6941328afeb6071490b14ab2ff6792b033ab1eaf9ac0f278d4af62a9fdb6c98a8e727947a2166b113dec0ed7a2f23a28ae0d7654ec35f11ab2b18a40ac86bf0636f9741d735f9875e89dd9ddabc5086268754a042a54740577b593e4befb079f2e41d944238fb344001ca5acc65519b681465be0e2c6650eb965f6645eb9a345248781afddd93a6fb4286b60234b671d41033061c3ac7e05074c4e1349b93ed114aa39be78a3002076325cced759309f9dcfb486ee30ab08d60cd837553e6cd23fb6b6e6b948250a91642be6d0b3a3b49b53f35a8516aaf7ae81a8a21355e593871ca6dea49252e7b3d8db4213e69be6e75f311ab43181e56b40a0dc522e0d3c1140371f2dbbd0e3a0421d1b5a114062c8332ff4da60b73ac66ce0141294d5d553d0d7bccf7ad3e3931790bc410e39de5be089df27db32920c50d233cb006b93587945fb27c261b59a0672a44c997920a556d5fbba43be865d8c61dbad68274f8465a33f5455fc796751231cd9f0d0f79ef3e6d0d0fa41c35337b75cb576120e804fdeb6853640a29c089112f8ff239020a72e3a4c3d33b60e61e94b4c89eb0301eb319784f3e4ac7b3c9d558537a3d320deeb73b3325b55df7f085eb1813dc8b1436ad933393648d2d9dd0aa6de1a70ee1e9277cce08ada07ee9e047d89bd142cd4eec5b45611a5bcf193eb4f87f3126ac5538ac7fd42c07fb316e82bef7326c3fdcde2e2c944a14934e05fc56fe89c7714a43224de6e2ac6b096a5baaee081d20a13b2b402a39369bd797933b695ae7bf463029554902446cc85674a8283cf872fd1ebe909104ed538f854c0902ce6c03338a734015700d720a2b247c053c12482d3793aabf2cb46e5adba2562ff8ae66d87c452122a5c869c78bb582492df81bb3ad1016ab32cfa41dbbf8e4bfd4e4d507164cdb0ccd426470ef3dd9a0c9023277cbbb7ba37edde8d5fbe3cbcf6a238db8cb40ee0041f89f95388dcd206d180702a5ae7e60a9c621f51e090f137828e6e84a69b004ee012f196e60d94583615536f51d6c26072dcb2d72e7ad5c606879dd14bff6f69737baec2fb3f4855cd5b1d6ee7f0e36301f62448de9ccbd06aa4119e9d6678c7a5210f31c2401b6374664f0db70c9144cd481b21c5ff6a9667911f671c5a8ca9e80c3db125c953a6234ba60bb6caa16903148cca218e80456d10008f4d5c1a48506a5f12dae014d2f915439256ec87f959c806299524174891f4f64f05e74cde451910ef0a3b328912a9b5db6c7e811f39c954938300142a938edac56b1a78b68ec32d67f90d35848643d7a0800892563a4e7ff6b55f73641131a0869519396581e1cb73d704201f1f406a1819580a63f93434190c837b18a2f8323ab28b0245e8c17f58723406ed4032d04db9253f8cff16f5c3db8fe7528a2cba9d0fc9540b26a863eb1ac5a4f10a2cfc70b4a1a727eadc29b880cbb38debf6a6b0195f50b0851eb9a29e15ebca7ee589c1c6f372ec8057c22268cc1a7ac2484d1a1e63ccd1fb5d8569915fb947b3036a9551dc30151b8b99c5b47ed2feeb00e2e25203f8d0bd0dca67a39dd253c520c3972071597550a6fefc622ff07e3e6de5005b5cacedceff192579fd855acb8ab2a58b57cf95c50246f671d7b1b6f3d1aa96e00816f93cdd3d58f00093f228d6f74d993102b051a951dfc2ce7edf6c5f10a8ed1be7e3b3f23a87c0dbc7fd5a3285d10304d60467ae100546d071883bbfe9c8efab18536c1d17a870f746d107c8531bbff85b0e2700769e5f23a4652f9247b44fd515adc8ef9ab449e4ac91e313f13862a6d12489957635b72fdf613ff859defd1cfcf7a1ac0bb952c4a946885d641c5b729ded04444cbd8bdc21c2ab11bae7ddaa0bd1a3439acc7fdfd8254682bc9d1c9b8e3fdde31d068fed8edbc9f11f1472637cc0eee4c665bf670eb8abc1f98ba0a50b154bd65e38d887cc624a3333e82e1dd9be701b3bc7371f1dea8944dfaadce51afa440aabb22504efaff2fc063b15c8252f78cb32bb7afadea9a0f3e516767f89fb5ddefb1f28065e01547862bbc494192ccda3cb7c468691d79052caa48f562625b4fb90b49550527126f9b64c760794abac2bbaa8584a555577eeb4556d086a3c04f2ade4644c5833cd370b0f98870c45519b51dbe162c3f9e52bee915e9f8bd927bbdcbf0cec955a79c322d54e599a1f4cccfa05bcfc124f41050877e97d43cca939dada1dccbb67969b3d0540820d638ecc5bb1f3f23d5d37f58a68139e1ee0d557abb7a87f0a7680d8dd20eef3f5066e8a720a1dc9fbcbae4d3084af7e21fadcc7225a286bf7263cca0efabcedf746e1b3f001c17a92f1a1cd424e735840a9f73f107e01607f08a0342419438c10da051c94c419fb8b0f4b3704583225f4da08e81b5933882236917960a695a93dba3264832568ae1944a1bb515765c187b4db4fa6bab85a1a53f309eb18382f4e6f25a212e1e6edc2f497aa3d9ecdb406e7d7e709e268d1e36afe212c81d687ef81d7d46132f909c659484889480a5514608e7d4968b8388c231e7938ca517ba688bb5fc91e9abf4936ac61228bf52c74eae067e9f91c6d785d69d4cadc52f3c5ac91ec31ba00e93e8a85794f0bda0c37d33cb3ac2d93ec1e0ee8d4c50c3b4ed8ee08d8b03e3055aa3b1655cb4cb78d4750a72a05132bf74d52f9b4c5891a0df0ca38357f23ced9466f1f2c72e838a96b259b0ca1a35640fbe37ad60cb55376f2725cb22c710878761ab4c50254cb92b2bd8062d28052913e2e394a56b823ef18a8beae125843411484d3814e48143c6b84b1a14691931985ac01f6087e508c391aa83e3bd299be52414224ef5540b26a8893518fab8641f981708114796a985bf4fcac906bd5818018f7156cdb0616c4844437ae8e95bc57f697864f6efdc076f71e6c5f269de411fe7279c60b096781c074835485fbddcd1d1fc2a3299e21b6c7ff970911726348b5425cbd61274dcd792e4dd5b6d2c2697abdfd36670699802f329b301bc271f44f2cc26f48030936e92cab3af35a4a671dadc12f0273b63518244211e0d74882ca141c96e3e967ba2bb989eeeb14519dccaeccd3d8a3eb6ee837c059361c71c7e1926a3844af4f7e7c19bd2b1f0dab52ca6e345484815efac0a282c126ceb1c3d3091bcab3949a25dc7f71037a18c81e7ecffa0de8d4be5dc073017eeb70ad855c3198f7432d47ba89754580a04492c10ef713cb7d93400153894d6844613f31dfb4cf72d72113019164c2e51f4fa900f06797509ffdbc62a8a4f5155eeed43c553911b0b99b66663115c370edfaa0a0ff6be840e99c20d13876c6b7ee0558305144045cf01841e8f84cb019fc20321dab8956a3aa40db63e94a7a2acaff6c153b8452b08ceafa03188cc45b8f52da498a03f2fa3fd111320896a49631ac40910960e9501b74b58c30f8033c2182c82e59958bae6308d4248d4671ae962aaae3cf3968a4b01cbab1a158354dba8de32133aa09ec04925ac852b8c659ee0a2533de32061f46d3d5bc8a20ddfc97fb216e7d502c7a3a410e200cb79e2ffc273da6259e427ca16c49aeaa3b28796d8829cceb51ed332bf6691609cdf440231285cda1af54b79955fbbc76341ba01fa5a3752f7cc024987f918129a634540572bdbae925b5c0013044558716509418f4b06f358426827c532cb88f44cc13cf6d84c7a9476fffa49d3e393c9908a0f0e7972b2b0f69270aec384fd7799fd0c7e8370cf9b4bec6887efdf31514c223adada73569a07ffed0c580d044efc3762bf90b04cd224bc59b867d785bd481ef69bcc22482bb3a5748ac3ff199479adbe636faee5a7779206a67e3d10c2e28ae6a71cc0907ed4b3c08e2c7b9c4eb68ae2e21a00b8313dad1d9e56a52315b5c6a1573cf9ec316a9354ae9059aa7b4489f3e90f6cd381767fa85fab51e1e047da84231a1ea1a724801848d42b520e6c9c101a23373a960610fbee0625db6d4fe18c0fcf69fee123922959b0a6929adbb266aa3d9fc59c941b170ac0d72e752de9153fd9ec7233f7591f129f1313c6df1abd6cf253e1bbdeba0f2e44327f3a8687f693c1726848f0fae1a2e944fa659e5e775af78007b3f26164dfd85cc45a9d83442a49e79a5b75ef06867d355bca5ca72bc894c71945108bd5644a188e2fb6d3ed544e5c14d62437d1430e21e85fcc33de6c3627d32ff2c1a43515f80b797837d5f497e097c6c4fe9895d08bf24b14d5dcd9234dc0e23a7f35282707148a55cdb75a5c43039fc639fa82636c338e55857ffae10088fca4a0c668db9d3f81ff773d40bffecf68d3a4daa742a3af5ebafc498a01b4168bd3264c6203faafd4d340d2ce740992ab8d2753d992490e411ac80a876ae42987f5f725739b3e2026fb9cd9b3e65dc885181684a3bd287c6c7309bdeea937447098931bfa8180f75dc9675cf05ca80dac7c2920ec08ac46a596eca777704bd59cb496f0809fffd4d207caf9659969d331892363d08dbfa661c8c6997094ca16e54a7d8daa5c1220adeefc556658b25d3ff5875cf110e6ee5d76427548e0e1030eb18f5cfa313f9eda3d26f95e69a201f3a2340a03984bb029b928d67f002847c046a917fb656205c555107d998c43b0d6c420b390c58e144f2367c37b47075fb3e91e7139c10fb487b698a08fb615f07301e1b5b66f9972669b49f2ed1aa088238a091735a578e79f2e572dad7f37823a958b27793bdf7de52a624033c0bdb0a540b3f408d639223924f9348170d5d7acb4d553633dddddddddddddddd41b4a5945a6bff0597efd282c5aa856545a59282923a996e893e891ce98f4afa61f9951efd8ed222b2d63af322b35a23e3a3d34cbf391137bd3b72697622d9ca609cc48367e5c047c941957fad7977771a2a5525c33dc21b7af24987462eeafa5af3c4d0101dc2346a4ccf053d16b4db29e000d72d3ef6a9abbe2d6909d618d5bbd7d97a730ff4f529519be94d777b74f4a3efcfd17b7834c225d8ee79d7f3c459cf8cc78f13ebff59fab7230fb0937377b9a5887e8fd6df29fd4e105f48c29061e3060fda877b66c3cd28a47033879bfee01340d5f873cbfea955f7deed4a95102efdae51b8c9c34d5af52643cb887e68d9bf799a076bf476d6b2c63de309c350d6333765b969b641d85ad2fa9dcf2e88ea7df6a6601031c3c60d37bd233b4cbd676ddf968d73d389cbf0ecdadc4eeb98f058190a50f654add6915e24914824128944127f8052444644a8d9283722f24992fd474c76c89ddfd024e790a99137c8fa53b55a432a5dfa280f45b29576c8a437d9d8cccc98a64a752f0892be8451333769281e3b64d29fa8994dbe2161d4c5281ea99ad3ec406b7c70f9a0d2e1c6943c3486f2a0313403f1c4078da1f9bc403cf9415dd0bc426b4c3be430dc13354be2343c9ce6513eb2ff15aa352f3ea91aea06360052031acc80f24073f9f859254a063180c18f17b8a00594078a4bca8215a8c0470a50d083f240495f96273041097890600422a03c50ca0345cd7a50338a6753a02fdd83cbfb8face81e58bcff0809e5a105890a40b5e6ff53a4f24c65d293244e438d3c19cafedd90ae487e9792fed83d8c96d01c4644ff32fc44f4b4b69c37832a5a28d401dd2cd29afb83ea8046172cf01d2de91e3a1bcdc1bfb38d968c88b2113d5be1cbe366aa762222bf051391cf8289c85fc14430308133382f6a56635ca604cdc174522497c769ce9d20f94404cdc16445a6d8448532c52f9d7cfafb536b4c1a637ad3abe013347dca0f0a3efd9d790a9f200a9fb75496f4f457e634a6f7d310f729592a4d7e2a4de52df5d7ff92babaa419350b6f40409f0c28472adb4e09910ec8a200b5f0943154e1d3735f3e4b02991a803e5b899861bffab01eecd7d18960f8e0b3fe067cfbc29a315ffea6aedcac58c5f2eee59ba76bed9706c2696819bcee6e19eac269bc942f2ff5a56cd6d770d365bc7cbf3ccbd260954fd07f791a4ed3fdb7ad187473f55dedf75f37b1aaae58de7230d3a197f7ff2fbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc607abfbbbbbbbbbbbbbbbbbbbbbbbbbbeffe4ef9d394bfff521e54fe71f92e2d58ac5a5856542a292829547777778f24a994fbbfb21ffb690922f99475da1c8f0d6ff9f3d8c2277fe41929a5a35aeb124bcbe3dbd14608de85c35b5e82f57138cde8290e1a5b3dd3a6e2973a3c53faa30d1c4e4329fd11db7013c78d2128c6816fb8e97524a386fdb5fb7180e0bd2a9569ceccd8d8d870d3d2320e8ac371c33e2edbb881a3690e4bcbf7d6e56929ce06c9edfeb419fd69d470d31f06ced232112f6403c3d29ede5b96e1f7dd7412cc321627857b7ef631fb793b06f926bd5745c4162e0e6c830a09e52a6e0024bbfb905f6b93d64615682cf71331c3e64c3cc476e51ae882406c5b4b5b08ad7660e6404ddc3a50ad5f6ee431d2c6d998f32fe7634e64e2355656638a9cc689d380cf9344096e0991d8c4ce6acdf83ef2d925c95d27352b13adccd272974474222671d3735f51a724b7c45a4bbb138bc426e21012518988abd51a71898b4c46b391acc6d0f2f9e5c45c18ee7947b7fa9475a264d729a5eede524425736491b7c822f0464df39f529c2baa982c72d324730edee09e64aec922a7218bc8dc53b2c869fadd4bfa3bd96bad2ddd530d781f664a963653efbb16d14f3b971db4c1758b5b8aa8199fb12cca6ee3f148f61faaa550f61f42e42707c95e9fdc13bc81b7ae1ec4388244b2c5a0116fefd6eda4730726c497e91b11660a76266fa4508337f0762a026f64ce694ef04636b1c10f993bf138d14eb353aed614d59a8e46ebe9a9d5c85cae939d2068042c82aa59bf43f001c8926fa829ad69273299cc0332573f89426b3c573f0b5ad3b9fa61684dbbfa5dd09a91abbf456baccb876c6b93a18a1a14d157fd213cd7d25271fdddfdf3ea93cece9861c84bc23dc14e04f79ca96f6b3aaf676a20a343fd0551b45f764235a0df47badb76770b9584b830c9e856636a47df9dd66ea81372f3fb273cd787633a2e5208327737376940fb8cd0aa19e1defe81046ca09e8159c50c7e647ffb5d7623b8feb4b6f477164e8fe6f94091d596647f141e141e2cb9fe020f8aaca74099f9701aea3436fba3102941e1911da5070508ca0f0a10ca101422d6a2c8567eacd4567a5864262014198b0c45863243e9a9359d8b86c40a372910c9dd84ecdffdd09a1312684cb7f7fdb98c2897a337a1ee06cdf67a7c780d6a1c53a9d58ac5929179914f54ee058c7ca27230f2e9d13a2037103cdd3c1a158300c98e2213898850fe7459a1a964d95f05576b48152295dca952440aa50c9192a0d46a4d890845566baecd0c0a90eb0021d3b78131f3c2941183b818c4c5206290ecff62aed65c1b8df1bf36977c8a397a6d62eeda6cd9ffe47f8168cd5509dd1b1d22923d47fed41ad4d010f9833add48211329497612fdae6fbab35a73efa511a954377767b9ebd44d548e0ba8a15a732f6a081caaa8a12edcb8d0f8bc406006680e94be5b80e64045905b055f80c6d01eb9ffdc4941ee37d14c3413cd44cb5dbba031f42b7daf42e5c3a53707436396c8bd80dc7f8740f0de3ad41c704bb165014af98a174a3c371ceaceb936c34f77575bab352620fb33c469a83de234f4083927d96d90ecd648768b247b92ec5f698b6e44cdfd43d4dcbf932d19ee696f192412d66a4c0d626b3d6426523baf0c97e12cb696cf6b7f9c865651fbb1419cdcd37bbcc779acf7d8da7953e150a62f3bdedfd06dc65bdef2b73bb8fe3354064ab2bf1d6f191069f813dea243602efb8f295c7b008c81ac6535a5211718f3dc30e8797f0efcb0b6966a3bef03c1af0241c12bc17ea77d2a1b5455d73eb37779d87a8cdb54f1829bbb9aac98765b70f7be607f5e8d48762ed0a7ac93ac6517851a9f2c5b3f534a55f449b2fc84e8834de24fe8c80f411fc461798ebed3d25807dfc1ce439fa5213fa16fe83be2a65bfb7448a8924e16d162ff27d4a4113f64f2e947ced8c9d55a10044110042bcd7db8d9e3e64729a594d2f7be692f71d389dc1471a3508d2169e0d0cd27f8e48bdd273933c13dc9998dc13dc9d91a88f8b829fd69ca2454ea6538291b8b6acde97d06ba507f2a794260e342e1fb33d095c2a79751291904aa9cd9b84e9f2a794200ba4e3fb371a14e9b49a767d28b7624916f2a4f7f4d7f2aef4b8a4cb2e1964f7246f2207de45369fa2691f8324ee9f56512df94f08e9afb6fa6a411d40bb9f135bd06ee932ddd644b3fcd35baa5318d8b4d78c49124d293243ce6b385c67dcf9dcf96223c8f3cd4853f354226cb26bfc5cb5d169978d9651671d485df97e16449f328546b6e1d79ed7640a3386a4cff74215a763f96670d1c876899c7966cb3e8ce73e6e8805ce6267df2a43fa11ebab26f5d143c021a7153c84dff86845c2074040968e413f2ff849cc6853ea1c6b47af31aafd5989fd3856eee9ee4cc6b4da391337246f20047b24672151a8045671335932a5cc093fd47cff33ccff3aced6cd7799ee7799e67edd3afa5a06513e5bce520edbe70f3f64be145550a99b7fc4f55197393f6a52f70703bdc3229dc7c11036970af9b5238b59f1b441e5b2d6b63771d1075e14dfb68f42bfe68e5d7e383d2b798567e3435dcf3a3f5d02067edf9685f8f9ba6db6efad128f69efecf47cf6a4c77975fcf47fb68eda21d59bf6be841bcf6cc85f0ece11659088185eb80fe083e1764ff9eaebb878a575aa03c34fe5060c40942dfcfbc4994e0961031092a914f7a12e949311472bb177ff4a33f47510cad906b3f24c21dbf7bfba190db1588ec218643b8a28cd39c2fffd3344d168bf5ffabd54aa552a552a97bef388e2008dad9bb6cccf6f2a7dea23e3232a669b258acff5fad562a952a954add7bc771f4565bdbd6b6c5393adddd0944ca02f16933f83d8e7dff1083371d2ddbef034f1b629cf05fe0e35037bdef067c4afbfefbfe6b1faa426e9db341b7df9eddb4f043f0fbdcdddddddddd2dae7aefe193e23a6b716110c4f69977c7a1d45a101cc77b5329956ab5fa67b17064dcf435dc4e22d66fc9afce3bba6c7f477762873ee8f039931beb644a8641b82d54cbfd8dd32f633ec1aaf13456335444a480b832461836301cebe64e0e855c24dc18e0348d5fedb1dcd5fbec4ca98bae32b92b19f0440d1a33880042060c9b17333226eb57aad41d415b5fdedbd2662b840c0c06b34fa90bea02cba8dd0e977ceee4d70fb9a3b76c2da67d69104322b7ff465f2495b01d5986bd3eebb099f4a432f4c1ed9c4cb2e559338e5cc17cded3ed4b95eb2b96497f36cd8932a97491c31e5c180c0683c1603058df32a52135d1155ad2a635d445fb26136938e455c0afcf527d5fdf5cf9177defebcbf8b0fc8bfe6a3543a522229502e25e19e30803046decdb1716bfe8cfb8c9827362322b382766e21c15db876b78b60e33c0cdaad22a55a555aa4aab549556a92aadf2f541d0c65b1e4305bfa033deaa5f69f9045579f1ebd730bd455568780c1638c6f2165579f2ebcf701afbdea22a4ffa6a55bef4f5816051f9fbf565ac98be3e8ceff4f56d6c20eaebbff0182a1c03bd453fa6a3f2a9af3fe3315474f43a29aff23a2ad896c37f84e98f39a5a4deea9545956397cad57bcb2c655815df50dc0a441ccfb097e7d347c664fd4a95ba23d839361d9d29c5d482e34da956cfb2c14c37fd77b864c7326e3a1a441919d3fc9e3e8bf5bf5aad542a552a95baf78ee30882b67b6b3b8c53fac8c88058c6343f6cb258360fb3dcfc164f7fb562f1f4552afaa954cbd3bf57e5aa95a70f82a0b7acca7acbaa708e7dfab52626a3a3faf1edb33c860b8e993aaa27dffe7b8c1638c662f13aaa95d374d887058ebd8eea4bef619f158ed9ba8fe9a8524ef3619f161cb379afa37ad35becc38263b6eff416fbace0980d44bd7dd016a6debe0575548f126305c762e2eba8bcea7554d896e3ed98554a3ade946ae5a64ddd72452a59632953decc8030b0322c1d66a95e055ca5d0842a94512a45235ed4d3f1f414343dbd4fedb7cf0e976c5f4686a57b1da6b9e2754f9fc5527dded3ff5701bfa7bf5aa584e0d357a95046e1d34fa552e2ebf87b51e3ebf8713c91e3d3074113e97574265b6c17c376b8e4d2ebe84cb235d6519665599665599665efa8b8b7025146c69aa6c76281ffa3d56a54a948a9d4bdf7348e29104c79efb7aaf7c6383bd97d58deedfbccded5bd8cc7e8704e4ce6b3de776f637c382766861ef8df7b31429c136389600c11e7c49e1c8d2ffe2806897362abd218a38473622a13e97ee9494f3f95425d1c8bdd18289c13bb288f63b1d929060ace898d2a291c8bcd523154704e0c5c49c1b1d82c25c60ace89596fd516158ec566aa182d388705c7a8b7fae9af94d65bfdaad27acb5fa504bdd59f52a294a3b7fa53a8f27aabff642a53deeabf65ca5bdeea2791e5ca5bfd63b92adf5bfda3f2bdd5ea07cbaff45afdb694f196bf8eaabf1ea2cbb8d9ee2c37dbdfcdf6959bed2a37db536eb6fbe8663be866bb75b31ddf3875f3dcc98e69cacd7e37fb6ddcec8761f6cf70b3bf869bfd0c2877ba6d0cc40f6db7df6130180c0683c160b029c41009b71f0461a5af5fffdcc915c36060572afdb9934b180623f18845ec231c62ffb07bb862a755286128ffbce18e9956610550a6551c0157d3205256efe08a2120a1c607969082dc33dc0f1fb02037cf065060852462c867cb881004202964eac4034bd041159916b181064054c8b449170318081142a6391d2c0cc948902993580d48e6814cdd1c5ffd381f1010992c9f74c9abf10de969c6119fb821dbf0100777cc384fdc9075704f8a23911e0683d970b3f19f94c908d326b99f16e5a64e727ff3e47eb23b1288f429fd94282373fa989ebe699e708ead43fde9e9b358289c63f3528f7afaff299c63fb503ef5f4572b149c63035354aa149c630b3f9552c139b691ea559efebd2a9c6313c77105e7d846965f79fa20c882736c64cbb33c7dfbf67d5a708e8df4b129deb5fa96a7af8a6f2e7ef9e374be4fb3cf0ae7d84abf7afaabb2a5b4deaacf5282deaabf528edeaaaf2aafb7eaab94296fd54f2955deaa8f52aebc55eba34a96b76a7dd3bd7feee48b61254cb105f178536e8278f5e1c72c1d7187e4d60a31a4e2d22a8e80cb383db3c325bf4c52c4a31fbbecdebbefba9737f29ee2ec64ef46fc0f9f3a79fc5159c53af26ce2536f8ddea33f96dd8b5fe9837a4a0e818aa1def4c5f2089f1ed6e19ec5ff46de8f368ffe8c658ff462e926ea2df0752eb6e5b0effde965d452e9adda6244ee482c8e4a1f13884f9d3c7acfd3b962ccf43af7a9b7467c7aef3dd8bde7ea9e0584d9fc611dcee2e1917b6410c552497548129f36c35ee3bfbaa7383bb9bb21bf4422b993e5bb4c1f68d769739713a3def2b791df79df95f449a52d953ea6177532f9a3a99cbdcb4422751fa3de1adff49df76469df74ea28bda71e63f62ed383a60eeb18477c7a1efffbae3cc566ef3a6d269f7a8c138e516f9d2f7eecf43aa6a7de3a6d26e1b37bef3c07313a95b377c56cddebdc37615b8efa5dffa82c827a2bf6e11623583c7cf38a229f25960e8bdebde002e1dc4669692d0e6e3e3d898d0cad02e827fbbf80e1b81af6ebf7b72db970ab16eef92c1c1bc459166a72cb1939d222adc13ae492d6bc8952ead4e2161af6a911b229d7985094756034cac970d7ed4604bc599a3d814859274afde166adb687baa82fc33b22b9ca6a4dd8cdead78a435ccad5182ffd24a97543b95b765cae75942bf128d14ab352ce8e70b736caa1d46e2dfb8f46284399bec0a0132d1191ecdf31e99ad8688dfd8a6d66665edc6ac383778f78c6c6e6c553173e03beb0a1266badedbaae23ca231e37679e4717b414476cc775aabeb2a51ffc1d17ee7bef6b7cef7dbfe73d88633635c63ff6f93743b1f88303eac2e5eab0d85363dc62b156635cfca12e7c445463c49e6ea6eb806a8c03b93222103805da0e664d0387a7ff3586f2c09816056fbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbdbb2dcf4a7ff2cb3b3e48c9db1e286295be6664be19e4dfb7e9362d3bdb5592fb87c97162c562d2c2b2ab7ddddddddddddddedc2c5095e968f8660ebed3a24a3b7fcdd04e20cd84768d6c10ffab484d90fc2063182ede68c0de7d1c298dc5dd29aef5b874c4b1df26782d7f46af7e87e7c2ea531b40e09e9934f592489aa56efe047de0f55b7946ffaadfdaa5ae15fa99ebe18aade96b7d20f9f9cb16359d9621db5913851e3704e435d46449d388dc57dc41681d198bd86a099e2ece4f09d471daa434e5434b34d9c86c7692866e24e64969edda46fe94e54850da826a16f2b923ae4661d62c3cccd3a54c1ec44d51f04ef55fd10d9244ed316933a6aa64f9e3c796273e32a543b33dcb3fe0c41b35010a0214e53a4deaa11a7a9d887fc266e3a31f3d9385cd7381c5194ed03c424067f6e03a99ac8f7cd14ca3e943b09ee556e763bb8fde0ec366e5cc5897e81fe2708137b83ca725365d237dfa4ef34fd9952da0ddaa6d9287134cf8f4c9bc7f940dd0c6c9021f66604fdfa95e296fa140c970a7aa369b1a3f5716fd7840b76159e881731737024fbcb00e00150d2ea597c7e78c604af8a7a0f809a767996c23d7da652f5f474ad05f547e5cb2587f8c67b1c7fcf3eedbaaef36a6e1a0b58b2fc7d62c05931306122c3e56e09544806936b422db370b983a1e5ae5940b97b5b93e5ee6c1a8f5c3fd4c2ed198d472d0b4d6b5aa36028ab9c250291b26890f75ed7d4d62021415e907f1ef47d9dcfe45a65e014df2d5bd26933096cd20d4a7dea94fad4874137e88ee387411e0ef52794b76f4d5f68bd964202c15aff4502abbd91ba944f2191469844eaba0e9f2352d0185442499d4d3b7d68c53d592b2e2892847cff557c52d22de8f49a872b79b8d1df528934fe3806d9ae1b35eeb3ef050969dbb7ef866a941231b442fdee9e36df91a91b755ecb5d774ba53761d3bf6ec9d4d56e792386565c72646fdd88e456dc6b7a5357bb267c7a40f7562ae15ad0edfc72179f146745fd72370cbaa5bf55566523123e677e747635af5971c927498c0b1ac5d1c8dddddddddd1dbbbbbbbbbbbb15b776b51bf8206883ee5971d8eb3ab07673207619bae1f6d34eaac42a49629320b148863c3b74c47a47843c2b64c47a466e9ec904c37ad8c774c23ea6d7e1922df639b5ba67324be8e49e33d9613a5cb28fff135df5baeefd697c1ef87def4f44088ec29d1f3e6c5084f0fd6588a3d1fbc318c51d1f20810990ec6f438e777cff17a4d7e19249ec73f108a040beefe8ec735f874b26611f13c631db4b670a54e4fab6d2c76c2f0e40a10d36d2cd2b33c0696c67bec77aefdf4d70f5e0872a209c6694fad18bf7c511e3bcea8f24f82409e3bceae3d827d19430ceab621cfaa5f7afb5cee017d806c39031c2407c98468d27182084250cc2257720d6a78296bf0fa9a85d38858bbb24321c6809b25cbffa4c770b1232f3fd27d3559c6aa3fb7864efbaafb57a7bed64ba7e5ee77d5ee77d5f4b992244860005f90152fb41691fc542eef0d9e5eebfafdaee1b1a99882115602fcfb0d7cde8d5fdab33ecd5bdffebecec3226eb57aad41d416a47e74e1e61187dd8f830f261a387850f2b3dec7b98f7b0ee61f661e093602f171fc35e4e3eece5637dd8cbe98ba1f81a7d68a37ea00ed0fba2f83acf7bb9db1bf6e56de44871f388b1129faaead394e95b79f88491eb5390e2194aefe9bea05e700c975294afe35da2706921629f1638660b5958ec23aed82c8b0e6b6cf93a665369bb6eda121c552a292829d4292cbfd2eb6cce994c47a3d1a865312974449103c78dd1e86db859bbbb57f86d1f6e9e9e358fd5aa5cad7eb57259ad5aac562c5638567f63656354f6acd6c4645e5e67f5f763bc8cf0ebac5ae631f0a87c9d55ac1c7d4c6725c5e398cdae74b8e098ad5b45d122e5ebe7f854be3e0e1ba88ac162b4b2e131588c5a7ef53a2b6ccbe12c5fe9b7b0ac94a04a79514ad5ea59a64c45d921fd74858863ff551fc7fa30926ded30b57d538d6ab7717d1bb2379a111fb93e4ed7932b127ee4caf22ed2c9904c9235beb81aa9c21478edf8819e754a7a4a924fc7f1a9283e1d8d9e86e153107c6aedd3ef7bea794ffd67667830c05bddec096f7549786a8cf8a4485a46c35b742836c35bdd112988f05627a40308109fd4481432bcd5dd72c0f0160c1c36375e78ab7bc73336661a06a661601a06a661601a06a661601a06a661601a06a661601a06a665647898e68cc5e2f96fd96a1553a9a448a574dc1bc538e600411cdeea6070f71f68d70d6f753038c786b7baa79d7d2266b4d058d560f1440b06b8fccb070504103264c0806163f3e2c5cc8c0bce89c9b4cb64fd0a0819306c5eccb8bbbbbbbbbbbbbbbbbbbbfb97623e2ab2967ff9a4f0acfee5833263f12f9f54f3f069f12f1f941452a874e85889228a538e1c261c38ee8dbf517a8f06f6faf0cb07a63c7d7262322c704ecc5ce19c186ba59282824251f95779974ff9168ff22c3ef5ab47bd141e8305e7c4542ce5abbe7b1d1e83856505ffca771f85c76069797996ef3ec7c9c4fa96ef1e87c738e19c188843a9fb1b1e03079c13b3389460be64c363e000836333cf7ac1e5bbb460b16a29a9b75856542a292848b2b75025f5d6c9e685ed543b236ff104b1e2e08e79c6677032106bf77dc7632477f6713e7cd6a7551c4196ebdfd8b7e25a71719eb8217fadb7300af7ec5bb6b5dedc3422746408491225b825444c724d8a9cc878663cda7b72fb8fdc434dc3389d9be276bab3b8121ae1f6affcca4ab3fcd9433c350043be51b5a8bc4a6dc21327b8c095634b69417994161cb349c600851fb8726c29d4cfacfc8c4fcbb37c5b17e8e00a2ab8726c279357832bb080c79563bba5d20f1f3628822bc74622bd2020c10635578e6d2cf900094c80b8726ca346c30e9ebcc1956303470005ef59feb5e2b3c231110a6d78f2c49563ab3fc5bb5a708ecd7ee9c91ba640858b059f9d613a99e55f2bf8e6d599e569a66eaefcb99357304c85a99b2afdb0149c24f7c3521876c2d44d533fec621809c3460c1b611888611e86595cf1f9229f4d0b8f5c5a63f14e0c62f884215c6a86cee4121621d77dff59c2757f92ce1128537a8e68a12cd76f4c4f0fd70d594cfd2ba5efd4a9ed86822852d2bfcbd32746fa17f8f5418f31e298ede50979801c71ccf6ea0c7e9d628a77913887e70d2e927aabc3a70e073f27a633d2c20a843ae022b18e27e401d7886d16c3703ac37c3000832f00e189cb661f2cc1724767f0c312a7334cc4afcee2dbf1ed7f256c47e7ef75b864f0bb1267f42f11fbe08cb00f89633936f06ddd4ff1aed16637a085150875207fa527e481ec959fbbd27add11bdfe40cc19fd149f237e9f33fe149f43fe143924fb39259b7fcefd29de95637a5b7d9c1d0b8e37e5ad95b71ac3c215a8fa52deed464ca909ab98524a75c01dd0bb0de2abf30e1be6d2c3e7983d10fc469ef7f4c67b9cfae7ccab94fd77c0ae4d40d1b2e5c0a9b35fcb9b1ddd0fb9d6da751b68c2bda98f53bbf7aae7d5da358ea263c2455141a4ac7324c6727f28847b86b2f06687cd1e7eb964fb348bd6b6103bb94f0ee40e95706fece3d897f7f54b1d9d2975e13b5e5fb60fb37847cdaf58aebf9375bc6aaeef392cc2edf7fef47037fb5ef7a110705884db6f311ee5c05a6badb5360947b8f6e5337b574c0adc1284d85c311b99d383118080882b661b635de88142912b6613777850048536b862b6d106b4200220bcc115b3792110f2802b660ba388d9c09fe25db11d97ed3b77728761245e8d5825e2d4085f0f8f21063f4cc50e9f9ebbff4a0cb87c1870c9213ec1dfe192437cf67b1f7ee0bba5f96647cde797ebd7b08a5b9fc78c4716934247143970dcb0d13be8c02052d6e9c9b2d7d108ae77a4877ddbbd5137e96ec3ee2647ee9fdb91bb0d474e7ae8e3257dee9d7b76745278ddbf1b82a4d0bd964661e8f60bdd36c9eb46e208ae7bad847fbc9d4d3bbb21f047f8acb2efe6e53edc433907cafde0bda984de937832033841a4ac13e6c6a205f90152fbd1e3c369685df71da6598b5f31b28eceac1a75c1819335cb192c3b873fe4b008973e7df1f3aef397e1e1102ecd270ba8fb1d9de3243b5940373bba4cc2affe1d247e7db97b18de517387cf1d1d60c63b6a3e71cbe8cf9b41cf5d96b2575237e4af3c4f4db837dde3ecd861f3d367ed80baa8b2ece1b369d9c3e1888872b9535177a266b9fb908adbf99c01cadd50eefe3cc972874fcf3b593c72fd90092c1e4e73b268ac19abb684ab93314cc72be6597bb268b9b68019fb8b82f8c2e98cd3bd7d3f77b247719962af84c160300fa7d2fc79ae565b2ba594524a29a594bed7bcb64fc4d008b4a61ff2a0667fb7417726e856ecb52b1051a425d14792f86189f3ea5c7f2cc5b044bf54dac217c9300c3f9fd28bff953cf2f41c7ea9547a4b2a8962f71efe4612e9c1b7f635fe2bfcd7f8df77a5f7a41267e755b237a40f5fb491ece9997c90542a75251be92d4833b9c3e5b4f8c37287cb098638db30fcb1a4992c5f3ab98ee2ab73ad21cd2c1fbee9dec3371dd6e12c16876e00cad6abfdafd1e37cefdf1e3ebfa7372348929e64c9eebbce7ef8b669f769febed108c4e248fc97f7387884cfef6f464ff3fddb341f3d3f6a407e82000d2152e46644e8c81092348aab381fa2dd806a3799cde56c5127eb665d4f0b44eb7f7a41f82d04226589943a0decb3176e0dc770c1fa99521714c4e5532ed3673973f42d7bd8d2b7d6eb3a8b3bcff33ccfa3f6568320824ed32284ffa9ca0520ebf0f210764654e532ed70d98a271db9b763f2492b2ee949f7495253dc4cb7dbd1529c15228e82a8b5d88a5b7fc67a1e6ef40391e280bc709b0bf624eb4cc99b3ded8dc9adf97449e308f42a297ee1e992c611e85552fc6cea7449e308f42a69c52f75baa471047a95146d4a4bea7447d0ab624b4b8b25edb7a4a44e97348e40af92228b4a4cf148967f892d95a5e545554aea7449e308f42ad9aa94d4e992c61158bd56a5a44e97348e40af9ea18c0bd7dfdece60651851041143081104100670e5cf6128c3882288184288208030802bcc0778f1830f3df0b0834d0d4deb5bdf7780173ff8d0030f3bd8d4d07cad1830cc02e890830b19010420c6da1830cc02e890830b190104c0c6106066002b00c0bc942e2d58b4b410e0614d3c8c8987d5802df13025604960188d8721f1b0231e3603b7133834c16202d7f8259458498206124790a4c882c3c39a7818130fabf1b02530550296c4c36860181218760486cdc0ed84aa891426522f8a354e4b5c2592a081c4115ecf8035f130261e56e3614b3c4c090c4be261343012f8083c038b3537bd70fd8b1019026483d81f0bc4d6ec0fdb6369d687e5616796c7ca9c1435c93121c22d519204c9d0112123b722448086d420f5a702a9b5faa3f6541f955679d459958911209d7827200005145020e0e5f3843823024ef81735c931215a825392040148480834f14dd880828967e20135bec67bcdc977072cf14b344089578201497c120ba0f1341480c423918023fe8827c87f894fdd9cf1339cf829de45be440860ea6613186603533799c0b00760ea660d7cba91ec0f7300a66e2e814fbf3540097f1803307533090c5b00a66ed2c0a70fc9fe300560ea26121896004cdd3c02c39ec0d4cd19f8f41f046077a21d8f6af70c6567b827c9854bff24995ccfd40bf7b4371918aee804f94ebc8c269a78239860e28ba851e38998f1f9887721f106a0f14024f14128f1422ca144123fc5bb682071c40cf15fe42ff1439064880091fcf0492764e0d31669c2087c5a224c14814f3ba40611f8b4404b0c814f1b440921f0697f9208029f16080d20f0696b4818009ff6c7112e7cda1e04ccc8f8b43e4223c437e20f504411ff820822fe872186781f8410e27b082288e70108207e07f25bf9695c5f63005726c37f896f80b711c54f4618861866c401f0697914f1029f7646c40ff8b43c43f8804f2b13a2077c562741f080cf5a04c40ef8ac4d0c6083cf9a73d5e0b332c934f8ac4432c8163eeb92ef87f07ff8183ef8f0307ae8e14d1e78f802881f437e005a2f009a97a97917369fc30e3635342d28c4ef5fe1eff03ae09b57f679f1853fc4c06755e2030c7cd6243d98f8ac487828003eebd00e3ae0b31eb1c9019f55a8c6053eab111a5c6f2d5c8b9001c06725f2428cc1671d620bf07d019e003ae8f03339e4f00370e1e25732320f000140218087094000fe257c16e2b720df25861443fbafef63befcbe16d37edff25f010880cf1a4487197cd69f1c0680cf0ac4c50a9fb52603007cd61f02a83d0178c167f51153e2b3d248177c561e620b7cd699d982cf2a0b59e0b3f200000a003c0e3030cf82e2e5e53114e54ff1ae0a94ff507c5fba11be4902e2a326403e0a0558bc0a8e16bf5201979fe25d385ab0202570030a28bee55ff65dbebb79f5cb67659fe56dcb9f3bb905c30080033edd090c0b9f5ef482f1e94d4a17ec4c5a60ea442c54f0e94b1ce74a3cc98a059f3ef439927c86b2970f14dfb2f23eb377ddf8978acaa7a0a07c0a85fa93c9f4b774a3f4240a903fdeb05f2530816ff917cb5360023826811b160a9c63eb5a5afec5d2f2b485e5cf9dcc82612b2a7cfa1115ec4228d88da0b0df4cd88b94b01321b10f71a0107b90cf7ff2197658ac39907c86323fc920e04d822bc4d00cac27490fb770e9f85e8ae28744f7fb0f7c30fcb0c975cffe58d617cbc679ff95b54a450565e0839e6541943639fe787a8d44126231290cba7f49c7e7cc4c502583c8b36f76146f15ec3cd9f80691b24e1104c1fb610d73d7b39794e89268644b867beeb81782f696dd7dc4e18758c464b89e089667df4eafd142f0436ced87a527761d2d08feb993414c47d3260c411c86d65a6ba93ba93e657df82607c5610fdfe4f05aaedf9516dfb8d82015c476af38182eb775f7c7e91eda3bb6bb48b4551cc165cf6b4e4494cb1515599995d9999d5520a02a9bcd68b49e9e5aeefa53f31aaf794cffcf0f101011bff9cd85685745146a39c74cf60769155090650fe7a0b8be794ddf5aa8857aa8873a4927c1e188886a6c784c3f517f918754bc7a0604ef55a9febdfea8801302f4fdf36703359191900a545389d4dbad0a65af43d96b124a71def79f7856a016f25fdf46a10cbb10af7120092c0d075465b6abb9056be0cf2da948e0e89e4c26036b325950d7b937b3b93795d0e38270a787137141f6767a32f1bb7536f7a622e1ba5a5793892f9edf2d4826c4f370b46f41b51bbd32d5ec69b9305c120844213342bc6f0c5a5910a6ee366a4c7d1c5d54bf6706db5027d32d79b666813c2ffc7006756a1a0d9af9c2a509f97cc8ab0f552f97eb7b4544b9e26f565485cc78b8b0da2f98fab362a4e29f4d3b29ee9cc1d598fa4d54637a7235afe847966b9d11a9a4207b136b106d4b13d261215dbb7eb8e476b83f9a870691b21a6cb06b3a5724bbcd724d92fbeacc57c1b3b40f070279431e06c39ea15a125c03110901430f04a990fb6117eed775176ec5607f3c22659d334284f477507bca87e2090185348de2282ea893d914b1a28034576b6cfdd326854f3b7443e1d326113a554b946bd0ed06dd2052cef1d916a71a5c82f8fde7d1a7cfa24a41dd6e2e887c2fe86b4a51f4acb213fd50c83d7dc9adbfe40a317d09f5a110f1417c36adc3dd9ffa6f42f8ec223b6493f84c059f1667bd27e8b4b7133e2d2d77eeec1c3e2b2ef7931c9f75e4987a5bb72dfda1400c9594b82b5c6e4a58d4ae683955b833e566ff4cd56a89146bfea1ccafb88eeb7b599f8aff1271ccf6b2325976f1bf8f85e0babe7732bb2e71c43a248d47267389d8d61876e3208c0c4e406f7d23f70747584767f05f224ef8af11f6c109b1cfe8628339341e992c7fa595c9ce9dec9ebb2855cbdd872a528408912143808050415041503fa81f14101410540d5543fd40fd40f5a07a503e503e503414ad08912140a820a81f1410540df503d583a2a17cb8d93d8ac70cc58342c99c147d4d724c88ea929377c281278ce261c2a8d9c5289e1246c948f8e484c4a7a20f9f9a88f8941be11393119f883c7cc2b9d97dc5a7256e76df8bb6c4a9bfa3b3b59603f9fb62f9fbacb5a1b5d5ab9eb5d576a5fa9eb5d65a6b6d77edeefe3eaba484bb82bc29116b578432251eee0a2537652a824859270ee18757dc9325cb30458a102132640810104c109820303f303f30406080c0d4606a303f607ec0f4c0f4c0f880f1014383a115213204082608cc0f0c10981acc0f981e181a0c0c8f3ebdcf8cc7cc34e3b93c30b2128ccc09c9491159d4c4078563a826b91c931113a29168098ab58485eb687eb170a03d61181e260c33bb1886a784616424cc7242625611ab092bc762c22272d33eacc32c1c662d71d37ad6abf664c96ad7ba81ec794dc1ef06473c8ea31f6b7f8f4afb20bef9befbee5a6badb5e213e7abffd5ea795ac0a17699e0b0e061e10a5f077a9ee77d60e78125065c3208821d3e3bef3fb0f3ba9dfc79ddaf54a93b82b4ab7f025b0591b2ce46c150aedf05f90152fbd1e3c36968344f4625650ee4f17fc8a1924bc26079eaf05c9e2c59be1f5ae1d2dc83091322a2254b7038254a922441826468e8c811212123466e3726444b704a9220193a2274eb51c4b2bccfac0891152243544380548082a404f9097f80b48c80d4c4da8fef474ff7f8f0ecbfbaef1e3e7ad0dce297c528b863c1dda3c80aee1e4454b87b0c51c1dd032805778f2021ee1e3f23dc3d8088b87bd43edc3d7e34ee1e3d8ebb070d770f1f6ed6d1e81c7dfdf0c5fbe2cb25a3e01b0f28557a89e379a5df617ad893a827714bf7322aaadc51f3397ef7a77247cdf64db7ccc19265924b26959dbbb18491432aa8c5e18bff95d676dbee9e5a3b7af12b03ac11a8b46c97753def189a010000000893150020481c0c088542a1340f363d560e14800d7ba24e825c1fe95112c314340600030c108101000000000060020078414c13a888ba0ffacbfebc78a113fde8173a0b10d6179fd6417f0112e8ef3f0da7dbc648ae00f9971a4bc51c002f426a8e0244e4b1ec06262391b00c7171004a481161cecd03c5e1d09b9f7865f7f4ceb5b5c812f5414b7ab525b2d8403ab314203914d83dc573060138f9eb5fbd2abe4c60b786ce86dcf579064093e99445cc30071161c44322c4e5c4645dbfda7e76c051052fe2999ed324c79643352e49cf12b45ffca0f820bbd736ba99a0316714cdfe404e2ae56db4e1a875e56a40703447ec5ec6d1239a90cff829cfa54f7070d33cf3c3a1ce669f70a00c5d3dbae5154cb1269df15ff4868c98c8bb5c87fca718cf92f9c9378b2b13f29173ae5c00d0a9e8e4e1bc2c6ab55aee62317ff815f35e66bed1d70aa42ea7a0de1f08fac59965b7bea9d9fad5912c5b9c62e911d656478b896695ab7330cfce363908fd3d8be5c0c84697d8ffb60943bbae8911377e382fa5eb5403f2b1d151344f2bf2093a5227028376f0d8d8d244a87dc43c54d49e464c7bf699bbad4948cae1a9d43bc02fd07c8722a0591a35e082b1afedb95c4b42a7a1c1c33887c90530b6351db90aa22a2092dce4044be9634fa537bdce1390ff6cf96baa8e49f4b75812535e4b48d66e3f557edf0001d3f03c8dab92399826c5a3185c4a8a71c23664210f934527acfe1baf52644f51ccfdfe2e5ba15d63fc759cffee8b7bc8ba6ab6e87837564753196ec469024360d5e58d083e5f96af4e7e3b5cbb127cf2d8614374414f147f058a2314560defad15dc7a0be8687a950fadfe96d10542493a68e4d2d86e7cea5e01ed8358dd0d2ea2c0eae98ab38a2326ae3dd04b9caed028285c2d75784e69c32831e73f2b675c8cca56da47b8d13a489b5b916a7b49990e7b5aad6b714e12146377ccb81b66ee8e32f6a399fd51e6fe30a373ccdc1967e80f19fcfa583f9eacda14b51403639a783002f398219c4a8f0e30a4011bd0c10c7560431a90810660480332a0030cd3418635a0214a0b3adba5a8218d79b860682166937423ea6f44cb590a061d9b1105a7290ce8fc1ad1784e01846b443fc969f9838e3423dae329d08b477419ab1745ec33c2881ae614cc1d8b46143052e88715d73d7ba4952e70f1881ab0792cbe76784991021e51c00adb06759a9aaa83e536a22e0c5315d3463416436fbb4a38a20ffd8e5bc8cb11a51073dc46911fd1525bc7ed3bc3883e753a6e212f479446cc711b457e444b6d1db7ef91407e8f1e02ab3aa267deab05d4414a92800300cbcd7e7478bba15e77ffff7eda6ffb6bbfedd3feb64ffbdb3eeddbf26ffe8a4f3e34bedab17917ce8b11bde1615c8373ce97ce6817e43bf6f60e26af6e8dafaff7798b6d660921b98439c95ecc9c7e61467208661227313f5dc02ce97b6644a73197799bb9c7a709d15d8497e93b584e9fe15ab7bbd942ff5ec25c6a2f66a7be3023350433e949cc9c2e604efa3d7311d398cbde664ee26ba2e81782c5fc192ca66f68d7ddfd6ca1bf2f612eb117f3d32fcc900cc19cf424e6a7173027f19e99e834e6656f330f6a6897cc9838bac570317d06cbec1bda75773fbbd0ebcb989fd8c38cf40be6a543313f758219a9059889bc319f668a59dd5bcc65886676a28a0e53a824cf3ac7cf5e1dda6708a207c4824c047d2f413d978e314e5758a8479bb1c7aaa5d900cf8ebfb17f59656bbf976aabee6bb50d5611bb40b03bc12bcc7602b639837172f9fe69c38a04b92196402d746afde0e59a1fe17ce34ff8d30a786fd0dd75059f939ae4a946e2aef6f46c9dc15668f07b3d3a5c2f8d8cbdb0797b6bbd3cdcda04314eb5c56dea3257dbe0715f358368ef257210565f86a686a7afe869642325a2ee2ebf047d8ac0f22270faa1da076a1e6a1af3b4db6358e70ae9489409bad72068a348b5ad80b687c4b7ed64ab8a44badb6240c4dafee19e533f344ed91e15f388e4b5b146c7024ff5ce9162dcddfa33d57fda60063d9bb41f1af726d96d8fe155dfc72b7a56f8eab7936ef60a5ff576b234819ecd948f1b35f6eeae9565dd537c2f064dc1a0eb3ff72fced54ed83c6a03d98ae7a26cb9619e9bbf49d247c8de904ef2ccc19560626fdf1df1553c398623745c4d2098187301ff1843cf1ba48e67cd3166ec619c4832f81f93c720a01eba6103614225866e7111709b943876c768a33982cd9ffc52869627b8ea37926f9757a61dc26bcf4da641d566637acc6c9c16e03b0f0cdcf0cff8713e7ad5dd73db4491d30a5e50c26481ef93b059e013280cba79751796ca1f655ac276567eacae5f205c2bdd9fb1b08e5a98d3405f15ccafb4160c3340df3bb474d30b6aa61e7f35ba4e2f2722f0bda29dd9cd78afe387efd27bfd2d3e580d834e97c587a78ccfaedfa8276a61c3a99a2ef9af4cb7297131e0f0f9ccb1cc08ab01a2e191e70368405fe823983bf131a66f24e8f601fa443a55efa3236a1136565229ef3e3bb98942b9caf7884ef99e0348a120dfece1d69d2e997a45c8a4aeacc35aa24a3df66cf82a041e58a6687478a45e62e5001ae7086b0204dc20d9d48f7783bca67ef60dc29afac13750347d1591c3b048e71a12980915563fe2565caf31d131c90059f526a1dce367eb4f25cfae7c9bdc977d5c6b5ce9d7de2ddfa520c7fe5abb2b18de0584861b00e9d6844d0302ed174e57404fe991491d0afa4702153ea73bea51f32ec2d91e888ef2cebdf62309c773834b35741bd95fc7c2300792a7635735e8db027dea993e914f499815b6967bb6c562c53d6dd72bcc02171047ca5bc988941bb9c82adeac96ae4d862f3f5ff51220a011921340bdcd853f01a44dc634e6ca65c0524d78d124b10913eb7164300ae11c261d3b5c0585e71faeb3e9704de64c467a941101ea525580b94c988459696fb9675b4481b20f4a0ab024f7c6a9d0de6edf5e1460122533599abed9426889391cb42d25c9c42daa254dfb42a74364c90dc09e333e58bfb9cf2c3839c3d8c0092f111e8c7e06b917133786693165dd0dfbc3cb581acb1097689472359469cfbb28706bc9be18c8ca9b7598c482da9b194b7017c4635279557871459591b8714b88966369f79241133144fa1061283c38f307181a02076bfbc877ad85561bc322657d90bd96647dc7bdcb68c403eb3cc1127c7940616e157aa0329c523da42c94427b586d62e57ba862dc4f7cc8877cdf41b140c471411d2305cebd8bf849cd158ad00e44489cd04fb7346265061f041b10fa4d007c97c6ee03ebf30d5ca350a437a8a56f50323655ce32760193a5a3c780dd2b87dc0f407be9d6715a55b91958b0917c1641cd8ba28585174adbe19bff031d776b011f2a11e07b9ddc808f5e312c9f9e9a09423dd28961af38c439f2f114b69644eafd571367d59e221c749060deeac38560b79eb38e0f795388b7d3368091b026d1a1445f7a2858125c6a60d0bc8e0e6c403069f2753e98364a9eea395ae796c01cbf169e25ca2013d445e72f8295e81af391c6a63d14007e902b0b92cd778a9c96b27cf6c4d62abebe89ef8f632f2b9e9b9c9b839fc135fa19d13f32f2706c2d51b0228979c587a82329c7529fc2ecc5ec737ae70649d712ae952ce306975855a72b19eaddbf2eb8f11265c002b8504702ec57a8d37b16e93a86d44af051c788c0ba0c9612507216eb6b301b3458b13f06e694db680baa4cf4277b55de3ab0debf22dc72e9eea9ccca18950b024108ce41c8e08077c1efdf67ca47c60195648b3162c9f6b384479a1ffd11d4845b195dadaa9473cb14953651118cb1912c76d630204142fc60ca379651904a0b1bef3267e3c719a2dc5e05b21aa65e725e7f6c3b68038855f9abbfe33b91482abcd81c2406415ccc563a1eae77f14b09909c99dec44ec7cbf8ff031e3e5118734c7234b73c4a53d04af8a8bf29f4108de7b072aba239d7bfee9023d4b32a0ab9b5918f001f502bff6ab2f855d6a9a590325666aeee82c3ec9d9f2ad50ba0b40ae08f574b3c71c8af5529a2d6569e1dec7b6dd622d993f157a06986987ac46c2e2b91bb9fcd41552b35a0e560fe3e498d79913676382e17e1cccf0e9319409b900c9c9fb39e4b07789d216359629bd74cae78a2c5e6504b33b0bde37f9233733290074549e9ac663d4ff3e7de6949dbe9afc7be6018cdf3a2fdb0678f617f64c720208c05141d348dd6b00c72b1948b547a1c178e48ccfbdd80453d5c25e1a2f0c1991bb53773ea2da7bed81778fae786f45ab0ef1a3809a3de4b9c685b8588090a4629c3e4ceefbd167adb61dab1356bfa381bcdb00c399295db73d0f0773f3fbc6a9bdc253294fda22682b53c0f104f77c6be43617582db4716327938d65401dd593cc0f3c836094f068130bdb7326eb309456bfa1147f33d0da40b9ad6292f6c0e455e219a6cbc35313fba741f0f2414b65ae888645f5fb06edba11c93ea4de0c0147897051e7c811765e006cacf52a79ba3a228de0e29dec6c41b29717390d8012386ff10a33b88c3fde1157b786ee09a91bfa53e75d595a98cc54636adcccbc35d3e86d1ee13c90e569d0c3b353a3243a16a6e72bc43351127a56eb028219620091e77100b283ac5a5588877b173b87aa0c62e053546bea2e176548dae81785bca5563b5bb174a7a3776170d8e22d98781e336ead63ae285e210d40a755ce26b8e5458408e19e3e5dc646053f18d45efe2f0f2824be5bc0aa6de61d3694cd81aaa9f46a35c1390a1e12a84030b809a1ac245149be6e741a7fc79e00fb5ceb0283c4a5f1a979572ea27840cf7ade420aced5724b2d8afa0174f7f2b27d457b1fa865c249eda7e4da1d40b293ab57348ab0fc8215fdae656fde50c4dd9b23ab522f8ca713d70b20a80d0ca1dbc2d4fec574b0d87fd72a9bd737c3abb069d724a2f3d13f408fd7c45b807b2b28083cbbe7bff4136cff4db7dcd46d7e02bceeee818c15106f79fbcfea7fc468103f683a37763e39cba7766459f51720a6828332c35a6d51d65895cab20a81b88401fe538df7aff0715a66635a9d2d89aa8b455aaad76daa061213a27afb0dd02ff33543812492e5b22cf564b590a1ba5f2ef9cc34329ac916e47f46e40bc48bdd6e7addcf426bfba7e0afa951ca986f0d02a556b6a3f3549f809a3868a773093eef6581ace4ea6e42f6bd31e81395a76dd424eb4e0091b3e61b8b4869fe9c1349b6309403ec5e063419ce28dc9c5618750dd2315dc77333806fa9c0bf0daea83ba7492ddfabc3e0b03fbb219ee8ae36499476de5b4ba9cd42e5612169926c200e158b1e94db3978ea1d32ea7bd3dbbbe63fd038310ffdf4c5853efe5a8c4fdede56e1f94667833caa585b8e1506af8a10dac8162f8a2a0cb8e199c24d10fd33ac1693bd0ad05ba28c306590210a48969786bd806f31a7527c8361d59f4b15a735201cd12a624f5841249591525b0989b1c324fd54ee23d8fc322f37c77b6d2452dc01531940b2548f25986151e7c5db81a502682db74b0932698f4940c423cbf95011ae7e8da5b08b4a1a0a4a6d396193db4ee0aac5e9c362b70621dfd573711024b7261e7ae38b5580608d8a5e88c235e0b42d45135f54980059a3e7ea6d15d0909087beee7add05c92546895460f877d8c04064ed75a9783b8177ab870cd31c6a129d079a913535ec81fb66231cf3d718189e4a6220a990348cafaa977da313f97d0afb068aed3ccbf1125718eb79d5d3c88b5579779c8ec54bf74c25c28efcde2c5513de9455387e03af3ce744daa5aad5660cd1cbb7ba8110bee6c72d61583481c24577b6f2c8f7a4f9b9748930297a761139d390f7a8074a737fb900ff15052b171bee0b53d3cb4b85b1bfceb8baf1b68505c45d536d8255d4005bb212c8a651024cf9c1b0a6d6b468589d7d480e6dbbec3439fb8164d88c15acb7292b693fcbf718501134938882070f01dbaf8fb5c308714e13e38095459db2aa86203a0d8a977acee12ef3ab4237f1b120c0e6277f365cc2bce94873eb091370819a2661101bed6eee74cbf544428b4867130d821913d2110befd6836142558d0136ab9ae0b328c9a1eb80d9df0ba826fe8d429af7eca86525845346aeb1b52ad512b056d10efbf3c1aa73268c60c58b07acee60652f4cb64703d00af3ffc662f6cdd9eaa3a6636d570a36932044f3c8290ccfec163c4aed32b4ffe35a9507f37ecd9614481618715fd27ce77596d5d66cc88f008a02b40f13b09746c2ea0e7ece1c933b520fe3fdeb4b84abc9f19706a74ec22c4781a101a0a12107b01da4d1932f924eed762cc355ff79569f2f8f0ba4ba518fed0b09b4609aac9fbff815914a470306f80ad288826072f8f8bbea077d218f69bcd149a6f20c2e53db8bb5e78e940f65b1fc1882ab13d5ca71cdd2970cd51e739ba892ee905bf0a0cb90058843c82cfcd322b876792bba3d5697ed7632ef158106561041c8ca70218258bcb1647a36b1edb2b357bb6d7b9392c2ff5166843496fe7a79473a7d735d73dac019029981d95a66d4be17790e557e153c78e7a0c2f8c59d78624a18ec8dd7e2d593a4168d5075c406315993d82b2ea6ce9621d33f1eee3817c78ff94a1de6c7f107ec401b628a906f2b31956022304e7b5c9e27ebd2225013a63deacc1b8fe1809182695ffe48592fd5c007b00783d01907c46579d5147fa98ed05b470681fd13f39f1def4ef05789409161302f17cbde69f71f9eed9956af73428d1191b8903e52828c387952022cdc5fe32f0488a1018fbd317ddb1c60d2a9442763aaae4afcaa6c0dadea7d36220fc7630a969cca94c3bc87a22e88ea177f94a22e2a67fb76d817ae2f791f21d796a70a9824dac272b6f5dfee793bc17fe7c66b7865c70a6f26be80985018533cb02843fed2e38b0c245156af7b566c135d5666f3f31282b9abbed06eb3d8ee4b87dc2dac5085a2d8a9d7f11bf04230537571e88889d9937bc6bef94cbd000eb70131d809dd0d05fa7c70c5b74c5cfd917eb63f42986f9a6082b5b59ded4fd8d12f341624dc218bac5d244d1f768c3ea84140ccf71d32546e59e215f9193c62401508909fa6712e0f812b9154384899e73a1fee480370753ad83b67b4369c687f6024b5d5122263d2409599283591c3c6e4fb4cf10344ecc245211a3717c21c36f28bf6ffd02d0a32f42bfe5bbf0fd9353ec434bce608bd84fa95405e07b7098f9a90f6a49f543161276eb492a0aa1552842688c9b0d5deaa6da599368b6e21c5112d2df9c54520248d6db6a18f62651e173521246796e636efc2cc7f3e8008deef32db7160cde66ce0aa9064418aeed81d451100d2b45e5a82fef2c03119414019a265b25d59a3f0a344b83e9be80611a424082685b7c8c731b6a2759235c705a6153730c3c06fa7d99a5c799482edb061cb65824a58c132499222fd524b8c31ae1595f6bdf08efa98ca7fce2ecdcd7437ef7b8fe162053f26f15cd48d92fd99014b47389fb83e38950fe5518a7c57ae36dd6596cab9df0be753ea8f8193d4689a398c4cea2498952c224ed31000bcdabfec6dc4aef0f76e7db30a4800a42f93287282828261099a05c84e7cc5c52e2d313d35a37bf7aebe6d7f507be1413d071cce7f0e296c7c23aae4046c5c609b9b3ce3be8508e494dfaf2f530a8d422dcca91965b1bae2aea082db57d8fd2252c3c0cc6eca63ec87db2fdbe0dd2509dddab0d6012074e8d0d31bdf45a1ef7fd0e262f13c8e35ebcf1c782a46b708f982853569ca3498be15f259b60b8177c66dd40a50a149ecd7e1e18d035dd14ce3c547ae1cc5418306ca66887672a32b657982abab02bd5ec979d3adce6f298c8156db36b9d96d982cb505ae5fa3c7d0dbad96342b6204e25b890e35f6ece24d61140437e453c7602ee2928ad208eadaad36e4e704fae3ed75adbde5c4ba4d88c4348578e93ab8391cb0d36435485ba48c7545216da78d19b9c8d7639ed145d798cfb4b47aec03cf2f4d207f2db1a4ce26f1b147e924ee83bb666e65df928a1bac3b97cf01f7f38e7353dd308494bcd0133061baea6fb55a401565e1d393c04ca56b55e824cb0f28769dae9d514df45f0a987246b8fb90be24568162fdf7a953b3518a38b4a6a059ecbf7e283a0034fc68a9437b9fde51e8e6c7687e49261ebe3e107cbc9a0ad3f35768f850967f6ac0c5fb419b1849c74b797629f21bad9222742cb4e1eef8d32eb5acae28a78f7d59ecd49f155e9d427657b8c0fefaa0bdb99bd747cc55fef85468cd799365169226cf6e209662fd3b11ff5ee6c89b3bf194875190473395377547ad1f54f93f51659991a0061f632d801035e11206751ab7d17f2ddc9c804901d3cde0785e31bf8c106b1a4b1a9abd03ef0bdc8ff52865c2fe2837bbec6f6e0ea2b7abdde2dd1ebfa171ad2755a0179f47d5f51687e609879eabf02e9ee1f9e7251fe3097688dd1d117150f34aa475fd15552e0b6be07cccda2662634c30d94a19dfca52da9e0726fdf840f238615623efdfa69d74fbf3dd2bb9757f3f26ebc7cfd97abfff2d55e9ef6cb2a744fc27dc359f210c999d181cd885dbed207835a72ae7fa91ed58ccff438a3d0ea593686c92c46af170a577a03065e5d432e4a7b1a8c184caba1c207399e302746fb0d2a2006e42418baca54ebd8e0cc2303db4274abf4e2fe77df0ba6c4cba86d65e18177373bb1d74be5c41a1155a7edf39aafe78ef7f932fe7275c1bd5c97006146872470272bd5ad06a2bb6f0e0b6214540cecdb44ef2a9699cb51a2a0ffc166f3cb9c160ecbd48cbb6f6fefef97fbf42f6919fc4bbcfca86aacdd6bedf1fd612ddd745bf5e2cea193a7db40cda3665277052d1b21266b5b0c52f5d5577571cb461c00e045481de24698fff730778c6a13a40250758367c67abae5d32c9f6e73a4732e2fc6e5cd70f9f82e17dfe5a3b93c6c9765d13d81fb8d63e5419463a603b611be2baa0e3e2808f144de8ad9548a4ca578d715191743fbb7486586dafb45c24eb3d918294d50429b3b7ef60471b141b4101320488d30a7385137429dc225720411c228cd14839b7d3db0fc909ed990302811b19fec87e4628ff43a6a561a2d9b27510de0e8f7343d83b3680bd12dd20646e23f252d0244aae2436a80cf1e95fea79ee5500dd8afda62af48b594d0495e24927dde8c7a91b79baabe19e86d03eae335835f4752dac62e5657091fa5cd9c6ce9d33087027c14c0e5cd0606474c7ced2791e937fce81cf6757a3fa4db2b88272fe5372ec8ddf843dcf12c70d2e0e6a472e3c0ca24ab576a3be84e7710a3459ac50509d30bdb487a124d6e0c7cf8cee4d01dabc31c98be346fa1f5ee4d94bc30ab96e2c58fb471fbe1e3d314ed207626b40a1179b5e47a390df42ddc607befe24cbb9ff47d75b70d19a11eb81578bce84dac6751e22210f23fc2776443ba75e48c1bd89053b3515b555eaca838e63c6beb30d1661765f04f22a0a7981174fff5300eac498384a9494106e627e87b846f8448f2a070130d53d992e356fd31c3f56d0db600d80d58cbd25c678957842e0c697e48886f954ad55d40a92012b66944508dac02d930f54b80c256b40d4fc7bce44e7ee27410411a9a34746928d950b2a144438b86120d250d4d1a3a5e9d838c63d7f4d6fefb9b7fb7f6e8ecd875b8ec7d25806a39ce4ad0d8e2c0aa041aa95c962528b8ea1a96a0c295cbae84f65a59478d7a7b2e66257a24a21f04c7ab8451fb694f2578af9b794ad0d2a9afcbb694a4e3f387317fa7ee8d248795ce24d4578e889046c8405f422a711798ea3ab6ebfe1ef1ab867549658338e26daec58963ba65cfeaf907d6d97ed661df9da0c7b6f742481bcf20eb3dcb2ecfc9de0f49cf974ea8e29a31cbd816453dfdc408ea857dab3a66c9c9dd7e1786842d31887fcc00ab574fd0b29bdff6696b97816922604d6fd4551d7cb02c166582f6c657744ce080e92c6b27bb2944fa1de6932ea18fd21078f7f4f0dd7952c1db43f9e981e6db385ae226886ed20d550ef32c308b70c72d3701da149f14a2230855ffb557351388fe9e539445c047d2de9b7cdca38d4e0bb2e4914052c779e95b24e1b9c1347580d801999b48672e5d910c1a8b0b2f5b0855b4e0476a0a7eb3eef133d9d314a18d024e50af5fea38f17326c0f174e03650544235d5d2be03b0df340c014aa246bed45696188194a3411c80646183bc7dbbc90b6f4277dcb3611691677d4930442ec14026704eb2488ea3af30c4bf8e6ee82f860c3b0ea3a288c38b78385c7693e0b1982f7fc3534fdcf0b9db0c2069b8d7245929143d045dc7e4eb6b20d34aebfd31898b02348db2f1e4c86a7dd1cc3f66027e63bd2b7dc48cc87a34617725104dd203e98caaa5085cf523cbe3a1d8fc64f689feb38880cb8097291c623c788f92ee5d22a4a80665a0c7a19256039d9222de20269257d0091063f580d52f20255ddc3b494dd1cc07ed23c4179722ca406f72322db1613d11d6ff0a147b8d5d1bfc24676266199f7e776a55a09ea44f3f170044d5b85d25309bc6b45087a5f21201c6e43085159738766d3c914d60fb8301fa1ccb75a5b0c04660ef16f7bdcb9688ca27438951fbed8ed9da3c65a9333f4128c8b3497b14139134f92694e2bcdd3607178f4e8b33798732ceffb7b8b2f0617ecf18b5caa9290f35cf39250ea40c4e81733027fdbd078adeb1c0f51e45cc86297487a01fd8bfb3ea309a5ed436776750de6f532f696cfed588fc3087db5380ecc7ad5a57c81f3641840f00f4d0ba18920559a9c989cf6b999d1af32f1d5986a09300b5189089651e665ffa6e2749722057a96d072e21d4390a2b0da683c6c82525bb6f21ca0dda7a20a879b2dbeeb482b3917b973562d28afab6e5afd038e239678f6065bd8c1f316af9a256a0b3e633a690cf96b397674ebd0ace2bbdb03896fbf62ec7c6e2303af78db80269a33ccd2042a6c508ff0e2f9f2d339d0fc7567970548f990df55b7313bfa8c8448d9d9051411cdb7e84d173825c88bbf33872d74b597986758e6a6a801ad44aca136a38e13b3a72b0c245908256a4b6bd17b051261978bb81480a783c544f3a62baf820bb7a16d48b2bc50aef0e66ad35054eb5c2dcec55481a805e4656ffa6c9739931d32f4f6d5f43d6bcb3ed781f834fee16af80b76cfb8e8e980a5a007d38a4ebc6725fabfda5218681d5aba17bdf74a7bc17087e3db5d8a9e84b71b02ee6ffcdea1c033a9405d74b72f940975c38bd9eb0801ca9678a1e5e9b18f06448ef9fd897fc17dc19ba9f9deb283072f0916e717f6870468d4e5fa6f3f4006d121360518a60f335fbd33fae3e74b0b0ae2dc109ae4575e989ee7a73cbdabe635c92b8c9c8ec2396b560d6f7892115cb1ad586a574362fdd2f54013e11b0bb6cb754cd834970b6595897b3c249012d7f1b7ed6d897b17d2bd6e53b7dc120c0e04195a7dbe9f08e5c38d7f216a3d5d3862283d0afc0b5fa23f6e06a8e213d35ed85aaa49dd12d2480a6aa7b08071e6f46690bc5578bfd7c4e5124a3b25680ae7584cad63dc5436409e813f8b3f5fcf7b69cdf5714f946701a170bcb9c90b79bbcff321f4590869daf3304aa3784c6ebcebd6d0f67c5c83e830c0c5a86f99d930083da2067b1f78a97d4bcab6d9c35faa8280f0ec3a43a7adf18b4b42589ba9fb15134e6097834bb6c2a88022d5872061263198e8aa58235a8f01a63f504a8ea97cb03c3a62c75b4eea4e8134f551cd589d91db9486b56038e67c98f4cca97651589de556fe1f6a10acedb1deee27af209b66e6f1c5632fbdae55bffedfdbfc5fafee5643d65caaa865a5c663dc158f4d4e6f2c7831d7c3a4a8b56df286adca5e0541ea2a7df4a456b64006e8d54e5772868b7200e918b1b29d72dcc839b28dddaaeebf4520486cda6f69266c0c55053729fe5b7de798d9835010497ae8c68f0ea0d3ccd423aca5bc93aca930b4a827d077b1aa672c8617522ffdadeaf06b132317bafe7b271e9e8b6954ee06505a76204a2720189ea351953b60a257023013eec72ef9216f461ee5713ee55bfb63d9e08807d4215027629255cdbbe0020748137d15be04557106bf0a7de0e2e3a5f3533d0901218569c2e085c540d90403065fbd82bb18bdcdaee9c97280b175771f5b1e1320232cc5e67f7c628bd1940d1217bd4ad0028b6d45da993848411e843e032bcdc01e9234ac01bac1dc1bb6eef0d0508e8368bb9b799ca1324d38d310b9000fac10cab8a4933fdff79c78ffbcdc37f093f29b14f80033fea11df590cb98486b8e032488378539eba01b80c03d7876c089246cb88fdef9a5d6c189b9cf0b487fb598f4457f062450d5cd3f25e63de382dea8e61e9f23a4ee959a10e0aa46888f5b358ab5c6c0b4de679b4ee396925dfba656105b15d1e777eb06db6d0bf83cda851b7ec4c69bc712a077ff64c8f61ca6172f1c3afc03c13cc8f3591a7c81db112961a242dd42c751113bd0c777ca48847875050b506c09e5c62cba6b95a27ad680a0614ef16b6428eaa0ec405d3a22a3a254951743339d4a22811dd4e2d6874f2001219babf280334e68d6a1b7043951a15212950439d18d40668e1567e2156a27b86961738479dbb9d6319df9fc27fd26c0881cd8d73827a813db36f26e2987fa0c9c62cbe7dfe5fcc722df065629640011f1e6691fdf7606196107f2f07b38ce4f731308bc0be1fffb2c4e57bd99765f8bd19e75e3e03a02b6af3f2994885b4f6b270d1d8e6c7ac3c9574e20547c2b8378b986527afe4802ff99a97ac96f3a27cc86146928b2094fc63770ea69c5927e46115a1a9e9124e582b5ef043ad6412676265c95f2d552d6dc8bd2a27759c0df19def6df478ae6d2379846fbaec56aa408fc98814edaf4d1af618cc982458a6136851e32184d7c08c9d8a3563915959aff1718d9d497317dc210abc6917cbc5a2306c5b686a6e8eaeb2b1c02472d15dd42a1139fc1eada99c45dfcc53f99a1194ac5387fab16dbf0b1f18d855c103ebd28e746ea0025139d6b14025e31b744b360ef44d0505d6244ddf2d3533028fe750ae1fb811d036703691e48e13f7f0d3774e72d7ccb0782b3f55c78a2fe84630363035fc33941141764f1dcdbcaf92f48949b64262215fe8ec203908ef734e9b56f99961b31c686ddd5a90f14f7e17f65301cb9f2a61221732cbae6f117cf2047fb069992c27aa01d7c44a345da3d373b261fe3613d37530ec8f41400b92ea2dcf3083c996c3a0eee2815f2fea8e0289fc8f2ea74034eb9eaa2d0b0dff6d6ca2c471b9e0dc59dc3e1148c806751f0f5c1d1b513ca8f0bcfb41658ece908e5a4b173675f0de608337ea2796659f043f3f970ee69c8cb2546c1fae4d091683c8ab3198d08f51669ec1952c7723f24ca4c3f3939873dcb3f924ba7cf6398f8dcc4f7a5ae4ee73bfba24d1fc55a0eeb539912f03c7dd8214770b575c4cb3e67f967f600cffa56d7edfaed2f8e80482019e85bb348b89f8d580361fb4a0b3b72b3d74ae97d1ed823c70bd77c76e37112a25e1ea1dc8167d24414baddedfba682111f4b522b4f147484cd5ed42a764ee69e426bb37ce2464d1edcec3706fca47bbac2b68477fba0ad3b75ed9db13b2dd1fcd09d81f116f485a7fe597d524a7c16ddd7b2e98075efa228c016d2be978d6bc298b77012ceb5dff830a2c6e5f4a5cec4b858cd44a5f8458164e0f518e141fa29e08699489c4e6834cff43862d458125126687c76829b90379664deac344166e51d98ac54792149abd101c449827ad480db42880ede3c61577bc4ef7014b7be5e2786b6f3048c86b0802229dfc113caa89657eac4d8ef031a66703d68096636272e870a1d63bd179db3cd9d3a6a7bbaaf1790ff07efa716b405b1fbc635036c0350616091dcac8c4be3c16899d32f32bcbe37dc928b65716c0e0d53ab0bc582b9e178b60f36a01185e5917cb8bb5c0a9a839210ac2681618d8f2482cb226c838aaf1aea1f1a7e311a7b072481a173accfa26e2a1a27264bd8af40e15ab5f8521b581c442489dbc6098a88026890f391ab57851238b8c16b9f0e3565a9fb894843f3a830a2d9f0be741c3e77cc43bad72795e90871a5ee791fe74d5e57d413ea869491d16528dab554ae9f810dee7f30f9b991280b258d96694a52d7603ca9696b5ce9f6486094d60fe18a08c589a3a9af740124ff563abb44b8ca4a53351cfdf56ed01d612943838f1f112bc717fcde4628798ab8248f7ca12db55bb79acfcb98bf2adf596f7c40250beb5d37256482f8bb5fda5fc8b5e8b9bacaa6e443393cde6bff3c1fccc17f3331f02c43516709ec4209662cba2a1a5643062fe9097376d3c60db41bb2e60f91c5303d87186ca6ff6859d56e63c6e7921789bdf2df1255a6fc5f60bf752e004f55984d4ba2a833eb849eb15d677a220a55fd8e5d38688d6598b508a0d6f959551aaa28dd67d747e5697f031ab8f06497a8ab08fac28bed41bd84f35b29ccad3794c1c6c781acd2e918a1c3abf8ba6ccf742d338877ef800d899af9750ea39a4b6746af37e59d5daceaa7f6a02174a89d49163cc001059150ebc1d756f876304755a512a79db341a693ad188854d9a388cda42fbe227bd034897a4ddfa68823bb011947c0bb8a05dff1547b1370cd6054cc07a0f616c583899eda466a6b84fb450b5ebfc31b361200d0aa5dd4941314132c4ac32396e983931fd0c63b0b5d21b675db62b69a417cd6b7ef82e1df0810b034d335120260a4a0db68a38a7e2393736b80216a25f52562750ad50b9128040cfef1c746d6ad083b82144585e24702ff19ebb41ef41742f647f7aa0502135dfeddb33868b8e288285909e088e01e702992ef242ce474156bf1532fd77500f47c5f65a404a0290a22d4a6fe259aa1739578526ff856e756ef0b3c902dd6762399a32ca989feb6a08b87d0cd77b67d8c0c3c593c3cdd4e1a076aededeae9930d8234c27113941f32a52b9131faa0388539b82900cb2d651121aab3f418e907392131b21b74cc7536d2b59feed85c2e407bc2daf40c36b32d0a8f60a2688a2293b3149a8f951d3ec765b39475d6fa09e9503bb0adcb34814774d1efab2d6418c5d3b55aa80c7963d5fda459870fd9e048d1a786944d10890089b59df379a30eda3a0b216ead9f6b1627e173af45aca8fff36e2b38455ff7ce4678dee91e05f6a9747171fa75f92dde1b47aa18155cb8c75b526fb0b3edd20ada42b7f4dfbf57b0536f498e674ce614556e038a68647f6f2e820d8cfefacf83068a8561baff82c013e46660c4b7fe08796f4ef68f19eeac458630d4764bda9d307b53b0acb86698b51b7342211a33845e01e7218dbd358c69181e83927a294c05d54333a8b0315f966b0d6e1a6b19a3e51a8b9408cb9b5f00548d8a7aa3873cbb50706ee11b3d480ada626da77c1d539636a78ac9db3d29b50c11801817068f7fcc706f5e40e1ef665b58d1fc918a3a4434a127cb10fa65bb4d64aadf8f5573acd5bbdf3265d43cc98e75082b9e0e03c77b9a7c902105a3aeb8c7d6164ba4ba0b87e4262959f3b8e14551347a13cbb8899f64905bd3ad32489f3be9af4537a9b121465c7cdb000705be157ca3702168075c2f7bbd5e63314afa08eb8a014a112115cc30b91b22bbb6a6f4b57871d1cd6dbf60057315ba9fddd47260fea46b9a04a5c851e3c559aabe4b8791887d8a82aca79c5833aefe4ac194ab49e7d95db53887fcd7828d2d1eba24d5a1324f1ae2c1da16266502b6e1f485f6c0edb40274ccf153bdb65170a1f021c5034f5c69689808eff861631b5e8376418ea0c0e8cdd11fd3cddc2ee2209e668e47d138f72de3c11e4b9e9c64d713bc4f735219c15b6f3ca9dc4917b1b3613ebce7bad8d3409d0d006f686730474b06c270aa48832348499acf1bbef387ea1be3e99724eca2df970dfd7936d4b4304640d5b797a30df177adccc4dbafbc616e5ef7992c0135a4affd1f7100081521e8252de0267f0d01345fc9e549a99790b5913fd292bf47f614e6f23dd7ae38306be14ec9eff8315cc985c5e18eb9867ce05697fe5ef8c540ec3d2d5ae1628b4d15f5131156622e386809f5e8cd9b669af5a5abd135260909d75392ec2860563dcd53c1c30f6adcd6513dfdf2ce06f49adcd065a38e146ff67fc804f3fdf7a64854235f2cd3ab1fd6f0d039c0695d56b178ebf41ec7ffdb8c537f7e2ad7bf11aca43654dbc513855a572072e7d5910df6f88d1a6df6fd5afd76ffd38bfdf0e71a7860ae89d8334f9662ebd7a434b367cb5cacf5b1b707f5f3fbd451bdfb9554f7eba75d52ffe62f9656be3ff5bf784ef36652f9733e838fc500185ff495525077ac5c1f0430cb6ea25c4fe691006d4f4669e7864c395fb36c60f27fbe9718797c9261ee26f3408f115df24e0694f7345ec4245a9fc0cfcffcbf75bffc44f5735a1f104c091f9f536144dfb39a07b071b85f81d0d436525de583855526aea71071d4f9e4dba3719703f0769deccdbff1ff7dff2951df11534907536adbfc1b0fbf3412d95b3d3febee55b217c79a0b06fe5cefb9c83cf8604f6fd97efb7f80a9fdecebb7a20af2d10e42af6897ee91d4970b74807b7d7420f6e481242a919cfe641505e804351756757d315ac0e7e86c2b6116134f4fc2e6e7f142a8cd61336be0274159b9ef49cea352e6803c67fe5b64c1cbf679e96f46621980163e7d6320c91befebe2951c602d15609c29f1689579457db332fa143550001707e45eb748bafc74b4089a965a77df4fe1340879b0cc98e21606dd1c858b98c55fbdbeaca2dc1b13de95e90041182ea287cdfcb5313d46a3c1f7079d199136cb8a325f82bd6d5bb8f73db85bc426ec4f5f17a8444f12af4b83eec057e00190764e404e123937b2a428e375d508f0d197399dafb0787186dc286577e03e4f9940d74dd9fd4fbe91b5d24cf54d6eb223b7a70fe7352b3bf2e67b8e6792ed23b6149b18b40d8008c8af489f7aa5ae0d2fbfdf3bd8bd27b05e34885db63c20d02f8bca48fec116d0da6dc7fd6a68caa1d9d135cccf3511c3a025052aea4d6980c429454f509f2fd0c6bf21c9bbb12944ecac2020c7d165bb9fadec6280ff3b0c865473176ae783c6feadd2ea2a8300b89a4a713fc4a0d62d10d84b98a14ec2c5c0b8ee01abdd295a1d94d87aa54070ce6952f56701c1c75f91f26493978aeef8b323c2a6964ac986a958a7f50ae68322a11e0b87a8bfaeafa3a73e64b9f44990f4d1e50d9b7cf983a2a8dd4ecdb9b3ef81645915aacc294e2a9bee6fa1ef51d6898d2b2208c4f907aad27e7793fae640d640f05fdd30aa9b5255693eab3373edd47082895a8bba9fc7048a44b8f738e4996125ee546671c9aa16156026a72422d8969d781172e018d59445f98419a4d29f43f37281fa7bd67b348f3a93b0a0072a3109c4267252c6482d0bf16a7e3864ae32200fb576e920718eda85cf276883326b8b4edfa4e35012514489f62d7c8bc2c936c70f21f7861f0e9943a545445e60313dd7e7c68bdee70f57a5556e3ce912de850c794d0c5d7dc5ae9dc6d5a1c05c612f930a132cd98f4cb843a7855d72f0e800bd87f121806c0a2d92ea9b27313b90ccdc01a093efb6aef6e895c79b8c173babee45cdf51b46949c8d7c4d18c4a09adc5f9a128b633904e17c1c18a6e9f15d9bc8e49dedaf06cfea50ca56e3166be0282b4dc32b2cc24ec670a80b1dd38348404fbd3e1f5a851aaca26daa4877c51e8325557afe034856ba9b8c892048fc99a02a079541033d195ce107badb83511de7409dc355256a62e75ef5686a0eb75723c752ab2f053c47bd04725937ad3cb3ddd851427b803d0f31be00f3fa7e073a60133fb7ab61953b72db8fe5ea0fbb3bdce20adb481082d2ed4d1f7c2e0fd2cd2d3b3096a385388c39f8c9a24f3dd2c6162d252016ea8024436c6779ba7df86b487d33eb9ddc3dad1c5d9d7cdbbfe669ae054247fa202634a99d875e776d9b8a547782c6d6ff73129191ddeeb418d10466c7d4d0e1249c7c008ae195562f15f75df9abd221c5cb450fff0ae67983ebc8d0b6c6030418f9a8e903ae817fd6a6085269d965b3c96655b5b0b622f7ef0427f462468b1add1c60aeba471c71d124862e71d070409a3cd70ecd3a876f80fff75cb89a8f58657e40f591d31ccb57d954c90078111b6b9badb662626d6e1ca34f4d36166cdd40325adb18280d33e97bdf9a37de96e5ee0c62d2b96422229bb8eb644eede7082c5dc41f5f16cc3e4b534be65202443d3a4553b377283d58d01aaec6a1ab7add70a8fbf14c0c8f694f696bf4d34960a9ec5e570f0dea9229899799a8f6c973e98b6a0fd84a114e7200b1d2b0a5f533e06668d040b88859b5d8bdf46648ba312aea00dd1a975a40e6a8325b28c45f37c487afc9cd862f9a79477be4834e8deb88a376adee33e345eef611f8ecfebd00dc7f77de817e61e6e40017232e665d275e42deeb7b06b50011729a526ac2d59270080702574ac0f168f06a94753588410a54e193d04829b4c089720433294b45e7abaf0931af236a14052ad405a54a7ba7ec7d015baa170a5a74f6e2c099cd9eed2e18fbefbbbbaa5dbbe3022c89c7bec60d38cb52cfd2fb6cc8b977f93bf49e6ebea25400e4e4629d7d0b180e059248226822e5b24fef0430d78abdbe58d0e6ff3a6252064d161edf87990f33d2fdea1954d56ea82625475f6dc0a837c3146f78f211ae4a35d68e0223492c02f210812b2c8ad7da97aaecaebf6580cecb42eac80bc0dd116a25fdbf043369ea2afa26323acbd6cf935a06d704fd7f6ddddbfedeb752d62c8d46425e332b87d099756a149b069a34646e922778597b63ca53fcadeadc8dcc1ffad63d912595a9463d6fac50ee857afc7953259918355dbac42114be3dd37fc9bcbdab084d4356422d0fc6852949a18b0bcb1bd4426037691cfac4df2716564511d83252402ced493160b598bdd68a04ae99916ac297dd33706e5a08570398e7e27a82f38a288bfcc3663bbeecf3b38148507a7eda93ff60c7ee50c3fe41c45c64147388ec108d2cd70a8ac66e14726fced9257f092bf70c82b8d4dbf2287c96cf28e31e8c7046e9c01f5d48cf67c33b15254036ae0925a515d51ca804e85da9dfabb50927bc19e74c64ed8d94a52812958c9746c686f60da35415722fb1a114c51f11cb6e8ae27cadff4e1c59b079cf8368e011f624efe03aa352d25a60e724c985bbb7dce78f5bcad40cb518b8d4174a4880d336cd028b490a865d060a294a189842283be11d27829264134f5b3815377dd15068554ebcb6d841d7c46d96b79ad2715e21094823d414452759b5d5527f72027b74318955f39eaadbcd56a34027346c750ea362e1efffe2a2186d918043797144fb17970b9596236b6741f6db8b431a5585155a40b37d233d0eff3dbf223010103dd3f1ade988a533d2f2c5426dede70fce9d16e33ff2945c8432e8b021c851f47c5712e6d39527f0e45516798b11baebaf3fae1119b7948b77a96f4de8864e4b8c5c775d1cacb84a986726fc37a6ee7811acbc611fb22958de9af807537cce47ee64e57744540f1df9534ead77f7a9b261092851739c4749caad12ec335fcde39bc3c0b0e1c048351276e9a98496a39df3318674aa0a6c94471d7700d5852f76a43781837e5e76745107dfb92729e76ebbec98a7ef63b946f35a89f8dd2fa665bf619aba7edab1d6c79ab43b418f68ce69d2d05c89f5d5f54fa0c0211144a86e0ac3b1626d3b67c52f5a817d56fc313b585b3c732120cb571f52c515bc042bb65c660be1f622175a6b21afd46fffe5d39ab8a07517022a821785c6ce0d8956c8508025d86024dd6164d38bd1fe435d8a6321fe4a43c297a13ed7894995176addd145cea3135a72f1b537782ce93faa0c17f7e5d95ce3873d2b0c6240dac4c389334205aef5b227bdd4ebb1a4985abb6abca34dc3ab390f1478b2b2cad91d58e9012d22a2f86aec92ffb767dc365e696432bc807b43f409833f290fee773b8059188a9b099287c7e311616b2357204b7fab42ae25ce91dbddad3227f08be965a2c6051ce432ecf93afd331b7cd231af771db5f62f1b8332688aa7c1a7b37a6cf25ac86b50ac1b680f0be149d7a8f2bc4b7d745f93ed57c519b8c8ac0f160fb09461a86524fbce29f80e58295d78d5b5586ebde6aee9d72aa062c5d70ce8da2d938f6bef57c44f78bf28ff3d1425f58b3f9d9a913ee1ca4b48e9c2514f8e746c04abfc8c860b403c2426d8c822d0f946d981ae633877d7f9557fbff2d3dd46928ca5d88b493a82d51744917130d57fc4aa22fe8fe3d25c8706d4c2bea29c43340dbb0eee3898241a9201b6d80bcfc01411a05d24a8da0c34305c48cab2c20d94278f1057faaf3274ab9e23f3bbef75f4fd3fd77d393fe6e765d8e94402e57d3dbb044645b11bd5788e7b3d7ca51456b8850cdf64819ff42e25f8691a29c8eac6673925dd75aef86fa7af259eb9ad19f6fbadb7fd3fdc6f1ee723e10755ebb6760497bbdd075ff21786d43274300496ef981a4f98119da4bda474ccabc8d86f7b4d348a741892dad55f4d9b1688f0adbc5201a8e4614579d991a045333a853262083784ee02ca08a22c8c21308e8ddc04d76bd4063fcb861d9660099f9b07b3871f376444c98667224c4700ce2e2f5b9e8124317ab07ee77b905c26fe55438f93d72aa4dea80a1d73076f9ad1e33cb4522532443a5bb1318db7b65c3d5949a69a3d988473516ac31b496813506d67309fde27d5f5bd8e05a83eb6ba5585a346075c1102c72df2ddf3e8ac2002232671dbf0303c89481605211e906a96ac43ce0f6410b105e47ef77faad833394cb41dad6a2c4bb870f0f7acc635d645bc6d728cb1496224d9a0fcdf8cdd6fd67f8dbc1768cebb6d3c3f00081149abf840892272f18c3fc75a37100334443c982c54b6cde531288598c712ea583547dce33286c75e01c3d740879b4643935f03407fc7962f07d7fbf43f0a92c1148c925960d1bf2bccf2c0b45873d365c277c58931c75b5b0f2a34fbe4367f800b3c885e8c448bd9b0a30932b666f4947b93ed889a36d72326610ade09d322370d8fda6eaf02896e730c20a75c2acf74f4eac6b929c374e5be1c0535c47441b95a72e6e78284f709b736666f2684ff6c810069761b6428a1849ec5948cca2e0221bf8f7b683b842e8f06ce6495ef822517085064b8c2bc07a22345011a302512faca8e2afae62d9d6172b62fb6b300d464017b50bb36e4e8dbe5fd1db034d8a0957ef2ca22ecc3712cab42e3a13463df0e32f5b945458e5ed0a322a5a5f18cef201fdb7a25a6d0f275973390910ffb6194c5d83c29ce5bed6544bbc2ec69087797350417703adc3fb3c3029d76183625ae2266ab61e30ea0091e0a4675ebf63094cbbb8675241d348a7ac86c15d0303a76b5091444aa53efad68135d0da3ae3e9f105de9f1812a5874cee174ec47c166865bb2b90d8b2258846c72937a738d01c766c9614c7692b97ff9140f89e9057d9f5afcd0136d5232a51b093e0485f08a80cf1669f8c549ec8c4f35c9e60d04f06218eea4316cbfc7fcc75fc18f0823a6e08b12c94a7f1f04686ee8c9aee6c6313f5a20c522c31ee1a3d95003ec281a847b53f84c4e2fce9b002e3df33320c31c231cc18f728f68c2015ce8bad99bc7439ecd1645dd6f69bbbff5f5ce914b0c8a336ee45da98eac0be920062ee548a2a2badeea90a2cb674936a7eab2997bb90a1a96f12540556b1752fa15b2d36d3a05d93475499902a0e705ad0f52e4ddf10ebca64e88ce040c5a22d41e3038a8aa0ab353f36f65c4b24464d474f981c52313f4f6286cfeea3c209d5bcf56c4bb665325e0c818be443e0aba6c79e4a4825292066a34e038ce3e63d56d14242240481424a1d73d5bce0b686acd6cdb4cf2f77421a116abe43e17d9faebc039ac5fb7dd7a92da576c45ad62a69875dabc8dca7b5da47be5dbb879f0f2823251e8d7355dfcef0b3e51226bee9fd483c8ef4eac8c6bc1443a6d3b23a93777875cb4605704a78496954f8fb1cec0eb210c3535a721ddae7a3802ffc20fd63d745a50176902a337ef3a5b7fd1ec72cdda920434cde6e1108aa8d0b31af24d0c9852857600f08776061f09ea0e619750c332c06e82a5c1a46bc54a1e01f7bb16e3b849bd784437b3fbb595ed4a92bcce9f4c71f7870695bef83a25d2022e36c8975c550626fe4cf5e07f030292e7c484a4136d313fb3b525ce490e27498385854c8c621354c763aaf3f26cf64476b33262b696466a027317c52a0b745851272a0ef51500ba879e839928461fcdd6f01c46408fb2a9708dec8fbd5149072e0e878c9e737fe70c128bc94cf562ff7d61a38ff6b2283adc082dfae254bca64c9a8e1f3b9f550de0257f7ffe1392afefba19984f449f183cc28becb1ca038ec6b650360025b72931232d113838d3412907220b0fa06a14dd21ae8f4b0ac2a1ebb0c91f2c06acd1816faa9f518090abd52fe2b405f86241499962ca19ef082cce7dc8e54f221167186ae6cbb266ad1f3f2a0a0028f23fe897d849af779accfe824ee2d9fddce48a414c37d82478e32bbd1be085a5556446d89f2c99992008aab577a4ebb56f808493523a5f16650c960a153c68e660cb7a713591a95dbf95c329d22429eb5be94bda0e0749640f29b14326d5b7e303397d79326993eb6e986970c7c4a7772d36772fe2834b22422b2dbff174f2ffdcd8d51c4cee9c98d0d64a74e3e5210b3530c79039ee4601f1efd4a1616fb6403dafe05a631f4465cfd5cf87deda3fece5aa6eee49717422023c67fce2345d64b22558b7f6a4453bc242a6ee131cb2001d552c17453343809d84c81ab02e870854f655a71ed4fa980ef99e0c439eccea59685544e1186a6ced8d3fa3214b55bf6bc263a4767d4ac03832f037d96014042480ee391bd56bf0e7bc26cf723b5ccf92695b281d2e0d0f838f8ab092da66fa6a2e89e59cb4d03e0275d1882832e0fa0296acd4c7be173b2f900ea60bb32c54189b63854ce6c5cc0a04ab8dace6be3067877eaa899c6d4d5e3b8aa3342eb48c55664e9aaeed76226f85043fe6d6207a0009dc210f0227229e1ebbf35cfc78dadec7694d06396180c9fc384facb84548951debfd5eeaf6dcb85e55e35170815bd390bce72090db2fc14421618f5eb9cddfb7b115fb1db14022b04e66bf41d5aea36c841f8808f6d9c11480df252b66212fdd9e6c23751d7f6183d077146d00121358284128f028a89e33d7310c5873380f28211914b5221a99e11551616fe9fa3b72dca7f1ec706af6f1da91b9039fbfd145011890a548ca6d773dd0db70025329b13a5ddd0785e58ee34e653d1e50e0b2a9484f604b6645d9e6cdf51c3b5b45108afe80c4fe93b7c95e33637afe6ddbcbc9b7819acb82aeb535898d073ec8e472ea0d3563377f5c9c7c4c2909719df6faa40ae3e7573aee1a8cf2ba84a53bd28a3169d33e1cb645095e4dc89f6d6278a2db7255516ac2ec146999b9cfa9eab461f2431b8894b8d06b14683e8bfa342d94c0c9029eb42d161204329baebf67817ffe95f0ae53a45c438b63831a43eb4bf17f020756ec6f5d1dc220492e1d4c6eb179135307f84b9508cf4398de21932c8494cfb38dca89d6ebcd2745da6ab5c29d357fa2846a6428d00ba7a22b2842d9862a4afc21ac155caeaf1e153c04e4d20bbf442b1efad0a9dcef8244be8c2cc0a2bc9e152f522d03b6bd05fadf38da5c271a7004b76e445caf33730e057968930322858c630081d59be66292c695e9cb715ded06055613907511652eae7ae9be477a3b3c5f96d1b643d990dd9876b9962c8c19469bd00c8b261a2aadded8a36f1eb11df0a49b5995cc6ee4dcce1484d18d9cdf4c7e9404a6027729665e3485af858d4dd92ff74ca2039cbd87bc61adbda49a1a4ee856023b5cb92f2d550bcbe66d82359d7037c13beaf6e144b077ab07d6f29d91c553decb077cf4729ff437546d2a1a4f3db9247de2ada67a4df764664a0ce0b2a8b91c6d992a2708cfcf23333811fda8ae636a0aeddfcebda04363acd738e74ac5b86ac6b85e208169d2333a6ab80242820054038b17f1dc482e680934405f441bf0b544d16c1da06064a104b312637c3cfdc56fc07de1d5c186f9bee2f6b0f2f0a4fb18980513f2263725fba63c491ed578771d194a52b5b882f03ec55c70356326b28531d9185adc6c050ec1e100903601afdcc5447f599a404a66e21a103e0f880384167db5c67f904b319285eba4e0928d8967d5ffc9f98785cd15cf534d1f48b78265e491566c5f9f4d224d3d0734644e1342d5606579f9476599ef170e57810858b6f0a59df8533dbcddae86325c1ce5b2c9c042ebf5f51ac2fc15cc35f4f27e23474ca8993ef64f928635948449ce3efb860f7232600839dcb03c24e8342ee8bcaadc78472565c2709d38b3650f2e78c31c3ed40ecd9736a81fb668ac4737a4fac125709a36c42e08a103fc606d3b0e6a00d3270c9e9749db4852f3c3fb18e04a00934559eb7482a6f0b59c1b724659cc7f7c56bfa500d5e822debdd77e6ebec015b91e23142878b06543eec579d5f48608562d2c4aef1a5feade91745747478fd7c98a0abddcc5ed38925152d2c7b9d11373d321a0b9c3b9c237d05cd7cc1971461f084bbb3a3e4e445f9efd395b99719b557a557799f59438eb458006e340c13131ee615d28ca2debb064095239901ac340741b3dd5fec610a0a3fa8a46eeaaef147710c29c0dd508b98785e96c1c52ddc31a796eede206140f2dda716bb9f3a06d9effa9484c1312d5ec702774ab07f1046e4d140dc40b6fbe0ae253736e1b6673afeb980100ed024ac00a7b074ef7261bf797cd4057d89e53ab3a297e503e622d90c06ad1db4924cdd364e4fa2a84f084fb8e3185dd3122ef768bb94617ecf7e3d2a3bc3dc66b26e78682908a58d99d08d90fcb33ba860b4d0bb1939a5e11f78556a1fb36a12b3dac30e64ac2659e26f4131c4b984cd03decf17381b04b774730a4e58e8c65e223c9cc347d6f111f3d31aa9ed6da3737558fd8a78aa72f4da19bca21cf0b9357e37572511166be174907bdc4e1cdd3b292cf2b375a8c08b1ae19ee2d3de3b2d3cac71ac6c1c5074ed86193c03bcef92e856a1a3104ff98088719651abc5bd61b57aa7bc86bca10f2062e5642252a170b4c88a8519fb33cbad63891cf4b593a206c24fec1f93b1a5445d74acaae85e2ca14397c97290f0ac7479ee3c86b40e2df62c088cd6511dcff097c03e8b7f59f8cbde5263972e95656ba66cdff69d56e9b0c196e10b9f5c11a8e0aacf936b09e8e031ff06c824f42c086233238a4f0e4e416c22a0f2b932a79155f5006758ae5c37583e1a89ff895a2b2033096116400706aee1902cf666fbacb65ecf5b0149e385e8fa03db77fe22b6b668f20828ca0597eed29b6a44a6571188e2e6b0fec2c0826163baf301bc10173b5b2da86ac2c8b0cef4d0c6c271680b6476d483f858834e98445f6393768a1bcf7ae23e005968a0d6238d834fbd9b89941e4062e34c9ac56508328a7abdc7e7aa3aed56f8ace9ba55ee27fc8b38a27e95d78d6232c5c83d3e039344c9a2f59335e6975e2603cabb3426f4e5f774d0a05f3a6cfce99329f188637b34a9f32e804fbe9b222e68307c2a2b8048c7bca94b30a0a8707c734580660316253254ead5a140839c5d1b8a20ad73112414e89a4f15aba4ad2cf3c10c59877d795f9b38bd8bf7f6df629a5312805f17e6eb725cd40d23e15cbfdd37b864b141085aca40bb6ea17831cd7c2eb43b596797e448f6bc5dd44920beb9cc745a51c0db2c1e33b1fa7dad74882d9ddf028c3095a8dbaa5d61af0fc6a526dcfb63346533f3ab96dbb9b69d7605aa3eaadd3e2b2b496fc9d5fd0d0d2f03bed90d5f1cb42a3424ddfe8aee74a8dc6baa67987c76e7c2cd966a9c98d36b1bc476e505fe3d85a51124871d961b3334deb727c72af785622e736714775a54dc5fd5518865888c3b22ca4e01fbb89bd9491e271c2323d994133ace9bd2cfad8275387bc3d339d31c1231011f2c9f845d2d186c0298153ac8309115b2dcfda822c330d82b9794cccbc10c43c95bc1111f5db21c1642ab057d7839369855c45482795382e227b4da9ccb2610cb1574da9c5143dad85b7c15ce3158ffa02b7c30e6511b403fb075242c5db8c073fbead213dee7e79c9cc01040fe6f429baa0f4a9eedf672bd8186e719eb335df8f1188de2ae40bfd2899522b0940b86b8117ad49e7bf5fb8a09f5c16155a49750d6a541852236cc3b89c2a66b1b931ccc56b7919c083e85e8abef2e6194a46629450b9309b64f129be0bd54367fb5258d54d0bafa1f7409820c4d8081c0b176a4481bc71e843e3ecd0001109bd331d3febe48da08ce64dd8e41f187baa304f8d10efae70f62829d2996af60ac3626fbdf3221b3b1c24e800bf4caf69813a7ca7e998742df69aa2df9d6e6d07423d887aec2c0150b010b27c213b4d8e54c6b2d252d4bbab0a8a987fe65d8e24c1f12f79ea5e1d382044c4236bef4f5b74d9d073f222cd43339146661e8e292ddf15f03dca61bdf0a40b544fba25dfc1ae6f6275ff080f5594fbae0a5310a4892401ecd6106e0450d74096b4e34a714f844272825033b83e666e85c62ce640fc0ee4eec4faebb5ff02d8d70a9151f9af1ccd4409bf06044cb8ca50adf75cc616421e7b4f1a213b13d795d92b289c2a1f9ddd4f0b550806ae87531f6e41031b5413b2fef7a827c3175150ab3c3e49e84868064bb6d8b3a98db44236d50a0907d5e1bca014157e5492addb318ed3b4ba196f3cec59925ea7277845dcb05c68aa2c361cfb2b00b34d45706abdcf8174ef7c757afbe18519faf616b35b502b77b2018f9c323987a4bdc1c026822063af4eb7ce1a1970e9b5f18bbbdceac0988776e41e865591207500c77870f7b2168d9b9f2480cf1da5405a3081b5b9d969256c6bbdd386bf748848eef352139893752a206849f95fe6046a53a11770291db1ed429f895a6de0cc866da5cdae8b32a000323c5529f98036719ca308b9304ad8db59bcabc0f03bf95d2bcec0a059ce25da1b8be0da92402101ec599360790edd499b2d23967f60a85c23f89928c10d2a33dcc3338093bf80f8b36b97c78592d17fb651a6892612c5b0432021abdb428165afb9076035ea27d4e1eb4e30ca0b99a323ad23db81a746a7834443a5fa537396069b594078f606a74b9bf70909d4748127aa23fa105fd79daf171d06b0046c59811b88a1f194e04f019a193f6bb80cca9fb92883e8f25fc855fa7d0d55171854bb758bddacc519cc50cd39baf149f0007f480948eff90aa7012e3f2d56086fc95321ae24ad9619326f8b819c3b9cf61b2bb40ae6245f5bd28ee9bd4fceaa0910cd5d212734d9060986a1c14285181a8c07fbc5828800dc2743d832850ff4f1c1d610a7c3f5c02d61d76a178b6be81524e83a7a5a0d75848134a2e1261c47978a027f4a671fe8cd205dfb64ab7b983ef4781700cfc393f4e85695979f24d06d8219af79a48d2804f57df314114cc1d95316b807e2a5507b74c49cc1976e6235aa237dfb3a037b6a14b5818330ca2940c994a35a8fa7ff8aa595cdae040598c855a2950e14fb03e755a9a70c638cbc3646c75249f83262d1a50a8cd948da59e2067b5bc7978ee4b241aece1787783b21a5504fa6b4275100a7a3ce066c85f61b69fe9e94b0892f569110cc57414695fbc5f422950febb14140c2c9d8de0b242ddec1320dc6ee82c179184abb53e30fe14e801c38ccf83b32edf3bcd7ece7d3107038219028ebc223f62c20afa11b37ed9cdb09f4d3f266c35f8981ec1ad8746b68570ed1a4fa86e2319827b1bf1b3e317a84a4749bc6f8416555544e6883a55f4f1623a90d1a43f23d005c4cc2aeefe5cf04e6f8198fe5aa95e33ab6accccae66b6580b9fe1e00cc8d4ec10bd7eea4bfecd97870422ae038252281d198402ed5d332b6b054b24ce9f13c3d345f525ae6d5be8c7d37f8a7533be35926866890a48794ff84ce6a8b209e883dafa5253a701f57e2c778fda9dec631cc4921c03fca466a62f8c5074ac5e0169f894647f306285c805beacd22fa871177266741516ccac9bfe29582c390a715df2b806b34f85d87b860d05a3a37a06b6d058968b1da8bb0fbed8d36ee2835cc36ddf5feddea4d78b110fd52d8cc2c664ca603ccbcadc5a301379e333cc78963366a0d01b68e5e0d1d8c07637960711a6c75bbf23a3cbc244656e517b3143a6c56d4aefa74b121a0fb318df6a169c617b0fb357482a7974893c667190fc1e4b863cf23879fb1c3d3abde24fb70b8697df0953ab358df5e6509e203f034a0b6c50ec5484b0909f8ffd0b825453d747d3cf4f8aa31a1d4228e864f71e14ad5dbd236170656d766576ff02fb6ba12066b7d247c9942b1d416fc7630b2e3fe90030b0b1c77eb488dc3725c0c94ef9286c5c1a5bbb75514e8a7aec31b69430737c3e1b9bc15748235e020b0b2f1178398cba1f4aa1ef41ce86cabde30c4ec90b5262dbb1e13bf7ea38ab24875a94d040dee5948b25d0ab0765e68b213ab2db0da1175b9de255300c17628f6c74238724917bcad88745a8e09421276f19a2246455b8e9d1433023d2b7ed08b1ed159bb0a05bd282648db04c6dd4b4ef7ad8365b16626706d154efc37debd91d35b5bcbf1d66305983c4ed642559c148b6577dd3df53863898d72e1bdebfecdf9fd9211b8f63fedd8ee9747ff3ff5cdb75a27f7d4d6164533817b5b31fb93171ee87c5d99cdb291ba5e775ceeee1f170656897375276e7f47bf605a19a801bd8ff0682b3b287cfa5bfd73fff6ff32c4fef5f4359403f589c856dbc14ac97e461fd6440fe8d05f125cac61267a5bc395cb2a487487a3a7b42101693f99256f22f04639150c7ed1396627a7424ac95775fe9b9e607e44c89bda9181e080d69d1bf61b0204bd579dfbc19250984ee7683d4c8ceffc2a237d5329456e2ac0ba3ff9ed0948ce5625f9e99f7ae59d2f53acccbb38028ca985282c4eb6723269788082cd7dace998d7f984afe602f205f21ed9ebce702734480f3ca781d549dd38ce3302fe3d05d5bdcaf120f6ca9e082c3d018a5c95714b11b6f5be33b1da5c80406747a0725ff9aba7e8ed4d527812f5a487340b702ff94138c725b92753af197e82c58cccbf09dc3b4141136200845b635a8c41b58068ce81a62c5e5cb5ff2f05ea214d70387871291d28442871c3f6c43f3188dd5584ba3397e9ce109a0d202cc56884c617fc1b139a3f9ebeed8b789e0c0fe9fd579c607a6d9bb8472a3cd43473377a92b5048a38934a0a552f19fa72c7b3ddd28f1a51f565f2be57feb8eb43f6250b879a124cbd34c5911ac161b6ead36fb052781cab7546a24936088acb52d2475ba9406f9a01404d7098d604433e9feb25ab7ce86533b8e7a51d74d1be9181172c1acc4e2a8adca4a5e6d1d1430bb739d58add5bbe3ea9cc04ae74e8c8f53af576ac2b39e0b6d1970d4eaa76822bf87c6f89df3f329107c7c1e0106e2ed1f42bf7683dbc161ebf3119c816d3ef528fe7262bd15cee700118ffd9b68d7537c99f3c0e9a9a309037414f156ce9bb0bd0700f1dd82cf04ff603dd7e8db2463f51e695f18c8860c784116139ccb300f145bc81745b3d2c207d872dd85671e6b71108c0a89a9a0080b446e814ea689ce91674a64ca8263906fb700ee8018868918bc6f925658842775a8d514e00fd330fede8892b894d723088ad783f6f69b00aa978a1128cd839040edd4c5fa4d70b107bc20884a2c3a030ead7ff4b5c5f86ed10b484d8638aa3d2b1cb6b0782d6f2cfe446e963c9d1756c29b1b1e43db44c523eeac3b054d8c841941aa5c8e723d9cf217c2055c45cda81b14525da5458ac705c806d8a3edf6ab8eb0324c6a1e9b369c6020d9dafba62f2506608e1ca25b3a9b47f5fce2a28fc0c7b62183a7cfe69e1f687497e047408690ac767676f6a62c3240881442f83130f796a4556b77af563ba7c50984b572efc3bc34ee79744425683265723e05b1a525cd24cfeae88af625bc8f860d7297b72a7406f2a58b093ca5e8d89ea7323dcee98cb16c814b0962e04ff75877d1ba0526293d70760b814ffc22487d62e6e7487fa5cbae277f04c903e85acc6e0b3b62f715feec0d771726ada02cb742728ec7fd0fa41f6e5e3e76a0fd7f076028e2fe7d148b3e9f0f84a5af3c082211ac0e01b2a54e99eced3979ea6762e91bd397e9275b64dd3cea771455a11197e77b24d17ac65d115e9caf48be20a33f6ea6d79ec254a6f7261f90980e4f62c82589905aa65e693559a6499d9f60e425a74bc21fd297e7f6c83747562a41490b8f08d514e1e0a186ed7f785ad9ddf22a2f6d78d44932348ff89089910b468839e7a66fbb0c52f75d847d4d2056ee1a3ecb1ce2338f39d2bfdc55ae0911637a812072147048236a4a6304013e7412da9a2fa091e22f02bd0c78802bd59eb65c968c1d3dd7e74024b4f94bc67083b3653c81ad37ddbf1c4892ff3d799eb096db58aa11fea412c125462a2e2092afd8bde84b630fb0b66a35168ae3376db174e6777377c33f24e89e92d1cf4ac3b5818c69b3076a988c2a07e0205889423d5fd5111867908fea50696286fca418ed967c602b8d9bb3126122a7056a80a425bef7c424fb9d6a66e963cb1911c98d8c3d79622970ec31c6e69d7dfba60946f109f10a6b903714af93a6468c735e8c7a41161760889f63a9d98018852b32dd721ea188b2dec107538bc6d74111c45dac20448b607af03abc68f44be7bb8f687bf5bc6005e215f09af65f4b6f930bf7510bdc83b20e4408ec54a7a71ae098ebaf54d770e63406c2dd8c338162c93ecdcb181259de3cc2ee713c4ced8b3bc281cf173f8fc660264bd13f08401d568f54733b7cac46dbd56656be3babe7d9e96ad7dadea89618b08a1c937120dc99966187dfae101f339818590dbe6eb4f03fcb418fcb68073f6b919f3763036d030707e4adcba4c4aa576f2cb3e2962bf04e99507e0d307652cbc9496852223b12d9fafa242256494ee084b9d681bbf8d4e55a98aba5f4f43c1eda499d8924064b21138cbcd6d7526eb352006936b01a4c2bbc3ad95dc5ab27d8289d089a5a4321dc0b8d396d9e6b5c4beef90e1b3362e855214fea9c21a883f6ebf3ea7f9c41f460ac4389a1ee4294330e92632e4df652332f15354553f8e184783589b9b3399cb7fd82173e64c71d87a38387818d1966dc931ac4bfa817702dc764481ff468b17f9aaaa661fcc8f46ff0450ef2a3bd6aa871a60caf9433b55100f83b1cca628eae1c6aa48deb5b08d30323e0d86f8c78848d73df0e28e410cc7f5bd2ee1d2d6e67ca107ecb5dd390c5cf9de5d92ccfcd4325b121b5d11e403dcfdb60138de3ca4b154cb06c8b6180e25d54c7f4244c8883c3732b6d47bc6117fae50142674b456b478abadd42bae9f247da4a06d74dd987ba5dcc48808a8f05a07463728a02d0c39e746349dcd3e60fe5ebaa704201dd801ff7c6e4442c1af624c085399c8293ef638ad4f40edf08ff517ec51467af79f5dc91469fe9e68bfd6dfafdc68a99554c504c3727ba97fce03f5d7448431114eaeaecc48dc131f4d3afa0061091d8a0c35ed0a883e1f4b1e7e3a71fbca8557a362399afcba2e963cb4b2d014aab5fccdfd6ea15aebdc2bed74d03b8460cac5af04731adc020b4738723842372684c785bb987a6a47355b9a596ebeeacd6afc099f00d3b7009af31cb1d0a61f9714d6458d72e2d2efa27659a3089b02a61c3f9dd133b0b27d8096171c27922bff185dc97d8c18f4e9199191cf2daa70a42f4d6f6ba319783a8fa75c764f0c20f33a3a5cf58eabe4815637ffa0b24cd24b5f5e214eb0779aea656a765fe4e48e19a4cb4e58efe3343b213c1c1e7a2c43226dbc53d7a4763e239297aea20d7c673ff17d4a582341e0d933b58df189d10740ea606f7144f4426072353c0bebcb777717e93860c71f7dac359d504c46cbcdbfd9948355ecc330500174a58e31d9f8b43ab33ebb7d810f20fb1b8ee755a4ab30dd0393311f19a6709e4dbbd766a6408ef671921ddda1c9f39011a9056bc6285c088bf371efc7f72888f7932b9df5caf275628dc16a630abba4cffaa194df87550c8ca2f695d626db1fda0b3ea2bb49dfeb6156f10f874a6868f47f8ff77db37c6d786f350f400b5f1761caaeda5685a98ea513e9c7b04c15f430678a314f58cd635558493f2b8f7315814d58d72df3e4b7bc4da09efc3705234e881e7d6362254596412693873825d5487c01307078fc51d4c3f750ff410b7691d5077985d0a22d56da95913ab498f388c0b11bb879b287cd05359090a125196c93a60177ebffbf171596c42a5d81b77b6c80216bc1fc61950dc1fe76e19dffdbc587c6af5c18a055011d9ac48d5c2c3ea2f1ec6493c6043edaec0a7568df54e1dfc9d07e2a0336077e50726db8eea130048ea6c4bc9b276e536b67722d20d6d6ff13dcf20b3f724143149418e31b403274d744fb0f8fbee34d4905d3ac1dd8460c704deae631b534e4819e320d761a20c7e750d888849897e0bc3d2e67b038e077bb35200a15b0d1d9deec6018d306ff103e6d03119a65829eab8c8f1f71479a11732edf4268945bc3235c316408dadd3c13b7e0434d37529f2205180933d6fcf12e06071debcae9ffec00344c5e50d51ad78717edf122e9c6f6f28564acc16012cceacb060b025340ec2627706bc8fcbbedc523e80ddfc7a7f31b9ecd4005230a6755e251804f3edff9e0e8cc844fad4f61843a9b478b0343c6c8a7e0190d0783a579ab2d8ae473fc0262711e07c2ff93dd10762195c5ee47553b946910f240111bd52f871ac6f66b0f758f98c0e7220ce5c86c01373493d32e1d3580e83f56cc91b22e371fd2a52230e1855039196b3e4740eb62fb70cdae18aee0a4fac3ad391ba0eacf38e8359f7578b6c71ef3f805825c024fc737c06be62fb9b9215147a7f9db8e056381398f6832ab30859c12b3d25954425659b799fadfb10104e47d693af9e880f3a9a65c678af94b69963e2444c56ee9613d5e3c87ccde9fab9125959779e495f60e45eb2230938ab86d1e33700f9c0b558e4f3eccd0ea1c93aba6d9a163e6a2da313e1f004d16a48b07c7572af33476669f4b5469f2023346eea3d831a9d1f5d8c6ac86caa5dea286af524013f68c327ec66d76a9f24f424d314c4c2d811f66fe1d1e73074cca8afe7511496a1f228c71ef1358ed97566c91151294e8335fb0f3c7ec7678ca95964d29ca701dacdd802168a3cfc3adac9046cba3a26a13e265795fad49d8da7b9b7293453a152750a16d4b94405d80e228fe2014162abc0c63780afa1f3e9cbb2e98a6d15672e23383493248c2e0c058bcd481ebb75eeb7accc7ab201f8a48f5a6f30a133b45cc9377025805893f598340cb1154be07baa02d9952c83a872007394bc63e330b316c980a187c3113943e9dbd2f8dd40664d1949d82bcc3538145ce4fca97d3dc743241af8ec9bcb6f0bcd5c0c589f7b3dfb8d606d43e41d4ed401626a4783506b6257d7912efd83d5dd5baee0bb16e24ebce758bcfe5fcb2a2445111fc5a8bd63e4aba794aa625fbf54b774416d5deb05a41af2db88ce53bf10a79be60f4e20c3fdf24a2c0f564cbebe2e1f83855ecead6ca0962c9633a76d10cd943d4ae74a5cf051a7c9a3a73efa50ab96e3f342fb356fcaa21559748457439f59cc5f1f01db7696a9b4bc0e5a5e5e1b69e140c9983766a1a4bcee2d447616af091f44767fe38856e572b935deb8319c8d6fedaa95d21ef6a360ed79f21fb958c4aa5b5795b04364c0d75ffe9152133c99d202788aa4c5a53a0b0e84166cf6b882877d0b0e0c779d3ef6ffdb412d3f2fb314749341ff9b92a3bcd178974fdd85441a4ba9352507ca08099012a4b3e2835846d9a974ef392f0277a7c5a0d7a4fa4059f737c2ae2935909595702a7b1c03af903e4255f1909f1036faef99cb444e0961c029c865c365e74ed8136c9037a665b0c5fe4f226143238db554e45f0f560aca1ee245e38af0946bae081219ddab8202f7348fc956215e5015077f097e6a65d53e345ce9eda83bc874726771c1af475cd162b66db48845ad8604ac1ddc744d2d9c24f42f66ab51037b59c560b146bae659d7d323cfe16f6c714482d2ee265e0a6a69bd5d7e64aba3a262d17dbce5bf0f9e0bc0d5adc8e2d2d4282bfb9c197e0ebe11744bb34da305bfc68e06d86c3cdc7e1c8a16efd1475bfb6a0b6615035d34bd663d50487fc62225abcb03578bb085c609669893a94e3c289538e400a93b5c1a3a0fa1d97ab4a06c44e0050f5f1339400440c782d17d4f328e3b8825b7373001d5693fbc6297fefd5741362d150439a02e5730084926d910083516742a6a3cd874a218049d85562b82cb0e548ba25d8371913d071ea0690f1f0ed403ff49bb89a4d16254b9e563bf945f03fa71392eac9e1c58918022014475ddf231ade16516181419639375a62480ba2b7004ca77be574da955f676420859b94158ced01e70edd7c4d16d40845ca750af241b1fc63440367e02163c806ba4bd02a9f59b9a61fe2d7313ebe13447760cebccbaad9ad0088d454fc69690f77e8e94f2611429f08c173d46072658027c8a3ea302971b96915e6fe4c4b065007359cebd71e33dc838eb7383c986c2f347a1d8b028a8164a40d890209cc29a3687c988b8072aa6650739edf2daedd1dfbdc23a1e088232de6b5c8e2dd94b7baf1c3c876fd1196d9963bc5cddaddf3f3cb6afcd7682670b573f77c8abf0a4905ae84515858bb1ba9fe0fe02f22c90e6b9c6d0b8641bc76eee525f5f46a1cdc85a58797b0dec7a4294cd5e566001edb6a44579c038ef32f1163619b2409f07dc6e028e89afb1529ab6f645951a8e5c772ec6119f5ee884a5538b280c4e9c0ea3e88461ba3934d0ae300a02a705fab9a0c2d4e452fa8ac5db147401b280c483c2587f41e4e2ec039444a51ee57edc6435f674f2ae66636a14a047ada6349458be73a9c13b947728d3d71dd9ff549bc9abb9090cc64d2ee1e109b07f8ad3bd302c218cf4f58a1684d6ca2270fce8b5eebf7cfc7168b68a9f07982e8e416036d065705a94da0e984880a3ed0a54522fd13c2353938acc5802351a8e0d6269bf883a428fb4e71fdf8950f03588f51a7ffee1dd031c568fd5e3c7a7416cccf04d4168e70d2c84598c5b924ede5f5d733d97cbad21bc945605754f72e50ac112109bfce4dcdff7e0298156f27dda46067c62a5705060b295a7f8cec7f547aeaf00b6c3660ae40e5c964c99066e7708181e4b1058ab3a07bcb133e73741fd23ed0728bc1bca3c139d14e29fa08c5b8a739145e1286a578bdf7ec5ecaf6c5fcb53e099c478573cd4674f40dbb6cbaeb93b80982b3c05e846b26ddb6e42521d1fd920311bb4144582c640d1586a336116aba94061a0288aa6c4f4852d863e80a6282d45d13486445319eef64b8bd0271b3adb11fb81d6d254a6c670698a2aad08a255642a9154ec2a7dd9a716a0b258926c96a2b19f2980fa80e61e7d5486a62821d496f640d17496a63114f5a14da80d2d4ad334a545a101a4a92c4579b11dd10c1b0fd488058df40c3a4b67a03234867e7a956a1c2afbd4a5bd4ea205c4fec804f483a490c6501a2aaba146680c4d9ada8a31741843d354a6d3a25b123a43d11a4fa6e6e0a1298e664b6b285a44d33487180dbda5b258178a943e5134c684de8852d45643d320298e14477a23f6b14757a0b434458d64b9982c9d91a6294a43652d7adb8112cd527486aa10d648a96a44b71455da8a6a298a04b5a1682c4565e8147a2325a63652a2b496ced0189aa2295a446fa444694d86c666311415a2313409bda145288afa4071a4b8580db5c9d014458b284a8391ba4065293a93a1c494088da538d0582c4d65a90c25a6294a23c5a137d4264b51142da237525c2d86ca6c321445851a95d1c3e614136086c6d01b2a9381de6e45a2273570a03a64689ad2d21a47732f784453289aa2298aa24c5f7be73bc982166a42e875130902f169720448d092ed4306497af8f35a47387c960430f0acfdc2634970e701aca3d80a8904530a5ded5f102312e048626adbe0112590d144dc2adc087b30da213cc2a1c11ed02982c9431004b5a1df25a3c0c19464932efdb9205ed2bc1e02a8593222475217e5d03158bc9a16513e393be0b58ccb7fecffd101f8eabe59cd58960293b5fed1303afe5f59e509e567238c73af9d43f9bffaffa4cfd908d2e5dd9e378b345a11ab1113214c564098cc08ad87466b4b68c95d10369b15d578e0a04526812a8b5154811b9a983099911b0c9c0d195cc26e4d644e623888665a914dca36a4e1623e64e0662d84d9ea84b980a2e5268c3d8044110f61b34361b3221a358415cd482284dd64a8486b3e664db304c2bc209a71668b6c4cd88aa3154731265d934d86eed0969900b661cd29b622e664ab202c76446da2e1686fc26244341ab225223586ca8a644b38a99900b526341a341c6d4a918b221737193718b526b129b6d068c4e26c99e50903608aaca99100dc90158b56d0743234c6148b925d15c5a0a5b525b51ab5aad90b15288d28369315c562b134568bd962379c0d59ac96a4c662c5154e57a3d5d0584df69335c950db8c580d2db71c3337612ade68d1d164356c42b6c878d88284d47fc8901037f48181cf0a799ecbac03ca1ca180fc10c6b011849a02c8adb0d59e38b1aa3ae4c20c31e420c343732648033cd8f0820a2378a0c19aa61d8f059e33992e2f7144213f34cc80029d2c58a44071c2c4aa6a88540e1c3160dcb19345830cb05c41deb011c33954f0b0035733ec90a1269880f224060c9d0d2aa440c2081e7420878c010320a53459625545f5820b29ec0901cd540e38bca0020a23887041050478e17244211b681841843b73ba847196eaa8332a0404201e5640c10e081c607040019c454a81f26409d5d147514967f4820b2b3ce0c0015d382b850895d4d1c70301e805175848c10e081cc8c1c08c015da210a1fae1a328fca94a2c74b23f0404a01d5858210514ec802007033307185040171f9051a00069da49118591222b54e860a3cc1802982ce14d500001605f706e876286d2296651a450d8dcc8daa418a46bd05eaac678e88e882926404cc3c891da406bd468c466a03264315018b7162c58c472b215452a7246348a6610d9c0e96e351bad96d268b3590c7d5a171c002d84d56eb59b4c852d58bbc56e146969a942b225d170b6a1ac68052a2ba221655e31a3984ed6874b0361341569ed265b32ba31cc200ca7a488952da9d092fe6acc92c8509a5309613f8c08d1714965389911a526c282d8d2838f167456d4e508a22595d1883139d1a3a799003484d16839aebabc5801e52536440b98b019b725452e8a5c50917ae1b4751c13614ef36d48d24cae768b19cdb664038cd16293a9a0dd4057f8b40831c1ad470d5d6c4e9c519112cd82e86a445911fe24ce9616b3249c148e070d8aac478db8e50309866c694306468ed7c5683522e68430a267eb0017a3de0a54898d988fda8ca0165c8d48c3d954c4845443623770524c84e16a544659b6a91a4729dc6daa288b75fa202c866c2988a3155b18d170444724291784e16c5338940484cd62b9194a4342c3cd7cd07a3c41113d6f01d8a668b8da0c2321b71db2aa5b0c173678d080d1c32640112c1e5a70b65dcd67e413525dd58a64351ab3622c782b9205a083d46e359cac695644360c82ce6ac48e66307837db1a231e7dc8b0e160dc845aa2aa887eb624d90ed90e5a9bb01e2a64426602cc70dc76c86cac506337b684ed9ad0581b6392c5665590a42020420c6b90011f3c7134685381982c57befa56cbd7a414284e98284992756584c85471e84be201800e2d4b01854346081202c81300483466d4d4ecd1b3e602244720c51b2f8a886827dc01010e9b35155020819a07922405d0b473a001adac435228a1746204a11190b1ce0c19b77df281abb139a08cf076431f0cd81489c1182e8870b69a8d1a1e740085b3565544a8a48ec59faac442a7c248068101038061f10718820619b4c9b244893028c3850c063e492879fa11bcd56872be80306782051020a04a04104040c6aaeac9470045681431285227648534a134904c88b487d91f1487d486b4861b0d4533a430a42fa4775239310dd22dd91474079ac3766366c368461a237d81bad0b598b14875684ea622259ae1d29bcd96d66ab35486c65094f68f0bfe3f8d1c0c2bfc55ee197665671367e3d5859f37fed1188cab87a1ffbbab5f10ca21f1cabdf8f39fd44bd8e54c2fad94f4c349c3ee922b699f7b3127f7a2cdfff3f8dc8b2eff4ff4b9176049ddc65a492769cd59b7c3aeab7d80c95bdecc55ef194c1965b7db3d61692bef7fa6e46750b9172ebecb3b58e6f3bc9d4df2dc5f164b1f15e0732d6068710776e7ce59cd5ce7dde431ab9592f82a3fe3de02825c8b30cfc27cdebae73ed782c9c21ce9732d822d76b4b1d672dccef29ebbe64b78cbff8fe3ffe6e256833fe599f777b7b5147236fe3f6643c1a05e8878a2aa9fb42c3fd71e44e2902824068940e28fe823f6882a9147240e8743e13038040e7f43dfb0375487bc215138140a85412150f813fa843da12ae40989c16150180c0681c15fd017ec05d5202f48040e814260100804fe803e600fa8027940e26ff813fe823fe0eff7f3fd7a3ff5c7fb117d439fd017f4017d3f9fcfd7f3a93e9e8fd81bf684bd600fd8fbf57cbd5e4fedf17a4475a80ad5a00a547faa4feda9aaca5389bc214fc80bf280bc1fcfc7ebf1541e8fa7e4b9395d9aeff2aef984a354c12de19292aee82bb8255c15ad977415adb5d6ff68977f94cb3fba658a6e4a17931e2ce5743374b55c8ed0ff277511b7944ceae2dcf2576b5c5269662e5d59ebb9e56f525217fbfef12397cb93cbb1f9d7dd9d9f4aadbbab61fe163b0b3f63e533d6ffa896ffd8e7725ebae8a50002d0f3d62cdf5a5d783b735172cfafffe2fc3c22c7b27cf48a653986fafff47339e1ffef7673b3fdbe42ce7779a7745fdeeeb753999a5a95c703aa5ba9ecf558a1da06996277d7f9bce5750726cfdd5d72799663e5fe47c3fed12cff2896ffa7fa97e9bef72f8b2119f38f5ee1cf7777e9a42c1f931ade1a8e755229c9b9652ff8592cceefb373aca466f9fbee15adf28f52f947c150afff9ff1ff5150ffbfe4732a3878ddf95943c5549777606fecccf1ff518c605852d9ea09508204eb0e359010220693ab0a9c5818044605a56a851f1414bfc07933c507a022d4c86813004e0017db0f1c3c5298e1818d13e5b94c610096301c80a8c980c1b39011004c60c7083a43c04654482182f0f2b6c1ad4e9a5881228794601a27463ace89249511223a333d6e3d392889123a18a40289175e86d4a0d1811e2fc60d963ee46091e1c3972f5a1b35283c70674fd2040b30c0f384400713b4999603cc445dddb1215e7ab0ca58835b681260e0011a4e190c21011b04e83cf500226c8325a2e001868305682c81049909d20470b9174c4831018a30400840a9d138338112414d2f17986439b1961c9153689664a9c00484229478a2138a3eedbafd7f7a680aa23b4f525cd92698a2c2c6182070be091e246f98285d054192800e4d902d96d40070610cd24a034cc6140680f006011a8a8440e262817a1921208ae239c80558cf510e4a042994c1943d49f01162c80b2b055470e1430212be6248b164a0ebd01250360053668aac2218ff9dcbce66bcc24fa4ea44cefd553a9fb1bcd4ea52c3ae9e63187663a7e6cc398e672dc7ad3bbf4facff07e0ffa1702a6ed75eb1acbf5c79de4d0d36bbf053b7b19ee358d6b0cb953a9e7577357ff79af5ff4bfebfc7ffb39fa3052a92c545d5a48c0b044e8c1771764b5ad029e4b4f33e8899f16315a2052adaa115802c35ab8e3a8e05470b229b173810402433a82823879b0d707edc282313b615745052c485082f2123d420544005453890b07344d345862a5b942edca43044ea0af880014735b0749092d2748352c2800f5d74b8ca38b9c2990cf103136faa186de8200c179c951e4007910a02efc41304080a440492951a43940fac74a81c1b2e48f281cf9a2f11c4660cc2e1bc289083a6c848b79923443188841b691e5d97f4cb153f5934746a62b001c9163482207a53f4c010655a7e70f8d9125080070416767e5c60c402177a4674a9d2598043c906133584d11104189868cf0184ba02e0c92f4c0953f2c0863b665e38528457085e69ba9214ab0d2dc91c24471ad028a083c32905f5d01c264ee41c94c040e1ca1f4110648013618a142777daf49090814c2e8a3a30d8f9434690952f430708a520c40587e218e05b87e4a1a3c52943032b158c6c731cf74695d40639a42c072642f610c158303da929c67a40a1480b0938811650816b2da0d9814893fb87898794db0d865cc0a28238400145b05430a122137193f0a09412c6078e1165e01800239090192a5ccda81aa314b441010f30f19458c003b342791317951e4c2812c7ce190a46e0b910648a188ac615039898a3408252fa98c4b4a0c490e2ce08af255f0d7bb20850031fae1a576cee8e59121eacc81d25113ec04246519b304934f075440674be9617f00c72b0e0e7001b7464bcec59a00e9cde01402c4030a16334f59b19a9148940cc43c31237364882070351f019d2030b303bb012a5d48fce4bd0faf912c786d1902c17642085c404062f760063479a90e8e1e4861ea6a22009402807871f4b7b7698e0cc6e80412eb698dc89a2a2bd8975f811541833c05289119c4e4d133225a47812f3c21f2776207130fcaa08c98cb0800f341c7416c8b0d29ab11c35a050e5f9dd8e6061e36c47b4498860ea4448a36422c28580284df68001d18b42c7841d46f09280cc913f4b2bbca624414454960578486193e29454436b41097db46e485aac243c2ed0221a12b4c3288c19410d6760882926dfd0d158e7d0ee4f5495950341d0f830c411bbada096a337454ac0c1d9381b0602ed70880a184293962c6e11261a9d8b164cc0407990020147b2e890e483860f0b6fc02cc1e584845702092d0a8008470dd6a3a09994232e24f0818bed3345084c0b6429e2c31348926809c2a75708034259577fca145f80850181833b33a8405a426b6a04384c144686518809162519e82e0f555a8e0b0704e141e5091d6ce09cf8b960c2520c113660810451dc9545c4eee30575c785df9296891814ad10636800ec71da60c5870d08382a014c0b0f5e4e9ac277660642a500247a5ce88ac9f8088a7dda15eb83d664293d7065ca47ec63bb49d06796154205e921434f0c1d3a74e850e7bd7327d8cc43ff1f9ffe1fcae76846babceb6d1ccb4ee492ca16901dbe5fbafd3f8bff57ff9fc9e766097479a72e9173dbd288d568f19f8a4169406938fea321280046f78f7ed9a2e54a00ffa815f40b1d83444e456919a186382912858562215525c8265254584725505646a0b2a4d019a8469766f827e287ff291ebdddfebf09a5ff1fe17f04dfffdbc1fdff1ee486f1ff5968d7f3ff55fc7f9236d63257369fb09e572ecbf10abb3a9e6157b37c0b7e32a3887c91a5ff9ff25bffefe473e9d7ff1bff73ff8f3229fa47e7df6ff8433a5d3ef757d9345cd72190a736f980be75c8637b4215c855e1b0655a52d962eaf333de5a39736d9add6553bc94f7ba6b5ac22e0cbb6f5397794fd2f48ff6ff471f95593eafdcf9c535735ec2fcd5b1d7ccd4c64c32f78a9d9a39bb5e46e6ccba5efa6b37357f95fb7577d7d69c396b7833672df3251cbfbabb7aeeeeab59eebe4ee733eb677bfebfea73a8957f94cbf9ffb1cca96830a5e6acdbe5b23a9ef5ec6cf279de5ddec97c769bf8eabe9dcbf1da34eced9fdaeb0d957cab6cabf429893e20ef07e4fd7e9bf315e8eb0d833c2591e86b5ae7fe949b666ad0a2ff473f179bf9ff189f439dfedfc5e7d0a487f9ab7f3869aed4ecfb8c995d2be9ee26e92fcec2aecc3bec7679c7c6cda69577e9ff54f9ff323ef780babc9b9b6dfc8fc22fc7b2cc35bc35cb61f9397379867993bfcea6ab6777cbb35ec2ee3cefa61cb77a3f4ae6ff697cee85fcbfd1e7beffff8bcfbd1496bfee6e75e7339852eb36d670ecce5b83c9719337bbbcfbd97f0ae3ff6d7cee657479b7f22ea4d7969b56b937adf1fbee263079cb4af7fd479bffe8fb8f6ebdec1f9d3293218ce8f18485193f3693410f1111ae012b56b0a43aa6b1a05aa6adc0b1d2258c869a69ddf44c63b1699c7e242b5f34d40cc90a169ac62185d150317d43c262430aa3a1b0d090664831fd1a0b0d85897068d02fe8179946757ad4250caabf9c91913bc23d9073229a7dd14311191da5bae808d54646b1a2dbad4b9136baa535a46a9ab655435a03966a1ad21ab098066294e95851d1114a7494a61a47a48968445d649aa848bf1112d951972b388d6ae134aaaf106923a8f4284bd8d1172050314d74d4250c0a15d35f8040c9f41b1915dd8e50a83495d990c2629a566474f450b7a32e37db5117225d84430a8b75b98225a68990c2625dc26828239d1a39c98585858541c5b4d1d1152c317d430a8be9546bc5521d24c51d8541a170fa76140685ba69a2a32e5f8040e17418148a4813a5474632a3630d24326da49dc47491b61d75b12dc9026584ea2b389d5e21d2682ea604853ba269140a27418eeb0f1969485b6bc052bd064ca67357a9468d6a2091e9546bc534aa6d32ad6329cd0d912d264cf5eb87428fc2c0e10212e6a84b1819121c2e205fe0700131a6465c8fc718c382a24b88700ce4528dc634912c353aa6293a64866474346689a145883e3de28aa57af6daba6cd1624c752a43e9107d16a29ab671c58c37994c96ea9baed964b59b2c56abdd6a37242e2b32994c168b11a55650349d637aa663332bb619526a44248bb1660b926ecd90b8ac186f485b359d6ada4c96c53825d5e8560dc94aaa51bd35e380e8531d436b9a886876d34f15d333a4ae54d3f44c76c425c388227159e19231851a6d31e3cd86c465c55843da9a69342643e27ae31759919640247771e530ce34974ca77ae6ca517424c3c5918d34b8d551e3ed4dcec5968b3429a6b531a6635a860e238a414444f4485364c63416fb622c95ca124339919c3ed3ebd833bd9e3dd36bda33bdae3dd36bdb33bdbe3dd36bdc33bd267aa6d745cff4dae8995eab78a6d72b9ee975ee995eb378a6d72d9ee9b58b677afde2995ec778a6d7329ee9f58c677a4de3995ed778a6d7369ee9f58d677a8de3995ee778a6d7e8d12d4f4efbf917cac8bd3027f57a805c9601721a4eeaa228368be130c63e07f486012e0c0e4cee51c0a3664aaaa7d4f416d7165aa4896a475b5c5b35fdb5d7e9dad1168ea66f5aa7a7d0fe680d0b5d3be25aa1659ac8487744d3a53a5d4b8f70ba76f4dac8165b71b4b542bf118793e915315c2ea66b47b8dc11176a94c9888a8ed6b0a81dd1d2221b161d0b8d4577d3342316708834aad3e911d7941ad2ad680d8b1546476b582085d150ba0ec748c3e934fda8aebd7145113ad3485b355d3beaca614c89d29b10449f3ed16ab61bee89a848857ebd237d5aa1d3af9762475364463838f40a15464544b89bad3625a6793aa2221cd10d67bbd56cb49ac632d337349699aea1b1cc340d8d65a667c88801e3858b1632bd86a659e82031e38d231b47325b51ce850c1b7a47d2526e850aa32222dccd5643b28265a65f662bcab9906143efd058664859502c33d25a0344366cb89021a3850b172c72395d51111a43635a86c650238dda9021e3b50b173a977b5d54f4da667b2d93cd8af46b172c5ae858e4742b7256b8ac285a63a46535a30b242b36acc8d0215971915b8164a5c866f4426329427a2224190ec976432ab221e56a482e340d49c6ec05d223d94881a9ce8262d1a5343044366c7c6c032219cd862b52916361c3860c192e5ce4724545369b4ca63b92c96cb6a2a25cce850b19326cd8c8a1b21ede58dbaa699cbe1dd5b4eda8a6896a341c979c4ddf348e8643daba69d90dc959d332a229734aa46fb7dbed76bbdd6e3722227d9bd58c44485da971be19159961bc21d5284264bce9d458d3b723dc519198f196ea5aaa77d090b6d032333d44bf83284d0bc5feffffffffffffffffff3f59fb989c421f4b004d1a3515b0791387833a77d2a4587a421e3d7c66e8e3e70fa04082d2a418d2942f83a2288aa2288aa2288a2680268d9a0ad8bc89234b4a004d1a3515b079634c759aeadf115b8100d1efc8a173bccc0e0dc70d1b3568cc901103c60b17690b16badc0a15464544b85b0e4d9416e5d039f4cd4eee5f964396e3b5d677ea7010e70d9b0ad4a441050502f4c74f9f19f8e8c9f33e7a676949af095347000138e8d1238e92d29ba4241d94b902d0a8e69ae9354c0168301aaa5786092981dd119a261d69783bd4a87aa6b900d0a89669b4821e0f0d4643a9bc1d1a8c866ada31215d81833443da9a2171f52c3cb44c2f21a10220a13d905025243409090d0009e58184028084ee40427520a14848e8912c87d66552a5476353936323234eaaf4c2a3097552a537bac9912345d13b37685a9665f48d91a665940d5a01aa064d83a2718124a365d0316818b40b1af652a8a06959fe42469a96695afe3409872427d3245a57aa511a14265a5746a68404711afeb850ddb318e754673116a265514a753ed4743215a67c624a35dd27d09f4281de8942614e84792c78eed4e120ce1b3615a8498326813263c27441c3a470428942820201fae3a7cf0c7cf4e439c148c3e334fcf1969268341a8d46a3e1bce4705e72345dd3b52b61c6ad17c51343efd4e120ce1b3615a8498326813263c258f99a9d2f934d4261a27565644a4810a7e18fb794b443d368341a8d3605c5d3b31851a4399605d725578346abc574a7a940aaf13415341a8d86ea2933342e173baa11336ed5b491c675c915699bdea2e999ae192171c5d05aaef142d7b45ca3c5149d36aa19214d61a16b485356681c520d157aca0c154832fd362d03892b0652cf629cb3186722dd050389ab6654a1e51a2f90a6aec87011936bb4409ac262a4e937ce391d52570ee394d448439ad2b3e0749a0b87348505920e69ca0a6da47348cf1c461cd216ada6715a05d2948ec548a4df6874547444b4e386b4150b330282689e82c748841ed528129b82121951fd475d6891d815638a2a21fa1d5b34fdda74cd76f4b61a9642c6db1b0db9dd6cb62b634da689701a57d3b59b46916adc905ebf91555a14664c7551181ac856283745cbb40ca9c6ecd33f666e183c0a79c28c6c7236631643399bf15188e18ff151c0a3c688ea2a9a26b271b4a5d36f94c96e4747474737dbec481f1da569aae1749bbea5475ca8d186647494691b3a9d1ea553527dd3b6a32929d29c1a733aa6cb21d5b01515d96c5c336dd3319d0689715931ca521b7aa66d1c6dcd90a6ac39d23a8dc5881e1d85d15047391d46431de91cd2d1919ea147327d74f4503aa41bda48eb5ea6d3e96ae890baae460dadd3366cd8d01d3d6ac469dbd1d16cc6d1560bfde2301211c94052a18b8a6c69128d068e801c0b6da48bb40a4da4e285c6691ab72872321d43e3344ddfb40a9da6d168ba280dded0344df44633908e72d0389ab2c68bd64756b8a05047dacb91b67134a3461bfac6d18c1a6fe474b7e954a79a86d6d940ea3674baebb40d5de3688b0bd53790fa0d8d43f71a1a071257ceca15385ca84e351c1a1a8c86ca8174050e178ab4c565ec35f40d1d2476e30835dad0b9489368344d83a6671c298d372872328dd3b7203119476f8c7124cba6d85c1c21c1388e2d90669a51a683a42c8e66d428335a717424d246ba289da2ad7c1967b3d3c815cbe999518734250b97cc9843ea4a8d449a082d5a71841a898a34116a44946a5c4da3faa6c208696b56448434c77e870d69a66947331ae98a038864da4de3f4efd013464f173d61344db323a705362d54d0821a236d14b3634b67798ca99ed94e30a63322dd5948711a278796a6321769924c6b5e9a24d3bf3449a68769924c3bc9b4102369924c5fa54932ad9526c93494344946a3c96678521e5e20b269a2a2a2a3352df48a229b2e2ad270faafd0e9ef36a42d5ad1949ba6e92e1cc6a25fa1e7d458d485c358a4e7d4b802c92633de7045479f26dda6a449459aa68b9058e815369b1522242b2c702cb8b01869fab9d6b4d053661c4e450c87e254a06f9cb242e3f416d7941548736a9ce95b0bdad1142219ed684a2e8c866a516493195b205969a1b1b0b869dd119715e3ccd8e2e8a1722c8ee01869db1157cc38d36b5868a22934a49b8a352d74da665b71b4a60552180dc5a21785d1502c6870566838bdc876d3445c588cb39c5671c4851a679aa67b11d2168dc8460387b465d337a42d1b5a941a7521d2362dc32d90a3214d39326e4de9428d9d46d35da991a665aed47893b96446232d73d98c459a2b6724d21d4b4dffc78c642b8a6c9da6b98890b666fa8d9da6bb724568342b1d87b31d759b8dd63baecb34d70d69eba6dfd865daa66f325dd34162355dd337a4d928439a53e315a34c67b9a131315304733c23bf76f3c9098eddd969f5b59babdb61579ebf3892f7ad94f9559f994b972f79eaf99e4ebdef378ab9cedbd95d2132bffadacd6211b5ca4525b9efee9afbfc3e77cb59cd5fa5db619ed5e55d9fdda6fb36f9dcc108e05c965abbdb2c163bccb7e2b958ecfd39ef398baff07e3714e72db2836d27981ccf9b85f79177cbdc69f5eea61c5775b07dd5e55d5353d32a04aa2b10d8f4f30db96faf3ea14fc9ebad4a21139fb73c77e5b3bfbbc8975b8ee75e2cce72ec743e3b9237b7dce68c27ec76bb0066fe2ecd9bcb4b3dc7557ad7f5bbf7fb5cdfbdea25ecb2f05373796bbea4f8f22efe22e1d89dd7dde12dcfc5b8aaf3264434fedfc8e78c573efe5fcae782f0793e770e23653ebbc8662cb7c8953b7bd3cabb724138f87faff86d65de156bb0d95db773af73feff7d1d6dccffb39c4bfb6061fe84dda67ed22ccc995b9e95cfde26cbff333f17e4bbbcf38a59d8f5f2edd45d8f698bbf9b6522aa40608f77c9cff56bb329064e28827c54083754c208faf36f438e128349e867632aa012c20195a751d93892815de165554aac0230a9f1e810092cb11196c2cf6a984103044dd8cf02f150ec22087a9a0443353f244e8f032109451aa71cde569cc00206fa507d4d8775e668109897c9c08cda92a3f6341848023a8adcbe06a562c91116dcbc8c01301a6f4870f1b3a19610a7215ef8d904473f51cc00e0674a38ec30000e289e761442d6c493899785e03402145140f13325189081c11ade3f008086b03095c3d78c5e00c1af9d379aa13086b1f2c0131910e3c1a3207a1c16b9030636e0e03f0911503d74ba7c9113437328b880859fd500c5030050a0c4c7b2f2243d11be787488a4040084753ed6840a12908900cca73012489269d2e751a25947134ac2d3484075193441e8674bbc2c81630def69218445e953d27cec87d9ef09530e9f0a5ae1dc9aa5f02a9c8e36146d3dfe064117d4518fe2633f843a9acba3a7fdf0f3e48228382f5be2ba380658f39fe4c51b2e194c7c1a030b1806e851f13122642a0316338f06f1600a1ba29cf035231e0a40d3818aaf45b065860327d09ef6840d0b4149c1af2d01008d7047ffd91c270a9e30c55f1ba08808ce32e3672a7054512469e1531d3c0eb0e2e7cc17c9456168be7c79a2a8ff332b70e66b0ac828fca428f4b31d3aa070c781e7a72d7c04724248cfc74698b2c649fce33f034364789411f3afc3c59d32421c1feb82801b056854f029f1842b33c8d0fa3ff44071cc04391edda2c5431419465fb44450bae30e0c6fc34105102810f5781a0d3539380085d6d7880c0102cf22c0cbf23859e2ea61fa1a01485c0520b8f1b13653af053ffc3c8d479942445001e065b71990698e094fa3d2c4c4c615173e5d03078f094740f85a07bb240027dcf85998424e30e4c0f133d68806170fe9d74ce89d591bd8e0716f2c031b98b0f3b7a42e8ce08896b7694511c30c1f709ec84bc7172f3324f8199b22119f3a375ef6a5ea082d5dfa7fd2124309f4e0e6532636a27800f9e1ff83fe000b0902fdcc080b212fe1e31f879dac302904fa59f139a3842e0b7c8c88130b2a2039fe4b39c1a4eb343f86440611b31952fef6222528e3e2888fe126c882d440d8cbe6140a620924c8fc8d97c21929f5cdd392611c844083954f7dd8de422d0d8f167088823de5834791f87c3cf162f468983d3d5a25b47cac96844294a73d1fdb4781d4e070c0cf9860dc00ddb8ffc41a5c681e0cbef6028d226af86182afbd80c3432c439c2f42322046851d58fea6a40d1d264874bc0d26da60041b3d5f14428e99a109a2bc11cd86a51948f47c6c4f172766aa2c7d1ac5e40d0744533e1648c7c20728803edd392141a0068e1f2bd2c25f30f0e5692840c9d1634e0e3ff393c2a106644c7c2d65a28490f5f335dab0c98c075e4fd353820763764d9e684fd182d71bf3b6240eba17726abc2d0719229481b3fc9b9110aa979487b70d70468b0a7dfc7c6c4ed4ee0e043a7cac850954a85868fa590938b2c0c0a0e563357628f1a08ed7cf6cb01064ec0d7a19d381d44d0c1ebee615401a1822bc79b4831f4c388ae2c6d7a088a3841349949ff25ef4b8bc9eb729d1c3010330c5f02a3e38428e07493cde36f5419d344708fa9a51142904ad966fbbe108082f46a07e3681970e4a9228bee664051c1baa7cbdac8e21ad040880fad8971087cecc31f4330b760fb0e08ce0d12584aaec72247d5ac6841a6e58c07e464192284889284fab63260e1a1e1e7cea6703a624d9f84480702c0e4c578fdb9194b3829ee017a5491d6e7470f02a9864b881039e2c3fbb8a0267548bff3930630b418b9d47f320a591014e95afb1907368042142fc8c5940d21078e07c4c0b0b278fe7091fbbe183065ac0c1e0632d9876608430c1cf704833c39c02ba7ccceaf5c1869c155e36c3815fcc05acaf89d9720210214e7fe341c30f6ffa0a7f9b094a8bb831ffcd8f953449187d7fdbfa117b93be3c9aa5c66fe3a07e0ccc12640c4556f81ad4211633de747d0c4db3028438549ed6820313887065cdd7ae7010633e92f9988ca3b4d8d5e55325e6f011e018fada9c3c108840c17e99024ee86039e2bd2c031524cc4015c1cf8808d066065ef16bc30ade0e2e20e05125738a90b182d4db86d0d0da64a547cd8c01038392f6512c2933085163cdcb6e67a85419d2f531158c9ea69a2dfc87c568e2cad3144fdb2531850b4f178fca5400d990a5e6d30b0639c007cd95af150db0420e2c595e86a77d46ad067c4dc90a494801d3d77c9880d4c30b86dec6c70a501115083e25c38bb126068b27eaa1cf56b187342fd383434b05000a781a14779ca817944fbbe80079c6b67cfa02a5c0070a3f7ccabb81440e509eff425081e1061e541f9b01092fb983231fc361caa5f2c4f7312f004c418024cea73cc849b3260df036274aa023e432fc9b0c609c5a7ed09711512ae2e3dbe0654e32a71506a5afc508a24bca81daa729b8308b112ae05f82261f30f1c5c1c7b61cf17468627a1a0871509803e8829789a99225090b039e4643021846673cf8dfc050129d34193cedf85e3fcc3c3ea674c50705b0f078da9979105308fdb12927542e984288a77501c6808e317e5119207660ca525ef62e95480a51c0df96a49228109af035019c3c69fad0e5652d1b675a8ce1d13a716cc0e3020aff34e4887998b43cdac4d3ceb12a3ded50001818d26083a711b02705076098f2b116fc3880e5089c7f660938b4e066cdff0283c6e030d31f77e7ce02529869f3b679820f06a9d0fbdb0f07433306ae7c110e56031e6c8cf894821ebe30c1c1054f5b62ca0f2e2c50e85f8e0a08b8502ce2512c6590388f50e2d12366546de1b0be568304990e889e8fedba0d27b8b0e153362300b142a1035e66878c11232cdcf82feed9c2a4e5e1694672602a19c2e56b756008ad00f1f9190c3bf044458ba7e1993ab2f1a6885fa10197991e45504f84c396c2912090bee6021c5d1706093c4d4a862f652e9f36c7c9cb80071abcec8d117a4698ca7a190a38f0924d42f81a1e17ecf061a1ea6b6a147ec43ce0c3d7623322aec8333c2aa7d67714e1c7be1c3d003224c9ab28824e93064c90e163457e3001250a1d5f1483080c4e5c587d6dc80c383704793cd1920d73cf98f46308dca9e295c7c6a34a2cf9c264cda08f29f9d0b560e7ced3e61c61c24d8d074f5bf1c780075028f2e90934c280e020eb65324a00c312c3ff5bf0b447891f7078b40913887802d4c3d76a0054cbc15efdedcc528f0ba8f46db1050e707253c2abd012f4e4039ff7531926fcf9c026e5557cb0a583d74a88a719d9014dd0eac6c72c8803028b2a7d3e26010f3a81c288799408327d8c0128fd67d07bb3ace3f53442bc087418d1f84fa04f926206568ffaa0a7041f17d93f91778149bff032f8a8072a23761f0b62c60a2701fa51353a109809c1f9db0e0ab4c81184c8cf5e120a71cdd9f24548206c3c3081c0c7dae08a8239fefc0c811e772a80007ef4a62e6900b7f999912532b81451e5d31b3e7c90a089003fbbe1051c5ac41cf131136a689ee6158fc2d0650c60010ffe1970d181d60872fe83f8f2e42ce0c9e3d00b8c330a38e089d409c2fa9fd8e3628829636584039f9229a088d301e3a3708cc4d226c3473380a2a448d1eb674ae610e9f84df9071393e2e68727beb691c9a7b8c5d78a0bd8a0c26c81afd110476be77a78f40e132af02982c8cba49a3b07a8e2d75ec8d37ca2823c2f3bfaac68b579e0632a2471e29618f44554535881d141f1b21ac85829127a7efab441c19c2d455f53a165c8d08be73f4c1c16ae28d17bd91a60ada988a04fb96450208d107cfe81a82942872c433f43bd84f18187351f2342ca8f5c820e8fe280ea1db08682afed398086203820f0290e336baa9678fce39282411469e065f1105e8ef880eb6d39d0b9533446cfd36233960e6886be066501178eb853fc999c28749802ce9797096168c170a37c591b08a85ee080888f69ed39865d60e41f8abd34a380a99f85600110c3ae2c4f0382d2498201fb315cb008b0b5f6331c7658b04291c1d7a25c01308409ac9fe541017726c981bf2d39f3208f3ade36445313019c40c1df76451881840a453cce4a9b1e5c383ae2711d2815ba21cced6749639848d224ced7f408a102c35393af1df166f8d165819fbd1c6071ca427e9a0557e133c30e4f0be6d05a3040d5d3862054d4448501be966504101b5cd078190e5c124810fa3d7a4ba365811131fc0ceba909381ce05328289494c160ccc70600a4010761d6fcacc908705e20c0bc6d8884062345c42f636eac03dc84f9d485121432ac9c1ffb5d69d04508d5cf5e9052a2891d6a2fc320811a7c45a8f0e9971404ec9987f81a9425177049dacba85429847ba1f9332737088a60d7e3635a9ad411f243f8b33d5b442442ce57c1028c9e4119e47ea6b4dcd92290fa58095f8836b690af4101a7cc0e5d00fc0c8a6e0601eef9590857cea4d953e3532947ab1301375f731232844047c2cf7a38e236021b1abe668787302308433e1d1e32924229cba327d08020c890e66986664e08f1137b9482b4c9031e40f13409a2ac805201d5c76e20c46b6202cccfc638d9317d98e269632ae8d184ce8127322289233d1f98f0b2acb70721e7068fcae0d2418586e56b07f09681e194476531ecb0a705f26556585d34783afe5958334bd3037e4c9904cb21a2e5bf0149aca8139bf03f08070e18360e4f530aee00ab82e16b422469418daae26f3d1b309011c38f475f28f09444c7064fd4270cf28ed5fae9546dced4170dbee644125047580b3e1d048c1366c8f3676adc005900840e9e560305a89c0a7f9e76c1151c4ebe1cf9589f03c8d4b9a2fb9ad7a00a8a645a4f43611dae6c387eacf5f2722505f96314ac47342db9e06d520200a1089a1e4feb715c736888111e97e7cbae051c2f3f6340ee393100ee6724ac682fc062c2cfba30a982e404d0d7e6f449e3e484278fb63426586ea8f232220cb1f0c2135e3f4373a405a7670e3f93a30bc036a4c8ff0b02bc017f927c2de9053e008fef6b52c522c814b03e6ad4a78e0bc1d4c792f8794116f6e46f312c8140133d297f7b9500348253d7e3a0b8a6482166809789e064d5e7ebc6c75c1a534a03395ec63546013407edd36213114110b1e2694f042185084da23e467c52068317c29fc91120880401787e86e480412304b77c1a4327bb4064e567b90c604861e8cca3431870640024e09fc56a602da022c1e394445044c08f1dbec84f91417b8c474f344328840e862c4f83bac0c68d89e9d141395028b6484f332231f5678d999f31512a43c5c5fa28981f7c647530c57f8c4137fd81f263346ea01203dce369869e8a546e207f16c41812884012f0a8182a6a90aa88f0312ca295ad12e2af65b0c4464d0c181e87c419a1268ea197b9392a22e6872a9f72211ec14107eddf86b83a386974f0680e5e5f07cc70f1342e19bc44bdc0f13225f6c8a6ec089f46c44a060b684879190db92c3254d0f2a92f05242030e0e86751c28d2cc4e6d1b0a2237e9861caa34b502c7f58a287af2d8123041b14241ec7624f918d0298bc4c06ae16303288fa9ad2941b3a1043c4c756e3910a0a31dfb64418295ebc107cacc8062c4d0b7c5a5ff6361f343f9603a9040d275d2f73a1038a32c796976541c05667c68aff1c8a78a9a140ec65caa725e834694fa363c296b510132f5b007da15bd1f9dfa148b9440c24fc6de9e634a80efab577900b374f863c911b2c0094989b7c8d6f08de0860e78dae9c4fb460f3c1d3341881eda1000b8f8e19e04e913920bc6c884310bc4f107859a1f603a527043dba060dd5d0c0084feb418b842f43683e06c7096784abe3d73838f30c24059aa7a54080d0c921c7a32ea83956c0127f3a80a1425d6424ff96e600258235bc37ca811904a687f8693c18a3208280d0d3ecc419a0041571fea124c142b400023fab8101010874e1f35f87901f2248327e8603860c15e3c47f1f086a882d01e8d19c10816223317c6a400266ceec50f2b2354b82f03166c8cfa6a0d3e6069e133f53a188a20e22e5717a9e68a21702035f03d2a50906ee0cf99a9108665060c6f9296b02a02b59c8d3a2889440e187c4c73428d4c28d32499f42d0808ce98cfbb4ae097cf212fdff1304938c8f9ca7f9f899a072413fd6660f141764f6d7ba921cb242ab7c2a858405367061e9694d705848620c979f8d706391c701402f8353f39280158d5771a68141497cf8bced38e80e0ac1107ffbc3e60a8e60016f73614d222a06277e26020641baa03a8f42f0e600a5abe8d1394c214266b4bc0c0621487c29813fba65a6f118cea705a03bc1c5095a3fbb7ad3c64a0b9a97053b900104cacda36222a871800fcda72d313aa14905888f1d19996f33f0c71570449f207be4a74d45c1414d49d6df7e20a00140542c3eed2108af32680cf899144a94b8a8e0879ff9a25881801f954f5b40e106d7823a3f5b91617a489df819ac167ae248cc3f112fe2fc4897fc4c862e330bac7c9fd6163023864f8ba78159a2b98aa9f28f0524c61e30e68b62149f78d082cacf8cb8014007e28737e293c49b153890f91bae8325a2f8c0f9589f37f3ecc69dafe5ccaca0c708a797996024e3482f7ed90960203419b4c1c7dcf86248604d073f23fa4106049648f035ac153f3820da7dcc46102451b4a03ee52780419993fe49e00814d280cfd77619ac186928f8d99f1ac559e987bf2561a78a0a64c5e3d81d1bcda6cda3316850a08c1d7ada3ee21a98f0e5697b668c40e547eb531f4920e1f105888f7d9084c25376e5677e680a480108834f9fe0b00485a0e567365a294505283f35f4c4c701afd0cf7e1432b2858b3fcaa2109c3c34083ded8ad3eac71096af29402846d68af671585490d0e3459a9fbd0184078808548fc6460081f0a47adb15a2a71460ea3f55061b2c1521c1cb3030204c1005063e657280f90608223fbb618d828605eafc1349c3039227a27c8c0031388029c3c1d39c4a30f0828b9b9755ed2e60b1a789a7f980c10c1c043278992139c00f96887a5c9d2300c54e835e85aab582054f2abccd881d62365040c5cb2e50e14c2f02c3d74c8855f0e1c1f153a3e710651b411fb39381148d819347ad2cc122ec86364f5b9202c61d01747c2d4791315f3e312f9301f1c61c18f329941b0c30a2ab819f11c121f9c707c0d7fc1c4a8304887d994e3bfd2491e46b786438be0027cccb042961c29a2706fcad87a7c60c36c078dc520d0db82cf179da918b9c30e490afade04106f8611e3d9a518bc282ab8f2df035800dc6e77f920bd41155b48f313521ace365eb6b06308951048af233279ecc7015a67f6c0308600070c3ee631110114406c9889f6990020c3938f63c910d86d260d999fff6821002168cc7bf45e17242115d60de4646830ca88c4bfc0c0999526ba6fd99d5021b44e17cfeeb276702c1a9e1bf8e0205dcb1c37c9997064f60d101c3a73d2e133891133eed0c8bc29186e5d1306176725cb0f233e64fc62348d0cf9ea8722600998d7f40447c48a524bf76e5c6b70bb9799b112a80ec09d2c3cf42308006aec2883712818d1f33567a7c0c4c9f1d0bf40b3e251a82841282f04f8338e5084529fdfb987262498a0bfe67ec12092bba1e6da27f318636ff3c09324002052b4f0bf22a523214f13299929712bc2ef85a956411625e409fea4912220e1e1ade86cb008527e00c4f5bc0384001076cfd0dc7103a945668bdcd8593819509fe8bce1420c84c0622fc6cf390621a88e1655939f21022f6f0cf038f18272923ffc9069c163c91fc8cc505cd2656a67c8d19f7f811c7f8d80f9c05442f3cf034423c7e30b3e73c6d4ca026c6c4627e6680002eec9608e1899a6ea891c2e086a73d404baee002f1351c7f0c1175413e5107479e5843b8f0b6e0cde987272c3efdd2c594c46bfad8105833cc9183c0bf085dcb0e141cfdf798e2913880884f07ed08864041a07f366654f8d9eb3f044343184408f4e9170e60f8a015f51fe885073a0e3df0b1233b3b3900307e0d830788bf322a7c4c872552e80870e18daca094504108467c4d3de01052121a7ef6e2891b5cac69f1b11216d0c1890934781990c5af1626e89f480b0a34c4ca7c8c059a1d0218c0fa98970d3c4bae00f168d10c05ed03cd4f5d3c9121c7851d8f1e0973c301e7809751514206002ab18f4560670b1322bfb7c14d0ce185069fafd1915a800818fc3c8d830b70f8c1a7e36b58238045b09d6f5b0630f47a22f4b5e7b2a40329f27c0d4a01e68c2f2fff2704f982c456073fbb408a0b456e529e76028f12de5c65bd6c8f9612e905f9b36ec49b5d9d0a5e86e3be2766735ef6801b3d6f0cbc7f019ab0c1070d9eaf25a0c78c570b38fe06c30181c48480c2cba6a0aeec2992f538ad65bc204d984f972f60788181395f0340854327c049f2b4b0242fc8f421e267443540a1a1edf934832d43d07013e36bce2243d47cd0f535314daf03fe207ff6e7500e2e37b4ff3e4e847a8a161ff352a1e424c6edd12f4e69fcb061be8a3974d43ceda0f9a2036c4beef8c0e2696990e83c47b8f33525421cb0a0bef0312414b80dd101f0e8d50911ec302586afad902414a285e59f1905b2850d0c3c0ae8cb6d8b097afe992ea4b428c2e57f460728d0d0144f4372d1836045f35fd6a002401f383f467cd235b001cacffea0c004ab377919911606b84280137ffb229a20850b328f9ef0c5c5690bf3651aacd0da49d53762d1c3d00b155c7e66c1a01bcc434e3e66a360040b60bcf0b405b47411eef36b3c393e063ad4a74bc4f075c4c1c3d7b8fea0f15200a0a735ed5ed8c9b94f5528e120c4a7c7cba6f0f5148634ff8f6228066178be5116510c123efba20e4ed0f2600bd0cfea0c0dd0d27279d95c021d05beb87c11047c9628c8c2c1cbc28eb1146c488fead0a507190808f37f35000f87bca6bccca9059c005826f83fe205b023542c3f9dd1fecee420e5635b5956d8e323f6280b635650a2063b1f938007066e3ccafc4c2a0f3beb86fc6c050b6efc6035c4d77298608e01556ef8a2404e6ca842449e970d3ae2a90428e0af55716aa6d080002f9bdf22bc09a19f697db07c33c6f8b31d7ebc179440f235202d0011a469c0a35bea5890278fd6d7686409c2d08e2d2fb3d998228016093ced8a8305923a9e4f6b9813a5032de9c7be4c09d13b807915320060e6480e5d1e77040d471ce8099fe64485a4808c2d7fab43e3cf004830795a97110aa87800fe99ae0616b90c8ebcec083dc3f4b4c2d79adc4c78e343088fa62044143ab4b0c1a75d4d0ef0a103e3653ea0cc7054c0ec6b4810bac890c59eb68254912a1cfc322f594834f068f9d89e2f52635e207a1a0ea403b2b0d8e1630a2cb0c30e5324bfd64216d40c1db7bf51d0a24b011530f0343db1162f10a1e665674088715073e6652a0c5e0e4831f5b40812d0538687069ee6e308100ce8f1fe4b30a3ef28f8fae7f1b50586aef4d32c1706683223c9a774f8047692d0e0511f3c68d014a3afa13e7a594640e0d3df145804fde0bf690c42a8ddaebc0c47201c8658ec7922251e389083d7a0b7958034c167697ecc0fc712208b8797558024238c1e1c5e36454698222a31bc8cc71594041c987d6c09852992030cf1a8183a68d207a07c6c0418f814dbd0f954988156144ef6fc6cd743cec94380af3d49a9be444dbd2c0027190020d5e76b368489006a48c0cff0f0a9716609c5dffe48cd4e0082895ff15dc484f5d8e16b4e31f4511cdbcfb824a982c5c50a5fcb727a4280a1153f73f143f1f8a78697051aa1cc51831a2f4b33b320079c159e36a405fe83acff8c0a092c945b684fdba1029b0f4bf3694758620f84b14f5404021986706cf8da1b219acc00e4c3e36ad450030350603f234218a6cf06fc694b3117b0596d7c0d8328e4a4a0e689ff2c0caab40e4b8feee0810b7a8caefcff5933030252781f6be641eb6c30c1a3350ca2210620d48f15aa5ac247002bfcb371869813e6e5d3a59790b989235f5b6aa04def48cecbb6081798e192e76f40863728195bfcedea030060c033c3d794f43a348e281f07854f0255148cf0b2a29b2016d8c0cec78e3831dac04b014f63220d076986fa1f8a1820003973e663391ca1a5c7162f8f6aad11e2490e9d4f9f3802822f03a03c6a664b0eadcffa548905226804128f6e31a182213580f0b804a0bce002cef1444f42052cf165e97187e4b0001a91def655840e6ab4a03ebd23c466811dfdb309b64c394200073e5d9975e40952f8580b4d557935e665515fec188152e069080031e2d367804fdd1cc0e49924849fa941d03c5140ee674d4e9430e288d5d7eed4115ab5d1f3688e4015481103ff9a046c0f1fb051f145549205b041ad5e364b93e73625f7b41bb915b89200fa591c3646089de13ded88181d0c5028854f676032120108423f336a790e2cd5bc0c4c012608d000f6288b19182a6d982fb38ae10925325a1ef5c5f0a7041abf4f9f92025022082bff2024c5a8a14ff04f9cd910e480a7b7597942060a7e14f9590f012f151851dfb60411d193910edec6039716130060e28b10486189313ee4ff9bb186155e031ff34348851f47597e26026f81d9257ba3558517225c10c1df62e04360c1e0e3635d08d440a2ceef654a6a106061d17ccd86214c88d0357c944b8c3ba3410c5f63420d55955d8d9f2d40805083b68447f505b07b06834f9b3e34200296f4b3056226f878007fe6a48d904147f4bf52ad0701023cfd6fe9612109211e1e35214b9939b42e5f9be1260509a4b07ad98d84049024747ded4b9e3250a038f4342444fb479e43ffb59dce77987c5ac4d46e890cc4ff29da84450942c4a7757a5332296e7ccd8b0217841981e06b464849134251f29f060ba42023e381a7d50880880a35713e0dd27c0085e6a1a7f5312a0401f3fad80b42f0c4c2b03e7675d5d543072a4f7320011e738e68f2331d74c1870e0e7d8d98c2aac6c9cecf84982089e2517a944d928f1770081f3bc2428b265f14fcaf5871e8501140206a7c0c043a6f96809cfc8aa9109647410cd25df4fc57704bba78c35591372a2606db46be5058f26bcddacb5ef603fd9a1a949de9d0daaf4067305015a8ad27137e2c01198e5a6ab3cd643114fd18e9eed34791c880a05ff331fb1534f451149dcd7e2951fa288ac6d22914ada1298ac668545234456b290c2c14a5a1b54f51a35d2ca5d192701a95a5a9ac0c2a43d114872e91a2b79fa1b234c651744a8aa2a92d495a2345539a2c458b4851348378ff820aed94d839490bc2d314a4662788f9bfe3729b13a4774a72779b5a8edb2202651551a708f77fd77bfceaf9196b782f69aff8e54a3d3f953d36b2dc6b33b5a458ce72cec2eeda3916cbe5786661eeeccf2c2896cfb07b449eb79363b149583ef7d8c8dc9f4258ee15b3f0918832ffbb241149974904ef7f97242299d443d4e1b921be8c435cfdeff813e65ef1ab63a82172ff72a03fee5653200e7ec7c4652798bcddd56d39cca156ae04c9be71b1a8c5b9dc22bd381c686a172519480b51e885c8f3bb284921d0fc2e4a5208e60b311442c52e4a92aabffb09bb5ffbc88e37dd79de9a7d63e6d73e02c3b12bc72d0b730df61e7138d673dffcd5f3d6b32b3fe3aeddeaaddb97f758882e72d87d75339ee7184aefe25977b7bb5a7ec66ed766f2992fc176b36bfe3a9f311895de65c542b41c4fd94dbdb5f3a961ee8c8b5bdd9535ec156bf91983e979ebb8eb98957917f78aa7f42ec97224979f2befb09bd4bcd5f05e97b8d2d53dc0de7773b9877ec660baa5d24756584727baca38a5a5b18e5ac623d6107d84d25a59498ee81dcc9df18efdf9236dc58a66b9fef1a4ad58d14a49dddd712eb7cd5da5779bcbad66e1a5deb9320b8e757f35186cd4bb9d4cf667329e67385e9770fc6e9d4ceacefb526fdb98b35b9ea17432f98c9be86432a9af68fdf4b4e72d442fe9a52727a7a6cbcc72ee237cb97f68ad7515adf9eb3a9bf11ac3c964f2a875c4737f9dcdfdc5353baf9bb37beef333d66dbcd39d8727ff5fe4733ce4fe7f174000bac8bac8a5de7259efff8f3fb703033bdeee3e3f954f3786f5ccc1f4d20cbb3bbc686a6dd43b186c95797f6aa32e2e611796f792beb5c646b4eeec1b4f6d2ee4ddee0cf38e0536bbacfbe47257243f4785b7e72d048ba5da5a6323acdbbbbcb5c646604e25965bb62ff72bb597fb6d3997db265ef013666743ce8fd3ff6f0dc7ae911c0a3d9b6ae510e79de4e0dcb13c2b85828314cfbb70e0b3c3a1cdaad58b452da7af180ad977507d0eff71c8fdffdf10e8063c37a8b901ec91c85d67e3febe3bcdff233f87c5ebb7f2d9c19c2f1b37917df27c1f35ffff9c393f7ba7ea53e5fff91c2bd9c97c8ebb64addfd7f8c4523981c9bbd97cf2ad3d23fbbc915a4eec1bd750a76f2fa317a76269087b213430f9dfd1c083a221f77259cf10a8cfc0c2ffeec969c9ba5e1c7e7a72fa8aa166b0c9d04706362fc3970c5332e8df4549c65028063cbb28c95c0c6862d8da6969e61a3b8fdac88ecbefd660f0eeb07b64d78c57ae7c77975183c9bc8bebeeeea8f44e8e9d4fddc69ca9c59bbb4ae64e4ec5cdda712a6edf35e167abe71e335978eb5883bdef7ec2bb192f2d6117ec75995ebac7737209bbf0b36825c44a4befd81806e35e49fdc36989ed4a0db65f2e44ef92c56252377796fe4f79b8e2849e1dbaa8776dccdf557797cb7b7edd3d73160cde3158d71bab3fe04f6de22b1c2fa93a34bcdd66ccb6f1132c9e65be7b12bd7376776b78f36607536a572f75ced9e7bbc22ed651cf307f72f1ae7c76fdbe492373dd9c33b5da38d9971ade6b8f67ad945c4ab2c9a425184c7ef6cde5796989decd6bdcfb969fac6665eed559f8d936632ec74d39d64bd8859f5c73791bdb385ea277bd6bce64bb2bc75ae65db1bbbde45d33de9add3d66ae7ad7bbe2e6bbf54eb37c4bdeec923bc34f0df6bab36697e8ddd62c9f75d74b5cdeccdee359cb3167ce7a49f315b6d23b78eb78d6accbf462df98a9c1e42dc7ce26d7d23bd9e5cc59b37c1bd13bd685d22434d145ce652d3039061e21f0ec80074f9dd73fb41787bbb8ec5cd23f742fce78d03c1e2f3c50fa926ec6b22ccbd79311fafcbcb9b238021b3323581961f8ba9864391537396f64522fe96211e6ece442967471491f9a37b243f0ff443e27025297775ae673bb355f61b7ebbee5ffa93e1742d823e1bd2635ecee79235930f9c96909bbcfb885a95c968ab9c64e8e5cc2eed69e7b907f9496ec6e92dd7c2a2aa9db580b09de152bb7de5a39933f590db6bddefdff777220c400421dde74e7af5809532575efffcf01084c3e1003c25497774dabdc3fd8e103129ababb7a7675df3aa961576bd8edac8b4c52e78925ec767917c0e7ea68fd4eb3731c63796dac77ffbf0d0fbe3c60e2c1549777ccbe99f0b358f460c90319ff9f4cea796bcdf2231d491d6441be7b8d391c5725b501e80a66fe5ff9393a78feb753772ad3bb399a87e54a0df62af7fc6cb29c4b35d937e6545c3a41583a3264a7cbec747ec7419f3acfb25bf7ede5c5ab12f8f7e2552c979d2eb373212ce7522ce752591cf0fe3fc7c1cb1c4ca9fffccfddfde2c9e4067934cb79abb79ee3aa0de23ccb722eb58199efc924d28bc32c15eb3eb930d5ecc22e0bbb458a45ad0df40673fefc2e4a724e9d9fe3c0d3c9bac8378ed7cd525db19c4b759673a9afcd722e35c7552ceff11bc5722ec552b19c4b553073fd7fd34b7d4e0e9e18c972dec67333965b39613b394cfe77727affbfeb2c6fbafb8d6239cb1a899f8b53e7ff9fc709f3ffdd6539676ac561f2bfb5c6af6ee338c3cfc501837753c7f1acc19fefaeee73e75d5574fe7f27c7b25c2c3eadeebce72cddb72e16b59ce6ced9270df42e4a064e648027030794c0ee915d3229eb27a7952bd14f3f34ebdc4d5dec3bad59feb58f78c5468c7d6b8d8dc45ab1cc9d7c02ee336e6ecd67db77982365ee443a95c4b2cc997d33e316a68a5bd845be99726e2e27fd1b5b329973d307ec35c6f9ff87630d5bb919e0bf6f2f23cbb1f8fbba45bc781567e3a867961b19b93675da24d0e60adecd8d81134bf929f396cb3a963995ff07f2390ce2fc8e098e61dd379373d65d5da8cf619095c340c6ffef9272ac93721c2573e6ec1e775e1ce639367d1ee6ad8e35676ab1d9e0098c6f3df1e7bb9580f1224d3ebb1d8c6f299f1d8c1761c384b3f1ca86f7bb284936b635817e1725b906cfaf41b386b98b925c23fcffbf1a02b3b276eed6f3d66eea78d63267e558c3aefe72dbf9192bb7f68ae1adee6a38ee9b63e9ddca9d5d7379bf2b6735d8ac9186c0de91d6fd3ab9ac87c0ac2ccd72ceee7a007c88def1adb80b7635bcd73d6fb68d35b3ef2996276927e75b7ad7fb566a1e7ac799492e3367a524ad77c99eef99d4ddd5c964dc35fb94b5f46eeefbd59c39f3e686935c8ee72cbd9b7bfc6aae6ceafe64ce3a8675fcc5e1198ed7d6853973d6c9d94bb7aee6fdb957aed449a5a562512b29a9b9136c7e762ef379e66d1b37bb0b6fe6ca9b7a09bb5beb96e7cebbf8ebbe2bd3cc5cbaafeeb1d67cb95777ee2eec36653e73f67d8d4e9d7f711676e379e55d7a2b69693098772e3bb99ca4f5d630e75e33576abd9bbbfbeae49396536fbeaf3b77cde198f7bd6ad86d63a6f919eb78a9e718fe8aa1f48e53713b13ec6abe94f7abb7e65d9bb9751b6b25f1d5dbc2aee6ddf59239738e573d53e99dacb952cbbc8bc39acb71cb65ce9c59786bf8a9bb5b3c6a5955e95dd7717fb75ed23be72ec9931a4ca9679ea5776c2c3bf51276b9522bcdae8ee71e8073379374d73be73eb22473e6cc97f1ace7a7f3dd4ab03bc75aef8450c9fb7daeee2c6fe7fb3e5be7e6cce2eb4abdef8ee2cd384a081c57f5cde515a68ab53acb79156feeaa953b531bb31498cdddfbf3a9bbab391b57f17820f740ec01340da1343da4c1210d0c69eea40121cd07ce582b0190a48bba492b01a09700d04567ac9700d07092d6c5a5ae7594279c8dd7e23fcdadd243034838d027cd9634ccffd745a5a479fffff0736992d8cd59bdb510ffef009aff27cb650dbb7a7597b11130672ccf30476e7986dda25b2c1679dfcc2bde37d3f9a4b5bace7866e578e558ce75cf9b9de1671cd572ac1eb77047c632a7828463f86bdef2b1592c6a158b1d8edd0ef3f98b178b4b1552f8475160c0f954ffe809266c7d61e1050a2f1478218284dc971c5ebebef8be086162429f94904349e0f38fe2f94747f83affa89dff57d165852e83ba90f182ebf280172cd7695c62b5739d5bb76dbcdbea9ba96d63cd9973967e2a16b59c64cebef119fd51a03c81a2777cddaf536fc5f16c5c608577bfb8e670ac5bb7bbec1bfb009b59aee7fe9ca2a3409179cc3efb13289a33b5381c0be9c6987d664581f122accb3eb3bcfcff27939a33b56698771d1760f20bf062f699e5c5e1a7f7dd514f51ba6fade5e4f41543bdef5e9fb49c5aab98e9a5409e67b38b92ec5b81afff5d94a4024b7e1725592c269f68ceb3fae62c879fc8987df6987df6ff8ffa5c0240ecfa666a97396b993bf50c6f5786dd3dc371d4fbeea81d18dfd231fbec4936f9ff5c31fbccc2e254dcde7c365de62cebeeea5c15aeff77c63c40607ea52530be95f4ff4a9f4320c883f12de4fcc5612626ce5be4ee73667cfcbfbcdfbd762db5745b9889f70ec68bec5ce7ced23bee049b3518dfd202786db98d7907e35b483eef9d3e1a3146656996cf1be6f35ee178d59c39efba4e0edbf999e44a9673b873777639cb7becfce29acbf13c73a696deb19cf7fed460efbbe30ec6b734ef7aeb62318ee5ac58e64ec066972fe5cd8ce22b1c5719bfb4fa157f95bbbb4256eecc8ad2f3f17abc5ecfe7b5b158aa2fcec2c5a2d17522914d2412b9b51cb7ecfb6ed769749dc6bed31d4cdebdf395c39aeaca88dc316727e75c9e77ec1beb36e6cc9d9e3b573a5b576b964a7f69ed98f3d67ae5ab765dbd4b26b51cb747b28c4b90c8dd1276dfb67d32bbeebc6b596fdd772c9f35d8db37134bf767d7aceec8dd76bbb4ee593a7e2a167b73cbfb4ae6eb938de52b642b77fd824f2712c99d605a4eb09975913287bde2257289f4da326f6e58e64ee4ccd97885914d305e048c6f21957ec1a75efa059f4933ccd71909c7ae92a7e1b3b96166dfcc20b037f5c4d72dcfccbea7648d759c9d2e5f593eefa63b77de9f9c8ead157f39b28d913ddf935371bbeb34ee64ee746ed94bbf71ecd4b0bb99ab069377d3959d9deaca884472d989e4bb662cb75a773171d979d4fd09a797987d4f158b7ae9498ea5def759c5ec7b0a8acb5773fc663de9a520b0a797f8bb79d613b3ef29bde434cb719633969d4d2a3eef99d9f7d473cb52b27cdcb23af2669cc5e1b84a4911ad2721ec88d77d2afbd6f3befaffa67f595158fbff323e17c6e35fcf5b73365e390bc6b7ba64deb90c3fdf7723bbdc77239d9c6f21593eef95cb4ece229133efcc797316e915bfef46fea322b070bc8690fe3f7ae71f75f2ff363b73fcf67f140499b3304793ac8b3cce4fe45ff9ffe6e7ae80f12d305e44c7b35ecac6225cc42cc959e1c3f349e9f5ce5fbd84dd190cdebaf3a6bcfb3376bbb87c2525e755e8ff7f7cceca575fc22ed80bc79addfcd5f1acfbec2ab566f9dcbacc3ef38e6c168b6f538ebbbc53c66cb118b3cf8e64aaa2f4afe5b85dba4d1dc3da4b1a1f381c83c11b09a6ec7c5d3752e673dc35c3bc39f7e7147623f9abdc30ef5c8ee7fe280f45ccd9f542f2558edbbe91efbb91bccbe52cb26fe63a6f252020a088e2e9e2b578ce3df7a63bf3ad3d77a417cb5d0ecbf1b38d9f5b6e67b7a97cf62eef78bb2465d2d10ffe1f95d3d92b0657eab93f9b7bdeacd6ff288b5c57b0abc6ffd73ed7e5a2bbcda6b5bbcdfffffadc3381ce9fbdbb4dcc95cfcd78dd299fccd95d363515bb739e997adedaa97db05ce6cba52bcf1ae65cc9e527ef723bcc5bceeafd0cd3c57736f7dc64fcdc9ce7ffb91cc34b2adee3779d9fcece72de32c52db223914f99b7c8aea6bbdf75d9d5f436e5b877f0ff3baed44d3e5335e319decc2b245217391baf9abfcacd5c3797e1a786b92ebe1b46beafbb859c9f317376bd9033ef9d2fb713e9e47d4bde4d2e0781bd24c5e22ff8d4f1acf72af3259f6137ca4ffbf8059f4f82c0de13c9e7dde5cace20b09744ae93933f88354f5613cb9c0a08c8b9ef9789ece2b2d389dc73df467ae7f23296afba5ce62a1bdfedcef2be2a16db97674599d21a52753482ccca3a561db1125265c4fa0593c4327702c7554f4e2b57b2845da7731fe971fcffc0ff98124e32b3dbf219def27e2ea9f8cadd2b0da6d42ccbc4e5786592a5ba1487ddb635aa43640ec3ee92ca56b188ace3ca5eece6b25248af0b592c7a219d3dee12f757d245bda48bbce9cec896cb492b57d25da7b1bbcebd845f67d36d6e18b972a7b37bc54e33cf72e5d903cec63092bbf29cd501cb5fe56661eefc3ace7115fbc6532c8793ccbc77e3bcb91ce515bf1c0aec85ad3a0b3fa558ee15bfaf718eabe638c68293c0b11b47b1fc1fa5c381ccc1b691b88ae5cc7573ac2847275459482147215651554724961516d6117934924488d5112413e3917f7403d9eeec7acc3af2792fb733969d46ba9e965beb0a6c76e5d8959def86653e7f1ddfbdc646a8b2c066574992b84ae6f0d2cd623714bba1a23ac7ea47e62cbb50ece6f2736e82ed2bb0d9450681bdd84b8b6fed178a6fcd31fea37260be156b7530781f8963ad2e5fc55558326f3e3b1c47c1eed295add80d6524ea1f8dc397bb77defc47fbfb64e3234f4e2b57d297f1cb99b31cb31c5eba1d7ec26ecbe72dbb4f2e2e6b387661573b9f5b71fcea3986a37ae732cb6ebd84dd1dcbe73df7675377edc3d53b0d6fddd47d73e57e9bf1dc9fabd6fdb9995fdc4b3367d955eaad61cd6ea5deba6f66ebbeafeba5e4a5d45bef963b9ea43be7ade6cdb86bb0edd4f1ac612aad773fb938b3ef290dfed10cb6cc814020100804fe7ebfdfeff7fbfd7e3e9fcfe7f3f97c3e5fafd7ebf57abd5eafa7aaaaaaaaaaaaaabc1eafc7ebf17abc1eafc7ebf17abc1eaf4724128944229148240e87c3e170381c0e8742a15028140a85426130180c0683c16030080402814020100804fe7ebfdfeff7fbfd7e3e9fcfe7f3f97c3e5fafd7ebf57abd5eafa7aaaaaaaaaacae3f1783c1e8fc7e3a94422914824128944e270381c0e87c3e17028140a8542a15028140683c16030180c06834020100804028140e0eff7fbfd7ebfdfefe7f3f97c3e9fcfe7f3f57abd5eafd7ebf57aaaaaaaaaaaaa2a4f250e8541e0cfd7538fbc7b96e36693aa494e8a0adfe5dd9679134bc56177091fd919e64d3896dd2ef82873e66cf56e9ec5e52bb6585c5d99c37cd9e433d5dcf9d215f28fc279f38fbaf947db28253dfa5f04f66a96b3f10af37f1403740d9bff973f1745832991bd6fe7ba5ba6a67ec10c6fd86dbaf2da5d56379f30ef9c75bb62d9a99b7d7bf578aacbb12cef166c6fc57d6be5cca8a7a7e1d369e54af49293731fe15cd682ea2ed2d9b1de3d6fa925ecb2f1ca85fca316f43d6f2133cc65ce84a966b7e91ad9f316c257776bcf596f3cd5ec3a7667ff472ba0e01f9de0dd7f54023511fcbf8a6458ce4995ff5ff13927af13294ea89c383959ca6119f4bc6fa613b9f22fdec6b13cf7d8c9e73d7724979d30b36fa6f2ffb7fa3fca05f63a9dc67ff409b36f26724793219dc9d99b9a9a381b47adac98a23d6f76cffcc83f0ac103adaca49595b47257b198c68158ee3f60707776e5517edac7f0f984a5e24e302d305ea458e472cfc752ad46292c255b4ea626ccd4ca5dbc2b969d5b5d96b2fc81556ce5ae2d67b195bb98c556ee4272342284d9f79414961225bdc4a9b85953497d86f7ec6e66146fba336fdd17d9945b24981ccfdd65f695cb4ee41cbf9d456e9923b790ccd9c9596453765b385ee72f0e3ff5cee166ccc21b6bfee2305fb7b32b9ffd8b9e42e6f8cdfa47cdaceeab7c5e158b2c773a77b1b8229d3d96b91330283876bbdbe50ae94bd865ce48993b873df539eca94958fee54a2159fee5b6c5e2eacebcc99c5d79239dfd1f6de01f65009d613e77b7c3f10a53fda368f872cf1db974fbb339c3bc2b8d4b37eb79e4e55bb21cc3cc358be55bf23e32c755ff28972baf9db3ff0fc3c69b1b36d2f90c0625c585ccb01b5ff1fe6ea927d7b1c751efe65d1ceb1f3d832ef0ffa8fcff6b1bc7f295024fe7fcb492c252f28f8aa1cad221bf172d1bfbff55ac9fcb62f35dde31e7ed6c029b85bb1e53dcc26e02ce3ec39c75f5dc9f58bacf306f2e79d7cc793bf5fb1a8b459970cdd16c83ffb7fa1cd60c5c731ccbeb539e3b1caf5cd6f1ac999ab97cc630d7730c636541f22e77769baeecfce2ad9c8da3503839244efc76c19d8f8989bf7bed4c60b32b6f670a409777479f43a2e4f50f27ad8bc925ecc2ee6e7239a9e7be9d9aaff0ee62b79e6318deab8c84f7bf6379df5efa7df72ae473577ffe877ceeaacc66eadde4b3abf9bb84ddae8dffcff4b92b26ffbfeb7d33f5fc54e6ae6cc4306bd544ce6a82ffdff5addf977bf5ad9796b03b77d96d751b53e91dd8fb3e5bbdea398635ebb2bab3ba8d7537b2bcc967aa269fa93a737697f0d7d98ca3583e3b9fb2cc67988ab9ce1baaa70436aa4a3aef9bbf1c0bb984dd39eee2ac2bcbbccb6ae6bd6dadb6e027336a76d9a7713be7f8edc819e6b2fc5cb3f6bc85c85c099f632573fc66f1a6abc59f5cdb69c5c26e111676b77255efff1ff95c558effd7fadc91167e1705ca1cbf7d8985ddad2750769d33fb7ebbe6f35eddd7f96459cef22eaebbcbd4d2bb397ebbe64d77d64aabdbba2b7776261676b7925878eb64923b9d9ba9932cec6e2535ccbbdc651b6b96cf72ece4b28e35bc7577359739538baf306f5babd59d77933367573676eeca73e72b6cec7c8e95c0545de6ece6535b9e7957f319e535c39b85f9dab990a839aeea54b3db6cc62b97aff852de5a6eebcefd4964e65973778d148b32775b57e65d48b0b9456e270b6f79899cf9fb6e27eb2267deff51043a77f7ccb3c066578e99f3d3f88f9a591e30c3cf78e554dccea9b8592c6cecef9e63ad7fb4cc1cc7587c296f2371acc5df3d67b1dc6dbb3bef0e2761df98d9b9ccd46a6525ec86e2f273def0d2cdda502c557f7797cc67d8457ecd7c096fac2fad7f940c1cbbb3cbecfbcd5ac2eed69eb358797b71ac2ef3b6c35bd6da5ae3174ec2c1642de6ec2e99dd1e3bb91030594bdecc2ce61a3b8ff3669d49b6d6d808ef8a9b1c6b86dd235e5b6699b3bbe47d9f524bd89dbbfb759ce32a99c35e56735c95c40a769b7115dfda7316ec1e61aeb3eb95b5845d16e6572c9f632a396e3e9beed73e2273212c9739d6fb643973cd026337975fe3caa728ada8bef69179cf597cde3287f990584b8a53e15c965ac2b19138d6e2cd0d3fa56698bbabdbb6cf0e53b1f033969ae32ab0d97d5de556c6f2d51cbf592c15a7e2667ded232ce7ebd751e6579dbf2cfc849ae3188baf5bd65ac26eefee113676657ec597307fdfcd8c92f9dc1a3bd6911fa982dddd8c85b09b4f7ded23dc09a60527e96ee7301fc26e96c34ff98acbcff9290553f567877987e328d86a7edd27d4ec74f9cab1b6d6f8859a612eef2bd82b86b7e0247d8e63ac7e84a9d6ee1ee15ccac93b533366c3483d21f5e7753cebcef225bc99ab33d6fc09bb331cafae3ceb67dce4809cd400afe700e0ce63b6bbcc59335797e9a59796fb6db516cbfb533fe326ff569e899472ecd3dbf1766ad711ca0a4b2b2b893eca06edf28e2b6379eeea8eb7eb31c1ee2bf3266ac03f5ac03f3ae6c99f3d337270b9c18d0333e618242ab0b25860b544d1094e42b6b3ccc0cb945b10cb301b1a16a6250c17f61f16f669d8c7c27e80b02780807fdcdffe3fccbf98b0bf858569092320ec3f2c4c4cd89625ecca7356b1e8ecf3ba9dcd38aa585c391baf710b537176cb4b6712de7467f88935f76dc49d5d988a8afb6ed8957aea7dbf2b52e6ceafdd7c777c065322dfbdba700cef957704ad7364dbcd812d51d9f3b5c0df90a84482c9bc192f67386efed41e70f80b3e7d4116e65beb560a3d380e813fa15028e471be89ca56655d2f366e2281bd601019543b38b240a012a8fe7abd55496c793cbedbbd413a471e54591ecb03ee206f7b3f619083230be4ea16fa80be1d04aaca21fbdbe0285c81bd2df4b1c35515b2c0dd9b73dcc3cd639542751deebdf2803c39c7dd06955ba854ae3c2091f780bc38c720abaa3ea0706585be20e72a51deb00bc583826a700cb6ca3d6c83c05515aec3a050b8db816d59dec26095136412cde0c87f41df6ff803aa3de2e6a9c316ce914714aa411f7015b642df8f47ecfd82e89ba3d0c7816b70ef560506894155650a552f0efb64ce5ce5cdb3e4394b5585f2dcdd1c95405f2fd85bb9cf070cee2df4b539fe883e22db036ea050fd2937afdd4c0c8e449eb2edf18041a1f0476c5b22fbc5522de18db5dbed76dd19abc22a2748166573eced5f2f48ecf17c2b4be4ad3d2153a8ce3292b8e6d8db3c1efc6de056aabc212fe8031285171c77706d57bef6843c626fddab4f95e76ec151b9028942deaa6cd996a854873c6470337b5d286fe6facb422b38b642ae6edeaffd71e58f5d83bc378e9553280547a2af65d5f51724f67a40652be4131c7bea6fe511872a572ad735d812dd97a70651098e6bafe71b2a7b9cc8899b0dfed69e9a63905d3991dd43a1d0f703fa844460ef884670dc3ca190d8fbfd866c4be4712290295455558842705c5b625049e4ab2fd812f77048441f38f6549f50d923f6804ae58fb33e21104d731cfeda95070c7225bb370fb806bb0347226ffdf5b64fb8ee55e813aa3f6003c79f92eda92be7c256557940b5f531701c0679405fbb85bb15729f90d7eba13902956d8fd8b66d8fe53f1e5f572432d843cf1cd7ad0a855cd9fe804256095c7f4ca1cae7772f70e443b5e713f27c409f703854f254058e4a25af0db6c196b80a872c0fb82670dcbea1ca03f6360be4adc2e18f33856a3cc32ef2177c227997b7f3a7fe50048e2b91c889431fb1e723f2863f56d853cd1c95411e1bec05f7baee1f71c883dd35422ca2071c83ca16e86b81c4e0f0d70ab76f889639aa2c30b8571e67d76190d8fba94ca10a9cf91025730cfe9444a192e5c4de16f6785c650ad520cf8063bb79acb2e5cadfb055aa6a50c85fe7538b87167014fa8040e2af15f69444e5afa78e39b2ed56893cf527dc40aeb23c1525e0380cfe384fb82a7daab0271cee161573e4ad446290c779aaf00714ae9c880e70dc3c62db12576090e85b5921eb5b12e6f8fbb1ed4f38e40989accad596650a55f6e56e0bcc52d5e1dc6c7d4e2898a31aec29f9fa635976037debda33b2fb6ab7eb321f06ab9c2097e8976350195c87c061500dfa7cedde3d24eae5a8fa78445529fcb19c38142a89bd2ec75f6ffb3890b75c28040a794a950ae5720cf21fdb0bb6dba7f2de500824c62d4cb5baf0bedaed84554e902dbae528f40989c35e702bb96fdd43dff6a9a896e3ea13fa581ee7b53d65bb834360951324161a765c57607048040e89ca95070cfa7c4ca13a6ce727b1cf32ef82e37528cfdd97e5b8f688fc17ec1179bf9e0fc8d5a02f58e5040905cb31281cfa949bddc3a1720dfe80ec6ef7be7ce505ab9c209b5cf1f976c755250ef7aa0cee214b6c893c1569e5e8638143e0e64495fb7e3d220f3285329fa9a2763b96bbce7895c2dac153e5d9e9ab725c95c01eb055d595a7fa884adfda8d4460951324132ac796f7e34ae08fc80a953bb8aac01f15d87115aebd1f71ab5b480c12575fefebf8dbc4f6f7f3f9565e90c80a5b2253a8b2dbe9db791dd7cd7950e5be2ddceb6e7b525dc71edf4a1638fcad3fe18fc7537d4ca1fa6e79c96e676ff83cf284c1f5072412b972b71c180c3285ea2ff844cecd56381f879cef20f0d7b242960854832d53a8b22e923bc166216cdcedc0e0ad15f45539411efb51c90a7bc1e1ee097f41defbb141a14f9e9d4364a48eebc803aaed6e853c5525aabf15b8c23191afb0152c151c7667ec731e7f9bc7b6bd20dbb64355a80a5995171f7bbc9e70fd05833fceb23f21ebf3a93df8b8d9de90f77cca55a96c5b9f0aec3d556d1e59df90e544e070b35cb9aeaa8f387c8f3b281caa41960bd7a072d80a794ca1cac6c5ade3567d3cb87d2d51495cb92a24b23171cab1edf1864a62db530a7b9b07f95679ee71e8e3f57eec4ffdb1c1bd0ed99629547d3de6f1b76ea0cff713fe7ec1613beca9eaf238ecb12d17b66b0b5c77dbaa9c29549db1ccf288edd1b783ed56795c55b63fa22aec3185eaeb6cba4876a80af9b1a704b66d2bfc0d796f6f4efcc573afe7833dfe58b607040a5522f7097bdc07640a551deb9103595e901864b74a24b63ee2ca6476a11a541e7d429fb2257276f5b542e2060e994295c3f1bb22e3662c3bd51eb0ca09b2b88f429f6f73951854f6d6bdfe822a53a8aaaa2cd5a57e729bd4218f3cc8067b2c511924aa41df70f77a41a41c95c31f91d8f311832b50d9fe7eca28c7d6a76c7b6a3bf471b51754894328359ebc70d2840513184b8e405ebb0a896b50e53f25cf27f4058528390ab9706587c11f301814b63c56650ad5b9ef16a9aa416012e773e61d29cf4876c72f0bade350c9d72067792ab1d7eb29f7daec6e1309f357a88239e315a8b2c0e70ead1d4ae073478f671d95ad4a6c7f4325af47e4f988c32153a80297b08e9c2bb76fe5ad3d3e1c0a5bce364172dcbe1638e441def25608ecad5f1cfeedd01ab2836ab793e37977ac1d513ba8766819d931c34f66d6eaee765de6b373b37bb793f9ec06796a9513243ac0d5715d37fb637f3c96e50583abb28d6724af17c4ea1854f2d6208fc783aa4f18fc6d962954959c0daa4e55478e42e18f08ec11876cdbeb71a1b017ec4919392a853d624ff913b2bc550a5b5f90295461fe225998237f3d2010aac891c779bc1f70c8aa3de1567fc075337f4b2a5bbe2a27482522c7a192c82a571f70b8b62d4f29547f501d85c05eab0a59b5a70cf67cc4df902954bb601729b73d753875dc2c5712b9d027f4adab700db64d396e9170ec226117f96eb719c3606fec44f2793fdfddc57dbf25438e7cb8aebe9ed2075cd71d6c872c53a8227bbd2194d431f85bd5561db6bf5e10d81b1279468ec7a1aae4ab8f381c12d721f0f7e3f5841c83c3cd894256481c7260cbfa7a51c7cdfe7ebea150b9813f75c85b2153a82e615776b713a83e411d79ab92e5be2090e86385ed4fed31852a7f973072a882bdf15597da69494975a95daf179535c449912eb503027b554e90291ce371f5b1ac72b33cdfcfb7fa56de8f2954df677387d6901db294dcbecf23ea90dd6e49654b1dd2a5763b75b9dbed76c42a27c8af204795e8fbed215019e409f98f2864994215d9811c7f2b90edf1d69eaadc3d1f5019640a5565335e91f2e6b0fb22d5a5dae3a9429e8ebc965d396fb887ab10b895be4dfc716c89c160abfa802cbbfe382b5c814e47e10eaaecb0ed11852c57d59e509efbd1c75139e4b5eb5683c01e71150295be61f1b8aa5ca9f2d6075489c1df70a8dced76bd9f3c3b8d108fc33d140e85ac6fd80b06371b0432852a4f558774a99fbaec01e7fe9489554e903e86c756e8f3fd76af25027bac90270c7ac546a4088fc335b87fbb27ec11794f1db63ef78b4fc9dce94cd27cc23e29c1e3afb7127b3c60dbe31189c29e705537f048e4f594bd9518e46adb5b5560eb743e7fc7fd1bb6c1601048dc9cc8fbf11f53a87e712652e65ef18b5c3e959c05aa329f8973b3f5f9f01d59225f79dcd71b2a3727027dbfe1f2a9e4c4df93de71d8fe7a2cdbb240a292f3943e95295477680dd9317ceed032b20309bb48672cb3be9e3c3b7d44f518f4b53e15d8aebf55d80b6e9eca14aa432ec751f256f25383554e9042de714814ae4a1ebb879bf77a6bafe753834175e55d544d47a2aaf2883d1ee4c1e12a14b6edeed8530e7d449617dc3e9627f4f13653a8ca9bb9f2d4254c475f90b7836b2bf4a94a2590ff804ca12acf1d49dca13564079f5d7949df4be667738714d60e1eb0ca0932c9d271250a7ddca714b2bea192d8b640a65045fad4604f80a32a04aac4a02ae4c26150c863954ca10a9c9bad8f478f23900df2df4fe511892b070e378f2954913d3538375b5f50e9186c778f0379bd20905dd796b74ca1caec4f27528edba06a24e9b8952d1128e46da0903385eaecbecece53391bc33fa0aa1a0338028540a590b70a954ade2adc6acb14aa5eb1bc44b66a8fc791edf9d855191cb22d10c8b6401e53a8b2f046c6acda13eed01ab2c3b8236a87d60e2d233b56aec46b63119b00705483c255e59c731ffb5bb90fc8c2ae17fc8c61e4502dee38aabfd5a7aebc5e8fb7aa2acb03fa76680dd9d1f33de5b805dbafb3bb4276bbb9d9ee765c8ed71dbcde73c7eb6cba3bb48cec40f680cea6eb6b3e61dfdc6c7d4a1dc756fdf9388fa86e5f8fedf5d62053a80e5521d2f137e43c20712b7b4a212fa8f6784ca13a375be41276b7885c8ed75f951324efe8e8db7b555ba1f0a7648140a0f2c714aa48a12a045639410e75338e912f2b2391b71c327f59783391fd2923913470a848ceb471a39d9f481bc21a3468f474ccc021e317bc11a3db80b1b56ee5fbc6728f17492ed4005aa8c8787682c9ab0e165ad7633972fee23d727a85928acd651a46cb1945ac0da265fccec0f16e6001d8be7633470d89a60e7b2af22bf69a914bd865f6cdc431eb21c95424ef3362c82f5e2355915c6e6da0c8f98be3789c05b60fd2a0bcb96199ed83188c881e05192a30b2f0b9639ccf3dbf76103d0a3284195f881caa2ec82a4251a6ed71722da2e2e0d654999a1d92c283290e1d3a64e8ff533e3632485a38f48b81890e3fe6d088d2dad101029400d224291005f18b02353a60e4e8259087961013c1a1295e68e2d0a14353246122c36dc0e3e9504a33c2450138d42881c715c42609954bcf0e955aa022d504433ce0f63c3884c4a02187a6885ae2d0a14352b4c96056a302373b6aec6430e8419b74da804b98d2e4c43c45ea000c362c145378e1d5441275747083c505273d7847046b80896103e58ee802840d649321483d868c50058a8c06129c5238828521472af09039428700381840c2eb50e7802f4e96044511ac01560008459d0a237008d3258b06bb618b168050b3c30024d4480342103681f8bc30a5c00c00302043024ca0d46c49416545d01c26a6c03102440d5236249056c489a22dc2c60f081011a58d0b47287892010b73fc28113a13c8490f0c3190c8a4e022cdd0c1716951b32980b5c18c19b80a01b00cb233059818982668d22ee0c29d1b30b0a0c1e030cfb0a6c956409fad2a118ef0136307127a98c162a5ca0b6b267042c10a1c88683023c5952d52f2dc00abb27a63a5d00766e0f4986246ee49c63049481e0294c21e5402473fbe90a085cb53139328164069000617403481bc60bd145d002a64e5430e65981318d51883254c6ec755185bcb7300cb528f2490b27a5e2ca06100a315007d791e4d90514873ad158c31f6c415980b9fab180ce840850828082d40c0c409a5810c5e6a2810c50d92548e3d16c4b027b602a02f5c85b86e351c91fce0b203160356e83e46f872d32447062c220401c20e1b86901982ca162e2c4b969eef49f17b5c9b00febfe85012b5a91b6e88a0c921dd4c06170bc85a443202bc835a0063068a8e151818a24c1248a469ead09001c20c0b3fb46900ecc90b9d190a302d8b088301020f70c1530010435e230a744003ae2b880b6e30c88e5082871c3f1bbf185234501d11c42c413450a4c69a0ea28abcb181f52ad225092f2c4658f26250c3441c2676e07073c8909cac43873e68e306fd4f3fbd028089accf31b1fb1c13323e37a7c8e7e600f9dc1ce0e7e624fdff0a1c09579f2301ea7324043f4742d3e748d09fd372c0ffdf8a56c0f1f33938327c0ece9dcfc1a1e073700af81c1c2b379d2e887e5d10d9eb8004fa1c04423e0701f07310207d0e82d90d5d13faba9d12afdbf579dd0e85d7ed3278dd4e81d7edb4bc6eb7f5badd92d7eda25eb7e3bd6eb7c3a8c50c182d64b2dbcce8661493d96269ac96d26a44b4235577a462fdbffaafea10c4e774b0e1733ae8f99c0e743ea7039bcfe9b0800ef08a182c523407bf9f83919f83ad3e070bf95c11513e070f3f072f7d0ed69f835d7c0e96fd7f2d57a484f83925eae79424fdbf8a9b718afbb929499f738590cac12306d1e5f33957cce75cabcfb9bccfb9b4cf31ff7c8e49c2e7986d3ec7e4f2392691cf317b6811f1392d40afe3d1d28ec8f9dc91043e7704cbe78e243f7764c8e78e30fd7f0b1833a6567c6ec8149f1bb2c3e786b4f0b9211d7c6e88059f1b82e6734306f8dc90e6e786687d6ec8138b6f61640306113d9f23a2c1e7884cf03922097c8e0898cf11b9f23922fd7344929f2392e473448c9f23c2f43922373e47c4f6392a273e4715e87354377c8eea84cf51d1f91c95043a70f91cd598cf517d7d8e6af9ff37dec8084794cbbd70d1c205958ecf51cd3e3775c4e7a680f8dc03457cee013f9f836086e3bf68c5140a9f9baaf3b9a9359f9b3af3b9a9309f9b923f37b5fcdc94d5e7a6809f9bcaf1462b886830c14bb74fe998bc69ae5fbba97f3869d86df2e68699e239969d2bd696b3082fddbe743b13139e2e3aa18bba2578fe75714999d7c52550fe7571c90e5d5412e85f1795d4717a9d9259179538bd2e26c9f349c6fceb62122d5d4c62e375512b902e42799d5617ad29a4968cd7c5ac3fbaa8cb52f3af8bbaac25a40e4bd0eb22569cd7451dd6fbaf8b58ff48c2209171e54717bbeeaa82d7c5ab5777c5fbd7459d15209dd557fb3a2bdb7f951a5d15ef481edd912b5677a4a88f2e1a496384a98b4678bad875454ef87f5d9132bac8beaec80e228274914898d711b92262e35f17df50b5d981cdce66db3e955d179f4ed8d5ec868ad967965e7292e37747158bb8f7ddac1b2b2916914898b3accb44bace8d74f6cebab192a898e5723c178b5a73384ea3feffbb55e75249c066770897e3b92fdd967d66fda341000ae21f05e21f05f4c33fea430ffddf68e3bbeeb0990083ab1676f208ff1f0562e6895599011eb8f3ff280145e45092674e6efe1fbdf180d284a2618cd1ffa347fc009138f43df5ffd11c71272344091d0dfc3f3ae5460a47b3a4433ffc3ffa430a5bc050108193abff4f8d1c81004140000434f1ffb11764f8103a83e64e0cff4f6b400127d0198a8682fc7f0a688903ac4871e607e1ffcb1c48d61860b630858747168b48bee51ad9f2bee25bae913966f7d61b1b67f8005d10a7cfe1cf3fda07dde11fd5e11ff583e6f08fe2f08fdef08ff6d9401ef86739ef4c4c4b1d90a6ff2ec3f1ffabf0ff41e89eb83c7de90df5288eff27fedfc9eb7e48e1dccd1f81501b6aa0618627963b9dae3cf762b36f2fa77f5486640c280c619ec9301784b91206cdffba4b6a1676a3247bf289e63d89de2db1dc4d52e9ddbcb91c47edb2e6cd4c722aeeee277815d2186993ff47beae989bf7d2edda28aff2e2f0cc812b3094a5a51f4f3fb4d217eb26cd2d3752c492ade6961bd15a6b184a15fdc5ba48be6439726bdd32cd46bbd1882bfc70d2026898bf33167e3c6998bfc8b9e52f927de3d913311dfcbc2c4dcdc6dc59fde387564a82f9bb5be5aee4e9a7998c1faf0be2f97fcec6b04ea36aa6f6e55dfff8a1777cc9723564feffc9eb823236869b68514519af8c51da497fb12eead401e72eefc0e419e64dcedd6ce25c9e954d66b8503e0ef0e0a179fac791fe190f1e3cf48f99f065765e06e765605e1625839219653f9f13b31c7731aed3c8798b8c6724ccdff9eb89027b81743d40bd135e175d2f5ea58f743ceb7f3486e64bd7ebf2dfbb6275bda4ffeffdb33ab5ceffeed5a95f3bf5ea5935e95fc7738285378fcfffeb7871fe85f0bab0bc1dba263e4a2c5f773c49b3f2668263b8ef1dfc8c5bddf4461baf845419b18638dd59c3ba7766df5344fe45a38649900bbb4c744c6afefb1424af5bda2080d72d8dd13131615a62927d97774bad6e39bb2a3771280c027fbe9eca739dc69dd2deda49fcc9a5e39933b576c936d602a8f97f25af1380c8ef9231d32be96ee712e7ad66aeee52d2c8bafb8a73a95def4ef7753637f74a269dcda7526f3df3659ca57733ccbb4e3addb96f2d7397e9434900ed43f7d002e824fd433bdd1939f3d78792d39d93d677afc81f5acffc6d6a7297e6fe9493c9a4de39dd194ca997949ceeac639809ec95f7eb36ddaeb7869f32d30cef3599d4f0e6cd0ec7ee92cb1a8e9deeacf7d6b0bb6765ace35927396f91c9648ce47465b70b29999cddf7d9d49cb7daa8396f91ef8e5b988ab79cb748fe3add997329ce5b24974a072180839b357c2267977d6e64d692de390c3f996b8faf7632ef3a66359777b3bb4bc9a7e1d37df7735eb7e66d0cc699b3defca877f376b7de773fb5743a44781d689ceeecd4e998faff9f753a7457a155874467a7430a3332754857ffbf9bbd0e2988d3d5d221d5f8df75a7ab15a53b8ac3a404c7ee3cc7f0d296b9ee499acf7b5eba4a962f59fe5ef1753bb37660513b3896dd55c3eed7d652027bf9bc5d96379b6ed2fc74aebb78e65a294933d7e796826377c682dd23bba5bdba6dcc72d9ed9cf5d271d74b49ddc65beb56eacee3250bc3b19697965ba34c2598410009c749de937c7e3a9bf1da9deeccb9d4aeef60b7f777f72899b371b128c4751a77b3eb855cbbcb5ce244ce712cef582ef766ebea6472fee248e4d76e22bbab94948cd2c839ee72f275dddb9de7aff7d95ae99d122c3f6756decc1ddfb949adbbd45f77b730677a75a52d39f69a39dcf7caee588ee124e7fbee75f75de73bf77ddda686dd27bde4c453e2dc4dcd9b742ebefe351c6ba81d7ff22797cc5b396ef9933f912c975b0bb903837b538e5b993be7b86a337b323977d8ddcbad7be7302c3367de54a2bf6666df5341604fd9635da44e5788f63a9d1d9d8e039d0e835feaf26eb853773c26269d8e458ed0ae73597367bc760dbbc8adcdbdb6365f92b5f2ae15c9f2952b61390b3f63a84eb5f9d4fff79917b1eadde96ab1b05b040caacfdd35d2f7bc85f4ae74e5b9bb42b4e6f885b991febe5fbcca08066564a9be785555dcc254ae90ee1557712e35c76fd6968f2c15cb762a39beea5eb1bcf663e75cea7de3a8a8584ae69df7f97995055331fb9ee2afd395b5be7855df5832775f27979abf7815e7527c06839ae3778edfab398eb17abe24b11695769d5b2765cebeee134af71dec3663b96bc7ec2eec4ae9dd1cc35a8edd3e3fe3e7bb6ade8c8f148b5a5e31acbb85713db721d8eb82cef6c2ffbb4f4e604a0dc7cf989d5dbdb4e5a751cbb194de2d775cefe4d84b83bdef527ec64df4aef7e7bce5ed746edda347ebb2babbf2f6e25040585788defd1fd102c031ac643997f6d1e5ddcc3bb2b70baa3b5e1cdad4cb71c1843db119f4c46c405b48590ec6b7901b9947272be0ff77597c8e9548b13a1993ef3d5e27d3ba189fffdf81bdac6bd4c5e4ecb8d3ca953c3dfd82cf18897c7a72e273acc4e92b86e273dc8564f953b1a8e5e4f41543a56574a9738ebb746910015e97da74689e7f1d8a4687be54fd6b1f51fadacd24fdf48aa734ecca71db3b9fe32e2359b07b64d7d44b73fc3a61572b2593495a4acf305f39d60e49236996cb9cd573e7f37ef54e29b995d49cc919ebbef5d24ed29ae5c92249ad79d3d53aee94c066679383cdc95533693599a4936b52cb7ce61a6c76e5a792e9a5e767acb9fc5cbaef76bb5c79ced2bbce953b95e7369fb0e6ccd7f9e44d2ffda5d4df77696b384eea73fcf6b98db5573cb5650e26f32d1fb7565756c67d33f59679ecf61e3bc1deb9ef77b75cea7a8937dd198ec1e0fef2189e79d61cbf4e2dc75a8379c55de6fd89155fc9bbed52ea309f794f72ca7c8e952825b15ceff4d29e37dbd5c6ac1cafb0bbe7d8d965178c6fe92ef3a6bc5bcdf22df32cadb72cc76d97e356efbad64bd8d558f195ee5c0f89d2bc7977f66825c48ae54bc4f9977dc92d0185cfb19258d112cfeaa5e55319f5ffc2cf2981e775ea0413979d4ab0af8490a71d2921fbe41cbf5949c4f9ff1d13ec36cd7ae55338d6ac8f9e793726f1ebcd3b091b1280b4d6ec5622c1c1ff3b6d20c1fc9ff94002470e0917ffafe7f8edcd23de34750cffcf0cf8d9d4116c9d2e7f84f1ff8bcf701cb5845d78e966cd5e74d7e55db1d2c8797f16627eae900c99cffb9ddd24dd9dd8cd7ce258eeba6f2f23c27ea764049337e2f7ff4fa8881c2134ffcfc2cde752de9ad0d78e90fe577296b3830a2907a1f967b9bceaa564f28b9f1b74a514cf01a471a8f40e4de5b1a00539c5903146c6664802000a6312004040341e0f47e421b974d7d4da061400046fba6e904c1b89b3248a510a21848c31600000600000309800900030defe3485d84be9821e045ce7e90e7b25461946188ebaf1b41f744855d82988fd998f980e64ae4e37f0df9f66117b6a3bd131dba971c3ca628320038b6f3e465a234c73e87d19a9474263f130b47e6b243c7e23ccb2e8d3c6d48ca304b18c1801131711145a4b2b20060b32760106d2c057ba022f4af236d14e75dec10b177a3ad7741b7fdcced411be2ef4e44cbff2b34d105947eead8b5d7bd1e2aba37c68d6a83de811a5f95c1eec9685b2fc5b613a5aeceefb8090ec6b2cc24c09d4ee9fcd70af270ea262505cb209e1eea70cc1f5404e5d4872aea83ba4896f95baa62366be6eb23e453f3276f46c3ece48f1582a9b2dd353bd134b9d26b3fc5320eed66089e56356e8a6748aefacb4c40d63f8940aa552a6cbf4fd9253415138425568299030a2953885463aad8c2331152b1a2fe1c4a18e93ad727183376fac5c21dba5ff3b5ab983e6de86358d4a202154d7a357c9551f895f1d9c0e00c6069a405a4eece0d52b790477293c74b32e9bb52a8c413126562180df60290719e95290ef14b3c377a09d87ad15750351b66a4d7a7113617207f36a1d398ddc3db4ba9243b87a3b9f637c6260fd2edfcf13d151750320ca2d5bda13145001421c25633a205fad153e029e702db348871b5ab0c44abd9d6faeca538f499e5cf207f4e62ef523971ccdafa9291376290c542d99114b1ab7784b5e7f5487c0436a381ce7a941cec28597f54e5fa47a884208ec20e584d78eede4ef6194962e9d0a8f029b6e46eeeccc54a6145f83b741dd0ad5efdb144877f0e3db4c3c1b677cacaef01874d8ddab85a3020e33977685c3dffb64a9316a9d75693a2f68f1bd3d17d873f5a79e8c32cd24cf91c08c2f0d2c39c984db9d21a83bfdbab918614946a22db2254270a9f3a945cba1e6b04389b58595dabb9d65599d6bf612dd3d208e902eb235cc02d192901d94ec6f92a90912c4fee68554a13f084743add92abd1d13a618c509d5ddf41981f48d4d276e82b5fbbe5441b50acddc3e0a3eb072772ad110029a2d2741f2d5b85e0d47a4881fd45e5699691f08a253efc94af4e52784f01c2f776e29aa1a283f07b8240c3814d17458a8cc0a075d983d891064778286427166f939450cf42673f22522ca7691e5da14a7b95966a581ede366c36d955a1cd9c660adf512c17175c0629ecc8fd9c74541d4ae1a28169f0e056757f72c76ddd08bb269a386f5059ebe3186b7dc3dd9786defabaff94e9c5d35a25860b09de30cf95f1815108f8624b0d8a104cfa3dd5364cd2e7b64c7b80e5098a152fe42d12efa4354bda98a61e617b1547dceaaf878c2331386e3809fee1ba282a1cd2007832b0e0706e797f5bfb26f1edf1b0d98aeab6d86d26eb7aebe3382428618c3a791db7c4a9630ea757ef81acb601d029b933086092a84429a1a6cd372628f16d5550188ef1b6b71dacb1463b18ec47f7a81ba5af228aff4768d8a130514994cb91eed76d545873f76c319c06a60c196c46b731abe982f8b9023a0583c725d38cd60666e7552077938d106e042bab4d30db2621414c2c8a76fc9abd505774a6569198f0affb3d745ee6260dd6dacabc62bfca970f669d3bd4a115120c1e68cf92f3a5a31fe50fed67cbd6845dfeeb12ebae2614131a49b9ee9d681b942b232cbd7c9f914c6bf2e9faa276d3b2b163a577d78f77110e5d662607f2fb98b62e1cc3a78ba400debebd650cf4086eec9aff538eb3787fd46eedfad373402e1609cea225f47b01c5e117a3c8cc3a75b5a02e0fe596648ff290b60ef0b4a85cf607f07b39ae0a15e1a66e880f0d0b5eb90df27308e69e79baaa1c626a588b8d6f65b58a29e467df7fc1867136d57172a35135df18aad84314f444531db889560624c37c3b8bd14863cd6df4d03e8455d6aed011079a66ee9dd62909159953f57b5adcf9d21ab42749b94ea817bee0be938eb378dc572b057efe0c6b03657b37090fa6d06e881c4c766c4dc0dba2aa4b988a7cd027decde17adf77f2e5e4f87a0bceb22a7ef786c4db0895884fe87d7d2c2fc36aba5938b0a6a4f038081d8741b61107b5ca75eca95fc941cbc6cb0443c571311ee9271d6002e9bcd00804f10773a1cccf3ac678b85a9875886f47dde041bbc750b03f16a96fe02d9d6db2b8e21c78e48bb39d37d58c60413c5a0b7e54a9f9b9755f9533430ba1e15edc70f7826ae47dc066625c13fa0be3f5ed373f57a71dc64ee1fee510847eeb02e3b529e9ef9c1dbb9da40828c9f21d03176319c6ffce52fbe4724edc2514044553ae0453012e9cf79be4726ac8e117064d00b52b8caa93b57174a7acf55fe28c08dd063f97c630753efec1a5b5e2b6e803fefb060e90fb27b50205d1a796498cf55c874ceb9680fc927520afcd308d1d764a3af8196f4495f8202b76bdbd8105a3f2106c7af079de4d3dfd01e1e05d7f0077b82fc1a6ffa22a0a46ff19ebee6d357026b7ca74f77ffbd88f40e55d60721921dab53f0bd66b14477fdb5ad033d5cd65f67705169ceaf0efffbe1d7498684bbe705813ec695230282b79458b58c3c7ebc0fcc27a1d86f6128fcdf5625b773bd67d8c2bf0afe2428174d2bb640c0ebed93056737df39a286d2db0504c6b4d4ec23a13e06119ffbeffd0e978803fe94744067661439581bfef1f641783cec1a326386bb36645fd1e44b855e01cd1d38f3c7f5933bb7d2ec82e7c63cfe872171a1bf653f5ae64f8b5b3609ff2f4d4010743f4c6216c9907ae8abcace35a6f40bc5fe4a722d103335398b79ff8dffd10de9582a7cd2c9035fad86d0ea37887542e0076e80c2b7eb3748a581bef21b1afa66149f921ad6f98ffac3771f94bfa207a52f2977580176ec7c4cc82c3e318f335145d78fe77f8586457e36b79eff75ce780846563cff3ab33e1171a8d21affde08e07f209c0daa4b6f1710cdd959c59b69dd594d757a49b417b082075781926295d7c81f48a0eee3327b3033508b4097dc1b4743ecdc1daa1cbc65c67d5a575a1843ddf882db29a389af6c24993302a6086cc7a7873faa24d84723f83c8f1f84c7c6ef2770532bcafbcad5ea72b59948fdd5bbc5249558de91bb503258ef1eee618b723b1875b41310634a8e0b6ca1ef9769d44912eaf7f5d6f839f86625979c3509e70c33a02438f1ecbdd1557c0301e4d19028776f428c4a6a531b30df504ee900e181b314b811c5edba0e8d7ff11e7392410013ea035ef7bdfcff6e5b2549c1f57df06644d9280101aa53374990b7c856d83d9dbb0d01df41577a9f1e5acbe8739de5336ae835b4e8e323b8d17884826c089a6e05ce173cf604d1d78ab4fb5076f383e4d6f2337df00240c1525740b89d0ce03fb6c571f1d4f035fef13c23bf24deebb5a44163d8dafec6d3138db9ee7ae54bd6e6b2d1bf62eae66ce48ad0b3f4b652facc7d756a9357eaa26871dca1beeb220277921efb8b73f453beb1af45531c869ded1cfc68d5f20afc1cf99e5ae0067ea0e429b0f88cdda7b7e3f2156c8b3eaa7b9afc21c13a7e39e8898bb020ca9fe4624e7339eaf0e386c8bec0aaf30bc8bfa8573673446fc1de06c2839ae574127f2388f78a7fcc56f37b91fb79c67e823c95ce0eaf34ec17b26d3ac7abd9e2ee1df19f6bfc5a087abf920f64f1e697a568b0caef1e90a7f32ee41cd260e5e12e3b6215a9481ccfb58578413876b71033c5d7616d45abacbd0c49f15acce62dc50a22e42f0173dcfebf45ac21a78fe926fa562f57beb682a7900039a456b9aac8aec46df3fddc3cd183aedb1bb05d1eb320f2ce2ae2c892aa8b623e2fc65d726a5ddf7deb42e2bf65fde2bf44d16dd0773fb306f2608b14cc0509c9a4e7bc2856cda319ec364411c70e16e5fb238939dc694b4098b5182e1ed32c831086051982530ce955b0b81093e81b96c7d9e3202c61ebd683ab173a738e56ac99c9907299f63e853587ce827639a754fe15a5120d13741cd0a0cfa7c9f59706c57bd710b11274746a7980509d5452bb09d08c63a3fb788e59a730737a6c5ebc72e1c9c03fe10e210c50d6ba689c724255e644e8e36bcf401c4db07b3d5fec4b665e5960163365c3a9984fff3410dc2987fed03a367ed7e077f8c4bf3c96f2754b563d2ffebcee0793f9319e43cc01e310f17f8aed7f5e2c87c5549afcc9b709393b799d8832ddd339e78a329c80e62288a4a1f09dd34bad01da63787b86e99f549b91417a93aa813999c06cb2812b4045caf7099e523cb87f7b904504b887cf93db0af299a08aebf24283b57e5163cabb16adb3a5402db35d0e026f5879e50316d6f185e728794102f69e780fe963b65c28b71d26446204c7d5aef0f3eb11403c32f1758744e1918fe52ddece75dffa27ffdb43959912b12a6ee4beb29e1b681e76fc5bda6eae2c37dc5edd8820d0026d417f0d0ec35d13b1e4083fa4de23774e6e737f00129294cb6a18d62133db73b2bb21799a2ca4de3d295d8fafc41ce2cb4fdbadf623e8fe5c4fd65227cd4ec291c95d1482deaf8521989a0dd2b5c9267318323fd30899e9701e5612c4a557f142f4dd7239e6336c8b7624fabbc8336c24a9d05d14585fa4a8f037c3da7852378162834dd17b1354e2119b729609b7cfae38c435f18747c0d78ae78c97071afc6c4efe60f1224f792780b9e481aaaf76cc293e48eebed3b8c190d77a3a6d49d1bf4ddb8a18737c7a7c9d1c124c9815270610a7e4b2f3e8a9c49b0f3d7064743c96fa78df2910dd17e6cd8f63b394e4680d6682724362611e3f893de1c177972504732e8659b7e6f2cfa54513cb705daa3a395f0ffa0bd4c70e1c8d077dbf9ab500057eaa7797590caf479c92df94dd5c3cc5f5c7cabc6eaf84f14003454144b31e7e32ef0d5276a38d1538e33438b17f6a67c65e6feca1998ffbd621f62c87b438a5c73ff137f419f873e20de8e7d6f87f3ba8de45d9e9450a712b62bf5cea0c440e2b3f4f39d199951579690a6313f83e482e07d7cea719e4886043d621f454a252e01246e0b8db56da5e5910c17f32f00a72128ef9f9a12cf7a25131268dcd88bde07fe253d72b04ed3c8808f2f9c3ead09ac421b6c5eee63c7f3a6881ee3983a5ecda2dcaeb1e178b450fd704c4d050f7c65bff30c253c45d7d0faf7a322dce34c887f31cedd2eda3c0b955586cd81dddf5486c091b0c22792ee0b217fdcfd9ecf770d72dffc058850a4d336bc55e581dcbb8f63ade349e2abef1dc6c048a657aaa020e2b3ce59cefe1bf405e628ccc0b8c3f7bd8ae9577bd79e21f7d57517d4be1460f8977902ec56583d8fe487a81fcb2e7e7b4e1b8879096154fb13bf3f7d6e1970bc6dff0d1db392d6b9be08c05ae0d0dbd87512cf459822390ff13ff24c40bbae34ab5cd6376534e861f23c3b22c731963c9b391019725c557eb86e564a310db057cecc07265418a3ba5c108e01109b94a2c9c40d602a41f423d8e6902afe00ffca9357a08ce749f38bb6e8f5ad1a547781030dc6924fbb0e7a558268d45c040e25b1b44becf1cd8d908f532d815d0d277c71aacb44d09c65e0c22fdbbe694d81246df07143d8b9f8b7783c4dc554b90f6ff08607e98439126cb2d9e46d767704e2eb8d9c4421f38144b4e2e6665bc56c8a09d70b473da8c07b723f3be41f08d1aae749f274fd174eab2294287883e7e38f42f5e861146302797802ebf00368a180dbca050f4df6971659bc66815fa51f8a286afe9d541fff4369455773d5dd4c264c3d9d75036b0dc32c3a2d119a142836008fd879f45573a86ebdd3ae9fe0120e27fb95f63907671faca175a926b0b08c351b9031f26be90d8d4e7b3dd99941a232fedbae9e1a278113246860cbb30cb8d0eca8556d06d9343a8547f0c18dd8699331c22c632535e0bcb6d9227dac2dd8538462d743605c6d9588a6ac641d1bd52a16cfd8a7b03c71149d74025c0b42ffe5c85371aafc7e8c896353a6a15b34ae4cfce8f7ef47028d6c96990ef6dd1e88f5ba9e1c4303977a206586a9b1d4d876684b623d941e351d467f2e02659bbf3e59a96a36fe30fc584c68b826c0514380db300aeb8cb97cf020e30a8edde17a589e83262d4fe68aec7d5e48b787ebb3e87098164a9fc2784020d880cd029d5e303e109282701aee010af292561241ddf20d7278dd3ac7525793e74178dfbfd7c72d6276d31c9b3e1667cb94b793d0797fa6391924adcf1e45b081ab66d499f390f49f4d0147eff7f969d3de4724d2e3f6fb734ff0801518619f1bba1fd9d1353d71443ce1ed3f5fd4e5003b50627bd2a92f52779c48998441b75dca25f3689c67a992bd99e4aa1113daf944242168ad98d35cc17bdae3a328d0987a15b239516ee44e585be2501446e6ec98e9cd40564a4ece27d03f63bed45c2d34ecb63cedb5672629fa792013aa121193234b6d9c8c230441ac9c26fbcbba48e47472609683a5e64188493d2a0a9c4e29c0eff6b816657ea945e7cac76f9f04947f3414050e0fef0e00d1ca32e70f8c2bca1b49eb6cea8d0baad9886db5677fa83df5dee48087fc38ae19d19dc4ab1e086969443a5564b538fffb5348dea1a2bf8875f6d8a5f8369eac3687ba12f7642038a831f1338cfbc93f9a0c8453becc5c02c5c4e4acb08ade9ed39ac82c5dab045c5d7d32162d0dead48f0bd356e21f01e9d35bca006216c3fe6ab7bcd296b2507455275cbc2f0ea816621c37006df8f714109b98c01a961f8e6442841e76c1b83d5380a88b24f578ae872f55fd7b1aed7f1700c1ab83fb23f60bd3eae6d6e3e22f5b7113c3e76b9e31b5a32afd3b8c75539e63d01be648369c35bd1fcb26773be09e5addad4f60f82b58967678b045dfd4af78466af0efb9cd4d003ecfd6adf9c4ef0d110050cf5628f24377c36474fea96ee9fb13a58ed2bf54813d63343057a1421f7f236e98fc0c74d3f52c0d09f5e88b5f60262dd00015f54c218978210f63ef6c403897bf2111734e805d6a32a73cc585787c5cff716cb0d054aa41c91a8d4a76c7ed9543185d98421d9727aa0fde4e37a50e388161592db2fa9a6f6ccc6a7def085b64d6a031eac6d62f6c285bf18f98be82d3c15fd5afc15de7a6af18e6927651a5aa52b0501147ba9ffdcb6f2057e57c9ac834f82968a8a775031fca1e8e36803d347044614fda8c25f338be01c8e642ea33a63c8df92885cb92644b730738e3d8418c89ebe04541a33fd35683f60e1e7a4878d102dfd0384c079c8d0de21b7593c7638eedb44702b197d9f425c78d451bb08f818c3ab183a2596afd192b0ccf022300e5f14f2ea91aac39675960f11ef535026390a91553328fdaa0d086b455c817c76776c6902964cac86f1eac7c0abfd67ccb9d735f6456abd2fab96388410cc6dc27a20a391414da596a04ce0c236d84811e4c0bea314fc17508fb0ea31ed0b28d0d9360c49b1c4122321b13dfcb648421a270edc946ef3e7fc93fdeb04d6d2276aac52f43d2e2c05fe246c88072d7be8be81842dd49208eebe1c9291014d690d8ff7031a1481939e7e07f045ee6969d37f9816a98a207faf1364c9e5104c078b0d80f37656d9e5ef5772941d10623a9e0c405f1a7beb723588261eafe0ca3ae8a433bd954170571a8941b4d55550d349e39ac0e86ba74600a8c4958f95583af799e402acc9298521f4e8420848a9c84bfd1d93f028e021fe25c3b6d270ad8dace3442f3ada2e0a1b0070c61dc3506697ab1cad958512f1cdb4e20008d72df52decbc703fa6be976904ada921200dce075813cd87c37623bb847c6b6e0674d1f776b87a0d31f8bbeced18861c6d58c7acf737da7733eee07345fc1127cb5e662a2d85225024b0568f4522711770387d087b48c76902d0218ac090114fb95db8035824b80af72f31e48c97c97d9b0bf4904a803f9dd31f6cfbd761be9dc6835285d4bae754c5a8ab06a93bfc781d8a00bdc66730119372ea1f780bd6084834ad76cc9055102fc610886787817f394763153faa2680255fdc17d84f833060ebfefda6c456dcb646f58a286534dbb17a3c2012191c820880e3e41e6b162d36b6ee3a6c7a08c1c94ac66fad700000bc2afd2a11a63ec89e8d45aff0781fc7a9193551890f48d8eeae780406d9ae7a7c1c7ef94ac4d23814c014578a8551abd9f84576c90b2ab6520d1150d5ead7541851772fb7be9cfb8e022fe76c02207c5b99b32f9b003ef035c93934950956839e93f16ea35b958cf0b4809018ab82e1ae24f05fef76275c082e812faf48ab7fe83aaedcf48b92ee2095db3e3276edd7018fed43559e33a5e77584e68b30f14d983257a5517e4aa6c87dda3b82cbdd4f99838cea9eaec1c2552350dae22f2ada711af690c8e18003263a5d7d15b68332b28cc6fcb4e020b15470e19e3a2d32f07119bbf2bb4b7895b6f8ca6e0fa932dad55bc6f0505fce25a141ecb1103a7599d293bde668ff2a4918759de466dcf6f7c9e9c1f12b391288b363f9135cc09957e6dd0b4e383c2a57a0c11cace6283c75d18c6712e4617c771a07687506e0224891d0525cea503fa746128f61d22da9d886d5e6f49adae6de8c724374075433f640061095a1977c1417ee0bd48da1d7d2e231148e7433ee1a56da383653627e83ec0d8ed39a7c81a67f1018832e8f4543bac77e7d8ea53a6c459108e678089a4fbd32361aa3e84cc40e78ab86110883eabb17cb582c26178f226030f0163f8cc80926111c1fb7c9949eb71a20ff51489184d8d17db5b9028793b278840f223d44f57f2132b359bae3377176603a82d7819dc0cc6fe84a6b02980a6e3b9fd88c4fd49dbc0e30a2287fb8234ca1393ce900aed505233ccca2eba8ca716acf268915e361d6bdd8e9ebde1f37d97cda19ec36f69f323f19e213bf6097008057356aabdf9eb860c3f06e1237c503f71c00b8217725abf2e3f9b54a3330b47d80fae993f2000f8554afc70e9b128aabc9a3bddeb8d08e191d97ea7e75a809f13e0e7b6e75aef47c23f3ae972f3d58452fc697a679796327be5e61fd930357f0f7d402b8875b48dd7288362088fb31fc315294dfb5d6631048523f079122b3d732c865afe5ed3c0140bd53a2e6c4c51427fd319f1f84aa3fe77fe8fd4a0d4879355e5a4692ef8398bb18efc91d714c58855d10fee3e709f90a646155bb8a436b6615a42d151685778067f7fd0901b8732ea178218150e320440b5d965b8768a06e08e9cc780b1e04569c06e957ae8daeebf122b0d68c720f48b87492e0dffda908407884bb2d9da3b6bded7d6a23fe4cae2b5fbff96506c73f44984112d418baadda9fb03892950faec5eadea81f755466e43eb4d1da7540310ef3a57421e6eb2639746eeb662702c92bfe1835ccb8ca947b38cdd65c037aed60a1a21e3ada6f7312b09d177531cc8b98be6de61882eec56983d7d7e2f365ceeafa26c49b37afa1464e27da0d5ba562ac98ba48d6a68490ed09e2949bc82105d746f5e44359789b306f2621b8371285db937077ae0cc686fdb7a701e12eaceee5b0c481911b20bd67acec321203398cd1ebb0fa96baab8ef622e9342b2b901761bca3f5ab8015b8fc762862acae850650ebc9f63711817fc66ea1c7bf40fc56f130becf8439dbddf8e2ddcd55c45397ecc44f7bc1ca1aee871758fcbddb5cbc027d6f2b716a26630fa11e3677cfae70d04051c1fd903159c8e367471c2e8d2b4b9c35af11f6c4b6fad5f081b79aacbebc5aa4012b9eb29b20596a821010fc1de6330d0e9c38f45f439450f519c7785ca9bcec2908f1d03ab023ac9f60221171fe30ca0f3308373355c03978b9be200cb171822eae3debba0d4bea21a1fa286362771ec8e98b6214f9b8514c62246c6547cdec7f87071d2947d170f57da25a43e4aaa0213da2a4252a61f37951bfb1354e63ce6314ce5d06c0ac483961bf7e12db47b4aee93c728a27449d2df3e2b53e4db80af6ca7eaa28ab1f4ed516141fbd8358236a29e6f8e4cd925ebbd4dd0774b793e078ab9f3dd059e731e1ab15a318d25f695b029b4405c61a320c848dcac15699c13f86d0593a045ce06a8d1d18ac6e249000ef05913b048c3b8e4531e66ec890c2aac8fd53b84bda281540b5082b95163e13218223a7aa834ba889bd551097969b2130fa9a67272b5f0eb85c629e6d6655b8257af818735de940ad5272237ecfc2693d06e4267a9260f85c42a851d3a46629326d6f17b57c97555c7b15ef7b81dd3efd7cf85a3f856dbafa305cdc15340e755059fa7f81a0819736e6b91fa46262377f1d90629058d29e9f8736b64964e6a51aa4b11f2f2000e019a25665c82e1fefdbc7094788e5754c778a56289b7afcfafcbb0c0527fea5486398552683ac0cda1ffd0c5e5c1d2a9c2d8116c608b2d4beb9248de8bff0190c0b0b19cb2175e327b8fd6d132a8376c978bc8ddf3ac3f0c25cf2e78557cc27ba10d0aa81cb52b61e77d01929d44b89f75873a956b7ab1745c2bb75590935e0ba9b861b7482fe0d0369b7c68f57b4ab0ccce7047501bdfc059afff9cb28e7ebe5d6696980185066729d9b8000bdd192d801abc0d1a9d0f2692eadc038130ff4ca14a05afb3dab108a801103b11b684d374a9aa704d90d9210eacd0346ef8bc29e287a16d89e62acf7ccd2c04eb42af9e0d464fb07327890ef678d6586b9222f54035564fa136e4c427f65d17d75171b5107f2cfcc4d03dd9298dc909580947cf1133a4304c356102039710f1ab06af03ac1c376d5b506d9544285197ef4724b65538eac0283be6e0de98ff0c216a32878dd7cd2006dcd6c66722fa3f1c1b612faeea8abfda28bf9007fbfa1407843918f959a16e149a16dc969e337331edbe209243f1cf2db2df85b407eac2f98ffe68417ecfdad063cb27fcf1e0273d3989e1983257ebcbcd65e7bab27a64f807c71e13a514e57b38012dab080243fdfd1200c90a468468553aaecb7700bac57975daf0eb0fe14c222e995ec259851bb7d4fd11ea5cacf93a3cbf44837ba06c1fac47289e22b687ca1b40c3b7fc0db481c46bd363e4695004fa24349fe9075218fb42ac78c1d7994e47bea323d54eac746aaff0597b9e091005bf754a58c96e498618e8f99fbe1a18b2c2aa582e654875e595afb36341f122f8947febb4ea726204f086467867f83029275b016ecefc3536adf437c4615e1d24c9b5bf272ee37a6f8704be7ab080cae41e9d4f02600165722e77cabc1a2ac11800d2d3852835c1e9c21ee2b264f3293fa1a0b7cf052a471f09c233fdc4aa199f9b5398a6a92996d4d5f747f45fd2ff7a07a06c5ac5fecc3da459150a0aba20907c54304a8d0ba3e8b4bb7d2baa4d6a3e5be5b2cb4d9c14019da0380d3f4b459fbc1e2e32ab4c1ef69b9e04950ef67d88dc39754b470d8b0e38cfbba354029411e9ff7a8c90ecb23371265e5673d7e192f5cf2ea641e366b24a387a2d8a935bccd13193cc3f73579f2eb1a84df05eb2aa76ce50109dfa220ccc205e5e5294bae4c8fefdc0e3c3c8aad8ad724b490dbc7221b0cad717f89d846d7d4e995eb9dc2464d624a93fa169bcc8c3601817446714a3d73c5a289888b3e0e041c63522dcf9d523d5f44733145dac4cdf052a00531d38c848ce68335660ba3538ab86cf77d64e37bd5245b521d7d5c2c61195a437e3b9057e7da44c8c2699231b79b9dc68d64b7fefe00dcedb717310ce6623b3a2e8063c650adc29d660b01e53dc1f88964adf34115d6de2fb4d9dddd566da533c80725807bbd9e5bf2077a9bcbc72774cf4195a798361a6b9b050ea673bc1559c232ec28d121e8c7a046637ea51af9b468c6ac3ecb33201aabf7c4ebf7344071f503533fd80ba4ebd15f94049bc2d2c95a02b757fe27606cfaa8d98cce6260a38afc0ede462397a982e38391516bb7631f316507b7b397d2c4547cb86c992cfb82534002de5c25bb64be38e151e3d764011a4db064a210cb199ad0e9f04a6ce48d46b07dc03263df84e643143116d94735c3fed6bbfebaabb58f44f9774067ade4d80227150982303bdfe21bc075d20914eccda8b357b14fc0a6322afedbcca594b52861ebd720c673624ec7fbb0277eaf1d8a80b998291f1199811d055aad63439a24baad58046099390fedc61ca436eab8be82e22e516bec2ac5fe079554999fc74bd078bd27bff8fcb0648be8f3d96cecaef9590b63e8f4ecd35d4422456f50fae69cdb2d661bb8b578a42250e4fede72fa55ec64d28954e4b9be5fd37b1284f84533a187d95de008abd4e078157e71ff6c725a5322dcde3b02b6ec951e3fecce31bf60ae1ee1318c4c24531f2fbfa26bf79d2ac653c2b1ca406f8cfcec1e38e8850c2c31061046c06e43c611038c1f46b061474ed03f396a490e485a4c8553a81d03abf961413ad69fc33a582de3c53732b041c7a709f3614806ae1e95962523bf68f9b6a73e1c9c0bb18a8bf2843f4acb4f567b87a3f5a07ce1b165d1a614b7f1404ce25d247157a9651cbae3654c6e6a5b7554c88b3f324c054875987b7bbf29ba09d59f01c391f3b201e080a9babd371eb5002c43dd29a0b64839bbf971410e3e287d09dc818b0cfa4fa3d56ad4860913cfeeb5299f5be2b745ea0eb60f1fdc14ec99416ea26cd518db979a49896249230879ccf6ac5fccd012e67f5f382c17922f6a4b28c6fe9a666f6196bbff331f97bbb6806730d5086b3a5c5aa9d4a5fed35e0c7f4c5ac480bd5c8485b4c4862cc9248642f208474a969255a5dc4894291006d1531c7de95c857f290ba74f478ec7ebbebcadafbf7011d3f776c86dcce0c7647d81042db46d344fbe25b38e95c06389a2ab1563fcd866c0a2143699881d82e27865bf747b3fa5f5ae78231c710635ca7e06ae306b159dd87dd84894efa95ae1361d9ea990a0c26a889bbeb3d45621262834f1d28cf90270a04b9b0d16baa90f8c29cdc81079b9787cbf4f76c23971cc9338eacfc642c2fc27cbb7a2de1d09baef3bf65fb04689457d7926fdbd0cd75319962ff196938b185571254b8ebe949d2c4e9876cf3fe95df2fd2cba0266af695c5a39ce9a28fa41ff9430c688eb8a27eafcc22c8fd6b5eaf5501922a03b9705b6ca5e1e8190794ab7f37a46d4e033cdb545fcff237dc83f95076ebd773447ead640861710a692d4fa76ef89faa0358c3a49ed5e20f1bd92fdbb285fb79e4f9247daeb45147572a1e4f037d2138c80bd4aca00e205c08bf02c6b25dae0d5cd7430a87c1619b3195a539e58bdec346c49e09d0112cb074db27ccaf5ebefa62b39a0d7cd0f5c3d5e898bd37c963db551789cea45a4199fe64add1df82ff9a6f2dc45c25bdf8422b1ce47c09047e172c998f8656ad622d2f5071c337963bf112d0202769b5ae1611202ccdd9615f97815b73f10c1c0da26b585f7d98d8d725db2ee5b226991d6dbae718757c278dc97a81fd4153b479a7b8711c505d6ff8b51a9d2e4a255fbf8e00f6b3099842f8f1679f90aaa71486ce77d6177ecdc3ca188490a381136a94cee878267c82a49c6c8738f0294aff92161f4221817fc53d99b32924c21cfc927d62d15c8b838f10cb48e9c8eaa529a165933986cd28146fc3166921df1001c2fd93eca8c8609021f62135bdf51bc7619b81005c36a570b4dba3032a4ec33f25eb38844ecde37dcd6484278546e00356b94f9c3e035e64ed10bbe8105fab1b540e851c3944956a49b0baaf80191ed18766d56af2889182ce40d69b05d7a50291a93116c38c76cd07a3371b745b14568d7e2a62800aae4708bb3924e9c94b413524d4aa37bc74c45dbbc35afc49499ae9fa8ac4bdf18699a67d38025a8cef238e03daa5a4a20d2d484ee99d547b7019a08aa3253d7efe1ca9fed634de1dfaf660f63c1cb68cb0acc9449b8185a17f8b5169ad0973787c98652c664ca525a34293ad2674826a3e4afb9e83748a8525acc5ee721bd969469fbd596829a6f7c1ad0dad8d1d3453bffc3a2a2cf99c644fd8a64e3abac715e393828f25d36f2eeea2202ea1ef3a7a2fbd6628f40dbeb3f8b709f3f6f6bf3c8ac88e0d09a03b67ec3ae3381397ebebe098d682824d9e1d660ed8e0f80aed8b1e028648eaa461225555a2bdb187b521f97f1250bd7ade7c1fdee67458459094c7f2334065b136c8290d7d89d56892724c07f51c1d9b99f292f9fb27f19f169656a5c34b50e40e1b162dff3eb78e9aa61b9e8b6ae94969e029024f818cab8951360fabfc74de53b29ac32ad29b734f53c6cc815827cf46e656400b14291da9511e1bc1fda6d95318e98512b7cb910c592dfddfaa0020b4ea7bf30ce526fc62234715d88c3b629b65e280c9ba17020bffa2e83e56651aaad610528678e67e4ae24702e2839d352e082c575ac1c0a9109a94544d833e0fad1bc0494da0eb79d9505e49ab0381a5514280304405f80beccba3cfc9c4239f4f1327c187806b3a9d7ffbdbb40edaeaa259225e3582067d438bd2ffcd0e9c30f7ae7ad27ae16f8dbb56ce0db2032305d5060e0fe4da1c93972853a66b28eef6c18306320d7f49f0b403b1c188422e7204fe91fabf6db87212b8a5f84b038eb2d680d49d0ba154a7b183c1e4873b4dd3c92dc87189f6db275518997b3f6817a283c1ccdd18ad76b75bfb94fbbf05cfe3e0591fc768a97218fbc436f3138a0785f9db8ad251ce90cf0628dee5c6c78964e3a86127315bd7f91d90ae823e193a72d37f69854482788ae31a5f8cc81b7a3c8023d66a329353850360421b766e7f5026d689f5a373ebab148a4402aab5a3b3942227dcba3f7f593aa1d0a671de2b81bf2290c0bf2070a40e026eb087099799436278bf2befa0cc4689942974e012430ae7f63417043b4dc738614c458001db7df618b99d21c4e2405d671d402943a58d98fffabf0c1c876706e5857ee5c454eb7ce8357d786d04459c41fe3ebd36c60482bab545bfdee7838cb8c58fadb83f2404ef63bc73d6f7bb79e95c543875da211dd28ec81103a50cc86e1814310fa7103687d220a56ac4e9518886fbc9012650ce9bbc005d009c32d6550a049cf4dafb391fbc35be5be20b8b38bb436b5a34c6e9f6e30b68984e2d68d5003076033e9aa11cc46206d363ca50fd33d608a1684c695fcb9e170c41f7ae9db335db7769469797debe2d1623cec23fc5d839aa8824d4e4e3181e58d33a8da9ab86fe5ae7ff14eb1a77988e441c5577a95faa8b24b2235bcd105a56b053b049c80453e43c9bf0d6b850eb700a9924498c794d2678c7284c172bef0aa32ec57b6b5165cdbf8f198ba3f40d774d6e6a7c32085757972d1d016d80d57aec3e7de40315e40ed7521879e0e70e7452047a97fcdd1c1e7b411bb8a89c1fa43dd4496a27bf1a181992c75677a6f897e2e031dd160f6c9a104e138a2ce323f646fe1eab6da4f8321b640797fc0f328ce608fa074e9ad71ab6313cc0a1b7ecf49c7bf23c65be65ce08907e8f4a24e636a5047c59e092f78be0a08a6a979ccee616ab444466c1406f480d53f316db11d8225f7863766aa33af4207e3c0f84735b260d0ad5a804a293374c90286a14a6b3b78e65c1a16a9e872d1a903b523ae840078c3f06e11932ece2e76df4018802197ef66f564099beeebfc0531e28b4f7683e351976096d0c9b5d3ef01c5b8565edc46a70a1e8de1472f432b5f8707768bdc9d6f030428ff3704b66bdaf22d1015a92e6f96c86014d13fbb8766df39d300f1318ad21124c3a2ebea02a298f24db91c587d30404c3a688c923bc5eacce371691c5ec709e4dc1354db0abb480b7c4d27ced023f7aa72b896f451ac96409760a9d0c799bc69cac9225dd627fb8b2ccd16ebe8e60d7e276576d278722260544ef1900c36850dd800b091c43f2b9f3320c77f5078480e5b440f6b94ed32a1e7aefe3758aaf20ef43ec44fcfb4a670fe51bcc53269f3231ea45365f14907ac3515602b2707a211d2ab84ae8c10cbd0f9d6aa3b4c15410c3cb34b8eea6903c312caa2856f56dafa14a1071ba23e05c19207318da4aca7c82080392d5ed0038fb616c164a814164b9d288bb70c317a6c4e85055507295fd55c9dfb1bb755111ae82d1a06e740eefe40eacd79f50be0a9664008f0f3f5afeae0e5719eef0018152b26d62eb1231fd4f90d7c1a756c59bd2deac52d0455b3068f70dc7fd32f3e8886b928d9e56cb068ada799de5cd8f2e274b5c87bbfd3f6da11f67a9807c0ecb74eb0cb46e345d59177aab573206f60946e545486927d287678727d3d95556754f1a9bcef13688991ab6816a1355ab844fa3f5cd0d3d2b3991825d67f3a8b64e53e42d895e1b6014a9ac355b7c4860f21ba989e80b09790feb0fc35ae4f5fdbf58eb54281e6781380c77d712515c0fc3d1a2e983314a78d9543c32b1fd30ac086fb5c71815803f865899946d6b88cc99ad648e8661bfa46b1bb0a4076ae60187be215c3700d8c0dd55da62a0a60a25b1ad3978a169916ee2b988e9b5b961b6ada1c4ee520504d9e1e9d64e5ff8927fafb1470bc9eccd23167eb87205f26213f48d2d3250cffaafc4320f8c469de483669e079c8267c6084b5e9918c5db2b9347dec929ddc6026a88baf5f9524a744c05e0e642c3753ca3de1a3fa18571b84644a32087bb83922f8f725bb349db963d5a955868a1637827a20b12a7e1652338c400eb6e135c05f4b2521b43269c8fc5e3d5cc2518e9e8c618c07e08549558406efe8a015990f45b176016f1647aa0cdf0e4110a58a0e8e8611d2b488b5b4596203920baf5cbd8383d3fc99b3e7103f4cc057ed42dc5131fa0ddebacd9bcd98a1aa015b8e7d0b41a535635dbe40edfcd83f7689c210fe15f6856505015a532f329870111b33062c32e957594bf9fdde06b3df4bb1de110377de73311a9c23c2db99a8e1e69fcfdb8538afe8fa20e870e545f103eb721a2190ea4dea34bf05032c03d0601c005cb1670eed16e47bbd63e6ee0c483ac161190435b16cd81ec6a1e5c40fed2b5577e55a8ea6e019b7a8051b3abe73a7c49a431b13ab181e3470774102fa0f653447e331e35aa8ffc7ce8229714d6113b2c6b5f23be4a77ba88011394da0b514f13dd4def6c5c4b27fed599a508889b76e9eac6226171f0293c5e3c49266a863c6694accb22ed31f4858e9b52943960671b75822e75eca9a86eaad6c0f77b3dd4905eae322d05b2c1f9203a723d4482dd4e8d8270d193bfa01189e805ab13ac7119e3fc3ce00019bab4ec74c7d2e90041e72d416ce92e648e799d1f2fbe20f71c8b1414ea315b02a69b38712b93cf8a0fbc9329886fb8d3e61e0b5dd8ff804695b083544ab1d1cdfc85ae7824ded363fad8722df6e8fcbe01c2af7cf109c3c89f675d439096d2047191bbe2d00e6c550b5009fa5a169e539a54c1d8d29fea732b5a8af9bf0829d7e3b1afe55c9ead4d2840f2cbbc079f5584fea4c9260064c071a5236e951714d6d88a97e4d6e4145c82823ef44103a2b67cf74427e4b83738545f76a2de8df324a22f88c6019c388be37f7892e44e334c09420198e71f97484ee9d2c290875e66795da37c7712d87cba836d667aac860f81dccaa860557028927a6c88accab01299a960ca323d7e18c9eda1607a686b70578caf1b46e33b6d269dca86bcdb52ff4a0c3c9cadc0a0c37d91f626ea5d94c5438d78bd0929e2742785dae7044a727e207256667a89e8fd6d9363bceaea194cb0b71449b0cd9a9f87f7c2bfedb3e2d31125afe60702bd2350623514f089468246ad6dec560560fc73d65ccfc1d7045deb748bec0c1d150fa1649f1a9eaba46e2a2ad15b9ad37807122aeed80e23a7d238696ca2c2910c767d7ffa3e5d31abf3b534de5d20dbf35324e3b7d42362843cd49da58f445037d2b45880d60fd45028f4e742423b495335c6f6b11764f29d6716a17a4d4ec10375b78389b57c8078f6de88503e3834ffc466e9e8b5c592c921f6c1854ad4f7b6369516bdfd76d7fa71e72c135b6a6ce10fc441ac663d10c480c539dc9deec8585df3029e81d28acf93106f96ac8919229945d4cf03ecf3751ce10bb502e79bc8203318246730273fafca3413112700c2c7631d3cce50c7d02f70a948c39026bd549143c381c98a5cc1e34368646a6c60aaa3e58db0abb19f12d67c0b64dbfc422c288b8cd06c1e1d9c3894271a73297f960b118dda10511231630696d108485b086e6b45ca1e14857134c134e6cc85fcf056565b4df18576c2415b33c02bb91268e915cc669b8073c62319632e48c78495080651a0392ce6be2246a5a65b02ab615818b626de948d0521e82a8de5ed0a1940ab7fe1ace2fbe0bfb258b5bb75ef4002cdabc6011bea275615a42b99c3e0d9a442fa6e0af54eb1053fc907f34590459c7b9b1bce09bd95e23587a9e6fca49d0070cec552639439910687b30153b6e7caf14a93265eac9d81f8a320817c5eeda6239d0390673d0860a114ca3901b54b906a8511037a6aeb556fcc33012d73687154c46caae38902caa68208ca550c01fd6d3303bb6ad2920bd43c49746181d73f06a91f9e4d0270d240e8095013a322e6a3d9137aaa0f1e49a98e473dfa56a3307e6bac0a08758916d342854ad6e824c1490f6fab1c143eaea5ef92ee9c96fc04f18458fcd3aeaa3b69d4a369429250b827b8e6cd96fffcca2b1859c5934e55e3394076d39470edf0d448a81a0af67e87b472d8cbf362be547be8aa2a1fa5f99698979af4fd061a9b987d7ac3720ac61a8927e107d39c299fc0cd833e6407bbd88c4116f1d50fcd6a4ca9cde5d6ec42c7cba397e0e162fead385eb52da40f8a1b2cc0a7bdb5afec9745d525ea456fab7706b658d5e780e04b668b28c42c38981c40c4aac478bd5cedaa23573a71fe02181f37fea34baf420a9292cde785ef1ae48c2da3211d18116c1894959ad292d6188583e09122c7b764aae3317a0a26721e527d2a5f83908f1e0b60e5ce8db56cda50dcb0a410feaee48065838bcc02094891a01ab19bd22c454500f9e3e1816f4aef33879b3d7d548b416d1cc0aced79268477035bac7b465023d6f79c18e3f5cfc1b981ddda94bf4047ed93d2eaf62789e2722b7907876da8530621941e0fbe58f7852cc68bd4deff3687dcebf993316478861ea109c18e00401cf3ef7634afaad007dcd3c846ec3e85f32773071d9fa308138865caf1c5f03e376fb58ff4ca66b4dfd6b69b01de8642d60f686ee678d5d4d5638932c31bda32f54787ff1d41b642182f5d72074319fd4ae617b3fa8fe57a2f9b1c0c1d6a32b3e4cf38a91fc76bd3ea8596f7723b7ae24d2c4a0c1cefcdd2b8c3d655b0822cf69f96438e21afe5c456eafef7deac0e48ed08d45aa71e6f3645fbb11142b4d32e47a66ad92f91c7a222a89361971c1be22c1b9889669f9395674c649a14ec782228aa3a30a2034c23195d88949e37f68a9d4237e79a6d6f7f101a96eefbfa057b8327e080ed7cc1f7ae2d8b632512658dec4c3a22100e310fd985c423d98b2c2604610557f805ed29d4df8e94149baa5b8a462b3caf8e1aca6a4c923ec26f78f095223f8ac2ab10dcabb1bea45a6614134e611e2c184ba2ded5b13c41f82aad49acfd866ba8c625a7524050c0d40aba26464559bf5a1626c36b41b8e7f149e61710919500d465f4840a6ef988ff9a3988cde2712ef016ee31300ce2e9142f2713d0204a9b2d4803382f0be397ccd358f3005d3910904bc6ed00f1528f6707edb866bbbf2608510f3a8478728c8e127966ec320ddc8ef83f8487bb0eccc39bc83f8b9861ba3f6893294fba306cc8c5856c876a32484a5119d3a43b98938c1b13dbbe0cb37e7e6ed192227a6eaa847ff5ad7b8b7fc9355c1dfd3ce53b3620f4aa0454c637c4620355c2efec538702f390289ad759a80058855dd15a52489c1c72ce2df22ad9efe1a1a448a861cc2610ea610b32153aa3f7e01a1bf2affb18586d2292915b591f03bd0865ab68c081070eb5a758c0822f89590142afa464faf791fcd49f21145667d58e578eed7ebe86489a4b7aa2033ad308b238970057c7160d51689a8557476a98d91655b8033314a441ac1177e68f2b84a5b98239eee9a52849e76be8263a4bd605e6bd3541e66e10a33c5a9194c0be003960c51a8c72113905950bb499dc3a107ffe5771867a19821ecca4c9cba79a69839fb7447bb43535646f76f126558685cf2919f4f2348f5e339e9cb501183eb6305a11b777e5a44dc09dba6647f3df6f2d670d210090c60ad08e55dd8f6cc290c4f3fdb729a28cfc96b74fdb4ed2ec97a26a9bb0a8f248b88cec28a12c98c90e28d517bed2f7f21026be4d39e2410ec7f9d8a261e26005e1fb8da2944b67aa66b637c8ea24b1be402380ae696ba058ac8fb6d13628a26ff8dc4185250b1f41898d596847f7630123ef9f821f1ededd9b352533fefa683baf550a279c38cc378d555aacbdb9eb926e6a1ec8475a001a39e75ff49f774103564bd79c6aaba0edde3877b2a6730d6d00663eced7b3963a6197b320701a5371a932e1a7b491da4e4b6662e564ce30094571d577c15b62fd1f3bf034443032094f775d66cb5b1d5c23c725bbfcda28899e9c584de07011c0c1f802583c00a30ecd4a1bed02f70dc5a867403fc08bce6f5bb5cd742d5b24a613d95bfe503c2338fb0c37f7c6527f1d2cff0c48893de8015778c0b8b7ce6e74e2c9d1df33f00084e81f6e29b2542a9987f9e813194c942e327b8eab1e356fca54b44273dc73b716f5fcaca90c90a1e307d8c7a7db70d59ca41598eaec97d52ac19167eb616cf0f91fa66ad940a17525fe7323db788efecf9d28c6aa79aecc5ef0315333b82d6e1fdf4c294bb8f33c6f2013165eefe972fcbc844d4834c1d40b9b5eb24bc01d4b4c4664c8a2e2d46dff22f6af35ab547ca41b881de1d1cb33635dc43ebee73f9f2ccb5ffbd27c659c10dd2a105d6f8c37cfe472d15ea5ef3a31db3ef9c214b67fda8bdcb6057e39692aea0c86b1f630cbb69e0647800d4278ed55a3a791585080adc372390649167df7ff6f280c2a2cdb6d6288d221a68291aec256b4d533602b19afd8104c5e44bf122e964d2ba55459193c342097dc81579f4d72364c3d486f80972e81d87c89af86a40051b114cf3b30cdec47df2d02b82342c7ce368a6cc5f89592e5ba3246fa4b79aee001053b2e7a46cabdd776b7617ca2c4ce5701be2af1df63a0b0c93cdeb381498b392eada85036c9fc9181f318b999604eca1c5c775a2ef1a7bc75545cc7be41d2410941e878052da8883fccc244ba8bd2cca1f866c08b3fbda1330d7fdae83b95a3284fca86a806747f3faa768ff5700616a9bf5b2a383bf3378019978d8b00acd79826f85eee17db2be07a4e85e2c2704bfccf4a1e223aef5f5eef3014855f8bd7ded53e4bde0081550b34affc46e5526d4e755f84c153d276e829fde39d506f8167e9dbcd8448d397204ccbc0165e7f5697a193102289b70c878cdd9a4a5f826485d7e834bfd1938488c7b980a877cec99ce964675359ca730255c9aa69e98ed72fa8df661fc3ce406f140f7479bcf488c1ce9956a876683ee969aab7bbd956fee33de7758d9ef154f1ea10388dc74c4280b9f92c01b52a7687e450c38e00370765a366dd8a4bde5d5b058389c71eaead07ac953536a275dcfd9592201845b33424854d8c6ff6c8fd26797b83a3be07ee9fe974808bd2073fbf707de662b4dfc2f5b76df1cfde4c38e4739f715c9f02444fa7845622a95f95c948f53d8a02b7ae57d33920497c81d8ce7b049ef0fce993a633ac851613cff80b2fd90a3c574c33e0dd4ca5de9825c012d9357b414cdf7b16a863baa945b6a2b6bcf8fc98e681ce8cd21312ebefc0be5e3426d94cd33f398d80496f1cc81b2c30f7936c18e2006dc2a32ca4e50cef579decc87a6276c9cf2710f1da4c5201cbb756ac2e7aaa590c569297d09c493f8429f67a06ecd64994da1ec750a243c113fb6ad2bcaf41c1bab646cea607ac55ab6844c7287a5d80b8ebb729cdde1d8ef1424854f078dfc4a8728097e3f059d712029e442ff1fa6684ea31b681970a92f59be2f575a1651c40f21b36de28f91f5419126b51a8089fd8494f21487ed09684b4fb1263d795e4d3e7bd54f570b425d99fab66ee82750cae7957ec1394459dbf0d5045b58d40509e3be803acf97883497a2bdbcdbc2dc5fb130018b6fd5e2ccd64dbcedce20a6dd836f1d892ddd357d3998cfa8b66ce10af2844d77f3e1561ef311fb7eee77a8874634a2fd6b2876552d198d54ea9067f8ae852117d53b618f6787e26a64aa3a0e85430f981c0c9fec67009bf870f9a284e0b34f332b2528917e4b4aaf20025be7633255a9481059c247cc716a91575659bc27e77b73e118beee81b0be4975b69561b14694c198eac4934343f2da9a70c9888f321e7e87263bbc3e43e9eecd81e4bfdb7fd97434df047f22fa93197cc0be60354b4985ab366e089412689dad061789fe638dae4cb9b7899c3ffaa1ef7315c5ba0b47410eabae87f77b10621317a6eebff19b56937a78888c91d1a9d8bb1c92f91874167004105f44b742e775559922ccc161ea0aabeb22c5ef29010fac0657af8f83fec7d90919defffee2120672638d96832f883f4457c1b9e91b73921a9019af7d22f3540990ca1ffd085883030fe3178f69e8467cec5506e6033a4ceb3fafc3932782811bf7b68f3d3cf19b363f010808aded38e9efc3025c7c4bdf4cdc3d9bd6a1f20022990cc4642bf588b142048933fa91f122c2da0a1cdaf9d3bc503907f10129a0c9d450f05bed04dcd29cddd09c17418e99b6a3a8834212eeaf8a81e9819a095a9f1a4a7097be21db663d0938bdfb18822a1cb4604a6ea2061ca1939ea9e91895ebb8d35a2e2fc9b2833a048f9c3fd508324388fde00cfd15ff4e59d09b495698ff4302de1f1f994b17b31a4f7d72ea33e938e1b5632adbb73792eab92482ff493a9ef6ec9948f65a9a24fa2c4941fe124e267d974c12f1c09ec889fc637906868e5bcad03f3164d07e9bb270bf59e519af1533e98ebd8964df2509c44fd2e9a46fc144b2d7d224d167490af2977032e9bb6492e8b13495ec5b9080fc4d3a4df82c994af62c4c24fb2e49207e924e277d0b2692bd9626893e2b75d55ce669993bb7b4dbb2b4659c2d27b69cd7b2b596bd5aced412b91718a56e58304cddb868947273d168eac602e354cdcb86a91b178d526e2e1a4ddd58609caa79d93075e3a251cacd45a3a91b0b8c53352f1ba66e5c344ab9b9683475638171aae665c3d48d8b462937178d463dcd9024882e86ac7a6876263702995b2f360d74f5b971727967256e3d6a45e623d6634f3abd8de79adb52455a4477f04b717ae683c5e9ac921aaac771e4136700510d35d1f74e9bd2f8577066e2f2a6e507bf74eef05ff749f37dc658d3f7c5d41e59d4b6722ac72cdcbb40f30dfa0a40c6cedb962fe531582e5df3556b3dfaf7e2c5064281703c31f10c2d286c52091f1956cfae597f27f0fd223932346bd4430e48475dcdf5da33a1f70c264b08f3f43b2f1f1e87c294a5d6e8395c36c258e6aa0823be6e0fcee746985283170e4663ccb572015230f9e00e6316380962a9897e606604b387012b85049d58e65f582d1828ec5a68b53adbb4fa6853172ed28c793efb6d36f6882bb3448557e327ef86b491c3bb76c778b3ae4d251b9bb164a9150c27a15ddce435031f8b1d81a5267c05477fd5dc15aadeddd96734b69e4f41589fff43ab9ae9549d8c0a4cb9e76a3f2fcc9b01ab03005fdbc6b81b93664f4504be2fcc5674a5b29dc0b1308ff43ed7cc158742283071727715a82b51d786f0f372db7b22371de1bfe6ad130e26c5e6f13adbacf5b6b18eb616c378c04832c7c547220ff8984b4d6ea239762de092503b6da9bea73d0458eded1160ed32094bddbd2b7c2224676aa9602ceab557ed5c78ad9e1702c05287a80066c49d46d0e0352c2b91e05360ac8dabac2169eb608cf0662d3b02a3148bba96af7f1b97975dc343094172be1b579bd88ad2b28369ac7bb0f0faf76e9671448f7a7ecd449da893a58ff548203c28f79a0a902aa1d294c638512a92e882809b87b9544328ec5f02ddde418abc6248c67b713c9c09a27e1d5ab33c81201ad202f970d5c08ffa1efcc649406fb7c0e1ec71f23fd4b062d2671fdb4cd46287013c89288cdfb5eb3d12e89987aeccfffb84fa374698f9feb4c8dd17380ceff184c30e2dc14110105f099aee6ab1df5f105f08ec5701d1f0be9ee079e14ca65ae9f31bb1ed6898614bb032def40e24eab7db5842670bbbbf6d7f20acfa8cfc08b21267a2cd924ee1497a0cc15d721096e874538ad69d67d88f9465206688c69a536d89fa06ed6dfef2e8de3246388fc47ae129e005fa3dd1bd8ef8e248d723b3625c3022b78bd2d932070d4f7e56a6a1a84c2c76ea95fbc28b35bab34ef817b48a710a3ba229751c45a447bf52fc2439e92140546c689d8389d126d43571fe3c17a58a4f5fb17a9aed83eb980f8b9432c653237543eae22334c5b1b2b09749db985652d06aa6f0f3850ead13d5d74425411c171404165ed5cb4a83fded0aaf4f3a097c1d18f5e800239ed0d8281343154401d1b36efdaeb9a40bb2897b2b139065a4668d78d7be49448791d42ffa596e7530cbdaadbc3435964ab3823ff6825547fdb8e5ef5781a1f79e54ff016297b2f95931eb293a211e0aa13f8e60fa34297d2bf6a465f704a5eb4a3ba8a659251a13321a48748e64e7a656e95714ae407f81b2131016fd2659466242a725b391bd3591a6999dd145b935c8bfa8d925d565e7ff34e6e50c8cbcfd9743a02faf51af8f3e788c18ddf74d8cd996cc54c024d309c1ccae2b35893db951ae5b8b961e12d76ef54d923b034a893159879a23712dbe0a3ae1cc0a9358c1bc559cf9e854db2cd22597c649a3c7aa99df99cb0fecd6a6c46d3848afd7ab881901af59d7476b2e44db1c7c0087904a8a71e417488c5c47b888a9019f69bc93b9325e37f7365af56029ee2ad6e91c67607911545619b2459edba22639d887772a055092111e6203f28d6f2fae466c6247f8bbf085c9dfff28ebcbd30d23ef69b06f082d008636a9a74b22e71e680c3b48b1a98b35cde5e3f8665297574b4aa7b00f6ae8baa03319779bf6e7c8473503580563f9068fdb47d6f11aa0dd06a677f5cdb67516a05909af700673f73e772c3bb6291394e41176ed2518fb97dc9fb295a411c19d16e4687cf3c89c17a2d80d5e5b4ba39f40d3987dc049c2d49b01049af515cd8073df80231dedd884b17ab10e3469af7edef577032b3bcfef32cf22f205516e5d9029dc0c7d4841e5341df227b17e393cdcd3af500bd945d973cf431410a0a51756b3feb5ee7a0266c5dcb0f55ff56dee0fe3a95e87e9bf472f376852fc7ce6108fa46c2ea829dcd03954fc826d4a606c2d41ff98f1119e58effbb8a283c33fdfeafebbf2a40ecbd86d4e1818a633d66399a6c23657316f6d362a36fc319eed5c92fac03b6098171ee15db7b964939d66c6a977104b15749b1f967193f6d179bb9b6ea323c7f20c47a835edc2fc61b1c2d6544791b3dab70776efffeeb56ede83eff4ee9f637a99f3f1ad0a977fe34c273fbf8c6bef7f3c1701e9bfef6576bbd6194340b3dd5a716036c3fd65ccb6188187102b6cb00f061d239676306a0f8a61fb189b3533f5dff4ba2c34f33aa0bbcb71b90fcbdcc76a1fef875b47791ac98139fac40d7ecfc190366dbbab8bfe49c154c933a3f1dc0207b6ba8834fb4c37f97dcccab86cdf8fcd66a3962fbd7d82f0bdce071d3ff0f728c0fe1e5c2fa91d52e0c070354adc0ce78ca3182f2e07d2461a843f951abc41f4d51403404dcfba7ded62dd03c19f19dfe9a8e19c47a8b7f0a21a9b7b36ac9dfa3ed2ec35f6699f5c8be443d8bd3c03e7be42f66d3cf97b38ca79733f12b7ef898311636773763c9c68c433f53419af809b2172fd2a58292d709fd3d77304f411e85360d4a531f09f67bc4f35c1f1d6adb94679cd0ef12ec7157bd3608b8429cbcbdca76ab07cfee827839be747944fc42799826af443994e3108cfdb0ab1133b6fa0860a62ea12e6929a03bfa35c28739c25db30483d8a2d559995ab08a6a9e560d5faafbe48cb1916007b823fcd7a9a90c91f2e4127abb0b0c181f83d89e9cd1b02b7a4292ddbd82cc883f8c8487e5d3bef0b8b0ed480f49ac8f99f0766af82edfe0f0136eabdd0bbcfc1323e15ac41fe6d34bcd3bb81627a8bfad6b8cc877f1ed4f2cecc2d45c5d41b13ec177c76898af696e0cfffb9f19b93f67d08c9e44eea326d63b2ca5b7e9072e04784d3321c98ea81fc60d8d7e0b8192009f0ddf21db8a62ee62000055a4a63a1e9e100f49c4d534a7b993d9386bfa0000d2ed3578aa94d92441f2c754a2958766f7ae42aaca71b659905e214606e37e9915e92117f39909eef75f0ee80fb7b8ea5805fd2f0131656dd10d3d09308dece599b62a976af37d462873bd901352bf2b88f879456c56dc7f6bb70018292216558c6a557a2286c90e1d2d2f5b6b021728c1dbf273858b9ff2d57345ab136223a4b01a1b0030a2524ca8adfb3e5dc113ee92bb78a066a0e57d02fc32bdab7628036cbd3ce1251bbc642ef0a2974934c7a08c756b861fd7220589f6dab35ab748c7bd9b0f066d7c3d0e87afe0719c7a000dac729b8d6623042e407bbdcb9c4de147985346964f092f02eb86937c29accc0bcb8a21e5e010f0057fba88d6ef5aba73066007f2e846c90e3dd68c3b5056ab275e1b2b1f08f97d398dee781fd73013ba0176e146d01ca96b0ac06b95190de3f15c1f784e0ddfc38c6fed97c08d1606913329a8fbbd66e2c55b48c2c336a2e9d496c6d56d970539d1b3e02405187b5477cce2bc44422cb7ea657b3cffd59ade7dd91b30260702263dec2cfba5b60e2676493267a7607bc7b9f55d12bf10f8af1e199b437f460a0a8a08c1bc5da962b458745dc7523c663b3e0038e12a21b869d5d9c6feede1469c281a1b71c39876b6a49b9026a864e01aa621596d6f5994b86abe20fe304d07c15afb98bd51f01ba4c3537b4b05ead57d63b3c50411bc1d9d5c43bf0d039a2e316ea95115b8baad806e5228dac800026be9e008d5b3fe51960c182525c9f43d6776789348a731317db572df3ecb908f678b93a46693f94464f92932124480f8ab694884329488b3e0114ef7aa65a7b6e1f40eabb710a6e193da4e2740f81e34184e060516bf4cb9870b0d8392adeb9e0fe8ecd75f96684eb93ed4449aefc6ea404689e2bcf75b9a4dd4e57d6f985ccfca272dcb44de47d1773ea7217d577a3d06b1f265890952d30f4272db592b9a2c97d92b2cdb161e3dd2a665008703649eb8e285c5bfb009a96d312bb8a17c01123a456cbba015914ce7ffe2684eac143c1af70d8fb04c9b84525486ffcd104f3c6e7f267e9676de8460baf5941941ed09acaf6c74a0d2f7a1ba0de33babf83401d2cf672c9829266a9237ed6f18cc228f0d168b846c0b02a83125dd4825e5c2de87af9544547a155a83df2e3f1144167e29b518fd1d9bf61ee4d443913af4dee364ce863f21d920abb6fcbe66eccf004baaf898708518d4716b4b435a81750b60490d55b0f49067914b0702b6b0093bf01432a406c27f7518e951965a9d00ef8c54254e802347f1a45070714a406e57f9c42fae406609dd79de1cbb64db75c47662b33c693921af34d19aa5d00f45c9e8bac285eac2e500c791ca850d46325a8de48e1f089f5498a634f4e5ee56bda8eaadeb877214756bcc09b0a58f55322e84b8325f16ded385ddf781746fe0c8bc629b46a27ad763d912f3b5211f3e5ec99578966483cc353447352c77f8b279acd3fd1e197fd8024daca08d5650dea166118217eb868e55aa2c833406fe62fcde613378577bc31c7907254e3ef438c41059ef36294bba2df28f46d993cb105431df1ca5e707ad7dddb96acbebcd869043c7102275bae51f44242451444827498a86f216c1c7dfa4b452ad4b7340f9a218d534db22a38644746da9f6e2cffc4d8f662e98f55be7ececbd0427ed69f6938ea29a28b207641546dc67c69ea7fb9a625c39d49096639a86650209c95ab92b3bb6849e756f70cad71d1d5721ef71b2d28fe433f41ee23ddb6216ae2d562f2e14f00e4210dcfa4c48997552efa1fb94e41ce86a4774e04622bdeb1aab937ea93aecf086d507092fc524c1f916f8e3b6ce9a61ae756d8760e1cf4bd3242665a2387c39c84e9006f18c453c3e6c17ea4316ce19c4ea187b653a853016e6f2bfc86fc7961d6969aa516c84824b8fc9149fd5ef9d8575ecf8659c11c3f24bb9643d4f3653c3ac0178dc08f4d6e0b56a1ae14a9c2ce0e0775b05f9883303120c8724789c1a0356e7c6324fd74336b236be542968f8d494f764f3589e9178946e793433aa5de2ee319ed7083777a5ba6d59c296d6e112cc5988820e82e225e746add1f7b234cc7c4305b781d84ef48eca335cab09f815e28647e9110e53566618e2381dbd64fc5f446017fa1558e8283f7d4199694e975cb323232b377259280bc7e929793c9cb67793191bc7aacbc08504f92f108cac7a4d89ed3251563ae4b2c6aefcd6f4eba22a7ab96428ecad5222e1a07549de1d6ef862ed0a6b7e18857c4c919291ad3a38dc302b953886c560d980e4bb175fb6578a8f52e6b7a81fc5b4c85e3527e15a0b51d20ac1f37df63beade8ff54ed44ea2fad8948bee94d0a9dcf55622b5b76967e01649af7e190a5c19cae80573ff02705e9568278b3869ac238d161092f3fb99ce7f30cff832601cd399a8d39987789f3a9e338f7d3d4c6b36636291c7887d89564cd3fce4cbd806cbc29fc91620e4fc6a908bd67c60e6cffa2164b35bcc03a7d8fd97ac933d9e3249e564c27b799bd4b3c67fc6b3969021caed04557cb6612dcb3a5ad89e268623dba40b04c64abd848e725f35af138c48e8f197cc7469386adda6bd2be635b09a47c02bc4856d1ecce31230ea1c712503332f2958f1716d2400e8bc28e0fd84efaf8022f3783479362e49a1e9c246c48d0bd1ff8d50d690125c5215e0177ab7c1ddb49824b25f41ce08a0fbe99f55df29825fe21d31380ba4bb4d1676960c6e7e2c0d99a48df0fca1fad0f3cf2d9667f349c27ad338a419313a519640ea110a45f5473c4574de62d79f19d78212c1eb6083434f81bd4c819612e0829a72b6bbb08b2474f045b319562878fa434f3a4a9360359bf56863e2c4c308fd6045f6214e7f0a77bf52151dbf9c57d2bcf610e8059692c3ea628d45f5a8912f061127f76008653ad68c399a58989d06c18341cc3a039ac09c5ab920c83ad311f4bc5bf3f45cb2ecc996f833a004338dfb386f32b59e53f5070994421a12f2998c207114c1957a0d15204da7d7500b39ebb9d7eb622a21aa717b8ab595a741df59a56fd83ede80729a48c9c71d5c59a7a98e629731a327fcab372e2f6b11ed4331ccd2a18fb04f00a9f38033b87a5ff047a9af4dd4b42ff126553af95a1bc6f6f96ea5b137af11fb4b8b0f924d6586217d1f3a537e2964a202b4fe2690392f21829b078329fa155b61054fa0c72eefe05e8a78b76ca0d69ab3ed0a5dfa7dd7ddc54428dcb1aeaa06d06f7bd2f735a23ce36918987249e99334992a4579e4ee019d9464e7ee00936ede1e331e778eb85acdd51fc5d5b1b6e061cce7c208a4b091e5567876fe34fc0155711b2530af1895b232d59576bac20dd64755ecf45c927eb93fb544a26a3ac995a8bbcb89dc54f593660295516ed1fc47c925db85345563990a88a18b813b08a690a4e1144d272154b4558c0a820d23488c5188b482c70c6d03cb2e9f3e79dea52ce194cea6182648bcd1da575410b31a3acd52d7e0fb42a5d4879a02be282d10c540c04ea9b1aaf62f8b14762b5db182345e918a2aa085d86d5071cf22114004a5b163f30b4a5fd1c5e594c09bec877849acb8753d855e7e863183bd4e78e040c414d3cb122319787a81fdfc2243549d921b9bf2d984cb6b439e4d52403329911c760ed371b12d208e5257588340d89f77776c9d413bc21cfef1223f1b4f3c89c77272394135c9276fbee9c331af9e05a2c70e65579d2ae7c126b6449acdad74459c96ec20d0c54d66f379bf06a65737e4855c1840818a82314533918277d59901d1fe1c8e16d56890bda125deab1592c846be3b45f03343a265ffde2b5acc55e113435539fe29a5919ac20b89a7614c40cc3fd0f82b3d2f446e3c73fd958aadb97fa0f63ea308c04c8658b93bc634f33267ebc898ca71aecf81136721fd610248c7c147558adce4c343b8750b5db41949459f32970269dc7985032d01d43ed5fe965c2411ddef426f955c01c21389f0543723d16a63404a41fe56296648c72ba50d02952773799f253ca4cbdd486733efc39ca6f4df4c142e448bd15b53957a4ae97953ea9f0211b6bc085f87348f8414ba1ed29062f7a4a13046282cb3433e407df4f68b96637477c6175c4d40309ed1f4597ea405466d89854256254dd5925d9fc64c3be5a17e4ad485b3bfa73a62a40457092508cf0dcf224defc742119ede67371fbe33191c21acd4d9805881d93d2fb6f1abfd2b37b526cd02def9a4cbecf29a70d97898d9700a66a1c37dc098ba95207f1e1a29191efd4503297ecbaca51042fd0bf4b217f432c3d52cc63b0c4a7378e77f9350fd06715de024055e12b709f1b91f1ce4067f6bb8a529417e17c28b2046759154192a34ba148c47333a589c022200bbc0ebb9ae0636cd08989a55406149c2f91daef80363f73a43b7c582a09c14b271d53a6cfda88fc533f94a200859ea72b9c823616ae46f892aea73cdbd43b03e2d909bab0ecdf57fd3468c05c1de1ab1c05e1dc0830b5720ab313d94095b2041a6b989c71fde98f1bce5bc7e6e084d567ecbed1ec8bd4f24632db637a86c255301c11f1fcc1a8e5cfb4542e573ffba5a104506372a62880e9ecddd2b4a8ab690a829f4bc0dce1beb43b452085837e97526f6157db608f8a3343258a624f7332049167e719a14d68191bcc4e4b7108525f7ced797a67299dbfb4b406c6730507611644eb1124c1ae8e39b8a599a36ebb7c5e86bd5707a0a6fdc5085c152833c973fd658aa528804ed2f951d831d963a25b88996755f74691744af842b284ec6bea4c211b9f0ff8ec67fea469e77b0ce8a52a296132bd19bfd72c6a0644bd41868f81ebc00720b134290b4e3d199af6b1630fbb8a684aad98d9d58da24655045312ba2f6bdde79752f09ec4d63d88dd36b0213874747f99bfb3260352240badc1e690610745578eed63c606da5d8a184dd33648a16d865972feb3171869aefdee8060b78f097f966344960b8dde10a2cf48127e975274fac7b0857b3956016d50359acd317199107b6d1c283058f4e70b6fde18f98dbe292c59d0dd8777e8f12b5a2efb549f0f39fdb1cdf89794a1de929c278630688e463952edbefb85d4b22042ab12549fa8473d576013e0bafa74efe35e458be67c7a0aec1615b96e4ea3026193bce5d9bed1bf5ab51020703a2084c261432cc51e3fe95210fcb5ca8da13bd35ade11f61e7311f08926c948a3f3e467b4f3521d82940b7a1e5059307782730c2faa0762d827cfb31fe4ed4a6883527538591878ca5421d26db5388662a19f8c5ead182d576aee70ec699c4d55dbf6553a868ed2d6b96cb83697329141545fe62d626d447f25b75c8fbecadbe7a89640ef4363c8e46a5d4a1fed82ee61e5a468d4b78e193a80aa3015c981758f59281b705882abff24a47d8c527bbb54182315c690fbff95b892067f398479426f6cb2d25c098fff91409aac13b0a7c2bc044f5c4efbf72466deb4974958ba3c38c5b6f66b3be6099eeced115ffed50cbf730429d7610681430d00fcc78bcc8ec2bb9586838a2fc79d45c9f31d3ca8d5a5b288897a7deef943dce2d2bb6081d12de2d10e746b07e592b7dba05c60bc75a08bb68ba2d0ad558b73e9b0f7dd0244fbe58649a67ef5901016ea6a04c2fa3d3fbcce90f826bbaf5482fe55a651738f18d8ff2e8b8647f56a89aba8503b1204ccf8ee91f63504b329965830e36b0b044b5895824edb01463e3c5edc8eb3be4b2d650371934b9fe76a391d4c9f2804737ce9cd99a4b628653e3a1a0037d784ad7004c7ce526584b96844155b78573596ce4c800287478a2c3631c95d91049fe35a39368c7bf1823e9e3ca9003c25e99fd0a4fbc4aee3dce5633747732788161d9746cd8817a16e315bcd105d0e44a77d3baad47a7a35542dc5a35b1e4e11e263447cee9901038b87a81d4bdb8009eec0a907108a4a711743651d887dbbcd057967cb756869cc73b4e5a17a2321056470602c5a21e3c685c1cffa3671ac93dced5a006946c26edd18541ac05100b604ff784c4db3b85637e914e32af5a99fc8620b805c7258fe0cf11b6e30a9bfdbdb7fd3c684b768672e3aa1de4b229667e2861c43013a198351a5daf4847775e91029c3b64b0e37f309a7427b841969b25620289ae0c7c2411dfc5833055be0555a15c11e00c74e43e0562aa8976ae0f9bb771ded2fd4d54f5a684f525157445ba2570d615b037586cbf5797475dcd8e9092dca3b04a5786d93c79d2014aa2f0955620f69d556a4d8c01c3556353f8c21aae4d0675c15f8909c5a7bef5243ec3e9c509b107df61c3495da8d4a6307bba3c48294a015a1ed2dfd3df9ee3d5a56cdf61a22f2c2b81b5950a1c3b3f75b9ce64df21fe1b447e615c5b3ec624dd1826694d06a5aa958b3f157dcae53a6f3e01f476b867bf1c2dcd7090b2d6b03de4d057f0e3320b034e9ffffffffffffffffe119187e6bebd61fbdd92f93943b193a32080151b9c69f4c49a624534a2e5d750576b7feb6df07690e240ebb0d9bfce0ea9394696a9a5cf68c3432360021834a6d3c1d6b27adbc5c0c65078a192063508c91376b7a6c8feefe8491138941ad5c7784cfb0599fbc30a8d4439f18bad5e9bbfd178241a1d674b6c9a4ebb941f60595d8cfc9588f1e86ac69028817d4ba968708ff59d39f2602481754b23ff3e618db1e6bcc0585bacfca65db0d5bbecf4a00d982faf4fc757bca8e00a2059558c3a635c7ac9be7223a8064413d7efa948ab869be5bc2826294879d7636a53742290d2057502b7bf1a543c6faf61ac40a2a5d53c39e13ef49c6abc26bd2ff748fd03af8282d2f5b00a182da8616ea8671e262de2067a6a0cef1b4bda7253cc49a630e41a4a09ad4ac391eeae7a33fbc67a491b901481450f540a0a0d6bbe1c64fe735d9f384595cb6e58505e4096ab371638db58694a593409ca05832b65f87788ed8690c068341740103481354672e42891ad6b6151984090afb56a2d48739cff2c1605a7e45474a0a30180c0664096a7f1d3c48fb5c5e2704a204f57f291bcb8558b3cc1b86b27203b4032409aa6d6b50de374df2b610673008204850dd745babfdee5adb9a3b83ad658d73858f63a857e4b5b89d3b4aa7db180ab9fd966a23afd47c7d1443f1f3369b9fe732b539c45008f7d9ebf2a5bb86f930146bf2b4b965c6b6898dc1b4963584a1dcf9286a7e322db6e460a84c6d8d9c07bfdbe53630545ed3df14d3e16ad7e617eab139fe269d762e255aeec2d6ef113e7ca1f634b7ed2d3d35b5cb5e285cc98f9d379f5a131e27e183170a517bc285bb89d74acf20da8562e973d1331735dec13ccc05185d28b6daa54679b9ed2d26177ce442f1623b438bf9ff49c4b8508c0d4b8d1642da0b57c26052065d5a0e1fb750dcacd39a3fdbbedfd86da1b635cd493ecd2f3edd580bc512b16d5b5c871b435cf8a085525f0d438b256fb33035370bb5789a67cc539326d4c36064a1f87e0f7b5da646ccad63a1d24a0d2dae26634cfd1b16cafb205ee2e6b8c80ebd42ad45f47ece111d86bc17d315aaf75aa6d41a6d18b5ef134684b6b115ea1c6b09f724c48e53d3a759a1d8a3c534175e225a856afcae7bf1f241adf16130dfc2dfc2aa50bacf8d4f5b84eefc730a9af0910ad5dab6e39ce757fa2dc660ae0b1fa8507d87b16c0e33d90083c160d046183e4ea156aeb4ebafad866de3b1d292e9d1647ae87941693a31e3a298c6872994a6c3d3c79b105a9ece09634ac2f3510a95277f656b183ae265470a85c8d16a8dbeb039261b85bafb6bcbf79a860e651285e2732ef5c163d9ac3c7f1dfe520394179750a8965a3e3ace50739a66b6180c0683c19c9146c6c6123e40a150fbd3e43aeb3978aa9f50cd6a78b186b631cad4f384fa77454cdf9ce93c7b3c795951c14117e472d809a5ac69587d29dae40bdd06180c06b383870a2794b2f373c783cb7f7121dc845a57761c21df1e2e6a5256561a4da8a68ff65928f92d765833a150d161fb68bfd9225e4ca86c7f9ac6a4cd16d1dfc9cb8bb3f8c725541ed6549519e725bf84694b28b44ebbc5cfb7f8d835278c19179446137c5442f5d1efc445c63fce90124a0f6a73906983cd539a8442cbd223e6bda7313784064a0a4b0d5a5e5cee4312ca1b840e5f9fc4cccdce05676024d41eec43dc50b39ed72924d41fbd6d56736cf951d709e3c1ee157c3c42b5d3ee4d9b7e6e3e1ca18e9d3b65d35e0df18e961516ec6859692be8961796f3f2d1886704f860846ac7e89aad838b88273f16a1fe179bb5269b854dbd576525050706d3e3657d28423d3e6bba765a2921cb1b98e03081018befc060fe5b5e1a0ce6a6f09108e59d0dda85e76843ac8b08d5707eee697ed9b8ee9d7046d1e519051f87502b618389d9ded6b343278c2dcf92f22799cccb8acac9dd4f51a3e577645c5a3e0ca14eaf5f4f8831fe76b685507d18a92676a8f959ed39834b08758efef9d577e9a4646710ea3c393b4dcf4a7ad71ada6c41e643108a3136467e6c90b693bb1a087596efa5d4ae3d9d977f0042a5d3a09552f734bee89b6f51931c65bcf0605171c1e1c71f94376cd9e56acbcf9b443c585e78c820f941f5debe1f74cb1ab997e5a30fca531f53b77f5eabb5150613850f3ea84dbc8b65eb8550e2b6192cc2c71e54626ccfd25ff98d1f868e0a1f7a50ba90b6265367be7273180c4a307ce44161fbb5e7f59aa344ad6c860f3c2875e6ebce37357fb0410c460a1f775007f99b5b0dfe3fe3c164d0e56525c5a591091f7650b71c9132d5bd45d7c37550ab69742bb1e6f7342d257ff115603ee8a01a6f5abb5e0b99eb67e3b13ff898837afebcdb67787a51bf1c94ffe97a3bbbecd9149dd19c38a8a6cb0fe76ef2c7e37b68f8808342769bceb9848c299ff7e30d2aad5bdab46e0baf797f0c8685c5311816163f976e502d17a576ceb631734b6d50690fdb2ff333dae6c606d5efdc72d1214c7ce732c8e78c34323604f1b10675d61e77e2654bb535a941adb7b766cd41d4ceeb7cf0910675ad89da4ff229bb5434284ddd9b527fcf9e37fe1a6030184c3a238d4c8f8f33a8e4dff01c556548bd4199d87f4b2f7c98412d63d7f2fc4976cec76550dc9a44bad6a26a4b4de333d2c8fc0719544bc45063ef093fc6a0dab74b673b69f7d9d3d0a60d30184d2c7c8841214d7d1222576cc8ba3018b4858f30a875f6dbfed71e670dee0718947a4b76673121d344f6f105851a67eac897bbeb61690c1f5e50dc34ac1dfc5cd8ac76f6d105c57d9afb3ad1f9e033b6153eb8a05a93eaed87f87f8e370c86bff0b105d5da343d7f745893d88e3346f8d0823a27f591aaff21b49a3538cc826a8959627a45ca76b711ca071654df3acc5a793163792965d2f07105a59d5a7378d32d536f877cf8b082c24dd9a8f1287fda46556082c3240526689861a288c74715d4b166f91bb74ffedcc948f8a08252eef55c8b98e1366fdcf03105d5fdcdeea4ed966735fd90825addb74cb3cfda337c4441a9a6a73f0db1c7c5d23198fb8082f2c36821c658cf724deb8451c51782c1c71314f6a23da8991343d7c7096ad336e446f18e3146ed848f26a8e59fae8ad8d970a53c61e433d2c8a87c30412d76ef948bed399eb34e183328ad65d0244719292c3b5cd043052e2e8e060683c92034c3c712544be9b9da34ec1c75d413c645848a67a49179c187125472b4db249eccd57c623c36e523098aa56584cb8ef6e1d20f24a886ad4c4fac7d6a6b51370b368ea19a65e3c7cf61c7fadc9dc135863a6f16eab6106e2b5b74c2a8580cd5fa0fa3c5fea094f929c7e1e1086c1043354e6da14feb153ff53014a6f5435dcdb5b7db332a283abee94eac414248182a9fad464fdb3acbeb9d4161f14ce68c3432181bc150f8d89ccbd6ddba79ea94b62fb0010c85d6a2f35a84701d5e7fc2a86325e5fc42e56a0e4abbd820724c7ec2c82b66e8d0b16206cbca19188c8e95145fa8062ffde3b685ce9df884116d22a24d3f7141e9272ebd50a87e0d6bfc18cf3dde09e31dc2b66af85aaf063a238d8c890d5ea847c49ad498358da2edc660fa8c34323c6cec429d64e6937abbbe593e9474a17ed1e742b7fc340cb5726730a56023174a139e9fc4e97b93afc46038833d6ce0429d9588f5b1739aa469ad5ba8838dedef100f3bb7b357b0610b95bed98692a25bebb09547cab7b0702d542772d42cb68968f9620c466505e585168a79a9ea293b5d94bcb56063162a65b3b69a6de7ff73cdbaa4b0ec4059356cc842ed59bf9ae6fa34e8db170ba5da2047ab997ec3d5566760a116fbb44eb3f0566bf214d1050d1a9898a06146be42b16f998a89be8db51d0c068359768542874db1b1296aec92c97449747941d9819282b215eafc1aaffbc418ea860783c12c17941d8a5c5e50bce505d5c1062b54b3de5827d5bba4ed0907180c06936e0a3656a116aee474d2379c72fd54a1da79e3a3ff4f6ba16b9f2ed848856229a547276d2f4ae9e049e68780e2924c729471b8061ba8506dbd610b9bdd6eb411262fd838854a8725ccf50db3a48da60d53a8d49cd44dddffdd9e7df2e268e8c98bb3688f973c2c856a77ae9763eb41d934e98471a5a9b8f4703430180ca63368a30a3648a1509ec4d8725b7e8d37154f6063142abf59a6d7eec7a5d9892d0ac5529969c3b4fcce6a10cb4acb0a3018969516c65a9c47192ddfc3cdc06090602314aa91a273f81c9e4f4e07146ad7a31ebb4c6bb1d4eb138a5762a6edb04b54551d670525c3e2b267a491f1800d4fa8969d5e4f36f4bfcdcbebc04cf1839cc34627149f4639514aecd7e55a4ea8f3c9f73ddd26767afe84d1052d2d2c58cf52030c26473a238d8c8d26d8d8844af88bb566f5d04a46d4e305833971f1130ca6cf4823d3624313eaf22cc6d661ad0f5a7a278c41c0ec4c28c4fc1c7d964e6a16729f30bea0a8a06432c88c14a840066694815e849041781013aa39cd63e3cb1d1bc6d87370461a99346c5c4235b9a81d675a2de52eb36109c527fff5d276c36f1a5b5409b548bf796d667b7f84dad30083392ad8a084f2b379991c593ac41cd99884c2a58cd924dfc358aa9e301a184ccb0a0b069349dbf2c2d2031b92508b4c7fb1d75ece30f30a83c9643665b8602312ea98f1e36a1a3c8e16a713c61d2b2d0d8359bf067b0cc6248719263b565a5880c1a0c6c10624d4a3dee61a6c5066d3a9efe24d2685c78e4ce677a0bcb4f81a7b4e6c3c429db574adf651b489c7319848d870845aec9e57d2d5500fba75c2d8b2b286a7b48c0e94949447d90885da392ca1e61a5f73d7d04071e5e5e55b5e5c505a92193618a19aa2cc63b7c89ad6d9f05861687d606311ea912fc65643f6df18ef09a30b32c95186498e94c6735c066185a9a0044111ea13a56cd8d9364a3e29e551cef835565ad0c06010a34bcab3951d99c462d84884e2c7fcbf7b6df9ac39278c8c3963297851415941436130ecdd6003112a0f9bffb0e58bb2697dc28892c9bcb400c125d12447196cc30a360ea15a2ba3937b8ed1b26c30180c068351c40383c160ae3561c3106ab9251ebedbc6e87c4e18d5c820acb06c0e6c1442751e4ab6bc11ae9478565e1a57b194476181eec00621d4f1c38ca5760df911fb41a8f3cc3deaed286a3b0883c16004a1d66abab11f5eeadbb6d264d4589ed2a44f796978b8a033d2c874c04620146273a8ad368e8bfd61278c2e018ed96ddba2e6861654666a9675bbd7e1f6260b6a6f1d25263ea8e94dc482d2543ddcbe069da36c5d41fd5f73bcae9dfe0635571bacbca8b8008d1b56508fd98e9063c37b2ea56115175c176e5441f9dab5ba3509517387ee84b16380b86d70830a2a7d215c8f5032d46cf78d29a86b7f9a3aa77fe2186e484169c2dfbb9518ffbfc928285d4ce75a3117d2e6bb0105d5b07227ec76a939bf28f370e3090af5c26fda5ac8199df584b16585c50c131c2634780c460171c3098ad50f25baee94b812dd68825a5ccdb965cd3768f3cf0d26286fba7b9b91a24b9f4753637063096adfd7d1bef66d2ea51b4a507a9a37ed77af3e2c6d42c28d242867eb9071263f08173b1c988a7003096a253c8c1b3eeb428ea1fa6c533d4d628d56afe6ba25c4184a9b695fde2db48e8bd50829865a4ddb20f37bc7d6c64f8b228418eab0ddb5089593fbfdacb03344c83054d35c3b25a23f8dbcd0a7f0602b3b301861a8e673da0c91ad666a28180a35cabee1751a6f66b8c0506d5d13733a6af7abf517aac1e46ff9f8778dada32f14aeb69edaf1e1426d9dc65ea8e306ddf633efdef6222a2284172a53f2e689b5e5f788d22e2264174a95d74fb36b1d65ab9f30aaf4602639cc3011c28a0a3018f6425869183aba50aa4d9da96e5e1efb1e2224170ab1d39bd262f26af6192e5443477dbf397cd0f9ee645b5e587284dc4275937051a2c367f1f7c23984d842b576633336bd4e8fb54793c954b10106c3c610520bd5a4ee2374bccf76377ec22639ca58c14b082dd46adbc987d0aef49417320bf5b7fc99b586adb5d69e97d7c1f8f26584c842ad6cf585cdaef1e4252d4262a1daf72c6b1c11dd3fbf8587cb4acaca7486c042256ad8b1ab2e6c8e793a613461ccc36407ca890b660d938679989ca611f20ab5185bc8d3ba9f6dfc72472625c557bff088810a0bb6435ca1ce3aca5676db8621cdbcbccbb7247a4b0e0ce60921ad50d889b319ae5d5e6eb427086185525dcdd27163d685bdab500de3963c35e9506abe61aa42ad75dd308688b921869e53a11ae229d3c3aef98eb50a0a0cec10820ac5da41a8358d26430761dae1823d855a55e56b2d7131c66c4f18332bac7b10620ae5ea48114b8b11375d79c288b0859442355d8b78a7e571d45e07fb0c4b41395999cceb68f91d9b2b21a4504dfae48ed037e92c627fc298e2ffe29251238547b398f24346a136b962f3ffe9ed6ea528d42f9e9ec49226f6cc4e28d46e439d0b1d6fbd1a0685ba86b13d7407354c59c24fa8766b21d4d6329670f378425d2e42abec9ddaba677908e9847a6ff20ee241dbd0eae28462db7acd5d423d9c1cb209d5f99b8d116b563b9f3ce11e0812219a50dbb8e5ebb2f6859aa399504d83c8fc8ad65023d3fc53328a378081bf19384c5e78c400836979355a7c070d9ead9cc154bc0598441f9508c18442882d3e266ecf104f3be11b845c42f1b16e5cb60e6fbbf69650eb5883b93cb1f760879b2cbee3ec20a4124a133779d2ee2d66874328a1fcceb9b3e88fe6194226a1d2b2d5fd831a6b9a759784ea748e65c39877685b874442356dee4d5b7dcc1b84c3c4244719384cf2f038ae440824d4366c253d8c1a6b8d627a843a949cb1a61d3a6f9ce984f1c4a573853842a1660c1d9f2f2e2f7a23d449c95e573b8c8b313f8c50ecbbcf1a77dcd4655d84f2bfd566289737b999c4dd1a84284275dbb32d3f21fec675368424425da30621caf4c88d9f8608a5ac69a76cad6dca3e3ce14328a447fba4c31cad1e3243286d1a7a949a3dd7b4dea6100a9beba6d959ffa869d0228442d4b69ef51dffe6ae41a85f45cc8935d78efc2808f598fc5b23b686dd5a1808d534112fd49a65caf25a8f9617d49e0607100aa536434cd9ffafc00f217f50daa47667b8f0593bc66713217e508a8d312fa7f62639cac071da10d207b5305ddbbbd1e77e964e1883d9e4834a646f2c9b96ac5b2e9f30221884ec41b12e3faaac690dfb6279c2e8b26892c30c130c068309d1836a450ba1d5a0dd46bbd113c6171e2ca705217950a737757345478d9f4f0f2a221ed441cf5e1b64e91c4b999b85903ba8065d9bc611a5e3c3a93961446e796139282176506c7969c3bc51c428f74f1833dfc29278185207d5a4bc6b56fb64979c251d54b7b657678dcf7df6cf41e1fa6e2711e661d9b4498e324c540d30182d84c841218438b1d4436f9638c54135ec74cf76d95fd25e38a83b4dd37ab19470db1b0b7983c26b8c785a5a4cde347783e2cef5fc0d3b4eca32b541751e868dccda5f632cb1411d46799769f5b871666f0859836aaee9ead324a6ec53222984a841213de6d4d69ed6b0eb87a441dd597fb2a59fc3c9d768508cd3a5b59aba7d356a216750dcf6b869630d6542e66650db7bd870addf7bb61f5206d588efdae462eed2e361d0530821836acd367b8d6a6f5b6ddb0487098e49848c416da383dd8c1b5eec5db70a21625067d136bace6a1a4ae95808cf547098e430c3e46006d31121615097a7e1e50b139f269d6482c3a4e59b1d3cce30c96186090693984114881030a8bfdcd620cdd334bffa7c41e1f994fa344e7db865877841a1d51c3d2799db42a813878932c96186891842baa0da196bd8417848cfe1734135b4e93c21c76d8b9a42b6a0d81dd3616abc61b7cc42b4a0d8496973d7f1f1fa9c2ca8e76cec4e43ab2174a909c182caf4ae9d183a724de75c419db5a77bf35013d7a59414c76105a589189b63780d7fc3104d729461a262030c0683c94f695074a8f0689914961d28073fb4105205a58a7225e6b59ed62616420595bca7c15b773817ad143205d57b905fe24b0dfac5fc8491d110220585fed8fb7a909d77160595297162bfdd3cfb93f2e5300c215050ebf7d98eda38ea6f7ee1b1a30c2e843c41b586589b1fd5f58f2885f0983c429ca07e7de2e6ac7bb55dacd9879026a8a39d297d7d2da6799004214c507fe7c969f11a6676d609638f5723c3e23b300f597cc7695979f194095982ea4edfd9dc5775a16fe1e1a2f28bc906214a50ed329d5fdfa07a1e7ecb2462302a32c0605cfedb62224292a038e527aff4f6856e3504098a3599e7acc6a4cad8f1311462ab17ffa6b4d6e23b18cc19696458408ca1f0d19ea37ab9ee1b4f17069062a83fa959afadb173f6352d0308319437adecb0e7e375d07f186af19b4eac397f9ac6bf8571125b4f6f987eb900120c75726fb5cf33fa5ab880a15acaf7666c7953a393d21c407ea11afd1ddd42e9da13ad2fd42562cda6744cdbb3260683c164d005f542352df37cf6b6f36fe2856af0187f2ea40cf9263c80ec4265b37ffa71e2d5f34906188c0bc3014417ea9735c9f2cf91363d7cc298f946d6b950aaae9c34ad3cfca84c87ca8bbb28b2000417aa59eb30425ed9981fb6b223b3060a63b46903459b3c126fa196e56736fa1de6a2b6853a4d9ee8d9fefac67b461a9917905aa8dfa5aca5b69c9a83cc278c2c3bd6699101082d14a7d4e678b35b8b9d434c1980cc42b5ae867d9b3021dacc342f0091856266f68f3ce935f3a6582864c4d29735a47c12222c14264bebb913c3745643184c11405ea19a4ea9113d4aa4b9be1b57a8464f7fb5ffc69b7815a415ca1f593e6742b81ab23e89150a7d6bd2b25ddf28393d08e88c3432199055a8d6bfb912b3d35a6b1ea94235ac7d7a6dd6355bfd54a8d4dcca5267ebe60e3f082b383098660920a850d748fb19adf3a935e85fbe062fef7228069053a873b26deeb1d593689d29d4a1b39e7df870d3a05ba550ecd61dbbd69cd4cd350d84148a3ddb84cf9ece422711c828d43ac689b146192ed4a4230a757958b3d21ec766cc1f0ab5be69fe9cd30d36cd410d2854c3f5c674ddf19e22a34f28e609cf6a0e9b536fb23da1322d437de9163588b54ea83cad29f9b2a7cecbc609d5f464ef5f43a875a306ed261426ded67dcc8f1db6d48442fe47d575519309c50e35d6991a5cdfcd8b7500c18462a76da195ba1bca6db4066907904b287c47c7d3d8cc783a932594e2f283524367599f7595509ce9f0686ada76a1dd3b805042f16277987159ee273a29804c42753af97d0b9b5d99ec647008209250875733d35a4d35f5792454fabd73b689de167b21a19af546d5fdbdd4b6b547a883cdaeb35037079d44c9116aa5b39bac69ebf3389b46286ed93aad2a62efe6d30b208c50cdeae1db850deffa9e13c6469717e822543bffc97ca9498d37894014a1d2facca6eb1051c2c64e1813910e4012a17ebb9da5bf87d7eadef2e262c2021a9860122f09018208f57dd269a9b13d3aeb56565a185dbc057c0895fce44aab69c91932d686654e5cfcc4410ca15836c70f6a186a0aa1123abe3257eb85f681f06992a30c1320280c8665c7520121844a4dd38c8f21d6344e7c4006a19835ec34791a776a7e0f8820d449468d696ba849fb994002a1b6bd195b364cad515e40a885ee3593f6c9dcf6b440fea0d435ed72d44895914f07881f146a54fff81c6adea230186ff903e983ca86db6e373e6c69ade684f1e4c59fadb7a8e32d7f12081fd4a765ed8ea65f998b5b7b1aa43d2874d40df3a65b7bb17d0bd343b4507080e8416d6e6a8717266e529630180c66a1e441b5750cdb628ef6a04508040f8a695a0c0f7333fb789d301e6a796101b9834a6d79a9a736dee90d4f18f1068a6b1c545ce3681f40eca06e3f315f4ecdea61e969e0821e2d2f2aaa0525c3e2b2f2a2e2020c66e5450565a9005207f5cd1f6bd6fcdd273774c2d8d82300a183e2bbd61ac4523a1f009983ea65cacd59292154847cc28842002207e529b56487d94a88d05d523ed3b29261f11d889b02903820558c626d7df5b3df39de4917476941e0a0b6114b8d69fe42781a83bce1a862146e76a2c550b6e3d5fa0c1037283cffe4cd7a8d1ee576e29279715939c9a054206d5088ba0fa353468ae935f3b23c5b00c206b5692d762dfff83978080a206b50ec1b3f2d13c3ddff5b1035a8d36c90274e0da9374d2217903428bdb4e7a91bb4bc11431034a883e89fb5cbfb8658d30c2067502c933951937d50f3a61341cca0909de37d4deac6339b41caa002ab17d9b106a96b1b14379a8b2b537bc5ccc60685995e151d79f7495e6b50df344d6f9fc55583da93b011c3a65183f63445438ca441a56cf891a76787a1e65f8db59282399841c4478ca041ad6c69251e3bcd8c533a835ad8c7c9177b4e88979941dd368ee92074ba51a6974131a25b9f2d1fbb51950c4a51e3498ace36dc74d331a8e6991a9b66fbeca42506752765d30d235f89cf5306fd301206d58efe6a0e6a18bf519e368c804125c5b64df273788d35f70595fc74837f3a655beb8c78417deb7d8428adecf75f7418e9825a7f9636a68b0c9df4e582cae6516f7276ce36ea77131c26384c729861030ce6e81e46b6a050eb46f6ab25c6d2a51cd1827276cdfb7d837e21b4181246b2a00e735add526e5abd26b1800668778c604129df49781e9bf44729e1c8e0da61e40a6a1d435c0c8f77a622a38198413d8c5841b596ac616e781a332fcd6010b210235550b91c59b59d861b6ceb970a0a62840aea244b8c35ad3597fc9aeb889129286c56d3306b0e9db1bd7410312205d5b9edf13337e521842f08122351509d9e5d73ebcea273cc2c31020595989d6cd037c9d45bf2c81354bac39e0821cc3edd84c160308919c43cf4c48813147e834df631660d35dd04c5c8979a936e3508af30c20485de121bf593cd715f6b57185a6164098aad66314a0965efbae3080b234a50cc79feee76e135e59124a8e3ccdc73f95d3b4dea0812d4c2b33ce11efb9fec740c75e8b0748df798cb4f1a43e9aed7e3f44d9357f362a87652a23e6a9221dec6430cb5bfd8db7810a2f3b7d230545a5ee9b979ed2e6f1584883054634e5f8b9b666d5b6a82a1aed96dbc1bdcce5fda0043a5dc939237d16146acfd42e99e5ff8e7e7d3b3e4e682882f9432be44a64db39e2dd47aa1fc92ad74fcd7ed20c20bd5d69f3ba2b4489bc6b677a1183245a9b54fba1ecda30b858787d59f8f6eee6972a1da31d6929f63e7f6cab85049b15bd34ba7213696da05915b28f7eee46d0d9d6c4f6a0ba5dd4ed3cc9717b56ea916aa2d5fe474fc73167f4184162af5ffe1628608e12cd4b6f3dabe9fbda15e8db020220bb5dbdfac8673a12ee7aafc1ab150ed879499f537ff12674104162a9bcdc7d4e866a6d67e85e2d4adf5ac5ba7aead5157288438f962fe762edb1d06d30af5999a3d37a7c76182a37b88b042fde3a336ccf1b04dad31839f105985ba94ac25f55ceda4b454150ad1955b176a997e191321920ab56ead6d7bfc132a14d2653eca899c7c219f421dc65a62affcd83c799942f91daed4246c07297e9642bb7ba1440ac5fdcc31d72e8e427d73abdfdc2132860eca6186c9194444a130edd186fd7245dfe48542f1ca45f65eee67b90a0ad5b0b399fdab41bd4734c1717110f9845ade24e6b81ab3d3e036229e50f79d9b774d9ff3c7dd09c5b661d2840d6783562f3d840827d4c24f2bfba06b7e1ddc4da8e5d89fb05717a173a409e568a5cb739ebdce424d260f229950d838fb62fbbeb918e73f0b3098ff76de208209d578d11f3327442ce525545b8861774b8da98b962514a35f3a43da20667a502554d37ed3eae6fba0a6a583c1ac5f034528a1ee7c6b4dbb85ee34bc55030c068341cc20c2a4089149346e1cd9a76ece7298a106114928fde6dc582366cf188f482494ea2fd4637a0da5d64b04128acfd1fea6f5bd3333c96186090683c9f02354e33bdc603749bfb77184e2e6a4e587f53dee32156984e2843a2d6fb241ccd5241146a8f4a849d4d5ba296a2b0b4c70344164114a111dbdafe96ecbbaca0487c90a70a024882842a5d3f234a78397687b25421d74db887542dc1a2a428442d9283aee4d13b6c583069143a86cdedcacf33194a76e08b514d7616a6fee0df1891442712f5ed3ec589f45a784507952a6235c9797da0c4231a79fe3a76428101184626fa7cfa16f3eccd9692a631009843a09b5eab29ed538d205843ae7b474c6da34c7f2f784119145fea05a3b9aebad595cf7abfda0cea75dd5c4d57d50edf3f1dcb3f141214c6c9f8ee8346b716381090e131764b420b207857639b285d499313ed2835a86dfe86f4b94cd394d1ed469f477cdb5654810c1834a4dab2b7ae656de944eb85f44eea01c933262be3c712ba71d941ecf658bda222ff45307b5c9ecc9af8eee9aed5b83081d1467a2e385daf96a74179983629a271b35c893b2c374c288c160308c390693b2e585e583122272508e992e1b460d1f74891c211207b5186bfa3f76e4aa0f0785a9f5419b67b54345fd0695946dc3d2b2f4bdc6ea06a5dcb046db5363cdde701b14cb938daeef740899321b54a676e24d9c2c73ac20b20695d0f112e34df44bcf1251836a76de4f53469a9a641449836acfda9fb75e1134286e45e6f8afd9dcd6427806b51a5a460c35d4749b0645cca0dcef1332b30697f6c932a88613fd1f656a4d878e081954838d971d543d67e5359131a86b7d98b819afece6500caa791bd6ba35d6b5db309130a8fe757c3925f46717361130a86f56c27b6cd693d8e617545bbed55c33edc14376c2a8f229ebd748c802112fa8db4cdfcdf194b9eb924817546f1fdab628e537c6676d8408175483ccf4347b90b6d5c52da8675fee2d53d77af769413d3376ce9f2324920575ab9bfe6b127a36d7a06306112ce8695e1be4ca56e40aca114bced8fd88d51b3c616c796111b1823a6c355d83487f533a97c30c9315912aa8766e78f0923ad26d2c420575d01bb47e1bb5b33c9d8a4c4161ef49be721b930c2252504c75e57ed376a1a7068944411dc2660fd161fec9d14a2f884041b16c10dbd5645a69b52d1c8c60107982623e6cddb35053c4f94e50cbfece1aaec6771d6a1354bbeba58b313dc7f6be82081394362f4bd71837224b50a7b506716be7ecbc1d135182ba95da7ac6761a6ee7462409ead87b4fd3382143e92882049596df21636588167b4cf8851bc750e9ce3a4db39ae94a9fdc180abfcf7f333aa6d6abf970a3188a6f65ebcf3dac6cf57961519889c40d62a8869f7da16d32b593580f439d7632430b7de39a67094335dd927179aea6392b4f30546a72a56d169b75f788bd34941397cc4bcb8a4b66f3a565c5456f004335cdf636fb7a254a676ffc42692e5bab5b5b7ac3176addb1e66fd61e3266bed10b95d85926bb6f38d752bec10bd51cb4ce1ba3436d9dc31bbb506b5772b4f09cd3a45dae0bc516cb63d593c89bf6cb856ad2c9c68daf3d0d6ae3156ee042ad85a80d2546da8ef2dcb88562c7feddf8e9bbeded862d146ba933bbd9791eb41a2adca885424d5a676c7a8f3275a68562ceceb66be91c553d6c16ea133a5d788e2dd135cb3268891bb2508a56fa8414e9ab7ac3b150be8efa1e23436ebe8485e2c6c828b1d6ff0ab5991a6abf4eaf6954f9862b54dadf764787b16944dd0aa54d5e2b624c17ea9e6585d25344ad11577535ca56a19235aaf72ebed4ffa90a758df13a8725447f186a4e18cfb8910a859e984f2fb66fcbda19154a7bfda5936c59b369ce29d4a73ebced783bf6564d5328b4be213b6919234f3c6e9442a5642c2d47ccd161bdfc849159caca89cee006295463cbd167d3b4939c7f564e322a2b9965292b2788851ba3506bfd593add8d1d7b93525c45062638ba704314aa69692d5ebefbffbcfa2f28889fd2243fdc0885e2e38baa2cdb7a6cb840a1f0ce1dd48b35986c29fa846a8eb56f4e6337d94eab27d43a8f144fdbb6da4b6685e5c9c18d4ea8e69163d2636cf52ebd1715941d89130a75b673961d624daf499b508889396f43ab5186276942add3ac41977a29536e9f09c5f8daf146d93a6a12c2843a4df3a7211e1f7cc47b0985d85afee91872fbd96309e58cf0b935744d3acb572554e361ea6f9376dd9e460975ebdc4aa9a1d426a172176a948de1b7ffc613c6cc4a105e25c398279584426c485b931643cd1b969f09831b9150bbf999ab9b4b77e85fc60d48a84c899e359edcc46d2d0e9324c38d47a83f479e1237d63815d3e1c20d47287476f25b3a488f531ba1d0b5b536136a1a67f366843afbed77b895576a30111eae1b8b5078cadda961276f8beb84d125697043114af3f9dcf7504a844a7dcd7a849aeb438d364428a62717ff30bd43e6ca5e8db592a2982a370ea11a6776b0114369197384f811861b86507d94b18634d337dd9915d63a6e14423de386f57b4abeb8c1e60621546a2747cad24a8350a91b29bad374675edea57b2c33306aac95140c06b3c712845a88cdb5fe94485752448150bcfc9baf663544d73897913030c16182090e3700a1fe1691b7f3fe57b4e70fea329bb33ca5e2f2c5d80feaa496cb15b1e6b610651f9432c4defed59cc5db6d0737f8a0dac93e4b1bf586d05ee23051c42331106eec41615b7c56b6a30d43c65a0f6acf75b2e6207ae6357bc278230f6aadb47bdccbd8cc877850095927f506f5beb7e21dd4396bebb06d3adb195b3ba853c614f19c5d7f23831b7550779a6fa7bcee0e7db113c64c86a5ac9c5caa1b7450ebd70db2a4bde6a010427f7c31bc5e8dece4a018999feb3a4da3db9d9d2c1e83152064f11d872f37e2a050b3ac97373f1e74f67050de4e367a4d4ad6eebcdea03499975dd3666d6d6ac270c30deab8b6846dfba4736ef1500a37daa052aee63de8607353b8c106b5f86c7e83fbbcefb9d6a0749367a2ea7ffe62ab4121773a372b1f62898a79871b6950e8d1aaa7b52753b7c6d1a0169b63968b16df6990df388362a7880e7f3a7ee99ad4c3531a576e9801356354c30db11fea61bff2740f6e9441b55cc9cbee58ff1e4432a874960f37c45a5ab8561b83dabd5f4dec10f3efa21854b7e6aeec9a6edcebe48d30a83bd4a9bd503af774270b37c0a0b4715ac467beda34f22fa84e6ce8ccabdb277596e1861714e3cfece6ac1df1db754161274f4dab75b9a0f63e355ae68a4e18d9c12d28e7753a2f427811a8e840712101818b08be0020f87029400800c098c32c8ae850f1946581207c4bf33b565a40000f5c8a804f04272f2dd0010bf4487939d181a22282c31cc6a0066e7cf46844200000bcb8f0a041888dd7e13c74a8780ac9874b891a055017141617808d3800c0c5a5c1847cf88b33cc0d1bfee26ca505330200900694b4fc8b0aca0a4b468de52f2e994c0100600301232c3bd87050322464ac61840c351c94979413174f430f96858683f2c256769ce1a0bcac81c27864322564984169a74eba52fa6dfa4f4fb8137924eef896842f2a283320a30c07e5a5e5c42525932921830c2fefb2e37788903106d5f0b3938e6f2f9d352606f58be1e97c6df66083ef1206859833dee59d079bbcb5e3773022030caa1342ddf650ebcdd58365edf81d68c7ef382e2a282f29283c9a4ccba7a09c914666c9f8429290e1852e287a5141e1c1051547612a9f92d9b1e20032b6a085969685049081851620b85c2185c70e2b343c5caac09807800c2aa8e408195350c9b06f51595139001952409b6444016d920105b449c6131a4086138630841e4240329af0f26a2c1e4d06c960c2a7a0bc645cc85842cb72c9b4bc0e9567614161d900194a40160490918494c5e3154006125a5a014a8ea192612b3b322fcb0025c648969651d18192e20428290631545432293c76b810a064182a284258696161f14ce308281186b2951d2793494049305c5c0125c0f817d7f12d3a74782608de0281925fbca0a8a0f8a2adf48231e7456686905979c9bc0b8ab724a064172525ba6011c267525c05850025b950c9a4342ca3828b9486655e052585a4e4162a19969595944ccba7a4a0ec1840892d5e6525e38292496469b5486471e181a2f2cd4a4b4340092dd02cdea5e5d750411140892c104bcb5c0f21c4e28670d74308082881452249c92b94a5655c9159283b565e5652568f9580925620969649e1b163a48415892c2db30a559094a4425191a77849e1b1c3142e293ab214498a1c458a2243912425a0c84fa427848080924e2427721342d03e0328d14412a024138989bc04969151412940892550474605650025951842c685870aca8e0c2576121b846f6191c4108690e9d164d64061252591409b19b6b263002590d020644e5e56569a4ccb9fbcb88e07943c621da141384049235e5278ec60444a3b40c922d648d1917949e1b14311082849448a23c20025875039991e4d2685c70e02941882316704282944cb4a86315f4009211a1e2e01281904633e801241b0b4cc4b0b105c464a029146c6060c280104024afe6080123f1ca0a40f2a3d5e5832a7a2c38500257cd03e0328d9430a014af4c09807a0240f0928c1c3aba0b4e69995970394dc81a5b5b0a0ac6f1940891d541ca55959fe02542a2b39ce70810cd06840491d464ae8a07d74bcca1240c91c74bcca1240891c5278ec20a3240e2a991795951d99c5be250025707883074adcc0819236a8c5cfbdf575be390d6a091b32162859c3044ad450819234642e5082060c949cc12593416149412a314319c8608192318861022561804009181450f2850a947881a12ca0a40bcf2850c20593922db864b4e0a281922c5ca0040b5a72052b74a0a40a54c840c914a4208192285ca0040a57f20497d7a1e22d11287142131e50c2840c0a4b0a4a9690020794282109990b901c030424c628864a5f8f6e3572248662eccc08575b2df1411f86ca842c656ebab4163a8fc1b84881441816200946044880a10e69b3d237ff6cd0112a82e417190990f8020224bd9000092f76a13e97f7553df7843125c5395f5076a0a408814417b95028312d84ad7ccf721d5ca875dee7526bdafee359b750b9dce87235972db1db423973d3cd9e7b22555fb550cc7cf1b64db6d69f332dd4f96a14b19d6490209985f2659c7fc792ed598924b2504da3b87c8d3a4bd4dab15007e575271e33c5d6fe8491e1b3f4c88183c4041258a8a3e7bbfb3ab566799b57a8e66ca5fc4ebe58731a7485526545d6a06cb4b1694d2b14fa732ef9187b525d3c502061856a7011f51d86e8348bf60e24ab508cf0f89cc4dcb5d55915ca5bb3f93cfbd77c29a642a5ebcbb6bc77ad3baba1429dd60619da73df7acf9f40720a95d265fbb3325362b78dc414ea11ea6b3e1b6f4aa1d6ede1f1a52935ee4aa4509ceea06cf87657d2e351a8cfd4b0613fecc55a8f4414aa79c2a3dbb4ee6c8d9724146a37355e84872d676b3524a04000c9270440e209f58d6be26b0d756b45ef84da94a8c9e7383ad97e39a14ec3d233e379f3faa34d28f7b4edd3f52e86fe3c892614b7edb6a7bb2e75434c0b249950de5053ae6c10e961e7280f4830a1fe5e931f6e9396b56685e125145aa859bc4e369977f9249650d9ecf15e2f7488e16262cb0b4b092b482aa134354defadb33edf17524235acff4d6b9a99fe2c9e30321594b64c058505188c0b7e308164120abb97ada3a74cbb402209c50df2e2d3a44be6f94a1209d5b8694a4dbb46ec1a172b4820a1fcd17359363ddcade523549316a66d16b5949d3885a1645456981d44e208957f1ee5ef4ae5c55a2f492314b275ceb7b65d46a84efcaba91f9430253bc9225473fe645c88d20963eb2051844a7c7790a6a7446e4c13a1b8ffb4e1632dc79e914666062488507f89db74c36dbdd97f9243a8e56fbff7ac77792a2231843a977071f7b6666c4f2b843a9ee990e7e723cae3278c08910a2484507dcc9a1b6dc6f66d2dc92014de9e5e6ab489ad2b1384e2ec66cb9bdaab393556564e3e85a164ee1c4802a1d22763b7ed5b73dd3c02846a8952a6b43e59d3863dc91f14324d483391213d4dfa09a3cb0acbc13290f8419d75f692f5a5e66a2639ca30a3137998a06186499e3ea8d6d5a0069ddc43466d278c41f096cc7fdb2990f04135a80f7d6b1ae665ed1be6d280640f0a2d4d6fb49bbaf5a5cdacb0453d283fd4fa74c36e193533491ed4baf37cd66f211e54b366f3bc634c720795526b292d4798feb8cfa21dd4b5dec5fb3b76c2b86c20a983d2c5ffd938f1e8a0106a74b275d3d77631cd4129b674798bd3e6eae3023556564e16111153335a3d89384c2ee939238d0c881348e4a032adbafe42cc7ad2b313c6fb01491c543b7fd89a72d90923421519e048494981090e131c26384c941e2e091c6e6d33e76a7f43f20675cc5b36d9da1f84bdd60d6af9b6fee36cd63b46923628bf6628dde176869e07b341e972b4ba59f6bbe3a97790ac41b5a6067fb5f9e4cdfd93a841a5e6d65ef346c490d7af09246950981a9d6bbe354d626d9a040d6aad67d6f05d6bce376292332886de0dc3736efbd9d60a8919541e6defa7e13c4dfc2b9d9146c608246550cb5a5ee323cd272183fa73f9dd1c9b357496c7a050575b0c1daa6efa8a412d7e5ddd4e62d334471e06d59a50f388b9b6c3781b09185043addb3e115dd022031764a313245f508a12b93fe3ba841ed30bcabf61f42b3d63cfcd320948baa0743b616aee347b6ddf8e0626384c6e0626384c0e0d131c262703131c267786091a6698b4bc8a0a0a4239907041ed237bb6a869494f6b5045751682640b0a99fad284cd77fd3c6941e141d9b47316c26f6f9c240b0ab531696bbd3e9dca48b0a08ed96fcb8631f6df92e353d468f918f05981e40aead91b1b62ad4f3b46c80c122ba877ecb59a065d626d915441e9f1e9454da30d151426e5feffd48ca5f7e980640a4a9bd42eb5d3d420b3b648a4a00ebb668cb6d769fe4c0f4d8d014914d4366dfa3a7933766f100aeab953b3347775a6a6ec090aafb1d696aa763bbad00b8913145fbedf2d7449d13788a4094ab94167b19f6c4c50cb7fadfb3b88f0b4fc13461c262668d000070e13843c4c70a061c6c904c91214b7ee33d3e6d85722dbac018912d4dff175aa69511214a386d8881d5fb53f912041e12e869b8d6b03131c3830c16192031334cc30d963a83d4dc6669bf746cec650bb8cdf38433e07d5ef8431b765a418ead21fd6b40659576a163194b6e65659e2c83054c3071b536c9ae66cca45f5c18830545e42bc96ce73afa6f1483014a2457e0b35b1cdc67aa70523c050a8dff5f431b57571a7f8bb645c504e1923bf5009134f636a6df27fa12f14a3fa354fb874977aa6498e323ea5417971961dbd5029b1f1b6b0354da24bed84717179a12eb1e7f68c8f9d9d86adac71a823bb507a8f905b636c1232e309230a4674a15cf964afc48e9d9fcd13c68c0b0a270c4672a156c3e43bdc8df8a44c3d4670a11a624d93daafdf1c76d209e30b0f9674a9466ea1badd33628c31bbe7f38b8a2fbf416766c416ca1f11d354c606bf1b1edd3c6e0c23b550cefe9a6aa686dd68a3b450cd9ef38dbefa5eafb1915928747cda39da36bb35744e18fdc53b4b30220bd5aa68f5b469cd551c8985f2e6e71cccc76e50fe21144660a1fa4e73f973a567769a57a877749af48de9778ae70a859a948d5d7a6d124b47ad50de949bc6e5d520e245c90ad5ad355dcd29abe6c2b60a7554d9276b98a949df5e152abb79dad6a841e9b6e15428be4c0d79636cab39a931c2082a94eea6ebb5b44edbe6780a75b069ddd03a6dfe942639cc3031854a8921afe5cfb8d9e6b114aa174b9da7d17ff7a65152a8cc84289d379d8d314d1500626414aa2dc673b09b839bb651146ab3a92384ca16ed4a140a956791a21f6cda2ae207856ad9b4fb69d826b25bfd846ad21eea698d35ebd6c613cad123476774ecfa350f66501313239d50dbfa6b1b44985a3a6d9c50be30f934d5c784b7b709d534bd386de79f2654def2a6b7cf2f1bd294c3482694b663cd39a9e1d6fbcd423c8c604235eb9c96a749bd6e7ba1278c5c42f949ceddac327f4fdcbcc004470b4c7098946182c3840526382ca17c99399f75100f595e25143bccc8deda5383fe382514773276d3566a98ce170693869149a8d4a4b6abe16c9be99abf6144126a57eba59b5a5b6b3251245493acf9736aeda861dec10c12620412aa41adec38f667ef61f308e5cb08efa09eb5584a4d891147a8fcc5e776b9775bd91206733083921869846a125b7796bf99bf3d32c30823d469f6d63bf170f11db408a5ed60de5fb6d69cbea5087534add53dfcce50c24c846ad06f1d4488a16d3f8d08f56d79ab676a1a445d790895761d6f07b3a5d69cd71143a83c7d891b6d3a0562a4108a5baf7674926a52840d21d4b23cc92f213266d83e08b56d5be3634b9b5bf92708f59eace9215e8bb16124104a535b7ab8f0b5f15e0b0885bbe8989c699b64df3fa8a367f92cd673bc4c9b1fd43aab08a596dacccbf1d430d207c59659d3c48931ba7ce6836ad79a8bcc5a4add6eed419d73bf1a43d7299bd3a41e54defba35c287f35d9ce481e545aea4d42ec8f5763c43c46f0a04e975b33536e475d68e40e6abb3db3f5d5b41d54e38bdcb736a1d634b21246eaa04e37e7d6e2617e86d62d61840eaa3ff1e1faaf66b5e699098e488ccc4135d64e458b1763bdf4f8871139a86b994b51f37396df180795ba9735bbc9b2513f0e07c54757eb9552723cd8fa06c52cb92b3abddd24727283baa65901925aa8c471050451240a053114c33000c041a38b000312000018181a0fc82422c1605976bd0014800343403e5a403822361c0c4763c23828100743a1300a8228086218868218904542ced800e3382e2137698e2d8eead4b1f8ff28f1ef185e4f570c6bc4e873d141e7d585f500ecf2e8e7b1291c725b86eb3f3d8d6391a01843cce2f5f60b1b5de82723902780a07758b8fff9a32b7cf744c616100036fa6830d072085938aedc799ae3198ba297b76b40aeb41d9d72c315bc1d2938565d8b041378cf7f6da1cf39ede8e18bcf5e4a167cddfda89c589ec0c024b081ba6469d9d03b3a284024a909255201698fcb29c3b711fb72c4372c26be4257a3d1dc2fb233e61db0108179b71f43d280322000eccce4e7c0041ac1da9b55bd8a6d21146e6ca659fd44c99f60d062654e5e683576e5d6367182ef8d79e642060c46eac028011a97dba1687a0a4c4081e2dca3a74c33c87bfddf07e7ff4176405c78a4dd9e3d2a936e26f683d55aae709a4d0f636c86f63baa8e6a3486bdec56dbaf6539edb647a083e7e1334f224d16685c7260d4ff488658223c220396ca0bcdb498180eedd98b9d608749f77398e165877aad59ce52203ad535a2e2ae33f6aea714993a6963c813327aa57464b3bd6a738a1ef10be15eb3483b62d21db87b0a08e902ed49c40de11979836e5ceceb4ef9e05105726ee3c7602531a03fd8cfb602a47d75c8700e65e8ff334974051bd3e82ee0ea685a73e1273d68cf8692f8211068cc60ae1f43d3a19e9520bbe87ef127813a472b483c90abaa6e8865ec30b289adf6929749492a564ee0fee1d27301b83724593afe92ae8f841682368a7024de78422bbe78228b7390e812fe08a5a744669d5a21e2e669b8959e446b1e1257a263468bba8843f5ed9ee4d351d44662f1909f7a433148b5385d3e94a0b37a753be25468b0712d66123f5384cf34b4c7e524967249fae42741183234f43c8812008f43e74ed79076855722fab33c2d594287255151bf6f6f83ef0511f6c8cf9df787e2b3d550b54bb8aeac8c4a6cd41872dc1828e6f17c3d8060e2b814be76b6bf89ca6b1b50cc74275fe72e71269a83c4f80b5daf684d1cb42c7e47b68b2bdbb09cd38953fe63796f2990981224494f8783be3ea53c71933cc6d21169111da9f6b1507c42f7e743aac00ce8906540d5eba0af97ad28ae0ac618411f45d43479e3acb1787cfe184bba1e0c4da64c116196211a9734b49143dec413f4f5febfb7f726728aa4626fda34527b39f4c8dc444c148da738d76301a95c7c7903ac2de19c04d2c81e248bbd50e86e9529eda9d77698f89ccd5c9b9251b4b1e5d04e840f2be9b1ee7002fd02520e0ccfb39fb2eb14c853b1fa0be187846609d2951343a2f073cf5a93f39fbbac1c9a0bb1289c4504bb94515c2c3f3052d9d1f95abc966056c7b58d1137502e391dc6a1bac817c700df210fa089f9c74a740c14ced786e175a4f9631f2e3fcbdbf48ee7568c9b731c122aa19ac1ae2a34f5c1c8382eddb9aa398f2f0957c0a5d04bc9c0454bcf7e4e0c5f22f32463256d2c86368f517176bbaed3396eb647c9ce85da7972a167662e5c0a7f9af81f7ffca9a61875fefe931c7c4fb395a724383c20d8c728c554963aa1e5c8321bd0b188ee84346d9659389bd9aa58c736fabef23c199720b3b19900cbbd7b8a7a4d2f209aba94da219e4c233b0eeb3f4cf2828420a0774fa4c9b44f688b54ddedddc0c19d7b1f4361c0e96f49feae4e28eef7ca58590088c4b573fefd16c76eb7bb66ba6394614c543b43392909c082c6e742f7a02130c33b3d62bf1efcdeea321472d3dee5a34dc9a4c40fedffe7be64b0c3ce217c68548b1f78a3c465785827af60acdb59b265215058ada11b23c053e5aeb51d12f892bbfd09d471db8a9d9123a17c08b3897c7c347d15caa40274266ca003b106c4cfe63a8e550e317dad79bb8340239c25fe3b601edcceea612d2c5012030eb2bea9a306333186c2a649db9e1b0dd86f0f0cc588a0d45eb6a017cfb61895c33288ab3d0d87b8e8766a4a9a6a376cbe5b762afd55a1948fce1a7ba6e96ec58d0273d6c2428ea467504829de3d675721181e4d067a806846d5000f87e949dd74f9692080ed13199dd401f3f0047f2c8975f7604bb1ab34d172faf34c0ceeff5c06d52d1f4683732121337c7a256acbbeb507798b083a4fbf43d8b3b52dc9a1e77b87568e7b8277e114bf3aedee23b96cac828c8fdf7f82c46a415a46bbbe13def111f50f392ca4087cdbf11a15304daeb0a3b4175ffbc8beec93906b227c52511287267821199798ae3c1fc31c9906bf72375ded85773de870e2b1ba0ec125a66231cfb0410098566f6e3059d0fc024602a21da7d9fa140060a3bfe8798332f908c57e8119521edd076d4a451757b0c0c74aa9d0ffabec6fb85727b213203f0edbca2ee998b06a20663ad66452661b54545ad3c8b056982f20c7f4ad7d3ff4a2bc8754c272cdcfd0842f2020562a892981a41a1a60a3e426303ad8d11d2a38908aa8faa2fb1a6fea9626c1d205226c2a80004998d7abb589accc2f246c07c0189e89404ab284b0f3ef42086f06a9c57ed7eeb57eea0aca87a9d9cff41df43c0bfd50b59d7c39732ffb590062eecc4ecf8cb8c9bce153090cb3c6068b2e2ddb009b51eb705bf95330e58c270c8a83802be0a4a16702fdc49bbd7f9de61a0a8fb5da9d32fe6d95a341656b05d73bbfb8cb5ed43a34d8a72cd82a7148bb770e2b20c488ff0f601899b35110504448a93d5e95aa3adfbd7160c039f7e037d4372153e598bd0d804f650f1d577162a512d46f86e5502a35010d4a86f1974e559eb5d0ced949baa4fdcf1ac8c42393bab727d560734fe73086cafe134a62ba46a934482d99acb19622590e147113fe28c9a06ca0cfbdb6f87935217858c0d036e2861c0be59477fb5e259b910ad38ea7a048f0fe3d1f868808305b00a74680ea5fce810de1dd8f175bb9a045f2064897e3cf40eede078c6c8e0ca13e02ddccd4fc89585951322d1645ff481012a4f1e1896728a9b45a253d9c54889ea70274cc69bfd51b9f56cc88a7e4d4fff2109ca450394946ae2337c1328e68b828442b59e0d760532dc739541ed92c934079f0931225c3c838abeb1e07e8ab1d4d766f4512bb56aa79605f9aae8e75af92998d9f75de9ba73eb8d862398686b540b8cf7cfb944bb7b2e87f67fca31f1d4e375a2dedfa4b1890e30c3d735b0302621468af929e490fc03524690735b2172e44fd3b0f2bb0b3afea628505ccd59765545620d72144d61360d8d2fb4e6aa6ed9a6e51c86ee3cd147efccdf6f593d5f14ce726f4d3ca228e9d6bb3e714ec4cb8d46cdc986ab48c9ce904bf4f6d3d5695ee64340506fe9a90d92a4caf039716729a9ce0c43e1a3c3504f1d690117b8442ef8890dda6f0ebd543f933617b1be5e33d06055b35cb26741f6a9ce5359e851288190211ad07fb37d9030c64486a0d3520a0fb991e5e937523f1c89413487ee82403898f7b3d28df20e37806f62ef575601e7e0bb1c823af0578fc9108048f2b933d31f773156e5d1030043dcd6b099a78d24f55d8171635e091b4ff82b4b88ab2c52b1906d2cce80d03819c9024702191fa22428eec242975302be3a8cc741d66b5390d215a9de505a40b1aa43728f04bff62590480a1bef90e04ecf4cc98c8131a5b154dbd7ce4938ee539bab5937d962c3226516eced15d38d1b894c934b206b5df3b3e3c0b3c920b604f185a919f93401c520e1c096408798304c862bd96c9a4ff0474b84707e1c5f45213378c686134fb182ce1484b7a7d0a4850448d8570e1ac420c3ef42a590818e146fb313f0698e8cb5417cd19dbf4bbca2150afc85e3d9cea9d8c84ea2a64eda4da9a65d36e739ee991506c0b9d70854066e05fad0728ee9c41e084dec7d5b1b2b53db31c9983cfccd13dd4fe59423bc12f2fbd17025d03d72c9271f074157828d0533f6f063a16e7b16f4f5cfaf478a3578380d9eb87ecf6cd985ee6996af8c8146035cc06d060805d67d060e1c9f2ed6786da0662077357511b4a5c1983f6fdf480664f484c416f3cd4a3d532e6a0262c31134c479f541d9cdc74bc0ac076fbf17d569524dee868a5e95b4ab18459c074d03721f854b4d704d411515971456af1776805a33f27d0222f4365c417dfc742ea12a59f0754fa67eb0938562ee817da58d751d385784b128a1189b854caa4eef97c12f47fd8f39cf40e7faca9d22ed11109ac796619bb403226462e82f3f759932cd14449e1ec0c2ef0c4f1fb9eb54de56d17828e38fba96251a1e86792c551dfed97b90bf664e3d6de45e19a1da4c25a254ec3a6417683c239f40e890eced301db0cc7bff47b37c46c1b78665a3da1c89469a291ef068c55760d1e2d3f270e698611e84522d5f1f594fd3a5fa9635aa3970d160e0555d07a4b849bf1841f4e295f552a51b839ef6cfa04c81f069644d7e8c68457f062318caa5ceba9aeb35eca13e9d678ed8d9e8f091a576c6776bcba75296723e23254107aee39a957ce2be29d5f2c01d2e0a48fbeda00e1a8a2a9cd7890c7e4494301d2009753f55f4417b7c2ec347b2fe687fd45f2a303664b4fc424b584ccf3ebd1803c87e0d6107ea43c8a695cabf01a01278183c607f6b363550d2260bc3f2c7f78eb0e0d080e294b58b18e111b028d84426746dcbc33aa2559616329920bb9defd9486202c2d2c811d454b1679f24cb5fc6cbc303b61efc31e5217c23420125e228061721c9ae9f78f4ea95a110489e5768ddb951c4aacda5d45c6528ee5e4cdccc4ee1ac1dc0a332a28c44471269e9e9fdea113bc8461350fa4ba1457cedada2ccdb7b955ca73383993cc5b19e65ae8ba9fe7d24cec0abc17d99e2e59c88b471832e4f28b2ce869c97226099d5e10c530b432135d1c1b3f852eac7cc9bf6f29082c40242f81fe94e54766516b9416fac52b151f69b5c7c7097a8cce151bece22533314b1406757f280987c436f048c58a03c231d24172000fa4eab9434298ef9617777ed1b8e274db4670ba0513ba3280c87e0b63fd102a5f6da6fe21919a293d529e971e309a6905d8f2c348e47bb3d1d334f1dd76df70d5add00144d74d91d946758149c0084b22749ca3fb878ad8495e9a6c1fb538b49da28c4f03178708a02ba12882126b0f9b07a8e2c796a8198fb20be9b7a6d2529b79985ae2f4b4ef7808237dcedd63742c48d182c8d6f4a3fc42693a9471b6287544bcdd591a86d1c3a327285679b50bd51fb3f2daa72a2710d6bc20fc2297954d4418a857809a3adb17f9f2145127bd9c5fa63faf78977acc18428b38fd24446bd942f7acde52b0745bb13981a00f0c310fd9c4890071d53b7e6e2a06cf5f484466febe3737080c2e3f76094b7d681f9078a009ec4e708f60ec4f647759229335e38a4b1e395accda83097af0e6100723260304b9b4cdae532a0c335ff836c1a0d99aa38abd51862797084c649ed8976d59880abe116f069fa713a39e393e0b198ca921d27382815978cb691f192834652012a0bc084317ba012994d4650cb546e3948f54f818c17da441cd51dc73b52a5976f050fd851917e51b81965d6e6e6a703466edf26b702b269986f1c4cdbc923be604353f16488e8f4ca2ec6d1293493852ec0e434e1b6bccec99c140ccdae8d7e1f29d324dc4c3c64f9087965bd5348f91b0428a3ad9d7d6887936c2c603c90fbba45b7187e61cb3222da26d2f0f71c3239da15ff60aba6645e4673403de59bec3df94a65fb87099a895fb7a7c3435c8adc9032c674220c9960a0002c14ad6ae616eea009c4b50816903e24549a73dfc3f383ad27146926e31008e2940d2cca33b76101fd62a59e25def5f916e40e08e85b67e3b97aab1aa1c4bc5ebebc0705a2266f6a0f3b8275b61f51487782fe6e39a94da66b0614109c7ae869468bb5f6941ce5f75a0b442aa5d2c9704438dd51ca9ef25c05797c0f2b1ddd9b0db89f9f3224d9060322531feb8641e0972ccae303936efa3e80f3621bccdc24af8442a71589f4cbd681227203a3776cf9e2d28d89f55c77eac0b00a9a135bca9966db06fa21e2b3000c5906089552085daf15d2858dc744f971e43e729b8982ab0d0623a702be1e4417a9629bfe70a41a276a29790dabd61730187c14587f80b3ce4ca618e9bd4179d4d69d1ac97a39b73948f73432bb9d934ef5f4919f99583032fa1b16e2b7602779ad503e4393163a8ee586564b747f8635c4713a6846add15ff874fb2b39ae8e3fb32f9d732f5b090391c0a4010f6e4372c1f8bcb8f11984fe4f9400d9a5d02e316210f42d58ad1bc3e7ebd328394b11f3e7538db488f7bb3607a99e1e0b04f24309e10a9da993c0a31ebb200d5871a5f30e6aac0a54d0299e6145dc23556d7a24f8c7dac7ab99c2375926aebf6216dbff4c84e7081f1c19f475a336c34d62f6b32969c8f524e62a7a32ada66c6fa1c88928a7607a8b0a57bb37b5a2701db6bccf30602ae06eae5ced87195312af65f6050d33c94f413f55a8bc2a24a471e7713969b3dd8295950ff333d091863af140cf9dc6fad3ab20ecc186756d721f138181b02c4ffdbfd797e0260f1da555780d355cfb1bf2220b094e48fc44ebf04b28b31a32aec8bb62c18d727479014ee4ab36b4886f936895967eb6bb5c2ab0c1f2bf67f486354d0cda0b0b503185e93bacf4290aea9988c8df08d342923a3e64327298b2f5a394c219370e8d215aeb17c3bb9c0918a242b22683f74049280436261b579f1cecd731d37486c0d3a314d7929522a17c00fa5f41f3506c6bb8cd47b237abbab1eebceb34a070a01e8582634ddc95de0ce10cec9c80e4a8cdd4358eb353ca7d5832ec97e1c873872282d28dac264dc5e0d6959a1a32538267b167e97faa604a2c404f25944d42302e072d465adf4e7891ce0235c52c92e64d15f04a4ac9d72a292a348b7ae593f423c6bf75da3109f5262a45a964631cf00e7b6c6a90ce7c07b61ea616cb0fd9f0d4f44a72de3e5783a77f0f22e64f40741baab16a991996673a47643c07dfa2486201b3086bdcaa12a084498522db7cea21567bb30b8bf9c2131b9c82e085ebfc630c6ac56a93be61df2bbdbf4f0247d0a71a7ebd7bae04210b9884fb72b958cb12df6ed10e01cd725bec7cf9304bacbc71761175e624b4a002ab2d1057b44313403ec13f219c10ed907b258d2b58bacb6d601bc450e7c575222533156efdb2747d9b3d998ec3d60b0bebd37fa0e6786d35af6d16e00f4dd0da297106e41408bc4b3672f873230ad268f2d986ec304cfb5671a3517944e7570fe66723f1a8416ebb4107d896bc5ddc59cf7e76f0e3099430763fda5ea1ff59c4084715a2483a20a44354b4b78fe8e2581f04c23f2e9d338560f1827b34b09cd0ed842bebae77f86dfe3d4417954c8a55ef17a35f8c49014dece4e378f3774c11b341dee8dacee49b661a2ea0eb04aec712106630c8c3194dca03ffdb62b91072ed10161be9586379b45b056eed02d0b0f892f259b3f4cd992dbd629767cf8b926a3497d68bd79345d1e2b514a6bb2bb3c6ed6ce84be60c8c5717d620b352cd243ad84ea3989c9d1a774d2cce7950b53856bf11ee694527e09b74953a630a6c1027235071c5a0e3f2c6f76bbf4f9adca05cec1bb9a8dbb4a406f76e5591b21cb05023c032de96e00e2b7c91aca435bc6d1af7bc3380a2df64151df5581437826c394032f74a11a780ed3feb3dc4d22272bffd035ba00fad24dfdbcd762a21d425e4cc3e9c50bed06eb2efae9a009875cd7fb5d697b71f054a48d30e485b419f9b5b2fc02834c68bc25e80aee5baf5ce41df0f65371b9f5255a47a8320ca8c80333be66b5e0403e28896df8f2ec3b4745866a43215e70057c73e2b27f424d69de6e1660860e466926a6aebb53596da7df65f065a9def0f7a465af3f0d842a08eed37782f4c1cb93e4b834a45fd058d000e56b77439cc17fd024d38eb534fe3c82d359336a9b4e6c81ed1cf704ed9b0fdfcdb20407d7649c8f11315a6b47f5e40e909863f0bee6485c1a9eb113f9194515cf528c7e99e8743b1b6ed356b1787624aff20ac5824656ef1c3bc8128f0f8b1317f45090cebbce6183a5a14fa034c87d125781a31f7407c9f91f0f814ff8886db8959378a561c2a3397185ecac14df1ffaa185076b09694b59e87c122cdee9ae29549af680bcd95f85f29384c9e691298f85e899768c2c79069d46ed280f5633d50bf7fb8e7439dabb3f098225e48628e17e9e9b9d07584269675509c477ce7d82dbafe3be9264d8b358144d8d78807a04132ad19b34160bdc8182f6dd3a0ecd2f43a76bf206e91565ea41de92d3678af8f173d4a85eb66c3dd1cf615d85ec04b2a95e7cb87c91af50964127b5976de70ecde0b5e413bde8b73f97003886a4b9a30a0d09948b1b32088ce11bc4472d1773588c072fde3173e4b2b4342d59ba967f3a19692a86c32f3f558bcad36bfc9997bbdd68dc0f5a4bb5570cc1309112f762b07295965a1c6d459635f243248aae4d92dc04d27af591c47251955779fc5231c8ac08de9dc2195928503866688e75b37c2f71f15ed344669f5e3bfd06db579a26fb5e3db0ad245d13489c1ea0a4fec0d456081be0f9dc07fa233a23c07a02ad4def5c0d7ab2367242aaa61016f4dccfed198629d6d5f81f05af32c8c96ac9de94db27fa3325cec42dcc2021b855ec932c092b348ade8b0d6aa6c3f101d74e680e1373fb59d576267f11e3cd6c24453fb8e239f5d23474399ed5b2d168df60eed010000e00a80116fc4bcf9712746df1ab31ff675f8d07602a8f3d979b565b0d2b963537cee5d81480a16075a44f2a5e38cfe7d584870476bd07d2d60fab06890e5c7c27560d412cd8e38c40b2885210c62c7bb0bcce5617bdc050c2b9fb780fb21d7857f4561f216f38976e6bf329a8610a4d104441d50de6c80d74067d9e1e283a3b662a643680d86010fcee0136e4d0a8882fabacebe51912ca61a877dba19c58c3abc2006f40599f5e9bf262b88630da61d42e184d4fe6b487abe6b398b332f02ed0ca596985962192e0539ce7c294782d7925d774395bd5a20e0d845b1cbbd21f25105e23ee7fb9a0c867d23026f10a4382eb9314098772b6b28a303b426f71da04d43439628a422dc6e064515eb583b35e1dc90f5d39dda5bdeb53f80fea991852822dd800c386a209e67fcd635eacbea4d39a69f219332128369ea6c024a15b58dff194ef0943c6ebcdce26aa77c9d34ca2281da83d68b8229150856be6974367f1f50f052e9dbd5212a00e1a60f0a1fdbe0747ccb7d4fd8ddfe8b9416f23f881c611880f370aac504ec32a332114817305ba6b853e1712934767808dba7433956f964d087d2219c439ab60b8934170f19ada05203d05e4dca98eab6f057ce8a427b80a8f21acc8e1aaba8e163ec5b3755e6f26f0bf3172ac9fa79e6aced479536fb13a06a7d51f434f933c6011110125154829855b3f993e56233588c3f9dd1676933c1166ddc02aa29a562105d07d6710a94eaf79f9139012893d03252319061a1320f0b8d49e94986c979690850229dcac143330a0ca16b8f916186a7744640c19aec6bddcb8b9fc37d16b5a1470dcbf832d4118fe30c83d51310991bc4126b95ba11076a07a3a1a71afba930b9225570ad7e10cb7ad29aa3241961c900a6e23b12de7a4937392d8a790085878094675b4ef5cd85c270545c1164586c5c6a12787e120d6c7b0bfba76d95dd190fd186aaa9e080c43255f4a7632009215888ca69ce5aff9deded9bb2e8d7babd11099efb54bba69177d0b6a40c2f7aa95e1f55eb3d01146dd83d742ca9f58d20e95fcb7d079dee12f1427deea9caeeb10e353ff5230fd67e94607acef8f017612019c8c3634da0304b0fb605143aab75c4f010fc90aef0e452d9dc2104351107f6bd1d6fb61b4b52d9e64a79940e263f402a32afb4969de1d1dd9e4aa984b828e46846f91b43c3ae78fb1586246206a61120f5e35a14442771dfd049a62cdfb4f4a97d429e3e63449b2314ecbd9858653110428f2ac650a157d9011827d0bead61d1b18ad0446932ecb971b7824e2884933c0d8541a56ac4b15790067cfb30d83b2c142d18472f4f3e6c54171fc2c2bd0fcf783236e432a88aed5b72b5ee9fc645ec250d272d6b88ee32d0c4cb8ed65ffa76d2f34a07d3510036822291096724f72918cb07fe2e0c8c5bfd97574e1640c0ab5b6958f0d71e011dd16194dce8a425458f52167e18e86be458802ce91345a5a84606c7714040d4611860f8db52caa98008e67b911061465040a5907690169472f4eaad0b6aec818d2995626f78cdddc92d66c496231cd589f566392bf88f09d92c8e8f75297021c21484927154abc9e238b4e9b3304e8f0cb8897f5182e05a40df8d13a53f15f19dcfe04da6b71998b63950d46a0d5ce471ee4678d50b636b4659734b9cff23e5ec8c94a7752b66fa0aa6a3767789ff8658235ddbf16f733a6760dc2e5ad9fdae0fc28380582281b85028d215d73e355ea3cc5b3463d7912098be8b74d513aadccad7d8d43d1d9a2172c2d82f1e4ee1c14d2f526868c5a73d6d28de305e9a6e4d17b165ca561489af4aa05754a7037e865e3c23d8a4a974ad71a54773f332357b58a9defcac446770c67856cd29865b05d57b0ce9091f4d848952ed98bfcee68337fd8fffffbf45236a7403d8f0e233bdbad2412dd59dbeeab8353068bc72c0a553fc9da0530acbb07c82adfece48bf99b23e474089905d4258d282b827c74485774229b017c6e85b349500dac97582e65d84391c9ab7d9b8752e295a5467bfd50980a1cc52a22a5acf3195d5010c5365a0da788f13eba366784b53790e5ea590c15ee1a7df2be9f30538ac2430f238c1e94cf4450cca56667129cd0249219986871fbb4fce7826c1951b4bb43b95e81f78a102f7b968e4fd2c1052f54df0e0b7d5cd53aa99209c3827eae218f656e1ec08868460ce1720b05a39d0b66ae521630aec2f9339bd3435acd440eb042922862b08f5e715bfaf4567495b3b70511dc041bfdae3c4262bbc22b26c6a7263dc7ff0b25d1de772d59caefc34e10f1d525c602ebd3e648db7c5884b3256d41ed515019c4835151490e59ec8d24e4aa3061837c2a02c1808a0e250261d0868e35d884a25d3936ad92694f4535a8748128f4e953cbd4f81ad1641a7a67247087c1fe54f33e198b3d3bfe4f07d784f11b0baea895c687b42e5367030ca980265c933c6b3fb6f9b7ae78cd4d1ea5daceedf7619256fa6f03af33d5d8ea72339efd249ccb70aca8c0e02e816036e6f54fb343618fc93c0001196d5f216924e4f9a4b7739e19d971a78b3ce8e9c4da5add0c4fc98fa1d865ed40b91b48dd8cff56a4999723059e7b108327337ed6488c80acf10ff01ff39f14d8a706197332e523dbc8c61ab834162bb779e08fd486322b9f1340b24d5dc261867dd0d48ffd8c9cb6d56cb7b6a7b7e3955ab3210205a9b2cb5e41b41be1d24c8a19a7c0cbb43262c415c9753237c1e07fbdc51e8c6fbee7be6ab08d185c6cd79f7f90f4b013d35ad5e657212c0f307d49e52ede61dd6d01bc98a464b7e0f33cecca2de07000a7d2752638ad4b8b4978aa7e04c3779bdc3d27e954842968a20066403c6b12d86f84d91dbdfc60160f4c2dad104722121b709b226841651570574e55cfb2230c76ac947f6fa44321187b7d8f4361848d09dc0e5f71da613fd0aebcac03654f4ca8846cf9c862e535b6de8c751bb8202ed52158644c5565bfdfaf5a2876fc1e888db18313fe3fa96ac153494d3d98d15ae15461019746f3d732292e1ec06fffea91d711ebce5f376a67afc91cf079f15c4224096ff73d06f83ec9c41a8dc268554203b2e79f6a567418fee2b7558d5de399a1b5702b14b072b608179836f7e0eddb844908505627bd5bf9ebc371f749d20d33ddbe3d9d827c55549c29d8ffb644c681d08e83d409716f7ecc4a1ec0fd53b18e978adb109821c5e9efd6325d2f462c78fbe2cbf9a0da6d64cda08f04bbf82bea89005733084e1d4d560c8d82571d67e1e34543c4288bc7e40a010704508baf2f3a99bb118fab10a7c3ce561c6c9edd6dfcb4dd7c10a5035ba57019d5d3b3125fdfa99decd801eb6add119ff214b8e58c91a5e7387f9cc1bda624f2c120b40428c6f50d34d4d1dd900491765fe6eee170079522069df902504b2874fd80ad67700feca5b4df80e7bcc776bb034b3f05136b0c03d4fc0d28d271e6be895bd5161353ef8c55ca197d8de53b9cdc1edfb9ce534ff0c662e9b547e0f0c323fdd29ca02573008997833ae87cb6285c2d9528766f9762109b9461291f5c61ecd7ad21be0a53a861822065810dcbd8eb740d19dc4df9a59075af18ea7fef04e3349056ee248e37e0a2ac489c416e53d038ada05c9de209693bf5ced68212f94947698017a891331ff899ebae3441a36c40d6ccdc4b542935dba0cbabc392159f63b6075848024c4be33707a7dda06081833bcfdd5ba3126e5bccb175fd95cef2e4d55652a325a050941ca48c71cf730c5f2b5737bb582cbb1fa6f124c499e9aba12a6dadd4a19aebc4b57a28e203956ac612b36a469d2cbee6115dd3f98162cee0337e7ec4368856fe75b156e09cd5653e022f28b5634f048a3db7b472b614bf38d922b8af8ad88432f9802dc4ca4f4c4145e396b7eb9dcacef03c3333664f4454f91856de52700e04de9c592de4a19bab2c7906b6caa5d44cf7f81cad450c280dd23f47a05316f6c8917427eef01ef191bbc00b2ebd91164a7bb056fc146c46f3153a6d28c2f1e01041e9aae62204539377c1b494e073ecd83d2c88b0798f9f9e5d8d7f485aa4d40e1d612088d5027eecf379e84c5be3bfcb89a970b8f255cc378da69e6cf57442aecce706c6a5d10679fa23611b1ac16df8370a6061e289470512e808df903184ecaec0d2b3e053e9c14a226a8c5460b5c95a1782dfdc55e5b4c94c7eb315f98950aa6e4156001fbfaa181da155b710e0e8eb63a22c5c8b71654e68b520bc1a1d7a59c5a1b2568de3f53d33cde6984ee81ac6e77144de71b95f1efd449790983ab5c6759840125550243b8a3b6e1814ebb2017cd1d54bd392fa4eb0da2bd9392a27144c9eb4fbbdefb4e5c087fa1f40019943ff6798ed30fec4940cb3e9b2e0a4caf62391166088459a707cfb5e7f57ebcc8d32d695723491b8e591df625810ed2f86e52e56a453dc2ee24d9aee08dba62e911c29d55260025c185c1b2c80b16ad19826bb4849864a8ba881a9adb0bd844b44dcbb2c2cae96a6fe5fe9cd2b941a24e25471544aa88d88940d806ee40069158b778bbdb4dce4a5fc3268589a2b62c8b31f7af4d425600ecbcc30b70ae4e1bd2548a4ac30790b14b49b4705a216b1b279d3a299a30797ad6208555d2bfcf399ba49588af8d9e1c141e9f470148ba19f897a417740ab80d82d7549682d19fa246e197f5c71319f1294231fc8b3f0bd1c4bb6e1798356e11970b5d6b1623ac575ee81d623eaf8c263e3dd2c7989d14821de845498164dc20dce755673855f085f9af0999fc7cc579a6d118e5f76515a99bc6cfe449084be21788580cd84c360eb3e1954c8e601613e1d0cde0a86ff2022ea8614b5d0fe5438e015dc2756f2d7143090322763f9cea4892887610b68c2a694693072c13c308fe20eacb47d6412a00cf3b55b5d19b75c8c3f11e3c227b138f71defd1011afe21ec6dddd36cb7e230c577990ba9a9209e57fabc997fbf05828168248fd710f63f46af3954905875519e3482390fca1e1ded36a0bda7ed6190b3574c219bb61a1acf5129d7280119bb3b031055e26f33b708b587bb76542c820727fe6a6b8fd94c3d26f63e70f7273f80191df695b67be9c851ea02927dc16cecb5e3a2b60bf8d414eb567780dcd8a17c98c1fdf4a55e024ffb47156de88a57f99433a222407edc3f8773cab5a15eccb9a70e791d72821e081878cb62f0802e257cb171fd324ba7980cf6ff393051e382d96891ae8a999f2e3b0610f6f1ca0c842e23a54df45341c70e9bca8b4149f25249451eaef02e40e07fd16cc12f8ea3a642171dd8cdd21247c8e80bcad667f41a7c2f90b54ef2c67e870b0b134294ba6abc95242f98f4fbfe20c6ab41a5e2848713f5cffd6cda5d374875d8841f17f659c9805f7f519d50b96f0cad2482ba642ce83eb07949b3b7e6e6c046418a837a362ba48e3865492e6a64c8222b5865bda844387a0feacbc5f014501342bce33c8fa9046abf7c202d4d662a59f12de7d7ea2e5fe70f28522f28dc6657f205d64e8d7499a7d5b557a4a9e8bc41c02256949a837785f1f875972c37824ef4951dc96d020d1eb5384e5a903c841151584372383381b70fa72783437758b1d211b5847995a9af166d740996c548a41388d1cc006ce06cc068eece9ec93b45cf9d707412f505db14c135a41176a11532c4e668be6b153b98cc5d1e3cb304dc9d7b50ce7f173f31cb81551b611748c5881b3ae099a9b8554b411c2ecbe8edb8f11a36b339847efc53ae3e46b2075980c1f6ddb2ce13477b1ee0dbdc66797dd4d93a82b06d99197582fbca18b5e62cc95b35b0a054ff0c523ec97d838e5a0727736f1e55db2bb80055d8d28c1adf9f81a746c2151047a5d96c3d56413d5f0acaebea9fea8995b2a00dab3426d4be016cb070b34adbacf2d75e6e8a2d31e45a980a7f7133556cd2e3c50cdc7d584542cd71f1b978ae7321383e86818ad0b8c0a58c086547299cf36af7a09e992daa1b0a413e14712f9cb093ed2afac5c8e9d72cf507a6e8ff001ff73172a0041bc03ac05e58417c8493738669f31753e62922a9d86a1d4c78aec83140c964b5a1af0299f469492e30e2ee9e9230f30ec81b9ad3e0996a9f0f5016790f9f8d80f7684870557a93e58cade5a69b4bd405161026bb28d0a2eb1e81f476705e2fd55f0f9c04c01a07013fba4640ec068cf1d28483de135887db9448665a05f5b6a24568275579125b90b31f4c6b422c5bb68d13368ceae1eefba141d0098edc1db4fbe20b71083dfa5fc630babcb82a66378fc71d77adc3a88aa2668d678cad670137811b5baefa9f5badd647924c09ae37906d803ada06a7e04d82d5af95ca43e8a72a701769303072fd009a2f65224061caa7dc84170d12d1251d1a5533968b12c7b027f0a0b85cd11ab58dce1d8fad1908b7e5ca9dc26c454131797dd7a5697b0c3e74b6080a6fa4358730aeb352fa2d07b6d4bdbf1177cfd0d227c94a1bab4a9c933d8998a5e0b0919bdfd4320121ea02cdb7e459db603b4fe374709783ef5d9d8292f6a1c0b5295a23ee4551d2737cd936d5063cad017af0096599aa76ac6aac60636f1fd2cbdfa688e4a850ae45a42dcafef4605cabd5c19bf22f79c3241cc25c86472c418dec1025ed2aadd48a276aa33c752a14a2c9a027021509b3a5efc6276780bc969ba4bc34f52c791f6e648cab519adf376561089a4cb0f241784b9a5851852de0470cd25bbf563e7b95c5fe81f924d9d6cc1a8417b553d43139b4f01f1d9e433dff86298d83eaeab1d4176701a4ba24b7de6c35358324b0d5087c6168220e952790ff6097695733a9e79ba82b9796a23a2291fece94f7f6313b6627f68ed60c218854548dc5bfae10a0ae53706c9e7266cb1438118279ac72992f0a218481e790de82326cbe84a62d5d592672680cd592ee614648cfa47934d46d1fe82c2c69454575bc3488b82db22728914d6aea1654f8dd6dadc4e8fa4f97dec39dced6ec39356e24cc20c696cdecedc4033561e26342e99444ab4d9869cec956e21c8f05f76ba5277d89f994646582aa4b825780034803640be5fa8a59280f96f973abe84e60fa22eb7e8b95ba86eddfb92f35e96f66191028185d1c08b1a13dd50140bdc898358a8c2a274a94accc755438b556b48a734786c3d57837af118db888be4e2802e966a5b209c71e25f1b796fbacab1e82b933f8592f8b6be81c4e19c8323678486f4f333ecc356452a3661cb9cd43136d9c10f542d47d07fd46425091967251c1a1105a17bf010997f0f079ea4440f240573d7d2677160c03b57ed6937ea507c0ebb2d2d4b752e829f0d4226d057540011412b9d37d7f3b148e6093862cd0df637e48167282a0044216018408002e7a0b7666075f0d5020f632f6216b8e8ea595e5f70db6a6a223287c871ff631dbdf253095761a1971299a36e9f42da0c12421725915043ecee0472889c823990c15d46741cc2730d9561c478941257620ae8c1ffbe074ca3728f838181eaa9a47f8480d5a241363f14e1282c4afced80e429fc154c1fbadbf9bb0ed0c2feeddef51194dc33c185f792a88f06df215af42cade16f16516de6d001761c8c1f2d57372fdfcbd701f257db926eaac63aa9a9fe76ebc52747e0b05dfb1279d61d0a1f427db48f386d5d192d559306712bb104bae3ac9dfacd2023490c0721ba8ab0087e0fc55a0aef1eb28674d59cbe3a58b9cc030ee7c92e7770306ec0b12bea1a6064f28d3666832300532de2501f094158d2da94f421609876a9e651cc70934aa095b4606698028bea023fcab15bc116a6029d64a8efd5733b49af4aad45d1e6a820ac74161d49bd061c8c157e977118f9284a31732c9484dc78afaf922b2e718981359d10e184505122afec7de5161fc6b0565522c6b9805b0dc52c88a99a58b007129be55f754abf7eda14c434a96bb3a0311928eb7eb2dd6ec786c7c54d251c21d2e406fa90995313efbbfa95a61f089e757db1c055f498f3050af024d8632aaa5dca878847766f63e7fe6a9c16838e789f8d445001be8e2f33ddfbcd96eb2b8124548cf625267a4b4e4cd4c39cee6f0e0dd14e011407be2a63b1d47ba946af2fe401899fe93da5e6cf0c04e649056c54583c7c30e5189d68bc45efe09410b93ddf07f5d273508f9c627b58e88315f8c8c3a1d24563d78a43b9011ce3fd51e8fe8db35ebddb28a796a413b546b3d680491ad612ba07460aa4b26b658caa46129108c35593e4005ae68dfe6fceb58bab3ae4249230ce977f635119b2a8f61f993c623595596bf8185639563404d72443156901581a0d5554d0ce19510626a29f009449dc58940886955e4ef5d15c08418004cdc96e667d1386be13eda78475f3779ba755b36d80d900a22cf034daa0b1ad7749b230b0153fc9cf3585a83df82d6b0af4d5afde0bba5b88c2a4e297b92b478e99956a973ca24cd4435fd9ddbeae9344962206ad8ee7991f6326ff3be0d2059d48d6d794311ac52ba48bd707d5cc2f6d0a54bf98a25116a1180910e4de92eaac9d7bd232d82f72dff487a9873c913240529d6d29983f44b75571780f8846c7d0f2444f0883cc838ec112b003bf23114fc086c5cfd135d580e07d4e2aad955142ba95a018c7453d23ecfc61e20653a55f136609cc14ed40f4d37d3b3b9881adeab0608e3be108bcd0a21db0a65a52936024db5c627150c3c050deaaa352bdce4643261a892ce8488b56096bd190f135c1fcd4935cf3961b9f8711039c2a7de79bbea200974ae8e1c7351ca91c1dcc9fcba99627c94122dbc60472c1b18428e1a33593cd0bbf6dd85d69df45b519c6442ebcf008708f8aee5f432b1023182567b60a780dd3ac26a74c4c2f718f838e354076e8199407d0dcb318430e8172b0c8461d3b3b91743b44dc7be3220e8d59e9e4edc23daa40242acdeb4340a6eac5d44ad21ede915240b7d5157101de065299a4a58eb6a315df689a04f35059586ba12dbbcf7b0388018264593695b0822052dd539a247de796bb4963e08cd40708ff65950a4a23445b00a238fbe26e1b17e26a1d0402d35a280bdc55bf309c16e27d3110d4f1f99fd8ea4962aec6d8c866789f3ea20765f048b0f4cc3c4c33b0996cc08b5119c526971b030fc6b63589100e44ffc3f78c0ac9060a8dde9d14ae6404908f4e8f30f781396450e6b275523a1345cf31c22ead01a96df3be0090506ecf802bc0ccd52f2310097667d2431d8c0c6170ddaad1bdec2b43ba9551c0a83e805fdb44f9cee0d3f28072539487a37f456cea64bec4ba0b43d7540db445c15648b1391fb357dffaaf4add3da09c3bf48fee1eb0cad6af0f1729a509b4dbef340ae497709170ccf2be50dd2682a94e14f0ce5c961c7c683d6c4c03708570722eaa984f31b7f776344fb97c5b162ce8187e8df599c63101e15dab7da0bedacdf0f9f91e70feb5ee766b829e2d9eafbb044a67172dcc5e2b4e85fc6dc1d141ca7f04dae783175c0a068d011f36247ab567208cb4ee8c018c06503e1e1da5e537244bcd9610538b077fa946bfd537c958a51395b3504bcb64133f23944b08eb0c4a79b9588e434391ad96ffa19c8294e5d0d00e2092dbbe76ab13a223dab3bedfb1ff2a6ba37a994aa771de80a5dccb20276ebab90ab42de4cf7e2afbf5b68f7476e5e8007df9a73e606134f6b976950674fcec25f87e303bfe4d427380729faa3101aa7e44335ca27ca6f6c770bb9072861973c6356f67633180f1f2d8740e94932970793737738f7dfdc67bc3cc10da60461db1f", "0x3a65787472696e7369635f696e646578": "0x00000000", "0x3e1e8e35b440038ed6e6cf14c413a10204309c1c9f4f94361ee6d85489afaf10": "0x00", "0x3e1e8e35b440038ed6e6cf14c413a1024e7b9012096b41c4eb3aaf947f6ea429": "0x0000", @@ -110,13 +110,12 @@ "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38efe1dce87a8138c87a9755a192d55aee4e448bf0f6c08e0443fd318476062713c3b84e1f0d3558206777991441ed0a1c": "0x0800e1f50500a81f0b010000001b0000407ba5f06381960a00891511004eed002400000017aaaa9a1f63a91de0e1", "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38f2300b6e4e4a41213463d1870331bc97b089c0020178b1025ab79018dbf442db463aea6b55feaee7c8500e6373a40c3a": "0x0800e1f50500a81f0b0100000017000090ac6e3278868700891511004eed0024000000175555618edeae344b0b", "0x660556752ce236c466dad8256bea8bf44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x7396903df85f816e40b96a10626866ac01ac5250fa7bfe35783a9fe1889d6309": "0x01", "0x7396903df85f816e40b96a10626866ac4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x7396903df85f816e40b96a10626866aca1f7f19e9ecaab191be170a34f0ddaf8": "0x01", - "0x7396903df85f816e40b96a10626866acbd7dfaa70db5595978338923a0db23c4": "0x01", "0x7396903df85f816e40b96a10626866ace61eaec3ce42854f2a62e7b6487718e2": "0x64000000", "0x86d14ebdcabe8f22d507b904cd78e9494e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0x8bdb109e83bb8c1b6a8d9569c54b22464e7b9012096b41c4eb3aaf947f6ea429": "0x0000", - "0xa56fe8526dd0fbcefe5e4cf42d4a83394e7b9012096b41c4eb3aaf947f6ea429": "0x0000", "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc60faed4eaef575446e4331b0aedf3af1258a3d7cd0171466cdaa0e615533bf37891d51589802d279537ee0ca1dcd7500e": "0x046f726d6c76657374f4ffaf1a416072d01f0e00000000000002", "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc60ff8f7c8dbf8b1ab0da6bd1d0d1f2e79920e642365c10c6ec3ea0674bde84312fb8f26b9ee76fbcad37a892cccc04004": "0x046f726d6c76657374000004563f414a2d3c0800000000000002", "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc61ef923637ea66cf01bee7ea6ea08e4e87a65d30c7b3606d16af154d852bc1b47152eab5b714ccc9e6d6af4e4a364b14e": "0x046f726d6c766573740000e038f8e815c2e10f00000000000002", @@ -155,4 +154,4 @@ "childrenDefault": {} } } -} \ No newline at end of file +} diff --git a/crates/subspace-node/res/chain-spec-raw-gemini-3e.json b/crates/subspace-node/res/chain-spec-raw-gemini-3e.json new file mode 100644 index 00000000000..05c2cd39488 --- /dev/null +++ b/crates/subspace-node/res/chain-spec-raw-gemini-3e.json @@ -0,0 +1,164 @@ +{ + "name": "Subspace Gemini 3e", + "id": "subspace_gemini_3e", + "chainType": { + "Custom": "Subspace Gemini 3e" + }, + "bootNodes": [ + "/dns/bootstrap-0.gemini-3e.subspace.network/tcp/30333/p2p/12D3KooWMmCyWDJ51HNNcxVSYBMxxcR3RmZrYwwNPVR3upUbPYFt", + "/dns/bootstrap-1.gemini-3e.subspace.network/tcp/30333/p2p/12D3KooWSdYSDDysqP7vQVWYB7yV2eGVcb2VxzUD1FZoBGyGkBDq" + ], + "telemetryEndpoints": [ + [ + "/dns/telemetry.subspace.network/tcp/443/x-parity-wss/%2Fsubmit%2F", + 1 + ] + ], + "protocolId": "subspace-gemini-3e", + "properties": { + "ss58Format": 2254, + "tokenDecimals": 18, + "tokenSymbol": "tSSC", + "dsnBootstrapNodes": [ + "/dns/bootstrap-0.gemini-3e.subspace.network/tcp/30433/p2p/12D3KooWMmCyWDJ51HNNcxVSYBMxxcR3RmZrYwwNPVR3upUbPYFt", + "/dns/bootstrap-0.gemini-3e.subspace.network/tcp/30533/p2p/12D3KooWBAKTZKVyon5xZ2aBmRfppU2S1uXn2xzGJJbUctQoQmsC", + "/dns/bootstrap-1.gemini-3e.subspace.network/tcp/30433/p2p/12D3KooWSdYSDDysqP7vQVWYB7yV2eGVcb2VxzUD1FZoBGyGkBDq", + "/dns/bootstrap-1.gemini-3e.subspace.network/tcp/30533/p2p/12D3KooWLKt3vf1iTf9pnLLtVNs4QAv8bq1B9u5C9t1zbA3LczSf" + ] + }, + "codeSubstitutes": {}, + "genesis": { + "raw": { + "top": { + "0x0b41d0c7f7b4485bd7be1d66066b00ad0b6ad2361b0842d5c935fbe7c14587be": "0x01000000", + "0x0b41d0c7f7b4485bd7be1d66066b00ad4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x0b41d0c7f7b4485bd7be1d66066b00ada89273685860d998fdf453e8ecf3289700000000": "0x0c65766d00000000007c1128e5ac0c37ed02c3d7e5bc911325de4be7745d7c1f6d89cbccc9fdc73ef14228190052bc537646db8e0528b52ffd0058c4d8043e4fc6b7134f107877930ef25458395803d02fd24f66fc3f7540a3ed8ceeb3369ee1ba4aee581f88b8a60164f903da7ba82dbff1607d073ed36901421bd15218681d50aa93dd3c5e86b66d42f6de7bcb2da59429a57414001326135978de3d2b4ce0d83b06d37e49c15d5070fceb1d0463e521af18ccc31df37054e4851760f976c686de72b840dad79bfee0205cbde55717ee4171004efaae9a18f338ba2b0a5cd744cf7e81e1f8bb180687e5db908e63104318c200c317bcd0052e6c410c185f7811b590052c7471052b5461318f5498c2165a48210a505820bb40f6ad8a2dc13591e5d714b856fdae58300656858bdec5306f790cf374f684d52e72f1562c7a6bd62e8e79ab897ebfb3c8bce5bbc3aa3ed8d02f0e29c8f00ad93af760a9739e3fe73ae7f98ef9c4bf7f9df69e0f202eff3cf3cb085c07d40ef40488bf2b8a9fc8fbf6ae4fa2b7c78aea2742fa761d37e4c0b9c171c3c6460d1a3533686638d268d332ec9a968cf035ef02c1812dc1adf72684bf1d527ec7c157cfbc1b9046931c80858079c5a5040c0a5915342f362f8cc8405a357048cc5ca149c10c17d43841030735786023083657dc50020e28dc5401c78b1c5eb8617b3c8794c9f0bb75d5b13d9e1a1eabc2b5cf7dcc65226145f4d0a10f7d7b5bce9fad0ece045c7e7f3f23ed8eaeb9bcf4ab4667daf1d0b33fdaf93f26baba7098e33800f79c7d0b7239f4b805b9bc7de75d3cd131badc74de782c5f2ef3e5489eed166b97fae817ed3c2585045146208223a084e08911a820a01f274d9814b1c4a75342c41042f404910404483a1d4ff28b0c6e7aabe23a13754ee6d2f989cee91c92cb4d08563b7ecc3967daf9f37c26e934beab33f34c9a6f3a6ec8817383e3064ded6c6cd4a05133836666a6761c69b46919766db59b968cf075c77fd58e9de46c84f97466b8742e0211ac18821082b040b6c6b5da4d1adeb5868fe6e5352e6720fca00a2a7cd0031e8c9cc6c879073a98428a1c4481835d20fbed35749fa99da1b8810d9ea8010d9c5820bb40f6a5cfa04cf44cd2b12a5cc7fe9c899ece9eba7673543bee74d5cee63b267ae9730b8239f49d87d1e5e80d11fee8fcd1af3470d13bcef2d233e72caca573f6a5f7c6d39c4dabc62033a6888b306056445bb874515919e22c63901953c4451830bbfae1a3e493eb6cfef25d9d3d91f849be1b0fa932775554c49165bb61b54b3de617edb6e877e3c146b583f223bf6827559108ae8a9eaa89fe721c1daffe721cd7e53befa2998fe80f94d72ec73c6beda299f3e683f55beda47c748cfe58afd52e95651965eef2dd782edfe98c6215f57e08b64514538840eaafba648b3efadb88605b44b1c547cf70605838cbf7a7c78d6756e62c875b04526f79c6daa4fcbb59f51a838bbed3f3a337975f1ca4c0d4d6345f8a744ee744643a277eb75a40872ea1bf84de719fad73d16d763aa79b3d744ec71de91ce90a00a27376e5c4d04bef40e7c0976fb978f9e3e566f112fa4e1351f1524a29a5ef0e597d964c87916d01b8e7dd84beab24a478d80e1b365c87d0770714828acf969de076f5c417127448eb475fe6de229032c2e64dd937ead342da596bdfe9ac3548f9b3ac35de844cc73ca31de63e9a679e35ed327a3372f8ef779300a9cc8fbc69ff6e4358f523dfe9a6fc596fedd1b9476375f6f4bc694d979e679bc3edaa0a2e1efb19cfb2a8f1c6b33d63f96e0f92476fba398976ed97ef16a47dc677fa66816cb5e36f7fde5b9076ce771e476f88b46fdebe559cedf17c86de10c1be1dfbae373f5ce6a1a0e19e0e4ddd677afe9ea99b2cdda73df3ae7d3d7a36b708a48c90b1766d42d8b32cf39dcee6d6c3ceeff2e82e8db720eceded3b6d6d43da33df2d08ff0f97799f6c7b3cd7b6c7f3dd767b3c26e2a00a891ff9f30ca31d7ccd7b0bb25f54aa1f55a09f25a3523d8ae639dfed8101a1b4e79ce4bbf9e004a3dd7bcd4914e8a701dfdb4373947c9267ac61b4ebd77c4481488e92cff96e448cfce63bcdd11f1dbf3989fe34e0797b689eb136a23f5ce637c768c7af6d7597875631df793bbdde74ffa240fc9376ecebbd6dcf5895eb92acedf563ade197c22952cb2fd90038762ecb96db78d646b63b3a26f3edafd32887f3fcd952eec6f367ad0428542167a7092fb684f38fe27cf6342e6bda2e5367a789d59af67781ec3401667becf38d7ff4c667511b7ade78ae2470d7145c7bb745970f38f6c68161e178e8f7bb2dfaae18166e8b7ebf998c15193b5313d74df8ed70ce21b2fddd91317ba77d33f7affe89dc98bedfb40502c445ff441b65ad3185af91f91feb9fd06cdae889242d102056fd4f039e874095ea7908a7d258db05d2f13fdf811302ebdc8dc896e15a0bd9feec9caefdf9b6b3773bb8f6e743bbcfabb34bebb04b5b8764eb1c741f9dd3cd1f9dd371de39d10dd039f0e3ca095c3e3a4ee7f4c7efb4ef7c7cf46d9d3e75da77361f9deb9cf6e8359df33c7af4e8bb23569f5d31958c7d77743e34d82586ed0314226be72f7df6b63d03bb543bd47b76ccb9cec9acccbaaeda5d8ef965cdceb1fcb9d639973fcf2cca9f5d74bbb45dd29c3721fdb04b5aed34c7dca2fb1a45bdbf3ce35e7e238bee67741fbbe80e9b67dfedd1e13cfb739b8e7bae9df4e8cfb3c72ce97e03d82745c567df8da7e6dbb3cd5a83f2d29776f36ddb33ec19dc36ce685df22e3db71ca74bd64eefbca59076fceb92a2deaf339d5d6ae78d67ab162bd7a59e1c4ee7ac3fdfd139fb369de3ffbcb440de3fdf1d0fe358836c77743ebe9bcfb439b808006e574890f1bb42428bef4adf5e80df151244df1b8f895ba954df69dfceb1cfb94f67dbd471df71ededdb399d13bd7d7674de2290fae8196b91ee3fca9ff1163d8b14c53f3cb04bd087701f9db71ef6a3efc6b35deab4cf7693b54bbdf447bb191fede04bdfe9ecd1ee019b553b286ff9a3ddaefe79a45deca10810478870f2cfb74b1d947ffe22ddb7e8cf2b53a6cc181ffdd14e010f1d7aa4fbbbf960fd93f4c7fa583bfe577fb84c993265be4bfd7348b74b5c6197d85bf21b43f77bfcda77fa753b3bf4eeeee7fd987d3ed71b22ecd0f9d58e1ff312b26e3e5f879dd3be9e3d1af733d61e95df949f6977c4b367cbdda36e04cf8fb2ef36243efb4e3f0abfe97eaad948b69dc3a4dd8c2973ed1969b3a72df71c07b60407fd39fbdb78b832d7fe686f3cb066adc1ced95fcfa0c6db6e11487def748a998390ed8eceff79b63ab86c7370dba56e3e6f41a0a8542a249e3d6b6d3ba7bd8339ecebbb6d979eef3453d8a5e739701df7cfdba13fcf6a3a67ff79c61ad739dba5f5e7359dc3ffdca67318d2273a3e2835bf7d7ed71b22edd0db6145f173dd2e75f0d7771bc2deb56b67dfe99dde1daf99b3e0151243cffbccccbe3bf833271cfbf601d637cb3607c7be56b64570ddfc76ae73d8db6d16087ffbec5dcda0e8db6b3a67bd7d773403b2756e572a2abe9bbfcea521ccafcfce592f40d0f2eb5ae770ebeca9abf9f5ddb1d5c77f71483137205b1cb88e7bf652e7749a4de774a56767e7d139fcec5ce7ec0a09d5b3d7744e3ffbb60e9f3a9c67d73a679d7d7770f5f1f18b438ab902d9dec0adaf953dcf965bc7812dc1dd0c69676f675f7fbe1bcfabccb5ef748ab9942db7be1243c20732ca805d31b8647069b9607065b998b856700d5d2ab8ae5c56ae145c4b5c582e135c54ae29974a0911434c32661a26192611a6157308938ac925568942918a1c23bd20b1d05ee831dd85e6426fa1c53418fd457bd145ad85ce4263a1bbe82bb415ba0acd4553a1a7d05bb4162d858e4243a1c3f413da09dd84cea299d04b682534984e4223a18fd05fda4b63d157f4aa8dd0456822b4153d84164207a1bb3410fa075d4553d13ee81e340f9a4befa075d053b4149d838ea271d05b1a8abe41dba09fe81a340dda89266a19340cfa05ed82ced24d3413bd825641a7a087fa04bd446369137409fa4a5b6925ba4a0b35959ed248b48acb701b980c66038fc168e033b0185c0626830483fc820c438a91599057905dc424e417920bd20b798620928040a2c162c18544444154c123583ab07830ab38028a1c8324832423cb20c590669069905d905b9060c8a289863643936931ba0c4d861ec3f4e29a01e780adb0125c8585980a27d1e4031ee800fb00c911231cd00006580a1f029867905a18410f1e3c30b96a70d1e052e22ac12534d730d530b530ab308130bb4c31ac27582b886299409621db20ad20b99054905bc826c82c2413e412a412a6192412a4978b485e71252157d208120b5904f9451e616eb95e30cb703571b960fa401261e680a990606412a413e4136418390469c555450a410641769140602bd808b20af9034985f481ecc11c43f24072913b903a9052c81cc827fa0c72061207320af902b945aa404221532051206f206d206bc04592063c05e984249a59903090329031905aa40b6416d902c902d9846442aee07262fe6006414e214f2097b85020b1f017988c34812c81bc22ad482564152924a9c8293209898454c532b18cd886484664435c4354431c23a621a2219e218a11cd10cb10c910c9c4314431c430c4302218e217a217e298d885c885b88528268211bf885ec4a2a8858885d845bc42b442ac42e42252214e216e11b58852885188508861e213a21362136216910971095109114c4c4244423c42fc12bd442ce21571158d108b108910ad884388428841885d2210e20f6215918ae883d883c883c825ea204e11a588398851441cc42d118a78836883f844ac41a4419c4194418c41d4126110b3c416c42622131009130ce88429065a01870093307b00875e0f5a0c7009c601c4c23378605e126418de9567a5cbe836341b7a0dad861ea3d3d068602f3017780b2c86c77017180cf682bf602d7016b80bc60283617ec157602b7015d80b73c154e0235c2db858c0456022f01058081c040602db809f60556ab6e18911a825152691f12f5b60b8faf5042101811127487a88306224e31704931e2346b0e59e25204082626284104650497a809404c14489112337a60d36090aa8e70993260ef0319f58145013274e8c083202d4a364891325a82546146104a5a408254b8c042119a2067b044a491225a820244b7a68b0403da8254a8430e2c42e5982844ea20d423951d293a40748873903196c504f90112824a8202023921060c6607b50487a809268d9254b9024c13161b028243e5fb0404d88401981335db0282439cc2cdb934409901323414886d0315bb04994042101010e93054438a048052a5084113d403d44a0786e984d6c0026131bc412239a1011a4c35c414f1093264e827a808c40690202264a003055b04c8c3002a50908504634a97368837a86401214d45384912082901801ead93151b038f3040bd40382228c60620415d403821c738923902ce901c26162d920941809e208244b7a2a50334db044a09cf40481a40820254230699244c72cc106151104942198f40405f5480000d3ca3a2902092aa8a7082528233c4312309518828992238450d24408234147f4f82c6056d923504a4a536851498c0042053169920400930a01e694450519410535716284089492101829c04c62837a50489404d15304500f8a89129f482c500f9321940419412541028482d203d4c4014c942029a2c90370a68a08d4104c7a9694d99e1e218c34411941113184929e1098ac323668891224a89e208cf4f408b18345c63611828912234700f518f1634489934731e929e2082445dc62c3f62461d284891124469438f99e244c9a4c00c5c4882649927c0e6b0d413449d213840e6b8c0d3aa2c7c74850d0113d449834511214d463016aa5614360a48911254e1ea8c707a849069828414244122184f0815a626c0f0a49104a96207962a4c7881e2328f043103d430c81e4071e2c336c904f921e22928c6183504c7a807a8860a2c42d31305122c48d15c6265112c44409100a4a8f912396387182c408504f104b941871f249d264c909c702c306e1b0b8b0488ce058606c114690a090048104d5238119cb0b1128598244094a09132534ac26ac4f92243d507a682c262c501307681798a1c0129104850404466e8ad0f0e108219400f53ce12640238115a249132027468610818f911e94114e8a6892a40604d68911a89e202341f4a0828c0042190902499325340e5814939e228610818f912628232068b20404359e0606d69720ac7e53d9ae54aae7d4bb21e11438859db00523cd4d8c31e2a0b989343868628c3313c2eb4103588f796efd66265b0f729099af072de6f760649ecc163f7eb021e4d70ce1833d21e46bee6eefeb8ecdbdbb90bbe7ee76f7eef6db8ebbfc76fbe2f7267c90df9b6ff27b8faff796fbedeebeb7bccb0b593e49922c0bf0a484cc52b294dcbb9259b2e4669949e6deb6116f0c61ef63c890e163660b3273bfd7bb1cef663d22c0c6ccb07b9bbbbb6737375bcbbb6f7799b72d7eccbcdccc8f07c0ccfc961ff39b3ede3e013c8bf93584dc3c63744dc8dc0df9bdd7dd7c5901e8c13c7879c4af790040f7db67eaf7984b3b2ceb60bd7dfb78b4cc393ce6f79869f0e3659efc1e4308df5c7edd6f9906436b07c3ddceb8e6e57dcbdcdcbccdccef3177bfb7fbde7bdcdbcc3c2fc83690e183103284cbcc8c0333bfb7b01f2f2fcf6d18bb6fccf99a39628c6195deb02caba3b765452b76c76e2c76c4301ba4dd7efc2084ef41985d107bcc33d8cc6e4f07b68f993962ef41be2643de6cdebb2e187bb93bcec8ccf06d3367bb713124b0298f66fb08a02645f41421e512a0e74993243d404690040591a4c7c8007c720e400027497a78d41882c6104d96dce076004b7a9ef42c3102054911468660a26488219a2cd1818488a01b6e58022811a207c8498e1d000a09500f939e218c2060000738000180828c344139390228490e507a88c0a91102658411141325404e72d808a207a82708a0263d4a805000202d019a3401c2a1192027070e921e201c338260d2e3c409121c2d0815a4044a0f4ecd0e000849cf9224374f98f4bc1a3b802294a0981801642449909222aa4f12242058b2a4091000941451449324a58c491325a8244882982001421941012141ed3003d51364a4670824404d50413708d0e383640908fc07010660044a9310a06ed0720e4000233e489224e9f1313204132544042121c2ad226e78c2a4e7ed0ec00893264a82807a9e18e9e90112c20850131492244d962c41620405a507e709939e87339de84da55252584a6a1e59299cb2a4a452efc84a91f252d791d5a46c3195922938ca8e6c2a25e51dd9546a1e91c252a4f491144b49f511299c9222e51d89c251a2f4914d4991625947529c92d247a4b0947764a5f4919522458a9414ef11299ce2232b454a8aa5f091dd2329de944cc523294ef11129294ea5522f058f6c2a957a47529cea239be22307783be0dde52282906c1ccb4d83d433d678a0fc340094da3cf5b7e5e908a0c22e01a8b347ad5b6411ecb269981cf374f664a306d30cca6bce9499999999999999999999999999999999bac694778375487fe63bcd947acdc6433da334f31933321ee8be2c23cb6803196c58831a641a241ae419a418d20cb20c920c720c520c320c320c0906f905e905d9052e6c410c185f78b14076812c6685ebd84ad1944594cedfe16c388e5bc122c577b08beca273b620369c3d639a11fde6b53aa59d3f75a79dbfbb0e1dbe8b719d4d49163d5391e76173e9343622367c735984c9a21c64d10e5984832c82b2a862bc0307efee2c5c9e079f51a4b37496ced25968cd16a486df30391bb6c283cf6c446c7897e2f29b432ab095a7c3c3a5c3296ca18514a200851d6a375f876a45009e43ed6c7e05409fe0842664c1842528210014260122011e017e815e2016f00acd7b5068842210c18a21086181046181ec0259d8c5a586d16c416a780e975d740e005c9abc9b25efb81d74f0ce1fe6e05d09d64e4ad1f350bbcd719cdb88d87000d42e35f49b9336223e7c27a5e8377f5ba49b6a374bb5e376a89dcd0ed7a1768e83e750bbd2d5034e8777b0cbe46c76d4cebf835d70a85de96bd0fd4a679cd21a774ae33a28c937caabbf81e6a01dffeba273fca533f59702870a1c769b057263813c993816c813ee66813cb1f9cc711c6773f6719c29868503e29e1dc7b18d07a73267c369b608a4de864b2e3ac7465dc24451a074ce8d4b6755e7601bcfcd12223a07875f1b0f0ecf70e0a058e63366649eb17643e7e3a0f389783af324dd49e76c7683dad0d6d225b79683346ac71f5df2f06ef6f08e0b802c8a5ee301b0e9c1f1a0b4896a6867a141c3770b4263860ddfa703bb3c9374ed398d63347b9487ba249d86b2952e494f0037c33bb6f272c60ceff274de9667923e6dd46e72356aac0be022d0a506709bbbea35efde96cca1e6d0ad8d074ae8b2a8736095aed12039d3e9354d04379e1ab6d239342e9db1748ee5d279a873f6dfc643e3190d0dc52ca7a1b12cdf69ca3f5f72dd3333dd515b6ec6e3c6d35afa713de3bcf1cc400dbe116d2d5aed8abce618ed9aa873b2daf1672e3bcc49ec198976962e49b7009779d75984b4964e16756b5975290019e5c7280ffd4635da15f9253e7c7c6794bfb3b416a6247f70f55b9e44f74794ade8925cbd0c00d7dec12e933f7bda0c9dcfd1fdfd6c52e8e3e167509bf4d23e7339a673acdaf15bae7917e537dfd6e1e15bed329f935680b3bc93452f3d93da7298cb8d27f38b72ea2d67da69bf5d62a65895455d929ed12d8814d325e996ef3cca3d463b282ad5a366b2a85d14fe6e42d8a2fcb2a873a64b97622c9f0e5b878757e67cfc4ef3a0d08a36c90abb74493aec6291d1a173aec858462bba14e3ea63e4d2a518a9f8189fe8528c5b3ec62c5d8a51cbc788a54b310e7d3c71cfa5aff370b07b5c7ce4d25d83f9d8c1315ce4286d3e52d1a508f42a73a9362f4619556f089935f4fbd97270c5858a27b664d1f25262e99294432f7da77781b453e992907d8bcaf690bedbab96aa4bb23bc885fc52a5155d92de59aa97cec345e782c9c02e04e8d2a5cb0d6d834d26c04b7f0eb33c9d28068e639e8ec626e9ed9dcdac5d2ce325cc62d52ea2e125ccc23774ed6eb0c16a6733b976934d1df79df6d25fed38583bf85d1cf352c631dd01097713c2fff31c6b0a4497a443ca64ba243d001cfcb1ab05b361de9b5667196b21a0611d26f3c4085410d08f93264c8a58e2d329216208217a8248020224478c7cc0031de0c0063400c402591cf5a52f03e0a563429812dc4eb73319c9594ce6a50321ad212e8a6cb9b91ce46697b42e31432093aa879e6919764dab574f47ab30cc33418713e3a6c5cc0586995c293eb1258b162c4350d52508a93c7c627409be311e329787ae00ae7b61b83480835c1e3a4f98870ebf83bd7ac8c403c1ef609887de94eb12f4a875096a943f5b0ea74bd077a779e3b1e912f400703dbbf4008e5daa5e4725ac90f1d2af84916d04b85d5de9e29f432f8196126081ab9f17edf82fcb318fbe4db444775717ae6ba239a71f808bdeb5d37c7dbadc7c90fed877de43c5b71c5ece7f39112e731fe8cfbb25ed3e97b377da3504fa73225c5651fc964b8f8e55143fbcea137ef6f5de789eef46849f7d561fb87a609e8006782e3db3db3c333393249727d9f872366af84ecff0f5b94f670a1a9e39bbd6399ae5ec96cd6736de4db7711bb7dcda782c1bdecd6ac33597dd91f791deb14b979e79dc78b2ca1c57b8f960d1f9199dafb543cabe5c06fd4960c6338a2db1a4899e2b9326fa8e0445ef437292436f875c9734d1cfcccca03edd1229649e090ffdf69c77dab3e52e9aa1d108070e0c061c0f3df46c94d56e090f7de6cf47dad34652c8bca203703e7d4ecdf2eb0c5cd744116690e7d39962e444b8ccdb6d38ffc82f1ff9731ca987ced0b30ecaa5b2c8c8a218e671c151f939a43f509ec63b293fa23fd6d3f86e439ae9f3b8f13c9f5e47d377e4196532721a54a810f3c664495891c49724b248428b24ba98a5675afa8cb524c424114612622441c6142a53b04c61624b98019ea9017e550229de3672de84f02b19f96e43464ec3334c6bda9036d3decd460bf3ed190c8ab2d670384e8e1bb29b1bbe37cc70ea749f2947edb8c7a99b0fafe8a676f333c751bb79a376dc675e93656ee3562601f6ac3e790e84e28f516c11c516ff84fb33ff792ec8820b3ef827fd590542c1cffc67c7b0420628f827f0b30aa98df38f8eeff88768d76897fab6995946e733f54c01cf393cffeae7334165e8bbb9946b672c733e9d27a65f181fbde33e52212373cda9a8be7b451dcc346de361df2dab5deab3ea337c9f0e75cb359e51bb59a7553b8e725aed6c9eda3c84ae83ee3c486d38d3eec877363cc36c50e9d0af8d077a0629730c6956db6bd06d8b40eab96e1b111d65ca94f9f6cc8606a9023e076b5a1fcc21705e6c98e05258d362b9828f6f2c606c69ff52c03355c0af9a207a1e7ebf64c1c267196f526ee99cc8fb74e63345e7daa162d6546ee9527449255197a227806bef24919039a37653c3a6704c8c8161542a950d4ed1b3e5e4134c8cd184aa092b436b6a624ded590ebf9b0468786f45de18cf54649f293bed56013ef1ce6bdacf92483ed13aae52a9923845f7a7d344a519def978b9927b393f4ece860645b5f3cf8d4756e676f54df4745e51aca9dd9c513bee9b888be0cbde7b4544747c0f918efa1516304f43bb54ea3349e16eb0fab0439fa14dbb267a1d9ee533d7415fd13345bfb2e0ba57c4f586fd49f1bb9a12060fbf58ac408a7f454f4cebbc21954ae58253741764691710b9608b0bb86c8f7d212dbf2b2a617c27893eba0ebf2b2a5f78ebde782e2770cfe3163d7c3324cf68373f931b0fc9331265aef925e1043178ce495d9734d1734eda88bc249c40cb739ce53b4da2f333d666e83eb71bf4c9bc7d44e7f46d9b7e69decdcfea4de63e7e7b455d8a1e008ebd7b45591de26344f7372a85cc6bb47b633e5e9e5d94b94cab11487d86f96823629d404b171eac7642f69df8f8bee8fc49f7e3362445f4dd04560f2b932d7a58976cd16e438a7c175426ccb7778ef4e80f0802159d232b131fdf75c94b2e381a873256c8f86e3e333b33df408ae7f7cc9de3cf0e8dc8d6b9f6676383f31c3e4dc8102e7a46da1d7c9aace3834dedcc26d8c407eb3879a6f657bb1fcbb06242489ca0376152c4129f4e09114308d113441210203962e4031ee8000736a001203280810bfc60810a50a0c802594c09aedb309815ce4924c3ed459ece9ee69ee6dbb76f857817fd5576d8393eb1de0c89fe3cd607a9c69aa47bda8d87605b56b2a58f86e473fafcddd13998afefe81cced74b9db3f93a8fce99f1751f9d43f2750374cee5eb3f3a67e4eb0ad87940e74c5fefa173a2af47a0732c5f2ff20310ad3387542ad515a75dd73c6e3c5a658e5540f49c3d4ae3f3bde9ddf3e9d3a1c747e393723434231a9ada1d799f9177343ef291931cd25454d4ba34afedd2f49d9ea11dff93f824ff9f234faadd1112e76fe3e12a73a4ca9b0fdbfefc8bee93e8fcd1e69797fef26efaf8cbb5da713ffeaab34bd3b34ab74bb34adaf14fc7812db184877e56263cf49d1432ef73f9e5d1db2f0abbc465ca9441e2675dc2436ff90382404597f6f7239d332c81d039d0a5af6792ee433a9f395b2dd2ce5fd68e5f3a7374e8d9f6c02d165dc8f81bbfab24863e9bda72d0e7c6035d6e3c8fda74a95d0827bdb3f1c1c300bd09c1e952bbf4127fa4feefc7b7979ece6ce8ed38adc3a9542a2aa786b0b3795861658e55bfd3196f3c5c97b42e754d978afc78a60ec2fdf86e1da8525951a94efda9c8100bae7348ebbba37b43d097eeefea8c7cf36e6ade719977369877feebbb3a9777a5df516d1556fd3b26ba6a57faab079cea59b5e3bcf45dab3816a34b6f8c0ea38ba2305afce3f84b971e83592e3a8e175d7a7b531e43267a6f3c913721ae8afe9c876bef986876e951081fc0bd2199920dcf60c58aef3cba6f18f66cb9f6dd781ed0254885ec3f607bc49d2e45dfd7e13affd85d3c742d1efa02b8e8ae7af60670edaefaf5e84cb1253ccc18f836d8d244ff7cbbbb7d1d32b3a36c2684d051365a8cd151369c94d2513635966559be6e33e77494e36c0e10d0139bbffcc9fccb8150f37f5e19aabf1c65f357652c3e295ba14ca54bcf256555979e471a8542e9d273a628eaa4e3a2cef274307fce45afe8df7baa7fefb910387ef66ec960de71987f1ef423732c3a0c6ac037152a55e6690a690c55159b13e654aa944e58a552e59d34c7bc4a024e5a9da23da354a858f971c26a95eb84f9945786ea6445c709732a532c3254aa9315d209f329a431542ad5a90a9fb0ca43cfc4aa87b5ebbadba3632efe39d78eb3fc5b32ff9e13b1409a76fd69c0b7773f3b53085c74f6e7fe74a688f589fcf68d4803be8b9e69ff8d99649ec9015ec678a67d48312cdc5ef1fb5da9897e7190f25256cb3364fbdcae94d0f25315e6a7aae8b3a54be6a12f17bd09932296f8744af6dab93b84103d4124010112231ff0400738b0010d6ce619c0c0057eb040052880097198150ebac3abc84e74e8cf0489ae2d2a2e53d5e5633755ab8f5305e6a35f3de0de35e5ae7ec174ed52df2e69e72f33ef2676f9ae4e9167823e6b27ddf2b705992aa297de80224f4773e80c5880021200040158ed389293a84ece010c5000020c60248000f4e0c103004c70a33be890c30e1c2af505b20f5da3fe4c503abb4f68f33b4f2a81252ac1c49aa2efdaac5c7d0cb364665f2bc876c7918fb53bf2113e2c3a7bbf915feeee4f6754b7aad58efbacda3c36856bbf6a177dfbedbc48ad3245f061171a38f8b0ab76fe975fce0ebb6979c749ef6c1ec36a77f93e9d9d676aab56ec0ad7b161bf767f3a7c6a2f75fb165d1da3207d39ab4a174f069977d56361486d774bd89c82cddeb02438278f47d86c1b27cf24fd6da40ab38cb5a64ff8db79884724c7a8701d0f6553c8c08de787bf5df53cf474248f9eb32c45a07566541ee292ce8cba623a1e1a39c9964c24b39179e9171a3838a177dc84d874d5493a67218d4624daf9931cd2ce1fba63487025c7a670129bdacce6563b9b9fc24127f520b119b7202312bd7c44f74b4f07739adacd99da715ce9a56357b86ec160b3e7100338cbafd9cd9f1df7d33b9b9f3cf4746ad41e9e497add6a48336ae658121ce7cfbb05e3d9d4e6e4b8cee6b77671f3c1558f1dd902c433499fbecfb4f96e15e8e1994cd2b9dab543ef61926ac78dc00c6d43da5036f4d2df1604f3e83b0f9b735e73bae53b6f5a95798871b440006e574264fcaea690f19db31fa57857fd8c2c7e7a0d2b7e7abb96af82e5a78f7ce9fc8c147d39e9cb5dbe1cc643d16716ee6377bce5bbba013857bdabfef27676a63d74097ad3300f3dab513bfe1a6ed1cedf728d76fe9ad3d0ce9fc6b3999999191adc4870339a635338cb3ba7d13e371fa6d7b0f16a4ded6c686870d7d068e634547a8dda71a6699a6633e21c9bc23def9cc6f7e9d474ec963f1a1fa6f78c2679376d78c7fd4c8d77363fe3fb74fc99a2cfd40e157f865f6e6d445cf59bcfa05dea37f7a743e3a46aa3d6549a1d9b3ae236dfe96c372153a57aae9d3ffbce8c6353b8cbbb2d9a61008779e659b6db101d659ec637daf1d374777b373baeb3f9ce3f3a7685db793a7c8a9a96654fe3ad9ba91dff8c73deb4f36f6666ecb98d7d3a384ee3dd7c1aefb8a7f1cee669eaced3c1a9371547dd67aae135be4fe746dd67a2e1331c4b828bdeb54befb6c8ad8da73ba27a1acf78a30014209c3c53f422cf147db70aec33b1ef568123cf147de799225602ce46edda2dc74ac03d3ff274f6c4b59b358a68ec44ada676dc8cdad9d0d06ec6378f1b4f37e324df7933dde641a9bf21a2a38ccfa8de1099bef9f4cd376f8a8abff9cedbe9ad9bdfedeaa36799ef3ca6fbbcf1645699a2e7da3da2679595a197a5680c99315660c27041b4854b972c43565ad5ddcd8ef9ceb3361eacf245312cbb7f2d809bfbe5a15b75bbf4dc552f2bb6043755aaaecc4d95ea777aa73721aeca692653d3396a808aae52a950b10a99c3c75c73d1a3bf48373ecafeb676de52cd0c6629f780408f369db38487fef9e48914f57e8875022d4178764897f0107c76e87c856c29f7fc67fe139c0f4a7d3ba97d7774a3a287bbf1f505777181eb62d1c3d55f61e0d63b8ce8e18e7956c2e0d62f3070efbbd8c543dfdfe7cbb395b9f7ea0f946fae43e677bdbec0edf4fcd80527601f066162dbf042ab36c0bdaf9b9999b9df7b0eff55147f3b1f613b25909002284ae08324b4708a3e3b67c647e7564558c1c7a153f4f1859bf3775504137cfcf5020426a864fbaae752f21be37d37223e03d55bde6f1bf2e8f504b7de3d22564bca607edbc7bcd37fd96b2a2b67517d9e47da415fe77e2eab0f7406f31d35b849c0ff5549fd9bfa43d56b92faefe6032b416abd1161300f5ff581be42621087d91ecd596c4118ccb77765305de2970ccb00f3edf2cb0cba7ce9f7cb0c863edbb73c7a4662309dd33dcf9879323333c7198744ef1970f1ed927d8095b3f0811ee5abf34db76807dff2b74082deeb0512d4cd0b2488b7c774de1e9607edf698bedbc372eb27cac387bed38ffebc876ed1ae93ce711b02dd477a3bdc8640b7aacf7306f36ff361e745faed197316609ee0d6190a5f6440e619cc10568204da61f57995c164d125286c8f758ba316d9eee85e986f6706e29e1d2842e84012e84d20d48ff5db237aacdd0f97f927ef83520ff4c3633c74d4fc48df961a35bfb1e0b8781ee3dbf90a8efd79189dc356be9dc97002f8dbb36048797bf07b2de0a07c31c618b5f0b105a7186bb764c7d2f85d11010d9c12dbbcbe342164493921bcde1884f0440ca200832cd800061a26ae50c18b65583fa69421068a283801862d6654c0f9ef9715f8e06d7ebf30c1052c334208bfacc089a779e810c29d93c259e1b4524457c8c00b22d0000d437001b7c2620a9a14b03c97f107b1d6381aac00c3844a8b950caa38c1875f52a0c543afe99cf8f00b135c7898e5047d47ebecc9c73e8710064187552a95aaca0942e80ebde677450423c41b482105f4ab40cd0e9c2e6410b364c7b2cac78fb74dd0810c5280c51629a0c2154ea35f5fdf293d1d785a5f0d2cf141238a2d72b0c4879730a8f8f50206304f805f2f6060c1b38aa974cef319e6e774d8647070fa43bdbf7cfaf566e520b5a91903079df3878f42e91c586394bffcaadd73b90991b5867b3a4e9e932e459f62e0a0774b4608ca67dd2e458794ff51edc33cab3eba135474d839fef18581eb3c88ce811e9d084e0014dc7a0103130f3dcc1598773c7e7d55a74e01fbe5d717b6ce3c7dd142c6cffc7ed1b282dfada7a58217fbf955b9476d6abaf4fcede852c70ff708425ac26086141071e9c2a686192801e376385e7e6045079ee44a3abb249de70e252c210a2350618c34ec40d3827b26f64e7b2989d0c44b87d26b6ab764c74be7bac47256eec2ad45777429f5c495325fc2aca1c8064238c997d20b1862bc749cd6d9954aa5b27292bea397f8f8584bd57fc0ed89bdc43d1d78626fea5d62c7e88e36b17315dc8ddf1511887ef4eb450b57bef3bfda122282123a3a57482ae810d2f52cbb91be1f7d522a56e669fae516b5324f962feda4fcd0aad3f48b56f971b29ec08f7e3384893ec6573b2937b216b17cff07ee347da7a5ac3fa48f158a0959f5935af4a562b709745cf01c522bf004fd510c904ed077dfab3fa48702aabaf9052c60de5dca5fe66f6c8ff6a5351bf3e3a536dba39d57558c79eec6c619ad8a31bea64b69c882b8fef562062a2ed88c75b64796ac33c0770af8d519f93a576383d3dac58fa67e52cb359afa483bfe1b22d12ddfda9d4e3e96f767fb03f428e6fba1df408cefa88d28959157d91d00743e491a7d44f794456db7388abed3da0d91cc31cf1cf3fecb87976d19916ccba24fcf2eda49bfd17cff72486fb41aa442c1c4f76b5050f9fecbb3a7f9607e6550c3a8f449f961c7da10ad3ebfea0f97b9fcf9d0af559f0e73e8fc57edfa7da007a55e12e1cfea05f97bc352c059de457fde0ffd77bab3ea0d11e930d61be837b012892eeb905861e5edf1a4700a6bf9842c8863c7b81d9e1daece9ebaade8bb3dd6a1337d2e2d20aff6bc21f2ea6e0f8b1d7baed9f668971488bf9b886b247e66078b990d1e028e1d9ab86e4e2adfae71b4866e21e0d84390e1404cf4a641fcedbdf5b07f35106f8fe8a8f93f5be633ef2d88e658ec613fab46d83ccae6b92ed6d743d75c8bd7fcf22c8bda7551a6dd4504bae6bb0db95cf39d166279e64c33bfa8e66f2332834ce7badb837da735da75bd3ca35d3faf3f59b76887e294e40603741c6879e9af08105064f16017ef46baef281d21828b8fd815468ccc1c64bf487f3d6840744e67b36022d039fcd17d74ceaeb650f905d3c5c7ef56cc47e983936f5f7694fca6fc3b3a2752a075942462e4db65fb72d75d1ebcf1f85c98c65b90f7bae7966716ed46f0d2a390a0a794ae5deaed55bb769f59bbe7eb9d94721bf29ebfda91a0e9f38c9bc8f37622b212616fb7e91ccba3e3748ef4089ddbb02ee9b266d15d41f1c44b1a9fabc97a8b401bda504619bf5b99e5b12e2997f9dd54cb637da7256d1512cfde8fccb545b64c831d1dc75bc59797de5a3e52e1610db8dec1ef4a0a30be67f0bb8ae2cb977e573810e3996bc03d2c7e573cd0c1f397dfd50ebef03c7e573b50c1c76d88fcce881420a10945ff73e4998c0cfe47cae83bd41759b099c177a82d33f8e23b9409be88df0555a10a1e8410e6bba02e619e3d6e43323286be1342c6d04f956acbfc107f5e20da02c17e5900bfceab23d9f47cab98422760a70a2d5600fbb276edbd0de9da49f976599ff40f01c4cf7ed5605ca669737b02470ba48a2cff43222d906dc33f979c80fdd7c97fd422b2020297b70591dda522155e7aa4c27741a9973f5ba64c994e7dbbc5e507589e3efdacb5a63adea2910a4f68c08a6a22ded223f5e94d089779abde0c816eb910e8564565bffa81148fea8fb56b7fc21f3df5f423a5dfa8ec992b54f50ebcf1fcb4aa0b28865806b962ec2600aabecb12c05d54bfde0bc4c7afbfd5d9d37a6669700bb25dc839e7b4de9cb0e7e4d2885d83220be2e0efea892d415cfc5d3d21c5330e59b802892abee600ef3ddac5b7f3156ebd8ce1bdd1af973138e1598ceed83baf44df0bce052226bb16c8e664efbdf7de7bfbded2128f7f5ef21dffdc6d6c9e73a527b23c74d8a518638c1d1f84daf688fea8180f7d13a3c53f9f5971f9ce4296e729dcaeb260e5d96d7e575818c377f31788f4e85bfc5d61e10b5f134d301a8d36d7dcfacc47a3d168b4852ccb30cfb22ccbac90ade5194f61a9f035bd6d0f4bdb1e9633e5299cf4e8d02dcbb505d26ef9d6d613b227f17f1cfe0ff7a4ff073e4e4d97fc46466a870e23185142b72a13593be94b1e0fc87cac32ca4367e98fae1350f0b24231b34eca67915a4cd609431fbd13c14b2b7a17e565edd81f9305505991c26c298200a88045eda0d480cce3fcae6aa0c593ca9429a3e57441a1cab1840d982002ca816807605428272be6a15009800a58a89e2c80ca0a8a083e26b1624e5755ad18285435b2c083295e50a94e5ba3ac4b61220327aa8004192ad56956151595eab4de395987f4796fbb6160c68b2cdca08c2965ca9cd66bfeb5944ec596530cedf0dd56c6d225c6d239403e1e0ae8a9e5823f5f5863a552a5c729ba9519272c9d53f3dd2d79c6d2a5761fdfd57cb75b284225320ab88eb16ce1dba340e79ee90c5a80300320702952a94ed19f47baa74755300727a841123420c2894a951ea7e756669c20952a7d926e8501a7e7915a61c029ca143f3c8f52e499da5f982853fc203dd6283b51a6f821faab51fc99da63f5617ade6d984583124a80220c5688c28b28bc80db53aa892c882003195cc1450fcc70da13f4cec70fae529d1e96ced9619f69fdad73c31d8001053b85afe9528af9000f421a9dd98a51fa732bc6d850c0e952f4b7452c7c4d9762f634862e2b4e97e2f71532f6b940b87e89410e9ecf05f276e544175ff3031f677bf0f610b2a9c74cc5f35d20f13ddfadb3e131fd497fd29f1b60cae74ffa7bcf234e97244f15bea6673467e937d0f9fb6fe015a447abe2744956c80fe9dc1eebbb0ae38921cac83809ae474fc0231c27c1b1afb640d8fb711ab2f5dd011788f4f5b840f87d74297affae9c78c2f378dd4c8247e774d3e6e9601efdc702f1ed313d7aa973b82e4d8fd134dd9fceb4f1d16bda343dba135cdec602c1e9d2f4f7bb72228bb724150214dea64b93b71bcbdff7df58f587cb382185df951350f89a2e4d9794af8ad3a519b7c7fa6e707b2cffdb41267930a79bef02c93c7a96d1d4775a10cbd77d2c5fd76867fdae9c00f3707b44efa5ed1bb5dae7f48d4ebf84f0acddfaa49d394f6dd2d66ae69aef2644734cf34c029b76396f3f50a8248184ea7fba10b0a10d653e68c36c61a204bf1e94faadab655a07e533096cb583f2996b1b04fbdd1edd3ae68305c17cb3ea33bd9bce44daa76f17dd9f7429cc187a796fa75b506964266ebb54237bab2defd9f48ec9dbacc043a1072bc8628c1ad270c569493391371e13d7952057ea9c5dcd20ccb7f3e89cfe7603b40e9f3a7a6b5d5ae7aafdae66b07a586bbac4bf6a327001d637db01ac6f167fbd7891835d46e2df12213df4479fc087f5f9eedb5d16c03abf60d482ec7735032c8fc3aa6f27c87856fd7ad63afb1dabfad7cb17617c60247e6bc7aa7ffe04fe3aa444489ffa0efacd10ec61fd21fdfa52e17d7cb765be7bde19d4963ae1d8a758e7edc79ffb577154dd83ccc4add7ccc88238b83da3750976a926230db1dc726bbfb776282194990561376fc3916f8f9dd547029843ffc199b54bfd748851cc775e0669865d73fe7c68c9b83cd8e1f260c73af8fcb0fe4479cb839d9d9d1d83df4e7fdef79c757607bb349db720fc9a430a615d1ecc9f70bf04aa90f86efa8f450612652eda6dfedca23ed12d775869d775dd84d07f2695249078a027f22f7f627d50eaaf0a7da2fa47fe46f587c9f8b851547f748dfebc8ff56608afdef2b7f158fee8d5418f6ed127fdcfb3ee0e0229233c2f8fe9d1318ff427ca3f9f145287ec59065fcfdaf9ce93efbba0d4fff4cbe3cffb577d66f561bfea4f94ef1ef74d6bde0da437d0db2dcfd8726eb71c0ee91f2e0384d2761be264c8919f3eeb2e0f21fbc5a2dd741fe8966793be6bfa7bd3310c3a4a3ee65d0361f3f29d9e976390fe7099bf7cd2dde501b720d1a1f3c603e9e4ae1d08d699d278f3926d9c81fea267f179c61bc720fbe594619e91f639cdc7cff505c2bf1ae53ac7c7af47ca75698744c73cc32846a347c7ac2093c49f2dd7a5cba75bce1bcfa416bd68a44ff831fa847f4ec8cd0f8eb0eadb633dd2597d2ccf1c6e3f53029667a46b3a6f4012db2eed8d741e3eb36867f9f42cdbedaa5dea2fc7e8a41d04309fec53dbedaa3fef27ffc08fde4197f5873f569cc9b14af67c773cfac3f93cdfe1bda421cc02e97c3c4cc121d843879677af7652fe79774960c17858a1b0a02fb51c520c08800a579439ad3fda45f9d7455f92d2f2d23b2909d81540b72b1a607914bfac4c56ccffbc32653e5628a2ac4b793c2073b2aaaa8bf2ddf5bdc3afefb68175c2d06977f8ddd1d5c747ec0e933559030aaebc408b151d90715a2ddbce76b281b3e912bbf5ebc50c559e7f96e1ba12cf32b8ce7f740ebb023a473ebbf378766d4a96ad967a38365be7dee3d139f09f7f318118ff1e07b27e0276095e3e7d3d6b6d46e9534ebab407fa3cbf21627974cba3fb3c677fb57b701b12ddf20c6e3e3c97ce3e58b58b2eabcfac57dd0abb043d939ad63940fca87e4be78a9f609bda218c3e3d93d1d78758e14e4fba5dda78b8eb0d91e7d15fbdb17c1fd55d6f55fee8f347c7a3d8123ed119fa4497b3875bd8d527c2da3d8fde9ef1e603bbcf36e479f42ed627f1a1fb70bb8a01153f7f573180c1f3e6c3f3583b6d72c442b6fd9ac2ed5dc04b19b6d0c7423861f7bdca75693dc59c00880383c172725b874fec9052f68cb9481fc7e18090eb12165bb870dc968cb3f006812ccf0146b630acb3be20b20d70a40c086e3708a41ec23a6b8af9015bb2bcc775ddefda7db6fe48f975ae065ab6fcaeb4586198c94829e4e21681d4cbd4cb3a9b624b702f831b4f7cd277fa46d620fcd2e53e7ba4fcdc18d906b8e7c3de3d678ac18037880cb4f8f8bb8a0119bf33d902a13dfc8cb49c74eefa7c6afe6e82b43fe9ecd0e73974e9bbda73c916082e236de7ec4a4b979fda2465807bdefe23857d21830012fd5bf9ee5cab519079f43ec112584c50822bd39223ba4a5411a232258946226eb44c196d20830d6b50431ad0700631cc5006322c905d201c2672a4d1a6656ff574b8ca641ea9ee1cd5da71b276369a95c9b782365eba98c802ad602103aac888f1f189d9690ef3749eea99a25b9943dccbf291c37c5c79fb5b7df447f474180dcc649e0e0ee61adce8893edef0725a8e5d463c7a1cd5b8e13b1c1f1d138a1d8d7cc0031de0c006340044063070811f2c50010a14f1610212880011080ce94148109e0738e0f43b0b643f3a6f98125cb72b2b71462bca9db8ea8644232e5d68b07fc86e11c5163958a25921b3c8bcf48c37201eced92dca9f7113f3dd2edf696b3ac6cf519ea10b573fc3b0d2c5ef6f16cf83f3206485152d6fc3c3781a4e838c57228b9fe133bae0f236bc4b0dfdc0ed4a092bde86f367f199670ebbc822ccb31b9acd361da3fbebcc43f20c47bbd92e9fa1d3a7eff468a6034545b478c082f9a1001e3e989eb86e92bcc6c6d34e63e3c95c288c67e717eae267f80c1a7f1bcf0dcf96abf1dd786c702cb9f1dd78a27489fa6e3c3fb85db1608c0e74493a6f1258319f851d07e6375d36daf96f18566307e6379e61946f2814ccbb1d234a97a463bed33576e010fd7907bbd8a8a1711076771c5b10761edc49e748c7d12dc1e1994671502210c069deed98255d92ae55275d927e75e1a0cb221c5936bfb10561d781d1f8a3d4618dbb8e68002e731e9c7afb8c73389ef14033583be6d2b38f675954c386635302bdf1c84dba9649c7a494ab2d257b060ab83cf4ecd5a05133c369d01a3a836635a80d379f690d61164874d8737e8f7a68e4ab7181186f19f3d0c33c138445df435c6638ac7148c3610d87443c13f46e725bed38ad0e3df41a148867824e8316a13d447a647b8ce192552e58e572552ecc85bbacc03c1d2e35e89e68d03dd5d03d3197a7b3a7c9cda07bf2920f1a3468d0a04183060d87fea3468d1a356ad4a8518346cd0c1a3ac3ad49c6d85cb2e690b08d489c941cc7711cc771dc0e245155d111229c406115ab58e582a9d53c1d19e173ebb9f5dc826e41cf98639495047b124a9da650ea64f34ccbfd46be3dda0ad9ee689f4be6dbe1dbb7ee96dffcf0f3fe4ce1d314ec168dcef407cb638d32056bbd712df26a143e3d879504d1f7b4d38f0aa54ed02d2a943a3d9754287592fed8db6d64b581af721d53dc8f093dc44fa299e1e69c241b1a6e663e13748e4816bc068ecb02e1cf022f77426688ccd067423abb34e6b240faa1f310d4b28c5ff31b410d66109bb2654ebcc5c9d3e121284f87b330d13341ef61423827c7bd2c90ffaa3b5b9e4e0a7a96fe5889d81ed0777af210ab81eb164c0f459e0e74206666666666666666666cdb46434333f2191b0dcd100d0d0d0d0d0d0d4d96193366cc9831638657f9719ae1b0a6a6a6a6a6a6c6abfc38d53874de4283060d1a3468d0a0513383d2d0198e34daa48cb1afd4d5343d50fd4b7dcfc97136b3f48329952a3788bc6722ef7da4f0771e53fe1b744a034e3dc60d3238c6e058a17e735319674e1c1c6763936d0f377ebd78c1e5b3d6fce9ec731fcff48aac0a87dff05d1cbf719cea1d7702c7f1ce73d49d677a8ee39d8f13dce039bcdbd50a6ea849e0f01b9ea3721b0687ce8d027bc2e1abce592f5f80f9e76d457ff9e7d9d326075f8b1b0f76d10eca5fdecd78cedad3893245749a2cd22922b4d10fbdc699761cd00f37388effb083dff0bd51a34c81e337bec30d516e6a94295ce63445749ccaded046cde6347cf3dd826c6ec337b7e13b7d3364f31adfbc26025aea33a8bd0d7a06b5b86de086df38dc7ec0f11b37357a0d1bcfba6eda7137e814b002fd70c373f80f37f88d29807eb8f11b7e438ebacf044970a346b9e13738f5f2a637e89e6ce80fff34a04c9932fe66080dcf9c861730863edea07b8a42f8b9de0cc9dc86676ea38e9cf31ab49b4183cef8dc786e86645ee399d7d427ef7d6654d47bcc4bdf5c3c9da23047c03c1d9c1ac5c9333dbf51a34cf1c30dc7f18773e339e3e0dd16edf06ec9e4e0387c4f3a3cbf41719ce9066e384e8d42a3a44e389cb71b0ae0f80dc7004edd67bae11b60a2677a7e537d4f387ce7dda08c63058e9d80db93fb0def8e57ff5c6e44e073eda4f810bf6b2737e04e53bbd469371fe273ed36c72abbe633942bbd4f0f91afb90e94c3e440998b1d9471a03ce6999ed30ae5bb8ec33cbd68e7c315f53acec2e59f33991b7fce633c1d1cfebc554f07c79fb795a793c39ff7d0d3b9e1cf379aed9e32d672d02839bc0a0df2fe721c340a0eaf42dd1d8746c1f12ad46fb841addcf07da6f6ae8bba76ef1b875ab9e15ef7e5a0566ef80da8d78e835ab951a780f5a7010f7d9f69767d221f561fcb77f55d1775971b9f53a33e531ab0f53de638fc862856702a0974f89e6eb87bc6f489fcae421dc73bd4fbb905813f6bf79e7f1af096533aa501271ddeb44b79ada2c373788655a07ef6aebb7c151d8ec3bbe95d77b9a156d1e137fcaaddaca8f75c9fc8b72a143aea113738d75dfef90d749f29cafa447e98a783a3de9833476d8eeb6c6ee86e43f68a8fb0fa4071e390fa44dfd5f31664571f2b1447ec33e1f0d8388e536d6ee811fb4c7c040e1c753e133b8eca3d13efc653e406bd516d9e895d454ad5e81b2b207ae8194792724ae9243aa21bdd88581cfdf14cd049d4c733411fd112750e4208a11f7973729c0d4c01e71cdd1389ee6944f7e44f674fd3f7b44f07fa7c3ad0b9a7e3d06d9e0ec7711cc7711c74d2689b526631c6da4d4b4a268aad0d5d1906210946ae7986cd38e71709a24cf103e6974ff1f3c3c8b54a02acd60aec69e424b8aeebbaaeebda6894118d320505468ef9143f903cf38d9280f4c34cddb66ddbb66de3b66ddbb66ddb46a3d168341a8d2627638450ca958a8d9da16875489cb373363b5df2dac3dce8a87294449723f9a846e17cab5148ced528534cf1c3c84935ca3ed3a8ee3c13f4adfa7826c8cd7894285246be7914293455e629ab6273ca2a9529569932654e24a752c5e6a4394dade2a7ac4e0184e2fe72cc399742e324cf58b3360958947f7392779cef8954779d86442291482412c9c7a8ee89f3996ddbb66ddbbcca8fd3e67be22ac7711cc7715ee5c789abb176a8d843e7ccda4921d1d1a6d1b703989e51b80710c0f48bbe7c9a25658c453365b55606729c4226d9e7ea6cceceadcec8d96d564773ee01fe7e0fbd63060eb247c93ccaf46d341a8d46a3d1c8abfc388d5c23c28ed1cdb31f30df6a94cd319f42faf643e6588d42f2ccb38d469942fa144546350a9f469eb1b6d129a4eff6c3e65a8db25592a6699aa6699aa43f6c3eaa516aed5071ab3d48d1e89ab23575bba6593babee9016c8be8cde43ea6136255b4ec005658c54e0f3d285f7de834ffb5d7931831731d800cbfbaf973161de0b64bc8f5f2f5e60c28b79ed2d67e2a1972f68792f5fd0e2b387b3728c314a47f9c088c5685992bba6911daa6bc7625e3aaa7f62d5673a74c672b64b3c1d3a63b583cfd1394e58f3b0c6daf1b611c1a66b9b90514ed1fe7416d339cfa7671bcfccb29d21f977b37610d28efb541429d0ea48f0d3ad871d93791fcda5fca4dd7be8349e410c3a56b74b1d8fc13cfebceff869aa0fe69a0f9c7fc109b09c06d5a8fe193e70b5ebd77c46edfa313133b59bcfb5cf6a61ae61508b0eb1586f667e649c6f0e7dd66e08f4e903f4e9cb459c80e911d5d8121caa7f7ac7629eb54d88e5b3fa4cd73cb336e748d14958b4fc8aded65623a9669389d7e80c4677bad4ae0337bdb721d9c30a7dface1b41d77c7a57f313faa039f491d3902674b8399b4f9f9b83f9746d732c9fce6d4ef4e9bb39239f7549cdfb689e693e677cfa6e4432e8333b0deb0de7d2d9fde9fce048b5e3e674b9a4e6a1774b6a9ec6339f9b10e83e3475c6adcd07eda1ffa0f1de52c73d8d77dc773f9ea6764b6a7e7ae62458bba0d44f9fd97878d21f5d6ae7a802bad4a4aa0307bdfbf1d96b3eda302baa2cefb49f0ae89c39a7f3179c00fe29a14b6fb8f164b1def4f0b16229f8e8eca99fb4abf91969375d6ad3ad997a8b2ea979adf2172c00e919ede0cbe718bd58ccc3e76d56e658cc33dd853b575b6e4b291aa68104fc02b1802b8805fc02bfb07476cbb27e5ed7557facb73a290fa598ef50fdd26343e742f505316eb8f66d087fc102a09105d07151fc8205d0fe7c1f9ed89bc79b465f281fbd298be9520f99ff9ab2982ef5f1f9fbb1fe697476c927c730b2dd9189c186bfc364e1230c5ce763da50fe9a1d9dd355e3985fd7fdd1a3dfedd1957615c6640318620863074bb0020b252f515479a20a5d2043850c66a862072f27f84014b2908103316ad0032d3a604186ed77e5c50aa1245029c145044616921436516c5ec4043cc009594401031360214c1b72480215245049f9808c35fc008929be08a18c1d5e92d0beb0c00654f60c2b36640185269c28c30b3884c94a705189365f3001618434bf2b2f27d0b020630d0bc038011866b02a13461d7361c103269c8842604011a9e4a0851833c8c00b6718c216f40b79051a527051f9220d978d480461843364985ea07cef69ffde95d37b133a7cefbd2ba2f8f2efbd07df08ccab818c49a052830426134518be70c117a258c310bee047602cb43481050f6ca6f8f8c1d452e54d8ef00a322f39be1548016e8946182a361c67b393c6ef0a0b25d06035b4728513ac2ca8600796152ab8e207f20459a8e20a50941943c5143a569082eb7775c51655a224c28b18d420095fa6a08421dc2003088424ac64914e212cb6686152195df144f6454b0a9248e2677e5757ac204a01c58a176188c4e081179ac8514301322c8042402950031aaa3043992ad680b32a638a54c3151a625e6085d97e57ab30bad00542b1615270842d9cb084189c20831b2f454ad4fcaebc64f1ef77e545091a9429a450e2095db6a00223e0788248d322cc462ba45f2f60a81efe7a01838c904b6b25d0052344010d568ce0e5ca0d2f6768425c7951c2942765cdea0993cce6850a66c0565d10e2d1c50b5420831c80e1051bd8ac90f025065d98b22ac214b3c435062c12092844e1085394d0028c20d8a002234ad5e0073d588218d8c04511d850a304181098105a41b1d5b06086cc1892c0f8a40226bc64818a143bb0028d9509c2c84c521b59d3255ea9a28c3fe062e41840862d7c81ca195090842b6a56635041f6900c15ae7362e52667d11aee77b5a2c2cbdf95189af88e93cd8921add964a8a4afa30e5660c27041b4854b976e820c31bab464c64cce06b28a871a89564dab48c38105f0bdf7dedbb811fa7828207a26ebbaaeebbaae6b62188661188665f2b22ccbb22ccb9a73ce39e7d4326bd23d5df4882336ccdaa8b5699aa6699aa669d6755dd7755dd7c4300cc3300ccba4c049e7336c0f560227c37012153f26818bb58b5fd7a24b7be4c8b4bc28ba2eecbaa6755dd87559705a1776c10b429b67b228f74c16afb2d837a461777777897e0b972e3e50580e77f592eec9a2471c914dcfa8cc321a2dcbb22ccbb2acfcbaa473ce39e79c176781307af3ead79bc37ce9c8913163c620f360b87ddee2578bedb1b3b360968b0de30e21840b218e94524a29a5b7cf18638c317a951fa7e8ed9ccda47b82d6b4a065c5e8168d5246ca3dd3f5fa8629196ca8fd763fab20db1dd93e1df6d37ab63f7ebdf3f1eb9677363f7c941ed65d08bd2bbdacbba6f6adbba6f79e976fc752c0f9efaa0835780cf0294acf897d370cec38b14bb152dccd0529e14604faae3bd7399108f4182312df458eabe1b637f28e8e6dc89e355debd2e4f1736b77e417157f2dcb9ff53809dcfbd82de1f1eb9c046e7bcbafb3bff5dff770eae4344dd3344dd3bcdd26cbb22ccb32aff2e394797b76d13d69744f55a3737da03822f322599dcf747a9767f4f247392b82559b67da56fd45b9675282b31338f696627bac7be52470f0d96a2b092f59fc5ef1eb058b2e9f91b2757f3a397cbd87a7137dddc9d3c9f27474f83aaf9e4efbbacdd3c97c7de7e960be4ec4d3d1c1f7c6d7b9cbd3c1f175eee970befee3e9907cfdc8d3a1be9baf3397a7b3c369f8ba8fa753e3eb403c9d19be3bf83a6f793a337ec3d78b3c1d1c7c1dcad3b1f1742a571b8a4315e2c18307c06bd05a8570a89e83d3d01d4abe839b7c4469150a400fafe11add518572a0bec32faa4315ea51c379f8a4375568071d1c006e519cbac37170ea92e6a8423739fc511d55480700b8c97150211c671d4e83c7e9061d9ec3392aa4a35ee1e12434721d7ee3d94dbd323ab9e354211cce798e7a85c64968fa8ddfa042198ed3f01a2a8443c373382987939c46bdf24e4236ce39468572d42b3d4e42349e83e499472a44aa57167012d25c4756afe09c8432bf719c7aa5e62484e3d16750211e0250afdc38095d7ee33dea957912c2f1e7900a4d114a9d78d42b7c12a2e1399c877a459e8448aec36bd42b3427a11aceb90d2a04807ae5e62484e3d254afec3809dd70ce4bbe51a152bd829d8466788e1dea15d24968731dae43bdf2e32464f98dcf50a19a43bdb2c34908c7a1d37ac57412b2e11ce6d49b0aeda857fa2434e3397c8a50ea8443bdc2809310e73aaa1046c36b7c86d3f88c5fe1930eaff58ace4908f39b2a74e357f844a9104e15bac2271cd79179fb0d54a8c67354211c1c7ec36ddc86d7f02b7cbaa9424242429c937ce49b6bbef370dca0a5675ab7a1459e69dd0685f24ceb35d669d0f94ceb35d4c733adcfa0403cd33a0d65d533adcf50def24ceb1ce59e699d447f3cd3fa881e79a6f58db295675ad7287379a6f58cda3cd33a46779e69fda2443cd3107779a67549fd99d623ede199d62175f24c599e69bd29af9e699da90fea3dfb3a01e6bbfd4264e551ef7dd86dde464a0f9e5978ce95b3e0184c97dadb59f5748458b526765641793a4250a038793a424e9c10f174848820e2c8d3113a720488a72304c49ad88178a676a1226b622ff24c2dd4430f3a423b6b62df79a616faf1c3c7d311f2e143a8541272b7793a42366b62b779a6a723c4ad899d7ba6169a6b629f42bba6ee6e497f6183ead9ca775ce9e8e8349967b33a3dc63365c1c12d5de252b4850ba23059c00cadac74892a2e636c214334264bd1101756c2fcf3a70233c6ea9f3799677aae23d4e59ff798677aae2304b93cd3f32e7aa608847f8f61e17cdad94a73f1afe85fd75cfcf3ac8bce3ef095efea13eb12b6c24ce06265c256ba2e7a56e2bba8739ef395df67309d63f3af62583806f31b579128cb7c813cdf97820b5abec7af972d84f144433bfeba107c7b17ebab96149c74efeaf36a67e1ec76896b97e2b70961ef0a79765fd36ae7e43b147c6e2978e902979f1e218410420821f452e7400861263722dd6d35ed3808b3047ca2cf2e15894c9e7023323d46e9b3ce2e05a5540f81d4b3ef2e8f76d87ec5e9fc3aeef9fac4daa580f0ecd7e6c3acb04b96149c0ffb7c73c29772c88f7fecb1c22efa7669f9f9c862c5208cefe6b7ef28cd1874f1ed5a93766a28f8730b91faacbf27fdd528238c505ace4ae09623129d57df2dc742648db5abf965df698727f0b2852ec490f119a9b9e3205c7d9ec467df974be06a22b5c1716e7e07c13c43a20fe3d9a1982ef9449fdf41718455e1ea99d81baaa00a5a8159e05051d19831639059f10a0c83e1e2d9c344effc7d627df2beb33e7ae7e3dbc79c73ce39a7b7ffb02ccbb22ccbdb77300cc330ecc709f3f61e9e0e95ab74ba6c4e975b99a7cbafebf22a3f4e97b76716dd1346f75477f5aa877fd147f44cec188dd4078a232e8f9ebdadc8b5654f91b2ea2dbfa8e591f2ea33d6ae22b37679762ecfad8ab455ff5445ab9aef6018222570d0772b6d8ff69d66309cff8edad57c1238d277f321776a2fc513ab78de6fa346a84449578a83999c049d530ad1d448938004631500404824140b87c379228aca0714800d91cc5a52a70bb424c6510819630c21000002000040406044646e023051383685897227f9ea706ecde210e57ed368f07f958e250002ba8f5184300e97a3837905eca16897a0646e8b9f9855cacf5ac77e599178a0c07219b092957feb580c02a396481e640530ce71f162489f5120080af97d9eff6db75dd3e6886a586260c37bd73d73ab60bd4ae41248c64cf53f78ada0a650a7c04930a0e7ae512702d513b0df480065708c3fb9d2c707acdaf045fb279b67125e1ffa7deccb2f9823c3fe0043bf44ae71c9481248c15e096e324fe9e7ef69792cb1b8c453631a9f403c0250b9de10d64283dd0281ba7ca267a0ec25f9ac61c08254436293a891050fe5cd1e2079307010bb58ac58970be041890db8c3f679a5702afc1b9871ccbc7bdf09c241aab489e85bb4d0ac888b68a505330f8fcbeac7e05da0c1b2591feafd0094f240ca7dfde418e7d0b0f009dbe1aedd49d31c30dd639d20016461a0481233aa28e18b148678aca67886f8016695cd0c95c70cb8c232882d012d64a5c24575963c213ec6e3a32e57102658fad4ac96ff6e24542cf46a49f75bd60c2af87391c1df2a1dfcb904c2df570665860841934cf4e4e07ffe1790f0d7b36155b86b5c83dad2c2182ec320ddd4d66d8dd554abb598c2ce327b2f7c5093a024978f34f8e8e9478226e6d8387f09a355ae4e655d858e286f3e486d153f7a0f5e5bfa456f147e9d5ecd1d6b2de6ca8b2e660d2fe14c57beeeb1a528f54262c7075aa62cd2001713778e4f47685d3820ba5c5bc3c53ca2f8152add69540996ca0b2990b2d905d44d59dac7ff45472fc78418d0cfec7f4adfe6c97f9b8e79f17fdcc6d2a943b7f304fdeb4db4526ff295545794aab75c3c74e67a382b51c02648bddf50a1403f2cf2c66e6a7f74411b38816c4e39f7405444f98d16fa2639fb1a13edb05b7923674d672ffb561b66a6c969acf07fc583e86e8b5bcc773cb1d9ea4e6e0a3f5bf2fbb118296db62ec6d09cb087cbb15e32dd094ab3fbbf13c71979b76811143d12b05313138c204675e026caedce21bd10660899243ec7dfe23fc4f395260e0982929f08710febbbd681dc8f16e44586b02c24e017efacdd4faa99de8bdff07eabc875c9699a8aa9e82d76fdc7e20f24e4c822ff54f8c54ae0d8280bea2897a8f87fa1e6a2d5d9f1fdffac4c9cd0125069c32cec58a3752079e17c4ba48629f1755c2a62beb4cdcb75f91dcad1410c104ac461caa78c39808135b78dad595f94b5cb2a9d66e7e0472cbd6e064244126cad5a7a568dc86e658e1d5d60080629cb121c318bcafebc08cc5296f59a3ad4bf9d9c73c56f606f2c85c0176e3374b71d7a487e9e4cd7298dde96bf9a72823332ce552251d463d1fd40a394663b1054b3faf4aa2e7f70c8ed9374e8239b289776d164cc6c906663e0045e23ff1c38ab3907e5462010aa420757d35afd9e68eb52d41e83072b8bee0e86a3dd6c4f265d210eefe988263e277941929c2f1d3fe21cbcb6d6f4206b0fc71d47525a87b459b09f7b3b055891b9128a20ed58abef59ff136c70c7a5317cdce44ca2ed2be948a83bdd7a31b5857694628ac147e63188843de3be2bdd15cf621735d6ddfe8aab3ef226828b218fd94d073d0156a6cd8c21ffb8b20c6ee7a4852756a77848f84b756ad59bd847e24a839f342289d5541b3d11ea706c4e98916487a198791f412fdf69e16d92169bcfe6e6ca9aad8fb010956eed5475cddb114b10125e1514d5ac7a749501b5b9e307d2d86be8cb932f4ea873ff8509637d3d2e0e94747f5fb76413cba425783802c097e0b35a88bf68c5500ae8de809ce4580861e8f42b02f90cd40d3ebba589bc2442d41918ff69776870f230342d987a6b4a9351b27f6852245d6501ea63d7b561a68d7bb18d53aded6de1df3d1aaf0df26c3bdce6c4ffea73c25fdf8aaf619479172f4303ec285b12cd4c0947b4159aa9e11650232c652a8e6338133b432c2f53b47e53420732ced11a81580aea532fd286514fdf85389d7c8aace23540382a95427197e8744d4bf4df0bdd517082fa91b67b025464d25a74dbb94b09501f2e0fc9dfc2505b499ca03bc01900ca038e7fe82af4674fb818472d1c3cbffc4bc85c1a8da6a84074b604a2f82174e4b26c442035f49d4ad6e391ef90ef1c277984639833678f8d3e6dfceebeeb5da103656dc40942f2c549ca87a86fd606cabf73193ef81414a9a5cc5cb396286fb838475f52115c90df312df9042c70a9b2d41b0b8957d284228668e03c499163a5461fc1f89f5830e70d7446f97c715346b83d802b1bdd90348e2a284ee8f9b9405ec6a74652957cf085f4ecfea14ae8e1e54399faee9b5ca8b944f3a42e93c8c406815c793cc8950b8f5c55a403db97574554854733a9626995bb532a4b54fab58cd94766787e410cec6f210348bbfaa4abddbe09e45dc3abc388dfea64b6653f806a46b84b2f22ca8a0f5f69e00e0539e333241a9f2313c297f2ceead541f80b8653af7ff2e7bba66ca7f27c09313ca1d8960ebaa9006be254a4baf2db725d3503f439b962c0fb750584c68a82e4c939f49eabe2337e1eee9b0e6fd264d4929e4b62ad67c0018c44aa2d13d9205bc7be634a018b29c661f87de00857b761f4ee1998c91c7a63551d6596f4cc225e02c641ffbcf5b90863c0858310ea9951d12284e806e7c95d0da80dfde107849e9f0709dca42622aabfd30568c0b90655161b8c7218ed07d0a951afc787109d24efffc6c749604462c13249207f411bb7fa21f7c70d5e98c3f5340d1b7d8a2b8218c2f615711175a374b12210ca2bf7043ead1ed832b956d60e32ffff671c9ac118b7802221ff64260b88d0360ed83de59faf4064539162a0bf96d3df183493640a1feed2e78f315406070811c9901950c4321652dd144eff53170672d5b6f30e0afe409bb1b520d783971a60b53bdf174b87f0339bfd22fe80b2eda2e9b918b4e265e8884e72cd7f07cdea66e260fdb6f8ffb8dd734d317249a68576490723d9eb42f3ea497df4b7c0c3409395765d4c885c494db8184f0896fb00a029a375a23018c72f3af56c528c7f6c742faac02aa12cef9f665d6475b4157b749a40676ea481bd1aca1088d1ddc5c7816390964a54fd9d89cdc37062f580c7a4b960dfce9c2b82170826f18d6b10bd1ff2419c28d3bb59eda4904fe6ba32ba8192db2b025eaae22d48d83115c9197af3e7970fe0f2939b9d5d0ba0145bcfaf3af1dbeb1f66234b438a1b00c42e880f759cbcc60d7fd4d7cbbc445284ce5d2bec9785b49c9ef698d92dbcd575feeab3ef040dd0082830f6c7675167c3c29a2c85f8596333b4b3249867635af80aa55d561479a9311d39bcad94cd2f2d3e5146f90ae284711e916ac5f6c1fe30abf73321758e29382b059715693901eab03deacf36f6f495e805bc82ea909a1fd616d691ffc8c1881fea0c879782efa132e3bc7a885c9eda81059bf08f52929388004e60fba86f142bf770e2f06f1aeb4a515f2ddae91d587763e6034729f3e0838e3a5bda2864014ab9960e94189fa9e5c53983c24d47945ec089d6d2eefb76ae3c01c9a31b38bf090743cfdfef7ab22991e2d117f961028d9484212c7a6503505d6ab34bb4640e524c6830986cda4f31d9b06c6a7f21de4488483bc225b11cfb0547e4dd4f267efcb2d93c896f7edd5f85e98b7acfad88e3139a8f87f00b98e52b7aa3b1280935da38d6eb03d5cfbc408fa81e691de01117114a478a98ae33fea9053243fbc19fbe476259bdfadab3cc3fd6e469ff160494d4254bdb74aa212934c2d754b19cc59142eb4223ab0be01e5ff4b546c99dbfc6cca5865b0462da316987675c1faa407356ba0c1048c8ff96085b8f56800414c6795bb2434301a7ca9fee15a69dc9606fb7781aaff4527dc8ab5070df9d3694d48d3876a91cb9eec222b9249197bf27f62e7ee59b8f031968410be3d5b53c82112b9e3cdf96ec3ef5705851a3887580a92ef0b60bc0cc25ef2f592ed711918edf0f3e1957e39f357f4879bfe803a18e115ccca0fc633bb85e2d708fa10da1b0b3cf948b2c3c323be63108fc64de7069061522fd74ae3fad819e2460984a46159c20ade11658842413020353712c1d6a6058c9ba77d418acfc5dff244608cf429ed3a101a332cdc019190ca8f413f692e26d9081278753f72e68e9bf7fd50883926549355b6b3550113b18d024ebd815237aeb097ba61bc96e201ab23d569e5ca6700149ecf234e1897bd2a956dc8b36dc75a2df7d14fc38093caeff93bfcddb7432ccf898f06fda4a3632e221c029f86d8e5d41b61a10ec405ae4d7539ea4b63085e41f1f1cf75a4ae33422fde294dc9aa27df7a7c3c52c68fac2e0e71f154f8544ad64152bece130dd10cf4595a99c2e23d187c6a4548f72ce216aee516c4eb989ad165f2686dfd005fd89f3e2540af0533d0a64724b2108450f425535f1fd0cd1ba59ba809dbb2ab199e2886e89f7ae3bfac992ffa756cdf1f1cbcd6b791058bf94791441af99873f8d962d46640611cbfa1bfdaff6d39bd85fa9bdf20f20fd27f14ef83dfad8adefeda752178030d195691621792b6414320c0be80a24ebe299538b8ca224b8de336dd9c787d439ee48898efd9ba6f33a1e0fd02ebef63cd7909a918a443f702562a5c945488b68767d553da6cda106b7b1dc37cddc4efb5474a0b3b30a3b91ba30cd0ea1c9dddb3aa791f70358ee25c7428dcbfcbd6ef26133cb1212c1456d041218d2b380d07a04e2f95a15dbaba9cdc9bea8ab33e3345500b375c1170d13fc138a223a0cc5e4e1e900a60be86fbfc2efad030dc70ff73aea368dee069f3e35f3b1cf79f848d096438c38f6ac64d16f0b120d3a11e370596f60d63a7414a24f27cb3ccb3cc0750b9de160217e965956735fe6a54cc8168927217dfd0965eafa5e6ed1a7348ea88b4a35bcacf29cc5b61b12a9b0a6751a84a587b12fffc2fc48be2af1255ad95837aa7c66a835469daf7fc940550420b7eb6b3f540ed954ad29ccc550eb90160cf646a137641bfe772b2db8c745d2c43f2eb86161d38ac6dbb3a9c3bc21392ca0254a07e46901818c9ce9138b0fb7e3bf7f50779341f3bd90cbacb010638a59202f2832a7bc4e1ca30c58f48677dedb42b21baba037a07ae701b3c6bef11f2ed439ca1213b1ca41e5ad47813182c9c61527284e047956efdc6dc5a25a530c36117de8b91d1f4326250437f5b9c99a50d40ab9713fec83ce1476d2e913e229b14666dd89ec8aa01d0a5efab71b8ee584eaa226613524860beae3db5bb65976328f61bd6cfda6e0f0f91c92205286e65c7848f912810c184a2852796286b07a0e3371f202f86de8378c56530bacb742f937b43d009639ff11b28ab1d06f882f84e427a3419f4346ec8e55661900cee6d7171802bf8648d6b39a568f6a0203c8eebe047a2804f2fd0948e3ae16ab12822020590d23e26d80c842553b4a0739a829cade8338423bf0d910592cebac65998d61519d616075b8a066285a065910b03d10e1f5a0782dc5a1e729f51d2f2c04c7b31643c6f2804159e6c0cf62904e30888f13eff7d1354605c804038ff4b7f6c42258c80319053d0378fc828c157e817c94a973d00c2da2d626fd804b263bd4ab833aab443a187355bc6f8713231cdeff720923ea78c188ea62dcb63e1025447c3f47f419e22d262c46f89d8af0f0e438e87f2c6e56dd209f2d81316200cad40515961bd8ed20d0fa19d7f2ab48871aad101e3bb1461da0c2baa7696656c5a8dac2b60bb2f50a1770a64b0119efdbb2001bd0a83057a7dab1fd87c5dd6cfefc373f2576575aef79f4407efadbbc68949fb8551a25d977bc17e5dc6180f2a4eefa9481562608b6ef55c8baf3334d355f10da45105c1cab412f7a7d0ccceedfc5eb59f32fa8b282f0fcb2123361018af8fcaebce4c50740638b65d3300d8166c9663d94dd1c536816501e2a7a736387dba9586d8de9d7cbb02d499663317a1912b4cf6d878d9fba1432361853dacecce6a39dcbfbb582da5b29e26b72a794c14059cc48e918acecb755c85ef21f4698be9b6451a84e4278385762e55fde5ec24e06df4358614968b65ec116459ff6de41e750b3875bc163c358be2895e96d6b8c44746ec130bf3d1559e85392202850455ce72d87102b0d91751d34398c9b073b398c19e2d615f2af60c524e8c4d83f8483c1b6ff5975c31375f227842b65ca1dfe0dfd69d439ed4d630038f8180c14219f8f65c861263cc869728effb44d5b77a9dda6f6ee658c597f9b12bf3cc541a3c2af2e977cf0d0c7c0972dad92e0f69beaa4ff13aa0605c843218c4561348e70770aba34269c4009786c2a73426efa647a2497dea84ff7f8c51cfd811ee5f29bf6462ab28c0f4a6e0316a625c849c716b1740c52a663b79073d863e34daac04b7df7de072c25f13f4ddf273923095506ae98278694ce78080b1cc96691cb286b885d8b894f88052da0ce3c806fde34e5b676d063cfd211c3ba61d91fe37c2d87e1304ad4317c6359a8baf0f23da1b6ee5e28c125cb26e2eb1f936f9102bf5466a99be413729df203e189f208b36e0003bd18c858be8328e92193fffd7e8811a4f2b0e7ef7cf18332d97a0951da1e0b679f3034a6b846d8bb9ac99a548f7c71a3c00dcc22bd44c828fe9d216288126b9547bc61dc591a80c0587b9776f566a3dfad182ff42009f27c05dfe3bd93d9832aabfecfb484d339bb80358ddb331d78702f270e9520d2b01d26544196d9839b670ce5a23039a0b29d261dcf7678e2d4ec2518d8472f9fec39b8126c93c525afd8a376dda1709bbf459da2b281f30cc308fc8a8e051fd67edfa2345a6c522b31cbfabcfce54808e7364006ad84a1acbc5774a3f0fa059629e94e813b7dba578e0035a40a5c54e5e654ee331c1a0cd352728feb193d1cb241815c3705eaa2a131e0e74db0c18b02de0ab1afb985c3cf28e74b3bb9e710ce21b25c2bff738ac28991dabe810fe2e2e759baa2881734e12cfa37259464edf4367c470d0be8ef1318c21f5c49b139bac8d8677a52282db004bdd2442cef5438b83aec01ca2b04888b159e18f2babc30943e26399a7e3fa7fd80c86a29cd3f581fcbc34ea443ec231c7ce6dc4210ff54f9970489ab5215f01e80d1da7d15f3dbe0ceacdd76c3300caa6daf9e10862e1690e8e19ca77bf523c5c5a5fa7736376c6069d6779488084b22adc88fc17a3e32cf26039c077c080aed9d51e1d130906aba208ef90fbd3ef091924e6d6743e90879cb1d7cb31345e8bcd9343e0c6b26d81a59b4e4c0bed0af69df6e1150a2d27dcc28e76760776a5ba81a3f34d4ea8c989c8de1638f0a602bb7c88aba1357ae5d3154e7d34db57df88c5eb94a10aa8129947ec97955c5375739e676b611ee3e92d5ddb10404c9e34b5a2d15d7785bc4802c0554b93a2dc2f43ef78419f41087553db1388835a8bf4b6b419ab4b527eb33d911ea51fbf43c3380e5819bd356fecf5b354845138eb5b580eae07d9eb04f464d3e95ebf0c4b3a980ec2854ec49c3db549d1d159fc2b9369b8a549e223748c8b19f2a6acb2a4997b68aaaef9ef9fbcc063a91713aaee17cf28d12e5c1542f0f78b85043a410cec1b0c97e61e23b172a8cb46de3e4966466762926bd340c8d4c10fada07b658e8e169aba41758e4a747f91fc05142d61c23df68cfbf7d743d34dc4007955159a11ecf461cda6ed588e5e7222297844ef40c69c52e0e5a62858aa887a628e6964a8372618c3889ce64e018c8e7d3527e7baefa41b396608c2b4f744d0aadd5fcd0442434dab5b56c74b90cc3bd70444d450bb3da660adda03406bc2b2b570d825ea027fbde6b03a7f7b4c379f7408bdd715e59f8127fcd2ed55b696caa9dd8019a74a26b61f073fde37c4cc1a74746ca7c6d3508dc3bc7ee3ab025e1201d2eb601fc7c957475a5b46e14aafdbce901b29b50b23261ab17109b2f5894c2082839b4fdd292d1ea3deceaa5974a627f430b5d01d42e5c0edd6fd06f2536c4bdec1610dc45e414ac1338cb10bb78a754bb725dce1beab427ba47ca45a60d829d78adab77a84af6a4cf4c08d08a27dcecac3c803db4eaf6130aa53acf4ec52db0a96c672264c1631b123a4bc1cdf2595c9c696a31637988d42b4605939688e0be7dfe1d10180cc14e94cf75d7e20f7ea29e9e2b333bc88bf9e96dcf36aca03b71c6bca3341328017e165cc5a99034f8a134d7c2c93d0c91c3b980583b0d8707f9e38947389af08e4dc5d9e509a47d6b1be01478cc5c55b5ed415bf0aeea500597d1943ba8bc6f91c2a0769506395acbee910ff74725574ca87c06036bab5c9cb862bca8c3cc5c5c9845ef2bbc9ba01d63e1a6a172418c0180259e4437a8817a53c2f91d760b042bcf83100ebcde51c640119c05e2bec968b74032789a7b0b4e524980b81d5f72ab98acdaf8e614f953cd2ad447c7ecee4b5e7eaba5e166400939ad2f2c7c72c7eb62b9686fad6d0f89e6d1cb2e0f6bd8aca09e34f5eaa9dc640fdc61c423723e31c651127dcc6e6f71475df6d3a2e03f3865d41f08be1e2c0e37148d5ba9808d44c1c53c5aeaed9e132385d1a9626f8872a77ba3d63478f819cf9a7a022026e680aa86bf847c7e72138dcf5f914313a004430aa7f94c432e4891b72694af2a713fc43037c094501074a6972f21f0a962fca25298760adc59e144b759565c6284e41c4a299d071dd134a48f61a6f0133dff6b4d580e51f2a2b4f58bc54f5e001161cef1a5e5cb9412f29f9c9e7986a96bcf04d9449b3d5cc82c11317623d45b369e686f316f705bae575e598286f1c26aa68a6ec595f0207a5c7330ee4438b7e269d5ff10824472a8e3d71231c21789ab892ae1b53e29e8ffeca4f0073d903e602e7a883d23dcd202923259ed14ad91fcbac26ec836c3aca91a5a6183d72778fdc257bf5c80d682b02f630732edb386919a99bf10ae2c24e98e3b57c0ef01fa0c0d880227b68c25c276d0a733d06a43e06287d585adba2a5c81f2491dabcedc048d75c74623d6c2c29a5e34c3bb689073d6c1ecca03944b4a8f77464e2f33665218053afd188ec7693add21b9e334f5cb9f99caaad23d052c65b104eabe1710bfad4641f5e87334ed95aa9d56fb3c27c43e4ca7f584408115ba066e2a5409cca409fad2b9370e289c708c51e6ad72c1e7a1b14f61764dcabfe412272a2997b2ff6cf8e2b97b1d40385842e6763cd63dd2f91ede20e2f7a47b696fa59b8400658f94fdaaf135f8c898d307a8de8935694b1f0b8331bb53b4139ff760b6ca3915c42f412d44bc6ebd8566705c0e003562bf914669bc5f46d0d866621fee4e8f45db3079ae63647bdb6a281b4e10e89ff60fa1ea813f9f5588794d832499f2c0dd78be256989273f403071111f1b32e7a1ba378d076c858d899324634f5747a07d43210766fa56b8a1901c2e6a480983cc162f9323ee38fb2dffa326dcfeccc25fec010f9fb3fe595760bec6a9abd3c4fe90bfe65c06fd6aff4699abaadf7c79b44e5f70cabffafbea30a3f3491cb56f29c4676c20d546649f8ec0e99554fdb0f81308290ed110378d5f5f06d653a3576f8fd629e734a717179689bf8d464d4a844d04a848c1dd2944a077b3e404c5e563cb0ecf9214b4600d76035c7dc7b9cd6d0631cd8a086e473a93c6078b96894d05965fc85bd5f09d54f278e53786a4dc3f95583df56a4e15231f8974f7b101f38cbc4228899500aa28d7cc0789fdc947632a984c646bfddba11238d3cfe9c30271d0e9efd04872f08d933cd1a8927f1293273914caa96038def512b88cf8e7d18522461452dd1dd1d924613413a8f3b5b9a871e7eefbd245503e2c33f424f82499095b8b28a559ac439d452caeea09ee11ce22cc30843a75d57b8134c86602c4d7e026605f29ec97ebbc2ebbb7c019888d9e82351804b827348172c3ae35f5e58566c97e7d0a8b30df72f395e22eb3f804684c95f08b0b0e97ebec2b26aa3ac7f490a16f29084eab16fe70c684833d45ceba198fb6853c8bc7e4cc25fa3fc9ff198510cc4422888467d4fab741e7673d5b7cbf1aef53772f0705e016c4eb9c383273732203ee833041b74d929b5368990080692d18c3cefb9f935490114faf4eced929aa273d579954f16a79e2d5817467cff5271bf24bf652c8e51d6b2fa322b3aea7837b7ccce5b1c97fa17c8a03939733b9dc132625775acd6db362468676aaf0ba3f0f912807f8db1e2e4f676fa8287e6b45503fc9867893b0b867b8ed517d87542dcbf4b699dd954619abc0958a9daac304fa8d85c1ae2cbdb36e90571cf4b8d6c4415f06befe49ef9773cc00a28814845d05776d62c327ead8dbec65901019446de8fd8ebe8d70f257cf80dcdfa3ca43a9b611207269c4072c754e571f9fa13025ac72c3e17c05ca5b826c4df1d4e1cec2cfa0e4b7405e2e2aa10bd9fa7b0c7b3f727ecd80d2b78cbbdd195a94a6ddf1067d8c8355fc1b529dab0590f082a23c8914fcc3716f31ef82f89aecaec21c3453f26e2ba989856e209d00dbc6cc214e2f420b1fe3e28fc60c8d7ededefcffc4f2a8327fc434703e96cc144a2b9ce2d3322e639ffbd36aba2e580ff4ba4cc54a78baa0619efab2cc962b78be202845d000b2963da2451fb2ae1fc0adfa2dde4f537b76bf8e35990eed28ddc4d7f00b75218e9c3b0ed4d614062e085a89b35b09e5bbb0df5c2c817e1eb01a2bbce210909a2d35c4d394b5012bbbca842fccc408a8bb31a0335400226e541f8d7757f30e8e436d7c7a2d56d149c370af2f12f4ee8cb97222417909ccea51207b0b36c82461c5fcf20a5abca5ce69bda738696c5ac86b40d7c6e79c54ecd6e87ae68d4481c79426d1ff6341aeff05f8bd7f6a1e91b20273ff2ce4531396ab7cf34123aad3ef2c895f99e6a5873fc0635f017f39e51921220ba049fd884fffdb2c2e49001ad7e5be3085bde8379f4200cd0d69a827fe372c3bf6471cd4ee632cd2432cd5e37804f63fc488840121a96f9272985866eb017c1eeb8d0f945ea46a0fe41aa15f58851ff82c6b405f3db0538939e0629f20f8270f3b41bd003d9382d37034a4abaea542bea44e20081898830a3052ef9d9b83cedacac3817bc943582588ffe895cb447a42761241c7fdaacc5609af0e70165affa49d40c344431f8d94f1dec22bdbd73a5d4b5430749b34e9edbf5c84917603a23f1aee0f46553ede37cfeaede3f5e744031780e30763ec6c034736d1b69db0e887840fa1d226767db0a1b7d24ca027a30dc013372d19fe05bc0c5c9a9654261e35570052757bb1d8cfd412bae06e8d7a52a36f55e6052498271b4fab423098edc48c22a463a598fac20d5a80d8fc3f76a8900b2810e6c0b603b2f38bae45856e7e35ddaf14a7cd7929dfb371dc32a40797e56073d9d61b4995c474604e2a2c5256137f9ba190219b59c8d6910eb7fa3f10fd825c994162da20020a40d9b269b847be3018e8be24d7f4263c262773da76f08ccab34b41d70e871ba3d06d3f90c33aca3a1516c6cba39a129db475e50cc3522aabcc33fd47a928a99eb718b0cacf4a882cc7b3c426363df55cda09c2963f93bf5be032abae5e56c78d2fb5e213884e849e87337b31a490a09a60411d8a960d9f6552bee9c20efbcb548495b972ff806ffe593df63fad7e05e81559a1be06b8f6e8e4b423decb59eb03d29ebc16b7c12355f51ddba615968924743fa257ff2c81b941f9d9202eaedb9460f6bd81188354e16ff56266e1c75d6f5dfd6e49ba2deae2e778b80f32b661cee0ef3083e04faa8f1f28f3cd19f85d23e443a4439346ecdaa7496e089f4be65babd6a3e4e5e12a49f7579aefee7fdd4df50c750449dc0eb8f466015e9641ab42218908c104f98fe549c89ab05598ee2efd8f2a581fd908b533444eb89350c0a04ed7a7b39e8429d623395309da542b71f8e138627672a3d66980663ab066638cad27e086298741001aa9a11da8816a3e62d5070003d1d47429a962cdc0a4eb65add053134cc1959d3e501655c5e68503af23cf6a832b803f6de5bf9b5e20e0117140d0ab21e2d08a0e2a4cd882158e06082be7fbdac0d8258669456ebdb2f81cc33909c23abfcd0e2b46d6b37657038e53ceea33714a18b4ca7f4501a0b73c1db4bd8b7bad51dd2af1e0785fd30efd3eb0d6c86f3ccad2940eccd7b66356abf23be8d868caaccc7077cab31b47bb0ae72902537cd3d95cc264768f22aff41b93b85257b67c6b8d420b03d5399b1d273bf0fd1d3d1e317129ac0246de074595917cd6212c200213a8ad18f389a2448e3cd16d6af94a181c40aaa36bf2a03933b06e3f77916da67e8d8f78f3ef08bd4711925bd82c83032cedab450632f241e63eddd91ec1be60de590193a15943d29c72a303ab11dc9fd9e0c5fdc35b7465af8b157c5c1b4da91e7b633056b917de4c968bea8997aaff9346145482f13293d144c16b393a9629a195ad2dbf65d63d5393a0104ed0b605fa75f6cda88eb172fb540e8d76a58e0f50dc8d5434b6c3625c197589b2e14744fc72a26e0a216269ea6535fafbcc571680dde768404d40540fe8f6280064b576d52203ea155828c987ee9bac1d75f75fee90f6975b61b25a9514b6e6d0855f9c7c8e58c013d006befab27249207826bcefc54b1140ec42ef646b3ea42eba3ca7020dfa24b637eed7013f38af01b7c7571404def14bf9abf3b3989016ac4473fbf80897dfcab5327f13f87f02fe2304960cb120d37e3fbca85b9cb63c0e88c2b8f53ae163951517f1babfca7c43b67d96ac8138b61f3623bf503a77824ac2cf36cd36276d17363401a54184bc13d751d655799cce7d46d96822afb05a6c3f6ddb926b08c68777f3053f43f5aa7a933576e2d7ebac194a41f8611f4bc1621b09a84fcf9c6bd2cf99c07ca6d80ec8d846d3f72e0a506a2e6a38dd9bdcc8616b862eb3c7581f1e5b7c1b1d6215625d7c12d21ce2046c25c30e7d828ebfdcfcb0e61023face4adabb9046864e20ec52c7b7158a72d784f783cbae821b09210c5cbbc3fbecfc186d4dbbf4db05ae3e7758e4f73125efb132d2ccfbda2bfa7720f25138ec23048a6a5d0aa9abe8a599f8b861af501e397d5d987c44753028e0b754c144990eb10661e81b90bd7d2e67aa286b3d2131fa5f7c9674171e0435420c50a76083a216f2456cc618d8da12dc9d95e6acc206ef5d177ad7f88051c33c5c54436ee0359c4fa4ae4d5e431fa378a3cb69897bb19d5b7b3e855baf0a1db37d509c63f76038bab91002ed76fe2e5e031f7625b9b5872d434734e093d783c3c245e7aa96dcffbd9417fc9a8a20fb53af757030de23ac31af4dbbf4518df2df697e8db7963fad17917ba632dcb489a733ce6612ec27815ecab6979bd0a0ad8da778056ab7da24ab27419fad0f0e9ee7597c127f699ea00b006f0ef72de9b7709150654072c935c68094620573934adf0ce43b3cf66275163e715b64113735ae6774180d155839c042cab0debde8623ebf018466fe5ec1c7618186a3c4385cd454b627b2f8f174330663a50af24241c3e6bbfc9914eebb4208813c8e9b24df5474632fc6de5d35fbff3ca3977b4e445c55b96657f53c12addde22b432d185327560e3d71803b0eb96500f84d3d726244343ca34a602663cbf624123130d56fa3d8949216023e071a673d197ad44c2a4e2e0ca23475a872cffeaa592a1d28b07cf1a98f9aeac17625f4898657fafe4e4deec1a0c8820b339d2943d35026797b5c7b4ddbff0a9f785084f33825dccd06326eb292df10de1a8650d4b49ad0d58566b5fbecc2e3c2e87b213a0041c66b0db0e3376efd70917166b3dc3f8329091a147bd1c6f7b018f9230cb6fdc1bcb003ae971cb8d11ba35db0c455de2a2aa88e67550080d12074eede1de014f9932a917887db9cd854a4f1bd0a07855de0d2cb5845f00a73e361bc40dbe75d7aae1759d5266c790b74c300075c8d7e050eac897037d199b65870948bf814b64f38ba8ad2946bf8e19965076791490caeacb7bfa10c1736ee8d05c979c353c1fb692f89fe4b1583e4a0d6fdd5f85313cb6f07c250d9cea00a1e6536f2da72d39b665dcf827bf7161cfb274f5c59ce9382bad9eaea4f46f07a1a528e724a253628ebb157ad1d3d8d86cf0264271ff6e2d9011aa8fda1804e3d90a528b47525659e37c1c21d838925a2aacbe72542853a51aad42832b9df7a19e1788ee61fb2a8998481b0419bf9d35d2928e00dc6dfff2eb43ff618e4638c5ef4bad5c4e824a687e3a2059c53297f42bb23142bb47d192b11f0aacc40debe003717194838009c24013746fa8d1367b4776dd411abf9fec62d56f2780cb793f22b0cda15dc659f005a83e8681ef6b9542cdd58662993ab6ab20a26954967786936ab139f887c0a8487cc49a38dbcc88e718ae8389ba178954bf84c89c013df6d9c4827a9f62db1f8bbf7c9e30f6ea2c78963db2e015bdcfb40b2396d76997f12f2ac3aee20de69499d4945a56f01cc8eb34418ebd019fef04e3d24d9547790d90450b11bd99181c5fcfb19a42f6d8ba403679a1f164af28a23a62953322c9e0d91483dafa74f9de44902b2b608bc62b3f6b173edfda1aa5b7ce9578b24aa99fe44b6054941ab0a2ae3aa260f0db2f9a378a9474bccbd45081fb82b517963d2fa585d2c8cab7677f2a3491b9d5c310e375e8df28dae08fdadb2957d970e921b038934f1f3f84a21936a83066c668d0e2533935b27fce0f958093fd85969460fa9c342422964db150ac6f8cac4213394c2e41d12d75754c471f81fa129e04ded3390701b2c2eaafef962fbfda51dae735ef3d03c50665199591b8b2825feab73c0903b23e1159c314fa943ee6ad015561ac688255de3d6eac0c776016a326e2cee7394a8309e6b7696f13171ae96c5b4b27bcb0cf992f2a32c6bbedddbd29c96106f09e3098e82576cc75b7267c14eaf5792f15279fe5bb65542a2068cd8cdffa7450266a2c1328f9f635a155681a895d6ff8496b7347cf08980ade6bc11b6705e79f37ea92311aaba766868e31d3fa0fd640bf71017f38c6a35b88396783a0b8c9832c27fb27cefcc5c60fd2962eb6999a3381001aba8f2ff10c1134f9abdfea850e402ce5098eba602471026cad731fd1826eb408477658c86fec5e2835edd839765156002f9c25e0f9ecad2839427f28f2c1c456813211953b0b62c549fc403bf6c0263e51299f9eb1aed7049064d3de512713eb1461ad4db3209522e1d2e3429ac0d9eec0ba2a7e97741c72d284c078c15ee8b07be62c9cf5eac53d5089b017b94cf09ca463d5fd40aba5f00f6421d812647d0bf6d24050aa498a2c47fff886da07afb5afb2d64d63367c8ed87ae16f02510c361fcc3636a51532efc119fa667b66946921dd0131eedee5ed861f0dae271c844b2fd4e4982059392e1df9f22996b796a0f74e3e415476e4216249e926a663432527759d911e92ca61318a7e0152459f22c69c5f3952b65da89ee8b35052350b25c9288a21c87971081a0d99f1a5cc19ddc591941421fa80083dafe953f7932bb1be7fec933c87a3291e3e2f7f950c4a540185ea5180e57ae01ce8da177e5ea5e912b27ff4ded2b29b515324d4118da8c3b6ad6e2a735a7016407b8126769728d7a5f6aaf9194af419d2c26f7b4fbd261666b634ff86634ee1b71e7684b3af32860d3a55439433adeb2257b340e7d5a294a8ec05dbcbdbaedd3ea468549156bc3444382ddf112318e53a04a3475ce40681b1551c4299d2d14ea68a668b46da79cb9d978b0b5a2a827fdc542227770ca02c659b18a86fbe5fc554c44efd0d8e9e96374bcc9e9b7849ddce232f99e69202576d12eca32514c59c02436863643580ca9ec935f6686b39fe5c73e494857e42e9708500fd5958317761e406b6b8f37d9f4bd886b354875464ffeeea63f6416dcfff47e58c617824263ffeb678f02456196e43461e5283b05a89d64a4e98823a5aba8350d4bcd538518b25e8c7165456b61f2e175830a52769e706be22cec69d3ab22d47084e8d6c999c713af351d472384d8c16ff515ccd809f917ad76f2862c46a111e1584e567aee8432af0438d264ea2a2731f8cd97ca9e7d293498b809cd59e58f8e12b5c24091aafc6cb8a40b9b4408d458ea6d847b008587991f6cdf23c8d0da51887f25945e619a18848eaf5b23ef556133790b2fcea2995d9e1a14dfdb35635bb4f6bf474b85f9d5ae29689598abec0138d60d841da0f73ec8a75e72974630d38131be1cf71f28e7aa8d6aae23c04b258165a000bfe137d8fe5978d846dbfd7bf986398699e7e546366aae1c7680ee673aae1aa3ff288dbd6c01de9250dfcbf374310feb0bce1f308dcf140081a1b2da8a74d4460022f324464310ac6136b06b1601b467c59746a3bb4cc3c5653c7ddbfa34173cf3eb06a08a3f5f5328f3edf06b1df113d6a45e095a2b322aff926aa4992fc448154c91e3c900e9ed811e5e1f4da93a00428279334ba4780115029db81dc6b5ae48c02c128ef2441b926dbd8cb948f76476fd82392d5f6431e66bb95a09353d1bd92340b1bfb06f3bc7e80428122a286a5836e0579a8b9008f823c2f711660d3f206f261f98dff207b7a892e6307dec32b79716a9d7e710a09783200eb191a084ed2499e6c5a97e5167411bf9b23659ff06a3714beca6ea98c04f9ab794837bc2678afc8c7b75afeebc3118e55c8487e7af75f981d12428ddae4b45a339521bd23ee18069dc1648697fe4a5c58cc9de86029c1e7d60ef33d4de4e684edef69b81d15bbae3929fa126e8e50237188b83b7fd76598857eb3c8ee09234800aa532dfca83aaa7d90d5dc9bcccfc46d05808bd4d0d7322c4344bfad9eb5a210d046934891d5d1817214de11a8086182619ec94f3b810c79e9bb5d5020393dba90ee31b92f28c90e93b5de731e0b13a1a289f3d5d384f8c92c6ac20f93a372792984116af3f0d6dbed22eb4f98f8701794eab0e5139886b854c4e2a67bd7788d82b0dd2d5905e8e0e9df382bf9c9797ede38c06470cb814132a405b4bd177e3dc22d1bea953b4fa128ba50be703a1230bf0aa85b8e355e45c8e6c773eff0dc529d37d2baef434092c4d8ba1ba7e26c53ce2844b27c4648e2f4adcd2e6d7dd2b72d4ffedb91df5da0634ed6644079afb73b0d15fa7edfc874bd684fde04885ef61ea8dcb6a742596d189068a71a29180531508425a1b52ea8677d81c076dc602e318edbf73018193c7889b1628ae89c1a4cbb02c8fd594b957d6da7ad43e54cc8362b859151c8d47f93e52a39fef7ef70e9e4b78a5bebd4c67d7cdf816c12fa77b1d429483f5c5d33ef543657b62ae2fae10086a54be29a88f4f00c1f18c2d3a0dd0842a084a04cf2314c082d71c8bc53fbb57c8f72ce8b7e9fb4e92270850b7b34ed55c98bf466b77574865b90a385eb16c031fa5797496a0c20f39104c302dc761eaa4b558ccf7942dc3fe1ae0269df7f63554bc71227695ae0c663b08f6a2876fcd46e2ddfdf5e0dcedc6e0981955784c90d379310d65f12e2256678155883db6a33019db580c8b3def5ca85b9365f0102583cb1cc8f0c9f977c1953210c81c6984e2c161dc70074c09072ad8ec80f51dc1f6c385bb6ef83180c93c1c7a6c17e46460f6c81037b8dd7eb5ac8f688088aec2e82561802d93216399a8d249b6a4d276cbbddb52eb9cf201d7ece12b7b08c1280b9c8cb16c39228ccf2c3b8081f36bd3033526ebae5772b1b8ad912c7338e68bc8fe91d055d134cbe03afe7114b46508de6bee3924cfc2ba878145176d36f5ec92507247078292364fe4adc85244ed63272e8b8f1277a589a0305a91a644d9612e27e35b41a93fcee80cf6201c3ce332383b0e1c9e752143e5357e597221d94a41b5010bff34b308a7cf5f43df95d1602dc4af74cf54269a198451defd00094d999393e155db1b663046b363e655042c8d2346a65bca9a0c502742c3adfc214a39fe4575cbe5a4843e2cfc53c144434a9751c117b2ff6a8c2331f23a520719603c2422d9187f3be152276c6917bfa8a6c612493566d99e949fab3a4f9846461a4f2c973a9750ccb3f2c6e72d491609c6e04bd33d44d6a9bfcb4c4b16fa50fda739235c4910f34e8b380872d6fae3128954fc1accc262537aed7998453726f529e4b8d6a670297b2ff278856697ad6c7a4cb7ff96919159c860e8a52a1381a69f0872e0ba5d769984643752550efb71e466370fa44f8c3092dacbe30ff3a23c86418cc51c2770cc6141396720a5dd7ebc68d1bdd1d6fbc071be14b45510fee6f9439a0aea4032331a47713e04b34fffbce6e11ff30759b0c36672b88dd5c00e199861b150dca46678f8f20965a1861168def547180bb9bb9966be94dae07d045e37adc248702b0354858e1283f35f647618e5d6f4be08890856ef3b7d05829e04a00021aeddb1ad637b67557b745633f562b059334179f1038b8fb43297ecf670b46282e5cc70da0dc7021d41996dbc852fa0094b0917913604aed395fd4af08620317bd0cd7e3a5219378fd2ebcf79800729bdcf98b41a252a8d7f65284a17ab6b0a64b283f0f24f01d14a15682bdef4f9016ca834163a2e0f87c407d2be17c62126028bf71ff65d91835c0ba95d7071e6bccdd9c114fdd89d76d469e52364d077398921045cf9ee262b48c4ba91beed1f283470723d8b2b7f815f0da0c63622bbdf62b9dcd2bd4e546f05f76c98a492c7a9dedbd635e601e8af3b693c70fbfa3533361ab86e2f1dc5361d5ff331dbd05db872bc61278d44a9a9dafa39eaa8a24f0dcf50ac5282c6807cc63f703b0b6c590ad5609691af332ca29c94847ee1e78df5d05dac3b65a8fac900349f22957351a6aa0007e34b329f3f896fcb3c2837cf3e995e42fe483046aea629c33453f07a84625d85b633a6f17d64daff81341145930032f090679e21a817d62afb4a9be87681ac4027755129d4506ce5bb0588cc91cd382485ece3caf780e277b42abb8e459605c5416ca3e2e02fb9e290f4f51b5d2fd91f006e24ff802300a6a8dd18253054ca4323180970ea29d877c4371905118d862807ffc73eee3048a8206f54e7292a7ef67b643c0bb30da2ffa8efd9694280037f55dcaf24f2293f26b210dd62ff7f12c0cf03b464edcf451db04bc440fe7910d1e04666b0132824edd08049e1d0a72b4a577027e9b1d70348f37b90175505ec9028ab32308852c42f6c2d1b0c4fd2c940759f6b11708d49f349b69c6906f622b947131eed5792f3e3a41750153da567a05990e4a0b58a80ac90cb156b74430f3ed2eb862280ebc212a301fa7b1182f9a414d4ba78742c7d53d3a188acdb06a0873a5d476bd5f48b019543848034a05425ad9abb792fdd48ddbb27a6d529ae8eafb965dcd4abb177799e1338ca68ce444ae3f3a66f902d784cd948e890e8cdd008d21c89c5d285f381d09161df12f8a68b2a5ed400c42736b0caf682a6b70a73ce70539035a13b1f6f8ad0e2f29e588cc946a6046ee846604053fc1edd9ea1440d7143d65124a6869ae4dbe454e5715b69566572d6ccdd48a608d4235806d40700464bccfd192e2d0e11101c7650cf8ec5412e0529c1dc779b0e797939fefb0c3f62327a7e896f60672ca86aec4411617b066ce3f6081a3e64090137d0fc41629d86d7e7116e0a07b5099155a7fdd1c051a1ea6214a5161ead9d91a99378d702a600397fb8aed05ad00f1fc3581d0630a761faf2e27627bd5904f47e2d39698aa22745e74e5801eef0cc2024cc7a39846c80643ca14ec43c73704e65d70f59aa1d7748ef4f91564d0b3f957fcaa73fd853783090c2fc43f707617a452eac27c8740834732d308e867e820618f2b4299c2d057300311812b321e2be85453ce1e83491ebedfc3dcc0e64f71cbe212ccb77caf546ca3e0899baf11632c6a943d8f9db0eae5a41d5dbd6ec7f850dddc0d88f7ec6e22f7bfb76307cc2b5a8807a09c533a368cae75debb0d8526563e2f6360f2751588b554ca24ab8ce96bb03bcd391e11d516116094436c77b222f84335bfad625de8692117bcb7716f4d112b85fadcaf89072ec1e40af1e3087faeca33e9cb90c4fab78691f82b6d167fb50375e57dc04fa49ba0e0db671bbedbd17c6ceac25ea24c528f06e862e015c75770919f199d9f8b27c8a75b3f3b756ef41c6d29c9efb351f3c234fdc4a10c47e08cdd722ee50230966d7219409b8a58bf8bf4b49463f29279312fecc31bccbfb6c938485dc35186b645c850da9df072eee6ec8b3cebf092d63d0e85cb92a74e25196f5b326043e0f8dc2d7e5ac4949ac5ee9f583de2d10495408f8720d6e46740f9df0a282b6c4779ac88a83e0e81b973e586830c96eba57f4d365de854f4a9208f9c63de7a41342f8482009f241c2b1a4fa10896a094a0e300d79ad626d43cd2d732fc7cb70e35efee5c0ca2e450f2dd943802f6033828c2a76bd0ba4bb878841cd8ab8cf27e82eef981578b697bc8286213e2da5324a346df3b0eb75545d255bd1749ddb6e3929153d47a6282e9430b967afd7f815fea83e309972e9cadfc034dd2b43a758f680b3d8e66fbd3187ce4007ee0181192b1060819df888ee2789f4071c722cbb4099c8caefc0f69b190b1e8b15cdc29a7158aedc97d3c582a4f646ebe0421f0f5bb836451da51d47e7ad77316a141592d7bad17225ad0b4b8d5302c8e019dd30ea13b2bc11845cabe2f7428a4e7e9ffe12a199259f84a674b98484cfdcff002e06bfd451f0970a7d4835d3d9cf20d1293bb7bd4c56e8eb8774dd62c4842687e691f4c19755e1a1e46f02e7c052646c10aaaede745225dcc1ca9dfbaa2d0b308b4d06a305937b7c805694f82465bcb35d0ec929713fa67ed33d7c4e4bc2de6cf0ecf86c050e09fb0eb2aa9ae784ca13dc69e784f74f31768f9278900d89ccdd7c2c7dd4d7d057b7d63139eef66e6d9f22a9282346d0c9eb77c8cc1432d516ff91cade7c2119e21bcca5678e4eeecb80e88e399e14cb62c336e7c44d98b7d3d41c74cd499cde6fd4306bd62f5d90928ec1cd4c633af65edff8f740022116b9903dd6654baa463ecb2dac2f06a4a23a2cfef12da8809392bf9c7269363f0da39831a2f748cd392c5d0b5c11fd6bd7107e4bbc5cba7adb5525435c38916af512bff9aab91be8e250cef94f78e850cef85de3cc4b0bdd007bee9e7ac1100a29672af8890d8acec2b4391403ba2c4c4aa36a9923c26e25affbd7539e0e20b9334e344a1032071818cd50055d0dcb6eb06fe44fea18b438656013060dfd47b7c0941fb579068c7216199123291fee9940072242d6d6402a297f960247c3edee786473fbaa5c039229d9be522bb5bf0bc3f4dacfba1ddbac70c49500cf554f2052e1367ae398a8ee0b8887d59794d2462b24cfda24baef663ac6f4d66e32b1407ac82c5b9562d6e6514b924c82c28245c642c090f1c9a090259d2729d06111e988f9685ee25c9dba0ab533a367528e18fad44d996a384ebc6da2a7a7081871bfdaea142abd80cb8c33833fb7c6743c984a13eb7453d9d0ed0c65a5cca0bff1ce4c3cff3bab1654410def8c4f70226ccb7a7492adc5f0e41b6f13c63c0a719b3eb614166241faaefcc2b9e0caaf9ca55dfe8cfbcb84b93ce7f77bea602102978685c024a1b9d548e2484cfbeda226c7758c832fa0e7a5230862e6b6b190b0a75e93a80670beec3e1573c64b22ced79b62c8f7372974540fc5327eda30c822cb469901e93681c68835867807dc6e7853ffd17e56f5dd30fbd37a8039b65e9ff72ed9cfb574d111d83c5b103a71ba8cfca98d47f8eec00951f2fa1f36342b42e53e151e09984a8ca226020ca1d471041104647182cb70ce0d9488abdc6fce503c44876d961cad7f10c618c29976099af476e4db92a303ef2eaac6558f732ffa2c343a88e6434587ce9ec6539e30c91bbc1b8a2eb58d117b0c92dbfbe1794eaa5130d20837a2642aa1f30025fefe6e8fb0af7523ab07d218c1d73bcd26f50595eb909c978ad96ac6fa8e3e91b847ad0588fc82738479761d3fc665ba934ae0a70c8c0ba79d610e6cdb8364997e4c2ac6bc71a0f9479be5779c0b3378992b65603c91da0dad73bc6c70b59757985e34af98c605acea2be9a25dd270f8c67a27ab6b6bd86d69b41b612a9a17a8649099a5181d724c9f0da58a1566716acf94d5122ae84029968ccd8203789b1043a15a2ea2ca64aa2d21fb78c960cfa338a14b402eeb8e701e3d10d2fc91b4b1eef94c2cd4426b219bcc0c09a23ea4f0a93d2576589f2792ac0a176662eabc601deed90d3070ff3075200c12cca75b66317589a42ddc16381592f03c08fd8c422992a6985bcb4c529669c6e69067d18d0e204d4b345f6129a506826899c38f1cc63a626034e80ae22211059b3e819307a946fddafb12f09391569c8876ec22642830108f30c415a13144d15b05fdd61840acc38d04a6743fca35b89297ba2ea76f906620ab1f0fa7342bedf761263b81da9cc897993a20d1db5b31100dbc1ed6f318971caad3accfd276ca37e5dea11e57fe3ee43d334b2218856a6c505d426d4de924ab1b5d6bdce8c2c811cf4e77935dc5caa9adc213f75bb08d80a608cf7043f1bec1e09d033d58425e26c1eeb939863f96dd8aa1050bb7c40be55aa33f0a87814489569a6d620d17a012037a6012cdc43c3c19e2811a6e9c42e5ec4d92bf3880e290aad99e2926219377bb20ad61506904d5436c1c01bf0ee01b5ac1d951447be2fc659a031aad0b4af02a849d961c7c761983d40a9ff1cb7c5be4497a8cd3ddaa12325490f7fa091d6c9213db5074e884030a7e1b98d6c129d610b2c23cc7d92ad0f1d51ff3b2e0ee3d1f0effd3472bfdf77d64cc6317bcb6236ab9b8cf6356cbdf808fa9c4e8cc9ad9d0ad08b65a103aafabe3d7459adee0c2ac5bd36a32cdb1f20a3e485a106a95770f74b2682b72a57aec6f5093777930f310f5017535996c12e3e40ed63ba1d3a0a7eba808595e3ca87c7f01182a1fabef5218ca6fbcbd9d586a2340607c0712f78982f1bc11a90fb4efc30866df135f359c07292419e811f6d581cce5df7864e55d9d2e034c5df64304cb8cc2f7fa42bd051fcebcee9ab1aec203c095fbfb07d94d764ac3e4c8b5f607991a9c198d6f81ed32d1613a04ac620e7c073037532be5c6e3b19eede56ce829438781ddc5a608f936edf8c3e28313d3b7bc1a28e6b9eec2d009213238ad91656b2b985a6a8ab28285e18c6ac1918f62d844a5e35fcb3eb366d055bed26e159e1c0e77e7dce78b63bdecab044fb31385fe6341308588c97df535338c33c73403457a09aaab41e9719e9d537ea7741f4ebce6253583db263aa51dd284bec13e2cb128eec029a51fecadb9cf0fec32249f6bbdabf8b5ea0ea4f840086613ef1e57fe181b0fc2ebf998860966300f80efc1db1c2be0f9c8faf7c61090a87a99cd644742c90f0a33304105ce2377fede0be73e0d3fa93c0a8359d954d0751503e73b6c8a7b2c2d08991aa6a0c62af171b578a206885845795eb4b440e7c9e678e26553052a9c1ca9d63b0603cbc288d3abc81ea2bb173161b76f4c64054bb6b924b57f19c5c00380c43bed0bfed2c99458568426bd2546f7f1643cf8b805cca263e7373afcf15cf1bcd12c60cd8419bfe19f3a72c5e1373595c3e7b288943015a7a3637edcd5af68a3ed0bc9f9151b811fa04d0724590983574195e5fc798e3945bdb1b024aaf1f09ca832cddce819ded4eebd7449aa799d086bfbbc80b7c6e3503b47f82a2288f58f4a14b84a712ed9b7a0845c5b6e8dedf2d483d1765ea2eec67a51ec2b75bbac37ad12c38a684614b31232f2a38930c04e476add5103f300a4910697267dc88108166aedfba00b36ea0599a9b2b9c4a0a1993fd9352cbe5e2b68e0777bb87fbbaa83138fea656cf50c446d852542e2f8a66bfde26eea6c046a36eeaa9b1016885209185c50b27f288cc888023cc9865f3fee7e5e7deecb1ca406fb47b2da7a9e72a03e4b5efe5a5e66846b09b731a2ad97b501b82c1d20b5702f6b457a39d969e726ed2b5a251d87c94e9236a0eeb727b144c40a159688a840c0b2ee5047186a86e3054546c9166358d790690313b5632af1b20acb1454dcf26b533aca606b093f53bad247c4179c1453e1923e9043318692f9497cb134666a58d68e45eee81077e558fb192a2de2f16a0a4e221cb8e21d80a02108c20db9eac59430b2148d27478dd964059bcf4ae4fa874179927528417097ba6619e451d6ffe7cead3f0cbb374a03a136ffda6703c4a89124221901891f0b865c51a42a4911b18e9fb8ac3e0adcc50564a14a5b2484b7c5f548e80afa37cc4a4a9c8374beabf7029565fb29f3687b6395f15049d37e670a6f29637532622eb7480f4b033f0d55530b557232e02a2d3fe8090d13ee071aae10db83550d6bfd12277a1a4154f4aa2d530570a8fa8ca478ec49e894c556b2dcc7133b027075c3908b0030a1d35cef5087b4800db1139d7e4998c7c5e68b25b0ba11b98a58de21119eb17ac45c0b344ffa0199c77249db901b0b3c540c65430e865d46dcc6496094be8f352e9f57a4208d68441845362eeeb5ded118cc8248b561a833b98ce5cceda0b4b3aa54d0560f6e852576ba1f94da928df9f92180058e79343d8645cd83162c531adab6094772c6ff5f19447124fc735c07e34edff7ce6b841b33b3321ca369b4a060ebce4e79dce418867d3fb3ba6a0f03d638ee5bce10e405cd1cd125f0eb6b100f1d4ceabcd918833ad592db5888a3c972d9232180ec3871588f9e34bedfb653cb8cf88913c99095ad71c7f475b550a7fd29e909f15aad2725aaa90a797794c3aa2e745b94591a3283d38420cbeced2481e8efa7540ba44b5b230df264093461bfed76141a5b28fcae0f4fec19dd1fc511ed91e5d3e4b3e45fd8b7cab9995675b8ad735108246e50272d1d82753f7a791c88b563e40a7207a001ffd5fcf2804271d8fac8e2e7d06747b4b097d550ccca32b742b463887f939ceda3113e5148b753c6caab60cffc668ff414ea86f1fd83ae0141644c29c329c8be92c9e4f8519cbebf95701f159623aedcf7993d33f945f97b3d9aee6391758014ce55fd1c378da390ea3f1554e355a1f72f82b07b8a24503b778aa2d37d06426109d4afbd31306e9d64e4d3ba370f841dad0485507781dd4e587abe3f9d609c71b83cdc70d33f1f603ea302dd6785e71fa8f28969547ad03f7bdf2a4486ec1659c50b634dc5a157ff7015545b89e126193cbd9716aec8264ef2261bb294d3c6c943a2dc478b901aafa386eb3f282d36d3f47bc971cb27a255cfe22998fef48138ba972d91a5b1fd0418bb2cbc241d15d37281a06e9282b5d0456728798545b0625aeb4e454268a5a9fcb93ef632c5fecd59ef9bae054bded9b872445bb949bba472829a803ca7315060a089468031d853dcc7ce6d7a02ac3d0161d91bd9dc98395319dd1279bdb430a40df459fa1ba45d043ac9720ee905eb08a3fe4645a9e9e771b28a988e8e0f2822dfaabb0fd4d5b11c96fb83d227d8b5cb0a19954ef3a9f928693ec202a0d53660b4d61a5dba7d156f9bba3ebb5db47c30a0c66878c84ea819360543a029d64dffb29cd33e690b740131a4fa5ec181d62aea6392f9e2171c6f924e02f69c04d101d1e62f6f31e80ac23ea42db2bc2b7b654bf6a340a0da53f8b06ed207574b9b0e63ce4bb28b5c482a22bdb42a59a325608f7466ecb784da513c756621599dcca0a5bf9866e2cc4dac8e660fd4790fa1488374c2326a7725f1fc82044f92b60872a4e03687099939926e3d25935ce793906e4e1a319240cdd4c7ac6e619e357e015e127436d1bb7c0122dfd86b0727d8a8288bc295b152b564c1249f921a8c9bde8eab66d926ee5c78426107184de83230d925dd3c81a1a80d1e6852dd5111b904cf2c6266fe48aa30798cd7cca6c5a9da03655b376aaa2b46fa463feb6b254af652709f4c64c7aedf58a57cd5e8637e93c68012dcc03b464e7f6d94ad9d75d109dd4f2133e82f14f97e0a7bdaa4ec0213800f3188d74c888097914c5f60b9704b53f4fa18b1a32fec671b5f8403266f4dbe8aea32935505fa6780ec26c36ddb40f873a197ecb155713ef1a34f3214af42563ea78d16f067044a5ddbd6dc515ab431b35164a81f4fc7ee7dded80d02f1f586f48618efe6f7a0a78abfa5ebdc6e08bd62e1de73146f872968fa2c01c39857bcc2c5c814402f11eba5d97f418cada282b20e7c0566d9311b184ba1b53f704f73cce9855b0286fe13b81f70ed227c28298962d429bc99c86e2f68663fe02496541d925234c21a85a0d6a5c26ea4d75694855e8bc8b4fb15355fe397f9221407bc00703db3da7a1cdf2025f02b325ecbe2c942cd0c0ff553efb3712368f1fa8cd9fe19ae54cc1bde6538eeac6f2b13a2f7b596ca39126e2819f0d2c34ad6f7faa3021f018f2e4b01f33796017faaa8b0dd76d906875e3f89ed3b404bf661a8e489659bd9bfcac6b928cc23c0ea3244389503900606f3d1cb402c0f98744a301d66dfc52ce841d39cb73c637c0e653e0524a865ec6543d873e825ef0043fc0b4015474b8f6c84407a57038213e116d98089919265098c1a2f46f3d25e09ee6368a7df8f98032c44e6409f00df759d9cab2709345b25ab88e50954414efa6f84b2c03cd615a90da7ba97a40a5caf30d2082dd63e1c931a56aeb311ea1546b12b1eb7a2f1f492e6c0eb740f32ea052d73faa1e182a7c1c837809452f0736c4e8636ee63d457cb1550473470ecb772e38055679c5bf71967baea8c4138648a3db3d3204b5bb4b6168c754fd006750cef067a6a6a190571be185854be0eabc32c608061981d5434f9a86d273f1c8c5a89c02397ce420baf5f0de951f7ddb1bd76c039bb54b6c03ac26ec3d470333ff510a1b5529bf89881dd1d28a92a8b84b427250e829c0886e432e548e8bb042f9dd30fe18c1e3c2f33ee23c661489f819f0009f87191463adcb6c5a61af5fa65244c93e834988b2cb657a1ba3049ac84dccab4d5bfccfe933e1056981170e2528b283c50c59c8b7d7e638792d95ecd56b72c1c76dbf371faa43362be6663cb1afbd6c77a8f451ec42cd102d2b8ff39ebc310fe27c4d444b71dc63b06d7c37f4b414e7b629861ce3bfe2acafc602317ad4d39c04cf0bc543f77446f2fa1b42b243af8ad60719cc947caa3381b20a44aabf0e62dcfe4b470b0e480d4b7b9625e0a4e4d0183996fafb1ac0bb60ae200ad93e8b796188cc4bb8a71c86bb0b819d2466a161e6523d0cf37aaa6494cec5a74bf356a042cf8a29e16a890f2e55c7544530dbb103f2f85a60ca4faad1221ba24ab0e833231731c328e8606048c514fe25902c2a988cd12c009897174c6cf6a6f102b05c1321997c2279a89e4b520974891a1ec8dde5e6bfca53dd04e7efc50e7fdcd28a5d157f747f35a0a198907a1a10ef5fe934f9784b8f222d14626545e268608a30f2c6d035a32cb9e55305e11271df95c32d367a4bd64a6cfacb31a243768c3eac29233ae512c5e0925712fc662b6b331c3827c5371121a865f134cffefcb056cdd57190efbc1e3b639fc66a88ad6e82b5adbde8d10b209d984ecbde5de01ca09fa09ea091d0b5e40294629c7711cc7719ccdf548b712c90e5b6fad688f71724a74ae159b589aa5ca308ec9e1802a7b297f4251b9f7de7befad946e566bbb057bc9af84dcc715a40815bd564268fdb4bfbc97ebf55672db39fcc97c1d4a1486c4965de6ec1afe3a67af9ef6cb0b52848ade7a3c8a80aa8b6b4094c20bc5341a8e0d80aa160ae4eaa602740cc34cc740a552a9542a095151954c2693e92693101595899567b003e3256fa552ba89e5e41fbc32fde4e4a6cf4ff0ea736bba781555272737990e03af4cf72778757aa3e062fd82db0a527228513308e955a26610935f899a415e9c2451f3147fd8bb4fcb5d3be4680f1cefa16196ab484e310ea87209dd45f45136795055f2a00aeb88dcc79e6c422a7901210ae3bc1e393e24d8e5621c50e532c2f742aefadc45f4d0260a81ee07c3b0cbf6d6050b610aab19a55a9682161584a849a917f39c2db2631d52908214a4c0c5c5c5c57241b607e17e8374d7bc2042aed20e218a76dc66b56bd23981d096ab9b8b9861998dae75dbb66ddbb66dde6a191d824629466fd4ccfb09e5935a59354dd3344dd3344dd3344dd37280848c9c8448c42c054fdc385821c7c4075facd273e33ca882a78a7255246a526ccad19d3b8e0e9338dc926df48d1c9f776f8e890f264914a516c686f349401a38a73c398ee3388ee3baaeebbaaeeb3e9f14e8de0b72422412894422912804bad7a7e336cb83b59581101515cd11314fa8b2d65a6badb5a46ddbb66ddbb6ed1cc771dc5b32e426368142211c21504b86901431ecc2fe99d3340f55d1468e097beed7832a6badb5d65a8ee3388ee338d2b66ddbb66ddbc65588d20e391ca0df436ee21ca1aeeb4020d0e7a10e04aacfae5d40f2949000d83b6f4204604360af1e8434b8cd5e73ce6ac44658a38f6569ef4366acf63bfca33b5471075d236ddff02733767f252a5a2c3376f975c64058c8c5418a5075ff641e8f22724b21778769fa1cc68e402925294bad3b4bc28611464421902804028140201008046a971f16e4928216d576911764d5a2b2bf077941ba831ef2828c1ebac80bb25d1424aa5e68781491b37f7e6ce73ef27e907cf4cefb41b362dfdd36c7b29de33c158f86621e2c2498867e8451f08a4b874f12356f1b0537c33db05612f3f38808ae4cb10f9989d8432e870c95ed3e771172d586efbdf7de7b4118040281402010288443a15028140a8544582412894422912804ba1ba514ead816ac2d1a9af5f15056342c9fcf57973b08af46f7200eaf56a35f0cc297a82924aa56f74046ffdcdfe70f4a9e2f51156566665c6a246a5e4811aa179f2f51f502471b899a4f814e7f61ea9e9e04539f6f5bb6bd6e20efd7fb781df222cc8ac406c90a095ebd7888e421dc44e82ff06a05258a04af4438b2f013abcf5740487ebf0212fae840440785600b478704f2880e5987aa4fd4b98244d58bd3aae984bca812755fcd238f0b85b4db7befbdf7de1778a6c6868484848484848464240a6dcf36d0fdbca3e7e82dbd96611b2cad256bd00fa691be69cd7715a6913c43dca685b84d93524a29a59cac3c6fa29f71a89a973732f5f9bcc491395247ee481e99b29f973d3265f2f9c992a9aef55e12e93f9d50505879f660d1ae9d65bb8657a46f55d3302c219db46ddfcee115c7e17bef66378fa607cbb69de5c537bceafe02afb60dffc5b7cd832adb7934788502fa8742ba3d8be9a41b1209db286999985cbb0af4d2ad4977161313bc3231c12b10a73b319540b6ebbab3e07778053ac6ab0e3701753ad037a8ba27e4a4fa3d4f888a10924a46c5ba907db0208f860504c22b10083f41ba27c30b827511c383e19d7826efe5a4ea5848f6a4171c59252c6b0ff2a00a643d9a1e226b63acc511e6c270b7d120cf45c64137792e301ee325cfc5f4939b782e262ff560212139cb4f8257243f9ef97194214da87221f1a04a8627e4a4927190274445084915e3303c215505e3272737995e2addc4b3241e0d0b0909b62121c1b1e6874315e95facb1b7d124195e0c2f08d6050cefc4337925cf8a6e4217e1d82a395489441e5469241e5495989042de6a8457a38770c4b95ce9a697782ea49b9cc4732179c965782ef7f8313c97df3b0ccf25c665fcc47339398cdb91b71afd83579f8f70d491a8f917872ad1edc5e180aaed33bcc863a278c5aa7e802a11fe228fea7ad8f3bc7b32bc181e0cefc4337925ef8567e291bc128fc493dd9229a8aab7d56a56c7b44cb3ae6b9a5aae8eb1020b677c5467d67a2f89f4cf989819536f2e0e29e73aa79d8fcaf450991295c1302c53af96bc2045a82077230706e7e586b25a3d363c353b333a122523532f41fc26d77cb91b190745ae9f7f33abf98e3eba89898ced3f390b7ee9b08457341843791958a96ea0931c047ac941a06f077dbba5d2ccc14aa5cb38cb5f2a954abf8c125e95eacc29615989bbe8f34fe274df3ed887ccd9e14dbeb81ba1d31899d281d1e179893c2cca62c1f4c0c8f0c8d4ec744da9d4ada9d33859be84bbd53831fe459dc8d3ac8601e25fcb9cfe750dea5fb74c0e5502f8d738a59249a9f408b48e2759265ef3fc6b1e182fdd44b26a96c1786924714cb21cf1077a86e3ef3b4f84452077b4125abe178027519e3c7912082f009eac91363286276f242ac3f03c095363e48ca9b169dde0c028fd97973b3225e3f29247f6c8146bbec81410979f303275ba3c08086f05c48504518338007e6ff50b09e2332ec35bc9b890201ee3266f65ba90208e83b877136f657221413c002fa5a30e84f7527a007eefa574005c86f752fa8c9bbc97d263fcc433f15e4af77ebd1dd7557a50784e3bd739a1a84c71f25e4a9f22ebe4cc2ca616d9c613971107420821bc8ae7fdbb304e60fc436935f17f1047c63fa823e3f82718c756acc1ff22c62812e5c1f0eec9f04cde4fcd215173c4270faa505e003c2851157f57a600f06678313cec795ec4f8a33211efd00e5b99cac8148ccf5aef2591fed3a931963b93a3fe313d00af327e3af703a074fc19b72fe11f3f1caabc03f12d089a29feb0dc3c8ac8da83f08214a1fae150a65058c80f8ff14f877b5cb94f58c80f379dc34060213ffc0f0016f2c34d5eb1901f2ee3427e38fecc998185fc70ef167f116b98c80f9804a5d37a7f2a61301963afd6df2b834432fd26a7534b989630599ecec854bda49f50607850a2e014a444912a93c47ab74e1245aa4c5616b5bc6800d0a0adf0840c5b55b8c92a19b6aa0093214948347accb29a91843c9148241289442251734bd8911759123543f3cddd58b171897db85fb35a76f41c9db8c3137b6abd9744fa4f2714944f65de8a3ced24a26b2212928bf06a3bc96dc8139d2574115e690f69a287f00a74d137cf857b7712cf2574925bcd5bd1d0d3ac8cf02aaa46a7a1871c8b768b571a66d13ec22b0d83bcce139178210fc2d6c8832a910755210faa6cc0d6075b1f6c8542a15028140a894422914824128d46a3d168341acd393f1285b2d70c7f3f40d8ef077b873defd38c5b450f0fe5e61cb170c1055ba8a20c747881cc00ee008322352dd84e292de2047bd1ebbaae22575881462f4a292da28597eca2d7755d45c050e9454f9ff1f98136f3a2f50c5cb0c315f65043062d5493469e734e2a5932c0aa0c5e70f9a005940606330a51487a459116fcf41997a97b8517a4b8f45e810617d0f92ccbb06585186a87c870457987193656f4e1453583d25b44c80c1b9b61cb0a2da420abad9b1d2ab349b1a8c941153b5ec0c31021e0b082495957639b916c79010a5e3003213bd8814e120490061654710622501f54e802086db071811a6c1084185660c50c36440c6c70420c861085143340b5acd0420baa705b56b4b2966115606843c5838d3017f609be075864887d748690c6a90aac2b7872fca64283ad6b641127cc2cc356912be4e869e12a02861c6fb1223c45d090e36b15b1b28f0c341f80326c5d41b35d11851c6f399b61eb8a22dd155ee8326c5d81864fc76d56cb2a76d1293bc2db4148036219858d3045a4c8f1b0b304b8a63e1045647a7864ccb065440539be768a0c65d83262831c618c0821c7ce107f4f640869c4225878c3d3bad999f1e5cab065052b764cc71c5cd8b2a22667d8b26206ca8e7076b0a550c3487dcd6a85b8ba68b7df62bc70b8313ee3707038b8db671c8ea8da6e6dc69d48779b6d95ab5c04b8db57ae7211c8fe39ecf08fec1fcea3a17865c31685545b5af275d563de55312019e60bc84502414b6ec91213c92240298703aaaab6c14e69928d8f327ad82fefbb4c4bd0ebf49d8261b75f3dad18e67d149f44229269b7d124998a2a0dffc81efae4706cd73e391c76722cdb351a8979b0749846fe738957ec396fd5a2b2f65de8b3c14e89f6933853ef8b78e23a0413c9609699e470d867971c0eed9f1f343c58ec33fc23bbc52b1a96eedc6978b068ffe01fddb9ab6858b26fb721ed73ab8562e75d8ff3a2eaa4fe49cfc89d416bf14f526a1a86f54a140ea842c1fa73c45e1991e8727779c23e49ee86c443e29cb2e3118f64931253beb3c4df1379c6c8286527719c01a401e30c32e4c18e517a49afafc8dd908f6fcfb444bfbee21db952fb65c77e4d88e18ae1903b0f338d7db010d698359a08ca012211cd8aaf32a5d9c7934491a9edf12bdd2de77d3e78d59deb6abddd3ceeddb671f65e0e8457dbb30bb76ddbb66ddb38cc711cc7711cd7e1aeebbaaeebba0fbea49f3e1db751ab65559b3181ce657d64ba16b7d2d95856466b653f742a0b93b95a1488ce64c9169925fa0ddab388bf1312dde82584117f13fbf5af3385f044f1678346bcfdc4a86535e2af898ce10ff6e99a5e8ded06d695f9b4ba950ec7da646c4bfba193b1aa0cd6ba80e850d6eca245467661630fdd68b39f12d6d04ee210139b10957dfe241201e110592633997dc3f8ebfc9d484823c35f13f9ab17b5b1f340ba1ee6615e96ff02853982b21c1f7fe3c27e870e6939be65fc68197a9036c77849448c958c31471386092609861ee8090957839e94809e5c315e749789041711264c4649fd602528b09274a93719413579435602aa919144909590e4a0914244682521d06289252189ec0b1ff6c536da4840b091d0812b3921a1399e1bf5e0465b74315e5c39be13f1e8aee872f89c5482e5f84fe8894fe872b8a40bfac005e180305803743d00baa12b1211fa742074c514547db0105d0a51f31f49d47140343b2c462777c4ed18716220c13892ed23c1362c5ec4e85ed80dbca8560c259f124d3a51523531904899064832055519154c2c3ccd7f2799645233609202ab4e69e61839e68f54c230508a44c0fc6d581b4c337fb5c40453ea552f60aa571b4e5260fe48273065eb13b5c049a750185d9eff64e478121890882d0e31b70ac0d8221130cfb986182f624022ba3884ec2810a38b44480cbb0c5b2203d6f8401af34da9fc3e4b3c638fdc124d7c3232ad7dbaf0174d4a5c58fe1ab130ff0a3759fef90a361f5295734af9297b5ee21df254dea4c4bcfc8469e9d82db0f7ca2af6acc61589ea9e51d048239f21c4a45b77cfad6a966e576be261ce39bb53e835218d8f3eb2fa04fb843d6acf1e392bb1ab665ae6d5ebbaaeebba2e4abb650d4e5f226ecc31cf13e10e15b09db31a97358e1c0912e09391eb9d8d95c1c2149cec572b5f393ba6f31965fb458c734036239ec12d91fd9afd197dcaa610998ddc11d7b12fb317ce5a768b67f449882157fbf56f860334bce33af61dd7e327c4123f08b88a95e863f8a3ef5fdecd72073c3a5658b2f85150c680c283fbfc3c4f643b75c9ae591ae3761c4fb05ab2d5704055f6151d73c3b5d65a6badd65a6badb59aa6699aa669f4f3e46494e9bfd136eb2be5995d8160a1012eac220d3af9abb08a3318c93db3c81ca80167c8db3ab8df8558a8c9d93315940328602b02421403c0142402db48249a79946638893e450c053b8934b9fa99bf98357b8a39fcd16fd7f0c71dc11d416fbf7fdab9c8f1d6332d91dddee21d1a26127a86bb28c1f01d729f61fe6e54cdd95c04faa2f409564ba6145ea54241c9a49f40201008040281eea7a338da136c8d391560edbd63882da719561e00c70061fa144fdf755dd7755df7f97c3e9fcfe7736dfdbcf45e0cc2212cc2282a362a167d3a6eb35a567966733b80e1c125d2bd3e3b911016e6bdb6eaed98ef67945362beb14989eb4444bfb825ae4f4c64fbe4227059933be893935c042e4b4a693191e82df9a01136f5b98f4cda3fa6797bd02f8e070bf7115e91244ada83f08a66dee28979ac7cb086bb6f18de5871895c0edb75dc66eb06618d5186d82b8661a1cf2fe836da82bcea85e60c85704b06e17a25aa7140d507935eaf44cdf9d9571b2c9c01618d2bb75ec0cb55d9022e6ca2c76e1790dd245fbf3d9e2453a6fe758d07cb750daf68fad71bf360a9dff08a46be5e621e2b966216ed195e0591a1faa1bdc6959af60c430c7b866b7d761cf519be12152536e5b89e1dc7f5ecc64a767b79f6d9757b65d92fbcda9ec9d3b0d45f78655f25cbf58a5795e4912c86575165b36b7895612851f7b25cc7f0aa56899add730a141458236608e191272008606a0f79ce9cdf36b8113fd1755dd7755df7f97c3e9fcfe773efbdf7deab7d5ec5461232957d7e2271330aa431df35b8102747d0e7e853746c867e6958d3344dd334cd626badb5d6da0d8346b78a4218040281402010887ea4fce37e3aeec2ac96c5ad8576e704fbb9f59a4960d808f86e9e5ea8f5deacd60bc7551fbca19c8438409eb54ff6db23d7800c1379f1db277bc845e0b2ee4b0eb90c9b5870bc805c8671409589fbe82425d8d41df41253f6d0ef6de45842bfd75bd16498070be8257845d31df40ef3d0ce6116d15fe0d5c786fc582f46d12b245814f26aad15a2b2ece36557cb3646060b67d8279ce040a7c4865cc8183b12e8d6a8877b3b90fd78aba8fa80f02aaa7434215149b05c40ff5c050aec72ff3908a3fca059f9fce29344ad5a541f7c3ddcf8f2c464cdf9824ba4fb07779cd8c9f5177763c5feba381c50d539eb344dd3344dd3e04ec5369cd8d9d9d971e209285820100804028140f7d3719bd522ccd50171e65475723ce96b2d727c3fcbbe11e92453d9f424d6d6b0ccbc6ee1a2dc81ad872d44eeeeeeeeeeeeeeeeee8eaaea6122586cac9ffbad025b87a8880251d10644c549b1c36dc2533cb5507ef3c43c9ed8328f55ee231a13a9b1d21d8c72ccf633a34f2914295f42e9930a8a03e67748954e91b86b9552e28f7a2a2807e8533791e7510ea0d21345a5534e7deaf749d6e0a274ca013a4545019dd22b785e976ecd8f328a6c1e29aac8147ff7cea3ccf7a4525838c314edafe7d08ee11fd8b55ff8070d0b864d2bd74d38a0eaba2987e442855d72a1c2b029befeb8b029621313d8e7735caf9ff8c77f64c70e4d2b2a150ce704a3d5bceb552ff32e2f5ba9f15ea04f7d896a04c828ae134df4a9df82cbd32da990e2b6578a2db8900a3f88c93ab81778f5364fbe66a0aa2393bf932c2fa191acc20005748a01b2acc20c4fc8f20650690fbbedad3d9b7942506fbbaedf3e4d10ec539d5db1cc1bcd2d7257e49688bfb67ec4f7a4531a93fa242f829e2cd6ec94d89758250e212fb9aa733bab7c0600608deb9273c064e186a72bcb4f4e89993f2059e6eb566e9727828eb2e1ec78c87ce14882914463b46997bfb26e97a46193eb42132fe42a9a3e0ef64f882caf795df4a2b39260ea3962225863320ed6c27bf29319197ed4deb7e5ee8e110916cef830568e5f96bb0a29689161155118927532ac420a2eb9c21acde168d5751ee42fcb5fa5224b14a461bfd28e3de3ae23fbf61b446e08d4e11ff69f4355a8d3de1daa4056bbe836202f146f40219292df20f2c2fea3bdfbbcfb745b8ef6b99c4ecf0e8f955e8ffea7d37e80aee930e5b0175d847f846e0f55dd918022908ed0456fa2f3784cf3a3b7a86c7b3de473acba5fafcfb1fa1c7bf61e3c74d46fd791fdfe0611ee36723a40d71e391da1db15ed169be84b58210f4a9007a5f60293e0979107254ae499265e81b2bb7a507a3d788020661e3c78e830e5f8d1bd1eaaec759872649f6787aad09180996add41879c8ecfb51a02792679fb16d5f4be9ee174743a3e5bd767ef1c970e0c378c44c567d8d4bf271b6da35762727ce7e5981aaf7078c3d6d33c93c42b2ab2453593bf99f32253f582b962a2aae2fcc8667254f092c9f17aa1351fb5c991b6724fc6b9581aad91a8992353dae38ed5bca8ba3c2a2351da2f8c79f117760cffa8bf54dae4e9535c9939d9855dd8abb7a2c911e3a084222c150aea57404ade7006968ac51aa92a4681cce20d3360a9ae6be6aab964284ececacdc52353d8e3af1e9932e5c02a8ebf3c538eabe278ccbb78242afef226cfec91290174010f65a861c9548b146e7064aa060e8accb47264aa45154f75642aaa6277052e148161a9e2298f4cc1568c2ff98b325186bec894cacece57e7ccf9a84c8e9fcacc898f383bcdea17279ce0042d557cc7c49958b322532936e08247155fa58a4cc5af6b600e6ca9e4af62a116daa3175838e37d929f101134ea93093baca20a51e47813868fe88c1d5681079c946cc927c1d20407b0805c74ca65b29ad045feb6bcd554e18421f983395936618bfc412dae7ccb639e1154d8f409e6cb33828a29fa0473f48ca0a2a64f30a3c4972c0b40802c9fd027986d749c33fa247f99bab74ff22aa811a665e10c0b89b832fc69eb8d955b54f02758235e699bcb7125ea7acd5125ea823959ca4ebadcef9475b24989eb1736c13cfb2483dce7af56993a55599b750224640c7f37c37bfd2453525e17a803a910052e32c55088efe6f8c691b161ea6aa4d04b27fc0591e5bf0264584496ff1290e1e9c0458655d0410bf9016458051d9290a104d5f795905947a77496c722a4d110d50928a2002a41a0e053e921a94d014e21c2ee2e1d9707218dc6a6ebb095039e0c5b39e822cbb3748aa9df23e67e5f9e019dd29848bdfc4aa7c47f108b2c9f44a7c84f8f01de8a8e4e8998c8cb551597a0cec48285deedced15ff2b9fe3bb9ff4629d0bf6d660a3b85235d5c533acc79db39ea75a79c7775785edc85619f36888a979694e511f5583ff3be9b7dd0dc8f945ed84737edd92d5ccb162bf7618e39c25463d1a8ce22f7bf2c458bdcff4019f64d7cad7d5d2a4d5b0151fdac82f2d737f70cb9db907b0eb93b0fb9e50972dfc813dc0fe2dc64d1a73927959fbf4ff8e853af222bbaf4e9050a68c5fd20cfd49136d2c6a444c6c898524fc9a4c4c4c4c4c4c4c4c4a4a4a4a4a4a4a4a4c46432994c2693a9542a954aa552a9c4832a5309774e6f928b3037372746216da44dab857313a3906a905ac8181923235333d33ddd2359112646d1392dcd457b7189a24fddd3a7ee223694310a17160c60a480936186316ff07eb81bfdf99ea24fdd4372cf19239ef3c262912c0fb37cbc11a5913e7563d1399d85d73a8dd3a726f2bc948f36e4940d843eb54c9f7a7a9ad530fd72841a48232747478767c7c6a6d5c2b98931314626ca949494949494945c88cadc993c32d59f3d2626262626262626240faa4a26188ad663b69a96550c089d9a4fe8628adcef18999a35a17fb1a627c27c3126cad4c854b3e24d4301f2449e8b46d68d4c35ab860cb086fc0bfcc5971712fc451818fcc5987ee99796a2a54842087f91a709d8d37321bce8b5436772702efcc5d6cd8c4d175c70817137aeeee2d1f176726c41544d02d690393837333536dc66e241c145d64eef401a2d25e9dfd4c9fdd6027f8d45ee4f1d9922914824128974212a2a526d23bdd3585cf4099922bddf2e9d9a431ad5fffa268adc1346a2faa07f1126e6409e0ff64456d48933ff5a07b91f6d200fe4e9c7181ec8d3876266c2740af6fe8402ac71bdbf08f38fb40379f0077b7ae60c40f88b387346a6a2ce4bef5cfc4538c0e183bfb81377600efe200ebeb1f83be10f05057f2a7db3d34d2261dc3736f9eb9baf6f6466e24b8461c548d6857dc2020b8c7237e827b62e1ced200351a3cda46432e2564c48a49b78a49212d2953fc853f23a47a2fa264fcadb126ea5a493fb25252f792525cfe4905b31c13cb95fd23b1fe40180aa047691fb4ff88830ab4e517df165cadc37324543df6f1c9922e197a85a494055f2beb491a926648c4cd9c8e914f99ef8c2b3d3f3f50dce4c8c9159e47ef7c8d4a1945a742a6271235f6e48a7dec91dfbe68b596c913b9e610e72fe720c68c9f149c01a268a73cc5095dcc4d2aa15065425c73c6206414b265282a1449d640a421b951a9499d34b85c9b146283b93129de73b4f0c244bdc348034e24b95b248ba044b98539e073d8f09f08847b49588bf98398a8f90972705254a5f0b0f8e8066c81083a02553883f7a48b1117d6ac936786e1f0e2e391efe07102e0938f1470f1d40f1b7321d013fbf037e661bdd109ee0a512137e610b2e722545941cabd8428b1c4db75fe11422c31fe053190d3155d7250d91bf9b650e50d0859b30e8c8210a65b8c3142a528edc8deee2ca0c3b45768655c0c111c9830e05d58812720aa6965129a594329b744a29a594f39257ca8652d2eb92524a29af29a594f28735e29c524a29a59cd20a38a8a088142f2d2bd28042b3ab080d5e3a89035b86c76a37e96e996637ee0617b1ee6bc973f6e9927e70495a47d97d2db0c62c4778cc48902119b6ccc093afc8b0650620e4db29f3a4d9839e2cef03982cb18fce2120e50f0a168b957d904444707088fe07da32a4335329e567cfbc437e4a49e36c297b462a31e9eabe961c553a4f30420521c4cc0c114216194e81480d29c3291089c94280c9f276ce8980231c00056588534b0525524a095073bf9aa594754e3ae7441142885ba9006a4bca566c23d0308210a71310b20836a822d89c66ccf8a1657aa6c666d2e400802667c62fc3460ece0df5a6e897fc931353e4e99e6bce0983083a272452491250a76243301902693412d54a29251142169df2cd9e9624cd49e79c75742fa5b0e5ba2efa993d36dbe4cc6db153983192e114669e906f8653989922dbde8ca06248b6d31b72638c797a11c41941c51022b7d67b49a44b5987cc74ca173d1984db38de94963ca44f3067bb3d1b4105103a057b48a7bad52879988da022265b7881d0279829a5341a41854c9f6036828a993ec11b465031834e69c9305b0e42901154c0f409e6af5b465011a3006e09ecc891237dc8111b41c50c7a3a85d52955d3f29527fe5614060231ad1fdc780be7ec26491fdc2b7f973d90912d65624023d8ad21dcdbf89bb941b04fb04f12d75ba910852ae49b230f5a61b0c95fa50211d68e4cd1ccc3e6218f74919b9579c8234768348d083ac72bc221e62a9f05958d20b712d7363d9619210228cdd404935302dba6a7e38586874ade71ca2daaac9e478c2ed985d0f050c93e240164c4b8235aa0ea6aaf526e0951430823ed302c82b610d2a0cfb353249e10c25aaf7c1f87c4a49608a4db04dd679631a7e1634fec22c3c71b2822179d72559d9da842d181a76645969db372d15de860cd438a33a795a892f25f4b51234fd4c93b76db46db373ac1dff6eb1df7eeb6f33ecfa454624a4cbbccf5b55f8d7dd088c5cc980763abbe2fa5acb2f6cc9426c70ca893a3ca4fd58684d783107252f44b866f56e314f92d52249d1c035ab0ccddf5870fb647ec114fefa36ae149da790b9edc94fe1be5b9459f7a72a1a345966d7003a4216370238f8d44c55f3d2dd60df6225172c8bd78a08a75bde43e77f1c01af0fd6b0eb0061d628aea21a2fa9a16c2340f90465f3112d5b407d2682c4b2650cd459f1a7a3d0748a32fbda603a4c1235f70bfeee1b1bd35c7448e1113f1f6921c12b1b91b9385fb46a24418629308e7648a738c2e3a8e9108b7e41e58e3f3fedc42fe9b5c90bc2f5932357a7f540cadfcd19cdcad436d28bd09fda33531b9a90c9dc97d0a2353275970014bd59f7980a98be7a327f8e80a727fb6640a5ef566e2e4a63d3b3c3b3d3c353275c94854e7b4e48dca4d4fab6ed792b4ec5386b274a6cdac993320fccd988bbf09935f72bff3c523530d0388eadf20f7bbee41ee739f2fc67cd1a67bbe76c97d122fbe48547fe44591678a872a514ffe6e8fc8ab52dcefe2b978e277f1e4be9414ce219f421865aec8f43d53eb25fda7dc333d15b3e0421d99a23d984ebe68c8932c89922f218ff6748f907bda2353dd73694f6e8a7b22ce148e689127fe6e8f14bc9025ee1cdcf8ef6230b7499e60bb958345772bc748eedec10d43cd637ea9aaec3d27910c7f505c185629e50e1f9de74519724b009127264282943965cb23478890ffe69cb347ccf0c811559d73cefbe84ca41e72398a50d5ab6713e22d3ce9a7ed1463fa5f04428eb1151f6fb0883a718b9a18239db1a653bec8b2e994af5f7212e20d22f0ded3af828292444b079115a9831b673aa5711cd2a7293a25c6971893e3cb0775a24b13321523d5912d1965e386c170607b6cac4c0f677c135e7a5d68288e42ae8a3a8d807e76e8c52cfa2413634857dee07eb027d6b08c9069cc91573b3cbd2eb0956197d9ea94593186a38c54c310e6a8b7517df8afc67f17833ddf297fb027655ff127c4760c7f33f2b7fdc2df49feb61bf1f74a3ad9f037237fb065b1102d1b04723c74f44f33b94687e491a8fe8d8985fbe71fbc8a367146a2fa2daa16558e1c7085bb5725cac4b26d18b27cbeb5a83e98e5136f72dbe4965f71e9308a69c32b6862d16edfa2b2d6932f39b97bbeaec9cdcab6737a46e2ccab3157badc2db28fcef2337e7607b9effe48f4c239f431874e9c93fb72b2b0e6e670b97c241b203061c8879ed6c779cd2b5ff8b2514a3965f4be7a10b464294f9f6db6d9e2efbabce084353eca43e6ec2068c97eeb116efc57a91294663be4eb9cdbf5acc40e79ba439ec25c2327e16563214c99f312c6fcf527863d53e6942d8f1c21a23b77cc3b7ac423b9bb63ee471f9d5bc6ee22e696ffee07f1771dbb7dbe1e775c107fa41c9fe1957d8a619f307047995e9477505ca784ef6e375838c3d6db32b78fe83fe859b4d5b5a2d9eb57d859ece9f57996fbeb5a4b3b8723cf6a56ec2cdce729bd7696d06995f6991cfdfa85c97e0fc2b12551727555bcc2f06ad58365de9e05fb3c8757dc3b1c71244ab2dc770fe1d049f008afe8457815c2ab0eaf38a9bde22656342cf5f61896dd4138cadc4f4d9ec32b2b1a8b571ab671f113a71825c2f0b46048283a35f711e750c5536fc5241d0c5f9c0b578a278612d5b16b9013e4a84c54fc79573b8ecb5199a898746f7be765d6d35a549dd7a2e2bc1695f55a5456f3ec316f45332dcd9c9a3635bce2268ba66599fd86572b38de48546cc2d3c9f1195ee99028f9ca0454ade86842a2e4b1131235b3ce4e48947c9432b85f7d02d69897e7016bd09a6bd323a6b48892d7b42f94bf7ae18f9431d1aa93444d09833b9b1ab190fe6a998e30e5f87c628cbf5464eada34fafe3cab91084d052daaeab5a832af45555b541faf4565318fbbc530cbd9637885ddde56af3be7ad68e269586a8d2c1c77dbad64781555993ce4ec3bfc350e0bf70cafb273d87e3b0efb2dbb761cd9357a1cf5f43a0eacc58613594f5f14bb8e3f92fd54970fce4db76c723cfce46eacd0470e47545d87dc556904c453af8946407c7b3b604b76a5427f6aa75c68fa3aa4d8a95733e66590c695a9557df678f8c9766e97d7a75e976de56e4c8c63404b1ccd2e5f1ea51e972ddda8b7657b6dd4b3d9621bf5b46ceb46bd2cdb6ca31e96adb651efcad66ed4a3d96e1bf566b6dc463d996db751afb3fd58d00774bb0a69c4c30851b286c645a0fec7aac27b6f702bb57a2b53edd33c5441b1027265b61820152602998d807e7c9128ca030821ecaedcfb24ff7527c848c4996d73372a36e5d8de3112c571325d3793e3f37b1c9f5f5c93e35bf2cdf5d293325b78550e50310aa4d130f783ad243a65473d7da7d8f719b0d229d87ddf0689478e1ce983ea65aa56325434f427f902e2922514182603a4054427cbb7b0b26c91b18141ac8b7c61199bd5939e5d65edd2b3f89b37647f3720a4215f6f43561eabca43e68c350bd2d8e15971f960978eabd9709ed4a8d46ad92a839c654aa1991100000000b315002030180e084442c17026c9c13e14800d81b0445858990ae32085411004310819620031840000882106290283b402203073fd63ec752df6949a29766f3d229125b10a24e7b3c7f29bc679c72a0ad79d2347330d3c43d01bb03f4d687ff9d6cff317222b71609109e6ca473924fab5a4606ca1443996b541eb4e6ff4b1029cb848cb05a97374f0c7aa167a89d925477ab62770ca7db4de46f594ae45aa7ccbce0ba75b3e96d4fa8cbd3b06ed5225d10662fc57364a4dd738c715a4d0025e78d408f1ef59d32f9c059face9b008dad0d45ae5904a0404ab17d52359831c5a605fbf96f469c6aba23f336f85e0b7f32bdf0acb4b57a8876d2591051b2665b39a1eae58e71584f34fffdf1c7ff9ec9f61aea142a1b4913a6f9c51696bf934ecb00d43049e5c2e5e4f23ad9ba77afc903730418db700d8f5628db25440fe96f5714fd4fede8b39a11da361e17bee6d57f6fb40b75a70002e7014b06d7f8cff625fc42e1d5b5af51684e1a719752171b1495f74fd1dbdc7bd8b25fad28da00ef0031fe502d1769d55878201d8dc510a006e357a2aeee869799777c4f39bd88eb064953bc82fa19bbb42745a6d064e42b0dab859d713dc9682c7fae041d027f3045dc165531fd9ee202229554c5f96da07ef27b050dc3aa8196ce09c93fc355aa1ef0ce8799cba5e22bd846ce251aa6559a9c81f0a9d9b1b4797cbe82b1aad36de715ab5d61bd5579be5d2107f943d37366e5d97e8951ae51f50d46d9c8678d3522e7a543a0cff32ae8ba8e2ddcdc7d1f5f2d14384ae5ad06788caea834436830ba749b97d246e4c11137ec82d63648e94c5bfe1792e4a678c9f80867378e3d697cb4a8dbbcbe5f4c41bb3d03ec6d5e3e9980a15142b77d7f814ad9f4295b44cc3c4520a89a6fdbeec5dbbf4c1cd8c7f2f991e1a79fda3e97dd5f032a7e1a64bf403373c4e5d2f915e0bf20aab74feab749b0c585131bcfa9035ae339f74d1dfbbb2e09ec7565377df1cc6878fb0e7797bdbf696ca67e3d881ab20ee7d8dc3b81daaaf7e0c14cf4bf2e78b31320cd0c41d94a3bfdd2a9dd7458b5e29edfaa533729090bb62e970677cc26ea188cc85fe4184b031015e28cc016973a7f25d4920de8cfa75a1d0268b91017996b1249830fb874e7a8d1570496f0cff0b3d3255dd70529667b67284f837e9640eec51939befd12f40fc9090188e37e494867a79eb116d4c7d5024bcddec5ff37054cfe01bcef7a0edb4bc1fd4bd27a22389f762312dc12c76fa05de26271dd66905aabd2467214c7b2bdfa40348c1fb07eb09716da0e94445d40cdd24b9391c1028216d086e3cdf340c8b852c9ef223250be9587c9be0a99e6c6f2ba388eb06c3e16bea6c9781b8efb8f87ece40d465a1cd32e3043feb44edc797deeea8e9aa786e2c66a9174eef535f54eae83e0bfb769c5f1cae736296dc42066aa6a185fed81779fffcdfbc89735cef737ac9891112198f9c3dbb688cfc82605e132a37dbe3d806f539e5bf933a2301c2d1d6c0d93849f1290666270e97fd66bc2608109be260ddd64da7673e38fdac5261dffb2b9d6753376ea50d454872a0e1fe8ae65a2e86892adcb9e05bd357df3eaf9ab3c555f4641e2b31ceb15942f926f8e3e01c06bb44386ae1840f1679f61dee21fe87e5eeb0e425c771f18e564899a8ce51181f411b63f0a9cad24d36e7b7d23aa0a8d2150b70fb4ae5bdb4ce46f83bd8cd2008a346e4860b49ca21d5688ac83705a83f962d6c84bb7a84bc8102a768e9f7476fd19a8598699302690bb80b18b92b00e04049007037f3373314ccd93dcef0192d83d0a0afaedb53680d4031353113e949740ceae4fe26997039bce187ae03c12d3f81dce66229300d09543885aa99344c11cd26f834a979fdc937021651b42f5c1cdb56822ead30e4dc58f80ada5e34dc7b461b32d437b6ce9bd9255aa8102e96fd3f7c30e6c4c9f8c1d84353a518d3dc5c69853bfda5d2d6a160b41d6bb223a9841fd87ed07f783785881e46c7bc252c97eeef89d10bd5250fcba360ec9d16a24ba0fa9cf866b5f13ff10917f8325d9dcfefd1a4c5e4cc0e6051859de9046f6c0ed08f8258e4bd61a183242c53a4d367e9d18eb5e73b4996831d069295a92faa20357a903e0675e80374aeec0f0430bd6c17e766419d009ad8bbd0242c8411502bd14108c2bb2e24e54ccbd118be89098b80b7b0f8b609e06131a917ad7bc07d5aeb4bc7a998b607201ce1dcecbf9c3dca7eea4daf2943d0af0060a741ba5b08ba4b9449bec8685b4aaccd62576313e71467515f4d9b4be33d69408d1b9c8342cb30e5a7d9cad0015fdeaa5e850a887888684382b66593ae4dae4d350954b10e5e8d505dba4a6fa0016d88a184053c37c7e9010397c6780aaf6d9070e57dbd0f1aab911c77ada39454b16880875fd49cfde6d6d3d11055844e99e50d222b4d5afbc8a02ca89d0494051e0fb9b7003f59b6e766cd23a5d76bda02928273843d9513addab776d4d039978c10661ea20e0c1854b11f829280c31a3391df93fde3ad0dca9f4ca7f121ee75c3092607df216e15d1ee09dbd96587c5760cea0de776e4396bad39f7842e5ee4a16241daa704bb5674d858b4aab46cf99a9ad2c2d6b8c6808556d0e83cf5985890af975a40fc6040f63bfb91240c375b6d75cb85b98514b0ba4af3fe333fc6ec87448986210f5483b4fdf63d2447898740e65b7811cc1b0f80567947342f241d32139959b0aef3b38c635c143085840c39396a81f1931c5c749da68626edea9567cdaa72b90f0001a4102f74e1145e00e4fa3a86c592285578766f92bd72e2eafd9d67772f58b63b6235b330f7b815a563a5f058eab72fd6505d5f6d8bd17da1c2a1cbeeaee18486e8d410f8a1a1f91afc2bd4e19ba17d28eb70889d188fd1c7b7b8a3fe2a98ddd4ff580a9c66648af0649f080b7951ae70e5bba344f022f5eb3811214516b396e0eb2e10bb8728d588097112da875be59f93cf074fa00ebc34e082a9270781c2cf93d00656568fd58248d01458340ea66fe4adcd4f19bd471c8048ed1839cf30b41819e9f626a02d856c6a59d01a0d240e4c38c8564808ca8e2924343e22d961f435588d3a58bf9cdb54533b56a3e00be75b020d6d7eed6345333a660af5fb13924584bc417f4d0a8c6a3c6f422e989738102a025d2c056db7c731242a724935af701a0861ec56f3432dca524b86304c98f19758fea3ce5ed58b4b158255c909c9f4b8112ca6d49a6aedb64c79e66d0f7377305ffc0e304ebcbdf13f0dcc75d380482bb33dbc940bb6ba89824aa2f446438e8eb881c647304a171d4bb698fd81473df0c53028832e5531fc2d3ff52f4171a3faa9a8c994955ddd7d78be80eea42bbf09b081411f6026005ab4e7a96fd73bf411fcb798abd04548449225c624c2b500643719403e5b441cb8f64ab51723fc96950afdf9e2d1330f40536bc2200aecb67cda92cf8102ebb367c2d751b46e1f064a7bce3855e1b191da487181a1ca8498ebc0d14c89028e3a62e1d6d2913e745e5c379137194b91f259efcf8acf44997aac482a1dc007f3222e5a9352e80f347006ea660920dcd26489b7b5003c37497461e5c989438fd126e8115d270610c7ec9f35096afbb24cb98057f0e84348941ba514102267eafe72b118fee5fdb2330a1e50aa15428843e38b86e2f83aac3ddd4435670b543278b10828e27a4085025dc39f18f5a4ca680214c190df30f7289c2e0d36f34dc0644660ec27280b7c493c55a67c475f48a25f97d8e5d9a3f7759ce23f5beb1e3ed43b116d53ac4aa6f7c3ae27acb79838a1208679002842122c7a204c0c371fdac9e4fe2f15c46558c294eb39aff56c771d18bd7b6af89810a006e114a542d2dfe2f10252c9c49141ae4ff92fda551dffe0cf3f182b8d48a8371bff3a442284b97dabd70986789593814fdd6f0bcfedb362be6b355ed8aeb17ae9bac65771dcb5fb0410e393421caee84c0ef2ee26dedd106a7f2c1fd878abe3df0350061acc3fe050dbb60929e8a3a091e928a1927b89249877faa7128ebe075ee077097189c6054bd42d60211e230200681eeb5e68a9852432546415738510e65d5fa09f22d0bdb145753bf45309a0ceaa0038c13c41e60260e652af9944cd2a65c0c26e2e67303adbbe8a67095a8064b2bbd9bd175becc5aa7e802e11e3c12689af8e0ec6aaffc0700ab56f29829099a503e64a57e292475d2ab85480dc6c96d2d0c9aa5a98cd6e79ea2b9e055fc2c3c048b723094d2b7493541831045046eb4fb661160ef1f7e4e92cd8da739a84af41b8d5aa93d5f0ccde0367203dd26aa664398dccaddfd02e200440b7ab8491b4a5958edccfa94fead20e6795d545188f7bae16742623f91dcb9150a41de7806af201e06b741460734034251a4bdf563fbb7498d426e012e4089af5d7dcd15cada5ddf2922dd232114404dfecfd057bec045533e168c6fb6dfe1cfb95ec0a2dca8df55eee713f5abed6b08138154c213b668343a71b67abd6869096219635d64aa1b06042aeea7fc656f9c4e42de137c940ef9c099a499543181a25bf5cf8e8e31706a38288f036d1d385b8b376f850818804366b38acc21524fb16f3c3af27ebe485b8ef6daee3ec8cb31a13e050ead19cbf1bcac010c77aa8896561ffa20150fa50eac35f71125eb4901eb1e4c0ce7f240be7b0b3eea6cca184a0db8733f9d9f1c2e124893fde816108df776d2fe1f040d522f06d9774916f90152e31e14f50dd9a63364d3743f1e2bff0e8b662bd884348c905b02d95a6b52fbe052401dd9bdf818d2b6f281856df64c6c1bd862536757ba3d3d658391f2cce8cf9846caf28f35f607a516ebcc319b3001e73eca1936e149cdd5c253337a4d4fccbe34f437521428fbe720674af40e2aaac9680c213793d196311bf0ad30a9c157a772cde6f49219b587c315edf17c342ba7b9b5d187967e9300340d4dcd1593f033a6ed8f4993c6512b0e236ff22f559011c206c372320be0efc10c80ea70d4b5b68d8dff31de8e70359a9c1f758e6ac2e1a1f5d3cce823d008fe0ead52844cd01af7ca9efc000b8285427cd675a4ec3e8c947c2875d752819e036fd7250a67cfee88654b9facfa6ea0abd1c2c81543a82ee741a36241c0e68b601a1e24edb28b74bd41d57443420505efef457e23054d32e6e0952088c360580d80c9726b13f1797721905f18dc594d03b813043c6a2479fa2cb2e860d720d88421f855b2e4becbbc6987a5182efa31a6ce4d5441271f5629adbc7aa9248f8d684f91a51ef69b96a33bd313a9923b6eb035b23ad0e0eb093785f6b8af553519fb7e73892594e07d674eda09d8591611a82f31ee9b1bbd527b9a509544502e60494f10df547aeb30b3069c5d001e1191cb77106a2a392428ec5c651717640d01b11e48afd94cca31c0d16bbf28e67bdaef0014076940237eee3522c6407d52c675cef02a4bc33ee2e5c9bb6759a595a82a1f7ad4a02192337863098baaeaf10b69701625edf4ca9932d6822f9f10c04adbbe15b208505f90c862dc5826e4cfe48a35ea15b2d4db8ed6893bfc6a5326326b9221a72db88db524c719c1abfd828c1985354064f83198784cd5320b64007652ecbe4422b4b3232370605ec603e99dcea71a09892e3df8c6dae77eaea7c19c9332365d55243d28b0127acf1d38dab5e5812aa479a620962500796014cfb3177f2cc13204e353f1b2dc85cadc012685f2e8720a03eb5c4dda1da2a9c811f766a15a5e449e98c596430eb77e231e0307b42d7f173dafc4c10b3389417c89d4b479b4a5796e6fd49a75269f5bb6594e74e3d82687b493130b4956555f312493f992dea38d9864cb0090f0e4722fbcb1045b32012f047575173c8fcbb9a548fa8ef4cf3093e89cafec461365b2d4d211979e0cfc04b3b5362df2a0a9900636028bc68365ecc880a3d4537db1d9c8a896fc229bbe2062444cd61dd0166c3c421c3ad3608b880cbc3ba6b20be2e2f013ac38dbdd4b523c6df0b401909892406aa707e9e4ef15c5e0560b0b122eb48f03d87a45601ddd5a4654dcbe47d60853c6543d5cc5a026388628cd43567161c03a47452f8cbccdbf5a8c4c2cbb4acd0f8f1f18c99df582969ff68ca98f17faf2ecca1d318f50da849676928fd2e55271c992d56d511014c163a156efb003ac9ac1667d3591def6a2aa4e2a27f3d63bc30430b3cb3788a643bad302ec3c6dd9cfc063941ca7d6bcfa7da1401d5ad8697187a5876541bd806fe60f02e66f21da7499ccfc84395bf5d4e14063f7fb577678ef0c6febac338c2c7f2d9de6ca7b581ff5705edfa6baa3e73af99de071cfd28c72350190ba5578874e356f66d8841dafa85c0f9c2e3c103adca101874f3661b1f506473d5d4627eda8c789e977b4d317b1010d402fc792edea0c5527e7aec890555b6a26dea5a8e0e2bc6571edfbc49e86285c68a9a428a9b9e685c6f96168a9776b22801ade672a2ae52c1d6e78a589dc0da1a52cc523743f8e18aa55052e5ab14804809c7739a2a75c2dce438c42b61b4b7e460d425527b06bc38b7fc32b452419d3582a7b9d5cdfb750ec6cb6861a814fe266d3fcc02fb66fa5a727cdde21c1a8829028de6b509763a4a7407da6ba31927a5ff0da0f6359fdf203fa1e617fee3e019f3a6ba9c42c60003a3cebf009684be1ddadaa55d8003a858c7547afcc362dbd1b0a6541807ea8dc8cd16cd56ca1db2e8cbe09ea07a161a68bb0a4c89a7ad44b84933688046247a3643dfcba0524d3b191a3c1b8ff5b1cfbcf024b102da8dc8a833c610e3ac89d6fe8afaba4e55956fa36049cf124e1310f169eadda1acfee332b63e64b96f8d32aeea2f2826a06e2967851aa7c6ece56da051da303bd0b328f5dea41e5769d6016ff58fefbb1c99b98be2e66045eef928b96e5f3a467878daa38eecad23eb15808cf5adb3303f8dd2802c1d17aacfd826fd228aba9267445beee260f269687abfbcbed6488fe5979c0f22ae8a243ecb63f96370975be097849bb1db03a75f9c8dd7cb28317b4cca4f90aafe7ea5066dbcd9174fb22491e27a55bbda8bb75d0c6f0494ba1aaf2e51890ad233d6b1f1163fce7ddeb8de0bbb95a5883308565c1aae573b002f2c0bbc566e70e0cf45edb7b3c09155d6c274132cafbe33917f74c5c6b25b6f0532f66e93f17c54cbb361aba552820947249b542de3ce5b8329c49d040a4c8a988fb287ba03498711b211df6b380bd47c409f6ac638552c55192602af5c2418b7a041580651821c3464117c5e5dd01dd88315bca53e42a4376539237ada6e03bc16f382e065fb0b221139462080e2e6e597ba9a1e075e1f580f4a100eda3e8017af6d81d6c7d84e6df7dc8a79de2a523f06db832bc54c4733d85bcaded42c7b5663f741accf52ef3f6a2ac91a29fb00f481c5a3a0f43bce2d262dafe652456287817971a446292d91e08cc6c7094f69a9665cf026bedc212fdb4362e59b498cf0d994135245b57bde88327aaf928ad559acd6e7a7334b2951a4b57f7c0600792a99b07565a03977d81f196b3b14ca3a880dc8b6a44401e6a8bdb3fb02f71c460fd6beec9cd9162bc3fb42ea2e4ab291fa0faf4e5ce5197ed905fa83992577db4bf96069389371daabc0b93490e7119e5907faeaca39cd6c91caefee3bc8910086c452121731e8ada6243efcb1dc806299107657a32a066e4dfcd9a61c02c4c11c47066feeae7984b8f80fcd4b2883d02b662670d49a759c2fce9481ee55414eb690e88111e5b3ae8651e9ff54da96fd2f5c8450196e2d0224baf0a71e1c615825a5027fbe8e0d5908372a7cb5d3d47c8ad91c05ad527d3b315fef4f14454b1e7a34113cc09092dd692e651ba8f80f6f81bb2716c0fcce531d2b4a3e2da400b620dcd8183e1a3ac1e9c5702a3f393f23c27350785044bdca2421eda466add35475c2c57ba55e5e20b23c7133f59d4ce05671a6a247eec2d2162f13d51c0181eb7e7ddcfbe5d2c05f85f0d2688e6c32fe2c87083acbd144f32142178d6214044e09d440c3d60dbbe82b090c54e2bf5729f88dca90da7323256a0cd22907d69ea9984b13bd4e6cb0bedb255e19dec6ebdf875cf152ab97d4fb5d8ce2ec4fbd8d4aa69e8e595d138a65c446633e176c5cf508d0f6a83fe2ddcfd89c5d909965c79627b4c1771476b5b61433ad2792f387c36d5ba259896a089bc165882411fe5704c1f5bd2e64dc2ec70c7559ffc92e40e6b199967c2e3b8a0bc85fb1d057fbc997694c53d5c141a558ef678934ea21448c97fc91c554a7804c3494d0f3f26984468be5c9c665bed3fea42b2c461231c8c46855db4f89677b8c425882cd9831d1394b9d5a53170dfc8472b78523f9b3356528f22d14ca0ce5fdeb6d3677491242620a9e9d5ec6b7dfa4a0380531b48a5429521cf20e2cc46eb3af95ed6c9d1e4fa047c2f311cebb5593397684003b08747f97d5074903b9183638b4989d9415cf9ef853f546492aed6b120429a4d324007229242725a60e7b19b8f48f31c76188231c06d20d91c3efea422c9a85f54bda2d65fffa832d1101d17cee0ccf708ab4424b01a95ef8a3824d19f2a69187b174c4a6485b5b93d455e14214af492cdf9b63150b488a0736e39418535496af72f597860d050ae8ee8adcf33ef14bf300d5be1f1f34b525ffd3715e6835066f5c45c8e87dc448ae00dca6b3dda6088a73afd9d4e5b339d07ad63c0af49f3c6b3ce591173abb4c0e11d7af42ae09830e2b0910191a465984538c32911555e71b8cb6ca804a149e867016ebe3b1d5fbb8d6d8e557222bae94792c9fbf6f78131d271a9920a6688fb3ecbf0e23ecda83964a5995db8444d0a2420c0175be61adb8b85102afa63595f4d34f0176ca61fd4a0e6f05ccbd9755e848c75588b55cbf46b6b8f2df70616d0f325b0217f3f2ee400d19025ed2dbbcfc16f0409b1bf8876dd3a151ab171eef98e434dbbe066a6fae175e72087ff1ec5206869220632146b7ef53d3534f1ae0a28a35e0095ec2ddff0d65e5846f5a35031d23b08a12b18b041fff8c23a80f56a9d625495e607924650592886a92d1530ad709001361c4c9e660e353b90497540396813861efd7698b3df2132688b9331694498e8e11e8f47329b54ecce9cd76e043fb7d2b07662501ab33d1560023c55a52eef11ef46a0e119a43b73b27775b4986460aee99e05324f522bcae51eff35845abcb8064175ee2b079f68cd625ff24350db8ec4d68e58d393a8b1ed974470e23c66753c6dd21b97414b15f55099f9218a3f20df2fb2f14d94ea1aa7fe044d270999f424366fc061a5a65c91ae9874e3bae8d80d18b139dfb159ef44049d8d9f4e5c96da0287bc81e504abeb58fc213eb40245a72c2c625b83344c2e203089f2b96b32c24d41ad4633b0b6f473e1608fe9f08013c83f252f634fcf684b7e18704477105584413b5aa795bda25acd811a269c8f12a9cc9c9a9e82d259a712aad2f5a4bd23fb64433d74234a333b060ac20411fe0f1195714f1c4d8c49f975660494b755d21ef72c37be9b2fcd9baa6bdff12473662648d8e4e903794f2d10b13c6b320d3bde0047ee9b3fb929aef27e252bbc2d6cf010a9b0d0dbc1d1ef43c3478e08e66065bcb99a2b601886f7dc9dfd87c97fd21441176a1440dd1770e9b1cbc7480e5f899cd4caa7178ac66f88a12e5f956255caef0f353c7186429ec79d03f2e943002602a8a5891ebc969342c3c78407660ef8a6416ca4b8566580db68d214322617e7a65f2b878e871860d87b05e71c5de3314459ad056798bc80407886ad67dfbdd37039c29f740949f8342e7f60310788add7063be05ef2acc6b0960b3459c63bf0fa95155d9af2a2097d65ef3788226b7373d24706ea05d7b3a2ccf362ca1d2ae33f80b5992e051a185653756b392602d0a71b581ef6637ae1176a1d0bf92ce2125ace2617f14206ef555e3ea5fc50be1b346c5c49c0338bc3957d68f501dd05dcaaa6ec4b7b82c00c9a0d17cea86f2ce5eb5e940beaeae8a9e20a979b4cf5556598f651924df78ee838e0139d7a89de2d342ca340ca25166780dc5cbae7ff85bde96cf95f401a2b84a4c182cdc5c9b247f495775ea43eddd218a5b3a03b12e13452a7e94bf867300a8435775095eb24c6880b18c7c79803c10953c26211553a283192ee91e585cf08e06daa88a27dcba3da557b572ac7d1f5049cb2f1a45dad77991709a88add89b8062a486b089a5ffb694420bc89fc04a2336da4a5ebd8715d1fc47670e17364a975dabc8e27157b26ff873be597719b2f396221f03824772ff5d18b6ed4eaada0852d9ec85dac4c8b561b550f3d613b3cc89ebd1dcbe0ac8c0da5a5aedaefe8380e82ee2153a5a6c73fa9f59e2a5231b49deb36de70f62852f695269b5987a2ac8f61d9967e139997caf924233cdeb61f1b1dec0c241cc04212cbf061054ea45e5355553f0975502bd6e1219643f432cd24c6fee65e9087e1fa77a9589ba7fa3e48094370bc00d02a1dc4a13715f3cd606b46a8701215e0082f197e1e50c259146c7493a54a65bae9863a9279b0249cf82b91e830649fc9014c04a243c2407d08bf0b9cc0a068933836d99d57a1721fae7960f52709f1126c556f5952a0b53068fe493f435b7a32dbe82461004f75a4d62d987ebac002ac8aa6b49df4ce1b4ac93b8600dc654f913aad14e337822ef4c285a0770691a5341fb64bf34413b2a3d5729870deb6d8fd59db07b885ff6fcefa484bb64b2a108cb61f3c850fa50ad4f368ff2c97efefd5a54aabbaf7ab25b719ef539cce6d5a7b96354360108677f445582c2dd8fbda958287f591d838978498493c20c23102897c076d0a3028e02573485ed405945dd10f9508d45678ea923e1cffa75252c87f2eb343096139900e76ca7510ef7a9133918c069ba044846805d1665ee0a111c7f0820a66d3e9968add4d4285e508e3711c443a66773c49b508f134dc02e3960c03c5d8638afa35bd551939b8af631dd5a4246443107efc15b28aa04d959e04c9cf0c99a98165d52bab43b3cc3682377d0809bf97ab59a407d2faabde48c69a86e71b392265b271b538560f94dca191bbfc0f252c92c1c928a22fae548a704b81b25cc620284b5fe4d7323e3d917576f1667bf0f09208b7ad365c087df311bbb0e0314d3360359a54f6b039fecf5cb958b824502a58e17486b8bb82cc2d07917add8ebd3124b6f534472c353129747521ab3248b5621f09695201050239b476b272694461f6e82b0c11601fc32cdd0adb5425ca6a0b3511482eec4790c4c87d25f24a6e754a943ae9d8b3501cca147ecb6a128b7d62898fc3a9764bd2ee40b7535d84ed9f1f0521d91cef71df805a0f85c089d641d177d1f712e2a8bc6c53d79a0b1f5be0b5f8605ca73c7999507456a3072e2befaf23492b30c81472a9f2bf8c3f6e4df85e967816a84dcb09382a989493d2f2ae2d1988a11337c620f2624afc7a30771209a6734de56039b93440f6e861dbfe88a51d51950a63823dda605f8a9c2b355207838aea16487c2f695692ac212cbef2c25507457462ecb13ebb3081b696df0ce46ded9de139283bec26551f31878e3d459c4cc8a34c5175da387061f98c6bd7fe8f9091d4b62ac08ef375fd7f7cc1d2493e562f286086831f199e54b7989db50c2727ce73786382f224ee23260ba299e615159083331cc6ef60180e4484c3f8c742dfcbcf345cbea873984a1c181663049e86ded1267c9b2054262d5e69945172826e5987f15d2550b7efec59e0cec0bd2897ad15692982520d138057871912c5a51d0fc273a09a9a45c13a9dc6fbe83cbf244f52ad69fe1a726553960bdd6d1290e24743d2080a02b864c8880305b2abc29ab48da8528b6c7509655c5bc9ac0218ebb78b181844a925f29ace21082477b5d180790712af3fc20000873305cf80083e814c1490ec2b0ffae71128becda6b7cd223422a98ac4a11c25b814dfdff65e1adc5808dfd1d4717f4117703dcdfee50ed45323590fe3a924de7aaaef38cb3998e35cf1404d8572dc34284c58273901448698af2613405480b5c359d920f2cecd4e2ca9b2fd53181a0e3529b1f3e6df8a11d284a8d33b03ed9e25fa197210ff26925643c53de022104e4782979bba9c717958ff8f9cbedc8dbf26bde91e73180509abdcd7fc0f0398d7cc6e1549af434007afd177e71bdb0d1f6484dddbfb02e2aa3a57f2171ed85d02a0f8edfb04fc7f062951bf64d5ef1069a28a25adf7092e2b477af34117c3049425b7a29c4669781917d27fcc657890f776c401e399180c7414e890410f85ec65160a765647972a2e457458210928db48750dd439eb72d6d8b160d5a43b26e3aba70375f95161605a1dafe4e54af1f0bd9686d58f848416a86dec748b1add10013745cfd5c92571bf582f3975493e50c2392619e012ff63ef9a36c1a65e3fa0990b2102c7a28c571e8f38bb69db18318b85a34ee401899b002456af4f3d0398395195d2785cc34a61bc2c700093ab791a11048ac0ae047896973ddc0a00e9cac1f0a8c27b353815d5eb1bc90cef0e5488d1d6efd686c7b43570c4151975fcf3c8b2d023772b906c5c02381bd3858de7bd107e6bc3f2718605708d1daa170217aef0907d2fbd96d4e379aee284c010373a1ab6439a5458e8f61367bb6a4ac065780e56508a53f88450fe4f86a8c57bd32e6e7f5e0b68a2d3ec360f51a164324f7069aababce6e92c1c992d1ff75fa715cb7754a672a4e2b1e43cfb8a65bec05e3c565a72e75a2f8c42031ae9e15b107cbf722c1770c5b9d7fe5bbf5a97c0abd07472cc5c31d03cf57a483a40f832fa28414f16910ca9a1083eb486730a77472c83fe6558f8e01ce4ab7f39a6845bebe51934304c81b798f3bae8ab8a169dbd681e2ace4e754fa3110317529a5c8f02e35b2308b24c0c0b912a491acddf54c42c3ae5e4b3f2c54327d2600a48564ec902cd3bcb8552e3b5750ca9662d2102c3ccf435dcc26f74047781bc409f02c554ce1c0ac4b8e935755f9700657e3b4ce7be66ca27dc38551d8b09134cad302d5ee1aeeefb041df7019005c3f407bbca3ffe88f7c0e619f9550834437e01fa32c03f02caebbb7154771c9fe0316e67242210e96c00c54031e38226f60e6de84ad093836883fb7ac258a9080fbfafb645ead60305f12db0e2416ace4b5aa09802333de0090b517e2de7d241890961aa1f2f6b5e9886f455ee2c966522e2a59858e9250b796c49dfe00a093df1c6fc7b812e5b7b4ec45a147ef229b67b5455a8d29a05ef94b0579217ed690198a2d6dbb486c9ffe37a4a104a346fbbe97d6b8579542d63cb282e548ca69324d57b2afd816ac465b7e4061903de7df8c6d0ae344e0d202e126dbdba91574a8b4008e20073b50d703228ce96bff54d88ccdd5c9f0fffe978576f832c80e2f0b81cf7e12b815810c39ffbbc6a08f87b1488204c262555d0011f3b496ff447c232d68576968230067f27708b5a2206514df5aeead67be76042c0cf6b7c897544720f2133aa1f13ba8eaa2d282bd62d87da933bfce7970681dc3cb73a3e6021c604052386b7e40ea6107cae0517d08e718825e386e7d79122a403f382415b3f5a2bca9a61a03e4298e8fa1dc65046ebdef814b5507b5a0980a46bb99a09a53d6d190aec6fe89c9c0c2dfa8fd1fa9a116c08fa810442d0ff0520f7b7b070f087c4cdb8316b6c34e764bee05dc84ff55071d0d3657a408ea38aafc8242d7a18a2a16f393a52fb9c968df16a338ddb34c1157f93514a76b0a5adea00da4d09011c74ab8172841b7a81d0b1053a241eec51ed4271d42c2b12b4ed92417148b42c80478b8c4d059d1c7d4c0827b82140ef21b0b3bbc090ac2592521ca2a4830f4312e99f5bea02ecfaabfc856d50c781fc2ab9d25ecd3d3dca1f9b7d69183651533b20baadadf7e17fb5dbd3ae1c5a60023cd2a25fdcf42c04b7e9bd6ae0c6df190143962fb2674c156b821c8a9d6ccc728b90a4a3f22d6d143b802675ebafc0985fa2382303790c434f08a442258a3f66e1c17dca3a2259d6a731912259b5f9f9d85c16a334df06bcd2619a42a44282fabdcfe72814082dd11d2e793cd84f09a4a2d9c4aeef27c0581861044c4350fbd25dafda370cef21e5594219b7d090f6ee8253d0aa04682cf15057047d8f2500c9fd1ccb43d924f1453647ede32a7841813343fd8c55757b8bac2dc836799977724a5d2496eb8788f5d53136ff550ee42775e68d72eb5f0418397473418623af5fda3c11ea8a3704152863770405a16c8904f2d1229f2c0d7c02af9efb8a746426d18820c1cefe56303f7254696adb8804875e893edfb925feabd2b4e604930eee964841f7f563b86f6c693dc59e60479b579c6059c8a82a187e04e531ec9d1a206bc2894afb8f964ddd78062b9bd5c389ed2356bfd6a12d4b36910102660eb9207ace34d3ca9d75a8e5286738d2ea139fe96d974f6d4040aa77b324d5d28429a6df28f19c3ac621581569582acaf90f5808f84521ca8751b46b11a1fea23c032845e91c30d8e3157b8605bc5aa3591173d8f1e0762ee153da9de9fd1b1f987c4fdb39baf4056bed81cb26decedd814d4dd0b49f7296a121f94e408c1f563c87e02376ee8f1df1d9fe2c13269e071a0c69bb6c64150a9fe08214bd4e1e516a13b678adf57ab8e44e91362902d35aa5e94cea2ebec79dfb195387fab7e2228df3d9c317dc69a2662a58cf503cf370459ebc1938c0906bdebc28ffc596c3f98ad3d389fc1b2051ac8a8e7d91dbc9de5e79a6dbb3d44e36c983ab2db05a28f6c9a2ba3a3d87c18d604d210dcae5eb9cb60abd319f41dcb6047d5d6bd032b6b80669d4026bde7004a5be4cc26a3572c978d9f7dded1e24eba52e22b2f9d989e213bd301d084319ff7b84d90f902b90cd502751b93deecb42f6cb7d8af5315ab950f3ae650f3d747040f515c831fe1a03cab3d8100a95956466dd27f8adb60fc71569a5d450c443fb4ef90299ce14c6ca658224d16d7357aa3a5cfea28cbe39f9d1312cef03893576eea607cb1557b2f8964f21ac5de89330613085bb0ec406e8662870395604ef748c314911f0a81bd7ff8a59d32b6746e3b5c113a894743165bc2928d4e98dfe4b66f7c34e4e711d0bf2c02045d02487aa144595d96ad42a7c76a76b12ebe24b6c8c609de66b6f1aceadffaf681345765e3bcde4d6d41becd88b4bab117730a512bd37e0c6b13c15e1e7e3af788ec90f9a6330432ffdb49023d9100f805998dd8ae2d71538d4bdda4e1523768ac5237695cea061a97ba4183a56ed260a56ed2b8d48d342c7583864bdda4514adda061a99bb1c694e0dee84d09f2c6f4fcbcf528f52ba67f02fa99344f26dee40944feab56d92a353fb97e915438c4bd51f9ee913e614cc3969784c3415adee4a70717b53c346e158b0f6418cb0f07a943c4f8287333a843a25188f3a45eef51047d51a59e8b6829a56184c5c45ebed5fd26f5a47e933dc53d266ebadf949ea96faa37b836759bfd32a527f54df508eea66eb2b729bda92b53bd61dc4d816ff57ea911177f6ec7fe1a5cd20d00d92cb774d98fa1ccd949273832757a44590b7732c19c2a0ac07d2ef652dd9dcb0e373e1f9148c7fac7aa735e0489ea39017b2c1e3d94271a0f73aa1182c68f5cca0923cb504dbd8da294b905a9cf75c13ab55dd4b75576f016fa7eb2eed226078cfb9f92801bfe44ad69ad0c12846b242570f1e7e596f8ac396a7ac9a156832fd57d99bb82bcd88678d21968f63a07863b5d671e3493c172d9eb1d43ae107f035f64bf87c4d12667530421f6d6275a549976af8e42d21747abfe71693927d6cd41201abf812e72ff87264dcfd9a21213e8ef73d61761e6cbf6f8720462ba63a860c91979e5974d98cf8208048874dec098fccf3a94169b4c1c0ba3548974634b0ebec9f108355e41586961c60a3239a6e804b401be098808b8aeb0edc47bff3c425df0e6200aba31edd91a697cec64834be9447c641133e7cc1f3bd3472d3372383eee4348691bcbef53536375721e389e23483ef87c0b165d08847388d659309f40af3a0c678c68d77f87a9ff7340de8847f71010086456585cb90f88f374a1d34472460168066eb6a2f46e38f8e8819014f70dd22615378acbaad59b40443ed8509b2779fc77ba0ce2140a936446fdfafd662122fa4cea6e8c4f39053f14b8a146967bcd2cc8cd8d496af82874df1109a499251424663f623f4db46fcee04a0469a66a8dc7157c2547b2ef1c218264aeab9bdd2d89284de2d6185d194630c01f8b24555c4848582ba9cd0e4ab54d93943770d0d6bb221610748e1b534d5d4ab22cc25555eedfb582d7f4b41f112875606139af3b6744cba2357c0a989ed3a28425d189e18ba4cd72e73fa6b4875a6392b5ebd59b232286600b0cd88b40f1a4c2b918b556d3c7f1915a27b3ab1beeedb10711d1963c4bbdc61798a86b33cd2135f12df1d8b5eada7df645b493aaae1a5f2aedc3ad812bd70fe4ac2f4a588ded48114c8ec9c65f622d78584e88085c3534d77c8a277cd84707f373b60e54bcce07f02fed85af5c23edfe09edffd50c0339bb152dd595d91882437c8cfc275e1ac5b072709d251563ed906d7d5a0d02982651d6b0462bac47a1cf3979c4b2edcd7f179b9a0bdcf55db9fe32ad845063721b98c4ed7d881d2f1a72f1b8737ce05fbeccd22dc1b715d9c467413c940322c21ca0ce17387f499fd6b02beb8372402e30c29ed40a98bfd17f7f1aa59d4ac4601e0a78c89c103010cf07fef69f1088363ec413fe4605a159477b30891d12cbc090646656a8860915c4d0a798f8dc93a358bf290e4970939d0380deb9fcbd2c409fda4e6cb52b1d9e3e515dd1943a8d4021561f45cc370e3767e187948e1b1e90baec65f4bf6520879557194d51c9b98cbc64203eccfa54a2a70b0d61d13c8b59e24438976494a48a883dbaeac3efc8c9e81bf0b479a8763297255e2366ac9f6558084ded2a770766984ae2eeaa496622fd5f29f2cc7faffd1010430b33339c842ba6fd9e9f6a244e88522605d2d169b2580d70244a532079b54ce2c32cac65cfdc750f2a19abe113ea64d22710822e41072233b8c3808903d122847094b20798064c8c58324594604cfce48a2cb09d3542171975098670db6d88ad71d5f31092da5669f652331fa0aad0c0295196b6c9bc4a1450e7b0c59eddca3a45350c40826d60bed748cb71695cbe445f84a410f8eeb1953689b7a0f1ad9070237ce11552d58e78d3ac29c3f78b18bf208d8e48bc6bd64a20dba1dc9af3609924ae340dc6a19bc558a94305e932183abd8360c78e99732331cde9049ae061524136f67e090081d218b4e5e3e739ce48ec033dc205faa3863a0000dc581a2681b105dd8065fd70ed88cbc898466e72753f11b58bef3cc9abf366e19e3a5074669e843bef1933eeeb24ac25c32424daf94cb332b0dd28f4f26c031ad51d289e03da30eb4adaefc7fa0cd4614f8d244ca89af7d6ea832509cee10328048d8669dc3b43c0d077be348b9e1584100cda8cc1c9b144581a1384c8cf8e969f7db56d94d06a959bd9c2362272a3dbdb5c877d03e8ed013db94bf553d18e18ef57b4e03f01984034cecc4ac9b08d985998c5c0cb02f9808923c2413037ce8106b1f179802d5420f4f3ccd5ef51c0671c4013f1e488e8b04ba794a1bf2060f41a943631be3874ba540fa73feec1dd2ddfaa287e6c423bb5166ec69340600560406d40c8081d220b468fd2027598385b64777ac0ec6017682b8c7676cfd52f565834ca92c0039660895e8da83b1b4e3341626bc4285c54aea3db45dac378dcfd4cf3eb60f5b3773ebe75d7b527948746e66072fdba84d67f2cfd5c23cd324ef592f4550113332a7ca25220c95d89e8d0ea58e44ab08d7516e3d0caea6da447ab11d8dc213088107eda53f2e3d59ec392bf8bc336e527cc6852ee9dd9a46be320d266bd4436745cdfd3ddaff9f05ae5bb3dbc0ab97a1c59ed9e68d376287a0a36d9a0523232ecd50cc9ac65874ae92ed24466b22d388d98824da6d76167f2aa8f2cd69a9732d7750dc62ee614f1ee1366670d6be50e4cec588863424b3786bddbe6c2f3016f5928920185530ec3a0c5589372dc62162b69ae4a84419a958eee300f0d0aacab59be4fad9ff95f86676b60c494b20b47a1d78844c7602dfbe7a8fedcb24d1256da72a200f17563b461d092dc4ca484ca436026beb128cbac29855a7065dc4e0110773d06c11b0da62d37d4014e97d57094cb7118bdb7156de40c5f95533250750c56cd8eb288ec26e25a9485b201463dba9c66ce33a373e1fd22535b80733a4113339acaa599a19622cae747ee9dca1d89e216b0718857adc775e407344d255ed79ddffa04af72316321155a2b104d79b3aebccc76985d47833a9b7cd58bd44a091658560116c891b80ea76daa880c32ccface3bd538ee0494429999a45c13641444106b5922b52b407fdd4b900a32f2bb567d18c59f8854431fd89ebe0886da81e2e48cf5f18ceab6166f0958a03401291a80f89b4595341b5aa226ee6f852bc18b754c001af664fe9fa28b64ec6c37b5ebcb8777fcd632ac481ab448180b6917aae0c0e97d9ec55cb97111768f5394cbeb258c254ffc452a49916e84e89736835e0371ebf3db76f4bb16c0b96fea599cf6da308afc807cde1c058ef559430ad5a4b7af22bf7f01a47281a67977945f3c4b995a340fbf110334499a3c56e8df1327766880f0219a302add0d4cd7270c46d454ca4399778f52cdca92767d85810ef1e13cc79d5cdd4addafa59278a0f6d0af7d7795a4c3271d912ec57bc6fe6f433d7f853953d0526152b4bf646832a2dc7493380c97104099f7cd6c8c504ee86184fa1430cb8725300bc0baa24df8f7490a151b3c17609f9ae3fc0173a21edfbcb03c2211947b4172350f4183acaefa81590edcac905762bdb9c4b77f70173d0861659e94810f0c083718b41fb4f0792d9af6e37a905c4b9a2208f4b998d0b7a7f6291531f5685b5873c0604be30a0ef95ed6d6ed16fc41020edd6890ea0eedd2706d06076968b8daca6131552b1ce5a83c1ba2aff7759b5c35d8b26638c861d0bac31282c41797aef5a75c4f0884735fe2ff7d0a3f4b5e6cad21e8e656d2835fb043ad60d3eda95ad18e492383d771072521eb04cd0e0ebf57be8bcafedd34ac9068f090af6679a2e3db7094c1839bb2482c28e531d718891c267c13174f1631ab188f1092d2eca301bda6caf1440d6d1e1a64f74b15b77a60298712f84dc1bea6009d0ea2389e243d97e7269434fb94b9a2aca8f908141731a2c31c525406743fda3351a22f0119ef892b7b627292a74b6781b75d1816207fe875fae5da7dd4ad12f79d86731a33d6d263ff79d1c22674c3b3aa86535020711fdd628382276021254eea36a124542d6b777a88ff1e7f83ad70590f6ea72b8df6c63b44ac41b5fe3ae6fba1326026024b4a4f0ff66a593dbc0dcb381bdc48aeaccc2c29da575148df396c0b978e143e7bc471ae52e80b52cfb5f3a769cb07fdeb28a61c960f8c78367e0e3a24aece172b37faa0a1742199241c3e05f87063979e8d2dc7e2f795b43858d41907049ea67d24c4fc5cbad0d010fdc7b29836cb38cfc23e4e257dfba8a70a5f68a1c4d83f8bc4a316219b33ca85fa45abf838981805398aaef1b711b991cd5e904510f28e8b5bfdbfc5c2ac8e03c5e66bc2774ef3a019f2641e9d67a27ec5f03bcdf76879c1096bf21faae88e4a49ed68130daa9f8a28215e7006196e4ab931b735a0978bff623592e30c7dfbf248e4acad830553165d3276471399964ae322829e7576bb79e0821e6041412ef150cc2e782e58da855d903a78a68438acea0216f4838ec6e6f922a174abe55d43af8b1458c714900768cf3647096b977c7702b9712b061519b36fdb05606dc0bede390f7ec106d5bba3817e77daa37f6e4bfb75e03588b8f1e8d208230477075995f505c34094dbab7f072fe2c682a695fc47a5f2a131b48de0b6a15166016a0828bd696950e92837a33d669afecc5a27eaec8ebd856e10e27494802ef834679b57df0fa54b4d3dee41a3cf9647a08a72981986156524fa1ad7e9bc2bf807782bae4b4f8126d0efea3718ac57d75f953d1bf6518fe5f5529bfb452e9c7b2937c46fa52ed7c3a091e53c1fcde7cab4136115c81e26cfdecaceac755d1b41c03907f760e166bf06811ce7bc0e11c5cdec110b552911f55cbd1ddd186d2768729fe66d70ce3f7a3257caa0d1eb863505eb5063428d9c7c333d203499dc97275c1a93eb00b59d1337fb9fd9e1400c2077454c0fb34f3d1433f3e5483decf52f227d76783c2ee9b7c37640ecd90e3df594dca5ca39d911714b19ae702725c08eb07f89d1052acd892554355113736b9ed52129c83ad6a2bc1547b4e1f1293277b5532b4a41f514f85bbcbd6e4b4c9e980ca78ed7bf0ea72f5429dd046e88fb2d30ad7169df159dd5c030487f995b90292e007dbe2c853a7807b1ebf57ab3ff72cc614e86ca0405b5b39344940976ed7641a02cdbfffcbd31a6e1e8b1f8723ff3b62be4ea57ce4f3f1c99dd87937ea029d4a83cc408faf7856d89de3dc3fb82efa265dcea2cb7cbe18ec3263ccf280d095841d3514a1dcb9204992fa92273898f4126d98872d71cf1e044c845da003db7b0ee06e06b36ea93c90f3f28131e010bdd686cc455a280bbd7952d917f6b4afbfdb69434ad013a4733a4405a3e41e18a84c1c74db8fe16538e19a71c7593f82e52203f3b82ab22044dc01e0dad184c21ea05ee64692716e13fc0cd0d2461afac6facd5361bb144cf38058237ce8b54ea3646a463d3bd6d521f419b9802043664e6c1ee28c3d26f82c9aecc75cc3122db320501dadd71463df1b1b25521f0dd54ee239ab0887023a590caeda063fa2604d685ae2278d9341de280f6b3ea94a84a23a09a87a4b8615d0ca5c1280240c1d7e212f4e5a02b9071c5cebe3020d09f0f377038bf03367924d16b5aee01c2c36b7b83e3471c03a401de320f8419196790bf37480c466b009fd293fb3889b34ac6eefdbaba3d205bb27f83075baa4133fb54d80f4f8b84455954c1c2f7afbfca20ae12d0413c8dea31d6e223956a00d141552af292726a0362c7ba8b6b310bb28ee0f682c01bac677351bf18bbda8039fdb3209ca2cb1f7fb084e7bdce42896e700a41493246f39023a48e7e0fdc6e6fef3850a9a54adf500140957d181293154066d4c1040d418516265256e7ec8dd9fef2e63d9be131e7084ffc4fd3060600cd7b2c1e32d0cc0bdb5ba996a172accf0030210d170d3f98f35dd31c7ff3cb854a74cc6f1dda31415ec90bf6ab3ac196d0d4c0b86224d86f398e27a728dcf6b502d29be7528df75f6396dd7431cf7ebcdd925eea31dcfdea24602cf11c9c671ea04e5500e70984093dc81c4e284d632fd9d2c1df6cc954155604e2074683377910419cfe006646d7756ca9bf9fc84072f00034749b54720b9f038019c242c50d75060022430b508ba31e623f41a26042f742b8f99cd33e404755781891214a500e19d6ab4c7ce7ab28e631e154baf9e24320b223c6a082b13cc6229eb135ac956602903714941de9033510d2034c210f9c070738512c25c18050030f56bdc9086484681157da5a6f2a50cfcd53127f82b636910132d53423ef9d486ef97b6025b5ff2a4739e6592a5bdd62af75e263f3def7dafbf3c075ac327a71711e72d6b59f80b5cbc0d0f4361ad46a3bff554439cf70fea0dbc6d84be6638b626d03a1e609589102baa3deeb6ed9d3d700b809856d30df599fb815f2ec1a7eeb98d267ee3e8a18463200439bccc2e8ace7b466b9c5a4c40555da725e4620700b8855ec9a22b190bf0244205b20c2b240753b60c4c082d3b2330c2062e2b2a452220cc713ebf1134a7746ea5147e47de77fd3f403485b9c21965d88ba1c6b2a07675a10044d817e7dbc590fb704969b8c762bde55e47a5716c651e6d32fa9b4932d6e9e272c1c05b60079d304826c3a0b4e53741a36dd45e4f089ba2b6f511c5012cc0dbe9b80b002a493c44075fce3c501703a5af205f23a23a04cac2a1624dfa8b7ac44022769b129ba8399e6bfb345afc29eb899ddb4dc7955f33342a38bfa0b0ea6137ef1cb07d2dfac813b112c013d962e849c9ac016b9488b2e05d6520a5bc75c4e29b7d2fd86863e822593f5c436c0c2300fd8827e88381f7885ba94496f87becd411067e3b7812391f405ac4ef1136b85408112bea9e2f26aaeb48c434f66088577b45161d9aaad0accc60ca64fb5cd95d814d8b30d499ebb8a6c1e984cab0825d3f8f4d24cd33af15174ff13d36c8762f70b5056433b75c4ad52a7820b30d13d4f533eda31a429c2f48c780a294b8d9b6d7d82f285e4d545518a7a01e3a6cb350b8ee57ce96ecce5fb7a70fb7dbf31810a34dffb42a0887540ab240449f503ad531377567a7e32d82b55f0bc998aa0ba9fd994688af895282a802d31679a0a6dffa4096c4439d794c5284e558bcd9691eee338e0862eb1b3714fe0046d4b7d0b6fd4b3a9e944216eadb2e640c5c94349cf27647726bbe5b9d228855d3e005025417aa122a1125186d8427065ea42e15b3b92eca139105dd19d9a8df700fe47e7877ce30cd8ff251e99cc7abed08f2eb031d2486c206969d02d646b4eaac4a55f9826a3561998908752096a8158f4624c57d86ef3e26d1d0881908ceea5580627500d1c8c789d980b9b0599d53985df4b434ec5eca7883738849a2554d2116b6ab8e010385b60ba1554f419ac518981cc977aba99b5997ec1c7d7b802d728cc71dc4adbbcdccee3c28d3358bae2cbeb3e043865896ecaea5247074c49543f1c8ca2b43b01e774e08d9d6d087d986c254c79f8cba2a0263c064f244ed660e3b3d774f0444175dd25bc1f04cecc04bd834adb49952fbb0221da5a1a78e283cbc22641e567d46b4fdfc29ffbd2f04f928630c4f59f47bd233d90f648187c1196e2597a9f4a4c04766ad0a7dba37bc503ad680a95fdf925d2c12cf45a5be72f711f0997a6394ba0dd9e6847620a2b94e7c3852eb0ad990b216861c58ba57131c8f1a969dd40c0bf1036357fd6dfe56e299249c292be8320f1232d94d11e30b35e8503e8f5b16245353c6ebd27aaac441a7c5ab8edf4cd540d784b7ddfc6a5198c43a38eec9ea000edf72b8b4e8a288ac6841c16401df3bf72be3ad3d591a51021df22f526e0ae703e61d9ae7bbd6d6d1632768829ceaa94facf10ade0acb33e99f69c516d9fa37edad351a3e99b0da930d9e56b0ce8ac98fca2cdc3f72be095ba8b7584ae94d50f8ee1d952cecb92f5bdd2729c248527979da4a5ff478fe013139d1ade28e3098aabc2bc518d62be454754fd88fe455641d4563a93025c25ab137d41cf50cdf2364557a29429e1a8e30fa2ce1e54106cc9dc323110e57b2069e53b31863b89ec2a62677144c8ea0974c40b1cf28597e315b1c65a43e228eb246240bb4398159299c3a849ac9e21364f077afb7758a7670093044a302702e23e391b2f70d4e7269da901626a4cf06dfc542b9ff63bc354ac2f5fe1d66e9704738e00ad5b9be69fde44292c001bf820b609a2359fcf15a8a2b9b62963c274805502ca0ca8552dc6a8df2a8a5425f21720b7488f07454f39ac1afc446b4b7e27919d647072a9a2c1081fc0cdd12107c23c58b9d0b91a78767ca5c3709b06e800b3259959079c2bd5bf696e1410223f0b0cf007b25343ac7d236b0540d9485f7ee52589531e36f15d395c4899b17871480da8629ec5fd4cf12ebf27414c181050bbb099f22be7c4dfb7028beb180060887e98d2cea1f5c0c8dbd3d2df0f07353c67e6a762f925d45726a70d70ba5d6f841558e2b0143c2c388799755a187eb406e6d15e508883c15ae749dd3f2ba91bce2a757d1d75ad20a72698ea96c7f4f92b5e2b94a00d0ef751d0414270d695ad508764217d6926111b69e4bd4c755c3a1f0762761deeacd34701920a2d67cc113170873bb8dc2bf583f030352cbece75e96bebb61f2fac631b2decbb2c1e6a44bd6e8170bed0d5a78e0dcd41e325f012c81c98c7c876d6b2d34bba0fc4db8606176ecbbfedf6d4bba1c1aeabbfda24ffa7dd0f7d8520c2e1945fcb891f6a1ded8a14d282ea8b0f8edd9a786f8f3586046eae004852130dc7e984e47aeb158231ee605f91a59681c1270bbf1c83e16d02affa5aa38187f37b8baea3d47bfe4351a2cf9fb3246f90ee6cf7d390c5e7d67b2e7891d1c0539446fd714caf025121a4574d39d655e5763cda70bb667a8e86aca956d7f2877b527775cd1032e39b34d77887a8154ebb18ee1207ff66c458d98e6d764a773c3063d8bd65d3eb4873b3ccc4ae59f74c2458b3c6279c874c5dd47e836b6f05d57a41f2ba4c9339296636827d1b0767e66536568dcee425b39319ed7aad5d349a0d4f2ffc3a204a4e038bd9f812dce4159620f4248e2c49ed14c864fb6cdb90d19d45c56cb445111d804c5666e9a6b2504f0e775180cd6fa588acc38da854a28932892efc2d10b42ccc9852f61c82161370e06eb2d91ba347ad822b025fa0307a0ba5300f226b04bbbdfaac3fd31d8890d5e646290de57fc1002d630ff15b712000d2c05a973703de8086c00fab0a7a08edbb33a85fb572a143669ca90a76b7da237bf6cbf6b238059331d59ec1ee18a943275a3c367fbb21245d9558a9817f190d73ed80cae3f92e7e194e34129de2a7447a5a9509e28f9c8b0e2e75d154b0ea6401ee81ee73092a8c9c9828db5554d538dc9648b54fa180dffaf01bdc13900e2d3ac8e84824aa91b7a6a1be882185fd56f64409b04145709c155c1443741c60b651170ab3584d50188ac916a0aeb21ef711172dc1c8ccd424c571e4cefc82dd49b4ddbe60204edb0662dee2af50bf727cb1a2ad790bf35cec76218451ba7c81721ba152cd90916072669fac5a2825803b270acc26a9e79042229fa633964e26e7144fca784fb34bcc19ac0963623ee7b1b8aa37b1a99e2013f0e44ae972f13411bffa35d842d172021a70853d51fb038639a5c0f7c335d4c42610cab26e7375cb08359258192f7ca725247bfbac43c8116e299ad2e1e9f170ace3f052ef51d65a7428111448cb3196fb2f7af129433bcaec543238af109ee0474edac193c8fa42db75b37800267fe9b348ef6e07ee91616d30f3be9eab536764accdd132ad19f60f237dd707c13abf2101bc7f05cee644410f53209e514d07e958a1a923a316734471c26a40d3cbc32c8ae6deebc71afebb67d3c67af7e687f6ca82803cb42ffb4359e4f65537dd72bdf280f9101662c7a7e5ec48c982a6a1896d6bb16d6fb9f7de5b4a99920c390f850fd30e50b4213bcae7f5fd321d82e800739160580a008f06756f3ced72236a66292d4b358dbb34204d0b334bb9ab69b69416d3b4d0276d0d5b2abb77af8e8b35b8b654d37452885a4c9e3a2574a9fb8205d9ffeb5afd61d722c955e4cdd77cb5e893408b72ec82055ac82fd8704796b5a5c3810d93c822e80f51b226021b810cfde41e72043294ca997f365cac9340a93588881776e3e9a6b0281c8f3c75ab8ea78763d91cbfd9348b55b78ab9b3f45f2e4a2ccd8771c9f32b4c46ea72d0432a440a367af123957bfec4dc147eadec1fd2a05cc44d06f042094364f61f44f09035ece385067190aa5c544555590b37514c7f1c74caf282a5acac27b6f154232e22518977e275cf36f1483e20361e9189a75d8ec7e5722f78e16cc051c1491163fc6d176c977ca422667c0f7f040f5fc3c4bb01bfc667dc1c15a06634786b8d1e26d07ccdb8393e3830cf03ced9c1e30a9612806086972dffc73cce7f0ccea1a81c9ffeffc638329e06ce91f135fe4fe3ca78015c003c016e007e00173f78efc7cf86540445bd3c4e4cc318b6f0042df0b86a1cffbfce7d193f2fe9e6e52710512f6f847c030ae66b7b3137a268dc889a715f9e870b43801b51039099965000f800bc8e0e7e9dff97d7b9af23e361bec6c11b5102a830b7bed458f6975185b2ffd7a1ec7f53d901c013801b51f846d48d281937a25e6e44c1dc88024085350df2ac4ee68a967e28f3cda93a1f72b45c8ccda9b276c52096b52c6349114b3e056705a7fa0e2bac48178239b32e5824c2f20836069bf848ee1623dc9af37edac15858bc16eaa2ae17189815af2fcdb5c5935cb0e17ccd2f8290a510699cd535844c20370df1938c3893653a6e3ac956198f8c479e0030e7968ab5b490489fcdc9934a5e369e39679c11d1fb2f2f32647c36dfd768455182614fe657849cf135de5f10fdfd4d40a2feeb8bb7f1c853856d3c3c1370d4fd2224ea3ecccf979b30a9c63b726981b53902196348e63200bc192726d75b793b314695fa8a7014d7591d1faebe04b2154fa0f982d9ac2763c9131793257f1c723fd97ffbb1adccd54df1e262a49b7b6f856dc186f3355f134866a93833ff8978ea60b1e49f4d913b36a4c22c95234ab5ca3cd92f0fd7c3378e31e39d4226d07c65a92c65bb963c715cd7e25cd9bb16f7e262dbc6c5b818a76a9a6ee5acf99aafd06365ff4d93713d9eeb89aeb7f25499178358c39b41f6166241170e73a0007801f004307f62cc97c339002fdaa8695a258047b5eb91dc98a3edfe3f9bfacfbd7623bd9d3520925a6b97c30ab3b73547d1dbc180e4a923e29d660517a9051bd6eec6e5677824b733f5360b868dd67b027c36df4b30ec490e290beccef74a9406a401656d887553f7fe1d912e28d619e984e409d7a1d1caaa728abeb87c8ddfed6b9459b011c81c88e4b06a1fd22037452073e891fd2b11370515f12a5bbac8070fef9f118de201e738817a0d87d92b28254f3cbc7fa68a335a1472c865a91af415e1281eb81d07b160b915e6540eca2bd8b083859c2a5391cca8cbe5a2ae204e15c4a952b2a492a72ec3e10d19110ec1d1c8da2cb56ddd6a258754f5ad1cf4846429254f9e6af4a5ec10a76a6d2efb1a01c1c020192f966fe0ebb1aed7c3eb71d0ff5e8fc7e371bd95b7b35defaf97aa4131c6bf5bc9530de3731bea193adbc172118e92812b4c9680ec57da69b823d01432c5b0ee551679e2706b020c7eb94204f5e0c56ed535bc82a14b8ee3a9de6ed5345dab6bf8cf972c5530f469566195bd6b350d17eb1a9c4a96381970b11c76ad9bad62cc1331269b22d660010da8960121ca1473314e069c2aab020dd99feb3a8ab394156c58378b9dd2183ae79c343c7a339d0c8a18e3af653c3aabc1ac42673bd9b3286a7c3655b06185c1e429a23a32449a8da76bf8879d19b27f5724ce68efdfc1bad8e61d2ce31163fc379ea6c96ac0bda04f2e3853e130ab22fbd38dc7343115598a0a36ac1f66a9ec8d2b2cfbc7b491dc9e2bacc228ed988333665fca8e166fd61735ce08a59cb2033196b2bfa37ade5b9ca383e4bbf73e47878f0ebbe3ff297073e3a6239c02d184010c4453072278849b90f00ea421bb094704dd87f77d7dd49fd787bc3e541635448897bc02c99390cf8fa456cf7b4b42f29e25f9ea5d992a332dc9772fed736f04c977af444a92fa6bffa47452d28a8a4bc7b1b47ca792d139e72ca12593ce8fdf4dc9df8cbe2f897ecc5d327faacbb54fba24cf5d93ef7a460c7d6a151a72f3b821fbd7f658dd93bb47f7cc9e438cf1a643d708fd05ce82551472b9de936efdfeb6df30893ec106c59930e2c981104bfe414159145a627ef69fe16e4aeac949e24505701fd2c82738c08c335901224d9778d39bdc9671f3324184f4a1c115c6c83eb83782c3291fed9df0a11335f270a4a11f7f4634c9574027b5b05bc320fbf0de8887bb8897fc3b489e747cfa75a2b0a8fa516ca816f418281f79d251c9a0ea4761511cc985e042882611e01041343516117453f7b42a36165b48203b70ecd7efaf38c7a7b10eefbb27f91c1d3ef67744aa3353fde37dcb7e7d2348dec33abc27f98a75f8e0785847f7de937c4e8e8efa9cf7f623ca5f0ab15f8e5da4ba90b71cbb700215397496955fd8d092fa71ea738fe3911a1751bbdfc2c6992cfb7b11e2a95fb2146762670292b9081d88e56bfc8883ee3c1c74897dc5e336fce7cb29d846b57c247de8412e1f7a6cf4a1b74277adbce84937a2463ff22434f433b1a73a0babe3d3d859fee3368ed8af717b9d254bf327d76fb95efc2466627b8dc3dcb7dc0e935a0a36ba807ee4cee13f6e0aa3507459a195fd9b70938d1c5d553079761f72e8fdf8ca57aaee2e0b801882c21013f3354c925cf7047b1d08adeb41e852ec0384a2b611ba118010e5c6ce0a62c37ef547651736ec1749ce5b82cebd4d20a274448ff22a37a22acb6d14bdb5bd2ac38bd059ac6e56b3e2c8935dd8300a492937979bf2249347b925bf72495ee5daa78dda6af5be72a41b512297ab7d3637df6b5f897b5d448ddf70ef554b5262f2a590d4884ae957bfbafbd5fdea4ef0f3e0799ec89393a4c49bd7337772d27df23517ab8997448842922e2bbf9f447f47a6db771227defc1a77d6569369008873f6d432cf75b4d2bdf2755f1f2a10c5e1137c408826f62ce47bee2e4972d77bee8da8df611dddd7e73a4cbae1b8ae7b2906aac324f9243a384c92985444f7f68de09e04eb20d1e18343f2dcebb0de4759bdeb4f62b9aede8892bee22e101b73cca1afa8f7f44f8cf14fb9350260616121b9cb832f2f2f323c3a3d45faaa65aa0c1994caf8e84f8abd0e7293e782ec5fb1c77d364cf49328bef13e661c2906aafe6c79ee2314dcbb3c14dd93aec9936ec9b75c9467b927af7245bf72535e5e942ff9bea41bfb46c837a0485c6e44915822d6d1816247caebe8a0bc8ec9dbd739799d922759b911a57277a4b470d0df7f4aaebfc9bd2837455472236a47ca59ddea1f07c328d4225d5689191f063d6e001504c16f0ec09bd747fdeeaa1ed53dbd27d84e607363cf42278a477538ca92ea511547596239c1c69fc6458825ffe6626b20fe95005e7723aaaf67cea67fb8f02c8264969be40ff991a3102db23bcb5935a38deb97283b3497c0165c28cbec9452ca2dec8d3843b3ff0f098827077a42f63008c91f636e2cf9cb842197b27f47597294e4818d7207d689e4fe299b70e3861db9d0f429863bfcdc81151d45ad8e7d9938d3f97b0ebf8c3c71ffdf9c734e2063f0b803196395dd2f9023c5407d371fde6449268a2c65eaf7d30f88ce9ed599a914f6096d96c1e196ad9db4574fe0204b19af58a75774c88d6513ec8c313ea18ccc9c581ec1ca928b839a6f5af44f2b12c9ad5612b4e89f24b45a3aa8fe75c339fecd1f8e54429b55b0fc3000393e8ea69308fa872ea6ac7f66be9f4413032258e3a00b214b6ea23434ba8677eaa14bfed1515b8be28b15637a349ea1f961abeee7ee6920c4530389257f2914a1815a998f14509e8ef8509443302bc180682a4104730021c6f897a07b28e1a6e64104bd8380ea96a88d90fde510a62ab571bb7a60a53ff7fed9947c0f6c7fd82ed1f77526d8d8451376b622dd0b79efdf436efadebf8fb849f4fe9e7213c9fbbb8eab7cc74d27efef2b3799bcbff38833f6fdbd0691a6c18835fc7d0b55d4f791f2dba7f958f999ebd44aae8f95aff636acd2cfa68954b0e41b5662a7eab3993b0ef647841c42e61ac66f023b70f0f3c41b6c00051f30c2808ab154f2f596dc1088fa286f723bd7c87a23ca4dc2cb272b78ee78c97fb338dc91edcfd5ca9bfce6a69237c161125eaecf7dad77aeee54fdb075e76bbcc4c4a4e4fd576e8c2513dc3020b6bc444e2e79ff86d872096e2236f6556ee2de54b2aa9f0d87dbd66f2f977c7f44443082004610720957824943d8e7dee28949e0e52f2ec1860d23b95b04ab296c2273ef60052b6e98473f20b65c9f7e40cc5cf1123999cb1c6e227327fb6cb2b973a74a09366cd82492f29f8d6ae520e8226fde5166c51955c4c99eeb5c538a0475534abf69d30d8a18845e83c6356c3b64e74a72d8aa39649722965ac5850dbb889fa297e6d3f019b93ff432a52315af77b27f4753abaecc6107e536755004fd9b254799cd39e7ccba48906cd9187650966d9a5d99b3b3dec8d326e0d99c99d4c256edfa66a5ecd72e97ddd49a1de5761ba19775a2dbe88fe251d16d845b4e6294e7679a86e511ec1c6d2c1d6de6a2f2034b54806a43a524207cf941750395f2a10c952b8764c93f65a632b9452cce38b53a3e994e047ae227474ab391376f4ce1728db6bbbbab97ddce29572705fb745cd67dc8fd2442fbecb76f08ee331c76cf7dbddd8eed3ee6f6228c55d69eebac5ddb7de7fe1ab7ed9ee47bc067d37d43742f02eeb5aff583801c638c31c6c832707efd86981f1132f77b1f0498a831bf89519e9466ef1b42e6d089ac7ddd4b99bbeb3166fef755e975f704decfc3758c99df7d4064fdb988eba9721369f39f3cdc44da30139de7cfce73c74d13fb48f1bced869347f69f2affb9335772f2f8675a0ae6ac0ad6f1a11fc5a352bec6b92c9b7734536e741b24efc699783d4b2dec666b7bcd65184f26c1861d14676676abd3a97e9deed1e9c9dc67d3fd4924d81863e6bbac2ede8d3331e51d35936d77c82da5945fa3a599a3a41656b3990dcafe3afed3e22277909b422ea7dc21379647b0d34751cb36d1ec39f10200a9eddde3267f539cb1214a03b8e8699f9e4aa5524df88c9844448cdd44aa95dd1f63b8c35b7edf2476d4b8936937742253dfc96113fe357e12e817748df8f3fb46db3570ec17748dfe99c37f092dcff8f4c64853154664487ec51692e3c72bc5c8f1630e4623deefb91d0b201fd8b053b1f6f7c30d1a3236eef167e4e8a0b7943d6c7ccf31c6d04ffb6c601d5d14eac8737e416839c6186b1ddcb29a27aa26710b8b23ce78f954e3a51085c6b25874f1c8fe0df0d00b516474cd146e79c2315dae18c3219160678ce100b18b83fddd91a19664549abcd79d5ca9e86ea8f6c4a1dea0a65253732d0e541ba2adc18416c9140d5da2405463b921fbcbac13ea19fae1edd913873c9564a144e2396b6043efd962cc7f4adebff6e67542f40bfa9a9b4a96a2100e7e81236a21fb87320fe81a9d1811e8920b214fdd92257ffa2f20ef2c7416fc05ed267f2282fe26b8854cfc69b79c8a6eb9caa588312d244f256f223f7495a7e4a038d3bdbf4727432c1246a4913b5dc3ffa311a58088e23ef4316c1f3a908f114bfea11b494044852939f49e1f222af42db26b9d0ff91872a76934a0aee1df09494eee642c5733cf2ed7e84d1e36d4806860434e675261e536e4e014362392c1624c91ec9f152179cf846429fb4224f9d0bfbb055d202416bddca2c69998b7374d37cdcf76dcd45ec67d966ddc76bb18d8edb96b7fbb16b7d5b84ddb2637b3c8921e0673ec92b965acb96d730690c9d357b665f347e59a6e0a47b911903bff903b879e1037d1e4ef6b24bd49d0c8b14b9a243f7a21871e6e0ab59e8ce2204962203c4b1ebaa1ee889f74a42b0d5f64ffaae3a698756a0f17566ee2c153af70537419e191fd6b8f9b5872b6d6e3a65003ca3ddc8400086840f274f2b114a3a6c2430ec658f6ffee1614bfc66ab0a1c6aa911acb4d328b1f2d5a6e923888987f68ae206e7ab989d4783392c5c8fe9b5076fa9a811dc9c09ebcc98f3eec84260cb4988e924779920ce64a43913cc30c963d942c1e3785b3a7c74de184657753a8c57edc144e33e4193745571ac4709396754208d85457dcc8a71c6e5964530e372d6a4fde729df27a2642e60670f1030636dc545a8c8493f2253855f22898d4aff23928cf128bc54697e55218057a75d1035866c9b10b1b04e5fe6ec852060423927d219e3a2159cab810693455d7f082f682ecdfc92196fcc3ac48f6d7544d93c1ba4606d3761cf458ee9f2fb0daea6aaa7a8518314628c6d49eee480787ae0ddd1ba614565bb9a9635d7bf2a68a313b31468b8dc71683588235cd2645dc609075217bee6053d5a85063b1589a4adbd184e28c0f62d7860a453c69b158995091e0539fe8e6b0c5c0d62007d97fba60dbd9569d903c692c39c4934684c8c9ab650a8b335dce44603146c841d78810bba1cc92a7ae0db1e46fb3c49dd0ca869b6a46a14dc166af7d2a95332834a0cc8478ca01461ca2c2d013b2ff968378922324589f201f48114f9235450e372bb27f36c44d99cb4d2155e51c441afa8458c3b5f05344f5c8d344f96742b2206e8a99466107910a0d35909bfc29ec0a1ed94e2c4b16b52d3b52b973741b6572b7d546eadf81327952e31b1d943ff91da8940fe98bbe5e92f5fa6c6e504e52f0c945b93a294f55f08459bca9b6133c9a2db06127b4f21e2601d12c5009a5529d9a4f983ccaa7ace469aebcffc692a78872f5e4f9fac9ad1b95aff112ce6b4edb388ee33e9bade46a2ced47965c254f11b5e249413979fad1cf669a21c6945c19ebc184f741c43ab3bc35d76849fd9d3b8898e50711737bf476623838d409a52c05c2f4e5a01cc34ad626056cf423ac635b55ceeb84f2a6ba830d25cb0c71a63bcf1e7992ae1ee9a2af97ebe5da56b2c4aa2bafbaa91ae38a375587c3adb7cdda910c92413e5a38c25a2bc6d8a1e443aada549bcae54f5ff2a4f25df7e1a8abaa950cec7c95547d2a4f357bb829ab9a168b332e1776492959b2562c8f60b9e6616d3f96a7794c6e0e2564a93fe5aa72c893cce68a9b4b3d99ed9a116d881693278d154bdea22ca26144705e1a72e3be7b7be75e7e365bd64f816a6e84141654f23a286ff23b50275fdbfa8cf91ccadecfdd6dc806b4098931411c746d3f369ebbf5c8926f2dbbfdc44cbc79692cc69c01c8a4f1f68a31aad5914e88aa3ae6380ead363b8ab0d8667bc6cd8806f8acd6881042ba64c935203769b148443475b75c73ca5e42344d2fa6cbc1a012dc0dc992572922e8050ec23395fd651d6c485fb9514694bcc99b601d1b10690211054654e34e6853b5172c5444916e7474280c6807aaca7a52c26529a594720bbbc520ced4ecbfedc49959831cbcc294dc5f513ccf2537a2e6a429debc751563ea144335254f27ef2fe960c35f6d9b6b0eb673e7b0794c3ed458b1d9b3f5b47a305595dc46c562dba6e5b829e526ed876cb8a97636959be41fb9420c1e2a55d7ddc04163fbc1874e79890120d6d39371289e2c29d9a8c9b6e3a0ab3aa1d78d4ec99b3c7dd1177dcdd909cd2ec59373ce3997e83136d5a61add925983485c8922d0adfb289a12748f1af130856db28715c34d110850d0a44030c8bacd050483682245d0dd3472d0254f2f67d7a043b2fb6f2d5234d125c49850d7707fba84185220ea862eb5dc44cf1041ff8a294cd6df709612e590f6503a6c8e8521797bb9dc1481604148f6df826c422a97650f1b7a8ca61c741aa342dda56dc014480e36dc5cafecff65217eaff9fedf147cf07d113f2b4413cd3e2f6c2eee13126d74b0fbdadddeda5d869f8dd46cb638d87073650e7f3fe06037fc0169f87b6d520c1b7eaf39b3c8fef20b42e61ed9e796a936d7e6925226f6f3730a65724f8fcc17c4b9a80d35ce08b35a721dd55874cf84c27445d4ec9e0985e9d29a26035dc39180429f40108964ffd93dd9edd41231c61f047128034dd34fc41af2c444975a000625624c9ce1b27cb91ab9a44b26958de49609325d31c65f0ecd54c96b571e71500e79ca53f264224f2697ae86526e8a122681de60437fc9d5a45b66bf57f2e43a5ef2ffbee270abdd93e07044f21e0edf7b0e87a0e82d0e6f9c4a9e0487dec3c3a1678143d7428443ffa1f21f0e3d93af3844c9a1a746df792ac321a8e1c6e18d15552e7994dff06b623fa1e09962bd138c5df27c17e244b2fb10217e924750423934347be4a9e455664b9e462f27102c681671d386f2355a3a846b9a066a1fbf6e9bf9f41bc2958833ee06dbd9724f251856f3970b893354f02a348dfc9315ed045be31964c5a3f65f6060de88947fc13a5e3ee5615e3ee575c06cdb0bcccaa7908a60f995c761f9959667f9c638a44fc1392e4f7a6aff5f607ec7b78c4ff91c985ff91da3d10884916db0290ff3a17c7cb14f288174a6047a092b62e565bc112b8f75fcffcbeb90f12b37566ebc8c94872115b1f2298fb3f229392fbff28d71521e06e7c07c8a900de51085b9748506d11865b95196ba6ca7e51009039a2e3954f2ae8275f868af628275a4bcc98fb08e951fbdaffc68e5fa74bfc9375ee246e5355cc40e54c9d7c8900a85592a6707aa441e71d0e76b8eae8a8cc2ce941c7250b2c1ca0fe550766d7706992fb721d7f09a86c3c6f3e5b2ae2026efd29b07f1e4df4470e885fd45760d872d85ec42b2771fa3697b6a755c67f690eaa77c44912a2615a1f2286fc4caa7601d29bff22858870f4ecaafbc0e945719dd88ea1e799a2e59f29eef7bd1747df5a3fd7ebabef70f4bcf2584ca2bbeea744d97836ab09d4bdee479101b08db86c32e42f6d7ba67ba66901fa6cb4d9a903924c87465ffe99aae6dc3f208f606dd4c2e284b32d92a471e9c28d941e2325635ce08bf6e095d8b5b0317eb96c6ad818b65ada6a12e6e0d7dea6cd0a2aea6a141f3d5d9a04fb30a5e678fb37a9ac67fb8cb87d02787420fc5a2c787e02c5775ab57d3358be0507097ff9840666b1ac17f4c2f6611e2890281357f58f3871563bafa5ddd3f9b258288f9d3365511b619d8903c65c5191320b0acfceacff9d96c3fbf203a2f41f24548d43f6575302ff96b5a6c248635e25b5724c762f667542bcc41eda5e8e4a5111b67669665d973aa92922044d924c8bebc8c1fa1fce8925abe948f1f8bcb7d98e7546e221161f22bbf82c31dd90493563e66938fdb888a94d1f550482d2c2e6d62b2f212c8ae6093549c99ddd04aa6918e62c90deb134c34ccbd5727ba64b07e64fc2adc4438b42b5b4a9e38b9a5b22d458f703179ea561287242b8e9397e3388e66415c00e95e3bc85dab6b75ada67155f6569c11893227041b0acafe210794ddb005db72c558586119e652dbd0c633b46d3c92e429ab1ac9f4a7ba7f369976f2355e823b58172451fee47644d260c30e060bd24e5e548db8a9e4635dd0c9c7cf26e56bb42a3619e9c31b9986322c1f82997e1ed12dd3af11429ef0d3bf91a797a71f9388b0acbd087745b4ce48f69768b0f42b6c44c2e10ddb824319161c8223bc82a5ab04c3e88953c90ec6ad34983c6d28ff2ee8a3b8c21c74224effe4351c7af90cb606395861d588835e612ab712a929b7c6621605734212733133d8b05bdddf2e3e038e555819ecea66b8eb3432b870b122d64d24cda28c72ec82055468d273cfba88b4954f483ffb16d187d9772b073b1e1164af7d8d773c6ecab06f5b96dd8ea75b39c8a35bd1ef561d0f99f9678a39212ee6a01c83ed78a818ac2a066074302f254ff7fdbfd5c7c34dfd32de8e7b421ed0a7ca5f2a7b431e2c7b411c8bfb91d4254b3e7a9d702e29e254185f92f624fa1325511355dbc3370a47f9b4b74729f2e1f2358eef44557b63ae5673d7fcf933d435e489b26612fa44873054e25eb8ab4f33095d9a3fb23479b2cb578f83becd39a766e7a54014c810fa54c1506172a869fabd31bd42ac119b76d143d96916b23f9078a261b85c34886ab033642d0c42aeb3f3576c3ba3d6c6da7878688d1df1539672afe78a110fbb93379dccfaf15aa32b321e1e7962cc036d3a242a2d9635acc53421b7e19f5dcd481836d462d93fa6094d0d264f2fef9fa56a86691554945f6ea3629266d2e551ac1c7a29973a9258b01ade54a955d76a75ad51100d23721357588c09b2f879d844df5193af5dd1cb6d44599a163420caa2acf9d3544565b0b1362b684ff6a6d980106b6c37d8846084ec5f372b22cd09b68c83387382519ed887cbd6c34f9c187e859f74a29041bdbccaa25cde9f1372f9282ceae5fdb9212be269be78b0bd50215096a6050d68b34337490e391589fc829d4f5fbb76cbb18b27bae856151663bcc62aac248715d6579467e5422c791561742ddaf184c1ce8ec7c8ecba979fb7e3e1a0048345c9dd8ac74d9113721b5c8c53d518457915ea5ad3e3549cea72ab0bc0fccb1bf12fe38d78f98b75c0fccbcbc03a7c7060fee5bfc25e1e0693e4cb37a048386f40f1f09d630f5fe3190d8a9987a74234f693878374be26d0a435489e6a6c5ee8f510e0436f25800f3d1e990f6b8cc6d721f0432f35800f3dd58d28991b51356e44699ccaebf158dc8a5371ab0aeb78ba9583954885d5a0972cb2ffcb4de95f6e858132f7e56b5c98d76ee71eaecf04224a67c6f3f031e6697c0f553ec1bebcdc14722a1775d1206eb2e1d4c5a9e469be54f34583e6ab9ba2ebe9a8e8923fcc8d6d23ec6ed075ab95cc9df1352e0f3d2cd19824f1d42a17624cac76e1a5c2aa182a6c898c89ec1bdbd027ddcce0e1e337808f791df0697c95e1c5ea721d1563d6822c75730543f63789a70a8b25b9858543ac4171268c78daaa1df2768638b30531a66ff6deecbf101784209f3b5712fb41f2cff0d3e64aa5524150f2473f64ea43a6f467c48fa61863c46d63901c2db519a519a5d134f34b493b350358ce70685fd2e81ac2e8fb2ba5d45bee82b9a988cb8d78cb819c880749974fb3e972d3cb4df23b88bc6901cb77f7f37cb47cfcb295afeec5ef56ff7093f6513e8a490e7912420924fce4f2a40f715ce5c34824c7940f4f39be8d48d344d7901fff869bbe8fff839f58ea77a796cf01caf880430537d1346da46bc84fc16264146cd23d39e4c94725381c598b434bf2daac1d6a94b7442ffa96e84537b68b628cd99ac74d22dc3c4c34b1b59091a6e92379e54a54aa6bc84f79aa697cd535e4afbc2bca2c9fbf1c74495f358d73b1042abc1ef9c34b9245fe777dacbcfc6c3aec2d25b0dc0ac452ff17b0c0014308d91f104b3d248b21b69cbdfc888831fd426647174dbc0309dd42f2e4a93ed234beb3d3471cd5d335e4f77cd75dd77fc418f9d965a2099b7d093146be73116bc8f79e1e64f9d35b3146febc830d9b27f60e2de467b3da691abfa26bc8bf22cb9d2cbfaef818fdbc3e569ee57a10f71e97cbedd4f5e1ad7c6561f9e82c59baa2699c09bd0a9d10ea6979c9e3041d64b9f2435964f92d5789584ab15c24228e98440457422bf72696624f10771ff00d61f3fc91dbd78c8895db28213bb498d4015f2021fb4fd11031660a498869296c91fd65bb32b9a395fd47236b8fe8198da676e71057e4d8685f9193fde54b1e373576e92b56f0e8db52283ecaa2c619e15c65196547fff9e1a6fecd7f46fe6e452cc9973cc8f2455994333ca776e79c2a39e996c52a8ca161e701c36a7688340fe81a3ff2489cf12c6f4f7376e5911823ff014d23ed106bc897728c2a04c93fd97fb0602916a2c641f9f2e78a0e91f1c1c1b96dd68e4651364db98df91d86f4955f997bc3c10994c3286329437166cb7146e62bfc345d5e9abff5b059642d9efec8d37f4e962cb9e653a0d18f884c21f359d38883d316994147bc347fa2cca1ece567436b2783648cebae2c92061b24636e8a797277c6ee143a4275a88aeeb889eed04bb34b75e6911a2d17e583f2b492327aa9f2f26fe409e5a5ac2fbfd62134d8ec83c8b08f93af98a686e6113f9d6039bf4aa13c3fdbe690c473c8c1234e77fc0c563ef715875427cfd4a53b0ecee72ed5e92e55c5ec148a3928cd30632d3f6d0b9e73885258fa449ecf9a433166fecdc9af7c4bb7529ef4f37bf42e3f47ef82737cea8fbee22570529e94f212dfe8b4e09c46adfc09ce69144bcff61339b370706e75c3d3e5e07cb98df93a3ef2ce2064b0e174f9ca355f2d77feb88df9f24e9683730eb1f2f421c9df9165c9c76cbfcea19f58da167ba783934484f17479de6f1e9696846b0b9632f334ed0b4294b3dc3e1b19733873e4366df3faebb26f021275f232488261eb33317328e917445fcfeaf8b47c8df66bb93ea17cef5b42efe7907769cac1f9211279fb1a9f47eacfcfa3518d717efdf9d9d4fad5f73ce9494c871c9cbfdd79440c76cea7a9e91a4dcf0a799352d6a992a7e80ab2419eaf5ebedc24f37c29643ee1fbd9fd7c17e2a6ed67fd300ad559679df3fbd0a390e78cae1b52e541e24cf6f3e4270b6e16ee942bcf6eb5ec1cc99e3c2d4f9e5baaaa5c9fda9eca25d177d444558fee221f2913153f231a9582739c409d3cc9fbfcdd7a4330bbcac1f9a45c2f97650beccfa18dc453221c5a5b7f0ed59ff5c3431e2ec25135b234699658b0371c9c2fe3e09cb6e350ee48a2582fc6c86db376f6d3201297b185dfceb3695c95637dcbc94c43e6468d3c71db6733ac3fb5fe3a3e598c5b3c916ebcef6c3c91a6ff289e327b41b72186a75ce59f5dd771507aca53aeb2b787dc86d015acfc7e2371c6a5103782dcbdf5d3c3b3927f43feb63d09cef1a1bf3dc54be0702fe27ee21b9d0fe734aa7b0fe734aa4a5096e4779b941b1bec0c99ada1c619e1d3d8d13ac5d2b1cc700f4af2b75be3e0d78c942181a389d44e04e21183e2908e6a7573849b701cfbd0bec6e56d806bfb8cc4b66d1209e93888ae6a9c41e32673e341edfaf659862d49d307d0ec27a52ff11482ca2bbf0112cb0f29de1c9c39668f940635ce7092fbe0df2edb0f3606d93e44c9f2b96bbde4257fed8ee86c306affa0a4c60f52c54e577183dc5d8e41aaf0411544a8e2f5e518a48a169de2489763902984b22054f00842c58ecd3108153db6205468c105a1c209b9bf765e902a6041a800aa41a8d042102ac2e0c5508f21a1da7122110eda7b45577cef53b7ba2467b7e28c2bcecc2caf90e5bb9c5994e9edfee1a0ec96abfd3de026ede5e370d3a5dafb67c344d7755c0c7e80a4aee8b86e69402e21b02244b2ec205936912c651bc9d229fd6ca4b78b6890bce1f0b5eb011cf2141bc3a0479be2a787833d2cefeeeeeeee5669f4c3f8d2b4d681d04d067034b193bb5d40bac8611c02a4852fe43178e4301a21c9f148eea6b7015cfcf0e8b8eeeeeeee98b9eeee6e547cfd08991ea990dd2696fca3a86147580bb3300bb33095f7c89ec52a8b2d67b8474602368259988585e0115b74708aa1c61961d3978791a4f9df47d2c4a40bf4fb1be1ff611dfdfe2658870f4ebf7c1cf2d42a3955726a78246563d2f606d4f79ded87fdf3ddf84f11e5b72ace64597eaf74bcd7c93e0a8b2279c9832cdb8a2c3f927c141625838683b2013542b80df93a3e534349939752b6eb44a67c8f4c70c8539438e429a2a48665c09d95db6815917eadb55a72ed9bdcef53aee8516effca7579954bfa93cbf2a3dbe2f37dfcbaf71b51244fb0f127f5909061841d918156edb8c9b3a438e4a966cb2110a25cf369a20cc618f9352ea160e3c7faeee3fbec7b19576551f649ae4e143228fb2abb44c5a48d13bd0e9827f9be3a5e5ef4553ec1aa628c7c19c4c625b4e7b4e7b04df64c90363c99984044e9b83ce93b4cdade087f9237a29fa4fdff0e94bd240d938a28f9ef350de398fce39c97377919bf03d569a40e03e1b97b6e24d4abbe82d55ac8b07f64d93cb2ec2cb2ec380d87fc24dc64234b5211252532700e0c2669ef4ff225cf611c93ff70ce0b266db8087f127f12124ebfe8fb4595e4a6bce8a2bccb5d79d25569b9a3cf563ee575541ea5c424e6961b5137a3d7d159799d942f791d159612941415f92bf24727a39356459def495e47f4f64d6e4a927050aa2e89fce4cb1dab04c6e1a07c17ea1c250835cee89f6e49216e366b47a357d8ab0ffb8a6d8b29b387c1851caf90fd697cfa35cee3bfa54676647f145f4337663a92a7887af7295dd329901a6764f5b53722fbeeb5ecbbd7a1916eb427918c9062a032261c7b7bcbee1b9dfadd57e9b1a56889dfe49328c77174ce39e79c73663bdc270d6a0576a05682b6b0a5d80fc619515880dc1801b98538ee06f297cb47987f99dc37727704e2e9e6716c37195767476d2fbeec4fc6d7b894e1b2b2dc888ab8a75ff2c7956b9015bce0c51ba2d03c02f1bcfa5b889b6ce4b622c619f9fddd3cc81d773679ea572cf5775f91f589f29b87347f473e7993f7dbb9dba89b44ff7d7453cae84954701883b28328388c62386882c3e8a0c5618c9160f981f61fcc2f71af5a555d2ee9e6e5856484182897975dd8f8318a2128954a3de143ee7f4016b99f67486e1772b1810939a491bb1302632787377203f1f991c3182497e48ecde3a65640fee2c7ef66f4357ea3c3f223d2b75020a256c016d21d5d96bb7261565e96ba07378f83120636f6cf5671eb86ec63e74a433f54911f663447899bd513c72e350dc5b16b84366b57cb1dfd34e587b6b3b8deb6857d423cc5d845c83e930f061572d640b8c859d831154bb5da46a3d1c4c27eefbd7fd82c28ea7f0f857defc33b501e2651fc7d38c787d21ad734eacdfa3ea2326a84fd0febf8debe8775f8e07c6f5f879765f294d1686946bfb036fb9a651e0ebbd5ac8985d5e1435f87fdfaade5f8d96092f61fc538224c2ae2fbf9240de37cd8be7c128e7df9160b213dfafd1ea7f956e56763398c533f479b1fe9c6729f33bf3e87658e672f49fbfe41d54bd2f04d44a5727cdab52ec8557adaed5c90ebf4b4ebaa5ca9a75ded6e2ec855a399b689382d57ee6a5ffb2315f17dfd0b7c5f3169bb80f7a40da7bec5393edbe790d8176997e6da9fcd124474de341b8dbb19c7ca7ebbd9735887cff63ae6578b75c8b7b9a424e80859ca5ebb34ff8671e4dbef1f59cab217654f92fd97a1be66c952b6c2ad7230cbb2f938f271c8522c673ad357d4ad16dcbffab5e9a6b0f249f127c9bf203621dabbd099cf3bc44ce18ea0f47b028f724ada3e84194f3ada47f128eda3cf14c17cd9edd839b1f76d0e2ec1f6879bed2f6a8d36c6929066c742c89d3d8b52bdeb844da5524fa0ea4b69c3c912faf237da11945fe7078199e97337ebe8a2186324a923757889cef299e82cb9dbd97393fc395fbb9ef49162757cb2ffbe1b81b2ef68da91331b67a2f4a9d8c72926c9ef4c738d4f286a3b18230e6cfc2a5590b32c7198d3ab88fde56003b91007fbe70d6ce82f8ff91594864cfdd55c2aafb2263fda6ddbfca3dd7ac3d2721fadb0a1d562ccddab96f835bbc70ad99b5b752a7af65c9de560bb163c3d7e7ef82bc88aa545cbf572e92f3785be72a0980b698f2095334a91e31863a60f2e0b079b87e37181afdcd4ef3cdcf41dd4636557ae357c61b55a096dfef1a8b7b776973695ca7710741bfdb40536949171930f6e9ad17d087fa022897b445bc6a02053f0e4d93273553b76c7183707a36c2ad49cca3eb0720442d1f9525c80c1c54f0e696400e41cfe20dd737493ede82eea08e445ed7fff18638c31c618638c312620c7768f518bb1e3490eed49afe411364ff9126abc53d397e02dd3c43511745f427479ca1ba87bf2d85e3d115d8a986a9ddc1a75ac9b759a087a4d0f7646d7f000740d4d34c5d8832ef9bb1591c3aee25c3d0461d25837377d049d26fbdf88569e3a5cf39cad91a7144ef5c42d34e4365a0c3008e53ea1a05c0ab13247203c46f2ccb10b2710e96903cb046d56ab87073106066b2ec05c0d6b57c35c8807b9912507fab0571cbe99911b88060ea04d932d34ad5bb061d3b1b0f25b5cc418ff772534e8afec4de81afe610c92fd671536f4164dcf0f716e41a71c9cd846d0db155be045f66f1ca3cdb21567beecef3fdc156780c453af5c0ad97f07ad9e18c3839f1d6420784a965c94250faca756a955aa57cda14420e7a2e5a9562bc6d8c09f909e02f294b75a6e9a4172e8839056ebfe04d2bcd4a3c6198e6a825a4ee270653d41c87446949c9fcdfccc52cb614a65a55e5f2e07257fd808e8a55a712e14ebe6d4c4f02339288c4d24da34e9cd6da319cde87c3ae9ece84629cd68d6dfddbe46ef8613374133f7f5f69099350e6b3373610f0123fb93b4485a24ad2c1fdf1a59fa943c2171632403c6b6163a6736fdfd49825cbcc6483d4253eeee47a88e9018b287f5f8451c8cb128d43823bc4247a8e32e06761ec9a1cd97ae9aee6c41b041b0473caab2954415678288b962ba233a429292a706bc7c51113729e0e58b626e4ac0cb171971d30f2f5f24e4269a972f12c34d332f5f34e42604bca43c255fa34df9f8d9a4a45870f4fdd9ac7c8df62525e5e54d7efb2d9fbcf6d9802838dc9151bede50f6b015e54d3e7e362c3c1c9435e5865328a7a4a4a4dc7016c926269de7f7e51570493e01b7e47fb8f669eec9cf5cf011705148284f4621e1c9f21b70597878e9e5ebcb6559a560161e69f22a35af825fbed6cbc2f37259562f5b3f6459b15c514c96fcb331a9292b37bdbc7c161e2c3c2fb8adc94b139cc414caf5e5474463218ad70b9e532847f0faa879941a3c32e2a593af277714fb4c70b8239bfc48c84d2838ec8cf2f2bd0671e6bfde0f7d8a5c5d8a5c5b8064497eadf90a7efd16e2a6d2d76f20370de0ebf71037b93ccc5795afa8afa3af2b5f657c7df94afa9af2f53d156758bee23009e7c9287724348a5561513e1cc5821819f91a47dd968f6243a1be05489e4643b2243f00b805e86220961755965f612e005ee5cef8bf9e5bae8f05bccb65e27e135bc60bf8110f2d455a8ab414c992a6504a5b86603217176dd4a55c52b224b98ddbb80dccdbb6bd0f063ceaaa361403e2b6591c76b79d3eb4f906c964c30007f0e15500991aac1b0001d45cf0962258bf746322587f00b70011acef726d44b03ecc454004ebabdc0444b0aaa8c0d21037abbcf6da67a3424a79d980b0725b8ec8b8a454f7d98c70cb50cbd0cb8d1389479e5a864c36aa187490ebb70c791d5dc4825b0a27e2d02fc8f5bbcf4625042d851372c829df4fe4fa3ee07034875cff006dc8f50dd055f12a000e373bea5e5e58b76b29810ce83af7566ecccbb8347e747b78d4cdff57e697cb04134bf4189900bf444e2a955fbe892d17e04743f2e4a2b243b95d2cab2c63a9fec66d251ba945395a83cad0982cc90fc07dc992fc4dc687f69f64e526d9a5e4c985158e6cb865048c0a60633cdd58f2bcfa953e5a97af9fe77da5affdc1a8e0704756f97ac3cfb5e65aafcb27810824a7e402e0186360542ea9c741174ce2d98050baa42b1ceca93ca41628436ad5c0a1e56a0f778908d68fb92688607d1a370511ac4f80ab23c6d467c11d72fd7c7574a278548c0708e31a72fd2864503116208c4236ea7bdf102819fcfa7574510b0e418ca91feeb0011a72fdfa0111cf9053de25b66d178360ca97a4901f87a3970572cabbb0e4898ba55a922b4bae3fc2ac9bebaf605645c1105c4e297d952d2bd89a973c6db154df6e23fbaf2cdf25264f602cd597d96cfd58965f734956ad015c92cb41e9ca618e21b65c71e9927ed88098446a65f92e2c92950a12f9e50580c35100706853581500f70311ac3fe3862082f5177047104bf579b8268831f571915c9f03b146fd17c421d7ffbe2150f2cb575147175dbc81979457a9efa5bc8bea5d54325c54302eaa97171cee70424e79f9249efaf2ebd777c1e1a800d9d66fc13c59be97f22d432a2f559ea56548e5472d2abfd23294e57bdf1037a77cfd6a7ce526151c76ae9864e5a04cf9144cc203c5e46b7c1473d3c9cb1f1971537df923a113dc16050527e13cb90e910150ae2715938630f9fa26d8c324709e4cc2c341f9720925571413197150ce2239ec52a92cb1a848146c48b2123dc94a3e090f3749cfdec0842265c831825e8dbbe8b68beee660d815c7ee86b527cbe748ad9aca32ec523928cb9f374c0285eeb8295ea11f9c860c6a946167ae245a9dda8d83fd0f70b0a79cd3a74b0f780947dbeec399b9affe1d69e8bbbc38907859e9812b73bd3a39dc467f0b94e06e130ece76a7ee943aa54ea93b7589447fdd7663b7bb37e14ea4b808a34764209bde71ce2939d1cc47e023907093e62f3f1b4d4b0225fb6b1f1107b0424819b26b1e09507206e4e9015eeace6b17349a3595f4279d73fe0cd0fffd820ecafc211233e4e739a74667d39fefee7e1b7450fe0c07c3cf6096f92ae80709730a5db460480f560f578e04d029bde38e8f5f77e07c52bee39c96979f43faef775c70e670f928ff7b23fc7b17ac43fe27236ae6686de698148fe61b502ef26b74f9c1c18973e3e0115a3694c3835c79feb46af6541647e9a00e9a1dcb33c335f8468e833387833305834c484673cc97e1c99777517994972e63737e8ef9393368cebeb91163e694715fdeaf8bdc3a478c995db0333331f3cbc78c435f1bbdcaebac3ccad7972be35d2ecc93aefc96db4fe48833599cd1f2f49f53e429459e1f653ccef732708e8ff639f2bfd7308ef73038c7dffbdee57a5f4f6e7d966bf2a35bf22bd7beca2579942bfa8cfa47ba91fe199ddf5cd9f925f327872ccd18ee2007e77b4af3931698ecc8714bb763b38f59a33fea762c898893ec2819938640c9f45132c5e1e6e260bbe1085e10b2051c50610a6a40858e7fd43f1ac314605043769771d68c9fae542ad50315b76d349a2125501732888137618b343e8d2f021a31a533c6183bce1b3efdeceb9cd90d3b9312cf9862a01f15203f7ed7072fd197912789859037e4899a5afe03fc24849bbc07a5473848df8bf85ebe11de3b9658870f8ebff73ae47ffffdb73cc99e7801efbf3742f4246fc4f71693e08f766b669aec56b75add137f224a49d9e374ae91f41d449b8783b4570e521eb7415fc747db5a30f1845614ef49e59e0de3c04874538dd2d6ced69f7693d2ad4b7fbedcef61aef79c8ffcefa1f0f77ef4da4cf6f41dd0a71cb2441f0b99beaa0b997eec1f979bc266656a23d3ef56ffa0ed3d92f66a6e20c6d0cf214f1ce8127d1add90298d68c8f4358c04146cbf7b2fb7e5612ec9a5c3a48c1322ce704f7f88786a2e62893ee568b782d8e6386cb335fd6c982065f8a685f4dacb2dec64791d951f7d03a159a6feb4e99669d3d63cd9052b37cf7bc499f9f4dd07f1d453442b7c32a5f4bb573186beec8275daf22e7f04e95fbebf1b980973bbe582916869217da4abc3dffb96abc3277b1d925484fcef71e47f9f611c67b9243f2a79956bffe4d647b926bfe9d817bd764937dfa7a303c59bbc8e4ec9eb90fcf73af6754499f77090b64b96e87f22fa24f4eda56f72e9506dc91265798f8394b67c7f8a45e0aecc57b850234a87f753c7f65247f7db4bac437ef61388a80de7f82c81e3fdc43ae66b3f8188f23489aaf5e640b103457f7befe6f814417f7b1f1cfadbd7ab83fe86238e9bbd4e74dd452a4a6665faf2ce3a581dd87e5923e9dca48f21c2224cd608ebaa8864f6c421b524a21b1b10f4b3af91daf5a771ca3b44bd821278328c887a052554b1753ba8cb27e27b9b94a194d24c083ad81004696c1b10212fbec0430e42392647207200d23f6b5a3ea5d4b112fea4cdebb075b06bb88d66ed619d0ed222cfaee98aad490ea7770cea7cdaa0d21bdb877eecea4d8b5b943273ce9903db2fbf658732b9678405719b8da7ee259e3297db30d8c3fa699e39a9cca426a59438472cc5ffe1609c73e296cdbc44d56078f77597fe52cb3cd23935994997608e2fe5d675d23937a9c94c4629fd43f91447a9b514f2ff5bf4cfbec618a33b0e9df5d3d2349cb95b11b877a32cd5db7171ce2cc31beed71cacf672cb70c492b7a6c1828488a5f6ee98b54dd35a488c896f238ef1a70b8c258e0935ce4071508ab80fbd138cf28c27256449c6b62cfb1a396fa8fdb6936912214acee64d0225879d498092b52d44c9d91744120ee270507e2ffabf91a7fed0622cb3af91f123ddf8c76c447ff7280edaac087fef71fc3d9cb30395e383e3e1f493e09c9c1d54c57150be2465af842cc90cdfe0902594dcb147507c1363e14b211b7e877de68f6c6e97e6148b2450924039801542ccf00154ed24b2fc784394dcd863a458a6fb7d70d06f2481925be6460d2c8d6ed4269d7a26232323032483b07ddc5e0807ab90a6440e9dd5151a45c24da1cc7ba073135e6a25ec60e5871156244bec79186179e2076460fb7e21e4e946bf0f4a586b85524f7421a4c42a0b21177df9e0c30c3f65ae542aa5056afe9cd3e6ee19634384900516292c789440c9e894de4ed0afb3bfb88da8e4e189335c4f0f37f5873d43b264d742b621166554e4c37e81621cc9f4864ea6efa3335fa48db46152112f0ff3382f0ff3dbc3e01c9f0de3c0bc0c9cf30ff33932fee577a0e8f7cbe24d84250fdda4fcc252fa32ae6c8385f9977ff917d1ad103d0bf144c35d0a9106a3e4f0bd90a9101b9a858831f4ab7f408832e7062bdda51b2c776dba292a963c9a5c83953dd9cb77bfc513cc7738ccb0ecf980b53cfd71667bfa37ce784f5f099aa2e1a766e1a66928cc70d3277ada13038a41421f3ea35fe39d9227c9c36a2834cd3f4f4af2a424cfc85afa99bf54504cac0b8d5a485f5d9ebe0bc9a0695cf0d4018f2cd5276121cc8285f00a16ca744bc1e1664f7068e908879f495adf51d1461261203c8b3e7a21071efab2270bd97253102a24534ae52b530994e98bb48d524abfb889aeec7190fe77e5150ed2f7aeb422c650d9c3a70e9a46dea06bd0a73f32fd8ac3911699529945a6326f58f2c4182a573c3196ba87b931ca55c73de5566eeab0ff903cdcc4611f2f4fdf5bf42995397ece72906a9fd1f71eefe1260d3b8f83d4570ed2976fb04db7cddad1e81f04fb35f21518cca7f41ffc1c7efe1089196e92dfffd9db7b8b7276d6de3326c53fa55443951f8eb29b65347b8a7338eaef83239fe29ceda5cba79ff576737cbaf7b99938a751d3a7fbf8451c65c9da8bb36ded84e62e03ef5c05d80e163f581839e2079216f927bd59699771120cb6b74d8b7126eb689d9efc5cd4221251b8026dd54056bac1babb28c79f2eb7b03970c4192ecf57a2093735c983f345e2489cc9e394bcc9736f82737c4e3ee7e44b7e475747967b12ccd98f967b1cf234b93729b923d9065bf2263271e6fbf9078826d1cf3f4513c9cfa789271cb200910688ae31dffb307a91a77483cd7224e1bec671c8538a8781681aefe79388be1b821893829bf01e9ac6c361d7983f754ee2912dbbc1d21c6db4f76f080f42662e09251c9cef1f1032538c630c1bca945c19374d2532fdf9d9b50e4a37d899a3046ca678028dda64497eae1de9e2074020781a3232371a70930129135f7108cd26ec674814a2125512cffe27b3f144202c1f62893ec99d81124bf4bf1f322d55fa4a44557861dccd401239fb30276759fffcfc3871876601a5fdf31bd8c21d3a8862c86164f75003d927feaec9a8f4ecf296b1a2754acd8800020000a313003030100c0945c32191502cccc20f14000b95aa5276569ca75190520a19600c2132000002000000200c0090cc1863aa338515a1bc0c36c90a6f8ae4e501319aeef64517b4ef47e92b320ef8b63571c0dbc37e46fb1bf6c575d3abcc982f03619fda96405589fb80983c37463709fb51638a8c343e14a56116911464fa5123c807d63c70690b9e46ecb198861e7b6ff7c022b8bbdc0c2a291d9ade4eb7cc6191631a9ab841ec81997c7c199b97770c4ace54c15068d09b430b02482bd64a9c2e43bb70d719636321675b46e4b9003e8759ad4029307d271ad8e1d70f58fcec39bb65f4a6f7394907d35a894196134865f60791c89c09749918c04c32dbbd6e69e3bca578d88bd5303a9760d7f4ccaff6094be759637ee752c61c2b105b8c364af0593d108bc29bd9f41b8020ba8c2f62599de8447b289a699e9c12abb4901372cccb26a0335023923b50c3aaca4e6341605e291158d630fcf6d88103f48bb9857c519824a1d849f76e04e0e507afb848930838f01ba9c59c572b96f6896b0cc49180fcc40e6c73d169f07e4526840e32ab444f4f00a47bf1008f7515499f19ef1bb948a6a389c27eee02648ea4970e12a28b233df9e4fcdb6682b226a24d633cca1ba48cf5cb516aa8e4c3bf54ba81151a830b7121542e5089b8607c6049d1b39757213bbb43e2a29848c41a12318850a842f2ffe23302ef49652496a5b6a02744eb16841ec5c37cda13d49600a211d708118f3387ff567e281dffbc297befb7198c522c6407602d88497d809c97bf29846062455f53d545b243f581c19a0ef98c0b93bbbcaa679c521f2df2faabf3b95ce7750bc2d7bd7d7ed71012ae5065e4d069338ff8f8e59a3233fc2a752e0a85a43ac0d90b9dbf4868da5844f1583c9eb9588b93b53a2e29cc567a40191a0696d57c81d911b9dfd885eb304af03d602d00ac923f3d90c5d8f531fd8c89d3d58dcd1017e5a89d0138b53ac6fd94a70d1bced757c881fd47099948724cb3177364601e863ab3f7c7055cb90cd33a2b0559de0a23614f3e02de4abbee0e1af01cc99c1dd6295a6ae6caaa57b6f1d42901527a6f8eb232306e3d7fa02f19e89a27e5593e06eb1bc97c9006c21d235389056a478fb3a471b299ac430ebb31557708bb156dedfcac6d2b717723ab47a4361c30456aa1af2a87ae1bffe2502b91adf6af27db86edf26cf51f4409fa7430b889e54ffa99b17bd53016d1c4dff1629344940baa39d5c784c9f61b4c26104bc80885a180f574ed151ea315b04917049b6d62a8688bb9bece85e79cb6501a12b908ab765f4ecec096133e97f70807b5638a1895de45dae32e0857ad24a9e622fefa20e14ad901acab7fde918bda6f3ea21db950663397ed38eeaff325492e552842108ac73ff846359a16cf031c830e982fa11d4940e22950a909a4501d63ab9f873ed09fae0cf8239ba271ea6106e64ae91ee8752c7c8deec338ad2b6a955281f340ea2255810c5a91f7722062676ad39b24469b74f6983eaad574770e5dcf675651787d51737fb3c4297feab836b7903f91922e69a8891c87223526e514f98848ea7b3934b3ad439b9a502dcbf2b429d43f83b0b29b6607d1a89b52205a38453f0121109940af47240949bdaaed58eb1a23f3e77d449b58ef992883d7f56f68a739a20069582545d1636d27cfe9ea2b021c7f637ee17419934d02402666134e7b01c745caf89d134c99412fd4724dd5a415ce475fb54a04e488bcc13ad22161ae45a09b58ff163febe2b89482df8bc9e91f117317f470ff74b94baaf97a98aba2aa40d3586b4ac4ee8751fd3b1aa11c60f8147ce5cf5d8ed8c4f8640cf116aeeeca6feb86d9684b87633665198cd8ec2ef0673ff2c8baf2727cb211f9bbc58b3bb50f3f86b20584d1009e85345c91f31c4d03233d94c7cd4904eedc55faae393a95d719ab1e35ced9381534af933c036cbe411b1256682d7d2526dc6cc50b2066cd73d6d6f59ed694570cf6afb0bf6a04e9658e738e6648b8bf82dba15ff3092440c4c4895f7deb60313f8960d458b10c86f657367d0544a25f56c853de10f0c3f83b93104dc7e081036fc78d8985c9fb9553a67908413144f464e0655b5be49e4e6f760168088c9a6228700fe56876f67283b287ea27cf76b74e33cc377469307c2a754956a811c75a45bed2e0cfd194524e36235f46f7df4faed4bd8ad75604b398bc6062c01ce6531d4bf81fe496e995327a1c2c376cb975932be42b653220df4b07f37089ff7314dd99a61e8cb808a2e4f1989f7da3c471f53b98e0071016d5cef1377765e93eb22239aad3b45ad7b5b0706dc83367732e93a8eed68d541f068ed5839996ea4857900355f3c1c3bda39ac8a51a713a0d8126d5c53368938413c6622a6cbe7e45dbad80dadc0e816f901f44870c89fc6494f0412d9a3e00fce96b43e6ee8893196e9df3f290a4fc0b087bc39079855ae7edc8fdaf723b8af5f7c09e72a92413e6926a6220f3be521fcc101d81abb66c97b242b41a413488b3c9c0f8ce61a8a6ea0e79f1027204b671c11f6bb39c0ca2ae6033d307d0a1c1ed69082ff1b3366a58fc820c84f4ef31968c85c07b4ae1fbdf34b0f8ee3dfa5d618965df1b2083290550553d69a836552487505b522a08de1a645212f3d16fa685bff7ac018a523448f699fb9f4940cd773f804db371278f486201ff5822d5e03c6a074c893b95f15ebaca11246e0d2b9c818949dab794de1c625083beedb9091cdcea1ef86c3765e68984a4b573b6c07ecc10fef805f8f78bfea295c6e736faeb1e9aa942f16fe61ee9093dd34bf4869e757fae85797977ba8947a00c6f4283fb29a7e4da3d2a93756d0007d368c34934104ca10847de63e3be49b10caec3e82305f3f143c4c73b325e3d794f4ed023f286ea46d52f41e1014400b35078c138e614ee673e6f316f0ba1ae66ea69cf33f6dafe3dcc67264b5b7b79bed35b772074deb56e1f571ee1f6446450a639af341738e29fc3eaf52b490a4a2523f5111f62d2507ccb89e8434f45357022c0ac71fc5dbe2c21ed40746609245a08673c23e8ed8068aaaa82aaf1e54cea3545f1026785570ea611c014e5e4264857c5c32443b4c8486047274f0561252dbac11731efc6c7999c6186640541c4a9ff9e7d478c3ef6d28d31d4f28189e488dea88cfb7e8c7759d90b3761960841f5d2efa2f2b76fb4662cb4cf8b65f66ff7c9b586c4590abf86685d009edf6d57b7e01cf09bf293899defc7c651b65a7c42a7e8ac4386f5e0024b713af85d81aa6d9705084483e527d1a3aed48c39a9cdb501d8ee5019219fa1b0140361a413f27fb04c668f1a63619bd11911bb4d00b61b734051776721ec9460577a7331db7e363125696bdc72b0c4123e37a0379497ec855f053ac98a45f509802cecdd76b7f929c8d262e47b2df2f40863d7bc276c5a2c984c494cb394df73a47170f22f1050a4a1035fa9fe2ba4c138b143b3afb6c1250997725d96d0f5a660fb6c2fd9f74cc5c2baa1ddbada6f65c9d953dd46a1275d9fd24e1892e935e884e309d0109ad4d8efcb1432732324d67005a05b1476828f15ebad8ed66844279c5f8d9149b840bb05b376ed787ba0f7d51384e523c112ea074cedfaa95ea7a69a9f27eb6eec67ccf7b9bb87dc69c93a2529a9eceb052008963349a816b0e5abe63698f8427a4f8d7d83773bc0d2d40eb2f4b7fa3669522f2e4b1da813b757a70f69fe5c1c5439bc07aa2b36badfe26e2b21fc6ddffe3769462284635dce1d8435d95531995235c4834e38bd00f16c9cad09ed9323687185892b6cb94133256870547afca6c1071a6738d8297cecbf7a5e3b8564fe9695a0b117477f5f1e19eafcfe598250538dd6c4d9be005706bc2d5bb74855bc74cdaa593e3264a90833bf90157e90c480895a3f80c379a0a0596b6a7dd0189e42468663882dd0f03cc6791ff011197015143e5f44a78af884208ae6cc3a62886fd34c581ee5cd1bfbb4ff8c6046cf1bf62fef20a0a757e287e5eb76da7d3f8ba0cf0da0cece29566f3ebe154610bccb8aec4506bcb61732623b161a603134b42ff68c3bab282953459ec15a9b39547e01ee0c1b1302487b630c27bfce6d360fd310ac17c151c317ab14934898d088d151f7c9c491255cff988244387fd7517fa79d723f11c8e132a8112e92f70123618acbf17d2bb28c9770063122679dbaf6a68d561436a9496b09cdb1efb4bb8e86aa9d14467c0ac53b5d64e4d205a81b52b784373b5446a2c063976f95c826a35f6e3dcf2bd2a1f88e82e394dcf70a89bb9cb66a437e2b0215f52626450b58f0372cc95aa62de8239509d1007e8c9b38c0d38b86d59b2fd7840e245d0dcbc2db581e8199727958748f6969858ef58edbe41382a03dfc095068118943b83b405cc0845872650bad0141e24044e1e1213b9cb886f8194a4a42668c1e925ec8071e51533ed735769475493f7b0a09ef16a628daf7c3513d79385c07a5fa079bc80650e4c0648ec73792b9ddcf260554b38bc8e9831694fa802a7f4480ece099973120d877f50f2b0009e204c47f0269293b91e7bd01ff01bd2d05d354a0ef0ebd08357394e296f09965c310e6d40e6643223e1fc7add6c04e1ae92c2c9670c8180762e6102d852e11025ab2e1f15fdab56789df6e1e46384a6def54a5dcb0dddd1b7601029dedc60f0f05c39bfd851cc36c605fb646858b18a153b72422437c3400f8d2110ac118b1b5bbbe11874bf812fd4629dada1a3cb2e371abb471188f0f07c86408517de7032f7545e0cab1ea4af43ab637c2fc252890041524fb84047fb8942269dde4c8cae80456c7542efcc3f5f1a9b4d556966ed70ee36b67af2028edc4731c0776950a14a0085a0f5aec7433f327bb2e7d42d8a3c057e5910a53b525d47e973e2f3e14127ca41219c0f8858c0a67c61e0b90d2868f43b51cad2a48fc8b1d0950e4fc338cb50df71d49e21ffd9b0c361ea4b3777d55126b661878fa927ce50b8401fecbdf08be1328c079442c68e82f5f8dc00616ce84f4cf7b0bf6a0b004223c080ba777986fabffe3dcdef7e0f8d7cb07041f8c19f8e03ae150334fd55552ad7fe270e98219e2560d26439005c09ef67ff908163c99bc0c945c1b803c7b79083c36f4d73c08411ff4c0841b7941428ad8bdfeb0c68c01da84176fc5a6968149bc15575b9409dcf1c4631be667c4ed065811130db9ff35ba3b272b3dc176f49d51e1a3d0e564f85250ec8ac06a7713286bca2f2b3a760d2effb0d16088f2c1b7bde2776490c5ab9139ae6f1110181f3444ae284581ac8a54495fdd12625fd4a82437142439323b3eeaab9e3df29ee89a160a252cfe456179331f6318d941f448ea88ecc047561d95b71fcb203edbbf7f2c0ea0798cb72386c9f572fe354fed5083ffecf3514ef666c7125b1594f558dc3c49d30ad80e3f77bb269db216493e18f0465525ecd814e25631c5d321f425e46983a5c588845ea9310fd53644ac3bef392439695afc09a5efc11b16219d4e146980bffa478328874cfd17b90591540bf16e6b4c591d02c879382f4bf0e7476f581dea518fff5b5730738475d86c9b9c65822f7509030f25103d80d094aa7f2e8164d8e38c52f36cc3078eaa072219f38647f238db8c561b78317d7d43447fc0b051ea1e47e08543efb47d63fe18281cc339a8e5551a7abbc06f8e08e2edd58730ea60a3be7e3f92844facc4200577011c30e6159cd942debd334efd6dc3bc91f05583e879e639d4d3c43d0197d72b18ce46563a5f0c499776ad9051e06fd8359690942110827575651d831731a3495558ee9268e5f1877d837988d3c2f27eed5141c12d8ed0ab340c1fcf69d7dd3edcdfba10a919713dca70a114162dd959a8c7942b36940ff50f8cd53e7788806a5dfb3596212a855f2906c07c0997a56dcae2347b2a914e80aeea049045d3e1f3a8190b36a6f959f81f51141150633ef7bd1a606342c65f8643757fab4bc059f2447d8524620d8ace230f5c0f2f5612654454081f854c28894e8304440ddf9b5d6bc32dbb9f239c105be845134755af044c622b07cd59fddf51b82c533d9d42ad766b39b4330b01d26904f44e5d476954ef770b7021f47bd2ab9f47c6d4e38a68c19cacb2ca09eb079a4f9d3a9b0822d3bc3d19fb79670bf9dca80b9aeb9501b17b442318628cd041cd6a033105f45f69050909375ab1d6a6a981d9843b1c973daaa3ad38233fd0f0febda886f39989bb9ba9f009f4f42c4b23835c2bea4fcbd961ce0346f1d441950b9f19633e0b84a56599db192984d6736ed1a327dd167aee5c0940bf6a261409fe7e0d12945da3ae696130f629860366596017fb925ba2e7b4c3e08fff1664957da07dd998a6d7330aea71d1cfb6fa3a7a9d80f67eb4921bc9531302b3476c8281991952f382db29f82fd729dbc5d835bc4570a063dfff821c402cba4e99a43d3b2834b833a0317362dfb071791b49fd1121e3dce4053566ce8830fa0579c74d14d14364fe0a2d96b3b5f12c98ec1c8028e5bc9acc8caede22320411ca7c526e495c6481db3ebcab7836bbf9daf072ff5b4eec4c4e8fa0fa0d193d7060628d98c8190d19c0036f5841eedffd2fa25b92a318cd482a3ec711a4b7870f0c789ae36ab97070033943b081519764bbe3b7f233a7afd45a698a45633f45cfa2b36f551df695afb8992283193cea31c09c61c11c60ea0ac4d22d3546817db8004f45e98d859a9d5682ba5df6c993a62819c01d64068f783f481c41eaaf7d375e9ae3e213e0a3026cb003f007987d65e971b42fbb8aa74dc460893393fb8c3dc94f70c1c6bd5cf1b3b59c290f744b9bc5c79f795655d801c7506c094c18baaabb45edddfcd740c8d7a859030aaf85b08ced184c2f1e9fcd3405adf2d3fcc546c915abcfe8e75aa5e0da8525fc57cbb594af10168e9eb6d334fdcbce716b7319e262fee95db5981e162edb556350cc4280518e61904078279991c51096efb721284d2d2335488678ef56bf047cf5e13cde243e3ab1c1a6dc9f2ae5ea3fb5e5d9d7cbe9614124b7e643549eeb399b7db2ca381cb7a4f01524365ee5df88c96e9b575d85f856dbac768c151531a6151774ed1a4eb2287208d71368ae6ec8944ba2035ba55395932ed39eea094727be6b95a30e0105e6359f600023841390d0ce68726e771413e8a3b71c9fea621bd9006766569c4a2f16370e8f99e2b657e8195f937f198061bd2c17c79da0ea5eb7c1c835a00c73bd2e0c13c68ef9eb8409529c417c9a1faecc4752bd536f5bae21767b2153b87670106a5fc3aa05b1ac3eb3a9375e20f7370bfa73477c82b7832ab0f4813202322d8df959c2a4b43156f43dc8e21f80b2aa2976eb7da34e56e0294830916207e290f7b29f027457f6e38bf128fa5ae678321fc6448de5f068365407353830b95d61b579b3940888e3e6a6f06bc56ac89999e9350d0e98a22d70ff0b75bccc49838766ded5d41ed1630f05396a9f9ed326455b892777ae1d4c86f08aaf5ae7446d93da49a66fcf65509884a0c32e424f5123de9d9164024190d89dec6651c4261148fcccfcf2bffe2f120490d8287b50f8f9ddbfa2b5c91007abe11e9982f12a5ec29a309403c62da2a0a44ddebc8728e85d466bf2536af1cbc3f149fbeec07faad8e7468103a2d467fea4b4fe696a408fdee8905ab0581177c232f935c6b1044e16faeef7bd98227102773e295ee749d010e28fc360da053d7c9c166f9af8fe4e06cb50549e13e7960b87690eee1426c6f9ca8c1348fb680d2f63f8b9dc10a5cf19ba748dbb154ee847ed02a60fdb9c043ab9c0846017c88e100c88df9df38e44fc0d06d99104ef7cfdecca192955c524eee2d0cb24b2da89dc584546a77c92aaf0628401ddbe5d29afbcef0f6486b2e10206bd1790f51acf41cb89545e6190774bde43313267972bbb7dc8874fa7579a272ec35fbd99f66ed4962a185f13f74f6fd1137aa467f49cfbf4ce6ca1991db67a528de8d1d25a050fcc447aa0b96e020353decdb2d965b9eeaf156402a8878becb79c8cb896611cd1f26b1ca2406b51d5bfe72caf6847ab361d45e5201cd11786a319566eed3f218812481fe66d8c99c48f9b080e2e278b2462360b48dadefeeba17d6b0eefd16efbab3679448eb75dde1d7865d610ef16640ca18c02490d6965eb246f74fe69154810678c963adbd7dceae3e961f9bb37cdcdf15d1b50904ed2a9b61ff41207f5afbe0c311c934d73e89f4c4fc738d2cd3984e840336c9e165a14a4e927c1b0b849952df9cf8c896a70e0fc6042331bafb8990c19154e18d1391a5aa8721633bb2aa1564cd5cfe2c535dfff1a2cf26bc42f4c26dcf0bcf54b917ec02890e6d7ceac73ca610eb47591fb1361a8de26830f73c684c4497216c894a34926f52ff9fa87e20cbef1edb65b847f7221dc32b94f0452dbe31d2621409ed60191309fef5e42eb629075b3198278e9d9e3bce6f3700f283e3027157bb538ff7da3fb8ddbb298b2e1078c1ddaf78297e0a61aae3436ac3ee324d61145aab57d82d13e8af36e5524e3678c417f5f0ddbea5e56be48e97b53b67f9dc8f477025d48c3d4f19a99c6764d1ccb4b1221071294e16b0b4137624fb7a4e6741fa5f5135a15c267c884af5878a7912c1983e197ccb0e4ac4e1f244715b881e2dc39ba1fe2dbfee418446d9ae641970b5356ba1a1f0a3df9242ab70f702c6ee95747f0f617a368cab4c38197e49ff248bd24547a445582945d8c1dc8dd5642d992e92c48b2f1261f432a7dedb7f49a5a3682f312b1e5c2c7f0bb9a6af34f42cdb61a7a5d56b6f9e912e48343c1421e6b821fb25290063d384ad636e63f18c4c3b1f184424138d75c63f4f5f00bc08c0c0db2626e5d18aa84041b4f17101d76e9f8e9d91863c1e9a2cb80a0519a81dd2bf6ac4e597ffc6f01b4d70e59c99d7c94179ce14339b0221221557d23f5d1617e9c75a1c867452c81a611649d0cb6290ae443185aef15b3cd4374aec01c6e41f9bbdc370b44f879300b649bce07e8016de28b65c6fc15b8ce3581a1414705622c9244ca245c236289bcd543b11129fe32202a653c93286332564dca131ed45fd5f295d71e4f9d0994a0285458e91a506afb9d89f7dbdb0834c458ffa7f218fde4fc8d5fec2c0519b1cefff41e522707fd8c2d2d3a46c3aebea5bd77fe9f873f1c61268b8b58491396a260c0f799c79667533f15ee9c45a0ada4b9aba2d5bb1ea0c3af431060190a6c35e94759731291dafce2a2204f307683ad0372a70b940f702baa7559e3f61fba14f2092f0c06d15fbf3d5dc620f12b69228a5c916496183e85703e7178e6647d83afd36100fe69d44dc730f27a897ddd84fe55bbf3f12ef74ebda904c7d70431c43d22da8a5b72c5b15d97e445b405bf2527bc1a6c112e6a930e44bbcb850d74b546ba33c98b672b3f498c607b4f25bf50287e665de999af78d0be11c21352051b4911f098f2addb103bf29c95b4705c615d808fd44991e33afa10dcbc6e88418de5e8c5b7ca36cf7c0b325f248f87212e30c6ddfd4e68ab0420a5485276c2587fe75c545a5f6c516ec7af3a0ce4350d8f9cff84313f75f8611cb4a41b46435a804ae05217b42cde35262429e65959ba63d9eaa24c4ef704519a41ee8c432c2585cb301f6cc26d206c2936caa3b23aad17e4387f6b7b2a30a6abea8462680e81ca1f92f49e66e655d54edf38fb9e2dfa954fde20c410f749935d3a423a2257c13d2901527e12c5817910d7844ec6504af725de86828190ed5815d6607f29dd50701f1e62f228737998e1ecd13a10c11dd02db8d148b0421405f5b85c563d30a5f2478627a75ecac6bb15eb147edf2f005fdcecdfc2cd62fb112601869ca3ca7f77d8e0da5a140cd979e2756251b5259aa077414727aa279962d36f9d5f70771b6e286975db9a7d814be57ac0c82193b47853937c78fe1e33057798eb1176e87b6418faac22ccbd4ea197c5b88cebb34b30bca863d10e33abde971798fc0a723ed022e286181bb198bec30bac3c1c23bcd8c126f24aefa0fcbae8152eea75e81eb5eda6885bdf51dab816ec529d8f2fd0defc5c1550bc721f0aa9f38e52f7648501e5d36db5f56c1c02047deb92988bbb93dbebf3f00dc19977490a1af9cd91431bff3f20626de6c0eb875fdd8034d510e0887ad7bd8bd9080887b5c36637b32a3b8c32e4d1605654237037caddff22de567c1abb30daa3fd5dd72bae98ea67fce74d37aa7f4ab799708b7a63780ef5d53f072e74c519865ed06f7b94297383ffa14587e8404550193a728645f88b62ecf9da636bb8e10aa7ff7debae25827ab33d0cf27a86c178330510938de47898978f51002e5cf0d070af4707233f9bb88fde9cf141064a9232b9a6706a6220441054df10fac09525d8ef2e4012e6039dcc38794e691a228a662b0a60565951196e6498765a068654f299ea2b0d246606531170b0b2e6b02364193a2a880bca844cc205a51106e5f78054903c971d70c83ff20c6bdc9ae60c8c64b6f3807cd4f93e3692924e6a6996ca90e421b356ed019b06220f5f40dc4ec4725a489c5fe66965e6893c38a284e72ab84363e3af31e4b6bc12bf63e12e1f996872053983dc00b459f90f36ff8e94b7fce6992f610fd8f587064d9ce5970dc82bf364a2a7ec924c64f9c96009b17ea6198920ab9176fb0d6684288bc54f3dc3989ed174941f656290fd82b69905b1b92528ae0a89787868702ed867ae358ec6f83a01df8da37dab0851d7a96e554f6d84f17a9334388a528b23e6985741b21bcb8cb7b09526bb77bb72a394d9713e11246092226fa2f90065a56c6888c46bf61f62ad29fc2a807a9bdb404071baa61295ae7d371807183823b3eaaf3e4bd3a3ac3f279edf2902e40ecdd4af93529f6663a5aff15594ce6e64fe8f2f6d90fed0c8dfd7f5f9513570ead524892ee6283865ef61d581e3529b16a1f6a3c65d079905008d6895e57f5ac27bcc4eba3a32b6fb602a97188707f332e72cc10fb1b663d74f5b14a335adc152028f492f44dd9317000bf6a4f6dde78f82f2c227fbb507e9fe1606d46c8db977142a6a35fdab8a1f7251584b9cc881a55e40d380c28a74e24921f0414e307ff249d4dc97cdd8ebd65c07f0e75dc09f8bc06188c58fa13b8c7021bcaac184e0817a7c6b622a07aa1a3d1840790cb5165ceab364ac00bc92d1513a3004550ec3698f7d9d0c5035b5933f1bf945b274e88b04830f5c10132c93c00820efb272fd045141d6c516603ce28e379d4ca3e5c6fbb70ae0436d7efd8f62eb2d837523879bd0695d726ed2461f1497952d4ab15e51fabbab214a57f14b9a12fab4979c95ae62ebf06336350ea8acda210f5b840644e61cad7044f4a583efc934b4e73928308c260ab8b46295c89975ad702caceda260ef00c7b229c6980dd4425ce6a3188fd6c394f39da595717c08655b86653363e7dc908e1f1c882016d2cd4b6e0286ee0bd505a14cb7d6cef5ca42d7d42a02a9c0a864d5b5c627261d626cbb372d9d71967028bd5d1506138bfc8ab2248d2678c21d758a66911cc0218373701f2f99ca50adaa68fc9d5e387d7021f13db9a651b956af26adf137c01efde8a2bbf3f29eee125243405be94b5debc9b805b9cd58228c78bd4e6c8de1dda5096dbb1a2ca3f07d576ae27afc91b06d34ad27e91c0a03efb88ed312e21a1522fcce6d962ff309e2cff6b348beda2cc46cbba0e77a400bab9cb69a6499e8e9c7edcc76910848ebd75f31aed53459e4f7ad298dd4e3a38779d0a69a188c886a0a403f8f38e186c80ad7d57e4126cf8ebd7f35d105266cf39d2544a0c5e24ab52310250b18e725ee8c481157732a9d515fbf9bcd0a4c423690956204506f87c48895f13529794b6fd24025e66ab63e56a7a2164309cf269319632734c31e198cd025250e5c051aea82e87bb381ef3d9d045358143161e27cefdde3885c9e14f4ca26c19330cd6fd574379d26264c2f0b1187b28238acc142c0d06ede4858b2e1c838be6d16b99781c8a5bd17809e936850fa6f253eab412488b6d2e6cd64b4d1a064369611c3951b5975d1ae15802e59e06370d96409694431e50df564383d6150c2b7c774af1989a1fcf4b53f5813ce648d05bb301fb1f3a888a50cc76617dffc1375dbbb0ad13405e82960c93cde15c61aa4009a8d16520bd47b0be921df1b7528a0342b8495f41b8387023ff6a79b6783550ce256b459211b14c024f18127570496916e41f5e0473809c97d5a3aeb13b5ababc9a9b613fb6ef672212f86181aeb015f47851194078262a8a75324935cd23cd6ca8d5aca7f31c2e85ac8347e30c79c777471d9b8144740b188454fc65fcae64d39564a95f8a471c0315c00506fee6358fd68147af77714a7c2848ba2461e450dca421e3aee8083067132beed3182a4b81459b52c99cba7fa9f8e43d84410f69afca9160e140e97124e8e423304e5e7e2b7ac904be9959935d8b5c06ff5b8e911c7910e1459610b4a2ecac31594972454a4d85c40b12ba679599dc67b46f898ce52f73617044a2a997636a76191ea3389d92b7442460bd706fdeff874a6c433c2764ad227d5e0d47664739b45589594302bc92d2e7dad902e93e6e8f1a4e7ffab35680dd6d0ddd5c3624c8f7c317d30f5e42a9b765cd2bdb8dae22ea289e586d2a157e46e66e00597878254f71d141ad3e8b2cb23d423542b6ba89983876bd66e0565326b2c317c79f7ebbc84125130eabe8ac714e81599b485d1a0c884e3a13b1e4ee35334ac8e0f0d81b495690a45cd67d5fca0554c234ebcb861da3c29112728184c17f0ddfe5da5f16d071c2b1b66e082860d6a12a07ebeb896c90e68c452bbc54fc3348cb447dac7975e868a7d6e88da8662137a6d41c78ebfd2d9c76f67a58272f8f1fe6d2772764a6ba0eba88f36a64bbd03d7491e507f62166cd54a0f7bd13a09cfbdaf5bb227d4757c833e3421d02e946cf71445b4b29cf180a262c287e93f85e982072768f7cf286630ef87ff96c6b2035b00fd1da6633326e6c751bb1d20e8e14c82bf085f9f4e34cbc885a853f2aa7f08186d265e73e11b33d25ce9f43de296ff842ee58ad57ef92f7dd6b312d130b2b92aff7d61ca927a30fb6326c0e5796119d6956ea34ed3ee35d27d92223e0c6befce4d3385201aeb40543dbea91e02ce2a02a6f0fc3e3d36721107f1504272d44314559eadc9546aeeaba2e384a91cfa194cb021248c96bb1037d33c762c3be4805d3c9ad3796fc93579867d2e6868ed1fc6435e1639521ab01e0ed63048a11fbc11820c1c8911d8854d122405da585db38bd38a81226ea8d2179a764048d5d46b07ffeaf445ea2424fe396c53f07be5543dd74539695d160dbded1d9441b53f523ea7e871894b9c7bea886c7dcc8993ae0c94ca8ff36fceeafc323285745a8dde107208e7e58116193cdd947e74b580f28a90b81311d845be2c8283f29d834f3df24f610ef0815ab2bc8e272c5b95836f61345bc66bc5b05b4216815ad7c0fab2c509c94b71218e8f4b61e132e3d9643a918ea267f7220e92339f43792eccf7f943d17bdc3b789ee80568c991b3d2588c37720a9365061d6bfb31ff3b84de90e4b75eb587e8215befdee8f67eefdc4624392470a93a8c040f6bc1ed3c68b15ff0176b03d595f131f2e607166598cc440912c7428b166f92ada223b96dfb7ce9a5cb32a1c6ed12b7bd3b586dae5c03373f41e6a065b3b6b1b9ac4402739a1e6da8cfdeec07cb118cc05c2fe60c146eb61506a0ebda51f3b6c72f059debb0d232fc71165467ac0aba73a54d773ec9fed7af042ee9e0414116b07d29e6cbaa1c43249aa4315f31a9f385e0c1e428129180f130f2886ea2267939046c321f09db5cb538391adaf9061e3d2c22f89bcbe62704696b9676d58c7cc354f39d339613140d3b420fe1a21dbdf23c43dcff8400c0c77522908a13242a362fdddbe917c9807ec95c82745a26f06abbd38ab6f8da8d3a4c30d391e9b64f6e0d935d1bfb20a33e930f15742546747b17b7b8300903611db846cc1deef45feb720578f3bcc1345a69d64cfc091551bf3487f654283f34096a86340b9185c4336878ff03100c508438499608bf4093cf623e14cd5bb52f020de4ce75c9e967e7efa24b065dcd965617badb2c6e6cbb97e53bf67ed88fdda4b5eb3c628219460af6eeba273ce61c4c97177c13a039081e3795e8a44b316c349d184e5627e713cb87a16d3ea8ff5dc3162849d7be3dae0ea7ff209c3e9e974ed4e426c0fe4d012c8ce01701bf762f8afd3f63fdc4541bb0c648db8f191c124219ae5a9562b115eee273b4eac8c5edd2c4098e025e46924fcefcb18dbaea77db5c3eaaa70c45896b80524e0d25100f91ba01d71d10426d44155d1586672184e1cfdf8e31b6f14aee411d7436436940b28b13af1a0a29ad4a7a68fba9680c765aa4a4b7968e176ff03224a048008f4f4768376a51d78fa6962c49ca074e2d63806f8e3ec55f8551707d3b86ac347ac646210f1d448ce9a67a435373302a5a62a151603c16bbf181d074257eebbddb6e396e02cf59bcda164370f2b69cb6190fe0a36d63c0d0d0f3a6cade52af3f7cb28bac49246bc868956c2bda458a865258061c22c260ec21543222528b490c74ab22aec918d2300f19089aec5230a30c7b06be92ca12cd1f91e836e4087323a34c7c72a8f3c2e9154c0b507ea8cabf7881fd7da9fe812eafe513966c1563ab59f908eff2f752b372d650840fab70c08831da301a16b186ce0a7bf8b49bdd2588ebfc43efff48a18dc72a063c64d1818bf95bc7f4cf22e30a388a10c5711ff2e1811ff0386c49d608e8e93d2fce12023bc48ef72db68f80925d365a487cc17906e8cb81ae3d3317e5aa6a6b0a1094383ce7056dc24c6832a3f20ba2f3e1912104c69e7e89562aca0ec7d8c55bec3910de074e256e7f973d8cd36fb7eebf03887ae848a782e96097e1ca80dfa1f268aeef324f606875a82ec13b259516888bbe365104e5fa3a020c80a080fc00844071cd46bf5b03b420282bcec3bbc1d661f603bae13753e2cb51d4de0ba8919a1a7358d87fd92f628272ac375cae4e9f37bc171031b4fb33f104b1778320ff761ec97782d916aaf9a23e864fb80cb2740405032988d06c97169e67e7d6c993c090a873b2508be6eddb3c4c54f3453be7e2e4b06186507f0051e8baf51617ec82936961d87c0bdbd8f890942e3cc6a0ce8c523db9a624e83be99cef94e6bf23c1ccf07507785c0ede6bce928bf5008071900c189eed3033c0787e271c1cc38938c9e26550a0b1315735dccb872f55bba136dcb887b1af589a0b947ef77d0fed0be120ed8c0f05123b285fd216e35edfc53e77e82dc7d8d13662430bc05106c9867d3b8834d1080013cd989ea7ce3fd1174eda74386bd26f96c45895bcc5c67ce797c6e87b92dc918345a3cfe48a11908c01ab39f9ae45dc271f25b5706eaae8cb826d0fd61979f94e319acb3cfcada83c71033ff3e69e23114185b279a604661508b9b2015a523e3dbe041fea848c89153ba94ff7762d553432f2e21d9b28bbd3eb9bff48e606b8ff2e505b5a11507e70de3ec984a7b36eba73834db7937de23b564ebfc98a66d2dd2816a55f8c3e188093090beb9055ff22f08abb62de4d43aeff781b84737c83da7452500a322d7945a5eb3b4bc43d113d659bbb11d27921006c74c679cb5fd6969a3823a1f66a23575ac288ed78aa561702e3fb5a28183c4681c936ba1c3271124f11a41c3d15ba38ef1a9905d0085c07a59562afa99a035c315ff9181978df1e26b6add9f84ff5bd4f55bfd57a31e374aee4136d9c5c45534bfd410b03ecb3e1e3afcc49f5c836fd32cad51aab087361685e9ec0a5f1089671c9bbc9f5d89ce925b8bd1c253045bfaae80860bd9389e44b4f82c289a8ae31809504839b8a69ca9df6b8a04d151b24fb4f041d8447d56f362ded1220ed304c56b0a93556dd40d1ac4d5c625fcf8ac0d2da20592d4cb8148e0a3143b2a1573b9322a8aa9702fd4ac0e850e5a58dcb3411d249f259c047d6cbb6de9da6243bd3d8883ee721401ef4b92dfbae31369e86f94acb3cf842c41e44bc9ce1b710891bdf8d5c344fa3db8be88ddaed328efa6cacc6ab276bbf601a5eae953858fa227218f9156e2fe8e77d79026c3c847330c2c65a3da27dbe2d3a1e81ae6301085536a1aa40f232dd4ad5af3d9686fbc7bfda2964d9a90a42da4ae779c3d36db1d66bc5eb94f3f30416d551ca01ef380c31035050e625ab8260a64c6430ea64e3d3b6d5fc820efdf7a23ba1f47e4e72040dddc52a6875be44d7b984175da76540be6f336e5970ea755b2f73d77d8e204fde9d6be027d8b4fd632fbaea214ad30a019244797c66611ad3bc119d70e1b091a8d7243ddcc90efe308913f383802a390aecb74fa3f2179f00306034ccecaf5f90de43aa0b213093e8f0805d913d6ec82c58c8a1152c405b392c18935a57668cba476dabdb08fc1ee313326447d12268d11b98f90ed744169410e62fb0f2d90442c58789bef57816e973560954762072ee73913b03d9ec3aaf41ce83eed9205e4cfff6079ba4d768921ed5b20e4ba985abb7e86868bb05b10b22217bc53214407838c5ec27f66f8dfcef2a8beee2a22b067ea728535985ef50d6511994d305901311abe94ffd62019862e4b5b72031e87c1a85782f8dec89605335b02146a582a478656ec7b2c8877ba6043a0b8f44478ff15eeb3bf2226a7a092a13ac1633852c5ec554922c00c806ef22536d0e0458288a30d057924f21f70f4edd3c1992d111d96218a794e9736a26ff829e5d4b3a53231c4c715768d282d150ad894e60fe8585b4378c81ed0791046cdfcdc63d70a634352ad8f923749edb4a7e7c9bd813354f38736ce625b542a475071e35933530aeccd85456824804cf6379e230a910ad62e70a641f829de437d43740f3e70c1fc7e10b5c24f437d8de130ad592836e35dc813081d978b4b7e18c10b2bbdea7a82d1301a5df40cbe62d3aa0d0ee3c461c0bf418c1d8351df322def2a4fbb3e0e9a09be983f9894e0c6bfd6ece7210076c338bad7cb539fa236a9df40599b505b5480b0f50534f66e5eb679531440f3cb82edec2ed966b059e12e1929493c56eddc30f4ea203e193aece6a8e5c9280db61502b09e73576ccd5815a0ad205e67c73f50b9d769c2daf34e7b8c2daa9d381cfd506dd5c834866ad32a7844b949718ea2faf78c18f135b6405700a4896f99fc75acc180fd96242869ce51c3002ed8bd1c52a9c406baad1cd297271114e68a7e8f0cf841d0eaaaaa025715ab2c8f27b222bc2db6ccc43c82beac56c553ef822c7c19fd83d6a00b8009f8e6edb59fc8bf8bab5a306d77162ce4e2dbec6f359dee89cf88a3a207301dfb901a5659bb1ebb63492c7fdd80af1263cd93550c74b8ec3db0aa7161ad6f756b6cc1df1f2a35fa81ec02f30bf7260ffe4f40a1efdc2f8f825393061fc500f9e025d13dd12eaf42c44eb5dc7b15d27e7dd47f16ccd69a8a711cc504afc259fd8b53603e42c69530001e5ecb246afac5fe7cfa11237ecde00217c82af9e8e579f47bb386533f7dd0581013f6942b9121bea6a011c9edd1cb352c38cd63233b3a09246f15385acd914574f929acfba284660a78c8d8b93d37b6b65905baf5f76fd1de9d7804629951c86e314b02b37f78f0d1c63fafe0b2ae8131d9335910b65148932d0124754dc34a608bd291ba682f17603db7f9d4cefc5a1788f632006246124fd6e94fbc3e6e345863a5bba25fe8a274f1b6aae0909baead5e5169b836dd850384c7cf4d2722920be0c53004897a39b46d58a0abc08448a63c81c6543f42e90987536ddc33bc6c1d20956085ed7b1bd1135ec043b7e08a1c9e2920546d209be703ed0d9938b91cc309a2254dc1c7894e420f73b6bd17458e0b8b43913a3837a33b105ec3097bf3f581708a0c240e8f73b5e067e552cb0bc59b38fb5a4b15d4f44d1a65b14213a1db2f7742ccc863bd6383274bc8764a3723843000996e990c39db5c93de89f081559ef074bc36e9598493365447a4f394a3a6a625cd065c87ae44a866c4caf114e32a4143322c0b419dea69d13b01502a40e7efd28f455b078f2904c1ccd01a8b3006a47001c7c992093d038dfdfeeee4c43ca78b283d5736d89ce02938169933ce2b454a1fa7cc9ab637b9fd8eb523d43bef4c709fbaac77df7112e7809fc95a7062ad3d5aa7fdc597ff49ff1ba7616521e55de705cd032e2991f285249152b57ffb0bb686e34774219aae511b8ab8ad6662f4d268928b171e503afe08e1011457cfbb66e54e577a8802fc97ddae100253840d6b725e3e69d68887b450ceee65c6b5ae1e39a449275204ca66a5e86c2ca7f295a90854c5511c7a02b36bfb2f4f102570771c18c20ea2feb59fd05b4c77ea1b124093cd75419b8d25a44afbfe830331ae8d78ae51230445baf110999a4d86fbbaf07cd646b8a9ea5605198c03f133a7584e345569f89da33668744178cecdc64b956cc4711dc828223f8f9c0c8ef2ae307990e702aea3c8a05defc4c649380865bcfc6972561ea4fd78a07e0e3b0d007cb3505518656feecca2b8ad5eef77ac24df641c1ec821c21999e37bafb8a1cba6327416f69444769c46adb67573842a6c579af6b96c1a3651b41d4201ce19355d64c63373f7ec0288e714c24bcda613527f48fa586e2526282f20d65d42e8c76541b06835629b44ed6e4a8f845212835b78cc0765daa5416b2247f124d8062a01eaf8a10a8c7133dc697da9647da88e51b0bc1d33e391f422fc7caef83de8cacc948492d41692b65691a462f46bf2944a6408242f88bca02925f3c3ebcca6ade14d5fbfd96b7e6748e730ebbd3bbfce7e46a62f9f70a72a6d62433e2ec22a480d5b5ed915df4080c5b02ec6b666e24b312e7ac91f318548ad9961e19d4c7df0413ec932f6653c18faae0744e40b14c591d5272576ca9958b53b998129a858303ba8031c51dfa0f5aa5ab32635005a6e06e736c7cad8b786214b7645c17962d6005e1f093c06162dd25282f6dca5661111c9201ff7fbbb552ac586288696755fa4138fa36e5ac838e03b5e8271621d19938159795acc32aa27a4ac58b46eb0b3c0a61814fda06d67757e0b1b27de29e17a8a3791af9fa140d1304fb9c75093335b8c47492dfe6ce069d0ed275fea4097c348dd68de07924141df68b020668e649047ed1081488346605defa3d437f57321593b03dc47d6191574a413cacb5920a4ec3ad5098efd9af5b6d0da6bc715b77f4fa28ad00bc4bc2176486686f081a75f9f1a94b63bc8da979f5d4d59be1805c95aefb1295a22b696430be06196c19ea07cd4243d011ebf14b4dd671243163679187bbd869d38e086a2f2131d2b342a4678e2e8f5e49c4c13e16de130d2b7b5d380a59a3000cf2c3d593da947f011a6a82b3f2b2e669cc763419f5cc9cbc65bf7a6bec2f93a631e7ef0ec3b92be0a9f3a4f54e0036ea7f4d5b7d36a6336e09917a64325f4467b267e978aadd1fdc85e58d412435b85b666ea54494f8a6344125301b5be34782b1c7fb5c5606fb6e58640e8aeff878a9e80282332077e60ae9680fb58f319b9a2ee077eacaaf45dabd10f5b8ced691126ce70d02c3930beb912c7cfa305f13a2d3082dd5437981167bb4a1de1343e8cef1204422243f37814d2304d378c001c0dd4c5060b2a201f1ee5afc26030aac7ed2f570e48ea1860365c5f40e5f70a7be94ccd85e429d663b919c0b053dfae2507b27f85453802108040026e751f8f8216a31bb7d71c12bdc89910aa849565d2a1baf8756fb50de2955d0dd476b66420b8c8dd16045fee35bca3cd7d3694e8967dc868ad35d345f3b5032660c346faa62b32e3fc3d34374470001f956a7df98f01d2f261e2fb4c0048e098b5ad043b7e69177f6101ea36433e061a712126a0265c01d411e6378d20f80ca561133025a294a7cd2175ff70e91597d11b4d05ae2d2ba2cefa94cfbfcad8122449d05d8f68dc66004ba207bd662264cda9a117a54f16379358c293654690fac76e8e96eaab7229f1a0c16c950d0a3bab0984144ef79cbbaa214981094cdbc2160936d80abec4f114bc95240bcc3b6084cd34c56d9a470bc8f65f260cbc3c8ce6401e3e3ca0e387d85c490f5469b8290738009e87d6beaffa4425c43e05625ca6a0936311e43817a5f83bb303dced582b4d5490cd4659d6dcd1180fc332bc59379b650177aeba1a14e233a38bc3321031c8526e6eb74219374212be6a3652e59b5a865e64d83afb9532b7b8c5dd7f60c3b2d9deb7ac16e5292a8269971c4f559ce40d1b4756a7384a3006210689dee2bfa4a60fdbaaa8d3e3e6fb68ac2faae244469e4ea67b308f45d07af097c9c4de81957c1d1da8df445cedaef44767e5ad443121e11f03f2f220d78323d7aeb3373a188a0ff7315ccb002ef85c4fc6c29ace3ef8c6c334c49f8208f7dd4a0516d452da02aa92aa58970bcdda876229badfb6e8828dfd4942ce4987a758a1f8b8549a0f6e90c67384a44968414254d9cb1a9936d42324dc1ae3dfbfc3e874f68c36dc91c8105d1ad2e8cbbdaea815b6e3a5ad963332dd2554003b28f17fdb8acc2b2100126ae77ddb794af8633d6e75d43111cc46715d17277a769d1e79e116aa511d807acc2ae1ae5801d6afe6c230b003692bb3d25dc36686b42327d51a9c75a10a35402e487d6c8281a608aa639af25e475852e0219e01124f2f8638fc9c41d607e16766d574d6b145fdf8e79b43a64f6358296b2b37e6815bae1182938d2ddd115bf12e4f231f25915be83c9e6aac87e35b157c2ea50eebc72c102ae80edd7343c69c02b3b298eb2321c6f2ca5b8fec834e81e832c2f91ec9a1309c160565be4b22f50ddb84df6d967d525d2b97dd67e144ce40956adb452cbbdbd5443cc8bfe2df898403069e1331c15e5065165d3b78cb8c51a74f272e0d4903a657c185120297da7e9557f5c0c435b8c72ca0cbf65ee52c621dfabf615c673b6aa5593a3467ff9fef712b17e669c5f9ddfbb245bcb8e8b4497c95e25fbaa6519b3ab399f4524807a808a00af0442ca2f921aef4277144a006843dcc68615c21ceb83cc669c333d045f93b0f8068bf5adf153b85ac1a33aeb0ecd77f14c108aa5dc4960e18bd503202ff651182c266ff92c44b340947be1eddfd1371b57e62ca01605ddc2946b5676132a5fa05bc16b48a3a24a12b8f3b1bfcf2d55aded75e4270be03d7a44c6a9377fefff5ad5dec0309d551ab2c44d3e9e39881a17c7fcbc4cda16cf9d0f95adf8dda69c267afc9c28edca3603683f6a87ba3094a1b687d1b3859bc12bf0702c54a18dc5a6f96be5c38b4d3fc94d3e429854a8de08d3af3b71284d90fa29d526bc290a872c4edc082c7fba29f3d9b3b6a109c5563e721590ff924ed3175eb14c3eb632fe5481ffca5ec0069a1d548d589ad2f7a4f36fa292f4afdf4b9fd264acf0208a328284ee9e7b36f9ccb16521054d2991029a8742a4296043677c9ae45e6ed0d2d487a5af30979b6967cbaedfb3f87a424661d40cf44542063ee07ebfe4388a0b917d87f5d6c9e27990336b0b3c9273cac06d96c1ce83f304718d00b85ca54009ff2ae76f719a1bc8147b273092d4fd91722e3f896b28deeb308eb249013b00e5543397c88d0167372bd46ee349c5755061981005f3eda7e333b0a865de2cbe993cdc283dabc3a0e892ae352f709296e2e2e3e4d05b947640fac07a8521857912f07d13b1251060f310e14d0ea004706b86d6e20f7c905890128fc3260fdcaa875b659d105a42e3d37d9e947377c80fdf016a11bdc83af9bb3196ae1dda65b24edad9ad00878155986dcf34c8fc40983a1bd7a4a07351e4173f925a494bf13dc16253700d3e3531b74499029e12a81f19b0c1ea0873b304b5c15223bd83d962d1828dfe0fff46065c6861b96746c8f0d9a93c65fde4e314e4c7980531018f8a3b8cba7337e9c4f3d5925406c800b68e6a979d61a2addb4c9e6ca05e62e4ecb905cee00992b5c09c194113846163f06517145f13fef75d8b5e0b68b5753965b79347d66493996c7982789a4e399d40744c6d568bd474ee0952d6532c4406c322a0b8753d6834f7d444a1b3511d9d486c3b2a2c2f25a2355d5f34afca8f25bbc80af379a03517de11f6c6434219e136ae7de4f1523c3b8ee99374405989061a3028d8cdcd7261616cc698323736cd7f15e1c265e02c180c70b43af7e8dc4ceb57cd855acb4bea95ae2c8faf372b8801f4836109423a2719c9f6674f5f5d8d604787ca9e0a399f4387212ccc25812da5d8c73e4929e4ceeae030e6823d0f4321344f7c816f0b5037705dd013a3dad9f5b4b8103a2b10fa3c2c10edde444df1d88a9ba843171685a9d1eac50128f94528b4538a5ce17336af1cbea1a7e36d8f07387a5bc3d3f9ecc8479507f27a8534a6c38036a52165f5614b2bbbe4502b095599cf39e9955fad699c78b91c1e5ccd36f35cefdada61e70a951cdbb430be7c78d4c254efc26ffd8ad40a4131144c2cd804014a1cb4fb608adf1b30636986a27678b57451532ac227c84f3b074307d3cb23a75999fa4cf503ca440887d08246affb076eccd88437b3847793a420be8d7c7f30f74d059a43a767e8636bfb5eae8e213ae1cae4eb1b3856776432369a2c0e809133412fc332c76405695c4a7f2fd947cf4c8ed60e55b9e4c9aa1651c98b708312f66911c09b1c4ab01f87e99f8b87115148062c86b31859b485fcaa121df9900a518ed116814d262a49c9cce5de145047cc7db97cb4e65e47f9ba6cf49869144cd1063fd563b45850c778a743ec2bcb986a3010446a024dc9c8f4783d69b2df83581b50726aa5222412359b15855da0b0a965ea283a5abb90534bef3a5719f5b2a147189482f27071a01fda7d2b1c08d825f398ce1e332a834d19f8f723a5d984fc288122a401b83c76f12a2f130335b2b5c989c113e7cda0c3084bc2954580fda07ef2b8c200eccb1e47e3b7ac43b6f118da5d85900be0ab66cf3d0ce18dc56282feb01436315f6b9cb5b9c92a5306959b9137af43f1c85e8075447a2d22d478b18bb785e7bed8e6a3ed0805ce212b50f77082f672b761e4b1191118791d85bb21a5dbdea87e8c82ec09c41d75f72c74f5a72891f285716354b87cd2c0579602981567a4f525795cb2417fa964c26cd075bd341022bcf5a1e731a3bf687e7392d02300a3123ff0e01302d4fb053f274a62d07b54f3abc13487d68507c54be65dc04c8cc9061931389571534ebc1c1955f4d88a3483e42837095e14875ae93d45acd11d21b0fc079e4b1bd97a8d73981f0c7402beb88ba7bb0008c3d621575a09a8bcbe91ad1f70b7bc0546481abf0ac5f3195dcda0383d4a7073432ff58757ad4efb19f1dfd9eac90c5e5427396054e4006a91ff1a2edf93cd8433154997c07046b9acd7a0830924d6428b48d15427f5dcd712261943c7a0e2384428a276ea1ac1011874d179c0681a296ae12e1819a67c800f4aff981bad07c42c7aa5d8f57bdbd1b299486f22e9dae3c07b45220ccb82c896270b89d9490d4698d7ec18d5a1242703faaa899a32fb20c8d924c51290ab5d03cd2f0af6522e0217f80d2b72ccf756c6be298312eeba602ecc7ba0d0e80c5ad42b6112280dae22af6a804b3e8db2ded94ab4066803323168732c711a2e9c3b4e7e261443f3a9a921f25e209b2b91334d32c24f9ebead8f0a5023c0949101bc0b06f9f8a7191ad0aeaa96d94a5a90081f48fd18466accadb40a812a4da245de9bfaa0e669245374d85f8ecd414851158a381a9b32990e6f4dd9521191628e8b48250bdd03438d45c796c2f09e4b5a3c50b0de2b93ca80c052ec38f63cc83589b14ec0176c3b19cdaf29c1b5fd536226c9b6b771267c224a854eaaf85bb27f56bc20411dc7ec58e4ff417737f841685e88f30e028725d3f8ebea2983fd70d91a900f8c5c666451bc4bcc2b053ba95d40426ead1807022304774a89ac6722c2e2da75117b645c168071900c8e2938f60456f361d39e3a8ddd2b38e371b553ab631b2c2e5afd13650772feec63c6d03a68cc857704ecaf68087f57d0243565c9422bd4ab2123fb1047b54e84a4f86fe85780052a279bbfd9803eaafacd1168425dac15380c93defc24a1688f78bfc02a85dd81a80c3f4995b22c47c30e2ef85a7eb6cac6080adf98456f041f973c591b004330240384985939acd0a2c046269058e2c54139a5131aa9b167e65a93d5eea085fb91ea5c3d56944042d2458f6eb9a02e425854efe7c7ea15b85bebfd41a50479d2844d2b7cedfad766169c0b3eb459e8c35cdd235c015ea855e75223e070648e7cce5fb18d76d58a0140dcd7b4426d43ed0120768b33bd1fa76c8fae40541fb26b3cf51b4163366359da17008a44baa8105271471f32bc1cc68e0d76fced09baaa45fb231b8588d8fda6758fb647483356d0f1cfbcc98eccde60fa05282753e4aef70ca187aec002e712fed1958016245a03a462d10e48197e73bd337f4defb73d2a697d347c0e28238e677b90a8a3cee8646f668ef304221fbcba42c9c8a3bf33a79a984caa0fe9c8f7485c64451fd18f255e93f650e0236b8a9091f257e50e147a261086000cb0cc84b7a6cf74b89b17745de031551ea961b536b0601f35cfb31c6acf5f25b2982fe49516bd0c8212adc83f90caad4f01ee18087540880eb279b1ab4ba16ffac1356123b6fcb0942e5b0cc175a3f858f7c2d99cf7549af386b5b69810b01c82412bfe0e8645544985231d3ab2acbda8c14d7c3a58c061ea4ee858061053fd8bc0f727d29781aa0afeacdea37853acb6f6423bb2fbda726b2fcabe4880aa0ff2da5e6926fd12aff982c6f658e6972adddfbc8ad61787ce0b8c81179b0aa7f3df0251b13112ff43c320af07751baa9c02c03a30fc51bac1168dbb663a334dbbb660251e793e9e927ca4740165db5b5955ddec9944a6e30eff2568f37445c04e87fa465adcca232977a721a659f681c161874049a4e19d646a9e8ef3874be0cad6b350f0be584d25fa6c27c4014d2a6e4fd2cf2cab91ab1dbc7abd280897a074684a260a4ad1a6c8f1770c0e7985abe30ca91da5f54f2382ab6d37b72b697634823fb15ce06e978be39823f97808f296aa44ef3fc33255e9c90066898405182d37ddad0e7d142e0ef649a706ea4d601c74d3466ebf30a245ba3c3ef8c8536cd180090833e8dfd168d10389ea7add72afd91839335e8254f46eb19b7d5108c7d2fc115869d52fedbf68805c3af985052faaf90b82e5720eb94361364cc8787cf92287ba601b7487bda7eded720666a68f6cbfcdb196bacce40e2e77403191f218abf614997816ccd027026d157c2a987af19c9143a5978b5cd5fb4238cdd2eea2ffee397c85de39742f0604f004ce3c060c75a290e077f77059f44e640d3d3832791678e5db26fd7ac004b70201fa6dcfbc16d0da35e07defc0de0856b75dda60a4b35ef8896cc185331693823663eeaccf539d99bb200c1df5133803182ba0d664905345cd3524e5ba37e754820ede68a70685fa207acfa96ab856b76aa745675459dbdf4eeae48e7048f6c72159541d5e2806cbe480b415546b554a056a358b9c5159d27c83a75ead82098162411cc95927cd470aaea66b69bf5a7f4ec9f9e2d69f7fa06c3594dc1d9a9b8c68700e8773f9d3b939f444d68de76ec92d208c38efc2cb42cae82c4ecea47510423ba02f207ff56adf7542770ee82f90c35a72b9e274c61caa14e038eb5e756dec93b7204d759af8a33776bfbd5aed1b20733e3adbd06c2cdf4b8a141418bdbb759f302ea64a9db59e4017a15408098ef84f3c0915904f242132811893680ef330eb8f04f0c4c3d7beb1d300b1de070a621628d77035124407d9b6f317ac0d10a2deb0bc02d2670b3016c2595ca00e04e226af0e231b17d8ceedeeb07055581932615314fd46f7e10c351cd8a77e2c5fbced3295258d4802c14c97c0c89d5b30c17d95a012b5478b357b850f8d4c8d8ab2026cc13a10215cf7ace0bf629fb847d4b4994b5832a5842327f9886f26658356636676e99a690a0e2f243b71d252dbcb1e324565317902386b99acea672a56b59b884d4b0fbd45f5675a5ec266dc87aadc2d86829e259772e6224b170642a83c8a9414da8a93f2e4a7b9e75f85769d994185ab3e4302fd8847a48304f20f609bcba154f12d3afc9ee1021f9f7be7dc9052dc55b5ed25de64e2fba05960b459b438537973cb4a1a46641c92a83b9cf470ce0178b280361176973dea3d54205c4e103bd2c174e9090598c4ff914821ea09992411a66d21400f17b7c318400d465a1287ddd6489f36a725d16d71043436bd8f044857c781262be7797deb50027b373bc63b562c065368308077f47d08e0c6497af0a450ec921bdb40bef424e8b70f03b11e64e6ccca482095a1a2bf3877852b5c028c25473dda209e660d451dadb469d959891060423c2164f5aa89aa35afee061ce110672ae34a3a532d724460f169e4fc0a65ab40cf0d8066bf9ce71a27a1df9c04b505ebe8dc7d6c98871fa5edffad03548ceb95db071c153681adb1162036bf8269d4a480a1ff3217db1c50aa0dcae4a58a9d2c0ba9db3d714661228b3df8c208a2394a1a0e49d2043cfc73e8d5a5acd00c83d8ea5c0cd910403e6e583034594b9f530fa922fecf90d4475e704bb784b0a7224d1243d79e8a083133220edf3c0971135a8b40e0746ffdd41d84a2c04a285690b6095d0950aad7880f8ae63d3535023f0b1b419f80a2cc99e69be3dccc35f2f27de968b24663a7c925f0cf91b10280f580b7ff93007aeb5a72fc0d5d3912b5bbfd181ae868753a7c03fd10ae4a781003f82a958f8cdf61d588402d681c467b6f6ea9056b94d8c58bb35f8d9f06d88ed43a817928ae015201e739ee0e728a8fd0d00182e6ac2b8933dd712691fd08725de59d8d1cd7dd5f3490d61824b5ca725911cb038928b644ec8973830aae0f5ab566c6de37b1373d3bfddf30ac410a5da22ad597ef0b5bb7d148e589d0cadd0cb8f2f7630d079b4c862e57d8784df7995fa4fb36658aea3b3a6ac207b5a0037f267fb88013f1f5db49b79a088172e087e3371dce47a50ed3d5a03898344cb72f9ded7dc55cf801df0199587138340ae61383a3de6be05594e76838a7888bfcd0cb20a81e56352e6584765e45b8d15278b7e5838380480c4bee005e3ee675de76b7a05ac81e9a49e913908c8d03809543f0277c668f27d21a896c270838a0040c3f10ea834bf007538ce12bc75b23fd6b0e95a653678631dd29e66da7d10ade738be4102dd2c10abcf75b19180e7ec6ea4ecb939881e01429ac75ec399cf3e6682d40c4e1e0e83f9e78c50aa92ea61b84e15be4fb9842afaab8398beac496bb01c0bdc8142c0715bab0b0f5424f7acd1fa132ead5e84269fc9e104ecc56fea4529b88141cf2bd8216ea8a88e8209bc808f6c68f46231b308b66661710277a07496c6d44993c146a91608f90eac5a20bb91f456d24c00f3e5105eb2bb499044db375a97fef24b801a218152c77a26e80eb6dfd0dfccfb590e06e3b5d39ed4a2068d682b4b5ffe1ca527829c2fd5ce78e96ef8c843ac1f9db3afb7414e8a870fb3ba31c3732bbddaa22c24b27d2ebc7cf658bb1ee21fb9ac1e9ab92b5c77217a7103ee0960a74cd20e3de2be173231af5c815d2161db03ddf6474d7390c3266d2523fb1b91489797fd63beaf83c6f3b4aa4951d268d3381a71cdabfeb838344eb6d1e8e6f8f60921a9c93dfb6cd8aa2ad8551f0d21ac313e75c8da3944b629f56d7422968f9349b8396d58c16feccad139d7542690763d2f2f4dcd164bac1b5d9e95a03056f6b138fd099704c9c33a2fe21a3d2050f01e5a9e4cc518163a639dfe40621dad6783083c1998dcbee1212b7ff0a3ac3fe93d21e22bb4b4e8290feeaabdc53dca9ba9b81834b72f3a623982131604a07c0e38623e2a806a21db9cf7a9c4066a91d7b2be03ece32eff489cbec923a94263842aa83511faa459d35ea48d2dd44c489c75681105a4998a782c1de52b4fbcfa0b8f19bcbdaed80663f75639e90074ef73b6c64715a629f97e3a6ba4a7ccca12b09d9de67e1a8912aa6f72b63dc2123cc713835e741351102c691b3295c612004418a2686d27ca4bc53a2651d79534e7f94b3f50f092a9a35e7e55bff6e345e06943085ca05d2ed1f16b6c172b1287e817541a0d030f3e23ff05ba0a4a4bc0548d943ccb18e8a9ef1ea357851ee9b72b914a188889d922cf0965fd9c4f6879f2bab6361051eb085a178b2647dd5114eff9b75de123abfb6cc62a6d6fa48f31796298e1d2fef881fdc6137449232578a95f982e0a682a12205c486ca7713da954b10c9da520b58adbb9aac30ebf2d4e641770d09c3412e93bee71041f79d6563e9af217314524345d783e6d8a1cc200b928731fd8e87f0b486b8bf121bf495473c533036e493563b3ea5a33b37614cc14a1dce5c22bd0ba917b2e8dc2e991c7e01648c65cce506d7d7d87555872bb7bb5b30e3550f3830dd7f0f1df527c0314d32a7c7657dc7e2a0a01ba2545714c04eec75abf0402b757db483a11ffe1e4652f7a07589f957930bc6d23e55c7f18e1e9d04a4e4da576c43e3abbc5648b2e8e598f8679456f41e6d7b4ca814c9d0182fea9a024909e178e7eac666389f9cfbb748115194307ec8f86c393f7edf65b82265e9ddd6a76217ee322394fdcaa6aaedf406e26f2959180a6d9a66aec9e61124413195b3491057bf90bd416ac2ad49521d0b6d206f682012b4368ca2bbf8fa5e5b7e9a92317dd4af3354e8dc8145f5ff76b2250a9c4222fd07704d867085cc254a84a18c0652719030addb2bed8aea21f0a9d1cd74534f36edc9ec6a023fe13ba7cff828e1ace889ac8deaf9943f4963133a32bfb1c1fd4b9ab0224e7cb3e60eb706a0193fdd99375266c48a33acbf7c1a9e3954de16b613daff8f2533150f3c362cddb08871a4b2710642563a039ca0c007934e9576576af9e67ee3e281d2e8a7df16f20018426d657c4b3d88dc8166ad38e97c57306f2c6a430fc97f23acb05512ad712d43f9769bbd34370a815e51196dde195274dcbb5632a410e9c94ebd8334526e6c86033f9a0a94ac20feb4b2a272e94fb11bed4cba9f996ec20224d2c186c03f92a7559a5eb7f22ea4f92b56ab51b44884b053915b0e7cb7c924349218ec48cc74a28aae0ab2a63da67d4bf43ab88372fb3a0459151e5ed05ad28fadf0abc08337bfcf5e5282245848d79a5ed320bd8740dca4097af2490f4fd4d15a9d07b9203713c288da27b23719e3dca5ab3c4786d0c02b50248627361322a279c41bcd64537d5ae2a084dc1698ad72658b275e26a36165ad5d9d29ec2d5135555cccf8f45340731987d0bd021b870c7bd54baea955d8de08984502e26ce9120166e87019ba8480ba3d7bbd37cd985e655f7b68cfa606eea3101006fe92c75b6a82d5da5df99b26a316781d32168ae063ae0e128a217a61872e007898e746d6d2be639a7201c2c01b8f304727251f8f5da6a36748186fb2834b43ac33b59669ceada5c637b2e2548fa30ba8c0f41f3e2f0db59b874d47a43f2072f9a061bf721c7f735ac046c632e6b7b86227a4d257b07026f2604c54438f69060aa9e05358e8ad6774a360d035d60d2e1482ac354e06e87e4627287e88d6b68893374aa0443cc6b74d1cf4446a1a2870b07636ab3a683177d8dbddeacb8a2d57e80fda0ad37467aba253177e334f46ae6f27c89263809bcc9454de466b280f516d3e8da0fd32f2fa4eae9fbb1e9f51827a1a7a3ee294fa7049ef71e45cd10fb3e8c3362fdc42db92335748009ac03b0cc0f7b1455864928a6ee9bd3b058a0ba46e290a11375ddb4ab06a941b81c6f67456acf0049ada1c86390975041af130c7b539326eeda83ad322e698090eba0b291571452e6add4d39d48c84c92c5ebc94f3ebba08be4636f26229dcea373f4b72929d9f3cc7b308469aee812b9e100859de052966f8c0dab22477f611c4a26d6d9a7a95005e9672dec2f4fe6c0c8b577154d823ac864738500a17b4a71f69f8b264b299306eb620f67635e29aa5b3fcb9e225e4ba4768fcd61ea44a21227295d77670e515882f295dbca180edfcf864e64fbee515f5ba8de431e6c806db94ca20cd888cb75f47f177ec83e365b0e10a8e859f9819ca7d0254d527a070bcd7011e3541747fc13e7a868e5ce6fbc5fe453c57e669dceaaf2f685d418fbf86b6c7075f7aa60ba5df4eef9d5c6c75ae59354782dd775c39533b92bd3209605b408ee2a1a3307afe6248304f4eb012e1223e4836f939354d4ab1592bf8418147e844a9bf41726e56ca4247fec54beb0963d789de1a41a9aa8a82c9bc3c186f651343e559f054b454d281fb80592d9ff91478f34905a96014b09614fc94d8f595701f93fb06818dad4776a7687a55771cd3be9c61ee421f651f47f71d215aaed1173f0725732f8a0e412f8ae9a722b14e7d0d86eba59f5fa7680c625c0f6ac72074c30752623d8353acb8b7a2738b077e4830074f41757c0e89af2b3e652fd84342b4df43df6363e1b06aeb3ec835ee07565659c9b3fc1afaddda8882ce03dc68773a7acb631827afd5a53af65e395c8aed2ef20266cf70d6eb86c1844a8480ffabf6cb3fa7e0549533698bb56ac2078cc40bd8c3a0d389189e78d1999406d807c4a3c6c96d8412a39910c9a96860200ad1e3810fe18578beeab20522d20dfd68e5a1328d6feac83500f96395d888775f1ea654b96381cb9dd69015e75f3a9caa3141a80a98b5650a192fd690bea4ace053aee4f870176c4ce8f20091b2a90aab2fbdefa4b9f6154dcaf1edc0bd896bd4f0a27cd3ef323a53e9acd3e7b8505e6966c9dc95aa6cbbf6fdd5d90ef589ce74674c80150e3756c3932d83780baa99801d99aba9c67c36e05be81ed4b6305028da9e76b924cf669063c5a0e130d88b75f17077efc82fdb9bba0e468cdc58191e1379f9dd7f46774216de6a203d341a91274e83104adb4c983457031eb61e6e81a2067279ad7c8273d34c3bb59ce960c2ac88f23e1e03a73d77ddb194057e9f81fffc0ad39b5dea2a0e7733136bace95e0a1ba9184490a96174b2071f000c2c93d90488c2acb0ef889a788760292fd82eaed90ce123ee4e03be0eb15ae1d05713542f4ef7fc4dbac900c00477b017adbdaaacb28bfde88a3dda0eefbde0f1ff273b9bbfe0b3ce0edb9fc9c47a2ec755e02fa002b634731e0e9f537cea031b9434e4e9d6920c7c7eb99206fdf6750d945020d4081eed7e42c08a5685cb8277bbd581dc3bbcdd0d7aa91668b0236dee5faa38a4914bbd4d55b08e782609bd45e9cb3b747a67a87d35a5a28cda19a95e1a6f382eb9814ad59a7e72318488c80edd0cdd3a29bdce4e384a333247bcd1eaec610d9d2bf19c0994aa9ce86ee87dafb2bf33a90efa3bbd9c7c8e541b4975799b08a0aaa4fbf6a358a7291cd81c706da99a13e5ab8b2db27933225fc5ff577dd3c93e63879b1d434f0557b2c3a1bf001086ae0bccae57c7b5cc199d80bd293b51f5c1dc23add87a6b123b5b273960a6e6f2bad3162244fb19a936395e1fa2694400521fa40029d0056f586c01597e3c1c545e5763648eb3c91c5b5261afe4e711e42ccb9392a71a851f5335bd2897762e32b61c28e9a77859fb3dc812d24fcc16c8f5fc6e00bed7175469889cce22a2c4cb3eeb3f5a20ccb4d504ee58bc469189d799bb212cbabfc31d72ac944f13289f38387efc76b4192d596c690cd4758d9e99ba14f6ebc896b09b87e9b6e5aef0c70e10e60c558e3cf2f4e3a8cea7e953ae2d6c2996c38463fd1b956529620507d0d9744a1c0c8045228540842bc7d049a5ff1c23d589a05e6176325c2e252773ab42f7f56e909227414c4a7a8e9e1813bc6c7cb012351e32803c3ade0985dcda247a8497bd008777a8ec047d4b78897e0fce403633675ecd4df43661e38662fd7c65c1487255e3af6449c53a5610290615a6e13fb31e4560d0cb4f7665d13feb6d210426e380c4f420990a68263f02f5773593f59a10bdc789b8192335cfc71c6c361ff180ac9f9dda62d6695d84ba9f6b8832d7f551791c03d6cda587c05dccc84a40a12242269fad6b16b244c9cf5247b4fa682c0849dd30c7915b19e1d0f587b6f5caa99b304bc8b4024b7592660be4aad9562fe1d37e6d8070724efa52da7df332bc3a7bca6cfe4aa6d0bbf628079ae8b0f3d9e0b2f9ea5ad1d623adab530d95b9d5995263f263c767605cd2191b2bca337b8d9a7f6e9fb08a42ecb2933aa7dd46980c4a930d34354dd6dfd05d2bd661d62abf9b1b04388f469acf31bcfe0c53a0cba066db790941b892c8e4bbd1c093e7f79fc42bb1313469cdc0ac3383c274c8469cdbb09100fad2e50303d09a7c85dc28203ad64d21e85503cbee0d75e269dea84888803c89ced612b320b98d427c3b0e263be628aed776e785092aee7aa0173e3738a1c888dc3a0801cead3c01f5072a1efc4993f583347171e9aa5e95a7aded562f6b7f47de843b570c3415891dcb1e265fc7494f28c50ccbaa81922b7e27433ed04614e1ae35a9eeebf66197374ffe72e913609184c2163b30a6221c9de405f245d96d12e783614d514d7c296eba340dc881fcdc861949c09dc7705d434577a974c3aabbfb2d489072f2dac264488db9db1298c8b6446d5fd638acdebcfe3e3fa5c737c220741b64b5ee84e0a3b53798b45d1323d6a49a8eb7157ae75877c953627c77dcadb85acc4eaa5df343d30af8a4ad9a89364e34fa90bae8e278cd1ddd540608fe8acb29d857a94fef87da1bdd78be854506bf1644e7d7e9c6fac6cdeaf71acb9b0cff1b6de18acf175cd639def7ffe0b261efcb1a63bcc9aa48d5f6f4327b12339b96b5a17b3861b5cd05a4241862519b8da4dde8f0a804ad3805c1e3e897983fae98932d02ff0c93fd08e36363b685e0c6e5383901dac56c9dd02330153f2571824c902eb3e49391ce0b2994d0ea6b08d251e56f1b57a9f46902e3fa3ea635f9632930f28f8f21ea07ce3d263b6e8b70354c11a0ae8075249f088143e89c73e654a9fd662c19122169362349ea2f63895b78afb2557ea7546e12bcb88a50eb6464da2366331594a60c10437c2a4246f6b8b10a8bbef7f46756a9681a810481016e81fac1ad66cc4a1199bb6fbeecb8b46a049def1a4024eef831562cb18949414896c49999a0d66e4a434ef8c4f581edd60654560b0b2d05d63cc3234b52c588d3374b267a4dd404228a8912adcf8f72ae4a7e42d2b3cd82eb0abf5f642cd4434e4d050c27955d221867e70c8ca9abf51993dcee49347012cd35d820641c20b07a0fffc86eae78237a82f5084ffe9c26668f52b9495e6865e32b69c25ef40d27c0fddb0051f39da0e4c2d61c127d7d74b61ac4062d207c574160234de441513a4fb8d1c250caa755946177a51006a7194d8f1397837b9eb0cd59dee434e697415eab63e62ec119f3f89b8a0270a2173ba7427da9fd98e4380da5e57ebfb8d1813dc2569c46bdfa1c5bf02468cf5b801f571d29f370f9eb3a8e8ab175524d44f5475755d747eda946203138f4181fcd23903a4a1151d8b5e1e3b26eede1f236b459fd8cb46ac3d750f6e7a5812fa2ab03f59ee6ac4aebbdcc05bc14de6a67f4b6a4690641340a2285d1e23881422b12d2afc166fd41acfc455cb158dbab07abd91387ce962e55ae1ebd9eb155807f92f6571398bb999b44e0ca81646203b5db2b2b548602c478f091d5043ca1777db4a1dbd8b6a5bf86399b0b22152dfc9c94c80edac1eb2c9c0df8b41acf33a2d4aad49568be766e1738060a28c7d5dd50f9ef5508a142e478e22088aa04a097577281ad8ba6ecdf97f28c20ad9864249f38df7409c8ddf0cce060fcac25e43c3d6ce0b5d7f9ce21d48d16b33c08c93409d835edbd6cf4c32a1fb5c39d02e429a090a2355a7bfc65dc3978e4b3041a3540972b980143096007c8af263437dc6a03aa3db1ab093c6f0b0a905770acc4bbf81e753fc0c149ccf1750ae1269248a8f67b307b3298109a279efc81e582f02b9a557acb80b6740c2b731ca8c2fa3408bf06826d38b262d640de5d3e0b19009b8cdd253089137b8e18bad725b024dfdba04a715a883eacbe98d37bf40b8ef0d23d34035369eee77edb6959a7b3c6e9e4bdde8a6746d114fc216c78b55fcb94490b9ea58c1101222e17e447bf60926008fcf7a98e0a869fec2e1a59ca1493e215fb2b74d93a06dc138b2a4dbdad26f0a01bb6f8236466fdd03f12041f9b499366e62d33a24dd735ad10ae036749b0045fe835307f6ae0348aeae506bcab2301f359e16af7a01836d4244752d05e681ce782be0e5597d1a52579375ec5740e19e9587d9769b215b7a919c9794b73a14ff5b6dff1e5a31fb89c52395d8f799e4e460f46b01cd2f0c9c29d9e312eccf4eb372fd6f84eaceabc36124747b4c63c588405a16f9e279f14264cf21d8c293b2e2d2ed6aa3841c351a00fee73fea84cbe83be89c55a39054232b0409b85a5a332ee85a2f983b896e198f0ced5c5518fa82ae7783425481817d15275637c50bd427a98fde04ca09900010e23cfe67a30ce65579176e26a0324b2c57de475ce950d2c4d4c31ba29a41aa1e143399d1c745b0f52cb020cf066d8473d5de026466a1a0e8d992d504ade51aca81569f761e01a0e014195427d5bf0f4b07ade1ed9504bde9913b0dc0044891f696e1797f226c12f8b0f13fe4875be769389026ff08b0585213ef1899cbad74906dc1fba678c341a0750a5716984cc669d94d94cd73f3e802571dcc105535620977b7a79cf217529894ba85b644a551128d657d1818104feead335c7c937cbc3346775abba4cc88b028c21af86092c96e79c2e452950732759839a722aedb4c1e386fd7e9e7b99a96b76887100ddc6643e7ba5361b047021ce6a3ce8b2beff0bb252484a412396efdb37c11b7573fb0e7dbaba93feac016e2aa43fdb5910c5fbb7e0ae23aa9faebe9ad233203b578b4ee51163f1021c25bf0a59fb9ecc48ad605b0d643d99769794a0b2f59efe74dbdc59f7360a9f75894ee7e6b707f4ec36357da1cb809f8fea45445e43e29d5f6574849b50eabec576335dfe735be03c82f4ace7984dd0efd569b960b07056954fe6c4d0b2517fe55e0dd8c67a50872122eddeb66bfbbc35c66775fbe647669a4d3b7a20d0440cff7da07e8a8189602ac4cee411c5f8076c9c46157337117f6439934405e3fe38f8602588e20f775a20c646a3f1ded93595689e78d827e925e23069e9d8f5aea1bdb48bfbe6c547773b08f0d67a1ca5983b411eb981d0b5e099867fbd9804a2080f57227053e7e3c4aaddb20bb4d485190f17be290f0b11322e1015f5996966f6763f97a45e6d6881f4212f32e6919d7b21bffa082f622f77045d13c6566c818776e12cc8861788353ca6000c152bb4e288d8943c7eb7db6bd84f2f4ffe087af7b1157cbc35becf0dc1e83328c88b35d429d24ced37108361d1ee1fc2f2f5d772d6386864fe76e48b41f004ebf9f946666f7f6b27143f56daec69228e98b4879eb635822a711caa847621cfb9d0cd89520a041cda3800c95988558de861924b6b5c5734206d570d6472654e8f3f7d0042512131ff104dceedf8cc57ede0bb3f00aa1633294cec197d42b3a3906c11917c1602004f28f3ba2726c3d06eb988186eb1caf16ede3bf98ad47856bf9d06bd2500c842c8e0ca118680e2a5675cbce9d299ede558d05b2dcd02b5e637e69b0966e2ea80066bd5a7e5a1cd62c1a914a8d153ec15854aecee92735e4261a805a2128ff6fc7185430ba3bbf2bf9e5434a2e7682d55c03d6db093d50abf4e361cf448837edb9e274da3df24b5b996cab5c388ae13c7c2299131dd8568d5da3da785ea44220e043d7268aecfa833d971c085b0307f22dbde8e1c2a1cdc9fb205da0265062abf604e60f802e797a223132c32b390cdeabb04a493888b1bf80b4236d26383cff51529e8a40e11c9862979bdf402420cc907c7178440cc00ceca8e71f9fb785372c165d7006395fc511dad4414f0c5f774e0a38821b4bcaa34db6eb63624d451cc8929e52eb4757b2f9d987a709737a5417eee8d226b613fa6218bb2f902a1d568ce4039f50cc7ea31f725d2b800913bec05a3bcb2c0cff77bc76414cc17c6f779d830694084f2f8c578879e8ce0b8f5c0402662fc222b8820e9bb36db7b1a36dd5fb4628c38b9e0746eb1796306dffa1fa235728cd5d81c3e2887e6435a2031c6278a8937dbcfd7743aa6dc030c6e4405485b14a2c61b20601d92034a00358ae96dfe9d25abe6e18ab7aaa43160bf592164a93af0507a2d97f2f96914ea8c12100a1ba8fe82c0d833315368c62ff5fd3474c4e13a60b5b12b31506182c070feabb8cf3341e3f0a50b08411b4f65ab90c0d29ee3bc6675e6d992aed836a1f4b6590025ea907c77ca95855e1245d67c3c9229a80bf328709d0deea6e764cd5aad8f8363af2fd85b0cc99c7ebd194c2178fc086f40343932fa62b857048f833cc34194e3cbc556d9d5e66867d0ebf92ad90d3d1824ea7ebf77a2220d840d851f14edbe13bcb544d8835376898dbaac00c746239394055e243d157e26f899231efea6bb1b7903d6b841220fa33b00e0307382b9171cda7edb7ba163d5eab03c4474439f3b0005754a64b3800b711cd22dcb9a471a268b6402465a3936c9c8d79f27e26c491f4af2af358108012968b8cc141362cbd2969c00cab03a653070c42e50927f2e3dabac9bc90f6fe054b85772fb05ae55bee9b960478e6a5e22ce770b3c2d8d99035a4ba10d77665080f1d2de9554dae51bba667984acc2231f237c4a610d928878e991e129bd18b02bab0b5eaa67dc1dc413a1da25b1316f00833ae2362d48a8401709038206922e5f40510670e42863bdeb69d95b0a72bdf0c9815457e01d6eff3481776f103b2b8ab9d6cbbc2f0c116f02655aa468ac7ba4478be314f060493bab502f592ca970a4697970c0e0a54657c292d29a1f8acd5a4b3ba35db03d3ac28d83d28aaf0a186bc0f82b475c5798ad4ae728c0e475a529ae3653253a3387676e4207e02381ac8a1ddb57d65c9cf9f9c21e3c2de759d4128689a542d8ca4ba305eb7ff9c7c3ac76f94d02b96b18cf8085847103dab2615742978ea24ab920420af0d4a5a5d7c6fdc05edd0d900584217e9144847972b7a22580f56babea0c51a7710d0ddd59ed0d92081de76346c16843f5ce763c6c7f2cdc09dd51e6cc405927910b0806c20bbdd43732e117e6c9a31b35740146e25e217f685450dda3f4a237de5e2f40c430423fcb3156938f1d311441641b013ca0914bd04f78c71c0312c37891ee9d16e27f0ab5325c06b168c5676d5ab86c962986a3084be9577c360be4106a6dcfbf35025e23c50d88b73384f52167c180e1bdbf0f1753556e933e56bc2d6a9e20a0f3ef183e9ced09670cae8a3c18470246d19cffe4ff102fa91fe1f825479c91b165c77265017c05d59922428b69b39387c3a0092ac135932864b2b5f94bb44f49c3594ac2941d77aff32e7fb751808e9062e286434fe0b3be65210131925d51cfb9dc1d8f29f32ea24934a8a17b59c74831d8a39fd162c8d45366661ff9e2e133334d76811ffcef6a36abc81f6aa69b41835d09260d3193cb6d637b59ff7168ad79f292b379557402c8861847bdc89f57ef0376cfb4acdc60e5691658c662f4da301bc3d0f7ab7ee3aade0a2a1eb7c80fbcf9ca6685ec846762eb1d6f622a545d0760f6298669827b1a4102234e06d27255df3c6dd8db451ff00159d629d5deeb7a8cd1a194cfb0fd3d1dfb7689dde233d2674c61d20d059f085428e8fe6d310d99a4f3272b97c2961a95115590a8d1d4d14de59ef5bdd61cb7c2fea2d371a5035422587f401bf08bf6158ec218698408052044b47b10e19e07281b4427964a52f5a0f2591ca63f2d0099f4b1f7ac5e291966bce6397e16b7292ad6608174b2164d9255898e933456aeba8b75d435a78b55455380d753896ed1b1ef07326a0d0ac92b49ba9634572a05c1d9d41e63f2411c6051cc8153fc6fd14dc7d020268a816abad0437dbf6e171388d3962753c4d220a94e3658cd83673d61f99ea2d32467221c217ebd0b281f776650aa91d389ab14d96ab4b9a9d9d80113d6e722b78afa014471634999ebb42c8728451702afb1fd9ec52f5666f7231fd1affc7186a4150dd59852e6e1fa986ccdc3be5e8f045015a24f96e34d646e8a7a2031b2493e1f96d7955bcf0c205c45423d648290d4a7cf4c57288f7799bc15b43ba800722bd7507a3c0a43cd9a878f335500179891396d6dd157592efb592e8cfc2c6b8e8efd66b139319455fcb82cd785d3835283404acd11afb76b3b4f9469381f27326f89e836ca61a14f98f92b34326840fa76473db2b1fa73a180a16b7d908beec3a0f4f360d97f11f07c9e30f83028d41bea391d8b02f749a397fdec1f47314bcb947ec73cec9ee3314dde63521411645afbe843b9b87848e62263fb8b8f0b062d5125d91a5c724aa8bc50212fcd512111df3b79bc319a48d7cd9d7523223696a3a4567767379748b448049383c49b1ed7bc5b6f26b6febbc3dc7f80ae106e367523e2150236b5d53266ab41c945a6a3ea412339a338c3a5bac58d5d81d7dcf7a7b90ab8def4f0b009e09c4dbe76ad0f41aa1616f923e030f89ee4c720fe694e980e7ec099278d2022fea0d5a98dfcc8bf1de282afdae44a0db5eea70d4d098e1276df4e1856bb2191de4df25fdd40f44be7097f95c3687f3f7fe81f9109f397a6ac7d7fe792370d56e066916d7463b888ce63c83dfdbeeb3205e229a226a77e533126d88afed1e3455c125512eca00474c999a15938bffb122a93abe34a6805963a9d73f92e5bd29c436e10a6bb78d0fdf75b0b730d4a89fa57d818a9e2e99705ab6535ac7591ecf17798c77baf821586a28d76488039fcabad522c9e319d50711a040a7c16399b81736331753051ceef462009d0d4a4f4148964a680b91fd044196aaaf5e20c7f8a161c5e99f02e12b5069105c0a921d4025f1a13db0c588d1f7478f46ef48f5d8187d4c86ddd5f90247300d2f7821e61bf9179c2436e23b45c98dbe938d1ace13986926a34fc4390a6d962690ca0df66bdb360c0393a9c5d892384c3afdab85794233c34a8b10772c60dabb74f211aaba970dfe27089140d1a36ba30724d0e97601d40108006065065a0d265b3c05d412573c4ceec2a9c8c8a7c4e4569c46e00c36984815d78314f956ef740189680a7081cc7b473445e50b6231ae9960e38768589af2fffcbc9e9cc9c8060ce050683ecab0cde5ece17c6011fd81e137f52694db69ec882690345722c918a5b10bbf81bffa36b6e05c74330c1848e8aa5b09c25200f47595008d0a97dd0f6164b55c4c9d9b2a20e11829f31b0da3ffb2b3a903e4886ffcd38fdffe69e403dab1ad98ab5d5bd1fe91b8ab18216c6964172576f157bfb9e29b2d559584428ae5bbb4e7ca8a5304513cec1b80a1a850720eee3d7dd23fb226907ad7db0bc1201b7638b2b83fbd8339dfdf1a754f58e1a59b826569087eacd37402b40d24d30f9f5fc73f5c796a98178ee4ff6c590b487d7e99176a06d44aa30bb44995c604eeb0aabbe0c0862050573ae06cb01bfc92ab0534e9ef01b7a7b866bcb567826883454b3bf058fbef0870857d8c79d854a3656f09f626f8c45179900c247d9a54727a245df32d4142764062689f552f98bdd9956dbae3946f61883b2159be1ebdcd1f248f29432ed98458b77f8604ed7ed4c371053a11849cdfeeefbf91995861bb3893c50058837cc85c950bd69d7dd3a55199a9ace40051c2865983a274805cf12399cdb95d7373accb3a05f597a9d295337a700efe76af509270e52f73d134595a244552494067b6f3050d7d4893937870fbb88b8ee7530e53e9091951ce1028d0a41b294971543a392051d67fc22efbc0bc0e72bcc16013b6a1956d64276d20af3af5697f7233816ae6eddf788d8a6237c4bd8fdf8cb60b2551f3e4fd7903948fd691516534d226749a76dfbd36c36c9325a92a477b741bc0a64afb9e5185d33a6e7a3f8b2b55aca383c9302467e3efde0005307c80fce2f769e3c7b7f73c332e3f511cb613b8727a103365a5e64a41918c0c8232b0f434dc857e52565a632a6efe1d953a428a8f3c53ed55c9209aa6c9cd71ddf463ea74b5bbdb60e371e4ec37187710df77eac4fd1a840d4faf47593c74e3d98828045741822121a26378ae4905659b2235ab7cfe368f285b18f172d47f82e1ff89440aa94171ee3a7eec26940edd5514cf59ee31e12c79f33db3042827bf97bd2e7c5f1cff0db1fcdc31127c67fc14b2357dabcc6987ae66e1134a448bd1da109f31b328265a42717caeb80457580f09d0093f57039f719e137590fc49e2481a572fec22ee07e0a0e8e377a441779053c97a37871d66b9d3080d117036e0ce0505e1fe81bda72a1c8b8b54f160723e3540b9e75bf44743e82282e859091420c8e53383a848fb4cf688f71a1bc6eef26227319a87e384c7e218dcc56f3345c193a205b31f72dfc0ea138b7550a52c7ae0d2307c4daa47c54796b634a04f0149598f4f2fe23580cec1cace5400a47a9ed89e19af604a8c0ef0cd7a2844bbe59cd85567de79eb1db3e0591cb9d00f15d11bfcc1f80f3a2841f9152ba45e2f832e1b1a499166a4d72e1301797f2d147c856875291c202f50e3ac7b36c39008d0f984260943d66b81c10e0f22858a6d0161edf6842d1bdfca8ee4ffd7c34760848e56419ef153fb682a9cfc939202e542f2dc0cd282bf1d56baf589951ecc6589f3a3ea69e87627a40d01fa571bf2d7f07f836d0072077eaed6907d43600c8e7ceefa83c0de943a1d092053bb3e4fd048145d7a46d75ca312f2359cd7461ddc8a88c2ef5d7103d587264c7cd82d8dd16cc15dea01fe503e4096436555178e80823ba71290e6dc328e241ecd14fdaae02d716e0d5a4c61e97cfbf1bf368d1dd5251d9d88b291349efce6024e011bc03b54ac21dc4446464c7d3dc1cdf990a7c585c5e2c0850dafeb3bd864c11c462120c1fc37cd3e8450f94cebaf01c91cb2d352b276fe5c3188204726df09f5720b08aca9fb2b655d13e01100f21f7684af3b50100dbe4aa1c26a10af4f3573ef061c97734c8515f405b594b85926f0168ca2600936b194204e5b8c33f0c2fa6900647df29219ef27d9e724296b9d03cbec88fd9712457d14a94e3ce8d5c25922d004e17cfb3e125801e8f09e1eb4ec3cd79742dae8b6b02affb14c39037578e2dff29901eff6938df8c0a5d8caafe9be399abc7520153cd18a8d57b465ff60b3ecb53af4956ae17254efc5b6a302bf3a12fe4c8738c50500ac71ce229a8cab597dbc2bec4e1cb0b4f96e6da833ac72e8fddc85dd103c4111006bca6040eb0048b0e5010704627e9f0d2341c4751691a8ea358b29e21b18621d8ba3e2535b5f0722f414d003ae28abe45c8780d1c071f80dfca55fbab8805d489f8f866ab813dc65e48937e5ca035698decdd1a219b90bdb70c220e9c0e100f41cc977dcbd571c48ef9b25fb9484c15787122712438e458f655e5eaccd78a3591ac0d6db2b561596fc55add66b5eab07dcb58cc234baaf225b0af3fddcd86dccf8d434645987d3f00bda35af1f8f48eb459e8759c2ad32c534a69a7626d56b39aa65979854cb2975890c81a34c943492d4d7dd3b0b5a745382e9c6817f4964a4a29ed52a96faa944ab5a9a8bc31776f16a62a4e2a719cca5a7b4eaa96244e388f9a64d48d1c334f8e39b45d481c1cd9cea395e6326fa5d4256918544a6aadb5d65a6badbd54d139040bdbd75e70f7cb626a5da8a5d47e7533a5ee2cb54a3e732a491cf983a52c98248ec4f6b308e5623a491c17b52a6bbdf9b2e7e6cb3e33f258aef2d6c3a9d4e2f2e2faca5d265fc1432b77dd855df4ae07953ce5d65aa5a438c445b2a2729a56b3adaaba92dea5692a6badb5d65a6badb5d754d4deda669242b6b7d65a6badbd3684d38cca700f17d0cab30c0f655ff90a76d1a73c68e526f45afb92dbf3b57237ab335f2a2c91927a67de5ebba54c53caa07148a708a30115ac9551563a457b3b8fb2ec4282f65205def67e92a0954e12b4e72e054382f6daa5452e95940baa04aa054d82937cb294da6bdd0fd5eef4a26becb99b111565fbf9c5e442bfe651c431b3d0bd33b730a7c8d66653294e252525d6ed767bf944b5e826349d42b6cf50e075b7f6d3889d42a8edb1b61c937a4795ede3128d43ec3ba96becbb8b4b12b4f791dd3495ecad86e991e77d75ab7d75fb6963b69f5fc8dba752949ed24b4929a59482b476dd254d49aa5249792d28d7d32bb146293dbdc6bab644505eb1aead563eb2c66e887a09d6fbc8f934b3d0f3697e21db773f9c65c8f6d20a7b7b592486c611a36898bd7da4838c9a116ae664317b498584c2fa2043b62b4bf536c585944812a7da2fb2bde645b6b75629dba7ea95d071c4cc71b9fd8e99f3727b24660eccad0d39fbba727de6cbbe75634ce5b2587aa198ca5d14eb202a39cb8562293fb225675149c1475cb78ff6dee2db15ec635b2bbfb7f55f96bb6ec9bb2b422876af50ec5728e6ba42b1ba725d57b94144a80b07b9be0203f3daba2a7705a9bce55279790b07b9fef2aac28283628c85082dc141f72d2e67c141bfcbebbd28ff3db9eb9a7ce596d07b9417718ff29fbc88ffc4759317e1ba09c52e23565ef222565ef28bbf727bb4ae72d7ed91f298dfdba3e52cadabe01e305769a53c06f778792be544805ede82b9ca5d17bb7ce529378808112e5f39112097af1cdf1e2e5f79a71c5f98dffbf25f97bb6ecbabca5b2eaa519701bac652db94ed43ead435cb9be54c6af4315329a967a990a0bdbc114982f6d4da7bf30e9a4d9ddece3ed9ffc7ac3540efa46e7f6b676db177b17fb18781b91db3f6d6b354628f5aaae1ed66aecb72575ab7355fda5552504e4c4ae88a754a29a5b4534d2d1ab46fa5c9d435f6b30e5e7d2aa44ce1b3b58ff6f3c9dac7236ba9d5ac6635abd94f234f85ed75709c6d3965fb4b1cd5ed65ec55571585b73a6bb552ad3adb557755dcbb53592a71bc5065783272dbb804b3209e908cf188c9c8d00c86743105554c496e669a46b36d723215555de9a6943bca847e75fd9eee9dfa9e22770f71e4fe8dc6318f22ac7bbf758963df9791382625efcbb0b1a1c311a1af26b773c9ed9cadb8bc653e52b334eb2277346b9260379fa41512a96bba67f707b93b65425f91bb93bfe0e4a164dd4c89a3389491e93dcad43b3577a7457aa773ea3875522f24cef679946de73eb98d7be52ec9539704474f72f59cace7aaeacea355b73dd6d49c473595aa324ef85a13d562dd53b34e24a739244ae25489d3ddc831f3e4ee138ba9f4038983234ba72ea467dd6766d7dbb64f1a86c40925d416c3449bb8e84ebba04fdda911fa45770ad59d82d19d46d123b36e5012279451198c2e2a3b3dee7e558cf1469bb60d2f65b5bb0d53260976f3c867ce238933a940b222697bd7130b8953258e6bc35916b963ca5d51e6c3ebcecd57f7ccc87339cb5d0fe751f7790483ef7bb8805edef29794b7e0a196bffce5e541285f791a8214935e4e2e1331c78e888eb55c46cd1ca9345fdd71ad975697a8a1a12112c4ba4f23601cc988322872f70e6dd80a6572b7e5302bca1d8d85d951ee4eeb4699244ed7853a46244e28953294c4099b09b97bb793bbd3268913dfd12e7247bdc89d4ca6601060661678e17c7a7a99511aeee1026ab9a6e121ed2d6fc1aeed2b0f6a798a9204bba7745fb9f168bebaa3746fb93d5f5867be2a96471248e748a7f9ea9e859e0c72f7eabdcaee87e42571c66c723b57cdce8e7bc94dddde679deaddebf64c05ded649a44bc1b8a9307277131a45b5a04e4d78ca9d444aeab64b246985c4c972379fee0443829d7dea8691bb998586f2c2fc4247876442bcdc39164a27e9bd2379c77a8c751914f2487c925d842787f349daa759444e251985436ee2223c32e47e549f4f990d9e50e0adb8779f4628d3d3d37c924e13492ab574ea9dec48d2a98382922d7b6e184a22755603af0add5df76a6d67e99557789f4fdd33658ab1fb99475dd37dbb324ba579d43bd999b054ea9a9e2ba994753f91a98b53b8612c92bb6b51e89a0d4bd9e5f032653af25437c27af7e985c4a1ef3e9fe61712a7be9bef3e5bf2e60451debe6d9f73db8684927c7ce6f6b955d5fda1dbcd30ddb66d3bf54e59de298b25a32415ddbbcb212e348e78828675ef1ec3905059acbb844212a1c00bb97bec5a94ecbbad88944712c7765d482e3a0a5d638f44103307e6dd75cc1cfcee47cc9cfbee3bba2e2a77af2dd775638c4576f3090d9e508ce5ae0deb2042b9cb85622bb143c128b77b7733ef5edec5bc937977aa439b3a17ca656ecb63aeeb2fd7e5e50ac56acb7d39cb0b0e7a790bcbcbdf82835afe57d765f94b10cb5d4436967b170e7af97d65b94144b613d1e1828362cc85c8868283640e0384ef8283628e5f656eeb3157e52f37e52d17659379eb45c8bc1573951711739597a7bc8897a75cc86544cb515e44cb512e9463eecc5b6e0fd759fe727bac9ce632b707cc5d5c67c13d7e16d7ca69708f7bd7ca8900ddbb7e968ebdc8cce0b77ce506112102bfe54480f05b3e737be0b7bc3b2098bbe858f9cc85b9ccfdcbc5aff1ddddcb4cc762b425e21df2f652b79ba36bba77d52cbd35cf9b65edaeed31a7667baaee3e3275231412ecde7dbbb14882ddb3216f1a916077159e4f129c77a07766a16b3a9d99e332427bcc63700fed1d7bea9a2ee6e81dd5bbb7bada1ddf09355fddef9d51f3d5fd771e99afee35dae9c519a88845f369beba77b4f352789b38f4dadb3e9f66b791dc2c9360ea2fd7e5b65c6fbee85db7355ff42cf7f345bf725b979bafed2ad79bafed29b7355fdb51eee76b633d66ef74b56ddb76c393bcf27a877b5fa777b2dc2799a47114d060f77e776f7c44d7749f75f0ec55dac35654ee1ebbcf278ef3bc56eb2977db39cef35aadf0dd2913c7795eab45cf94bb4f23afe296e0aafb3ce238cf9bdd5b12a7be7bcb250eebddeb5545e1b1eeb1582dc1db6be82ea37a27e6eef5c62ce390bb4982dcad6ebd9c0453efae7698c7a6c4c91e2f1e032f5e8b8f286197639665b1cb66f7233b96a0b64cc8329267032438c3cd0c5e76cd05837bc0fcd3e3602e55229a42c027ba301a1d589fa74412c77e5e2b43371ca81592629127bd22cfd322aa4491e811b7d4a24d79266d5966868ec562923733bbac2ccae06d618cd9594b1264316521c1d91dca0b5964f0248b49e274cac9ac6bc8aab7979db59431e5d55551338748875b3edf5dd13baecf77d8217549431529cf735bc49c9512e784dc7ac85141e6613daa45793eac4334df70a83a92e739229dd32d7150484e8bde29f93c97c45d2171563eb1d0bc879c11544c1e725650118724d253d69e589e3d0eb55cd9029a0b7ee67e97b93c3ce6be629ce60ac566ae504ce60ac562ae50acf270631e8387c7e0a098f3102346e63ce0a0d79d79cc0d22d2722240afcfe0a099bf5ea38db9445a665a2e50cc5f38e83ee632b7cedc20222e27a2e3c34131f6bd463b7389b8bc3b2099833808e632f828b7c424e596bfdc501b925bee728162fee1a03f06b7e010044c39e49ec4c694359a0bf399fbcb5cfc987bcfdd237eb82162f0eabb875c529edd112ea953ea86742ba555d37ccd27156e618c824fb0890fab24d7d8c918e7e42e33874325b22a1691208723930455af71f69cabecdd919913f318ec713806af9aba278eb5d435ac21744b418b9abaf40a4ffe7daf65e31d82b96dbac8f3317769e65c6c1fa372e7eeb22c6b59d6b5acfbc8146b712894455ea97442acb0ab5ff44432fa456fa35ff42e238864626262fe844e2cc625c44b5efd25afb010191c1313138379fa45df60c80d866c5f59ac2d49caa106c53a5a35c9d5e72391c4e9ae3a4bf5156b89eb8ee0ae6597f2fc9483178f28538e43b188c5ca6e882e922da6372649709e75e75d5d0e99b3eeaca16c0c5e38b190580e2d75cec4e0ad1eb190e0fc0a8a35c40d79ab2d2acf6743f0c2b8d47d3e6ad1396016f41309e6bf9ff84360fd9a1267f5030e9cb56394b2a5ada87491826224776e56ca099ef6fa700565cf7ac52a283c2da5fba91bcba64ea86052d29e86bd9b754064988707b49cbdebb54349708221412d8cab1dd1e870e99004e74b420d8a1675cd14bc5083ca130c99e3c5e66951ef8431b523799ea4fbd13c6e28675f7861fbd02ff46b9e96212acf8739b48beed2a74bbda046ba86d2a63caf4da73c4fefa54a970e99af79984b93e66b96a135a8ded93eafd5a177b2cf53a499f36b6bc831cf25cd0e31673ec509458de234429f789a4c74d87e63ecb7635a193a67b51a12873c57496bc833d20e882cc7a5ae99300f57dd4a89c5c45a9a3931d6baca7ba29c853473ba23e159f5aca3a899d33dbd042acfafa0564d33a75b9aaba63cbf525252e260ae4b07d13dd1f1bb233387b5345ff369e6c4211b89b3a5ae3a0e5bad93232647f2f4baa73cbf42ea96660eeba81bd261d129499c8c6485e4e17085d45dc375dd52b714ca2149821d47a2a07c0237fab855dc787481dcf8e346a4db73e33c5ebfbeaffbf581df7743a78707c42d15ab7a323232323232323232e2c3870f1f3e7cf8f001757474747474747414f5e3c78f1f3f7efcf8f179d51124242424242424a421204080000102040890a22aaaa8a28a2aaaa8a28acfd7a3994314244890200f122448103c1fab008274f3f8e3f6d1e57c5caf5fb047a3dbea170c873bf20d5e59016f090882204b85b13c7795230b2e11f827725c269ae0f24d7d6a79de7c8d8a5491545db4ac002e133cdf796dafe707129c4cdcdcc6796e135ecef11aa968810b60974623aa84ae31ff844d8c32a17b98a75af4cd74c1ed586cc1ed58a4c2e8760c4699523d38a524c11ae469e6a4a06a1557c833e25075d1f25c5cde9d63916e6e135ec6f1faedc8df752290bfd39040fe2ec404f2771f2e90bfff70bbc19087141bc8dfe3141fc8df41a1fce190e73d30a25b8174cdbccead5574cd3c8d5b8374cdbc10b7fa706bd20fb75e21c5ad43a6b855a9d6a8d35988dbd987dbf987db394a713b16a7b81d032b5226044f05c3aa21096641f042d593ea49a5852df4ce8cb7728d971a2f355e5e9e525252ea7a7ab62b6ede731f1f1f10fc77431bf93bcf0d9f790ebb790541501ec9b0ffdd81d8154467f0393a835825c5171986c3ef3dbfb941e8dc47de5cd861b73bebdc246ce420f0368308ebe961a258e89d190fe261cb8787de0f0fb90cf36e989bc3febde7fadc58e33fe090cb357ec4071c7ab9c68f0481c356ae81c32cd3f875f00d86e1900371e86519ff700e9abfefdcac61df71dcef36ee8d0d267f4fdff347e32db748343eafea22e2e886d1380d8b44e3346e797028330d1ceec81f567591e75bba1fd8c1dbb9a565bf1bf3f77d9f4b2784cc3dd7f379f9aecc95c57e77c2b8ece7bd1322a6e702719efb731a37f61a1700bfb90178cd579585ae9907e2aab4d035f33f57b585ae990fc05501e0aa8c48703e76555f48703eff875be33e5c9f47296e3c7a9ce2461f8f2cb8d1e83cb7cb3d37e64aa3bb819590e08d576969fcdcdcc42fc0dfbca7a7e735c2603018ec42f9bb378c193cec86df6f3ee3dde5f8ce2394bf244ef20c1cc1106137f7993d172adf78773f37980212bc71e3c6ebdc0c085e48996ac2d845aef9663fc8b7338855a9a5efa6789052ea9aa9cad30e5e458281f7b9944982f3352e2d22c1f9787469938f4b9d8c2e7d9aaf995225cd5724953ff4787037788343efc3300ce296903ee5f9bb62712784ccb0b73a9e0b1ea603e2f97bedbf5e2bafd7eb7557ded2725f7fa19c9cbc542f93d74bf5524526ac4221f2771fc973c1f7dc06afcc15dbefc6a80c5ed749ce72bdf6bbb10eb9e73621f34f7c8a616bfd6e7bc10bd1f2dc2c73ddcf1d72052d78518492627442cc0c3bd8fd60a16b701cecbe1bdd90c19be5fa5d51411a74af19b0789001490cfbdd98947b6e964d38fbddb602cace6bcb8237cb2a5dcc82ca7eb7270b2ffbdd18467675f10a9de5b929f9bb990fbc18a6a0545e481c1a0f5b5e6eddb4905aa74c11474a29d22dc0cfd324f4ce8ccfab92664ef4f1a94aa2aaa43c5f8ff03ce41e7a0f5b3e70f74bc61fca7c233ce3ceaef95e91664ed6afeff329a5af060e5bf2771a386cddc0e149feae83432f8715890787367fbfc121f7e170078895f27ccf95f9a6fb81bdee589e6b927b6e7fdff7e1d007a7238089056f49fee13e5c212d16f4145cbfc047292e111151914e2c1a45a368148dfe844ebfc0d0c69bd032ec391d016486bdead8db0d1133ecd5b3dffd61a68b5c2069ea420913bc98b9669b651c37e6ea136dee625ae81a1caf2af6bbbd84cc735d710b5d83e32e292e2c2e2e315c5c5c5c502c8f8c17d789490989a7e2c2aa2d2d2d54eb9f6dd5bd602e2997d40c171717cec565cae8e2a28a6f58851ec8dfb3dc733bf3dc2de3b82928199f9c8cf99d0bd435f1366e6c9220cd6197e635451585d7c3671cf61bb7079bdb030c47af87b7ba0408c5e211ac07959cdbf9c6b5c142e2d18c1917e737aecd756e0f87dd9cc3eef58e2ac78357956b7b33def1e8ddfdcc787745aca2d1bbfbee23abca8b4a9cab9009100b8946ff2e0e1652c4c5a2d16ddc9bd7b89d69dc1ef0d16d6ee7d97def0e2828fac04719bcebc32d4118f6f1a07884a3d1a30fcccd579c118db0375f4970415106711359febe7312040fd2fca3e9ae9979cd0d6351a6b98c1bb6914cf318379459649acfdc505a9169cec30d6552a6c12e20b42cb3e89ad75f6f09be702894674ef33a2d49ee9fc468deddcf8c0cd831e0e514620e9e933833388cf9bb9c398839a8fc9d06f797f5c0fbfe713333573e75cd94b9212bc7e0504e21875cb80de5f99b72caf3bfe149ebe53291b954242632d72d0a69139888adcb449643ca14722716e932b1e5b0228527618b6591e6bb8a144e2af27c951629cfa79e989039ac4cd01c56a44ce7b51b724fbd33b3755a8194624883524eb5e61485279d2ea7d0320bf20bb99ff1c08b459824181f539d29698f12d7b9838ca62217124c3d36e9c08b8f56e89a8863510e225e188762d28c43f107f2a1cd4370c6a12e927a1232759d9993fa1132e45a9e87a74ed6c9a96758344145c523f3956ab552e75a332742a552590ebc0c29434a3dc381d71b76016d677dc32e21f4ac6f977682128c3e32bb81574463b147118db1ce7a65dd1e41afc845235d335955e89a89b95873db88859c8a4dfd4abd1f9fd039ad13196da3713af7ec305621a75a5d937a66034f3e6c7546785eca897bf28cf088f05267a9c0930f635337446c92602c5283974aa5528f6ac84ee0cda7de3229cc233391426d9938a7eb348c9c659417c9abee473bc7711ed0e679d07337b401c42bf7aaa376378cb9534141414151b93c288a8b8aca515056ee72a9d0151715151c6645f2ca9b9079ba601ef3f42a575151515151513975dd10e586d1a5467b575450ae329bec498b8c0c1b99e248d20da19af7ba1c325e3f0089b3826de722acee67d6da4b317878e15bc3895d4e6fe8b9e65d9469de15664e19e52e9707cc9dc8f38633d31a170e85b2ebf44e177a179c35b91cc5558379b81cc600b06f1171b88ef296383573c661389419e63370288b6494180f391e5af8e133f887364d18c6e5302e1406e5d40505bb662cc99ca4b4585a082004fd34005539ca33a688631ec5759fe9235551785991ac7219378c59c6bd2e87eb2898e5ba61cc1485c2565d0eea7a4729ca5d302c63c3c830176586cbac9962baf21a19b605aea01ce6f3a10d1403c01ce532561e63e0908b390f38f45e386c611cfee210047f1cda642f6cf5ea79459f35ce715c705cbf9f38091b9907cc51603ef151e8310e6386c932c52efc95ab7ce9200e6d3e1c82ad193914835f86e85792b091511e266123cfbf3cccb2ca6d9703e53c268e41b95c9a2defd67be6a4bc67ce4998848d4cff72198c82635454aeea7e54e8954bf8ca2c2413ca61ee23ef5d5c365a323c99b025dbf7eae149b62167831840b645c411b37d77636e9b491c95db936445b2ca8d2848564850ae5c94afdce58642d9e552eb7e3a2062b611c68cf24a6f8ece94e2565639ebdd514a557038bf72a18c7261ee52b9cfcc33091b1906675b44d8ca5f6e98e5156bef72abf7b095592cef2197592cf9d58f9839efa7161cdad8802b38047f146af3b0d5c3bb73683ce432c909a6717bb8dd36b79be4f16e37b9426c5e22a4e8311bcc5d721c0e2710a973b2cb51f2c8d19378fd149ee4301ed9db84d68496a7ecba23bbc293dccdbedd26b4902777d6e948398566c8181fb53573fa5c76ed614b9eefc8718ff19a16638c31c6f7d41ea716b598c5182f87c3a0548c31466e13d2e2c482ce303e9b59d453b8cd88796c388958149fe06d5803198d49571eb55a6440193697a04ed7c81893a6d25c62caaa10d467b6db07ce764e2b4d2cb27ce4c2cba06452541212d47cc9131465434e479a8e443145412d411979726a625a7ac92327c8a2240e353864191f8b7077cd4c0a6792912c8f7a27de01a55f4a7081c28c156ab89065945702107a88dcd4a081482be4503e65962289d3caf22c6133d91b02fbaa753a54b757f5541ccaddd9cb94b978e550d6095b53de466b729ce74989c3e7a479c5649a58247952d63b99e64b5e7567d37c39ddf9345f3e9c8c5892341da2f2c40431ef27f440f5da1644711077207b7a6dbb7620926faff5ab200d6875ed94be1ec8e4f436e5f6aa0984f2ed2447aa93bc044726121cb4a5701057ed81b86b5f25957c75168e4e2467dd04076d37f93c0a0e3ac14126abd5eb537807c79df51212ed1e0e62e1208b836abdfd2a957a87836c4d71da467d64ea1dd3b8774cd3b494c6699b46351c8b7243c3964d8d3be5a8152c8feba1bd6a1ac7064aa946351b1f09ce4f226c591898a208c34612d920a1098ada323bf3f7c8173c60789265cc2098391d8b2588441490391de301ed89d4bc78cab2a58d2c652c7c96f248c64985c51182dfcf307601dde3631c34a1ae188add0be5b4de9791edc3939777c5104ae51512b456c6eec7885fbbec88f8b5c3dc0573d7cb65de1d112f97b98f34c2850897c768df8a50cc15739698159698afe02096c75c067f0507c91ccbc8ac1ce320fc95c75c79c422f37d32316fc141d3483c325fb2280a08ffc341136a68beecabb4de0a291b1aea9dedf613c972de8c4f19093a67024991e4301b5ac58e88158cb18c8989ea8e8895636c8dc067797744e05b22993fc1c5bec7e04945d7d8993487dc6fbea06bd83f61139b31e81eec2790beb197b9db5c9aaf89d435f6d9102fb4e996534e3993bab924411bb95c65f7f3249be6cb881394c52f62c51e63bbe56d7e21414bf134d235f6282bca88b2a10c8aecf61952c557ae56a9a73c2fcb3a7b191d726a5b659b501857deb7cb797789a02c979859a96bec7d2492bc2262915d44f6d67e26cda5a9348764abcab21b3b22beb7fc08fc954f2a6d76634784cc5d979df7ec72afb3a3d73a20625e7dbbf47bcb8bf8dee27a1132775dc8c5612362ce720f171173960c1b81bff222f057e415a9a76c74660ecded7db45bfb705291ede3117bd9248f847368285b2b8f54acb548583ba92db18f4e12c97eb732b731b78f46ba33c2d284fa2e375fdc656eccc5b73b1d3ef2bb2d97b9aec75c96e3bb729aebe23ae6cd5c57ca3b26f3d544b2b825417b99fbf9b29f5178d9108a3db126386c451c835713c962ecfd5e25e6cbfed746c727dcdd766848cc1cd65974f399393be66bfbc66da92d6e1b6bb56d9dc529e7ca35df04d0eaf4a9c7ac5dd77c0f22f23de857ef4124858158d7de6375faecba2676454c04fdea40f42becea98c440da59efc1c2ae897748703b12f3b5655b78ae499fdd88ecda7bb8e68562abd31ba19d7516ee9109c5b26bdfb683f11b07e66d355f97bb5e6bbea6906cc33ce2d0949c90d0cb52ca9cf3987c1003e89d99e50ac288ad450b90da6f9976ca4279098fc77c0c73bc510a0f0c47a2cd53c77c35123b8e98af3e52525a626a3ad234cd260b5162befae17c26851cb614e251444abd3955ace99b865cce6ed852c8ed943b773ab894aa39eeb6e6ab3fdf505b266c1678e133c7795e0f1710e5aee12157f6d483e8b7cf7393db2e658a73a8b53da924c11fe47e6c8a5cc47ea4c35043913b88172fad40ca1d3909522124a35c426d99d03a491baa272dbc9999cf5c65e633879999e199c1ad2374b043b58afa82dea9b9d9362617105a7e7de6342b5c5e79778eb6d2c3c36324a90056f3f959d43b3729a09922bd66662e02a51cbe9e8484ca33c789f1d026838f3916069187f76984bdaff54ecdfbe6df2953ea284c4242659abf704b90064bcc5918c49c6a87f89aaf47a67664e6cca2fa1471a89678f00d9d2350dcef35374671d88d2bf82caa768839a920c4d74c29cdd7ac4f11361fe376beb9dd536314b7c6a16be639ee47ba2606c8034d86046f1ed1e059f418cf8e308b5cd4884773ca444373159ac368b0f48888c4f81330afd48bb1824bf3ee78b88f8c51dc9a85987b6ea7529faf79ec7e54594870d2d0e094526aa9e6e6d3099eca5644f3f98d0a89f3f2bc56abb1caebebba5e17ca2f1cc6fc7a8df695f5cecc3c2c1d4b9783c7eb9d69ee23b7a2ed4882f3afbb5121c123f3d5f3853f8b5c9ed76a85ff91696ee7787485868666d1cc6997d7fa0d56d560d59204e70a544b1d0fa6796daf66424173ad4744a406cf79246fe6e71d66910a0cc7f8ec7e78788ce24635e41a5770371e2e3bf0b5065653230627263674510303673d92c3cb34b83eddc0732236c5a21126025ecbdedd4fb53d191c5ac1b55674cd7c8ce2da1774cd3c0f37e65410549f4f29a93e5f6fee8c509c87ab1a222a9260eeb91df30a2e975341408aafeece11d59039750dcdb3ee07c4dfb531ae6a8887ab22ba16a96be679b8aa2750f524c1a9f2028cb976f78c4793d1803b90524a1db437f3acfba14d3f339816e972acb211bcf89032f58ce4210678a51bba661e7665185d337f736554d7c835d821d7fa793658a44832f3d154a499ef9ba1830ca8f868662a92c4692602cc288913caa82c660e1de29a4543be213443f28c242ef02ba2b927127481180899419ad3288923c318a24d5cc81ca269e48a3ca765da42065be439e7ccf3140c89d35bcca0294f199b073f9a228913aa9eb2c4f921cf4f2a24ce4e9e9f1d01e6d16a064b30bc30166519754273d6e9d1cc63607a347394a70c2c9dbae6751f3973433985fcba8c6af9688ce6d1846246616d8c183162c4a822e2a847222caaa077becf5720bd1353f0875cee90e64b5ad7434e05d2aadcf596b77cc8e596b78c11e32d6354a46c085eeb3438e472ebab191c7ab93557a110652282171f53701a19a4e51a6911aa850add42b3d910bc186f799d33ff6e96bf1b4e15dc98828843a585089b3f79cb3c33f39633cf86e0851549f5a4f1f0107ccc301c06e52f23d962074819fc87bb6b42f09c04bfd73c543dc514dcced28a88a333cdbf20de8c10df7769911c5afe3065ea9a99cff0f0ee72e8dce6de38ce9d4173c9d43be0692eb5e81d9cd35c6ed13b3da7b94c42eff09ce6b248e3c04e73d9d43836a7b9e4a2717a38cd6b16c48bf1ee8088711f29cfe0d52c21e2a84827f88c28f88c4f7c2aa17762d1e78bb8ac0716d8e309e209623700a1dcc309220aaecde313b787c713dccee05de5ee7ab8346e736bfce6da38cefd7a00651dee909be801c7ec236f6c5c217e737bbcc61dc169dca04712dcef3cb773056fccabdcc38ee0061dbcab1e10966283b83fdce7faf09b2bc4ab0e89033ebeea9060bc81c160b09bcb0384e9dcdc1c06ebe9b90179746e6e78de84ccdfcdcdcdcdcd8d0ee6f11dfccd755ea3bdb9b9b9b9b9b97977437c077ba24e8df606f69b3047f59419b15027512d2a990c5619192cca208eab6e08d5f7aecb31e3353e801a8f34687c1f8d7fb7ddcfc7714faaa70f8759feae73f0865ecff71eb0e77b0f789f09c2ae7379dcb813f9037d7a3078c34c07bcce779ff9e91cd6e38379e8fc4610077b0e7b4b1c1ff09f8d7f41dcb80d9dfbc80fc6719ed76ad93cddd0f90d1df006eca00e8c32719ce7b55ae03f1c0a01fefbf7d819003cec3bac07f69de7e6336e18f38c775d8e9ec3b0ed818141d42e07d8731508c2de13040eb3ccf37373e3c274be833c18fcc7739f193cb0dff887c319370e9b01e29620cf554f331e72381e7a3b0f5b2578f868828760247a68033bf881f9fb3cd6bf678de3f3ef5ce3e8fcbb6d9c9e7fefc609e21fbe71d88d7f36febdbb2160e06de030e61b619641ecb2719edf50261b221cda8026c02158021cbeb583c3160e5c31781ed8f7190fb37cf3549703761e1fc671ae3380cd301b10fcfefdfb7098848d0c7e060c871c10cae071dcfce65bf77363e3c6a54d129ca7f16042d47ce33e32081f9d1ed6c7fa581feb637d3cdfcd07fbbec718f3f74ce280ff7860e7b98e8eceab76734310046f4010bce17968916ef4dc47c2eecd4dcf4dc246bec1f31937cc32cf7d26cfa5719d5b030f4082f103af4592e03ccfb537d7c2aeed8e060e4282f17607bd3323a5e4795e1289f76e1c2a1235783d072ff8ef76066fe7572dde8ac757d9e5e0b20762065f658cb3084c44c4871f2e947de4142c90329bd382d7058450feee6555ae5af7f361971145c4a3472a2e945b105de0fade592877f743f404182322801311c9f1277ee3870af90b3f90796e8f47122c000907452b8e30375fd1c7b5899736fab841d1c7c11e41ccd8a363d1c7a5f15804a658c7b22e4aa16b3e1fd766bebecf4edec0e60d0c87d4e9a9c989dae88376b4fb897df7911de52ae440e6c9be471fe065e5aaf2aa056f972bcb82d7e6ea59f0d65c496c89056f2a73f9bb245d03de2d57140b5e9a6b8a05af96abcacc75c5822b2cdecaeb9ab8ea3e3c24f45ae31dd3315fb0168491bfdc49a0222a277512c01095a3ac576815db11dc38f4a02b7427eef79638420777c0c793f4cef7f8fa5dd86b7bdfbbfbf9f9f04977301b8dae8c556961d789d71a8d60afab956d626935344dab11e530148b3e322417ecf1c75ddf5da091918f0f2fa1231ec1708ecef1a8d6fa832587a11809a594aaa8ad472c928b88a0182b9ab1a01308c5a20f1c82e82356a30fdc4c524831149be2d1c78d533c1addc81463c17ddcc88247a32b8762dd11141414a3ab8a75579fa211ecf5c90b23505125dbb66d73430252451540904c388ee368d339205504f92a4815406644ba5e3e09e2053f8e8e5c358e8388f83cfec03e2f70f9fc4160a0f843c221f605c141446ad4c04b00f9008284a913068a46120eb16894e296503a1dd187aafb70111d73c17e157681bfaac3aeef57753f7c606a042f01148f1e918e3005f1123a6215403075c240d1c74b2cfac0b4a9d34199888e8c94e28febd2f1ebba2ef0677540c4bc04100e22023efa388897008a468f40701091efd1e81fd641149170503c3aaa4874b55add224d939bdce4110e5eedbaeec98936cd17d37c4d8b747272e2c30f27e133ec294d19768b946bed16d02328bee011068f31785c9a2f18144230c35e65f7ee7c70489b401c52a70f87f42973d135300ed61a2ae91c55c92b0c04107108e0373cc0e51cf7402bc3a177727c5ee585ce89547c5e4586ce892df8bc4a0d9d135df0e94311178b2c883d45604cd50521348f458a3898b879135cd6f9bcada277687cde06691c213e6f63d096068df3c3e7ad90ce89527cdeeea073e214291d73752c0e098a463fc2e8ee889d51075e76b0abd4a88134a3d1edf95ab1d1e846a31be482ddf5dd05fed379900b7cc77a094362f5bb611c92618f4a396ca82c717cf8418a2958f0f9ea6a6969b5d868744f62d5e5e5c5271add3864be608779f3057b77310a5d037b34ba5aacde46a33b63f59a949078ac95d8295765c573232edf7c747612a828c2c5ab8a1771a872b4e2ba8c88468f2f7062c6a2d18b523127a2d1a3112612e6e8bc044c06ef01edc7e30b2ebb05784344975d110d621750113f2e94adf05144c7a2513c32ba11c908e9d1080745a347a4d7e8e3462007f27104e4d1070e8a3e1e81bcc6a31b44043c111db168c5d12502be3ba018e4f1070e8a3f1e831c2856f168050e8a478f55bc461f418ff907c7a31537be007b31b81106b7b6481cf34d9ac483797509faf71e3d70f4822ed30d402807f50882b14123b81f3e39e91212efd75b7938605895743fdff7a17482818f41aeea69be5446805c1514d25545fdb8aa23f355876ad17cd523a599538fa49c668e2a69bea6ea06a79c6038e4381c7a9527884be33eb746a57183788debf30ae2005f7b6ee7ea13a3cfec79ddec773bf09e2b82f3dc109cc6f5c06bdc0ffce682e0b503220801083ee00126a8a82349f9866a337866e0ad0322cbb06f1d3878531de840fc24b786a6d8f77d29168edb395bf242caa47a6a727abaf93c350215458f38c1946f34026419f68a943444e9c6528bc96b9a393c9faf4e3387e7069e577540cc0cbbaa1362e2b89d411084812008ebe1315716db3327e8d96b67bfdb5588dff77dabeeb19992c2caec7779b2d7099165d8bd9edbc4792e074ee32af11a7789df5c265e37d00407985842890d9ce76a1bd800c949cfd5c0796e064ee386af7179fce626f18a010d6420091e2106ce732906305082d2739138cfbdc0695c0abcc6adc06fae055e2780c4052c50010aacd8ef4ee03c979bc004c0abcaddfdc06e78786e6026293d5702e7b911388dfb80d7b810f8cdddf1ea0009446007041ef05d071cbcaa1c574844ba71912e802b04062f90e2f1c7a30b2e519ce211c8630b2e5164c163158f545ca268c5639057073800062f90e2fef8f12302b953dc58c58d2cb831c87db4224890204182dc5615d7037239a4db1ff8930e089961271d0162cf6dc0792e034ee31ef11a5701bfb90b784d400318b000051c61ed771370f0da04240085c4f65c1611f723e23dd788f35c049cc62de235ee017e73815e893002014007288288fbbde7c6cc7349866447808fe73ef2e3e1e939a8a3d3c3a3c2d273759ce71ae034ee005ee312e037b700af43e8304001083080abfa8265bf3bc4c15b7fb842a2d1230b2e51ace2d1c7e314972802793c8a488f3f5e8718e2768e46011ad5a2b621712947e77e8eced973745649e1bd69d631a96c23f276feb95687105aa6d732bdbc962501b28e72b54387c4c9b02b7365f24012475e87043a62e674ac7bc32baf33513b6df79151e9077188bc918f372615f1e2e539cef35aad1f04b3a7a39369519d73fbfcc92ac7714239def024c7f8a951210d473044d89c425b8c54a8f12dd3db56bf9d52faa8aaafd65a6cad0a871cf7d47d664cc246e636aebb337a52e36c81849260ac8007124ac62d343d657a8ece4ba5d99759f44ea66303b69a723b698f74205acadddd47a144caddddddf4a18442c628c719809e3b7757106d24ab1ec62c2483ac7adc4256e16e1921f7d455e76ee7aa82c2e3702894b714ddb230d478127bac15dbb7a752317baa738888d856edacdebd5fabea72797549327a16cb5e7557b9be7bb5dd4f673bdbd2ad72b5ad7aa252a9542a954aa552a954dd359d7bec98aff919f6536679242525241e4b09252418391d24410b586498dc49c8021d72654d29b92e463478613f45a5239090209038d96703765040e228d144735e04c30bfb889993baeaf1482881e7110dd8212920919049c4a7ac04123bee11f3352f2711a40f1dab33b1be0b8855e6c95eeeee4727bb3ce6885af315ef7de6d8e0f9392fb7939452056d64dac036fd28e7b491a08e8d7cdf47ea709ce7b58e4db4b1a193b58d4e838f5ebc0e8f8e6ea76984d48fe0851d158fa2b86c6a984846ad6851e141d1aff60251bf3af79fcd77d69ad0ae95a0e4b207027c07ef9d92c1c947e5aa2393af1cc76d524a29a594524ab9512963aadbfde2324e08306b58484a823ed8478232fb9c19b691a0049d40ce486d19ea21a07120a0617d8985dc0f1b0b12c7e4f20d9038272897a780c44951b97c1212a7f5151c9683326c240e6753dde57d02207158dee5072071482eaf43e2945c1ea8775c97f7660b8ecbcbe58f642e771fc93e12e40980d401d43b4ce4e8ecbacc62fd1d330999d3b1d65c2def1c5d6ee6ba405dd367b94d48b0bf72959060bf759390605fe52221c17eca45b93b24d83fb90d9060dfe41e21c17ec9d521c13ec91d8004fbde0d42827dd60d8004fbabeb23c17e777924d8b7d7c69521c1beea82f7e572fdb75c32e342ed991324cf71328748de044a686f21455c6c9e65264028a6452112173da6d1be46a7bc1d8b1b1632af759bbc2b7b9086b1d074624a29044d0b23b9a62ead748a313221d7c74e427324dcfb3a3891b148cab66c29a710b12ae3644ecb5776eedcea29d6e7b52a633665b69adfae4dd7d4cbcb4496b91bf690ebc4a78fa79276755a1939ff0417d35e7f89b3e5505b2f2371565e0fcab0a9ed91709153726f418404b94a9b723bb772dd2ced84fc46be885112ac4344f24882b5bebb986336c1028bbc850eb2c828b9b720f2239f580de5db7c55157b4aefb2bfb1694625748dc8042dfaa6bed2d86e1f3a167a3835f7b9ce99896561a825b675637bd2a90b95cfaf60ef44822af5130c9eca51b22f783c545ef2faced5c4aadc92b76eccf34ecc496bc42ba92794881643a8bce4dd01a1f292f3683d4585c58445c524a5a5927243151594eb056f5e1e75217162ae2837e97e5070f46256b95122bd1c2175c1b39fb5aed8f65ebed2fd987ce532b17d2649b05626e66d13addc7dde26b86c7fd0deca6b7b4552aeec4282f52ab775a51712acefaeac42d7d4db2ba7d0b0fad586a553c8651d12aca737e3828772969fdc62b924c1fa89a59204eb51eecf123177d7482609d626ed123139bd444ade5eeb99175ec95bd5f270bde5dbedd62ad9369cd2cd77deed769577f7bad6534ade2a2dae92b0e4ad92985b57158557f295cf7bf3259f252b2a28bc9277b6afedb5b0bce5a15462798b07cc5d2d2c282b2d47615971c1600fc4ccf290e52d2cf7912d2c2c16965bcca3f5ed2c0f5b2740eb2cef7ca2b4c47282a3c7c2f2ee7e58509e79e1991ca5be65f2dabdd37de230e480108f969fdcbebbdd351687f328d9e4755e1ef69d71e844b65ff9bca1cc2add3529efecedae51c161cc3c96c8ad1b3a914f5ab0076236f9c90d4d8e62721f8972555178269fb75f753fb6da9bdc6e37f1fe85bca9a0f04cdef9c5487eb931cba421262f387a262626dd4fc9ab7579ed5e2e41979b743f2f57b99de79db956d7ab65b92d41d77d6445e932099ebca6086593db99e576ae292525252e4f79b946fe82659104eb87e49089090b0b0b0b0b0b0b0b0b0b0b0b0b8b091313536ac5ce1cb3c4f5ee7294bce53e121f21a70851f2161c8fdc18156562c2c2c2c2c2c2c2c2c2c2c2c2c2c262929494a4aab10322ba86b0ef9ec3e20eb704bb0be579969b3c4e961b066592cf6b72c3a07cf2d8e52839ca57ee2ab7ee4b56b9bd051649394588122c040547a8684482f55e78cff5ac9aee2b92de59917425bdd3955893deb126f5a477ea890aa5775428a9f994de4975cd4ce99af992ab947cde5e95ad774cec4d2e5de91dbaa2b1f48ec692b97a2773cd96de992dd2a577a4cb4bef987c3ef6ce8bc985691e0ad335b376f5166fbfb20bf91ac2f289044ba72dd42c562f9f7cf2c6c434ff3c71b823c929d721926a52cb25c4f3f6e7a19854b7a13ad462b76b35975fbbddb4b0fd36cb823763ac18915818995e4e61e89f3418abe1a0ec29e6441f39fd3dc502fdb53fe2a7388827e6848d15695bc5b6bbdbe78d45baa6fe3772215ff5342aa16fe615a29dde222ea6e148837ed5ff12153df622dd437dbc22f674d70863136cd03cdd3d84f109423ae75cc424e9435442dfd4d70dcf9c5dc1dbee3d8c4c39bc3c7164ea9afaec069eca52ccbec6d8ee16a0b214fb7d646605af48efa854b9bed6d8ac77341e09d61d783336ebc2a3e96209eaa9a665d99cb149ca286364a2b7638d8390381eee1f316b7d3d90c451bd3e89de99afd72171e2ebb9935a3f2bd7e558659eaea9ef7a8f4f748fcfd1735cc4a459b99638135f6de2c0dbfec7afae8b7bccdc53d7c5bd330fab3e75631109d673373249b03e1bf27c2458bfc23a12ac0f23d31d3cf95087eae41aabb5d67758c7b10be8a7ff297609d1fed0e63e912d32a77f9dec065ec8d51e4534f65bee3ed29eab98873482220320879e7182200882606bbe926ed28e884506411004a9d311da8c4f714acda84629bbbbbbfb66988bdd5ccf30bc375456d69c9749f004aa7388547f828b911015e9c448fe041793ad98046352b33944455c6cf5ee1e763924e91e9ae4cea4cb85ace212346757a277ba2892200e53cb32d046de642722a281598999f3e213959286fcb5753b06a3727d664ed6e4d34d48cc57d6f2a03c2d090d23a184bc81ca82d36e768ee42fd7bbcb74a95309de2592f7eeda3624660e4e52222816491c2ada8a9c6550e48c8b4c473440e2dc3ccd1c30035597e425f195dd63c9d9a5e7cdbf5ce9a2aa18e89aec1ac90d2351bc099b0d397b44026a09ee8709ee15ff6c2aac21c1b59c68e5aed779492eaff7d4058104b3f7cecae5467477c12eee2eef9811abbb38ec2282e42e3782e42ede7bcc93dc08ef2e77c13d64cb3561b9285fb927ad9bf20de526273a79c9b5ce2d2c9d7510119d80f5941311a19cc8e424cf943039414961651d4362beb22024985dcb9a2967530b2fe6cef1d953920407ab79e79c734a3b6ba6d252dc9cb16b7a8673ced9dddd29557767b6bbbb5bb15244da8b1cc7498ee32e39b9451ab3db8496e52d8df2096a25d8dc9c2726136cc9a0ce39effa9c818c9a365bd3e865a6385422ccbadfcff00cbabb3b9359c473ce4d08cf7a7637e6b62d935352f91c396f76a7a08b6177b70cbbbba7aa3b8b5abf6b3aa5491a9b9b93c5ea9dd4b65af50ec7755def6c296b7b87aa6a963b5a55a97a27b3a954efcc4eaeb6ad77624869ec9a7e38e79c5bd8ddcd69a94c65278e95603f9c737a79ce39e7acd2c6eeee77b7a5418d755e92744d8c714a398108cd289f628e55b63f527e763f325422479c754db7909ffce424938157a35ce57e942d637bb66bbe9853a3dbd66aad7012a70a329b736699d6a9c42cc98bb75390c962d05ed6e27e186e6b9dbc71c863d29e464f4e4cdeade1124ee2384d4d9b9aa41aa551cb60e0c54faddf9e047b346ecbb26ca2743fd9c9c671273a347b816a35e7cc4cba9f59a2ea7eb2cf129da9c9962db539b33b6d7466d3b45676dd0abccc65bc79d026cbf22a1eaa4a7dbe5a955269336b9bdc28db0967922a519154cf9eb55a752ceb5512125549ca843bd96248425342533495ac3557fa244a96d905cfe3fa2d27262528275c4af69c5df0bae03d8733b99fa9345516a7ecb2179cac6c668517595ed7f49b93316739cb66ff4084da61bccb82782197b9ae692aaa94fd19034f3e93391d92cc39a3e7651fc9d406a878d292382c568e31875cf6451b8ee49e33c33ce467eeacc9ec13cb47cc433ecb3c64e6c59d96781275a5cf525b2ac5a5b86d0859ece0e449a658884a35b34c0b2430f26c262f8a6043c7064f33059d24752f2d799de75bebb02ffbda4329fb527eca4c4a99c9d972d239676bdd3d63948f35a8a8bc318bb894c5a5ec3cb2cbfbc8c82471b2ce5a4c7169ca6b3fd9c4e1f3748117e32353118913959851ce7b332eb55aad25c9645445ce969666d39c5515b3202232e963dae3939038f1f4c6183b76ec58535b2ac551e16424c56d6d25d55c6024c618638c31c648353925c5e191b8494830628f6b4519e3b3224b49253ea411ad23ddaec8329a6d33d892a4916d06db15db153466469498c2934a48f00809ced91204038a02fd1925912ba594ef963714caaec9acc8a4f25995b75ffbf461cc934a294fa7bc3e335b62eb4bfbf3cad39b6d9116d9f12139b4b9092dcff3f8afa32f6f84ea11f788575de21e4480e255ef21dfef9eaf4419178bfaaa03f5554144381c94baea41dcfb42b1f91d46348ae39036e45d4f475310129c9e7c9c36b91f93b62eea167ab4071120d6b3f7b83d58cf9e25c15b5d3b0bbb88585dbb6b62a015b6d95d54d53d8b5521ed1303ad9ee1a0ecab0769a7178a6de7629cdcea06a635a8a48b96a5b11c754e219a1124481000d314003030180c8805a3e1709a66cae80314800f92a45674501b67499052c820430c20841000000000023230b34d02d8a508233f42b1f2a0375fecb5125f7669ee2f60c582984214088aa6dddb254679f6f2b272eb3708f2994159e41dfdc74528985a52524b88fc02fa7e72393b310ab2f4e13929a4e47de184dac5e218c2741c491931b02130dddd3aa1536dcf126ba3ebfd4cc289f3bbaf225b80e0f79b52ef1589737daadc3a8b60d882abfb4462cd12ae14f115a7831bc420292a239f7daee674553a62e28e67de055314296801937602649f7bb5f9944d54a4b7309598b0468547e276c539a53cce277ec6d4fdd8c8fe06d2e4edbd261012cd6c2017a1c314420d4501f9c9baa71d915ce4aa866ff7943da1d056819025c1a3e1db8ed643d185be99528e22d8f774018df51e72ec4511f5258f418a499cbc3c937ad39c04203371c74470ecb7c9a9c7951fcef19322dc5c331e98ea9f3a397926e1b980f95854461786998d9abfa777f9ef719454ef338b06634bf5dcb29810a45157a54e3368ea383071369ef69f0cdbb1ff8859881c1aecf3f26878c8fc603c4d5a73476209a08ea3cc7329c6d3b5f7c8ce59a8230ecb44ebc8504ed981ff72bd35acc36364a807bd7f8e4da85e144122651ebcd1a5008d14149f15b6884d5a8d705ab27bdf8468bd1906bd0ba75b2200a807ba5c04125e1c6b9a67e02dfe4fa6af466eec45117064ef5ac5e2dedcd513272d9fc92cffd7a209e3fda289a7e081e87ec62bd54b2fbf9c2f38208e41fcd8a854974fd3974fbe6d1011b1d04b4d370ed2eb63f771638acca32e4132fb4c8518142c898a470cee735405b4b8891938b59ef2c578e22d79b26115b1a4ac666028441b4121abc9c3ffaee0b68d1b1263b03f990f8c945f885a920cec952aa06e0a9dd8e4b2a25e3ad9f9f39825b64ce5cb721afcd335ecab93a5f91f91e3cd3e83dcce1305af19ee070d07845a41e07f8ace2e2d4f40632fcaf9784216d345e58fba2311b0c9d7ee8cde1f734f1e0463a93c72e3844c4c11f437646983a52b6fdf66ca7f825c52e4968e4681d11b0e8488886806d2747e17a06feed858ac56f075f2833c16994b88f0a9a0a27880856895e92e91dc4fb92f998045ba2141f8d142ad3c6b9dc2c8c3b5efd1c872dacaf2eeb5d3985eb288ad5bb33ccbaa2633a087c296cf879a1462dcf9250b1a6fe8fbf429d8a0e2b5f2852a90e0eab35b3ea65eb584be46219e4e14157645a47934b60de0acb38bde517b6c995fda12a54403f00335384ff0963d5b5d96aedda631f7bc22cd43309146a841807e3529df064968cfbb763ea21c6444957a245a49039cd9a019efa922b723bb835f5da96bcd6778c9b924d211c238bb75b7bd638afad07a7f591ed65b1821a211aa4206eca38e0d0610681d0296209c02cadafee97f13841545b56133a2a56f466e6ec9179e469808b86713f3aa04fca986c04087a2937eab24c5db0ce63b3a16d385e2c004a242829cda4e282e9396acccef749bcc99136077ca87c061cf9721778d063867b08ac6c4d07c9949a50988e55cb40e5261aaa70f0226189d0193c4da34c788d5df32571c2392e48c824270ab9887aa1120b403b9aa6d1dcd8d0085204ca6079394db9a45471672403112d6b8e80864cc3552c53dc0e21bc09a4d68ec23f0a1939f3e1879727a24d842121814f6144029c360ca3921bf8de7ee1e62d4163a093a99dc3bdec05347c08d66117642fc3eb5b98e09c287873324a57ecef3dd4c55820550e629f37802a63d6000ad956b09a4b4ab0da24021899d70f06a33ee616002af4b32a5dec64ec5c69f8cb1416e9dd56f7d928392a021218d480c4a3d80fece2ca37d3d3a28929183a1ed42cdaa044448a239704dde5bfb0339bf0dd6f659464aba40a43a5751e13952ee1c2f8669d4d9412c311348a995e4a697b474a50cfd24698536a1fdadd10dd501e3d38da5f2adc7e481e96252996cfbf21ca68533c1c1f836dcfd4285fd778241deebde69a95c2e5a38fbd0c5f6c46cffed173654ec7c26570ec31ae5b7ba57947918a967b0c139a81c2cfc9105c73326b3460327091529ec93e38e07a719a33ee7711919351b82dec25fcdbcfbb8fa7a1fc06785e2db1b190ba95ab8523a1d7a7a913d977b80af77c884240dbb377af62b767eb72f4c0e206e803c24fbccebcd81b31fef1ac258baf43902dfd35d2cede0a4a3076e3bc977bfbe6a0afd0255b65df0495d7db8a96617f2124cf20ea9ce007d7ddaa87b4e9ef81050967e3c32929877ac34d2acf54990e6956261a1c72ec635064287a68dac969adf594cd5438c76d5b6d877296e8b80329beb5cdb31929e165b0e13cf44c50e890ec07ec3b474b80533e65ad0c3bee4d6f724651cab8a8e44be1514100c557664d1ea0d4feb6cb2586a10f28c9a0d0bcff017c00ba99f5cbe693a4fd679ecacf0a4986f4302693772b5d63f2f5000e35a3f375680e145b09e9156f06e6a4634aa4a0caec89e6316261a7c4f3e5d1d39fc1b5ef470c7eb3f35aa1777170c1a75202ffa4073477748e03978fcb20844e5feffd112d44e79ae5eb74514914bb614519f117347a65915a327d7d211d16db366ef3107f399d0421fa783441ec4626d59d9c023d32a3cadf37322bae65b955bdccb43742238ebac44b50dd62f1312b33dbb56936d238d0ba9fbd4a0293d8106e97aa54f89d94a8825c44a9ed8d190ace18083060c7bd643668cccf71b1d00a9e6be4be240c22896e9d26c3bc4d22ff47ddd50967f91c06f6a3a70867ed25db9c8cb8c25e778b1f4bcdc184a82ab4c2f78658979b415b7997d64de7efe32235845843eb0831c0bd172bab07b93126aeb0825e3abcc027fdce4124e089294333807ea3d29f0567d1c523950dcbab5b8d6860c9157f1efd44c767ce4e7d630b0dde455b6dc63b611ebf39c88ac80152b0a5678279a85ecebe48f0ef3ad248c03d99432f366ebe204c3869129eb2f454556ca7a8b04a9866a04f405b67a7ee53d5f4bebf9c92402c1745c01922b238de2feb69b70a1999e053a16495eaf2bc69072b2a39ed13030294c00c3f8b14cbedc7d0c72b8bc7372a4b87775cd14132fb18cf8900667c15a63bb763cef2b29ab998a341b965d5dda1a55f47595ee6a54f632a8ca1195583d5776f42346018d75445d534709aa648555a3fac011cb3c5fa0c609774e70f58b79af8038525fc5b968823b9673a296dcfc65649702185f472ba2199e7d61f4f88060402f5e955fae350353622621c2ca09054627d88842fa4567c185b90d19d690326d90ff607026c314c57a0886ed7865798408e25dec077239bfa486f79f268b9a840b0169791d44e2e7ceaf78b311eec984df7cad242f06c54187aa8839074fc7c05f4c7867b17791d73830b74f1aeba86b54ada53e66887427224b721a202ebb78e1e73a2b84c47dd4bfc1ad731d859ebc0a681a766bf47f877880d02a47e5e8c472ae931ac463b427afa06195b35fd5500377d52f237e5dc05aee111cc2befa4f37ebdc7fce7a8e599f29bffab77d6c46d02314e63748b7849112aed7b70b27db1a32e654175d17533b7071aef762429d13b6cf933fea84dde40db4d80ea21b62dea40f3b17b0bbb9442fe8029c8d331197ddb20ccf9c42c5275832fc96fe5b46c7726b5a8f52006510d53eb84206cac04f0f0f4aa8cccdb4a351744985b2080880286eb00920a258a554a78946b6c6c03de686b8940ec9725bb310413a51d6a7bd8f3209044d6d20411579809e6bc1c60d423a8359ecc3e61f5d7d9eb7f8eab9de9024dbdb3a0853a9469725089009297c9893f63ee8a34e02e62890dbac737548fa14afd34aa3cad6b2ba2a07f2ed8dca0e07c4fd4d554be23dd1352500eb8951838275a9bb982420f37e041ee06c29eca640da46968d0261e42eb6d2a8dc76a14ae31877eba67ecd0979cf26d82b8f1e774731a06ee891b5c5f21828d9cb0f709ee4d482bb16860fb1e12e896e6c08cd2cb9cedf313b30119dda7883fa67a0ea08ffafd28207768e088221b2d14869e84c444736baa1f8acc73c3175f8907270d551a2d84c69304b8057e9ccb59c326872011783604a4143b25ba67c04c73d8ef355f9021baa1badc5a8a23cfd6c933cc1889ed98514f14b519c09741b3d7c7f5b8093c2ed2802b75c5ea8e14d3e2e368f73dab2ecd4cc7ca968a9e40039cd7656b4ab19dd97d2f85b0b470a004a9ad8478704186b70dc9fb6bab4d311df97213f0ead87b0d9f1f8da98255a9247f49200f009e2433df108f46da20476d88d1f6a8b898a331beb60150c449b9798ca32f2e3c2f3380cc51511a3e894e08d13a6e35453565cd4018b698e2de1645a00ee83726e4a8f8a5ce85223cbc774247c6da40ccc6d5016378591ed3135bbd38b9e1e3a35f6f1cc9143d471882d71bb515d68bafa8c7acdec9f7f8187342fe6c8a6c9cbe4fb92301b5ef966bca2d4fd7563248be2a91a14723c0daefcd1e15a767522d5aec60b96b4f8629332ad8e99d0874b635b0910e30377ecfca58f9128e11cc45be953aeae83435686b5b3d0a611565572b2f2f5cfd68c919541a2b0226f9633c8933ca4d30b5f38034c2899ed440f5f1cce1caf0934fa453475c1e548a2934a601b76151b56a13c5aae77beecbd2716e964136b63ffa330108fd70f91000942164f8f2370b8f2942f04d31f2224e0e4f0e543f37f8f386e69bf85713481087b0b9c37cb0dff66234326139ddfe5da2379adfa2615a815013eb2608c88847d212df0a3d67efc5eac374f53c78dc5d76db49037aede50b1f451c3bc50ae7377413aa13d201e60a94ca71f0e5c71a34d070404fe9bca3b952929659f5a04b940ca9abc7c8a4ef957f6d11b7a44ca760b0c354449e428f13129c611a2c42194330fae86b92999c619cdef941e728d6584512f49d7d88b029871d86a06a12424f0f1e40296e1f3c6c1425e93ba874c7c265ef5a210e33b47f6470ae8c93bffa8708d39662343584a5932f8337a646fde734ca4af9e70811ee8810576f9a1472e5995ec90015dbcaec8923fa149b07c285f210f8ad7e5ea357c971b30ebfdac44208e801b4531ec3c369d1dec825b364b2f18ba86320a132365acb738d1c77c828f1e3d95ac479dadb721ec96510b44528f432242558fbc4468b26d681e44dfe17e3a6fb0e9161b52fc0904341957db89d883ed5bab6b925655879c7f79e5a02e75aad7b8a7f62064c07b5032b80cda6e66333898f6dc21ac0a8cd5d882fd309480eb498e6d5ce911d3227fe88632fedafb838148ce4963c0247537bf258af44762bd17c99f47dce55704943f67b389b701a8ae2f0596efb6a1c62af92b3dc9e42f22d4efd8e8555bad768c94bf86e05e100698ffccd8056c46631ce205310949bb44cebf4b6b3d7d55562829b7cd108d6ed454e56d5888868e7196e3306ac56a81b3911b39b5644d27e43607799ecc91755f81d879cfbf105c56ccb7892ef253d1f5135db85fd5dd0736aad866450fd02db107f1184979dd6715f9f17ba759d29b1444e8139e8a0e8cd023a3f029cef0e489bfa91392a1eaff9ce0ab773aa1ccb6ae5ff6562a7be393c149a5acdb0b9a041880c4ca337fb4078c91927968442071e6f7d9fd776f7cfccdc3d8522bb2ac8015aaecae4de86af0524837f962a8b275e37f7d64e0209bf2fb41f9b41e0f7bd251ac9c03a10cee6aaf89ae8534eca6e8eba42b540596add2599d15805479a113ee05b69438e5c3e97923031edb85164db555027ba165f8f6c5bc6709f6ba64eec15fc849d08f0746b285aa6950b66fc99be511ff3348501c1f3bd9a2edbf4694d2270ea15cde9ed7fbd320990cf3ab23d064261f00ff9691d83d0d8bad9f253e434c16b1d8c420a7cfb7ef5715b85650157612ec059c3343b225f6f797045052cf1b373991027bb9bbecf5eed21f9607bd06c6217db903b1271563110fa04bcc575d1bb042b7a7fde4b9dc1fd953f0f6399c2ffc5a292451c8b0407f70ae645ac28ef5d0cd486bd967c2d645d087123fba51516d0fbeae1bfa59e50379d63838d8887df427fe3d51073f3432829463b1236d694badca8f6fd2280b6dae0362ce924ce3344eda9ba2008448ae5574840cbd7ba79761e43f899daaf30f9eb290d7922950f9d0033359df7478294c1483feb0bb93832c581b9b83ca7ba178e92a87bca48f865a908a3d3d9c3f00d22e93de331e96c382a6542f92b209ab60f2a5e6ad1086219bf23c7cd37d0d89ba95c76a7b25622e9b38d26220b7e50ca14f2eb89cb9166869165b7fb3f8c7efe0eb24c3d5898741baa01bf6cdf9631d89db616faa1e76159380638a9567561522c870bd7378711fe99e7002d3091b1d2b344387908cf6609ff57db87ce86c90bdec0762a26634423aa08818d8582abfac4c2698f0fa9cb0f11d85ec4c79f4d953c07a9c744c88b4fb72c56440aff170a20624376b974b0d3c45fd1136679ea27ee052d505125a5931bb453c8f11d8a721c2b04c6d81f60d37305a2f61103a17951e35f3e47b3f7dd1eb8f88721b33c5da4087594ccf9f04f4da557cf0f2a42d6eeb82c9a4b582a18dd2adedc007194a1e4f76fbbe1e6e23b56d50839c9d460171135d44d34b504ffa1965847cfb84b2ad7bf151281002f3a4abf2585b8b9bb8318b26ed9382306924e7eba754ecd3e8a5109b96138db2d20ce20a0dfabd4bb4a3e18f0629807753b8918d20190186a6761cef921248fae880eb937ab43ba83d738bcf3363bffc622fc78a45546f3e4ffb7ba7259c9e753124ddfd512f1cea1841fb28021484bcfbd46182a01f13e9a0ff30732131f4ec9308b1338b71e9ffbef505c800ea31eceff955fb5e1998cfe3e5b1f25b4c6866fd32247a2c94770798dfd0b8281f70f6c56f56937bee4705eac6ef0615b224d67f01fdb7eb416d72a9dcdefe93349c0cef9e2ef603649e8812c0e6c3de1c657cb6cd384510f1982f2a2b72117128fde01668d3822cfa81ed34524aeca34853461a47aa22681facae874c5a76c7ab9dbd6ce8a68512dfe7f60dd850c117896f41636639d59b6e9402dc7e7f5b24137c4422bb9f1581ae8c994cfe02f0d9067cd98b2bd02ba6dbcd9254bfa3a912cd4a79f9567cd082cd12974b9a762382ebc10df8f00118118e9a1eecade0dea948cc938d4ae5a0a88e429881f79b33d48d9f6fec96fb109004799e0685c284cbabdaf8840c48c9f3df6ba9efa13f6fb3c58824275bf6591a91c286e0eb2a5fbe575521d77a86d1c2dd6367493b7265a62f5f51d89fc244b001c06e4c962f9c70f5a8c158bd8a8757012ccd4a08d157da746da7a3e9312771f1eed12a41ef09a2185403604cc0a3492b40109250985f2c67d10c897e182118ade3cd39cf47c48578f019f801fb75be0c3b646cc703b6d76af633fa176eed1d81e9adc977a31d0b258b179728c0fdcd1fb93c49cc3d91e49e84c5623418b2306117553eb5c88b0d594849d913237fc14efcdd347687504f85bb8ec10b7b7285a3fcf7f811528929f79e3f7e2d99a27d7c5d60c11dba3fc16331a78ba6bf121015640b9219405d16ed780a9b8a7f851ac7aaefe4514082913838069959ae17dead5684026c41b047fbacd9a18665aaea58a49c061e63c0e45abd0bd543f8ff882e3cbf85eb4c0a4407aef454ef34fa8b4ad121697232da2d7b57d726bb21152f01ad9d42fbd9b7bc6dbb846396e01791063f2083ef36ac54433215e0dec03906788b156963094e14542305c5285deb6e75cc09b6e9d61cd76aaa3544d5e8462bf11d8737a9f87da1b11f91a19defb95fce8f0d5876106e2dfd6e3a745c6f7d8308b2b6ece1b570f995fc502e58e7771077e0bd267f775a1cfb7b402015a08d89b910f1c3cfb1a9675b3479c34af6259691361c46576ba12b31d7c29fab54162356877bc2cedd20ab40e0e39bd858c8b0dff65a56c7d9a803d271c26b3d99c31452dd11f5b486d96f90e413fab8d92efb17013d8d14c66153c53ffc7b4a3b176d2870f840315c5cc0bbaffd24389b1e484aa096e69d98ee8f613bd6d94af52f04560ffb40b1d444bff02ad2af70c189209c3800491660e2429fde0d679e1bcc92c5bde1f12c704f622073d2cb4a9c3223560149317f4da26379fee656279df88f758bc076c8f28292989175802e70805cc3cff7323ec92f981c86cdd76d37f4f56bea6899de4581f26bf2868d2765641c8afd660f36d3b769631369b748243eb2afa6f50fc5450b58a87433ad4929ec30f9c7abbc749db2bfc2e7944d0686fa64cf08c36807ad9fc62015dea26d6d13cd03a045169bbe4af160827171667a5f3dfa4b4f9a49610287fbf1a90dc3c22c2cbbdca168c9f6a921ca6dc61416b5e418d4517fd8de2bf56c62c95d5a72c9563200c159530cd7b1e30fe0a16a60979a6932cc2897de4e2d395b65e75b91cef2d856f8f65f55adb361691f57608c3cfb4d050ebd3eb99ca98b1dc3cd0322c8104253cdeb061914114926a57db96158aa71a60393c5f3c219764c22ec7884a27a110c90e027a407ff660e926084fb46c559e9869de81313f84198e5780653476ce52116e9e2b5b28d38b436eed33556b9c0f87e5de1d533f5be9ca1020d29e153db3b7c7a118a00cdf40d0f140d8582b65cf6f33d80f8a6139684b77072ad8a807609d90a7de8f73cdb75abb5972cf4e9239256c77cca500e587092f923836c01a5e6f7fc3814ecc809c212018d55f1e0d9547001187dfc825ac21c7e8666fdefed17268ac2ffbdbf2f776189d4e1340e8f37fb7ce85f0f6bec6fe4a5944ddc15e61e213081c12f5baa908cae87588d5b2ef9394b196edee8f1450c34a77a444d1a398e2a9638660a2a923bbc09f864f62093b0c2fca758f655957553522ce3ba4ce9ce8e80b1464607b8f3b969b1a8f5014f21613b694c96f13a29caa6adf7339ac6048af9a2e3ae06e8fdf87066be44ea1755ae2b6466574b36b200beccaea2d57b8e268901ba020c392e4370dc6b0f65ac925f8106b00eddd0b3bfd13c05149e34dcbdd0854b53d1c66b6bb81ec68b261ab87b105a8ac0a115e1cd4586246d7b4d39e45c46b4c94f42c52f955de0bc60b1950b2964ae6e3a300d5bd5f1b4621fc5d1428178b3247d673916e33981a768d6982e9b9bf49b8af04cfd90c57f8c63ac19a9b2bfe60681073230aa9b9cceb00266746c1d00689d928ef43f96ca99417385776850ff82e08687e97c608c01fd3536637e72b53bf72988951bbd1aa5bd4d3bee27d0a1c49efcc5bb83e7c7aec699722c305656f717bb43fae17bf1943db44b0ba4a4ec0ec5c4b73cfa69fcc9f98261a2433671ec8b2ceccb034e916bc9e91364a3f355685ac856e82592e719391a0918b11e86ec9209a1e9654ffc65b25ed1b3dc00f935d0127a05e07a9a9a7fd2bf3b43bf3dde90b6400bcb7f427dd13c0f2a2ad7e7787c5ce2e460c2d69f5edfc689d622d51741a1cbdb386784628457ae9fd2e25a04cbadc19ec526f1bdf84d383503b835f0af487cdd1a7cf2b0053cd2d8e6595fcc7ee246b1f4e196f766e0e9c45e15f945cff2b7f65b3db09cd84c30b4b18b73af6d2c0360b9ff41c5937c678753df951cd20c0b7c3c37baf372cba26d509f8853ad56d1bd2707f93558a44f9a2671dad17f5fa95f1676e78b1445e1eaa1df5f9b1e77264a95cde49fdccecea5d829acbff0a451db05cbf233f9e80dee2a66baa339e0748a1e9b6f4e9e3d888032c57b813547e4a7319342dbcf324345782b7baa148567af0261ec580a311cd95c5df4cb056d1fd68f7568b859cccfd6d85e26f2dd943a340779a2826c9255be31626ceb2887f4ba814de8be2684b365b6d281b8b4d8be7f7385c2032ed481712764527d6b3f3254cc3cf0014e57d26c23e475ac1084eb4a8774052db0ffb9908b099155dd0cc5229b0ea174d68bbe5ce7f2a5679c6578c63e222b088251798d8217fc07da34340b0f087698fc29549b70d5060ac68571a88af30905325dff35cfbdc744acf113af57aa53c29a0201845a10d7093d2b305d110ea5b5ca53ff7ac4b8304fbf76ec3b2a5da1b105a58c7f7bff3025acdbab220f123eec0693dde3b6855df2bcfa540c12e75ae0ef6275eb5b735ab58a23a27f46ef7e93b0900bed6b940da8fbf1eb98156dd8d05e2a054fb66ad2f661325b39e862304bb255fde4019032cca36db1d6de8eadc91f2e4a7b330c1f3e421d9ee40f522b6eb02d19a4b1a7e1ad622388fc944bfff94253c225adacab7e1a465b9d77ba0379d3c7dfe0daf7deeced138a919d8e3610637a3a7782d6eed00bdf30384fc834526895c95ab9e18cb6e6f2e9dffe01c33bf219fcce9d641135daeaef2ff24429d3a8ebee681e723e8c8db68a2a067c55b7358adfa6d86d1a808f20a5d87a8d499d6243af516e5f40ddcd6306e121199edc4e91f0334fdce88055afb444b8648e4d960ea229fcd060a731cf4bc087ec172515b904cc24732121a8065a7f1a8e6e47f4497de750d334c583cd1814fc16c06698bd9db69b1c021b74dcb0ba8bb7b28e42606fe9ccb2f6d935e49a9aecaac8dfd011ab316fa95cf20a0868d1134930e08d54679924920dfde1ebbd76b9c9ef5bba6c6929630916ed2499edec1e7cf98909cb4efb8a8fe7298f804fb9e8da63ca08d4dae78bb1180747ce073c8e1c80ea8e390166d99065cfb4517284c267f5200851f05e59fbf141553c610e2cf5212f2779bf4e0e89740846062a68aa65e1db4fcbbe29c2309078a030edd823e9a6ccb19f98b2a8c57ddc852f476220e527be673d4a29e6b34a20b1478bc94e2e7b50d12fb45c3a71aa2eeaa6373a6ba374371d70add09d01531b22306f9201f0000171db845f367c02c1f21b611a9f320ccf25483e5dd0abc90479ffc5785be2bc81428c1699b17c36529b35d3c7d9f1d9914d3a6d1414679c6f4a1531c3c9efe61e2d207e97a89da5cb697d5274015304c468f19201208392516658e5ccc8ee51044777a9393cd608b45bcb94b33451919853e04c0609540a46346ffc9a659de21c1189886c0bab1179a0db2cd8038dffa4e87c53dee80bee2e7b68cd91af8dd6bc2e671a0fdc3d8e2f5d560e7e30a640ddce2140744459a5ee4eef31e5f18fda2ccaf4747ab91bfc904fe487bc294b9b6e525c2c40e4b8a4dbd59c7109844e569924272aeab02c446b6e9d073d7c977f8762c2a4c265e017f11636eb104ff47d8d09f811020eb2d2cd601309ac517cd6e996fc5e1690fc0f9a85d7c7507705599a99d3249d6fef878c71f532dea4a7d71770655ec29ceb7ace9587bdbb29bf9a50de0bfeefd65c879c9de85227f9e1724aa71084aa228956d9f5ecdacf00c3d4cbf8fd1db6ee8729c60a61f9bd8d3c300fa0909aa5307b10fef52231dd5fd4ba983ca3dade4813d0ffe84b1d087d7414eabc984d724b6b24afa69ccd6904222afcdb7e695e0ff9e9c364ed42b0e50d83da4b189e81c0b03f4c98a7985cb8b7a098542f60a30aef4b57928a84e172e33a21e21e78c237589ca75e8c6ee7c79e0cfc81069b83880d0fd8ad00d55e176a922771e9438118d81d7c8c932f822a638c938413929a39cb81a0f3c1a7d4dc3c7a63e1faaaa1fa2731a4ea93b49c308b44e09fc641b2aa605a5a60adaadea8444b4a25152b6b408072200f70c9a0747d1af607568dda8242f09f126e0b7115e56b40b36ff07d4ce1429a08f1e14d82455346fc28d833609516ae8917639556d043bb5d3d85a50f5d5c0f77d83f8b34eb9df00a9f65139ab00f745c9dbb4db87c08fee75c3f73d43746162abaace8b931fc66a8c706d707b286dfb2f7d3907bd9d6bd80a341d602303d40ed37ea6dc3e9c563dd7f0e0d48e6463a02bf10486efd0d35f3a2fb4e90b9f825c9117e6a00eca1ce369500aa1240311400c7c401b446d0dbb45e7f956107de97ad9e20c11e84fc5283f2bc858cacbea6180a8b94ebcc5ff7758ab067370fbee35f55e20f14689879ff770a1e0e5d5cdb0903a4c74340ba402f3eb0824ea9a7ec3c67ad26de5a3682cfc79cbcef2fd14af364847a26de2bb6e8227d0b6fe0a7f4bd730c076ca119109802f235c3fa3b9db0310e3a2001b776641328aa43bc1687a597759bf053fa858008012d69404c9ab885c413b38fc6f42fc45d94a3a49abea18a3a887806c86e42a44ca212edba4584aedc8303118e139d3b736fa8b8528b6fc108a50609126538a02e3d15df8eb732afcc29ac5026857e13f146b1b75e6a1a5f8b8785536be38001abdbe0235011dd1c708dd851e1c25ce5faa813674925ad830b4fc08cc4a25c2a51126de5bb9543217e1a2dfae0aa0bdd3c5ad9d9357ff16072dfb97ecabd1b3d0357360eb6a8136b90df018123a3a47765b0185ddea69430648ff2ad2147593d28566d60425e5dd7928763430991f44c63077d045673c684ac81048a12b30d29c87edb2cbbba104e849b0eed2550c42b8a61384768bdc92bcc6f3e880d2647c4bf55fe21e29ec021000e267eb0baf36d61f8665eb0b05701e27dc6dc9f4d80e1cd99ca23a7d12bcd5895337fc06d24cb12e7a5fd467e07c63edbc2e49027cb31cda1f958250bf4c51260667650932e69a9e2cc454efef00a0463a69a1df1c8f43e90a8a62d5aca1efa9c3e8b48ac6615d35d6477ec22347d4a8ac230d11e08868d9c105aca7837bbd8d2807b11397104f43eeaa1f394eac8eab3692e35b15aa3d14a18e9389050e0ee48dd9e25df0154167ef3a90ae11a8f7f5d4cdd6d7ea88ac54226afbded01b87738d638449d48862c9987d88a90e97f436d145512a4c2bf796a413f932c3e2ff21963b4279b85d5dc0f56f1ef8486be0ce75a1a03a434c231bff031889234b8e77e61fe14a743a8e5d1018d22098738f297c517eb6630d3251ef6f4d16127059814b1a0b7cd9c0131fc4a9d36881e4c7d36c01a95893d6acd02c692ad2a381dee3a5267c987862ef3499ca9aabf9be6f09bbe396dd98e11682945ff3c78a5e17b32a2c59b30ed3ec0f5a2a402a59851cdc4b7f7bb17a1ca51a521cb483263b0f3ee0a32e23c636f1b105d67fefdfde81ee9e253a75752f143ba3d8ffa21f75dfdb7a2654f55b7cba060aa461681df7ab95f7558b84ec878d0e4132e23597ba2e96c04fdbbe26181c872851b0efd400c1ae20e2d0272d781235bf41232fe4eb48a88e1a7e1f8cad7805423facdad91b73b1c21e32735a325604fd16892392e91004c56abf6b285338e5092ad4d33d72f4ec7dd2c3613801b15f20c33dc5847c3c9ac66f972e93dcf7022b91414ae0970ba5e20f83c689c4fcf02fc1ecc88e412541a72e0fea5adfed10864e22b7a8480f74b639115205ee6c07b62e926cb9948d7e10b997cd6d13537ef52301c0706e118b21eeb7239cd72f76b7bcbe13443e23b07ce6578f3a3a46bce6ef267c9cc316e3624fd5c8d2dfa9d86d5e27d62d535408d420fa61273ab724ea7029b0a3a742afec3f285f6dfa6fd2b8fa7360447545d6c435cbf01874a94cf652422b5e93a5e260788457c6925fd0bd08ac5a25dc7181491943c1fb7601030e66d13bad3b6406ad745f0b40209704b054e8994b839b00adce5514eca46b9e0408cc262487d49c263400d62c40c9f4f6988911433588b8c597b3fabff2f9864079105cd451a4abc5694062cbc93d5f7192b9ce5e3afaa78002835cc552a1b495dca83c0b292a158c8c53e5574e1d016450d0322ef35759a2845a4729a3ce9c2a2ee4c3813a08a06949b158512a1591121cc309f9347f60b5791e803dd16305c5c45485769b6e03f3a426c37f4b0e1c8dab73854f9bfada800310b7038218d17e15519de1d6c2d51f76291b6e0e6640276527512ee9e5dcbdd3c519fb30238b7a7682d91a21b819109b5213b8c57e1422fd5d0da2d5aa265f195dc144c7af09edbb69668954df9036f6e4e691eecd3c4f6e3b352e4fd4af7def1eb183717d9c99692d490989f503579422070ec619d9ea12d9a6aecab96e1ef8fdbba212c3180b0875b32a22bb05db1c38f881bcbd5dc2108b274077b0aee006382ae7187de1d6c3c30753882d3bbfda6cf5aabeddfbfdc4accfbb50d9e238ed49846a4c60d12fc13331c614a5f2dfd2020cd0516df79038b08d9d6eb991d3b97a9c622700ca84e3da513102feedf1d484a73f00a1dfa187a853c0c8a632bb0ff3961935fa4fc0e20725032af50c7cf921b2bddea27d59d9d7d06e7959dce9e4d14bd85201c2d43a93b7c14af73699655a8e2089f620758e92558a1512bf0ab416043d801a1da9df7344860ee713bc1f7ea9c89c436df14286fb5e813b10e9998a8c21c2d53bc879ebecbcb51f7f54b6fa0af1cb17fd409d5eaa76350da490f210b6b063cb44ea82b7390ca6b2f4b08cdc1228025a1a1c7b1cd232418222449cd70401638354f2f351a7be0df1d19938544ca7abf0f40366f62129a067092531b8b7be20645f3378502ff6783d72e85cd0861e8ad72ce2746ea5108ccfbd696e1a4b0ff02da5d5d7714d2b041cdb5a23cf00b94f6656b2265d8602d047d46c31ea0bb5e029d28130386bc5a13e887949845548802421cb3c5eccd480ca97c7c25386a3e3bb8ace3cebc099ce290426382ad5d8c29dfa92458c90121aca9bb9d37c64abb6f173c8bbfdf0f1fda053d288fb63c1175776ab72f5dcecc897fdc8cacd7cf72eebd5615a3c5e52b1fa410d94675f1012d25afc02b11ebcd611312486c6909a58b86a55bb3eb40111c2e7e20c470c912c6d13551b04326a5ef79ba1cac18d2cf2252ad12ebea3ef5495c635b8ce0ee42015dafb1dcf781fbe9de43b38a7a6f7dc8e83fd35866dd8d07551d134e3bf5650136333203021372810020a70b5cfff643957e2187f40138d6be3a5f0d01834ba996132fc8c8a18cdd50d7c1973473a87f55aba6f86503e9dfbd9123fecbcf1a462990b6483f4eb9f6df424c429517b9e7f864c559089451322932afca83113e823642df16bdc59c0e1344fa5364b28a8a1d0489386375e274f9890bf08ec3f29cf3a339317a51442d187a18c72a8062b9b9a785f4cc84e20dcbd7a2b7adedfcfc79e5ba7cfebd2dc82fb2dfbf451ce38f15312eb5ef341140a761cd2a098e8bceb18424221da0d027961a09ec5f7657d685a85f246da7397266310ea94e620cb6fb3eb66b8b1cd143b8abb79d55dac3837537c4f3622944fab0fa4cc2e8eb791b66d354bbdfd02adcc84fae276b6fbadd357a98a8c1d30f653d6c86855a6a7e0cadd166562f4372ae5f534d50ae414b74e89e27916459e52aeac3420aa0b14880e272bb87dca05116b3a0786509d13224f3b6f6c7b9cc76090f9b0cceb3c84d07cb38ac80bb5ddc57be4abe86fdcfdd5d0149e22602c2c782c6e8db8dfbb72072ddb51b597aaf7eb1a1c033141eef9207e3235998abb67526d52ac859ecd8f373dd073160d629b9bb25173244dda24c9ca36a7aa55292ac99fa13cec8f7cd7ba7b30d98d595e2193cbb5f075254bce3509625ef1e826e532cb165a5089434bc8d3ca0d6eb62990bc65fbd776c71d2732295debae47722e8daae5f9f9098fde152c4bb7d65596ec0d6f890c28f31d686ed94bf204dc6175f64a35b75024cbdbad49480c4331b690f5731ab88a8b5179180b3a1a1164ae3ce6b4f91671e65cfff24a56360374b35c4f96a7c7b49be84d95c74848f48e76eadc08628550995c0f9bbc51325fc8381f69b2c1824a1052ca8590d6170a9a581134c29a1c5fe5b3b2e0d7d2eca055c0c0ebf8463d2789e6f67426bce20b8658984aa88757154060fd3bb99c13ce61acf3c28f896a548f00c74fb146028f0c39d1b0a50ea5e89724b69c9742e95fe230050c474c824970bfc9d254820232165e9757866895fc3bc4a8c2014024787f7e92d1736f91d704e8b16df87bf7839431184337a692bec0cf55858a2f85ca2f9b8517bb273d0e0278f178cc529f14195a01a5aee516dbfa11cd669efe784387ce460e83c24024e7cbf30acc1a1a6c0f12f853b0ae4069ddf71d8df55ffdc42710068f80169c073109d4d750aa8a9933252f2cdaae8d0d99dea25b0e48a09aa9fe02beab76544868fd8e8f8f5db3528844520d7731125d217839f977017338477912690a8d885bbcfb2f30097da8f7f55884e439cf2252c35f368ecc5e61dc63f29125aaa668fed40fc009b9a807e9fbce9629f9ba39635525fc0284b3c7d7ea7ce3ba0d63c97bfdb026b92561107b24b8e8e19cb2b9a7d37d27712d6370db536ccf2249b32e064f1611db7b260350a12fb904cdc9655d1dfb6d02f69906d838c1e73cebec06684f900c40ce82fd1b5c55d0bd314557f9721abda9a114c001ca9db40fc7e9204822bcbb019a22e55385577421de2919296c2c338b9d158883f73d0d39bf465226b77f5236807918fcc3550394e6a8d9c0d16a42822b4d52fe171ab9b145840e80a80a7c63bd2e8e38ea694aad53f2e8a5002acffb7e9f17ad5c618443e2b3eda95d8c889ee6328e1621071d41b8ec144370cf1520d28360b47ffa727344a8577715515cfa18142bf3aa21b21eaff73b2e49a2d0a569955269b709c068eef09a49fbd09ca5cf80eaddb1f72f720bccd6049043c773c5ed8be0f56f4002fcf80867ca45c6f8779493623cf376b1c7a59530e6cf880b11fff26160b945b41727ff98e4103537338cad9e5ddc152fcd43f0f2db0432293501af6fd222fa302a29e1e292c1f500148904e9810b99da0809144ad5eeafde10e0f389c2ba737be8b90aa441b6612397e031c2b8cf9f342f6d65c8231ed8838c818fdc030718808a47ef5b429a05f930e641b28b208a3ee719a0bb272216aa58524579b5ff0d6a6e70e8a0b9b238386de9fc4fb773d64b0b8992ef29ec369ace459ddd9657683e0b72fe9a2d3f7dfd6a6b9a9d5301cf9b53592c5d6e9636cb745f14ad2af32b6b16daa0e0cf787eaa64367b347f01d0437886f0ab891a046ef12551d3f8df61ea6c71bd320b8de4d4c8c74dd4b470448271569e975f0a766a8995e7fd667d87d52c03a2c8e6aecb9a252779f258fbad6de988103153c85699f6a94a4f850ddd308244c462744e7ae9865f086f866210369bb5fb61fd7efffc08e1c0b24abe73fbc29b8eadb8d93a29be21b05dff05072a8bf5f897b78ead5e563aa368b32a540ec423750de59a8aa1028a427b851d84d0f65e62cca48aaeeeb0a02d3a58d6fcb373796cc0fdf542a1e3470a5fcac1b9cb079900446e792105d252635c80da02d90f9a1c662383b0b85f5fabb3681b4eaf63dd0901d7f755dcaa3b686fc93b05bc169bc9e8d55c01b12dcaf99c46e8ef6281a4e045cec1f396a3f2afe1852a3b2573c4803ba2b16c04363845018fe18ac461faf78488254273e748c9e3111d27bf8db4d6f8ea62505e53ba75361f6874f8f65926d2ab7d37b96b4a9c58fea500c4fa95c957d8f7fecd1adf8ac9f26c3deb2564c501e5381f8a5a4873316d9c3c415ff5675c48f7b8530d01ca21b5c849b53c80a75a1ac448c10ab7317ac152b23b01046eeea1ef12322b50f4a596a8f77e1e9053821add41c8f177a582de1d3ad1c28fae9f5f8bb92c5a33b0f17859f429a64f4c6828dab20457536514f0cedab00a6c5a679eb314cd2608ca439a3421890f3cfee335bea02d9c621596fa1517b7a1e33efb93aa370796580b31e474389c0de46d47570ab3f457e257399f545353f2a8f93da157baed193024f99f1813f3c77135f9495eccdd7e4b26126b5827bff9e2feb6ab2564c7c62c54dcdca663e2f0f2a036b7fe342494933e026887a7ca37af68c9867dff0f3a5389147f830f3b5f9fb081085570b53a5b9e16f7ab335d203b33dd820c78d89ae8774d3cc815946b6637fbad27086ae37793840876e3ea835bc3ff9d481060f74375cdcfdd6a3910f84e4252d9957191e98a35d25ee678cdd76699bb22997995e57cdb2117ac692d18ef222def8b9f9dc78ae4d6f74b90fa9b509b768c60a4a4f538edd0c366bfb87c097d985ceaf3ecbd90a803dc90d09932235465c66bbb260989f39d7e7cbb2a6e8c2f4e855d388910cbeea50c15b3d605f591eb0c334409b95a6b80ba46a518ab791ecf16f51ebdfbc04672c9bb6eadbb1119dab8b5fc3c82189aaa47a747f11b8bcfe251fddf99d8af215ef8fc722c346d64180d8eae482057fe49b75b0a1d6492dda1c65e7c5e0b289b0159e88bc6422c0cfb358040fc907fe0b410bc69af1791185e0522848a9ee1f3d05e05e6c9fba4785b1765c6604d05eb96b6990e5ec97818666fadd96fe126ec64f0e637c8ea7fa95c816b2a99175650254623e9dedfe70a6adf143e6b91e5253334edec150bae8123634b71d5d41a3fade47db7352ee0946ddeefd2b226b397fad3074adb11c2e108e62115a0cfd53051ae751b205a9e3355e9cd6392823eaa722d6a42abc867d9624346da0914b5145be63045d85cdd0d23b041ade32e3e306a4c865c82c95a36f811142096e2186d69a88790b177bc55b6d2874e9c7241f2e20a312166a98001831af3b14321e7ad47a68024788a91abf13106a6e71f48c44cf5a5dee91597dc3b6a99221436235bca8ac3475163c21cef377187b47c78ddf8dc7cd2357b786ed016d1a72eeb085934bfa59e33cb33f965c11047b649aecfea0a08a193c70bfbf148b9ed59bf85fce215678b8d25177712b6108ffc852e9154be2bb17fb4c0160f7c013d42f0bf479a67a1afd9f15f3af6cbb8eca050f608672ac21309ed3b59460e90ddd9554d2d8ba32495a33e49ee358826d9222bced8b24974957e7f190da1bbea1dec67b906be4b85506f4ab5f86029e2a08ca5ec72bd024c4bc22106569e29de2ce8aba6b416d4139b18a786e0a7f6f71cffc0c4719856d8f47f335bc6f2f21ab4d8da7ebbdd9edb060f414384b5b43bb925928995403c86d94c25e6b540693d069c8af971696ff1d28fa0bd1d45f902525f21b346415ae9d326516ae372b13b2780e86c849a273de7d890b4505817187c30726f7281529d7f54879651e16c4503f9198086a8eb99522be665778373ee88656d99a0af48e0614557d27cc1b4ec0c6152a67bebb7b8da85810c5ccdc3a872aed342b05461b44addf7476a8df85d1fda021cd61767037d282a209908e425bfa70b5fb219714bb76ffb00ef14006aa695c069ea5e8bba0548f22b2647adfcd4f6ef4adc7de15d570657aa4f527cbb5b2ffe3bc3d375e52469a6b1a2c6fdb488184683d2d58995aeec680e4fe7736ad6ca0d28a116e962316c1f1e880e3328673ba487d1e54bbebb3e543f81f0b7464d73bb56af802fc96e88b04b3d64806814d49a56e3069cec70ca302e0761fec2633f07b2940892c14f4591cee535ebeba585ee1467f095408f3e41e8b1c9bc0d42a3e604832e7995b7f59b037e9456fa2eb669ba52be58c0b76a3e76cecdf8993fea04b5269aa2b6d6a514c32acc43a602029a5d4cf509c87a9ee57d61b7673e3d92715fa3bccdffca0f3db4ff4d744fb108d3828e76ac7e92406b6286a74c00335514dd409d360a8588b382dcd4ba44d4a52bf7a6012905d3d55d2df77d8abe401eb6ea2287b77faa302899e04c22ab0030f78a2ed2ad35d5fae5e313413e8aa9f28e8aba32cd81ab7a8ac0470e39bb1a1334066bb83176da33e7eb1a8d58b449625369e4165afecef63600b4a641961af4723e8953d95b9c7efe32393ecfbfd9504bc644880ff4f379defd64880f7b74b05af914ff03dc09c6528c4be245fec51c49855c61d96a53b1b6185a5be5479ce2b8f3c7601dcf3a4e68c934c172886d6e50d7326110b74a82c5064653a6943f26298cccb606c0bbaad4fae794c82d4a04222f3aff918ba418884da3187eb77c273ab398f25401cc4a3cc5300a6c45a97f13bb751a102b6195ba0fea778b989641db26ce45f72728826a266851efefb39a8d8a0548dec6072177cb919c9d4f74c68a580a8f401a0ee1b60a1b9929359c1bcee251922176d4965412c6cb244ab4f27d3421b2d90fb6a3d74cc164a806276bb99962ba1110ca22702e45be3a40f15c8d3edb12182a301e5843a08c3464c02cea20d387d91c5993983e7d1ce29e429565457f4cd61f32f6a637fdd7260f70a911545a3d3df77f3f853b39ceba430b46e5c20cec4f96eebc033eb22ce74c64aff70ebab4fa04336f1de56cc898089c83d67eccb0ed7bd84c2971b8c24b7696793d03df57981670cae4e449c897e10a277305dea06cfc3be68f79a3321fdb9df0ad36b8a3506806c720475f245efe50777506439ff119ad5bbdbe70786a8652825738581cf56f9750e6613de893724968e3ad1e33b8fad3267e4a4a08125658d52bc033d80d4a77670cdf56237b8e1c35944413984799988b2a038a1fb0246f2ba3d3c0de684997cba989e1ab6a534f1adf33e6d6aede4e31114ccb3be0d637bf3045209a55097c2391ca62afc58be3bc0814027bd2036ad147de13259a2082e93d490465c8124a1b192751c36cd0326949d06f8ea03ee0d0d20815c54c8d7db50e6f556fe7a440cbadaeb76e5ee3a7f081e2b5b3ba8b1382e4a35f15f3a9210a002d570831ce4d7bfe7dda98a2be31d0c6b7986e03e834bb6aacceb1407b451367f1720e5838fc98a5f9c44f6dfd525f376c7a76423f1d2c42278588004f8eb41b44039a18bd2519a830099a96c6a8eeeb570b2aa168bf2ad9230ec4755b7bd088c5f36a28032265c1dc8dae962d0dcd64b613744e92ce2e8e9349c647786556ff478a6f7ff28c6a299f0d5128c3cf5d491e2f7a34655cb8a7562a5c86565c9b35208a6b622d22bf82c2b32855a693c6bbbec2a484d356810dc615ec9540e10932fb68c01a1e3a2b66aad6c2208485490facbd26c847770c279687c5307c7bf6acdec2b68e72cd3591070dc202eefae5c6d679acb36bec54f260935a4236d78ae39d93be21eda4cff7a3434e9857cbd98af7a81cf7bd9e591507323741707f9cc319c695b346ea3a3b7dd6882cc35f328357c3f69259ebb2d298cc57d7be22a54635771f45e09ebd10992879df5bf718002af54928306636f40108736d36ce88b53b0ee4f7aeaf6fb193f0eab94c148263990a19b89661b20d77983a341c7e801e8dde2e190d1f78194715659ae16143ea5539b8a10577595fdc42d2919343b0f99265ceadd1b64acf5efbbc36a1986fc95cd5e259c8abd32609be5dc6a2e34c4e3b0d810408fc2c6691cc02812b3a765880d26e58d4d08f0bd8d137281b0bf25ef45ca18d48472e51485e456250c66c5677cb49a4692005b381f5a6273d1ab17a71b3366e735e64ab35fb5d7861992a6c1af24c11dea89cc2930804d59179bcf082ea96808e4206ea5780f7982a06bda84d65d269efb6810843dcacc74953b910798c78a2c2582e891b5adda98880990bc482f7e0246a4a7b75caa23b000b86a53d64458e2f97996813bf85286120e765c9d29729ad8cfb0f08113e90642fb89041a1fcb6d0e01823164b36255ae43b19f1d0ab9ccf65bb2ad8c9dcfa0b58cda6fdc9ccfd9a8fff7560226e636024df442b84c94667a7d8a018d8ed0000bb7f273f823a87406a639b3996c813e062fb2bcf39f5fadfbdb73ea09503b5d73ccb552bd3140786d37494f83a19f67808fc660929486a54c177d9b0a2dea042f5604c5da7d7c1b7f5278ab130247595eb16db1c38a85c01faaad52a3a1cf570726c5f9bda114161cc1db7b065323251ddc6454b124b9b9e8fee25e3a5a656616c6df09862c5d9ed120aa38a97438232594812235f123c475646415e57a6495a61c391bb4a76a10961b74116500f71b44819721bf386883cf1e5f204634a7da361d470cab4be21a772a76a45df4389fa4fdad3f7347e03dc5c68a6d11432aefb1c002d9a01d0f8499c7b384fabd698caf779b610e02290fc6a725b30f8b7d65898bfd32ca05dae46e8bd11e4b4196c3b5acfa1e0493ebdde757c458b394d951c237e48b191b41c541734e0236d3431cac87bab46ef7f2aad7bd39b31480f0387d83502636af8f1d0a90e27bdb01c9ff72ae52ef718ae786eba1c3b6d78d9f3f3c8fb06e10abcfb0094dea3eb630bacff4c2dd8b7cf867bbe02ccf023e263c35744cb5c52ffb2e3aa88ee87ec15505f795723e808b05365654cd811939357037f231b2dca3655746236c1bb066721bf1ad00b0e2e3685e0463cd211fdbf44a67b188f20d666be491c5aed294bb48a3777e9876086bc8f4a91737e7e4699ab94651c4813739c23927a79928ff47127d697691529feefeffafb0eaf299438d621a8d9826f51b5ec4ddff3e4c849e5892f232d506283cd41aa4459a05e998f02cf2e4520f09310c096264992fac097e0486f9f1f18075ef18a0e0b168afe59e0e1ed3c107e98c4e32bff63d83915a090703da85385a8eb0cf49b7bac148c5257122499b8ae29c514699878e7a799cfa866696df610165f2bb6f1afc865e7d4967c74b6e77565ce9e4c7b9cba8ef2a8cf57ddbf9e8da31927e4fe516ea6128ba65f83db15de88401525e3431fc4aa899d464ac14db798fe44bdab23fafcae251608359d6a90d0793988cf3f243760478e2c0f94938fa2df9187dd635f48ad9d3972d5a1adf17b10ff9f5f9a8017633f68c5ae8df4de745d4997bae2f9db0527a9800f0a28ef7e8b5a196e9d7458aec69a980a84dafea6453267679ffd42b8545fabd5121396e10855e835ab547164612e8becc1bbe2a199dfae9deaf9217be113435da380d198cbb3043c5dc10ed783a0e39eaf85dbb304821a85fd1681aca3308dfcd6620883375284d62894d47327e2ee950cee6d8f8a0ff08a843d1e1213beee8a3c362d858341e0f3658ddb4f0b52cf565326de7ff8b966d27fbf4c63ec999c70026c0e3fb60e541d7472556022412bf8f87830876dbfcbe2c0a0ece9937969dd1702dcc608b1e6e4a8b5dcfe49b73c8818d19bebd6c55ee2282fcd61023f3ca484bc4a4614ccfa6ccc0d1b4d732f62411667013c92791d9a7998790112135d8215fcaaa9985793b7acf8863b486250cf7edf6bf805e78909b23cb8d6883d020f9ec20c81a05a6b6b4590ab211d7eb40166a9b9b27f9ecd51fa98018f6759053fddaf386dd814fc967f5c6133ef59a902cba96fef04ce54be6967c96be82d79151c00d583c23314846b687916c4234d08d90c1ee59a8a47321101fc9670f5c9ea5428be100afe44d14cbe5b0c1a166535c2192cff22806c24a2806618a88650ee44bb056f0d70f76518150534a9ec1673f110c3e33f1592645fc58c03ce533321b28ffd4cc817ce6534b693496512ee3d9a7a61bdf48934f12df9fe910ce41cd3d0e21863bc350bb1e5d44aa7454ee174b9a44f43f5f719de9ce9285a3edd60ee47dc9d80bc0ad203e4cc79201fa8a791de3920d3d426cec8d3056f1ee05edef6fb6c539702fafe8e68848dd3cf3a78407e150f048931f353a58424f07202ee54ef6679b12e82775e3232704387751b44b124653fc9b2c521c67367d33a56720c69d912aea59c733756aecf07fdefed1838f0067d78a92f649f4185b9c8a012a332162fd468606be744ee9099ec41e33e33e644296aac4bd470d1a25d7f4d37b009fc09fe632a8ce1ade92044ed95fa2dcb2f823c99196ffd8c2025b213e2a50c4209b5f7c9466a0f4f9305481fc566b8b65920a7276528d44db3f80325ba31354c4a6f2fa28e6a988fa2a567ff3e3ad64523641a61b5b0f07aa0046081ac401fe11991e9e0d98e18533adb9ab1bf3525b81b4558ddfa6f1740c7218d88227147ec1eb3a3e927c490c8108f9fec2cc067183dc3a6910c2a497c0fd0f8a6081f01c3eb07560128a7550325a8700620590c68cbc40ec457306a406416d854e541c0f6bd70ff1c9c1dd34272a44c1ed635cc74e20189c26493123db9aacc8f39f0bac74afbfab55d9701d5593c4b28158ba24f714b53a7da39be864bacbd8fabb772b62e6313de740a80cc2f31ce6bcfdf808214d5e1a89380c9b46103e6f12f408695cfe47db6540831cb5e47b733a95a44e02030eca58e10afe6c328c78b036230143e7621d70886e71907a0822e8c29d6fdb61a3615abd97c7c6ab240d8521c821ae125eb719a5f0776847121a362de9256e81348145f5581deec0ea49cd61f9e0e21935dbbebb262bea38726fc02abf4ce5109b4d55d26c5da6c4f2ed46ae19d655291615622025dfedf28319c6cbb08dbcde49dc12c2a8b2315bab2c18e3b17457b233a2eee2609269b4b64d09d50f8fe88a29d3a990249e964101158843693cb0b564e7d738b393ed60977b8ff6c63993c73feb9eb36b068dfdd7e8c10780a0e313c573bdbb46febb85f7f340096e88001f86172721e1b06d57744600d56a61ab9867554526478367c5872eee4f7f9547be6c6629bf78902d91269b81f23f3841cd4ac6bfe11aa4456842ae818480b168225aec075f0521c76dc5ea1572afada9f325d44a1600f3e7656509fd3fe51d0c3880ac8991ef03bb82d754c9d04f1f359456240c1aa552b0e4070c415ff6554b0b4dfb3012f208e11b257d7792345a15f7fb45db3ec8f6e8135e5735e6102faee6e3b11f81c4ca3b9002b4bc60007f4031ac3903dc8bb8451280dd88dd21daf11f3ab537f2e97644e2d4c6050222c61993c0ac81f9c20de81d21609604a8b01282a4ea1317da120874f5e608b00c0005a0d6776cd738ec386ae26b5f8fb043b16261d050020f7e40a18b9ffaa68b364f2859c0a45204413c04eba8ebba2abd8efc3db4fc0776f3cb0ee63ed3591b6961121d6120521801b3e6468e2eb8accd71c70db67af6621f229f324802ee9200d15d4e1bce03e08968f626a965605b539a948a55bba9b27a60d5d292ef1367362150a36afea9f709a23656584629e645fb10b30a96272b766ec09c8b724e76362c13d5ed04e0d8ac64bcb76eb986d57db4e34e4fa7a36814f2b6371ceae80de183d8a3858207be8454c14e5b4afe20deeda69ee7086606b61a0176027284e52555f0b1463ad0d878acb92fc9301ae0d3530f343cf4d8f481c529ee12042feb23a8d811b5eb1ec24bf9a39dbf36331dd89af029cf962d4e9ed2fd095a1546fd0795be1c43d389f3b30ddb9e3be41d9abd69fcd97547d89d427c4812e28a47f48e1f433716deeb700fbbdcaaa6849a8c4dd8eaeb91aec324e6e33b29cbf9d2d44251b1c077eb6c74275a85f85ee284727d19903a8682616af598fd92b63eb6ca1fb36ca3767edad4b2a65e2f769171df79dd5fda056a1eafffa5341d603ed76283dbb2bcfbf1ba9f712419f2f4b99bc13a28c869ba17efc90934793ed413923dce310eb5544262d30d141058a9e24d37f89e9ea9b9617bc256c6a69bf8ce4a518c6103d5f9a926317cbd58f3d8b8e1753b1e1b55bcaeef2dcc6419795d2be8e3b7c2dcefb45d6a2daf5f7e8a986fb2ee8f4739de46b3f9e477df71ff8a085caa0744466707f99fddeb4c3f8a1d4e159f339dafd8aeea851015f37ab4be52fecdebbe53c76a8573e038abf1499dc8808039abb0c230be17242188815f61601ec2c3ebbe21992309252954501b471e05ef6ce5cb2cc2e3edf46129af3fb24eab396b4f2c81d73f27d6688793a1f44e115ef7fe7be710e3931ad5e2edd0d81765781c4d069c1694e1006d5ad4780e5e5f3527bdd14156217470e8b1a5cf74b65cf27dd2275b479d651731849eb6de2814755ff484ae00df5fe32e1e5bd7c3e3a4b72719c3db4030b68e2e7f984d37afde1dab7f2bf1f5989ef3a2d085cb16330efce0d46d25168bee6d45a3d9278b8eadefc1ff21370174e6b8bf2c60d56bbdbc0130dfa94552357062e0590e4a3cd529d3c95ffe8679243a2486746cf340a20e92188f218da38655d64ca03b4e0e3f683670a832d01350885c4aa447f8642e288a5995d972b104d1367fc610188e693679be1adfe804fc2723595721a3dd0f9a8bd8088518b30a83b8a8d21a38cea11f41279fafa49f61ca063ad040b208ad2cb61faf98ec4efccd75ab4eebb1cbed55e3b9d69a1b8676d3746033d37905a06406ebc7d4322a9decb5e1529402d34bc386bd306edbeafa7c87dd859961823f28ffb03b4ab10559a83f1a7134ef4b9054a701a1fe21f87bce6c7f5d1268db5cb2aff5f70a553d54bd326968e5f1cc46e3ab3dee3b35041e6078df4ea71a9fef8d55888d66cd261bb5d566ba8b59f0f48f6e7c0a3501f8cf481f925aea73974cf84589c59e8e7aaa5b412714d94fc319e511aeb8f47841047de670dd2b82d3d1a9637284786017f3c052f6315cb42737575daaa70b9491dc568ce0625cd3f25d188571f6658da2dd5b3c31338ab4d080be048c4ce7be1e4b51a585bb683a0f8c5428038fd198675195d694f08febc763154b7f47391885d9121f2631f1d9cd280e0ba53d27adb536aa0ede6f882f0d14a1c0bfc024c31d0e894e8482f3240156fc13315a8fcb536b6106110a7148bcd58c2fff3fe2442465f31b8ea8964449930ac65e4e55867156e2042c4297768993153bddba9539be8f71823df4bbe56e8d7ff4178bd1294f00144dde6862d4a67ecd5f08e3448b99d88a3f51ed97e98499d12d9c2fff74aab58e98bc6da6025381b48005be8439993dd0dc35e72d9c60c9fe3cd03eacc89f9d57ffe9f0014e84b21eb1e0aecfa82adc854e1bfa617b897acc980ce70183b5210295d09c4f6c1674ef10c2e9317011a118a37489ac2a4486e0f5333e61844e73d3b2fb6564d203f9d43b8370fbb956ff8c2c4a6bf7009267f1f5b7ec6fae66100455e632068700e20206b12a799d006335d5be9582f7541898c096f109b30a086275aa50053ec166ff17eeeb45ec2cb018e513c9a745a5e1905922f9335a82d13f3ee136bbdae14e5f48c7e1aacb2784b2bd61679929516225544e14b457aa70ac345aefa856544870efac3d181d06e15d5e029895d033ea254a49362b0517058e6db598c88faa7b09663f5297e0a8be92cb8ee9a64e3c3a7e8a4848aa6fbd842d918b10df7da118bcc414bd1b1baee95770c34b80833b8c6519f5feadc525b773a10ab1e5384009409d2864de965e2235cf8aa8d656e810742fd1f06ae2f3c27412cb85567db5b7719e8195ce4b90d3f826bb232ea7bd7889aa9b47940e993e55f04786de16b31ac3a1fcbf0cab6bb488e37b86801a11792f5196fb8781f0d76cbdab868cad3a8541c12bc7152c0dad7fd5624b7cd33a53293842ac7ff0390390df12b0b319423b5e63dcc454ac565bf1264619f39e9cc97e4c25388236624b9405ae44501f64a14145dcd5b3aa28bce60f2406489ec018cec3813db1ac33dae75a84fe4ada5d00062454badc6ab3c4a90eaf89bfc45b91d39084d43ba9ef9a9a97c86b72a1287f373d386a1ec1048b8a645fc50342308a1136902542e2074b7a3422c84918904c5d2c7bf8881885cf2d45bdf247d5eeb60acdbb1c7a51d2b9a3987800b1e8723c1167d099d7d473a19c0b9ab952cf25e5dce89beb3deee31e72f8f0ee2346347eee434e35f8b845915aa9be426063eb6814e86c8aac071fa67dc74d510e26f445cb3570b23148466a7a0b6a867bfd0ece779f446a2ca1ebf54147cefd2ba0fa3371da5eb1ca0ada827ad3e03588126511d41da093b71b7075534c9f7c8df455f55e8b9fc931ba506780044c9f42d3f8985c345b2f32289d39a0bfd89760f45f2035f9c7ff883f3988f8fc25aedbade45e99c0d382205a740df59b088fe8b60d04b0c09b6f8e8d2c9fac2297f7cd029dcac6dab50f47ca6b41e4dbe9bc3967555114d7387c2db67f290b6fdb748a4616ced4c4deddba1bd45a5ecd9cb1decefc29ca5762c074777c68e71151a9a92468f12758e6fb3b21d151c7e17153d13a7aa07bed376104e0c7f8235392d3f449a2cf560d5b57d03b17cd9530c59fd42e4acb9a64fb99615573893f0518ba52197d6c7dfed26660941c24bb064180e5486511e24f00c088aff2f76f1c30f127432afb024391ea6b1b7e131431d73d79781856d6cd6341ca7cf12760cfd24cba4d6124b91edaf730b4c59f80b2c867ca57cdc4ed8eaa7cc4b21058c0ac3937e3a25de66817cfb314eefe8c4e228087d5ab679af04fcdc8b25f546c080cf729d5b46770e09f10d5dffbc1180c9263f8a730ad0fc6a63251f01a4baa1c712fc62510a187e7f44b9107978b0b774b5ca9f8b429b226236c5d9b9c5556f7af9c12916608469ec2a5cf520c5b124aad182271145f7ec72b152bc0e353e83db21d408bde994321820004017026e40d8a64a874a28fdf8105036b05860c7dd130a3282308820fd93e5968d788c92012ba987c54cc08925e8a99ec3e8c09fc018921ca1b184929cb945320ff62010099cc5a39ecc43d23947573fe3261564dd458d9fa38616748de493a6ea7fbabe977a7e2e2e6da84aec8d5631a4337efdc0bc60abbf122d37ae724e393883b811acdf6f8a6a4c6dea41c07383580dadf83ea8307cd1126b8693c2dfcd92c9fc09e0a1f971c635fda41f11297fdb6acf9690b463090dc4e82a481a65ed1764c95494568d3ba20f5fb30eea5a73634920568c32d6c1905a0731997d59ddba86b56a64d50ab0344207c6aa119e3a18b15c58c6aac3495d66458f10cff41fdcb78037702f1564ebab318b8131c9e35832bce1d6f0770279b9ccea30c467f0570a26dd4e9dccf36c6ad861e0d9020ac1cb860956b88dc893cb23a4b6b123e4370197eadeac74a6e21096242a76e71c86336a58ca6c6001eb0d0e39c039d1f030f87c42dac1caeedf210338f89714d36702712b314e0482d06eb75687e303f1e5529730b2bdb19fb2fe8110a93163fe713b7cfa43480e87c6ae493fb0d8042703e52888c081408d26327ecd2e216faceef8b6747b5fd632b7cdec595e540ac6a2407334feae2681f360c5ad19f767a58ae51216d13f0754b651b17e99fde9ee07ac236b2f23614252b0bdc0be3d03688e3065bd160a3fa6918e5da0ae93ecb471a2ccb1b29501f21d1970e8caacb3eb4d65da5e43f6deda076fb67324e1664b8e3f57d19b8eafd2b09bbb0a0e7f1c79ea13423df35155257c5e26d0e841edf0efd3a8a3a74380cfe228728657c84c6af3fa1518b634d8d06b80924e2684448ede1f2c994427154ead27ae0dfc62b9bc7435927ce5ed2ac8b8dae53bab384680d9c0f4861343922f161121896a5d6bcb2ec216015a171e895d840548af71503124e305ac2b64cfaeec2e94529ac87b490328e6a869ac009642c949806c4bc892885ccaebdc4a99105c5d6bda0150cc68a3d218be06549ea348d20ed8ea54188a4dc938427e30077ec587ab6066c5b1c1a305f994324410494415706a5a1435238935518de48480231c5993c9068138993fa44df1c88590949546921c9270a03e7026821a9f3e56a564212d73cb28b690e92da099f5c44bd67e281594f0c4831d0e38679320aec310924bfebe3ddad7f58f283db71bb16a3a289d8612b1230a7a12865d74b68256185bf8c205d4511290e3e5ca3467b128dbd8287ddba056c798d39bd58c5e83c394f50760240399c5ef7f16cb6f8d2b457cacf5de615c0c4c4cd007b3504129b0a7eb74637523dfcaea31a6a0b6faaef3da70d9baa87da35e6129642964df096b18af7b841799342d65378c78689c4e044ddf0a77fe8f340afaad7df95b42ea145428a302561b29a39f7cfdd45b471003bb2ef275f6a557c8953aeb12918d9dffaf0da35f3ead98973fe7d5fe3cf54188863a6e2d9e1f98bc2fd3442645e0e10686700cc73b6052bfc7dbf80ad3a1913d718aa958cc09e69021838f11d790c4fff334f2ecd658d54c214ad1565d06d7be03ee9b7fffd03fd6e5fcbcc8c04dda54ebd3e165d8a5ca4ec95947d84366ba57af6c4d2d46f65aec1642d2e86ea0cf3178f981f455663982a1f32320a17aa0ac610a888b5cf9490df43063c2e9647a9a40a6bb7b199978218afcaf373830f516d935478bb308bad265f913482fe0d5200dc7ef108d0e759582944f655456af2f5eb58459bf51821a0f4ca24905e9f4f051fdf9e51e0be8d42d356f2f14d1688e89d40fdcf435490cc4d4225fcff6c26b1535c95ebb8c1ce42d6daca2585c8ff306751d97aa723f4899365188c749f7c5a8400c578051d227a92c7ede605dd8f1ebb03e919b44d4be8257ef224f1101ef471f600f85800dc548f29fdb7c22edc69efb3210b5d39bc111d326840e80df263c0b9aeca80a742516008e0445a4b6eb80acaec7943e5b9feb328f2f394bf90bb942ca997f554bfc2b53bafdb852a191336affa9692c26154adc63454fc141ecf909fc9eb0152322dd844462b2bbaff93a07ae7a3ea23657ee0dff75bae0d0407a95499847081a2428924e91a2dc5959d18013450bcdfa336d57b67a2da8aab95c8a38b051dedf383c2cdcfa0e91a0a2f1799f72c242cc4f8ad6c627b8b2ea13a8414db0b5f71fa3f1133bb3760e9907833bca945cf386c0113a02570f28a93e82f6838097fc3659f4ae54169a34c330daf24a8c3831d57e118f0fb05211e87e4c7c416bb6f66fa1eaec49e758aaba7dcc6299773e9bf6395a7ad25787e24141ee06238c13c2977bd41ded993a2e14bcf7cfff90437981e5a626af57816f3aaaa0075091357f8ecf155ad7d86a4918e79bb820103aebe800fa4a9f5311077a7a84c45f22c523f6fba9b5d5545d8ef8c80babf6bd6bda6ff61f7a0220711ef265b40cd03482408d5c489be2208bf76e9520bb9a6e1d4b1b68e2946fa10f8a030c2abaef46891f7e0ab30ee4d7b1c5bed547133dbb2e2e81982115c65dc246830b8ea53ab1255a3ebb321b0f6108cc5bfe1b9580cbc4f69110b08899a9f24b5783c3be78699581b7b1d7c01b69538c05e1e65d6536a0749114ebe8306ff82974d456c752c141692a98a99383201c1bbac21f96e8e836f914aa597719e395fb31fa49519a4c7b1793970aa39015407bf2d190c228ddc64286214b0b78459b574692e1d79db92a7d0a418005050a0fe27ef9ff400101615a1f400be4d2054db418d4da6f0e2a27629f3454ecdaa97b6d8925fc4c5698370672a62f498ea455aa75ee3dbbbfb58e9befebce466365f5c84f801b04f66c4b4d3bb7c6130402492c3af43b644754d2318a877312abc5c8700558c9035da0f4764e40ef72e2a36f7eef941de6040223e5dae3a85beef71fd6c1a59d12b48be72829fded303eb4b421126cb542738fe71e98656b71e231f3527be005fb4fbd79673acac33e133c3ac758c4ca435b54db105a8d28a49396e23e7b0921db55500de7203bf107e1bf11b447acd1d043a57257cca568270c20a09ddde3b41257aaa435a95af20410c2921dc4cfbb235995ff8f96e0d721abbac24819c46aa22c01f042c8c0235116b1fb85ef662cdca343b00459651ffdd7843f9005e22592c3aabd1134120b5a75983458de178c8793570a56045d6ecb172dfb250597608733f5562914beff7a6ef615851411fedab4d624bcefa6b9abeb1de0075bca9659b93d45ae42e95a7446c9f8c70e72297d94e64c547713ebe955776aa2456481de75f83117190adee6384fb380e6c721f47c1526a1f19109a66297f49a63ca6ba56f335358d70254dd5969c619b5e080c184aa74201c368c93a83cea652a85931ae388cb8e9442824a12db810c45aa9078d3581b0acdba19c3711c1f187feab08b7e4081d5207f762271a3324dd28c9a4fdc6bd89d6d7ad88de98e9e866f36729e3b52737bcc01641b81ca555a59a50c4a527d5ea82a5ae946eed0c76b8280f0cae1d09594c70469c574ace31b9e10c9a1911faacb8a4da8a90d3301ef2e8f5e1357c5310b78ed04ef2049dc7a4865fe128365e1c1f6bb5ce295daeb0164d9dc8705be4a9148b5a6cf7eae97a0fc6f3e9911d6ee4b00f62aa89574e88f7aca1e923c31bc3960b27d3431424605065c843371f2635ec180bf63088def34f525c1f67faae95dac98eaaa270d90d2642078d4660ce6eff054db8a3089b3ed8bf88339bfa70745be0cddc3b33c28ec9bc69ecc3b951925dafdf37a188d771a421529107b69e14b65269d0ba48fb17a8b509be608793a722756195523c3d94008738162ebe25a9533ca8a7fbcc95b8c39ff5a7f28489136db3fe64d4ba54c3285ef039c4bacb9893d9752faa44851961ae5129c16e2831ef9297bbe96595bd340cc08ac36c899c9002a59f29e0b7fa09905214ba628cb051029cd9da699f426ad9f2ee0205fc620d510a381dee3a302e78e8ac702e7786108797e5000cdf9d64d15c023726411d61ef7c0b0900ace10f604555d94f83c00cf12d2746c53fef0880d6190b740e6bf5d0188df09c4147818fe9ccd831b29e8a77221014d32ff675624b3c09a34cb7f559b09758af9fa2da6d168c5d22ffe76d0694027ea95708549a6cd046a00b3a7b29c4123aa98d49072e226ec539a43a1d941317886033de0f1ee5c2832895c81dd7c426a19b7c0589f37954d637970ca4aa31bbba83bf8e1a14ad1b7acaa2e6355d620ae64db0c4a6d67b75bd1bcdd42886015266a1975128d77048f4419d44a093333527f1fb182df4ac3f70bb9a03c06756343cd12583a78ba5fc2d6af1d051e6abfd3534b706d414e891148444ef6fad5f71cccaf2eec95f88819fdfc71c4b88a095bd2df55198e32de9652809468519701224c3bb2729af6726407d220e215502904f06782287f297a8a8cbc2f3fbb5e3b3dd03232acb932afd3b693c5f4563477de4eb0d931b6502d2749ce1de0b275703a46204ba70afae552056324e076af99f0b67e37fa4e5f6ae7f7323c52e18601dae28ef4fae37e88ab34911321020ef585a0f73d3c7da3e8c7bb291aec0bb9b142ab96646e70611285843596ef0839ffd5bfe97d6f6eeb6a5dc52a69464850a9e0a550a5dd775a9213a3a2ad57f2af5511b99d4edfe76ffa96ef79fcee9f43b4edfe3f434a7213972b0516376d84f4747a5ba3c8278d82f951aa2134485f343d8a831de87736d623aeee74927ee13739f4c3130a69818989887b7debc918885a7fb061a39c230cf7fd272b737d2ab98dfbe3d23adda9e63fee4c13cecead61c1bf5fdb718981898af1ebccc395896344a4b5d4f7f36e37c8fef44ba373dfc86452cb03abdccc337f2e895f160a090edc950e3da5ca8459197fee955cd6f1f9b589993fd9edcd3331a32320fbb93edc1af4ccab379d8999ebb5c0859a793fdfa64c3764ff6e49d4ecca7e7973c7ef298a799b7f66c5ec6ebf1b0573dec0e9b4f3d1bd9d8d8a4dee6b973d958ae2de56e19f7c5cb1f07c4eb8f6dbcd47665bcee5ccd282fc7ebf0e06d8f8b848aa21475b93c2ed4a268e86ecec9a4e8c5915a0dbe6d998db808bc6db94bf7352ff3fdc5cba4efe9fbbfce32e9db7d5b08573c5e05e4db7e3d7ee6215cd97c3f0f0f4255db0ff5e379e4f0b01f977a201e843929fbc5dba9efffe1d978364ff3335e0989dac32a415d1e354f63bf78657ee6b99b21c9e9e3e56193d4d88fafcdf338fd4cf733f68bf2b28d4dd23d8f97f9ee6ae02193e2f19d4d727a79bdb341de93ccf3b01f77b932ed49b073ff1844e4d44f1f8378c8581efd0389309c8133bf99bceed9e37b72987fb4619f4ea7ee79fc93cbe3f9f972d7757c4f333333cfa3fbafdeee743abdccc9e64d366b549aff620c12e197b15fb531280639cb513722fd47ddc623bebc46fd98e8e8faed1f48a4afa7be87076f0d8df7b19756c1f5ef929cb71471613bc389e6f4f0cabc3f7be124fef2f28135948e42c30f430ade144f9b769c62e815ec558ee7475918747830b46a93b130cbdd5e87c78ff2723cecba67c75fea5ca7dfb8dbf961ff1c5e95a01fdb8f571320ec96711de54c5e7f67fad3499e6a4e1ebc9d67baa6eddbb4755e77378deb3cee6e25aef3b6bb6d5ce795eec6719da7ddade33a6fdecdc4755e76b713d779f26e95ebbc783718aef3fc6e315cd7e9c8a1835ddbffe054463f7efb1e6701f92de737fb250f890eadead9a17b49e7a880fc905170fa023ed89a8dca0fb9cd737c317788e23cd5a23afc25eaa773b1b82c71b0419c4fc2a6b408e6c477cfa47f1139161515bd9aeba17e21d67c6769d6b7e27f642f06b52a7e8d1785fa055ab44561caabc8e8080856c4e5f5e5c61b5fae0603bc8da11b7bd5ab5501626d0439967b84a54a94dbc285597eccd07a6ea93fa9c05e7dcc3ed77f2bcd2f51494de942d5a85e7aa89ba8bba8edc7503a27befcaeaba1749beb66e87e7e94f0ca86977f52e95c2c3d68694c0f4d5da5a8ed17fbe79473cae771c9a4352f497d27b7e1a99babd0e793d53e0a2e329f3f26fd69f6eb5b3fc67e7de937a95ceeeeb675fec7dcddddddd326a15fbf37c97d6cbfd8de57ef93269df1cbfe66d0f492f43bb91c3b1afcd2ec35f99a9d553a1bbebebd3abd36a7fd26959b3d93befc94d299120b6a12deb66dda39e79c93ff63dadd3afcd236fdc99606e6b39f0ce867fbd1d0cf36f4f37cf913888bf04b7eed79fc9b5426953bbb19b4973689fcfa9d365335eaa86a9cdd39b86e86d65aa3b15f6ac64e1e3665775819fbbd0efba55036478c2d6db9d5933094db76f6a7ce8377f3be21f7eb2adf1068d4aafab2fb4f722fbfb349b6afdc47c14532586d98dd664a2ca8d96f3689fcb6df38c6a2d257fbb1b765f075522a1ae14a5b4dee1850e57396bded3b6969b8cfb6dc08c5a9c429526ed4d151a9fe5329f9d9b3bcf5bfec4b95fff45f77b9a59fdd0cf593b0ed3eeb6ce06e654edd6abfaea4a352fdf3a764487729bdec5c25c979cea555f147955f6ad22b7e4168242505a5bacfa5fde5727bb9cc473ea3e02246bdead22b3aa95cd8650f73161f1dc18e1a760414abe0a3a3a3a378c44751280605f1abb62abee63917376a551722f623d8dbc4a298cce6952d5934adb4719d89ab72aa303139503a7670b059291e906738d82b226c7363e3dd783dbc1e9e1bc59a58e3c18824064d4dea3d27d6788fb6612faa3f7c2e6af1b8a8c5862b02e6c04f2b026e375ce422f175e1c721582f8a56eae72f207ff58b3522cd7e29a27f954a676787635534abc7d7fce7587c9ee5c6e718b56d8b5099edd1b99a8588e33efa0703e16217d51f5e550e104da8e7d0ace4a93a57e93700744ff95b77cfee9ef6c9dda437e766fad287527199079bb44a8d66712afa54ff5253544dcf549a65a403e2803420202eb24314f13906ecd32cd55783e21717898185e0212091f9f179a8f66421d291911d8638ed6597a9f2184af6ab97daceecd7f78359a69400e05ae0aa7415d955aac468cc5f434022fdf12311914321fd2e84fb740deac571dd4210a84517a3205a8308a9292101b0425351ad8aed25002e0cc134b055f3af79d4a29e13fde5b2b6b4cd51ac707d7341470655470044ed6589f1a313bc8d587489220fc58f5cd4d810363939393d3ea7a6c8f6a8b15109806ba248c432a06e248242624351fd3ba8551c89defbd1020072541f1f8815b742370948e700d8f2a231ea4d0fcffeb038d6da1f37363d6a5a00408e4af6fb60e17d742e6f770873dc5fbab3300002f40b5f0b5d760210a073f1c3865d98e7441fd2b086e26b180d3fbc734babe2f3b31a346cf988915a153fbe6a2c8a44ad8a4131280671cc73628c2812f9f0e1c3870f1f3e7cfcffffff030102040810204080f8f4f868f3f15bc859371fbf63385da5edd755ece37c7c3ffae8799ee7799ef744ecb4bcb71fdf61ceb2b11f6f3ed658ef078e6d02e47db0c00210379e8dd7c3b39dabbdce259f63a996ee435ea01b7d795157d941f5af22bb0a4a0efd0bab9aa7ad4e8a36f8154bcad44da52e593b373db69d0278f9c23e0520e20f73dadb26792152c4e36f4560a8b9b1e9f12c6b906e8e6c7a785ee439f18fa83d6afc55d41fb91adb2a693f1e42baefa373350c9c01fc99d25a9d8798c88ddacfdfef2f67c156cabbc423356e742f063000d79ebf1c964695e2c74bf1ef73f919483781fa0272f34080c0ed0007e0dae3ebd72872971b7ff37f1b198ae2bb51f4ee2ab7c8e846b73eba19eae5181412bf9fa89fbfe28f8f34a66224f29cf894d69a8a3f7efcf8f1e3c78f1f4fc44eeb87f5818383838383838353a9b5d65a6b9f889d96b5f5e6e6e6e6e6e6e6663ac1e95cf2e3cdcdcdcdcdcdcd4daac8c6c6c6c6c6c6c6a61af5e8d1a3478f1e3d9e889d560f1b7d6a6a6a6adec78708daaaa97922765a3551b2700022351042682184d0c6837fd3836686476a870c8410ea40e144164a1db76914ce4c7a436623d3d773a35cc88293fa24d52c34467713f18e3966ec1c37b6cc32d38dd2a3d767264d9c3c71b27212e66ed3c67af993b4fae6dee9f6bb67ba5936b3ce4cb73dcfeb2e77b7c849cebdd2dd32ce3d8d5ee91ae725ce37ce39ce3bce4d9c472884df190ae17686d1ebfb64f24c016c8f4d9fe36f307d8ed3c7fc0da78fa94fff86fa34e6f0603ec6e39e76db9356ccd679da6f9b46bf2b79dd6b258d72dc7b8e566a1cb4e76c13cd52cf297df5b43f79f44dded6aade93d6c97bd232cdefbad971dffda679a59f5ae9b5599af33b8fa3f42dc4614ee8d1bf7b123b23d260785cf8fcd4a38c2fe5c760a457fdce4fffebe769cf087ff32731e2b03df38cf0c4d02ae7ae869b2b3f061965b43badf267aad32a7f9defeef892fe44fd606c1543afbe6a6401f2bd87259452f244cf1c062af9ad927f7ad8cdb07de77d7db3dfa877b23e700f7de92f41f22267faed867a3d701cf7f42f895e7e4fabe476a4dada2af9734a9575cb3c2950bfa1bc26973e1750869470b7c91d71d612cf917249f7d4522c95c24b37b8450ee50991e38b975ad4f338ea87fb710f338e38e280a307be74831be5326f497c11f4e04cea5d125f043ed0e767522f93ce3894075bd4fb98da1e3c8767253e7b4cfad2d8d32af9d4e3a155b2554c6d6c95fc2c4e1ebc921aa1c6e7df38d82b865bbc9cfd4adfff51cba4e3cb4b2d6c9534b5ce16a587385bc9a3b901b69eb44a2ba8b0856ac156e9274d0e3cd42a3d0fb54af6e52d27343970abf4dc2abd137eb64dacdc005b43cc163fcc5b6c6972e0875ff29a001187d764f3807029a54db56a7e6dd5fc928c1d638c31c618638c9af6fe31d28f34c618638c31c6184b1fed928594b992950e7c4d846c5929794f5ab0f3520d7fe5ff1ba7e9cd8735663f7bbef4a1af8cfdbd65fe3c9bdcd85e74b57b5f1401844298d04b1f0ad1ecf7e432b5fcd9b79724b334f176679965d235701c71c411c7957efb7de8fb64b21b49c9a45908de3c7cd4bb1cfa9bc477221f265b3438d826372dff27ad2ccbb2a7df820de2f8f439e99cda6710ae32cd72521235a35267c1d60f5095202133aafca3e9a33dfdcccb4680803b89f09695f9d423426bd1e7246771663f6967145ac57f32d2755594ebcfb0396d0f08b8fd5f0f3c97879a51e74bfecceb81e75af121bb5c030212c065c873e0f55602b814b50ade047021f21c789d66506cfe7a01b53e0e76d0ddca30113cca6d7666878de48d943d527f266907b113604e7f1b94ab5083481971fbbfbf4b741f412141d48f5f40470c8706ae9796a837176ac185cbfdde2d027a200fcc190202ea6e686792f4f38b5fb73328b60dd6d8aaaedb3d5eb1419ccf814a2d48c4c4c115d482cb15563ce0ebf57ac55afc8300d6e5cf850ae4bbc9faf2ef802c46f29c5569b53d7f0eb8e28a3410bbd0ab4e6b2aec82738d0498d3458d04676930a7ff328c5d46f2fe54f3a3fdbebdb9bfe33c356effe6157db408e8eb24dcfefea6c2459a0c08553baf935255db4ab8fd59195048bfb4546e7f775d1444e52a33402143cee2c1088539fdfcda49d2415219a588aaa4524e611f696a80715cfe24fcfcba9086067e5da750487ff4e2b043e8c8e9a31895830ec4b5a665fb23949fe39314fd6d6107b98108b2230a2f39089265be6474a076a82eef5ccea2643f192c835da99f4c327a192019c45d3a471aa99144e34720292a5fbe32f8ed81e338fd276142194c4b23c99f965b6e7c29247fe48fb3689c55c5593c7ea6c74b4b9f1b85628da9e3eaef08653067c598c1326e6d0c2424b4c459250b149f858068c336c9e7699aee7978dccf787589dbd6a6ad3533454b9c059b7dbe38ac9961733449db03c7e16dd90763b7c779e815f49f9f1faac95884fa31116c65305624653eeab0a88f3b2c8c8d3167c5d81c76b3f147da9f1863424ea9d00bddf83b3c191da826378bf1605240348f9123483ea5aa3a91a88848680b1787dcb66ddbb66d9bc9dbb66ddbb66dabdeb66ddbb66d1b10577e85adeeba8e6c7ff2b8e57e6a41fa55da715bc99bafac7d586183389f24ea15843228c6ea1793784a27398bab68d88d3470e2c68f465824c18c6e11acf2ed1eb69064901472968c394b0efd4c019a53aa68c6a257f287dbbd7349a11bfb4afb2db96e65155048944150487cf913f40389f0953087c168506137c2209129ab080aa37e34c806f96d19d62a9c2b90727123183a918c1b3fc67e008b2c800859dcf8b1059075041a01594b220c12c93eb5836a450637aa60891bdf911c09e955ad5ae249f7d5513a48c2fa9d0ba755f19758d5b7aa7516e090a873f57f49e3baebef34aa7c29521f8b50e38ebf61c9ebc98da959f7a6cf688a9350ca2086c164908c3067a562949f08d4755dd7755db7434646464646464646070a8542a15028548e9898989898989818985a6badb55653976d25ed76d0062b51ec992aa87179d861875ed1df610a5b2c11812a9862faf22baa57dacb8f41ae7c24adf2efe9d5c7118c2aff8345d75ffa4efc6a2e2a42d611ff2091d3cbef1ec222cf2ec497a6df326f47c78d9afda733c39056c523ce8ad0a710f9cf4562f752bac9e3bb791f2c8246f008de1d77c8058756456ffef69f7cfab39341bec66dde37ff0be77536c97cce5eb87ddd6f4f3b6eb348ec9129357b78a5143552d07ce9089218693eca7cec369692e66f58f27a2283ea26506bb8f39a9ae36360b328bc5a77f0e31167d17ca43a6a2c8fb3e21b7196b510e6f048a552a9542a95aa7487b5d54298938af160bc4ac4758c111f646787678787529e1d18767660e0d9e151b56a6707860f16f13c12b7a7ea135f0d2384cedaa194ee44b91245157676623b2c887dc988b14a05e1121b7c683fe8c1bb3184e13251f9db270b378526d2444be380f9fc39d0871608f8f4d902610507f8f481e017133ab775766ad7e8f6e1cfd8445cb17f7548e7f858612b021130a9773e137a8978d8b74c4fc447818189f9b64dfa63be893fcc3fd14adb56fac848a7ee4da63f5920ba37756f7a988f1116dfe4d5586f67698ee870a3858a4128072ca055f17b78c8224ce69188623cf473aa30ff5b0e194e22c5188f189151461817d3e42cfe34bd8cd7bdf4f8eef0acdc80fa8db99659fc18e94649fae10518434172568f1123c960ba3d99468302902ca0e4dd005b32cf4674bc8c87fa1d1e6c6ddcb9604793f134f5d8082824fef4f80876213294ee173e9672e34386694f7344c7df005b3a3e07778326b3474ca68e614b308ca34022b30a0c5805414764ac8f4fcc571fa80ff54acb5e3c78d90b8d034cafe37130bd0edbc48afc26b64d49377ed6d9794590e36127239b4e1546682809896148b4734c618338b1bbbbdddd74297fec5c514aca2d257d39b549dd9372ce292773772eb638adcae6f79df65bc2f6a1906cbefc258ed4415906618bd6eca594524eaf85a49454bae65273395d9394ce3963a453c6f7d8164221f16156dba3c181fbee6fe0beb34b3c27fb27f7077e794eb684d2accbac958924cbe69c1ca58a21db1ffa6f2dd9638c91cefff932cbd8f35bfa6f7256fa4f321113cda066ffc9db5a969254fa7f30786625cc320fe2487a869c19bf7cf89f7c3a3750a5a5d1891a9feb55e4ac6ef98f56bebf527b5821a75a3eb5a80a219416da142d792fc06f246cb48c2a65490d250ea3a1a1f91e3b380c3663b3d5d4d46cdba7de86ce7cca6666b3b1d96a76a01ee31c0683c5a0580c4a8a35515213d1ff9a28c9631ef3581779ac899a88864223d38ca639e37c78b31ebf430f78b75937d82b6f875eedd0aaed95f42afbedb93b5925edc59e5e7df4f9b7209f9220971fc9c65e0f974a9fb74fc2b6a755dbebb0b1d1a73ef51af0ea40e940bd8e23333359229699188b59285751a99ac75105d11932246289b198656b6fe665bc6a6f663ef53166a4573333f0ce7cccd2ab946ba605d4e50fe7f2174467c89016bc06802ac7839ea3f28866229688e5e4c17ccba2b8c5895acbd0e558cc12b3c42ccc424de5f878fc8c8fc7b10f212be7ff216401e05bf898d4b700801c15108f897c581c16ec47adf5ec57dfded82f85f35f90dbbf838952f61b32a487fd742e0fab64c8902143229688256289592216235a62d850e9505a6b2aa552e9e8f0e861bfca63c6aa543a3a3a2ad57f2a656363f39b8e4af50f3b79f036b76906784dbf3567f2ba875d03e035d97fef2fb38e4a5555385f931ac2864d1712a6e3c2e72a612c613674a264a034a2768a731530bb3b8f99bd3f679566354fd3b9a0ecc1b9fd52a81567599629495df830f6a8369c9f51e13b51d9de707e46a5d4dd9ba166f2d7aedb00582146c650ac488b3ca27ea954cde3d01ca10fef56b23e30dada34bad9128fc32504b8b0ab0136e1462b058d7f13186b95807e09b4558cdef6fd69a23da2bddb1b602b0704b4a864223ad0e5fb355a9a24da54abbadd89fad5ebb19f8686f87ac91befab2fec6880b11b5f1a511b569b7611fafe9dc4df13019378a578d1e4c02dedb9a55918d7d21e7a0e0d7dbe34349c2efdd395c2049a859ee3483c273e4ffb959bfd37e195ebdfb19bc41b424a6dc7c8df932bad0f8d03baa5ddd02dad91806e3bd0e5699eeed9d914be306e10876630d2961e3f7fc82ba8fecc4cff634b61c38c8aad5ed44398c3065ba5ff602ceb2130a7f4747a381d64c8022e45c91a1c1d2e8539a577afa4a4c2d693e824ebfe628b503c7bf8ee3e214be70b7275228f0ea052291f14d822b5110a912faf3c416c12c1d8e073f035a60d9f21911ab4cb96a190d8f0653c71700533134022dca653c76d25537cb14ee6d52b4542e55ae5296fae66513e73470b02d4f52064abd5cddecabc8639b1e4c3eda7b2d51dc7964b696ac127de0ddb3e7fffcfbfe74de21f3fff8e0cbbbba5881cb1a0dc38ffaaaea94fed5c8779ff23ce8a49793b3c194f87073da73e4ad371f9db9c8ff34b34fbd56abf94c97e6f3f15673f9d93fd7662bcda3940b6606cfcf22a93fd543a1d44e22052c952ed51960665596e098b4b9f33ee21ce2d71f6d3e1d26755e9db69bcf4fbc751cd8cd6c0a2540a890e3133e9d17d6692deeee62236191ccbfa4b4176e335fbff3dcfb16804d42b78034824fb1212b5bf260a8aa914258a4430f88040c29d347b86d1c86bb041e6251b679973bee39904a366dfdfd37159c63dde0e3cf41871e959e62e1d0441709a6379a5a5ac6e1bc6666dfe9957932a0a87cee97f67ed4c5bb22ecd1ea1c20efd504aae7c96b1f62a7bf99d2bb31e696888efef83bc46f10710a23c18d47eeeced11caa06f5e59441091b6e1dbb35c99046c90db47137ec34668c6159623063380db921d0142abbb782b6706ecfb82885dafc2dd49d0512a1cfdf64402240bd9acfd6836c1f01b2fcc773201a3f695cd8417d24c69117177e0701b2fac873faab80df54fa7be873f29236c859feea9797caef2fff71e9ae23c98d34e8b831eb2367f9ebe8b5659e7c7f655e3cd141a476a70057ce70fd9b8868c7c84395fcd621def81dd441eeae2121b3ac2f3b3f23b96bd9e204b8120054f5501ba592a81890c53ffc63c6cf1290784eefa48a9288be7e55d9d9a96d74a4069297a42ffd6a278c80aa04bd1ce6518268237a09a323a4a4d810d1ebf57ac5dca88868c88d9899db9d5de0048d28f9082753a09452239c50c181808080a6bf5eaf97bb917b4783a6f965970212d58deab3965ec9cf9e4bcffe3c9f9fa5008970ecfdd5fe438f7e70c2856d5cf81d733a44d440ce8a1408c8fbfbd59f12f220af924a5dc9e2afc97ededd9e3f5e20eb68f0ae7639ce8350c86661e7d26cd4a1278b6ee8800416fde02c2448e010422ba5f1044da5a813a000ca32c8450f687ce544806a24a81ec39cf8b4a341bbfe5ba9bb01b6f88bfac5d7eda057a9f42abd4a2f0d48d380866e2674e5f650b5d90fc995ab9266d99396ab60b72295aab5e7661907b9845338e24288860ba687012824fe0f3029094f5e80045e7992c5f5e7f93b9e4ad50abd0b5c7f6e272091189bdd2463afa0906861ccd43eb86c110af593b00b851a0b66a752bf46622320fc182184b157523ec38fd2c9f23329353a6394378042e0bb96579da1ffb9f7ebfa330e11a832f59404b994dad8851fa35099aee69cb1a9307d2d5e0a296da0e89aa5b661de51bc7f5e3007be3bec691d222a8ae99873ce4c3aea631b5525916496c91c32cb648ccc320923b34c569965f2043fc618273b4b861042287d029de69c93facbf4c518636ca3f26f6955079f87db4a94ce68e5cf8713c2f9f0e72781935208adec97763250a97a5377fb69b7e99cd335fb21a477ce3927fcfe23a4a49e19912a0ff1642a9d9d973ee5cce6b4df9c736651c608ddd2c6296283385f24ba3de79c5386f9f2a107822037c97ce9c1d0aaee7aee69041cc7f5c16d0fa657fd5a9f1fe6f9c68800c6721050483f137af9f5d1e321a0aabf7a2c4433501b351217e9ee94e94f1e1379774c9ece9058fdfa3ba957f4fbfb8bceb7a6b9a09dde17e4768ec3e7ec56e2bcefef473f7a359dcf3ce97d4a82101dc1f4412efd545f2adeee3f7a2bca1403c39d4e9f752e294ddc9b7e3379f533eff4b17355db9dbaced471ea554a82f4bb922035ec88c20b0ea24e8401854192954a1e233168e1862237e42c8f71445cb823cecb4988fbc20d71469c1a1c129774b97b5dfed87e129246272c7a3580cb0280df8c454f87cee1ef9efaceefde5c7a4b6bb9fe9d45a8b1e895f6f4ddf27f4a66ecf6f72061a3ead02afe203ed98fc6ce7ea9de6c90d0fdb82169e43f4177fe078fa8d48ffe5c0e52dd2b7db52721cf59e324747a9d7c5a056b159f60a00637f473bf12fd89970b0214c21f9f50bf52d0e51314243af4ccce25954c866589825ed8799cb18b43abf888b362e81c7e6ec8a3fd2a3714e3866090b6291045a08c530de48154e16fccba9b93a090d67ebe16bf402249b412b91a1bed15fcfc374fc0467b35f3f543a6532a0e1becd54de5867c0fb0c15ba1165f105d78e3bb679e0f94867edd6c36b9d1875495d2f381defefe6f3e6dd51a757ef4be269749dfa65268af690ff396f69a0784950ec056ac1c454a1ada453d77ce87f0c400834317230753fa254b7a45b39a1a339a65d9677c3a751fe377907ebc1b7319a5b00835fb69433fb93435747ffa194ef59fdc6cfe29fbd30fad92bf84494da50f3b1b7ce84b2dc76ef4b9f4bbefdef4522ebc508b2250b9f4eb6f933b79f47fd8684703b527ea7d4d3efadb779d77facd9b1d3fb5b373f1cfce757af6a440c9989a5be33d7ded3c26f176bfc459395e7e8fb3502f3f87d7e339284bb9af6f7aae2e61a284bbf5616ca05fad0f35b7fbadc7d4b30312d2926d091323a31e9351cf0e4b5c56d76cccb7ffd0abad7e574f36f4cdfe87cd2ec91ede2dfb25ce8a2dd975dd76eabaafbf994edd69abcfd35b674db6a7da24a7cffef41f3462c0e9b3ef5efe0e3cf46afbfa5b578f6b673a75a75385799e86b1475a25e90ca7dbd98f2f77eb23e915b51fa5f653c2ddd29f7e2b9dbc235854fab0930187affee93f6a03fdee79bce32e925e755f0e75b21fbdb4a866cf56c9c7973e7d251f5ffa4a3e2797ad127eb64770e855bdf2bb72ec1a39fd76aacfa4af937bb25ff67cb2465a25bf5a1ecb37862d3e17e6422db254696e4767476748ebe82c6142b3547899f0cdb80a555bfdecbf27f73b7d4dee57fa244cfa7ed99f98f4fd46f0e4d6ee79ba7a5fc99e3c15106af79d0d9d4dc29f7d127e9c5649feecf425a63836f067f27154a7cee37a2af1c932e130a40461286e9c7cf85b2743d7f9a0e3ac1e239d213d46a51ea35a754a3a3b62d4ef23447c4f5faab5d46ddef63c5eb92f7532949e7fcb7ae038e818b5869b68fae132e964d8be7b9e5ec9285f3ef57ce07b7a9d5e652f7fc84ee6d567fecc64e96719cd3ca8ea231001efb8eeae95b412fd1e3a17750d4aa10d389e70831ffc600848380a226986524a97742e2f421057d33e049d4bd360972b72b08506b037aee0a509af219c4080c6d5b4ff00dd3458051647650cc107596256981084124a3a97832184abd55ced93742e4df3f9028521b8a0220a22329610441b53fbc060e252fa1e40da6036033380f083c516563ca10b1470a0e18225d0784113925082124630251eb4ef4063f1e182c8a5cf811e31de88e2c3850e626b10818616664839d10dec00798b2a4cd4935c0345a680c113c24043095950918420b0704f37ba692edce088285be028821830a3a3eb3fc48728e53cf742394bb70c60800a81e5e4493d9dcb6dceb0820d2454b9f42fa0f19538b6540b5480d212e490f8222b9574a040e7dab29801640433a670e94f80377777219848514a7d938012566ea9f4483a5789390a37b8c60d625a6c20832c3190828433c4d04a9e27954aaf086c9f43e7da585ca4c0e2844b1f02a518602c07554081c2126f40d14513ce08a20be99bfd220c07eed2327a7069195c98b8f41fa0717073419922e90860b8118588969b711d054680f184139aa084116bb4b8285144b592a6713740588423e26eef80ceb56dd1c2a54fa370e91fa9da4689c8c06708423ea0c28a2bb4fc53febf230924baad2473f0c33fdadb7084270470e937c08d8c886613bd5e2f275a73ce8749dc39e77c9eb28561803020113c5516747c500de8057ef161294ca505467003cb0f1c58540006961524618a18111616b801d38265ca1b585a0006161754c1f282d7f5674095ebbf801a3ad79c4e5e7094e1d3842932483a82163f88c2442d6ba1acd87a022485095378b101186e18b5c8785901632db548568c60c515515e2f057029c618e373ec8a28dc9865884a8c34c62b98b8316e11912212dc12adb872e316638c21c6d799c28d436e44dd404acc8d91a95cb1825bfa587a1a3a57a9b419e95c255884628596ab7dd47e86cea5314c2b59ed65e85c9a17ffe203382efd48dfd5b9288df463e85cb40bc79a3e10e24e03dce9832ceefc04d4196103b8f35b9d6b3a91118a3e1c16ee1704861d7cc183175ce78114aef7c08beb4231b8ee4242b8feb7737984f12000e97acce34c8207939134774ae71fa073cd1d58b931be013a57f449bd4451461353a420a80b5011125d48cd3a52127d183a17dd011377ce2f1283d73cc1022f58ce0883cb0ac648020734c61889742ead0a27dcf9b15739777e016629bac3222a45304aa3891e28c189961b010925c8394bdaef742eede36ed44114aa00baf1599d2be9f57abd7e628c31c658fa189f205186103d40c10b94508497567c558c915a476a9527cda9590ab7cd7ef487a750fa9aad4f632dfd8a51d771823011f71b02c3f52cf0835bbcbb1ff412c47dca75a652c6c7555cc7e2fae36007b4a65ea563c5f5dfe1317224688beb8f040754b8fe3c2c09e2faff9083245e534081c5ae076971fdf9078806d79fabf40a5e99e28debcf41bd8257a828ba0eafe8208aebff02c766d4e6ab099552cd7e1136c48a1b77ce2740e79a27984204266a4004259880c69623741aad930ec08a1737c617808eb31c69ce28010525acc862882668d00ae365048c91914ee7722c52906efc18df8577961b19adfce5ab1c251fa671a59432bec6184375bf9a2b5c09e38b942f4f7803cbf50f807b69f90b09d2b9241295ce82eb3e931cc98bd3163a975f41ca9542ae7c00742e99d4ab48a37ff5ebd47a927524247a59e65801e9469c1b5fd5b9225252afe0fd5a0a0ab26f9f66f14fe7f037949b7197a39b3d2331e166f7632fafa122da78e3063e18a3f5715211eec75b9a155f5c6e5685502c8e9b65b9190e9810e48614cc70a3054db43e1e7224a41bb00fc36ef61cc50837bb1f4b41e30da09f1aa4a08b1f305a1fff00b1dce8cbcde096a29b7d0f11a6ece1078f201291169613750e7ff6d55c86358ecab32cbc6c6d1c1185083ff8420b174c697d3b377b18f3c2dd2c8b15ac20c2152ba868c115adec6be6b11811ee5773fd7e38d7a51071dd9fd6a0eb52e0b8ee4417d71f88ea7acc290c11aeff8f1b7d3abeceb89af63e3a972661e0a5b9db84944be9e3742eaab13e7f4ae9a4b48bab71f99998e2cef92c74aee934c6e8fa5bdfd2ce858922aefcd82b005cf95ee792f1e53f3bf67a01f10f4f61a05eb965a4d7eb7e6e19c8f20f6439124b59228c2137fe23b1b43d542481f8877f82d87dea0dd05dc2cf43115c20050b0f82b6807941e5776c9698a2077d512155d3b9b298fb71d7a30c5d1fe3fa122fb8fe3495715e2bd0c13c2385eb1ffd794028c270624b132988c14f1b5ac888e154e7ca9400ba2ec6f5dfc140afd7eb0877f7ea2b25a650810cc228c228072d7f95232174dd5da673b97c1d3ee096fbd580713f9c02dc2fc81018c2b81fcc723fa8e508366ef691f6e06629e072054a101241dcec75767a05af2061c5cd9e2709246ef6469230bad9a320d117a508cb71440cd2ebf52ac2dd1d0152b8bc91061420bc0184967771fd09d75d3a4ce7f2ece187ba590dce10ee17e422e07e436ef6b0899bddec0aec8a9b7d4a889b5d318207470471b3af3b4f5e6f40810a29e0f081f204175996f8c9e40aea690c18aebfa96211028c5211575cffd8c9181b666490abc2f58ffe5bec927875f1e52cfe99ee0452f6acd8e27835226af0c5f5a7d9d7d4a3ae4451054daaa0ca9f9d4b12e1f3e3fa675b044145ade23ad1f597d1d991bc197c8132458a16327e3084e595832dc6e847481a67725215d4f8d220b51c7419054cd8eb1f8f22e41feaac039401c517579418021763b4b22daec49164ba99fd8cfcc8bbc827f8c7a7cb0dc08def7ec41f8ca157fed91fd971567c7df6d957673dc9c28ca02329146184154368659fea1514c2cdca78a20a4fa4f1061648a8d1ca8270332c486871b31fd2ab793369fdc8288d0af9bd8bfac5a29f167395cbb127af17d1bd3e35b8fed18d9c455bfc7ea419dda8c38d032d4054c0fa9b38d9a480146bf53b814140aaa2d5df0456a1e5040aa1d5d60a3f7c27cc453688332b8cb779e125965aa246da3834298df1f36a4d8b24f3687098db1aad697b96a85132b45730618d96fb0e357210a5553a4b546ee4087fdce1f11cfe6f47364319ad60c4abe5dcf4687298403090a5a1ee533f58947acfe9f93eb4f45fca8962ec2db7b5b4aa63adea2cb7fb1585058c861062088107adb8659c7b1cc4142dba0cd142e3083188b5320f0ac18cd6568272446b7adb1684283680e28b586be3a01cd1e22a4df81c7146acc550c4c841acb57554ae4489b5b63969e0456b7a4cc507caab45bdf8c417ade96ddc176220010c20c45a5b47c3cf4f7cd1622a8a5ad3a361eb006ed167a12c5ec45a7c450917c45a9ba9c80a71c45a1bf56648a589ab60a2353d2efac1155e2dea6d1c17d9055218e1d5ca3c1e8206ad2d73e641133d78b5320f56414aeb87195d5469359967b49ca06cd0ca7e7a4db42d9260ad26d93bc992dc10422b9b9e8f1f40016b6d1a373d0244a18b576b2b71d3d3f1228ba1162c82138c88b5324fa78ad6c6498ed376aa6843a895793546b436caf1b044adad82ad6d7a4da21536805a4e281aad8d9b1ef59c66a2d2f03fb9dcaa8d63411262560841ad69b326ecc415aab49a3899ef44481a42b4a63571d363338ae0628b2aad26fcc45151cb49abd182fdc2c75dae909aa607d7880295a056e66d5eb43658caaed4724446522bf336315ad1eb97090711c6224f4145e5242a4ba9dc44e5e7e9212b00caa282a3d317efa784bb7095bd94524ec950d805f9ecf54bcf37e6daf387cc92a1c8d8aa8f4d64dc3014b439babfafb05da1f2336bf9a7bdfa3299bd7c4e22334f265179bc9f9b760658f338aa3bbf5cf8ee04bfe096188fb40a664eb52c6a59ac25123e99f42c4e9d8c4e9f71ce39df5698033f7b98fd94f06351ab60bc3246b7bca5553aa52e47f7a3334022a348c90671fe51ff28e841083d0521a3208419e788eeeeee15be3b64c83483b5734108ddb3a717c2e8fe303fa725d1d4b9321d54d7b9b22cd52af81c0e4ce28e7c8a4b2da154fe9d56c14c468fee514a9dcba99459a675aeacba9436f382b44a663263a11875464dd556795f9d3a9e5ce8de04777777cfc15595e7381b06407151c6650a602ad5b92084d55934e5906b8ace9a8271268341079549752e29510f3b06e4b849205582baf077742e98a56aca73744021f03bced07001a84fa824ad3685452c1522111101008000e314002028100c88c482e180340d3465fc14800d7a9650845c9c88b324c7619042c610430c0100000000444466a80600c09abea3809d74fd494ac0661d8b9320301525a617e5caf9e6da4fbf02d176c0950a7a7b4a92cb8116a85c9dc2ee3e805dffaf82bd0f71017e9bd47699a28423fa23806aee7b0ae7d9fe28180b0f1fdcc2a0ca2f2881dcf29177a48381949e7c4a0d0781ed34fbfb2bb067bf4e76590e6dc416587bd832f8859b62f36f11d331518cba294d86c6bb5e25f054cd5842f87b8c72c9b512722dc0cb833499d5e1fee8495017756c62ee1337c449615be900844cba6c08402fe661c180b504834ca782b3925395773ff376f40635bae9ac756e6de2d48a40ef09df40a269b8e7cb53d9f01b99c119f74785c6d58550ea6376bf1c5ce723b75d4fbeab0ee26fd691f6e693922f0ad21d291692c63cd16ea342fefa8e4f39d60c3b244ddd24c75d91c28eff276fd2a80f722379a28976d3bdbbbff6fc91abc76205c8088d56e8fb44ff3e6b1b2090158584a6e3c18d48c5ad91f15efaaa3250038f996cd0c071dffbafece5fda11012c0a02b7eba8b27a5594cb33444f27d99169473c85b38785acdba452055067071276afa382b228e31c42206bd32501db6cef2c1d0800c2bd6e79785d0d3527dc457ed8743be47a2b84ccb6e9b844a912bb0da020ad82b12886538b9354ff61da45ad199208ee8272428809c2cb7119ce628bd9176c5ebcfd0284f56443bb234070997785e9621f2271f045aab255e16455443d7ca88dbf036490b765270f629661d026d63c0d9aeeab9d5631ff4a1665165516bd0d99f3bbf631a216395fbef2a670759f67aec73d33db6d008e26d527e4d4064fb672b9375da7d87584db58fa41d0433e11f59e3b3b0c33e2221c2839b839472c73c5887ee531d94563f5574396748c7b81953a89fd46c470bec01148c7501dac8b107ffca695fa1322add1e7cc39f52d7c88cd4cf32e0432894e00df2853e72302b05e2c01db7744c26c5248cdba7af1547ab2fc3810612ee7b17dc72ed2d2b1ddf02bd2f4be3d1018d659588f2998173c8fdc9d83799b3dd32f105ba40f012d96b7d79f6b5020617584235472a4fbca75360660dcacf1b319996070524370e55be7526615cb0f7a35f90bdde094c82e7a2306ca75128d62a1ea0903290535e0dc34928bc65b62cbf8df313e266d08c0a6a495ff0528caed4dddb8664fb623ff7a0a96e18750da0744af67f03ad513db4a431d69e4f227411c34c96c332725814c65ef8d56504ff698696064f9ebf4189abd37e74a169748a2105f6bd203c0e2d9531c2059ab28c5a1668b4f9cc6f32905a033a1ba29c6459ead551cf64868f6dec32c4bda17af036a097a46e764255328a35e06de4115f49f272c896ee54d1e209d05d2a899551b04962010a11a33427d9fc65d1bf0e878c1a234c0d83f454ac157de5439b86c3b3c532895046c20278adc8c7d2bb94792f5eac768640693338ff0d778250cc29983908681d080b30787f1725145d527192f2e162b900b649e5f7a32f9e542918bd5e2863ca94712291f670d9fac7ed4a43a321f441c43abb4a14c9e79c799db6c1d44243af2111185026a5d288be0664e3ff7171f4a2b43b19fcd54498ed29821f53a710827d8b46df60c13f1c713de0c97e13277a0fc7794b15d25d026c300b0284358f308a24e73ca6cc51a52b79a7f956abcfc0a556435c0ab634243c9c7390a38014c24054cf392efb8ba59b41fffd5d65a8697c4dd3202c5317c08c0a69682bf37b0d58c02afd4d0b855eda670262701c236c6a012bfb164f099e9d036acc0b4b7675d23c7bfffc418ea7e4dfaa036f5c7b230e904ce9c0f422e48a295a3e675d8956b88c11eaff0b998ffb58120d835864713422309dcb5f652b43d15e2b54933c4a15d61839fda281d4e10af68d38724eef5bc3c2e3708c3ee0a035e7adf55258e6ee828c47b7573f1cbfca269c917f619c81e7cd8f07efd0ea827139ff4e2784f0c0c072980e530aa4ddc39025bc0cdf21ab8a070c5d642bbff5ce56670918be2a7fece1c8925d80808052ea4caa25c8cb7393b3904f2e1c09fca1ac135f3f54a9d700298d466615e26ecef3df6d13e9a0123135a54c9b31c7c1c9a5e1bc257dcc318855ff1aa5279cab1f69dcf621dcf39b03f79df06eefc87011e5fd095fe5fb8891a5104717f43372398e770fbade440e143e77a8a279113dfadb910e0fea9d100f75584c63864853e18fb7ba4030dc4fe4542edcbafc93c93feb7e7200ecab9df1e326d2ff0402fbe0f5cf1232a19aae4d8deb44971bf0b6a8fd50c6d5cd980787d3175f9011b05a9bd11817c84fff5cf6c6d1e57cf538848904f638e3c9c222c7e57fc0d5db32e79972760587da9086f85cb6737620745dee394f672301fac96cd8a0aa0cb4b0f5668aae2968084a2d5fa8356b8d54598ec77d25d883382547fa665c72195c1712f8ad0bd4ad5443d343736a914f7e40354a8192bdeb450996ab1db96bd1959505d420ca9d62546697ee2d9af0a5b4fff8781a24174701cd86a3d6deaa760fb7bab442e91b240787576257d26089579db051b6399317a44ffa2d798b5a214a9067465fe45d09283f249006186084886d1760d46764e4c4f15afb75a10cb3e3c1587b4dced56b34a2c7102e2e22fc0a1d57a99ce2a3c4eb3ee3bdc1b52b4f94b7455f0335aa1bf33b33cdb28bc919bca9fc47ab8a4dad8a3f44608c3f1882824342603c2dd6cd3e0467d82dcda7eb0d82ed729f2737fcb66c114b9a9d716b4b9e000305a886b1ec38599a04191b96619b74341e76aa10fb0cf3a32b154d501984b9d1cb5130b1dfbd4436b706ef7485b8e247cc7cc602eb1fa592a18fb6f93be535ad064fb4b03b72422d9a47035d0ec3d025aee4d3d3aeaab8ed6bb371f093a667cdc2b41c3148da414ad9022b7d98e6eb9829ca1a63a1a37809fe66311cdfe531ba7cb6e3418b53b164e6983140f3845011a7d4bd004018469f4091ce749c403999f9ccb637624afb3f73a3b2022adf6472ad132508ccb891d71cfa5cc1d25921deb12c8ed5d9280a376ced3921c5e19965517c64473ccdebc0157094c3c314a89e4cc3f1c7c83706dfd74e19190fda10542a0a08f3a522c6dab83ab796e944cf2684069f96a6f744cbdceca19940832eac863dbf4cf9c6e170e1cb8beb0f73e63b2d223cf99fc6deec730db24f01e7dc49481f62b9167b1c5c1c7fc53d5907ef008eb24b6cbc048a624758bf98940ba205827330718f90af00598359a5b8aef1b4191fe28a16bf7d15f380ee49b5b6d0feeec7528278a8a347919bfb2710f0865e0a11345379b5322bcd97b694294c1182dc951e77e102d3453353469e0190726fccda749a8841b0cd64690e97c9bdfc2b58514b06d7531a042f870c8270f65d60f60bf1404708e373b519d60ba25107bccd201d1751b9dc4d62abfa39f02cd0e6c7401bd56e35fba5146696e5ba14f4b6af18af6130360138ac9a7f8d7ee4c8e5bf9303b81d4b56b0e8c2b083f2e6d1b98154718c2d1f69cd438509d06a4d987cb0dbd33c099594cf7abf9faadaad900912f2821e5c9c00c09eb48b9aad49b5b277d2fb21915b176c5eb63db368d7eca70965b8358f7df0eeafea70ea219fca5a53c87403e90b7a179590a06ada67e7443f8296145928f3c11080880938492196449a4e3291c1f8144be7bd4b96cc0f91ea8b147ebf17a9e030e54775e32c31516d95f24a92513aad244cdd8bca1099445b88257307f1038022cfe9420783ea34b830be97b0d9e410d68db85a086c3e5d5ab3ee602cbe583f71d23b1c0d427e6c2b803e971da54d1adb70df7fc15dc7771c84653d62c21910f474fd73b0e7a945d44981d7525fdf7d3f86bbe2823387647a497b2e2239578176727f2d325cacc81479f5bffc65156406471c730b5f2aa6965485360926d079a0159d449201950016b650c5e4e5ec6b422d34b6cc984d1f686aa1262d94a4d99ece8b1999ec9203a14158f209521d856ae4442042c5584bfdd32c7c9544687c41465ed9302eb2919260282ae883ce68b0e42003cd5900395529613938dcdbd4fbd0647d3e556d79c5fbef7a8bf6e2714562bd4c951976287bb06b6d3e044336a25e219fefeed9fd3635add742943cbf35b36f04ea51221d4689c48e6e2c0a12f03793c41677c34dc17d9a124f1a5f3551a07faca148135bb4850339e4857e8918f5df6575d5678ea775441a368a77991e2d720dfe95219a88b917f81e332ad1ec5ca5d837e24fbd25015582581edf3199ea5ce4fe8f917dda8fe466471ca9d9660fa4dc031cb0fcc9f6981fa8f27981136639400889da189008502e4579f404717db37e595751252bd24fd28849efc47f850c83f1ee03cace119f2a45b336a504da680694b463bf75715c18ca5735ba2e400e2e6d4adc79026323f6c7d24ece6b42699a58e054f086a9cb034d9406969180dc9edd1b944415e12763477444f6002152755fcbc259b97d37c733838eeb2a29db1fbf81f12aea1f2540176be585e1a5c5471966c8cbeee28a91c2d157d82cbb0890de8c94981a1fb7213dcd381d41c27a904020cf84f6ec5e08a789e7f3ad753d744e188a205b019cf03e350a1e9a4e33f8dcea665b5c09b28481b524dd72ec79005fb2179c85677be806a8847fedb4239f9c15c2dbb26f6b1d1200076a2bbaea33f7c3018601805af743b3f0450a9cc66bb72c4052398868d6334c74e88277e51a0337629c466a4eead9662333727013607001ee875801b7fd952496a7dedc5e8ebf5a78aa129e3131b237505fef5ed221aaa90d942c75abb3fa3582710a0bd27493b5afe9b5b7b30bd6a139cfdc7e0cc83d1236b2e1d4e6dc6c701b1f06fe41342e209baae128ebaac2e4591cee50462eb0c85444e178d3356804bdcc01963858328d0e7e7d54ea9ecc3ef42954bf82f2a9992bcf2d080f8e26c90958b1213597972e76510ff0f916736856b00c7c544bfd5beb9f809717d5253d1fd847603cbd6d2f299b46a42219a2580cfe5a097e193df4d09b95e8895c84e6177bc576f982cbf75ba2e5135aab2b2cb640557cd75d747bdfca123445fce1dffaa087e3e1a0499f93ba0d518b4b4712b5f99613297d147cf239a1c0785614ad77c9bdf00685880b74e432cd26348a98522a890818bd7768258bbec486a4881c5223d6ec25e92d007d3a5e4ea44d1a07fdeadf5485a8b27d52690ddb9bbf67820d1537467bb8dd2aeaf3909a38f2cd9a4329f561a57a2c4caab60dd440b230996f44cc90abfc23800721488f4d9afcc79f2cb08479ca917e918ec4bf60fadfab23895e01fa2c317c0215a089908b650f7ffdaad31bb7528ff30818d0064a006819b30c485e03d8feb697984c28508d6910a00cde0802c9fe558374100ce021537e97437c0e2a712724078f0597c9e73d6894c29a0802c76b0f068176f2e740fbdc2e48dbb8e2890719d08e01c6eda0f2e749ab77af2013e43ff51b6bb569c5847ec4b5fc528e4a7ff688853684b24862013a13aa3e271d145b1ff106ee5db24263f6e48f989bd83572bce0d4a9f7e69e4d321551b210aaeab5522b30ea17fbffeb83eea92ffb0c53ffb30896dc61bbd44c71e75261776d8b8336a82170bb715735bb65ac72b309817e7a0f87895d0380784742c54509fdd49c410927b2a57f7866d383661174f2efd0d425329c2214ffb6a3413b32dcc87f8bd505426398ded49d52e595d4689d883d403b39b735d1fd201c8d3949b3d2f556186683d922ab62f96ed4d5b45ae3c9acf7f4f3d5aedf2278af946333cf2a0dbae19589ca8be624cbe9e0710b222da5e4ff37f50907e50aec05f6e0d145b80ddfe9e2c08596a0b33f63ead019d30095497516a84338179a54b77e0e588ef20968c722c0d6a21e269de24307bc0adacc2e333f181e880220b28af047531f12e430bc67ec683c64a312113c2f3c642278bc236df34bdc5857ba6c86e2175e208609825a2e5f178ff135530f4da302620ea2e820506414e3647e054aed7efe9f7de6eb95c98b8bf4de69690d41c1a8eacee35d05f318094ae197a901c327c277370681495c9807c78e2ac4b63824d6e2053e05684e198552f55675932f95ea776e4e69d283ae89206e439ead4091b606660ff23625c6153b20b1b42e9bf9f6e2fc4a7f7596029f5c730f2ff555a0d302155c17503c8b1842249c0650e3ac60f00a212bb974fa093d4ef136d22a558c534318382f5a2dfa466fbe041f715ccb196b8f1049f8c5e91e8eeda0173db50eebba29ca7ad5ef2b8490f80db9d6b34cfada69b8be72499f76e9a771f7669844d2a0f99b682f7f00c2f7462190318007115445f4fda54320fb7fee6457c4f79d412b79d45150a2e6ab55d0b30a2696a776d4889d804fd66feb3c40d84b2281145459ed036ba498913d80a280a371b2316e5ef1c92220529d3737e3686bdb90580c207478b4e65226fcb4078eafa170bb65776a9110b03241c30366b3e49fa2524744826fdc74d2c572544d48c2fcd1f431858fefd60114169017788cba78c6d0d64918cf0e2cb220de0b29ff077ea45b008de8b4f1df30eb5b8be26e0d8042f08ce9f3115d249d5c38f621be8236b851f3c5b1a90a83d7a1885d8240884c7cdce7cfc1af98345f2bcc4066c42115c761967300628912529be40e7a406081c0be7f990800eb8658fe15748f86a94c46dc87dc4f95a01f17b8561b22ee34c4f6ede0267df116e8bc712be7f3e1042d30585dc5a0aa1935fc801f62e6c082152dfa320d299fcc56084ef56e468ab029393c988f89ef78f9bbfd3ae86231bb3d8ffd042a63fff4e8c60862e8b677fd02106b7242576ba8cceda92136ec9d5603428de5551257c80dfb891f5482bcc056b788d5477b5143b40e316751086b3f53f11406cfd70bd873e159302314ccf92be8e91e35085a923899fee874e2cfb6a3704dfdb6f820250d432d67ff24380b70ca28e53c07d6c8833559154ad6fca1edc22817f6de75a87353467691a1cbfb8c4e79e8824c6822c71906ab5cc27edb0496114e04e8277a0d855e702ec34d2ac5cc7b601d093fdf1864413ce888eb1fed43462738590b77030ceed21084cfa8352e181a0bc90561ed93507699c2060a980bacda855871b3ba2b63879bacfcf58ce59348ab3f8a9ac1f022d12102cc0128ee35bac65064911241d958892312dd83912214bd9a118a71ab4928c1a5240311863527d85119c47129f0cf1d678604d6948771b0de28a9405f6a8038c354d453322b642dfdac306a9a47162d968ecd510be63f74378d6a70ec84152d1608d9adc5dbe73e3a873802069944c706105e90a2feb964033912b8414cbccab8c649a19d53b01b29eb9208d5a5bb822797ce4562eb75d4f9051a787d96004e69e97caed3140949189fb18a49d86d124b775775802341b98e4ba78306755fa5a32b59f054950ec11aeb4f36008de006d2714d3f62b00ab51b512d2db4c2f086443d5f7d51ec2f46ab85b72048d41e174df76fc395dee3f5f9fd4cba9f8fb58939646c8dd9fbd9dcd9ea899d83a677ff4e1f7ddceaaf288d618a2e86e1249e32d96bbb20ac18186350b5bf2b6ea5c78b101203cb1a1fb7f4104fc204c59cffda1002e7b8c418875e5349bac6c194dfbbfe772b628627936c06fa1787995e2a927fe9d8c219742600a0ac077972bcbafc91590153c520a654db75c5a5c8b46909106bcf7b97bdca5ea13266b38f48506d8a1b91a83ee61df626200f411d3b67fe625e40c10e471f74edfcf44d7fe3e875788fe8e44ee68029e55e1cdcd9b6f23f07f1646e277911e778e0c4bc51bf14bc201b4834d62d3a28ca71751d38843f16cdee78914df9fb824bf1b128ac6a5a2ba260ca00f1a0020914b2ea2865b6c180d1fe6e05c3db4fb19dc264aeb204026c1a04bee63bd0dece055126ac94378ef04dda50bc0d0c8fcd817cc370e0c8b27c52ac75c79127d6c27c84aa0c32c7a103c6e4c4fba8601fdf501eb1a9b8d285734a0e3af4e892151b72a39a8a53b3b8e5baf846395fe86073fa3d9f0bc283e6ed3af53b95507bc3f70ca29cf5c0465215ddac280dfb08a6d834297d927c3893b8db8dc979fc0e57f3f50fa721629e285e6fd594f4ed855c491962a03c71e5912fc74a09204b890476c5c05bf16cf0f0899d7c4af4f7076bb73925b8c985509e03f6c2397c8b3b35ccb8efbebf74c345112ef0a88e6436786eefcb78354fd29a20fc74909b57ef38427e7b8da2048edcf808e44cdf98ccb66f86caa7538f1011bf58c09c60ed8cb5ad1c25841c62f4e55f08637ffc35f5b7aec18d4d311b69c1a40ab8e399e4e3df6b7603ad8f03d84bd6ab6a4083171c08d631c90b0eb0db26f77452ed7aa839ce0656d464267151cc265d37089857a41fb523160af9c8e3acd083a0b3e724be3aa235e548762e698c9c65b1b54ed289c801dfb534f8c0446f44a799d2d0285f71313d850b0b7aba2cda2c717aa4b78d986541ff849eec605441dddb97ff8855046fe37126dcec9821ac61bac68d49f3aa0861a545cf13eb40d11c2795d00886ca9c1b0cc68bfe5cbb6ecae6867b35e2ecf7435fe47aed5535a9f3c158f88a56b820418621d1eddb2be6f05dedcbf58ac03879be8d644f29cfd4c9411242d2a0a9301283c8b46aa42f9cf28d93db087e02f346357ee210d2c1abfe474242f9584a679fe4653215cf20f76d8900689d6f556b3990f4c6086fd3c487a397809ed51a9eeaa38350675fbdf6d897db13218e0feb9ad016ba20e6fb614be091db3c8d5105e3f66cb8579b974c7deab1cfc305306f3e9d0de13966a4dceda5b92dbabd6c1316f2b52bca43aa3baa7a8c401eeb4d07cf4719f25704fc8f6b892012fbe19a00be2bce8ad70bc0818b0a4421c7bdff0c3208e9c43a0ae2d627832ce6c082807d72453c951ff05877cfdff13553e73321819de1b5f18a8fc247f8a9a540b5a7a6449a554a8720a674c8a3d221185dfdfef99075825b173f788a759b01e42c0686e978ec1917d486ae02287f99ceef8901b4bc10ea16c37129eec00337e7710ca7df09218d6b32b0978656dc79154d6b7c7987b0ea4de20641c42e950dcf47da61607e9fd53153cd458ab712910bbf67d42274f2a378cd505d1b317a9cbf15977f2f896cf7a7c28b947fc4f21786ba583179e31198893ce6be365f080a06e6d4fd8d2afaed3ba2e4b0a64bb18074bc6ebd0cbdb384b816d65bb205f74ad12db7953ca87da0f62384432267ef7f30852226f846e36d4d41fd5a6a73c902d725d0acce8ae5ecbfb1b1374033e68d0270800ba1ba102dc063f37bcf88dacad289c5544e21d6a8c6cc29d0773f14a7b41ae557498df35872c682a7e65227433ec88fbd4b1afb670045f7df131db6d175d226b1640fda2e759b097cb8929e9e1d79db3187c76cc4aa6a940067bb19998faa8f023448088356ef41a6d74497a39d290a401bac5e4e3c5732c36ac9a371d1ad0f6866f4214da76e4a6e19055e6d490c3bb8ae8cb3275c210c2b04b22372d904b27087e808b2483ce70044cdd7d3e0e491aaed4aa87604cd4c00cce0dd5583d5204e91ce0dcf5cabd41907291967727a88c29e32e47c59d2615273b066659d5292cd69bd9990accc3f428ba0d54dd66cb98307d61a06f723d0186a309c120b8129ef354746e54dcb02f6eac0f1b906c07e3770b234495c732d32073e90cd2c89c67c1f61745b213511c09ae5046c6f6bae8b10a7b9a1cd63e08b78a91f00c5af8ce9e08c63211deb5f05951bacf49f4af63cdf32842c0654c534ceeefc82b7ff5db3dde9c154591b5c9192b8043856e5b9806490bb489e25d293806f05c2e9329316e5e8103c9e606145abde0aa912512ece14993e7364fe3bdc5e06e810914b5e45bbe91b695104b190507bae7fa1883bebe27ccc8fab0724becebd1280577264a1ca598184d6a3138d0b0078c18336a8c1c4bd9674737ebe993a2e01be5e4f1a9081f2e351ce41283e7b4df435234f6657beaa14f0da0a096185e580c236762cbb58975e77b1e613ed483117d6a3f0e54d894ad197c4d511c3c927405262f5dd328a90591a44f6290c27901f7427c2493d0a2254ab5bc79cd416fff5f25bbea79b1f2d5397057bdc5e6803edad9fc437770132e0aae54b253e99c798f3dd171d2c18ccfc4ca75486c0a2fe18894293fc4424c97d290eef8a893e379dfb524c6c5cdafa855ea07004305358ab12b8f09ca6a6c01627be66bbca290bd11a8d982b0f2ce33d1bdcfd324cbfd4e38078f9d3c790df279fe238586b344945323dd89390203407a90204c8ad3fa349c00c81ead51333be56d9facf8e161c7ac8ca96ee6df6227569c49ca07c73b8911e06ea7719b217bfe24501f5b3aacf866a0c19d89e29ea9c73d4673294252b08ff1485860064771b449a9fd33b49956dfc7cdd1dc8d62e3f2bf0b9fc5e0de9ac673b9489b14c15a884d70de4efe265cd0900e22b24c3253f3d6d2058681e6b9dc03eed2c2817d31b1305f53faecd7f90a6cf9de3a1a654a856eb1388246fe063f3f64d9a83ebbbda65f28458ecb95d75cabc2d3af36e50de813afb5beab451a2bbeea9437df7aa2009063345605f7a0ea016dc5b0beed0296565e5b352e25243f22354897117e8ecdd3a3e5843f5eeb8968b6a433e92d62469581aa4e616d3faf4ee33df1af2d932d04ea482517dd93e1fe13bb65d4058bca7fd0b6b4a923d2c609cfa6e484b8bb4c59e5ac5edcfa5d7fcdef4a574bee1ac7463db93d97b68b5bf9f25cf3d11046c325a267dc2ba48dfd4a2b0888699f19e7f436df40aaadb8b403ba59c7bdaafb2bad64c5fa6b8f8fe204b04c7a7b3e365643d729abf949012d2f063222a67ca511baebee0c12807a1532c24d49c4f538d69021977c3550b1343ae668dfbcbb03b3e41bf00b38f25943b3a685d31fcd906d748ef4d2c2c0207d22cbe1e14cb619af8b88cec8b9d7a2ed8afe009239c38a6e9aff80699dc0cfa07d32dae68fe8c5f59242d99259d0c32cba5a2c2aae8bf43cf9bf71af95e1e9c60dfc27763425b734a738613d89a85d431347412c5b32db86a8abf8863d26fb6938d07b22443f8ec2a32b4808c5baec61664c7ce332e302e6c965da0295e90326279894cad6652a02050021015dde98da1069eac20dee0bae3c80cde9eed1cfa87676b5cf3760c4bcf2eca672b1b092d1e8766b78fa8496c7a01b87e825d9d7622dd6ca9b966a472041c2383a55ac95cd071b406115931ba71a7f9c78a0c95a4e1bb7cae66ac3ac24a1c86e0cb3a75f98cf475bfc0dde0f01ec0b3124249aa7c300d5fcaa25cc5b5aa1690cf5911a3c69919db9503d7e513067cbddb135702cd7e0a3dd1e5d26c002cb43b57095f6da6eb4b6b28ec39947fea5ade88b8998fad873a0db4036aa095cff8f57bc50d4f862138afcfd3518676a053307a1cd420c755c0affd6a8a6d8529a303bcf6ba3d6f40d85b3525875244b9bda7a889be984e2ea3d473b3564670a8156ec5a1653e6641a536357234fb5842022cd96f43fa047a3f8d16c34d319b0cb81f166f25fc22d9b17bae2315a4549b54506f20a3d3c73d787c3869fc1169ea721a71288dc59221d42ff6500cab620b6d1c23ed99173504ad43ab84e3759eb027c37dca0a521db587271ec875e03beb300dc6bdd3249350c19c6d458d63836f7c900d0f4f87f4fc60232084687ae219a7f82682f1c0d4a3e9f697a2e407c8ed9702c8f338f3510d11b83371995bf8c4f56d65514008e58fd595b045fb4167527ca57078ba4037c1a135deb3645bab9ffe0abf00fa52a4571d59e39a48a78b0d8d29936920f4f62453908bffb626cebedb8f520a9b28da8d3fbbe51dc4a3477ba2cc0ed3be7fd27635db32c464f582db19443284afeeed223619b4899baa9ac5ff66720fc93f1522138807210f15e5871a2677c5604041e4460de9dcb416944594b1db0e022c27531762adde0bf0dcfd68a96f810552f1d723fe5cda9d8abb16096bca710dcdae169b0088a0b4ad082c99e990f2992aea6193d2dc760eb5ebfd6bfbdee657418baa35d987655cf9b2467ecf07c287581b9c42dd009929e8255c0a3a7b99e0bc47721f83e059828dcc2ee9a6abd2364844e90405f90fae6c010dc447b3e98d799bde59f051aaddca5414e5913fedd47c667d49c58f26a23e9257c0f3f2291a7431aa261024cdcabdc067662e93382093b0de4d3ddb48e5ecd53f62bd7002b09e42713892367a87bcf260b2aabc80f47da1a91ddd0272f3a5f31c22df5738aa43d973fdb3cff5226541ce86e4641a9972f1dfbe11c5118d441fa40eea4b5f6a1f95ea2a9dc8ca20503d8187ac64a1d64605d79d050e1dad6f8b293e1ad5851401b889fdf3602b8adf37547e790804e7e2bcc34574fc3050bc9e55806bab654b27a1e0787bf701970d7198fc7604a13eeacf014d117bd64c983eeb5b3bf6533da8ba6d43a9b4ee0a25b883c2a44ca963e520a0908480d17b3b5aca9dadcd0564dce12bf65bc150e31ea9ab18630ce8a21e70e8201766232294c2dc5baea846aa588cbd2ad42bd350b083e2399050c9ca0331470800e263320721411a94b458ea3d2b1bf7db79f26b7fe8f897242952026c7b16499053091686967041ad281154649939d9e8900d2de1c3d1cfb60e883f7f5e6daf25ebb86540efb097cc20769df8ca008d59899bd9c50c926495660dc9297aa6721df5da6c320c81fac98d2666752168f809e1d6faf1770b79cb5a34ed33b13ce65aa05822e6544b72cd6b590146b879ad6f00b59e7ca9bef0e23e40456351d3b7752fa64ccf7f8cd912837f4be394a4f35e2ab9c27181ba3a76cc6aaa44594e85dc22df6c10d7712ad27aebbcf201e73e9b22a82f4cc8904b52b940a90c0a118a589986da2999a6417b42157096b9b07a7428e59c281863bfc95a058d03c511a979919c1fc78770bb754445f24fc48e05b379b9bce2624ad73cbc0c5cb053a166b41dc1a64157da8971316b89c0e93ed3e300c7c3bc1c7aaac3f375e1f24b0e5d8435e16d39a4672767474ed0d55b71354420c0edb9c0d511305af3c80e55542e4623f4cb4fa5eb98292b725a3ad726b98c06f4d5dc08cddd7d329c0d04a4a26ef5232b77e580c096f4395117a396dbd67d32b9ff0ecd284626b3cc22255ac9659d9b50b92de926d44e08c8836f9c74c2b761bdecc6dea8a17bca2a25e42cbb05360eb275471bfc64825e65eac0bcd67067e592b5126c6628dbcb9bc6de2664242c0a00c42bff6ac3b2266336d35ba1a07a3045579db7d3c5577cf7188772eabd5ca8fafa1bc41a391044fda2d8b16a4ef1a129e166b26b138e112454a3d2aa6f899c4b23569fcc0e920db3afcdbb4114b25ced821d4734da2f3f66918ac1462825462d9340a67802c8558eec4c4197cddd28113169a6b1f60f311b48c55ac3ed91d8a71ce72563e009339f2fd73072a5ef2acb35e6efb333187f951cb8bec0ced7431fc9b8630869ae18438c797efacb92240886e41049bd684b2828d6d6122a84827676c6a09c59d21e51ecf8536c531e1eb9f30f535ab7b971457a3ed9dcc61e9c2d62ffe412dc112f7a2c2bbddd4cf1240b40a44812e2938f559c472855f69fa9efd24289d30abc50b3a6e5eb5731e16753133fc557f14c1ebc7ca098b439dac7ace7998ac6db413fc0520c20bdc0fb95867d10afc8fa91b3d68e1244428b3a3ae7ca79397f72ce7d62c4e34f6cb31ad320fae8922abbee7870404aa6628de4794d35e58e6ca417030f8b75075ecb1d2ec7a97640819076b0d04174e0ee85ee8215693bd0e93f9365603b7084baaf618abcd7b5a78f0a1cda8976e00c7bc9eace74791da720d6ec38ca1c18d61df9451f81f4381b46925468c87c52686f0593bea52b5e1c22cc619d5d5ce6f4383dc72ea28eeb3504a2703c553e57aa800d1bad6be07b8ca491c82ddd550d23fdeaa1111d57bfd2c0469c9417d3e7513171a8c11466d02e94d9a5d79f140c598cb426b5d0773e4ad6c72f23c5c92673ccd4a94a7021f9324ce9666e10d62cf17ce5cd633abc4d00a8a10a83fa0f635c49aa30a3f5b2443745bf75e439b83efde60130668708e2f2e8bd3a826e22b8397e85ab97593df96dfe7fbe60aa79982592a849da3c537a9839f6a9fcb50eb1fa8cbaf192f429af690a881a8e4175243084d5662a9ac789e777f7ad584d38522b3419f493ebb9810e2e040ae6adb41ad9ced886d208091cb8f9a9e8e4b04eb03a50ef3745d3ee0278378fd6f1386f6675b4a58a78b2da6f0c86014c5ef70c23a3182e0faef1ba8b506cb19b97accb2e36d4151658bd47e2cd29a1a96130e33119e8a4e3c462597d15a1c24ad0452cd48ba3e84be6006ffa5dd59ac5bf91a4de54eb30f501d9d844646fbec50eb3db8ea979c72bfd05ef6d691e95ed655a168f89f9d73104a01e95caee8640f38c9ea9a237f8f5c150917d33c42d83a391c0730fc01a217810a0d34c42228fc64719a4f0834c59632ab3199e79d75a6011dd8c933d18f79386eb1e82ccf2312327e26cc11441e616dd444cc89c40d66f8688f18ccbe1d4c4c88844891d21cb91f5394771042a952e566ba6486ade47048b7944c3c15956336d5f39dd80e46559c40fc290071f722c96beb2afae2814e101e24c537c6a28c53c1a3f03a38942cd6bf1f729c4feb13f8aa4e2512ec3fb81a0839c57c3e39c063812dc5217193e5333e69a116f20d7f36e7a2c4a6867b0e5b94da19db8c694563968cf46d6a09d02431bcec84e0435b6c18827845fc1eec8fb0536bc2f85561065c6c917638b0ea0814545e5de031c3ddf1bb43bfe28e948bf526714d99b2f322232b21ccb3f360635df274d414bbfb9b5ab1a19adb4fff1ba95801eac3bc35f72fa2ee97bb935b35d1f89d266df766c27284e09d218d64b768eb225c69b8ae662bcbd611ec54a1cbb33e202820402e9cb881d7ceb2060b766ff462676e4fddd59edfb023ab77a81d2f882b8a817b89a89b1b1e0f84795840b46eb08813440c25538dbeb58d37e237c2a216252e2ccbaa5558f3718edfbd1b53fc7372a4c851fe074bf52be272362abc719f893027aadd32b8d36805947920aec6e90db3028de3bf98840653e79c4eb08e32f81d4e91613f8bbaac202c5905cef01f4c3fe28296d0bd2dc04cbdbb16a63e1cf1d2563e1d7887fc60f04685026c162cb6ec9709c521d4e75268b87d74b8060b06fd11fdc247aa723ead417202a2bf31a89f26276e0df319e4e3e06b245876eb6cac1746e6d24439bcfc816e4deae1209c01c89c607aac88304677c821aef6a448c48e541d6026dde3165113e8556e85b5930a831b1c58a54c3e19b27e9e3a2c209c5220601cc9c2c2618ca86b4bf99d9351614eeca3453692142ae4da148bcf32f5b016b87990f2ed3ed2f7e2335fdaaf91fa363e3b3ba4cd80f4664987593a679c0184bb8c0dd6f2363ab6eaccc0060e59b2390aa7b15422d90df21546221776c7b45e6f1e70b60130d279b42b7b8a0945815f6d19b85f7391d75fb0e056162291df41ec6c46bf82d1017a00385f8a1e762825f5b56d500c4ed1d22f27d4ad09a19ec5c4c0ab5baa51459cda68e9ec60069005b9299788d3217d09ae01571ed633e81d9580670592c12b9c9ac57994fdc00df375bb42665bf9f84906deb1d046d6c1439f892d28570e83eb6003773db2b0e4e716f18e4e3ec80a0662ae9ff6b8dc2e6b19a10f2fc435f79d5b250dd250e493f530925f21b17f7176189cb3372b8b6c5a94f88997733b3ed2e1c0994b073bdc16acead338418ea076474e03cb4b16367fa1a835ed56764c2ae12a14ed4f874c83fb528929412e84c49f2372efe31d250f15ca3dd40fae3a601198d1b4e8671adb73a3630dab7f9a78bffd3d95801f556e5b700ab2e038b7ada4f331b1ce455f5de90ea29db4001ed46c6e188ae1af4e53347c45b575b572357500a48b54ed611501ecd6256539e49cceb3655710318d9aaf9c8a1d67d8e62e5fa15f304fd8f548cef27ed754bdd417131be2219a9aa29f407abf696c4d9f581060b1353e06b30acbd963e5b92ace76b394e5bc885e779382cb5bef8e58eb2b670f021c188dfbf4af7019ae6d70a94d0ad2a078f118331d4b645d21a4c45c056f4eb33efe73f5211a96be215446f01a5a59cc643d0f8c7d5401415be00ba425fcd835176da52085ea61a3160b28292a11c850256333c08d5b047e908f28c22cbfe91f4a8ce2ec233d2bf14e1298e27e005cc3b3470a33057fec4b88b0eb4b140891fe46b85ad7897896093eac0459917998b96b5fe36e4ac14c7ab6edc6b5ee3010bb64079ea8de0093dbf50f65df722213a6131f031ccf201afa3d11a2886246aea2b0af941c73ef842edf78e191ccb7b9f50d1e19c0d0fbdef531e02863d5f19cb2eb1d3a66097d96dcc2953c724a16536ec70721694255a88474a0344b24b98fb1ae1430c593e28fd0c53646c2195bdc303e37ca375555d16f3e43542477d648bf3d3665676d2d222c016ecb41bbc40fe03d48309d451e1106c1d25642f958c93d1b9a655747bc9299ab70152e324f873452a204a0a8bd0db91f6d3651060d14b6096ea8d8ecce240777943ae78844a78bd4cba36bfab2b27147eb8018f7e78c5123e82f22a9b173828ae426702fe4403202268f16172a91ef98f665fcaf2be95cec0385b008cf80b772bae3d6ed68e83449c481808d8905148178b1405952bb608ee18b77e44246ccd7ee23e7371daf40877537680b134a4dd6567c0ef0ed7cac96f163fad0807c89910ff7addb755bbe555c1dc27bad640f0ad4985344a3322a81843133cd4965886014697c8c490a1b2ade2f760d791b7296439e931e0d4d42acd4ef1e9ed3595b8e9c6393027973c89c811c6d9886599e605ac6c144110196b1f87d2aef1040fa25d9f1ec54f4a310b78bb64f2109ab3031dec4b7dd6970613657eaf94abf730960e8106712720381fc091ed547a89c59da323c4048d001d332f42a38dfcf96a14277ed3ddd640e17fd8573c568e2bcbb2ba869b938c8b5bcbcc0c306d37424a799cc5c5d4cb27e3dde861cda8760c31a2abc2e08c773dd0cf6252c7f0c456879226821de7454311e5362c859186b1ede52c3d5b87475ea400fb15a326a19f3319005e97eed4141d10340ccde4b244382c43a70413df81d57837c1827f272be03a7ab578174ac00640b3be2337f415d5d8f8922d3337baa5d1833e0d963ac82117c10b131abd163d3995da07fe02e34346543dadda5e00d389098b5abd7879da8cef04bb0adbddb6a19f8be3b450a50abdef8ac8c4a1fa2a6aa506e7b1cc3bc898bd4706792cc128f2c2d2624aa4b8db9b3fb659afdabec18fc5c6ff0271ce60f613a2b8c04055ee21e9bc21e66ac055e8234b718181aa5824f2fb488bf307332fccd47b3b51a5a226c418a43f3f78f3d80742600824d3032755acd8cc5129dcc723cee21b3004a2ceee23f5575dc15826b5d24ada54294e72e14b93dde5863709998216c878c424da4004569b81b59a5630d0baca1e07e421587515246a620c83b280531e104738e048d3a016430f5ae75c721c84f0b0b621992a2a4a653d75efa03ac4e888ae50f6752631ffff124cfb4a94a02826a25edc8b7cadcdba75a5904fa1da6b17f23a6740d37e11e38e43f7f2c41b3061c7526cefbf6e4ab600d45f08d8895cb2563b06a2f2a7b17807f555fe3a14adf76ad40243804390fcc0058a2b0c048923e8487fda22fc14534ad05e0a28282254ce7f534045acc6913ed1bcc95cf36529f790fd035e64251168e8dbffd43418bfeb07651c9299fe6b9209fa6bfcbe8871e7952284a733a53ff2d7c56459513068b5ad0a9e9c84a63577fff4224cd4381414378279450d2a97fe4942605e04d0d2fd7b7c8bb61d22638212ff95aca325ed4e72174e2d09e3f4ce937c5095e4f349fca0d171b7f29a4dd7a060c62f1f9a17ba92a964d2081de31d8aff5e5e0dca876096bf99e51431f6c8741f829b3885086501b4a606e614e015df891325288e10b4105dc85bbe61921e5987bd2519e303695c14d12d16e80d0a8d33895b8479da16c3c94d03832874f4704733b98c448c178398462f4c48486814149d3e9179b37c21d50635cea76a86c26aef37614f8e6df418313e1757a280dbf5cfb258e331a9ca427a43856429eb08c3c117e15b5757775ce4d11c82e2f02d7cc0b9742161c022813e258aad2bdb2070b7ace33cd3ff61df1e760c368a92ae3ef4e7a190b899290d79311675c5c42d9e5ce9380069d66ffe647174292f015b19a034d07f3d7a57322b701ece14bdbd8e683f9f91c0d705b49785f74e47022c00b91d1ccf20e53df75a32d273eba7e59cda137c466e08d5480b67f5982127cebc09031e8b93e674ba8a9e05e5824b4945914046980aac8c62b5f252218b1a43b6abc4b6676f374ce052377ef000271e59c18c7f9d5a317457f37425b8a9a1fa8c72dc807ff9771154793d2b8dee710822cb79e47ae6100313793fe9085f646a3885dbbb87ec8fc49071618c9d13fa24edef7f3db534bf4fe264ff75fcc97445310a8092fdc80b514a80b5097a260600600463488797fe1b41f010f5677104abc94c373394121fcdead42a6575ca450d139780639d79890ec399e4e4dd353e1dd2210852d19261cd682261972a4052069ea80be42bf4dbb0c63bb6e50b6847fc2ad22b33acd92e7e67b76b83acb1e55bda3cd2100c2cf9007c30c9a3dc1abc114bc8b031a3e0dd1d4330b6cc58211a0e24a38eb9d779ed7a95721334c232d04b6b71794cdb2a74c227c3a69964da1a8382771d45d294b24c2147b18d777cdad37e0fda72287702119b9e0283d8643fb73005501881895e2074fdf61f8366872667a2904af07df5c039539bc7df5cd221892c1496b61fa12bfbdb5a4d0f48346d5c05dafadde1d862cd9a8ea70dcafb6d39ac1c2b2c90accab6596c60099f021ca6aab2ac9ac72bc33b4f61e50cd479922d1142aa159acd17c8aa95b2944a6fac7f130be400bb9d66122c169fdce33a50eef6a26431e0dfce3174f355aad237c8e60d916c1e22c70410be93cd40c16b1b27a5a66770891c3cb7666deea0c734429c16066ebf7f618c1d7f3ecb1a4d6b6def0694cfdee7db95d2a8333d6806525533b368fcb102fdc2c4e0ad1e2cda2e00ea5449c47f4f0eb072a5b6b27638d6d36b1b56100a72ff807ab2dc84afa64d5cc06b7f826415917846c90ea360a4bf43d004cbdd9b4177684d00e7f4b573fdc61d3029a10d03a1226280fb32009f95394fc1da5dd3e414dce48b299019f5e65f515025716279635d49096447f42efa512f50ef8317a26bd6d8f8f3eedb4a9f427c4faf62bdedeb745af45f420c9b3c0cae57367584d918c6c261b25a3753a7efac4ba7bcac3c252a64fbc4532af3b46a31f00722aa347049103e991388ac86ef512a99dd972ce8186533ad8263dce13081f2d2ae879c34c68d537a4f84063476f2a3e6ce9d98af99cd58cc1252f12f72e1f8b51a4942c42a68ebd40ca9f4cccf8873b681194388450526da9ae215570ed8bf0f64ce07d303173ab6a929838b698bcd8967b464bb10e8098bd9f4e1cc26e0ea422ba449ea4c0072895060bb65ebbebc50142bbe11d1cf6c38dcbe4839bd2df48fd1bf122230aa299120b7ab91c4794f4ba329183f75247ec387e45c4727d1fa51214bbb67083083d84c04858b351329973cf011633741a2c69ade5aa88f1d3a9e7a2470ce3d2ef39c0249f61c127507b1c1aee23dd50c03e92e98588623fd9bec26f8ff092cce56a81feb8943175b79c7a6fc18ba2fbcd6b9e8a4a4725d511b0fb3efd91564d881daff32b540e0a194eff81b12dd21a00b41c5130c5a9c34209c951807f7ca9f37b7a80341108e4d2e489079dc76627f5c65ee30fd846d1f48e48a2b29150742a4661d7e6b20b7bda2bed289d517ec7bafa2c62dfcdb5e9e834918c50415bc433f8e5124318bc345f49d9837e4c0f758a7a204bc208ec52518f9596c8191f85b1116f6fe560c048273429794f8dd1a74b0f41c8edb53e64f47b1d68742fd57b4edf49871cdce98d6167a62ed307b29d9fb4162a0221b708bc29ba28488256669ebc23aa44056d5454005240c86360dea76c985fb809b48393d9702e1d56067667de7f5b234a9564774a328d44be86bb8db88493fa8597158d888233a14c9775ad62e2cb4f07ea1bf920338d2d041b4aa02463ef5100c3ed0d636806de4aa9e60a88b1f202908b03c1359e9ce02d30e6dcca0990b657aaf452495e3cba4cd4660d9b6e3ddd85bbc6f18cdb41b507180680566f22e2b65178da2f58197e1a0a7c60590e18d63fab235368beddce7409373040ce2317446a51486a10ff45403d87962d3075b7d80efb17be7b30d8d9a5031b907f40d59052c0b9b18e9089dff40c471d5a2e91047209c832bb04342315809c2f38d342c1bc27dc906e4b1a36221d5f3959bde344044caeec6c47a734aef61d3c2f38c1c539bd741e920ecfab38939de70f27000ad06d8b6abcaa0426ca9ef6f3ab737a7017665eef1eb5822e7f0a6194544f20559e263726c091e2205bea697664f860c32400dca5e813eee78432247b570446d9812b11e0dc186361bdb5fff6f80f79581c3c388761b9ea5317b7cd6e7025410fa868a5a03e141ac2837734273513273d3578e3cf204ee9ee7ada20c904ab647528b65ecf1e712ad0949b7290b60d26d24353bde46f317ce36e7252f8ae3efdb40377b230b76b5f80b49026c6a9114903253a4d97634b992b3a6019d81e46df0b619bdcaa2b76aab7e49b7a8dad5d6e636676bb75febce46f6a351e8a2a403d04fbb7efd68322c7236125564ec5ef4ae7c003c57faba666ff6fa23a83dbb2e6d9aa8a68f8825378b68e61e83cb111ca5a0ba8ebf45f9a53564166228ac93629540a77a284e094b7567455ad17c2fbad62b3c634f48135c47911cff5371f78d92b674d9ca429c1b6a8c6367bcb0e1f2d1e8db99f2e7ea5ac8a3c2b53edc27cd1a7baf32e640ed90be5b4c93f868fd68b79fe7e6a70e919926022ecbe6fa250a8d91153d1f4eb4912fa37ce80977daea48a65fe62fac6060ed31fe52963ea408868c5d253007da16009913b3bbefabadd6843a2498564e74f004bc427521cd4efaf3fd8ee1012711fa59a2372bd9a96889a192968d7d9d61805a3a0515183223f2f7232745002e08fe8fc8de191321cf08ca7636c7c826ec91e52372f42d11ce47e58b15f6617b92e9cd00e9deb60513fa86475471e859ad89ca5c7332c01610d619f8d6367ae6a991da04cbf021f3eeea228b296ff0a63ddf18162311e0c59075cb6bc1c204c684611e1efa22924dfd7954096878feb4510a0a22ee130b130476367e810b751849f7bc583b173279996e2ce90666929ca3ddc3aa4810c9aebbedf57a918f9941e0b1c70eef8b72857304f1ee6e43fa22c3ea9a8ff8c8b4a8bd4a32594c47f7305db186b74f31804a36c00831b6608444f22922e1ed6d3dc55c8722dce1239dd1dad919fdcb9deb3408942063ca404ada5153f6e11eed20fd69edda98a68e7d1448a93f16fd347d877732e53771f68f127dd9577df01633496cf2c78c84a30cb7a04660ec16d6de64ecd06239748bad2401d15d48b00f35ed78ce603dc0d31cc630a0184f54d4512a91c7b968ec22dd6f626e3c7c4351fd58ceda364ecdd2d417fac64510409baf0279d7bf20ce91e5c8a086c950797192c495a7b12fc335c5b4d0fbdf1ef42ad61d9559144834ad38de5ac75c8661f6fe37ccd28a4cfb3916bbae191fbd77e4c9b7a526230c6085694e4aa5077b1b791e1879b1f6c13f2363fa0945db4b236dd46646e5143802172015830b319318c9c6cfae1ab5ac76c46324d1a7da84b15091e0b8174df1a9cf713446c20127c4e12e7ecba057ac46f7d8799cec03a1c0f7a18f33a88d3789141601da2f54a3ea547ad073fdd52457f4fcc809f50d503fe882439f70be39bb1d33e36040266c7014c734bf85e44d635e57a262f5d2ea3cd59faf68eed24b6376f20d2bea5dcad50c34ae27d3b48f65265028ee7ff9a70ce55dd1eba5ab1ea89977f42303432b9d467622bccea938305c0151fcb415ddbe6f22444a0a210e2e0339537d54175be5b110842ba08656e90473db9f129ed5c1387b44c569d236e2ab5b4749e31539db15ae3e2f5a2647f0504c6070501d6ce37498c4d8869bd4f49334f8dd3154c179e6081c24c8e4d2259cfb5f2e240f77bfa604e9c6756f4858926e009792731e095cbe7f9a57f5615d29e9c0b019059337d57609ddc21fac74d11c852cdfb242eb8f79eb207b290e49d2b02334a6caa4a7b20be3237b2a2e28788be27c33d7e8fc8c8f8538d26603046f4152f665b7a528424df48939bf1643cbbdf96d6b609af24c3283dd9454369d6a36dedf60cb9dcc8f38349c5bdf2c30f5a8db50b14738257f919bbec31300ff5188803a2450a6a04d5155ef70cd02539b53c459a0a8a9ed71d854fd84336eb4e841ac4b21b21309dd891a59aced77c427ae09763d7cdfd4682862b1fb4163b3dfc8f0d765ffb2e86facd5654c22040bfadee1ca44653d39a2ba71d244755c2ff906ba1f99b1cc5217a0e02cd6efcf3e0a8663b7d13e49b123eb37b1f6be5f094641bff55ac977c84ece041e6cb1a14860c68858c6e4ce342d35bb8fdc1b517b5ce47565a1fb8f17805c4ee71652d7230a5591ea763df6b6c94fb0d174987a6c516594a74428b282ad79814837167b52323ee20e4fc27b9b6ed2d6cbfb7501c634bb71144d35fd8fb5644988ae506c978b5f8c2e6d575be496a4c89d4f1a0bd70c7cb9e65b44623aadbcfb7377b9c549bfb31fd87f922c513e301c9e8e2d1b62ccd6a64bac69a84389e9727bacb0925786fc4370ad557f7a664b6ea5fc449b5488aecd974d5c2a51f876efe0c06e6d159fe5dc5b2cf0932fc47c0ec06de19081be3ecdaf47d5b0c4046e4464d355bb32d2069cabbad20419d666c8483170eba03485eb6fb46aac429ea0af1839dd58c420b8f4ad7ea0142e71494be13ac9a6330ac78dcf18ac0dc243e67e9a2b25e45444b6999b051686a225eeda9e93e553b84089fc09acc7bd7f327935c1f3a0c2dc17b0809d9e2f821166211be900ab2c89cb51c0f7dfb1ad8f8422b91e949047d166c11f9d49ce012440d9966444bdaab801321919b506aca1cdef9dc8e4c0dac0ecf1e0b55e3af8c5e08142d965be67c29991b8778be958b040f7cd02109e1645e2c279232c532825bfed7122a6b170a890b82ebe43d125d51f7b1e0ed8579b5d2debed4031815cc4e0858eb82371858651b417c0d8a11585b681991cd1d4b81245b614c3b0a033cd1d7868ac0183246e7e41a00afed884135a14a8261d70ad01ed807fea485c19b62cc6e762db7f5455fd1f78e3520ca8c38a27546f1d571faf2a9f692921cbda271610602147446dff89d7d70dd8d404841b2dc5e375de21a2c2516102e11d6e8e6aa2b6d6ce307471893e58b9d47ee10a28debca2c15f809c91ff075c37d34a419a6a0b59e9d66f29c33fff31179ad4c085769d9eef41b4dab09938df57d5352772908fa3fd9007f58383c625d60a6766ce859a1ff77374f3e473a75e0e29294f26da4e66f6b4d94137345aed2dc7a4cd0099dbb554c83ebdc6eb4248bebd4112343afd53698c24b4f5bd151a98f30af7f82d9fa8794be98c5c5bdcb3217021628da7f5b03680a40049c0eb600f374d715c5dd69a15499ab5793741b1d2a62869195b278c105a58df8f308c4603185b6a6c062f19e87ba93e652df5a244916b6de280a2e97202d2066802b1a923568c873268b5498a4a7ce5fdfe976f6facb186597771e7202c636260cd9bb82d1b9fcb243bdf9a4780d6544a1c01a36ac019dc89acf00250c1091b1c10dfaa03de807256d8823641649aa333b1daf45f374c43dba64f3106061aa9d3ae8d617f6aeedcfa57d506c10bec8b174c19426c03299f88fb4f2a91dd6960abaaf8ac69b9d34ef5b03200490729dca8be056614abfd6bb8260fb37b79bed2fae22e9b85825431de42d309f3c9bb94e2253cce7a32f92103244719124e03c8712371f156696c99b61ae72e2853c520e0665b20af90b0c152553b12d9df36f7f7ec92d1fce66ed400b3fb5903635ef7074f6783590419161a86e11ed844411d93ad9ff0135f0dd7d03518fb81b1d6100a13980a34cae69f7fd4aaae9b6fee8d3bd4ebc3cccf1f0b829ef237f5b111fcab9a5c48f880b1636b54718e96f2f6e2dc488310747e7def52965f452a2c6d2b28df0ae69da000f904e4b13a811cd18acb18def737577883e6ce7e58056a2e4562065c1d674d1633dcd0915009dd8c1f29a48b6188b63b34676148fe13c2923640eb3d9915b0a146dba1faf4039bb17cfbeb1e16fdc1090dc0c3b1017a08d39111e8f0f49cf8fbf452782889de3ad44570ec88a0b0b399837654e3a7804804d3693c8b5b01fc5e42d6191a2e838d5ac4149046a306e2caa0070a645691220100934c1b83048f60fb57d2e533253f5bcb361138f5323b9ace89d26cb179bd104c587d4b424d18b4209af05ff8a3a1e9f288deba887abff62c83c78f13e38dacfcc9b7e206360f573dd8573a10c081127b32664e1fd42f5522ba5e26253712e964ab03bc21f0f0a4e3b4a42e1d276c25677f2c8e4406fa940d447cd30d5f44d4375dd2d0a04443447f35be9f1905ff04df8b2e46121a17723499d1143c1acfac847787ed2efa3dfb6c0a6b188ec629151907368e5bf77ffa6da7a7a8e514ce01973db607a57e638c6d49bae95fa2605153959681401c303a65cfc85c6b01eb450c09029e1bcbc73e0d2000f81b3395ac174e14a50e100f009dcd335f8f01387918f60e539822caa43c9003c7ab2127ef60cc894ab3f9e374f0d844e4529cd45992b0e350a3d9afd16eaca84edd1e476f3cb02da98dc1256b8489deb21708739d012c3e2191b18babd7f73e3289257316f00997b8644e2c49e1ede0cafbe7b037a4c8473cb3ddb865d6cf380fd7bebaeb5dbc61a5d81696d6810a6b79f4c8bac4208d30591fda1aaea6e04596948479167721f6c05682c7897920098429aec51e70e16a84eead1f620c4611245cf3749bef63ca50fa40c0251e78b34b71b22b7b982be1f565b9564d667d1f68f3803d3b5b3e934b6108dd41b9d227a30981e472c9d9f09e18902023dcf6ae678ea0251b3b0334ece6e6c0fbe34a12e36026ef0cb0102e3560a0efbf62a82f72488109cbc2ce2db3194590c9448c63745d50f0066abe1475a3e929baf77e224516d6b847fd66102f43c577d20efac823b892e7219bcaf0814d76fcb9e9f8cd9454b8c8bc039f8393679d79505a223340c6d9c1b54ee0f7b5d35a92f22013e22b080d86ceb49289527901790e200be6c552279074e8f7d7fd4f865a6f1b45c81995d479d334d6e9cf94061d7362a8bf97ba83a8e41bc52e77f10708ee599f90ff74fe0634f0a056237ae37bfe948c3f114570dcdd4df21e68f86d8a958dd008f3954e1cfa74862c1f7622959ac8345acc1fecdc239348fe96476803347ac6b70e35e87c08164ec035968383c6744cfadb387b19ddbe56d2b0e7f45050574fbdbc89aa85c1e4333d0d884ca19bad2434b142f8bff357d383a3bff3512b0bc776712b8b0fac94d556c2ab3371fb1af9a3875cf00d7fec4d9d12d1381c02cf8585cca19bce23be7300cd40e6e6ca25322253122c21c1aad4cada1bb7c4a0fa52391ef0dc60c46e21c0cab617a9a1b74f41ae39813d2813a53fc19c38a411a09ecc26b6b66e59ba581b8b389b88c9ba4966b1a61e0c241c3e1213b4515762a37c398d27dc3883984320503b8607144feadc69a1bab134d7dbb52cc3ace5b455d821d3aa236f1ce6d72758e5434c25f7c6d97c91699640262865330effd29caf572f01d6abc3f9cd8a9d7a41d7d4ff4157278760d99e526d148b9b0b0d7d7e2e1d691a874bf7d328578c6b468c9c7c3d5278d462db8a9d7952205d60e595223c3a1e16d58d6907fb638171d71d47fc5802c3f0ece0d5bd4d380cb0dc836714551f2525fa85c7bab34545686cbc6064e583a5cf863e4907fa541083939c5103eff1402e77d01993bc8a870edffc14f0a54871aed18afb4f40934bd78c411d0f4c3e0722d9d6f650bf90f7030cd0748f8749f80aa2f78da02dc2a090a1f06d61ac250aba56b702604d2cc4b4434362f0d120178bf6927206e384c1a120679ee8a2d24b1b7cc61b68897fc43c8d5f1f633640a44d652500db100be11c663f7603ff4d79ab3c09a21b3bf8dabdbd5d5406a50b4091a64bb48a61b023df68b5c7496395a6ffcbc8e13620def30905ff46885cd809b223d65b1c0e773f83a166a2e27bb6a35424e60a47068da5968182ecd1d6fa7b7e241a9314b7257d9af4a8f64335af042ec79bc70d4ca2a0c59ce0fd4face494c2e1d1c7b7a9c443986f54c5a1b7f53fbcf0979243f20becca33dc1029415b7cbc8cd1dd56ea1ae9d08cece3ab32538e5d0c4abfcf99f02ee4c5ff13c2905d7d8391c6b187108d82f47afd5e3a235e87ea4fc5fe49cfccd948f42a39c61dafdcc5ddc5cf8ca26ada79574033800a5751e000927ec5c843048263a6d1a36123804d056940374d5edc7233ab49fbe230fc34bbebeb2facf9f94ed0d970e6413cf30ae4ab3f4cf03060a93cb6353bafa443cca4eef6b571b10d61f5ee594b67bd7d91133a7f65be0fc9f5011f8427227fa0e514db61d009c44702b8db14db2ef8edb5b29fb527ecb976578f785bb21af070e162501abbba5af80126db9568124af92730dae244d6e0dc6aacda980cb553c0b096ed3240b3f9995bbd038d31ff320705204c17b1040115d35b63906e85f32b357da4541731edc09031595fed9e22158001c3cef36adcb2c1d816a7750791d25f52f12b204249422f183780658d4fef0d7df28392d4c741d8fd1024de369c815614c2c540bab6e5dd0bb3de353fceae2bd704fe11c90b247f99c676c8c886cea230e0942f2c69765438dbba209f8ef1fba4774518ff6fd87b279c7993f9813ec41e695abd55501c8061ac49c9e26a0c1bc562e99d4316500a2cb9807704403bb537df530de00a9a2751be9ae088303bbf846077853587d3aea48cac436d9deec1cdbf4a1e33b8f8fab76bf3a3d96f90dd15fe1b599918d7594fc6756e7af7dd10c7790e89972c917b08af217854da1244a90d97968b12c6844e1849d9c2254aceed6c8678d926fce48b6c7a9503c871395fd5636f34539e8a2908dbc0496a2d7c23568e919558d30c28b5231628b0bd643f7dd4125d497298df3d5c22e03a81f9b4c1a61ab5bc79440e42f1fa638d603db23220f44394e5a097b715800fbcd2351745d7c2644369196747214af9c258c02c022baf7b1204e56ec06c4d70072f7ed70935237c6ede772a14d3980a4d4ca92aa5d22b591cbc0242ac8d1c977b6fdac85da0c68434d9d7c0cddb655dc83dd0716f404d6d73b02bd72737faa739b02a484a35f2109e72694b2bd2624abdf5261e5cc0f715104b34905fa6c66175712267326a9640e1a1eb10c40eda5284bc046b14e18ebc218c66264928621a5734b2b46241adb2c06f05ccae0bd65a71aeae53086cacc080b754fe590c3a665334bb572652b62cd084c815ebb7fd6ce72af9741efad0fa810eddc2284e187534f750ea90498e5af8c74680d810527f337e85f82b1846ee2979b8f704d0f6720f8e0c136f00354aaccd1ea16262d944d76963e5d0ba17cb9b934c4862807cc38aacea6c7648afc895ac2be05a38b9cf0661033132a0f51754f914f82aac4c24eb9efd35a371e5d67978b2f292a1621e7cb8881be324c6615520faa62839ecfceda0f45839bc742e18e7b063e8b3627e2e15ecd98c1b41b8a7cc005ee3d8b0d06b82bc82fdfe86b38e4a7c8b6192591a261c7f5277a28736e1187cbfd5797f91901869ecdda3cfbdb848ea017e144cd95f04dc937a716ccbebe0ec4f1d51f007cb202320fe10187f607f0dc22e26f62a70a22575de9b539f35d69e09e702d2d5d2c0dcbc5a2ea53063eba88b0bfee3bdd0c1b537eff82aeb4e43f20c7f2f443a635c16a7ff38b878637301d1433b62e9e8159ccc8e40cda3572898987d123c40dd2513d80b58196c4991317e568df34821b5f70aa68e5b801ee4028322f153ccbd59c32245505034e417cfb24550d8eda129dd12cb54f430fb344b447422ea523e0102faa5954d142a38c9158c07cc25f6103804a586c5ec0c57ebaef66f3d060237f19882f26bb4ba0f5126c74d0114fa99d9e2b358c7eaae570ea13ab7f7afe2d1a699d239b83cd84df7454395f40867323a31f6e27920e357af3612dd477c033938fbb866e3dac805f7a4fe887b4fa8e2dcbfb170e78128bc2229302dbc9b7b2b8bcf1dc221ea490e75ab14a215d8e8816901df80dff7efbb7e74e39680f916d97695845f5f48dca1c4f70c9e25f1fe127eb99847bfb1b023c6bca6725a8ba10503c089322f752ad183da78c505caa864ba108a99dc9ecf493abc00a9e6d987184ed736af8d6d509a63704cae4127904281fd02d36d0bca7a24ee2bc90eafd0bf9a76d8b9e66dde484d3b42d68e24c655c5fd84d3b156321fa1a4cde7f9661c0dc631e9a977d0420a79232a5e88481fd384f6d6fad1143095d4faaf736c80939455631b9c0a8436931fa26ab0864ccb3c90096a4e533b45a88fa00a9f44ddd91590f91cc928db84e5db05b6c722f6617d8c05215aaa8a7068c61d7c0cc0652d0f907a90fa2d0f70e7a6a6f60375374f1b96923c9aa2cf2d2a3da44087012a4aee102003ac11883a7ff5e513d782f88d69e65da9a585494c8162008932519560048d02d7ebd8640f4c8777defd62edd1e89f9c1847690b6b4fd2a84f14e4239f6c8cedc9ca939405fefd35a5d7d459309f2be072f1b1ce44b205c21861612891e95144e160c7eff1dbfca9afc3f29d32db24e7e841f8b9d7db3f35149024c5ab262c4d83728debd77ed87b0c85b32a064c47c3a558dbb019a7b7a2ef363fef9f0d94f87ecb54b4ec26937e4bec8714167957da864a2ef7724ecb1eb843d20f51cf884ce5968a4a7a1ca9e2c6704b207b77374ae23bad02870c063a54bf520bfc69d3c2b4a909f0599cd8b12626b477ce5c47a92d22b7cc48b3589aa688a056c88d185cb6885abdfb0625dec642c688e6014af46f6253ad1a0fd6d035a53404f5ea6bf99291a3daa810aa8a788117ea5dd61a42ea73ee76a999a016bbe21286a87fa096b000a03179444cd2c03383d547a97d0cc4330b4bbf2afe5143f9741dd2b4344b680505368b60210779373d495a2212f1689082fb91649f38dcaead4fa4b4b9326237678bd970c70011ad66d374da316d79c16c402315914e3ab46aa3a4286ed95add9c32978dfa0daf55e61aa89d8535135749cf4e9bc578d768e17bf5a3729271055670de61ee10555fb2cad7ed8de3f5eec37948a98377546822cd1a89282d8bb8787617002208c8ad813d549fb91c9aeb9a54e660d1b020bc2a96b44a761783618c9322016d579365dd77fdd7851ef639c42382e823a54dd108aea8bb0815ca13981537c5d5d594092f075e21e1d9490a8d9dadaa0726dceb19037cfc12b1bcc0fcc1cb347bf50fe6dc58e4934878a78fab736147846cd3b22a7e3db88daad7d1c2717fb80f4ef9495891ace374cddab2257d0113ce738191dd5952eb0f4508028f1321d18e5e11d996b0794396d6367da04faf3dfc84e650a873f05f44bb173bdd762148fe70bebe87a01a6f81355324c04589c93374a7a91a43b9219c513974751c626756284e32877c3f54c6477a706d2803b37c930db740a68eac76f65eb871a36963925d3841d2057e5718035eaa86274040d3dd278fa789c951eb930a75961488d91f12f48e50f0e799047b6e4173e7c5b93db01c787a90609ae7136fcf361c90b8266df9ca930450363e7afc46a6a65480f9f32b9b098276e54312e04f3199b1847efa6cf9a65dd5a19ccbc6461d1c16d33349ca18cba73835013414ea52d12ea054455631bda7deaf9e278555aea3b64328de4fed88f7dc77313c5564620a89b07146cfe076dccef3672ef613e0f3928aab9e9ea946b989611713679b6ce322169790f8752e259c0469fbbc4cc35571f521bc31529769bee98a75a56aa519bcd00d46cb10c2a39b1a4631978fa04102e03d708cc61f2617665c223970c5b82e3e891a6dbad046df60fdcf99a89276c6f1321f41cddd7f81fc6c510a54e01f38eb2f17c8774e7ca9ac2fcf015f9061c28df2103decb15281da891a108aad170e6972f0101e4c1c030ea5ad152f0c99b3742d2414af45ea8b4a0e9be77912eae260a87bc0fb4964a35b4c4d81610167509ba65cdd249436ceff9ff948bf4962db135920ef2f7ee0bc5ca41c5c17108abc3ece09b764ae0c1e249cd587fb33b903fe20ea21b0bcf2cd10d141f20c621c07b37c8f99b6a09710824f9fa4a9c9662c5718789ecf96f4c3b89acc3f3b48d38f5cf95982e2af2a01115275976b8cc6e35b4acffcfd901791febfd4ffc4a1b55cfa812869b70095e8cd3732b8c2e3cc35ef8949b3db85c8a3e89d01e7c23b8a75ce0110367449d07a1eefd7a2d516303fe368e681901a7a8e319fedbb3e26e8b57f39ecb017d49e5ed975a1f1b4a5b9baae38bcb58b489a4131fac51a22a621e5f003f452a7dfd667f255bfc59617ba29b2935f65b85a635d928ac2eda0a14f96ae6574bef4f27c6d0b91a4e22fcd88da2a22cb45a975459529f0c1349dbb687a15ea76426b19044ed161ddfb823409ceacd0f39fa3a53392bd7201e813a972928d402f0bbea3199b9dca5dd7b30fcdceabe90c581dc2a4c5e459fd105684fdb8a9897fda52e683575c3eab38b8d1231ba1c20d1a78fcdaf1114a5b638d6f2b8b385a4bde0106318306d3caaad9dc3fb97f1f9806b465baf9521a1a7d6aa7fa9603860b25dc4be5faf71e25f4d712c50d76ffa4943355ad3bffe93708d40c75c8747c82e0d8d471a19e4266e8b09498104305d8d021342f3c5380512c71dd0cd4d13240112c755cc2930e63693d9be7f850081b29c9353fd285e21138001eb1f86a1daeab701ea8e27636cd451a79e0d35380a241cc50f67986f26be9f02eaaf350f1c4f7c664bf6e79bc37fea7da345e2addb24c3193a77b10dcc257aae75f4d310f8625698f5d2a5600b807cd43af5aa037b74a1269bf5362a2b9392d8f6e0a92780924813e693d13411251580a9a9dd664a71e8f4bb39929985eef22d992d755b341b28d8b9ca9708e517e56f5b1cbeab4189f109f37749741803935d8e58da410ce7d64949688b4a8120e97592a0d0a82b51ed5e371a161a02197fc5900367a0ad0b23ab6778c48c9fd43d927c1a56790845f7844cb90dd25c3808b09ce607e29551f38d1da446ccbdfc0a633f4cdfbaf286bd0ef454c8129f18a2489010bf23741804c7ce47a816d746ddc38809c0d334f8c47a3cc33baaea163371e083bbf830669c7af8d41358120f1e656e5c7cbd3f8b1286ee6414635ccd11e0728b2746235c1fc6162e633f5a286138c0908d3bf901b91179a328ff78ac73c245d720bf687bd45eb87787989b868bbdc2b907ebfddb6c35b6b33d6da687f6125599f5b73db0e2e12386ab52e17d909f1a0482c260b4fbaf5b49c2f3e5520de0f0bcf7d8e1aeaf8ec115d66892d23c6c842ed402dc64136ded1be36c9f69e32747a51b1c69cfe407d6714415939a44986113751fdbb1f346d58c8a81813b4085774c489f2412b05633d7ce08030ceedaaf3c50ca8778a0003bb38704901371a00fb4057f5037240a3cf118e965e6502462fd75bf3940165f42785a1e49fa6cd28ae6775cc4779ebe8dd9d3209dfc847c4234665f8f0dcb381abf100b4b93890d71f64d058c2efcfd63bc42bb52168de983eb5963d67e64d6855d4647ea235b19b304ebe56c11a57127fdb8aa1e38c63b8d38ca4f297516aa794b431468383d4effabbe0b51ca6f17a8e7d2a4d29f2ee6901fdef69d14d6ecaeb9df97469e44fd957e1df99b971792943951a0cf816387df8218dea04d8bdf3025a16913a19b03d80e7f9d60f542b1812198e66cd39c63530e3fd7e7c82c3dfd4b5cbb7cc7afcdc6f5b566fd8f0910c303ab73cc6335d3ec6ed4feeaa4dc1b21ff9ef4ca14bfce381008067228d472f4e5c744fb77be3bebd6e9c9b7b37f9d65167bf75bc48548108bd71f6646fa16aeb7bee372e6aad000f416b520ecac58a782019c20f7f5b0f2ba45d9ad50904a17827d84d3d75d89d1b78f3055bc79e9ab506a835b3f899e5e9ee3d5b3dbc67b5d81c4c4bf465cb68e549007ea16da9acb2f684bd36a852fa484b3cad5bf31543a7ba30494353962b3c74569ecdb45a41332c8a647759f4a0d5cc78d0f98e6157432aac16edcb321907bc18226744b70a5446551d79e08c31ef474bd0af5b4493758e220bd9b81868efe824a42ebce9e88f3bc54448e01ba87d0458976aea87d0886543f604f534ac512f343c2eef2058e3de1d584ab620f9569b4f7e1cc57098c600ff85f9a7bc44c039b8e5ec190e88db7a6f38313d19ec8198b5d8a2f58be7415ac1073c0e2ae9391a86ac6cbd628170060f9aadabaa419028096ac4757c9da4d8dc5faf11902050f43d1223766dfe7aff4c4df52825aa6c9c5d612aedc4868b71a9ca784d784aab7077a79b99b6532c6b5d1c2d7c286af746583f3d051ae055b843b447a6f94120508882ae75927c07b985bd449b130818c98a3eb45f0cccb41bc7c59aa94021c18c983ee8dcc614b8a502b78252126ecfb9b6f2d772e32a1f85b07aaafe6fd571f93ee6f2cf31cf59ad89223a1ccacd2c237d1e5f9d9fb0f21edc9bb075855301fb577999a03b946e54fe2dce0e781a4b4ce27eae10348cfdd82e3ad87b410421b8c42b0f460812188e9ad4a87b02512d51f3b2e817bc63ec75cba32448e8e439f411965c906732633d7cd0195c85d4703f1093671ffcd1ece8cf7de0f2b035946da35426b612e6270e962a0b348732ef32815ba63362940706c5735bd21ea8c7a4d5cf7da3d5c1144862abf9500f40eb0eab044038ace3dafa6b759e5c84f69c2ce4220e388d0b35a5d80e2b6e8bc44b1be1bd6de2d595043190197a472e7086790c386772cb0c811a486c18ad4189dfbae24a920563ffe3a48f95090a28169fdd7168b9514031a81c8686bad62fbb0bb20a368bf2020b6d457d2899a312ba3c0cdd041494ebcdf659bcbdb6de914348225280c31d66eb8bcb38a63b7a7a09c0774f0b4de7c25e3ab511a6fbbf121c6b130c3c9a7db4712ee46255538656cb510125b0bf46ccbe4514471c939c32770549e628eb3fdc8f00a07274f4b62a48ad05a2d80df2201fa4ff1c5998324a7d69ebe26d95014d014bc0b6ca6c3adae50106c58c2f186a83099c3136df2047e1142ee1e654d12c5fb0bc0983a15cfadc4f2987e59f318bafe9011b3ed0f587b80e4112a3b6e7fe3d40c258cd3a47bc5589e7713ac4f5f12025b18ad0a5b96f438ecae81d3b021a1383ec937829f9a7d2af2a7b71f42f91d89788c3ec73c5a4ece14291b66f5e65fea82300a7829869aca2f0911cf10feecc6dd4db1d1ed20a6ffec02d01c3433265e211e56cf7ce8e7c98dfd93d4c4ff011c4ec9dc5ff77c20100fcb23ffa9a6d3d523886a9ff97ac738b579ffb42f6a766e29d5077ebe5bd0beac557874cdac6f4e085cbe72d811e00a570c7ce602a81061824f3c35761723b598425ebdc0b02eb9c648ed3d460e750425eed588aad17fc5a9219c89cf6755096e16aa13a8ee2d265bd61d1c31d949e4c047ac884b141258cc6bd1ed20c3a99c73e462b78ce0cd11bbff908f25815c32d72246cc80626100ee51756e24b8f4d8b52ebf54efed4522a2a4cefa2454f34fb2bc5ea62eff212ff3c930f2c76ea703d698f69843f3f94f7f7fdf6d9e02e983a4ef68551a1a53077b0f3377889b88140ed7e039b9e2eec5509be60c0f3aad76f745c9be2efb1a29bb0099f28a05c0f4fcf47544b82a6a28e149e9459069908abff8cf4ba4ef8142585d667471b9a1b45460a08d8ef547452c640e9baddd291759badb7f663e06697f8d1b35ab9b5e97a56e234357e679595514cbdb4afd78501c2f041837b51c4edaf54609efee36b3ce505fc55a9f7c7c5211991142cd4944a0ca995919e69deacc7802b65055f6e9f0f09a0caba07a43525ac8f56a321bb3a6d5f6af090368f690412bf231cc2ac8461319af890eca04db45718e1f849f4bb479804761aad309847349014b4346608679b234d3c0b8bc92724f2c87552ad32a0b50c5d8c51e6b2cd5419cbb49e8e6cd4dcfa37b12eaad8d08380655c0c0ced87cf8b1b3d6bc562328c1094f211cbb7cf480e12e19608e371b02c32147974824ca0a153af0c29321c8c68830be0659eda73796b610c2ba99dda8b270071c2705e2e85e14b1166b89a8430993eb21ad55c66268ab71ddd4282f6e5783c23352543f4f20d3ad467936fd3b14f7cd938cd1d66baf9477009269e0bf5df3237418f98a959ed6879d4d7c8a92a7391b3c723fa7c09d4bf690c2be8870723aac35a1082fbb10f3723de3b5b02435a7863d38d7a8d75c35cd25d9a9bea97e5bc73ad850e206ec5fdfacf402dcc256c7de43ad75104256c18e08a3670f198811eaac31314654d7d2b32f112f6f2d1e0ae3992bf089c0d558ac2e5122aa84c2e0184c7d0d85b524f7f63ba95bd407392238bac894420a6a2068850a463fc4b9931800b8918e95e1379fcf6d73b78e03994b7452f4d444c54823162bd592d49abc8a4e3db1547fc44ba3c84994b5b014a400abdb18a21b92eecbc028a46c67e5930cea8a40e681a2e853321c445e568109b700785cf2c6e745108135fba56e71267d426c0edc550b02c593959ca7c39377542180420b36980caf895fa03c0d5336ab44fd59ecff1e8bf3f11d91d44d437b4246d4b29a5945beef3078f07e1071ff249f5794bed3f7ce8162afd7d407e99fdcccccc4cb742d2dfcc716be93d78e8f629fd79d0e96e9dd29f5682fcde71ef3648faebc4e277c0dfa143876e81a4bf0ecadf60836e7f70ce39efb698feb896f03990780eddfa487f1c765316d4cb14e065ba3d21fdc964dd7c4c888fe9b647fa8b397a8c3bc7d684f487799cc9376ffced4602b232aba0990d1e18be5b8cbfddba0ccd4902fb6e3d441213fe66e1b6416807860e20255eb06e46b77eeb0fb8dd3a07a46e9d8418dccc5b12afbf5db875f376ebf6d6edd2adc7df6e4b7eefbd03e994a5bd4e181a452162c38b4a1113c618638c75dc9e64c6ebfb5a27a9f1badb1ce94f5b1ce9ef86a4eb37747c8e28f11bba5d4a7f1b9060bd060d1a3468d0a041432f7aac94fe7094d18fd71deba41be94f03929bdfedba454a7f3bac2c0f83e161606060ba0c4ce75d9864dac3c04ce00cca132d54c1205f7c6b89878101d3473847ec0ed31f000303432209d44132888d64cfefdd79fabbdb1ae96f57a00921e248cdeb21c72354583b582d5e771ed690d7ddd2f8f2b9e3a9232844964d4e6a7a888e669860574a5e030dba9591fe34b822f21932749ea1ab197a862e7366c870f5f358008fbb8d91feb0d69daf30b245e92f8395d263e81843b730d21f062ba1d7e9d2984ef49012b25583caa77bf13a5d973975bacebb24ec100804eaf8744c9064753000885f4d29aa0d454e1c8b34513a1af142f4baeaec75b744e94f9f2befb696d0856dd910a5057006d919d1950fbb784c25e5710c202f4caab72ed29f6eaacb5fe8f842b743e9efc290b60a8f767e49ec138488edf8dc18a1f9d0a1473bda6568d0de8bf1a88847bb89b640fb089704f7a15d021c45a7701ebd80767002d2938aa1a28e169488ee8ea23714ed763875f6e80f0bb208875c60554b92a05608c51ded76098541d13ed5e2613a86e9b645fa8331d7fe3808633c5c06117b3efed6f1ad5ba1f47723a2e3f71ea1275906650952931edf0efadd6d50fadb4472363cef16e8c805292e3143848648f991baf219fd1c80e516901f40a7248f2f037deed627fd65cb22fda1a6d25be8d842b72bd29f85a827aff257539054530183ada78bd0a7febcda779de61cb1bbda79b797e3c2af225e7d125295058dc79714beb584cfabfd01aa56bba94a0dbd6a417dc18db217338c844b3354166a27e192e03eb55b20567b4020b046edfdaa7b8c8c7a8c3192ca2e6a9579ddc95eebced5e1eb2312153de7ce735773b73de92f4739fdfef0bbdb14e96f0bd39fbafc0a1d57e89627fd55b0f9dce73acf7535e7cbf54ec3bbbd1b9f135122d74778c0cee53a07c03ea7e6ba99eb260931c8e59a9ef36e77d21f379e393d5e410ea41b28492f5a5cf8b0d5497fd838d4f0bbdbe0d1c8c3e3090618162ba726293667f726d8e7dc2d8ebdb1c3b736c6c7e13cdc0bbcc65d9c87b46b0f2b8ff7ab7d0f6937559d672878b02f28cc947dd9d1f838312606a587ca4b458d10ee01393166d458e15145a80785f186250945d2cff0c9712b85cd39a1a4b0a10885644847cd4e17a105cac80140cb522a0ba8e84a0d9ed77da77bdd4b30f2bae32fb023292e2aa294d0766670efbdf7761cf6e0012f0073a92450a2050a1064998c339fd679dd775d06a6aa2f1e01efd1196b64895faa79822c1e503cb440d9b9f26d00541d0185a9288361e3d3398f678c66395eeb1e83f4a73906a25ee8933fd1ae3fd136ce854765036a8b93229fa36f45817fa2c10a285b9c1997f010daf1ade8f0e65794e8c204276129b4987d9df0ada891cdaf28d29f1d65428ba8b1eb57940aff8a5add255fe358fee46a604abefcb3f3e10f09803f76e850816573e55b39d1d6fcca8db69364131845982831f3ad1cc9a2f89533f124d7cac1fee462373cc50d5791e4572ebc490e5c2a526d30e5b2ead7ddf6e7e662516c1a16858d3ff7d19fc14ddc467f766dd4524e3e6d34ae40e1e0f1ad9aca9ef85527c7a6acc8d2a65683a7cab76a2e0bfc55836559e67042e5e90607926fd5ca2fbfea65db06eee0ba877fee9f12f4d317a83fb5d39f46cdf4a7e62a21678810c655b0096bcab7662fbfe6e39521aa2c2fab2c2f7c6beef26b269264f3d2b961c585966fd5402e67d7434dd446ab46d24b24c84accf29203fc9ab54c90a9fecc4bac2662a80705cf0eadb11cdf8adbb6fc9a810d98e2f2027964aa72e15b7350cbaf793803359c253c6249c12ddf9ab37c46ca4cc513b2d406ccbcd0fec4651cc06041a10a14488252aea2b8be7c2b6efb151305f0c3a928e7a90b961fbe1563f91523295dc94ade282245c7946fc54c6cbfe222c749cc85bb20806ffebccaf9d3e6cf6edaf3280a6946d2911f4b5a94bef516d77ebd46aedb75c5ca86ce7ed50e70896ed19f2f4cdc61f17482c10e1a692e8c4f745cf1ada7da0fc0674d075617a412ccb79e577e3da974d0b862446307c8966f3dc1d2cee53942ed3cb95c1b167f8521982284f0b69f3dfeb449abf5a7d008ec848e1a1249e65bad955f2dd89f40c856104161a48a856fb5cb5fed19bc24b8ef3442d5fc691680832982edabbd7a0e587f5aab3fbb0982b34997921c364280fc40b346aa6fb54be70853cb79f60f9c647f760f5ce092502f88138817229db21f5758beb3ab25f414995a70a1182b32c3779ac54c3901a9c3950554e53bcbfed4244c30201088e33b4f8d7222c4b28bc2c0a856f39cf717f012107dd1b285069424a92a28926ee8c549feed2ee01a88717b9397c45dae1ce556f60d25c1c573de5bc06df0f681245b6947539050f1424585950a28e718c5df3a0bcedb86a5142841ced8c6b4a6f40ce95074052ac0f0f7a650cba1b7110166c7e59c31ee2af02645248571c648a82f9f7b13695453c25a8419426f01399e33cf18e3ae75bf339787785ec7619b31c63258eb99dded580fd535f756f773a8dade75e06e0bb584699aa669765e7fb3c53dcfdb4235a9ae14d45eae246181b85f5ee45daf2dcdf3aede8ee345957364d4110a9cab2eaa5e6b343fe12e7debeb023d16b5c03ebc96ca7af010a301f45da7bf2e8efced3ae451f8d7c777efc5f7ee0c6f22a3d86e0d0da4117932a1c96b058b20138052f4b57c520ab3a07c26100aa8581b09d282c554162c2f3f3eaf90a122e64d649b90d76f4aad20b2b0d9344ddcb3699ab89bd834ad69bb696d5f3fa09e1e5470beb5fd5cf23d63e68bef15db01d1133ab813b648c88f3e618b761abc897c9af2ea9bc8272657706befbc310df0fc1c618e387bceddf63e933f787b13d9e4f3b837914d41db73e788be8678b38408132709ec3b95602a1ebcf5d6db0ca7b7d65a67e5adf7de3a530ced0aea95779e3ff75dce59e5780687fcdb85ea9a384d9c1c19757cdc9bc62ec58da3c7f5bcb7cbc99e7a99f8ae772677bd5d09304cf59c778efbf0f91b1f737e628b4fcceda9225915638cd5e5736b551563db7b6e2defc4a7d173d52679098e823d7f3c7c6b87def6b5c39b9d8359004b3445b0604020b0c767005bfc9557828da765940c1ca228433eb3cb9804c025e0bd08d28eeb66d79d232874d3ec3d23100814fa56116f1ea38a7f73fdf6dcedba5dafc22df4554489bfdd041513536a35a94cabbf17acbcfc6a8ae9fa6a2a31f4b6abb3bf3619fa6a83f687e8d4e32fd2ee766b4cf2f3576ab554561bfa6ab52c5892a515b34a5b66d52c97bffd042afd4def3d857f4f23237f8f66fa7a222dd1f4f5ec51343681cafd7a4afdedeb49755a71d0d7530bcceb5ccfb2bf6a6d40aa6b13b4cbf50a63fa7a7f887f95cbbf32f7222dfdedf1d749e9f57befcdfbde7bf7a8ac21ae0492e28cac2a4188563ed0ec594f49fc98986ecdd25fcc0fd71d0c494b30eafa72a42447ca510fdbf4ab6994e9ba3fc0032cafb5d69d040be4691d06f5ba82d69a43d7dd2e81d8d19acb829d23cc0fba743aa66b0d8236029e470450bb396263843195439fa0fb597492b27a6d8c62f35a6ba30b1e2a74bce01174c5b79e5c3d7e3dc15ef75379969d5aed351760f0f5b5c140942d2d7084c4bae8f8d61b34e1d73b241a2131ed78dde329c0234b114596962d20daf2d0fd52dd64087dbd5a97eb75bf60529457cc022ca6a43995019922f3ad57b943f7db063c47980f80be629be0eb8e876336af7f56d0a5a94875852819e45b319149778c8499b071ecc96b2cf5fa458aa496236640a26fc554af75e88eb9ce111b74dd7197087dc51823b74cc06a21c8d2828309119b900ddf8adb72fc9a81c161afaff9e77526beeed988cbeb7cf43a23e99e8b9704f7e99e75967a9da972dfbbb9e27bc79decec7bb765e9afcf585545fb5eafdb2ae9af3763553ec6e24510a15b2ae94f84e3988a0d885376510f000f1e00dd2ad31f008e52803e8410ba254b7f21889d7d88319e88e7259e73ce39e79c73ce39e79c73ce39e7bcef78eff13e02ef1ce09d04deed90778bc4bb35f26ea5709d18f62ef1db685a2537baf7e602dcf667e3d8dd2efd4e8b61844d088f2c3c40df6a99706cbe37cdde475251578070100deda55fad7209d5efbd77df59fdeebddd47d89d03bb9340fcdded70778b7435f6bbdbb0e4ef6ec5d2df161b3e081d83d06d58fa0321ff2af331dd5cfbc7f03ea6c7c4c4c4f49dd3c7741b25fdc5841df90f3ee8164afafb200cf82012f020ba054b7f203870e0c0a1db27e98f4394241c7c4579f11e78d0ad57faf34046a6730c2fd36d57fa938142168213db240965e83f74fca15b26e9ef03c618e30f3d1a3b3c8571075560945182b69c78ac895925dc63e0810e0b0530aa023c62030964864dfad51ad9255e96065d1991213826e81852b137b04cc79803fe3ae1b106c173c4064210183f217adc017713d3c0bd63fc01c6fd4cf2c4fc7a6a9d5ca7f22c030103b13cfe80bbb9dee0e38bfb7d8143f4f51e3dc61dacc68708d12d57fa0bc139e79cf325bd27c70701846eb7d21f081ba7c85494135e9c96ac7c6bff8d845c6bfaddf1dec7274ebfbb5592fef697d57fd0f107dd6aa5bf0f7aefbddbacf4d7bdca1e44c720ba4d92fe40882df90d361892e2484a0d32c80f926f036be337e81649fadbe0d7dc73e85dc6e7d03107afe173e83699fe38cc58558d128b7a191919ac9d932ecfe3757b24fdf166accab5089dd65af79dee2a5e39797a0f3ce8d62afd7920f6311fd3794c5763baad4a7f313356dd3559fb0e7adf41b746d25f074daafec3876e8ba4bf0f5497e99ba4780e38e8762afd71c0e4eb3b70f80e4ba0e1990e10a82c415f871adfa143870e3d446fcb7780e9d0a143872e810e5d6badbb2592fef490f4d7e1c844c6d3d0742b95fe68b8b8fccc0c111e224f6298996921f2cdd0f899999999192e2108401eb98afa1895fe6666acda5bd2f61e06f01eba35a63f0f3b3e671e332e166a42c11a325f3efadc7732674c2f4bcbe7b5c4e79cb34cce5ac8cf1c98ca9c33879c95147da62166beb441360e3fcbe46e669b3c4774e8b9dbae9e73b7cbad261b7eb56a536652ae2861293b32f3adb66dc6af273028cc1e72eee792229f7f3d8f3e3b493a5bc2c41306d4f1c9f8b3788e98e9b99f4e0154bb9c06683eb86e672543fadb39b62586f4b77b5ae7da741b6d862eefb4b67c21fd65ad7b57f9e7a697358c852d94cb5aad98f3de9bf39c55ccd19615b0b8bc202244eda9871227516a46fdf5c2070d0506acdba551b8e99510d1cb59eb61ba462c718e30d72e134e8b5509b3ee3aadf5de5b6bdea475d69ccb48c29dbadd92e986729ecf9429baad7a65794198bbefae7bee99479de9aed35a2f9758eb1b0fba738599672b5eaeea74973947f0cf3d0a33afd676aabbb364ee0c808dba6f284cfa3bb95eaca8503c333a4198672a170e0aaa1993ca05e593921955e04a12cc958151e06ab2835382a55c623db731638e2bad07a502863373af55e06bcdcdce31af724b7f19f540c345a4484f9a92194cae7cba0916192bb8e531f169b139ba04a4a72479d44e561277d51053d14e525c32b0acf439bbcaeb34bc322256996ce9d15d6b5d85eb82307b139d14bd38063c3befa530751a20bda7c191ca77510d18541b21699f1193163a72d1cd37ef5a47a3e24dec8450e5fdee0a3bcdcc9bc634b1ded326708e035ae0da890b77e337266d1c2af8b342d55de5751ade1313cf503cf2466354c85d487033e5b06ef704d434c89b54100d1ba70b4e48188b821030fc13b645ffeced95c19a1cf327b00b05230795c477ee8fb1c915dd0b29f207dca09a221434c4e90a93cf9908d430ec678689ab3d9de6f889eba2fbacb5d64596b80c3729a290be606488610de6c850876641b79b1a5ea0a26f1e43d5aef23a0def4a0903a62ba87db7a35a5a487f3a6f946f292e9402afd3f088a8e94fdfbcd1244fbb1555852934370546210a57249906d137ddae8851aec746af86b8253ebc49d1d8db6a8852d13e305ab7ab92aab2e22a06af24a6ab2050412a96cb0883950447efa0786f299d3cc4b8a9683d8462dd8ec85253d15f6ef74811af815d148b3ed59cb31126ad73af84889e886e750a3bcac3d9dc68dc9a1c8b09c52aaa3a0aa9dc39e7a7226271e5a2a07eb2d6bb9773ce39eb9cb3038638e7bd9c92530f7a54e2d2df563222e451c49bd2968a8d044395a4f068dd2e8a4a6929948bfa18cc79292705541b0ba371a986cfa9db19951784b9f40308897441987ce948cfb1784198dc8418152f081723da130522bd9c77ce401b7cee3c67e05994f9debd831d3e6749466cb4242dc16b5a8a74ce79a6d3f45e266253665f909179858624c718d255d9d5565b10676cf3e951c0565b87378dcb1d2e77db27178b8bfb62d49510e48c8893106b08e386922f54f74b95ce4edd993ce741b77bd3e8950477621d7dbb0db1c07791273444d35fbee5a0dcd4e8168e676dee1d84f25dc389636535507279a7ea76425b253a61a2316886c3bc4ec30b2a22495bcbd2c211c448cb6a6965229314566d1a5cb5ef54dd4e489955f093c8848b5815a260d5be5375bba0e1dd44acdfbb469bc4606abca291c333016589df94f2c9c2b0044d73b81ffcb6d19e43510e030cb7f7c63c726e465ac8f5529a51bc5375bba2a5ee1c868cdbed2aafd3f08c88da43de3f768dde8621f41b3d7bbd444f440923dcbb24540d23588167abeebd8b80a8878b768ea23d025cbe8e6049d2a00a927545416ac82505cfee99bea388da7eefcef7debddf6c11da4fee41c4c9ebc095506848141e2a527c3bc96fe3efae739afabdf74c8993d72bc1235af6446c3dfdda338db9d34290abf9664a5994f3f4772ef59c3b9a737ed1b6fb4e7fbba802eb762ea8349ff2b943cb9bcd4b426d4274aa45dd8e7882308df810d209c27cac5e12660d96216b1667f88b1e2f9ceebab359a14da91384f999c8ea04a15e12f85b0c2f08f3b179336e1581a284929969fd7e136966a6c3f0b6ab435d112f6d7a4db8ab07be17df2ea72ea40ebe70810a0b2236dc82640231424cc6a4132c55477c6672e312744c1d1505fd6009da8175ccb1459fe0c99de7a30ee1e78ca3b5d944489214c4af29444fec117d06f439e7acf3aa5678f398a3ecf39b4633362b19b861b6c5aa8b688bedca47e7638d111edc229000930ca95204b8c25a1919e9afaec718679db307ae9544e571d7618c71c63b9837915f589ebf1985c4b2663a55e8351d976930845260c020f2dd2ab626ede5f477c9777b4dbcc29b48af1f1b3c4229b20cb39018ad19c95b738ca5e631ced99948d45a12638c33debca4137f7b48af198f7b338aad0dbbe0f55e6f898612072970b64cf811f2d9e2025404a9f6b359b4c8371e9da660be91d604d77c68f0f01a0db8eddc76d59aa9b52cf08921931f184c2fb6506d315d19352b6248790c3538c03a88a2914cb1f5de7b4359c87aeba82549f5e7064499d1260ad90248cb5414174ef6da22ccc81b928d47477d13f995f3fbcda8254554588366c35683adbef7abc9df7b698abbbf5f48fe5e9a22fef2f1fc4de4978e1ea459d266c39b48331c8fbe89349b52edcd02a6880df5b0f212b44204055b9e7ce8006340b10d39bd20a1412589939255935490ae30a29fabe4972a649ffadbd3056a1bf837b3819a8f0eb01eb41b2e1f3e3e367ad1c1514fdece9680c3ec88c98f1a2721a1ef46f590690ede3cf6b03d85378f3dcaf38bde286891442b89568e13bc58631325619f73c6336652e794f11c6d6a45256de59cb3ce18639ee14da4122455be4201c7f3d52f6c5214d8ca0553490c213d4a5e63452a0b3586a9e4343992abc14030c63a6bbd2345c6d8c5d1e3143e8c71c62e563c8537a55cd4a046b6a9f38a7cafce4d99c348f1f7d64811a97d8537a588bcccd880102b5c505d2724a922c4e87391c6202028b515fae622142b47c0baaa5a3cf944bd88a177501cb678458d0891becb7a6ece6c5a84343866110b0b8cc5042c32b8e09b45f5bef7de8bb14edf7bafce43f7e2990b6f22bf5eb0083e05d97c7813e974e5d337914e6339393d5448d8930a0df1e47642347670423a746e7c0b15d38beaf8ce6b33d2a4ecf830cb72e50406696191ef8ae58d9bd89ce234a5aa8a12a4139b2f2cd61e637cb330e7ad47c890e1034b0e1f615e5854d9c947439d73ce3d74d65a6ba8a4beaa8931de6d5a443a572eb6f0e8b26207cf9de1b1d8d2c145164f846a7179837ba709baf1e9afbd0793964578c3a649888b19462e4e5fdce9858dce3a6b8c31c639638c314eaf893b4de1a51272a4b1fd1cb3309960638b99c1c7cecdc7cf4d0ffb40116c4a53853a3f4d3966994224a2f9b016abb369ec31c659671b8d6c5262a1a6d7c4b77e13d984d524841fed1124491f25dcd048ebc264ac0b958f2cb7273a3df7de1b447e75e1185a56608cbbae06c39b5131921dbd591ea3c589ce90808749d10d101c55326c9b8ba1fa66540c9d5b5563890265804729032ca989c71696281b3db7a81a598076359455943867365e693adb6b8b690e99004681bc6274f21ca4ce189f2b94862cc4fc555211d59124d97196ec2a02b22901b7538ece89599e49693d51494fd06c6e6f2295846926bdc3690f5a6bcd75cfbd9b5a6b9d397ed31c81821397731a02f7cb972f5f74015060cfb719aff82d3e9d944c4d4141438b0ae233d79e0253b673dbd5ad656a348e555371c2bcf2f293a39e6e2c1e2e5501d590494c6a7fdb5ce02e88a313d4ef378f53842cae905169b294763406055dc9da693b9bb50122351f39b4bad64ea48d8d919129953178ecb09ddbaedade7d54a98235f8fad2113955888133ce584bc83107c8b158c3c577adb03569b6aa181cde44b2b5d0e06d57a9f4fec0664855969009425a966b5eb7b59aa139c44b120f1857546a3b2c5a1b973cc30a529ab3ceba8b5ed328e30cd79b81822a8b5a94b3b30b4821cd9a50d0605a020434d36548da921bb02023b3b21cac22629727a592585659ceaea2ea8c77762995638b9530142a7254f995a712734ac81152b596c34a0f245f54987c76324ad1a473c65135af77e1cda3d017a35dde3727ab39d1511c5aeed0c1638ad051ba8368c73dbc7914aa09ca52864d4de55683af12a2277f6f0d8637a5888c104929953a2c9c1a48b6865d2c54b2954a8ce49426222e6c6455f6c6cdc57c445304caa12902096f7abbddcbf0428878db63d4b3a319dfb8d0e66a6ee5b91027cf56e09ac4ee6be8dc85d87bf7786be7d9ad322fdf3396b5b5bdd5571be722449a88734656814d88e22674126a2f1c131bd158e0ced872d679c7478f2d3b67485a635e61c6b3a392a95703bc69de8c83a268342fc2bb0467d344b3cc7a8c33d6bd895c42fdaa767c435806d4454b8e8f143dac14bc1ca2b1dc41f392b7cd048e10a7786c9961638b58cd8922384cc4df274957d676502db3a4f96c944b028a4d0ce886ed06940fcaaf2697d4f6419e5dfded2354ed230a270ff36654d28e3a96b3df449e953d853791675fbbb7782743636f28df2d1e777c336570e718f7bec31823db881eeff2cc6e55f59f67d65b9b8bcc8ca69adddcbdce37f1e896a327e3ce31c638a805bad7b63873f13db32d2d3413e1ee4d63d997a70ede346e797a9c909ab7d6dab8e5049d31376e19feed4da399513d85ec0820b473647ce2b3820a4c470d881d6596076f1ab7847d4ec607263c052321de3472f17a958ba7c16aacc7087858354578d3d845c72cc73dad1106a05c4deaf7de28ca518eae1573d10d6c6f74efad72fdb4f7de7befbdc6b58d6b587e78aa1a1206ab6e136a6de8de7be3a83b9daa2bea5ded08ab26d6887bef5d94d9b0dc4e14976f3d286733bbb501f901945e72a248316b51f52486d28fce79ef5d544d6041a2e9e162ea4635e79c73ceb7063b395bd15412a65ea0c637ac360a1c4535aad124129a6f3928e76189e9f6de3bc9758df40f7cdb33f6deb722baab98703333cbc17afffcde7b9b7bcb06e3bdb78daa5362a6761d44a739f47772dc4ed65aeb9cfe76466d7456f0d2466735e728543669508e0d36110549eb177c497901c3c9972b475ffefa8c7312245cda854909891572aed1c04636ca39672d67b4a76da0b4711361c32ccc39671b0e8236191605acee8c6e28e797633e4599c98ee9a9db5129629eca3559909d51ab2a877bdbf0eede7b9b501669480842491aa9ed9802c4c148c5788d64c5ad73a74979dc507e0e87368dbad31555a65cfadb493ba81425ae870e9792bc3da9d84114ccaa474be14d84197332621e13531ac1d47ab850a83031b682479b2003e66c84f262c78414a211c95985235149c47856d0072ecb054fb077ebe61ac2006f5a149bc0275e02d475930023a0f95b137589d1628c697a10235678b6a01cb514f161af2fdc92293b5977445daa5627ce19639cb4c9983fce03cdede4369ce3ac269b73d622ee9d556398c5b575543b56e29be70ca5854df97853137c51e1c7869b43511e231c855b0a2cda70ea765c146e5a6bcdd1a38e4e06cc7d3b44ae755753045f775dba459448c194b5d6391f834b0d3e1e2e2421f1289441a1679f90eafa84c333a8bc90946fa8d83017778dda0aec0b02f5cdc541ca2e824e5f4e11efe8b1982b6da0b4d63e9ce5056172df4dd188364389ef36bff150795677baa21aa6c4dda26e5542cd8f2a8ec2a473ce599824c355fb4ed5eda280e5204b94e9c9eb343cb1e1de3696883509625cb296f21c16d437e79c75d020170a350c8c6864470c2b24559e748911b5188c194d411822e7bb9ce6d00de9ef944273189d51e234dcd6029bd7a8d4abdba972a894dc0c030023180000180c0a48a22c0cd3386e590f14000d43b494a8a8643a0e8803811884811404510c05310cc310629431c429c7a0221bfc66552c96096cbb7133d2755fe383c7cee903307f9c6f0b8a49f6109e7f19c47f6658d9886e631ba5e16016b311fde32a91f77044bd8ee93656dfc6b8a29a094836d4c4a07f161055088032c09f77ce11d075bea284547239016629c801831f0d8eba88f4467b873ba05153e8e1dc2cba0d93c8a97e263dc46f09a4cde8b042c15c0dd023758ced239d66a8a95744da08f665de0da9a3a0c760231321984e655a983d8b53b9ef0b8d9d3bce883fcc5b7be4e767b55c53f51e2b61f50e64f60724459b186fcceffa154f276f4b8b6cd049d7033d2faf809d32dc468f0f5dc2591db20cd2d88529a56c9f4340319d0494ee06251e03f3f4181a41e537f36e13c6e793443c1b412eaf1c122981b94dccd33e0e147dd01be0650810f5f0ea6453e5f2b4c631dbeeb0ed8b57a03bf137306e62c73c3dc3d27a540adb3a493c392c98b547c3f71caf02fed5be00d8b49f26f0d6a449a5f0463426432f1f8125fab88b41352ae7f135eb01b2fa8fd986fcf2bad5d5736b4d720270e27396d98cc915517c28049958c798a2c390dc1c3a83b1804cd656a7efde7b87bef6f1980560d871eca95888011c5b146a2f1497d9dbc9be91b3f58c4c10149ab72d776cf49bd085708c375ffb35fa58f0dceab8b0edf86bec7b6bebe09a7b60a180e75c6ac0fd59578b5f2f229efe60df9a41f13c930917a87a51b52e02afd751e4dfb744a710475ed41a951a8e87bcd60709d64968b5817aaf5156888ede4fe729b6828d4f534ecfbc21b9b68303649bd4b64c13264fd3789a8214dc794d8004802a6c4e7daa7d301eed30003181e9da528f248e75a2060c13518963a60aba0b3244ea83378939ad791ecb548959a35ae2cc13668029cc26a6d8d553caa1b9cac620d8712f0fe802c219425eed5857e204b393e4006b64409b4a180e5933af84a4c90ab225e1504f7304133d32acb091ca30ab7e75b3a5e0f2e98f724122d638239efaa342a0824b8de85dde5b41d0d4b731a42299b99dd5df6e30eed62d90ea25c066b03658c2e1e636d3375631242c06fd4decadaea30ec56235d5ab88756f924f876557f4ae28722dc37cdb52d4ef60bf1a69278e2badd5c7b9f8f67cc80214eb50aa68f3ed483b7004d1d5989001b6c6788815bc5477f65ad7382519adf68f00bb2e8c7bc927134003b62bed2593354ead55664a33c964988341ac7ca5f8308c15b343ba60c23e4a091886600c44cbb91ffb9c803757f9b29baf266fa0202e795cd4deb68f6ec0463c8fe8576fe11aec02055520b24f09374a18ef283bebda1f39e9a6f29a0ff5ad37461cbdc491e99fa6c6a3bda9c87a291ba652cec2c15828c82d7e3b31e209c724532b07b8e06e442d09c65fbdee4c4bd723afcbecf6fe16d95092148504754a7f1ba3535847936caba2f2e8927364d11b58570946588a952af24c60cd0a65816562a3c55472593c5543fc4f54476b92d3db8ebe78907b495aedcbd532a1c598a91a3b379bda1261acb52c9af60cb024b655f4514fe22eccce16b43238fcdad14597e83fc1bdd66d49512db7f713b22d18c6bbfc3ede7ccbae65873b518263b6931dfc465d659b6a092467a809a12eb8db462a7c177062c2e835c16b1835005208cf614e84b3f5546c4828c5bc4f0beb961194d85b5123fca7070453989e6b8c95d2b7577d755d60d0d3b08d2d6f9cad242f3d5a594f631157f6fee9eeba06ad7d8e701e438925d94a32c73d3b08b3871717c976b5adeb8944efde156b5760df0eff093aab2bc6292f9182131479f2c288ade190d61ca7dc69fce51277182c723089c1e993d81131e0a2215b8a40a4bb1523dfbae1b013444e0493dc2b2319c20cc412d47af49592493f6b7b2227a5953f25706b027d5016996db843a42b1bc29ca1ff1dcde7f1e7979584303ff79713de958b0a129d302b2b0866c825fb9f47929921fc7185e41f7c1d06aa10c1e3dd1c31d220b492a7830ae5f746a0b672dfdb962b7013b86d95ae6ae3aafa130e673cb3220715401e1533caca94c9c2322155ff5fc18f0744d5e8876d2508883dc411111368b2609dec5e1a4ecac2b8aeaeb990031d47945ca024a451f3c584d49c4773b05ea5eea03e20ffe37cbf7201e2ff59d62e20ffc3f90e64c880c91f9aea56764ebb5e40de3f4ed3ef9c6c9957fd9d916e45f32ee7c300b84fd14d0d119fdbe6e1237a407ca529423e8ca8f9b6e3a39b7113191c00bfc195c0d9c90de0ba2e9ce6b39b51c4e9b55e50eabd3bda71da24e5b7a5006749ed0d49f9b0c37a80ab8bf30de589e3f18685fe11c77b431b694e32cad6ebf9217bcb889884f2d3e3c6ff519328dd3853527abba2fc273bbb621e1f08e2855b248a46c82beac2b993122ffa3b1bdb08afcd761f66e3d985e25a58b07fb9d8461ce511357b0a660c05f6b46e023366ed7e85285e455205aa4f86bf251758d6ad1d71ea0dc44eaec61b7214c6dbaa3de589a45bd2c6d2b3561e517e1bec8656026438f72e59762161848d55d85ca29ec40756ab8453cdc4f9a5fc6f74846b5ccd4902765e03b8bb72be0d9a3692f261c774804b57e79b854b7d2146e7e75e4115f0eb3b079afab21a4538a52efa0aca4d7b55453f47a92d46c392ed62c0dda1070a21ad2fb3cbf1b17b6476ea5f2fd5d35a903c53440a9cc5d481f5b2108bc2c388bff33b657f3e388496dbfda3f93b854ac6622e75ba8a8b1023ff405321100e26c92ca74c045ccafe40bb8b0e0da0139702ef5ee298e85e600bf22709db4b0cfda51bdb309e450061ce10eb04b1a8872a1332052f00f0bb43e4ba2c6f8dff4c7e2909cbbfee2c20ab641d7f517d1b8392ab3d3e039a9b4ff51a1030464279b46d0b3dbd4d478acd52ef8e61c97e1e4d1a23b8c55b00101b1ab4849f95bf23517d310882861b8bc0330a05c153120de0614000539692125390d7a354145ad075b19d2def1d43c53ba907b8dac56981fde68d5a3490940f384c8ff9fa7473a9ae343d026ddf0ef047a170199f3a44f23206ebaa7313e22abfe9b168ae573ae605ab543e88aca0d95895150534afe6fde67792b690860c7729a3f19087e91a87f0ab96ec90ba5af41d6ec05f5070d197ff80dad78e990bc36c52f640e0dc95dfe9a952fa1ec284b33eea0b3442b6d3f9b6e240fb329215656eb6e00aba4272c15aeb0debf6f533a65d0bd18d7a07c9a72980855425c2c8d7e3f63ba6453f312079e4b8b270570a0359bf7f7db73974095cb5d6461835e1964d6f8da322e51fdd00ede35c3e8679d765a21ce10bd78f4f39670de99a06642144b6dd344a2a6ffde542f7d549d68ac94c122c25df458b8eb902edc1a23aceaeac939620a13d33673e24c3aeb11072da7d2540f180d39c6d315929706a2b62bec684f39e499adf3237a2514bdfbe2a7c92e5432684615f2c6f81a0a0e1882febf61c17df8587ac7c646cab493d2342fcb60afaad310b7ddb07110113cf4759125f9fa3b4c1911a7c3e898e61c34c6de269562c794b16558bced76298d0cf1c46a9fa76cb42a7c3dbb3a069336973240e740a718610d4f959d03ca23b488115304af200d0a3df946b6c8ac1f63635d777b34504bf5432af1a3d618a9db781f2c13a5876781b01ed3408c313849d3b1587cd42b398b8b798432a0ca4f88122f03a7fa930eadeb9346970509111dcbc9b86a0a6d0cd7f9065e1117ccbfe1a994d8a8cfaa6a631bacf7ea1813023bdbc1f951d93a9453fe0c9311827d412b95e40a74be6008c7d0ece667973f8e0005327b09f9016e822177eb643d954675c8b299a20b3ff71173ecc246a5c7ad2e0333a9c1774d3e5c89f05f06fa76a5e81dd1467ba2a33bf92a6cb4e785659626516b05894da9fce510abae2fb54d7246ad7b2cfa0a6468798843b369f7818032bc569be5b9b0c628b49381e7e1c8d94847650c200c87110929c2e366cdde24e0c1cc7e0a3854143a46a04ee56c60e8c0a1fd20541b5d3e6c6cd7a39111cc0285ea28f1bc53dad2d8efa7553ca0b0e8ebb3381d1455e69cb3be93580d79dd3163622333c7983654c174a188c56c54e8bbbde1147e1227be2aa10b1631c9270b5e84644c2e56aec2d077a7b903973919f37efa4e0a038266da03fddf21b1a3c6f1f1196990ad677a2692fcb3c29dc01d77a3d98a97a9f46d08de7f3d99aa7b0a49407776d5697936526b90189f3a15d2443373a0572e027a2dc3975c25946afcb1d6e12f3f9743f949ef0697d6cfea644c8f7438175fbb06b34c516a9e3603b60cd182482f2962b9d1fff9241a402b524f8fdacca03119b299754c17024f2d942143b8a2df408843c2a93d18aef295341a8dba4014d62232bd0e50834562a7e03532af5045231868fb9650fce27eebade4a811bec4094eaf80180e8942ab57bc2f712bf63ca542f03cf39cb863f8319a65ea14ab58cc6ec59b918929aa09ca87bb37f7c19366c884b48403b2cc2b1c6c0f68ec1632a2a0d88f89183fb446c30a7379cce1c667b78dadf0dee47994aa1188fb0b854f8565999f7a5df6279246a06f6cd815151a266581ffa14c81441ad2e4d18e316b76085ad3b2d65236c4c0c36efec0c25caf00d8379a759cf8f64abfdf388e034b73a01f2ac2deac14e484abd389fd1a17fa127bd8e04a44e9dc2a6303b75c9116c2a62d0bb011402fc2c799c6145c2a978f07c76ceb75a1244def6b3d264e2a99ee43caac1339247544f481df745134b46f42d46e9aa4469d4f73b157d9f461a1b9ae4fabd16dfbc1eb5c26a61f3fffac2b3e24ea2f44ac57408815c7c2603431935b0657bba6fa5d060bddbeb0d99d3e69d3e816eef6621bfa2353258c50065e7c021e87b2aa0cddb7a1486b1263df62a0aec08c6e36f03f1672685c0208c468ca221a90aa5e70d1b424b3ebb9195218dfca2f9f37bb3fe8c5125bdb6e565716fcd140fc6040b7b1672aa854bf6c57649d0bb73845bb49c8b09820ada129faed24ae617c4242c58207421e868040e8072ca2b64a9a09a1378f80082c8a5a884afe70ff0b405d0f0200a0b3e538fccf6478775020215e2c65257cbde82dccf8e1c06e5936b77d3750a46d66c40515ed7cd8291ede42447d2bfe0bfdc4c8230293f5c3f5a5cbc1f4a78302dcb5ff8b6bf9c84b63235a6324afdea262c17a95ef3b52adbbb0632975e2ba7ddc699a6de149324a085991bad263b2f29cd20911a93ed7979417bcee47b332a247fcd8d6da61570a7c2d8c5b2e3ddb78d2793657956ee5762fec655a1ebea310153032fba17cb2f7f70b3c4fd714ac2d03e2d87e00c3bd2e5cbd9409be2246d2070796684130d130d2252f4b369244b14151be8d787949fc04cbc0a9c1b883e6ebe97622c03752624e8072615803a8e3dcae8e6d16f181bdedf360051d82257a3af5d5f0dd505f0c71991a015b8ed0313402a2cba0183744029db2fed179a3098732a5fbca4c1a810fcf60ee650edfa3dd18ca58fb58691e8fd6d0310952d72b58fb586d801d82376e17dc3026e8e78c8ce61027b56313bf6932a8f5d1b00a1de263af2942a5847b78fdc8ddc6375743c4b71cb3c54b27369298e4b909c4664075a5fa368381c4a6107f26217513b3bb802ed0d1c9b0f7b410587ed4a6c45844e10a5ceec68512a4e9045bd45564a5e3808aa72bc0c6af4ab974940559a83bc0bb344c2f1e677bb0a3d86d29d1251163f189c95be1c93637339e37657c59560ac05f77a2e666a0100fc0cc94bc1491c0e6554757625ebb78be86a1e3823a2a3e108e835fde165a23a28fd41a125509dce78bce9129c2b5c724f7734dc1fd87afc167035570d1db595b08f835b0793b3491feb13176389f696353aa4c1af471daa0d42ac4fa3334eeaf0e51a362b6deaf606bdf0a3eb2e7b26b366b9e45556c04ee003db89adc3004eda42e6e730737b058b9611efb7e6f2036be53c92c387d995e1ccd65c98ad895d70f6447928b7e23575da2e816d84283c9509f5314aa32afb91d10f37693a030679e860db6668cea4d64e0ec0e4436884c9188e6762ff3595ece91d8f57859a1c350e515edb9d9330e6b7deb409c9f0e63612cc2baa5733445beb2c9090c9ba2054082296f1347b253304c7bb5398dda365c29daf835e0e503f2c1b8a5f86110390f8a55f38724b933471410aa163877374c22da4dc9b143293700a3c0cdd32c9caa819ad8d9cb85e6680865f50f6958691aa74f980e77ef6f6f5460aff84f5a92ada1f8cf6f226ebb4efa94e6c2ac7303701eee1aea876cf4d3b76ef052852ace41c63184de041e6fd0076bb31cb4f0cb970b4df9b06073f5a68b8ad72198c2c57c92c21f1232dc4c7c10d8f58ebf84f26a0118e1f7e896016b5d0620c35c5f888914d9adf0e43660de96900f4e8d5a68528e92d6f06e1cd636cd484eee62b7d797c46024ab5663140f42ad2e82d54d037ff68a1cee40b9f41573067d676594400807377662135ea58884d9401bd1a4fa184dd660b7971c3a56ca3392520cb177568f4f6e00d30e6814d14ab115d5482ddd1dbe25813c6fbc45ffb10067a93f8179ce841a1ea3685c0e843749813fde20c62ab4895dade0985dfb0a533cf07abc0485de5942af9fb02f6ff366c78630ad740bb557210cbfd405720cfd2db1a38948c90a6bcd610a479000fe5de0feb2979f24e3c07ab3941c5149665edc31938d82a0bdfd2c84f4b824a8b3af833e35f865c7eb675135c90bbed9cef38f8494ca8960d56cc5fb476faa4f17f6c9479df8826591c213d9f4dbe85931dcfb70f0df2d11a2123de2dee521462b4ef89559388d65c61db491383ef0ca27d4563cf8df74f0c21a4ee553aa7f0ff463e40282bc440c0910fbf463d516bc48fc37caf0fe4e28d17a6fabfd4f6eb7a8da96014abbfb4029dcd1ebc84a5b9aa873b064d0acfa6b348755f440557fa055fdd3d42f163bf5e944da17900308d474bcadd141bd457f12f3802ec067df2c562e20565bc11c2e2ac87ef1d8c6b02a0090f1c4a64340b7a64ea66e8960c553a59beca2629f72bcab167423bd49da14a27d457194c66e8a59c9cc1e660ccc9f8ad6b954cab7ac0c242b6e01484bfc424e9f4ed3817a41d8192e314a538a13c15b257369e7147a8748665cc5267c1cd92688a3ceb59e45414e1a535cc15d9012357d56a73b125176ab247cb035b130d0cbe2243529284e23a57e83351ed55ea43da74e69df3ea79c1db1a9a26f07ac08d15841750be02cfe7a060f2951062050ae40287681b0a611a213b356f7faf2fa4885dd3c734d12e74690ea94defda1c86acfd51a111e6340a4c49cfae408dc24b9ad30f19255dfafae35ed38c883afca60da47d5934b5cf18eeb12d3992ca481d8561922c5a85d875383f5186741c8908bf2566c5c8787a9088f4f6be7cb9b4fc36f96137e971a6a14642ec02e263f9901f7e9d34d5fbaa3898e1e8664c23b354dae5f97c9f79a957271df2129963e94005c1caf90e85383bc715213dc55767ca587a08db5d1059e8c3956291bc7a23add019a90749967160c4014fe3a3b9421ed6936729a629cbc4d6ca375e71f05cc9cf6b36e59cdff50dcc9a48d230fbb0208d187dfb1e4583a849bbd36ea659d6251bca63cf8fc496ff5f69764759b69d1d81fff0a632498c292e852349a90df8c5d2c2f88c1356ca881881a32c706dcb2b3d516c3bc4b8a797f0cfe5c4e139237c30981a8cd987860d3b1f384945d589ab73a942c2702b70e7c7426b0fdfeec3341018b4148f73b23eeb18b5c2d18a1fcfebd0ce7940c8c68d134249cba922d86a780f034eba0d35b2453d59141fa733bba63ceedda7eb545c4c1ce096cb80a4b265a5ab2560228b57103eb6e7696ed11eb6f731cd86b1e0e1feace55daaf0811fbd137008e9d1a1e744d62b3c19c2e822e3f6e6b7dc4035ae9664d1e24fcd712856a2be85e216dd889e2be7c09efe3d2bb7efcfe8828d3719f2a3e7f798a8282fb5355eec7cbf67ad5cbed104068e3c851e5cfa33a6a96744a569a432e2277a4e7ef488a0216f87e46e34231a4f1f2855d102dadd73f82f51fa6422bdf47a7a81d5a4d04e79730dd3de1838a5fad199fd6dad909e9198832936a30bdd114c0f2c3e7b54dd5b18cef307358e8ede0ed8c4b7c6dacfc6111fb3c1c114359e0cabe7807865456b14728397c3477025cfa4daf55daa8ee65a11cde615170758082bee9d584811bcffa50b998e6c49f14b9781d12439a5cac028d09c3244640c29be32326504645e892282b382c995cacf560151ff3c64e7127426e30e04db481eb09804b4a10cffb3a26ad5efb022d4861c5d51f6437cd86d1082a8b62ea2fdb19926bde53a9bf4148324cfa1cb69d9798fa5b8924466288953b68c8c21f9a522ae8c9254aab84ed6d81b841b9e26fd256aa7d19c707e9c7248242e81630b5bddfd5ff4848c3c99d942056752f91b452d4c855bae385d81e9ceab23ab1488036d62727f16000642105bb3a6e53a058b19402038caba6c202e680aa58891f4515e4e418ec4c1a0f5aed40723480b553b5c1932d5ed080a7ea41f885ec38eca58abdcd96bfa9097534ce27307a88bbe8f6fc44cebc8051a4181bd274ba784c087e1021a82bc02d4612175a333d1a035d1f351e4ec4a35b5590649705446cc9e2609f96846777299053af24ecaf9ed977fa46c740d8a5ca0dfb532677fbe29ba9f069edd2651b50eeb5bc6a01a7bfab0d66e1612ad7e19b46ffad9118b39ed0a10f9db9abd3c9a84fbe97a13a445e0b7b2f0b22107fb19764d843db804e3ba1dadd21d57e75a7a807be062b7bfbfe947a7d22ff097a701b872cb526ddaf5380fcb00841ffc85d3c56ff1889941a33312e118279efaede78815c420584889e988c9b64b2456ff0e6f4e8554852c0bd02c861b7d936b7834bc62c565d53f5faba4403c88a348cdd947a2a7959e0535df7dfac3725755f651b2a9f3bb7935e2461998820ecb22c321b09eb26fca1cd422fbc2bf87c564843e7c5d79c1cfd2abaac05d7f63efc7fe5e1c2879a055b518303c649297143f8666e92d7b1727558cad505d527fbf0b06d9197c856d1fa7f8fc409b4247fa1cff3591077c9f1f8d909ee8838e941bcd8996175d18748fcf69c10c2b1530ef931d61e76cdd61d12ccf483dfe94a257bb32cd8243a6b3cfdcdffa558031bbc44159c8ebf508f6a27089194e177fb3fb0917d9d37c9cae6740cb449f5cd757e566f6a2ef53789857b6ab8e35239d2855a887d9bb36792e424441bcdf0b2dc5fe23a52fbbda678abd20754895635a0238993674401f7578b797704561f5bfed1000a166344876bfe349b9e290dad97dbfd922454adba0890c432ac4694e5f8b54591122d84475bc97dad7f314312035ea4c4bec32003da50fd320fef46059ed4e1a6bccaa174ed5542faf07468182d59b04c4d77d62bbf4e9fa40cb7a8529712da0a572ef1c98d208862761a904dc5c287e5bbe39c0aef6f30e08fdceab2334723809a7e1712b4dc794fed1dc80b57f0f5f09ef411264b0ca422877be8dbd058885e5408251fabe6a051845e0c0f90f5524038ff582e7a31148829adff99156888b2660c7a7fb7c01bcc4d03b40cb355810d2e033f1efb84bf9017b6f46dbde92763d73f73eb20b4479b23d6107125f924711878daffc7a6c314760c7ddbc9f38362a6fa16328f325392ee59359f19ebec80ba9731a98163c6585c445af26272a124d06d7292dbaeeec4890f666529fcde3e5d3bf8ffd2c8f5d842199c2aa2c7d369aff4230cf61ab59b14d948cb28f19313d323c166400c09c73c64db17a80ca57af0432d5d19e33ba1a008642d98d45647cc5293a6df7bfe1146a5a94d8b29a81d7326723abcd02b4460b2b47f07e2fc37cfe86d244c9341de4258ff64147d41b2654db69f6a203bdee8168a9060bbf1d19ec716608dc5a29b3cc7b9d93f031a3016c4ebb677d306bb3ea18af1e641a9f7ca3e1b7d3c78181b78ea742871a49746f49751c64d15de626181e0f94e001b553347ad94a18a4816dfb95aa502099807990743028fe698d2860a55bb57cc80c733dd504c3ace1c321c3b56b01900d3d055c4b2d518d3923f56b38ea29cd692d1cf84a931142371e6ba7e39eb983cb12e126cfe0286dd55fcbc73069f9cb4107b0a93713d84a12a5ced6852b34900369e4a83ed24c384e1c69ffe3d5d12e1578d4db23d491a1598b6d17d0b1b178d6e07e7296386b3b8025019764ff28486c6662a653357a4636ab28a8f74ab52d1b3e213894e6562321975cc5187599cda60171ba8359b39a5a7f75890b2b59c98cd406b68d61b19fa286ea44aeaff82934fde912251260095b996aecae0eeb518660f3e28fa389c0e2b034101e4ca939d0a1145838d3b16d9b045a4409083bd56c0d6a304e97e91755e6b664d2f6f84937986e721b536e35604680586d42842770731e5b1e8991ce2ce49b7aa4094dc6aa7a2be55d169e388785a34be2e9f80428cd36c15e125aa1958606337a12734f19d0c55f576c5789a484207fbd66b94b5bc2be23b1ae8fc07c0083abb206926cfe57e8b69beb8b84aa6be2e136a895572eb2b9ad8f252f53695536054d5c21f67a12aeec47e86b04e796a9d26f438b0592ecd6621942ba268811e149202db711e680c0124101041848a23cd6d7645c099715aa620ac8c3b51536654913dc793bbbc8bc124f8fb9cd235ba1082b774d85c5d1e4fe16ad34b15d4a299afcda03e1dc9fa407fd0dc33f5dee11e87fd147346a68dd4ab3d4d175e12b0beb91bbbc6ea529ed81d7103567e13515c6be614f9f671e37fa74500d7f5beace3fe98c99951dacea809734985ddac24b01bee20f32751282639c6ad4895e1c4df5e8925f86dbbebe1dc5e60a1f74dc3e88e34b094dcd8975e7870b061a8992a01b8dc4d4315b723f20e06368ca0f204f0a91422d0640e6eee5f2e8179ecacb026951159228e60dba17d2ddace68281166e83704728c841978610a261e96d47053f3d5119c4a0269d756ff08162ba88334c4396fa7ab0b4a15fe883349bc4e3735c797d0910126ef46142ed98aefb709cb66387c7c687d871f93f7f54fb957d2cc62d8b2b99cf943c70b2a702cc6ea372c8470b5f7c8d2cf2e13a19ed9436d10161bb8c184d128459d7e6817c1607d7ea1a5c7fb11a7969e9defa8c0697b3b1ffe8760fd6d4612cf204a3b9938bc1f8b483dafe32302065e507f416e071fbf3623ef9f33fd0620087c5274b6bfba740f96310b6f564f57d15cd6a067b5da343324bc8063aee80124f9ff78af6eaeb5acbdeab6381d95da45d8c2e1e0cca7cd1a4ab3e35ec622e92debf93d24b0df6b324837b9297cac7f5033e5df6664da848f12a5b590eb987d871d87feb0ec750cf33cf2d0b852650bee9d643ef7b0ed668a48a57ab80582f42a3c69e1c31f4e055e87a068217b744bb0b41eac8211a37d022a8b6a9c8237d990a29c38d4697d43d85f622693d44a0a2563e0926fc49230a809e5880e3451abf20e2db1d915fa015f279451003810088d42000745cd3eba43110b39543bbe9907d36700519fe6b94770e5ebb15636cdc50d74e20a41ff5ec6f1cafa8278d2843edc1d49ce5f3d7d301876549ecee2d969f058d2ee24886d1345d811983463614426e421d79214b6b5c98ab86e88f0ddbbaa4d2da95ea2d900a785ba74a9c162debc13fafedf1c18cb0e446438eb20f2247c5fad15b2c1ce15d64716c90f69f541baae952fdbd4d3644483d39cbdf4d2694aa6e57ff0083f9c6423cd4df3b1d1a58c1b4e1578aeb127e2a10baa4a2573e3d2430c9edf7043410a0dcee8d038a7f8022082a176751a2fd5056d1b903189ec144378d7758e47f678e8cbc9fe8ca1191e2dd73a1dd10e04f7788648d21bc03e6839fcda6afab00cb2a7affe715f745253640ff83ab423d6baa70cb97abebcbb6341b1c0fbe422d2bc7cf0b3931fb1c23d0dd95c9b491e186111719856073a32452e5d86109c98a90823b5a7c09e3302651784249554e6f26712d49deeae0ba5b988444dc4a227e926bb6b244350f1d2956f9dc81fbb6dabbd2c61583b0a88e63129b4b0f6fa4cf10856384f228b18277d485c2c727632d316879762ab783d525c9c1c7a1bbd880b2081e0e6ac56e5c81e8910370c5a2e9cd36ecfb6b92f91279160bdf7427c01a53cd681bc38a4d2f382145bda243d1605f89820e686b2a78c18ec8f3bf523504f065dee67e82129eb3142dbb0bad23d7b041ef7978ecdaff23b5dc3328f3749eaea859d1723f16da503875b1a3d7012f98b17870bbf593b2c7e45ad6bc59e948322f3e6043c761e8befd616e7f169f4ce9c33364f87fc4ade4d50d1ddd8287bf984ae2c40d430efcc1e743dbf40ecfbdd175d10babce3cf38f00fec3c8e0d08b9e99708d5966a2436179bff97ea3056b69c20e24e3d40ea17dc922b07c289580b9c46f11690498d0f3508ae0952b0ad40e063fe1cb984d7fc0851f9eba4bad6d382288c954046387aa953c75b035f5e5e180ce2068b962630e8b6ad7e6c76cbb823c6e5a646d242ff7074777840047cc2636568576f61bab645c7d026f41662a352dd4d52bcc2178e547b6d0c7642c52994f280166254c3f0a2a1fdda537de8fc6f604e05c45551fb8299e2a9320bd137f82a81a49d44f973a9280c4e71547f78c25be219bf8050f2485cfc29b843407078d3a97e52a385dece018f979b839bd4aca7a78069f4d1e344d8c89a355cf05107c3a081182c0a232b6d61adc934329c1ee3b82a31213de39270176ff8c604509a8e05c3bf5b1687a31e47a6766057a611aa776744d6c4e635043399e11c409d8caa86ac51c5c2c3ca1a48acfc131c6bfcf549cbe8a6921c5f7465d4768595deb7d44258f2009904800cad7344640e0d62a5de16a13cb32e833745e4069608a6528f55d466c138825b5a91c13e4f9714a27377d10a0af13ac5b6e6056a992aec1a0512d1a443c2b4ba56e87c5ebc7095352073305c2211ccc8c5af34c1987ba30f445c0da60f372eaea05b42a4015be6e6115611675abdd67222ac7dd30f2cfb2e23d7f14721c02e0b3034a519225148bf361bbd1a1347f90f0098109bc327d1d802eca36bf1ba2839bd7f1a656458226b8526306e249860285719b1d9c046ca7ef5cdf01713d07b2c029fad8cc1d02e625c997a6c0e9d99d1f2b5212ed6bcf394f812817495258d2eb806eff8a232c15b6c07207945c9c34d1981f13d0da3abc729152ff18902d39f7e1489d78f7248934381e6c8907fe65c3b025963a9c58d6b38e214327c74b14a789c2b6ae12b995007d6bf5dda6105196d3ad9ab38b289684bd471a47a01ac1599d8fc4061b02797bcceb4a664e14b7b608c17065e455b48ace3e7f86ab47319a25ff51d4a419e62c1525908f4fe92e44e3a9efeb6623f521d586f4c825808a0b93cebec32db9896ccfc8cb3690f8cf4c3534fe4e58ee3183a2f2baa68310c8c00ea8c923b94526a7b7d143ee2295ff6d4492ab858509cc372ad75df4f523d6f713d1462208cc6597664160a9eb5c0a04ff9c3d17d6e411a5ec08ad47994d59e4309361463fb1a9682391228a63a48598d0f1ec9a522f108273c6dac00c3decb3792757474eeb2c9fab7168f1f44e5839427fe3ce8395a32f199ffba8b7cdbf4eac328ebb641bf1dff27729713a8b9c44f629479e70f1202d78e14df8464959b83b4592b34749c906986ca890ca15093a485ee384ef79df74f53b60db99a669710416b2005ff8221c3d34d09341f88e12828f5e8698eeb8b1ea82c4688fa6dec6a8abe2432975da3b86321f7ee169c665b8c3a749e4a73168e761e525af13088f7bdba978841fecca127d9ef95eae7a833cd77d48e3768762ce9e14f64e14fba5f4d4afd05d7df741d35eb45590fbe34ea5b7c53257d1460d76404f23e9d2f7c95508a871964d079d7e60d10b0aaf84c4cb9e6ca6ea3aeac684c82bab919f6107cd6d691aa6ea5fef75d5b811852515acf60a6846d11bb4dd15db59b3564849a3e83081d5e1d85c4e7ccb384af9a65bd8dc08c0b1ea92266caa9e5315979c2e6613b8f09d9556b8bc10f8191c611f1a0407b6bd5f049c9fb482e8c29354ec40ba64c7033a551411cda8fcc6fc22bb0b571ea415eaffda046184ca3d8c4e92d01f69f170c40069c9cf3ab368ff2d8ace35af29cd4782ecbfb04aedb3e45e03c9d1d53a8eb29a7716c281d7550079ac344a1ef1e7d56c6d2358995b4ae0c7a6e2c725b3c0a14f941113a9f47bcb1c088d15b79833aecea64739557d7d353b8ecc3bad68d38b86facfced3a9d4dbb8b80df14896a11dc47aa0f0c7a828d3fb5c63cd1b20e5038ef81e1404e66bd85bff09542cf65bd9c910dd7b128c960a9d8254dd4f6d5bd0dc12f202d65cd63f437ae4a4120b4627089d932cade149257a95de4cac6cd122b987c1b106357b37b03ee37c2de9233aee7f7ccdc1f380b0c05aab1b06ad32747921b0cc44737358855c748a6a37a34a98b9d0f06f7d568e328f575ccde15241bc37c8a976715ebf5f4267d933324862518d0774d65e00ed7dc4351fdd0437b6d19d037931c66c826e357236880d77d27e67ae91672771b39c21377d960c33fa53bd604b58932c315a69e6a1b292506f163c337f5b0344697589f921737e46722919a08115b90fc9f9db549494bc63b3051e5fb7134650463498b2921a15069e3ed3c420acf139ff8ea1e03c1458f23fa89e9227e83a9c79eaa5c0d7607f9c8a718472b3bbc0805a279db75788ce7db7c5948cdc347baac431bfbc26b1d11d5c18ca4e9f0a179b945e9769307a66cc6f5ce3419bfd073c6a4993bcfde32f9653eb95bd1dd9ca91ff36b756443d9dcbdec6d5d533816b3971d1f54eb007cabf35176565fabe59f9093b709f943540dd2ddd9e25ca0942d295a67e0b1bdcd17546cc661e311e2e31a392c590e7fc89a6185d48d50030ca67921adb400645b53f77d8d795d03f8326c1b6ed75366911c11f3b1334d3e8454709e6ba3c4801ee240b82077c96e377d101f12fdab525e03e7924eb56cdcf64b93dffaf7a9d0f9b5cbc8819460af44c22c23162f847b9282bc1caea22abfbcba6c846fdc41b356b9fdcd89c93dc847e6c5347b9287b566d671a44c16a4dbfa7c466f07d8cb605ebc5aaa3f6a75637412a64afb2f3395b67d48f6a7b413413951e65164e8208976c0b6def97cc227082480a593a166a53139466be70186901fa7ecee51a1a575762491a8c0dedae46c3bf1d1cd2aa996a72dbac8b47429d3e1cc67d828e3da8a1b56b84d6f67914a394185f92e26044ffa4eca0c1203e37f528a04c9d844b63a1ace022f8a9bf21c4ac19eace4b0d5d53b7e5e080f35e6f759c2d91d5dc36fb426a47abe9b6756741935d1825b5f5edcf0a28922bbbd4e0775f63622e430b64c8048a6945457481c2a82d699829020996a0ddd44b7bf0167aee261f629d49bc85676218d10488767e0c47059d7e2506a827600a5900de268d4ca7b76682ab6f50c7345454d6ddfe4f5dcc7332eefe4a26d590ddb176d2b850b0909ebcf21003632de4d73cf8646db7496287bc4d01d6d39b1c7145ce8f8211a6439f8796e13e1a4db3dd238226296674a0bd20ca5047f4848762156af4106510b7a24c412902433b22f694bc8ad9173f74147c2306ea2dd6327e58507eebbdb5002f946d61633eef3895d7a30514714b9a94bc139d5d68bf53c9e0efe379cdc46a4a7878d49d52820dc96d86f3311e83202e5825c89af892c0ed331f28c84bc52d50b50acad3e2d754c1777dc9584294b9b5066ac2b5b562c563f72c4df0475212adc63ae09a62a712074148f5405f4c586dd8cb94f05f672f2defde8d21adbde811b11c05060d5656378b7e310d64cd63e72160274ecb3e3eb6fb5cdebfac97a60e30feccbd717ee8b37ae579eb1fdda80e756ce9aad7d5d5837bd5eb3ef53a2f14405dde274553effba80bb7a9bffbd5ef9eeac72d0f3bcdab6becd08f7f86472e7e7e124021a035d0540178f8d8efeae2ef0616cd780658436ce3e6cc4fcb5bb1560f1a6c0c7ab6f0930cc3db6a970cdbb28a4107d4e492078e681cf7377db61da9de4ee7f86107972e96e33d6df7c262fb30f0974864ba9c546689ca9454e087235866001d46b85005755bf8da2a8fd8fe9d20726ba064d516d4b0394628323c7185bb257189fd3113584fe2e83ab9d6d9145b0eeefba374407dd4bca0ae4c5c3aa11a09889b194761c37261499d4257e520e8b5af567ab791a616581e7c90e8a04a53458505b2791f77a8ebb9e61dea8a6bb447a700aa087726f0822e7c5337f898a7293b06950a198d4e347de241dd7982f366e8119ba4cace63ea21a4631c7f64c249c3476bc35576a04b2e1c74da00e84a9b0782cef1c3b70c555acc814bfe1366f1af661b44bd1049f5bd2a104942604e8446887f0b3833b8b652b836aea6f8ad2545fa65e0b03c3a39cdf46930e6a2a30114bafc600ac92dd64fa3c1be5ca700624ac97dcdb2a15811b489e1fa9904437fe74a6970a51b9767489c77c6cb0ccba71db1711fff8d6401c1fa6c3af9d11b99200670ac1206f7246919346a2082f2e1584a4442563dce5f754976401bb759d995326dd50f89706bdb73d83aefb2ba47921e4243ad04d4a66f208fdda952029def6e2eb873637958d479501cb0a433fc5eefb1a6e3b0d4ecb688575a10c0fd039d568708d0719214fd468d7e1f571bf425d697c382fea69d86f7e5cda4a84f16663ccf411c37829e4c0bd0a5a9006be8b696d214dc56bd6ae623fef113413bda898fdef73d9bd5cbce089b8f3eb2210fd18ea74724a2773a5003af330087625ccc4321c1bf96e5c5a9230daa44d6f05e2a19ea735515fd36678e1ac21c4fc579380c61471f508af69a92b624ba3eef1570764db4dc8c8f7c2b53551af47bb95fa81fa153fe972dd78c181538651430ce1debb11856c2bcc6d658481a97887ad424645a4f1a369230e7483278551a52cbb9673934f8a631ddc8d82378abc8821eb1314da07594968cb85d461435faa52523ee3dde2fd6cffea9b83f8934dc886823363716face7110b0b0efb4c4cc57212e6471acca40ea218782a5c1884a3d4e48bc4b0161834b37359743d31ce8262564386bdee36f539c738df2c003932653173e307f15b293e60dbe0dc43e0ff67685d65aeaf02bbaa556e8a57d6cf224dd09e650d0b8a076ed5a08f9372b4ab5b90016031246ee9537a9e27fb66600cfdf71777cd84196d5d65c2ec5b654410b123007f4fc32555d25d1c5f3d1fd80dcde245717310396c67e968cefbbb74734cde4ff6637c4814217b17cb6daa077c47771bc4653a03c9e10a0c8372844626d8eb8ff86c0e9ac957f32acbd4e9d5afb929237643516d3bb7ea1b0f0134c254d962d6324d9c85e4c1033a73399af01507344fcaaf1aa79f63fdd6a020c32c3a34e24f8dd6603ab5c20937fbc8e81004bf9275305ec8746a3169a6c1a738166136eba0e52d438ffbf3cbbffe9da5d9063045ea4b5b4c7b7aa098eb57a1a0d191f10005ce6d165001147a15c6ba1fb22d6dc317e8df087cda96724f8a7e36214c297656052b1bd7c1ee2fa336abcfbf1787b234b291026601329ec57dc7f6f5fbf11e10a7e63def64c307e9cc0d5dc40809ff7616c14d3e68f79df05a12f0a454e23d78c28e5f87fd2bf55ee66fd52269f24c5181bf44610c780e1cb75409c407205a9efe6dcc0e028d4fced88d888a02e6bbb2fc1a7f55561973d80d01f2daf5f2f6e2bade34171cb7502da293ed85d9639c3c9ccb2947ecc6d855a6fef608b1b461a85083dc26d52b2399fb60e66851dbf8117c8917117361de9aa83530a859f4836a549094dd61a85f8330974033152040e5e01b5263077ecb4203ed0926d670b8307cb9bd2c6a0bfec373518f74e50b880d1161869fc6a9780bf4ee8bf0ecb55d46ee1084b0d646ba9f85858cb55be70f093fea27ceb4b66b8cb7b09a7218d0f3d4269d0b641252e92a50d0a22d4bc67ce69dde8bda91e60c2dcd9a104b94cefc08ff6450eda4c02c4cba0af400dea77eb89dea9133cfc58482a8e33a6d71f7a77f82d4c733568390b3e62213b2ef772d7f90d43d78defefd6d9fdb6bb707b82c8a5aaf900c6c44e01bb7352428f522c457d83c07844b9a465c5511c015ec8d1538978c1ffa91cde8b0b14f9832035dcd47413642d4f750092e193306d0c11053305421831d562da3c62f72d887a9a1b0b2ea1dee41211e70c63ad72f37b5f41c1b4c40254eaf9d7ad37c09d7c0aa01c3745e4fa006632c69924f8bcc2bd0cca054400bab50ea917a28600785db14663d5ea9998d26d93301cb737270269640d7c73c265dcc8da9c28e8cd298bb7b8a1b6cbea8720ed26d20de40b5cbc8b1ec2c03915dea9cebca4e61c1a4e05817323b891403d464535b180990dcee7faba5416a71e0381d9b74d37e453b081e0df46d1b92f16e44023b92c11092d21abc04b1498787615b64f558f6ca513488bf2083f721fcf8c5c8829248419ff1b90c4ddca119e60f7bba46da8c2cd4e67f55df27707e8b00c7400ec5905c12ef63b3179ebf5fa322e53e3562d2981b3b15e0f24d7176c9054522e522f371ca05dc3b5a2009df21dfd2fbc83629fbb1e33609b1396ea3abc050e488daa0556583e3722e43d21b30a817dff2c5afebf543558cd86ef96726dbf11e523240a516221e3c72750497cc94769d79a97ad2a9c51d81b693336b547cb0006379b35e6d22afd79e5a0cfbf75fc62a5e13338743629e558055796335081c9bbec785eee1f322c372151f0573ec089040c2f14d0c5cbfbcf7d588e7a4d031005b78beeebd72a30fa48f07e974aaf68918197c64e09d57f96e3e0ab8ab714577c8837f11d0a801b087ce12c40fabd214e2ff0df5cacc664bd9c6d8510d369bb001eabe0834fadb2e4fb883a72e7b19754bd0c444c4b646fe9eea79f3db932cda16598a8b12af8353d0dabf5f20c0e82d275727e815b8ce05741ee8020cc231fff45e96c82f1f4b1fa93c0eb8552d3fde9559b5e0033557850582514703a5200dbcc1c3bcfb6d8b4a0000375bcebbdbb8f2c524ca338e4414439e9a2077346a5c5a5fdf0f85e140b942b3e0ebbf7d8550e00645bce7cd9989d143510c1fe2f58796cb17910e26163431a7049e520c82cbbf681f705efcbf689c9debfdb5b4bd6b42e7d4d0032ad299ed5a754711c2964c0c20e01be40bebf09b3704114e954505495562f07bf69be8620e92f3af3113cf5bfd2b2753ea9d6d73fb808eab1c829c034c70571cbe56e4283b85e1e00a478fa94043359ddc8a0661fc101b23f7a76e912a99d6f1b3b5c22788ced72da526dcef444956b6c826d0d854a7121d0f092222ed4fa87c48805dc743f0b85bf3e727e563ce70cb1500d65b8ebebea156aa825925a04b3afadfb8a5593f79fd7b22e4ae4c5ff636425279d5b03a8407c8d1839672d0fe2bafd83a6c445632c5c3783872c84b7f620ea1152fb7a8c2712010014bef75a7fb3242523669840c9640875607f25fd6d3df3436f18a4e904ea09bfde33bd4a53fc403dee1363ec035b1facd2cee468c130e836d84c4209dc46db0c1fa9aed7c98ac83caf519889bec41e31f7d7fae508c70affc2b261e83c2d33ed77e6a1585d67726945479363a7e504babf86f13670f10ea6ffe1edd7844c05d6aff4f518f09cc3ee2e6e3c012c718f8682ab5dca95232f2714bbb9676768683a0ee2be63489f6e7ce1d78af95b13596b7284e8ab2407c53c00f562f3e2d3a314ae88c6b3be15574560bba119bf9404c56318b5be5f5b8417e6b52b036c357a9e9ddcabc84e03cde590c94b619b8a64eb8077f702816fc8796d08cce2c4e1b37e09534df6b6dbdaff35c87920ebfb99bd9bafee42318ac9d45f83e7f9bcfe56b4766d8fde8682dd48700ec5baa7f1ebe08376f472db4196e12456c183a38e224a3cac4a05702af87bb89d12df7698d0985b86f01d70dd1b05155956a91308458056446d2f5e8e0a6962454c9103b610f0ee83845113ee47047962b16f4c335fef0dd95e9228b7bc22dbe01dcad5f84a99336b396917be4c9da81e6b17ed6147f998676d65b61f6e03c58a32b26b433868d61163945441014eb2b5e32dd88104f46b02caf119685d30ce594e07620c9b899582bb01d2c4ee027f1340b7daf827f4a88d9e24082c023cc392518405034ca4280e968743203af245ddec717a51dc18312d6bf32cb5ee807403f85962d96c3866ea2257b3539416a885f4267b6fb9e5de32491954071d062a06250f7ddf768fb4fc80947175b559d7acf47d33c2d1aceb83fbdf5352c6ad4f5fcdbaeaa749a891b79a5d7f7404d02cc5d92df6c93fa8dcaefbac39ff396df5209b2e4141edfab54cadffe190e992104ebb9e2012ce7f4eaf4806defc872e09f164d707b1f88fdd15480e44b22ff047d2aea0ccd6012873b3d69c17b33bebaa4fcb4f36826971d546fb6a3ea6bdd19e2e57c5e33a02befd7b90aaae4eb98c3259916dd38fc4541f4d0727fbdca952ab5b6afacff9cd34a85f8bf6a9baa1ca99b859fd08eda9554af519b5b5be5941997d99a08cea7098a60c99b6c0bbbecf0a10aa4359577d23dd2c6765b99d5d7116839ad3a797db33fbba39eaaaafc37797c1d8aedf6cca3ec77d5adcf7f5ed53752172d9e7b8cf9a8bb27555457d5aeeb3e66438ecd335675df5ef967ce29c0dc72094e718b00121aa52a81a1505a66a10c04445e1b034b7c2c38ca579d141268a111c649008f162647214d1816346c894f185e7e68a922721076cc638a115c929e11931e6c60b3a6bc48049423dac1363a5891931498e882922a172dccbe50b11171f727c16e4a2f417a4160828f504052999ccc75b43c6f33e6f8dd29a2f5e58efa764ca06f38e4e1e3dd0d301952ca560c7c4a64b4a80e05c851426508483d344cb0d0636ae4252982138184525c1a14921c7131938db61e68cbb6c711a3a2105519ada2059a2bde0b32d4f94047175f884220641ec79588a11528460137b03040a2d50d920141808b21085730a8e7a40baa149103f8a80817ec206c12516ca6c30071808decffb619feff3713933eea0f2d1daec506dba44f3c2860c99385e70438c767013ce24ed683a433ba302ff516b04c93215c492239480de0f2476ecc01d43743b549b320dc942f43e3e4f7cf8b061a4c89917ba240172c577d4559bdb9a31485eda0ce13d8a28896752702af2b4559b3a154142c179380fda4685d90c524a60d60c016f15a2159cb6e779dee779ac4d975670322483123d4aa4f9beef937d1f11f9dda042bfeffb7a30d57cd8e4a64c352c3e5e78adf76e9a29dec3a094957c6db616839ef5aebdf6cbb6d63d7b3368c18908149e0811a2c6656ba46c6bedf5be64cfb3d64ae9b6b5d6b34d46e4c0265c3000b3333ae8b8ece082227644914e45907e500dda04818be510278c92126cad25506c007f18a305f434500316dd949032305c711d4ca6e425262bb80108a3cfa33234254a181d12342db8810827fa01cd8e8f26196cbac484c8d78220f571fdece5f01cfbcc5b68b052c4c4881a92d4c0238a0fa5a314491e49d3c1c30536199a128840a1c1715cfa093912121db13d1990cc26ca874afe1255446527c8120e8243910f159c37750a12c39de25484c21e37752a22faa877ef35375d7ae148b640f8580ffce27d51d6d612d64011e37d5c402d59a7e6507343999bcd526fa4012267dbf7c6d1a53133657cf1467743f724e46087a6e88c0a58877a52675a30c3f2ac4f7cef05bf4bd3ec7b99cc40d9570a76afe726acf4e2146898ca389db929e81926323eec4b0676efe77d8a715326323becf37d74e0d830838e242fe020c4d413bf41058699588484a5f21f13783b043ff804240881060840f963b8593780c4041508b1e10544ec00b31a8675d5b1aa7c9f3ba7e9a3fea8266c7ad21c0afba4bb5cffebfbd487511fa83e8dfa24a8d57be18661b9c2c7c907946df7e9b3c1dbc277c476acdf4cf116bcd67e3e90c4c92610383e7c4cf9c0f1a68d1b5d9b227640b0e1f2022c463449555913839a5a9a243a21687a9870a60791993765d4901133064a4c0fb91d8a5801114a4344897a21cc0a608c84e08102148f1282800384d40f64be80f1e2830b703eb0e0a9861ea67479c265c996225a6429f02093653902f7821698d9214a072f5878b882430e361c64b8c1c002166e38b28222a71d3d9a76dc60da2da1b11161c30f356ca1e18a12939519aa20cdd02429053204a152c28f2925e490e2264a1a28b9188240eaa2021d60703ab2f2048a13175ea0b930a4a6e384263a74b430c5c21a26639608a1e4698516d06e4842430aa42071724489112245886644887618c5196284903241c20071415116156e29d830a382c2d1094c4c30f243051f3978f4c811e3c1467666c710257cd1a18528871c4b3892ea0d15d4580b47208903040e0e1f533870bc69e346d7a6881d106cb8bc008b114d5255d6c4a0a69626894e089a1b269cb94164e64d193564c48c8112d3436e8722564084d21051c2282761968031224411948f209c62398078f3c39a2f64bc847181171fb43c5de9a1a98b152e51b638d1b2840723598a7047f868c111397678a3c31a2c64ae84c9c10b0e5a6e5758d074839515447172d2b484c9c8529c224c6d717c3c204e0e07bc79b18603322ec2b4f0d2002d2caebc9a7eac6c10658513062c5980110514f9c0f1a1024e8e04bce959a3011904843980179716f38a019a0a60850051523819c0126da42cfa291f0298ca11803700589301199e30187841a165e7ca892613564a44d1714262498e9156517ee383f526c7ea0db94645660c83c52f2117bc03c8826bfb66f0a0d8cfe6a770e2f977b2ce67dd996cf7c7feeebec2cdeaeee6673d1f776f727364bbd32ae03bb3ba53479763b17ee0618ce9c0250441d0a28879b853c796e5c944ada0bd3a29ffd9607f3426940926f26c092ab95955f7b10693401ba8b39ba04d09cf3209de3e3f1a989464f31f7af105b1ad369ff87b425a7c2d89cdf3944929cba6a40724764877a872b38249e09fa0d3ae1fe210e70ccc151fcd8b5599daa7ca874588ef47abf9cf292631f19f05ec4abb1a8b3251b665fe036a5049fce13f5637d1f9fa60927d89b40a268934509cf9cf09ea3e20fef3bbba0faaf2546daa1a35aefb914c48a216b44ff3f8b8eafc7d319bd025f411a8b32f9cb50e831853288c6dd6d1574b91569f22e8ecc00aea53049d0dee40ef96fd4f109ccaa4f54a6fbb083adbfef5acc6a00edc893612ce01940593ddba2da9a77555636b750a5ec74f49fb332c2c4774a9ed2efae369a8e9fa432d62b7e1966eb5a2cab4fef4a8d657eaa6b55930f9c42b726571f661e169e88f27b9393ecb73fed37a7f2fe33f3ada427c7fb7b993dfac5029ebae32690bfaee86b668e96b7e685617cd26cb95ed2296ae2be339f7287ff255c92addca6eb5a83fb9e9504a79f5e74afb1787ba6ef2896d5b680856c2bedcc81e0195789d3f7daa6ec7c2ca7cf0ce93f893c53e7d67c3c49f6895a7a7d9fea3470699f81326caa3aa4708dad147f5497cd540443a5fe2e9c4f6f79be3ec6b08e6ef4fd6a13c37621665b2f2b4c9f2c45695de1e4b5a772d51e2a6a38323f1267e068937a1ebd0fee0c49bf81927744db22e7f135ea2acb45a5875416e42000607b4c7df9639a58f9b1cdfb97539356d788071d979988c98a94653dadece8d2a3c8ea33eeb1eefea45516c7ded215e60dce24a14c5db2a4fef5475b02f8035599e75146feb6febc35fad56ab57b5f459f78a02e25e6990f460f5e08ff7feaa83abe3a6cd6eee3c7573bcf713eb5e95d84d6f7bb35335921dd41e5545b54fab8bdaa3baa074bfd2b6ef258fbba6bbfce9fae3c7f676257fb0eac56201b1ca2fade0f43d72e591a90d08a9ca2353a626b47dee9c296a91fc1ca8297919184b04c9d4a9c84de90146f9549d2b542d46badbd4dc01186bddf5554d5258b095fa526799c4a64d52ba8a34c30ef7f2314f1f1daacb41d107c15f20b8abae7057fd8a855afa3ef605e3d2a913b85963f80fad3bdb9d9decdeaebb6c7ab4be8766ac30dcd01a5860ac5062a84072fd9e16749409862f9b7ede7489d6263f9951a627b14d5fdc74a9c909f555338464ca5445ca3e375d5ac1cda64c5598ec2130a0da7449c914a5d8b8e99292174a907dd3a63544b55d08bee03243326d923ab24f95149013d3261599fa2a4d3da0290846cb02a65aae0988212ec8f6895d8a6dcb13cfb6050bb8ebe31140ad91c2e444b74f5c1fcbb023604a2ae39b2ead40e4995ac011c19bd659f676fd0ed8da106dd94f5bf6a94114bd8d34856316f26859d8b967f249777cac8b8aa258c90bfe0c5167f1f1cf1035d6e1f8e2cf18f5d01dbfeffbc292c270496120d08e757dd9cdefdbe2a657695e8c487632e3e0ac4a74f7fee3cf814aca3e7532b0b571da670adb3e35d8ee04b7cf15db999ace486dbceb06ee27f5f0e91050b427494e50589828d96eb67a1037b485d555cb7018feb74f36b73dd440337caa8bbaab2afcc377376e54ddb8d1aeba701a7523ffe1a68971ce6e33f22437aaeefeb9831604299898ff0491db7976e71df1685e0dbcb5baea52281ddd4147cccfdbd9297f2f56490ad86da3688f63d9a71b61ed5bec9417b33b37324d1f7345c3e8fdc8a1cd5233481ef31f26fe4397c010e5fcc876afd69cffb890ed4f9fbe6875d5d505ddd47671f6053ee1eaa2e6aa0aff31b4c7c73d6efa750c6df135575de450631f72fdfae5c9cdeffe2c2a9fd8c7dfb43616eed8da8c370f10588e8f4b1eefc1c75fc91182c0c75ae8c87b509b7a84a06bffea072212b55085857a470b5558ae1ead76d5e47b5c7e0f96dfdf0f1cf6695bcb545dcd65c9b96add068e194918a11eb14128df63add5a997f3749eccfb41e419ed237667adfd2a08e2402cf5db94e9460ed856a9dc8ecbbcdbcce29076bbfe9789fcb6c11b08e2febe10f8df0fc16acd7d65c5bb569b26df07dfeaf209ca78647cfe42485f2ee87b500bd999a55957256538ace6b0f090411c7873d366c92728dbe0cdbb59577ddcecc9687b50340ab53fc001da536b005957b7b4ef95dfb34af2c772e501dd2450dac3e369190e1b431b59f20491e40fc156254f0ceb529544ac578149fb426db7ab6fe7cbb086ed0ff6c8b6b04addc0df9625dda32dbc8538501724d4c03b840aa54221e82bdcd9f00a7d89332beed0ed500c92a759a8056f126ae0fd2dc9e7c5f150e07e1d9d46a4d1c8bdd1c3dd75c1d2165637219ff5622dbfbf75425f44259830d5cb7660e4bbbdb5a803643b30d59f36ca76d59fac7ddada6351f3c8001fc4e20ff4453e599757fca768663bb9edea458d75cdbe565ab489b5b2c2726991ca9a994c374f6dfdf8ac6769a1fcab1f829da26d7f1d0011118ddfd2da42adcab1c40dc184c65f7dd0f8abafbf5a7dd6422b6d85563090470ec319688fbfeac90f6bef8125a744f16d0e99dc95ab986f60cbf88b7c1a67e369a530ce7967e7b435eb01cdbeb252db1f692ae337c927fba2304aab21ed31c9d6c65284129fdcf4914fd1e6e6c746b169d32eb657e3ccbe6ccde26a6bb55e55fdf44884aaf00f77f635c660c4b66386b126225982a9f834ceb0d1381b91f438b3b43cc35a7cda894fe217dac26bce2cc80e38b016caf6b748a19311b85a72d5b514df96f747962adcd91759b32e716659b5dd9e89330f4059f6fe1c670efb31ce46232245688b6be41c67b5ed3fae54b5f4b65d92cf7136ce680bfcfe630ab4850ab4456d7481fe9035378be88bb459979fe4cdc8765207da269d50d3ff1cc9190e1b5f2cc59d082504ed01437bfcc99a7d896da8cdbec4303219c61b35ba4392d8a7f864db16366ad1d2f2493e914ff645eeaccb1fe32732493ec9ddf62777241cfa126de4d4ca847d92bb5aeb1da11e41b2407bfcf19fe36cbbaf4e146c6d8b64fca228d25b5ed91781bbbf4f080fb1fdf74c46b3d5af7a5b6d8764cfeac8a7ad59249b646df66671b445addaba4055f8636d6bb427e3b7168be1f7696b73d36d929bfe6169954aeb646f6e6289806f8ba33d3bf229da80acebd6accbba449b7ddda46bb36d11b7fd79821ca66aa2d24228805d7afbee0f37fdceaecccd074bc83c74afb83972ded4168708076e8eef0fe495de9c8badd19b45b2b5edc1466d7564a7c960ecc8f541a27c5e99cc1d30fef09f2639d3bda285ae80a46afd5cc162fb8360592b56782cbc1efcddacdeb65ea670d353b859adaee66bb1e6efe44abdd6b761a7c6b6f762b61f203f5bd208c137f01ec491af67bf7b2f2d0b0dcfda32c5189afe73b5f71e0b37bd0fc1d529c02f87cff881ea2160117ef4f985d706c9e7d3f814745b50049d6d6978abbfffa3c634bc95be5f465aa2d41b33d11138fe577ec04d0f87e208ee88f7624de303feb2b119720cd445378c382e50170c27f2581c22dba3b6f3d321d070d383615f34ea0d261bd467a6e17d3a863ddf9a68405a6dda4483121a6cb5560fabac75ebb9f5eab94756c0fed8a7a553b3bee3fade1eb2d54e8d34c529da76751f411004411004ed056fe4583e3158756fb2d8284e0840c985184c47f30499789dd7d1423c413a8fc163a0855eb51e3198ce0fc14cfc106c0876e287603b3f0443f19a2708832ff125b4104f508947f128b4100a0c34855d6d8df24e89a234fa80b8598530d8a18407cc84bdf7defb188328d8f9fcf7de7bc94ce2592dcb24dfbf1f3e2d47e0463b04f7437dae9ef55ca2365de2b2c569d3252e276c300d756102bc755db66ccab4e9d2162c7ba407c874a98bd3a64b5da4bcd874898bd40675f68571ce3b3bffa609ead3466e87af53f204e93c85813a3f042b51f2049578136f420bf1881ab4c1409c75d52ff1433030c9bad86491665fa24ca4b9a86d1114f685429bd02a7d624da939ea336fdd11790a6d217e7d904a753106d9f7c7d2855415f74f37da57d41e242c570fea587f4baf8c9bf5734a4fe766fd56e94db9593f979fcccdca2abd9d086eb4affe626e9628294ca7544010313a182549fd11199141fd197d3337a5f2f9cd2ecec037a84f2da6f4be9829a53e8bf1d0dd7b44f6f75ef51a9c284f90112206632121710983c4e5051f13fff1681eeed4f1b2830b6891d06c19d1a0b92292365a9633331e6237f01279ac4bd4064b959b3ae30a82a03531b3b62f4e5d98a0be4499f02c68c124a40daa8bfb46fb54f9907d7ee05b118b622886589451157683ba89ce15658f5b72a18c057c86319245b3e4b36d894d19479dce93d000318fa6264a455b5342911c14389d18e30fca2bf2198df4335deaa1b68162d076fd0a6cb9391455245e55dad0b1b17ad6e7d246ce933a3f6a1bad1f7f0685e968a1a3118eec53d85150ebc7cf41f9c567952ad587bf2a858e64a83efca320d5874fa2b4a10acad1316880a02ac72743712443711449ffa310d4a8e02c8f5505a6904f0a544fba12cbfca1580ec1c65c86dfca1fe696f8590be572fc20d58f5a287cd5973456ab300c1f04205bd9e4f3d66e2f886cb0fa17c9be282ccb2e2ed79b0c59b5ebdf180f746ff685b32ff2ebdffa17cabec4274b104a1a6508d65561630cebaab718f9c6dcaa9ac45e10d9602838b21f82b31cd6f04d8193c2ded8768d0af8cf0b22db0e00132d004cb46d358f045e10d9b67d4164db4d42206a5d1b175997eb05910d463f08759fa82909146a8722ca27bdcd320c17b32ecd277eb8ef098718f675748a20c9a65f1f2807cca60fc32f967bdf3d10857c7eb80f675f473ce6d6c0cda7ef6d8efc31fbfa70d9da0f879ddcac6f8dc89ebeb87bbbdd9bf8313eed5abbc7aaeccf034fc859d4a13eba3737ebdf2dbbde18401c08a1c68d41d132bbfad91bbb32ff396fee12dd98047c37092f965bfd5abbb75d6b6ed6ff6e6dd70fb7ebef181feec37d1fee9b19b9c5b85dd510f60caa8c3485bdd6fbf1af66e1e326f5f97ce85b1e7fba7d30a8bf8f7e501ed5368b3abb9b340515dd96616dea94020f9e207fcc13a479bcaf6137e5c0f7f675547fa4312ebee5599f36ae319efb43b0f05925cfd540443a5cdbf00f62bdff1d82b9163aba3a68f5a1165abd10ebc5a24c61e2e3fbad52f561c9fa5caedecba3ab7964f88f1fe43f8eef9a5a97bfa885c4779dadd05110f9aaf0591f143eabf5e15f1d94c927b5d0118f0cd6b73e88f52d2d74745f88757510eb57f8591ac60b1d05b5deb510fed6931f1119d00c6961168be51c18fd1c1faa0606a92a4c90c0b054048cc2fc615832acaa23d7424741fea31602b22efc1e6a1ad6f5142616c914e69a27287cfff0fd298c04146ae3074fc827d57d36ebc26f89e887ab7e511849f018fd1244caf64f9f7db2d8dff87df7bbf6e530ef473096b1e779d486c3071fd436c00f35fe400c5fd414468df2996d881f3e58dac02f03cf103fe4097a5163f1c117ad2bd4b804addf31b4bad089d1ec5f4b1239adcc5a91aa510c31783fdae3b487f6f8fbd326d65d53eaaaee84452cc786c55d7fbc2a5a8ab16d97d8a72f7ae548661443554c6dff93476aa4afb18caf629b3e25c79c8fb9190e1b4515f559c0a6b48901f4e5398b731e7326bde5ecebfbdfd9c9191b6123f161b8ed7b721c36926161e26316e2cdba1cf72fde74e41e791075f6356a19c378d9fe9f78b3ffe2cd8eb95b07f677548f7607aa208f388f6dab59b11daed60f3dec79a7b537c4da5b216d566c35c58af98f27e5a667573a593e57bbd8f667c5fca7be5b2d53c1c41f77b53e6b57518f3aeb5aed58b1ca8ab969fa98e391bf5fed5653fec2b03ae656ba15927db54c30aad9fea32ef3b0fd57b855d2cab67d755bedb6fbab62f6d5c232d5cebe54ff30f2cf91cdf61fd7500790efdfaad957eb66575a28d8aad95badb61d4e6e1566e5c5139f2c653b30f1c79ae383f6f8e7f0a02a7eb8cb5b708ee400d9fe674b47b7aeb5a32d389ef7678efd514b558e2c67e61b78ba094f10f9678eac1422df060ef149cdf301f9ab5f691baa27f5110f56c1547f4920f1c7aa22c76fe5645fcd91794eeb665faddc4eceb7ed9f23c54dcfd9574e0a98c8f6cf5961fb9f39b1163e5bb99c588e8cf6784e520e528e6cfb833832dd670ed2f65fed5c55b666f6658d726bb6cf0fc876ff3e1c0e236d77b174986ee7d8b0f3b4610202a5804d99803cd9302c1499893c4b2db5f4ed0bc6ff7b302875185fa5d84dbb66a407c894a9e86953db96295fd148a881b709b0c8238a3e476a570a13262038f69515e52ed24dba3806f94c387f4dc6afa4047e8fe3ccbe4228da1386d92afcafccbec22877f98765b6af7668b3ff5d99ff58cd83f75937de1ef5f29fd64966fdb9b3c9cfef0cb646537080eacf5b65fbd3fa42f630d59fb78626ab67952a77b9cb5b7d2e6519b67aeb84fe9cbf6f00d9df389bf9cf293e913c59c7de20daee0cd84e649faa2bcb77dfcd3ac3087cdb7b72e73f6768f34a4f85551f9548a8e4eb178e82182a46230300105000a315000028140a888462915014855824f70314800876a244664e2812c601711805411404010c00814c0000008610631040c418a403d1d61558324f6100b5cdfbc2c2ab2ce45978b9a50687d4292edf184f505a580b8269a9c1a612c480a2e0a351e4a1b72f7d1501d54ea4de012a7729de780284099e93f6aa787b7af9205b56b998f0a59c2e5b0bdadbf37954d8feaf8b1651876abc6aa249447b9da0219c8e33171e9376b02d81bc37bd42a9b6e79fede9962cbaea84a3811593a693dd9a9be756776ac976f428cd64b797787d8002ff4ac09bfd33b576afb702c26ec9e4cd07d5da3c359ec65f7825956c2c89f42ae6050c1822830fb88cbcc17b060ffa2004d73701b2c47fd64d408612ac587f181c2ed134bde23438c6a47aebf4beb0b05b999f8a255812a9c01ec1f41814451fe2e7868da2b01254bfeb909dfc2d528856d05af5c196dc4fd3be215f0b98b71b96e9c6c7c2014ba87aa93b25969e651f5af7b3d74c587c4d104c3b24627a3f6ddb0f4b3170e520fa9b11b191db77a238c6179886ad0c5a95ebe27845af9969f187557aed0c616a39a1af51484e72184b4e6d8e9b56501ba69e2fc8965edb7f7009dabea74380665ddd33beeb73115a742c95917eb0ebab56e9f8ce2bc647908cfb1ca8f36c1c4bbcef282975106afd9a7616779b8931e8ba8ea5b011feb442835e41a33b82602fc1a09643c0c2651a78e4818924376707116f833c6e350a3b5b8c62c88c41cf8dcbb812b55d9d05e92a36518eebe71cd170740cb838792a0824a073c6b4f318a94afdd7ee03a83f80f18f2348d7418c031b3ae95c113612d6c677171e0386c7daf2221d65bde69f9fa83202d375d61873ac8cc21f3ecf29d660ea1865f395b9cb0f27f49e966ffb82f49cb0e3f0302d5a7bb83a75c4a77e8a9d5342bb4bf848420cb9a6c76d434163b72b38552de25f557e448639987e3ca75a754a483842a222e52583ee98f037f4332386a4164e68435b0d88a0b2166f79097e7ab7144559082a8a791a92260107f4f03be6d34f3a03404a975d6662aa5626cf0a60d70067f0d9371ba131cc39e690ec5e01c9957b16df01af530c10521d50f65af749b583c28d03b2bc01ab50a704e42557db35e0946a43f8f531c3e7cd8d4cdbcd1860736bc05e772a06f6d0181f09816320292663d64317c11cfe7c218ba84dfac7bf0b7c90aa11e2bcb9ab5dcf3f9b68a7d89b4a05487e2c693262614bdb3f2fbe077f74d9156e41f440e1c47e7654b4418a010051f24c656a04f97982863df80490d792f616f6f64e5eb410455826ff219cd9c027a47035f6de72aaa6147cc1703472f9ba47c4d174d065d829fc8cc45661a756f18127d22582dffa6ab62ff061b9f43d2d438ed2c66270b03d762f8c84fa34757c804dc3cd99c14e7144cb3a19298a34d12a5a7422f5410b19162d903b91347319b492aaa033ba5c78b1d28bf80faa4e5c04869f3588cda644ab5281d115dcce1f5d24dc94f1f23910ff5bf26e8f40eed79bf62dead3076e63ac57df3c84155d47a2dd521027d29a3e66a5e6dd4cee9633fde87b274fa92f120a45aee9c881302ca101a851932c2972afb463a9c219b57926a0f882b51d10bcb37bc037304284fd8de7d2149412a337330ff1fd1de5d8a6e7c99f1690087ea1f438606688e1fd950fee4e9aa39b2385e07b88dd61e391d180c8fc50a01c592eca735b1534815a1e7f532baf767df2e92e3f219dfc5088976578e45d3736cee54ab1f1e790165cea85db28c20189f8af861e8a7eb1ab6346094c7c191c8740657158b1ebfa518abe93558499c92832c7d88245fb0e967356b2aa17751d319d3d1488ca168d90ce513b0b8589de3974fb7e80cef2e94108b0d13a3378c5b00018d861aa18c6abd622315304516729975401ee180e76ab6198e4938a8c584ba1a9a130a93f8bf825823978fd00f412283ee1ed92e9d66df414b4b6ddf901c9e54251474ede014446f39d43416e6c641b3b9496b0254db7ee3be68758f8ee6bbe167aded4494203efe5c643830f3ba90b6ec2c0b4ab1e1e6ed9a86ee3856d68df0a6a71de562a2d94a15520f7901518fd94845a43d6c7d3f02f3df1a6746574b82921483b13a7767d140523879391f932d7d002c5da226cc16d70c1034e74802d98f09a6b4683163535740405777291cda45f90b7e1e58e0edac2cc9b619004882bfed140f676343c9f06abf7f98c524a796a7a8151fcee9019b9c1ea08ceae316864a40cb34fe32220ee80d85451bacf1c28316ae357094169f9b39fe8f39f3c87901a16f0042cfb262a92ea94284af427aa4d3be7c27cac90f31393ba887848986156b53cad0081593d53550ae9f58fb10602fc7d61493302ae400df3067ee52b1f8b25350072542ea000c8db73a11ea38a1deafa5076d2809dd352662e39e10a0f51f6b418b52bedde274118f9829894e55705ca3457ab448966aa02fb57bf945dacbf2fc092d8508d08c28090fe801df3c66af31f95c52e52164b887e852707118cfd2dd009cded43880c96f5f3d182fef1401d5bb4c76bfaf0220000593610954171efea13a1786ebf0122f62c0e804ec963a1e4c48f823eb80d616458f0b6cc7435a964879677d2ae479e4ddcf4a59902c73d16efe075a0be1ebfe4aef1ab938c664aaf5423459a38d7efa4714c4d579812c6a0b4d8fd8ea5316d395c2ff0d2458c56812c63b395bd826c60fe52447c0907d21c3b6b4c7e9870e240abc74e37ff2af7474264188b5a4d11834189c62992199ab919ae0a3fb983334ee683090db3487a7338984236d6513887d8d21f3b77b46cda14ecdbe3b65689340438860e69c0ea700850e842417c8dbf064829b5476f2ce38e9a3e408ab44921c65fd61bf6dd414f73471c5b700c9bee454c16abd25192bfe90533b50b2d56ad56e571aa729c134117570bcede52643faf0e8f3d9171561b97a7c6fef46ebd1ba062a3bccace3f4521a1028d778e45e845ccff299c6009595631590d64b9d5faf4f7ee242c4f46b915be643b81c02fae4d204ece1e8ce37f9d3771f0fbb1b2f4c3cc24b638a4c3370ccb18ffcaf91fc0a73b36261b4eb94c6f09a4f0e0c6c04de44519621a5cd1522d916b1def018cd099410dfa1d0ab50367224ee333751fa45c723b7915cf1376fb61c2dafd6765522baf389866379f54402abae5cc7149d947261021d12ed3b18326dce369acfe66747e1574282f6d77101d2e611436292bea9fa8578593048dd89731e9050c0074024f6691ed1eca0f25e951f251b3d095c0fe5b28a619d8002d90951b4122450cbcaa1c4f6adb557030262e3078860a993f6f8818cf4b879b014ab16a9b021bd3339065079c4021821d7e4bb5f3fd5566675da87df1a19f6c877c573394a555e433b56b93a7a47ec2a8136c58f3218543aff95a00244ab5304eaed56a48f206d83e5c60e1c2cd2b74cda40f1a73477efd390cf4c46a6053accece24df184646eb9f16f40092f3f1139e7291829007b8d39fc69077025c0e7ca6352fa97504051ebdbc213d483da383aa8690e3d6a2e9fa963614f231b66a352abad60d3621e49a830d367dfc4b22f6c609413afa93ac4254097490d0afa40dc04e5e1a5409fb0e9ff496e54da1f2a4be862ed9f3095f66dc231204180ba7f9a532e865b5011a6b3c24ac0c1e6eee85b984d0ce1a6a947144be0c507a6f481d06c641cad01ceab5e46c9bf7e1c191a772d7a9cb23dd48cdbdd8beaa03865aea382f444f59c070bac245e20b29e50528b7409a9083a046810eff6603b6d86cf878bac417d5409f6de717578ed0d05c9141e9b98391034e1291bedf676381fa0c1932b8de9b397c9ca03af076d477630250b6dca7e6297f0dff5c3fcdc075fd3b7cc3cac0fccd4412c59f5c4651ea07825bff76cd7326a0b65c645abc3a3ca80fc8e73913a4943beb17f09793df7774a123dae53441b6331651604015920a9f8151ebc4802c809a2a4b0f1a624e95831714f97081dedcc6619bb526b47fd0dd29d86b4a0e19b68563ef985193d21b269c177e682d2d681ce7c0a1c09fa8686182e25a1a6a9b5fa9208f229400e413ae66ceb8fa1294cc1100f3dfe34c79e2f1f0b0d9e0a0e7fd48f00841cd77a2f88d326d7e630e33627b3b08e05a78bd96399ac23d33dd58d374f70d2d6a9022fb353c25ae17a27bfa36103d661e43f78593e8e9ba5d483d29cfd5558de661f6e65c38b7ae468abb95ec8d149b13ee144b25c75fbcaf98e11c43b4aa63cadebf069ce2a2383ad2b18f17239d969cac5db0d8a679fd3dc8c341c11dc2be3cafcdf59176c8dddd470f2bfed215e0b83ee119ec597a3291e5c0818c759b5dc559b7748ce85f5247c90d976312859507a447c233d8088a18a659e6ad8cd44516d1fb8e1209ea8b7ff3922ca1209c1e98b9520dde5e385990106612393cc5f6ed97da99ae8bd82cb104532c5f22c88c093919ddca11c4b89e9407024064a69d5a5aa24b1655c9f3082c394ac885703829b60e714a1161dece28a898e1a1a8d4aca42608b8c9f0865e0e62298111c414e5c7170c49801ac91a85ff0abfc6e68fb57d71d67343a7ea46def27cd9628b4b69ba8dc44f2748d94f6a4172f0175120d44c001a134364e388a5b43cc085a35e3f87d9488f1d1cd270d2efdbb329715b7167f01aa9eff8c9ae0302d0de9d9919c8dd72d91fb1e93f8ae9c9413f8b5ac5934ec24948807b2ce4556cbfa8ca4cd5f6360e2ee5c94af03c80a568fd787bec2e1a8840dc53ade4616c13f1727a0c589199b6fd26ecbde4be2f0b7a463e8dc46c5c92384b907b2fec851a78444f8f94762d452321482e514558e59eb5b0048a984cb18124219c75ffc90c6d3e7bf3df03d0d1cad0a318bdac9e6f91e8b3ed9203fbe41fd24c88ca349db98dc39d1fb8e514c51d6dc686eb20699854695b7f61789a60349a32d0f4b44e401b47dfb7d33a1125b76a4c99a1082083f92ad45030aeb85707a4c627dfa89d4de20e167591df5ca2415f23849e0ebf4b09745de52d671720faafb95937ddc81b0b3e84f371ae1efde1c390c3b04671a5d99a78babd864ecffe674dbd99602612e2512336a9283bf89811f34fa8111bdcfb1d1433b1205eb44f80f465815b991e97c03364a15c18bf289e1dc810a6c28aa54f7e705e3da4f02664adbfecf3b7f6290427391b8af4a3c5aca3a851677f707702f54b748859f0c19b800f858166b50883aa8bccd9a01af1650d0e5ab2f15dcc6beb19fd19b56657523a25a628cfe9d1d94ea0a6551f0b70e42bf671e3526f9ba9ec339bfe129a3c73b22309a42b5814847a33423db1db79b72d56c2880d7315c8539bf89bfad5fac09f3d45a50ed60f5bb98c79b92fd49e8bf402d88b716da1f121eb3c29c9a6c485d566c7d96e1c7b040e4bb5040aa603edd126050790c79fe4c60a3af768a20e1493557223d11bc3f8498a2736b5648a65c581195ea482acca7325c76dd3101e50209d45e102054b2c96c2c7b81f9c2020ced9385e8ad33d538ca7e1581f3069429434dd051fc32d821c1250d83bd8ceba3d6026ae06c07eafae0d583807e56a22a660b004c8b7327689d3564c2dc3d95138d5ff7db04b5f28989680aa7a043ce2a0e0c77ba4c785db758a7b74cc234686e581947f7d4a68983c3ee08983577be435902fa2a6050cac2466dc2709af91eca62b1ce2a902d1283dbf42089fe4a3f55978ab89e2a8e777e15002219cb0643c37064d03fc99e0c1e61e922493205b4aeab4dedaa368c7bb13c5ec3b034fbe1fad5b098a6e14445086d616664abb0898483351db72a669cef424a4514657dce42cf5c90cdab048397834b39993f7ab603c473624ed4c82daedef5f5ae45973e593249454086d4bee14b24ac7926bb204b114f39984fcff019f16979eac142674e33f804c254229354cba86099e8becef8b8d8a9857589ad5a8309aa81edc2bc5e4ca81c5603f276c767c1c89e6244bd1234cc1d3641ed6d71a130fb81f2627e7db06819fd412f28379333c98e0e0742f5befe931d6b430782815153e1d2efb87b148883848d710adeccdb54021b654525e664e5fa88d9c67635b6d24188c57f21a5060edfb9ad4b0410d34d92ac67e0e8b4e3bff30e80ee342a81e87c3d8a133f5a1a9c65ec2b0a819199074fd0525e9519c728be6813e16109e8b9c727f89a094d8bd2e452552d824c9ea9b904c4c89d064790f540041d050013c8a3506f98b6b1b255748db5b7e810e646765772aa64f7187867e96a70023e4ba27a4b720e8d91fb6beab03b2e22abba8b09e106342a5a2a4daa8921d3eb790f7ef920aacaa8b807237325464ca1bb6eb4ae18da74f8106fad4314730f6a35b90fdc44da7153669d8cf4f62a894ba534c01c2455b50c09fce080553c72f733f10383860e5f84a4505823f4c73ed7ec6609d3bb659b5c1d9b8729f76c1665400c375db7984c41e0b3348f4fc5f0d53cf0e3e063a0ee05b711612ba6f441a9a15b39d4ca21c84f8d8e30b3380d8999042793929ab5330039492e82400bc76236e95b951dbc3b53c83ba1da9dc462ea419701d233ec5ad80e85e26444afa2cc75c01ddc77fa55b83fae66efe60c1920b4588fdd2787b63cbcff466cda41ba0e6345eee7bd339e7a2f97033a32fc751d91b425337e06ea252b7d58da0355bc4b6308a0fbab58d857fdd700ab95adc58d981f00f3c60696e3b93648cac72e306cc317da3d054f791a22444c66b7675d70f24904298c9c27476d4cbbe8b8cfded36104086a6652feedfe7a9993ddff73b53595af076ea89754f03a76541fccab4b8c7dc2c8ed54c850fd42d5d0274016b0c19bb098a3449a195ef428e0ea3c8502521e9d0a79131b98b991821633644eb46fa2e14e88834f37edb132825179f5cfa8f42572b26daf33ca283bce9a4f87ac9936f3c22d5b1ad7da931c277b4e83f17fba0122313b1c9c39573def0d93a4515610b8609c0839f29dea19ebbf0b80e19ce8b65d7eaa20a9aa82db34e6f97b44425570ed1c596c428407dfdd78d9f7b6bf899962ecefb1445e07079ce3b137d91b08d2709a444431a9422b5cc92697eaf7bb33d01282d8366a52845a8efdd1322b43e7b07045e9e87a9e628e16b0de14d4ac034e9f7eeee7d52b028838cc6981c34245768960f9c4c7b570f210c3ab48eed8c8a3dc7064554f9702f2033fd3086c9a44e68f08f5a0d0eaa05a04a254fdae201901b666774fd7c76c3123cd485cc9f4bd965cc1e8ce9ce046d30c64527c53959a31da219ab0df420df447d14e94b409953ab35edd4275185a121a75cc14a1944133042330f4a7411847971cf99e72cf97a7d375a35ef2de7ca1fc89eba8be2a5a32a0e4da161852179792911909638cbcdeaabca801002e90116610ee063b006c2cff6f0c7e8266d16c6232c0bbd017e6da9b84201480b8620bdef727196d0a421b0fa5f8ea59a6a78b44096b211f3473b87ea2518506e45c8bbc9f9c00f12a211a91dc64b62f17fecf7e241118d1c40338fe663ac56fc606c5c5442b53cb8153a7a375d91041908274072301ef1358e123306166aaa7d988e0c5f2e4547fb38fe20ecb28b90c9a9b4ada8fd0af5eef5ae590c98e656d331cd33e2527821db124031e8d89bc05f78dd4ab4be49c8aa4421b98ec10945cf5b02b8eb566d9b21497e350a72a1865fdbe15b76bd6d2ec9d0b019d2dceb0744b96284807882473a7849b439903e34cbcae31c5bf483317467cd1088338498f9979f797ec73bdc0a794127d056134521f52ee7e3cf36a136befa962ef678381c752084ba1711534f46fa0f03c6578e3d91d365706585b256aea5093e2b5f506560057955eb9c5a1bd923c92c73ea64d7e5c5a7737a5fcb349c980cda0e5b0ce71b686b3b31a8fa1352821bd1f661a9b0d4e22f352b72913aaa0c720d814c72b9a6e7b8204268a4725f9b5df364f0359f8810204202477227a0eda29af728a9f7b2d52773a74b3024c2d9ed65a8c6437a331884bfa587eb4402296c8211c69c7b042f87d41c811ee87940f10be055434c695a57f23e323ef74937a7cc196008daa5c6ded3faa5f2759585bef3e0238a4ae6590d5dec8b6914faed49288a645ed458915e043fca3d3207873b39de402390836c00e1edd9e192792221ea52973bff89e348ec35306c1e94e2deb3e807e868d569c799ca6c005186b6c58aa57408b491a59e791f13180f9ddbe5a9007e9f17436294db0dfd8fa2dafee6f239592b7cea00150f32cc61a70240a93a37e28d40e340af8c130ede35cf4b51de6d89de21adf0da1068d41b8fa90ea7a4a44e4ab79b3acfd7c3210123b7ea259035c40ee1874e09287651392f7c46313a25f2f0afd672dbea0f25fbd87272c781521a70769df822c117eff6d54f5caaebb35b829d1932e045c583a538e5007b134179b3ec0374bca853b1d939917f0c1c343e4858c606f5f24c90cd90a3a8490f0850a26391e2073def52d2d302919ecbbcb1825710098da676098a7c6921ef819b788117d164dba80efa1074f440a5a53a6562d4053a60664f207f584b7ed3923ab5e77c851915857dd1b08f25f0480bb881cdf82a3c77013840972de9e90986ac84d8c736c0873653a7b00a4e1f7f37bd44b2a2182462e4c0ecdf94884707cc147095b7efe459af66cf3670570d15f3c92d0692ffc006aac07673bea17b03cf546068a7fefd670854cb76a297d5e1ea91130c380fe554bbc1864781a8b708f06d3fb8b9338a348e7aa138ec93a46e060ea094d77e26fe14b2d36e762c3939cb3090789f0db637bacb8a684e1f080dbc55958f0d809ed06cb7411369ba63ea707d2160db16106eb654b3f3f2a0260c89e8656a352fc6b81844539e0125c2b31b91466f676146676c77eeb1d8696471a32ac0e56443c74043000333240857b5985d0ccac80b0260eb495cb647ddfb1cbc583a3b72753e5e27cc00be26d96d5a5c34b42b66c06406b512ccfe3dfe807b13a8013652f563b289ac69e20910a83ff48f5d2578f5f008160ae143f835033ccadd6322344b256dbb3d998cb66de9867f5143ca7674c2c051c0636278f60640c8e8eed09ce5192d064d050d3a62141865548abb21f88c809ea9b2f61436bf1f61705e84bd533218d36438c9b1550f87e5b75ed637346d5739b068425235cdcc6628843db629d0f30a412d93615e101824f2026912fe00c24a298cefbc0c2073edcd184de8f4251ba1c1ec3be78a7f789b7b93d8ffb2700510b6bf670cffe1c308512318cbd5002dcaa20a8918b0b6640adb69bd0615dbca0d4295705f51421ab90a3f072537716f2a26b1913198a958950ffd66163f9025b334ed980fe9a95830d8e263b75f10f17818b88d076ad3c947c83bd54d914ce9e58f10fddfbe0a4d78c6ebc0504bf68b3cbf471976ce5b734f425faf6a66079165f0a18340415d86d2ba3182528730f215f0f01ae309ad32fc9546a1a675e6920127b0165c383621a8942532524286db16c0d4a1fb2396a573a2e90799584610361d44d7c36a4a2e10465563f3d811c78a25422967db652d031dfe463bcaafaf30dbb4af4174b22d9343674bf079a98d4f53e08b54e4e4cf1dbfe64553eadf540db17c3b661ea0d13791f3140862d0aeb20ce9c4e86681bc3a3a27cc372d193126611e7f3856ec86dd031bc740e0e64068a06fe5004604e44268e1e3a2c8966f47aa9f6781a3cca431df26bcecd067c6de3da358f1d995c1671928643da15b070c20ae7e1e81bfd05da631eeb0dc10ea642ab7579633e6d8d014121e8d7c29b6495e7b28580a0ce4e232db5e9a41a7101e653cf30f2248f9907b4918a8f171b5ffc2b9cc023d4cdb6e962538d5b1bc7e1c4ea8705b271872bd77c2a46d44e8129e3ba85b79f303d5ecacb03204405c2f150f8704023f926f42bda0e7cb40e53671511448b45f56608041cee4631118e3605bdbec6983d716a2dc7c5bb3aeca04121ea00d8c5a30bb0ea55896bde85c74cdb10bbc9a1c73920403c3850e17d9840e72ee698ad1eed4756c50417909b7fb67bfc6d6936c02de56c499f8bc7df44d0ce95ff8d757ec732f7f78f5fc7ab1d71dc31bd47972c272b6d8b7c7ce1ef7137020e36cc6e4aba3c620bbd9dddf6ce0eb9a6b44017d61386bcea558cca94071cc48386784f97011baf4912ccf02e7281f8ed5cb043f3298c2c49934e07fdb3fe7729b19689cb053f5d727e7da3ca272afc4cb94ef1d9348f5c93d2449fe0df7e7b098fd409bf5293e4eedea20fa8ae8c3b873bf4de3a99ccb65d4256c04b5ab4880dec17099260c326c38866da2a0a235b40065a24f2f8b04e781d54e4717390c46ed2024bd8440c27abf0f955d704a71efd1a87a1fca1986231cf41a3a998a35e8200c6e7d6d1a61c6d55c5a16a690c5ff45926b8de07ed52c4114b2b78d37a1ee43c38ffaa6c5c1f05ab1ee7b8700327668362843adc03cc4dbc706234c1c683bc79628d8106b6ee96e89a9da87c27e4bb0090a3bfa58aef7c696dc3d4189a468fa938879e8901306c57ac6a55fbb441714458d220ce1b5f8003c0542dee7caf5ab32be46605169ff81adeb1c1e4b0b68d133b7eab95a457a45f4dfece1f3f24cdfc7a4fc57b866064cba7b22f7935b7df69a47223b457451c50c3c147545af389dc49bd6776dc8d92fd885033926b0521371952ed88dea9e3193bc93e2246c854eebbd91fdcc2072eb42962b7f4b79ee1d1fef065b575c80694a6e24eb0ecd991d9e49e8eb64851826336a04f80415ea346397e15b87dd4301e3aed95f2e9934a34458323a830063e04be059872f92ec25c0e2a0dad7fb938f72e6c8cb008a390854fa22c9aa1f353e8f4f14f10e0f6538e41661159d780e9e55582ee85d543724e76d497ec0a216aa7e3eb561c0c1ae5ab06b78808236e67d4af7f94a229dda1b8ac94e5db55d19af0a902cccf66490bd1f61ba2b3762a1498c35d2f039cdb856b36d65ad672548a5719a113f607f6d88cfc24cd4c1bab30878a5fc4e3c4785d36b107cfdbcc310e75dd721affcfc0aa2a7d72350a9fceb479ba1b2de98c1a1b70f531b1f117d63714d567b8852cc26491045d878b61f00b68afdd7dab7e76e94adc974e5c6ae25d20c79ef7f87fd8afef470bc37f3a2da6b89ca82eda552ad0c14ceb39f4d572ee411aa1fb82dcb6fe8b3e886150eb6f0e3a5ba21437bfc7889cad695d48607e2a419c3f640041c2b2d9f6568969079f8309a32191f1772bd5113c6338a9dd3a87ae5659889a54a1f96ed2f0e663d01a171548aebce856c2eb8d68739980ba020b57bd211bef0cb5b8e2bba876611cb54937ba13ca1ea1529817874c91451b9d4477547657c63ea34bed596c859d0e13d97d301760465671a9bb327c2ee0ea57cab1fa00c4c276c84b47fbc6629159a7e1c7e5058d3a315a023eb41cf99920c630f30efd31df93442d71d131e0e5a93871fb9270192e79099ad526b42c3324a326e20c34c54e811fc576274a8d86544610e47775a7a720f091dd0e5f205a6e6704272b943cf3cfc3b3ee1338f00fe6e39d01ae1a98cf7affdf9e3174e5cc6c929603c2b7d5db9159f45fa88ba208b207de02c5f50f3e4c738375405d80adbc2eacd6e9a2d97a13d45993b9f270b0249941a80e63ad51e1df862679f658a3abd6cc7272644303c75a18390b8bd87692b36281d2b2462d744bc90ea23dff37a02e1bd690385a765813e424b7532d1fbd13200898c490319b52b8846a65100e8946672a9982e3cd591d6c98856d1550e12624edf94f152d9b5111c6d9b325761023ea9166b3f4849762c10937bef0bd3606c4263d768ad7480af7629a74070a24ca3a09724bda631a0c3c793388881cb5fb44bbd4e0efd0b7496986726b735eadd1b55f94197331c7f391e06beefa191700cb1b0f655a6806d46871a3f496190d775d21e56400f00e5011dccf136cbd8c4b594bcc8af09875f648c1f0f99ce88a0eeb981d84d0c00f59fb2a720f06f293b2a14404ef8f6b9318ea991757788bbdc83dc78ae26b1ac3ab5c080245de02d0c3b037be6336f5556b6bced527c88149f7e5c00bd3d757a6da3f7ba6538d2b4d072c64b7d61cda89d02b7cbda9b4edc202bf80fd56f23d96a3ca0979ac8d47eb16d8ee13832a7d0404e32b63ec10fff04d6382a2620985679d4d3996273e77267ea7a1fddddd8dc5f74c4b7db8ae8b543b5bd6d75845ee3a0b4a704d5b91d8b1d7dba32f2a67d57b3ddfd00f24888b29335650522d5a5d2c7f58ed4a60023487b521cb66d55bf0e7c3c3f08419252aa23c97f475e85ba15da103f70122ba0729866bdae9cf7b9e501f8e3037e2dfd82f465cc4458f00a5c93ad196c42333c434c3b98077eeb9ea659c58ae072d4a0229aafe2c08c5a522c17e09263e4217efda243cf2cf8ac2b297ae899ae3461eb9511f4ed127f6098e67d543d13d5ca433985ad3ba28489afe2ba394453bedc04acca0f86d3128f90080192a9e6e8d2eccc09fd2a53a859cce12fc36409a1633240c7b2a5d8e8eb0af9f8519cc2add28a71cdfe498ed3543e55c817dc626367d71f79768899660073444c97090ee70a19bab211a4d042e3d65059a0b3760d60bbe2dd1702ff426840953c36854e7ddd21538f9203712d8380096fd752917bc3c65efc6f5f8f132ec4c7fb7f869f2e8590991b7f47f94cb70cc0754862a275ae1b5904c1594221458e1d55b99d9c44d294d0771e243c60830af8e6b2af2baa02a1e3e08b0a9508580cc18a0d28ac0cd165bc27f9814890dcaeb8124e7d3a91b8d680ac6967461f06e7619274ab60de445c825a0c328519a9484c1075746219e851928d06124ba8690b3601342239043d7e118c9f08b125a60b43699c2d539d9385905c0be62a2f0370b06f6f187af4e6c6760e00106b9d185d79707d07931f377264c60294ed12efd0d09a01f06cadd6ffb6987572ceeddc63ac68bca230718ecf761f7277613817a48e15e79a3a7658f94b7616c672c1e3776e8b16b037dfbf5ce1cc049427deea3b4c6ab9009aa7adaf9de547168d45f57f3c2afb6365862b6ec7b12d85931d016958338013b98019a0584f60ee1a7e9f157230eb1c4cd47f5839ea290535659da7eac77de757152ff8b4552ff538d795c301b1cdac11873e923926627833e815b690f3c3e8982d0e762e432480cb08bcafad4ae8bfcef9ec8f3c2341ecdc8f08431b18c44bbcb281b145736f675e67cbff66e1457e747ad723daa8eb634dae6d2db24882d352c6e7a0bec0a6b49a8f2b05c79521652ac8711273b8468e4192ef2d5878440e4ce3c034935e2f6443e45b5d7996ad32c377371343437eb5e20b50fa1f1963e290c20cf50c0277430b26839f3eded0c5af037426fa388d2cdd97ae98199dea0e1271ced5798419485b1ed9aa89696dae5e0911a1b00452cfb6f8abf1ad4a068213f6ca0ec4be61319b014c3230be9a66b7bcf45bde382914ee882700d85fdb4acef782c160ab5de736d867869b8d701c7f8ca8a7d0457a2b6e0e568b4b11a8b30c1b37292315f710999cf5d4064def84ba3ef2f2c7d81886dde27dd808c10ca7bbe2c773dd156589adc9756f70086c27f63d35672f3f3dffe3cd7508fc2b350cefccde00fcbefbb5c49e4b0369ec3ef54fb4012796e9d05a92eed77d29ba1067c841e349b7114e8317c72506bce0544a1d6b3b1bec0bc9e2b2d90e45a3888dc9d947016be55dc5b8877854d987b89823a088f89b78e101afc611170c8fa36f4258fec20aec8db2ed77d8edc13553cbc643bc7bc68b49db7cb8d8a8d677c94502055d821aad71b8f14fe2227203f22663883f30f4542dfbe37aa43a95ba1815a905e10f37f55b4645a05456dfe45ecd0d094fc83021559cec5f23550abefe45f3898a908bc9642820b2e54df5d74c59b918efa307d645aba798aa91f88400c39fb02f278111cab160809d78e01a1cc208a68204c6bc019eb14e17680faa056435e57f16d835cb7fa35bd0366c4801cafac8e8eff519bfe4a26060dc81deae34264fd67c4787b87cc504100a79fa9727148f636dab40aa9024cb38b3759a351997e7f3c5adb8b1e0f470abfa0db91bdf954ad48d22a05ee350e58429260729a08e5777698e8956a70db43a101b18ce04d44def70fc119b8fde5c39472d305913b5203349f5dadd0f665d02ee7af2e67dd613fc08df83492da14458dc038a5b3c6faf55975e423e11c7fb4b6926c7bbc8472b5e04f64b470168ee96f7e08f0e7b74e8df5e0350fa0a3292208b49488d8d68b7bdf551c87881eb9c0a89d969071519d06fea73a177db110aaefe7f36a4455d28e3294b875163023315935e1e68c1edaaa86f7155f7cbb9370e10c1a5439551fc1a3a74a8dd496ee1fbc7a378fda9deb24797363e56930960ab80de8ac025dc88816ed9692bc0d41733b526f1f1f570f04c4c75ca73aa09a99b9e476952b753ac2e09a70e1b291306e825dd768a7b31e67cbbdc35e2e81cb0bf50f2c5b79d3200bab92eb09e2bd26b42fe7d4303e1ca84cb300e8b63e50e85c50f0b0c16b7d39906e7f31a0bf310a512e47cde6669567177b0a4ca54009b3d03961df959c7cac594d1bf9224d3fe3aec11c8cc929f5a5623417d3659f6c37fc63d0167d9b08070d83364fc540229f919318052a27e5afbe301906ea211c387ea614ec4cfc251b0587bcd0e2a5c944179366cbd2053f0b30d0be7705688760d1c9d40c31089593b9ec7b68c136a71f1d3139ee526d9c292f9b27f6ebd1d876b27b528f92db0e4155d945f8004590613a46f02d9af2c6795fb438334bb9bf5290a39286b75f8d69b06b2241832750d16090d396701028d12d75943f1b725db2b8b293cb211e2aa1b3f7b2fc16ba10e92a60080743d855ea5b29db47d179071e387d9d7e426d48711078d0a0ccb3fa56d90f74fef34ed4a3e4b00ea4f3d7d7848fb2125e7d44c66a554243aa098f5a79fb6012440c587c55784e398484d82d1699ab75890cd6f1079cdb32058e38c2412713359fb6e55f254ccb6c177a785ca9ec2055654428e5899f91067aaf0e8a3a794567a83bb97440eee349979923223756ab7e12f54ca5746b980152291a9690687080c40b8eecb0139d352ba19bd3425269ccd402a502655c8d8472bd7dc1416b92380f4715ac4d80ab9cd36d04b127681d07ffbb844760af10223f83b4e07cdb482c4fe0b730e2089615540136ab2fed88e4b60da8aa4ac518cf25e283f356de2e3a6f24677451f4570a902bfbf57fa695f6c2dfb0270473dd497e3c16a246de5bbf821c52d5b87691717d5e1d21b1abaa959fc88dd6a659bfd7fca5690250a15ae711055ee15d17ae795b8cd4cd42b9435491f07810200aae996d6572a926c923de2e5190b36ef027fca60b34207d8a5b5e11e36458e211063d9ce5a5599e1a4802db611a3d469ce2bd4d31894a3eb15249c69d4a68c9439b45def688562effd8e93bb5a705b3c03c78a4f08a8fa08678d1824e799570dccd0745d3acd97107c01120b5579231f96995da98c1472c9830769157198eb3d096699fb4be4e28a4945050ee045c77282156ba88538a6cbf7ffe08ec0c677fe0d60a476bad1d56ca8a4992c81c2a1b7adfcc3a31f7826c575b66a751847a6b8a0a53284816db436ed519cca39c43066d949b7802d4acde961ff0b3c4581b4140165879c2eb47472eeeed4c15bff3d90b5787103b84f3487aa55880156a12f24e0a90b57e7b3ff9a3f0b06841deab5c6426d1a01d2049447f73b260077d55c8a49ba1c06da139791d349cdbd73134d164a03f478116e315f7fa2015fd010ac171643934022ac2b80cbe4c6713c9beb131ef8176206e88829d7f04b0ca9636011d3e084f95b86928ab3d5d49af8480a6c79a56b8198a1c294bbd949175653635fe67d176539d1c15a337e8c7b47516e0ba537e76ec0bed29069fd264577ab3d30c246103c46b312313c7144965385b60a66a6e8e737eba71be55c6675957bd88326f8bb77ce23235b913dafc6e0fd032680e4be864c5fcd9c68d4eb384bf487bbf647e7cf3c4895b2553671bd638d603d8c04ffa20b36f93e1e223e89e8e692a5acc800518494275ed339f49cebe77e7838fdb78d2c3fbca957554c01998860a06244121d3441c5b2218c2e960ea90dfb25db9c9c0c5d7497a3a8048f00275f988665485e81e869ac18ce4fab01ac9e7b0fc0cf52bf5b25af8856821141638b4eab1a4e793457512d8b5f3262e7616a3ba813693620e31071c7dc2a0261ae45106bc48b3343e0deb43024407b8270c62648cede0b1547741b41daadc86e320f5e932fb66a68b442d6a8ab5833310476a5cd87faeeff83e66a33c312889741e37d3be9508720bfebb126dc1f581dc2afed9c4a883bc0f431224a3e4f02e8cc93ec5438b7c594ed32e672e29b6481889fcafbd546642e45e1092b0290bec9474b2a817731a7c26c09f2b0a7a81e7182f0c7940aa2e56e8c33615db325f91a178263a2487b7c95075d37ea048e069b1c3e17b27e8a1ad64d2314c0581b83476662aa5c983425f94ea8709502eb0cc624944c44027857878607eb5020736a87504d09099d85a20345449a27ee99281c54f09749aa7c504b4d15ab42206ed6d76215480d10db24fd7111fcaf07ab6811effff3d3d89610bebfb6a56ce0efb345db5152baa5ee7a421ab06a20eaedf48d7492e8c1012cc04eecb4133d3da26215cf6c158c3f700c35eb66d2b6e5b5a39821a08c3d3d578b220619fd5fa3806a2ae0a822c869bde02ef9bd4ffcfe1b6328ff427b49d8f851184fad4767b5e2191f4f865f7d90aaf520022a48e4a56ae1a3354aad6763bd04c82800341e6b1ed1976076886d2f12705c447b3ff12b25ea2b6aef356b9bd9ee09427360150276e4b26498daafee5433d25e22b8aec5d049349cc303b85476b02019ffde65788a472361fe5b5d909773c1eff581f65067b7e0d3c90ab1a8bd8eb8326abf8ef4a613623a327b1df2012035f1c19aff87c3595aaffd15f029346752d8125832261e04cc24640d7b29660b47a043eec334030b634c0b66b5ad27bbfac5b850b285a30e9c20e9083991e3890b20145e30fae0a609ee1415927a49d6d5c47f7a3f27c83d74d8c52e6dbb1fb99c85ae29c626d16bb1d816e5bae768e4de3687726c3fd5f220fede791ca51bcdd61a0736368381c9ffb938f20b1d369534ffd0b95ed197b9c28eafdcaf2193dcdd9a761c54fc2c2e81ebe12cac9d1fd905d42bbd560a0c57603351dcd5182a5172055b534d0018e8a7d750117d082190850030f91b2b1c1f9f93d2d11b7e58f2374f0cda1ff946c00c1d68e368ccdfb3dc9720e60db84194845e305aa7ed953c8e7ed82e5dec0e347bc7ca56d0b263c0d99f63b64dc92e42b337ac6c153a3b029cfd38675b54d92514ec2d1b6c152d3b02c8fe38b2add4ec22347b63cd5651b22340d99f23db4ec92e43b277ec6c153dec0860ec9f33dba2cc2e20b377966c15951d07cc7e39b36dd4ec123a7b67cd5651d95180ec87036c8b3aec0292bd67672bd1d931c0eccf39dba6cc2e21d95b56b602951d03cc7e1cb36d8aec022a7b6785ad46831d01ca7e1cd9366a76199abd65672ba8d93180ecc729dba6649721d97b56b60a9d1d030efb718c6da7661790d91b6bb68a921d0364ff9cd9566a76099abdb367aba8d93140f6cb916da1805d4087bdb1b2d5e8ec2860f6c7996d53679790d93b2b5b89ca8e00647f9cd91665760991bdb1c156a0c58e01643fced916557609cddeb3b395e8ec0860f6e3906d51659790ec2d3b5b81ca8e01663fce635b94b1cb90ec8d2d5b45cf8e01667f8e6c2b35bb00c9deb1b31551ceae83c81691b22170d99f33d83665ec02247b63cd5650b36300d99f23db4ecd2e42b377ec6c153d3b0698fd39b2ad94ec0204ec8d3d6c05951d07cc7e39b36dd4ec123a7b67cd5651d95180d70f52ca226407469f59de6716cb9aa54867d9af2f4ac97ea401afee9f6c5f3fdbb1cfee25b237b76c459d1d17c8fe3db36d8bec422a7b73c95654d951c1ecd733db620dbb948abd7167ab54d991a0ecef39dbb6cc2e25d95b77b642951d13cc7e9eb32debecc251af7bf7df451fd7af45aa745decd7f292e297c224182d7555d82cc8b18a16b3d68baca2cbac354556b165d65a39ab68396bad9455bccc5a5f66155d66ad15b38a16b2d64a59c58bb1d61761152d64ad95b28a1759eb8bace28bac756556f172d67a31ab7891b5b6c82ab2c85a5766152d66ad17b28a9660ad29c52a5ec85a2b67152d65ad9759c597596bcbaca2c5acb54256d152d67a91557499b5a6c82ab6cc5a2b67152dc75a5384556499b55ece2a5e7c59f7a2ac2b2b6be3924d10c93e7467ef8a661fb8b377a2b38f6e7dd5bfafc24563d3a8baeddc26db95cd4ab1bcf1682c685be57be0f9816be1f3e5667f51bda36566f2619082eb7407756e9134bf777ed059155460705fb44c03a2722a02013d07c04a3c5e23e5120d018917b524f5f29954773a7ae748b91c5669c235e76e1dc32af590568526962b8e779d27c9880ede083a8dde5fa9341a6125a9ca03669f22ec29054e6584800d5520a00d271d2d10bb8afd89d52efd47d7a2ce3b2494497fc6612d4fc85d5cac4c6cf39cb853904f23940b5800640180a84e490288005e554535f8f9d84e6e93f7c7dec43e0cb519a1bf19d94608216493bdf7967b07740d260d770df7bccf9dee0bbd661c4c35a9a2d148d6882afeac6732bd6f6fada08f8400778446a3d1475bc01d24ef93f474cbf612e44a3e2525877055e35ae8c64c595ec82132e4d0d5904394d505b862efd2a04bba1ac98df984e70999840a99e43c5ac824f8ab87e931e08a0dc9547361ffd1e16a54144f8c447dd69d744dc76e6d1c11491afd84fc8558ed85fc85581907e35df36eec4c0e391813db466090836c7a774f1848f364d323e7a38dc00007d934b38909b34c3774daed2d8558a1560eecc5475285cee081f6d25b164f3133c9492a119e42ae1ef6bc43b863545fafe5b81d62914ea3fe225bef42bc975ea2ddbb3087422c921e208d0353ba56bab123b15c64c182ac9160208de3437291c54cd6aecd2417cea1fb421e26a948325d44ffda41f79154b95be07d780f5741d9d50af2c9fe70cf46a6bc1d0f8cf6c6f0723c33ba2500ef7b345e0d00be102b887f931562853cd68a0949c5616baf699eb792a8f6a691ec796864ef9bab2cc4bf99933d9c65d1cd95f6001cdacbd8996ed2887a4a3c9dbdfd8855b239a51a89b22f29a12c1226dd209956327542d33264237412d221e9204c9d90804cab8f69357320ca76d88565580f8426968dbdc9f65f670fc405e22cd7300e868565a2916d8e3b81b8964a953de6b1bfc1639fc2d32d88b2b73fc19fe5f93a682ff157ea554eb63ffeac4eb647b961657b13fc954e68646aea407b13feec6c65fb1a2734b96fea91a9ae81287b9b6c9fe1cfde7438d9b264aa551065ed4cb6ff98589e493b8e956b253dad22e919d1e4c6f946acdc3d253425385f092bf771dccac104e05a006eec3caf622c94808cbc727b435f782b5828414e5eb916b7005c9b21b782439b0dcac16cd7b62dc6bb7400aecd2b369b5432655bf3e4df9c262d99ea562635b247f2c81dc9923a1f4925bb7fd244256548aa964c857ae76b9eee59754eeb34cbdb217910f8b300f0766a648ab2dae6eb9baf716aa8642aa369999e691a530d49455291543205a2197d582aef7a646a88f7432a19b2e9d0179db22f47eebfd94387e46fcb703a1610f8b33618dfdcc05b742abe84b8c8fd0e47a66c0afeaccc099e938606c492290ca7a3e9e34fee58c983a9644f8e4e8669583637208c83b17aa48c4c599b120d87bf6e06b37458b3f5c191a98c86a462c91465d194e06fc39141e1af84bfee11e10de707fc59fcf58e0ff8b3365ddf941a278a48a29b2f466694d83ed952f6ae853cfc75f6cef26d4f785260a13d74a588d1ab96a4228924176a71513d2b2ae12fb493bdc862e9e898c1c2b9c1b9f902e706e7e60b9c52b6b57ade674beec991131eef42b2e77938d463adb5f6e448d581d54e7a4a2eccf5e68b6cade759cfeae086fb701fd088fb5cee0362b1747474583a66806ebec0e13edc67886bc2872f45949494947025a5dbd2bd592a954a25a497dccf87748e2391b893483a12d55b3eb9b15c4949894b93bc7f7243f2121d0cdfe4beb6e5e894f15a45db6a1b236341675f2f6a6d60f4a949aad14925af556bed43dc7a85b8392e4eb788dea35109feba3c1a7d0821ee09cf090f87c69153b6a70010d135917611f7cf1d6d38df49fe369c6fcb1f4975bfbf06c7713958f5a0114486ab9e2664ef24273c245b9e62b46a3e92aa253444066308940d76262828d2c4242525072828282828282828120505e5c60d9414940bf30d198449c95dda4422fd7ecf7f4927aa27d986ec5fc386ec86b3e184425abd31f6b3179d723dec433cd9bb53c42cba68458334b216372f74612eadb6c0f94ab7f7eedd6e197248943049467463ec450f5d2a68f64844c2b0b9c9a24b529186f4a914aa9c0f912dd50aad195816e38685fa29d5507785ee0b55d143273c1ef6ded9eb1764edda7876b1c8cf41ba77698c83b9d7acd0d57b0f198951e860f6ac563d7b1bbf70d07df6daebbdbd66e3c6cedab81e0e22730f69860aae90af66efb57bc8c15c7caca7a788dbd9c8d4090f8d3de1b12995ba8ec6aeeccaae728744ffac2c613b0ab1acc8b664aa736830954cc19756e7b4725aa552d7498ca653590c27f755194eee632c99b2a552d7492b4352c9d6b08d6bb32d92e31efe4a3907eeba1d74435832151a432b0db9ff86dc0fb14824559f26199d4c5de1c58f1c2722c7af687911ef6f3a3275c51017826362880b71c82531c4f5c262299868c15ed817813bf96308113807a62c99822fad9d4c7972c728c4288efed997468739343ad139314323d55a5feb6b3dccb062ef7e5dd6a2163aefa592e8a18b06e442ad9aae8ef01712e1ead230e6939e6e69cff3fe9df01cd1a40065ed272cd13ffb139d3ef5898e1954ccac610857bcbb488fd5a7f65eef5dda22a9482a89f24ebaf48c3e35bd4167aa1792ab66ea21ba26c2a2211a16a92a0ef5789e57ab573daf564f24aa9e57bd4a92f1482aaa0ab162f66e2987585ee9a7104b878e3368ab5b62c6ac104bbbb1f36ec5413af700420b3ed80290920f20b4e0032d646b3fb3c5267b21d9d4a3defb17734cc59b91ad65f1c6ea1369c20e7a5ef42218d97bad276feb931762d980d5a71a7447bae53bd1c98d03c66a8c9c6e29bdbf95b1e96c666caced8cadb519e90d8d4ec1939e139e52092701b31c5db3f7a4e79ef0f4a94f7872ff84e7a4e784a75b46ef9f1ce916fbd879a35ba9674f4f744ecc3861750bb43848ccf69e06bd8b069d4b8758d0c80e1a39c4133a12ead9a1c9336b5ad4bc8b43de857df26eef2724db50e890ab580a99439fd05dda926e49f76aadb5d65aeb3d12f62eb90468b96212a95bd5da7a1759afc59f901cba4b5bab79f77a08f4791bb9aecfaf474993bf203918d962dae8f6d3def33e1c8ce7dd4586ac7763aed7d234668f3cd23c3157ec79af6f23b877fae4dda4776aed5cf2ea8d881882e4b05342bc96ee1181b11038c4ca8169ad27e110fe6c26cdd7e7b821fc852e7a8815646edb86bf100e3273e8db29c93ffa4d7412ef1fc54166c62e4a2246fbcc1e8ec1f01773e8de49fe954e82311c6466edf65f090799b9e434db108e29b977d19bf3e189a6e8253846d3ec4eaeef33441cf52e3dbaa0d7fb39e91ec9a19edcd65acfc39df5ec610e1909ed8458a134fad4aad289a6799ec554d01c63ef1d724878582412dda5a5e8a2eeb39f9f2291a669da356da41d664c6b2e634157bafde8cd25112ad9c86d875dd228fb926b720bb1642abe34160dd1e6b527b9a33ed98b6e6974ed150da917c98886f4a94b3ebaa133fa64ed0db1e4a7fb4ab9e4dbfdba5cc24a43251a2292e91693cffb0cd108983fb1eb9d1cb3e935b27f605ed5008dfc8570bae5db70c0d856dd82bd06677488a552e5b9032d441bec5034c82d71c203d50ebef0116396f923f97cd8bb6f574cbd48abb73e9b5e773024d77347c2e0c2480eb542a1334246b4bac17a49d7eee5c3bbc5a692db5753c9471795b49256fa574a994a300f984da1c794bcf450c94b2fc1253c1a7df47aeda3fb399145f61bddc6b5bad9eb95dce24f8a672a4c72e9f69addecf5eae8f5bba761d3081f40482e6153e931a36b2fcd3ed56b18f6c9bebee47ea3d738e594c05e3ae578c48cbd62ef28d7aec82120e64a3ae4101045f7d34ec259169d86835094571c83bd8463b8d7d1bd9f863dfcd5f825391f260ecf3e7df03b3cfbb4d9252c2639e49698c72293d87bd7bc4bc2f9f8ea3d4d922cf1d9d77b5866928d84e4f6358aace18f3e8844028b1cf3cd3e79241874faeca0935c10fe6226b9770f7f9e2733c9e9bddf1b246692c72033897b926b06dd67eac97d938f98b1e3ed119b7a986e6fbac55f96453be0c9416418c60ec68811fdd79aeb9165ec90f371f2dfa5a1e8cfa6ff1a64a28361706146fe45d7a02637c88d464ee46a4f4af7247ba5ecbdf4920bfb54c2a57fa36c439e776b43f8ebb27dc94917f6a9045fd8a76f94bdc34ee5784909fe6cf6f0c7bdbef41c1736aa843f9b2dfee66bbc5e1be7ee373fba54c48cbd1f391fa6ff90eb81fdf8131dfbfd44c73a8f3a723c6012a56bb7e4f67bf62eb90308c9a67acdbe6a5ef6ee379f523a56caa6fa18eff615672ce84c3dbcdb7b78f669bbc5db217e9fb6128e114d1c846611fe6bdc45dedbfdc29c723f3846ae711bf77322d7f88883a1b0954977e98eeb31ca27d87435c885f077454e0e3dc7b522bee478764deef76c72d2856d62b3c9619b1cb6cda5c34ed1d7fb354eae676c38a3d12dfe2c2bdadbfc594c85ccdff305beced9492a99ca9123478e1c3972bc043a5e72bc6d4b0ec652964c91549ee77516777df2ee7df625de6126f1ee43a4dd6a2ff9674f52f589348424a3fd23a9b2f6187b582f1b63c6c1681b07e385587d0a9d517243466e682784469ffade0df170a1569f7ae00a153a56e88c4e752ffd104fa807ee80b91f3212da91a9a852813818cdc3b1b3aaacc18ea421dd62df07713e44982473caea16fb8f34a44f7d922a76d67ab31792542499be0663769126b7c64917e6ec6291737cb67447f70b19c9fdd0056271109a258c1492d5d069dab1db0bc5b5ca31da314cfb3c43f75d3d578f4c6d93f694489e776b6dc9a5b3ef224023369cf7177047c9ed73dce20f48e3b8e8b864a0e3881cb773dc98a38bfc6d243374de4bdf3ee7bee1c814a51bce86b3e114c971966e11e12f66d181344f163d744d74594e349d2809d15dfadd321abd9b26835eea539ff4a93fba6efa644fbad7177db2f7ee85d327fb927b810157ec4cb6ff288b672707a63296ca64fb2fc4bad7471766926bb368e6fa6d49007d2116eb7bfe369c0d27f7f5ec86ceb038d4c2219691ee0be5641d2ea5a3e0e8788618eced9503b22553a3f755342e3a74347171457ea824d763747a9123a18bffde124b9597e767b1faae265bbf80e37ed0d512bad817185d349d6c50a642a522b2065dcf3be48faee8d4b4782d0a07233b7a1b1cccbc32064f188672e79a3652523898396bab7a48e88ade3240b6966955ab7a48e89aa834d2a86e550f69195128b46d299cfd6cbc349f83913a3db287147f4058514709dd94343736d8c9dfe060a2197deaaf24a34e9f3a723da4552d678dacd04553242714a53ccff5bc57e2cef416097d66795211ba0d51f337a254e1602496ad1ee81baecc9b503e98662fad526d6ab223131f6a791090050daa78410f332d6e9914320f7958e91821aa9e5e26a286431a08d1a852a95428ac03b3d2acd61e34cb6bd746af4901dbb537b1e126e0b315c4c09d2ce445c84bcf4b11f390afec0ec9dedd21daebfd62a6452705ecc94124843990907d3516597ede6f0e91af6b50c2861046ee6371d6d7a70862738438ea839472ad564cba65d78569116e82f0850be44dbcaaec46a3f80449a5a4316a8fb964fb1c74782e43ed8e20250f79c8431ef2f032a4047f01bdbb8cd095ae4fd77d40f0cadcf97341576e46e8e68883f1a2cd1a49cb5916dd5ce5e8b0aaa08902e7c6a666e607945a6729c53015951c1d566b15058b4e4f8dcd0d0e4d9d3637384dd4542153209a191995852db8c312b19c950e4a4faea2627383b3aaf921519185a59299a1a902a38f3832f5791fae68a2e8c7199902752fddd474775f4675f579c47e1050e7eb01a2e4c6302232ecd3e9c697a691a99c1a56dfe0745ffc4aaeace17ec419898af56a2444e4ac05015311a2e24b3262a13c7fe1a0abb19d64ea845d9b0a96617710bb2d45955342c8369a304bdb6768332216b8e2d1341147870eafe3ba95e638a4047f8130c7372a826606b9a7cc4372891266d436747d46ec9863c9b5a2eeeaa0a6ad5f90832de04a97c01df5f05e3402bb7e5953922910bdd8b4f9cad37b65137aecda8df7e2e195d7301079c95b33cda05b92a86c2fcb2d812bf1989741b765d6aeed2451b22697ee28d3442322c411df398027b266f8cb085d87b2419a73e468b2666393975eabdbb77aaf4bc9c9fb05c99adc3e120793812e29b14bef28d25f9ca4e7e85fcad8b5c92c8bcde360361c3b4dd3469c56d26d2e32bbd45e1107133b7961faf891f49fac4d10a5a2aef6b0c96da32422bbcdd830fbacac90ad89b042771616d7894b7deaf9abc4d8dda212638c76ce49bb5bf1b37b76b3c420644f6b2db67d1a453837888a2cd716624bff8ba737e2284f7105ba518659ce976e4a41d6e41e38e79c73ce09696c9a29a00aed78c894095e3bbcb6dd622bae6f9f3fc9140f899a9fa5863c640ac2a86a414e76270fb8e3eae40f99e23eef844c619f737e70470ced42b433916113bc65c2a4007bed268899b0d74c4c60bf8efdfaa56917be5c3242f931c10789d9d4978ff99ae0aff022fe8aecdbaff04262263ed77ec506b1a93113d9a144d5978899d0fef9151f6c8298479fe6e18b06bf1dbe64dfce804cfb15a0671bbe82fb3a98f3e3025dee566c17f2a271d704794cf09f0b79e931416c52c076ee4c6ce70e216682e3f00f2851425e84bcf0b84ed02501f31425b8d20fc195787becdbb9438dbbd06ed7c4044b274bf318bcf049a260e71bd9960d1a88e7073230def8c08cb84553c448748eef78720e0ca30765e4196b8ce082d90333f2647df18c08bb616cf941f1442db8c8f3516646191444cde7b073da909173059d2ee409c7904f7065da3ca184b23b1e6c0b0d769a16b7d92d19f6fe322dc3f097bd6e778a0857ea83cc4c6f4c76fa4969959722e641fbbaec70beb7ccd4e3c3346c9e1e0a0e66c2d46717db2c4763a553b27441b3872a596787d9e11b3bb704f60c338246be198a518634324f16224331ce00468e44ba192dba8566460c34a8729f66af1a8663b263cfbe7d401dc8457659f6ed7eae14326797bfaea9c775f84bd3b65ab76b90def8281f2f7cd777cdb81e9daf7f10cb0e774078b15f173bbd31d9e5eb8dc90e13803dfb763fd04197d73408afa4f7a3df28e66477aebf62e38f5e1eae40fc51993f77692a85cc580c76983f97bb525891b16f37e64a21e1ad09e21ed833c8f528e52feb8c7230198ec1dea71c12b30786df3886eb41f1270f89d8d34ffbbeb516c7d4cf1c437f61fb554c85cc17e87f33cbc7c4533c6bb234ecbb992351f0d2e606a746b3f2d7f54bc269a44ff0d77561b34e3aed754d99393369a62a9bf6bae02b4f86a7f0b30551f0393aac95b5b9c1a9812878f9c94f7c556be13128254d49aae8ad66ad85c7e0696b5a5ae575c157780a6f57f2baaeeb9a2cdb4d9d869dbce29c73c26395d6448b49cec0c58f3258ba659e896e8979be89531033ceeee69090ad7554096a7f59ec3a5c918f39ddf3499fe41fb5d0c5c33ecdedd6e66c4dd7bdcc7961386b9c41a88787dce14a8c57bc2a17761b510e669e767773f397f371dda5af0baed47ab1478ddbb44ce5d41d2769abd7755d25cc47a6695aa63dd3b26b9af6f9a7699996711f0e947290528ef67e59e778af1b9385a10399fc0cc3c8c14e96d995d1faa89570f3daa589ba6b8998f89176bdbee251c6f9a8b5661b10a23a80907c1dc22028e72326e2d1b70454dc5dd7b5639c8ffaebaa358335b611377d5c8f11421921d4542e1c131fe18a7d9099215cb160e49863ee22c30c73bc5e7f5dd3fef93ddd73879f1e07a372fac8f9d9a6edf2a2fb6c2ef1a211f37ded212e0118867de2ae2eba18ecff9cc39c0fee9fcf6ef9602dde0e460e8f32eca1236b37e160b4e3a4a1d1c95dd7248784a9c785688f5f123047517f1d8a5a2fcddea5b36b285be4aea3703036c31b5c893fe9138c95bb9f88e36446ca7b5d2e0dfb4467e3741c43839f69881df3bc56d04030337f30afb85fa3a18b9f3dd70fbaf824f8c0075b374f6fe763e8e96bc7bbc525223ea24f5c0f8ae144e207a58fdf498c116f7d6a3a7bcb7d927b364a1e02383c26feac4b8db40db36b0077c81f91919999e9cea2b3c8c961b1605c6da5128ba5a3939363637373838393c69123b476e569f5c43bc01d74678787a7a7870d6cd0a1430e70253edac854ac89aaed9f95f12b99da70d7c4cf7ef6b339dae4cf7e36479c9d1d1e1ee82251f16318438690c5b2cdc2a2c34695b53a3e9653af72a478762b948346d6decdee5d0d038748d6def1f60869647b4eceb98566370ddbb6777fdc2a127d0d94ede5eed5836ef3116f3fb91edc6924a3dbde713e6877cddefb755c12db291ef5693bbda6452e09d02da6f7bb4b536e897ec592220182cfdb866314ba10127ded9ffb451ffdee9f77d7d4a37b7df72a04c2156a3ff72b997ad06bff5cbb8becae76d0fd80fc73b5b945323afbc91daed8c79c0e3b5d365dfdfcd68d4af2a4f672114ef12c459783cc6c714cbffbdaeb8d51e83acb0bb11bc9e8ac8febf6137ef69a952779c96f8be7a226031963ecd8514a29a5eccf0ba4f42ff419220e7af9beb48de4ee16bdddea9d36689089ecf2516eddb21dbe839fd3da18f9aca58361e094917307c3c039236bcf1eb925347cc425d7434a956e51e993d6274a293dbd628c9fd12ea16197b436e8e2a71434a822e3657777b76c2f0499bdd346bad567e89dde992ce0c12a0720c33078309335503dbddf9bb39dc2b0cf6ec98e819cc8d7855dd8853d66b7c7e841ddb7ebdd858dbaf00773183b80906cda1ea33dfba63dc39ee1d9a7eb4ee4ebb6bae40f3e08cd9f90dc9746702c0ecfe4699aa649237fb6c84c183360e4cf7e33cbc33078d0ca726280e52adda223f74fb68bdcdff2b74195a6c2092320b2e9d8441bfa5959604a2ba9c88cb28cfc01214e4b6b755aabc876a9b572dcba71ada9365d44ccc00d32959a293bcc58e3843a988778512b177493b87e5d6be8ad365fade9c7505c6dfa748a8d3fed7206ddf5af562eaa8d8c797ecb72cacac57731301a159f558ae14c555771b5a95709e4d5deda6de3eb525eff6606b2cd0cb90b9b64d6f5dd6cb49191290c091015ef044b468ec7ae10e18b95c170e0ca3cc2e9c60939eb389b751cfe602fbeda94c69b19192d6ab62eba053a41045c7c446c51256e36db4d8edbcbb7e1e4782adb86c8cd0c8e1632c8f1b16790e3e3d734c8f1f1eb2dbee602fd82ba21c7db325ad52d1f6602cc0443e4186d221863a8984144fea28d1134e2111ac419944aa7d249536932180e66136fcbe896cff25837e8e09103fbf45d33f9a2a9355545bfe8968fe6502e6c71c34d707f02b2a09117f8b2fd833b0ce0ce6193ac79b1c95226478962e5f8dea25bba86065558017b664055bdea956a888a6238119301dcd18f467211ee907b806c71571579b080465ebc883c2a556e6c8a324464aec58c16339d3de5f09056490ca7df33345b449adc628a35918b9a5a2353d8c435734a0c67c3184e8e9b8ed698a68335d0faf09a4b9f68df44e984104208218410c2d9101e423880214ec88d213c4503540c65097432e458fa044f10de42d8d009d911b6e28d09b8b0f6d6a2cce4bee4a2b3f5ad69720eddb7e118a1fb42add0197dfa84587025b40a3901b6d4382cc1c81948aa55c93f5b1addc35fbde85abd241992aa7e84bf92777b8e24632d1691547047e32962fe422c24bc333afb215e782fc15f72586b4ba5104be3602c8eddb377698e4b5b5d044915a1d07d1bceaf22dd1533d9063fd45b44742aa297a2db10457fe27a5cf5c633502cf92fb280a8cff392feb8567aa9ba6e2204d775c1dad79c17965db48879554ae77cd9e62624cf392ba574ce59a9181a54f96a8b47a6a40e9a47a67a2e5532a55d5eca6c9737f9c07dca2e2d61108da04088385e0077c817484cbde04217552c55bd014d07b7d0c993d203b86b180b1303e28bf6f8a26199ed85bbcc7c19b23dbbf1a53926e60b874b3002d08bf67e8136db6d00cc51df1ccc9571a107793200e6a8d8bf7a832de47ae9833c7fbdcad8925c6372bf404e894b0a98877c09b926575bd5069ddc66a7865c2fe4af18f94a7f3322f3958399f065dec69636695f13aecc3afb3469a573ce19734723d4db7aa983aec2ae62b55659b7570c44d6d87a05bb491c0de35c56e2e4927cd9b094d142d776ebea256b5a092740a3654d9e7d9259e82486af3a330f549bd3ce69edb4765a3ba79d17d60d42083a2cedb0208470044fa04afec1023708ba411a35abf89c03fddbf2dcfec93ce7233462fbc41f90511551e474f21fe4092233e80e89325d04e8dc8d43faf4c9324d8b9f3b0515a5bc5d0a2c54f9739519dd3c05c176233c5ddfb81e34db6bdce43a428ee324f6c93ef39ccf2eb478f6695e9c0f4b5f459c13bb3c862714a33c2d07fb3fa0ce74c9f472ce39e9f1b459e8e4bbae9b18c719aeb7190d72c1ca7d638a588a98e390317600466e1ca43b21311e40cb508c31d440956f94618c36f667a79451d8d86a61c148feb66c64a7d5a7be42e7008c2f58d093bfaa0a83053cf105aac4186dba4719bb86dd6f66ac3f2bb9f85591e3bfeb2e12764ddbf489a4137543622b056964c802af17e4ac8e5c5ae48431f34595a9443a055fb4d8227f35a78b884d24f7e94aa79b2248976916aed07591bfae69011714bbdf88d25aafcb6e9283b1934b82c2d812c2be284937c40bda5595eb9029d373d3ea2603bb0e11751c06eb6cfaa1776951c75dcb62cce69c1a9744dc367a3b5f577771494078fae069bbc6655cc6828ebe4f5c1232d36b1f185bce0f3dc5107fd8ed3bf6905e114141c6624d0d07a3bdb924e2b5539d6e89b86d684eb76838daf4a905dd95457755eeadc371e7b015dcf3078485bc54154dfca68909aead4435fc844c48c0306a8e981800fa9818d03df4107cb9de413ac2c71b03b1a9c796e3b71c1f610c864d3d2286a9e81c030fc3a83992e3e396e18561d48c91e38d62cbd7bbdb81ae89011f10e49ae83131017ae8216c050853d60743896aa2e3a12daa2351cde149a4bb86745fd7d43401b8b74dd7c1cd45c20b85acc931f1f51ac41094a90e5ce95f23e866648a7b7ca661355c76efd7657aed7ea54c29fe28cd76a316b10c9efc3db7a0a7aa620b78aa4a8356b432adb953d8274191a01962a869197e418e304318fa2824438a81c89a3c71a4c171a64f5d87d4f4c0460848e8ee9a2a53557dfa84a894e853dba1fb9e4de0bfae699b6ee92d72cf8148ec2e86d0c52c8b0ef6744d15baef4fddd4552a446b1b6ad0a08a01900046d6e2a559664d6ef176d6e61681e8a01870a0c9508c376c9189c8500c9e9d4aa76c58495d7771e4a65be018296019000938dd1271862a306e411b5282bfc8cf17d145f4e510861c72725f65745158da17a574d6d059f3412e2030dd2021109b70e226522cfb924127e54d8d02e4cb85271b66d3c6693905aa737d61f24c1e6c66953deed8cf6923636f26ceccacb135b634551d4fa9d5b16a74eccd5755526686a62d8faaa6a666eac014851d7c367766697553aae968e4ccd7449e2d27ad97c5326de3b60f075321e7e3cad785c9606c08a6c254f30b88a260643a46963d5aadd6fc2253109491ad56abd5d40204686035b6c6d6d89a23449648c9d7adcaaaac4a9a6145174ba4e45955d28a327ab42acfd3166dd1567f51065dcdb95aada21658a0316b680dada1354788509939a98c0c34a38b9e3b7367ee64b87289f333272727e74e1c9b118540832a1fe826c74f233b138d6eb92e3fe7919e34b84b7c8dc70f25cca0ac8906eda943b29c4a84b2280f4da3cad4992ca75b3e964ca75b3ed8cacac8726c6ec945d793524a6976c8c1489a035bb48c9865da37ee1b9e3c599ed29c6c2551d348064614a8945a37a59c53c3a61ed9e5b3c9932100955084fba46534aaaf511dfa0c7b96e5e4284f75684e0c3af98fe6e432b07bb521e2883761653933537cb1610d39b48c6ea18fa73a514a6a693204946057d9187d8aac0c8c2b0a4dc894123a74e450569413b340371babeae448779e88c28aa885e4c9317651c6d892a75bbe538f3c2279ae22dd0759bd65d1091bc91053922551f1d71bcb8ba69392351f53305afc7df2275939be0b4874beb074820c23c7a61c0c95fdd9dd3c32c5f2847c62b55375ac0cdcc1d0283204b8a36997b5853b06698454de5a7aeece3e510cbb862b06b2cd27806c42b4d851204282411a1110e890ebb01432832e90264344ebbaaeb90468b9c3ddedba18bb4717d9dd78c8c17c5c3a460d7431fc4592eb518684e491e4918321d1eaf6cd10c9bd9a83d130e8f376cf9accaea8e36e11d235c9dd102e423a07f3b9b7bde492dedd89bf8d43627bc445bc67b84809cbfc858461a3b6fbe9b6527ce872875c12a12c6341277afc364242f40c17f1b0cc5f4a8a94e0d9a839badd47772b5272d12d22f39792124ca335730b49d35a68339a8623913e7d9148065debaefd9b3848e74944c3df7619baf6d1157db4652d742d8b6ec340b6bc917c8465f799371c43b2c97f40b6497314e198f9cdc7060a81be7de298ae8b1bfe2291ac69ff5c74ce0bc59663dedc86619f3624e44bee102fb897e02f5e648f1ccca6dd2bbb305f17497f5a971830bebbd923deda6724c746c74826f75e52a3035deb6e77d00d752f1d791d4e54b62039839c8fd041d8c471fffcb339136113677a8ce8dc4da27317719fcfbb67ff741f0d44458a855c0fed5db7e55028c3a60f3e8090cc6113f798ec9f73d93f20d827d041ef1eea2ebadfe7d0e499c9b52e74d9ddadebeea66d09307987634c9ee198d2bb0331c1b04fa487f00764cba5c3d7b892f3117b94f0ec13097fbec39f87679f4a40d8e8d808031d0bbdc330d043ef46d827863d34bfd9a78e04937c921cbb24f88bb97b87bfaeeb7edd2031079919bbc4e84c3e62e8201c9361538f08ca62b2db90cd6ee3ad7d06ba5f900c1281fe3907bb4375db41968a98430f3d748bbfeca1c81d4008d7598b5be85ae87221ee9f2b3ae86a9fc780aefd03ba76d0bbce5de7e6ba83ba830e1a7df08663b2470d03d97286ede15d24acf77b900c2f39980964cb54c41c5f92e34dfa3344c397289caf30e8757a39a1ab06e8d37cbd52de8a5c2bfeae05744918a04f44d8da652d6e3ea24bb7d0772db1d34bec12d1288959d42025a5a552a7b4d32bc37a3e41832adf8c95a7fba08e1976084bc75d2b51f465eb664b0675a6982c6bbb4efebbc453cc53db48331ad52fad3a9cc88aacc8d299746b0e46eac89d6e21d22d57cb9b9aee9daed380b946a6e49146f5a58ee459759dd41142a656c8029ee8230b327543968fd8c491085ca18f390b2ce29083c5912cdb06a221440b1e930af922cbd9dd4da784109e326de24e78a26f5b05d7c58b95a9095f640d625340eb439586976d0388bb067025091d6c193b5052f92c5d4dca22e549d2ec589eae45cd00af63369306e0d1a9d0e17f3c015f459c8934353245aa7168722821849275b1244ad503831ccaf04dc8d4d523516d658cb05a441c74831ded969cd3d575d1d54557175de10864f94845872a27b225b34a7443177e51e46c8332259aa2d00c6924db0c89a224836c451cfd9945a2935cb6a211741571f46524b9a24b5712d355cfd015856011f3b2255b3274698ece02e0cb943766aa557a6804e312708d5618daea9d3da465ba56c9e4c697fe64d7c47eb20f06204abec68d21802829858c27c0820e9bc671a54f669f802bf225970744c97bd70998ec0744c9cb1d9a6c1fb3cc3eda9c9d562ed93e6adc1229566a561a81a1de26daea9559b6bc8038fa5e643b7db22b7b43636fb06dd91b5f6adc10446537b935202abb6d65f6ca5ff892d9954c4727be78d70110255fba1368b5aab4b583b13fdc852f908c237097075c9127b93a204a7e745d60eced4a6697b63edac353964d88ee214afe4e7892dfee089ee443b70451f21f6e892bcfdb1b99b2164762d7eef478ae785e6ba44f145bdb02916c92bb583265add591d2ea5c3d568b6884bd8938fa5167d5210ea6554de06e7c31b951d5bdbbeefae64e02f973e1a793f6a5747b40d476d25500446d0ed89e861888341218fb03bad7e10f927184ccf1802bdb47f7547259603eb73a32a563c5128213da9ac8dc216ab310b53dc42d71e54f0751db7bfb6773721f6e4e64b9c3f578e68c886aa0dc1e20ea06d3893a9788eb311a6d5af5e069feba26f0348f5d1b10c3d3bca5f1e1019d6c6d9a9761ad64835c02465efd55455ec3201a716d01675974fd027c69610d944413d0e50c4f9a43cb685534823a01e2e87f74257bf2475b1f5d89015726a6330f5daab1c9210ba82351873476069626e2e84a2f85a77959034833dfbf2ccd9434f9932d9a56fee8aaa500fa42574ca0ab296964a9f4000a2be57a4c4a7316005f6808ea072ad763d25f95d6c0565dc4c19113d6d864b5a929126b6aaab4f9bac1756549330298b23529c84d73872ed2449a796b165dcf469e9734970f0f580294ab3cd9e6a5797209e84c4918c8d2e36026ca36ef8c3245a2caa3578ea228f2c48e272f09a2e0cabce8d680a8f9d09d40306009925cbd9ab2cddb59eec814c9fb013aba05e5f147748b001eaf04dc1180c7cf81b8066fccd56588f71042dca52184104292e9d554491f954ee20062c9a37c8dc6f89fbdd2d0dd9201c42e4ebee896519ca31b449fe24f5e922892c9d6c8600fcf7aa8d143ca8df9049881b9881bb38d02cca0dc96430e26759786104208218490a57279157993fbc56c7278294589a6a7fc8f3fe916efe4f12ad723e971f458f268f21bd746571aba018c46a43b80fb46c59f9c5c69e8aed1c92f8f141bd705e51e71755cbbf5297e54a37489e853bc7795f80157e209863a6e7261863a4ee355ee17afe39683b9816307afc11dd7e28e1b3bb01302b83a6e131068c13ffa14612ee2c24c448c0fc5df53a3e2878817e21ed1a7f81e6e8e6b803ec5b35c1c3700970270650593881ec4fdfa237301703f207027fb70d10575b20f4490411936f94024213a894cd997d6a206e6c8235346bc1f35d435f9254b77e9ab7454e928d44b281f756a003731f9ec96949bdc768b77936fdd62e326efbce39be028f3d92b6badb5d64831feacf4ef16284a39e62add42bafc29886e3979c99fc8f07ac9fd20fe854b7d92275d95d13d9978ceeb9dc657ef9825c77b871c8cc95d1a5f0fdb3e993ce5ce3e99988c1a65f2936cf21a8f1c8cc94bb854bad96bdccf66d4cd50373be2fde64edd7f8846725ffbe1c22672fc0ff73be51f1e3918f9c3ed309053febcfbe176f7e1384674f8d1687417194b48484e2a19fd47b7e0c333d12d370edf0404ba45a5a587c35300eeb8356e804eb9bcf4c31402d8f8008e72781ddd7272f823bac5d402054b8e39b90b8631462858f275ebf5c892a5bc27bfeef723cb9f60202cd9e427273dd0d718638c314e2820eb5126ce40d67cbdda255fa5c44e50ac7221d027f81b97893e618c7fdc4b01b802ff5b806b1b059f42805b6a14bc8dfb3ec10fe09e1a058f724fae8e3ec19bee117d8237b92eb0062e618849a42bba77e347f7833b597492fbc57851157d6a113ee2baf0f8c1441310802b7d23ae134f04b122aae2903e19e964e46b852c39c618bfd375c91a87e4b6a2fbd1a79647201aba78a388ddc705dd093e5621026822c2d0a24a10418c11bba59c93d25ab78b9b16da49affb1cb520fa44593a15952c258c2248897e9fb28a09a34307d4c9d67ad17df3fa7c5564db45d7b065fea3b013c19cbfcd1a08aa9cc4d1a8b4d948f96c4e41f9c96146788c93fbc3ab0fa5cf8e1bc4a586ee834eb474d8d30d6cb18d63f7eb3286cd3c4a43c78d442728ef9414fb1a2928378edded35eef79c826db43e20a7dcc36fbc72305b90997bb833dbb871952b0d9da6a15c839d8e3ea51c8172bf9851acb5271d4af429e530e59083c1700aca250a12f2a7dbb850c0568e913f9d2e6fafbc0ff78bd907d43f2806112dff74647b44b6cfd00827208e7e8edb4fbba100c14292a57845dcde05ee00c018d987ff700dbb31a3ec5879632b33080c63c9a292a3941ce5f6a23ce57e31a71cbb1f4bc6441f956e6d974add46ca4952184ad406ba571a3a937f3a28d0271bef5711557148b78cde8f32dd42e4e4e4e4dc0de29e544a126503c33eb1cca7c09cef47b62f99b71c0cc9a592b35f9c8f0f68c1075a98c9160361c9194976978ed9a4e3fd275cba04b396e3c64c12008ee3b810d76047c410188661188661d828f494d0536e6fca6bdc2fe61ac7b051c9bfad037d4627dd22d26eafd22d28b73f758b8ddb07d12da6eef644c01d9c8e5ce3bfd699e2cc135d6ad4a67b7aa3ecb52b0ddd075b43bc40b1f1fe13ddd2693cae015c8ed08172ad8dbb752c4428f103ae582de57e9045c46b5c9831223eba9f109b6c1f22e2170773ab23b7dc723eac20a3055cdc64db72676ec14c1441c455a24ff643dc1f7d12021ba04f16e61c1766161c01d8b172597404718fc8ae0b006e1340c0d675d4fdda8729e635b9a7fb61bfde63f800c10eb0b0d3ca189e52894ec1171f2eccfdd4bd44a5b01df78da138e5981b57f9f77ce37d92fb9aca4d7913d95ee57ea7aca27217a9726f3ce57e16033965fb1b2af746ea427cef899c171a3a0d0ab893b967dcede55eb76bf7ffa0199f5b9912c0eded4b32a5e3f63fc954eaf62cdd52727b1ddd323ac9ed5dba05bbbd01baa5c6ed79748be9f64dc01d20d8ea5872cce8d8535258522e142c19e59043c2c653eed2369e72eca6a03c723029f76339cafd7e64eca3dbb81f8681b064d147a2d1b56ba7fbc953ae592ba270817d9248d8dbb84b63170ac8ca31f636eec413f283ac9c62e329370998b1a7a4e0cffe24e59edcde93dbb81f0a06025919c34ef4c9fe0437d1277bd365a24ff62617027db235f08f3ed929806b1b654fd2714b8db2f7eefb649fbaa7cb32ba3a8e70e9937de81aa04ff6dde5d1277bd0a50007f3c1dc95dbfd84d0c09d2c2f1fb1cf2ab4e0032dc8648b81c09d4c6f73bd90a5a6884eb9d166667c02e2298f1f4afce8162a7f8441079bdcdd92078f1fb4f250a26954828719ba9a822b48810db90f2f23dd0773fad405dd077366a60a344b83541145a4b1c5c0d3538a47baa5b71843359a13c618638ca5aedaa1fbbaac2243f759bbb5aa79e0a8d64a29766597765d933efb25e9f549af0b07a199be391f29f495ce1bb3c4036cc9c16415abf5d2ae4bca6e4a825c2f795d54becad74a0ff15729a59576196649afebba6aeed32d327ad775d5d6dbec946618fed1ba2abe70bd5e2fbb51e9aa525269a909a69c5593524e29a594725ec64b29a55cb17472aae8517537b1453323b3838676cd7e414baaa48c9c9134ad1d9e10f4099a05b3a626a746a746a552a96a56383736abd52ac6185bca68032cc8306944011673a0d7755d7490b5d62ae56ab55a493aa5d4825cade48aa45e932db803bb7c94038e333cac2658ac1a9b1b1c95cc4c89a69b9132a596139a00b2f6a2507741f893408e3dae8f9839bb711c4c3ca24f17d62186235cfa8475d86a75b02a1e44806511f6073b54030c300057e82d079386184cd5549171042b5b2d5403b04c3b4042e78c33248f33599665d8659cf9e0388333ec12ab820493345ac49999185bf27126c6993833e9e5bc8464c8f4d2061390abd58a5ec67919638c725ed6ebba2e2cebbc9c3586fa0720489e15f759fd3a6ce9f165be6872e3ae9c73ce8dbbfd326f43d4a49ff192d68e5052faa17f9933469c964b8b9c554e4e4e4e0e0b47a2c66854ffc606a734a3626dab0b7bcb99333a256b6664660dab068d98e58c4c49232d5768ccd4cc1a5a13862eae285ecdd5b592f352bba436b3d0ae0d8b3810691c0cc3c170301c2c8e34cd75d15c34170da60526bfc82e0f88d3188516bba615a72979b4fec48175b1405d23bff7e794cd850e1e723e6cd76850a6bcd05a4e2a259d524aac035c0fac5a098b90d5d289bf38c4be045e48a12363b121cc7171480881594a3ae79c2dd0a0ca77515a8299f5ea1e5983abda4c9b7403fd78228a2a66bc1a9cc39999193a73436fe86aa543dbc0c34375688ba24179ae49af6a3f32f6c0eee9e9e9a111e83692b3e49691a2394948449244e469a5284524347a21b2662621f9e891158de89e88a32725b9ddd33d2db31491846011f491155952159b5ea47aad46b6d178515732b223232393e1d28d2fb5555b59eba35d53f6d13e3a3a35e64de6236b72dac79b2f5d1ea4eb048cf6ba9ab377687276a969d9a5f67a336f5c7276b9714ba4d46497c7363c65646438123a3333532201c4d12701bd59adaa19ac3ed5f0b45ab8eac884204abbe9d68028ed5547bbbcf3922bdaeaba03206adebb1380a8f9aa938618742148869c1f5d1d10355f725d60b2d71b392f415866d7e53cbddb9df0340fba23789a17dd1244cd83b825ae4c5f6b64ca561b27b05b597856333a9d566d795fa78d363a537574baae9aeac854bd41231a516b228eae2d3472ffba9d5b60e86c064953e8b515e209fdab3ba14b799211c82474215c09e9540ff41aa047160874925117c21f24e308dde50157402fb9278802bd7459ea0a942345a04bf9d1fd25015d546f401507d412c933486aa0dc1e6a0d86d5e46640ad9684eb31caf6259b7679943ea3a73c3215599487f2749155354cba5eed45623a915405338b33ba9e24a09399f75623b5955df77345f044af754fb778f064d269982a20bb47a63c88f221d31f1c7019a1fcc45f1ea87085c65a238a0d5b72c8926bbc145964c85d5b1147d718492884457ca14c5f5bb535e916f99360489cee9132b7c695365255ba0aa02f5fe828c9ad10455f723dfad103b81ebfb81eb3c6dd0151f4a51b46a69742a646c813084f881d48945c9311068201796610452fba999a5820cf1e5dbe9e5151e189ded2cb0f343cd1596fa37b44f13a7ce93c75a762811ea92d896acad32723aa4ec4d1588e892b12572b93cdf3e6842b126d6cbc932bd7964c45168bd5aa446c7030f52d7346a2aacc8c9c40b46ff45622f364569ad58ebe8b5c403142e1624dac91a3eb51cc8707e47969835b0294236683a644392f53389814ba5d71e65c91281365f2afba0377cc7bb78acb158982c7832bf4d725d18fe84928bd9c97975b8224c7cbf518d59dda3a02779c91bbb3777994ac5c564e60ae481390852d3d0277f4294fb744569faa4e3482ce441d16921b5c91d377a2f0442fba1844d1103ccdc4924ccfc83337546aa46cdc8feef1c2d585da873225a297a8128b5eb77b4ab36af2da79e3060743a5b4f1c6d60d0ea662959611d12579dd11bde20fc8d6a2f2a293e07846a37ad8546e6df509f6e9b68cec90908c3615aea3b9070e66ce5b652a119aa2335805325365e8bf2a5389f4a9e98c4c455664f9e043645523b5070ea6e2daaa2daac2f9b0b3be5b6488839923593faab362538febf217de4a3d4c1f64ad1ba874cc35c6494d328666048200006314002028140c88c462b1603c244b2add0714800d96aa4e72521a884112530a21448c210300000000004092840466c30212aacef8181a41a42b76f58849522d26abfdd8c206fae1233f59f30cd5027da2c67ea7932014f10b8fe991f2c815dcf75f2c214b08205648300de7dce4e48d9c589e2c7620d40ae0072fc62490171325ae58b9f16420090ebcc94a77f85ca4834b744824d7ba9070406c9ce479f2203b970e6749daabe0482e2f397ba8a97d7016ee612a939d00c741bf17d0cf681414072701d2a4099997125d97f2c17602fde5f98bcb2aa0c45a5a44a5207cf59a48945e9877c7d24cb5e18c0dfe7c667cf499b52acf332acde394b3e987ad06d4e59dc02593eb6367ae0cde669c7e8988f538d3bb335ee779f2209e249b16392105b29843111240b30d66834c7a256f7e199807276ac80cf8270044b876a5705743caef356480ff3f73f18d12f54fb4ba25b13ccd3b23398e63f225cc34b4d15c6fa0a9b65240070c0cb40b86f4d3f7fc703a0d62014ef8a99b1b110100cbe4a3f1cdc72480d55431bd35a900a0e589e6b3d26cf5fb82f6c34909e1711796d2604391a01be74dbc05dc464945f662138054a8d0bfdc0f9cc6cc8362aae3d9f0cbeb554e904235dc6e59f65a2b662055efe3bb58d79d454abfc10724389c55a8fa1e6555410a588e5d482ecf3dc5c848d36ec11b23dac7708ffe43ec5a23427ac49d62ba4c917ff55377ff537732b77073167cb8a7d98ee746b76d5cfda2a73c4af078f18f604c1832a48042e21b144afd35c5a21baba9fe346a62ec9f027df71d9748b507f6ef8069aac20c399319e2444633d7f4a579778767cf509daf7b61ff55e21b611347fd0c1396a1588fec54ea26117bf3247fb8ce415df0f1674b22132d3d7bd603988b044e29d85c5e73a0428dac29c9d4faba461baafc1e6cb60e06b1466befa777f5879fc5dc41ec6feca6697d31e5e89cd9be67f7e98b6c11a0d0d8de422d3e0ced3f4707744a9029fef73651bd93b57c4741152b664192d34ecdb6f918a97c44ab7688a77026557fc2826cc340e6874189d1a59e7a69f701cfe5b2b226bfc74d96a84ca62d91a3a7f8e7db1edf5d205ccf6ef39ec688fa45636e2db4bbc419d244043f30bec1e4639cae3d0fc6dd5facee8c434e9dbcc492f1860683fa1fdb0bcef6620f89d711300f091bc440d33ad6eda23dad16c8145a45082d2dca2492fe270c257b163884b94b0e91d098b40176806345b031edc6dc852443596bdfcfcc4ed6bce39f6233a001be4a60110a4ccd6828780929a03f04fa09f67f1584bb050daf4a6cf407198cc0dc4fd3594b0ce8c1b9324a40b132fd3dfc49aea9684bcb894fe75e9f780a59329aa62f4f7026000767d0172419220567a052433a2cf2bf97c4ac19d630572b5ef192cdf801dfd99f13d516bfa434a23ac2623c358db4ce28ac24a9deb54ac92881a6b842921b748c0cc6e49799e1ba781b77d3e8c11ed7961509e236947115939cbbf12e04c550a23bc5a45916e59d83956703b8728762ae02fbac244bd24468e25904dd945eba62f126b956fe7c47024e191fa0407a17a323c2728eb43e92362b7f35e0a467ee1c559f1685f9d9bb8944b7a6d9b973dc31df5cd5349e6d63e52251c726f7706712e9bf0060b824963cbc952e689d07fb2d04818a82037f03f5e4a253398546028d52746ac46ac4606b2a44d93935ccac11c7ea9c130f90a5a40db6e0b90b67eae16cc0074b1805f550041fe795528dfd62de0c1d00ee7eb0c0057cc51a2a7cdb74d4cec677435120a9fe98fa931c293a23b24838c12b2a84d6f555f1f22d1def56e6b399c022f63a70bac6dc1ffa841db6323381a076a620624540c1c47c85a573db499a73b5d749791ab3d0b8cbf1b7bbb66564748406a7934638ae03d9602b82f27ee00680cdf38ebe563edecbaed7fa58ff0bb5517a0117f0e1352e3e7c0dd8943f9e2a665451e405cbb501b6192bdfa46766698e5c955f120363868298c64a634ce7216bae3a01ea68670bb51cae2ab718e80e2ed47ef9738d8f0a1765122167c458612b69a13a01831666b3f226ae10473706312fa56ce166682c35db458c19db6c65b6cfcc251071175bea3cdcb5d8f2045b7896d81adeb8b008bb4c48edab4bee703b7faa9072991f0c39db557b37a171ff47036328840fdaa5375df7f6e70d696e7e2990bf9216ab57e41ca3b24bdf1880e45823471a000b47f0b945156f943a45fb77280cf31252b930fb7071dac8903cc8af39cc1edd345107eca50ecc0afc4fb32b9432d3db8275c37f52665d68be60192008cdc4220adc1e4a5494e73a7cf37116fcb1134a101a473a4c10dd305d76e69495a2419977506f07139030c7df2660a91aaf836e5ac36a182e04f7bcfe9134eafcb9cbf6d6a6fdcb941a6dbb8ec3534ebfc45ee566055944cea707f0e267e6ccb95586107b1e64595ffb1d93cf1fe6f4e4134be0c873b9ad85da388065464512af99673ee248abfaa70e955e0af59a5dc7046d26237ee78d27619925d920eedf53445ddfe20addca29523ce317823edfd5798c5b7b3458ca3654805e26c09d6582b1b3a41c160d2db0907b6107ee403301a5dd1fe8251450b099aac72448be9648ad32fffec25e1a191bf3ca37e85cf7b6d0a1d5871c2850dc505cc808767a4757717513d68bb351f3d3ecf02671eeba9dd320e6071fd2d9f65361304b2640d9c7f776e1e064d33bb70a8d0f761a200ca0efee6bc8e08fecddcbb81158116cda9c18818c571140dd0d3d261a10543531ffdb1fee59220ea6c592ec206b3823851255ce60a048580115798831f39ec777fb5d88fb2df9679e9539696d594ddd03833bd0b44d93054b942d36f61409d39e9e8cc67e5309cec812b1f32fa78b18caf76dc93fce1b74d8471c2cc9015a16a7501f776b3471694d4e4881a62c5d8e1baa2fa727b712223997531cd66a9f10762427b0b6ea520aed1eee457924b6bf54be8f022633cd0ded42ebd50052dd6acf52311b66719972fc237cd9f249ef8c3d48ff2762eb4c4277a303b532b05bd84ce0540fa7b9abc95c71dcdb97fadb5bd424d4d989b15cb70d2d30f365b8ab943c183fd27940d910224fad3b8d86a3d240acd9ce51a5adfb62304b845ddde8d2e43452983cf8d46e49ef3970eedf9e8a8b6ccf46411ec1bd6f3431b234f311b6c257675b293b251bdc1bc2065fb508a08397b25d9f92c4861af0917da2675bbdf0af0483e4220d524e9c511e6977bf301183b2cc281d824338d1640212672d71bb049826b1d7bedf432d2ee761bc7d322bef056e0901bbcf6b14a3d084818eec2882df7dfbced58f5a63b04b43097d31a6420a91ce1cb43b5f373c23e5e5ca3bd414b7d7c674ff8ceb5e651bd11abf7bff08f3735d3f45937b79042e7d2fafc5e90df72a7fdb32cf8617d9079faf7e418fc656537493f5599cea4b88cd108c1663c8a69fb42d1ebc2d3f2f120108f8ecfc92fe0aaa2fe60805a3079cc2008445c97599059c07794567e5f74df3ad4621f44454a25146a99ec3d7640afe60fa5dd5c0fa905d4b66252aaab0bd17f71190901bbb70a56780a0c431ef60713e66953d5bd27eb544e764c3c81048af4455a7033430e10fb625f265cc1283046adba569356e89ac0897f0d3d56ce8b39a92291aa56fe952a2a1acb4b0a91fa6cabcec4916064e7f09a2ea7d5ce66ccfc8c614056a86a2cf79b7599d8b4c8d3490f96d5e63d9d196671f9afb42c90886a0bf99671f6a9e26c2b6b30767a7a97cd741daa6ad1bf6e2825d0f369044d6407a7ea8555ed471a5cb8ab07371bc4da0d994ee50cf3c5b9165395de239741a8c230b56fac62028c5b857e62049e38faee23d1ee8cce4f2e88be059ecf25af069407ed5082fe8216e9c2b3ac991579b38f4ae99f1e48c4821fd8468516363a059077fa0fa2d933cb4a8899a397e813d5b885bdca5e263359167e71bdbcd7ccc03ce6af69b140035f6efd5dba0339edc380716db9893a03b4950a61e2cb75bdddf70463a49a82524c4fb3d16e753a53eb57df9194e03c367caafd91f0042bf824c909c80bc3944714dd1d4707294b2cce0e1bbb26565b430cc90b3ccc458a5ae696ab05341958d4495e9946277d115d88a65001ea31c4bfa13d1ec01b82e334da09747796f812e6184d89795a7c91f9db25fbe920a7bbcb4a263f67758b889ff73d7ce42af9337d74c40702e181e00450e6f0eb21beda6bc9bf308540accf37ae693740196e4d78de5451f43cf0c38867a8b80d100f4ba3914e2082dd68b6c3f143759af9b9b4f4bceb06e788eab789b640288756d76e0a936d64d7bddcb2d1b753dade00020d35bf47489a0568e1403ace25f398dd519e1c3b8114d332b6d9efd98f3a92638539a0f2a4ec0db3151342cdc87c34b5db48af0c9fbaf1af911c6502c731b35ba68d898aab12686d56362a3e8380d29bcf3f3dc3b5f0585d6a660df0e7d10d99741681135f5ed5c64c331f4cfc631ef190a3ff737ef3aaa2475d57b5092f74b7539e2cc734c45f6d32166a158ea1040d54899d831d19b4c2d60b083b602f126943691190633f15996479bc321646ac61fc3a8bea7320915cf2d0eee065689b75615318538813e84b72d6216c7862a35a5dbfcd160e0d14d00b48237d9b36c800cd24d09fbc2773ebab95aa5a79fa142fd8323966ab64f9863a72e527a83401eddc49f903837c229b300d15248073d0a8516a25fbe29280bfea6b2c147373770086161cb524a58159c165c1f0213b53012aeae9c2aa3d701f33dbdb12a15d6e6560cd99caa754bbab76112421efc8565d0b7d4ed6e56430be686850f4c44a0b577e358726041038128eefea0fb22145087befb033f67bdb269c33c48c09d0c0cace4b9a231a87dc70f365207ee175c7213d83d27827609776081fd0a309076bb43682752a22d95fe1f7308620c7785293752d07d7062b27f1c4cf3b35972b311eb92f40a849b22c88135627cdce391105617d7d80bf488797c6ff4e14f0ad995453c50c47743d5c7c3e1e52fb9790561da910f7eb90659327d754508dee6ec83807ec99074ca022841173b8ad46fa7dd145e77da5f6735c85e7a9916a47eca2b3759107f6904cc93fba706236856af04b7b19932eaa7513ad30f223243111c2095444dcf013971a108d23a2dd7354c04907af3e719660fd99c74df5c5c0a82af430b6b103ad6353e47600d49f8f0044ce854952e4ff8a5405258426ff9e555e611787e6ec08acc9d38861071e76a2b00bf00376f212e326383aa12267c1db5f0933a3350813cfb2bac4b59580cd4b5f2777970e4e4e913e614f9811a209a205510be1597d12755be14c1b222d86f74cf95d19ccc7d68410566b1bc2c36fa9032995c1b78b6a8836973936b7d01dd07d6b629115bb144da55194a443e54d06a8c5d5d32f323eacf59b5fa50d87c08e5f635a9c41ebf9c9d96bc6b0930a0e54f285d06b131e6819b085d25b7e632d45f14d3f4318e5fbb11645e1093639a465cd1213773c407ecff839ba72b944b8d777a8a29c13adc679f2b01a0a0dfaddf765948eb85dbf44539bf35009db721485472afb7a7bd709b152fba8fce3cafe45326890f9bcdde3d68b1e210cd8f6cec4be6f51e48ca9e66df96f1727ece6c5744e686ac6e1667844520a1d7295e2cf42d47c594f962752e193d62b8cd5351bcbe39649e38d7fd810e6f4649adaa98288e42ba960569ad2f59092c1c8628be17b6a37ae40b25c42756b8cdc88be91db91d5789c4d8c26d36db8add2434fb93287788157762416f9bed480ee807feb2fe0e1441f3d01dd18c774917c094063d84bb1fd1d1030d71390bd4bb04ff598bac84a979b7df3350ca01369e0a5a570d218ff0d98f9306ab8ea040705fd6d07117848a69b2e074525fa9f8645b74464204cc953dd34334169c4d0a8f6a941a380747ccd8f01c2fc87383cec6350f3d2b4cd2884138621b78a8b1270bb18604486289655f8d3866251b3c9a800aaaae96d0a4b4ed6092cbff7bb4011dc029656740e95ecfb1411f98af5c647e6152845de68668c337088ef085ada9c6d785f8673aca1305292a33813c77106df8aeb319e4dddd7a14059e86ff8b505783075a146d689aede3d96c839647a821cf8ca1f4dae07aafeb4be882adc70367bf9a7d61d567435752def9ef697da0fc11a963b4e0b3a1e0b6d6f1513f5a1b92bb1a28204cd4bc4b2fa5a1fbf03c40e658b4a258563d3e7ca9bb5ed0b12e1a5281e207095f8b0802f88f51439a61720558b52b8c6938c3ca82ca21c1ae89ac9c41fc4097ca0cc17cc2f0f764367d1ba09a9de3ae1b7092874f3faad496f56ca2cc7ec4ff9f3680f1364c43d79a0b8d9011a0f1e80ae6a6d5fb33fdebdc953f3674351f95b4ac064992c7a037ef0ebeaa1e951ea8a574ac09901de1a1c9aecdfdc2f8af368422523c4630e67bb0b144d26c5aeedbd0e0e6af61f2d6d8312230c6e23b0b00c1ddbef899168ef732e879a2efd15c602e8e1a4e87fd64f115ec84b97fe585c5f70401ef8af0e2d09818ff749d2d354a23da304f34fddc8885215dc9d660e66e982b1b2cbe80262c3e14f10550959e261df89a11f30c586191b1c7c9ed62d4b9946b6d0e5bf676769d80e3229cc85e0639e127ea056dffe39ce9a09702e20c2f73fc4955a55ccadfc98205fd605c2c2cbe09fc9962666a0ca3faeef3ba91314993672b8a83c72a0b45065b7216d4a2300992567a61094a0b910c834a53d3274177165c186d12b3792b52d4242b27d12127a9b250cc42585b51454062932cf9c9f7a14cd84c5f94a9c6028b2a4e8812e802923e60db223e9042ced08add9976b8b4f5b3e46a7fb7ad2cf097904956dc1151d20371f1f72b0b567b53df0d80b8e85d12ea0bbcf2fb9cc3c2fdd87510ccfb45423fa71e2470b2e82501d22c0452caae9acc064f17c3651856126541a9444c188b2d01d7ce0c62614d984310dc339a5f02dc130c8c287a1bb1465274b84bd35f190bf146d47d2532169a38f47f6976530688a7b0d805633cd12d4c7110fcabe1e0b196031b31375686ab23f69340dea2e8605f9649b0ceb41db198b1e0ad3d2f3332c94b0696774f2c34479eac6da03b48a26afbbce0e79a61985850e7df8ca47d89fd47b4549f44349b39b1f0ec4f5087b601792c0e3438b486b5e3949a85de0de4176e5317102feac55b60f037f4e30f859a85281ee1869a888eb2ab6968d4b1277d7ae47ed5742bd0cad7908ba270532778adec5b4a2bb7cb320b9d1a758a5877b51b3a56f94d9149afecb6247c0a76c78d18337e97336169d7e2515d7aa09bde40f9d97262a13049156f33492cc4baad22ee1622c05988a9dbc16afcf853cc8f37d288e94c2cd0c475b186615ba807c5b6419fe781c378a49e60ab5cc018c8bf690d276ced3687812e525bee60e4ec6412437f0e18d81cc810e6f46980b82966216c64a32e333b4d54d5afebdd14224329854f0cb21adc7cf2e04d53e9ec3dd5747099fc6aec6726bf5760670ea3d5bdbd6e1976bd3b861b3c05b92fe8ac43793a513cd887f25da4269768f478af19224dcd2a752c2780728459a2222fe1c865cbe504dc6e2199227caa2ad8cfe445674779edae26e0351e8aacb77a44ff4648250aa0091441dd00da17d71d0a4b2c38de8185bba079de3482c5d3e3c445057c17a74ca0e24b07c48a3f414c515be2088c72486bb0b6891ee4ee6ad6bb2c38b40d094067e1ea4173855a4c757fa34c9eb56124bf8c7deebe8c7a54fd55d82e979da20f877f055a91d68b779874ca5c5e18319385500fe1817511b284ae85fd7a281a4c0eb426ffb2166bb76188edd2bc0b7533b32b2fc088393b18d77c9438d5cf1405127b451f38c5782df7c60e36c9760de05dd11d4d38bb30535e9469b65495b6c40749db2db26618a82d2e2e54bed62d36bd5ca1afd174543ce2197d2677130b5fe0a0423a746305ef2910cbff37be020559f8004234e17c606221071fe3519d8779a991c402d42b971e40554a59521f66849005c22ec29260eca78057f7eec4424e60dd22d9138524b150b07c42c61598befd47094b2d988235b1508ab7ed7b1eba199ac8280fe07b486330dad3660425452ee9cfdccdc70a389e7987914cdb2ba9adcc224f64b781c54c1e1ee3260ff94a2cb4a88027bb3c9aa1f7de60588954c80717683a46a521412e51f7a9d78e195b62c1e39fa18dd6b9b4d28dd718306904823a60984262a1482d3937ed54df63f9ff9cdd0439854021d2c08f6656508ce3d5e1b90057ba161536b25299d7d3152b7f038dd5994a0b816f04a9fa1845601d56fbb62b0037b0277b4e42a7eb34e8960594c4108c4e4e2317bba2451a362e4defb6dee6ab69f85f9145a394588b8ca65ccd728c71b1ab48293762f18611d07b813754f5eeec26b32fe568c6ef67b031e94042095f06387df54c16d995c0944bb01805b2f88b855eae437902a302f84a04e1c53789c6b8d1a28adab407b7a544ede152dc744878a35e962602627748c56e724d190c4bed18e8c0f1f55d424142258834c02010cbf37bcbfad1a4685d43ca1b5d72edac7950dc2bc8a77c3d0746598b70286c944034c430b347478ac46f6b72a4c2bd8e44c6c1cdbfed86eb68878f98d45b49350bdf09648d769adbd100c460411e9a038bc1d9deb8c637e278d3ab69c442cc7c3f4885379d1430516698080f87dc8c2604d2e003c1e2a151946f95a4377590bbc454401e3a4e5f9337b901369cc5b615c54f02fb1a9b56648652f16ee840f8cece2d5960cccea8cce4bb83aa85a6c359c36278aa26f76aad605c0659407b0ca84bde4cba4fabd5c664bb662dc19b4cb067c3baed49bce55581cc9d43334d118435d7e1ce60c7830f39aa57de1e783c7af4df7f1d6ffa5d6fd274d2edc25f12534e272e987eb900266eb434010872e12c97d6f7eb4abdaf8a1da745d6e141f690bb3d0dcbff326084937684c399b7e89f502d2159b0c3ca727f5af101be247b7c0ee42a2b33ae6c1e10b66e6e82413330cc281e822bfbe8c5830bec5145cc1f610dd5387ea6eede5d2045ad273d5dee6e9f4c57389d51f54d332737595b6ad48335529dc7024e0ef3c6022a8b36591df7431bfe7386074395a323f7ebeba192da502983ccb0cb9a9ae328001b574185d95b4af09f4e7499bc2e4e1498c579fc358094c2911e10a55d7544bf9304c88db11fd1d22597c6a5a66b9b6fa2070c4ab881c8399308c0263a801bb92a648e2fbb8db533b9a72a44d273bf9f619b194a2ba00f78aab536154f740f01fbc559c696291d7b5082071d7bb56a4edb1a3774edee94e498c7964fb19a57021839883e173779d96df9b7d794b6aa0bd3375be56a251693e5284e8cbcf68bcbed98d5398925de1be0c2da16b6da767a74f7debfc7aa52390008b40043b6502dec2232564c922d465c22673ec43ac260e23d0126fb66d27c2763e68daa71d0402d15035cd7e2e5601a5589cd7350f8d99088467168ed5024d846f2c77ca5c7265717c85eea823a8b85f24a1b6519dac9c628d2fbcc31da74a3a0145376212f3295c74dbd4c39e40303ae5b301f90ec362c3468aa4a48ce802a4d8097aaba360f2b8c850c445b604088d4d6c3fee91b30e02b47596efc1bed31d9271c806ee7bf3388a8b0a9516ba28601164077503d8b70bd2c21e339da07b82daec001b6a5d7756ca50c6a530283e600de08bce5a633cb85d386d217f3382619c0844686c1526411b5eaaaa122494301b663ae162328c682dce3cf15dcc8a642005dcea9fd9ba79282f266ba33ad96d3bc0cee650314dd09c4696008c345e09b79028532d40d8882f0287e1d4302442e05c8d495a9954d9000af9b4cb2bab876137ad2ea7a6d6955462275881a391136f5a035b22bec6c0c544708e67e73b780a2ce0c0463c71d024e36bb16382721422ebae67ea04f0da86fe29628208223e6031264261be3f727db1dbee998589863ac4dc2542f3c1a40ab683776d5d2a307279b6ee29d11113bb3897a2ae745037e46fb369d7d79ed314dc463ad69ad0318e11e0db8c487e5fc9ae2ecbb293cc9868586ea5407bf7d364816d88501991dfcd67908d812af5b1bf14d49d4d9259c2f20d4fe977f269191dc28bc8068cfc365ce0848bad34caeac79e7a9e49821ac0b08702be4731360408df504d4b205ac2db53071404e7a62ea1f72ed436b729d665bc08d34bd6e401d29b1424b09f76b25a205842a5dd1ce7e933b9af4f480da15536af4374feedfdde0e234e532d9d7fad4f33c8b8e7cf09c98a265a3e1d356c1de2e5bbcb21bcb5ebade95b2c76bc6628f99a39a2fc0029b60a6ccd0d5e3685d7cc210e8e532aae8a77949c239aaef84c1389515f0592b93c4fc586a0ecc2d96b0888fcbce8426e1cfabd5780b167f3b1a6c08df3a1ecf8be4ca6a0e3912db64ab3cfd4275961f0636fa4702e3bf83f1522680483fb37149969d7db003cff4297814a7bdb95be5125760db440766aebadf66f010ae0f560c9b9f9423a89de4dfe073a8fd923b1d57125a0200d5af133beacaed0cebda69f31d1c1cdaa268c98e6106a511ef36fc5e844934a180dd9c8922963c551afdffdaa19e92c08218792341dc9cc1204e8799fe0188ca80dc9c9bd3f6b1a60b989b17fa3dba928d82d93c6b6fc80259f5338122d3337f05b4260db33f80d208cf5d4e81489aefe3d909929ddf289fd08f889abb380ca953384f75d05304aef96eecb924c9048ec97eef5c7a0401a857aedec4423273c6f9e6aedab9b4a114b384f8edda92bef16b214ec18321cd4a3d5679fa7c7aa01d18ed818c65b0e113f6aec724e9a0ab2ecf142e3180facbf959b5093b369d92380830f6cc08cb6d6a44abe09763da222fd41099fdd4a22fd384a0090f417a97beae8df99ab6e4af4a54aae4a79ad2d3dfa3680ca5398b933c10adc23b9752097e55beba7eeaebc0142740de2c876b28707f915ff159559cc0cb45417064fd1c99e3ae5dee71fa3c5c41f11cb484014c643351292dd9c3b7ecd22765c229bfe58ba1955e9a0935dd03de55ce1efffc760ac1c98e8e5f757d740583ac80636aa89c72cbe0707b68e3f191ec1740c6b962dc6d6d3c6ae81ffe5220165f06a1c96c50d3c9eb19d2b629cb0e88bfd8a873969a9482f4eb84dc3b01593ca111a3598f622086e72e6eac1c17002872fc8220aa0cc4a1f78524d1a037cfc22a3ae7d4a93d1094452d3866800ef7952eca69b690c5c10a0f39d24381ece9b323e09e17402ec178e1f7e66c1eefcd726e989668401ca36e414003248fa9702e15b9522be44e55cbea32389dcb4a97b85d66f995f7eb0f178c291013bf1b43a450a358dea1c0472edd4511edba04b22668cca8a226a833a666144be644dd3f4da77225c8fd79fa588a259272cc23c2a79ed42fc59f414abb221a6ecbd3bc5b239c09ec0f548325313aaef7a9644ebc16ed7a354b1d90a9f30d2ac1964ac25063f380984a29e34a43702cd8a58a14380a5333293974c159ad9fd00ab861818320660d5c1c24d858acc11e5f84fd8b054e038f0eb9c102c3ccfcca08ba3b9227c4465b4385ae0c77805d380cfbc7ae1c1c0eb66a37dd33ef18f7f7880f167675346fcb7786a47a47be14147f1e6ebe86d97c1ee31e5044d7823e8a53b2cc2b1c704edd291b6dac139f8ab85d0ac605108c53989130e38e6434e7b7ac6afc8495cf3c8db655274d2a4b1ab248b1c5c9af8c8e7d5b15c81d49b03207c8cf954f306d1ef2a44e7c736df83f82099c715000a1984b01c080b663c0f0b55d959b2922055b0ff19993de08d69dd15a92a3ce08240abd1d8a0b3304152ff34984d7fe815ea976c64ba37c9fb065481ea18d446ff23d1180f51fe6a727b4365f2f1f07e149d3da47fef57f38db9c771fc675b8fbe51a8450416c1f8043ab80d243afde2eb681342050a1db2d864233862b4633b1ab93f8a4b708ad560f59809837529cc3fc49d9e7a221c9752b3b90198339dc2f367d6fdd1d23d9a51a61cba30cbe1e734f64a7e15c006827cc760087cc20ffac1131a34bb6a5b86778540f256ebc4417d44a0c0b962fcf27240b239bfd6a5cdd4159135f99644e3e1998582f27e026e8e024b517a7be18c3b2e067ee92c26f23088cdc1024bd4b4c2365b5ceca4046e50473c52a2bf31639ef24cf4a2b0de63a60a63d2ba98084a86c7fe40cfd603628ebd0579c6feeb0df4beffcab26ff4baaf9b4e6e20e32ba577c9e49f4abc1a91fde0bf69dba0a54ffba955307494691bf9e2d8081ac55b6701c4f976193a5cc8d7079b8cd29bc920eba04fb4b71941a3b61934083c23cc1aec1bfe2f5499e10cf44134274ebaf40977f4a385b2f2535cc04f5130b700799d7d0e00d240446bd231ca2c74943a68779343077d1d6d58104031664eabd2e019198f361b1eda0b9297424101868c1dc2e0034f37d1885712beb30ec3f78eb86945a0a6abfbcb1bea030bf6da35397adb1c628c4ea6cd56fa872fb25a6665471eb4f61ef5ca327933d6012b4bfb71da64e7e39e8628c9a56b768089de758e6963ab2e336e8c4cd3847d3fe747db6b43cdec1cb71df130b5c636f42c59f51b277d7c327c104bda8f9b05e1e16984291461a98efcfa1611bc7c9dcd01fc7ce211d295960c15ad1ad044860c07eccbdcb78ddea011acf18d291151671e9a7436c29fdc69c3a8fcb63859361de9c6c4fd0bdf580d23542b1af447dd4109814d1031e0b81dd5a695dc772fe8961c32bd0a5d1e2a02d9fe7418e00d10648e0413463cf463e91b4b5c2c206b6c29baae73dbbe68644bc5fd0cc4427f009247bb490f6b8e203ec750b8cb7c629330e44249962f2731580919126e76b2e7a90c1043b050126b54d5bae038efdc08117e83f26a50f7c0ad7d1e4e028a4f546b31b83265325569b72f4e7377c07c992c54bb4f58f5e62800043734f0900559a1bdf7ec983d6b4867dae1e5480fe51ce733d38159d99628267151e2e248ba52d782551cd45141b5404a8a3ffa810ae19704fafb4499a843e7934c540cc73174d9c07413601254fe4568ca012c71be4e8d7872d385629c4f07158ca7b2631c88cb502c986729b37fc2885283eac3c80f8c15c16d502f4d3436f91116928bb24e2a2a3b68c83231b128606b293836f33e0cdc2fb5d5cf9be0a61c3577358aaea23b1c1f909b26cf612f1111a1c17850ff3cb7f47eaf8fefe142568b2b7d046ca420486e6903ffee8682ad049612ed099500a0495628d71af6d1efbb2a73ef36f7b8f8217d9152132cb342e287b399007f86f19d4dc1c4ec874d32fb3d07cd9b9cc18f4eb4e8ff9a4ec18da4a9241a4ffcaed19e709f99ad71434f2cc219150611cb7d8b707cafd6c39ba01a1b85df543b261cd4d604729c7f9ebf6b58cee4b480e5e1158f8119b5d50351d0734a959e8a50109111e4c443bfd758a6b41ec0c727aec6400c7ee5ed0205292cb2953fe4d48ae0f97eea0d5f9068cb4f4fa94f1c56e304145c5c9ef88cb1f39cee3f45b0683c320588f02f1b421119672d1c3651f2604c6aff1bda65e75fd4ea204f7c1b0a14435d607a947bebc3fc17647043fbc19394cfe29bb3f13ecd978a3e0886e46b77af5b517f3691dd1303df06af4f5b915d71b8aea4f069c0f0cfb6084442bf2ebe5699aae077cd43c66dfca18af873107d257484ab86b9efa051ccf8a30499c2e5dee7d612f1af142fb7839e298fab70b748f9313a05a7d47a4d083806ce336e57344ca7960f4c2853262e67a6728e5df776db8b776c99c3b119405042cc740580dceaec8846aae3e9be859333b0b19d6acd2f01f0371f339e86a47339d51f51afae86df69fb213548b189a790bfa4fce2aec695468c84a245d0056400bd5d4d7ef43141e2eccbd9256b1b81f849528b131ebad26926a13298cabb369306ecc5b52cb38dc0dc7857e6fbbe051b7ccffa2ee3a61ba660e358845a05754bef951d2d788a23790954ce6913dc67929e060277650affdc6c3dac9d7ad756d28d8f1e0b6c963861bc2f63439d4b12876f501818d5d93f4d8ade6bfe110653f2d9b4559e2c109a5702c512a028dfecb68bab82485614b38a52390e97a785c8ce16f95ca153be6139b5b367c733539342c522931d33b1ccc95b8ef848dc0e127b302da8134b58cc51a8c8988bb8698acef51a9dd98156dfe188a1c83a783c3d523e505befe2ef2d55fa7e28b49dffbf2fbcd97243b4ac7a79ee3f2e443cfe888890da5592d2d615fd121356c04a9345c1f57c31d1f01612b8b6138b1a38d821804b92074ee00508045e02b42f738eca5c497be88bdc67813dc1a2cc3e2fdadddf3e3bbb5297ff1ee4da3538bd00b236265a6bd6b3eab859560374a3243447a45efdced7672d27766c5e549ece68f4e4f1cda8995e9f19589588e9c38dcf57dde17b5cb894f5d7adfea9fa02a2af8d1a91467aff47ae306c8461937f2fb9cf2179f237d2186a07e97e586504d19fc361cdba9b43dc3a92284471ae15509f1bc6b81f11408c70a922b412f2af875c41fa71943fb55325eb42df05e87b6e8f1eaefa538061c83ae2cceb43b2fc1e10101c2b1f246483e495c6f8b41c0f4e75edd908033aab2663a4730158bdb426a6ae25e802603efd51ea7016fc64fbe05d39a688cca4bbf311104f1906692104850797682c79c58654359a1e70f69a52eb99a09907161c8632a414115ce4d1ca8e8fb7afe6a2dd20f01b0387c1e54f5677f9991290c6f810ec4720b2dbd6be2b208a078f7d9142748f6e205eaff787380bc1f81643a8cdcc60226553868ed330df564467c0097c8f76af7da46ab71158fb9003bca9152232a63e3f481323615fb5c0b67fa9ecb717ed1fd47e1dc2aec4bef3209a3bb01565053cde2bd8bb0b8a9d91d958a0d9130d6952d2c2bca6de8d849dcdad643dda37659624ae5346f2b449e10a12c2c70b6c8c34acfe7b85b3bb5e90d347faf953bb08145d1751bd60151dc75c35a8804179e05c4439c5a92eceef73c549ad7b31fe6b1dab0f313b21bb9b11392058715bd1edb02fb80c3495b806b322c7147dbc7f404905605cbaad87509a9df3c211a91e8b0a750b4ca37a410006171a60e93d7b04cf89f1eb85f116187f9ed6433efc7d4213483b4da765b3d12ccdeef995c25039971a0cdae09903afcca2da9c3fea63f7666b9ce75c49e839e770836a9d421583d111489c15a06a08b45f5623deb476d8ed2e7c2131c332ca0531ff2461c7067cad3ec81be0746291a010aa7e402127ef2ed55363e92543e2de5c443f21e26a27befe361c1ab758e07cbf559100d9e817dadccb337256037dec0e6bca0d1b93d3e6098923b5825ccc777df98f7364f0398875be02ffb40f8272c764b699c81bb258933334e91334e90aeee01cc4a8f8f9e20b53aa61e8a5f45502d2642fd2b1375b113e40398956c1b63f053ec624ed67e053a3a0860168d00c51b5c1179d176cf3298e5bfea7dca9732bbf75f2ebb2ae4b27dcf74c01bd6be84ec0dbac3fcc8570b7426419faf4c4c87024397a679bc36f91e1ce3af6c02f665fd5250f3c979c10e2e7618758c20c6b52c3e268416788cac8c65db29edbcc6757ff909f3fd8cbc5c6cb3519da4437d59c24105bae9724354d6094854153d2e34fcaba52d24762a30e20f072116709a42d90252cc9ec6ae295937afb174871bcb6c0d7a0954db69f2e08bec5cec73e8dc825caee45289c0384005090310763adc53efa0147934542366197bb8ea0de88c14ef814b44a7e4339f18cd117e43074a211fc1a94dda0f28fe3901f0f3fd4594678432aea68b56659e33f70281605436ce620f1f2ab18141911a569dae1f890369f005c7ad1ee3bc60b46cafac3c05761123ce16b9a9f23941366d579728d16fa6ceea67af63868b635f82e431a8f1218d0a95c8e8df111abcd6167e28d109dec87b27189168d3c4c2b916d721aa922e2f4d16ff491d8ab0bfdb8f8171b461ba4a0b6701918078c0f2417400e41656a8049376c718614a0ffe66e2fa9e0162595e94564b9bdd8ed07787a7e5363458950a087e3737fa10e19551af051b79b618f2251399c5d922602cabc6c0b80762433992ae4f316415c323972d1123fd8af9579f8287cdcd30ba9fd4ba9cd5a798f41010eda5022700797dca2821aa759a7e8ac8e846375f4be074634fc08dfe53504a9f88fedbdc0fa1e48ce09547b14e4c2b90a654b3f9f7a1023982a89e0a29808aea15f5fcb31e142b79fb6c61e81d8ecafbf0a6ad21740e6475ded1771089a432798070943719c16cd1bf978f7f3fa2499761373fce745869ea825b3364fe3e9056ea3318e0ec00e51c158086457576a06222db5bc297f0c343b71e4af10b53659fbb611e75288b012b56fc14748d2de5ffb19c9aa352c17568428ff3713b2a566b6366f298a302241143d4392a0608d894f62f88e71cf9acad413e11588047c5dd2fdec3679dec703fccb6b56a119347259768af64c9af386ad241e21a8b9a0273023700dbb2d82ca6f47f78829911a951f81452c9f3db032c53a6dac26e27a4e24711cd85f699c5862e22d242089e8fcfe13a136e638e62f810242263e3de05ae51a3a452793a6e11c363faa03a8a42c21ddd5436c381084deda49efb2f5bd35df9c5a850375d06113dcb5d62ee58e4d990964d16a2be89d43525972b5e377860237ccf0444c683051146b2a1a1a81205bb495671ff39186b15e595d9271287459671ab885788dc8f10cdfa2753d9ad12caadc7f87e2ab6c2cfa359e10043f2bdeec69fcea517b169e5138fc45b590bed307433cb0a7b5b455077b4545b9db98eade1f2a3dbfff2d4e5d63afb9ee3bb0be1b35d2cf6f051e36654eab28be56290080ed31d4d30b0e29bf7fc1cc8fffd59897fdc2709f45e22d0443c453a07f2f53a9c486860071c616d3b78665449036a3847cfd1d6280191828f1ea0140b4bd50c640e40b6c65526b934c883e722f56f727ce41016e6a46086f4040aa3142c03556d66445da4e2bc02eaaa20a820c04bef5ba82c81ecf7e42ab17c53d270c062d886dc546953c860fecc12585b86ceff66e344f376e3652909235ccbddadbc9eb325ee32727dc806f236dfa39a8a6d538cf06807b593011537ec699521f7338815f4632ddb791f0ab966e2aae971051c2b066b07124123cb5cad9773872fc28f6e936dfb2e76cdea649986be8f664fa8b6f4e0a85e42c1369082e7b2a00fa7c8ea66efc2affa2615cbafba48f7dc9b7f8741d2e8b8b212ca756240b901d4e0ff5c0cf4d4315e8cacd26615e149773c4b89c77ac952e1fbe40dd05e5393a31b755f9ec6e47244e57258513e516ccad6fe07048b936c6f9d41e9d9d228069b1a9e75550fcf3ebc0abcc94c8c3a88799804ece340812138db5d9a106f8b0411b909d332da985117af6845a580c614a553c02d737f58e66c1fdb922d8b5b3b50241fc04004040599555a4429d2c4701a77194f37559be817f7c786c543a26c308e8475727fb8c8bae2bc0cd06896adfe56d6a96712212b9c55a03b33439ccfc1c45da66d37935bb0e2a8529b6472561cc6cb1ed786b54468acedb105d48b5befa10021a2500e5a87b05b5768b5680a6b7ab45ec3d21e935bb1acd310af43154ebc910f96bce1298f0536e982076b543fcbd32071a039c17ada03a9c5670ff0fe456b86e4993c92207df92ef4013267096f95799fed8877bc4d2f30979f7a7696c54088f46e8704b3e8846c95eebfdd7e833358b69e35c4f3ef488d55c9435b1d8ed5607cb9efed1fdba4e8103050b197ee74bbe36504e974ab5a31a85e6de05b2db896b1b23935a9c827c22aec31d4f4f1c4dcf9aa7bb5a53b62dec3dfc6b6d5f340889409ecbacca2fcbcd20d3ee355f1a57a0c3a540a8ade301b4333ea83762ed2cc85489b8d9bd30c4893e70750e64425e659e757f91243492bbb7ef2a71b8fdf723eb3ef4011f56f17dc56458c014788a9c3d3bce6db4b9784e38fef4e7a1d4032957c3a5ea446f53e5c3c421aacd3ca69ebb728d6eeac69ab59de3a7dc3bbd83409da8660ee43364d6bee4f63f70c99637c1c6227a3aa3aab0438ab112edae3b64ae178f56027ae6c542d085319b3c7468535f0f3b8858f204385d3fe4f5e729674c796c57d10ab32b7e4a43a70814e62d3a9a7b031c49bbdc01a6923e331f5477993eebb7048ab387afa2894ddd98dd72df92641349624b3177a33da7ffa4692a8e4954442bf1c6f416e40dbe3ddf289ad6b8be711a22209757772a546cfc823ad6c23a7d826d283cb5f0f104ed53f6f038e41df8f6931a8708b2286f321d5c5c14698ae836ebf1b52219b5448f16236c0e28108ad732abdaee8c840659256f3e7764f0907905410fa543900a1fae90c57bbc172d70a700e989be20cb9541f719e347705dd2706ee3c296f6d3ab376f9265b679d34a90405800aa099ad223fc9168f7bda49104551b8d199690e697e880e34cd38850ad5860d3a95a647ef099dd0e622af1cf5aec603186ca07ab7e1cbc5cc3663f6d06d7d3e8ff1019b01a7901e013fa6dfab88b3192d80a44b78c5d320360521ce2fa84fd0d79eb7226e0c606b2cf786212c5a6ef10f2071319659c37d2d1b17f2e092a3d394b975bc98493a1db74938f798d641c83786be4cd0646f375597726d893f8f97d7526d4678c5ea0fbe7c27c8cdc9007711806552ecc9838c54c32926ef8252db697f9237a98b37ecf520fdd93173049091c15031e5fb0bbaa9171c1feaa64034293ca1116ec4fe0bd11e8ab0a9c65bb8413ffbd9dc4acc180e2ac82b5788ce6af340d75a81ecce4724b07654abe6361bdac1de93a0f7d135eeab84a670aa57835e3005c61404f5b0c741f01e7bc98636106215986991c94e5dad519a208917ca60846b020249f413147b58b45d99494040825a896140a8c69015a7b27f08748766f8df4da1d6f81a8936c9887e086049f3387376b8e50945e732e0f96f29fe0f58dccb3bcd5db43d035dddb31f50fc29b33fd8ab157f4e0f670831b7c0ac230e79b448e0de511931040a81104169e5d224433cc6c480d39d4129d779046fedc1e570b3dddd183acf0b5f2d39a390ebcd74027b4eecdd51ffe7fca67003242dc143962b25f4f84355520e551be315f886cda5aa6c1bbc9981e2d698f532d0fc7618c19ef84a482669f4d9316bd315226f1022551565862e56fee00270ccc257a867a30e42b74cad4fee077eb00319b65a5f598bd53991b2eb0335b835ec1fc0ddb418875b7ab65b64e9bc9fd36744704f9ad0919d7a4a786b9ff71c16398693bb15b88151015ee22c2ff7e43c13a9b9ed62f607018cde067e93f87415f11790ea009e2800f45fdfc32910caaa7d8d225187308dfe9b44f3af22bcfb0f276fc8904a635814ee3ea801450e7c9b057158da11a256c074b279beb14ac51831d02e7a3b38dbefa626ac58149968a422544ca21c73b09a23fc5a041539c55b6ee1a39773adaf03053d91f90c32ad0e5e49c686689ce64a26510aa59fef3c1650124de819c84dbf020ca7b8065e85143b79a0f7fbeaf2481e82d0953f0973793ba4503cff894a00a760512fae7218b025668bb3052009709f4542c66c79d5c52dca10bd3018fae3d89a702cf8dc1faed3675a2ed692b731967fe3b8ba2d468a87d36671df08fa198b25b8ecaac3497e71ee31fb195f3716f9152ed20bbffc38f17debcfb5d1ed8913a74ac4139d87758835061a5c7a2ac0c9e6981232c8e7a9e40d2f6ca9d57957528985d50b3b732a11dcbff66a0e0904178d14e431e86d531f39a251000c9050b0e8c043480e019983915c493438b2ab37602517ee5484e11d4441cd3a7711bd9953195e7869a4a644edec657b1156240376034c8c08612884f781d0b94d1357a7a78d009315a6f197088641254c41b21894be22b42fa12375ac6f2402772f9aff2fbfd1c564f238706b78057d3932582ec5600ca000b4224976331be5f41253f79ab48a79b66a81a31acd327617bf5a6b39ee1c63792414e3ceaec273f062ac2ef439e432d141e1d714dcfc5d5c83de8d55094ef309f48a634dde1994757ceb8a0d9d9876893aaa126c656d48f996506415d254b2d1633a929e71b74ca838a99198cec208d415220b044bb8f3961a70a76d3749694a29c6269bda1751448cd3772a32296eef4260931571a03cad46942737edcd0728f5c0cf6732d9c6195527864425b9c0ad630ef6ecefb02074655cbe799207860c83fed31f5757ab945af12945dc631667b7d0ee1c3d411ca8c6db18c3ac3b162c21266857e7e632c122877ebf29d7a4cb8060f6e844d9e92ceab1ad3111c906ad75a96f841536da459fb2cb2f2ea0b27d896d1f4bbd2d19fd9f97f623e4256bd223e5c0e57ebf9e0f5459311f2c8c2de758849859c41823396d3169d513dd611787739e41780d112ebb785b07735a4f81c1a0e04b1ca12b292a216e1f8a5b78d60aa7297079c6e3412e33afaf9c0feef6c1b58f87ac2282b28802a963da1c7a598a9d8e82ea63f68b0564e1dcff3f54687ba1228880d32b0f764ab920ac9f2c4d717305dfd87234ef55b277b1096407984929f1fcb7e1ba44201af43772e3436db2545c093fbe5843f12eab14322a5fd235f648a143e88e98e094a1a35d126866f7a886813e816a71c1521d6dd73a86f13b488611aa0254ce9a166d66ae89f9a2e8732efee9d75c486bf5016bb2445b2ef1ea100689d5a6f92f18260d264a38d9382c89c9c7cbb1bd97fc5690fd2a933a218adcf9d6cc4e2381440b1dd50b33ec6a9a8c277e88f922513e9370238059016c6c93e77055b6a352a4ccb4df7ec4ce58834092e977ec6d2c49c9f64e5b7210e93f8bbdb6653c9614c1118c33682dc603fd416a11662a17201cb21c2be4c98fe918bfd4d8109166ed16e252e97b3baa06ac43f6f333f049ae9267c354fe1a3c1ac20ca92dadf75f3d4d766bbba2059d3df338faa2f94d66250dbc6b6683b2243017ae6dc964e147a9c2a2a63f897d4fc47cb861cd844b4f04ac1e1798614d42f5afde972e013f04bdafb0cb9a951852da9224b06474ac8ee29bdf7f52b75d4ae09d7dad5d87fa425f1ac8cf68062ab05325691b0fe8a4ec6d04eb8555bf0a96631853e559031dd2b7d0138d56f8d8243640eca36953fdbd2f9c5b3d8c019667edaa49d18a81ed29d032da99255c02d3678e14068bcd58e01e8acd72459a77ca9ec7968d0f08ff21570359e594efc811845e73b68d3296eec814af92e1a52398968d019b3ebaf805de8ea21e25da758cd4ebf8f01aaa7b8890ff0e32e7c115184fd9dcff9fc7659de5b5c86f9a2514ac9f8bce8a5f40085ef1a6b4c718182e86b66085478960f6c3c86cea5b5b9f0ea791929e851fe9665865d6fc404c749d2633895fceef53d9828d5a60a3651309f7cbd7bb62ea142a50beb0efb949a7dbd54470d26e8a9d4d1d35aa9b7964439f9754b6f91f6ddbeb792dd5f303eabff2d45d4f3986357ddc8eecaf00e6a65027a285b0bf4c50fbabae936ab5a4f499d59a11b4af916993b99a60cf34103aa6c095c2b20332f34ebd75ac9f6a41de64a65c1141ebdb5a6c5d2b9c48cc778e7e66face72f23a7e91a9395b5f481a03d86de2f4137e6394c6e504132fc7c5177f1a6ca8f561c1b4fa42627a73dbbab050daa763f8cf841af81076104c2fe9086751d38cc908d0d56125bf172a34bf8f630aee0ce0c5012633a85d27485fb8bcd2fef560b26e74a091f41bb32094ae17d2a923c9bd4c893376777c9e264cae046062d907199abc48933d3d2a53c8d3db3cae17b29f6ee2d13be9171542303d35907285e3b5395b85a65e3ad2b0eac10142c230e3dea2c1cce70da28a0d90ab92b63596577150f146a5549db91e1ed56c9d541465d104cb87de7bb17d1e949197af4c5732e56258bea5013922db92bbeac5d1bc92279f1893a01436f7aa273c2656089c6032cb771af68b5b729e2abcb8305155691dcda99b6b79d3bba2ddb07be80abd6846d843045724a9c7f9ea10bab614ec4c42102872a168ff2ee46ec6c89abaa8b883e7588ee26bd8042e3fcce28e2f2b24bd588b66697e184210a821174dfde7202f066f790f87bf9a510b6cb58332fa55f5f095ebe530cd652da22521186f856f214c28cde0976fa464f7d31e79743b373e45499ccd5bfda3a4d309dd1c8b50264a7265170564acf150a942eb73de536c9f29ad61fe4c0c0eadb5b083a35bf6015f500c33aa560a4149e958ccb02eeb3c367e67beae54772400d79b010bd8c84bb27535a9331b16c15a2b359604f439e560dba5673869149a5486f9a04cca5f1249bc123518d2170d548f94ec08f206456f0848857cf29c62f18237219353463e40676c1659da7c33e96dcbc05d66998c48d64d424bcbf2da67b1be8c687afead06e9a5150c04ae04a4b935d2afe878743c3722963446a633d1c2d089c6d8221338ee9a3c382119b7d9cf9af666b6c4c7e62b145e344e3f04e8863b372ec299538814e2a61d43a7ba84288850b8c1b6294f75a8343b1b13e8dba531ab2d36397ac9efe287a97c5b1d411662332ea680ac8915d5303459aa17d61efbe540fc68397f7b9a4bd5a37c3165265123a6a12fbfd6605ec9d828cf38931e3f01a5cc88ca6bda99b0ef6fb704834e8dbab25b8f575f6c80be6fc0f545522cfdd058eccf2a1bc0c40a45158ca024f7296a7d997d96fad2091705ac3c71aff5deaa14d1b6b65ef8b60a5621f77008ba7af06833f55014c825403f5453bf92a5eceba45354da5ad9e628aa81856989d490c961bc1dd28461606cf3235085bc3c1a427de35b15759998cec19f8bacefcdac8f8a8ed69443a8be951339b58de41379f63a20976911ced5b09a28c3a1c267c476034905108f4e277b3bde7dbc82ae83c006d191a7c19d2e64a4adcfe21ef8814f769ff3a5a0c39ad12a6cdcb40b161cfeb6fab4ddd0f16063ca86abb98604424cd6ca63f10c4e1b4f2128c06bbd3e9b9512a4fe4c4d2e12a3539b2f1d6285998574784d28ad284866d1d9eac480fa41c74abd17276a0058cb5f4f5753e5d5849f5c9f107d72227a095ce1d6bb98c7e1863832073ec6624ea2b4a29735cd76a82ea88c457601c7d9d1f29cbaf4fdcdd7a3c10ae27ef07143ad414e39783bb107f6c015689c06d26d4504bc471ce4c7d598db2612ef5241d4a18c437134dd0d38d7d1d01d8d43d3dd556180e7b1c5a32880893c6107e2f46054a0f3c92ddcdacd527cd2bfa5b7cd9c2ec304f66b12a61f4c457b6aba8196498e867f2b9df6adb4d2f5b639cbbf6a377308398325a3328ee82e44be4dae756b2f0e28adcf43bf351baaa41a473c2c6e62b96aa452cfc78ed00a081b9c909ea296bb004f8c164b7f1ac2f3888bbc7522050fbbb8dde1c3562ea13c72746de2f6b85459282e89e5b7908e93f1b379dfb1e32d90e1d00291b53bad00b798258c3e9cc9b136d4e0e76c078ff6ffbfae5c69ea66a5a1e7188baf6505cde63106705ffdc20aa00f48515f71d492eb7340cee18dac1ebb71e3e6a7025c310e9e852f3b92b004fba65abdd508edfc206c9dfc83561572c207e0e6ff28d2e1c39c5b0c10631d5a29b14170613bc5d7335dfcabadea3b079fab01274fcb153d1d2cecb606385929ae19928d9028c84c23cdc3717998ed1c4aaafb72be2a17d22224865154e2a2297f7933ce5ead3eae3d64eeb5ff3dc15b9922ae789e2e4d75e22b35048a90229c272708c4febcec8833b7ca2766eabd00ee65e4ac8a68b6f9bd52be15e3eb9c25934880e6fe3b07201a361fc5a10ebfceb9a664ba99bfce1ea6df5ccfad8f579749866918ca691b82be3c1fa758b92acb9acdca1ac1152ba9e998b84b9173d57aba6a3868246e118072c115598239f1ac5ef227ffec50d26210cc55bbb0cf6be1ab4a9a2b72a83269185cc2106c56c8f062d4b9b9d2ac0caa35d5ceef70120d941a0a504dc93cfb4fbef663ca6c6b05f9229938146321d6a5038b298247727ea472016f5d8f560e822db1f527dd61e7ee6d4555f8aa5f380e8761debb3553b6bd5b6d1039ab018bcc136df92104966f498f3d2905e0bc1e1f439dae86b02e45847dec4e12786cc0bd2902d9a532355f73f5a9ce2d5756c872f5d55c01e91c9b538a3b5c44a012832a5b0c64704605c18d27567f7549a4f7d6f099c0ffa66d4a27d8beb22dc9b4b225d551d870acbd471e1ab9d3aa42fa6e31d6844da11f8d068f17d70cf5ee45868ff79e63a1b33b59c9cc94c4b409fd5446f0445cb2126df77c8127ddde8ccc990559602a503efa6c05cd9d6a28a243896a6fa2874b593fb47f4730b6f2801dc20f9534d80b1f7a68b9cbdc6400d5313201de775afa4601f1732531ecd31e89322249f8d4185d54d60dbd668999ca494f0dd11a6bb31fac5065ac1e41849d55bc24acefab27ccad046aab99c3c325976049a97d66065148961c8ecc685801913649dbd03c1eda5ad62374599103434376453eadfb4bd66700e66b7fac5f97c301cc19dd6b490d7aef3b642ef47df3df9bbe5b01d709165f37b57fe1ecb0b0a567a9089a9d10552ad30e6881980613005ea6b4e2be64b5298d97ce6dc1bf83b9d09f67beb93830f67c0bcfd06e148452f3cd1a0a3da2ce3bd1dba8ba579c984e581413b1c4462c1e19baa1f7e18cdc3080181aaf5593f8a41402da262c1a1638043a3ecbf8285f05d55eadd007415e73a32f934dbe6093183513c9c55384854841674c9ed1175d81558ae821866a6fb5f429361c12260c557b75d4cfedd8f698ab4d9fd102d87ed16a1124573509066c4219917ddbec69413881b988fd55dff5fac4377b3d6ed47709dd6b29272768b13ab01d239d69fb176d0033a55801afcf9d704c99836f6a21a7fe92cdb60ac946d49a34c63f1320fc2fea365001d9db33fc67c5af6e981fa7264c229040d705f2edf30bec824765297259baa8f819fb81d685b89a1bf0e421ce7a198bfda9530595c986eef2f50aea6cdddaf8229c51637c7a518bc8f19d2df5fb738b1101ee20e71421c1981d800f55f976a538297e3c112f650ab103a71fc0a18ee56e1492f513beca2f2556b123dd47be0e5b274546794b2af68db1ddce7a89bc6bcd07eba3a88f4fb4d2ae9f22f7ceef1aa66c29155b156edaaaab12ce4884c250e4673d507e282003e02a708cb53095818b3483599d31bbc216c7ab62b8c1288466cc38e30718ad50f688b45f6106a23008beaadeee3c17205f652647d14fe13c71b4fc76ebb950d3d2e0c6712a1692e32155437b066cf1435e25e6816e1f41dedd199d8aa453f3c1308a791ce65bba8197b7ce3f321b9fcd559a57a087394826b27b67be1c0998f6147f3f0553a256c413ee74bad497d1a8d0c0aa1b5b0979f9351b112b322f3aec75557308c739a48bb6381eadb3b72ffd768357be793027c1ca1826067cb2a08f4a4d5e5ee2855f83df7cf34f165c088980dbafe261e5909989fb3ade1da5a9306baed1a636521b1debca46fdcc989ce967212e06fa39d3386e5311e436719436243f4784619bc38203fadde947b93c7b3c04cbb0bd5350bcecc771aeecd0f77dc442946308287e60adc73ad4a7d34045e555fadfc43ad9e4ce16e6be5a7a57c68617038d5dacece02287e649fc1828679ef3d91e06165016eae8a8ea32171df09cafd80406c5048ed5962ec6b204f4934c76a195c5cdeefeddb3822fe1d06c883f811a2212b577c104f918455538f3d2d4707677af4dcc3bc9bbabace154ed22fe2a25b61bbb3e089dfee141827d6199a8906619e8343187e8ffed51ac8474a93ebd8eab6546775f15cf40a13340fa46702e95bf975f18d70cf9911b7076feb346c11977f0380ef440126c760843e185d425ab00afe156fad9689c6bd2714d097c914fb4dd6b2374a9fafc7aac0c583066ecc948a8237549e64b366f019f533c3b28355e1648f9abc417c8d3237995e8b1755c8d4b0957665620f23752c4d7580a3d04af2a118273bd36bc99be998905347138c155b1f2c123267efd86375ab2acb5bd3f1dcc2723b4d3c488970aa55bde7c68f11c06a60a45b845c25d07690c0b9b50b138c5f2f0ec4dee65d99c40c680aa97ff9b74dc9b3eb87ef24a1bf12d503729b39e9f1c7e7cf1dd0100f626c23f6e6b99d9dd08dbd6b978a19b0645bb597d1b73e761dc619924fa36dc2d0c800b758b6391c78d3c0c62eb296d9f747fe64429c5fbd769410f13f581486fff58d9fd34bd84b4a5fcb0c6681763f70e55165ef2828ea8b178ff6d86c50c1fd6d89dbe23390408c4f24289a53f927484747187368cb80159131baadcf7695eb14045123afd59a64c8e2362845923ec19a0bfb7da6a7ae9d3ae5d235bc82a7aeb8bedafc37f0f1a9d8f8bfd2cc7326872220e6e55f59261d14ddeab01d7bfee9698c48dcc3b79912a9980438b2cef7108017ae0f8b82b7cbf69a9a17304e1b77dfcedd295df13b0c7c9e32574f45ebde0ab0c24ab3939aa77dfbe26448055922badbdb72bd90ca557e6ce41db021dce8600ea9b9f4d58eb2f90346a2aaf4c2c2b84970412c72fc780a2dfd918a5f0b1faa3f34a4988b8c8b61b9a8cdf1043a20ab167f9afc84d190884c9839bf3e348425d3691a5e439d82fae18834e11f8894aaf65d2bdbc10a68d71209abebca6ee2bda2be35031f43b2a9a593513c6f26f89efa2f1c4052b173ebdbf5f12fc50490ba30f75821d922a630b933a146fcd9e58e369225204d7a3fa3ad826abe79d4192bbbcbeb8c552d0ef47c4bd434adbee45479c5710b7099cd38913a2dd0f21ae8d8fe80ac6a0da13218a6e514d507c1ed7fe216207ed0a3cea891fb5bfc86a520f367a0ee86aff5048260f86f6466acafbfe552756e475936182853a07a3190a661d815ad3a4652b331b5ec3f1f89f7ec62a2efb46a749d5c2059ff5cb2ae80e7675e0cccf861dc9d02130b07237fdd7d4d3d418d9223458ce51cf0920bf90de278b69087df5ac0dee313541f7b41a4f30c40ea32423eab04e37d86d9f787276bad8e46c56c7baee0970a6ca7bb5a27840e60dbf9596b8e79f4d4a5ad3745509bf95dd03eefc945291e7d9f80621b89ed4b0efef5178ba91ca205db96c2f87fc6ef91af2f8ed7983898288916ee71b95806a9c37130133443f987af27cd9a79114feccf438944904edea17fe11df480c2bf427166fcf288f7a87fb5b988ff37dbc44e5ea39a2efcf25254952f291c1f5321d8e57fabb3aa1ce3e9227486bde8563aec5d347b38447cf0a4d286f528e6483d42e02dadc2097c4d7d74e026b0f7689aab74e6e1b272e9b744ce088c77c43c00a1fe9c9c2aa2dc898d202c660135156ce354f8c34a3eb81c4446b320580bc1225a042b2abb8b11f161c5eba720a9b53a9f5f331d8474b9ac4ecc0ac8fed692a902890ac7629043d127d7c435c401665ec0f06f905e123043135f71ed93bcb184dace5f32ee8df6be180201dfc6941f9ce66ad06a120984a6761e94460b15ae38f342510165fc5419dc44d7dbf612afd2fd0a19a0332079a0c200969d85ac257f36287a1d52c5226843c49393d559f3093c035f395606919a68f64ae41c402c6fa6f700173dd3e09231532f59a62e726dd7fd58a61d84ea11cfd3ec2f53c88b7b05c4906ca58a2f392a8c31c1e9f0d6e8b060976b6d86262824e51d73bd8aac63b4856ccc901563b15c59c40c9921533f0d4adc4b4fee8cea96886621ac6352729e44c160c2eb800f34f8a6df7ca1d1156be410946830f4920528c796ce5946df0b15abcb0a8ff67cb28d5a5a7339692a1238c58055008b2d13bd582913ce13ca07a9e560c23fec4e2f64968fa4184b2f6deff1cfeb002718d203c0ade9c9cc9356f60dbae9450424642aecb3d4200a9e1ff1961709dbef6bd0b951acda56886508de8d381e0994beb80624917e81ab459520e48556b6f405d59b8f26989c9505745fd8bedc89a5585c2e480c81dddcab8ec02c4c6adc7188e5c288f12839c5a084009e092b4c5df2c3ced7f42fb4fee0027ded151b3992c5d8dcc3f90cdd869d6f87cc47b99059aa3b9b1c1571628af6169239858f017a162a62c598247a5f2d94504b5c42c7ab947c57116fa9558da047f1f60f078e033a6c7c229e275935a3ef971bbd64cc76891e1c4f89310f97f3c4a3f2769cfca080170f0275f1a94cc4f4d16b49935ad567349513b826eedf94230d7dcf660a715937c007a80a9e3110c472892c0ea1aa8e6d3ca2575c85818d29a82afc10684d966f85499364dcd3ff50196fdf6930c48497a8dcea3daa48480050de578b154fb676f53971de91432bd9c2e2e540c7d0b72719a32bb1205e1dcaf5b942a5555a4a7811f60029e9f06384ab186a3c01b07cb91af69c8621ddac9d20ea2f35f289bf8ce1332ce5cee0c92ca6305506cc6d6cf5905cbdcc40e8e5be51bc767ccea4528b227d1134c6d0266f0bd395b0d90757b3c8fdf27d5a3fbf20240c48bb87cb2efe2d0aa07fff3445af7f99a25348c013360bb3452485a254678602e4b37c2a2aa958476268215c3b07b98721859b28f489b1583d99b5afad9908bbb3a83f41081ece34696c55d334b9276e85045da9f9937c54d40fba2af96533ca4a6ccf46224d91fc20884eb6bbd02d94c0c26711d2b9b1243d81bd5ee191b939ccf2523dfa1b8c828404bc555dc3eb07c3883a29ca2f4aab6074de0e1821ba3dcb0c9b0aad8df2913e309f1176718d29e638f252809dc124e13081a56a95b35063b71278e726aa3bac7ca8fe21a638b4d5241357d553764fd71162390f120c41583a5607d58fb8a2860784f93eaf83b4bebc96021a697b2524f1eb4fecac7ea39f24cc2216c8652cecbc153904dd57e000d28301c4f83cfa29db28c363892124030b214b3d5b52d81cf0df3bb1babc3ed122df6c4ebad5e2b9bb712640773464fdbe38a86c5aa6c56fcad6616932d81650296d1fcd798b3ca08db04f508725e5eb18aa0b6d2e1e1067ac264af3d5f969508d1d1529a7cfdb798bd590620ef4824e53ac3c9ed59f1bc1b23514cc73aacba211ace260ae6b0aa4e437787f34bc8f95be748b5347eb00dc74376ea63a18906b8cbf086aabb0c4fa7c19cf872d2ce22024238c0b608c95e24f1bfb22c3f07accf0a6d7faae324a4a6b1ee9385d62f9e8530417fc93867a0374c564c27e1265a24b278c0718472d13eacdee84a0961505df975eec7ed359715f124f8836eb94628dfee5ac7ac00ad5f46359d9263348842d871780e2af0715ed2a4f75f648980d974167fbdb4fe1b8a3d1addc3d7835f3d4bd7c78cdeba9e1bc9f2a01cccc0eb793d8f39849bf02b03a18aafd9c35d8ba3e396f1a3fda53a242ee185ecc3e8838a1c897c90b52802732d0827161f40a50edab641fd1951ad409557021d2aa7dedfb770347f4c302a2ca0790731f12b2dc3189fabe9f530b6f5804c4712f91ae2eb5e205fccc6455242661efbed57517c15952ac3f33dcbc90a3668f44c9040d51035b3e1950ce2104533e106278197539a84bcce20ce1becab3023ac864860160779eeb5c5bdf2915b4c62eeec8f7518555e69807275681c2d1472432646f437e98ead923623018a4068f9bd76f00018922ead47852c15f76995a388981fdb16e030d546752a51a5c458632fedb2c4a025104e48f5823fe0876638872a4ff8ac71a74dcf2606cb254706017d1a76270287858b5721224ddd9650ce3d03c77368f99678888a22b423cf11451440b00b151bfc955ca403e45ebc028a481f4eceaead87832cfbe715275bf4be7fb7368782c6fa085e3750e6c3495b2c2adbdae702f5bbfe1741f0cd257c13b06cb8244e32786127d82eda537e4b289719215cf818656e8fb61ec1c5f99ca7fa884520d1f3b48d468ac558b84a84584f4155706fb63f5caf03ce78c855403b768218d3e2940c323ef9c404b291a3cc01cd5bdd8d7d4807627092329c917df34a6fda09f75d67afb0d9160dd3ee915d8b0ce70ab81dfbe0f2101d20c60cf394d824cc09833b70bd594dcf6aa4e0d4befa1ad768d4b1a2f39b7f02c9479316a2a150d2d00b29b0b84a9c379502faf02f1b90bb095a429f174caf23b360c90b4131f38c8785554fca684089b6895ea579a3fdb13f5c257537ce52ec3d68bc741f6cde10a5d266449fbf7fe6bfc59a37d5728623016255e4ccc3052f2b301904dba9d0c865c329ee1257b286b231441977a380f1f2d3a859fbe5e55b1b6fcf1686e39302ba7b426955d411e9a335d265854455a9d8eed0ec09a0148fd56b6f67f1e6b5756a8e59127e45dceba1095deaef7942537d9325aa62dd125b4f49b04fa33c3a9977c49e4b1ee8714ab896be1aa43c223e2052bc77341f18d0d911a471ccdb9097c0fa169f24fac4be22baccaeab16c92c57c2deb6af621e1291a4eab4fdf523001999f556569b37afd3148c5e627a367b5fcb06871ed33c5dd125d6b5aaad477dd4b76d461c9cc408ec3b2753cac659f5cae9f391dd702cd4d4b761fec6ede6a8a01c9c0d9e7230c853ee9741e5281ffd0401b80569f7afdd0613db46b97b0f33428e3b10fb2ecb04bb1961ede1b76298ef9e55c22ec1269c628f4bd9270d89367f100a749e371bc1588c2844896240eddb31099f117ac621a1afda829530897dd093057f417a07afe4dc30022416d13b0ae0af69841da5228bc8da9799c8f5f4d0b784c1c2d32c7cb9190346c0e12e254d99783a66bfe95b4509b16152e75f70c28a3ec10da22967e87ae7c9837c9bd0175c0e0d75c325256c48fac8f45a04e8103411a63bdf937571dace33488366f7de710a80416c62aebfaf4bf1e6e0c7d14f2e0d4a130b00d33a00d847f5745e142211d690d8e653e3cb02196d205d9afc587a3584562b6b9a6f9a59982ab2d995bb6b4cf4365606f7171295bd6b5b60630b98593b1a18335594213db1bcea5c40bd7f42111c1941b0d17329563ee1d3e7fe541a921d05784f44ae1dea850e33887ffb62778de86688f01f35bc86634a3d091038f6268874d573feca097b999317a7d924ed699f5b620e347fb6d932f1e2cf00411878e137995c26edb57fa6031b40235882dc73dda848cfb60eaa68e2ae372d974927d7121086b657007a00f8e8a0db183fb46aeda3bb2606d0238384b4279523765af8f018c3f3fcf0104ae493c9b1389289165349bd18c0114e404a8ec224e97325ef98744f8a891dd80d7fb298f007d9bf4147891c592765cdb06fb5279a8881cdbf6b1d305cf82132e6f83d75d0f879a76bf8f180be28e3a6a52dced4cfa4759f9112f5b13df476980bd60b5a2690298adb83794c2d847aecf26b8c3830e5354ae79a09baabc3c85dd52567cdc4646e3e56f3deb0ed8fb36bcf3ed0d4a709628a6c93ebf89f2fb40a4c26b041acdf89d92a1011e78e5c7738972510df61fae3901b2086db7f7a9770584d0291b7e056b249e789659847aa209a8d54fa2e17d87a6be6dfe7366c0854bb768a96644f70dcd62447ba3b88db846ac08da2b175cb76aecf7d1273c806b9375c8ee03a84ee0223405e28268fe95dda81f62c823e4ed47c8c5086dba50d5b0d95808781498291c7ce912c012bca2b1e5c4cc0db4c25f0d79b996b1a033b2aa20135ce3f2905ba72d7239eb1a6fd4f4bc02cd90a09c727040aa5cbe8d513554dc50ca41001a46564dd68e7198c4ccfd24855a2b6ce9298e21a39be5d64bac3236ba423d1b6ee470c9f8a83081591b65a2acfb66793b0833f4633341a87438b20abb81ba09c00994db26e04cac2b50023a6c8b573a32ca44a8dba72ab4d348a8d6139e05261640314012e6a39fd0530394b7459d5a232fa275826f8b304fee530246897d312cf7db901f58fc3b358b16de2ccb895e0d9741025d224855e19e07a9e1035fa6775477d8588ff96853d8aff1ca94635b77e755e18e0c1d557ef72653e373c52840ee99686e5f67fbf5a4a27746f1d572a4455d7873becd21042d42f1d34b1fb0647df84805d2203b579ba80b2c3cefb70707b70c3fa876b380c52ef139676fe5b418f5e9d05cf5be7093f806e06fa63c573a2a5ba2adb0e34d0b2c90a232e3252cf4fdd442c5ba6681d817663a800c8fc5e4736023f628dbf44b64ed8f1bbd030a002b8500c0b4eab7fd818cdd9817c3ce0d3488396b2f7ad19e0a0b3f775451358a806c17897102c82eb5e1f6da59abd3506193629016098e67433a6cc9c40121491535719a0d464cafea4156405356acef1681fbeb9f20b91a392788ad97207118b10061a004ed45306989ac68100686f1c4abfb299308695d333f38626646263e4a3cf0afdb07839d12560ee64c55ca0d0d658db421f4fa81de56efd95087f6520922a03b20d84f482356c0ffbd69a81e39ce4eeb61a2450858b6fcfd48c1f1147c88a588f1627e27e383949c77ee8b4db10ad718210a1c3925b4631c108cb3aebb2931e2e3d091c700397b8b488379e52cd91cc1e4711902c98eb481f365f9e74fb6f56f72eae45d52d823d1057dfaac4a6dea29ec370e9c90915ee21ff1d4a483e15d6f07685bf02a1900480198de12ef570f301cfeba547050cdcf6f8792f845b999316f3a2ab1ccb66a8a437d8775f803f187a0fc9451d8166af3cc817638c2e728798c004a5f212c3b351063a7a10bdc0208d63a7d34c3d2c8e54284e67b0594219a5a948a8339af099ad748e7f2375053e4f89e6f888fb4de40a0b6418a23f0f1c2a23ac995b43e3b85ad2e3098ab81fd4c053a2f45f6f9ddf7d05c4c59399396dd22fd3e04178114cf3835fc2414dc1f2d8370a473609620b7b183b6691ce0f368984e3b38cf800288e4bf78acf135de61f5d8b1e2cb60134cbe421647e2897b6b150eba6c43d00d49c881c1ba8e1afaa2912bc0fda7cce70ef49b5f13c345adb0168b6d85d6c63308443ba4c8aa268c1258177b6070981d29266d1047a8fe897a7c82159e058e0b8489f8f64ec05d1032dc46482370e7f77a188b263c393cdbd19439b9579e02f918fa632de95ce3ec08f588ca08a7002962bf801afb16c4fc8287802d0799c13c6c6b1bf5e14d8f56a3ad446b03b1233590122a1183f1d716d22ec31465ceafd700161d78d7f24aac1b3e8f646b8a2e1b5c8e3e9d1b74bbbf175785d2ea2fc8acc704f0dcd3d0b94ca1d60b81580fc0e2e705d4de8da3c5853a14e127dff5ec4d34579b50f535a4e36fc25c1821959de1107b70aa695a4df5b49f35a89a7e4d462eec40deed6a5ad9759b03031c13e96bdcea8c7a92d8a22516b83fccf9537dbcc4e318f391b8e0a5b6b3cb5a8bddd915ba31aa445dacd9e3414adc8ae31e08a3f7b3a76112a6be53c0be318c12582bd9675ebdd2a51b35306111bbfab6ee284540410a4a8033f996359cb850793aa44384e3d0bb5fc12543fbc47fa6af0b368678a33faf3b673e99059ae75c56326625ed80161b36e3c052e7a97e0303901173c7bc3bf6172a4f5c26d8cbc03d49080020e19189535ca847fb339d32b49c232aad8e25bb80dee9153a9e0f6030137be10ce9c75232c10b56f651a45ec3a1066387b15a8adeb97cbcdcf49c3d761d91363e129472c0a061d40fdd82ae51184e758447854a0ac9e19cfc0643f24d04464cbd13415a2bafa04bed8db035cfcb433baca35124a96c86ef1b1bef76ebea1c49c5300ad57266eef751477ef406020a1c62e0fb0bd619863c0b5028cd62a1d4b67686857470e5528730644c1a64c8f7267d68ad5cb262e42b96cf6884001c4d31d0a505df99f08a4661e427754597ffb98abfaf3af43c0b8485d5bac80c2df4ea6552978e3efb916878df77c4430008c15fbcceeab92e998fb851d6de23943b3765a609c6de590381c4e1f69efa05045777fe9a36e9501621461a986cce5260721794ea07c985fc597c110403d88c194b336ae31bc69f65d47e74c4e70e1295ed58a9809770de94fe8ac0ba4a873ee1ef116d5fa1035c3c4a18aaa2bac3a3816812c6cb53c7cce520a0e0c36b87d44141bb76a57004450972ee888bdd8155f3b1e20f7fffc55e16992ea3890c253c73d7efe19040c8a060ff8a203eb9fcb3173a92321714c61d4bf345c6b48f09f4e4d2348987b0b156923969e99d4f735413e151e617ca046bd88e892c32269cd0bd6bb734413b9d2eb47cf14aae404c7333c7ed9de0b611f4dd0fef6011ff6ad484e8ef1b0e7784db6a068e00917663eca8533e5e3144daecf0c3513eefe557491962e312fda14851ccc3aeeb93601dacb15bdd17058554b935aa8ed9a4fa9223ccaa0ff9079e05dc1ecc83c395bc6dffdacb313c278bc0ba69a3cf375fda2c8c8aeacf340b93960ca19bdec2b07c763aa72cd8fcded536866c08d0ff326d3e0b5f28757aa590bb86391b5e6a58821b3fce0260b1f04266856acf643bd29fceb9a985b61590415203e874242dcce8053d17d04bb08343d10ecfafa530f34d1ef9a3d53cc09f2fe3cfb47aa1568351174611cb26292bbde017bd089058fe241ebd801c833127ffdc509c558d59117ba5a74550634aa2d07abb792ddf8aa5fd9e4cb9051b037710056e9730f968f5d066d2fa670c21f4e8107f4a2b2d10ca8aceaaf0790825d30e88e99aa2e922904bbfcbc26f02898584f9007faa9df49e1c6e3941a086db7a4f916bba99abf14272a31d2cf0c9aa21a67df59348c3152e2c3dc2dd4ef23c01c0c7364c926049e8faa8a7cc044de279578a08bfc51474e23d8b82bb6fd830df87d362202742d077272a43a3e53825a28d6ecb171dc1c65752c31f81f27e4c7600f90aaed1be333d4c7178b922088cb0c0861b863206fa3eea57cebdfd96075ae9a728bbe85b946f9bdaa31dcd25e11be8ff237ac7a64456b6b4099f346b8d751631f686863463e168ccbc27cc2f5acea0d224e0da0c51862629b77159a009f6062898b9f5551cb5221c243d4a695ba985f970b37ef9bce41a098242fcf9ae8f9238e670dfd2dba8755894c28f57cc02743530bc15f38e8b9ba538abcf2d2dd5546b244ffc061048583b604757c144983510483a9b40100f80be106f23b45d5fad77080d7d3127f873e27fed2da6acdf42121ea1dad968759ee662cda0c0a89d8e24ce844e9ea1b622bf352a030c2ea1aed4ad7adb94c4736123a9764de42e873f4b4c3ad3504ed0c4d909c9d750241d011e6fbbaf532d54bcde2f023c415b650401b5b5226b8e70354b6b1aa457c536271ea3c4a91a852e2415b503a0d2fc0e152ed1b958af9a04615bde329ce5d35e1be04a250d20f0c2c1aa00ce365fce6ab79937379e4aac4eb850bb39091fafcc6a8642e00d787eb04fd6f46fd63f55dc2ca78b56085556406f321f6d418f0e43f339c1b49fedf77f89019307a27ab98848ee8649a15e6ff0354d66c4efda8b97e539f4f302de5f9db2f2bb4cdc84a552f02aed3cca02a87aa3859055c8bc957b2f717bad937f41626b0e212247e2dae30bab7da47ddfa24879e9e245ff6bd434590ae7c968aedc18ee1a539d5852f498b77587dc7a4f51419f345f132b961a26710ae94e78e99f3d0bb3b9d17db4d1f36dfbc3be34ada6485e1881c8df46b1c5279f97ce05026208beb231685312e48391c167cf9963ad23c17cdba51fe9a36e7829e270d91975c2f76848a6c1bbe5b43d628fd7cf601f83f652f99bfec4d95fc748012193bc354a8215f9f84beda6370b1ef58152ebb6bff2d2980d9876afca3f532370916ff637930981afa3f9c86327624a617e67e997859af967c12e11463f135eb04577d820539ac43a94f122270e4e1f9ebe93b0463528dee54fcc423b67be2959a93c81d1f4c0660ef1421909a132e7f320c5030086d97c65cffa8561a63f2ea83f0ba551bdaf047a0a9b35a4685cd281b95386b1ec630f55235de301e41299615128892f0a1c8cac079a50170a2033f75aaf5de6270c81e0388db2821a6a3764475e9356c1e75a384ece5e9a73f9c1670c943e8133aea78be72f024b18f60c6ede62e9729852acf56dc0299e49aeee32951de46f36f86a85139a6587b908e4e527fc061fa50b8aef7cd9054a2515f828293c04c65494f352c428fda0728b36fda695d8a42120ce9b06c63b34a35573f884da4128842db7e9f578fef2c5b92b39be7e85d2bda367a5e5505277e70601831221d584c9074742852fb251481c93c32b22e10955818ad5a4c007e8c9b57fc8cc190ca87906c6555b7111dc052a9f9714e00740c5e12501236176907de5bd2287b756ff11c42be7e5a5d10658a206bb11410a18bc493d5a0158f613d4df28e6d3e0e65ac29894ae3a6f3c36e712c93a2634d0d733631c804f1909720de598e18382601e4445489ad746022918580ba1e34f50f846b289dc8d27e813e0e1af95007b28d4716e8fb8558c77cccdda72e30a88a35c0acb4a96a5a9096b1410b32a8c446d7f89163461e30b85c04ec0a76a824ebf695b3d88b7591ef3e3cb90c77ac40c166536519d128e886c8000c44aef897193c407bdc20905a1e3a868fa67a49a2299d00429ed5483ac0361434a9107a3736b9dc4ee95c97362aac47cc488706bf32768609b776f19b561904fd7866f44523ef8e52ba603a52f5bf6afb52ef52d063004622a874c1883edb3f05962d4531bf1b1c5a4a65eca03daaf628eaa7c67648cde014fe60e2be06d35cd017ac9e43f127e632f64aa0bd1abb1bf61668ac223f95da48ab2a1b7d50e0ecc333032c44617065cacf75d9403484290b0c1cbb2157698bd8a9315faac335164048eebc259296de65dd7d74f72f40a6ca0783e307477f1726a1b0f521424093e0926f79faec6bdb35561e9dfdf1defdbb7dc1ce2fe680c95effe5fe467ee14679573e727d178620a62b8a4b1782338673d756975279cdfb00242efeb116383378a30d818d1fcb98aeb162ff218c343efd6c9915371d4a192586837ffc0c1d1fc3d627c30d8027fb5578e1998b4670ad6a1de2db6441827e3ec900f333019f198c673440e9ba944b8c45eb3c9ab1b67b7bd14d988abb2ede22b618311525f037300b8ba50cd02739bdac7995c5be5220b955cd83c00b660339965250530860934ff9cc01b0d3aafa31a940a2a3bd900cebb6007a11d0943b082a6b71dc4a5cd602278c885ff4a5c059a7d4f2dfa8e8dcb9133dca15430c3c0a5f00fb51bf1decc4c2e0356b11c23ede3acea5ff0ad94102f8ee9b11212f3380fd2a91361cedc59766eb0a351c44e335037b59489cd4a1326689e47406a87a5312e4c415e768988e96a8e5d9c7bac761cc68603fa6b9074a1ba0ab09568b2da00b942db25ab65d5a10a32a46c9ab454201d7a7a14920b15b8a34e65c571034082f0f8dc2b921f5b00ad900d9dbb90d19ad3f7c2432e2d7cfbf9aa01c2b8a0de048dcb3249d5c6b21b15fe154edba58fb8793ebded6db67118fbbfdef18b4a5cdb4f4bb57d2db23c011512501684ec9822cb829aa0dc20d0811e9d45fabc7e22186a10ef6062a87541cfc70d1930a00209b12326106a4200eeb1495629b4b8ab26effa57585e60cbfabc7f4206342786656bd775c2dc4719c717c9d4b9b0fd330f7b8cbc5ec1213316169098d5224a34c387dea3e59fa04ae928685884fb286c5e201a245b39bd9afe9749db448d7882df95698696a5c11c9849c548590137a6e41a6aad9d6752e870b5e53c342a9a7af32487c3270a8865de085972ce634f9bd640d11e6554301920f7aa7b1f29d03bcef629b6f1744dcdd413209276e804f51f6db4065f17bfde52dd4ee4c08c970603d088fcbf5ccc1d2d7723c9cfa8e3d7f8d091868748a72679418a8cb623eaa1d710a4ec97aa0e00295367a6a76eb2e9836e4584ea46063dd8bcf112941e822a7921533a8bbd44aa38516b426b72927a1684ce3bde9f1a0d67b561c5a8469b209887f774961ceb734728f0a8190b21b82b9c3b0ef60b470fd404440b15554aaa52fc02432a038f6bce586c66c7b9bcfe255f08e2aba5bed8b98f6b33d0792eb25946e4c4913f635f3128be3d700f61e14488c7b36e8c33f62a0041e62e1ce8f00bbeffa4a7d11255bc2fb05d29b7223d0338986e0a1b9ca1b83bd07ca462c3ee47b36a24a23fe3751a5a1ee979bbfba8ef6d10e20f80b327494ae54bb6887989e20c6c7843f61639ce77d21cb60b162be99afad1d2b7ffaebc5840351b73444a14ab03ceb8b34a1be2c19965aca23021d3a24c9a9c2635ef916f758cb4531d90171959a675c20cbd645d0e1d95ebbd106584fed85fa18c2ac1331baf5047201e3b5ba951f06af543a28a53d072d8ba62ca52b292e48c68bebe65309526c16c0dba0caffe85384babe7295398fae735528452e3a5605a603dc36e24476a063c453d9158a172fa842b5233fc9b115cea2dac1dd736ae3efeb5eff8658332ada876df72584fa26fe600873c7cadbba04c51f303c05d1878c3233d61319b1dbb2389e7624675e064c7c28994fd1618065ae2984ed492d6a67d1e46402592de6d32a67bb4a7467cb2009f2ad30b5c5c8312a56a146208f4902f244f48e726eb4f8476aa0530da64c8bd7c10b266dab623738d4da6f8a93bd030c39abed2cd0a9658bec9e9a72e0b422c0a3418d53093520408f9f737d47a8e4c035563e8fb1653691143f3794221cd2f5184e57e1d2112b3fbaea0db097c1d1ad21e0be5180ad5c86ad72541997f9dbb34653428241650097cde24c9723c11f1675c961bce801d2cf0b9343d68ac2800ec338f295eb0ff6f46c0fe59cc8a9d8d811048edece804ae2b11f62fcde33af4536cc4363237c952e6a1f643097692c3918106419a2c37d7e2ce6f89d436e84e2656fe39d0addca8614f66a086095e10f8d2f4c8e6e613b7d3c7a38f392d329002836a225ef37f124fa730f6169b2dc94f49f8894413bf85d8a6636bb650220d0e1a3879bfa87e2d6fce2661e90e24d99df756716c178e1cd4bdb78bae0ee0ffc5a9dff56b7a245bb530359446d9d726747439a140b7cbe8d3131fe6095cb3a9a735ffc8b1f7e87b1e390275ac6d5678117f91b8e1d6d32f53c74801e65584d7b5c389bf9d5ff7551fbaf40fea5fa3e61c744750d2ece066e47cb11d07d12e4c40161ae00aa8270cdc3f5b5146f27492ee331b4806ce32fcd2afbfee49902ec07aa50e0ceed857aa1a220e43fc94afb7c69fa49697c04663785fa91f4570bc356970d0c6fad0463e7fdfd8cd263c47ae7f9e34fbc5120117a6eb8853835912a15a455a97479bd150ac51f9c4ba1b4d30e721340b903f8912e2a3514e34c5cf953f974dd40c9d48bcf27d678d7e82b578431b7d26b1bf7bf33240e7670077c2b32ab3ffca9bc8f7fb9419a406ce2d4acffa8206617118180dde856ee130f06805bc5a6b3e062229ad83598e2f494d859576cbae77ea99d831e256a1d8bd5902d630c280c67213307baead043334b17ba877b3fde85473d2f47c3b85e1fb22402529bf64f08aed82c25a43c1305579970bc71ea920f2fee17166f6a3bedb246e628de09b32fc66cd978644d3479d988b6b9e8708c4217e3e2cf0875646e418208087d5cc2cfd6d08cfe5a71319546de051a0066b9429e4d78c68de6a7ee0ed89f10e4d5ad1865a0c1a2cbfc0daf32296d2101e2dbed1a2471d7f5c32a687a3835068043922230f198c86f49843c2182c09450d90e4c1cdcc1f8e4ceb111b325ab61cddf22825f9ffa70efe23d490cb210f6fee8fb3d93d8f3d8101bcf73614ed9e22a6101ba879f6a24eaa14308ff60452bb2fb20dc8523da471032a4e4ee693729134de49446ff54cacc0a93777ee0520cf7b940e4ad04392019a48106ad60fa571d268927c29c6d70dd3cc82e410391e9ca79c385c3c5a981c284ba39ba3e9524ff3d1ceca7f79b5672638f53f42c62276b6cc3b958cb5649849994216b22935240bd85f46f9c9fa000558f0f96d82bc9090936698265fb28f44743676e2e54861de3f7c5d18aa71515f881e461803f74be083911930ac3e1eb78dfab53850e2884de5a7a3974c090fe1ad0477bdd34df1ebf191e2395aed7d8380d4472ad0525a0a6f899b8fe838516e2b203399159ab55ba3faac3129874d8a71a6735f93aa4d95fa10d5a1b2f11c5b4253f042f7ed444b346be0809b5da07063852e457d48d13ce6d6ce62b10d2ee1b4a452a09fb8f651cd9bf06e0d4d23a92263c03b570fcd5c596ecbccbb28cd80b29125fe1e1a624ece204a53148ae23f65b243e53864418052e2484d40c55305e51493af90c2234371878c9841632f14d27cd3cd11cb48a0b2f4fa2e53ae0dc3e82688d0f108e3f5c4da10e00611c65bac58b3a04ff308e8b6d2cb426e8c9fecd20d1b5a9a39b6d6db74608d96413b2f7967b075a0c270dbd0c701523842b08e114f95db1c13feebd4ba944f7f0abda761f8c3184a11ce23c6a0d86ebb7d8c16f5d6d15bc8fab86d1aeaa552bd8c5c70ba758c10b5737286ac1b2e0f602d280f0bdd765048034e00f8cd16fe91790c67b58c4f42abab41960af628ed1ed7d8f5c8ed12d8ed171201b806648ef6c74e9f7eadda5e7ef1edc6a37391b5a8c316eb2e3ea253443979fd0fca8cb600decf77e5106d101e5aa55405706b5aa5731a681daa52f856418b492ff4a1534c58570bfe50536049b0f83803a46066997965574108e2b6c0836f74aae5a36c39f9516abb8823ff007855282e294518dd6aa036394c27caadb31cc85e6d071ea3a9c5656a00ae76a39586e731be94e7f5cbca4978f73ce49e3bcc742ce8ed6e81c66d0b6aeded89d9ea3614e1f19798ed369e4a7c3f65122a5fc95198ec41cad9235fadabb7b0df68f95a7743f483aeddade3023daece22c9259c4560f2192f3422c5a25211613f579230704c4247f3df3e8257f2f66e5394588f8326f7e576081a7c98bc9b7a3a09c3e2f441fc5e4283fb9a38bb2bde4f226e2d1f316040dbdc4a34b63bab2e42537a23e7134b934a87344c8ed74730eead2507ab7395fa3eb675733294f920382e426975d074e9886e426d7e496d299ee8f0ea5fba1dd7cc27276a81f2b11f8ef2567037569aba494af11e74d5d8a44cd43e0bfafd192b68ae4c7ca8fb272a5766da8ee6112d457baee8f0bc2e424afd1a6ee4787ca274c427254475b45f2aedbda85e49003c2e4247fd7a1c88f9074d951baf76ce4d00c90c6c302d76745b48fb8d9517da9f4ebe4a6929b509efa880acd3c7dfd9c4f7991f183cc8b8c1f66a7036ff2f1a6508f9f29d4494e4d3693678bb714ea0af130c9493ebf9da4cb3a30c5713be9daa53d6e0893472456306a8b9d9c242992cb801c4ce74dbabc3d3b9de4f47979ee1a06b907403caf13bd459c3e2fcde9249726e553c709a3a43cbb4afd7c7343a45cd92a94fb51fc2896dc54725389299ae62535994a4c1f994cf1f3de3cfa4dc4a62ce5c93df9c8d49ddc0cb1491b75529a3ebabc88499a6e9283cd4f68e4f0f1a2b95ebad6dc10f595ea4ba55f5bbc94319a98dcaf74a767a71de925dde9241d12104f22ea4b2fdd7c7dbe7c7dd2d3c6b1cba7db430e88c6b23661291e793ee1117969ae7cba3a4ef8ba2591ce6293257559c748c7092301ebb34e8806b44a1e8b9f371a263edf604a4f6f9ecfae659d1071b0f54134a055fdba518ae93106b1100d885979967deb983fbbc663a57bcf85a6f4e750b5daf500223f67ed96f80c109c211c4fe9058438bcbc35e0bb1b805fc01142bc1e35da0721da87b79a141e0afc2e2dd8147dcc620627663133319c81373feccabc58ba029bdfaadf90de23207c77aeb6d0c22afc565bf8c1da13807dab2d0ce1b7dac20e8681df4a0b5fc04758e0c5bc04f500410a34288216b29869fc5a359f835f97290f0c3f6b1376a5852c60ad37ac831d34038c113fbb961ff545a6de97970de0010adcbf807669c1e6979718738176e921f408acc60250285087366543ee16bec31012fd6bc9d1478856750362bc42b4aa65b78aa4b04fc8d5ad969096aa88e2d0df148eed75eb56b7a48cf4dab5dad5f8b85dbb96d12bc618f3cd8c1b8e3435812c096deb521348a29ea6b68b833abd2fbae4d0645238e8ebebc5515d54767b28ba742a1e65bb53095adda2140a01e113a21340df6fc00dfab8e87375a6062d7777c38ab5b8758635b9456d6e32f65ff7ae8935ba61d94623d6ea963507441f62201a7784120c106ba41e4b7ce63af6d792afa108d43ef8d0d73037d80f405c031bd4304111e8d9b8a978812061792d86b8466325b0395ed15eac18748a400df39e70071ddc8f52c42974b05d5127dbb883b3bd11c8de086423509cb9eee5135d9a0b365fac8bd53099622be876c99e4c6c183ea1a80a12c511c68ea2b699ee180fe8e8e8b060e668d05ecbaf2ec61a31c61a31fb25e3556bb0f1b5cb39b8a2d4e8fc22235eb2d5aaeb8ab1bbe46377c5cb28df0063c44bd9ba2e29afebf0b235a2943562f62cbbaed59baf63d8a5c4640779b0ac049ed71f37a53cd63d18a3afebd8d565bfb2ecd775accbaacc32187b8de718f8525d17e93907d31f6488ec06b2cc0fa418587ec46d9a9c08c0b2fb00c442444a2dbd0e4737c77851b9bca397de163d7c311ea02628a6f0027cfdc9106182620a2ec0d77589affb32299617fe3c18dd0398859e29f038610709b80f85a006bbc19f4e83cdd69e50286f194153abfa6089b5b7f0b3aa56d135d85675f769e380a0f83d18ad04aef58f66188a53e1bac1247070bd1bae37a3b4bcc0f5e6178dbb1c026960e7b0fa6ddbb66ddb24cacd3a64c83768a6a78ed230efe47248ab614e5e2bd65d17e9543e425282aa37794bec669476f3b79b55f5f264188661b48461d9f66ce51a56ba34d9a948293b4db9c8cdddd8e4e61843aa2f54d41446eead553b866d9a087669b24b6a81f3950dc164165756bab05fb2f5e2d29970dce1e36ed621e3055f2212de9bc6f004435f28ca426b0a444e40404c8e0260aefec2ee4d6759e51b56ee4de34cbba9925fe7fea0c94973f4db27876035d35fcfb285b99b3a121744bd7669b48f7cc415b141fbdf1c63e56655cacd37b91985ba2457fbb56127c15e25be38ecd26f9b7c83767a393b9a244972a166a70f1ee9e41b4ab24b0e3975282695db2ec7c82adc19654d2fc7552bcf31707e4214d7c02d308a90959b63a8526e56fd56c86633199bbd34d9b5dee41b200dec26efcd403d1700d7bf6c80fc82c57669b42cedb5d3b5d6b6c32af17653160a893162a862c7d8dbb1ac4306864f797ec11c7795eeb5ea7414ca05a19d06a21ce38ad8b016c345958febf6064843db8ec2fd5d9c0d6eb39a95319f6570fd01d7924a52eba8926aadf5a89737c3e4f505783350af7ff20d06803426f06e61ed69afd54922e2b90711b72e4b19793b769b83abbdf20d3006f65397253e39ec2600694021225d8d20da67274fbb5aabf6ed76d3a6c5af4293a9761827f1d6d16f1d76ed469aeabd692cb5b8cd3ed1928dd3b4d7688edb6ecec12fb8be7ed334ee19090744f6ed9276a005d39c9cb66093ed71416837b7602de61efbeb0474cfbae7e32ac253ff36d3f6d337915bbaa6eeb5aaeb5ebb6437a3e0fadbbd76c12e6783d39e75f4279d8e162c618f0f9e21364321d08a86c93a5e6815fdae8932b93fbad76e93f0c1e8eed2e8b2ddabb3b86699375cffb20e5b83edba8eb6cb76db2a6903be76a35fdbe1479c8dd185b6d67b2331e91c478408b6d8620b22bc5d1d284cba26b2c5ee98c417e9be9091f14af455da061b1fafd54beba86a3743cb1151f146e282b09fb73547adf2b56a9a96711cc7dd74d6d190b6bf6dd33691de5ea3610a200deeda755225bd747357ed2237df34776d1acb75d2ebb57ab3dcba6cf186e5e02881ebb5bb6939098cb7d7885b97e1133863af5d8e43447cd52e4b8c3dd39e411fdc0653006964d7333d7733e4e1ae7bd3f2de74a61cc7fd7144d46f95c5015b4c918e9d73c0f67af310db6b111b57afdd1ab19e8edd76262e08edb5b4715784d344acc69dc4655ded5eddeef61abd43cfd2dd97bad16b446b73b40ae35eaf2dfb56b7ebd268e7be3dd714401a57e4fa5cb94bb39dbe3edf443804fd86750ee0ea4dc4daeb4d65c74eaac77e91eef6db611f75f95d81b16b5c10db69b8eb952b62c3db610a6c7270fd459f03001d635f6f44c3c4d7e7a81057c80379b69e9c8d1ab805e6ceddd404badf47a0fbbd39b8765ab7755c97ebb18e3edbba1cac754f08d79b88e9fb5be999219af6aceceeeeeeeeee3eec0b6f4e84b0079af6ec025e7777f783ef75777777f7834f0870a7fb8921f8e0bb945823f50002dfdfaf072fdc6915e461023e78acc52713a4f18b31f0c50ae02d13e3508a77f38b2ade7c033cc32870bf9b512a089fc0dd3f3f3fad13a363b9943162bc46c7383d4b475908709696b3b0dc36cc3dcb4f0d237396a31a66c6598ed23007380b8cd7e8d3e9743ac1bb70f191c36e04df9fbafc824f7f976fe0937425582ae5f02817b96f3931799d7cefbaae93bf6ee558f7300a97fce424cec68a8e0d97ac9490fcc4a42495a28242a1aed2bd50b594744739e950ad221909c06ff7f02900bf8b005ce36cb46c9bc477bbb6552c04e864ab580ea3db5ac57299eed42a96cfe850ad62f9013a9456b13c001d6d15cb2167c387fb5ac572dae5631696ae1ed57d408ac44062629a7a1720ea5dea5f5a24f8b0271fca09bb602cb96e015ed29d50a6eaf61767a300175a786f2456495cb20f80013a6c0dd6f4f803841042185fbc02c7f7866eb42adeac43e412f9008e751d78449846e40318c0450e3b918f3a073c1a70e7c5e8bf808799017d50393cdd2e18324c5cc402bc3cc6e103f090243b192f8258f9172c6cd03ca5975218c4037b4597ea454686e48edc7bba225726cb4c93ee467479871c04e60cea0a115dea491dc532a84807d7e517571d4ed1c1150c02855441b17c91c8429dcb03aac1664a29e521692b0448c509a0b0b0060743958f176a6160fb0f2f31e42f2858420acc04ab48458f2b2096365a0f9bb1706b3bb0195be1be5a18f2c067055ab3cbed912581628a88f7f97969645c518034fa0a53068fac90049b5f646464b4fc825f70d76757899a7d093a43815700795ab3f7cc4bc3e427f483df3bbb137805902f3dc0efaf0bf8651afc9e056541f8d10973f54b54420276fe229325d025a40a99120cc1fd1f82bcf84146a57a91b1665321fdf9d7728a0f3ed9d913d8076323f02e6143d9300b3e505051821f08d42d8a02db14c347201c4cec881c383fa1898f783d8058b8d9253e830191f7bd1c47cc1fe1844c63f88e9836e0670afe811d6e727bd96218a3a2d45a99d8323126878c8c8ccc21e3b122d8fc8472c4183a51d8fed8f90c96657ec87105ee1b810566440e4ab7d9740b595c81b3c54fc8c28aa7a3e9683da820c14e64c99eaeb27a624c2d7a0b4584fb3d15ebc1b015268431167ef7bd436ce85d6c4767886b613b3b1813741bf904c515a4288c02f2665c3b12c620213f224abb342a5b7bea20adeae0867ff747bc837d38d278f9d0f813a3b88434cca36204555c565c3d3126be75747676787884c41f21f1664197906c48952da0422788c63bd878394fd7052186410c831806e744d91f340221fbc1bd46f3388ed9f540abfae6667a8047ab60cb4aedea52d921ce6e264e657f33dce9f39350ca28237c29c01be2e1812d86e0fe8d161bd75da05d3acb2e8dc8b1014dca6c03dd11adeafc862ee081adc2232eb0817b338958c920fc753724269ed708217a1bd0aa3e2603216e7bdcb7b1ed7ccf033042adeb1d206a08f700423aea40185a0c454eea32a07773f4c1a5cd8a2ca86120243dc3db0c6813da58a51b442a3d9348279148a4934824686f06d4aa2c2803ca825aa5ea92c8b52e8bf4c880da870e92d90b7a221ddd5ad578cea8038bdd364c8402e78d753afd74b38e0884e54da68e624156ca08a48974163b82cd1bab3ecb44bbf42d8f65a2634e3327928d15391b221b2bc6bcf7587dba2cd828d4c551622613b9ae0c68e47dd22ac698bc4f2ad28ae276cc089685ca8076ae5477ad8ab85fcf8046afa30c08f599cb27c6a01e49a78b4275c99244aea9a3b8d4f5bca27bb48d05940de1cd0a9c01e12ec29ff1d466400d932310166a989c0165526c2c2d707fb362bbe247c95f890d9949d12e9d0169c1e68d0564851d1a69db02ab3a01794fc21940fcd242322f7be0c17d193ff4104ee1f88b7916cbeea5253f0ab50c41396843364696d0bd2ee7e546da22d00f8419debe117f50602fa1381421bc7600b71f1c5b31267b7cf469982b3ec698dd6c155db29e28e48aab8b15836e8e4017eb625dabac75b1b6a1d5b56a98201ccf147d3df8bc9ef2f15a480409d3c06f3128be190d216d95bdb6551d853c184df13585bc1950be735c615d1cc221ca99d1b02ef54e59a927248f1d873cf6f72e0eec149312de6ba80c0f46cf7b09dd8b155de2cfccccd55dacee128a2e430fc60c845d83d9c4eb474c0fb6650b7301aa25512d2f75033ffb50dd100f0fb4aa5f04db0f36d483a65deb7ad0f6a17de8bf1e40ae6bd73a7855eff5c96c93cf545efbf28d54d96bd3ba1e1642fc81896f249e58f7a2552de53789e77d51d9acc2fde8ac809451bdd0620a6d6b97a656d85e5d6878dd0db906e44022b05e3695163d70ff850c48dafe5ab60ebb833d8651fe4148698ca1f40336e0697df65d1555ef9e6c0f20f552e16815fc7bcd8ff56e0e1c50d36eb4aa9fe3c6ab8fb3511b90f36cd0679d8d7753f41053206766abb48318eb2e0c2f1a38d14203bc4637cec68fedbe8857d50f9342ef30418fdf16a394524a292516310cc3300c9392cefc8e35248a2e1d45ab1a8747ab1a3b0f0c7b7e4518d46918ec36d65863508707ce3b8f86c16e038b3ca04e03b5aadf3f30b0f915611e380d933b08f73ba8a568291ae6f1882efdd93bb867f35c8ddd4c71888888349df68108d378f977318c47bbf45f5f5ad8fc8ae0af7808391bb7614b6b83475fae362a484990a00f8f036f6a02308978f83783d38fd74697f7c7dde84ba30be929d130021a36710ac7a67d7b0ef7510b7e11a5b3201e563d18aa0703be468f5a2a86d2d2223154c364aa63d3b1652ca0f7b50abb34dd6b89b4a31348277f2d79c407372aa847ea2773a280bc9f7423516020f152425ad46afd5dd86a5516adc70b7d7ac01674832d0a0283f7ba50c73a941479c32f1eb68a5a0def7cddc8afee40231dfc69158d39296ab5604f116d65f16ab4167560df35d8f366c8e0cd98bf7e031abc049cbc0f9df0604842adb23c3c3da4303c5584104208f1057b200daaf323f599b2a899143c290c0fc65482a7126a189345a1ace5c1a3938e9472249285a904a7a156ad56ab15ee394752dda9155d1aa250d68eec50924e74e9119d568decf4c0fd911d6c711e9101ee6ba421948fcf67d210698844c2a26124ea12b54ab61a664811aa05ef89e887048ec8e0c19c86604e6778aa7e1e7902f7477a4e45a4d451aa9545ddfc12eb85bb51620d29b120c94e39d45f3803bd0277259feb4a5a62a12eea666a057e98de4cab3811f9b0cfb648375b4a5f0e76f38bbc2722d8229100ca01064236d3ce25b146da66f0660c01f74dd10416ca01b6608c3ec90c0f469386608c36812599e1cd8090467cbc145eea830763eb615d2409e40c7a331ab7a5bad48d1e233d4e45ad13d10856de637f6234f1e0bea9fbbd76da4eb4070f0667433b16445808b5aae315f8548693194e432e380de10e026ed12722221a74ade1cd60038ca13e802efd5aaf1e08892e1dfd69e207c317498a56354908a4213c1824a007a30536c31609e8410e02a9db45f7b48a2e7d1d2127d6043808905a6f8649c79458b075f2672944b2b2b4420748274867b5d243d145eec438bc981351bc036e398291c720ca121a92b0752121a8c79e2e42ad6c106c916e863eb00766884f443dc05d85801b098fab3f262240386b559e9fc7a2453126e54d145d842cd189a805754a3e2a4739ea87354259286bca5831460408e8b4d330f3ab55501010908feda13b2bc0d9b4537dfcc49b4d3b225adc5c9f10d1c9a6568c1161b18484863e73722da5833327a221dc276ab58a4c233af8deb8d724c2837ba6c40ac2fd9590902116eedfe8ae09e8cd68281d9c29f9c41853e9a7e4632af9e07b6376f5108ea04891c8894eab60cf8988fec013d18928bed64f15303c89526b51a85fa57a799191c99e61cb76b0a8757ad29f86adb8442bc609457aa88f15b134b0efd9b4e3838956f580507e4776b0f560c4e1c190c38381bbe7c1681cc48563740293b4483a1749e7876601054b5d2733c2eb0ef69df4f366401d520f1e8c4501106948de78757474483aa4211210698804441a220191864840b8df76e7c1802dd2102c6a9dde699eee31ed9880de0c6812c283a15978aaa63ff4c7b4f3d3f3d3032f659d88724674467662cc2bb14a42a5a112d12bf9947e808256425a279fd3cf0928c6c8191f1f1358b87a331ad2e819bc198ffef4a46e9c740ecdc28381ada70a7a2b2173b002f735140853f0aad471529e727150cf99b90cca551e8137a37271e8cda896679939f3665060aa4bc1e738e952f07e20026fe646e7ccfccda4e64f84526e0a47ea294fddd48d95a770a4aef2d4550e67522e900ecc5420e527c7d1fd9f3f9c4979f71cf88424ec60881b2693744e4444303eacae00d42feff6f84f5ea34930e8d1302b29f854a773f2d4734e9ebaa6d2e9fc2b7fdc8ddf148e95ff2b57eeac1c9e74291ca99f3c752700677e3873d81a42de543c6ce9e8e05ee9e8609892bf6f9d9ce51348fdde24ee5367b94900c1719f7a122cdd06ba47048b585a07b650def21e3d52bfef7172962e35dff29c19942e7594e3481de5f328276fb9382cb77f7052cf9951e97266b4932ed5ddd43cca734e4e9e3a8e93a73ee7c5913acac5495d5874510d6ea9f8d11d1e8c7e7767d0141aaddc115174e99f7c4e4252ef9fa690ba3e3ef6271f158bdd8c425d778b24b0b0c42ab162cc9b992909c5989c996bce11408c08d6c6a5c18911c1cecb6358e58898bf4e435a75a37164c29e5af744d42af97c229aac56957c52133879eaa99b44ea277f3e5374909290125050c33cac0e367581a478e0b4aac8b4d32a2ae994764a3ca59ed54a084b6888c8f260cb637bac8ffdb14036e8cda083cda421226c77484316050fa665f054fd3eb9f0e4f9a967947da62f5ee04c1a4aa114c5da140a75491c108de7ed9e07a38f9dc0ca9b27d1a935c273223a15bd88ca27a293938ba3c4cc0c1a15cd26ecbbf9d259411aa61d18c3948207a36710fd31a5a09e5c0a5bad2c6051d6845c5bd88725863cd007fd81ad477f22fd91f48742085bb075d2b309dca3151582472cdc7924845b0ec19626a46132fdd18454015b79f081fb300ba8056c55c1f3660cc59893f767132fe6e423670f704f1c4c19c0166cc1d60c3ab95acf4e8cd17c9ee995e98f6967fac477f2c10ffe9dfe1cc37b22ca9a909f51503e1109c1fde089a861321432e45d58c58896836a0ec0618b3fec1e86abf8edc2a056053783600cad15fc68696979b631798d8dc959de72b325b988cc53411e4be0e10c7b60616179b621798d0dc94dce7273e9a7e7925f194f053127ee90842c4c4c4cb84e444444e4befc08210f5490909090dc3cfa8bc6411454c0046d4565ad853e56608411589596a78249ac6cc0859e52ca9f0a721c1702a1382c810b5cc95150ec35eda3d168048226f66002284a5e6353323a3d852addbec6a6747b4dd3b48985203a88c3e93536a7975ce466ed26cf223f212121f90d0a93dcd35341eea5d7d8702fdd5a6b6f36b93952210c3dc2505252f26c23f21a1b919f5e72739fe4195552525272ad1d9d7b8dcde8dc4ba552e966929b95b082178eb083d3e93b4ef0e9d9c6bec6c6befef43c522a954a77c3b48f5e63a37d748ee3b89b4f378b000825b003164444449e6d307b919bb3979e4d1cc771975e9af6d168f41d2a787473e9660c0562404113d8daef38c1f6d9e67a8d0df6ebf69246a3d16f507874e553c19a7e7d8d4dbf5ebba67d870ad6ae8f1f32f4e0bc5d4dd37e83c25ab699afc16e737d3edbecc030769b1d2318fb8e936cb3a3e2becd0e11dcdfa182fb3635f5d96bfa36f51945a1e49b2b870526c00adddd404081164d00430dd2700219a050f00638982f5e43280be2193279cdebbaae2f68e10a58604190264a60051bac84702b2eb000de60958451901a0459828a266cb1fac114824e3602146823b8ae6b04f39ad208d4860048120690f00a928204978d31061901c718a38c123f2aa67882055404f9902d7d8107e38c6ba7cd3e28e37d82f6fe50f6ba10be67f859219455c2c0d734207c0fc2f7aeebfd7a0f855ed7755d177cf3665226467fdde8a34e6b28230ec69e6599a66599a6659806651c496e6e9786559a65b462dab54d4e8e22a92d2c6db4611e7c30dee785b1ed7141702308e96996bdb30cc49f6cc33c5496550c6f8a887af87a786f20ce0ee1b32cd3344da35ac3a9652d352dd3344d7bf70763fb86655996654dd3b40c428c83df7e7136e0b7ad8341b00d21ec28e785c147b39b3d80b3eb5aa745884188611886490a3f35886118866118866118866118866118866118866118866118866118a6dd480ce9b5679a06354dc2348dd6deda5faba8f6be35ba429851780c768454ea90b1dfe0007820a3acdb766d544af8a4dc60a4c293d7471dc5a49432d65a3129a5945372524a8e4447a3d1e547d888e36a25e9d87095966632df4c29f3a494b21ec3b07aec10e3ba572f6b9552ca3afac591482412099371fdb1f0d58007e3ba26a59452ca1947f5b24a39332989c0529e74c95d29a594b54a29a594b54a29a594b55659abacb256596bc56aadb5d65a6badb5d619a5acb5d65a6794b2d65a6b9d514a4c4a29a59472c67a28a5947246acca5a6badb5d65a63adb5d61aa5acb5d65aa394b5d65a6b9412c36aadb5d65aa5c46aadb5d65a6bacb5d65aa394b5d65a6b94b2d65a6b8d5262b562b556296bc534296595b2562965adb5d68a6952623262326232623262988c988c5895524a29a594324a29a53cf62ca59497524a29a394129352c62aa59452d6bfa7d55a6badb5d6196badb5d619a5acb5d65a6794b2d65a6b9d514a4c5eeb95fc41ca8a5d995a6b95d82525096729a31316da2c63564d276ae417045f276bbfdddc82b751d45e391bdc1f0733d03f61c8bd392456b04d0ee9f1a4c77b0331f78c1b229e74f32c629e269ebb91e3382ec618b939b5d18c73468e9b91e3e68c1c37e7dcb658b76dfbb6651d2d387e536dddf50dbfeb4ec0868931be6e744d7b932391482412a9723771ce39e79c734e6dd46519accd39b939a7a5ad9ab3ce393109236326719c73ce39e79cf3be6895f617ac5df84d0c63471c1bcb6b621b074494a3798d8bdc7fd32d6164ec2d1a261efb7b34ea61e5b8ad056bf3be55f39a165fab244c6c1a701ec698219e378d63bc9a0e191caffda0752ff0cddf17adba6a766531a228102cfca8b9b8496dd62bc618638c731e469a79e0863c4223238f0852417b2d19629f14c3aea8c5681f51f6a4ddcb7638daa5af619c8d6d3be56ce06855ccc15da823b61c5b778385e308d27da37bc1a86d719b5393afcac85c0f6328386a8c082c54642109747043133f8c50832eec8c9a6085071be641db6fd8a71237d7b1cffa61b3bd99507aa12fbbf8f37ee7ea270a1f4ce0be84c242c10448e3dd86018cb18437a39dc0aeb03e417ca060b5141a9c41bd175881fb72bb41850baec8125f1c3b8cc73e0efe472bfdb5648d27eb8195ba1e40e84b8f50588c88a8470d366344f00d615abb93ed1eeda876623b7c54b0727b1ca5343b8d163920ae9c65d7803805119161aed68d522a599285b1266bc4e258b268abd9b51af175105b1a7d9ec45947254d07a20fce384398867efe6120a24f10f4196728fbab7fbfe810fe7b41dc8c83b34c0f6f46f67eb60748a3be5944256de36451902cead1e541c186419c29ddd62386116144f3ea803f4a59dbc1588b6545c3f41359e03e3604cba254da4addb462b23022a286c9141ba2f1705b50d1c41414283281fbbab09e3ef3a77da05447cf1905eecf28260f6c9ec70ea7cffc993e14fb9950ecc0fed09fec4a2d7c1a86420a730abb73a7f107aed4bcd3879c4fe078f3f481b12858a03907148f15b88fd262b15f9770b07089cf9c07365efe2894cf7953f2d2206c0a36531c450b88e8e459e233b367073d76f698108bc2186c0b4e283f6cffea7a00b1adea24789ac8dafe8b6b4e99829742c1fe40eb01046bc917a43fc07eaf55518894efbe0723bf20b8e9797a4e73bb7a78787e90d133230f8f8f2bcad87392136237f2fcc61e1f11e63c3d35787cd4d89145415a74ab7b9eac215924242424b40283827a827a82540e7b523e5b9307ab88c56a982cba5b454fdde861f21e27288f3c0d33278fbc426221dd0014b49a33b1486787a7c7e70728682584e5e3099f9f3959f2172c1a6a9ea206d2321824626a917a6c4fa9471615492d7858b0e3e389285118864589ea7e74c7ded583c224400dd4d3ac9e66f5b0666bb250286b2f8a47081609c12223ba2efae0e9e191580e23306c3ec75ce972acfcdeee2bb24816c922897d051a81cdabf41881cd9ed9337b30a9d2bd991c0d338dc0b0940ececc568e89c91c184aeac42487119365048b95a355ab2982824e59078642423d424fe4306255d2294cd07a00798f79b02d6b002707848c41d2c7e6f8775fbf68d5a4f1e6f718f4c72962c307e3aa61deedf7786350abe22a06c5558e4150d5fd0636c7a0b8925726284e51a365de0c3cd8f984e21dec5d3ccf566bfa1011f5af15ea167505c598fb18d31df59f9d9dd64e6ba7d5d3304f340ccae57b9e8b2e75a347ca7ba87ce539337f0c6a986e052f06eaac7a740cd4d1f1e1d9e9418211ccf427136fc6c33d4830029ca713183ee133d32456ccf423518c71b19ae9471d2bc54c5ff2c49800f4c41848c5cf4c5ffa1860a62f81624cb4c1ce4c5f06c51808c5ce8c94ac18631a9ae9d19099d3cfccc362a62f5b31a6a4c58c077474767466fa53a761a84e8cd519c12a48c3441d212cf8ba47051856f871b161e6d530bdd33e74c762218ed445ad653126f6a070f46998ced3078aa02ba60882720951ba1f2e2e5dbc85ba2825644d8450b6e466db4574e466cac3335b3e285429c8ded1bd164717a768973e0cc25009fcfe60c0c7221a47788da583332fc6b8b88bf7bb6e0100006e504bc7d20dd161fae9735d8bb07b24cf02238d9c0d7a3b387305c5a0181483baba65b77b3337e8bb0ece5c3c65783c17cfc533c4b78dbbae5db07b54e3c180efba3773a3615e13dead74aae702afd2bd3c17f8944e86b3f17ea3068e43b4701c81610b285e1cadea478159f16ee080511e870e2ce4c669a7612e8ea154a300c9c1630540b88f337ff9a0238347630c089e4b7f0416054d601e0f46fff83c23d8fc84721cb1010f684f40a68a31da559d9ecb3bd6a13c97f7ab9bdd8be72203c3f3884532307cecab8ab70f3e50b903bb021d25fe22838927aebf9689ddc1cac3cb6869d53b4cbd7b95cc162f7d02edea1e047b7dd5fd440fdb37835ac21ea3507185c202858a43913524846e54a8a087840f8bf366d86de008087f81f70d340cbc3062770318188aef1eb1018afa55aa9737949f10218440a02e502a52c07af0b17e60fd02e5cdf605c2f858bd1a82450f7ce2060aa0c07d1c57000131fcc3580c11b50f8f15210feb06ab59a7376f3453149ca92ad39e1f70a63d414e5831597649cf3f8c9e65e41728a7fabce1dc82f363917e9019c9d85028eddaa1f7b2dbf25c9e1118fe0dd13ed71824167116bd193578336811a49367c74716499d56758ca25591c64bc360f3e4e1993e3ae63a3fd3870a7f44320fb6ef02b3d37a8dd2d0ec6615fb6bd55f64b01a6da6d5dab5d6bf87ca2cceb22c7ba5599665af5963f45279f39c199c61c009c2628a20404abec467503c1342a9bd8e96acda873e6dc2661844dfa27af1d2aaada4e4aa86b9218447475d4585e4484a49318c9a4a76848dd09388a96447f1b244cb7ef0e832b0df3802d5f50b949181281c3a3a3ab8ffde0e69eb9f60d885f52fec7a77b1b5ee324e1fcabe378d7fd46b57ab5088164a601eb85f3b1264af9dbd5e277bbd3d5efb30fb7d33c43e3bd09fb34f3bd0a7f306fb855d6fa6bb3c3beb80f4a78cdd64a2e167d7ddcd5f7f0d5bca22e0cd503b9ccfb2fb5a058520fc7043811fee48bb9b3ebdc1b05f8fc44591b85e2f0eceea67bc35f1e682d7f34d631d4d1f7ec2937c5df44e38af4decc2e0ebad3b3925cde1a5f38f73406ade87410c06da956959a761878f08ed1906b588f3fa30edb4d70e3b94d79eb0da25b5c24785486c8ff43795d6ace09bd6b4c80dd1d73a5a03b7788f66a7143b3d761afa8eb62a3b8ac23ef65a6fcea91d260f3bcb04db7f271c2f6d7a5343f4e1739fb62abba9f92b475e4a5a21841ca413521b68ef6918869bcb2e8ad5ee4da33a792d66999412bb2c421ecb2ebbcc018173711405f32ceada495d812d39aa44d32e61274fe549d73a9256d265ed28d94912e947912af684ad401862a9233f84b1dbababa7dde8308f0091f35a957fa84c8185b5dbbff8668ab0c9c13f544eaf696f95cb9bb57b2ab9b971c9495aa7d2ed7c4605f59dcfa81c75b34c80cac53922092552ae5de55abf248f5ed23dacd23d6e3b1091937479e4de34b63510c716155358618873b0cac539b9ca45ba9c83451eb90a28617220224fb938a9a7bc464ce970528eb3c467548ef2e626a072db89743f744ebe72958e04275fb93d8048912e07ab743840e881c83f6e08ee348507cea5df34d64cb714ed3c4d227597f8ccc90552a3048e1f7534373db53fac69d2e4a66f6b17c6ac9398c6cf4b651c694d0fda6b79a81bd125a222764dc1079be047859033608d72a7f3bec4beaa5645d54bc33c19340af6b5ea068e1c30d77cff9a140ad8e35ffa9ab6dd8839220e19dda1a28a526173dc1badca2afcc90a62e1ad59c1d8e7b571c18d5261e55fbc5c18a681ebd6df3496d7b56dd79c57d6f4a2a90ba334075f5dc6c9d7b7635dbeae1d469c20e4e76bf7f9e6ae0bbbb0d7dcac65d09ea43488ad59c11b807fa8ed92a70f7be2477658616703c3b13b9fa91bddf94cbd7edd2c13502f4e7625e85ffb0067a705bedecc3c10f89a083900af963bd05e4b6e16beaeeb4052100dc1c1b34ba3cb9cce34f6db6f9a54726d8422895cf234dbed1d7dd6913684e1ab6861f8ec11a7a4bea474ad344bafd1b51b71364a6f6e8892d468449594a03e3aaa7b33354ae0547de9225d0dc4dbdfb50cd5bd195266437ed4ddd410a5cb972ead1d8d0eec5c7675709790eb8b44631a7a7560268b6997bb0a21b6bbe99bc6dccfa50551c9afc3a2920e1645970e9aa2553bcd048f8f3703a3d13f30c6751ba5d34e3eab54629a357d8dce80a816ec4f3fd143b310698fe4f6522771ddba942c7d7b10a5bbe5e09b5eeab27cbd691cacbd3617c4e8a3dbabedd96d1fba0555a4919b5ced66f652c962db94d8fba77fdd0ef2605ced04e6e91d0a817a6815b6a7a7a7e78956f9b4962110be7a825a754dc1b2593cd60db7604b41de0cec9994594adec64153b4eaa25ab0419266c19a3e7aee1f283c9a7ed315a48314e0ec51978e751297ba54ffe11c6ca3745344608f0f02bb370777b95fbb8c838347875c10f326d3a8eb9dc941aee5610bda58bad7d5ef3b61164470888f07c367876559413f70b58259bc19f3d721111c025b733e9b458d4a1c3bbe4653fac70141ff6c96c91be36916698996baec8feb0fdc58dc8188b1772062793f50136f2cf640c4d8fd001216cb7b63b17cdf8c73d30d24c583f113bb8e020b160a8f0644c38bd1413a08a2410ab8e7e506ebba42b71498cc304d72d96d202e8aae7f8260bdd2e6265b7610d3ae066e81ddee6955fbb4ea89bf7faeebac2bde8c96ac6ec8d3f2dd123e71410c5731a67faa7833fa67f5f3f3a2483510f60fd8c85eaadbe3afebef6e0f532bd8edd9fb873ac1cae70ea25394ee2b95b6db3eadbade3badba9e75cd44f7b4ea89565d18cbded935f8228ca386e2c1b80eb3db3e7a6a78a045abb8ec1117049ae2cd90bfaef6e46913ec71b7110fc6755f409febd761146f4607f50ab77c77d0b31dd4aaab574db097dd4a761b79bdc21458067e545c6109ac695827bbacdd6423a7479a04729220357702052471020524c18d4e1a5d8b231b233cbaa921de47fe3ef26e1af77b7feff7752d7bcfba8c834defadac2cfdddf406d24cef995ef735f8248c23ac7b8a2a889cf4dc411df4605c2f753d45af3a08be4eab60e3b7fab42ebd58eae41b397da5678ab3343b13b54169492bbd2f2682be4b7d3b8a67400d4387a0cf3079dae51c9a3dbb7c033dac65f99bc6997bbf1fe6b4ee1a8809fd5304f78ea255175d6179692c957c302d5169eabad4e59b4fcec6bc0dd4b746094c0f311a9a1b1c9aa99254c123b1f6345942fd75025017c754a3049e27e96ae0c5d9981f627ee4d2c49b2e8aed7bd326d31fe78089443710f6ae42877b7345cc733837e18943437303713ded4ca65fef281a863b67c2feb0e90f3361dd712f95b8951539e9f623532771fff4f579b3c8b597269ee6be378d0404c2f47285ebb957c1c2f52d85214a05db410df3a8a84210bede53f4aa6182e0eb221c10a36f97e2121039589e1e872d7977f666d2b9470e887ad3b5be769c92732254d002b3e047451024e016862f5d5ad2ed7ca6244b9c7de7332525174709d45ffb208f53727ad96958cd160444754066b8eecf74694a361a5e62d29d5d8d1237bddd5ed8bce2e887bb3d18179d82cd6f45a760b3c55488bdfa553e1f7243f4cddc659f7b5f1aee35bf38007b3d9582a591a752b0d9f34d672b6fee67f2dce5a5e9d3d35329d8bea921b8d3731d88b85e97f4efa6b0147699c2ee102922e6e3d09c504a39651558183ea3c968b2c367ef7518e4284ea97164418328b67bcfd237e7005804128db1c36334d32abcbe8228e99dbfe4bd69986d5c11f0184e96cf010207cbd788d8bd694cb33f68b37aec66db623bc1cec7773385167647af9452a32b3bdf9712d34e6298e127969f7f2d63eba66fba255ed1dac34f76cda8fcbb06e547e7f2f5d2498e75f9f48cddbe76b95ee4661c2240210e722895bee304979e6d4637976ef2ccf2969696d3b388c877a86091e73e09c9454460873448c10e1cc78dceddcc7d7b36b90b172e4448484848429003277ca10da3d16874f3e823cf246f696969111111d1340d0426c8c3167860b90b1414146b2d8f343cd163c7b6a452a952a9c483073868f928a14c2613eae4e4048382135180c30889441a41a150a3d1088382092678c3c8b46ddbc8c888a669971390408639682693c95a3baf98830f2cd8a73cb39048a452a924eb60062ba8507acab3c9cacacab66d1cc70969c980082424242437734f792651515171e1c245cacd71074fb8431146ef9e53bef2bfa5a545d3b44e020ede5085f6ee79e52a2c2c2cd6da3888416887848484e466fbee59e5ef6e865678010960004be08355aba4a424c727a80d26389d4e494881051350a0305105960c52282828a55209470942d0810e4a27a9548ae3381c170001062d0e757272321a8d42b05a431555188da050284dd342e0c41659c081661a1919b1d682e00542be60025b2a9578b040052e0042692391481cc76144f87142099c8b6ddb46a3d1f5d38334583142796e71e1c285a669530643337881967a66696969b1d6ca3508210c5ad89367131616966e0d79425009f54c6262f21d26d884e3b85ec2154e98801b792e2121f90e134c321a8d200ea0d0821a462a3fa1a0a03c9b9e4f2525df61824b344d83e94114b2a0fdcf291749a552cfa46791d3e93b4cf0c95a9b04101be4400a7f5e39cac9c9c9f3f67c4544447e33ce117462308795d7d8ac948ef2acf2140a857a76f1dcddfb1d26f8a2dc2c023ca0610b29a8bcc646e52b4f493da7fc646464e4b9e5f95dd7a56e16810e135810b2b2b2f26c93f21a9b94ab7ce5e419e52893c9f4ccf2bcf2ffe4e61038410a4cb8414545e5d906e53536284fb90aea39f5111289f46cf2acb2b2b282ba19044eb8430eb4909292f26c937a8d4dea284f19793eb969dbb66792e714151595919bb123a4a10930a0a0a03cdb9cbcc6e6e4a9a3989e5127b970e1e2b9e419252525c574f344c313b670452a957ab641bdc606f593a748cf23df5a5a5a9e4fcf29141414d2cd720b5a40810f4e4e4e9e6d465e633372d44fb667d35db0b0b03c8b3c9fa452a9ede6860314427040a150cf36a6d7d8983e72d4cdda5d3c93de626262f27c9f512727df61824f5cdcdc3e43a0a28a9191ef38c123cf36a4d7d8906e7acbf37616121292e7ee790485fa0e138c6ab9f9ed61092544c164323ddb6cafb1d94ebae9e6d2599e5ddca4a4e43b48cfa69191ef30c1232c372ba1873bb460091289f46ce3e235362ebe9dd47292d3e9f4bcf24c3299bec3049b9480c20d5b70c2b67dc709de9e6d5a5e63d37217df6e1e9de499e52537db2051b1c86d767058e43b4858e459e579bb0d1211936eb3638449df618249384cc0c10c59b870e1e2d986e535362c6fb98b9267939f4ea7d3e9fe5012aed6a8848c7775454c999a110800001400c314000020100e07c4a2d1703cd164c9e40014001092ae546e4c9aa8491243c818430c0011000018181840800400c081084fb4470b1f3f48735603aab5a2082632a9fc009e744378e6bf4ced9762c00adc652fb9e593b2c09c7d94fd0dc2c54abf9ca27e5c8aa0f9d3ea243257b2510f0421588659eadab19cc606993ef34bb452939ddef8495179bac8f9128791e09925f920e968c90a4c824b3f9cc74614e76fd9c1753f7e52eab29f2208070bb6887f22197cd16ab25fbe0f0f9fbdc33935ea141934f06186897008fcc8140e971c5fd63b48dd930ee4879848ef2d445ca1142673666a8bc4923a459817254c104ae26a53482db9577df18cc5b112a57c1f0b5bb43e2aed8cd32ac9701a7cd2570670923a0fe7276e66fbf6076f4ddc4b87c96feacffb027f10cbe451fa55c151faa291f27e6100dd49acf6ad05d55b3c94b35efda7f8aa76a202044aca324662534c239bdd6bf65c9f67a53f8138bebd701aed33a60bbc83b18f8f28b8daa438baf26dc5b57a83d262aaccc64ff9928c20ca9c2cdfff3a95d67cbd1735b57e2a90a4fd70e89fdf2664860c7da78f9453356410c0ba6037c529ad06ee0e309ebf63b1a6ae2f00dfc0f2235ac62c176cbf4da15fb004039d319e3febbc3838574e682adbd5f38fa3a52305db1f9d5fd1b8542bfb9a82e827dfcf64fd9a0fae5b73e922a5132c7b2502cabb32d3d5c75f54a6f18b55bf5b55d151022f3b799eefa78e323f0efd14faaa4d3bc4689ebda09a08eade1bc2400c707aab6fbe15d9731d74eb53465aa9ebbcc2d1ede24bd5dbb91b782bb6875a366f397437a8f9bc0f8f21ab00fca4ea1aed4430c43d24300ce26d3935dc7c074f177bd4c22df00b069e56f5734c9b7de3bb14b00ba277fa6f49118d747dece1fc01afad160d89b054d09efdd3ae0f655cdfe0d72eac29dd5b41b8ff6bdfad557203d39013e5db5c33ee7164b6901cf128ca09eb2aafc28bfb92a31022da3d8e6d7b4e725103950082c62778a1cf3c2e48860141675a64b5817ec3a9466632b1ce4c46df84bfc39c5471ae05123de97735df98989cc64e555fc421e232a6a0e5e29a6f9ba36b1e5e54ea94373bc6d0f60bceef99d9882240b9cba8965b308778963b6580ec22d0ac59b0113eed5f7a48113e1902469d94fc6742ca77c309e5d4feff1aabc2ad967a8fbba7471fb140dd3a8b73f75eb48206915b5781675845d9c37b8dbe7883581567d99a23b1520497df3d4108a32f8e743a4408054a5c49f157ca7e5356a8af10eab98d3adcfc2bd5d5478ce9c2507d9057f25259808390d4f0cd5a852ee56174ff7dad683f0c2b9df24065d45f5694e046f59556e3d63a2424a49f43fdc3b93dcf95524335fc5d1b13d1911f0648f50ac41344d4f7f6a358664df752a5b6a2e82ff166436fff5f1dae96a2d7feb0c7719c2335105ee1f659bef2297b9b0e723477224ed48603d65e23e0c12e9c97faa6f5fc380a146d1ee943b78150e7ccd457edeaee0ae6fb68218f6b5e8e09024de76ff3e54acbef3e2bc40149392bd77e5a3b104e2d07eaed20871589c717d3311181759837d6e311db974c9358a63d40429f870454374f2faa37fcd8102ed9a95ade49988f09d35edba8050f34b39d3d45ab574edffaafba9bd8eb1efc7d17ba94a062f2f220a767aed0680a5a57f4c0fefd1f19bbc6f9f15934acba4cc8484321ff73fa926a07eb0e7f6232f44f07fe516e8affdc85803e970c55df0e4282558ede742f4c1d3ab3740a5f29b5988a6cfc03195fe78e4666b8c8417c91335312e0cfd2de2a28019c8fb46f174c7fcb61b55ffd051365758c7debf6b4b5a3b6662779c9c05c443977339229b9083621552259178f160ff2d8c544712c59e0a3969fe4ec250bf56714669f1e977d0f54f26379f1d3c6bdbd68a1d451b23d350bc4dc20796b608e6c0104ddee530cbbb3b8cb0f4bc7da9caabe4087e775e1ad01f91489963218c9faf8bdb4cd156eb5865a8191acc07c053588dcfb7e2cc673a6450dc70f778495b91a405f6406dcb49e53987c048acbe6d45e77380a1fd87c69f1ce4d07b1bba3218e0370670fd7b5f9c00c9d18bbbc2f824136a6d0a5620245850aadb247367e52edd5d92927abcd194f23b941edd985955c2c2fd99bd60fb2eb4098ee8b294386c7afcf800ecceb73d95414c64629c941d83556dc21bae2ad80db1f0be601731cb326cd1701a5cd8fbd177231100063c26f2ede2d53609fb82ef4b2beb952bae75065bd20796ac82d2024a3461056a3cfd49626888527224d95b1ce4eee78eea3573eaa8fddff6f95fcf6add53ecd2cafc8d78bf7971f04d75c7fcdf24de4ada525eb878b6d47261c7ae3bad1a3756aa21d128423906a780f1086e60301988da1f93ac6158c953484206d6c609a3b8e7c7608f613a15d77807961aee9a7b8990f9ab147ab5a6ec04c3fb5c0ce8d749c9ffa866a5d4da3efdac893d730e3cd89dd18211ce6724766ecc97acae202cb53677cc2f53ab5968c3f48d8b7362d65b3b3f016ffc1844f6a67bac1343e74bfe750c53dc4f549ee55ac614a3c7e78eaa1a32461ad9a461816d55af3008973a46291b894b3b0744dd0f15dd680b6b6e8b532f5ba9856b6afdd2fa536d90c834fa8a2ee770439ba2deb69ed5b8673a05504caeca41803e334c124b27aef4166b321207878c68237a123c38d3c410cec1990a258eaffbb8f3e5855b25109c4e6bd5aea8c82863b147c4dbe624da3b84283fa41d6de46f4b9eec25f9c97a31ff923a25767f272e8597970608d3c8e90d5858fcd8f5941383dc79ae64e25f681123ff6f9505fc0dd804c3ce5b13cee11a7bdd3a113713e1c0ffe472a4b364a4511971b3c65e0b79b414cd46b6c07db75a5b17f43c9bccac5f95a7787bee0412523ba3cc9ff65fcd6507f1c6e687148818e21303f66720d5067545fa3db4b4eb4591c14d33f9c2342f85e3c66b7a0ff1ef25b3452a32cc63bbb82811406e52e6846144f8f2bb7b13ea81501cf658c376289c127667da58608f61b99b7fc42d85d3cce03300533b7a69d29ad94a4fea5fee07fe6a29a5dbd7d4798188c9e3575419283c44480ca931a14d8855611954c90e2435418573c48483941eb012a58e0b8ae9ac5a4c39d2b873e8a6930a6c4162cbfe1a9a17920826ea6ddc9bbbc6fba35f7f6bc2fec2475bc22115377b683e711b808cf759b5e57a6883609cd07013d43d67001a763c17d0a460d3355e738465ce12d790535274f86e7fd14c72aac34397a415c1a4a8f80855079e00a1a97f384760d91325ca3e11cee87024155765e65b3b9a1f46ef214eab5df243dc179850558b26349f737d3456016e23e82613efcfa9e9fc0195e4b1af621e7220fb46ef3a01634d0d9c6e52d28656fa0a7742281ab30891268ce8452dcdb9682d41814b49eee2294594e5ce7bd5b6135dc61b180ac2139d850a0f02d0d59e22e60fdec22dff2b552bfb3391a835d6ce0310409851a20f0294e4a076298f2cc83ead43aef5fa795bb257bf69612a0a98ffa812046cae0929b73071ec5151c70f124d80cb2189258bcfe58c6486825cf80b219f23d7c3a92181847650a80c8dfba63093e79aebc973ce9739d09dc9c13b12dce36e5ca4a3b4c6719945c7d33798292049b83ad39a45ecef0d5e768bfe916cf918b8d19bc85631acecec63125c334b9c0f8e5698d9707b0c8352a665f8f7f751c57bded37369d5956f996a0aa4e97cf9aa0bdf6bbec7fbeca7d8c8351580a4ec4767b52473c03fa8454593c79f01798748df67fa5d015d104b2778432905e05cf4275663e507c6894fe1fb4635b9d627342bd808670ff7270c3f7d08b5e3ddb79976b350ceb5ac7d2f9c10f9ea9200ad74c7556a8d0618610368f1b33c1af390295a6dbad3d084835508f2209fedd208ccba1e0f55d73d162059872c9588ab923a5732a7bd54fd93a8b3a40281ae7624ffd8525181be214da6383ade2264a3c2ce45a0032a538693a79febd9dbb39222f1f2adc75c8d857f16f55e84bfa8331bc12d317d02ca14b52519df66670350992fda7be426439ed27bf20327b2a0453c14774726006fa738d1c92b6c08b1cb41f65b134c4fec75d32e520657147186172e7534fd3c28b9ba1e7f918ccf253833d09128383425ffbb085fcb304b01fdfd78864b6737f5ae905e1f2a7cf6c44af9a7d1ef0f7e7218623cb2f6123311be05979a6c30925c5448d5a5e4084cdc54d06d606ee470223fb45c94c620f550681e97b7f805d0c54dbad9e570cc8a5f039e8a57d5e6f778c96e0187661fd8ba1f355ffa2cb0e2666709a090dba405dbcadb7689e08d7d110c0311721c1fa886b84953987209c65d5d2cc215162a5c8924a2211a5e4c404b8be3619bc8bec9019092df6dc2bc723ed13ea89f5f2d794534bfa525e2d8dee28860970aa2c3fb086ea03ccaa9abe9092c916e4a2390248668b4d3179daf87e1f5ac4cc13645f6c3bd3b591d08be48b01f7ca2c9272821a5f61bd9207dc6e766289d5e2da8c82359d237bee3ac60f563b46149ff05a99b20917b0db9295f0787ac4da6fd4486178f436cd99b31f6ba9b0e942ff1cfa5ecaea6c63ac1ba882d78cbe33f9c5b7a17b75e495652698fbed37169250b733b878d89638c130a0e6ad08745d22288a534e38b1ee816f835f09d699ad9853d496fd33cc188fd835af2b5fed0a78e98db07ecd482fa67d626af11cfb5fc0750450d67fd5e4f9a73cf6a96a498b06087da40859459ec042fc1ad5092db99a2f5840eba6bd526b616a59bfe3113f77aee38b1aca2c1166580d2ef300f4e9e85758c48f92e5655089db2ff588dbea0d10414abec878c164ffe1c1da8e01a2ebb708d07f2f76a8e6542fb1bdf7e3d64b993dae02157c40a394fb2125ea296d40853c1ef65e1629c983f37bd004f895450d3860eb3eb94e117039c0585513628b2991d53a7ee8514511f7728ceb49c8d7509dad7145e87e564695d1f999d1ab306285980e67545f87b361c161a18e56cf625e80dca2d2734b66ab84a235911aba9cda185b463825d77db3456a4f9e1438b458149656eec62bbaf6a31228d8aba3c196a1326fd51b7d7b46734e09a4c43539db25841dba901fbf19d367f28be4aef7f593398b8f8e7997e42f5b47a30d8f8bc345701325903b72eb2358d0d1f72827dafab6bf641123de70d8d0bb6d3368558e3d441a77687c5871915f903f8ef88e30a509cf927531cdb53823ab3b1e36fa0a96975e7bd2ba7d562213c0b1e5d3e1381d703e4d56c127d8488c83497ca3913ffa28e1030411dc5e847857b583e6ad4be84d3244f8015acc96398f0cc330f5552d94fe1fdcaad1195d90cb15c2e8427092515373823b49abfcbee8c7af763d5635d1a99cbd96dbf3e5392684bb3cd3028b142c23ed450448e6b73ccc80bda4d7a3c7c93bd1835f109f2bcc05e60ebd20dc75f220437a37f2f66d25bd58c14550888001d10536f1b743f59d6f077c5315c2078bbe3076994157a79e396d8689b43529dd5830810e1bbc3a7b68f4cd9cf8c6d9a0482400bf06a6872f75219d9e823f5956106d904b5302cb973ea3f7dd71a622d912ab0b78c742c9cd7c96550d877e74fb967b0b3d163e50f5196662e192bdb4aab93b9cda272760202791cc6f8c1c3f6946bf3d8ce886c13a7036e1f0d19f99682d8c7b66897b19636f557f9388fb60dd2a946e553b063da6cdbe31a440b651024753a8c33c8a7cea9e62aed5e74c9ebda83b18a04b87d832eae9ba1b38ae2696874055b6ecf6f22a3d9b3d7cdd1823057e0b3ecd72ab2eddb5eaeedcebc925b1e0e89f478a0b8c06fdfcb84e1fe060e82f5a8749b8c1c4db29217c3f92cb9cd140c732aa0d957fe717d83937d77ef6fa9bcb2de758aa74736fc89d4b24eadae1f7fc0985fe0ea8d899bb02b1e8845ace320cffd5151906979bf33e96212f97180883f8359184a9140035b55d85676f70ebdd29b899189d4d18b83bb85c81026c5985a99278989471e194fb42eb1c4d51b13b65f28a087402b634a57bb138482b0e6f2841028b901f67cfc269f85dd1684670e6975432c5937a3782355ba9f62a61007a68b428a33e3884fd4ca36440859b97c37350ff23c0e838b198a1d716f80f9e8b513336623d5c8ac78198387c9cedbcf57ebb67b940c0113984ee1e9b58836a26fa87ea166c6420ab74845c77595ea34aa15a93e50ca3e24fada4e326a479dcc5e743f3281f490e46f87fc8229c1afc8a23ce7d37f93f1ae9da4da3688067cb5ab3801da45626ad2c495d63b632fc7e881bf6d528c21245308280f1099fbac8b755d8e947dec50454e39b3770a08c6253f8fc8bf15c97ce28435f0a75cb111b60f662441ef284fcd1506929331476d9ce95012e1c42f886ed4223bb05781455ec3eae396aa91ad59d9b26599d2fe6c73f480f48df33694f2f86d436ed3fa9d38f3c5e0a63faa76171e2f511edf35a32761e957c239a63401d63141c84fc0cdde42f14fba4a27a375429029d009584028d7d6cc9572d0de95d681bb3303d08edfb17f7395a74108ea6ebca770a77039aac80648bd38623e42dea98bf1b99bf7ac02fc11d78a2df1a85f88562745625eb900844e87bfacf77fc4d27fc901fd359d995774539f47c730676ebd8d9a76a6e4d9b504e23428ef9975d7edcc105c0987c6fc2c8bfceac2c39df534e6d0fbdd34f85c227c2f66d28757310d0ce972e79060d10586464b4482e39a3f00f35b5503aab2c9f09ad4b51ded1eec8cb14b945650f6321ea15bdccb14b0eaa682534f40cd0003d6da39039e59a41a931047b595241ecf8f9f098e144315709d9619179556bcfd36c6cb6c15decc58dae5a0fe71e3cb46a81884708523838b0587b39444061c7ff72927e4327c0065e5d4eeea75593a36499577e5fd87b8a4a8a017e2e74612842f29adad97333a0a0c012cb93e4d6d8dae252129cce5620eccbb0d798e225e5470f43653589eca3b56cdf2b046c3a6b0d27234cc35c85c6e3a2d26efa6d163b83a91deed57c6b564eedc0d4608d672be8d0d5993d1b286951d34eca02f5ad01ba0bf0b6de2a675f25943aa999a38b6ca738fa473a1daed9e912ab4e355178a818c542ba213ea7b5536b95cb8fcf2ad19dd5689880985e3b6baa6208673876e81cdd20dd0939124462c85983abb95a9d4e4e71d14195b3afcd943cd4eceb7111b06bba2e75f6c532dc5334c0fee8230ffb7e44d2a6e92c6fd3317bd4b4148da6a8b460f36b218c263c4816bc6c36bb8bcfe1d147632b251f11572affec9c2851a168527e4f20cfe84b8a7ba2ed488b71762c47ad231a20be26dcbfadd5825f199283d6eb5ab9d8e3a688de92ded9d979eef9483fa287eced9ec673c159fa4f8f8fee8b8dfe9b955ed9895eb761354378b3351a131da02dfb2fca34ac664c0ef0467ba403b464ff424943d4ccc105df284f3a40bbec5f2869a89a395ce08dee49076891fd4b250da919860bbbd13ce8002dd9ff3f4a51a857f8261d228369d16595b273b96cc36a46f2046f34463a404bf62f943444cd1c5cf08df2a403b42dfbd1f0c959cdfc1e5f61f345075552f699b0099966da068aede54307555af6993209c990667aafe6ae4aca2e97982f6cedb33b2d3927d3ce6555931d6a579f6dd547332a4deaf4dceaec0e934211fbcf753ef07c7edd7fec199df646dde3c87c853626bf7ebcf4c1262da31614295369443e9adcacc22e5d1be8390aeced7878388c5b594aa7b9be79a0291bfe2e4a293da35e4a5b8b7d2a9eaf2122cf610f6662e5280be69b88e939ea23ea5ab953f27c1b017916fb50124b8f31305fa5949e512fa5adc53e15cfd71091e7b00733b172943598af9a654ccf6355bfac41f47f247086915185aef1eb2e9e7a9a7e47fabcb541869d51bd91efe64be2dc52cbacfca2be5690e6203a0ca92217a488fe4305bc1049e8c2c3c72299d1b65f1bcffd4226909b0c2bb6c447cca1f2263cee57862348ba4f0b29efe6f69b457aa24a2b114b2e5d238b90b6e6cae73ab8a6d07cdac6768337c94d70cdf0efe696f3c93802dfba368cb7dd15304333f4e17c0ddc5b46ddac61edb5b628dbaf7bcfc4a45f8fa7e6be8eae6ccda5e7b64dd8e2a6e1dd3695796db7d3bd0eb7f49a85f8b456e9b3a82fef0829136a03f7a9368b99837ef07c42645916e973b4d07d269bf2bd4b1a026ad8d0e2a8a6c8fb48c115e6cc9448ef0112c2b2f58a6e910d65b83574d91d6d354e4df48dce4fe9e39f17312b9f1b83360122f34c5e0dac68886e5b9ad75b145ae12e479371bc466ea24ee7133b7c82e6f87885d470321023354b17c51180a5ae93837f914a74e815871abdf0beb1e7ff12c881132619c52c95d2ad501e4afe04fdcbc4a677eb92ebfaf7bb499416f64302caa0d295ac337f180adff0ef73b49c057e620cc12063abbd91037a62c03ef70c547dc84611a818795426e4ee7e892849fd54a1ecb2fb1f80d53ba04265b411a0cfc67f9998816ad74e6fbca620a8bbeb8ac508c7386b41b819857fe1653d40311186f3cccce72607a696243fe5a6352096ab731b22c6f6e0e940f9d2e187c2a6cab738cfea46b118ca0d432b1068f8d9311c64953a7cfa4d0b81e8423a94e39427be01bf8173a40e5225c4a18c6070ade52e8aba3a5614d458490031aec4924f8004c4763ef9f9d938fb371afb15d820a82dae4cd1c2dce904888f156999dd04a85584c0b8b8429288f87124ff5a6da3e7682218d68b04ff427832852917990f8bde7fc621c1f95f23cc6bc1b53ce52102d52a11cccabe027b0f142834dda9849bbf983bb3c23dba54339570094c0f48614cfe1931a8d2b763ba68c3c0ed7b45d4c690c257693defa92c014930769114e512966bebdcc1352a41d00bb794566d5876d98af6d9bef51082d863281ca318ce5fdd600ba18b525a6af629016cac2505c7368161246682857f682b396e1c55b692f7594297a542c3b1e7867adc0f77c4f8e8870e76a678256a85b45c5476de7a3d1e94800f9de2d1c4d223762dba9b58fea03f331554078e5026067c211870a3c1d95425f66a0dbba8b322b31e265d1ea572c05fd3ef910bf95724f3c00c9a04ffcede4438f14d570970861824637df6e792006a3b52f3b8e09b655e82d87fddc1fdfa343c0e8960c33d7836f8bc987e85948645cee1fc3aa748f7d27ff06864b60b1648642c835d89defc2588bfbded1fdddf6f51408101a40d320764c89be1f0682e5bbae54a6bb9d12c2f7dcb466359695b367acb4b6fd9d12d5f7acb8d6ed9d21acbe4b6746a2e2ca83c5e080775130050b491bea04bb7d6c65c34698af2e3c45bb3111b391492b32c7bdc56db36cc8ca84a2a3fe454d04b5166d152751f4b8d4d0838e4a685d805d8d5800766cb530b084603dd6d938b9ef8113b50d242a32683861246fc8ddd2334f693d6d398f3ef3680b8058f16293441d0fa53c9c9f09f0c02f53a13ea317cd2ea4ab22ad964e4a683cc349b76cfc05c9f5e668b9d6d1ddae4b5ad4014af6f57147b7c1d74a8f816f083099de56b4947696e6ae7560c43fd93fb84d3dffa0090eed0c2ac8e0166af8ab5ab16c368cb599c4f7c097177c82f0fac434beb2c09b0c833063022ed10ba8521cb080fe0abca9090170c04520b534339eee334fc7e43ef17ddb8e5b6c68744f5222607d727777428b1daf5d3a52262fd164d749c7b2b4c626af849d14f3a78803e5195df01d0122e21a4243dad9b740785d2fec5028fc318a0e009ac1657f53fbbf75662d5d1674f6bd3835baf400845546a8bafd5c24c37df6f66af629a5887cc17202cb2082a45481eace2da16e043380d3464c900c6706a1c52b091b03a92e62693b0dcdc30ffa428acdb4998aae20e6713f619b38a6f7f6257f728a38bd8cd4a3240369127292e4da2c5614a36a86874804d225ef1baed6cf8d159f4b2e9c433f2409a2cf8584185d5c265f4ece8f88340e79b3858396d41ca17457baf1a0fd01c40e799870edb47adfc2c0fe20376856aa043118518aaec2bea983491a2c90301432c42dc7cd4f124472dd2272cbf92256c14e954afa2406d7df119a1d4f1e93871353cfcb9e84c643a64ba95ba21a3d2417245d676a33914c7903bb8ff7f19cb5e8150a0882e28286790891d8973782c4c1c561fb26869ca0f3ae468475977c8a34264496649ed7cd5969b85fd48e14aa9c3d3fa40d70896ca2c0fa6b0680e0d509067f18c8c2d1db3064a1fb670c05f730288b9b962ed95d53f3eebcc7884e882613f71aadcd2a6504426ea10a2a7c105b2026440ca233cccf78464ad6a5602a8b7d9c39faef5bbbcfddf973a3c6053dd315099a5d15e16069f48aca0a75f83815c73326b181755a6fca7333e79af17bd882191dadb379771c13abd0ba58254319ddfe79bf472d16bf9f3388c946664d439207f81de447ff351e9ac1216793e8018ba85ff83807c5918d1d58bcccb5a5cf43bde73fe85a9b31f7db22989e96f0a9baa3ecd8b9f647f4d8849b33de3c664f52e2912b7440edf57b5614377a9f9ca011c22e1010794aaa68e151ef2923def4a3a6cf579ed33b6b3d89f1d6577995a02e6936cfd860d269c42c89ee0e6e7b5624c32a8df4fc3df6ed07d7483c5f72fbab281f47d2d88ff65eac2b0e051609464c931070f88fceba1cf4056634421c9589ba4837f936948a896058b278511705e8f9e840ff7db0f0967657e1fc5731ebca907f844f4ade22972972c9292a05919f319766be8c270c686e1359bf44fdf5de1054872befd044b19eb0e13c33c72774494bc14cf19fef732ce9a26ef0c913869048ab3eeeefc3ef3a9690691570450dd0ec5797fb42bd98d40e2e7a5ac9f69e948443c2dc20c27893d23e48f39b81c5cc69417cbb330e6b5e674cc305f03b951497acd2467bad68a49bfde2672048a163fa4ebca91d76601aece640543d68f49418e156db7269ea0d8df85ed5cdec021e99a4a0b9d11cf41bf34748351682df9e817f2718451efd95972136e776b907663025e5e45a9a64808ac278d98de60b356e763d0a2e249571fa8254b94eb4cf168f9884734c8ec9732a9ba2b406383066bdcac3eeb4880fccda6b6345338abeab3356245dceed651edc6249cac8ad0e69110486f1237fdc0a6aecec5306d89a745781a147046d4cf97f7e266b8ced6b0bcca163baa8faba578d6b3ef17d75602dbe678d8b12ee259331d46d40191af5a800b08519c7846645bd113f3c12dae7a33bcb410aac4335c939d73c74405a3293166b5112990f0224ff07ec8869ef5dc542357a38d4ac4d1f42d9aee3c4bdced148335247549ed680fb7a77892b9537b3a037a89908cc206825849a281943d5948e2195a30d4ecf9f28aad047373891ccd744c73e640ad594e1d655d2b7a5d3ce3c57ab939f07d21e2299be26944a9c5ed9952d309c467c5cc8f2f9fabbb8c704c5451628c4115e9764e93e2e1b12a952a43c4e1391e35d6f405cd1aad95c7a56d41c59344eed63527d5495c317db14a55d7536f28aeb9c244b6e6b630ad87520ec18b037892e842a6871a1a8a6280da1601394b0889a2f43dc5b9039e91faeb531eacce798ae33364026b00fc2dfc370e01d5f5f45866a47c005eb2464a65136be7c8258af5b80eb507bb92f49a4e5b16d335a3938910608efc5ddd6aa72dce2dc9f8d968b26d186bd316a1ac87adb7080aae0f76bb18ebadc672b35041a001c05341061ccbbdeb18d55cadf552f6363b117aa989063e45841e1a6e8064ee9c54d62617905765136d722253e749707ef900a7d3a1a75a2ecc0bbfb4c4f90c41f33f60e45eb1f2ef03e3e6f707c3081433f9aa97577fb9289e9fadb14f9a1316043c8824685360474d14d5cbc23a0c507caccb30815e1e9b1564707fded46fcb9a4ddfd76bede37da3fdfa062b451fc658b8656b09565e0defae402c388ea2708b0d322390a708e50cb3318be541c296693a413463f35e0ef7006c14506438097de1938db479ef5f5f8a238bc470f2308b7dfd206c643c1d40508c079b7d911d8974e9adc68b71f7ab03a4e882bb5c386de45d635953f70aaec1827906df62a4512abd2e987569500003a322f718e9b635a951ec34c02ff6719fd92f7e5d08a54f2042bec6c62dfd4f092662485f124794a3384283d63e8aeedada4faa348e652cfe22516e632df4fb1fc064ffb45a4b1388320a3a1cfae6e02e7aab1a2a5efe9757555adf4b22fcf54685e4eca535f50122b2f349bd1cefa5b8b4038120bdf1e51bd6611b198f3921258bf10260f8a468fae099ef265834e4614af17a415898e1f888e7f27b02d1642112370d9465c19b3ecaccd928ee638428ea8ceef7457ee5c9720f0e49fae0c86196748ebc59b947641806dab294716be8841f8babe8efe7584cbeeaec46b81670be2bcffb5b4fc98657d426b8c5a97cc4ee031a6de5133f0bb2ae39d318e722954435064c2f46f2d86f02fdb0270e80b305760068d682f585a581f17207fd14f740ea1203a71224627e0673a893cd48899d3f91745fd0a7d27f567be0284c79fff99d6029693b05b59cdb0f12a0194fb1e38c20700e2600cd00ce2a0402eb4db38571145cd00eb3f896a6cae247193470f75704c4988270771a586a95199cbb225699876d35420ba73ba3a6202147dc7bd84ea998ea1eafa8abf5cc686c48136c7647e98171fc5b4307910aa802c68d0283b2ae3118be7fa78697905318a0b860ef88bb20d3ccde22ac8af519f547050b236df131c83887e1cc03c1f41ac68d615105da02879222bcbd95f3e1abc11cd623bf3bd4eeb9f10914a791b84a400251fc47f3c068cbf4f05d8d10a515f6b6e2ad7120a219a799454e0a267eba01337ebc01133fde90153fe9c6ffaca3921126c097a2db4fc2004f87a0aae7ed130c1edafdbb5eefaac7a8baa8b460c41b688fb2c29805871f7c65132cbf6c1e4460849be3cc2e92feac30b4445a5ceb06d9795fbfd59b4de16b7eb10254f9c8a19792bf24cbb283ab7111f81ba34b63d3f440db29d06b5a7867b1b3a28eddfc5b44045b4e4f28cd99bbad96dd00af0de2e6449b6c07c0e34707c19cc585029ee931480a4953f6c99d177953b21ed95c95d477f3ef9ec25863ef0ef39cf211ce1e4dff1cc2c3a6ddd6179a9cb4800ffac77989e1a3c7b91fa5ca0f73401e6c39afe92666800dd34b96e33aab7e0d306e45e118ad0bda17efe03e800af010a4076eddda41d025b0199a4e5542eda99cc78605e95cd5a8f55ca103a56f3d178fe789c3189c1bb226aab54b1ea3117ea60208563349cc7294b50ff1df11e70a4725a8f44372bf99067a842a4099df91b40bbe94ee5ad499b6047cf6143e8188d50ea2a95c54f80c549da8baca4e4d0f69c426db52c18e100d77273d4b0f315014389f5594c6f25531747e3ba68b1295c3fa8744a679f53248916bff43754bcaf222a73b5b4765a4a0b2d5ff645f10dda85ac3829fbaa4294f186e02170c0e2371ed421a89337aa3d94df7db610e20a327fa96b97f91f7992ee0eb4c09b9d6b01c7c4210b567905a4ad193544d1081922b3cb5f4db349d180d96e0117205e61eda1172ed5d262b01d9adb6e2505c8471beed4ab0094ea2de86284bf804948af3bbb3d4d08bdfb33bce30742600b0b2f3a663ba7d036078c97a54f0c5c2293b9c908929316fb55872f3b1c42c5f005a4d6a4f0a212080c6f482be0268666e6de50e3822cee80dd3928393d5d8197f652240a3d62ab8d1f193aa10759f8e2deb4cd228b04cdcd33caad2b9f47397c151a136b9e05207fcab8cef5849b3d04255c45907f54602b5781a7adc3004a4e1cf1a7a119d097349afeb8b8e063c22d62de2341a21ed70fedc5fa88b5103a4341812e8d5ad4e58f290b6480170eb8e9510ae5aa75b32abe58141cc1e85ec6bb73616377dfccd0bc491ef71ad87c99db2e53a646778d748cf55004e0e601d3a89843cc3912dbac01a8015fb5dda5c7539ea28ca43818369dee6405a424c8124945fd5938efd9a337c708df586837d0487215569ff4b910ca3ecfc67209fc0d184e9696944b16d9c0096ac0082640b114edeb9440c3853d31de95f7e799d3f6499594905e139de1a3cc0b24c487385f53ffb0f75e3577106a2af5085d2a30d08560e61d336b490749546af3bb6af2c044c4efa2f2d471efe998df5666f16da98fc4cb9df33aa0bba0b4af87cb43a7a824e001b8ef30ba92ff5a0caf648899faaf2523656dfece2413b143c63b9172779a5071c2d29899cf58b907f16d4caf83bf2750acf42755c6c3ca51f4cd0985fa39f32c7a3ad120c6c1f6c8fe219cf14a6a65356de5f65e69ac0bbddc5b9b55006d125c2c3a6d9ea58d4cfa2a367cf01d3a5e14620a3b6f776cc0ddf861ad8079ae3a6cfb9dae4fc623b8c2176cd7c994e56ab40fbd1be1bde9c879b142270583780e87e1118ed258c6c21c8eddd9ed1800a61c110da6d5736f15d9a24d6ed6c9c863e34098677c0cf0ece1b16edf8c43f1a3475152cb71af5de0c16d94c6b3cda06f1f6ab6daed1345cbacdb4f94b39fffc6cf23636d3737f6b17d6725398ba07b1f9cbdd7cc8263614431eac6ec1731bbc056e3c484296a2894739a439b9ca3e32363a95058e3e88765f9e80fd08d20dd8ad497e938f8c25afdc5c3f223f2207c4478200f9867e171cd82a0a602ab70cf68144a93c3d702209b205496b2d4219b2525be95839e2cd6fe2879f97fd00efc9b16f62e284602d41a5ec8440ace0e4b298dfe10998f5385402b6c5cae0e9a0018cd1fc31cac23a11ad0c1bd1de5dd25ef226df1d1ff15a067948cfad43c0f3b94ab46238aa5fc1a34cdb1cf9cab05069bb2c65034afd41c9cb1e9a7a1910d70783e48ee9ef9f274e5f58ff20141e316d3792c2d3b4110ba3b70adcb87e7b270a8ad6cce120845551688824538319c55ecd04a9d155846fb8fa6ac1e5385233cd6a65cd29d1a58e473456e1c7d75d4d899ece8490c372316c32be2eacfcf8bbd68a96b3e0370cf360288934dd2472bfaadcc43ae42e6d30b854a4b834b4d5436b1b90cdae1dcda9111e2b0582b3b0578048db84ffab524054b712f33be0ad6610ff5967e073ceb601c6875d1ab5daa1d85e05c3d476b1d0bcc0d8ba90045045716a5f215ead76ea0cb498fe01c9426ab561f96d630bcf45af178c76466d0eada0c84d652903dd3736b5693f4f7d5cfe5d6eec41993eb96f081ff0430b5a49625fe983e817ffb95d8644a53691cdb160c48119f504606e774af390d0410903160ebc86709532e45dbb550251ab24f3e49db97775efc4a6f7ff3e700db7ae63555dad99da0c8463fa63530205cda78db466af2c9c8fb460d9a5dcab8b7dfee5710e9b120c56792fa84a9bd998b46695f7acfa6db81f93273101dd04221baf01709e758fa5fa3026d5a4bf67db0ea55d7c75a970a25030040f36bae21359481ab1ca611db79e53eb432e2f674e8aafa96506f5af633a1424595bbeeadd2daffb792a91f9a242ed1c3a1ad570c3b0c588b72a7b9b06ad4d4c856336db1694e7ebc84363aef08abbbcba0c49d570ec1afe4aa5763a4542c73dd528b7c0edc2c434d0eadbbe7152550528dc67e40c16d17d7927d8614536295c72299ee8e9f88624362ed141a5fec04ad7a527a6cd51fd3709d930469f9ea297d6869e545519d1390bc301f7611820b4ad4bdecd1b1e119cc04ef6590cffc8e9872c082783bb21ebe4b4ef5ac401f6856b1c3c01568e58b526f620b7d18d8e9d6aa7bb10f94198aede3484539c8ed93396f64e247a1b25642c81c107da7a4dd194ca85b50e1e6c252beb358f476ddee60e65512c8166934f8a74e07506b841e3754967b317f18525203584c4decf8e0b8373fed2a883263078dd60412647771035f82dc645c120a6042d8234a2a82120c77cbbae5c2949f163a3204208c4a90f3b5661b266df762bcd5609189bdb22ee311875b0f162054986165250c30f5903e025712cf6be28ca062f7b0ae3c1dca7bc93fac2a99030e0257442b06b2e965ac72673c0844bd58b466ac8c4ee02b58e98953118c331cd9d00d5aa4245b07ac4957b06632453531548fb172266d2efbb465ff88fbad14d7ba352eaf9a6b150954d3bbd516100f43284253a9c1104974cf90a092d48db00e3d11a49c320a62b0a91cc33a4c7840af028ef9f9e19f3f7a1ba32f4e07b365bc44f65a20585c087f24e8713dc29a11b3f77a3d529fa71457e9cc0d2727756f3da25a6634cb6ba943848a9eb159309dfc71da01dc513356fd44cafd9ce7fec70ac0e166e4bba18b61dbe1d1412319374beb43573992501155b99e62a5c113ca09f8b392c292865e8b15df052e801103c48c94fb50029d9c9abae7273dbf0cfb0423b7aa3f6e91fe5d67846459a7b88abb2885bf03ae01d3bdbbda997e2b4e5fa19978ef434ffcffadb913fb1ff929ed58c70c3de7453093f34d9ca22b679ded99e5c991682c11ce987c9da139c4178b02b00d7d33d9a6250e1ee3ba4fa284d0728efcb3d8e7c5bd4233dc2e9643c95db521d909fdd388a021a7518dbdc0ffd0a5e7a6e428f17dc0c58eed0c533ee74b1fe17aeadd65fd68fa64cc90f06fd4ea3cabbb965afa3bf7824da447feaaf8e698a0954e6126ad0f5c83c87a793022a819619c7026180fce8ba2bef6b5ae273f20d39ae1c2fa9e4c37810d7bef005e8894d237ee27a095ec96dfbc64f4a9b358d3175ee7b6e29c7888d7a298324e55a16790b0223e88b4fca677c69fd3f6c9de162d8ffcd1f009a5b8030ccfcd3f3ebce8e668a14af9d47c0e199c3d33a028aafd2102ef38900643c5a5eb544650e31ed3c872a7d66b3cf289482704a9a5bf23d857f2d95556fe40b789a66cd4194742eb38de3a70812069da80d33d49e3f392261906099f576040bfbce2efa14e66cab03059a13a821df43e4e5b606b9d69063a19b1f088d18bf8da0058c4de88e09f199e2ddadd1a3288326d33a39b0acaeac5082279cafcaaceba321c27d1074657395c862b641682be07dfb9ac1f8cc201bd8459ccda347099227d1ea7433a69280f77b8120028114a70eec243062952bb559f00d692098321597dcb6ea3dcd0a5c180b80e16ce6472a531d92dcd59182d6a6481f16136a3d1514dbc6161ad1be253976286fac768d12920ce54bfd751b1dfb7e408024c4efc716956b1c19226320a31e9e1ab37897786615c45f19f39130e9ce9fa7ac9a3cc1d06f1a2f8a2e811f6b41183f67e87f6947ed30694016d182a4e3844db0d5457132c6de50c73216273c089eaddf18dd186e6bd6fed8793a49ad9bd313ea1a04998df5b92efd2a38029f48e7d4d7ce18c8b6ba1ba7290a92f0873f536f56960a1a835ce4c95edd7e8fe1a08dc98a0623d502a063079a150a936c89858e6e3a629a90717c06a736d3719a9ce621ee6c2eacf76e063e2f0b61a2f7b605c5fe0154a44fd3d93d0c971a39ebb5fac578864083bdb1db155d94d2efb4f9479cf1e37bd7266bc0b1d1d42072fa49572970c2c1f73f1aee7cbe6f082b083838b4a248b929583d023f4698847c2695dae847ab80812440dce7bf5370f1fba100715cde9efc6a1958115e494347f43b601dc8c5d1f3a84b78369d4501433243b0b983b5242edf1dc4214a3e7a4d9777c323c88be6b325e012c5068b48650b399e3c476021912f61825ec84f08ab77f98388024bb9e89bfcf5648af3245452ba90a578a5b9d30b6ad693f34b780a118d7c027e95c3f14e0b56a2bfa9900d965158de5988d07f2797cfe7376f14dc8d6f10d6b1658b83309de1040787cfdbf31424e917eb6d2dc83e8396cf474640c63e233b356820f654a32dc931296edbe59ced879140ba16d5449cfb00ff2786d7032d02f53735e81f05044e9027ea3ed268e19cee4a037d155d19ca5fc707560b33d071470bbbd62ce6caae357e7d5ab3be722caa46153df00fd9e0e4d56765d69f1e1394cf881b7c3f1a30c9d310e4c1b4faea36290662c5eebc48776cd651c2a62d99fabde6e2d19dd5bb7dde270ae5f0fe85c673c8d26600a55521718a837d282284d3d9e90fec75d1667a1a8c8adf0800681d88f0fc6c6b04bf48d23a42e6414a0b23c61052822a826db99deb1108555f11ad745dd9e5cf892478160f2370384bb36170856531de86f5cbb4d60bacee981f35f6ac2b0746304f58c3ff810e088a2df29c7db6f935b530b00c42378b62a54fc4cbc2641e4a7b5ec82b17bf5f9c73f99761c446761015dd6fe64649168ad67305f85c07e85c819e2b056a70ad022d9b63754b9d2af1ea43e5ed25eba622008620a91ec730b4b7007bab65d4f287bd35484e5075671055e1d0862d1244d8dee1b5d4af7c6806e62e72a9b894e1159b05a1b914f5b6fbc2ebed71524832c59a445e9c61f457cc689a02b4f1fc742aa075b779ad45a2ede0686c66cd9d7bc20b2dfcc952d00a10a42f7148bdc38defaeb1ee44c75b686865dc20a9501eb90b469880da87215733835812c6d75321e9cfad613102689d87b8c262feac23486bd28c21bd3a08a4cbad7d6b43d98fa53dd70fdc15671b923595f23ce7281e03834533b7ee1afd42fb417dd654557f593d10e198f52edb8303919a10fbd52a40c33d08bbcafffb2fdbe51fe9f7dca1b3a9ca4450f7bd28ffd1bd30fdd8992c004dcbd64733ed99cf27096642142337646e05d13a81676fcc68331227b1303362e5c435a669aa95eb3b20981a57348ec081ffe4582f6681bdf92ffff6e72753c133ce44a87d1d16cdf377553a5981a9c8c182ac4250ae6a795034050db410a3fe01b07317fbd65cab7f53be18896cfacec7000d284dcbdd6e482e3fdf93b073c0e3dd12151ef71042fd3fe430b8a91075e8a11ef236756776752af9e24ef55f851eb2cd4425393d53dacb48cbc06cdeb99ab5a6bb6dca86ac75dbce4b67af95d5b510b8fc06f66c585bf5e84bab09653018fb651c4a90438efab63ff8348366ac1ce86df19222005bdb2a21893803b86a42d30b3a72744807cc912011307fa575cf9b2a2dd4ea7462b218d2308137592aa2d97f21ae5aae24066be57f41c3f511471bea618bc38cfbd5739d303eb7c68f5b85102ce1edaebebf5a02bbc60218ff1a5e55de66486adc750c0cc838bb62456b26fb6537182d196cadb57617df82ea8790146fba2b1e58adc8ad9367921f2a7e9e37ef84518e3f236e1c279f4bf3e85dab122add716f1fc3b6f43267a6fbe42ab15a5119e3f46797cb9a884d444ac1d64fb8d2ab1d6902cc2de9c8e3852407eda5a7f2c5e2b45648fe8354b38260ea6d291dbc17536f870c3808da12e9151a36aa463e4e77439cb0a56b9946157172dd578ad639f3699ebcd095d47091f6c5952e255d616c14aee3aa93e8e554cf7c2f71f5610efb97b683e8ea96b92db0d2131b9fe6f127f5e685b051b2d295b62611c633393eede76625a51f811c74471dd6388f2811948764d5b1f6a6f68b95f5636aa176f83c39aea10109121b36ac74d30be945550f5a0846c13ff3679d15ab4ed1b8569fccaa025326cc689c2682c6428ff279c35240610a8e71653d58539cedc4f174406b18c6f949dc955f9d9a7fc1053ae88e1fcffaec2ad369e078ae3dece0d796c80b21a3f358bc09ae07e4e809c3d2f2588438b4ab89db561284623ee75cd11f96bff2eb6609768dac5ea03d4de50182a195b5b318d1e244f0706d3f87f6eb21ad481f67b15ed8145ab149a09a5d2f8398c7c2bfd99d5c885752f7f17cbadbfe4835436b1dedde38e2aac9a1840c2428424aabe640262c23561cb84daedb05744c29a4e71cab510061c3ccfa55d7c8a441a26ccf6b0dd14da60e6872ebbaec4d63762dbbd30c88c45960485547c0390b98541df900ecfb4b77c4f391bf513bf2e7edc83001b589d45c92953538e9b32568240a4fef17ce579649c3ec41f3d6e0d2d37b06486a34b08a36488d0e28d6c1b0def36bc9a7c99ef56df40058e6c951f353dddc62216b60227e7af9e3865ccc98dfcd85c2226a15a467f13a3ef2bb0a68cdf04bf9c31f8c4367aa7085fefe5a279e5c82019c0498f95c58a89e80ba6caf34c4402a0ea8b01bf946a65e916e7c8b63954039f0591297bb692957325ce809f34c773423546986fafa2f49438abf42d32a513206a8d49c9cb26785507abc01d541283acd9ab01507ed7b83726a57fc3fcfb8087b87fe9129145ed4e2ef9468d58bba49e551d6628c24720cd2b29b1b47bbdc9cf61b4a8e9ff878225f177a4a2bf81f9012d872208a5482471c228c5ebc065170dc203346a07e6a056132ec5b816e293d8bd84a7b506a307bd07988f4505c37c8e40200c75d2cb4ab5474ca500594c9d03805b336426be48ab72d8af5d33f2909cf8a9bb2e9a712e233f305fd541e45a33f614ae8a768136b7ef2e43eb17d1ddf21d8cea920eef9c94b1ee41607dc2284b4c52803d3a93a6066db1dfda9ac38045c7b5a8202e6650a22e009b418a6d5fff41c776f936be6d529f478d5832335198f4534bcc91afd4f257497e088b0aba5d97b4c8e3d27fcd03a05c0893261cad54c2eb339e2426273ba02126f9ab3ebd28dda598d4725bdaec401ad568ec78c5c51f86393bacb8f068dc20c60b184bff1a70619c9442c71109b6c70f96477b3e62c9bda74e3a39b0919306547c873ee257c457e52dd47da1c1cd17a8d0f6f8afa04bd6d0afdc5c0ffa5d237a91a3761faef98737205dff25da2085b8fdd1a50e51e08d1b8cba0ff52018584101a270e2282dba8e23972c20f8d113f7fa7bfef41024e6dedd23dd25abe4a651319c12f10dc70291f0c0ffbd30b32872acb50ba4242614d3b4a89b40800d10183f6023e51d683a7baebdcdd7eb609079e9955f8ab8b5043d0881a4793f3013e8f4bb19d1841bea98f7721d14c99b1c12a1dd560c6d1ab0419177f5d17f46449daaca39ab38236ca9a28e999fb4034c3b4d42b6bb48f2dd205f00c54be1ffcb17f6ad416395faa3227ecc41284f775372306cc57605f64e552ab00868a1fd7334bdaf45bac5b7abab0792412af6a48198b58274ddcfac9ceaa916b4a74da5ee790bd7c8b7c464b4b8af8e3093076ec883749835f0d916d2df93897574287462eff58e1e51411d4ab7e51a5d7c532f26bb65e1008e6385afa0bc300b112c61fde62d94f8ab0c01a8617bf8488ffb710cb0960fe205207b50f6c190a7606dfe74047a426def64c20d8b40cddba1fa5b110d397793035e4db17e24158ec4626152a726ee6c974f06080377f3cfc279258894de369b8f976be7c991f48eabad59cafbd25e3678cf09781b4136a2543cdd0da35408b7397e2a4075cba78d197e2dfad505f35c8287a0fce2fc3ddbadda8c65127c58d7c43a31019e84184c2449d9e706b25eadca7a3a02cc5d0424aa78c3206c521c17bfd3e2e71fce4fa4f02f117efe637bac72d65fe015ea0aa2fc9aa4159320ad680a82af337ee80207100718075edc2f7f079270647bd11d257f8e13fea95c641fbf96d7914ae70fd477bd19f843aa49173e19f92ee27d169e3308d94f0c875c0e40a03f3255debaf3e089862e135c1f454498df79575f85de5f0b5ba3d3095eaff1677a3d14ac6fd4fc979168a725799f36618388cb031fbeebf7e2405e41bb53901aa4208a282a09e62493b18d814d9383cf3f84af3f306484324b1b7d97642e6b9f3cf450279a44be093be9af425fd664876576495c68806559b3e291448eebae04107ba9d17aadd5e102b96eac4b19c8bca3edebf41a285c3cd4a1d6d116cdef7e1a00d445ab036b6985e403e1a123a431bf2df9369ccdd337b409a9b8ec8c473d86fd82309b8cbffe2a5427c550a834c997261aacf813fc170eb63247f5425f38660381ddfc69071377c22b1afe954a207d539956f40301b385ef9430902e7d440a3a0db454906d9e840ccb0643544135969d3eef7350bb61b2619b3018851f2711a354292c1e5729eff2c5ec4df3c6164284582ae78e538fc8d892f07f3004ae1c16821a62a97db102f371d3b5478683a9aa117c5e759522518214867c6cdae8fb20dad7390c3f315600c2051dd1596146612d0112aa82ba70ae12a9490b53bf3da040716e669fa5754bb8aa9a2aa0753e757b4228ba48c061781d99138b5521269b044e2ac7ac9c91b41534f8c7c52abe9e912b66d2a715651cd788cc9daf93ebf038c4d66bdd081f816074ba5e75ee892bb4b42bda9e8d1bca0708459613061485d923c8e16f0505cca634f14af2456bc39a3ccdfe78e0181741a3a7c6a6a6b9051c79a0f94b8c1c1c2cb315eac817f6bd06b7cec72187d157c123761e24b03fc97ae441ab42be546810419a1cf7f980ff56a96b4a3fc812a66b9a66eb571f91e7c97c8f64632b6a388fc53cec90b0bdaf9d58aba7f2166e1669a4018c36d71e27e1046999cd92567660dbdf74159925caa2e53781ba59f77a347c32e8fcc8a0708a88afc64ede0896a2946551ebe15f654fe1774f47c225082c2d700fafb65ab846494df4e805fed96d3814b5fac46a501252b873f612109eac90170a8a37c346c7ffce4b6c4219d3cea040259301af8287b3ff6221bb1e804caacb106d3a10287dc75c7855d98490151b0678a64c0169cc122b7f4816246160631076c7f7d204738639e8a1cf8c81b473d0e763341d468f982bb8c0afb3b0b08df55e80b50b6cadf241449c60123cec6d17fe01922ecfed7d1c11be0a7f94fd14cd9cafa0b703bd7faa0c0ceaa78902df2b2d865f9ff9489a473f4762fc227df5ebabb00f4ddeed3e9813cd8132716a49a10d461297fc4e7b5ed6b6c927ea3e692a4dbfac54b6b0ea6876b1a8e0cd4c2f09c90532dd29a96cf480cfd84147f0241d0aad46a3d8dbc6cb718d4ce79c71dbb165f0df77545cf744b7e02372a38e04d03a9d54d721d3be911f700084b1e9d6dc58f116192e43a9d76c6c7f7bcd7ad1505d6bdbe1e5873ccf928e8086f88c19ed4507c6a41b7a714483d49589ba7f2908e1421576fc07d3b6dc0846ddbf826eb00d426b6cb5cd9e6ae092bedcf67e73a968b650ad2a5cbe1feaa970d963cf51e4eceb1bd8ce5f91a6aa4a0acb1478578583097c4701c4fbd4b11318e065312321e0ed84b55ea78cc4b08886a1589baf83d8db75e108aeccac9a8b98ddd58487530da5050cad58b324502849cccfaa66274b8b540f67d1992c0031ca924753a9074f0bb7306717944f8fe6ae1d9653a9f0205c9fcc375a0dc67827f6ad89435dc5a285fe3eea1362d8d80b154625ace1449a61afce10b2fcd0e68534377ab995e14060e97b9670c4f694f614b790037a2c07bfde6ae92e540fddaf28a54a057fb92d303ffa79ff72d939a28e4f90dfb139d685a513163d994923e189e02e6730f208e25f78477be8fa24ff3904e99491f1ec155a000d305bce48f92202016fe725b91c489958f64cc375b2095939c810700e70811638559d9a80ae5c3a5f918337e91e75fa4ed1825d0acb1659bc0ffc8d4386b1e5c411f06572848d42515735804aa0a1a455685c05087d2aae0498574928bfcf25027d871a2e04632ca59c46f0223379231c08756c995d5a759d49c71ae6847e81ed037a622d115032adc486438e1425d9697e0849808368707fcae80012240ea6ce41a881426194dc02f563309ce8048d56c12938982700bc723f5692ac7671e4252fdbf42f3cebebf24b62bf3f4db91a7999ed8a010ae61cd3c54bc9bd649908c6a824dc4cbdda35cf392ccaa3b7481cb901762cc4838ef58072480e7a144464cab9bf266fa55cf5298e90bad372abd417ba621ab1c8624f57583d737e0111984094d05852a8b3e035856b7d7a45c50258769aa9f189d7455537a733432ddcdc9fb13614ce11cd03c00c66e9806160664012846dc116684020bb297a61ff175c34b291366c3548f40f0c5bb514b8d71fc44534932ef35acf4f9aab4b743a61231d716ff9e455a9246b1c69bf0fc6d1f1ba735fd6d1c61e312bd1868bebad28240dd1e905e2e4cb1b7eb75252123b4e0c7693632fed18c51b04a8b84f9e6668ab0aa27c8741d085e9693d112885e28f308877f75be3975007d0b071de0afe785e95cc22ab70bdc2194f936e28891b929fc7c3a89c6864d45fcb222ec47282b04c19b665cb76106d629668dabaf20ae336a8c42154ba27c1d7ec3f6db2275d95f222c89e92aa6b0ffa3b18c1ddbef6f158daaa721e850c2875a3a8541fb39e8253a0e79d4689319967e4ba296c52a036fd44e45f579a1522235260231e841a960411f1d7cc0f4ab7b6fe44c200fe508a502765a9e29670c96a7e5b3175f1bcb0924021e527db567cfc601599979041e3961eeaf9d8452c5a5dd5bb11c63a149c4846842d7cdc02a65b27024c476e7424719f3a68090824a6488a1c1c1ed43de3d1429bcd912d8de7e70d74fc260c62d17ead864a9abcaaf95fdbc7ac82fbaa1ece04378b3012a05f45dc06b32f76e75066c5976ff0ca00769d8d7d03e5be6e9a8ea90afbe059e6ce0b587abbef7112baf6c047e274dbe7324a4027c1a7144e3fd7f266b910c3d274493a40825b8dad4a48c2ab10223f22abb5d4932ec9731b43c0f0f5e819020188ce276c8685bbbaea31427926633dd83b8c8ae01840fc29c78123aba32d556f0a876e3106b5ae0f0d46bdf9fedb8c399e3620fc53ea37ea6b30fcf3ca82885b1406e5fe35c536189b78acee7e7d24fce00b090f02b93f76350cfa2cb669b8ba32a164e858a48e5ab7246b0047e91da13f6966fc410f384721c7142a80fe203dda0df2e40faeed4ecb7c344333e5e4449f1e7cf03d6dc9e33293db2df6579688d66532a5527ea858f15b3ad025f1fe2b37c76f13935c6c0e9d86f48c81171f57b2f433b6c9002526e2752e7e76fe5aa83d9c2c1aa0bb0f70c1612695c970691a1f5d1a4c5e34a516868310a5fe3d463ef4d1db9046cc6abc39c5a3c568517a4bed44dc76e0f4ba0cb34efdad0959ed25854ba0881cef79a6916017ab416643b91102e8fa23cb9d0f661220bfdcfe86e1486ff4ad2bf2fd8b63ba858d446c7de1147091489b99f5cd08a9696887a0fb45f0cc05771535e7b12d51d3679e062402575c7450de0fde903a9ea5a199bb02abc115a361047868abb0a6ab2c897eba0feff86cc2255287050296778235458399919088e90b143e259b14e50864862d96a0753d276e3f3aa09f7f99aa01b63851412b4ec90c2faca468a86b32582cf0a63dedc7d58b2485497af5f94cfd46db962a9b95d58283a94e6a6e0becb57696609c22ed208ce45ec607b5f243a2c037d3dd0471cc05b7a0e9b5311a1060e97049336d6121c52b82cfa1b927f645368bbe88bbc0824ea1c9fc5f4f40ae0942b8e7c286a6bf9f86f85108db2bad1019091c995660f1ecab48c74e26c48bc124cd8a99f00787b0d1089a2eba4c863e4dca4aeee946c1f8a363f3a0a7d5ddfebda075671327bc27bffa8beea284b6dca9ecc44fe02125db74d8cd433148f4dac039897d47e51aafbdf87a1e4704acd3edea646bd8c3716afa41a9b42f6cc814e866d058b00799280d156cda9eaf048abf2652d5c1146409623dfd55506710e92b961ce3ec4a4f8d4960e0330871f471f03da8785eb9bc8e7adf0e1aeb18cefc762f488ada3062522f0c10f6bbd09da0d6bd3d70887f5727861a412d908a3f1bab46507b72360163c51e51eeeea810abb5ad5ab768c822806f77cfadec3e0a79eddc17447c0a1a008ebb950badf82ab388c40efaae26186d6b2352c96c5124c0a1bc0b5ca7a88a4d5765bf8d165fb5c4dbc0f6c01d52cadd9de8af748b5597429728c15008183645ca5468ecac9a2b029bd41974e4f527d96876c8ca2d6b852f6855d69b8902d8d68da09afcdcb2b8fc1b854140ae9ffc7d197f63e59568809d51cbc42a936811ba761b97e95764d7975b846995a96629111a394ee66ca7f860918ba25017963e3662e6be78cc52249e0f95b0efb93ed7c2243ac0d3ace05523283cbce77d90c03ac484b8222388f86b59e5373982ae5cfba287236577178e5b9ccf3021ada3fb54ba44a53e4d0f8d6447e5a64d57b181529ae4cbb68dd5fe22d624e015c3cda9754ede231f02fcd3c2bc471cad22647802f48ebab34a9e19b32b9043be11cf834c9624078424ab6263e130d7d58e6343f68cae2d1dbad9e66ef9e561143438d26d10138a87e7de0542423fd8f93d9e3446e3af9c165e417a122f5f18878c8d13b5bda36144ea7a99f3e2ca0e501cd8307ca2ebb0f9cf39de6e4a757dbdd61f1408ff4e9526442f487d0974bc50b6ba3fa72a24990920b6581301f82070969113e91ee55e4d63783fff2c0d3d332fcef8229bf051b22bacda9fd4f48963b8c976f3181ea2f918ea982831bab404b9613471e372b7b201d33792468f96c952181c1649ea655912730d7501e0664287a171da35046553fe93c41d8dedfe00681c69f65b96fa92dc79c7cb8b915b02f302b757805c38a8e545573022e187807e0b4a472b7df1b3a24d4b25ffb313b1228f582c5dd1962c4b9b4213432624d794e50ffd8b27fc49df5e54ab0595428d6a718675e7042f5267dfc1018202077b62cd6143f0f46de2bb01bbd4b04591cb2bbc456dd7c166ef0acaf479d5027185770f7572d1b490959b61b15a916650710e0bac3d56556c32bcdb7eee158c2798ac3e5da16634dd035b6a721e419aa89b210b0e582bbee783d57b565609bcf8b6dbfc347b152aa8e28572f032db229290029fcb6b97d8d7e0d21f6262afbcd7190b38620758f2a70814be20f83b75cf2c2c65976f60b13570deeac3591332b60d36c62fb679347994941a21cd8467e160cb142d061ca77c021450758f62f6992a61241f9129e199771df3384a5cfe61a92516351d5f51448d27c5c0d0915d1045e3735485333995faf020d3f8e18cf076291d31d0f040f3482835de6df50ca97b3abc145e4f2bba851e7a82dddce08f6529153e6e887ed40e59863fecbbc8830041440a0cac89eb66aac31fb1bdc15089b069618da0c6f55db7e72bb822b15b60c3e8aeec9ea393a0d8aaf82c9d267bd52f1c9090f225a5e77df8905c20409eba4716243a27fbd95482309365b363beeec4238cdf06a899cd49d4f2d5d3082b74586762b6ac7d06e97a2d3e923c5cfed61917153f9ca8544a744720002213e36f7618d70ab635b90a4b23569ba0e0a038b5c0d0fd9d6c00892467c8d6f7bd60583064ee6eef1dbb7a1c384b5d4f53371ad280bd91840a3d4a32558c4497a403272174f120f18e36114a98a0f1262b13b81e9a425f249320ee443dfecfab8d8b49b8c1f7cc851dcbe13a1b91a98170fe6f41637f4a88010d8ee69e3339e1797f24eb40154c31de2b36e0e58fbdc21cf07808e20b90976b74581a3385d27b17b3a83b3187b0e2279356354fbdc590f162dfc746802407a17113f8f8004a2512d4ab99d76b602f09a06941d92e0f14d0232ed8c67c9e36d506060a87ca9c1a6a297b0110098d59f4bcf124b86fb8631fcd635bd9bfb4c9b57bcd10cd7e690478404898cf08f5e27c4d855e030a9918c08aa90cd5aba15f1f1de0054ca59b0787012cc62e5cef9dc537b043ec14e42e466bbe042940d832ffb1aa86f87fb812c7098c499779b2882de7ca7fc09e260001ca9ec6e1bcf164ab8447dad4a518b11b0871496650d67d2f040dc9f647246c3b72200ade5c641fafbfe91b0480ee4022286344b92fd3a04b9bbcc8edcf5f72bbb44206651f3115bda51cd9a63282741ab2abcd25b097eaf80c2656a97c074a51ce5e2c33c01eb73f0a2622c5925902ff5f38f8a82ff607fff22e5449f48870a8914b6529891af4cc26c00f82851ef4a2dd998b303c3353276638f5402d40811dc5f3e7de25570c2f1843a89605061b661ccef45caf8e676222f253ce91f7ab85da8fe7bb5ec4ce511147d5c6921160aa482029c19f560f4fbcdc310433a10964c986420b9c6f205c2c400231c64865d2eb7f67a21e3a5e13beccc7c60a4b35ed34275244f5fbe75553f3b648a63f619fd9f43bf7cb2a4d2a8b0b82401fe6e803daba4e21583c03e5cd5d5ae25f124226919d40fc9f1d0b574b521797b412182d2747c911acaabd2081350473e819116fae52dbd2ca299cb32e8bfc6ea0e0436d3f1533e6559524ce5a65aed75769c60e531882d8e5921c51884c8a6e7d3f30d6d608ec85553330497656ec87c4617a6b82babcb37b4764e87d7d7bffb0d0e84d1fc614617affbd8a39a764489ad1a68779fda69ddcba0ee58a6894eeb7dfdd1cd32c580e83c942fe70e1871d80033be1305aea08fe6c2983f5ffe29f2ae46445f22b06cbf989b92f0c0264381d5236a3fba7398560f7cee634347795aa1bacd58a2565ba4b175431e4be53735272dae7cc5ee04143a42afb5ada3c4535653c055dc087b20bcc994fec26706f1a97b62dcfe4cf1c6bd9a12a9e7ce44776241732c1d35c3212d6593c683f08108ed1abf2e9347bfd228c380fe618bbb04e7a1b2d7b457fd756022daa06920076c49429269f4e6b6ccf2ccbd6cf06282eca7ab31160f32f4349e6581bf13faba484fc62593f78ca57c277900ccd4a027eec428c78b63e53411c2a5215088fbe1c0549f8cdcacb91e63e8366887b1a1442d91a73e4f05f312e3cf8180381317773ba00b2c20108388f824685b6bc794286bbd14de04dfbd727c4f3b1239e6ca98008a0e95a9a8225c5e8fbadd1581149cdff7b8491243a106875c68069a59b87d020c21e2f6ee031a24aa89ffcc1e3ea01738cf50d78d3d743e4a309c991ab9e22a5a6b5ade66bb23921bd7a996f149c1e4f032dd5bd581d019e8b5206bf3ab6ec79042da0c7880d08db07350731a1da77b0f0610b885a9cbd814aee9058e5e4f60390d0c6e5d7cf8f7229cd0851820101afda40366779888eb0b8114692b84d7f5047766b3bb6dd3471710ea374b46e4665363ff95e9f7e462d1c1b081ada8382da749d2e81c3be44cc29da620878ff103fdd0b44a545a32808e92d02e732271a18a6bfeed346ef2c1c9acccb3fc90420683d1c257a8c0686727bf28a9c403d101b8bdd1d4049d0a196acb54b4bbf92b65745a212b4616cdb74da2e6e09b58c7073cdd7509a78a57d210318364bb807d2770e64519aeb6d348181ce6ac76b0feeb43a68bbcefa69b7085a21114ca920979c20bdf9dd0acac7c77c4145693ad1af5bf9e72c65dfb52f0355715b539606f4af0b22be78ab2a9944eec4220b09a398463e67d887e45dc4a0b850a0dfbff4c00f44acf759a5c47772ba2eeb6b4c6c669eaf11fad1d40479ff960e2fe765065d8a2272ec25f230dee200f33d48ce7599f805e790edc105dfa3201ab69ef5eb92d406d2bb51685b4ec39168db086b2124f8449c780dc017725a1b8d77194384f2ce46c25a7e5337891ae8de9ae5c59c6fbdea7c8c987070f62926e16e8a970526ea0d940e41c3743899d7f165c1d310d0a9e331802fd32316425cdcec03e53b4f97aaa628145eea84f3a21d8499bf916d6876f7c12ad6ce414655d1dbcbab44c6b45fb6b2a5a10a353f7230c336205dcf1ce71b2ac3a40aa6d86f00d5474e42eaa2e02f4614714e8255450d2c744c416353a4858f9f92f868547fe65706dad8deace80877f9d88f86fc1020d8f49a0ae57ffe3953518151e9a1800f5730980e007d712e6e5dd92de892827d779dca191153c305ec0a60fe5161b7f14e3d06202788ec7d28710dde76f8683c41f84e239bb46a185cc62791d5d7b3368ce1b1eff86a50531e809701c6713990aa96daf03d21e43f2e21844b156c7c998b3dca95cd1dcdb3fc396e51d34af51c64bb2cc95009702e22ed9700307a5e474cd7ad9595e418a42b963bec30b9b00d4781360dcf1db50f7f39275710fbb393fd904a792585d5e551cfba28bb9c8df11a025b998e8032ea08654c4ec32582e77f152793eb591f8dfc1a3531cd54be60bc01989bf31b54707c4de1822e0a619d1d78df8ccc980d5c7207174b7cdc5e5d13958b5b9f1ec1789f312c655d976cd33a0a91aa7783cb11619691ca49c6e41b26a973a30d6f9c8720bc252d2b9576661f1f623884a68847d06f76745321719cc8a61904ede4313e8cda7279e232cdd86f47c5a4a3682da3c1e695e80292f9dfa34821349a0bac9e4af85ae6cd1d1231c7892e47cbf6bdcefae23a992c6151f254ad6b270aacb02074d19ec83cf44bde27182e31e2e1e95802c691a114fb628ed70ae40c2862a74c5b823972b2b07e9da14c7c2c1f31e60369350171c86626a0ed1114717f4a07e9f5b554dd423c1bf3574c69ecdd93ec8faa15149a8fcc7d9b5ba87f91c941b56fdb002f323433d1901b28be1d7b609a29ea6b257a450b06ac90885874036dccd69caee7cc27506afc087b6055b6b02a790e3a7c456f7877ad7cdc5300e35a5185be4a65e7f32532a084f3c89fb98953cf259c812f77c66a63f7ee0e29a18024678594d73330ff978e25f9250f94880208dddb63ac2f545446bc3b4e925677552cd5ae155a433631884415f3b2c90e65af4b0a8cb0252225b21418f7ccbd214352f67a857d7fcb212df17769167352298c26280540c1c26e93c0bfbadea80439634cf6da4ec1526072600bd6dbd47fdfe246511b05c60a69ca566fd64cc731d67c176407a6adcabdf3a1d54f69b630aa7f3c3a2ccbb0de3c0425d2cf20678fe3ee305dfd329e31e07965b2e68d99d89d3b851b04590ccb3f31e8c709e033496f616891563dd409428002a2af1603a644cdb82c7087985f14dad0e7b8c760a04733457580248af8c3b4a2698a93c6f0ec13463bc61859f198191cd7762688d25a458058059bfa0ab31012413adc781669f7cdd752a0a4d599e3dc92e5035ff77a446012b280dfe2b89b109a2cfc5e05dbb4d72b26e13180b69a2a63df00c38fc1805d6f4ee3f542f0fc949a45bfab64d946dd22907f44d695d70a0c17602c96ed6f6212147812954e032dc6e0a791713386bf08f8b4761971148f0d4a3c342a793ed2bbb6e586bc3f641670beb6a0b2717833ddd86e31b208999d74156c8cadb502fdab8641cec93b4f4604b30e4d0d040de69e03fffe565c408c1f5ba93615153012108257b6220c22e4b4dc9928bb423a8b6c78d9a78184a847818dc67223a8c8afcca8f0cc46f7850af556279fa41964b714befde749b7dc0e2a605c9ec2960edbf68013fa697d6ca557184004b64771f0e75d7ce301856d85bcecc8694653478740ecf115147c551030c9a66d1579936b6306f266ab21333e23beacb01188488d67d81f5c56430a497d0c515a99851693ac8dd405d03189b0979feac4e19161faa86d4ca008c1188b603b35ce95ee9bf746b8759b5ee95582b8b5e0373ac1eec05f9f5e19573c5c72cf4e3bd36b5c438926a19466bac90f1ed26ee3b62c58b28f9fe1e453538c19a20689d3428aa386d16c64627dd5d97de0804b564e2170dc622b81e2c011ba6893e0ad6725144275ccf99c69f308476a9389910a50548f21a599968afd6845557e37bd8b37e285c8837a154b24c9976303bd9182ebf59d88381fa5310201f89f710a6714af57b68ca779db65aaa157081012a7d4f4b2c2bcc0c7612c386d36e2b4b9df6c0a616a585a1e427c9da17c4fa3a3c80bd3077b13f21ad40d28e5e1338de77f690c5103ea23d42978cacac9e664e6f1cdba58425144c2b290af680cfa6ac1053d80c4ae3fb5753113aa0cb3d95a1b00563050054ac02604b8ee1647080975b0b36b4023c0bd58631b79942e034efe4b660dbaa99a14c3d7bf4054562f8d860bf529a4584acb0e7f70356efd2328daa63ca707765a4fbb346e0d89d2d997a4469e3e9c567422492f60a2cb58ab15d6242552eac719917d916b6d16191ca7adeaf42052bd72e63094206caf9cee79673e904dd4abe47192bd3c6a5c1cfa66e7389a18c54730e70b9fd68713d003382a2084613181dc33797705928601eb0ec1de8f760f77032dab9e4705653278119bb6f2537e5bc5a78d48e7955eb826c903a1d236c4968f275d5320faafa3a2ac838d5cc4ce6020b42a3c0258163840d90884a59fc370cf0b1cbf82fba018acb870c2a4a731d71137f4c0263e217212b0042be6b05ffc92dc1eb5a150fa66a6928bbb77f3ce1febe1b7cff0aeb7f4d3b57e53585d594d541bce8b1d27d603174efd42fa2ef08127bbd8e94e51fefdebe4de3385c070f4bdd7db96fd625322adb3de96625ed2eae1836cd2da2b04861e74e8527f084b0fe0a70108ab51e4d33c11136b931b374da2841e89152f9281c3eca124f2d0d287d23c36a43bb07eb5adddf455951a6699fa5c30fbc90d7e764ec9aa21bf59cc335cde241ea3acb63382500cd1b020eb0edfa460645b46d91fe59222b7732406a49069a8fa94e5e894393ef8fd91fd165ddaad1f18af4b4228010cbe42f1a021dc5faef88453d91042a3f0075d6a07bca91ad43a26717c525c4775b325c5ab6086a829ca3b5a77f9ab77af720cfab376a5a573e518d38bdb07f142c8920bb7da984e5907bee6367c4b67e96232c5298fa50e0238880f034b1f85411c8b975ae18539305003c70002b06f30534a5d1170aeec8af3368bdf22f2656aad842efc266e5b84a90b91f6efb334c0599725dd21555c69cf903f9db63233c95950992d023f772f552a27ed7dcc0b19fcf32dceefddce9b5d1c16b7d950a85806e737e6441b5dd590037a133657307b173d8f19fc3d862cfc0ba9ccc84e065887822823f2e05453f53267a67163197980273f3a9443e92b11e0c4156bdee234d97a1080adb7aeb912f6d1d9b22594a6611105c408ef6bf5ef834745a2c4ed221c7b6143d08c2c9cc02b704f7a0e58d330fde46933f07dc2a7cb094bca3b7f4319a640a8aa7d5320673edf83ce835ed80b07fb846bb034ff93504ec853fe574e61d496e8e2ab9381f914f9611ef5c3dba18a42e0db838855dd3ef12b25f0261616c7b38e4ec2c3bb33a961132df548e061b0361820aa5cf5ade3282552671603ea25e9abfed778a5998d53fa605b18cb06b498d42b1201240e5273fb68c1002d104ad22d96e39c7dc811430fa3757cde77cd789e34d213ef93fc3736d19a1fd4d39def8bc03fb22d2705b477056b88b9548f9b8f304190128e28397c163a62d49ec91f54b21cfcd9c818c707a50ae482e2ef8a76de391d34ef098a31f9bdce13ae90934a2738d6996d801adcf5f60c9cc8fe3e3da96b644ad69937ca3acc700b3bd898e981387238e316bab8d324e11b8200151d62264d14324793f2ef7b14ee69fb7a3a0dcfd9599cdcdf1b8a66e6709c0b5bb333338757fd58cca22e07ad875abb80dd948863af08bc7023cd10db760c2a0d1a38ed8dfea52407ea4dca7040c412d298945036fdb1cda34091328eaeb4f64dbd8f718f5f1f2abfadc0fc05feb3bcef427810db593c669e208f1d9b2b8e4f6c3d40ea7f12887711247508e78e49594c4c86e1f3275965a54127aab2da4989b49d71334fc0217d04882896ae7ff32348c9c16434c89cae2cd739d2364d0aea208a524194bbed230922db674f6640c16ce4b34ca84ab881e5be4a65cd00bb2975f652f42c310b2a42011c62ab237dc3707b822fe240f724589f5e4148804945da4934c1cd616266597e27ac3a3936c5c9e19c1e0012952f46a998b3a84d5c27ca32bc15359b10d47370b7333e798725f4dca139dd5bd6ad96ec25055dabc2eb771569d77b30d7f3cb68c732060f108b6cb8cdf7711e8e20c9d6bcb8fda2afaf251a9c4f3f1b5f63240f782535999ed62d4298c0bf7e982158d2e116642f54d1acc7defbb7c532db4263cee562a62698f999c9c985a93906e2e18be36b5b4a8346312c22f18c41ab7decd16a2ef8cee4aca8f6f3c7f46a1ffae967e166c9b3adef2114a5f4470adf74192a8b5891fd176665665e44115a0780dc041333ab6b00aa7c6327c585598a4184d0f2bff15627a61a5f127a76d621a2b7ce7839f565e960a83b8b31b9e8c2b518f5547e28d65f0cd1faa321c2ab5661087c0a10b711185def2015d8b51a8ec97b47debf0c4b2397fa0adcc9932e9d3a6da17015430dc6b00daf7b44bb4617b6671c7ae60da4f9c85343f8555b120f1cfb022aabffe3d080c63751c2de22f2217090b68dd502e336f5955b41523bf5de14f224105081412f82b16915f3421a707134d697b3d6d97238483754a7470969b443a190b4b7831f6045232b98f243238bf9f1463fd60fd0b14632724fdd29943f605a56e928bb18e0523e3d7941dc3c9d51713718963ae1b429cba62ec4f90b5ddd876a24d1301e6c2d16e8ab1faeb7e43280fe54595fcebf6b5aefc49c0a81cde8987abe38813fabc55ce452c6685b97fc08b910123ae033fa5a02c69c445cb38fc5b2239d137d0c2796d753244c380a1c81e2002613d77ca82677418b0d7964dfc9a1eb062554daa5ac792441d1b2e9f88b293bf8e1362a402e982faebbc7ad1c6a8dd5f0dca7489cd80fe8924b3f197f08ecc744ae0f547e2ed94e3a1d9475c16bedbddaf24d5c0c1a09f2834d40817b213e759249650010cf53a6ee954f27d7a1214d0b4bcf085c61b4b8176cabe0e29fb24238041e2f344de6e4cffc88f318aee8b5a0418b43c4278db78292af0217add1f21809a240f5b422998947bcc7b0114d367892276dfa9f8f6dd36ed955d4470c7330ef1bef3184d7b0ca2525da673e786da81a70be7453a4292e3e0cc1f30a9c41b8674f4700fe54845b86cba472aec1a1a4cf04d578940d3301ac92d18da320dad90830077a1d34c797aae9575a9a6c06bcfea1b309dd53b26ab18ccb820532feed22bdfe03d3ea80630f6d47bbfb04330094ee480ab6d9487f126e22e224c003ccded7b1435dbce9e37969d9332ee0a608b854ec714aacffd9683cfe171b56042f0cdfa5b61c7c76be77f6120096c7c1c7a2d3afcd6ad240733b9bada8d5f43069199fa018d1ffe869f3b28cf6a8a1d4cce6fa6419e5f1863eb2ed1d2fd56f4fdbe6aaa762371cfb0dbaf554d6feb487636d9386f1eaf815a0de862b43044ca951abf5d3fbbbd5e77ad08477e959a4a85e5be45c49aac9609b0c70a025221e86c0fce8d32e5ce8fe994d6f3bd704e6f7800476765926a6fc15dc944e27cf8d9349bbc86bff6e3483ae41d186d7b19cea63e59b95b82f0dcc9956fd32dcba1f680cad7969ee397526b3ab6467d02ca8b78d669ef0c372704baba281a5fdf8cd6c347e6e073660073de6fcafd038dd012c8a250f49c9d4186ae81a8df5fe8969b436caf9343c33fe37ffa93bde53e7dc12607141aba668e5f7aa101ddbe11d342f79c4372a472cdca2debfc92339818dc937b0071f5116f24de56064a1cf3ca1da3a3d97c3ffb7c35c16b7f036358cf0c861aa177257fb28b225aad1b3752108fd9c859950cab57d376cae550d773446584266b0fa17725dc3a272f08b3cc56798136cfb19fcf87b47e31314335e82de8f544ce587ec0869b2fc41b70ebf060ee85bae6eb335c5cffcf7ff27286422b0223c718fb8c263c7c96b2225d284a17202e0be88e725e8ff25aa0c361ca2e12a8b78f01c3703b8e17ec87700aa44e69c611343ee0a5d838c83a983608401d51dd760efc4bd8eae6f1fe7a9d2d0c00a729cbbdabc87a0d202b1be0b3e6de2548b38844c061c92485ebc4899000661a60106df8fb442850f97a58718a3d2e3c24838d83e024111296e91dd0c4542f90c073049c8c638b9470a4899d41f207137f1bea835c3f74fbd6019cd5ba394d3f60a5b5be5f762b7bbfd1ee3b12e0c5f9625533e995270be180c6fc9f314c6ddbb4746a6b6b9b719ad39c9eb1de9965946fa566c6ba5e96eae4323499e747f70211e85e538b5427e771fafddb40419720b36440e97c02f265de818d6b7f216bd67b7b14fc1eb67a452cd21d0d3e33c4313abcd923259686abaeb7906bfc7a45136a08bd82f184699b2251835fa2cad1a8a5a357a88b7bf5f4e1269313aaa874792c73e273001f99612b5d47f4b330f67f7e6e058e9b04552357b28d7f1aa87624692c420b90b79570d438dee0864620ffcce2deee97b78ba672dce9849960a16449503f637892e985af41783079f68bfc505dea274a4a9e62406dff6b1f1d2b3091e57eb5d5e4eafc4f44944ff0af15cb1e48b6ac49d647862afb43d2279e74d24eaa962a5c14527bacdd6aba2d520c6742db605716992a5e1d0cf5f7a65fa3a7a26647d60cd61ee8dec9971db9c39750c2bb894de32cb322d0418145a78acf255e53ebd92b707ddc47bc04915102fe3ee1c69ebad7a023aaf071b9c776f192370a465a22a39f12997cde04096db640a7d8cd6f8ef4cc257ab77c054ffed11c96bc70195c8251ecd4c9accc84067c58ae98620a1e0baf1054d78c2ea014feea0f36b38f27b64d6f35da983fb27d8f9fdfeac2654630f1f1304d387d95a9ade8f51c281f167b77a30e30367481b3210e124c277e5a2de195f4a6671b1347710d6509de50a4836615faf223bf01b15c5e9e9705dd586dc08d6c260735e15ce47c9eb613eaead198b555bdf85334a69f97ee98eb0caa5ca60390700316862d85b7b84c66b7ce8a79b4bbdd1cad788a773808c7b123865af6531457ded0e1b9dd8721bc830d234f052793d284b5e64d98303d5aebd066b497269500d07a43d48a586414e3ba46273b6ebbf3cd49318e00543e75d3868e4442291be47629230364454f36c321f9f8e5978c2a7ce0b10f220306add6cb5717cc999716bded1e30693a20834199e0808a8adbd86f18b3c1fdc123e1c4d2a711f3237ce86134f7a931aa2840aa0b7fc62960894fa516c4fc60e98255e83e7ee50fb0970777a383f87584cb92731eba41fb0906e558880885d545df6331d6e9f672535e31034d426fda958dcdb2901dd1025c0183421c871783408bdd1132c35fce5760ebe74e1ce4b17609184970077484b59661248eabd2388abe5b4faa0957162d5176e6f630ca6293529629487caad452895cd5cf694666aa8d6bb120596bb2944f8af26421dadbb5154ff82aaa0d8e2b2110a40743750cb3700cbd435ac4ac4a5d899afa3b186511b95cdbf52e35e81ea652fd9eb07d3be4b616c7cc1b4b2602c941a4583c84c02df13a2c2c94d14b1b8ca412e08fd9ca89be225dc78c593d6a2264e08fef5db19fb639ca60a1c7a32950194dc71435accc818b4314b9f978cfb738f2f37e865059dee3d633b074c6a0a1fe80b9cb9d45fdb5171b55618840c5781dff7c398ad3567cef69836fa7b5efd95e6fd3183d585309e2e40a4103874b93324f71bb2c31ec773b9de068bccca94107ee005f2938ee92f897b396ac4921ad1660758eaedcdcc12716952cc3bc68f895261454cb66189563f2f043ab2088fbd7b05133dbc22c10cbcc06fc670ac248b2c639773001341fe4f5b13d744209983ef6c3d4378d36b2bf5f75ace8e6c658e184e4049a594e0113e8f1a73b4ca50aebe97e3b10a8adeaa265275cd9030127aaa970587ebefe5986742b923f746d4675e6e1694e5003aa45e13df6cb46027899ff878b442e84c4b854f58dff1c7d52ae9f52ad886b700e50b73b72dabf375cec6f2f78a0e6db37aab21182bb540278f9aa80858fb461d7e1d6f3093a591e1280c58ef1eb7d88daaebf57dd84eaf14f088e5e6b483241c5166de8f2ef879f8a8ef7f35992c816fe7fa3ce0c9cd4fb89e08bce63272622e7fc86cd696cb09178420c9abfd416b7e7081420df4ec4d243cf04ddd936642171930e753a862f115b420ce9f7e811b4c3649b801f1de0e23aa035c1c9184100a3b50cc06a36e306c062fdf431370fa2c64718f5657c7ecfacb945c0619017c5eb31ef468c3dd242cfae6839481ee2c0650ce6b8c782b00bdf99b4e15f74976016ca5eaa7cb6db319efe4d226777293bd347abaee5c4ff92eb20913bc0b1165bc5c0d14ca9d42d80f841cc10dd581adcf2faeb38f1dcfe44bd2891ca6979c755eff12be86c3d54f7db54e9d23550fe46cb8bc274c095da519d14780b6efca8cd0de7028ea71ed8d159146654f4a19b07805b200ff3bf012b9d290196c9664ca6d4acf9f97a170c8ad1540aceab864a18a628bf00830c82ba3e1042549399bb9590c6b31eb9823e3106c180b1a59ca4d2a3a4227d57c7363dfc6d41e5b7f7b4139627083d3207cc94058665f80ba8d4fbfb679bbc923bb3f3d97a19a6add7f05d17ecf7e6e359eff8f738bc514efcdda44ff260e38e69aac7b2226e9643eddf7d35be945e6436894eff1979c16e8b5386e325774c5ee59b9f187f824cf15859df9fdb8f421b875816b34f3c03618e926330d17295c515f90db25ec2975a11814226c15241acf95bad960c7bc4a12c6e233badc00bed3287685962d816b95ebb1c785c126c188b055ebbec79b4fc0e29ae66c1791cf46b5d5a0478ada65d14d73a65072c13db7994288449dc15f741b3f1040da1dba0d4b613a5b84fb34a74a8077b4ca89ffb04b2a587afdd1162b11aa962ca7b8177f8781c3d35594b96006b85b3476d3d7c844b584d6efd07f3175642dfc80f9ac1d80b6ceea0e8af42bbdd7a3caa0a3d72e8fe6f1d14617820d96c8d775ecaa4b34e2c5f3ce90924bcc1a6335c0557033e12589a1929cc9acb9a4f5aade0f817da49469c6fd4b0e8f20b2b8cf6d44dc0c81c83d325b352f57851f898971245d5cab6e3117403cbeb32065db01cdae9894f5a86604a5d709ccfadd891068942408f5d1849e9de69d2f14c2dcd0a7bf4c10e3b9be0a7495f631dfa98495eb61e9edaec002745243f75f963a2bb0a1e9aec9f41e1f404819ed5d6fd1e0c48249f86c3832f066ed662543b494ce0bd30ff4be78ded35fd2a7dcfbe75d6498e72feb54670ea03a09d5ee5ecd921abdf596c09a887f8124cbafb47217fd3a2dbe0ab851c8cd5b3c4cbf2979e58ca4b148c02868bbd0544bd2890f1fc7722fa46c838cffbecc13a148c124a3bbb414d8a2fce6eec71b56e561794a6cbfe17b462c05e93d6d81e40d281e1b575738a8851cd7da62ed3ab90402c98b5d9be27a772add16b3afef54f4889d812aa4ef8ff4cce227a6d8933cafc8de2e9b6f503be2c210391f13b416402792b44f35bc6c565bc1621061955c52554f93c0309894f91ea0cd398041a12375f873317dde4b17c9f7a58ea3d2cab37cd937fa97b54b1dade7642c8695a5ea165132ae7d583b05caac2da8a022a09ecd5b37d4ab5306c963de40c1b2c70adc3b00c15fabd808ad2d4cf14ada7ab833bc66e9addfb401a4567c2c1c4042fe5a59dc2976744417a6e7a117f6da28751acd448d0a63248ef73ce3009536ba5bfa9802635b7759093c8d2114fa3416210ac8b5e41c1515cdbe7ccc51bcae50ec850a4424a13fa2a6047754193dd530fb9d4fb1efe9d6775b4ce31c889ea47eec5027b0e0ddbc062f6dde180572edf6494ee3947407ce89e279667fd3b9f3a691011d9740e41f5490070c719d083cd6d5dc58ca831c8ba09437b7dc51831721a32c7ec81fafb33461e84bd5d89287b20ca1b82571d754b32fb23f67d89bb8101f6390ea92ac45e206148a9ed04a8dffc0c9e31789d21f311ab4bb1f1151323cf6716ab666589737a404028248cc0984a553a640320cb9eef07e6d5020943174ec352155af23867509953737c5d4fe6ce40dec3a2f6b6043024e224a2ba9d10a3e9f967806857e44be434a5d841845f7c2570b5febff60c0f2cf9753dfac4c6697b40d478b49b3e4bc44903f661fecb4135167880f29342a0db3e59087b9794196bcc354469f66ce20693edae08010845904a20ba81355b7732e89d593b2417d254ac4bd2fe17452573c7e76aa783cb0f803a2a74fbb4cdb6037035f202b9b1b441438fa559e2d66945af525edb6b85e2010d479b75bb623f8620f704cc7821d3ae3158df6d7049f897088f45c3b32d6c28bd0e99ad30a14c52d3fe74a317dd5fc0716d12d4e60af8f6afe70c347a07c253261ca765a3f9a648003b430d49dc28e7d97961f92c24485816114576c599a54884c287fa82f614aea1cca8125241288d98bf78740c6c7d987b37adf2e14660b20ee8cae4ac4188f2bbcdca9f7993632d97b8701441f0961d8f80a346304ac2e51a467517d7d28bfa91b728ee8ba9658795cf087b2064247da458aae20e3f037cd5fb1df04b526fe20f94e939e7d1afe5c083fb8b712d174a4896dcc50c5bed042360bdaff933f8b3a453674f0ce6664ada2439e1552098ea5a456a96a7478bd0a7725acb4fe8870378ef6b17ac9282d9512e127bb514a35fb609dc8bbb984a1bfdc932fa0bed2366f1bdfc3dd725e75c14c0505588389236804b59102bce1e6db83776f519b8e007dcc91df53b8fc10862f91d045a045a6e97a957305c15271d63403e764fe57ad9f46c5eac7435ab7695a3494225bd5e13d5632465f1d6eb542230f4db1d08275e8211eed79a41deaa1bf6ff5d56ef09438f50bd4a155bdf4c3c5a91fd87bd454b2c21841042f6de5bee1d060ade0a960af1f34877774f51cc81ec990486a191333831bbc0c2527ea3d30647f94c3ffb465f865e7b31097b8018ee4082213f8f3a4480e20a56f8011596c0218a19700d93736c2a9fcfda33769343b969afcf57fd511e7ace60f7e2d873e8e6ec39a809caf3e827071daadc1c1aae3763aa994d2e9f73681805cbb2738737cbe7a05a55c578737c0e6cde1c1ace1eba4abbac38abb0abe2e7b3cae3cda16194e778ed66396fde50ae92378796e735ec28376bd8cd98bc4abb3934cc72d576a9f2aec21e7ad68e65ec5ba70ae5d05dae62b939348c7a2dcfdfeb5dbc2d9f9ccb38159a55effbf442a00ada9e5ddeff3a0f94b2a5b85c7b4b66f90bcccbdb35851f98610cdd73cab1bbb06cdbe59d761ded422a9203d516afba74293566d7964ab9f97b8ecba596a1458735e0acfaee6dcf29f3f97361e936af85e56aa9174b4bca432cdeb1e7cd63d99ebdc72d6bf1bccf166cdbb696cbaba57a2d5e77962ee55b8acb73cbfb19b57981870641704679777946b13c7b2f9e5d6a0b0bb781405b77ecd9bb265f609e77a55cdd3dcae26d6779f6decfdda5cf2e37f3ba9bf2cdbb3934ecbd7bcae6a59ce55e16df1d74966fcff5deb349ca73cb466f4a304518709e2995bdca4f1ebac94faefd05ca4d7e3d73db68041a751cbdf602e33ad15730968f2eaa2d2f7d74d5900a6905045744210e50c0599552d960978fbec28d68a682f22c327976a925965264a9b4c4524b2f9e4927190b5622a164248fa5e519c5427a8bc93389e5a116af046219bd57b8d207969c010e5a90726828125d617926b1943812ad2ba29b3c8f9ed1c64837b3ac742da58cf4d2b3e898f6dc72736898749567961228455a117d54599e127529950d2e7da5ba410c569841aae5a595cb6711ca73896bb95d3ca9bfb2652e9f2a2ecfe17157e82e2627792bd7caca5b44272f9e4b37b73c47567a8ead2b3daf5c7b0bcb2536127d347a6e39cae973a98566c1630d2dc0198552d960d1cda59b599e232bc54b63e5aa9693eb033cc5b39cb4f21c17ce2a51153d87ee0b3c4596d1333de9b9e48d9e03747273682ad2576e3e798e0e6795e8e61555e8aa13d13376d255a3876e263d4786b34a74d5ca4f9e576e0e0daffc7a1edd1c1a165da2e7c07056ad8c7ef21cfabc8a74576e0e3d07c559757273ca737038ab4657856e0e2d777fa1127d7473f71c1eceaa93ab521e7af6ae72b1949b43c3a0a35c2bba39347c72b3f71c209c55a19bb7e7d87036b1177a57053a7715a8bb3934cc5d6cbbf64e788acfb23b82a7fb6bba25788a747e5e113cc1537cdf18f0f418e32606960529a59452ca4b4a89497961d725a5acbfe425e575497949f94bca2a748c31c67e8c5d2a92862d983025618387a60ce187b2f01352faee32ddafd978cb3be897550877d0e4b5b8619977749726dee84bb694525e2921b4027ec1745e6278eee3a2e08321861df86e68984e1b3276418c8e231e316746e584109e4209e5e5269c170825580805161e8d1a52810a2ab08c989703ef4e08ecdae75721b4971208b7c06007344c6f316b062b6ff635a161fa6d8375abdfdcaec7ee464daeb7c1f07a769d7e4dbc03100a2c0ca1c0c272a606c33abbbb0822e689068684d1765dd9e5e535f9d8dd58e2dd0d381331d698112c9e97038da3be03f0b236a01e5e1f02e20bdea897a603f3f295abdffcbc3411677867e023a681972662990dc8ff7d6a1a5640c20ae799a61173b1ae013f6079282f21bc24bc3372521d8030807f3260849f9c1f7e4019988177d053187806bc4bb20084d754607ff801dd1ad8c08400848dd6229e2f78d6b40dd7292530d2c3069c47b862341a2673b8c2644b447d7d91517bb2c015d71187f30bae3938c323b11efe450686b92d30f6d8cdc58e315e1112120a8c2161a1112cb0a802638f58b00173076191c5118c3d06c1d8b163e163721fe8f3800b4ea14237390af454e8aa6c70e8a0cb84b4cb730735e906f7784e5e7bb57b4913ce7632fa549f2b07eab88e9b187b7fa2d40d792ede1c8dc01eb78b24073a01816e398e93f226e74c6e1682c2856e8ef772bc06e30ecc71201d266627b94bbac15d9eb37daad76ede2eaf4808ec13fd861091ecdbdddc98bbc9e317fa0e91901b7dd04342506ecd0ed161cf906f4ebbfcbc372ae28845dc619f4037e4e341177be68c9097eb538703fbf67845dbf5ac06e71a3c232f8dfb120f717e9999f88586c4fad49cb498a8614c15d45d10e0312ad8fec48c60e5e3479f1027aec6688f8a8da4a91b09b61f5fab13d7af43d136245669dff835511feb533416c7c7d6a91d6bdb607ae1ecb9a014c119e735a5fc136c9fc223748dcd8529d879193b76cf38ff6927c06cadb24adb4036ec0232354dbbf6ba841fbc9d7643d8e09a7dbbf29cd15eb92d564d8b31cacb50faca7d3a12d8b4f76bb867376b38af813da306e75a8dd617272b15b4ad7ebb36b7c3ed6edbd5dc26cfd5fa4d863efebae82be81bec1aa0eedacd1bd68140dcb97aed8bef3e187361dd9ca72def8eb6d17a2241cb2afdeabc966550d002d72c935cad97317ed30a688409407036b52d08da1180315d8d4d4c77b5b87d39bb7633bc43d0d7d72b671ac38a60af0c7d5f866edb2704e7074ae9e684997dd2fa999e6908c098ee9b963d3ebb338d6f6eedcb1846821f62bac3aed15d1d351af72de332eddcb3c87d30a6a276a022d7ef59040ef6906174628a51d2f588a5cc66be8cc60ca343d8607ae168d4a73e6e910de2d2e1c0f52c09168bdeef3e462f234ae00297303492043460edab592246bbecaed3998e120b944e41da8ed7153bca9620fafe1a6f30565293705c6883671d42fb94575fd785d18bd2fef583eeae03751d287a18be830be8e0017abebb213a5005d519b7ee9bf806a9a7d6c5eeb4d94508fa06fa481de892708040a0eef3bedc9d3be8cb5dd75d55cbee9c5b74bdb05f94bed29a5559e9976d84a8694cef0cd6fa853d831884f8aa6588db351b4fcbf576aece4b0a363bf6be6ebd4838eabd0f51bd6b83afcffbf295af77575633c4f6ecdc76334a27d7337647884de156daab8bdd9c17cebf896b0326fdc493bebb1402bb2857bb1bf35472344e19a5d66db764e7bbeb9910d869fde8c6611d0e69c47565b0d3d3675fe39b6b708d5996d9e099c61b56332c0819d0671a543f2cab32339d418f26dfeae56becb19beb9de15ebb78ec931cad5a94ddbf4abb4be9c6f53112fc106372d8354cae8eeb24f821c6d6b05707ec1958bd7dbcfd608cc771d907b1edba20b4833ed20dfa6fd1765b073137b14c6950ad19a9927060cf3e0476b36b83af2bc24ebb4f60e1f95a6f8e734a1c7d9ae5faab7fd51d6db375b7c448135a386347b4e881fb4cf4ec4849f3d67ad5c758bbfa0dabf3ba28a574bbb66b7e41d40bd33819fac659865d57f6022a69ec48aa775ec7342da3dabb350ef61039d80329fe629814acf66c93734e1029f6250dd117d6c473ef2fc718356c88ebd230cac11e22b47d22617d9218a5f3ba66f73c077b98efd84d63470eeed08fc78cb0415bcfc11e1ac3f763476fc96697f1b64e23fab11f65d7807ebc32f3fd0d8b424c9c279e7dd805f1b90a4d3091ca409f620b6376749252aa1aa7508d6574c4e81971e5c548250545741232d161afd35d87bbce761ded3ad975b0eb5cd7a9d7a1d791d7015dc73b8d8be7c11b63e53b9d1a0604f2eee9c567ea19f29abef78c7895afd433e28c78944fd433e2459fed19f1271fd733e28c9ed1332e0727c659511d4d3a6fa94ff2fecabc807a4eb16df18334aa6c7084983ba53172143e46ee39d2ec35dc776caf11e73bb46ff1c2acd16e2dc4081d9eeaa1e9d861293b1c6987a2edd07287a8d81d62a04354fcf40e53a878553698d24f26ded2ab4327e27872fbd1b8606a3f13b1f7e975a0cf44dc71dd6722e63eb9cf44bc69db6722d6b4cf449c61d927f69988af7a7d26c66898d04dd1b8e0fa9988e9c9d5a1637267bc6f62dca8f43e7da7185e53196c316274a71367326dbf562a65a31126125d8f31aa6c708cef0bf15e70bc39c668982e460c18ee7482d94c2618ed87c94a25186c341289ac85a15708e8d6701c866173f68c7ecd7ca44e6cdda73ec536f5297697fa147bd4a7d8a23ec56eae4fb1b13ec5ee2bd3b0fbd906f73df5295e469fe27de8533c104528f1cd186cd09423cb07c7af9fe5c046f91e383e954aa552a9542a956a126c59116c4c7997a077e7be5d7b76ea793795027557469ffadc767de8536b1976dd4a2f127deacf9b449f5a5e25fad4f0888e8f0dd860390c8f14696178640828ca276cd0147770052218c1b107124f30410a8ce303e40753e0080508549085246628421076a680339c83134c2092040c97c481063b56c019b281c600063c1002fed9c1859e950970865cd4e4ecac9c40c5abae9d20ab15867deae097681854bc32a043acdabaa0035ea23bbb81e5b0aa0b3ae04c07f120d0b30d06dd542ab5449fe2855ce078f883211b707c8402471c1c7bf850136cf0d006c78811e3743a994ca6ffa55269341a8944226b2dc7711886cdcf7994bc327d517d1596f2d906cb9b82d825236f0c54c44262f4e9a4ddd3c9945d93e9d8fd4bd72d9546f58efa3412e988acb51cc76118d633648dedea983d235ec7133106e731dbe716e79579a13fd8b221161e19f283558737bfd0b86094ca06c79fb65ab50bf3360fc32a5665ba471d3a74baabbb74d80b3179766db4498dc9bddbddeb6efdb85f7107e8ea30315f0f63eca703e576f3f509f15e711ee3bd7edeadf1be035457b0d4c4d79d59a997be60dbbc2d85d28ea2872a1b4c65b2634745ac4327bb76fad5f809e94eb3aa7db06b74cf5af79aee3b388af3981a1dfa1ddbb9abc3843c8dc7e0b752af0caa099c3d4cbf42af2cb29d08c9c3943f626b04611cba5c0fc41277240fa6c39f3c2480bff8a8e5f01ff83a02dc8c6102bc3f52004ebfd2bd5979e9f5bb00f8fd7f7d2ef7a606e0a7631f8c7bd3f430be7da67b63fa01f0ee63b97d7aec269f0004f0fa011ce5fbeecdfd6ebacad7726f60a01cfb8bef864480968b62c4b0fc891b1befbb69b93c0a1073d3bde52bd7562e0f508ccb49f7e6c5bd972e0f94989beb2b1f912ebaf693ef86247ae9a0ef0674d1e521636e54ee3dfb6e4a97c70e313726a01bd0f6164dfbca49a4cf87be1b140cfbca9bf4be84217ae928a0b79ca2dc7bca7773ba3c483137f4a4015c1ea6989bd1bd0be0dc772380cb438bb909bd542f0f2fe6867bcb037079d088b9a95fb9355d1e0388b9215dfe97078c989b947bd9ffeff1bb01c0e5d13137f6a57b79d488b9f1de726fb27b637f63f29bd06f443f398f18d3f2eff2e021e626fbcabd59398f18f37b137fd3bf91bfa19f77f96e48f786478c21bde5ded4df5cbfc17ea3b17c37272fdd1bd2bd41f94dca6f547ef3e2a3f388312bf766fb0df79bee37de41b72109f0ed68e117dfe83b4918f02a29df07240c78942fe64818f0a20f3bf95e42265f5c4918f0f68b43240c780fd47ddc1771beb8937d36240c78ece38084017f7d912561c0d72f16919730e0e747c4d7c4177f48182d0903de26ee80d19890cd872cb60085153578e2099f2142e86c2102f819c213c6a0e409391491181e714117d2055dc8198c4450e91c1d69c192232d5822832de660480deb3271c4052bd104161e71c10a67aea5ccf20e1cebafabde6f15469c5882780008e1177b6c5e0fdbc7703d8cdfece81090146f0ce494c191287cf09128ae80e11116548133068f447104530c8f44614564e10b93e08d87001003095870861ea6c98238cc0b562ab360c1911abc00e14814566029a57c0102b66178240a1edce00d4a78bcd05aa7e99ad289597d4c418a1e52dec711707e0a301f45786892fab0811419ad45aa8f16f4b0231f52c039e715f5694e597d381105bd52a4210a29c68023c51637526c610452588104524c010a539119c2f0881433e0ae10a750622a32051a4e804d3107d6d5c304758a11d01f30e8612a82831e3f301539428f233f9ec0324d0dc3232a288396c4e706382c8b04c3db200b0ce10ef0b4c52139a841808d87706464499009c8f0218528245919e182096ec004c704c7e1862ded8a071a8037361a68cad0c286916df061d87c7a39f11063da9463e0286a9888e1cc2e49e9923660fa424386acd8b5e487fe2f944e19557231a9bd6874491905fd4276cd229794bfa8912557d028a51da51405f465de98472f329654d1c120850548d819824e0da8f84210fc007a4159e79c9325855969adb5ce39e79c93564a299d73ce3967a5b5d639e7a474cece0d4fcc49a794571bc4700d81869135b08e65f1823d408ae5297619598314e8941986a191355401c51677b083031946d610c4c81a723ac6939587d002b20f8dbce15362dbb18d50b10b0c3f128eb7bf0a8440021480810a3398c2c7921abcd818565482b3c233ace109489cc0c28a243288a9341812d1800334e4603938bec89e13d8abd2291ba2810adc710e5600b168d00287303482062e703c16822d8a80c85500081ea102200a98810d28388313386728018f0e4323679042056db81131b470e68c98610a6c82a111338c607a181a31430ca08d33b0d04819a0985ea9614838e4e93d49ba31279678f3408dc3eb02cfcb1b5108782485823fab159e0961ed7286c39a114de0f903ee9aaa10e5f2038e70077a54eca20818835e99d9156163847acdc76e88fe94f2dcb7d0d737d964a586c9e64938fa53f4204e40f2fdd1ad620fe2e4f2f34a0de3756704765377a71fe9e4a1ee4f74948f8403bbe8d84597747285b0c12627e10875ef52ba2164e83349f930cf6e37632f42ccda09d138fafda28a585e782308c76358cc464939ca614704ca07449f6ec01e624eb191f2d928354cf678e3fa66f2515b6a182c076727e1a0cf1e7a9629843ba0a47c991a913dd3632d9c3d45c90eaea741d8d30ff452c36037e694cf43b843a6d7de9d11d9536ec68ca8df3cced43050081becbdd430db513e92bdc94f42179d845e1fba247b120e936f37f9062102544c3eeff613c2067b17f4c974b79efb64b68bb51b676c091222be6317c40db8434469aa84d66a46e9cbe53bf022bf657af30ba69fa0d0890847d0b57bdb4f3e6bf2eeee64f38b77a9ed53d462cf959997b33d83c895b49fb2296745788e4a789ec0da77f9badc681744b4f6b00bc2ce6927b51fc41e057da23e09713d36eed912146514db06eb5531ecaa134a29a58c1d21161b093468c4f7b0755c8cec9af66cb27dc5382361bd2c872237d07755dc7da08fe2ede3be71efb8e33a39d027b90ff4350671d8974da29228e579e2eb9d3db9db777213aedfba6d438926261d0ef81dee507f922da81302bb877d107b9fd67df272af97d7e1281549c31730f7cde322eebe89378f03591119ec55e9c4b24d3996f2c186716daf5de58d5887e30753765d58c4bae862f6a945add9a0b79699091978464a69fc2617b8a7113dbb6bfd6cdea7abc6c2f615e5609acdeb1abd86f2a6bc289719027c852e9f2a679dd9352c511e8e9f734e9a89e38d97525e57ccc2f3c1a2cb5bce7c16d5078b2cac28a7f26083a62c800c0b9b4dd99021a8882b8db8ca8f8662553cea871841806b0e01ae5f863e976985a7bc44c52c075329e3b16711a35c708c37c658eb150490b3852456688e5a810a94d2579a8286810a7ab03ca56248901c887fb0b24f8600db837ec05916167473c4a0675f36ad7076ec2369c79e4dc1429c23aba31715b1f7f8c87d117baabe2893d3847ef24df4ed92b4670cd3eccb4c9856187479d1472371b6a73ff96824eac22e1824f1f6e5c862f980bb2fb276b03cc41b77f33ceaa28732f310d7736f1a8aa7a4ac294c2b5cebf5cb0c3e984e3370c1c5ca07532640244856dcb99b03f0c3831d6cf2c134002c4c4d3b9876ce0ad31c5957b0118785658f868138e5d6e8a054f2f466966541a8d03e9f32595d2365fe982f547ea01ce54365b55299993614383606e52957b131281d0b8ad58ad6101ae6b05a611856eb5cad30fd74b0a058adba951f293e68ce3c65d189d55a31ace600f901f251bb438c6158adddb1ef5d0e90210da3fd18bd505919a1a4a0e874ad15c3e6ec941494d9c7913564b4d29115a461e615b2a2d22997bf222ba76ba834cae5238b8a86c92eab472a292947796445960a4a0a0a4a4a0a4a644556644515f4843a002d58c1439efa4a239c10f2c4d66c5d57c69343a487a7af8bf6f44479f3cb14570b4f4aa93d39f9c9331ecb85329eea136289aeb0f2ca78a60968b640d4e4269a96d2ce894e423747d61516c3b6fa6a925d614d6e62325ba08322cb6369d6f340d91556ebb8731ca5dacd2f78de0c7df2c562f1ccebe56a994493d6964d019a329683e5a946eb21a5f62a7a99ed10d3af9b2daa1199d728a8afb0d6e426d6e4e6ba63698ee7d11c9ed68fa539f6d63ee369d9eb878877efe6172c57d247aeb48c883d05ddfca2fdf8489faebb2d4debeeeeeeeeeecebabbbbbbbbfb0adb92570b9b2ddc92af944e2cc763c266ed97adc142fb2c0d762553431a948891c40909537d7dff88175122620484a84fefdbe8fbc071e7dea7d19771d53ce8fd978651a1ec95b1875865edb30db63795f2eecb9571695c1f6c6817884b4411f7082492b84a10e159c97e60fba535c7b0c97a6bad377b82bdb5a7b50316bec2ca179ef85863f4a9534bd4f803c45a69ad5614a962878a21417280fcf0c1a23555b7196c591452a8c629944c3cc47d54b641459c42cdc3a34c314ea6974622cb6991248b1e272039924aa57860bf8c07363edbb11cf459c206af4a1e352f7c86ef1c5b32f22d0caffc52f2b8476c31614e79e7979a57b5300e72b0fcc0064d5742092f89531248989038e24714512a82881111408880b0616df8c0f94003a32163caa811f25e3a4688b25a9c9298b2784fc9092324a22396f301a381a1edfbf2e2d9900dd950c886423614b2a1900d856c286443211b0ad950c88642d67e32f62fd0e4a067e8334f63c4389d4ca6bf541a8d44226b390ec3e684d0a4bbbbbbbbbbbbbbbbbbbbbbaf84125d1249704820b11d718456441119114460400071d9b0e1830f4cd0a0c101199791813ed1a750f6a2bc2fd1277a7aef93b1177272ef86429ef5e8cb0bce63425ac4c069182ec969cbc2a4f5bca6613227943ed0301892d14cc35c47444d344cbd4260cb32e103c7011a588d900c1c43a75fa26b846e0d0b45081b34750e9e93ce1e3cb32be015f60a2b5f78a04fadad185b38b6fa740489137ab248a285cf164ab8f861435c12e7b08202a707ab81e0487d00afca2646bcc1cc0a1b4fa4638eac4c0936c6166c41b0500d26d4251bc20f7d7cf67ce833883e7799dbc95b0e4b7ecac70bab0fed69d89710be61c3196314b66c88edeeda2dd387b85572a23cdcb7a1519ae084856768856708700cad72682543437fc052ca18298e34820027c1cac8ab64ad52cac4d3789ba047ec09cb0a1b2a6294901a1d797b9dbe779d79d075e8bbebd473d7b9be5d07bbca067a1f06fab8eeb3dcf68d347853d98530855d084fa9eb42784ad514bd109e52f342784ac90b2184a71d980dd6cddaa0296b2c4cbf6540b030fb646826ae17e582e721dee69452089b106099eb32336265e65513558f41b8439f0675e1f9d4a49138dbd8e019f9c6d9106c7dbe7eaa4f4f6bbed26740b8d9106cfca4375e63c91d944622cb611309448047b0f0c80d76f03caed827735d0fb8e05c0f7b405dd8fb36588646e27c61f988630f1c28e2aae603334d30c1810c2cc1652d1c7107189ae65c6df25dd8a65d67d1c6ae5a8c5df7cc628c9dd67df5d4ba67a675d75973167475d3ae936b5066bb2f9b61a0ac5b7a5a96f5bcb29e1154a9b67561bb7330e8de3de8e6d9daaeb132edc1aedd2c57b1357fae1b7be24fb4ad1112d883f30927a92b0604a0854d2c2a8604c901f2c38789c59af3a26ae099884d3970871060130e96dc0f381b828587dfbaebf392e8e17588b36907d3d3449c9908ad3077f96cdab9a87a9a785117a64f5d1a89b1ecd2489ce9e7318ca987fb8374c0dd97432b2c9f25c1cad0ab6868a869077007195a61eee6c8c29c8f8f12253f3f704968c96a85297d3ec1c1f4d9101b717ed9c1d407d3e7d00ad39bb99b7a60f9ec88a947c36413cb84d330f3f226200d9385d4d8a37e740d10889a7c740d10cd6998dcb6316edb306ccb01f223888f0dc3b06d3305b9722e20d790ebc76512fa8909a61de2ad6edbc58e8aaa2ce3b8eb536547d58cbb7e69dfbee3f965530e96370d115263729429c8897d8d0eaa2271c294d335ecadd141453cff84bc890a1390cf44c7135e175d74518718efa09b727a86bc2988761d388fb1b76687e605162011410ce8388ff1ee8e8ac48918d0d5a137a58a385583028331f07411a3d3d799d7c90e3116314d0be64e135511a76622e66e3d2a62ee0d4ad1447c7dc645b51dc55dd5768578177475e85cd7d199fd69d734a44fd744c5f1f555244e60fa81c00b2c402282544f130b4b9700b4b616896043a92256cdcb37f449c137bcf20b8efd9ba18f9412420821841042083f931077005f78acbcdd32c8b66d52cea9cd398570e7be2b9efb94dc0763621784446dcfae6f9fca06633a74e86cd7e4b5ef3afd7adb685cf03653999c5f7cb6725d19fa7a65e85d99d7055b3c4aebc70b65388cc7ceeddde7a7a4743e9b38b21a46053aaa5e19ef10ab609fe67555da51f5aac7ebb9732eefde8d2c1f3f80e4041942c54e1545ac681d41e2849e2c9268e1b385122e78ba995f5ea4dce636b56bdf36ed5e93889dcf8460394c4f332236ca9dadc89605c142dc8f5b8c86c9793e469f4e2793c9f4bf542a8d4623914864ade5380ec3b0095fa3839a873d031e7ed6aa43871ef68c3c0f77449b6ec9820d9ab2f4c1f2f19a33cec8c2d751d855b04f17f6ce99d7afeeb9aeab4712813e2f58ca4f1e7b0396843ed8757577777777f70de6ccdd83e5b31b541f793aa70fd6b3c5bfbcbcbcd090303aa582704e0ce3386b45a2d1a854fa4d26558c3ec51b9cc1c6249bc4ef93bc0915310dc5f33431d243bcc5cb92173ec76f07865df6032b89ec6079292f55f2314e499890f811a52246448880b036381f522a28c30667442c0e7a707e91179582a81a4ca301b0544289249038a2082280b0e1030d192f314ea6974622cb492a2ffd52f4f198c605671b8cfa01a3e26a87d685b36555d80ca66c5638853a9e9938e3818dad2f7f0035c213558325ed25587e07c0d94eecd1a788d3a708455cf5a9a64f1f98e9537346884ba5d26834128944d65a8ee3306c469c3d3f7b469c5707fc8e186510b608238c30c208238c505e4648a954e23eaa35e8ada9c1794c8d7a7588b4c35bcb6187c7b0eb904a5a0f75d011f795445d43cb6a64580decba6aa5f4b1a90936688258e6baae7dd7b70d0e56a3cfae0cf626aecf0731135b9874b50cb681ebd2c4ea02ac7f248410420821841042082184104208b19690c80f942c1f3f80e4041942c54e1545fa24651f41e2849e2c9268e1b385923e9d24cf65d597d88a31c618638c31c618638c31c618639c2b28707ab07cfc0092136408eef7bbc703b24153dee83c9c3cb585a5445a7931524941119d844cac07eab84dcb6036a467d7495dee6245912a76a818122407c88fc885922d7cb44892458f135243ece522cf6a1e80c0414ec380437eece41419d26a1840e00049c380381bd2b5e5e668452c12ab20dd1c77566e8e54c4213148cc01827273fc21ba39fa88acd8c3e4e688636f8e50c0392c61c38f569f4a2dd1a7bac5af7e3cecaa124920714411440061c3071a32fa14afb2c1337d1b5c8add19ae2fd1d79328f1f95182af5f87dca511f231ef685951a48a1d2a8604c901f2c307ab074e8422aee6b0840d3f5c28d9c2478b2459f4e05a5b3ed090f112e3647a6924aa991cec33395c32f13b62b4a248153b540c099203e4870f560f1c281a06d67c60a609263890812594480289238a2002081b3ed090f112e3647a6924b21cb672dd7a55d2268b8325d54ae27e3d4fd2cce260b74be2cedd6ab3ca6b1ed58cf21a9f53e00edc971fc93e632a281fec6e349ef8baea3a4dc4591c64ea55f53411d35fdc45897edde4ba32a1730f5ddc9501bdbb24fb9c72d9eb9d063bca4589aeca06cfd8e019ed34271775e1eea999918cc9ed4d24ae4fcd587b65421e70c1b971bd5965939ac1300ac21d4cae8c77eb5d0fb860997a419746d550dad87d619b892dbcc18f145b30fc64fa2c187637606b8537102f4dc4f0361d71c85c18875d3b7e70f69a21320ccb4ee511f8d27c321dd8eb57256597946518ac9774835b7d243ae79c738986312f294e91dd001e21c2c236b018b6c1f0c80d76d850e407c73b6083a60ba1b47485bc9fc9940e71f6f8a5fab43f197ab390bf748831ec1fce637ed8357e6b74505df3d37f3086b60b2edd17ef3ec2383847a3bf78b132baaad1caca4727bdb8aa1724d25fdc867cf1453c8278657e2a1f4df964ec9968c1262618e5db8a778ee35616f46ef39e85aefd6425fbb1b33ebbf795d7730d437aa5425a546e1672e3f25f48cd1331e6bf79e24ff9e8fb3322e5295ff966225e39e99b899874ec53614795aec254f1f12a1fad5cd5cae82f3e19549f7455a4b35cf5e22c1755ba427e711ee3d27275e8a0fad875e875e8a0facaa062bc8eca552f4eba0d49fae28b0fe2d11771aca75a9ff25d006768c8368f503e88455f6a86becce1da81166cef4cc5f31b8675dc2976fa712809fa8a7602ed2bda0932efcad063077d3311cfeeca506ebb33129bb0ab5d19ccf4a2352d6ca97a7968ea012bc5d5571e223cd84965d7ce9dc3faaa543b3db85bbb46a4f669def6695ed4a7f9519fe67fead3fc4b9fe665f4699e469fe67d9807a24ff345f4691e893ecd2bd1a779cd593b5b4114b6d353332e58c88d613add54faa8241a5939af889b9f71c1f2da3ec9cfb860f16234114397179cc7502a0f63e627836a286cf2f08356472565685a7076f9eba359a6bdc63e83319826a5d4b09bbd7351ca58cf55ef10cba0ba6f17629fb31afb1d2615cb6e3f1863f2e980bc6f98bd427454dd619f327ad0a7eabe417c57b42b833dbb32589462bb764c6a26b0f5ca649a8855941ef48c6a5c336ae2ee198561ee1965f17655c4f5075d9aeebaeed24c7a1447cf719706c3f4aab8a3b6abe24e2f432f0dce54d93b9576944a3be8f4a02fdb60eea6b0abc28ea25761aaeb287a55d9dcbeac03cf675f5653d8cd3598de99b6d1a27c014bfab05a3b39add50ffea12b8a437fb460cb166fb31f676b041b346d3375ac057bb32f584c1e43b8c3102ba11f0cbf32fb047f5093524a299cad126c58c39084e8e7d10f01f04cc543c0976df48321dda00942b865a875ecd88140077520e8f31261e4a93b708b3cf2de493f67ad1a1036181fb560a316765e6183a61c5af5e0071fe00730c00d101f07f0011840c6e30e3fb80bd027c03c0d4000a643c90300ee7728796816d92fbdf88b1d4c3a898557bef242a55144509af4ad07ea9ad332f83cb50077f80e311ea3002f0001609c7efafebdfadca5e52d2ca5177f515723951414d1c94fba775560c7ae5ff4f452f22397ac26ce962379d87a48ef74916e359297bf14616198c300a107c31ce666e893adb49684d147d2934449b67ac1395b6961fbd7829df119374f968ccbb859fa28e00ab859ee24e009b859ae107004dcdc3d2f7fc956395b29b1b96be1d6c2c2e7ee0aeb831e7c801fe0e636c00dc033800fc000374f960ffc0e374b25316e963f05b8592e992b0c4f809be70ac6cd13e774b3dc19c0cd7225809b254e006e962c78d3cdf207006e9639720886bf37cb21dfcddde32379e89c86010fff9b7b88cbcdbdd37273178167b9b95ba59b1bc98bbfe0f1c1a493fa073f78e52b37439f171d5b0d031e09861fdd1c91a8dc1c7b92c4243ed14709864a4e240f4b340c78253ff666b8c4bb39ae4010772d24b6a5b5e0b39b4f384f2dd83c5babccc762395bc5875633a2cb135b268677dd16b6332c58986dc15ebfb063d93606dbf9d41f5ca50e24b6c28e35e6c978684ff7c89dcb9d3341202213646f2d4f6c09badd3b9eee190f91564f7ec11ccfb6658dad2e4f5d7523d8a009c3ba77987d263330d8869d6dc152d0115bd87e4b56f761b3f5b3d19b6d61eb36bf0c7db02338c8c92e117be7ccb0d9c2f3428c868d896129ec5832017d6ebd324c740e96a7dfbc329d73756143c94f76f797ea68236324810f1198338487c8853cc89dd6953d3249863e58ddb68dc8f5edc2d6aed834ee749b5a8b980936689a2c9f1db9d2aec96b17c2d9b576fa335bdafcc1f3e7627175a7ee5cac8b75b12e16cfc562b178b49fa67172336cdd0c9198d84b7928c57adabb7e70633d9dc3037db6d30cbbfa97c61fd9059b9d44501256f1f1566cae5657b2e425ce8a2563ebea9c844cac57e3cc993bf5277bf6d227212db25eb860e5fbcdd2ae8cd5233b099637d71f1f2ce59517ce12cd27bb7572e19202f71c5b9195552512c60f29a594525e38584a22568278b69b23ab46d64ea5dd3d93f5f343244a49efc5aa6dd8a029571fcf1e5ecf27c3b2cf3b3f536eca2fa8722879a043248c9c213427eed01c152276f4f939fabc4c72bc7e11b13c1a842a574959a5a85c45e519cf4ae529a38f6e7ea93bb548ddd9a93bb2eef09c5c25f414948b9eeb0e8aa867e8217bebddcb75c7bbc94d6e7ec1f147f200b1d88a2dc94384bb8d2defea7e5ab37b3ae7c2b0c6fed2b11591d0b0ad1192cb154f76e52ab6aa4a141dd9a029bf10c9881049b9502a11cb823ed087a773e82ae54a949b5f3222f1475e661ab3a735932009dd3c7d7a4c648e2dcb637940f418f499a288316183a63c7f705f75c2c3af7c94227ac673f23c5b3cf6d7cdf187a77b655d3cf3d163617802b3dca14442cf8295cf82ede778cf88807ef28cc8c6c288d0876e7e39797ceb4e24392e993db95733c9f4614d253f784e6e8ef7fa9ad89be3cfcdd207c783fa66b983e337adef45e324c54b055b96c5e783854b2b0b961c2c4879e493d2ca915eb7e5f4b3a976a8948d568441ec98a2110100000000a3140030481c100bc662a1681eeb8162f614800b91a04670569c09b32486514c2103083186080000800000808cc04101da5c8fb6ca2fbdef4684e44e9032a46a35a79421de0dbd74f53cc51c76cb77e1de368c719986eff35faf6fb3852fd6495a031b793edaa0ceb6fbda75de511939f60458e618893a7f458152d630a389aa94550e3306ddb448251c404708150ecc88119cdea03a26c2f0af37a7425a59f4d00fd9cb8db8ddabc80b521be50e67c4b924d8024c4ab555fe6f125a21d3146e0dbc7ab3f26f6345fbbc831d89f40e9c588186d79415afdee9b552f6d9c850dd4099ae7f1e3e35e62217142e400860e7dbd20b641c4e8db10772ce5123ac0d6636f1fe71ee646edd53a91c39ca0ca4f7d4d4f5cfb24353760036b0ffd4a6ae624ee7acc7db9d64d42d23fa80ad7dc8e6359783b891ac577325838e03e2f16ad09c40e0b23d83d0b5e2599361bea1635000fe3783cd196236b8b73a707e8b87fc2624c51fdf6a729f9f9ab87ab354f4a21b4ccd832f18d9121cd9eeb1ae12d53a659c8b37328c108f97cd692e216c74e25a45e585e2386a09709365c46bc8ab1f7eb62ec7fe469efae0b7ed1af9bcab9ec76f983d5871d3cc6d09513c48d1c67f9e4d20d60b0b93032a05ac673fbcc0f31c7bde51447c50b19c908e5e81c0c30d76d4539427de6464996b30c482e3cdb42c7fe1f9ec6f54f8e650c10103922f3221ae6352d93872726ce9bbc316a4bb5dab9a2572db8608e594d4bfb654d5f597d1a29b857ca3706328fe9f54c176488f9923cd26476ae3e27b9652c624559465fe3bee9cf084ccf3bdedf38048cddaa065aa7a480a0204f19189105f50d1a2372b5e7fba2b09a3774ca6028ab25e5d937fb7dce3ee92295fdb22af33adab5585d2ef5cbd876554b9834cd0af125cffee491ed267a93fb74baaefae5a1df80457cf3cafbec3501a2cd0ad6785a9c72abd413b41ddbb64b5522070711aab284aa82addcae3fd7af88f72465d13786d5a0082e80e03fc249229b57581a54e6681a4c31aea7ee4a2db4ef2314630c5a3f514a67ac48fb6921812acdc165cf95977b3de7759ffe7dc96e78c97eb72feea8d975f45c70793e7a16a18d8c048115cdbe111bdf7af042ee7457f3a3e01c8dbb5180b5cda6d1ebb0a365adecc79d3f9526dee60449fcac44ec321053ba524c377bc49fcda259573408ad6dbef3982ac5a595780a9b2f7ccc8bfaba5af026d5fd0e8ea436612ef8a63a5a75cba55ecbd552123e80182b43bf831c4719c3aa6830af7754c2b9ec6da43d3d96ebedb561c6b0138be99d61c145eb0e53883fe695c33fc9c18bd6bdda3435d600980e55c46d31fdce0d4975670984a63e7744265071e2f1ed2c79b4c62f60bed99d08f93d4975005e9e7cd1cc3779440455910d461e52cf2c9f0e528aac7f1b3955f81b7e18decabe3a3175f51f842cddc823fcd905a749a8137f74768664d7fc39df358436b34f3a9ac84ea5108d86fd70a1a78234e7f3d6b5cec7b0f5061244e78d0908b0ef36e00ee17ebae5c0e99c008b991c2ff1a2737e14cfb2eba9a53298b42f2a7c9550f9a46405b801073d819f42871befaa00ec6f8b0bf8c41a1ffdf283c7e3b06f02ceaa8bfed32feb5e4d58ffd1b57127e621af2eb858fadfbf1a70c12e6513de874ea67c966d15d96670fb57c54f3b13ba6fc70d59b744aff538f5da225db05b877455cc5886d73f30ce3a24c730de0fd155589b2e9fa464b55a984ef903ae226b5dfff02b3656cd93c47a52319bdd83f5dba875cd39758a8affcf8cd79f9cabfd89a3ecb4dc41e2498a898d1845ec280d372b79c774e32d12f0d65a08b568246405b4f2e5046e8f32135a45e03059c272a8db78292da04a66ff317cce921b70889063677e6e6f11ea03479d652b0de708dc301203556a564d92606f09e770e9546d7f723785107461c2802a9bd312373a7470ced9fd75bf0b80aa07f0048a631c8fc25602634d188eef2823228de8bb8feccd799cfd339217ef77763fbf831879e4866faff282013920ae653de0c82a3fff180cbc0f4933426d3a68648458790f314d503325ebdf25be0e2f47b42601a157128b63db84eff7fba17c526f50e229e73f7e1fc2c602d2c3457e5812cb82c4384595948d37501d22283ff3882ca7bd844e07e9f34f489cd7246c7afa82f157068fd81d1ef55ed75be8f1868b4c7927982bcfa143a595bc6a9d12c96c94441005f2bf2ae69ec3115305ce3fb1286776f3dc4a6764d93af482389b9a9a2c1be9bca1bfc76e0e083a14f2c2956914eca8c6c0eda587f6b28c17e417c411fcc658381d7855e0ee4d2c078264449ab18a595260b294a89192d8b3996440ccd728246426867c90021b126b4747d242507ab66afa5f73899a5b4c4b980b9b8ccac4cc6a22d9141555ee0025556021e2cb3f8a2f706f17c941d833faaacd8a0e3ed96c9fe14d1464923c183ef297482899e57e91e75816048663177b11f26cfaa387ae00585906a71680deadbbda0126794fe555a9215f5e066de52d99816e1614c9ed88bf5cc10f0ebce39028a03bc44ab4c031c5866d66c7082d20001eb7f462ae473c6ffe7ea80dface71a17fe2f03ebdff93fc69bd4d2d97e62809f539b865560ec296c4426dcf39044f057353113ac958c4aea6e1c5099dc6dd6b93330e6255954fd567033a934d7d67921e0f409d3ec673126c43b33ae6b72b02817ff3cdfcda7dde2205ad7c3a193c0d0637bdb2185dd757b08b1c61cbd4c7b41af70c8048bc89a928db3616b4a30c281bb2f5cbfd75fc53af72f896704a44a15fb83b7a8f8b06d85848809162bdad42ae431c7e32734fda35e1a217f7b84eea0dcc990a3a87b301e7a21ff19528d7942086820563db8a220f42c08b0c6ff8fcd132ecb9b18947072a168149ea9577332fbbdd752ae16004873d37f91d2f489ac8e1f6b39d736e8518a79cf8f06bd385c8e809d4c30c5b4a4e717f904768f6538f4aeb08ffa079d0f48a3ca51a106c10bacc9f4ee5418f763a2589d998b33cf9c4cc8bf22246ff3ea8055431501b4388997fe960ceec8a146553658b1f323bc22886d883abeac08cc28e7faa1c2219026e0d7869784aa5db8339f19e6034c625b1e8580c83d1689dc83fef0627efe700b65f4a6cd35d08cd88972065f259c08b93286de79ad6ed78654fcb0488c8d684de3bb1b6d6600358bb0fcf20df92d0e960702c14148ac4a7c1086170c38e57f6e3810192f6e800dd590f52eb670b9f2f9792d46794b7cb76047be78c602a0d3735e445dd7566b176dc804337ab6e3b31bf2d064ed0be81186bc5525fb9849f6bffaff866d3ad850a6ffb9c9f4a3c3523f92bf4d7904401c3ac4cf4c9ec392521db640a64a32e5cb9f37ce92788bab9fceac794d6b7465cbce6d52ba7341612dc776e04436336491f9eb017956ecbbc5b8d8e1cc98948c77e60267327226a620d362f0cd84da3540a8b4208636ca0ad832d74b40ce3ee16bb555ce0f302dfd87864c1a397415b29f21508375597a77e9da8e2a01705bd3b5869cfb083222d421183ba0b97821c67596ec7de8a01b97c4ee44ed33b98a6e64c38ecbe17ba658e914acab4f6c3dd633c256b467add132bc07aeea2cbc1edb38af0c42ec4cf1b1ecc8d563c7971122c236783c099c8851787a95ed71b1191fafcb1242f91695e0cf65169c0e3ff23b48801f6e671fb505b778555e46a685d65360889e8d5dd7328fbfd6bcb320d1848493bb2e6dcd26f0bf384d7ab3a536ccdef99f2a024462c9b9846c027613d8961a5baf0d890dbfe05eef95242c3569841e45e2dab81c3c0cc118261f98e36412e986d6af8eb946e74e5e9b1c34d00ddda0d1169213b5ee09fa6de1c3fbb5bf54e5b3e7b2bb941ab38518954a13790198fcb1030a164c40610b89dd28090d65964e3038175596620a2f481ded41451cd253c6f62bdf1ab3378dc3062508298f53b53397650ce073d793a0d809c1cc439542935f736d22e111e890b2da89c7bc848fe0c7f256074ac5aa439d718870fdc030c45812a0627c81bcc42f7af38c7a836328e02fcbddf0b84ed8bb67302ab058c2ccd23acde679b123017a336a927ad1c1d29df70b23090cd667daa1742b49e7eab15472b3b068b9a975d4bc8b6c6ea8df69a8fe67620da60dd30515aea150186ed495beed9fee415379b2e497169b2b1203bfc82182a9948f32b81d4da950d25013f8b3b7962484b5c540489a234f41c981beb5827885b41e1a56c6ee6d117bab0f3af1d000ae85041ffaa81997688bbb9afa2a0fc1d137ec04316bb142d21ae29ebfcb11f1843506889fa854f0ad6c8b1581907b6722557833ddfff1aec806536f91a9472e018dc80ee2c032588d0faa9ff459fd45036ef7ea27302bc6f527c63558537331d819e5ffa670b4f375ca2ad451e38f9615b5499f0c42104980f2873e5fe704a25ff4169d42431fce2d7e114a9599419e025cc84a8aa77517aad2da1c2a9d94ab4e950712db358d25b0d3854a86688acf9f5265bcfc2128ce6ea69f3fda0b0a917844e21acba85196a8e1e9a2f282d114f2e2c01cc2459d9e4b4fcfb77bed99648acdc2d58ad946142f84b9b71a7d197c86b8db75b77555db217cd4b16e9d1bdb589f486fc0533adaa7a15a2c20fcf5b43968e92ae3e910383856d7dafadbd88ea7ff39c984e485f83cdbabd831da622324a208b6f3349b688776e99e125e2a8604978b55685d16203c0456b66f2ae1f87bdfbea352ace550e25d646e033c2c418242a6a804a8cd4ab941ed1fb4ba64fd774d4604cbe5c2c91560f81b82fb56db6a2eaa7d03a44755843a757c3b3c7960b06f8672b724eba0d44efa80daea2481401782de427b7b472c371d63146bfd1901dce3130a59b8d77aef056ba04c18a65b81e88391e438c13887be29a7bbf8a3e82d689c1f8c7536e12c94014518012f83f5fb89ea754c77298d8f995719914316eb3152c946b3e60325ed2b03a7c06ff4c584ada89032bac7c1f5137d94251a7bb23fe3162b617e941f5bbea20492dc4b301bbabda9a213a59230fcb29efe8cf0e304099077fd66166cbf0bf7b5e8a08b230734672b20a1814b34c227aa355c40618b06ccd5f6dd1bbe5f2c689ab83d8a27aeab8c3dcb29b93d2eae18dbbb62969c74b022b72b3a555c9a9ec53e491b4c5d12309b274cc9dc6d0844f038b93a4793d214ffcc029247a78273093ca46c2ae3714f6dd72985d84b9a570dd72591ba1574d73e3b83945d4b9c3d23f0add32c4794d1821c0ee34651d459c0c74bfd9e8ac0a4eae050bfba319ef550a6bfecf26b50b85a03d0a14f8e54ee4e017bfa0cfb9268630cfae54291ead9f9f07325471960226cd4624e31bdab8d5b3895a50e5a3b681b2ac6d5fb00a7eb5d18c9822f7e446a42d078715896347f0d5828d3d9a9b97d4a932cbcd494c66912dcac568c46f0787d33134cc8049960381da9480d70486521353112823250d536283f33d574bb783cd48dd4a38486ab97495ead9dda260f213f6b0dd78a1387bf3a1623cbaf5fc2761a44a90200aab1b64b1995e4bc06c404ebda7699a6c1400546af9415058578fe593e4387b626f7e81b02b67a421086fbaed2f57d6141158fcc4b63898a8f0bd8a4c140c82d8db04d909b59eedcda5e346e3ab70b006614374fd859e0701bd76fe0b4106e35e0ee6655550e59c00811a5f1dff78692f107c6fd09c312a9124a710e5d36340e88e1d6cf061dd5f5c9c823888f51a41a55be32435e075cc8c20da5fc179b8fd0c0635d3506d6c91e9170cc11b141f5426902e2c60d3aaf4d2747b73efc13b7972b0607e1627111eb9a86854598c0855239326d781272becf72cbae7acfc8565f6fb3a01a56f450868f398a99b8bdabafe8dd00d3cb556d31c9b274da0f919bf4aeb21382839210140705e3a2200d28f14b06a04bad565a5e4f5aee62321f2201b8f64c628161df99f1f074502e48161cc5640d62ee55e27b616b6be8fac155d746483009bfe8c6def69890c72e2c886d86e2e23395216cd3cf09cb0327a92d9816eb153fe0bfd60a70fc4c9c2da4a3ad8c6a26052f452b7955899232267f21ff5552c072902aa249063895720fa2459c09327e8cb6b50a5356718c9ae15a3476f845cc623339772692a45a3a42e94c19c7b2359ebd23f7fea37ebf6cfc7ea1ac0e01b708cc465096a463800bcbd11e8b2232ddc8428042f559a9d0e7617172839ae24cb3faf7f5b939a275cf086cab46b83237b3a9c1a0c10c96a7c27ea036c0161861feaab87bcbc721d04faad2a25ead4925b4d9e16bfe78d57899c931eca9a5e4a7823f93ea82946915598f8fb5e2d0481561d895ada6897f7a69658d5279fd12f593c8219913a4c68dc5d17d7beba5b483862c5fff78407a8a546583d2d2b368cc49f453757d6a7b733315f95d2b1175b49f87b8793c67423c18210f84af6ba4d59a3d9896470360ff70c7dabbe636672071d1c1ecb6a7264212a978eef473cb077317efd742a835c0a2140980430b5857fe4ba6ebee083ae4a3346aa3087ea252d4c87836f7d08ca5bc87fd4858f3d9ee7f915721b672ce2538e1076e290d0b1d619f746586c8bc43e6776435b75765fdae1528ce867c38aabe740760e72b4b2abf416ef3f53f9d33179de34f2aaa328bdb6b9be67a46a4eab816a6c0a1ef6f582a2c7ab3dedb220d45379675e1224f3acc8a74e2d85b924f5005ac8cd9c1030b6e776affc990738e83aa2ba57b0a6cba62e758b4cb4f4124a16dd89eaee794c87dc2e0d8f6a562c88db5aded056d3869b43c956d8d7735cf600b62dc1bc87d68ffca26c99af32844c367fd9dcac88f06009d6390559d3d56c7f85627e9d545c33a7bb28eddb34e52ad8bfbf38c087a6cb8e6c96b7921529e6992c724c893c6f1c2603cc38cbf109a9967c9e2bb7a4414197153395d1ebe2d9e7c14c438f2a67b5be7fa4f8b4032ba0f17d0d7e007de850127598048daf6ae29c64fe9d07bd9c9abcec9690d5f10641c99cdbf9ba9c3f1eb14a00ca6c56fab6fdab950e820dccb15efd18e097adfda6776f85dd23bd2b156bb60ce0e11d6b3b46bf1f42c9d73f0fa5a70691036230ea4fb08d10f1c5e97ef7c59efabf585ea940975150d34e1abfd7f6d2cefff7c1d246bfdf59e2fbde6e2f7bdd50fb4b9f842aa1393b55de668fba8308086b2f43fc800135fd1b355b145b1e381c5c1f4feb1ca8104686deec3b0d2b2a0a452a9cb4226a95830c2bd478fc694dc00edd681d4050599b3b364164c9a17da51702e36731a78578beb0deea629e57dcdb70cdcb618e588768d4328e04fab91166adcce603f5537929aa7a58d80612678b00f4456f9db000df0c5d5e4c5636aad34ed850f17fac36df3af0e205658eaff9616803d2f4ae32d3d8d96c91e377aec8800b74bdf0daf051669f6801010a7661d68e2b5d09311cfb3811286c1213a11268ae3d176482fdf1927a7981512806c9437195f056179e3fe54df09520968ecffdeeb667351e8ad5d78a7597c540afc89a1008ba522421b65d5a1506c7b3393ce18ae13f6a17e541201f4cfb3216408b64b8158687469e6c7975e8c309ae0847e3551bc76f87a01a527250446767042e5da9779653f63627f0383d02e8e60a9d04a5decd38141602663f88766ae1c083a9e27734168b5e67e9b37386efcaa42aee659306dd67c57c8df92ffb0e840ffb704be7aa6ee1d48224195bfb4eeeb50a36c99b6bc8ac8c823f1a7280f15c636b36a32c793ca842141d7d93039d4f1067d210386895dc56d184b40ab324fdc9b0350a6e0134af003f6b466a2b86166728a8b1b31eb4ecb8700659264c64a1e8aca460c14a6988841b6fb15930641961d6f9883cf681e5968a48419c16f8d796110191b3996060367fc8ffc9ccc45c9aa6fb9ebdc84e0b522aff1c0779b819890e1230576c50431f69a013bdfa9161aca2f4214d4e8965d73dac2053f9a5da4b038ea7684607c6f1b9ea26087c2095025b17827afde01e580409930a9704e3374053b2501d0c959e65b549a0322d7f343252ae724f6b27507537a331ae04dcfe0463a49b1c727a85eb3fd2c417579bdf0b3e43a69d6c9267f95275ee767da5859d620120b32f68ba6b8284a61ddfbca2a5b64f0acfeae843f8b9779cc06d5172285e882558e911bf296e5216411e07f20931070fb257bd0eb2b6923a78a549cbe0703d19f4d8359397f490cc82bef051bff7c7cf9bfdc888718332f81c78f21c8af8169cd9be5916fdbb6d013fd927d2dc034f72367d2ebae80e2f1414497afbaf5ef2beba8ddeedfe2251f48f8afc551ffc4d6847d78723d54de312b9b266c832091ff8396971f330a318054d084e76ceb7ab2f780426dbd12db06caad7011cc7c4265cc0231d58da6499d5218036e07ccb0afad1e203dc451ba9e1bf95f7c8697799b02e00628b74d40d97e2ba8af5500c4d0ca9853d2ba6d5973e1065c90473b0d22bbb5c64ed6cf31bde01fcfd80d75d87fa357e618bd6a4575f9293bfa81cf10a7e5f8ed76e400a8149ecc4c48c04f9a4c2cd9e97afad67d2bf37bc7eb327b9b3baf1565218570bd12cec3c5741ddae7cc4342fb42b4579b622bd1e8ae97570bea3dc7021153a598230a12eef96418be4d4387e970dc233ef8453f6b0c5871ea736e2731bab02f8c6ca54786097bff14c3be49521581f4fa1944ae0ef60589eedb6ae5b116c2f3b900d75e8c646ab608327ba6c366880311821113d3412493d4b5e0fcd232c7bfb57b512a638ee498377cdb7c43a65964204d21ec91a294ef8621e7d02ad54a71fc182fc739dabf344d92780abeefeabafaa419be3882e5e02f73badcc47e4a8de54df378157c4aa38fa3f4d948b823b66fba9bd445da34f6a6fe4502df77fff310f3787c747be8812edad15d504d745186ee1df91a0a56c355b9e5a41d217d271c90926ab6f674248c2d1aa8f21f61891409d2426f28fe4c018a950a67af8d225ea15c9b81c74c239daec102ce8ef2ca68ca28f04df292632c78a9882104022748aa6d15aaee94bca892144a90a2eafe986c75361598e8b7fe4f871506457e8ba163d06fbdbd3f445f5b8bae944dfbc4d0a538080169b7dca32038bc5c1da95be360757c226659a3039b72e35d510af4c11bbf18cfa365209461d3f80ac5694245998d3f75bd94f31c1ec7861275712ea61756612bceb76e55afd03f6a2269a9c5904f012f99b137b9f92ddb598b1157134f2a8538fd573a165f87ab36c071d24c1213a45719a36abe235413414bbee3c66d634957838872b1385dad7da4ac10e7573381454dd991e1cfd586df5b24a458330d656cde6706073d1dc1a40cd453d8c1a24a14cf1a9fbd616824d1b20d11c3ccc17f88298d20d71519012d05ad1b427b8f401dd57609527c70b038229994b7cb0e3d21adf4ea5792dca967a2bd2740c2eade62b59012ddc2d01742fbc462a4520d16403ca7419b3827e00f4d130da455dde40b49c4558c08727b8574b2b92700f52a2d8e4d99fba91d17c065182d9468cf2a75ff9f01daa4f63826586c823b049aad94b1d1ec659b87c4d2b4edca34e72b746b06b7b650bafe5ef87cc4acd187bb9a20dc37c644a6b9002cffb436cc913771a601aac93069388242ed76f92241fb6b2f9b31d3d87068b2ed3b3e5dc6ab9c17356f82f23c8c2decd397055878158bca73b3eff8cc279e59b75c4c4e02d9ed6899e0065d820631fbb0a5beead43f10ba9bc8c808cb6ac7f088cc88fb231e65491b1c894c824c5e3ca58da0358f2922d56a7b3c5e83694af8a48015f16ab63c89f3bba2e54fc65e6946a5953a894ec2b365d26cc27b8cbfc1719f780855d26bdb0d4a25bf008b07f792305717338f7b468f90aac14070ef712f306400d47f2a768201b6cf26a3ae7224be329af155d65ab072eb54b408cc91f92bcdee7c045e4bc4c228c4cb0164f751d41808f34070038000268d023bf427a5faf0e87f29e37122bf05a442f012a323ca53d56c6c556836830eb58c90b2000e401b938ec4f234b8a67823d1c282b9221bc55af67361170c0d8c756d0f010f04cfa06ef35f331825ae05e1b25d91cd53fc76edd8f3a5810deb7465c36e4988570a7fb0678ed5b3d943b3b5c9d4941a3c2eec868d85f4aa2ec65728c4f5d937333cb07c8557e0f45e7f81555c9a23ec5ce608ac3bbf16b424f125c9292573b6c41958a56a973cd3c2b5cf203e4450a6bb9b520c72868a277f635c9532e85da2b9a22906c6010bf2d9b8922586b9061419edad7d88482b2dce0727d92c51d62442d4a66c244fff206488472e7a7b3be9b5d5849ac5a653a9394681883b24aefa7048c8580e3984bc476414b1f2db170e8c8fe4489d4a60e4ce8fc108717db5f09219c4041fa26eb5b2b0e82655a08fac6b389ae7d49c38b445e25785f8f70b17a1fbc79832b5af8037a31e823ec118d7cad94c6e102b675c1c66ddf5615c4ed6a4da1e49b7b31b75c3b8487b8ccb9cc146c35f50f5e60fb2a9c78d217ce5b127dcf21c1ff56f218de60418174bedd1389c2b2e4556ed4cbe625b501bb779d1722eacd443eb3795a479b1fe17722fb7f9a18267471dc64536ff90466625dae17a3b5d588f65b5b951f2494147f730313677093d0f2f74278ad2be08b7552e9c444fd4aa25e24e1ad14e80e85991764198ce89ef1668501a543130d667a99e0b7deda1e3d3dbc416a733cc30600af0abb3929eff46440756ad00e06cf065350a3887e5f2bdc9651ff0d7a6f44ec0b155f306a0549170f542cd391d87f9edb010860546f980c4a9f17099d1a527ad19b7141e76bcc426a5fcebb860a8378f74e84876ae47abf920bbd0db686e4430e39c782c87420174da2b40a37d6d507bc4f5b527d4f926c3ba8431bc75059c0af548491e6d2eaa529f96eaef50db19c7b463736d5a0c5a96cb06aac370839da94cde2bf74b7306001da018f70d58a888e3b54b9429519dad5dff4c4280ee27c4ef29fe72c9cf08fe5cc5738d6285660b99118b6f602b95dc5fc808bd9fafc8b2f7deb6cc60d872f5a076add979ecb4f41639532c8dbc1db73f2e0503f594f828aa526a9e80e4582a6020c8de26b0e8bf28378cb22f974aaa00082fb794e1ee3d33d2c0ec454743cab1c729a6b414c2b576d4071879343d29b97e5502827f8e241074a7f6234acb8e19724f8819890053cfbc9d488f65db3506df1597aabd3200f1886d1b2d99f2e711735930c103c8a2a941b1cac785237d1c7f5dbeac84d6a0fc2d7d8cbf19709447199faa6c5c50410f0587c75d1266e2905154929159db0fa48baa2ebd190042689bcd0e66c552ea4dba4ca91ec64c05c179bdb6f9c12dc1e0bddb7b75b328874b1e77743ae20c746b60636876c59ab59774ecaafcaada4f8e02819de757b2f688d7143df569bf7af68af8b6e29ca02c28bf5f782b5445df3661db134e21c5ccc0f55a59fb12cc329a030d8c4b583937a434c03634a103b0f5198df392072c33e5b97f8b630593737f8c70d8c08a8b3b5b3ee55216d238e7e33ccebadc7d6dabdfc2aef4837471673d7283012bad5eb52150104845e6de1b8d79953f62b1a56ae5f5df7e3c021213f62f0ab974016e91324ac87f147d8285834918a5bb8546055076818e78215b7058bca787420b9a358cbea2acc1071a39004988ca4e75703e7aa52aa4bc971c2295136344393c9776a18d56daf526401fa661696873bd5e6585d13bca8675e8dcd2e8c6ed1a4f7f2fcdf685d40742f47a56b7099b9a49b072c9f9c4e0281bf0c98148e73e61ac479381f46d8bd57335e647767cedb2d8b45fad670045fad883fe5dc6bd429607e91964267d7fd88fb6707df84beaa2e8586d578207f186973ba8ac49be32397535d4e03bf542bdcddda0f22a18d0fae3f848bd8d683288b7c9e6d52d887346a5c93c008944353b695010dfd846eb0b9560206894a09251a1e408aa19fb7fd4c50195aef9530630ef53f64a7bcae3f194d245ab231558957527afb484a5677c9d2431d1b3626ca7e0e99220761aa4932e25263d757e7c9275be55e779099934cf5d5b3b646c829e4acc87d02f47ae5fadfdd6ca3aa971b5125012a72a7dcd9cb483dae1a9cdf74eb5a086303d2f154ae924699a05e4348055879012cfeb8cf0f6295eaef9bbf417b6c623df10931980750c8dae3c250c853672bc1cf10608291da56d21be04aba4d2490a767c37d9e2d42c03573d3e851382ddfb94129aa32538996ef8d066e0c88a1f8f8dfc8e9592deb0dae7a042c11e29df3c0cfc2cc38385608a92e35841f18e1e34f72d24195ad5e843634651f596c895401e7be75798138fd07da94299736f39b6a19fc628cf474b1cd82b96d39d4c0bb14d23a179073d6d74cef4be146c9865915be674ba9a9badb614e06c17cd1da0e883f4dd415ad3f776397f6f2fb8b694c9cc5441e5e2a3e015baed09264587ae7926a6b7f549af92a6b87ed38c409c7454ea8b45e06ac6250fc3e56d7da21ed9114befb65dfcfe9be0690117fc0f962a910334bbf71c47599c91e764e1d726644d1b022960fea3f016f1ade0398026cdb2a785b30dfd30b49f4924f21a44db4bd21d4682ee270ec81a217e24493ee0027f5eb231c0a507a2dd4370117b5d36b147eaffe020ca2c4ac7080ea034a548b4a1ae8fef9a0825eb438d78bd2faa128dfe348868e9a9e886a5ecbcac4a0ccaf4f23f70bb45e8bcd8cee3c930a8b0d7ec53ecaf65c633491b72e2df8b8c942f7252022e458acaa2292d0161dc138aec4960f4ee44692313e8b909a4e10947e6f217a2feba349dd0b2d3b4145e3469aadb1738449289974cef0b9803d363267e31dd4bc00e86ec508be34942fdc590640a7cec1b8c89a2acd8e2d434f3cb5c6961e7377ce88e9cef861394629f0a77f3424656fc85776733f11da928d884998644660c25215d18063b2d738ed4de820eed3df196334f552acb4eb9d3fe202dec81af89dfc17bc9372916578ea23c876a75d11a61e879a6fa80f5f985ea69cad00e47a4a8636b32d795a9baeb1b55d1a529876108d83be0d78d75ad14a7122eb59a382c33c723b1c3161ef42f6a899143710fa52e4c0fd5f2f8c4cd086961dc06c764ca0ae9b40849575990e7bb586a929a046bf7774902194b9b16b7b2cc766732b628e9845eb8e93218c13f1b33a1d0cb47b6cc9172913f83c464fb3d3f548ab689c8611fd2eca03947e0c6994421a776f0970a3846c23e4d728d917ae53ec01c08f2dcf3c6dc0265a30a658829f803810732f6f6c1103f9498b4fce4a53d0988a9c1bbefa034ebc4037251d3f85987952734d855ed465a0583f5e86518cc10d8ece6305974e19c30fc37b7799aa5ae69f4c9f43b6059e565ab7597810b33327515cddf07f90dd05e1cea41b65bc6678fe031710e19272d77a2ab0197a6b39a73ecb4e27fa924214608129a0e4688330155be3e26b4060d2abcc0d74bb8af9f219156ba89d1ce11a2adc405154427ecad6c8a0424de1255d4632f3c2a5734e50d89cfc5f40b5f446d93761e6da447da3a73b4a47297dc8bfabc03b80332421e202681b5b502a2065d9449ec526488a4893483d0ea17205ab00060246390d1d7618aff43e7af3b894dcb1bb477fd0594fe58ca40ceea5745e2ea52f08e170f9bc26f510b759b20ad38e08a007e106f715a4e6e298eff8387d573b6b87613f0e56a848a584fa79b76efe9f031724cd34364b373d317bf334d0589b63408c0c451bb8b58394f836d0965c5d920725e1b2f6c497f91cd2cff0a72a1bbe06e210e1bf0d56993896169682a652c0e2fe4a684ba8b5e282afb0eb6cd3d64fe34a418495762052d05f8f84dde7f359a08697a233439f23ef0af5d0c4b7b157c17425af60f1a28a942434312198d12aa97215c62eb1378b52f2113c818d61d208152e9486f2230bc45b602028fe5e1a4139e530a9981037642900f34a0fcfde81d060c7b8fad2ce04ff16821460111bbb9657512906232064f015587d4946d2a0b351a0e5d8bbe17093954bc91fc41c21e05e5ae38fb7b7f2c88f8c401b6b1f587f991e30cc4d0399b22af251a2e5f3d1da9ea8dbe4f5fe892d80eae7966a0a7f145f9236954af16f4b79a4b5d783dc9e586d491f101feea293f34c13a8dacfe1085302687bd618f8f4f9de79c0d1d135a7f1798b54ddb31a8f335cf4e268f18863c208b9d57f36cd681c341d03791849365cac272ec3fc982e9a24b7b40b99f7a25f3460ca7ae658c0e97caebd64e88a83b4f34b05409a72225d2729f4e14d59cd870930e1d30564044cb04cecd8d751c09e38c0cbc597a54f38aff8786c7819da5170a75723613443997f064e9dc6df75ef4f7b70a12ccfc91d3237434b2ec89a757b76e75f193d63a1aef71a72cfd637177ee07ab769c7283231bd3f42806ba590ebbc8de56f928a3f9b27187ed2c444c41542dece29156e660e50f2c7790f231b8249783a796948a453b6cb372854949775890019d1b495af6718db1e76e0b7402d53aa5385c65cb216070cfd83b3f5fcb6957f78c96b69517b74b95b78d8bb64b97dbca8ab7474bdbca8bdba5cadbc6456fa39e6379a1a5bb207b1dd8478567733e654b3bbeeeed663108f9281310449580104fc1fb3193fd9ce1cbb339ba3c19a3d535a2c62ba94896a5e3d53fcfdafeb5fbb53c6b3d12614bc415114362ff90a54531dc6b89cb20c81404980796a41bbcffb235f8dd3cbde4d116800b9786dc131d25673b1d350f657e1aa128656862d055e08aa4b74b0a346eff4810ba92533b9714ba706297669181f6ce21c3fd56b387d130305ae63c1b114693ee4ffe57100bc0c707a650d011acc81ad9db57f31c7dae89b4245cacc7ab97148f50b577386ab7cb10402de4bb9268da39522be3344100e24fafb5b823d657d8de0545bc6465705b1b9159281103914c6b405d824ee902778e36f22c5a9199753d8f1e332e46ae4e404f0f8994a09b8ab1b05246329c7223d53e4758ca3621ee8f5a059506be029b27673167357ffd8055759f4cb3e6c4887d9c579415eae464df48b9106eaf665eab0c97f041858ba85bec790df1e58a5bd4e3873880ecf85b190f575fe5ac18e4b5211670937a2be3cf67b894563f11266e381782f67affb7354448221c92c1c3d304dc96e9ce5856da487a3b9c1e94f8c12f5e35f4d64646f773eada2b198f6cbc2d983dfc1e7a70a4fe78c387c347bc101941fb803feebe43bd9c0f96df77a199de5297bedba64fb1c9fce3681f1ff4795a573413f2e4bd6c4e478da1a4eda5411891adfa4dc7e67b22523779a554918acba29c9cc6a1e2305910fbdb547396130a6a8f149f34b7fbd79f23113588d0b5638e8abe68939fe422cc77300428d3b5c989ca6445509638b9923dfb337842b0bf35dd1826a5e24ec9e319331dab453ea4a4ab539bdaba0fe7819205b266be204e01715ac64d8cfb7fb84cb1859e2b3d209d566b12268a59efbbab3a86ba11fd0de03394767331e582098732ad7f369c42db9300a5a3dc97a3c6ac26628c2ddabd63e78259e69214de64da6b62c921010e240539be28e538ea6d3e410928b627fa800ea085f0e21401e620e79022735ccb5aae815a5b0538f8b5a888bb6f391f9cb3e50e6ca51c7c6a2b19f370b76934283cbb0c2628d21e57976340133b172e20683a8c242c545898bfeaffaa535233ac0b0d53d12bdfa178ea865905904b3cc4d6b3168e761e181527d73c84faf88a50b6e49945e34656a5b74550cc38ae8c877f030d476e1bee1b6970f0224c4634e8478dd2987815810f2c55333b5adbfc321e3c88a34d718ad6c80607445e4f3a38ff6977cf055b787afcc0248b1915234cf9352c9fefba186ef47ef2d0e2209c2b95b46591230ebf2383e22f292b05218127e6c9e0788b7c8fb9ae5e2b5cf4474420f54803074273ee8ae900eea51029a0d9a524c28d74d86491b8ea4c958ceb160dfd762792b0e607985de7fbd73314fa22aeeac4c46f300c7c70a9eacd5dfc0c67dcff3268f56f6e7bf55eacde8f503966d60b27da92f1e4c2584152b7d5a436af8ab6df4b45e3e36d5d1de24e2ed5b99983c94d9e4b929f64c17ec6abc4acd7a0db7d590a9a36ee8ba6a7374363f576bc984320dab422b43d6945a33ee7063aba55122a1c203b8d02e630761cb3379bc0ea1e213e56eb301038ab797220ad9546d8d84ff1c54a533be9a11f54883b884b88ffb9ced5a76b420754a182e62733a5fe87fdabffa9cbad7a56f1fcca677e89b506cdbc39f8e5862c21369456a14254d60a279acd8589dc81494466f39b6b5bee73107112a158ff65d06a5f6972a9c04d8fd9c48b6b636ecf07bbccb8666c138d37251afc00650394f74833071eb85ac5fa6f5f57ff0aef56c7773d6394bb7ff54d8a6491de9daade353dfac2da30ecfcfc5e8c8890c5a6d80496553025beb66d432ab7f9afa2ab89ee3705a44f1390c6d1019352976b4856244ca35b05265d91c365727896be54ecd54b1f521cdd4170ed693cab99e9ded456db3fc8948d499cbc5c4bee65371f01ff2e4be8911321e1fa45551282feaacc97225d586a827096b6037e867c9948deb1ea9c7eca24e556fc0f6a5dab0eee063d531b256a59086e346f33a9ff53020697cadc58937298cd1b40896cc80180d64a8312d548fb437639624b249de3895fb40b24cfeef60f07809d18a83f15bc9c1b487eb2674410f6b8069bf750ba3885a6b1fe5d412c93ec12f0f436abb6e00a100533d62b67756d139cf62230612b07318819f970a0c1b2008592416bf720fbb7388d10c0f028aaa5b44bf9a61fc86d6f5f630f5e89fe99a2e1a4a048825b0973d103482fd58aebb128c597b11b574723abf04a326a6c5eefd17711eb47e69cad96f9fffe29afefd2a3bed740679095cebc9462678438ba5ff2d587fcc97d6629cd6d8f9408090cdc771a30380251a309aa0d78bd6045fed4991c8fc44d4dd9d75e1c34010ab4230f6cf26defd99f440017e6c900f7482d705d7b0307c4014c372dd6b27ff605aa794ebf19bd9af4305b3e0d033472ce3ba185a2695e3a821b27f386a8bfb477dc21fc85a31cb9addfdaf7687c9ece4601b8012e14e0d35429f51f5aac9fe4786d3a1a91e99871cf3ba2007f5fabe8e2e1947ce6ab5fb5ab4dcd297c0e18223cead59ab76bc7c36ec4d17d0a9c0df6b2556678ed23f92d5459f667e8d400eac3e9ac004408209936c92ed95d378ee88d2bcc4a468b6c6e5a3fa1041badb3a0c716369b0bdbf45dba18ffee9bf7ba65f8fdd3b230603ff1b29d7d769b69cf83b13606e611f1eb1f06eee7bb67ae79d4cf4ec381b981aa217f4177612eb060a7dfcfbb3cfd83619526ddbc66f5a7fed48716167328f7ff7708c8101ce1e89e7c0987553ed963575090bbb3f810edfb68dba09b8a8703848b7fe99c6d8e297750f90a05e339abe3808f6c577f2e84531076678f9dcf0ce1ddbb44fac148b1d9630f03008e619c9977bc64487c665c6c56bd22d62a8b9be317d56bdd1e18134f99714cd42369f08f0104c3833e06828d8908fdf73a9a6f9778d6188fef27840157a34cc73771f93f9216a601c012e1cbedc85cae7e9f1fa7f9fbc6e4a438b9ffb8263d331605a76f55b5c659c0ea923d32169f16b2bef26b2cf2a8028331fc21cd8817510c7009f87a6cdf1984d150917020249a6966397395fe2ced00e129fe1c8303cc9a3daf4109f8f13bda0b8693b204867179776a24941f6d9d4eb41ddf9859f62bffdca4ea3140b9a130e7efb3eeded5cb64eb408193111087d9fa3822ea3864108f8ac1badbbb77961c8f026279697b9f1ca74618c64d486f5cbb037ac40cccf34137f803fe4fe4429fa1f2d9e4d7adf7ff78f284efac63f1791487cb93c6cb6ec917ff0bdd09a6ff8e18eadb3bde91fe6ad2fd2ae9bc04a9e6ce54e42635bb06c0c9ec1d4226de456f512941e00a7ffa71fb64f5c24aef3f60ee753d4552f1870eb6a8ceeeb7e1606e2b22e2c32c0fa626d0f3bcd7b6a1e33b3690e13726074fdacb27363a50912f5f4c77081450d096ecac71dedd8e18fd2eae2dcf960c3bec01ba9e0b941c08a0d84d08f0f58b35fabcf0fc721a997043385dfd1aaf5997db77ad57a3dc3531b392fd1aae7ba3ea7f31bd8df33e35658498fea2b850eeb84d105eeb4c1e8791a70207d0715b4102f091460f8d001bba94a06db1a7e01269b3accafaed9857a6ac1ebad69191b75ffac4a4b8f08ea3f4a26717c7d1d8537edede29f7f64e57a47398a18e656eea1153eda8526ca54298a1cf947deb7a3d0084dcd0f054b8544af88478b597c2723d1e2c722c02f6282730a8c8124545ca038f2f88709b2c7738541c1a5706201f767476d049c6c3e0c387ba8719232a4f33c1bc200f17a1032b80fe131ca68286e85cf9feb7a05dd1065f562531a31d235b567a90c36e9349aa6f65cb95cdaea60430ae74c1997139515384a2fdaa3ffaac9336615107c016563f92d1cb7c8464cd36f8d019fc6dec16a6cf7e2c87db196a3ef13031e66a20e2598646d906114b32d2825698112fd487c18d33939dbd1f02f539a1dfb29b9ec837d96d2774dbdc36b09dbae02b016f9c3e7a6a83aec4e76269ab68c399425613f755524f9247837d079b10c969659d50403e8130bfa7ff34ce0fcb885463114f59c1b527c23ee2f3fe0481015be0ad814a6361c5e40abf438308fab662b18748114dd605239fb85d57387823af80a8f32688362c10efffa038d103a35ad40729fcf9d4e17c68ed0a1b9f53aeb758c71ca3235fcd2f6ab413da42f64551302754171ad91d3776e33541620bed988ae4691ef22aa7c038c2700f73ea4fb399f8f96006860771795b6a643e27fd643ed72d13f55fc9ac396e94728caa7537c7e3d34a8a47acda6034751cd82217e6ec1e5df6265b79212215a8e67c8db96d99a98ff7aef4ed196886e144a27575fbb229e53491492a8f885c4b444195602e5eb004a92298d5e5b86329cc962f78d94dd058d3ac6bb86344ab0236c5d63f9d84a0832a801e3704ea4b85423d43c0a2ccad5f43465e83b871d78c63dbd2f1c8facc4df29af5189c1f27ba3913140986dcd49b2a142687ab098c6c51b2ffee2c6ce17a105eb734e83a92e91b40f23024b1502d5351f501fc8ef0b8ff0554be3997473c761d2e77fcbe0518db9c4923f6b20e163b3eeda95ca2eba7f8fc768481fe6210f204e66ea01b6666ddca9322a22ebc316e4515aa76d0330d4259cb23a53b00444565a877afda6b443a84d01d0891e039b593f06fe1a483948053110c6ac214a6b972699af2ee1177f942cd4c59075131f025fa2ea7a3fd7c97beb3fb004bfbbc769c21a7c064f0101263f1cfde3957662c6752743830749968c90a0f708fa6ccf761f939e94635a47e10bcff690d10498f275c30c7008f992e486d9b220da89486e1876a2b2b975c3f28d3422c2d2a054f4bfe18fda6119f0561562af6cfb191b6e1030b3ab653820c45264d8f189603b8301e9604c4836d1232faa0627f6cae78b456564114f32a7206033b84e16db2ce8eb5fc595c9c4993e019695c468c2642006fc0fe7d3812ff859a84bb0bc2f06327a30a1c708ec85870f1b8e4d4896515d87ccd45d029837e6a822cbdb96c0ad1c88212cb778bf897f0b99b223eab20fe30567dd4f1b7b18bd3499cb6b9b5e0ace4ba078594f558a425c1e758b7733cdabd53a32c9a561334010315071b08f1913274908158059bd8939ef387fc95fa37b79f785d0da44cb551101d9d438e0831f99e7e0692d96771f3680e899b0444ab40d8ba6adc11d42f15b4bb49027110c51e87a16b8b1671900c8932ea3e71a122e2c6e64ce88ce411f29e663f3a69d0bb90561a745da4215f4d90f4d6531b325efdb045d718207b33e5e84c2725c9e8d01caf25b6a45dac35a834aa312c6cc1de5269e2b5cd069136e732e2d74dd211993fdc5110aee1773e4e33b7943a8f3d05406221aeb9b34a9be7613867d3d06fa0447c1a91587fcd3ca38222e044647a917063c229411198590e588fdcae46ed80256a0b1467c7f8ecd2760c3a4c293a6c5b0c663ef84b971694ade972795db059878938608ad1b841c289a016e291e01b95aa896fd39d71e8bf8cafdb128f5122fd8bf0105e0d6f5c43b66bae6fd0392fa5eb1992bb29ef827e67d174a7207eb56fe34c2294e8a0c3cc0a2102da57a22cc01cb1765f012da3557a5f3d8bd351d3b3761927e88e78e281fec06a0b88bb5fb36c45af7553ac229a9466b4328598a2552401a1689a128073d11dc95711a42ffb2660772ec180033b7b2907c03d796781603df3d6e1b808c83b60a93ebe88c18fd055c64f302a2226417d84aaa931d10a4932cc997f5800c6fb38484f6b821a77ef0e892f8139077c4207e60d2219684ab53bfbdf17e665a4efa6f514ef73c268bd1551180545865bdddb33adee6f52faee27911fc51a7abd6ea5c83ea06dbcf477b78bfcfd57d815743722ffdee5a4f546f7963fc3a9e3e76f61c681d51cb75a5adae9b8bc2a7966febb70344108799a23d8e7a6caf0c3fe17868416c4f5bad89c8b0699a22d8c3e1a0d40ddf0beb48029ee3255769595033791f4840726df104c38836ad8d755c0e8f9bc73eb1783716361e404c809c59c599ece6182833d506b9ae7512747db733972f129fb1af5bd8cd4253a2bf73df4585751f520d5ba4af715418c2ba852827fb5cae2805a27ed01c1dbce83e4cbfac681dbe92c537c280eebf6296c22fe28d9e26ba4c805e3f3940af3245df2149b79545330e045f0b2be3708cd9951a5cbafeaf36c7425e729207981211dcac20fe19b9233dbfda61bef5da6c2a6cd0dc229f1952f23f7004aa47160296a0cead82a6709965bf3e6282ee3fa0261d8070c5d3cbda218d512d6153da2a21d49bd7fd275fa874d82d1c43ce8f7fcddcec9ea908bda315ed697fea07f4eceb056cc3dc063f450e719fd6855131376472549f7bc6ec941f0024824d16f802685ae39fd124c28abed1898360ba1a497cda91f612609912b315435c1515d3d0d92274d9df3bea965d8b122e27c609aad00f9f66a771310ca865673b87bbf904742b2f470eb64e17e9c583e61611644cde62c22eab554ccbfcc93f530121d519231271ceb6a07dea3e1b027197b74f18395f99c0cb0a3929009136da1751cf4453c34e8836de5f13ba043f9fc40d0a2a2fe1edb12349e0923264ca631b99c926cf955edb9c70d1dcea804902a6538e7797c5808125cafa0327e25472865b7f5d0185fb6beb5080b9d6a7c519e0686e89f3e3735e9a8eb638b5b491266a96fbf12c133a75128f321e212e2ad7ec031ddc396348e706900090e5dacaac21c983ec389835a48f1d2af4a1326d19381d874632a7b03bb16141da829a6b230c6535ba5aea781b9d9cb20ff2346cafdfb9b46d03ec5b116f22e9f5b9cb2574240b66efc1e9b38f1489c0ed40abd7d0b28a336ef0e965db6c00df7023785740004f560eaa2c395d3a07ff6ca6ec47ec33a9ffe5766afdc32ba445df4054a40e347e6b9dfd33fd64b4b20f0fb406fe558f147171d33c7e8c79465fde30425675e49968ed7215117cd1fc27f40fd57e9a2db6fa4b81f839a0b6d3e7d1e7de92eca25e8a5648f3d315ea091d6a2b2fbb20b8be8a723f9f5d0ae06412a5dab6b20599e2214beb4f7c5c5f1b16ebf6e582135312a47171be83907c7550a99b9ba1c328221db0a9068b5dd4ef12ef8adf748e30f44644c1b5339027c8d809c213dff7ea332ee03d017f7d1ea3a45bab3fdc8f4cb46e531b972d17238a15879d69c2f57256420eb69187f67642065c053284a03fde9d5211d6543b4fa4f2a963264863fb2f793a49230b2ae7187fabb6b72430ac316dc225dd827d6493a5ebbb6fac038cf5ee567f6a4d190ffa2ae3010f9bb0367fbe843f777054853d1df5ecfef059fcc72ac446325c24ae94e3121771f1d962e3a2f44810684837d8c60f4e46340fc545123142a9ca162953db320221102628afeeb8a04df6d43f062811919d5e5294a542c028cda17c4a50759b816fb0be07a4b2e09f0d4afc5fc71457443ec86967a44e3f121a670e3f7eec2dcc1d87a2bf6e6140c8e8860d80b76e8657d9938815e492f4d5b1e753fdb0c2b2b27984c19f46552275de6c0d0a444d190245ff48d806dc81346991a9c20a40b8a19f6af634aab443a06f27664e10f7b450ac1c8e8986ec765b5f20bfcf30767f0cc565329a088f2caf6f8db9ac5308b0085b171cfd738ab87f4ae3aea4e6db0ff49e1882b49aea187672875d585260a284d402828c1702bc737fe63cc68df536179d48e0f620be0d11aee34dede0ec00925778ab19ce3e40c8baea800b098848db52f1d564f692b44d48a0f9b5b0df37246837bb1ac6549cbad4475140d56959790f7427a4c33a32bc49a97cdd7f026afcec4989d3b0455132188b704ad3b092b6f9f96219cc77fec934c2429d6404d27c3967f7854d0bd0043de32e9266f38d4ec276255c2eae470be0a503c5d8f490ed9491d09b2701ec0141f316006981203c46c8d5b1de9102a81757f9108e2cf0826c5b8e16e24496ac5a791479dbc669fd4c97ecd53b3aeda0fb567bf786c4ca0c7ac188f01efdb518a30629532c779fcc7872173eea9d1e6bcac2490d059e15357eeb33eebcacdfad4153bed9fba787fe5c2333f4aa93209dfec2bfd66dbbe51e8d9beff5fa6bc90894c61b6000947737403741ff7c7cb141e00f83dd9f12b88002e77c6a467bd808a2c0cfe6a538e2fee4ed55ab477b79522ba58d6bf17e88327c3c223cb4714ad37a69d5f3a027b3a9b4a849ef1a02b23d2045523d2f49a90866ee64d7f04d9824898cd3df16ef80d4c51ac967d1d2fc2b2f2820d328184a99be8c9a1322881382328cd163951a545c1bc01db1d1f7d0e2e2fcc36da04ef10d71fc4a546a69bb43f17219cfa8accca26905157368a1eb118f655c7a57693760b1042d282653c414bc9856caa818617fb520fbcac1f7a9c66f3cc788b7c6bdc0415dfc7c25cc3fb6f48ff94512e9b8305234f85b37735ab564ebf5bf02a13c9cfc9edce5be6404223239345c32cb8bab603f94d427a8b3288cc1752c3cf02bd09a41a2e106f94542a780e09bdb893222e1709f84443e58377747544e051771a3687a34a2c3adbe289c75f4232224a7d708cf5b1cf7e95a98cfcc59aa8e9f9a8e65f708d4228dd26c6a01847bf3ab4c6fdf194de14416b472cd8cc531b817f2ccb2579d28a179e01a03f821eeeca9dfc8fcf700bbaf0fd8efcd5101e1752cb5b8ea04606ac71877f67aea825a82967b04227a27514c483505ba78b3f4fc5595ade9f12f47a9f58ae4b79d4440baa97578ed8a78657ac2daf40cf13b7205693d8b1e1e93ceff9a92008d3c51c9b3f7b4fbcb75a09ca2271c074c2e60fe537d3e33b55618096735c21c81dd13ce031adabc5069bfc066d73fafb1879ff045084476eea188f4a0dcae89403998db74502d11e73e985772947996770b406b8f0945f52b58efe85ff95cd90e56b7b13b29fcbd876d57107b2fad9092dbf7db0531f9670b5e7faf003736194a466a9b49edf786b298d5ecba20252f3aeeea93a267a5c084f43ca688fd9369c908f7dc2fc23b9ffb8efb9971c118958d67ca128ae3bf9b01fb8b9c4dc10340704e0ffc2bae282f4a4c259ed299b5e85c1fe91d86534353c54b43496d5669e9d51ebbaee96c0b05c4ab58a98a06cfdc405290fdd8762a416fa91582ba822b9064c5e77e12cbe9f4bbe103510efa7698a0700f42dc24cd4f2e9ec1c642f5423c72a35f4017c14730bcbf8f988677b18ec8925ff779bf63c0dba4e1cd4a068658f0d2480f7546a97a58156b93fc388e799c0d0af32d4e63f2e2dd3eafd42b44671f054a753b31fc3adf69bec2b30ab3912edf4a62a765cea99073db6f5a1c75458136cb9cc4b1d30585949122a5f54515334fa86346aeaa6099eb4e482edfb6e2004cf8e164f985ad364d7f40fd508b6af6c8ef7dc6dc9e57f9b90b5959abdd5aa42a157a701cd55e57b3a154c1a56e33b4fc67ec79974e1023ce03d4935324050ccd5b1d5566945ab869593356bf448a4efb3b2f708ce651f887aeff6c6bb01e9bebdbf596b338d694eea586d9f817a4409937ec68cecdb19d5f8bbe7b189689ede64791e1973545b4041d19dfdcc36fcb767cb1a801db9ce59d974916a8de94d6a56ba4c60a10e8494afd9a775b29f96f2683b75024b1ff69ab45f12019d31ff11fbc01e241566fea0b9d54cd064500c8d56023441fb33c3a4f2b94470826cf269b6569504634435234337deeff8dafd62c05c3830ba17717db1e60998db1362ddda2cdf1adee8ae30d86d916384fe84552eddb87202be447e18e400972a075545eccf83baccbb2f1a6b9039b44c6b68b3a58fa0d8e378cc32cbca792052fdadb8516d2d4571a901a5cf986bf374a6b90c01e49ba1996ef83f393921a2340f0295a344619771ec11055862b0f3b62b2110539e5a402afc6ffe2331a28c90425815e5c39c11ca80cf579d2200a5801d6a1031a840ccdf5e1bb248dcec1a07e59a2171876c8010d26a9818a38016b01ce06af941588fdd4914f3c0596e3f92843cc109520b19344714132c623f3c48324570d1ee4f3b2f449b83ad7f165900bf84c10f3355b534e0812d918944e08c408c6816b33a3cf2e966fbb2926c5594f3eec4c80d812c2ab6271d172cedebce08b05870f84aec704b631098e0c1bfc773e7d2124db9e813ef679981f00d49c4a11382c329f8d6a45dceb6b8c2f94e138671dbf7dfcf81c1ed99fdd6a38f01027173d583cf438af3a5b003175d08215dac0a230eb7238521510cae5c5cb0441aae5060746648b95e6a93853a5c73413224dbee029496d7a839ab236dd3c7cf77cdfecc3d239595b8ee75471c771059420bec88f609c4841a6945d6634c796834dadb212807fa66850c1a7d0eea4d6d12770addd73c4c6f594a39b57e0d7805ea79de1207d5567855bb84e2af5704d0e957a8e49ed17e88e951980d150834d7812e53165031b11d6abb211a4336e4de98f136c6766c9dde8fd35b2928022800f6847f6b45137304f30921e063e9985b170aa00895e4f1792135891fba0968b0807148dd77d2a1de9e7bec9e67dbf373bca73c467e6d712ce764e5bbc1dc79b25b09a9ec6d49c938d7d032a6c93121a06018e22374890a808a7c053416b4771e5c419a9e9ee63c2d9e3c663fcbea88059cefcdea9c61e21f4a91854af1b0e0edfcfa1b80cf25c5b7aa765522b4d7369b7e66d177bc9eaf10372ac31638d9fb4c5607b2a6050905673e339264cd46354b8340d8dab0381d8accb24141d8b1e8e23b5b8ad7970b058206c63116dc07617f0cf6d21c4d7711caff4159d1b4cd6762f1d961ae558068488b04ba01665a81fdb40048f39b39c987e125fa8f850230525ab9fbe4a22cddd571d164565d743008d5cceba9757e449f5ea8815bee9656a0692cbb0cc660bce39fea6388459c5a31300fb962d41af385a2be11150fe6b0bbdf293a761db88517e14147f779d55657d38c00adeefb04aa077568a596d5ef4c87df0c903566e4db509627c24cffa1d1d9d21f75e0b01701e91cd9c85c0fcc96ed58dab2c8dac7db30a6cc0aea70de4121443e207c7384064af8dca7ede1e6abb7560d44fefb554574c5a801b1bc7ed65b5c3b6a05fddbb05715a094eb12887c95657c6f6a0280f1d89a00ea109fa0df8a8231cc2f0f9f415c46f0cf6bf84914c174cbda0c5f7dfa690869dc7294ba123e87cd838d014791c07a3c2bf187a8cdf1e5584db34f1f2ae511fe69e42e2208bfcdd514f182222c933c8a36c45cb8f1a56dc6aed54d2e14212d348caf8f92f86e567e758fa4b93c88fc76453f5cdcba1dbe99e4be24935066aace8b903dec2cd8ebeabf1f4c375ef5d0fadcab21facd10a7f5c032de5e8a2b8f727424ea754115278e7c6cc412e9e5b4feaae75af0b0b48c34fb515cd0dd5c7e6136f3bbf2e3905108b28e0eed23cc8007c6184292bbcde6dc7f1522b267d6088896b2617830efbae1cd1b4fc623fcbb4ef346f10998936b4112d8cebc1ffd8895802c7241cb08d792c44e884ddfad28ed5284fb4f2e75b740299d72189c978ea22290dcf80670465d8a7944ad0f4cce3e94798d707e1a041fb78412270614b2462fa32afc03a9044f29bba8ab340bee5f0e076665fb2f0f7c5bce0d038871b565908284ea3a4c8bfd4fece5e4b69875e5b812b4068e4522a17f06c23ba3cd225c64c70d5cf4417bda405b8543f993360ae5ad8d2611cdface0b2d34a1aa59f7861bd1c998cd13d6afe0265d49a58d29698afeda166d8e71c6d26f139f718d0d7bc843e555cf5ad33e5a7997c2a1961ab4b9c9a1970e5f0e04c939b0867864d086536126a087cfc327004048a18ec9d9388b4a3873325764db03b857edc630c83080ae8b2070825db2ef8eaabc054e541f5ab0913b84af4875942c8f86261db1dc591fbee2b1c7597b7541fc7b09435c7d492c3e5d8aa41a6327e4c3cb32e59e2cafbd4097104f4308750358a457859c89cdd68dff99236dcb0a4d08f7e1137786fe5d66769c98b3f08b297daa7e658c1bd1caa7b9fdba1d1ed965aacc2115d3ddc4c51e1a55664e3b6bd5165246e512b652830a364aec78947f45bc12a77b7a7fedd54cea382dc680d310e20d811569ad1511b9e137ee876c574f13e9e50f4dbf230da0ce7fb22073ece1df57cc33482ebf7f537434af655de901316536a364d0e23b26fee1224ecfcb7c5ab93e305a0936b1d249b996e51390ba22c4d6ed0c957988ac16caf79cc2940799cd30f51d8c86a9666c14ac46f60e7653eda156f488951bf014940323d5cbdde6854e0e9b87e7b53c9f823c0772c93bb65d0d7f1d09268f2fab678c981b90a3b318f0a3ec9a54591fc975480308ae41810066bcd8f1947a1daf3783e1f60e2bd36525b0578e29202b581aaab3c4ad7e61fe2e6e0fcd7537255a46c69998c960ac30851aa491f6b70bdc4b1a7933d4fc9af1620ebfcb089345c461b1fa192f878e065168847ebe571a9df6cee37232c2fdc3b090dec936c18796320ea6c6daaff3a7fbd11f3ece749743cfb0307187b1b13a8687a2f9f4e579b90ddb943545e0fdf8395c2efd0de21612ab3b218032b1a6a93c0d926325398e500ae06c288c510654fea682e0c6b0206a392ce402314d41bcc1ce7741b0a704d80a62a42ad70bb4b25cdb61f8d3694fb82e4be8d2bd89834868c8db363afbe503ed8efe53aff3095029e70341bc4b5fe23204e984006a15220be91e9a0f17a22a657003d1c5a93b65da71f3aba608430ef003cb27ae373df78df38fb54b5ffd6e24a1dcd9811cb1aa8946c56f1302bb4a7231583f4948d1023ecb30121f7e59c03c3386c92cbfe9530e0f8216b497bb03d16b9653d9417e6a07d81f8f30c4839211f533eaae040f3b358dae13c68b027cfc5021dde8fd7df4eadf88037adb3cfd33ec7d481252182b5af0d00833fa74d7365ff2fa92dcde287a7383c2c03966c21a77cc4376813f3207d6c416306e3a7e7df36acaae191943e8c379144c8831396666ff0b278d10fc1a1b5319686e45ff13017dfc882268a81fe98e67290cc392a504ca056383504edbc51018c443fab50043618e3988e88d6095fec72d601b44da9d3058d0ee301c9609d504933c26107eaf07b747bee6eba87053767b2b9e83187b835c4c7e8208e5a2b8d5b8c45d83258ba265d2e716fc56bb5858283d4fd1dbc583bbbed4ab2b9f6f7f991ee5db20ea63bbea4d1e7095cc63a544ff4c4562790b7e65a4db0828144992856a0bb805e6441042deb1a5e2d0fc06cbfe7f2b747ce8dd7c7f17b833953a92191502d325041e5d95434830e5895593dba72ae78e1f45f6b6bd4a2c2304a323b934f26530d3b0d25f04eb770aa6c7fa12cea04db295089a610e6a6b2016fa2281ff9f37dd9c2e1f7d24e41918efd40ff45ec89b87193741baaaf882d653b5106c02d0e9b3a17fa65560b16c859795f028c40d879b1e3af3ed63a7e8a18081304e4c3dfaf2821309dd746323d2f4abd6c4e3ba7ef55c427398a8f783721d095b8e27b542162709be64774f7409597df9e2ba7a1dfd480e8574840461c73c91a8a45008360adad48c2e800858ec6750f88c7e3761b9f1a64e3ebc00d9dd7a8ec6947c90dffc3dda1aec52f40955d174f45bf9718307fe7edb91b5aa5b0afe5e8b41c2b8b30b5c0772b34ef832a1d7c0c3d42d95323725e20a5bc711f1eac8e3ecadb7e5d862ca5ccbc905b158972c4bdbd90dabde693e78d0d7dfb36a7233d8ef4114f914c4d29c99b62b7e1af6b3ca5594bb216b5598cc7aa5c5fa77e8215ca6f94a35bb8dadb340deeb94e78fb72bd7a28f0a583ceb802a2a6faacdb12adb817979abdded75631eb8ef26dcfae995816c7e90712a5360572eec85b82f3014111070697b6318cd196c09ad06e80eccc3ec24221a6415650184031e3f9aa8f90e3cd6da214cae5ccc4eee95759df7ff406b53dc2e5a333f2e2d24e9d144d9762879d1e70da1b32df1b3afa66fa17b735121234571f5aab0516737089160a8f2cd07e1a91581a0e0353959e91d83e535b539023228612401ef41b3431348e84e2fc36538acfe01d0d9657fe152b4cafa99790339131ad00c1490b8c9d71496f64e74bd9acd99fc5eb85072e0b249303e78c95f9ed8d414b6e014cb6fe26e480247a20dbbf26a118bccc24b7ac38458f89ed0153416374bd6888d4870e021128ef609167a008cde69460dd8e54dcbd8443d1f6bafa0fa061ab0fb7d31f3f1eac7b2c6366496f4342b81d71c85187873109951ab54004ab064e2bd4c3490832d94315ed8dc6a0a85ca313448542009a43b0ece50e819fd6140bf78de3ce7c4234abd35c2a108fc78dc1f81158694666c64f11de610b6c7e7bd5a96737692a049de1a436ac578b881176de2aa35a7d8e85fbb59fe3171cfd70019ddb787d2a35bf98fcc53918dd43ddfbf4ce1524db91b3d87af89707c74e9bbeac239eb8e51e740d98b96d2c44caece3d7a47d05e3f06c34dc5d99de1ed3ff0d82df39889cf8bc10f560a7a88d33e1ce367140acac09f868de85324fc204bc638f21f310306adf84e5e2df4dbb8271fa9e431bd3a9256b4c7b987c821f524315af251adbd3730df19459d801673986c2141ecc4563456a5aed4e1e95f0bb06d2d00de68e1f45277e5007bb198e972ccae5d9c864f1f1a6a8d825cc5a8af170ab1eba2d46b294e48cca93458787557e6bd9ea825cccf5159683a3dd7bb2105d25d3054fa7ca31cc7c5d8e0a530327449130a6c8dafe7dbba6f9fc31337eaf51d82a6f4150ffd92bfcb5568d51599cc180d9141ad2f3b4525f7bde8fcf2bc07dfca2146cf6ac937e1b49c608acdfd991f32744a5e3a044d6592cb58a248a89e00040fe4f573879c28d03d45675126378e5b5d6f56e91419eebd7b3c867c735511b735db9f881517d8997f318813ca6534559a2b21d038d13f847c2bb3113afb15d7985f8602329b53c86daa16c0e8d7d33e224624dbbbd23dbbc1a50bea6dc456444ade532bc9978fba54192e5990dec144255e61c7f02be04b3c8eb791f75414e58846de44b04d6dc6fd2ef49e353826e210c13d4825d95cc95a8c832cd69694d73e235a4507fb20e37240655c95db5fd9efc2b3dd5038d76289c59b2ef5fbe4477b9337f3693f1296ac635822806e9453f3d11eb9454cf6afe8c611290eebbbad95853c37141e3dd219e71ba4b35aecbd4967568e089a7c58e427d59206e4d2fdded8a4d6dfbbcae6d0444f8af8b3c2318a69a3f05e17bf6f32697f56346ac2e5463ee87bbb8d72208193dfd7996b3b6597f491d054fdc31d41c5b2b0fa60e7837120505d8c80a51900c6909c1bd6f98fd8c8e2ea83c90167da9b4811a09e82f4b435170ea7283e3b93c6f7c636c88c3bc4e5f4771802e909380d5e79e96daeba7b2602d2a250a6c8aa0f563d8663433854246e01b6a437bda52a7db366189f2490ce50074833bada92ed2d1af39338c1e41d07e11669f158b18c83d40b83e148a6d7c1809d2ab3cf12160bdfb831e5286a253942c7caef8f1b08fa89c2272ea157c7205cd4ca5a088d292ae0ace9ce71d9fa96456e020119a7fe3cabba4e471727d9ded3950f99eec9ea287dcd6040506a689f62623d346a7d81bccfa8860f3be8f38c919ca9a67bb46b6dff2e77c1f5cae421cf4bf188b16bda8ce1ad41b4ce88831328b5099c801d83fcda45b0e5c036cd0054515c48f5f723c2ad809cb20cf1067c7c2ddc3545406420e9c08dfa150f7fd008a61a5daee22b92a2b8dd12c94715f346d139308fa1697735bde8370e3ea163f3f6ea4ecffb5c48a840c8bf1a609180b5e85b7959e705b9e8e59b761fa0a3d8b7f7d9f778cfaf49905376a03d6e1d827bac059db88e50126c1ff47878e52e30ddf4049dc5f904294a9c7187ec58102e8a846b4d81c1bd755e4ce123393a1190985f754ea38e18d396d0f08a60ac7bbdb78560025ee19c9a10cf906388eb5aed1ac857884678f5e3f800b2af2a087adc0ea22e9000eba5008f8a0617e600743e161eb1b41e536629b5202249f5237bdf6acbf83742d73509f070b8cbee4b250743ed3377758912c06ff23db66c04906f2e02acde40da25071a2591250c506ea06d4758840a829670b632841de6a8c3908f82a13c489c00504ca6e08201c0d78ea054973ec2fe52dee6a12123f5f7dfa0550d560245608d4adf66b2489e590c34ae0eaa2b2737c8c972989d7b98525c89cebc01636c38666040ec6e2a8dce4ce0d0805d793604cb39b5c7cebf3a00fbc57aea4571aeb6f0c81493e94cb9a9c5270216c159969f16d5177efd232c6a9106aa2502cb7386090e72a438d4e26fbe683c59a897e756704cfd3b2e173ab33ad81b0e0e358556b10f67a4f6f4e4bc55341ae4ebf1a3f9e385e4cba9af169bb67d0ccbb9cd4df379bc1e738dba43e6d3dc5268f9a320abdbd874ef77c84087e57fe9ff48c72f3cd00d3a5ffe3f0bf2a2a1bb06e6cea76704e6dc9064d901169a76253d8a5262f2fafa878f9e5591b75293975c419b768a89c3770d176cea7db17e9a9f8155e08a8f95e5330784a52ce7445ecc30abd256c1d791f12c09de37e80e8b80a7bf137a5d68cfa57a957b518db77b14a8ea1db94dd637c675c579cb9da784523ca3bc724b978cde3e97e867af584bc489d20381838cffaa53a359e3b79812cdcac6e40e1f4f5e75384b38f306811d66e4b8c69aa112e5130a853702191e5312884b6f3e0ef2e9d6bbdd3ea59225ea0d28e2a4ff41592a7d4dcfe6b3a9ac06b54b0e8a0a7901f8ac49a8059703f8de9482d1cb06f043f66d1d654d9e5c0fcaf8b88f421fab245e250db891f26e5e57a987d28cc051c06d61120231f8fe8a08ee781bb8c4342f212d99ddcb41bfe4ae23f66a96dfb6fe6bf62edd5f027e0a0552211a5606020fac5fcbff15d9e1523b744ff1c94d15f260933d636f0f6231626cc46aad7cee51d5f715095cc4c474df414d881dc8f1217fdc0693812ff317f191558f619246c7f5827c2e4030d094ea8ec612a3ed2aba8f29c8cca3b5680803a045658ff223d2dbd440ea6d4806641c34fd0ef51e0f90d7ebb7b9fc9558d642b2815180343acde99af72810d9362dea31277567af4a7bea54cdcda30964a19ee942c0550c0b832a1c31c3f58f1e82e78a6c7f5c511ab381c479d95e79cae9ec56f89ca7668bce9f4f6d8b349620155a9b3d2ca2769ffb90ce7502093bc71d5488e8df806211900c3a7b7b2a84129deaf2f4a49915046d136286bb39f6ebb82548d0dbc7f3eb76422b8d25237efd9012f8d9b5092b901fa564240a52fbff2eac8070631000d014668e8c00acedd85a8b04bdea159de827c3721dc279c065a9cd1a96e4c6fcac59184a079dc2d224af76a3b8fc5f8aeea1f0e99ac8ca1becacbc44efd25e19ae7443fc691002a4be08830d6a32d29b577f7954e7ec9caeaa26fed3f124eef793ba49e97755861fa19fd7865e5740e24f63cf1d4e80e96e53a201c44152c0f12803cf8893094ffc4de7e67dceea963d1497511ba16bea2fded41586ca903ce50487b2cb513156bd2a6c5f411f34171c75b0f9f051c5252dad0faf4c5644152475b67f7f6282d2aa0b594faf6720135b385493d8855febef2fea4130ed55e926f226fd7564507bb3bb01597b89141fa2743888131f2ca7f11f5b61628021eb87fe5992704e752bc8f8ee9bfe0b1f4c2711af57e93e96b72137f0a25cc179f2a705103c99cd2051cdfca372ce37246ad6cae3fc2b3ecc9ed25592e22e0a1b2553f15b6e8e2f268491f600dd12a87ae0204f38b48fde717828dffd2eeaab7bada69d84eb3e64f686708fcebc8b223036a617cbf47258af4076c74ad80aab7477eb26702bce5731c000a9352f33884e0a2ad69062c17b0e117a702c6ad7a464dea7e13bde9dace3eb4f762aab3946b2d5d4a837c2dc270a672bdc189016380e75259f635b3f30b2ca75c2fc1101851af8aa8784ab80523fb1eb1a1989f513a954cce2a5d07a67ec512657a21f365406137e6127b9facc4464a7cf0ef761d0340f20e2f46467a0bf3bf993710fc542c9a383a31c39285a2e7182b8d3e3125eac34b3ac81100f7336e70ec4571b0e836fa35abc73fddfed2383f007f65911a3acd21afec950e86823190772dd2f0fbc92cdbd87887683c7191404ca9b6b9df399c658daa7bb731725584003b229d44b2c9981cdb3b231c95da3d24ff2d7f40260c51ab9d28371b1a4c331eb1beac0234154e2022ba7723e5e93bd8043e6097408c7ca6ec636e1ebe4c25187c8b4970f4dea7d87d2144959eb30c44ea0d67fce200043c3e183ac5a7736a5ee0985257b789680e976d037a67ba73fda0618d6dc720a4998cf1275fb5f0d720fe7ed576152f2a3b82a00843dafb0fe94d3e22192a64fc4a064ab0efb90b41ce8278b1410cc323b501a37386b8cf866c3e616861e338dd4c555e4bbf831fe12c19c2275acdaed4adc16662e1a9f7f7c3c8ca5b38c76c690b23fdd68c5eb49c991bf029aed5a2f48c3cbc009c7ac843643be3e434e7227fbf50dde931ee96d059e424926dc53c379cd41572b0a976e89c859c98011cc3c09706aa572e19be7ad4836ffc314faaf0bd7c01857550fb232309bbeee14b2b1ec21f9e0a674d096f594443f2e6bc04bd901c83c4af7551a8c0a4143b047fb3b52d7836387615851c1e5748d19887a7172772380995abbef3545bd8667aa1bc23a01e2ed89acc0479748ebd3135209cb3847e2b4a52c341df46b332c2c14c28d91ef621c746c7964405bb600d1c6065277e995e9d65b4538b579156c40c718e3c1d5bf16a88c18756a984836cb280044cf2662a55af03b3eccafee127f828142d4722f7f92a4f074b943f79304bceccde3740b684878c16ca08176fc5c1b701007d20a770e90df8df8b14d62e02a4e20e4c0d2c8d19ff715cb209c39c03b7bd9c7c2671b5c669b1b69ff3609f96fefb71b76d823f1e8d55bb1b7ffed7c2358fe9f176f011065df8702cf62171b518d75ae9ce5044424d1a71f6d990d26b1cb96bc2b663c2ffcde0d12603d8a9721dd012ab77ed03ab1f63f0d122cf57972ed58bc94349e71a2d0871abae030f0407ad4000516350e013504534082100f39d4029331b14f65109c94ea8621af8fc6c23c77f6274efeb6b8909944420bc0b1757d83004c4f214c66029a9699df7b8c751e56f380e5ddb660ed81416085cd89dcc9a811cf3b00af058925590e7a1dab01c60847aa39f07c32307ffa4ead1a0016302c10df90c849068d04cf12cd77717198fd00e09d23014cd75d6f4cccb857340ae317866c7c3ba29b010c50cc068d4c29f8accc62c2d90bd474f5cb3343a37e2f700d283a9ea3016f90085b6510c14e2e2fb3281816c4c588674b667b994dbf2a2625608937335dd335c27159af6501c8134e6458f2d16c03179f1f31ee57dc1439a5220ba36b2ba0ce71871e7f8c66d8a82a0a2c757bcd190b261b383275c5430a0cf6759e872d116e000601c5c024ec7ddd093f9845ea142ee2bae6f02c4556efc82cf29a6afdbd0cc77716482f5bf2e8c391576b1d410093059437c332853d7528b35f9912f6c1595138b4f7d91e3098fff3d493390b82da55fcf6a95a00722d56c2c3a996d625ceebfe7f01d2ca3dec41a06096da5f79ee60308031ec05f3da9afe5b1e9bf84cb65cbcd90b9a60ec761dbcc66a93ca8a194ddf3ef5ee95030c531dcf0931a3d2f3b828ae9764c8cc29f6c17f76f955f970a8ef25ebd1c436bb4fba11122b26084f193f25ac875ba6c74f926ee332ee37b33e607f26c518c75def31764931e800fbe0ae6dda7e27fa7327471c234c899c458110e63f2ca530fce1811c122aa87e2b0db2660b977a4ba7cc500b99e46cc6ea438c4665a1d11d521481113b5ab8f2e44960e8288e7687e57ce6b906346abb1731981f7a7fe83d82e29b809ebb7da2a778573e7ec65de5ad12514e3b5beb0cd5440e142c51d34c24ff78c66ed955c843e52d1f343d5ec1998be8904422aa72b4fa0b711edf8878779b5270050b4c82ce3ea743815c4bece0d03b17923c445a47019e21d20954e740c70d8ee6205343b02277a7923be1b0450625994bf6277e686087f8cc095066c908bb297e8ad17175a0479523580d62c9106bc93783b69ec8a1a1610815e7cc60a94ddd7c122f0c41f4423219a5e685f3663be489a36799f79bb8ce5d3d11bf4864f1d216fd737f62c33cbe15c124ed2fd0ba086d15920ff29a6389467cad780c1d055146947f8fe099c222a8c2dc51bbca192766ae8687563a851d7a772c403f2b28580c59cc017dce34b2532704cbfc37f419c8d1ec77b5cc8ff6a805b4c9a45096588115696eaec70163ac69b8d9e112561c722631ed5f02b58bf72b69486cc1052edc47f619531050ada639c0b3869e1ce77a0c781d3d393a4e6aa0814919fd628c91ac73f231e9dffef7724f132a84d4ac4c22577e69ff8c8d63efcf892c9a3389da9b885cb9451bdbbf1e3f26eb35691a8ce5e3ffffd68dc8d61dce19171964f979b40cffdb5fef2b92f22ffb87227998737ab364a48739279e25242a4c2c13c20e859a929f1a35b9123fa01faf944f96fa2bbff0033f0c356a9f9e14c13d9efe4793e4a74ee1270e513e791a7f48833f9eca4fe8bf2487c893c857a4c857e489ac3b5cb15292bfeab283e50e3b96c09f7f40e2a8a2efd1925ca59450830be6b4aaf8e0cfc51d3e1d0269298654979ad332fcf151e1477b30952ec9d457a6803e49128cb3edde9c24e334efabf536ded9a6b18a33fe5786e2d84f3826931134261dc53efe7c292a86948906d4418e57b9b52a25ee7ae12bc3d9cfc58df3a0de24ce09734e2166c9061ad8d0c69c73669692d0c49c9bfc522613693291a739a7d02cd9d084fc15497e4950fbcb2429715fde0a557e3f499298485559a268a9b96c11f44651f5237d523fa8a24af88ffff3f38d250dff3d4a6a14fd71f5401f197e7f4ef51c3bcc249fd2634fb2b356b7a625b9d9f699de59ce3ccc6e2fe37ca9c792f456e4f83fe193e4a79290e583a05625219390ffa35527957ed4a97c923c952bf1b9b8cb2785befea3ea04821f97327ca03fa1ca2fe8c465d4a91f45fee528aa542b9e52dc2955ab71fc32d4e10ff250a3c22c640e08ea274cc692a448f657ea92b4614990f8e4b9b85556b86c5df2a852ab01fc4fa8b1f07f28aa7f28a2d80382fa49287ee40782e293f24b7d54caadc732149f50e1e29350a77cb2772ba496c2c355946ea55c59e161962757864a55aa9bd3d2e17728ee08e92afcf9ab5462c983853ffff6b7e2293fa1aefc84ba4fa82b3fa1ce64fa51dca714d0cf690de07fef15cf9c968e35a51c1fe8b1cc69490175a9a39c70538124e61146cc3981ccd9c32c01a00772bc1ea0451139c82f1525978af4b0bff253a8f21b751250033d975d18ce8fe2c649017d14fe5da812928e0ff4212d3f4aae502545d2434e1593096b360b497ea612e7b43a1e3e97ad3d932905f4fb23b593dfa106b517c4862235ca643a5d3cc56a29bf51ab4e4327ce4572e8b99cfe478f6249a6bed429c98f0a49fede39e408f4e3aad4e1cfc7c37586c60712f763c9e9f952fff844971a4aa685d3b47a45a71bdafae7a9601967afe874cfc57dd2a5868265d3f0159d8e09d6ec9425fbb5fc8820f9e59093f1b97e94c924f4a554295d929ffa4afee4ea44ea9fa1125cedaff78f97aaeff78fe4d0a8bffdf50fdf43911a7522c74fa544910c29007189864d8e57287ee5d664a8c7b25e184e6af5e3a3cab7664e0e8e630a2156c086922da65420077250008d268409a2dba2c373aa62c50a152754c9b6fa21258aa0872a7fa87fe36b792eee8722f64461c2645b2dd9af65c97e2d43e5c73f506b11eae1b21ff544b5e2228a54c807faca2ff58daaf0d32991db8ceb94e14adc3b274863118734959907189f39939a99a449c2c19a335b583c668835338558312b58412c1a4bca737400d20c33221a9a18d2c8b2260ba26b8aa6b50329076bce2889994264ac6959564ccc15fd104dcbb246a229963563892c6b244384c8125933a215b058968c35334516906b2492913152432d924844aac2225996a8c63282c8f231632c9268f4963584c8b24434594430882c910c4964f940645932226b078b05cb1a89684010339a0962ad60599625e2442ad08c2c2d2c912523b22cd1e8648948353eaec8c6624263c5dc8c70b0664422521dd58844d61121d82a82547f44195d114dd21449c0228d8c906244d668c66061d5614d91352d9225b28260d1886eb02c518c4834b2accc4a62d1583622914824f3c4b2412422892c6c74fd7081a6060bc8092f881260c5885cb048d6c89aa22b225a6391a6e89399d4c722c068120181359bb8211a59321669c602628db21089684c236b1b592211898a6c7c18b1622c6b0623551a304b54234323b22ccb9ab12c932512d1602463f9109146405611d1cab24638968f1f228b66c6123511cd209a4124c3688ea625c49211892c20a4d2882472412412593216a95b3e6eac1f31222bc60a922dcbb22c18443a333f7c882c8fc6664664ed60d158d6486491ac29960c224e1483e887684614638d2c9125b24c960ca21fa21992358a195956b6469611cb8765635996126b0651cd68c6a2215922cb325996cc0aa2142c92c88a21599ce8873512cd608d4622114944b23891c87a415463f9b0684822cbb24c960ca29a999145a221599695a9d5c20d344b460288b146960f8bd482e5c387e9c70f30cc60018064894432a299b74a2a603fa65896c8125996853367a66a6e39c2cac387204cea03173b88c3072276fc80075d0705b2dc808ed943640693870b153c8f4ec1c4c2851a5a6021225ad9818b21f2b8a26f132a5ccc4084293a068ce3a285249c0e2246be01909b4ca4c6c237b0f6c03e611c806913e6e5b38419707cc01021a1c30b1109c56e10c01648f0a0c187dad0405938616e814210d327c68a49494acc399a40cc7965ce6964965e50cd397f7f204f4a1ca30c8d3d735a500030e7cc52c40a08242f80a1d29bfcfe7c7b9adb32d66e662b468e972e353fc92c511380138099f131e383148406cff818c960d383c44e111a233235341bc9468845b29139918246404643483150620160648288667c9090009161a300981a2d369c84240812a20b434c169225b3e4036070a00265881222520d89ca912380c9411237c4818415631a4243132444a41746382a8b08931801b8008c8c0c0d5796504188132646529070028c0b3e78b049c1260522a2a8a0a2216bf400b3a4f421c5e78ad28c8f1190182e2428a6408286144446064b4886840ebaf071c30b96a041420282887ec4341932c39174f81fca480285182335516a6a90018274c30c970407b89092441854ac50c29600b2a9441102303f569d014a00b1422c2d318c94ccb88091a899e1646a68828cb28e94910c3551f4005333a3038487660a0c5d941a1f536c78f8120e8061818404d7c89850002253f3a32b228417606a68a6cce049012666548ab1647690a9895122730313273f563e6ca099225333e30210283e6e483b3e584821861a5e58e1061a01e880a506246a68ae990c489675aeccd890665e88318db00f1b920db4c98c8f991a5292181d485b132b068611919815301f347bc4754a5aa0a959c14746e2c9ce8f4b63847443ba910903cc0d41485062041033838f1b520c42ea488624c05c49ac511fe1904631451411c2006b8861052810471b6554208c0844718411422497fedb470820b6f4a0250bcf152a039862da32233504000094e48608c2e0f1031de4c02400455e7061668b3750f085173b7439986450c1e6874c08d440830c30be880004b8d8428b2c466c48723160013d3c619850046f0b1e4160e3240eb9828aaf3351523303861555641f3288c104c030719885147ed4d0ccc400c3063400c4732b3b03d089d239a000503871021d5a072a4081308ee0414bc62da44052411c44d0c20407ec6346c6024da071812e106000298a7880031c4085951d264a6cb0b1963052820809a43c6810443b20e9407483183aac198860207a810f17d8b440a402510a446a882c30aa80880b6908ebc6a2814686981880b8206241a48295c21014624e100db14aa420a21f3135221f3434a299991811c91a5996cc04226404c3680d30240280215191b9815a334640a2e4059898189b991a668004898b4a62c1260262c844018644c5c70a3531b4a004181f3e90b68c66f851cad8d044a1d9646a464a5aa8893901189a33c0a40004123ef2488b21d8d8004c4c183031362fbc008c4d59640d303e5a08229a51129324e6004fa8f0c3850424419a028c102242888c708624a16961489824620440b3cd2c1909192da189009851959a44a646660c30a31f322f9090fca8238b6443425213254600333ec8bc20532333844d0a3629f868c1c70a333e8cf64842e685511949c490004c008620a5e8290032904c3642648690ac11cee809e98a0d0b32a2191e666098d98951218825f3631443b2198d46a2d1cc8866e4a32606d26826cbcc0942aed40c999199b14633a44b4a42b2685c18c180840f1a62c40013640c2486c89060a0819204c906491439d119a6093a90410c5410470948b0fae1b1a28ace490e386431c42308496c2809a199f9618b959d3070b46005345081659180260bb0010c523002363650812f925c3520605552418e4610421e72b8a0052230e3882f4200b1a5072b3b52a2d030030b2ba891c61115a0c017234e32c420863404b1410dbaa4c08469c211f400e207165618028311b8e1013636a0010b505100284e42f8c083951d9d14c0e1c61b1dc8620a0d6690821188808d35bc8880144c2821843c60e00236d650e3024b8079aed30d0192c71d76d8a0042248038d0c4cc00a023c3f0901c40f3ce8744a4c47860049011c25d08201562cf15c8801e844e99498820021cd3bec48011c2670230d34326081095c5180258218800e0e4a4cf9d623270c21cd3077d851031394c00d11a4818605267085150520c012759c82002287241713964045072141e688a18a29a4e88107ac0b0248312444868f30a32688f68859824809346290c2104d40f4856545758459d70f9c91004674051a44315830ccbc3072c16a81c482b5820f144e3861542209b1095202f2828d0b3f62a819e263864666462423131333b2e69c2fcc9a520a63cc073d5d86dfa84af25cdc5fb892614e6b26053053669652c0524a6100a5146e8e5023943effc8f0fba892a1518f1ab5a9466108253cce28a160c79c3ef427fc1e15448f18c161090dbf9ff750c8c09cf3c72ca13081397d681729f9d172c80be2baae1ff894d9d89c315a668c93120a5026395ee1f865a95549c6921c12448c39a700660905eb841f845f493ea7a85dead48b9c1e31f27b5c89e40970944e3863f2f04b4dc9d22c9d90050fbfc82c9dd04fe8e922fdfd81241dc54eff27d4a30f2133cce98346089f733e09eafeabb19c738e68ac27735a4ee6b472eee02a6542c771b56fe0b88dcb1ce634ee721967b9ca611cb76d5bdef0a66d77cb36bbd50ddbb8bce59c71d6f2cd59b6b9662c7378c31963ace18b336c71c518e6b44dcb1ad634ed6a9966b5aa611a77b79b2fbedabd37bbf6d68b5d2edbb29ce14ccb6e966536ab19967176b3d962abd96b336b6db598e5ea5673c555abb766d5d65ab1ca611b96318c69d8c532cc6215c3b02f956c905a8545d420315263c4086a042d82522435486a8a98d36a32a795c39c16932373f09452a592b6522a616af2f1a1a61a243e3ed454f60729adf13952a27ebe91d2b23f68c4879ac627498d030ea552a924248f3929f9952b8f52f2a3e1832692872bd15b89744e0b873947b324e40d14502436d8404b4df973d95fa855252112282d218e394de5aaca288e6317248ea3e864ce299a252147cc39af8b1c2f2ea69294a9fea3b82729c4f23eb01c454f939c0481a314240493e24087ca6f6b95de5409c581860f9e823e144131e736a7c88c39270fb31404ca0c12c13e3e90488e57b94a9db0eb5e152749af18a655ed79d6f25c3bc611bf8bfc528ffb127a1e7e4363497e3f3f5a4be6b494cc6999e69c3a7392864c3b276984070ae6b4386b9bd3ca735a784e4b9bd3ba735ad99cd38539e7132773ce9d59020266825fb98201480c931caf215054d130e70cc2c6023f4470b102f80017bb06300c41072cf47025024b4c0084211d20764a8003044c4d9031c6104aecf0c1162d8461438d0052d07290d10613aeb0012f2388a9c41e05f802660677ccb06002ab3cf008401769e061060f42203a271de48009308c9abdc5072f4aa04108dc802d54c81a24f8e85019c0902b6ef041fa0081081fd00010820c410526a4c0f0820650c0440e067e9458e04b0b7534212413c61622d0428d377c40208109b4b1720000f4908941c28a2b9e5c510306e2cf06760b1b73c9e2000ad0e2852514e001176018c00c2637dc0106034658420d4e6400012f1861085474213a404d49053d84008112c0d8610020665e4840175a7e900a82a3071e15161ebad3942c78e019410f68f8a008f347086ca608c8c79c5314668f1f6a3061c2159a2e860812c3143990317d686387317a3872a5c90e0798c387130a3ccc04008e298aec17865ad8a300688c610017d8e8a0489713aca01c07fc58c20a087084282042832234c9830243bc418438742045052b588c2005255c7840880526fc2800288c1180c0801355ecc163b3c29c53b512c71f5a7f68f8d1520c29f9d132fc44157d5449fea84a893b5c9daaea5492a037e70cc09c138839a728967414fb57822b2c734e1ee69c37cc397f98a5983874e0e9a2e343155f0e64b0a04219170f289891872a8d5947142ee0b07570021d993025c801496aa71bf25f6640810343851948c1510104530b348881811a39be27397ad094600e2d364af420080a1b3004810011b09961086974592cc1822292f05210c30d2951ae685a1480080c58e6882244121f4eb428a00e2033ba54b1c588ef810738d0638c227260a0812794a8b142a1000047840126129220c50f76d0832256ea0a82e0809521960560e085913ae2f8a289078c5c00424d4d10042c90850d90211ac5c61280e00119442418b284a80923e4e07961c8162b80c10e49580fc881ddc33ac1917ae498410ecd0504da40e3843470f0828a04e0b0782cb1334402331c89418f173c01801c3811fe78c38a2000d9808d291802cc910dc0408d2b5250c507411d086a00a94584250c992c17d8814805642060c60c4bdca8612ed0c39691065a5610811174fcc00114a859630821b6a811861d020ba8282de10c15a44107153ff0d2c4c68020b8a1032fc29451806c4b21811948a85aa880951100a129cbf864d8898281d28944831ea0bcc10d9d80c3640bd3e80622d0e1040750691220229c394116351840928f0e9c1a84f0218326c0f1250807050174c012a40722c6017c596ce00901260e32f0a8828c02acb003282e8ce08a0b3b53783fc00001b4c0c1b448001bb2627d922e44dc00043a9491460220c0060647933d44272f1851003dca251471e26538519ca008524c171e4148b217bc7184005e104717188ca0f96e6288b00121252259b21627b46013c6134458809010286086d08f174f011a4c20871530184205136f20e00c32ac15da973b7a3003c8941b934384cd1a1c095c6004193040841a14b08438a4dce084a134422d5e946bc6e4a2cbd14419310091728417148852448f09a870a38daa2419c20d5b6470832941ec6043b6c00c7040f2460dba48c005051052e0d2831a4f7464c610e7986c8c600a287eb450a919b2c511484560029328524007126e4e352ab845642ad840401d3233182201166c99d488061880d021c1f5210413e81a1a21f42c3d400d59a3011ece00949022081fde18bac3066106086ac04610175454a1038990a02188d083274720a00626d008b1c4c80bba043e10831e1f3b742c596af0a2876bc20f6e8080413de0050958210a93cf6c42977346988b8e273b5618d0248b3a7820848b0b4682c818364520a386e6c150c00e6a104647eb4012248ef8744065312405147a70c2c906dc90a2ca1173f8c491451c2618c309237459b203f6010f742b006b7415d8dd0f6284a89202177574e131d8a30338083842873a92b04316249ac461f398401078aed051854985a127d0c8801a2d0852c4083d53d8089f5802956d0951601b1f05909f0d76a805e0b0a2490d4424618e186a9070e100011216d6c0c00943f82102f1f440c720c8891a705c1eba1e2325741d4c211380375430f0520706a420f2012750d8c01c8dec9125a0cc810802ec8002388046a4387e309a22a01109842f788e6861c4948c8b018d0f2e6210c3d3810888c234e1872684091326cc7c223e9206892315fac652a7e850f9852bda455a8ae248c3ef3d2a9694fce8837af390e3453e49be6aa84c61ced931a9819662964c72bcc81c7cd46c2299f38439e7cd9cd3ca2c91a698e478d59f53d9fb9c1385394551e890e7b45cd0cd6975008b299c1832a7d54412481861c39c9617a1d369ca939e1c2752b6e8f0048b85e554b59c7c88a283a5d3e2c40a15273c512c2416b55c98968f39f7f031e73c020b73ce1ee0a0053573ce378ecc39d998938d6cce99863e059973665961cec963d92ed2f1bdd42aa4e5fe711477f851b10c3fca9f4bb8423d99930b9239e7103acc9c398039e70eb36465316769ce69559b392d6cce498ed7bddb3da9be2f49d04bb2edbd69584d9269d9de306e73d5bee6ade3fc10c105a724576312b25c895cf6a37692f2fb4922fe8c7a5f494a511c93a04afe0551219da20f7a1afc3490a68f2a69a851251dff2714414a7efc3f50a55af1f02ff7ab849ea2ca9ff0412a0695385dc4193f48545154f905d192fc409a33a795e49a738ae31341873cfafc03fa38154b5aaa525f967ad23945de9cb385599a7690e355a63ace9cd691398ae3f834d4947f38aeca1fcbf0530faa521f2d3f3d96f427fcca52a746b1533d2d05cc395f98a50965ce0964962639e7546196a610fcc14f774a7e39e451da451a8a5fa9e9d028a63e458ed78c99536433e78c6196660be478ed073a05e931c91ec9245b04419d6468d4a3f781735a48e6b40430a775c324cd691d2171a08a1fb30d306072e688c4011afcf85183009a51f6e2e58b888ee8178b92a817327a66a80cf5b2c413d4494c8f0f1a43bfd0d09a225e9aa04e628a78f922436b8a3c419d8ca88f225f688ac4d099225f648ac4145142c8884efa45c60a7fc0b083100858d42ad28510369688a14b34719d8ca81721304fc828518486480f094c1793fe1059407ab822436388c8c88c886491a1a3225e8e7032a231447ec400b932630489c64c203cc8d011a9092364a8e584343343656648b489484666091a2566c28409d38411236a39116539c2490c1d11f17284139ee924a64813364e48d402d2430c9529d284e524a64813961352910e587402f1ac1d848471322aa28490304e9eb84e44453af045464462c00f2e3194443b91c82a52a48948871f5344a4cb2806a4592209244454441a59961924128944ad1f243a437ffcf03284450770840c25790112d198724463e888669433c3258616e9e22547446564286d321a4244ad19225c688a7419e590ba78219146a3116944229148a311b580e82064528bc64ce0c7b42c6b882ea39c19fae347cc04125112912e2de47011cd1cab48172f53ac1c9a2ea31c1f458620d114e9e22567a60897111d59744464928a7419e5709974e64c11ed80d584d504895a54446489279aa0990aa8c9826694830029012122b29c0031e28b88d214012312cd00110139824813393819d11f449678c27232a24de4e0844427101876205120b46764438310994e7e10010284d6fca04f584e6a882c61437fec309df8a0361408b5881851432d1f458c20a3a7865ad4881f544404080c5166a80c9799225f0c89a84c912f864634079a22604694c606c812412891256a6813d4c90f6ad51401335ac2882f23faa30898d1124f5027166d823a0132a2408818f1654483140133a2407618f58ca8a886c81396931aea83c81396131ff40791259ac8c1490d7dc272f283fe10d9d011900e861d481408dd32a2369486c8123e7838c20990224690d1f3835ad4881a6ac48f1f3432d472122647a608972f8644f48b21122d5d11d1182030ec40a222da03e4ca88520efca01965119127c8e89243cee809224b3c412a4246971c9a20a34b0e39160f3f4a552cf95183454d0246a02e34e4c4d0b20b0d36445a88017321ad1c1f1328a5c025851c91454714cc8f137eb0f0e3c7a4f5c7289a38938e26cea4a48933a9ccc4997466e24c4a337126f5317126ad993893fe983893da4c9c49814c9c49834c9c49854c9c494b1367d2211367d21326cea4284c9c4953983893aa3071265d61e24ccac2c499b4858933a90b1367d21726cea4304c9c4963983893ca3071269d61e24c4ac3c499d42232a91c7396a24c1f659468728e28c3b28088c63073482212b546242aa2c1469486e5858f26f8d863882f84d02146944b178bda081142643a1911f942c86834a21195889061536408205d7ed0192a1af9105132481b3a638210f94208251121495dac1c9b225c80d099038408100d3924fa8308971a51492443859488903153648819203642be1052c40b1935940cd2079d3154448aba583933e7051a9917648a8ce6f88189708d11234c8a50198a44868a98a44065e88d8809112a83022d8d989486509911932042e80442656a88f820f2854d112f64f840425384da502322cda23344be4881480a270c29090902e40789c6a6948248b3449a25d22c1b7af3c5179b22448a14f142860f2245bc903183020a279c40bd78f1e2e5092f5ebc7851c28b971fd48b0da5f48b0da5817eb1a133d02f365406fac586c640bfd85018e8171bfa02fd62435da05f6c680bf48b0d65817eb1a12bd02f363154055a4389d0406406223210b11169231a039192481b511888a420d246f405222d88b4117581480c226d445b2042459a36a22b103122d2465405224844da8862225c53e40b198ac406891111a629f2450a45bc7c31f2450a28d02f374c5028e2e50b8d41c4e48421f44b0c2d88980c29d12f2d302915f1f22585d2971293204c80fca05f6844da0f2af3c5a6884c112eb30d924803c097168e9011d1e4e0470c2352736a9fceb401850838c1834b8e571b149813d8e9d9a17392c3a489d5411e3bb842c9f11a2a4331e501910e3a009df8ae94832de6bcf4a83dedd127de8a4cc23ac207ab07241c810869cc8906191f960128b9a38a39279171d47bc6f0cdd21da5e9033d2c222d1ce1076044c1b1831c2fa08fa3381c7899e4f871ae9394e1b7ea38f89124bbee85e194e1f7f37938a95508f495fae743223324d80f94e48891f0c1ab834f521c9650fea5e6b47a30a7c58339ad1dcc521df3073ade7081062564200603625053ec1004cb1112b06204d3929008631a3f146062081f39f899734e1fdc6008c3e1a2f77e2e447a76b258797282b293c50a965394930e394f9e743a9c78b812479ac3f3c464dacfc52df6508788ef498dbac2e434be4a48a74e423ac56489904e8d7f856462b3d512219da232e75c614e2b033640f229f1398de2c9a75372b4403dfe95f279c49d392d1df0ff314af85cc4b29fc821ad22490d6eb1873a554852834fc8217d65ce19c31c0d98c3cb1ce024c78b87ab3970f0a1261f5a6afaa5169f90e395440e2ad775d9503e48820fc483097ca0074de4fb20eefcb8a10e704eab53428308cc498e1f9ec62fbf534a1c7b92fd40a53a8ccc3953a2083a39913f22c8e447a4b264bf9613130cd7295b359e54dd64d224dfafea989d7364cd69896a68ac3945d69c226b4e9135a7c89a53341259738aac3947d69c31d69c3431a3186b443241024452ffe0a480fe8811717c227020628226733e111f6982142e2e811cd454024e02264c1284800440cc11e43147f084384b2328b961c7a42637ce0041bddd78625253a97d9825376ee69c22c8839a4a2d822944d0c39cd414822284600c6a0a01484d2130424d20f8013581608c39a90904e59cd4048225939ab8ccd20748304b1fe01e288207ca98939a3cc027359d4a1e2851531b714c6a6a638a369a4c368a30273595d858828d2b939a46365aa0263aa8690d30e6a4a635842635ad01654e6a5ac3869a3a10c79cd4d4006a3a75c0a70348a8498d225013a9c613734e357aa8298d1da4510635a541258d14d0a0634e6a127541039cf31a2a55a927c72f3fa543f12329d74e44611c50420386399aac40b1d2434dfcc550e42b9e2a5a982059328aa07e6232d5984c27f2143ee71feaf4a9f44945922653193e50f7a9729e7caa9c2757b05cf42b714691247f7f78ba8e905a4a1210d4fb842adf0825418d138ae10feddf9f98fcaa8b565959b25f8b10086af24fe4aa54953af59142cf2ffed1a1f2a3fac4c3af9b4ca3882a57393cfca250ad4fa4fe39855fca6412faa2ec8fd41e795de497f256e0aa3fb93a5d1ed7fc3bfd90a9d3f58492d7a529f99142a2a74fa78b96e4937f3a512cdfe953e55c2408ea272971ac02a507faa972742e92e69c4ea74f7de5a7caa1a94f95f3a3f884d44ee8e5e3737a90872b6fa8fcaee7e24e7d9a5e94bc52a3d8bfd35fe3ef4f95f3df4f62193e580aad3e55ceef50dcb98e682edac8d0f8ab2e542ca9ce951cfaa89ecbc7a78bf4fa549a870a8006e9f174fab9f6077a2b55f8a5dea1f813fa6cbd5cf950fe81effd577e424ff50744f99343cfe59f14e9d073a1e49354f37fd2caf5a9341d9fcb28069d442ea42e69ef3cf4fad5afba7c1fbfec3ea78b1455e4904e69140f4515e9e35392e1a77f34253ffc7145721a8efa4151545111557e4a0b152ac3551f9f83dfcac989a4e4157e43a30692427ee117858e22e52b7093ff2971972bf1caa155481fd2c7e73df2a394875f103ea4cf0ff4c92cf4f2f950dcf1a148c88ffaf8741d7aa57e149f5cfc3fe4a143e303fda7d2d4e747f1890efdabbbaa68e9aa68e97aba3b2c3be6b470e000ee801d4461c40104d08ef9430ee69c242874b0c00f7a0cb1d6d0d99800832d72e430e7b4c01c09a2630e1aec5862ce693d91c00f1e9425c8c10ae69c560b76503c8cf0820c5ccc3949607431812b28a441823ce7b472b8e2072b5540a1851a734e4b0a1fd070648c5922c69c5344a5cbe10e296c90e20873ce910a54c411840464a1c60ae69c320bc00209560b4c4d6832e714d961042bbc30210138c8734e12037c6614803ac11036c049013d8eb722819e1c7a1d42f123c9e7b1eaa8a24516734e2d88d002ca9c482812eb06590eac19e64c4203a68879c38a33e6b4e8a032e7ec73f6f9c5fc62ce1bb4c183395730e7ec99250664b15d180e8ad4a8ffc6d206735a3598438e392d1acc69cd604e4b06735a3198d382c19cd60bac16cc69b1604e6b05735a2a98d38a634e2b05735a70cc69bd31a7858239ad13cc6999604eab04735a2498d31ac19c961b735a2298d30ac19c1608e6b43e30a7e58139ad36e6b4d898d35ac352634e2b8d392d34e6b43830a775c69cd606e6b4346065604e0b03735a1798d3b2805581392d0acc699131a7358615c69cd604e6b4c098d3fa624ecb8b392d09cc6945604e0b021617735a5bcc693d604ecb01735a5acc6935604eeb08062c20011616735a0798d3328065c59c5615735a54cc691580009614735a51584fcc6939613131a7b584958405e68839ad2f969739ad22e6b48898d31a9ad3129ad30a9ad3029ad35acd6995735a24c964fc544a9cd31ae79c34d3baa61863cc4906024630a74ae8b9984af2e037aab89852097df8a0d087ab39ad2e2a314cd14c8b0b163194900216404c1e3a8a140b169716dac52407006352d34ff88d73ee213e14a97f4efcc9550ae84faa2ef650674eeba7cf69fd9c16a7a2082a4b35e7f499250394418ed7d058869f44a55349fec7d24bb23ded93e4c4801a6aa018c5810815634a3063ce081fa4382ca9a1068a0313cac39f3155664c0e33c605920b482d20b180e4c61532e47895a34892e3357ef9254992610ee376c7dad79bfb86b7fa5cb51b876558cdb8ffee5ce5b4df49f69c96109d75c59c13cb2c0d218a4a7ea358eaf1cb4f749a73f259aae20356d4408e579251ac2920b18a72ceb97a620531671541a83863ce79f988a8209f4fab90fc775aa2f687c4c727877ffaca7f948b144baafa3e5095d21fe4a34aad3caa458e44e4a157287e65f824f5517de593ff8dffa17e871f494b2dee502547044095d01ba800a8118a03557de5a97c50c911d5571ad9a0de271c282d1f4c9284fe28863f1f92925c8d3e3e3ef4faa1431e457244f595540c8d509c2170d4e097fa48aa69b81a71ca506f9f1d1faa69a9f5a7c850fc7e7ea4a1a8fa4aaa354ad3f0d3a52752b1a43ee1d77dc8cfc7878e9f2816517de5f80115a13ea0b6e2f381aaf2035729fadf690e157ba8f3df4fe183fffd3404d7aaaf64a2f37d05eef023c14f970fe53f8a08085c139f1434338a14f05f9dae15a7fc29598ae24881b066a7a0488deaa8e43ce1896232cd397598d382c2671c3b1f9f2346547a0c0a5726930fe5503c317ed9350de2f44300a05832e7d454062868ca78020517ff3c319e98a28b27a84041c0867a8224ff4793a44aa7f8f3f182a243ab68e94e5cf40771d1cf03cf7e2093897c1014f789ff7e2dfc79b8129d905c975fa514fa1d5d6a28cfc527bda70929c6f19bb83253e2d89bc026d7e13a74901f136030e173f11f0299a04bb0604e1d1e2b4b345982867f4b66498936c29528f4137ea4129ad4a8521279ccebfa50b4214ca28d3993a00267a8fc524fc95349f28b8a1737cc394726351409450282fa0945b2240bff53079f3ca93a8ad453ae08711da1dfe9b090ff57485253099f0a0982394f6ad415fe417950f58d3d1feae8906395ff28a5d0efd82c8bd8f3f14f05893b3ae1a7514f482d65fc2bff519ed44e4631caf865f829b18ac9d4132486478001c7114de624575d9e64b264c843c197230c8157aa5c240d45f25b89bcfc28123dae72e82846a1d7cff514f43e327c926afa5c46518f1ffe0fb922c3274371d3f04911b5e9b8127da01749ae4a3d6a954ad315174715bde186b27f9c92dfa883de09bd482e7ee3ab7220bfd4575a2894bcfc60fe90295a921a2ce79c4966c9cb18931caf3d4b5e9ad0f0a394d424ed224f110698f381444f537205aeb89822877410a8c951ec61114de6a7557cd4413f8a65112dcc0b4a1144b8001447541025628b279f08304444d91f86e2e65f942124cc8b879afc86ce18027371ae29f9e9211da13ce6bcac901f153a63ce398584aef2494a0a6d735e3c0809af0a52c19cf3e25f7e42dd879f38805027089b65f84041334067cc3951a5d625b50108450e691088ce798d1f06890f827a935f6a45c77c15ff3449575bcc7941d1a14f56a8b9a273ce4b0ccb185c5074e88f65b985aa54a2ae92ce8b24455e227730e79ce4478231b5189253f48f9aa41187c0f9713c636a3a8ae1283e597ea96ec4624ed207c767c90f9962d2b384ebf08f892a8f36aa9873ce2ea82edbbc82e862a3a26352d3a8533940b5c437e768e742a3a442327e18f6920c3f554944023595411fd29ff0136720ba414dd42496f4baba487fd455e8f5e9204d7fd474482ce9a924397d5499855e2971871ff9a8f2f4a3ca870a89ded0a8475195fa92e6d0df5a45923694631025875e077a9162100d7fbeffa8b8334e11774070154548f4ca9515283fe147925f959c52dc193f0cb2528a3be1cf479239620f8945dc41ed525729c59d1fdd53a27ebee7c10273ce1b66a906312650497ea9c15329f461195cca19d2f774ea519b3c9926108c00c43604aa547a4e21583f8cc6072ac16fe58961a8b7128af3a36a086a3352ef9f2f439d8f8e392f2465f8e4477f4410e7c72bdf07e645fe88547ebcf28116fd003095fca8bac82757a40de0b77a4269a84d5c7b280c2533e750f9edaf2435f8a7f2c927ffc7ce43ae7ea8f8692282b45c891ffd093f24344804dfa3e5ca234554d04f0b53144732a7e73157a59ec59cdef326b3d4af5c4746f24bfd58ea2db4e0a5f86dce79bd6aa82cf5fe78f8ad7e464d411d7e512e1e8afbc96f813f122e1e83ab04635e1e179a578a53fee3a6487c7c3e4aeaa015497e7b07735e9f12c9d2ce62fc5283f433420a5d7bbb8e70b1ef162e29b3e491605e47ae9feb8d04e991eba039a769963c25e69cd711b1e40f24a68c509e1279f80769540f1866e1ff3cfcf68a247578161ebe8a5c39e15f865f15fe2852833cfc4bfd8da5563d169ea57c9e9214a994e40a0aff209187dd9cf39a255dc69c974f49ab403dea26735e3eba84faf950259f38489202d19c92cf16383faa9cf8a87c7c28ffdf42bfe33365ce8b874f3af1f915a762494f6f7c5c82928cdf99709dffb19f823ee4270e8a26534f493e3fa14e4de61584cfa924c40eae207c6c982521ce9857103e25219e9842f84c21b020f6d02141bd0a3f215de5fad457d2a150d352530e8a282c42ba4a48454857b9525f49fe28765a8a3bf422f2a1484b523ff88d2b114877aa69079f14a150d3871f485362598a4ee8457e745c891f9046bdb7a2e5ff0ce914497f250ee9d08b4784424771089da29aaa56347c9568e2427e230d83443aaec4215a6a2a9254e4e3037d903885faf0ff71b59f0c3f1ffa9d3eaa0c9f867a2379efa3fc3fa4370c81a0fef106ba128768d7a144ac60e9b6d09d9c293d144bd793d36191423b27b487274b157a85af12291f69f88994f24fe91d7ae91ffb4ff821f178429152900e8539f4223f3d0486e4e7e34335259f5c51243e624987c69f500435f5f1a12412b277f1b91e4b4a7ecac9e5e3338a25b9127da03e3e3ed4084a99e85243a148ae50244c9674f07996a43e148f4a57c181524a691194d2073f554adc62e8e3e3d35100d04bd32e8e6209aa525ae8a9130df4955b3f1769172f4a965fb8d2f2c59c538759d202c49cf3b2c1066ae2df0909d97fa423aafcbeb1241fcbaacb17ea4001f557863f547ee0e7691ebe4aa87b70c51fb5797eb4fc845f497e429d7e282407c529e413f13f46190a751551dc72c31453971a0a961cae438e3a5cb648857f65b812539acb267f34d8ffc71e3e11e2d873b29c4e3b567478b0745a4e9d941c2c567a784e279311001029f50031c9f11a7a2e27506f715e616d9905e069a35e15070cc5f1030a7df0e810e8e97295faefa2177e4c28121e764c6a2892254cf88f0ff481cf4f25a94126472812ae23f6f04b896314923f138a84c991ffd1488c30a1489694a288e549117c12beca0a286eb114c72be073b1ca7f14f0b9983afd77f227fcc49f72259e84748a4ce9515f79a223f65087cb1641274c96605ab816c1217d85bf28aafefbe9cb952a25ee8f128a569030678e9518a8f48f94d441618e15301e54a5c4fdc4cac7c70a6ae658c999738a34b4c21f0b7f10fc74f81dfecfc52724b9d382abb40326a54b3b502efeef51dd69f8fd7ca3481fd5b3434b55e20875f9240f1241b0ca2c55119a3fe36a54fd0e7ffcfe2315c727428f8fea9973e6304b55b0796d8a138a2125358a7f890a0b4a54b298735e3e3ee27e4e4791fa80a0de747c54f97557d087f45165b9b558522ae2d0ebc0e457a0d692faf223879e8bb722990cbd0e43cfe5b9b8a994e67371eba0431b57103e251db2d001d5448716e600f29857103e57368d87e7fabaa625179da2624969f8ad444fd32031e42292fab1d06bbf8aa47ca81c5f258e2a5a24caa69164911fe9a6f1f0507ed9107ee54ba11e94ebb98840e14743bd29f92a51979a771145ea29d791921cbf4ef987ab51454bf239281aa1aa7f2e295a855e24496a8f9a48b2064a2f9f1f51652986b47ff40837429f0475147af9d86ce543c98ffaf88824e5abb1875efcc357a9348ad292d4207d54d945eaf3291dfaf8d01fc592875e252982f43d4adfa320f805d1af7fa5185251e8c3321477ffc24795d4e7c915fd20da3ffae44aeff7a8cf112426538f111ffaaaa192fcf14bd42ebf7731457ea146ed4fd19ff0e3b2f558fe379694dc3f7a7ca0073f70e394a89f0fa46410f9a17ae82586bfbf92fcc22f357ef91c047396bc58ee07a2fa088ad4534ca61e3ae451fe65f8e48faa1f8d504dc3ffa0f23dfa137e2a95ae42af92fc40eac3a46789cf872abfa0d4a34a4a82e05792f443f15322499fd49b865f1771ca9548c51f5a8aa190e8845e38e147ff67d420d5f481344ad32e522de29552833dfce8935fd0f8a852dcb4d4a1171de97b3f8a9d727025a248ca434dc315253f9afaf233753d5676f8734ad28b8a24a8291228f452a1483d855e3e3e74c8a3e5f3d08b3f49fe164715fd09bff78e941f154bd20652a5534628492ff251a446912a5d05c98f58d272a502351dc51e7e17eda117149d5183abfd95a356511d7e20b8ea2afd28d3a7f4ce7e150fa97fdca18ed843f2ff1da1eecb8f145529f14909ae747f28a1b8c37ffc12fca280a07e228a21c68d9c22393661f668d283267334794193379a9cd144034dcc5089f448008c50134d428f04800e8d62a979a853144900a84925522401a0a04e8d62688452131292d2207e782e6ed39c325f490041d0f181520e0768829ad3c89c939ba52637734e3b662907084cae9fd321ae7f047372e89973c57fa4e1475761166adadf8f486548258e65f8273d96e1677a223ef03b999ed42815939e25fbb5f051dc8fa50c1fa823c9f1532b32147719aec427fdb190a32e3514b187e4491c9f88532886fb55e449a84cfd984c3dbf43313c994c64287e64f8a5d04f0ae07033e7bc17562f0c67fcde571e4e09079939a74e152824298e4fe6b47ae06189392d2d735a28cc4953986389979212de50020834a084098cb098736a99a58ba3529a7c7235ae36177798984c3d270e8a50949431e7c5bf243fa1a71f8ab47f24253f3af45c2807452543e55786cf3fca1fb5cb2f880c0288f145be227f00823eaa470912410031fe0004bd7e6b5045b98862494b723544ce8722143247e42b1efe3fa1463d197a1df8c7573c4a9a4c252e8c62ef9880a07e82c56462f2f3f5507c42494d7b962c11129d047d28a282dab882f0316d7105e1436a1318930ea41e7a2e4127fee1ea24f21529f215790d3d172af21549df878a7cc5f3e3b7eaf2584a37e88173e2a670db1123f4b9b84729d831e7d45c9565ce91cdf6c5760535fd40e928f69ff00312538fe581f8879302e2df29fc348a24ffe7e365f8a35685e54a55aeac984c28524f41917aca0e9325fbb590dd1493697fe387ff6332a9482e5b049d0c951fa8cb51acb25fc5f37b7c1e3e8f38fe9650dc213ff2c39782faf99e879f51a39e7425b8221f0b76824d78c3178e61ce494d478c20a1478c50727f2ab1a4487e4490fe84a10e9eb4d4f4c18732e7c463ceb965967e708576028d045cb62e499369fc305c8d29a0d7a82869456829cd47e3a18af624086a02f589fcbe9f40bd2ab7a648a88922a1268a849a7ea0dd8f08de3c90505207952e184320b8ea2bd28759ba4d3425ff3b25f5cf487fd494fc52973cf422f96d615e644a1c3b256937e7c499a56c0e1a3ed0f7b3694ec77f442aa56c8b3991640c67385774b227329fff5eca9accef342bcd39277f15057529961a5c6d503fb179cc79a17e3e948dc19c23ada2a5b36d5c5b50524b2959d59c73d2948a8a25a5a89f95183e2dc51d7b65ce790591a38a925a8aad61ceab8b34b50a9ffaf8d047f5942b55f891e48f9cebf20bbff24b7de089d43f4c7a96742be5ff8cba2c414d3239429160b84e31b264bf9692fcc0936682359b6549287ea5caca50f98de237aa4e423af52b500391fae734beeaf4df4f423a55552dcc52bd7205e1634b159b57103e75c89c57103e20a8b7c974c5e707facf633708ea1d54c2bc98f322358a52f24395b4d4a892ee8f0cbfb1147ad42eb58afc381d5f45cb507fa306a29a92e1a7cb507c12245271f21fa50c3f35a4af04e991a3ca8f8720918a28f6fcfec62ba49612245241fd7c5344b187d452f8875f7f1e6619daa11ecbf01f4b8e952e258e513e253e29c9559539a790392d338ecc39a79227e22353abd427a453624941bdeaf2447ce48f94fca82a024c04418a81128a5062431226e0d1c0bca38dd108e4b880115fae58028023346145598108e6b4b2cc69f5dc392d9e397f14b7757da94b724e0bcb8dd8c3ef743a75511caf9c4ea52b00251c3b70e6983e948eab4d4920eae343c34fa3364e68855e47e80d25eae74bdd4051fb430519a124a8434afea8c1fd9c522acec0638b05d4f1df719ed49e7e7e0a1241509ff8977affa87a7e7aa00fd427d53f1710d4a7071a9ffc315c91faf45c8f3faad5a97cf2f47b14fbf83d8aa9841038cc1212d59cf327fc86c050a45c3f48c59206565baf6341e8bedb9a69adddfa5cc6faf4137e431cab5a6e9edce82096a18e66553a95fd6001a1ebdcdeb0c776d5f0c51d3f2a979ae7baae14d0dffc832e67fc2dcf72f7342d738cf9a0db34ae7add6a35f3328ddfcc6ab9c2ea41b739ef76bb79deb6332fc39d079d8665ad7b18a7e9ea615bc7406b075df6367fcd304ee359e7fa3ae87ecb72d755e3ba73da676f1360e5a0abfd3ef7db729ccdf0c5f58e4edbd8e6d52d631babbf7179db0c60d9d16559ce9ccd38cf2ec698be5701160e3acc655a86f7cd3abff67ed31660d5d1797df332d7b3a73ff39a3577aa08b06ed0652cb357e33ccc3586f5ad5c66c2a2a3dbbf2d76b76a35b7554ef332012c1b741976b1ee1b63cff1c7385683cee3ef7197bfc6bf35af768eae5abbb37eb1ba719bd535ff8854aeeb4704af0b9fea8f086641961c5dde5cdf7eafd771d6996b53ae0b456ad475e5536dc2a2418775fc9cffebdfb0c6abbd5cac19741bd674ed167b5b6fedd6cf2283eeea5af9d5b44cdb72963d8be11a832e676f359bbdbb7de634d758b353ae2b9faa06838e6b37e3ee59add59ef1ceaeebbaf2a9bea0f3b0adefcd5dbe71cc39e6ddf448b92e8f9f50a4465d17f8952bec826edbbb73987b99b7d5efbcb7a0cb5be6715cc7dbde9ee3aece288b055de59b732df3b08c795a76f71db256d0659673dbe6cdb78d1fe3bc6cdbd97212b254d0f5cc59cde95cff6a6ee339f5a5ce756d3b5b4e2b2b8eee6de7acd7f5ee3d63b777ccd6baa5a0b335eb9eceb0cceeab6fc6b56ec1d16918f6b67ab87336bbd9c550b9aac011bbaeeb414fabc0713bd56c5961bdd1712d6b5ae5f66f2feb77c350b96218ae2a0def6c39dd5828e830bed5ac6f7eef7d9ded45e57ac3f3eae6c7152982fbc6cbab9bd36679b8c657a9f418745d9f4a9f7e14f7b6b3e56455619da0ebbf73add8abf7adaebda27285725d504cd0655b96e99afdd57c778f7754aefc4b31cc4ad03d6ddbf6568d3bd93a3e1777d8ed8fd44e6c656291a0dbbd6b57d3b2ad795bcf190bbf9ff7b09ad23f963c2a100b8755e0988da0abef6d7fb597b7bddd628b716af5e367961b9dc66fe59ee52eb7dadabc45d071d9e3b457b3cde67cf56321e87ef7ffad6997e37ddbb27d5d189faaca02417737af7395c33096d5fe9a86caf589f85f7521b313eb035d66b7be317c356cc38f6d16952bbee9917273e5a687ca8d0e981d0abfb2d69d2da71ccb031d97f75f8dfb5a3daef15e8d7b6bac6d3b5b4e38561b9dcd38ae76efb1de32ce5ce62060b1d1e9acaff6fe2fdfb0d6ec5b4c5a6b74d96bcc5d2cbb58beded5b0ebba2eac9e2a66b16a86d5816ed3f67a59db1856318eabdcd685a546b7795ce67fbf5bcfc36e9687b0d2e86ae66d2ccb9cbd7ddbbc0cbbaefd409a05c642a3eb3b6bbb69ec56bcdd9a711ce8bcba316e5bddb1ad354fd733badc39ec7a9eadbf61dc6adbce8d97651254a53eed8bb581ce625ce5de5e6d5b4b031dbebfadf536cf6a5ae3bda14a7de5a24aadba43a5c5aa195da66fd5acde176b58d7da43e52af6f0baaeebc49deac96a8095810ee32ddbf575ae9c96ed73d7055e17c640a7b7cf74e75b86b7c59eb62fd03d67bff7ba2fb7d9cdfebd16e834ade18cabb7f68e79592ba3d3f0be37cbbacdd87dcfd32ad0691bbe9bc578f6fedebe3505baaad9de3d7d35ae634fdb30199dd6b55a378f5fbb7d86b37c5d437a1c75c63b5b4e3ed6189de7d9cc7da6711896610fdb627418d7b9e66d367b19afdbb361741eb759dfeaa6354f6f7ad78b3d6b021da6692eeb4dd3f4ced8cdaf526511c202a3f3aea7654d635bb658e3a00fb3f1517bd4cf33963cb5e6b124bfe8aaeedb735adfb69661fc6acb8baee6ef98766ddfdcc61bf61a25812ed33cebfd9679da725cf326c4afeb7f423d5e17a9126bded972e256043a2e5fcc6615bbdbcbb286352e43a0cbdcc53466b55bf1c6356d3c7156175ddd9a8679c59fabc675ddea58925c74b87adcab7a732ff79aad76c255a32c99478dda97c7daa2b358b75ef5b056df7298b5a2e8dd9d2da729d6033a8e635bd7b84c6b0d57ac7cd2011d87edf5bcadedbae5adb1fb8158c59616dd5b8cefd5b56efb37f3cd36a0db1d735d2ff6b8e2fd9ed53a8b019da76dd5d3b4cd3bcbf8b14cb52a6bcdd602babff8e6cb79f7b8aefd7aa4023a8fffc59acb36bf7a7b97df2cbafc78dbb0661f6fbb73d86609e83cbc614d735cc677cbaade2c023aee56edd97b2d869fdb179f4ed846b1b0e8bacdf772fa318c730d6bac52ad0ed0617a633dcbd7db3d631e7e54ae428f3a8d1f2482a79f95f75cab06e83c9bf1aeafd6f6cdb8ad372ad72f417d45b755cee3dceebcb3e6bab759d1619c66b157dfebdae6bae62a3a8d698c7157c3dbc631cf1595ab5886dfe9e2d5e9c951ab6ebd16151d573ded629eb766b76d31ced602741ac6b90c6bbc61f66adb31f2a3c2992c02747ddb9f653d3fa6e14cdb96b3a6e8342ff3b0ca655ae338c7b5f2374b8a0ee35ebd35b39bf3b08be98cca156351743adbed718b71dafde7dc7d50b5eac12c28baecb1cdb98d6dcd6a0fe3fa13ddcdb4c7350fffdb2d639f2d273a5b7ff3b2ddb9ccb3be2d6735d179f635e76d6b398bb98ab3c54497e58c73cdd9bbdeadfa6ead4cf5cc5aa2dbf7336d6377d32cd7b60cfed7359e5ab72596125dc679f7f3f6b6cb799af66a0ed75736bcb3e5f46325d13def3bcb1bcbd5dbb6ccde93854487339bb1c75ded3d0df7db2d305ddfd8cb7d7bdcb9d77996758ee830d69d7b59d6bdbcb9dd5feca1cefe427de5baf2ce9653ffd27956737b6f9be69c66ff6a9e115daedbfdfb16eb966bfa7fabda4bc7d9bdb9cfbc7e3957f3a6ed6c396129a2db1cce7afe7b1fb35beb1bae9fd04f193f48a49211d16559bbbcdb7bad87b98eb90cef6c390131d46d19c7b9f6b6dc332dd3b65f1708fec6f0ce96930f4237bbba8b2bc79a6fbe71b6adc698965a85d929a8c357732cd3b69739a6d5dec91c4edbd972ea01a8c33edb15d76d33bb35d6ecd55975bdd7ba39edfdadd576adedddd97292527659c6bd8e33cb756bb9d6192a57ae55d94576d9ebc7f27d6bedb63dada272b551c66ee3bb727a7bacf2d772c750b9827afcf932fc4e5cab6c1dbfe4b62eddbe7767cf756c6398d33e43e57af1ea54a67ac6541db769f7725a6b19e7b88c7354aefc3bbd6aa8cc61ce750d85ba07673b5b4e9dd8752ef334ef9cb6b3dc5fb3dbeaa687cacdf8a5ce93ebe2ffa9c41d05cb0d56c7529585a721a9ce6a59867955bb9ece19ae8fcaf577289e40506fee7768258c823752256626b0cb6cd5b6ad5b67ba73996359e5d26598fdecbd9a2f87f16b9bd57255652b57a91397c3105db6affdbcb96673cf3ad7aa615f77b38cc32ade3a6f7ad3366755b3a86e7bfd7277ebbcd9ad73d8db5a7fba2df30d739cdbdde3b47dbdde75ced69de95abf6b5eb7eac377d9b5d9be7f3f67fd77ef8cc3bccbdcd55bdd36bed9ea6d9ad5b86d7739e37bd356c358d6f66e0c746bb94a9db8ec751b7bce59eef56e1fbb1ec66dbaebf8de9ab9aab3cdeb756b54ae5c34f97419bf77f3cd326d7bfe1ac645eed45def661c87f5b5f62ba6b38a09d1d56a39ee71dc731956ad6751b96636886ee3f2e51c9679dbc398cb9ead15884ee398fdfd9996edb67de5a85c55e2c831ee87ee666df36befe66b3d8c79a85c4155ea3bf11f358adc6aded26958b66557f38d698c736269ad121fbace69f9d69e6d19c6d56d5754ae00e8a1eb58ed765facffe515c31795eb7ea0138acc15f3d0f5ad63f5b16dd3b0de2e0e45709f1ef47429a6c45155adb6b3e564d232244b77f3dd32d73bcbb29a6ddedb263dddd78abb56efb53a5fab2d4f97f56f588671b71ddbf2f5b0eca0c2959215d5aa7c722c4fd859a14ad7319bb9a7d5fede6fcb318642a5e3b4eeefedcb33eeb3dc49dd4fb5624d870174de5631d72fcef07bdbe753f860ae432a716b956bab9b9e1b4f5bdd70f675ba8bf986b7eb758d352d731a95ab86644ac7f96759d332be1a86b9aaf920a5e3b0665fbb58e5fad57829f4e1bde99172a3735dd785e5e6c98dce4d0f959b325ca178f6775de4f8a54a737d61acee6c39595044e9be637e37f757fbbc55cdc5f284d9265df717e3cd394cd3ece53496a172f5c6279fe3ba044a197e4a2c4f9e087a2b3ce9387e1f63dd72b8731c6631b6519c749dcbb8df2eaf36631be716956bf8e089877fba56d39ce474d8abf9663bdfab6d9a67ac51f787082ed9ce96d391261dd73c8e33b66997c39cd73754aeff133e086ad4ce15871cbae772c62ea635ef1bd7b80d952b50f89d50bbd4de69ecb66e4cba6d39ceb8e5b08aafc5322e358afd148adf29fc4ea0fe526238048aaad3977a056aa0cf2e0f38743b6f7dfb7b71a6ebb55945e56aede6644987691cd7ee6b19f63acf9fa928e95e6b9e76f3dfab795be661d6d475edf75679ed99d5b56f8febf6ded9eed79ac637aebd47e53ad4bf9ff01b3fadd22a93adabda76b1ca39b63bf62c6751b93ef8137e5b1d02c52b6494ab274a1432ca65ed131e295b7420a35c9a6677b69c4464e48ebb5f7796edaf59c632ee51b99e48dcd9ac6f5bd3dcbedaf2efe02a75d323e5668c32767055a54ab9ae1f22b854296494ebaa3fd7755d95dbd97212d2babe31ceaf576de5b666330c95ab9712f769d41f7ee0a9fe548b5528b7fbcb55fddddbdac6edce95539275bc626de3b89ebdde316e6b59d56ce7750d6f9ece9ab53bcb1b369664573b8e651ca6e15ab5ac675bb39f95f75036acbb38bb77e3ac752ccbba62a85c6f7aa4dc5c17795d373d546e4ee177528923b7772c55199524dd86efee577fbd5bef58f6a85cb15aa590516efdb15a49ae466e67cb49c9d5715b6f7db5aceaacb5ce184e77b3dab9bc35ab37a7ddae51b98e1ab5b1ca03928ed3df77afdcf6ec7b1cc3a85cc7923c71373d526ebefc461e48cd43b94add44c17283693b5b4e5904d0e99bb3eb59cb3d5d3f5b8ccaf594556c6fe8b0bbfbe63df7b27c336dc3a85cb51a8e7419578dede634efda6deb1f86dfc9565ca67a868d7415e32ae7611e66b5ad56cca27245912b15ae546ce874c758eff76af8b3c57543e55a7ea08ac4ea7331bc5aad393574fa75c57a670fe39d756ffc39551b808ef3aad699e6dad5ddf36a45e5ca437d7aa0f1abcd373d526e726e9edcf4dcf450b9d9af254863e17cb8e92c96bdab2d56edddf0f5341e7e41e14a0c4f5b3501a0abaff5cd376e6beeb52dd3b29b1e2937365b8d621fd2a08afca05c5799ead7f5a3b86f30bbba0155a9efa687cacdc96aaad497a5566156a67ae615e9322f73d7c3b2bd96dbcd7554ae5bcd44ba5eb5ccb1cf3ccd33d76c46e55aa6fae927fcb8703f8afbee6c3961b4cb2c7e9ef556b7ccd5da2d2ad753ae59dbd972da684889e209e4e3e9e46386d30b328c31acc6d329080c485ef871c18516aa90fef911411a58d0287286156c11150290423d3d2a06147ab93a9d70c3102b8ae30ba58b6510a27f7c21480c40c892fc843e069b1f75d40f6e186aea26bf54111fda034171bc81c6c88c2e6d90a9a7275d88d96c3dd9e7a2418f34c3086bf674fa09bf52e8a9a89e52335831cc9a06cca8e00eeb533a24cdac8001363f66083890819c394b75d8ccd212e2b07270f36386800355e44c1dd060c70b1e9312aae8641925149e9451f345115362c23061037b840913a609734e511c3454ec70823077053dcc81c3055e08a2a701003480b0a10146b05802d7041633663861016a8453182344f180307ba4e00861c284d9234b0fa41a0cd4c0248c48068f140830c3164568e3fb011844a84ad8348898d98149a70b1e68f1d90d84190210a484d9e38911c28409c384302830618880183730681f8c37d07d5431841f18220912ca3d440c58010c1398dc5021e8084438630e31bec0b1e5064c081886a128f80e4a4258e28e184e3e4829728314368a0082e4020f2c71430826904224481b54080100029841013c30e738c38a26b620f9c112300c430440c33424081e33786289232a706d289ce08e2d6a0085076068001a4dc0d8411c299882450b02a000161ca007275b7061828e971f5c408f21c8a072c70ba2d00ca188903296d07d10030e0cd08320c280a30a047ea080092e20c791202460074b50a002168a50e1c677bac28c1a255098a1c1020b065c68c10711c01720a4b187132bc0e9c2878e0038d490410526a04ecca06cc11749680810032e3b6b08410e166ae0811baef8e2a588147cd1c516080899c10f175cc1042392108204320ced5819c34b1e1cb8828c1bf670a1c4a485cd08141248e165ebe400447068c2034828c124490f4148008805a820853b5239a8c09930a560471e56eaa04115a82e80c030c597274a37579ea0e91803be20b9810845782c1312700114404a604713ab0e042de441bf673b91334a8211a112715c5941013410640d0b8d1338a00795930ab0800918b008428c2251687843022b786354023b9ae89247171f2fe876c041891a7c29400948256c088991c4022cf8b2460ed0b88181142a784004971a3047f0a0605a26dc5913860d734e9b304498992203193cc08730436258900202c61e8e0a0180403881135700018012288007551061080d480dc9828a3bae30010ec258c0101326cc70010b9c1f1f3c31010368a1441b04b8430a48050b0db8a00628075ef85001490845b0010d3786cb429417ac213de08ec8c1027480e10b0d3cd1610c18f0201d9620021327b0f183ad600b3dcad0e3660631c234c1023c61c270200c317eec600ef981c71cf2830973888dcd1c62c3c21c6223c31c6273640eb1d1e6109b9c39c4a6ca9c73a62463a3471166e908a2593a42cd9c33888f9c213334984366943087d0288942c3ac61b2c00d9199610e91d1e6109922e610190dcc21322e984364c2cc213301984366a0cc21333fcc213349cc213369cc394b2b0441c28e5942a208b39444cc2c2501c32c25516729891c6a5050a1840218c32c8138b304e6304b20965902b7cc12c867091c670904334ba00166091c6396400fcc127882590269304be00e66095cc29cf3071014b2dc314b59f298252d33b3a4258559d252c32c69e16a84d804f981956609bb6196b03b4b180eb3845199256ccb2c617d96b07296b0246609b36296b006cc396d5078a19433c62ce59c314b392398a59c19cc52ce1166c9c9902ba51b3d66e9a609b31400993927cd0c181a0b0c1824c0d48099130c982902334760261460a61452cc59337dcc399f98330a30d307183048809102cc9c60a20093844502ab0d312080c5aab20d11b2c29cd8657186c2affcc620ae7fbc7865814c26153924881643824c71849a9e888f3c21a1a6fea391393d3024c80d395ea5beb2bd16f253e5909f4adb6cf5137ea02af5a9c89e20f1c93796221117c3d37f632962c1ea44d69c93543e4f17a5fef98034c9c355942130b4122482efa47c92cc099f08718c1266e1a038e5c983a5b8c35f34c384e21766c929c59d5214513bf551197f48531177a07450ac3cd9e94e58ac60c1d29d3a2a59a058a972ea21a7ca9c5613e69c16288ade97fa47abc451450588c98feeb9a2a503f516a9e8fc1e57228f962ce20e0fd74e42f1e3dac993c74276a872fc9c68270fea92270a08ea2758b36250cf73d1a093f0fbf9462b5c3bc1428a3b4ff6089f8bd833a7c5849c39ad25cc6929618ee2388a5598fc882013fe2ad53796a42945eaa02560a94b317c1224865cc22cfc8f90ff435a45c592863a3faeca55d71e4595e3e7518d22354ae883526249ae36bda87e4f8339d72b41917a4a12e6b4903087c4a0408fafc74ed3344dd3b47befbdf7de7bb32ccbb22ccbb2cc5a6badb5d6da5a6badb5d65a318b59cc6216b398c52c66318b598ee3388ee3388edbb66ddbb66ddbb69c73ce39e79c31c618638c31d6344dd3344dd3b47befbdf7de7bb32ccbb22ccbb2cc5a6badb5d6da5a6badb5560cc3300cc3300cab1cc7711cc7711cb76ddbb66ddbb66d39e79c73ce39638c31c61863ac699aa6699aa669f7de7befbdf76659966559966599b5d65a6badb5b5d65a6bad15abdc96b176335baba4747c608217538f9f84eb7cf8fd841defc647955640fd3c4fc62bd6114271e753224fa7c79c9611e6b48aa0a58be2480ebd0ea8f2e3e147f3efc4bf13fff648becaca9c16118650927c4e4b08734e9a79da23c97554a4a5b9ce9c5677c4883587c039ad3ce6b4f098d30a02184818634eef44925ab5751f8150863afc52dfb8c98fa7481d44c52924a84bdd8734179164c2645b2dd1a5e6a48ad4a58632a7f5839ff0e38fc5eab4e8a0d255fec71e5245ce69250942c3415caef3aaa19ea1d7412c5543e35691e2f85b869c4001c12f35fe15f227fc50e5697cd566eb6ab335cb89bfd0d74da6938a2479003032a107941f23c400556a5592a1325f1647ece1e7838b2cc915169afa7992a24aada22098633291b2c80739480d9889a12439c50107ba47720b51032ac5c181a2aeffe14f8ed77331f4a147e749ce959c27740915e21f91198381982f88104717422517d41123e197e537069da6b5c4d2e69c4456e2d08f628a725a8a21395e29fd6349da4bbb301c153896dffe4095d0db6819820c737209c26654c93665c99c3408cc62b84e114208a61760ea10c215010471a9928b573f60cd66a9210f39e649085884c04331214c089bad178683f35c7c62919107c603408e171e09a0382ca1d4e4f3137ee1a7533ffad092d42a20ae47fe8954ac9630a76a792c25b8e262651cbbf0554c8e20e13afbb55c01c10a6e9047c9f6006581861c4dc0e30d31a0f8e90060cd49c4473e179f4c6b5a739226898609bcc6c80ce8c3a744c24293021aabc140e1099acb634e68e347cf0e6dc387c3261ff5263f2eba21c7eb4bfda552e2fe39311a63021c98d0f0c153d91f3c71509c231862f3c49c3314491d8aa416cb9438761f3c3104d230c7073ef4fcf7a0df09fa9d1f0d46d19bfcaafc47b19ce8c10d2ee8b8ecfde5dbb6bb63cd66f9a647ca4d0b3a9edd8de18a613deb1aaff5662ce8309de1d730ee7abb38e747e57a22f5b682ae6a1c7377dbb48d3dadd5aa820ebb1a96ed7d77dfbfb7adc5d165ebfdde6cbdbc5a4ce33a29055dd7f0f78c5dcb6118cf9fc1d1e90dcbfb7a5ce6dfebe55a23bdd1718c7df5380e7bef6e38a3a0ebd6cbbdeecd669bd63c7bcb7ff204dda669dbf77e2cdb7b2deea88c2fc904dd67cb1fe3afedbb3dac73093a6fc3f0c5d9ad19c7df3d4c824e7b7ad319db3086694fd37b045dcf9c567bde386ce34debafdd9d2da70190dce8fe777fad2f77fbc6eca645d0616d77dff0863dcbf1b62d2904ddd6aff1cab1ac6f540eadd8ba3a856296fa3810749cc3b7d67dabb67137f3349115a40f7497578dfb7b557b59f6b45c31c9039dce308cb3db72177bee65f594d58dd446f758e37ab6f16f77578e9f7ec28f5c65b5078d8d4e633a631cf63973dbd6ce496b745b73d5bb5a679b87f9ed40c76fbd97e336ac7adaf61c27a9d1bd86abad9f69f8b37aed4ea3e3f2d5dca66dfb66bb671b86caf522a161abbdbaadf37b9b7fa6f9ee8f3d2671a0c3b6def96b76396f3fe771a85cc34f1ce296a4f804ab997446976595d39ae779ba7a196fa0e3daeafd97c3d8eddfb58da481eef5c6f6eeda7f63ec7dc6373d52ae0b755d3c24564966741cb679df5ce3dcc69de3b20c74f96b5677f7f8e619736e13f789fc4e0ff491e36aff9831d0dd5e397cb57a73b78f398c74810e639cce2c966bc7d93e76730ae8319205baccfbdd36c7379c7959671b4bad7bb4955446b773e6386fefce653cd72dd70a7499f3b69ab1aa75cbb1fd8dcaf5547e426f2ba68544814e7b9acbd8d6aee16c318b29804446573fc3efd9ef9976397f00698c0e6319b6b3c7dadddcc655db85244687b1c77586f18cfbbb33cf65f89ab57887144657efd65d6b8cdbfa5eceab13e872c63d86e99eddab69dc7b24303aee668ceff6da6b9f6d99c3ea0fa42f3abdd5cd611ed69dd3b0ea5554ae3bfcb89b1e293d5e74d8c669bf711ad63bcf328ea372ad3f2409748ff56a77b6d5deecef87ab2d9fd422d06599f6b8cd7986b50d67bb6561964c740012043a6e7ff76d5bfd38c317d3b00290bae832fcd6d69eb79e619f3f7312179dd731af670f6f6f3f965d6c3b2d41daa2cbb89c3dee61fbb9d5dffb4605e9019df65ec6f5ae9f6f56b54d72408775aeeedf34d7b5ce32cd4641d2a2cb75d3f6c61bff768200a9011dbe1cce36ff0debab357db78b85c4804ed76b31cd77a6ed27371d564f7501a405d8cd62ce62557b5597e103d5aa80ee72f9b75d71dedeadd8e3411acb75e541caa2b318fbce61f63e9761aff3cd52863ad7155202bace394d7319a6b5ec611cc79110d0655757dd354fef7fad398be14ac2a2ab17dbd67a9ad65aab9bc3a85cef01baea59ac2fde3267b786dd8bca58b34fae50b9b966900cd0ed8b338c735cb96673dd1a96afe838fdafed2d57ce6a4ecb9d644587550fb35ddb98de98cd7b2355d16598dbbb7258cd15ab98a69d86b40a57924445876d98eb4dc376ce35dbab337bd323a58a962eb4727385cacdce961311a402746fb9ed6d6f33ce59ddb14c2240b76999c5f6734fd3b887fd254dd17df636ad661ad6337db9fd9ef190a4e8b4be9877b9cd6e6dbdcccb5099ffcf8f2eed10a428ba8cff3bd617d3d55a2e5beb9d5914098a6eb3386359c6f5bedade3adb1a04e9892e67fa318cf3b6bc399ee98acaf5f4650b929ce8b6d759dff971ce76ee768bfb94d91c484d7435731cc67ad5dcde7afbbdf5c90d0f3e9198e82aefbcf2e718d6335db366222dd1754dabd5cb2eb7339c79d52ad169d8cbb49ef5f6aeddf2e5324c4aa2eb99ceb8c699e31ece36db4948749cf63a739ee9ceede7bb92c074cfedee1ae7f635d799d6c2749b5b6b79a62fa7b5d73fa3723d915f569fa787cacd95eb22abada32674bfb7dd9ff5f618fb5c2d2ad76d89d11e9d976d8cbfde77df0ddb7e43e5fa388911133a8ded4dc31aefc79c77bbaf4bcba9d1123a6d37f6156b555ffdcfbd6a7d3152427773d7b4cbe92c5f2f7bd986ca1504f5be373d52b024a1fb8e69957bd9de5ad332ae51b99eb4cde9b86a658484eeb3bed6db9ca7bbf7d97fb6488c8ed05d6f6fbdd79e39edd69b71a85cb9ec6d2c55d9d0488f0e6359dd1bc3aae7fddeeae5e1d76d3da9b291113aedf18eaf877df736ce6a5e11ba8ce37adb30c76cf638be75227478ebd9e6dcceaec53ab79eb681d1103a0cdb5e75a6552cd79ee13ac548081dd615739ef56a56bdcc3d46e5bac3d5589ebc157912cbf0cbf6a6474a287ea48e11a33c3a5db15db57ebd6d378ef1c5a3e33967dc75cd5cf7fac5f6ba362c4641e830cfead6b0ad58e5acdeaa122320749ae51b8731bb5dcff332fe1f74bb62ce69586b8ddfe3585fa71ac6c8079dbdd8b6791df3b48d3db6d51e74fb6ed85bec5e6de72dd78c075ddd36fe9c63ae66bd6fcb77d071ba73eeb1e7557c33f6b40e3a2e63dbc63aab167b5a2e853eb4357b19e5a0d35bedba7a9a76b19bf1be5dd7a9ded1ddceedfad9d66dbdce35b6a3c35f315c2dbe5fb9cf5a1e2ac7110eba9dd92d7fa631ce57ee0681511d1d56f7eb5b35ac6fdddbe56e7aa8dc5cd7a9dea0e3fc37edb96dc9d3972bef1b4bf2e39cfd7ea318d1d179ef61d75e9e6d6eb5ad6e1b74d8be1bce9a7731ad6b9add6ad0616e75e59b563ba635cbe139ba0c6bac7bcff2a6556bf596a3cb309635cdf7eed7667bf368d071bf799fed6ceb1eb6616cc39619a3197458af9bd7b5ede96ceb19573b4632e8fef9fe7d6da67d0cba8e7bd58ff50de39c75def957d308061dd795db99b6bbe555c31e17be4a7c4197b18d6d7bfb8d75e738ac5a0c8c5cd0656dc33efbbd3b66b3de1f956bbee991725ddad66c67cb493483510bbace619cbdd6f3e3cbafad2ce8bc9a69d8e376f7bd31dffa0aba6c799671cee5fdf56a1a6f56a5ab40c155a55327ac96231574db67ee695a7bbd562ddb1b476735cedbd5cf9fa3723d891cf38c52d061ad3dd61a63be3d6db787ca35e8436dc370749caedbc359ebe5177e27916b18cbe88dced356eb1977eeeba671c66f65324241a7716dabe76d8cbbfa728e3b4167f5de3ceeabcdf0d61d3fce616482aee3bcb3eddb629d75fc2382a74f037da3ea74ca3b5b4ed7a8045dddb2cfb4b536778b55cd8d48d06ddd7ee7de679df7cd36e31174ef69b57b3df38af5dcf386ca35576b8b911b9dc6fbf6ac96718d77e6304d049d865dce7299d62ea7ffe6ec3434965855c028045de7b0667b76b7c6651e77312a576e683fe8e90b687cb2daa1bd8011083a2ecb2c8665ad6eda86afc550b9a6b04aa7b20f7458eefc717edbbfd66a372a57d0e33ad7d74371bf8a0c75aeebbaaecb665584c5c803ddf5ac771f574ce7ecddad55ae8d4ee76cb56df9f6a52e5755707ed0fb7ec255df30ce3262a3db6ed5329db5ed6e3ce3f487a3353a6e336ecb2ad6b7bd9acddbdef448b9e9d275a0ab1ce77dc3dd66af655b55a3e35e86f17b9ab6597c339dd3e8b89c7958b6e54ddb30cdb12cef6c398523343aede68c615ddfb7b56738ab77c4816ec3ba6bab376fb33dc36eb7b51b9dd1651ca6f5af5aab5c7f8dfb6a57a30d74f51fef6dd31bbbd8db5e860f30d240e765cf699e96aff5acd6e38a0cbf563b32a3db975fad79d5dbdadaff4d258e50ae4b258e9c8f7a2505d419e85edbbc8bb5df1aaf1aeb1b956bf93fd5823aab3d230c747cebd9cb36ae39d7baf1ade19d2d27214617e830de75d699b6ed4de42b125b6364812e63d66e195637c7ff7b199dbd76dfed799fddccc36aedc0a8025dd5eea6e90dabdbf2fededf0f8c28d0e5aa61dc7dcdf3ddf47d2d57118cc8e838dfeaebbb69dbde34eee131ba8ed59c69dcee5bcb157b1ab9553746627436dfe730dfb2fbdadd74564d300aa37b7db18d3d9c710fe3f7b20682d1043a9cbdd5de9679dbdd1dc33b1c12129d5c177f21d17b72c355ba8a4aa77056c1e8328ef33a76f9762baf3ab3958dd1171dde5dbfc6add535dfc7eac88b8eeb8d7b3cdf6cab5bb7955f57f9e4755d17076624812ef77f8d61ede5dfb89a3354aef9875104baeced6fdac66d4f6fcc6ba68da52ad3328240d737ce72c75cd66cadd81263d445b7fba6f5ef5ed7b45d79ae43dec95afe6196acc5888b4eab9a97b5ccab76db75f33454aedb4d8f941bb2fc40503f011a6dd1e58ab72ccb8fadf695638eca75b4f5d363cf755dd7e8015dc6b6b76597abff36ebdb1e39a0eb9bddb6965fc3dee661b862232d3aac596cb9de38ac314ce378d73a5a01f5578efaca75a9523f6a40a76dde71c7db6adb679956cb9b28586e74a9a1a87aad230674176f0e6f1edf74af5ce6ac12a30574f9eecf366d2fbf1cbfd9a6802ebbd9e359eb56f3b0e61e26e557a0beae4bb3ac1865d15dce725cc73a66b19e799743e57a12b9d64709e86cc75ac75bc73297b16dcb50b9723a374f6e7a52e21865bf8ae7ba38264608e83abf58db1ac670eeb5f7da1fcb854d31c2a2cb76abfd6e5aeb9ead2796dc152c3718969b2737d80e3757a8dc5c17a84a7db86a9b034607e8f4aecfedfed8e3b8b6bb8fab5293b71aa0bb3d7bd8c61bf759f3b6c7fa09d72da32bbabe7dd65a731bc6fadddba3723dfdf793b5a2c3997b59de1c776bc6186ba85cf928ee1fb72a85cbaae874e6bc678be9f73c8d85a2d6ddf450b94901759b05c2ea888a6ecb2a7e4e67fae67f5dbf009de6717ddf8eb3fb96f3ee264077bd7f2c6f8b3596ef6bd9141dce1e867198dbb2acbf36f45c4e27954e558b55954e65a3586aee3492a2dbf07bdeaddd569e35af66a85cf7476a2f03c26a149de6bd5e8d9f578ff33abf2328baadb79eb75db7bd6d9ab7d9d369f444b7651c66bd0cdfc7faef7e8f8c9ce86eae5abb16cbb276ed675813dd6fcfd65aadc63487759c6b1e4b55f68d98e8b85bb3eeb8f7ffcd338cab5bddd97282325aa2f332ad56cc6ed8629b8769d996b3bab3e5a464a444d739bd3bc6b6eb651ad737a3723d89bc56ccda8a555b93e878b6e1cb69bcbb56bf67168bdf49456a3b5b4e388c90e82cf698c56ccd986f9ee6695a28824faecb1b81e9b24ddbbfb9fdfbea9cb95baf4b2b45613a6df7ebfd96d31973b6e726745dbb95c39987b9a6f14df3b124457b745ccdf47e8eed5f8c5d9ea172fd4ee4b75526749fb98e555cb1ac6115ef1c243eb9ae20711c456f09dd6bb9ea8cbd6b37bf1cff753d17b74ac460444ae8b2b7fb31c7fddeb076359d040e6bae357cf3e578393e1012bacde3aca6b78b71dbed79cb1909d1113a8f6f3df3ac6d5ac71bdb3c9c12223dba6ce7cab3c6dd4dcbac7d2e9f6a122223745cde98c6acf759113a7db9cf2eb6b366bb7d5d89d03dff7c2fe75b867bb6656d08dde5f8e7ac629beb9e2b7e2174376f5cd76ec776bbf55a9e47a735f77d7bb8de5c6b56ab9522c2a3eb5ccfde7e86611aa7e96caf2b085110ba9bafb67186efc63c676f8b80d0dd8addcd6adad5175f0d5b5b7fd0598d6bd6b4cf5ac6b06dfb84fe7ef8a1b6ae927dd0759ee98cdb7aa679863dcd7f7ad0ddca3966bdc758dfb4fe78d061dde32ece59dbb0bde91d749cc7ab8661cdb37d0cdf8aca75d441e7754eebfbb5aa7d56af7773d06d6cf7b61cc65ce7bdd77c47c771ae61ee39dbb7af5d737674dcc632d7316c33be59fd38e8f4c5b6d5eadfbe75efe63a3a9b6daf7f77edb96ddfd61b74d7bb9ab35b7bdededa6a968e6e631ad6305bb7fc1cb6318eca95b341e7758de7dcabb63bc675ab41b7e9dab7e770c635ae691843e59ae7e8eede6a96e9afbce65b3339ba8a35ac614f7b9c772dbe1b2a578d06dd86b5ac568d71ac596dfb45e57a67d06dfc7a7bf3368771d679ce64d0f1aad5e7f2c6daeb2032069dd5b0cd77c774cd5adbf6751009838eef0dc37e570de3fa58bfa0bbbce79b3fcb59c535d3de05ddb675e7bb3d0d67cebdac059dc6312d7b4de3db2daf190b3aaedebded4cdb766f5bb52be8aece6cd6b9dc39ae6fad312ad7aa826ecbdcab5eeddbdbccd3b6ac5af138bae7308e615bc557e33ccba5a0c3b0bcbd0d7fb65abf9ac751b96e7074197b0edfcc66cd7da6f31b9db6b96fbc711c7b9ce63a46e58a51d075cd6219e334ce70dfb96aa85cb51374db739bcef56e36b319bf1e2ad76b820e67dbc3d7e3dcb66d5bdf4ad061af71b562dc314fdfe71c2a574b82ee6ab572bdb7e76d996b38a372adaa151f41a76139cbb0c69dcb98c599cedce8f4b6bb621b97d9ace37db14c04ddceb6fab957bbf7db6c7f16828eb33dc3587b1ba72be7bdb620e836b7e19ab7def762ba62ce7ea0cb348b31ebf15a3bcfb2ded603dd67afb1aed57a1bdbaa976d1b1d5633c63bef9bd5bc6e5ab36c748fefd6b99e31cf66d9ad6b7418bf57cb34be76d37ed32e2ad7ac03afdfe3b8cc75bb6da85cad1a1da655cddb55db76c6b4acda34baabebce36e76ae656fbeea172c52c1adda6e1fb5deb35eb4c5b8e031df75bd3d8ab989737f76e86ca753ba3bb18e6e9dd2b563b8765ec51b9e60d741763dbfdd7b0dc312c6bac81ae7afd7ad7e3bc568fe3b5a372d5cce81ecbf0f570e6aa5677bd19e8b4e578f7deb3ecf16f1906babdbdb66bce96c35e567786cad55ea0e332ceb3989773f698dbcfa172ad16e8329e7139675ece1aefddeba85cb15acbe832bb5deb6d966759d578dea85cb90a74db56394ce31ecf98d5b8bd51b96e14e89eabf6e2cb65dbb6f1ad998c2e739aa733ebfde57886650f952b1ea3f3bcdfb2cd2ce7d5be35cd51b96a627457c3d9ee5b63ed76acb58dcaf586d1d50cebd9defbdae671deeea85cb30974cf79f82fb678ebd5f68d43e56ac1e8f2de3667b3ce3ac69ad72f3a4cdbec7a3dc3bc7d75ad1a952b8622572a2f3abcf3e65de3abb1cc7125f95c955a0d21818efbcd61bc33fe38df2c73a908741ac3dbdeb53ec7ecb6990a021dcedcf61bf3ead6b1e7368dcaf553a5564374d1e56dfb5d39bc59ee752db3a85c55a9d5105c749bf36cd3b2f634e6b4b71695eb666b26daa2d39cb7695b6bce625bd3f4ce1ed05dac690d7b1bf7342d6bd601dd96fb7631efb5ef1ad7304fa445a739ae6baf3ddf6ac669f58a1ad0f5acd5ce3776abd5aac53885d52a6240c7354de35bbb96f3acc66d4cb5808e5b4f5baff2bd6d5c6bbc2aa0d3f896fd6637cf1b7bdbf6e7e2cea2bb1a73bd57ef6ef6769b2d2a57cc244a40876558deaecd15eb19dea727e2ab82310e2204749bcd1cd7fdd6ce5dcb718cca7548256e2cbacc7175cb3cdbd9621d73fc230fd065b8560f7b8f7bbbd58db322a84bcd4150efba890cd0e15ef9631a86b76d7bab317d458739c7f163b68f5674985bcb336db3af31dd335b4587edf63cce317633ceab5843e53a8e54749eb6611aa7d9ba2fd7b6860d79a202745ae7eb611cef7cabbf39312440a72bbf9cbb5bdfaebe98d584a6e8f2db7b317e370c7b9e7346e53a8a5274bfe1e77ac62be6da661ad351745a6639ad376dd372ef981b9f08f2b322283a5c2dd65fe3b8ea65fdbbfc131de66d8f63ec66ec6a7c77ecc7894eefeb61fb377df5b6956ca2cbdbf36cbe98e3aced1a667f98e86ecf1efbbad5ad79df19cc38a2253adb3bce566f7eb9ba5d2e43e57aaa57a444f759c6bded56af6e54ae208acc6e7aa480289eeb2a3f6f67cb698b92e830b77118b6e97d2da6330f7f3e52ab588444b7dd9e6d7eefbdab61dbc6a85c55422f02d3d9daefc5d8b399b7390c5770950ad3696ce339e79e35eef1d6385bb5267415cbb2acb977337d3bb69a735deb1e1de65e7eee7ec6b08665fe4ce87ac6e5ddb3db37bebfef123aadb98bbd6a77afdece2e86554d091d87fddeff796fec61bd392ad79438f69b1e2a3729718c725d58b33ad745625c123adb79b55dab5edf1a56398e848e7bbad69cf14dcb76cbd846e5cac5d409e8e3196b36cb3d42f75abd1cb63dbe37b7330e43e50af4713dbadafbe53c0cf3da2fb6d643e5eaad4823741de7bf5ed76ccf3c4e6f5911ba8a318e397637ae715eaf9708dddb0ccb6cef9bb3fade2da372e55c6f9735846ebbd772b8f3eaed6cd3b65d922750033d076aa0bf492c2174f5b5c65b7bfbd6ab18d6d7954f35a7803ecba3dbd986b5bddddb1af3b49751b9de5aadb6a5803edbd972da62e1d13dd758e69e87b99f86a8540eebc5a13c0c72140541c6102626ab0d0000531200404030220f88e451d174d7cb89011400046fa072884614c9635198e33006a228630c420620420c1110a0a1224d001dbd8d1d4f9fb8a8271757c2c247437d1a929575a319c374eda4a4dca337618d4c9dd344c7a38799a08e34586c46c0bac4f4838ab1d1a51cad4f22299d6a053c361c6b91ee32b4065349440ce0e802f9580af964553a6a57bc128a976ce0af8eec681d5df995212c5431af1a9b0465d9c0d1506a902ac45d7adfac322cdcbe73085580098568611368cec62853b1bf1f42efcdc5ca87508e0a411665099a204403eb0cebc51e2e212ceb6df3ee431f3e5213863c8735cde5fa472f0c0b6f0ab108c9ca81800fc9f7dd087c38217ce08ac7e169b30996168ad06e4d9280187131900c962c0054a4380eeb57ca8354c4b6fc2665bb06bf04ffbd25b10c5f17c8d64d5cd1d4cf12c33d36ef5d9fd161088d71a0f15e24a31fbbcfc6b26fac2302991b4784b56d7c2970c0a80b2b6ccac86b075a7bcb90dce30e6db423eae78d3bfa7c0881ad04ca159f2b4e823006f5c1ae2f80f45b2c8a2deab8d6d61cf8fc1bb711751de8799bbd11c864de2c016b998aa04d1f2b88e66cda8c393b718a36833d87cef8f9f0c19446b4b47b20cb51a95294040e5476b4d4399904c00b2e3a11927e6b3372da9065da39869927ff23afcbcb8849f366fa34b8029f9cb6b99e6148d2cb7f1fa7b17788c538318295bdebdb05715c35f1c9847b1cc20c6d21dbfe3714ede9c52ebbc015329c078544996c557c378c7b0e29e370588b13779bd1a8f679a61d6ea4c876c04f2c24e56a49f1f586d6ddc4bbbc08900bfcfaac14c620c4588b5cd7d0de7856de34309c4cf283c503261dff0998c9eb5da16acfc90b5110c0818b63e22282641b1f106e8be308c60aa74b30341ba945f71a757bbb60102b9afa5cd3cae87ec31615cc2f19d140bf7f773a42e42be082d13a30eacefcfe6f10fe706c67bd34bc3c73b45541ea59a5c287dda25fdc111c8bbf6aef5d3cea51fadf69c4a3cbeab29ac4d321d13a355053cb7aea671d5c403e4966f58617bc37eb5e38dfbb48eacfc749000bbcb0b1404328550412d34e73407bf492fd45e397f6cf876072999a0754a20f2952dbe3fc26a48246007212070f9225f63d3f907f8da5dc4878a858a6a257a84360e025b40c1688c3181b2331153cadf73e940de5faa459e1b4cc31bb7c9152fdd25301226abd390b6e7284dce30d8bb7016f7a0faa9db39c2229e9f28ab108f9865a0c0a43a1005d1b7e1a0e415313e94e1ab71de69b66084fa9e4931f90003155ce1d4b8c795e729312144dc8d8f70545c94b4fbc136a57976aa4198c257379348cc96a8701e100db407e85e8224179a44a874f4f38303b3058ebb6eb1ab33d7014cda7d7b41d8a54c0b82757916657a360c8e9657489ae4e9fd33dd094efe1b48dc04576fef4e06f1542f732516394406f20838f4370dfdea844509846263f0765db72f9f3ec0602a7fdcee6e6442b75dbd223d44be77aa4be028531452e916427eedc5194f68d0972a460bf099f17061bc6511291afee0c7e0caa9adbc56fea20a1981bdee3436ed4a1246ef59ac94611fdddad59d736e2059cc0c4dd77c8de6128647f21398e411820e3b5cfb47c9ec3155ad22c4b34a7cf9033a1e96966ed03fb7eafac6fc72af9e158223c2edd5ad2a78563a65da27257d200ef68c0df673dabfb1a8e361f01ebe55ea3850a13d030d742dc77a124ec038d6a0212f700ecccb9bd56f6ea9a554d73ef5f043aa3a1396366c457189a47e7f0f512012dd79b4b5ff787adf892511684f7b2d663d1d993d6256ef2e8a4d098292ae2936dc982a8cfa6955c68fa95309ded37a63141df4e40a171818bbfe6f7af4039a8e13806fafb9a16ff31e0bd927246b9ca238097c73264f568ce842e4ca8dd986859d25abe0dc7845e6ddf2579a20cbb69f3ae1a35c5bbde3f4c93abcd547abbc27a73ca78c52a89a8e9bc07ec7538239b41aaa94b5d70e744bf22e7295df5a41a9b1290aad388ecf58470a8854db860a87a8b1f1af219e65105b138d3ab855ea745b7d4c6d26addc9623ec1d42af12df690bfd059ff69ca755256f2ebb50ea9f0ad84484aaa299edd7c42929c4f374164bb34d0ea6211a7c0bb38e5aed2106259ba9e55d955fe30f341a2749f3cf6aaf62a888155351b5a05de91ca0eaa867d41716943cb4d3a0e135612ceb162f1ab98942c20a291945bdba2ceb78b4639e7c241b89e0fac161ab337288030b647b521453fe1e83ae1837327ed45892b1e4991a754b603c66bb2af78d1e1ee0a75c04aac002ad566f1458687619862cd2ddd1ac1e8c8b3c422d112c33119890d0d94d421ab50555df9f7944c3504e914a4df51e84c1b7c9a39b40b419e30cfb9b80874385263dc7d8bd8428083ce8f425ec279b9bfa2e3e4b7af3dcdf0a05957effb62300e9140a8b89226ba7aff69f940c1c9e1e790eb5aff279d1385dda9fd72a3602b62ad2e78bcf09300644641a2ac59063938d790d7f11de9f4fc9b4fa9f32ba312ba85cc9817b01b742e59c880b3c43f402b4b541c0b13dda33c0f01d10efd4858dc9b5b937a420329ebd22d15800eac312841014a567b03cca0caf34f97ee25063d976300b40687cdc116a8407e7fc06085a46dc7071d2229b901ee75f6a97c5d8c384e0728ee4e9365be2307f16c32740cac501b5fad84bcb9f1b55ce40fef85efa6db84654c72fef6250501b9cb8336059737af8c40d0fe428f9236940afc3c3b93b465b76044eab62b23d620b6b82526515b4b2d02679f622867dbd3b21c0bc708ebabb8a4f1764de557503f502e8b0cdd6662667074786f31fc8ce7cbec6459113e3e56d1269ff70317fff64bf42db884702aca542f45a8dbaeaa499449fbbbb74a263e67b2bd46e4a0cdc44bfbdf03858e07c33da491f3436c9f90f3909ae3042ff5c53f6c84eaca9fb6437385ff89db1228f68b28196455f4de2872069b54beac97420f7261291a1c0d0199f0ffc84dc81a9163a71b1334d7e45020bfb2192e4d65e94f239403e76c782488cdcff265be54594121e226de35acb31929ce1001e79a413fb26de0c5dc98c067951ca032a7eb73be0a219cb772cddb709f6a685098f48359e9e2152ce04c9020d3fb885c283df48fe55a80a1ba72360cc74d4a40a0517daf7025a1979058e833ddc1d111284577c4f4e45b1b0868079464ce305fb93c45804b214bfa6c9159863ee049f24992ee250b984691065298dbbf8f03a62cf5b59b43895e1ce28a2526d4f388f91bf39d920f3c7f1abfe0baad5c9212ddde2ae550182db91b4c4e91075ddfc0c92bd1694ac8a6d57d3605f95ecb11a15457c2be5b5caa765e6c7d7165a35c6a8b6723cd395b1a49fe49222f91b84138a772bd6b00822d030e48504ae4e211c4198653310e7169d89345c73cc567c2e603039d996501d8f503c84c6d96887f314398385719170713af9f66af2d5bd867476a1e665163dadab2e30ad1735ee0116d2728026b1b21ac6cbb69ce0ffb7f95ec329d062a0606ba833a1dcecb2d176ae5ebb98d44705cfe8a281ce4f8e13565f3357bac990f73790dc32f0dc1fbe3d4ded51fc7e0fd54d9b664e0396bbf9c1bc706004c6d2f806cd6a8909befb7ea22c614313e1f33d31c6a1c4b4b54bd34253798a005530b663a81616d7931c04094b5b241a2d5e74a8d2c0db2a8bdc229346a11e1552cb5172228f4421b5c5c8dc27f129ce2164a4faaf3e93dc4c2f2af7b163417f3328e885e087e35455c534b8cb06757e5b90636433c1c3507bb887f07d8893c665990b735b8c78895ec0ffed886c0faa58de2729e132e5cdeefb85823bc6a003e6ed1959d9d39076cfdbb8af0c675854e2451a381de3069b7d7aa04ca8bec5f7228c3cf8a79deb2156456fef1480d682aa5a02a0fe8c4d732791353a18e21ea42f01cec78a4b4285ac4c02bd288e46975c3ffe4f2821fce236da154355bdf14d5702575434c114353f8ce58d79d92f9ca5251df1ff1d604914d878622bc89acb239843bf76b69cf2d779db270b408b466512ac3ddd10c40fd9a000b077fcadf14bc62200ca73305a9c4923aefb1f9b474277185ec1d01fd1844a705bb44800867ee865011c66c074e3b69d4b74a811884918ec79abb289ad22cddb89d337748500032ab91c265bbe61f113d1bb5089deebf3c1c7b7cb35aa07c2d8795e87d517f6ed1b3680f5b3d649345f655cb2a1ce3e5039f8add280010458c5f2065e29b7fb24ee44aa244f6042d425d3f12221cffd459bc3faf84a546270610b49cd6cdd3d2656e443643931d889975eabd61f5916907db3902f446c2f6c6aa76326707881e266042306a68c941f5e8727036c60774ccc4ffe4e884533b3339141296cb40e6bec8ae3c08f6a5e5e363c96000bb1cb4bd81a7a73e2837f70bd9701a6aafb00c36b915474e145f79f2ea30ac14b7bcd5d3c8b8f2e8082a9fe59106758f8af3219c9e398f6d1f199b246697d821ba6541ad6f432083b454b696638bab5085f569dca7ca7c5ad6a74db837a6e39bea0e98c5a9ed93902c99d2117474465c81ac24c5a8a95157e1f6260383d9d63bcdc88ebf5329b37637c9d307bab944c6b3e9b08f463472eb3d53d3e24a1569b57b925d2aa03305d422562a80454b2af1455d93a80fb0889c0504554e49b6b0982868288072b14689ada54fe50eab60954ee97a02f9302d432ceebe0580c36d490fc0464d5f1a534d67567bd27c20498014675a1209400205c85fa51cd901b20eb1b31d56c02a6e9e0f7564031756fe18b5ad365e721ad6bf839b9460f25113f1d39952fe12a6c9a7aa26cef371caf3320593a3b398a181bd1882b2038304561910b239c36436182e9515d61164c80ccf2fd4a4692fb5a7c3a1b4ccc4fa30c4652182a4964c31ca2cbdac251fa0cc120c5a81a17d20ba4d86d3b65a660997f9c513c9ec3bddf5eee334f1b3c5604556c9df3f6689f15e22d6a7ae35216bde4973b905d113346068d2c9dfc7a7bec35f3a13b7a20e779d18e51a636e27495ccd775c8d32385d682b2af74811b184ddb1ec4ea8c9da8514134ad68b41cba7302cc996cdd94ade37bf2e82a3bfd024037dee2658405786fcc7f37d28f40e4bb5a0fb869f85eff8df4631da0e5f9a5faf947c11a660cc2f361d3f9bd744d3e069faed9a90319e6e5dcee0d231178785aa569f41b5dbe1f3accf45500ec84b20333ba4047902ab5468f7467bec92740e5cc61d3e8c91335548045b9e8c1bbf71a0aad8993c65342352972bb52ede10f2b4eb3d82b1269ceb5faa8597710028e6a9fc004a13166eb3642e9f1e043ab135b2272fbe2fb69fb0386ead0a32815c04a0606bc1de6946ce8245605e4e0a95bda1225d31a7f67b573209b82933e63b32f86d4d4ebd784d1d0f4a2a370853d500a00390e30b336a0401452a987e54d5ced991ea3d2addfb95ec5f857b96f0a883ace587bf00fffad4fd01cc407a0c7440287cf00ba669e0a50f4914332c8d7a0201e43eef81fcdcc62837144e33bdc2dcd5ca420d9cdbdbd1491a4af06d52034d28922f8716400c5aa84624d808c8887b86b6c0ffbeb447f0ca7d5e3a6606bf158eb1f11470d1f5546ca82e46222cfb3639a12badb3838783f07889c4a7136681a1cff9a3394588b27f94e9c22083bb921a8b4226d22f90d2235611c0ade98b3cd5f2eaca136aee9e8e67556d98c58ef83f4519d50a6bbc99f71ac7db04c2a72b8b1c81d602d112f1dd28f83f048f4d3dced85b09e1bf0ebcd93c4ea2fe97059f100905ae482650fcce78747472093ba2f1c48bdf478ab64e31409db640541a147f523d882708e9129ae4e31d52cf78de16bdaf0f568a8ef8db3b7e87a0068cb0498357c72917c52f82e38c8a70fdc3f1414a329d8f0cf422bd86ff581341be460edd3d6c24594032cc95361b3f10694a30c3a2c192666ab2cd70a1bc299ddae050f316e4344046162c7237c5cdee94fe880b4e91b265af7106934e285428b380ace2db15c14ccd78e20f052cb59a3aaa55af9fb29a79628404c54a941ffdd2ea93268f7c54d850f9cb1a44b340d6f618e3b215a829681ea24c73c66bc5c64e64c05a07719212d46e12d9d43ac9a2df4dce8ee5caf2c79dba734cb0fc264409848353fcb30a4bbe9fd89c611a5f681a1265f174bb5f75b5dbd3755b6238e6454561fd81db83f6bbb5543c14a87fb745e7c16ab7a2c1a580fa895056e941609430d45865e226738245abdb3212e7c3dbc961ecfd2714fec37c12c3764b7f090e593267a591652af0edc9c6a38ad0b712181af49c359be96ab918eb87187d656272d3c4d67c5ecec4d3dd07e070e721a1792ae4fe488b0fa500454a9b1f330675096f14c0a0a27b0ea186f114904bbb0ac316ef57f2b0cf37b324e90010800a9ef394f7c10d0216c9828607c9ab03aa60b718e168626c04b42ee2826a430ca54e890d20052eb0f5d5cad2daf260b1ec71f5ec28e4ca2a439faf0eb38b1bceaa258b253b052d56d5fe60a737345d914223240fbe5a608fd7ae8e125273aa1f70cb4d5c4547132ec73178c7c3b2b3fb9ee3d2958cea26cd01dcd634f5437345b6165043604aba2f79e3b34da05524d2b2ee8a4c5345cdcd96275359114091158cb895f853d483f8854f1eb9fc43539b3c5ab923f90a578ae85e22ec29616f59fe71632fab2387b3fc6398784141290ee10af575d923cea20ed4251024000b1b54aac25838a027825d50e7cfdd9964928a303079c45624506f91f4125aac14e4bafe14c6c7a2853f53e831eb368eabf7bdd24efdf5b9687fd60b7fac92930690317eab2e0ef63aa8d014e9e1d1a21e4faef3d93ebdf03198b2ad1a89da29fac63c969fed1d0646006b9d0a75ad6d5037b738e3a486d8a20c4c38dc393da4c2630fab40de84b21780057a21fb994051d1223aeede5832793b50999afdc59e44194b1f53411d5731eec26adb65ea6c0630072ecb3666a4de74068916cd4c31de19d83e947dbe0837dd11e4bb2b680eb44669789453ed09e6a5045a650732bdf4cbc0161a304794ad567fafdc55bb7286d3aa5e8cddea0191124e76e8dbd07803a8bdee3e45070616002a1a33e8eada7eb01a9626792f337bcc1d5a2ce874bd066326ad8d584dae68b762dd20fb4fb0f4a055b806aed25c7543f235291f07983f7764462e7c5419af5ee92e592ae7aee7b3c55cf1eb85d48174a600c4ba5859302ca623f38f4c672f000440fa31774c2bb31b2060e952c26ca821d0909ed012dba67ab0535470c1a3637c773fe4f8380554943833ab39b6805f28a4aacbc6c3ed825f7a1d55817090451419bcf45432306d322618cc4abd83e2189c772f295f97f676cd0b6425b58443f2d499714c8fea452b10d6b601e02b422a15842093cfefd30cfd80525232bb2adbcadbe916739851a8430ac5bb3e56dd7aa9a4b549136adab34adf10ed50c4e576abbac0ca7f914b262c4054bd5f9a0fa9d4388e06866c09b9c0de93cef6850b9565b93b17c4e55c85a67d0602dd171d794f33f6f154281db08066dda49f0897a19ca86403e5437b74a5a5ad720c0ad9e8b3c7e30670b2064ea3c7a0275972d0fb0064fbf88b420c723cb4756518baaf1c981f0ca741bea6bb6ccae0110f5e763ad342f1af53126bf1a91e84b8e6e108897cd72ddf9343e3580c7545a9b6841744bfbaf70ee8cde971e33c16fa72816ef4c6a58393e322b287427f0221a825dd626e19828b8cb88fe33e771c2d25b8cb6f7815b790436ffbf3ff9b40686d39afd4385233e6492c66bf726b574ea9292cda9e18004125844404586286187558bdd17019c03bbe4008b5bb82bd9a8c7db4f7c91146614daacb91e7729cea7a778336e2175843456e0b904bbc75201e367791186408223bf50ec67045a58f85fec317815a1a665f9caec15dc5467a1154b9d0c23f458a423841036628512d2a05b4ac23c0d8c26c605b02ae4844c788cb4a5f710b66ccf5ccd854e780621c1fc81d221fd1006689e8f7618d0a9cafbaaf4f7a22addaa77ad1627e2f6439b37bbab198a3f78f02a8c2dac912197cb2fb3d410b90a7e95789a690575545c2ed38edc97df84a428597f845ac6e37c764d87d69ded6f044137d9f32ed7d88914ee87560495f0a14a63e0bd461bff34e3b5f2c847be5347624a95d484b66d601670aa43584ca5989ca3ce137b977a3f7f75eeecdfd77a757d02684561c04edbb2842c169a385e2e228a22cc8a64c65e6077ab6b3f0500ca5c8f3dceb45d9de392b0cd049f9396839cc07f3fb90c9f9a0882dc24ed1da59ce5e1b4d0b3b3932b6ce2ce18b60e4eab33e38cea4deae24951a26a638d5adc837e25785bcde48486906b1a133e2710668f8c5f944859d66f6c16bef5807e3b18d409cdc595819bbaa514f163202771f65acd8a8e3b07045a0d35cb730c86b70dc00729ba785983755dba02b12b14b1d736f75ff24b5e0b3ec83c875ec4b5aa93fd74ca797282675b1dfb7aeebb77052209d7aa8ffc312840b3e0da5ae4c3f2878e0ff8ad7ecd5aabd7193453e4e4c551c89183ee8834685284231d5482a704d2247b483f4089e6a6703abfdcac7fffbce526a2a6b94f599b28aa9ae4b3b98ea688ff0fc4592fb69efa1860a8e92336acd4e594c35c9f6de9152774a3c6a4ec0bb8c68d5c4e72d3029f9c3bcdad77651091320231cb4723806a1d61aa0c740c5bbe9ebbdf83ed02fe4a2cd1093a7ca5afbf386b115f3b473b6904e69538313e93784a700088d61ef70a15faec654d37db98225d89d1e533c39754a1a7a9986025e37a6bae9e332a65a229476ea1d908a05a79181dee486d6c04ae8d6edfd4daedad6f5c672c3be66144e6c0f82d0a3efe1877ef271fe604fa6aff14ef48004da3012e84d8516046b5c820e817e73a3cf1594b612181f5474e8d83e10fc5619d0de6a0eee1ff27b4a38fe81b90c89dc7a9c16de84927380ff9b9db51098733f100f1ab5f167f13f93c47b723757ef9e86dbf23c5543e69578c1c935d2ef33646291faad5ce6719ebd39145cfd9e645ad54e514d30899325f967a3f390a5fda107b10554af671e38e232cddf64fd6ef9b5dcdad35b94847ad5e08ea7e0d067fd86a9602d87b095ffa3db7423cc2cc23eb6543ba6544ffbb0b3935a1091dbfb72db4c44627d644014316b0f66e790a1c3c626d40f8b9bd4542aee14f65f0d4506e1074e5b1e027411bb64fe9536ff785d4ee45044ca14db050614353bc4c1e8c1967f2e9049256c0b83fbe6ede1965cac16e55fb0109a5e01f9fa1d6793cfea9ddbd1d11342dd5b3e45606830faa59f0a1898e8a23f3ab600ea535a751c56a0488c4c3511fd0ee9d117f5e363a4dec51bd3ad00322230d8a81b32472008aafdfb637e5dd6d13d69fcad9033d4ee9e9b1895af07c4b6836ecf7938557b0261eaee7018456e3c65034771356b71b509c6865650b3ee0c4fa2145e33e85e68ee36a394a88afe55d881ca84eeb569f78bebce5fa65b790c6a0ceb5f7376e428c1be88a1f3e4e99a22c05fe22b57386257377ed6ed00399a57ec3b0e42726302b6154ad3e259c4e2d0fbc23bad66f97507d4677e2ba27521e31f8acffde7711ff844bb35df87e25e129190618e698caa10dc2797378fea0d5f1e28a0e8c435cde3d78ca951a87a949861cbd8f11a7522e65d2868d18715dd291c0b74153ce6120c31cb1388d77ccebe66c6bba2213dd3b1dba24cac9b9292aa6b2671ef03cc73c86db2c890b4e0d2ed08cdba7500f5d51481ec5714b3325b9fa4a055584224dbd7cb684af3ff31c4be09bc56fc278c703ea66b233a6c83e19176a0a94d45b71d8b2c69768d033794bc16250f8b9826168dac433cc211c0ec54c017a19f615deb24743e941cd957bd58aba0ba4de34f5f11b2a267688d79cea72f1a2a9f8c92899121f0c2e79abf927ce3444d489c21dce43f9b9dd8c668ca57281fc86f7cb404aa056b59c134640cac835a16f2bc6f1e2a57b85b3f0ab418144581d8289f7ac7ba843aaee17ce3eb1b5d7d55283dade42cbef015ca8e689115d515b332f974f63cc6f8e5e53516ba4bd8b524332831212a709e744551df420de8c17bd110417a1768540dda4b5f00fd7d901115384f5a62882f030dd4a0bde908205d77985874a6e2afafd4a569c00366cff9d116a2bf0837ae02e3454f10e95da0412588376d61941741c634a0fc688aa2be0d195580f7a72580f22acca016b437ad38c2fb70431a507e3485d05e061a54407bd316417815664405ce93ae28ea5ba8013d782f1ac2e85a7029d872786e4c6d23d0d67eb672d8debe76d11a00d552a2a605c3ed074b1efdd621907af8be6149a2df1f065303d103b66cb4abe3e0b5a0fac097477d7504bc1eba1f388208d7c78255c1f7874b14e5fe38e82a98fef0c5d1dc1c00a886db0f963cfaad4320f5f07dc39244bf3f9869a6d2846850688067ac339b663633fa32e7b085ec403fe80d2a52da12dfefdbf2deb76a61c0f385add5169f36b2d61641ff763e34a45b03c88ec3be030b41970f4dbb0f84bf90f93861a2c71915051459a075adaff5f90de9d6fa509ad777c3ab08b7edb2c8213b2b3294fd08007e4c4c0c547a2949788f8460e5f2841bf16f7c0ec9854aacb26c67fe5ff2db5be69e18cbfe0acb1fadf5cfa72ca2727558675931febd57abe660787694f0d51d7dae32e636ae103d819c5613ecc675d89becbbef5f000942a7829e00fdc90291faffee424b7b1c58e17114e83e43524485e91b6154223c669927236029c577e9e78b92ccf93eb90d94b2ecf35e5faabce6944c55a2f4624f7398cc51e449a4f9a4dca5c123bb48961204168d7eabada96a1b63d3de0b7630e6fd9abcb20e48ba4a1af244387a2ae3bc91dfbd96020a144e578974a2a201a23246df2882116977bf9ae2626a8a943f0ee6942cf79da301cd5def3e69b4a0f38c3d733585b8ff9e74a0537d581b02509ef32e7b3f8276a2681f823f086e70a283ad4ba038ceeaf562d252846e26d1ae56df8bfb94634d857a2b04876d401881e5cca837a435f6eca73a9186c23d8ce3039f7b959870163fc2a04e1a9c06390c180bb9bcd3c5c684534cbee689bcc1a6219c1df702f22a920eae99e52812b95cc45f93cb1c35bce291dce59417ca5cc54e5dfb1564f3a0b0c45bd89d9a006f22e2d226ea13fedce424960e8222d9d2ce2f32297664dc5c58c97693d472e238f3f203bdd17fc167476df1b9b7e4fa18d0bbb4e8cdc6af8789978fefbeb42b1913a8667908a96b01bb13f33a5c21433a239504ae84b7f52acda5a3ee530de9595a9f5d857026692b20b64fd812b8e7e2fc94f45dfb0034502bbb98c5e5b3cd487c31abdbc0f1d2ffa99bfb6773fe89d119a3215fd0c7b027915da7de6cb31cd7f62271f906b5aaf70d965cebaa4e92a5d91481ff8f33a49912ab53c06961599fc041507fa965cef36844b8d4a6474f315a0ec7b2fcd3ff0b0eb1dd3e960c9c95031c70ec87a1c6c5704f6de53b7af6ed6e417ac691b87a8bd61b05f6445a5c7a67911b070eccb2648bce161e9f186e0b5172f42a73395eceb67ca45f77de577e02e14150ff3af5d97cf7566201b19b6fd73fc8143a99784588bd8c973b0aecef2c82b99529753bfbda88b1f2b02f9caf9017f746262d9478396f17fe75949f63746fef3c404750c21dc1c3b0a4e5d588a1956d4029a8c2dcefea0f82eb2477848f081316ee7c4e67c0bbb070ff807adf062bbd2926dc86b6ec809c2bf9127c95077c6433cc63e7372ed115503f2ae2d2e07064e21565fedd0517c0bb81b1e4c391415d3b0bbba04b5e22622d0a6845edec84a36b427fe8d8bc3aba90df66660ad63cda63ed655679373035f9a41af6457bd37b46d3183639029c48329856ec5a8770d5850f11feffe999a2ee64a08d4c56dcaff24ed508be81df187517e7bb82171c0e7da04aa0a87dd8c6f913b4302a0f530640ab2e938791b915e05738a0cd48de92cd46b44176450e604eecb467c5e5c1e920f82723414dbc8fd0a25a1d757256f7ec68b0463db10ed2f4049e115febbe2e016e27bcea27a271892bbc36a11be276d23d02c0670ced0b1ff966f3d0a8c3f9450bf53836de3be72207c77285eef44b3d4f1c4be8487b90fc35caf303d72d2b6114f11b033ac6552387f18afca029cd620a1c5693a7b5029f49f4b4cedd84c42f2e7d0b44198ac9ade2f2490fcbca094748adff8822d090f274f71c78d6af874107206c06110cdbae086db4df447c728c2458d5c5695944bc6ba28813883af11d88941de45786a1129d5f8c081e46c14c6da7e7b81c6e8a0c6f966c1faeb21a379be76d05fb36c83a303979843e053f71ad9c0e30d3535a36d0448e21b799754cd776566f838c88981ca71c95d7cebd99c8a66b1968e6ee180aa9a1ad934b1567726bd7a41be8f7521307717693f2ebbc5b7cfd33e60bf575d9596c4ddbdc5f3df154503a4fde7b04cd51d43604c5c90b3a43d121fda04dd694a076d25a39a6eff2998db373e897b9f32d66b8e88180a2020f2d40453e23547bc5ad0da0f2b8ab91cf05254ca41d84f846a11be9923090c0053979157d76466a2b0c6db36e7fecd44c35722a74d3ffb259202a88cb8fc756d0a2f3959e7b862710f6355bbc8493f5e15389854b8859c2e75adae27130aed5bed1582d1e7232ffb6ae9fc500e9599392c9bb2cd19d972461289e515895e0f21d70712464defe3336861e7021c6a3b19f7669303a49b1e429f205c8d766686beb247dc7d336040a388c50f58b5485301deaa8ce01434433d82155f65b55077ec7e4955435360394d2a89d66df3c194dd26fa762e175f8c0c0192f3bb6affa8bc7ed85a2072956281077dabc6252a3ef1320f105c9d233d58b9af31f063ef33417dec66e9ca987f1c0d41e327de77395ffed71867797971d6f8dce9ea7007648758e8965a2ff62b49ccb2115cbbaae2363e234fa584be34e0b408c02a2f0fb1bbf32ee45ea29218fe5f454a34113b64cc409208e6300092921ad1c6583603ae1e1b23d950810804bf64832f4e9b36625a7cf2a65580a1bac2264063a73f4c4d4a613624c41f5c344ebbf22f354492a11c36a9375e59caf9a4341c888dab4ce3a22f35122494d3f246c5c6f5a9f9c73045262ca4c7983e0e9b3c496a44f5d4483b737a88732a0f4943a4261f33d80c680c08b5b1b4ad9a93c1fbb2acb45cd231ec485f9fd47f75887b9b34c1aae848f7b72372c323d0abac754155ce4ecb3a89e66cbdfa01dac56caabd02be573a07d962acbf56df12ebc118dba6e4457795c8d9f6d4fa32ecb04eb80a204053d00695c706b23221a1e977ea4c32ddf36fc3d65b42ee4003201d8bd485bfcc4df1773e310059b5720683f78c3165f79fbca993c433e862e1e3e861a595753fbfe90f09f8eb32cf0f4fb798adcbe8319a6f43d7ff41a1c6ece003c9f4a58e6af64d9f7534d4ec84f99dd19fc327ef69eeeb27886fbb12a632f16bde17a7e2b909abbdfd5aed541c5c5d731464fcfa9ea5993fa89631f73a4f48cbce2a8d01bef42785219d3494fa2ec2b62a2f0149b3ecedd4aa6ebb4fb449c29ab6569d7c840bcf16e3641a5ebddd700f8376d4eb39cd00a0e1e001e36c9de61e73d667f8a3031371b5d996a9ca45a2fefae96c6c07c51ab139cd6729fe4a4a00329bac36deecb2ede44d7f174cb9dd809bd2eb037596becb3a6172b6f5b75c93f2ba0abe6a32c8bdff83eb8451b73b0a6abb0fdaad3e8c6a0e74b01b81dd7e4132a3f45b3675721624b1c570645ec08bb20f484419a5fa030a2a94205395398c4ec656ccefa311d12fc027caf825d514ef62471dd0cd8e5a69253307142be78829ac90e8c247136c35ff38d469fbd83c7dde0bdc262ab5646491b80b46fd69aee80c0c41caa2ff255adb6da28b587e8443a3460a66d21528b032e2984650b28e02d96e83410cbdf2982a981ea97740f986b97f7014679acec15afe8733a3dc46a7a076cf290792266eaaa483d451c4a56b244c014f2174fc50dfac6b32922e645397a30748338447bc3261fa4271a4a937b08422b83f48f0a5e53f0081663d8ef3247ac2b80a2a71588d96f137b9e0a038f43bcbab0350ac55669cf46cb398cdd1aaaa0bb3ca69d2cda86ea905ed1755ee567caf1a2b18dd10da3ec92f9faaa698589c99c47b2962b04ca5c900023b35261bc94870b44c22e7bc685d5ce849d1803c6f4dee993931bc579c06fb0bf01501ccdebf88c9f70f55b17405b51f19d134322989c8c4a25311d6b9b56b861ea4273e0ebe33e78ede4e2e3f019d0d28e9a85f01e531222830738a1633e5d9e667404c1e821132762ce0c0e4ff61424cc644baa55ed3ab9043534b8c95256f169f23afeb1abd293af019bd49307c7d28c6b06a13df2df2a1bf7eda6f28e8481ab0b7f7f27a2e020820a3cc68ce210f2b7da0f28d224d07a5cbe3cd4316d38794403029210665dfc41bb0d0a91e2ec931cbf986f683fcf3248c43b8a0f528e3d3f2551db6fd13932bf4316852daea5b68f974dfd5c8d3576673021f68a58137ac08b0ae51e4860cd50efe4b514dbf2fc0d768c4dc63e3f20f24abca15a5219acf053664404c0377202123f41fda337a65e44f08a44e187885040bf939b86216f9588b5bbb015592ab99195505d630091acfb49a4c223ab6f568e7a6526c256607be37b047f3612165e2bd263d01ca2c58f3624c82909306c83d88e1b9a746e7801d0a61c93833609b5d67616a623e2fb3f1942f1dfaa4257e72cf76e9951f1d19f0ff73a968a9db75e38286436873d2de3741f553007849635bbc12a9a3de82e08cee2a3aff4a390b3d41f569ba73f65143a4b8d0933a8babcc95debc7ae8ed92ac22f3418474019126e73ec191a82f7eb0050457b4e12f5bf2f6dece1f117d82d3614504938205be7fa267f5904080bb3a401ec14a792e5a96c1ddfd4caa2c7fb62fba12e7fa0440f18bfc98bb9ffb7afa0ee25c91b94a4214981ea6879a667a6a76f32b6822cb55501ffdc337fed2d112f6b05b2150c965782a769d57dc65336ec936f8a9fa19649960a40af9579b25647c7d00ee4fa39fa47b08ce71b1ff58929373e4765f1c3f97473afbf5787a8418ebab20d07b7e3b66e02e846d6de4c8c4fbeb3f33fd2e5706a7e4bda599b50f8ec8fa56ecb8fb70047429954a294fa40bd52ae8be6c235406358c19150e636f46ab0609800aeec626c3cb12764e2796f7bd3f7d562a515b46e644f630c82e95843a3e74edac0d7b3eccc4d260154dda70cf6fd3e62549ca080b5d36c07081346c163c2f8fdcadac0fd69c0a6a24b1c316fd0dc968c444f097f622c73c415e4f04b907b649a3a3e85e2adff72811196deaea41331a21ccfd8dee1f23c040161a9d70703dc62b66c34162c956cc57e64ca91cfe238178c228c4e3d292a827a7eda7128a2e4d543d709edd80a27ff4a4a369804ff011844b6ddf2ee68fd909404d3f8a0128079811565949ec339d1a29c0f21f1253d367334d9c48fddda0d1946ce55affbe8d633b9892f7eb844d3860cbb7e634263b8a48c095c489898f7c350fc925576afad88f331ba403b5d4450f1884a2fa46320c88dc9446e8ec260504a689d1ee4a27d05582bd6b8421de4b3bcbbd615aa45a9c8b385e9670b76e3d8bf506d7be8ec35250e314163bc249e907dc20d3f64f070b82c61d15ee3fe96ddd32e4ad9db224b310b7b4041e1096567d37a0d43ce0541b9754e14c3216e7601f3cb61f938fe4cc0dc738630d391a20259e0e38e3b4e2e519cd5be3365aab127c2f41e773063203ee7f626432dd71bee99caf11a0b2cab9aae76830cc11bacb165221e8d52357c47280a3861d55686e6eb361d36e8bed8ac353e796996e9ee723cfa07e2ff97ac937c241ba6223cf71356ea2129e56d4310336767ed72ab47f38a19ecd7d1c55401cfa84d424c08ea84b238a3605f2ae2fbabafea07a6b802650af3795797a179b6cf6c490f4dd334fbf6f1ff082c46601121516f6e0e41969e761ac199df3a6b96100e8a13cfe6ede2e0c965c04038bc89cb24d9ea59fd830fbf5e5b81b392ae4d1467df4162623aa9b97ec12537e97f5583bf93daa214a237813760a422dfbfde31b2f05c298db5d903b6a98dd80fbc6162aca1d3e5a24e3ee87e48fd3dafb18c3c96762e998d1d3e9ef7bfa590c8934f877a579bd36f63c8939f05883d07930bb9f214655219e17a08ccdd74c51c3a5751796b5eddbb9e5e990db8751744a0b374c0f60078714eeb25969cb1b03698b553029e69a9bfa598fb0c3e72efcd2a8c0ed37d63329a282bac239cf79723fcbf1df266cc3cd9b998e900070e76cc3f27ca1cd04a4732b66739379ea753eb638bff1cdfa0c6e3c4325d066dcd9e7ee87035b189ad5d56607d8f2a05fa5cfacd390397e32334745741928d79366a0ca37bcf82fb4ca30047062fdacb8df12e43ebacd8d50b47bf5d4fdae3c3fff93d29ee627d7e7df27ce8ff9dff9e1851f58239d0132b4b200d6c30155832b704826f0f74333780af6a512d2a68db3f4653c308e5763e64ff468e946113038fc96a019c52e20957a9ecded2552eaf45189e34dd43267c2d6a200a715a0a90f1d0cf9f0c933804d39ae17d6d81c703d55480fa4641151e32669bd8859f58cff7f9f477347989ce2722c008e282c75865f67c813acb137081558191cb23cb3195fbc03d2aceca20a6f3e980b927a07c3244fc39f35e07ac0e21cf8f93199ae636fca5e8e59f33e5df97275502f62182193f32357db474e8a7dde3fdb7abc37d84150b8fe416834fdcf7f79a13c79735071f62c79b3900a7791ee07ccaba7efd313b2f0f8c68a3d7461ecc254120a3cd87ac39f1af7cdcb194164311e5ed5b347a4337f82740025623e83c39a7f40c2707aa0488b01624c9e6fd753047d654ded448de981af6b4b3ce19422c67c36a89f21ecdd550d2382e09f1b54658a054f6f48fbfcd2fe497bce4cd25fcc1079c365996fe57e1679f88b6ae09e804b689295c266984d78831c7e05db3498cd121908cbeb44e6afe98dd9bba9d95d745eec00506c9defe1b351188b65b3527dd0c904c9863d16885811d1ec614e9c5c618240eb816ad32ed7aa58f32fd8788155a4e9ecd1748913d98568856e59eb52373b20c35fdbfac3c6c1a3d017ca686f1eb6ec03b867ea38343ee619a15a355870f9bdb99b9879db3fc9af1aac71d1961341b368486226c714e840fdda0d15cc7484ab76637224b05f344d41615a3cb1ecdf08828ef269202bb41157654276095b9ad12978f008a051e8a45d674acac781814043ee4e2b928610ec8da95b1622806d49eaaba21df0197dc8b4cbeffa090dddb07e0534be271726bff6cee095aac05b23877789f2ea9039fa108e19aaed6e458f2f3a7a4aa6368049c8814e3a6145130be0e3a1af494db05a88717898e6f66c4c61701c5e7efd14a148dec7af84b654bc852aeb90505e8c13e2d7cdea1e9d5409fd2baa1357598b1eb039bb39d3a07871cfe4cdbd97254f960fa7247cec93df346fdfda2086e268b48f9dd28e3ba5480319a7a389ba4da40bc926a3c4abd62428eceeb3ff808fb503856b8f345284bc491b15c4ee49f91c314aca86f22a1ab3df4a6f7428fee21fa1fc45edd13ff03ce0c7e1565e8e91f780d1daf3dd32566b5d0ab7873ad7cdf50f5e2e88e44fc0ba1be25f36fc52bca28395c9992b9140a44f09d8e751efce0a074376598c4c0d992e8162a7fcca0ac31245a7cf17574fc9e0e050cc3bad380dc8ca9238b06a77b12bc716c6bee92382f636a02a3896980f731bd7f675230f0a6686f4fd9cd1b23642b4ebad8063e24a4b3276c6f1e9c52cc887872e067f65fe6896508cdc3376ab70a7ec4b359b98d80d08d83064e0cebe7f82e6669d8f47ced4ef9b0b910d085a43036191c001e04fcf7c0bb27a145f879d1406defb465d06c0c7d6974fe656580dee4af0f1fb68587fdc1b87acf0eb6152275f4d8cde3cef08a539332f6e08cd61292b40ce13665be88a44359a215e7db67ed0e5a33402b83dddabfa5f9abd7f6118360cf751e41929265072559322c833c0c8b3faf7fb1f72ad0d574bd595cbd18cd829b8df2cb64478a05f55b437d71fe5f758603b806ca607584dcba3380d37094e8865051827d686f4a1c441e1363cc6febe9cb8a3d3a3fa4e18ba8c4b2a24d5408ae8183d42720bf3ede1c5b9a9587bf676c6d74117ceaace0f812a9517a608d41403d3923c54f76bf7bbe257295a9ec45f45127776f32b6d8e0ed1d75baabcb1e7b39f9773b1acbdaae90603466f881d841048f5709278955039f61e94d0d6252866281543d3108be933dcf4e83bd2c3dc9fc5ab8d27b6f60a5fc638d533ab124df1fc8d2a5d5358c03aacbe127472740370fabab74cac35a8bd308f885b07b78e75ba7360874e9a0b579718a7b9ff8a672f62c2eecd2e8ea57854560c5d1c3f6a3f32ef30dbb6eb12671381632fbf05a326494107f5d541772e16c3e564b8c56df137b25811647361b0e58c15f06110725081146a47b24e98d0ad474f5192147da892fb14f49f8b72ffa9f269cbd221480b78f1b4a88ba9ddbe514e894a3d483179964cc538040235048458a739633937a113f84344a1345e4caa0f3d809fd761f38d735e730c4016638999d7ab83fb323dbb585a1bb8e135e6187af1f3048657378c7bf4aa6fc0718f6f418aece1b547d7b0996661c0e931cba11003f5f6de23bdda47236256ec353d2656e7456a679ec3f0124d727b2b76fd3bb9aeae1d806c906200fe4f44f8fcb8734d73232cbbec82d5a9b302968d4a00916ab79633893b98f683accd9a793c229dd82fff90ae22670327a5aac860e2fa0b511d9e43768cb3d089c93b2dbb21b7eb9031c858f54632a3b41736786e18f7dbb787d3bce76c9e4cf336323a6885b1f313dba10e0761bcdd77e9808c3498bdd3824823b9b54ebc8708b6b1c64cf60edb6d119b559855c377e481b53a337a0df4ec1fd81f2b850804d93a14bb7b4ba8ad21824320c9e6916fb66cb2f6e709c438f0e1527ef3a7293b1d128b29934a89b44251b9c0e2cb3791277a6f3ae492b2b2475bbf8d73eb4d79328a905ae6a0477706a1c31812fd6b7a60d1472e1206f16b3af8116ee835b396c8c8c4f07895acd122847a14f5238567be260e724f9b9271e43be01d466605360b0512678e0d66dd3129b840c315c888c7f79d2ed9127e371b856d447a06121bb508dbda05d4457cdf3b1d8453914a3019486678e1eb4aed57b76b5198a6e80c2b78ac1c00defe3b8b61b256ffcb9980dfedf40df8f58b054f556e181584b016691aeac443a793923be7786e944637b8a3700dfa2134e0ee38600b0325cc61de902cb67c63cbbc77f79e6557be54121c3cf16e34738a5b87428fb84994ceb99ba9c7cde689983affacc181d817fcf5663cfdd68531944379ed7365c1d452f51fcd0734778f0296f0a74ee3dc4a78bca0bb6eaf91cb51f48a19dd26aa8be155f3f9fe29c58bef0f0c5bc84e98b71501506b77112b6d0103cbffd766e1a06cc1656ef9dfc5dee5fe559a88d81025c05149a80a92943670200162cc7b112d2a8f985ef615c931baead7aa0e024c68b73a17c4faba88d876f39ac986e0e0307f97842c9451854abddb45c9f36e1c350d15850fefd2c0aea60e474b0dc45090b8de8a04cb8395f317b8141f95c7dccadc25ca393c11f700672ae4394bd11f94618dfe57f9880f0a8fc5d0613ee512e8e905a650d1844f01b0cede3270edfc5baa1a186f4c440090c12392f053ba4f4812d2dbe6d7b59d856be9edc49d7f987f4c3d7c0769ac6fc53143d921a0d9ec8cc21bbfbc7901cc10c87c0e89526432cf33c94ccd611381e5519bf53eeb652509081b70cb03205798dce123ee8be19f7187840e63bd9783210bebfbdcf3a98e4af4a848e94577e1f523f56e715db32ca3f84f73ab67d4fce5fe85d7f139f031d4d72b73697b54265f9608a8ed2f7aefe6813d48c0135dc2a4674abc8f5ec443cb318ab16d3e8d34b262b0722e17d04ede7922fafc079751a996fe11833d7ea6b7027f1e05caf6beb6b389a5b0978c628d735394bf6063c05e6b9f0b3b2e1a58c288c70022eb583c57e4aab21c6f9c85d5560cc9c871438d954284ffb7262946c9d2b1a3ea0ad8733500eca192afce5e3773998e90dbb32182e028e51bfd39a45869f039fc13ce785f369167e015debc87fceb953ce2b274a006382a4079b305566b2c0a760b0073ce4213dbb524a9a3ba31465c70b370a0c3bde36423f52ac569cdd65e849e87b1389abf55781e28f39fb840ec20acbabd598695816b7f685f69da2e31d1c84a71e5280846c631e10c58f5e9370401f66186585d222b29f5d16c03aa3e25943b5ade18bfb5d426f092666442b5cc667cfc7afce56428cf18e09045584321134f0836ed9d8f16b86ea4a8025ca03bb88a651a4db115bf8a1fe8cc4620afe6ec876190d03e9cfac4906bebcb1a1709d790e58c0464bc58e6c00d4d4d0af45854d27eeaaab1bd6155eb8a61c5c8b567a6aeac7bcc9f51fcb78f5f557ede49c2e1c975d0900fb765b1cc34766b57bed2ed62796a739cab2087373cfd294496e47e08172730484ffb7b311cef8c052002fb3e1e3fd7916fcf1c71c84d80bde90f9c9dfeb561740a6942ad07696cf493d2439aff57d965edf5445b5d4ff5b91d27c921c9ef43dd2c551ce177c2009f9e8e13dd60f6e3006f12604b1848889700876f554d1e4e05a35831f23111e4af99c5df9b86b2e12bc00ec492200c49d55dd8965f5046e11012cf4de2d04cd0ec5c434ba9e9ec54880e19a1a7dfcda60441330c6f5ae808abc31fa8090a5337d1963a702b2f05dbb1cd6f3c113ae1ad80418ba2aee7e7bc84ab2529086060174396c52d528701772134f2c7b11c5a0bf4442aec1c519b2973df1e0ea03560ed7fcc890a63b80d6c37a4aa9c25ef992aaaeef10f5d4bb2b2913c8be50c672eaa76b44dc027e12f8f5e843c5f87cf3c549f21107c4e099010c4d65c23fc3411ee60deeda70acb6232332a57a0b3089caded172a7b3620d3df238f3bb231870b07944770959f1563aba25e0fee8294a32a97b2bec626a4ca0af211d6909225f5de30bc85ffa42f69edb796b7c42b7a395516aa46eb041168240da7449092b40126bcb476765d396f314703b1fcf566f5936f04b8eb2f7ab875556e090351987408eb135356df93635df1445a88044dcc4e44a113e96aeb15e33e06d6fb8b8c061476ce2660fb2459c2dda359f2e9a5b10e35d6759445a6d8ce9a05a968ef4fca0b80d566c5b6ebb1f05d2d062134e580869a7547823b942d1880855d9309b9cfb44e7a18214e3c8b146b8798d482adc9067114fe44acd7f371f110f171a8af84edf752a7cb2c1078b9a5c3da88d61c5067a5c10d184db88a86eea8c35e7b67ed37066aedb381f5be0cf062f062979c266c9fa38621959e10fc3c7fc5fe68cef5a36b4b199d3dcb822f6718fd9ada460c5cbf243d5646d8a172f7e128ec863eb2fd7cda18dc5a88625c23c5d7384ad6ea08bf73b8c8feee0b02e547c3962f832d28de0ce6910a187d92fa6a7d7384ba94937cb6536ee5da1e0f0f88c1a339d203e6d4555021cd23cbac0d1c5ff2811fed4d930ee5c701f75fa8a6ab4472771adcc754dba223a7fb155adb61d658c629d667c9d365bab5f6ccb8c38ea8886c473900fc9fcbed878fbb16a42b7e9084dc2b9c4ab401defbbf142399ea7d55d3f8f137fe3ca836da7306ba58a6afee899f7492e10c00d831cbda89a26344dd3129f0ef61c71237ffc4ddb9f693820aa0e1e57f94e2ce04b09704fbd86ad1a6b3894f2996c7f7f14dc9acd09712f378f3e9f9b77c58c2d0d168e03dbe20ed31d1c83870fb25b7ca89500a4ceda9090bf3cd5dc1154e63fc13fac5c679d29b546d88d3103dca41e0181d4ecf6756c0913495392b91c9d5e71779fad639f5d9e7d2055dce93fe9028875f5db488d974d1a895f4b830bc74a0e6561dd69c8b9a2cd61dfe856b5fd6d4cee6b9ab48c2ad35171b086d2ddda1c340057fb906dd24c48e47dde8dc183dfbb411b7f481ff7471cde3937e1b86356548aa9be8fb58b1e26e57dccfa69c76c9aac9a46af4532f383986f7c365f2b8b54daf0846cb03be443c3a75565c259eaf987d0394d43323c2378cdb95867776b0819f9347a91a9d4bb70b03d2a7db9891b2e037bba070309c85d87259d00d159cbeaf8429c0457663475806210aefce9a6b83e30e045fa604e8a50ac6893c309ffca18ca46fbb01fbfa63a3de7ceef753ccdd2ee1b8ba81ae2c65f40481f608f514791024ed2a34981c98ba8a6922443de956ac762a9b78a208b46b94f6cdd504b3e92e657f0f33faeb7e0991448adb1f3199e1a7a3f7a71e1eae5c113007f35c0a0ace6efcfd398452e6788b3c9edb377bf72ab34ce758870702a5092ef602abddce6f8468c1a30a1203dcc04d646958add2ce17b8f96ed6527350901d5b1153e7f355f8c220a3dd498fc543437715530c4c3e4a6dd83214f01d2dca1d89950ae148a174ffe96b3dd6a228a14658f941065dd156c7c32dd46b6b571c62887bc6fd68e44c27b7645352a90f3c90b8d741ad0f6e12d27e5b8a0088607d77cf5335099ef5239b211d994f64457b8b892f3b1479ac80bfad0450d7ff52008f3bd3c5ff666a46d3fe93631264dc52d66b957a49e90e3ad35c29689e73f6fc7ee40953c1e2cd39f48bcad18ff06ab212b0c78f8da72fc6f513be9d4bffb70fc44f5c6c0b0b2dd4f17423c65fe0ccd67956da1129e0be2c515728283df3a5d3f3a47189ea67ca08a057b9f886172f4c1828a02f840d2b9f53ab3d7578db8760e7c9324c0f91bd743b8043fe6ddfb0b265278e8ce9d8b1a1d1c5da89763b7534db866dd91d35721c24346c81d3b2f35311f4095ea140286631b75bfae1f1e67c2c8b6be4c02e2a4e378e45516ca07eccf8482237cb10750083758b9ab5f9755bd3a2b09762d3c9069e74f5047ee063708fe0095651f671e3087092e173f59154afecb3489566d8e7296349e856d029808ca50af815ce6c022db8aba614d277693e92bce94519ba2bb60516871228779ecb4b441f7549246cf7c0546ac352b9e6a001930cb1080dafb4c763b88e42f662f2b8456b95c7f803d1da651ec846954c2103c57ba5b58442cd4525ea91fee57016288536d0a049b1616bcf1257f6e250617232d5a7b9f81c0c8f794acd86fd1a5e94fbf012f7ca4a4e3743de32d03e58bdd9e0b49c939e113faa5973fdeb4c866512b3f8d3fb1f571c1780f78cf77a03e9a3d5af54e43feada9140bd50baa5a20d317937641ab5c7bda51b21db63d10239415ee4be01be49c06bf2ef289a04908472564687252cbe33051e990c015f73c2855313fcdea88b06d09768b123a557633d4614426f57d64089741986b40f0ebcee63982ee3eec0669b6173a608381544ea48614330d1e588da88f05b0b40a7fe4277d146600dad0cf42676c1651a6f00795fb44154898e244492d223d446ea1ad45c07c8a5f6a7ab9086ad587096cd9da9da0eea252b0213fe65e6d1799be09467f8009f23378362e94a9804444dc625689b5742c86c478be45a1c0fdeb2f6ecd85408499e133bc4df8912ead8567a9d6bc59e11cb7559e8aec90ea32270f8c373300ff297deed3c204ec96f46896a50895258e4a078e5c9f5bb597e838cb25aa0f18dca9f9276aea7039e3141a6493928dc09c548f76180f259d101526d1647084083351d000069439a05e6f5463bcf48e085d9930efa171845802e16a80982e2f9361d87d35b3f538ce9484df8a83ed47162f19c11a34154fcaed508a1cd21c8286e69ffdb99aff3231adc51f40d0b2d680662a5596af1dfe699a5af08758bc963cfa25a892f818edfe1847013be6582913fc9354636c62ad92d1925462fedc9618f644a91face23174bd24571b6aaed6674edf53927f64b19b50df224fb4948f66eb3f9689a86e156661da9091d67221e25564d52471996f5a82b356ae695df63ee25cd042bd6c16071f1d7323154a032f266dacaee5bef27ca962bd06c568980872aba91e30fa5ab96253ad55c0337f4b09b676806c18ae762d72bc5220ed9e4a1693d1ce45e834702c61c3f4598728a37dd61f587ecb1fdff3fb4b9d94c19ffdd8ba2f7c58eb216e7abd9565521c51139704164b7fcd2221e6637958ae9dc48a1f14397e53245495e7f6983e266f57f5b742e1a143556262714e6a0abb1b096ebf31fb13e8804dbd65ecab3459f32af96a3ac5614d07297bc940be21851d8e29063c4d8de44559bd7a59d4d628f1b2090b35f44e3a39e4ccf00bb524641c8600f04b757c5194de1682a324bb1c4e65eead49631690275aa87c6b8863a609b43aa009a142673d89acb47d441196a84a96ddac3587f5fd50a0916b315cf5e121919e2632c52af612b9ea17741e4201bc20db83af72fac1699db3e9dc12082f033f160f9937e9b8d6ad012b72348672a789d590daefbd7acc98b2de9dde94b71363cf28144a74083c4fa5233fcf5ce2bc7952426e69e3fd657c3e4971d6af89cbef654ac2af40bea2f857bc69e9704d465a8c79068f81f08e0aa68b1bf6910942a1b9fe9c211eb6e05f92625cf622080e6e08359cfab51573b8227b9abdded2a15319f5659539d8f1b367b7a7f9ae9d71411a01b19f359f51f279b845a3a2efdcb47cf3f29d00f9dc8d5cad98fe7ab31dcc47a1673b996f79e693c5694b2d198352d355258794593ed27dfe0a4f84f30ed9f671239c422be3129fd8820b4760115ab407683a107e82aff93c610f5d408720e746b7ce7c01c46d4198c344761e7801983eb8f0306c2a01f8ae9f1ec8e7c98b6b0cca1295553d0e345ca619c1a47278c4fd6aadf4e8afdce82b38ecc09decb4cf5bfcb91c5cba5f180c262fdc0d9e104526ac347aa0f97199f448cca9439a2ac17b16a2bfae8831bc1dc092e639e83dc2dbf02524f85a54c29756c38fca3f5ef70d60a7b9388037bf0cc0b9e7f9c506b731c45cbca03150c42125cfd3efc9306495c6a1f6282700d90d1b522970618054c488e1e557bc12e0d424b1873aceecff6adb7c0884776809538fec725a213593e49b7b3daff92ca2098dc01551d5dfde84f19d1ed4124ad2405f9148118e6b79ae06a84862a7f1fcaca96f63745253b336dbaebaac6af7df82513c98a6f487af75fd917c0cf6a4d71dd981f6e8ee2ab0ae9f6ba7de71cd5c8763cc97e5718a1d868e995fa871ade9f73a8438265692bc4c38a84f37db3a4ab88db9b1879afd38976d039c5f7236d7214dde89f25f9f9ca3acf4d20ac6c28153330990464efab42e376c7501624c5ebc121b703357a75041b05fe8c106976e4b24d0283939e8c499c13efc9de1812152508aff826467f41eaee6edc9dbe241da7a6dc55a690395370346189e1caf40a6407eefe1888d26e85ec689e9711b84e526420bc34c4a6e5cc4439d241b08f4885aad8044852e8c7af9f4152c0c51c2c26d9ef78a4e610863254c5ec9ffe3a0eb87f0db36cbc29250fe21e663c4bf7a65501d5a87c3fe479efc59dcee10b6bbf3f7d1b061c177a369b4c7e4b7509badd6fbbf95078eddc24e70f3e38730d99922729f94698407ff5d0f81ec30be38d52f267600aa3e3842f88a9772c8ce80a30fe0fd340dfcbf1be48c77412de8108909890ee2a3203da5a0d1d76bb0c7d07ac3e96f23bfdd0f78c727fcdbc383185c9d2691f189e5e96aeafa6e0fb19beaf23f88b0d2e49136dee1e6545f356c4a09e08d8a24d4416a6674b5e2c4b505ef7959810f761a087c08855ae84e929d2a78e154ed7caf7b560a0193d07928037f2e805416ff8db750d9863b34cfed27ae487390213511782b2bc36aecafd54809c33e7403d43fd529dddfc1e8c51f265d375fb1a7cad0c49cb3552aebc890e7ecf2a1bcd125a5efca0e2b1ac5e48ec39c4e93f9cef41782f4a3bf130a31af707a73ca623cf0229054bbedd7dae6d714ffc8207fb4b90fcd2974ef3ae411c4c8e5036e94e0e2901bb32a224324de569b67ad73f1dbdecf22057c3310bd6f14473c95ff9beffea3f83044358689ea3b1c53da074dbbfcb6b857f1a18b955f12846b807e1a1eed9b6d806957ebbdc0a260d2f61bd56ec0ef0fe52f56ebb1d917a8fe125ada1d1d3325ff149309757df984fa899263c00b64ed1dbd1c904fb705c1eeb0c68a0c45f833e82eb67975b3821f6befeb7af5d4b1939b8b7343e1d9ae2ebdf0a929168913c418c08e66fa52d9180d4dca8ba98c0e421e7a866bacb412fff970a8ef31e7de7c0aebf214a6084793d93d6d1b398096ec8e3d5baded21d0f969a12ec77c59287d7d2cb66471dc786a37d5fde2e0a21f2464d411663f3468f586c3cf2139dc7e084f0961bc8e94ed23edc3d3a36df3d3377cf38777e466dbe0fd559deb65b7edd36a3ccad1cdf9b78f4948686b288e2741649ed831acf413a31c7a1811d73fd91432087af48158a7db8cea573434d552db9117a6c772826e967847aa13e7910c82f4cacc608ce0feaa20691658fc7e73bd4fcdfddcb9d705bbe504c2e0d9a0a909cc94f8b736f561cb5c0972130f5067496090cba0af3f99e34682237db96e3157022ad1f37e596f96478054d9362829e6200f58ef7ebbb35a5c6de20ce535a1cf68ca131e786ea9a9230dcf29fd3dd178dea6fa93cce8ef4b376debbbcf8fd2a44c3895a8baf46276fcb2986128853d0efbf9393a03ccd35b2ab3d23c9ff3d30fb6a08e4868e498796a0e0ae90e84bf60d7c1ec4e476edeedc0d488d2f0c797d11cbab70898539ce3e3714ad22a744d0d8607b8a181c5ba1df236cfdb66bf476e6baec0d73fcddc247ac66fc7fad4cd319156d631da819e0b500c08c820a67a75c06f83d278c78903dc062366c13eddc396f2c4f9362833998c984098d34dad2067afeb145a4825c66a231d62734b536c8b07364ff21c2652c52e5f6a4fd51115ac997106013957973e963768a6ab4abc46dda9d85d09618518bd5a716f4f175f25295dd7a86b5afa46bd94c0b4db7d0022497c97cfcbb7c84002d7be594045f8fa993d61e8caaee96976fd866509d6d62167c1eebcba46e0fcf2a6c56f80e79ac936580909b042670a486b3030922cf0644b5f078c8fe10a3da684c10a20483827aab3194aa52fdc4b33e1f411726e260c5d5b52e4eb5d87f7e426c2d7a033604b52d5e76a3da8f7633ebbe89ea124239e8db643faed0d47a99141456b0334de3de1b01f7e11524a592b100f5cfca0e8cafd98a3be733f26d78dead8cd745669e73954aa96ce1aab68343b147a32b462679b48684ed91c108f0206f3889bbe02b80f0dfcb9e98e24115e5088dee92996ff59484d430c7144c974d5c23239323a00b11f8856b94161b1c0357139109e622d74ff6b2e87f9c23d9836f790cc941d35e90adfd0b986baafd46b904addf415698b3d3328ba6b433f385b7cec8ec25a2a3aa5df521c57f23d3f2c0bdc0c214edc5c30f1548f4daac3fc911715de535769613d44925db6b6b184f69e80c69c7998299c33e956ae65d6f282f3f7b78c44341fc2a390ae2bb994f32b21096729ce4cfbde6e3fa3df21fb35ef32e8f61a90b717eb06116386a75f548e60e2e9adac622a8b3efdc5e3229a490a79ac11da680568b90dd7a76c552cb9576db01000e1f1de4ab8943e5019701e58e386a1595d6e0c622a172de139de3e31a7c917b80932e7972824b30cd0393e6979b7b262f5f7f00dc6cd6a55a7a54975360d0a3dbb8d9f51ef0e513f64909c954ebdfaf0827a8fe902fa2759e0aecfb6365246cf12ab6d429f7d2ea1ffefcdd4453a795357d01a6a6090cc655c113a0b72d5fb4bd81e809535766982211328b5cb6d88a965ad11653c2c6ff9d3571b5ddd52e49f9d0928dde297e955e1ff95c9b8f505aa3b3adc4e0a1b761079c21d6dc36dc735f2b17c34cb796d07a58032e78cfce482042bf482f221e1ea08c7c6dea38ba874e71af46a817901ddc47c7133b85ae1195d6e6b55c1f516b9ea73f097585b3e7bb2c838d99a13305988a2fd263cc38c928bf28fcd0c12d736e95acfb97e8759f4032c7a59ff4f6463d99f1b78b8e1494b654a6b955f3644efb3b1d5db804ad6ceaadbfbd7f62c9cf2b46b74f687f492caf04a7dc35bd5bacbe13e3a3ad69aec452206482194b8b6abd3c53245cc8fb3a7843d2a797e75b08e2b0841550cc42e35c5b158031cd565f262f04e2d34848338a15b125df14e65c8205a2d345decce325f3232ac2fa97558cd9c0f54527029c1e4cfc789b663283d220d18c6131973d2c19d694c455c1ea138c68ea66b1bdadd1be444335806f0095cef14436bd33da927803eb686cc436084907a543160e64087238fe012c65441620c5a2c37e6f2ef7185d8afc4e2b58f7b68b1874b8e38c9fc520aa418059d8187cdd2c87d1e9897e454723ac7c79114572637fca69505bd1747d45f11d1eb0c4b7954b02275d70af43a3c97b4090e54d76a793d737b8d315a2c713c671b507232eed34c52968823cebd6ddff8e6251f4e496d6c3952b0f413afdd41255581c75f8201228fa84c3086d5d04d7ffda3791e7dda873841001a445cd70d3aecad119f7ea7d8f638d15c52caa33b4294eb9bf9b1b41482eecfead7727cd234c27551260c545e649a1c47b62343f003cd3377b86e59313acba1b1560548dee43dd081d8a1d12ecd76c9ea461e291f1d776806c5f52f9c96831ee7be85637d1d280614f436e0d0c05ccac57f8b0277c622a98569c5af1764ceffb69911b68d058f0301c1182b2ad76f9555d0347c642e6ed38b0bcddf788e15d13fc8126ac0308cfc6cc2573bdc3535b6ae306ea86c88fe9c92084007ba4e75724fec26ee1f5d21f9eb44b7911e494dc5a3bc9705d37010eb571de5510b27dd0804a73072e94714a9e0218c70e9c7569f0d95f901fafd7e843720f034c301ffffffffffff7f0cc48c58bf3632a2eda1a699d6ac4c2949a372c086f11d966c000552ca24654a49e62957dd80f6ee96ae01e807c8073108ca315e2b99a2f92bd428d37527949c881a9443a514cda1a3ab13e351d6ec3d0d26291a6a67fd5fcef88d7aa88ca23d6ef72eb7185a4ec4c9101551b4b79e2e2f5fb5f2e8722dd0a022202aa168fb895337ad54dffea3c1cd22a2028aa6ccb1b58992312dc6aa4147543ed1969f2a44bffcfaccb6e289f6a9cceb20c78d483194c96432994ca20631d312954e34ec54d5dabb6b4f5237a970a2a5b75cb35bbb89d1b3947013ed29a5ebd19df5fc6ab9269aa242feed72114aa87731134df7ace4903e63eb351d134dadaf951899e57a847b89f6d82df79eff31d6de8ee0a858a2b123567f1e333db2b395688ccf35224cd7e7e54ae90c4a34b490db47aed951fd269b4463dbab5875d9ca4f0f9724fe5feee22aef3c2912ed3cb60929c4542931d25c9068aeaf1979933be818f24734e698f9ad58a655b75e1dd17a2d5cafcfda95bbd06a4473efb53f65cd0f293d8c68ec0a1be93fafd5ce5d44cb5ec9a964552c194245348650f32ce608a5ca84540b9544b4e48b3bd963c54a7923a2b967cc3e5fbe6228d7a143347d8abbcbddfac556ad3243c5106ddd959e663c4af51d2fcd33540ad198f924ae773d7ff81309d1bc3f35bd93d05a285406d1d05bc8215c5c8c561913445b2f7122b60817da558c422510addfebf3561dfcdff35e2693c99c2a5400d19c9da6d4a7362957ebffd0563354f8dc3fca648850f1434b57fe4e2276769872f5a125e2bb743d4f395c4d3e34d6d47b9e7a67ca8e72898dca1e9a6ffbaefb879c6636d243c3c5f419fb3fc70ec3cc4353d49792f5f7f2c4bdd0152a78688bbdb2576e7c0b11728c0b953bb4e39c91eb727bf6bfdf0e4db9d3fb84d699d53a47c707d6a1fdd9e39e3bccff1172d2f1a163e9d0fa353efa5f9cab5c2aeb42650ecda9e7983f4fafffe959c1878e0f157c9431c6c7a654e4d054256b6f75b67237a5508983e663aa5f3d6219a54114342a7068e8f5e3f354fb422eb7dfd0d259e6f47a106baf5c288fc29f6e686be559ca54664afade6632990ca266a1d28696ce4174df8b9f63769a0d0dadc5acd5bab3b9ee5d26a3c1fe33900e9535b4f66fdee59bca4e3eaf412693c968709109a2a286a616fa93cff9483f114b62a8a4a1bd5c96562d55e7a91d56d0d0ceee619a142fcd930ecfd0dce2d4baef5862ad0ecda07af47bfd59552354cad05a33172557878e502143c3dff44911dac4fafb9e501943dbcdf59eb3977d10dbb3e2a888a1317be752e62ee5b7ba6168edf6d17f157726b360a880a11de7fe8c16fb7d140629238dca175a22fc55fc98e7f95f9ac9b851f142d35f8fd473d713d966171a43eb385d4aff53f36f850bcdd7c3f3d84bcf4b83abac50d942637ee95562a99a14ee217911cda6315d50d1424bdeea50359f54be5e67a129e5bf10b244e65ca5ae60a1b5722a938f5babee5555aed0fed77f3ea5ef1222a3a0628576fcdf9db79e1fb474a574a5c12154aad05a29778b10528b37f57de8f8d02d54a8d0f2fc7bcae850be560fd120a6a0328596e8752fc44c0625a5d012dbc47ee17a4f676bfd0e859b6f412693c924132a5168ea97a6768f9ce23d672b5068ca9ea584cb1d6ee416c6d13ae1539f50b2e798da4649e361f046e5094dd7fab273ea507f1582a0b00b3e747c90f16183313ef250714253cb2badfbbab316215681a3e16aa56b31b64ee379ef43c7c7878e0f86245179a3e9798c9737f52b6e34ef644e35b53f84d6532c549ad03295faba2f5ab99e2a962a4c68e8c7fb24b7d23f7fff1f3a3e747c8888b08e0f1d1f2af8b0c1181f37c86412f6a1d246636f536ae66aad656f1d8a6ea8b0d11ced7b4efc2a11a943200a3729236b931203923052658d9610ba56c85abddd691d090141c99c7190199525b4a79053ce4ea52a667e4014ee7b1a8cfc468c0e59a6464509ed254dc692a1557e92aafa4125090da93dfbf4f57a5d8927ed5041423b2e93971d335751a3e97e7aacedf8b863cb4921c72f9a3bb51272eb555be161be68fad6dbff84242fd27f8686f5a22db61a7d9f62a6ed3ac5908317edbc74de3b4fef51a26365c8b18b86de5ba7d1e1b37ab1755d34477ed2618b21a44b19e5a269224e8f9ad23dd793b8680edd17d3a2a2e2f5e7162d296cccd5ea3d86d66358c8618b7656931ecda328d3517bb231c9518b76dc7bc632975be99db468d1322587bad837fbd5dd1cb368ae13eb5efa899cfb3873460e593445493956b83657f79f5834c71c428cb8eadc952922430e58b43ce7f5d3ab45ced139200a197a456b6dccc484d217612257b44fecaad16a7547b6dc8af6e85bcf5abfa8df51654553c649977ac2c49716ea428e55344d8c9b12221d3aca18e303a52a9a3bf777f2ed6fb69e6f21472a1a7a86362553a5de25e435d83572a0a2e15a8a29537a9431ff2318729ca22956fde408bd4b75d02487299a4247f5e357db9dab5f8e52b497362dc73eb127456bb58bbc9e9215fabb51b47ff5ff5d9b10bbc204a216fbcfd0307288a2a55cacd5696594acdf812844319ce43768346f234728da627e946a2ec68ab9b59adf3022281a43a9ddf9856ca15a7f4a36e713eda1f4b38cadf53c6831132f19d90d49c80d7684acc0136d79b17378b922774d6a61926186468c1c9d68eed923eee4efd272ad34289b901d21ae799490206c425ca6529a91149203831c9c68ab917b0fa5caf75ea936d1982ee67e173bfaee92324db4758c5929f57feadb7de1097264a2ed635676de41c8b2137de44d42688089a6be5442e4961e4ede89416aa0725ca2b17eb8d4a67684eeb9dfa094e8184347cb6450342367fc612387259ac2458735533e6cb7398c4c9de9a072842e7d3a88c29489162534454bd15ba808357b692d4968ab582bcec45f4868eb1cde7312f52e3dcf59d468f95ebd72879ff5f5a00f3c7ed1503fbeda95fab8b71802c1c3172dad97342543a7cc195926c33c7ad116a34c8569314a76ee40d488072fdaaf3e6bb658e65ba40ba2704964a0434444051f3a3e3e747c6cd0f80d49898e0f1d1f0d1d4c1ebb68ea77a93fc9d15b969451e0a18b96feac6d5ec8d455e5a2b1e5e5101ed53eeab0d2e8325cb4b59c62ce3b37d769e646f0b8454b67bf0f3b17b245f3f3cb99eab4127a67ae16ed60b69f74e68e53ebd378d0a2a9c4aaac5342af8c313e1ae1318bc60eb2858a5495f6af97453b2ad39f1d11d3e787d88945db74d855253dfcca3d04a2525318143c60d1501d42af1b25c689c8af68df0965fa950ee37dbc5ca198a7071ead68c7e92fb4dfd9ffd69315ed3175ebb95ce279791479e0b18ae6ce519dd621738a1d8554d1fcd35b788e7b8a913a4b453bfe9219629e5f7e77a868ee295733a6f43cabd553344e4dcccab21da5b4cf146d597a5ee7af18718f97a23d5be8f16722468aa69b8d2e21eb7c6f1d8ea239f6b3beaa5369e73351b4676cd923d7afc853ae50b4564cfee8d98876cf01454bb4ccedcb1d7cefd181281d7b3ed19c31c69bced5bdb3f879a2b56742a8785b3bd1d091eb37af5c071d7d8c13adbdf1a9b754bd3e29e5269a3b4eea999e5aff949187269a2e42e9b77171fa1d713414cbf0c8446bf79d6b6daf66a5ce4c3c30d19ef9d57b4ed5a2b516c9304383038f4b3495c83a7d263a200a53eec0c3126d9f5afb6a397399d76fe05189869d1c42c48e5a9706e97b50a2e1e1b5944b444f93639543f0984453ea7cbbc5e3e9fcbbb7564ae2163c24d1d4edfbfe4ac84cfd798f483485566e6af6c8bb9eeba581c30312ad99950f737ac594df23da4b2cd521eaa675c59d4ff070444b647e8a2173b998d86a44dbec54ce2c5533a239c6c8df292a94f0255c44cbc5f224d647ad229aee71be927ba2a492ae0f1d1f71f0484473d5aa1d66e27a20a22133727a9c7c8dc1e3108de5737c97967aabe72893314473ecfc4b69b6bf7bcc0bd152d27dd528bd546f77cd8307211ab7f2e5a3969ee7ebd920daa62a7dd5e46a97a12488b6e821d7aa9b05a2ad841a5f313beff94a5f49c98989e2879c6c342628ca03102ddd7ae7b8d457c44eab3fb4a4d9bd963d668fddb61fda51ee5822facb3e344d55ca4f29b7791c3b7c688f0eb5db5127c79c4b7b68cdd0dbf7721163e5f8aee0a187968aee29b3746ba1fec483471e9a6b7492e233c7bd125a8b1ee18187d67bf0bc84cb3435d33bb4b7ec2476cba8d03dd10ecda1f7a7187bfed4bb3a0a8be86056f0a843ebe447472d4cb4cfb87468fc7cd86ad4468e3533cea12dc57e1d4c5d8c7d5acf0d0f39345fa55c22bee4ce2daa3978c4a1754acc0e7b74fe7a13bee10187961869be8358afcbd39ac920c1e30d8d8f663b951c5bd37b74c1878e8f167ce8f80843c7070b3e7438c1c30dedcfa3f6c5cc74d9596e434bf9da937ef33968719eb44c864f3ec4830ded71ab3f0eb1b3ce5b96d6d0d0a23d880e5731df6f26a3c1c43078a821bd79d3b6ef5a99ccc6e19186a6693dd78c9e3b9ee336d3282123a80d1e0ccfda949e31b4f40c6d2973ab9de1a6e4abb4081e666898d4eb63cc7ecad014638ec8e9b23bbb3e191ab722dab31642094f3a1a1e6368889343eedd3a08a55e2b86b64e3e871aa5fee4d71e86963ce139fac8377162bac0d078f939c8fa6cca5d67b1c1e30b6dd1a2f74e7df5eb9fb767f0f04263a81c52daa999438e13f38247175ac29796eb759c53efa532c1830bcd91a16d94cc2146add216da9e77984399ec2d775c0bedf89ed7b316e64a0a7d16da61ea93e2edc5f0b0d41f3618e3e390c1030b4db52eb4ead97ba1bc42533e675935bd448eb7d30e1e5668af12cf4a8f76a5e330abd0d2bb7ccb6e79df39ab1e5468ee7df2c534254f6c29b68345c28882c7149afab7f21d67f81cb54b52684b513aa98fda835e9db22a7844a139438bcf5b09f52ce78c0c333447f080426b6c5f1b47cba39e628e176bdce509a5783ca1a546673d2fe4dbe96725c1c3096dd1ef4a75b6fd51f9b7e10147cbf74d67be9a29fe4b6fb4b3dca6845efb618c0ba12678b8d114e25ada0abd647fd29bd0d46b879842bfd6611ec58476d8257227d1974aee581beddf59f62fa9f4adabcf838df694f24f558adca7c4d4f058a3fd224ce7e37d8e539896d0d4fd79a47813931f55424b8f35dba97bfc6f259684b64c1f4b3faae9ce3a0e09cd2157af99bfdbb386871aedf395f5227e72544795a1f28be6d64165c685b01913f345538e4821f70ffdbecaa585a8f4a2a15d88543e53ddecd9f2a2a17dfa88adfe97fabdb58bb6163ac5f2b7739119eaa2e52b6bf2c4ea9f7b8672d17ca52e4a4a355bfc102e5a72eba645feea133afda12311955b3464a5ca7bf1dbc48e2adea1628bc67a3da5f5d2e94e6e559ea1d120ab4573ef75ddbd8418736788168d612e855a3da17ade9e45eb778ead444cb533b754168d15d115af65afd041cc5834e69ca547ec768a3855db88a434a1028be6e829e698532eb1a1f28ac6cd749d5129424e53bba2fdf9e3787525869ce26e45730721672b711d75eb742659d1d84bc71826456c1f732fa10619aa525456d15c73d9f999136d1f94c9fc49496b4c5014196668825051454b69b9cb87a99c7a2fb1b5462515ad7d4fbe538fcbd3f7414543cc2da77225cd578a591834d891ca29da736ff75c299efaac3ba614f7bbd53988c6d84a6cc77eae69310651f8fe4433f2279a33421c71a9e02288c6abd5e173f4ac4585e88403d192e6599bf62ca596368fa0145c00d11a77f51fa53eb9cf839ac964321f61d0e02393c96450105efed04e23feeba7d44389a1f74363dcfb07d9fda43bb952445e7ac1a50f0dfb934389cb5fba95f2c287967e21c75c522fd551aec6302921630f8d0f520f9da4ee1d579b1211659341502e7a68bceb8fbd66ab91f36a1e5ab2c374a163f70cbdf78287f68a596ae7d375dafd52b8dca125e6a6e62686173b34f7dea96c6e761e952bc8a50e2da183129157669ff6a7437bdf7dce69c68b0ebf4c83cbc8649c7099433b4f65bb5e47a1533fa905173934f4503aeb1d3cbd74317789434b8fd151fffeddbf6b760c15ac400663b460376868162f7068cc137aeff5b2458fd033e3f286b6785eb12eaec3d64ae486a6fe28ef276b9ff728a5938dc9a50d8d3d5af792512ec2d4451736b0b3149fb3f4e8ac715943fb5f8656ad57945e427e514373c4cef9af7ba947872e6968b949b1564d8767bd73990ca3787f3ac2050d0d1f23623dfc1e3365949733b474fc8c25e40f3165a78b1934e75206328c410c2222ac814b183c7001c317bcd0051111ee095cb8b0e1cb164e4a40362915b86861c31db8640103172c74080a3b0e5cae70818b152e55f0c0850a21b84c61031729b475de53ab5c71fde36497287c5ca050814b1c16b83cc1091ed2800b1c6fc420041737dab35347cf9152972694e0c204135cdaf8c0858d105cd6c8cb12f4a2840c5c9270a2a9c0050917352cbff045d3749443c9973b86e74f2fcac880851716b0ec0203165db4c6477516be23a50c250dc9d38ca0701034aab9d068c0820b8d062cb768e8e8ffbc2af6092d2e88c2c4274df9e4d516cd0ffb3bdf664509256e2d4460a1c52c9ae25eeeace70c2de60e93456bf59896cff1b78e2b158be68a1953f84f55f2fc058b0c585e41018b2bda6169f1212f0bc2d20acd0a2a6061c5042cab688fd171cfb2712dfa4ca68ccc4989892a5af2e5ea1ce697bfbc1c44e1c92bd2602d165852d172e57ba5a8d551578e699c6c485a82c3828af6d479ce099da7879db3271b13cb292a6031457bcff9cefd53e94b597a8469b094a22dd74a3b759591bdf410e200e119998c188a08cf50841652681460194553f99ea663eb59a32722c29b909110118d281c6009453b8ebd3a558bee56b70245639956bbee7ef55cf227da4a8aeefaae55620cd313edace5789e9dced4b852279a52ad8ba1528c5938d1bad7d2c38753a346fe9b68bcdc5d951bd773424e13cd75eb73a79a325f5733d17c3dc46cb550ff34624cb456bbab8ab9d78558429768072dfe3abb325f2a66898612a564ee28b7595bbdc25289b6e93995cfeadae88c12ed8fea2ab5cbddbd5ccd8665124d1d3cc93129634f9925d15ebe834ff9267698dd9fb48325124d8f636ba1de6f64c4280c1a7cf0c10289f692f5dbe77865bf846e79445bd969d53fef859f7af06071c4022c8d68cd29ede1e39aedd85122c270195100cb22dab6526b5ddf238712534453acd8feba4dc784f889686f15ee7bee0ea5945222a2397fcca49bdcfaa554ba613944fb3fec3c4f2c953ee56588b68bd06197473b95252e444b67e8be097b39a22b21da22b5e8bd52239e4f6e100dd15db9b273dc4929addf9c94a02cf2c02288b698f1514f879928fd8e931f39a8964034c793cc9e428f5f23c4806888dc7ed4613ba69ca7e50fad1feb664feb38b3f8a1a5d3b7963b47d1d287b6309d3aad74217c93346cb0040b1f9afbc77c755acafb38e31e9a9fc71cb2e59eb24eb9163d34cef45c779f53d7a9581b963c344fc574cf5921e6eb141e1ad34cfb785e3a5efade1d9ab397aedee133bbfa7a8b1d9ab3778a2cd72da34fa80e4d21529dfeb94fef1c563ab4a4d8ec9d3b7edce13c9639b445e7713e72a6528f960e1d3a747c9cdc83974458e4d0f49b2de45d77282565806c4272b0c8304383628943538ff1ea97dad72174ca0b1638b43eeeb17b6a29678f1897149637b4a54ea94b8839869242ef211a9212e562a41bdaeffb3b887cd5bf77b8994c26932182a50dcd114f669ff38be5711a3481850d4d31ed6ca52c65527dc8b286d64957abb3e98ff143ac86d6ec8bc88969132a1a299c86869876fa54e6be1eda0cd120b3a0a12195a99fbb7fef71ea3d437348252bcfc46e59a264314373299f3bb7082d6568982cf95be8d673ee0991a121969c3b2ba5f5ce83c6d0f6a8d79bfb18515a84c4d0fa99a363d6aeee4c29104586191a1f58c2d0d42aca5fae56bd7ca9200a4d444e3625080a831c5c6498a11981050ccdadd568df6a1fcb175a5aadcc95db858f5795c50b0da14ccb517a0f553f7f62a4a50b6dfdc95fe7ad3e2ad727171a73553ce7ec63b86b91650b6d297512b54a9bf7229acd0b0141d16c4e4a50342425212937272528c8a285a68c9762add07abb8e350b8d3325e4fa2de6c9792f165a9ff5ae88d46976fa1ccb15da494c4e3df48c9a99292b345ec5d2bda51667ebfa2ab4b3672d86d43a8c2186d0428586cea2c4b7089352556e9942c3d7a8537aed30995daf1d162934a74e8fb3d2838eb95d51689d9cd22a84daf9b215149a3a2a593e7ac8ce554a0482258ef68fe1d39708ade3eecfef7842eba79c267f7a74e1ba03a2504352824f22834c06e507252520886c293f589cd0549d4a5767ee3d1f0a4a342c703487d87ad5edf7e7395ade688ed47372bd14d2d7cf41146a368d1986c58df6a71172d7ee98f1ba26e11b9626b4677e09b96f86bd4f3d10852825268a6a13d2441d1fa7bd88498a0d3eca18e3c3141626b4d467d5c4eea8d4df6a908a67b0b4d1703dd6a5ece8ad5b36da43a9e82d5f46a7c89d0f1b8c4108cb1a8ded53dd4c134bfe2a170425c5c4089625b4b4011b349e04243b42502e224011615722b283048f0011080045b3f91d27bc41c0080080291b92149782487032277310013b4858a42b204848827448a07932031fc8401a221b901d21242438195419ec4045006938121400001b94141ae408c0efe0941d242c721100cac9637e3006025e801262c20508401d008082e2323904c01bf64c2500bc612f39c95800300008604e5ea341000002b0008b058c2d6888e60286165a269416373eb7200abd64e4a11117228240363c824e0046169a362ff6a9e8a053df5868cda9d4fd2d6fe267ef0aad91b27de44ea587cbcf281919f91135f2230b86159ae27adfd48bdf72cc09a270477e248151050dd98880a0301534647346884fc14b465e0e30a4603212858699d21d3cb8385d2507a256624ae2c89f78bf090ac30d4988a290846c4442529ce664066040414336272028221a0d068c383464e32523291a0d068c27a461d24ed83ccac88f788001475ec078c30db41b9290942690708893bc8866a424026030a10160b471f2d86000186b9c000165092229234a7029284970670280810492b480a10689c6ff84a4844401985f6c4a5f6cca5e4000c30b2108210d3470179bff41a7380deae24542361a945c9c348ae6e47790bc894988890730b8c05b8874ca6b4e9e2d4e1e0230b520d178c98866d309c0d0224d9e86644788081f00330b592400130b12128d48ca08ca0130b020d1a051726262c21ac70bc0bc0279c9886a340cc0b802851b8069c56f78c79fecd8c19a20f0c90430acd8849084ace295ec200939096155b8732a529386d39c11e21a21684a369a4709e11306605081c19cc2048dd7883049c80130a620d18838d7909442c4b9e64942442e185290684c4a4a4434272f2212326200cc289ea4448312a2493479a25893a709c5871400038a35799a93061a9f384238270d341680f144e205d3094d878c946c4a443a8d660086136bf23422292316cc26124d9e4613994098c84b6c4452462c8122b2439395484ae42452121989bc6020918f48472c00d38864442e020db4d400184564221211b84343126200cc2184a04149210919d1182215220541f39b1442a02068403625254e73f2201bde2101cc20922036a5c64b460c8009040a82023080d888a48cfc41b311790ac0f8e10c911d9a8d48ca481f3428210bc0f02101983d90a8260da71149193900460feeec07c0e4e1a444e3ce0ec0e0c1a5a010007307773600c60e264fb33901028a0553073334377800860e0bc0cc2101183990a4b131d11c921d2807c0c481001838881c00f306772600c60d0cc0b4e14942de634dc94601183698bc139390fe130360d640c221aea4f905d8484a6c408618322803021835a084583069404b355e32a2d9f1245d000c1a763c491700730691941130306620d16c484a4634ed7f42004c19da2a77ab75bc57ad450751f814c290a19d3e985ef27e8519433b0b551e65f89b189962c4d01e5be71de79ab512306168e80e6a76755477ef570b1830b45edd4c3531637ad8d92f34744e6fbe572bbd77ecbcd0d065a6a5893dd7ea7c76a1f1636b1fbf740f57a3c785b6def1f57afecdeba82d34c71ee3b3f3dec368a1b14d0e313b0c0d019385b65e1f235d75de3bce111969f0c909a7110c161a73c47cd735f7f9a77385a6ecbe551f74924bf42ef3068c155a52bd321d7ba7f3a8d5a010305568e8b81ff12b4ce4ce4385a69472c8cebb4c6fd37353582a31d39c3f2deaa7be071829b49307a9d57fe750a6c52834566d4dbcd6736a692328344de8a8d6be2b7ad41a47cbf596311f5a96f8a99827b464778af151448c139a1fc6aa52fba323648e81a3a546df3f4f991dcfe36e8079a39dc655aec7117228f52131306eb4c45c372def72ae571da6094d1993934b69bdd457df816142ebdd7df78fa1a3cae9a160da6889b563c9d6c9a518395303c34663283943280f63c2e41819306bb45ec97d21e7eff3eabe84e64f1df4f42e736942ac8486503e45ddaab9127a1a072609ed21aaddf675eb19236290d0bc3db56aede4d69d3b1835da596444c6c4145ba751445e7352a231e111c4f40b3c8899d6ceeab9be9e63adae28bc6c33f2742fbe688f1df78730cffabbc3975e34b5abf170ae56dc4d4cbc68fa527a8b2c55a39e8750341b9412100dc949b6cb2eda26d683f89df8a28b960ba9e492ae7327996b944b2e9a1f87c7a14b98f88b91172eb8682aa9c79bfcb093ea39bf454b48d57bffa1e3779737b8d8a26572c4ced17e74ea306bd1567a84c98ee9b4688cdc9f4eb34ae93175b368882987d879e55ea6f79bc9c8a229c49cbe33f510c886cbc8f025162d1f52b5e8566162c85986e4028bc60cd32df66a7c4563acd453c7b93b3be81d57b4deb5cf1653f9737cbd091131a9c1c906e5d28a8694ab65af57ed79d715830c9cc285158dd963aa46e7f15bee74154dff78639ea74e3ff6745145632a29d4759e723f725212c6c849c96341aecd2515ad1fdf43fb12dfbd5ea8680a9d21526b5f6b3a98d2d8f4e5146dbdf73b7e44740a9f3345eb7d8d0a39bacb95982a4563ca8fb85e217dfed7a4689ec97e7a1f3175a7d165146dd991e3d47e1e7377751145cbf7cc52933baaf7d8990e2ea168aef8db213e4ac63af19fa00f1bb420c584440c50b485da35a17c468e1eefe5132d2d6d75ea74d9fbc5fce28986d2295b9d07d1da540c44e13a8b8d4e960c333423b874a21dcfc35852e9394fa89c68a9d951ec28cc75d944c394123db5f2793fbed5447b6fbbd572f4c5a97e33d116e6d1d4ed10c3837af223253b36242523074d70c1444b89e563edc56b1d57d59084b048104a4cd225daf385986b9dc2c3b81c88c2913f19791a58a2a1c3c9dfbb4b2f923222921203445c2ad1fe2dc568a1879c58420a51a2a984ba119ddfe3e9159ac36512adddf3f2854c31f4944b4139b885b848a2f9f9d3cca13fdc457f426e9072874b249abacd95e92d567f143a2127906888ac94691f57fe8fd523dab2f293ce27b48e5bb92ea5066f5c1cd156a3b7483d97ed89a9174969446b3d8a29ca5fd7c685118dd741c49239f4d4d1a5a02c165c16d13adfb987f8a9d5a98d2e8a689cdc53771da7adc89d4ba901a21d2e8968bdeafcebf9e3d7eb39ab18ee2a582b870b225aeaf48c9a1855ad5745c6e5100d21d79b5a3146b848211085aae36288c6ecc956aff4e7be4f9e14a2298430e97baad8612a454050348909051742340e8abda80412262359288c621888621080c1a07d13003312000020181a920824e29058b08ebb021480044340365a343e202e1e1a0e88849138240e0783c1308ac2208c621888a130160925b30fd8b32ec5a005abbefc797574e25113ae63bf405dc819912eeb670ff5d6e74c3c6c680e46965ad30d2430799e09a5fb49017d649c4143dfa9505dcab654bb803c337c278c19d20bcd3d27dd3658554a4c9569d68f21472b916f7b77c7940e7a24f2ff4329dcda0f223f8c4fb631ac18f16940a93b15da4fbfeeed90b44444f5d03f8454a051e3c1128933e966cf48a692c5396480e0c2f8ce64c27008bb010f3ca14680ddefa9b21a08be7615980519142d21b2672998eea3c653a8993cc560c34b8923c7e4b4f0ddb3deee398a139a815f746b6d639de8c2b379c6114a3113931b287ecd4cdea374f3bd6652aef7027e18f6de93ee2550b5e597d464943280c0efa46ec1a87cfb2188dbfdd47ee44eefbfa997dce3a33d3806e98e90c259ab9e837d1b2ce125b7d6403b50005612d743323eb2db64da40ac429062650c7cba01eabb96f6b09480f1850944bd6455c98e02f9078304ebde4514fa6cfb206fe98055f5c5964e915b4b072c32be6136102fafd8037d99bffd4c3c6db10b7f5fc2d39d59e1c9e550dd82165b6ccd575d8f869bbfbf056f5836af54befd78bfbcd2487d52c3ece97021dd8291f3d5caf5a2828577713423eec6e15f8449f2263706e1e6c83e23a7deed3d5126a2dcde6b676c563c9e13a8dae41a913f028526e8be1c4fd7870049c2f3e7236ad76bf72a8b7a17a08b6b2dc008d2f5e8a044c6e94e8958a701863aae439b181811618c826e8c37868f40f187d61b57b8254c886d81ac21d2c82925cc36436a266df6713f4513bb79f69840f8afc60c5ea3a20be913266576cf4099c6c5f6bcc309c63cbbdf9c14b6f73b6449b8067bd2214cdd56c4ba5bb39c19add641c73e0a5b155bb740be8f858f1ea24bba8daf3e630ebad047e3c3b00f12e3aefba28a9ac95ac2d3e6b17d61929167e2fef44d91a9dff1b27edb984bf6daa4a0d6f342dedf56bc9b212dafd7da7441ca2458bbf42ccec1a120f2341971694cb8fd718ee761e1addbbb75243c59cc8065ecfd64972094d39996e3db71fe4df095ee575cbc4159d868c47e82a58b3d7d2716e7a5aaa13b43d5a46265ec6268f7a9333bd5487b75257f5e9bc85230c30f2e25c5ee8a50afb6e94ed0218c43bbe1a3ff271ed4bbb5dd618ca52ab624f766eddf6ddcfc76cae5744cb96f13ec3a30d7a2c91d36d6063ba6a7b65a90c02d051b89bbb5ed1a183e6fff7a8d2e922f8f06f3b00743ba5e4905415eb7f670aa2e074dea46fe41e3b5810ec41c4814985107f259eb84b5a47f5061e2f2d4ed33710537b6791b87717b090023503b8ce02cb2cbda7fbd37186e9f1160b93aa970ee6bd4fadc1079edf9abc523b57940c7be6e77826831dc1e95fb29ce0c0fd5cb789a4e29e154f491a5b03ab48c10b05d729cfcb5c04fd56be37c574ebded05be172c2ef45be8af42f95f30550b5df67d95623e139c83afeaadb44e9e23eb6262750504da75ccd19f3bd78f50376331663dc30a748f254a9c81aeaa18572b867cc64c0083d18c4c7ea047658e8cd570d652f9b3819a22372fe7ae28d2e42a49141e980182414c533584a0a6ceba95f1cf364caf59a323b8468016f510fd67bb74fc44c43f58ab9f5cb2e56e1f83897a71ca61692e809f470be72a00db29d646ed2deaf0711814b01d22d5bcd3caf9b87ebee7de7bb92d6d74817b68e0f07f3f146945456c400474eadff589592efbb621ac7f1c34cea03318022ef89e743ded82392134213413fb21301ef00848a0d8ea2c939a826fd5880bf24a79088000bdb55926848b882e0fc307df0dfb208c5799f16f55b31be67961a56621697358a0773e6c6c052d862b17595ec0ba90b661baa1d2c745f07af21cfdd3cfa4404aadb308b9f08b2ee9ff8ed1a1a4eed60041490600ca728fe02f739a1bddb1ee8d5db72079769210bacb05b9c51996695b99928014c33177963c243c45fc7d6e9634aa402a507e45e31a572970a52cb096be3d960f67ffe7807848aaf144e614c6e483493c9243743f4f81c21f4e4ccbaee8f57f0d84c799830478ce474f74d1b960944417e6b66519e54b894d66d7b05d1de87477653d987b88f0848eaffdf600042d830a7b4699145597179ad1d91bdd98fb8fd7aa048f22916db9100533d003e0cb07f2b8b3d837ae0e9e89f4f9b409a5060c6f396910e3a700173102e1e05d005a86edf05a5386b8c4f80405612aed1e32e9291965406534c2c4f766d521966b6795421bb6cd992a5e6f240639f0591310edec8aa912d38d21e760949a1b4a82bd6b8d327a9e3ef5793af6aab029ec95730079ed6061f0bd4a1e8868fb71e038648a9d26c072acb89379114932fb9fe6b4a5303283e9bb3a57055fe20113072af9340846b53153c6a0c86c8f801373eb03322d62f9b2ff1ff5c2186dbfa87a5c76c1ba95adde35b5225da4995b1d3f06973539ff9d394aa1f4ea4a4e1067642dc693612e32ab7bf60541885013fc7a38f011786bcd260869a494d47b6efa65ece7b27b1eb48014a2948dcb400f36c24246cfc5073959f80018ac8b0c426370e28c9d44b41047e44bb55ec684b5894dacc11c7fe761a1b3e25f39c72d42c3521e190369cf6e3c61f4936eb7c9357d123b1b25664b3a4ae8dde62541f361fa49c0bd63d6f6089b71378911d7847ff4509b24065af0c7b73b89ce24095c5a992020a4bf45beb8c8d65385af75264206d2480ef6f18c76682302edfe6b67b5d80bd47511c7f42f435e69ffa6f004a4c2cd8c5ce504812e1d991652ff37ceb6ca13414ee07f704e504e3b05c2bd91efd590f02f302b7b0ba229d240c7f59a1ff43faf4dc8d6bc889ee39813fdaf65481bfbc256b2f5ea03958c010974acea4ab6de9f06e084f24b6e8829f3282c7bb744a5983c72084c45d06e61a02b81a8c2ad170ba05c80892374d83ddb5e76275fb6a66e00ae0a00f029c48c57515a202257e05f004e780c4ac7ecee2a4027cc627ccf4521a4544a4f0a7adbeac225f57b3674e112b6b8a62559dae2ca31069264eb82e605239c2ab2b5ab68a575227b63e6398f0111549d0557670a4000d8fe6e223fec3e3db08a5280632cc995ba7acb47006a5f194474b426803b9cd92fd0dcf0440a4e03583e9627c408291db1eaea714e8099cd185cdc17c21142201fdf6981cf8d64c9bfe505f7ef02a080b074151455b6e77263cc1128121a9c77498ed09aadb76560068c158cb9536eb67cd529c11150906650d871816c41c3452ebf8e51ee0a64ee9de43cc982c1ae300f22802b1640b16413d96255886da27ab7afd8a3201a662bb9190f2878e00d27af1d2813ce37d231f40c22c36e9e2dcc505d30f74e80afe9ed619efd7aa0850e58456fa6ade84dc9d5266d07e932d1b53ce46ea8afc4334ec075b0624e0107a756c5bbf2131bbe4dea4892d3a6d4e337f65c9f9db1df2504595b03e7c4d3fd37a4a5c6368db0adc2bcc154826ee125f295e5e6de4099e5efe2e654109e6d08c76562d3e794751d4046b0b19c3a4abe0a43c02847d5656345ddbaaf55abe2ecf2f19b19ab0f2fcb1ca2fa4344937b2154f327a51b890a11c37bc195c1b0fc1d8e3513f52acbc30a1aecf1d5dc3ce81b8bbd56be3e4da4328224a68d38c93404a42d660f8d6853ef9a551b176c7e4575a121fcad7cbe0d012f9830bee5bc0fa08615c36712e42db7be628b39553416792a3cb7b14b4653406befd74118edefdee40bd278c68121cf80fa05e6bf749a7959084222fdf95055dd68f0c752a994a22ccd4acc2ac0104f82812b6d4ee82f75904bfb42d9a9a32c41ca751aed45c05ea8ba7ab17c25baacfe4c66bb990e4f2e52ae6b061fc3ddb3d184646981980da4d8e3eab9bfa7d134d1ccf836c8942a732ff195f717dbdc383931fb04999ccc40cd8b8f1689f15cddfce3cbc5fe721a88e48b2f5e1ef4b3400558ba4801dee51268bb9082a722bc5b6c331caa0f80f1c6a7974c7be3af211a3a025809e6567b6a0fef24b71b34031e575d7582735fc216a60cb45eb60355977a4fdcc9e117edbbb69d193e8656b4ec2c9e8737ab679dcd85e26a92ae1a7a36f8e0b2a6a0115c1f03e7f277d6b41089ce505cc402a3dcd4fcff3223ec0e8eaf00b31cfd6d0c17a40ac1978a17d4bc804709d1af8524c200843e90ea01c98ed79ec9543f98504490ad54c0345917d96cda415c2865a5ecf0bffc3c94797f395323de12289c29e168d1b812b15472a5a087aaa82500d086d4cd09507fc47bd45348a3ab00c66c7898026982146c6067726f5848a5a0108e44e075bbaf514361bd79d1a21e5973dcfb2b7dd69f1f4f33d662e4272c7b6e8fa8a5e6c19fc7fd4588dbc444972d98bede39cc0f3dae925a6483b17b3ce0c2e2252f5f109389a5556c15fc4a0716210a99ce2a03ffa0bd0deedf175f86dfe17b42e801a4cfbf2ea857feb64291d769c10f2f57a25e1dd5aa62f18b1541447e58a3018d12324d349b222c2640e5ff2dc1f87ab3780f2669979b5dc93f85a02c5d5da02b5f69d28424dda18788f3dd8f7de9b91d7bfad92285e00ad2532320eb08a1f98db55a12d82018f42ec28cb956518ec16afef9bef9ac471b1a7a304337b42db24dcd18658eb08d7c852c3cc568763425941c7d97c9905bef6a1aa038f0e285cbf2ee75917ed198d5bbc3cacc338f1872a88b1bfa2eeb6ebbf9dc0db5334fbfa88a454e3847cdf31361f3dff95e224e7dd8745d7c1a7014c73c18ab241c25180c9efb10766e4b08fd2a5e87f0f9ddbe592abfad57a927fe070abebdd26c911bb8e9495c22dd8e68c5c6d90f9bbf36abbc606be1a49a8c4a303535fdc87bdd0847524db980ba7a8426a1e55daf4a9ccd506a3faa2375e47d875598228c0e786b10ee6209a984765cd4ae4e129d8dae578f8e3517db0d0816f4f054cf9977315018b09b9fcc411a4f637a020006a7438b717e608568333b78ccb7a2664a9432c9abb767a8c7d1b69e1e5ed5909d4dad952672dc12667bb9926170ab429235adb9054514c82fc3eddc17aecd4a1ad98a229ece9dfa4096b548ff35ca6aa8d184dfb2c640e9d5644a99484bface8940e98e26525a0520709f1d86d9b9ad8ba68e59906bcee537fecddd9384a0ad978ad76fd3636da02fbf38a00024987ee9685336babf0e12ad06cd06b048853910d3e7275c501a7d01cb6856a3e09ccaf1c3c88b4ae33364dec3b9e42bd260532d1b0114e6d55c4f3ce7ac49ac43a7e82c742c09228580bba4a4dbcebb8156bc3b0658b75e5af33abfd13563e2f2d38f4391830280580996661d14c01e80199a5de80c2d98ef139743804803607256511feb19e4a22240aaa06903ce1c7f3ff2487b712baffb519ee36d03bfdac5023c625b4c09447eabfc113359e7738882788bdc858fd9cc5fd0e494651730d00d14a2ec62699f367506e80518acbdac55828f28f3c8d979fe6b0d7002b86fbd1ddcfbfbc19bdf57f84981eebe69e21e4cf8fcd225c0a7f74ce65796cb1eb934a1674b300e7581c69ded06ee66fe3b21f065912c0807f478ecdc4ef72cb7562a0d57f49ec937f2e0bd4a4c1ad01bec1eff5cfec8ff8918ab0e77491b855140c32217a02f1457f690969a500594b16279383472029a62bb03ef85b04401ecc1451883e183dcf82c030bb053e16c27c2bcb2988ed6bcfc9e38e440ba49865bcb18f5f9b559b4034f6ddc1f13bbbf756d49805901b3270eba4733887b30cad5b686b685786ba4f4d02e91a9a88b80511ce64d547a425a3523eda6e8dd67293488bc00aaf4d09ed3a32960f47173579ee25fa55e2a514d4ca9006d46b87a5b868451e7cdaa1185d146e77d13ea2072a0fc045108ed7c6bdab04b3b1c4dd7e4b636330462f8296de804d644be4e3a4b6d28b2f9224ffb3c31b68a44300ee3e872ebed40b4be8c800f66d644d8e75b6c22e77f7d6cdeccba2568d230f7311712055d0f3d9bc5d076450f1447537c7e0fd603dcb4c700da13c6ee2e13b916345a1a7671ed91e43b2f3b634bad05049d786054e7ca387b26794055f6c67354459797da565624c9a2ccf13c0164dbe210679bedde2679157d44eeff267a3639aea9b089721f47c008f191d0625ca701bd3e47380cf72358e1e186270c67029905d2871b3e7c66bb06334001e05d427784d012c3c5ac00361023e4e03dcb50ad597bd05e561fcc32d85a3dd545f5ea5d2c4b5acdb80e106ef5ff83bc36dda22d855a6fa1bc81023398c895af106e766db910794252f357e3326715ba8b47b27359d4ef4e469c464bea6e8fc06e984328345ad0b94d5fd7b600c8873cc733218e92633e69da80aa20307a9c92cd9886c057fde77d15fbd4ecbbc334e94474735a054a2cdb58e27ce9cb0870b5c60e3f9885a8334417e28a91b47277e7e17540a256a9a5d4256925ccdc86b6cd486f85519a0e5a03fdf634dfa9e8ed81bffc0c5229cdc2638da7b95caac1869f135c3a10d6aae04097cefc7af65ba32c04af265f2bbfe0d743351e914bb497f05f09c62b2cfd1c46b28e3f5125f573cf318fd6381413de4f362e0215bd58f8ec60b12b1822978b4cceaf919060991f2e2cde4c201d349d3aed363a1bbe193ef314fb55ef684762ce64edb7980763841109effbd044403965f56209d50024200c86cb11a6cf59a50b68222f0d90220fd17b0c60531923e06a6ebc950c2028625f82163d35955e8ea8f8a3a34f34056a1511c39483c8cda2d250ce32d3216c1250f709709298b42864676da0c5ce1f54e234773f5229ef075709d947121887ee7b8d0fe56a494b270cd2fd29f726f6a4f241242ca003c73eec605e8c604b30e49955012a272cd1bf919904c22039b928b32f2af4199552180bd01cd49cb08b8fc612f304b6d4ff52098781fea8223e95b687c13e717a2eff614c3fb3ab81c675120a859afe94d3b3bbb86214be04a8aa3cd939ea997435705da706ce6b010586b5c936131f0efec377316904be765880a17b111d0920dc395258c3f491612cfd38e5229a0bcdee31087a269e5787cfc738ee84ab92e520efd51706a43f109d4861a9a6f05e747529ea22aafed9d12f138041186d3108ddbcf240097e31af1df87f60b5acb470ac37b64b4170b3a0032a481f6c96975fbb696c58cc73ce03c426694eb85626697a7180d9305211d495ca23c3c786531a9a9db50cecdb7a75f12e2ea66a52cc24eaf09762144dbe4d77dfa54f79c74b12282fa828a9771b1e5675b608fa68cfe460b15099fde115f7cd458f1035ab0f9046090fc86088134fdb5b24c9466ab431e8a18d9eec434627f6e327d0b509bda3c102e358fcd4c255c4a286ea2883c3e2f0d70c5abc9ef51243e6a24efeae933078258879f0e5c450897af55783d6243e0e62fe20602b550cc7a8e6aa797d8ac8dff48a329c070d42a67b468f6262c8e5927307bc081987301f6f3fd58bb6f177ac3931c1d5e74a92de4add2b1249b409fc1c271ad41a9904c8923957d9fc01df4e8e71413c129d198bacd0e85eac9cf817e600786a535a0851c628a1ff79765868613bcd2a19b43ebd37e6ee20664ed0ce254be432ca3329468a19282d7b2b46ddb4c36f86e52d33acbb62ca8db9a9d2429f9425681a60368e4b09c26e7ec534bdc1bff27b904548182a09e0953468a4121eb4e7933b773476780e2a18a7ba5ac8a07e34e70c765da18b65d8f1b71d21c910b3d5ed96d45434a31a419aeb23c8473394059bd7ff0c88ba3c39e10e92ed55ea7ce81cdf37c7647df73ba03541a89d5c6d5d3da6bc2862aae840cccb13ac8cddd7e961322a1d88a90aa2598e3a2857efe19e7f05d9173d7a928d1392f288e78a1fc46191cc6bf8d979c4b077d30f294647008c3951e64f82bc4854ea014284588245a3d071219ce41be8b2c3242715e300183549a4f2eb5f8e066da0723c0918210c82fee983ede503f02485b0a6932979ec1fb370b3e5aa187d20ddfe1ab1ea73ba0930e7b70e194cd8e69b82a45076cb158955f1075569145372e85db6996563bbdb642a9903f9be654bbe487d0d816b4e97232de6449b05022bc4695ce50fac281fc15f3114d30348d5dd800ecf083d0027d11284b9643ff220b2b35d7dfd300b819e2b45616f8ab731aa0adc96bb3bc0d24a369d81c6719dfdcc2c6f6302f488fd73bb133c7ecf176ba518f29d9dd8d86be16eb7b61a01ea8191ce383ac229b70f18e3b1ee41cdde05c0e5957e441991d5b25424d0068085b30065f3357316cf4a3eed6694be00ec3b0b3300c3072a0da7d8f354aca35cdecef8a0e847f9a6d25eac473ffcb53952b9e93ee109d46c6e9baf483809da4ef88fe16b74b382ae246f94ad89341b6aab87273502490f3bafb1423acd77b5cf962a718d3b550403601a6c72ab0fd3f6e90794c84968e0364f965959e640e7ff0c891ce70d88936ac5bd0c923e1e000f8a26bc983b942b1cac52eb7fcf65b332b9778e568a50a44394c93d4b72888e96fcf849ce6533a8edc4c753683073f6d3018a10380e3ca91a2ce460762781d393ca1afeac2f8e8e1118fc6c69ee6203911fed4a45c448524b32c49554004311038d273d01ea27087e613d3f271b53a95a8bdd03e24ca9665de69f3dcf4b3051d810c41768ead7d69c77b0f95ec4a98917e3c40879a6f47e88572507fe0c60d1ac6401388c886731b4348670e70726f0e3f76225fa27daf1cca0fc36ba007bf5917ff96e4f72c2768643974295b95744338c98543a492cbc0a366ac2fb41cef2f377289167254fc3909ce05c601acab42c2017392e4c04e98e9860099150f4368b24ac9e77689b440d442ca9d21a63d75d3c277fb0666da119d68ee1ffa1baef356a986821f1a000a8226de31a58d50a7b6c47e2b6e95a6965f51d0c67ad1bf8057276ed8d89473fd6f86fe68f3220cb6c48079063d65e5ff9827c8ab0dd45209676de9064b20e425309ca8c429a91abe86096578ea6e848a3f4ec5c1fd722c30bb21195e7fef2b644d128200cf8480ec9453f2e5a52c5b21a0e17a63906f66fb6450bc52ee9391c6486f4009272856f4eb421e549350ecc37f19b1d1d8b26a997362ee4daefd82511c477a948e42e90a8afa18bcab0d998f635a549c9f846e85511f40aff5f0308a367115af946d9859d3410e3b820c0fcb7039249ca7f08202fc20b8291e5b25a250bcb05ff582042b48e3a69f3795024c86c49db56d48f7d6b78375d6955e36efaff252099886cb665d9acb4eec20806339d8ace965b2c58afc276d3c32c3e5f3f676a0d362593207667fe546295f982fb5bbc58829af570eade81a8e8ac527f2c73ff1228432ea7ffb9b71c0d81e72048d2b054698518af22e40218483df140625915fb715e02818a402dc4a602232f14b240428f9f1f35fa2adde996ccf76831103096538e4894040492a36b39c70c10093c4c14ecef2a16d9005c083803388bce90110fc0ecf53da1bf77ab898067556004046f91d5a813d4ef47f7bf6285263a7eeb9cfeed7f96d1294fc46e1e30bb575c426d1f88cae34ea81e66ad6d8318ee1063b18ee7a622cdd22d8946f922132a00c119831f93b27ed6ffd52ff3bd36382ed4eb2a7f4eeab0705d06fcec33ca683084b0ae03e3d79223b6b12ec8c4063d09f03956d58d633b8dd2e132ee05e8231d630dafb517e3b1ba3b1040aed81739476d194202d97b369d45f44bf191c47b3abe3b9e0c067d29475c27fc5405a6d74554e5ffc89a29478257c4f540425986606471ca6217c91c9964259efc2c2e583b30b23524caa4f1d35187bdf404bb1f978232142a62c1a5b21f9b1bf994efc7e9297dfbc3d0fcf457a84ae54dd5dcc4ac018e929ed4cd3da230ad81fb1618383c62eded989fc1a8f2050d22d9d5c4379f79d7556c922a2119557682b9f5fe5b1e0884555bbb825b664544421df64c7486a6d30026ab94d75506066842a229d90b040e1e9a240cd2b36aa51d8ec986b3585e5fd26083c10f18a60cbfa419215c6ed9d5988fae29975b9ec8c6d566289ad9db9a3533ca6edd196fb9b815967cea652d309a7e668f8c9e4209e144385a50e1f0e3afa2e16b302cddad0839cdacc0a2e603b0a919973a4c070403531fe726d21156912018753c573482bc693d81b01727c284e6a63e31d64fd82672a12ca000a799266de38ee7fa26629a44dddac93d96bc60acb895d63cd827cd47e24f17713d703f55a9da054deb640a30d1da2cf8c53246a8f405011162b2b6df79d8cb256e1e6caeacec4efd510a846a1c75d2ede076529a93632b854523179d71fc9ac4111b41919e376b425096ee3ff27530b076ffb310190d3d229652d2b9caccf322c3e44d32d745dc05899757898546f78ccb9c4555acf406f8a323619cec4ed8b7b32a01b6958da58a39061367f0ec2ee7b316624e620e3d6ef01957901d0013b8f8c74e401964fab64d7b500db99acedc2a453de11c670cba213c98821aeada96a689dfa7e548368200c6bf37cf6e31958230583b4a140196d7503e6cec42dfb64109650d0a83b9be9dd78259fef23c0e2e312c48316264f2308e03b3e677b1ac375809cd3a3cd6cc502383b58545a38d5e8005c3735dab4ca18eff36caa88151ceedc89b40e1a46d15f3f99d16a17b8f5e61d5fa80b99a9864f50405443745c243c606d2fa59672573e9ac03557729370b86685f9281a99f38c7dfc5e98436603eb631cb42532197269a860429ed6a472dbd66d007b00b8b9834bd8ecba1bfc221cfdba204b82ffceb6fe4a934e577695c1c8d46c2c48efde5c5316e4c73756273706163652d65766d2d646f6d61696e4c73756273706163652d65766d2d646f6d61696e00000000000000000000000038df6acb689907609b0400000037e397fc7c91f5e40200000040fe3ad401f8959a06000000d2bc9897eed08f1503000000f78b278be53f454c02000000ab3c0572291feb8b01000000bc9d89904f5b923f0100000037c8bb1350a9a2a804000000a11d1af5ef20e41801000000d2e6c974e90ba5430100000084e41fdde0772980010000003fdc5ad7fc3849be01000000582211f65bb14b8904000000e65b00e46cedd0aa0200000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da90faed4eaef575446e4331b0aedf3af1258a3d7cd0171466cdaa0e615533bf37891d51589802d279537ee0ca1dcd7500e": "0x000000000200000001000000000000000000b01a416072d01f0e00000000000000000000000000000000000000000000f4ffaf1a416072d01f0e00000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da90ff8f7c8dbf8b1ab0da6bd1d0d1f2e79920e642365c10c6ec3ea0674bde84312fb8f26b9ee76fbcad37a892cccc04004": "0x00000000020000000100000000000000000004563f414a2d3c0800000000000000000000000000000000000000000000000004563f414a2d3c0800000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da91ef923637ea66cf01bee7ea6ea08e4e87a65d30c7b3606d16af154d852bc1b47152eab5b714ccc9e6d6af4e4a364b14e": "0x000000000200000001000000000000000000e038f8e815c2e10f000000000000000000000000000000000000000000000000e038f8e815c2e10f00000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92171efc85ee96dd122f3b2765b2b5d724a6e9105bbcbbe1019cfa1626a13c118e6f77912fce939fe987cbe6fd5704453": "0x000000000200000001000000000000000000f0812e80f655c33300000000000000000000000000000000000000000000f4ffef812e80f655c33300000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92b52ea25f22ca37f15ba4b55494747fea44eff5faefb33ab41cb98d8b6003db5ed693d302430d285c9a8e0915df5fd39": "0x0000000002000000010000000000000000004c59b818366b690100000000000000000000000000000000000000000000f4ff4b59b818366b690100000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9328619bcd15d3a65e5828c4143340fef5408160bdfd98e298253355d60d54240413557532d97e9f297d18849c2848812": "0x00000000020000000100000000000000000080716433b629a33d01000000000000000000000000000000000000000000000080716433b629a33d01000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da93cf7c292560b2853cd863055849dba959affdb642e45267fe134a281638b34973d04eabf4e2e419725ee4b9e8a425978": "0x00000000020000000100000000000000000060934945800ae30500000000000000000000000000000000000000000000e8ff5f934945800ae30500000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da93db2a7637882267dae62ddb2296d63f21c71e0c8615d19b0f973afc04ee767138e44b546d2294eccca2e4afceb31cb70": "0x00000000020000000100000000000000000040683bb3f386f03400000000000000000000000000000000000000000000f4ff3f683bb3f386f03400000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9405d66e8362d05d2279a7f60ba93a27a867ae1095c920bb339b570004ac97121c989fdbdd3db3965908279b7c5724b49": "0x00000000020000000100000000000000000038981195528e960200000000000000000000000000000000000000000000000038981195528e960200000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da944d05c4c59c44805473b81294dc5feee4c6358a29ce86cd404342787dd9e823e1da6a82cd0bcc74f286d44b7663f2e2e": "0x00000000020000000100000000000000000000e3c8666c53467b02000000000000000000000000000000000000000000000000e3c8666c53467b02000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94755a560a6e7b022fde2ce4ccef2243c18e828e85cebd4c7684e15d2e1e0d0699b243f76ed457d22895cc48f3e3b8c35": "0x000000000200000001000000000000000000b46f320e4dfc0e07000000000000000000000000000000000000000000000000b46f320e4dfc0e0700000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da947d1e019255f155b1661cbc344650b32549b096144124726bba7b5f3518ae1229740be100646ff0e4c28c340bcb80239": "0x00000000020000000100000000000000000000c9ea268367780800000000000000000000000000000000000000000000f4ffffc8ea268367780800000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9575c2ebe0e2e82acfe7764d89a8b379c302267ef0b206915c96f39d81ae769ac11637665be9e014e4898fbbf5db92f31": "0x00000000020000000100000000000000000000c7c147af100e7f00000000000000000000000000000000000000000000000000c7c147af100e7f00000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95e52e5fc69d19c5249999ceb9ff179aaccd886be975fbb469f788aceac28cd295b7fa0e5c691b8e3fd780fdae59aa144": "0x000000000200000001000000000000000000c8d549f38918354300000000000000000000000000000000000000000000e8ffc7d549f38918354300000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da971e68bb6be54305b43fb93f16a9e922d8912d71a1cbb7efc012ca9c4cd6b7300cddb39d77f088d91924891531c5421ca": "0x0000000002000000010000000000000000005cde317d8b560f160000000000000000000000000000000000000000000000005cde317d8b560f1600000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da97ca5649b924e4f7bc893244ea7d7289ddb5c859a44555a3852007f4778184309f12a02a22276c37decd753ed5f23e56e": "0x00000000020000000100000000000000000058bef612afa4660700000000000000000000000000000000000000000000000058bef612afa4660700000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da98c55579a256cc8aa3de388477e3c2f10aeea4fcb658f17b2c6cd1fce911866307e614dd49c7324eb9ca193ae037d9c0a": "0x000000000200000001000000000000000000bc084753715ce14100000000000000000000000000000000000000000000e8ffbb084753715ce14100000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da98d1ae6cc576e36be3db95844cfcd04253a2441e795639e09a33bf51199132d7ee10b9b67ebdb1ca30b14544c90018f7e": "0x000000000000000001000000000000000000a0dec5adc9353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b2611eca3c4d08d1f96a367f02e7ef421ab54e6f4b40816fe44de8fe8933fae4cbf7239428e080e6fbd92dd6c6bdcb2c": "0x00000000020000000100000000000000000060934945800ae30500000000000000000000000000000000000000000000e8ff5f934945800ae30500000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b2790bdc65df4f43cd1fa30327e0e4616262eae57cdf41aec44acc93f416bfdbb6d8a1430ba19b779ae5c98d6b7df870": "0x00000000020000000100000000000000000034667def14ff3b1c00000000000000000000000000000000000000000000f4ff33667def14ff3b1c00000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b6ec98437c6aeb030233efded28ca4eeb621672f0d8be43b4dcd16aa2aa034db3fe3212b9f46fbfc26668426f9510a65": "0x000000000200000001000000000000000000c05e8694bb891d4a00000000000000000000000000000000000000000000e8ffbf5e8694bb891d4a00000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9bca32e4c2881d806c76954996916e56540cb8e75a9a1e766c8a6b551b635e513a16cbb8f4d9aa13936254166e4de4018": "0x00000000020000000100000000000000000000a316aca2722c5d00000000000000000000000000000000000000000000e8ffffa216aca2722c5d00000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9bd8f48d51b9726ca4bc2073ac23559d59ac654f1421b1c97b2380e08e297bd16281bdc486be24d970b9a5804e37b606d": "0x0000000002000000010000000000000000006c76ee08fe69d30300000000000000000000000000000000000000000000f4ff6b76ee08fe69d30300000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9d8e3f5f6e0e7467fb94c6f63e03209d588a7d9e994528a48574fef4fbb9b731976760ca7a97358a38734c2ef04475909": "0x000000000200000001000000000000000000bc1bb190e1568717000000000000000000000000000000000000000000000000bc1bb190e156871700000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9daf780801663f5988ea2f39ab617da297a8c2df3c7945888b20fcfc570c45c7db18e20c9fe57b66b0071bcbbfde10e60": "0x000000000200000001000000000000000000f45802b1aaaeb400000000000000000000000000000000000000000000000000f45802b1aaaeb40000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9ddde0c79d5570b8684a0379815fb60c6127661e3abe3f347aa88bf2cf09545f387f03438e8ef778fe0adf3bfc61c395c": "0x000000000200000001000000000000000000784acc5e33a8b40400000000000000000000000000000000000000000000f4ff774acc5e33a8b40400000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e10702f089fdce41f89785cdc64bde8dd46827949a45e460ad655510b58be8a03079eea740ab57f3cd8adade1de78935": "0x000000000200000001000000000000000000b46f320e4dfc0e07000000000000000000000000000000000000000000000000b46f320e4dfc0e0700000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9ea7d4c5edeed232ba55a698373b8749c146459b6f23d9ffa4876ba11293be2dc849cef7d5aad3c583a5526764dd47a54": "0x00000000020000000100000000000000000040fa1001fa55e14500000000000000000000000000000000000000000000000040fa1001fa55e14500000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9ed8dc744f3fa96cc08a0e88c2ec81438a02fe19c7b04359086a7753e0ffb918f3b8bdbdba1ef0db8fdd50f42e14e202c": "0x00000000020000000100000000000000000080f64ae1c7022d1500000000000000000000000000000000000000000000f4ff7ff64ae1c7022d1500000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9efe1dce87a8138c87a9755a192d55aee4e448bf0f6c08e0443fd318476062713c3b84e1f0d3558206777991441ed0a1c": "0x00000000020000000100000000000000000000ed95c28f055a2a00000000000000000000000000000000000000000000e8ffffec95c28f055a2a00000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f2300b6e4e4a41213463d1870331bc97b089c0020178b1025ab79018dbf442db463aea6b55feaee7c8500e6373a40c3a": "0x00000000020000000100000000000000000040b2bac9e0191e0200000000000000000000000000000000000000000000f4ff3fb2bac9e0191e0200000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x04207375627370616365", + "0x3a636f6465": "0x52bc537646db8e0528b52ffd0058044905fedf866f155110706625e98083f03405c742f800b44655e0319f453180acf04b44e3e367842d3855441d32c031b95a341f2c5d8034e1440f12801a17b191a5f480ee0aaa9b788543c7b6ad25ad1142482364efbde596015316d6144015a96351e8b073ab3face9e70f9338473b3da48273382775ca0591d50f76f6eed0fbde108b38f42ddfd5618938dbb91a3466d8d4d0c868a9df8c4c0ccc8b4b0b0b4bfdba148adbb4ecc4d50fbbe894913fd8a7fac1a70e8f80451d97d3432314010b220c4108bb635fbed50f8339d798a3b0d3634e874100c20faef0410f78803a0cea70073ab0220738b8810d76776cf35fbc8d387c58450d6840c50c641083ddb1bb639bdec5834911871ebb42f7c1c7c3a4a8b32bae1f86aa5fb7516757a7facdf407939a1ee37a6497df8999b79d57f303f63cec79ac09ddfc079f34bd76f8044ac139dbf4ccf17037c32d2b4d60305559a2a29404258a94d611127c62a5090ca62a4b545649470ed5b1ee9be9d377757695829dfa723ca90abb53159a349ab65c563fa2ce7ef2be65eae5783254fd9634ea27efa3ad99249598628b93fa749a0f2af5e934a7d377e2c9d38ef27e96f4767a768db793a71d72435ccdd56fa8e733efe7eaad7e443c9aa679b03b7d399ed37758f3b22a14db4756851b58a101447daa4696a9e723f723abc20daad0f31a0dc685eefa36f6c9f1601576d725d700a2beaec10df3602f7755cc09ddfc0e633dcf517a6d0c49228e5bb400c239dfafe09cd9df72212f4fe59bca7f5d6beb75f3333b9cf3614270ced705e11c7a1e4570ce2ac5808ba6cf00e7c8a671ab34d5d174b7682abfc333569a524a29fdded05a649b380c6d09d0c57f98fc2a3109a3255fb264b997f27b238f80a2b5855374ab44032952f2d2ab3dbf1032d700a22370670f9ef38a70107cb8f17758e34d7ab0358d37c805813dbbe67dd98b6cd7aeb1f7695e0deab2632fe780d495469d3deee57cc056a3bec3ecc1d698e3cf771166757615cfde0babe2b5d5d1ad9294a4ce9ae59a3637c8f12cb35cdfc591fa3c7bdc53dec73f7db91e7c96ef70cdeee0ea079b1fcf5c0f7ef79dd879353ff8dcf95cb5591cf12c5ecd8facf95973adf98157ba8a962eeab4d48d38f131e27c18a42fc2d7fef1f7f31ac63580e8081adc4e5c10f09aa67d87358c1362a7776f7ca70d723de0f9fc1dbe381f7cedcbf580fd03af74116d71c46f8b237eb95d1c11c2a093ad261af5782df33ed9db99ebb15ab45a8daa403fdbd46ab5504b77dfc59101096ddd3df5e5864892795feced290fe82701cd8b63bb10edd435b865dec7bd1de501a52e44bbfb723f7a9afb0e77de4f8de69ef27e12d070716cd7e086f27ee095e69e791fec8dabbb37b69a7d27eef09ebded9307041bf33ef83d73cb2c57ed58452bbff6ac2fb08720518aa916da003af84edb9b0f36353f7e5befb776360d5bdbdac968d81ab3200636c8d959010f5665d3d1b3692d6eadc5d9234c676705488bb3bdbb6367054f16c73694d1d193d1dadc90fa5b26c8f1602de8ae2b1dff5b26cca883671a8c0b1d44eaed6f999a2bc6856e997a9b611316da461d232ce62c9fc7f1471da3d46b7cbb1b3981977900e28dbc7307c067a28e114b65c9788ae53037423df5fd461d23afb25aded1dce8d7bec7a28e115716a72a4bca7365f131599dc0b3e469bcbb114c65c5c45c4665c19cc57bcccd63ce92f1ed2c9ff9be8b3a465965658ff15a4c65d56336cec323f698b3e2632aebbace95959dcf8ab976237a9aca7a79794b65a57eaaacd33ded2cef5a65a5526769afb90bf3b7cabaae679595aaac19cfcea9f359dbb9b22e97b3aee35c87b3f83a54d6cbcb612a0be618761a95f542e33018cc75380bbb0e9545e394a271d6e9a63a51b95496cb61605ee30203536f23cb4e63469669d9c9838991d1a5188ba74c464a6a30178b776d51c6742c517a18a738c360b46b931123437a2cdd959d4e298d31986e6319a72da6c3a28c198b77c1a42e989894e4a107d6228ba7dd874e878c071e5c62b4d40907e7ac781c9c930c19f52a96576d3df47056f61e7af0308ce5f5385b769c4ba53acbbb8a07956481e1d7f710d3bd87fb70968cfb80837396761c1d70eec359a78b071e34eff5aa0be6aac8030f3cf47016f61e2a8b071ebad47dd0418719676d9f717a3d0e8dcfb021c387e39c15731c956a87eb5059aadbd0e1386765b77116d79bbbb8c498d7f33063c66dd0a0f19acfb0f11967759f21cfc36f9cc5f21b3087cd7d388be53ec09bdbf0e137ce92711b67c9e3a86c6cea6d706e7396771b7896769beb5053731b342a6b4665cdb88dd7d078cd59db6be059d775b8ea2cbe0aeec0c359d879a8ac1d7878adac1d4e83c65567a55ecf3afd4665f5d0c36f2aaba6b26aeee2729bcaa2a1794d65d9dcc5e53567c1bca6b2686a4e73d6cdb7ba63a33ac951592d2d9f5159349545f319dfb6d7b36a65b5d8783dabe55a4db238f0d97d382bab4b1607de87caeaa13a8138da75a8ac2cfb4b65bd5cd3e1da59a75a84565999769bcacabe9dbe9d6573af0281a9422c0ebcaab27880f90e95552bab5e07ef379565a3c66b652d198adeb0c59517acc104472b4f0a4ea0200a7040430b8ca4b032f2be1371f62cafb264d47ddd88b3af511f71f631155b1c781a3364dca6b26a644e53594444f0411996aad4e0065020c24a06910b428085126471853754996225e32c1995c552bb998a459cbd4cdd881380faa97adfd599b3523589c5818fa92c98ea04ae8c58fe5259dd5daa931c2ba3d45b2a8b857b57594434a8420e55d0c08a186648c32ab55968f2c10c4ae0022b59bc61953a2b555958cd81aa331167cfd58d3800a89f8ede73d5b15596569da85646f35965f108021667d881185468c2c1ea549d7c6554634a1b7e70042c3481431956467cec2cacb2aefac58167d1da459cfdac1b7170d42f47ef65552d0e7cac4116077e4f14877a601c6368eb75ab148230ce392acef964c739fc1ba51070119be19b39c7121a3cf47ae83e4cf69e8f618c84b6bd371a84ffb66608b9955a09e5a0179bdb760710646a251b4ae30d7ab2b7a6feb95a490bb7a194d0d4ee0082adfe4940431fb2d56ae8a36b6d70dbddf1c18e577541c88a2df763af787bc3b548c75cd0b631cef9f8f1cb87ff74e8f871087e91583156ed25abb6fad0d6ebe47370ce87e9e09caf3be7cc03c139b2e7679a7ade8673b8677f5b7f397a7e598757dfd6df4ccf779cc39f7fe19cf8798c73f6f31be7c0cfefcdac4556091669f07bf3e5d824aba0e4216410b47e6f7a8cb96516c9aafa09c586cfde718e7669d7e954bfd3b39f2e8c73aec76f9c737abc7679b0b593b7ac5a566d875c10dc92555bfdb667bfbcedcd138a7dba067961445ddeb6e66d6727ef66a6e17771c4cf7c5dc3fad1cfc76b1142ea6d27001ef38466c32fc7f3d27c6d35de9634fd7a1ff6610d1fb96516784d722b5936569d55f1d76d5875edf04e5c4f7a1fec3df58462efa187b18a0f399eaddbac1dab18eb6c38671f7fc339db339cf38e57ed8ed8f17b13333867a0edcd97a37536e22c8d6efad0ad521363f42a35c1457faae60fa057a989a4668ea7874ea9d5ea6f6b7e078ff5469d659caf6bf8afebafe3f3977338679e8f31c7132bece621d700a29ed7e036bdede8c1d62037af4d4f08fef04856c9fbe87a1e72426ccf2fc7b3acfab6d696a3f5236afae87dd88cde279b7e87b5e87d0be0aefa2de9ebd1fb56a9e3a7f74d218014112489241dbfacfa96747c9cdef6e5fdc42b57ae58e9f9e87d3c5a5e7e7adbcb0d7175a4decfd5b37eb063fd8157ae5cb9d21f51c74b6f5905ab64153c85110dcc31c2c8dfe1c87c787966e6788e101e6b586b7ec0cbc3583fd81c216c82f661f17bc939fcbd16bdb9adc12d7ab4d9830dbdcf030daf2d64467d2068183df8e57ccc86dfe1e8c9666f9b88618fb69c0353bb1af460c7d752cb39b0f71ad6fbb86d174f833175f2f1f091e3811576fce831c723abc69be49cedbd2637c82dd700a2e61d2682100a41db9bef1dafed3b6d6974cbaa0f6bc8f558d26ab59a68788db7e51cfe2773e0f7cb2dabe277187a9255f13b745fd7f17cf978ed8573b6e335b8759cb3acdac7bf700eecf819ce818f5f8e477a4a6a741011d67cacb9d6fce0cbf36515820debb2ea93bd5fce073cd78f0fbfc33bbc379121dc02a9e16776c7363cc6393bc58b2f1a7ee39c554aa2a2e15f38670fbf37b01679af0d22085b33d2c12f1360bf9ab6343af8bdb425d27d58f33bce81e7cfec0ed87c8c73768a175f347fe39c554aa2a2f92f9cb3e7ef0dd722efb541042102b4f5ba556a5dd11fd6fb8e73768a175ff41ee39c55ba02a5f71be7c0de2febecea7be9fdde6c2df25e1b44102640db9beeeb1a5ec539dfd6f0f0339cf3a91a1efe06e7c086ef3867959a6835fc0be770c32febc0d567d3f01be7ece1f706d622397a6d104118016d6b74fbbdb4edf64bb1a59d1a0c21933d9051240f261573065306b215afc818c811c810c826e4141207f206738a99344b3057305b30593047309f98289829602f180bd3047c86a982d834777021c1242c2134a360294ca429c584c17c3249c06c8857c41f441ec4283107510631061106312992204611a788278826882540e2081f9e03b781c3e0313019d80bd107fc05be02678189c04360290c04f8030e02f3804bc0453c858db805cd00c38065e026ee025c01b4012c824c60086013b035544448901ec803238670600319b000bcc17c01736142d10100e0b8f1310c2e282e260c0678858ac1482c049a05569a275822003a253e211e213a811281d14087c054a041a052580d5408140bde023d0235022d025c0355a25950245020d01fd02ba80f620fd80cb4075c060e032b81f220da205611a9a051220ee80ee208a80e380d700c36019c03bd01b5018542aba035a0348057a030a02fa05250174429d015402b502b680e580c8a0399034a059d0195018d014da2534031680b280b22125805540534051405f404d404b4041489928046414740a1a04f501150279c053da24ed026d488b7a04594090d016d223281b622947965ce61ca81c79863b016661c261ce61ba615a90369c574c36cc364c31463ae61aa61a661364d34cc334c33cc3066192619e6182618530c330c130cf38bf985e985d985c934b9c02c985b985a985ecc2c4c2ccc2bcc2afcc4ec625a6156617231a930a730a5309766142614e613e616d309b309dc6452e126e612a612f809176126616a319130b39853a6d23cc234c2c4620e610a814fc05af00ab8094c2506216201bd805f806080619840983f8852cc2b780ab307d10dd309098614830c03ac829970128b404a11bf885d885ec41dc4a55884b8458c428402fb2052894d8846884388428852b80adc45bc41ac41a4413c8a2f8848ec06ee01c781e1c06f602b1108ccc460b01858066c05e6827fc0516028f013d809cc04aec24be024f0141c03be22ea808d106710ad6017700b78069c024601938047c050f011d8091fb1131c022807d806880308061403e402fc027a0132c12d402d4422c029c02ac02afc0584027c0204029c0194010b047c05e827491236e20e34d80be9124e1c7d828470a02789109f247a7a34188d38e2d3d3932df431c2012142479638a24768880f1011238e10e9e99171b5210921248ef81861c3faf81cd18344a84728092488f87400e71263838c101122e463448f8fcf113c5c6a5824471c21d2e301209f257e3c2004c8af34accf9023488ef4083982e40142479640326448cfb89a8c4032c4c7881a171a36c8033e457a827a7c848400f91cf141a227c8033e3f8e20211214e42301ef3ac32651428850908f124484602e33ac8f1148861c212244092446d4b8c258237c7c827a903842c4c811472c9144504f900e57196e2e326c9091258e080af219326489a01dae31f81831e2c8121c40c2532f30f608122240498e202142011f2020405c6258237c8e204124e8c8123d38571836c8882584001d51af2f96c6f585153a820890114a2ca10491254294f08250908f114690d8b8bab0403e1c506289233d4608f149c2bb983609a1243e46f4207184c891258092f404092521e233c407e8e6e2c27a00488812448092d05c5b581f21214241339716d667881020a1213e42477c94f0312224e423811997171b24744488501656286889cf08213d46185902491241aa0b0beb019f223d438818e1c012497a8490184972850d02f23142884f1236ae2a42477c9440c287c6d5c50a05113142c4e6b2828f101225de55851d82440991257e7c7a84809024f101ca7171b1413e481c110254735161837c82827c8e2881c4882342807a8c08e100122348d4b8a6b0479010111202b484113d42488c04c9b8a4b040488486f804f51c21d213e433c48748929e254294f8b5b43e1f2012d4e301202442414492e82192a47d86084912c481252430734561837c8c181132c408282c12478824492244891e243d4243841049d24142437c3e0e0cc1c3f584ed0091240de4530408490586f0ae2dd647488811448c0851d2e3b384cf121020c2081f24901042840f971336a8c8109f24862c6183848ef800f9247184c82f251c217244cda5c50e211274840890d0129f1e0f18499244480f908f1146882cb12a3204899195cd85840da2b9b258213d36d79455a247889010238408f93880e53ac207881811424488c811223017155b64c8109f253e2dd70c16088902b60ab048609318222484033d351180814007a465883d020912a0243d487ca0488f8fd0124994403224e6c7265942c827a8c7081fa1a02580847a8c1082c448cb0256e8888f12487ca0480f12a11e0e2031c28118047426b892f004532f91b64aad5643a22883c628310a4c022f2961a49492068c84a10123a584105ef005a3948b34c71521c4521c5f3078453a4321845ca4178c10524a23a43132b3bc60849132a53032434a238dcc0c19a394420e9b734238e99c73c219e175cd89c5b84b614cc10ec6e5dd2ec2d59653bb0100c0c57039420a3752082194190637f27545b81046b82d7077e3c2651c9146c8bc90993108bb08b70542086146614dcc96de805706af08e1c28511423e9d20a42ef1049737460817c2cd60cce2a9a606c20c6610c293cbe9b4cbf082906184f0823072840ca10ce4b8f0f2617b70897019c65dde8531421821334b86bc38702f1a2964c6e02e2feff2b26a35c87137ee2e3384308bbbbbd8521817725ce6852dbb7017628b518d39ce401863b79146b8304218638c90f98291a964a6c1b0c810ca0d72a4e161071d68aeeb6279c3d7252fc92c9937c9cc1c9923cb6db391b1cb91528da3708b10be6c2f9b8a36e0b6114208e51623851c4661aac6c87154327481cc129310421a9721d476175bc2a6105b963d008444091f25a84f12363147082dd1237484085092197305e01314e40394440924437a807c942019e203d42324c888213e3d3f14c9218000920cf1d191412300a0201b2c3e457a8496f81ca11124144464898f4d9121423860c40812a01e3425900c5169404284827898b13f14e0070210400046f8f420114ae201a021366eb302408204a8c7081f201f238090f8100112ea0195430001f408c0a78810231c38cb10214147840009f508115182034b04f51c2122248921471c8104c713e20344c382840c19238ef8244922c4a60509244664fc081222424b184112d4e381238800f928e9095a22e8884fd01124437a8496f8f0a0e4884f9cd91f8cf828f131d2b34488123d481c21820412488cf4082df1a9a1e4884f64d91f942022746409a09e21414494a83a04f0038d1a2b8025448ef0014a5265847c8264c40009f13132a4c7070921404884826a5040e4f42c41d201a11e248e104922484812332e25682839e213777fe83982844810908f921e1f1fa0237a809008091982c48811213d424b7c6c941cf189344e4ff09e82ecd0d0d0d0d0d01025229a4444444432290d0bb24331c8101c1a2292431c648986ae204390080621821b64878638c80e0ded1011518c4186868688e0100cb244340811dc0db2434344449368062182449048061922824b444414831041220eb24430c80f0c07b8bb508920211b3e78b03d0078de4c7b8f50a24e00aa9402808ae1a8150a659252b82da360449d5dc9c4404f5bd2dba10721841042082184104208218410420821841042e87d831e5c4e561fdcda77187ade5f381eef9ae7697771d17cf0b6e9153a07398c110738bc81ba81b681b2818a41d740d540d340d140cf40cd40c3a065a064a063a062080318bef88217bab03b76772c9685ee83474c1865f23cacbb93b9cd9d78e1648cfea414ea05e7703d640eaf414f4b6aeeb5def3beb7f77bdffbaf51e3bb59f7cda82853c401d23e70a787e17ec89c3b65ca28930e94e98632d9a04c9232d50cded838333f89d23edc05083fe127fc849f782f5c8f98d3c0ba1978e4c359b81f32ff88a23477d9053c8a3a374e2fad50052ea8300529f0503fac77380ac07538820f801705283c610b2734810900f0e412a4126412a4161209320b39653b0e4f1ec10845c0820843d81d42d81dbb3b564a39ddb216ae47cc679c7ac1393d9ce2fcc354ff3a1e76f8f7963afc53c9fa0d31b50ff5e36ef38efb21f31eea4784d4dc53dc8f21fa1b626aee110a3d4efd3055fd3a1eea3773f31dea771bd7a17e2aaca8abf14f4ac1ba999bfabd3f29c546fd541de36d578fe59ef7f27b2dafe1a5ce7950a9697833bc0f76f48273def4d07b8f61e3a4c846c6ee5082d1ec0e255dcdee5032d3da6d6eb339db36871ec6850ea86b789b671c8f4d859dcc5bb80610b5cc6915ce91a94660126b09e7d49c1eb63827e3786a8c24c139343f713c34d76868bc4cbb8b8b760d6e351ed6341ed649441d6c459f84735693e1cd782c05ab7e6d2761ea077b9edef887e1f8d7018032cdbf1c003338ba1b9ec7492f1e3f8181f9723d605c64be51474a8938f45b7ccb334f8b1e4462157d8b078f5845df80cee51f3c6aeae272295127428938f4984cfdb02ea6ce8a80ae01aca25f00ab763aee6ff5f62f42d12eb7cb5f1c8fa4f294897364a5df6052871ef6174e921ccf0b3ce29c96d3432838e73a3d44e29cedc8f1b45c6b69f1b2eb2d2dd7f51df660634d3b661616e6b96dc7f2c9f1b0141c3b6639e47858e42623ca6329b6fa01e9ed99f77112e768f583ad9d7ed953f05acae327aca29f40a7fde32741b0141f6562964289553f681eeccc8348cd799bf7016923397234c3e6272c05f4528f52a9a174cadb4679100b5651a5a63f74fc4f4ac1606b7163f1b0eebced6d0df3648e96adc90df34e5b6ba76070ce553fd8d7b77face6beac73e35cfdb46398474477fda34c4dafd16dbbec94e3d17ef220515f87deb7356415845e562913abe8358feb41bf6015fdf59de8759d79df9256ab85585a6a733b79b2970b025e1e6ccac439d8e9e917d7b14bd6b9f10abb1cbdc3373c8905e3d02aa5b08a5e4ab99a76e09c291aa4130b56cda9d4734661d59c57f49c54b06a4e283de71356cd2945cf0905abe644eaa9802e9e7edfa3935facd2330a7f4ca5e727c1e8269c74a6e715ac9a40b1c2287526ce49672b1241bb907a5bdb4e2a45b9820a284fa4684aa16015a5484dbfc3bb3bf845ac0a62fb2a5a1cf4cbc57ab55845f99355a8169562c12afaef6a357d8f6ebe0a6c92520420458a141a3c93615000f249d4996780138ca8b3411c7afe3783d56fcea1a97c72d56fb6a1a97c026970fd68cc64f59bc160fd3088f375fd6d4d1febd7c9fac9fe26184de904833340e57241c0fe89cfd82b8255f4d2834daca2ffa1933a5669a9ec528cd8c59a06b70eb4401dd8a46409a120a09f24488e2861a4c8472409248ef0316208078404e9d980063280810b58a088ddb134b5e917f6d0f458150c0bdd0ef36113ed2ed8d4f445d00ba9bb81b61db69de4783a8c551bab206480465b2daf6d5a76c22e568a3a5b954b11475e6259875d1046914b58a79a54407922051448b2c52a298b5a46315825a39596304acb1fa0fbe252949d4e4669f91e5dfc17975a5ef62759a9250a1a48f627975a9ebd8e55f2736395dc3cd8da7636ac92df1d861ccf0cabe47fe81863154f074f5b91a7133460d2b145d3472cb47d40b74a4fe4a0e3e59f08e3092fa4526327ef837dba9e7d7e9793989893300cbb4e37cff5dbbec74eb921e823fc4e8c42b3afcbd3619fee804e7b11f9f8cf08bfc8e9f0df76f2211fef804eab42b0afd3cf675508b63c5525b0e137723cf0ccf1c42ff703363c568b48a548c5480c0944435543f89986104298a2513a35f3ed6462bec3cb39d0455a0173eddb75f86ba6b5997fd8673ef3eb17c773c9fcc3aaccb7d32f4817a1ffe0e9e9b54f8e47abb0835572435c1ed69a87f5c6971efc769a7c7400cb350f6332c2490deb114eea8f09a62e927aeaf27c09ab114e6a161617afc86764a8a98f40a4e6e2e10e5fdbeed4828442d1d060617410a9e53594563f2310a9b5c7a3b6b8a1869a22934e77ec18b65dc7a8741f274da94988451d2b507740a79d2f73d8a89f8e7a3c0d51cb4379ed5b726a51a6b914a3d054182fbd9f25ddf26fa851decfd52d5fce07432f7e723cf1d82b0afba2ae7947508729fa2282a1154151848222298aa8c8c1e2acaaa1a76a0d6e4557146151a445d116455c147951f4c5aa32201a7a40f41391431d7241c02682fa723e5087b9966decb1f4187abcdccc96d47ced05519a0faff146739b1934b41a195f1a2ef7ee6dc49951bfae6d2a374464aaa91fd6da69ea87c9a85fd7da5f34ed33bf3407c06b55493c9010ec79832adca00aad04726bff892cd8220c3e6825dc5a051292adfd67ad60010312b412d95a95decce14f8dfe6023c1dfbc8fa87906d3340f6be809cd6678ed3c7468b84a8df5174cfd617ce80586459df805c7307afeeb7a6ea17dbbd1527f91e993dab6713cf0cb69f5236aaddee51b75bc5fdfa04bfdb08a5df5ebbcae65fd66da9b69295fc3db89d29339f4be20fdc95ccb643c7af913c723af490f76507a5ae5c7781cd700a28695e37ed4b872e54af335994d7a3c7a5767670471589c65823dd19d60c6059fc1e26c1438c8d11c850f56b57de2d1d0e3d12a686a1f7aa7a40106ad6990a3140ae7cc8d3a58c49987f5139a1a7b140aabe6a947935835df808effd1a4205cea876d98153a1548914bad568b06ab796d3b4a850aa8a8604905559816470560581cbea6432fe700983307245a89384036e268abe52200577027b2c70d6912a58275de6ab542b09a7fd4e12495cbbf1c4d97764db19e583703e309f161631c0fadb05ba5e6a4a81399e64bfd3097fa75cd499049462dc6c8f4a346b30f7aa1568ae249b7781f11516bd493cbc95a045e9ec563efe3a4aef127adbd861799a6e8bec8046b0d7c1ca357c9080b1f7a955e50a52353fc82752252abd562c16abe0560700b9ab80556d805adc5b1dd248c5ea52658f447937a7e875ea52628801c33c783c5a08b9fcbd432b2a4ae791fd61ae57852d7521eec18c62544f182ee9ee26a8493ba7b8afb1197108514dd75d77738e561adc18dc5dbee969345b4f3511e869de3b09fb67f586bb5467b0e2e32b16afe870efe8b4c5af59103e56d73de50536fde17c1e879ba76f260a76db50144ad6547713fae28a490c293d52f88ed24399a4f1ed698b73d391f4449fd3d40a9653db24c2dab91655ace0790fe82ae2c359f73e8e7799ee08273683d92a3b91a691a85866d5c11c116fd610d559c030f21aca2a82184396f78b9449c99b18997710b4268bed56a09cd2b68cb806e5e4bed0d5c61502707c4e143882391e4803a49220e3fd64fc74259b12a4dace4911c51c248918f4812481ce163c4100e0809d2b3010d64000317b0401115a0c00488904004200064772c16ba6f97b02c74496613e403893abbc27685c58d1b37887ff3b1c24bce29326b8d8ff9f859a3f436b8516f57cb4124c9d791b635b61c4b1d6bec9852f6fd0de774dfab3887fbfe06e7b07c9f837352df03c139a7ef75700eea7b1e3b0be01cec7b2138677edf00ceb9be07424411ac8321b55aad29abdd6f9f1ccf5661074d90d4508b5ecbb118b17ff1d8b1cbcfd872cceb5a5a502d2df50bd24550ff5a8e3aeaa9cb962a34375661a76515f61d66f13ed84a66a7de3f413a55bf20a9ee91e3e92aec52157243bcd56a35b78df5c9db4e7958a3b89faeead33f2c479fbee9e853c558855dab99b7acc22af53ed8d86930262310a9b17a0422f537d4d4454e3f7d9e7ff224abe0952b579a68ac1a81487d9de7092e58b5bd3d3d8c05d220708e3cfd5ea3deb6f4b08650db6d7adf9bd60f363d84f3f2dafae85689c9182da35789c9526bd8b69d3cc6f1c8538e277a33ace20bd1d17f33396e00c15c1036ace2d3ab604fef1d75345f15753079be0deb74ad56ab68c5527e332dabacb083adde610d723c1dab3656f10bab80e888381c44f7e9683eebc856eba8d55a71134d28b3e83827b5df9b2f22c9afb7bdab833af70fdbfe75dabf99ecdf7bbfab73faa7ea45556e65f5fdc1a453fd548d1575ad78d5afbbaa3f6e75500c56452b1c86174c4b5c74eca016ac8a90ca76f334719e9ecf1e04a3699e399e09b920de9a8fefd1f13f9884b12a7a92a78b489488b2648308a0e8eff3df25786d3bfe723c0b6095f482d85ec0e2983bac9adf2e40f7bd277bd1f25cb43c02baf9b71a7ea7e3bfd5fb79e8614c5f02a3062d4eeaf86566fe5e42082f348349292f34b3cd392f34d3514a2f34f3725dd7f5fd0c866117bacde600012999e9d395607d3a9010d63f710ead3e5d68a64f154271cc83471e2c62553cf5608b55f1d363794b58150f3d212fc90799f849d4c91e0f992253c7185b1d633c193ad8f0df3665ffe052c707e9d09ecdcba00434171535c1564c52565a4d6656d98b9aa856592d6a1257dbb33731c06aab56f035afa8e848c72aab4d4eabec4ce21c5aaba31aabec454cae315aadd5516a959d49ca4aabd55a3581abac42a488035b2debc77517c707ab743cac1f7cd2719b3ac627b13bd8e3fa9380e67f3f3bcd2743370f1fffa863c5ac4a68f3b91f09686e459ced788421459c16c19388b32d3d8c0bdd4ee9ed4fc549bd368622d1c5940ddaaeba553a0aa3b1d652632da6d6b66e53cb6f378fe48812468a7c44f6b4d82e1247f818318403427a36a0810c60e0021658ed15a0c00488904004208055e9b02c74f29727203d2f1f7164d2094a2b0ad692d2f3c35a4a3db116959ec78aba78c2e82af552e1fa11359f7adf9b6affb0ecf45d1d2011471eab1ffdf5c8f5c05a494d9f00205167bb3c020ec0c3003b0a90d5af4b3de5e9e41000880108e00754000080e3860f3de048cee361071d6e6c54efbb635b7ef31e71243dfc3139d33b911e79318fbe589cf9dd99a54a3d97b609e3d309b4bd09d2b37e417aca98cdc37344fdf4ff510755b9bad5af6badce3466858e7faadffc72dc89d3bbae30c99831a193313bd5ef7dfae9f0f2c3ae7f1dfd37d35956bfd337eaec441cbe6ac5bce878b2e4c87fd4812bbe8abf4c279e53a0dfee3aca416f2185528605dd7657956156c830e6b02a744922446518cf248938f4914b55a96970634f096c3e4482a8d4b12eba0f22695668921ccf0f6c7eab2152d4a110150fa9aa01ace352211254e9b8d4fde28348a824da36cd26aea9e93126741293ff3a4c66d85b2b7af8248542a5bcef9dbaf4beb7fc312e3ad5312b7434c3364cc338cc0a9d7c4a089a6193eb814a79a7a3bc6d55d4c9de523f8ca57e5da76a7acc8bee5b2a19c6185202baeb27ecc31afbbac6fecd340691a24e4c1522e2d057ee25e552b56355e8bac77f4be51ab66158d77d33bdf59bdc106f7516044a1111871efb461ceecb454088888343dfd58f2f2f0496aa5f87a282c4216d481a52d347ae47f6f99d98611876c2b05fdf89d855214482365c00a25b2527b6e85532daa239677b8ed16fb58b148d3de6475034767e18ed84178d1df5ad586ba9f9ede8b73b7dbb0c22cd634fba9efc4128cdf539dd5bfd569fce87879e10ac92676fa9e5b598fac18ef9e57defeb9bf7bdb7b778dfbbe51a0b0b0b0b0c642e3a96ed9815baebdf61f8183704f61899585fea37d302033966f3b4b778f431f583dab66ddb0caa3b66852efe7bcb37eabc7cf0d763cb10d8d98553ff30997f5db3bcfc9b69966fd479c49967a99fd06c979f7e713fde6aee2ede47d4dc1f755a9eaa32f5a5b6eccc5454c77d87b5e582c05aad86f57bc3efb01cb34277fab74c2c09e8b26bd7b4e57cd4b8d22de7bc0f760b33f33fecebbe99fedef39817dd4ed481abb96d9a1637c87d2cf583cdf2eeec7d6f8610c22c5e66a38ecd5bfe61ddf2afeb967f33dd5277a28e4dada93475234ecc5fbe514746dd880373976355e8e63f3efdb74cbf389e2f48ab5bae410e024b8a481271e681449cf9e522b011077eb908048938f33b1167625ae864eac7bf8e69a18b0f12757605eb87c530c1eccceda57e9d4bfd665abc8fe5dc27c7f3b13cf59dc8f2710f22ea9a1f35ae1441d59a1fd8b963e7ce9d3da1d9dc77e20e731fd6df2af5bca67d27426f1b723cda7585a961fd6252c3d611527cc204469315252a4b5592a04491f204e9885bccccf0d977e2c5f164159e3c8c0bbb7d424087ad162d7fd56555fc5b4d2bc6d461ad1657d861ad56eff00e7341bc95c3b0e98567cc40dbbe8cb0e36ecec7e9ed8c1e7ce4f890638e878821a452230ff939c339462052c7633cd3138aede38a420a2134bcf48c4024d9f0f2300bdad62efe076b25361d44d4fc147f6f3e1453cb6bdbed9783d80f3a4c08dd37995a2a35a6d4edbf2ca9e582118f8ed0ed312374b1bfe945cb6f6ffcf26c855d8cf5674933ac3eb0e68a15a1db61aca717d000db720bf1180c3af80f52e15f73e8ae3774b0f79fa472d4122a412a2d178c9628a631b8c08be6c30ca9afcbddc1dfb3b7a39352a9af6322e8e2f5069d8e7e955620a5693e8c06ddc7490def820ef6379768ae733e78a2e10c6608a30c64188318c200862fbee0852e4c2e6c410b5e64010b57d8ecb30b2b54810b2a4c410abb6377c7f65531a68e93ae6336e8b8d5abf4840a76856efe9b4b7d7d2e459d5d65f59b55fa9a4c7d61f59b60f4c549bdfd5d4d7d7d6fae5a2443eab54124a1cc82b65e17a58a73e2638c496074e48e3146a0281daf1d3341f701f1819400c1e62a04fb476c3e5725f3fc5985b87fa49a5f83c60c9b1a1a19333231302f2e2d2c5d0ac56d5a76c22e3a6564b8bb830663eaf6cc05019b2f3dd8a78127668932a43771e80f5701b02927266452d0aeb075811b032a0da97d43d7048b939612b8b0e02506303688e1818c1066a6c860028d146aae60d3851963a0b138e2a507d3d0cb71adb138e21b1abb42c7c736c22898124680d4d4f2f25030359fafc3d6f6dd085abdbdada5f6e6e3284d7faaf3d0fb2052c347ef7b47988489a0cb4ea3d3c5c3733d4e979f5c8fd3f93bf1c4339f79db61871ccff5edb46f97bab6dc3c79df8986986081e0031e58d201254b080501fd244172440923453e22492071848f11433820e4abd101cbe3e8e672591e4547025831e1267015791c5d30cbe32815b33c8e646496c7518d99e571c4c32a5616fdd100563c8a8e70ac98442bad56abd58472cbe38851cbe3284b2d8fa39615f338a261591e47b565791cf5b0e2ca9a3f1a005d1e454caed5518e15bf49bc96c7d15c451e47dc69791cc164cbe368c62af238d261152b2bfe680070791c61bc3c8ebac83cb8b2e4875c56d7c5949e499c99f34c62172beb6800ab7826f168002b96cb4a56169318875c56470358717d1ca2502a754eba1a3466d8d4d0c89891898179716961e952286ed3b21376d129236f1e74a25ba52384d12ee8e0bbab48db1174f0c60dad5909a999538b031ec2c46f1f9d58e693e67f32e65ed16d37f47ee0e1155d8fa4e6c39e44c0a2084638c21096c755afabb258e74f1f5cf1032004418a107e04840e761085073db06279cc1a78feacc1f22862925a1de5585d6f52c5f238925096c7d16683e571f47283e571648383e57174b3cac1f238ba5103bf2bfe8cc1f238c264b03c8eba192c8fa3192a96c7d169b03c8e54aba4e57155560dac12902d9a9d75f4b2d27e04448761d3659b3262b0179ea9ebe6ac19b77116cf388b9b3634cc3a7c87b3523460ce62d489bb16d2ee5059a9eb5083441cfe4d6501b15159704665e5b0a92c98445359b156469251593b313197a9ac7b1522b9d0bc76356a931babecbbd234865a46a3b2ac202225e3ecb2657c0d2909cea8acd46d2a649aa92cb8045359acc43a55168cc249a77795255b11875fc30c979a95284d4a868cb3605acee28ebba4282ca3b2e8672a33b1d8859b58acf1656a4c824ccd1cb1180a535fced2368a1d01b17aa92ced2e3532451c7e4b65c5a588c39c54639488c3cc174f4edbea64ad4aa6d3ca924b11878f55968c129b220e335f27d92499bad65b395af0caca0af9a2d902480086c142a4d82a3ab25915314951143001f84d6e56f3091c00ff839c84b42a3a52ad8a9ae8584d128c20c76a46b13ff09bccace83fbeae5c99c315ba68820b928a8e805815616fa263359dd81f9849aac98dd5842236c13358010b5f98820a1656bbbaf89ac20aac2004279e508b9ae458cd26fb034fa3fd815fc424d5e4ab59b43ff03fd9d4fc39c5ee90e7cf56d4b9ea2ead5d272333eb6eab59d61a7b632a45ae5982b637df6c75fc594740ace659f24ce47ee6f42320bac964a9508437604740acaeb3b0339995c564562712b09295c56aad584e246075aa2c2712b0a2954594832c9c58b1985c5756f44e2460855596078c8670c483265c7165c59a772201ababb286c42005169e40a9728295fcf5a226dbeaa2715453c71fbdacb08b5e359e625aa2339f309f81a18f9148bf8b529469e3f2546fa3eb5ecfb279371f65bc86a9a377193249b6e4e9e63ac8cc78b9ccbe9cc59da5a9e3b9281d938e5e5692e659d352c7eb5059a7dfd4dba8acae56d64ed7dda6b2624d654519952593224ebc57656ba6b21606e631952591e4ab8cd22243d6a87249d2a84d6eac505fec9d12869a51731b979f669e7a4b528aa9e3514931c794e232d954d6e9353548c48997a92c201127fea5b272b0b829e2c47395c5516252931b2bee5965c5269a1a97be4b392e19a71999cf6cbf5eb46f31bb164fcf98e5a788d49aa9aceb3215ba5456928813df525930295559ccc4e224acb2a2524c8dcb944461ae97cab2828896bb9cc5b28288ebd8594740ac52d759f12c2b88409d9ec54a4a2e9585bda5c2adb260948813af555656597caaacc85219a905a32c158af006a4d9619555d4645ba52acb0a22b0cfb336e2e01c01b19a958555c81471e2e7afca824b2c546525253824c10d50f881139a80f0c9176820862eaa30c36a57b232b9aeacb83ac44bb882072690c2182e58cd0a9be0d6b4a43149a44ce924a3cc7f318a6c9d64d2f62f32cdfa26ed5f4cc29ab27f7169ab8fa2d519a6d3bf88747d57d8bfa894d599a453ed9656d7bfd8c26a8724bfabab62acb4a2158b38fc597725eb469c598920bf74e1085cd0d171d29297d2db6b5a0dfdf63ce6151d612beca75fde11b6babede374404b756d84f5e131dab4b89ecf91a1f30a9678df51baaa115c8f56d22ba15f61da6b4fea47ad62a30095b8d799737999fd06141bcf48ee44a3e7a1448ade47763ac3fa9ae427ebb6831c316a86009c21fd8f1516810eeae07fb4acb581cecbd7010c699c5c1874a52a2f4b7c998d91d2b5936965e25294afdc22a3768483aee9db28327db050b34231dfc6abb31d60fb67a7fa45a3e7a4a64cbf8dd789ddd5d1c4f3420b83f1e18eba0beef5e666c78fb5e9543075163def5cd23eae97db06b7ecc5fdffaad5645ae736b4b01f98945734b1b6cd1dcf328af08f526bb3fc8c315f5e651deae266a7e87b79a1fdab36bcfce7d1a226a9cf643e3b479ecdac9fbe86bb66f9f2ebd9aadf6a83608a3b9b7dbc08be63e5d8b5b91ec274d6e9947e5077b6c3eb61a7faa3ff0cae97108eead16f9b2cbc33ed58fbb887c1051d31fb0b57afa8939ec8beefa371fcf2ddfdf556b7ed0cb596be46b64fd314fab8f5965858b230e41a28c691434241d7cd6f1d0f072e135bf8b632f0fbd787aed8895b19a1fb1eee2b8e0b386555b1c7cea01c166fe0e7313cdc2c305611cb4a00e5ef6d07d1846a5f91bff85bd178f0beae03ba0e5008b79f68260f3991362fbc4407071cc0b61fdb3575a3b733db66753886d0dd68c4f2bf9ed39c8416f3f5dd3e6763a79d0fb4e3fe4b72fe7e3f4ed3b1cc475edd0d37ef2b647ee07d6033bacbb38e07778f33eaea76bdec70df74af697f70941220ab90cf23810a3e92390226e4045945ec41afadfa882248183283db353187342087bac16f45188ad08cef966964a033807f67c0ece59a51b78d14bc58b9efded173de910499abff042b4d9837dc339d303da0bd11f3dcda7fc85e7ba7b03723c454ed906b91e317ef1d7b5cbfb40d0f42c26181be2fa11c53dd58f5f04ab5ffcfea3f4f13b4c391fb13241d98bd720ff88e7ff80b4fe80e7cf70cef5791bcea19ff2500e7bea2ddc2e6f956c3046536f76f7a231d70039c8610e73e8e5aeec8d3df5e0955eaeb537b8d544c3736c3a55415b98d4c9c70eae14289a9ec5e8d945cbdd0123c70363d0f10e7a95764084e6297a95ac90a255bd4a39d8a2218c4117b3e855baa249432d7a957a9045dfe855e201197a723e687f4b9440094f60ea9f200d9b60d03f43a8fe84bcb0859929fa1382328517fa137ac20bb3bfa02bfcc087212cf5172465a9e127e7431b03a9bf20c640f281b55a7ba5a18f37dc1ddbeec87a61003e0cae0e8538f12b05066c801d29526c00b669fdf8ccf9e0fa0d359f5625dc4800c1863fbd649db66d18a744a2760712c43041ffa452bb63e5d0f1141a603b7eb4a377fd18c251d31ef44cd4d7eca2e96717fd051135fdd92b57ae3051f3afa3965fb4d75e6bbcb157a32f6f76a104465621fe71a69f5e11e6828057faaa353ee4af07217f5521ad958450d442dcb37e7c25b0e789daebe979cd425a435865abc5c30fb7bc9067986aa02bc6ae0164ab3fcd00504aabf7bc3b72f43eaeceaef6dab549aec77a41310cc3ae886192310caa50f05b151a924ef62ad1a085a49bbd4a34286a684306599cc08a7e21408cd113a3f9d0a8db2938b8a2e1638ca8de2938084307c5f018723c192e8ef9f5a0d1fc9e24b63bbed04ebb6373b4a00e7e51da12a05b252a98fac394a470d131c69544b4852ae83eecba968a8f31c618e3c638a7c488ba55a2a2a9e77722a5de77f8fa990a19199998c3fce52e27ea5acef2eea9cbc8c8c8c8b421954aa1ce7dbbf6542a954a7941d3b4ec9aa6695a156daf6bb005eb827ef991cc2d8e6b5b1cd7a147d4d1cfcb5fd7b7ddc1bfcef105054dc9ec9fcbfee9da667128e17e61d5656829bebc9c5fee0795bfea115a3f7a2391074d3d2b65b53ca48fde4281044d6b1598f60db536bdebc84201a9e7bf0f34bde63f56d3fac1c7230728524a2d41314200bac8a27e4ba890d236bd4a54b4a035dea697ba72e58a14ab5315ad1923a0010a92807448da0195965092fda2ab6805a08b2c5a4a0e50a4b4e4033d43b05fac4eb5b55fcc5a452b660b3c603286566bb595b51f3a0283185ca189315aad15565b45add66affc9cbfa25d94b2f9eb9e528c0d2852dd4600e4cae5c59ed5f3af210134da656ec79e86f2b848255100ace01cad155c8136d181ebfb2ce5ad404c76afec8650505e7bc347f461a42c12a7e8efe5efa5b3000299a7fa2fb201460683e4bbe8b386c9022085304210a53abb59a8f9fdeaea2d792388862062190411156454d70ace28f5c56b2a809afe88f10b08a9fde1102562c2b888867018938fcb8c4b28208fa59593b2c2b88988f95356b0e9cf86f97b60d4e30a10a3360e1065d984219ba5d11a5608b22c0000653aaf4600dab5dc97f398878abb58a50700e0fd1db880359ee6006db827e611511840488527af3105e73d2c75f734e1e4e810dabe6233763d02fac9a5adca03cad36ac9acd59d0e0b1dd01eb94290c211edb1d71956490d42f3fb26d16075c1c412c5184f08af8dd1df37b6dc6f8e5e06f44ec913ed2c70381d1f8481f63fcb46115cf0bfa855936485f230f9bbb464e413faf6ac32a0a5b2e8efd2a8581841cb4a18e392aa834c69061906ea883df6d77c073846dd0f67b237707fd7eee0ed8397a95647082be11bfa11b335127fbbc8eddf1c5817d5ec5391dabb0cf8983fd510793e9f917c6c13e1f03315a6677d8b00a7b44a29e1761f40cabb09aebb1b96baefa03afc86005bd4a324841bfb00a3bf5e0a9dab00a9b8b63bf9c5c1cfb1da61eec68854679b27bdc7777689fd7348fa8bfadc7f57d91ebfbcdfbae5e251940d172714c5e8fcf79171fc3ce79d84f4140ac7e7bec1a6f98c7da21b6611e6f55fbf6e582c8b667db350770dbe9f0e7eb401ce470a58376090a0a44d0fb20a2deba9bb67d4b5a730057bf25ad7ddb1ed97adb45b21ed957ab45b07fd87ff0b173276fbdf5a4062512d6832ba8305a0fddb22a468b9f228c1819763718e4b008b4147a70822dc078831ba6ac5606cb5435e74041f36f700e371f08d6812b9ee70dd6ad5729a9a8657d61156c4e03f6a96e708eecf8ee25da74dc1c18d81ff6abcdde2c9c5c61c76907f6efd49a3663ef8c74e35eaacd6db92062fd60e484d8debd11b7e8611b7342446e08f9f8b3a428044db47a5945eb17991b82fb895d247e720cd036cc63aa7143b0b6710fd8e98c0144474041aec791fe19eaeb988fad465f1bf700a2248e0b8228a97f827476edb4a138061091a0b36ba92de37ce4e81f78253b6c8c73007fa9be8ef1eec289fa8690b46e3b9d76186314ea1b4a6afaccdbbdf16587efb821f8d9c95b8d653b79db94f3c1a7556b61b811f50df52e8e6f95aa90a2e9615f758999169a691a0f1f8bc0f3e363fd3cd07c0c5226a82c68bd4a532cb50d6c35cb40a961abf71aeb6c7fb0c5bd53a4c0c110b089defac156c72b91bd97de8f5413f5275fe3236b597f52bddf2e3a477f7ba5bf78d6e4b69e910ede8a3de47efed375ac362dee81d643b77f71d190741232cbc62ac9aa172de5e3faf56b9b39bea45252ed92cc7059a2be3816ab451c905dfec706ab1f51639799977d276a52cb4e18d658cb8bcebd012ff7067cf6c9862deb0fabf93b9cc5bd010f0f0f9fc9e67b3fb119c32ac69f641576c8f580bd5d7a52d6e5c9aea46b23b2d5447fd87fae319ab872f23eeef1975764fefa65f5beeffb30f9831585a089065242fb7425570711f5a9ca6342dca84754fd8163f4e43c21eef9cdfb893d6b8d0fa8d4d723c7733d7aa74f7efef29470c76bcc1f03888ed0706f609fd9a7f7c3ea78cc93de25bca6c9c858fdbe1369ec2f88a81bfbe9f32776ac45b05a04fe547f58fdc5aed97b8935d2ab91e75fd7e075c8bf2e7df00fbc0224b42de723898f208d1dabbb3782582d2eefc35e44feba8679f1843d46ec59262f443bfbc7401976fa0e63a767d2fb8157fa74ccdbdd1b92eb312f0f391ee961f0e343205931a20d7248d056b2c8c7796dc66b9083b3c76ab1d2b26ba9edeebb63cbd1d87ef33acec9d1fbe9633ebb967999373f9f5d3db0146c6d3b569d8efd3ae47830af63d5fef24edef494c0ce3c25b0b1ccc3246418252aab5f1cfbe961b5c875ed92fbc11c705daba91376c81da13fd56515569755590dbd0fad5dde771dbba62d77aa1f519f9e7998f731203b068f79cb9dea4f6c0cfec89effe469fd813dab0dabf644189c4db4f8bd899e125d91781efaeb9de2c517bbe3cbd19248fac85a5e5eff62fd863afe3b3960bfd0b256717d87bfde75e95120005d4cb9b2da47ef6375fce68d1049d1f4df90017603f0ad920ca6d042b0693db25ff44fbc72a567ad82b51f8a3c685a5db5f5b15ad62ffe3b35f3d0fbe52eb050405a2d0f3d9997342470208193164871a4833156bb69cbdab21cba1956c177ac82bf7aa76ca1d5b063135dabdbe079700e6df8df68f88d89a6ed461469565b8e52727102da141d60e151a14114408e014f14d043059415abd1084d035d4a8318e8966300514b59b14a04e102a840418c1dd7ed8f5f64ebcf50efbb19c0808a5e251814c14e498d4ecf93dde41a40d494a869c5d8c398baa8498e6746fa1daea1b5076c7aba0d3f3dd89d154d035d84ffe2c380db638a273d7b9560a0d4cbb2b5db5ab696da8e1e728ddf1e6b7af0233dbc2c122f4fbfbb75146d31d069a9e59c5582c1151b96ba4017cfff19825f0939a0ed8d4d0d8d8c19991898179716962e85e2362d3b61179d32325cd8fb1a3466d8d4d0c89891898179716961e952286ed3b21376d12923c3ddd11dabd231163a3e7666a5b90299d451e9bbd85e4c02edf31cc508a07842044eb08ba2bc75a28951119310701393f3aecc410e63c4010e6f70431bd820c61ad49086ddb1bb6369762914b7695129ea741536c5545d0c55ebd7d1facd6c9746a352919cb9aa4f2878228fa01843b69ac4e819bfd861b81475622be2cc1f61485d7cd2132ef53c40979d1f957a3e26451dd806089ba20e0d84311daa937ad2687a3d3bf57c7ea26268f447d3f35895c9b367031ac800062e6081222a408109102181084000c8100f7040037e30c0871041f4e059800256bd330f95b230b1794dba33959865122a4a0dae30b2496e1f5b851b54010746362c685753d36b9003e2e90e7f79b0b50ecbbedce93b7c61cf60771e64f1160b11e4a0b7578af6e13e3801c5be0ba3658e45c31c668b96a25dee9283282b997f444814e856c909142d73d82290a2b56b97522853764dc636c361cfbced3de4495db3d96ab8d3593cecd87718c5920126205c2c60a9e8e0712387a780eec3528fe178f8301c8f8645c3c31cb4cb5d5a1e391e19d7b67bf9723c3334466abe1c0f8b55de97e3d9d1add2132a1960153de41cb05ff413789aec355238ef7b7359167393bde65ae6c11a6f49f66fadb058459f7d87636e6cccc77f528a4ccc067bc0ff345c0f781f9e8473e8693e2334d7368fc64bc200ddf66fc130c22afaad2661153d26824e9e32d13ce12e83eb015f236b79f4bccb97bfc6cce9b4fb70ef7c967736d77cf034593f08550d7334a44c3132c7acd041ca6dd2bb06b7ef008d4679a0047330a242e63f4132a897d7ccb0bcfb4f10cbbb6b9aa6cd2868318334bcfc27e8e53277a99f7619ff5c4e13131373a1998ea92fab82dc59fe13c49de55dd775f59351bfd8842c14654146e61da069997f412eff0972f9cb63fecdc8c8c8c8d4ae439dfb4f10eadc59585858ea1753bfa1277411041abcbcbcfc0beafe13d4dde52ff5cbfef20f86858585a56e9776d47f82b4a3ce711c57bf97fa8140074cdc10051717977f41577797fa9dcef2af85e338ae6254d38e42a1de011a8daa1f4bfd2e275a705282eeba7780a6bb7f41f43f41d7e9bbfa61e7fea55028d485661a55e5aae00f3ffb4f103fbb764d7b0768b4563fae7e120550b8f0a4bfad6a9a76a199d6eaae0afe0b9affb91e14d481abaf077500a6af7780e60bea40d6fca00eb834bf03349a1ff493fdf41f7e1067270ff3366fc6865542d40644c013349bef854812759e441d1a5ff8d5397d9f44d4d1e14bf3ad497daf2306893aff1e1e459ded6be3fb7d8ea8e3f27d1151a7e57bd88a3a3b7cbbcfd4ef97c0a4a8e37100a81fd600b88c57ab910f3d1cc7613caf1a55ef3767f176e0e13b5c75ce7b35c271e330d73c1bd5e8e6b771ccd3a11add80b90fbf3c9a6ab4830ec739f56aaa8dd7ffd3b3a9463436678f4635d201e7aacbf08c6a6eb411e7db292268350068fce5c66a068ddb3ce519d1a84e7c581971a7719a6734d5096a55e335d548c653b7a94e605646d7693ee31965357fb98b6754f3729ba36c8efa4b75125746324ffde419d954273856462cb7413dbbf48c50d5c9015646da6964d589cdca283bcd6baa93979551cde55b3ca31e705427325646d8697ea33ac1564635e747cf888911d1ca876af31eaa13ba32429dc661aa93969511cc538ff18c70aa939a9551cda7aa3ab95919cd3c751ebe79463c5427d9caa8e5363b5427a995d1761ad7a13ad1b132a2a779e7197937d5090f2ba39ac7bf3ac15919c53c75fa0f3d231bd509af8cbadb9c8911d1aa5627085819a54ea31a9d5eee72277045e35e75a2b3323a9da61ad1dc095c7dbe866754538d9cc055cd69649fe119d5c8f8cc651e73983b812b9a6a646464943a00bc21a59631e3a9643c20de9288b387d9bf7858c4d9bb783922cebec52b22e2ec593cd88a38fb6e9ff2509e0e2f48c4d96f7bcd835122ce3ef34e1ee625117156caf4a427449288b3670f3e89384a11674f048770305685dc632f10582a50b902131a8cb08536e480460a504e47316081c4ac68ad800b67408114a05845191da748a14ac7ade394a3283a9e6015639431a6778a13562215f28451ea04199a524a23c6055625a54e6ca129142b4a7f6c865518dd6815559aa29ad2bf2c465594becb02075534a574d61959bb99d3d69b0509c2d0b3370b2422602cc798999999f979620955d820093828c31a84e0022aa0408c3158a1074d324e5c7172a20831c8d1050e4e4d9c884146050e64f47ee6e94f4f06a4f7d283d583dcac3de2116888a6e8e5426fdd0f3e88a8e7e57ccfba005611f50eabf81ca5e329b868f83d134352d66fcecb2abf43ccfab11a5ed69a1e7bf9227bb997bdc3bcaa85df688529b480310da7b8a2e14dc3cfe8f818cc6ef4d7c5a0e56576e2e2543d1b56f54a5e555f677a468c1714cdd499a8236752f10c391ed8858ef6720e5dee1d56414338a7989166d105156051c44aa7134f4e51aca4ece68775172b060a989aa23006159e800423076e8a132288a2091a50537681a57aa734619a5668ad1c3a32a3deefa8e2f2b8b07f377affe9e85d2a2ba98e5c2d144ef3babce8452f246854a394be64c1842e6813934ed905265ffaebc4900222200b2b88c214123881095dace27706eb7ab3608214fd759765e8e8c6255e3002145cec008b2e44b19a2e3d9b50e9197b367142cf14ace66fd8488e6db8822fbd539a5cd15a6f165474a143d236eab038a907472bd6109f35a4b1a14969c51fda24345db1e27dc36a6895b0e26a058406684245ef1423281a47ef1423315a52d91df2f1b4a9239410e0157f8afe4efd4928e5d2d4ceca0e7fe25ec4e9db79aae8bec32d2ca9a38eaa4c684f7d572da8eca8ef8a45cbacb0d056c7b7d02396161899f35411a33d951d953a2a85dae8938c2a75bc46a9747caaa3481dcfd1242a8542a151b4e901c9a75095099667df55ea45d45040bbcb5d2a132dd7be2bd483d8a62f7761f9cb972ba2e52e9f4928281d9ff2a274fc8b5743ff72a295263da0790ab050e763a7002b75f8d3817e8ac0bebd88d3bbf354c15d835c112ccf0eb9225aae0129caae3dbb566baecb4ca5160f8c8e6769ba2a90982aa5e3612a95178fa9e35dbc1a5a812c75fcac223dd8278f02fd04c1fef989c0aeb44760572dff29a286024ca05e440d054ea99fbeab9607b11a64e128803acb972b22f5ec920aab628b279764959a79ed442bea7d148c8ed7245704aa885404765584fd74c92d5704acf4546be43b307678872712add2f1282f1ef36a6405c255c9249b346f234ee6d5cc0a445a8938442b28fd711295a52f56e96b980757d813ac32716a9249bd8a4b56622b1e45a54825e2c4a488b31c4f44da155b89383189a17094a803e18a3d0623e264cf2a132725e86dc4f9b8d650800f0f2b13d8b96ec4d9d5ae34b8652c85551108279d60b68235044301e8228b00749145b6c26a535b69305a8a54a2001f3b1fab117a351480c70e8fd598b41c90b8c3324a0423ea6ceb894c9250a20e2442134d28ad62ad9952a963ad991508af3e29a5e36394a8c3c4294a893a4c60478a50a252a40246d4c95981184d4d495167a52c451db88ae72a516757a7133cc1cf1a9f441df8cab28202f00c3f68027656ab85d52106c3d20e5aab10442fca8082d68aa974e4c7483ba2c92d31c8420e3c383272a2c846ef94a22f9aeb42d2346439a464d2022ac268c2155700030f56b1a5e314c6d0315a7943c71c5d6030bd53a6c045d3de2c9c5081064672c0dca00a383092836e94620a29566c008720bca1052c51c0785094a38b12b4400d57443004278ee0d0696122a10c5e18418e2e2651141d2081490bda8005264cb1922ddf3d81b6ccc209155ade867556e986757695a30b6cebcda20766b0018d521629a1a5939594dcb2a3decc0bfdd7f50babbaa8236511115a3eb19252d28acd29a52cfa41cb262b29e5945c2f12cae00569746323250d5f18b999324551ef14183c6901f44e7941181ab66011e7c4df484cd60f835de824769d8ec953ac58ed5845bd971d74f22dbd259c23ebc76aeca7fac5532e085a5fbaa8932426d14127ff6d531042ac9a97c766f4b65e9a4f22342f39e7bdc3d2db5835a715dd7723928006a041b7535ef045cb2f4db9feddf878ac16bd540504eb60abbdb61ee876ca1ac66896de296b30c16703450874e42afe9556c92a798e4d44d1f1927560abd56a3159c5bf54c845b75dd4912bc85ef7c238f0900a9d4c6f164cc841cbde29453ce8af6bca310a6dc2edf8b27e333da33cac5fc7fcb995d22a8379d85a4aea6cdf6fdd8bb679439d761a19e3a9a3bfb009977380ecf9d3e47c4cb88cca5eba269359058272e39c58abd82e2526e52f4f3e4af939b73abb222be8b96fde2ed1c3cd216adab55aadd66a77c746ad5ac1df596be261cf4b232dc2d7c4da833b9efbd402428aa517aec58409fd9d0915fdddd0a1bf1c9f8e8f476f64d815ad1251c3d81571140d2e330a56e8846e6b915d4202c7ead14c6925b9a0eb20141df4a1db293b38ea9da2032b00e89da2032abd9105f3b68e55113bb1602e48eaf8b85bb48e06f0e01c54c7292dc0a2e36f72503a3a7ad735ded8f330ef66a3f41dab28cbb20a63558cd875f25e5875a290a391fb014f8b30ac9d0de7709d61c939901f3907c02bcd55070c407ce4f8051db78edfe8b03be8e335b9313744d3caaba21d2f391fb2bfa11fb1e9b5b8514f09c3c82b513fb16985dc71e1cce561abf402a55ea5176cd1357c20ae5564fff4b65f3a1e8bdfd8ab551c7d95d56de92201448a2c18abceaafd0dc8f2c2aa1afa9d22821cb4aca1b5c7142fbed0894a7b21880862848b6fc52892ad258cd1dfd6455b142b360b2a52f4b7553a8b2584d135afbeb5d27beaf13c518555dbd3e379220aabb6a5c7f3c415acdaceb15c6f7bc1aa5d95ec58abb86155f761dd6dd1b9f4d7f54e09c10d7abf718e4beff7662f8e3e803cb2a0483ca535467f866fa3a5e6275bc6c8fc4159a906afc5f8131b7b1051c7f89dde279bc6f8716bb07ef4f25afde8b3cca3105edf893fa7eff420a2965faf6315fff26013bac9f998f3a71789c7e47758d24f4a0fdbc73cad5f91f859247ea3de9c5e11790c72f186a914c884eeeb3ada74f2b2725764057c93aface0c76b809923471d8e5f22f85e0d11b1461e1ec8469c0a015e6dc4814390087206b4659d5d29b55a3ba369eb5db4eefeb41f625f04620c3fa7b719849927b32a59c53207c2650364bbf0b3ee524a37aecdcc4bef4729a594524aa164156f9fd0dcb0271aeaeba172a03c8d61d4e2c6eaeba7d349d34e274d3b09318fa6411951929b1bd5ae0c3b9db0ecd2e83639898a29ee20cb8671cea2b84dcb4e580a0517c77e524cbbb4d5ae6db920389476a81dfb07f75dfce974bac6db3c9d4ff12fa7cf64d9e1b3c32a04fb94d54fe386d07e3a699aa661daaf6b1a9c1a4b4d83959e344d63ef8b63fb769d4ea793a669da09c28b83f01e84106ad1315d8e72d20b2e864ad2a7afe669115e1042785dd775413835583ff80bfb775dd7755dd7755dd7755dd7755dd7755dd7755dd7755dd7755d9726241bde68de6234a722da6a509b2c73201b80b533d4bc0fb6a67d35d6aed5cd203c61f0d7f4e0f9dd067d3883b69b23e5e399f99e8c55b20ae64819d900cc9cdaddb1ff987999238c4d68da76f05175237a1fd4a0ccb499edb60dbbe90c634edb2e5e9a6429e14ed42e0ef91d9652568e4d58498ff2b04bca2ccb3629b32ccbb24c13ea6febeb9ae4a4945cfdb04e612814eaf2a80bc571599632b275263bec24e92734a50e1ebd524a99fde2fe5d57f6ebf0e2735ed4b2cb2c9352ca0c75eaa1342e954aa55251caebba80b86e34fd2e356dc0e2a0d7a494524a39232abbcca49c2729a53cd6523e7589713ee453f5cb86c85e449eab524a2965964929a5945926a59452665926b34c6632cb6496655796655996655996655996cd286596655996cd286596655996cd28e525a594524a392394524a39e3553facaf4c6659966559966559ccb22ccbb22865966559964529b32ccbb22c4a795dd7b32ccbb22ccba4bcb22ccbb22ccbb2986559966551ca2ccbb22c8b52665996655994f2cab22ccba4ccb26b5e9332fb27a594999419b7945266599665d925e525e325e325e325e325e325e325e3954929a594524a19a5bcfe4929a5e4969fd73f29a5bca49452ca28a5bca4943193524a29b3ecf35a96655996655996cd9865599665334a9965599665334a9965599665334a79c96b928794cfaeaa2393cfe4af7f59269fc917c9e445a54cf527a58c39aeada3ccfe49392f0fe5e57d42b2e7e3acfbc5f1dde83d9cd241edf3d4db591cf4d3fb568ba62f5df7ad7e37bda1e2bcc63de378b8efe9cb39dce15722a1fbba66fe0be7c1ee3887e35258c7631d6bcd8fd4e3538f550836f713e7233e55bf79aec6c871dc9c31c6182337a7869a71cec8713372dc9c91e3e69cdb16b36d3bab366efb4eecbccfc84dc76faacda3dfb079f8c918233dea9a87ba964d2e954aa5524f65dc27149b7bf639e79c73ce396d3494f7e9686dce392737e7ec3056695fce99339b736673ce8f3bce39e79c73d61bacd2be1cad71f5236adadb30f36473ec38b7cce39674cb3cd8f3dab21eda5ea8ac468dfb17638c92e3e19e5d8859e6c8c82dc43f22c739f1cafec51863c6714acda9a00637f3be9bd6b859cfaa79201687163feb175be6c8c8f1ca153600c73d0f5f0408f6958edcbf39e7f5a869df899bf719e1a17939e07e66f5c6f49655a79a9d324fc6d35f308b0e1e25eb279bb9b8496d66f4a45d1bc6391f8dfc3767fc1c22bec884533a18eb263dd85ff48cd0416c31d4b7a453109ae0081122210a1abcb971430bc81ca3947352ba5ddeb55ddcb2ea03a2e14f9f2fac923373621293584b4abd65d5a92eab727c360de18f7d4eece6a6e3594984667a592555523b9db646efd3d1f152a8e312d9c9fad2a77aaa9f8e9e3a5835eb6764971afb8541a54edb8b4e19195ea86f49c323747c283747fe9b758dd0c9de1d56c115570c664cb4bd59128f06b08a32f52670258f6613b89a4de0ea6a0257f494c57c49e772d89ae9be7f06b17aaa826279cb09f5d44faa65b5d41c5d65a5aa8e2ee22c6bab3b33118759a72ac4230eab224e11518785e5081275589d8e24a20e6b462949d461f12f0f2279f089078f224ecb5b127176c90a9492e4056d6f96441db9df53ccf78b6acdf9d47ebb6fafb3bc658f9d4ecfbeef34ed1bf7fd0cc7dde5e5fbbfbc1ce64ca2cc63be07127558a8cba76a13b84abdeb4eff2d134b6d02572cbffe2d182ddfeca76bdffee5e0eef24fc7cb6156a6c2274922ce1ec64bc283485e100f1e794578b0e501f19678100c0f2a799029e248f16095881325e5c1250fe5412a4b4b6ba5f91f4cfa546b45157558f139a20e8b09f9a9633bb7935d3b93182f44d4c17e3a13f4d7b78a75518795d52ee2441d1656671e755857dd88c39a5555b12a5713b5c2f08a0e689e7e9fa11e4fa7b398e0b47396699589d376f98d3a5b65224b1d6ef08aee07f6456565b49d75348055aa32a131b15dd40ab51275b86ac471955a8938f146db5621951b691a54a2568cb233c16e94552911279e5a313a9d095699d895d10972fdae565fd101d1f3a1103a864205ca2a293535a54b100a94a88355161625ea702b8725295167c394a28ed6c5432a51273b55266698442612d004afe8e4b97ef047f2210c420783d07d5712b5f25d49552014eeefa27251893a104ac489c7b0ae9bb9a8747ceb4abaa85c49fb457f74895aa14b02e88fb62814da9a51aacc282ffd49a679c4947d1269f61795c0884fa21237c52754b889a940692b5020b49203b63eacb74a8e0feb0885d049e96073bc30a2c92828342ceab0984499c92bcdcb6f9ad23156aa2c8c9e05e55951b06fa7988349ec4ea824adcb96b60e29e2c425d64224201a0b3305a92cd8741825b54a5b6c9d943aa52dc7a9e98a22bb262ecae917cb65ea3889fbaeb02775a87fdba5ea51155be2b63aa3219d6696865c5617444a1141ce9ea0ed8d0ef68b461df93d93f8e93189d263122f8fc5241ef39844990fb9ac8a9a702bb9d137812b2ae5a7c4de04aeb079daf92670353318a6ec4de02a83a9aca226dc4aa6e828012b9837812b1899ca82519ac0154c65ed40a62670952509d204ae6665c1a5cbca824a4de00aabac0e26b1b6095cd1ca0242bb092554a267fa364dc854875c56f35b875c56f2b08579d49bde8cf79bf84204f95ad2640460c52432d56012c768d12c8f2359c33c8e5e662c8f231b1a01a809a8e488d8e983991a0419630acdd048838004f31500404824148c46d33c9014f10314001090cc604e268bc420c721640c31841080c00000000c88cc4c4200fb01165d13783be01973d931bb800f5e6394b05ab82a7b0ebb24a0b9a60a1cd30b50f9913dd5e4f582c6ccdeb2f5d67b7e7b1196d5bb2c9f8478b07b55f8c389bb0386a4b005955d62fc5e94390341b99f644b128351b1fdb6576666397b61e356ffe3fe141be1148c0844fa06d4a0bc0d9f874012742852fc627597881825a1fe4d84ed573e4a29841fb3711d3a90c26c4fbb071959614bf5ca95908e41c7765c0b01a2e7101ca0968d444caa5e61099b312e2f1e5626e32ee74c592cad29a934e89fcb3de0db1ce0da507e8d6755112bc78a345cf9878437ddd297a3a76229b11ba9cbff5a0f662fd21b80ff263cdc24cc370ad706bab7c933ef3ab8ff2d438cc78d9d0f5c1752dd65685f237ce2053a4af10e9865251c637daa4377ab6ad456b524ae1dfdad75db3254959e694de560ab9744a966445ab6f3acd5ee106da0c741891bed7ef010165725981436c20ca207119a18af01ac74aff4a7b7e558f6479d3d167b4b45e8f4c4295019a10c039ece03093ae0423f7a05ef472ef07610ad1abcd1510fbb080a4d4f9de563cc3ab14f709991ccc4b59336b9869e62ebe5fa41299eaae9f789da500dd36388588c8099a467d12c195b2e5e07cb7b6a514db45d71058666529209497622348b453db36385ca3ad731fe5d48541e4486e6622f675219fc8b7741e159e36aea796f46bd05b5bd467b1b8c5d5fa013626182f48406bd8860bd22247ad10b729653aafbb9529465f4e659b78c10bcafd8128ae871a0e7e459c2e244a953b25c6a17dbcd6953b19633297e1d87688c93f9b205cf3cc58cd987305ab35affa1098409aac284c2e68d20822d11ae82835c4c4ae7eb4f50c0259f6c9e7eb72a019c67e16d54fbad9a2baaf6ca0db4cda66bd5a6e7d5d9102e8e0a2edf6ae7354f716575889967bef0b967a116069b495919dcdf38512a70d029065e806ecce961b9bb0d9470980f2baaea088590a05b43a015d342a45b109d6e4327b29e676a4087ef70bed11dabe024c867a87e72f2a83d6480db4372a06457df1d31404bba58b2412b1d9bf2cd7c71c3109eeea44b8503d93a992a4bf437aec828e034fdc2825008c66399576e4e803ebc2e0b0d871f4e412beff7df1ad17fb7e03035674c511e0143ddd22fc2c02537d33a1dba33ba18c1f4c4a50b1ca35b41bcb946afd2a3bde25cf51130f5d8bbc648a33ec40ac5fe4c1922900f084057f8b05b850368622931c236776072af99cba81b6444d63e0e3ca8e0a1db9bc4f973812b7ebeab10209079ef84cc263b455f5a5c893b13b235eeedf9b16bcaf285a7407275c008b2b680104362d2f2c8164f5df7893c27dea868a2f61bee93b25510fdbc86752a0f8bfa4caf20bf7116c560ae20189b7c1706aaa01de363a2f849e6601fa10f7ca0145f0ec37941609838167af71c5c19826d80975c3a103167dea601d9964cea3cf44fac6b2d0f643d6a7f337f6e721ba3491431cd2e7b05026d3d1bd5bb06be19eb7246470666fcb976c77e579612d0b318fd15d5c6c32510b54608fcd2233d0a209a8c30884b4194a5a632682b8939d5e87d4d755f26c42366916a91f845a25c3f4ba249fa16ba7e8cd7548d4b350da33714b9631c6c5833ce098361f5348a154e75163fc2e6e2091a2db64c6191656cfdf52f8fd71ed4240fcd0861d677d31f3743deeeb91b742eb785abe2ae220bfb462d34d36dd6667b3017cd303403b0bacb4a6b019fd85397caa485e74aedfe79490192f3dab2a2061156894efc749c9fa1597adc392ef142c7a093d7fac37a2a50ec89c8d8aabd158aea4f9222ad29047a2952048aa89440691944dc79c11594b1bb14cd78b22ed6034b01299210cc6893e2050cf4c740382bcba4f6a7aaf5ca912edc2c89076babcf91dde214b175c382da1b82f68e73ffe7eea74dbcfc5f747d69c8509aa016bc9c409be8fd0763a26d7311856cfefcf197bc9199a92501028d8019eebc4801a6b98c81ba2e770f058ba09cda04c69b5caa64de3a7351bd4ac8b434699e3f679a56265b8b8dfcb753fa064ec567fcdd3e1c380f3ef01c218330cd58db4c1eba7b5bebad331c3d9eb98b67562d2642c27d0762ac1c0ee138ac3e568be5ed38adbf4343867c883487c8cd6b07e355ccf24f861484fafdcc1a374045814268326c98fe198d9e472b70af029a0b85fc0bf69aabd2ba1ea0968292fe04d061343c67b7edd6644c8941e8afed7c7bb8b3f43834d22fbcb973a190d81f8c6189a0eafa985d45b6db4a00946d007cbb6e2fb4d437066a107f00464e0303a3983a0c73421b0f187a75b6766b01ec48ea733507997d639f417a55291fa6e23bdfcd62b5243ef54a6f771e99048c86debe0c7b9d00fa10372993eb5119fe289b209be1d953704a0a7b559b0667b4f378815272887fe3cafb4892f5b8aebf5805f7fbed9537e8b734df0004e469f1e547e967791e5352077f729a909ef834856d359485fbcc8a20dff266aba14361f69587bfc7837545fa9cea748cfd9300f54a2ce01e59afc8bbc0c187c7526d73a2f0053b7f5b924f95e28cb7c172b160c07f44d85273831adee2745fe8f0be59dce6b09cbd2c5804b694a701e2a64405ce9d14e2ab785450e2faab8b3b5899d729ae9eb8ef5f3af6e3876eb109f54c33333ff1dc405972da986effc43e0b28e61bf8b9491688e3202e4570e2ebe7458c570f1e44513d33069f822c510b7cd1403e5405822718c28d3b3acfdf8331da8e12235efcf56d5347465fadc0ba13810c72580cd76ec5d0948852076e5ceae6c56d9b9449450330bc2005ebeb7c549c895a986c5b617c21f3d48568cf1da0c46571e39823336ee293e5523b1164ccf41d3963ac320658c6b5383d257e83cd0a6b3157deb08e09485b79e5fda0030e91fd5e3ccec948bfe12fc86678516536601857afecb64353caa0dd90f0bc95b73de6bf55780519f7882e0d0ad7cc3e93a04f2e92c73c50b6f23f8eacfa8da731b76ca0bfed9f3df17b0531aa2fbc78545758b357fa634b5febbe2f0ad4c3b2251c3ec7770f179a37c3f7d4107fd561654eb291677b3aea3759494bca9c00e4b72a0aad1f72c1e132479d6d57759436998ec3481514f0eab8ee37e88a7c62040ec07956aab9d7b3e4101998ef34c67db5ed4714d6fec55a7f8a2684fe05b55199d38c4c7bc6c410451134a9b690058f7820a7cb2ccc500e84fc87cd8d8935fe50f5d1381b05bfc68a7886a82eee0bc5218b6172190b208b4bd57eb8ac5ed5f77525986fe397c1cd0520e59a4dbdabcb13462201096e415b0f8c7469e454b1f76ccceb43ee96848b9aa895f56a803caef52a13018465acda3603c04a5dd2386efdf08e3c84394c7b60093133a02f99a7c4bdb26a85afe473ab89541a4808c86bd4e63bbc4ec19304ed30754425299caec709fbaf9037b108aa0b8110b52f83f54860cc6a242a364883dddd6e98086a97a105e29194a155910e0fa78d26cff03e529ab25ab1d32b3c7dcf5755c18637100927498e9e8eb16edbc44411505dfae2d0a7a1d25031b706652c9f82a816adb931f85a9438015d98b4d0f8e9e57dd2afdac9b3841cad065d80c09e282f8c03e3256bc3e967d3cdd94a6163f80641e91e0616b503d9c7385d89055df6f481d8a293e1a63688c2bb4e6db141830e6c4315346cf04420331ddb9985792c4f719f1c238805052a6a6db2249c175e32c74418df86e522aacec4a95e55cf368378721c32a1316883eedcd2dce8951eed12a5a9d9463e1acc1b493b5ed1040debc41e77aef40ff7d6d2f7a29e6b680133d5e4710317b5ce7eb41b042ca055fab5675b7ea539d7c5b692b07fe82f85672c852e26c4fc0ce5043bdab942285e4f569bfd10706cdfbe3c52c351db2e2b80d6d15b0ed72113d31926b8ceb0b088ade9eef8ee0b5a6b8ca1aebb89ad0349149fcf2e4ede77a479e37392157c0782e517592d0929e88f30e6703962efea93c98503034e600e6941f001f548f6c9d12184c356d96051ed6e5b504575cd68001738aafb1437db0272192fa2839dbee3d1c25062f320abc35939d1b1d2459b3191c7a89dc55dc169842d9c5e041e72bc410d8f18b9f16e26cea3ce0bc09db4039451422225fdc73adbb1101e05692807fbb3908eb4b71f42f4c9b3fadf67a4dd59a823cd589bda703cc832f1c5fc7129de64563ea2a43eafed544258697c272dec981a074061547a96ab1d868cfdb9b36246ba7e36d20ca5528adf46b2368f3a2592c48c5b09699bddf8b3abaefa86289a2faf1019ca71a4b335072f90a1c0bb9940a50480becf61889e7ece1b223a1a2c7cac6a9fcca4ebbee88817b804221b5fda2a17b48c3e3fa321bcef7a9ef6b42e58c43395082a195aadd1e75c248a047a5ec967f649b379e1da623e07915e9e80238f7f2a7031def86911044743ed1305258340b82aa33b97588fae80e1d07a115755611bf9742df484143297cbbb665bd1bfbc170e5d07507775ee82dd20473d51d5bafe87485548dc7d1025139411eb8c00c8716fb2e47a46b5103c0a1ee6c51f8e1b5099bcfd8b55067bb3eaa1499c9f3d9001ede8686567e9600865b8a27d9d899f69382ad2e11a7003bf4484092b536efb506642906148a3b6b59c6001ec4bc226ddfee6dd796297be63aa534c38ba0d1018a2eb823681e92b58b9e2bf4afc8a1079e6d3b6f9627deab7a636fee4c0580c33adc755f9e9b7c8f1dba658ac03096d186d6833e95e451667054c06bb795fa9362ce1b06afc74b90d22d311bd89a58a5ccdabab9044b363fc8a340a09a721ba8550cc720381907047874e4074c3c24a6a8970c1623799b6266f3f61b7762f84315be4599a8c88fef16bc9c4c7856627e219e61dcb2486f0ec4138b884b4ea39c810021a0f35e07c0d0a8265bee1a66a6da854e4fed7949c72a582f5d74d075f78f905e2f759fc6456becde2ef59f263967c9ed5cf67f1cb2cf99a95bf67e5b759f87c163f63d6a37bf862f8cbc9bd1fb43f5aff9bbe2699965be07d7fbb2eaa585cbbf29d5b1d72dad4e635f88b5a39c3c24da4f3018c5155f2806c6d45a01a05fade4705aff9859f211c75a66255c6dc07d466dbcd9d936963c6a470933ff125750596c3f4c595a47e9ef27aba38b870516e593aa041191e8074de7f63bb3b56d6bbb99deb605ba05e1051e04f8f07d55d7f69b3cb6ba40b7a8138e495e2664b25c6d944ac2eca0c016790ef31ebfd0557e634c40942615764589ea86716bd3bd3848b732551295310d3398d72060423298694fbed6529b97e2346a479a95b819327cf6bf39d1dc51b72a16197173f61a2aafa861e99ace8c139edfb308d787c2d46391f1d64fdefc163c49dc9391c257e98a1a75145a4847c15525910523f522f62931268cb41f0ed235cb7cf8f3f97e833fec7be26e46010420d98ead7a6f003debd0d56912924243ca992ccfd185e52020c45ab462ce6f784a7acda4cc276db39210bc82b33c58a21fb1f48b58c6b63aabf278bb077227d70964ef18295ed2cfe2ab70eb643331307d999061d84785a846bcda2b5f38bd427a0d4bf2df361dcb3191160dedfb244a2a47f2b6bd4e4fee21a8fe151aee1f6f160457bef7dd264bfd828221d3b7c49e1bbf671ba5fba64d88a258a2e0d9e05012ed605dd1370c4b0e958ce3751cbb527c5e1a283975afac551e0c7a83431eca26569b71330f7d082aa18785cc0cba2412a7f780ba977aeb105e11e59d5fb3325973bc0c9a22faac53a9aa77a812dc682c88250a5961f6c4a9505f323a341c0408c194d4a4e850d5e7bca646a6303611262d044b3134953995c47dc462a25d708838647c26ef81da32fa95e9f8a314e42db4887e6074d49f71470597830ed661fc0e42a52ab3cd0fce5fd344e3964367c263c0af6a2077fd3efe18d3fdcfb789cd4dcf8259280ebc0986dbf62433bfe78d36e560a58dce3b6b036e3cb403e04d612929d3ac038b46c6eee5ec8f04242a03efab5759803dedbf8e0cbdc4177a25cdb044df99e184848f6ff5a43057fc22184505b6a78f95e837cd035dcc57066b3f331ef8843adb4474dc0b03f993e3ef96040b5352f490d8d382c9f99588bfd44a64508839d9d329a898098c9fc24119f996056808430022cfd5aa130d18f7966a3637a33b27e9abcc14793b39821e0a7240373fea34e74aa286061f18cef497a43bd2586cc20625f5d4d1856a653633691d89559aa2c4294956aeb9c6e5c4defa747eb1557eff949ed9434e3b1c68ab8196e689f253929498a6200d62866c36a81d2b7b7732e261d6dc44cc7aa9d6f45ca1e9e7bd40ce0994eef648fd79f0386cc4ff4186d2f58d493389d20e5dd79b509ec02382555301d0aba176bed14ce7900178627695a0a97f8e3335318796bc3b41b33deccd7ef23d5acea744ae4fe0e290d90c25b52bf817c9a4a7d878ecc43efe7df3311355a6943b7d94b15eee80bb9341b5d7de6e8ba484f88b0108231486c2eb9419194b29aa9f236dba2c8ff1622926c549b103c3e9326e460e305e8ca47dc3c6f408adb28b5637388cd8a2ca2fcb3d52ed9a8961d5f7e5f0fe4886ba3b8af5726a7d98f84a26caec170364ab98e2df8db1bcce0cef3e26ba16ded5998a148fa2cf1de81fd7cbf859e8ba3ff3f7ccd14a000f0bc966a9ad4efb751b65e88a3007d64c2f25497bfe548f741086ffbd69281ee0fe35343c1dbefa28a816dce8b29cf13ad518f569db56d0f43817b7a09baede312ee3660202c4788c1466d4a7fa12f24464986f1d894950eba7cc7d94661e9a2aad5dfeb20cbd45f4f174a3988ef1a4a2aaf7a9bc514b0535de620276731cc2a777dbf3b8caadfa98d82f23ce957b4dbba8a588c2cba8ea043eacf327fc976a60a1c8c0862ac98644f7d9d7d60f24078eb2c6cbcda6b1a59003c759d893adcc538af7835ffee155a38365ac9733ce8b6d18b9dd60baf84ad98873eea038e019f2aea079f1fae37c2311f8336ba7ab3c126d2c93662c48a63bddc6e15f4f28fb0cf72c174f4d296f55af0c318c4bb8df67f34993a6eea254080e4b2a474874c08fd852497472957048cc165a002f2d45530cac74b8da0ceb7db0ab0d66f5196c82ab39d1d0e742a0361a41ffee3e3e9a066c26d342649d5685d3b15017ad2de5858efb10f38555982102fcc02b3d1adc0dec911dd2b6ba3b477d575a063d5514d59a56b3c1b072f0686d41c52741e6612d883d3195ca6df9a1a4b7f1b8d3b3c96183f511edcacb787134ec6461176f8f3898e425b55a30f2766fa84c1da4d2b4c4c7af1aaab8bffcf1880c3e2478ffe8ee6bd48cfa93294d328ca2ac01489d5a51d3d84bebf2f07b984468f7e7180ba8f2f349a7c3e2e416195e2d92ab45f342f2602caa8d0b9739dd8ead23012569241860d2665f32024f0314b8bac5de56eabc6af13bd72bffadff860c5e664323110ac8653ff8bb37592e0181af5ab220e8cd8d1548c63124a8d875322b72a568567fc031ea5c460cdec47cc3df65ebbef3abb8158ddfbccf2c78f9bdecec1c95c6f638aaa14ead57c10d2eee7474f24f6513dbe71feafe1966b90b4e9b2cb6f1da894f2c08d612877ec41bd95585e6e4300bfc6f975b0069e3dc114d40a5f008ed023ef2a6c9c44f91dbe551422cadb4f2365249d551350ce1464f330e5e5500077bc1b3a1cc511ae0d5b7d8e0a5b8bd6123dfc22929e0d6dea50f592df46ab15d7151536ead5f94b020149e8e61da3e40de33042b59121e0d62cf104617b88d9b9c9f50a882d2e1567c6d5181306da88a9a6da52b2723bd78f583c332c27bd34a7ec2200f252c3a542e50e7cf0b6322576a24fce3a8ad8bd564511a3f59a4a6cbaea3e5d43aa36840b120b91ddf1173b38d9da20bd9f8699aca811e8decf2fb72d9ce449a5c9dadcf59cdee12d8ab4653a10c4894deb0d53ef84d5d9575b32ba8814d3e6b8a56082768d26c236285c21b130b9c9520b385464a89ec4dc18d9318aa783443a1a95f86042115b510d64596e1c29ddc5ee0093fa9102c6c3877cc8d762433f58ba0d1e42bab97c8357203e41e78f94be83bcf22f944337975f358bd09fc5e6083aef2d960676fefb1a1120db967b45820689e8a74c0df66e600402f6b7b41b85aedebbbfc888585a0cb597e78547ec89c2dfa968b125a00cdeb01988db0a3caabd135e227b3c7112f9749cac5da2c1f84113acea3af6d63f39bdca5d303abbac5c0e3a372223816c919923aeb78710925a4582e0f842d506e638152eed8e426bb540142fb12ed7403b46d344a29c25f97cdc69e031254bdce67b76b370a9292c7fa3f309c3ccb56611b910304693ab0328757b3719b17c1ac50cb78b5a6632ab12f1b41b5d8921145b2c8428dd1602db461586ae90586029e7da447e9730518e7251507d3ac1e2fae7c721a6aa9975084444b82a7a3d0e7c46ee15142cab895b34b40fef27f3307190dbbd5bca76ef94aae9dda5b6bd6729cd7a1902fcb64045ee68260c2a41b425440193fb3eb44fe0929fa39387343e391cad91b02328dbb909c1a05a4e58c4fd73488f95eedbf955de86c48dfa6baec2f60bf9aefb5f7003b8c045e3e54fcf618ccd5e963fdb1597f9cc16a4e77e1f37fc8f17666d9a4eef1c2fd0ff6a13c6be58b851d4adb33f59e17b5906c34e28fcdd09056e25cdeda8f618cca8fbdc61ac7d2c1bbe28eda3c3889f130a4650146c6c73426436cda2503653ef7729d4b105d720259a658b114fb8a64f2ed60884ca2037d1a751d422642df6ea26b8de71cc10bffb1799620c6b2c4c6580b5809c5e64e829e3c3131cca9619112f66d8a8266a65cb5ee75a45dab07a21339c84d118f7d9c6bcddf0e7377727f3dad064e0169c7e227c8d93b78866d8524d5b0aa0a08447fd9fe8b0af387651474cf6b33cd063379bb3fb7fe593b54819dd76ebc76118247ff0c732b835ddb471017c45eb1894a4e5cdf88300c75d2840363e953ac016dadae5d555ab5602122fef0c8f19fde75775d8ced559f17fdc3e69ef712b2bd1a4972f7c3e256fd7581d50276b3bd3ac419dcb7a8d040bc6866c52964ff3dd100553819238dddbad14f78a3d06f750410f0114910bd6979696f5c219165bf84c8c2cf2d9c3cbb6d9fbced1a2a84f1fc28f1f9254d10267960e9241d415ce8803efff0b6969789b96df6716e648a8fc880381d31fde2bba876026020b0a4564550189418c758c2e9524e502d875936d74e6761544793292f03f12d8863a11af1e20cc08438654aeadaa408ad00e856e7432ab3e795571578c94da1d9ca9b5bbc9e0f13ad8bb77c19d42c452d5a039dd78ebf56569b99309f6675167ab7499765d31cf70286503afcd8f9504fd090c33f88001109242b312c54dd40e9801fec7188c319136896f98db1c9f33b9b6ad01a1d7ae371ce1819e40828a042b9d8590264ba04285ec25d723e46a30b37e4de277d11dd8607bd674fce900df013e91a4ad3a4c6320e9c926facd6694f66f852110d4bd1f0d6b71c7a039ce9b4c5b628eeedfd21f85e8002a23fa2ac28c4000df73d954629f4ca9d798289c5406db449314b0c75fd2ae040e6f5fe7dce8bc20d40d0e485808a86c921fd595e576c94e918dddf981736bd4b248ee9d5d1ac015575b3ccac0be77227eac12ca973b86f9de0736abce65654046ab0cc22214e7edd8efcdbaf2084ab59d18cf981ec0ede81db48918bc7ac85c02d1ad4893826da33ffd4cd2b323db4c1464884d238cf0b50075cb60a7dad1408f93dbacff200054aa3f6ed282e5e02efc1bff4d09f4d6bc646e035ae0a5cc76ef3378121cbc3b36ebfeb19576dcf2f24f330645306539facaf87f9c703c68f81f967f8de0b103926fc0d739005181d3b29b7982bb443090f477c2c3d2f0bd428481b650afd57bf005edf0fb911d9890e90c78f9c6079ca37af66f44efb2d3e7d087b4eb928a1cc4581740d785d0b52ec3d8548129008600c152b92d075afb33dda0ffed7e1e0f95d8acae2c72bafddab753e57a14898273916396f1d8f8854cdcbddcf62c3d6c82455fd6601f1aa3387cdbfd0007a7da9304dbc1e66bd52cbccf5fbee17ff49980a84a489b37a7ad2b38f6944c7518c778f8f4966e42e063e5c58b8706a29fe50b954c53dba9b4acc2cb510977a1a19112e63d8d76824d224d25b7bba62d7e407d6ba88619cd8a908975c94692df3c24f61c0b600da0b94d514691d2befd2b8a38e7bcf0b49b8a20914a3f539a3cacacad5c2e57435fccb9f4b3a420b04f8fd9a2d0e583af0b3e62e724ec2405318e36f08f7f80d8bc2dfe1f516a22fedbe0e53bc1fcc7cdb58258e9402b38cb2f4141359af82e2101c00d448d6306a087e0995b5472c41022a870038f3d71d2b65e59dced37a48a604ce38b76a708cffd62a1e4a30e1059b301aa8e5cd626542ef820deb3fe53c1c59f9bff15aa3cd8a0d9011fb821beaa725f865449026b2228cc4f86b87594910410c48ef581cc1af5e00288ee88e89c1950eca1510e0658c46877f853acb1579e978806e85cdddc66cf27d3184b0c580a444197245629e2e073f4eb30810ebd65de81660841593f739df21d2967283311fc847cc046482d22c0002265b14422dd057782b0794708b10506eb01f893a95a06be8236edf724a3509e322259f7fe37e0fc425f5b8cf4c73357497b5c86f61da838e3f766723c72a339edbf357f4220a2f8587400ca55a596025e6842d2eb1a91d072ca4e430cadac1b12aa22164ac2ec9917f63f578448a189e3dd6157b2b496bcb044490c89154c2872e65920b1be9f76660511d27c6dd99639898df8695ccbb2801b9c4cd29b95cd3f8f28910c1bdffcbf26f736e55442035b375fa963911a162eac6cecf37155f04e62d81dc2159d41f79e4bb6bc8875fc04d9fd4f1ddc6829d5a07b803ec65be6bc68f4d8c8d3ff1bbbe31734b54158ee991eaf3c0c35f85d53d1e6b0748e281ad5c3fe071e85f6a088976772f266f02ff0631634ce9b1574595a01f3ebc2fdd3c45dd8296a51c297447577a17e1440234a8177f3ccc84726e683ae113e6ba1c1f5d9dd45760edaf032ed5d5c4022e4daf240eaf8013dc478ac55db53fcf123ae72825cba336aa6a47ff3e7407761b9951408c46e4d30f0994cac2682830136c93fb8678615b6c7138f753da5690ccd46a06930b48d43b7016834807683d06d08ba86a1db38741b80a601683708dd0603ada72e665a509caea8e7208816f989ab67b8443385888aee53f511f23fa594b30112b726c40a965e4733e26e3177cfe29246193ecfecb88db5f9c55298b93fd164348b8537b009120d014bac32e11a24daa21840c84d250e938228013c1653013c9154deb54a6c2ef6e2b43ee86fc3d24db36be5a5c815fca730fdece27f3e45cc03aa5604f6b1df47d7a842eb35c1778d0f62ac686eda4a2e2a12b430cc5a8b14359c2acb663af0619ccb0eda865c9cc101016e981a9d835042b9b5430fea01ef2281a82d1562892422819da3f2b785f5d97f6f2bcb58109152166300987370dc2264506f85701b592c4fe055ca08469bc646f15d21773119eec4c1ae330514846e56792b3fe3417a6b76fb57fca2954f66c3d50b5cbb948fe2d58c072ad232b1a74c1c01e3d44d3502829ace42de311ea0f28ed3ea1660222ddf115b8d07a8589f8590000ce364347788a2bc823a526e53f2f15bb8c6f63f13bfa98dc2c54f3dd656883a8e5c8e58fac4456764985135ee12a23ee299b14575c4880454d73f10ed4902c3a3c6bc45aeb4bd937823e4538326a6ee2e939a0b83cd9694c0b4c125d7760dafd3198b685017e4999693e5ad1465b8498ae3e33e8ad9f170ee0e59f188cdaa4a8794307d66aea05042ebf22fa58bc9548814802503b856c5bd011c83bb6019c94660ae1ec58843d0d06cce2a11913b9b09509030f30840f2c1bd7786d25688700ebc028e7cdcca1975a4435e02ee02d84b3eef4c16e68d20cfd0cfd74120d81080cb0c276d07c5c1609f407a18423eb53b0623601d1fe818a166ff0ec3c3d92502deb46b3940aca13436ccd9ef43ec1fa0fe82dddc79746dc01e010f82cd397f42ae909f9f05501a5c64dc08b323e08086e6bdedff8dfd79f3a727263f274f1d190eec9664d3906b2a569d1402d54ac99a7ed70a18f391ec717749feca4754989fc0eefeb152a7a661ee1734bf130303a90c1010bb519b0c2ffb275126b69fcefbfd2eef9c0e2fd4499ffa1aeca8e3a4247a367c7acc641d63d817824c38e0d1dc7ede21476912728ee523b7921abbb776bb6c75f4503618dc7c1607cc5b27c91f9bd840121b4fb6af0e94f6407a16bc93542e33a92b9348ffc5eff184b081d9192487c68b2a4b2c3fd4a96e014587097d15e52cbcd82f5dfbad4917fccd16ddfd01723d96e35eb939abd621430c9971c016e82ce1c7af99b217a915d2d072b553179c854063533faee507821c18360807c1594e2198ca1adf4ddc5412cee4a4f7498929ed4abbf66b0ce735df9bfe945e693e9651354eeeb32beeac329a03fd052d079ebdbf277d571febff8cd752d2aa5932d7e65f3cb99d58be90eac306b85d4c99721d75c6b641f3311ba80a3891700cf6fe24951a9d9503c1bb3448487a577ebf888e50d82e76b0d8fc91a40f21b5c0fde2ef63d0ecfa22ad627d0fa0896530d2517b18a30996c435cbc09a5141eaa4ab8bddd3b4064793892daaa04f879c793a38c0fc5514f4de58631b003f06cb57e4c8ce63366e81faf489e24ed22222546d4db3a364c6c1601447f6b8428a839b3e235381f447bc308577c387c9e2423d67759c21728a3d016428e32ba9cca95534e8a7763481faca481f89205358b9f1a968128ae3cb32e56dc39525d736cef1f14df03e30cbc83b5e594d3d38fc4d0c305e6e2f875f01928950fa079a64d9401e2a50fb2e0f5fbfb37b5ad049d894cfb5e4209ce850064e829fe554a87ba2c24bd8c481c1ee684b789abfd58743d7c383ae4c105e3b543f8a802e894b61f7aef59e9cee57e985c315e416e00fd2b380779569a8bba3c7c82cef95d40242ad9f72bf5633720c7a4d1dc64cab6ef614c64886defde42158c0e6895e7c10737bef1631d56f60575d53d19452172151d43c29bee02287e8106aa0774e33d13fd4847812a8f79f9d5d1ee90d92d7cfa790b39438a9e651663b08525a0732a2436a2075414e5bc0f91b54432be5d58cdf997cfdd50cb3f3890afdd1ab688d49fca81026058e0e938fad19e6d2a48d99c4b5f84bf21b01d5a9a65790f242fafbd680ff3fd9d4ae76a264279746c7dbc16ae1f001cad4e8433016bea632c44c59f51ea58d5e43a285213156c1313fbfe3c30d521b849402e1df96514cf53ae7b3f50a074e491ac19c00527883bbbf807cb9d221b731b953f8024756286d80a7f4874950d5f8ddc13e8f1387489af325f9390baa692124f94fa6677fcbebd84de6df302232cdcf11d0cb00ad25734f10a51e2067b42b8456dc8e35b564b534288c0c1b45e6b59a97c666cd19522996cdbdf00b57c6660e00e23239c58baaf5f6d6aacd4d8572ae0134e9f76e9eaeee46b4fffa0b301d609f87ada987c07a29ad80874f05734027e5579b5754aa928d3079d628b0663d8894795c0a883e2ad02704ca987030988150c8a5a20ab555e9cea7c25b6db31dbb1ced3c94feea634f16568397710107800c6643e8c9946fa13f4676e226666537013de8bb9aca6233d0c99c66d5dabc3caf2c22667f2d7b62ff33dca44e2e8f3a40fc442f92d0879759eaa464e11ed40c5d219da0ff787b9b5c99f1e3313aacff9d01e8c2369b95d9e524fa365b9eba79f2d8d193c061756a9b14b576565e2c060d4b62a395431a3702aa8b218923d2964f683555c2042147a6feba52e3f37c23bebe4a064e8d27bb4985101393ff51aefa558b48c1a2ea70402645daf360f8ed742ec90d60044e2694cafafac1279694febc8f9659404ba8cfa661af8cb1fb234c21979dee7457364a7b7793fec9014c4d7209186bede858e99b427bbc32719b02ed41ad26c389761968150178eb57449a1183261c0a83726c1d96dd9f41ff2c01d0905f24fe51555409bb45a933a4cb793830b13d33d143b3187230bb032e9b933df7cbf8739cfebc8f5f530d364cd3b7f990b65468871e6e9814115984139aa4df656ab93844d89e0d7b9b1ec82032a2e80a4dfadf69999d8d5be980ced48d66e6ebc207e836519977a9b335636cff5dfc8aa4b7c6075b0b3c764e05e7941777883d2e44cc24470b49c8a0adbcae9f9af3f60870bf31883c0b3aa4718dd8af03a5f1643cb381cb88198698ab3894de326df502de7fa3deaa5ee34d883aace418505cfbd4234d11490e564160da831472debce1a67f0764ca98e3190d0bed6ef225399fecd1ccf2405ae07e0b3c86c2894e57be4e36de5e86bbcb048f3e0d68064f6cf1d18977460afa4d93669e056ba80169619eabd26ed2d04d82547c3dea99b2040c9b817d2c65031bc5ee19d9e336f4cf71f0e76b2e32fe7274d83f5bfedd91017b44b8ad8090ebfb5130332cc2ca24325204878c2ce9e8a7e05a440805fad775e1037d3fdb05fd42c018f6816d528579844051fe426946152f5dbc122bf3cac6b5ce4dc243b01c990b40557fd7ff768d2f70fda48e09521ce4c4d35f3e41ae9ac15c3a445fb5e868c54234643195c5e811c26cae5a0729cfabd9b1649d691c424e32b349f0fa8f55f39829b007949367218d7e662ba85836289b0d87242d7b69baddfb953a90cbcc94b0dfd04090d0401c1cb282e702158aa744c63cd1ee22a14e30bcfa31abae5a01ebd7086d3678772fe350d8c35560e2a0270cb847b02248ecc8a811a279b9556870d0074837a28d1fa82dac39686e0d5643e132b41f5bfe438ef7004612460723a38ddd583b8c89343aaf9acd1c44595d1d9ff18aa2990c7a84ac285222a4f0d80a7d2753b47def838e3baec2b0610732aac2a17c2589b1ff71faaa0e78b0273241d4789f4e72537aa7381759402961197e72aa9dd4ddc9fe20a0695cb86f3175e72795a56f8a96bf3ebeebf3a6995a3aecf60a9ffe0bda5148a45399c676fcf3db3199c86cfc9e8c1ba05c1601390a415b0b6cc7db0373a9f511c0e1112d389d14e03c8cb3110fd48d9ad7bf4ee1b9ef8fe3f3ecaa041e4f29c78fc85b17b21f5412867a5c2644c219412995c0abe2556612e40f42d05deae884f9c1d57d118156c658be6d39350bac7d417a44084e7f5a5961202889971898801618bce7d1fdff34dc2ec13415e9eaf8c06165ba61a3a0f398655ae80f09b4171a2bc87fe881a5e210111699cb16b839c2e3284fbf403dc927c337b5d2a6a61d5137fed7d70a2fd2c86a5a00211d923d192905a9c577aeef680535f22f6d4cf92655eb06c090314b13c2d6a8cdc8302e408153ec3d46f84fa60379a5f11a089c5ab7348d53863ba79593ccfcaa5b3d3f45dc523daec843aae6a0ada210ebcb991a83206186123579e7caba191f4076436c3056cd6e70c683ec215371ffaad4cd914e4e7684aad82d2e656fe6ff72d4d67e585748651220f694d0668ac69b0ea54cd232986ad27d0fa0df94610995fc3a11943e91e000f0d1740b5836dd2272099e929a035bb366347540820d3ba6c63da9d8c2aaf34e0c608c6f9674704b43702ac48fe89884e2fbc92fbc6a861ed85e5648b7d27c6f72b308179b38689aa8e16d7387b31c91ef319dfc812015d51d8e1f77c284e90760731d97d39fbe9a79f883038c3ecdbd0fd1ecd3fe2c2e5954d3f53ef6543b002e0bceb0a76b644450e598b9f192b00692a94511717527e268d6d92019cd6a0c463bf22948fa45446d13c89f7f15fb0eb8c0d7a1399244a66a3caca3f68d7102cc1e19c9715fbd3b431baa51efd2b6c77356303f25059c64e7a7f6296f07b4cd4a07c959d45fd772c233896bd23c23b00d1b85f60618a3ca1f1bbb983adbd6cee9e423fb6172fe33378a02c4e144996810a48f104d5beee91d46dc0c53554de439bbcffb69b5cbedcc7d537dc5967d7d83b8a9718aae69b1d6514de71aec9643fa49a4ad3576420cdcee439b4393382729e002cd0146885bcb14f9818d05585549c420a9b8dd90f78151add1ad4191653388b9e0e4854a7aa92be5411dd22c687d8a23c1ca23061e60329015634bc1fc1bd8334ba000598604d873be7e4b13b011fc6f42e4acc76f3976a7a2ceb9e39d549846339cec8ec4d3b8e316f3c75f79f8f29fc793930f2ed03fcaaa48a387d5588d807b9360030b88f93e29509a25d63063d8c268252671bd9da46038d0bbd1d9c328c6c0be24f54df849f5aff439fe56188f925d13a5157becff7cc3fde16bae9fdaf09b6ce2072d25b356c6e80f6b0160d34e542a9667eb959ab9e7d096ce05992797c4af67d36e5f9509aa6a0725a8a2c104a8709e68f24382a1000cb07791a10ab3b87c27c28bf1ceaa5fe3a3ddf92f53ac8e335a012e0514e0587d95e862d2e50b6852ef883a36354a7064076637457b2379f39146a6a407e048dc0456a8c2d566ad148b7377574cf4d834a6017f8cb52be30b40b2f7d3dfd92f56f783a0cd2a50fe3794f306b0903cbc50c8139792c11ba37909423e53d239100605b4908a68425b21be292012473c273bb1538030d10190846b96f000e6b0c2ba0a13439ed6e6c5736e59da31ef1442211dd188a339d2aff497beda26442700cc401407307062c2b23f395cf4ce279fa566e89991156d6a3d104bc35c7d922b58f0812022cde934deee4657a61dc2c857b08908fc6a1faba470e99b9ed3b750de906e58312baf0f8740ef495dc23b14998b955aadffd5aa5ab2fdb0b9699396a5eef988d6058fd6740a0bdb10fba50184a785ac2b978014ff3224f5b444740f058ae227851b1af5d20afbdc094ee5b9773abad3223baac4d167bc48eb81d7cccdc3918abc57e7eefbc2dcf7edd61a04c845e184267e490ab047526972cb94afc7c212f398b1ee66a49376ecd74819e9be82a0debd20b932c300621d49020ff30cc4fbfd1331c06fda32ec7d974a08712235e6f07274c1e34876157c3d4bcba3b545b2e7f759848d83a3833eb9e00a7bb6f0aac54e1de77548579f1361889037a217c4bb809a1ac744ee6d4a28ce362b17346a84548596355f5956cb1a5e253f0846eabc096ddeec2bfa8a1f4eab05e51c9926a17c604cd6ea0fe05b35399b0d1a41f43e9cd981a2f439edb8260e96235459007e28518858644bf79879ab071d4d03300ced2b225b75c7356eff0dca408c121306944b9c8da675da1782d5c1f919eac2be013bf11502461bf10b88b294cf88e2c3ddd89abcb6a8907df9dffaf896baf3948b8fc7be94a8d23c1f6c28566ebd136a43045792a8029c084a0cc446d64983a9d8c48b82d083636655b0020e84fe4fd9e3c6435b27095b218218c26c0402d3cba90183ea6abbc6fc38b39d8828812cf4f76c8844c18e2b220ab0cf0aa0bf9d24160511117d45095165dad9169d7d09a2e2b017246e0acaec9313db8e0b40e1edf5049e5a72dfbc2aaff00b65ebca8d803a901190f3723caebf08d9ea0a484f3668779f2865db15ce04d66a6ad7590ab1a1b761949f7658184c10ac99d1363ae4bfa59840eed1b44dc493e4ee0b52b0b91b48e20e523c1855d39244bc9e3d539a5a502b20ee2793cc699d2687866664a5e2004fb15d541335d39b7eef01444b9ee15559a423a84c47a0bf21a7ea975c6e43cc67557d4481942583c13d33dd402b6573669ca6acac296ab7e41cd86a4e9eb6976f99e90ed73fb11f6cc056623353a895f23fdfaf11258e8572e21e8cc50fca2df11ea18f9c822957b6d745d6311ba8f74c47e3db81b4fded697e33e136debd6751b18c6822c1e736e2e51cc1160f422f33ddbe83357fd80aed8188770ece55509e8ce7c4561c27e865652053cc5b24d093d872b2620359bd219af8bbffa323cdee7dc9653bcc0cad12dec7860af5079329f0a3d056e902883b37e0770152eb41881c80397b840f36905891e3486fe5eab8d3bbde9c878e3f6c23ea12a6bc86389f191dd6833fb9c75e03ef6a5eb920e2f70a8b74eaff78d311a186a88070416307d11b7f6f631404c18da89a14000d61587a09de8ad4a86670cac083de20be0c53697d603181bf6d24088e10f6e42ab31986de7aa6e603477ed2a0c318f0615d01c14f03b1ab06827e57b708eaf93f934b14cca460c8f6f14beb423fc406052825547660652ae9667686cfb2ac0e1189ae9c1c4b159d2c51d2b338018adaa68648238a3275b765a5273aac0e08626d5842c71779f203825d69436c8dbeb2004760f3f6ac3f491c1aca1cf66119073aab0bce61a54ab1aea454235bac20d0e82c31a5ed18e9f24e92dc49b2028c044dee5f7c0a508cbd4e54404ed00d592234898b66f317178d06b5f1b5fdf9a3e5b0bcc17870fd3018a02f3416dc3bc0c6facf64bf6bfada161047ab11c4ccba07c6d16a0231b3c6744139aaa27724f741803437ec9474c6784d367c2fd09566aae45fa364529dfbfa8a5b94ae0b0b985b1ef9585e8c8db2b421f4349e20fc3035cf983f210a31456cf760a03ee10568bb9b91ff372d42736630a37bef6ef6b6ad261c3cc1f71c635963a6d678b512e3381fa89849f75a5f3319f203a4004175fffb49752b92e6b1b19808658a31577f50784973c6f55ac60d9c1d7d265e85ff6e6bbd341567a0c7b50b6ffa6776a8d9a3727a898c0946b435bd324407f90cc4cee9b3e7a623836f7951ec69d67e5feefc96e443084b9adaa844183bf5d0cfcee3073d44b22d3c91f5f0cf2c5bab61060d98be4d682935823f4184cfda5381e1d5dbf10ccea3afd252bc4ae0b661345c849642994a53019c5a73aa7d6d8e54227207ff5c8548a6cc96d8f68c3dc6498064501dd23a0068852f397d67207708c62f0daabe20bd049e27ce4b707d545e0206ce081601e5a24bef1b6d31a3ab4ab7d5942ceb684ad275b42a7bbd8d56fe2b0967681f9054e1bf8ed5d026bbb34291de4fa4f8a68c9d6ec959a3c70ff6ece58879de7e31a7f7b372be28bd519b5f73fd87b67e57ffd45173b9477163ed32d03192c31afefedb8ebe0d539a30288994ba3d539f4056f557eab08ecaa84fad6c8369dd34d0282321a4694e5eccca4a3a15022a1355dfe961329b83e02d627dc82806cb5c067c7d297266b2cb5475abd6228d9a4f754bb30e22634e13fcc89378bec3ddfb9a2f61297ddb9ecea89a8f9229ae1b06e6f820ad29a2ec3e3558654bd85c411676826994238a2011f402a44e1353358d985ce354d571ba555e3142bd28f8e633ecf8e73985907f0b3af5f8deac929547d545aac36b2eea5de1cd77725e59ba1bd4afc8b51d39ba683a99a2023d9c7e4c984fd0306952c3eecdf7cc9661483640433acf728d12bcf1e9cc3e4019203c88ed25c3df652389eefefcecf9a4c58b94bb36bca8c8e9ec940686434ae2bb068eb0130bf3e4f423f02c8694c53bacaab4b51f318369814b0a650e7a7ec1e0ed99a1668e5313358cc3187037bd129e4e38f8a0aa3b12d00f2fed76964902f5f3c5d6e35790179bdbe38ddc0062df74592964deb1544f442f9f008b4e8e38ab9b2a11424466db556b0c5bb2fc898974811feea88700d665ba6b90fe6d69d8f818d8a1c6d1d46670ca98e76a6c718915795608d03bb55a44061fa98291f2041473f55f634e5884805b4e10fca02cac0018e819a0e356cfceba2687914e8eb879330cbb93b83a78c732bcd4fd912cd0fc53dd1b60034cbf950263fccbaca2da2d0cba9dfa3bd488648710874f5d40af304a7c611892ac143cd4b16053336ae574f67a7999ce8d8d02a181275c65ab1d0821e5a91fa70eeafdc93c739546c4081d3f7992bcd28e4c66e52fc9e5b26e92973fa3d60015ae96230ae832b8404ac3094b99300430fc5436f7f89281bfcdf0448f5ec7749c0c5a1189276cec704f5ea9afead9c5791c7ee08d468dd19927c5c515314fad21c798bc4c05a827769d5fe50d6a0ba0360ce60898a66e40d0496497d9d98fa870efefc48c8cff203ae221ff674a4e0f27216e2a784b9853558f03b423d7978c77cf75ec2de69273f9d7c38fe5a58d3a7be9cbe2fe73b945ee8b5e55a68b2402bb9f7b38281b685dba438920532967dadeab01190212312ebe465ee0f8c953f82597008e772920c87fae8fd6f58bb0e352b68e051c474791cae46bd1b9d1fab76be79199a5c73701a4ce79f08c6bb6fae39c8e0e416f0390c5d1a1f3503eb16a48287f55932e7c6b42215f6f1638a53c29c44226b853f82f8516d03e1aba1b92ce7453f1987aaa609fde011ccd1bf0a338e517d25b614c74dc5abda33d21cf25c06623fbc84f8d3ad6095a5901b31c704ea3ce92e0d0e62f669a92568592e9114e03275882ce8fb0e038bc47388264abfbea0b3c2f0d11a63a6a760ee1971ab20560d9cd49b1f84d6a50028a5bb8f00bd0ad4dedd14f4db4a95134a0e1caa60e0ee50199a44fbc6829d9ca3caa6070e6a3b06b7d1eda5074709b379e0178bebd983896d21fc2b912aa5c5b16904f4f5059a99410995788775a5d2232a44283b736278e594b66c736d93ccaf86d4ad2011fa1494bf9503eb49054c7d1646c4064d7a847231ed9e7c9769efb005690566587aa92b1ae5832a0f706481ae1deefd7de2cd108df3cd98d2dc0f95a5947841fc227e201331adaa6e66e0bd7a8033e4c71d921efb60c3a13ed33e7369d87d8669dabb13563382d0745943581bee6ad7defe77ddfa17733be9528aad52c689b22dde1624d5401b2c6c7734e7c12f7e2798892bee86c5f12b2f29c595006aa08a61bdaf0512aeb2ab565961a5feac3fe62a70d039ac66b8201f42147026c4658e5b96997805ed59b2d529fc1ca6d70aaa25b00166db4811ae89036dde1ca04343811d60febd89f12bc068b6d340cb86857c055dfada36bdb6407c21b9dad3d0c804303379d87a83143a16db4248dbe1096385108d4a1cca220e7608bdb1f0212e739e275d1e95f85417a64195d9803863fcfa73d9bc684f62eecaa34abb77ca54f902cf5582c787a15cffa2c2d41a2f03c02263426f11a401e2878eb198ca1cb5348aeb508806fbd9267d0ede411bb58b817e2b7e4a9019cc114315446f7a21ee80b7ccaf6cc1321d9701de1026959838765624333d6f198a43989a241047a546a723a9bb0f2550c82555937a3fc3f472075beb2577e735de7cfe0b35bf237049c5d581c31804d17019f3f9d827d0bafc6c2840bcfcbd204b60df3d0310e62191e626740997541c0415074248c87dc5ebf6ea4ade3e9ebecc4a64e7e94e6fc7d18479c94033138aa9addfaa471bdd0aecf12f227fac2f1020d332782c049a4c463cd892070120905d14d8782575887a00e22e24d5a4977af0676edfc4c2565f13105bcd3c466ec671e3f429bfa3bf73611b1485314d08f8d8012d3c00d9387a2ff76017f9ecd560580604bf2ac4acf9a4536ca2758a0ea71a25b9601817fb3f5c49741c56eba981502ed0554445d2e3094e66d705b099443073d81ff4c27c2009b29b05ae6aa4c4a36c89f7902f618ee0f6e8fc95fa18c8689a50712a956e80c8a586c11827cb0d6488d706a55e554e1db2842445f8d8d3419389ad370704d43b1faaa09131dc6650efff39da06eea31a5d9faf189ab8497cd872a3a42ce88baf8ace48ee1290f9d459e92f49b530526292c1575c3e337e57111a0eee404e04c870a56151c0fa42720d1fc2083a22a258cb2f1ab1ad59b0f9ab90dad7cbd567b020a7ddaa8a22d150100116312b3b4eb754e7c3b9d122b23ab3b15b039126243ca6dd820a6e594d3f6af3f5f6ce7d4af876fc703b031423895d9df2c8d5136ccdb6cac83858d37c2fc25fd60f1bff7f63d61f8956b310eea95ecb7e9f870289b0c8f9f8ae6c50455d890d4a60401ae420655ac3bdb0f0cf0ae74867f45c52b6f8e091c273479bd9c19da5beb791b3de6e9c3a340a0899c802c1ea9140c6947e7c1f4ea3a46a83d5dea3bcd659fb45ab5f6f5b44df0b78fc9c601cbcdacdf5ed9e07f1b40dbb9606118f35bea63a4f851b045907e0097e6ae472314313ba56c49c4da7a6a5d2b58fb029877861f0f83f69f134f09226307a1106fe2ee6ba408ed7abf3251b3444dfe555452004f56c5a42d3e931d70a778c493f4a91e1b4cfb32369b29d7cf918bb15bfc59f763423c3128422a8b68d86d929c7695e7cf7041121ba38cbf60a33425bff34a2326a8634ed8f184609da7bbb18cc090951701d6f088f1877c48b54446e33451ce601e7637c888ad30dae453e5826ffaae8b902f2653fe2be269a98a70f1bede7f4bfa1d22a32d71d7dd34d4ec8a15426a0ace8d0c5e7a91d543f20aea77a15018977b488d83b45776c216f8a2079e41bf1431c72767fbec98cdf66ccebc3080a1595c770394f84ad1f83bae51bb4bce47d32768dbcda44c75b30449cb0c29fc85ebd04fdd0816fc4070954be00a6f2b7c5b719d8e74e59d5bfa5ef7f46fb82009d482e177c96b6044c93e12ed1ff09c5dd069d88a950fa2d6bf18ebba8bf5cec21d795831a07f8b74053df6869f23331f7b6d61688abec5dee1350cce06b6e8141202ddf08392bf9ae516d436c8e08f6e10088aafc117de06d011273505d7e2bd92763a7d1e70b4d843422fefe2062bdc2f732c480f09bd959b01c3cf61e8a7760e3693cf3eefd9d7cb0cfc2a6924b42f3432242a089d23f010efdf9953ff57e412104ea93759c2cf7a90e66d0ea62d26a3324b5f8105e15e4e614bdf18e2563bbbfe23669fecc7c26ffa2c9fa39950361ba51cce3ce090ebee41fad4a839e1240aa9ec1c9fe369eee769110f8b45a2ac373fa08f6f34f49916612647d0f72eb63162af282747f0e6f51d644f1532b657ff8a2d37df653656ee07e219ff4eaa631877c7b39e15b43fd336a7cd2664e2344706ba38244e46c45090352b2ec147318ec1bf4d2346f7a17ffcef9c07a1d12f64ac714d259daf2af1a5a76ecf6eb02098e2c9b660f89dd35d12e4a3ed49d83835bd01a114617ae82815fc6fed592f28155b965751784a2d101992881381e22f79f3e5c93f05cb309ae7abd4439b38c3e51aad29add20d0093536a08a52199381305c3d13d3a1ffc156432d8946278d1a853e6c8504089d93e9c0ee30d7ed01944172540dc280bba6a5c7396869597b07f824f7a21681930b06983f6ecd49cc2e49d73a9fdaf32a57ecd899cd201f6848f3c5d90ac92bc655beda01499ac5d9dc23a682e9ccce20b44d3184a853d47aef8b38769b65eefa29a95c32fd7ac1cb629ec1577223857c801a20ad2d12b63d2b0087ca6aa2fbb0bea5bd13cb649bc9b9b0b3da6cfb9497c812343eb6c4933b3c4eb46f43611037b938c0fb505cce2ea2463a316b57dd8c3f35f9cc947c8d2edca6291a81d773db3347291a6ce72d822d1c43d889e4a45808dfb045481fda7be621a9d29fc9d36e62fe613e1326528a2752298e9f286b9e7db70b4697890cbe4284e22c275a4988ed7e57a9fb61db88c6e1e3d3435ded0c94214718b73d1126f6219f45ee4c0b9e394af1097cfcc54eb2f92ff724c3fc2a92dc3bf6b0aff273e17e641a040323b1f97d274bb6021b9ceb4b2288426fe154cc7cce0312137931a63c7f928f60d1b5c9c6bbc345d8eb0b26ed21c390b8b65669a80c8522a6d140a47a53208d5c1628d787ec64542a6feb38a591d85c27cc369006cb3f5406eefa065764b051de172e8e15c27262f23a76c434d873b3545c14c3f3311cfe850617c85a7968cd0877669148c76d4812e1104c638c1906a4d195897138edcf0ae2ec41043f2c45881aeaa4897f3c9123ab7ec68b72547e8ddd45fafbdb883fd383b0271ab35a1c1f15019a2334b7bca2b98e48137c0a44b79e3c7688102fd32cd35a75154dedaa6dd269e39c4c34b1c3c80f712f1abb55a580f676c86af61cfde08cf3cd4d135182124a6805282eac2555bf70377f203e8881f0d257e8d64ca43f285df048ccd63c3ca1cba69cf7d32bd81146ef3c40032b26d66cfaba466f0187ccad076c21d1aea720b09c1c4c215e354455274c305dabb1772a811d97018fc824bd622ab61aac20838f4bd683dbde44b6b96ac48084543759c340a9959a6e1e5256782dccb690e443a2e82e54db99e24544d4954db4c95de44ff4e1a2cd93002fd7e122b0e2c7092784f32014a5a50f4bc132c8485692189cf0ca4525c6700aa3d11ec104fb70d8519e220e17273726e27e2461ebcb1e5d6bc826a12b71f7297db6822d43f75652192e8f980a8ff91ba8ec9a262a9e96c9985ddb3f2482667acf0d8519c646ef20004e17c0c897672ada843ae752db576a3600bbe217f5ed6603499f94bd8858c54e7444e454484883b0391d249d825184d1585f292619b13923303106a79caad5cde79ebb5d480ea87981828e667a88d1ab3c8fa611fcf98501ecd0739bc6d431b5ac0f65aa1e77a9e024bb02a8842bb584e39c04b47848feb54293cdd98656cb73bf05b6e14bdd2a4e4ce82ef20cab72ed415d1e05433d481e8caa7ea209a6c0b8ac1c857609180a2e683ea61069eacd9e113c149b9019c3f6b028b90d20881c2ebfb9af836f5c7a864d30a779b6f0497f6dcf3548c092f7a230f4471bd0ef786a38a3b26a9618b20f19067916ebc97907fbde5e0ea1f040859f140358e17a10314cef2bf3f7c690f6d1196df01bd560dd74c1dd1a6bc7c7539cdae2d8b418425d5b2cdcdeb5f43af3edb5f6ebeea7b73c051300340cda1421dd05bdbf0bfc206b1c6d5de855b2653222be7630ccbc2aff79cfaf0ffa5ac1fa1ef5f152fa4eb5a7c657ee37d46da3084243e35308c38b2cdfe69281175c5d5cfa70f5123f2f80677a3f04b2f8e69bc9557ee83a4909086a69b286f4683c091dfc9b6510571a018dae3f30aa885e3242a0cad3be9b6d32d00a5b68e4a289be781a58549c8c7e4558c13a1a2a9d06f3f2d960c0b50548e0a82db36c138b52dd25a933a4c28cbf718265e40d0e484c9c076e596e8c87c33eb6242dedf75f933ecf26d88b062254e8513a214b43cf602390d05390036093304649becba6b935f68a51e6410704e6a0c0a2cc1c4ded3b1c1ab60f3cd89afd937c51bfa19eb222cc72743421d52fc5dc947e3cca5638c16370720dfea9b95a4ae2312269310af01d7902cffb69853fb9228c55c18a4cb0692f95c52937321d7a9faa498c175f72a85b97f927bbafb722314b6fa8a851e22662751ff8f0dc29922f6ed9b5d98d1c854d0f4dcd3129243eb7cc7e7722ee83ba7fb24f180e5546bb8596994ce9f66825bc6309116350d4e29ffc886cffd0361fb41f250cbb78a7ea8db2c05cf22a874c37bcff013a641103ed4471d21d13a683754f9511d0113106f15fa6d54cb21be1edd831722612384e26b98ad10e785fb75f7caf16f439d3cb4c1beec30f157aeea4f4a8cecf4b8fea060d28052e885e2e3bdf0641bf8fa85c33c42fd0b1df298a372648b3a59dc6b5297810d9c9b9d22d9d7203da4c0214ac26e767dd0b07ab48477d4ddede30317958e16da8f0eb0933bdf75c03e7ab41a53d2932f61ed040d93b0b3473a581083b2b5fd3492fce037bde17377dbcd61df1a8fc316b278f2986899d37b70e2f9570e8620b1d88b3072fc2c61276249c89435a9a0ca703ebc36278eb9294b525ca8c91355a699d6bcf1c049d5d39a92ea4e7343e389212c47f10fc3e011bc1badc75a190609e65346f24b6003103b990ba1c6aca0ad1100205db85625608849880b2f2fa92618ed034f40147f24f0f688a36a00f28e14fcb506fd2cc3da743fac81b103571688bc41af2efb818770660e00778786defcb1da6ff395265043a6b26fe337e501f034fa89cb57b343e4cab54681c35796242e845587daa106ecae6742a6742f90c0e74283f3c37d846414d0796d80e2d9f5abdfe71cde41951843b38eeb6ddf0109fd773da247c63a7820b32d81f0fa090f609a83802037ee3843c9cbe3f69ccb4faff247e3385c72924cd075d37dc42c1053419872c40106d30b875384913ddcbd1375944a1ec3346727efb84fe1d498ccea1b4250c40b09a7f490a1ce3d3f4fdfb15cc40df1153f8089b4bfb0c7a0b18684a924c951026029a6d6238e64ae1c35f79bd2311a2f70c1b5c7219b4d069cbb669663c8ee5482101b156f70453cc227d203465686ab3b8fa93397a1995e5c78f5abc208b07ed286ef3d5d16d38734102af3537d3c20a14d495ce8da79ec756190ee4422def0aef50f320006ef6a8f0fd8f3f7e238fa2605e1903689013f450de398f68d47366405e029368d01fe4706249bf172aba0f9ee7092e09f51af20c20c482776318ba823f6cb506e6b263d6c9d5aec9163c6214bdc94a201cc3e853f37eebb678ce31e254b69cf2f7368c8229bd074dd6be808d2c949b868319ee6400ac269961e9737246dc699c92cbe9ff9a5c932b3a7c86d2f151406db4fda4bc7e9d60d6b06eccab5234bafa46c2b825ebeba2505eb514447617dcb0d44b09fa8c751262703ba5b0e513bc0ea4186093f0d77d4a0a8746ea013a24bb60d34688496bfbb84651bac84c595852de8470c1db0620a21e35d7fec7638f2e33952192a4e33dfa5c586c599f15b0d8cfea210171b00736acf4dfcc5fc523a4bca1b8a58c793abb5c0f0e10b6a3582c9cb8e0f6f893613dcbc97812e684b10140b55b079be831278ca466a4f43f73a791d759fded910d3e02e932d36861d5393d67251e74faf1f089ee0022b153e2a74b40409738c5292f8be2daee895789bb62654909b33487d6c25261991d705f1c6c4ddac81fcd303f5a3730031e3b840be781e28fd871464ca7292175a3568944b25d883392fbe1c6e725dcf826c5f57e6e09ab7dcc262f07b25f0f77e6f9889ef1c855c75fcd8e9a7b5bd738657039e7b217eb8902664813c5fad3c1380bd31cd184845de78260f46180f983240cbec7b11386944144b96b995b05008e3971aae0bcc82c1e297a3dccb7ab4b74ad1e72842ff148ef609d7e2139230c62f3298dce1703af100e1f046d2010922839be0ac66142c4b6357a2ad733ff8a9989bbb02432b7d422076e1a813e9c124609f803922f38b9c473c60e7b1f141c29d95c5f57932c7fe45927081d4f6952381feee468b07b51109e35ee11c555e2781e6483f76d4f8ea33d3d6bb4ab2902a63e9beaf997e1db3c2015de19303d52ff3ffaf9b427d3ec95c6dcc5a864a9c5e1da4f3ea329606f65fe0c39bda1bce0432bcd4bda10c18603af215cb045e7705a588b3fdd4fa55bc0a9f96abbd53b88febec74671f5a4802b4148271550e5f11406d244105146cb60ce751aead004340a79af87116de1000e7657fd5349cca3635f736a4b312109db0db41f6357b1a2bc5f0ef9317d2c800a12309a36764db7cbb8ccf86919cd69f0fa3249f818b07180513c3ad099377ca3aaf333cfb75b5ec1a8d4a13f87bbcc78e93f0e482744c9ba22f8e6c5ed53656da27bad39c0623630cbfc31161dd7bd3cc5e44a43ae806f943d13e7e7b31fe315206f70a75ba968e8f459b176d1e4016808f000b48c0df9bd34200ea5232878f343e465ac51862af0ca97e11dc9d3dfb01eb7a7c1e91f4684167450614e4e06ea8f9679b5885c8c4ec200590ae13620e5611d2a4be40226bdbf3142c1204127c185a48ef3e553c770bf13236ed690106623bc35df7bc2dc00bceb500cc6aa12914d29d2a436593c11ed2a99a4b2e1e949d1550f2967f7f7f4e0df960e3427298e856ecc68ced39e7223b7776810894bd5cb162b7d0d3f6807c52809c2c1ddbc267808fe3828f5d53c6c9e8b3c909c0532e69a78c8a5c13aba3787f48e599bd2f8fab33038d38f20324b687df2d4a563f4de72f55bdd29225fdad6708cd355a8ee59a88d59c04c798b25d491a82beedb328cd35ad5825c9f41bce249a6b7da59534e8b19fc9f4aff32a2679d0db7c86d25caf95ade44cafc119a271dd57aa92825ee6b34cfb35afa224077ddb6729bd6b5a4ef35a199b89448a9d32bb4d1a07f570ba2599c4a04c77e74a9786e1fa5932d7f046e06a25398cb920ca4b3483d293cbbe76715483ff3d31fcf8d3984806e8d7a4970b41f2ffbbc472d09f32edbf6e3442f1d47f651a16426dc1639c522fbd888758450cf0dee3e998928ec8689b76912a2780713c04fc0121dc8b4d6f93bcdbc73bcaa19cdf35832989a111be6c5a6a622799be6e1d9a96343a0efb18f7e6ccad48b9562d9bbd8afa94e9efe0051b5ef36bcd59866eee5a6a517922a428085963023874c5f607b12f4632712bdda1834eae4ff574bd161d8a5ab1534b58f1fd9de31ec9a0d6c4a809f4b3c78366168d216b7953aa2b64c45f5e31d20e17078ff7f8efe7f04d882f0d1bbdc1937894c3a6a00762bbb9d16bc1bdd68e5ec58bcd47f4564ee6bfa0405b81a2a2edebb5983b0e14f109318a94fc6d9f3cc123639d0530d7ba5f20c65b11c5a1bb7a01923066f73d2a2919f53f03b9fcab28a42c05e4cfba0ebeedd0d1145dd602d89680e886146c288d442a77c9aa270d4a4e8bc75795072a0281e06cc5729bdf39ea521e194b955478a0b5ebde999a8e11345186f0751125e45870774e5fe2543d54e4b7efddb8f49bf44910f0dad2561475b541bbdf46660222a4f3edfdfb94dfd93db500e943108699052e63939f5ad1bb725cdba9790c5537dd71ce8ef4e20830bcdcc8163d62628339991c5b212f089f3240378d3130975ecb6e112b772811321a96427939e783566932ba635d83e2dd4124b631b940e1585d990e5c9f79f106dac6e792e8df187ae6bfd15985de121ea9ddeebf520c508c96bc427d823e9796342ae6cc9c7d6df522b2ff34b42ef46fcb5c5011285f0e5efe6a6cc646116b89f564a13b89c4cc3afd9f58eea367cec36fe708b629e1e0cf2d9f1e6f53ace20c0632754d52ea57c9fe9a148d1f09eb8352ff6f7100377ea601ead564a0d0cc036f79e277be414da001c1149cb52041b4102cd6efffcf526c446bc7f7612da4ddddc82adb9c59640edafffb8c5f5ba388e8266cfc1fae4d7c9c3646af1c002cbda94f3f794b6814fd22754ac3c47ba32980daff0a587c0f8571cb897b1b4dd9263592a24a8c1a7792e0a85050e6623db531cf51304fd3cf59d00eb04b3d53470e44341d1eaf29ca40696f537c68e23252d9c7284bb77e72d0449d8e4447303c87a2ebe42e5c388cafe41fcf269a4d026aff361db3f0959f8323fb8aa6d94255df3bee403ffe0999fd16894c2d8e12e7bdf8969bed43424a41edafc616b1a280026e48a158d317ef43fc1c0a0f5435af9aa619f4a069744e33f4ead95e87e8d40eb61d67e74d365a9267008967ef3f8a90ae4094f4c57a4f467249a1b52a9adfdb22e32f02d61537a8e86811682e3b1afbec26e988af96fd1b6cee691846cc9974700b7f6c76a0ce356fc7ce60efadf2cb790998a3b173fd44ac9479a747c03ea2f73afff06ceff5971f679e6fc4d6b7f274f27fcdf63b90d03f5120c100c336655f5b527a24ecfe0e92110593164a79ff3651ce5d4a0d1cca6d995837205eb0b6abcd2b70def1da8a59182cec033e0acae8113f87e6834f52ef4885d618b288333c10bea8b507e18b51cbec65c4fa72fef98dca9698bfb598c28cb8ab569a5f85131563055285516112b0a6ed90fec3e63effaa31f203b313a3e689537185a760f5797ee623230f7614c98985185377c9029d7403a94d27d7ac26d728b1a33fa860da0099e39f65d78d1e4f80506c9a9aaad2f205321f422b25159d8641c36655fd36b4a8bbc0ba721fd1ed365e13240bc30c8e85376700032494ae0013232926bb9986c3b032e53ce2e2258e785b7ad9ab48e40794d377339edc25e4e125a2cc78022352d8b8039fe31a8236bbc0e1709c9e181e464851548d8b1aeff9e2f076881aace32c9eceeddb0b0cfdd141dd2e04e91abf693c17e1521c51f09b08a5807cb8a9d357ac26042c42a3c0f1be91580cbcc367bdac3f67eab91d474c48c0986f701bea07844068e85b193ce502bad86695592050ca4d3af6aaeab6aba9aabacadfd0ec51d994aab23a357b9efffebfafbbafdc404491999494545a301b801e03515150aa3f6495ee325327a83ff404c2382f823dc801fbf7e6e3b7e1edf86dcdc8364208219b10b2c9de3b49090009dd081b111b6f628052839729b2c802f4e44c2552031a7ad572f624cc15703219abb4bc17635ae220b4a5248a81f2529ae6bc138651ce9e54e99ea0b62aa38e35d8421a70a9233ad08c0d7b1ef442792793716c3973a2e53b019967b48bc7d75d6b38aba09b58261ec73d91b2c46edcb66d5ba73d69d27575ab6cf0099664a15283176200c6151df5a76b132da6b446276544e146273560da68c0e408179c9859c20313275a982c1350804e38b162c48994264e8e386962e264c81129439accb818d33b2d674db4984e40d91ac6460829b5890f4c3419628071665ed8e1098ccd566b3533c58cae34e8a8b56ef52dcd1821a5393975d6794a44278f8aa78c6d27348fade9e93d01ed894bc04d59b45dd2cf29a92625d156a951dd26c5a152a3a322dd0553ab8f7a8db3508c751395363cc7faaa63ab1587582c639c6a2a00dea3ddd45e8b4c0cc67e04bd0bda67eff5dfc16b220fef20feae8562b497ddcd66606aedde41da793dc5ae8a3cec7d6c620896e3da5e2a63f59bc8a36e620f8d1343a0b2a83e48ab76ddb6e654a040b433eab47d27f2a043dae212d807b1dd69dd5d2a89ea3b71070ded3d016d7b506a74ca7a4aa2a37769db5bc51d534e7ab239bc5212559775590c64767d0966d7d753bc659e5223397b4385d58ea40e6dfe594009c3ad3de768c98d2cf0d5f2f40c6b99636db47a963ddfe8d433528ecb22edf9002d250e292a79f5637729c72dac0a72abbb85753075a5246ad1d8ebe3953236d61e51e8f1da4525188d69620f4d6b0f674f8c801019c2ac30e78521c0b48142879443ab7b3787ed7d7535718777d5c73b3b49f354f747d8281686d121ed9da87429a27016d2a8c7a89187594f3d85f38fb0bd7f07bd1bbba7338a20c0684c1b53a9f1da5957caa1146eedb00d04051eb647fca2310da5699a771af6782af6906dbab4e9d2e3c129c511bb78a0ee1d852b2e216c519631e6d6e95a19fbdefa7290f6ae5dbc55c6be8757cad8875b3726eeb0fdbd8a3b6a7f18080aedbd8a3c3651a983c5684c23633cfd186397a21d9c13951aa573ce3927d534edb5353a8538610624a07441e2891552e8d85ebd5d1952048cf16b69260a30459af040a4890b8a346901119e9666a218d25d4b3351a4d1b4d9c5485b821c93325d6fa746b4e9756c670035aa5a6f1f814998de1e4a3755b6ad9338cf225a7e3b8c1ab9dad5d9466f076b389b668ed9f2338dc431273da57882a0ea5984aab7831cc77152124dee1cce1cc7cd264944a51da24d2fc653cb334c88e8aee5ac09979ed8c219e79a96118083301e278b2dbca802a4540c2a86249ac7b1a4c11086249a546a988ac441a73ca2a524a297146b54245117a3aa352a3387ec792d8699c538cfcda35e22460e4da35e4246c6260f2d3bab7a091819933d5f678e5e92832c925a9570cd4c4993f6b9654d999e4dad1d9453ce28674da8f48cc99ace5dd35913a639a45b84d9d43d26114a40603d8bb4960632cf9840e619dd3473c896338b517e6e91389666919e5b24913c8e252db325707a363548c51026115db5cc268963a95e23a2b527d13412c76c9244f2692491fc2c42e2d03010dbf3b4b2006aa72e7a831e493a643d18e9907c96685a63f5f3b38d910ed1db6be9107d775b5b9d6d40d9b27e9ee5ea3c89b737db83e76ee69eba77b377d673f771757a330b6714c40861032f52a99be0d3a9e7a513cea9f73c0b1d0683b19e57ab9b00d4ab677a1e9eaf4e10c30a22c41045f1741167f1e173cf6bd4a8b1e2e1e1e151810d3327b4389d4e279c4fdf79e6390c0683ad562b1004536084ce196580df79167a8dd7eb358e230aac98a1489211e672b952a9140ab458912325d552a9542d1f1f9f4e88294374b18342a1765aadd6e974eab0046124ce491586e1cece0e0882dccc0728e6802a956a1cc7edcd1c293118fff32c8442a152a9540d430a3645a4fef3dc1314141486a1288a4d726010c3c3c3c383b3f89f671e2020a01a356afce0ac653143c60ea7dfe79f07fd87c1602008d21facc43102fc7d0e3a909090d0388e3698819b243c3c3c3c388fbfcf40ffc5791e1185851726912e65e4d0a041434895315a1861b15829e84005132c2f266ad6c0e07abd5ea9540a0532395cb992f271b95ca228a200058717e4882d1f1f9fd3e9a482325918a1e6b4d36ab5401054c1943392b002aa767676c6714c419426278c8ca9540a054e9640c12115a2502851143b315ca690116b8461783a9d382e3758c1e6f47a86d5a8510304c10d06383144015dcf4230186c1cc79a450e4fd4197d9e7b848484a89c2dcc8c49b59e797a7a6e424ff788a2485ff0668a1171e799060f0fcfe9749a56b02871c509e8acd7ebf5ac7a66d1a071137a9a06088246370c9104f83fff7ce572b99e51cf2b16eb26f4346b1cc714c0d46003117f0efacbc7c7e7397cc6abd5ea38a3d0c39015cc093a90a5a0d45fcf4077b55aade71acf17e39bd0d3f885f30965547106114007b204f4a0ffb89e7feeb3b3b3f30c7bfebdd785f3094398c4a0292828e879e9e740967e0ef4209fe7d75b2a95ea59e839e8bf0fce2a9811c1840b2020a0e7a5d7812cbdfe73a0d6b3eb3b2814eab9e719282828a885730a6664d8a0c4cfcfcff392eb40965c7ffd67e7d9e7aa300c9f799e7f8080807670ee7ab0c20519bc5eafe7259f0359f2b9eb2fd573eba81a356a3cd3787efdfcfca870deaa30b3c41b97cbf5bcd43a90a5d67dee423def3c84c160cfac67d7ebf542e15c9750a2852e3e3e3ecf4b3b07b2b4f3d67dc267d56b0809093daf9e7d5c2e578833ed028b9b2e5aadd6f392ea409654df790b67f0359e5187f5f4f43ce3e7968fcf4de8699f1a38d32a2e3863c4cececef312ea409650577d07e7f1b0e7f0423c3c3ccff779a7d5ba093ddd82e12ccd38426608954af5bc141ec85278d45538a72ef45ce33d3468d078feb36a67e726f4f48e10ce2adc808c27475028d4f3528d0359aaf1f028d879582cd673d0334aa5ba093dad3a9d4e2a60e162895918de049f0e9f976007b2047b8d87389fcef32c741a382f9de0ebd5974c107b751350bd7a067a0ebf7402ad515f32e1d4a89bd0d32814987421c517356ad4785e123a9025a1c35e83c673cf592c168b853da081730a6820a7c916180cf6bcd473204b3d173a0ce791e72b24199b283852c614660809093d2ff11cc812cf7b2e8473eaac671ac737646c7653c8f8e18b9e9e1e9ef7e02cded56ab5c2322e39d039c3c3c3c383f3e936a8952196040106c5c6719c529af0b0c2080493b19942991ada5049fd5cc6a6288a2a70638317b41169fcf51a0f823f9d4e011f0e42bbd606b57073436374b2f94e33ab69845204615e14c52efca77d34d6859d285ed93ce20eefe1abfdf7794b80b50fef21ce3e30b02794220820f6b9a4473801f7dee57d7e7f972ba66f86aaf0ac87ac2b69ec4be1f15e49873c9c5ffd1de3cceaef535412417b9ffb03d67552a1312993e9cb9867d364438d6c9311d4689b6ea891e4b6560f9692887ecbfd77c33bdad6ad774b92ebb821ceadb1bffa89df77b0a35dc63cefe9e71a6ad49dfe5e4b87c25069febba77339fcfc49543ae1397e1f0e521b7551ec71c219679c814587f847ab510757a106beabcda1623446cf73e9772e9294297bbf6bbd68073f0c5afb9d409ce728f6f83a4489208cdf3e7eafb2abecaffefb4010f44451148350effa4085976108862befe1c5d00777544a040f67daa8a770a61f985a61f0282e0485b8a33a7f38d7f0e6b1c34e080a2a84604ea1bf83b8c33943e7eed74778151a7c056f770fbc37a5881888d6795651843c95cc1c1ef76c2f8a384f2691c341a815bf871753e2a5d8e37be8dd3c3fa11050e0439c670e825da877174308ffe1cc23fc2742281efc4c32737c0731ebddc79b678f57892080ffb08fefde53a0c8c22b115c8da07894782ad3de45dd6a69ec0bf1d75d75ed852e7eea9e9ea48d23091ff71c84865fc8611fe0a764e6c841a88fdd62ccdff317446b11fb086fff1d3f0c3fc510c4f0c32eefdd51dfbb1c84b6f8a651d8c21983681dde1e5fa90d9d2ecdf24d77074510c2fb1031f74f1421ec30c479c9da7ba292fdae77eb0dc018f200dbd2a371ecef1aa046dabffe3e95cc1c93a93bba893b668bd855817bfc08dc6321fd5df08657bcf97b175eeb8557488357bae9205a5b3c95cca2ee495a77ebb9bb6179afb4744810d5b1c5abd6dd2d04595d2d9c71bc98bb6bdb88bab58e75bcb2519b78e577bb536e56ed6e3808a538083d4dcd05704ac9751c672bedba6dab526a9aa669934a6a46d334ed07d213f3384031eccec9edfbba6be18cddc76b0769c77d76dca76ced863b9dc6852078badde972a7bb3578a7240ab977170fd2214344dae145b1c70c6b73a77bba5a8bb79e2e6df156099e42298e380be9f1f666585b56f7623dbfbb6c53cfb5551731963406ded561cd1d144170477b0ad49e025977c5a952b7bbb54fe20e7bd493b4f186b73f601d82e29d63275e0d87e72e0aff80757894d8e335c60653747810158678b6786b83a830bcf6b66e18a524ca631eb36dcb73251de20e5eca711a2e3364c890fede59b18702269cb11bb9b9dd622bf690b5b9ad3665d12f0b9a2749665e70a99d659d7fdce8ca7196b31cd5ae752260398bb8d35cb768aad1a9639e52ee94721cb51a15d2cd8a06943090bb9aa669b52669deb9ab69da9328e5326affaea66968643734aecaa1318eab7234ed7235ce2ce25eaf5d4e7bad5b3457e3cc22ed55bb550ec7d56f577be5b8bf667dbd1c7749006be56e92e61d8d93317e468ee30ed6aed6775da7426f7532750e42db3b77ee52dc40eed6835214612a9945f5ddb93b72efae9c45792669ee244c25b3887bc75d1eb6bd8393294903d2b5c7bdbbde250d2b28c3ee66a4ee9ef45c14e38e4820a4395cc37a3d40a2317aba651c4146f280c6e8b7461575fd490cc1cfabf47476770fd0f596603603e8ad1dc7d6e991a8913d359a7dc2b94826e21c1bfa05716ef57c388fa9b6d87eca2312fcce71eb7010da3c5458d24469ee12ff40eaa1c292064a73dc6b73d8c55d48cb688cd606a70882ed8a271749346f9043d40d0b9a7ebea146dc93a092866996c487a69f39343dd532863446cfd12c631e25574f0f8bd9903577b75b5bf33455721ebb01174966338019638b11506a47b7300e9aca6b4954ca906633006134db83a64ec6490494638b524a290d654d271719823354a915d8c0ad4e91c7d6f2931ae5edf5da359107e541ef63c323b69ac45129127006b100596b7e5ef68ad9b821cb785bfd2c0edd7577db756368c3396439ab1db5baaefbd25d77b71dce3f60b1e9e16cdb4651771f5b5547d7c96231193592b3f35b1bea1c23801a2c53a678b2450d4574147de1a5655928b5597aca3269641e126c9c88484811be8504174a4024c468e1b35d0c86b4e8d55a6be560374f550b40ecb0250a356eb41000093350364d36d5f9acb495be408a33d038f1a48e184445acf04452d9b66ecc9623223303194e70c182158ed8482386126d0bc3c471384d998de3382e8d1a17ea6369de701a0b2604ca0a5510a941892d5c880ca0e9cc128d4b23450bf41c77ed684ca30593b1b5851963e45b3dec6b393be286163b5fa68a336e21c875a212f5c61794083790cd866d0c49b421994525eb99408626e4e460a5852b9a10400c4c1c132b4eb62ed68d4d5dbfae35dbd6c86a61a10dc9adbb4d700c9fc662649a683050a9e3152a747c6b64b59ab417a6743d2c068bd1d83c6a2a4cda90ecfe0b4646f9263a2457b0c68e48206132040d4d5bde90196a82b399111343139699375210d1a1644d786171948054ec61f6021116a694d1824fcb335918d1b6e56c8a17efb819ecc89ad0344d6b226bc2ce6c80644a538d3359e8c0c2d87236650c101155cb336ad484e146089616ce40b3a60c38597ed0b1c57a63228b15b45a9eb9824e7f2d674c408164931c1850d684a4810d47c8f05004162b6404608a95300c3745641cd09423a7d914292c6421454917738e2c7102002960a4bace9880a2ab121d55d68445b53cd3029a66b59c4989e20b3735296c9ac0d8906972858a94265d5fd051b7caa67ab1a6512dcd30b1662363ce903952a2c8e91ccad917394c574b334990a162cb9994212e1eb4b5d31352e060548b803c02871a5c30d3c685269ea8d1f22d6a345ea036f86cc3839e5ea55c3d92e5960b75eae5872d7632ce31744896a1f6921e7594263a64a576248530320317735ca812e60a989b28703a3cb658dc7615b0900196333788a2cd0a84a2aca9b3286c8afcf568012d80a30dc9d6b48317c6820b9470e97cd94737236bb0a821823233406326065f2c3105a779d2d37276254c732d675e9a00756e757d0d32b001923236b059a2e3f6fc38ed1cdf4cb4042b72a0028593268c14390498b0704c708cc05e083383205ef8414c12414c4940a6259a0cb59c3175e9b0ce8f8cd3c8ebc99b1795715e0324c49e18f123d6da7d4019e5ec09d772c684a5e58c494a832d674c493a6c397b52a7670861ed244744615cf9a2b32cb365b565e749945ea62c8d25d158fd0707c76f0b6d11fa23efbe894af35284c08f5c87941ce456d7138cdeeb411f0b67fc80c66a0ff0debc0f0d8f8019406375cea9cd393f429df3b33b38439823543ab56e7e843aaf36bb6e84da5dd9ed8de05d69e45239801ab95418c8ecf912cc9e9fb33fa046136fa1af670035d29ea5115d9ff4010346a0d81b8b80d9be832b1daaa7675970ce59adb578e7ee3c779ded54afddd8a96e0faaeca6527dfbb0a7a54224f0f3b44ea5b256d5d4b3bbfdd66d3b3cac5b64e72c9e3bd76843f33b170c77d625428255edba0ebbeca76a752b1daa497a264132a4e76dedba69372592a8da716cb5629dea4a8ebb0d3f2f055239a8ee31100c5558d298b51cb6b803a376b47a3d0736a0810c60e002aca7feddebce732d50010a4c4002118080080f08c1013d1ac043e290aab32e083b943e58808e4e5add24baa6d5b55a4f955185a0276bfbd488eaaab5af36c98e388f289c5b5594f5acb58615ac5ff5ea2dcd613949e79664167175c372f5dc7d3bd8ddeeb57b5ddd983684ab3cea70e6b0955d5f6f51f4b504d29c1fa184a0064eaa00d3a6080d6480a38d12dc72c68498065b9ec10206478064d69b5dad67966081da8e8d901eb07811c30b9431987c3840163034b2bc89415b23849b2465ae58e922064835a0ce60018356132f10c38c375f98d061883947599c8c599450c26d5958086558f82c916d2c2c6c5875cc58a269b32c683adfc2000888864de3d2804b9a207322c2c99e1fa6e0c24311308001a3a31a75ad67be30b1446a4dd4b3889c5a9e19d37403000090840e1d18c418c2ca9a2a3ac092a562b9018aa661a9a1b5ae3525679480d3aa96677cc8a103285ac8a1062aa0e0c1cc0d2d43b8b1818833a270819b2d640c70841b285e4b336ac840c2c88e2da6e0820a1b9288814d01bcd8f0044b912360ab65ede4e69c734a2d896e542663dd9a386fb2a2f631d2b1c722a3d671751baba6d507d12db4dba9eddac7766d6872d6cef9fade4e7d6cd7ec86ab6c2a275c73058b09068771ce2de33cd338e793f1deb8e2a6832463cb99161e8c5c29e2e40a9424576268e1ca9546b59c15b14291990d3368afe5cc06319496bca146f3b2c179b7da5a835a382fedd9387c69390313e646cbd9973a0d72e1949c1d6998302d5b69890ed448cece4869d9209d929ee61237d4c8353f7b62a5256e5ac2e464624e9939464c1aac7069afe5ccca0c2d675698749e2dab70d156d05431a3c196332b637a522b6c7ace28a39cd940a5734523c40ea30d4c5aceacd4e96ce5cc8a1856aee8f96a03171b7ce06c58d393b6600e97393accaa0c1141ccc6c87a496dabdb653d56b5361f136d7af6945119f0b05b0e1746399b010d0bae6001133d1fb2208e066634b0a9a8173572f5d0be4d0ed55a83a893c4317b9ef6409d41bbd67aedbbf68940028e6bae04dc83703d3ad04082ba9ebb4014e0006963abd747151d2029ce5cb85d7a49c3edd64f1104faaa7dbbf5dac383aa4ba976bd1735f2ea5d3d70e6cebad2ea2489b6d39ba7763315a1d66b5dc8894aab6b17757ac7bfa811aa1345b0306a2493e8267ebbaed55594f59debea61cfba3d0bbb567887904eddd54375f1aa8b17790e82764e75533ce3f5a1dd1e7533776d042fc5d972f5dd956de28eca69e20eb1077d7d159528aeb2d6702825513ed924760e4e7107cf772e450648a2f924ba733fa0311e12c7dcae0f9edb27f1dc245bc31735f23ebb83a9bb1d468db6cf83531cffa246164b7b77f5d8ee5d95439e4b49b4b373796edecefa1445f09eb75b34ed9d87061d9afba6347ebba7bfa891c559bcfd949228f3bc5e04ef3c385b11b883a810468de40e218dfa8bbbfdfc0ef89deb1a9ffaf6d5765567dd6c5fbfbaae1edc55e7aec2aef1ae1ea9834f1d1c81c8d491444a0e683c89a62eeae3dd21a45198c6b5dad0fce9fa105b3e40dcdf45a2b1697137eba4da69dbb09ca753898724ea1dba0db17d5cb76d32ed25c8da47bddac1bce1530254cf76f51cf664b5b4217afa77d4a55d5677d486281d53a78f6947aa87d98a5f5da90dcdd41d6f96a170def0367e38c8d6dce79adebe5b5b7b09b2deb08f8a3515a89091562c4134ab05d1bead4a57f072ba361886728c894a94cb4829554aa2a1b8c3b654a1bfefd27a63d71257b1fec299c2c41985fe24ced586634bc4f905e20c0b71b6d11fceb2507cdd62e6e82e76dfc3300cc3307caeaf67598738ffb881f314415ce3842208aabbfe725d5efabc6ee1f3961c6ae4f3ef03bbcb7d7581cedae1b9d44ea3f5bde7d4e26cc70ee71688f3439c631fce459d2793d7755d67535de785f7820e7629ecc3bb5da5bcdb9f15ceb4ed7f70a6edbdca69b007e722382d9c634ed0c0f949f0e0dc4ab383f1f781efba105c75d887c7d53a9d39af6ed1d52f382fc575e7eaf3ac72644363dc941bf153c4f9c70d1167597b1307a10d4e2470e61027c648424e1a2c662de6031c91c0418bdfb92e5bbcb2b8c609c21dceb541eca271eee265ebf5a8ed32e8a77f94758beeb3e79eab9c16af4289207c07b10ff03b3f7dc7b92808e7d80fceefc1b9d56ae2c1e0b9b03b8fc55f6d4eecb07d18d638e02d16c7d386aa3c7882a29288e7b855e99d0bd2f058f7f5d415afbab25717e8e3cd453986bab9d563b62a498276348ecfadff3cc7829e8be8ab2908e7a2d80fceb1bf35e2dc9a93c9c3e1e8fd937538621fdec17f639c99a37bcfb30c47eb9983fe2e7301241520f6017eecef3b0b0c3f719e23ceb543ec1a675351512cf6b75ae318befb71a3c1e71f377afee759d622ebb9b678a02b698cf5d79592e8bb154100ef63bede8922840dcaa1ef54c6b2ac682876dfd34ab5d75ff81f9c65dd7dbec69939409c978474f897289e1395c470bcd53638fe14def89e3da0f12ccbf03c4b343bcfb2c988fe3ec9a6bf0f4e7f6f5599c4d1f3ef1c481cad7f97354e01668e0acc22faefb4cab9b4f6d02e1e04ed2216d2e1cdf5467f07c110bc636df00af971a3475ce3cca2eeac9b6bfb7c5e17f6c115983966d32ca2a75fddd4bde0b75b6feff78f4abf259a236f922469594b34489ae83a1d36f8326dbb85371d6b89a6051d1a4d0b5b34d8e11b1c43701b3b4f2a9a5e4e5528477b95a8b41dfc6e27d60ebb486dc83ebcddc11ca4aa02321801450d0c5a28020643d288d11487882a867823c412688a3833333366d682325a60404310525e10c412208260810c193fc8f1e18a3134e8a10d0f46ec7046871fc4e4e0022e39b020cc0b2d7841131c5e50040c9d2f5e78c9a20b9c1b9ae082c41621b40091450c962e57acd840c50a104faa0071840537a8e10b1ab498410a199c88610d0c44500962053bbcf065ca1529314421e3021432495c3883298c275c38a1a2c9134c945892464999167a488203922c47663012a5c80f4a88fcb0020b63cc15ba9843ac38630666b0b9819a3a66e8f850461832b68c51831853c2f08109183e10f9a28c3936f0020b1b402187892e8e8883860b325bb8408b1b6a50258b156031c6c915638c5851a78a391e155a4c3185144f44b1041c35509ca10199198879e3e5892b3290c189286e7a58d2440f4498a0d3660e1b2d96984289279258628d9a189c4182cc11628cf0a2e64a1132a489d2c4c31222782032041d21e6a0d1e2cc14669e98edb0849565d428e04c02c820408c075e725cc121c301a220edb0e468072246743a9873430b034c518027385842a6a6e80c01c81089b1e16500570420c35094980e4b02a0031100d0a93107a685d014f889bbc4d5049d0122f323e6e5c575c547869e282d314b688821c24367670e4b8bd514aa27524b8c6a50674e644431a117f08afd66f0a658279d0b90702e18b29151c7b7469617dac7d8615ad0f1ad91356e54346d7a4b3f524a397afad8a6494a7378d3f495527a99cc96e26cb5395fe46044f7b49cb5604d83a81458a09f4761625705700a3a50a0d7b0380215a2438a4a23245115e88cc0dca4941bae525629e7a4cf53ca39a9a4755230a6e52477aba59b56b346e7a9b664d44eb7e7aacd39b9ed56cb0531eba4b1b99d282602f466a78579c1069321dd6023bb21b3ddb66d97c5605bbd81919074a8db36b25a9da66d465ebcae769a26b56ddbc258e96ddbb66d832181c972ccc230d19b0b3ab64d56f165da9195b564debde16a390b73a405753acbc41840508e1f34490f28a59452392509f294524a29a5d44dd34973a86d2f45a5c962b542200f28e8e7af2bb1f0eb06e0f29915be06d0bd0d8a6594487090e020c141b231210cdee21c6b7ba07b378ffd73afb627b254af9fd3a05707f504fd08f5dcfc0ec24057b64abc70f28f58d7b890c5416ad73838c3f0d606ba42879dec08fe3cc8839f9b67ff586b635da6831c4063416bda880e0a7a120dfab9f6b3437bec40b70409a77d688fc5aedd5eed00b87936003ef42ccfdc307a46ea9e670fdabe650e0fc822cac1edabf57e04205b7d413c1ddc3e49e218c02d06c003d03f38884e899e446d789ee7c95ab5f39f9dffdcde9f07dd3c3be8decdb2f6542c5044dd5a7a7474a0a0af8e30c53ecf4820a0317a0f5023a0d3a3e074ca3a05e990fdebc5ead7c56be3c6602d6d08084b1a93d507a96e1ea1ed77565d27f650419b2e6d98dae21fb25e7dad3bdb854400023c89b6aeeca02b1be4e0cea621e11ca0e8454fa220cf2dc04139deb814950cf024ea799ee7799ee7b1520f4a3de8f606bde7e6d93df73c56d8167562bda8910abc3d8c1afddc3e468d806e6f831ab9c6dbdf903844a4eef90f8eaec974e43afd649a5228bdebc64e87ecedcfa55d8a80f9013afd08a8d108b6685c9e9bb4733d40fab916e886a3ec746f3860044964c1a09ba59b1befa9d237ceba590897b64fdd78272add22b5d1add803853450b084696b747086bfb58df0043ab8711d4063f606b823d05801f00734669b832b5b5644001c4457562f928debc17793067049108076b384d37de866da59c279dd12d4ce128ecfcdb663377bef4e45a500a0e971421625b08013805b91b423abc301f44802e0ca8ec9e88feeb5a1a35398c4714f7109b1f62174d8f35be8f8f9d5f420ec061d24a1ed6137c71a067b9206bb420fbad9e21fb1b617825da1a3ebe17b5f92686a1a92112c4162b143fcf74f0c0f822feb636f4f46addb5bede800b71fa9118ddbb7b423a4db9f1af1dc3ea61d1ddd5e468d766e8f448d58b7f7801aad8cbcdb7f408d7a6ecf006ae4ba3d091207ea16e71f124e734f79ac031d04ba5e10ce427ab4d6daa05b82ac7f2ec51d400f7a12057ad0bd1b747bb3acedcfa7a81474b38cf59f9b4768efac03ddece11fb2565df5240a7459073523e35f0fb2d65a6badb5d6023d897af640f780766475d08f403b9a43e8417bb374d341400fba60966edafee7921a8120db7b5010cef6afa0fbbabdaf03ddfc837f4837ed610fd098fd0b934063f6ae3b011ab3f7b91aa0b19e2b5b8a3d78041ab3f700d7d2217b1a17e9b6e8903dcf3d8dd91fdd181db2dfb9321ab3675d241ab35f5d0f68cc5e759368cc3e753fa031fbf13280c6ec51170492e8246ae7b2102a128bb64a5ded8182365dda24698b7f482cacd6010d0a5385504aa91020929a0a19334b906eda07c592c66e98a8ee76d66d6ea1f7f9911a699ff35bd53c7c1a8b80a1529e82e9e8b5d92d6ab44dc96393939ee6b9b961d79cf695dba8c5e228bb88d4c880a01c272d0246d20e8a8091f3f2069d43a376f9018d5e76bd950ad1a6064015801f907946df739da4011646a0981d51470a115fc2e0bebca005584488983a65f0b00218343f98a1a30ef1e58a6a26882e8a7cf1029b67a208f90189932ada585981943174482124606d8cac974c566e8b33e78826169200c20d0b7470689ae3380ed6392645ae7141883648348983440d3ab433532c13cb84894d82c916536e5006921e9ae860c60cd396fa05872c367c79018a173475542d675ed8740c630ee7432f5f74b65f8af4bc3d61ac9cb66ddbb679c9a137189b7a8491dad4f69c63ed242a0214245ea2a0718189d5c50a221b92edcd57eb56c3d812a58b152d675dbeb4fcd67276c31bd9e54d774b7060dbb62dc96d3903238e0bdc46270b91890c4605091a1ec44815196d8b93b32e4c4222345acec06882e341c8dc4205046ba8f8dc28e04446d39c1a8479828c2a746cb7db1a37fd25a1c485355fd009e3098bc8184efa5b2735ee8bd9106fb06031c70b2d3a2a97325063aa3891610041c707333acc4005120580b1d1098389152837a72242ac8a701923562e5c8ac8aa6402c5963851b8a123061009e8a28917c69a24ae96b3309e7869c25893c21c0078793faf3627bd5908bdbc93d2a9fd47d8f553484b2634263b8e09fdbc1437f9fa79e57c951305f49389a4f5db9dafd76e435aceb6ecb0854bddd274ea49b9245135aae7ab94445dc0c9450b0a0c007e1cc76de1d21ce76955ab58d3b6ecd01c5737c95918b7552b505c2764ca1c1acce8414a1373a0d0c121a0b92d6034a76a8ee3ea615f90a9e2d18e0a98c217a1028053ab43b3b64493e60d14d80dace85aceb638d932448b1cdb727603281d5499a10a53cf87485ae0d42953c588a696b32a635a56d1a1ca979e0f2350e6c610230f1ac580d099247e00830b17b6f0e0010ea72a558aa18516663cb166055490c8a10506245a98b4ac9025998ea8744a1a892331cb9c42332418000200c3160020200c0c07c5a24996a5a2f2031480108aa2404e44134982912005410cc3300cc3301c0d108008328618028831531e1c7f25ab73148b3e696ccb3c2bcdce8ab56575e1b3a69aac3f5556e7c8aa83ccb2e459a9acac987d56079e35d51aeb8f0a56c799558f9465cbb352ac59315b56273c6ba2cdfaa16475ce59f5882c5b2e2bc5ca8ab785d50127d6549bf5a3ceea1c59f59159963c2b8d9515b3cfeac0b3a6da593f6a56ef945587c8b2c8c64a67112b66cfeac2664db459ffd4acce99550f9165c964a5595971dbac0e2c6b5a93f5a766f59cc3aa430ecb9665a5b0b262b6ac4e78d65433eb4fc9ea1db2ea10597679568a9d1567cbeac0674db4597f6ab17aa7b1ea20b3ac9166e5889195b1cdeac0b226b4593f6a56d79155879c65c9b3d26c59717b56177cac09edb07ed4acde29ab0e99659367a55959b1b6ac0e6cd65493f5a7c8ea1c59f59159963c2b8d45acb8dd581df897894df32766b58415b31a70d69a4dd64791d57b64e911b32cb32c3a2b2bee9ee582674d6d65fdd4acce23587a48b02ce659345b56dc3dcb81cd9ad8647da9599d67960e22cb329f45b3b2e2eeb21c58d6b44dd64fcdea7b044b8f3496659e456567c5dcb31c0a7bdd9fe01bfbce7a2d52b197c6feda5e60fa587343a9977a2c1b3d33fbbe9455fec816b364a1c766dd94b3ca3c5962d662a1638275ab9c55f26689b364a16167dd94b3cade5962d62c74acac9b525689274bdc9a85169b75579e55f664895b81850e3bd6bd5256c9234bcc92858e957553ca2af1668959b3d062b26ecab34ade2c71ab2c746cd69d7256d99325d6022c34ecb0ee4a59259e2c314b165a6cd65d6956d993256e918586c9ba57ce2a79b3c4595ed06bca2793853eca672d79b2c45559d130c3ba938cb58ccf573d621ab3685a2486d73352b4d5db98128a544f4663603e6989c935978a370fa63454bebb2ec4980534dd0757c59fdfddf7558c2e375ee526864c2ae17ccf435bbca692492392d26018c8d1e7665a8123e206d85667c852119fea144383371a4c9b4fdfc980cb2daec0c313e4714a4ca999df1727171f9c4eed50bd0e1ea34afb0136ec6919b4606a8991399ebebec0195edfea9dc3356c98e618f254bcba1eca75fae43cd1d7ec3aeda5f4bbc9f0b160da06efb9df26e5287dd42afb27916c0038543105a1824a233694f623bfc99a1b25bec8e3efd658b44013fb17e1379930d102be39d86900a01d7828b5b981f066e4bc76f771b068d1493018a818de80c0f5b802730eee86421ebbff9d8e04ce97b85fe62401c9253613d951eceb1d4c6c2257ddd4d0c49e5315980ef4b613411f9c611a387d0fd4c21a58c6c11e6f585a9ea199593545759dea52b98dd350a3ad9e7c5945aed1d8a90e331e892e62b5440e96020321c8859aae42458474e90377c1a6212c509988ec0d934bc0ae942f5af3f381864caf169d97b695751eceeb00efee2adc093e70b429ca5bfd184dbcf51b813708eb985c658a70a9447e4c96e0866401ea3eeb38fba95a96e1b108d1c100b1ebb7a6d420c97fa2ea1b107ce99b5da686a08d96a6f10526ab1dc3e79c7ea483d983b0e030886d74a5e2b575a4d53b5a077ac9fa48fd48caf807ecf25b759d93eec4ff3c2616c6c95e6496c03b85b2d7d0441eef9d66c89e7a7a7e1828e0fe886de3775b03c9ccb9d6ddc52f73c4ccf4e7e4e4cb5dfc2c4e9a098ccba3b493be248b63992bb453f157a7be8491bed7889575ab8059a81bb244d5204dbce639554196bdf15cbf8a1135de18d1ab3019944a3d8e40ae11072240169925ec3a311a5a767b6ad83787726a41af2b7241774b460a5d7446ff82ba4f087f10c9716f57ecc04c93f3ab92d1e0f7f911964acf7011b584c860b04685a83bbd8c787c388897925892e0cf7c8a4281f6954e7567ec27d1387781e7b36ccb1a3709f86c864eb4f6d780a6e1f11742e11fa53dbf203ccf757f1fe944e7e331cf6cda17f6550bdaabff1b48496a2f5ceab14d3676c9aefcaa7ac6dd0b006aac6a6b0c7be2397254ee0ea60555dd4f10ed18eb96d56b0f26f08d6b4b8a70e0f705904bea702d6351e1facaffba0c505256bab633804c4edda0825dc20334080d157a5247972870db50db2a2484cd16150c49786457a3da1b41068088cf104843c151204eac57570a50bea403b567e0c1d02215f38d25c3a9b2bf10e1ff99c370f33949b80cfc46467fd103fab22021231154084db8fcb197ed1064f078cc3d095709dc039434591ea62d86bd2c201f3bc5045422a74e957e2a50dd0ae69d18101a2ad2124aa798025655ce6a0d7dc3e848baa3f98fa4fe8ff491b6af896c089f3bb93cead3579ee9fca7e47b7728b3322b5eac0b26f984a59b0c997e217fe8978eb6469a6a913fc8fe13d932bb7b6c992ba15036f3d8082df74144aa4481d80dc186c1934adcd9fe0a28b6acadb3795fc7eecea63c7c82f17d6e1a0b6acbd89ade506a400c1df7b516af5cd8791456ae40d73be6c714322aad97df76b1a7ffe53b18d14bf67f804a50206493cfb363cf70be2b0817f1284a290cf53652d53006c2de08d93b6d040ad1e308f459addaf32eebeabaa043fa598826e7639845590808e67ebc45588ef785fdbd6f7c061b8c218108426ee886988639064029ee0383f097e5bb27fd088409980e1ec83a8bfd0f9467b2cfb873f706f1b45bd4f0f9d5a30426ad0859ba1773e60a0d8b55660ab52bc32ee3ed6f44dae9a3c0f23368ad69d6859cd9eb718f0749fca5821bcbde52a9ddfc25278ba106bd5914d18ceda593f20d4b9a76cc7da77e5e9b2d520a70022457c69617fda87d3474d7d8294ed0e9ee9b653d96ff78b25728d1df8a2d5c73af2fc3b39f2b5e2f105c33c68719a090ebe852a46ad6ec6a83b550d158a51e653e049e258fa29fa6fab459f35e212e57a55b7ecdbf3cea22bfe115451c98d7d96242398ef845146a0109893df8d3b8f357462a9be324051293ad1273d0f863827951f8ecfe2aaeec0c3f4113647d361159db98abc753f95c13b15f5d2f36f25daf0607f4dc00b215e48384a68cc509cf8ace9f2582cd5e400cbb8e1892f689e72a96aafa2c7984ab24ad42111e670f8c08198c241c8618169bbc52dcb16c0fb6504041fc190dee09ccdf460368957ae2a31d3a2b84760bcad4d38ac71108ff4080fb2809992191162d5af24447974689894d52741bda3d2f6918c46a5ef5363685b71ad78ee88b1e0a096606e8d1db8dfcbbbf73e4b413c0018df8128bf1c908c762213b86f6db81b5e5ed76abcd9002d1cd077e3d7d8e6b317be16d88f004ab83cae8e27360794a3f99f4997edc15595c766d38eccd5fc796b23f1064fc9a35addaf9a34a0bf0ac6c30cb1ec8c10553d6c620f5cd9a301a866e4abd5df2a77d93a68e0765066c6dead2c0c164ca1821ec5d7af62491b94ae49b8c0a0ef737131207d97e624cdc26361a8589a347663c0bd3beb07c4e0b2612db26c3eda230f12d5be043dab4e1330d1dcfd0392695b5188946cb104df564207dd64057739c70765dd7de32af76e3e33c546a14f879dc2898318c8007bf1eae775149959a0ed6b41bdf09efd391611b62156d84515ba978723bdcf2c5de452540138824fc691a1d9efeafdb16ae2025d493ffa02a3b25886b09cc250ef978bfc073670c14c89f114610a557cb5c73961a66251a5ef729c403bb83a1fe0c2c0692364a01faea64f98f22a424feb3afed1c109ee7aaaf8b0170e2148aa6a5a368769db2e3a879b534cf993bfaac6384116cf7a1798c4e7b16e367a8c3af44f095a5b4dc8f1c07897718a70fbc295b926a78b25544db1df96e6cac331a60422c94247163b9e777ec0ae8f8d1ed7c18dfe46e1f7e85c81406281bb8a16a729c4e73da5c17aad7c229578d166746dea5a5dd36b1ddb516e3f9c7b876987f39d1ea94907a56222a2805d7b99d6568da5b49e594c530de2c4fbc452e40ed716c2157370d81e7d188c34ba6ff8713520b636d8bcd88935696b21e12a0fb5449b8186c1f3ac0051764445e112100b827b1aae391a876c48d7a8cf253a69f98b35ff93eab05ae5efe850d62648efa460d6e4047eed4c93ea319d675bf3f66c0d10bc693eac2b07427b1c71c727fec1bcda7bb51f55180dc4c9441a403348c35fc2259ce7b240749bee1419e3351fd860af1eeac7a07961b4a784766c9fa8ce48a05f21471d50b34648c3804207d69272a3545fb65fe7f51c04eebb2e607f1c1c762684e3d8540e2c8076db832fe27ead8fef7a27665a2a76d42bf0fc14a45b4c664a747223bc44f2fb47699a63e35d35ddb1f7bb449fb132341fa8295329e23449db125794498c92bb8e22c14f3b54b40f83056f986a98240b03aeeda78a4ccfd6c053515f1aea59a1172b694b8cbc546beb4afde8b380b424e537a45f7333c27a9fbc4284120e2fa35b0184fe900b16509d2fc7db7fcbca59504ddab2ae4d5d9b7a0e61dee00bae0d2dfade3c9ddcd612314f48918997acb22e5052894319a496010de8b464e3df83f4c1155c17fedc8ed48327fcc63962cff5f270bea45abe1bfaaeb376cffb3428513f4402b142604a6e984190721a74912def7c25e0b264b992f5394c6377c09c59951bb727872c720b5bc42e73da37a5e2614c5d0f8de11c968da759eaf6746cf6951d3daae751ce658a03a5629fb139279be8fb0a1b44e6989216f080e1fa64bfdef561fd9a5fb18f55689deed08742ad093759df469e1e87e9db6fe7c7e47c0e595e97bd91140e480d336b4e524cb66c11d013e3eb7f8ed387d5afb3b02dc48bab7cf3935794d9d6ffff56aec08b4780fcdcb013b051b00d15ecb00989934fed4c0e5a0c23d451271e17acf4e021f108ec0fde074e05946def71b731924e94146eea8c50684eb362a388d4cb9371397c016199436c2ed3662e7f054dce02028fc54fc8b4852079ef605936a3b5eefbbe4cf49e8ea6d566de86d349c91eeccaa1d34eec1af71b38308b60f0789f89f851a052c9e53ee755053e9023f1d655198388c9671232a373032f33f2760f050c581ca51826e1c237045016c200ee29a6814a8ae3f00d8b97ced85ed45ce9ac441a34ad4fb43035f292f43981340b6631289030788307431a0edf0701c6e0c28c49ea940c963f4002f910445463c27838ebf02619c5309408bd208ca496c9dd44a2b8168fe069a8138f1cfcb819dc551c56a1cdbd6153f91a374b81ff36ffb73a51023ed8f5fdd2c317ddaf5aa0ad00f4194e470673697606f6aeac79ec49ae475f5483c6af911752cb38c97eb2978bba88225c9101fbc0f4e5654658df7f57a48574b10171f66c8c6fd8bf0e52522ad2243f74f8bb4d72fc56558f82d43820e7f2ed45fb28318baea3e22912e77340602b48a20f1e5c2fc650e068dd4f5b59f1658cfaf06ae86315aefdb55a01d34964e05ec674fa00b5057d4afa43cb29e0082295176a8ddbe941266269e8866ef2b931b03dce3023f6ee42d68f0c48f6ba04d0c8e1b9ac63133e19e34fb87ac958a8a22704f7a3c4e890cbe5614ddc99068fe0c3c50076b91e133419eef8877119addd7647bcde12f82f1a5832a2e0e8247a10786f19539def64946006b3d5aa806541467dee42ee63f989876b39867b10274719416c5954ec75573a6f72e8a4b047e937b4f431856519ccd4bb017c5291f44b0200c2c39edb8daa2554c1cd04340f381137e418fbff792c6f0a2506151edd8975a7d1e45420f806c130d7cbdad52dc96afab5ff86c7a9855cd7089a6723e243389ca0a048c5d563018f0c8189eb1df9216c10efc5c7332d097eb828300422f256b4e7ebbfb2f08afc5f2eafc087039587371e95dbfb6738e30d6c5a8d567fdd781b75b49a7bc9ac0be38cbafe65d79b01105f56292d5c9e99689ed0d876e5cbd90b935de9e9d17c4a23ded7947b7cf4d545421e7c40f00079979f859a732a2228cbfacc401ef6a9c76dc82f60d888a0171431382fd2b2d9c411e1c2f8d5b982d5673f03270b3acfe550832581cb2a281b469a4d2900bf57d53b144c0b68ece85799f74ed1c88cde1502a038d46b464dc28cc1b2499a8a09da6d129ad3d6bc35b2536528d3030a6204a08842010d8a0a1cb06efebb939f03842df3896f6c6bf226b16eb1507c62da8ce48772572c12788a90e76449cf4aceb059ceee97fc30de0da7e055de48512b24fe43c59bfd83454d311c3b9d589c1f8786d1245ff5c6b4568f94df1077c1cb48363b160cfbaf3538d5a0b12ec75d167e862e7dd7b57e8fd17fb493378b174d51f3a5b4d67fea67faf318a992177ea24fbed3a0f12024caaccafb1222aa41062633553848aadfd01482de27d816a7f9870058048ee4ba8401663efc115937eba5c9410b251fd6bf638da1e2b34ff2c50fe59f444988f3840059533d016e8cb7883b8891ecacb75201d151f77bdbc4a120b69946270753b3a7f96111b4851cd4b22815ee8139ef6f3ec4b9fdb3951d72369c3f9733de2966f20b2922b93d06f56c150794c3e8b75705917fd64893d5443993017ec36743e99418cbb2448ed1e5c281d1bd4cd4fe2c4ce413ccc8bedd5a47d1ecca29a37c1d943640dfff1e7c51219890340287ded9ac41db19324e255af3de7e425ce009064a0d37a2773f57d249bf34da0ed73fa116ed21748efa1f3ee62e358decf09d786c0cae16ec660281103468462925e6f5d3ef62d614030459d6af815d8b952278445d4f3b0b788dbf7a22414c4d421bf880533e93a3fceb70bffaabb84deddb14541bf32562d71c73abf010b0514d4038b21e1244acf1613f0af481b530988760480d5c0608421799e5105d37794508fda8fd4d9691020af65e4fcfad19b6b0b2d5f578b9fd9c100fa3441f0509bb47ab1c41b48dc7ce7f7e581df8c7500fe1633284baa36aad054073a61b6161037b1d3d4c7f7dba4a6e3ee5429513c8d714ff15990aa5b865f073e72405036a348eb0908592ff305da9b0978f874bb3ff7587536b9c7857bd57296502252393ca4be1a2aaadf86a403f06de7cf8a25446106c1227c4dc99aaf8525ac0eef5fd43b2bff6f569ab85d1aad9310f7cb7d1478f95d63af8c2d96f72c3c00ddfe77b55d697fd57d503f9b8002d581f7134861608bcfc9d3c045a5395f9b0c573209c30d95de56ba3a5758f0af15657b4a6326cccd8d4e570f3553c8ec4c77d39eee9ba1e7d9ba397f4adcc6b5abfc05ce98ccd043634b3cdea47286e0aa55dd221dd42a6a68d6901aa6c8eba276b070cbd3ce3ecd08d90d179d2d3c99b6f0ec7f7c91b5eab74600550ff2d1371eb9668b787ee4146c15e8d189d061905e05435cb07a9b0d0b34f567514d9733df374cf9a3e7342231a8aa049854314271d48303161e2171f82eb12e0c293fe6a9d1cba70a44b45bfbca1d21415594f82c9c577aff58f92e54909deb5f574caf98fe88466f1d8d4ef278055b382ed2a595a78125344757fe843925cb5d69a2a9a7f0decd03f9b80d904201772f415444d43a9862def157256625065bf933adf297f476606bc4715454a9e47e0945b43ba6f85c8ef769a055d1c5b811ec7215b9e9bc2415a923241056a24298f8721ad31b87fb9b973d50b60a19f487128838131a9f297236f1c7c0606f07eeb1151aba72ca8903c5032ed39c438506a68f58b815f7807741d6f80c1f80edf3a99c2b083cf556f92b6c652d779936aefc83af3472236f56f9014cc5d336496e64c91b245414b8d1501cc4d386e9b0b698a60cbfb30871519b4071a78929234840857c0e86b395112bfa50dd98856768967a526b897582945c25a351fd64525daa9856c9b95c1bd6bbcbe7667e884b7dfcd3a7fc0fec95eb2292ad929b0eeb76bc973c73536644b3291ad9decb45c8c67dadadda234ccc96fc23a53c75f1514346d3235eb6a0f7e316b92aba6527bbe693e2e164931cf919e8de644a59f144049c46e311612a1cfe1c6dfec69bb5cca2adb2ced676f4b73ba92a583eac1133cd58fa1b51d5c50f642ad77e10a9b8f88540edc20f023557ff10d45df943a6e6ea0f828a2b7f08d45cfc415075e50781cab53f48eaaefc2151b9f00749c5951f2486ca2d28d3f0b1c268ae812257215722194e37467cea1a5040a7f2b0cd1b8ee396841e767647305ab71862c0c81865d402fad17f4e46a0f3ace08a6dbaa3c2d56b71a5d82bf3d6b22a20a832d22077685658192d1e4e3718b9d9ded76007363f406f813f9bd9ce81861446a9644c8b1a1e038fd09400024e42317fdb19b0a1906e3a2ee5ab37227f3c78af249a73c33e040c54ed395a8245adcf9d624db4239ee5eb6743046fe338f6c028973d3b2172622679b475c3c50d7931b0cbdcb9e1a067f7a8cac2049092afb1b43e5bfc50337a54c32d999a7ba9342ff0fca4debc54ee04a620f9aac55fd4164f0ae08cbf46a1f6130b7ec422f50081089e3b38016fad57ebcceb7a5588f5e474c845d31c6558e1269e52e75beb5dd696da8442b0b1eef6f78f386e57e54657d8d832be0b5e66b6bc5d6dd8ba52c6f1babb354a82f8691e970d00318811b636e60334b190c5560019f8a1164d784a8cd369b894588b692e07540d70ab01d714d6cc5bd5d7f0e1afdee0ad2b22bb0ec50656e73436684b295c4bbcc53ad16711bfa4144f0da9446bb173c3126db417daa27954b8e49e65952aef3577b21eee7476c7c7e5c9de0d908b55b1d5c0829ca355296ae0e123fdcd79e03a156b35d5560d019aa2130b615317c5e66d24e9335b9d0b727a3f3343177c9d63dec97eb9970f3afde61ad9013a49e6cfdd25f90003735c6c44481a03452e3685da5708877386b42e923e742e049d85946ee713c7a2f58a40952dd9e1de75425d1a9df3caf71df3f64e355382162826520dccd5a259b883c88e82f41a45688dfd2903112f7c7bd89ed3fb4f1425c736b3d949244ee0c0557f025d1fa3262ccef5808cadbfc6d04f11a8b04328953ed0521aef4f6c46b7c717c754eeb1899c5465acf4088364b3eba6accf01d51faa4eed77b21c5f5b4bcebb1aef20b79ebe79696a5b5b649347eb6c2e5647a943cc5d9121ea16a8021ac8ed9cf557256385d115220e4c11b0bb2e3b835e0281cd0718ae1bb4e7c20f8dd3dce0ff8e8feeb018740660fba46807621f1f5b8f0a7aa89097a71702d84adc176db482049cfc99ec438e91a1a264fc39fc7ad912c1dfe58be83539844b93f1465ae93e0583e65146d1508b725b3b32e4df5a05afdf5916a45ed9ca479b90153f6f1ca41bc4da8e0a8d488f132647afa6095a3e6c8cea77f60c6b4fbec8fd1f622cabbf37b4c9d04ecf5b0fec2118f0e0e072c92c0f0a43499966b1066a114d4f4fbd4ecbdc7293efe38e8cd64aacd2b03d27a8b550fb029a257a01eebf5cfe57cdff364fc027fef5c4ea3e90a4f047b295bd91a47d3969d3b51397b6a99033b95dee9169550396a246bb6a45ae9235eb27304745c8fd2fa6212a898d5ef4587c89fe575d49562f62c971560b41411c4958fb049f01eb4affa4e1883db370f8225bb8cbc5c5648fed2a0f9225d24803be44dfc0575073ca17ee27b67765a0d328e83f08c3d94cf4738e13ee74429dc9e5230c81eb372312507a87af6643e5c57d861c5305f2ecd11cc95e58be1dcae3fb69880298bc1c01ccc2697d391bcca0791bfe0c1bef9190fd2069c522af7864686ce44356e87449528e419c33cdaa7e6d435a0c70de6d61b651726f7c9558ea80c58e493883ca25ca00caceaac29ea6f0ae4c2863eb02aaaeddff9923a1a778cbc8e8009e099e760b6757f2b62145d9ef92265ae31c27cf4581ffc5742d0c69aab28620c6b1476f2baa34a5e724b470c3d54a5c526e185e2099c6e0e83122000b23383647c585c82851e0811cf29421a534e53b7336d62d44920f19b182086f39c6f2e84f6c25f9faba73b66a6cd84df6d83aa805c252a52476ba1766ceffbc221157d387d1f3e3c9242e6e8c2855efc553f8cb4cf1a92688c8f91e962dd4790070d2791ec171a43838837543835eb2dddb35500ef93c75a7da633d22d6ef425b4cb34821b92b286019d05857b97b6c410233252e2d8ddc0cab8196bb11a31d8ef5aaabf51e36201a24d98eceecff1c6b01078cc327c861589c258cf071c5184761646b1e897265eb48d446f9a31a65a549b184a92c7daa25a41a591502f50df807559aafb584c1189d66a7de825fb652ad7301d1e1eb6ef6e763b0bf3b86cb5f08724c959d03f0601c8ce21971a2b85432f07ae0545e53347c0ce15f9db18ba2a374707c646f221996827697850c27c7166d0a7d1d924a657e54501236891145ea83965accb44961115b41559dd174d0042639d0af56a9908f722c5cc071436c24e5eefbeefb96582219ea7ac82e27c5dcb8915d50dd0aa50c208657eacf83a1e3ddb7b30420a30375896a6adc250fb59fec3ebda8d6d8b48aa7a25145c4e2c67022049f6f4559776303b7891825e2c6a147cd13f551f1447dff9dcdcc8ca2cfc951457f4db2a4079f204743c6db664581a2fa8244e74a160bc8eda4f9614461191e7af4c161eee223962984f4ffa53dec52351fd03dab7684f49eb9f61c925c54a94ba47cbcfe121a3cca008235ce826d598b86d5c76358d0d37cd301cf425b07d619497a0e09b8a5de375bb9bb7b1e17bbc73df7ada67d1fb8b3d813bcef7abcb0ac662a516255c2ad8aa396767d7f82bf5dc4527a7a7d29ddb5a91cbceed56bdd76039840c95d3b9b2c8ffb2cc28425c1d48e00c81c6199c51c3b5d064c6c95738a3342e69ceffbf21367cc8b26b555188ee328479463ec66b44ecff48bb061492574e8a06987a60b62d7d08ddb2c917f5b7084f8e8a73a229788ebb5348556eb5fa4bbaa90cb1e4d537c040351847dbf9d97cc46018330154835af7d73ea85747338b127a9663339148f0af95024bc3f0c68f26a9d9c6752fdbbf990e7e634e269bf12e65042174e207ae054c0ee55e121cb741de48325d9ef0647bc766045f6ea19cce791ffc59915cdd82aa882757249d46a608c4742ba94abb1dbbd1565f27827dca8a813536bdef8e69db5a9dc98493a00d890799de5960736e91f3f50e68ee75037da02e5866162b105eb15fbf95cb02f585db08fcb8c72b49e767ced00f554510bfa9324213b6191977c0ed49168882cc5693007066489d6cb6ca745a0ffc8da4b98bf9eb4f8b62f47cc16f2a1fdc72f2ecc68587f40c31ae2f1f29ada4d143a82e57ef2fd8b406413089942fbc6b6e432e954313da588585816ccf8a80cd341f22ade14d318dc2ba5c3cd3d02b66b46c5f0ff5a25600df80439c0b22254b5d1d2f2cdf9085c0e0c4f82a186986d0b8477186fb16eec203444b20636e7829c93f9d3bf0d3e7a14175615b09308c449e6bc7356d24ece83f727be0e407f0908f43209c763ea78ccbb92eb9b65833d009c8b76b8b2255cbff54c3ce6d90d745ed8dabca4845f55cebab7185dcf16b401ffd45c09abd98eb8ee14f6c9b8d22ec176017fa10458ced368432e303d33906e9a1438b50a6f969d231c0363bd1e8d18c319cc64e80bf800503d2954b99bf5ba057497773c62faf3be2378b78dc733f4612446f1c55c1a3e25749e89115d4814479f069cd2a858a483ad8ac944af33af15ddb9784c616f5a612b1adf98b0d144919e5be6428485e306038f885099f8892c4445104d8144400f1f1965a0b66d1ce4a1e00c79250d418ea87f2216d8124883bfe7f3064958405e715be7cad00c54f1fc3306ea4ca67982a58e4ceaf34c616befd514d2a6901f020d5720b15d4ecf194eca6af7d43a06b61e7cb690f8dcbd8f66588800aee9c9995f43b7f9e0ff5f03ada841dc6e50526119327e23526bbf41e427ca53a5bcfd9717a68441852fdf83683c1c76498c74bae05b61acb358e18538c7ade0c1012450141435750122fa2a5cb02fff4c63659ad6191efa61048470360b1f1ed9d74d188e00862d602f79a7710cf753d537816d3e80d922e9b3591d2160f1be3fc6dcf421d7da7722b712825b17604942c739e7fd5a78c7146eca12df30f2e86e69219f0b3b73d6b1a5d233feb1f68dbdf6929baf3a150c5bf25b046104b66c6caa73438f2f3ae7c44a04c59cee530680bb827f2b98c3ee9ddfa5de5bca95d068e3992e8eba15ee0767163afb1d602d9fc943e36f95a73e8223f2452c18ec07b691a585904c6d952419381d3e358375d1927215677b1ae2cb39564d7044b9ab566fa97dfa54f7c211f5f1c249f6ea5553f18fed1ff07f7be0b299dddedd1d14c5f00478c19de6a6b6767e9fa6e31e946a0617b7b82bafc7fb468352199b87a16f7db10b8f7868831277af61c3a4ab47655f2f372fbe35629df9919499ec189b65f2692874c4ae1a05f94d27fdee05de32d95aa4b16b60f68adc829d36839f4ce6c9f06a01308c13dde8c7422ab24c26490a483ea61db9d8aede0b0ea96532b5c29f2dd985b6f296cbd435ef6d36819e13e88ac6c57b95a884437600128213ff388aa6d3d3a63ca1337b3011f6c96552e260e8300c4343ae1a7e7e686852a2ef3269e28701721efc2997ad348f136598a113e22ba38e486d97404927baccde5b94d5b9a40748256be7104011e830025aa58e9f71dce5373e3a3d32de9eb007b914e5f261af2e4a448b73108c0eb03cb6d685690ab8f0ba9c2decd46188e620dbeaac9b67d56d7a771d1de909730eb8d6647d218c4edb6c9e926b52700d4c04e632c35d8dccfa47fbacfd07f6cc1625b97f5c1ae8e5e6e6c3a0d33a518d36847a2efb851cfb7028bd0aa5a36ddbb973fdfad570749e01311665785f87ea1828927ab1e9ad3051a9200f813c476bfca9e3824417078a8fd804e4b1b0c64de693efb1b3cea13a1c7c414a6f698d3423559f90679653ff3440a10db4ef9f9fbe87710e103e75478a7a1a2ad352b20796d6d3f9c197b2c18b114b0ada67376336727958822d5e0cfb5f329011c9dc097d7e78f4b3ebc1b44b958fbf96c221dfdd77f07f6c2d92bacfc856c2350eadb791163d28f58e11424b99e67ead63ec5d84f16731ed96425af41ce81479c08a1efd3913de61a7fd013b93bfa8ef4d55dc52f1b81f24e6ec8985a1b87311f84037c0568136c711f5cdb21c79a977ea84ff195d4013cc2ec78b67abc8c81d9e7c642f5e8b807ff753f1e4700cd958b356c3f044ab1ae43cacfbb251ca2d56b76fa1ea4d5efb0ee6189bf2372b0f651fc50f603043198617d866b097276e85df0bc242b3e322a8ca208128045eb3a3cdba990201fc59c755c69484b9c62000843d11935b4fac68191bab194f0fb9672fe9e4906c84665ad7a5952097699d203a6bba674b218c5cd6c883e84220b5f8d517005a320884e1e06097332d7467ddefa8eef0825832ecd24eb297b705cd228569b3a622696e83f981a3a4adc9edab681d8cbd46ce7583342750f5f686de6e9269ed5f94ce99437ed3fb38886ea46de1d29c43e514fb9b2d06bb3d67b7f2a219fcefabc2394fbdf0f15acb58ef02e6902b71c474a2a56ddd9c574d9e48115dfc974ade7584f9d22e1378d96a45625e0d159b8bc736df0ece2a03d718c3711fcc0de356a52c19a3b0663a4e93bde4050d653914c3be74990e13b4eba715eeb5df743186baf0abc873644a9fd744712b0e4c61701517106e3e996f94f6f07f7ebbc288568c21bcf0746d3ad5c8d57805e2c708f2223d2e54968c71310ce692979eef9d8785bbe295969c032a874e0887fbeaf3d270cac4926359fbba06bd9a848cbd3163c3645d0d88740ec50996c2cc5b093bc449962f125375da38a0e4f609d65f585adfe9b90374020d1f0304d11747d2a6a0ac4e74384d3c9ba1b7ce35898dbeca7d02d3892a58e725eca575170556f6960998826a1752e9c6704b75fd8bea6ac82e408e9dda08638fa2ea4f04255c7a25519089c45210a317115f41a7da50fc345fbb4e0999f221fa1ac337acb9a047b6033ed1033fddb3ef5ed545aab8eff439bfeaf2965463bc0be33cdd0ea0179006bd0f86fa2a2700de65185850bc33e87fd53a0020a1e61cb5f4a22c95ac3348c662fae315a66d7aac96581702de8b13da598fef640e18cbb017d02ea3ccab288a21a7a2f644fc2f8da6797b696cbe59c18d52fed95282bd3528177455914fb3c5618847db2e1c2d400d0b31bb33bf85711d19397625825452040167270b2d6d21f2d47196b9b0bfc1d03ad4a54d00ca6c15ef20861ea6778fc9e1ddace8d582840f64c2eea06800f1571e01a47350adf92e5b56144d4fd76ae75e657bb230ee22618b9c6e5fc92049a2ec4b2b4dfb2466ac30e2c785b871f3cf4bda2ca421d94c6a10761c4f8d33e116280cf9805870cb2bd97722e2902b0454774c70137f5e014a57ba3f0a7e36287cc41e60a0eb11a2509c60900641b6fc9a90b81dc67a134df8f7f411d7aa2fe9c3366764d0fe6fc529e5f8d498451eaa72a4c09f01a17265a5a5caa29fc032c87e9f5f6de740d54cb1e7d437dff21da26223a77be6ef5b6794705b6dbe23a9646544fbeaa9180a72bca068f96850e821622895d99e71336305178f51ff5cb5b1cb611af65663ae02a1ac3198fb8a1317870e72a55570e12ca1021bbfdc8be678438ae014c845d900443ea7fa6d97df63cfafb1303cfec67b76c7d6fff0561d6b072d2b08caec3cb01cd5da803e1ac53d91fe78802ee9e7a9d0b34567eaee30810bda2bcd2874016bd10d66852950d5eebcc9778b5bfa60e796b7c2c4b6233dbabaa20613fac65b1f83a4a2d46b049a5815e4a105f05145ca3e8d9dfa787ac410e4616c49d14cae1691100413c5db11da815d6000d1f38a3baec0d23556d179f87e0937cf8f0306d89eb58475fc394e921c658788c9041bde1f35364887b7dd863a80fd66169fe42bd3c755459181dd5273d46fdf4116a883fec13461725462c1d711b1dc4ac20809d0b72e89f3fb240b9ceed5a8c51880ac389d3b778ebc2c96f89bc92486a3567a0e3b6ecfa9cf4c10163c1fd1417c16422f894afb4d8cf98e4c9efe8920df342488e1b98267f02c0cbe91ca2d241a1a38dc95f379e36b0e9e4ffd50e45459a84334b91bed3a5856bb81a5272b5138e1c85774088d58567c830e62cc8dd1269ce0a2761c7b8669d7ab10769b4be189af0396344cec126e9b84847871cacad7fd7ee0bd6519b84fddab8162c33843cb4268dd7be515eae1c5726fd82c4ed859995320d5dcb4380d313952988b1718ab1bb6a2d969708fa5ae1e65855fbae408212d1c0e3aa363536321c1de15d63488984391847c08802d0f3d15349ebf7925fb4209ad5eecf1d5b4956e27bba3b93f83083527b1d6e1b69af0c37201b83a60088ceb234d647c14edd7d2d7cf68e90131826dd1a9d418feeb0aa052f809e8131bc5d908b7cb7ba79930e163bea7082ea54950b8cd37dfe07f8a2c3166e61170d466217b7598bd2aceb640b8dd339e33eeb9d2a19b48dfb83990d4d5968110b8620acf9436f77d90f060444a6949559f9b38bcfe2a41a942340f0be9d1423d5c65270ef8258ebd65fa52a627101b0817f5eff3ed1a44b82e15abdca37cde871a0047caef1ef7b4066b705983d15582ccdf1ac46d71ad3dc9b990ca24a6126888c0d7c37ad982a4b52771b0028a2a153c515b3d0218acbc7aa90b2468716a50e21426d63428a2d179563995808203734cc1eca77a9b55e870da25e18f21362f44b74b79e40d6253b182fefb960c327fd52176e1ec44b12877d9380a9af8c764ca56240e1dbd121f6955c41a42c1069309a3eeaba77b5912ea3e205b7fc31f7f2bffc3acda357fbe9c7e9d1237e7697571dcc1cc0967801d715e60bae913dab0aff7cd38e410383e2ee7304b06f0d676ed7bcc6d373001449d9aa808ff6c9c452cf190d35f949ddec628745f76883c34c838a09dd8d594688e4f72e4f3ab7530173c1e4c40f7a43735873e4a251512410fc8aa5814b6995256b960f31e8690f185f2e890f84cf57d83dd20090f6cfaeaa5a3eb9e835cd0841c4b98e50feac9e85933e5ebe26819ea159c97778ce97066178c5c02a6399bcb63080e0233592824facaf459d03a931ec6caa56dea35a9fbc62928742b10911d5270716c9eb489b708ae59d878d141b7dff522d23c74f2512f283a801cec279b7cbcb05798cad45716e6fd92a72b79c9ce578f503db874e121271295ec405b770362f5a7f506650ddf1e5c9db277d0bd2c318a6a5ffc5779151fde49af149b61ad3da438b1426533dd04665aab18b2667280830fd8ae0fdf1da085d9c8e8900ee97597d54c857d32b11897fadc5890dfcdb031e349fa328b11cb7682557433d0af48b3161c7a628a0f9b288f181920a2c2df687ff9ec6347c2d99bf8ccd5e9d5a65bedb6f1a6df5b0e99d856f2e41a6bc5ec8a4e54c900da27c90e73ca0f0283930abb2c48fa1e41ed3a40df4c81ab354177f3f51a5dad8cdd75de1e3a07e28f57141d5b95a0df98a4e72fea5ce867667c92dfa2818a120d661dd2777c1202f37d5f2b05c2ac9c345e374d5ec6a556de11ee0c7de1e5cb6419fa53d4170745c23c8b32f12dbadcd5a9cafb6ad1a157ddeacb5915f7a677bf94787091f65374d6f5c77f575b994c15af5ea5b6d9ec6cb246f3b9405786d51553db17495a5138e9e3346c8ab51670bf762cfc7e48079b369bab2bcdd6f5b4353477600454ddef9c50bb59bafa61427ed203c36cb0debeec6bd17db9a8530a974ad1a354d95351e841abeed10d775d69b699f07192296b41e99322e1d609f28dd0c8ded6a72dd392e24243f99e314587b4bf6e942dac90f5f3b2b28f2d7835bcf0068c3f2cabcabe98b108f9fbfed4642eb266e566f1d2ff4a04228a2b9adf1dac70bf6c093b72024ff81d0aca9f811d414a1c72243ebcf9c2c4ec89ef04fb872e3bb4fc7d40d23a952d7c44fb485ebb0237931e31ce751ab8203b00adedc1514f49f7bc3361b055af2bea858c9b02f9edb81ceb1ad0f0491d687cd9a90b9d1c8745bca390af12cbb9ab85a8327012ac2b497b2c0958b8721f838eb1b92ec1abf9025ec494f1fa4a2af86cabe96a36ffdee8575037c66cc18e74c40650c1d3c8f43820373be8701ac933ff20f1f8b189d891d8bdb7c1d08789aff190fc351959157cca68e992fa7b8161f43244c297c3afc9cd90145af500d82d51698460ca66dd945706072f34fad54ae9ff0a0659f635dc74e6aac2332047a1832f8f42afe35ea0906c5c0251d9f50398bab8012050015404ad26b432d51ac098a79a9a728b278459a10153bdf4a7c0a7bed64ef742962e79cea1fc4abf1596ef05cd751829a4a35079178cca14610282bb7a4474a5852fd901373d936c0eaad961f7c0bc7ff4d1aac548a67a9844a2a4670ba73346c1ae6a8291411b570359130ae99d4526bb350f4184ae4a781782660a8154a615a3866c042f539e868b7328dac43000dc214273b242448b2137ce8ad755a82a200b2cacddd41dee02ed11df3dc16f1c4d97a845ed1a1c71835108b1b58779cd4cb803c7d022fa9200d945210b5e5d8761e31d5e02ba56c14d8e8f7ef6821e8eb8f3a3764d87c1307b6f55c540591c5ea9e17aa7d1c129e059e1a986360e284993cd3034fb2481fc60a90472ac3b46cdd6c3678c085f2241a065a1b1fcf0c11489c371a3f0e16af8fde01138f7c7b54b3320bb555476a51f3298e43e8ccc27209c919f2dd46a265a6f313e75fb498c0b01d6d6cef3a5d804c7ecd60dac7d6f95dd63d0283e5af0bcdd6a39eb7dd563664ab7dd8f0d41d092ff7473720a018a4bbabced1d9ec95626d5b984504f2d08f0d952e449a156c4f60328bef269c195161117cb88d91f02772bb8f2d9e38a8f8da0beaff4e3eff0302d873f615f5d815531109e5d8f59651bb558b5db08f4968a24be2bde04ba1fc00ebe1b0a4d9aad3bab9d0a0b495729e85e5db6d08cb55fd4bbf1280a57fe3fbacd24404903aa8e5aeffaf6215f1db28f27b49d3a91a5b35f193e6187ff1f180fb8d3b1a392824eb49507f1da3074e8fb3effd64a46f6ab8b5304039103019c2af5a0514f3a89d2ac81c29203bda1d8e8591ebd3c00a7bfa5411493e5ad61ce1ae79ffff328199d6329ea138b0d737d0418ea255a7766afca7446c9654048c55265408ea05aa413f833ad5e08981033d756883009ec29061ceed600c37a38602222f0ffd839606feb6f4eda08f46719678d1b66013780f5325a000d7f5c65c2589bd622f027af38ebc40e874e0997730863c19c43959295a739c3b0e5428a262d618c7e6c537113c61b2c243fc57c2a9ca27d022485f13809c3016a3e11f839019eb3478ae3106f0087b91da08c9e108953e58fdb07505b215d68815603d0677cc1db22daa2ab5e033aa1044a87617f9065772778e01df60fbc436f1e5458e47a9c876158949e9c970ad1eb05b4a7f608a0b4296254f0af5fe1d30ed7e951466889ef09818ef82bbf320a7a3e600363294863151dc098eaeaa1db68a8bd10b5e8034fa351c7499f98f0c3260671f1567b4dfb28bfcf5ad7913678f7a46aeda612be6dcfd539323c4177efba27facc0ac3c57b6028d48e69f5924c2b49c50e549aec80f5c59b660d06e8d0069e7e6ab6bbf8da4e517afbb425c1020e443ce0c883ab04f897db93ed6806c10e6a75586108387c5439bb4c7a9cb803e5cfbd77dec10556ac1e765ab060230016aae1954215a560f7503dac44a5d1f3e0be3bb6a19d4b1ac3612c96c64e6f799558096fcf957565b75d69ef5b69f9cbc014bf65ba18c33915cccecf01a1001451a9a0d9c9de09947ae3eca9e94d5301f67273a00dc77971c0464754e157bb5923a533589d6e49fc103f34256b4020b0b352c8aac307b4ac9441b4951a163b90094f01ecbde36ea541b4d3f6baa5b1cac00817234176cba1edceb8daa66149713201aac3388acc874aab45332bf681a0f626a839f090ddda9121a56f6e45144acad9fb5afea7e618d2dcf573aaa56301661f84a5a19ae978f3700a55b3d2a998b3670459b81ae140217d5be86a54af6b47cb262caaa30c3a806a548739f5da49a5763bced8b8a6554da1e397f04d240e62ff577319e1722a543aa36cf617878355c36d496ae7025d169dfdd183c144d3b7e48dfc734c2112aca29323ccfcec936b961ccd42c8abfb29ad06ea8384c84dd9d9c9b1fd8c46e3cb808f78fb249bfd78c2c244b30879cdfcbead565c6bdc11cc7776c5723288260d97ff3e5b4f566632c4408eb551a611d33a6a1c35ce1e33b2dab6ebd685ec37670ed3e0ac8bbad0d1114e1ade3c1ac9ce826f8a6aba05948c2e4ba77964ffd06705358403db44b7a59b3cb2fbe84e514d4e80e0a371e9681ed91d74a9a866a740b068b874268fec0f5d5754c3532078b45dba9b47f6e63aa52cfb0afd675c2dc0a1a3796477a8a7829a9d43fda2e0d0993cb23fec5d410dcfa1fe5176e86e9e947daecfa96aa054df05d9922e4554f61133669f060def581526ba54deb24f9c33db2d8daed073a9dc649f353d1ff9da078777a50ad35c2a6fd927ce99fdcd713d13543d971034a22f717ccf07e7c36e65e4fe9f4b74aa0a8e4ff83c4a35e6bd7c9afb179aa93bc149d2b33c61341d02af99ae8e9967a46c3fb9eb6140948fceb78841da935f0c7e2cf710b478d612566243a5156b9e36175aa43e795086a466d3ca794ba8090075a5ab09da386b8926b1a1d285354f9b072d523f3c2843a5a669e57a0bd46401a89a6bbe1ac7b33afdf23e97996786171f3c0feaf8c7fbfcc72453527970795e873fde67609ae51e36284cd4c39265bc9f0a5b5ecb996fcb5461daddbd65347c9c0bb99cd81fb40110b608021edc5616dfde116b42dea36584efb97c9a6583c0ceb6d7a2dd73ba24eff52a40df66da5275204db5226bc4dfa52de333de222c59d3a27cdf514f25cff6c1da8dde0244b9a640ae2d8cccd9df7f41ca97482f9ce47404eaf91bc858201a1aa5038d0170fc3a7b320feb556fa65446800cce60227eb361592c54463ac133dcaccb8d73808d2b22ddd4d11d8e03800871f03b32f2b285748ae5879d91359abf909b6e189b91924f6229edde5b92bdf79652269902460db00b440c0ffd47cfd59339d600feda4aaf3492970d5d442fd9e8e147f2f8d33ecce3effaa4471b08afc0a35e418f532afb85470f5db6c6137bcb02e59adb433f9db26730876ed59e6edd1b950a5ad5025a9c731fa474ce0ec104487459b2aaccf9abce5f57cd2f677b55cedbb96a2e84e653b3576d71e89957f2b268536bc41182da9b6137d965b364f6aa9ced814451085df9b642b4d81e08a505327868b3b478aac513028c7a398b109109953f15c9a3153e1510f83f68784e53217807ff8c0a48af6a0f93ccfe8040e798dec3e4ca3c2ea1de4c8888033f1a8f72136da6bbc3b85394c75f0d8f3f1a8fbf979b8833f457c7cdccac0e91dac3e4b242f46ab63ac7f43845ca8f960c8796cb9b9ed11a5e8bd3789c53260ce0afa708e92d5e44744ec6639cf616bda8500a959f80d17ac881cb47fc6409597e7a9066f1127eba1044bef8bbc59b8833b31f4417a79450a16f353c95d378330eb9cd6908d9ac8ae445853cba17220915fae52c3a422e202ea75647f35854e18c5cd4f84048205424fb4335e399c72eea957219ef81f118873f4d9a85fd74d88a385108b8844eae47f73ff8c6f4c845eda9721a0e81991f349ed333bd9a42449be93568c42daaa7a6ea874a35e3cca97eb4383f9088e5e33ca767bc21a273aef2866072f910d25b9c39d502a4b73810e92d7e592051c62b798c573de5991cc673f117af73947772cd63007f3d3d262f798f8b57cf3cd58f1667007f2dee43b4c2c7c978fcf107e3f19779fc288fbf1f3d3d45747ef29e1e93f794bcc57b5cbca73af7e2f1b45a38f46ac256b499dee2f3d3ebcf4f2f01fd7497a09f6e5af2b3f384fee4f167f2f873f1f82b79fc558fbf168fbfcee36909116de6165587bde9d59c1ea754e832518b0a9dc28d7ba4c7af4d3c599b8ab80ba323cc40e20a144801052574210553174fa8605ef39ab20b2e5ea65ea2c0025898c19423cad8620b2478018507317089c28a15a8a0cee95590011527ca9001125e0c7d3209509c4002174aa49c720727b89ab8c4f89a0f0083ca153ac80209a8b0c4178bba3042a90b18ac409e51c50432769175f14412bfbaf8c12694529eae2297ed62898fb1d6531730f85b5daa00fa1ce9608b18e0c00a1c2ca1852eba68fd64cf513c014a8d22dbf3132e9450a115e5082a70a1092074c1c5176314f12396f8908e5819a30753b48006546c3154842a5170e08409233df8e6942dae605b60e1670b26c43863c70c8b5b345144ca15143c509205253ec61865f49e9f6c31842d9c90328059a440333efa16489e9f6c61c48ae727538af0f0ca948f0eb134abe617c0dfe5d33d95f4cc359f9e8abd9de497a7823efd120264429f560890769225c284bd2d5b213f344b047e9995164810ad8fc8b44d6a7dfdb32488a34d3442bd1ee3f4e8d157d1078c0284a988e06b7825cbe575ab7d543ef019ed46645f3bcf7753793ee9170a456697ec175ee126d721bb73bcb075fd8877fc107160eb8bee4aac6e74e4ecf00302d12377e1f92f43e187ba31241432a6e36bc7ae6bf28e0e2899927774c0654c7df4d8bca30341d48fde90777420886895b433df800ea1a05c7363eb234fc4e92cab3595adea8d51b489de348287f86d2f8fb43cc4f8d3931fe315d1e1eb2c3157648e667c3c57a92cbc32635b48c629fbd022e8696f1e716e7e704bc6639c79c6553e63fdd6307cc6afd3b039d126fa8cdf9b306a380dbf3ce4841a7604321ee3346c65a2192f8b36fc794342cde22745493e7a3b6928909959fee65487e49d77e1775ef22e7c215e3345879be73493e92e747a4ca684394d0f0820357cc681c8e031ce319608931957b90c3588a82c91e933167acc843971fec2837318e7f89953f9e0fce49c9f14b0f13c955be42617811857b9e480cc788cca4e47a59cdeee188f89b4400089711a0ea486c730010288ca63bc068d21622c911857cd58d6843ec6e32fe50911a2c3196774e1553e5e9cfa8bd3a29e9f31fcd0aa7c508771ea30b6f3ea28ef9a5e3c21b0e419a7a3f241fde4d44f3688f83b263b243ec957df4511c788e88728116726c667e28c25126321fc79c12f1bd5f8e52b30f8852d19e72f06f7186fc6a11781189fb1443c223c9f8c434eb580198f711f66623c0230c83a7f323931c683434ef02c8cca9f7b8cf7c5f1201fdadbc3fcb6f78a80bb8bbd321ecfc75c0ff3a1bd9c932cf4cd4b5eb541c4bfab6ff17c5cbf790c1e84c183351e7cc18347d126ba15e2ef8544ef69dedd8176481c12f9cbe01595478759228e8c47ef56c499f1e8ed137168780c651a1e111a6e84175f73198f888c1be1b9fb8c4764c68df0bc468ce713e31c6dda6f1bb5bdf17bc6f38971b799d3f07c62bcc690f8ed329e4f8c6522ad101d6cb2b6415c2fed0ee63cf4b78d5aa88d228ecab36cf3768ae8f0cd380d671b9fe4325ec3b5193b048df317e3ee34882be218e1f98cdf2151487e666f949e101d1e73cf2ba2c347e3ed5d1eb746d0380da7d602d10f8da07119bf99b7500d6b048dc7f890f8d006713d6695d05810d4f016fae835ec0de2facbf39328e2c8d8687168d85a611b7d7495d79c8f1d252a97be339d871e723c78e8a75502821d252090f13934e33336d5ada7d2e3a1577920e068034120e314723f646c166de0cbd80a879e399d1f315e8c4d459bd6b7501d9304e59a0bcb60502f27934ba9a5e3364ad2b06bcad89099fb09738a097ab420238a272051edc01fbd077f749ecfa8546f873de50478076359ea013e3800480318b0801e14900004f070001f8d793d78e818a000dfe7f08e9c2454ee9e2d3bca9e63f44649da66e310954dc25a9bdddddddd3ded4d612d1beb96d2b196edfdd3d0e3275f50919743cc83c01ef30b5dee40c7229489766762727a4fcf3c62984befde747b5faae9b075b1cbeee8cc395d7277777777638de980720d6b590c8a38d4c2a845cbd126067d843a74dcdcace0956894baa97a45686f2acf77f98d403bd061ebf91b87081368813e7aff60defacba1776f2a7f10b6be1c553b6cfd6587603fed8e4e5b217cc6b707817d3b6c7d7b24c133ce0ab080c4922f7a2ae244d71171e4d0ec99839b560e9e000324f8200b0ab268a10513a6164df081e1f989164078d273144755009a45b438228b20610b5a1471d538212180294ce871328322458c3e4642165366f1b72289e18a10ac78c251912d08c5e727593011b36022c6605e3020010523b8e9620ba62d62400414e060095584a27c92e88ac4720495a2ad481647281521c209a4cc620727c8e205df3d4321850c2952564c599322ca01510e8288a2d820324f88846ec7a8c54bc4c30bc39c39ebf4e2c8cc31b6f8d4ee21fbcb218c11466f7a507253f6f054d0f267bd8a1049943010c01144308862258a139e9f5861c6df8c9f4421fa420c0a5068a4aad8b7c75ec596f906747e81b25f31055e21c61551b8020b58fc70cf4fb0684d9f28665c530441dfb0299a4c313445150f9d92b0089ae20baa3d3f99428c0d3ae5b6f9d0374aea221357e8e0882b7c60a4465e0185bc629c571899411732c6286394289ee8e0091258f1649e3690e50529384a628323507c171650f8b12208d80d454858c1030c8c2088d1ca52c40a3b28e2bbaef8cb0a2990b08209ec881ab60209ade7a68b2b685d38d2451492b8e922e8c90bc218820cca10020b3e698514246452bc4842d690f2834c4a1192a8cf4fa42811bab009039f9a29525a508494248e90328298490dab620bd8e44c4a2de200c209869290f284117e20a58a1f2011671558b053942b7cc0c409289290f25d55fc85a50a484c59535f9ce04692b4c9ca22166374d99a9435988c31c618af2aa648a24e5b638c31c628a357f183998299c5ab8a1cd44c995530918476cdebaa2205466a4e5590e0ba3097f314e508a8c8a2022ac650011560f850e14511544c31820a2b8e80e2089f9e2754307997e72758aab0258133a682092a7e26162f29b168f2b266ca0f4e906101a5660a16534c500345179818c1588061040b32b060a488919a294429a891536081546474051f2c51b04ca9c112216cd01b2a744ee9c0cac7403e3fc1e282077017ce88e2082f9ce882112a5071012974a0c4081b1081042c98224a939f519e38a30a946b5f5256297f07e2f430896e847f5be780ce1cb8f561e478482f8090448ae728a3b443e44768468c3146e831c2ed0b8a4d15678950df9ce75301e13ae799c6e15ef10ecdd96b0ffe15df58f10dceab21613335247b6b6a1c9b99911eb154b3e0f6994fbf41b6d8829af995d99dd346bdf884b25f866285a2ef26af823d50b038f9b643fa3d90fa21b5e6d62b92b0ebbaaecbd6cadfc38474393be64992c7986d929d97cfcb7766fb74e9d104556218366d90ed25d4606442b976b7540450e9d7755d1eafebf2099d63e4742664eecae433b380e8cbcb8080fdf09a2ca1857288b6d3f674322a35ba8a5d5a55efe004e56f20b8a666b527eb1cb573b473db5c9e9799a1f2131d20f97bfa4ec1545f1b0fbd6b130a9fa596691e0e374fa098c2c7672850a0c5df9bc7ae2af38cefccfaaac62376c538a1584217ea6a0a17aa30038a2d00410b4db2a024cb0bb0b08232a0307205288a60d18215a85085232a8071858b29582105285110821527c8b00114829eb0c4d113148cf1a4882a6638c10a54a0d08430c4280a030b2329c01802139e58020ebe90811258e0c5d04f12868e28ea421757e0c2ca164d98e285165920214a164520f201164cae48620507bdf2699611f91266b03b4a3a6f109a512f55a46e3fa9d3c8717373097f3c78a457f3a52c223b228160036548642649414e2fdd7b357d86774827e381980fc4fc9b32c237ae9ffda335502769163b6916477185283f1b8abc8224280a2c53f8db4ba2c012e56f3f21c3df16eaa18ef233b6ba873992eca917668159a019cdd22cfce9d5f4e9258fd9a67f8ad4f96c7305fe2c69d613cde228b0d0e467cac9cf79e427d632b284bf30a8077f6113abbfab8751a6a66f3faf3ed2abe998078d409f5e4def9f9ffdd3479a25db686b941354a38c5361ad38a8a4be39bbb393ca3062060c9ab45a1f03fac3bcbf4b75fd8081212d6884081e31ca027be0cf35e58f66dd1504960081dfe6696c33ef075e7ac63653e3bb81928feca563f703af7d8c4a3037c0cdcdfc7fc8b228463fc4b6971128e53ae333f554a113aa21f085c0767e8e387e338f900a0fbd88677bb317d24d7e0867cff6f9b3c01ad712a7629e1db24fc1fbe96457cd29218410420821845332843efad92ab9a0fb05fb213b91e2f96085399c5adfcf40c0b8852c15e5cd0dcaf8eb478c3cc4440b3821306ae147c4c9e625b397ed84899f362b72050add9d5a558f58b75422dbea49cb344d08d34bab04042c2963fbd5b208f10738b32bcb9cb32ccb6c965528bd21b38f50fdc8a853e6a2ed3142c797b94ff651d7ac4ff665de98a7845a92671e07766096b3187786f44fe937c8cc41a0b1a48ced3ec42c87e8574a2981802fa19443fa9564d2fed0b4ece6eab904cd98d9c9f38550288333cb52290cc37c4ae9bfba367a14c31c621ebd35ebd966afafa6dfb496dde05c92a543e9521a5d4fa01cdc9a99395e666609a7d4665f106b69e11d1ad675bc23cb388e7760da46a2df3b2625917887dc348d77442ecb78477718c63be005316666cea626b3666d3146be1163a4bd41e68c9d9937219a350bc22ef10df686902bdf602fa38c0a7d0914eaa04909acf834d14496276414fdcda014e1c4e73b48f4dee694724e29a7842d23c4e1d38b31b2773b6c6f4e674ecee9713a0d9d65b35c26e1def3d32184104629124e91f00be9704e9d785dedd3abab8d3c6ce20657ffbc0d9eabacd8ea6f5eea78c943cf11a7866dd849f6ea98f2ec9abd37529e190a0ecf6c85b1b019ec8416e3e38cdee5303e4621aa45cf436cc33228e36ef2ec906dd8a573d4606614a75053335ea3393f906e7d24af1107cbbc9d35cfbc1e23747c9ac5dc27fb4836f39c9879251f1d5fe624afc788eccbdc47c7a779e698c79f860911e22319471d6879e95308f6d1eec8faccf1c0633c5b25aae84478e803c1e520c0a4fb10cf38a33dba0f0c556c7f601e2d03f8c3ac0f3a7cd7e4911d89287d8197af9ff1e17bd77b2628d659af3c96a0deda1bec54b34e32c8e919aa7c4036c233946728a2d1d18fe61a750cddd44f7b03e984e16ba6676df48abde71a9d37ee29854a06d105a45bdf05052c150a564edf1167eeb04787d32f0f9396c7e7a3e39b9ef9dc7c33f3cbc39c7d56df74c8f1903efe4d6f8ec7f4497dd3eb379fdd27fbb0671b447c764d8667ab0404329e7146f319677c13723ee8f04dcbd18663472a68cb4e800edff10a15163d3bd1b35348ea8e918ad68da542ef6e1bc9354ca5a494b6ca7add4028254f8db708e54c8d0dacb6ec7031d5312f89c5ac530e237c1233aac52a603dbacfb6e88da4caef56f9982f9d81f80cd3116d78c863b4ab1b19638c524ac632d736125d5d279289ba6c25ae762d5a57b9d2e6424d4e3a692f190a8329ad6806d2959a315226aa60cfd0d81a49addf0edb338eb0c6c9e452aa2d2f9304a5678ca3b9b457d64b46f844ca585b58c66de32a23fbb432c340afd8fde3755d978d31cb6a659e77052f18ad50a1f34f6f6ee31a9de374a437926ad3cdae9db66cda736da7756b2ad45885cd658b546824d434e5c52a1fdd5f0effb277889f43cfde52ca9845ac0950c57489410cbbb00bc638e5132823a88000ae8031c608a34a3acf9fdcc4516d96ba970a632f04e25ebdd80b9b789794c7d1a6da0b7fe6d3ced68853a925b5cdec4d5d16fa2c2042544b2535197fddddddddddddddddfd691eb34db44ab07687fefd13b7a05c03e74b67a8c3916564966c3fc62853bc452b15b2472b1536eb32942db7eba533cbab26856d9a648ffd94659a47ef78e1cbc8cd9a1ffd34b94a47713a929b25df60d8310ab59d6586d91efc32aaa46df2dc4f3c26047fae3011166d6024bab1eca2e774c7e97041cf3fd4c89225cb18316fc8fc58757494a928ad741a09b2bc434466976c9f9b05491b47eab6968db678b4ca38b7a30afd5630b821f3996be93aa3527aec52952621b2603ecf1ec1a8507a41309f8feec2e944778a617fc91376b7e7eb8238d85bb65aaad014c928124024a3925123142af4c72e4de31bd265c3e2cb0c6621fe40616f68f4ecdd92afe9edc54bac9154ff3b9b481276da5e366e56b3ea47f6f1a543a197519e9d555b3c2761ca1341d48c691f1ddeecd69bba1ea3747c4285f10915fa0c7f795e0504fba8c7bff095504b84888f644b5b3caacd3a99367e19f2d836e7cc826ccf7ea2a80d0337f52c1d9331bac4ecc5fc469f2fbff51866e5e5b1774f4152cffec2e930a360521b2966e3665dee158c6370f33c534ecb3052e7d84bdb316b1a86a0fada21107154d1aa16407d731fa0b31dc20ec104083bec7c08cd6325f945b257dd48247b55ead1b5ce732f1ad59b88f323c3e69cf6aa9bb43f28bc229dd009a1bdd1e1abda97678c83f9656b0b9c089897cbb843af60c7180d20639d3d99a03049a9c2eb7249cfde10070a419be82c67172514e266c58f0e857887fc08b3f838c5c7271fa5d7fdf4e074d2ab382d14ea551cea1cd17b98c04e550003cdba3c419ae55d763a81209148da099a4c21693c370c834470480a2c82549038f21142f908bff818a1958f3d278d0dbb9b0ee5337b1df32a80815e45bfbc20bd8a1f7118da3ba5b6301824e915941606f50a2e811042082184101e7908047db0e92accf2e8c7fc05577e48000343a0c0a1cb53889ef0c45f36528194bf6c85afb019589327e0068f4412740d42af3595855f83104208a1f3576dc65132d8440a1c923c85adf8d6e1ee2957089f801636814210f8a1a8a8c224dfb009a026be3dab7f25b97eda25df3f14a58a6a512d9a0f818c8b86c43822fba7570dd439da7b9844b943c4815f2a954aa590c056eca25e8ed2ad1d78474c85c149684f059de721fb9c4048be3d6b4f459c1fd1a6bda62a4749a556fc331571f8ebeede21dab4f317b7a8d256d9130ba3dfa011a4d22be895bdcb713a17bcaeebbaa2c38f42ed5caa5790d39981524a292151af206da11eea1c5e3ba9526b0fb55096124291cf5ac85e704ae340270d8de051b38820942f9af85bf3d0a1434a72e8f5610b7dd7e22df6aa2597ceb5c56b8bc3167bd5ea1cc9378ffae436a773a318c4300cc318eb2e11aff2d13dfb10afc157f10b71b66d77c9f6c0a02880c0850aabf56406857ac57e79fdfdb48f3c749aa9b2acd6dc0860f510878743d99440cdbaf04a50b36e172181fc5172eca25552db884fc48159aacfc32cbd8252e09566418746414ea82e049f6041c24b7b6b8d0e635ba396eea280428c9e67288c70f2553c4351c495afcd4ad116d9e4232bcac7cb8156ab75b96fbfa667c6c15c23af7ac89fd7b437da9de8f1b93f4e97d2ee4497bf13a774c83b2e385bc6283bdad4ad577789f894ac42e3b5f1d1698c31c618638c31c6183d82f171d3e16c03fd866d608e9c9857b6811b672c99573c74e3f5a515c281ed8510c9da2ac9dc633b6cf8336100e1d396e6e837fa4daf7448ef9da8a359d16619db1b9b50fdf987977e83830ec9e9c4f65ec129eabdb955f68f88634b55facdb22c956a8ff1ba5245157eda5b6fec557bd8880558a60ba80378befee9a27a0c2196d9d46065001ef6f40ac286dec3841bfa2ae26847d106ba5f2edafcb21149c7f4cb44476ddb876db7bad523b9a65790adf76ad5393c6e8de5a147c86d9ed371eb48f9b341b05bb1c9114e8d982083274c6861edd32ce8dd82de3d30e264198fee33be21469599a7fa41721503f823a97cc0f2691e8b2a3bb31846ad564b041ff415fc7ee80868164351e508ec2bad11fcb5f19074a5ca91bf3a1e5271f297a13cfcd80c8fa095663113a6e7b47b5702286fa352047af7ba4a8e3659ea4de54d7e830d9ba9f3ebd4066adba85726a7c1c6561ade7947ddd21d1baf361d0fd4aa68709353b7f19c5ec50083bd59956be27a54dfa127ae07a01aebd92173a67695367ae1746868b0a9ee5d455f1851a15169388c771598037c18b7e1c16f230b030303d347a954aaa876953e82b1b0f651d1174654601cc6539ef5aba8c869f84d71e75994ef3a2ffacede8e96bcce69689c9b45e39d0ebf9d25007efbca0ebf7d5443dbd037c868d6c4f1403a713d60f01a3e8726943934a598515e389dae816e7841c7730ce00428800bc029754a5328140a95f2766a38064a355a5d43c56077aad7a43a1c3da4ecedaf711cf6f6579f515eebba0ee55df83528bff19bf21badebbaea35def94d6928d39c82aa2894c9533ea1a4a61413aac69072538da3ec9d51dee443fabbcc5128140a063b647e8ddde92ecd0ba81750fe02caf90547a15028efd6d4cd6ebda91acd694555d7acea7393a3725c0702f80004e039cca10925959a511ee530c0e02aae47aac66752286fa01b67e180c373a470502994864a790d94632d548a061bcd716e2c0d0d87cdf235de57279437790c1e8de7441860a0760ef5cae4395d8373b4c139def0fe820eae63ef6a006e007b6f72f002d8abe3c6290ebf385e00bf9f1780e2c0e137def9fdec90f9df368377e1cfe0530a1a37d5747d85515a4d79e7d4efca69f06be334d81dea34def9b5b1d77f056956b4b798981bea9fbdf07178e75d1c3b643e8e1b37394e0e5fe1c0721ade5ecfb177a583bd2b02d801d87bf3176b09c0e660af8e97d9616ff63201b0b7be0c0daec3ded4cbdce02c7b5336380ef6d61a3c87bd9914a61c7ea9b3706c665473d821f373f8a576c8a4711a5c8f1cbe432d0e5e83eb61fb1c8eb568b036d65976656ff693684a0173c88103cd0dd6067b6dec905983a5711a4e87e60607a5f1144a4b65f952aa94f2524c8df1924f2966f0e0cf21996d51fe56eff2e854a752d3344df37b69261a148ac64e29200ed38cf2f2e18cf226ef02ba905c4157925e95bc7a353ce5dded5ffc028a9ebdd98cbdf5dd36118a381bdbbcf88bc7606ff6e23058a11721da75906da0f962c3e38729bde0c978d765f06e10be228f7a357d067e1b1e03c0ca2f683c7e186e013d6c2b7e2a1f78780fef6189f07c3c9c3f1e3cdcabc9e4dd9b37f96c35cb65ee70001e5c884739ca79f038dabcf8013c8e36a59450b499aed90b8147d96b7218a772bbe1493364965ec178320b0baa4a739ed784aecc22cdf04ba8f394bd59c9defa6285be6da64f228a720d6567513b39d97632891a6812b978f04d1e173df5aefc2cab156bc92ccd82f1e9d28c160c4718f788d3c3617cd52ccd6180a2cd7418674e07c6739ac278b05218cf643be79bef9c391e5e6eb0c50dbeb32a1e6467559df37c170414711a49db4cdf4e7f1b08e83650777bb69dfe4ea23bf3771219fd1d229fda0e722c49b33097bfd10155eca7599dedc11fd42c55c9f9677a7c8c1cc18030245892c65a40b5819ab564c66723094ad24d947c7a3fd12ccf67696626468686bfd8bbfa97289cb0f233cf513881c5dba032ca6774db3aa7dc02f8eb6189f4708e369dbddc56c39bb1d43dcf5ef8ee25af8331398cc977908163d4ec1d32ed851be57a58f7127fc7dfb9046a56c9bb6e12d9ac5e704aa9bd52a36ea26ed23a375137d9a89dbc9d1927e229d34069d7d1d0c3c995803998bca333f470b2b77fc667b0b7df45027de794dace4dde853f63f24b694729a526bbe3e2334ebbce5e140f118da23ad7a84c62f276a813f19d77637c1793bd3c6f72cd938ff293e62789e45126ea349c1ce5e22693bd12e8513ea4677093bbb8c9e462773aa76e9ac16f1fbd09657293c9e4ccf1d0393d799a477ba3943901339d6b96ba786755338e729337104daa52efecf541bdeb817a6772cde5119843e7da2933aa5702a14c6fbde37ad8f0ceee747e72ce86c9864933996c6c9ac9a966aace291a12a70363619551fee4cdb874d476471ee5347830dec3dbc167f064f09c68a9953fbd42794e4fa28883b56a6078c1bee0d47afcd4465b511bbba3f90b2ba74ac038aa738e383d3a7b8748f9d56fe79a77f3abdda10ee39d662f84ccf980714a4d5e1967368936d33b676659ef5c326bc63bcf98e5e29d6fcc3a79e7904bc00bd457965ad50b8ef25503c5606f0a067b6b8ded1ce532527e8dc3b0b2737e8da31cc677f064f0b25ec560ef1079dbe8518ed5c0e017d7c3f6b4c6a74b253a8701a6c6696a3c5563ef9059617c723a30dd0b3254ea306e675c4e267b15b9c75fc3835feaa32ff5f0924b25600ef04b3e53725972cfe32f99bc54f2ad59d44b35c65d381d194779d451eee2e291d37131393559d50efc26efc16fb226e77993773b47c1f8897a3caf794d74f286cc87b152098803e53911e8b36fae646195408ff21a08499226f12a4ab9df6c079bf20ee595dcc5736fa017a7b1a96a559defe03c9cb9ce02e1e13b58223d9c87e734f7a387f568f3f2e2c5388f4f7934a8c73885db0c0fea2aafbb9cc8f0d3182f7b1f1e7f908b217293dff9c54fa73ebc0b08652fa0ce2575f974eb3628a668cd263e0c46c45a3131ce9c8e8c4bae874cc66b24bd8a914b98ec9ca284c755146da6f3b0b493456adc4858acbc38954ad43b897c78fc49ee2a9252a9777eaf26cd7aa259d45e439dec01e71044f603de1144ea5f7cba6c229f600108354b898f7f3d7cbafc421a459c2369a57176f0e9d249e35c4519949f1ee3657f1d49f9293f7d076f4e691b9453943789e82c6a566745bec9646f10bef29da39c761eca9b442ba89dcf2956fec4e968b6817aeabd8072e2a9812651b3503e7d4e994514e3745016d6ce370e013cdfd9207ce535df381e3424924cf19a5f423a97935ea13cf990d33aa776e32b7f21c932253dfc2a8a389328da4ccfb2a2a29fdec3bb9cb48d8bd392bd3c5ff26ba859267be19b603c08ec7993bb383579d7d02574a49afc5e42efa4f559566b2ae5be5adddc5c1d1750478419aff9ec4edda9f39bfd09e537f52f2f2f2747f94b2a652f0f12a602e339af3a6f14ca5e09bc56d33fbcd6d90ba857f642125fbccb437ff26e67f992e7b450b35c7cfae5a4594326170b2b751a04f67ce794e30133322305dfb97456e5a3e49d97ecc96a00f6fc8584b9aa857aaf15af30bf802e90ef7c52bf90406012d154aa561e1eb30da669d32fa06651db0da917d085a4599ded20ea350cf8860b18c7f4cd6ba0c844bd32e869c004f0c93e1e3e5d06c924bca3f301f8ac6c20001f1d1f0fbf12073f55986d23af8487e568c343f4cbe5cba7dc268bd46d9349d40b83c01cdae767912a690bd5380cf374322ab57392b704f588f6722a61098352a81c45194b1efe6da02bb3fc646dcf519411f4b09344ac91b4789da4977413da268bd46601df984e499b2c52e10321b32d48e3c4a068335de8a7c7266c46101f41233f5d9aa0c29f0d6b3569d6d5c27a5aa2e48f1dfcc8c99f8af9ccd6381d696fab66ad16922d88048fcb8db29aa56a47a347d2407c4305754ee9d56c1271b056b4999e654dbe89148a38156bc99f3a8bec24ea954c015146a57a5ca29234bfdb738ef170ac157178d806eafc66de4099d741999d8eb59ad5c23a2dd9959ce7740be6d4a9d7ad2cbcb441b6d734ebf33106459c2cb32db5874916d4396603751074d2abc93b222cd2401009df4041954059ebf90522309e6f38042390e81584a75e75ed55aa7334bb3ca2c21c29a8ec985fcccc1eed0e778c6cb339d9e8489b989432b3d70db481618c6533d20edd2cb65fd19dd0440a1753c6dee69cf3bae635a58d9509655b570f1f3ace6cb55aad251f4bb97a661ce8ee3d648508dc655f41c247db44d878ab97279bf3313f7a4a32979ee47c6897071f9b52f20ace10c42cd5ab0a1de37462affac4e9405b97a80c79a0974d5e4d41b986c29e9b8d664dafdcbd4a1d55a31f8c03735251d86f18e78768d3291cf8d67cc3a01954e8b0151bf39b7aac95c3f9f0bffc0723a38bf3e12fadec4c0b38a9d4fdc13f5ad8e44a120516848ccaf8118244495a865dbc6362328b5a9320654adabacbf335e5d3296b3ffd6acf15b2cd749696a5dcb8a66caa5773ba34d2e1b8602e4d50698c9b63f6b2f7f49b971955e9996f1bf43aa74e9bd3a10fe0f95c9c391d17cf690a9f661e7592b779e745874f63e4743a674ea7457a0dd4c3a4a53a73b1fb08f451a21a29810f34d2369b07817a858404f56e7f535bfff44f4b5a03f46a7298cf8fc9a5078d947cae5cfc46a7d4833e19e639ed22a39d59462df4217924cb79e4ba0531af7f4c5e03f9d4ae93344973bab83ca25ee8f3d3ad5e4d77f1daa7734c9746d436321d1ec1a6365d56efaa5fb5769e01023a926fb4e734d6e40799bd98cf635e740c934f5478396683a45e66ed1ac07c7e077a4351c293960d08450f8e0845e16b8f2e54a80c7d1a8dc29739cf47043e918589a38f080c099faf536083d6d0078d68b284e8a3bd957807103ce647f7213f26118116c218fa54d1e11559e0e0abbce3e763979b13474b0c7d3958e1c4d0471b7277cf2b7e3e3ab7ccbb96e809ea0123094c5a790151cdb422c628420a883085e6996796080180d084d0a739cfe77ca33df334af3e51a14e744a996fa4be3e063e5a79b9f482a43e3a7562b4e423a239113d82222a7c4ca6f37c34f3340f23e2a50a4876ad0a48a6799a550121a239cfc7f3e54421f08c33cee8c24bbfbc879410a8010c7c90d4a7640fea0d82f9fc94769bd02f7e96820b2c1c11c198f01171c2c197b9e611d18e90c527cb9c882b8b15a4f8326b041f4089f2b116646061e8a372d33c2692220a3e1f124aa032f465decd131fbde675412fcac10bb27c993743828f625ae6b116a4e819fa342f7583af06146031f469994700215831f4691ee5c2075fca329a0ca1f5699e0a081f3c429282a14ff36a947cf4daa4d71f89d07cf11161c20111d81ac3083034cd8980538a9ab0c4a759ee1cb7fe1858bee8f9f6d3cc77c65947225922447c300a4278d2fa348f9110c5273d187158ca5112b27c748b8fbdc21cfad9a9b6655c4bbce3a39a4744329142d047442606c768d30e95502313610c59299a7c9a959a4704ae600b4b3427e2061446f069162ee188298eb0e4230295382afa88682b1f778e7b7a0831cde328542149932ff3a8151fe5ab61b8b8c9b2ecb6d441bdd9b5d1353dd3a7ef18bff818a950ed95bd8a258e36d60c0a0ba03c843038c388179ea12c01c4052e3839c11446a028b105125094c8024589319afc9c524a29251349a24e873e367a357dced93fb662b3a191265090b42bc618a373decec55c3a1174ced2f4529415cbb02b6a2427d552a9964ad573622539e7edd0ea9bd35a49ce55e7481be7d46b89aba46b7aec966e2bd9db01ef96ee9a23f9d69947a7242db33756881d01618430bba05fd7955df042ed4213f8fc0dcf504a30c504449809865e8667282600c230ca752d248f5ce69d776be62d19e61d97d9cba95125d97b617647c36edc4e5acf2b9cfc0ccf5050f0f328683d54c1331423565ed5ce9f49ae1a664f0e310c8326cc4d58762ec92f27e2318f49d8c432c7a60fe9bf4899339780cba9cb6446249f1c164da793e97432794e34615ebd9dced4723ab9c984793579c584c43f794eb754ef4c9ed327f721fd15622e73a70b2cc1eb145d187a0bf5e99d5779a0a75ec1bfba0ac471ea15bc2cc645947c2f1f72257bb7f66ff0b3e898358a3b425e48fc2c734a2fb43c442046bda940ec3616cce543ccd9a8a9c01c309730fa907e29247e0264322bf5ca1fd29f39db2197df3e3af2363c43318191912761fc3c8d1c3522c54892a7bd5d9c0e75c8512f2339d66307d35a6eeab9c3eccd3aa7de521fa336d4de14e62d1ec9f230db64d7f4e8d8654fbd62a72ea3dd9cd4581541563152aa3cb14ac2e906164819e3e495714eadf98d3fe5673fa743ce21c8e9af2435462ffee6f5ac3a476f4ef26ae49c104208e1746dd65e5186b0674ddbb4538f88d653f72c54e8d721af306c3abc6443965246ad63be81794ecbbf66e4742e0b6b8c36c8e9061648a9f2f39aa70b4baa594378487a91022462ed6192758ee8d2880a8b2025e5ce8848597b1eb625924485fedc6a05fd64524ee803e105a1dfd44f087d7ea08f7cf83622a7239bd3690ffa48222a83aa74da2235c734cc634d73e9bdb2ad691a6659cade0133334fe6ab8fa4945332f305a5511bf5515769a3aed2477d14bb6ebdf2a15e49292f49e58cd22b795d92bbe09402e29012cea12905c4017f4691f29213fa94528382caae719253da1be4309b6d4b5abcc33aa71c6659daa0e60c454ed6a0ee907c1aa0599c23e0079066751e1d02cd82d4690729e6f249b6ab40ccde6c1e0e3a6e70d0d1ac0b7653875cc27937ad54522fe7bf6c54830a7fa840b3a847c740100e0c11a2599b47bff06f578138302b0f1d8acf95bf6cf40cc5e7e8a357c04a5781382067bb87b961974eef00cf5f247b21e635c6cc460c420e929edc6437cd9a12c3344dcbb02ee28b76ce875402e298334e9bd352098f51c6e9f5478828817ad5d199935baf32b6ce93c12985aca638bfa9f7e85a8639471c0fb2facb67a581b34d74d732c7561078cc61f6c3630ee775d9c8f11023a50a0f3e662a1fd2a36b60258b64995f97e654cb324dcb342dd3b42cd32ec7307b4d0df6127c45432209157c05f6604666fc3cec510207b0746fcc10764b39a79c53ce296f909365a804b65e00798774e937e625afa2b3845ac6195d010bf6d77625557323809ef9c6e15bc7f7358bb66f66a3d984d4098765bc628c31c618638c315e32422e67c54338e8b8e9555c7df47bf3d1ced8c0b24cca1afc5c914f5b24efd0d8dba1d60a6aa259dc2c28431fa57c844e3e46f948f4d127eced6512b591f42a7af79c5e03c58d086c350e75be29c959801a490375100ef569ef10d9410d2465d0408d24723ada74f833e1112c086243e44fc7381e7438e38c337e0b423e3cf2cd5dde8d618d618d617d839c1eba948df9ecd81df38df69f7879e6119f36d238343a046a96f478799cde40d48b3d6d131d528fe4d1a759adb96c1cea9abd41b66fcf7c626b0bb5bd47059d3ac9ceb44d8459c889b1d5accca3c79e66f974c6e96416d676ada16b308356e503f376cc9eac06b687477a15a31698cacfa4e29166b5ff6c4728d7dcacd538ed2c5bbea0de140f1c1e3688f3f09baaa91e58b266336adb644e99db8894521e7923d16b8b911884b5b01e8c76d32019609c2b096c337d5e61fcf4cb57f8791d494e0788cd872851554d7a35e513377a74dfd9ab4816a95b352599455ff46aba08863efe0544058a08967ca4f24df8db4d24a09f6a1a7523fcebe19dc763f5da25a47526d72e2193cf560f0ff3d19c8725023f1f8ebad3e8e7d0193d1ff33cd485a3cf814acd2c95073f7f7a8ec209339eca6c5c3597e1745029ee472fe91c34b6e634db48503de06bce9c8ed6414982dcd3774e559ca991f4cae490d3bc8334db40582b92a0767e822a4e875a08e4c3a7d31a124a8b28064d2231a0b4907418938877d0780478f80e4ee3c5974cd4217a380f26aa8e0c4eb9ce9f5ecd232ea87706fd9c46e4d31dbc0338a59ce4bd67282468695a047a49e3b46e2d5c0f1a0ee307f07670eab2d178f06590426d89e0ab8fd04fc77ea49c584d5aad9613be7b9a6cd42c8e228b299b4b45790f93193b67f59cf691f1e05a23d1a887e140374e87ce1fde019b85f2cec256af2a0ebfd9fbad3af84d3d0ece8c03bf64a25e4ba889260207f01d2c9103b8ccc2f2d9790dd086fa009ce10d9dbdf5593738cbe924a2c1d9c63976be72e6743ccfe9172f7992d32939853f3ced3ce5ccd11737793c4fbd21f3532f2ff88b57e3cde9d438f53cf8307897e761703ae3755ec3bb3c5fc3b9ced83eead58c97389d1a4bf08d54e9056b99bc335986384c4ebda662f234efa8e6b593ce6b21db4359e905870807ba0abca173224fbdf3acc929f56eca3bc0f3d4ed859dc7bdea3c275221f163e25327e2773cafe139dd69fed2827aaf257efa0bf5257807ffcb8b17e3346e5e6a12c9175ba2625f3c27a6bc1afee2cdb817bf8653b8791effcc8ce7b40dbff56ff0ab8966c1e0d319deec6ff02b49b366fcbac1b95935dc86331783cf78170cded5c40b353c253b788da7040133380e7bb39fc169b0377b7bebcfe0363ad89bfa19ec65a3afbe428095596c960b28dad4606dd817a72e9b0c3d00c05b5ffbe79266d910d42cf7e933490ecfe1ee6e83bbbbfb46e166830da5124da954a291a129954a33944a259ad20ca552a954f299999919b88deb61c3637c2669d6f419e4eede399dc1964aa552a9542a7932a5124d49c6eed0b85792a9c1f31a6866287934eed17835b8c94b34356c69f39c966a944825d74a3319a733e3d54023e3cd50b9e5c84153f268686cccf0428e1c34258f86c6fa0b356832ae070d46636bd0cc5c9cce0c0d365e89429a5289c6dddd535e8c5f4528cfb2a28e76269333d703e52f267b3b0f02bee62717d73c17ef2eecf9eaa86a616612f7f86d807f008f3f1e3c99e306ef36cbbb8d83078484b13206ef4a273a2e500af56acae0c1dfc1e36f062d69d6cf046a16976af89cc1a7cf9e2c6fc3ef34f2d365f0177bf9cabf38b5e15df8369c52139b34eea3ae52fb088542d160d3791b3595aeab641c0f24ae870d6ebd8d9a0acc811fc6dba859dc47cd82a1946ba0c1a68d9a4a63f11bdaa8a9b4951bbcabdce039dc73f4d16b34d8eb43260fae59550e3739aa8166bc9a366a2a7d9472930d3638c7f5d0dc3bae870de5282dd5c2f5d07c27652fd4b4a735a8242cb6b5991a754cd1c800020000f314002030140c8804c3c1783c4f23d90f14800d8da6506a4e9909a32487410619638821c628420000060644668619273a5cfe330b85ebb5e50b0ffd9022d90ee3e735e60f194eebe4d38b28c84023077af8b608de6e6fb6d92973f3b2cfd61f93bdb19e73affa1edfdb152387a5728983a7412d0fb0b90c8a78b081346bd3038a9331334028fee718f355e75859cd8832b0c9af61ae1ba67aeb5c30f9e3aef0ffb09ad7bcfd10506435d111178418293c99ca75a3bacbf146df5382f5e9870643e0088f4d8dd91668dc67dbcad0f324b91c1430773aaf0898bee6e7706d7387cd5a962df270d41348bda0b40f6fe7a2c11d7bdf60d1570de7e50d8a787b6765a259d875c4d11870e20b3900e78a46de9bbd3e004368c93d88a94fb6d8f34b38e07c4b418d984c23011e2fcb9378f7753ab707c82c94d4a5e7d6fa28bcf0b2118eb77493efef4ea7905810937a3174d54e5a801dfc05a0a795fa6919440a81e2168b513819d38b2d335e9a2152226c73c1f664bcc0705b895c227df584d3e68d3bca78e5734d2b245ad50635706587254ab5adb9ee03cd805e1e52bf51a7eb5f41bdc8ac4b72f444c49dfcff7706020380ed55d029723a0ec28778a5f07b889b53b95e5592534dd43138f2f9f68ba6f2834aa461bc824dbba3e7c4721c4aa8695a0256c7b64aa6bfb269695572ec83d8be36ee53cd6010d79a45506fe47abdcd0bbb1347a1177d1325d96953ab909c44105eb796641fb160957ec522d574dbb9f853eaf22652291a0e019a8444c0148fa67f8aeb20bd24dd0c32f0b89c472cecf10c70dcb779e0ec2830381c5c95488341471ceec001043a337c81d7fb6a0ebfd549e835d0c98177252ffd4a043837d5e4808ff43939bb851c11b73fe273c9e5b399f2879900144497cb6bdcb38ef2f4cbae5351118c7f184856262d5623ea90e5a20873a591daa47764322008b2092053c88668a343363715691842a8b5d7cb1b910905e24ed716d4db80457978baff03783b3f87449c50b03074612bf297c80e4deb679add6cfcd386ed55b3fddea4533ab6c79a4050a6bd2c3e135dc688d138a235256afce177f43c7a343c419cfba2b1e6b4bdc07214b157470905131bec55cbb0de4d2ea3965df2806be0c03819716afe3a4bb8539395aba33808bd6c3bbd92d6ea52ef1bcfc6a3a9b234ad7dc06ef84e6a23d8072bf5bb6d7eafcbf88d050fc3204c862b5ebc7e28a7cfa8cb09c61987e538121548c345d50c7565d73837d87da6a2573716851b366fe51be07d916ffe9a48bdbe0c1cd9577089d8335a0dcd14aa659ce26a800a5f4b526bc04c6e99f836604ce125e31b9bc3e5a8494e6890e3b38e20bec3581bac3ee32f2cfac1782c187b3780a863b4093a398631989155be08e83d07a6c82414db3ce67834d29d7e3ed384338a1476ca96d91b22f4285334c8a1ae71544223f7b055424b53079e2683d3e57b968450bdf627547335dd9c0aa137a27408679009874a0a66919fa6a62ba9e441095dd5b632321ba5f0ea87f67970f65c0bb5deeab9265429401d5d2659aa3eb03f25add50b97a22328d900d23346200908a4608b5228ad929b8060e69fd505397900bada7903e3189b41b660f6bf26ec5529afe1c3436e65c8ecb07f1c516ea62ede93a828df0b87c57f9cc731e6fb1d65e75577d4ab3482e5aedbf715fb50ef7377f90a7c866a62f939e4f1bff174a96da571ef35f7033a9cc192ad8a2a3fbedefc984d3ce867061676731a3b8b8a93c8aa50ee644f6e49ed1d0f7af4123190a06e4c62663190c157a2cd1263dd4a84626cf3524983bcc4ed1366dfef137f474b5d142ede13b70ff8f2fc0249bfe38cee42002618f1a159dba6bcf804796b486f4da75f53082a3532f469907adb6e335844878810b55babdd961e1d910a1fc42aabe0a400231d861f89d455e1e89c6b435dbfd24ef02c563171d16fab8d95c83dc2e7b2d63ae4e0a2c09a1bfbda4e5d1b0c18ec337829cf1e27d6cf669553e7bba4f64d1b01f920f4e34e49db38dc268f458b6c040a8c44635feb76a801e75581af85488e3eaf5da9934d8706638b4e10f1340d665af508a276ad4d0322d20567bf1ed8df18776f8d2772772d18f0b5c8ca707416bcacc4610fcfa5a8a2c2c4039a3f090d7240c3373a031a217f65c10e118b928946ef82b113ca26c5f66410de0190ff641b75810ba97f96808e5aae2b1c6100c08ed22ff3bbd182adef566fc66b5528bc5ce2e29865afb92dc71a3a9bce792aa0f54bef8ffc6832d7c1fb0c28e6d2d48b0029c4925eb9c0861c6c92a53b704cde77c8a4d245dc2433265559dd06e363d1fc1a3b6f22654f412a817d76a57a979a089b566355cdde000353cb27792ea6afd9de2708e5f917a0511a8aa42fc87f53e5cae7c95e85f56a0fad993a08578894d4323193b27c2a131fb27f1ee8ad0c15af6de5291ab5016c4b26bc5abef30ab23b80f0e7d9796589649883e41239247220b82ae8441da24100e06ed94ceb1175607a4d8fd9e3284da9e4e2227d164be83a4d8eb242a4b2667d377e9765c2c545f7037cfe05a930169b76ae444b3ccdc37d01d70dd5d49f5f098fce3649f746ebc614f52860dcd2e94c50afd233c544e1865833dc4ae8c78b19d055690a98a60c9a0cb2a498757f445dc943698c0cd2a367d1f7519161a95372dc0c176ecc230a8424e9d9f56a3b4dd4e3a8a26503f80bfc71021a9199937f304761e459b43c8d3c659a0d761b2e5c252acf3e88e675f5790e737087b2a31535e2bdd2e8bcc7cef13cbaf621d655f5479d4f68747562fa8ed0875d58a1a14aac828a9253c8d181c785255dafce2e517329793a57c1f3a4c1d624f94e69add8ea19687b6c99d03b61e3bb9b9ea416ff55e10898d472a177eb31bc616ea62bf4de7de9697ad140c4ea1dd9462cbdd4d203a10a8e397b057f987798d93900e6d6b1168157ba86f8f2d9c968c7848f4579195889b60a67a015173390349e4f3cab3569dbdb094484c321a17e86a1c431ea38519492d122187b5c11f1a258449fe02d65e057ac349ef67aaa16a4629b0a421e7292b79a86c8104b536031892097100b1d598f57f567c3c66476af2e2b87368f957ed266925ee2886697f638426d2a7355b861df59d2f6cf76992828228c707270260787e28823d2ab0429be3ec5aaf661fa0a4bb52d657e787f198004e8ff721d4833199da111d5cabb18f346f81c42a0638dd513591d99e56f13bd8ac8961712ca8e01ccf0967ec00e0e780f29105bf2bbc743bab112c10b9284620770b7770d63afea5ac1daf64d485725180bf00200ee42040848a2bbb3a49a3e491a445bad21dbee1bac7c2374044a121ee2e8c8598bbf0e67e206963909c0e7a810abeceea5817e0de755b289f6d7c2821cd037a9b920a64ec71e92b00107997957d73b7fecffd7c12ee562cd72808b72b6fd36a7e11198a86832d3afaf2655f51a36b5e2faba414afbfd13e9bcc9a8618364e7d9b246fbe2c656bf1681eb654fbe8bf58a5919c5fb6f9ff616700373bee3fc7cc2d43bc493bb3f2bedf5fb2e59af8c3e4d5ce5d9c817875473e771cc0b79b06cea40d74d85c62f8d6a3bf6f7eb62b67cbb69c2e280bbfe356289ab3d208c751e26dd3de63468fa73459ed9ef8acae5aaea28dd2e81e8e0b35408739a9d6c0f3545d96bc9405959aa471e53e97ce2f624fa9cc33b97c9521d42ee6904198d086b014e2eaefff10be0d1a033dc7272b8f5dc348577c5301da23a61e372da3138d60e33a2162331c7783507c9a907440aaf566db967e594df7c2841fa709b0454a3616566fa79692e8cf6e1d96aba7d93c0327cb5b16b540763419b35fb03d91ce715a64e98ba5d3b6f57f23cb80349640edf4906cadd0ee90378dacd9096d0a1f561e45500152c8b83e6edcfed49f9281ebdad600cdf8c3a0e54db03600ae97076e0f7243c54cea265006131401ed0dd91fa65de6e9ede407e9d05dd1131fbb2045303239612a1c84819fd0b88444faed29dff9acdb93a1e7769687d0f7bd6908451846266a70f3a00ebde2904a910fcb0be844e7ae0b05ac37d9654553c40d2648084cb19479743d52e9c263212ba7c178050db2f9256fe69c133bad815df1cb1f44d12eea1cebc9038239ffc24dfdb271f044b33270f568309d5d419525748468309e0b5b04354bb99d6ca1e10ccd40d12ef005a7cba81017402c820199db9f304b9dabbf9e934a3597f3782d3c7bcb2119013406c0bfba00d5fbcbe3252471fcc1b72e1c29b9ed451cbfa6c4339ffcc4cb91cadc52c95439b4a1899065a8bad3c3f298ef9a515b657df0804a075540c7eca211c414744d4c07489e40dec8b3307a709b1b841318d9e263c7ce6779de672935500a21c9d76bbe2b0674172141af4509d6bafc02cccc4192977605445b80a2abffff9d946b022571eb7e7d4cb9ffb49ab0d269cc3888165725eacbd0f1eb900912e651e7a984c79b5f2e9c3e5501bc991d5de4f6797440a49ec75fd8ff3b9ec81f3787d44c50034ed6bafbf0ebd572b98c62b420c48dd710b31789c49a6744c6ff3434c8af64f946e631d1256af424c0d28ea717f13ca1dcd8069cc232b061ef4bdd38f33e86f47e91c407f308fd67b2fbd48058b44f0e96fe53c6bac7c80f7640b3ef29fed28dc10c524b56608d560901083ec04e181cb35914197b24932f2c79b822483f61a2bbfd146ad042d1c4fff51b8e008c732dce6b38b45fc5e74fba00fc8467eaa2be2efa02e37c6fe8f726be5840d6662039bb8c14e3e8bfc852f1cca74afe265e11b2859076878c2620808952e1e9b14b51f05a31471143ddd2aa187ddb6eff6a4d0c34af1812769e258bf7bdaea104a802a06ec58f9fcf9d3cdb63a2a29b572f45850c84c65130792f9d44e825a2759d591704a6c240f35d866e545f4edbd6bd2595ea2b06b2870bba9a3c406944c2fa8164a38a510880fd799202a9b2e87b626fa02f33060d5fa19dfd2c1f22cb30aa05f53a153479ceff07a494265f19942a459ea3ec6c6c7af17c7ec9179299cf08655fde6fa40095282d85353b129a859b45868db4408c2fcb92ef57aa31f166d10692c83e52e43be55a11b00225b2e0b566a1a760366844bd5caa92d07dffc8139e00d20b6fd847572156a8f1fe5c9ba010c740a7460559f5e7cf4b58a3012c8228207f5892129d2b48b7de5711a920154061e38bd18101a9a2bed75e4ed4ca3f6e84cbc68bac5fd22a208519561fa0bcaf6655248f7b5876a8d7006c9d4e0ea4143260346375fda7e42718f5f1381a50d4942bd8caa54d7b3e977ceabc1d7a068c9a8dc5989f399a1c11881fa5556cfbdd6ec57f5aeaa2ca637b5097112998936036b179130bfd75d04c1766e6694dd8b8f3d7c9f22725893f0838efb1bff7459aa79c3db1ca48e1c3c09fb83f133d312a005c0157b29dcbfdfbbb03ae2700159ed8588b8a7630af1167e75bb5478d5da01232551c57445a024ae1e0089797e105c5c61a13894a1a480eefc1966f2e64261cbce78b0a317d37ee9d05f36cfbd93e2f358a7b2a0f5611c0d14beaf6c285eecfbc204efdcc6c0d68adc7e3be08ba2632533f243e12689a97e9ae71f5d13f8964431f025ad440c0b8f279ad2beabb67fe737d5541d0e12621cd302bafbe13a65603ef169fc124d2eae601a9591866a44a332eadc343ff7c7bf48dcb4f4cbae9ef0567d2738d09832da770b728f070fc223c441a59ddde5d8df5cf1e7ea8ef81bf417fc54ac312cceacc7c577860ceff95660e64d55e67a71c09f48c2d62dcb098f65dec5c00216785b2ed344ccbdae1518b6f220e829081ca53f01530e42a980e6486f5c4638733373c638d0ed4bd96a19a92225f097875d18e02d8afd04cf24e0eaaa779f0466d6ae321049877184fad01465a4eae69cfb973dae2051742ff4367323215ccd2af444e19181b9d2218a2e2f6ba074fcb319f3b347c086e0f8c3c126811afd16177c6ffa5599e869f948c83e27727d048688839e6f7bd3f71c553cd103c96ad7e0fab9d0633c986e871a3df6c9cbc6da1f1887e2ee52ab42d516239ddf5250c2b729cfd4dcdca642ccf0815ba22178328ab135c9bbe84cf5ff58619484d15298fb50f327a5623a285999a80b1b835af74643ce691a77795ae053b4ff52cd70e741750d1fa9126a3503285537957016c2e41456d30e986d820b2bac13f37dd992e29a0c67c72ccd450713dc72afa71a978856b24362075a100bd5155b78a784c088439c49f9c539ad632e579e4e8197a3178b4c90f047dc7f37ad7cda31cca1cbaa71af99e1052128e9bd1eb38f4671baded99a6aadb7810615746b6f899d19b2d368e3963588a9db134f0f298358ba3e80961fe33db2e4829aeed979edb5536db3162e18d939df792dece64a9590a70b969ec033cd83e8939300eaad9092d5e93e89388fe405d790006b6f84bccc1f9af59b46fae49986ab0b9129fafb71cb1c45a70035a9ef332c0f43acd595955fe46c2b36567cc5d4a501f4837141ae51018ddc3e255e5703d32f3f50ea89482eb1bc5fb6a729f19f24f2c1a7c4056b704d486471d05842ad2348f32b78e6ecd0c96701ec53fcea5738257a26d2a01b4a32cb371d1cfa250d3ee5a0075b2b992f185bfd2afbd6ce63691895806a5da3119f0ea069dff89d3639e04b1c9eb27b31220c9a724151d19dddd45ee5c7a075791b4b49977d127998f74bc44c87dd8c68c51e95d42c38aa9b3df7408fdc156f8d256ceb8204115a84ddc066dfddd4c818db8e01bfe9fecedca4c2a08dc1905a9e32c2c02b6ed5905f258e40fd1267ed118e88f310ef17789b9149af38404f3b273c581ee043cf15052bb9544a2aa7681086e82b48a708af463497049e88db03c16f4eda46f8350d162d744e64b48aa01c6429447b522fe44eaf22a36039d304a5be6c5297bd95a060ef2a0c1392fd06922200dada2445e55198fd265f0e0012bd147b21947fa55285a6e93107e5b8bfb76630142272fe4476eb56cd2db425ca66c9fa1f8fcad14346c09a6ef3001a341bb6eab0775ddab3b819bbdf079925ed8e8ca3278c1c02ea2715869b002944d5413f317b076a5758c1835abbe74d6c58c054b03959f6b0898b84bf9552c2cf178de00610f88d40d261a3839c0fd074e211702b2d101ec28de6a582314c1bd7c43d8aa4e6e2d843f5217548f1f15fc8aae779052d64fed783745e7fcc27d96eeb90b0b5f677c595fadfb919ab4686f59220c7876a99f02038e21710b8b6b56c1f86fa95f956b977a489f1a8fc81aeb7d351bf8a791298d90b316c74adde0166b915b53abca7ed97de3aeab655af0363a0218d5c89605e9374f310ed28eb5c842e7a043410cdb0caad46ebed50acdc41efad5223a537a4f51aa0851203f00772b18db9bd0ee131464d5c705c7c01bd10c4b04a680a92ff0cd5985746c80044958806773b74ce46a1af80bfe42043887949fe8f88901324f7a860bfe20df6f34a184669255ce7e669d28539d4ebbb2f407df8457b2734782326d0ba539bca2fe977c44b91c82139ebceed8269086795ba7538ba310702e94510b96566b15aa55da44ab14d18fcd549a241d400048cee982729a2a4db6f60ac1eaf8ec6b73c2552c773be604849f2ad5eab0246e7501ee9b6563edf5502c228d35e0f7d42d5f1c9bf1a5372f9a0fa333e677b9161722bc69c824950004103e6965d77a23ef5238b7c82760667ed6e290ffbcc36c28630a728365aaecebf4c4921085ac216cc8541fba327a691df9669de572602e5c2fba943bb0369905d475c0e9f4b68cd97458c6eb1ad8a951294d2730f5d71fac835d16d3478dd704bac2627b394af92218d46567c8722e0a06a43ea30c78739a13f9ce5a9dddae3cae2e51b444c5f78edbf1615fd69cb2303923b0d6491fd7bcb237e4e3aa955b0a01249a3f228958fb53cd2c69074c61eba0d2ebbeda42254fdd36d0ecd395bf47f5c47cc1d98ffaa24d2ea2f0c6c1ec0b26e5674ca72cea9844b9d0d8f29b7650e37bdfa4e14e6f5faee9d26e4c91c8584b7c5e48dd1392cfdefda5ce8b546c2020dec2eca47f5574007e529d641b55b0b043d48c531a4d9548421d9286826819a451c189db118c4e46b9a0953e3763e11cfc284348acef5fe5d1fb657791c8e36ec272a1c34b7b034fc61a0afad83233c904b9a37e0b6511413bb526445179465a0d563493a215f492bf0324d28b4783708d30140d8043f5e7d1d84e65c9b15f144e0161b941c5a3b1c9657b532322071c2425a12874691ccf64b1e0b8b24ffb66306f7d284ba078d241126bb214e94ea814b72e457182c08d1bd648a3561a7fb901aa65efac774b06d0046d30682e5f17d8e2b4ac0fc621a810c4b22399f1ac7e8bd9cfbb8382fb2e7026b65260db8999a8833073514c565a9305f35eacdd206345143df8a3b61e5cf7b1c6e07cfa9f95ecf40138b421342734b257b1abb57ae4b0d18ad43b665003a2e7846222331c3d8b46a1fb34c8c6583e79adb1061b5cc306faefa869daa667f85e716eec6fb35cbfe250150a38480cee5d88467fd5afec43373bd63318ce24044d508af3e2b62c06e6585f0f7f5541bad8e509caaf02a81508e70c559cbbb59dac66c0c64db2b4409b1bf1f81e89301b1639ca74337d1eb7e3ba1cdffa8c8f9bf7ff57322bd5106e8d6a036f54bdcb93d26eeff194de12000ece281a150ceafe579fe082fbd6921ae0fadb727bb188537aeea26099d1a0dd7178b2925ba18d3ad194c8f58688948afa214234341aac5bd44c61a16042bbb2b758aaa1a1729f6b5eafed8cd6ebf54d08244b74e42ee055d6809d42ce117d53ce2d177b91f7dfb25cd44b85815a430e9b7492501ee21637aee1813e92bb61e996cd760668985321956995dd0af14a372cf182c9db5889ae31ef799c3956845e6a7437f58cbe15663553215b5fe69d13a00b19af9c585e653840403164f80f3220cd6a3e6e9404731f77803361d337a29504131fe96952d9ddaae215b5b255c090e25135e9c17d59695933752d1fd69cb1c7448f87094cbb1c05c4f798b30939ce12814424d41943bd8561bdaffabac36e54b8f0e38509c78aad0f85d6eb548c251f8055e9912eb939fa3a6a99d0c680b24e64b5153c675e02751867695cc1c49e48ad23fe52d0bfd1dce02ad16a0dac43453b0a9f9cbc328605cffc007bac5bb290be88c691a7372d922cc648388b7c2383eabd8067d869bf3d9375d1548a5cdc807e5331ab31d4e7cd69fa7638b2377b29990a8bc2190c7ef1b4fc6377c9cfe04dd35b75cf2d8d9382bc8f080be91045533e583cd6c1195f2351913137a68646420ca364bb6094ddaa61b291bfb3ba08303b907b131893d1669f0c9d93fe9416206c2a9e35c1bbb9c250864d2419be85c78e3a344470c2ff1387176bc88eb6fd3c4b4dd657b3f8f59287d12731739d44ba76fd53d38e500c6a0da4423180d9633f9ec06b615078784ecb555a2058fa9f0d731c0bcb22960fde08408af99aba9fee566e3bce929e0afd605baf81ca9be5d4a3a3bc094dbeee786168ff8d8f4c2e15164f3663da796f01352dd4d5a87a64eed98e8a636a4927aa3f593bee2f30978c68dcbcc94a04efa937ae6183d07286a4325f132c7ae38f12a207387145384bdf3db41a96e229f8a6e462a644dd79423eaf4d70ae96c83e87abafafc9cb568093210a1dc751f54ec48d07b70bb488a7dfb2e6a52176a6e89dbd058ae94c1096d83eafe926ceff8f68393642b3f60309de0d2936926a5d6ccecd392426c6cfdd5cb33edaab3e3dea35222a26701ab08502fa785f974506dc0a703043154678aaa36e80f3421501f15f2fcff596515992303ec36ea6931b87fc757f4002db472ce01dae4449b73adb36289df79ca3932b1d04e1de33dac17d55f929fe7ebe95a0c7c3049e2dfad66da564c1557ca47701e1efa053d6c5f5ba370e83d26c757e05bfb7a72d64eb551ca57b4b786f0ad3aca70bb75162a1047947bf0ce53e93f4e9af7a434a76f1251f02749607b4241454af596c744518e14f0c340041f53a2be889161fcb7e7e7efb6ecbf55801f208f830d7a64cfbfb4dc01f55e7533a0543c6a844838b3a152c872b3321da36e34adb5ff0974c42a460bc956371ed2fac4b622bc9f693e5539907e9131f2fdd006851e9d27ad05df99e1a73c713ee4728efb0ac8d4ab89c2ff3535f0b5938e6b29cb9030dd57ca3454b2e0e15bf6bae7484cab90eccd385e8f551df537bf93307ced8ca973adbf6d516c16579ba73929427cd6d1670c8903000efd433c40f896f2f0e3e80c87ffb7ea1dddd42c2f27c067e048ed9d4d6c340a42b744ea425dca3ec98fe3d63edd921060b9287ec7fb4cf43f7f39a5e4ee90ac1d5e473cd931868af4f0204786cb859e159f35144d9b84226fd3bfc51a3ccbd7b36d7b0a5b4e6cd01f41fe2bd07cfe00fe4c74af8e099419765b32830a0ca40f16ded9a0de13b7a1acebb2e821201344bc3e1ab791caf299069a88f69cb437fe54b9dafdfc7c688364babd9dfc793c3453ced1ba2fae72bed5f56c2c2e92670243b4ae62bc219bbe09d6a06a63fa6163450e29d41e1698367f2496bace67df9a1808883e285e90280826a17b01e85bc423e7ba015d802a4579fdc550c8e67d2e9738c7a8036656f562a0038b2fe22f6462aba84f1252a5d034d6404a4c70477f1a174d08b4795b38b68bf96eaf04a100273287c906803c798630b428a19c1adbf508de03df169ce2278278c1bcd66c6c10fe7239b3348d82b5b1787437f9fbd0e3854f26ca30ce6efc8dc9f2c1c44181c8a724826e42c1f1c6ec8424327c10feab7523d6e25394af2950e38d64c85842e30d3cd62766eeee0d010bc72d7dca713a5c63f04288ba402702e1e63c7899002c92fd3acf33de920e44a603de95edac4a39e6c47a237e138d41c4cc56683b8f709777ab17114901173f1c11abf48b89cbc5e545033ed4d55a17f048e08d0d6120294d5c015b243d8ccb8d92f3e2690bca2864d138b2bb7cfc3ebae56486619db2723cba0507888cb7e57806d65610f5b86e9c30de48d0666be30a0fea9ba42356ea536391ebcdf04c3cc2a0429b88453b8685f84264e73d7c4f2bac3ec74b885a11285f0844df9688f03daacb3f019609df73536bee11951d89a7071e97bf30e51008f57cfca68f093a4e3fe2b463f757fb4a121b2337dce1d2d2d94c62097e06d4948a82087d9e8e2bf6566e8509710236779cefb258a539656a181078f3567460527c98b1ea85cb84bb0dd32191a598047a966cf1358b769ab83942a16208aabde288115dd5514e0e0248c5692a980a916dc47c88594c9acb9f478b0194ededf86302dfccab7197a389f697d125fa57d0d158b15fe6f4c939db70e1ed2f669702673ceadad784a109418ce0c70ef9b84f2d5dc67e3270d8c2ac2499b79c3bf205d0f7e7e78a98ad931c6894e0c579ec37ba16696e6d1c3f04074e7e6862c6ff391914074975cb1fc2829103801c4c94ae7cdfcab5a9a86c1ef5fb4a64ed1bee2d0d011e009c94302381887ea838b1e689fff4fa5f21d164a467acc6b0825fb568e4c6dd1edd60845158427d2ff9219f106dab3457a6ab561dd99bdb8be09234c0b555e55ad362a6a5be14ca154365bb3757ee69f2d4390599e6104188a208f068f3cc0cde1a90146e5307e3d2ef482889d6eabf8a994289245ceb2505ad77ea1004b379a5e1d12412381c93b0199bd0b2743d093729f4eb980cde4eaa3798108419ea6e8ab0e9d401c31f51086066a4bb050dd9ae7de31e415d8d715619b6b440bee2e44d3eb304a2f2763a3e32c941787c6a33a7c0171db7de7ba2687e7b3895294dcdb20ac8542ed16bc4ac72350975962e56d03816debce65ecb55ea34cc30508fe071f21db2a5fb35952d1ce93cdd51b978a0a1eb81117486f8f7510e2f4f16dd27d144b72c9794ff5b2b0056be32dc91e6affc24cfeba41932644851063add8ff4a60a3fe9a3581c7eea52d891ee0e711b9805f05dcd8cef83b6d4048e591ad6b83c90e604670feb42cecdc55588550b5cbfc60b7fe689370b4ec4029a068af93484534b7cd7054c4d31e31f00c5e62cf56deafe53d4f6df17df20f480ce7a3a9f3d330101b23a0bce0505ca3abac607e8efb897ad0d89d2e4c82ecbef2f3512ddcedfec1e30cc0296aa8e058f40d474b6fbcac83dbaa1850051d456aac2712a2899359cd3c9bd3ffcfb05ca7130febdb6fabc569e9d13d4d2f3e03dd90f8f817b85756d8119598658db70c3c75836da299c1261f786c04e20d622680ff6227b1fa0282574bcd9e40d6b6c4f45d841b4a1ccf8eb6418fc39917cfde1d5dc0959e231b3a7ea9ac6ff7f5323446d9126bde72e28fd2d48b32caadadad0904b27cd0e65d0b6f65a0f73b471c37d34968a4a7944fee4db7e6d69c9d7eb9f65f897492958ec5d3096a8c67dbfa08335d4273d725a575ef59c6b7c4413b626ecd2e66fc4657365f258f54ed8bbd891bf0d6a134e3b3feeef55d4ab930cd8f1441974ca8680071695327f7a35ea4b99d56448083bee61d64c50736435aa83bc1308bca48da89c24589acabf63e57683ab536ee37cb40f7983db81db544e34b48a25a8297197e8d5351c9582e3240ecf39b698fd82ae9f2bb8caee9600a5588442b55105761ec6c63b1ac3a84e547fafe3a4e8ad57ad52bfba3f844654eb79840623d92524a93b7d587f360ca2e4651c5d1c1e61abed43980d9b38cfba9e3a29e3b08fda959eea972c5ef78bd719d5c44e3e7e20ea67c57a9226ba2239545fc8566cde3ff6bd3287cb0be702ccc7d382f968c62b95fd160102df0a7caeec24bc2881539908826730a2a39c9d0e8f6df00233f3a8064151f6aa714437c7d70b501122ddad44eef39e7940260e55063cfec98a5733b1ecfc347b591065fd43424ea67cb8c9818c7ba7a025c74afd42b42f274449c61c2182384932504ba653e675d190afb3c901ce8423265993b9e8d5c1999ec13a51072762eb0e41909ee5fe53d6bd7b54dd13f9aa5882d79dc93910c0504fdcb610760963705d85fcc0c2ddd6a2973c113bee0c6bcb100b2432481a4ad81b17f9b8d19bdd1235f4f7d7df96d8d51fbbba0cc4c7af034af3357b242dd903bfd6482e0963673a1e58c3e0f9a4b97c1e3988bd5b5b3a87587bb3979059a3e2dde976f48fea5b50ca40b242556111b387b22107af90c1a23e1c54cfa991ca3e198fb210ca9a2876595773d30d2f179b63cea7e06b05f80607363ddef76549dc3da34fc95af38c60cc0320622a1e58dccc3652d8e7313a9b18bf44a207164845c5b6fd349f8cf0918933f684eb83f608540f073b90ba0f8040879524f0ab24bb53f436848a5691e00b332766a2ea42dad3fbd85176b874057c357def071cb9f0d7f8d00e6a5f75fded8c3c28ad91617b7495a0743af55ef5bfd1f8061921409cafcbd80d53c49ac1dc175b05ebdfad20f428d5f62a5ab644ed76174086984e61c06df3cafbfea54ec4d960d034de0bbfe8779b8620a1b54a1f36a5300b505ce360463353528e368ea611c30720e1c2916cfbc988ac2edd82a9b68522f79ce860588ca736c0048b4df70f4b0b3ee15b7e50d01de460e32e7ea78d0878b1f538969151751e2b8e9911807693b944599e61ba3b2625db30f1bfe7d7cb70b5bf276f4f7dbffd07b86a4fe03fea7dd0f20ffe781cc22d161fbbc54365e56ae084ca61b5acc271ec2df0eaa06c8438d3716ca5a0332d41dcce3d5afc9ff4346fcb09baee2923e3285481621dee2cecce2cf563db42382a30d5efe2bad42e11b43c17272c5678a5fb5d24846168ad3454fc7e68a37e961b16d246852699c6ae822da00de856ca773e8f5dbd7c6f79e5b3921b2dce1a1ec1bdb78c698a7c2a764b83306f413a8c5be1f53bb0aca45431e86c07691e3d44fb45de1858c1ac1424f833bdc6ea0bf6d9f790a80d0ce35c88913b4959ca67a8d29682f822a121a4284b1172c62e6336d80972ff064eb397093762228d62cdb5a9769771fed682bd808049ee040393845dcc56f9db2102466af8f4ef54da5c8715f771a76111946a96d45f24a4dcc6380c2ab0299c25c21cad77a061e7009d795f77f506b6edad8370960d39d273e95a2748d6de490c6c25b9a1a01090b9c3286883e5710720a80d1a0a2c37f2a6830ddfa302fbe2ecea907a7f059b278429dd25d88157806d99f3c2aef3bbdaca7c585656ca74415d864750fbc272e505759b0cafd9b3b900c6967c0a1cdd9944f3ebfff864f4c99c44331d2ed504562402b5d9e91c64290ed63517c752349846a9a9c3f0462276c2c925704b6fdd0588d22405059c210c3c418b10316cb3b767d5aa70c4fcfb61990ec5e89296ecf87db862e2c3e93323f3b31e0f9e6a35c6cc31a8c2d39b9cf79778553189a50c24983dad0721be6b18202610a16149732ff49ffef7bffe3bff063f2233ac840e49c32b1aae6078cae12b5dd8f71d812366f1480255561bcde2514b0dc8c753b0f034291b8bf6932eaa700ab245d888e1baadf9bcfb10f8753ef698c0e83496e0a32172e3235eeaedaee08b24d180e89b0b449135b1916a8eb0bcd05cc5acee235c19e80de1f4996de852c4092042d241215d9a8805b200a791af73cb88b8e3a7a3122d07722fdc72529a6ad5491886e1ef29f3696f361ab9c0780d176ddc505629e6447122420f7d2da921ba70a2d269fed7187c343cb0252501c1e28fe258b3c6f79a0205458b47ccc6e1ca60163725487a3f6545970814dba104a4d919834a7b73248640e2fbe2c47b2a7cde712f8d25e684cf145c4e97824e6b1d6fb6b02b98e380952b9fbfcda58b866fdb079f7c02d0e9dfeb9d935877898ee3e2166785987668fcd46f61f8da89ceae8789ed185d1c8563837222760c5a3af12658b862d0ff66c998339492e10ee2a9348c5eb85555be1686c707a6ca6a13b072109efd828e6964d306040627076e164d581bb58abf0340d06885d3b2ebddf81a32e6eb710bed03a936887a71bfe7b5ae5f512710dd2defa79cc618325c18c380db7e1d66f6121f70661d3a6368bb3c6b54ebc03253b104ed8785e1fda41b874743e31e029b15958fdacf6cffc95c36676d5dac6753886ab655d1decb12b12824dbe2dc979f3febc3d9cbeb103c57f9c8c99b866a3f3130f3c129bdc5fa69231fd6968edba627ecd1ea46ce98d6fc20fa2bfc1a01bbc4b65a54f0f93f7650ab344c5e17fc0e51590e33b7a608a5d8bb3c6c0f2e0c7db4d2f66dd65be481000126e41eb986c107ad63864dd2e2564ec13655223482abbecd04eaf9cbe58015ef757f0fb2bc7d6d9b5e9d95dc3d5074d9d18db7458e4dbfb58540e921a6c78824f91f1f3211e0bf5880135cf212444961c77834fcaca6d9a13cbf2e5e16f7db64f201ee2764dce6fdd029fca7a78a9e0ae43cf49a41a3d23acd52f1ca1427b1a2ef195ecd4a90988c0e885d290f4dac5043e6d1dac33012b6612761101de640d6141e50e562a0eafedfc20dc71dc2bd6687709698da94d30c1d9fec95b20e5aa6cec4c50f02e952c0423fe24c0584308e23d0eff45aaa02b53401d2b80fb24b1c32320c7a56ae67b59c954c271ef123cab548eb3460022b4b219627718fac109a41386b50b269c744de81f57a476c34f59fcda649cf33cd87d47f92e12067f1229700464b2cd6c1b6283e45cbec3606d8c2b4348d83cf7d14dc694dc8e64a44c65e9b28108a7ad5120dd85a2e74511c21d906531169dd85d11f5c9f0196ee602944a81d2108db53cbac87d8579f46324c35df5126338216de5c2ca8636c30f4e9087fe2147e2284f1265c3e7fdddfd68b75803dafcec8b69e72290282eef23205ceb3a7b90f34c2044adfed89170c697cde8e8ef5f6e5bd6fafe049f02cce798df5e5598bcbdb57ee9f461b23e6023728265299a51179e700a75104a4c80422a416907ffe11c2444667dfb3662da0bf94bc88382dcd40cbe939e292237f3651d0b0b2393c051865469278b59fa401a8850582b76ea3a882d1d793e764e7f0dea1277ec0d0ab8d1ed02afdc743121ea0e8d3158241a3255d12a920f993e1841838f899c6dfa3a12cc8183f25db00e7c3bad2bb45ddedcfbf9cae65adbf485170fa3fcb88f5cc8f41b0304a90d272aafd737307d723276d9a47536f0824ab8eaf4752d1b10a05c0d0168b144832b26ec7054a2d136a0df3dcec9ff57390cede98e8da3a08424929a830d39e77223a20bd7d65718c2230023cc3e61dd95c3758bb71e1e2eaf8b770c91860c8861c90609038e0fcf64b8c0df5934172df09280b5085203cbde38ddf359c1327031d5285dcd064ecdb00a8b5524b99cd29c90721de4f374eab61a78df4c438deaaf323dbf66d595db473d4c31408bc0e7eb030771705f9162e02a881e75c23be3b65680fb1582dc1f48451813af8ad40e04f216c0e3d351e8d423b35fcde875a931abe1753348e0b617e3f37fea673d234fe5fa8c6087596e3cf7dc77bcaa79c058a32fabf196c60cb4f4b27c3783a58a51c84968f22383eb2a740db5b32bc3af5270141e563b77a02f317856c2d5a12156cff2b1d0f98da85916f2bbd3560dfea621aadc78bc590e237c847946bd7d606af4b8069c2d6665baa3421084cfbadf216e9d7c421207bb788a2fbbb36916e32af70f49a171686246b8f70d6bb6db8f9f0dd4aac85f6797ac34c76bdece177ca3cd9d35957e83769ade038f3d11a0a6264a81f96cfc938c842a6ed13d7195546707aa4137c0a85b1f055667cc13a962d9827e1cc88e7ae04a483fd310e2a55c0d5e0036341f3c281bb3f4d6bf0dac34daedcad2607eafec6110c9d94e137a1f9cd0ce2ce950671db4095ac93aade42d0e4badfe9f55b400ecc9c48f9399ffe9e13d028b9c4c54f52194c02379ff7b686e2cc3d4183cb54612c22f16b96f25fd48285e965eb3933325926c7fae6e7e2a9c313934fb6e897a19665e8598e4e5dac963e8c33b37d8c183e70b9c45b3aaa8e962939b6d2bccc5be5feb6fa9f5d750efc830458fb2c5ed3d39b5b453277bc17db3c987a93cc517381f6c5594457fa2cb94108b44f4b6b995be686da009978c6965cc8870a8dcafa474281e762e856499c661f7805cc8a94b5efdac08ad4774ad8366ff42bf5e92b50b6c1b9b42af3953033576be5867880760d5a13235cb95d76c346f38846e546ece6233addc1196d3f72a3735b5373e6c65e0ab368a8c1980e36fa04473f9039a37fbb064a8251136472662cc574d67b2e8a69da04614692fc7e743d2d1e24c2fe1ff70fda6c059300f9d957e4fb89017c9eedd5e1636efe3e85c3e96c8ab98872c46b71fe0c586caeae030a5326d884b57f1e18ee340c346b12932465503b118237d9f6c319acc369e2abff48aef59fbb0c1f9a1563a7aa1c8886401b4ea3e70534e959a13aa9df54cb84f45a4e42e9ea9fa92f242fe01a267b2833ca9b433877c92a205a9c7580063a966590196e340eddf77303792bb98faaa3d0a2204b22bb0fc095b8280647f8a6fea4f1f9654733b897768f5b83eb128b60fcee939ebb005f59499775097139feba713cb56f940a75faa0ba0ee883cf049d084da3d9ded8e4a86a30d87c07dae63c17414a1d2c95c0ccc433319a954279d69ccbc1734bd8a0947447cd8df83de7ff727b9569aecfe138dc1d51b97e56d53d9a33415c533a9a16829ba261e91543971218331716448baa23d1ab34589a702d6c63fcb87dead46602f762ad46e95996f13889e48c6b30576aa694b29eb565e1ebb129dda565c03fd72169105d5ccc06e32e65c179f9f45b6d9481cbb4d8c521ca407694adad969e4a1248cce004956479e05ed662a034f331490338b7d29ca45ee959d07906a00cfe0576559a6ad662750d8f2433e2aa442d67639277d6be885f697468a3b9058b9f245d71553a25a83460b059f15a6a659c3daf998d9e5a8816a680fe14783219111a5c83ae8307a24b96dd38bb50a05c73485dacfecd53d3cde61c70f2b37310362809b20b0e80d39feb4389988c882413e8f6cf395a9f5ed3655306cc4df4885db8eebacabfda8225c0b60d0ebdcae6bd66e8b6e78cce97d9742e55ad0c420d7173e6f4a0dc82289ff4d709a25a3d90d10e22b7c302eae2675d92c0fffd2f2df2f2c68c56498d5f1d33074bfd9a6585d1ede4867595ceb19a1c70f6f3a7cf120350e3b18f6a691ca18e0d53a167fc0a18c692ab7756baeb8217b9ffe3ce59da22dc579a331902fe731ec6fca69c82c05f46f6cffe5bced875a08df48429a3a541cc5f4ed2a0e028b765209d1beebea27a4cb33a2bc336fc91a15240016d9b0504a0aec99481b7c146bc02050d616a6aca6a5edc98946558d83b7c2df2e2b19f5b2c0849fb6219f7fe908da4698b6d7ab70672aebebc3b2c1077d239a1eb8f883d8cfd86488c387fea93b700698ec09671f3b5b42e0e1a2b9db9b050de1f7850803f42075695f01b4ba7be83c98d1e496ebf0fd86bc4a0d5236719698138116b5b2a290eedd64468ecf37f8e1231210c66d02993311367d616cd04184576fdce8cacc12adc3bf312b50f16bade7f0f094a51abad40a7493f27056c9b4131ea0b7474b73fc642cbae5f6f8a0b6c9a9b8012c8f450334753d6bc435cee753f253cf20c3ff9695d9235a317e5b44629c66e0ab250af761274c4092ee5814c76077637fa87bfe1f513b2472f845b45bb51d3c9aca7ae7da2874a3f7d0777ad0672743780db43c050dfc5b3890e6e7417ebb61a7849544fa286790c64b2894751e95258ad076bb60e839d9eae67d935f031796d0fc5e67bfc40713024feb7ae90d730367187fc8fcf98670b8b48e3389278bb4e018c1591e94aeee97422a3ed2abef23329ed30e1ac1f79879ed6497a4874b03d0be04eb5a88ae90533b851792971fd0e01a5493aeb996568635a3d1d8d470a3d6cb4662e9f4742c917b787b7663ea3db4b1b13478e454037df05a31c96e09fb0f0d0010b9165874bd7faecaeba044d14d3c2339800d167c3d140f34ed4b5f6a7b1a97e241d7ac17c9ca081eda5a4a6645ae8367526dc57a94de474be809f7ca1ffa65cacf80a9bc2da6fff9736d6e49ff3abc4b27e933385cbc2188b82b1828c56ede4878d351386cb53112ab6b6e6288216e85c4ae90cb53cd04084d68689db4ebaaed7b1fe179e2b2fe31e0d8a2f0f2cbafb9b77210fa53f44df011c39540bd303d77cbcea1f09378854395b34bed815826cc095579802b9133b5eff191dc17b71a88250cc3e7bbdfc6649f2721750188c217d693d02af2baa4502355376373ab6b7c00f59867a577a41827a5dd91aac782141f58c4712262ab7db3aea2af060b2b287f50bce715637343071af8cab24781a860d49fcdff6e619d82e2020625bcdf62e0858a3e10501dd32c980598a97edb65849aa7642fb9576a044a50eb6ccac06bed93536834d26730394d6c98a0bf73ef4ebc2057211bf4822c373fb72200da030dec09b56c3bc3060a686016f4dd3dbe4e0c80afb200037fe58017da2b5e37ab876cc56b236fa69f8abed1bd1842d6f343e1059a3ded9cc06753d1c749e163d91c727653e361ecbc9298c8648c6222c1a3ab4aac1ee8d0ffc5742bfe8962ea97bf27f0048ad1095c678e5c64b6a8509c733348a36e5e3803311534f74608880a3c032ed9597b444b41b71ed60579ec0da68c141ec3696d332ed0679d4710eb042dc8f2a6bed49427fecc489b0ec71e0d045dbfbfd20b132cc16670d487df5f4fd125a8116731716c12812862158f0ccb3d0b88a4cd46231f4128f265e8c00c45f07465a3f3dbc92b8081567b22d13b3c275318cad9a6709038c1ee717b63bd38ac543d5d09b140ce2ce7e89071e32ca824448c97654de38d0db58138583ffcb9ae07f4e1bb24e82a796a1a02e128c504e941418aa607996933af845378d6344821fcac54348082f44a78970e800420685aa9d95809d25b6e5f2cf057cea6207bbba4f482749d1831a2026be01df1dc9cb0ec96731f474dc3180dd51b083da5135de33b90d0cdd7bd8f6e41cfcaf150b859dc98e73179b508fcc6beee105ac6294ed556b85a8ab467367d16a70df0b3474120ebb5c67e4e4d56f6218ca53bc62b6fcbedbf52a4f70d0af0b2eba710c89e3aa0ac972c67437d79d46765fd369c83084da05698b2bf8101087063d4422a74f47fb1da5364230900091abb150f42c2c28c2ea4e9f024cd4180c9dd9907674df08b0cf9d235e8cfb3d5c9b78d982ee65971412ee98897350f1b59e4924cacb370c38c6bcbf1d86b973e6431b4493e91a1a3b102daae3e10fc058f5945c61dbe8d6ba334d3e0816ee6a574d95014e291d5e0f535805915e8bf003a064d147d54af1db1a9aef6bf7cdddf778f46d5d8c397a05bfd69af6f19ec89d509e769e82a3db50650b7c8b2e347835599400e789de606c601d7932ba4771d2f90630cfc434416ab8d1adbd5fac53bb69daa18d62387df23260d1bbdaa6b49fc8f4991a0967407e48f2d3a5beb795a9d4b56564b1230d4ac23bae48eb49971821b41a15b87aaa7cc6a8daab9f701d8b7aca66d2df1fcbd0c37ffc806668da7719d7b59170e8012ccfdb55d581198ce36516d5afdddde135f5a6fbefb2d4705bb640eaa7f31a163eb0e89978d116b6f5e9273e057d998e470fdce0eab482396d2177cb74062b5717cc6d2c463de0f09f566df58af31e2da9f6d3f2d60bbc7a3703cc36f20b88f8300903f8dc4e9905265bb08591c7c2182186e2187684aec0980a575928ada3a53416ca22422caad5e99237a314f1f59537a2eda0880737a8e2081467a243755e807bc0fb76d54df030387f718a5e581821b8bbcc855a2a83b6f062e201a034c18b01a047bd4b8c593efb4db884b992958ea5f919ff9c9bb6c804eb47d6c0d9f93728433f963b79193d2d8de25368852fddc15615cb88f5ab42529bfc188eb486343b466eb36757eb10101178cc5fc5af66ed3876976cca0e94bc972a182fbcb40d8f45b60407e0b50493716d01f218a6416a346c35161a7e581790aadb06aba2c21203682c8045664abd2a910da91707d73e24433f1d3f253901158df95d1ffec9a86d04338769afbd77bc6f69a5616fc6ba3607bd89ebda6f17f214c38ed31e8f205536ab777ca7c3c234e1dc0f0c9a32d045a3220a54fd74c157453d4c0ae457a234308189ac63101f9eee50760e1326fcda14242adede7650ef5c76d35d0c5c7c04a5e68d9af67f4207b410f5080ccb68846f60fe83f4e1668bc611629854f6227ddbc5b029e0e250639e4e9b253b614c39ee983391909da9381d1a0d020c697abb29ce072d45df50cc3e38222deef963e45e32ebd413bcae4f24505ede630bbbd5cedb070a482ef9ba358eb55b9fd0d10deaa0aef1d68c2a297362f36206deb4d044adecbbb53ad19c64eaed65ddaa7a708ac2b284a3cc140ee98739491e1bc34fbd14e0fb93bc4eeebed3a88a9a3ea872a305649ea26744907ad2a874575691ef5ffaa9a8a2a8cc64ce267a931f88b27099977456a435ea4ca486806ca95bc0bee5dbf8292cd9fe998e18048a301fb9b7f44eb90e84a63ef04c98f22b4abe4519304b65aef22b5feeaa73d1a8748521c41ca35bded866f68685109f705da202435ef5bbaa4c4c81b0ac631925a27e64c36f1915f157b47bb31e7b5bae3813a4891c89d1a2220a76d65b39f4a5b293b89ce0b271366c8e3ad10877654f40211f92795d08695e56e264deb53d0381c6f1a757542ceb2b1d511dfdbac1cfe7af56f850a583b3593a0b25ef31c002e58bba35021fb1438d95f3c104876f38bf1bf62d8bdc18a51440364a9a2ffa031db7c69c2daa74e7791df11852de7b6cd59a9740e02c370cc4458ae55a88cbbe449d7a44a27351ca1dc0e3f04c6b0bf4ad47c735e6364e2c111bab1ecf3f1a30c4376e0ed2158b829a7f4259c13c44705014d983d0f08dd5472f3326ab7c92cfcf439da8845ac1f398b757562870d44d6f3e2af0a71d898ffeb42112cca88719fd7def8980d4aad0053015485ce7a76ea67821a08244fca37dba68a5515b40545c0fe4a8d2f5b9be9704872d87c7e13aec2fa9edce69ec4b7b009b15fe94ab93415c48fcccc0c826b49fe1873634f34a74b07b83685720c2d5c34f88b2df9a9b42706390298c2ddcb07ad9e6f3c49121448cf8662dca7b37f8d6178a49c8466a16565f0a46daf13a60648709840766a0b12f7ab949c5e8fa35d6af33711d39a86824f3cf3cc85c94b792cf96f993a44af17d6fb96bfd5420570baaf93da024142edd5286420ad035582ebee3d71175459a0bf26d305fcf7e2cc44650fa67661445988848e36fb861eae032c7046c23c8fc4bcf7fa3a56a5a01f7a6898ee919eced120761d01dd9bb9c04a55797ca3858887eb77d5daf8f7a06526bb94e91271fb88b1f575c339847a65a3863deb5bc08e1d410bf6ca30a6f13cfbb584ebdcef583c5382af7f349e8c1a35ca09c49120cf8105a97be0b7b30f05e6ccb28d61429e39bb07527be9de8a687b55ebe6a9ad3133f2d53ac150180ec0060d605efcd826ae18514ff11e7f8b2a2d9e198ae6f56399cdd9d5d32f10264bb3c567e6aabcfefe8cb63e91f3e1a5c9686a8e0c294840f62442b009531d898599aaa9eeba84cc449b150ca715ecf852b5bd5bd5236c6d191d97987a948dcc8194f8bdb8cc467c50e4da3932e6d579361702a8e627cae2483190a1e87a9354c264cd7c0404d6598871c348fe91d9646dc83ed2e14d9ec0897c1b63d003fd22166669b8bff94748b36c4a44277ef522ee346f757dc8ee72f2d50c67f5e763c73ce44e59a1c4e3530745fb4b45885418d98d9c3b4795cf71cc9a62e0811a13b9880d019be8227c6d722148ba49016606a1283433afc12eb1e55d6a5249147e70bc87b13ce41d7f163f04d386e56add86605eca1d66d6cf83fda3fb120086824e58632448b03214083697565971704a144e90387a48adf0c7e826dc7b85de74e70411f3b31e0e87ca872feff8198c8a4d83dcb0ec2057cc4055aa5948f6bebaadcba375de7044b982ff9961ea0b64ca604e8cc4a022bd4e0ee4461f8f3bccd8110c339be96ef51d7c5ca541e2d64be61dcaceee38dc6773d984e4d641a9041ad6983b8ac29f67d96909195cb360a400a3abd5a3fe01ac1475718043b0c8fa0990674e773e0395830c87265661fa3183621ac1404f20cfe7bac12a2b7d0fcae607f38e43fcf39752cb1e1c81455838d25319dc8c7e86776f8756f4ef21e849a986de25ffaccd86096a18f88fb4d04f3de0ea49f50606daa304ffa426b49ccad2d5f53f125c800bcac1487a95c26a16f97a3e96e6bbb3f7ff27854326229008a4ee0ed2862dea98970cf7d70c7fc68234d5fb1d7d8e8541f380fb6c01ec9169af87959f1b0eaf5e41b32af1afc6e6b68502a797a0a20ced5bd1938082836c50fe6b77ac5e5977f74cb3aa7edf16510bdbfdaba6593d9f9920980d69a25c063893e36f171156ba0f69422d056a9b04f2c532bd5d0f569b0229f2e78da199cccf317554ec19675172618944e2506499fc955e412be98d24fcad5c43e86879544d3614067705de161058307bbaf3725cbdd9d17ae88957faf8209a18c2f9c246dc07d451651908bd2c82034f230124730e15fe459918c497832bdeb4149243a747c4abe443d9208f399a723781c49468873b1664269ad7f2649f6254ad2c750e06228e5881ee1e537a06a0dcfd32c8774d817bd6637704c8634609e92decf1f0f1d1ea3ca839ef7b69fcbb6d7cd2849b28bf668fd6d9c83766edf104460091a73595cee20821da394a6992987df970c89d3f6a7b063fdf738b88ea18cb35007ccd4d286a4c54b2365f6909426054b86fb93bf945b76dfcd4779c5ad1aa23f9d1264cb9fa934c44fce4253d62487487f9b041f019e892a8a20b321f57a94efb3ff469e4e8c2f3024698c94a57e82edb3e11bc4c019989fd622e4802b91305130a2334a39d5f8c95f2d1cf7456a0c13146787fbe116f9edb9f04f2ec3405f39432ef4901c79540816b9ce6b28d322c2596f57445341bf5b7a8de8936139bcc5c504a1c6b7d4f78283bd0293afa1a8846af586aaa7112210ae959bd62334ceb002d3cf6d0425fb440dddb8f51d701b1b4880118d23fb921be6ece3c4f939729e62e4fb7649f38b0d000fe55bcb54f0407c865ca66ae1da4965962e60bc2e5d2590af7e1e1f01c53ffe89b85d64f252d7be31a3b7015fff209aa586b8a59c1e6a20bb7bb1d7339945a1cd4cf02b9529750f0ad63bfde2dcc7c949b0127e88b185552be278150b4ae2828121e026e88803793cc963dc93796068a612cd363fc29892cc317dd9e6c8ba9b7cee06a4f7f9752c0e40678a2bbcd85e9eb1f6be08a2ad9a380e83a0ddccb8ff3b640072ed64e7acead1fa8e43bfa61f40e361a8f2df94397a343ec345ace0f08fcf21ca0a0dc339c021cc2d52d4e9d76ac198c5e3eccdd2511923c03d82a4df2b4f97f2f50c414b7b7831ca90d2485411b6abff91a63c979e5fd9e4162213ba1dff5ac0e12cb909cbbe7a69795d71ffc4db6c7ff781e2a95c503c76872442e16d43f112494cd2a46601b3deaaaf8ab17be4e07de265b9598ad5ae0ad731f16e3dad13673e270e69ae8e027abbf06a541c54962abf82577139e6ae5c876d2b3e4ed1148851ee1385e017f6dacb9fad65911d6134b492ca024378262aa496c22a1e421353f4aa25ff4a87364ef3ac39df0f91d25844f613349608d8735530c5cb0b034216ed601541544825ab5b6d0b0ebfac07a4f5f4d51433b1524511accd953a26373b2a5826834d67da833dc0acf52606765ffd79078de433ba8d477a751c0ff55bbcbbc249e82e840cbc0323c88fd3766772c95fc915d043882d6fcbdd2d96b66120c45dd59785951819bc5d797bbfd014c33b468fb65e01162fead56651586dcafd6e5935a42bb63f88b71397de7ed0fa42868259b1b0395ad25a010be1260f870cc223e2dc1244509425130ce6c9c0ffec4976669d086efb8ec9f2c7d4e9f593a6524c86a7e03a8d4cdf2221e11b8272396125f54b699a6ac6ce620b37134a7775bd7586a2420c79eba4ec5a9646d92ec531c9354bb66a5e5aa68f0cfffeb19e1316c2afd88d85321797d10c9d35d92cd2a158ddc826c9020d6a8fcbc650ddcac2a0d0bf4f27eb6ffd5b6d2d04b43caf02ca6cd5d5a83473098857e35c3f7a30b9e9b2bef1c70ce0f1689e4616fadb165ceaa162950ad35ce0a88eb7d0404d1c20ca9eb760473bb3c6c9c660984cd7285ae305e115ba8772688f83e679d8256e3bd89e6767fbc5ed796cb3d2a2f9beee4b28c7e8d15d2f11636d0448ec0603f460d26c1bbf253c423b6cfcbe4c76af0c0eb87f5cd71cee1cf1af9677f48367d7c3eae0510cb12cf080525f9dfae0dd72140bdf8958f72f53a4e7d9356195c29e73ac5fda01d2c2367f6dd08852cad32b2b863b6ce5275fe43b6ac68d68847fd61128eedada207a31c62a2de3a67a67a88e78b4fe1e2315500db084d7daf762a946440df8e92454d77eb42820bcfa868031447a6988700635c44c85dd5680da35e074f27a0be81ac2a0b73e931f4bb65fd08d2f93a662f81c349f5e73c12cb70e20ba408a283cbab23c8012c2dc06b9024822fd62a9692097b548c2adfb2017618dfeed0e170a807a6cd6643797700f1735fed354897f255f0f77457cdbfb0da0eb56893cfb15925529332c2ff772d309c8363c4913ed6e15cd195b79ed29a8e2f39f268c2aa2194020be1e3ed6684743664a28f8e6da09bc3b9348697373e96d977baf076c16678b9203253462c95bd202b6a98f11fe5d5a4279795a82aa9041f79cc9a3489fcb3dd22f6c2152fd5ace13313b4a3bd6cd5755527ead098f9910898b1ec3fa52d4711ea892960abe7c87563b4e7933ce5bf029bcd87844ca985583487b9a4cc4bd5725097d1578ac2fb7faacbdd27cb9bd484ef6b25de6963fe0f37ee3792d3b61891375c143dc5e51dfaa98dc56e2595839080888807fb404d63f05e6c2c48745c74890075a5b37408494dbfc100a158d780b2a45a406d9a33f55c3ce8239ee3c31abf5926fd638c36cb66ad7ad82afda3f0b1cab6066750d16ec8a2b97692c0694c4afca6e5af4647bb0e965c430a48d0742d549046f3001d24b1cbd115266634b40daf0ba38689c1312f4c2111e0c86892904d77c2076236fe314e9bc4a80635cecb776bbb624e6a8416375b579922bacc02f5416083507600f25d3b8ea8c47c8b289709da51e294edb810abc6f3640c8473ed377ece03277fdaa89d72aac3860d898898106cd61864e4ee5b8293049bc7b4cf93865e8d3ebe73f7a8b1818d51a94f864838b064f508919b9a5f2704c7f6d4e3ad535335d75fbaa4ba963acedff924f82ae85727eeb45dd0be6b37ef65f8ba582d90a443e7ad8315251750b69ff0a1999364e6d468b3babd5bbf2e76998f414df5ca74245397ec4b43afeefec4dcd4a14dcc8d81120f3254552be27dcfa4e8dd9ed1d98b5d4ce93ba793a8adf7cc8d63271414af75254fe9a0b5482514b297eef95bd1b4c2676e86170aa02965c0d5538888638ca03ceaaffbc369ed36b638c8933fb58f3f9cf64a53636ddfc6bd9badcec986b90908e88fb8ed070e43c27618fc48f421300fc4180fef3ec3aa136a315e48540424b79c7fc22970c373d209be83bca8c2ee8d13d215cd1dec0239d796db3ad46d43fb2199f2600d1661b8f298b7d990cfa8c3d0e1091092430591a2d80ebc9fed260770c34e445f8552f04978e3fb433a03aebe89193f6d46214aa4fa83ac50c5f9121ef57750f264725b68b00d7935aaa0925428dad3f52fa7490e9ff5eb6d82033c899aa1cda99130404edd1c070e27e6196204d7acae4dc88404bb9fa4ba159f53c5008487065452b51dcc5b4bea04bc7795df50b1fca4e78636864d5ef7eb83889fecafb7ac19538de1a50c7635185f4f54958440b4797fd9d2f641adbc995d398df30fa0db07e3bc78a3c3e8d8c3abdee15225af672e4a1127fde39b4af648d66179d5942d9319cffe38bb4acc5afa20d2c9053e794abf83d6f0429f623baba43f13d702a0f629d57fc5a7f5080ffc20ec386a83c6c4d947c4f8d70f62813f6bb7fe1d04e28a6b8d042c9a333eb09ccf1d55e4945b63036afe72bbd9f5024f5387a4da8fa8e07853e18c5499a999ccf71b50138024288bb6099cd40ee204236bc5cb5f68d058e380c78d93f4992f8c57e4217c6d25584efac07048d098b8bca00701813046bb7805bcdc041e956c0a0172eacac121e932df17ddb25c56d5c3836ac9feb2b9cb4fcb51374923afb29fdd6c249ddc129bfcee3b7b99579a216092fb015b40781239271f5d095152e8abec3637ae31b3909737cdd586a7705d12145d5cb0c58b53d0139f9c8573a89d0c240d414286666f9b48a21ce32b0f2af13824324fef385d3b4ac91e02c2a233147f6b419faff32b2b2f1d9346b6fdb582c35103e5bc809f4a6d9a123d360bc4d915a81ed2de0960823fa19481946cecd6d376d22984dfb47f0b2fec6120400fa606f7941a9b8053bae3e5608e6d77cae56cb27d85514feb8c1b8cab7e449b11ba373e40f3673e0ce8d43045ccca7d9b9d6d871debfcae995acbdd4ef5f2b1a93b575797aaaf9d6a670e83b5a9c9263cab72542adaca5cb5f337ac74953a4ab6162c529e6caaea6d58e8b401c7956e2c07c1f4f851dacff66053c593daf68bd09dc59a0b08b95b9e3ab091c77996644597fa911029d842d944097b8b0aa4fbfd0d9e4c41de11b90eaaade12ce522279ceaab8aa6c95887d5655ffd24ee0ce820b5154e170f1ee0192e709a57e9eb6efd7654434aa18e28a3a3f95732e2f1a01ec4ac2dfa60fdb55dad4c9d22bdae66d5d3bb53699915a41075066ffe6b56518adebd58ccd288ad1f7e54ca69c9e46a5704a1e482deb4432d1cf884cf5940951e834d5ea0067996c1957c2396c40829e395a883bb33af143a77b43e17c92b7f976f23a25fe54cb589d2f07e6f6e749008cfcda1b3df89a8f07d6d523892696c26d0c02352b91b0fdb876f1257cba14dcb27bd5279aa87dacfa30f3290d5bc19ec376ae85e300d07440d52a982be451c148892ac8ada68209dc7c6f44630d433a282ab570634bf05a8f23a831bc4ff519df5f4355331ddfee76c0516d06d58a4dcdf241f3186dc241c335bc7cc6e84983f039f564b19c6c26f0847dd4988d459f497d04a196e6cd3a7dae0bf41d0804389f8d0476581448b1e1443ddc6c1f5ac8c69b5b8044f519a043835d04ae8ad5d6a658ed43b8ed6ef1ae964d4948093ad77a4b35c403b2e07882f10a4782562aa5eb1887eac8159d675eeb621d16c1dab802990ff7c881bd42c4214e95ef480ce6418b13a0dc63e9f51af6780c569e4502854fb502003346f044d8022717305bc2112aa3ba3f4ead6a61eb5fd2834428e86e53bf6c852634f0bed3eef75971459fe84742979d45fde34a43f3cd16ac02d2582777946fb91fbc497aeec420c0e6d70d2df38d7ce464082ac8a9a65845bc55547109fc73b3e1f3e3408c5ac61740e3317142f1794248e3bee7a5779ce1d6b2211578f8d7ec8bff0d99d721733462d0850cf1f4630b6c5d75fa41500bbce26d30cea8b52ea8f723f052c849531a47cee23854c6184be59105437aa5be30b8633ff9814586cf5045017353c3102b922512eb138bc9e70c9039c6342a44cdac6feec44fb2a93251efb837f3a7d8905000c89e47f099bbfa0a054a7cfa6f2e90d8a5503f060665a00f03bd2dd9c4bd9702be6ee35b8c9f55d16e0ffa65120c0244cd11c5cac5b5d0e1e0f1a7d7f6087711997c314971d7ddbede2d7097c128cdec564f16e70afb4f25d3e4c3c9442077bdfba6514e9f34aec123cf25468ce1249f999456488979af22492ad9c92c951456495a5fa4b60c6c543283a72d1f09580198153954a0d75b2a8b6478680dc52742cd8978c272e7d5d6115a35f7e78b9b7db4ab11bc91a7aa78571ca3141f8c98b1398681b0341e95d1c4b60269e6d4599e3c48a082ab3d3cf55bdc547555099dd11b7fb33466a5c60938b29d6844f9a796078b9de520558a80a7078668bdf55cd803125e87d4e0af7705d3026999a661e7da9d1e6c0c82e8b75124440a2f51afc3729ddda508f3959ecadd32f1f1e0b363f0aec9eacf0c9b82ed0bab7702bc58a7f3e7fb595d655e8bdf95a92d8935455faf4edd35fb7569ea1e6880f506f69b1417a0eac07dae65328afdcf5987c603853ccfcd30f70bbcc8c714ca49064bf5de03040e86372f0b1c04f4d6a2e255b8aba32464aa7b3aa966aa8beb94bf14f50446d5532f0a8e2f79209d2f74491602d07a8b9fcd332ed60a631b976b12c8b1c1e95437c84e8b2071f4d008ce9538089c04dc6ba50c0ff8f574d6e5128af44942f6b8034462aa5d88bc6ece6598ff0720fdc776a5ab9cd22606a11f6968ab70ec3dcc5ae74df972993124a3da9d2c698fa4e90543af8f8a50da5d32fbca3e45dde531da507868b4ef114a91147e08eb5525c4bd574fb3c1615ace09178e0eca613f9cac153c4a6f008f8c46dcca3bb2943900da204062a6ffdf97d5d78467b5ce92e6e69e286dba251a1f9d8adf35e40efa4bb0f73bc2d7b4277f19e6d55f37c60ecb6c5d3bffd6befac9abc62fdd7b2916ea5c1cfb117d7b862154623ca46a1beb88d0013ed3ac327ae9ddc934c248f5c87fa9a08029515e8defac549b8cd8f70da1162dca99c6c7402d6e211fb15c95cc54a4639e499e1ea532b6c9384afe6a3e0d93c858484f55529d903ec988ffba2b0832048c930997290076a47247844bc42dde25fda625622db9810ac82d305517fb4a930701a17b18d94ee64bbb049aaf38f76d8028dd125a3cb365036bf4648e9e3253affcf31c76eefb18b512e7d3afe29f172126e20fbda5b0baa4d0a8d9e4b58b4ef83c4e3d6e279ac493a4f5e413ce1ef3c49179d2d85d4e6082268f767542c168322741f604150d3cd1e1c32add9ede1feed2479c299e389619acb8e5daa2cc55f4c272cf3016a91a5ea07d972a7a81888935ba55d0de09013dea3ac813d68003645a015267143c210d81d47393cc4d7e8c50649f3069588f1e869dd9d5b020ad23a70543248d3c2d2a0ebae9debcbc607ab3ab76d7862ba74d35b3758ea09a3856349f801a31c3f2a143b7599b4cea236cc2c5e26a70d062f952ec54a480e04bb2e7a88c6988a6d98cf84c1a841660bda00586033f3bce95e3c64df9607e335b267e5b96a39f2e2fc6653df06385a20441ae11c68ae8237523f97c9d0e9eb97cb5d964346f3c4ff45402ae2e11f580b32969499d8a57b408427149390dddbbf177b62bd0083d7c06113d688b52805eaecff34b7ca0e16050855b00d4814e44e31a854fef4c926e6a8bf532d7f6f2b613c1c150afd0fc50ebcd46958d4b041b8829ae0cab8c0ed5df3182e9742c3e43d0a0843af1c5a01f1da91b9d03fd6b5c227124cf75721e78b80761169fa5d030d85d4529013d30e98b6dd6bd7bcfeac92e7bf8d426f2aa366cc0d75c955ab19906fd7a5cf2328949c3a548192ed60797beb391f42bab84e01da6ec3ffe7910620b430caf6593ad9bc180661067c7d498725dd79b352b6396fc84a5f9e992a0013ad38e66e158b8a83681e89f25e624f5883cb73a9e1f4ba57eae008fdc2acdff2e7b40cea342791a9f06bba9613626761deb98bf507d6272e902dfbe918c6d4ae3815bb701c154b0fad6a427d141c250ca88f13d5baf1d2ad899082447fba1f2caf469d4802f3f9e215dd39017510bfd3bf1e9b1ad2e2409c5c9e3fe8406d984c7477fea0bb0b3f06f07654981ede07e06ebcd5373635f551999f4e211b8e0c92e8cf88eca51bf279fbb2f55aa68c9013935055843c282cc1c616bbdd88b4deffe2b1d631799029893eae0d55a2cdd04935e01c0fb110b5118fd7713e6ea1206227db92f08d15b6226e82274de948e255d3df456ce60de6427934a155742f70f35211026cc8f514429abde842b1d39834dd1559db308f34e5eb2935051e7842932ef31e6a18a12d8e0aefdfc459651de0b274cbb744e54eface36d20c135284ce6ae7dab8d031cb91263681613e440c18a4bf90d61f480882ddcabe71f9833a201ea64a3416132f6fef2dc223cca27cd0ba9f4cbf87823d888d2bf61a1bd36711393a1c5bf68e4f491fcdc8954cb67c9f7ce574fc25c74838cad149dda51203e5f71f1bb5bc985d5d99b9da29284e86446e5025acef3e6e419a81a2656421ed7b8ec16d472ee08c0162b27497fd2249f3c87448b849d5cb325ad5e826ea30a8b2c67d4d528f06c3db522cb650bac639d6825b3e3072fc97015b7a22c28b202f7cae5545f7b647d69161fa23657ff9baff5055fbf727bab5cc5a344d7a1b55861ff7fb0a1e83a50a06bfb19f8a3715450639885b900682b18a61b162088cfd19055fe4e2658320dbcf73e7432523bae3ae5fac072b7703e8ee44d41653f36ecbd88483e5929d06190b88227e056e7aa4497467ca1612f4b008d56b5e58d11e85f5405891942974c23099e2c1cbdf0bdf94e6a7be66352716ddaa729b3232a1e28865d37375367450db37c7b07118d06b391ee64d08532ce00c99752705281eb0d4e871311d32512fe1bea160f8081badf70deb5908cbd642afe6593b8174fc75e2615fd0298b8177ca8aecd818237f1000e3243b332a8ea00739ba4cc6bee385e01cb32a85f984b1c30d5ab8a50ba5aa729215c792117166d8000083f3814e3b2b20ed7cc3759c4d635e93cdb9874b673a8c4923aca99927fc46c76db120cbdf4642dd99ae374a0054ad0950eb6db299c3e11923ef284ff56b60b95b819e16edbba153983f601013bff1040dfee13a5ac8cb5d85f10f898a0cff160f4fc4d6307b140130649e7a9695660c7c4fdaaf6449a896605570f6890f97fba6698091433bba775819a2c745f9210938ecede708ceee74145ba90bf2a4890cd1922929e74e833d1f3d75e2270800cf9b255422c58028df9ea48be8f270bb81ea31560018cc8e1148733a7b206efa1fe69c1ef1fc5573b600eef6aad7c22557b1a580e091f0de4f00321de7ede1e652fbf98c79060365dfd6a78f4b12409727c4244a5511303c740d28c535b0dd013c8d808bde195ebaa362e3d4e5dd8b692b63501647fa453a9ba2fa1d916b62d6f649ff1d7c8e2b2915f87a9dcb42fc6ec054fa02693980bb6353c01d6735aa8c3b0f03fc42b7ce80c85bc49b3212fa406b9a257c789364fe55600fc6dbe6b268652f452cb21474b62c0a11b1492ca93aba43dd6d8d1042c68c69224ea3ec5b868c4414e28462d2b7ff72e631cd7d0ffa09c70626a9b03ac0c2d960a002d710d0c714910aa4d42981ce748ed9617f63097842c40ebb153ada79844bcf47e13b8918b39b79f6d57b296a661c07e3e08cd0de43c3cfc22d60d0722c1b8578212829de8d4f303f8d8ae66b364e22bf1f2110934b136efbec870b07a23beb4577a7b8b85baeb69e82d90f6155162c923e4311defc712f4bcdc29739e1753008a72db9f9d43786100801f7230302d3219ff20e2d7cfce62421a4382e6e7596f0c019d0206968c725a43c669cc297ea8fa93b33804455ae00122b3e08a0c2c3e384d7830027b20f42abd46fe5d84003cd9fa710b69a032103cd556258406b8dd5ab2d49dc41a4827754f02a82ca29f3c8729eb5c9c9eec9b06f032653b7c0c86b2003e3208654f1d5c32597c6e894e12b68a619cb304b158b6a7f0d61a1e17947e320694ba1d0e677267400c007e9556390069e0268dcc0ea4bfb1666021dffee4a6f849b903bb9cdf7424fe21fa50a1d47bfb9386cd103c4d21d4ab506ebd998f5cd0a2818f01f70168937c366803aab74a580d1b67fe647d8983f44eb2bdde80276d9a103c22df04976fdf04289ea64014927c13d413a0bfafceaea14ff147eac85cefbfe673e1f7c99692e0f425c956cec1212bece07605da465e629a282e36641848284e488f98fd9e2441ec0a20eb079d74de51b2e1d317aebf154c3295023436f97736f9a5c23f51466aed6efed7ac1652b9c999ed38459fe77658024018b4fd8fbc7de7a3cb9e7a6f14dd287262ebd80983be631ae66dfe777a247408979cb653c973031fd96ff8cc76bb8fac9b7c66bfe523dbedbeb26ef399fd860fb1ddd857acdbf964bfc527dbed7db36ee59bfd26df6c37f6cdba99cfecb77c64bbd957d64dbeb3dff295ed769f59b7f918fb2d5f61bbb16fd6ed7cb3dfe493edf6be59b7f2cd7e936fb61bfb66ddcc67f65b3eb2ddec2beb26dfd96ff9ca76bb4fb06ef30df61b3eb3ddd827eb663ed96ff0cd76739facdbf966bfc537dbcd7db26ee42bfb2ddfd96ef7997593cf29b514254477047a92efb15a309a554d074d406a116f1a9f15d4dd3c30f965e982125fecf07d48b853dd9dbb38e23dc8a1772195cce338fe037a3385a100087803cb8eb22bbdccaa40f7143b2cc58a69387787968a53ae453b58c428bbeddd6d4bb9b79429c9350b0e0b3f0b34dd8bacc988643a3159ad8b5d890fac005fd7894422db69d5969844137a3d8b46234d1b795974d2dd10fe492ae154ff47ae99c68d3adaddddad694d37c9bd74b1887e41ebf44deceede52baeaa978383a9f6ae87ef435dd8f708f22db9f708f147ca22f7a93ef7ec335f63ddcc3844f1aae41f4267fa2b846f426ff7dc99f6abe2ff9ef4d2eca975cd2af94dec565f9bf2d5f51dea6f4a4aeb37155a2f219cbb7a07cf7d6c5fdc16adb91504a272d2c7175c262e3bd7d9b9237f99347d3bd89f54e1e8d8de8bfad521f7aab524a2965a66df513c10ce0a25351d9b6ec82dee8c293c9de8587c333d7d27d978abeef9016b8126db5e246425ff49f2633adca2c7ff74445d77bd1dbd0fd877d7cdfbd08fb2852f3e1138de84f271b5e62b1faf0897ec9c755f73e44f844f1a986efeddb20fa12eca3e4456fb18f2235252f7a1ff63fda7925374a94157dabae24d2efea98301b73a435fed8b66ddbb6ad6a32431d00b7b4dc7b5ff80b180088007899e10343800060c0b0e101084000b447c9f8442822e1505de8b90174048804d0b47a92c306ead82e45dadbf0f883e3388ee3b84dabd1078a8e7301c1010c60002e9dbb3cd58920fb732e5dc893c981c696b8f8ee6d56defbe875dff221f0b8964b7a963b7a17b7f42b17e553eec9ab5cd3d3d293de06e547dff74423127d2d2e6e5cadc47cc2363621f8617a1b9bd2db905ef436286f33faef8a62a420892add937b831257a3b8fa7eb0563089f21fdc3057914ab0bd8506430335173a0b201fb23f17a37b892fb5d66a824bec0f0d1add77e3ea009e8cfc037838fc6e395adaddcdcd98e1c9c89fe1e1f09cbdc83397eaea1dd2fd775bbffa9ede0edc0ed8bce14662f3c3af3e1c25aaf5ab0e7b320d8bc2c6dcbdf7a1c380a68835a4101dd63131ca681cbae4264487424cc9772fd387857e85eccfa5ec7c4ed5896e5c713011a6a528aeb6db0d04049435476bad0e7358ad34ba449729bd0e8c2efd283f42de811827f2a1408e96fedd111d0e7872f60c0108742a6b5bd6841c4ecc64d95fbc7fd83a598e0981991c1dd3ad96f1028156a5bc5b1d23f269193a64aa551ae856b7d369a0d311f9744c8744b4c10f443e37ba1c9f9dab6f26136cd838aeac93d666b2bc96378e54b1602d48a2fc6bb5d664fad78228abf51f52577b2dcf3559ddae7ec2a6e4b884911e72cd9187053ed01b8a2355ff5a901483bda708c4d58fd52aae5a3eb42c342f1ec6ff7cd9ad0555158cb18d74f9200957662ea59430b094b89bb0d98b96fbf10a3a5262da358aaab88a56be8c22267a75395d4e4caa341f89ea912a1af3583f4140740706e6a5f39159ccfcf830622a2e2184911c1f8c292eebe8980cbf4419ae8e997806bfe430c6b838e79c9ecc5c826dac0565300765066bf9d22fb146f61a78e9989996e15d8ed440ab3a1c64d7bbf180882efe1d0eda73e58ef1561065f808bc1618e10a1d5e4b0956e63fa97ce313ca77cefec59348a4d285f17f22fd2491be7148efa4064f2e5c60cdbec036ed0304232d552e1843663d1ba77beb6cd0e574e79e4c4b8ba60502b4201a34ca3f04558d23bb69d05e09bc5644f996a594120c5a500e1ba77122ca5ffb024ec768f6851684f3d1aaa81021ab7ce3a8a8f40bdc385a500de1d0bac0a1499a7e7a90256e1c2971dcbae8e1a8df38945138cc53df9fb84a874989e5be71a613168898cab400c2064af0256cd8389d23552d5df6cff22188e3b57ca2b8f05a2a380473e8b5fac669b8a0b02ddcb4f771f63f72e6e26356f977716b9763227d8c30b08dd401020c7ebeca378ece2a2ede86ab5c146b532453f90ee2a08beb05e160f62e3ee543172eb277f12e5ee56db8e7f2d4cafbbbf8d0bac891a8953f3db772bdd3f55a0efaab5c2f08af959d543e66e9c99c705b1595e7baf35a9e4b05b7ab0836f45a5ecb53a1c8c7158417c453de8b7ca4db17efdfad2e47aabc5ac2a195241c9ae20887353b420ab2f45a2c786a39da48eebfe93f81e1e4f45b1c9ab4a0ecdf72bd1b9e3ffc22914ff61c36ce0d7d276c23f9c5c5b7e5eff55a365a0b2e1276396106baa77a32d96b73ce99d10b3a188313f9b4a4400e07fd59be45e4e3a92e870231d542b85ea48a05eb6889bd74445a061411f055cb37122c471ad92e27eb72b2cfb41031354304fd59de7f061a44aa280b1ae5297a8208b260ca62f9b0d29cc6a131c0a1adec2db9eabb65f9f486aec0bbc184e55a6e5c4d25d896eb2bca92aab8f29bec1f1bcf24d8d06b65f772a44ae2782da9922d97eb26875e0ba7711a67ca0b3a188a62125320c9fe4d44136969c13d7658b160d1cf8adfa8e2889f2360feab0364ff10010688312f51867f7cec2b04644fbd44d09f092651451351fe522ed1839e9c23490f5ed9bfc691cc272c8da7e2122600cafe35392ae0aa58c3f6217c8aabaaf38323d40db33e9fd5f6f669628da69aac34d2fb27879f46aab6a75af65e4d0f1a5b7934def4b1e1cb4b18b2a7918e35cbdde88c623b5c247c6999b97c70e35a81163e383c6fa0c730e79c3f42b848187d68e68c33ba800e36f58ed53a3b38d441c69d9d238cc8fdad73c4cece0b387f0ec7d4ed995406a3aa00ddcd0f0350f13d89a07fb892b20efa830ec6140322e86fc324551c9e9128ff98182da3cb4ee22151fe349ba1dbad1a44177f793b27bae044171e34eb0faf29e7649a9649adbb5f6b2d935f983c4c203e7b82ec2fa5885146c1ca2a5ce4fe506a21bb26b539e5ccb2ec67266dcc1496f3ccb22ccbb2492d9dd3769e84ec1f66b9bf63ca9d7899df048ba0af421fa6e4a8cda935122c27af932ce79d57faf26e236bca3fbc4d741aad49fa83524a29a55b9c9aa6695dafa20c29a18fa10f5de418fab085bba1db327a5996652db54dde2d4b29a5bc9fbb25716a10559d84cfce9010285539e687a21c82790703628a0311f4e700113b3cd53088a07fdba079f48ea88b80e52c28fb4f617fac6ab0c008392fd62a8acce52999fda70dbd4df411222737ee5774f1e7e68e95d97d0b07bd63b99320e91ddb1f7663713d888d3c3758344caa7c8846f9f787f5c1ad61d9df8768956c4994ff01baaf38c8531ce21c7a1093e3c0d2a0bec07bdc8103c8a13bc1e1d09d68499544e228ff242e2b6eb0c0915be4d864f71944f60fe54e7609731009d6c75350784af6bcbc92c74197af10b629127adadd5a07b6a6b5d3e0badc48b024cb75d75b164d27ac84d97e9bc6198227f76f9e4cb7f7dddd33ace4fbbe32692f86dc524a19babe6a24d8913db11296fd252c871ed062c81aeb458beef1947f2a7eccd1d3c175f0894f33448975e8233136128efb56bedbdd5bca69043b1d2c820d6b0f117a6cd86522d8b0cb31cb328dd25ab76d864ce825c7e722c7759de7554a2b13b66ebe49897becb0a29e4cdd3cc4759f276a1aad95a91e0eefbecb362281c31839ca6ec75b6fa2930342b99fe6c6218f1c4ac1cb0b2f2fc078c46c4aeff82308213c26b8198215442092a312436099725482279689f00dc187c6107c66bcbcc8681e2003f000bdc48841009af803d453dd6509aa936380a000a88bded09cac52e50b4a0910068c17d36166123000240183f1dff26f6d585ff7f52b2ba7d75c0861c5642a59fb4345b19420d81ed36874525fde6482e16acdb28c04841fba23777ef6cce69c234fa6db76db6e4d7b4dcb3e23511433627f704a302124472598082287a2a02cdfe6a8c410b6c89c773240783237af6d1cce761cfe98b7c49301c2f3031bd29dbc53abb526d33f08bebc845506088fa7787cb20c909e2b03c4c7075606c8111ccbf2ad27e3324078a2e70fc4c7c198791c8c590608d7bd0c1023479cbe328fabe88ea3e4c72c03e4e5a9ce32408e3818330e67ce5c06488f8331cb00f191910162c4533f72cc9c1763890c901d07630ee94e06f292c19b813a960162c4c19845311190a7aa94fe1f4b0251701146487590b0ed73bae3d434c51a3b56eb810d692b3f6dc95a9db65ab495fb65f4929183fd317dc38fb35af63356ff380dffbe0d6b180c96b53a533c7168518043933509e5b8c40f62806130989bea8965316d96c56459786c037888740ff63310d6c7073b9845b0d90fcc4124496cafe4f420b837b1dd62b5727c63b5ea76ddc6c111ac87fd935e4551179f2bb9be6a02ec0767752513e63f38ab611d13c37f6855aa51fe3160313aa689c4c8fe44e8e8644abdc4b7f447b747af465f236afb931b236ab3a2e7aa27e37df5fafb95eda0073145fd073a1d4303ebc9ee4be422722c9320aa4200444c511b2eec560ab2bff76081585c5d0829f4cb5322cf3defb9684d0efa8a13eccc95a75f3d4ec37f5251abc96b8c43fefc2ff95007097e14acaf4821f79b5ed52455751581c4cd7b701f624a7b7f17414cd1f76ea20b911bd0325c24fa1299af3ed77161cd169748957d1cbc08588cc30676c8ddc71c0aeb0e796ea07387c3f91cf8912b8efaf2677b3594bc0df9b5791c8cb3f6ebc786ce62fd7fa4f1bcadf6d6af58c3e5cca468362c34dd86c142ced3f37a8542a1d0f6eed96dab0dc86494c450a131b54f1247f43c1195504212ac77c3a463655932aa1ff617b2b716b27715d93b0a237c52ab09c68d73e81c36eca75b52c41ace838a4a2874011d37cc39e79c1917edfcbad1edd5c98dab1bb60fa315d91fd6b2a785c459369e920de3320f47cd78c8c9dbf0ed75825f2f078fccd0e0298a73387869a0604b3e8c3e45b4ee0996767f81edfee67db87dc31cec9ffadb3f0edbff88de6bdd581125faed39d1ed1f244d5ff364b6dafdf3b9621d0e7af70622d85af235c7258ec0839ce5d05955933766cab5a4b8b38927d3afe6f194dbb8bb1c4c22c6380f51c612b186fb105dfca713ace7b05ffd22bd6a671e87dd068728579c452b4fe9c9d0ed3a0f3186bf8a4a2834336d659a52f5e39b3a66a675fa88998ea16919fefd92a8235ad54cf84d74d9bc1bad66c245d331bd827e49558fa0053ead586303a2c56a79b7a6136cad99571273763b774b46615d2da92a797fb9e3296e22b1a1bff7d0b1060fb186f623684741e6e110e56d8b1c3c870d93b9a76895f7d028ff50c8c44445a58368826dd79cc2967cd8ad6ddbb6927beaea96bbbb3993c993994fe9fbb71451e53cb01a86e2dd10658a9db595740ed692ef1c3aab63bc95bd61b186d3dbd9bdeceb05caedd198e01ebd2a993e568630ab717e1083bce1d03acb070b99e21b6aadb57eb75a2d99e5768b8b84ce72d6b6553a63267d445e8313562bd55245b9beaa284fba1ce94328d5b4914824934d79d34622915060a4dc5ea15c5f6da52795de744f3524d20e45e4ff5859a92291482491cda6a6d5d72a0eb9f78751c22f8d6d945ee28ad68a927dd1083396d5f4b32c3631637fa026f93f9f23e42f8a0c039d2872d7c0e78af2d703a3857807216b0b67b8b395593f9efafa1b6b94b2073fa3a0a0905e9e92524af922553a26e9fac8f61d427a94dbaa28b807ca97e427ca265c96dde8ef3ee334ca6d9934bb93e84dff6345baa7ed3b9764ffbe1c8a28ffd0f77d15046b50507ebb35a42fe11ea5273d67ba33a54b63fa143c93954a9f8269b2acf425992cdb349156a2cd1229925b6dd9776bed8fb29e6f82a2dd1cb26b7dc8a1b3cd74d8912793b98ce49efcee861998df1acd2657229164b32a13f5d5ac8e79a94cb40a028df26fd64bc7e8b03fc88e747de503ab32515f11e51e0e914e74814174f1b73fb42a36ca751065b0a4aa63b0032b64ff0c094b29a5ee45c057cdea810d6babb66ab5d664fa7afae78b6659966519cdad12d31f0600e7120a0a0a8ac4d286a7ba717323ee7b45ca3373a4ce744bab944bba36a43771a2ed7eb1af8ae8e229aff22a29b8c61f2bd3fda21069f893ae0d02c26f0ad9ff8797af0a31822627339bb809825084555c91de4d6f2add534da994624a4949f97c52de6432a5e00ff6fd7c3d9f4f0cd5d6d7d30aa2a40b5916a5b47370db88e47e1939b7ac106675b80473d1c196acb6566b5fdc482442b971a5f52aae4637fc80c2cf0a5b1d71de0cdf75063a43e3c70500b93fc6189a7d2ca12880f42bd2cb8af4614b8ed8065004256792524a1b9ea22f0efa7f0cc52fa61b5748582aa5fcdabd225d1b9b1f7e65fa1f5e56a44ff968e9a7dc5e41a4111110b60b62348084014e6c30ec18641a94eec954fa1f2bae742debda9644954a6fc296854ffd5d7a947baa313dca9bb045c1a7263d0937ab5b8d851813a3651c21cacfc22f0b26179114ab8bd2af2f9ee852871051feda7cd521c4ca136b74745171488a13875e0eebabbbabd6dd2ca979e8b96d1cf4feace520ab6dea4ba234dc2ddc2cdb2af728222ae695144888a8984d727d49d5d7d3b5be5ecd7abd582fd187d54a1c313a01b9df1790fbc30264ffdaaa35b4190e5d64a979cbe056bace9e73d1f54a8742b2d6868373e610467619f99563e9a28743d33ef43d7c8461880956a557ac61f3c9847b989ef43f56dc77d166ff9eccfcd2f5517a920d29431e411907ed431ff208caa1faea71aa4979d2a7e010fc58999ef4a6af506c419e0a65fffa92aad3d7949754d55aad35994eaf52bf9eda42b92794ffb1e24c57c7dd2151a657c13af0a9bfba4c9f724f352a9ff22a78c7a96f7024ead4b8065f99de846bcb25513d88de1136fc7a5ad9ffebf98ec41a9dbdcebcc893e9ef19a9b2b50487d5e2d0e25aadb52cef6d78d8ac57f68cb061b39a6593c399b7ef42daca9bf699e8c64cba71a5956e0e2f26aab04261e590e5f0eb7191bbbea24b12d1a5f6485455a2417f9fca44cb9852d8b0bebabed9b7273f149760832c3bd7577dd54a35fac596d16f714edc8623b808239c5a05e2322929f90163a30706043c9c87a79a0582986a1f7c88a9061241ef161021b2bfb72b82fe43bcdfee90ee69f7da1dd2b2ab26a28538ca3bec2e89f2771c9f26b6a4c45a5b824f1d691cf4b73747f499f2d4f7d46f5fab55ab2c2a292d5eb7e24285c54ba99aa669a33ad2eae8694edff7543fe61e695ccbf7dd25bdb7ddceb17befbb467d7f4741ab7a8705b95f31c8fe5c773e3d3d477ab41a4417f7c1cb8b882dd73ecb2df9f6b2cff0a9ba2bd6d8dedf4f10552ec5b6b9b60dcbd0ce97c8af085aad8e14204240dd34aafabe3bced43a992945eb91e86d426f53ff07bb3231f91fecea446d0b4b4742299db49cb06cf4a31f6dfae5d0ee8ede5eef516ec993eef72777e54b57e55946f274e3ca849bddcc3abf7197bb3c4896651e8d3933d4aa2bef4fb76557a337b9363fbcac46dfb22befa3b781894f9a8f2235a62f791f296ff2dff561fa92876d80cae4407fc332f57338699866d4394420ae6c565ee5253e696fc3f725cf79f77fac46dd7b4fdfc33d8a505c63ffe21ea6b77ffa1f2bee246a2c1ac8a93b75d126a23787196411219e18431e227a1b3e5611f93b14e9ef6fe9be17ddc71a1badda2be0fbf045f4b1891de421de3b2a74211ef6208e729b22dbdbfc6057ddff5057f4dda6f5b2eafe07bb12bd07c09be0de841622a6ba891e07bd7522d844eb48877dff43f435f645df2fc23d8a34ae11fd877bf8f8def351c487e8bb1fd59a1c964bbe615275ea37f91ffbdfdb207a13ecc3e445ff611f456a4cb00fefbf17e153f7e8e143f4dd17a9f1fe7b6b3fae4c2ee8302fc725768062e0c99cfa6b44df7dcdf71eae41f4dddb20face6134fb3b9054b5f7411ed4cafe4ec441ea3cfef21ecd612e240c26515ffa50b66e5c9d284caa70324cc3aee3398d443aecc7693891ecaf79fdd1a3b16f3587dd9cecaf9daee85ddc8fe21c4eb7c3a776713d7c6aae393985ad37374280fae52f98bf5e5e839def1691d304eb3939d097f8d4de142e4574719fa251b111108a9a46e8546451deb0c3a4b01a17bd537b1c50a937aeb895db2bed7254e36cd757d8c8230411b9a3131c8927e9240cc87dceb975f5e459aee94b97a4724db4db79e5f62aa32196eac9d054d28f566c4c0223b03fc3533e03c653a10cb9fb252631862dbcbc4c17c7cd23b683e0a29d370e0ae9eee207451b1570dc17ad757094edc857963c39c6bcc2c523366c9d1cbb09db1ffac88d63d64274393be9c97495e97078e6a226bda7092645c2fadb90f1060794b39642361dd953caec7615dc27e1706712e6adb90f264f350fefb94d246c46ebf470388f2d42ed03cbe460f798667898326f2f87ce7256f70e6cd83dfdac268a1051b9a330f21950e44ab52da46da1d0d63d5a4e4ecee659d3344dd336daddad3df564b2a71e0e8fc51adedd7758aee4b07bac10852883b630b7d6e6e2beef16444e105b4beb2cf3cce1d6b2c10e66ce0d622a073195f56bf60fb2f360c38e754cd26ac33b676bcd8a43bbb5e6a473ce596bad1c9e546a5b7b72468977784a3e4ce2d8ac96f41e1af4f71f5a86fb673c78db6830122037de619a8913c814f3b459b5b59c04795381078945972a825490bb676eadeec15b6fbdf5d6dd940720b2ff3c41f6cf7c05d95f6381c1865b6b6b4955f7ccad956d2d6d6b75d6d3d33d714f4e4e4ece0d4dd3344d8b21f1a6e33f36a76182f993753713da472669193e4c68555f91f515cdca493ac681885a00a142f62f4497567f21aa5c073a41ae1334bb89ee6926b44f04c222680b4f698f844ba27ea4ea7bd313b1083589ec92b1ec6f847b4a621dc4980ed42c6b74c0e446b84af49e63e4a6fdd6ec3a8835faba8ee6471c7498c75c6261438f655a3f16eb719f1e97016380599e7886f4c1f61cc9fed3630ee4a0cc9144a48ecb1ba9fa4adee43d1c222ce5cde8ed871e64337a7baae1e44bbee6e44b4e70cdc99be01e271846a23c63d9d083b829a463bc350383f5341e327ae9ed50a4be7b32d4afe0b12b722cfa0aa2ca5930902d59031d78ec8a58e8e37bac63bc2726551d7445ab5a0c1ef39e8e7158074995b7185ae50e73c7095d3fc111ad8aed30883250d032982263774517ce5db1c6186ce8412d8574e72e4f0571d5f7a20f5d88142271b8af8ba2eb2b596b0d652e21d34f641456def878eacbee412279237bf28d490c1e947990f4a0301e61ba16d283642893a12c946d52249febbaaeebba8e0bd5cee3421e27eaa29779ddd4c24a6eca1b89e3345cf4f34a2161b0f5b99737380df3d96282c17e2ff24e35887e4271ea973827f7d49846c6955c826d58fb04dd93175dfb9cd7f5f5568e9ecca986ef4fbee6fb931ea3ffdee21e7df3363cd42d9744fdcd889e3c3dc13b8c34ae933798cbf545b777bc1c3a47d43bad2351bd933dcacd73407f681de4bef110d16f1edee1c345e617e9af9eccc4dcc8c1ce93995ad8cebe3d8efbbe5a49275d2b5d48be7773433d796d74e9e76e56b968b9b87de17a4641e946de0d5196b883b4b032871d2473aa61f4275f33fa137c5ad5f0684c53f2261f57ede55073f223dc434794a808c4d58e5bf3c7d5f7610c3ac145e8c795e8c31873234caec49137bee33a0ebaebc4ab495c5a481f661018628a1b434c8566509640a2e5bee4c9849e3345534b51e6f2301ec1d5de0defee760f7713b6fb2eb8c1c8202a79113e84eb4419feee8a72ce39a7bc913733f1c8fce9dca5075c8411bef87a7e88777d3d1d93a375246a8856fd11b0afe78fe89edc31f7892843aaae12570953647f2ce464548e495871d3c4d7f343bcabe48a414c3da5d28d54bdc9c7f6e4572e95743211294f3ad94f390eaab44cae6c0a926d724a1029415284c80f4bae1b63d971c92a825c71c945f1c3587658761e264ba51ba7f1a5205fb061a96b6795d2bf31072f10fdf0c6e805f214dd4a2e5a72d1922ba2fc29e6b67b81e88df553ada20c293da59f55fa38d4e730c7bdf6dce6c9681a57c2d6514d3d99edbf0be95715edc38affe761f463d5aa279365d905aadd6387b47e8582431fde984c48eb6ad71f5be9addfdea6793331d758435c53da925e96178b11969d0b74af152c372c379eeaae155cb0f3ff9b202287f20e3ce452165a0b161ad7cd7b93882e3e3f9bb0f2fbde57cc2c42586e58709cc67c969ded93c4b23f0c49c905abd54a16284a2e4fcdf72f0571d5ad22a2fcb520e47e81881291ecef37a605cbe196a016a00e873bb032fdf9610b90e7006765da37464b3725978333c8e2c0a7d0c7bc3da55f6d90961dcd0f4bae5210d34ae9a634b3b0d3648b1898c8848d951e151f152852704a392522a697e83d8bb88749d58d3912ac7c63586489596e24cabfd61b6b2b802e16b1c6f7fe2f703ce565ffdb85a86a69090a43765608b2bf0882a030376cc0744c4dcbb8d12a0b4428602cd09f4f4dc77c524419fe19e16b0213be227cb0af475e99e97ba6fd9eb979041b965c262ff59482946e4452cbf3880d5b92e479c48633727863428088b841445846b48cb866e09b5c3a82132d0dbdd079b1e3051bded70b9d178fa7b4f9e1c3f20b231cf4182c74635db021fc62e7850e1636bcaffc4227fbdf97bcaffbf266f05e08cebb1cf420afc3051bbe4be75d52f53029ff5df2df25ff5dd9ffb18835b6e0a9ad7b2eb499eb3e2cbd14d1c561d1c5e905bab187696f43763787fb3ad8f57a80f7da6b9e8c150fcb28ff30947b816e2c0bb15b4574f16f0192aa6b05cc8308b478d6dd42f60f5b826e2cba3c1207b560ffe7610e643ddcc2fa6b058c0b74630ece2cd80db3ec94587644225c62a995e566b2dc5c2baeb0ae92eb9bf0309620b0ec70b3de7c54f87eea4dc7bc8eaae4faa8d0aad210af537944177f7a31501a2202e9748c0742301491bdb6a0de50e1fbd111637e796a9094520ae9a4e5324a29a5767ee6c960c1f68d5d20eefb5e2b6eec02792a7e3f718bacb3b968eb18e1150a4f751f7424fb07c4f3fd18c92d969d8d95bdc2b2d79fec1fd6243596bd6291fd630dcafe758bec5f93d41f588582889ae3294984080773b25f961defdd93f14aba6e06a0ec3faa49acc99f480fab5074ff7df7289f0d92ec6f82adf89238e8a008088b56f6bf3157f6bfb1d0cf0fbf9f79e3a01596c3f7be1cfcf0beb27f57b34a6bad955a0765a8a30f932c4160d97958c7dc57cbd891aa1b0b42abee15f7f575dbb64dde124ee904d1c5ff5e51bac9af8e29c120ca884955090525192891bde4ba82ed9f392cb9ea1785e812850dbf9f2f49c98da744d9bfdea07cbdf1947c9a230f0bc4d057669e17919c16d21908d59b8a53fad0ad42ac60c37a83e3a9b843471576c32730c770f0fbf992f817f3cf8a20282ccc538d4fa28f39f4fed99bbc9c827db0dec458d73eb0ccd51b31646f0b77a7d97f6f85b8cac5af7c6889387d6889a87c688d48f9d01a317d684b1fda23d9bfb2a0552ef097c451fe2b56c4e06482c30f0b1ba87c5b14915282436be30393c5a10d4289128e8efa70688318e1fbe92cc2efe76546bd91aacfc361e57068bb9bde7ebe9fee100e6b28140aa1e05088b66810d34e4dde6c7a3e1c8c4312caa93ad588ea5385549cad67569c79c436e9e604e784887cc4862540d9bfa0bc45767b93bf240efa170b4b5c2e749280a4b45385ecaf7938b26c4546897553209a93c3180b632c8cb130c6e66c424a296fba6e965cd9ff3467c92555269fd20d119ed2f194114f45259eb0e29678b2fb4f5812927dfe2491c42687a59cec4878e5b06444765b72954af2c63cf573adf054a442f6ef3c1c591675b3091bda564bf925892efefd38e8fffd64ff7ebe1f9f1cc6d84da6392d1c7a93fbc318e4cafd39d9f38bd7c82720848b30b81b57b46b19ee44ab505a1c90563bd1a8ee919d9128a594b6288f6cd7312d1105cc8e5bb2772dc932f9efc36a4d1f825e0f8c097e29c15554c156b77244548d833c1cf43e494c379c186b2c725a5b645f410e3b9b4cc788bc84cfcb25ed6e79cae314a44bf64b7913a45b4034103f33371023e88049ee96a7227d79235df2660a2e1944decc106f07268ed1a5b50fbbe7c6671a5f9352c8d2257344947fad3df265e5cbd6b5d6da3ddd532be8e08bc4d9fccb011761847226f5d233a997998e69224488748c8d49d1b01fdb315dc51457b83254867e84e5e9c9342c38fc4cdfab0f0d0ee9c79f88c461f165629dde10d1dbf0ef29ad3a38e873d3b00edab66d5a96d1ec9b9e4c96f1f014e5e1a9897d02cdd761dbe616238da2f99d83f4a34a18318f1d116866d369b3584148927841547a1ca51aed51eeef62a4de4cccb4a5fc2dde996bb56939cc41240efec0c8ae1d0e6b584b8739ac71b0d031c24d26ebaa462c8ff791288278eea011d9838093e312392e018429b28cc71866af4396e9bc0ebbfef3e2a8960f635f265a9365decfeb483c87d3f0a797c6c11724f3656b97365f36fc42b5203fd8fe76ddd8962cce4b393a3498738666b49f73cef93de79c73ce9e5d3d9949bb9b1be28173865442ed27140a55ea3da51e5ef9cd35ed6384423224bb97ef3a24b6d8e7365f343aa796657366969a3c15fa95dca1ed433f3b73a13b7f7aa199983bb499be94a13b7377e8f656679d0e36c52142fed8dc2b4227f68aa61ed0148b3f96de1b1c94af63478f561021315610ae1b2d9bb03ca3023980b03a62d9cfa840f6970f235f60e49e53cb329f78dbe810fabddddddddddddd65c732a9c3b39759967d96452bba881f257cf8c9a1ca855e2ac7d5df91854e90ec2b7f2e545f66788d618d3072e728afd612d36f8f43fdd087f53b072b8e235abbd825b4eae0a953c5373cd3a7e1024474c186fbf1a187ec28d93f039e8a4ad824c9fe3b786cb48aec5f57a24b7ffd6df3ad7b1bbe3dfd51ac494238ce38e80d70d06d94ac4de734464ea33fb4b97621af3dccd9b11c67b42bd9edcfb28d06cd5d736dbabbbb94eeda7c29d3da9ca199a1b7e143b87ed73450fb0dc7d8b6a7946e927b29df871dd651f3859b54e2173066ad661e0d3fda4611606886b47e15faec75f874d47cef46f2e5ed979ec43d1367d43efb38739b72bd33343838b306ce489ffd6a0207399be18490524a29a594524a29a594eeee516621931f43ced064343828fbe5cff8a59142d348d9b265d3ccd0e0a0f46668c9d9d3304323db67a4aa57324f6ce382300ecef0f0e8e06940ec9130349eaa81c9622ccbfe1929a9cc9c05450cb286432b67a4cc268e40338801036303c6a5cb2a5b76d6dd2f2038036646c384f50809e68c624ad9ddddddadddc0c0bcbc80e0ffebb580ac65fbb5af95dea01c7fced7be25d46094e53293dd9c739a1e7ca9a396de5d7777e6915c842217e79c3f63482cb160c39a6b674738629672fe4966edea1b9c1c0a14d4ac6e69d9d4269d34964d392d9554c352caf8a212022ec9919e96c1c1e8608c247805cd178b08982612d4ae16d239d9d46052120a5d9d766492c146033c65f21df7f16fb880a7be8faf83a74a3e3e8fd1c380dc67860e57e5a071958e95a88229b9318227cf757b32df739d2773c9cfe8914b46389cf904bf985cf911cfb09f0887939f4387f47838281d94bfdd666930522501902b05b2f62693dc640dfd0c4f85b0fc972cd77f7961392867f478813183f4a497896f4f3c21448ea4cc82277b165064e72165e7d25dfacb29dd6d9669b2a7f48eee999c5366aed5a09d0b092d95daccb2a949eab54d9e9252d60f647f19b64b293f21f37938a8bd06c6cf46304712460c9be195888a3d4d0ec6fad97c4d7baa691aae33cb018c395f2c168b081839c6d46c20259e20f2382b43ccd6e9824df597e439810f4a8e49608144085424a10296631254f4e4f834c724a878e59804153ad9cb31092a70b296631254b0e026df50653892c1c0f683724a59a5479775661f4a69254a6229e5cb6fd91f763f65f4be813b5ae921180de5c74ab1751c2236ad641a920a1bbfaff0ff32ac39aa2a8bc562bd56f225cf8f2693c7daa6eea6ff4fb1189a2561f4f611c6414efb53add4dddddddddd9d6a9f23a746662ba23d3793e5adb929a5c1414f92b50ccb40833f8c54819b041d74f96d1dd4a13ea9f073041a6436455c7efc307b6dd299e18aa783f3e79c734eb74b500208405924c9028b4db67bcbf8028d6ae1e7ac356c4da36e6e5ed3c841ef9f1a36f5db78eb1436bebf7442d3b44ccb422193a812dfa3ca23ca77c89de18e2e3e43e739843a75b940a707297e5a7ee7ee3aab8c4a480194a39c990bfde74bc73878366fc5c17f661cfca73b8ebdb2367315bf724fdf86d06bd887f6a1a7d847911aed43ef833ef7da3dd150aa692fb158e5e000cfb1b7d37834b54ad49cdfeed1d8488f2d455fe93dc9a7bfbd0dda57eca3bef61bf651a4a6bef63eb6a717703074b93bb539ab444d1d3738386704d27eb84f21e244991f8ab2fc50cb305225b10e1c5bc3b165d01c5d950107357963b1b5d7116be0788a66ed7748957cd38ed5d162998df5be7b7f1a9b1070ef7d08ec771e3e65effd8f55874f99f7355c96658eda21519a0e076dac8f22d9fbb0cff5dbe7bec6e2537defe7739fe11a113ed5e0fdfc53c5351eb62fff54635fbec5f2bb87d9a87d474590b9d9b76df77145710df73d3cd1c7d5f44ef47bcce79e56a0b3f7547fc78abba78a6fc8e16da0c760459039d9d51b12416ee55a4590394aab883ed7dea906efb99f80f71c3e6d13e8feb4e1530ddcdbafe1def6f89e13bd08f710bdfd1fab7ab3ccb527b381193a6f1f81b82a891e4dc9d3abd192ab43fb4d7b4ac37d04e28ac33e8a6cef633e877dc8b734977ccdfc126c6f967fc335f26d96c1416d874469cf692fd2fed3bed3ded32c8d0e89d26c38a87dc5300e6a2fa1b0da7cee6be67335f24f15bf83dac71528519a85912a1d12a5bda6699a0ead06d7c95c644493d23debceb0a92d06256a4e6f396738f14b1412373afb4bd7625c9822a17c7f9896effed171c78cc3f93660bae5c3fc74196d48fce2a08d06782a87c42ea5945256a98269d94d7c214f18981f1f50982c7b181b59f63295b974e932cbb0766dc80003e3a94ccb1cc606f83036bc019ef21c0d03030303a3f5ec5942889e209b20170ff76e8f528bfafd40b9e3f52ca3b019caab18902427a2220aee9ccea94974222a568bf2190e6cd8399d236b95f2516e91d1099db13565176cd8ac2f6ef3d2e4701afd328799b321b6e4e96fef37e210ccd1f3e7fc36eb5b668743bbe1dede5bdb6f8fa269cfea56fc2468369b6d749be744e736110773700e336700cc71bb397aceadfb6e1b6172698ad8fa61f4c1f1523fc79b43479b5503514f205790bb7990319ab0322236b4a2ffbedf72f1db88a74438ec92dbd9643fdc461869819d6f778cf4782adcbc1a5534db7360c6818b32b2cf7ebe7cddc066dd3c334c1c263ed59fbfe153c53551a2c20c8039f4f249bf7d0887f33bd039f436e476b30fdd1e07bb5f0ef616e3acd34a54ef70b01fe5d2174f8e834dc4c10d742e096fc83aa0ec709087d3e8cf6c60c366d1542dab8125bd4855ca774dc158d650e86d48ff362277e73491febe436d2477f8dc69fe69d6e470436ccdf2bfe61a6bde681c6c4f862687a7bc39593f71980130c70f3d176f0e9a19d8f861f4a97130a2e6778ebc7d7b3834713846d40c79e46dc3331cec4a539323be16b7d7eac901f5e357dc610d807986832f2f336c1cec9a53f6396860bbd59fcdc0c62592e4e4b0593593acc98146ae5284254c1094c31af2844048965f5ffec440ad6e927599765e18e3abd393a978fe37fb398d3a87a7f700cfb5bead37ec727dfb9977a37ee8bfdbb924035d1e39cabf4d9eaad8e443216c9fabb6c1606be8fb4d6e8ca8925a82431e39f4dd96abb672af71cf85ba2eb37766e971f8e480efeb7fb8d34097b308725de674f0eed4381edd8d11e4de3d07cc1ce27ae4fadd9e0366ae788eb411b65fb0d6e913b80823c618638cd984e1604b9b2903a8a2a8c4ec3576512d19221100000080008314002028100a0784c231913c9364cd0714000c839e50705a1e08c42486614819621021ca00000180119091d1a401409c538e4fd34a50bbc3b6b127dfba2b7520f9169761a51f03e9c73ad7ea67910f9f736b30d999dfd8ad4b9229e52d0c920e9658cfc15f96bbfb8db6c0a0e0b3fd63146f48a01ae278447818292b6db70f0162451959e5daef8578f6a84c2552f2bc471c0a3e5e8ea3ba7819f22087d3ab900d2683e345231dd80f9b5c04af8e8065cdc08004d46ac106c7d38fddcc843e4699e845bf560e4d032e9f931b566098956c56faf5cb69776fc7b18bfd441f13379d50061b25687ae39ceb1eea6519000e36aaef5ddcc684bce8d39978016f61b168f9b5ac46c8cda59a1bac951d52d7d30906ebe4c466f31145c5e2cef6b7802a438175a33189a608eecf0ed3ad64bd865db9a5ccccd02571d9c7c991e0323edeac6547289484d23e3d5cfb615ddcf29800d655b7c4e654621d4141f41887a2c693dc297455e842c428f2ec56bdb5c743c2446aed8dc48c5ed67dffbc929e85d79a352cbd8e11c5a814339e1a821fcce7f3195591c18b802a608bbb61045e3ef110424dbd489d14a1102a6bf98408a096b3a97a793b2851e0ea78a8984a91254a1ff460012f8d5fe867b4e50d8d42586a8c99a1d77f3ada602e19ba1431ab57624c68232a1714c1b5c3f302e168096fe48961336f272bddfc82f28455a5d74aee20777f50d77db08abde70ae9c8045b6387c4de59ef10726999b3b26c2d2695cde388175b30789b254b57e6b5a6f9217d538d42b16b888fb886598b54f7fc0db13f02c313fa96569b89db08b2b069591d672d27d0641c57c3328af061219cdd7ac0a89196826bf5000929ad82382a6fba5a6b5ebed46d1145aacee5d1f0a3bfdbc2e96f98f3df14d498abdf4e2525db4aaf7c872f493ebad676a7a1bc679de8a8d6ab9634c68d3099f25000a0220e07c0033c85f711001fee710f69100da9c93deac5b47a36820b5c67f887902152bf8738c20d7f6009e026a670bcf9efcbfe4040fa1f996fb5933dbff674749305626625004ddaa32002aefe60dd5dd5bd4e24abf75cf6483618913a8a21752a3bf5da484e4eb70b270e72d43b2e1cbe075753a6d5bc131e690f905a00d8811f9047aa4b9fccf87db401b82303959250f1506e354490b1101af6754b262ede560f6494f417fb19204b5ffbeda0527f4ca7fd49b440bca24ebf62042f101707d3e84bee5e3222570237ea9bd5451afb7764856ecdc29becea92ff832b9aa3ef62ab21bf58495e6ff2f8777309bc5808a8b1e88b02973341c5403b5a570e03ba48d85493d3fd284b7344e676522c9520c24ab3253e60ab73570ae0309c3ebc817d006cd3e700eb472eea74051c57c715ea08d212a59d21c249a05b3ff51ce52b9dd6beaac0da9e60550751bc7769159bbeea300ea31c2a585104cc95e59c9c1f04dfacbbdf923f51471bb0512fe416adde136504b4a1755362f7cd1b3c86e3d63fb1c462c0c5e272b65a3373695c7fb3464cfd1c33aedd7636aa87f5fa30e83cc94c11283fc7ad9c19938562943d271982c8025af31dd5cdc72088a96aca042ae752bf5d6be969e48697ed615c70b80c8c8698791ed371ab8f6c42c55497401a4ac6bd342bc8fb543656c5d79855b6491bbb68375806d7e2b3ad30e6ec9ed9f1f1a8d83ffa04abc2e64ed7d32f5d87b681e9e8e3754374f13c466c8636b9ec6a7b5066a9931d0e9dff211c5ef01ebc400e8dbe3ec5111d93ee9c131cf7de04b4a4b81b50ea185f01547802109b3a6c63075c818087815eac5d608c772babb9a938eb2f6fbe5677e4f7c9712504b8edd8465480a0ff3035d6b1efae73ff72eb4eaf5c8de706b9b3bc9df83c4d287915cefce337514aacf763bb61999cd708962cb16ae113eb4b1ff6f06f697d5e940222b47a40c0462414a6f36f6cd4bb88d0ba16fd9843ad5f69f531cc4d0e8929fbb142435b446a0f6d554546365094b406c4075ac89fd54bfef2c9b46634ee41b5f01b19b58b30e154a874fce1c0cbdd69ed5be0a593bf52518d139bf4f64cd3a9c765cb972149c2f8e931bf5460f362d30ede15a739e52b0042dfb5239697264dd7d75d1ccefe175acbb67e6227ca27cee4fdaf2d211f6bbbb1e7dac15ccdbd50f8e0e0694732028e41f02998ca20ca8f064db312343e1e10ea7175bb7a155ba9029157e2cb3e472d8bfabeecf4522064dffe957c8252a1aef6921c7950e3e96a8f10d3c4af8275a77db7d9235296b62be26fbad5af57089941fa33ca7a46d58d92d24029f7c481eea97808e1fcf1beb68b3a81dff2a8978df7caf00c8b2ed78aa5a03925d8d59324da70554a6161aa0371e2db9d235225f979a96769d8bcfb2c2d06c6e9e4e735ac7c86a8c6e31f59b91f810d74361492d1611863f5fdc840f2f6ae566ba550bb37e35b96f594b11c7c1f8d0f7e4d18e3ad6e9471781906a82278475c1155975efe2462a3ceed46810344e4cbeaad50cc13288d3f89d87950bb5794f818718e9f3c3cd6eb41cef1895b86d73d1c5a1c6e86c3f8135bc87b577f56f63003d4b7d464ca5067d644f992e2bb2403a5c3f7e6a5af26bfcdd10e686a96be083ee09d32ccc0da56ad4e43983d1b7231ae1295c65ba4b703754030459996e6624914078e8fd88aa5c54d93d813a9ca18da7165d18321e9718691f9ed566494d72ec42ffc3e6fbe5dfb9d9e280bda4e3c98ff3c3c9b9a67cf636a5ceac618084977ce87e752d0c9768b50a2fa64214f2e84d388d86a10a7e6a7e9309cd074d2e8054a1dc6dd0117d893dc1d862dbbe2db176a4ed14b1aea4306abc522bc57122129ba590c58b62e850ca2cfb1dc3445e28e5b9671eb7fc3cbbbe6b5ef7a25b3a487ea88fa0f7ab71b0186a8fd620f9a0f03f27d4cf956ee2f728ab0c3d671dca7be0b7ae9193af0105afcbc541c42d941d0f9aac8d44a8b29b9a255956889ef057dc3cf9dd08ddb904ef0b0a52aca370d26363358408a7236c0b85f6adb3004678036fe9be934605c334224a6f01ec774d7c5939636864321b02ebc3aa4367b40257d8ca0a59801375840142dafc3a78ca910e3dca56d55efc6447edf8902d928bd778044be6efafa7fbcdb8e97689f3680bd17c7dd1cbe768bd49ed8c6ac6e346ae732d923a9c1134ee262b0ef6a09338ca6f232bfa8b97e2739b7809ae7f8ee31551606160719b50503663a8a0621bc65d5cd16e812bf9df937b35b8d550b693fd260120bd99dfca7b4a799318344b707aa66d3775a070de9725297e02019bb694c42cef09310b815009d07cf36bcf4935c975b2eb6b547980108f849686cccc61d9bc7be2aa6027ef27a32b0740ca2848359321c8d30b94f819e64da172ba178754f155d1ff651c6f07e3e655b043ceea9213e707c08c9ee575afd2b14e4c16af4c7acb6c6acd416a3c4d020de21b3e20d965e5823db3a97196096ddeb7ceddf1246de0fbd71d2bd0cfb11f1272bcfc903b66f5b0364efd74983a8e9018ac05328f5408e1859db62822f7a831b9700d63098fb2061bba1acfb9da892523b0d805110ca324809434c0d94510eb35f62bdb0e07328c79806cbb28108f4c6f576fa60b1e3ff4fa27e360f08ad90f930f71799ddeac1b48a217867780f93c20f669b157aeec5eaaa469f0a658fda7f28648ae300f2f547f2f6b3ac8e3ce206f4c43748e1f91ffdbe057c333ed0ef4af3399eff47162dd25a5c1019f1fb4ff17d193e410b38b791c3f0ed3281f88eb56ed0fda062939b9c2137960be2f1eefe4d6a700a3321872eb4b39ef3f6984a43fff14e2c51cbea5a235787bcf6293fce0eb4c091eb1ee88521da377ac097fdfa849113891467e5d4e8affcf9e15dd81a0ed20cef9aa2f02ba75d1e7dfbec3514e001fcbfd2877a3570a11fb8e98f9d6256aaf76400147b64fb4817731b5641370e56d203b97b3238407c1c7d400dfedafcf2bf078979ab3cc09e258616400f8ccfcf6e79448ccc4102813fb6e19122ab9107b8d52c569577db8ace46e47430eb7389a5d9c03a7999b5fd77e7ee7b2cc1060db4a3f0a586e43f1c81710f0a5582614f0a30496a33951323c8c25229444e2e5e893773b2688612cbebbf696dd565de4dc8fd4fe5fd96fd565d6a3aaaa23850732edac680900bd03d8d0c4832a028794ee00285468f69306e00851b0c83902d2fa9c93a1fef0e3d1b7eecfeac2e173f328ab833e76f942105eb44fa5dbd1fdce5f6c3e3571473b02504735fad524c7392d8c7909e7383a68e4855f1692237689367f8916382778b8bc1007b524cfc85fe594adc29c50a5f55093586e8652fcb7e322fad17482bc7e1bd43158f35825450ea8b18055789f43f1291f26209e4a10a02909ff15e80e6538e30c714fc37132008fd434d2398fd39abd5eb226b42dbac8e21d7dcc49abf84ed1038bbe0d7ddf039425309ab80a7b5ad0d46655ae345c7d850254d4119a8d8c4eaa46d31cf474e5b24f5a6281997721a36be096087ac8543227b09377bdf6b20c3d9b6cd3eb7d0fa4cf1bfb796e947f3a819928f257a68eb8102c84082c94bd5666d8c8297f2c5fe042c6949f3d1529cc960cd0fb8f8b3f9278049c870fe09f0f640e1e6eee2a671015044183e801904f87486d6a2a98df77428efbd4b8789cbef12ace75938ec2f77816d18692b239af32ec1f2807efe519aaa791a198337b72033cb70d5b7887ff192782d7b3328fcf12aa1990b59938554eb26574a064a0b9461cb596351dd5e8adfd22dff33f1eaf09470a0bd07b8057135cba50275c020ce1c18b881756eb16ec85389d44e02079adcf94342a67ce78ca2fdd770a8191e5f96c73ec3e39ef5b167fe58b392c777354c8452e69d02cf94e40769f80cf5b5bca414323601778daa1a9122051d1d7ab07adea81e8b8b68e707eef6425726975551035b8d7cb602a19f471e0f7df2ae1c0c3cc3600114d2eb0d7833f78b3b07c6bf34f6f3f5dcde21571ef1f9afb9528965cef500df9f1617f83b96e225fed813b9ba3656196c3ffb43fbe5fde9d96d3ec24fa5dd24a6f2340f7144911bd009d5e2fd317595fa855dc97adbfae61ac9f224530af3d0533077843de9026929fade32780970901511e6031f89537a52db9c8cf021f82d88e88c522de9f7442e96e357361054767aa5ceb9de9c1d45d90abfccdaa58b84d395a86c82167c9199caa4eed29ad5fcb698e4672416384fca9f81a0388efd1ca4e6061302fdceb26cf40ca04dd1559abcbc598c1e2d7a7070f1527995463da4797bb5c1587b151fc86d975b09c5b0559bc3f8298b8f3fb77079f12ebd6044f5d0a8dece53e76cecb8d4d037189bffaba1ecb55c0c38855d095ddfdce58b219983b9f65c3b53c2de31215f21145b17c54a6a3cd0b82ec51da1284dd34363085e2dcf81daaf43d7adfee03b21dc104a6c2c92f1521c8cfe5a1385e9744c6ebe75ea08465590ba9f994ed5a1c65f32971e764bb049fda33e0844328908a2ca2a74c1527af50c8ecf9c024caf0cf03ad209578b6af6534baad3e1cd0bb1e1ea4b95ea81b208371955445c6f40f64672c4d2f586925e4f036c252947a03bf9e42761f16bc2b8c5befa99f5e8572a0f4e5a8f9531c8644b25095efb19cdc72b5a7c989dc3258b5d022f2af4fa854fc9f297a6128f7a4baeae93a2436bfab13fbce4f7fa5faa54f312277a165e809126830083aed866b2f879a556164725f0c8f24713eb046ae7544ff9e8f620d92e678a6792b5d65823ddd3f6ebad97a6fe92002332dcd3051698c1ee77e82befb39240d9c8091dc47795705a22d26630aa84459caf24343a1c27b5af693aad18937a658dde74cb560a301bd421d569f8d08996186392bb90ca23ce4f62dd4dc9dc14a6f4165311ef7221e965ec9b5e959c2b2cb43b3d1c133f9bc1b0cf23377ad847c4bca6592a4cba1c4f5a1fc4475e522803597cded856b21a8cb93d82c4ead60538392a1b3b51bc93304d1fddd8e8251d99f82aa4d3af5102d59bb4d2c3bb1860e026c532e04f6bc793271c573b2c1c8cad06c4a180a4fbfbb74ef89f6911ba0796a13bcb50172eb54bb121bc7206f8f7ebce4c252bdc86e23ee8afcdc14486b227eff9f87af0c5a42eaf9d22efb56bc8f8830f0829f27ee440f66e9681c2baeb2eb800ce7fe65e66792c1f6a244093e7bbc9dadc8d168cbcce0b38d6b58828a00ec508b799357b9ded8ba2704d812e0c474dab67e167165a1acb3b108d17dde3e9d19342ee38660e683d21a481ab00372db569c87582e871acd6ccb980cba0971ef1c86c74395b49754b7bd0989b4db6b4b7d76adf57df85a2328f2048132038bb2ae524591dde18306a26dd5d12d1d91a3280f9c1e575b3a6c8375520e464823822533b211276ac5eef6ebdb7e9fb99986eec0da6665dbcc1f0efcd65b2fc0ba319e26c6ed5ae2bb591e58c751cbfc3f76a66c24821081426e91a7d1a6fda05b167f4c5461c3a656cdc7db1beffe2812ba03f8b519da317a5431a943038d84159677b83ba45b18b986499e7ba8a66bbd1469f6bb8d8be8d8b7de97e41af601ddd2d09326fe8e83ea1e5a6f141a6e374851775b8550f206cc1306d80473c4b8b1cbcc1d4f40b5f8b21c0c4a3c3764a47015ac320862e94c4e385a3620bbdb2d295e9c4d73804262cf77026183d334cb2cc756a96b425d25a423f20b6cc7571b98ec90fbd4ee22aae4af09a66dc1aaf233475ae54896b9956ab4683547f0f53b2209d700de04aa5c991b7135b8aa778d7216bfd64c1d76536292daa064e425d1733de242bff866d63a6661574350e480fbb524fb7323767ee426e5e7902912c845898491de03f6a4c8a80d73872f864378de7dddd1d4dae33a0b2ffe640ef99bb50c0d2ce2cb346a72a99cbf0c5d24a80c8ddd062bb0b9173d798ce30c93cdfc87e10301d0fcd6e076dd0d311c361466ddf6667de44c5c06db28d0269bdf0244944158e4846796c6f6d9ea5e9490fc23876a97067761f99355418f9629a8471e018ba1e52fcc01e280670dca8d9bc588faa992358a5e6d897dc792c6d690d87babade53c27bcc4e2a934147d48291395f8a810e245d25840dbdb746a86630411ce23515849f0dade316d14217027b87f251e0cc89593ece9295d3acbce5e9e1d3cb329ad6e30cb02139f700078124e22daff4d5d9f82445b28e88f7bd85c0f5140c10e4787e6c01849ade6b3912de58be4ec3e42afc92c514d58d2e9e42c3b3efd8639d7a5b71a2714fbf42d8da2b03c54e8669859e138361caa40f2fec4faf86fda1458a0e64d73bbc2bb75edbc83c5376083b3e00db6d8d037619cd32d3aa20f0e0582a076dd25acfe5476a16e5fbc2335fe21a017cf5e9706a13b3bd360d579d3f4e6be2380c02893cc4fa59e56b5bf00fe520b7a74aa615c60986fefa543bd14e020cc0336e8ad37808f19506020bd48c55991c713a8fdefe46dc1dc78786f596c156bf4de34dcef256ff048b3b6dd914d8bb238c0644e4bc5ffb1b09019db328842d007a4fce0ecf63525f161dd68cea823711098776158040d83710821edfbe6dcc7b08d39ae3adabf701071233c79fa365de3bcfa2122b86fa4038775cc5710b09cf66f5aad99ede510b967ea71b4bc38ca2a1eff60e14fb34f357df29fa25a74dce1e3f193c865f9e724fa896597f28209ea8e85547a7cd4611806b33abdf5b293336a80cfbc3417b30ac3220845973f5adb659cf0719001a1ec049301751abf8171f1c463bdd98605c1c02252fb4d9adc8187cc1881400315365fe38054390592d2c3f90e5391256c30ec1b4e6a55ef068ec6ad560d87f007c904cbf6e882af9911ac6a86c907b51a01e4557dffed2e98d34f48c62e6c3b204ac9a6f9754e405f8e5046f6f65b293c1496a98d71fc5ed97e0c22b52149c6a9d22198e698760149635b769bfd5f0e82eea076e540d46788a00dd87fa5caff558ebf304c57ad8ba0a3a81992840f0dcae35f0a12dff51652c434d40ba2011854901722308f8b446960e86ef71a9e37d99280d990507280de24852c9d8d9019bba45aa7e6da394559d5da489364e5102de8f4899c1d74e0b77f3a41d932fd8b98f201e2e564732da7f4689a13b0c27372931bf59b0b890d38d781b4e01cdce92f82dc42c7aa8cf77757aaa71f0a24dfb7c99eb495e5618c20b65fc31e649835b05ec9389622fd706f7a45bd66c3c05625211726bef01e028b5a3bfc21f13be598e6113c54f2daf637137419bcc5c6fd86970c22fa336b821ee7654422f24110cf811762b120b7f0f29eb13734fed41ad3dcca320782b138c42ebced4ae92e9ae36f2da94839b72116c0b16eb8ac6e510e7a64d10b67caf74ce091eec6ca5b78271b2e8bd142b0e57e87f122e6958bb689a5701b372f32f9b7a57fae435d59228c1aa25098e7925ef91305feac2dfbcc333fa4ba3c85aa013be6d8f4cab1ac0278f7c09ccbaf1fd25f295371a57ffb6b3c899198ccfd454625c9b0d41d2aa1e042b74a0d36b2d1675b8fef4696648e58f8074d42a122f8bf7cd754ee608abd8989cd4f4ddd57156ae871f93f2b54f8a177cfb8d57c16cdd0f64d6c1c95fddc64e94a9092cbd31064ed241b69612ad9b3ddb8d589f322796ee719cf6d7adfe89b5f1701bdc8da078a18d27f65588d733f86936468677f4746bdf834e343e19ac60720fa5276d4f4dce15e2332d36e907128d4dd40a1e2e2e579311ed748c30d440e1c3773677201e5f2fbd3647351a4b1a311fc0b80433a51f804852b7e4c094a3a42663ae19deafa75c40429bcdba1588953ab463134444b00a4a9947a4823482cca2e9c982ad6d09340f8d3182a93b400f781d60f49aeb3c5439bccdeb551b4bb51fdf96a97be6c76be123dd081602b161017c610ab31926cfe8303005db2984c23924d6a181572ddae420198ac4cf90c08fafa0a9c1faa9a4027fc0862b0d86ed9b4ff8e9b9a1b693434e3ea03befebb57714803fa94377353b5475e4c0f2904aed41d4d881ea7e35137d0fcf6a1118c6f624a7c4644da6a3ee3f2106591984684dceab147a393eaa3dd2f8b1dd9ac91b2c5b3869fe659ef2bb175d209567f9286fe50ec8db6ee6d3556d03c7aa0342355b9f034c201c2308ddd3955f33d0da2c677f79e5692e1b2a564022356443254f32eae48a1fb34921f576c7b07d9e1be2ab1c05a59d85a8fab38883f6248d9038b666df41c64008d2f7d10204a3698f5db836f23496d73f3f4e86a7be33d5acd8394384d46e0a5571205a2c9ab645cc90ef04de67a253c3f67a2543a5d24645ea11f26f6b1ff51a141ecd5cce8153fb1cddc57c7db40426fe2b193e3ab4de61b0e95afcac86a874c039f72ebd7a2a4d7a2c1e5ce307b355c0e7f3cbfbb578c154c5a97adf243f4b97559b34394cb65e983c70b23bd7e63627688ab5f4029eb6a0b04bc2fe61b82aa02fb71a26de1564da32dd9adb63e6effe2ab0e28063191cb258b950959e82df54c7fb55dd414b976f28a9ca1c64601acdb4aaa637e2453b51c60cdc1f1e71a1b1272b85aa876a2106496302a5ccf46e8da467e0b5e83f7f9d92639648c40c7ec3979f1f6a73eabd96fb29912872dcf0345df785d870d7e23eb74dda9d60c5428baac214a11e95c9f14eb4a9f6486203a76b305d7ebdeeb00480dc47ea8735c2e69d2458bb61a0913d3ba6bd794ac233040c38084b3a1ce64dd3064a1e0c1cf74a66d8f0d555d7699ecf8001ed6b35c972288a82ba1642efb649eb1f4321745dfa810b8b38b9fdc07fba3448c600499e7b61611b9e20f8a311cbe5bd1640a75a6fa99408ac650cb80fb76694cc6e3f1d2500bb95515eecdf495f31d05d305f764e51d6567f6f5edf52d6677efbec2825b357b1107ca8a6dde16bd524b5d3673386c656ad5b2b07d2fb80fb0e93f9f07e945c17238c76124364d35ddfb6cb49cb6160c253e601d28048469d84baa0ea0cda51c2c117cf53649d21bab6f31aa0e7623095e48636049cba977e3a343f55b8a4b8ce005a4db1fe54c7b0671a782689f8ecf6990cfdd5294f906fe4bc9488e76496dd907360f7ab362a494612766a829c150567e11d83a285a5340249c4b2fc112906569bf68c0e8304ae3110297cd5312063c59530d3f49052fe9e35aa5c1c717c493071871d736b91848206492670700b0c39923b50a6bfecb1225ba8b41a5edb1ae261080ec80f32cac76bd17d515a28142aa5c76e4302faecbbe8b59e781744cec7b538cc8a00e4f0eae243a5021531232021afe0ed3d7a5bbc3c6d74ad33315d791279e419627a160bd742b55b4d744aad9802d1a74d210df0390890b3eabcffd8452499305a58c746b19a4db2470188f786e3467ea6e1afe52d26571fcf0e24ae1ed28805ca763846e8bf28618ce7337a0e6cddcc56c253e7367e57f5121f9327045d182f4d47be9990c02b2ae509259b18b765d81fa07775f908c9623cc08dfce183a7acfe9eee317c844789e34b2b2412c26388b2e9f51bf0330b661790768f58791fb0ff57fc5b37946a6f560d4c6e5ba1f40e551d39602a1f7168d50613f37bd19704275204e149697032904e11d14a2b22025f5a75467dfad3db3c13146cd5c3fa9c4dc205b122c6694a5e33376ca81986258ba6d17965be518587ed8405ff30033ac9437f718538a267cde08c5f536d09d69976026698a0abb0a0e2bbeb46c31557b5d37aa2dc0c5eb6207d461f6fa84e83ad21b5513f52278c1eb9b3bd2f8eeb1fa86f79954807d90d7625e6131cd9f2f2e1cdacf682d9de50c85bfac5149de323f21441a859382f9e1fb482267d3af65dd24fed5af7a7636bc53707bad363b6ce4dbf917cb001f82481a5293653f39809b4749651ebe28f46aa26a9cfa0bf373a4d1918b16529687b95545529887d441eafd8b0ee69582b96783b2161b38382039689d90393070fb830b4cd10e790de069fbc6ee1218d8840dd8cea2b45a217e853402128b28c55159b4d42fa25c59b3b9ecc4c9168873fa7c27d99463d5c297328874b913c350310d6dc08897ba124981d3c5039c98ae53f0270599fa421f8e522b0a439907e66ba531b50626182d694f3ce0289116b1533a2643274f8ebdab330440ee7894a2638a455bc503d31e0c84b18c9a75a4d9b529a78c6dd841da4193f730871903b0987d22307191aeceb81bbde0d01f92de6a64167a2cf05d97f0629a19b6f4044d9818f5910d45ec4f5f72ca6b0c90a90c29e43ccbbb5fe8104ee3e62ec3e1e1fc8c73729966fafccc78baa62039f1061f34a8a70f84d1bca7cb39a31ed8f97300cf2edaaee7abb1c60da2ea86bee8d5a26e5da02942b00886b6a8c8c94d6b90cb6e5ef475d079e0acb1ff0aca0dcfefa08ff5861eb70ceb5b0b791892b32f2dc6e23aff888005176bb9060281b6c567ee862400f399caa0b4b047b49b4b7d2881cf7fc853af8a7ff602181df109136bd5988ef3f285efd6146d6bf624cb227a4bbfda0ce7511261c6324a78d2b6d06f531240697899319a06349284201cc68b2aa8703af509e0241db19ac3650ae0bb6de3f3b8308c5869c76800116695221415f2ed5cba7175d5c610a86b27d08513d92a4cec90cc4785ea87786eb47825c4cd65de6f659d7ef2ab1a8639dadbd3a835a87dfe77a19fac2d68181a7caca7afd00cb31eaf809a7c16edd4f5852b58b228697b21027bbfa511e704c88e61e45ea4c474d63fdb0036c1f909b1cfd6badd5e812bb1b53974ae18a46632ade290d9b5301e10c434ad3d5eada987cc3c72858135f5af6b258f291b2b552dece4e03e3d238fd0603ecaf0a4d40939b903154e82a20e968e1fe4778d74c30e0e1103d671f43b820675c3bd771f2cd644292caa86a017d419a590cfc83a0f10dd66aa80822a01180fb5b20720ab002562ca70a4a8adbdd8a996e7dbffb75da3782e38b7b46e90ae207043a7407fc5359929dc0773a29fad4d9005326225517469251f06bbc8054923d4a7bb82ea01fce2944bffec381956101da9cadb7edc8456a32c3dabfdd4fc211f6a5153d584ef3f78f618d43b71992b6d2fa1894a90478a4ccf0c6a7f348b64ba6a74779887a3b130cfeba03afe1586b9ec7b1c0d1efe53d6cbd20a3fdc689cdc1ec8d0b81c22d68048771af489ff86da96c6b8f4a278897120b59d4d8f4b8cb91f6ad6ce44d1d3ca081d092ef9215dea7788cfc40de471f0b8cda91f8ae520e0c00d8ecaf47c3c989390bd8550b7709c2092be7c704cfaa13856c6b10189bee932984e98e53504c7d57481e9b5facfc89586db6d512502c1ee49b09aaf0e20fb98b52e92f9e8a866320d88a38737d96923a928811d0f392d2179dc64373dc080dd399df1384dca5b8c97001ee009fd08c8694712d4b406627c7b8233ad522f4f032e685941f03d58fc080d77a74c7924bbe700e154bf17c232af4d20ba3eee5fee5496091bd074fc28471cc51068a769e1ff1de88629bcba3b8b023d4ee91c21fed6d0be10b843798d1ced0d560afdf1581109e3951c35092471661006da7c1c2d50c20b5c4392bc02c242c5b1e6670e1488c76d8b7c0a1bb938041194dc4976a1e908a047a21704bd500155bdf99b21266867b4e3e69dfdfe11798f24900f7b8ac824c8f1a733fe106ef457bd05d752668cfdfd112f7ae0bda0cd998a87f82d5e9ac39eee018ef99b7cc5749fa981058e849defde8fa23a1636540b0e2247104a0ba0ef1aac25f30e804eae07f812a5508526cc8f905e0953efbe0dbb5785fc59a26535381fb87ac6e1d32d89281e73d84c970d87b88955b34f1243b41c16454e9d405b54493c6e139c2b3d5505b274e702c389122ca1fbd4fd4a0e4db449d344e8d6946924024f3fc8c20953a1c58db71f52232b8e453a074a52fc178b394787efc9b0976ccdbea1dcc3c334dde68e5974c6301e105d22ac0bae09adbb188249f7a391c3017616cf5d6a0fa4a8fccbf49a2c2e5ddfd5d85bfb81c0d2ea49935e4b91dd2e80e4cf96d7470f75adcb25cd342556640ea68e817783c93723ddee99ea06a73a4af877e1a8f3d52d1577faf8fee518dbcc4e72fe4e200e8eb8fffeec9cd3d07ebfc1535ef3528330f3dfa6c044fce90d91d13c90e70ec105515a004a328d7e3334c50d303f799d5eb65dbb81e97db239d96e22bb33abe9d4657a10d358a6053d0543c7839054ab70db53608a1b75e3af758f4991e3af340a02ca388b65220183709b05c08eedc88c91069377df27c074b03470c097faf49dd6afb9a817540dc5a8f5430713f92d0f538e4267c6fa381b52aa32e9f31c9ad107ab8f6b8b674ed6c7c8fa27a6c0245a989112e1694f95b2d1a21eb15718432332c780f4933c803d6762a15981b1af152ddc01e0bc153c3c6e84fb41ff73673420a62fb8a4dc074369080507631a847459e78078711b59dcc8d77c04a89b41c0ce79b41f505a1bda012a1a56901db339ac544243cccf514a9346e1d0f163339b54294494ebc5886dca833e7a4fc9096a6a61047f8f4046766ad800b6e9985f34dad984a51d4de3727ea5c7f5934b71034a5b94e580954eafcccc32406d6cff208046b116c425c7b3532dda550ec76d7d1fdeb8b06e564c27878e2922cd57e0e6475e3922120728164c9d85ee0bccfbd11a1a8da3296cff80dc6284d796450dd16e7c3d24e40421d9acbb71ff8146cbd0291821bfcad44ef55ff84ce428b6cb5e43732d2b693e8aa4646027aef54606c6c8d78f1d3376f4dea1365025c71f87ed3b9cf07ae5b61b7dfd073f636761a2991afed92023a40cc5a632b0bd0fb24f5624d987fb9c24bb28245429c4d86bf08496566dc6d41d498a9b74887b848786b89c51059fe6e526d13c6961e97d31f8c794f7c3c69ad2b74e81d0ad9e4639dc4e3b7ee8e5c3712790e2f7412838b6d2c649d4c34e9bb13eed424bc0542f6cab86bdf0db84a12b1d08700b7880495a14508de655ff2840951db1487d4d304c36352e51a32622893c6fc700b2df1cc115694e5a98492697bbbbbdc994e4cee0edcc39b3e4fcfdc0f2e346f8335cbc6cf839ec020e7ac0b92501c2dacdb80aac8d61fd4907a9e1ea7266d2e502f5013792604e042a40f3c2161725e0a6677685d450449fa43a2bcc8d07c930887aa79270253fe3b6d756f2ff47197c61fdf1ee9b668279f3dbf50d5754e23e66c1d8ef32ab4e0132dc0e6b05f9e6affb4b2b3a6fe88902e0b82d9913682519c1381d951a6b2eb34b2337b1c7b7705b1b878aecb8d0c125ec767d79538466d5702381eba2562daadabbcdd8815731ddf7c568eb5b5dfe7fe6f7267415cb305b3a26a6c0448e610a67d610e842f27e7c0738c5e1ec2cbc5eed7e09ac89d1f0d5af7c78b20eee7e21a6f84ad1904227816bb582aaf28ed8f2dd3a1fb05f682560d14a26b376110d1b4ccf05366d89022450ca364ade04ae764a62e0c730166fb2c59667b4d63b3ac5e107881fb50457083bd4ec67edb2000378647830eaed637ac8cc641ac47ee7086fe63391443752177627cb17c4afc07f71d50b5d5d502b4118d212ef0d4285bbf1a8b496662f83abf1ec7f1bce7c174e39de78cbba13d0a78cf460be0c51e89412a1bb8719df4575b9103560b12d0c53fa5c24de91fa06d9351711df93aaeee68c75ea75a1151b136af0e57395321b641fe0e9352b990145ca5114529ac5a89975dc670955a7b819e9058b06b8c58b5261e6ffe703f21aef206dc1fd74a3033c81db48c9a34eb2a682283890771cf44c1458c53af17d5a0de28cbe2fc74134c7ef0db6d74c1760b638e0ed6a8e932db7d2fd895d030dcd1393bdf62a09c74fcbd1dde9a68ab5ecf9491e5b5bb0c8149ab95c67c56fc181d28d2505b05002ad28d92211baa5e871c2c9fc963455b3b4992d79aa8481a9d6ef525550762fd275a0e8b1ebcb230743e88272620a18f4290892f552b4acba650050f9c7d40293c0673a8f0194a551ef061bbc1c2d133a604689c48d10814398d20d3958e58e9019bce97b871f32b4d6f3b0475b301b355047783d397a487cc6b27d49a88c47f2d6034c9f279cd03303701cd865dfb766811fe40d617cea918ad4514a2e73361d84d8c841937131eea4bc1d75e59072dac3a389da995a68dab8222647b90bf7a2859409551a62fa38358b1f2aa62aa90a523803927979b29a5f009b72ea0d7d3584251f79bf0ef2ef96cc718667954127a1d31d36c8dfb02661c3b413e064ea0106b87adb554040afdec033aa0ef6a215813631d0598f7d7f2f6212ddd0c2d6391a9808aaf7f837c2ad213f90224b7d00106c9f1933a97a9876b050134d5c13645d10da6681ac0483bc7fd9c80796a8b93fd6a8e2cbb1aa8462ec166061acd8208ff483068fc356b88eddadee53d9c89ac4e0a101fc2fc4217b4bd5f15d24b4264cd1d52555c7520aef181231f2f3a2a443a365ba87e951d3e06309e6a7512a8c839a481085abb1b61b647603fe850d865d5d633db6212a0cb8021e24941c6a36ec27d76e7de520cd8a3c5365c113b838fee2fa99ea2e89627d7051ad0acd291a46bc7fd0421da01f0e2e53a1804aea88edf764b063495b51780aba81fd796fbdc92b397678d6caf50e72b7c0ad4c671481615303cc2b108c93d8fef172be048f06c3fcf2908f43de19b6b8ce176cfdbf453b5b81f8ed63fd91e50d73b439aeae96b7a1b380682264b3882b90cd06215a1dff89d8fafd7b846bf6d0974636cdfe5377bf984bae12a4e466e952f9ecd90695ad6161781ae8582a69f8db11281c6e6a4f3ce4e8f57ace2c7cda57d0bdbee899b4f0c384b012e85d10e1d8e865b8a5d8d0eb9555ff632ff11aacee8e2d1105ae47af8d637ef82e78fe6688759b8f6ae6df110efb0dbd6f3ec93ba8e2b1a24b58d5322f1eab2de07ee06b86175c1a09a2a7d02f3c4bbe01855bf13ad8a65eb45f7930e71ead4c69c912d7a7b3b403fbc30a8f3a50a5fc4fd4647cd17bd4efcb315e1a5608fd07fdaf887b5e633480551e818913da2ce01ade2d8d6348008b411da60b4692245440f1852452430c5bb798d45e03ec9aaaa06b91a2059b33aa8a6752fcc3c50b9fdeb644a6568d6fbddd64c87eca5b3f5f1085978c30083c29b71ee512c9312e8ad5c89a845201edc813e38fe6c4ec6ae85269d94d780d3363e5afa7b81d95f39c8d75f00c48ec2fc7e4a59f6f58ccac5a9a8502b95cc5bda3eb609812e35e7a84e19358379295b332850fc8469cc22278f752937e79d7092b87f3905d51b825e26642fdea401b524de0bce5722755f87ed83e45085ca2e72247e64a71173ff0d96469853981f4d6bbc70b2e35318d051318d3d6991075b4234d9e49e46896fd760dc652bbcae1fd00fe475ed23ffcf3d8422d9faa3f08b032d0152b8f305bd2ed22f5b362d9f759d8d4d39bd175ccc393849553f175f4acdedae1a0a4197e04c888897cbb19801e7f4e680a5424b38af631b962d2d3b1bb8d421815b6b9842ab177f1eb549cc7eb74c12022215549b34a160ed79f936aa6022c49fb63ed759be5c6f246d5d7a2dc0dc549ca71e50bd1be3960c103d2fb8326930f9345958fe7af095f3416f33576622d5b7c9f71b41674bb48d3d092edf602ef6303fd4ba8d423322a9b6957e510f8d37963cde428afbcc2d4f4fd65d770f70f5cf9cb834ece07df61834250e7c792821680fccbcdaa9abab4b25ed4edc9deae0aa71681da61ddc60ec2666ea8069c60ab8fbc0f0ce07d816bcc755d1fa7caafff22b9522e0e567f9daca750b80ca7489e7d452c8d5dacde48996f3de3ef50cea1b17ca2ec754e37a633a3a6491434c69e6daff1bdaa186380af759a4a2d35d8899a42fb34a58c98a6759461bc48c166d3451e3f02cdd6abb54a06d3da52f3bc9e8139f314e44115a993529b91f421aea88d3e6ad7396e1f9ad50699522dc2dbd0eb207d98a6a8943f0330e3ad22d132ae0cf7454ad81a90c645415dc96b69535ab337dc2e8c197fa313eff32baa09c1077f45a0973d685e33d7f4202d0cd4fff4a1ae9d8f89ca3806cad2cbded96012dd0ab1007fec563ecaa7b954cb2f5b487b73bdc155bf98442933db3e241adb3a8f264af08ad5d0d6dfe647bc121c460ce6691ee2f4ac8a8a1a8dd28d3c3c2093bfe599a8cda156e4bcfd3526d2c009751e33c6c08167908911ea6bf1b61bbfdd63ff4a12b5c9e707c4a85fc8f0cde416c1c02099908a14d3171c487a8b210e2e0221aa1db1187f655ea35299aa34a88e80d43dcc511a6ba5c154a2e31abc2b9e948b20237f86391319ff257863e3bd385d3569ebe81647914be68d250ae36bbefcf231ba1efe3d890e98224fbf877f2679ed68199599667a8998dc31f7ad9ff0812df84c81a634906affd123afe8c2fe33217f0d6ba14ee6df2b5d47b2debfd818053db698449c54e040a2415be020e6dff9eae5b3f23bd1ca8ae3870f4b69c26f8a282011f4c38c5af6d9adb0f600ee916c9353b6dc0e08798ca1311db0b0a011f0b9d6ea7835e83534af9e019fb995d2494bc434842a97ddb3991afe118400b58d7de044d8e97ea679e09bae81170452e86adb7ab7079ae2824af77b56041c035d6e41e7adc5431ce891daf4bf6db8222e401bd6ab9ffe88e3e39832e770c57082349260672e8f3910420b95cca859065a659b7e5edff4993ecb84100f0e8c798e2f6679fc72760aef1e89e12dc85319905dd398da64673212f9aa3970da0ca2981bae0d142cc0b7744d1a76ff8057e0bdd64f3c7cbb88bdd833b25f36d2b14cd0cfd42c3a53f2dc55cd86d559cfbdb93f0c781f02c03f07e0a8b2c84816bc1f41a4bdaa1e323dec097da2dd9d96616b657da6ac66fda31413460f53fa27213120d1aa0cb39d55f8115a977d2e2ef84d4230f4d9b6a11164e824eb62fa188b6a5339965edea681164cf89094ae664aba6b3338bb7466ac6ef59c436732a721301305f71c8e824c975b2ecb2ecdac599bbdf9ec94e5118e199181cd42547f3db422605437df77f22f1247a76b451e1d9288538fcbb36f50eaef4650d92fb46e81462741e2fc554e0c2f4ab0c767a218c2bc4c5fbc593ec1ed8cc4939de1467fc8dfaee399a79e85bcaf9cdb2b40bc366812e2057d811206345432db7d0b71b0cc2bd1a8ad00fbe45b1aa6de11c3608cb4643a26524359b460a2a28056108063940750f9843c2ebdbf3052b759a6d73ec5dba0e7e6eaeb31ff4740f45471c3a5b200132ef9b035d1d9841effe9883ca83201b90878c038b4a7d5329072c15fbc7666983aef134e47637680da3d7450b06005f31074da543cb9cffd71acffd67d7e5d8ee9d7feeda2f7d6f46ccab205cd298f65d3afbd655a2e16553e1039c9603687cf783dbde8a124038870886f6a831c24525514d3cabc4326cda573e92db8d50b7b10f8a2a2016180edfb47c280d4be767b4349d85f94cd831baf663c2f91de417b3e148ad4cab21ec10f287241bcd6c0bfc018564bff8dde6cb5402f1cd70083c52abf3a0f4dc2c888a49e7269bbb2c75cb5a5a531f805ea75da60615f44d11d0ee01a3f0305811deb2b65a27cd22883eea522f5eebba5f9b1f8d956c0f5d9302b275694bf7218fad3b77651a7329fa12398c0bb8758d7eb3d36feb361b66cedd59b763787953bc1c36dc97cecd7e26e2637f1182c003ae029e817043c5e69a148ea1156246ea08a2c8db58c370132829a360c29809bc01797ef70e53fecc1d9f9bdd6f40f3c3bf35d7766b7c42c9a10a563cfe30bd1617b9fd88cae058d1c5f206b0d647253ec1bd71c561d25109a37e8319aca58542d7ff686f66c75a88a023badd341c8c15e3df6ea7ae2d7458f90f27feb7ec9b233c84f00e9bdc60a8dba1db3e8614588f0ee2a1a3aa37f5b9d02db3efb21dd661fe94e5a1880c040be3645701d0d878952eb471d1a8a87502cd28a09424fd7944114a9ee3f3c9d98aa0bb5bd5542b10014279c6fb43901fced40860bd092774abd1932b8fbbae5bf5013b1aa2eac2068f04504132a0e30097a492e7c1d8e96a4b91d9657725a367dfc75219b03822b92ca0a07201c81a2db78a1d3dec390eb5436b15e7057f973b71bdd4255195a1d414e849937753c5bf61ed3ebeea8c11fab4f33c8e11c092e188d10b3204a9c75e96b148765a4c62cf154ffe29e321e9e446292d1eb4a75e751190cd4bdf4faf23a1f4c7e676f1e56b0a8db77065d7e21daca7e8246e82f0157d3aa58a25d3ccc993b9ed0cb18a1c6f59d47389e78b9a10a0dd247532a0b761b3efe3a2704b8bec9d7ef0ea20ec56083155044f882250b6eb24b4ba0455fc845fc5fbfd25f09eb91e0d9a8410494ec96cc6ac1668cc17fb5d4d31a8e6df02ad5b58c357d8b86b2c2e337c2f6de37c97ce0f068e9b0978d5479e1e45f4d863806ade1857cbcfd1e114f13e38dfa9dee3553587b178d0ae2399810de0fd9885a5f46d558f162b9f713dc16398284b26d33f68606f743b0a79c423e083e5f53f168922f51f4eb8208f8e501f94c38829f0871c9c8d7697ee7ad4f842e402903962899dbdd9f98646584457d08c4ea574780a9563d629009ac7bdb1012b678a44b6fa1015c469bdfbea047f11bf0990da6ad8ee58b26ad239c85495647d0387517e6fcde3025c85a7255cf826da982ab1d1626a7365f4760a9746bbd02a16b7e83f2d1acbbc5ae04f4bfaf14b3397c989aa72e5e6386bcd5587ec8850d27bd066ce1f032eff49b4185ff0e347b1ff4c88153d9c2b6c53a27cf18d2ace6c7a4138f0fc1807b2c39e923de2805e5d1c9476a33e2d59515b32093b7f017e8aed17af3aa957f2961cec2f2699af5d5feb1445f0ec4e481700776d21574b28dfe425ab53ab68f2551804a5873449b5793c7eba746eb524b9811e14fb2996e083822f03f5fc02f0fc64872d452fefc16b43d408b83ae44d8253e43aa8c59dd56b3783873173bb4e7c5fb51293585132500002cb03e30848b53733147b1b7909f3430887be2397491df6bc3ce43be3bbd4d326a2a88f45672141654baa2c18a67d4f553ac424518b3f79c5d87dfde38d7e256321eb44b3fab02460c0e29db91da797b430eed108274b57bbac8ccfe1a0b60c4616ed3c4bf2ed21dbd061397da785f1c74c2056efc306a0ab42515576d0237933b0e38ca56b75e22aff4518a4ca404e489304c9b318bb3c0b7a9807a249092e6bd6a1dfa4f64399c5c49031eb4ab5a48590e4894794c443cd2660ccf7ea909868468ba3a326f1642333b9ad8376ac869a15a208c40e002b35a08e39743ab9da45c868598b9ac6744df3c5b21c8b4df0d579ac5407dcde6d13a0635bdb5a7efe0116fc20044ac330636b2e18bfa4ee5fcbd528b7e30db004460468b30254bf6daac9a82a457716fa0eac90ac8345f2c7a42495100138bd22d6d34fe3a9dd19d994184e327ebeeb36ae250557e8019b505bef66bdce1fb1ad4583ca87c7dcbd3f1d4f9e265bb80d2ab624c474807e0d14a8ce2748adfadd30189a7b418ba62014d98d00e52cc54304a24b30d299c210e5565124f7273c24707039a70e45ef0a93104eb652d389a321a25e98cd8c4c56190a35868d85a8ad8a78ce584b45d46ead06613eaab8dad0c0443b86b9dc6eab661327455dc898bb7b3933596c3cde3149a741b0be9fab48d83aea0d1e13d2fe7e12f389b2649ffba728bd636992f8f2d1302bd9d04edda8d476c1552db2a209eea0ce1901135377b0a737f2e4a03ae99f8196476d012bb6573b51272274577abee25de2fb3db06672ec183bdfe545425797b5e31f2441419acc7be726828a893991c19d2eee3bd4b404e26a12e13769941a1aa27125d44310be56ead039d195fbef1290f029b950b5ba1b31df58d086b340dc45bf3d499c18c50dbdb88e632a29b71a71c5956155c4ed49ca25144a83e7400df74120290308463983502187276cf5ffda90c235025837359a35c34e12dfd821da2426ee189f4e562f0ffe1d152f735c769a846f634d68ac38392125aaca834121086b61d51ae5e3c54c9bf75bc1b04c5919943780c680725e652122daee4af14cfc217d573c22cb73e032bcd482d9f4e7a517f994990ba26088184135b52bfb9bcc3289ae346cd951bfa346122a7dc5d566915584cf7319189d8b78ab393aefe1499c75052912e71018e6232187a78f3c1e3044d45523f88e6e92d9701a054eb4b85c41a97edd543910e50d57b707bb618386ba51f8af1e6864618f9d5aa5a7dd53ede238d38312c65fd1061391ad9cfc7a431123109cdcbf2d1aa9818e79552fafea78573186d0ac4a70b855442660d65bb9adaeb6a7a6bad1ebbe72789e0c0ad4b4053ac7e983d9864bc9229dac2e9ab50f9fcc24cfdfa4ecd52adac78828e9b2c599008af15c25a125a235f6586387399a0779cdac077701c1745972b606f54a1181782dd29f68a81f3ba9e488f339404bcf4c81b726e386e59f96a6cdb7808fd65191379ceba88b14ab6366ccc3cc6857c02b9a6ac8644b49659816d917d35daf4c58c63726c6a82c9deed674d78c92ef5f2b7c0b222f49818a63ae76f4f66abad7c9f8720ea0768d95d53b0e818e5a218b13cb3b1984d3813fc39d67d608b84a8133e4d60a86f6a02076986f9d381c799f6ca975fe8a4f5f6921f9f1b21efc64d42ae813d4bea512f48d7b74fd40d5a2e2937a13dca725da500ad3aa5156bb77f99896229ea32adaf1bc70822905ae769133078f57be49446732c916188b9ea8388f78ef7d1ae8d81aa7601c959cf0cfd9ca77d57332b1fd0f3c350a4a9a51738027aca8b02acab20727789b502e54791c98b5e689c5e6e7ec9be38392c252a9bf36782dc5513e04bd63e0e4e6ef6480ef2050f701581338fa2d2925991e05146747ca5425dfc9d7b0f678f2adc4d84aa0c17a545ec01cf4e02026d487297108aa2060cc4234c493e44fda02def3bae0bdfb6a10cd48eef47fa0770e14e5c34b825c9c056188ffc7d6eb4dd8cfee723a4f29c71f558e4e016caad5ca89d1e6c234dd1dc8e4e4f8c1af510d6e20d910af3b5d215cc2f966f07472b62b34249779b31220f42354557019dda60afd26ad91f9166e4ad1ad6e86307ec37294eeaad1755e6b3db482e1cfd447a16ca1142141f5699d49f5eb960009486876671976b6c4919c5a69302c45e2d572a3602dfe74f787099095f521df21cc7bfd29df5f9dead54f1c7faedd6df24e395ddb5675c706c787eb4ae07d49e5805780a9168a3e1a6d967ffa721c1750e533ae26ed6c04a8d53171c395e50fdd23911034c1ffc030be6b4908772582732229df5b158ffd42056f4bd3ea8f9f918f01fd43706bc05a5dbec3be02dcce361235fd9aab206bf0b618a0668281d1e01624e7af316c695c1582539613c8934ce1f0e429b6ef939e42c4a268c1dba6c8ea8a354ad7c1a0abd77f9b8714f747ebad3005f3f2563289000dd43eef890d7c5a9a5a268ae5a452fc0169a4ef5228cfda859c4c4e75a20fa026e049d814a549c0123365374a66eec9b2e61d756ad73d8883d6d8935e908a024556a42a3ad1f2d70591f04b8b28b91c8a5dc6c566f7d5102e049a7e0efa9c4821ab5a76853f2a439694c9b0018c6bdc3386244df16567410561b18681261e0f1afc8627fa3ef3563dd8f1a0a8b01f10b90a25ebb4f48599d23b866a6b829ebaae0b917cf4aebf13057a1614bb131b527b218212ce70f4be4d7e05263ee7b193139137e8aa12981c1212c4329e28b88a1205b3e8879aa1050d6a6aef1440f05c05b8c9ffd42c0876db43d444fa788245a423231339910997d42965767610f32a5a1c5fe3d7474175af520cc7dbe4023e5c6c0bebad39a413c49d318c4887141a71bac8afc177d6d556a11d275ecac8c3899fb3a6fed874cf774cb4d29296e80497b405176626bf965891e7f725d42dc6d3f6d98ccd33318dd840a0191520970c0d8c58dfc0e1fa2f1c6174339620d85460388de59682509f227b0c92a69cfcdd5fed4e952349f96573495af6cd0587380532f0fdec7520aed794bcd6b77ef19d1daed48c513b98bccc921f0906d3a840ab506e12c8ac2cd81db78be6a8d4745a20393efcee3043920bb98801a554949485ab97634a4f7a982c3f7d89bb29ebcfc453c782c440d21141eba38bc0f404df48dce3e280228c4edbf8815b48d155e18865c7fc0f222a2c8b25ac430914a6214a55940a13846024d098b95d3ff9df1085de0e14e6c031f69a0fc751b86296b4b2e854505e708684ea1912c4e0dcba191227dbf3c322da3b1573a974f4425d2e393e97b56da6627ed3904933a02474bad34564f3c6eceb9423cbd956c15c3885c9d7d9f09cde94c16dc24c0b21dae7a37cd24a70564752149f380bea5ec8288d1f0b458dcf171b5e18a97b0134ba0652b90f937d22b993e1be994d01d52c12ba97ad890277be452a5f6b0b8fc4edb676bcbea4156de2ea38af92fe6c20308bd52d0c02cc597cda84eb17633af4bd2285f4dc2330d20d7eff73138630d180035c75eb96359e6d7441bf17efbd0d15bc4ddfe2766744de058f0b86d36f8039cd87bb3e86cffe395c075ab74eca97dadf380790893a2b603be0362da110c3724d1795c66249b4e1d0600917e3397d06bb2dff5d2b238e2f86be9bd6bfd24b05b95d9d65e0c842c02360a218f056a04e311cc47d682b8b7e913be7e52b4dbf945f6086182f1ff103c91f44ac98f2e839c1ce40676c9b19ec933c1e98bdeea7bd22d1d0f807155f0edb01154faefa8af80c5eea755e3e435f72e87734203fb853504c8a6bce3afdd9b8b783716fdddb0ab2611a790b8b5dd7b671ee8bf2c97c460849d3cf48a1fef47094ff1448f7f54f9923116813736caf0f31b3edeb8f0a498d68cd95a4ea597f39fa2b6087c926f8e9f54ceffaebabbf002ac03455d5c8fa329a3f30fb2758b00e1c7dc7f7f6a6f987e50c637e0b0f0e9a55674958f83d88c0b719ab5a2b1d88e1c126e834c7a642a657cb61d3b354072b6ff1b285e69c34ae5c31cc1b6cc5cd8d00778a7fb40353094649b9c473fa3ce56c8dd94e0fd317739ab2a446af80e175dc137bef6941f6f639d62a4a6f4878dbcfeec380377ade5bf3c3e1ef9c335a21b128493de1d7d4ac72f76b685bb29f131cc067ded7d73071d03bc28fc84c87875a4422198f99aec8db10c9efcecc3e7977bb029a67c7e8367bd67928866646549e58efc3217c1ce2772d14b17da8189645e8d3694a8478c127288a4aa112103e54a9e6dce4633880b368bcebaa5ebc72d73c2be8c18c37bdf1591b2fd3a08e0d9ac70a30c25ccb49bd01997f5e3f81b3e969f27dcb5f9733f7a1a928a9a322bdb06087b95c11a412ba7d7f2c1ee835f44568472cb3dd2d8095fbe5162616df0557288f46325dd36098981062a7102026954101f8399496df8b37f23608382143930f10213bd27ded354d3a4016713deef2f2a919f4377d93820f8587fe0eb113c56a479d43e6b278c1ab1fb146c81f6614e30265b62fd99e4bf06ff387200a9d6adaef5ba249182c1ed41683262247efd43fba7d050082d3865f56c2bc8558672c7400c70459a7dd061013295f3bab8fa02620e71751aa856bcf9f562525884d90e86cdbab1de623f18ed6af9ba20748b82530487afe1a6ebd1e6ea0d9962e5878c6705a4dca91b177b407fd92f79d1e739bbbc75a565a6fa9b366a48838ba5e8242a428be9b30bbafaf100d357aea4a9484a77e9ab2d3fa9d5d4444a80d32894b20f9615dbb274ccd1240809fcc242a4e80842cea73fa2b994223d2c07a789e70ed67a5728aac1429875e9a8e6426b8b36c511706c5a99e31a9f79cef946255e2f10ea081c4e346eca503ef95b360e3c0fe2336d2dc40f2607713dcd4836f127de88e4e3992b57f8f30af60d7ebdffd95956c8e100e743788306d2e1a23459043c715afe614eaba508322cc0949d72b2d78042f9c2e7bb9c35437b076d5fb393583681e4cf424057407093e2ac077531e3ef0490ee77d92f25de98506bfdfbac379b8e05e97f6dc0bc4beba81f89d103de4af0bb7a3234c5eb855e12f48ddeeff684b71f8e7a232babb3f578122cb18e3cca373f2c8094d988f67bfe81a092fb753bbcf6203fed875a1731050873b984abafb6e0270f0d85d1ffbe2a28221e60fdcaaad47626ccf9fc22b0a831d69785bce916adae7cd1d82a44726d7b6afe2cf15a2fe41a9085af13bb0250702c57260e8a36cc49e91804617c92a7667217ad37bc43ad4c8f63ec51c08091b5db3affdb1a7c61e16f25213ad612b8d7d205c693945e058bcd1d92a96018a12a232631d2fc33ae4724f5cd9d49b2a82600eca1f7ff50b7f9dfd531f7bfbaafb390c801baf9f1f380d577ac6dd00e87d18245be28e55bee1699c8bc6cd433c2283dd866767b0043273d07e87a42408635c67baca12781709172b89ffc8daf02c97c57b0c44740aa04b23f73fad397902ce504b2bc87b66ad2936c08ae37d9002d0964f45caea1d0cca42e6e468017b64d248b6d9353f0cee6f7240b27d5c2d39f623c8beb75f7026a45bdfe285dc6e55a74672df6ae6f085d353d5faba81ef07ee1cf1d68fdf11b6571f075439a8581cca3f33f1d61c44a542189d57e71cfceada68d4a4d6e3394718e3ef00d04ae3cee4deded86a42ce7388f6c4e39b71cdbdfe8c2af56c3b3f4f7e8eca800e4a2777af068ab44eff83774ad05d86e90d6ffcd33096a19baedbf5905819a62bd214988bbba0a6427b942f8c430249f003cc0648062f6f543d9af0fb4fe1e6e5401454e505019be41bf8340ef4c49f77af37a4adefb01b8a4625459995f002d6b6fc87850b62b66a0028c8ac563b8568008d2e313d907e7d532be08fa9811e0d10adf31d698534473b8cbb0e5b7aae32d72a90ca960674eae47a601c8c967c5b1384a944313e206b372fcef8c7e329b8f74f6e8e9d99d5f116489f01f8d046b0b68c9e32a8fc42e1165a178ebdf716504b2fe02e9e075d2aa12471de51dbdfb8b5c1bf6285929673245609b31a8386899b44b5bbc307f722e72940bde75f2f7f53c4f302abf71cbc49ff163fe33417f8dcf071d6446464716588d8fbb10f0310a3140da82994a14c478036ba57a2728cbf7bcd1024dec9a30945e74462c22a207c2cb641cee471ea6a469a29f9df92115b28ec687bdbe9b652614e510b71a0284ad1a1cdaef834ab19906a3ea79df60997bff2b4659cfd2968562aa45d7007f0206c2abf8bad80b9a3b2618a8b1f30b70b76d03055d49562177fa258a15ecf2e72787f997a538cd9b95d075932fee87be51a7dfa6c54e6f0a0a2e9de904b570ac93c1f1a5b2143aab16d290914ce24011447a437978d02b9e7b7137b49390785e302de6c0eca3ecfff4381d34d27ec815829a3ecd9bc742b3c2e55abd8b9afd4b4cbb9bf64ae75325734874fab4b5022d18777f0ab9206dbca064c154223ce21386c5b2ec8290f641c13da39e1008231febf19b1bb259025fc8829c3ea467a810941a6647f58746e2f69739b05091a66c57defb4ed122093a5f6ab70bd8bad04a48249b8fd4d2d9f9c95bdeac414169909130c716b105f715985542e4998ac381907bab869e0d6b0e2a4d717e1c97c97efc582ab2b625456c7fec5867e34b8d3cdc8014aa71755b5632ee56e3496149638c9fe98a2c6b715ca43f728e67148a13e802a0f8fb861496b24297ea1b30cc666a84b71711f8f0a420b75177009d11894aabd5f40e24933fde212fc6fc1fa1be73b9c473350888d6c38ef1e9b8d5d1c2603f2138c36e90b904dcdf714fad794c5b866361e7a4a12cf7659331b39e18210864c6a84645ba09b42ba8410c322b0fc150c89c23edb2e9d3d31d80f309319de09139024efca7fd34731e57cadac15d5515fb33f4c94aff86a0f1a9a5c8b348a6fc185dae21245ed2125e3e21e881c76747d5b74c7b9f7be91ee6347e9ac93c0a13880e0ddca0eb6a3095d93affc95b64ef4adb8713d1b05d1f76e2c3d2a6701c716137f310f7d041ec0ece178ec2f225e0afd6709159fa363d72757a3dd552f7bb43e198eb9fbb859985d71b0c8cc2f55753d99a6a235b16e79407cabebacfd0f6b9639c8bc4483a607729766a76ddd84ef748cd31d4ab6d52cc036a6be159cd68b4af16c9f03b13cde1d1162aca9f05c7b77630e4c1b5959e919ff85c146b0dbb4dc15cf498d03a82ac8f9aed5cd9b6780eede45d52269e5511a3be9d633375456de33f8a2da8248f4f55ceaa77acad70b8e95028d91c60220aa488ae1cc231973c733fb7c948bc914f27d52913d60ba0cbf7775d84dcda17337ee950fd96c4d8840ec6172f1e77f7a536f225377da605b833ae68617731cf24d4efb064d54d3bd54fddf793ef6b1271b6ddc0df105b7515bb77eafd9c756a0df28d8ca476d2a1d00469cb4bd4808f9910f6751e27815a5b3fc48a7b089da7c501ba442a5b8dff4e995d85a3be476523a1bc470ab7cc348257b375b2d575e8d2b1440be86af64ef22b07fec1431845b3cd08dd3275668153d6d65789a92f08f23cbb0f9bb22e5966f71e1fe104de8afa589a4c41aceed95514cda6123557f0e1f5f52d99ec08dfe35a8caaffd05eee2267eaca9628c381b814a3cab71417a2c940021a393640cc4ef288c590f08403ffa6ee9e90e0fd33bd2bb0f08039e9110e168716ee8c7cd0ce758ecd066df47866891ee9507dbebdcfd681f28d1026804bf7e9fe7e4e2af3040713fc660431a8f244e61ca328e4d6b8b4fe676bc409a3a294d2a729e0f5e0eceed948eb05550d8b87103784454b1e57c0ee5cdfdfcc8dc879b86a73547d4ab86dec96f47cd689d915ad39155d397a3ffbcc01f5c84e99686e1dda03504803a9e48592054065734ad8822187f19523cddcea3d2716f209cda97c57fe12280937eba1b0e9b054c70ef00efd8f955cae26dd51bece6da9f932162f2390fdaceb24325b8413ca146c29205f0c1c3f10b88e031d40004c3c307539141a91d8fae03a74685d2a07967f7392bf666f0e72e530ae7537dab71738156b4dd7c3dda2927c28daf0551568101338662341510aa9f96f8774e2899c1077cd12f135b490db561474ddc6586bd996320509c77678551c93e41744231e2b4578ecef6b9829460ac684024ecd4f3c966ed68dfc7582146239dfac7c7c53f4fa14d2932db4d6c7025eacdc3a05539da60fca38dd6aba42f3787f587fbaf2b6b6f2a80fc115a51543f76307aec3a72b513d96de7591e07d116e5a8fa19b334bc3e9f32d88a130f89b4d434aa0bc12758bbc90d111050d9d840f8784cbf70035d34f1479c3d5ea66c207d6eb73930e4f9b0c382e58f1d7e9d7514d5b052627fc16fffc6a5c0e75ab8c4b41080eb5fa121799c4e3a900781ad92b645514f228aa6dd646c06670369f566da2fd2d5a9c1c0dc6160b8a048346e967238b5e9e3569772fce4d059dc15053af05ca8d667a3eb8ee9b5b1a47b24cdc884a524684017c8e2436b02b435f0983afa029adb46d8afe44f42d6d6bdc5ea26db068b7f1500fa2dc9cf939f17166079fe0f9a8face9277c21ae14fef778df7123a1c656f71fc283e4ddc323ead9f73ed1eeb62d8e7f5ed92d1ee632c40c7785dc44fcae30905310325867fafa54e8318e8e3b5ab59644c5703c84e6de09a062f59d5188e63a111e9aa4c9246544efb9cf31cfbde84cbcc192b8967ee16528a83677621fe90c987add8055d6c932cd35c862047deb1d49c98141c7bff0586b1de9189c25c4e0ae08f032d14610e282b9f1349f6046d144e4c33f2027d688ee878a23924e4cc7fe471afe6ffaa2d2be52013da0110754a5a56870972a0b5e06af27399ab653b6b8807fff972f706d771fc4e6e94de0aef933560b4a07f6b6560a873fbb2a911f05700ffa2ff13ed6d7c2680ef08cb0d037d68ea56fc46c73ffd43d8c1b173d4c8f73f905d2b07e16324fbdd8b0c381cdf1b08864993cdd3db54ad95292ba0a1f6d63268b2d50c394d018b751a26309b9fffad639032110c9cae3d9b1003e4082421f4ab61c348e367b69545d9dee13bd4a74285d74df91417c0d32249dd6d98780827cd34ff0dfbb919150c52a62339b43b1c409c1288f8d7fc31fd85544f1d77c566a3306a4914f1e159a2c30fa15d8941c0f5bff107ce32111985407ec6270d7292ce588c0e502282878bb2385321f979145a8dc110f78e49cfef22c14e93cf5034abfa8b0d021ea7512a59f72290f376244d1fed65963129db5b711ea677ec9c8ad08b7d932115006894f06cd82f7573584fe6c6cb221985c103af569aa08a2b185ce56b72d29057372ea7fa919efc621185122be96c6cd5e23bb2fbbcbb109b23b8b8122fba73180431c7b982320a84534035bf73a544cbd5cd6d824d5fa888cbb9561d9aea65dd8531e35cd17a55810f8ec7e12378c1122a3d5107ac7096111d8e739b20fba12f4116bdeb557f552c5a718ff0b30b9ca101b87e85ba3f52578f52049c4774ca895e3e1b4010be8d246c82f21bf8dd021d3fb73d885b14d107d6ace3508ea3c612bcf50e92f8440ba5baddcd84508b2feafb88e88ab1da29a405c926a50ca14a7d8925b98ca0f9d78247598357b61d422b14e150e7af2994b6e310cc9a1639d677fd708c5258da362992fb2c72ba09bfef5c48d7422bd6dcaff40f15e015bb912e268e077d4e571e60e2e622efb16c42e159640e264ffc4fccff19d4c95d9908beb8e3991ec2a20cd323567544b43dee2e6061beccefcb793c1c4c698cbc3e03efacfcb256256b2975c4ac2dac80b1e83ae0043b88402f5945ded891f995134a3d00300a5776fa0878586462c7ebafdaabb742cf042ff58e6e685ec9467540b2ebee7cbd64bd37dca36b694543e4b4477b018bdd6d97087f162f7141feeb95b0083a288058ca2f014700bac5d2de21772056e1c4d9a45af4fd6492aa7b406c728645a1cdea355c6989c42b2297e3909307f7660ee52992e58c7944e932eab83def28024ae87d945e4fa6d7f90fc427818ed647aa72f7fb21f11775011db00ab19503581e4c5ddac2f106f3993fe699f6d5c759debd9ac36e6d496f9c7f62fa46cb7ec9492c859116445e5a6dd26966cd1c171075a132d9763ad18851798a6214571cc9ac22d1b5a107bd57882835871fcdfcd2e9edfafd5839af91e3ac752ab5ae52e369eff724831c32398f3de11c063230cf8efde0b05a4f1ccfa8189c8a1b876f923985d60e47acfc548abcea0e23e4045fc3f789c92e46c1b00ee1bed4f6657516396b522694b0b8ffe3a7c1ee1caf64c2be30b7a80d5b1e448ffd0c27fa087a133ea96e93e752a2aec9bd3c5fe804a2f369a85d0e5d2eb0ae7989d96c61af8395404674400dab80e4ae4610f67a90666a4be1de521096f2cdfdc2501776139cb0c106c13642e459fa69ade6abd59f6ebe5b97ec2c042c1e46e17f8d0cfa87efb5b33dd06d7d85abcb961ecbd222e3a513f1f1a1c10679473ba081c5e94b203aeefcbb44e0088c0a74fce9cd1d8331962db5806e39a7c27c8542129e58e60f02515eba1e76cd8f6e9fa81b7bc62d0d2d4f2ca2073ca328b784107f935e782b26eec2485ec2010e1678d75dd81450de348f23fbdb49c675983035892dced113c14756287490924e759b174f08c5a805f1ac5fa72173bee1dc16ef1b96c926cf4248792cbd67a99534a380950533985e04d9104a3413b1c163f5465ab99378961ce5b9afc0bc79782daf45bb9d5c2e1914b067584b50c178fdcf7904189645cd05afa38bb30e377024cad4a92c00886c0a3503df74a81623ba648ba3d66a755f0d370ad5985f1acb25a96e3f1aaefa6292a51c46af8a6405c911b12d12641fd1291ba62aac50a71b2727d136be4ad003548f6531b54d2a74358ecdd8958375c4596fcd2d174ac6fe0faef1a34a03b110808854033380822273278b7523733fb3b610371c2aa60dbddc09b4a09226353a7474e2c297538f14bd823d0d42adf4582f7e180b563b119dd356f7296f66223c655a0d1943a675563edbf7a8b7b90aef75158fad99ba5244a7ad2ef7bb471fbb8832ea8f8368b77eab287334b2ad3c61b70276cb9ddd2ed561c146aa6373bb8b8a0e3fd09f4ec5ce0005447ed98ad3e75792e511170393f73644406aec4061814374f65173226369c7aca73f268dbfddbd4fed4e571dde48c99364fe5e062344e61fbc04c61eff3daadbf7b87c5df055221850743090a2f324d26b832352acdfbcc2b0991dbc3e7b6bd9035c5d8dc70ec3b43ead74471527ce93ba6154d19e056058ff2b50e4087ba62c9f44d03f5e73ac4ff63e8680311a894781e588d8dcfa3c5e93c76cf29498ca36fc2398b9db87f95e97a0059cf0e33cf130b90ef222920175c6318aa4ae1291045344b9cb6254f16f74e3f37cdc457af08952ee1363604033c17d99a75c3cbecb2266901ebd89f1ceb9272e6979e720aaaf9b8249ec198fd90b8587d660b46ce4b4315d0896f87ec5177a32d43662cb50bc0850c1a87d1112f94bf496884532dc889724febf61ce10462cb552a84c0f7b4f683640d87f68adb3a673e04b91afd8cbb1e84d268cb1d5420bf98cb022970a66f3dacab586842404e56523a7a46a7581816d725e2a578e08aa794265af5460eedfa137315ecdd3d8822b43e2d466188b47796dcaa8a4b858c9aada7a0d87a0b06d85f191b2cb82106f9816587aae74623f1b0b12b3ba09c3be77b4287e6134a41b344fd2bc3b0785489124ae0f1fdae2993b4b145e6267b786fc550688f65865f50a620652260f1dd2e5e671f7ae775f77a7b032121a3a64b04d8f0e510d697fef49c968244855d3749508b4665d779cf5801ebd3f588e65a79a5ebfcffadadc44aad51ed506dc87644173f44a0b1581f370102eb9b6fca097726daca8c9aaaa8d4898ee955ff64258a807c1a3e192113a194595373d8903b5f5a2ae1caaef8e6e9d0f8710b5a54828cd0db21406acd76a34b1fa794044578c6f7a8e1571e93b81675d2a95229358c0e1c66e5b7b67278de03e892c25fa1175eff3481f8401547f8bbce13dadfb52b595e576c101ce0c92278d43884294033410f4b5e7d2a6d4052fb3fb2baedf621a516732ad3839ad741f03d3bf3d0803544c7e9c0ca37b5690fd341769750473a1ff24fa3273377bea97d996c1d8c21ec3fefef9536da9b0a4f9e6811f5a3f7b4964ff27ee3536dde7c88020ad4663482f2db5f8e50b90eae096a5823178234defad17389a6eb00d5a470178b719c2c2a4ad7c1e38857d474437e4647669c40a91c7c9c32921eb7ccda43a5b97a5e14b33c842d97d01e4195311a2ebef6f2dd035e0627d1b28b86ca9772b94036a27e83d95970ad48840d9ea7b496169de348358606a7a9285df3737b6ee07d7c46efd0da29cecc41d65ff108139e03b2bb382a99529d2b9af39a7c0b716f87caaf2e7cf0976aa361e5541a2e4096776c9556f099289c6df1c39c37ef208813fe782e914060996408a0f84ce68c2cac899fec8347574a8ee8528d2b21c7343560fd54b1d403b2e726ee6a87a5207d11726ba92c3e7c4eb573330cf4aea126ca7c8489d9c8a3e263498e9c757e2384d70dbd15984d30c9df734ef8e733e36fae4bb24f69cf085db0a4cadf422f42f0ad348eb2a60e27c9d1c01ee44c19c6b63275d47a752584f00d327581f38ff1d13681cc7bf040ac53ef0a04a1494a5abb460f7c9d6b1ac88eec0d68a49b758f3d200ee1317fd49a05aba265ce04fd1607dbc431d433c6a87a4f2db03e352a09e5cae3b22bc73bc5111a88b65994bd9b9b5c59c434873c88cc68aa7133a2301a35beeecd009cd8b575439e2c93f483b521d76736e2679a89467b7b82c40fe41a3ddd106d1765f248034d0094c2f639041e24cd1678fc3231c92a47e63cf6f8ae0626e075e2019ef93f9ce043909e0381dd6ced24ffe0e93b482f385c9476f140a21a579ef5898c07e9a3b70f15380de5b7f5aca9271cf8029515cc89bb30ab70a8a9e5bd2e30d557b2dcf04b0e6cc0e450e73f09330cb015b0926c853793385904d56bb2f8157c19835e71ed1aed13a0575b2fdbbabdce6ff3fdfc32d7e1c1c2035ebc3a4d515b07972038b6cac8b05d09a8fe143e0a12e08cdc16991f30afb8eb8a7a60151c23f5f896eae30305c85bcd6beecdec7e5f111d8ab6a7cfeec572f7d055d12d4c9ce331c693a2f2af257f5c8ee37a15fef4f6695e20ae892a4ec2057eed6e2f70ac193077b9b02653f7f7e12a72074cfc5d3c3ef17fb0385ec2acf59e38d4512da4a701eefd2c9f4735bb463bff1c26f92e08e05c6776f336c14dde0e59bc520e6b1d98a5bb9f6ab0c8a587ac543e5454bdaffd8f4730761b7b341791c61bf04d146442a634960d58ec469f7f3391d1d36257af0423ce9624f3f056271c5bb2983c5bc93ad3de6bc9645f8f0f618e0c81259a9d8c2c468c0ec2cbf3aacd01d5aa97dc8f038f37fbf5afa263e8e7409fedf971b67a47e5ff4e6fbdf0ceb230b2867f485a2e45cdbe2b8b7cf9a7020ac7150b16851d154d9dfeba5a2fc21ae279d3f40d4810fb04277bcb8d1f0f70999e57806f32e3ae35787ab1b05576c5ee8ec4e234463d3aaa940153820b1341da6f1590a85b7cc3d01d904323f3a2868b8c95cedbc1b6300c5eb5bd13d209a44a6d01703434aadb38efdc71d3a4ccad31e499714d741975b479fdaec3f24b970da4a92e98dc591de0f1bc8c02486d43200691a87215b976707dc2910c4e8826e4ef78686a4ce48eb7d07a399ecae150f05231aa8371c555d8dae2c2d47eed51ddada89b7352fc2bff3c46fd8bbfb6164ddca0b65875dad09561a98ef44e59abcc759e1b694762594db0134997e2bb093ad648ee5304a7a0badfecb6bb3a58c3d93660dba5f9c964740e3f6865f2dec3b6dc9009ab2f01cae6e5d401346e9b561d308df42e6cfec3bb84f2359fc50fb13a00c5ebf0f752d1995415e51f01538737d8971040e2bc85afb6cbc414bfe548b06914ded16ca6c196c3796965dc4af6edaf146ab5c42b814b7b0bffae392aa1b7104c2b9715ff32a7b85583d4e35643f64306d89c16a63b5fde6e4ff491d754fac40a8031744251b6c923c0f292dc1d278f6294a6de9806cccde150ce35338070b8316e41c62bb8edebf47a6620a4f54738193f7a701312ad5b5f7f6c10eafec19dbd9445f9cf3c40f05a57e15257c77bf33601d2dc7e2b3ee2f05e40fca76c6aaa5ffaeee3e96e5cee8a7744581c62a1beeffdcfc2e3c5f67248aff58d01280b0fc8d20e99e4ccaa0410547a6b5a053d66ff8436098631f0eb6e24e1956ffbd090b3c77deed2dad0e2dd708ac05870f9393fcbe396dce4a8bfe127d034c8ff825fc90defd5502e5c6f4685bab8ff5f8cbf4fd336a4baead5ff283757115ea1a9def117fef117fee71fb0525f3d4a4cd7d56b0f400cf91bbee7e0c0ce53be5601cef9386049d593ef918b11bc6af5834887e6065ca8a8e8b771a5748e0fb2bff989de7f697abd5c52f562c0226ca5cfc64b29700cae07ddbfd944efbf1c7a094b635170c49c819685f196541bda471fedc9823e49e35f9140a55231e51c43357846ccdd6eccc4f7bb4cbdc9a86e343b63ce3aa4bcca8fbda63b62537903fa0de6aafe78f390aa3504fce74042191ee8127e60ea23757e99a9bcdcb489f4bb448fff624fcf5ff9bd643dcb95f327593e8c2bad1f3f48ffe64e5cbf4bea4d318b0e7a010930cd63e6dc7b98c3b8856a47c5bacb067d50b9a71d42b0099b6710218cb120e1bf13a86e4dc0efd0d1ff72f4120e4dffdd20b4887ea0d075a059adfb5f5ca012cdfd15975231756e6622fa2f81de41b3020e74dae88d8ee903869543540a1317b4b5e35e236c7bc6fb3af0f05a8d17bdf7a94abac3c007775d426d80a5db8d4e9cfe4b7a0af13707385fffe03923d83385a28c20850c7a3af82905c013202ecc543b429d0793d42f6bca5f332ed2f8c6e4fd73418f04817895313335cb926d7a97f7a3c19f1180dfd08b2860b6eb218dd28c4ce0582bc4623ee6c02db60b280673d700841420c7aad82490bafe23dbbcea8991a2d9b35b91368b465ed69354762314b87d434ab4c4a0af84fae2159cbd70e140046a5af6ed0683b1afab511cf0bc055db6d2d18c516db33c3af9c86563f75e61b0b7420037baed859260f78bacdcfc81142546ae685247be27e789c652264a0de4a22d0801e66ff2baf9448add3e83b9e2f6bea151bb6424d46eb3f30af01c91d17b5528e482ccd227941725cbf1f16048aaa43c6e827297de84418ac642e0e469e1a98aac65ad70fa1ca02ce53355ed596f30c3cdc62452f4845aeec503ae81a1c8ffd08c00d7123c4cb3fbeda5294a79e3a9634ba0ecb7d4340620afd2abeee9e1a7a9ad17fc8da384d8ed185bb80cd287aefc6b0774f204bae4d0faf7817f77cb15c97d9cd7c601890b1f4fb0184cdcb191e448f7767e03f706ac0854fac9faa8587314654047857e4d9e6bedd4585c57f98fbf4a9e632b2a39cc3e5988e16d4d1e4777e3ae5a209ff0880b05b5dcd4028d0486f9d2334436e909537c8d8e3cddd1aedf2292640514b7f1dab20d22e3f6d5818d2fc8bcc3765819d970ed34b290f78e0d37eb761ffc10041a77f7bb521038a5d97490b2ac5a1eade54292ca2c303cd53c16b54cf358f7f9eef3ddffe7bb1f3c27c34aa65f8426581b48c90e5c79cfe8bc788a85e3b12bb226dcc7e92222694d9608739196f4a64db6dc524a29a50c270b8e0b1a0caf5d57e4b5bb55eaea91a68b8ac86b2f995e0853c74b18a829274e7606e9d1185f1925eecf087ffd1615556a35d576b431faebe4181d34b3edf0f1d7f1f5313c0aa3420643ae9f55a2af6b948690cd3c757d973a27e10b968861e4a9ab0efebac697ca58a9632ce3dfadf99782c6138e224f6c8e0009f369b32a75468cb1f8fbaa73b8b15f3e658eba4b55e4d520b64e9aa7430aefafe3b4bb85690d6a6d05c60d9fd91e4ebb7ee2b347b3bd9a9f94d5e977e9701ac063bf38cd2a5d9e36214769ede55da274ca84546df912e3cf1e9fae93820a54170ba0559c3b737cba86d75e5ef4bcf611bcb3053af69987d3ce9a94f44f7cf6d52f9bb2babdba4b74aa9e35586bad4fad12edca01e643787c86d3c8e0e7ac0eec3d12c6678ca9b2f0bafdee889eeedab6392f6baef4939ee1ce5e593a0a18acd7a62829b32f2faeec59ffc0561f85a86d399e910e263af04a13b5da7511a078c1f66a2e24245473211782c12a09f14eff9cdbde99dbc1b043f1c259cd51bc0043489aa54601438da782ed55194a14d92ad95babd56a66ad779750dc78e72e4f1d3df7906b141c38ecc2dd49cd168079b86edd14395b1be28e31663a5bc3c4646530f5d838d49652cac3f9ded9c37bc38d791bdbdebd9bca774b28cbca5e8d9ed2a52b9561688b713eb5ceaeb59b28714d608c71e8d7c77067625702637d6f0913f8cc3c12499809d333acb17fe095b03dbc3b218b89136c0f339538c184ad25ac920914ac1266d28eb5d61987786bdf589355f91097b858e7300d2eab9fefdd24984660621a81c4adb867023e61edde555fba7e32fe8c96c4685d050cb80cb03d104a29ad75053cf434533af494c3b34031cdf5e69c73c635674a29cdb962242a78d60b39e3b801f4f3f4f4ebc6d653cf56497eb4beb4a501faea361523d5e005db96edafaf20d75ccdec234fb6f7604f584f7dc8e8e8cf3dc28ceb08201548aefca1f3940b09d65324534fb9aea6fe1cfa92d2a744f2f494eb48d89fb6eab6161118eb1225466288d081461c5652a7610f1ca5f80535f627cd57271156b7c81ecf943d2999ff7a6549d46d3d7bea557fdab2fe1cdafad308f8e711d99f1f8cf811de7eadc8fa935a1c5f5060399e7e41697dee29d79faea75f50574f6fd873c39ca3107cd968c225a18e7bca9536f5f4ab06da9f56eba98f4fb9d2ee3cfd8a3aa32ef6f4abc6ef4f4b9646f6b6a75c692b9a4627ea70aee0503de582f3f4148e8b3768c1af805449b9f09ce121a36e7bca8547ec29179eaf3ff519179eada75c78b2fed4c0a778ae9e72e199fa3b7ceed5538b240ccf8c3a828a48b23dde6913bdd6db82adc87a4f7b76db0b3dcc3adba3a70d87d671b774e20bb9cc3dcaeb6739947356c13169eadb827cbbd45a6b99191aa08cafd4bd62f8de8b4b9d51a68fdd8b70ce965a3df55d6defac4d4c4c4949672feb7b15a0adf79298ca5bde5d2685f572ce67ce396733403bdb74efad983a706cab62d14f8c31b65a17897ad657195f4b667b1c028df4e8a4c0a746474b146b5ca3b2f746687dce1afaac824c56b19539645cadf59ca79af00d76b831f5b2575e4a95ac9fd7f375bb4b11563c06f8050b764a5d6c5faec989c997d3f96cb62d35b960f291eeb47d373ff39fe4937ee6483f393cc53484ea1484d39b915bc5f4b1758cf1c518f76c0f27d903606f52925740719742d07af598a6f9a82b227152301278858b8475650b2bd81e0a7b80e0954cc262dfe306bb9c87d8957e8b1cc478d3947bd764bdf4b0280cb7af70977855d851c4208531168271b8ab0a5609fb09ec1bc0d831c63d1ce65ca822612f77b41ee0fc505211f87a889df54ad61c448d5754abed4c404560cf48d82dd5f3d86dbc15a808ec174d59b78fdbc7ebf6b65b017f70236f22f2221fef2e27ee60b03dec270dae4043b83d760ac253201d04af68a770f3a20dc253c839089e0c94a060bd74195ccf790aa58370103c19580e5eb413f20fbb0e4eb41b720d7638d7ed3c74700ede34e4429e77452672b9d2c84453530b9c7bf0a6a60e3ea48109b687b1e73007ec43d83b60f780af52fc562841c2f66e3b7287c78e70ce4c179ea6a76c9e76dd29727db409e9bc8827039b6be04536d7c06550e4baea209cfa72b4c88d3c059b83e0c940031928414103b7b90c745ee429e8bcc853d0c06d45aef3146cae81ae5ae7da7416e78ace0b78434b5c715e77289cb8b5a2607bb79e00e1a26fba64a44d9419c4ce6877c22a659e0914b2945be4a1607b3757ae724f99b84bd557db95baead75e0fb945bdb909231f8126c2a7be7cef5d2aaffb593d94371fcb5b6aa6ebf7fa15b3ba26b40a6a1c1c44ded537aa2076362312d637de3425f5ead72f9ad285eae62ef20fde6473a2d3b5e6a500628ca1fe76b6dd59b08857243a081baf680220bcc88b445e0a2078456ee4362f4ac1c86d246ed18efa6c2ed0418306017ad185fb9a67ad93bb76dbf4c99ba7f8dd76272ed275dccd5da7143f1317e9ea78a5ed513a4e59fd3d29703471420428620006d1d2eaaf169656e94cba1abaa50a285809abb47996caf634cf88cd99984c26dbbbae3da390cf2cba097177c2f6aee8a26b27614fdcbd4b71fb09133b146cef8adab7a84d9cd02480264e6cc04ee56ece399bd0a558ee7203e9bc78f320b218a0fc5d519ba8cedabe4881a2a8ddc45df21075420428620043f5275df397dc0ae38416fe49d3449dbbe040b154f6ad8f5444762a8a62e8b6cc78a7792fdc9aad57fbf4e87248215a0090b97b69fb46b03dabb55e01450c4e52d63e454de95b4fa8b08131bc82edd930686fdf048a134cdefa06ac9266f35e60d2de52b4b7966c8001be058b647d4451ea6808daab57142b5c3f69b08507d8d73c1d155189be96a0b6db14a9bab82b51cf155ebb2d95c2129a9757b04ad8b12e6a40f6ea99676b41fe1346b048169bbddc22dce322eccf8dcb5cac6931528a77f50aac639883d75d1563c1e63517bdd6297b000ae4fc5ecf790adf5866165ec85bdfc1d32e283abe0b0af08d9e763df9f3e3b5d976677d9b5b9202d47777f7969596bbcc2ca0e0e278d9e21d0bd86bf5473bd638f890d04ec8738e8290e73c7b8e178392cc4321e71d78310cf19262e0e0429ec2a763f08b647d28a9e801dab3671e0b28c85ef480eaa38f3c16a8edf99cc42561af48bfb62bca4eff56adad2bb63716690dac6365809adea2d534fbab1885553a6bd5bf2096a6081c6bd8f75d1272eca555b2918e79e7d809654d4c68477d636ea7043b167153c1ab0047521030ee4b145f1b706db99d12fc9847d25e2e053a03d597e39114a9030b21d9809ddb91e409211ef60a86dd9e2178b201a54d0b790a1c78f42209790a247cbf295da069a5d3e0a7f0a5f0691f5da88372bba69c9b6812f214afe5942ed0b47fe13e76eaa39400373f29b086b9d08efaf08e7eeec45fba483ec00094d24bde4a5e0bece36cb99d9216d8c75d8a6f2edcc7f16c540476307205e46ed31e760b6695ec0b5f310cdba6bd865925cdab609557c36ccf8ad530ef85fc5bdcd843c7bc16e4af61f6439e0854a0645a77a95e5d55c7559557a7ec0a2da0a8409c81c01d1568ab707648c90c3ef4bc3be9966d6f9db3be2cbc8071ce3b1cf22c9e40cedb56ed7bfbd5a1288a27d38be1bde10d2f8f0592029785eb39d7df7b6fadef0d751d2770e9972bca7a01fd2947af791d79b59a9d2e5a695d576bf550ef306fdb25615cce6efcf531521644d7bb936e89e118861318473dea518f3c16ce4a81da8e05eda36f1ff528eeecd744b14659d0e202aab8abe404e84512f1c62c4aedf85a517491774299fdbab6bf5b909f05ecdaafdf71ef46da2389a892d6aea321dc77a10e72db6edcddaff9b8db7eafd3917712bd789144118d0a9a2572e04429c3e3b3f1e84512793a2a4274ece20efbc6dbf6f28a92fab55ebddc3f28647da4fa609197524ae9adbad94559fd8e3df5ec745d84f8fe68d1b63d4b7d8d53ff705227a3016766950be7f50a69e2a8fe6665ffd8556e68a10115f156869de570b8d2ab1669967ef2fcede6758a92e84cca74e9e2060f1e2e2b323e7f51f179e87389c32fa4f8d15280281b672d611fe91f90645716274f9224e9d54c0aad0cca13d224e9a02a4f48f2569de09c73b622a4966fb5092fa7b0f2a232b5264dda570d31be14d1bc9c77f5eccce4cef2c0b3073bdc0d082410d6ef8f9f1640185eec64264b44dc0d032fbad891f2231b83e3cb4e612b4692c429b979c5aab85b88289f7d048eccb724a49935926ab3d96c698a70789b6fdbd0db2a1a1a40f50869e62c964172558d90a6ad6edd257c367aef2e59e038fa10d98fa3ef3b8e5ecdc67cf439d38ccb65ce1d7226400654a93e57abcf4ef17c769c7d9b6df9eca5ce0cf8d97dc8672f3b649fef3cf9ec4c5689c5672f61e3b39b10f2d94f58a52d9ff1a4f9ec287e7c7618b2d79fd35998a8219fbde6b9e1b3979e3145aebe12a956a4398a25bc9992456c070e1a7ebe5c5f7ca632e473b6d9465ecdbe9ccf24e1b2e68c0e3233a0f8b297198b0c9fb3681ba3c8332566aa5889aa437055559695c21863ecf5ac8d96c7152dad8a614ce2ad2c8f73d8087bb5c2b5a946c5786cc375ea050c888aa9c0a60bd19fb40c2f6120061ef5b02701793ce231d3e321dc64e8b16fec25ce85b0d110e66db63641dee655c80cea4fc5d6cfa7a4a874fab89ccd6b907287dbb89c508ea257c8c6d365cee63578abade4e1bc68c8f1b79bd72ad2bc353925c0e781bbb03e17d6e701afbc4815c7d33e7a91ce8d54fd8c53529f07ee3f26be0efc7ebed381d41fe404a8cf039e7512549e3578237b92f4ea8334c9285b11e9d4e781db9cd2a522926704c9a9afe7b61b1569da9076493ba68b54dd03b224922449af41d22b69735ca6f4d4ca8f8e4736357ef4da8334c79aafface1a046e355bc6acd1f1a2571e584a0a264af49046062f353d76646b459822cd5c759026ce3f71240324c69e3e6088f838e3c32daa04c9d969e4e54042e3c5264d150e5ac70ad6282562cc8a1a34396e8836aa4543481c4511e7a96aa3f6ce7c8519bb5143b4895a4b3ed846318a34f101cc687dce67a03e7b852af1d6962d0cbd8a85e118ee99f2e11758e8d52a0cc530443bf3611886fe421886219a8b0fc7300c437c1686debba12759f970876118fa50e86fcc843e0c4320d9e66d8e6d5e6990a6cd46dabcce204d1b305375a1d5f871f4fa8481a38d377a95419a637eb2c1eb45c7a2d718e2287a85b1a4a70b0936347df6ea149545de99a70af0d9eb0bd2cc6463471f8c501ae1cf11f048ed2e3c658fcfaa3cce63e3719ee063ac47c663af2ef245ab2d6ad3d9e3adbb947f62189d91977f188b62e895056986779a3e67af2b4833e31c8a4b4ea48298292286c79a262fc13cf2f22f3be52c7a55419a229da20fbdfe4cf0808ac68c2a6ad024f16221b673ce3945979d2da40f7d063b631bc6188f8e71084dca7258d123c88b565d81e5b18f1045b705479701698e327cce667d3e7b0c2705cb39d33282d244a16dd570e7862f57159fb38fc8bf5d761a37cda46f2a8ad54c147de489bc71e49d622e6d1e03d2b40d1d7d505dfc396284c75ff4a4626b1ed3326a46fe49d13ef893027a8cab54b53a2bd659a100ffac571efb9ca7c7d877a9f35eb0c663672251c2049d1f8ffd840a601efb0a28c61e3b0c73e2fce038e978dc4587c763af5355bfab1ac4b2983ca65d75fc3c76186c85790caf0c7aec23c62ce69177e6a917c899e1c3d061c019638cf1286217c8b1fa9cbd05db04bb54837b7b6f7bd21894df237e3b3d997eefed43bbc6f8dbf7f6d22a19fdf66a56d1c6a83eeb3e3b0b4833e730677fa1ccbf4cf5d5bbce9cad8034f1af6c2286490bb3ab4d55e00225fbea744d203391cbccc1e79cbf747dce6118861985e829204d11843fcf0fe2887dc9997aec3a97d3e5b1f7e6ec78ec28480af318d6f22e0df5c0e3e76c450d4402f9ea8fca617263098c315d819c06611fb1731ef1193e016962116a2d5ef4166c9c181fcef0a1b3409ae1884d3041420a295b7dc65cd931f626860f0bc23e62dc58244d6c02d20ccbb43e675f8134330c77a96ed52b76c75efbfdd237ecbc5637ebc8d885f2fa6abdbe5baffd52bdb66869affdfe8ec8b84dd7e946bd765ba6cd5e5b293ba5e5b5b57aedf4b457cfa44bd76eaf68fb65c15ebb05fe78fda7157b7dda31edb6496b2da46bda6b8dc974ddc2f2ba7e55308d815adbb4139fd7387dd6a925bda5b7a8980a74ca5e3bd5217495ae3aea694f9a7aad995e47e9288b545d430991958576a4ea718ead12d3e3bc04a489cbc2e5c2e0e39c04a489cbcaf1f6d593df7b5f9df9ed2320cd8db376fded22c84df9c9c897bf89f99b8780346f39eafaceed371ff76defcdabbe73df76113e4f920e02d224e952f695fe01d22cd1ce48780ae645c7a25711232fba0aa429eea29bd3277d8bee01d2dcb7136caf820545a75757eeed55a4ec6fbcb3acc15b3789cb78984c2c9bc922e4212d3ee721639fadb03e1359f1d93b409a390fe0cc979d0358cc2ed5601003ff1cfad388833f8f1e077a3c26481821361e7b0921f3d83790b194da577df86bab6ac8db1cdb5c037b67c0caf6f5a7ed43b0f7fa31e6c3d0f7d38740801f3a067438b2c77e024bd9a51c45e503cf8f8e47bf00698e38dbdf634fc10297eceb560db19f2b5d7228e0211f2e1e7b78ec83eab1574017622e56a678c85314189bc0951e1e4c503d91400755f89011e861060281b040099df047cd637f40fd099921c30ea73976d2a005aac29573ce3f2bda0139ca8b8792c78eb13780a2b9411b0b6316a4c305e84a130f2568788c9d0158ae903b9a3cc6be808c69d4142157b2d890874d9a1c7fa8043b985e3ba21e6337c107284d102a4d9227486ed032f3212c8134f51495c78eb1fb481387d90b4b90a21d4eb3bd338c951e8f69f2393b09d2cc9887e6b5bb4e83239773ce5a0a287b8c3d019886677604b5ce8a8cc920e2f3f3da1d042f7e44126ae82390669825421c5b083a6670f0d8114037e0a2e647d39320245dd2aeacc839e79029c71b013cf6a5105719439473cea1520eaac78eb11f808ac191f3a3210b4c8ca83e5a60b79c733693e614d507008f7d44ded571f3a3451541386cf0f169229473ceb932a0ea7c61761c3c0c90c32f63ce398705f0c2d1e27187c74e00d2c4a167ec81151d63982475f5d83108a48957b84bf8ec4cd786ec520d521e5fabd56a39eacc995e9ed764bca07cf5f08aa2e7b50f80347518f46917f10169d6f0d95dcabf9dab4c89d929fff22f376d01d42f119f3d004e560987d00a74372f3bf1f22f6a7fcdd4a71d8934b5d793aaa3c7decb4e27ee12ae0236d9a51ab44f7fcbea5990bfd74ffbfb9ba3ce0a456bab4afd4221a6489e2d2c7cb8f9e23b2bd89e3f2b7029ff2c52752c1535aac6df7b36e86c0f9598375dcef8ce3a85f62fd8257c6691aa9f013aa9d8d87711e1fa1b260b5bc26416a902bffa69b48481f6a87793dcfc1df117ea4520321b337494a1e13b996c78ab24365e8d317260bce022f3c477f5fcf56a667bedf41c3a8d8cfe3c2ac2158022758c50b96af1da3de83ddeb25f45c88179ed1dd8cf5276096fd5782706fbea514576bce8d82aed5e740090a618d45b5f3dc7286bb0c9da8884f9bdfd8834b7b8746adf7b877bcfd9966f6f34bb94a34e0ce8ab5b997d183a07a419ee1b5e3b0f97d9a51c85cdaca67c0ec067df91660e6bd0f6aaddfafdbe56b3b3b3dfef4fcdab6735286697f20faf19d267c463f7fcbb4b396a6a6cca5983f897f6f59ee90daa1e57dd257c7691aa57bd07293696a0b972e4ca559e2a670a419a7a4819109bcb98ce48e8cdfe3abe43bcfe7a51c9c5ab43ad1f84ecf8ebf83a11ed7026e5e7828d1d1834cece84aa8e347590afbf8eaf6b50ab7ebf5f8c7bef2d497825a8263b88907941c6c477f1786133861eb27720cd0c803f6d43624708f8f38311239cf46bcb878dd732bceef2a1e6f58fdf6bf71f62afbd0784c86b4f62b24ab40b080dafbbaa9abcee0ad2f4da8780816a798a0355d9dfeb4267bfdfefc535e1de1bdec0230aacc8932137f8ee9dbff7e69b23cdfbb4cb9f4323fe343af2f2e7070af873c46ba7537aaf7df368135ed7ecaafe0e5d22bf9777aba88cfdbd43f7badde2e05eb7c02a3efe8a9dd041e50a8bd70d70eedc311bb44a39bf6ecd8eeeade2e6efd07da1a60d171f55f444dd33f7faa5ba00b8d7cad5dfa27bef07bf7ec36c07f77a953ddf8101be03b75448b3832e31b4fff0c185aab4322f334abec8f07d30a3a5aba2e40130e201e0760a69024048484848484848c8ad14d214a262e78f8edc4621cd23a3cf393dfd73bd5cce77cecb9ceba0245189f21c70e0f6096972c0abe5aee1794acf73eb843479444444446e9b902691d692dfeddc6691e6cedddd2d13d2f429681f2284db25a4198257cb2de54124e041b855429a204892244992c44a9ae2f446466e9390a691917fceb99c73a92bcb6e9190669642e48b8adc1e21cd22a3dffebbf7dbe90c3101bf5db7e3b7db2b6b84346f9435bfc1066e8b90e60649b4c80f6471c142e223ca0d3a7cbacc6bd73d91200e9af2d1fa83109ca67db42e0a1e854dc9a06347904c912a96b12e910e208cd53524d46b349d73edf6c928f8c4a6b56595e8837092c58ad9b1200d719b583053078aca4b141127df799dc8fc79a3a6ac9210d5067a5e5f28330033039831e0139a1d750c985572d77ec3ec8eec4b99ad924ad33547cceacb77dea018ed37ed879b9ca2a0b0d489a74e5c7595c5819f180ade8af2e5f5d7eb3d43664899a307c9540edf89c15e03b5e3b1bbb47dda319955a2af8ffcc465af71f0b57f4549f247476e8990e6919be78003b756a4c9011418cfe3b91d429a3c29bfdbb915429abbaf274fdeddc3bcbb0d429aeea4cd6fb081db2ad2dc4048c8b79097426e8190a65088106e7f90660827401e8463abb4c18370eb833441787923c7466ea976932a9fcbe5c07cce6d0fd2cc91594f4f925f596e9e74cb8334492f25411ad40234233313840b9efa65071a3162f736d92efe2a69f37749d65f264d7f999899f2c20a2454e5c70ed60d3eaeea8c857d76abe30babc61715b9cdb1936cf90f08f80f6e7190e687af244e4f44e4568a34896e9c3d55f1369b6f9b97369bbbed26bd799b6d4c11209b3d55b87c27d3dbbcd86c7e822ddb903c01e1b35b1ba4993dd0b3f7da91f878edb60669ea235d0af8eb36ca4291a6edc8d4eb746e6990a6ee088c2fcbb2749d55d25eba91bd5e965767fe16e0afdb19a479b5d6daed13696a2b83344b23775e03c71ab88d419a1a1849f3381c8a26155f6281aa40b5f1e166b88e73231cce7b77a946fd7e3f183e9c46a3c568327a033dc26ba75f56483e587d11f1f145e40ed75711234d5ebb85419ada9ebd1a095d6977e8fcc88265cb0c2f3d7c5786bfaefbf1d793acaafeba75a2606f5f90266e8894f7e0d8835b17a4e9a1c987b80fbb1c01f43b22439d1a6d7c21d887ae33d2696e6197ed0b6d42b47c48cb5410e68b97a03d5a9450f19d34c80506abb43df418c8af214670b72e1f4d2c847ce98155b7845eb1705f42c63cce31ce6d0b7aefbdae3b7b9274cb8234c920c1dfdbf7f672bb5d419a3bc8d687b7b9550186435594a22a60901fafddfebeaab03ee72651589c7142444a13175ffefaec751069e62a8834436af61d1c77f01a88343b7c89fd389a10670b4d178b3738e0f846af1f5de761129e1f47d01aac8a4081c5491333c87732758d5e62d4e30844cd8fb9d1e95d82c11133aa21554f58437c5ca3c37097b66ffcf18ee305b2e2efbd4092fcf50a88eb34ba4212f3faeb878d3f1ede409af9cb478b0f43af7e48334c23cd9152f921c756a9f621cda1aeb0b2af7dcd77cdcb9ad7dc73929eaf8da88150f3122784b5da17d591af95b59306bf068355ba5ef3186abb56f341bfb7573ea4b9afe31e12296cf2ccb8c3c587ef6efdf5ba87342f1aa20fbda289651008c2f2860e9618487e5a5e7bb5813475d6e79aa79e55fd28eeae8f27ead9eb9967157737a7a5ce3c330ebc412e6e26151e2b36eee0a1c3220b9e40818428a01b47b482bc8003e707963b653a056c392206478fb1af4157ecc830a630d2a5cda0b09f204142ac806006a836c398991f408c74e143a5ca6bd7815007ea56c6a969860e1a513cd65021a1061faff598ae185488402de9934647029d233713ae64e4c813260f14a029c17afa88773b8c0589bdd6bb274035350c61d374c6a7a5bc76ddd01c5ae27b45ca3b32e524cad58c33623e1de5b5e61234e5b5f62a673ffd38649c385ffd24e7bc25cbcec8b1b7e4af098536bf30315b8a3ce5f19da413943fc9a82835089211e7d7244897ef24a79efc495655a0470c346879ee8c89e13bc92b277f92596f9dd422b748b0b72490147b13e8cda0b701223bb34d518918a482ce8b2f34b090e23b6d4dfeb45da5b8c135688c95aa3f78c67ca72deb4f1b9e1b3d66a022220396efb431f9d36613b3ad795bd6e3c69fb6a0cdac8d0d471b1d6f9302da9c6c5923942de048163c4b3b6dbfb7b6a635a392352313db9f23161eabde8e576fbd06560ba372bcb688e981d2d211f49db5257fd6c66aa0e9b951e7298c93efac9129f9b3167ceb42a0cc88b5c9f2d3c777d6b0feacfd46a731ea1ca7462a34b52d68babcad7de1aa9ad6592313cba4942ca9c12c8e0d4aa47ca798e4cfda2feaadd7a66a5435ab1ad659cb7a5b8362466463466c33fe29ae79ebf414c3de8a626974de02827107c91418111c66797ca7f84372c506d99e31403eb2f84e31eac89fe25496a8256e896064f690e9f376a3455da41a75f6d6779454d5ce5281153a2dd8543113f3e23bf7d59f1b6c03c7ce4da6c19fbb0cb86700a1deeea7b759bfb7fb0a8b8c0b33273140e05c4df19da1913f432d2e348ea4811ab3b5c677865b45fe0c534cf161e70f96b3182df8f8ce90c89f21995522dd7a586616a285696fff0c017d09897c31f236b48a0aa54a3f43aab7aeb7bce8af142ce8e089520536a8cd11dfa9c1acfed4c011ce5cb5c8a3824c8e26dfa987fca9a917ad40565766a0828685efd442fed4676956c906286c0a9fb0682c58b4bcd557b674d65badf5d6f3585e130c719615b6644b1faf2adf9983fc99d3a2b494a6d25654fed4576f5d6329c965949c79b1ac0c9605c4683f117a6ca05d49abf1648cefcc4e557fe6a87c6595b032947c05c99f79eb6dfef261c7079eb74eab57393d9179c95346cd162e717c278e02f2279e6201a5054c9c3e6684f84e5cf5e34f1cb6620d8bb42b44a65af84e9ce5c33adefab2380c8be131bc86076ec1e3c55b6f42fb9c9f17d05bbf553dde5eab9b95c24aa0165dcc00b29243e63baf16d59f77eb02ef9a5b76cddeb6b83ebe0590bf544e37ca6ad92b60f40d9e3b5c68776c10d4e53b2db0c79f76cc9edda5edbbe775ba4f2cb051f64c797b5a28305c65bdd8a52146165ad920ae30beb38ef1f8b3925d3d09a486aa4d173e7e7c670dee908224491c206e6cfc41f39d356deac94abda5dad6291561041484ea67fdf271c27c0d7b5bb77e056a5666c9978b4132a8c8e3ab3afea4694e53351f941d37fc59b5de5a1f0115c10214845ae6ab9f22a021d0b727eed2898b844becb961ca9a32b432317c36c75bd7dd256a07ce579d266469a868f1e178ebbdbb94e20ace921a5462589909faacd45beb269cf0b5034dbff55b79bbdd6e4e7ddfbcbcdd6e42bc5b49e3b898f3389cd732d2c491918943a2a0175f14c58a26e52b0438b7dbcdeb1bd2bcb9214d512c4551c4c12892c5eaec69cf931b615c4ab2caf4e75057943abb2e294f6d74c01b502c52f6a228e268b8e570796eb5b2e9b3b4860b151c3711a7460ce8419aad9be82688a2288aa2973a1183d4d040064ccb0b994fb481852b6f373157d190a638566f399c288a6279bb8979eacc18228fc3793593735114455114abbcc8e54ab10c698a62d0fe4680bf791523cd5b55ce47bdec4975f250ceb9cae7ecbbfce16e4ecfa1bf19fdcdc1be24fded0616e86f328cf99b5732a479fbdd70bf9bd731a479931a13c5232e72c42e2f5eecd2e64530272f7a15439ae24fbcfd7ec01a8634f38dcaaf030e0c972607f8225211dcf4e8f386cf111d5fbe5ce3330956b53019b65811b125e8a5a6d0027564cb93341bcab489f2b2c4967f182bcd802d0d21cb7013f055e6c54060baea3427520b4879d187869c33357ebe0cd50250c71a255f628242688839b979c9cb3fdbab4eb71ced82f3ca853471e2d08b462f76cd795114bda4bcf865638bdf8a70f8f222cdb28b095397ce8766e494b8b6b8c2fc8d4c8bb85f14dd84288a5edea5144adae86133684b4992333e71c68ba2e8495649f411254e06fad56f5eb390e66d4d129a11b2647d769c9fb4bcd9caf279eb8e175797cf5eb190668e2a6f381292780952e72a8f8fa730331c4a5e0d2f9c3850ed3214f5de7befbd43ed63e3f42b9372ce694262b621cd22d1d7683f8b44dfd6a1719f1ccd29873dbfbebb9acc927493bd7559bc91a61da9843632b091ac016d57e3d590ce4d550d8e9308276d335925aa23179291857a4c6bad755955d65a7b91fd5eebd08d133ecb6192dbded151af843757576b2f3757afb576233fd2496e82b6d495d0266d83a75d2aca845eec3dfe725ba75d8db55d53a36287433a2d5a22ae51ea34fda349d81f2f6974900923e87ac9a1180497a96fbcf704431d23cb8687747da674da9a5ad3150e6038cced0c4bddd1526148d978d095cfd4454ad3624b92b3635c29ae331b8676ceb9ec032681282aaabc6c90ba8125505a568e2102601c2f2550726c0856405a5a18c60da9173c23bb4cd28034ed28e889ae65adb57e11357aa829e1e014ec2088c816f2091a1b120444e7b6385ccf21965ef6fca8a7022814a571a5ebca215dd3582e876228c849bc7dceb9e747bd3353e79c4351d06f93fe020cd747b4ad00def2e89185165947d7867425acf8d9ca42b184a6dfb86647d5f4cdb94c1896d0624af412d2433a17582ea06cd21459f0062a4f9bb03758c27cf9cf67a7b3cf3056b848ea7d52d6380ca964dfa0aab0091ed201b53652bbbf341c63c388ba22106d4b1740ad754e621a913422e92e39161e366b9da435162cac03e9d83b67a72db10427b0128b5318282a2c8185170c275b5a9418e1035cecbd936c6fa468885a236986429ef60dc1da12a810d096884586fe03b6df80e9c81a9053ce6fdaccf833652390d31b4137ec90ee06a78b44e1d4c0e187ec22d10da7080dadb59faa8b4437951eddc3d5f55b71e3a24728b59a769bd61acd58cb9273d639e730e73c661f1a27345a1a0b8da7ad431dea8cc62be79c75ceb9d48d8d81d970c4ad45d2b461c825a7ce877aff2e520b1c399cc3e35626e9ca21dd989ce09b1c66ae38d95376831b3d27c79c2b7c7b7ed443920300e682acca142b547ef8098e3648d1790e96db2460184b2b840c25311a6099913127ac432d012b2bb7a34f0d429cb26400d39464e1b4d8e09ae3c64b48e2d427909012a8204923723b92f09f5acd9aba83c28ca56ee84c89e546e7a1217a2e9bf0b83de9c2b15ad61b28d7bbf46212e45066014930c74a8b963e44cce8f0f1ca1a74f36a3223d499cc8f5c1cdb7bdb311c960918f6ba618748094bc6a46ce4b8b2a58e0a18983dda6a61ada1c91d6b254c391bb2bd704adafd034357eae82e87b8f46861275dab718da5e57628d6bb028aa4996bfa85b8a916618c3b6bbac32357e20e9354b1d848ce90f0612165cbba724877242d0cbf0452e15435e29e1ff59004c5e8d943464c89952ab1ba27098d9ce4c68c241adcd275e590eec82f776d8ba40ae317e50cb75abaae1cd21db9213eec4a02e3c3300cc3ac43245b21179ab1172f80f869d70ba70e6744d236fad9b550749b288abced646c0cc3103f49f2a2e644ff9eb63623b38875e590ce49960e7f4f3aef37b5eb65cf8f7a4d8039f4133ef9259df950b449ce943482c949144eba4ba508d60bc3b0c9d993e89be7bd23d14f3f72a4274f1f86611826d95e0d7935af67425e579656e84dae2e127dd1edde8da0420655e48c122a46f4f842b40fbd24fb30749d9d0fc350e75e5656d2089bcdc9d079edab8adbe2003e8539bbc8dbbc0c0c3d24cd700d141ed22dd11b479d1b172beae6edc30ee9a62c12adda4cae2c127d5cde25da834715c39ab7b37e594e57eb5e6bed43aeb32c12fdac44cbda52e74b027691e863af25add1a98281469ca3022733683be6d880878b0d545d48924099dde04386367a06e97006175b35177bcac2b03a3490f8c12f9a5890c04855193b5f59c256e4f1d3f5a5858ca3302836392fbac2a49e7cda15f6a246652809093d4f4ac22221014fb51c3406f9b1ca7e8e40852470f9d11a6390f0d9cbec434d4364b7312ef225e1d6eed568637ffb48fd75ba6b346818aad54b2f2d0e79dbf6aa9823faea9847eda5d567ad1d726483475a9631676cf8846d39bb49b44e963218150f99dc1754e692858ece82a749ec65f9c295408c8e12ab387dfc8c553c7cd67c52ed6957962a5564f8458826f42a3326f42a63e5c9a75e6596d46992678d9721808ea8b8c3e1ce549595253cd8d8814016103a5e5c44a55d31abc0961562ac6465518952c7eb8b9daf3df5fa02471b09f104a8cac8e8e022a305950fd7f038ca4b697b5409b031a70a861d327eb67c978e179819435e60a8c0d0b0827498d484052aa8c28f531c5f0ebab9ca6e94c4c0f84cc813a273a8c330c77e61e4e6077e513e21f3d7f1d6e9c9788e6af5b2060965d65afb9055daaf5da7353eb3a997188f30c4532f3280fef6d48bcc9dd2a219cb4d97ac63c79e4212ed338359162032526074d43935859620101f5fb8a2087221e7cf9ed4c5b19ff6d3d3d731504e1f8e9a6aede20e6b5a7491179ab848a19fa2dbf4ae054af6da4751f45d092a22b4f1f65680f504903082082120a02479425668b7a474801106280001723b100620e203010400c9963b0f3a00c011073c1fadb5d66eb7f9deb647e22285a268e3ed7177eeaddf3e8abb8d4591b7cf5df59b77b68029dde1cef60e7718e2ee5410a86b1ead206cc73bea7b77e2cc1e7bc8c3056d0f370077a782805de31ddee1ce6c0f3ba521dd65ed61cef4f2b6486bf342a6cbb71af03183490e2d7ce480f15d9e89938e99b074f68f389b557a0afcb1daec8e7e88387ff6be9679f0b4faae5e4e000b0e3a5f6b869c19f3a5d0a20a8ab133a52c8b1e5f751214f8246c0a5b2dd5b5bb62f171ee31d1e3dd63a4bff1486cedd9cffd7587fa62d12fafc884c823c0d70fedfd315e3e384a29a53dd75d24ea7ceeb96d3585adb78e06f470c1f2440a9b1a36e0f8a6dca8214f571f2e2e3efae629a00323aac09dc1a9c0e1c14e7f5ba5aa643d3bddbca2ea94b4cbec43326e8ce10fa7700c77ba306a8528c329d0671fd2e59cb3ce78e3aa822b50d885d2f3242c09bba1d45cd1b1514c95a916e8981a5d928e294997b477994486c17e6fdfd8ab1eefb262ecb887f1d55d9df5ba2ddef8aa96650eac277aea5543552dcbb296b52c31c6b83cfb5d6b89cb729725d9ef246cabd59575ebf025fbadc315ef9af4bbd69ec5b6ea77adb50237d3635cbf92c1df9fb36a0d5ffddce0a983a022d42005a13a1dc1cd9f3d0e00d1e00748143f2beef8a81bd110ac120a7acfc2cd45a74ebddcd429f524ab64dd469d239eaab061ec3ac7bd0f1e8f2061e3b10d83d1300f165f713df68083694d72d5e949e767959a12f4d8eaf195c59242e3f188972af0f7fbcdf09d35ec711523f3a267357b8cf618d063b73f2c2e1edba6c7d6c9a86acce31163a7a7c57a6ca160b75b3aac3cb65f8fc1c21e5bb1c7d82d999ec7b6ecb10d9a3dde61bf3f308fb1d37d7a8c9dbef8bd97fcd193070ccb958e2cdf26fbbddd686fa991cb9196464b151a505b769bbdf7de22e4370d6e87c12a7df0ed31346daf51567e73d84eb7d12ef2ed156b43f97d654b942f2a2a2a727b86348bba607cf90ffa3fe0cc1011111111111111b92d439a44bc5a265d77f72d2adcb734bdbb15234d27439afbabcaef766ec790e6ee4b8990909090bb9090077a17b3bb9cf8f9bdf7760b24cd1d863485bce07c88106ec1906688ae334f9224e94e92a4f72ee9057c92747a973a40c38d266d7cac509385a481f4125689c8493f81142249a1a117721b5e4848c86bc70bb9fd429a425d664f444474f4446ec34893a86be8f73efafdc10837bf1d6fdf457e7b19fced3aae3ebfbdd735c40b139bf777dfeea5bb9d81345d06d224b7983c08106ec148138499cfd977f632bb5166f2817e015343983c6e70f0e0e23b99d894b04aa4673fe1830a8174990eca0e43fd15652f9fb31016889cb76e7cee62e586cb9914352c68f8d6e49c43e4bc55e4b3989d66eb7497b62fd3adaca5ec438470db85344370214de7d552a705c78300e1760b6982101212f252c8ed17690a6591e18b8adc7a91661116b3fff0c16d17697e20499274cb459ae41716aa272272bb459a444f483a6863b66698325556e5db6a7ebbd562b390663ef2468e8ddc62214da32b4f9f03f139372f8a98d5003643471e5f2ecde7726e648facd2f69cf7726e05f87bbbbd429afbcb8aad22a5ccdf7bb75f372a4afbcb54e20423ae34311b5de3628b933b686ecc40a3a27918620071a3a6fe7ab8f52ac499bf1ceebdee37a55aa8e42b584a9b183a64341a00003316002018100e0985a2d1380ff430f70614000d6bb250724c1d49c36990e4284619639031861060008880c80c116d03b8f42047d89a5fdd4a57ddbca9c2d88fbde769f14606c3f4e703132089d902c9e312cd2be6406335692fdb5e2a1c331907c27d43b0217accb7b7ab298c2e42639922670a89ae52716f974169df855f079f7dcfe87284ea5425ac975edc7b5c6ff553a0d91e4043c8ac044672b8056c18c6e1ff4fcd14e2f10827d50212dabe7f89910c328b3fb31a2cd9ad77fa4ed60759118e3d253e1f60f4fe9a92293fc3da6de5fd5f84b3e526d63d5f9d131e2bf9c61643caed6e9e2188f281045294702f224aec3e7fec5346912e5f7f3bc33e3cd5a7d662827c3a02e87c03baf59596b3fb5dddf90a1432c63b2f2a6fe700173d74b0ed80df2fc4a822fe711ddaf6d24fc6da24b76fc3ea241947cb172f0c8f222bc2b7123d220b121684223556e63c0522358053c154da36400f9811fdf816ed1b52f629f08ebd253778a2e1e531e3455016e39d63a8dca09fc5e37664be0caac19a621bbf6951d776e928814426245d2bac10423d4e8e4e83be6aadca8f4faa40afd5656227794f040180967bbddf154625cd64add338b4b0540524835ecb71aa5e4d5711f0f24f4ac4064b1b4429599860b2af802516ad0806ead021596413cefe1bc6c8cb356b362310635f7ccb51feb38b11236716e1947f7db067fa91842873db58c1d670fa0ded55cb1dcd2586c0c9e29a47c4a3c3cbc84e43ab0fc1fe10340a4111fb6ee7d6c7c5a5f43ccf75a48da5b690a84fb496ebbd009cba0e0971a7d2bf75e6400e3695d1d7e976ef7cf3e0612b5431f72b40017a877a832dcb51a5605b80e70556850f62f0ea433170da124244a46ba97598391a501d4ff2bcb8c921a6cc4bbbb10c2de54329da62e9f8d7f933047720aac3729faafff89d6007fc3ea4e55517699e11aacfcaa451dd575e0cd1b7b900354c62be8ed52a75af524294d5ef0318d841ac3610d2352c29120de6b03801c545ead21d87371229e198e7f01a41422fcdfb448896012aa81afddd0ff3d614793c80b37a52cde2617bb1f35c518aedd3f909cfc2c5525429e85f4fcc89c21f9303edd2591833eeb07fc1bccbd7951ae63c69be9e35446f5a6dff59e52f05987a6deb20d65dd1110ef42e3f07fcbf1c021995cbb96d3bcf2aa56ed2ac323e621845ff73cea4b8945fe16a53ed8cb12701f6f99c9b2e1aa7763cbdbd1a924233af64ee5a1157a46df2523bf01e793a3e2be07c50fa4b5e999377fa2fbde5844e7a53a0d8a1645fff3d6a733dd4b1e14cfb8e2b03ee10d45e3e67fe570e41b67239f27f729cb0ff6dcbab73e4595470d0165f03f6e197f837f947cea0f6930696d3cbd4c7598eeecc4743b5ba0e4817f8c3b9cc9ab0bf5b9b57e70421b8f2b5ef0745720a7b43a5b1d60e8a19330e609806f7aeb63d8bd3e6251cd6583c9df236b39c2eddeec5d7a95ea52d8da269958e28ad2b69db2a75807b969602bdf6527aa6fff726e14f5f91d6ad385553ebb68d5b7e40ef2b2fb667296394a3f4d9ba1b6b8364606a96d66acb05505d8d624546fca3f7f46eef1215ad4b669061f7f5f50690010a505459806b1fe20859e7ff1cac2ec69f122103660052e154bddbf78576e2c082945e6726c6632910ea63410e42cd9f20cf1edb4230e6cdbe8febbec7414ef68061ff029e18e4286e8167bf655fb1e2ad337509c1b88ce4fbe5010d15ede5ffcea4268d40d944858f5a8a9daa53abc867368dae801fbfcdc4915f13b515db5ecab09048bf4cfb1dd831bd248976e9066523ff0b002b6b768da540726ed0891cbb5114d194c9577894508e43b47de4c26805f1f7d4dd6d0ac3e35577466390f06b8b6a958d85c7516290565add3ae8cb60e943b4bb38cec3b0b522b8f969a3c88c190ef764d4f850cc2d3c275ed1d013dd87e5b91e0668bc93a91bb240bcc01acca7bc56f2888a4e3ede482e450319b1ee6081feb4d228b51b28d11892031f58025d19abd6852802bb9a4c1b0ff275ecf902c41046f99b7033bd578aa853484b08e468148f9947c241c03bdad10e1ff3d3486e382426140dfa25e55e404dd4736bfd25426aacc184420309bdad42c3b0d200c7a3d8bc1881056f8ae275dfafcdbef0872080bdb46e81129d815bdaa6b16e11f35aba2748dff4786dc71a699b5619b083aeeafcb25e58d15682a0a53179c94cd2099a76218c302bc6d9584d45996a857c2816f906820bad375f15dbce364a9a091a7254f447b883a41b846d97e311c448428af27ce74f089037f6d55fa793bd75d3ba02cfaff8313abf9e392dae0248fc8a803577dd4504c1424c483ec831978eb5073970cc3c3a08844d9b68e377034849711292de329de8b8ca045308a0e432898944e8017e75a261247f7430eb1b019c6500404de8566e912c47222b039d066b05baeb10f5862edc48d0d1e1dcfafcbb39e5094bf8ad18eb542f97477c4833dcdc3de2fdc92757a1c792c04df7a3a8f8e51105cea1a06fd927b27cca0174d8a59f894c552805679e9742f4415188ee4eca1168d2cf68f6d0d5261cad415929567683230963ad49833d98614312eb6922960d964882d50a9241acf7d80733439ebdfedb20d83c6a9283be094d5231e5a7ffb47f23cdfcc0608f1b55fc1f71c51d10ada9bc10127b5a76214c449c076f0899f234f6deea3ab985e9f930d8eacb7aa9805b58b4dea015e45801125e6583856c43e314ee991658f87d8f30f34884b5382b9c0f8e42ab4234e8ac0adfebb1b0dcee2433820675820947fa1246b5dfa619ad51ac146e22c219684f6774512ebd4129fd540edcc032a7fdb2a7e7db2c2b4cb318518a7c729069d65639139ef8902563b96bcab364fc1a4c5b35947103d6f3164a0b60eb583707c0e84a3262b35a421bd2ce5f235d78b4b56d2d802399ede50f48e616aff0cb410a3d1e3e86f5299161169cf972ffd65c5590ac3d53b00dfc128fcbda3889b78fe4fbf451161ff02712c86e5a9b33ad851eaa413aaa8acf1617998657843b5a0d5b316d2bd8bbb4dd58fa91cebce560cd2c30b6c02e7c9b14f65251e615278be06bd2708006928b46fdc29ab9cb0032a4278278796c42ce96162aea480ad7234d98d43c1f34aab4811f5bca41bfcdca256eae39942a9ddd4b88a9a1e10a0d8a634cb45bb1679f20c099c6ff721f757be42e52d9bf4fd2fa6fd06f924be680c41d42f5382cc020134b8c60acb62c12d3ecac9650df6e5ef0ff24da72f98d71cb452041ab6cac14943807895262be2224a844352b60f8ebaf20f0b985d9ac7a8047e49f8dc87f8e80557d70a806e1023578756ec9ce2c620309d79f593fd225db4a2f9c8a3d4bc296d87dcc3802c9f6340721e05eb7e46334ff9674ddf3efe2d8d92461fd6978d5b4357b7561dbba5f4e4203cdc5fb38621164e1b66988bb82939de9f6867a55a04603601335bbd7d226eea74eb6f792799a5f4b949de04ab5c00fe5afee292391d09d0eb7d43c50c3a5d59cc388f9e531cc8557929d856be85aac4719830d515697906472cb05ea56b53890863fe114eb76395d48077033ce3c657506774c8f578722516892c419d295879f2e29defb41653377e0f768b904154f79259984315b16925cfa898e4f3b36cf9fa2fed4a9a2d2b6c886fb5e4363bd8c416bc5262367c7890c568ed3cac85cecc9887f832c5b30adc99edfd754a5b0f860bc8992678b508f8f1b48b2e321b0767ef95a092985e55502ed78dbfa661212e04064cf76e82bf599b3522fd7293b0db82c8d12a9f3b3f5c6b90eebd90776274e0c8cd8d8971fda26b0cf2689615dd235a2b5ad4b099ddf0b64900ec865297b35e4b4eae1a809fec0d363d11554dac8bc9836aa9169c316a6a30321d956ed6bc22d85fcdd824fd39ced0ad4d44b4f862b42d1442de97263f14bdcfe3a5e9b9704e74fe979893ab8419fba87dc1c6523bc7955bd0997e002399527194c9caa6ad2e135557993b0b06423fc4ce574791c86d4b77a2b0187c78dd77689202b66012917f24d5f921d1c23ea134caabad773ae416f9cb13012782c9a576f3da34a7ed9b69b33ac711d3c7e9f917a40c33464d056044fca797f2fe056d10781655b81681f97bdbfca082864fb6948a0e121a05618d8f3dc119181d5b33e484d5afd9d5dbec498ed8cc0ff1b2531b8770f81c0cd557f34cb44fa3ae5613a3b8a765ca304e7b8e7e753b351583ab151498b77ab0e507b182723cecab57bd88710cba9124640d3753fa6a510d78d03ac44e233fb5b6ed18e23aa83d4713b4b6bec3c4a978f7d608641c9c001a418c4941c5716b757d12c319c148493d01783556d584a9e817f878e34d059fcf7a237fb9e57a04bcfe2cb1866d413fdc75dc9b31c981b79f721b53deb493d43624f04039995132a7a7ca98a6c7089c63055ffd229e85e164c6ac5e98ee151990b5209c68205f089d800b5492a16918d93c43591c0820c6141d5fbaa4aa092c26f10f413081e54e4a0e661a2eaab66bbf49430ed36bdc50802bed8103a8486b1fe518c2cab44de973f47211c3ae4bd28bb00a6d3bbc1ee7f15d918de3b6680b8418dd25081a481ddadb4fc139c51da3cf0fc1330d68465f09ae347150d573a5fd33e2662b96dab88c9603f30a25788166149c1107d12d55821b6f91d43cbf14710626ecc36ab7194ac2da4c68ee3f85ef629ba81c5f8516d7d144037ba74395bcd9f992cddc42324a36d980e89fa996a645c5e6e1bcad64a40c939db8800dd9ca5d2ff52ae46e8c850a0b5a30ace83e14d3ba29e900f43655fe017099990ae6b22d5d758d385f883f2944449c91f6ecacf19ae6e27867f31379f95148f8fe2091b33072d55e15aceba84a78a64ab1d37282853ec77ab005ac5a183dead1177bb4996a7097f9141e3e54c933430dd4bb33658a8e483d6d6a28c81d37d245d12d08810f8f4982682f2ad922f6ae83fbf377ebbc0ca2f9937288891f0645e6b09a73677d89bfad634595e2d1235764c17810b898224b3b2a73ec475bdc8daa2f19b009d3e72b9caa185af293d0c3102eacb31c471e4483b798c48690dd1e3b091ebaaf9411a4e43d03699fe7caf6d24501a15f8f7a1929d74d3d98ec19b579f5f60bbb271686499cc3240125df72bc7195e12a81374d6539d6446de904dde7ca8ed347fd08349e87cd812faf2108a80f4340d14fa58cddf6d5545f1104687522969067c167c9e1d74e0bc923e810f101e9f576a87b829251e68c889b7340e242abf7a75e382bd2ccf2b7b1fe96a47c6f1d4c1807d8013280929e8160a5417988b487a0830a1ca9bcf95ca823ebd690fae2653ef19f60ae245d065816ecc27c875d243d13bc94647b91869ca52b2fbe1652653f6fae4621c2a684deddf893bfcdc59175afe038e4e2f525323160640dfd8b7898d9176236cca5f610f726227e0aada4e396e2833e26e2ad6bd22f23f6b20e44896308d2e3c3de6449fdbfc3a26fa98433970290fa0c8f40b1a7af5d28a1230e11a81bc7be9cddb6d64ac41c0e7eec265b7f3d3ec14ea7cadceaa5e91218a5552c429d373d338dc77d2a0bfbb686ca43b68ccd2d632e95bdfab427d9d0c47c3b9abdd6c3d611a264102416de541162504e333e400547b5a70761c630b7cd74264608b459a8057dd141074a4433ac8e89ad54cad2571b141904642cca637a324e38cfaed2064e7344cad6ecfe859c1febed79d61d8dbab42baddc6b0989e2a9807d2f35cc0b913f41aa49375e9b5a0db3e2db38943130669e7b82cddd9f42f25d400b4abee2c38603b9a1cfd3204eba36516ccc68028a9ab46c4d226c2649b0e0e98a2717439f949e2a9969d6b08ccf6f350f56fb4934c0ecc5cfc6af307dbd1015cf1c6485e155226ac37445a8072af0ac157aaa89665fac477618caf9d991acf89e49b869161bf8500febf97151f0a72d1f5b6567baa25c2018031b507bda21b4c94514a52a02e3d9b8740fd38624cea55bc671b3fb4cc4c28d754705330797c9c5a36b7e1f75142366314b5b92cd427f3067178b759ddc97635ce7b64528cbba873c9864c0b02ffdf67b69f4444a090ba70cd1c08499caaa70b74cfc920b955f46dc8cc3fa33849ceb026361ba796e0488119402826e663f877a48acc298bd058d96e576442564f10eecdb8a75a5d42aa7394eae6ec075dda4f6968e6a27bec2cf4381f718805d172ddb28334dcb0b88f349795e63b2fbac9ae5b2c4acdf17a0240f7c0c3e090665eebf34e4eb82d7082814e5b0a2bdd077c7bee2eb22d8fa065f11c3cf67bfdc4b1848641bab01a088fe8adb2c3f9fa67f7aa4b3b22ce2634f284b8227b6a6c0e17dde8d3733b8c2abad19967912ed98ac51afe3c9950644facd88806fd12fda3b1111d0009b69bbf4bed302396f9e9a2c3de95f424e6c647f930aea47eed1a4b82a26983999d103215b3427bff00d58c88fd802cdb955c9a5eaf355b7b17c7578efb7ca4ecdeb821109aaa70348ee74866eae3b0e91db003d883064c2ae1f800ce5e114ee931f807dafd91e5860fa41b81a8e206acbfce997ff8cb4d1a08fd9a0839d232c593a7a04d620371fd95e6da35108bd44d40b22b41f9d0da708c28ad632072e365c89086f49bd1d0ec19e8ef071c580f929dc1ff1b1f0837ced1d7db94df6c59885d5fb77d2bfaee65afb73319e0241064db333c70a16266e9aeb759e186a3d4abb0ffb13173cb188da8d64d0c6a15eaf8ac0cd727fb00758e007230f3c6eed0e2cc81b74fbfff238a5ad6261b71a6ee4edd137f3ee0d7409bdfcd602cb0ffc03636829c7cf46bb746e7b5a21227631bb7ef78a1049e4859102a67fec5dd442f0699120aae6696ff01d6305cf5f788e01324925528d6dadaf8d74904628c075a6a0c89c5d3d887bccea5d68ac29875b4544ee4acc5f08a1db92c3b795ae751d0e6a1bceb5c884b1326f9bb305a6f9b5a48cd13ee826ca0e2575cf132eede2c1969c7b6ce152701b1bfbe7830075a6fa956cb4b53f50dc14c521376bf121b9671593a7dba2649900a44d5e24451b2716d8a76d8d61098b0305024ba1063b40e4288b34a82c72c9c298f1bfcf84273b7da11bfcca6941dd5da48652f7d90430e5438a35702dae2192f5c161326eb47e1d94da13a275222ac21212ccc7339b0ac0cc34a4c7604303d73d51a5f2597086b06adbef93030cebae7541294b69c3a3c8eec19cd348c48461c44a6c82990dddd2625312fb1555975b2d1a6c9ffd5c3a071d48893f6f349d8b8dd8de3cd4e3f7d9f2b1a7e3875c3ea64f47134504baad0ec807689aefcf09f3cbc86b94af2ae0e6fe89e851ec03bda316b5494eb8c4f0dad3b489dc3355f73a8e3c266c38a5bac60e03ef3f1340271f4ee46b4737b98f82d74ded8a5fa0be2ec078454bcac084f410d044099931556e72776397799343602d9eeebf6cd146cd526b6695adc3e9d6b893a977f53c72986c854f5e76a98408adbfdfe758008047c54c5ca4e3510badb428fa111913109cf3a4b88563a09feaadb73b8dcc98bfb365c6e21eb5e79bb2b5de7209ca47724bd3183a94fdbc26f97913f0de5475c4bc56ae50f9c7224a2afe9a036f5e6f4948ac543f90ee9d563dab2e6dcff4ae8433ad8c1179df3c13775c52c064ad3f3c74ac4495a8822b907f5a3f007f82de575af6165f83de21a011374af00c9f99011dc3d4255cba96b675aba46543f3555c9900aa058e6f7aee88fe59787454d3f6f1f0ad006e0e55b8b472072ccd7c246a2de64b2c03f1b3f87e3d745cd001dd582c2f88c67bea8946eb2a00e5613150833b60dbdb78c2c699522676519adb9ee26ca434e7c34210ef904e74302c4c64aca9aaa28ce963ab93ddf9bb6c676be58f55851b7deda9cbfc1b74273d652ca8e5d805598842d8a10e5885c1fc4346f1fdc1ba12a022d1749cee8916ef3f076d2300eb929975b3b284ae2ecdac14ed9c03767a863206a1c3e50e7e10014bb98d9f5b38c4f2293f4612b9f45f81aad3414c311b5a120eda6ad22400a5c68273234cf0a71d8575e3b426bddc21f123058961486cafafeda01d583e330bdc75d90f1445e655a580e5177330ac36ca56d474cbbe74ba9e26bccaa8baff1d48efb07bee6bfe24f120354f6e9c799bb64802517ac36dd26eac043cd22cab9575fd65ced790f491a263944422413547d06f8d3666c66aa5b187c8019c80645a6244c894d4e3effc9e6978b64440f4904ce43a8f3f0788756126ccd3fdfac42789326073fab2004597299a4cea105e571370aaa425a4a7eef73673b245489a84d940485548fc3fb1a9d623f6cc59c060527469b221d5c29059c9090caae72771cb1514cf5d6ab432ed51f4370e2fe970c61bd03977f4196023f4df2ec37cce83bb4fe3a331ea85dbeb62bc5f7360ec0316262a75eb5106e1531834616f8f8050d7a17317fa43020419335a89e284e74b69cbff0c80d7cfe652c3ceaec6ce72bbb600d2cc2fa519c5b11313c351296aa5a983aa8090131bf594a771b5915fb43b44a89eded337702315e6dea182253aab11ec60472f08b33ac07e9e791b30c822257047b7b216c6f047de3bf3f960cb9de8f7fe0ff3e1c1b88ec35a50f2feb56edce37567dce02b2aa12813a9458c315aa3815a92874c4440d12ea40720ba1b950db9d4691f9a9b88e96a691f609e2234e87bacf6a96e168b122bea930f10356ac62751957b3b98dde4730b19003fd2668c646c345a02b5c3f815e7986c1aaf45cdfaf52d5a73b73e210a1106575ed995d7b8ce126bdbf04f88d4a6d4ad46cc080bb5b4004110b48ed827061dc84aae63460b1ceba901fda50b0cca9afd7277489e4c0cc8686a3a7d0feeda4b1a9d592b151e341106c70b77308655c3d0ccc9684f076ee91b9b0e8b9a52c1cf5e8e8520d5bc53a18887aa1086548f9bcb9ceea3c0c75d91dfb307f8c4b6ec6828e6b617b5e5b15979c7e0d0523579973c03b6dcaadeee8e68a5eb980aadf1bcf6e2e9ada571366f3b982739bc11d9b64a10a79a8861577728ec86a323578f5d7db99b9d3de0346aa69a30a1695b39a64f7031630165a6c791b71d4a9439570c19ee39bd331b71335f74dce291be84e739caef1910c25675c75df055ba1bffc26a5a4a68c1f496c1336bfe889287946aa76830030c10adb1e455da93cb66406d2e26cde65bbab07db206d76231740b62ae4cf4891d0c5504cf428a8390232e848aa0d9383329d75e0789ca22a421293a05bb5861d538c3694ddb9e6c4ec882d3912a6c8a5948610fda37fdd9594181e53661b23457ce7a10a29b899def670e9cccf71a1261dba903b4fa86b909db84879b173ecb139cb7b478aeb61d0849a68eb68b9fa0efeeebb3dc25c429786b781bddbf8323e2146993bf8bf3b94fd91784dc5ba7f9639ece1fc5a8a75de6149f53da6d09f526d32464b712b12e96c96581c64d704a0ac3e25d241e5a108ba076a8e3b8659d0eff4538a475149cb9b57d011746a1ccbd821302e1b3e49a26127f492882ebf8fc42680b67e89460ff25dad05e1c5077273e7110c2177e15257b5fab8388967b11d599c7026271ce6d4b303a0434dc1c06053c4f1787843966b0db2c48ceb36ad0d81271231e2ecf6d0d017a86d02d0a0442d9c2c998a9bde3e7cbeb2aab926ed9752ed4920e0882ef449fed7ee5936320aeb6afe5ab2ae31952370cf7df9e81f95f9c440301a4816b2ef68411720b101fdaa08d59eb3a4c1bb3ff2d113abffecda4524759377fd45a1ca6dce8f780fc749381ec0489613d3ea4440bf221e0dfc2edbe7e1ed333e7308fc0cccfa94049b5a322d48c82c7903e7a869d8413631fdd191cd80ed88c821d732e7f2384b261d250b07b1e36a9f33a2d81bd2a78d7015849321b7710b76f6a90795e35ebe2de0d7c4cd4302af185d38a57bdcc9658b5048f45baca908fac61230c16bbc0fbeb890538e460a6bdd256c7cb00ce71c83d8d27d1bcdb61711218bfb9854c44db65f10917fb933e22c6e8e7145a3821d07c74af59f0daba2b47a217aa42164745ea405fae75c3a89966c20618af45ed5798a03c9ee285ca2c419608a07b43b60189e35e34c1aa82354bf3c79be9e43c6250ad99920dc3d878602ae01cb7884cde5f631f22c6f4ddec448aa33eb208cd6619c5b546d09cdb3128dfdba5439d3c61d5b411330f5fd448f1280e73029029186bdecd40ad786955df73aa6fc1c27334ff253ef53da0ce443720de5993f7af5338aca3075e71e503d644cc993e7c264daa9c06542801f583e92dc1e2917bea0c7ccb17011d8228d9c63421917b1e1585e30637c3061b438a4b761f25bf74c52046dbcb943684aa210e7482b3df393b82587d704c12b8138b1b4e0d2a88f696d51cfc0fc027fdba85f5b41f4ea727fa96a43d69d800b43a9213e8f71044eee4ac7abed63fb0a5b492a8fef569c7ce3c1d56e7371a393ddbe2db2e1489757bbb0895ed2ef2b88307d812a9c21cc4325dd659a7a53c84c0a505c6aa5c6093caf00aa18e9c1026a49c302c0c7933aa47ccb28e8e025d542da140ccdec898c14bf649532cdfa6cc2b9e580a5e89e18a00705e0daf59c6a33d9ac228f34bd4354e32e8bd8b4a500e3806f375d96ea2ece032f400f6a00931013394e62b53510b641b01f3bd0d98e0bc51232e43a223006c245346ce35ed71e5bfcf595a7bf61c3a2a4026b015cf7062dfe279364eec0e15ba1883eb7ed02057c8d4f921ea2d069c65804c22b019ccb80eab5aab8596b63ff08517dde34dc15bb9c00a79e4e68e35cad5faaa4ca6d5b7ebe0c9a463bc58dfbe548639561c8d6bd0028caf5c590682f51a67b7fcaa2f2696b28496b27674a040a566721adff76759c2d1bc896626ee2b20c435685989ab8cc815b2711967f3873d9a18c27ba16d080a8e8c94583b3ab81b3e408ffeed25af23230103ff23f6c26f19fa39f3f9037f4b223bb16fb98d796116bb549f70d31bc0aaa214067d0ce742278094fd14e0f4019151ebee5979d27c2acad60ee27de80190436507986cddbcd8f60ae31602cf0b3c1604b997314af11ce6a0a001b26678973795d420d3576512a350a7c4101499decc822d100719a876d34dd8cce54b859e4887a2b1b48b391ce338afc93bffd887fb860c5cc3397b7f72745da8e390bff214b057a5fefb645d91a1ec2aeee7a00055d78d79d1e7118911efa5e93a1d7f9d32b10e863dbb0fcb25c9f5d4337a31ac27cdd9a4cac7340d391e68b0ab89728aa41ba0b20c7a5484a4f002d8ff57bf9660f57d5750ab9c0794e3d2e727449a9f3e23a4c0d8f7c6d075f03d43c5c46903a56e4b7a993e564812a1408ad560fb820519f928cadf138a7c908df867f7b0c44e650f042e70e78fd38c2db904dbcf971895d45027575a484965e2debf4370bcd10b8c92180f802cb8f43cf1c698b6a044aafd44bfcc975e044098f71494876dd96c4426b3fd40c1e44ebde88f534289fdc6bef54b1db81c5d8b5179f24899b45ff95bce3750ff3885849767cdd477e3ca84d6a8e43dfdfd57b555457719edcc6bd31bff0bd8dadd35a4ae4933fcb151badbda7eb1b4461e07b056b4bd818a7dab036e9fe23e6efb14c342311bc1f13c1f28122879f781ee6e5a01d50889440416751b5e3288083b6b0f5aeb7f1630a43ca95fc29a7cb7fa851620cdd78f60afa2a52d023488e1ee8fdbdb598caeb2aa0b3d327cabe833bdd0ef15d6708be9aa35418b67ca759eabfc0cbe2597b95de13dbcf0496fbda60652bcda6e4ff444a53d4a987b9c6e7aa58a2ba7758de7d256fe9869bd6443629c4b9d21c1408df1516536ed8cb9687f822bb7c94ff594aa50d64cf18729989b6da7d231e1fdfda3cdeb45a36ad4ddf5b6af7d9b5ebc9e2ae5e1fd74aaa43444a558d6951b2796620e8aff29d7b9ba98ac244fb12bb05f8dce5bede863fdfaee91d297c52f735943ba7f1d88b6fbcec4311284ab524fc2442a36d2cec7415518bb775d39ae4908d6405db11f0baec58cc86f97dd0e44954cb20cbb0a8fb03742311d37872e372745ae4677ed8d07b86d97becd207ac875932eba4db599944a962e477d743bbf781031f4f34344aac574430aeb529b901cfb61717ffcb3e72e2fcc6dfced9b2084edfa24af62e0330bdd75f4d280580ca47d3cda4ef591a223ccaac7253706918af3182cd1086f47652c531f3374aaa8bc1da19f0c4d365176247c5dffc4d5c4f0c9009334db4f3f5aa1026809483de17860d713cfb6957e91e356b2eb5a88096d5c8e2ae6a4a8e648ee340e68faae96a7bbe4feb0462d51f962b72fbdb7d6304b4c225fa4cb2789baca9dda7e5f0053a1085cb1e19c3cd2825572f075356a816c51e3c40acbca6bb2378a01e011a1b1c822806683580bc8ad388edcddcf8efddbaf225a1d15ca0bbef31a800400f221da760278aeb9d3cee0a15bd32b78d0ddfbe434647f3a4745288e930c24a981fc5346e0c28dcefcacc1fcf438711d6e311265dc9c32434ce0f3f929f931f593665fae19bb85f078277a2c331271e23f7aca0000421cb12b91e29609e21d34fabc1500225f5f54fd9b3db2dcad5a20e94c4c324ae28f99302a02d9aea432c157a2af49559e68802823c9cb612ee69142388a6e56f7486a9c128c71a9545bfd6d0815ddaec3995693fe4567575539d0809825b72ea0d7ce7877650690d7d3b0b75cb3b4ac002e41143148e0dd821fbc91e69ce30c5f214eb2f14b3fdbac7516d8d19f06e0f4a9263a909f1e286fed2c87c31cca8abdfc4e2c5576e02bed5ab9e30ce5f4276a53f4dbbc21633e1ff63fbebf2d4471700c782264caf2eee54769672e870ded58fc27e0e589f5dd1b7584a4adc9213566f2f6b4c63629cf7dfc380dbe91a4b7ceedf49389359043b06b3be2cbf640e7ba8192320bd4eb79cd81c071477b9197585996c6f913bb9295de9bca007a93ab1bc1eac38f750c28370a8b37ac2659c8f49ff365d8cf86ccd0ac3b7f3fb2c6eabd010b2572044c0924669a6db7c1f7039d12c78dbb9ece42f606eb603134bbb5a742c8d189a390f15187347f7558d80a543c6a40b8ba88799735e09afbfc3858f0b3173820010d33537641593e95839d21cb5632fed288b235b4f2fa3ddb3ada69b73e6a2d15b2495c5c0031ffe66a039e9d89305cce8452930009bde89e7354588eed44ebff28d2a1dc6b513ea7192910557a2747478b5155d8a22d1d1d3fc8a8a0dd4663d8aa0bd9a77901249f7b622e8bf7f753e9527c41699c0f1fb8f8cb30e746a43089b02dc206c59f336c1b93dd1b8411561f76b36668dc39c4c731bc78840ac29a3f1c8c6108751f4e97b45ecc0cac5cbb8d7e6f32d24243c6d5d98c8998e7e7636cd3fc3e04e476d083c14cacd1661ed9a826b97e8afba2429a4e2dba4be0d51780b493ea7b381c0287a209053f3a76c45d6557412c20fd3c80622a33ed2f25b8265adfd1f34e926d17bc724a24a5e6eec6f1dc9ed0e2fcab4a2ad38e9217afd49f662d491d3fc3689b29070d764a6c1cd8e05cc7265610516d2cb689b5f8b9dc31aa18cbd1c63a53315100ee7543e74d264e0ec0dd7a52fcf56b5c4d1f65b1f638bcfdbc6862a14326f4872353224a9830a89831ecbd46115f6c1ee55089b3dc8eafc571d9de86ddab03829a92ad3adea4c637919e577aa3a176a90fbd168d568974c8bd738db8f8212a96328dedbf85bb26ed4bee266cf01bee57515ddeebfcd00335d0e3ef5f709ff09a1692ae923741d8d4e0d37ae38f4f578efd1637a319d0763df58652decc1026e3b7a6fcd9e17a2ad4e75a6f143c9e2c3a17f7d073a915be6b90ad5da6c25db189c02b09de9604b066710e37e235d5e6deecf15cdaaa7226d7446090c46170ba6a5f2720cecbcd9d15781f5b02ff90da9f862ef1fd167919b3bd4f24f62ad60af4b24e2948b9ce1bc6e29b6255aada237cb625b6f6b68165b933fbb03cac34f1e79915cd10d15eba41d844eebbc95bc16ee75a9c6f05d2bd1683fc85e94abfecff8526ebd3e1363afbb6a5846bfdc91078f56e4aa07243ed9c31682ecd30f74052fd44067c16434bcabd526042bbf30ff9f0365979877098a07e5f4a9046a04cc534f5cc3a81014bf2747bc04172a528b4b283222a87be14df6fa6ba0961fa2e5353ccd0402aec419a691b569afe8ac878130e49075cac48b7c9e1c7ed837d612a3478fc3663e26f230804121c61d9310e1b24107822e7013ca6654963323cda8633f72ae836ef8dcdc3f10d6a6ca3b00e16266fcde6cab9b76bda8cab959634b79f97db266aef889d0dce3d400794d5c6d7a0020e89612ff8622619f3f1f213d00fd036d586cfcc28d625a49f883919a0f9f502be43104f2b1e08c648080894d03706a35fb73ec84444f999230afa834124b04eb040f8b911fa7dab00fcb56e03b66c416bb6998a30b57118c898d0ecb17cdda89ac08791a6e6a49b9fa7d3c72c4a4633cd0f35c85e4fee75427d60ffb041ed946104fdcb9a69d25cc8aeff63e833857bca0d6a1bae2a88625043a2c9ea4308c60fb8724ae25a78aac45e2267dfc71165e7a766a04d67cea526aad26526bc9f47f9fd3f1d0d778afa32ea271e9b7b6ad13bf1876475422a0e086b18d230dbd567c2477ad20b9972fae14dbd963f19f76c3f2fd7f69933377f13ab95b0d54889af0007d00999254cdd8e4337166d0bf9ce6b4fb216b19c1ae6358328fb82b96f6b4a2dca9edfaedce01997b6ac3f7c85cb8a88f27ef927b94cae17c6598a87852480f1def0788326ef8877cbf937114a944398b3638a354668459af2c1d8dd936dddba2a63d2cd63659ed9852b7e270af80b27b47a268db0d0272bde252684190a47825568ba06b96b206073a88e156fd31e189696841a195e399756c8ba519252a46c2c3daecb0b1da4a0a6c0e7536658916e25a1a0c6711d3dbe588837b13dd7ebb042917149e9e8efb7315ad36cfa56dea0afd5ff58d26ae10635617fea08c32e6b6231c97dab80c2a573ae478b139e3e67fa8ad012d33e07d28475b1d88e7f97abecc64ed94a7c00be6793cecf1c0ea752668cd41160a5e2b65bbe66b74ad105e48dc05afbfbab7260fd504296a793ea161249e8f0490a40994400f9814bb861403cff3a378064c7b241f81ce746fe0f2c1780c84c34ce0510830e2cb18a7d66247186a19b09cb64141d465f01d2f5b341f5365377c90deb842f28157d33e19f4eef6961e02a7ed0259e1e1d558f605d744dc13277f8e4c748b3605dbaa2c5879482830daa0c04cb3cd241f42962dd7367028ec1b54b69dda260095e4e4fff2a40467149fc0497004215b9222a4ca15c032120faf9cd134ca9288613a706d1951430b13a004f2119308c3020621b6c1e825974b95b67cf3614238dc885a0f4110878c82580f51a49a29ebc81e6fd6c75ba003175e542a527b60e77785da05d8af892b2034247b2493761d1bae3c70d162e9a605edb3ff923ed6b4a382e0fd3dfa38e8aab0a75dc69e1808304c7334a55a6e576dc0437249d3ecf9c6329212d82b7148ee8cab8adf3ce0ad653b80e53ddd9d25947f7aae54eeb13b8b3c12241bb825cf773620875b6a08d230e28508b7d05d9017dff19d4566ea48d85b65a97a442eb687fa32603c090da42b7e1d31a8ee7ba06be069c156c9f3bd3a901ef0b5163d23c06caf030fb805865f44811fdfed6bb94ac90228a949e1e5e9d3a27f3eb011a7d9b1ac647a5fdef53aead6de0f63309ccb242c80a9d1d5cf06849e7a0a408261374b9c4e4caf76bb4a5b2748064d51a9a8e77bed7d3ff3aa98a9889e127a64bf8c15ce0ef506504fb469c882e39d2656bb7b0d7f240124d45b660778b10782585d1b45087b43d7a2387815299d78714ffbbda50640efa24bc2aa7c8b03ee0ac9c53f6969325a27119980cc1323bb19995e24d958998e1b9e4636102e1b4c0272fee18ed457e90ba85b04e8aef7d3605c26d85c62b7a9621f95bbeabbd8822b5ca2e18a448b371f116aadb9a446445cfdae260b51975061608ad8bd1f8f95b1af64619b974640f4a049488f96c0ce1f5aacdc06487fa219485ff0ed4876dc62177abd4b254b3ae8ba7da9abab3624d9e230714bcc1afe7e212d8bd4827abc110336f926421819e05808d1fbaa1091560ea36e26f29fa0c565a063fbdb87984e980126dce194b0a9e771071b7888068a50290178c6274797c7d24e6040deb144406c2e1e6b16d014e51e35af4f3b2b55e1ba790ced99cd580384a059310190e8038f13da306d50e37f9a7290a4e7a9c523043ec6334883307cd30878dc62db6e21901a4baf57f04ca32d76c5c569ce2b1732bbc80b4126a24ce8f94e5bf51cc9dd7b2ada8c3206649b15f392b9d087d6c28100a2255a70984c9014c98f902beb87a5f2db4e2cf8530722a13d2f7ccfe6ca349c2ab63d19b2e0581d4224d67aef59072c362be4f60783a8789de120606f9350c2106b4b62064452a5bd94012242b711b0af98631db6b24597f6dbe0dad21bb67267ad6eda0e72733b0df3301b30fa844f57c84399a7dbb8e3d1bc9181f1c5afd0a713cb138f134767a58e4510b953a66078b3212d7efee62197102d35f8f023ba58cc5defd0be81c8aa90bb201912263642ee855c4ad6c455e5e42d672529a5786c1f71e082fa50c36f52d8b841a0cf08275f0281beacc03a982fb55a81489ef952e53385480b81efdd87c50d9336eb2328e4be97dde6db5e6ce69960dc501a2efbd1f2ad3a1738265aa1e0fcf1ee98f5237b3e5b0364af3a1738ac40635dcfb31cdeb52a97b02dc638b907a6479b6f127d0bd3bbbd8a25ac5d8f4ef5007791ab904b71c2323a948ba355c0d27d397b9e9b23960e2927ae5891b9a6e3ec734c5ef2b830a05a7c6cd4a80a0bb0a2eb38f86a8a590a5282d18ad679a9d86a371d91540afb628559f4c584f9b750bc65e1c082d9ff9e2e40e3659fe2ca5988e1a71eecd83a5f38aad103397c78d18f8834e3e5fb9a07043b88513521eb85dae6f555bc4dd9b378166eb759f719e06223f2cdf4cbd8050415490e691be19987d03315a0a4f15ee472775c1ffc519c40193c57e56b5a85a8c42e97cc5f23220b29562fc243170d8e87743f1bc00fc557125208f14a8ffb057119bbf4e88f35c463283845cd29035bd7f8ddfce8b93c52182f216c80888ac5332d4178a87e861313c000bd85b42b38a4d92b0b9b82a36fdedce881a7a797af29f719859516cb149778dc21b7d56e5b492253681142dc606a5faeececb07775306d45d92c6f0323b85e1104866ec0ed1cc30f61f0e73fe85653ee0c12cd3060cc563f0ade37c9f9c9d80202a756ba41997ecf616426740336e57ffc202fa19ddced38bac10f4286bb89d3995d6005bc0166cecce0e4c899f578c547af28764c48ae09135f6040e9bd819b7277c5bfa641f20c80ca8b7e0017eb81f73dd0577421b7edda04ee45e6d7dea048f82e692407e12bdeabf72883785f75964f974a904d38a7a55c706766c2ac5ea5f833bba6797dedcbba7c47db12a682192e044b6418f96b776646f02a8a57ff7c415ce6809bc9165034204fd04adb1a4898a908a0d96e0ca8d46be762d24ff9a79888ef41c39fa48cdb7e061178f5aabb435954638b5dbf4a3abd473b5153d6be3de9353beaafe9d03c5eb3f40f1c2230a8f58e005d2d3f7ad72f8ef7c3152c8d281366c43d686e41e53e4bac8914db3e840b765ca366e8050659328e6c82638832b1b7eb1587a45f227aae263f7260b7c05f02f7df26095f24836b452d632604c61340be20cb7c795965e0b3d33b394378c12628e680a3fd6cab1323a0f483ef8c5dfeebe12b314af6909d38a311331603b8b9440a1a6a18900f9536fce467f2d77983032cade46a98e455355b213cb8758deb57278123daa8db38734e8cc275a60decd2a7cce61ddc67afbca77c7f4d23a0a59d1ee65ee8f8cad7aae4444fe81da12052799099f31f6611e7ccec502965d2a93217cef054596cd177c6258f98aaee3c40023e72266219507a51cdfa799472c04254342decce69d7f79c9f6174391723da21e6bf883872c4f9dbfec274cf90d1f91b644e3ca7b1fa806f0ac1704781a130775114203440f9632a9574e4af32a310f64eee3e397b162e41a4596f11c450ae294900100843c7859db80a5d32d0095462aa06be87d03e86718ba02505adad43ad3256f7bbe87e5ee3e5df3e85a6f38a11ddbfbf30fe386b20b6a33c560286520f5a7a51eb8a18fcd9b7c5f062b776b1720a27d7af131fdab9abc4d1e24ab8c6dd3d43802ef09e64eb16bf44efee122c3692f81071c30a386a31f673a2805f07873609f28b8d3561ff48d132a76a92300397f82c998e262f0351b4cc90c933a5a7515c728ee05187c8e953a3b65d3ff8c132025fa6bb4d25ef6a0797fe4c1be103a858d44c71724f2afbe84ef4214a6f16008434703fc2caac4dd889e7ee61cb3867096833c7405157b56b3e4f7b0922fe97f2afd47185c6271285e919ac2f882469c5fab19a25089e119ce6da0960863cad0c3e17f2839e7b711f6d13c9ca9b0e27917a9102a4745a22413459db1f11b067de1be4e4a9530efecd832202ca0ec5c804c06cad3b6546bda8728cb48c19e51d04e10c7152d6438dd19f0465c78d99c7ad94f79d40a6110924c4705c629c12564ec9ac8c9c3fc234fe358da02bba9fc0d05af26a0c0069ab59803ddf078a1ae5c787d31a29aff6117fab7316423ece3e5967b989f457124d0fde8b01a4a3f0a49db732f9dcea4d3915c4c9300a26b5d43532e2e5dfde00dae3b42fcb5d12392adcb2280e8c5246321317754cca0d0452a802899fa8a760f89d838d784aef60227cff51ca0a6a6a09743133e1ea4ed263ea2b5fcc515400a6c705a03216168ae64f9c58163cc158f440d97dc481a8d72939491a5282dce350806b65e2e8820c5783e58596978a30238b1017ee2444571a297a1ec917166ba5da5eb47402bc1a3f5325ace3dfba8802a0f3c9039dd650c0b690ddcfc98c9f8b3432e9dec84b0382d99871ee82be07fb60779a740582ce51d52a4b0f991fe679bf413700d4cd6a559178f929ed3dacb80bbd0607e6a5f434d205ddf628c33330b27a64c0ba39719b592a749c6ed60531032bcd00ed451d712b1cac3b145ec23502fa468727d4908367c0c6fa07424bc5008feca6a24212fb464b38968ded64e33703e08044eff4161fe8a4e97374fc61a0f11bdd8f0854c8118ddb83c5bde74414cb91ac204d7691ddedb3c2ae5424e20708c72ff5fb9eb8a18c74686087c21d0ba3771a0f2a9c74eba26d446f9a87d830f51f0ba1d839366a2cf4602a57ba8fe18d7df9468e83da3fe971883551f3898e5714b90947b656c9920b40158ba5786ca718bc1f7097e469d7a4b3777fe2f83c1529c44e4b2ffa94dea2014b9d61143461c785d2d53cb00c7e8dba6cc05d40bfbbfe5a438adb7700702d602c044fda079f37675b03d00a4b7d0266be1a71290617aac9b7aab339b9bd3c30255d2afb14b2c633787b934336eba997c37bb0fab12dcf5bc435d621e4550b142982dc88e0056d8aec046c2b331b5309b6e68ffb8c4a8071293b6ac98bbdeb10ab268b77b262d01c1a868733800d1bc73042ad9ea3e36f0c3ea6f43ac5df7f4ab3deb7aad44f703cf93cf4823ce9016259bc08110d445cfae53b6d193d4ed3298ae87fbc60b847683b39e61a8093d1ef57dea3eebd1d5cc5993c939105f52bfd4eacf941a1ca99690c0ffcb2fb6879ddf0cbfee4fe1d8ca9647e8465c8d738ce43d5a1ac1049068949498e3b4dfe378ada13d2782ccd6dbdf91fcf02b05abfad3d6ac8e64a76ff0a843ee5db02bcedce49e80616f966fd9909c9a0396f75cfa6c66ac078ee290227d4d6f693f82fbe8fc77ad7759afd1b90153b0fa42a5028c9fa4ab2e354a03e44e2b59c1950a254c34422951afcacb1f64c9b40083508f69c9848248de805c667ee3914073097ad878c8caf3a64ba7cc85e1443893d4f00a93848c1aa65e4fa7280a3d0604174aa71e619f90d781f9ea2506cee9501b0734de00fc9344fe90e0fa82030cd5d086f892741f0e4e10ffd7c002652d2a4b4c27dc1ac53185e3c47c8e2dc3479c3560935005ee95961c3321ff7e8d6d9c0e775c770caddab952fb3da553d7caa2207827c86b1ac661d12f8b2e12b421744654707068c4701a1440b0eb920ab40b3d3b3d377d8d92a99cdc0544e3180da97f2fd28f700f155b1e0906582f594cfe7ea688ba8025ff091c133069a5b31147f318b710849616b67b8acb5e2729a6b068abcd8eb7e276f0c8d0f7a7dd35a99607a295269b2d0e8d5b365d7aa50b9ce6915011fe4f5059c601dd2f25851e6dc09c597e8a45efe87b98e67ef10c98c2c2f93e83117d0e362d75fa8ac50dfbfca9814b5d941d6ae780003a9a8877569d884a0753ad8c012809aae0f18610881ae594a7e0b1995d3bb6343fa3a017849aa4dfe886015f5017d02f66a2f712f73f05020f5d1df349e0ac1f6e6f1979fc0c8a0cdadeb7f4d29babd6a98762102b08e5eada7f2870f68fd21a5b0dac9e4ab733b641cc68caf544dfa245a96cef4287a698bab05bada992aecc8a6ead8221cb3f557e6869f024fc7526e8153e7bc29d1ffd92a369d70e247f29cbf1a401a84dd0fef13aad2ff25121b8454809e61effbc8c148b0bbfe2cfef8778306bbde1fd158f95b82690a2d2fb62ebefe59547eeaeb0b2f5ff15e430af9dda663e03ba0d270d7b50a355d7a58bd14ba710c45407861135599a50edf391e8e1332190fad4683df43bf8be9753e1fdd5efb517990f61a6c0fb186ba42b479d06b477ba22dd698150d93a5c1b14bd643ca27c8b9d3ee974a5c6f87e48812570e3487497f881bbfb1a7e9f543c8080b554cb347bf995c2a1809845534c572ddddf7fd5f4cb6e9a934e21315a80a70d8620f592c2654f3659e04ed21ed6114f5f0be3447a0ace9e9fd9ac9f96d1c7066608eb28befb1bcbd47bbc181343f3f1ef835a4c4a54476a3d14be61a744aed32907d4033b25e03c8d4a75ec02fba018ffe58070d6462508b5bf8155ad79f42b0f036ac2b6e1c27b30cc08cde1aa8063a26de9ed8a98156d8dd9e8cc9050df7a4978b55bef4936752307c2604ca6f6de80a4452c1f26b34d79d70c96b2ce5d1e929b1e3937208187e87dc4c64a6def48ec3992bc95831ed77d0a6f66e5d00d2431193f33da041655b9c17d069e479f9c7675ac360b1a3015b82490c650582955b4d9eab3dcb183c8212444651bbf76dc0b025f2f45b24243e8dfc8ea70bd298d4451b2c0a7fb083d4354c647b1373100323a7f3aadc3f1a5408075041aa3f8f01bf56f0131016046f1b1663d2deba44b357c67b776cad8437f8166995f12e62b63145c32a9a9e5d64421740a2bc88b26e6930838c421ba7bbe8b98ee03793b4ae5bea7810ddf4bb00dadf5842bba06426f002d99b28490ea92415133f1a838b91fe200a04dcca24f760a1d481efc21fcd2a375908e2f0bc31a5ce2aa7bec114813d7d2c449d2a3e409d4931fe5a865977fae7e14bcc216090e87d59518abfba3d0bb254c30877e13e81e240a17ef77d7a03f49b80a3cf3e5745e6b6b86fa23ec1192ad7ac6fe531c940c20c427fc72e08f94991b21cc1934e2d18e2973d3ecc1b38e8f1d2cc1ec6e3a3f0622db65edb96aecaccfb3a02aeaa43e51e60d211519e156076ca5fd4ea84aeac83aa4f176b69f6d081c8a42012ec707ec9cdbbc587282d47153da2bbdcef806d56cdf3de6f2d91ae74e8a7b87f061b223a62161a7921cba98976fab04ddde5635f6af3fe3279449bd3c402205aa3cfd6d471012f327b48263168cb17c301ad8ac17e7c4e521808a66bbfcd7bc102244400c49a5b20631312d10efadc12fc0174756adaeefe31add1701838a6120c399a27ada200158f4a34d2f02041bf0a807e3884874a1bfef7191171ea94a096b411c586562ad72f54ed6211b537b688992f863aa4d9c950250002aba380340080495a29637d6a7590eb6b0b5822c8e64ce589b1a0e870aa26b7a96b0433a45f7c756ec5b467b6153332a19221abb230b318319523727448a3e1278190d5409ad51b82d5561c9186f61eab5229d85fff72c8337cd376c57d11684844f110c9c56c47631a4ceff095ddbf91e2962275a5c2e89a8f353235003b6bc3148349c4524db86dac7d3778f4e22a3ee28d65b71a978fc1fd8d148ceb371df28af532cc33c87e2921cf22c3ff241bf4a3f2e8fe402c65a7e87e498c3b8db52579b9ac6c240a882a91c3f62f0227334ca52273c37929d8e5d486cfb6db6b908c5812a173419a9ba42ea4944013fda1496521b1bb75d0b04cf4b15a41c00e2353db935bff1d2aca37d69531386ef868a4bc119dece2e48b3519335111f79795e0c2b426afb6aff6ac544b12efc54ff6d973d642bae09f65687c53017b833af910b1cee1140687b011c7a93884309902cbb0aef21def2bd2ce5231f91bc2eef980cf0a2fa75bfe454c4aceae840c0518c43675e8399e626cf35abd1d0e74d87161932e9127d179860e03975df05bb606599ef84a18c8922ebc4828f8910145262056d0cd2804d11ea2524d3d7a2b9909cbeaaa762ac5c8376d134be4005fe40aceef762b3fbfcc3d17939ee6a87889d64f2ffdb688ac1ab014ac1c5858a0694348a4b73febde248e94e3cf80a1dabf0b3dd6f5baba25a71f9d57ddd3e0cd1a5035e6809af4906aa6811a68e16a4d4135e943d54c8235d042aa99036bd086aa37076aa48556370fd6a00d556b0eae490bad661aac19a17b887ebfde2a803d91352c990aca0972c8539d1a0f4a1bf2ae2de778254ec53c4da12793c1f5def537759b83dda7e481009291b39c10dc34917033ba263676dece1010221e7ecfa5d7ff5302c6854dc606f3da96e8059e569d500ac50bbe2f807b84413c8757c424aec0b7e13ca1bec5a8f630f4b584bf9381a74ce7a970f270ee8669ceca0ba7ba3852bb82fda003fa236100dc586b4306c7138ce8158d82c5f75c863e4e3fccf2c49442b0b29a92f31504d8693f88f0cefbf3b9111f3bc9fed51ea27fa9a5e2d60133692ed53925d1ec38457dc2aa4f11bfccc7ec54a2a4be426aaf527710b353252f8e87e8b6dbddf967f8d1f61bb7b77b6970de734bda3a9d076099b908f55da7e523c3f9085983acfa88896fe650d7396f2f22102772e18a629942a3e1a8f86c4f2e64bd7bb993948aeca1a38df4fabaf8c06f47a0a5c04d42ad9a48aecc232d20c021badb16997eb8ef25bba755b520dd546e6921a3dbf3219203b2c606457bfea7e54e66595a49d8610c3a25375f5e86a8b2a88491f010f934d6a0b8b25de611089ae84168ba26d1e5155b5286c5fc79f612b64193a810bfdb8146eacdc2ac62e8d9960924e7a7c1b41b532fe3efea191a8b2891d593ee33ac6ebc418e6792a081ebfa8a9ea107e206b4beaccb252542dfc31e5317e4f8b48185d3fd095b88d5d7b0685272ff7152e13ff10c5d7a7cbb4eae4100cc532c3acee9280a455912650ead5b761579e79c96ee9cd815bf81154c22d1a7986bd30b02e89845e8bb0a71948ea765ce7edb7e49fa8ce67f3c63394a798388d280fa96ab85d6ae81086cc1bddfc1c54b5bc9c65bd89ad273dac4912f39bc150b6157de1600b8b3894c2588131734006e0cfb20901f4e09d4c454f5c8ead7b3f30ce7c77ad88be09a23fbe15253ff0b9f86ed20bae57b605e145acced6652a6fa61beff0a8e6b4df0de9206c87026be8c168a388975c45e5c0eb2b1405b77cb12bd7ac2e5ce243cef1c9298f049a267e112c4ac2d40207311fa6acad6966ec9112e0fb48b0704014a8e9ee2308e7774d1ff1f3a264b9b7ce71fd84293adeb314b11db1974bc3dc5001985ec7e9e491db421f53dc957a69d4a613edd7fdfe4ad4d963b95e5865f70e2691898d848801ff6c26dd607305bd3db662cbb47d9134447a033fb3bff1f338a38cdc0288b6dcaeae645a49262f588c238725d0dc5f9143cde1cc1d957a4eccf10ce7e4444f514547f8b66f3c91b0b2c2931b3299f9bc3d4763f2cd2f4f14c3ee35af987c700e087676b75b758c9866a093e9c3e7ba736c34b3bfed47dea2c1b315e7b811198adc3ab76c9c797d1926119508330cc96aacfa3aac718cc34fb902d5ec0bafe43ec0be254f337bc49a83c29136f7d00a89a4d41512b737e3beb86f696e3ccfcacac92f75535761f9a62556ad66a82c1ef87ae4353828067bd10cd9a7fb8087929394954e417858a60ef4b9e08e3345ef9ba9a96b44aa4f4851d5b9dae061b9b5f8ffa6e7f7fe43bd8c8e200f8eab59abeb9a863a75da48a39a335cd068db9ec3898788fef18d5b09b2dfb170a09fd2ec79a921ce5d7071eba83d176dabe2c6808d97cdcd86ca7fd7f8b75298def8c22920212beb33e3b6f42cdf0cb29096baaf430ec4b6d5dfc05368147b723757602e88a62b6fa645666b479dc58f1688b91ba0855e9885aa6cc1b177e9d1a73b0a1c5637168bbe5ec758a18a9c5b98f9bb833d0cecce1545d79e5a9a3b7e9e7477485f980fbeb64329ddb85cad830ba8cb6b33f20eb9a6b3a0b347108aeed6ec704d1b72e4f7fd3f21fcec051e60b823eb8cbf0577dc1b3cbdf65a4b11d69637ccd88d0da24ed4b4766e21a3286db51c03994d842f5f23429d7b5cb1121f684ccf933c1cddd45c71a82e069a324411fe8b23e59b5446e28a450d23180738791cf2917aaef70c5759e1403eff8254af27a92ac6f0776c42ce7b593ae2cedf0822f283f23df7d88079527601139d78a5e514cadfe197f10d61652db0854e81133163160e266367b2bd166cdef0aae3286402a1807cf4edcd87b61713dd9ae30c467f6723822ab4563d1fab331e6bafc915b5aece2d56224356f63ee864b902da1e0da4b769f9a8b0acde0e71f2860b2ddd6ecdb2ee25c8bd3a296562fcfe57e91d5ecf0909812e7e005446008a62b0fd931aa938a366458fe94c8c6ad81b934404489b892ba7bb84418abd661d90eb1b2db8899d8e5f753ae72f5f8dadf120183cc85ea437a9c83b17aef997f0b2f46e556e090ed2ef213e8455028b1a3f2cebbbdf7e0690421cbe3fd3285172a38128f757b2f1df41e9db44a836a2147886a506932cbaa5f8f3c1079295b9fd4b8e22b7e1903ef3d6129455650b50e4ea03855d0b140a14076ea9a46a65956b3ce4c10bd3ae9b83ae2ee94e07b85b1a93cc63703e50110d8cb119104fb8bcaa2463972bb8a990140d8cb0dab94a073aa02daa833aece153459f2ba07744116438b0ea27799b7eadbdfbc1c258953622f74fcf89a4989ef87a7ddbe4db04b0d5ddee21c4993494f76e1335ea757f06277cec1d52d62b3bf8c589daf75831853f9eba17107d3b6fa2b647e7a16c0acd4708e383d747c34cef4b687907c467ffee41ebfa7cb7435c61066d257cfddd35056df4fe52f0a731892b15d71fe303a1609b81fe67efa29cda0c25c752c65e774938d6d2d5ed0d41bb68c6d184c4e46fdf55f8b1864bce1a3f0294a12209b4c94f3ada2897967115be49370124faed8009b9e28fe9f65c94580d2205498125124ec8bf131c930eee8b3b28925e92e17173cb34a42873940ce24342f636d4f047869292fb33eea0ad296b6691708113afe2396663a3debc7ee4affb8e918362003f87416f82f61e318360cc88b033d05c51f2aa7b2199b0ca34af0f38bde675b191124ece077a22d52c834baa0134065c499f4963aae868619667aafe10d72f0080fbf563518956457853dbd989c5a0ebd80dd5962caedbd5e65d58c02a796c06af6818a31afc0bd144e43f9bcfb87c0575957871f1a5abad21c87b3726f57c230bc293c79ec440b4249030512019db7b82763025ed4f2fc258e6b297619f7093ae46b74d8e4538f46f9968507a7635f9751a6d0af08302588afcb216f8d3387297d9a3406cfc3d83e4106b1aa7db37c7aaf649d4e4ab03d30f676de1aea2a9a179d47d1e7e736952d7e2b38301c60bd2723a543ae22b8deb41808084f6a3e7fe9c99c0e421d7494d2c13610ba6276bde716749ac4fa38e35de8e33d8675818e975ccb43c652e706e7bcc597e2d249749d871c0656e784dd534887873650e598947e48a3c829a235b4eda0b2c55879c18be0072f2f66272a0274520879fcd170b096240517baf84dc12f1bfc5d2245f7a52490b9dd996d97d05f7cf9acf9bbc6a11c2a6e0e8e81e5abcb02cccf769f3917b9b6fba7017608ebdfd865a8f38a7abce2c50ccaf89145fb997755816c128c912f159032b0ac78192dbcc5d5652dc8fe0e24eb43fe3d9abe5450fe0fb4bbb65a5acae77ba088090ec140992c14ed0417b3c5a9d925fb859cbb7306b496debd602e626b3a707d1e3c1fe3c22d49806415b626f6e1635c8f4e164a72cec494e3869f9a3906d582bde0739f679d3191c437507f83d3d2cc638c00a01c3b53c6421ee3c5365be29560a84f7e32cee03faa61e6056ab227e8a420c826289812b97c44e273be705695891bea161911c0da4d4c95c7306653138b2a0abce0fed8c65894c1389f1ab22042822ef2fee4e7543b6207f2a8ef371e4b943103594ddb6a1c5949249ebee670cbffd8172858aa3423c57c270b5e5a90badec6f67d14482e395439d0164ce12c5c02ede894524193253fb49ef53429c8191d54830945d827743bbe616834b81d0f574451d0fd691903eb14f33a22ef2ee474e82b6b826c3f71a9a89bd2efd3418cf95f7c8c622ce26e70c7182a29613ec678f8f3eea8616c76acea0c880f59cedf612ca6e42bb7d8243f33397f2bb7350fdab5461eecd86678706c9eb5662f898f35fa4791386ae73dc615a726a1ca2d1915e7f4b9864dc99a69799d2b1035354bab6aa313f856f7d0e8dbc024885ac93363d8e31f2bd1ae062f21dfc09df816da6c416c43135f7200183d0ce966e2ebd316e901c803577840c35682e423db6880ba83490db8532ca0ee6742a3f1ea511cef88f44571d92e5f4e192da1d47daf309b6acd5e2eff955c136adad315988a790aea2ca8c47953cd2cb9542cbbade7ef821466c315748ecf71feb8e35f35f1c7b73226f0d972f2867e1ca47a1923f756c96b54a3e04d7f68374100c6f9c6b0d875336812b4b9a2bd40da48a8cc19483187c03b8221ee9065403919341b609f66b5034420107c89a0c7098d2c66d8cbe1e84217616369a6c92f605dee4d25240b7a11dc4295f032aac0afc76644bc90afe1bf9de821586ac0de80465f38b0c8df1780215ee0d580b9ae05eb6510553ea47acd802e45bedeef55071dbd9a158cc5fc015286b17f3f5f782db5ea5724cb8adc30f1da745593f16fd5a56fcd0812cde1cd00eae6a840a047d7567a5bd19f08e42f88c765fb8ace341b49256945550dc9c3be02166ab5c00c166961b1b9dbc47ea5b57e33cdadd08aa086f8de438eb17250c783e83c435598400acf776a41b355d97662465ae902645e242b5add76f7408efb3b8830d756a2d2ee2c3fabb3449bd4a336881450f85829b56c1122920034e293ebe592fc52489b6008d62892d6ec7035da493bb84a34eaa61ec1e52126c2475a40f414cddf41ebfb8181db0c2cf5bb4bf34f33007d3f367cc8aabd8f7983b474cd7f9bc4870efc64c30e0a559e744b712690080a7074bdd420e6cad1e08f6c5c1fb6cb87be918ce09c9aba40e95d5b48959593670ad4481e48c2d141200bfdcc67039586e7108ba800a0dfac2cee5d8caa9a5277b556fcc2be284d6a47470d53ac866f8a894033850306f213af4444eb901b659a3170651f8e988881340b2520953314175ccb336788c3bcdcac50d4f5234d42a14cb95d6a5d1e991ffd92d24ac77e6a7c325ffe65117278db4d8eda6dfb1a9ed9caa3f30338c9ac53491257efc57b56f99459a67a3dd95cb5ef7c760d68aead2da1e48839cc71418450c81bc7833d95f843176947366d6b09c56efc4d801e1efbf6152605aad2b38cb26b5526b1960e935276c38e8f93608e820cda309eef4d1bf06b754986756243418f2c959502d7e62bcb6e1149e0341968986d0385ce88029709bc1044586140d6ad028f116ba96a9d1a7e84597fa769c7eb32e1cde8af956f6c4c415018ec0160d243352b99a2401d1d01eb854a8cccc9db3d4487c63adad6199eef296f193d5a1cd96899aae1405bf540874f2312c0ddbede7e0497601bf6ecc0d3497fd81baf62e2cf40f06fd2a2a16bf9186f06656bb8a28297b2f22c56ceba9ea7e4eb971ad3a76bf2ca1830afbbb12c2aa51fc268c10107aaeb4f3f65345b809926ae36702491406fb9cd545824000c508cf241462e735edeb314d95579cc319efd805f34c5d9ec1ad989c4a66fede1449bb0a532b04e057a586b5e65d7f5820a67631db69dd9f9d08c2b1705ba7bda364d06b4bbe59e9d1375c986e2b60bb6835a7aea29e66b8b3f77366e11d7ce8eb8a2a55af5b746735905342a9298082d3ba04c7bd9338002d4af0196c97939b8a1a8d0ebb1a255197d0130a0074033407b1444520aa530cd20a60dd3039610a4d458539a68712a2567565178f959baa4b3b4550100a71e99075815806b09f3ea50e9636b283399d77f27714c50d39a0a19042f7fd2f087f203b7f219ac141777c5549ba5cd2d7687b3c5f6e25170b622d692e6744833bd420891202cff814b54bbac4e4f590bc146af60009d489c3be4ba08ae71bf41d121e6f65008da93dcd55bdd5a1465ea7788364e8222f7b6c8df181a1a0baa75c4288eab27dd433313e8d7ffe9d9cfd92eb6239b330c94d2a8716de05cfe3fec6124fbdf7f08b3915ab9fd7ad15d34e4dd8f266f7098db370d96eec9b14a061dd4ddaf21e67c41012f94071b067589b46124757d1467210c069b8c3d4e516984514816d0b406bca6a457eec9e72d5b55bf1be0b5af982e0cc89ecd54a6facb8950d291c6b501cb755958c41670b83bafc205cf710b8c9c441b57e08c6d022912f2a7517d145fa32f2927e1ac0b5074d9d113c1a6a2db4932c3096944ff3bcb9e64bd0f9c604054c4d7f298c5d2bf17b4474ac6878c60be22fa9091f5c79c11ad48d15bcb7650819350c9342701c9c98c8d45fedf3face42c99e7bb409966b9206c2a4649205ab0db219645799284604aedd2831640a0bbad580ada3bc3abfa9eb8002a3f3c3793e5d1c7c9fbd5e5315c2ff209fceee1b82796949e6da052f0579017160fef47b89c009837571b6ed480b977e64d4a1a668678bb04242cdf88f2395c37e7b7ce268341bbbdc788b663ed968fce45379eca9474ae1b8c23092885297fbc12ca2d7a0c74f56ea45239ddc54b90de78d2e10503308338f8158d14d90d30e32221c0d523107e206090104ad77987df4869d66fab58c3fc73ab9e2ae21b580bb3dbe72309591cad8cf28c1ad0cb054e484921f6bb103cf0f6cbd71d42d435bd497e52b46682f90de407463aa708cb4f5243c430b7fb29d5c238cffde13d8225db2abcbd85a19b922ea2b855db821bd30a97be4cde58f07fae7256eaacd079e8fe3f72bc31a28e259bce82380e3e6ffb44b3d8f2842991bfc25a87ee71cb9012060a9008340f490810aac1875e41a2e639aa4d3f7f2e0ba920902c7fcb7b4009e013bcb4e29b527910483ba15f2af7884846f74d862307eb89d99732d8c597662835a814a2601eac54ba7a46956e8ebaee87bafc146b3d1c32f1a718685c95f7cc45a9ea1d0089c933d0c730d7413cae93a1281f0666044d7f5f0c9fca10f6fa428df8c343041a1a89b1e5e8a54a00b163976366ad0a3ea082545128cdce7210274ab9ec698d5b8850edd0c7cfff14e6279b48b269461e4472c4692b52706a277d3eda7183ee5c9a77b1fb9bb71bf948151f60bdaae74db70660063363f691de2d39f1751fbce06ffbf6226f35dec7bfbf6acef1eb1246a8d5275a1e63a0a1d676ced01080e4b49284722504fbcc9466f98f91ed6e052835034572696db67c2e1016d1231c8d1da5953c007fc5fce30006b9177cbe8c23900234b203aafcf69c5c308c3aa2366545bea5cb6225f074dede7b5c17d9b0631eee0c49816b64b89ce469308f26db210f162dace713305faa852020030c0741c4f0c9e4bf8cd3e865879bfbcef372ec813bd3d68cb78462282d6d55833f48234422bbbbbb77f80a3c0999093f146162240b15b446da25de13872f69fe24593572555f66d053e9e3f9b1caca3165459ebc71fdf641bded5651557d9c84a87f546540553547ad201f515dc705622055f85763042a68e5a43494a7a40d8a41c7201f29d0bdaf7ff74b15e69fea9e093fddfbeacc6911c7ef72e579dd0341c73f3c296dd4145555dd5519f4683b6b1f5c253f1cc17ce7477efc999334306b3d255fae52d447d2f1040a56bd478d42ce57a668d22f50c7fb84da2f9f61e60d79b3b08fe6335a26cb28c1a2654e08b10508263934dae242933232c9fa00460d5f7c25530f352f37600182960729395ccf49ed85264a649d43cdf542159b6cba21892f50a094b0952501c4137d4d352401b38149b64db478510312b132d1d2c50669b50c5aa6d8305fd0126ba28588c68e8c3163544338510443d0942d467c1873bf69f3bd9ece02e769f13569ac330ae32d29e818632f56f4bac4b2e5047d14ff3a6192807400ceb7015dc268e18615a2e0f2441422acb518079b10a07265c2690516315c2c9a0c6df045d017677430038511ed010b2345a2c8515193f3e28828c50b2e4bae7441c4959685d2a4c8628c73088144b7d65e7cefbd36c78594fb82e46a69ed0a46d65a7b2d8dcf9273a1be581fd573850a4229a23832e60649992d4712804518065108c4242ddcb060c68867a685571922be32b4570c1eb450a6882c434d0cf9c0030c4f9888704418a2146ab8a2092ab4880c2c35647429b2023070c840820401f5f58c2850a898c5e0448912f4c9ae87d2ae88194a421790192328091827372478e226060b3260d942c34d915911235d84d46596312c8cd961870958d15529938209aa08c143849627ac7891c548155407ba84081a64644851b2a5052939785f5870401932b22cb162082d484071588151b7d6da6b11f0f5d498c818173af14282e244688c91970885f6a1c7fba6bef7e67befbdaf3d4d840c1bb8541922e20558ebded0454877212a32bdd04381001280372111e31f7adb659627c0dc7aea373d9b311623b5b5539ea0010b7b43931427a46891493fd846a005162008850425d05def491363b250226b930e67b4c0e14a8b5fe323265ad8e25a4d456eaa7386a32576d8e25aefce1894a042e6da09039725c6805d1e71b9d2c7ef319131655f0c365fd385c2063250828f1d3d93082ab359651631ca290239ced87c3d5f9cfff37be6ef980f647e09f337307fbaa6ecd6acc4398a2250601104064682af1062eec5b74c19a01049f4529758849835a11780b16314253fb88438ba61043233475bbee00954e1c4065bd0114f54a0361c6dc1d140eaf2680b176c448fc8074807983981674da61b5bb84041028a9d1840b4720d605cecc5abd2aab678e16bc6895ae472b143162fbe4029018e071a882818239674c31b63e608334ecccc00eeb670c00d41a5bd568d7b610cbed6da37a1acb5f6da4c830a15d4f4e464c022db69a3b2850b60ae98200cda840a2c998a2d4570916ba3543c91840a2a644ca61e21bad4c498a2c44bc664cc0c03a7e0b3c5185bb07041288b8ece30a2e67c7149894c498b52ae942be990ccf9220c3682212a03edf690c2ed02468411f7e23bbfe86102b1f08587233cd0c045166264e815d683d8e5510c5ab4a890ed134532ce38df7bef0af8de2195d873d3659631485c26a89badb5b6081417a888105fc06ca08265499958b72f8ae9d666c9a28b6eadbd364b1659b2a852b3a031d018941843840c58ac4036c50b52a452b87c13862b8c0b4fbc60e4a575290cfdde9b6426a1e51d14696932cc9ea0c202105eaaa02f84918db144bf515af75e7c71add5d65a9790b69b77c54c0a74284324250627503d3e70452ed638532fd7d3f6b5b56228d12d9596b538ebfc596bb257dad7d68a8143b73cb4accd5825460d6fff4380184ac2d88561457e21000149bef458707ed70303061af5f362f50de30511132828c309962a2e90b9e1623084a8c84db6891dac2431c4c41143b410c40e2a51672f6ca6b4d98c0e882d2ff00003134858b80206143180c1113d2aa0ccbc98010a2b645a19d673184a98d82fa47862dcb841838c4246b1dbd91bc05b861edd0c14650827b0b44002170c07255534f1a65072d20101c55012303879a16593d82c5d8eb0f6da1c60e82e539ac019170e599c71c6978b213100347b13baf7de8b2f956398e152d36516258ac039ac900b2307a32fa0200144105d8104994800a8399b228932443e30b1998048004a64bbc5192db0174379172b11ed3ea29bd32f1e9250e07bc133511001c560d8414916669c7c5101c99929677e8072f4001cb6f4481f551e500c51e410432e872d6652a046ba5ca257232b4ccc40d182c6848bd6ab8ff2a68417b94cc5a2c418bdbe8f10e094e0d26dbac4a2c46c8a2ca82cd474cb10e5cbdcf33a6b09f3ad0007695fdb17ad7d94b5d65e7be68724b2f49e334bfaedf28a184a66c0980825460400e812cb0a27e8e016fc1acb0a25c0b28251ffbabc5246192b5aa85019830c932684bcd02249ba04ada028f11280a04ea241005d6249f2a5d3f09081ab8b5e50a215ed8d2eb12889520695c965973dcf7be5c00fb6a48b9c7336f2e2b2045f9508e674677ed5bcca04ee326443919b7dc56c28120681ef77c5a729c6f74be269953cc137a5b61a892e0533e38499245db8f0640a1d42b2fb8842b04485e5c8edde9c330d6f2189690110c10012dd90f125514dc510182447644676375d5ec91581022faba8d830b6f96a135c81f2f0cf8cb00ac8a8a9422443cde19ae04cc9c3d384a2b2c3d58b297a7ed392abafbe39e7705facac9e2892f4ecba3db8874a11edc921e57e486678997a5159c981d7b32274efbdf7efbd2d11b8309157898cd099acd0a6174dc4d9154b66a044d9129168d05a4fd131292287c4888de12531d45611b2db830cd4889c3dea7856c90d11050b18632366752575952c8cf450c50c277b9e87ea020355a9f772ced948ceb78a266678d44bcc16d1175f7c73ce19c9ab48457a30aec20a9b2e39efcb17e0991c72e85c8518d7935d6652d07a9ed2caf9aa421a24481ef8d570a29e174f0323584371a435e5a8c2484c5e649f17285fca2079180a1bc6269c00cb163c18a940ca115405286ee195323bb0e0698d0028ac7822f4421de9d100b4f584a40f4729e57b6ffebad490c2132a67602e3142592cb99efc42ca47adfee2b229d8175d644812740598a02fb68eb1ce9ec66166e8f8ed6c9500f7d5db29aa0ae10530b4803911851152b470083ac6f2650a249aab9c3082c97feb4bed555cd82c5c94a4a60294d031849fe729f12a25b9175fadb79c11efbd0ae05223f550c4d33ac9ebe3625744972ef8dda02cb65d125101361d16970c4e505aebfc795a8cda0cd8cb790a5d492b47214a8c302b7c3692185c34f17420121774195f0d31e433316f081970199d6ee29201cbbb3030d83335bcdbdd6ab519a34bb444012bd0c95c50401945630841a40033385597588886308235d59e1551262f229e8158e6cdace4f0e56cc4c8ad2faa3ea56ad162d7882845924a45130a899da555c13424868cdc2b050b1889db122352c480918081a18dc0a33501ab41c1929b18342a6b0f0bcea4af17ecaa2b39b5cc73117dbc87aa8e68de6bad4b608df057ad3e9a5d2ed484ca72b346eebd488062eb4896efbd97c888c662d4efbdf7dedbca02a3f7684b10c638a58fc010e59e5c73ead278c83423233d588a72b8a047b83cadb1bcea2af4202b2132a16e97c9912bb4237658e1ca0b8fd1b8763dcff3a428027366027719fa6ce8025a30318c02b04aa1bb2c294148682e24b182323485238f8917de0a2c3c8a124d28295c567811e69c73ce51dc6e1829282aa2132308284ea8cbc8136bc4062dbf84b92228e72b569cb952a4a4181c8638a20b123861c30af30c18d9c50266071b54222a2f5754a48e5c5fa531abd31f41203aae3c0132036afb062a6bb630a7ae137873acdfbff5863fb33a142aebc6eeab5f58b5f571c72a4bb6487c448937d66fb5f5fb565759536b71145128cc43abac54aeaeee3f0e75cbd9723d5a8b3cb1cb134be57695255bae57864d5a2e15c345295a65a91054f32a9c6efe0667c2c1dd704c37db9b1ec796aa55960a361f54c387c8960a3f2f03b44e7cc80d4fd1eaeabe890fb1791b9eaaa568b47e9f27565943b35523abac9fd35f5a5165fd98fed68c2aebe7e6af8d6756593f367f6fb5540d19b6d574fd7e8d5a65f1c87862b67e459e188a87d66f8d5a11e298caf5295b8fe2bb1ab21ab21938457c973372e966afbaba9fdad5d5fd1ab41930575dddc7e13f436ac4eaea3e06afbaaa22de1f53b95e44a3684181153324e1d2ba3f6b95555f584199275070c0d2ba73088909ceecce7c695d1c49c810e6ccd051ebfec455d6a432860b2f305a70b52eb755d6cf6cede8fc7d8cabac5c65a1fe3ed65516cedfc74595f543e389dcb45e0668cd30a2c187ec70ec32e3c4ce6c870fd1e1f8a543d3e143723886fd7d5ccbe143501cc766f021381ccbeaeafebd19ff9c229a303b4f4cdab8cf93b709d9c68877d4f1cefa3dd516ae559609b74837b37573ab2c9b17a98592abfaf7efacb26a785095725531b8008844891821a52c6dbb023843d2cbcfa16795df965ef63cede93c5be17eb9b24fda2ad92357f64bb03c543d73fee4b35fb5d65659f5282e02656aa4b29d27a1d6b2cafae8ded12275690cfea57dbf33bfa7abfa38699386bd88e3a4a1de86a2d1cc350ae442d3e8d2681f8fd515fd2157f49d283201159dfe0e90e9eaaa3e4ad9948d3b26ccae9236e8ef3efba892e130e2a8ba54c098882203fe79efbdf7de9cadadb5da1f278d47eef5ad384dd56a698356d817719c5f615d3caaa77e0995c46bad4ba88ad6ffc4af2a551f1f7fe52255d1b76f6b9db3ce59e7ac7bbc576e0ed8496915bb290c41d27a0f4faae8ad92ce2bb5d4515fdf5ebfc22a6bca557db1da50f928c4d4311038af05275845ffb380d0d5bcdd70b85a8e1c26138d1eca22d1d57ca9499ad429f6421c491dbf671f9bba885f736c7fda9dc1572cd74765792fff164d0ee6cbbf50f253f9545759548b52d6543d2c555da174ba953fa691ae63655dd09ca8eb4bac45b92d3c00d285e5f5a545a43fd61709f206c64f819c78dbc7ad9b400488e640e40adb78c85a9fdc0414fa7d5565a9e40a7f8f963412fa95524e6ce90467c8434abbf7a4b35e238d0494a91184ed7c90ff7eed7492549455f3b296124d7716d11985b2740ca4611a495488a38e49ea8371a2cffc1a2bc23350ef2737cf6714ba9a328bf0141205e3e31388a38ea9eacf22aa02234f7ff39284671fe9de39e7a4ac9124899ac81b11d12cd36da74280e072555cb7b00ff62da13ef487156eb5b23edb8767377bb6f04cfc51da6c7e94374cfb609565e2d3e845946a069ee530fd2869a81cae5133eaca7e3013b7118bf4ab321fbf87f6d9569075db473cd34da80f0da267592156f189cfa2ba6ae128442fc426107780cca28e6fa2ce55560d176f1a27755c5975ccb375a4ba3e3f879c869fcd26d6fc388bb01559829e55d66dd5f7729565f3d5f4f5f4f5b1d1e480f4f5711052c77d14aad6cc474debb565f9d8d3737df470af5b74a1481bb3c27454b773b95ebd5ad8c4e57a8f91fd5be4fda8a1106f5e565937fca55b3509d1c449fc16cd1bf3ab16b1d2c42f92a0cd2ea1b2fe4ba82c4feb5ad7b6d251eaf81d558f17d74bc05f44dbf4422c75998568d6659f5d889f4d6b51c4b1caba38b99a9fd3ba3e3f36df357bd160b58e63b65e1f97409c3f7eb05ec30f26046afee645a8f99b07ea37dbf42454968984cabaf95abf8625949268f8a8ab9b0da47a36939078e9b6cf308dfa501f2bf52792a35e69af540a9ef110e1f4352fc3116afef4b1ca3a711f757aba5adfdbf55a24564f9765b6234bf48a6760269ee524b12eb57499e588973e430f80cc222f621791ce2a6bf22057f5a5d0aad47abdd2ebacb2648b56c3b659246dd4ef42d432ae635455f113e208a449bab2260d3097cb95c2b462adf43a75468eaa6e0a5c1f278d4b51b7ddc088d177ea1004f00b795c1efaaffe1d54f39dccede359fd5a7591feaa8b6c0944cc6bf8b5d5d5e5f766d44110888606e0069003a2ab4f117e660b3f4889ccba9059eb33e471eddd38946ef003d4c28f45ca8268d4a713d8265e2744cbc789eb1ddb44f9e3b7d36230902ac2a7aba10877c6a9ebd236405538f11a752aa4531164ebdbd5d57c4c02d1be9562c4efdfeedb7dbb6f776955ebcabf1d55812ebac1a47d658e88e3b7fb761574511f697493801c3841f7fb334b0b5eba9d8f02f519e5147dfe04a2cf2c2d2cd1a7d4a29f30fb0fda77281f7f7a7dd9efd7650771d6248f7437ed20feee672bfda6fc304823df84d9efe5f609b1a7b2f49c75ecb992d28c1ee81237214ad2dd1fd0dd847ca60c57a71c334155d276ba77f012a27cd969b7218f593b28c58b81cb4bc80075d595fc8993f2c71ca3a449ae51f44e8931ff21d2aab3d65a25a6198974daa76b0b28535f3b697240b7e4b8f7addd51effd4a64565520dedf51311e7b9efa60ae73501f7c7b760e3b5bb5be89e29a38ea6ee76a4eda25ed87a125e62fe9f6c851dfa0cba32344fd3e55e1c70f7e1f1fa5fc52f8c1d7274dd823bf24a1cb9f62c2d0037977e44b10cc2f69c4f9f6cab7f3edfd1df506f19e489fb234a794251e240c3339b02fc739d21e8ae9724a31769c534ecb8384effdbc24c9473b2bd08ffc3bef38a4f739757dac7f020d329f489737bcb7bebeaf67ae8fd586cfc729a64b6bed9562c20fe44f39bdcbe7e63be28320cc977cfc315f86305f3e09133739907f4f901a27f6f05ef220f2f597c2102c69be67e7a5097bd80fc3104874daeb8124baa4eb2df7a7545425678ff97f77fdd2febe66db7ce724d0f0ebfd2884345e793d1ec4befe2bc34c0ec6d9ed7cc9c74aeae18f42e47dfb928f738fb5e6efcf10042d3fe4e31cf98ef7f5c3172b4b7ebd3f0a2175fda4906b9c389e50bfb739a1f6b0c7fd209a8f97aec20fe593b8bef2c1ef49c0a1079fdc9fd20110ef96b6d66c6c6d05284b9240c34c0ee614d3ed96959bbe90200627464c181c0961c48809c1ac5d253f2099b5d4687765a8aa46552b71a4b817f5a1a37d7522ea437fe8f4296eceafbbcab275d739154357f429a75487e23860438ac3218e33d6f5db1ff5fd51c43fa262dbee9e5e81f4fa3dbd726b6194569b86f58a254b5a21e516e07f618ffc41444ef35e1802a96721122744deb4ace3cf7cec0050e94b391d7a00d27d5d420110e983f877d027af6fd9544dbf446672303bd5469d9672321d749492ae8333c4efba425788a3785da68dda34428fefdc979d03afcabab80cd48fdd66af5d0efaf3f2b1d6fafcf9b55659d7656b0dd75aaeb57b5d17f351bcae490255c9a7bb0254253fc32ec89202990894e098386a8d9a9d6e13b724d9e9f3f902d8e71e81fa041f04f9eb3d0215758deb57deb608344f7a1a8e40c3493fc0b7df03e435a00ef28a450c41be3302cd872f020d0f1fa8cb100441a0feedfced3d6a1990acfb903676502215c8a3f408fd3805e2841571250c703ef1b015e2fcb77c14a715903e48b70380d495ece143da98ef43da901f8ab0a3aea4071c987f01589f3fce267dde4a9b4553684bcc3927be76ce9b1891cf25d33551b87d9f3279abb3daaae464141604285355be7c701ec916a8b1d69596fb42cc58521f3a0569b6664d8b38521c9f56a88a4ed9a26fbf565b755dd600cad33a01656ac400d6ef83958fb7575b69a6aebaa3c5501167269c99118ec9a8ae304e515d619327c3604d501da2424dcd9b785ea7a806e72d789c9c212a984ca7d35ff027d410156e3ec8e655b87993e9f79bfe69bc0a333ec8e6f9909b9bffbfe1e14366709be7799bdf79159eff8cc779a6b391978bbe1a3578067fc6e6c9b1affddf9e66c1fed98eef6e78efaa8ecee0dbce98b1df8b5111c1d895581f53b41a32ad451195a3555bfe3195d3a56295058a1a253e0a8ca5624578a027c35e1e6be8f84e07ce90e1bc8e4ed1e973728c4c8f4281436e9ec68c2136bfe3c572b2cafac9d175fca7d3aee3371955d6cf0c57c7deacb27e6a705e1de3f013adaef09f6ada64136f6e271cdf71bee37cc74714df8938b08e4b3f9e72e2977ee489e55dbf7549ebe10b16931519cd68351b2994933300681bcd6835db0b169315e16646b7225b4a564bc5683818bc7030709d7627dd29f73d48da37dd2ee54abd52b0da89768ad94eb593ec76b29d8a70a7dbc92877c29d66927625d785c85d07b5f73ae1c02eb089d9d83ccf96dd7c5165ed0faa1c67c6a3503a3abf4383c65b5023f5351eff36aaac9f0bf8d06c5db06795f5c3c387668b67d32aebe7f9d06cfdae55d6cfe643b3b5dff4f8b7adb27e381f9a2dfe275c65fdcc789c5c8e6e87c65b90e2a9590d9e8259b0533476ca6867a77476aaa8464a562315e31b83570ab73706aed4ed776a97b2a574a9da053b954bd1eaeafb3195039f06e31f538ff1d7a8d9d4b0d9dc7036357236b2cafad1e1dc95c3f7ada8b27e509cbf66f08d33aaac1f1cce6127be73b3cafa31711ee35b578356593f36bc867f507a0fa07890f9b24f5a19b5ae7b6884389e6242a6ac875f0af70766376196d1e7cf2aa2fdfa5f7dfb24fae3cf7ccc3eb915f167e21e55251e9a7d1b4fa718e9e3a1e59ee7f5ae9d0e77b3d564453c3cb38e3f571f4fb86ef9f8b89acfd5d4bccd8deee6e64d1f547f77c2c1bf5d33501f54735ee7f1ffd36e1effd72aeb07e76d95f583fa5bceeb6c2edba8cd67ecade3b0bac27fda3b5757f84d9bbfea0affcddeb8bac26fb3b9abaef0d7ec7dab2b5a2bfdeaeb0fe7be89e06947b5a3aa7ee3cf46b9ebe3cff48f60cce6f151da78e6f35811f7adb2aaadaef06b2d8a2854b5f122eef2f66ddf2a4ede744f8eeec97dd3b83e9e62346e3b339d186a37e3369e62b24edbf91f9d47c92aeba7e667e054d64fce9f4c8f7a9d9e195f9303e76d3ea88e9276fa9c0faaa6bff951d6248d56ebdf4f3ecaddaebbbac29fb3655d81b9d7a172948f228e7ffdccebcf33ddab1a02f24cabe6ebfe31771dd4fc3cc30263d5d5c7532c3643fa798fd787fa74ff9864f42735bf5339044aad9a97bd843ee6a7ae9ef9388366ab86ffd87c104fabe67750b0660bbd7cb03fe4830909a8d92f1f6c4c47cfff01dc7390fcb27f7bb4b53d82424c1982082a41e4e4f410c5871f80309212945f1ab46a9c3c29e201ca0eb2839aff09ca41b28b08c6a8a1e6876c901dbcac4c76f022dd203b789970901dbc68e470f3f8411d6407af0c5a37fc837464901dbcf40cb28397c84476f04235911dbc9e869ac70fc6640735fc47871749402b87fffcb868f09fa05c2401ad9d220968dddcd4b46a3e28ebf09f9f9706ad1afe93f3ff3a7fc1ffec3ccfffdcbc05ff53f3341e3f38ab2cd96ae9e82944eaeab256593ffb89dcb4f0db9c0d9fe1b88dd1f3226bdb7cc88cd5151e22ebca5659286e83ba55d68c198f716cf8109b5c659d4e8fbfea2acbc4f9101c141f62c25f77b2666515e36ab375fcb6af2bfc385b56d39615dbecd1d250391137ca1bfedf99675fb0378dbdb375b6acab30879f62f5867bf30aad8f9ea5f9fb788acd204449a3c9fa985fb6256463fa21ddbaf99ac741598396d0890b0df5b470727ec60fe5689d5e6888d4da79cb754b088317b2e069bc8ae7858654adfd3f846a11e0291f4591a77ea8a755e3877a5a355f73062d210cf890aa0500d50ff5b402f043a616063f8a415968e85b42037801fcea656a090d800f89ad01bcd0508e968d1f42b532f8c9c72700078be806380add00ff50aa051a4d03601b1b8442e2c09fc106bbc80df00f60834f481cf805b041db3400fed50697a01be0576d300989037f0036a845e2c00f800d8e40e2c08fc1066b7403fca90d063137c05f638344481cf8f906a9481cf86b36389338f0ef0dee2071e0ff0d3a9138f0f36cf089c481ff820d1e491cf82dd8208d6e809fc606919038f0ef6c504637c0afb3411d240efc391ba441e2c08fda60138903ff8c0dc6e806f871365883c481ffb4411b240efca60d8a40e2c07fb3c12a7203fc361b3c42e2e8216954378239f3d13edde30c21f791ba46a90373ad4d0e66c75fab5ba48e8a69a77d3093c89e8cfa8c39d68ba8cf788a9d6227d9a9a8b2be85ff64749af2a759ac890ed4079f681dcb5ae3a9d6f19f6c1dffc94bc79f65d467dcb78e7313eab3d3317eb072e161d32b176903ffbe491d361dbfac4207992bb030619ee935fcb93ea94fa40dfc3a3a50b7481bf8ab135093a497bd534caeeedfccc752f5aa3ec54a97c4633ae995d79ad491f9387b07a40aba9436f2673ee61fa9eb839944cfbcd6b8106d3a08c668b58e6d5d24e9f87397475d14e9609747ba32fdebf2a88b257da42edbf442ecf2c88b251d07871346eaa8a7d8e4226dd8cf7bd6b2481ddee39f55481df5f14f1a16faf8e7116579b1bac24ff28090a24a1bf4bd5865594963a4d18b9121cf481df9f14f31949563d59b3239a0ae999fa820c7b4183d223a7eb0ee531369037f3ecd3a7e7d9ad24f34c815fe930cf2067e1ce5c96987d34843d04f316903ff14421c4fb18e4121a40a7fdd201369034b79a33efe1cab2cb0095de1077be8f8c7521f730cd4a1635cf9f83956590154452291be3f8106014b24d2f761f89148bf8396404a0a69f8bd0ea6b1e1d384dfd390869504923e7c1a92be12999e93d494acbdb654a6646d2957fa9216a5d217b6a42be94a64aaf8b654b2f94b253b96ca5869ad7d71964abf83da4c5bfa1368e7627e9d5bf3a3f8355be4b2eefd28ded27c9ad28b6fb758e2a31079cb6fbf44a644a644a644a64446e2f209c09a29a599524be767144a5ae43294525aca95bec8f925cd396bacf3e34af3f9e948228120489f4449200df7c29004f28f731349c3305d53a887aa34709510e588052d3afd0a58ae015d89e374f5cc27fd0544a72980e9f4a7d013a943020f52567ec9cabc841446d1b8dc24ebaa870412c439b97c4a2d12b69e31d6251db65a576d35d625dd57d269fd33dcba9e7f0cbf8ea4f774746b1ca7e09738cd48435e49dcfbece3bc1f8578f54b644a644a644a64aa0dcfa002512740974742602648f3a00c7b84f9f5d6a1796fcb07c149b2e10470fd7b12eacabe0c4170c8ad7f0f7220d2c610a3fe81436cfdfb1aeea3ae2c08824360fdfbf8a85fce2e430f48dc7bfd3dbe1180d495f703fcef7b80de7ffae33b22d8f01d3bea4a7fdfc75ff351887ca04e6d48ed0eb35a942c332966953b65849852490ed82e64cebaa42a3a0428536335eaf6e7b4d2276d4eae495a809334b9b43ab15698ae1576abb01b262306d17f41585d427d62b589acea508ba8cfce9f414f5f3e6b738969ab2d417d3e1bf5c1d3b3d3f6580bcf96c8cc1b1e9f980b11bf9c3532b7f9f9abcdddafdff33bd6a31798294673396fd8fbbdf763ce7cb41edff5fc5a8ffa5aa36f0c7e6f4b208fee7192487cdc20698b50fa50d7f587bf83fe20fdfd1e249debfa2f89572c22df19a1f4342f4289e3ba7e1a12e97bc84ee2decfaf33e4b13550cf98dffa34e10632866ad0e98339474781fc504aa94b4fdddd519f3117dd2fe8d5c5c4899ff6117284509f1c0f42fdb99ed3e5519225b41083dcbfb75780fa9474404ac800f5d15c3fcdf9b973440aa32aba69fedba5d77cfce1d3f34ca8dd7b0fbc2fe56ec6651a8600f69cb7d65aeb526ed3bcb7734a39d3d0e4a701f38b9b36895195fea97f66b07b53763d7f07c5f9b196b6f831ea233e8d511ffa948ff7de5d7a5dfad97dd5d5ca256dd8bccecf508419dbd59506b2674b6f9e92bc3a1a9bb3fef110fff300c8f3fc7875ff3b68ce961dd316cf1e75b6dc8df20684c22815c1ff76d0ef320c81e2baee41b82a451bf04f2fb484900b02a7bfb20efee983397b0e8da7c1f33baf7341902bbede99e6e7f6de13efcf8db7f7f9f11eff6e1e13005257f3721fd2c61cff3edf515713a8efa079d3bcb8c7db009ec72fc7fc34bce641d9025f3f282120caa3205bd76f01ed28c8a8e80351fcbcf5d36c5093ee165f861f783f41bc4baf77feb94bafc311e6c77a7ebcf50ffcf77b602058cf97488e48aee797e19d40af9eefbd253e12a911a9f54cefdff8989de7f3d638b1e66d1802cf6b1e84e7310f62c1ebbf5bc89c75fd93874baaa2f11eb7e0bfbf608fb6eb7c0d3f005f3f0d7f58c02d55d1e06ff39a8f3b5c5295ce5baad2e1363f4310261f67cf799c972108398ff3397b24d27170c20fc6fcfad68e0382ae3d878f433e12cea61d6703fdf2d1e64fa83cc01f2d8aa3de26fc413bea71368a8fb3e380365bbf146d5e6f9cb779fd33f609b3e39c603bcecbb0c78cc719238eb9a8d3dff96076fd3cc8fdd38ffb27bef3e3271fbf7e5fc84acfa0cb2321580f72fff4200d7f7c21807ffa1d547a7c049a338fd296b79039eba7bf796f7f6076fda73f711af6084738edf1be7e506fefc1b9f30ff1f3f710b99436722e21cbba9a99eff8903d7f0fd933dfd1e7eb4dfbdc637ed3cff047ed1e58431ef3cc0480d415fef93d34f7216de09ff847d8ff2fc2e63bb8ac78ce09d43d1ee43ef8990b99b37ef969c6163b4e37ed71eefaf7377b2452b39142e6ac7f60cef0c709dcf7c32dfbf61eef71cebca7a470cfbe230bb1c702feea4a4f65544665e2d31c397a7a54aa7f51e41d501538eba57da32185b6df1d0ba03fb79de1fa0e5a74b586e5c840b2ae9fd268a81c628f1cafaed3b943e8a084ae7ff21c9a77405594ca72c8c61c9667d0c13f7d95ac2b9468ca4617d0950868a854dec9190517514c074a9bc88af2b594fa004282d4811f85acbd0f24a150735450ee3eb9ab9e94587429bbe85202f23ee5a387af2a03aaa240c2f9aa0c6806f47b7aeae43432089f52fa3490ea25a09452ca1c5d867bca950f908f397a501953a9fbfbd303f200480666fde9c3f2795d7a8ef55f45a48efa5a5f28d2867c2945118512ad7dfd792490868f3acc5ec6f9cb22d721481dd2e6c5c7decbdd8387070b5040ab27c066b37c36d0c00005c0d153b37bea8aea6ed5b86aea33ef971ebca52def7d1a71e2b4a7eab5569197b8d43db33e0da721fdb4f82aca8147e72d9a376aad7fb98fbaaaf65ecf9b5ecdbeb6caa7e7cdba7c7df3bd46b54e5bebbdcdb7bc446d26aecf03e4c031aef6ac997a85e3005bf6a09dbabed20e8be96064451f4dd82c9a32a3614a7de68d04fef7f9f11d5fd5f325540e31e42ab9aa13e45a7394ae5af7ddab055edae0f1963fd1bf01eeda402d033521b05aad06ab22050683e132f56075e6666e477d5e9dd6598606ea897ecd755dcd3a029572bca4a3aa1bd2c67c497dc0da73bfdefb74d7bfd47eadf475e8bcca8afa9cb96a544b64a601eacfaf46936ebea3ca5b22336fd4aff489743b02d59c38dee8d1c0de903a248d9a42c9cfbc67e67a7a7a72b95c8ee64541aaa2acebfc255dd7b60e802eb32429cab5765dd487ceba9b1035a13e34d6e7fbc84e7d627509162207ecacf52a6fbd54bae84ffac4c6864b90aa4010ac63f8c1d76b29ec214eaf7b2f3bfd928efa784f29283e08d6fab7fe95f46ffd2b4fa041484fa45749532ba5b125329383fbb4f291d29e4bbad9474aebe541f293be5eca470bf44304855e317d59bf54a68ff84fa041ea13e9748fa3edf2ed58faa28f27dc3004fb38ffbd7c2ce93a7e9cbca5bfbf33899724bff4fea84f6b498bc9017d49ad0eff58d2f54b7aca83d0b7f3d6e0d9ad72144212c31ef583483ece5225e159bd34a2acdbfda2aa4a7bd4171f6ffa72e3a7d9e097f658b3c5fd44c461a6f9fc37f1e997c84c0ec6a9437afcf9c50767ce3983003e89cac46e2b08627e1aba472161e63be1e3cfb5765d14461f7fde1a270a91b89e5f7cfce02844de462deb01a235a8744c377641eb14aa1900000080020316002030140c87c462a1300ca324d87d14000b76ac4a6052998b835910a4208882206008328600420031c6803235462300609b7cc579679c70e7ed3317d34c8f6ac71b5b9ddac54bf12a257b377dad4108f55cb5dd463795ece888bcec9ed68efbeb7b5567426af2b27bf83669f602f2df217012ee1571a7a98d970074d97d357f58fddda6b0a4f41b74b4150ba79f1ceb5c32574d6faa5e48ad3a03ee3012c8f1a7aecf9bbeed3365e88dcb468b6a117263e0635eaae4cb1b2cf0dab8928c4aea85f622ce4f681c07ab21a82b3ee1ad8b747fd505197e1b947a218892c9e25a1e25e31dc82f79ccf9e35743b72d11e2947aa10a33a7fa64359fd5fda511546fa02ee0e8854fe5064704b6fd982ea54f5e7b9465a8d6583c5e447543bd2d730f6bf9f82a32a7dcdb490b43fddd345219cd37da2a213c223035d8c40b618eeeeffc870ca417b21aa3a8d8ac2286934f77f782f6e4526af15a462b5717b7aadadce73c6a93374a136117b4442fcc1bcb35c86310436ea0546bff9c0d50e337d5a7e41bb6625ce2135ff3c67c365d4a8839fe33357ff1f72c1142442fa4afc3eeec6b05fb3fd075039d4f9d442fb4db6d180ef2bdada1831e12d87c5c61e3ef7dc6e27ffb3c4008e5bc0bad5d44be12f51716869c04b93667fe3c178815d701715ee4b5af2ed5a3c150c0a058a9eb76f07611dbefee2d3898a533b8d27dd0f8a9ba0cae51805554c5c5800917a52fc1c1d651c1e84f803b2a8dc7f90b236d7809cb9d4ac713013dd26b0845342be9a8234965b669d69a3bf312aa92c33e9911b82ea9809bf8ec083ad104b48465b1e29469953275b29f02816ac8729c9e39262ad5f6b309241d126b428d48be56dc310f42897b43da92ba08c7416e1ba741245940706a3187cdcd5ce2342c19489863a022e0027dd58766bec6b90c8559c44a368b56cfb7d61bca012f4df6d3cb90783ee413225b72f4910a13a907cce451fea2155aa7de5fff67cef10df28f9fea7121c67598865b9baa2c847c88c89a32900e0bee95ff1e2a54c132309250b017a09121d6849b7fadcdf83cab0796d744105e33fff8401077f32728555582b329bdacc3b439e575bd4d8188e618a21b9e13a6736b32126c03fc9f7089b2812b20f9147c21a920372f8adc4566fe0e4881a280cdda0a152892975350e1be46ac33402af4d25ade9cfd5617019bcfb44e97f93db2bf4ac1c24a136c24f0f165353b56e81f763b8a26ec2cb76328c27acb676a4bb08b853a2abf136134d29be7386da1b79b50c2d98abb8dcbd7862bb1840ee5bddd9d74f0ea25a547c738aaf502297d66f80878bafbf0719ebc8a030d4690d06ba634aa95ba2741485dfd2018c79d34f200b8c553e1c3bb9f81a2df80ea11a43e64e857ef776094587438603c28d6b9cb45bb25e95808cf00c725295fe853670b2f3d894cc120b97c48c240df8bdf1f51718dc37be458f32305d37b44abd7ee406e22e0221883c801fb904c8f1d4c4324693fc95b0f63bd52ac20353c936cd87d3c4d88db0ac71f12b1c7941420f43c50a253334ad7f7344f5429ac60afeac07c79b80f9be250385fbfcc946b0c419b13013d92fc040f6e511e69f10d19323ce7140c85478f0263e20d9b1531c96893a0e41e199fc0c6aa65a4e5c8561009fe6844cd947d98f02ee256d987262c3d6ab9571cdb9b793c90b42c123232ef971202f2e478382c8e392744121620108b6102e9653ac01fe0419b5e2c7d36ec056deb43ae5de8525c7851a46e743b9e33b185a021de12034f4ce4882348a652afa60ac169e52daeb26e54cc12e9228ec3967ea9ae259ee34c02bd6001404ba4f524e4da274aaf5447bf9c7584f437cf14bbd623170f1ce61aa90dbc9d06339fc39a311c2b7a4cdad6cc87b3e5d913e76472099948d09ce90ff574613e6c72a99353a4869bc73f89c89df92df8334339d1ec80f9308f2ec8a01cf30f5e5c8298c80d85dbe217c354b265724158bf4da15849f2b35a0d0e94653c1017fda8af8ff16414407d084d2ab9914b7c9bae08ec12e0a4bbd616adc201ac22b488c9d446b9fde8c9ae59c3cc36fb4103b7f73b787ac5ed522328f164c7fa9eba6a56cc713133e7f2b02d68dee1cf860bfd8c186e1f88f4878c973b9ef1d8c4c6648b6dad9c7c602dffcaf0b7360d5dd87a3cd969341deac8e3d9b616b89b86747b32a45eae981932311505fdb99f056aff1fe923196532fc31124289ee51533a45be9ff9ab8e238f03819056c94316fddbd062a80907054ffe6692ba6510864245ddfca0316b3ed541c38ebceb53a2d408509c9d04371955b3bf4d89bff4b67b7149d6960e85a50a6420b353cdf7e53a92da2c0f650b5958ee506429bcfc612e86a48bad4f68686a5afd11808a494530e19d2a8783c40fb7a7dbbc463603dba636743e84aa646febaff20d2ae3c435fb764df6740c9980c43b691b30f2fc7fc1329ae1e8ba37d496e30406100648a1debeb75fa1f100ca469da6d81b3a92bb1af9e54a1647ae134f372ad63e9d02d8551c0da8bc18435adfea265c5410803790f5e30f18f643a6b900928dfba0fcde8390ea90b4b519b4ea5014b87e7384c4897cc46b96c943f0b2e25ba89ca68f7695cd404d0f59d4b211d974064ec36a4734b3fe6c2fbb98fd7d0ff4888e5a4cfe528c7515137658d2e351572b135312112b06811ccb326636b5db3736d95b4c8928a34673d017512698293d0224760060309f94bef0416449c928a17c35c76847bc7dfd46f3f36aae4486d3eb24aaf0a3395f58b19d32db9388a9674669245e2e94b3222a1daaea82560acd819da59a360cab3cdd36368d0e3d48892c4f82f218ae44254e016a592612cc8e43851fff9d9d5667c4f8150ac79fb6314f700d4ca24dad4e782661f68d3bb3320284b72a79fc06f9d8106843fca6916a4acf62149524393f18ac722ebd86ce821088299fcae46290035c60511aa3a0aa0d17c3365686e2cb8ca6fc848afdb269a09eff8b83de7e9afa3ed1156a14ebc6dee47cabf7f540209630e4449a7692cf68135eb34e56e05dd5e65574b244400acf4e6cb379999b86740d0518912d5d060180ea76a2f68d85a9e2d099aac7f3af36efd2b2268bad9cc2494f48fe72d7baef9cebc64db2404f8ec590cb4a300c3e8cc15211d758ddeb9c6ab966bd62ccb0745bd0c6ec5cbdb08b1de3c195877be2e989dc249a75d5d3cd4dfe6011957cad918a272ff9a8e152f910a148c457e74f2659abff6522c268d5fddb0720ef3ce176bb7e80829380e161b2cdf05b688689fda0ed7294ff0e89889a43898e81ee8dfdf4347b63efe50a35e93875d70715f35f3e0b679d1e8bc0c84da453f4c0069d6a5234dc9e68e623c9d0ab9bdab539caec11073f483560efa8ecd4f8a34706b07d1d45fff6d528f2d41b72f9a6b75f8f0447cc6fe76503e85ce877cbb795aba726d5453dd43c1e405e1ec74ec0fa5a787aa3b5b5b901bef3bd89a56144b38c682a2667df290bba2cffee97bf5f50c7d4482fb6de03d35ea2b241ff6da37bbd8a1ebadf9162ddeb1fd4b9235e088a71a78cf40706d76dae34b4f17055a8c4f56bd088eba67db9c1d0ef6880f7faef750cee2c091e972d3a573913a8d8ec24f781c0a9ef3672f4b31bee831bfca40a57df45dc1a99a494b02244a1da789588dfcc8038b9962f6db09bf96b5a43cb0680ca7e384e2f912e6364af75d4f150f8df98bf56b3c83aaf613650e6334a97f75423b55b48b2e7875e7c9ad31eb28d2e7371aa82112a992b6c86cb4cf03931011bdf411b3431189cc46afd1e225c24ea6721237cac6c66fcfca52476df73238e06854eaa0bbd0feba37978afebf0277a2e79d4ad0931d4bca714f75cb7f99308a8a8ed4a37ceb572f48db3148ea350784f7ebabe9dddbbdbf1ff27d55e4ea7d9cbd4bd18a9aa42fe6cb2bcd8853248f8b8d037e98ff0439a0d8bfcce347f4dafebeaf8d68ea9db55ef12bb6ae5689b374ec22bb36d407a7c0d37fd4bea16b0a7ac19378acad722ec1a590a877da0f4c43f57d9b3be91e7f103a06209cfeda252e22fcbe6ac89c068c932b91ac6fc024b5072c8759aa7873297ac33958804a0ea0d3ae50330afcf29f9abb0316d8fb1cf37cb37fb78500136bdf7f2a2ef99eaf5bdb288dd467046019d0bdbc5785774ec6f2c0fb4dc9b32229d9afb882803b53040bd94ced820cda5998832204a38512da2260a8382b2b16fe732950d7a893b23eb55a8c4c974f558444f9016cf98c359d183385069c888ea7b5f0b8c1747a1432e326091ae26635f52ef0c5d4d41b7404bdc92697f825f82b9c519c86679395a5387d2889a17ea83fa3e2820bb8adbf6898bd5677f2f5260fb3bd9ebb25d336eb0ee127cb7606b36ab4f98b644169d81b008e28828b09c59106238568639fd3f8506262712285cf93d0151e80174e392b977d5db573379b13b0e88c6ea316aaacc5aed75d005e75774173b1449038378442408265c33d78ff8cb3cb646b15fba89c816ff82ef1e18fc113aa303a74c616a8517e0696c5a9f9ea41c6105e4ebdae81216c64478ee076c6505a9bd66afd121489cdc6eee21e0b939dc3c7754ea6ca7913525c225d3dcc344d305af6d98a5e0f3cc492c55db9adbb11891c9580a01d700003b9dddb031b1c8629e3acfdb1a2ada5b55733ae04e0e059ab38ec06ed5f4787f6c6c6ed8d62cc44b560b7dc8441f1fdd9652285b13fc4431863740a3aeffa96fb99c9051c35e8c5e6957041a5170ef44a964cfd5a07199a2213f5b852968df08f798fec41af9eedc61c72a9c1eea8f64a6972bfe4b5e5650636fbb24f295f8b32c0e0a63cd97cd6095253c98edec735a2b4d87d04d229df09a76b3e040dab9f4d889b569e29609cf0560911a2cba6e33807907caa4f0c1bcf45df663dd60e7decc89e4f9c02df28a822c5e2a43109325884e60fa93ee10033f260fa6454d0fdbaa5e13d77d1c1039d7c23b21edda4c6fa84200dbd053486e8da9e472fe5c679cba71b3cff7c79a78d497e22732c00d211cbe1bb19eba4d6e5d9d418992df1e4616b7d0a8a8459d34a529ea3569f5670bca57baf686b88ec49071ec667a53e2d93aae851766c1134209d8ab5bbb472a16f7b77083dea1b80b58bc51b65cb9f69af4c02480e54105fc7d81faabf90047df7a022c8a42b5adde034be7a94551ba2f4a7e081ba83c8f19bb93f21484cd9cb9d84f2f0995994255017a2c0f9890ccb745a2211b84723ac94ed56a2468d7e42c8c1a192c5f0629e2885ede1fc8674e33d878a959da2b33ef428ebb76612f5a550330ac871aaa21d6561411bcb6539d0f5ce907516a1a07ddd6155434abe59e34b6100ee2c08730f1b604543b2083303c17b1388b81d5bda301a1d4912525bdbcd59c1ef4961f8e49452521821a1a0862dcbfa813518ce3c18e90daf0124dae9e09a24b63cbbc148158bfea8e6082ea681fb9d129935deb44487771d3fd26e9c899cfb6ab0f5b6e7cbd63cea0e2f0698a196fdce1e5bcd649f34e34572ae1d752e7f5e5a9b101cba512558cc6e23d353f50552af1b5bb077e0a28aa4585c476a2a678e496cba99456d14374dec4cb61e2868308651c01e4742ca70d08b8046dfa0df35c071f523fcd57182796a93903a3436b8dc998e214a26d500fbc595b359d5e60e0c2d5222201177719efe2c28b80f0cb6efb5b81015aefa6b67a8fe5828e5401308be19f082dc13a8f62c8bf91476c9ca190c27c4e052353a257dc0a4ae0bb0b3edfd0c7afe1306e604b4cfb5eb942e42ac2b93b52a7eb15551d54019528d34251acaaaffc2b3db63b2d23e68a73f8d1b251baea8a237aaf326fa6123270382344115a95753b15ede508153b91ccca8ea6f4380beae04f31d059744e0919da1175d6c5909539b5f681c3260d8c5aee558eb63d25710746bdf34923492768a0eaa0ccc9e397e098fbde68237e7a58c1713dff592017e80274b10f72a77c66fb6983386dcc1a024cdd3256f8f209dbc3923ba95a0f0f536122ab79864dcb971f7a8dab1cfd382090e1e59af4ed721301239b55ef8eb5d63216309ccd933c66fc4646477e0c8fa58c983757d54ca70a64ee99d0665681f206d46ca031630cc0e13348feb8e637e84eacf5122c697a466a30e4a33c0b36ce36469dbb2d6ea46f98b0cb0ecc20174ebb0edd6876f2f74961e9dc20b7f2febde9f28a498ced0aa6d889958ce454614331df68225ba0e9ee9e69b5a744bfe0ff12b652808311840f8e1b4c60a040d295095b45a8329e841de4333d9992810940561e794c7d202376b790e3faac195b8d2b987bc3d42db0eade19a469299096ea4182a396dc26ea1f02f384e6016db6583c0c6a9368016e1644aebea6f2e9fbde18938e34f0bd7c1b02ff574e9324026869c3768bc5d7c70736c8557e460d7c3561d031419e0767c01817a4aef14a654122bde6db9d91a526b17eaebe1c6209170cc79a8d539822f483a506421ba624848ac3982dc0818452ade4c37d6e3b93d02f77a7d85aa7b4286411252dd440f942db42cf609cfa13bdc2808dc653ff82748a0250b60a8cf3409bb7077df27fe0047a4bb1de3abe6e020c24d0521213fdc073e37cea32eba683a55dace984acd9c7ac65b95f7eff18a9200cad8d828999053895b95d6e21ae36c2185581c4b98600c65383005a76f735c445c38acf7ad7b5015b3747bac874ee5da3b7a3cdbe6054d39e218998480ab93526101cb03d5c7b915164b92e62cd8446c6d5d59af3330e622b62db450e8396e53afaa042de84c751b7a1b1d39fbb1e69c20bdf7d6a3d9afee45441689226a823141456ca9183e27408d03b9d2b85cf8b7db7a5f4f602d27727b71df715d907dbfd4503e979d0dad6e454154afd9b7078dd9508bc7080916ae3532d1aefa698a5866d2e838220b30e35ebb57135eddb283b049954206f1037b55fa5923bb1bac2665360754141041c67186759d5acd48056838c704b75c5bf026a3001b6dafe17b6ae59425543ab86e3f39bbbdcf13b43f006ebf6a532d53002589b6ea5720a0daa4511cc5081a0ad6530cfb96ceae8781c6f16a18246c803c813095dcb227a08985f712c77035d4fba89680d6605aa10c1c58966b07544cf74c2c7777108be8235dc4eddd1c4e7276c1e64824602c64964963c7c4d05716aaab592f18b5a4cf40d75bb561e2ff42ef113224b40804f52e97de358a451c04da0813ce63da187ea2fbcfd9c239162a180d876d6286f061278711e625e059f79702c4e5d50254fb290a7338dfb410ae01f19a70e99d9041d218d8026451c90b6fdbf13a5b081c7e42d1797023398f439fceef96ae811055c05f7fcb09854f2025b13f47035381ffd51684e4f5d0d1eac3db1f52b0a1aeb22c848fa0984537d6059821ef9db72e949ca482d329cc4503149d5952c14ab668ac7c024494f93219cb2ddce0505e60f16c9e7a8c107b0d39e532e02a023a7e74bb4dbb5ab5e50de164e3a85216276b7ff2472d984490b630bbfa7d38e44cacff486cbc8ae62153294d729ab0432e92d92b041ba46442e02eb2b04c16dae7c206203f1610bdd5c3b510b02879cac71a4db5e45c8c70d45320a1d09e9a5cac37e6ee87428f7300997f7e36bc81e5d9e4d697f90d8c851888afe899413135cb7df0ec6b6b5756a0ce9c9804d150a291fdf6c6dead1f31b6ffc22e76f384a5e920af23cb11b507866ca891c38c6adf7dfc62f7c439ea6af0010de8c3e3790c7a39efd2a70608cbd01c1192a348454d08ba63410561c319ac82459f64b862c7cef05e050acb538e5e5708208e28570c960481c73f7a4f34e7b7b3b51e8b9ae96a411ae35c5ea51aa0d111e3f865eb5442e47bd2913d4ba9681b6e5716a7bbaaf7e7af24eb4fd29e65b2f96c0ed389a91d894ce3d4d2be3bb4fac9885ddd9cce79c45f64e501566c02fb9f9fa34ce2458e8b6d772d386707479b72877a5c1bb5519e78a57c3067b092fd2cdeaaa0ab5624db7557df96206fb6ab9e886ce84b768758978d50c6961e9479d39d28222700b469cee13ad28686c7bb49b7a9fbdba7298e8e7b47ebef7b9d6ec6558286be68b9f7d37902b68140e448568e4821696214aaa8e4c1db179af5290b565545e6badd8f572c505f72224d5cc8af6aee4ad94839728481711a02e330bf8302080ffe564b1499ebfaa1b9ac77a20355a8c1912e6c174b91ba8106b7e424223389a28780c655b96011029485120d44e5171ae081262cd5511142a9945121297c5855b0ee61c8157796ed873a3b3858f8444ac41ceb7f76122856becbc62e317a3b2afb1f9d95fc44535b2398b8a23bc0f7ecfbf579d08e2e2dd556f5b61f91f3b92c3e96475dfd657b7a96b6ad4400b2b26b2dad404d444c94a2445521438026b5fbba2b0601525234018046a898b1a7fb6c770ee16e2be2e41a2684cf57399b7a643badc5cf845e6995c486886aa8548664ae54cb654484741ec0487f4e6be654816027df660e48be9ad46fa3e63cabfc7bfc06dc25d8a33f9bc62bc8aa0362b1593073bd2110d6c0f3782cf985081541f8255031ac016db9910b9a2bb83f23c4a50f65dd6a100d6d25f701f76bef52a985fbca43d89dcf8839236526af4a69be882d3c150e6cc5c9676bbc1e81038d340bbe088a5a9baecb45cc39ef6efef0ed7f6d06e151c4b8415138c0df36aee0550b51ad3e6ca5afc3f8e419b3ebd4b25b0248e8135afff6ab988202787be290c528422d67de8537f097d2a06b2402df723c5fdcabec09ade665ca3ce1aaa4398744f9695b7a1159a9f4ce3a71618fc931006f4d7d27ad5cb3a27c41c6a76ba936f16ad1fa828db4b5b5b22680055acc2aafe68aa94ebcbf172df50c4624272c1f6b861298849495538d92426b32cf4bf82ef10aaccc568a8f29f5954397bdc68933c048785a893715db16c8540c7fd19ff887894c8284c3ad3f0cf478908ebc93326d742b98136a42acf52bf954b0ca5b161830552d0268d3e87b14ff1637c0de04d9b22c3b11f1f634844f7a3a472e5e4e482029031ae379f2a5ec7021ba85dbcea0592e1582f90daf9d32d886042cb227a5190a62d4de9a3b7220501c918220ccff20e3e1671bd77334054b291f6ba45d3b60e2d62436d9ce4eda43460114be6461f7055ecb0f5250f9dae92090ee63b95c3d0d4a1288909c37edf3e2efa46e1153cc5ef120995b34217785d988e958113a802a5e7e213da0241be1facdb0753d0ff1d4594b4d8014084d960fc390433c4da32ce9318d951c12e426db1859683b2847fa5d485191b34d28daadab9b2280844aa35b9aebdf60060f493f2dfe7aa456ccdc13ac5c42418a683438ba30e0255cc1fc69ebf13a188c6382291248887252e4213c1241823c2d006c11800ff8f59e8fbe5fa6693d86536f7a3feccdf208e5a9c281d35a76eef8e21570a970b2db37452c6478db8cf824d583937297f371726b458e686ac16d42ca598cd410222fc6cac5e206d9be7b3cba3704e592e84b5f1ce7107bf2a5f4a6c40aa3c3589c101d6261c978a5164bec732583351fbf2e2dd48c8c011e1290a17c0ccd31cebf1d58f42484517d84f43c0f4c5b019a0b3cae1290e922c099f46f083609eac683be353c3f83854a8a1a4b18b9bae052c1b3864edafd8f2035d496ece97919eda71561fadc4606352690a9719a26a91a04d8cb788aa21015e6787f672de9a366580f2fb582dd6b464bc0a1cd92d9d7081df7a514687a71ba5f5fe67d6d2b511c403aa882232eee47de4068c3304594ddbb89b3548549372c44e45e7068ec1a1ddf062cfb89c3865412ac57256c049a0f16bb47359e08d4ff6c6bc37af614154834de788e754241b822b5ea0adb45a0f1eeb5989b59b7e8bb926b4289a11d275e20188289452314276f994976bcad84879474a193cbc5468c08453a4aca19dc6699f46d7fd0951d920fc39c210bd980da5c84137869c786b2c47390d42bab142ee0a40986d8f984a1b69401a316b7906cb68b7689174b348aa486ac6881b615ed70d277f022a04ff94628be32093d2714ef62ee1be39ed1c0dbff9cc8a4906baf17d3a570a9769d92a9e3f4657982191fe2eb20838cbee90ac50a92fa394c436d4110a9864094e05990e585fe90f4da5c99457eca3328e96a286ca227901db22ee47e7d56300d41b6fd59eacee1f390b6008ad309222ae48b071affb9103a82696c72d78bed22cc21cc12b609d6815be2d8721a7e4dfd646d5cc370c5e00bf37442c8e99cd46a92ce1bc206494e076bb0779ce5b9bf4a02b7f6efb996fa5097beb747bec05a47f0534a12e89c6916fe84b5dbaa203b59fe2a20265bdcb980bcac08f015016853cf19329549ed24e85d416af36dab2f086b61fd8cca95316ce500b7b30e7cf07ed7f837e1e10640ed8d1fe0b9ee71865f54e5c848855aa56207e099cd455608dd27bef2976a8e40bc47639aa0692132f01beb63f9955d97152b39c6c31885aa0252d228587c870807edd4e67175bfe37479d3960b6ba7bb9e739011a398030a4f95cb093409b0e9a9ac6d212fd10e20add044c4b1089fd38e3179bb5c0c8afe8dc97afdeff95b521334608a013fc8a8f88ae45f439de0a153bf08bee7e089a40e5b6cdb0f293fe260807cd398ce4d34302e568c1aefe88794128a974d09dfa99399bb40d02b202300a0a887386dcb8e068c7a25e1ed2ff798f79fc1925e2cf436afdb624c11849a1eed4fbdb043ea1324f084ccff54d3689b0e7ad9d7baaa4c4d7c0c89f7b1de4e4fceb8dd92bd51e8349b7977ba13b31b350ac5e92c3876cca49d6852c93d6865c77291376cd76ebb10b2f7304630dedcc5b5775f40f17956212e4a0d74acb040e1df36cb264312040b0d0ba5ad92f1c61022420095ce07b405a02ca965ee7686231329485e12d8e7af45b4487b2628c9a7ab8bc3c2d42d0d3b3930c05a24cb7a523f32e20be6388e88741ede83ccb3d31aa9b31089a9eaf8e43ef0a28a3ddff06688e77c4e42a45539f97bb62b899d23dfce4eecd16d75d11b05966fa567a38f79c2686c640906f22a0c6c0ad5ecc827418c9d7fc266bcd88af5708c7e0b73243ffc1f9691ad4f085f84a8be141f59d8702243b3f8aa1117f61f1eef131e80a0baac628ef84b73a3fc436e97dd944b8b478a3f9c0c743db0d4432e979a6cc83256825d51acaa90340165e1b91c3954818bbf1367bac7cc64aaf64e3f1e66c2672f5db4ef3cae0724c36fbec142769d624708e6e94efcb0d669453493a79c400d9548e612942c767bd06d32b9c98136906c509fd55352e7e14a62a49abea315dd623dc91672b24aa07c80b9b51ab927827cda6c2e2c11d79619fb39cc90f5abc141dfcb541aaf1ce95ddd44a54b4a096b292e2d32b3729107855ea7ef9a44e333f72a9a76e848b5a7cc5d19448cda087d72f6ee88d1df0f4c92d08786965f01218cfadcb2cfc6991fd772f510821cada613c0b0c4242051ea58380acbae1840b2496f5a56a090e87dd8de39033c4ebfaf6dd803cec9ec473f00e89f65a9223f723d2c3bcc3fcd451fba813300b4b6878dbd9e503bb287dbeed3ea53daa5916917d610e3f2ca234a32cf17a0c9b8411a8209e978b029261c2c72e4be50daba8cff40545a06910b5053dd222480b4f364cbbb09212e8c33d16cf6718d3a811b922ca7b03f565c112abeea7ff5d836050ff5b86fba1fe1718b61712917d1fcdbea9651159ca87019a56ce0fc143c2f4edd18aeaa13c462d367749d2097676c86b0b07ab22737720df049255b15760c2b627294be9aa9913ec649f954df8da60440922b9f0b20236cf6be40c607c864c4e8a4fe40bacbe973f2473a24a13151f4636ab60794a00752b01eb271c6739259afc2f3b1a71312ce4aaba8fe865d295f1afd83edcb12658f11dbb9f74445169a5fc0f5e0dab0abd8413482a09772cca3750b832b49b923fd6007b0b3c8e2bc519ae4bf17992917cacf1d43f82c5b7da4f0283ccdf053b1549be1dc9c47429e4c1f94f3f43e06a967c7c9df679a5e8a4accbe7becbd28ee4ffb14aa4449071cd2039dba573ac6dbc6fa0c04981882c5e279c39cc782ae1e99d26512437fa5ff1892e932262a37c5590c693c3e646339593d10c64e180a1fa09a7e43f42539e642fcdea71fe45eab583db0963f3c4f63946017a5f9cd2814f0fc5d52ae72d21d41928d0c3bc5a99da2a7c9b8bd31ec4d78b53e83a70f706c02111d940eda3a8debd82d3a1a768ede5c9f10957b1302d6e330bd70af8a51e9710de3cba277b3d536f2813933eaf49bd43a3a74c9e261cea3561819463b1f5d8f6121088f66027df33358741f253988e4fd1f73d08375fd3759d6a613009e82c034b322989057d88e06f14f901206e77c765d68cb06b6e1ebdc28d41b069e526652c62a1ad0dfd0b0dff7d7b8790689e6420210736b81707e6282779d15b3b41ead39f23996f7651009483d37cfe49f85e37127acc67151a6eb9cacbd40029ee4f9241faf2c58259a9567c616d0cf4a3c8133b44ef1edc1f6bda84d190c4fa91fe95956df94fa8711b47ddbaef2b77e713734e0465a3a5d1e25954a3cd8295d84ec8a840494a36f9da9275ba8106fe37bac17a3f62736ac1c05286ccacd8254b560a80a446f23c8a58ed3961ddb89b806beb94277a35ca2d973ba6c788a73b99e5d7ef44debfeaf1d2c2e1f0e26620cd6d681485151c3b81b5ccba248543c9079f5219ede4bba2821c7982354323250a2d58b6a21828384d3912bebf20e00669ab702a3872fdcbbc983e70221b8d9de940ce29cc06799f4edbc5ada1a738d0cb1c3297b4709500477c298dd788383b84b30397243acace00474eea65de36a8e767fc810eccb86d1b14c2bca967441c406fa61ccd6c8d517f452d84faa0c7bc6c4a3570dcc0c4edde301511b27550b6ab9a11bad8d4e39eaa96dd1994c32ae2d301205405f72a019d0f450c667cecea974411107eedbcf4cfdd4a6d0eb63c1c5b05ab1508bf2a300daebca5acfd33e1873ba5ad6a2943796ea0985632ed43019be618e4925b2f58c4b0e92de2c1d3614800f99c26d6409efc57e81b253eef3f7c1a2e49b2b823250128a831318133c7df496c574ccf1af27c1b0ba5ba6bae07927df946f322a54a080f342ae2a3e8a14959def1fe9040183391dd4608040986bdf697eea1c33be1197402d1c9f6a9b2321302c1c712a1a5bbc4e55375ae0f8488a3413e6c9ea56c93c124bf432816055eab5bf2e96d4d5b994b5a0ffedee66f7a2c8191722b87b6b8dd2b7baa619f2678c3e37cc06a3b9fd0494b45198621f3d6a763cadeea5cb220adec6927b4344235a949651641e8da55427708b9cb1c8a56b364d15caaa4e86b9f8c263bb57393ff9fd7006ab6c95aa2845b4394caf99e9759576aa571806b485b55db8af262c43a10b7d0414f1ed4d82bf0b766e9664a279c2abe4327a843c91f85317008dd97c54de278d06a53e48b5827b2b7a5c2420c4f4ebe840f44b14058deb389f5a902624043790b8aeb4423f3a2ffc3e390bf4cf0721d281dbcd15b7f46f065d6276ca93f92e59a5eb516aca6e28867e8caf7349d7e9ce09a0b49e2f593e19d8dbe9024cce8361b470a7aa9c2b8d5ea47f197d0ed18fa973387c21bc4b0595f95792a622deb2f7a4d1731881f7b4c7dddac31b6505cea546c1a98f1cf177405c23e3047d50798592b73e9db87173afeab96ed5483102ab180f300a2400ad02cc06e8e073d402edf805a4179187c9cb81142089759be84013929e9e41c50cb88b42620bbbc9dadb3ba690fdd58fd3233c76912331bc328f45385b473b9954e6a9463a0e8c6130c29277dace454213139177d9279af6f5f8f29dfb2dcbdee9f5af0f0a8dd7b7eca985ebca561a80036227c185381cefcfe0cb02a6347852767f42024dbf7a548529cb65978135458fcb44eebde56cc66705294def6ebc676f6a04a73da81c03f12bca3704325f42cefba07b0377918efe628eae745398e4d380a50498e91ab27853f96071e1ff63280aec231907eff03a7bd79068b2fcbc087f97eb91e0f8b6c964069a6c57cbc6c82e46175550886dde9a31f44eb28eed4801281082591d2dd86f06efbc6a56def94e6c8af650c87bacae6225ff149a3012858deb91434ed0f62055aee16935aac1c12f60c403d94b7ded9066d4419fe46a6978d88aba23837291a67a47ca42f23233aadaf058f7531baac0b9f19928e14d6e1c0372044536d0b311314e4ab3cfd298266745738e987053479dfd01c123b6a49d078a137e05c1beb4205d9a482c016e8d5a0cfd6aee7085aa4568dfda1349c0c23373504accee86259ab7a371a800e1b639b18d7986226497016b5df4e5b6714368d45a545714e86f8069862ccff1a640ce0af5d75cb646bc4f279944f1bc6c4c89cfb9e32173509d359959e89628a8319803800a03ad1106a9056b83d90c0f8111aa49c4d35282b18524e7fbe56f7cbcd5b397e2604aea8cbe8f73c71d9cbf71b91ce71fe93f17d6b79300529a4ebf9a106935754e32ddc138b688ebc101d5a91bfaaf83b25108d3b6faf97ba0bd964bfdf60e32b6f525943980307121d7bc764f93cc8e438f9ec4abeb1f4ad6201f2a4d784465039afaf2e681bb777089946d41824200379caa5fb344b25935efaff6a7db83e7008ade0e0e9f3c4d4d5587478414ec2f64e094128684c32418c02b7ecc0bc075eb78cbf24c44551e140565c21e82dde6d34443f9866d46b6dbf59e4622f9ad8d7a39e84e2d5ab6b37d76d695afa4e3da1456acf5d58f7cf6cc87fe4413b22488e95e94ca8b49f6955676e0d1d63bd420f9318127f7ee788f031c197375cb4014e6d84d487527a1c32f25bab2db96722b8095b4c7d3aa44c70ee1d06c1543ec7e3de315bc4b61613a63e38bfa9a805bdf0bc0657d3ffdb9a18e456c51f5d83ed06271e6c52015e89c3f2c03b7811dbd451885bdf9e9dfca028841a6c48c0cdf30451e89ddcc486d584157e795737621859fe6084fd85c0e8ee51ac456406c2ac07364740e61185b6278d5b8f20148e7b56cc75f0f3cdd270dcfd1f2aad3f333b9f300f6b53ef0e528c8a4d6ec9a97caa36b315f958c2e6ce3f9fb4b6b4323d6553ad466b5eab16aea9951542aa79b46ef5cdcd355a79e86307a557f2ea4cec9c5c51168d7bfd5b4ef55209a72b01ab17e0682d21930eec0b2b093774b4914721410662d2279c25854a13f3a313d964c83dfa60e2b04392cbd9f11ec5c9b8e4c975357a3175941ede255e1b72d9ac362a12384213f333cb9979bb8e0a342f47bf7672884bc4ae6b792abcdda12efda28a2dea33f95234ebcc2ba08e6f461a529675ff38a6a6605d227a4bfc21880683f62027a87a35a0138be014d58b60382ee7d398a3f3d496f8000eb3b324f44a51c1e767dfbdb75b1366a9f5ac51b3891dfda78040844a918f831ba3437deb00e3e62ae631b40f4656b32c2f84d647cb3b92a71dbd0ea3ec7775a8578a0b4e52f542e69721ae200cce89fbe0c32790e828321e7e2454ffbd17f851f551b0dcb68362766e20e1790fe9eff76c175783c1c139d02e59e6941731d9fc7428180d7a90339e4961ca8d1646173b76aecabd48bfc74b92b80bc03b341b65a8549a9b1660dd296af3bdb5846068d77c536967e92bcb76056c6085f7272f94f8447e526ea6503926262b057de6102f2cdccd08e6612a57e09e18399f3731daba10174e1eac24912cc2185f2bd971fb5285ae48d26703d39349236ec42569f9270b5cd293d7561b6f064e3c45175097ebc3dbf059289dd24415fdeee34ef2f0347835b30911ab322b51d26aadf11be86db249c1c1be4280be4119f6845b24fcb29d9a33092c5d02d06a7c1bc4fd2dbf009d35dc8d903af446afc1fa393e702bc3ad15bf4053cd0973eac769d5b97742df47bde9045a491906ec0a4e11e8b9c9f8c32210dcc8d72c847e5d1764cb616a1b1ea365de65d7f637ebececce52a3dd66273de805aadc0efc2d48250f9c8a6fc74da3800bf2ca71f0b738c1db1d30933f402d14828d126d4db72e3d099dba175c3157e6cb8c9f7fcdfdd8850b54aba37b9239dd9a2914bad15f3acc22eceac1dcb62b8c51118a8fff2e961c43019ba55eff0f8b2a603dca209e20425a15ce7f37644210245113562465a0adae423caa4e594fca388debd8cb40e4379d8f5e2d01965a74705550c737290669d1e02654663c92a45dc0fc37ed68bd5abf46795d000c7e5463cebcc000790d6c8cad22fce9a7cf707e02d7578984a5ad88724451c082551b6dcc703b517495a89adf8118ea881ae1b0aab408787b287989d112ab1b6a980f67c134d225e1438577922fcc192e823a213b061232fc6ea100c6493559b5fe8c2720abfa86bc1c0f6c9f98e0535864249601b2a13b43e5129b436f241d867dbb3b50217fb51d3c39e002246b8610bab89d03fb7e6ea230d0d2ab1324bc284e94c5b869cac91cd117880e1547e2a909e26aadf67fc2234cf87425044894caac061c3e8608b5e82f0e6627aa96f1c452b12d7e0f887e4a8dd87a6e3d1381242330c98849a42c7fd09b15e6c40123c79b036d874c4151ea86b76f771a477c42c3909e96e34c33f8840d35ab75f4eff99082e5c66ee0d0cc4a9335241f16f268a7f11ab924abec433106648341a9f7e21007b293389c388bd89e0e38c1a5011532f908b3c6f98fd2acd338bfe4f2b6827ff13cd7d3db5f6bcbd970e08c70472aba2600ca67336900de5c933f0989fc97342d9bba1692b8fb047de140f13dba6d5c7cb970fc340fb853b721ee5deea3011a7e2ff3b2078d6ee6ba1121b41562f9aedfa123cbd3a1b9030b84a1917e6f83c95b2aeffee13b5d3e31aeba324cddb883538be3e584713c316ac512b3868a922c62d3721a61ab9a9d8073853b9a0d183309004c4288000859793dd3c838a7a8a6d183635b6e4f49a598060e1a6a76138e6a677bb96e0180cb0c76ee96fdfe6e83a51b967e1a67d07196ce1cac34c961335f385fbe1775eac9436d362f3607e0ca6adc488b1341119707815d2b90bc70a5eccc4b16b912f72a7728117c1f52efc5008e937cac78e9713ef94aabfc002a964e57c8fbb7bd911840fc100d9420594c2e0c723fd1697d95aadd69c91eae1044d095e1bc32eb60bd9b12cc9d1607546d454f4a85049c4b99338ffc3a4dfef457b5c553d6abab7fa1993908b6ec0fab32419b15c06fcea17bf4aa3d02623093b0a6e23cdf79e12273a5de122242e8e170f05461c49a9b2e9691875f2ec32e208b2d398c422e12fc6e989f17fef4e43c990b608654098b33a44c2dce445b4f68e2d0405670ae956997782fac8a7d63c3a0948f8034e44dcd01b1b4dcaf0d7ef4356d0daf4810be7abbfe19880b9b77906e68b1c61c12196e58b478efef500e3141250b935a8866a29524e425d7c444319a101c24e45dd5f83b44ebd37dc74a232c1bc58fa8d4ce6c2d8ae082b74e1e5173e31a805b86ba04ba234be0736dd3a5ee346bf8ee162332f17dc19f55abf0f1f34ad79386b4afaa35dfae4140eb847afdcee44b11659de504b081dc27031e43c38f264873f0a632dc3a191a9bbfd6c9801a218c423aa0857e1b9363c056147312a81c82b986058b61e0adfc556e302429e66b2c511d2a4d61a75889521500e5f8c504f5b73fa79e02c1dc4e1994b987297ce67ef7fe3f84eaf8c6a5afaff60bec3335ebb59133e53896f775837b2918789ec4cb1a3a1eb1f451989b8c3e2c9df633d7fc5e78c0430180c5057e219eebb6116583980c58e062510527f968ae97188ec5ac2eb926ad0e700ccdb79742834f5dfb81d262b6239e33825698450fcbe076dcdbb3997ed6a6da85f64b6ab4faad4fcc19ae92a83c12398921a00e74b8f3875b8ea1acdec4e42b4893afa2bb49dc4bbd977831830f8405f9258de42f2ab595dd75d2f68179f1e91eadfe9d95d655a054f477cfb5c57fbae17ddd4773e2e0f57e60026e1356c7e3c24b0a5817fb351dd246156c6fbbf83e72ea6b5ce85d345f0fa6ba2c461ee2bda180fb11c3524561153d2cecd12d1da834cbe2314a61e2f5721d2d907b64222af7b89b53cc0020ecbcb14b2c7c8758e8776abd3aaeb383089a329b9ab27d272d4208ee42c05e0a900040e00a1366c96c554e3eeb00809cd1606b9943f33c254254c9c2160dc3d989bbd1c01f479385eb313cd15e6a95c4d16e815af8a80a0e95a6ef4c8c86aa44878d3016235401b8101cc49a5475e60f043634f77d4fcf3c01a0c2b68843cebe6c49b2c190841029ba4ba24af35d84b62ecd6bb5ba7e9862ddb0a2574ea341bba81cb31f2c448492449597f54345c2e58def89eb14bafb2c86017118748ca5593a398ac5210e1547b4fa61c15ccb6558ebe514c74509557988292dbd0785da42fe34fc8040a0a8bfd988d95d825803283f9b7445e243df4009e47692552154819a11fdb02f52c5f8ce2c769b30a26f9699f54e4522dcad2d263b56f2875403aae4f732f0fc4c5499fa344f1cd1477e69708ec6296b8dc4b3104a49ecb918134c1f0e9ae74a9787c128640f26bf18a21d38d2699cf9e9720cb2366fee3164fb883bce9023bf1af5b19797110386ec8b9d1a6e59395217c7f77851203177f9ea36070989fc8a8872bc86e479752d51b8271c8a14baf3476f37a68ee7e95b2a40253547f72272d1b6683797d89d5b6192f05d22d00eacd57d9f11289afcc93482b125b22a74040256efffbda61f75acccf9c3ec5e1169f91803d334f9d1a39b09b4a54d6ad939e4240007f784074e157c7a65792704cfd38ec9da301824e81725dcbd78273b9c0e3fc0a073986e727d187152358d85db256a71de14c1df9b970d3811999c13417413c1952b90bae4f8e73ef28e6cec8199456f17a38049a64661a905b381df84db4706fb7a12a985e0f3daa9cc67094fcbddc286d29862a46d2486a41845623b8e31e31914044132c66bbf8ca9f9a4ee94dddc3a5309bd4844ddbf9febaafc14703d2791365775c0114674ac530e167f2c2390c4baa8273023b2c9ad42157653a801107c5f3331ed6170282e69717d0dc0a786ab3d775039c88a000e570d5632a79d696619ff2f42243323569a73a335e5c879e078108a2bce1106608b4d80bc78a5719217d9f0aae66c81b51c68ea1bbceeaa61a638db44aa1a8718a5a9fe7e59a7aad9a82055756a752db8390af0a56dd5ccafbf3ae88af84aa0077ec3bb7a7a94faeb5c1609bf96be11fd592c15fa17690d0a84c3b52f32f996e45fd765ea527f4badf2e0ff121e568114e5b03a51e0ce5a0939b9f608daeb10048ef2928592a1cc72c066b831e971bce8fc8047f3e18c2f9e1c1dc0d2ac9c3ec4d2d55ba268dd5f33316c3db0616413655ddb072bbacddae7cac1fc5bfb99520cb753e5427d964067d0223c53810ebbfda0d2f127f24296dc153fb3d4b44e7d63558f2f6c1c799948e9c95d6d029cdf2a7eb8238794ece284daa8563ba6a0ac42bd90c11104976e5c27b93a1585e56c5aa015b14b48e42b2e08834880c011173fbed67012e70cd6fa020250404d0b31808b39624ef69c4b47f6cc722aceb414eb2eeb5869405149fefa642a694fce9cb89e453897266d1c602c3463ece810c3b0893a338bbebd5d8e9301d0a76c0a85c2adaa888ef38d6978960746caccf701ade8ad5d7af801937b71dade42934b5f6d14c7e60f5f04acbcc219088f97e5dd34e2b7b43bbc929ae059d4e0388cd165bc645e04b2e336b07803989938bbfd226dd231bb888d1986982611e9372e35456e30bfba51f0086c90a1a81673a582242f81226991918ce7cba9ca98ec5f3c5973664a6731b3ba7fa71ef81587d1ad2ba1d2aa8853811a416f9d5d78d896937933128aa021db034752e767fed2783aa60ca82015bd46210dac05a241d0a9e1f519970abdc4e8425f90d7f192bbd3aa6aaad435b8cdb2881c2fd9482683692dc847d2838257e5fea8eb1eb9108fe4c2367559a84f0db0dd5746201c17c7aabcfd2d3f8d4a5c7e07741700fdbe066686e0bc41d0028c1bddd0fbff1a78a20e34c9b3cc7f32039088270081e38124f2563a9e4a91bcec0f08450108f80e2492d1b8ead3529297fc41a1280021ba0349f29674d5ca68f92790c9caec0a02f3e2cb0cfb7e0a6f558e180477efe10d3c26f57bf73f7c45012e8040503d8da9aa4f5252effceb8f9bb46b1f86998009cf1fa898dcb80ab36850667ab0e96e36076f78152804f60362fa9378d8e3e03675ef4a8ef701773a330cf83e052f552eea813b5d7065501bad928ea2662bb68f8efd7722aa82da3c5022ab89abb0c9f0df8008c22465ecaa1cf1c78f0d6abd6523f9d4979167f6149cb114db295321e1080c93c8d308cbc897bae9caf2e9cd71f438ba7a30205517121975036706bd5c9f691b3b12a3b3e091d60c320a55c439f1815c62de6b3ef048d3a967ea43d867b760e547f8f03eaad7e73de363db6bd8e5de653aa6a04d61cfedc5cc4163619c9776041406cbdd5e89ea896af2982d15bee4eb18b08a298cbeba6b0f751a637781dce91d246c2e2f11e98d93919e2528c73b3f090c58621f70a2e3479f04016002cbdc2d68a97c05708d2bff8209834cb0314d88d5222b00c0e6cbfe3d2c2731d186939ab783d34a6352617357e51d42580b54ca10280967dad4d5de89285538178755aea6463e57c6e85dc42fc5ba08339c033512fef0a0e175703ecf4e5cc45f2aaa8f6d89aa975cc9ad97bfbd9a4222540b1d082f5d6a25d20988be55d5394d846dacc31b0dbee18291cd3df118be61c2c209bc6fea058e9486f9e62f07d13ac4d638328cdd13be41a1e2f2af25b48941447700d4ec1d004a6818360be4d6fdb43e2f3c67a2bcd1ce92840ba49f0951c929b9314d684266ce88fdf167680ccf1a248d0f4ef172c3cccad7104448a9a0d895278bce617324113f1e402c1dfd1d0b38e5080c184092230a2b69e33afc28f00f2b8db6925386f710928df7359b2b49f99ad5bd8ff56b00444ad9f6ac3a2a16ef59b10ce80cb0806204205384fa35898a98ca1cea1238e934bc5974f573b9a908cc518a4197dd3eb9d8ca7db295edf71a3d43ffdcb51eca42e732e29271e9aa992ac1a28a28fa6df1ec990a5d08ac4f5c1f637820d49a4849351eeed94746818336b0e90fcb8a2c315c6bf3b58bb07272ab1e276b6cb45cc010a150ea422a80b917a0ee79e4ded60c5e72924a84a741a93d3fcfcfa5ad98b65274e4b614a0f92827f0004df47fb790bacf9f00db4a8390bc0fa46050c70bcc2cb41d8002aff2cd5ee9597cf462e9c06bafc51dfba836806e9074fe0e4b0f4f1fab18d61aad801973d2240a36677f8c7c8fd60c5de1fdd299ea3ec607e9a69491b66234a6a6a43cb7d1f7eb73743ea4695e21cd3a9c4b491abc1f78162a3fe9866c14c17a44ca5f6c7595e52ba17c474df1f8a00949053c38c8054184edf43b1d8ec4f72d915d18a4ab2877ccfdf45c2f4800d41f6fed5b4222b02bc3d60c062ba02e76c952b71c464f2e7c276658f0f7eaecf2460c3cedfcb8b3678691e0b4493dadfb62fb2ea38951be2466319dac0d766d9d67d549980a7826ee05f2e72ced1f6b04562ac241bc75526c601f370c768681aef3f151b68f35f400f74513097ce37281336b53442c1d4c2decfb4bf372f1101ff05456492b8ce245cbbf4cb716bfed2ee897cc1d1940a3f1715dac88ac81cc22d79bfd2baa0d0729ae34cb85d84cfb657ba7bbf6000e4a47e827632f9ae92c481212cac4cb17ef226f535afb99741d6fd1e4a7725172a06ff619beb24a1dd08c66b6035a1074c65245141f860052f3db31738ba3fe311517108576c674a71daf82c56d90c1fe9069cd141d8fea4a1ae6b31478abe1aa20dbe9826f10a96d270bf821539b0d4726d27579f8a75293b7018014b9d01c39a1ec0e9d9c154b00edfcdf7cd70fa0660a6e8122344e653650654cedb51072d29a2a0b8ab83dcd5df696bf54b8af0b9b473bf3c07945136276369ee623a325bf76347b71bdf6797a6bd9914d153315f8e60d2cd841359e79aa395e87591d275f8b26fdf058cc923c28b760c8810e8b8f158858913e90b48ecbc9d547c6c9d522ffeae193887c36301e87c8c7b3d3c6a57bbdc01fa2faf072b27dbc9cac8a8fe0e5186a368e9de18678ee6a31a9e862b5a4c5a176c18a788de5ab5a5602a481aea41674e5484ab9f2d319ae2c80e0ad4cc4692bd97b5b2bc191a695e3b8cf4a78c2acf4778fc092c886ea03a23854b4b91f9368c973e407ea46c132379a08f12ab912fb8c308d5eb497a4430649e9eb40ae7b949d134caabf988f31e3685f0f03c4e686ddcf4948bf46b69114f4c01e65063876d0bc98a00a57e5989d6668e7bf8791cb55121e1b2d108e4944608a5c8d5bff4999923b96f6f8da62d23b316f9974a21ccb81ff81e429465a3a2361431d667cfab54db910066d9cc189ad5ff2f65e86d0b233ddf648b57953209893f83ad28caace94c2f10a339297a1e7c66999cb64670d82e868a76cff8c3c66fda8f2478cadd3d95506f79c3a0a0a0cd485b790402fefd3fef4a32f64919b0be98a920e1b905c56c18090a1f8e846561a98d848eac8bb4847673f6f503f962fe772324793164b7d25b1f8d28d289c9dca5333fe9750c946371209c7df9b666375e4a4e942f529feae0d68b204dd981002c8cbbb29d80bba6d32d8681fac53685a4a686ef377fcead0f96d5b0469dbabf0bc7903484183c9ba56d3563633e0634f8eb91a746ddca41713e3ac443d6001915b24767a6377ab97ace2dada5d0f78b7f34d0a96f9c774575dcb635c64f6c7eb0cb68fce6e3da3713991a7b7822cf275180b9a56801f9bc92fc96a87057bff245a680e2a3bb3b612f0065200d5c7faf0c7fcd87bb98a7a227fe4b762743379eed9cda7ae2591a16c7a3df2386d87d9f9fd974d7b11c3bc328a36865bfdb74dd7593d52e99a0cacb8f53d9bc206b964c68b025ca21d1167d24deb3693a11262b9765a4919ffa5533c9bb098b23dbb187a9e754266efb7407f7ff8b84c49204150f5c73373b893c6f793a5161682ffe9668ffd588a531ada22c3171de8f4352861af642c6d6225d1335cd9dad4da8dbab104be5ef6af9cf3c61e7f71867f07bc467e6cf0ccb6fa3f4175a8132483ef49506e6932d12f4f03c5d015fcfff85f6167822cf083db01761f7b0c8d48609f94b5f63a4ded5a1bc8dabe166e166e8c30b8643491310d386f511a94510fdfe21c08ea994857190a1bef806a32099fcff1a409a9a88d50df16a4f14b01c10a27287260e81af70971371de3ad8d740e50c4d16b9ee0892cbc5cb69303709a0c423b8a38e307c9d7bef3aeb70c6571f6a36d9901add92363428de0ec34d39ef9af67de95aeb2438ac77e449433828641e364c2578c779713db10f225d50302f30eae5835990da659e833a9c0a821c590ef807d40169935bd0997033ef1ab8c5d5bca7de4c1a86047ecff7432cd376a6e4dfd3fde6474b58c04b56cd5e9b28ea2e5d31babe395cb03bdf64a29e3e11b86813c91942f10c6783425cae5e820e2f59159cec9d3cceab069757fe223cca51bef90e042a03d7cd1d8362862ef14297df9ba8875a46a838907487e687d0d019e25242c92f69a0cfa16117967ee28592f75254b528a5a0c65394bc0fc23f6bad73fb0ae30a3c364261dc1c6426cfdf4e4b16d18d34529701030f0500bbcbc5491017df150505a8610a849a0a5002c5b369c68331a4087ad0acb1f1d84554d845480b99a2b0aada85ad05d082ba2037f8f6a7842e1483467a54d90003dcc00a5af44f156036ef73aaee3c19421cc0633853750efee0c01deff79324d7b530890f3f3fd0fc5155d86ed0af5a274165242058be6e207be9e15f6a2a208310a013cd02deabf316b4267352530bac717feb85e57e95d3f7e74c78fc35dee85f2059df2b7c05f80bfa0d0370e2c8257b033bcea5d1f706d8f1e53d55cdf0b99f4f7006280f01941d01f55ca311e36da1fbd2c82a2734b3c8755b0de31e1982dd9fb3d7691aec4ba1ff59fcc0862e52ea74fd6e55c3754a178bb2566c758583a1a09885bf8c658a9698bbaa25d880897af1017bd3b7157095459d2158ceca49b5fef50f8a549d49e62fb2c15f845df4ede00bcbeaab917e5f1cd3d2324c58d9db201f094e4a407e6fd5e1a1e97aeaf8c63ac09fb119ddba9b1544a37f007219c8f0a50c17c02cdaad0a152f2baaef2e4344311d8cbc2283bf3937028504124dc82dda0417a0c4f0d56e1d06409b6fb515765edae1605e7f63689427124f3e3960432b3969953d2cc96e61feafda61885187c76f9f5533358ec0cbeb445c9f028358ea868b91f48ff893ed4e35c330599781b23743e8a4a4209b9bb3262d23be281528e412847ab6a98c40ae53695e85d6ef2245f873ce219a2cbc69cbf646044f301499902608ad1e92d8d1e4866b85bf802fa8cf792bf49964c2baa779fe3fb03fec18141f90d33f4521f7d2c196f8c9b880a02aa8e1dd02703dc3e999037b4e4e4dd65ff72f564807fe792917c7c10c6ca7a124e894e06a41f99bd407c03a54af10c27fa0529e80cb7c4b06dc096af34696d6f87cd122352ff11730ad3986705165b0a246b38e6f541447cbb0e66df778076d3f3204fe09c25b825e06c61ed2e92bed344c65f0aa18ce6cf18753ca7a7a152a823a237a379fbf05d3a8df869a9c8e1d8a005ec1c22cc772d6643fc9d98545f3c92d4353e8123beb7f8d9e035a3803e40f9162b9aa97eac9dd8e687e2ea7f21097f02673c45030621ae67eadd934a7e9ea4319e6502a01662082484b879ea0ce39c4e3ad0de10e081fe0d55923349def09814f5ba9c65f86cd80791323d0895a5a5d84eb7e67503d8e3e3492e7d1842ebc0dd83ed0370e3e83de2ba0a913d6fada769a8658727a0e7c6b25f7e297a07b03b209bef10d237492e9a351fd8398cfcebfe0df3070530e0b5905b04cc0e9d44015e65371d73ebc3ef6100860c9c0088d47e1f14410e791eb4e5a0abb6877cdf89e1abe48da8ae2ea32c46ed2501bcc836cb296f743f5c949fb634aa412bf75c2a40582a2c6211469065c5048f964302561cb201e635559f00f73952804e02a6f7613a44372bb35f99aa3c765209c44a220b04ff71e13fbeeb1248b80d2fbd4133ed11f68c53ca2ec31df855da3828e6c373091ea5df9adaed10c395f77c28cfb107fff749fa8d39e62293dd4efa573583b4d84552303e52a3e7c6dad5e83d8609028306a052ac090b4f7eb7b6ef56ff0d9236e5d5c43b41270bea53399b16ee919d16d58468e0d55a69afa913104db07444023815f5bbaa5dbde9f0fb4326817db12987fc3ecbcb8bec780d9f1224c73d47fd2f2db53a107c7e6c7ed0237a1ca04d9f4583f1546e974492e872e56038358d79aa1f67d3aaa9ffc626978e141f1aab1433ea98eb175135368844234012913e6693a54b237c718083af09781bc6f119910b8ba0fbe7bec45001c5e7aa2906f480ff2b32e9150db42f49ec098ecc9cc4ad8880332860517fafcf9b4b46068606fc339b407f13b0a0191ef158a49995f776553cb61caf2e6fdb22a7bf7f707afde626ab3dadb6e30f5ccb5cece5b3aef844240716510242ba10c19cc7585b4603e0abb3fd576eeea5ed114820e286844ca8d455900a6b5c2760c37025d44fe19471b1a120f5ee483c67dad5be88c989dc4fbb03fdf3dd7d65f4415f53ae52c6b2f0d62eb1be5e9ce17e2bc5a01c1b98f9d0f95aad6e8ef60809503e5488bfe63a54b5f219ec24737d75385a02661ac90c272f9d908a2829319a6878bdacb9149374e6639681f344eb838dfda8c6d5050934a03247fd6566478e34881ef2d1884414e856b90e21debb8878fe2cb316f5670f10a25e8b731401fbbc76bc02ec0bad466afabe4db145657baea0c6f8b279843e1a5a91fdb960dab5591b550c17b95b2f68714c6640b419a2664f20558acbc67eaf6925f742af9fbac854932475646eeb22e5e8656ecb9e9012c8fc9c4abc0ab372221b87bcc1cfbb8e5b53ed067195ef6a5298fa84171a660db4638a05bb89962d4d098b86edd118d270a5c6be62767849a316ac9936de5ad4fd20523193dd436bf018006cd2ef1f4c4566c6b2ca3f6f780b08c38d61799333bac8b79c159cda42013c7de8147d4109cdf40796325ef484c31b4d745b28f3a0318e427ea65c91b70277fe718ab02955d102113b8112c620948fd4fe466ed86a51104d38c19d194a72b583ea72295ad541b75447ac0af44bc33fcd2e43069bec0a28ebf46f1e385edee2f888c65fdbdb1524f9a907f4f09fe2f1d60280cb9be4897805e3db5a110848ef708a763b1ad3003a3e5284e843529ee871e73c2363136b91e5c05eff2ecd0386a4d74d08f736c463008a2ead4221c5c1aaf1d334b90687ddafb0fd37eaa3d59fb9bd0ee288bfc9fbe7fff61508f949d20ac9ad6e31398967a91031d0825f3c8ee49be7e60cb9f52317591d95c18ce5970db0e1d659ec8fc139af43e76d06f95f0cdf6aec64bdf83469635f5eba0ce906100f3128041b7a2139aad03004a0a185a016459d8893fb3639f1251206f851dfac87772aecc3171a66473f0184a1ffdfd0606be175ea1393385a09d65b32f9586c98b6f93cc2f73384b54073095e8d8d523e8c7cb5ea064b65139d18f798a22e5ea317cb3717c31df1e8683d9947f08d930bf1e5455c58dde3f007a3ecc5a39b3e347cc48d4549b595badc2bb847eee299aac047e24124516dcbbda963228c81dae27e18154e2904e0e03bb4d74ed53c228c73eb133b9b77573e466b5ddbd90a83d04783558a1eb3c91932b082ffa77795274c2615e6c557d7293128f6b9669abbc232cf9c188aa21a7b88f6ef0450c06c2ea3c23b4e0687176509a2fb30842b96111c6a8345c7a71c341a321a19776d2363abfc7cfcb92f616cf21585b64dd5d4602f37d5c7a6434d75b67e102e847f053490b3104a9a24bff588e944907bdcceded568312f01be3a06ae451de9343261a3b5c25252b814d0b5d526d0496178d31192974ca1715ca6e7ac5202af618f7528168e7315ab3117e81922e53b3777e013160b9254165acc1422df081bec17446b87b6371d7c08be4a24652e2854b055e162890ab38d788cba193a660b4a00ba02f75602f66c23aeec3d7237e11cbf6a33d49dbe20cf2335a15bcd0dfd885910a13b5e99dc5e2f71434bdff616b0195bf9346e95d57bdae03bc84d286425c00a07363c14472c26a323fe398dfa0e71a8870352a5aed950451538aac004991982786cfe04487a3d274c6c9c808ed5c3ae1694831e7086237c202e1fd60928282579d925d0f06938869a9be15a62a98bdc286a09cb2e7caba825c6bfbc2d0a44967ff19b3a7a816c343373f8ec74fd6d78b2e5ed722bb3239861f5005b92629d71284e2e96da0d960a05c0a0a0b406e718cc945310a929816e1a2ed6a89fa09ef826c59996067778eb4224c091dfa2d41492b9577b55490342152f5d63f0c7bf5e26db6cfb5989c84ee1dfe73714355692e298c6930c926d811023219088eb23fac25c0184a89eea26c9e0038524911f20df7580fd29330ca6113ef29c08d5e307f8dac1f6da12a325d00cc4bc2483be665ff38bf62a3106b4cfc4335a9f900b948a261c27585014ecb9454e93a6e772b01711e35da20393e7ee03721ce3aef2ad2439edf73e52bbdcf8a7ff873c87cebe39d6ed629b9ea702abfee32ba78037cd39f45a7697ab5e792807e557c653d13d3565bfa9f13e5c22d5442a6ab2907c1c649bc00c4351c9aeb9fe05cd24a7555f187e419af54b0f6de5252269bb0753479b551743af35c2844be0dfc575f6d6503bc427272d91e178e864e8d6c56fafa3bc511fd3116056766eb65d2511b4d27431b42ab6e95fc9ed0e58e186d2c21a4676ff26fd5334293fd42b5f4e60f6712b51d4d8b79a5431706391574422acb3a989c5ff6fb8dd3d77e1f7dfbacb3bdcae479211ffe9b5258e0e6301f5f68cdb81da8df8c025601d69b41b8ec0e9cff1709287f14a94db7f9fdf4d4e790ba2341547371a5731b4caafeb5fe8218cef1ce0cdea629903f7e71c77639af2aa07a83b348b8cfb22faa23f3bb420c1ed0419841d2e55a4b51903c4ad9f96845c60f8e2b309712144c32da3d618beb901b3f2339bb3b84d365079cb23573d34d3e23159edd36e879302a19c127026f34da08af08db92d333af30083535d9c25ac0afa5822d75a5910c27540847dfddfdfdce6f5d6669165b7ecc5ee9a417a44f00eab87b82aab2192a86470e72578b751c89a541a4ac330ed995cc8f4ac66b8bae984e8a65f1b625c53846b05dcdcc3f64c7a79bf7a52e9286456edcd4c9300e831616f745b9acdc2c4d97ef95e2e4fc7c81694fc4a5ac4523b15d484f1dde20fa142c591e57ce4c45867d776e0278dfb602b492e69d0fdce3419659d9dc4cf6bbca9cef997af7a063c187d0fceeecbbae49efce216e30521f907faa3945ddb22224e770a0e15030c6b05be71c4d50d54202015a9035977ca697459f5fe2494e14de58f0e667c09edf915d5798b850e3973996ebe50f91930485fd100008a8060077988ff7563a105d44a10fe4494a18f869480ff441860066442c8de25446e29654a52061a0e8c0d910d907b6ebba719d06fbf619aed41ef63b5b94ec3da755fb9df2bcb0e1124efc0a71a27e8233b1aecc71d56143b3b7336109f952cad4329108960844162e58ef1bab0686139ada89852504aa413939115853a6e037daa46a7f48630fd2dc4a1e33e41f411db61a083248a9cdc5f41ac0c651476ca8d7237d6c54d4cad3647bbf91c47758eab6aadd6e6c8ffac76f3efda4d8dc537bdfaa53961ab266b569e2f938b421bdf04eb94bbe36f4eeaac794db06b1a2253f2084ca6a4db1c2bace96582c198ffc537bdda6b98e9854db02173fbb8da708b5b6d5f77e28b72dc70d5715407b171d4822f604c8b81fd4c2fd3ab53435a763162cce6b82aaeb41061c457c2f220db1e40958d39aa79708c903b08ad6c6d6e765cd57dbfc925f45ff542eeaf5b800b087dc36c60a6572bf75b1e57b9c41cc5f3e1a93cb954e289e59890ed43b7655a6dbfcd6f0184e9ff2660103f1ad5df3bd0439007d2d3eda207f7f7ff1127fed6dbb4108e859c6644df872e4de87ba060fb1edd873011ef6c845c785af25bdab7bef53157b9f098ac8de5222e3caefa2620aa3f06d506b9ff7790fbabe5f9d6e33cecb5009be5f8dd65e5f82eb0568e7f93e3c33cbac02a14f0450bb211a04a03025131c2d09a8041c4efaf4180438029ff1d0459429651d8e8ab18e114f9d386b4204c7c79b51fed69dced558ee90c2e3b4d9dfae2fbdbf6da6b8f8e4dedf59452d8d971de98392d06b6ad60f9cfd949ec905908eb54445cd58fab8a5bdcaafeec633ed51065f9a22ca40415cfa9cde9f37e500a29724b0173328e29e79c31cefbc19c4ca594b3a90fd95f208cff0e6cbfd7ffb4ec5e63bb725757fec061832fdfc925125d21ea7193a8c755a6299876aec89d85dcdf637a693536be14f5c0d1cbb69c3e137635fa7e9115d6259ab92a646dec8db5017c31bf5f14079852c9815e0f7c21dfc26a54c0677590fbed0de2023821dddbcb354aa2e4d32b64745b76d5bdca135464f023cffcd59b4e7d2a39399dfa567a72ac53bd24f7d7202a473a15c2c91f27eaa199e6cd39cbcad014cb33cb5799756a74b9a7f1ed157de87633604e02429893e3cf9413cbfdf2342392dd3dcd746fdf621a1a8e92dcade17ef49bbcdfc8158ba21e267e65453df69aa26045cffd677a99781085e89fd7b40308130df0997e1032b95eae0a7dbf0966220284a132051844abc48c00552a5580a8fe98180108a0458bd3e9247f2a399fe995fbe10b1850c7552a2cfb2a36d50610c6f6fd55e62a93efaf3880aa9367edd8a8b872db74ff5521b9e102baff6a0f72e9494fc23d485f42f9d297708fd2a3946e8fd2734fba3d48a41289f4a227954acf7da9449aa1a1c0fa6b4bd822bab71dae458c7a743fc27075b2f94eacdcef21a9b15cb747f7dcdbdbc3bee8b7d8114181eeb9b7f73423b22bad13f71d5e61398ac3261b11b62ab3894f44f42a8491603f95d96ca54765b6d2b34207b862057c21dfe4027b5241ee153dace8b8ca240375b6392a2c57a9c06c5cb5a2e32899ab54668eea87b1729b4c363626d934c9546626598ec27e36e72a5173c449ecb099073188fe2d9e86c89f2b24f4db15d2dd9669d5fdc9ad61c25b75df32ad42af3283b96ac5a54367b95560b975aeb0a3ef64f8120b21cc6763b9bf8eee4a8fa3565c2b18bb72af2cae375ab027f934a297788469aa8ea33afeb7d293377b4537e72463273923f18cfd1186551a9cdc2fc2afbc454bf7604da61d7ce84d372b78c5b5f28abe92b3126b217692b46a05765363ae1229a9d5da9bb8f2844eae305792fb5d55c06c35d937dd782b3057c115ec53c9d1d99165159e95d78aabaeb872bf482527d69b6863a44a4e842171bd519902be88b8dea057b19b51052bead183952fd3ae07fbd51be82a1fabfefa729584559c1cf822e6489758cf69afabd71b08d35256d067e20afbdc3aa46ab7e25423ed75cd813079b0df8abdb938d9be72c372ff4a8fab64e04a0f5ce9812b1cb6368ed276f207733ea813e51459d15e8b66a21e8a078b066b339cc2260bf9f3e43d804a25c751fddc777b2a39aeaad55a57f11587eb1dec27ea71e538b3f1bf98930bd440b85e0e359925c32371d0c1876a2cccda12564eadbe38ee394c739ae15ef4224c1363c08315b060c5bd8f55c8d5619a10eedec7aaf1e7658d65bfe802b13a502bbbcd0af6f0d1badf2d4765734ea823a5ad90a5cdb425a2caaa50626d067354c20e7aa058a23add715574514a35974bca1e28f2c4dacc0b1f58a7a8abfcd5a7f9a3f7e1aad08b7e26f4a29f2f12fd08d388483f7a9ad0eae445ef63a599bcd4661e22ddea2897c1884d7860d29ab070f569b0b883fed0c08658b93f9fd1287fdaeca39f4afeb4d9e861d7e5d9bf15893c4779089f8a08bde84f3326217cb2e163e5020d16aee0187256341ce53d4e7e5484093e15c1802b42cf44af42ef6325c2ad5e85309d9d5c1d8e722bba15a26408d3d9c988d5113b4d356de6426e602c738ca0216b52ca2ed651d1751daceb3aef66d48c048f3cb1905087a43dff2ee6aa0e2784d3c53a9cecdfc1ba229d7a6d369bd9a060369bb29b9deac395e8bb99db28410b3cda63e940397588641944e99b4c3b8ef2a8cdb459b541d77532fd95055fc4d9156c770789672a7a0788f2472d4180263202323583ddd176bc3f52ea28a10e946aef52ec54d6929a5a03f802561ad41954205506d5891a83d1e72b3eb93078810be08bda82ca82da84c95d4165a2aaa0d6d4145414d425aed8831e96e4010f779889ae36fbfca7cd665ab7a43d0fb15a08975db09f36db715537dbd9d991c5b286bbd92a545d54e6285f519e16c23f7636e8ce1eac262395d11dbaa3612aeb94c4313035915d2e91fd0e98cae84e7bfed19dd96ce68a82ee68330863861dbad35a81fde80e9d514a67b3d9ac53ac4ec1973b59ab1d92ef74fe935fa790bd866ecdd1f9e46b5dac8bd51884f1ef74bc56dacd70176bafd3e990c4b2e34ea74382856ea65dc10a48aa408529fccc94a51005281c79c214528caee6842630c1c8129410858b6e12907084224628027c015f40087394d79bd9c53a24fe0f55559b7dec765ca5c1ba9d6ea7db81c9880083d59c187ca1b9ea14a02ac6421f9385ec5fc82e2b83566f765cc4f8d466b359d434adde74aa211a5caf6e36ea669dfaba9dbca4533d842825965ad07195f67294d35a3b6d06d366ad4ec9cffda4cd474ffd4b58359da26f03a45354a362b01fdda9ac53636d56d39ed334d84f83692ef8825201c2bc5c4575228f7cd9b85a59deb06a2d435d836bb029af60890053f0c513eca7697888da2cc2682646ff5527b23f8c2c08fd575190fde917a0ca046b3b8e72f8228e7ae2904598670dd9312d43f62738c1ca9fc6ea147c420c96446d67c7f38044cc943a1ee8d466f2b51dafd55a6d27fb5bcc61ee63572b8438696774a7ab16fa18a3e8521d47d19d5663ab516a433548d269da9cf3abcb55dc84e518c0f2cdf009363a79db72e4c9e18ae94e0e52d6a84c73819d417b22188c4709301e2b48b9d3e934e13a528041890cb4969141a6071ca82034f7a0b98d1c74a68d1cd66005c8650e63d9600d5b9dac1f47d0583fc4a08514e9ca91820d39903961c8811be687c502904c8a37b8aaa0fdc092ae9a2a38d7142a7841142694e53d532ca164f6a4000a918a0e0faab4b942fe6a8d121c68d3258b30050ab4d0029b1387155491b3e480b3b192fcc0c347939a3655583288aba558832b7fb5a6daf03c91bf1aa4baeaab4ee99274a7534ea92c3b4dd29ecf9f572bd29e6bf3a5a6c17065b5a7e114d16633a01a4cc3e91474a969339fd4c91084ee5025d91f7631e41541cc4440883a695f5fbb316b4bda63b5a7c18c64ffaacd6ad56695f5e3899d3a449b559b1aa4baeaabc2a8b6d3a94fdb9175ea0bdd2471ba93bdd3b036bb83fdba9d20ed753bb9dbe9d4c45a912e09f7fe1acc551d2c77dd2cfb6b3bde4be8d9a0052d69cfb5597bfe1956053168539bb9db10ee30915975179df8b3dacc393ccbfe21d7a7630bbeb0c11796f662b73ba594524ae7ac83fd4c39fa66238d4fbbca276ccbc14af93948b60a9be4695684013fe64dc69ed2f3e4b4b00291bf8893a4f1576d4b2975ec68cf218ce141caed002778accc014eec601d9707a931c9d433a6635ababc83d5c183c8a9ee90eac317a7213eb9ff2443cb5d823c1ff2a821c317c0ac752cc99d0424e48feb22e039bee08bf9a1bc4d0e4618a1357c381861f41272002ea924269bfdea23642f9223e019bed8b8b8863967cf1895b4e75ddf60ad29c3234e00314d9695bf8c463a653ae204102d9f6ac88fafe598633701499f467ca20f737c20bcd85a8e5d12312711f3077b62e88030fe510911be90910ad95d4c1107d963eb6b32c64d52c89ee322e6b4077586904f7f46e03484c4a78799e2fb2f68b03147c2c16adeab53fd536041963f18757884e014587065ff1d9d92d957b0874312cab48b807fba0980b8d845e05a38c5156a727c899123d91b84fd6b57e3d5298a4f9664a98c38207c32b1604b298e4ffcd56e46cc26fbc525b9bf46b270645ac411d91a22311a69d98debd85f8f2cbf73de360e4618a09ce37252aa4d4d7a6b116a940bf5bb8c5ecc9b66e7e03c2519e6c65f4ca2a3566b4da639e7949bbc3c74c01e1c3cb8063871033d981be0840d44c18c75b4376597c70e2ecfc731318ff6fc23ded19ef7c4e8e854bf5df94b276cb815971b471c7a050bb3c4b53d8e8b10861235f7169b90c9a0c8ec2210217c01adc9dfeb8e6bd60abe8723516f1dba111e93b4e74aa22c2a31a2d28f14479cff4c6bc8fe5247a7fc79b84af46eca9fa7087bb34c31137f512657fe71c7e10aa7487652761f2b5f7d367f31c4c1f010274f52927ae010d7a1421494350515ba30f297b3435d04a2e560845159dd51241625c605141608b65f87aba2b7b7b74718103aec282105f1c8cdaa1d6384e859568ec696ed1d6543c0478422085fc07ecece186d8ed0ab32fbf0e84b644a66b93f3a6bb624c6626c89d7cc64b359c8dd5debe6b8d6e807f420ef380c032fded45ccb41ca5e8fa0ff18cb8ed8a0d528a5946adb83360dc6233c20e360d7005130af6cca0021cc3942f324be71447bf2881b32ae3a826a47c822abb6adc2b6b9bb3b7cf8d3a39cd8dd3bc26eaf893087d6226200194a218458de44f1e1cb6622236693957957c940947c2827e039f2889be462bc31aa921b8e45b646da64a8ea5ebe0c7cf179f8059885297458e6b3fc517df8f33f3742188882bf9221a4b806eec803fe8d4e353ef58e4e9d1a231133fc245e7e8e4e412c04f4f26f740e1d20bc62e57f314309653b94b4b5d9e60e8494f2e33cc23b65fe62a6fecde941c66827a59412ba7497f20d363ebc43d5bc2527a594524aa9e453b3290653bb1a101bfdd31094e177d46460e3c3afb5520ae13b86d705fe87da3a3f197e4bef76daad10cd1d58fb91524af9e124cc811f9f9ec1c6ffae217c79e76023bc39622cc3972c60818d0f3b8ab45a31cd09561a86de5e87fa304a29411bd741accccdb9c9d28ee3421cec664c12ed2f8729c39710baa8237c2960d7f8b1cd5544e426dd61feb0589226cfa0e6ec1a1f7967e4074728c49c52e3e435a24504091719c70ecfda7bd9c7eaf31bfe62cde7992082848bbcc309e02fc3075c7dfd9d400e7192e96f718634ac4467fa304ac7b23dd99a620c4f2041f21f4045e9e23b898fe881a5d1a9c609808097e311f366830f5fbe98e882cf2ffd1e94420b46723fa784072c4329d250933f2e96e30391e11433a8c99c4e8eaf1c4863a06a832a6fd98075c7ca36590bd97e6eb21cbb37ac626196e90d620bdf3a75d1570b114fa002575c92dd6b603feaca2efa44a7b44e699a7ff26384c60fcefc81a598be30fd3e78b0fdf53b46b55d2117a0e04210b2f651fba869f8e40f2dae68a8aeb9c07ef1d572d5270a888a2f459d82cd82b7a2e34098f8c171d580ae25b507bb4376cb55b71c6d8ec5b15c1561365c0b888b1bd2293805902007c881411a381677c3e25e1c8c5b7d1c4e8e3fbd5f3f60363840da06397eec1be4f85fe320c78ff16b2fe4f84d38e4f85524df67059f1584723472e4858a03e42fbe945411ad88223efcba269b3c93b7b1b6d607e7f38a5f9174eaab3d150e2e68b8885117657d3336bdb0414761231cc53d74d40d47c557b282abed3fc85304c7e1938f1574542bc7df6eefb0e277904eb970c083e60693d5399dc3aa61c9f9c1f1b6017cd10f956421dcc30e032e637197157b4e0095ac88f4b058b9f129b67eb41e880d109b59fd83136d6e82f48f4e9da2cb455daefae0382a7e7549293f381f1cffe0e4c8e980da05b6c197aa5db86a2cc401d2dda39836c8c9f2abab581e3ecb852b29e3b7b47c09d39cbe059f280dcb77f8447dac3e3f794858a5c4ddc43c6428e2538d2cd8c28245621b466874c6c3557145922f6f5caf952ec5c4481e8e92d2a47dec62d06898070b098d364236509e87a364c7e25b52bef4aee9604929a59452ba0d6a32fd65f17d5bbcb67c78d067f12e58996512a78a6db068f9f9daa5005cd5d498bef41b8bfbdf725d9ee5fa9f2e9cf1802fb42cbf61fd72762222f4ff33a17f4c43447b1affd06b78a67b174cd32cbadf4897fb957bf22ad7e44d77f429d75293b7f39e6c8442ddecee9451700df7275f5333fa1ad1772fd3a50b57241959223b3281c91838eb928fda2629707777f728fb7dc7e5126c3ffc9631d8e0cb576d9c095388223bfe2a0b5c8554f23749f9928929e5bab831261a2631d2aba87c9b9850bcf4fea5d2a3609a123e4d94a7199dbe9402a1ffbc46b417bfe51eb19332721dd7f426ff51d39bbc4c6fb1baec0bd627944ff919944f79ff144c43c4f14cca9f304d0a0b3ecd94f7b16af97e682164b991c58d55a32d8dc2839872a1a3b4266ce947ff515669f434ff2e3fc2342d37b1c4a259fcca4b0ed69be89d0d694b1fdf5b4466463f62f134246c8269547ef434a4a721326362f234286ffa133e69f2f4b5568dc5fd16d369f31a159c7e84593c4d0f22332d3ffa1e285ffa1e2ef884697ab4c4141c638e8a5f5ae1bc507ef45fc48157b0599df0c996f0a971dc694fe6a8b833dd577097de7d09888adf448d418e6e03530a0bc2c4cfc3c4b39d154bde72958b4d37ba4dc1ce7294cfec9cb37bda93c989f382eceede03c5138890a445042a727caf897dbf9790bebcbfd623244ea7688e15ca94133c4193876f62f2254c63824fb4f4342313ec34874f6fabdcb6e956b7ac0892dc597154baedba94e5223d873712c6f5e54db928574e2aa64ecb9efc7d64ea6a2feacc9854d0d76be2cafafcb9b3d657fdf8938a9d5a1d3aec97b9f1a9df476e93c9d218a6addf24073b67bd1a53d68dfde66bbe3a2587c08ae0744ae219301bc9e9d49119aba13fb2b74efe30fb8f3e397696bbecd13b1c61af7f6a58ee22b0a9394bd3bede3682d35e8cc58f107fd6dddba9bbd7b46e3c48a71cd39af6e20aa89c104e77977d858c9eb25c35c25ef3234756a75aed2cc9ca308a44e217d5a1311aa348dca5235912531d1a6b2f529d4eb1582c1bf3e7acc695355fb9e61e5dd77154cbca62e5f71884891d5994e5a8f8adae35fd8d6babd6b4a706f802d234a041c919cc5006f802564bba641883189284010c5fa05ee80217a8d88216b280852b58014915a8005f40f802c21730466395d5a98eff50e539d5591d9baff96a1af31c578d3efa47938f53e6a858ab4677204c7c93eb3ad7638e92b9ca5fdeca31398e75982cf70bbf6c38cb5168b01f8db1664bd953ced72c029d05a1b380b8e2fb90e845728cf1e194ac4e7d53d6ead457694d742c64f432dd770e71157dd1d72bc7577bf1e92bc79fb24e7d343695e8d4812e119fb2a2d35676167ce139fe28c61cb507b72798c847631d7395534969636745c7cef296ab68cc9a68cccb119f664e467f729a39a131f9131aa3b11c5b9e6646398e8a3f9a31a1e9d8fb58413b3ac9804750e03a1571f2a43f79b81a7de9eb9c1c7774eddf1787e3538d51ee1ff9c538263ed550a2330e7f780405aedcf28eb25f78648924b9af8e51865fbaa722466ff226b807e94745f438819d11a799131a9dde31711941ea3991392abe096e1d47c5119e37ac1c5ba75a1fb62d00830dbe38a5f700ed4908219c31f01dd74816ec87394a38258631d0c26e46cc1d2fd71eac50c7ddd0327bfbf76f7ebdf65e3cec357ee8e242175ef900193e810b4af2264aa2fd13e371d5c9cb8fb59a4cdeb36da287dd83be88d08b4038a4f21da85a50adcf022afdca17d1f220dc03f42dbf827b109901f55879af634c76289805d7677988f22d5f44e959700f962fb17c099f6a0fd3a3609487ab0e7d3ec65c7e60e9cab8d0a887ba7e26de26b784baf7af5085f28e4397a6f4a1dfe2751c87f5f522f17187695830cad398700f223d569ee553be74897ce9439746e54d114b150d9199960f611a10cb9ffc4dbeebdee43bdc43f4a16f799a95d1b3fce85988d8befb939f66b80f3dd743059f1ccf6cdffdf65de32f6297efd261d5264677d8d36f215d5329c5670e218410420d85e5453fc322023d0aa6113da8e56940cf824fee63d5281f634cb2dc68b93a4a3c3c9faab9a3b038ec043ff43e56a2ef1e7ed7752b113e4dda3129b2718db8321b6376461c9322884310e213fc1d319ffcb34c87ee097e0fc74480befb2288f4e81ef43d8834ee01faeee39d017d6783e57d0eabd34c646979291f487b524657c5158baf618e9252c61d5936fdca6fa70b577fe18a0509c25c65031dc7613859caf88a2ef91e63ed499d1622084af7f617e559dcd2c31bb3cb25d2f25b8417669706839d5d8c3e75c7a24e121e2b22ce92189355d1d3113a0c271aa10e83c90865b7b1c9f269071f5e0ac0158b8f9d8c508eae307ccb479752c76248c43fd960616979d89d1adb404129699a7c297a67f57c7116af0d16b8a666e54d5fa3f22947802f509ee567509e05d310814f037a948778a6f42d9846844ff0591eae4a27884f44741d0bee7172f2a1ef61bf7bb8d2721232ab80f4a787b0337d0a4a91d245b929d77455eeca3d35cb07cb71da930fb1c3da934e85fc15dfc28908fbdd1b71f2a1b7017a993eb1b75934f04f20842712fe898410e219fb279846be9532ee6419638e9216c2c49f0173122608d33f7aee456fdf85a360b55764613dcdf4fd60ec833a9105df54592ce8a0ce9ee283b600d0b03974e8bdc946276c5eb5a6ffbc9bf6e2e7e4c4a8905511a3921c634f8eb06ee52251083459ebfdbb887154fc7a69e418e1281b8e8281fde22b481c728363eb8b1f6b6432194c096dc8c9c9d170b0c1172be3aad349e2131110f647dc237ec76f7ca2fd109f285cd90dce87767b19c7d43acabf2a63391987b826b27890f3320d653e059d5c610e91f8d013f5a5416b8dac137d1fabcf8bee89621b352ae8ef5e058d7bf4cf887ec5d110a17826f41f4c137a1a51dd1ef4f54797fb4f5f22149f88e8df7ea67fdbbe713f08d380beb1bd344466bae73e2ffa99cf8b46ff798a676cf71da621722242f4a327429f6646f4214cf38eaa2fc2324f436466f43dfa6eda200970a8c10f6c582c6bb2826f1203e520042b94f0440e8420851a5670d57db6c8d510694c4364a67fc334361c55bf3ff80847ad6ae3d3cce71bae74682cb09f3b731c55ebd4894da1d8e04398a143ffd6723f1ce2931b7f3c321cb624b8974fb272cbb8f379786392f65c3726eb7580b3b80373704e9c0dc210db8f5d11d551f041f7f3160f57c1ffaaf6b3fa157f4070afe1ef85e28f257f5cc42c1cfe604e03913f9853840b0ac4550a60878411d0515e8419e1b1d34c8783e3ab085804b4d1bd4c6ff75647711c86a2e77cac36ee394cc3bd08d76e461463112784631c05bfc32647054a32fd4dc485aecc385b8e1664cc1cba9e4f3705a22baeb8e28a554b17837efc8dde6ed62d0179a7423f9f34e7e9e70db13a08744b586eb33a2171967b561e22d1a4c9a09f5ec5b0ab21336876abeb86a8ddac5b12624d50d7c5a01c57fd39dc40425ddbb45cd8427ca19bdcdde14786f0459707082392d67631fc6d37c384a33789697fd374220cd02b825e9a4ee7951b4fb747c67d3bba5bbbdae18f077725f444dc8b9ebea4c9a1a70fba107a3f42ad50cd666f97070813a2d5c651af0823a4021844e826b482b673d4119ac8d0fc984394d4cdb46cd2c590739a74dbc94917c3695e999f0f3de962485a45fe4a35d22fc98a19a99321738c225e09247fa425b99f96702ccafcd15f0e762aa4225511e3c55c4c8bea3bf953c5f29844b2a251fdddcc55a4258dea2f8558241e0893b520c4aec687a5bb1a1fffb8cb0925dc46009212a4c407c2d0ff4c4c592ea90a0a67876a8f7a7b7643749e3f1f430bbf82220cfaf039f82b4f7bac688f34cbfd249e2458d89e4fd9b28b1127126c742ab176041bbf7a1015c3ae46e72925a98af67ada734ce22962e37fa40f0dcd6fe1823c492011afc89cf6f01360a3552baf6af9ef55f7617df81fce924e0f614ce5f22c402f575dbce178bdddd2f2f5a78d8d853b75fe2c9faa138b7db4cad2c2b174fe2ddd8ccea0ff683830d847abb985d3b2c45c152e5d8cf99172f274b30fa6476c2e9c5fae8af63ed33fc9e91ca924fd4b7eaa81e3108a61cc2cbaf872e15874fe2e97e6cf95d0abafdd0abdfaa0cb41af42e85550d591ebc71a3647cdc5a5f3ff9941f1e7d4eafccb7de77f35ae5e196f84449b0bede7bf8ba1fd733589d97d75b991c5859ee311e2968458a19ad0e9865ad726f77f57f1c49d7f0b21341cd5df726fc88ea8b3450b8efe06d2409fd37357899a291672fa7993d861f3e7358e07c7c51d12d3e5e176778041f4cb504da3fa81e40efde07864cc4c71378330fd5a107c984f275559b975b5b1702b97ae1ad6a9989ab4040d3dfaf7371cff6ea3d0a70710d56f52c19fc99ab0cb52f0e705559f98aaa5b1a9257f9f1e581cd8b4c9cd9530d7a097a6036a7d58aefa98c840325095d5af7ef087c57d1321fc9dc00e59be73b8ab1c4f11b898ab42ac8e6b2e16e26246d8708a1062e5be62891e3008fa9a1e52c0724750b34687169c2e08b407b5fc036a7d40ad0fa8e5864c7dc880fb0f0f0f0fb4820f23c054c0872e025afefc27f689c53e311f32f0793833354196ef1e8d9a88baf275e11ad638ae6af9fe6de5c6d5493a7db88a3e30cb8d2b90122db7218a7e8bed05c60ecd8630f47117a3fee6c2ad5c5fd1238deaef4973268d758a7ebe53224d476e38925e1abb34470a96eab80af40ae1cf4eac939be3c1c9117501d0f5017af25fba1a32dbdf7c80b1431f88bf0ce4f90261e4b7e8627c3420ba0f3df92d40af0f61d0ebf5ca9f162d3a0ac055372382f59f2d5a749f4f8b2e86c492e21c7a84c6a6562a494de2538dfaf22b962d3acfe3566eafbc371f386831ccda567ef161e2f9da0abaf80000aeba6a65e5be10d3102c6cef5d3a00b8952ab394277f249edc93649ab7fee071d052d8a9fad3d33094b94ef7ba1814d38ce278b82a4ecff5d497ad5ae1721eacffc7f15471a2bff227dc2d69540038d8b9a3ba18fef2723ced3500381eae0aae272585c4a13a6b670e401743d20b02c1361c47f5879ab23f08067a09c1fa7fa057ee2138aeea66a04d0002e8665c159fcbf504a08b5131c7c3f1a0ba21ea835ea0212098ec54ed62489329d337754304800b50704162ce94657b3000705e290007825e212bef2b94042b3742147d98aec627cb6ec90d0da08b217137eb6641cca793fab0fdc0c1dfe8dc36b96dde3114a23f4f3da6ee000c36221a286e1c1148e98d10255f3ef4d1fc9040034d13806e8442488dd3ee8908eeb73782c34640506dfa48c42b6a406f6fcdf6f2ce0809f0f990e1e3334579bfa6f5e9fc0d7aec427582da3fd2df26079ada7cc2065f36994b384a71b67bf76bdfff3105041b7fce11bc5972e066cf1be5e06f934aef3843f3a14b1d6cf0c5a3b0ed9cd6d27e74ca461b025f6c1f5feb7155f7d17efcca7255e8e3d79b4e7d3e8abeda401591d6135a900c230d5ad02a1e5a13104604f2a72170c8f6607b39e2242173c4f18a6b0e111b9f4784118bc420fa8be070dfdd222a38512c1689dab7903ac4d67f0cd80fe1139c8a88abd0c75508b7b895fd965cd5849e89ba8add8c5c59cc440a44abd0f70a76aa7e222400f7b18b0182a1e74098005cddb89fa209b1ab01a7889df32e5cc4c478debfc9248513fcf39bdc5ea641100624dbab2f4272453aed8962102608b68a62bd1a8129ef30650d097845d69ec250a9f5f48b7ab6e69650d5547889b8bf86c39fcea7950cd6dd57d21dd71a655b9cf17b47cd9a84a15446e8c9796b48164b899e524a9721243ccf8f393612aa0ea594524ae99d11da9b4c6d326d655a593df8cb515d47acff57b98ab3e1af6a38d95b50d8afdae4e62cd5aa0b2e81811421a8ae2cbb97d539c236fbdd63acbfd55a6badb5461d54ab1f4ef470c7daf818c841d1ddd128d9291ea9d0775c96dc7f9ea5fc0861702ff197839479e878a267c7b65dcfa25b135b2d447fd7ffe9628440a06d73d18d35212ef45c17a3c39105042b7f9a80bb117ada735d8d99eb6f9dec3ac2aeebfc1302bdcc3e4050bad60de12fb1dca43cd5f8c8dac1fe647257e3b3f631311af6a7979bdacbfadbb656a65cb6e7b8bbe66c208490524829a41442ea51079c51268b32214adae3694fa6fdc0c6ffa2ac759c0740f2d7363f3a884c06da8953c87636ed92e109320421838c0c3ba2b8822f1fa827778c9f0f84ad69f2e39141b86d94d81af92cf6d4c5806d6323ebf940b1dc1f482753d12928869d24202536891d36838c40840d6a2ff8403a6238a282ab26656d0c4a324806a7184392dc0f4a025202618cdd92739f1f0c61e26f303684a097e94f11165b43e4834130104e0bd1a09d9d2452d6a9cff74b8e82645549a74049b693ed3e90ca9ea1cfcbf4c976bf81b8cf8539c6f8f96d93526edd8cc8719fdb59fb8a67785c37a3f3e7b78efb5ccfa0ae2ab11f5037e383bb6e86e7cf6f2118db65e8f3200c210cc45fec6e4de73ca109f3469bf66cdaab2058a722ee1b904ea7aad6028d09bbbda602bb41eb31c618237d7843505d1987934096ab4b8628836010a69fdac18258aeeabe823ab726502b4775d518b148c8885948f733daaa93f1c95b37e323039437dcdd51e01ddef8f3b5eb2347756589630bb3d88092d8b8aa630051fd36b8d941ee06828dabe0eae6d536201968a7bdfe9ddc74b09f85b69590e1112a9e0012a40636766c1bdc369a0fec67adea4f916b2316d4a3b2b3d530f12b7ff942f4fb9d2cb0bd059ed4912dc872771bb11ffb04f2e58628a490af92cd047dec2697c3e5d46edb30977382e444e724468239aabb303f11848bb5f7dbe5489c284492b993644e92b9089758a5164956aa61e5fefaa5d285ed7d9ebbb5bd0f9793bb1b3309e62abb518e4eda51cae57476f379a1751097c32121e1e4fe19259b50cf99d68a367be8d15a293d711bbdbca38fdd0c89c48a5c2e725d13597b264a442f9158fb1bb4229cf6da487b6d72432fafe889f644afd0f490fcee651783f45ba30c4181a1bc526c4817e69accfd5783885ced9d9c1c91e5c96fd0a2a4e4489992235372240a4e91a5f0a4e4a42869af536429b2149e4ec15bdbe37e8b9cc935b9a0dfbc23741992ff911909962c4dde44e422dd98536cbed6fa79523e095bf927f833c9379114f0558afc9194697bbf11ec23ed7ca29dcfeae47ed1fd505cb95fe4d2e8c45c9539a5479bc19e922c772865f2b0bab6f7bb7d77a1df2415ecf76955c17ebebb18a2e738fc69b5676fac0d84693b73545f984b47da6b8ee3ba52acbd924462eb6fd09abc4c86b4d73c1f9b0f90f63eff8d5eb9eb5e7ebf23bc1bd9d1cb7df4f2d1cb47b8a453da19bd4a54b4d7259ddcfff9924e6987eb6e9dc1d5b497840c2dfb0ff1c98e3f1ed9b3e34fcbce5c75a2892a2bfb8bf057b17fc7e11e227c7582b51e4739feaa0b745b24571eb1722ec934212f4c9065ffcf5728b5dffc617bdf0bd78d92adf220aa9f23b9e7580818d1a9eff3201c9ff70f3e0d51fff39fcfe77afe5421db7f5a1232f7afdccdaf0d086858c8f61f8f0cc210a0e13577d6fcd64639c82d8d989b4236f8b26dd0a5f6dbfbc376ff1bd5047af8b2c52c47fd395e72777b8e4d426699eb3d6276f76f202d88a59bc67dae066afd971bed4dd34bee9b8474e1a8f9d5080d809658902a475317ed51a9846319ec80f6e68df670603f173c7276ffb743cebe95043f23527b12e7e41d9d3f0081988f92edcd8fb993d1f90684995fe9fb4c807ffeb5fe566b7d5af1acb39a206a7e9d4fe7f4d9944e7a447bf38d686fba7055f773cbf0094850d0cd700b5f7496df5dad75ce09796ee8680b5ff8f7a84cd48d519637a6cf3ae50c4ef298e5faf07ef06fb4379d0cb6ff8676032bbf2fd75e0eadd5c580afdd984f4dbf6f5bfa45f28e6e8f0ebdbf6320e1575ce1dda1cf043264a6f8540344f1c723da98184127fb6f9465bb226ca4d2cbfeca3b3acb3fd5a0dfd4dd51feeeee54c3eeb90781d0f1428ea959677c973042e92e935891a17c1985fd211f6aad2cafb0c1972dde21c75e22c7b806186395de3afe9f4bb2ed35ac61ae6a1d191b374ca7755aa7331528add33bf1db26ce6ea0c9246f4c26d3275228d037790d916efaedee8d1642c29750fad4b4e91bb4b546fa7dd1e84b973f01c72eda938f83e297f6240bec07659b07e48d4ec5be5173a424c5dffcfecf7d59322dd315ca1065896de798659adac17e15e6b2af9fd2df5a9d8ca30478c40b37b9bf16a946726b41da6b57d66e28c7b22c566db56c6ceacd0a8c62eb82c2ea582aac4cf68c82cbb10b4a6c6c5cfb4ddcaabfb90c5ba583c562bd6055d3e0804eb5126671136914461c5bf4298e363f72608e2fe300188b3f5c1cf18ac420a20c5d15bb5b01f8fecf4510ff452319a4e1a7187f5f80ffe2100278117ffd847df5d76aada95fb7c54b593f88879d8cfa41bc4c07f1f55bdcdae265a706f02dbe76eae55b7c8bb79dc2dfe2499d72f12dded4a917dfe2593a65806ff11bb43fc09048241289f43ef8f0a58fb744ba5f4c26fddfcf467e949ba29d5a587cfc3fc1ffb2a202afa494ae3cbc2eaf5d98537ee5455d0c971c5c4e71b9326b2928df1f5d2a29a716162693e9595c20bc976759b9a6f6504a3f3cbe30937ef8f7e187dfba182f1cf77265c61cb6edb518c095edb57898cbb5d7e25d5c527b2dfec535b5d7e20d7059da6bf13fdcda5e0b215a7cbddfe7162d2ee84d37097912841233e3003d0af5321dc4057d4c8f28e2cfcb318f60436159fe6b1649f3984a71027cca6d9158ee67cae165efedd32e060164f67e8b1c01aecca319f67f2880cea63920e622012e8c8831c618638c0eddf197e3e4655ac6c90be0b51b02c893719cbc0004f0271fbf98431f010823b6601040fc07b190637cf1ffc198102c5cfe3f529803a8f8e004f898203ebe8b4eb520e0e34300be1800d4c9a10f009531c0f71be065ba002fd310420861cae9e9e9e9c74bef179361ca934c2c5f5ba580d74a1f55a0a3f037c628b7a1b0f7bf66c51f2d057c97584840782f6f7254fdfa29a7aa02823e3cc807151f5c6eccbf001b9885b831b36080cdd67253bf41ebe2611743f5320d2184104208e1cecbfbbff8afdc2fe69587b745c5f427978f28cff2514bf9f8319d227dfc03c017251779e55bfc464ab90d8555408a02ee372a3ecb95edb13414f68b2ded49ff345c585c99969b80eb82235dab72634cf70028a56b03c244160c775c40173fe3bfdc2fbe8baff037f8e2b7f8e2b7c8b5b832afbcc04720e0ceb417df85ea6aa0bd14b6d15ecc425c980f10e38fe25faf51f10d70630a707db832edc527404c1003b81e803030189a3c10370999af00ee9703f26400bcc97b1723001ad4c90078ad1ba20446b0019257fe00cc30f91356b71a485f98638fab607c7f9c6da8bbf29a9b94981987e951a647a1ded4f2a45629e057565e76cae557be760ae5579eeb148b5f798bf2f8571eba4a0138b654feabd729a594d23831fe984c4360ca38b44f797f7f203ac5f2a5bf61cab1743f8871ca7d61b940b4e7124b79517ec6a7288f63727c14dbdecacb34be28b8b6b7f22e57b6b7f22c2ed7de0aa9512b2df863c92baff2b18b71c2a6fb7d5ec126d305bdca45dd0f84baa0047c8fbe3f56015f74efe110781987fd1f7494e4feed870bdf881cff87fb79f9878f3fbc8cff70ed432f87defe70ed03e0310e933ff9ede4425f81258500f2e4d2c9c9a794486fa353f8e1cf74aac5c33742039d7a79f84774ca8787ef01f8e2aabc035a25f310fec37759c0b37805a45a581e7e023a754a852026e36079f95006531a138298ac3d7d999e7129bc7e595ebb2c2fefe738474c5e7916161f36b8b3c3884c8e3e70e4c796479bfeb43925dcc98e8f78b91a680f7e8b3bd31ec6d8c6bd1e8030f0ff32e0d646c17759c035350a3e8bab80eb350a7ecb8db9a79b80f6e0af5c99f61cd028a8823f8824c347f9d8c530e1948b5352aec9a3dcaf7e3e6e3ec8f3459cc384c7c935c13aae0c0d1ba16b8406204c3f8c7bc48d1d349115cace848539ed326d9d46477bf7abd9e96c9af66ccc78c315d8087544d83604b3d40702fa004fd85ee24f1aedd99810b0319ff61fe1428e471b3468d8989446a7e89c11dbb8349860690bb24005376426ec0727cc7e3006b1a74ad95eac3b78e888b1a7c9107b3af5459b24f793584852c218e78c73c639a7c30bb3a93d4b075664e5d8af76cfb66ddd5ff83d55dac719737dd8f3bb2bfb013eb6ff6cff790dd39637f2073f07e7638b2d850d3e3639121b7ff80f2359e64dce8b27c73dec2446c23317e27e7bff3125fee626b1bc3ff0e7c37de32e0b9ef724f4b17572f2f147ec629ce068a391bc51ee932e9f82bff985380cb90bb33fe9e6cd576e8ae44857b65c21f8376fb92e58087ed9c5d8fede16ef17e5ffe2979784b70b653cca8c142ce4fe0a16d202b77e85796c2f37cc99fc5d6e8bcbca4d79958bf229ef8ff2329df22b58c8c5ad5fbd90c7b251d249a557b9a52709f94ff9bfb251a64e8558be7fbbeedc74c9207ed34062f616e9bff8e3e4b99f1f09efe84cfae9285f72f9f92a37e5559e86e34f7279bafcfc155c651605e7e032cac9abe04f666e060ef932a3601c27f88b39e551be44fa12fee4cc9e8271901e650814ce05e5491887fc99bd9bc0ccd251f0177fe4f9db65f979432fd324128944fad2fb0d01977190bef41b8944fad8c9283da986484bec62a064ff10e9d65fb930b3441644185f0e0ec61ff9f33159769b89c993363f3999f2f373d2800015366840808a4c39d80d51faede72d3de97e3b32c9f109e5fde709e5b9df524829f8848269c07ca28f23e5519ea63ccaa7a070dccf273d77bf1d7923dd8f7bd16f944b7957c225a3bccb875d8ded274722e113871fe023a3e013cae3203df728a4e79e84b9f929f7e3befe24fd9cb8caecf6f2bbdfb4d84920e6597ad84960bbdff6259c83eb26c6e1f2248ca3e5670ed9f2f5f333f433e427277f32ef89d60df1c99fdbc9acdcc989bfdcf017fa1d2ee3f39f9c27d8f4a13eb926fcc57cf2137f5be8ce8736f4f3e4433f7f7477c47c32fa9326d8132e7d7c27e120bdc96fddd5007d20e94d5ea63f6ff2264ff2fbedc89ee20f2bcafcbfb051b3f46ef2a2dfae1231cb213e6f62823fd2c7ee013e503ed2a3a03c7753deefc63d0effed39df30fc94d979de6f7bfbb193d119a53b1a309fe4e3c055892dbde3d273b884827190fef3df86737099844d4ef2e8da6cafe87e3b72fddac508e5e03e9faff235f99f189acc7133f6d3efda8669d80c921e10fe5f1fcaf48540a334c73462c07e16fd3dd828a5737e3490b6699a9caf6d0f3ff835ed655c935a958d6b606efa1e36f8f27d7a64dd71fb4d1c588f8b578ccbbb791b53cb593d8b4b4c5ea6679179a453a2ef9f3cd46602e9af417a3ed1738815ada2379f5cf2cd9ad37ff30715ada23832895422ab28d2aa8fce278dc823b65f0269d54706914ff42787d801be08591161d01d3040983a7801be3045185416a919204cffe75dc8fd9ee3473a1573249bcbf7cf1e576975ce9a561dbbc323bb7155e569b9a13727fc99268eabea4ec5c1383838f506e546c200a6b4584c06b9df67acac2357b01361683c60802f3436c001a6b49e394418d526066106f8a23ae19f97ab3435c05eafd7ebf532c19f0f23b946ae6a5f7962acb1c61aabefb8aa56d156549e8a838383f3cada8ee8ebcde847a31f7d6c9d60665febe914bd690fa527379d99cc8638c17d7fb58930ea4e0ca2351e3668b1d774743eadef6393fb451f596ed3fd0cb949c1dfe708c571d58708447584f101020ca251f027f3476f4af8fb18c9a2fc519c230401c2341872bf8c60bf8fce2bf77f74b88f8e4eeeaf3c1d7a12fe5c84fe04f38478de047f2653e87942ffd53cc21fe4c99a8f1bd16b2feda5bd344f147ad8298d47ae127a9ad79ef62650abc095a7f2c85c1a80defcbf1080a8f92e908a9c24cf27b4d75aad5611206658dc17889a9487f2501ecaa37d585a450aa49edc32b6cb09e1c3349c51cc550e4092e58c91836fa2b3d658aaee21fc2440f2172a1282dd90eb76495a15625961aba89d1207625f2158a848eed14ec89547a3184c05b6eb0344d508b87435a6ec62c8c01c07d09071cd0f0926f426ad32438b24c25a05a707814e7ddc06d61beb7a8d7440d528e6a88630e40202aa42f5003601f9597e013f218c04cc6802093d9800ea3401b9e3bbbc59ce8f33be34137272729ac8d30ea3d828368a8d62700d3508b95c2e179c429e3e9280ba40963e406f865894865834c4a221d6ac95ceaa4d39bda39ca41e133d6cf0e5d37afac67e7bfd72a4bdfecc0a9237415ac5c9786432199539aadf0463ac66a93496a35a73b9da65b9ab1d919b16db5eb68afb0d7f39382dd65e6b39da11eeba9146b9cfa75a4e7bed388ee339da914ec53edb6c293596ab1c078785c3c261e57e2aa3322aa33293c9a5b9341e5a35ed6a4a3499111bffd3701cc7711ce7489e46b41c2d67561a4ffa2bc79660a3d6b3a960553f9b21ec8e2b6d081eb8f2e1cbd63e7dfafc0855d03718638cf8dbc067d06fa1fa7187d1bebee6a36af1fa37ee2bb4963f7cf9341b29c32437aeed45f8315a19764354698310cc5a6bd286e4d0a6a6849a21d92453fc44be5a92496b459b3dc081d35a3504f32433d96ca6a4ab90c564324a298414420a21a5b059aeaaff71b1055537fa7b1af6fca0a7658567c4df7093e98896c937d04a5d4ef7ef2ec6fc2add9dde99e895de9955f57a2314c2699d5f6f4dfdfcc761769f52caa72d9d3005800b5074c1f4f29d4043da6b77ae0a49738ec8bcfc438204e976b58ae5735cc5821bc61284a53be7b3c568bb108e8e0dd1caf2320ea01173da80c89a16361c150843d38941f4a7e3b8953b575da455ad33bf69683f7f42015f742badf375922479bae89c330850e5b269843ce71254fe9b4fc828734e9b495d8eea2fcde9ada9e94c99a33e843f8fc35fcc077f2e3e2c8abfead8e5e226c6c66bbdb37ad6ddd35cfe3a49ee9f42a64970e59a5bb9cabc9d6ca440145998fea58160030c8e2706c1f14418dd8c63b9a59a12abbd2a661106690d30887e521b204c472fc98a4b5a5262dd524bf6c8e9b48b4135195960af71a8f46c94964d8e32553322000000f313002030140c8804e3d1703c224a52de0314000c90a8507a581a884992634a21630c1100000000000020404200be0138aa95ab4bd821c1a4b8fade54c8aa9322eaa46cad855ab0e9ba82ce7892b433e0f758ba171f3b7af0e753049c04bac1f37ba84e496d706d2df8954b777f5bc71608e880cb57bfb7d4f6ea941ca73538736ca9604c5f0b8621d5b97cfcacfaa8f051167cd476f0064878fcc9961bdc265211ee782dcba88fd04fab8b1fb42660218a19c7953b681c5f1c7690aa5d6aeb4e4b8d5cb993b584f26f9135966c3afea66a22adcedce6e70f14cac59fa62c5dc81b1e4cfba0f97f476a1bdd1cc9de280a420c9000ca83d007560c718cbf0656922efac830061f2dbe9ac5a2194f8899b44df2351e2743beec55c4d67e44daedae23677eb46dc199e57439e0a98ee6f026d9db4f3006cf137f4b937dbf8653d258e3a44f66a671f711b984fd2fb543cc6126144215c37c556dd26e72e024dd3d3396f724443580188e6897035579b76d38d258c3db52a03f64488535a767f6b081a8c7b59b558c26fe704de4b4abbe36d2bf0c40ad63ef48368f41a509020e478c9a092865220183d100cce7b00710ca84d211a379acb1e910a4078b4775fba9cb1af2883fc0562535933e791cd90e7e987373752b1566d56bb68d687369b2689fe7af89233ccdec8e843ebe47d9e50a52688c1a3ee2fdcf3229f6dc254020413986ff7eb21d24036b333b506b8a8a653f1a1beb0439938b624882a8ec0c2ef062e4db67237e7c7a0b50c05c412af60df11c238075637aa6e9802e97fee2e80f7a0f568952862315b5cdc3f9c03f2fd246c08d58f721eae755d895b6d7d71f9a36d2ac0bd1f863dad36e5f9614c1f3847422d3a6c334eef7b052f2c0ddfed04837cf4cf0ec9ce0f96937f6ca2ee65f48e02d80c7151bd2ffa710f3a1c25f9805bcb330946929fa0fc5812067b44f4930e68610b0af0321e77588a4c54cc4471246e032abf8d615311187981514d693e5180c0331dd6dca8d7203813b347a1daf8f1805b00871adea5bff0a41aca15c1a057d744b13102038717000517cdd0a00a861013da8ee0cbac31ee4ff0cdaf675349a7ad6e4704801c1313bf94ff3b191c3efc5177e27367089016b493f00a3c1daa76c7b7ad541bdeb3bc43541cadf1d729a441943f4dd75822a06a2c4a211037aea0ae53f4b0aba10f839c6bd1e7e58cfbf3a3df76d2c7a755d5a78c85aa9133dd04d2ea7f6c9a222eaac5af5ffe1f9cb17ef0a575609b995bc7e0b8049cfb686c99e918b8cbc9575aea607b54b5733725867b4344ac92627a2292975c430b17373da2168727f447fd34cbd6e5327e9870d67025903def04f73a54550f66955a49e73697ff4fe885bd7c66014158abcb97b78631576ac56c32dd57806eefa5cafcedc40a8d58469ba7a10afdf2a63dd9ea9f69562759b5f8f37be3f51904bdbc38f086dd896bc888799a5b4e810a9f0494d4ba30638a0e5ac99fb2ea9eddcd95fe5ef5352db419762359f09d72aac516655d2b4ca681e1485297d1ff3b4f46bdde7902151384e3c63a2f4635c21288962867f3789d33993f3cf0c70faae26fd29ce89cac69ea2977e73602f0149dc8684b1ef21b623b4ef652d4dd2fd1b106a5b1871e96e7bd2b78e252aa23f47e66bcb34c8e1c52d8c871788df0fbbc166de5e45fecbc2360c7524029e08546ede758a37113367c4b20bc8d367514849b4d13144f430c8895dd9653063d9344aa394386eac916f5c7b3806f92a51030da0093846ddfbe376005a166ee0e2b98333c28ab5bb386b4d2127b3d009ab038f198e82f04b1c65214cffe1774aded8b84eba565a6993b56b94590177f659399d4b0ad0ffae3e36f0af9c363d0f3476657205a8d968d0ddbe7001de988aad8fbb05f9dc89e88baa8b53f3f38a1fbf734a107d86c9ff899c7bdb64dac9800d251c2e7cbb5803eca4a00fa32c2044dcfcd7ad5db70fdf6de13ac4f419e93060c519c7762b37ec61e9f983eb177b86b9d33c07ef74c2544cac83716d047afeaf3b21e7d3ce4bd46a2a67aa34309b9e4477081967fa3730d032878c1620f3be563b2c595b7f6ca43dec1cdb4db57896fad4ca0e8e4247a16d43d1113b7f3d48d418171dae04c8bf5082cc054889f938a6cc8f876e688146c583b735f7fd4948c10cafc4702210d248634a6ce2f2d6976089a62f5c1a1caebb5edd52eeaaf25b0981ee3b407503920c28a6cd767fa5d6802f2d6e4654ca374503678ed974b4736be4f302353a2ab802c52d24c6545732cd550e368100ddf7cc7f8150506c2fc002d116f1471918ce4bb63fbb5e48a98783e5bd0e1c1c6b8819bc9e906c0e62588d74de8fecf21e4bfec6506b3d49d13c464e572a62d1119fac6d097406a606d2d6d210d4dea89876a85853f97008a44f6b38baa059adc2aced27e88cc07c05b45b149d94fb9959c78d8a0197963cd3e48e51d68ebf270b21fcaed2db0943a0488676769c338312f7ede89944572eee05026718fdd459c4f4c06d47d11d54def2c555a32d7391197eaae8ad1f5c968ddc8e5c744aa0a3d94a6055483d3dd8d38eb83defa48b718d0cdeff57ed8a3c736cfc7c550f91cfec1faec3dec7bdc5cb26fbce993a72dd34b1d4cb95caa2cb196ea77c4aa89ade94a313b72a824c4fe831f82187453b211182443ee14e0bcceb8fdfd5eeb0acd11595b404f030cb210cda4845e59091e4dd85f9c2fe6a2fd8f1d078bcc2173da8e11a8719d7417f6d0cb47454e204d550ade7ae5527d299b28f83011d0e5b1b8b9030ff87061cc0cfb7e866b62ce82cc5ac738c880464dce962e4b471caf790e670f50d5b12d7d09295355134e0a9c1c321bf8e93687bbf9e172273cb9af9830a7514e6a4a6cac9e90618ab8f9b5abb01d7a1c083d4a19bf928b9c8283b1aab8fb58dcfaaeeb38c63665ab809c8de24d306242517222e3f6369197ac0d5d5b88103accc150fb0c6ad82875d341630cc5a43ccc61560d2a168c16ba6bdbbd25e40260fac2980210354dbdf1930be2eef06eeabf627b4a13c013258bd653f9dd8ce0bdeac323e836f2d150718fb16ca164c0f36cc746a1690faa008d2f1547c4bec9b7d984872a2862dd7c4fbf876753ad356910168c3cf47fdf2dce5448525a3b7d2b135328bc0e861711621c66513ffb856608002d7509e6f057ec865bbfc227c9f994d015be1707be24646c5e1669a9d8bb00e78f06a8113c1364424636d74955c658acc548bb5dc7d412da292756a41b90149a5ffc01f3d865d95c7570f8c19127ca457a0c8ea05cf504ccfc2a8a81e51b585483e06a796f6681f12fdc9003a8f89507daf21b4ca0b7f1d94b2be143420ee51de3dad6ca85aa30bbe34b0e5623fee51937169626061fdb1bb9f15dad2c2fbcd1acf06a42c0de477afabecc220e9f3b455d3836e3c33d39c62c6af3eeeb7e3a047060cbeb7361a5a1502ffdf0e0bf2b0399a7b049389aec042bbd00fcd8d352eca2f411de462af7e5cbba01f43db7a534291612c98a6de9a1779c7778619251ad358fcf149a6529bef5b94274a31c3c79710ec49ab0932146fef71875feb6b295c156ff21e0445601a201f765c6f9a26ce3f12a6f230311afabad42865b1f68264a834972f1d01d5da900ac2b3216492a7331d5015287be744c94ae5803c15486ab7b67129ade34bc8edfadb708a9f3f993437bead7c995eb9e38bc57fc281c989de61fd2a28d25c46765aff9695d4d8d04dee5b337de2d3ea25d5637835c48bf5c9ae16ebf41d701eac26712f1f0040e7d26e4ec030f27f0d58364e011921c30f2223d078559126bdbcb6bf83b5952671d24e4ec79eb0995d4c1942504ef187eacca3a5e0f9eded226fdb3455176421f8a9f7376c1b63fe08b3e4d2aff76b4f5a13a9a81376248cd020333caff7b58e50605966f05c72930b42b75451cbb3fdfdba9fe65c49e0519b31a96c9779277d45fc470df4289260a8fa60e4cd49be589938f5328a34053c38d752794af346357b3dcf4b24ba55c9aecaa6d4ac36558ffe7a72c7e2d3845450e45d2d064896b0fb12ca93f49be2972b7c4cb725b34471a8ec901df27b79a7f3f13aacda8a53396b9a3b87c5ed8bc4a65424ae395df95960a68c6edb34a5a0c5b1e006bd1324a8ca7d07aa8444d3bb1c25317ad13f7c18423700a56f5e06cd18ad95ecf00e318976e96d630f0e0473325cd4a9ecdf4a5379ffe8a4e491c8c4de4dade92250dfb0cb3337b728167dddaa3d8be29f44e20261303dd606e3219edf43a1c8eace2a10493334c390cd4194b3bc070a11f047a6ac51aefdb9fef0a32a0e72a15c7b3c76c7ddb47dbfcfbfc865ea0ddc02de3ea37030ced1675c1e3a8d097097fdfe8eb141d44689c5a33c29f8511f9cd19544e13d5d255e657bdb956ad2881547493df13cd7637a2837c4d8ca47ec1335ef37dafa1e033711cc2bb016fbf8f2513881f1af0dd4c0aedcf52561b04670c0d1711bc1decb314af7d1aa9cf6f298bb5e1c33fe06b6d1992eac8313783ff212f486c30fbccfaa0aecdcebc93f271a51604180e0fd6b12dee34d3f97df3f3d3df40b599ff05e5aeb2e528432640cb3f7b6194484f7ecd35986e53a4645d9d8c732c27bf4cfd25e18b00d26ec7743782f9a5b2420bc97b79607e817c2ba59e6bf3249fdca70f188d9edf8e711ef539b82b7a7c0823aa9f2140ce878ab921fd71df94e1a3e0ccce94ab6014590115635b0555fbd572bc2c02df488d3d15ee632d7428a390404718b05366731d6878d693fbaab71c953fe612f08fcf568da85dfc3c6555835ab0aa2013778ee1bd8901c247eda8514a748b4fe5c1d76db3b66ff7fdf1dfd4992b08f2fb39bb7b49c8c69759a0bc289bd5342c3b14c4ce86e7ad8da6ee88b86334a7cc8fe25297e6725be592eee6e8fbca24505382f473015fc39069c7da84c0cbfae6167ccfabb8d5655b27757e8e89d06429e0c56b08af7aa198bab4e67501611830ac4a4b9fb95cdf35d30514e56b10c718cf0669fadc5f34e662bf02ab39daf186a8a48782084b35fb6282f2d1f102f71a24b35faae147fb0ed7d83b211803bee216e18419757552d28daf4b06837567a1cbd56219c7afcd60d6755ac59301383bc94ea8bd618842409339272094581005d9c3f9c46de2cf515184701b09d111e8b74f29b8ab37cf3ec8f41ad85e29667b4b673882245a04b496bf5ca7a7ed116bcedf41534c2e116fd27f39572a2756b23da59de3112e25f8fa1c3af82e2072e1c88f6e7e70e6105ccc68c5de967e7b655c76ec117c135882129ee2569ad071ea5d683a739d9f93978f46294b5eedd8ff029bcbae12dc924dca4b86d2169a68d32e01453ccb398694cb0c55607c9918922708d79e14310ee4489690ce85c693399ad22674f93bd93f49dd3b9432412e6bbb0c9411f4cdd0967fa6cfb73fd569906dd4c3425b236da3712ecb4372cb30b3e3478c2c46c39d0993187327de65ae41eca67ed5ef36a056f1f3d5ed41801597f66f243f3aa8bacb7d39be07179189e1133d558c3f2fa281ff4c46f411deda7819148a38814a9e242ffe0d0ea0c688a42b14effc4360d62e2a844179982749b39f7317f7d6c1de1d08f38ec26856a025cb37b295758bb9291acbc33bb769b46e850e0c0ad439c22416900d9c38e30186140a09f1aa1383f44181f31d2bc8d409d46b2ffd0b6e28031da0940cba0e043c670e431ac73b3d5b962420980ce20bd119ef2922d1adde829e2d95125cacfd2f45bb3dfbd469ae84b34074a9eb63ebf1b39f8f3d295618d15555e02ac541d636ba1b84f20e1d41d2969315943c0969bf5aca3f5811882b2e2fec5ca3870a1ce52c5878edc6c92a8f28e39b448990676110af40059b1b1fcff06580884439f125ec81dfcee97da5368cc0a09d86a2915470aae7eed31209f48384f086638c89fb2ccb2d699303b6d4656c326674a18ce766615dc7980c8fdfeb22c4f685fea382485bad4407bb766d0b4319cb0e1bfbed743aa41bcaf08a14bdef6c1f1499cc5d8fd87e6cadd2bd2185e526579b40804101bb66809d7bea5c8318efa7a65b7337098453f9d1edc0f8fb2bea6da0bb112a2b024eb661a5bc8f7b6340d2dcade03110e3b254bbd0fdd07acb649a5807ea91f112147985063a63bd00755848241113b1790668f1571811e2996179f5b4b381fc23813ad11620c226d0c69b3a78db2772a5b1b653091aea04309399c7241c4354ce424284502eeb54b21a883ea2c35ea6ba3ccbffca0a3086247934b02e6c6680072cf3c97e0f5160d4637ab47f09d59f2c424e248a5a4bf1a52e1b01dd93c4347074c192dca6b01a692c6d2d214477a32acf0603a87fe7f1e48560f358747d3512226aa1242bee001a6ba5dcbc74234b38ea9a1d02c2fa22c92ce2efba647fd51a1303e3aaafd924754de9c5c7adfb5f8f1e730430719f64d287830462dcaa1baef0382923e8d6fea85e9eb2ea7700edc58ec80919bd220c24c1584ce1577fc1a67123e9e239209f845c8001ef2ac8a2401d8731376348dd841353c5233766493cdfe46a4ee1902baa97e203e2c0819a877c858b1bcf479bec2d74c1836947676de1bda3e33e2813000497e76ec690ec48eb3351ca4adc5fa4fbb3effe64a74cd51aa0e705af303c555184e7ad6fdedf633851dacf27d04a02de80d680de127bf530ab13e5cdf8066ad4cde7fada937693098d2943cc100757ae4eefc31603d466e1a05aec0a5b26e5ff86321664c6e30a833c7834bcc457114135e170c3622cf3ce34a5cc43d1d64c8e34dc09949e953b3b95de24ffdccb228dbd3225bc158822fbc686ad0b611a90ed7410e93e89ff5834b5da5c4005639f899d71eefb141945a326cad239ec26ac56fd5192c752c82bbf669a627e24a8a6225140e684068ae206b3b59074124608e9878c686daaa09eef8c60c36d61a936872ab38c4dcb915e9fae90224047455b4493884e8045e983475f8a2baa4eff9a2bc637e48afb0648949bcb121abd1c6e6a49f04b136a49cb89108aa36e3f0e3132b621088341e35c8ad605a92b78861640ee0cd0121af7912005311d3d2c52dd90f36b8d9e0825bd266f829a65680f807331a8f381e113092db06f10f5805a0ba5a62920c0054ae0c82310b081ec7b658c463b270f5c7d026a1119e00ffa0f548ce79e342b88058bd312973e954e5f309e6e846f99cf65936f9ba5b9c1b4c8e8dbb1076a736a4caf9a279c6fc8be36457f3d5110a9bbe111f2162ee2e724f13aa3ae297c13cd06b413d8707733abc829eeb39a155c5f8520da3796c33a84a28a5867b56316c26eda0828d378ba5896320271a68e94d0a8253647b63ad8de9acb18dc1e6ac26d73dca9e46deedb6ae56df5a0a78506f76385c883fa4f6b9a48d1f0dfe9d1d1ddf8f71996521c84e7ac10a33586dc108ad64815fdf957c409cde5f79f34c96e015a3d59e90e46c2f024236ff8948c9a769006f56a0086940765a955edaab84b715a423ae97c264effd53af1d22bc18a4aaef818b524f454aea06dc54e4af6c7889097b11e3409a114b7d0939dba4e216af9e2cd12be6cb73491ca7d8ab675f3092aa9e0a96d0955e003de97528527453753cd22f86e414c2f319601bf7e6194ebeaf6b785a771ef079d468791b8a8b3a00a9b6cf4d182e6a71e83d580c0375522de02774bef8def5753d84d2b44832af83f62a3c33948ac50cf975982b8a5e240ed069975bcc93c127e0bec95ecdd249eb302d63d413f73e6c73b0c1609830c8e0940686ef0c071df91640ac74c6c247cccdc6f8111095ae02a76682bfc4417b748eb71208f91aa5289f5a399c1df49bd853d2de94417ae284bc21d75e147a5ef8da742ed216572e44e9870bfc0e51e27cad2cb35c39e35e29766a4bdc2a0a8d4783734b8bc09bb5f6e5af9f3bd003efed4bc3a7af32817e568a24423db8bc6cf1742399aad7e67d82356ad46969f2e29327f327f56d30bf5f3f37603c7d7aa3a6476e3ed111593bfa1b222d5d54892ec2803f66355189fcfd2061581c34cc25b68d69b3ca0fd07586952742dbfd5dc74bb30a49d902409811c7c3f67116d22ce74f42536beba9e8f6c7755be4b84faca9c6c43eb464432f00a2fdad1d1b1d3b05558976efde01e72b640d8902911507ba6571940aad44c1f03e025d801b3725977a0086283d9925987150dd9763910ad01b1f57b3c6fe5cefa8ee5504bcf4c84aaf9abb8f633b28b795207652e0a5052b7aeba1281fa68ccfd503fca198a745f9ed161c98cc332356db8ad3195af9a4adb1e1e52919bdc70cc63f889819eaa1c294285c560b870b0bdd04a5d78c191c099e86620034e79dceb1d3b36aa99c9817f11edd42e1886e8fa9942d582e34618e0341bf9ffe160fe71b700ec6e10c3230739f372d8bdac00c4c1a7d5a473e651581ae03d3fedcd40010634d3168e3a96a08ea724c688094b33cc5bdbe86529f451024546d726dc2d17779a0f1dcce74275ff606688b9b7f7c5a2120062249d5324c9812776cae775afcfb9c47aa6099ad868e13966c9e0f13772ae1402c04628035d4d2460ff383dd473ffa65fd8a87a12f428d29768dd143dd7818492c8b791002d3d971dd6854cf0c0059131d2a8787b194065227e5f7f547492eb28b8709e494724907578f1235585ad1d9377d5afb57f0b0c3d839ec53ba7aac17b1ca41fdfae85f5928adc026353a5d0d9e98db16205d1a0967e2c5c798d88c8fdb69c6b84f9a3532ba6d8326642bfec234a5faeda7e6ccae15235893672012e47914a636c634d762b582d5aae4607dd0d6908ace501010f86b3149282e88848654b801f50dd66757fc5a5d2926365972c3d41019319b227b6d529bd8aa68144118aeeb388fae8b523f0e3e00fc7a0880afa23c1d4e4649226d1e989c7e4a84221f4a755e83a79babb1e9f9eea915a2eae578740b61a34c01d6b32c2f0109df8815b425134852eec899ee106a3a061ff12afa310a9f95120e65760d5f7a3c997d7bc556fd1715eaf789eaaf0dfb8d09d47efe8d221f082bc051d1d827296acabd5705618d79ada799f03cd402cfe124def42f1e6a4941c24c1e74c077264a0cc8a37489e0c2f40d2e13bfe26008652c034b9b59b66d880032904d77ea6873c0735878b9d110bb4d1c5460ce6e7b0c3a365c08cfac5ee1d9051b30b9b61a6b73a62a99ca80e4ac42c54868d69c8ee199257bf3d25dc34aebd4c9c85641fe967c46bea33f61f29e9ce071b80e672566fcb8d31b6b437541c953df7cec6bfd17cf8f134e9c549ca60d72e96a9a2aafb0869e29fd8615146383f31d9019ea9e14ab15253832f3fc03fe97c42e4eef1e67b4c810c93d11227ee4444f922eebf7b6ee6b14a5dcae2b87ef67ac208848d52252fd0a10c6c1bf999cc7cf7dca3d9bc0cbb76e7dd91c68e89c4780aa1f81d273898804e8a50f0ba2fca66b8a866b67f4bd6593493580f6ffb4d59e906bb76b89f727213f038510aba2ba43ad6f9e0b6f5c4600de6f292149ae15f1bc995eb61f43298bbaf9670c145dc391e3b468f333f760be02bc99fa85d8e0f56528267abfda78d363248ab48b7e06117c320a0d09e64cdfdb7ee0a239786abe0b844da5595bd48ae1ca79ee36cced3061d39f7364657f466c4d15380353aadfb7f6f0e0fc9422c0861b0cc62acc6a8038022d359e2939e135ca19cb5a6e564a7f23309eb30d7e19dabb5b93b20dedc0945831c5b00d0188dcca92638938889126d7d414b8c2e26a08b699bbe516ab007d86a4e7560c1e360b0690c67d6b0f151594055121c666a818664a0d1c462bc584b0d89db733134ad5f85c1526699036775d3fe75da8ed2201b0ae76e32b960b83af430f173e6c41dc77b568b2054000f26117e1aa0c8784ffda051253cd5dbcbe2a549c0d186a6b1b1d8ae6197a5a8cc2016838130a4a2f8fbd5cc9bae30b20790362bdeda687eaa7dbaf650be59ebf4caae7c4b8e664b74929efc2759e20d9e3b4991406b52e7a64ced040dca212a5286ada51f909553e6ad47539f2dc6e9291aa0e30f5d389cb04d8c40b725ab79465272d2137d5124c56d1ec4fd0c0bedb9e6c857ec57472aceef26ce22d7893b6ec7e6574ca9e565f0005c01ee1b3e91f380262cffa26547587f0c4ae8e51793a328e13f63f9906c8577fc29905ed2d9ae90c8595542f8a004a642e5120b5201d0e52e764bb563c4c0c3218d9642263bf4038e4e5ae87f37dd30537d0b4127ef088b54698fd8d8488e89b6653960dafa78780f9bef2c41ba6991ec4ff9b05505b83dae505ec75a1c0fd159b0ff8a0b70c62b1ec36b09dddd9d630ec3df2efb99cc7b0a62fc997dd0326a46f5481647510aafec1ddb3ee9a6d4736b1ab5cfa3ae6852c7e3f422ef1a7fb16d32f56e6ca7c2660b78464f3f51edf2fc5b7ff70012d91043f222bb8b943cb2ba44327e05205a23bd8226f3d304e7f8db261a33e50062eff215eb5a1e3c5427533977a769cd866eab22cbe2500109f7987b301952e61142adf87cfa1b17b2241ccd0f5fbe40aebfc53e2988724699f177495b44b39e8caad8cab590ce6415581dce187092354ca3f20b8d374754c13b0bcb3013368e55a175d9f107046b0db4bf652c886ad5b684e71fd36c16a126d1070f1323d35832c66d7d36471c1a71c9b3010f3b00aa5139035e8ecade04f988698ad147f6b3a15a9e58d2d48a0cbd0f1a940f72932302127c286e95d9d67820f3a9db31d2580187c3415c8f88ae0c2b71cb003a9ca6c99a945fad70f73e4544663551659fb3b974e7df77791a683a018be7f8b9a71e2c217acccd10f458a329f05515c89ecf84f08709a09b8d21972ae5336a0a56e310d569a04c220b6404c874d9f99c6bac464d3dce0db8949a24a8da2853d713bda50631f210ff9507c23a727092ec8213c7635f9f6d337353d96ad4337c831847d9397470f57d07d6660cd76f9f855d08fea703aac7100e82bdcce9f6f8b5f77aa422fb2f56ead90b80226bc4a1192d3f9e57d0e42efa820b86ba80350a2c31be5624b61df63945845d883f99f197c58cd4277d17836e0628068d7cbcaa8a780095d34df46e7a80618cb5f6c21d26b206875ef0505258b0b18681c81b5a222c29268b60385cb2fa47b8c6c59fdc18e84be094ac457364af999025004e565f5fd5d30f670265147c3229ba3901d5aacc557523fda51c1eaa70c1e303bb478262666295e4677d055c2daa239bc22ae493de6ea43c4c4dac332f3c0038a8b00ac0a317b5afcb23bfd68fdbef2d8d00e57448ae1325024ff9b93561e4201c11d45b955b8d347cd00eb06571088db2547cb285e7c36783ac03054fb95dbbdd2e74744dc3087550e3e4c4c563f8b4853db2f8c0277c70812b0cf0e5d5846c04cf03e00f64779e5f63626e9210f68c6b4a64ecfb3e82da4797d6c0e4c011d9e07b66f994a958d58d356c00b2058878925018fa2ffffa16e7985a9298e2040b34db1b011610da4ad93070a4c15a5b6e07f33a88bc1720fb960578cf94c9b3e8ec043e965efcb458ec733ccc903c658293aaa11ee6fde0563a7780b51c863eb020384981377d4b1652f1f63b78b10ed394ccac1b76b84f1ba2a9d9fc92ebc9701fb189e8758428a89836a03c1e5011accef2084db8b68da6d4ba72c79b58d4da3a9652681367fe8259afa166615594cd8c7077c9f586dc4bc2846aa6ccf7c91cdc1d3c248223eb3896204399994b10fb5613aa9fc28c9749505cc2d0684f5a1e86af0079ffc18063fd64c3a5b5e2a9f69523d3a7e54cd05358cc08992e2fd865276537ea723c547aa92b68e75508dd51d11ff9095084c250d2bc15ad5c64e867f3732c5dda385167312582d749594fcca4c1bac02ad6279bc1a1572235e50292a732c68010d72bb5e212712c1b0edff3b031f4ba5eb1111a19f874594c998bdcdfbcad28f2214c8d3781df54e9abc711b43285e618a513a7ce0a65bc35df2d9b57ff78f19b54b8bdc43e6eee565d2698f5b30b531e74068f96fe208114ccab8b1c03f4c74a026c79b350d142cad95217f8140b79b590d75ac3dc9d2244f2d41d6b0214d78b17ad89c2f715fc6ba8ebb397364868e2e963df1c4f6497bb0feb9126d26b0e4521e167e580492cf2f464aaeda99698b2dbd6397ad0eb016885aca1009e1385abd1975aa95448b3567b09d00138eff9700091cf8ddca1df472eab118589009ff8140d160a50328e0f18edce5b24979c393f75f9fe2d5d322f70277756820c8a8d66e9c1fdbe22ebe90c6cc475acb0bd78fe27493de009d54fb4864b65b33a836c0a12d442ed0da09b37231fa5713689fffddb89b737f695cfae9b152b1b239b27855cdc6c34444278bbb6c576ad00d4dd9aefc31616676a3c19c05cca688d7c44ee047fb81531776b3211a8d61cf8e5dacc2238d1eaa71e2fce338626c301213a2914be78a2caecb0cb2f9b2872e2145578a4dcdd274812d64985531d8188034affd19a9fbe598106a14fea6a26b0d2e5667aed223d5f3224755e0cf19d98e61ec0517f9fa23a6bcc75bc84be7275eb0852b0db25e25ea62f9f911c42061eab95df83568a3030784b260a83b34f561ba20b449f7fd04f064f48f642b572cb0b0e6bba0d7c8b4d705e089aadae3d5fcc58f9854bf3189d9abfc39756517b36e6050e9b4500bf702f3171461f1e714984f9e51d1a587140c96f711ce3ff2051106c9162512fcc048097615ef44ba853bc625972b11e335040b54c263b2d484258368056214d94d4ec5cae570dc670d44d647e5affee7f5c0cf4f91f74d73a1e8204559e34c97e41c1d749525b79131e01ee794061f66ff8c177c07a827738297b210e44fde07daa1c0c36cb9e5d6d59e6448a6b005495500c5caa5e0543e39ce204534a9a1326d5167b68318dc1371631043f73a4043cc94127d1aab1f784a1629a90ea075702d6c800335a712d1123c57477c1f604537cd51788b522a45919692c9bbd972b6bcdd2e9480527716d185e9de83d0ff0f133739f5eb66d5d77ae40cf68af5f655c96cff1016454544824bfdf1c0e62e12ade9ff40692216ab8c5e16e4835a39842629ea4e26733b9d9cc9d9a6a0f3438c6c55d4936c55285bd237cf2d0e907c863cf795bf4482ceee0951af95821e19bc01b65021ab4312946bc01e5fa5c1f0e7b455afcd22817b4f0d8b60e9bec3c81615598af22f9c4fe56e152010da971e7d7c36027a4f7f35ad84fbf026c1aa2a46676e8929cecacebe6449756b0e3901f66678a6ad8afac1c5f4f36f4942131fc7f0fb05fc88dcfb2cce2789a678b56fdd90d00917b2c976aba2e3022ae568e43490bcc5d247c7296269f095eb9a8ac76df3ab184fd2bb621aa914fc5865521bd8fcd1db918504e8b32402757638c45e7a15cf785c5a738b43a494d4489e6339db92569e8f920bd498be1ec42ccb530f107e6dce75c7aed48332c915099b3f4e273e5ad5fd1bf6c68ce3267e41842072aa33e13264d69adce090b3e71021a916a0da9ea5435d5882710f604d1a5307768e9ab5cdb82d8828fa1f0dc17fa1b2b39afa599d4daccfecc29cbeb59a26518cb5b76295b1ca55a21b4789b202b18363da9acd79620eeaaaf792e859ac83e39e70388a6594ba5b43113e352e55a907b89ebf3e684347ec6194fe5aee84cd67b5207c81d3d72ce2d3f113c72fd1dd8bbf95e2a6386b1d867a417ec8a54acc957d3dd11f1d5bd3acf43ffb6329fef3ae00364514471bb7d8df6452f4bd27e9fc1e97a105313f2bd97e86ee3adb8414975d843046afa8e6f6da1393ad576fc018aba45a8214c75fa1bd85153039fdc9e29fa9961b59c6f73938dfeebb9c69b8309700b9610780b7e3712bfb1e73b9aebeb8fac967ce4c86547043adb2db69066684ad0820532c5d2bae26fc6a28d1d2e5fe73849add29e5408a34684ed524aec2cc5fe7b9c6672cc7c672a2fedf56a7f16b5fe913d1ea8bc5fc3ce59ae8ff9fbe8f8a68b7928e461761fde28b40d7151ca8cb1fd8fe3fccadcee79dc54089acc2a2c156a9dc0bcb73d77592b20e50e26d249bb8150ef3beb3ca6be0ea7c59bee2b00396766e3009ab9412f6056093c9515fb36591d854ec0648b20c927685fa8a74eda99d34b6d824a8af5a173a691c6d77f9d1e0eeaab0511b023736cca70d5c03fe7e67ba7e0feb13dcf1d157a8ace416c3a718db8089905bcc1267a54e513d9315a29515ff4392f30e45322698662cf57b62279b823bac0d7656d601fd97831a945b07547142c41e54d82f60c6918d5944e234243342c32bc8e4344d0242e7acacc5720f45380e5349f52a26ffd1aa788f49823d8d0e8ea968345f178aca133cd58489b30ad3da429913608ba49055400d848c9173ce533042e032ac7da5cc8510d56dae12bd80faaf9654ffd3a52ce9683b5bc68c393ad9ee1b2b9f43a768b26f7d7a48e01b7fed0257e5baf13a7466bed8e768ee67ff0f8a454fac22a1007caa07444ccdb05a7a206415586881f698290685a7b52457940f4fc5200218a4910520e37c8da8baab13761d9c59b3996e482f20d30b4263b43948402fda5c7b9e69387df1fc5f8ddf7d42a100d664402891e5f8283a623e24509895432830876ae75c89cba62f797bb574c91338430b51b87b0e49e3ae8b8d0e16b99f13eca50016674d0b6f56e9c56b976a27a0dff0238b6866b95b7860bb65892adf11e1923d48bc9b5e5b5d1a857c326b661a13c6c91ac16954f13e960169dbac69f731f7c4d1f05d0c086f951c74a18968cbd04f169f7afed96fe74c88c843ed90e8ed69a82443e4b8bbe7bd79d3c9bb7e5991861ad589c5cf5db5e52ceb6d258ac2153ce150d04486c4b67285b60f9dfe1a9c2e0c9947ba3912b90af264745360803973be274d0adecddf8392ee6256c67c47784ef083095921058fd92b2c537a116ce5d60a3cf691def90fc9c2a204eb11f95343460f79092fc7426a1ce74c81b18048199b4ab2bb8e74fdda75c2338138a3e5c1d77dc8c013acf89b2ad0c17a667d4805438aafc5f70b44536f47df3da1ba3597bb0576f0d8d6e13d0107718cad37a03b283c6374e852ac25eb1ddf38ad847439e6d7857786fc0840d6b628ef8413ba26b66ded19387d674d57e58ffec6514edf4be3d8dd76c5112fabaca251c59909081f55c7b555d28e3a42dc8e2452339574ddaa6f5c18b82d0da89d7a8488dbec7443ec77f449666ddcaa73864f197792d4a6c80c088019d171a413c230952449693dbce1bd9db62a4828841d9751e0f4411fa5271a9a9c9247120ae0a576bd6ee1d91025b95295592aa0e3f1c38de812f3af82eb68bb7025233c7236b238724bbb76c7e68308c2a6a006317f38c1a15ae57832a8f1e835e6c7db7a6b2f897b811690e530363a67eee46a6c588743b129c68590c402bab8c266633f237c11a3223431d26ed23613d4ae780897ff90efcfd0dedd427073e05000e4ada0f191ceeb76fb8ed80b306e3147a809d168f0dfddedf53ae30b0d283576551a4a751001691067371fcb93f2a329186f35b4a154750ca6a7f00cba6d806529844116274a5dad404acac168ba17a7e32fe0917cdf86eda79a3f3a24619271d3b6e22e9ca1e305c1ee65bd0e0bd8555aa027c005b6f021dfedc20269fd7e33ada4d9754692d5f3957f0252ef9780e1df6dcb118e889c4690bb493e1bbe87d15121311cd75c53372d51654acd0f8e73a284de69c4099942fbb6cd81d131416b8805b4f78073dca06bf35c9aa61a60c9d75efeea1014167d20ac8d3a049a83bff464a65013b27b64dff9a6a8d86a066a1fdc2030274e2cec8840dfad654e3d7ae85aeeaa8d4011a2290cfb36d84af5a652b0a3e451feb6e7b980205959733576f26bdf18a5ff57869b6b261fc8cbbeced303680374e36da747f5f60122e0bd6109459511a9ad2f1da2fb1e984501b50a2f616e00e4fba4faec235c28bf6ff61fa7ece36b3af9a267b5b1252cf1bcb041f9a782b2cc0c091133d8b7a665b7ad81fdb636772ecc34ee01df6e3a8f4f0b9f6110ec4496d55d660e3a0ec6f3d35b02b83a664cc4d70c294d52dd0f9d1e76f4cc437f74a0c4ea3f83ddc81acfa13c608c326746a370da56755d2738b0c5023cb3262ca687dc780372e2c9e49454858230d77890abf291cce4fc145bed54953e267321a87a0afb73c9c31350b5ee7779bb1c5e42156120dc0bcd378d80939fa4e32ebc1766cf57f3d3fc0487567eac91b43e47d352c43a8bd903efbd7e99373180bcf9c9a7a8f7349523c22bfd91a47a64ca29d0963244584b6a70f0c461d5ca29ac0200f902a96a7b198a512ea60c909098901f523e3f07fefc826985233e1d8c9786d29b6ed0d20b87596f53305986d0aaa580384f171575f829af8715c5aa89900ad324fd08a2577042d20c091a0aa33cc53d14a019dfafee21f7ebd3e33fbf6093e33794927c290221ee3282c80b20137ddc7a0f2625251b0d3fe5f7a7d9a1420310b3dd69f19cb3864f45f6c6b2156f7c0cd8fe59aab1ebe96f0b491182e4a9b7c5f4affea3bd26c6831caa87abab6bb57750167e43f29b9428bd8a6d4fd1a855152e2d5c5e5cde6e10545534f63988f7da00f02c3a3c91653ec2faa5587bd98736113e6110b34df72813ed55f82a5073efa0faa4525789c2c822a74cf98eb92e7e54a91a6dad89e2c19a2724c64cf1954fd81f4ea52095750270c355a5ebcf039dfe13379f42a994b625d53f8f9dc83d2b6db494a687ed5f6806704ad9459b1e29d2abdcc8831cf82146a3cb372625a2544cc950caefdaf1ee824b887d6569ed17348f4e35ed5888d930a5d457171558f44edc03ee600941bf3398abf69edaad6b9a7486e7683c5281283bb36af81e0ad2248c296747514f9cf1fd8fb13821cbe45456b36e5c42b269e429fcfc4cb1f61487539fcbc33f5d323b52ef33953db0d47a1a3ea213569faa2b064312772edd1af0f8b6740acd2845cbfee26360233e2eb207bc7a61f53cee0f2a154be18ed42c7542c6eb96a929f88cd337009fe8d99b7c7a2c35ccff5c6b95486f6797608bdfc573031403cb91cc62155b934066cb9c379750ed2acb11a1008324636df0e1a3d5e2e530793698652a4fec9c305df10712803ed1d22089aac6fc8058c1c9b634616622c44b0b5094f8baf1a014896cf597a416b7c4d36f6cefb710511e082e1a8a5fe49b90ac2bdb4c8ed9be24ef311655387962e043b29849fa9983cdb4f45a342d0bb377d551386ebe052621a42667b2427fc5d107cc31840dca7aa5850c4771ab937ef442329fcf59253c6874ea8f2f821050c70685fa67a8d5b820190353326041aa5bab8addbc9dc4e7ec8b7efba3e03f7d535d0e0f84f4a7232f79a09b7679516c2bcc67e3c603d127d2a01a92c4c4d2d751f6b2adc4b291c76434eb3f90f4006be7533eedbeb4840e07163ecd990e79be64b3f7b44e4adbf92d96ce9124be87eecb64dfdb051ef05e26fbca406f6b8a1347379ab1cfc7edbddd8a7b8c7b1ebdc732e7ebfd4006314776a274ad1d238f0921b041fde8cc8cea80ae1785f6f4d054985b09173ffc775649426317ba4ca7eee5ba1cc9a146c96c4c4355f5ff79fe665c7523cd064d86b9c72e9590cc9cd08b68739fe68f0912f4627a454d576528751d9f2f1a6de4416e0c61c70a240bd991b5997fdc854db4bbce8a8faa1e5f3e010e98aad768f4d788e4b51066ea481ff6d6e4a95267b72369b79e949f3725be3b98d3f937b9654bce2955242282e7dfd121e56a44dd7a7830c765864c672730ea4410ad0c34af5ab003f49faab003dd89cce783f970d41103a9c5434c0d9a783ae5ad544f3e83d936896dc639e4c7313a3613acf1e362d204f5f52b9fa348289e037c8d0817eb33955d13d810c581d36e4e1603644b0b41150990d8f455c3325b44bb8d39239b62855dd1b333ff7b9ef70ed3bd121d5012bd1c186e87118268b792a37f2fa8e179f0463244e589e470e5b834515906bdaab63c808a05aa56751344073028b98535bb14957bde37e519eb7c31c3fceabf90ddd2544e4132c859d18adbd533396165239488ca41e4678a837a615e004b68bc61a61e69bf5121578a66e56411564351c519aec50ad60f2ad7c24b5c5bc53d8149cb703ddfdaf49179d930d2244c230a69b3c54c31fda4699632a15f81ec52f6cde814292880edd6d9fb71396d3717cadb6ec34c3af2d80e60c033a44de7ea07e039c243d3947826caf7ad3cb5b42f5bf8605fb921f0cf02862e2c1a81a238f6af6896d24236a24bfc04cf55555b9db406a007b46323792e6987ffb891b238fe050fc2bacb178fd10f7e99d7b8b2a448c24878b49f5c1844e397811516152115e37017508339a2419e66022b7dee1b9457cbb69bb0a5e2972d70c6c25be81cae007a76c72bcf6462d7966b4c153d52ef9cf896d84f21a765bdd0dc792d610112489b07fb8e9b2312f258b0ba455ffccbcd8c1ab00485686cc1444d02e2ccfc54e1c6e41e91a852b3626bf3644d4888f136797fe858ae9a416ec8c062d4b196906f64c87a6f0050268f95d4a13619c7459bf177717ac1ccfae5799166b56de9a5f778e9cee8808c6b2cac3f23d11b026670a2cd840d7cf9b10fda95de48d852ee96032cf8614cf00812a1a0e5bbe8d0361c459eec48cc347083bc2ea37c918d4a5bb8ad80ac7230ca99c39775602e8831ce42df5f6de65a06b087e73a6c0e3535c99f423fcc437278718f7e98b9c86ca8907b317d316c763ab9c0fb5e00816b7ccd03e5df5e4a108c8113ab73d5b027c58a9b0343f0c890f83e8765701ce1011e7020f236f1c80a1916c620c7aa6ac37c6f2f1c466c6228b564f37cd5f81470c7524f9c33a5fec66f3139ac9f7967d6979150008c4b30b1f414f84114c842a4904b284e10bdfd265888bc151a463522a5ae2088b776b18cf7b69c98ec4362ee14195d08d2e0158b9569c2431b10dce3aa541d863ce2bdfe96d0e5333b4c98e5b373fd0dc87aa63c03a6c50d2bb2e3e9e52fadf8d90d606a32045d88ee9716e1e58e7780dac9621d9707016ce6273162e445f4408d88e477e1c5e3cd90c9940d8629a4ece6198c63c411861f943b5d9e80ddd32689a094d6567d42607853b2cef054c59b86d71e6cded4d183740882be77c5ae345e2c6645891946489ffa1d389f823930b7cd60070692ef8d1302db0ebdb201d8bfe9114419b8bd32eba3058f71ac94988269eb4bd6c899affca8ac37a547cd54733536e1d8e359e82f880c457b796d265df81872707852d5a2fbdaa34b4d10d1f09c7571898b18db71f1d8814cc23084bead10e05d3f5c978ef0165852cbe3f802b522ba526d9065ec1db6d5809bd7fb4e06ae3e64d69b66edb570e0a1fbed4f4e4c607b71b0a1c29e2d0b9a61b294a013b5243e37c3b47ab603c6ec3f09ec1a88e4a3f5d78fa6f86043a84fa13d51c46f0fed6c5aa025c873fce7ee6563788e7deefcfeced62d110740e226e5ca89d5cb86fb7790c0299bd6b36e5329a4dd34a0e0b1c8b3d0a2740fe8998c0e434b9141598e79c253d5f344bf8d3f61cf034e71491442bc2d3068cb9737f32b904379933cd8094d0dbfe5c296a67312b024d14ef2739798103862d717d4c15a1a4458d5e6403514a9b590721083d834a62ca7f6d5342522f19a00d673c8e9335cbc7ca3260899f23207ac99c416f018c3f0857674c120814f7d38e747f7f5fa7e4f1a5b56a6dbc2ed97bd480a9fc3290775434538c36f8a42e62cadd3bf12806734b076933ebee2787a55bc11d3e1fb74c88f750735db098880625b469ac6c7123626b81af9ba8792d53c51af4c4ad30c73bb18e8718ff689aaad6bd6c5314b9ad60ce7fd521bce23fd22127419f904c2107d2869407d21079a3f77ab820cfa4b2a57973536c5d3b4aebfe9636cb353e89701c868ef7ab3c3260b77ff083f98fc327d16462e193a3047a51a54292f405dd6575104941cb3b128a9d5b48e435bd2cb10c2e664453d5841e72ac2f72155d1faa4eb082a60cfe3982989f48e4af557c7f2a4b867fa71f8368cefa463267a14cdc54b3d4a66541e61abe92f58b0c38292b68fce2c2c5e4a4dbbd213f48b074145028351a6fc60c6de04dd00785aa521daedfaff7deb5bf6a92154253a6f219c9d1cb303a861033771c9dcfb1f19d2cd627e165ffaf949819c9e1cba3c26ccb67ea1d727a115de7ce1c6066b7a096279ce2e84fea71163ea397b8ba2d0386db30cd1d16dc6fa3213015d28b7b3bfdc6a74d99a6c871c7332bd9f27fd87df443b472ac4b7345bb4c10659bea2908ebf442c3e3b649af896154c5b8a044f8fdc4c34e96260fe704087fb9660a91189329dbf021d8c08ec98ca4595da46e6c38288a85201d6cd75aa735abb57f220ff2d3637e3a705b8e0650df1d7710aa601e8f8fccf71a46bbbc72dca8b5d60c0b501e13e3419609b6726721ee49d9b10e7513e31315913beff23241091eefce5fe90e93c11a964b623a0287005716a8b387e2f1219f5c07486e66f42c9bde16b5a1ac6de4ed61b6e63062fd16c85193f1c4c2b944da3a0ea7a4584f6588b61af9b31d7c447143e624b81d28a3cb8a00de1838b952ff80b10821e7f681c3041e595559652a3fc762dfbd972c11ca805e2850941a2f0071e5e42a702b2f982279a2450ad8cda06ac0f5d3f807f8e02708827e4514ed34887a25452b1e86b30295223858cb6d6e956b9f9285c8e72b0abc2ac44a8243b11b55b77c2f1ad44e8d6a87c1eaf540f08162d6d65e95577fc2d8aa461e5351cd7100cc31190522883f14b4643fff5a2aed76d203fff2d769e8f4c19f460eb027803e4ccfeb9aef6edf29dbeaa5a33685923eb9fa3e66bbcdd3ea21f3af14904a6abfbbc545980b652a9d2a5e24c88a859d009f6aa03a11691be4e16797f840a0f69bb930eb423802b39280d098245a8f1fb9ccd78ddf069155a031980f784bd18bd51d26f4e0b0474b97ebad9df40efb673800c0102d596f363215d54361e01a60202c26c03dcfdda7fdffaceb5e5f9604d4498a9a8a049182ffcb05ae16d92c4639a5aa43bfd540bf7eade15380a2e3ba9dd45e0afc5f1d866d716628cdcb8b97ba5160b0d7cc078e97519eb37bed9e2f455035cff9365b12a319a0c1cf9b1bdb657946226be2477f15743e721a2de9c70b7eb19795ad928ad442b406b2136180d4fa62acb3376a5ca10c38d74b8e5f0a03e904b65b3b565da8973b534addb236abc21520ae09ce519d28f8a4c2d5b632a3fcf3adc6b744fea50c07e82affb765935ea5537e7d922c8fc577b2e191597da7be8b05bfe88b86468e5fb3b5171946f942622afaded6ed1db823a9640b8393807ae0859e82099b67d45964b9cc3edd11d1231a7db782bee7f2842556dfda648f0d27d33546e717176809a44f2a595be37a8f3438b028e286688f689bb16b547b479e69222eb1326bbbf645a0d100830504a4f980cc736f91bb49ef8d202a557c1982f40198cae51bb6459cfffe8cad2518b81ed00153ab92a35fcf02b394953ec2a7c15821df54fad93ba111480d6dc172bac4ace689568fbb3aecc8c9034014d97517595f8a9cdc270b3fc067a4b71d756548beaff5ee1629050bf92f57503bdff2f23a73f274c02288647a3f62d48e825611c7f03bd6492cbb10714c0a7294d2fa2375d421a0b58563f85bc5f1e3c05b2a5d079d4c869b6a4db8115332e09ec7f70b096a8cd1ddafd0d9a842b926b52b3c76837064c10c2d4db654218da6100fad3763f002a2428f049ad56faab901ae2bab42067081c8eb745a61188007e850127ebc900c03c825971fa760b2a75210dd84b91dff5075a681b03f4392a363d6319f6aaaae3ffbd14daa0712ae4ba8f1518ec5548e734a6cf9236a21f8f2cad086a77873ff078160806108e05ae9c7c80e6dda8db916c92cc17b34f844471845835d207d0cbc6cae7a70fbb1e6a22e6d29da092a9e755f4be894e1d302e6d1d540372a20d1f727ba87e8967ce807e89f7bb79a0391b102763289ca8931082234d24b1f2ca004562de790257d5b7915c2fb82042aba8cba919a91eb83500d9211eb5d46f18a83016135f3d9d7126979bcfccb7282002f7c301d5ebb7cf7e130c1691f4c0ebf864531d09bb6e3c009f3e62202841bbf24e9cc5bfa14926329f6b6328add24a0fc4647eb208791aa22eada3cc565a84165a5f34db58ec11513e79d5fbf22cc4da6c3f1e3da73c69dfcd4e0dcfa7a6a7d132c634ac0e75a3a08aa4e29caee90582deb42203d0f01271a9bf291347789188f21d1f262502dc2065acb022b05ed9d726d79865987146aa64e6b87754798cc16a14a17cd8681d71836e4920a0e44d00b793a31b290d1714b1cc880b98a13a9bb3081259f217ca01022c8cc55849831066c3efe48c5b29a94fa6502533126118dc672d46ff169c2ffb6b002767eb6b17339013a0432e8b677398a35c563ea7d28469e595103697ea2d609fa28bf5a96ddcc401f0ee0bf9eebfdfc6f2efd531d1644a161a3381501bba42d56faa2e079128675c233cab7498f2b7216d8932c75aba0260e2b7262dac8f4061d5135492d78b4e6ad50dc23fc1be5d12713fe6114b330ecb36035f484b07787802dc950bc4469b733e8c77c9498c8dfa1af74b64c3e6ed209a4c7ad15e87964a0c7c1c0ccfe0c9d18d4d62832895176bcf3339c84b0f295033a66af0340a17a9b3dfb8c20ebaea4cdb54c2fb711b53d0c486a7b5fbe5fb7dc3cb19e6b1b2f2f91e6c4e1ea34a6ff7b12f3701f773b36994e2e77dbab63759473ba1d974f8234646d8aef34918af219d48e50c87c42aa02b533e35dace3c8b4a170c729962e625428c84be678a1fae78178889742e77eaa83a90a84c8b9355c5d056acc5e613be3aaf47e5e93a6fa85a01ec2865ee9c7713f59d1581e93e6bf36b5978a03d3e05d5b92dcdcc7f247ceb1de2ad84aada9cd14fdc4a7662b8e3c48c3874bed963debadd0fea6cb1e062a202424d0cea97232d390acd3c09b3681dd54e078e67615b1e41283d04215630aca2ddc741060899f0f8efc5b90ffc3fbb602ea71fe8e10bbc0ea3b16cbe56a1da56e02900eabc6bb6cf379d9eb67fa6a4a366b1a52ff9d96b53776e68f7c91316741158a142a7ca82700e36d4a64ebc9a860c1102ddf00486a16eb45cc42c39cfaf9d1bd3ec9dd1b614fb20b8bc634d1ad1d0fec723177618456426eb94d0b9a64f00ec8b6135f9f3049ee22df97eeeb977236da9cbfed6af882422e2b8cd932140f3db515d5b87b8333d7d3b4480dd9f9c58381e10b85c320ab6a0693acb8cdb1cedfaae6c77e12e7657deb9103c176828c0bfb530f6a1bda69fd879178e70c89557397f7007b3ffb9441161eed3e01d44e15a6e1d4dceb7b2f394facb4f6733cdb2fccab7557fecd8030853d1ba4cd66cc9c6071c1e2bbee55158123a0db4ad5f0e67e33c4362ddc4dde87b262932dccb9e0c58757552a04f54a35899c86149609a0a4af381d55892968c1f5cf3af9327c61ee25e13cb97f1a268f5cd36263da9ecf2ce39d0854d16a983dccbb335c956fc0403207e9a4960bd035ddd5a534c8a269354689c99bcde055e604839cc0b5c3d5faedc44ad151378be7cc9df48969f46b028af392699ed1d061e4fcd8415402adc020a9bb52d22816d95f9cc22f852c0ee4d1aa6ebe97d27b7c9de85821dcc192642818a3bd827574c795ba4912f7b228486d70af2b40a23bdb143e3ff387f56fbb02412f6fe5cba01b528fe8236f0fa8e52c0837ddfaa8723c29560125860bee9db674f37092dab9a0667ce5d71b9743dafac846dbdd3277179ab361bbd7d6dc22c144ea9396af94a5732d55197d21c9cc956ba058cd82ce15aaa4b3b9c05ef2b4a44d9ded578d6feb66a98ec65717e66095177f2ae375a84eee15e0205784e23971629836c0c891a8305f0f4bde75a20655882de99251c85f1cdeb02afea6541eb2b1205b87b4ac469f1804d097839488da7aa6ec8ba5eb7453cc3b79db8b0d6a1b58222d90a8f4b3142dcadfd3f93f90a63db5103e1be463e80127e5656c9dfa4c79790cd4e5f4250816cfb7446b92c029b079024ff42c121d589a549834396897c66dd4861325b167785b219779ffe32fa802b914074e949a81887da0464fb9e84bd16d8b38faa05d0be3cc83ca0ed9992a0469ce25fb6692d891e7e426e094259b725ec984b78137409b297b8c883312e9324fd431cc288562b07b539aaf417101052e69cc56e83ba98fc9b351080244adde977230dfbdcdbb689222e4b30911732035c8716724ba047c5c15205d14c732441006d25abb5b90a88d452e47e9c975b42cdf3a3f65b18794c3ba727b87b465ee8986b9b3c9db478161aa1649635574b0e06363250fbb37c5433e87a214dd7772ed3f8dd2f096e100f985b34fc970394073adf7a7a0063054b2b79309a92484d5bc2a63786e1d1527c44cf30fe2609ce34fd5a01a27c404e32dbd9cfd21e1e526f8e59d2c81413fa68903c2df1174d605930c702fe7f06e61a8e812832fc05824b0ca46d398b0de0bf50fe714361b10f444de45a9d45b284f51758307246e03c0cc5bc5fc6eb9354719bf47c09f4f8e87bbbc4308413f8b69c654f1f26ff712ad955acef94b5233df966916305af9ae2b18830e33ab5a8cf1cfe16146cf0bc1dcdabca941a361996f01cb6519078877cbe228088c3bb2068c696a2c4b87fb0f59bfce54ad1619cb6096e394427d3645297376f80b7d343ba18cd1106be6fa7e817128bc597328efd17f5268d726af50906ad7e614fab5f52b8d7eb0ab38e21230a0c91ca2391918285d3a57b25a34f6a27e39b8a59e826bcfa45f470e0fd8be8dd96e9526651011453d5b28541ca316888d7d4165fc6288c349d8577d292a104a3a307409dee6508d7454d761756ed5cfebe871bf33261f2aac3d18b42311e6713f5db88ba2e058d5218d04451a214b827274e2352927bafb80202446a0934a12ce8daed23cb82746ac7ce1c2fb260d554c70e0ad4da51b68e84ba75b8e763f8df842bbfbcd53dc83189b1c77d56b070e258a108f48e1db7ae0e432dcafe6ca2d0e7be81716c16f62e56bd16ffe8720fead44b0a25b3ef86d755b01e9217a3812e6004ae71502459671d7c22355db1d4cdb9c0023cd13e30c8d7725823fc9829e5f6d539300eb189bbd19910f427b2bb28bd826c6a4569d7c19fa7a31b65acd0c7694b50dbef94ec2811d56514536564ce184b6095a657459515dc7f630f48994855c6a7c3daf266a908d395a3a3636548618fd44050afbbdb136ae925a33c39cb8f70eb58877a03689a1f543efda062bdad16d128b70f4ce4120a44480b90e05c15a12f56300214252bb700b2b739d01daf02c09d0dc42bc4da2c891383f5715aacc605fc966de44e58254916e2e340c2006ef86562110854404b0f0107c0d532148ef784f1dd798b7a79c6e46d38b37d7894718a533e75548d027ad15302e415d9692b2b77d5df9b0eee771f551c65a583b5a2e3808a362fac21ee674a20d537f298bf7a6c0dbd9258ea5e7b1f9842411aced73084b24875d4cce2e735b238f1f0c3423e7a0bd7cb930a11fed366198b4112b520bb5dab505e6814a865228105301cf235703f926381747afc06ac93e8fee1525a6ba48223385a1d5ecc804bf70e96e2b7abe5a876a3f160bd5cfa7f06c8b0931ac1a26d1e1a633fe234e877b629a03bce7c850de65d0d22e08c5b39226981e0dce0c087d7f54292ae711b2aa5813156091bf1f890128633e09f867d813d2fc0883576a24711cea73ba23c0c57385be1a22ce63131549ec91cd1812be9a0d79722943154a26e92d44353fe90ca7e3fedc27fa9a9204f8294688839eea8f4186e8d485e58c83216fdd4b5bf8c64585e00a215a7f53ea1cb186b15a5747e32814ed6e88e0f727b5b217835dc635092662f00110096c6290cee650dd3273bd02d600f4cac1cb3cc0058b451c5e31b958bcfb2c4840ba4e6df0f138d1085837c7af16965e5c0207a3160e0600c554a5e7827db38b92b1c710920acb1f37d31476311c1beef8e9673b4241db657c2069940852b9fe0da7d44698a00761b84f3627a97c50a9ec7aff3832fc315a4c7131ea6d798dfc1be1d0c94e795408bcc6102a593741c2c4e22afda17f00a14591899ccdc9b902bee73cb53632f3e5917c856956377453d0b55554f77c7d2f52d1ad401123941aae057b6718dd8050b7aea00a15b6d7dfb202bfb57b3ff4cad4772e74960f5f6601762b86535252c3b00168982ad5354962969080a8f7b23a22f7ff4cd943da9d2b80db8fa6a9cbbc0567fb6268bfc072e810174c5518ae40d0b425ceb97e88f1ed9e28d403a9d14ed873a33c039274f7071b035669506e1040f05cda39842a6195ac2a3d3bc62a0a7043947744cb23e0fd0830420e422317c5943f8f8ac6959f4c6eb69f27ce02d6280bac8ff898a826e715f6b2a03b2d70e6a6b5505434fa8834396168c718198f3cd3f7cee7f67fb112e23ff0ad8c7232ca8f6459d3866155de343502ab090ab38b37c12479547fc6285225e581dd1169541e44e04974033b6f5f9def8a4201bb2573cff7348db30e29e0f2b1dee3cef31d78e7ffce88731478a010aaa3c7a6df80a0194a50ca104f40a7138175537de5def0a576e5cddbee2d8055f38c53423ac8a6575f61f01761607b91454313c94c3f4271bf80c1b3a6c1b4a360b11d603947b426c99d7c7f9b07f2504bf61bf01f7320d581d0b57f7b9b6305e8527727bb44d53ea7f12460408f3d1f6ce6b600062e99f9c41be4511bc05b274a91882b554faadc38c0b20cfc44e26c0cd750f5a6028e4bd935ffdfad01b032102c5bb679df58570978f61af811354a273900843ad0437769079d519b13d99747c2251107290acabb67096dfde9ae63b56e102a640be64f609c496c19a3ab5be3c702c1b46d2abe2be38764d3519bb0f0cd4897433d931ba29b3ec2d4ad103ad740b27ba72b94439f7a517caabb66d6937044c4a8916fae8d0afa8085876aea113fbd789db0b63e4ce47c74268b7a48b8d63c6c418e832cddf9e5d65aee540e80b19bfe2f2d1a7c664f89be09c0c7ec36944e927a2ca7827ab0f4de4968aaa359d8404d4309759ff498ea41f466db1a69a38f400d5cabbd5ad30494df3cf2ab016b89440e4366f44ca2bcfa1c985c0c0b8b1223c3b715841e57385f37b4ed17fd0fa9f2e9f91bea2cd93d084a62bd0ad5e4532fb88fe77d05855280eabbfbb698c1f67ef54b4713442ac5acaac4d5f929a28dec70d852bae52b6dee98a9e6934f9be7a85645bff5c3da168da5cab56dc6073317e75360cbb0345bb924e53795e3445e7eaa996e9a88a7c43d83a2779e0db95a9c35ea765b3b05bd488960ef856a049453ad449aa387ceb2064921a50655dfbdc5e6083ba8910ed645133282cac223125a90bc54d526a4581d83be83f0caa63dfdf8363c59c367798eee85bb9d8aca0a46fc2ee432ebe2aab3bcd8ea8c924ac92b100ea4fa39b5b3c025c132ce0c002bf3850b09d87042a6d468dfa108f78f2ea5b0984f9c09a44a3973965c1dd71ff649885d041d2205f8555b4c63364b2abf38b6bae7a384aa24600459fe59eba2401fc1314860f0e4920844e04c9124c909bdc6cca886b469c64f039fa2444092ed7860154ab6ca511f162dfdb4e66439ce4eaec46608a353b9ee135d78ba9908e069b27548d4dab20f982228b1f14a0d38983fcd1d9bd46bf6da744318dde00a2069faf0d2ba854779840229bf6d1a2c7c70f24990fb0d2aa13157a790164b626c9fa84f047b61088238ceb3db5e80921a6ad281d5d40701351e4374ff3f25e022c9f5b6175f8e80354651f35d5aeb4bf28ad8655492274f208eaf8d842a0ef5bd25a99ed35e21958ae5faa70f8de509064eb6e140da53d6897b6b57687ea350c6772a24aa0901407686a5b8bbc2ffdfbbf4000ed9ef1eca7a4217d26f206f5127d815254d86fba0a238c3fd9d7e1b4be842b79f79e0f66518253122cb53cc2310f15776491c5dcfd72518df15c947cc8805672b85336c6da71ee35b2a200425e9266955242ab01849a91a89ffe0320ac0d1cc79f49568255cf98924ab94104b42a3b89001a1ac0a24156573f45b140b534231609760041ede95d462c93d1b4c1b15927fc0644283f159537eb16a61faf5b389e3a9b9864b65ec521be138d0b75d2c681e43be822f07aba5f89de3f1030c4d981bfdb9a7f55b6df6fab3539abbfa30abe27a0cd7d20f38ecef99bc1e12431efc3903a77bd3c735b60b53fae3f811b0c8b9130e34d68c11b34042c3e480379d6c64a6dfcb5375abd60801bb22f0e0b7893fd4d8ec86f758584d0b3ac460a433cbd4fa8ddaeb5668b92d4296bb214f99ad318407f078838989c5fbee5196dcd2a05a62848dd1e3e1035030f1ed35564b269a54cf05ab454faefca158dab985b439d3f882a83dabbfc215582d81106863a568ee3b1e014b592c63ec0abec9154ec2cefb2324c607b2c7178db593664c6b7b613740beece4339f0fa4caf097cb85a8cf9ad805e09d49f09bf076fc9aa7cc4e582ad8864f0d3646ed0e2714539a91271c7d93ab0b8e450206dd68a12f24b3877ab4d235da520dbc6e628465507316842ea06160b76dd917c1c1f46b2043f7c4d7e51acb8517500ec68f17fd302021794c808c2284522b59421020aac21e9712510fc0326d39149a829a1130c3296e757af9f55809a73033de55d130feff78199bd0dc343bbc5410d0a25355a6de02d4e95859a370355288585a578df9e7353b385f37624101a8e5d68c0e62998aff01d4b09c14e59afb73af4552fc7832c4c35755586a485460d2a6093943953a050b92464d1b273ef50c7528dc04b888613f00557dda724b2a1ba5cb437f0338aef8e8606c2099aff1de4d7a322ee197b1dc88fbd2275740753072e99031d94743e51f708b5752c964b96212ff629b3afec6fbf9a13a1d6982e6200aa2f524d54146ba5c2b19cd0a431e791b29341b276802f626969c786b720176aa1e4e4e742dccaa387d6afa72d7b8c285f86845295d52bdc0b42f43c9b5e7073e0e9cde6a198865d6b568e290a95864e6871c29ab7826254a6ff22603128cde97273f0356e138e30fc3db1b61bb08c07f936a16f76468c46f02529dc2b724e384a3c0000e2288a033a447b81194d096fdaa1fec5cb051c64f9f6007c657c32e8232952fea55d64e58de508c2a13d903a97376032c62589ee171b66e70d3838b7b878b28383e5927de5348360dee4d7f63d436ea9c574b646cff05d412e749ea0fe308c20127918a1e09e4f7233153ee6de84a8294f479a02fb21463682c107f1fe9c87883e668e9cb428a42a22d15acf3fdaa1fb0880bd905d4a213b8281fd019e84770cd887982c6170ac0456169b1455cb07a4aebd57215105871e92d1fdc1a165ccd0ca5113ce146ba89d517d70587588c67d22c5865b302b775aac67dc1e1c32eac1117bd48239e86c200ddc0aa5619ec654a96e84c3f8576a997a5d1eac751a109ce036eb83211cd6b56f56ecf6fffaf09477c2c5d04582aae38a0c2d4a0a71901a494eb4a020a935f73217fb8d8c98a37aac2eb3700c212a9f07826fed09b4b22a0c630f5846ed5127ec645f4f2d79303bba24cb65ebe999203dcb6b18370ea5926441c68d7172cdfc340e0509039876ce1c9de771a880729ae084d2e742ed2efe6f9a1f9349d3b777490ee0f06f5e634c20f54cdd79f0dbe2351b5f7e2621fbcd233209cde8b2e0a1a529af0080659d5280985e830687aa69b67694d46f086e77e13f5875be6667e74270123dacc1d8a88f260dd8ea56db0b7b9c94ecfd26e5d0da4fac722099bb05e4bada4d365ef9204e96fec52374a9bdf874cfdfa9de22808a738047f81462739efa9b3ddae42e3c9143359ef3de4488ed7e60b0b8794e4f37dc010cdcaa35f8c374ef1c80864da16965307ba05adc53683881815c9140da968326f1c7a5917133cf9fadaeb4d5c9ee69c666f33b8db45d8aed789a56ff3042eef18cb518299ebd1b4abdf804a86a994c0bf655a50292de79600977500ed8495f511eb11b382d923bc2312304cd63169f438ff8e602fe41003dbd6cc68f65d699ea2b99f607a7fe9d7e47cab0fa7ef699545bcf956b881033bb5b86570a43c0d78ee5025145ee649202907ecb1a073ace5d79ce0c6bb8256a491faf9def2de3cf794ef54ab86a25e38eb6d2e3091ce3e1badba7dde5312d236c9977f75310185e344478a7473653e5fa9c767c8af03aa56b1ff2cfc46707448f58846e4967e20a02ac01f300d743ca620d4f85428e1df2e27b3bb43d7691d68919a6b92f7e2246110f291f5d13593d8979b5f558903010630f09356765efc76f34ddf4ea50ed03957ea4a109b67469793819e196a1328f24ab13d915871c976c63078a007d8d4df994b361dbed445a4fa485eb32740963b7c11d7260e45d97803881d5999431a35fd998af96089456a0c0177b9e8d71a86ed7271a9d0ac13c2da0879c0dc4248d28971c7f795f24afed083b766a48da90eac57077cd97c9d692e4e5344f7c59f862bea6a4acf5ff7849f50264c67b55cc101cfa957b627ca7664b78a4650a7ed71e300ba0d8b1da3381c0184670ad62af5a4bbcfe8cb644f1bfcbf875604f40e52451a4aac7d4554bf83df0367742e33504d52fde88666499998eb5caf8a2c0b7ece47df4875fa44bff791dd94bb603b902e9de68b2fda17adab63692792f038b705891d9bb565481aecdb8570a0d540b990dee676b2b6661879d9750e66c4208af3ffc6f413789ead333226d142bde6d907280f1a8498f2a5f7554b714b9fa77ed7fc1fea576200dba42cf450a2af20673893951b3084fe1b83c32903647b322bf8176e90728675deda4ede65fed1c01edb2ceec9776cd7710c8cbb704c83b1bfa770b6d723b09ab34edfcd9bbaab718ab3e3c8feb10050adc1bc1130bd9574841b407b63afa24599de3cd2c59960884c91c86bc7a1f6b0b87d71f5e8103515a3a0a1d0b4ee1cb8a98af86c32e5e43e6eb5f2d8bf38db7e09d1c45228f6cbe8911486039522591f9fdd58c2752f49a0458568985ec42d5c86c46f2aaa956b636790510b12bd41dc5b24a49cdf7253cc20772ed8c08d5e2776ce7da6830dfc4e988781e65ded9974e58bc8915901fa0c2b0f9702d66ab2fbe734e4490cdcca596a5d6553501d9c202f945b9d31b4176a67ed80aa3d718bf9e57e5e169faa293272d5248aee87d8c644b4599697009424d18648518b1fca10ed2fa1cae00207a4ae15117c6e7b2d87eb2a16203b5697938e959533c69643ad9375d70b2a4887aaa741be8feb4a83b61819b27dc3939f964c2cf346948a8b2c18b209a2da776f755e2b87bf2a58cd117efc43eb4659b85dd354b5629bc9a6fded859b9498b78ba44c7e222887c1fe8eea15ffb0949497b1f866e9af689e7c339f14a58a057a37cce854194c515a0ebb8ec26d35cc761716494940293627e79788a35609f07c1178785d8536964489dc251d3cfdf03a35b11dc572c98a1ed7881eaeae395bf926dbe5b0e2efcb1e533fa8f133381cdff549dd322ebcded8b21e48dcccaf97275466925727b99a07fe356b2ebf9f71bcb6ae1b2ab5da9e4901118ceab127bb122dc1b4538a53d56f421bf1ad6b2cdfb6531092df2f87f09c0b1dee096f3495e2a7face51dd072ec45c44f6df609c83ac90ea3da86aef6f3933d9796b967444e0bf1daa8d46896d4da2a5cc65d3ccca2a119b4d1a484f48372cbade2ff89ddc80136d05285a1bf6ce838ccf4e8419fd36b79645e0107402afd699e8535c5a686591f2ea25ef4d23c61a8543eddef711cddef6810491503fe6f6c3a992de46f5872ed9eac073ad48d880f178a42224e13514a182a36a2bceefc2c120339af18112f0b43b524ffa88ffdb3159c3c4244ec1255a9497bd3c8e59c680d13ae25a6e6124131fda1f584df3cd3c7119162afa03dd2781b2181e42d58adfa11fb08a91961475a400b32cfa26e07225f61f95ea5b9bc67fd8021221deb8fe858b0b7674690b3c92fbf3e44b7edef63b07150c8361670b5c4e642ed2e89d21c24324b3e5db40ba870c03939e3a60de33027a9a9e698fbce253fedffb56479adc5d6c53d700ec398aaa8cbafdb12eab10fec242b998e6a668f31d262f5f38f2f42da35dc2d033e9645c2e27ad19ff266943ae5f3c581288a45a99f2577150c3a8f01cb8d18bf8d92202a5583a4dc07e981acb84e6e54237d446ccf90b8431655871e3709191f63941e1e8c37dd982e5f6626c9ad880c0f28d07561a9a6c8db9740b86cb72af519083fc596e0459642d5e2949e388a24da65448c1beb637674df9dc0c3bf246733b8a73e6a8c626a2b5d281d67a034e3bbc5ede2975ebd57578f900e2783b000af6fbda409bc685a166bfe2e1ec7d15ef11434ee729c56aa8b8a9aa47a3a3c4a55dd194f25d35cd8badd4004fba51f48bc5fb0023b21584f47de6028a66259c06eb79610b9aec882a8522c4cbf1a2dfb45e4bf34296876f00d54f57a192a5b8f87901600856206685f933e0f6abc4b5c8182722c8ad2cc8479247f87327edcb48752753188a8d2c909809abe76f34c5fa9d448c93950e6696f6601d8852e5358e59c0fbf736a7a9e472f2b6fe2f3606634396399cc8b912155f8d98288635d11847eb001e8bf4c3dda78945c9530a29afaf89928606620193d7e346028dfbdd49f1afe98d6084a635ac9aa21c3a6d2f20c8efe5c66d2fe30795215e54fbdc72e831c1660f8348e707fd9803ae15a4320831457d266b82b364f8980c2055a21fad560d023158f2daa1d5a8086c1cd615e182edc7281bfd08821a09c1764e558ba6e618517e6bdc09a0fc746c3a292b49898a7412ef863ac78791a2c9fc1e9cd3bfda1ca2a6a3ab8861d889b922e28fb383c1a8034e24cf98a1f93fcf5448bce36ed47aa7a9ff5c043d094d3354ae2349fd518b2372619e03bc0e8b7301f84e8f705fadeab0a06e7f399b3c6190326717b694e43bbc290f3c4cdc370635cf42369fdaa07b0968f5edd0f46e3fc623f0a98a4503083a9829ed41888d819fbd26bad1a97483e9021e5b0a0637dee87ad5ad0865df8d9839cc90759934b281e9c9c1c648e308ba1cf332d4d6de740950daafb685a5151ba0a23154649d48c9596f7fd2626119ce8ebb499f2032707ac90160f41fb8a9361feaa843db18d4b9d9f3c7ad9ebf4204d13044aa9085d76bfbae8d93203f3adb56efaab3790d1ba4bed20172d26e338095b6044c6cf8f1f6778a08dae8d65611b102468835cb736889ac2bcfb4d60bd4f79648417cd4218807ac7c91291fab3c2b9c865cbc684828e05e7317739b0251a8d7e49a2390149b61acc1f122a591885a887145c34570234fce6f6df0a30b69615352329321ae6c0908a651bccd32e5f126029de1d71079dc5161c4aa7506b2338753f5b26b268f910ec8336cc06c45de195f0f912f468b0a20393df44d3d91b25642fe45a825c8ac6f6aba88a1e97ee2c2dbe418b00b6885bb41d5180f83d00255d58142c6765885212d16aadd1725a33a7183fc89cc2fd00554804a1ac9939a3acf4369b492992a00aa68be145e1682730d503c3728e30988fa8f749d75c4cdadc0459a3447d79f58240454f58adb9bb703eba30a158a5dda85294342ff74e2d8f640f2166078f6fcd50bbc247aa225a12f7d44b72258689789be361178de34862a991bbd99e0e45019361499106cf9c038b0ca33bc3b9f6465dda4a6e7e8c4d426eb2b3d1ee9a5e9afdffce58d1228951818c76af27196cbe18c56c1dec6b96d55f23603bccb2dbb4f3c830a89bd9d49130b22ff0ee55e0686b6b8616ea51e848cf22ee847090db27e9e82c9b3b973b9f686d01984d05eff0dc6d5992ebc11185c876f9a28b0337acb00f140d0c26143b3e6bbe8b293a7d7d16cb519fbf765557f08e97be29c5d7800b6f92f823c85a6f1eba965a7d0b7f324efe6739ceadd9ed4617b74917c2450a0a05decdc65954b882604a414d97ec2fe69c22c266ff0ebb7fd8a968361c2b0bf7183482a740a97af9b9559b71028faa20ae6c9223d1e45e9d0ca50ad71c0334d652cb1557229f794906996f2d2a7b8676da5eb6f0159c88ad00a47d4c81df65f48138bc0bcdb97dea76d55259e26627f37f8e3dc81320eff0da75147f645960faffca98820b8bd05fe9a6184c2f1ae9cd625fbe897c1bf88760c4c5231c9a9553a8e4fd3129a2fbdd18037365b929d8d72438355dba17e03e48a4fa433305570dcde950e25a770f2b6214937f3c2b912d75ba462b4eb1d8aeac0cfd13a021ed1b43dde59c2ec001a4b473ec6e02538a7f33945d27c55025b76c461ad0459ba481af87e4e5b7cd47c286e1294944ae6b4f2907c4ae1c003d0cf288c3d7f6d21ae2ae4aa4564514f057f309240b8a3aad7c7206d0ddffb93925d0424ed81f70cec06b7abc876e7cf7982df8ea37a79981b3c5681f7102e239da81e2c16cff3708719105e5a1a3d0eb0e2bb1e5b31cd8699e84bea9bd460ee702fec171d2e5b9a55626fc693d800abafbf212e8c02f8db8f0947d1b2c8224641047b9eec3f2163d497cf2480d651e51626554624a8d9c3ae89d03019ae11aa951b066996ecea0bbf797706717c4b970c9135accf3025dcd8d55a002e51d1cce526b22a44d9834355d6ea8ddd71cc9da2c95a052ffdfd1807c2272fe0157b7002e7b96906c6fc0699a64c3f9d23a21a5c42f7cb62abe817bafaf4277d0478dc477a3699ee21d85c4b527ac68bee2d00d94e0c55ce742d9ae3a9cfd41cc42f280a3aeedd6839613201a3e8523c6bd6474a5c97e1635156d57146ebd978c7563d65a07454fc0b2b04faa7b30e3af36771e6fe138f60df81f365f6722711b45172be6d34eba4d188b69958df33d1d461a2873648ee3f36424af34fab634e8a0f6ef5d0a4579dcdfb8286053c8e9164cc6fad2be9a3add1152161f3bf76306d3e40cf4c2da5c2961c5076f74a44caecf98310ef09e91ba6dd706262513baf0f4fbb58f00aca4fb0c7c00065f150cee372188ecf180c56c43a9d49ff9ec602b208afa29930f77b260946fffacd760dc994f94352b203b5cc6d8e11dcce013ffd9e328fe452bbf058f395aff9689b91a3494e5f70bfe39e2ab292d0667632ba263fb5f77261f2d1b60d353c849ee0eeae4c5163211e15328f1174a4dfb0229e9e739c1e5e9b08f527489cc5026fe79e2c4bbf6061ab55e3bee0c8a74c8a18020c8a407ac46e4dcaa7d96c977007d55389830cd9cb3498a00881eafd51c4648c768041616e4582d23dd42388809230adaa6367bd3ac81f8332cdd3fe08d203bc11b31b7c3a0ed76c503aba5003b2ff6a519c59502f82cb534c27c8c0fd7f7b5b696dfb298ac2875d84a78fe3912bc8fac0e61084a611833c82968cc0623a16ca6fbe4f7332b97332146f4c315ae72996e4b8f3c6103ab362a37d15aea79944d4b000c6814388311932d78cbca6587d98db6df9176480b2e8b9eff74f14071adc13dddefec7a6c065a6d3b4f17b72151090b01292f1f968e11981d1cf596f80ec44d5046a9c7584273dcdb59b89f6e59cfd521114d8df150c542ea7b8f404c140a73842ccd1117a54388f686bb167de556e263a64d46f6c0f285a2a6ef34ef78b4864f4995de9690f22db41ca04b37d68bfee475ab7cf3f8169aef558efc03d56e9b85620c8346625c3228867f9b799ca90174bf46073006c60f0b43f85ec633e19bc9c4008c0af30b3a4a470faf5b1303db8b94e226b5568c17ff18f34debc76eea1f7b529e6ff2d9330156c64f122271b6d844d620325bbd6b068510844aa6632d3fd468f69859c0bcd73d8ca32fa74fae8406229030d4d5bd60d722444db01970278f6ee4f31a88f34de7a6139ffee23a2084ae0aabda88c616dc7e85f4f05a72ea7aad99ed55892d773cab7a7a112bdfafb01294f1e2237398034246f5cd4425c033493378f50a6cc2c92cc5508482651e04c9b03b46d51cd4b2892f74f524e1b7a9e4aa9bb62355041233d0aa0380c8308c23a4f4bfa3afd4c9616500b2ea27a5213ba4e14c1f21d5cbf4f037cf63affafc658f777e1113b67fbb9e0675a65d843443240f74916c4c98f6c60fd80a6347899424e404e9848c9fa45e7d5cc57eae2cf90bb60b31caf1d97104bf9c53a2e2c12f71a01178a0ac23d3b1f98ab93155d1f7b2824fb62cb82f7c2764f620df277b62850f09096eb8e66eafdc94922dedb30bd20b6ec25f0b98b143a0f28036efb540c94bf7151457606befcf879e5243ae616698686b88e64a3aef2ea742d73c3c26e59e58de0cbef25fa8c88192f5ea624487928406848c0a151315522687ebe380e15d9e075f0cefc2e9f7948ed98c1d23a236f5d40069666ddb800e5d57acd73d5404036be8e5d1f8ea6b7d4115e8f335e1a70fef80b2bd405f2fb7af167d499b6e6d1c5463801802dc90580bd3d07b3dfbe57e2ccb720d5dfa432791df122ff5de3d66cb44a76278d8b8dd33b5f7043a53aa15a5c461c864aaec04e56e687cee2726c29adbf22fa735511f04d674ac3d7dab18f4a334c7221a9108f33f40f1b18c381f8ac02b53b41448232bcd5df189ee805d8270ca8521133f581acd78015fb97706c4d063b37653f50fd223c2286366a64c5785b108e71c56189dbf5a1ac978eec3c9e0e2a04e1cd3b775c3cd740483809420873116302c6a8f618be98f09042da48649a318d13d1bbd379d1499d6f7ac0a6c2b10bc6d286faf9e4c3a26278efc3d60fcb313d766fb9afb57b4094ef5748554564a70430e352d04cec1a8aace52b41c42cf51307892210ab5ed596951e75badfc7c5f17a6619a6522fcb222348ad5a390a315fbf7965c012657145e62f81f1f0ea6b5b0d37ef7f933eaa493d8280f8241138cb5256f88d6fff5a10f8550313b73b2cd7f13dd7c4e6c032dc4aad99a66cfe8307f3bc6beb979878c4f5eda7359de79cf5c961b992bb78bb34bd256ac3e3b751fa47d56bf9b322a4fdf34444b72927130a65d45cd604b5da937cc2d0085692e7961a2a1636ae84749ea35f22eddc65e91d0d946dc51efd561ceb9a3175a8a85798c0e987dfb8c81fd2fb7880680fe8a0a728d549cd784a78253bb332923584fc7bb067f1275944abf57d95492d54d17f4159ad75ebcc408f9b902b92109f595a4c1e2f927072dc4768af1a16651e504756c1d501b1ab0aa3a6acfe3f8531817669ce5b9a9883b3f0570fb5e26911184828e7e807345fef3c0a5ebc9ba66a43254d8fee287bf22740c60f4b11e6dd35490b78a6b9987df9061a908eca49851ba751448614e4ad4ff03e8536bf926c4f5a71189318a9c5712e369bb871aad15373da220c5592da4156878c45e62203327e840a23b028999ad16757012500b0380ba8dac35b6be7cb5785a00387c13da7cec1882fcc4ddf35ac2c136808307d1da3787ec0a2250a458b836ccf58c6437b1bdfa00de468112111a208d94d5024536633b12ed3322ee8add822da6541f5c8f3c6939c084baf586208a115fe18eafcd27aa854419005ac0be50cdbca7359567cbef2ee3c2601e30aedce6a8a13d9ba251f759b47a45ad84a3f17d10b190f8a83a158f1a570bc0002471f3fbdf27a73af36449260f9960fa04c6d30451b1c4ee2a1d5c89b78092a4804b9e70fe315cf542b83afd5e9f2aa9eec49a7fae0a152d9665dfe1394362bba0e3eeaf63cfd490318f46fefbf2d3d0d435254fabdf476f99078c1f9058c556811f3e1841d92383d6ddd6c8fff7dbf2c7f59b686789693bbbd63140aed72f0f34522ca0afc463f92e03b1e36be2cc42736b0fd701843b5777b5da5a6e6aae3d3a2094bab90a7c69d93ad806108093e31551bf882febba76846e7733577ac1d2f2cd231def326d966ff06d46de4c54f62d5efa3e972d13e8402adf9ae88ce66bc4dd2c3c12ba59cc581550fe3dec75d36470814ef57a3febcce13f3b421111226ed39cc9051c55e00b8a1ecd283e5a405e45406dc21f8d7692c8eb1245e4a16c3727f8172c70818feab875ecda0719239c047747595be7f7749cebc0bac17c42c06dfab608b29e725d13a78ea83a217bd6d81e3d34bbdec06dbecc90c5ff37789d5bc9c1b49e8de9f5de35de5416529979515446db9484ca7dd1b073f75af5ee922634cf7d1ec2ed2c220da90eecbb38610af41f936c1cc8dd5a1e8d848facc8ebc36f354a11922a2184fb71b47135bbf25877f9a2aeb9647aa1cecc3ff528055225560ecd03da9689d7450c6f72b68718ae35e977cbc97550421e1309ee7199a2d4cb444b54d6e8919520dbd2f240a297d45e5d9c1e0c3d0912e6fd31ba826c2fe1321be0d01d6699342fcea30f2feadf9a6930f41f6855f09c318715e2249370c35fd8fb58fea764b76586d966728034ee55f77d2339d880ac8037aca740cf66ff041940935754765b5870a1ce50f54a1d4786a21598b7f0f206e30879a870f16cc7fb0cb74561f442c1745aa0550ad72786e2070fe9f2fe988788014a073baa27be83ba09d35eb5acd4de908405722155237155e1174e76d72f1d907c161b0fa8871b2499c1f6a1877531d6e04565e0650aed3241011d1c57d68432c3a1e3755d52614ef6026a18f8e3017c5035002d39d1efcc25c83672b0247f407dd344fef8aba141a7d4a7e5a8dcb043e72eaa58899c25037fa6d723318f94d2d53522fc061968e0101e8fa6cdb1aa69da9100defe4f34b98c490fe7c151cf314ad3686481defbfc327013036a62653507110de0b9b2361e7cbe7624acc9a7a7ea44cfa6365cd8c2668d959efcb79b5f75f7e61a9c5e5ef8ba7ac33cc15a2be1dbac019ec6b73a77e7ae23b1ad35aef4206fce15104b2a30b8c61a959ececf1b673a8aedad41a5d7bcfa414be0a6d68fbe9102a4d2bb27f2ada01a2f9bf0dd35eaf4ae5f5f3ddc7cf8ee1a757ad7aff72fc55b25fd04d756434aef095fe33c25219015b8c61a53e9b514d4052d1cc645b539d4866faa41253d64f10f0d63de143bb6465c6b0d97de398028a06faa626ab613995bdd54c8c1167ababe6e9ae5284ebd85959349cad3793d7b5543656de97231570f6727177d107b2bbfda87511dde128cacb508718dedef6e337a7cf6f6a637eb7e80463961c835a9f53fbb713544d50675f52012b7955c20e1075f076d6cd1294087e09ce936935aacabe2a9113f61bc625da8e00188dd9c39b330409dd71a61ff5fcd9667e913bb3a3b7c8ae203d6ae2c71e2d66cb242a90bd5d29e88ac0d7747ad5902f713ff97988b1b9c394834622fb2a620046fd04d23b1e83b12c3392c1815c729d132e45ee6b4e7ab16e6639ddf01647480cd4243825d34f19aea388bb3eff0b4ecb912dfb8cbfd52be3830ba0ec54c8d62535f2c9800e414cbfde851684df5c0b7d4f6e43b004d0ad0bfa8e6637711cf5f1ec3e1802e55e0c82905d011c9d701617e86c28b889708c878453a1cb262e842b457138d3c83a8f7ce497f665f080c77c19d00bc0180805ebd889211ce1aab05d098aa5396088aac0c4148bb8d6809ad7c08f9a85a25e5fed5a0e9ad904e2206eeb2982be521ea794faf61114b533fbf86055a7532f8689f43a1b5f7594a662d2f4657b5a057698d4408108fcb207ac06f98c66bb614225b35d11b094a88cfc18199c1d32fd260da0161cc5cee97d97968ed362a27b8f72ff043078f527242d7ff3c6f8acc422d650c3e107f2f1c24e3d1204f787dbcb229982398f9b79324253f8e456d1fd93de064445a95aa814960bdc297e4928b821ca030e25e669fe204a05ce4f99a108b745f142040e1d311a921988ce7ac438d5ab7f273561c971e3bf3e41a024af194c85ee37c91e86a08ea5e56020bb12953ad019b66f6940d9caf3b0ca1dc10765ad8baa6b40eae684f02cabfe642b9fc6fe8573d94bef08d977d794f4f8da58a24473306066cf045d85ad617a0297dab9418e45a293e630fc94fc501c0db234bc512a62d9b6d3abe0de0629c56e96572d293edb9dd6b620d2cfb1b868eca8483a7d6e233a6c051680098f5a5b14733715e517a27329fbd0196be0eeb086474768aebdfbd17f312d765aca55b7fac96b2aacc8c3268881690843d51b1fa13397d76b110ea04aef5ca95aba9851042944f717d65900f4746a83d912f11fb65ca7f6eb4112f18d578ae61e228ea6dea733676a573918bb7b276acdf92b5ac3514f6f8829783c015145aa1faa12fa90419cef70952f32ea9438153714c0dbcd60fa9b62fa21c3a70efe1a91a5260a16583a16fbf2d2eacbe1a90954127275f39a2d9d29e9f18f3abdf52515aa2809aefa259bee2fcc1efb21a5cf6adbeb5a2c693f2e96f77e14aaec1ade0d87c85e1d988dce7cbaf48311d379978a921c18e959bcb536ee668e0001838e1fada959a7e588dc1dc6e987232e0051364a64fbde96488dbf912d4882c58145a4b207d18acfcb0e6a07eeaeb92ff710b41321de586713042e47e61afe4dd866f37ef093627392e15a8eeecd07060320afc0ede294e1bb464d631acef72fc88deb071e343dddbcddfaeebec595e8d2882f40911fbf1fe0689c25300b855d83800aa81cc75d38a0597af8e9df4d15dead3992b8e45e905e150ffd0a65397be5571f4936e477b1b7e20fe1691edecd62c740feea1c3ce68852ccf31165e48aa151d8afad161a19df9403342be46a55c7e03c90200623455ad055150e34462b86c7a90f1506e2aaa6af166b96997cef2d6cfbdedce9f961bef5f6aa6132d8cd36939c524534cc3f7cd4bf959bcd88125e5d6b41d1c4e41dbd26d9549d3993e0c420f408d7d3996780ca325335a93c22928636bf52414211b4c007647dc5598e962acd8f371a2cfc78723dee1262bcea695d21a4015550c0e3a077e6cdd5481b207396f485d46e762a0b363b71589cd79275a2cb47eee393bce76ac85a387b9c62cbe6ede1451dee8acbd1de86366e5540cf7dc241a8004982620992e42f5d464d4c5563917eb48b897246f8277433f1204b1ac1b51f8ea022bc771c04a993e7dc0ca7a5a83bd49d558486b37ba927b5e7934734380d2d7011e6c9b1941af18795c9b8cb007246cfed64d1b466c45d944d47dc9bbff85ef3aad5a210eb057a159d8bc81fe3bb13dc7a36fbcc348ea24aec70e4da5f3cf7d05fc56ee3399e8437e8386fb31cb5df9c2f9a8518a90623d17e77ab1bc14f4fd3d7750d001ed45908d58e14a7a52fcda0e697c15134df99d0d206b00eedd906573ee2afe27e627543d01efa92d253658cd33aedb3f4c5ab7541d4461b70095697b6b0db64f7d0079fb93d74f25c8e61dc3e0095432bfa779681961e8029dbd7d50cfbdb8cc70900700d82577520470b0034c107c6120a00ab16ac3b535b2a8f6441889a0f3577801e763b80c680c894f7085a8bb7c7e670e934fdf7d1719052100080c553985d0aca8c8916ad5a8f4341cdbad0321652c8b336a53c5a81323b82c64eb27e3a2276ae24ce0d73a156a7c213425491ea4e769f29b2d449b097ad15e52577d50cbd602d3b7b5b0d89a454c4b107b77c61e97ec14badd2e22e1b5a305a7ce3f67eee6878a5d8d2b041b06e8e5d0edab059235fe37dca25117e645059f80490e05586c041c5afef1fda32d73f9578ec2c4213efa181955e4380c8c0f96751584d46066f342e98e01d8f696e41dad4df86cb6141aac71d53a1fc0d689c5fea91cea6ccf8757b5c6b38dd59dd728dbe4450064e95a8336dc45b27add930b9acbbd7dec3b6442a04b16147ddf644b3f504cefbf222aaa56e0d8d85c7ad195db782446c6f11ddee7cca6af045e572e8a41a6d13379f042fdce7870e883b20b59a43a2eac6e6cfcfe333f8584dabf2753139442cb6001986137dcf679cd4bb2e323f92c9d741add2364a9d0c49ca684eefe312179cdca37994ee6d13f94469d3dfd06018d2042779049cefec31026bb2d203d98743f2cde7969998e6c02e5f2e60b1f3333a9078836470453b27b1ea02eeaf9bcb295dd2a4a82f3fb85d85f226e7dc416d8b75fd2444c9f2503263b40dffccd1b81598b9e8c10c9513ec5f08a04af7fcd14e29dc0c8d8994011424a712485168cc0ea4015ba7bbab2d730ce6ce0bdc52643b02e775370a98315bab95cb84e5765f524941fa0421413d8c06ecbd67e6e670db81e44143caea7843674bdf41e996145b90c771592ba1843a23ddeb73533520f8b55408b54b31259f745eae35ecd97ed0c02b815b6cf8b8ab22510cfd096f1ccd9dc2dc387f72ee12df4af9ed774c4d34a209dbeb931fbf47da6c76963b9159fcc8904fd06478ffbd2a753a3d295b5af71c9074e7c419a544349c03f0ed837f21f7e5d0807aa50925b2ec605434e0b68b073428356a31f8de148fcb58f282133dcba81a2d9d6600adcc15d986a662a9dd240a22e33b348ef04183e82d86574c9c63f9db7fd8bf0c3ac8b1b68a4b5c2e91ffb3b9812f5be4f3cac3fa10ece617e2f7b0cfb7275424fa468fe0bd4d477f544c49818a8f4c94acf391c37e1147693a6fd4ab9ffdcec9fefdfccf68053888c1c719eed6951eb937af4014787dc988053a8f740b311ab53c3e26e53d55d89f3ec621e968a02d49e04baaef3b7553020514d07d38c82c6a3f9b07011dceb844bed672dc279b25fe293077ef034f8f172617f1db91fdf491ac508a052708a40089eb554fdc5668e7806b4e9ef67d66684c9e5fde35387db480b35b2f7de72ef2d654a328e0bae0b2d0b2f1fdecb5d9a36a52e541466c7d47b794012670f888a44cf000f48e4800460d14b09e3292c9a4d69adb5d65a277596efe0a494524af9dbb7fced3f39d560123a03ac8a0510c1f60f174b412e965ed285c94716c43433c962a0e5faa2ffbab3e89a645eb0d9246b6c928532a4cf253c9a11727a53cc24345f4c8fa3536342de14e628012326e4dad7a931a76bfa424c7f32bd0e8c9890ffa448f4a5d0f4b6f4a6d0ae6e84563e710619ce2619f637cd4c414c55949ef42dba32a4eedb73d27f235f311f28fd07a8e391e8bbf422293a11dd19f6fb4a40c6d84b8104c494441aa6a317853eba26586e9c4f66d87cc200c72520d285bf7c028b4211fc75164d5c92c271e31097b0c4269ff96229f52020eb2d073fafeb2bb507c356ab954d2efab55f86da09aea1632eccc9366acbefd077c8032a83cd1e50bfcbcfc7e7c40734fffbbda02029e40f2df0f0f1e373c245cf1e900784fd3d2077f1200f28e8c55b3ed983acb77cd86c92358b65929982802123c90a6a6e998b1721d6d2c13929a594522aeb9c946ef2b95aad6dd95cf11e2e6ee18dbfe1e2289ffb2c87b81f5de7e61e6f8437f26fdc70b3dd270a7be3a673dc253b10f67720bfe1ae33d4dbd08de6643299fbdfb878e3f4e274c357fca5bc990d36f76bf3dbc6094fdba1bcd3dba9954337a8bfc02ba8c4b07bae1cf0bfff91ff854a48db350ffc3329ed2ac3b7652e76909fb7fb0b735ae62d3e83c2ce16c0f5dda4f75ce8bd76bd7b7cf2f66cd6331745efda756bd6b767b266cd95aeb7816441248c7f940856feb7820a2b60ed431da46c6183c906ec3fa32dbb7268332cc10c3ab804cb2598a185bfad456b33d9c034de21334817deb2f6c1bf0e960a2b607d80f9f39afa9a6c205df8dfa17a874c2d53142df3ba7a55ba0d56b6e40fbda206d265451cbebb02f6daa5f70ead80adf059e1b302b6c267056c850ff617ad18922e5a9657c07ad6433eb2e40f948a44433426820bba6fbee152015279a904a998644c8b568b20f943b78842ba98a290a2a9656ab54c2d16cb349b0d8d3a1d345f70605348b24c3831aef92263547ce40fcd9a2f34468e75b0b9657d0016c81f240c6c36b5583e269709c8f43205c91ffa4fba457d67845835ee1fc271ab8c3ed6804758fe900109705619e737ce9fce87bf51c5a522a4e252c9428b968aab45ab45ab45cbeb19079b3d570b580bd87c3999f13d4e8cd0501ca44bcba4186b216b313b430b513f08bee8de9cf48be0df887ef41290317f837a9c9887d177460232c6de8c6e46993ec3d062644c083de92f62ae78df1909c89819f746c615bd8c39d144f79ecc20758ce8fe70a002a2ff9e46e9ed6b6f45ffdd9b8e117de97162b20ceaff7470abe8b84bbe432aa3caa892833378734e77680cd8ffd2c15d524efa03c3f17babfdfcfe6f148e334ef7d291f41d43b2ffbdbd5487021d63bf63ec6b2103e63da1dfb371c42dc389f95454c03f3d0546ff5d1cdf8ffe7471fcd098384632e6142231633677c5b9653eea7c0fe3dd6d19156cc83d99a67b322f0df0bf7bf333ffa66577746fbcf53831f243303c993f7a9c989b93093e8defc11fdd1bf0f6cd07d2bf6bb89e4b766597c5ac050f8bd97c01dfbf050c4090c54cc46236623123b198b19891b85b3918d86ed162f10a650c8b20163077d1a6106241058bd87cb12c643c36e3e04d248436e76b3c76fe2672c07c4d25c7453f9981a715ac8a8e8ae79ad973b160b1e0992f2714f870b07ab813ee02c4a2c5c267eab0e0fd39e97154196331d96c88c5c842c7e5027a05c184522a636a4ce9a458299e54ca47fed076c5d00ad88a3848175f81bc43f3e5bb6f5956c046b58aacbd43fed35973b0d973b5f06911d4a2355bb85ab43c18bf33e9c2092b6ffec618f6f75cf3e5939ecb73792ed1d49a2bae995a2a2e97e935575a2673d13b48cfb2c9cb0556e293d6691d2e9a5aa6d67c6999666ad56ed97575505007793bd8ff02d5d70dba30ecdd156a99c9cb5d4c4c7eb42c0b3db07f07e92a5a56aba84375f6f50f9d4e68be7cefefedc8179531365f545c5e0db0670f06d8bd15e8702d536999e7faae898a6bbe98f064538ba5934d2d151776534b656c4d65a42a2376a932ca7e696a95f428f1912edc04028ffb5217e56d01ab2d9c4d5eadebca2d60d35bc0dc25778b29ee49bf54f1703a8f3145ec95f343f20f86bbcca7a4ab52cd86e12eb95f9571f077b3a482f4fd94f492c323299f529a034f297ad27fa42b4319c34d490fe33744ff7d2b0e8b1ec649a450e43f5c74958bfe017dd7835cec0fe9df170e05e9c22f0c7729a40bffeff58571e6fd5af86d5a8ce93cb009934f4542347d2d60620a7382cd2ad50bff1856deee7e1df7d77c1980014239fbbf6f911025d1103e7ce02f283716dd574d8104e45ca10f0e21baa41f3dccc474746548174b6110f6c288545058558b40f985dff74306ad8be50f28c2e0fe9a2ff445a5e8036c51a8e68bbfe84c7fa657befc455f2f3cc61664439ebe2a85827471a261fa9b36832b26e4c3d7cbbfce5755c910d20389a9540310897e14669cd19cf706884956f4d44a212cf25e14766f0aeb5cf986e8f03704f7df950f333f0fac5544812dc6f475b2fa287b00cb2a9280f655244417f698be86dba540d4455f34c874dde5ffa2afc279be60b40fd50cfbbf88c12dd139383790bbfc85fef015071d08cf17b784cdfec21e445f78be5ef34561303a058d5937e1f1859b5b1bf59bfbea79d73ab7c261eeb41571a26f389dec7c49b9ff560442e9cd9d0d064a3591f0f452349fd6a753d3b4a95d8d52ed29ccd4425ae90786de9de1e9f422dfb1d3494488d3b781920a20f7733e852260681fe684f1ff3ebcffb5f7a43c0f61cfc8067eca5dbc91116d885631671e2426a3318afadc404c19756b1ca35ebb734455327a9297f225e5330f4f4f2aed744b2ef82828a7d75e06ca3b4ac9a38cae0d108f1e057c121e6ecdc4a3cfe0cffa148fae4cc95312d493dc9af9f31b0c255706f594de06c3097cd495a9f536181a0ced83f623a1f75a28f2517a1a29791a72e0846546bee43f0af2109a6e4f88f2dfcd274cb510f52912f8bf4f4542a0e88730f3d34092507b53c80345691f81fffb304eab8b2329ff2829977e1b880a251e094b9e24447d4a18be142da0c414f6842f4542a03e9fa4af8c3c2aac2e8e7c1882be32f22d1aa2e447fe4314fa222361e79578df8988bc140921d2d8fbcef31ec6bd2f957e337913c99b4e7ff222d57bc150bd88b16d1b0637d4cfd74e503ff2b5e465c9678bc113d41d79edc11fb101969c50da08784f466e037030ea6a5fd29d7ee4f435ccb56edb29d7dfeab571d24e277c3a611ebe13f14844444c246f2231511293497b5a4d261293c9a4559347a989e99a98bc2934b9b9b1e92535514a3f24ac696c323961fbd23d6180f7f3bd6dfb92e67d69fb92f7a5d26f230f8661b681ebbc2e523a4b4a2ec9d7477d4a287d05754f0f765f43d2939c7e24b469ac39c0fbd2976ede5ed34a61de5efbfa279c4ff4b50ac4562cf2f944afccf6dee9da38e1ed96beb3f2843b1bb83b79de77a10c223cef84e7e71a5ce5cd9a8c28acb700227e8215bc92011557ef3117f62783889794efbe82fef2df752f7ce5dd45556fa468200ffe6d88c5b00a964fc47862302c9ff0020b964f78810786992f17a0ff91be97a99c9fedbfefeeeefe42253ee687d2f7bccf80fcfe0ec6451957a63f8823bcfa9d03e32d32bc85fb2084909872ffe2e5fb7ed47c993121f759f502c6a588029fac027b8b8e902efca1b0dacfbfde1400ff7b4e1673c3c962c0f798bedd85a19238abec5c71f108ef3a60798f68efae70ff841880b088e5134066f80931f860f98417602eb07c02c80ff01117902f2a201e1e34410641a0421531fe2d720007a47bfa3d0ebe819bf3c20ac43e014407f873b06b19d2ef6a26ae1cbda9f9a9607c57e5358ef081fd33208304d9ac52cd970c04c17e4490cdf28542a1f4f8ad402847e6fc6ca96e4d6b4d6b4debd638ff6decb1edecb1bdad93c04a517fcbbd7af89ba07775becf495ddbf0c781db57418ee2af03ebc49f07761fe87d5ef78daabbb8942e6458433a9b7a8194a3c4c76ccfc5aacb5b3e0e0a9babcbb2a181dc8506ae2a6449871144c1032870964372b0810b0b5856a1cda0091f1401cb590e2fc0c6136019e4a6e51a4780a58ba0cbaa9f8673f118472c5d14adfaca8c5e629aef0e75c0dc900531cd1dea80b3aa0e36cbd828e3e0d19d999939c245d19555e0be920eb85f3bc1275fca3f7d2c2c2ca228a652a9ff47414141a150a7d3c95a0b8260ad953ea5ef7735af8cdf953f4dcb9ff3330e9e7746d63a9fc55d64e6955935ee617151f4ae28a6ba9b4a7dbdff28dc4541416d17e522eaf4a3dd938b276b2d0882b5564abda51f47121d43bd6502f15d1cd25be6d32ba3d282f07172b0f2c71c5898a6f1cd2a9b14bca2c1c1fd62e92385dbe679617fae7119f3913e52ad5bdd6444cfe1c0f1237ae92ddc7b8d7bbcb00b371cf6654fe9a568015d22d538feb8eb852292e86e1ed824e92df5738cee8f8d8799a550c6d8f0477e377b610fe9b727853a1f43722048f786f43946dbf7e7edabf69b8c19fd0cc5dcddde64bbd535197c5f0d25fe487466e5fd4a7b4983833599ee6b17ae5a8403c74ff79eb7d5b047e48599624ffb1be92dde8b5ea3a25cd3f8b377b530539d0742746fbabf117d0ef0a5b764edb9c63a1f73f3a37d8eefc1fb6363be76bbfe2abd856e57668504ce2413ed4e203babc24729690c5c0806cbcc473b0dfaf369e84173c555a9d9039bff53b139d4590ef6074f76863d36576473c284ac7daa3db5f382d5155e5b7d6cddc163076b63f60b5608e6335fa4cbb8a10a0bf2a93c74b6f9e093a91c4e1d2ecec9e94817b37b18af3e7872b3f9d2b57ce69cb7bba8d75c41055958b630200b83510b23a182244622847aa166b08fbd5033fb2364d12686d420459758d82957a7b06115eaae30175da8de2a34c54b17ee1586615348e5c345c71c9074a16df23b9d1b8e0b874efaebe3c474e349df9308704f9f06f7f4eb9555a1999c2b5c85c95bd2d9912e7cbba571caf96287e6ca7c298d32c65576c856987dcd9536d82c6217594a5c0f55e7886a6002fbb3bc9851bf5f248494fed30a3c58a4e8a24aaab69153892ca2c8a2daa83855ed238ae2bb7295626f3dce9ec00651ca3a5f38a09304311a867119e82dee4a68bf6d2dfe528a3a0d2e29c319fa425017c191942ee4f7bcaa23a0a18a931eee65ccf6fdcd8572ae586ba72741a775a081d520187a31eb7d7fae7d6d6d1ddb755d4ef516c7dee785d6458fb31df7399835ec0941b5064f28942064d0a861a3a568dedaac2e839538b70e09e87862619f956673c569d7755dd77573964a43e3d40919b38d95aa70172f8250880e8c006c00dcb8bf349b2f21a3273f64b42163f7e31900774f82815bb66c2965f7de0d19437442720c803b1858a6bb213a3724c75d0c205f1010e308c052dad80070c75670d7b0047245aa2008172c11840b68205d485c225f6c6caeb801f0133687b84b2ecd74dc2577ae901c77f9101dd857d0a0340b9941134cc8200630903fc893cff59666e12c0c439678810b76b480052bb8a154410a50a0e30426d83909434aa004097292188108e40f52fe204346d12ca4ca9b6dc80ea44b75719c2f27efff05cd97fbfed6a70f50f2fe5607f20793f7b7aef9b2e2bd07d8bf9b47349b2f5e454376a41304c68460f385566b51a87f51547de30f17b4b00f58fed82134e3e4d4ed08c2f9d3f976e47c3ab0a3fc8af0517fc3d0a76a2e1efb721ff791cd978dca485436a2328fca24959d4440f371170b242d90e6b30d69ae31863b9153d7b94ab36f0ca956546d28610f1f86298f0ae57fc843c85847ecdfb1e68be6f28e6571ee58acd2ccc6bcd77cb1169b36a08acadb90743102e4a28ffcc8b53e5c0c19ebe9668b43ae0b0da5d91aeacb6f9c2b6e817011d207304b2d581f29a0a8075006617937a0f922ca15f04d37d7d2cdd60289debe46f7355f52ae80d687bb78fe16c85de4f54709658c94e2f752e4fd47dbbbf093313d62cfded7e3cb7151e71bbff1d4e194380f6708c253024e63e5d44082e39e60e5d7e0900881109e2f655fc30612d407975ab8521f2cff086903233e25b2185103ea638494955ab86bd4c066f99a410410dcfbc34caa6974feeb5367e05e4a2925f760ca577a6ad8d058de8faff4c36bda58c7ea645320fa4302c15e6307685559ada21b3b1d3b6a903ad4e574ac6e47c7130b3223c92cccd618acc6443a221ac483e9670d28086e1749dfe5a2132ece6810e681e5670d28a601c962660002248805ed0cc5350664b306a401693efce54ba33bc7852fe747b6d482266c4ee12defd7136cd338a05c86d5d569b0b702b9b6393a61c0bcf906cf6b5df3a5639e6045b219ae02bbf7c25e83b014d85f569d90c25227b44f1a4a6ce22e5bae2eeb2e147bbfe38c03f79d1982c3f21dd061791b9bc1c7dbf948316053d8c1711cc7b5e60b02468ee3385815d85b095280713f388ee3b8d16844aa5c8bd4f23916f601b93200c1fe1c0705c9b5886033c7e258eeb283f4da78c0cdb61a4834f7f57348817b0a2c946160ed85fbe6076e1c4170fbc03d6bcc1ff8c6109e2f652e65b8860d245ada930c891f65e0d1282d5c6517d1b2f2b31432e253228b11355e26399d228c903294d606b30521ab0c225cac41030b62b73041c820c29efcc5c6a9c6cb6afcbf0c46845156a30a194b4afc37b8cbd4686f1ba5dc3da16c8ff5cf76e67cb11c24bcc55fd630e7677efde92c39a32fd6dcd8e4bc36e46c16bb114404123219f6afa103f67f618a6bcce41f3103db9f652c0373ceab7a3144065cf4171bcb50ceb0385f641c9181997c6118ffdcca709188a6f2cea081441336cba0d9c9889edf28fe52e32b8e222f12a2288a52ca992c0112526a2f5c74962b8ac1e68a639d1764ae7ee5c653de93f9b80b960c39f2a98b953e818e410af9a2305824389b4545a528ab13441815c5c003fbb3d0d7446fd1a2b0fe5994458852f6cce214a914e58dbbe740ca568ff630ee3fa59cdaa5be82449dd5482055607f4a654c8bba799aca15f9283a29dcdd9aee7650017961ff173166f7cfcab5f6628ba95cc7548e14cbfdf4c584e12edd2ad58b130dc6d4682b0740b6208f3f0c5360ff140bf65fcd5f80e3793b9c72b0ffac2250e1ff5f395081818afe8d86a892e9dfc9157a61a8daaa5ecc39d8acaa2a95aafa6842add4e711be8fbe36bfc3eaaa406db0df4f68b4e7379ed17075917c905e2420db9a2bb35b932e5fb80271a222b618eedee48871e1fa852096f3018fb7b480ac7f6e2cd8cac4175c3d44c5edea25b25863436d3ba456b0fefe1d4462b94b168da4116bb483f4c2fe241225663488442291482d5b7e26915af3a54bd022f938e12e2f92142c1feca41ed849241289446ad9b24923232324720261528bd422f99080e68b16c3c9a41624861796cf05ecafb9e48b66059197af09693e9a0ea417246112464b2963be90bc7cd1b511212417c45f361fbee20f82a7130a4a2ac5c2f2e2458c18189c3157fc6bb556e3610e793a415e90fb00693af385d6d77474349d1f1a6cc67cd9b89b553448defc41221a448370b5a892847141ae231bfa1e26af0ecf3104dc0f2386ea85c8f229148a3df9c69a2f5e905cf147a1423696c983827cf166a82f6d2c941764b920679e1546aca0f9f2592b1a3919f66f26ea97f3fd3d9df9f2b93e5047c7e5e9a0ec3629a9c5fac1079b2f2418e98361d207fb2c1a7f206f26f9905afe99d4c2217d90520478037245669c24f0ed805c913827c06901eeff5c9feb7351d67c712157a48402962fa14021c0b660c962215726803b5b00f77b33f766de4c8600f76b58be53925788a318819463c157bbe6135cb2698bb6e64b69467d9c701789a57017a90427b4b0d31ed8291076fa03679ae914d8658b84909212c166daeae1a27f2efcf9481739761bf23010c8cab65d07c3388c531eeae34cd0562c07fb531eb4076582cdce435b97b65c365b10f4e654a0f2962b58ff6907abf202d0cb031256bb2005f6074fda3f46a16aeda7d13dd3dd61113368d4bef209ecee2b72c56f11335cf4193536b920b94005f6a7e00b0916536b1c3715557c3bcd276fb62a2a5ec4e81f07e0b0822a6bad6aba6aa052a9604fe89c1f4ec67ab687f1960c03f7778d86e976415f7118be0526b07f0c8ae976ab8f7d182814aae9852167cf173262ff3ca0eefbe694d35a2b0a255fe401bd8bae07147a2fcf47bd9e0f17ddeb1679405e3fbe6d5bad94fac88808f5f7dfc2c7cdf2419978b3789890f827419acf35abe54090b8c8cf6f560fad246c96a34846469ad52c12911111919111916635ab59cd0298c959c060942fe5f69bd692ca9dd68bbeb8f1ebce0853ed38a7e58679cf3bc725b817a69aa6d9ef43423ee4eb8e0577b698e9eba909db84e5baba434b23fa1a69a52f799e7667bc0749efad53486e5613b67edc73a5127d8d7ed43bd95ba49d3a7a96441ad5262c051f0435cd6b964ac6b6186b678b71af52975e5fcd814c65cdd3364db3dab7f632dfcbda8415cd98475f9a5747cbbd36f226ac2d7d496bd9d2cd9bcbd61dab692d526bc79b59ad25adfdba93658c34929ef49ae3f4b4d1cd2aecbd97b556cf98483463b95f9ee7eeeeeeeeeedeb9bbbbbbbb7b13f635b9d7ac7eadf78533f7da348dd616298acf56265869df7efd612d1436ab7e18e15f843f0dff19efa23f1128f5ebfbcbf00fe2e4e2fbc3f8c700c107df1f4615bde8fd5f3c0dfd11cdca5e19fb12d390acfd8c83ed9d99215dd58b0bde1817a6bb3288b8336814614497c0aa6819beb9dd6dbbb565ef7683581dad0b3761a70affb663c4363b62eb9fee03d654dba66d9b0e1f404eb87af8f06831c1b383a56d33db5783afda6066e5786625d3ab8cb36a3cb3a22f7f956211538f823a59900aa1296033f367e6cfcccc481767542ece1735095b93b0fd2a0be2f932d6844f5e9af92bfa34df2f3cff85e5cd7466fef76b76eba84c501aced0a7c9f3fbe7f0c2f36f186104a908b1081a291a337e06112844c840c908e214048c858901c6805161bca02f80309154a4ef962b4b8528949ae2612852a0824e3f2c18a3c2c0d2fa55a9b4cf246bb2266b325993c99a4cd664b226933599acc9644d266b325993c9da50c6be2cfde8b38c0d591616514ca5fe515050a8d3c95a10ac9552294beeeeeeeeeeeeeeeeeeeeeefe4618212aa20890068d6fc60c8f08223a19326a10417030302e925efb18316cc08051e3c5bfc8808bda6bf6aa5cd47e45fa235cd464ecf78490486f4d2692253de9b3cae2511812b60e771151c1020a89df14290ff637eed2498152835035eec2fd38dd1ef9b23662803560d40c3810a617b84daffd110e84e9dea8bca59f255284cf5bdaaf366d86a96cc2366169ee50073c77646cfeb6bd66ffc2fd72f1479014b02984a888019105995531d47418737474ecc0fd1a103e79691ae34faac0b608b2bf5f18c0c0cacfcd6ac1e03b817d3694b4143bd3be3f9362dae791f65994411796fef96b61993dd67c3abfafdc621acca5ff94f25dbaa4dd52f8383958c7da75dfdc65fc25769af91aa52b12f6c7d17a9e2084856908706bf4672863a32500cf39bb35dc5a6710e0e6b132f369e6b6cda9f545425bc286b0b0f0ad1aaf7a6e7ee6dbfff127fd0ffdd1ff682ffa9fedc1ffe1fefb9ffa34389892c23a1285d65bbe96ee502a8a3b6d5603af94e2ccbc524a29e6a838d59df569ff551d9bbbdc8d587b1acad850bc5d893f4ae71c0227045886fb595f6065e8d3d0d526bfa6b1942edc66c561fa33d466e2d50d9e1907d77077352b0aecf6999bf56f9fb758d6602ffa9bf655e75614d87eaa5d8f357b4029a59452ea023bdfbfb22cfd7eb9c3ca1f43304cbf8632dced400aae5c7dffbc3d95b1993873787ee3d6a17373a306091b353270440bec7c9103ba0778fe8f9f4ccda782754de45ddbf6cdeb16b9d3aebb459e3be7d473a79de722ef1cb423ce5df38d823eeaac3b67bb3aeadc27c9eb3aa75ce7b4479be67d54b0ed2d3c6a61ffd1cdf4d594d5fd77b306bb798edc6b9bcdd876b3c3aa7da182a68885b6510150f8642ab378e114ab870f8f16133c3b522c16a5770504ae699c6a4917f3250e014ee9600c2600571458f9f23f11f7f49e689fade4fe613ca75cdadb34ce364c23067f7e4eb9646c34fcddd5f6367d571cd6debb36b3a6e26b3371d69e7ebd186682616312f650d6018bc26c1af1fcca6365b4a7b1b149f540ba98a6118337370b83b1984c369b9986b4101dac3d2707db38ab5c58138169c4dacde0cf9cd281e7d725ac0e77c929564a27c584bbe49e1b3b4af13810a39196dae1408cb496bb647feb15fcbe5abf16133c3c767cb5d6ef4bf1e05a1c139c0fc7c3954c1f52aade4bfc6ddf77ebaf9ea603412ea4e97eb57520f79cf75ff8988639d5c2f3533e3d37a55fa57884dc1b9d8fb17ff3b3da824640faf960aae540d87bf3b36a4c7f7eaa87bb64cd14a698f096d2c56171d82186f4a34fb5bc657e8a87f738743ec6de9b1c1e185e10248298d1eb7c0ce9e6d882461033ba3fda9da1693c7323d24419867087981fff1ffa3fdd4b5c578d6d7ac0e0db344de3999ac6e0dd7ed5187c1fbd3f17ced834e6be2685e6fb15787b68bedb43baa38be387fb9f1ffaf4a67cba9beae122e6c22d6804580b4100861704898066ed9da65878a6b0787d7e12c1b7a2694cd331dc37d319f9e2daffd239a794524a29a594525228beaa0256f7d79dae2298b4ee58d58e9dd7278feffbe6a4f4692823459e47e9d6037e835c3ff8748242ccd5f72bef25ccecb8ff421a1cec551c387ebe97de42df7b2df4a7e1f65f17daa4e08fce74574e1ab6c426dc95d17ebb32daad71137a63d0bff2fcfbca80f527fd444f9f4e4da31dc5cd72179ad1afb62b437a8969a48b94e3bc5f6dd7bb9993f15e628ef4a4dbac1d3c4cb478f8f4703901e4e3f523480ad8144254c480c882ec88e6aca3f6fdf7b9592aefbdcfe0f7791d47eb68e9571d16d45e53e14e51b03fa0af9ec04aecdf1f8bbbe44c9fe545514ca552ff8f82828242a14ea793b51604c15a2ba52e4ef9373f2bfa2df2e5537ab56dc3f1a3d1ef3963787e3f0d7d29a3b130bd34dcafead3481733fd7e4ea6fe68b7a7dc73cf71d9619cc3e6286375c7c63ed3ba3359b99bd57d37bf729cbbbbbbbbbb3b8dcde786b28c511aabb04f54d1484969ad2068ede98442a1a0fca752342c2ef6507dc2764ce89b13832e4e948bf3dfc5f9abc6361aa6dfff69f7e6c052544b60e74f0bc35385b36a3e8b58448ac6cf40210225e31484850163ccd0488a83eb687fcc6186b36ade55f79d91d2c5fc9ad50dd63eab5a00981a51048d1944c8080226068c172a1631f528280c3ab8a2b3ef80b579df2605671cbc4a005ec917a642ac5e9cce57959038239e593daea1b826617170986fd8ac50a20fe119fa80eb085aa7c79b1b2ed620e1a28d1a2ef6cf64c0c5ee17aef6452ce79cd4c747e37866e55806078bb7b449098a6444e414622ae1b0ff23fa1ff07fbefff1fea7fb9ffa3fdcff6cffa3fdcffc9fd1ff90de2605cb67711712495e169350f496d18874c59230e52d73de948be17b4b3f4988e22dfd2321ca5bfa45c293b7f49fc29010f4967e5358bda5bf14da507a4b5f5052af76a0e54e1b8abe46ef5f19155de2fb3a9458db5a624deb06bf1bfcdcdacd0d863a0f04786fbabf013fc7f7dce7fe0deccfe1fdd7ed71416331bd14b797a9af2f5150a7efa5055fae5af4b28e5eaefa29e9e59d59f5a5c1c15ae9fbad763b2444eb97df216f439b144cb25fd398f494241a7d4d63d183a2af690c7ee0d734febcef6b1a7bded734ee6af7358debd3fa358db98dfb9ac6db9bee8c4d0adebea6b1167271fc946e4d636b43492b684fa810e55362c842728d061f0b8b4814c154eafbf750503a14aa9e4edc77370d0e6e2ae3df4352e1d108c78fbff4962c71b3b88b8885c5051445972f9572f1fe5d3a14948a42b970a793b5b767746f40b0d63aba37d45bfc6fe8c87b049fb3b8d82ebad89e72b1fd5d6c4771b11de562fbc9c57677f72be3d2fd330ef6cb22f607e162bf0c1a2ef61b11d219f87374b0fd3e333333333333333333e325f8ea0a6cff0ce9e7e87befbbaf1a89f4190793eecccc48745fb8e8e07763b8e8de8571d1bb1b848b5eb94dbbf4ce6b848bee128a718443132c88251426884d287cdd832c1c6109349288a205b875624c046109dc392060c11684d080738f482042598573bf300793201842607ee71c2f1f404eb87af8f06831c1b383a54327a7473a0c55310b220312a342680a9814413fe42b068c172a1631f528a89305f1b6d528d8af51b0db73cfc9f4e7c0dab70f20275c3d7c78b498e0d9c1d2a193e32ee3cd8d1a246cd4c8c011461441630611328270171903c60b158b987a14d4c982956e6fc2ddedd24c9c0a057bb26d27e00c4fdade13f0c1bad9df505b16f9ad3f8fc81cd87f8627f651e1aab1e949c255e3d28b84abc624ec14734fc3bd4de30a05fb7d7d99ed69360ebcabd3735f92313df8260ebc32a317dd13fb7984b397f436f545eeea746970700d0eaef1de2664a60625537afba589b79fa9b1f6ca98bef4a6db81149c1d6f378fecd754bc92d245e9ca90dede3c7af049b703295866bba36b33b1e8cad034f67e7331d55d99398ac2f0d5f40b7fb2072c43197f1e462c35d0d7a6b17c1c6f077c3225b3bd0d19e3be0ad69c6386bb9baeab356b7306e6c07c83a977e57375b0dc735b774fbacfcd921070bcdd13068023f607477ca2d1214a8ff0157a4f7a096e484231ba3838d88a71b0fc31046b82ad5842710216ee7fc02753df6928dd9a86727bdebff32ba3d9a48432282ff15c75edbec3197fede69e7f94effe503a107f6f7e56fe37ff5a95319a8cf6362918e596bce85115941485fa921213d4a54199983cea4f4a2e4dc9c9c9973ccc2c091ba342894f42894dc29024a42e76af8d8432f66df4804b252cf29f09e941b08adea456c18e5ef491be33bdf721df2dc1d23fbdf7db774f2a799393f7d77a7a20096d7a4890f2ff3d374974cc3f097af8ff91507b0f2130f2da35096b1a9bfc4958d3f8e46b48537f85f23495a6bf9fe4512697c604f534a837f9925066e57f72694e9e87a729791eee0ae5f6fcd5f998941e2e8e9f957ffd1fed71fcacfcca48dcff43f234257fd2d84462d4c9c56d7b921005e5e2f6232106705582a5ef7db6192532434d61062d077ac0f6d66c98fe57ab08945a08aee61dee70073ae091bff7dfdf91ae8c56d3988aae8c067eb7be4cd5eb5d999a2a718f0bdfccf6f3652ac735036ebfed8c49c066baf71e7c70ee54771a284630c3feeebdb7d147b9481fc545facfe2227d958bf461b8483f06fd20887091fe0c17e9d370917e112ed237c2457a9fa374f3ce0552f8c49fa949c13d9725257e0ae5512827949da949995f9352fbd6199bc63205cf4b5d54e93c10dabdf959cdef181acaac1a4b173d0adf7c19daa4e0ae27ec6e8ffda199bf6a3c7f7b9a29676a1c77d7a607dcfd7c2ed4be0b371bea7c8cf5fec6febc9b8ca9de9cd3ab37931eec397b7ede831bc92605cbac44ff7d8f7d1bdacf51da6a570a7fbe9bc11f91be863d3a1f636f8fbd373ff57f68442f5decb41f8534a2ffbe86abc6a22b033e784dbc2b53bfbb32b505df7b5fbb60b72b936d1ad368da8f3eaf1c6f7945b1e8f3aa62f0f3cae2ef6946d7c64522d1b5a1daaf40ed41f0da54ac5d1af057dfa5015f7b19ed4adcd1745e48e3fd8ac61b651c0cde997a69eaafb4a7a934dcafb42bb3bdc434dd73b926e3c0f4bdeee61b19076f77a65ee922b7dd7c83b55be3385e4f19b0646cc61cc67ab95aaf71361bd2464d47e381c1e7dff4a5c42753d25d661e5797bd5508b6ce5f4035cdb0cc36344dd3346d4693f46582afbacbc91000a8d9f00224ee577da81996da2753527eff819e7b7bfb8ee845a3d18f44a32b63aaf6f6cd35ee8c62afde999dcff1c6e8b6c584f04997edef01358d2c16ebc5f7f477e1cf12000050f1e55479395bb048bd9c37fce99f321d6507864ffea4042e6cf226254e32fdd4afb5e47cb1728e444f5ff3a582727a9dfc4c452fec2f801740bb78172ccf12800f00001e002bbf22be187eb8c53ee5537af81e787839514abe641b512322a7900f11bd4889fa55e364b33934eab4e6cbe7e302f220d5ab5cd8e55d66d8e55d6e96b12e082624eb4615ceddd803ebff2eebdff22d3753d68b7f71f38c15e00b70f37411e00970f31c07f003b8d961aa57ddecad6eccdd68049b45b507567e16d5262c0966d887f7e1666f09e0056002955711c0cd94159361f92e6e9eb21996cf72f39c0d61f901b8790ed111cb07c0cd7494bf7233d5116f9e2e959be7d8e2e6a9c3e2e6c99a3c587eeae6c9335b58fe8a9b676bfa60f9f7e6e913deecb0d87cf1d6dfec3eeec2f2536e76970361f93ddcec403cdcec2f949b3da8e44b4c30e2933f711d163679939b65ac84fa8a7cd4cd1d04c3f2496e6e98fc919b5b48e4e68e4959c8cdcdd25af3e5085f912f2bdd2c6772480e8d3d8e24160549e9d197e8b240b0357763ee463c7ff69bc6964e49e2ab4510898660bdfe580982ff85d507967beefbfab5fbce87f5edbf70be1766199be1adb58359c7fad5719ee3ced71db9d32ffaae2298550416efd0a7a39125bddd99a3f79b55736774eb08ee88beeee47e89c09dffbece5f75cc5a4b83693e6a91129f4c65afa21755fbddac40d6fbddab0fac369a3104ebef320c2b7dcd3eedbd5b8760b7cfdeca32567fcce1d5d5efbe8edfa5b4ab61ffd7137c61faf561bc5e0b03a6567a339da94fa5fb08cfe7ae8c0d19bbdb95b1e12d3c5f0be9d7dc17bed59cee1ecef8d3c8c699dd25888daed60ef7d3f532e7eb65c2a65096b1edfbbef98ddf95eecd5173b9bb66ac9e60c44e593157e58177a5a49c6b75465f15f6a2333ae358e0e6da5c9a732c8ec5b138d60ec762b176327d919e04db4687bde9661954ba1acc5e0da6c1b4acc1a893b8d94e85bda77595dbb49e4d276c17d22328c6febe5ba5e33ca2460f8d73ced9affb13622a59d2d6b4455d339587989a35553fb02ccfd5c1583ee7cddb2c86e73624c3931b6793d3199a1ff3d60f382a7cb967dfe766755b6caef0ccf09c433ea30b4f9dd1ce9ddcaff9f5bbb97764ac591a65cd66d3d5930756bb1c6b73c32753798b619724fbf2929ebbb4e32e7d3a42f2f48e3c47f2b2a5b5da476bb54b6b918c16f5f429ea69a9c43db7e3c9267992917184e44948eace48f223a847ddacda5c1b907da1821e3637d74ec893987e8413f993c83d393599ec5b922b6f2e52e94b37abb0acfdea57bfa6ef8ce05bff9e4445b31705bfee3bdfe9bcbe37330cfb4205fd4ebf362d46d2a71f33abea38f688c85647cb923119933119dbd154738a7c1d6d96b3f933689e6ea6b057c8cd5428c874338dc14ad3d61dbb33bab9674e6feed73d758de293a94c67d8b9ed372a5fbec9a37ee44f5f77423ed3d78e7deee69eed887e63713bf49bc4c232448e26f975b43cb0b3f2c0969e14f275fc58f5b537ddac0af9fe17caa5301f4b6ea642ae4363ce12b999ca9c6727e492fc66caea59cf6e9e31dc3ff2ebddf4a439167cb5278cf14879f5f0d0e27132f6a0623c465e3da7160f530f29c643f4eaf95a3ca4ff945f7958bfa716d6ba8e72ef7961632e5c9168cfbb4aa194cb3798ab1c9d9376da77e18a446d28eedb3fe7e4b85ecd1ebb7d26c5442f1eddd8b3c578f4d853cb072d5a3948d5af3c6c4e8d725835eee836431b0dd3b4765709c0fd12f7dc4280b72c635c6ac474d5530bb3b7b036675f79f3ec97f5bbc6da2a0577dfeedeb61eb645ab6bad0b3bd0810e7c344ddbb4568137c102189eaff5f0e1d1929887656f0e01b63f4a00ae3d767473e3d478e27dfd9a039648bbab6e306c4cf2bb2abd8d29e4bfd37ff7c47b2fdb488d78f4f34fa1cdc4d9bef621a1cd5c7138058fc2c65a38f117e666b162e00eb38c89c2dc72a077d5f8036fa6bfe2346e9bff8536da2a65366b89d488b78d7b0e0d31ac5134040932c6b016850c924123f8e0cd2c6649c0702a8635162c3c82940b6bde4a6d3f73b37ad8d661e1a9c35d241eb9373f2b924c49b4eb3a1e3dbca73f42590ec408e5a125243c22bfda41328e2434ccd1b131223f424287718c51c2c688e410b172c651db4c6aa0c338d65ab78d8e23d6421cac9c711499f08cecd05af4359646ebb66db56e2d2678463b36d14b5c6bdd36d1d7f0452d267cdcc5e341a1e807ab74a854ed34b6492b199a01000000088314003040181009c662c170481535b53c14800c8ba04e7a549da95912a4945286006288880000000000004198a000affe97aaa409509dc7b0d1a8722faff7c300feab298277b653ab8a107c0dea0a794c6079a4570f4d478ee1ddd3d64b76dcd561009cf843e866b91f2832c180a99617978ca918016d371521855726d91539074a3f221e68ab54edbc03eda04191268aeff03dea1f46bb44829c1aa7636e955447ffb1e9d5a502963be16179874e0206d2045c9507aca3c555c98d614fcbde4ca6d34b2676a521521ea307d0489f04d6ef5cf27198e540ea3522707ef9cb632829dfa5843fc030b59858a237f4663dd83260d8b08ef40394bde72d08d613a5623825404982b4940c8c5d88db1a46906e44c06c3a243a3a28ad68f1bc24874700b4e4a113be2f20798d419e945030a15913dda57365d0e517d717593e3a7dab5ac901a5a4499bacb059bd5952210413d9ca334c7fcfcf0134bbfd6beb5056270f39430811ff15861f8b4be7666a5335353583fe5697fe381d49bfac38114fc4d34796b2d36c00f605aa9b198bf510458ca0e926a247c13fa702f3a1d29cc7ef4b8b95db265a31044e53a135ad66e7563b6a43a703598830b4d7e097d861245f153df9320d8165c74ce52311b9d76a64d76ce598ea40d73c120a83e02746b7332381dd148336282920f5846906d677806208a353dd2c7a9051c92cbf3668cbb03441f3439c2c3fe703101ed67b3c947dbcb552bb8228e982516a6eb2f8034a4c695960ab3d1c2a866d505bca7f67f90dff021a123942cb67e452b261d56c97de6b3b761b767cc8e76bf589635c288f2d819ea733b7e31595929bec5f66419c8feed206229e835e2a6db70625fdbe38a25c2349da9f1ec97c90efe7f3c13745b18640921e95778ea61142e19cbb2c290d285dc6bc284a2f2a09cb461613a8e60552e7707a82a7ede14782980306357add2a88460da5ba73002737014071007dbc090d413a00b16c01271f04b15058efc14bb355dffee33578351acb2c65610cb5c33e3184b94abe484e3de200b3a016a052640200b760ad795416b87188592ac4de2aa6cb7b51e671661bc1e9452af45338b6ff614ce0c3f1949abe6aa7727281d131226565693dc5adda986c6c0f49b1fd2cc158b6b5d4483ef84ed8fdb82f7ddb4512fd95ef4723995a4d5fb8fecd4ff8507f0df2e59a7b3391e782ba30fc52ee032fc02f69531a6c5388b1dd47ae23f4eb206e183e240c942294f8995166fef90143d9903f6ddd4a2d1128e1f7ff18f75f4a9c3b578bf0ff88620b18b7b5f2c1ad52646409a1214621a2b1759f0201283d64b10fd5f4c1578749523136a2dc54c9869b233e371b553404182e33c24e4aa7981061f8f39b00d1f2389cfb56e893de875f61eea2648ba32ad619e1d3740984c17ae60680bf6ad01d3c010df212da7c12afb12d19036f865a5fa56c80b6257d79e93ab631e740f25dcc1072fa70c2e1dd8042e62f8d66b2b5190ad4166223bbf52fc9d46607c9ea1e1a999a3646561b121b80761947c45e6d26866000eb55823b039f7d8abc16e7ad0da9f1302118db404daba278da0c03c588b036f28df11787d82cc1e180211a1602c2607f6ce0f6e3b807717190a07b3e2836a449d65fed0bf80e3491a0c3c45b64cb26a0c85a50df2d2262cd671f538c62004efefcac2c4bed807bb13694ebb27cecf5788394801e61c8c92ad95b0df3d5d97f42720826701d6c7769f8fc63d695f237bfe80640ec9d3be0c030f72c80702bf6247a4ad12d3e2b03faf4be7c80809af8c935b23b88221b0359d09c8a44343ca61ad8b1b5ea2cbaf937ba89c7e191739fce4d509304e4136410117489e6de36b9b2e8d92ac4ad1f108026df9ea4ab64b931267516e05d18d7177b94d74be15ac35c89001e27802762e3e1c6fbbfe7333a70ba6d493d45a56eb92e08738cb55170fe06f6780a47d8f69c24c0aed76faa9350c015fbce22c8e37a64203442ff2e7d3e49e1233119615c83faaf6c87d33b16932d60faba60118a1556096dfc5759313e7e012622efe17652f92dd0a5b208b62d17d0362fd3d1b3f7c5a987cb6105a257dd9a9a8b26046c0efd5c14537bfa8790a0ac4fd162c46addcea5f0d9ff2d290953216da4adb8503aa16d4863f3b001b3d1d26546c2e5511942ee4ebefa1c878f29fdfba13f60e753a92945a9a0b4b6d03c519f82946a5b38c50101976a7ab0148b4a58b3855a67a682afbdf4f40e52d2aea8a5617134b650169968c821e688a71300c7e2d2287cee080a2c0c4c71c63ccdc9bec630af8e71b7c9610929aeddb7c038f70eab7d9668079d822646c08f6f5a1bcdcd05e1d9d1a128a0d8f701a5aad0caa83231a21e9d78d5f5e16bb87ee83954005d209cc9b57e55cdfd3836bdc1c1b59fbce52601d012acba9e2164b75836edbe4eccee00a92a17b5f15d5e19c5d477cf505e4e2292c0ae71121da56b379d5c90c1d1b220603386898bfcde30339bc04a212819193c9ca06870b816c0e11c36fd5f539aa007b4f19305a3b0286b9198b3c5c8f86f062a1532e4dbd3c178d3c39fd5e8a91cf60153ab16f284a51b9cf8a5d8b167c14aa8ab2d6ab5f6812b1e32cfb5687e63986aed12ad73976f7fff23467ec3ee23f82d363cac21c88613e2c14c4822626bf51eacf035ce79a2f21b64a68d8bd40660a28a4c18e65e352288fd301439c9c660b87f3845dc8100428b2730220d304783a07e005c8d64295e895b122da09068e762c9aad068a79ac24c0a1812ca5230880075077d5ed6093cbfe849760a826c9459ae03a5160e43eeef2f135955a05a138e82275d8a9f0dcb830197e479a5832e514275feae0ef9c1e2af8f114b33edb48315794c6e3bce646fbf4b59babe6508331d33a8c92f17ceca2b5b392e1d170e8eaba933492a36eba995c04aa2de7b8c3ead1db7d0e79e9bab9f4d0ee4e7276d70d2d51fd611c88dcd0dcfd00b40e226bcabf97c0ad9fdf5f4f1bc595e222923758ea237d4a55a73b0895b6dcfb02a8c0e7b8ac5c58c2d980037ce4689e8355ee4f88d9f64c03c6c3efba986fe3cd80684d71c8b9163706ba0dc6f301f63827e862596543d12c3e58a7ea9ce700e4ac07b56443670ca6260ffef55763ad6068033c9914ef9fdd03864024a74b990e11e84e27f9debc152fb81059a8266574645bedb80b7dee7626bd04da0b73c9183b2b7b158cc35e5ebf03af235562c88c5523219c25f1d3a04808252197fc3b397e527f82f8d4edf04257cceb856d24c42a0ea5df2e0f179c9723c6b8f3d4f34d262f1c6b8d6984a762df1ab58a64881859ba56e52522a3f707aa9694436ec2ece7d4a9c456b9f0a238e8345929eea26b798164579ac1db2a24ac8327670d0f047faf45f193e4f25809efab4ead0508103b44284ded7cd501a56b968196f55d11eb81054544f3b47176dfc428d278f2aab3770d94ed773ce31d69b96899946f140563cccbefb2f064d6e8a2b03ec2238eb4fcff29b910dd4ede2e49fa15ea83be0f94e25093b934e7a1396b60d2797e766c2d5ae1dbfe8fedb48d402bb4101f1735402946ebbeb89855898d997f68051f7744b1f5dfb3a83e63013e2648c3cb46ab0f85646f4393c517aab40bf063e03d20f200954640729e2d54926af65afba317ac549681a17ecbb9bf8762d9d34d2ffe95406cd8ac106f65677b07b0319fda3cf445ccb5abae0677579f128ca6715768a5abd90a25833a76b262624d6bdba1ea9619c711911d6d2bc8dddddcdd4cde566e150b4b4438daf4ead24a84f702610cb5f739f50bf69ee0b1193981ce8e59fff8a86b702ee28d1b4e0265de229b73a427d17c5487469b3162725cde687f6b23687685d5b12a20331f7da66c796c1109747c94283b9189acbbb160d49814d6c9b1a1499acead9f35b3e074b72aa464fa9cb282407259917aa2242f721589a061a60cf20372bb99bbe3a8ddbe1651564de3f835d3ddd20fb7a59849ba2dcdd54a9b45d2df309854648ce1a8b9b3e05953f61b9b49f830669c466fe3bc9a59e657cc8a1c9e5352a47933d7e0214b176b25ead06f1e4299f0b16116820b9c132065cc11e7c71cc27cfcdbd1610566e1066303970ae906183832b0e9c5dd03acd34204397c0214a4d645e00af3c6fe4672e6a5d807ec81af4db42a50d93ef50e605b0fa0262fb615f2020cba8f2e5da847061a39b6c79d9f1fcf387b9a9f90fc6e3ce3d25bb4e5a707ec085543c54bb21d393f0c6504d4807d01e0f56c8b59b452edc0c200ab8079945b1a55bd1d883a99564fd77552fd6570478274f08e2d62e377eb7c2639d54464960679b5e0a65d3518c929a83e953afbacd9645afe0bfeacc29c9d83ed54aa302bc2bfeccf2feaf7c64f485f8f9e720328896d858453915fc755e4c9cb71426726ecf8629e3e0c5e6512c5ccd148b8921351393a8961ea1e0a78474d9ea79bcc3bad455be9b8e3dd2c4446d1f9643012404f683b24b3479010485d0da0ba328ae06d05e046db8c2672130184bd154da4bd3e9a725683397b9cb191ebc0d6165e138742b911e830632d7d315348a80ad05e1ffabca4dcbb3110856aad2a45ed2a446c426f17b642dc32edb0c6ae90aa128534404231652e595a06022dde3e3d61cdacc224aed52ea0c95f90c772d5231de0ce0f0cda160632241336e4ca7d5073ebdc6f2a069d55f110f991eff16d9a966c12ada186978a48f7e7df009701bfa82d3bbea4853cb68dc870f13426e1b21d53e76a435cf7a70c1512dc0fe0f306b23daa09e0232e0821250f9db620f32dff432347785ac65c0c1c2800972eaa43859324f6ba65d76b4d5dc71e9ccc367aef7a41360ccdbd803d7fc2f0e57c1ddd3d56b8ed70c843faff0bb72778df967690ea1d1b03817425167aa084427599ef642777e37be2967c11f4cac8f16030df3e59d959faffb92cc16b3d5ef5ce785546663942753f16928e89919b504b9512f304c7c5852bc37f3d7cd68487263fd338774d2e9ac4ca28e626f401393da45c2e332b71b8efe93c352047e25adab912c1ceda532143a5451053170db303dd728fccb76e5509e1bf2b26d6bf3a04dfb36970ee36db54058002db207ef425fe1b3393b4509f09ec1dcd5fc476461cfc9c3b9faae2e14ac9b8e75adcd3ae3b42e92ad5bbe75cd083d73875e94e1bced97d775e5193b790146deb2c76babf12c8db61f8c0e7ce4e05972496fa09082b5a53e9d00c83d489aeef872af5028b4c4e8e1922c3a618b0b89ba4e008e3b7139ec688703bf78014990442727d3cc29ea531064c738369d082883f3fb36f53103334e73a19740d497cbc66daa2792964080d350fad505bc16cf754bb170dee27749baa00da0ffc4ee73b55c6ecb09d5296fa9e5579de954e4eeb39efbf39f4dab819fbaebe7483397827e415b7afa228fa70300d6e0f70ab05769483d8454178f55a212bbef20f47f560ae1a7ca00e4bf7a66ab9587cfc3abc54176fd6de540a46fc1dac3a8dcb225a6d21ab58eaf28154b66994dd02a5bc731ca02300a32efc2a11818d443462241a156d88ccde0db59bbcd455c85dd3aee3cfa8b45d1cd1643a3ca386d1c141424cbbf409482ff5547033aa9199f1640726c1ebe3782791fbe2f797f968a1858efd607b3562a1f0c7f3c80c1d769af0ea04661ff7d712d7a0e24d2a24c2501e5321adf4d808f352743a85b6bcc480dec011b99991a51d52611ba6c4c9b33117686a50eff9068882f53b538345101e50e3de43b4939454d1d144f9bfbfb6a5228b7d8d24f3d384879444b7fbd14b07f295751289480fbae21f890283023c3792c5a83087695a65be1bcf613253dc67576f8297fb7c4e23deb140cdcc94a158c514954a01c6909a7f24e95c73478c7fe26d29c09cc7281e774f8aa51c865603eabc67bc05d566a3de097e23e96ef7561e408a3b2a5ccac239a5a3998fb2403e4d9d06198fb366f1c99f953a5b0bacbea8bae36bb34d26fe1253670560cbd68e5e479897069470bea6c3dc2a11a45f32f449d35af3b4e20f8b5042583bc0c5112b81a64b90b52ec10a7a684d7ac819fb655dc73fb2918cc49a2edb0ee567ebd854fcec00f68f9fa64e67bcc3428e9ec6ad92fb3c017e6208a108fcfca06370a6b1028eed1f64735445df851318358e943e53330b6e4182928467859437e616093f47234e89bf17cf909a30725b10b72573d7d81d7e555e5d59032bdd6b257c9d6f9bc4c69a0bb08b010a81b9ccdf9e5f0d9a55d64c78e0aa242b001c7870756bf03a204d98670eaedde0322a6549f9de01c63bf58d6886730fc6927a77da91f4e2e48870a6ccee9fc8039b47db0f19bd94a7b53b16f52615283ea0640f51d8fdd11c6cbf5fe2ce96bdaf9b14c5d0d86b0cd35cb7888c406c66c3c95a9a7545583a85556cfe026b7f2599cfcae9cc15107ff60e2ef38ca30005aab9c20b285fd7f15905d87232780ecaea33682591b154edfdf1bca930d305205ab1af4e14f35c6cf17c8ff1f8d981263bac453fc461050d75729cce6722b08e755ae9eb6f904b528fddacfbf1da888aee0f9f8197ba02e446dc8d567fd5b5bf2fd86ff3bac7e22772dca184d9658136f4979c159a9fd3f44a9c91a944fca526b2f081d201e68b29bd79814861ad77aaaec4d500e956127f479ce98beb2a964bc145608c548e8d378e6f78ee1799b4abd8259dc1e4caf60e6deb4f869fc7f4a70dd3e33a0baf1c5e42875799488a8beb816ab8c8672aa355d17dbb24256a499da58d4f60ff55ae78a0c8f61518ddedcc1e8ed4cf01d16103a47bfe80309b8734c16e0cd935632e386041ca4696d819aae6fb7ee6695e898937387dd90d8546e2965000e8421e3c8db79fd3b16ba45f6af82f991bb22bd474b2052aa5475a2b0ce3d15f5d612174e8d69287c58413f301814e3a4f0b92d6e00a0854754d156aedfc8f3f45ee41121a129024dfe3398c94f5e88fd8a7161a22f10c243ea6cfa176345cd20b68414d6dd8c3514196319771d0479a52eb5efc32c59e5a197c6090f184808a1408e4186afce57268d7a64f3c0ef8115f42ae53b93e789ed9b5aae717c5c3e8a2ce58d2219e017d2abcbc24b16fe968485fcc8ed47884f19fb916acc7e9a9355009046e341e97d3073c72f41c2a4c5743b264c8d3f8bffb2c0cba2fe25fefe7943bd17b0e89cb56cd7c3ba60837459612b54ff89119dfa9ab959ec2ae2f3fa7aea5c4a78a8b96a228343c69f0c8d6a39018dc1bcea96318696842ed950803c40cd645fc83791f1faefba712290baec5cadd03ae3c92bf72883fa4d2e45a13813d2064909ec9c20606e4bcc756ee22527e99bc5e94e30b4aa93266082ebfafb1cd666172f0d0e1d6dffb6fafd5157102c6cf635dadf8e83dc6f7942aeb5e533054af4e6da31be547d28f2ab739458fa89c23765924a8bd41f461f94ad3de6dafef78e8c8c6d7f83fec478a338ca2a7820118af422634863aac29cceb7baea1db3ffd494e51d73ab37db423f76ce714be6562b3357d37229baa1d857da91028dab0f2ce7e69960428a8d32905d656a6498c12465703e8e10a64abae012b18b10cbd5caded46e64ab1a2aa6b611fef9e8ee734a61483c7250c2d610bec906aa7170509f4e2836dcc4ad44356b3cdf943a12bea4f6224df134138fd9f1060208488000a22c3f3ef79d5b6c51875f7493f04d86131c11c984e6bd4042da93ac4a0cb192929d1a344e7b6ae913cf549b5e4a064f0c848415d5dad23ee98e665af7821eb40d49a1c6cf376174f4ce21755a25f5e429f5b88a95b14156644da0f94423167b4aadd3c6645fdadc64a632d49870a5267c8082dd7bd3cdff964d581536648905649ee916fc455bd63949309ad1b6fdd21c95ba75509ccbb290c65ded05e41144705f2e4307be6ff774a6297900f9431d50bfcf9478d3539fdd06182f7e917dcabf1788ca341e1ca8b4ed01586727467082bdac81efbfd1f74181faab46b100cedc214dccf17e4bbaf54332b7a3c949239319a14bc34ee3a0fac21f43ee2696b08b4ee665cd63483b763bc88c334e54a66b24ca1949aac41137f25b8c69b804293288b0aabd4aa14b3f4e882fee1cbb28e3a88cb761347b50c858db3d28a70f5adc5ff76477d03bc60dacba79b7a915e421a78e30c7ad79fe84d850f6517fa7c4865f401103775a9d3f744746ab5ff758de8f7a0b166e7da6c4d6be314dd9eb7cb64719ab9275ce28f43f807a18867e062f1ee81e00b49f4e4d1afd0db310fa84a1faccfdefcbf97cc8afeb9c0a9b0a138beb1087bd11b2ff8584a92982daf7cff87415efccf2ea1b8aa8df355ba3988103d2584bb4fc51f1df5374c0c5b56d1ef05afdf97e9bc334c395786fd8e569ecaaed40ca68accca4ef8c6eaacb4cdde7109ffb4b302b8ed1da4ca0ecc794ef77f1af832c8b8a28438098907eb1ed5a190e4fbe8a5be04d4f8cc02af71d1e8e2af37aebae444b0c46be6a76f69039f6cdc00a9813162cdd89644cd41910f77879b466da6b729c139da689a648977a4e416e26c6d413e49c8d956c624a454614b909a861dde81ed1c788a52b662ba184451d19470bf251e7c977ca4dc93236dbe0998da53f8adb228d689a7e11c7d271b563e77ba763ff3cea3403701e442a7f358703dc17d888572b7c433b9cd62384b3d5920fbe9868dcb185afbb3ba7354d5b59c4a46701f87463c3a92b3ad4ab58f3d4e9872768aa17b26985718c92c77aa34eb3cd32c66dd32825470803ac83b7c71f05e73219e802eba5f4378971190a4a79b26cd6ff58146eb9834fee6f5973aa3cc6a548b9146cdfc7ac523d7bcb41b405a166361353ce11928427eecdb3745e8439daaccc27069c29a4921adafce8a95c8b761629c927661f90621342491241d25c6c4ebb25f66e52daa929d986eae43d27a69b6a2a073ced0433d91603c0d342ebe0af31b176603a87f212acea08c320aadfb3c07fc2d4bd9acbd2c0565410953502d3d3e3b3b1273a9f13c0b9517f8a21024ea755b912d3cb299f890d4ac0f120f3e64ca9ca708553a20d7e167df92e795e3ca3cc13fa39c30da735daef46095f4ec014428186264db24c89ab504f09e94fed6a475aabe4244787e5ec64fd51ede619669889d7389443d4bbc3f6c5dd5acce647794994346ea9a52a89d051873ec49a4e3a5fbf01ac8a3582776d315fe37634a72c697294864bd9c580b2179b88eaf4b46327613d617563cbe67bd5c7bf4a2cc45156321e2ad52d2df6e76f676d211162c7cec4ac0223365729f15aa1e66e21dd82986205e5e62f049e66d322cbc255dbd27a0da14052c8a18e3efea969147f7ec5dbaea158aedeb009398e3d03819120601585410848100a189eacb2e1a85f547cfe3f486d7d38df8b008297dbf7947b461069e0eb0d9d780a9be3d04b697f856b97d48753785488e2165d4a7c3de98140f7d881ec756a1729ad8cf60bf584a024b7292026df47027c7e0f28427fe9925ab6e2c421825ba925a7d50b99b78977a4ed8631cafe0c9a63aa09de07762a3542abf18bd47b2ac3aa12413eb40688d059f2fa66b4ac210db21dd9fb025174e029b95083bcecb9fe722c4506bd89094b1cb4cefb31464a30aea4d3ec04422fe49831039cf7b6cdebb9858ca5b6bd05489d8638e30d79aa7df7fce7750678f45ca1b084c981405105599596a15f5acb1068747ef5241f29520fd80cfb95b357586233f904e2877a450491bfe9f1660da570c2f509de25c546b956bb7cdd040a34ca270ccc545875352e23608a936c0a80e30ca94546e8a5b949f5e36c66fce847b446916783961a77463549c955786ed5189c3bd1b64a2f02db499ba5ce3472534156967a2953a00e9062b2ed0d27f32a49c062c5367a413ef9c1191079787f049b0b09c12d152a41b89b8215609af9134689306069008ab08e345e69f017e656a1c5c91a46eccb0076205acd1c9210ca4e2ae0bcf32a0148795972802b5f898a52c7859c7575341936fa1bc3f94b39ad565362d7553dcf068c286940d0df18a4b5984b3e9d26a41f5ca257f8ba95d8d8838295ca9fd90b8e37164b809bd451d8cfeef439d3fae1aefe003e07b8e70233e3dffae7f43c6e8dee0684df40ceaec06d41ea139949dc1feaf1a298c4fc9356517baf51afdecd38536bfe13e8a0325325034c0000a19f87406c0db99d7a9b314537a460100f997726db3d2a71849e7cec2e884746652804208992b1c95ed1f97a94533c2d5492be94bf3ca1c3155486371d4f976ae91dbb5b2681ca66fd941623f72923ef3d2581f294ada7f59c02e6e6df79a8517207d2b0c053732696d9d67c034e970bb6d34b3a551841a2aef3ca273273fb3ae12f6150f332bd35b2a737544f0d6ac7d4e842f6e7b46ee9513226445a6bada4393262f235453ca89521156e23bac8edc41a318f5e634a9581348513d00312e6552b0ed42df78e6fbdfd1dadf843fa172bc6b56f68fb4c6f87aa35c1cd166b71d7264ef1c3f834700654d6c28cf7b643aaca258c40f2935889bf9328a7e296358cc62df3783d46f4beea3133662a66476dfdcb1f56b54127160f0c7cc1e801bdc1d087307d049d87cdb51465cbbcbaab3e94c01967df98cc368ba100d654b53eb4358ad85a626902c1e00e09692be6341c9f84f18c2ebf5cb369003310571f43146d4e44702d78e4febed48878c9f81bbdf4b9a260594e1d30153256d4ba2b9cf8a3f90e1412216512488b46356dc7d458fb1656a9bc99b15a978290481373fd2822894d8d209f2c7d7b094e73d579d35b83380152aac8758a6bf6a954059718fb081ee1dd2d1fb31712f6570233848fc36e20d511ae6876471d0530e58c3ceeb06dc83634541820902e5a1cbf027400ef3039392d2db6e8f3870f91bfa0b1c7e4699103ef0371e0da48884650f2610bb4548563066d4c5b92782cdb75fc24a542f26ae0defe3bac4f0b6e40799e846edad44f789d2b6ca970defadb21c07679ecdde3f304f702d8bb1070655d9771e768a263941a3afc75d3ddf90f652c461eea5fdc9cf192b934b0354a5ef389175664d5441aa15c0a1ca4485e307740f47bb6fcfc11a05e5c45a478329b499b208ab683c87f66b8ee806dfe1e36b21a2fb4a068ca152ff463d5e1fb5f9024668c7b97378003a9979978ddd3a507c8293ce8f413b61495a4e9e7689270eaa3b84f03f79e8b9eefd0740fec06d861b7e0ef99a7e9d9f1f82eb17a84d8be1812a5c361a2211dc40e5f9f30c3ea6719de85241226830ef5b44b39fe31b0d9c3f4ceb8fc55702ecbd69c36889bfc7aa2d3aa49ad94e35e22cf1ad3e1ae912538111c73b752e3fc381a598bfcb9d954a9751ec52e0dd46884faf9338715dfcdc7dbf954b6702aa85216c45102fae0218b0fff5fb3afdcd4804cf1a347be4ea9bf8359fd20953f8261c1b038b67bf12590dbd15a81c7ebafc3980c6aff8cef014af7ec92102212219eaa4b09a62e7bca44ab9e4fdc1d6ac74cd6ad0aa479edd096006a9b41a1b573bb00f8142b003991164864eca0ea06eab9770b5514f2d98503a0382e71fb34494346da618b060ceab93805a7944879ae2a926fa167aec6559bcd7145153345b1b9a26cf7cd9526ca6a9897dd22ff140299eb0e0cdbb93e758e244197c6d8a73324bd42617d97cee2bcc97197c3ad2de16ef3a966bf3d73554b94e46dec7fd637a78ca2dc31ff5e56988ca95b557e650b8483f4a6abc1cbdb89861f052e4bb159fa1035bff6809d6ff2dde60c65a513f391f161922e041645c2370ca8f3f5953c07e4cd7466807b11ee9b7793180637c5a7a343ae0aceb75501a007444f904ad51f2ce462259ebd038e97ba3f86c9cc34092fb5dda9d85c1ed8aebf73b2ad0b6625f81b131705e33a71f7d3a06e207d38283665170083e2fa90d672a168d5c4820b003b8d7dc594600068942950b77c47ae145aaa7a492dddab8e0db0e8aa8c552d058d8ad95a8fbf8215caba7a879eb4f3cf9e296380b1e708fe9aafd45074e2ac91c68e609ff672d1642737b8dbb5a39b28332215a7871f731354e158333d239d11debe3508729648093d1c5a8e6e1694c138e11f394d05c315202ce778c86d9f2f845578a3e2704c4c282925980c2f4fc4d556fea6ca5ea871210c7bdf6c733c7e6c9043aa91278c8bcd1a95d56980a481a4038f2185283f484500bd061929718333d505b56f15a1c06f28b709d52dc2af40103aed39622e9f8d19d40bec6bc20af471499ea4c02d3fd2d7093c2f235794401f26f2d108dc9c213d84c05b0d72bd0fe81f40be75c075f4d1a90df87e1e1f8132a0cd4bb748c105a475c68d67c03307b69cac7de6698443c05533d1a2df55550b5c7b2449adf618c1daf1afed6351a40b742815c1bfb2e11325bafc929c4daa86b9286fda0c5d95cd73ac7d36be33ee41f281fb23906524b5cc38cdbd1f8c1e9cd3a9fdc827881d3f16a63bcd1655c68e5f011185c384fff415054c2aeaa60f6d0cdba1c900f9e8188b035c6506d3542117a418d22b2cb1d9a81231b39553900910065327c110856ab1f71aef5b7e2cc383132f9d971c73f35e5bc2686410892795f387696825d25e31b034f67996ac51ac0066ab488cb677dc0a75cd1bf90c574de4f356ffeeb0e7185e383bd3b33436c35e06ee4e0b177f68dcce90c4c1f52c03f1229928cd0b563cf0059cab6b0b85606181623383f0f968854cbe650a9244db20a7e7bc6a5aa0d8e81463569f0fd5641ea1b033c40695c219998fcea077e9c2ee2f34295c88e64654612bba202eb51028daa0f10a0e87ae78e30dbb72f16442e76f78b15b94bc77c22e99dfc95e47a0bb4b52b73d82867dbaedf7749ed1aac77a3a0206d48c6dfdf95a2118083035c1ffecdcf615ae987033fbe31ab027fd9736b1b7011713dfe7bedd06324207c5e20275617b1d9c53216286d57cde7161ecb63651f40181a10b25e181ad99f3cc293a8178038da608c4d00e41ffcdc1885f0382c0be4e17899c28b1ac691bfc5988f3451cf738dde3f4bac765c0cf809fd11dfd66ca94d3b5aac32bffc9d150ff97d70a2cb39658d7f8ec8ec340d979847f93d20084db7c8e290310fcb2706a011156acbecfa76971a2ddc5de544355296228b0c237b4055b5affd9f57e0bc2a8e16ff5fecd4674eb7d060470c9c848cf5f9cac511f3a1b705ed0ddf521e86a6122cbe04e49af4a668793291c0678c56ea5e1a550fe9e736d35b604636d17e6a1406fbb46730fee22b9eccf3fbf8850df06dd045da5a635c24938471b2cb84eb4a2278d5157ce4c5b3b278c4026359dfd436ad3ed18a224157a0e366587ee46a2f65678685e1cc4327fdd01a043222b99aefb445df563b068b350ab38780cdadd1e3b4c97aed1644b45a0a83b761d8d47e339e4bb6265f64d760e98b52ca43213a0fd31f248992f115996f6e9b29592c542c50338d059e895bcf016f252db6b1fa0825a8579f691e4e00863d26a9b118fd906689545da97ca971d36e37f5bd2915e0de911514637248c6f754a4021e24057d219fbe6e81efab01fe12bcbb3209b1ec948a4625557ad00ea8df8633dfb5da8ed55cacd7f5be6cbd0e09fc3fbf14bccd32edcb38a27485491961b3101a99a310823781133612236484e110bebd740249feb76f82ec0c8596fcc51dbfb5a6e0ef774af5e6c274c123bdab81d97680681cbe589ef5405289a443e33f1fa07c89576652e934d0407cba6506052c7c34a86533c7d1fb2aa588edc56fdbeee2638809239d1c2c420d522dccc7073935d1e7ee0da42eb672b65d7f41c9fac6e72ba40d40bc17d0fcfaba64a6d5c98b6490f732d8869ec9fafc49054934063b390794476b99d357ac63849696ec24b2cf69a9472e6af53bf28c51aef793e0a94e80734a112b25e9947ce883b35c1d081316ee9b9614d39b8ab524909c11c5d87b9f68d731ebd765253df0675939d0037e1eed85103d0ba129ec683e258442bde9130931c871be63d0b2fc5166161ca7c1f427a10064ead86f91a422a3bf8fa92c887e13ca729a7bc773e308470928c30b791a2953067e50fc2ce5db2e8daec467cdbc3dfe9c1e14fb6daf256c9d12ac49900aeefafe59a18b009056092ea2c864618bad25fc2d5620c6cf0a98eae3f0124e96ea898e74ee4eb6c760eda90168ac3542efb3d3c6c2bb9a74080cb4bc388b13341f285716dc9c7e35a73037240c65726e3230db8af32f88745982c061df55c2a0ab120cd6bf832d909006b861090b485ae917d68962254c9da6ee1315d3cfd45bd7e90d6307f5bca4321d5606a9df8070c8401954d2bbec1ae3006c33eff4d7112be29a149eac5b69e3154be3a76e174ff6478c097c105451b00fbb621560df723560d7f8ca84942fc7b4c05f4ce813a999e4b7c38f622fa0c5a25f9868dd3b36fb16aa80da136d4d3c26b78a588ebc26c01da86a80de9c9a28614905cb4674662850aa8c64ff340707ac338a30db32f16f40af11f8c0d834a353d4f3e7dac1207169f7923f8f1859dfeba00b110fb3a4688af3615419c7aad23c4142ab466b819fb7f123d893fa5aaac9eaa78c3c5727e57988234de1cac6c0a880ff18fc7848a0a35b570a20f597ad81da1f9d96cfa19db0cbd39781b2bc1cf7f119ee457a04456c8a3b2d994a2a936e9391fd02303cb9dcc1b7a4b5bc30f48dc90421fec9b83afb113fcfe8be2497c054224e55d3bfc67d09f126b5b4bc9923b75ff3dffa63bc8c6e9fb3c039b6801fbc712a40986108a3830b062678111ee64a36344db316840794b0eb44d82c43550934b404fa0b7dd42e20222b94f6b90565719be47c16122f4d8a94321df1e9d654b4617e1950f951ac86400ce5d0cd0fee4752a1799f3c43f1285750819b87097641ebcbfc11769838573f4e4c2dcc0f0bdb3232b8399ac136ef17fa0fe681577378d33b528d15193808aa61e73f6564900b0423387a857b191235ba849315284ed7d21a8ea26d6df6235cf9d3fc37fb815a4ee164866bacd27074a4f2510ef8226883b2d89384dcc61c4f9df94ad96de09eff1cb311765b987130398c8ba2bde56c3457f09f21fe689e6ed101132ce3013a4a1c0634e47ec2b9601978b9737f720c8dc92373f513b26e39cda361238121bd03594a72d52a2cd11fa68e6bb75829cc3a629a2116b0a1e0ba4528d918674199915209a914a469a8c1b8feb77f40dbcbb833bc63284fc651fb85debe87dfde07fcf822b9dda2a0df3b25d036b87d288ad7cc2449fd25f7bfb8a9c89887dc020c272452978a0f285878bacae1a8243062c8269849fd90ebaaf40b5adf6233252f8d54fe6b3586392988ad3e69cf9c09329a6ec6f23237577c122cea99d47ce1ea87ab4783befb303c08b9c572f79ff9a1699e1f87c217461a7fe9abfaf8ac09edee0e505e725801d63e67c2a1527e4fa889bb9f0d0a56f31b049fa361c565cab12eec75101966fbe1e96825b084b6400d671373cd0494381942c0eaed976530569e439125c4102d4f61ff869b09290cb9ca3dc256dc49c5fb7d48938a517da8e3115f348a699c05dad88420595ece0b251d4bf7cdbcf61e85e789adf8e37bfa8f02288007aece53fee6b3811c4d74c62a7ae159f00ea084ed31644b047f2d9dc8cc3c376ec6634fd829cf032faa21fed5de4f8838eb8022476be146a2cb14f4c66a33af508cbad0e21cf7f103dea2852abc791a520927e21eeb16e221ec21584b9dc466f4e77ae4d6551318633abb4037bc9ae47f66ea520d855beee7cd18177608904f3c65fac976a181864aaa1a18f13da10cfca9571cc70d4ea347d64ba1da26030e3e80ab08282e9f53d67f04f9f39b7c666d4ec79611f96e9aae21ab12386e82fef7a3ff22571d4a50ca6e542aaa3a6d16ad91ae5606e2904a4333d3d1c56026ff03c211d1b48e3cf72ece0a4770ef44587105dec7e5d542258afb1685105228ee1271fa27911e4e19216baecdde8fc8673a5d7864440d44f3218638ac646905eb35bc1d566613db088f8e2fb9ded8260e58b81817b7792c5409cf387adaea9ad5d181f3e668af04d851b54c2aee6722a1ceec1a97bb15794adf5598325fca6981b24fafb2595c22b9f4261f96fff1e8409b02b4858b93cd702ba0b75e0377fbc54d442a20fcad67f80231a169a2b652ef4e8e9d8119574c3a79fdf4ea905dfae8b2969dffefdcc7ffd3a99f2b2f312f9a388775ebd02a71aae82a7fa189cf5ed2475ff23a7609941c3f79a773242a484baa05a9f1ec78d3bbf61dd915e480d1ac348e2c3b8541ae7c18839ef5edb6bc9ae5e6211ebc9cee3a468f0138863767b72b526e0d509e045cb7b0fca70ecdf18682b76d6b676b7b02ee5c875b8521820447d29e96dc052427c1f04b7fe29f37cc53613541dde0ce1cd59c0b79051ff32338cf02dd1e86fde90c5f8641c05beffb23242444f12987bc07dd9b80e05442444f20e80c9960adae67cc6d43890c074a4986af9d035e9e685d435c45bac9170e290a154e488b98f22f8fec7fbbb8039ecd5f19b58509beaef5736886f387e313fa7772a4f467e8f172432b36744d2f552315384a92e76fb425d69c170439a8a5f05b4a6210f167e5c3629bc45a9674c332ccb180faa0f4e6998491f2cc56ac5f901e97710e9c76ca677f8b65f85c14fce67e4d926ffb070b8f7e8d3e3db322a53b8f05ba7c7b9b62c39b32857aa4c8b95fbcc4bb18f7ce7824679151499156fcab0af11916d13c22acc9c7aa6f54b48b87bd83707c23e0eadf0d96c78178aee29f16c96c5e224fc3cec65f11b6ad503c6f7f2dc137fa19b709ed62568833c19b31630695e2161262ae7102e71191e9d651407e0e93512a1c3ef55cfb0e519a70b8860ab818380a0b7e0bd5afed425ab473ef4af7caad1153932024ec7661d399baea61b8b65cbe37419c6c8a948748d129ae2cb0595082111891b73badcb9c9eb4221ca4b0c4a5e88adf311dee2cfc27983381f90c042312eab51f2e2695502e94e5e6d7e22c55ef0f9d74698c781fc7a8266465faaac09911c50a04e11389776d535413182d2181f84a72e956f517d9802000bdae54300edd7baa4db06eed35c7ecc1d200ade06c67bc72f676ca1dc1b928a433df8469e970786d7449de3b7bd9f84611e7e2a3f739d406df4432ce37edb66b421943021da4b8c16cafbd1129c0be80970906773bef914c7a233f8543e16f9c3b0a8f96909076aa1091d4def427c927438327bd7a7752a6b965ecc9a622f4f08d087d1613088a92ebb158c8e844bbb8b66ed0117226041a6ce9226e376b628ff0b6fe1aa51bf7147799c4caf9509155c8281fbb885eb086a515870c2414466624d9850354c1108305dca1251609438db76dddca963e479370656f9de25a20a30561247e9276a24be82c5c6eea89f78e9ad43069c441064adbe754a855d9124d074e1ca93fd85aeb025003ce019c3dd924ea9e5c5c5a3caa17cea170c98d4dac91ea0f10883f91fc5f2bdb9bc7db13b7939a9fb567f6c69268dfdcb02b418fbd64f66388ce51b95a1ae338211690b7cea4fd3f66b49622092edb37d37a48bdd47fd252dc043d78f4a5800d1f5c017c9faca6244d57d9e1c3739d848a29d38808dd021e9d32aca7cf28ca140eef4393fe316345ad1d75862f13c570d1e43dd6197a0832234ccb859855ebbe291ae82e9db409d53ae2f1da4f365cab07fe49371e73e08635e028e59ccde250b80123ea70b091274fdb818fdd3e8ad32daf8b3208d5d18f4418a3acc12895ef5f3cbd1a66f48cc1fa41403d7efcbae506d0f972f5e9cfb05a25981093454a58ad1636625b485951c898d56347fc0d2a58e6d11539e84c832b8d317291536a2f54e10cdbfb4a2c2601131e0f6fd12f7173c8b721b9e0c4146a89741ca2878332a9a237eb568916fedf23c73b1da6388651c2b21cfd2482ae757559b9d0c4efadaff2dbb553b5982a95a2a244aab31163146b530e2c64b8b80bf822c4f6c9442453f5362c5e903e540bb3ea26c7a89debfb1dc6d860a0a5a20836676383d27807aeba77a6a99eff3d6c2651a56f5123667ad6099ddc0fbbc5f6800c727309704ed364aa0a32ccb515893638b976682758f088f30113701136f6100666bcfbf3e6917dd5db0ef9ceb6d2d1bf94c074ca74e452cb58c304c118fbc194ffe236be05385245e65f622e9539cb5c84ed77e9b253d60bca372381fede911b094f1e51612f47af4a384bb2472bb27199b0324ae5049cc220b393c6c595560c890f25d29b7f5f2ad2fa75765583866b5722c149b6acbf222586b54c65db7de5d0a0ce88186481a6eccfea079be54acd689de734aa2b523eac638dd1d966e650fb972825667f5723c6f5ea17a738b77bf1cf348f3c4cedc500c00561acc970de7eb08aa042816f0e74b7923d160d174712811c86370ddb3be5afbdb04ce96ab641f4ec7e33c0a40fe413f645fc386d78871a384273a4ef96586196e72bf00cc5978dc29139f0364fc8ef0c1a3da5b9794dbd761b04fb1f0ab5173995833d207a5c884f87391022a1a1b856528bdac3bdba06435f23e85f023944fc3fb9ac86e24d03688b5aaa5d2fd7b04ef1d94cf672ba50489619227b194866f1b8606704ac5b9bdc29fe2a5d51f8988568970be35387e07d37dbd00060a0c27fe185b643569a73e59dea4d82e0c86c4eaaa01dcc4300004335a25db59cce3474ecf0fbdcdc5887f6cb437f3d46a2b407247560c540cf18c30601cf35a4d048c4ab21063c54cc4b0f8715e2cada802d6990162292bc68c186891239e0e2d39b5290ae7c66f7092246168c60589f5595ce6394ba0a7522cfa445233f896a46fb12be925613816a2051285dab19549ff0ea0957bf0dbb6a5c31a9aa05fb6e6d236b62b0e712fcc6fc84bbf8cf75ed0bd147f50e731fbeb9e0d8a278e2460497dadb4ff09c8bf81af0d153abc8f437d0d9730389dee765809e7f8176f3fef67a9c577ec15ffe4d65f3ea574e4c61e95273ddcdfb78ecdef8ac11466f9a9e783cf1137b3ef69e3b63875fe787a75c488260f2bb06dfe6f1bfeb89f3679cbc617dcd8b4e4ad6d6b9c359bcfc9c7cfd7383770bc7c503e04b909fef47d3d17436e8cbbbb2ad9b9cd584d9aa2a34e6edc86f184d0604d69427d6899450e56ce03656a0f34b433c26d575b2e2c7e75538a0630cccd3baadddf47115e56124552d75e6eb0293d6d56df87d604e50fd599b5db8a3646feef20b64805ffcbf5483d9bbf09afaa64a2ad4a3cfa05b96a567815456767f6f2a682305aeca3a083c60032ca0b398009dd38ca84db9df962c03039b6904cbf481cad62d241173aaf1efc6f7a90ce146573277698ea855312f5347f786a15c31f4e737323635b79d1218866bced1b7feff6b92d61f2348c7fc5415d8d8c8e5dd16aaec628cd813053865c50752847819527b92594a47f6b159ae81b4782807fcdc34350ea9b18f8dabb2a4b234401cde0e1dec69d777b90bfb58b7b8c3ed4e5f8b94fce47ffa978e7c56606b9a6951f58d1d3cdc975ec2b785ab3bf4f6d8edb43c5caad2d5ab5da042867083ea37d8f54ddc83eafd44068c5f828053d2c592fb0b77af414e8e773b2f19123c19a9b5cb06b7d3b59c1e7a38e270945e8772bb552cddd9fcefc8fc337a4d344794454cb664c4000064c8adcb822a3921b1b5fc4b5204cca47ae6571f0e62322e0c3edaf4e133614c78498e24f69435e63bfec8be1136f58580266c8c27b2f5eb5de884a648184e2fa3d49fcc0910f98fd355628fdd1382c6e3d6b8c3116cf49489ea23313f1abe2541e295e35a9b742f75028c53f8465223c1152cd982ba6cf2a72a2ab7a11062731c0ab32869b32a8afbc036001906c41190838f9b1ed48f4ad382bb8d9552bcd2ef26a9e6c16a33ff50454f8acf31c7925ecac1f3a01f1d8f6941916230a0278f472aead76e124231e0d762abd0acd42cb64b2e13764c095fce5656173d3403d3704007f1e9323e27d57e7b4730a4088b0b010eeef832cb327874825bdca2c177086481d20c30456ae8c64fd8f08dd477e094a5f98211531eb32033babd0c54b146b921fa661712d02e82dd849a6a4defea22c7427268ad2b51feaa288531645fd2d97c92a88d9ff1232a3b017fdfb20de19829a5274d67f04d8ba2321b32dc684d767f54a81c724c0ac0e2524b1515ace16f6a0850613b200db97fd0e06fe91ffc15391c30a966386717c96d186bcee800c801b5eb2c0206055ba91dc9560b007f6b800c5512c0f801c0d06187770837f6b35ca753e5e2849dbe828dab13cd31f4ea68da2329b5de1909411234a2f7570028d8484ac0ceb1ca1872407072fdadde108f5ae611988dcf7feb7d489860c62aa4d7868d0bf52472fb13fbc38059094abc690ee53a383dd21cfbd26972d52bad7e097e7f242818caee0b176cd6740c37af25c18c877403a0c47385366c3c997405eeffeaa6a5d884063b62393c209a0e8d6493770b7208e1553873695efb73c1df8898134ff9a84c9be0097f520ce92a5f9ed80881420a6788991cdd7cf9a034aa7064d118fdcd5222af20ca272d7d20859ad49896f592aaf23476dcafbf89c60c67bb8a3db9585a465bc0675810065cc6e65558ec6e5e4a516cbe287cbc40acc0c78966341e327df3f1fba180afb848c018859aeec6e8e7d910d1aa3833b2ce3d9e8b89d1a87b1a3c22fe0135925eb9ee2d7efb8e332cf3869ff6a3de8ee8dd782e0c6351dc78dc58e3f9aa69cde504eb8ca7181a88090d5719b83f8b45d2cc93ad1c66df0f86d2c9ce10b084b459349f91f429648d619951d58d4733a65d01b2383582293778f1199a7913d854e1a6650a8c7d3bd0058c338376347e76386de5903c3eda73ba89faddcb3eb2bff03346b3f1dd79d3190affbb795514660ac0fa201814bd7f47d20c86480c5783beefe476956f0c9fbb58463d57db6407f506a527f01b3ff6ae97bdfd3008e80faed1cd401028e2520af49b62e1bc0f6dac0645c978e460ea4bfec3b0bb9296439aae836833d400149d8cc11035f46b333cc5a8276c631e125493f47b9e275952521708a43749e7b32eaa9056146e95b2c8f7a98d6caba075112d1656bf899d6f3e7ec5a9d40aac6bb0f20c9f022f0cfa233c1c92d590bb5e4539a9221d9ea652ff2fb48b0e66b95ded26feb02105f93ec9fd829f31983c1d7bd9a8d96ceba72e7aea40d280d693bff09d62f83c52f07d01106eb083656b13af580cc4feea2e5b0841fe94f6a51a94cad045f84d5245ae0b46aff935bc6b6c251c4d2decf89a8e67fe45fd488cace727309ec1cb6e0c82a0706438545abdb542611a22f791caf6c0b246acc60a3608911f15cff19bc468d57b1954f21b76c380189b94de77257edf4ea1f8d9092650b81c223da6c93a6b8a60b2d22484fadbb4022cc6a701b095d39d1fa4df2330e1b31140a41550356cd88f3f6385959b3e55ac3b9b48abf6a4fb22cc9ed07c06fc70e08c38bfcff0de9f81c609e4acf650cf28cf591c9c6e290747fe15024c0faf9611e9a2c7ed5d01035e65ef239b86877165446fe1da604990fbffde7a596cda7e808d9e51b9a0d71491d19765990bbea97976f9d232ce232fcf9abd56570a06b20f86d0a07308cebe531a6454a45c492300e1062090ab6ee991492ddf069d9dcaf089c05591620b0a714ceeae803ea7c0f962a3abee68f7b30a3d81390455695fe26a9f02181a69154deab7e1d251706bf66f8145565a0d85bb03a15a9baf3fe50a933001481a6fd1ce91ea838204502eeeab623417a8c97670afaaf88f2a436babac7a4d4805aeabf3a9b0fd123ba5e4c2916f971aac04e2e14fe2a7b8dfddd5f37bf75712d89a3d9750df9ab5ed8d5c68b401d0a7fad0b0a00728b8f36f427cca97f673c424236a4d381af51b47bbc484b893eba2c272b29b980989aecb3e3c395f7a6817e98250689dd90555e0e921160bccfba24a163c5a113c85af2eb9233ebaf8819ef8480a0e0029d6bd9061015b390f8dc44fa2ba46e583d5a04fd5aff514036eb6f0b7aed7bd180e8c690d663aaefbfe9bfa997390798d645b652ba41ca5856313c42eb13855051048a45f0891f384929c4b3d50a67b9cf8f9052978cfd6239b8b20cfa67c92f0bc4ab89f41bf7662ab39e2700a9622bcc1a5233a7c106eb3def0eb6a0a34185e49e9d6b08bfe1e7e18464efa0f2220ff54c0a9516197a687c9ea97f02fdd621d24f2b6c7a057c87a7010342a8def8eabee7583add1e2484c57f13345c292270e53cae0e46f6c87f91a9e7ad6dedffdd74b3dd9340bcf74f5f8d4108e1f377d8ea51491e3d390e721e09d34d244d39902d72f2e2c3a10b96c37068e0b87afa20adc7136f31f74174c6e31e216fc7647abea7011f2bfd162c7882e9b760590cb9da4e904a369f976e1dbe4edd25ed03a761acbd0ff05583cec84ca8b50d0277f61738fb96d52e29baa52b292336c22db9b419f4e7800257052bf98087bfc5c5070bcc7f9f128e68328b17e8764674ffc7ca1971d28c208bbd6d5ca0572a76130f53036775016ff5cdb3652c19c32c7cd5bc5767414ca4431cef7d9501b7060c959e3e8ca804881c2b918eb17e5db99063776fab926df05a10abf6a919bfd4fcaa12f34e0e6dacfa2dc0482856b48fa5d357cd24eff498ad9faf794b7d38e818c99d427cc34ce20fdc7ec94a1a787ed7c252eb838e27dbb7e0019bbc05ea7f60040dcd7fac72701466c51e3234165225c5f19b3257c230a0b30eba7f458b8dbd9ca2332c919b188fe25e8b359ccdb243a86bb452d32088eac4694a4a23910971b55e762f2858732f0de9859a9a71c0e12d71a0cd6b4813a3bc194331a2fe0d09c36f48aee3df0be838e4c901088fcc0e0b94f198eebab3e3907d4e57893bd1fa3c2ee8e2accb989022a36494085264680ca6196959dae74183e05817ed982be253a753b24abd7b67c7a7185d442a7ae597d59ced69ba29e9f97f508e3f0e4d6860e545ae318b6db44d897648156ff5f46a8e4a99daf045d71c95be2898962c2cbdbbb5e12601bef62ad1d7cb6216a956cd111eb4c6e6d1ff704d7ad45a7be4e9c631e0ce6b64fe1d42a6ad3abccd70da41a5433454e5f4a36e473eeba7cb620bc7083c5bfbbc42501a639aa62eb891a341e747118a9e1735ad868782e89cff100fce4a386b4c4179055b415d3502d363cedb699ecec9937932301fa42fe9ddfafa565d06a9cb0c5dba39b0c7bfd876289af8c5c9b900222fd25a33fdcb5ec1ac37921737cf70720be7af43b121e3ffeb528ce292d54ba79645eebd9f89b4acbf1a56cf6c6968f7495831477fe6392aba92c320a4ab356a4812e145e9e9ddf818dc35844292ea38dac1e338640779a35302d9078e9e71fd4911a4ed5b7e206a55b33600bf59086e901e342d156ad7cc0629c8a67709427cf26cbcdbb5a49a6c2a3949383efdffdbde499d563c8f8a718637815223925ff843e7c15b309db14b37cf31bbef44992abad5a80966a68ae78c0afff10a5c6ad030b65cfa5fe16c2f824dfbb7adcad0a912f7ddabbee11c00ce1253ef3b8006ff27e3b166258b4321de3529e581022005c5070d8e9e894848fe14b3f544579baad54a39fcf37b31349eb1f2ee1d92e4a57ce4ed49e139d67a97152f084f0501c20c3dcd2caaefd8ecffd19570fd8676cd94bc61f2b05e76262b035a6eef171c1879d4533c60191fb4244e2be73eb178d841b020f6ee649d198cf10d3d07cab84c610b45b0a7f4552b9595e279ffc118a961cc7b77171a0778f3b038e1d92240060dabf98d7b95d4b7506fc0ba7f63a8e973db670467c97be2302a723cd82352f82b15481926181546d2cee7f200feaac994194e55f87036b73190cdbc7447e03b10cd469c410f1800a2217e05b107744b998e3a0bb8cb4b7708e55460c3798bb7c38913749dc027b78ddf2f0e9cfc33eeee29e1d22feb9a0d07075ebc7060c193918c57091569533a8fa25ed1793e7e62111c7d05a0d8447f04c361f184393c350486982e2aec4e5265a91422ca9fb3e4c966804b49cb5e4516b18d14392548e5cdb29ac3f30f49df8b7e88cd3de53378d1ddb37947bacdd2c868136fb247f33972369d15ba2cf0350d14f14bd5dc2113b0c18bbbb6ffa541f3f63524578cfa9af595ab7550f593efc592735af92114920a0034d4049d40c43fb3db6725c76136b36d687ac8691c3b7367c1c999ce11c4ca65e7d25f17945ac686b02c01edce38d276a6e9a8f2ca669ecf34ae222eebebadd261fc30bae4cbb7247702666e60de491b4cff0379304fd2e8629a67f935e3e94b56eff87bf14bb9e82266f590b0e685b365e09b2e79ecf528f84c897583405e5677b7081cc9d442c03f05d491975b1d50888e164f8c5c845590f3ea46e8cf9631a7708de68dcf92e01120fee4854978cab12504d18d83561d14e6c5bbb3a1cbea863eb4b4b9c8a0e3538b01061f49d1ffa06035fd3d764ec97f0b6d1ecf11e0783a48025847555d3c1c8383fedb2341585042f966bc317e585b3281de19fe5b3328da4486be837b0d8d0c3dfdeb1bf19e43911d2bf7e79943e6c6fa72e4d0677fee82cc47f3edffa0fcf0b11fe4ab9576d7370e8994a4b922ab7a88edcbc4e994be69380b2c574fc8f04ea3ddc544fd07b1103588629eea17c764bbeee3c9203c2433ac37c0cb509e934486a80aff1935ec31909769582d1a399de83035bbc90855ab7fe81593e224c52801ad21eb182375b4cb2572046f424830551d2aa120bb026001410f8af70a97f95583c74ad72180feebcba9311ad61620884b9bbebcd17cea1ce5d53e18e23689cac9cb8ceafeb2a80528ec8116586ce79f44bf12dc5f131b32be0cfb04f27575e3dd4dd646c5a13716bca98e98b099dad5b13db4b7b3d6ddf1081cd7345f57f604a9bea58ae5c8cd9c385183f9db1c041cfa5a5805658b61d4cb329140570faed81f9146b2f7af38a0caf565b27ce3d653799f1f003a4816861ed06d6a987701dcd006263541f143cd1a015b3c63187b3a276ad05806da6ab772aca12763ea0321465613e6aa823718210951779c36917905307f87fc728e9b28f3f3cd5380e7be03931544bf0c98ab42b468dddb34ef93ca330592f4a29e349ab7814ca91849d5977fccc2d131a08beb2b649572dc27b40fe77b27e7f22407ada4d186f3dbe8dbb7a05483e93653b7fc219534ae1e17ccea7a162574845f4805308d3b77dbb89c3a2f26f3a0e5ea16f9a2894ab53512651cd878ff13c500401819fdae33b215aa57a35d4f09d4d7836845b7cfb0687b325b023ba69805b809fd15fecd62727f75efcf91bb6171a8ebd90d14ef1bd2689f3908629005790542900b66e075b721c09226b10c73722ca3bc85c22b4f593d73210662561e4a2aa163c4acf260ea74bbcb6aee52dc472ee06ea68042c5f9032e03287b892c71970e5a37536008bb057d211ccc10a8c0306561fc2cd2716090fdd20c4356f98bc37673f717f1fe1781aef4a7bb69e8aae034622cb4771bd5531d7526a65f1084ba35679190e0f6460da9b35c34ddf2bfd90cb402405ab54aeb9bc937fa14cac23e925cb76368989168cf6d2c81b2211ad7feb867d1cd680f2b316f5fafb44d7d30669ae531ec5d8b9cc63cf62245acef9ba7a7800f4b522de4788b1c068ee7c57d14ada4fda4ab5dae1868a4c5a0b6e090b47188cc02b0479cd97c652e3fc898681abd5ce40c1b689d4b9f3a53f64f8d2559103b591b763b17332bd85c5197d0902cbb45eef170379de528abab91a31728693df695fe621a711a4fa9c1e56bd69107770325de90bc6910b5b9c7ab7ba7026ffe3975fb37d36dbdc3e9ee3fbaa9b00156462ace0781c58a1d12f051036e92cc5d64ca08580dc05c9744eaf46ccf5ca31124122582297f49d319814c01df707a956044cb33d77a4ca565f3cb973254533f5b998d291fd7a76e658ef2e05e62e2ece1fcd5720a9a49d8710b4f270593620e8ab9b2393914f00e53eecfd451caf4db2832b35faa2a7d03768bc1517f8a4181c265705e885e51b5491b2977fc0527308ac089a518643f25814e6f26906417ba0de9eca44726f4cc4a041dac274461ce2e1cc840d0bfdd6bd0c2cd0e68d0ef13dcf2594c1c4ceb003d860d75346e8b78dafab983c24d4b8b66d041fc2dc2c02132059c911126a786695214c2881fe579dd85298e2b012e8761cc702a527a1d5dbcc84be6cee1bd58ed57f382b004d18180c14c99346714c49b8cc779399ab55253efd4d76c73eb14d5728e2828ef70f5d05db8a2d01a308d3e97da87b76dc72a2a50e18fa06792e4e191c50633bd41d647f330b76d985ec534c10e32bcb3f9771ee439187cb40f8b6e4337f4e897af0c5a7a4511e6443dcb3a5e0248b703968923789c65064b928766ea90e4043b2979e22936132c331ea6362c7b973af2161bf2f8b97331bdc465fd1522c52efb826df464863145cb9f345d141ab0212ff9b662440eefc7e42056b51e6b70b2e07e0c5fa6f00c1fe1532d88e2c0e7eb3468c67945ab65c1aeaecf032656e0ca8be2c9f6d31493f62fbc6b952d2eb4d6496dab4977f1d6a85b1e6cc69e2228ce36179f50df98fa5bfb439c5eddb06f2cae9cdb41fb320e7b93d75a00ecd8176fe29ce448af76bc075500c800455d44a627d16d882115481300b1c51d3d5e75a4c124df192278b399d12914c020e2deef5555f8f7b3293eca93e804f2d9201ea9c05e1510ca29fa3edc0fe5c028e8f81a8c0e307db65e7ae6a6eb2c0e551bf34a8339da6874a0bf424e45f75bfe6c9ac40e4362e826bea78d46c0fc20f43d35bc8e1731e71a57cf8dae988014769a4c6ca56a4cd3a3395dc530cf9257869756179e4493a2a33f4b7dbc35085ab52820d5c5b9b12f1695e778f63da78eb4d521d279ddef5d9899579da493899bf75396d1dfa2f75999fc0a43db37acd8cfb7f1dab0221850adcb3eec9b0d4e602185b80138f837727804948ddaff1b9d7e5af93ae6f0a637391656d43680ace5383f7888ef445ab2d7fdc4c77e0ba0237919aef1d92361ff013ea2fa618f0a3f81f77e32273c8864c975d133da8ffcbba08ad90223773121d8cdf84cf582c3cf3c4482cbc5ac0a1a644211678715304f3ea0937cf0d3a446315aa94aea3d25f65a3aa06e959168f98cb0be26c67140308559a972c29e1399a97faef8d8bf7541be4656953c95305cbe2a1827a2ca1b61423389643fa7e362067b4e43b189f912b1751fdb958a252d2ed99399b61950c20bcfc3155a3e866a9a463e5bc496199053b0ae3c9ab92808f643e21ce4421c5650411832197d73d3a9914b315f0b47aa3ca33c775a53a3abf0b19f9fd9cd3db369f6b2510f055b0df9014665a9f57503de60680f6be835444bdebb8b3761b9e45456ef614f0d956478a49a70056501d3534298bca0f4082e589f0b44498451912557a15e048ab22d1395e2103a2314e7e1246c678a035f0283b802367111dfbc2613ecc99bc1fd0ff2aa4ade227a0263557f904806ae704003c0d4454c9b6057576f5f0ee35e5a21b89484bb8df8f1af82fb6e1b53992b81171a3b1ac67d278f62a20a3cd22d02040de3ff2bd85cd4bd9db26d5fc507f406d3795fe334fed60937ea000d831094e3f5fc44264176d43046b53badcfe3002ea95c3c21138e443be4304aa3956ac7c5b466cca50affc0020d9cdba50c6e6d3febd27b8e4ae9a4339f149dc6a185f94b7af38492e2ac1b195705d919672efd99c58b9e8012935cf119352435f17e13fc8b035fad4c514c5ea7f479930f376005366f7c61f8c16fb06639e062ae8a6c6e4852a05a3590176540d66af0943a3bcc37b03ff1f5743d06cd0c55db07264f5ecc74bc60c71b5c9ee307e7802a1b72822c105a0d69f16e039638e0fbff6c1156ca073ade57fc81d7eba20624948329cf414e267d15f21f428edf6ade52aae8bf012df6334ab395eea1040a7801b3b74fa8f79f429d6a404167a591180e4ec39e197c2c705bc09defda476c281d9aff26d8f32b7344fd492ad9aa178dfd15cdf8f4662a5bc59f570a30197969c002da5f48954e0c0af9ba70b38c3e60845196e8a858975537a618f10af165d6120ac003a4c21091df5498b9870b167b0191d6cdda69eeba7c1217086ce40fd7c45576d5e176a62cc2728ca3a2005e4b418334821e3c3b139f55ba095dec11c2774cff69bcbab009831c030c9cbaf714bac6e5ce3b246c84c8cec6a40139c9b94b4bd5ca86668d034cd885f9f83889adf1f1cb93a7809621b1b8fcfe73a41917e592472af3d46af8507ee93b5d9a0637c6f3f4f644538e2a4ab1050f6da959fafd81a6c4a8c86c75e11bf3da6f0f13c00178c2225138a1e10eb2148d29f68c7040b3a963f9a4e6cafa5ad71c3a193c1c9835a9bda8c099b0b721582d19c03e9c53ab2cf90aeacf157c76ddb6c3abbf48a931bc1dbdc66ccde10066a6e6bb18de6f1797f26cd3596743430170ca17463289f97486719d1fefca6363d61d38666facad3e34c57aafa0064d75b5355eaf487e3bf84fa8c9db573e3f081a6aeb06005dd30b05a996a49327940a0f9f81e07b8a1fdf4e1d7f2b61d7682de49dd9f32c6222d7cd07b40553e5039a94554f154a1bd82f87fa6414260b70559416bf5912135476900e71f2346a3023191513bc31127797b4f29c1245c250c65d7d3012bd029415bc88fad8dbcc46c4a2a3dd0cea0d9442315f0032e272b123ccb67e5a337ecde5c5bdaacb1d60d1a2c9c5bad8b53de83a89bb70a65a71216705ed284546097af3dfa1646f7d35ccaefa0cf14234b400fb9e6e13328a470e1384628ab86d3c46c9a5cd8e644346b9811408fa379d8c12c5e801509438266e30973c88b590e01884c4500c751f24bb0b217c650803950402362a953bb14084f6667548cea6e04ea85b525a0223314aefba9450bc909dfe790ef78b2149000fb4367d88d0a946d3340370f94f412ec0a733412dacc536f76b7b27895e390f07f1a9c3a5cdc793bcd26dbfb944a01620ff3a3810ab158c0e1a503e0db63dd98075ab0187441a38b1cee0dd9a889e06c8b3acd413e3f009b1b80d56e59d428af2984c04ec23d9a1f23e2442fab240b4b478bb184c1956646b7d8e249ee115a07e49c7b6e4ae8655d46f167a82faa3e5b646bb212a69071040de6273eed7b6f51f1de830d8b5523e67d100428fafc647e56da4374e36ac73fe2399b7c3f1ee602ff928e2c9b05231c7790009987217d522f9f4d51c80187d5f7855a352da8595c9b06439cccb0f65360a1b0b3b140952c0c8450d00b01ad4d171072a8a2d112871947c55e5f6741041a86ce0ca9834361ba18e043f4eaa21507e00c93aa69af4c79f8794ebe854bd6ce52e3a63a8015ad65dfe080ff5ed910103e365067a02861662d57f0985a416888341cd91f7463b75098bdc26f98e99e459a857832d0e1152305199ff76212adfe0b1331503739f21ef3004e53c84a11c632d07b21a43cd1bc178903d4cfd7b84631edc47225953594b66fd48aa2a130cb02c3bd7ad1ed3b19cc39a2912e23ccc42496cff022d674397316043fc4c8a87fabfb358453182951096b5e1cdb6b6f93dbe12492ade94a11de74e482af17cea541eda28d414e7b1099126ad826542e8c35d4a65922312c99ed3602b6ed4d6e1f62c7b933920b2ca24a7b1dc796c221e258bccabc298d8feba2156186f81ec884389f3a18a9e1d06106a73aca64822a0677368d1db58b1d85b9c35bf43f7bb304056efcae81d7fb0be4e1a273da000bf501eeeb950fc9b0c7a74cd7071001ffb5e48c11f3e1b7351bfd4687c63dcd6e6f9aecc7f4c61c252e41806081072512e65076dd9eaff5732442b2ade0a56e94f4a739c048459a391e3bacce34c0d7de7f806692708a7e327d9378fcb3805abb3ff37442e9776cdc8cacd62e12265abb130ec388a709b90b14a7a46979527d4a5eb52f165e5b622c6acb7d0b7c057563fbf0e98538ff48205debe711c230ecbc1e53edfce4540801dc811418b8473e9045d883a3190069797ef80723a430457618007711cf830910c7d13491b682b5be494325cd06f3260cbcd760802bf3f9b417ac20ae7d27c6fcd511a6769bfb32bc42bb273b03328392c82c92697316472c4e0634054783c095229cf8ed54d092a67db97f2b6c3c0b55dfdb05191522dfae0606dc588aacc8d1af3d8d286c0488a50b10215e3e914ab146a42057e3ccbed9c38dae8e523ce4ee29a718e146fbce511b2b1c2e50d50c4076e3e966f37934330085859c96e143336f89f30b6040917d92af9e16af4afe9931ecd6127b87b001ad977c85884a60697c9f6e0e1750115a3d9522e4e609603c236ee3241784eb113430dd18259136d72c7de1d4eadfe6b0eadb129721f3f89c835141aa980813beb0ad86c68a0cbca3aa01ae3049a7ecae1e6b1fae05bf9a215822d6bc2bb99906803554cc6e85bf0c169bd21db5d7e5b0fcf16b146f681cb14427953bc7af641d05c92876575f0822c7cb2c76b61239270c82c33270ff4de374bc03d3effc2e1e7640d64777fe101b252f44b9a652b41ec24a6c386e3e08115dda848a91bcd57473da2cd1e668b231aaf6b3f92cc11cd7e2001e833a1346077662157559c4bc438238df0a59f437f8e8cdffb93211fdd4873291e299a32d218028ec0be9014e8f1c5eec6d9f78ed386084976652e83697dc1701c350c5b2fd52ef8f2078edcf37c745f09f9dfc222178f68579107dc54600cab80b2158319f382d53eaf9c79724507b56ff3cdd1c703b374767fe4854f00cac09d67d3c7cee22a908cb5b055b21b043c4a0274a49d60a26583a3e4d59a4b0e879ca64435028a9b4272a2d9651f76689580ea4c5536c170b16f548fc8d591cb30cb38d93662e70f2ccaef77408dff624e7b54472163b0356b84f8230ca060a0fb8d8684d08978aa54452da6107d5df62ad7a42f0c6a42a665f2116c59b5e7da009f60334e81eaa001548d5cd4de64b10bbf13615197338f010fc8b2d83149f04d3036455e19b18159e400e00d89752f82a7e92bc019cbb97f64c94ed5bad2a865fd0789a95267317428865c6348fbe2313e591a400ed46e79152f4f0e8488e860139c491a34382d12bc927be644f3b8addbfc4fb16f310acf8a63b583413e6ac0be1832bb0d538b04c5921b57e71b3ce9234a05084218a8f4430267ec58d49cc1a9a5b3db298430f99250a250f13f85fe8cfd8da6dd3cd7b851312cedcfc7b416f3416c4601aa8d005a10a8549b0209c4f488998772ce7bfa0183c37110b2dacaa4323ad583158dea2ae5b7b596671d68f91c717c9920c9672211153fb12e93b18691ea5048ff648ca6ddfe6eb4f59a1344ae85051d8ccb7c6503868a23901db5e779aeafb1c430535ac49978e00261d0c4a0858c5015e7bc37cd42a328b8b33b41a860ce54e692259a71ebbfe1788c389ca71d167e649fc3b4e1904bb59920b23d5f60dac88374e601fe6832d812c3528da34cfee8eac40030a94a8b87284b9e5db5149b0051d48089b914ca94ce71b8956c253d6fa252e2cb8257aef138f747999a204971fefce6827b299d9f64159a2fc90c449c36bf0e600952ebd5c5bcc4f7b367371dcb9470e003a72de8a695a483b6171d082d87e8ac1749aa179192223c9d8840897f2a95acd4a189bac9189421ca23b2c650c291d549c6ef492641180f5e210ae48c460c007fb4dea86d833690d29a694906775508824994a7c8e8bd3ea20521075a4f37b5c608b77496b1932b5dc6ac379a798f0610c53e303c0e9d31016d5ccbc38b035ae03a6d1aa5bedda8f689a795bcd2bb80f3779bea0966d88ea4ddb0e3180519b8f3f8801d40c482c5bfeac6a28331ee20e9e2d6f1c42f45829ac700ed6b9ef89dd1e34f2c438e24c61d4c740ae2ffc2ebab368fa8dba41e9d48e82b67278d7a64f7dc76cfd2f068231f7a7ce1afcd840d7d3e76ace5c17958cff00336e8a2eb4483cef4e938a35166acff957cf36358d4e14a001f359083ad3901bc1566692b0e006269f2efcf265095dc428e421d8d9474e46462935d853295095c798b787e75cce22bc5b252d07c33420eb0bfac12ab2df31b56a7ea5efb849874210b7ab0fb8c66de76e113b1b9c6312ee234659bfc8c5af83f0989fee4bd0c19df28d480f726542193175d80671c73232659dfc91937d6884571b3d12e6447c9eb6fde9ce1c7c85d72b1483549ca4cc773affe03be933730c885034124cc128bf2c90ffab2d79e1a1c00f4ae826951416648d92921808794b5db1966a1adea1abbaa57acc144421e952a55d9423b7c7f64daa76ed9462e6595dd16d75cc4c20644a1cc338f960b0813b18902b4818515703ab7135e1cbb24feadfeb3c75c812764ad58ece56c577f8c1c498db084dc27d77a7fd81ae3e8aa9474a47c468b5e999eb904741074a6149d2555f452986483bf5a660aaa021d9d85499b34c8020e41cf4d2a46e2e8e9f35cfb24f43fe26e43e019d006cab68cb21a43fc92a03521ab988fa83f426472da5bad56421b6ae5d0f31cd75b2c27b96708c71428321313584ca582f6553658f22ee774299a4d1c567110ce726f2100e78971691e9a32e40bd176140c8dd61104f3c35a53038dc41c8644b159f5c63b5d33ec0fec43d4ee99fa43f635e035187443f7c882f6132916b5bfdc4ea14fb4ee79e64f379a3a5bbe1c413044e3777d4562a846f8e1dd4f503d8334988c8a104b08cb44071155f51bc07cda13a6b4b3bbe568588d19d20a078d2e823ef6692a70202dd398cabc4f37cb6fbbcdcdbd4f686638f6c47ac0453ea8e38060080898b0e9bc4c827c4c317cda249bfb9218c43ed5d31004e05d5acb5dc44269a5d5fbfd2bc2878a50240e6581e4ac60057f9f88d6c17dfac4c31eaf096f913dd1a8eda7141f48e02f691a966551149517a27265415a06bd1ef51d20d83b68c565c11a414f81c385f3024352fff5a73e491997a29b021ec1b62629538a7004ea07f8b52173997c2e3b1dfbcad5b20921da62ce93d894bacc68859d0e336e8ea202224353b2ae4525abeb4a523b929cafac0ef9bb04085ac6639bc5f9fa44dfe312a7c6abdcb605c44f7c0f54a3aead035b9aeb540a983b2f5aaab12de6404cee6e894bc83e5f9a80c6a1a4da5a0dbb3361db227e5e37e9887f5af899040ad278f2732bc062b8915810d32188f6e598297d05bca78769c0ba54920e652ee0e10da1da0eca44eb349674d09f9a90852195e2f3e2fde73db01ab381e0d574c86ca811430bf9ab36cbd10f3e3afeed4a82af67731037766e104fdb909c3e9a55c0b1d0c889e1965f3598afa125465d649e5168bcdcce5f1cc583685f03c2e843e3628a9180b22ff40a2c0c95de4064365ac0740333f6ee941977fe8b099f21f4c599956505693b3c2030e8291c69f21345401c539188864ff67c60da2019cb9d1c4aed0b8483b0d543c70640f3cc8f4537094d024687febc365c8ca4f01a04bd968b16087d9496de79b044d2a564bf356e0c921edbca4ab10c242d628679e0149975e4f80c868bda4fd04aca30677f05fa386251183385618eabc9b5f342cf20d6868ede4e4033cadeb824c6a23d9e93078380328a0c492408b31160aec31d124308410b5127ef1530121868fe9942fa68e7d76692676dfeb7897023e514d4e0ff492809e3e296c9c9c02dafee7aaf78cef21b249700c0cc6b9005e22dacb944a9060bbc60a87ccd656d7c8c05495e1734d088909b4226150cf53bdd725604953d7ebd73cb214e11dd13c10a35ef37656c2ac458dc964d9c4484f3e9a4d970b20a1a7d0a27d530c667de6ad4bf893bc2a83895e0e49a0fd3901df554060167db26bbb4808bc41c93cb0727caffc04b41debbc65b3a34bc90385f554df2e3db08a0f38b73f1cb9c9f54804a6d9b1509960e5447b0a7e92ca1d2b5441b793fe5a925a13f93045b80c0c88ea240f3c6494de30c83e09ee37703ab630d52a15a3875747774314d50accabfaef2b3deac8fcb8caf6cda89f494d984616aa77db2db8dbbbd112ad4883bd5d8512ade508b03894f5210cf820f4990f2740048fd480d030d3d8c00494c75202c4537b248e7fcaabe6b6e456d0583a60efab022f3ae97f085df60bd10ca9ff6af94076751f95997a47e62a797771817c9a29291f8800a8c3b99df6106381b27ac21903537c5356082d8a0addf5f0f5d4a7a8ab0b85782fe0dcc015af96d96b3eb60dcc2d47fb9279a824e446d4897abf3465fc479984dc317ac24302236ec1321404f5b9d22db8ef6b747f665ceb51d402fe5e7b1e826b421e08f49f2f383e6d4c0b82ba637730966eea75190be7ca104c46a07a3987c1567c3432024823fbb8e0a58bd3ff43a5c47ae6b2105edbc8c31d54e6c4dc80d0fa1e460f5320b5090370c2ce205a6b2eb419798aa1babbf3444dda4aca32412b76853c21900be55db3750099a0381f6db4c747732814972fa8a80d434f7a10bfed60cea659f1a8bf17f3357ac421da74f62d05babc27fadbfa694cf27c47283f38a680a801491109a1eabfb446c97017c8d044cfeda804753d7ce0228e869511c405e6dff30e7631b33fa47182e5ac4e8df4f7b27b1d37b1155430085153420d0271fb329c1f099149a4bf914ea709eb83c2d518f7888f090fcb8e4150f6cff8b25cc369e50c52b4b0602b8e679befd1f6666806d503bace1adb534db3fa0df1fa0d51f07ffb10c24b301fb85ee368bd95ef8f4061165bcef681bd1cfdb11a73f5ca22e0da68731ff868e6f61dfba0c0adfb4eb07b376e2910013f88790b127aed92dce9de6537fa6228600f0504f5554958447a0a49e730631d0f6fdef52b71e6dff57f4c3b0b04df6f3cd209bac92791f73c5aa25590f00c2d5b383941a478b6ddb9dc04d53034747a04542a3b65521d6531ccba1e4f093eb40353547168e318366a855bbb6a43f5019a004ed864cc89b1967a700dffd08bd39e77bbaada98c568484a25456bd296e79dd8379cdde1b2001971c0e9835a276618fc6fdf47a76f8a8721438ed1e687220c1182bef5db999f8fa2c0bb9af5d2e42bb0be554f9451f74cbb62bcf46d735f388bf3e77f6deab4236f41f6d1b1a9be5df34c42f859817f6c0c8adaf32f32a05e0cfd3981b9a792481333a2cce6777277c7afb3f4e17cb3f864738d9192df86044b396f4d01d9ea651d9bfc5bcdb1589fefc603e3d17247a264da28834ea5ca2814a8d57e2ee7d0d4726237c659f4782b90c60e01f8b48aff1f4d12e6725f53cd6c09df034ec82ee44e6192fd1a762ad0dcdba6cd26d25faa1755d505cbc93f9ae84c28fd79898e83d57ab30241f485525919096160e0dcf1acc5556539c297b14833edd076a105594306ac3e9fac66a9a2e5bb5d10c0b2bf5eeb556dc59c5762661dea4d55666e2fb3e152b0f35444fa7a6e373cf4a17fdf1b3db6913115061545ebe8314591b808a44785ed731c287c0d4abc082b4c8e9d771b5479862103266fe8cd99b9d7edeb4838e44745538ffaea7637f3580ca232e1c7b06355925ec09d27a3215f9ccf4a8ff577b8330c411ee2928c7cf5ea236f044829a2dfcaa9fd4c7d134407f3c0e0b1cded24f9a49fa78d2ad95d6e3fd5c48fafa018449f3362d58d653d10f380168779fbae8e82f69d028bd009885722c3d772d48272b87f8430036f64fca7ef4e5afef9ae27a0197215cde5c7c051280d5dd387dc078741f8288d8cf7b7ef9fd3d356e8c3a28e54bf938b464bb288cd2d4792a699f3e94172ba9b3bb07939e06c64eb794176df0eeea0165456f04425bc96a44fc7fba2257721014c3f50a160742caa0e15e7016bea1b84c45484b4217cce6b18532efcbba1578c275e14c313021ba560ea92bbefa7446fe56682a6cd5d4968d40db4072891e2e0cda2b979d7bb97193b294234bd1edbca55c9513741a1365d7bc70cdf38ca7930116fd5ea934115435760696408e552ca9f27bfbb2007e4a91a1e5960f4d5a42b70d74f9562abcd9826c112c1588d2b0e75a7a4850add6e19ca8f287d17916cb8d2a365f4ba12ae460d2c83088df373b07ba8ceb21e246e7d315e74d0e47ff1a04ffa2c891a88c6629cb904296620f620c14e45f8320a11b2359d9e44e2733e0d00dfe72b991be051d4237b66c553ede1cb1f74208049fdea358e941a30f60d2a2710d3e2ba86dffeb6edb5db343ba51f151828ee39fd574a9361b34d4333ee97e1765bd47787dbde1735459c873073a536c94724270cfb0d70c7514657cabf665823d1cf5bf6042a2c54f23254217ccf11a9a8445fa021b1b12a52430a15fee3ad3210e8975f67263ae3f804a1e8642d4f72ffb0c232c595d4234457bbdfb92be60ff1cb6034af0470813e38703d83a0c91297d6777dcce69befc983e7f2c258fa631fa535cfc4f48f5c5b9c2bac166dde09f54919b4b8e3a10952a6e30bd7e16e84296171f6059b3fd14467073016c9b8a7c299586f9983fe99e6050dc3bddbe4f55a491747dd8e9269530b16127fa3a99b4a1a17766a51650aaf1cecce874cc4128c3cace9025fdef176cf071d4975c60e9ec1379c7aac39a7be63c81a98b1c828b5d1e23cf0c40c1bec03239b795aa22f4a73d3ed85f17e5c821f905a72dc6564bd5e29642eeead79aa6eb985bd09a79e0c9639f50f35269571e5f3c8df86074f8ec043b67b9d9c5fea889860a9d74bbd11347e66402a20ae920e9044a321c4a423504e114c9ffb85c92413675d26c36ef6a620d13e63453cbe32e688ab055f2750c866b2d2c381fa83875ce366422065188ab3d0c8d7b6c50260b8a74e605c4aa062e0309981f491068aa560798178cc0170ff0c521bc60b42fb889039a91f4652a22ddd5018ac6939635d900fea0944cbc208d9762aed3e1daf2ddca2db7bc5c824333aab89544e0ab2c13f6ff4f480a06226e21801eff44677650e215e75f40c8f23880c1957f6915d9a3a58c16efd52400e1dd20f75f0f2f41542002c97b55d80819b913c1c3c6648123c098d7bf3ac88366cb01e507c56b78a166089f9fb90065c1174644f1b2164678020b32809f5db181ab03aefba0ab0152ada6317ef60c6879e18f0f3f7baae026644bcdbf0e06ac3103eb858f8d90001153841278990e497038618aea614354b13635b68fd1649c00c610c2c3863ad9466c85876d608210b823c27f02d628c247ce9e9f512084045a411879212322e8c20d0d3b3c4cca539921a650fdd0ae721a610e9bffae7c185104062bfc4c801e02e97007cbcbbab0f880d3c4171f235ae2498e6c88ff5040e3c5101380fc4c37250a1d19b27ee626a7154115b68f5511e888181364ff4d7441f71b3cfea59543a90b10a1f7d6349913859ddbe758c1053abb3c72be2882202d7aaed8f1b239482eec6cd0f333a5315a00422ce25f66542014c54880f7a674e8608a3047fcec8724144a9599ff9b1f1b0f2630782f8b3542687210e2ffd623011e5318f817f28267027ae365483d460e74e4fee71442c84206ddbf542f740a4c7cf958153b6cb9427379d80141b429e3001b2fb4a5e6f0a7079cf774d862a0099adbc352f8e1cdf3898f638712403e7230f03111c400e016a8cbbf8240b041841f45bccc82aa0d06bcfb59a8028901fdf45f1a476cad46a8f899982ae4a879208b972d018b0067da7f39948c8cc147c9c3de20691ea2e4fe8f8ea89d46ec1e0795ea06811efba21774a882012b8b8fc5904270e665e061350e2e54b0c5c01771c0670984055a7858d7fae22108e93d29d2588184036cfea7da5011482bccc39a04314480990ffecb2882ab8c1c57ff0979cb0ba048e05f580bfc300493d77b40bcf9018d25f2fccb032a30104a12e763503eb8b551948ffd2002005858f1e267507cb002040a38f1455d746142812f7c7898186534e1e046fc33059ae478c8808087d5b8299dcb181fab92e1ea84374e1f9ba20c8b4003819f1510841606e420780f4d0c22f8e043d5cf862cb0052024681e1654e48d017850f0b2a9162c48a2f7fcb7c40a605e38f3fd6b8d14287b8a063e0712024850058a343f548612553418d197358942aa20089a178a6148156dccd8f2b22c322ac8b141fc31a32576d050a8f2b023ef02a6a61f7ec645288713aea0e13d1eb8f02345102cfc97b544033e2efc7818932f491c3d10fb996d86344160af97fd0035456a287e981a2aa4217bcefc6b8835506f8a207a9911a40816d831c5bf2ab0608a29deb0fa5910544f4202107a211078a47920040c5e26c48b47115fd079d80533c84fd0b9e061a2115a1afc91f2b20e2810220e1519bc8c49193340a004f7ef81101a0461eb3fc9161a23b2beffa88868c3450896ff5ce81fe4392385f7c8580c31c2e0f899c7645cc08609fe2bdf30134619bfd02681869950998719e9c208a01d433c5116183480424b8c0fc201e9835f20f7af28fa1502a8a87858084841d808f1c4c3c204615334e688872599fa428106b17f2dedf086551b2fde73e3829c6f832fffb2c1083eb5125cf80f45a1ca4f97213e065a41d32521e0675ebea8354fa43c6c802e280800d5c4cf9860d3c153eac0c7f6f02172c1951b2f5405544c072dd4781d9fc64d9792297ed604c83ec213f43106b02860a6c70f3fa36ae2c501403a3ed6038bda5ac5120febc286386b0a441e362726c2913b3fbc2c4a101d0b18fdb13137ec60d1c85e36450841a499dccb8eccbc36e8729f680a0748a47798f8d9095c701192c5153f446489253078e2fad817289b2658e82fbb7233829db6c8cf48f0a3020f74daf8a722416a4bb1f4de14301021048e32ff55d449628204c27fe57cf06260e183f79610438923b410ffd5472a0d2603fcf0efe2f162852e35ff5d6941a9d7a8f2b3a50c4a188f547818af61040918f0e1850a489d5072e2f14253320860c49e247e96858e614815f687bef0a1400a041b1e5633610b0b58c8f3af2a5d70b0a0e68197a931a78539e9fe7703c80c055c70c1bfa028e38c12346adeabaac345930a2efcd746191c6c41f0e53d09d01ca97aaaff945c2d4e32cc780f4d0e21445962861fa2e04b113de2234fb41be38134d62cfd50201576984e481fb405861474aa9efed3032548843cfb631fa0095306011afcd7de62983fe0e15f41e44476eacdc39eacc943e5a982974d50000e3e4db4f9cf8408b6ecb0d0f031d100396d3c40fbd8922e689051c5cacff4c4805a294188f78e7411c29f23facf3c70ad90c14e8e2f1a63f5801dcfcac362737c100a437b1900b41fc460c9e26378ec5019e382f065650079a14d1f1efe4b8209470d5a8cf1311c6fa8c1159d877155b0650225b8dedb116b604c09b7875939a20d253867de238fa8028721e57f4d4903a0b10599ff1992802c417ff0afc698302082a60f22d30612203899f2b17102352150113f280d22a2262a2f7c101562cee420801a5f34010f69bc6132ff0b3911211366f0af28c6e8c1c9d1021faba10771cb823d8eb6071f358cd0c10b1dd1bdb86204939fadf121ce173702bd0c0122eec48740ff33fed57ab6fc078614500b12eaff1b25748131e08bff6218a5c0fe00f03335158cd04585839f9191c01c1a8aacfe9510e10f9c201bbc8cc80007e4a083e73f03721bec900bf432fa4d0f067069fdab08287b5e5d57fe353595a5448a312fd38082242b94c1e55f878e4081c030b520f2af195c38e12a8b2eaf430a0d57475b88b18b8efcf932434bbb2634a4c0cc71bca5faf7b4c85c9ccaf7e9b2fa596ef6b08739f17e46c7736346deec7578b11f5e0e2f6884a1ffa2006664f60505c5602fcf7b201ff8df7b08c00af07ec624f63a64de979ef7faa478deccfb3cef251bf3799f37fb7e5cf13c9937fbcfc301be3e992c69687bb0ef83c5f1609ef70d79697c9ed0c73cd8f7ea9e17e6f3bc2f08cb47e4f33e19ecf3c0f83c4ff6790878403ceff505e5107bcd72783f3ccff33ef5f311f4f236f03e4ff679def7b2791f6c48a8fc8abca6202f86e4e5c49b7d1f4c7c0d7d9fa7a4e3f41480894450afa9ef61ff89e0c15e49b0d8e7bd3e56817785f7dfd368b4f7de83799f378617f429f1bc2ff67d2fcf23bd255e9057f47ddf277be20df07db0cf0b5f209190a0241e8e1d43be0bbcd827c483792fefbfa96f0f79b0ff60d96f2bef81d71fe5e0bd013c7c2f4fe6c1661e0eef25e7fb826a2f2f7d79df07db5f91509217f3bc5908138f84de37240bfa669e57f3be0f8a97cc13fa60af2c0fe9db79de8bc91322fabca099f719f019f98c7c00bcfef59e0e4ff67d1e0e18ed05fb847cdfe7c93cd8eb0921f188629f17f372a044bea81991d0e7b14145b3cf43c00bf2bcd7e7c13c291e009ffa15f988bed917f35edee77d5ecd03e023fa6630ef157b791eeabdbc244fc82bf23c8f8967e41b7acdbc2098f7795ecdf3643fbe1e1eecf362304ffd88bcd767c47bbdbe0ff6c13cf5fbbc21df9027e405c13ecff36a1e00dfd0ece5c182609ee7a1db0ba224a8c98b8098f7f2843c58104f48a846e48588112f0098f77db26fd63d9a8f90488ae77ddee7791ed3cf5ef75d16f0fa7019e337170fbae0c3e5288b30b4f02b50c06245155f75f4c453796044a7e245fc150ff46c70e548b682800761fa4cf1d2002a1e1839430a2f12aa1e0459a2f21c26a056e040821e0d79a715de1ba755200ece0de8412b3f4698acec7c4b558c202fed5009017496c83862b58b8e6c203b9e0e0f306f158be0378c81ffd77ff99ffaffa4a711f1e1dfcbd25b184795936728aeb9eadfc312c0ff635160f76589481f1d6fe94ecf20afb96b93a519122088ae99d04c089623e89c09bd0028aa3a23851494241b0a4a61453a3c5891cc06d37ae17819c19a6020832e598e6f26045bc201408a42d750962217b694e3cc571289618179b226387439a102c588810f3604a3a2b446d7166894f039e3c56a46470c38f3c186bc9874de51538c0025ba64b22353697ce87852f38a72a6812e21425a8a7a14f51803e54317440fa9d1d5a4168a6225016d26f4c211c382b57973260896430680a7833cc3c507424a964813c4c605393ea2980146331536a57bc18386472c69086a2889ec0b4cc94c4523830751d09400e7072d4c83a3a5e246872ea2ddab010338461d5e96222f263321e799a1992a1b0acaf142a3a2bc00188252a36b681685832a480a91156a48484a1195db44862e20b0a5734856e381433644b422253042d750901423ac035db1172de6c910900dc598c894343d11ed84060892221b9a09c1014508094c4a08488f224986fc501244c0942b49ce0c058133120789464dcd8a60b321b1daeb142a820db00d9809cd86604b625360a9015e8cc8eb28f623140a6a5feaca2448d0d00f21f4cc1329a232280986048644564297921c3028310262468490c08ae8105f00a0e9029778aff7c5047bc514404a60821ae4380514f8ecc193420921b859a0cc168df5f6d62a812f5db664c1423545e50029b5944c4a2240001bc6c30e81c808838b029a04401a226446670821ea8c80c05a400d001f4544321df4cc70c74e9d1040f080ce0658920658026a90411555a03f68b05dc818c3069b6c24011cf86d623234b313411c54c8892648b053534f203d888682664588c0f0c297ee5a913a200a6ae50082360deca8c2a42105144a58404b16f40cd20366049f33b234393985663215d6ccb0c207164ce080021d70c0011c2b524d4c0628f2fcbcdcf8d880f5d9637c5dc0b8f8ac8855e13df131f12d21a44451129f115f119f9e4f85570a1f162c8c87c43b120440ac080e211f90cf87d7c388476cc767e4d160393ea2d8d0271414f4cd66b10fe6bd3c4ff63874bc88bc6ae8823dd005a32253b2bd591a67682374c56245b3244f9c817920c28014856082cc4d178c8ad08fa1224118e812e202ebf2324254cb8a82a08252d9d08b4990a158105d413174f5f87246087d6d604611155db1405db1a2214b7415d54835740905c9f1cd98c496c42860e38348c80568606fba741ce9387a31192d090a6214084d8c80a074d6e4a5e3d5242884ae571571896c487642d78b483604b64424be3c58116c69082a46c08c8b6c886c4816a6a847510fa120423f665c5e6fa0910d79e14113f3a14b8030b0dcb6090000ac56a4436604f35e4caf27b0a92220b26fa66546642615f391c39311bd62b0a2d7ebf5bd66afa097d05011d86b8665b643c7d490d14c36f35e3358095b02f38284bc889c113a1233a12bc709678c6430224150d0c0a8408364db1f0810174e3461049f1f7cd85d514510677d2ac0092ac7648cb164009a8ea099972e56a4021191c41147e084722e3020032a9828a2071b6048a1ce12308905bb1a0e3da751469f289448620717163093c0972e5bac4845813a6204c80f3d791648010533656c001491e32339a898424cae2b10a035d4f8e205c80f23267ae0e1061b607841053810b4b125c0458b15a9a82288e061081ae44881e289227ad8c1861a4608c101350c94d18709256ca841cf0a69baba1bb51ae1e8a3451654fcb0439e195a20218207ba6b4be08b172d512b939a92118e2288f861030d2248d3dd040e88825a99d472e080bd1659144104103ce499a105154890008234600e8872c2a48696a2d20e23d807d2228b2980f881871df2cca00209124400c10369aeb081f952c012f08f1f2a5374e490a2489c370e6cd1127ef080035c5b778402bd007d6fc4fc7c6e0499002be123e1abe38d9ff80a3d9088e945c06bff38f215f188cc86bc8478416040bc1f423c76ec78d1603a8a72d0700c2912425464c8486816249b7d32592cf6f2fe7fc80fd17ec0bee3585ec7f0ac5bd25db985e31d00ffdecc47132f7b9a8f12683e3ea0f920a3b493f6ee2e4cc730bc9970cd7ce6b776731f07d0aaa0341f4dfeadf6550cf79bd6564a72d264c7f055677d14fd3fd1d37c78ff56fb95370def9a8b050382a01757d686ffb12c1f7ba2f598f3f40cc673af6bae5b32d7f4c35edf7b043c8d07171e5062b8a6bbbb6f6dcd735d76b752526fe79d4cf34842e3417b37ee35df34ed693bfab871477ada8e1a769cf0ca7bcff25bcfbca677bf8af92ca4c3c8bf50d0771ac7dfbe9bebff7f05fd7b4c6633e8b0f3ef55fd7b54ffde152d5e1577d39ee75dab44555315554fd5544b955447555443554dd3144dcfd44ccb944cc7544cc354455314454fd4444b944447544443543dd3133dcfd33ccb933cc7533cc353355313354fd3344b933447533443532dd3122dcfd22ccb922cc7522cc352255312254fd2244b922447522443521dd3111dcfd11ccb911cc7511cc351155311154fd1144b911447511443510dd3100dcfd00ccb900cc7500cc3900d3bcd08c9d33398dbc56014185a4a1a4a2ab3cb6c05f65e1a5a1a5260efbdf7bf87c0bf37f5ef596102021f1568341126a0d1c6ec9a95d5ae0d2d5959ed5afd76dcde43564af5ed0a9ef7aedf8e4bb2da359a3b7142a355d168e5ffa6e17ac7ee4dc33beeb81aedc63b99ddc9fbdf93fa7f3d8d6644a3eda50106d835df6ec76ae198eb7478418bddff5abdab32cbf3bc6ac9f32c3ffdfff7341d39fc3f08d6b9f7691d2b0be342b00445a625af1886a6c859761c5d547c4f261906e95ef3b905b9e69a86affa5ccf32cbffbd2aff1e957f6fcaff47fdc38c7efc87bdaa50f9f70ee83b1ccfda56f3bc5aed98ef58de564a493a3e6bc5bb5aadc6ede87ec56abb1d87e3edbf17f5ef49f9f7a2fc7b50ffdefaef41f97f21ffffe429c7d4e3e07a470447184fcf20174ed61df97f3038ce5c8dc11a09c0c183760a2266700164cb54084d8010832bea8bd40f4e40a8adb973421826598041274809030c11d083477167cf1f09a870f1807906de80c04cd7135acc902061d7870c013ec843860b5ec438a26c5c6ca10657c250db850b19378e2470cee942851e62c32a8aca0146122811a2adc438038717c4c861860f3551880c794108354e2c5c3151c14c902bd66cc94aa0b3c3067a86b0ca410412f6ec3808400d59ec4c04123c99d2c3847c05431ba43db1e45080c106439aa0e08507762670a14989165d2ca4e12749032d5830240d33e07cf0513044f3a1460239b8d195c5045f66432ef8204b18392d22b650e9ae68596d52e468a1ea61cb0c60a0f1443a14fd9725f4ff5fa03788f434fd990afa204c8e226f0ab8f35cf62070c216a5290310a0400a2e361e5a660210f106a91dc215e40d0866386102258ab84012b3c3d372e280c8cf4e0c2262218ea040c3803e288419e20c3e5c44f161a5821e7a30f1e0862d207fae30c80a94c617161a88f30655d18fffd7ede4f96a8b573b86772dc79b86771dc3b26ef75b4df7599793db78671375b69ac6b1ff2fc0ff7ff97f59aef72cbf708ddb5df97f2dffafe4ffbd3c4d46670a9598282e71e002ee00f18107d4c2c3853eba3c7f851b214e5a2e82889205faa180a59cd46ad4cd18e1a1daf1f184032a1c316a418e98c0c25014f0132735827e90224b11035f6841b181c8180f845064c48c3cab9c3448288086ed61020f51a0a6cc0d20382272450aa80496083d65c1e08a2c17c4c4e952a66ff1020b354e50c0898917d830306465b709401d33c1b3d186036174f1059215f10830325831f254606284a42bf8d459d3c14b881843435a20a820a7088711bfd9e0478c1b00f87c304af3ad291305d510233a473081001aaf832dc637c6065458551446a2e01e80b067861d799c8c404504224632d24819896044a9881a4bb009608b0662a2212218236b80702e224c97120c4ce891a0882a6068d1a03587cef25d2941866505048e529081e08291263c888156d8d2658622cb8f1dca54110607280cd51026812e7a4a18cd40020ecd4f0c46e4a9024e1864d6a41a8cc103172304c20301d946f1c18533ba202958e90147508d0706400a8a059a0d06c5162843a85c3b989ae8d45e56ec3025080a74a60863e2591072a63860095c05539204849c004484991c6a9b07a65cc9b165cc7c008c850a36812e3e77c8887307821f5d4011d2c39410a9376c182c3cb0015398458490cb8ad797881963450e53f0e4b900041b42220c78437e1a520602356a3f484f2cc9e4260834a2d44032b496c8258658808025f8882152260846123b03061db4232ce8063b821495c0e68c0cb6ca40c185adab113a0a4780882202268ce0a819c28218ee8c119866b4d8e2020e2965cc694c510daa0f4aa401000b6724c1c00f9f2856ece0ca136761a14a17de83378a35788ae088b2c008284021a941820f24e6abca1233947471c20a296010180055e109274b434cf1c105601b317a606dd1f3244a76822cc5dbd0c39b365759a80c19d1590386c69f26374554c10612db9011a502281c1b2cb842f684910848b4b2dceb08912f513e94426500c18782ca78b17c7133aa610ecb7400030e80e1320497162318177298c2062d0fe054a9624987569833be78b2800549fe0425d024698957041c9aa81242e0bd8225c908552aa03090e0e8ba75b0c4053fdcd4ac1ed0ea144320b08a275256343040ce155e9401629d678e4e2842e3ce5050b783411753048a32695872660178ca4d8e510f1e5b1a7882810707aa2c2085151f397c8038a18134c4344120c4e186d713a0863585760d239640951e1e5c21c66de20d1a982c5860ca156d2080e58c017cc63e248c413555459c9a0f2e3633b4a027891c48695449b12166e3874aeac7cd596485010d5321b55520220203928c69438a22436c9444e4b004a406167698412467517dc19bd07ad24344a9e555e3e5c6cbc51b990043e8982073050b0e1ce1d0000f187e4e7a83bca02e60cc0308084144d60bc6278cd77f592f5a8c3a544a1b949142aa4d040979d0448c8a8610be4080bc000a142850a03e06a6b7963cef2d78ae796e73d570bcdbafbc6b599e770c7776cbf5a6e1dd71bca5a26790ee34dd755cf5ffda9464d364454fcf20fdcaf2acb35d8dc12a4048247fe97fc7ff23f97f2b4f8b7d797a06c52b5bfdbeffcfe3ff733305fdf79458ff3d1a2a78d380d1bfb706cd993203fc7b64b66c36294faa9c9ea27499f2e48a77c52666b171818abab26679b242e5890aca5bf2b627e43da1ff3784fe7f8dff2fb04862e8ff8750fa7f1bfe6d20ff3f0fb7e5f87f2c3ffe9fca7bf2ca7bd76d9f67b98de12dd731bcdd8e15ef6e4ffeb196fe3fcc9477fa03fe1f81a77db77fdaff7b60d1bff754966969d3c1bda671ec92b46d533314979026d9a6a13ba2a2d945347d99aec66031d1f54ec66afbad5d52c3574be4ab99b7e0925a96e725b7da85b5f616cfed8e63390ee6597cf75bbd637eabf7dcaf6219b769d8ed304ea7db51b9bd6ebb6eabef5b7d1577dc96b56aa657669abb96acdbb71ad6da350de3b6d3c786f87fa9a77964fe3d2703fe5f9efb98cdc5eeeec259b0bbe57ad7ba5caf6b4ecfe0dc6b78496f611cdd67b95d429e6aa8b6ef6976b144dff44cc5ae8a63aa866428a2e7dbdb571555b3b74bda9adecd4b621d784534b8f6ff409ee635f9ff1e4ff3923eeeb8eda4c9eeec76713bf9466fa54dc3497babbb313c773a86e91974e5dc92b667edff8ffdff204ffb2ce819ac736f01ffef794c7e96e7b9ef986fb7c7f3aeee731df75cc7e972f0ae613ed7fb2a86eb9ae766f9ddfc3d0cfe7fc8d31ecaffe378dad3ffefe3699f80db71307f37dd6b2e76ef57deb10cd77c73cd72aee7e819fcd8ff57f4ff459ef641e8196c7b964d8bcf4bda995ed2ca381c5fc235f3998571ff5ed3bfe7e4df6bf2b07f8f49cc013c44bfa7abcbe95f3107fc10110575f142c99031f3edd736e3cdb66c9349c3663fc5aa84766c9b09da434864d6eca718121933b23d84c4663fbdb610929920a4d89e21999121c5905efbb71999171361c5366c7f38d6cfc311258684f49a42f4df1111d1b763b8a03468ce78dffe6030d8cb05180c068b6dcff3b0be30de16826defdb31a4fab563fb1523e334b4bd19560c490c19a76fcb643b66c02bccb73dac2024312f2798183230d8ebf582bd603018ecf5faf66fef370944ff0af3edd77724e6e534db44445ed6b765b02331419cb03ea4fae524dbef3484e4e190e23905c18290c490719a2161bdbc97b75f470f4312f34e3f45c74783b7660d6c7bfb3b4ac3664dd07f910307d1ab28c791f784a38c996f0721757ddbdb41df37c3f1e158a06be8684d014faf4d7494868df7f4da6b0a78826d1cbbea55b4731cfd13d1110e1c7b8868b3f19e86b6b78390ba849e84d2149519da9ed010d1d3500c0711a8d99661cd90ea707d5b865487ebb50b70826d58511052d76b0715e14893631fa521dade1052d72b4d1933af4d84d4f54ab36677a1757575753dbd368ea332665e3b0752d76be340e055f5dadf1e3a62e33d0d6da12336de93d0263a4ab3a680a7a1cdc67b22da44df118eed1d15ed178e950802b08d637779eda21d749446cb024f3890cadca922dade2e5374548668cbb6f714c84986845587ebdb75b8609b36f5ed180e2208c0f6b7aba660fbf5c964200a7aa1df7ef28ed87c6c8ed2b08121ddf13c4f0b518cf6528aed202c684d8882b808f282f66d6fce1273c429b66b31475e47418e7a1c1539b168cf69e687d603ab87d3ebd545b483080811d16f9168fe9ee9f7eb997ec39ee977ec997ecb9ee9f7ec997e0b3dd3efa167fa4df44cbf8b9ee9378e67fa9de3997eeb78a6dfb467fa6df44cbf773cd36f1ecff4bbc733fdf6f14cbf7f3cd36f20cff43bc833fd16f24cbf873cd36f22cff4bbc833fd06e0997e1b79a6df479e8902da8ee2bf208f0679297db447430b725a008da702d1f77ddff77df3f65eb0fd1d29da5e1e6fc6469011417cc2d4d1b1c3bc3696186f176daca19d234646c7511d1dafd72be8a31ddd29420a83430cd19e7daf97d0b7efd045fbbfa4a1a09de3a88e8e0d3ba261bb687f47623ca722242c1cfb9d701c651d71826da223aca1cff3683a684777664861669b48471d1d4864ee0ced3bb4d0fed8fee86f0beda123319ed33b0d0992cd86c8905e521085df399494d484b4657b49b6bfa61e5bb6917c4d479b078df635d18cb64cd69443c7963d8e2ddb30a1a33a454864ee082d0521eda29df499de9e1dd5e971d46387114d470e1c44b0a0225a8f2045cc146d2475cc14211d212191b923744486cc9d190f1e3b761819d1683a74e4c88103c7264386689329da7b9b29da47b699a26d649b29da006c3345bbc83653b4896c33457bc83653b4856c33453bc83653b4816c3345fbc7365384740707dbb1ed2376b48f8e1c19390afaccd706e0a8e8335fbbc811ed335f9bc8518fcf7ced2147413ef3b5851c15f9ccd70e72b43fd37ced1f47499ff9da3e8e963ef3b5ebc8f652d152d2770621d5e9d1639b49aad383c73683647f4d3c90c898d945bea61d46db4c91205f93116d9b09d2e36ba2219131d3836686d694a30907d136132423da48668a90644858bf07f699019809b280ec0bda82a88807f360300f06f360300f06f360300f06f3dea9489122418204e9d1a3078d462b2a2a0a0a0afa4c0ff6c136ec333dd84b0622efbdf7de7befbdf7feb5b1ea142952a46807910521c3663f0ded1c1b47930ca94c0f1a4d68ff2e2a0adabf83823ef68ac9f6978905293a2ad2e36b1a126a120a6a0a9acd64b2586c7b5fcc01a247f24e448f4308096bb685868e669b886826046d28b6b182868e74b30d7b58502ceb73aaf738119961055dcd90b23ca76f3f12590641fbf5faefe8ffffffffffffffffffff67fffabafafc2b0e0572e6d009c1ce09785af8925efbf5e9e083107c9268228a2ab2f8925edbebe24b7abd3c59b8c7f33ccff33ccff33ccff33c3a21d839014f0b31e88175a561f3260e0572e67c3ae6103d12a2d8c3dac88c005084c810214180fcf0d183c70e239a8e1c388a88868482f6bb31fb877dbb4b163bb28fe889a1053c27d80981ce1c395e185d645145144d24c14788d9db730417e743a1f8d9f329bd0f72f8d069c24e159f12143f5d7c4aefe4c6ebe047f61d19410ae3e9f162288214c66b810852180f8f778267270852182f048fce0fa430de1c391e053b90c2786f3c3634a4305e9affc3061a44b23d87e124dbf36cf525c9b2d8b36f7bfb71c8be6ca99aa222058a014dd2f24b12e36d7a01a7fadb0b3815f1708c31db561ffaf17929cd76135d54d1a70ba73e5db31d9b8bdd73779998962c99a168a81ec3efeb2446997b1cc35763b06a355bafe159cbe57d66a18c59b65a4dcba6a3e12598c82bedda5edab5b7cf496dcf42c33a271ad6f118a7cbc1391edbdaaed3d15a72930ecfb5c7802bc7b60ecff5bfa7054da7a2dd7807c5858bade476393886ab68c9b8fe54779a768ab1b838594aaf799f9f741ccbddb8ebb6d65a9672fbbf77a62b9661f9498cc5ed5a320ee7746b79bf52c33998cadcb93815590accda258aca06658562e589d46abb62e5ca95d5b652c102c54a15db16a72affde02ffef71da6d57aa15ae71bb2abde6575c27cf3a2a594d57bc6a8aab8667199e75381ecfbdde5a71bc95a9445171d570162cb2d4dc5dfef484ee57e8f556cff093cbebb8e7b8f814570ddb4e7394b5aa3a16c73d752cb98aca9318be82672b2e7fba42cf53b2143df7dc8e8ee5275c31af229b893b5619a77f8f4cbfe234dd73ff9e02b89d2b57696ad2f62cf4958c9be19d983eef58866378eb7658b28cebb77a96dd1e5fc174bc8be177d772fc44494bc6b19b6ff00aec499beefddd3d27d39b8bebb65cef17de381cacb55dceee5b3dc3ece6fcb6e91dbf6d75ad9c5cd3bb16dc31dfbcb31c07babde69dade95d6ed39b496ed3f0aea2e93ebb2edf57311c5fc1348eefc4f41bcda58cf9f7b89ec6d9f0b99ba6699aa6599665599665599624499224499224398ee3388ee3388ea2288aa2288aa2188ee1188ee1188ee1188ee1188ee1a8aaaaaaaaaaaaaa699aa6699aa6698aa2288aa2288aa2e7799ee7799ee7699aa6699aa6699a655996655996654992244992244992e3388ee3388ee3288aa2288aa21886611886611886a2aaaaaaaaaaaaaaa6699aa6699aa6298aa2288aa2288a9ee7799ee7799ea7699aa6699aa6699665599665599625499224499224498ee3388ee3388ea3288aa2288aa2188a6a8a9e66498e62151caf6739978be2b2e58acf7d891bd563f82a5edd5e735787a58e7b2e9667382b5ee77eabade078a77ad2e729b7566be1b9c7fd2ad7eba89aee5730947f6f4b8bd6bf97f5efed9492defb222edc76bb2bb771fff7ea7f8ffef7663bff0f3f2dcb9ee7626d34cd752d7f9996d062ea98c7700e9e5b1a76776e1777babb70963ceb768ee65ab42c859ee579e62f17c79269acb6df9e3435a5bb266dcfb2979ae87895dee7aa271ab6e968baa6e1ad95d71c4a1df7b9dfe2a87f4f7715c3aedc76285770bce6b9ac55a7e3bdcfb5ade3b0e69eabd5689b8ea67b16ef38db2bdb5ede71ff9e1ce7e07f0f8715e6ff73a0636855bbffd7f1b4aab76a4bd55a955625d1b41ee0379dadbfb23cd7b4acab6579b6f59ad7b4adcf3aae99e7e059377736b78b6f34bfb1ffcf7ae18de6b7950ba7d339fd7b4efddfd352e5df836f335d9a27a7ddb68329379374e7c58dea3aae2aae3e45ae755c735babf57924dda8d649692ff53130959424a5f2dceda5f2dc25d175cc6b3a969fc430bf3d99dfb6cf5c358c8359cecab3ce56cb38dab5f1b9e378d6dceb18b661d97233fcc6725b6ff5b8e94abdd563faff8b76506a1997c054ade6769d8ed76af48e8e6d3a1a8b3cf72e5c4fb10cd370160c251dc55d3a8a58dcbe0543d9dcbe05bfb55a0bd73d77abe199db7474a7711c6a27668d65b843a963589e827282e796eeeeffff08caf1980add6bae275cc79a6739beb5546ec79a79955a96faf7aeeab8d3acd3bff7fe7bbd5ff19ab65dc1f42e57c7bda6e12b986a5705c77b56bf42cb4ffe3df7df6b7fb76cbdd3d53b2b5057b2fc7b5a68aaa800e6576385027ef5ff5d9e6625e99f9ec15bcd754bb86a141c99e43786b901741d7717de35bdbbb2e97dabb96ee3704eb51a0c3d8ab1f0b13a52554e5204d87a165cc33978d66d856d77e527de1d5a153cf40c9e20c9c4d471bca599b86a78e6ba4f007a068f9e56e5c76f274df6ae595dc5700cf35c9fad764d73ddee6dccb35cbe6b398e793b53e9f30fba9de65a1b87e32d94a751a113e56954a6f86df35cafe1dd7157314c333d8d4a90ff07699adf76bd6369539af87f3976a7b0302581ff0769be71b8ae45f3bd7415c3353dc3ef7ee5a80d72e170bb77b7bb96e3edc2eea6ddfdca9b76723b54aed751b95e47d1b71ad6d271ba9cfcc4edb56e37cfbd8ea36e6dcd9fc62c75dce1367612b3d09de61dd7afd8ae62b896b3ba0bcf73cfb25277fa7dad60c5bbdb931a76774e5c57cb38da56c77d9e776dbf8a39cd6b0e65ee597a2d67717b8c05ab95714fb1961c63c558ba8eabea46732957b13c6ba9e33ef3a97fcfaa9671543d0757f59d18aeb3e2c6f0143786b1685121fc7f95a74569f9ffaaa745bd1e04f3a59671f4921bc3585ebe8074bfd11c47ef5ef316c6e976aedb6b989675dded597dd3f0ad6a83b58ca377cfc1f5566ae1176ebb8e667263182bc98df9b6b2ea3a1dbf6d2b3786b1ac76dcb3e0ab57de6eaf6759d7e72def986f1ade7deeb7aadec6fd7dadd4fd6ae655f00bd7f4ee803ae66edc5bba437952cb5274540de77272dbe7a99e95db3dd192a9c87215dde1b9a67b1b3bd1bd96b3c451f4dc5ddea5f0b9de5aadb470cd73fd56c3b3931b5577aa9a86a9d46a73875f78ee5936aefab5719d1bf3f9ca56771c8eeb5cd85677fadfb3d11de675a7e2aae159bed53ba77f2f012b307d0c4cf73130951b3bd1385ecb55ffde978e73e3dd53c7f19a0a275375dceaf2a7d31ca5d4b294cb9fdc782743d5b2542dcb577acd6baa5796e7a977cee2f2a73eef6a1e5fc1542e7f9a7b7c05c758b86a5d6eed5970bd6be3a83eefea1d541c35732859ae727bbc9ba774706ffb955886e9baed61582b57314cd37015376a8b57c1e19c5a1aaed23b94aed34c39d98d800685c0ef7a8098eeb24bc3b77adf5af8a6b597aadc4eefd8400981fadf72bde92b8e7bb7dbaf627e6b75f2eebb18ae63b985e77aef642e4fe66fb60468eb961fc11014b3d6272b57aaa8acbcf7ec78f40c76569e6b5a044370648a61dcdc739e977fafcbbfc7e569ebf652c510428e30e084091ac46e6f10c871650111aca4516b129f31e7b942414d18a12daeba82bcaeae335d435dff5d5dff75fdabebdb74bd030efc0fbdd0ffb3f977d3f5425d5d67baba1ce8faefea72f35d68feffaf6278aea96a351d5db75c97939fd46a6d77e5567ee3a8eef2f94a87a5e7e03ade5da9694e05aee1386a0c8ce3310cd544d31cd7dae6aedbe239ac56c6b1385ecbb56d8be79a9ac4325cebac6cf15c0bd3313cd75bddd669cece7d8aae6f5770d7d23492bb2634cd714f6e6dcd75340c65ee535b3c57ab7956fe7fcbd39ee6d4748ddbf1b7bbbbe358988e7b0de7605caed73497b7c5eb33544bc3b95a8d8e3b965cd76a34bdab794dd5db98e3f853efaf8de6e23aae59aeb91bf32a383e779d151ccfcdb214cdc5a7e8195c82e3359a93137080bae3966adee7ab5dcb521ba4378ec7325cb79c8e396ed7e278bbaf62d88d77bbcf7c772d355ccfea385b8d9ec11bcd6f4b96b4a829b6a6b9a424d34ef2964449361c5b1665ea359f6b9addd134bfd56af52ceb743bdad6737c7e0d88e0eb59bed15b96eb1bcd6fbbd6e9b967f579c75174e7224b1129f97f2a4f332064f2ff093cad003cdf6bbac7b6b9d7b02d27cfafaded3a7a49dbb3680550f0ff5a32ee9d7b96bcb96ab8e53adeaef0ffedd39a08e3ffdd2e663371e3be8be1dc6eda6edc6f7caed91d5dc202b4a62e9e9e412dd98d612d1214c19109abe3b8cba48aa639f6ac79d7fe2c2605031da6d8dee3c284316cc2a8e2bfc80c06c86d8c8fbd09210a4a0b635e1655e40809f7878749a1d112b085c87b5e50a0a548170f1f2322819c02e4747dac0b2a6a740d61bccc83944e8940931f9ac1ca8d394da0f8a0da072260d044d4cf8cae5c702446030f43e2f604cd91d9cbe2022808608ad0cf9e7268a90284090fc3806bc80937f4f8585a05a58917457cec83350a3f4204f898d21353b431e2c6cb562e606becd478180d4d6c70c38f1b1f4303832024d409ff05c8220a1052a0f899939a2c625c9ec751bbe1c486cc064f04c12b49f743f44366e6173060a185ff336af0847021cd177501b402082300f1b125dcd8400010d0f817950f495e501fefa508e020001ac3bfd6e8c103381d34f0df0f0aace07069e23da23a8025de0d2fbbc13342618d313ea6454d1a46ea842fa3a10b0c1d66cebfb088955e98a0f82f0c1d3aac180f9fa3c9ca442d48c90b7190f57444fbf997133480dcd5d1cb9c44e1658427771ea605868db4a9f38fc5c7096282a8f1df113b7e4020448e7f11d93e24cc48f09e0130bcc104181d7e86838a07e4bc90e3671da011a2810eb29779b1b3238ca4f3675a04908322a13fb6421310bc30c93f6b5344142f20e4633986a2fc6009e2bf00924440268a0bbe682eea92b366cd133df92aea0a2ef85905f30ee59f3e1f4322c50e7a34d8fdc78349175dc610e25f3684a9d34576f28f02203849e2b8f90fa0879e38a8917fa599c0840a8684f09faa4399248254fd07daa0f6e68323efa1a9a2024c101c5fa4258c0f891e233ee8891c5aec40a4e46543e840a1811b553f3bc08b19fa02043ccc872e5a6021987ee6000270051c00f0af12a4e0447012c5cb92c4e9f3c518011e2614339956c8e16563966c29528688ffeadcd9934395197ef6026825800e007c8c4d9f26461c31f23117c71031547c3fcb61bca0cd80851fc2bd5060428d3c2f9444a31d5439f341557e8e10c2e4ce136905b0468d100f3e66a746c42706001eb646aa8c3369e8ff242d8028b0c284ffb6147992a4002cfe65a037d8e141171f738ab998d360f26f240f151b1ebaf8586d2704873416fceb802640f480c0fa0fc506d38e21f72f04827c111392c00be16c1ec4e951c6bf863e58002983ae87add0678b34cc80f342210f17408927bcccaaab051a9420f31f93205c9f5789f71e0804020f23c37b08904cbca8c1f11e9b2194bc689cf9d72c6907304d43fc8b1f7541e789083e766bc004d304f85f2522c6f381849f1531048c25b0f8e0673eee50212381e78b6c18b8e901899917ca52820b5b1008e08362950932ec08f145341c8901fa00cce39031b124040121fe35449a2e1228b0f4df932d27b44014e65f5d18edb8e24b16ff816c78d04506ebbf8ace741f18ac79d90e5f8e2859018a8f45c143a00c606afcecdb8206ea46f13359ba440218b45e26040e30bc01b93c117f834738bef920ab278c7ca840e483a00852439c3b572f84830b51cd47c507b5b9e04c0f4d44f1af159e807a3890e25f3c72181305c4928fe16084aa0123cefc8b08922c30c4a0f5b1223bc2701ac578d84d83cf042054fc4c6b80393f6a38e1bd17b0c8e1c80f003f73030f1a6c6061ff0b7d8c0cbc101f84861511b4613ae273c850860a302425f9202932c430a78c307e86c30f0fa795ab0f72e2480b35549e3ef68196d1172c7e7ed645c71d2614d87a580c80aa2870e0e95f5b5c04ba6005401f1301dc00085d07ef69194301f048d27f71725842c80cd7c740b052c34003cccb6290008f9c2430fc17050b4c49b3d3136531e43ec134f54348ac54f84188f38b3eab004c08a085cfc18404004fec59e063537e8670cce4ff162408a2e14c9ef77c409a83c41d057eb64385403640e1e263b70792bcd873e75f6776e892ec74f897133264c0e30e09ffe271cbf383860f3ef6c49c24567820cdbface0ae28a2c20f0f13a241f922e2cacfdca0d1a100284d5e288912589c40fff042b1303e3000a85f280a3273ce70225f08cbc90b97b4e6bd058894fc09f15f0d68b11d31e5879f3d05da21e484ac7f797374cc8067cccb82d0e0831acad4f959991680d42b9c7f0539fa6a5969fe4363856ec31d403f5bc1070e6a00813fac822e2e98390a1f86428e1b9288eae063071050421261ed676908b8174670e0bd2c2b8011e407a80f8aa2c41b342bbd27c19b068cc8f2be77258124b82052e76142178c51204ad6bf7ac0d1242517c47f179035ca34bdf132f08c3788d8f5786f1e9305135474fe1b410c0df8c829f3b3a2363f1c31b3c0c3f6bcbb272d043f53b2828482c0f433263920595104a00fe263258ba2311cfc0727045207c88e27b2a209ac9a15731e268491aa1e0478e0656ee8d1795a5ffecb72a180dd0bcd7f3e3c1098ec80c57f21006640f165f7cfc518239c4812f5af24ccd09a5fa8f2af27a4c063bc90ff522380140e10c0f31f152acc6993da7c101b38b8803290be10120de8aaa2f01e768052111f928587358135698d50fa19902db2a03498fdc70311b1d7180ffc7bc0450635b65af8179aa3508a254c2f9b01cf0e2b6431c2c3dc28b000961d10bc6c88073f705c00c33f0b80925c9883c2cbd6d7c2a24ef22fa53257546026c9cb2ea8c5b871b1ff25a5cb9811dee0e26569cc23bc374e5f14478b296e73020fc35da161c5c5032fb4049504029ac3cf08e8e22577459a87bd76745fed88f762c0c3c41e2276f85782a6fac074e6bd359af89156e96581062001500a2cbccc812178d0c08830ff0a220a0dcc54b9f37fc3e189204ca8f36f81186f8c4840ff901e3d16fc91a0840faa3f90418c1ec6172a9f0014c3a0cc171971534862878cff40b0628d1a2d8cf0b234c2604184057dfe55e86102226a60bc67260e02ba32d078af0c21525843577e46e40698510142fc0ba499d0a10713ffd9b1418b1ffa44f0b03c70a850010280ffda1068b6bc54bc8c0a14b72c5118f8590c3f502b59f0f9581c6be025078f97ed917254e404305e470a62245052f4f444468278a8b205d2cf88b863944502052f830a427eb7ab97add00587010c293cec043284b0410ad5c3767822b4e242c3cff61091870f10523f13fd44e166832b7ef68a7d51664ee23d1566340783fe6bcd0a430151b07c0e305ce092410e48fc6b8a1335bef809e08b801c6044971e567e1645c81d27ce244f7465e736c49bef5f13e85140cb8722efa1a165cd963a62fc4b8989511079f4bc6c85327210a203c3cb745401c1063b4cf94f87215d5ab440f5b02038709939e2ff45681a020d2c9e786f8d1cbe68cac28a9f2d91c5ec883bf542175c09d1e3e9fba097051134310187cf511546d3157c70ff05c9a10a198212f81c32a0790167858b97519942ce6905807f898067861d0a34f12f0f92b8d0051b37ef7d01a709a70194fe51184fb88a41eb6563841d048063c83f054d60a9a160e5bd2b84c0816400f67fc013c1b48b78587c64451419e0bfb610a243e7c07e8f4e0013d463dc79a1292ae071c480033e86bba18f9815d07c914d8b202ad498e05f250c159d47aaf8d8044af484c041fc9e90b894425cc2c7a86809c200180afc0700932b3ce042c0c79c28c2c8193765fc2b87999ca65ac77b4664390d60010cff18f478a1ca0615feb758d3a47bc0cb0f7923380979208227123fe8a2ab78fd10103771ac90a1c17f701e98a2d3c0e9bd3b545e1f97f43d14be649952d3fa589615880228c3fc37f04ac0042cdaf819b75935c93c7e56b380891e6216fc4c093c559c66c57b7ad4e8810f18073c0c2ac7a178aafdac081f726d84e0c3c356924c55091bfcab072cbaa134c4f8a2a837ac3460e4c6c3968043a636c6eebf5d1110564053f4b31c558000e1f6fcb3c103441934c687d531674ba684f19f18242a98c3059fff02e880210515a08f796ad85c41459d7f7d0115c58c8314ef19791a23a803c2cf86884009039e98e03f2312d4915a4af23f94746e31258387c95ea8294306311f04850b7a8ade08f1b2576de60519a09f7db1808832f4d43ea6821f29deb8b3e661e88faa1f26b00f2b8183a8225af8e25f5543ac5d2350f977832f097940cac76810418b346b819715e0b9808504f75f4327185cedec634f2011a17503859f819912208a1a573ee6c30e43172469f0424b3a1f6c6b001fe4c5923506d001841702c120c38c1ec0f82132255841c451193ff482521f27d8087d2ce98d1a58b8e0f9991050c618d1c4e5674761124ed258f0315c0b669a50d9fea38a15e093c4142f3ba178456823f5322fc628e2d2439b9f51915100133d863cccc8d019668c51be2734a74a04328ef8d895a62566dae6bf2737b2c421e1cdbfda6491420b6cea7c8c8b0d77705a34f04129024a5001437ed88d5f89c00436fff55072238815ddbfcaa914d24089fa58115068ac31c5ec612450b00409460fff6dfd716088da8b9f7d592262c84af6b0310af4192a22f7b12e4e84d101a8e45f67b8c400c509fab121b054a431749f63470342888102ed634a5760500750ffc2618d5a8443f9991b77e24c9125c0c7beec9c01e6101fa3a1cc05738620f25f0247ad6e02137ed6044aca81d10d1fb3a20c211bec28f1b33c547439cd10e5bf34108e3f4a0bbca783cc9c0189392f031463034a14aff740f8b86c00831b2ff3008c8e2f2144fdcb8931c2256a34f0b1375dc0db156fbcec4d084ad630d2e089c838e3480819727818154ec9183a16de0b2226803132333f8ba0bf18a461de831d31c5103c6c0fb372256b4818c03f1075627346f35f2c16338188aefe213843470c720eff62183162047fe2654a27122e29237ec6059620e888395e6864828420473879cf47054d580260e1899a6063d363a5fd4fca6c05296b52f8191b673c557145f84f0c130f9b28bb8fd131a1000b6678e165447678a2f550c5cb462863a4cb9a2aff6a220238319431fa9996182114c1aa5ee6c5524c31b1feebd552538687f95f20b4652cd132c2072530c00c53e428799992b54e202f6cf8211fd6803ceea8f91806f3c8469ba18fdda0e31dc14c0e1f4bb34501a42e59fc6c8526e674d1c1cb7baf6c8b19271478d817808028a20dad8fc9a91244931d141f53c16880a02853fe8b20e021a802cbcfacd4c411ec217f06550303ce03ed7b389a8801e640cabfb0445104accbcb0b1d91c6046b8c09bc100e8d2c6c6892f5434f62c2fc71d3e6613534b1d2c41600ff8265b7043238f230316f2af08ec8feab2df9628b2f74bcac8d2dfed4c0e5c9bf542f7148f0817e4c05024e331cd8f331042210c38613cd7f408c662288c87c8c86c28f3f802e78cf0b08aab43123fed86b095784311efc50960e8a1c7032c5174531458c219c8e9e4808ca8591110bbcec698422424c4cef89716487da8bf4322733a4545147828f6d518a33a647fb5e035830a17ae18d7f2062086d19d87f0d7162cc11b19297016aaa8d01c0f6b12ddedcf085cd81f7dc8ca183a4400dffbaa292c1c241fe190a4b76e80031e2876c4364d0c103e861261c4d71838502ff31a096d1c20bef0b4581a5d00d79e13d28b4b62210d2e365629050f3c4879187a131044c4a1ef465075841428421093c4c09da02417a38f31fc983191c4070f4b12728b7f5b1f35e575119582411e6bd2537aeb048c38a9fa5618486a02f66fcd08e218a8a3cb0e5614888e1f10385273f530ae3c40b6ebef857eb5425843eb70f4a83cd1f1f380efe55b3c335e7355f465fd125c890fbd7111b1a43ba643dac47005fd823681eb6c004413108d1f10fc51435442a783d8c6d4ac3859cec652ee480a6eda3c6c32cf08aa0adb8f03f45119bc61137bcd09250133162f07e8613a387095ea23c9109570440a3e6f2b3ce393881803c8f634ad7060f3b32bc2c051b5c251500f1de9b367aa6ac30c3c3bc08c401cecb040febf3caa0d44618efb527a02532b0e1655654ddb00548cebfeee8eed830b5feac850b765dfc91f3b2af80025c80e2c87b4488477e3023ffd706509f3441ac5ee883e24b0775c2c7416b408c06ac905f4685931f220ec678591e3c6d70c881e7ff0b163344164cf03122243830411a3eff318c11c50148413e66e407cc73c3c67f131c2cf14a238bf7685c74215339e23f082890e00224591e5647cb164cde44f9d81b2e94e044c8c6c77a00a3b60d48e0878468638d91060c7e56409a3530d013e567543a10028204baffdc1cb2989aa1bcec09111a3b9466fc2b853e41001027e93f0e3280315d00bf2ceb0372bef2feabd88209c64785973129731019f0fe55c2105f7ac0e13fcbc212c88aa7c07f09dc60010b442cbd6cc91d20ce78c3c0c76c10dae18306593cecce4c0d0556867c8e0b321023890f9f0f5ac5d0e371e0c50b5561a78c91f3810f22a23de3c9116c7cac06120ca0c388e13d0e70507cc92a7aaf66d3670c09ce3ccc082866acc1a1bf87a6967520ba970d60a4430f1daa3e3675420956cec879d8f94290029e4c78cf4d074422b822f7322d3874c88dd1e25f47546aa124fa0f3d504613060c31bf4c8a9f166659a85e080b0732c8226ac77f566ca115470e041ffb93254b8f10b0f818e9e70707ca31ff05b18313b008317cacb5b1b1e263e363b1d8a78d2337ff5ff8c0e3e4d3f23124d2c444b042fe37b34002377c78bcac813472ad1b05feaf14f0722378f345406a5e60e031e66364002000ad05168f83cf1927e87802ce0b0dbd90c6133e77fed5c409750c003d3fa349f08310643479580e38825419e587e9c03503173158f89709e41114d479e1634458203181160f7e764587931688c07f1531000130554fff751db8bed449ff37f409faa4c0e7673cce15207340f85815446ab512162f74461e05c40274fc900bdad9764a780fc81010d857a097f1a39e420e6b5e3684101ba2a2a8fa8fc919082459a3c5bf6448da61072bf3b1286415fcc98284ffbc0c5d098386331f2bf22650f400fb1f202f640b619f8f39e943058d98fede8e3e777c1832c6cbca3469a30064e667158c01844ac7fb436672dca0c4c79c8f9d90c59e026a887a4fa692c50cbba80f2a43b4fbc325fe47a1c0c212181e3c8c0408d89c3b60f01f9306b713b438e0634eb47e94b02086ff03e65081401b60fee5809b271a88d3c2cb746860e08301131e26058eb06388355ec6c40809ee4c80c2c300a960ca90c6931f8aa18c2ce426627c0eb1ea07119a7af8203290b861a1821c0f1ba1870be82946fc2c07b9072630acffe1d845614b08e35f7950486093d0e53d3269ece872a284972dfdf9a18780007e7664ca9b2dd2cdc3605ae05e1abcf9ef8b1310909195c1c70e78c2aa0a52809f4511680e5216eec38cb62e8a33b0fc6c0f126b1177d83c2c0c3472a8e30582171af7104982891f3fb44424050696f8bc6c6540852e5b949fe94802c77c36ef1d0999f91161ea5f166cb561c269f76fc5c0531952b27f31ad81c6a006eb6710dc543f5d80f9181b5e92986243ff8b050e7e08e004f8af0e0e08030e12191f4b81871f2a1819e289980034e74a9efa858a403900c2697d21300ce8004656031f04270514a29cd2f8981930a55782f763562c60c18f6ef7bfbd5cd0c59d25fe63a8e0013d796e0fd34aa10d330118f1dfc8c0076cd0d0975de0eeb0caccbcc7860da80211643e762be73d6184f1b13614b860005891ff2c0eb8e24bc0ea67532690bc8f091f44468e028630c08a8fd10081123d07198fa3063b51484046c9bf1a68028905f408ff117971030e06f4ff0c68421be389d23f13296c2cfd19e13fe62edda023ebbd35e8af1d51c27fe8010a66ec40e6656757000a09301e0653528383d6083f53c00a0c37b82cfe1322890b3c7b94f8a02114766832937899054e6d1e8800eb858c781180928eaa0f82efa040e683ffa20b1e084302146af8180f6d6e3238e26154477c1843b5e23fc91e374da0a8fc5b65a0136187c0c7768c90e34226cccf6eb2122732907f39191281a8880d5e3646122c24e02bbcec4d176bbc91dd7c0c02028800d3a0e189960040078a04275eb681ccea07588b9f19a90210511adb13bd506577c50b223ee8146a8285971dffadc9624a0a97fccb8b2b49aca0c204ff35d067a600e1e85fc91b6f46045ffc270692930610baf8b723410f5f6bfdd3002835a2862efe5bd3c28f2baa9efc77e1038600026df0af2a609e230238fd8c840dd4324e0fff9242cb1f230788781c56bee010020d64fc4c8c20101216253ee6a30d277ad4e1f12f1c2c90828d0f527898b9a39c758511dd566f7525b4ad432907eff3101c57428adc2244a24dc60919e2aab7fa004241624bc339a499988ea211d98814136d9d1602b36d75222f00be9c114fb4f5f9b5cd72cd6df5562ff24162cc2608e4f51c8f61330a5c2822fa1d1c48c20982a7ad4b4f8b5d2444bf8303789c9e0b28a446a0aab911e7a5f1d0783cc13354470129b1407f60782350a04080feffe313040781200295476c91c2c90a43c0bc790298e1cb0073922af0a3aea960e642032aec346c81d270d341a0378a582350a0406f60d9021b62214953a04f46468f078cd041630f1c869d334406c63c63665dd4a23ef062037884219019624409f4c6933402050af4a70414624442300109116e759e30bc56ba22310e6196b051bff169f0c30e10351e7c68ad71460c52986086882e4ac2324e225c6edc2e6865a4d1a2888d4b142425516c50e00b4c891b9af0500610518e72ec81534600043c01c10d2f450c11ace9b214869f9308d70333d48c7290f1049b340ba400a63c82d082ce146d6e2032670603ec74c1a7082915242100064850b0e5890ed69f283261aca046983b54b458022ac80c241d78fcbc6014c162822fc09440441510bca000c40a51288d7141174d84300208121c1e609b042e0c31c0631654c115168424d1731060468c3c6f347004d3075c5e0b88d003801140ec069ea893a8b324e88126b0a46a28230a2053dca0440233641428a2ce075d40d0f104911212fc298326011f00e092b27202993e32487047c91b42684d41d224283e38c0a2e31305474ed6dc708681a6255bc088f02503237a68912bc087aba6d6238b3e56ae8022ceed031c44de9861434332c526e80d3530b3a4e40c24aa518d084ab4c1f143166b766b0e41faec5ed536e0f46aa34ccc009fa923207821470dde0c4170b045f79402126a885400c60424a823438870c410af1fb25823a68f18a12556049c30308519087ea099d8b065c21215903053c316332061220a1c2fc6600d752d4025c48f7fca1f2a6180ff2f0a74c64c8a134e74c02590510c891e16cc552a1c02706204d180045f02f801032fe29c61c69c9c911c385a480004162564c0d5a4c6052115305d81c1868409366060cf035a44c151a9e0052586b2b61841c8085819685071a42c5202811ae2197da12eb045065388d479e1c994139870b5a6a43943cd0e1baec223e8a881470d24464c08044805aa40816428c184efbfa926ff02fcd0c4d37e10e36940ecf87f1d431dfcd33ad0f1b40e883cad0301fe5f87ec84a78d119f2666c8d3ece411fa9181ee691938f0b40c28785a06263c2d031d9e96c113464378de684888371aea42c710377c9ee6268aa7b901e3696e003dcd01224f73c0fcff214580f4e8f13c687e7c789a9f2b9ee6878ca7fd217ada1f234ffb633eed8fd4d3feb04ffbb3f5b43f6f9ef687ced3feb0f0ff443878a8e0e4692a48799a0ab6a7a9807b9a0a669ea642044fbbc2f3b42b189e76a5c3d3ae92789a0d4c4fbba2e26957603ced6a8da7dd5e4fbbe9f8ff19ad0881344f434082a72190c1ffe710726ae13cad45e1692d195047923c10951ff134eec5d3d8254f63c33c8d6df3349685a7b14e3c8d65e369ad8ea7b5e7d35a79eacbd3a6ae9e86c6fc2f3ba0ea00264f3b2080a71d80a3288894fe34295b4f9352c1d3a498f034293f3c4dca15ffcfe37f088972f4b4283d9e1645f6b403a43c2dca3fed80ffff588e9731c557302dc5289de175b9768be7b693263b86733dc76326b99667dd152c5d2dbe82e92b986682b26b69d1ae19a149fcef1a1ac2ef1aaafbdf3534ddb5f3cfffae199d724eab5d333af7ffae1999271899b8df35dac80c7fd78cca30fe77cda83c61d74a5d99dede88f4817cf3bf6b64d5ae198d55bcd178c28de6b701de6824f3bb364ad935318a17dd108df28dc21876cd28ecfa5d0ba5188545ffbb66b4648fd192aaf78dc02cfe4132466091115308464c4b464b5db4b06bb6a5ad2528bbb654b46b4604d0f92700b76b46041829f161d794b86fa464c948898dff5dfb1030525a03cefd7d772cbd6b3b5d0c6f973fc9ee8e6a2f3599651c7f52ab0dc9596ab5baddcdb6b8bb2e7cb3c13a6ed3d1b40bcb59e68ec3c9aead56abe39eb5eedd6319d639ddea2bb9b6c51d576fed40258ec593fa4ecc96eb7eab024158c7a936d8755c35019bd6e233cdd5b16cbd06e9958ad313aab8d7bc8de5f62ab64adf7a67d5d90ed770df70d656df5c1dab779adec95c1d6bc33aa7ee82565655a89cb46cbad39bee36900b6783754ee0dc753a3e6b71a63eeb609d938dc359b4cd0682361ba8b3812dac73026b588ba67bdbe31d35e5b46d2d0d836e9f69306765556ff52ddb16cf51d9685829c96abfb0aeb72ddf70bd6918acb770bbd7ca0695dc99dfc00ec249f40b2fd13898bf4a346f5d2ecf729ca4c3e138bd6990ee208cc3c1b91dc3b0aeddb4cd6683754e5aac80b08eefb963cdb296ed7d659ad79be97de50df65ddf89d9737f67f9bdbae255363086691a27cbb9597ee7aee3b4554dc730bfe2bbe5926b77c733ef3859d6ddea9ecbb2b7ea78f7ceddc5c1bb27ab4d835c33cf8a02de683886a13658cbf19ee50df79cdcd63b19dce0a6ad40ab9adbb61bc360acacbcec4e63d9e092dbe16d6555f33ecb4f40b7f7980ad671ab3ecb4ffa18b8831d7ce57957f72bdbe3e25f7677547d96eb2c5c351c054b87a2adfc7b29dc49e1df43e1dfbb73c2bf67420946444dc873ec7c40c2148f3c3ea0ffef152081172b71da6ca0e7ff3d07c038a234c79a98f0ff5e145d6830c293189f23320d070a1a0164f0ff1e1413384ede141554ffef85018087a35852202cfedfc38207340d80d04197a9ffffa8ac0568e1c0000eacf1ff2f1f70f88c71811c3d47fcbf2c830ad8f092a80132e0ffbf2cd28880cc9f0bb040ff1fa681d50c835b1061a8f8a7b9fa14aa5acde6c6f0948e63b9531d772c984a2dbb1c0b274f752c980a9ff9d4ff0b25bd11118c847fcfcebfe7419d11fe3d11bc10fe3d10febd0ffe3d0f3813532c7b311a2a42cf206d2454c53f67eab38e4e073d6c612484fbcd9f8c849c18092dfdef9acb9f3c0e36f8ff20a3a02ae6689001064d6ed7e9e0b9a66b399a6b35f9ff1cac9c7fef822d16185041172c335165bc30f399d961a68d99d3a360821eef49f0ff41ef19f0dffe07e4e3e2f5b8e3a4b47a1cd3a04cfc6569c9499393adb4e5c249f5dba9d4aecc56eab753d97beff88b027bcb856dfdcaed36ac96cf3c2753856441b1368070d2f4765cec07274d36013beeb8971451c0e6cc8ad4b4bb9d38d94a4971c781edcc86bb2916c4c91bc192febfbb72bce9ccf97f2f6ff422f3e2667a719dde4e9c6cb05fb99d9ec1eeca3197aaa8274e534e4f7693bde5c29ecee80b839ec1253a9efb1efe3da708e2689024c90eb793a31dfb2116439224dbc9c7aa7cac808f098129014b0286048c07236faa9e65fa1308b5c0f9f74ca38f63f46f8c1ef7bb066b75a97db4e57abfd69846bff41f888d77f93c1dc80db41568cb7fa0f0ab0075f10f5ec53017aedfaa00c5e0c6bc0ad01648c3bb0a10957f238c37e428b97be64cb11cd31c8c77f2bbddfec6d6d3de98faffed340545cae94a9478d33babdf682e8576716bc0f88903c7f0163f50fee930576ec86e4871e38f1b7cde0d12e8197403e9bfbfdd6d59aea6e86996e428866d54d1869b07ade49b9615cc754bbdbffbd6c24b564e2ecca77a8702695a07bf304e97e35dcbca4a97dbb19befba5fc9541bace34e6f2b1d5cd37ccf1dbe3151226033d94a36013b693bd93ab8b6d51dc7444907d7492d8eb736277bd71db76409bc54d3bbd9caca6a833ab8e662f792920eaeb71c3371e1668e837330bdf98e7733531df3d6ca6ac7bce7e85886affabc635907d79b6fb9defcc6770cf39a95b75c6fabde5f9b95d59ee17e939174f00c67215959c1385d0de376b9ddfbbb9d76efaf0dc73baef7b7f7d7a683ebdea1e80ef589810602589e4a77b61a76779c8aa67b1cef6eadcd06ce9dde38be8b794e76779f798ed3f092158eefea96effecaf4ee33e7eab79af7b5e630563dcb4e1ba47138beabdbdd5cd3fd56556377b419653451061e1d5c971147076759b565844e7dd2e883c2c7e973a3f599eafdedf304d4c1554fc848e299946219ae6b39e673df74d2ee35af63f80a66dd7ee576dc546fb98e0ae47a02c6f20cb73b86e92d5ea5c485eb3587dd9ecbc149f54ed7827cd37ceeb9ba6fa5a47d6b77b9ad254bb912c355c025ac59d6aa7b4cbb7dd6da32bd97acf62bebb05ace6ebacb576edc772cef3ecfb26ef3bd74c5b7c784c3999755b7c5b255a7ad681d5cf77aa7cbc96ddd3b140ddeb4ec587e327757aed5681ccceb0ea5692f3509b3e8786ee3fabc64491711fc8ee5fde4c2b62eaaba40ea824817b4a5ff57e1ff714fe3820d17455250044326262e3a174e0fd27dde5d27b7f48e611b16ef5a58bc6ba16a7b56ad666b7b163786a7703dd13456db6f4fb4e4784adda99c685e732856747095cbbb149a86ab6a1947df687ea33b6bd3eab11653a0931624e834a5d5a5c099ef5ad7b1ea179ea180337fb72cd7734d7796dd34bc71baa80dd62f3cbb1b6ad74d4c5b6969296983b40eee742cef79098cd5550cc7bb79ea4aad7665e565d3f07eddde6b5e73253ae9566bc9f3d56ec7bc753b57cc7138fed6b06e5b8162a56a835cb85ec331fc6ac9f315d75cc77d891ea0cf5c8ef712d841782fd1381caf69be5fd8edf14eaef77b4c70c1fd56b77cee7b9cf95ce5890c35f7386ae635159f57376aab4bd5326eaa96e52bf21b47b974d45697ea381d3c5739713d39b9515b5daa967154f42c4fd1f56e8aee1dca85a1d0f21b47c59d0a0ee7349258e42abad3545ab254d4152d796ee995ee1dcaed4f7a87ea35d7531df79c5ca556abd29263289ae8341150e8fee99d984e3735e162858062002e1c48c7f24e766b782ff179e7b467196a835760df20bdf9eeb3acb5b970b84ecbb776cf3b99cb06697a57f399eb747c2b51f2c2eea6e1996bf5a7026018ca0659b78bd94cfeab6c026239a667b0eeb46d044f110c1f4f1376ded6c406b59a88f5dc0ce532c1e76926f03cd86926b870b092a731a1d4d454cb599a6cc94fbd96b36cb6266dcfd2d454ab5535d9929f9a9aca7327db960822e0694af051228e1256af44fa20182b2582c8594978f120182baa388adee25594b6782e69cf7d0a9ee5979ebb2e2b86b7929555d286da75dcdb7e0544da482e4ccf7cd774af396e834a565856bb33c93a9dbc69be9778d2de6eb79a62b577cfc1552ba8c455eb729dabb66a37d316ad92b6556bb5e75ef71c9fb96e73d5f0bc63b5fabcbb825f380b9eeb4dc3541ba43b3b55cb382a500cfb6e966b1ec3393986e59acf3db7d3ed7a4e6b6fbea544e3704b7cc772125dcb38ba7ee5ad254bd9209f3bd7ad8eda7c5eb15a7866659adf369f3b8e85695ad671e16a9ae3703c0bbc5a8ae1bdd473701dcb5c314de3e478f77947cb75a7aa659c6ed7b27c65cff2de5cf4ee8a3c35f3374b89eebbee74926eeeb59c45a9e3daa42deb72bd6a836eef6d0cd39bdee006df96f7255e7337cb9de5f695651dbd6798ab636d7aeeb999bfdbed75a7f9dca9f6e6739767f9dd20bdf7550cef2bf2d4a6fbbc719c95715136f864e3e03adeedb0e656a03851b9abd3941f74b0333f1491b3bc827cd833777ad763d9dd4b573b763ff9d0409fe68398cdd4679d0fa10f41ffbd96b3643a7af0e1ad6a1947553fb1eac1eaff41a6185e025ff52b311ef6cedd75a79d3e9623e61423c3839eff8fbd3c60c96d39aeb77a1dcb4fa862e50e7d5efe1ff3a1830e2224ed10026d870cfe9fade34e73712d1cdf344cc3bb67c9acd30e48fe5fa7c31a3a20f17bd766799efbeeb59c45070ac65aced23bbdd3610ad4e1480e7c6819b7eb9d7c15c34b5b4bc67576d73b96966f5a39c8d902ddaec5b572d802e6d0e40c1ce8e8b86a37ceedae66be41b9ee38583d0e416e9fdb1836e06937ec0195661acef5f986380fb2376cf907fb4cbb2168ee35c76d3869d37b9a7890b6a78bedee5eb2b2a277340defd9f2b23cd34e7b82804aee6b830f0f2ad1bdbf36d8016d50926bb767c9b9a46d83bacbc9546ed7e2b72a285c8cc5eddd8de196ee57dc3ecbb51b771dbda37a727b1dc355dc7ea3398e4a0b3cd75cd7afb858dc5ed332959ade4171bb96ecc66b0d52e47af79d5b038d063eb4130d749ea9cf3aae99c32dfcf6b83fd1a083b196d06080150db47fd0ca6aebe9424bc6e9b183e35a7c76673df5ff2eeeb72bf8b665b9eef36bd3ea71dbb3d85c9c5cab55e9c9c3e7f3d0c9b39567ea41305679f60c7d1e046335030e51348eef62788b5701b962be6bbe5d9c7cdbe255e22d5e05846bbacff2ebc67d73e18e7a2cef9ae61db76bbe6b78dec959fcdd7cbfb84ecb5076adc7306ee7e4ba969f3648c37bdec97016bff5ba5f71f11cfdca7b779c6e2773456d904a86b267390ccf6dbe75bb1d779d5cc3a2e179c75af29e7732d7aef996e92dbb73cfea5ab2940d5ab9ddd667d86af777c7bc5dea2cbcdddee3ad840b87e37d56b27732d77ea3f691952b6b972de524a56a5f59ab9cd62b51f6fab4aba8b054d960dc75327f55f1479b0c99edf6eda4699321b395926818ec7d7e735c6a83bccfef76e3259aee2c552c6f1ab7b962a70dd2306c6545efac663ed7b1dc5ec5328e6f2bab4d777a897e5fb9bb7cae734fa095d54ee6b2adacac7699bd9b9a9af09a43d94b7ba9a949931c7ca3d2f12afd8a3bd97b6f05f6ee385897935b39b6b2b25a7700b35ce37439bed537cf82eb967797d774bd93f72b8370bc6341c7ff4f79da0a3afc3f38c000bbe6c2b625faedf3e6ff2f3f6d852a607f39bd3b5befd84dcf72bcebceb597ea18a6a9f0c3ff835c3cb7b7d30637579b9b3bbddb4ebb7615c3f1ccb5d058ad4c656f9abec255c32ebc130343c171b88efb550cf30e857671b214ba8fe97d867a2d4fa37bf09a43b91285d5ca545c98a667ac56a6425f711c54dcc7c8f3dbfbfcba6b3041c383e4fff98e65d82b22853ee097145a00bba450537d55299450a8a02044cf42210e0a61aa4e71b7d5dd186ea26bb5aa265bf2938de6381c6fd9f8e7f3ff7f07cf9d3b567f477d108c95cd06d26ea771383ee7ffb33c4d6b3f677734970ee7cab913e2fcff9f60b5a3e9a8139a7a2d6701e75ecb5957e6deee5c79d66d135800ddeeee706d0c6f27d7fdffdad34c08fadfaf1cf327257451029f074bf86037d56a557b49766112fa8060ac48d84323410e092e094ea00bd3dbce12535734b043e6ffed6cd976503b45e8a55dcb38bace9ffff75aa8c3a7ce9e7fba4e9c3a75b6d4e9f1bb66e5f63156a0d55edab5a55db32d7925cc30da08717ed7bcb3536eb5ae43a9751d57958eaba66b6e73b9cdcdf1d8864584354fcf60087dfec17d15c3ab5bcbf2152d7e05c7ffbf48084540f80342bcabd540d0f3ff5656bbe67bbb3d29802310966c38deca12780f4040fb20ceff97a0088a4c38dedfb09b0bc7f27a97737b87caf531b08b933f48023f08d2ea521e5431ebe01bed410cb00772dcfa5d976fad2e55a5836f7487e2f60ee5f60ee5f69aca03daffd3e85431772e76d3f161bbbdbf9bef5a96a283e75db777a838ff565674e6a7adacdc189ed204c751351cc3b55a950bdbb47a4ce79f96711d54f13b5d077b3a90f31dd03859667b568fb56417b6b951536eef506e94db3b142de39eb8bd43cd3dd6b2e2f60e55cb52b4db3b5408b90dfeff7fc9d338c023dbdcdedf9c3cbf72cd810ee4400a0748ff0fd26ecfc11cf7c4edaeebb4c19efdca1bd0f90d74ff4fc35b7dda0649ffdf6973fafcff73c53cb765b99ec3e76978d335ddb3a4e688f0ffe02ccf7353add6d4c235afa936cd77ad56d5a4a6bb3be75f832640301ae099e5d7a6019cb9bf3d4b0c5701adac76aea949dbb3ec2627dbd5f1dcaed1e0de53f2dcbb60b53215b92a8ed292a938b9ddedbddd5ae92d5ee529e870cefdff9d9ce39b8ebbcd95e1b9eb6c73d75165b9d1fc26cf7397df384a7e63d88641faffbf996279c7563008a2e37d8e9dd8b0b292d3c4cbc1f3ff34d7d2ea3192a7c939f3ffb493dbafb81d8783a76875a9eeca4f76547268b40bf03c3ded022ada0556b3bcade67eabe1b55bb0e76adecdfdedf396e73e8666c11c0bb6805a3d8e798ec7e5d32c08f21ff777cb053cad023e0f32c572bc697eebdd855b784755410923c9eee8a6bec3f12cb95ec34d5c7d0a57c7eaaedc72f5291548a920e94130561550d00405781e046345019ba7600b08c68a02027e2a35a9a8e05d63f1dc96eb3d777796770cef64966f2d39c69269deaf6cb0ed3a7acf1cd7767773d51b2935691aa9e5385d9f776a52516db77717a40788e1ba47d960c792b36278c7bce535775f79df682e45b76bbabb383969eb7ac7caed2a1ba469ceee241bdcbbdfacfa7cabe3fdc25b29696fd06a2477569b86b795954c6f7737576d70d734c7ed7eab7b8ec7567d966baa0dd6b48cdb9dcd6d7a77abb71c6f79abc7752cb72f1cf75bbdad6aadfdc2bbd33bde76765b292dd56a554956bbebb8ea1ddde75ef7babfaf9ca3e198dfda9edb57318cd5f2b9a6aff8dcb33a0ec6b54cf5ed0ac66d5a8efbde2d5cd3700ce7e65e771787736ad2b7ba1bc372ddf6accd95aa3617bbdd5ec79deeb3aecf497bf31df7ae5577766fb0a661dcb66aaa6a42ef7eab73381c5cd3bbc772a779bb63f89599ea9dbce5ab5dcbf196fcb4c13e06a6996278f7ab99e336df3d8bdff87ee59d459eaa39ee8de1dd69586beeb75a6e771db5c118e6b776cfbbb37bee593dde7d96df3ef75bedc67cc7bb4dc3b5b5ca8ad4066b7a835ba6717c2f6d50075a75abcdc5eeba536dd09567ddbe8ae1ce6ea51ade724d0fa0e3b9a44def9b8e57599afbadee5772bdeb9d0ec79562b896c1bd41285133c7ed5ab89eb96ef33dcb2f0eb77b75bcdf6a3dc7a5daaeeb34ef731b47c955b4dbbb542b57e5e4275062590a0743e170fcc95724c6c32dc7697ab7db34bcbb2b4bb919e206b6461a6dae68a3441b22686d766883a70d0a6deee8e4ad2440d2aeed255b4980bd24c0aee9e4bd24c08e93f6ae2dd17b83f1d25db9adfdcbe0ba8506b6602304ad4d569b9a5252cddb14f9ff4f9fc6068a7779773797cbfb8ce39bcd9bff9ddbe71dc3bb85af642a5c3a79aee36ee3731dc335b856ab3555b5b04eae3bcd6f539de6379d3bcb6dbfc26beeeae83adec94fde7ea5e5358722bf316d93e73ec616cbf156cde7357755ab55d56a742cc374dcebadbea6822826a6a65aadaac9dc5d9cac86ce3fbcd5778fe5fdc234ece264265cb5db6f6d0d6bd160becc5d7677b4972fbbdfaad48801f3c5cb970df696e3741b4b96c338f55886423bc9ee8eea09579fe2c2ee8e8ae9ffdfaa8e7bd6aae63fcd14afd5e3261c8e3f69ba82df587eb269beab9a34d9929f7038de36553579adc8372d1d08c62ac8d3d24c8160ac689e663310e8ff1f046325bb3bba56b3f2b27ba7a23957c7b2d5ddedf1ce26bb3b5a7677348d81370fd2fcb6370ddfea3d77ddae630ecf31cceb587e82c3f1272057c7dab2bba3ad5cabdd6f555b76775457687595ff87fb1898ceed72f0ad9e370d6f9dd2d3d0d43ad63ed3e7ff77cd7777e5b6bb4a4b5c1d2be905c319344c747f997a7f6de0d3ba4cf8ff9c3cbf9bde5baef7958da9d3b5da8de652a63a8ee5340ca5b7fd6ae66dd7515165d9aa82e91ef7285c35ec04261c47321c47528b5f71a3b6ba1bf35acde99db3de398b6c7be72cae3e85ab63d974b659ee5771c7e1f8ada5d242d33dae61add74ab7bdb20d8bd7541d8bd7b48d6b969bb43dcb8de6b71bcda59ce6c88e2d9febf2dcc938bac9698e529af652adb6979a66190a87db49dd682ea59671546e1494a6d31ca5eca5a61bcda5eca526f52c53cd5d27cfba5c147ca3b914a91d9fa1e679c5b2b2f69c4cd56359aa2acb141daff23770818083772ccd77cda7685badb37db0f5033d83bde65770168f97f43ed7ec121a27b73d96a5acf6ade6ddb569c9381cb7b9bde66d9f75ddb5f52c18c76dbadeb170386eeb5973a7fb1cef685bdde97fcf81ff87c572dbe97f4ffca05ac6b999bb1b770f7561db5aef6c5fe6ffdda76539752cae3e65cbf5be9a9da6b879061270f2b45d1cfa2a86b970b1bc5dde715bae375dc3efbba3b7dbeb17bed15a68ba18feff7cdaaefc0fc904469aee38ae986fbae7664eef6438abcf5375a76db95a0d979b657a0659d9add5647747db986ad8ffef597eafe0dc96e3ad66ce15ef4141f759ae6b7a17c6e5b65acea2dd996bf599ee6dcb7b2c73c5dcc6c5da3a8ee5712fca82e7eeda688ec3711bcd6db7b6e6acadb7b3fc6a91851f37e2a2af0a75bca67370cdbef28ecfefdc77ff6ff5efb5f9ff204f0dd5bfc7e6df6b4017e4a9f97fb7e378a7e9196479d547a5733bfbc9ff3fc0d3e42ade4bf3ff9e01bce6eede54ffde0e19499efdffec69f2d333d8d2706e494bc3b9ffdf7a5adc45f71d4dc34b6e6daf73720bb2bb5b0d5f2d5952a375757ddb35dfbacdc4ed73bfba82e77ac7bdb37ddef52c988efbdbddcd63dcef9a2ec7eb25b4dc0dff7d96e3ab28daedfd656aeb9daed3f2125c6e96733cfec1ceee5cafa372721df3db94cdb66bdd95dbdd712cbfb5bccff16ebb7dee75dc770dc7e3b9bfb62cbae3766ebfb5b4ed2acbb69be5d7968339aea5fb15d7d9749da66df54ebed5b056dde92df8edb3ce86c3c158b65b0d6bd9b0669eeb7379eeb65cd7346fe77ed5eb18fe7f009e865b9237ae873cf731386c35cd71375b569f753a1baf694e85a6fb7c25cf536ecf826fedec84e3703df3a95aedc5752a3052aaa248ad546c5454ab54152b50a49cae94271679ee5d62598aee6d8775b59acdd6d4a4ed59ae6258a7e3556859fe7ff3ff15d2c2e8a8e1b7d7319ff9ee2aaab71d9e0a2c29a2b23ca322cda56cbd2e58cbceb6e169b2e4c9f2f1453908b2aeed46f31b7f59b09a647f3baa92e168a6add951a92eb6055e15ac6c3bb62dd9df973d4d1715d3472455519088594150976be317056b6fd1f274d9542d55b6ec2afb9a6065cdf4445b534d4b534553937c49b09228aab622399667698aa8f98a6075dbf2ec2a99a2a1dab261f8bee2ac2caabe2ad9b9d8db179cf57c53ce76130dcf726cd956bc7a41b0ba240fc5f0ed2fd9b6a9d8433eaf20c8e71ebe1e58d59787aa68a2a779a26f79ab79774d3eaf249f3ba9bedeac623b966c98b6a8ea8ea4e88eb6bae5632ae5e5c04a9a6d69862ccbb664ca7692bffd8afa72b3be23db45f4153bdadbb614cf1b2abe7d76cb503cd127af36eb988ea9d88aea48723734cf0e8220d8c2f48bcdeaba65db51527dc3d434c354bda16278ceb5eed5c0cac9b17dbb69f2d155cdf72cc52ca598458aa59845962ebcd6ace1c886ee2baa2f27c9931ddf2b515c731daf336cd3d1721d4781a05cc7b0f9e6a56655d350ed68c9cbb69fdd1cdd1b2aa6625a7ba559d9978b7d1c53512d95bc1858c394eda6e8baeca9926c9bb237543c975e6856520dcb3e92256b9e1d0d471ad76db36cd3f19c289a4eaf33e158826beb72d21d4f377d59b5255d92e6a75ae75ef2d5b5aa616bb627fb76f36cc7f06cbf40a858822b7aa6ad18f2316d49f13c4751ea03b48ebc0c45b1ab2aab8e247aaa375abed9ce71fdde58dfd33dd392f771e4261aba289befcf2a9e694b8ee5db392b9e651bfa593b699e65caf231ed1d45dbf6a43f3756761c5377ec28cba26679f2b08d356ddd547c5d53444d352dd992838f8d1565ddaef2f2655f97ec2f2b4201417a14d758cbb36553d23d5df54cc99244d558dd565545d10c51b5ede38b9ae797c6ca59120d5d9125c9943d395a2af0a1b19a631f4bb47559eea2ad589a67ace9d9b2e429b2232747ee8a228ae6336325bbf8bae6d8f6912c4b74e465ac5d355b31445fb475f9f98ae8d7673559f125c33434c3b01c51d68ce023631d49576cd5d12c5951154d3205c131563e86691b8a257aba6e38aa63289ef089b18eef1b96a95b9a9de5263bf230d69115d110ed6f5976522cf9a87af081b18ea649bee9389eddfc62ed63d9763135d9b487a2d9ba5eac6e37d576445d96f732e4234b8a6817abcbdbd1e5ed7ba627cbc753446d5cac6a79ba3c24d3533d5553ec1d0cc511be2d56b5939ca3eafb726ea669dba3401035a5bad8b27c5a9862197e59aca44bf2f33cdb93155f1d6a7af9b05845b2a367dbcdd355c5f21cd12b56557d59950c551eb624cba656acfc2dd9d03559f23445b53555101445ba8a95ab2a2fc71465fb9baa2c17a95859b5bf2a4a8668da5dced3d285e52c67ee9b620d3959b2a97a8e29a9bae7d8519ba8f549b18e2d69a6a5fbb2225b86af1946b1a621dbdd2e8e6ff9922479be50acec39925d355df51c5b956d3b08be73d6f7c47a9e6c9bb6e2cb9662caa26777627d55d11d45141d4fb615c9265633e421499e627896669bf2306562e52fc95f360c4792bf63598a4bacea4bf2b14dfbc8a6aa698e23a7ddb69b0b7c4aac212a8abdb3e9d945113545338955e46acb5fb22d47b79325f9a2673e2456972d5992e46d19a2a83aa6ad4d3c8f5849b54dcd57ed6c4986221b8ea41b051ab1b2a32aa266a8beafa876b21d6fa8688a6ad4c76715397b9e293a729755f9898a45aca6d847b77c79899e633a9e260882a06a13e9b4848f88d51ddf770ccf573cdbd46cd57488f52c49b797affbb29ded6fef42ac6238a22c27ddf23dd5f0257910abfa96686abe6d49966feaaa29051f10eb19aa21aa96261aa2684ba2e40feba89aec589aa3d8724ea26208fab0f2530c45d6345bf71447d34d5306be1e56d67ccb327d5b9eb6661fc737e5610d43f4ede218aa6819f2937c7758c53335db9e8e6327dd9477d214c74f87b53ccd532d59363ccd5414cfd32ce0cb61e5a53b8e2767459135c79775c91487354dddb3445bf17d51b19be90deb9976133d4b9677971c4354dcb3729124cd515451b3744b5504c13ea37d466d5847b29fdd34ddf0e4afa8f610046d35acbd75396fc5327d43337c450e8220288a24061f0d6b1fddd745b9ca49f3868a3855243f3deb99aadd1c4bb7755352ecfcccb3b6a6ea8ae2489aa98a92afca6758c9777c5935e4e5ebb26d1751195652145ff775d33765cfb64579bfe235155cd3a854171bfcc5b0a6af3ba2fc244d317553b14461585991e46427cdf7e42e1aaae50bab4a96a19bb6a91abea8d89e2a0882606e178be99acf85f56c79c8aae49b966c78be6657755f0b2b4f53b5545f926cd9171d5df5145958d151e49d75b96b8ea2c9b9899365f65b613d5d3315cbf0ed6619be6329de6a3e05f24f85757c4b123d45f64445532d5d154cf1aca189b229575dd66cc91eaa670a6b677bdb53f1e4e189be244f5158db723459743cc993bb2e1a9e53304e4735d774f8dd594dd65545554cdff60c5fee9a5152e209ab48926537dfb7bfef9986a369c2da9ea4a98e6dc8d5f055c7f3bca1e2dc49314da17c25ac663b9a68ca8aa64ab664cb51f623613d55f6e52d77f9d976f5cccd32546e965f28e95cebc8fab3b37673ec2feaf2106d45b17dcdafcedab6a17ba6aa3996a588b2a568c632ee090872d5ed37c2caf2122d4b377c5554ed62696641f204c9141dcf8120087e22ac6ae7e1c9a2a1fba22ea9be2a0886b0b6ecfb76f344db530dcdb20c41584d96a3dce522efa7199267476da2f9c12a9a28efeec87614457b5a961eace5c8d3b39fa369be6f9b8aef698e526c1f9d556dd5b46d553224c7d2eda8691ef075b0b69cbf6fe89e24199ee6fb9a1f07ebcb5937654dde51922551b4f7b9445215a5dee9e2a850fc3658c912ed297b8ae91baa29a9a2f54e57efaca8df9cb51cb93a72918b623a923c0dd72b20d8e6d360e5a139b669ca55340ccbdeb236b1cc97c1ea86dc54553224cf13ed7c6cdf7c18ac6f487693255f5634d3b36c4b103c47399f9c357cc5d62459724ccf91ecac8b72f05db08adc25bb59b6642aa27d7cc3d2cd67c1dab99a8aaad9962e9a96fd7d419b988a69be0a56ce491e72f6e469e98668389623056b88a2e558969c8b9c87adcb9a107c13ac6337dbb414593525c55145531215e77c12acbd9be58b966a58a69d77958c602539e723aaf6306dcdd155d953aa8badcb17677dc5d1755ff37d4f511dd19eeecc301f9c55ed2dcb8ea91996a9199ae8fb41b08e61fbb2254a92ecc9d5cec707d614e566eaa6adf8b66c2f51558a254933df9b9545559ef2b1b3a5c9dd9434c351aa8bcda3f339b0ba25fb92695ba2bd7ddb5ebee6e766e5a93a8e2c4bb22617d9b7744150a7e320a8d371321c27f8daac6a4a76711c5db414c79275fb139227489c904c514172ee3e366b48a2276fc393ed61da5ff734d1aeaf81153dcdd6747b4bf25364db54b5892839c3b7667dc9b793a199b25c44dff755d5ac2267c9b48b6f9b8aea1ba6097c695694754df70d5994645d7374c7ba53812008aa525d6c5c1f03ebe99aaddaf692977d2cdfb6fdd0ac251aba6567c9134d5d6e9e6eefefa85af09d595bd624dd942cc57ef6574ccdaf6b7549912555cecfb42453f71451a92eb6ee055a4b341d4d532cd9b32c47746c53406b38aa237f53f36d3ba98e1d05419b78cef1de58ddd065cb91544f1265398b92aacdf3c0fbb38aad489e214751b3a3e56b967e56146d45966c5fb174d3121dd1359e1bab1aba268aa62717cb5324d1f1868a272ad5c5167b6dace2e8a6e2e8aaafc95ff4e4ee0d156df0fbda4424555170ba5c14d7134df32910046da7c881c7c6da9668e72159baa6ebf6306c6fa8688aa7588a6bac237ab6242f394b8a2cab8ee2cec4796aac27ebbaa85a8eec99c6faa26ea9926338a2a438f2363523f0d0584f523c5df244dd374c6da279c65a926cdaaae4eb9ebce564abde50b114cd58c71ea2210f49948fa81aaa6655288662cd2b6365dbb20d511e8a62cbf652e57d56f43551d34dd1323dd394eda52d86af3a9ba6a3d85979aea9d4f324637d4fb445c7b71d4f4ebe277af69a67c1b3ce6693ea6203bd315695b7670f45eebae1c886638a7bcd033c3156b1ed265b8e62eabe239b5ec938328cd5ec69c9aaac89be231aa2a84ce5ea4aa6a293a540f04ac681b1f2b044df323449f60d5df4756fa8789aa3289ee6c86ff439f21bfdc5daf29614ddd6354f526c398bde50310c4ff135b178db76ac53aa8b0d89e7c56ab6a249aa21774f333cdbd405c154aa8b6de775b1b6a21bba234986ef28ba2f599e2a17eb8986af599ae4f876f6655134b589a31b6f8b55155dd16c43f73cc794ec9d83206a13b93c2d56d50cdfd115d1917dc3b24dc32c56131d499174df2ea6614b966f6a83e361b1b62d5759974c396f7b6b8ae215ebc89a2117db170dbba88a361a4e45279e156bcab2ac88f214e5afeb86ea0b82b10cd755acaefa86aee8765eb6e7fb763695c0a36215452e9a6ac8b26e6ba6a1ca9a344e97834d2c6f8ab52dc996abe5fb72f555c99104c19362ed6e47c310e5e4d94f1375451004535b14eb699ee8e8a6272f4d574d517e434551a4a7ae204132456584621d59d14ddbf7553b7a4345da368ef4289ea328d5c576c57b621ddbb4ec2927d592444312ed200886a24d6c6938579ee71dcf8935eda56ab62d3aa229cba6ddd5028220a8860e784dac223fc7ee9a288aa6628b8a21136b37db717cd5966cd5917cc337adc05b6225db97eca348b67c44595565550b3c25d6947c47912dfbeb9eee8892a397c48abee9199227cbb2e5ebbaaa7aabf95479abb9aee4aac7504462757b9972553cfbd8badc95df98e6e253200882a94df41ef08e5879499e624aa25d4ddbb0e46e29367946aca3f8b66edb9e66189aaa8996a398f259c5f4244531345b551ccfee9e3a798602823a7976dd99efa2cc9d8b5301c12eaf88551455f1edfc1c51776cc7342562e53c354d91344ff31cdddec72156d33451f7e4acaaa226c9c57e45cab04d479b525d6c4a9e10eb68be6fd9cbb6244b563dfb9538e23829a2555e106bdaa2e9c9a6fd24bbcab9da02b18aa11bba2d4a8e2c6ab2bc546fa81835cf506dd7518160952ad5c5e6a9f17e583bf98a6817d5de3bc9866ff8a43cb764adaa3495ea62cbf27c58fbd85b741c3bfa86ac1bf6b2df682e85ab06413095ea629bbd1e569764d93eaaafda4f91655df1868ae298f2b0b6af7bb2af1bb2a3caba3c6d6fa8683ba9383d59a112e5b49d2229eeb09aac48926558b6ef89aa6df86e91ea62ebe2e9b0aaa14abe6a8bf2547cd3b245bd1cd694555372545bb59fa1fbbaaf79e2b0bead7a7291355fd6354d7224df7e0504c337de0d2be9aa1c5547b6a7e97ba67c0a046759078236d59c6b1d186fcfdabb6bf2b114cb92b39d1443db0a82369ba9da28f06c5859934df958b2e9e98aeccb59af86b52dd5f4144597ab277aa6a77943c59c3cbf2508b63dcbed5bf0dbe7291044524505494e9ea140502c49f06858d9164dddd67dd3777ccb73546fa8789a7ad6f22ddf560c7b2ba66e575d97932b08ba9dc67558aa67c9f31408baaed3898a34aebb72ce368a6f78795616e5e9c876b5345dfe929ddf5011b6d9ea590c3d8a48aaa2a01e04de0cab4ba23d7c49554453522c790a82200882e5b903411084ba82244c8ff064585dd37cfb7b92eec9a2fd3cd51b2a628d5ab2cedce2c5b08e9ca72319f231647b989ea45ca7a2b9bab80e43955e3c185693ec2d0fd9707c39f98a297f613d59b4ed2f998a696bba2c098220e8c2eaaaaac87693bb2f1fdb5ea23754dc92591b56cb71acda7135bba34fa92eb624af85f5355d31544776645fb78fe288e32d1ccb316fc7b38ac7c28a92628bb227598669e8ba656be39a7b4ebeaa6339578aa3999ee5b9234f37ee582d6751db29aeb09e674ab662e7a8a89ae8d85510c49d2aac3ced247fdd943cdbf164cd16cfdad5b1bfafd8966a3aa6632fcb1456939b27a98aa5f8be218b9a28ace6d9962549be231a969d65cd3bab999e653a862ecaf6b27c5b7ec21aba65f98aa75a9eaadab63c9d790c3f855f3c1356f335453165dd724c3b7992280872f179e6e829d5c566e595b0b2ec88aa9d34d530244f366c495843f5754d361d519674c5961dedacac3b926f2aa6dc6479ca5bb13c59afce1a9a5c45796a9abc45c312ed3a1d9604bc1156b6644dd4e4618a8e273fb57a4ccefdd6cebc53cd359528a2734d8bb08afc4dbb6abe696b92a15bf2105611ed6f6896e3dbaaed99869ddf405849931dd99e922c1fdd5344d32d17044190d6c9222ad5c5e67a1fac2a5a8623298665cb92a8799a2aeac18aaa65c8c3d12cc533754df3bca1623ddb543aabd89ae6e98a674745d3e5622ace35ddc17a8aaccb8abc7559f415d1d1b49d22bf8d343af35b5b52791cac63f88eacc89ea6d847351c4759664ba92e3629de06abea86e96baa24e7e6298675a7e7acea39962cdb9aad98a22d0f4b18178aa7a7c1dac7f32c4b2e8aedd84bd44dc70cd6f63d5d2e96613fc5b3edec688eab87c1ca9aa9c89a7c445b123dbb28a29e9c154dcf977c471455dd701455d5bb602d43b1b7ad7a9e7c344fb24d4dcf82b597678996aefbb22e17df92a52b584935ec22d9495154df9eaadca46045fb99a6a739f6336d5ff51cc90956f64c4f93ab2a7a962929f2749460554b91b363598ee1d9d5b63c6d36fa1ca1bc08d67744cb52e53d0c5dd73cf9a9d3ede2ac216fc397444bb67dd1903dfb0d15b7facd36772d1967bbdab1dd3545382b3b92eecb4b6eb625a9b6bcbda162af711c82351555d675c7166d51aebe6cfac01aaae678b262675fb375b988be5979c8cf502dcd334dddd345c51b2aca750cdbca7367ebf4cc75a598dbc564e939b0aa226b96a78bb6e698b663a88e2269f3dcac66e8aae4c9cf341c4b3ebe210d53516b5e9bf54ddb4e922fda43f324cd76543d36abc9926c28aa2437555775cdbaa75e036be8b262299263abb2611972f4868a67d8c45bb372746c59770c55b3ecdd55cb8ed3edaa424fcd4af6b075d5366ccd91b3a1faa6594b92b3aec99ebd8f291a76d463601dc59eb264fbaaa84bbeeda87a685676ec5c65db7154c753154fd43bb392287aa2228ab2255b8abc6cb5785d6b5b76d26cc3323547d74c515c875f934a14d33af73659602555b6ec68cba6a5ca9a9c159d5c3e959e525d6c5766d6eebe2d89b6212ab2694a8e25bcd5a5cc5d4ba6622bb39ee4889eac5a9a9d35cfb77cc9ac6f7bb2e89bf6f375d9d725d12805d6f3e4afcb92e4cba2addabe5d7ee3a8168ef91408a2525d6cef98951c45b31dc59693fc55513724c573e45a51312d7bd9c7f01d5d93f79e8a26df5ad5b16dd54eb26fe9aa229a9a525d6c57b4d6502d4fce92216a76b34c59f6868ae95bef54ba9e7b562cb7e95cd364d64aa266e9be63598eeca9bea74a9e525d6c5f766b4aaaaecbd9147d4993e4e30b82385c6fc353aa8b8d4b5d92e05a9ea27b72b775db936c477ee6763169a3d7b3e46e489a2d8bbaa129be2feda49a525d6c5be635ec642b9e623b9263cb4f732ca3c4acef2b8aadcad95e8ae2f8723e96525d6c51742b49baec7b92a3fa8ea3cb3979434597eb48505ec9ce7b88967d1cc7b4654df1868a2354bca66e2baa3ceda1e876137dc31b2ae2f87ce572dd28cebd56d3dcda96654b76f50ddbf054cd4ede50b13c77b63af7a2216e5553b32c55ce4dd25555d2756fa8e8c2b6aee3aad1d80904b9625e454a75b1ad58ebab922c775fd56c49f4ede678434524555190a43b24555490ccbd8e7a02826e8775726b8b619b4e9edd3114e75a4786b119c1eb689264c88a66c972943cc57e43c5dec6b20d87e3addadbd84a0c75a6b44e266f2bd99663475bd71cd117e5a8185ead2549aaa178b61c4d79ca479414c7776dd9b754cb96a3e998be6ad8e95114fbda86dd5547977ddfb187251baaa9bbbe67598aa82a7232655fb1e5375474e55abba267674bb4244933ed6e37435756d9b5644b52554f5e8e6317434e8a215f4571545d5655bb4a86e2c88e37542447ab3555d1d25543926dd9f35451761445db6abae1d8db4e9ae898a65d746fa8a89367375413584b948f68e76c8996237b86ec0d1571ba1c6c73fbcc6f742aa26056332453b2e46e1bf2d055e57a1c997c595fd5444bf125533254c5b4156fa8188097f50dc5776ccbf0eda52b866779bbd1a8787659dff40dc51ea6a979f2b43c6319d7dae49c3cebc4d194ea62ab7159d3f12df9ebba245a92e7cbd31b2a8ae20c454395f3bbc548cb5aa2658ababc2549522453b68f066459bb289eaf2996e5c8d172e4239615e53d0dc9f37cc7374cd192ada2f2718586806e57777aae6dbdcfef8ea91f56d6371c519735c5b7b3bd1dddf38422b5aa9cbf9d6d4b97543b89be347f6da2285ed9eaf73dcd2a6bdb4bd21ddb533cc3531c4f93ca94954dc5537dcb933c3b9b763447c3395bdc71a8c8a5935b5374cd1d922a24acb943a28efd80b53cddf44c4bf6e5a769a22abfa1a2b914b5ba6e2751d344cfd20c4f5534b94859d5d31cbb5986a2fa96a65b6ff5b8445215054914485f41f2044914922a2a48ea7877a36a6110a4e75eebb8cb4170ee357c86a254179bd726cadadfd32d5bb59766475391bb726d0b4703a0d65e9e67ebaaa1698ea5ca43f2868a6c774fb1c92ad73656c6b13fa0acaa5bf6337c47f57c55351ccf73847ab2be2aa9f6b474c5110d53d71d6fa818779ccd8dbbad1c4df3e9693d59112dc9162d4b33e52e7af25b7935068b94ea6253725a5d93754f344ccd523d55f64d6fa8888a4e0c58bb8aa2611972eebea96baae90d15b362d836bfa39816b0b6a37b92eea886e2598e21a9e666d916c3361c877372cc859375b65ef31d8e6775b2d4d2b4b668faa6bd2c4f928be5488a3754b4b5e3983e395939cab2ae999abc1d43f27dc3b1c9fa9abd4d45577cc9918b6fcb3259dbb645c7b673d3745397b3fd868a57313cc35c678a4db55534d332145d376cdf931dd5f1868ab654e4c2c95334140872e1645d1514140d058ee313aa285da6d050a0698e525d6cdf1d7555cb2eb624d97691444352ed3754b4d1e93a926fda9a5c6d4b3ebafdc5ed7248aaa22099a1e617b7ab224601c1ab315862141a0a04c52b1004415195ea62db42d7b70d5db764c551545b7324c31b2ab239b9b5cdbcc730ce265e8963284239d75eaa22ef2fdb9aa93bb6a8a8323157573ccd54555f947ddf506d4db35cd9d73c5396a3e638b6249a86734dafe4ea86a41a9aa7289ae48b8e2279b5633b141004d3714dcfb27d4bdec5327ddf90ec37540c45310a0d558a57a359d3bb5995ea626322aebd93251992a83bbaad1a92ee0d15d33ecb4f669ea5144fa92e36345cd5533447940cc3d60cd5914c49f13cc5b667452d59d596b7bc344991a39c733404d792145f156dcd91b7aa59befc868a33bfb5a1a8856955797fdb57545b76ecac1b9e37549c6bdaa622a98a82a4d7f0ac85e65aea5d0e09d41524a129d5c5866569e5254a96ec38ba2c173b3a9e3754b491e23912b08665fba66c7759122d49333d6fa868d6b9974ca264454f919f63ab9a6c39a6e9fbde50d1368a679d7bc9536915435554d9900d473315c570bca1e28d7e6da7482569e5ef19be6f599a6747c7534c6fa858c3381d1d8add95e3d21445a70156deb978f21665cfb3255f76beb2bde298645559917392bb66c95f9615c51b2aba31b7f5acb98b238aa42a0a1227244f905421a9a282a4ed59b4f815958b00eb18a26cc9c7501ccbf42c59d38d61ad7827c7b654ac2159c56ebead9baa2d57bb99922689a42a0a9291dccdf2cbc5713a1a86028275ee05c13ecb2d9270dc21c1e97230922a2a486ca3a9cbc1646e179375ee25d900569245d5920dd1b11cddb155df1b2aa6228ab4bea289ba612759eea2ae39a23754ac73afed2a86b1d43ecb6d29d5c5161eade4787617e5a998a2aa28bee30d156da8889a525d6ce9cec9b20de7ce369bd091b9e3dc98df6c438c74d756d3bbd966cb018068ebb72245de7a47041d3244c818401023407e28f191d4431c8047003bb6d1e806a279a8546fabd5a938c9711843c61082ac9b12008002d31100304034201088e431d19099cce11480036eb06c864899c9a349160429c41422c610030040040004668a86006adb3cd6c154a6a3358af4b212edf279cce491ba50d2d3e8af38ad84b8920fccaf5086ab75f73f1087aaaaf7e3f8bd6641d474af667ad5844e884bbc0f2e9c969da0bf3f905801fd2fbb99d0dcf42b50cc90f762d011122a07642be6f2cc61cb1b9d1f87df5df343ccb2f50a2b80393f00ccb8614928ac29bbcc9633aeb230dca2ac07dde74306846b1c3f18501e971441cc4449109894dc65b82300e52484513f01669955bbef578e6086d2893d951774df4187769d936975ac9e6c3e8536b6ba661ad23fd37facd11482adf2c188d4ed663462f1230b71689aa0151f4dbe8303c7eab22ad5a10dd23fc0a26b37535db1e8339b56cc976bd87d4297527c599b39a2a7833db25f29b84c187cf3b864ce92cad5d628f2307d71e0d2e2d065f063af48661fa6a55b7bcb9330f98290d210f9a942ac67840ff29883b23728f6ee42d363047627e8c32063abae59b958cf549e852a793769e304c9f44186837d3c94ab61fd9b30c048e21e31800af07f76a4b068238af9c2946df2a19c814eead9906e37d1eaf9cf1f614d7cecd1d2af8a104c41a00cc5882c0542b2d7e0142d5e89ac5a1159cc62e546b97c8e7bc123bc6b61e5a15d00750024d4525f38d1869973bc7f47f94fb54d8af876369e3339d4906c705c8e4a2b3036fee04fd4feb307eb6749c4efc33bd17234443eb288b7610837d8d44f9c72bcbc947bb5248322ee473b33a8ba05611e8ce4cb8b1467bfe993c2dae5be85d420a40aaefe9d1bc5dc06c9157a705cb88a376962199da2596595a49137871b7b72e47f9d0af4320a4a0fdd220d4567e013e7b295921aa62e195636219d8abfadeb754bcd908e84d876182713481d111d060ae4225676e7fde5e3d9b3b16161506c8f9764534d1fe4f385eaee478504ff5a8ee9c6689ac72d007a4413e29ba182b65d40d98fd1c6a75b5824818b861358d981c4ee5e6f3ba5f80ad2474574d21d29e5285b09297af7e04b18fac65fdaf7d9421f511bc680becdaf2aa72346c535f3da1a50aab9358e4d2faf58c49124507bbd4faaa6a24937196db35a359551ff7e33e853ca9adb4a27caac7a7862ede521b6efc746d2068fc7f9e9aeb22b85127932cc0f573ca94d0db426feccad7a6a472f73d1cbc28939a2fc4dc599a45f09cce07bd9199e905c7b6b68799a4287b01e336cc2dca321eb9d339bda8b3d2986f5ca2183e4f7611c0fcfb757fa180342b337cee5d9704d05de8eb51616193ecb96d72119a7b603c873e367926c04a4ac26c619dd4b2195ec6180b15fe4b2ba229039de06085ca936c09ebef1fdea4baa153267b390f76ad0ef2529176b080914313457b650ea9f6074debbbba9be8571da299dd69581dc2d26a0035c8a3081fe2b4cac337665c4eafe3d88fbdb906e001117294fc5981b8b49835acad99549ef5e525743b1bad894f49061baae2a078c86a6b7c95422530be5fea1ecdf331f1811ca14df4dbd30364aab3f39cc963f11466529c5e45b9505985f150be4e0931a2c2e994ccef6342c22dcd8b00464a856d24ae83e7407b5ee17f450fafadcd17c29bb4b1053847c0a79c24b2876f12051d71202b5348312829c23e8d0829573c8b226ce82768f56d4c6d08d8204fa886a521df15b2a99ecc0778118974e8329382c6dc312597917c7e5a3b3055e5f6db85234df56dccb7dc012c4883ea682606d53faa1d3912bb7fb3f686644b84f31df4f0bcfb26db717999f72d837ada6778ad8f25c496584d4a4fca97c766e49656dbec009e451ca2aab638a238803393d015face2c681de938ae339c62690bb3894e248c69dd8fcf42bf374e98f9d31f76544112dbdf3d5974344ab6502088bb2ba663ea9c2768ec81a9b923aa9ec085b2155633b315002fdf00d394d70f35060b60715a0a61738f44d46ae06d820486b0d984faeaf34f5fa6f8f89bf26257047beca95de7c4bf2afde5c1bbced59f502a08903a987852ac8488c64015f170e113999bd96cc4846acae6c369e800d774feb08c3b1ca696b03865edbb57e4ba6f832df1e2ab292bf97aa9983f96bfb76609c7756c8328d00c0ad64187dba300f2a7453643cac75d5733914a4b383bba8c85b0a231de1cbd0c0a11e3dd8ea667d4c46afb17efe5762c71f96f0cb91b2c09fc030fdce71a2f8a92accb0c2a8114b0fddb438dda8384681cc18975298ac4353abee14bfc50cb14f2f2eca4a04c2d3ed8851e126140f0645dfad0b26d27992bdd3cfa71241579902a538e56e874c067836cef7a76fd9973553f3395018ff9eb30ef2476af031bf6baafa5b4db5c4b88255dcddab0f9c0b0c0a46e95079aafde416874459b840264234511c17a8eccd914a5a9ea274e558b754c4278bb8452690224e603d57d87deb6b9c652732634734baa792e156e8740ff733ab89947c1cf2c026eae7e6333729c9261cd7e2f0870859a0b5d6bd10c693c444189532c8646240734e948c10847e88775362fac49029aeb4ba4fc6c86a7ac88644b052ae118ecffc637055a672fab2f48e0713fa8ae20c1a9c4617ff8c8a7d4aae4cc64144a4bb8248eed5d41d2e043dd6577732025254fa545ac5726b97f3dd7b25bc0b52313aed62b0ce36139b456e856059e33fcaafa7a3c9dcc6c7ec43ba53d344c9e773d1935be1478282fb77818f07e6daacaa1c98626b4b136780c10af05919564a32939ea31fd6d8dda0dbbc1dbd67e0036ae117011b712f13f26c7a11bc75876a09f571bf7d8a8b0e997cf97af31a9624e7fb7a2cb23d97e9c6406f222e2a5479df5a558eaedba173497ce3b232d829cfb7dd12353a4bf0ee7b2602fcc041684bced08ab53063edb0c891041ae4544f28befe9cc61ec6ffabeb008945192fe083f21e975fd2aa773776ed8b439989ee2f891cda1a620bd47f0cee9969576a3471a263bd4ffc730a9731d3c4fc098c415ce5044e95e0f446d815c559d0ba7ce164480c0751aa918c70f4d55580a698ccd80aa10c60273a0ba2afa626ab4793f6e4fafe4bb82ad9e89b3be9766c8594180cf5baeeaca1b9f1afa0d4a978e613de63eeaf4d57d272ec31592a6a1ac7bbc807fae14459d2f944c8d548dd58163f04c09d815fba51794986e22f4c7744f339a09f9d0cbe057faf09f8be73dd17a6114f51a3a5fb333f8115379cddbfdddcbb3f0049394192dcb8ba545ef501b681ace7ff0cda84d3692a80ed6709faab224da1b16e3c4b9bee265c8962a72745d53ef22b4bf18648e0b6957ac37087646e834bc349b520524262955094c6bf5a8fb7f7b057f8109a85d0e04af84e00e1dca65c4ad4267f9a594c08d3d935019ee7b5337c5292500dfbd4abd8ce9c1a5dc812fd4e7d90f8d240005990034a5a8fa40532d75e8e7672a4d4c243b32758413efb9d0847fb30a70dc608eb153942f2636b57f85425e4f8e56ec0a9fa3f5e6d20bd8bd9fc7b2108d4331b74b6e75d7960222bfd7ce38f9bb2bcdd1f35dd90270d77109b12adf88b791ac2cc2030f7ac6b70157bab2db9258d676da6185f663920b5d539808d875c46cef6ff310a5ef8ea29d560aabe10a8e7d2a077695ae8ad0f6a21f14c5b27bcb22d5e3b55da54ee4c1fdc1918de04e439d2f43d82a55e9b42bfdd961b14878226a27cc670fe540cb660c78c0ac9c5519b4b531bf49e3ac737f2adc882c1adbb51d3303f3772c9f6499444afa806bfa31513e331116f5f92a439c7fab99297ef766565a9e2d33779ffa2bfb0f761819538d9b56d9e6501fd0633b7b8c051ade21a653d60b735b269131520490a2361f37c158f3ca722c9236f70cc421a5cc2e9a9546a840ea7c7e7d0901d72aa7540e1768f325ad8388247511d4ccde94acdd1d2cb897cc0a2efa58387550b0e57d84d144db93db86fcac3c05d4b15195f8ee73b2906acfcda369f4758bb355d420e1f039f1b17807b7731acac81e68083a9b4429a4ed934b37a0e5757acfd28001770a1d1a8ba919db1c407903b1ee39a2f5ec72a4cd82b60c627e13b26f35d779edf27952edd38b4355a25a179d51fad1dacf4cb3756742971ccb2d520ea5e544ad8320c2ae4dee0be2382507963ef7afd771ccbf95b9632b84ab3cc8f0ff4fa4fb8141512e079c3a4e60ac2f41e3f71f2c0b56bb8af0143d33e5be4839ea92396a69cd8c9738bfce29ef02b7174aae753b6dd18a165781de48cb63ee92e5b9678c4395f16d274060f7cff1370233628983a8cff3849e0d3540661ada1cb717926cf00d27828af16821b69d0b2729a967788164fc8b44b3cf35965c686c0427b75bb44fc18600de1351ca992ce7e9ae841d2528c207202203a9280a5a2f1088b52c4a368cb890b87dd25f4ebec2dccc87666b44625dcd460c748884bcb82d0f793897e211ca2c7428f293ecdab85eefd0a02b540b4113fcd8811eb87f880fdbb8fe9253f77425ff2335b66a6c3ea68569d3691cad0430a843076c657ea5b708d7e1d59320c4dcaee6a2c1dcb1a7cc5d4f5ed79ed18322ecbcbd2982969289359967929336583642252e6320f9b8a33d99ac50f27829324afcb30f91ea61c9253256fbe7bd008305f81fd0023a647ef98c9e6814dc08645897bc0b6d1699896ef8b3b516a761f564a7ea53ac712c0f27cc2efa18ec0e9f8f8428bf376ae8a653d32ab1ab6316eae2fe7787441e6dd364bc01dbbe0c4b96662dbc9aaa00f9287577147a212b55675f0437c0aa9caa6025d85e524a9acf8095904230068004c07d4ff20eb33b71e408513afc82d948dbda050832bbc09d4ead28e85a51bce33e380253256b443b6777d14aa854a66bb590552e5cd25cd0e8d41fb7b0d41f3683d4c9311345ab1d3100ad9429bc5a869c0a831943ae0f4ca4b08deee807a147317e5647f8d889ca6993bb6259416bf38478024fb1cd185fcbcafab50b2002a516338d79c953a02aad9dd04a813a0cc43d56663481130189642cad8a6f7154e674031a47cdba92c9b1d7095362dd957c60d6746b546fa93260e2e71dfa153cc28050bad6b2f1c127ac926ba98f13738b1918fd3c6d462e8971cdc73a45e5f67d91486ac7e41a9bb06d0bdcb44c42669ea881d2b872e7fb3db79219f42fd810616c6ce0e8b4569c4f9034b295929c0fff4214637c589aaed268a1a2cde6a944330497ffe326d07b3a614aa4fe24d2e8f63463d1c43fa22b07b2db5373e06cc0eb24388860f0ae55e59c6d31255b2663238b6c002259879a620e42d59dacd934b4b6327c1c890d4766e96269b471c1b4954b7d8e67ee10305408c59c992618cbe6e3c9d4aa686f45e806cafc5307a5699c0de3cea5562870bde6fca5ed5ad67d7e5d636abbeffdc51002b9588d7e307143dac6d758fd0b485f573c051d2f5fdcf9db8fd214461b2bdab4c2a8f828cf4f9c7daf8b374ffabe29c2e8b8aa63b5e0c3e4b5270591d5f9cacd97f7ff3c2213400f285d6c6e279ca971039b0a6449ae9751327cf011140232a87aa4cc463897ab8f788ea3f64c2d1b97bfaaa02c3c96a299504472852810dda1755aac7b4af8e077a09b9565858fb08e1dbcfcfc63613c1ea7206fc9414235656e6fe044e5b141282e5b6a1a2126943d6da769a96719806318ff56644127af1b08bfe075904d6e024a95f0845eccd494e96ba0b7d5aec7be782274e9381a6313a27765b7e844d8d1e2dba54acba10ee1086245f9828a70582914f64ac1c9b875ca8a88a30c2f58c501d2009729a7dd050a39422096ba9d4ffa5cc110e653aa185d2de692ea84493b50c875a745308a216256db0d912ece86d403d10c734100e24c7f20f02ec8b6b34d32cfde5a2513ed00c25c6ba806783d72d008f733443541a9972d3207ac682261a3f23b6d5123642cb72c8e0a8fb97cd59f33bd1430a8d7a8ee4180e14e86eb6d89b24287fd56229e545b267e34fa1d6b428167b8c5b7c5ec89a5be0dcdb3f32d93a7e89dd294d9c18d8acb4e037bb2da9e4290cd0a8220b21f0b385d3b0c5512a57a4a1ad6da05d6a1fd97bdf78d508a520fc63e79e301cee3267c38ed02ea04ee19281e96c79f8206ed21a662ae29d1daadb2c89686c4d0ba0bea81256a6313c8a2e090363130a8a02e0c9e94f2433f1b89b4c19b47d4c373b5bcd21b3437714db75ad5110facdd4afe979949911c7705565600b491e4d2e95b7b4d09e7ffa12128fb3e3374695a4d6e9159ed14ae2cbc1a9b0b01b79a8aeb61585cf56d508853e8b7238637bbc4b43653111b103e47fae28a24aad9c76b0bab0ea516fe666b415afe780be544775c8a9d54552e7368c4dc08b5373b3703705182cc201a511272321fe0f22b76c97a774d83d530d48c219b504ebdc9fcbf0c9cb147fdd10f7ede87af53b3682b40f18cefcd0b50c945878c7fb0ef6600cd0a8ddca93bd263428b06d7aef2794036da1746e05062c6da18e3063c1443aaa7460ad89579669aba5835edde8d940381b8b755d96fd2e6a8bf6c4461ab5010752a049e7b3bcf8c58fbaa00a8cf842aab65043d53f3900f0bd487cbdadc099377500f347a28a13a243fb25aac7daa22fb39447406b8b7ef02acdd46b2de9a54f58127e098b187558421341d10b9b859aac9a6cad9b2ade70176c9b866dd1adddfe860a07bb5e6c8efdfc061fe980ecc442e1edb13e7701940b617fa82f2fd417621541a46dd140b23748591c2f94a5afae9313100333e5c9c11a2915ff3772dc9a0c1f1ba8f081f4af19705b5863b7f97e6d0ca67f0f7edca7e7821e92368cd80ff6d47b1a1fee0b907d54c6f8d8fc0f18b0c6c80f17e8f41443e7176935c6f1a07b55c70a0caf6f9f666f02af15a6299d3b41779e0ae57e78f9b037ab4f5232d98ef93972ab257e92c549cb0f2a9387e962744278dd3feb6062035acabdbaa77666beca8317e6463dc8fc9af8d0bcfb22db19721610fe2a2ecead97073fbe3a9cc9984fa9e229c44667a89716c41ef4cffd767173b35a4eaeae50533e3ce2dfd91b28da71d4a1f12a188dcd5e7cd0bbb882e34efd66a0df1bce1278df7aed5a96735cb8fe3f3c87f7c6fe53070c2e4d7dbba94155254a9f9c712d4ad1f329dc9a3c2d58d6ae010db1cae1c43daddc080a2b9dc5afc4d04ed9217baf848415c9b92da11b163a90e732d47039e89fb3b7ea365db031a4ade07ff8e038b9018286ac1d3471323738676d38680eddb3fa781038a07d34b4f9ae53834bffb39bae30ad81eaf0b7f2751fe2993d511715dcd10fe30982fb9bd81f1637773bbd423022f70776ff840fcdb975ec6073f31f273dc7bc06070971aebeaa89ee70007a1d5c500ad7a0c3d281be71e9f0c6fd4206c1ee906573b3661725fb7e0753ec9893a5c5d03a77a79f7be8d3ba0c1071d1b1eb7666918462b7a8969b84dac1a0bc23fa79b3525f27f78c0ab462238dc6f7466e2f03d3f4343273772401f45b3ba985c27e48e16ee0ea46da59193a435ebcf05e85d0264c1b89ec8c4310ec2ffae93774280bafd1d564cddddbe26b4cf404390ed79cc945f3cac65a1c4bf0c3ce1430cf2d61a775f56706ade05e533e66bab0877a5ca729771a3d09476e1998d4df47edde20e9ed5f775ffbcc11558360a66753eca6f0c38be6bca3e3b025c4ae62423802785d5b7d9a485f088f859d3248d1e4eae56f54f6819b6c0de3afb95fda9936ca38b473fced52be809fdd6d49e89cf28c5c59c59d371d113679175e9b810083212ca4bd1c7a960492b040a84d975ae239beb4c26201163881ecd793855e9bc2e0728f2ff73c00ceeefd32509e54c13710901da0a2cdb7ef9378bd4b967d16333b659d30451be10ea866f1b649e87c166ee7bca308b855b71b45c4d736d2deb87370d5e3688b7069cde39168c4187b3f09250415aed91afb671ba232cda99244ed8315705ec298293b64cef23f49ca2dfa4f81e7edfdb2dd8fe75961a3800cdc4ad1132ae12aeb35181ba42cf9809a93526f06f699fce7b3b8abfd6c0b295351e83d1eb9164a205204d9ca00b153d698c528f5629c7b1fe226c4d773de0cb21b65b33115b72a8fafe70d0c44afef36323b2a640b13861bb3aabcb6ce767003838101d0bcdef689920d744e74ddd3492285129160d0093506799722da52fd2f71661b253596a066125dde62e07a8adf1380a151e37c3cb33667d5eb27becbd6995e58d503d8fd0dc3ae4c3f19bd79c4f6790b1b761d4aa108ea4786653af1c06eef6bd0ed95e6b18867aef7173e90e901966727f929cb594a554428f6ef58b38e7922d10883a14c54664ec2ce7b36481ee5b7669e25f9f95d225be0c47b5a39db0fb3ccb5494dc05a383f919f3de90e83d244b6bb0abc55f8e2321cdc7e803bcdd845a08250138d67994fa8014ef4237ae1cb549e769c82030c2c02688cfb8f6ac34ce79810f7ffffc4d90bd56f0a33baf42cb3a7bc53c1b9960c3fbc3968bac31be7439805e6d255620c201554ffa65031bf9c64447a170f7212e89c50c2709b44697d0a047a595b2df36d3cd4500abb4db4c929fdd7e256288320fc6c26ca5200bd61ba2505c32587b7c69b3abe72b43df165cae351ad81b638e4408ce5b2119b064a92fe8e5a21bd6f9f1c9f58876c5dc637838c9d330eeae387dccb70b6ae51eebac82c7829c99838f9e32d41b1893af0c270f4ab798154052ff249a18d5aee1102fd8d8de7024770f6113c2875838f4d9b8eb01feb205eec9049bdc2e85848063cebc268675c15c0d555539c051b2fb36901c2e0501fc5f70f5b234f9295706220e4408a7638dd26b3cf27fd8f84fe097f82d89e02dd27d25f9b44e13bd1cf20826878cc8792f6d70e42a2261a8b1d4134127c9d8f7822d2ebb8a8b14695bbb9254cf23ba0c833d4d5ac8af97981100c54730f1051f947227cf21f0303a3ed4ef51a54374ee26a354f4986e85823680d1c0a4a9106492933920766cef740d62211e222070f6db7ab9b2c35454da2580b3c420f61ea9f15df92a76a6a5e2561e2cf447f0dc854291401318ddd2481b53cf8b9bf78e85133196999f18e650f3c93c4549810f4e2274bd3ded940e4db4ca864e4b3a77457a7f0018714d3e25b26825e0a04aedac3181251b24239726db47f69f27701f900b0cbc7b150b2d47d5cae304105fed63cd02b5eb9cf24a90ffa84e6627ca512ff34439375861ee34bcdef86c0d087122bd93285a8c49b139c9d9548adb6b8b5550a1a0d0e6e296ce07bed7b2821ac14015929a02cea8ca254df6928bbd31d8b573287405661d1891617eab2ac407ac644cf27d43ece11969a0c1a821b5bce999bcfe9ef98d01df2d78d1c9515709a59aa2e2aab48c6786f999102c9239a03b95483650787efe6d06662636514252a6975403250d0b0f318a3965d28cc5587d9db50573c24c52c0f0ac27c0d020faa7703cc52b0a5ec517c1a45e486860905d2c7fadec155c187e2d733fb9f7c427cf64c961159de7f8172c55c71b233417e796cfbb25aa955216576928e2c149be021e2a7906e748f3f9bca0c8c02dd484b0d4fc60af42c34ac2d3a3ae9cfccaf6cfe8e3ff2ea8d62664bd4d240c4f800d2221fe1bfcac9085cbb27a95b1135167240326dd46bbfad4d3f82529aaadc8261b47055977cbbcbaa76be595d1c811992cf7d934149bc6d9036d701d4d44e646df4e4826aae2e58dcb9504ce079d53005c629bc06b0070f5c56d9526c7de1e4557740530b8a46e3c36cd4604d336b0fdd95bbdf4fb02ce22f786657ea65f44609cebdf1ac821d7089d2bc16474148ee660b13285305b1fad23389add7686c556fb4a8d9adb52e89613cc3a0061e5c636eecdc4e85d4b934b17ae02adb044a66b6d5bfcd8f76adfd70d183c4ecdbcf616674b145a36457ea1682b1a1b412f32047931e5d8c6bbb872f7d9521604d628a87803fa8161b65d95ce4b024425a13440dc980e601d7342dbb87a2499bfd18d7fd7b80bf75416cd4012b8184187e16fa2761dd7dd66a01b5da692d6463c38ce93aaa3d8bcf77a1b6ca26d2cfbf7bcab6222cbc9a162692e44c8fdedd30d4d6a3685f98b4fd7f53e6dc81419d70e2d13b402a7f68cfac3f69f1b0e943cb779a22b44c92f5581aa41b0d96648d68b5b97164ebcc8789da179e8eb08d3172fd5734ce9c67828f17cca0fd1d0f8878ff195408d2b4d6f2b7efdaf3c5367e57f8577f4a2ae5917e9ed01e7b02af980ac080201db631ec92f245262cfca80c849442b1aa5dc882f7dd16b91386605d1b6d88d3d43a7cfd2d33a8a299bffc4da94990b0486878474761513b0136677562dee77fc71c89d471a5fd209402e8d37e458c1913f62cfccd80175289589f6560bbf7d7302ef24938cd5672968304973432f8c3c105cdcc6c8957f48e9b5e148be1f7906b9cdb66a69759d5c5247737d9fb1d30adb160933bc6f66f94fd185820b69c83ec0fd346efac5d8f03fd6c5b527770ba773395f6a4a0c4a7dd56681feddf805fdd3407a9e2281c30defaf2b14bc806983d4a1cf4b6df7e1dbccbd32c9efe190267fe089cbf98f574cc5efc231f9b45a98efed3108e4f1219b3c74cb3e63f85b6af3ce386428c5fa2e68a17437a0aef860373ad49ea9b80962f8a6c0f643ec68ed3e95b00c2c974621e93095d0f724474b99db8be338bd36fa40fa50c312172bdeb43a51c780e0c23183800954470321a7c49a0675cb62138d275bb1ec8fa5c608c5aa3b25e4e5390f4613e0ce59eda8148164263b6234cb7aacdf059b9af9b9d234046dc3aa34ed2521a64ebb8e8e36fac3181bb01f89e6817c16784b1bd90ddc344c197ebb2ee6dc2988f6682b462fe260e9aa31dbe91c5960c9f7cc7cff5ebe57367a01d8be1c78d0710d5706b926b5b215cb52bf256aab3226edd5cd63f16f02a82fbfa89b97aac0b3f8e21b25df63efd032572fdb7cf887f19d39bd4b58e596a26211789e17fe3dceea453f42f42def61189f799db6a6562e5aeb8921c18745fc84aab14780fee1fd7f53fcec377bd97254eb6fe79fd4d701118f7de6fed1a1957ec65133785e003c23636b3021064256bd02f7c4f5cb85245388a1abaaf46e0fda08bfde4cef6c213cfeebe21ce4d9c010ed71d504c377fe11e6163ab35aacc277aefbfc832d863ee721b39d8e5c3ddd7210bb942bfac583e9411ce2c0d562de6d59e02d3fa7523afc73fcddca739f58fb65da3ae0f274410205c6ee39e2afbc8b967564f2f272e6875bc933680470f442188ca1ee44e5d7133dd7456f19fb95570a39a1af2c31705fe9933977ad7f469eb8c6d1a06b6606e9a095b82a4e1bdb6f40561bc4db979367dd278c339a392a65c68aab2e7388b99cf1984863ea154e2228a1293686d9f8d4e7b96b04c4e280b6333675f1e5c34ec756134a220dba203b1c9ecad4fff2c1733030913c35a3a91a2616dcd9cb7210ca27a3fd1b8ed7c18967a76675b3917fce28c093f1cded9a1d8dc806d53116c328b5c2adbdc90decd8ac474ab43c7738ff3ee8bc85b9672a092b62d5544ab58bf20e344e75bc1d2a7bcf05a25339c85915588488e6a902a166c4163653a5e55953dbe14c0152f103a9257dd831d415b6d34ab20d62a9e16e6a47e42ef36cbe93d98016000fba290308d946ca776e9da956d562579f1b9361900be08b64d8eb7934cc78e2695781fdd26766cb9700cec9ead61521c18f1c6f41091fdfd5e04a1d93d77c386389b7f499570ff43a0ec545bff3ceb9f43288a7319b0854ac63c2dfc1d62942c4183d0699235f2cfaa2295e48f25447de361c92ced76d91f104d1815b7a239dbf6da0434ac552d55247c1d2a8e3592ad0b420b5db96e015cad80697d4d8d05ee49031f08f905733aad92be13e856f62455b75535474b71048b6bb8030b1c30dfee610d6ff9c3cb9a8090087f56b80b656083e121d456a76b6408749eb5c02e937950665be2a214459632a60e7371413d8cbc8f0224210bd8c1a794d7c6fd4c1f5871814caa76a33a58c71d4dc878fab29446aa0717f5934ff045477e82f5622f10e11de2f7d9eaa6dd63a4900678db281a698fdc790f4241b6e3b3da9e2400beea63803876b8084b2114b6a052c86df716fc1585f917e421a4b068b826e8965240fde3bcc4adeea98e2b77f788b0fa805553c25cff6b5852003eb60a201fb7019c5a5aa17cf2fb87a6e8921d952080981c0c30b19007e9d2d15444966930080124d3c465a2c9c43817959c834f4baa61983a217cbd419e832ebae751e106d9bf4dc883c813d48d83776629aa78cf15336bcb1e52409748cced9a0c36b1d2ce301c06f482ad3c35671c03c52e496ea83ad1065b0b2f79ffb1365cf17e2e6955f2c2f67adf6671765fade37ec8c9b35563186bff4ee00d1ba6dd177c0e4053d0583d0e25a385fd0697e38f688e4cad90544b40aac4e403ba9bda8cb835488e7b734d010637d0b0c35f912f3abc5ecdee14751d7e6690d31c8999cc760f381961c40c52f3c78de27c2941f34b95a012c9299256edee3c94262a6aa24354b1d151d1c1b78a736c9cc4163b006d14678435f56684de0e30182f01e10023f72b18fdc4615cea93d391dcd926024de956046a17623b7df42ebfd98941b32fbeda9a16a0d5b0ecbe439a06c3565a6ba8bbedeb2e14557e9c5c5fa45bb9d9c407f4fd11a416decbaae40f111136b21ec2a0c78b9a812e77d299966e0eb7a1062bd174687d0b81ef2dd4382d32cd8d007a0b256d2663167717325b6a8cb69d9a2beb5fe614a033a5152a3c68a3b72139486493051c2f50c37db3f34ac4fa17acbd8b5b773f71f318654a170d871d7e3d21d44f5805d01532ee74d5943f93797cabeed2bd6b4b83056f2b11d0d60b1117c599090d699b2e6b0b4673913012607e734b097378561440f49a77bbbe9d6e0f6fd3f40b327487f9d67f92bf3c6e526ae68f288febb7438bae6b5a3b1de8d6ee74176440965cff6516d9588d7eb7c8ec9441006fce6269acc2b355c7a09472c93bfdadb2b6434500a99496f415a03c1aa3d8cf56eb68cefacbde0798461fae4513d98958d4062c9d9146c1269012771c5ba9310e605b6970c6e32ba6571dbf19ef5800b0da38ed5393c8f2a41220b4d75d0a925633fa9db14d6770475e304f79782617016ecfa20122b4d1d4423f08d40662c26772861d1e1cc117cce0ce0750db81e5d89c34c22caee03d69cbc33d828f6bd6a7a1605624bfc3df33d36fa106523679feb9f87470b31b51e6e3a436b59ee7aaee8861dad8015444fa2269946c595c657babed401a6de4aacf51245096d6ec284b02ad0c8b9812efba1c996afb5bad55310f1cc030cb3034f4f849809e6848cadbe97cba7316ea73abf54d8aae49fd3c84c00c0702af2fe06d4e8c6b3bda0d01128581765feb825295279355b95212e14d454e8f074a598421a99e56a46f07cca808a0a7f2aa09b8009cc7752b0b4c12371bd051098c8332c401e77d94682d6d55b3ee6c82721edd9f60bfe01d5382f3fb085a2d9c7db478c1d26869caec2b532649d77c328d98e47bc11092148d4da5dae1ab0541fbecd4068b29ea588f0d02f6db03342e4288e6b396a9ea6b18fd0c426daf500e8610a31cc3f4d54c87c4d43092adc474f3784fb90e2173d5a22536b534effc5014b01191b64668cd5184359319b327749d1403999b42e0fea6cdaef55a79aae56a963965420eafb52d9bf20ca997fe56eb551834a541ef0df99b378ee57b26394f36c82b9a954641058f03e0af6da1856015ba4df3db6af440f43500eea041f2a8a78a08dfa202ccace64763cc226eca61f56a42922e80645b216c49fc01b523d1498c74e5a7b7f3188d55c5e15c877c2c3ce406fc8557dc802fac42a44a41205d0da45baf2b4f64fb85dc4300f95c855db5522eec2abce7c78575170bc90b943235928f5b3a86c867e7eb4d887c57de143fe98f28514a0b75d335454417250cba8ca1e30af294d61b2e74cdd8b48700b9cfacde25486bf24767e2a04c4ccfeccdbc8fcb0785d25cff2368fbe18e9ba86ef6860915dd81462c4c43077df85b2b354e0c92c05708be612173c6d1f91eafd45a766ceca80e6482bee906959a8a5bce6f39e53921a6257aa47c1dee558888d8bccf4615ab69682e4b4d18cfea15fbc0f3748e89128f0f8e3a68922cfb1965b8410c63cbede55bdcdd693f87bd7d04df7be9b7e379a1c93c63ab841c0a59ebd062aa1958d850aecd1502091a872c789b8fd32e4fed0a6ae355050923143a4c42134a0bd0c8a970a5e37a186471a36f171eb0f47309c8abcbf37ac9ecac27fad5f581bffc36f31b24fe914775502a4c1091e20580289371173fbdea2b1fc3c6ac3547e41e7697e3647f6360417fd9abe14d57c2ee7d8794ad42529f9fbe55e24428fa2cf3c4dc1eccc1c2947048960429131b571580879079c8237a7dc0d47b4edeeae04d0baa598ab99a7cd9e90bcae832a90d5284546fcbc983ca53b1a9e25411c126bd1b961225894ac3384a35fdc2b32e076ca122051087222c17c5288b77032644cccad00f245e6b00a14824382ccbf082d1693703f3021e781cde6146c53d846933c9c13a9f7a32dc5bcf286052749870bdbfa1c05f397b068e8425f558e910a89a7c4ab955238a2b73d7801b5363d7b4802433159cae48f8fddee360286c43e5eb17a825480f476ec947d354d70269303838b852ed83ef9d13e9de12ae703dd53a7817a7ccfb3233bbe1e061723d0e4769f5c9a9b22d71c31f2b06cfaf48c6b1b3dc5bd05b26fa7ffa223ac69e269d08be89f13fa239c0cfee431f87e859bfb585416bdbb1f43552a2f7f37a5e67b002271497a54808a9edd44554167bdf1c958a0c3837848b19fbadcbdedbaed3261b0003d4c315e7192ed0a0d8d2857cc1169e6fa1265e0b4d46682de19b44759b2506d5afd889ea39ca26eae7b932513469bd3eb4a18ab00d69559b5cc8109c7f3d1d7d0df1f546448a690d82b90cadab0b0f9cc285d951642391c354edc19a1e5d6677e41616f419935397e80598006176210048a221450b6ae018a683330ffc9f46b138e478b1e40ac9d61b08c41874d113a8103b30010f9df3c4c6140b84c15f20402b2f6a486d1aa046378ae94165280501760dcd27cec04e62ed91ee00ccd3226a35546d6039fb8022d49b1405a0824b73fdaa0510f1e444e8aa6bf44cdd04905615c85028804059eff0d75c6e8650da268723a2c1c042787201a4e7ec5eff4ea6bb1d5c71e3e7ad3ae72a669f21ff95624bc0c00e905de3d1c1cbb0e2e3f2a3b940af3dd45b30595c68a13eabfe71ed4015cd1520bf11a43b104531e9eed81e84d0cbe95e8575426cfc7175bf30a40aa945f1ac83af0afca111a1f486df0b99784122af81fcb1cff9200e4a5116e0645dba278a3dfa616452479aa63b07a9c81c5ff88e4161e29698bfa77fc4be2072028306134c94f3de87007e43a5f68a0d22ddc9ae5100a1f567b7e997c338740e38cbf80b98d52508e4dd78c948af15624265476b1d38d170beeadcf1a7a787091500e019610a21a00851ff60a4a120e9db110921fce1cf64720f11e88a2dcf7b1ccf095c52c4d66685c96a5a2ecb7f2babc4171d01dcbd6172b8babf43324ffa0fd23468c7dcc8f2af74f846f7516875d7f785e948f968ecb528b2a0039e55c049d0780bb8045fee156e7de042ab9f1830daa41d3f55d7e380c7a774109bfbd515831f932057c357da4ee328b76f4fe05a16739276255c5fbf57fc48e99869c0ea38a8d52b2357a0d95fd7f2a68f6417025505e479968b14003f031f93b2275111169902b53435a9fdd4100726fc8d292e0c721e06489c4a5a85d4988d16273cae8aef11873ff711f6a0d2145675ef0bb14c703347ea5606377e1ddaecec1147b2de9f49b6f32ee24575891c68108d04642cc23c90652518a69eb745001d83e712aebd8dae95b9f70588269b663e3891392cc66de6cc167edac48d342ac492d9742b6c22397b2fbbdce89bb0f42a57e3f1ccee80941be8218b2f0bc8582b753a77afa407782f25e6eb8f688bb8c8725e7ed36898f25bb87e3b91f5580afe27adec547f06e5c52cea00332f84bdc801dc2010eb09dd04a1b64591594f789fe60eccbcd885ba84f89b2c6d0fb3719302ac426bc9ecea0f3f97b4a21389baaa4c58c670cca5bf76cdd307f4067fed81252f91b03d8a2b669e3a0bb4855b9a467019fe7ac3198764d9e6d7e6f81f4661dfeca77403bb56d7f8602f8179cd4276866f5b55834350f044a4bbdf0686d53c883d19be0d971a84f4bbfd21ad2f9618c941dea42eb2473a358bda7f7a1a4989f3c8cf278f02febab9c3ff496cd89a91e32fdcec0387ad2fb13a22e3a5b938e7c6b937bbf05ee13dcd0d8e847c7b34f2d3fa27999edb7e996ad8da1811f633364ff07cc4f45f3b9f90cf6f34b097af2678f46546c17b420102ae6b968bc433766519bc8523a56b55653060592605df17f561e80e55249112734a67fe3deb4aab44c2d76df0c2140944493b977d26ff0cc7af72a4c832da081bce2b4b3cc2a183da770e09c29e08d817e395b1edee01c25318b3570d8df8b136dabb28103a039473a851e23e236d54ce5282709c8524fcbb0fbd797ccc0314d37633d0745670636765c2924d6f760224b118a0a833b5428218a4c94059f61932fe8718a95c3125525f4205dc4e2ecf3f624ee1f48e4ae4c152ea38beef8601c1c6aeebfcf68a11b868d7a3ecaba855ed6f419949533b33ddfbe8f26cac4a254d7079c35cac3f10d990df4d1bc940f43cc88ed98869593f6231c5a5bf0bce60bc92a91f9e54fa10cace175e95d85a81e05067c04b4364bda2499318d8290f6360f3c952eb1e9f3d9d6a22cdd3d8b5a1e72a6c22605012c45c3269ba52d1a383a5519bf322290a55691e8ee0b9fc6de804a70fa3ffdcfbb6023b5d96739649e731f3e456bacb04aecec92de5821cbd9c22870c6191babb67d442c199112a1421276c11e41161b00f60184a5907be0b544aa5ed189c268716c3d9206e6595a3479e5d4528ab83125dc0e69b003e248c8f03089a8ed4756605c9a4954673e69a4ff151ca32e6e78def80fe139d069d9087ea1bf7d36e1906482c121dc98a858a0bdd724161880dd3ebff7cc5884e902efb36294aeca9a532c0d4f58a0f85b554adf3301bb33723d0290ff5a31b69ffae7d7a6a65056e7fa8afc588e09bf1aaa4d3d9653e893feda0999f95d3a34193357bbea6cbf46d350d9f9a5db2f043f3c2ef911d51266178d66c3143989b78c6902ccb62c98faf9d54bd5b7ea320fe24cb98d5ec99a2818602de23e1281f1184e6a7c1ce73178945e841f6262a169a71af19e433947a29a251e3cdc3d3e5727fd47ce76a46fe36b7eff2df7a6127940aa38b615da4426438ef42d61ab7ac30578c75c33de4f14246fdfb4bbad37981e2103f32d5b9839c0a07b0806c7fd1f6ae4165851a79cf7908e0a8e5ffdceb1fa7aed3fed737b35cc7e92262e47ce11f43e06086a7894ad208eeaf62ed0e1237776013071554942ae268d3068d061fbc1d8e97cb1951d10ed95b0c93fc137c18a222a7599709a9cfff956e6e4e68280e269656452d5f91eea2db2f9bc386e6d23046c429e4f0b181ea3d120408ee9185289e94305ad51a516cfa9c7c39c58d0f02f3415bc55bde42d92970dbb178e2bdd7f386fbe5a1643f32ef37b7f6e00a21407f451c1a5de7b9b7c898169b84b3fd31676a606f3435a362e982ed940e3088fa4f60f062f9acb331c8043ee206069f5d22a8806772753f0397aaf6425e050ca36463277a9e0b642bc998313b5165b5f1e76b077be3c5138e789de7854149adcc453ac9577ad49f98aef78712fe11d5250d06aebb5b3c334edc8128a254a0da5809eca26f8e500f9dbfe6f25426bc4840078d3f0e149167a38106660ab00b8f1751f99864b4983a2ebfb4185c3caf43b545c09d8d172816fa98fd9b284b4b36f9559880fc6de99cd752e504bb18015e2d45e6295cea68c74ae05b573caac4563031b31552362512a796c54431aa5b60190790112bd2c8a11bc5002cb4aeff790151269368b27e701f2ca1a4cbc03285a385be94ca260d1e7425b0a16e5f6e7a0df8c0cbbb44adff83fb2327ffe9afa7589134099c6981b2fc31aa49020f945d2b74460e98fc53999c211e3ff89becdb450ed8acaba68d2c05d0910c918e59a7070f3adc21f36725d020d424b821cd6b679391346a14a8dea967c78c13c2e079b5ec6c06fb2f8c2168997443531be1688557b445b048d75563b050c586c3d77e3e2e107efd6b7426f1f46be991e86baaa16876b218908921da35ea9bef197f9264710ff1d5ff91d1765ede86c35e4af6fa1d5b87a72c0309a30481d24df0ce01f990f861de96f897a17e10dcd1c39464e8d8730024873c9ddd87612f2b354e7cf89ad3d61bb3eafb5694f19446d6e2f7f590cb2c914c5a2744b14edc70543403759b9364178b83acc548bfe4554a5dde05c3a82ff1c7198dbee251209bddffbe640e53874966fd88e414d28984b981dc1bad5dadd948ae991451ef9f8e6e044bf79ee9a3fd98bc989537360e7d1e040997dc04578e76236e08d93e3a2266ebea579b431c5cb3fac77fa0bfd7f68cdba87722bbd77905d6199a971df1f5ccc425f1982def02151e97a80ed5d9241b66727dc2056aa64fcb4189820f0edb0cd03cfb51efcfce99ad3e82cb24caaeef0f5ab5614e0218464f21e460a0f8be8db5e003883a920401ae97ab5962b30ff05301d57b315e94b68ec15e0672947cca6b0d62a54b7f3420a16f48a8f3ee238b0253562021767118480dee5a116da75ad65e0bc9c0d2ee78aeffc14a5b8121c68d04d564b759dd6606a71ec63866b78191ef3cd7c74f2e6a0e9eec1dfc663e19efde1d3d4def992ce2f97b229d5b4f7a23b766579b2e26810c3b4130fb8cd991839a1588216ff048184e945d37e8a0f860f9698c5355803e59860d119507cb78f1e0ce8f41dbf928fbf8995be21aee43bc3e7a419167b74286dd220f453861a6801f82f179243ddc7abf38f55b18cb407f758ae56353eff775181b5f9a3c64f390ee086515b2a2962eebde92e63c69950a8dd2152449d820e5952c0656613382040da60e46006cbaf422b4f09180de8ff4d9f8f6cddff40c08fd6ae3a5bec21541a8533e6033bcee2a9184e13d61a9d96b8a04c3b8bcb80a565c7e7ab757fa97f3ebedd3e7e3ffb5c613fd310e22b4625e4318334c40be7e460c4bfdc6aa42928d53cc1f6a2e255748aca70a9d412980d8d8d7f784f7b3d123325eb3352f89ee5ee95f681e0e7d1c80d5db3df4ffe579350b646d5c47a6ccf4379b9ec4c18e8e979487b7b0a43564c91833dd2948a49fd988bb182e7d9cbb1d8038923ab2f62e1ccde1b009be4b1a3d2a529c8109507ec63be56c33c23b45e54c8d209d853af451d71ac6fe8204e74f3c522e30bfe23a7c28a4e18acbafa818f0f068962a35bd4cc2aa64bc9702dded0c29da39b3884a8fb8628c756f9a9f2863151059e2d8dc10275e71c70c2b902e9ea9cc987cab8c048e03fe0e671a5a9605eb19af49290cd126ed42cc2c85ae4d6c0b64b546423dcc5f0424aae74dd797110c544a3b54e53881c25181a12cfa0bba2726ed7cd3965e5626f5cd75ba8e1ebb80c9cb5739e0d08c8756ff320358cd4298e5019032b16c6368f3a4ec9311f6c58a48ffb2a190cdbecdd0a2314b0a4e81986de19cab6e4598f23b1ccddfd4dcea378aca6a4a47c8f6cf0ea86f974eb832411631ad788051c1850eac27a3a4eb17e8ebf1497a65c9118f4386313a809d21fe16319311d6a50109fcfc26ed215f9d5ff26c3dbc31dcd4cbc3ba91586057d8c377d82079ed9a90876b888b339a11a7d124a1c76bd9d3d8ccc018a13441aff4febc726bd4be0e60a9686a1b65d99179d0e126782f9b128b24dcd088686347fbb419f027020611269fd6b787d3bd7d18d1af6e9e9143602f2599e95e927cef7c2c467fd109f98aeb4b870de46e904f164f320b717ad33c6734d157551eddadcd985cb0879fed026160e7d3eaf69075f6641399493a8456c9885381de17e7d0694a42433274c12bb20f35571940af5915fd98c1622d8cac65b7d962fb0017c2c1da343a00143d7980cbce56ee9435ae3e9f57d2c31926dffb47ff819466d4afa28da5cc33e4c0ea19b1ca0dbf0fa0f67d9a6f67d06f67fc2771bd7cd4970df9ffaed760a28099c5b7120d7854f6bc38fb054f7795f85cae371f5216d44fd3251278560ef5c16004416e92e98fad9e521b51b70ea56eb7500af954dfda9a89960fb4b55e9d12e7d81038b1c67432bc501f4d889a5a09a6f325d09a80f99cd0676da9f10390e22972acf1a439fb9ab56c3a0e7f1a0507c49044798adbe6de399fc19ad22a4b64ec2af843a589563c823e05c1737726cd77788da6969b2b8e001d93dd5ce1ca0152d542974120f927f361d218bf0750ca0c323e4802cec8a61aa720a29984b263bd3a7c8a2c2cbd4254d8a5dc18d35a00372acd15045c4e988f4eeb244860b5d07fc2927e36350694f970a5d06c744695345061b00d9564cd147d65705892a0342335509d58ac7b603ea906c88817cac5fe84ae9bac2d2720ca093660b2e890b1e7837c188c51cf70a1d8a0fe05e121adb49c0e244f3c647486e5220f0f583f9fc400086b095f8141f2fda8ad86baba5e110d655b15a2e0b568b3afe7fe30ee12e46742ad0d84402e9980f18053f13d9bd313e650d75d73148011e27324dfeba37930e5ea5aa036f7a24651df05694976fd1d3724bcaaf67448e20020a269032085af281417f1c42e62095831d6e18326c88d8ad8b12c1bb7afa150879a024188ba12ee8c6d750381983a47458cc5aef1d4acee840b99287ae3faabd311a97228586c970726a4694f6da3a41376821e0831f5f405cbf9bd398bfe63d6de071bb900bb06b0ea9cf1e93d6781802787708b700b0575798cb9ca140339d6f7047b4fed698d84bbc008dbcfc0b28df1665da8ff214bcc39a703001b6146752ada5f3717b8d1162e98fd7d10d7c742770a49ddada5d750ace978ec99268ce323603dad112bd701d1ded7ee28f47026eccc34e26180354ed47b2e116d756924cb8130ac82429dc228d1421b273760d4cb010324aa14750db372c3198608f0795f2eaf5a25faa59dfd9250f859b2199868bf12c2e81655f9fa71db20bc303d5970b0a982c9e2ef5ad9b1ab644f35346d62c9e3d678d9f076de3105e7555f24039ad2c5bed8d063a65dade3792a33aa15f5761fb4602a5faac920f68111c67e3e0a4ac02abf777589053f10064c7395f3b91cf8d76503def4832708b8a99bd4c9528778b091fa9128d1e30b86bf2802ea54d6200197b90abe837e108552ab0a431fa4f3fa9ab94bc0bea1828ef2ee61e1728f0829ebb917176ca46bc9fe7a7ea97670a0c5bbfc3222e6ddb4df10eea7ec644fb256213bc115466d79cda23f8272da177719627e93ad7ad545c9be22715d39e54321d66267f999fdfa35a49d96097ead69169f7021e01e0246d083b163a504c8a97e7f9ce7ce386ea079f13474374771a018298cace4485d2040fae37e5be9e82456dbe978b6d293f378f45d40006fd1164c1ed07c2b34bf669f21db54b5b38e67005c4398db61afd6875fa5f64c1373e1f6053499063527ab54b59c91849b1e3932f483ca73b9ca03b58c64824ecce775bf3e8d23daa6173cdcd6e7dae16707733e0d14db4f7328ab096921679a08d413a87028d4ddb7c9b6f99a4bb4368d5c2552b626718741c966ddb1e328bb6018cb5bd1cc469019e979bee22fedaa149373d58de37749c90fd1d7c06afc44db69782a0c173530fa82b411aec49cfcde2efb05a7a987e6b0cfbfb51cd43e94460290eee933e37487951b6e97f2043d555d412624eb406676323b3fa8d10d0d79008a4fd6590c310efe6705ac032ea4357a5233046cf1ddfe7de37d838843b7459417f3d2c19ca80f03e1d0edbaeaac3d5ae80f67e51193377c7346b15bf023ee6757f477ff49a5f00fe12c51a74f490939a4b3ca2ed05b148ba04c81b378d993c39019b728c206416e6c43c41231209170298195eb0b7e0a851d64c8e5a12304cc52938364bd7ef54fc9aee3ff95ef3d84f3078253205de55ef75183ffcf12414d79f31a9fb534b1210b064d922d1dfecaa260ea996c7dbf7668db138e9b71d5706bd96b2c0103fa2627a94513439b73d38b932b589c0d9144df46060f7e1c1d6b1ad87c31aff210d6feb3ec308481a75199826213c4029986d389126cd3bae559d04d57d664d89700784a6ece82f4249a16314ea7103fbc49ae2da435ec3bdfe203c2ee1c7bbcbdb96459aa3009f608fd9fafdf9f0346a25a6cd9471b068f15322fb0cafda9e1a28bc9288c9ccf8c0ed711f53665268036d860b59eb322f184274933c55aedce3a200033a2ae5dbdebdd95fadcc495332883c2d55e7e3b1a538ceb969891072fe2ce31bb4390ce8ace89cf58584898dfc3f5ad26731e549f44882c665674f2058e2bec141cde161f2ab5228ff0260137b55b19d5c093e37695a8ca0ecb6e7ecd0a002805307f02c887baaf7ff878c7858911c8140d56afd1640139404f66aa8438e31eace2de8508bfa40d32b1236fa672e7d26f645501e3598209179680a2ce425a34aca3b18485ae47258dd301ef4ebd3bbb9ae02a62615e85b391305aea1219f3a5668f0d3dcf33fc3138c1394b0124947abb84e3ccf110b4b2a3c49b63065d502e09df0d92afd6e581fa15c495407559c5f62281cd238883c0e8223e640f2b41669b1725e6a640e1aa44a25ea7833b8ff382bfe035335ee98c0fdafaf7330ae7407c242e4a28e26908d62979baadd3b991e5806adb252d84ad0e45d647b3ecba9fa615eb3438b04386e723e27701d917edb72e197ec9dc356aab411a5e18be4a02e73535e7783cf35caf3000cd9d7bbf3a277c3eb59fc234bb83d9b232f4ae820c0da50f5aa440237ac7e0e7dc49e8f2cc5a22f28219e53738ebcde9ac65320af43971c4a05c0e6870c96904b2011aab6d28cac741cc1a15ceb4789a786a4a56b8085131cd7269edb570029816ef81ec1cd6aaadd410b1825be5e47dc0377bef00f94fda70be78bcec29d2ff65d9ff34e32776c33256207eea0be71e586f4ea456b81e275642dd7c2237c78d25584192e7ef90b17f5fdabe3e7b748ec8d4dadce3d310e211ac973321f5f2dec1ceab9a713b972b4fdeaf12ac69bc9e976881526ec0164db57f37e194f02a80162e6e266654808eb4d2d3893be40cb0607742e6ea1a66d208726cc8638faa746fd13ee3f4fba6c39bbef161aea2d0070595b894b007e057db04cdc5f524daf9decb2049d823f49a150853ffab8c84baa4d191af7ca8dc49acce644f7857dd4d04c77f534a5a68da5c504a4cdaa5ec3340153ba0c2e5c224db7ccf335af1374cb8349640d8946cf0f34ea89250e1f25061234e08e7894334e5cbcad213ffccd6085dbf8231f07a4cd2c269c56d5c6f48fd86f566279e318d62902aa3095f1e1ac8bbeeb0f7ef4d92a0a522f46fb1646340f9f4510013a6cf9f3d8e8501fe4f06c966da14a56174e96391979faa2b277975bb97b1c9cdf0147fafdf5b077853b1edc0c8e0d44dce1fe11f6b800da569e1d114d87a316d5727be6c7835f828d365b675921d2957a91919b9c1945547ebdfff4120f5423df8bb32190bea37cb2d19777c85bdf9b417e57e80de7fbd31eb79bf49ba473619ab30432d435d59739e58a4bbd85a6f90064b13223f87eee95a92f90817750982086b971c83ce81f3f0130e78fa4d4d05c6fcacc381adc64f381c66e9b349526734e77e23dda391aaad172174ade59b0f5c1ccd3510837353725c83b53bcca7ccc77f7a7ed6543579bd2fff9f5eaf5ba360459bc6dadc739f36f2c8c9a2171fd27e205907bdac790bc018197080c282d18a92495f181327cf410d8235db051ffeee26a1a03a9bc7f1a20e887dae32160c7341a06cffb4962b7a9359f23d714763bece63fbcb723ba085cba81a74ef7e2b32abe696421046a3cc6ac52c3027ea5428666b9759581a0b59bd7b26a683feb66a2990a30418d453682a9ea35f20eb27659b44f8cb84825421d4909764694520a879a0a78e36a579d9fd2c1b1254c2fbcf667bad77044561d095d91f924e0f090ddf0c86506249a43f53195106cd26d19c2916c71abc5226c18a77971c3d20f54bc4264ae9b3865c433a2ea9644d0151880ad7386ee80302c5dfcfc43c39084a13b02019db0289125d009ebc4866dfdb30fdc943f80b1e274d3c708a2327f89300334015cc86dcddc4fd4b0ba2dcc65c8e16e619b20dcf7f7341a658483204d890e93e75a3876ef28e304b86eda834dedaf9c52d4ab24283e9ce43202b94f6dc6430fda02b79894f03977ad94152457014651c5537656353f9c9dd4322cb12863dd598cb712bac33bdbeaafa00b12ceda0ec5161ec33702a566f04af83cbe390b6bf6dc3cd3ad3ec9a22f731194dd3d4437bf71d07e004409ef43e3d13ea4697fd3c72f0121d1b0120f4df9e62de3a92fef1d3a3d68b3773d08ab2243555ca9d18e7805f514daefa38f30ae31702424406525230ab84eb7b83261790953a4b7eeb37ea08bf49295f481100d66a3eabbac96a2bebf6369ee5805992b34287d9910ea3f117f46db6c39162d1e747aa46348801d2fed9741384ca38cad901ec54eeefa5be4fdf4fa9da96bf4014a23919bb38150b59715ce38c75727242b87bb6c8d85aef211724197ae1a05919b2b360551a9f2135741c9a92f9d3b963032054191c3c2b7316d68e09c3b3a787876f3f3efed44906854ad713c61e4ec611b0aa278c4a139e1db5d4dc14e17152b8ea074c8c1c1404a3fbf6cc991142b0b48e1f973a2c2ea2c7fce0c9d18381776f9f9d3d3b3a78f7f5e1e3d387c36fef1f1f3c393a70f1edd9b3b367432fdf3e3d7c7c7af0faebf9e38327432f1e3edbf972497a4b46dc3cdb665fdb27d9426293764d943555aa8d468d6a36359293e095b43d406cd659406ab69f1d38360b8c22b3b3cf0a1c876dc780f1d9670787ef7e7bf0f8ecb381d76f3f3b787cf6d8c5e7679f1d3c1efbeee1e3b3cf0e0edffdf6e0f1d96703afdf7e76f0f8ecb18bcfcf3e3bf1a9bdd4fba837d4f8d3dee97dd39b697c696fe88902ac183f923d10d3758f99a72789ad4bd903697f6bf228cb1c545bd73c46ab722f3e77b227adb7a2c108680ed0a7d41db030c508f1705fa3b46c077140e4ee93ea49104ee26e244a9e454a2d8452fcd3078d4bc745f5c29755b19a5c115d4051e3117042d66f51506673affe2071c929a8cb371a2be5dc800e724d4578040b14bb97f9412422d93355a936b1a4547257a6562341bdf8733f9d19fecd3dea4e34010193be1fd643271537b820d93139388c9e93fa4603a0484dad04a6059c1fd3c06da2098cd1f1ac234eab98ebd457f02d138f05e997c181df1b930161c45af29a452611537cfbf862e2b741571c8f1f9f69a432ca0336e81f04ff7fe12c60f9dbd503401cc04296d9693eaff3240f85fb250eda341afdbedcb876c938eadc02f338f1340464b4566807e03bcd489f216b945da1150ed076830e0466d677a4ff61a52314dacfad2436d0000b1989891369d8ad4bbe0d944ad4e1012f62d77ba90df4d265b565e2cbeca5e3c961ea6c64037d682a0f3da66fa0c246823b0b6cdd25e9f46217b2c695383516728b7671d62324e02566708d75c5ee18df5768c045162141ecfb676ba7b41f53370c19b0e2e881ac8765a4413cf47ae437dbdd3fa70ebee6b47ba0fef2278ce29bb737737ad67bb31f691a16ce6b8be58f4b7f8a3744d75718bb5cffca7490f47bb0f2c84a5ee555005aaa10e5d9db20de9c4e03b5ae2bb35c7873829037839afbb78f9cbe9e3d06f1fdc48995ba02de3bffdea80eef5882ed06c89d17ed4c139f21dc694f9a7b0bb366ec63fbcf4b8dbe143c60c5fd7021367eaf673c364d1be7edaae7946b573e83278c4120de824e929c57a762688e940baa2f0a43cbdf734840daaeaa6557d49cd21799c7807b26885e71b09b581bf2915e138cbde193788e3f5a6a1c388674802a572b792ef234b57aee4717e88695ffc3fadeddf056be20d11c1965d08320ae053e66d020fb15ff46ffad32086602c8b8b59212fb14abf3017df6c9d3770438167262c5b62310ddbd5489bafd1d0ceaea1867ea90c38a59ed586bd28ac8ba9c6ad4116092ef6057545f5e1bbf988f9efc5bc3be7679d847935ec4bcadc2b6c8538201439897c2fd1eaf7f7d810e2a472eb085777340b01b2e02af0781b3efff2754a7a16b83bad2b8c060ee05ede3b0b103e6310d0149e5b7badb633c000ba5b804a7c1850b5dab04f644cd1fc9260a1ee2fd7dd5cab597ca959fc883d856df595a373ab0ed5955fd99d6bdbc2a720bdb96e49748aef48f7eaa593e2c3e73b6c8104ac94387841f7cccb104cc1e3038a65ecb32b02dc9872d85c6ef080d8cb591f71666444fa998a30af50d2f5ca0b92331b83fe629f57371d394ba838087b6b6a254914a00c9d419affd7436d36759fd1ba3390e990f787b84af45b295fcdb592e3792998dbf4fd44e6b2d4e84e4e01a000cc37f69e745286afaefd3f9b853b0595d06ea74ce76525cd7b10c197d80602738263e4d1cd6e002a083f4267f153165e75dd0476fd3071d15353f37cfef0f2c775c74bbc29e65418d9df810a34a4033a8fe06dcdf373a1d7828fde51fc6de7841edb1dedc747ff3977c1e669fd8b1bd9589d8b7849b5187e9e304a3297ea3cdffa7e9a76a5bc884bb01ef82100071432a7165f9812e4de31347ceffb59a3d813e60dd00de0fa3622f07e5df2382d830e9447b36727ac21b453f02c41ae792eb61544e7108d7fd6d1a246fad6cc39cdcf5712eb16832df5cfe4290f4f93b41b6dd6e40632c9b100fb7ea366be9e01631e03e05f172cd99fafce781fb75333585a1373d5e1fb1a113b31f3ff3e71eefcef030e71b88cf139efd2028ef9a2ee577897ff9fe74367ca032fde7e106241e97815c7c18f68d3c6d9b9bbda05cca4104aaf9ef7537e07cd733d2e26072cef13ab7328fbd1b7a891eec33b9953dce74fb90926a71ed9817e830661b202e30c3f1c79c02dc42498ba0a3a1103d535ee23a7586f1a8887a78767bf9df55433352c592c07a69c0fd3e715d94a3d2cdea98fe6b9703fe4dfa8ed5b3dd23a3ad99ad0bbef439fbffd8bfc5293dc95df5791f454607ea6592e5c977fba542242cc13ee2533fead941efe0498b7058388e64187c499e16e57f75b8fd325583735ee897090f4fc278d968399d3d7ca578f2e716143f5e96c7c4a80fa19ea7b49b102eee48f53f12c04c5fb2237e7ae21b798ce0935cdc625d9f9c7a7f56937c736eceebfa3836c7fd4afb3e49680462c750cf5f5dcd8a1e1662ecb70dd389ff40d1c6db18e024f737c51473b1f3a8bcf38f01f4b08173e72b3f3144ccacde11003bfc19a747569430f78fd2a8a07eee45776f7fb85f30e066ba78b23bb2014cbd0394b8e38b2139a299f3198342a67a40673b26d9985fe4fb7079455b6c1371cd1763fd8c4b50585c570193f97ccc305b4bacbd3817c635f9a94f114bb0e59d031a618e91e13adc89ec69059f62f24bfe2e375b887efc07125efc4122fd0f47bdef7dedbd8366096516d630fdbd6ce78578f8b8a15aafa25bde4b4fefa727160e47a852541abd620c7d61cc1a4867ef943e3f8ae58e713b4976df1051750581159de56a7a6b5be752177da162688d37572ac2396464838505686c873f74b7fca43c442fcd0caee26ddf2bdedbb1de414b0ba86beb409b50f08e52b55bc92d8bdf299d8f9d9c0c69ef7760a645ecc2110f282428d8e8277cc170bd31578e5c2d69cc1d3f7f307580f8b9d094087ab02e0ee71db7ff01453f33d289317e49429019549fe92f5601651db73fcf48785710e8c82d22e905b0fd9754a695729d3599865598f40b6a461dfe44668b23aa9d24d97a9c9a97d8b308db3b528ea253200c7b79ca0f0245e4bc42686a111348e8209ccf72c74aae01ee6bbef558f34200b2e0f66f9ecaf0e80fee52ac27d7b73af1d576a65dac2aae177b2c4cb8e0fe53f960ba90766b80b187e5e65125d15066ed7dfc5abd5a86c4e46e7296127f486b49c52ddd7eefb29f0d3e1fcb12aab87e5bdc8a7df1fee506ca62ea42f2171468116990271b5a85b0d3df1b419b9dbeed0b0eb4af588b351301dab52cc64e516e5a46790ee941674b5ee880b38b1e9289ebdf2e17f9aef32bf0be128d901dd513128b8ed3cb933426d969dff7b65c28f143549b684565d0a2c97be078a9ff64b3018a0971829706ee61824e9fb1c3066648ee290c2e3f80b7f0ae51dd726b7c1282a2ab8d33ba07aaa3b6a78bb6c4ef6bce72cea54cf5c92eecd64a229b6b485f867fe5cac0315ab6bfb12ed97d0da3819b0f94818407a3f8f71bb5b14243e8f844451f1795d1000ad9b4368f0a27923263b908bf8a4f49711b1302203c82b70240b32165c0f3fe7cef851a59678a7439be12be3522aed35d5076c8a970c11ff7418d9750d2106d62fd4cc3f4cfe1938c6b149a872f980c1af15dc0addb1857a44b3f7f15d4be55c15f97e38de882e602f6fffc8c17fdcee871b46dfce107235446f14e4464ea98393477f8dc5956248a1f0463a307a0211aa3e7f197f059430a289675da34aa7b852dc495bf88b4adc9cd72d8e83c9fa2e7d67ec7909ba403fdbf2c64a809095f31d9fb47758bef0d1870a3e0ef186f87dbeaee74d2b177fca8db7189a32e5c65dc5c3921efe062c055d2c7dfb57a1091470f06bde6c6d4944a5337b163f25f0358223438e8c04289fc5e343052e70d3d183245d466aba51f1da2ec15cf398c9edd0c7ad8c1f28054e86dcac08fd1bc07ca8ec1859e78c62f2975b61ae03bbad2913aa0d9970dfa7d76bc3ace402c8b38a63b694daebc0ceb011c4369ca74f0649e851331cc692a51acc3c23240ee0284aa2073823bc9c93aa64b2b1f501519d8c5a03854df6924c7f810d85044616a4140ac8a13972030c5fb9221df5c0a4d8cbe54a93e07e0a0c5ded4e09d79f59e47ca6c498f4aea9e5d4da93f6bd8740889244637c923228a8e704da3af9dea800e9253e451741f59405277e6912e9d624dca51837e6c0dcd9e273cd9421f55701442d933bf98613df811997274580671113121f2566623dc270fabb2075dc40c31bd944e159e51fca5114e7f9897c2317f98c7110961600a1cc6e58d7a8c535407dff933086c186cb0626fc2fdd14b2c13d804dfda95001f4019d48433d96a760ebfcb9f1be65bef4db8f8e168a63889b9b11f2945f2c5396370062aa915fa1214a04af218684c18a284e2654d12321cf4de9eeed010622356b8103de6671fd85db0ce8e784a5e61a744397a66cef454c143f747f56bcf73293482f62c9c8c274aa0d6c6c389cc9604a579fbc1303a9a39e18da4da381804e0a0d0012d71f503d668bd0e0c01590dbf0d57fe175a44db4401fe2f46e20ca649b0cafb8444106e0b084fb3ef5d906995ddc94cc3092633400d89e72800c15496c4058681d6d904c19ab42bb3c01c04e77544b44f093d408713669df8dfce69df8f664cfe081df644e1834ec523af280bc07d0c2137ed65bddc65300a0c6a6438bb051424e660de5d4af38a11f73892abf0f4f6ac39212508141302492918171f4e505c46fc686ae3359c915f75cdb0ed2eed62bbfe3d9bd193cb8cffe25f246240bdecc94826f954c6304215c8366678bce7e76554d8f32f688e30801d7a3d509c74cd88eb5f290b38b6602496c25f2928e8a0409514191be34a0847ed32ca23fce9df379d1f8403ba1c3e31b942ceb99b04c1c4db28117bd923cbd1ad3b29cd5679dedaf84a1c2c858b0faf7e1dff16f6839abd533af7cef699af6298e2a479979e2664014fedfcde11fc1fcd71c9d07dff45276681925cada111bf3b8337df76208aa98c390672f6a046ac05661e73ffe0678e2d98cf7f75561ef94654615c2498a7ff9acf9847ec042ecf07de7187517beed6b41256cc11dd6dc306636b2ece05becce765849aeb5bb50bdbe8569e8b287c061793711c1fac93e118a1cb53008237830d0562f6d38413388bf190175d82cea7693d607dca738af60c00d22be1025f4c1719130f7e04b2e11c41c55897e4fb28c912748303df7791910afa89371c6950f8756f897087adedf625e4d9b2895e5906004e33334e3e6f960381a7c9cc27cf3bcb00c0a97c5ea1e7b134a23d1270d3086689ee3850fe38b1202cb06f2c4a19214f5bdcad8fd788656af6bc2c9487614f5e00d0c4948038bb60c770a71ceed087e6ce1562457e412d4b5b7850f5376a7c8dc0d5039dcb8fa00a1f305324acd25f26c7c21d328848bbd43e18121b9e43ae33e6de87fb742e587e7f0a5318fbaa364a46db74b841dedf169f8ef9cdedfb6169fcfa1e1d112a53041d5d95b393f3ab7603e64ecd16b0325a1c2b9da6dfe546acb6a7573d5a83008d2a6854974fe05d26e356efb69fb59f38991e8192052581eebe395356866c28659ba60755dc0cc450316666fa64745896fd1f26ec619939772e01fd5aa1f55f003a6e3019dba318bb3c18dbd8171bef2e7610173b568b7dcf2e396deda09d259e615a37651af48bfad560977f8fb41bcebe255403af1cd3991280a590e3dc552b6ca3276f56c90b689c463f8f92b66c9c5873ddf16bce3f8a7dbd3e1e406a7687311453243aa92ecad45b16783d7a8e38ceba68dd0923631304cbd935cd4e7154d68405ddea6b9c595c7699cc670b06c114d91c9716128e5eb9342a45380cac3ee99e4e9d762da16d128ed82468a7c292f61db7c4bd24af3df795c193f3c2e2463cc0a8a85e057e0caf148e4e20b942ef9ca7c5974abe679d3e8504667691144e4af9b7b67593589b4ba285d57044d4dbcb3990e52d2e07719414a0f680698a8693d261056b5f292aec4378504c703c6495cdb4a218bc0a579555f0b0f4b025ed262627f6b3e43dcf8b77abd3489af909f15a4243a4518b50ac8a79610a97e63f2f8de2153e307a846b730192c48403171e95e11b25f6f1a67757f76682d52d63e1fef5fde948e053c189a53694118a7841f1b0aa44127200cac008e31a06f85c18a41eb18f0e41227519cc28832cab370dcd3af614643dafb3b9bbd568308bf4c3f8eb1141817d05ec743c5c6337e0546ba683cf65cd2c727bb0ac56b6ab193efd4dee6d1c11df819a71ce2a827b14d6d2db55b580f70c480ab46d354e3a3da6fd0a549871121e541ed2918b7365e99e5b7759045384f7e246526b602229d9b83413670b7a01f9dea27bbccce343a3a32d78dd72b20670121151d30cc513026a20538a3420b034e9ffffffffffff7f8187c2011a31fcd6d6dd0dbdd92f939452fa3a75248c84550507e44e29a59452f24557e56764bb1f0149083a081f084bb1a629decfa4b0e6079737a0d69a71b173e5fdd5ed4d18ffe20694785bb7e2536a5121fb0c33292159991b2b7fc2997269034aecd297354d63ba1895c4d1247d0b4ba60c131caaf164bbb00129a6ad69e5cd35f384bd06a4c79e4ffebfbaef966a400d2e4dc887f9f25fcb0c9734a0bd54ccb9c1fbedec4603624d9f3c67b9577fe36ac3e50cc8ef2856e99a6c0e7376481c53cd80141ed6c99a536fdac33b5cca8038f173adba86f1573919505f935ced27370d9e4d51b88c0135d91c4c0d179797a7be8801b56aea4e5eee69888a249ea3d1119730203fbaab9dae4ae268461999cd410cd2d7180969c121031191952f63259d3c4b21c305229c2d80495cc080da795ddf34974db7c6f0f205e4b7f2ce2ac4d4b46ea094e460879c2ae9447b70f1026af6d95b5b9eb2ade2b9740171aafb84aa6532622b12df2cc3850be8fab42655392f3dcc360db4fe1453c253cd398d5a1734102e6e4d1deeab96fc9a9190101b638c84a4e2389fc4650b681d3fdfc39f8df79bb480dab2a65add5ccb6ef89a5c972ca0a3df12f384b8b6a91e135cb0807a79dbc6cf716b2a715f0135a9f89ae66b5dcdc925714c64949244b2f806172b203caf9e5b2dfb3d79ac864b15d0613ccd2ab6d6a5362a2aa0e658dbd6cc5baad5db481c8dcb14909fc6aa4ed3eb7f53fe450a68b57f6356d59035d64d149066a352d92a86777d0e0ac8f154dbf6bb9d979b527079026ac927652a4f27b951cc5c9c80d469ced7366b52a3583dc74a4bb7b781bae0d204b4741da59af2dbdff5c4870b13d0df3ae5c4d2aa3ba68e66e2b204d4cc49356f9e5d738c7d436c8c311262a346888888aee1a204b4bab8cdd72ae6fe8d9138760c2e4940e73429edaee698b5b618436cd40811111111692e48408dfb7de2fe7467db2489630b0e15555c2c06f2f794587376927973163a8881563b897d33dfc4d4af9138a20f0365d37dc68ef728b652491c33bfa292e8871dc240f7ab39bb76d261c3b882817ea562c9cda39feb65c040c7d959fdcbff7d293512c726c4c61821e8062222a8858e5f20f5dc65670dd3edb4dc178873939757b973d36b75f402715b4f4fe97cbd59cd79b14af5a64796ba1dbb40a7ce6deddab6ea59ab2e50774b4fcb8a71ea4add868e5ca0b5899dd65d9d55d7242e5083abfe13b3b6bcc53a0d1db7409dadc1f68c6f596b0a6d815273c51273b5b0f3b66b81b0b12a3bf57eb440addbcae4a9fc9c5c2c59727c0c3a66812ea9ba77dd3e212378e89005daf4cc3ec6ca99543957a12316487d353fc97ada316b9a339ea18c84d8a811a298c16444072c102a3ccb96f2b1d4764fc848081921366a8488882466f00f1daf400da6938db5b39e94aeb902adf2d3ac356fdeae69dfd10a7487acd998a96b77a3232128c4468d10111156a0b352af71bbc2a6d8b355a0e68cff9b66cfb3b4ae558172d7d5618ab1630bd54905e26f77867c744fea665181b0f9a5cd6acec2c4da9e53a0b37e25d6e83aaa416e8d29d0ab7a3ec867295c3e373149235d0a74b4137b7f1b3e971c1962888d314250702022b2924c70e49ba8921b28385ac644e5a44451005ae82005527febfc3ae72ca3c28e51a0c469359cb749edea86a2400abbb16ed6f1e77309491cdd0c1da140bc495795256feb991514e81cc5e496b815b3516d39fc0452e9348bd7694ca55beb2d384ec6f0045a7a9cf14acdeaf79fd582d90984bf8bfd36a7f69bbf2727d0f9d5cd399d5aea63ad99a0631388e92fd5d66cc366252e89638e2f239351492798872ae94457525ad2d1046aaeeaa9358cf16402294f995a9daa2af37dcb24ce404484e5bfe1213a3081eedb59a741c7d6bd9ef7858e4ba06ddd74e347b5f1adc61d438725104bdecaf819376e78ab82337454021dd6dc35cd732daa4f4d09e46c9da3129befe64c151a1d9340deec5ade7bd861aa5f270e1d9240b78e2dd587b177a3be88084bb3a12312683731d6d3eccb5a378704527816b264d5a4c693ae1d3a1e81585efbd59af389197b6671377438022d556eda1395b5316b12c76f908c8e4620c45e4567d46615b6c55e708306051d8c40bbac98396bcdd62566124796729231a3847973e2609b1347628d8e45a0dcb47bdea8dc463b5711a8c1b6dfea606366cf980c1e645a3a12815671c3f6f33ea5d39222715439596c650664f02043d28108844dcfca73fcd89c7b9833e83804d2c63fecce795629739138366746c1a0c3106829d5fcaeec955825df42a0d5ac596e9e6df2d3ac1302b5e66e69532f5f99541aa1631088dd67aa5e27b6b5ce952090b7e60fefb46c69935a6974040235aa7ddf2e5e54ac49e1e8000462bedba8958d3929f3fc036afca4d4653c8bcf121b42ca8888c8123afc80127b1bbc8611d32f95227d40eeed17d5d2c596bf41cbb31c82a1830f685957faa94b9a4aa5dd03e26fbad97d544d0fe85c378f6ad869a5cfb6230f88b9b7ebeea4afbcf71d7840adddaac5761e79f1b43ba0f677b0f141d63b8da91dd0739f95789b3fbb9e7bd05107e44d4fb7848a69e7fa76d001e1b2e49a5a69aab3fb8e39206cd25acb9aa6d497bff9a4430ec8b761a71c5b4a7ccde6081d71404aa56ed7b2a1a7fb7d071c903aedd2dba7d69a6a7338878e3720e5ab7c7959af4c3d7983a443871bd0714eed79cb36e15a76da802eff0f6e4abfd45bc60674cd3a977b9fac719faf43c71ad0395c6cf7647b32a64e0a1d6a409f0dd3eed35c93ae89790689d09106c46aef301ec33d56abd08056379e724f63b6a9cd39031e8b2096be1bc654e3ded5fccf663acc809ad6ced1c4def3b42596012d76fbf45bcda9d9d44106c492a6ffa22a86aa59a7630ca8517fd649cda5ffb667b9d02106c4a7f8aca6666de1528dc4b14116182c8ed11106e4c72eefa0363295bac08098a75e6c8a5db935b177d0f105b4586f6af0d9af6996a716d820444424f152101d5e400c153b54c97805c94dd3ce59fb1f62a3061a3c0e81fc9b7be746d7e9e5b83c0c8118b7efa47a1ed7b9c44220d685cb8eb13ef5e62dc4468d101111918cf3c1831028bd629d77dffa7cd30f02ed593d979a4af610047acfa6ef4bedd983de028154a38cacf8dd7379710b42469a26780002b5bd6e4e767afca6e1442123212c18e92478fc0125d6d3b0393dce3d4afd8076d37aaa6cd67a7bf666f0e803ead64e4a66d8f2ec9fe703624b171f5cddd6db6779ec01b5c36c547a76d5b0bff5d0037aff6c5ebd8ebf1b6d3cf2801273bdffa84f78ba5a0b83071ed09f6eae7567b2ed739a3b20755ac2ee55e6efcd8bc411d151e06107d4749f7b9556a63277ad036a98537aafa64607a48daeded86afcde54cf011dfea9bf676b51f5fa16848c84bc20a3050f39206c925a4ca9d2a6c9a6d3230e28b5d36073e7ffa7761f0e48b1d59ad4c67d3cb5baf30674cb56217293ccfb9f1e6e40cb3b29764e2f957feb2d1e6d40978e37a583e7d775b3071b50626d9a54e8a79b35c86b40b8ee8f2aff859ad0d3a5c1430d289d79f1acf754abd7f14803525ecd7d3372f34dcb46e22822c258121139b9d2a222004978a001a9e4b3bc8f5b799c01a5c4c47ebcb5462575ec6106d48d4d5affcaed50755306d46eb1ec6c879b364a99071910bb84addaae1e6ff67d0c88b1b6cd9466530cd92e3120de5ccd794c4de5b34a8f3020b6a754b253b51ad6ac0603c2ddd577ec9b74d6c45f40bddfbe39f4f39cdddcc30b772e82b829f456dffa4d6aa97974e19c1669968d4abc96a71e5c40a9ffdfbd7ead4ecc79e29106f254ccf45d57d3a846bf071e6820dd3fa89efc870f8fda0252ac2976f6a8e398d8a48716d0b2a7b757dfcb02f2663dacf428d5984aac081e58408a9d8635778af17b2d3cbc023a8ba5e6539f54d55ad3580135f9ad69eacdd1a3cdaf2aa0a59c3d8fb64ecd153ca88074e5f61f6bfd1e53404badd5dce71c9e82871490e7b3be9fa6db9ec654145083d9f0e6b9b51af6bb190f28a0b3da628b99326689f1783c01296c2db15d4bff9ba4d876f07002f2dcc3f6bc5c1deaa6471310776b567aaedab6c255343c9880d2df6aec55c36d2f7943e2c89236f05802c23fc717ae6eadadd2430928396e7a3b5cd796f2e4910474d7acec4f53b9d2858b89e2810494d8dad66b9f6932d60ef10b9762a05f98dc18aa4aad6955248e2725c96465525873e3420c846b7fad4d9e4c35367d190652d912b76fe506fb7013066ad81a75a96572ba66cfb43c4b9363d5102963a598888860e658c140bb7e1a657f14ba9e661b186835f55c7a65cd796b8787cb2fd0633736c5e4bcdc94ec19175f2076cde9e3a739beaf2c7b813c35cadc8f15db9f3e2889c80bc4505993a5c6bb697bda054acbbc2d7dd6a769b3d20552c6ce9efad9639f1a6692cc4839791ba0cc2064248d4b2e106fea67aad89a3bcde65b4a10c930512ae904657181b833a95fd7accb2d10fb6e7013b2868db7c54daa2419b0a051259d640e6d81987eba6d3ccca758b3b540e89d8af9a6a36bd76d1f2eb44049b59512b6d64e67423f94c265160895d226dd358dca02ad6c7f4efb57ca761bb30e9758a093a7bc5c397df25faa9891c4051688ff0e759db3e9348c5f813ccf6efbd42d95c26691c1830c112eae40ab52a96d8ef29ea6d323214bb8b422cf45d0eae34b5c872a5593142bd0d153e4e6382fec4e6d15c899d3c2a4987ad6678fe1a20ab447371d276f7e18e34f053a95b0f16ea7491519430562efdd2c550d3ba61e4f811a76276583ecbb396ab18b2950ebd5d655e768a3ce5aa540c8126b4c212bf747771247a6480a842b35ef694eb39ad5d61905f2fde6d5544f1d7e541217056a54d39ab3e7afa79b1c0ac469e5fa4f6df2afad8302a9d49afdf57c1a96b7dae220a505e50534b87c022127c6cbdde5df606a124713e52d2f3801a471f1044a8d6aabb984dcd46a2bdf1a19b43738b87402a9c611d962cb2ff9d9c409949b586ba958fdf9d3256e02b5c48b7b97341da3424d20a65a553abd58a9ee726602b1be4697a24a774e7412c71a21232136583f5c30811aeedde684a7b585672f97407fdd24d632d71fafbf2510de3e6b3f5497cd89524292d95c195c2a81dc154365ea0f6be9df50023156f6b5cc5ef56e623c46b84c02f1abe5f547e935f7dc8e24d026e3d63aa975d4b36d469a4cc3251268215b858d1b67af6a7b81046a56eb8dde26a60e6bea9a95cb235093fddfdbfc41745ea9655c1c8152fd36ebc952bb66f5951615bd34023d325f4b6c255c7fd92222da80e2c208a47c33b175ea97cdf12685e16039425c1681d82fbe6aec5ebdebf54d70b09413111145a0e44fd6c589ad61ea9308d4ee7d8f529debbc424404c2b318f32635a737ab8740aad36abad15dc6d47d52c4435c0c81f2348ba9cdd2a562691b465c0a81d499b66efe7f5075df22e24208c4de54d92526e4445c068116aea6adc4e4faab36491c5172b0101b3542ce4859818808fb3352146b1504c245c5dcb89bffdd5d212e81407a52fbb48d36b59a370908b4784fff37c94dc22b2d2a362e7f40ebc77fe136a74ad98771b8f801a94ca7cfb1fec39ae62e87ca64a2e040448485e1d207e40ddfc9ded399dcad91b8894a2c68b9f001358d3246a59ab52576baec01e1b367dbdfa475bcb996bfe1d8f2635cf48014d3e5ab53be62674d12c74b595cf280cea7b65aa77c16a3f3afe06049315999262f78404a5bd2d5548aa5a69a25710c618e23e4a4848445e44d546a312344398e905b1e5cee809836df742f27f7a74d27191393b49a161c324069015fec805893fa89dda5d4faac2571ccb43ccbaf2496a4151b22224fb8d4019da21e6e9227a6584a4e3aa03d4a31b69a7a6f7b787c0f973920ddc6d8589d6a4a7d374a490ce87091036a8c5b7bdbd4bdadbf397901c701e9b6e6df55abd6973e5f7081035a76c5cd3654a074a6876bb9f3727d7f9c02a55aad695cdd7919aff58729d0fe396abfad5b3eaa4e29503b4ca779df83ec3a121242031b848c8c8cd0a046885ee2831428b1d62c9eab842ae01c056adc3c37a759df16f26151a0968a0b314f3b9c18b3e5231468353edd6ebdfdf1ed0205da5b4abbd9e4ba96375caf72031b37f8f804da935461df5a6f6dda3c8112435ec73fd96c9fb91368b952a7ff3cf3f44735248ed9820f4e20fe86352d9bc698e66fc205c2c72650a31433a36a967aa99a0f4d206795dddfa756ae6aceb49cbae02313281927b6f4a7149b3efbc0043aee7adbac52dbfef73326e959322c253ac6c7259076bbd34b931336e3b4043ab987dda83bfdb8a7491c5366888d31de4495b4b06025d02bdcc438534bc7552bc58cc3fda0043aa898aaa4ec89ad53f03109d4f2bffbecab2ecf5512479612cf187c48029db3d055da4fd71cba7f8e8f48a0b4fc89574ab8c7540b0e9573893e208130e53595ce1da64dcf6941492be5a0c91c2b2d28cf2ae944331f8f404dcf69b46967b1fe256f1a1c9761f87004e27ea6cdae29959a548d40ad69add37f725de9983a46a057bfb6e73355e2938ac431b5a4264ff0b1087452e669aa4dfb6fa6eb4311c859e384edf83d25950d143e12818e7f935873a767bbd18508a48bfefe8c7fdaa7d743a05b764e33b7e4feccd41008b7f7fcca662de4b3d24721d09fef7654feea49a7f6081f8440be5eb79d6bb2c5633b08b447af9bfaf2b106bf85d8a8112208e4e749539354a665c7320b1f8140abec8b4b0f4b0d6e5a1b3542b0f00108a472afb16d2b5b52d75d868f3fa0a6d7e46ad71cb28625f30362cdfac2bfd7565edc0794ea70b7669d5c6fea970f683369c3b56c97b12fed01653ae4f4bf67e1690af58018eb5fd50e9e6af3dff28058d5425e4f95bedbb60f3ca076ceeaf9a6f1d6e6f1edf07107d4bc2e1beb6ad5e439e9091f7640c830575df2aa3e4c0c0621232e081909192364a40ec8d7b5b5d892353aa0d4d9f0fac5da335e5d7340bdebd9617caa39991a8a889ce1430e889d73ea56b38d79b3bd7140d9a7a8add1f45b3eff018766c7da1bec6fce1bd01e6b4efc7a9a56ab696e40cfab67b53f2a594abc3620cce52cb539d52cf3cb343ed88094372ba6b0d5aa9f537ff858036a668d2dccb4eaa9f2a80169c338715d9316a6da0db15123440d1f69407f8b9ebc755bacba8d06c47b7a58393f39f3d448489e01a5e6d5d6be543bc4836640ed9ef452e2f7d5ec5ec64a39347c9401ad33ce8635aa594d6ace21033aaaf0f6d559356e3906d4ea2c534729b66671951850ae3a4364d75cc39aa530a0866b9bd5e43af80106c4cd6a4eadd466dbb2aa2fa0437edc7d4eabb96af7e1057496faf3eea7d1b3ed6417d09ed2669e540f6b76b8717c70e1dc59ebe0c295f8230da4db2867556d6d091f68a06d866775735ce8bf2a64e4111f5b406bb573fe64f3a67b56ecc38716104bd7778df6697e6d551650c3bc5eb3a94bad4f3716d032b66b7e936aca75bd025a75ce61c8e993d15993b102629da9bb8eb73b5cbeca582926227ef8a802c2a6d562fa98870aa88f29b5d85aab59efa95340bc7b9a5c6daf51fa0b091f52406bfdca6d7a87a5a686e1f01105c48af175b2bf563cbd50404b5313725b7bc9cdc92720c6a6cdfbeddd5acce604a4e87edebc1a4c4dc93e9a80de3579d3f6a865662b310165c36a536adaea51e9fc6309889b5478ccbf19e3e5ec5b527290413e7c28017da6eab6acaca9837c6bf848023a8b4da775be49badbcd071250c3d6ef1ca66b51bb954731d051ecdcead5242306526cee844d2967e39a86815652987977d09b7bb3143212321262a3060e4444360f1ec240c7598f257f7f305036dacd69b2f9964e5b080c744d3b6bf172d3773a61f32f902b5cb5b057c2d6eaf44846b1872fd06175ca96fd390d103388078f5ea0a5dcac51cf5a3becf419cc4178f002ad4ba7510dd327b50ef6af5f19c45da05fa93335ebf75817889b6c4d73af4ebb87690c3584472e5062a97fffac269fb3dbd28ef0c00562cda3c8af8e52c2e316a8698d6e76d39cd7b125222222929841cc434e78d8027db389e8d95a83ef8b6c058f5a20a54b5b31bb5b4b3579b440abee52a5a73f7237db290c07ce02a9e23e65a790cf79732d0ba41a63b52efd3abe2a5b2c50bbf66d6d98cda5261b2cd0fa7e6bcddf7e05ca6e14ef696e6bf9bbbb0265caa635dfc718bff7b702a54457548d9edbd3f84a6705d2a596b35fbec6aaccba0a941a6d3e2935aa61ece09e3278a802f952e7556f1beb73ba01e1910ad4f6fcdd35f63eae4aa840a9ad9d6d789f0eb7b95320c5dbcd4a2993ab434f53a0cc5fe82b5f5dedd1d4a0e1510a9494f2b5f6b6b956a93529d037b7992ca9edf4ed8c0e1ea3400b110f99572a3dbca71105da769aa3e7d46aae41440583472890aa5c3d4ca5269d6c4b4181fc34ebbcabb5349bf37b3e81d2bb9ee634edd7529d6e1a1e9e40ddfdacd475f9e771c1a313a8f13d2b5ce9305c9f1a27d051def389cf37ee82c7261026f7b5cbd49adb86355ef0d00462ad25bea4a75562c7c682472610dbe5d7edfd92b23f07e5cdc0045ae9e835cd524ce7937909842c2db54dc3ec1ed9d712a839daa46d145396e955660ae1510974d4ef5aafef96725e9440ea782fa7524755520a4742469a1c1e93400cafd983ff8c59535c9240cb98e9e9a4790e67369140c9ce71b3c64cfbd40f24103a7f5a7fae8fbbea7a0462ef999e4f35e584ad1d8176b9bd0f4355aca5bb4620c57dfc59367b3f6e8e65eee0c108c487e9d535d89f4e5becbf052222ff4db30d1e8b40a87a477d71c35dac4a11c853c35e371bb698eb622222cd9b817af04804cac657b3ab182b5f3bbc818888880862061b0f223c1081d65197542d677c09506e94b0808c80a5049f80110880e5c64a6a4900090080385a5070281c5b82133991c304dc404926cb43048c25e02b81e6a50642a0811c262d24374a504a7022e822e8010f01e450253000005a5870d8e01280bf9170dc40492620026019401900000000349080652951490608c01b00c0c2a2442e02482d8989780420b52496b222820140470406b0f22d2825292a9932566a61c9641200800030008301918596644040628174a5e67cea1e2aff756081564a57c65aa7e6f4a7bd02add5d3bf4c39376c5822717c33524e4efec44ffea4415c81149b67cdab49ad51292589639ffc0983b4424b5a4c4858122bb4a4c58c12b60a951355204c4e7578d8a464ce8ac49b441c8927bfc29e082526e9600b4a89b2a094b49894e05099953729218307991a80a4424b5a5648584c32990180a0424b5a58ca098e4c660020a7c8a1b24cd1f22c277ff201528a040121c528b65b504a7088022595309437c99ca448002414a058699f58699e5811024b274c709c7042e160d90463a900209a40490c48265032ec5750525016008289e6bc44735a22022095200211729c819468f932160e95c149bc49494b8645122b8b25b3f237505e45a544e50320914048982c1c9f59698f5869090071044a86a59c645a9602401a912a2d8372a3c424210084110700598402401481829231c171c282009044a064ce48595151491995180082886529279ac93400e4102cc9012086f89674e3576edc489921a4150a8014a2a504a584102de58950c292190463491099c9a1326694b00c1132292d996729492b0d0009c4004000a172c62300e40f281913c532287e30512cf328252620207d40c9a8a4a4986456dec4a4e4e400207c7894940c4b492651a5eda1555a460fcfb2f266a0941800240fadd23297e30c3c1c11ee729cc100903b248280d821b34a4e525a524c568ed500903ab44acb98e038c180d02151a565e620878d43c2a1c504c7c91b584c6ea41bb20dc9865c43aa214140d29068c8333000c40c095286058090e18c6df400206348316418f04606e500206020428605074ac949e60bec051e820a4817760819929694149559799296746302205ce0349a33c3524e0e0082c60e6101205b6831c1716200102d98b4058064c10c931b9916131c27586000c8154c92151400520514cde45019131c270800a10263892100640a2b2919c6d20340a4a070b01400240a8ca503804041a561409ec0830c0e2000e2040680344101204c40c9d1a29239941b2c08005942014094d0d24a48584c10009204c652014090d0004c315226a565011862a8b4159592f52b07c00c032595a8949560800825c506192f98010d2280110606138c6d34c3524e32371e651900038c1b8fb20c80f985098e1302607c819269414939c92cf62b05c0f48217985d8000a30bd47ffd9fb0b1e522a3010c2e3217c0dcc216990d606af1000c2d328099850730b260f9104c2c583e8081050730af588c2b448069050b0730ac406715b74a6bf16914aeaf8205031855a4a20318546c00738a108c29288029850430a41885284280090528583a80f90406309ee8c406309c38cc26582a80d144063099980006131ac05cc2129598c408309288044ae4b4dabc5b57263b24109fd6dc6b07ff7ef93e025d7af273fcf8bbae24058c233480694405308c409d94572d4ddd0dee1f44601691b100461189b00006110bc01c02e56a7b6f2d4f754a262629e359725252a3a5e4a4c42443d2a2f2ac0df1004c21d0bbfa6cb85d351842a0c3a6f25c53cb799d26078118aa6b8e33b3b592d30a027d6b1a3eed78fbd6127a2010bbfeb74aaada2f1b2050af57ac53b3856b595b7ac0fc01b13d0bd3b53e87f1036abac9d33eed42644d83e903627eb9de7221f69e333ea0ccd64b8d751de655f82a396ce8c0c66102660f088fdb37a9b38b559bd2034254cf1a5e8cabf9c586c9033aec2ff5b1a4d66e72c7e00135ddf0f65e9771a77dcc1d507e27b60ea66baa6a651d307640dd2e2d2b554775ba567540a7ac192f7fa5c3ee12860e88ff12e2ea1e9f0352ecf7a91117e7a9959e8091033aebcd5fc3e6fe946d138189033acddba65f54c7a64d0d020307c40bcfe39d7eff75ff06f4c8d6f2a625d6eb978f1b503bf3c53de91a4e890fd306e4e9d56fbac4f8ac310c1b506ab61d54781ae4c77689590303306a3000260d489bd763abe1a4db778f0684abd3afafbc740694cedada9beae1b97c33a0c6a8d4e9f4bcb6475919503a7baba57318a6557bc8b0941dd58d9b77c78094b7b6c666754fe3628c18105307955ac6b45893ab5ac08401f53aa8f7cd62aa5f55d7071830a066196bf01cd5f2b0612671cca43054982f206fa735788deac53cd363bc8054e3dcd4b3be9378888d313071a5454507a00a4c1750abf37b757fda69ee8bc431c3504a1a339492168888b0649009182ea0d3f9aeb6b9f5596b1a12c7c32060d2409c49f5b1559733a65a1a18345036dcc6fb976373d826660b68b5b4d2416faa71c34f5560b4809091d1f7542d1a982ca0d4fcd5f5f0d561cb4d58490625c5d90bca484921e94560b0800eb256d94b1bc52a1d7502e60a889157133ecbfb74d560ac80962d7dd47764a7794d554029a9c4e99272679e8ba1026a0dcb56cf4cccb0b321716c6e60a680d2dab427a1eac24801ade2e598dca8e6fe064a2352011305b49e8aeffc5ca596070305b42c9ba5dd3cf1657b7d023a9ece7e9ad61e7d535248de849564c601e30484f92c7d36db9d38f1b7a4a06c9e81690252dbcd16538deeebe74c40fb09d5955a9db0598a314b40ac4b9ddced3da5bc791247458c12504b695bb34fbe5611350988a5ed747da9adf3b5120609a81bb346b5f47c14aa111ad408492d06f295b4b39b6d92ad9548e23884b492f96f8c53f82006baa3bb8d6a8789c936f818067a574a11155d59939acca430c614063aaa6195cdaada372ef6110cc41a6fcdf3795d2b35c5c0400db7737d4dcf3edba609b151a33f7e81d6afc5d7b46c8aede2c6e80bf47d877f1b769cc491b1172829f7c4b954ae7f6e1e9317486dca74b72af52f51913836ca0c46485a4a74c06262a2829091909190919110330e79172835e2494b1bb5be4ffb0f5d20d65493feb0bfd5ea3991387a2e10538a9b96ea8ae102e1af94eb8c53affbd35ba0a6d13ebeee2863d77cf3830f5ba054ad690cd349aeabf93f6a8114b7abd3e4df499a7ab50f5aa0c59a934bdd62a749d5666781be39f6a59a4ffd872c10639e2e76d45d5b9a32d3b292c292e16c594961d98f58a076ac8d8879b8b5dee6031608b9a9a6efb03cbf4ee915e879cf36df36f19f6ff7e10a74dd974e5b4b6cab21be606506246b253d4b0760131fad40ff975625e58b15a8999b6f56e3f53f95d6041fab4027b55d4755e5f336abcf062123215783909190a341c848c8cd206424e4c808a1418d904655a0fbd4ce49985a33888f54206c57a79d4765bc8b5da8b432052359248a6218866118020043569b00c3110000201c18904704f2b058b653bb00148004393e385c423e1c3c1c160f878481481c0e8542c15018834110c540180581245162e63999b04c0079736d5a965f5b4e0e16e36f7e48f7ed7dd8b5b75dd1319150a6b37004ba08bdfddd79097d4771e571ad2123504d12469da59d43d90abd194a72c7b6a76ca453a01b3451fb61bc346de4a4af174b91c17065d282e0c498b729f5bb0a39d6457f3f3deff1a6e01d7f7cb18442b96abd93718b67c84b3592a6aa883379f154d35e72711e36b856d7c7912902037cb50da5da715f79c6cba507a4a10a6fd08cfe610ff1cc9dc599cb78256b30b22d58839489270ccbd7c1d2dbf03c972d5f43ffb5b82f91a8e30ad959ff730f2f69c318677bb649e2fcb7174529ca2984ae18cec3d32d898056f077efa48094916f98bbfb11b83c3fd57dbbb3c6b1068f3f72f11180f4ef3eab154d71a460ba46ef5091534b0902a134d20e148455f27b828f5e4c9f0ded72a8c8a1b4481220b3a247e19753dd9d4f4af0eeca9db1e5971cf2376a5b320a0984ca201ffeb62b37ce166e577a69cc6e54b62cfd2153d5b8dc76a04d011b4f67cc820edbd0df068cd8caffd4c88b59ff0021edb07ccffa21a8d891bb836b812f4b378c24255c038650b9abb01e879294e49bfff3b0d21d5a98997475b1d431d6d642d2d5d6cbb417c9277d7496d1e2f2edaf8b9501519a9b8521186ba2127915932450af0df2285cc53ae918952c4fd931277c3fc5a58c869fd0d46afbba284016fff13dc7337e7ddcf925fd1361d487f4f842978750192d1caf31732203e7b07071371b71ec44e1fc93758c174dffa4631ab48fb328d231df5ad179b95e2601759e1dab3f5c67c25b1a86a9e66a0d9211f3089b40ee3c9d22a1510ca8e5e19f391508f91a969ed1cd37c1a0eac756cf0f4923d5199475f3d93cccaeb61143cc8549a953cf2164da3aed792af074aaef9968449946f9d95473c6130536c29f67343851fbe70de930358f2fc7f46a052ded58f275f2dc5d1bb8c14357fd7f4a56dd29d398585911c801ad3587c2ba15a61b11734cf39ca2a5766c8f398b26920e968a9426f0b9b88a32ee80f40cf4497c92de418c9d38a55d267ee7c632c734d6665afe4ce46a29c2acd2cc02b7a21cd34f45ce1cd3b7949437b3ac67edfae585d3dc0a8bef879d9ded2b8d7a7f0ba5338d34976ea5834f9ddeddf6f7826956ae442a6334ca80304db4b917c03ce8db4d9864e0ff60d836242724b52b3f90e4c3ef3e6bd8944d903fc40d3e5fb50c6efd59976f8de9399bb4acd0d1356b19669505d5b19213a205da225faa11848b6063d4aed7b505e8f4b937b028aa150c96a91637eaf7430df95ef9d96e512d999dc023d1cf3a12711e1981cd46658b73504263738e15b15b5cdc051853ee2dfc4dd5c79d66a08a34d8a40c77b047466c8a6441db41214adb06339ab6beb7c5a44b15c5b9ef2255b637aa92ec52cc9231b1204188da718e2c0388dbc4aeba0681a66303208373b13b5ec81f36341a5a91fca9e71f7b1124a6ddfdc6e87877c2ffc1f0d847545d0229089ebd66545bc5ddd0a305e7872c5bd4a2f3455eac44ec21185c6b7fda3facff533772797001f3c57a8421be32417dc7227be734a86e9c19fc25c03a7b1ea3065a711bd4838bbdd61237f6a93d62d32fd896d72a60c1100ffac8f0888ec3361da7fdf5fbf16b5c9021aed0be772c7b8969eceaba306bd539b7471173834f43590f371d08de6e462fd86faa8b8d710a7efc307ec36985cea7d14a2fee3bdf44b18e9e4ac077ce910b54bcab1b210feab32050a7feedd4844b8c2b3962b47d74d3cbf332ec90e0faa013720beae3e6e7ccee2b671a047971f404f2917fa07edddbf984ea3e9a04914db3aee280244986f26d4f97f6c4bb26ede7c6e3c5e64ce058a32005ca716f9773816f0e0c0d2fa8d409a46596e3763455157ab5c5afbae9f214fe1a1ffec2a261f85b1e3948b24141d73b5e8c9a109a834145c002e13a6a9c2b82c1930c2c854100aa35b40b290965b3a2501fb3161434f90e83199a4dde580884dd58ef2d58ddb7e970d1ed57b2a70ca49a39293bc10192ea071278609b4d608e7617b0d9eeda112d1d689fcb8a4d3ddd2bf77e3f83a8e920505c6820c9496ba0a7eaf6116eb92fe940471e0cac701e7fc333159a57f93d4a4aad2d5586d61029d10492e53cd36557659c600f110fefead94ae3fdeb764fbac9e9d919fbac6931482bed7c82851f9da153b1bc6bffa90de0014e5c78ef2d67bcd7f7c4e125f3e34e9e9c7e1eabde8d6271723467260d4f92c66192f0e1eb23608654e4c99d2281c42a3510f6e9fc2fddcf8acb52002506a12ae56857f49adab3925c610f43962536d11a0d45c87f1cbd59de268c0d280d28c014330280507a81a8a82d15d4a748429d1edc3421174e1d3235d1e2281fecb088074b6340786875959c6187e32638e872226e6656c712fa83371089783fc17b8c5095523d55493773c06aa28d7819a357cc8f0081045360d58cfd37efd6c785fbf6d3e7c50925f9c86490585d7189f204957e77f54433681fbab80109d097078cd8390226731cf5d9c4915c1589340a3b32e72242272cbec3287de02f5b455d500267d9d88a9b44f29e2437e7d47c5aba3479cf4e195078eef9c63376cd0f227cbbb3874acc7c1f8e365741cc8e96e4bbfd735b7306da035600b9ae19cc15bbcc6e244ec1be31b734b2cda677ad6c0b6689981eb146fba6cd1342be9569d43401fca4288d7836ee7f3cc5d97e15d9782e623eab25d63c0de7a2a247de10b4e8a7ab771da28850cd4573ca0ea999448931b416c3462aa880cc980392c4628b420c5cea0afd7c91e8712cc22726b1432ee74caaf7953bd9bde05863d272516af6b85835f15cdd44cc01e662babac6d17ce9ed188579141d15e5c984c73c967e653ee7516761ad93b797ddacb10b9803d2f8ebeb23f2e40abd36c0659d950d0f8fb674955130dc2f742b0506de81a7f18b05295be9f43d27d175765071b1382acf9eb82375e06903d867d81af1f7ce173b4b29dae6a52f453eada8f519cc79dfc8dd11982b99bebc674642b0e8b9ad39ef29640891d25ef8c80b67c97bfc27db2d3557846edfb3e8e5924846056f8daa77a6fc9f33a1c04e320680dc74bc99ff1f09f8dc7e7906be67430cee0218829db53b6e19c0b8486ac4ef707e734e71f1dc05a71944d6af4964658ad116266c63e3a936be9a76b6b1ba4ab38b33e39cf385a238c6a6cb34917bbe2d58ed9247a0e1850a05fd5ea7a3d9fa3b79b3c5dd10a10af8d1df50000f215c6030adefaced68a07d24c6bec7b7a9d45424bb6b0370778f63ff6ac27908c864bb58f56348785e330e60d49c5104d853420aebb3c81db7a243b35f62a8de5148f91ca2309bfcc8ac7894dc4e2617c161c95824623980a2afeb03e2b5a937740de431477301daab2790f31974f1bfcdf78297050e68ca6e9d0ad2411f680ee660958088516a93055b0ecae69df521c9700b013f0e8c8dcd84e899b0f936b28c8a414f7a548c1a9ee12afee6563ca51731acd5a9083acd06b7c7299be5db7ba3d643420b81ecca2e1ad8d220b81d59a98f8e6dee9a0377823b169464aa2ef8a02e9cbbf509640ebb4d320f54dc80ed7f261667ced7a09d3da343bce6088827b924be0dc29cfd59a3e19532cdc154b327c471d641fee194481ca31298a290e5b59b3237c6aea343e8e1caa87bdeb070ce1e3ec7cfc2228981e2e8e7b65a7fb506a7238d188b40a599b3d62725a5ff36183793b4e3246687662bfb097397a528e20e8789abaf50a6fb43b368e656159a2d429d79109e330273da55c099473a1d0cf6f3c2d4c0f6df0b26920f6cd0c8c9af1b6400c84e4bf3ba98d720566148e8d4e95008722a826d57f43b8a78e871e67e7239dd1fc8311f1bc648f09e18bcfd0318d80ff10e9c440a85068b79879df3ea72700a5d5e27f6ff84a05c5808d8ad693ee26debfd9ca0475a9654a84371d6363fa4f4206573fa3449f334aa0aee95cc8ee373a231ad52f84b68d0959a5ad50d2099e21545324bde8c99332fe1d851d19b14a1174a1a0160a71557a898b51e32b44ef681e5b03d76eb2eb050ad375907c4f6951b5416d78b87c999487092780756ef25041a07c8cd06401ffb71ae9fe0e0b464e893c12766c2a1d97d42b282412dff7a46f492aac96e4151ffa0f330b85ea6e2e905e511c989ebf5a6f4fc309e709ea7aaf26cd9e20cdbd446902f8f47841ee44604e455c76d351a29d55dc009151ce041a901443cd9c0a8bd2cfd4563b45a7f09210a8c747bd2e82a50cc5814865e0799c85956f14b13fa750711be2d30665e25faa04ed6c84da3cdd7153cef36b6b8bad722cfd255345414d4df1c598c3d8ac56477eed1e40e6d6c58abd6cdb1b7df9c11aaad24d24b8d628dcf882740663777ee94e51ab1ab0424087420f28e46b3743cd45190a8587afe72111a6f33df0f7f470f643b709160bcc6a9fcc95fd9bb7b37f5dbf5a7a03a2a87b1f7424783907e14d03625da1132b49d431176e7a76650aa8d62bf837cb00fe30d652f3fcf3a6e063969f946e9bf4f3870a2cc87c7bc8127ffd445bff80252d18ba08e1acac0af93ba619d9d15c78a9eed7aa0504fed3c8006633f23549882c8da65613ff16fc4d256caee41fd997ec444333591ed38b1a13b054e64ff673afc0a63968a7c2159ac1b07bf52f8352cd8ddc482eabde0d68a7cd1562a296ef4a75db27f3ff48e159f9d0ac9ef18410af70d0c9b3ec2693dc0b8070917afe723c996d337b16f40cce2003f8dfc0c44f725789d154150641fa8bd9e628a729992b597936be8a91ce8d8de7147e735e99c6d839cc5d92eb43c4739480d20db96f6de46f5028975c02befdd8545669fdce9197253054f319a791204b4976aa3c442085e6d400410224118c6ef9671c28d661e7bed239f8d747c640549a0bee5feb7c0b97efa266f636abb477b54a85d1ef51d18be5c5fb3481ca0dd8c84f60282cbb8c0f54fee46e4bb743340e9f13b3aac8799c7362202261778558fe93af7080c5a9ce2c636777aa228a3804c34a6708b4ea785589b39f1b35357ab18d948cd7eedb105514579d76f3e045c8de1460bdafeae31cce539dd5f74d830dc0dfbe50394c8134450672930624dd5b1b9959b65f479ffca661d00c225b8e7082dce5a6cbb452e6eb657f1f6223260714a7fbb4c2e02198142ac6cbebd6dfded33828d84bcb570384b4aeb065b1c9f084c8ba32113a9ec8938ea449b4b81dabbd6806d99e65b3ccf7ce42582869fad4e8b245713a20ca74b00c0c4395e4107f80865654914414a7c477ec7d2082e527e0ffb795cd9c4b3801456134542f1e522f591725e0a2a84b67b9636fcf1c46217a042ed2fd6bc38e9b79d09a4ffe95c8d264f3a2c7172d72423bf26958ac2fc4c9e5d2d2901bba072129f3031801de4204530c62630b6815a6966697a8e7b37b2033da81ceb647716456e71df5cf5d9513b744718cbf070442c8c6da0889bf37915450640448ccf6cefa37f8e67cdafba10e243071e0b26f1486f3d4004891a0a0ae9bea7816c28031869fd111b7d0ec2223817b0171bae0df3a2b5584897c35bba16a22a7361f798d3bcce1451cb17e65c2a4d170879e487ef0a853c064387cf3cc81e7c3a3abac214e7c73e7f6934b99f6e04e92adeef364cb9d64c96c282ebde557e422c83b1cad040326405068979307a74813563d6cef6d529660c8d914c51815a8fd7389311ea8e31d61062500a9d5c3986b1a83c98c771bdae58b8ce7f0d8c17cfb23cda8e9f864872640daa9293a5e82dbe189331cff5b8f55e3e4f81d103653a9b6f8cb706ed46d3e45e666967deb818e7498952982022bbafbf53c86a9b30e3223ae99fd54ed9946627c7b08750dfbe60733a775a3d80ab726536851429880d3132fa2e245c613333233f18e78ea10205e53f579a0b158a6a922c0211d8cd2fb8ae0797b01d2d97a3ae1c03a5bd64556ff09d252616ccee60a0bea5ed7ef0d0c35e83b14925c396c1e168529feb32bb2909af490aae015a3de730d5272c723df5f7b6dbfe7a35610719942647f464f2e531fd3659356e538c1cd80f91b920b2ffcaa8ec405f661b0783b191bd36e620c5fd6604f9381e600563315516a31da2f401387b80e2a667a63fda4ecf91f224a7faadf93b90da3becb529dc0bd381e0dc93fccdc28597b98ef9dd6c11162f1f622f30d2c099aade41875da34dd6c58e0cd9a97df9dbe21070c16e341e65883d6484a96311091919b7f1312df568dc4081671e416b55c876456494fbec2a61bd972bf9987f416276af19cea00c457a31720c3f9347733dab235d3d26a25d16b5bb4870cc0234c059b8f0665761dd11212b528475f18051c05e22364ccc4d6b911ecdfdc124c0eba654b9fe1f965fbb34ae2bc81a87acb4932fcfd155e778f16206b0bbd38c160ba14d48cba8e09b33302dbd1def362c043886d881d8ee9b3e32f32a7d1a95736114104d3718eb778d51a9db1cbf6efb35d34e4cad2a5078c0a5daa5a94e010bc1fc9734158e2bde832a7b35988f9ca70acd8466ec80bea02acc4b21c78c277768a4234e332c5fee93723cc4b15020aacd26691a24c4268a8b5ac64c487a332b4f92c1d2cdffe653332a8bf1e32700adeb7cd2fa984159db0dd5e1545eb8eb4d13a836aae23367cdf92005bd3bba45ec52553b6c23f12c28283fe74b084e690c54d19b96fe02ad5f008701309c3631b9604cbcffc30ecd3fa6e8b039b23d88d16be6be52134ef7c11d01ef278025c88ed73aaf4d020950cd0acc916bb4c0afc65b17fa7ba341e930630e390c490fa96ba522ea2014c802ed0240c3cc6a88bb8bff11fa46c4a79188ea27103f220abe082f88ca2b33f9131f8b802be48cf2c1b2aa267e33667605bf36970bc2992200d329a4ab11abb6d8389a201eb31f3018ad7795b9d0ed406b6cda8a5ceaa6cded9fb25a13db7237d89f58ec6e0374ecf0cf362c552cc24056a5dc00322a5377e7c9d9cafbbb30351c2bb2b9deeb0d12724f85a1dbc177745b86a7bc21d26698ab2df647cd085bb33178cb5c330ac85737fa9aee346c36352144e1843eaab3aec2aedb8b99b0b254eb64c41fecf63ee167908f357222dee0aea03593aaed969dbbc462f6415853cec3f83842ab8250844ce423332fa78da13f5095ba1ffe5d0b37d2b19e2f21254059633c31b63cc21651c5857bd3d9e3da7e9f5bddc344e46e1f44153ded566eb59454d09f09809a20dab5456898f70798d20654dd0c94a90465fdd6d436c17ae1f94d40e9cd5d91dd7f9b58a40d1a11efa998d33520c120441b7e20a52d32f0807f759f0a43379d7b1a03b9ebed6643d830cad3f43079445fc730efba333afb9d002b0e95090d8127f721e8b38ee97384694f0a3b4e3406d70396744162ba833c2a4db4dd0aa4a59306539132033165f61e0524be77084e3fcbbeef3e03dd60b2ea909ae983579c6cbb804a71603a00df137cbd846fe060d4be3233a09c33a779f95eb6b57e1631aa695839e45303aab82676923b1888bdacac3800bf1f4fc14f9a098d61ba43818ddea6069244bd9bfdd43b8c8a8fc9138f728dd8972c48b96ee4498a3515a3d20ad5f02605319674ff24742e6b1844d38d443b383a698a7ff549d55772362cdedbf48cedbc5a9233103566551459bb9e7c96fe8ac3fa8a416c3465202e97e529f3d2cfb08ca0bf99bdd1cd3eed3f4d4d66b48568e2172c435fc4496be93b4817bc9029ac4532800737752909d0e36aa776c122d59985cb8913dc6b72f96cd10ec009a1dc963e9b1907ca274140c751f476647b5504393f769f30d59ce676988f3013af97b847589c4b6192ef9dd8a8de1464a390aa869133dcb1c3579d547427368be90bb3bc8318adac0b39c28a0f96d239a011178a51d736cb92db068088fe18bb5b31462dbfac70f34c24cc0c87002f50aabfc4d24d219d77df391cb27a395814fbae6f9dd7317d637b8ef4a5d8616734095dae93383f6fcd73ba3e5584769206c50b20b50bc77b527c2c4da225e9de79e6e6833006598bb803be320a42828cd295794b86f77a2aeb7cd3db7d71c32d68a92310401cb6c04992e008ae51b729c094fef4f0d32988d01318ffaf30aa5ce524a41a4d49a006190ca2ca1e71abe139040559cc1810c26d5a25210ba37baecb357d2d92d428b0bce8149ff1f788c56a140915cad1b93e48b705993525b0f1839244bd610823062503d053d950e44d64a2968d63bcaa5da63eeb4a0c7c0a55c663bc085dc41a84a79f074ea9ce3cd6003a02fd2513dbc7930d8440939ba23fa9172322c01caadcf9af4223c8e3d3bff25dfa025a5623d2fc401659739c82da9a35e286adc607c6038c540ae195b5a8534922c5a832f74a1626e313bbfad99b0a878a6ef9c5ade3588735f01e14993417895e10bd9a7f8c72453401ee498de97872658fd0e700a61b84c0b785b1b3891a28ec51ecaed2431a1c98c425f573a711e1aaef342fff307b464b3bc25d9fe4b7e8c7a9c9dff726b9cdd86ded68dc89ef324613332835276883d83a0eadfec18afd42dcc79e603a24d78e7bc95ad4828ed4324ca14dac9a4d8c65f0ddfd74eb9e445484de4e12cbae0843ba932fade2241f39e92e697fd39384eb7d634b43c8c726e75967c48be3e28ecf426c3deaa8fa42debe8fb236b4f4694980143c5203bd980be6c670949f2ff22e930df722c2e6ac328d48d026268060d278c327eaeaa1019f5a83b204fdc375d433bc32c850d623d52267f6759c760d9c6cc3d57939d8adcf3b9d0fe48cf4cefcdf7b261be0ddc1e8f157b46061701c57157c1c43ca3f07efd0e802d12439122cfb11df8a582845801579ee48d14cf49a6d5c6cd57c7244e644401a517c440575f6acb0e82931896ed80f2c558b28e399c506a0747cd240052399bfe0292c6daea86d35636d380a8d41033a4c1ccdeb4bf0402ee4ae2b36a3d77badac2c2abe65105440ba138a9df3b3d1f3b37ef63001ed2bcd9391b08f653bc10c1ac1590045e712a6869f67b88298ac8c9eb954f22fed939271f038833af01b1eea77ed36134a444108da9c42f42eede28c466d8b2f830489eab6988f5f5566cbbc1ccc6badf293048b64116616e9f49929eaeb43b84da9e905ac7d61a59919e86168564cce3a25090e27295dc72434e06bdc0c9d43f22a0d57d07d8400ff91d71bae12099b93e7bedf4d4ced2919be57274c3a7b58078c143c7d0663e8cc2f2ae7069294df12635bf21773fca94d80cc949ae9f9ecb6decdb241e82d8e206983cd683230c79be3b14e20654294a7dacbad704c9f74bd6c9420b037804e2a8b0c4632ab97c8a14a8f89e5c79e31e3e554efeba95883fd27a1f5b85085a5e124fb10fc1786e6d054be95692c9b14174645e9241d597c7fbf32d0c9645fe9fa26f1711de6b34dc80f09249b34d2f98ef337b5c284423f51fd1c85e633464968f5785221b50e68ff974893be6f8462908df268dde2a54b4765d71d54eaa807c0b7f9ae6cd3fe8b9ceb0b7451fb64924d255934ab8a0c5a7f2d29aa3325415865d7fe9e5941e770e28ec7abebf9452267b62b436e24d1f33216564ab6ab980c4a5b478431fd87332a2bd2fef2fdc815e0babb46165c36177cfd88d6a0585a3b4f6c144fa324dda1225a3de6e04ca1b085570245df89e8f50dfa9d2db8df45af756e142b341e7c8ebc2e0eb8e27161f3791b8902a2b16440602e62757046c46b822f08ef580e7d67df1d416c891c94e12dd7e4cfc040d44df6db5cf0ad542486e15b41cb25ee6ad68071b881cbce5bd4382339550d989d84721bcad0d42e28151e9555400754581eb463c8e83128090177ff1480254bb6a1ae1fe6d8e618cc295508a37b912c6c0ca033cf8f42b9c7fec3848495117e00b73e963ea917584403a2e9a7885b3ba27bfc0d3137487622d8795641400f5633716269e21275c265cc8b54f8f5497875ebe020aa7692640ff89a74e550191c2a39e59db7cc9ea17b73989cc901a9930a07748da341830005f735c7acad3edc6a16686412eb36c909fffca54c0088664225f4ce3f35fa54e38a7947ca2be0b53574c8b5072f118b813aec8f1860b0778d08df99cd6ec6136b1d90d9a6363cb9df1dde355a373b9249a14417ef2d58baccb11a6cf0e108fd7fd7889d1a36a20638b941f69c4348616eb0c384e514751cce09b847ca3c974552d4742cd46cb22bb0f870aa068af6f650db094a8c068e754bccf0abdc6fce39166bfe28952663186c288273b6cfb6405d1169ec85743c470ab1402abd40d99c5d5d1835b2f8a4b26cdd6eed4fa3badd352ee19e0c79129439eeb6f1b99eb11801399ddb914c8108ecab01498835218a910b9902cbce840c86e4d4d37f9e7655e2626c0f638e523ac5192dd59188655ab271c3c17c9dbecb9a6a1e132d82e05cd1b223a34d5efc45660209444980468a9a6a0e1ad2e61cc31ccca0cb503ca4f4a516e62e730083da93ad4375224f6cf0bc1bd0dabef05615846ac0668028e365238c18a0d8ef2ea35c559b638c9bf5ea2fb16490b30a58e40846b15a708e1f3d5a4af10653b6d05630fabcbcbfb61878251f77b0b2260e9b484211c5b8eeb31e1f83bb596af3aa08abe0631438197464eafb9e1571486221b03ee20cf3314d145219effdcec93997eeee075ebcb8f67a4b0a23e4306e95ad8944e19ba03d57a6f375c7ed8fe6534c3f3cfbdf13d2c0a1967e1d8a74dce006c2a6122199b60262471c7485605590a91c87612eaf2f4450b63c3f1b1ae92877c4a805c5bbffabd54e7e36e8580d8c02d9b3dc64286708bfbd255b1669f2c82172e3f23120b1e2158c487219e2a27f3a1802aaea8a4c9a37a8367c4820fef1acc7c8fd5f0fb108859ea29847faff82c590c8900c6a4a814a04f38784edf2b37c6c5d273786353270907ab505dd4170f28331f880905252b9a4bb19652ca037b5be8256460f017e0aa182de5303c04b1f88f62ee5ae3d5f97f372daf59cb07e5fae36e2d53bfa7be2378528870f0b1f1844f7f13b183d821368c37a2e5dbfff1e1c694350ba757944fc67a88fd43bead16d2a0e13f42359a48e8d975206d881be7ea4f745cc185b451f38aff78acddc369ee0ba8c8be943fad46088aed19ae77d567498cccfdcb63e14b125d3ea234ff26ae53f7501e178c7712326389bc1bbf9b26dd110854f1f560bc22c0de9ebf6745af1422c4547229e2033c21c583a8728b2d60866fbd1d16dd32ed226d582e3e85fa8b2af801a543db136bf05fac2c5923e6c498c695a5b15d6f1616ec3b8b60300b353fa869008e52d0c31ec9d9ab9d8db1bb6ec88920b2dacc16b17b60fc1e1e94674a58f01a3fdd8860ed8f680f09a710c7c85143efdf6179552f44aba1aa5b9c5f19f9672c622087a73ba300bf323a704c53c1b2776116fabeeb03cd334e7ff07", + "0x3a65787472696e7369635f696e646578": "0x00000000", + "0x3e1e8e35b440038ed6e6cf14c413a10204309c1c9f4f94361ee6d85489afaf10": "0x00", + "0x3e1e8e35b440038ed6e6cf14c413a1020a1f5b09efdc16f97d72eab89c1acac1": "0x8aecbcf0b404590ddddc01ebacb205a562d12fdb5c2aa6a4035c1a20f23c9515", + "0x3e1e8e35b440038ed6e6cf14c413a1024e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x3e1e8e35b440038ed6e6cf14c413a102583c8e2a2d795fcdd0a88255e8bba7ff": "0x00", + "0x3f1467a096bcd71a5b6a0c8155e20810308ce9615de0775a82f8a94dc3d285a1": "0x01", + "0x3f1467a096bcd71a5b6a0c8155e208103f2edf3bdf381debe331ab7446addfdc": "0x000064a7b3b6e00d0000000000000000", + "0x3f1467a096bcd71a5b6a0c8155e208104e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x407d94c38db8ad2e4aa005c8942ac2c54e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x46fefe2f3b132dd55efc5cdcada84f134e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x540a4f8754aa5298a3d6e9aa09e93f974e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5c0d1176a568c1f92944340dbfed9e9c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0x3a2441e795639e09a33bf51199132d7ee10b9b67ebdb1ca30b14544c90018f7e", + "0x5f27b51b5ec208ee9cb25b55d87282434e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe380faed4eaef575446e4331b0aedf3af1258a3d7cd0171466cdaa0e615533bf37891d51589802d279537ee0ca1dcd7500e": "0x0800e1f50500a81f0b010000001b0000ac4610981cf4870300891511004eed00240000001755558eb056b757544b", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe380ff8f7c8dbf8b1ab0da6bd1d0d1f2e79920e642365c10c6ec3ea0674bde84312fb8f26b9ee76fbcad37a892cccc04004": "0x0800e1f50500a81f0b010000001b000081d54f90520b0f0200891511004eed00240000001700c0ca51b1369ceb2b", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe381ef923637ea66cf01bee7ea6ea08e4e87a65d30c7b3606d16af154d852bc1b47152eab5b714ccc9e6d6af4e4a364b14e": "0x0800e1f50500a81f0b010000001b0000380e3e7a8570f80300891511004eed0024000000170000da2b851f0bb454", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe382171efc85ee96dd122f3b2765b2b5d724a6e9105bbcbbe1019cfa1626a13c118e6f77912fce939fe987cbe6fd5704453": "0x0800e1f50500a81f0b010000001b00007ca00ba07dd5f00c00891511004eed00240000001b55550af80078ca111401", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe382b52ea25f22ca37f15ba4b55494747fea44eff5faefb33ab41cb98d8b6003db5ed693d302430d285c9a8e0915df5fd39": "0x0800e1f50500a81f0b0100000017000053162e86cd5a5a00891511004eed002400000017559531d78320918707", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38328619bcd15d3a65e5828c4143340fef5408160bdfd98e298253355d60d54240413557532d97e9f297d18849c2848812": "0x0800e1f50500a81f0b010000001b0000601cd98c6dca684f00891511004eed00240000001b0000086d6776de109e06", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe383cf7c292560b2853cd863055849dba959affdb642e45267fe134a281638b34973d04eabf4e2e419725ee4b9e8a425978": "0x0800e1f50500a81f0b010000001b0000d8645211a0c2780100891511004eed002400000017aaaabcddc6568d651f", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe383db2a7637882267dae62ddb2296d63f21c71e0c8615d19b0f973afc04ee767138e44b546d2294eccca2e4afceb31cb70": "0x0800e1f50500a81f0b010000001b000010daceecbc213c0d00891511004eed00240000001b555581e7bb1325581a01", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38405d66e8362d05d2279a7f60ba93a27a867ae1095c920bb339b570004ac97121c989fdbdd3db3965908279b7c5724b49": "0x0800e1f50500a81f0b010000001700000e6644a594a3a500891511004eed0024000000170080d65d70b8a1cd0d", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe3844d05c4c59c44805473b81294dc5feee4c6358a29ce86cd404342787dd9e823e1da6a82cd0bcc74f286d44b7663f2e2e": "0x0800e1f50500a81f0b010000001b0000c038b219db94d19e00891511004eed00240000001b000010daceecbc213c0d", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe384755a560a6e7b022fde2ce4ccef2243c18e828e85cebd4c7684e15d2e1e0d0699b243f76ed457d22895cc48f3e3b8c35": "0x0800e1f50500a81f0b010000001b0000ed9b8c4313bfc30100891511004eed00240000001700c05362f69a41a525", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe3847d1e019255f155b1661cbc344650b32549b096144124726bba7b5f3518ae1229740be100646ff0e4c28c340bcb80239": "0x0800e1f50500a81f0b010000001b000040b2bac9e0191e0200891511004eed002400000017555585397abbd22c2d", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38575c2ebe0e2e82acfe7764d89a8b379c302267ef0b206915c96f39d81ae769ac11637665be9e014e4898fbbf5db92f31": "0x0800e1f50500a81f0b010000001b0000c071f0d12b84c31f00891511004eed00240000001b0000d05e29fc58a0a502", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe385e52e5fc69d19c5249999ceb9ff179aaccd886be975fbb469f788aceac28cd295b7fa0e5c691b8e3fd780fdae59aa144": "0x0800e1f50500a81f0b010000001b00007275d27c2246cd1000891511004eed00240000001baa2a7434bcdf82706601", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe3871e68bb6be54305b43fb93f16a9e922d8912d71a1cbb7efc012ca9c4cd6b7300cddb39d77f088d91924891531c5421ca": "0x0800e1f50500a81f0b010000001b000097774cdfa2d5830500891511004eed0024000000170040f709f1e722a775", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe387ca5649b924e4f7bc893244ea7d7289ddb5c859a44555a3852007f4778184309f12a02a22276c37decd753ed5f23e56e": "0x0800e1f50500a81f0b010000001b000096afbdc42ba9d90100891511004eed00240000001700804c79baa5c37827", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe388c55579a256cc8aa3de388477e3c2f10aeea4fcb658f17b2c6cd1fce911866307e614dd49c7324eb9ca193ae037d9c0a": "0x0800e1f50500a81f0b010000001b00002fc2d1541c57781000891511004eed00240000001baaea8325bcb1975c5f01", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38b2611eca3c4d08d1f96a367f02e7ef421ab54e6f4b40816fe44de8fe8933fae4cbf7239428e080e6fbd92dd6c6bdcb2c": "0x0800e1f50500a81f0b010000001b0000d8645211a0c2780100891511004eed002400000017aaaabcddc6568d651f", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38b2790bdc65df4f43cd1fa30327e0e4616262eae57cdf41aec44acc93f416bfdbb6d8a1430ba19b779ae5c98d6b7df870": "0x0800e1f50500a81f0b010000001b00008d59df3bc5ff0e0700891511004eed002400000017551521f2a76f509596", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38b6ec98437c6aeb030233efded28ca4eeb621672f0d8be43b4dcd16aa2aa034db3fe3212b9f46fbfc26668426f9510a65": "0x0800e1f50500a81f0b010000001b0000b09721e56e62871200891511004eed00240000001baaaa4e776de833488b01", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38bca32e4c2881d806c76954996916e56540cb8e75a9a1e766c8a6b551b635e513a16cbb8f4d9aa13936254166e4de4018": "0x0800e1f50500a81f0b010000001b0000c0a805aba81c4b1700891511004eed00240000001baaaaba78400e0eedf001", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38bd8f48d51b9726ca4bc2073ac23559d59ac654f1421b1c97b2380e08e297bd16281bdc486be24d970b9a5804e37b606d": "0x0800e1f50500a81f0b010000001700009b9d3b827fdaf400891511004eed002400000017559577a22fa08a6714", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38d8e3f5f6e0e7467fb94c6f63e03209d588a7d9e994528a48574fef4fbb9b731976760ca7a97358a38734c2ef04475909": "0x0800e1f50500a81f0b010000001b0000ef462c64b8d5e10500891511004eed0024000000170040e90559087a7c7d", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38daf780801663f5988ea2f39ab617da297a8c2df3c7945888b20fcfc570c45c7db18e20c9fe57b66b0071bcbbfde10e60": "0x0800e1f50500a81f0b010000001700003d9640acaa2b2d00891511004eed00240000001700c02fb75a8ea3c303", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38ddde0c79d5570b8684a0379815fb60c6127661e3abe3f347aa88bf2cf09545f387f03438e8ef778fe0adf3bfc61c395c": "0x0800e1f50500a81f0b010000001b00009e12b3d70c2a2d0100891511004eed00240000001755d537ec4e67d61819", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38e10702f089fdce41f89785cdc64bde8dd46827949a45e460ad655510b58be8a03079eea740ab57f3cd8adade1de78935": "0x0800e1f50500a81f0b010000001b0000ed9b8c4313bfc30100891511004eed00240000001700c05362f69a41a525", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38ea7d4c5edeed232ba55a698373b8749c146459b6f23d9ffa4876ba11293be2dc849cef7d5aad3c583a5526764dd47a54": "0x0800e1f50500a81f0b010000001b0000903e44807e55781100891511004eed00240000001b00008c5ab08acab17401", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38ed8dc744f3fa96cc08a0e88c2ec81438a02fe19c7b04359086a7753e0ffb918f3b8bdbdba1ef0db8fdd50f42e14e202c": "0x0800e1f50500a81f0b010000001b0000a0bd52f8b1404b0500891511004eed0024000000175555cd8fb1d40ef070", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38efe1dce87a8138c87a9755a192d55aee4e448bf0f6c08e0443fd318476062713c3b84e1f0d3558206777991441ed0a1c": "0x0800e1f50500a81f0b010000001b0000407ba5f06381960a00891511004eed002400000017aaaa9a1f63a91de0e1", + "0x5f27b51b5ec208ee9cb25b55d87282439c806850c4ee3bc06ba62b096318fe38f2300b6e4e4a41213463d1870331bc97b089c0020178b1025ab79018dbf442db463aea6b55feaee7c8500e6373a40c3a": "0x0800e1f50500a81f0b0100000017000090ac6e3278868700891511004eed0024000000175555618edeae344b0b", + "0x660556752ce236c466dad8256bea8bf44e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x7396903df85f816e40b96a10626866ac4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x7396903df85f816e40b96a10626866aca1f7f19e9ecaab191be170a34f0ddaf8": "0x00", + "0x7396903df85f816e40b96a10626866acbd7dfaa70db5595978338923a0db23c4": "0x01", + "0x7396903df85f816e40b96a10626866ace61eaec3ce42854f2a62e7b6487718e2": "0x64000000", + "0x86d14ebdcabe8f22d507b904cd78e9494e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x8bdb109e83bb8c1b6a8d9569c54b22464e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xa56fe8526dd0fbcefe5e4cf42d4a83394e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc60faed4eaef575446e4331b0aedf3af1258a3d7cd0171466cdaa0e615533bf37891d51589802d279537ee0ca1dcd7500e": "0x046f726d6c76657374f4ffaf1a416072d01f0e00000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc60ff8f7c8dbf8b1ab0da6bd1d0d1f2e79920e642365c10c6ec3ea0674bde84312fb8f26b9ee76fbcad37a892cccc04004": "0x046f726d6c76657374000004563f414a2d3c0800000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc61ef923637ea66cf01bee7ea6ea08e4e87a65d30c7b3606d16af154d852bc1b47152eab5b714ccc9e6d6af4e4a364b14e": "0x046f726d6c766573740000e038f8e815c2e10f00000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc62171efc85ee96dd122f3b2765b2b5d724a6e9105bbcbbe1019cfa1626a13c118e6f77912fce939fe987cbe6fd5704453": "0x046f726d6c76657374f4ffef812e80f655c33300000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc62b52ea25f22ca37f15ba4b55494747fea44eff5faefb33ab41cb98d8b6003db5ed693d302430d285c9a8e0915df5fd39": "0x046f726d6c76657374f4ff4b59b818366b690100000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6328619bcd15d3a65e5828c4143340fef5408160bdfd98e298253355d60d54240413557532d97e9f297d18849c2848812": "0x046f726d6c76657374000080716433b629a33d01000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc63cf7c292560b2853cd863055849dba959affdb642e45267fe134a281638b34973d04eabf4e2e419725ee4b9e8a425978": "0x046f726d6c76657374e8ff5f934945800ae30500000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc63db2a7637882267dae62ddb2296d63f21c71e0c8615d19b0f973afc04ee767138e44b546d2294eccca2e4afceb31cb70": "0x046f726d6c76657374f4ff3f683bb3f386f03400000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6405d66e8362d05d2279a7f60ba93a27a867ae1095c920bb339b570004ac97121c989fdbdd3db3965908279b7c5724b49": "0x046f726d6c76657374000038981195528e960200000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc644d05c4c59c44805473b81294dc5feee4c6358a29ce86cd404342787dd9e823e1da6a82cd0bcc74f286d44b7663f2e2e": "0x046f726d6c76657374000000e3c8666c53467b02000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc64755a560a6e7b022fde2ce4ccef2243c18e828e85cebd4c7684e15d2e1e0d0699b243f76ed457d22895cc48f3e3b8c35": "0x046f726d6c766573740000b46f320e4dfc0e0700000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc647d1e019255f155b1661cbc344650b32549b096144124726bba7b5f3518ae1229740be100646ff0e4c28c340bcb80239": "0x046f726d6c76657374f4ffffc8ea268367780800000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6575c2ebe0e2e82acfe7764d89a8b379c302267ef0b206915c96f39d81ae769ac11637665be9e014e4898fbbf5db92f31": "0x046f726d6c76657374000000c7c147af100e7f00000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc65e52e5fc69d19c5249999ceb9ff179aaccd886be975fbb469f788aceac28cd295b7fa0e5c691b8e3fd780fdae59aa144": "0x046f726d6c76657374e8ffc7d549f38918354300000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc671e68bb6be54305b43fb93f16a9e922d8912d71a1cbb7efc012ca9c4cd6b7300cddb39d77f088d91924891531c5421ca": "0x046f726d6c7665737400005cde317d8b560f1600000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc67ca5649b924e4f7bc893244ea7d7289ddb5c859a44555a3852007f4778184309f12a02a22276c37decd753ed5f23e56e": "0x046f726d6c76657374000058bef612afa4660700000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc68c55579a256cc8aa3de388477e3c2f10aeea4fcb658f17b2c6cd1fce911866307e614dd49c7324eb9ca193ae037d9c0a": "0x046f726d6c76657374e8ffbb084753715ce14100000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6b2611eca3c4d08d1f96a367f02e7ef421ab54e6f4b40816fe44de8fe8933fae4cbf7239428e080e6fbd92dd6c6bdcb2c": "0x046f726d6c76657374e8ff5f934945800ae30500000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6b2790bdc65df4f43cd1fa30327e0e4616262eae57cdf41aec44acc93f416bfdbb6d8a1430ba19b779ae5c98d6b7df870": "0x046f726d6c76657374f4ff33667def14ff3b1c00000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6b6ec98437c6aeb030233efded28ca4eeb621672f0d8be43b4dcd16aa2aa034db3fe3212b9f46fbfc26668426f9510a65": "0x046f726d6c76657374e8ffbf5e8694bb891d4a00000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6bca32e4c2881d806c76954996916e56540cb8e75a9a1e766c8a6b551b635e513a16cbb8f4d9aa13936254166e4de4018": "0x046f726d6c76657374e8ffffa216aca2722c5d00000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6bd8f48d51b9726ca4bc2073ac23559d59ac654f1421b1c97b2380e08e297bd16281bdc486be24d970b9a5804e37b606d": "0x046f726d6c76657374f4ff6b76ee08fe69d30300000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6d8e3f5f6e0e7467fb94c6f63e03209d588a7d9e994528a48574fef4fbb9b731976760ca7a97358a38734c2ef04475909": "0x046f726d6c766573740000bc1bb190e156871700000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6daf780801663f5988ea2f39ab617da297a8c2df3c7945888b20fcfc570c45c7db18e20c9fe57b66b0071bcbbfde10e60": "0x046f726d6c766573740000f45802b1aaaeb40000000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6ddde0c79d5570b8684a0379815fb60c6127661e3abe3f347aa88bf2cf09545f387f03438e8ef778fe0adf3bfc61c395c": "0x046f726d6c76657374f4ff774acc5e33a8b40400000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6e10702f089fdce41f89785cdc64bde8dd46827949a45e460ad655510b58be8a03079eea740ab57f3cd8adade1de78935": "0x046f726d6c766573740000b46f320e4dfc0e0700000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6ea7d4c5edeed232ba55a698373b8749c146459b6f23d9ffa4876ba11293be2dc849cef7d5aad3c583a5526764dd47a54": "0x046f726d6c76657374000040fa1001fa55e14500000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6ed8dc744f3fa96cc08a0e88c2ec81438a02fe19c7b04359086a7753e0ffb918f3b8bdbdba1ef0db8fdd50f42e14e202c": "0x046f726d6c76657374f4ff7ff64ae1c7022d1500000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6efe1dce87a8138c87a9755a192d55aee4e448bf0f6c08e0443fd318476062713c3b84e1f0d3558206777991441ed0a1c": "0x046f726d6c76657374e8ffffec95c28f055a2a00000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6f2300b6e4e4a41213463d1870331bc97b089c0020178b1025ab79018dbf442db463aea6b55feaee7c8500e6373a40c3a": "0x046f726d6c76657374f4ff3fb2bac9e0191e0200000000000002", + "0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x000050f732e897cad8fb060000000000", + "0xd5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0xf0c365c3cf59d671eb72da0e7a4113c44e7b9012096b41c4eb3aaf947f6ea429": "0x0000" + }, + "childrenDefault": {} + } + } +} diff --git a/crates/subspace-node/src/bin/subspace-node.rs b/crates/subspace-node/src/bin/subspace-node.rs index a4982f2b812..3ab768dc05a 100644 --- a/crates/subspace-node/src/bin/subspace-node.rs +++ b/crates/subspace-node/src/bin/subspace-node.rs @@ -16,62 +16,30 @@ //! Subspace node implementation. -// TODO: remove -#![allow(dead_code, unused_imports)] - -use core_evm_runtime::AccountId as AccountId20; -use cross_domain_message_gossip::GossipWorkerBuilder; -use domain_client_executor::ExecutorStreams; -use domain_eth_service::provider::EthProvider; -use domain_eth_service::DefaultEthConfig; +use domain_client_operator::Bootstrapper; use domain_runtime_primitives::opaque::Block as DomainBlock; -use domain_runtime_primitives::AccountId as AccountId32; -use domain_service::providers::DefaultProvider; -use domain_service::{FullBackend, FullClient}; use frame_benchmarking_cli::BenchmarkCmd; use futures::future::TryFutureExt; -use futures::StreamExt; use sc_cli::{ChainSpec, CliConfiguration, SubstrateCli}; -use sc_client_api::BlockchainEvents; use sc_consensus_slots::SlotProportion; -use sc_executor::NativeExecutionDispatch; -use sc_service::{BasePath, PartialComponents}; +use sc_proof_of_time::PotComponents; +use sc_service::PartialComponents; use sc_storage_monitor::StorageMonitorService; -use sc_subspace_chain_specs::ExecutionChainSpec; use sp_core::crypto::Ss58AddressFormat; use sp_core::traits::SpawnEssentialNamed; -use sp_domains::DomainId; -use sp_runtime::traits::Identity; -use std::any::TypeId; -use subspace_node::{ - AccountId32ToAccountId20Converter, Cli, ExecutorDispatch, Subcommand, SystemDomainCli, - SystemDomainSubcommand, +use sp_domains::GenerateGenesisStateRoot; +use std::sync::Arc; +use subspace_node::domain::{ + AccountId32ToAccountId20Converter, DomainCli, DomainGenesisBlockBuilder, DomainInstanceStarter, + DomainSubcommand, EVMDomainExecutorDispatch, }; +use subspace_node::{Cli, ExecutorDispatch, Subcommand}; use subspace_proof_of_space::chia::ChiaTable; use subspace_runtime::{Block, RuntimeApi}; use subspace_service::{DsnConfig, SubspaceConfiguration, SubspaceNetworking}; -use system_domain_runtime::GenesisConfig as ExecutionGenesisConfig; type PosTable = ChiaTable; -/// System domain executor instance. -pub struct SystemDomainExecutorDispatch; - -impl NativeExecutionDispatch for SystemDomainExecutorDispatch { - #[cfg(feature = "runtime-benchmarks")] - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - #[cfg(not(feature = "runtime-benchmarks"))] - type ExtendHostFunctions = (); - - fn dispatch(method: &str, data: &[u8]) -> Option> { - system_domain_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - system_domain_runtime::native_version() - } -} - /// Subspace node error. #[derive(thiserror::Error, Debug)] pub enum Error { @@ -138,7 +106,7 @@ fn main() -> Result<(), Error> { task_manager, .. } = subspace_service::new_partial::( - &config, + &config, None, None, )?; Ok(( cmd.run(client, import_queue).map_err(Error::SubstrateCli), @@ -155,7 +123,7 @@ fn main() -> Result<(), Error> { task_manager, .. } = subspace_service::new_partial::( - &config, + &config, None, None, )?; Ok(( cmd.run(client, config.database) @@ -173,7 +141,7 @@ fn main() -> Result<(), Error> { task_manager, .. } = subspace_service::new_partial::( - &config, + &config, None, None, )?; Ok(( cmd.run(client, config.chain_spec) @@ -192,7 +160,7 @@ fn main() -> Result<(), Error> { task_manager, .. } = subspace_service::new_partial::( - &config, + &config, None, None, )?; Ok(( cmd.run(client, import_queue).map_err(Error::SubstrateCli), @@ -200,49 +168,15 @@ fn main() -> Result<(), Error> { )) })?; } - Some(Subcommand::ImportBlocksFromDsn(cmd)) => { - let runner = cli.create_runner(cmd)?; - set_default_ss58_version(&runner.config().chain_spec); - runner.async_run(|config| { - let PartialComponents { - client, - import_queue, - task_manager, - other: (_block_import, subspace_link, _telemetry, _bundle_validator), - .. - } = subspace_service::new_partial::( - &config, - )?; - - let subspace_archiver = sc_consensus_subspace::create_subspace_archiver( - &subspace_link, - client.clone(), - None, - ); - - task_manager - .spawn_essential_handle() - .spawn_essential_blocking( - "subspace-archiver", - None, - Box::pin(subspace_archiver), - ); - - Ok(( - cmd.run(client, import_queue, task_manager.spawn_essential_handle()) - .map_err(Error::SubstrateCli), - task_manager, - )) - })?; - } Some(Subcommand::PurgeChain(cmd)) => { // This is a compatibility layer to make sure we wipe old data from disks of our users if let Some(base_dir) = dirs::data_local_dir() { for chain in &[ - "subspace_gemini_1b", - "Lamda_2513", - "Lamda_2513_2", - "Lamda_2513_3", + "subspace_gemini_2a", + "subspace_gemini_3a", + "subspace_gemini_3b", + "subspace_gemini_3c", + "subspace_gemini_3d", ] { let _ = std::fs::remove_dir_all( base_dir.join("subspace-node").join("chains").join(chain), @@ -252,36 +186,26 @@ fn main() -> Result<(), Error> { let runner = cli.create_runner(&cmd.base)?; - runner.sync_run(|primary_chain_config| { - let maybe_system_domain_chain_spec = primary_chain_config - .chain_spec - .extensions() - .get_any(TypeId::of::>()) - .downcast_ref() - .cloned(); - - let system_domain_cli = SystemDomainCli::new( + runner.sync_run(|consensus_chain_config| { + let domain_cli = DomainCli::new( cmd.base .base_path()? .map(|base_path| base_path.path().to_path_buf()), - maybe_system_domain_chain_spec.ok_or_else(|| { - "Primary chain spec must contain system domain chain spec".to_string() - })?, cli.domain_args.into_iter(), ); - let system_domain_config = SubstrateCli::create_configuration( - &system_domain_cli, - &system_domain_cli, - primary_chain_config.tokio_handle.clone(), + let domain_config = SubstrateCli::create_configuration( + &domain_cli, + &domain_cli, + consensus_chain_config.tokio_handle.clone(), ) .map_err(|error| { sc_service::Error::Other(format!( - "Failed to create system domain configuration: {error:?}" + "Failed to create domain configuration: {error:?}" )) })?; - cmd.run(primary_chain_config, system_domain_config) + cmd.run(consensus_chain_config, domain_config) })?; } Some(Subcommand::Revert(cmd)) => { @@ -294,7 +218,7 @@ fn main() -> Result<(), Error> { task_manager, .. } = subspace_service::new_partial::( - &config, + &config, None, None, )?; Ok(( cmd.run(client, backend, None).map_err(Error::SubstrateCli), @@ -329,7 +253,9 @@ fn main() -> Result<(), Error> { PosTable, RuntimeApi, ExecutorDispatch, - >(&config)?; + >( + &config, None, None + )?; cmd.run(client) } @@ -337,7 +263,7 @@ fn main() -> Result<(), Error> { let PartialComponents { client, backend, .. } = subspace_service::new_partial::( - &config, + &config, None, None, )?; let db = backend.expose_db(); let storage = backend.expose_storage(); @@ -378,30 +304,23 @@ fn main() -> Result<(), Error> { } })?; } - Some(Subcommand::Executor(executor_cmd)) => match executor_cmd { - SystemDomainSubcommand::Benchmark(cmd) => { + Some(Subcommand::Domain(domain_cmd)) => match domain_cmd { + DomainSubcommand::Benchmark(cmd) => { let runner = cli.create_runner(cmd)?; - runner.sync_run(|primary_chain_config| { - let maybe_system_domain_chain_spec = primary_chain_config - .chain_spec - .extensions() - .get_any(TypeId::of::>()) - .downcast_ref() - .cloned(); - let system_domain_cli = SystemDomainCli::new( + runner.sync_run(|consensus_chain_config| { + let domain_cli = DomainCli::new( cli.run .base_path()? .map(|base_path| base_path.path().to_path_buf()), - maybe_system_domain_chain_spec.ok_or_else(|| { - "Primary chain spec must contain system domain chain spec".to_string() - })?, cli.domain_args.into_iter(), ); - let system_domain_config = system_domain_cli - .create_domain_configuration(primary_chain_config.tokio_handle) + let domain_config = domain_cli + .create_domain_configuration::<_, AccountId32ToAccountId20Converter>( + consensus_chain_config.tokio_handle, + ) .map_err(|error| { sc_service::Error::Other(format!( - "Failed to create system domain configuration: {error:?}" + "Failed to create domain configuration: {error:?}" )) })?; match cmd { @@ -413,42 +332,37 @@ fn main() -> Result<(), Error> { .into(), ); } - cmd.run::( - system_domain_config.service_config, + cmd.run::( + domain_config.service_config, ) } _ => todo!("Not implemented"), } })?; } - _ => unimplemented!("Executor subcommand"), + _ => unimplemented!("Domain subcommand"), }, None => { let runner = cli.create_runner(&cli.run)?; set_default_ss58_version(&runner.config().chain_spec); - runner.run_node_until_exit(|primary_chain_config| async move { - let tokio_handle = primary_chain_config.tokio_handle.clone(); - let database_source = primary_chain_config.database.clone(); - - let maybe_system_domain_chain_spec = primary_chain_config - .chain_spec - .extensions() - .get_any(TypeId::of::>()) - .downcast_ref() - .cloned(); - - // TODO: proper value - let primary_block_import_throttling_buffer_size = 10; + runner.run_node_until_exit(|consensus_chain_config| async move { + let tokio_handle = consensus_chain_config.tokio_handle.clone(); + let database_source = consensus_chain_config.database.clone(); + let pot_components = if cli.pot_role.is_pot_enabled() { + Some(PotComponents::new(cli.pot_role.is_time_keeper())) + } else { + None + }; - let mut primary_chain_node = { + let consensus_chain_node = { let span = sc_tracing::tracing::info_span!( sc_tracing::logging::PREFIX_LOG_SPAN, - name = "PrimaryChain" + name = "Consensus" ); let _enter = span.enter(); let dsn_config = { - let network_keypair = primary_chain_config + let network_keypair = consensus_chain_config .network .node_key .clone() @@ -460,7 +374,7 @@ fn main() -> Result<(), Error> { })?; let dsn_bootstrap_nodes = if cli.dsn_bootstrap_nodes.is_empty() { - primary_chain_config + consensus_chain_config .chain_spec .properties() .get("dsnBootstrapNodes") @@ -490,24 +404,25 @@ fn main() -> Result<(), Error> { DsnConfig { keypair, base_path: cli.run.base_path()?.map(|base_path| { - base_path - .config_dir(primary_chain_config.chain_spec.id()) - .join("dsn") + base_path.config_dir(consensus_chain_config.chain_spec.id()) }), listen_on: cli.dsn_listen_on, bootstrap_nodes: dsn_bootstrap_nodes, reserved_peers: cli.dsn_reserved_peers, - allow_non_global_addresses_in_dht: !cli.dsn_disable_private_ips, + // Override enabling private IPs with --dev + allow_non_global_addresses_in_dht: cli.dsn_enable_private_ips + || cli.run.shared_params.dev, max_in_connections: cli.dsn_in_connections, max_out_connections: cli.dsn_out_connections, max_pending_in_connections: cli.dsn_pending_in_connections, max_pending_out_connections: cli.dsn_pending_out_connections, target_connections: cli.dsn_target_connections, + external_addresses: cli.dsn_external_addresses, } }; - let primary_chain_config = SubspaceConfiguration { - base: primary_chain_config, + let consensus_chain_config = SubspaceConfiguration { + base: consensus_chain_config, // Domain node needs slots notifications for bundle production. force_new_slot_notifications: !cli.domain_args.is_empty(), subspace_networking: SubspaceNetworking::Create { @@ -519,9 +434,15 @@ fn main() -> Result<(), Error> { || cli.run.is_dev().unwrap_or(false), }; + let construct_domain_genesis_block_builder = + |backend, executor| -> Arc { + Arc::new(DomainGenesisBlockBuilder::new(backend, executor)) + }; let partial_components = subspace_service::new_partial::( - &primary_chain_config, + &consensus_chain_config, + Some(&construct_domain_genesis_block_builder), + pot_components, ) .map_err(|error| { sc_service::Error::Other(format!( @@ -530,7 +451,7 @@ fn main() -> Result<(), Error> { })?; subspace_service::new_full::( - primary_chain_config, + consensus_chain_config, partial_components, true, SlotProportion::new(3f32 / 4f32), @@ -546,123 +467,73 @@ fn main() -> Result<(), Error> { StorageMonitorService::try_spawn( cli.storage_monitor, database_source, - &primary_chain_node.task_manager.spawn_essential_handle(), + &consensus_chain_node.task_manager.spawn_essential_handle(), ) .map_err(|error| { sc_service::Error::Other(format!("Failed to start storage monitor: {error:?}")) })?; - // Run an executor node, an optional component of Subspace full node. + // Run a domain node. if !cli.domain_args.is_empty() { let span = sc_tracing::tracing::info_span!( sc_tracing::logging::PREFIX_LOG_SPAN, - name = "SystemDomain" + name = "Domain" ); let _enter = span.enter(); - let system_domain_cli = SystemDomainCli::new( + let domain_cli = DomainCli::new( cli.run .base_path()? .map(|base_path| base_path.path().to_path_buf()), - maybe_system_domain_chain_spec.ok_or_else(|| { - "Primary chain spec must contain system domain chain spec".to_string() - })?, cli.domain_args.into_iter(), ); + let domain_id = domain_cli.domain_id; - let system_domain_config = system_domain_cli - .create_domain_configuration(tokio_handle.clone()) - .map_err(|error| { - sc_service::Error::Other(format!( - "Failed to create system domain configuration: {error:?}" - )) - })?; + let bootstrapper = + Bootstrapper::::new(consensus_chain_node.client.clone()); - let block_importing_notification_stream = || { - primary_chain_node + let domain_starter = DomainInstanceStarter { + domain_cli, + tokio_handle, + consensus_client: consensus_chain_node.client.clone(), + block_importing_notification_stream: consensus_chain_node .block_importing_notification_stream - .subscribe() - .then(|block_importing_notification| async move { - ( - block_importing_notification.block_number, - block_importing_notification.acknowledgement_sender, - ) - }) - }; - - let new_slot_notification_stream = || { - primary_chain_node + .clone(), + new_slot_notification_stream: consensus_chain_node .new_slot_notification_stream - .subscribe() - .then(|slot_notification| async move { - ( - slot_notification.new_slot_info.slot, - slot_notification.new_slot_info.global_challenge, - None, - ) - }) + .clone(), + consensus_network_service: consensus_chain_node.network_service.clone(), + consensus_sync_service: consensus_chain_node.sync_service.clone(), + select_chain: consensus_chain_node.select_chain.clone(), }; - let mut xdm_gossip_worker_builder = GossipWorkerBuilder::new(); - - let executor_streams = ExecutorStreams { - primary_block_import_throttling_buffer_size, - block_importing_notification_stream: block_importing_notification_stream(), - imported_block_notification_stream: primary_chain_node - .client - .every_import_notification_stream(), - new_slot_notification_stream: new_slot_notification_stream(), - _phantom: Default::default(), - }; - - let system_domain_node = domain_service::new_full_system::< - _, - _, - _, - _, - _, - _, - system_domain_runtime::RuntimeApi, - SystemDomainExecutorDispatch, - >( - system_domain_config, - primary_chain_node.client.clone(), - primary_chain_node.sync_service.clone(), - &primary_chain_node.select_chain, - executor_streams, - xdm_gossip_worker_builder.gossip_msg_sink(), - ) - .await?; - - xdm_gossip_worker_builder.push_domain_tx_pool_sink( - DomainId::SYSTEM, - system_domain_node.tx_pool_sink, - ); - - primary_chain_node - .task_manager - .add_child(system_domain_node.task_manager); - - let cross_domain_message_gossip_worker = xdm_gossip_worker_builder - .build::( - primary_chain_node.network_service.clone(), - primary_chain_node.sync_service.clone(), - ); - - primary_chain_node + consensus_chain_node .task_manager .spawn_essential_handle() .spawn_essential_blocking( - "cross-domain-gossip-message-worker", + "domain", None, - Box::pin(cross_domain_message_gossip_worker.run()), + Box::pin(async move { + let bootstrap_result = + match bootstrapper.fetch_domain_bootstrap_info(domain_id).await + { + Err(err) => { + log::error!( + "Domain bootsrapper exited with an error {err:?}" + ); + return; + } + Ok(res) => res, + }; + if let Err(error) = domain_starter.start(bootstrap_result).await { + log::error!("Domain starter exited with an error {error:?}"); + } + }), ); - - system_domain_node.network_starter.start_network(); } - primary_chain_node.network_starter.start_network(); - Ok::<_, Error>(primary_chain_node.task_manager) + consensus_chain_node.network_starter.start_network(); + Ok::<_, Error>(consensus_chain_node.task_manager) })?; } } diff --git a/crates/subspace-node/src/chain_spec.rs b/crates/subspace-node/src/chain_spec.rs index fa1016a1ead..8042ed94d6a 100644 --- a/crates/subspace-node/src/chain_spec.rs +++ b/crates/subspace-node/src/chain_spec.rs @@ -16,22 +16,27 @@ //! Subspace chain configurations. -use crate::chain_spec_utils::{chain_spec_properties, get_account_id_from_seed}; -use crate::system_domain; -use sc_service::ChainType; -use sc_subspace_chain_specs::{ChainSpecExtensions, ConsensusChainSpec}; +use crate::chain_spec_utils::{ + chain_spec_properties, get_account_id_from_seed, get_public_key_from_seed, +}; +use crate::domain::evm_chain_spec::{self, SpecId}; +use sc_service::{ChainType, NoExtension}; +use sc_subspace_chain_specs::ConsensusChainSpec; use sc_telemetry::TelemetryEndpoints; use sp_consensus_subspace::FarmerPublicKey; use sp_core::crypto::{Ss58Codec, UncheckedFrom}; +use sp_domains::{OperatorPublicKey, RuntimeType}; +use sp_runtime::Percent; use subspace_runtime::{ - AllowAuthoringBy, BalancesConfig, GenesisConfig, RuntimeConfigsConfig, SubspaceConfig, - SudoConfig, SystemConfig, VestingConfig, MILLISECS_PER_BLOCK, WASM_BINARY, + AllowAuthoringBy, BalancesConfig, DomainsConfig, GenesisConfig, MaxDomainBlockSize, + MaxDomainBlockWeight, RuntimeConfigsConfig, SubspaceConfig, SudoConfig, SystemConfig, + VestingConfig, MILLISECS_PER_BLOCK, WASM_BINARY, }; use subspace_runtime_primitives::{AccountId, Balance, BlockNumber, SSC}; -use system_domain_runtime::GenesisConfig as SystemDomainGenesisConfig; const SUBSPACE_TELEMETRY_URL: &str = "wss://telemetry.subspace.network/submit/"; const DEVNET_CHAIN_SPEC: &[u8] = include_bytes!("../res/chain-spec-raw-devnet.json"); +const GEMINI_3E_CHAIN_SPEC: &[u8] = include_bytes!("../res/chain-spec-raw-gemini-3e.json"); /// List of accounts which should receive token grants, amounts are specified in SSC. const TOKEN_GRANTS: &[(&str, u128)] = &[ @@ -78,22 +83,21 @@ struct GenesisParams { enable_rewards: bool, enable_storage_access: bool, allow_authoring_by: AllowAuthoringBy, - enable_executor: bool, + enable_domains: bool, enable_transfer: bool, confirmation_depth_k: u32, } -pub fn gemini_3d_compiled( -) -> Result, String> { +pub fn gemini_3e_compiled() -> Result, String> { Ok(ConsensusChainSpec::from_genesis( // Name - "Subspace Gemini 3d", + "Subspace Gemini 3e", // ID - "subspace_gemini_3d", - ChainType::Custom("Subspace Gemini 3d".to_string()), + "subspace_gemini_3e", + ChainType::Custom("Subspace Gemini 3e".to_string()), || { let sudo_account = - AccountId::from_ss58check("5CZy4hcmaVZUMZLfB41v1eAKvtZ8W7axeWuDvwjhjPwfhAqt") + AccountId::from_ss58check("5DNwQTHfARgKoa2NdiUM51ZUow7ve5xG9S2yYdSbVQcnYxBA") .expect("Wrong root account address"); let mut balances = vec![(sudo_account.clone(), 1_000 * SSC)]; @@ -134,6 +138,7 @@ pub fn gemini_3d_compiled( }) .collect::>(); subspace_genesis_config( + SpecId::Gemini, WASM_BINARY.expect("Wasm binary must be built for Gemini"), sudo_account, balances, @@ -146,7 +151,7 @@ pub fn gemini_3d_compiled( "8aecbcf0b404590ddddc01ebacb205a562d12fdb5c2aa6a4035c1a20f23c9515" )), ), - enable_executor: true, + enable_domains: true, enable_transfer: false, confirmation_depth_k: 100, // TODO: Proper value here }, @@ -160,29 +165,24 @@ pub fn gemini_3d_compiled( .map_err(|error| error.to_string())?, ), // Protocol ID - Some("subspace-gemini-3d"), + Some("subspace-gemini-3e"), None, // Properties Some(chain_spec_properties()), // Extensions - ChainSpecExtensions { - execution_chain_spec: system_domain::chain_spec::gemini_3d_config(), - }, + NoExtension::None, )) } -pub fn gemini_3d_config( -) -> Result, String> { - Err("Wrong release for Gemini 3d. Use the release prefixed with `gemini-3d`".to_string()) +pub fn gemini_3e_config() -> Result, String> { + ConsensusChainSpec::from_json_bytes(GEMINI_3E_CHAIN_SPEC) } -pub fn devnet_config( -) -> Result, String> { +pub fn devnet_config() -> Result, String> { ConsensusChainSpec::from_json_bytes(DEVNET_CHAIN_SPEC) } -pub fn devnet_config_compiled( -) -> Result, String> { +pub fn devnet_config_compiled() -> Result, String> { Ok(ConsensusChainSpec::from_genesis( // Name "Subspace Dev network", @@ -232,6 +232,7 @@ pub fn devnet_config_compiled( }) .collect::>(); subspace_genesis_config( + SpecId::DevNet, WASM_BINARY.expect("Wasm binary must be built for Gemini"), sudo_account, balances, @@ -240,7 +241,7 @@ pub fn devnet_config_compiled( enable_rewards: false, enable_storage_access: false, allow_authoring_by: AllowAuthoringBy::FirstFarmer, - enable_executor: true, + enable_domains: true, enable_transfer: true, confirmation_depth_k: 100, // TODO: Proper value here }, @@ -259,14 +260,11 @@ pub fn devnet_config_compiled( // Properties Some(chain_spec_properties()), // Extensions - ChainSpecExtensions { - execution_chain_spec: system_domain::chain_spec::devnet_config(), - }, + NoExtension::None, )) } -pub fn dev_config() -> Result, String> -{ +pub fn dev_config() -> Result, String> { let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?; Ok(ConsensusChainSpec::from_genesis( @@ -277,6 +275,7 @@ pub fn dev_config() -> Result Result Result Result, String> -{ +pub fn local_config() -> Result, String> { let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?; Ok(ConsensusChainSpec::from_genesis( @@ -326,6 +322,7 @@ pub fn local_config() -> Result Result Result, @@ -384,11 +380,19 @@ fn subspace_genesis_config( enable_rewards, enable_storage_access, allow_authoring_by, - enable_executor, + enable_domains, enable_transfer, confirmation_depth_k, } = genesis_params; + let raw_domain_genesis_config = { + let mut domain_genesis_config = evm_chain_spec::get_testnet_genesis_by_spec_id(spec_id); + // Clear the WASM code of the genesis config since it is duplicated with `GenesisDomain::code` + domain_genesis_config.system.code = Default::default(); + serde_json::to_vec(&domain_genesis_config) + .expect("Genesis config serialization never fails; qed") + }; + GenesisConfig { system: SystemConfig { // Add Wasm runtime to storage. @@ -398,7 +402,7 @@ fn subspace_genesis_config( transaction_payment: Default::default(), sudo: SudoConfig { // Assign network admin rights. - key: Some(sudo_account), + key: Some(sudo_account.clone()), }, subspace: SubspaceConfig { enable_rewards, @@ -407,9 +411,33 @@ fn subspace_genesis_config( }, vesting: VestingConfig { vesting }, runtime_configs: RuntimeConfigsConfig { - enable_executor, + enable_domains, enable_transfer, confirmation_depth_k, }, + domains: DomainsConfig { + genesis_domain: Some(sp_domains::GenesisDomain { + runtime_name: b"evm".to_vec(), + runtime_type: RuntimeType::Evm, + runtime_version: evm_domain_runtime::VERSION, + code: evm_domain_runtime::WASM_BINARY + .unwrap_or_else(|| panic!("EVM domain runtime not available")) + .to_owned(), + + // Domain config, mainly for placeholder the concrete value TBD + owner_account_id: sudo_account, + domain_name: b"evm-domain".to_vec(), + max_block_size: MaxDomainBlockSize::get(), + max_block_weight: MaxDomainBlockWeight::get(), + bundle_slot_probability: (1, 1), + target_bundles_per_block: 10, + raw_genesis_config: raw_domain_genesis_config, + + // TODO: Configurable genesis operator signing key. + signing_key: get_public_key_from_seed::("Alice"), + nomination_tax: Percent::from_percent(5), + minimum_nominator_stake: 100 * SSC, + }), + }, } } diff --git a/crates/subspace-node/src/core_domain.rs b/crates/subspace-node/src/core_domain.rs deleted file mode 100644 index 01f2e780ad4..00000000000 --- a/crates/subspace-node/src/core_domain.rs +++ /dev/null @@ -1,15 +0,0 @@ -pub(crate) mod core_evm_chain_spec; - -use core_evm_runtime::AccountId as AccountId20; -use sp_core::crypto::AccountId32; -use sp_core::{ByteArray, H160}; -use sp_runtime::traits::Convert; - -pub struct AccountId32ToAccountId20Converter; - -impl Convert for AccountId32ToAccountId20Converter { - fn convert(acc: AccountId32) -> AccountId20 { - // Using the full hex key, truncating to the first 20 bytes (the first 40 hex chars) - H160::from_slice(&acc.as_slice()[0..20]).into() - } -} diff --git a/crates/subspace-node/src/domain.rs b/crates/subspace-node/src/domain.rs new file mode 100644 index 00000000000..90dbc05be29 --- /dev/null +++ b/crates/subspace-node/src/domain.rs @@ -0,0 +1,139 @@ +// Copyright (C) 2023 Subspace Labs, Inc. +// SPDX-License-Identifier: GPL-3.0-or-later + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pub(crate) mod cli; +pub(crate) mod domain_instance_starter; +pub(crate) mod evm_chain_spec; + +pub use self::cli::{DomainCli, Subcommand as DomainSubcommand}; +pub use self::domain_instance_starter::DomainInstanceStarter; +use evm_domain_runtime::AccountId as AccountId20; +use sc_client_api::Backend; +use sc_executor::{NativeExecutionDispatch, RuntimeVersionOf}; +use sc_service::{BuildGenesisBlock, GenesisBlockBuilder}; +use sp_core::crypto::AccountId32; +use sp_core::{ByteArray, H160, H256}; +use sp_domains::{DomainId, DomainInstanceData, RuntimeType}; +use sp_runtime::traits::{Block as BlockT, Convert, Header as HeaderT}; +use std::marker::PhantomData; +use std::sync::Arc; + +pub struct AccountId32ToAccountId20Converter; + +impl Convert for AccountId32ToAccountId20Converter { + fn convert(acc: AccountId32) -> AccountId20 { + // Using the full hex key, truncating to the first 20 bytes (the first 40 hex chars) + H160::from_slice(&acc.as_slice()[0..20]).into() + } +} + +/// EVM domain executor instance. +pub struct EVMDomainExecutorDispatch; + +impl NativeExecutionDispatch for EVMDomainExecutorDispatch { + #[cfg(feature = "runtime-benchmarks")] + type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; + #[cfg(not(feature = "runtime-benchmarks"))] + type ExtendHostFunctions = (); + + fn dispatch(method: &str, data: &[u8]) -> Option> { + evm_domain_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + evm_domain_runtime::native_version() + } +} + +/// [`DomainGenesisBlockBuilder`] is used on the consensus node for building the +/// domain genesis block from a specific serialized domain runtime genesis config. +pub struct DomainGenesisBlockBuilder { + backend: Arc, + executor: E, + _phantom: PhantomData, +} + +impl DomainGenesisBlockBuilder +where + Block: BlockT, + B: Backend, + E: RuntimeVersionOf + Clone, +{ + /// Constructs a new instance of [`DomainGenesisBlockBuilder`]. + pub fn new(backend: Arc, executor: E) -> Self { + Self { + backend, + executor, + _phantom: Default::default(), + } + } + + /// Constructs the genesis domain block from a serialized runtime genesis config. + pub fn generate_genesis_block( + &self, + domain_id: DomainId, + domain_instance_data: DomainInstanceData, + ) -> sp_blockchain::Result { + let DomainInstanceData { + runtime_type, + runtime_code, + raw_genesis_config, + } = domain_instance_data; + let domain_genesis_block_builder = match runtime_type { + RuntimeType::Evm => { + let mut runtime_cfg = match raw_genesis_config { + Some(raw_genesis_config) => serde_json::from_slice(&raw_genesis_config) + .map_err(|_| { + sp_blockchain::Error::Application(Box::from( + "Failed to deserialize genesis config of the evm domain", + )) + })?, + None => evm_domain_runtime::RuntimeGenesisConfig::default(), + }; + runtime_cfg.system.code = runtime_code; + runtime_cfg.self_domain_id.domain_id = Some(domain_id); + GenesisBlockBuilder::new( + &runtime_cfg, + false, + self.backend.clone(), + self.executor.clone(), + )? + } + }; + domain_genesis_block_builder + .build_genesis_block() + .map(|(genesis_block, _)| genesis_block) + } +} + +impl sp_domains::GenerateGenesisStateRoot for DomainGenesisBlockBuilder +where + Block: BlockT, + Block::Hash: Into, + B: Backend, + E: RuntimeVersionOf + Clone + Send + Sync, +{ + fn generate_genesis_state_root( + &self, + domain_id: DomainId, + domain_instance_data: DomainInstanceData, + ) -> Option { + self.generate_genesis_block(domain_id, domain_instance_data) + .map(|genesis_block| *genesis_block.header().state_root()) + .ok() + .map(Into::into) + } +} diff --git a/crates/subspace-node/src/system_domain/cli.rs b/crates/subspace-node/src/domain/cli.rs similarity index 53% rename from crates/subspace-node/src/system_domain/cli.rs rename to crates/subspace-node/src/domain/cli.rs index b0a21459d8b..1cfd02800ce 100644 --- a/crates/subspace-node/src/system_domain/cli.rs +++ b/crates/subspace-node/src/domain/cli.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use crate::domain::evm_chain_spec; use clap::Parser; -use domain_runtime_primitives::AccountId; use domain_service::DomainConfiguration; use sc_cli::{ ChainSpec, CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, @@ -23,12 +23,13 @@ use sc_cli::{ }; use sc_service::config::PrometheusConfig; use sc_service::BasePath; -use sc_subspace_chain_specs::ExecutionChainSpec; -use serde_json::Value; -use sp_core::crypto::Ss58Codec; +use sp_core::crypto::AccountId32; +use sp_domains::DomainId; +use sp_runtime::traits::Convert; use std::net::SocketAddr; +use std::num::ParseIntError; use std::path::PathBuf; -use system_domain_runtime::GenesisConfig as SystemDomainGenesisConfig; +use std::str::FromStr; /// Sub-commands supported by the executor. #[derive(Debug, clap::Subcommand)] @@ -45,60 +46,96 @@ pub enum Subcommand { Benchmark(frame_benchmarking_cli::BenchmarkCmd), } +fn parse_domain_id(s: &str) -> std::result::Result { + s.parse::().map(Into::into) +} + #[derive(Debug, Parser)] pub struct DomainCli { - /// Run a node. + /// Run a domain node. #[clap(flatten)] - pub run_system: SubstrateRunCmd, + pub run: SubstrateRunCmd, + + #[clap(long, value_parser = parse_domain_id)] + pub domain_id: DomainId, /// Optional relayer address to relay messages on behalf. #[clap(long)] pub relayer_id: Option, -} - -pub struct SystemDomainCli { - /// Run a node. - pub run: DomainCli, - - /// The base path that should be used by the system domain. - pub base_path: Option, - /// Specification of the system domain derived from primary chain spec. - pub chain_spec: ExecutionChainSpec, + /// Additional args for domain. + #[clap(raw = true)] + additional_args: Vec, } -impl SystemDomainCli { - /// Constructs a new instance of [`SystemDomainCli`]. - /// - /// If no explicit base path for the system domain, the default value will be `base_path/system`. +impl DomainCli { + /// Constructs a new instance of [`DomainCli`]. pub fn new( - mut base_path: Option, - chain_spec: ExecutionChainSpec, + consensus_base_path: Option, domain_args: impl Iterator, ) -> Self { - let domain_cli = + let mut cli = DomainCli::parse_from([Self::executable_name()].into_iter().chain(domain_args)); - Self { - base_path: base_path.as_mut().map(|path| path.join("system")), - chain_spec, - run: domain_cli, + // Use `consensus_base_path/domain-{domain_id}` as the domain base path if it's not + // specified explicitly but there is an explicit consensus base path. + match consensus_base_path { + Some(c_path) if cli.run.shared_params.base_path.is_none() => { + cli.run + .shared_params + .base_path + .replace(c_path.join(format!("domain-{}", u32::from(cli.domain_id)))); + } + _ => {} } + + cli + } + + pub fn additional_args(&self) -> impl Iterator { + [Self::executable_name()] + .into_iter() + .chain(self.additional_args.clone()) + } + + pub fn maybe_relayer_id(&self) -> sc_cli::Result> + where + CA: Convert, + AccountId: FromStr, + { + // if is dev, use the known key ring to start relayer + let res = if self.shared_params().is_dev() && self.relayer_id.is_none() { + self.run + .get_keyring() + .map(|kr| CA::convert(kr.to_account_id())) + } else if let Some(relayer_id) = self.relayer_id.clone() { + Some(AccountId::from_str(&relayer_id).map_err(|_err| { + sc_cli::Error::Input(format!("Invalid Relayer Id: {relayer_id}")) + })?) + } else { + None + }; + Ok(res) } - /// Creates domain configuration from system domain cli. - pub fn create_domain_configuration( + /// Creates domain configuration from domain cli. + pub fn create_domain_configuration( &self, tokio_handle: tokio::runtime::Handle, - ) -> sc_cli::Result> { + ) -> sc_cli::Result> + where + CA: Convert, + AccountId: FromStr, + { // if is dev, use the known key ring to start relayer - let maybe_relayer_id = if self.shared_params().is_dev() && self.run.relayer_id.is_none() { + let maybe_relayer_id = if self.shared_params().is_dev() && self.relayer_id.is_none() { self.run - .run_system .get_keyring() - .map(|kr| kr.to_account_id()) - } else if let Some(relayer_id) = self.run.relayer_id.clone() { - Some(AccountId::from_ss58check(&relayer_id).map_err(sc_cli::Error::InvalidUri)?) + .map(|kr| CA::convert(kr.to_account_id())) + } else if let Some(relayer_id) = self.relayer_id.clone() { + Some(AccountId::from_str(&relayer_id).map_err(|_err| { + sc_cli::Error::Input(format!("Invalid Relayer Id: {relayer_id}")) + })?) } else { None }; @@ -111,9 +148,9 @@ impl SystemDomainCli { } } -impl SubstrateCli for SystemDomainCli { +impl SubstrateCli for DomainCli { fn impl_name() -> String { - "Subspace Executor".into() + "Subspace Domain".into() } fn impl_version() -> String { @@ -127,7 +164,7 @@ impl SubstrateCli for SystemDomainCli { } fn description() -> String { - "Subspace Executor".into() + "Subspace Domain".into() } fn author() -> String { @@ -142,35 +179,26 @@ impl SubstrateCli for SystemDomainCli { 2022 } - fn load_spec(&self, _id: &str) -> std::result::Result, String> { - let mut chain_spec = self.chain_spec.clone(); - - // In case there are bootstrap nodes specified explicitly, ignore those that are in the - // chain spec - if !self.run.run_system.network_params.bootnodes.is_empty() { - let mut chain_spec_value: Value = serde_json::from_str(&chain_spec.as_json(true)?) - .map_err(|error| error.to_string())?; - if let Some(boot_nodes) = chain_spec_value.get_mut("bootNodes") { - if let Some(boot_nodes) = boot_nodes.as_array_mut() { - boot_nodes.clear(); - } - } - // Such mess because native serialization of the chain spec serializes it twice, see - // docs on `sc_subspace_chain_specs::utils::SerializableChainSpec`. - chain_spec = serde_json::to_string(&chain_spec_value.to_string()) - .and_then(|chain_spec_string| serde_json::from_str(&chain_spec_string)) - .map_err(|error| error.to_string())?; + fn load_spec(&self, id: &str) -> std::result::Result, String> { + // TODO: Fetch the runtime name of `self.domain_id` properly. + let runtime_name = "evm"; + match runtime_name { + "evm" => evm_chain_spec::load_chain_spec(id), + unknown_name => Err(format!("Unknown runtime: {unknown_name}")), } - - Ok(Box::new(chain_spec)) } fn native_runtime_version(_chain_spec: &Box) -> &'static RuntimeVersion { - &system_domain_runtime::VERSION + // TODO: Fetch the runtime name of `self.domain_id` properly. + let runtime_name = "evm"; + match runtime_name { + "evm" => &evm_domain_runtime::VERSION, + unknown_name => unreachable!("Unknown runtime: {unknown_name}"), + } } } -impl DefaultConfigurationValues for SystemDomainCli { +impl DefaultConfigurationValues for DomainCli { fn p2p_listen_port() -> u16 { 30334 } @@ -184,37 +212,29 @@ impl DefaultConfigurationValues for SystemDomainCli { } } -impl CliConfiguration for SystemDomainCli { +impl CliConfiguration for DomainCli { fn shared_params(&self) -> &SharedParams { - self.run.run_system.shared_params() + self.run.shared_params() } fn import_params(&self) -> Option<&ImportParams> { - self.run.run_system.import_params() + self.run.import_params() } fn network_params(&self) -> Option<&NetworkParams> { - self.run.run_system.network_params() + self.run.network_params() } fn keystore_params(&self) -> Option<&KeystoreParams> { - self.run.run_system.keystore_params() + self.run.keystore_params() } fn base_path(&self) -> Result> { - Ok(self - .shared_params() - .base_path()? - .as_mut() - .map(|base_path| { - let path: PathBuf = base_path.path().to_path_buf(); - BasePath::new(path.join("system")) - }) - .or_else(|| self.base_path.clone().map(Into::into))) + self.shared_params().base_path() } fn rpc_addr(&self, default_listen_port: u16) -> Result> { - self.run.run_system.rpc_addr(default_listen_port) + self.run.rpc_addr(default_listen_port) } fn prometheus_config( @@ -222,67 +242,65 @@ impl CliConfiguration for SystemDomainCli { default_listen_port: u16, chain_spec: &Box, ) -> Result> { - self.run - .run_system - .prometheus_config(default_listen_port, chain_spec) + self.run.prometheus_config(default_listen_port, chain_spec) } fn chain_id(&self, is_dev: bool) -> Result { - self.run.run_system.chain_id(is_dev) + self.run.chain_id(is_dev) } fn role(&self, is_dev: bool) -> Result { - self.run.run_system.role(is_dev) + self.run.role(is_dev) } fn transaction_pool(&self, is_dev: bool) -> Result { - self.run.run_system.transaction_pool(is_dev) + self.run.transaction_pool(is_dev) } fn trie_cache_maximum_size(&self) -> Result> { - self.run.run_system.trie_cache_maximum_size() + self.run.trie_cache_maximum_size() } fn rpc_methods(&self) -> Result { - self.run.run_system.rpc_methods() + self.run.rpc_methods() } fn rpc_max_connections(&self) -> Result { - self.run.run_system.rpc_max_connections() + self.run.rpc_max_connections() } fn rpc_cors(&self, is_dev: bool) -> Result>> { - self.run.run_system.rpc_cors(is_dev) + self.run.rpc_cors(is_dev) } fn default_heap_pages(&self) -> Result> { - self.run.run_system.default_heap_pages() + self.run.default_heap_pages() } fn force_authoring(&self) -> Result { - self.run.run_system.force_authoring() + self.run.force_authoring() } fn disable_grandpa(&self) -> Result { - self.run.run_system.disable_grandpa() + self.run.disable_grandpa() } fn max_runtime_instances(&self) -> Result> { - self.run.run_system.max_runtime_instances() + self.run.max_runtime_instances() } fn announce_block(&self) -> Result { - self.run.run_system.announce_block() + self.run.announce_block() } fn dev_key_seed(&self, is_dev: bool) -> Result> { - self.run.run_system.dev_key_seed(is_dev) + self.run.dev_key_seed(is_dev) } fn telemetry_endpoints( &self, chain_spec: &Box, ) -> Result> { - self.run.run_system.telemetry_endpoints(chain_spec) + self.run.telemetry_endpoints(chain_spec) } } diff --git a/crates/subspace-node/src/domain/domain_instance_starter.rs b/crates/subspace-node/src/domain/domain_instance_starter.rs new file mode 100644 index 00000000000..95dfad5c602 --- /dev/null +++ b/crates/subspace-node/src/domain/domain_instance_starter.rs @@ -0,0 +1,285 @@ +use super::{evm_chain_spec, DomainCli}; +use crate::domain::{AccountId20, AccountId32ToAccountId20Converter, EVMDomainExecutorDispatch}; +use crate::ExecutorDispatch as CExecutorDispatch; +use cross_domain_message_gossip::GossipWorkerBuilder; +use domain_client_operator::{BootstrapResult, OperatorStreams}; +use domain_eth_service::provider::EthProvider; +use domain_eth_service::DefaultEthConfig; +use domain_runtime_primitives::opaque::Block as DomainBlock; +use domain_service::{DomainConfiguration, FullBackend, FullClient}; +use futures::StreamExt; +use sc_chain_spec::ChainSpec; +use sc_cli::{CliConfiguration, Database, DefaultConfigurationValues, SubstrateCli}; +use sc_consensus_subspace::notification::SubspaceNotificationStream; +use sc_consensus_subspace::{BlockImportingNotification, NewSlotNotification}; +use sc_service::{BasePath, Configuration}; +use sp_core::traits::SpawnEssentialNamed; +use sp_domains::RuntimeType; +use sp_runtime::traits::Block as BlockT; +use std::sync::Arc; +use subspace_runtime::RuntimeApi as CRuntimeApi; +use subspace_runtime_primitives::opaque::Block as CBlock; +use subspace_service::{FullClient as CFullClient, FullSelectChain}; + +/// `DomainInstanceStarter` used to start a domain instance node based on the given +/// bootstrap result +pub struct DomainInstanceStarter { + pub domain_cli: DomainCli, + pub tokio_handle: tokio::runtime::Handle, + pub consensus_client: Arc>, + pub block_importing_notification_stream: + SubspaceNotificationStream>, + pub new_slot_notification_stream: SubspaceNotificationStream, + pub consensus_network_service: + Arc::Hash>>, + pub consensus_sync_service: Arc>, + pub select_chain: FullSelectChain, +} + +impl DomainInstanceStarter { + pub async fn start( + self, + bootstrap_result: BootstrapResult, + ) -> std::result::Result<(), Box> { + let BootstrapResult { + domain_instance_data, + domain_created_at, + imported_block_notification_stream, + } = bootstrap_result; + + let DomainInstanceStarter { + domain_cli, + tokio_handle, + consensus_client, + block_importing_notification_stream, + new_slot_notification_stream, + consensus_network_service, + consensus_sync_service, + select_chain, + } = self; + + let runtime_type = domain_instance_data.runtime_type.clone(); + let domain_id = domain_cli.domain_id; + let domain_config = { + let chain_id = domain_cli.chain_id(domain_cli.is_dev()?)?; + + let domain_spec = evm_chain_spec::create_domain_spec( + domain_id, + chain_id.as_str(), + domain_instance_data, + )?; + + let service_config = create_configuration::<_, DomainCli, DomainCli>( + &domain_cli, + domain_spec, + tokio_handle, + )?; + + let maybe_relayer_id = + domain_cli.maybe_relayer_id::<_, AccountId32ToAccountId20Converter>()?; + + DomainConfiguration { + service_config, + maybe_relayer_id, + } + }; + + let block_importing_notification_stream = || { + block_importing_notification_stream.subscribe().then( + |block_importing_notification| async move { + ( + block_importing_notification.block_number, + block_importing_notification.acknowledgement_sender, + ) + }, + ) + }; + + let new_slot_notification_stream = || { + new_slot_notification_stream + .subscribe() + .then(|slot_notification| async move { + ( + slot_notification.new_slot_info.slot, + slot_notification.new_slot_info.global_randomness, + None::>, + ) + }) + }; + + let operator_streams = OperatorStreams { + // TODO: proper value + consensus_block_import_throttling_buffer_size: 10, + block_importing_notification_stream: block_importing_notification_stream(), + imported_block_notification_stream, + new_slot_notification_stream: new_slot_notification_stream(), + _phantom: Default::default(), + }; + + match runtime_type { + RuntimeType::Evm => { + let mut xdm_gossip_worker_builder = GossipWorkerBuilder::new(); + + let evm_base_path = BasePath::new( + domain_config + .service_config + .base_path + .config_dir(domain_config.service_config.chain_spec.id()), + ); + + let eth_provider = + EthProvider::< + evm_domain_runtime::TransactionConverter, + DefaultEthConfig< + FullClient< + DomainBlock, + evm_domain_runtime::RuntimeApi, + EVMDomainExecutorDispatch, + >, + FullBackend, + >, + >::new(Some(evm_base_path), domain_cli.additional_args()); + + let domain_params = domain_service::DomainParams { + domain_id, + domain_config, + domain_created_at, + consensus_client, + consensus_network_sync_oracle: consensus_sync_service.clone(), + select_chain, + operator_streams, + gossip_message_sink: xdm_gossip_worker_builder.gossip_msg_sink(), + provider: eth_provider, + }; + + let mut domain_node = domain_service::new_full::< + _, + _, + _, + _, + _, + _, + evm_domain_runtime::RuntimeApi, + EVMDomainExecutorDispatch, + AccountId20, + _, + >(domain_params) + .await?; + + xdm_gossip_worker_builder + .push_domain_tx_pool_sink(domain_cli.domain_id, domain_node.tx_pool_sink); + + let cross_domain_message_gossip_worker = xdm_gossip_worker_builder + .build::(consensus_network_service, consensus_sync_service); + + domain_node + .task_manager + .spawn_essential_handle() + .spawn_essential_blocking( + "cross-domain-gossip-message-worker", + None, + Box::pin(cross_domain_message_gossip_worker.run()), + ); + + domain_node.network_starter.start_network(); + + domain_node.task_manager.future().await?; + + Ok(()) + } + } + } +} + +/// Default sub directory to store network config. +pub(crate) const DEFAULT_NETWORK_CONFIG_PATH: &str = "network"; + +/// Create a Configuration object from the current object, port from `sc_cli::create_configuration` +/// and changed to take `chain_spec` as argument instead of construct one internally. +fn create_configuration< + DCV: DefaultConfigurationValues, + CC: CliConfiguration, + Cli: SubstrateCli, +>( + cli_config: &CC, + chain_spec: Box, + tokio_handle: tokio::runtime::Handle, +) -> sc_cli::Result { + let is_dev = cli_config.is_dev()?; + let base_path = cli_config + .base_path()? + .unwrap_or_else(|| BasePath::from_project("", "", &Cli::executable_name())); + let config_dir = base_path.config_dir(chain_spec.id()); + let net_config_dir = config_dir.join(DEFAULT_NETWORK_CONFIG_PATH); + let client_id = Cli::client_id(); + let database_cache_size = cli_config.database_cache_size()?.unwrap_or(1024); + let database = cli_config.database()?.unwrap_or( + #[cfg(feature = "rocksdb")] + { + Database::RocksDb + }, + #[cfg(not(feature = "rocksdb"))] + { + Database::ParityDb + }, + ); + let node_key = cli_config.node_key(&net_config_dir)?; + let role = cli_config.role(is_dev)?; + let max_runtime_instances = cli_config.max_runtime_instances()?.unwrap_or(8); + let is_validator = role.is_authority(); + let keystore = cli_config.keystore_config(&config_dir)?; + let telemetry_endpoints = cli_config.telemetry_endpoints(&chain_spec)?; + let runtime_cache_size = cli_config.runtime_cache_size()?; + + Ok(Configuration { + impl_name: Cli::impl_name(), + impl_version: Cli::impl_version(), + tokio_handle, + transaction_pool: cli_config.transaction_pool(is_dev)?, + network: cli_config.network_config( + &chain_spec, + is_dev, + is_validator, + net_config_dir, + client_id.as_str(), + cli_config.node_name()?.as_str(), + node_key, + DCV::p2p_listen_port(), + )?, + keystore, + database: cli_config.database_config(&config_dir, database_cache_size, database)?, + data_path: config_dir, + trie_cache_maximum_size: cli_config.trie_cache_maximum_size()?, + state_pruning: cli_config.state_pruning()?, + blocks_pruning: cli_config.blocks_pruning()?, + wasm_method: cli_config.wasm_method()?, + wasm_runtime_overrides: cli_config.wasm_runtime_overrides(), + execution_strategies: cli_config.execution_strategies(is_dev, is_validator)?, + rpc_addr: cli_config.rpc_addr(DCV::rpc_listen_port())?, + rpc_methods: cli_config.rpc_methods()?, + rpc_max_connections: cli_config.rpc_max_connections()?, + rpc_cors: cli_config.rpc_cors(is_dev)?, + rpc_max_request_size: cli_config.rpc_max_request_size()?, + rpc_max_response_size: cli_config.rpc_max_response_size()?, + rpc_id_provider: None, + rpc_max_subs_per_conn: cli_config.rpc_max_subscriptions_per_connection()?, + rpc_port: DCV::rpc_listen_port(), + prometheus_config: cli_config + .prometheus_config(DCV::prometheus_listen_port(), &chain_spec)?, + telemetry_endpoints, + default_heap_pages: cli_config.default_heap_pages()?, + offchain_worker: cli_config.offchain_worker(&role)?, + force_authoring: cli_config.force_authoring()?, + disable_grandpa: cli_config.disable_grandpa()?, + dev_key_seed: cli_config.dev_key_seed(is_dev)?, + tracing_targets: cli_config.tracing_targets()?, + tracing_receiver: cli_config.tracing_receiver()?, + chain_spec, + max_runtime_instances, + announce_block: cli_config.announce_block()?, + role, + base_path, + informant_output_format: Default::default(), + runtime_cache_size, + }) +} diff --git a/crates/subspace-node/src/core_domain/core_evm_chain_spec.rs b/crates/subspace-node/src/domain/evm_chain_spec.rs similarity index 60% rename from crates/subspace-node/src/core_domain/core_evm_chain_spec.rs rename to crates/subspace-node/src/domain/evm_chain_spec.rs index 0a233287dba..e0247711c3d 100644 --- a/crates/subspace-node/src/core_domain/core_evm_chain_spec.rs +++ b/crates/subspace-node/src/domain/evm_chain_spec.rs @@ -14,21 +14,20 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -//! Core EVM domain configurations. - -// TODO: support running core-evm again after the cleanup. -#![allow(dead_code)] +//! EVM domain configurations. use crate::chain_spec_utils::chain_spec_properties; -use crate::AccountId32ToAccountId20Converter; -use core_evm_runtime::{ +use crate::domain::AccountId32ToAccountId20Converter; +use evm_domain_runtime::{ AccountId, BalancesConfig, EVMChainIdConfig, EVMConfig, GenesisConfig, MessengerConfig, - Precompiles, SudoConfig, SystemConfig, WASM_BINARY, + Precompiles, SelfDomainIdConfig, SudoConfig, SystemConfig, WASM_BINARY, }; use hex_literal::hex; +use once_cell::sync::OnceCell; use sc_service::ChainType; use sc_subspace_chain_specs::ExecutionChainSpec; use sp_core::{sr25519, Pair, Public}; +use sp_domains::{DomainId, DomainInstanceData, RuntimeType}; use sp_runtime::traits::Convert; use std::str::FromStr; use subspace_runtime_primitives::SSC; @@ -56,28 +55,16 @@ fn get_dev_accounts() -> Vec { ] } -pub fn development_config() -> ExecutionChainSpec { - let accounts = get_dev_accounts(); +pub fn development_config GenesisConfig + 'static + Send + Sync>( + constructor: F, +) -> ExecutionChainSpec { ExecutionChainSpec::from_genesis( // Name "Development", // ID - "core_evm_domain_dev", + "evm_domain_dev", ChainType::Development, - move || { - testnet_genesis( - accounts.clone(), - // Alith is Sudo - Some(accounts[0]), - vec![( - accounts[0], - AccountId32ToAccountId20Converter::convert( - get_from_seed::("Alice").into(), - ), - )], - 1000, - ) - }, + constructor, vec![], None, None, @@ -87,29 +74,22 @@ pub fn development_config() -> ExecutionChainSpec { ) } -pub fn local_testnet_config() -> ExecutionChainSpec { - let accounts = get_dev_accounts(); +pub fn local_testnet_config GenesisConfig + 'static + Send + Sync>( + constructor: F, +) -> ExecutionChainSpec { ExecutionChainSpec::from_genesis( // Name "Local Testnet", // ID - "core_evm_domain_local_testnet", + "evm_domain_local_testnet", ChainType::Local, - move || { - testnet_genesis( - accounts.clone(), - // Alith is sudo - Some(accounts[0]), - vec![(accounts[0], accounts[0]), (accounts[1], accounts[1])], - 1001, - ) - }, + constructor, // Bootnodes vec![], // Telemetry None, // Protocol ID - Some("core-evm-local"), + Some("evm-local"), None, // Properties Some(chain_spec_properties()), @@ -118,35 +98,22 @@ pub fn local_testnet_config() -> ExecutionChainSpec { ) } -pub fn gemini_3d_config() -> ExecutionChainSpec { +pub fn gemini_3e_config GenesisConfig + 'static + Send + Sync>( + constructor: F, +) -> ExecutionChainSpec { ExecutionChainSpec::from_genesis( // Name - "Subspace Gemini 3d Core EVM Domain", + "Subspace Gemini 3e EVM Domain", // ID - "subspace_gemini_3d_core_evm_domain", + "subspace_gemini_3e_evm_domain", ChainType::Live, - move || { - let sudo_account = AccountId::from_str("f31e60022e290708c17d6997c34de6a30d09438f") - .expect("Invalid Sudo account"); - testnet_genesis( - vec![ - // Genesis executor - AccountId::from_str("2ac6c70c106138c8cd80da6b6a0e886b7eeee249") - .expect("Wrong executor account address"), - // Sudo account - sudo_account, - ], - Some(sudo_account), - Default::default(), - 1002, - ) - }, + constructor, // Bootnodes vec![], // Telemetry None, // Protocol ID - Some("subspace-gemini-3d-core-evm-domain"), + Some("subspace-gemini-3e-evm-domain"), None, // Properties Some(chain_spec_properties()), @@ -155,19 +122,87 @@ pub fn gemini_3d_config() -> ExecutionChainSpec { ) } -pub fn devnet_config() -> ExecutionChainSpec { +pub fn devnet_config GenesisConfig + 'static + Send + Sync>( + constructor: F, +) -> ExecutionChainSpec { ExecutionChainSpec::from_genesis( // Name - "Subspace Devnet Core EVM Domain", + "Subspace Devnet EVM Domain", // ID - "subspace_devnet_core_evm_domain", + "subspace_devnet_evm_domain", ChainType::Custom("Testnet".to_string()), - move || { + constructor, + // Bootnodes + vec![], + // Telemetry + None, + // Protocol ID + Some("subspace-devnet-evm-domain"), + None, + // Properties + Some(chain_spec_properties()), + // Extensions + None, + ) +} + +pub fn load_chain_spec(spec_id: &str) -> Result, String> { + let chain_spec = match spec_id { + "dev" => development_config(move || get_testnet_genesis_by_spec_id(SpecId::Dev)), + "gemini-3e" => gemini_3e_config(move || get_testnet_genesis_by_spec_id(SpecId::Gemini)), + "devnet" => devnet_config(move || get_testnet_genesis_by_spec_id(SpecId::DevNet)), + "" | "local" => local_testnet_config(move || get_testnet_genesis_by_spec_id(SpecId::Local)), + path => ChainSpec::from_json_file(std::path::PathBuf::from(path))?, + }; + Ok(Box::new(chain_spec)) +} + +pub enum SpecId { + Dev, + Gemini, + DevNet, + Local, +} + +pub fn get_testnet_genesis_by_spec_id(spec_id: SpecId) -> GenesisConfig { + match spec_id { + SpecId::Dev => { + let accounts = get_dev_accounts(); + testnet_genesis( + accounts.clone(), + // Alith is Sudo + Some(accounts[0]), + vec![( + accounts[0], + AccountId32ToAccountId20Converter::convert( + get_from_seed::("Alice").into(), + ), + )], + 1000, + ) + } + SpecId::Gemini => { + let sudo_account = AccountId::from_str("f31e60022e290708c17d6997c34de6a30d09438f") + .expect("Invalid Sudo account"); + testnet_genesis( + vec![ + // Genesis operator + AccountId::from_str("2ac6c70c106138c8cd80da6b6a0e886b7eeee249") + .expect("Wrong executor account address"), + // Sudo account + sudo_account, + ], + Some(sudo_account), + Default::default(), + 1002, + ) + } + SpecId::DevNet => { let sudo_account = AccountId::from_str("b66a91845249464309fad766fd0ece8144547736") .expect("Invalid Sudo account"); testnet_genesis( vec![ - // Genesis executor + // Genesis operator AccountId::from_str("cfdf9f58d9e532c3807ce62a5489cb19cfa6942d") .expect("Wrong executor account address"), // Sudo account @@ -181,32 +216,82 @@ pub fn devnet_config() -> ExecutionChainSpec { )], 1003, ) - }, - // Bootnodes - vec![], - // Telemetry - None, - // Protocol ID - Some("subspace-devnet-core-evm-domain"), - None, - // Properties - Some(chain_spec_properties()), - // Extensions - None, - ) + } + SpecId::Local => { + let accounts = get_dev_accounts(); + testnet_genesis( + accounts.clone(), + // Alith is sudo + Some(accounts[0]), + vec![(accounts[0], accounts[0]), (accounts[1], accounts[1])], + 1001, + ) + } + } } -pub fn load_chain_spec(spec_id: &str) -> std::result::Result, String> { +// HACK: `ChainSpec::from_genesis` is only allow to create hardcoded spec and `GenesisConfig` +// dosen't derive `Clone`, using global variable and serialization/deserialization to workaround +// these limits. +static GENESIS_CONFIG: OnceCell> = OnceCell::new(); + +// Load chain spec that contains the given `GenesisConfig` +fn load_chain_spec_with( + spec_id: &str, + genesis_config: GenesisConfig, +) -> Result, String> { + GENESIS_CONFIG + .set( + serde_json::to_vec(&genesis_config) + .expect("Genesis config serialization never fails; qed"), + ) + .expect("This function should only call once upon node initialization"); + let constructor = || { + let raw_genesis_config = GENESIS_CONFIG.get().expect("Value just set; qed"); + serde_json::from_slice(raw_genesis_config) + .expect("Genesis config deserialization never fails; qed") + }; + let chain_spec = match spec_id { - "dev" => development_config(), - "gemini-3d" => gemini_3d_config(), - "devnet" => devnet_config(), - "" | "local" => local_testnet_config(), + "dev" => development_config(constructor), + "gemini-3e" => gemini_3e_config(constructor), + "devnet" => devnet_config(constructor), + "" | "local" => local_testnet_config(constructor), path => ChainSpec::from_json_file(std::path::PathBuf::from(path))?, }; + Ok(Box::new(chain_spec)) } +pub fn create_domain_spec( + domain_id: DomainId, + chain_id: &str, + domain_instance_data: DomainInstanceData, +) -> Result, String> { + let DomainInstanceData { + runtime_type, + runtime_code, + raw_genesis_config, + } = domain_instance_data; + + match runtime_type { + RuntimeType::Evm => { + let mut genesis_config = match raw_genesis_config { + Some(raw_genesis_config) => { + serde_json::from_slice(&raw_genesis_config).map_err(|_| { + "Failed to deserialize genesis config of the evm domain".to_string() + })? + } + None => GenesisConfig::default(), + }; + genesis_config.system.code = runtime_code; + genesis_config.self_domain_id.domain_id = Some(domain_id); + let spec = load_chain_spec_with(chain_id, genesis_config)?; + Ok(spec) + } + } +} + fn testnet_genesis( endowed_accounts: Vec, maybe_sudo_account: Option, @@ -258,5 +343,9 @@ fn testnet_genesis( }, ethereum: Default::default(), base_fee: Default::default(), + self_domain_id: SelfDomainIdConfig { + // Id of the genesis domain + domain_id: Some(DomainId::new(0)), + }, } } diff --git a/crates/subspace-node/src/import_blocks_from_dsn.rs b/crates/subspace-node/src/import_blocks_from_dsn.rs deleted file mode 100644 index 276b0cc3f67..00000000000 --- a/crates/subspace-node/src/import_blocks_from_dsn.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) 2021 Subspace Labs, Inc. -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -use clap::Parser; -use log::info; -use sc_cli::{CliConfiguration, ImportParams, SharedParams}; -use sc_client_api::{BlockBackend, HeaderBackend}; -use sp_core::traits::SpawnEssentialNamed; -use sp_runtime::traits::Block as BlockT; -use std::sync::Arc; -use subspace_networking::libp2p::Multiaddr; -use subspace_networking::{BootstrappedNetworkingParameters, Config, PieceByHashRequestHandler}; -use subspace_service::dsn::import_blocks::import_blocks; - -/// The `import-blocks-from-network` command used to import blocks from Subspace Network DSN. -#[derive(Debug, Parser)] -pub struct ImportBlocksFromDsnCmd { - /// Multiaddrs of bootstrap nodes to connect to on startup, multiple are supported - #[arg(long)] - pub bootstrap_node: Vec, - - /// The default number of 64KB pages to ever allocate for Wasm execution. - /// - /// Don't alter this unless you know what you're doing. - #[arg(long, value_name = "COUNT")] - pub default_heap_pages: Option, - - #[allow(missing_docs)] - #[clap(flatten)] - pub shared_params: SharedParams, - - #[allow(missing_docs)] - #[clap(flatten)] - pub import_params: ImportParams, -} - -impl ImportBlocksFromDsnCmd { - /// Run the import-blocks command - pub async fn run( - &self, - client: Arc, - mut import_queue: IQ, - spawner: impl SpawnEssentialNamed, - ) -> sc_cli::Result<()> - where - C: HeaderBackend + BlockBackend + Send + Sync + 'static, - B: BlockT + for<'de> serde::Deserialize<'de>, - IQ: sc_service::ImportQueue + 'static, - { - let (node, mut node_runner) = subspace_networking::create(Config { - networking_parameters_registry: BootstrappedNetworkingParameters::new( - self.bootstrap_node.clone(), - ) - .boxed(), - allow_non_global_addresses_in_dht: true, - request_response_protocols: vec![PieceByHashRequestHandler::create( - move |_, _| async { None }, - )], - ..Config::default() - }) - .map_err(|error| sc_service::Error::Other(error.to_string()))?; - - spawner.spawn_essential( - "node-runner", - Some("subspace-networking"), - Box::pin(async move { - node_runner.run().await; - }), - ); - - let mut imported_blocks = 0; - - // Repeat until no new blocks are imported - loop { - let new_imported_blocks = - import_blocks(&node, Arc::clone(&client), &mut import_queue, false).await?; - - if new_imported_blocks == 0 { - break; - } - - imported_blocks += new_imported_blocks; - - info!( - "🎉 Imported {} blocks, best #{}/#{}", - imported_blocks, - client.info().best_number, - client.info().best_hash - ); - } - - info!( - "🎉 Imported {} blocks, best #{}/#{}, check against reliable sources to make sure it is a \ - block on canonical chain", - imported_blocks, - client.info().best_number, - client.info().best_hash - ); - - Ok(()) - } -} - -impl CliConfiguration for ImportBlocksFromDsnCmd { - fn shared_params(&self) -> &SharedParams { - &self.shared_params - } - - fn import_params(&self) -> Option<&ImportParams> { - Some(&self.import_params) - } -} diff --git a/crates/subspace-node/src/lib.rs b/crates/subspace-node/src/lib.rs index b26d15b6587..2beae5ce788 100644 --- a/crates/subspace-node/src/lib.rs +++ b/crates/subspace-node/src/lib.rs @@ -18,15 +18,11 @@ mod chain_spec; mod chain_spec_utils; -mod core_domain; -mod import_blocks_from_dsn; -mod system_domain; +pub mod domain; -pub use crate::import_blocks_from_dsn::ImportBlocksFromDsnCmd; -pub use crate::system_domain::cli::{Subcommand as SystemDomainSubcommand, SystemDomainCli}; use bytesize::ByteSize; +use clap::builder::EnumValueParser; use clap::Parser; -pub use core_domain::AccountId32ToAccountId20Converter; use sc_cli::{RunCmd, SubstrateCli}; use sc_executor::{NativeExecutionDispatch, RuntimeVersion}; use sc_service::ChainSpec; @@ -47,10 +43,14 @@ impl NativeExecutionDispatch for ExecutorDispatch { type ExtendHostFunctions = ( frame_benchmarking::benchmarking::HostFunctions, sp_consensus_subspace::consensus::HostFunctions, + sp_domains::domain::HostFunctions, ); /// Otherwise we only use the default Substrate host functions. #[cfg(not(feature = "runtime-benchmarks"))] - type ExtendHostFunctions = sp_consensus_subspace::consensus::HostFunctions; + type ExtendHostFunctions = ( + sp_consensus_subspace::consensus::HostFunctions, + sp_domains::domain::HostFunctions, + ); fn dispatch(method: &str, data: &[u8]) -> Option> { subspace_runtime::api::dispatch(method, data) @@ -61,7 +61,7 @@ impl NativeExecutionDispatch for ExecutorDispatch { } } -/// This `purge-chain` command used to remove both consensus chain and system domain. +/// This `purge-chain` command used to remove both consensus chain and domain. #[derive(Debug, Clone, Parser)] #[group(skip)] pub struct PurgeChainCmd { @@ -74,15 +74,15 @@ impl PurgeChainCmd { /// Run the purge command pub fn run( &self, - primary_chain_config: sc_service::Configuration, - system_domain_config: sc_service::Configuration, + consensus_chain_config: sc_service::Configuration, + domain_config: sc_service::Configuration, ) -> sc_cli::Result<()> { let db_paths = vec![ - system_domain_config + domain_config .database .path() .expect("No custom database used here; qed"), - primary_chain_config + consensus_chain_config .database .path() .expect("No custom database used here; qed"), @@ -147,9 +147,6 @@ pub enum Subcommand { /// Import blocks. ImportBlocks(sc_cli::ImportBlocksCmd), - /// Import blocks from Subspace Network DSN. - ImportBlocksFromDsn(ImportBlocksFromDsnCmd), - /// Remove the whole chain. PurgeChain(PurgeChainCmd), @@ -159,15 +156,40 @@ pub enum Subcommand { /// Db meta columns information. ChainInfo(sc_cli::ChainInfoCmd), - /// Run executor sub-commands. + /// Run domain sub-commands. #[clap(subcommand)] - Executor(system_domain::cli::Subcommand), + Domain(domain::cli::Subcommand), /// Sub-commands concerned with benchmarking. #[clap(subcommand)] Benchmark(frame_benchmarking_cli::BenchmarkCmd), } +/// Assigned proof of time role. +#[derive(Debug, Clone, Eq, PartialEq, clap::ValueEnum)] +pub enum CliPotRole { + /// Time keeper role of producing proofs. + TimeKeeper, + + /// Listens to proofs from time keepers. + NodeClient, + + /// Proof of time is disabled. + None, +} + +impl CliPotRole { + /// Checks if PoT is enabled. + pub fn is_pot_enabled(&self) -> bool { + *self == Self::TimeKeeper || *self == Self::NodeClient + } + + /// Checks if PoT role is time keeper. + pub fn is_time_keeper(&self) -> bool { + *self == Self::TimeKeeper + } +} + /// Subspace Cli. #[derive(Debug, Parser)] #[clap( @@ -220,22 +242,26 @@ pub struct Cli { /// Determines whether we allow keeping non-global (private, shared, loopback..) addresses /// in Kademlia DHT for the DSN. #[arg(long, default_value_t = false)] - pub dsn_disable_private_ips: bool, + pub dsn_enable_private_ips: bool, /// Enables DSN-sync on startup. - #[arg(long, default_value_t = false)] + #[arg(long, default_value_t = true, action = clap::ArgAction::Set)] pub sync_from_dsn: bool, + /// Known external addresses + #[arg(long, alias = "dsn-external-address")] + pub dsn_external_addresses: Vec, + /// Piece cache size in human readable format (e.g. 10GB, 2TiB) or just bytes (e.g. 4096). #[arg(long, default_value = "1GiB")] pub piece_cache_size: ByteSize, /// Domain arguments /// - /// The command-line arguments provided first will be passed to the embedded primary node, - /// while the arguments provided after `--` will be passed to the system domain node. + /// The command-line arguments provided first will be passed to the embedded consensus node, + /// while the arguments provided after `--` will be passed to the domain node. /// - /// subspace-node [primarychain-args] -- [system-domain-args] + /// subspace-node [consensus-chain-args] -- [domain-args] #[arg(raw = true)] pub domain_args: Vec, @@ -247,6 +273,10 @@ pub struct Cli { /// instead of the default substrate handler. #[arg(long)] pub enable_subspace_block_relay: bool, + + /// Assigned PoT role for this node. + #[arg(long, default_value="none", value_parser(EnumValueParser::::new()))] + pub pot_role: CliPotRole, } impl SubstrateCli for Cli { @@ -282,8 +312,8 @@ impl SubstrateCli for Cli { fn load_spec(&self, id: &str) -> Result, String> { let mut chain_spec = match id { - "gemini-3d-compiled" => chain_spec::gemini_3d_compiled()?, - "gemini-3d" => chain_spec::gemini_3d_config()?, + "gemini-3e-compiled" => chain_spec::gemini_3e_compiled()?, + "gemini-3e" => chain_spec::gemini_3e_config()?, "devnet" => chain_spec::devnet_config()?, "devnet-compiled" => chain_spec::devnet_config_compiled()?, "dev" => chain_spec::dev_config()?, diff --git a/crates/subspace-node/src/system_domain.rs b/crates/subspace-node/src/system_domain.rs deleted file mode 100644 index d1feaa159d4..00000000000 --- a/crates/subspace-node/src/system_domain.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (C) 2021 Subspace Labs, Inc. -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pub(crate) mod chain_spec; -pub(crate) mod cli; diff --git a/crates/subspace-node/src/system_domain/chain_spec.rs b/crates/subspace-node/src/system_domain/chain_spec.rs deleted file mode 100644 index 9acd3dd82fa..00000000000 --- a/crates/subspace-node/src/system_domain/chain_spec.rs +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (C) 2021 Subspace Labs, Inc. -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -//! System domain configurations. - -use crate::chain_spec_utils::{ - chain_spec_properties, get_account_id_from_seed, get_public_key_from_seed, -}; -use sc_service::ChainType; -use sc_subspace_chain_specs::ExecutionChainSpec; -use sp_core::crypto::Ss58Codec; -use sp_domains::ExecutorPublicKey; -use subspace_runtime_primitives::SSC; -use system_domain_runtime::{ - AccountId, Balance, BalancesConfig, DomainRegistryConfig, ExecutorRegistryConfig, - GenesisConfig, MessengerConfig, SudoConfig, SystemConfig, WASM_BINARY, -}; - -pub fn development_config() -> ExecutionChainSpec { - ExecutionChainSpec::from_genesis( - // Name - "Development", - // ID - "system_domain_dev", - ChainType::Development, - move || { - testnet_genesis( - vec![ - get_account_id_from_seed("Alice"), - get_account_id_from_seed("Bob"), - get_account_id_from_seed("Alice//stash"), - get_account_id_from_seed("Bob//stash"), - ], - vec![( - get_account_id_from_seed("Alice"), - 1_000 * SSC, - get_account_id_from_seed("Alice"), - get_public_key_from_seed::("Alice"), - )], - Some(get_account_id_from_seed("Alice")), - vec![( - get_account_id_from_seed("Alice"), - get_account_id_from_seed("Alice"), - )], - ) - }, - vec![], - None, - None, - None, - Some(chain_spec_properties()), - None, - ) -} - -pub fn local_testnet_config() -> ExecutionChainSpec { - ExecutionChainSpec::from_genesis( - // Name - "Local Testnet", - // ID - "system_domain_local_testnet", - ChainType::Local, - move || { - testnet_genesis( - vec![ - get_account_id_from_seed("Alice"), - get_account_id_from_seed("Bob"), - get_account_id_from_seed("Charlie"), - get_account_id_from_seed("Dave"), - get_account_id_from_seed("Eve"), - get_account_id_from_seed("Ferdie"), - get_account_id_from_seed("Alice//stash"), - get_account_id_from_seed("Bob//stash"), - get_account_id_from_seed("Charlie//stash"), - get_account_id_from_seed("Dave//stash"), - get_account_id_from_seed("Eve//stash"), - get_account_id_from_seed("Ferdie//stash"), - ], - vec![( - get_account_id_from_seed("Alice"), - 1_000 * SSC, - get_account_id_from_seed("Alice"), - get_public_key_from_seed::("Alice"), - )], - Some(get_account_id_from_seed("Alice")), - vec![ - ( - get_account_id_from_seed("Alice"), - get_account_id_from_seed("Alice"), - ), - ( - get_account_id_from_seed("Bob"), - get_account_id_from_seed("Bob"), - ), - ], - ) - }, - // Bootnodes - vec![], - // Telemetry - None, - // Protocol ID - Some("template-local"), - None, - // Properties - Some(chain_spec_properties()), - // Extensions - None, - ) -} - -pub fn gemini_3d_config() -> ExecutionChainSpec { - ExecutionChainSpec::from_genesis( - // Name - "Subspace Gemini 3d System Domain", - // ID - "subspace_gemini_3d_system_domain", - ChainType::Live, - move || { - let sudo_account = - AccountId::from_ss58check("5CZy4hcmaVZUMZLfB41v1eAKvtZ8W7axeWuDvwjhjPwfhAqt") - .expect("Invalid Sudo account."); - testnet_genesis( - vec![ - // Genesis executor - AccountId::from_ss58check("5Df6w8CgYY8kTRwCu8bjBsFu46fy4nFa61xk6dUbL6G4fFjQ") - .expect("Wrong executor account address"), - // Sudo account - sudo_account.clone(), - ], - vec![( - AccountId::from_ss58check("5Df6w8CgYY8kTRwCu8bjBsFu46fy4nFa61xk6dUbL6G4fFjQ") - .expect("Wrong executor account address"), - 1_000 * SSC, - AccountId::from_ss58check("5FsxcczkSUnpqhcSgugPZsSghxrcKx5UEsRKL5WyPTL6SAxB") - .expect("Wrong executor reward address"), - ExecutorPublicKey::from_ss58check( - "5FuuXk1TL8DKQMvg7mcqmP8t9FhxUdzTcYC9aFmebiTLmASx", - ) - .expect("Wrong executor public key"), - )], - Some(sudo_account), - Default::default(), - ) - }, - // Bootnodes - vec![], - // Telemetry - None, - // Protocol ID - Some("subspace-gemini-3d-system-domain"), - None, - // Properties - Some(chain_spec_properties()), - // Extensions - None, - ) -} - -pub fn devnet_config() -> ExecutionChainSpec { - ExecutionChainSpec::from_genesis( - // Name - "Subspace Devnet System domain", - // ID - "subspace_devnet_system_domain", - ChainType::Custom("Testnet".to_string()), - move || { - let sudo_account = - AccountId::from_ss58check("5CXTmJEusve5ixyJufqHThmy4qUrrm6FyLCR7QfE4bbyMTNC") - .expect("Invalid Sudo account"); - testnet_genesis( - vec![ - // Genesis executor - AccountId::from_ss58check("5Df6w8CgYY8kTRwCu8bjBsFu46fy4nFa61xk6dUbL6G4fFjQ") - .expect("Wrong executor account address"), - // Sudo account - sudo_account.clone(), - ], - vec![( - AccountId::from_ss58check("5Df6w8CgYY8kTRwCu8bjBsFu46fy4nFa61xk6dUbL6G4fFjQ") - .expect("Wrong executor account address"), - 1_000 * SSC, - AccountId::from_ss58check("5FsxcczkSUnpqhcSgugPZsSghxrcKx5UEsRKL5WyPTL6SAxB") - .expect("Wrong executor reward address"), - ExecutorPublicKey::from_ss58check( - "5FuuXk1TL8DKQMvg7mcqmP8t9FhxUdzTcYC9aFmebiTLmASx", - ) - .expect("Wrong executor public key"), - )], - Some(sudo_account.clone()), - vec![( - sudo_account, - AccountId::from_ss58check("5D7kgfacBsP6pkMB628221HG98mz2euaytthdoeZPGceQusS") - .expect("Invalid relayer id account"), - )], - ) - }, - // Bootnodes - vec![], - // Telemetry - None, - // Protocol ID - Some("subspace-devnet-execution"), - None, - // Properties - Some(chain_spec_properties()), - // Extensions - None, - ) -} - -fn testnet_genesis( - endowed_accounts: Vec, - executors: Vec<(AccountId, Balance, AccountId, ExecutorPublicKey)>, - maybe_sudo_account: Option, - relayers: Vec<(AccountId, AccountId)>, -) -> GenesisConfig { - GenesisConfig { - system: SystemConfig { - code: WASM_BINARY - .expect("WASM binary was not build, please build it!") - .to_vec(), - }, - sudo: SudoConfig { - // Assign network admin rights. - key: maybe_sudo_account, - }, - transaction_payment: Default::default(), - balances: BalancesConfig { - balances: endowed_accounts - .iter() - .cloned() - .map(|k| (k, 1_000_000 * SSC)) - .collect(), - }, - executor_registry: ExecutorRegistryConfig { - executors, - slot_probability: (1, 1), - }, - domain_registry: DomainRegistryConfig::default(), - messenger: MessengerConfig { relayers }, - } -} diff --git a/crates/subspace-proof-of-space/Cargo.toml b/crates/subspace-proof-of-space/Cargo.toml index 983ceff01d7..465b57ea49b 100644 --- a/crates/subspace-proof-of-space/Cargo.toml +++ b/crates/subspace-proof-of-space/Cargo.toml @@ -16,15 +16,15 @@ include = [ bench = false [dependencies] -bitvec = { version = "1.0.1", default-features = false, features = ["alloc", "atomic"], optional = true } -blake3 = { version = "1.4.0", default-features = false, optional = true } chacha20 = { version = "0.9.1", default-features = false, optional = true } +derive_more = { version = "0.99.17", optional = true } rayon = { version = "1.7.0", optional = true } +seq-macro = { version = "0.3.5", optional = true } sha2 = { version = "0.10.7", optional = true } -subspace-chiapos = { git = "https://github.com/subspace/chiapos", rev = "3b1ab3ca24764d25da30e0c8243e0bf304b776a5", optional = true } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } [dev-dependencies] +bitvec = "1.0.1" criterion = "0.5.1" rand = "0.8.5" subspace-chiapos = { git = "https://github.com/subspace/chiapos", rev = "3b1ab3ca24764d25da30e0c8243e0bf304b776a5" } @@ -36,28 +36,21 @@ harness = false [features] default = ["std"] std = [ - "bitvec?/std", - "blake3?/std", "chacha20?/std", "subspace-core-primitives/std", ] parallel = [ "dep:rayon", -] -# Enable Chia proof of space support (legacy implementation uses C++ chiapos), only works in `std` environment for now -chia-legacy = [ + # Parallel implementation requires std due to usage of channels to achieve highest performance "std", - "subspace-chiapos", ] -# Enable Chia proof of space support, using alternative implementation, works in no-std environment as well +# Enable Chia proof of space support chia = [ - "bitvec", - "blake3", "chacha20", + "derive_more", + "seq-macro", "sha2", ] -# Enable support for all possible K for chia: from smallest to insanely large as well as not popular in general -all-chia-k = [] -# Enables shim proof of space that works much faster than original and can be used for testing purposes to reduce memory +# Enables shim proof of space that works much faster than Chia and can be used for testing purposes to reduce memory # and CPU usage shim = [] diff --git a/crates/subspace-proof-of-space/benches/pos.rs b/crates/subspace-proof-of-space/benches/pos.rs index d9a1e316963..10de4961c30 100644 --- a/crates/subspace-proof-of-space/benches/pos.rs +++ b/crates/subspace-proof-of-space/benches/pos.rs @@ -1,16 +1,16 @@ #![feature(const_trait_impl)] -#[cfg(any(feature = "chia-legacy", feature = "chia", feature = "shim"))] +#[cfg(any(feature = "chia", feature = "shim"))] use criterion::black_box; use criterion::{criterion_group, criterion_main, Criterion}; #[cfg(feature = "parallel")] use rayon::ThreadPoolBuilder; -#[cfg(any(feature = "chia-legacy", feature = "chia", feature = "shim"))] +#[cfg(any(feature = "chia", feature = "shim"))] use subspace_core_primitives::PosSeed; -#[cfg(any(feature = "chia-legacy", feature = "chia", feature = "shim"))] -use subspace_proof_of_space::{Quality, Table}; +#[cfg(any(feature = "chia", feature = "shim"))] +use subspace_proof_of_space::{Quality, Table, TableGenerator}; -#[cfg(any(feature = "chia-legacy", feature = "chia", feature = "shim"))] +#[cfg(any(feature = "chia", feature = "shim"))] fn pos_bench( c: &mut Criterion, name: &'static str, @@ -29,28 +29,30 @@ fn pos_bench( // Repeated initialization is not supported, we just ignore errors here because of it let _ = ThreadPoolBuilder::new() // Change number of threads if necessary - .num_threads(4) + // .num_threads(4) .build_global(); } let mut group = c.benchmark_group(name); + let mut generator_instance = PosTable::generator(); group.bench_function("table/single", |b| { b.iter(|| { - PosTable::generate(black_box(&seed)); + generator_instance.generate(black_box(&seed)); }); }); #[cfg(feature = "parallel")] { + let mut generator_instance = PosTable::generator(); group.bench_function("table/parallel", |b| { b.iter(|| { - PosTable::generate_parallel(black_box(&seed)); + generator_instance.generate_parallel(black_box(&seed)); }); }); } - let table = PosTable::generate(&seed); + let table = generator_instance.generate(&seed); group.bench_function("quality/no-solution", |b| { b.iter(|| { @@ -89,25 +91,11 @@ fn pos_bench( } pub fn criterion_benchmark(c: &mut Criterion) { - #[cfg(not(any(feature = "chia-legacy", feature = "chia", feature = "shim")))] + #[cfg(not(any(feature = "chia", feature = "shim")))] { let _ = c; panic!(r#"Enable "chia" and/or "shim" feature to run benches"#); } - #[cfg(feature = "chia-legacy")] - { - // This challenge index with above seed is known to not have a solution - let challenge_index_without_solution = 0; - // This challenge index with above seed is known to have a solution - let challenge_index_with_solution = 1; - - pos_bench::( - c, - "chia-legacy", - challenge_index_without_solution, - challenge_index_with_solution, - ) - } #[cfg(feature = "chia")] { // This challenge index with above seed is known to not have a solution diff --git a/crates/subspace-proof-of-space/src/chia.rs b/crates/subspace-proof-of-space/src/chia.rs index ce55ef26bb9..a3c8b946f34 100644 --- a/crates/subspace-proof-of-space/src/chia.rs +++ b/crates/subspace-proof-of-space/src/chia.rs @@ -2,7 +2,7 @@ use crate::chiapos::Tables; #[cfg(any(feature = "parallel", test))] use crate::chiapos::TablesCache; -use crate::{PosTableType, Quality, Table}; +use crate::{PosTableType, Quality, Table, TableGenerator}; use core::mem; use subspace_core_primitives::{PosProof, PosQualityBytes, PosSeed}; @@ -33,7 +33,29 @@ impl<'a> Quality for ChiaQuality<'a> { } } -/// Subspace proof of space table +/// Subspace proof of space table generator. +/// +/// Chia implementation. +#[derive(Debug, Default, Clone)] +pub struct ChiaTableGenerator { + tables_cache: TablesCache, +} + +impl TableGenerator for ChiaTableGenerator { + fn generate(&mut self, seed: &PosSeed) -> ChiaTable { + ChiaTable { + tables: Tables::::create((*seed).into(), &mut self.tables_cache), + } + } + + fn generate_parallel(&mut self, seed: &PosSeed) -> ChiaTable { + ChiaTable { + tables: Tables::::create_parallel((*seed).into(), &mut self.tables_cache), + } + } +} + +/// Subspace proof of space table. /// /// Chia implementation. #[derive(Debug)] @@ -43,6 +65,7 @@ pub struct ChiaTable { impl Table for ChiaTable { const TABLE_TYPE: PosTableType = PosTableType::Chia; + type Generator = ChiaTableGenerator; type Quality<'a> = ChiaQuality<'a>; diff --git a/crates/subspace-proof-of-space/src/chia_legacy.rs b/crates/subspace-proof-of-space/src/chia_legacy.rs deleted file mode 100644 index 9893b8f7af6..00000000000 --- a/crates/subspace-proof-of-space/src/chia_legacy.rs +++ /dev/null @@ -1,82 +0,0 @@ -//! Chia proof of space implementation - -use crate::{PosTableType, Quality, Table}; -use subspace_core_primitives::{PosProof, PosQualityBytes, PosSeed}; - -/// Abstraction that represents quality of the solution in the table. -/// -/// Chia implementation. -#[derive(Debug)] -#[must_use] -pub struct ChiaQuality<'a> { - quality: subspace_chiapos::Quality<'a>, -} - -impl<'a> Quality for ChiaQuality<'a> { - fn to_bytes(&self) -> PosQualityBytes { - PosQualityBytes::from(self.quality.to_bytes()) - } - - fn create_proof(&self) -> PosProof { - PosProof::from(self.quality.create_proof()) - } -} - -/// Subspace proof of space table -/// -/// Chia implementation. -#[derive(Debug)] -pub struct ChiaTable { - table: subspace_chiapos::Table, -} - -impl Table for ChiaTable { - const TABLE_TYPE: PosTableType = PosTableType::ChiaLegacy; - - type Quality<'a> = ChiaQuality<'a>; - - fn generate(seed: &PosSeed) -> ChiaTable { - Self { - table: subspace_chiapos::Table::generate(seed), - } - } - - fn find_quality(&self, challenge_index: u32) -> Option> { - self.table - .find_quality(challenge_index) - .map(|quality| ChiaQuality { quality }) - } - - fn is_proof_valid( - seed: &PosSeed, - challenge_index: u32, - proof: &PosProof, - ) -> Option { - subspace_chiapos::is_proof_valid(seed, challenge_index, proof).map(PosQualityBytes::from) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - const SEED: PosSeed = PosSeed::from([ - 35, 2, 52, 4, 51, 55, 23, 84, 91, 10, 111, 12, 13, 222, 151, 16, 228, 211, 254, 45, 92, - 198, 204, 10, 9, 10, 11, 129, 139, 171, 15, 23, - ]); - - #[test] - fn basic() { - let table = ChiaTable::generate(&SEED); - - assert!(table.find_quality(0).is_none()); - - { - let challenge_index = 1; - let quality = table.find_quality(challenge_index).unwrap(); - let proof = quality.create_proof(); - let maybe_quality = ChiaTable::is_proof_valid(&SEED, challenge_index, &proof); - assert_eq!(maybe_quality, Some(quality.to_bytes())); - } - } -} diff --git a/crates/subspace-proof-of-space/src/chiapos.rs b/crates/subspace-proof-of-space/src/chiapos.rs index 15408d2d009..0d45b7c79ba 100644 --- a/crates/subspace-proof-of-space/src/chiapos.rs +++ b/crates/subspace-proof-of-space/src/chiapos.rs @@ -7,10 +7,8 @@ mod tables; mod tests; mod utils; +use crate::chiapos::table::metadata_size_bytes; pub use crate::chiapos::table::TablesCache; -use crate::chiapos::table::{ - fn_hashing_input_bytes, metadata_size_bytes, x_size_bytes, y_size_bytes, -}; use crate::chiapos::tables::TablesGeneric; use crate::chiapos::utils::EvaluatableUsize; @@ -22,16 +20,13 @@ type Quality = [u8; 32]; #[derive(Debug)] pub struct Tables(TablesGeneric) where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 1) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 2) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 3) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 4) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 5) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 6) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, 7) }>: Sized, - EvaluatableUsize<{ fn_hashing_input_bytes(K) }>: Sized; + EvaluatableUsize<{ metadata_size_bytes(K, 7) }>: Sized; macro_rules! impl_any { ($($k: expr$(,)? )*) => { @@ -93,13 +88,5 @@ impl Tables<$k> { } } -// These are all `K` which can be safely used on 32-bit platform -#[cfg(feature = "all-chia-k")] -impl_any!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 19, 20); -impl_any!(16, 17, 18); - -// These are all `K` which require 64-bit platform -#[cfg(target_pointer_width = "64")] -impl_any!(32, 33, 34, 35); -#[cfg(all(target_pointer_width = "64", feature = "all-chia-k"))] -impl_any!(21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 36, 37, 38, 39, 40); +// Only these k values are supported by current implementation +impl_any!(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25); diff --git a/crates/subspace-proof-of-space/src/chiapos/table.rs b/crates/subspace-proof-of-space/src/chiapos/table.rs index f527cd1dea5..2754ebc770e 100644 --- a/crates/subspace-proof-of-space/src/chiapos/table.rs +++ b/crates/subspace-proof-of-space/src/chiapos/table.rs @@ -5,7 +5,7 @@ pub(super) mod types; extern crate alloc; use crate::chiapos::constants::{PARAM_B, PARAM_BC, PARAM_C, PARAM_EXT, PARAM_M}; -use crate::chiapos::table::types::{CopyBitsDestination, Metadata, Position, X, Y}; +use crate::chiapos::table::types::{Metadata, Position, X, Y}; use crate::chiapos::utils::EvaluatableUsize; use crate::chiapos::Seed; use alloc::vec; @@ -13,26 +13,29 @@ use alloc::vec::Vec; use chacha20::cipher::{KeyIvInit, StreamCipher, StreamCipherSeek}; use chacha20::{ChaCha8, Key, Nonce}; use core::mem; +use core::simd::Simd; #[cfg(any(feature = "parallel", test))] use rayon::prelude::*; +use seq_macro::seq; +use std::simd::SimdUint; +#[cfg(any(feature = "parallel", test))] +use std::sync::mpsc; +use subspace_core_primitives::crypto::{blake3_hash, blake3_hash_list}; -/// Compute the size of `x` in bytes -pub const fn x_size_bytes(k: u8) -> usize { - (k as usize).div_ceil(u8::BITS as usize) -} +pub(super) const COMPUTE_F1_SIMD_FACTOR: usize = 8; /// Compute the size of `y` in bits pub(super) const fn y_size_bits(k: u8) -> usize { k as usize + PARAM_EXT as usize } -/// Compute the size of `y` in bytes -pub const fn y_size_bytes(k: u8) -> usize { - y_size_bits(k).div_ceil(u8::BITS as usize) +/// Metadata size in bytes +pub const fn metadata_size_bytes(k: u8, table_number: u8) -> usize { + metadata_size_bits(k, table_number).div_ceil(u8::BITS as usize) } /// Metadata size in bits -pub const fn metadata_size_bits(k: u8, table_number: u8) -> usize { +pub(super) const fn metadata_size_bits(k: u8, table_number: u8) -> usize { k as usize * match table_number { 1 => 1, @@ -45,45 +48,6 @@ pub const fn metadata_size_bits(k: u8, table_number: u8) -> usize { } } -/// Max size in bits for any table -pub(crate) const fn max_metadata_size_bits(k: u8) -> usize { - let mut max = metadata_size_bits(k, 1); - let new = metadata_size_bits(k, 2); - if new > max { - max = new; - } - let new = metadata_size_bits(k, 3); - if new > max { - max = new; - } - let new = metadata_size_bits(k, 4); - if new > max { - max = new; - } - let new = metadata_size_bits(k, 5); - if new > max { - max = new; - } - let new = metadata_size_bits(k, 6); - if new > max { - max = new; - } - let new = metadata_size_bits(k, 7); - if new > max { - max = new; - } - max -} - -/// Metadata size in bytes rounded up -pub const fn metadata_size_bytes(k: u8, table_number: u8) -> usize { - metadata_size_bits(k, table_number).div_ceil(u8::BITS as usize) -} - -pub const fn fn_hashing_input_bytes(k: u8) -> usize { - (y_size_bits(k) + max_metadata_size_bits(k) * 2).div_ceil(u8::BITS as usize) -} - /// ChaCha8 [`Vec`] sufficient for the whole first table for [`K`]. /// Prefer [`partial_y`] if you need partial y just for a single `x`. fn partial_ys(seed: Seed) -> Vec { @@ -105,9 +69,9 @@ fn partial_ys(seed: Seed) -> Vec { /// Prefer [`partial_ys`] if you process the whole first table. pub(super) fn partial_y( seed: Seed, - x: usize, + x: X, ) -> ([u8; (K as usize * 2).div_ceil(u8::BITS as usize)], usize) { - let skip_bits = usize::from(K) * x; + let skip_bits = usize::from(K) * usize::from(x); let skip_bytes = skip_bits / u8::BITS as usize; let skip_bits = skip_bits % u8::BITS as usize; @@ -124,20 +88,21 @@ pub(super) fn partial_y( (output, skip_bits) } -fn calculate_left_targets() -> Vec>> { - let param_b = usize::from(PARAM_B); - let param_c = usize::from(PARAM_C); +fn calculate_left_targets() -> Vec>> { + let param_b = u32::from(PARAM_B); + let param_c = u32::from(PARAM_C); - (0..=1usize) + (0..=1u32) .map(|parity| { - (0..usize::from(PARAM_BC)) + (0..u32::from(PARAM_BC)) .map(|r| { let c = r / param_c; - (0..usize::from(PARAM_M)) + (0..u32::from(PARAM_M)) .map(|m| { - ((c + m) % param_b) * param_c - + (((2 * m + parity) * (2 * m + parity) + r) % param_c) + let target = ((c + m) % param_b) * param_c + + (((2 * m + parity) * (2 * m + parity) + r) % param_c); + Position::from(target) }) .collect() }) @@ -156,98 +121,136 @@ fn calculate_left_target_on_demand(parity: usize, r: usize, m: usize) -> usize { } /// Caches that can be used to optimize creation of multiple [`Tables`](super::Tables). -#[derive(Debug)] -pub struct TablesCache -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - left_bucket: Bucket, - right_bucket: Bucket, +#[derive(Debug, Clone)] +pub struct TablesCache { + buckets: Vec, rmap_scratch: Vec, - left_targets: Vec>>, + left_targets: Vec>>, } -impl Default for TablesCache -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ +impl Default for TablesCache { /// Create new instance fn default() -> Self { - // Pair of buckets that are a sliding window of 2 buckets across the whole table - let left_bucket = Bucket::default(); - let right_bucket = Bucket::default(); - - let left_targets = calculate_left_targets(); - // TODO: This is the capacity chiapos allocates it with, check if it is correct - let rmap_scratch = Vec::with_capacity(usize::from(PARAM_BC)); - Self { - left_bucket, - right_bucket, - rmap_scratch, - left_targets, + buckets: Vec::new(), + rmap_scratch: Vec::new(), + left_targets: calculate_left_targets(), } } } #[derive(Debug)] -pub(super) struct Match -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - left_index: usize, - left_y: Y, - right_index: usize, +pub(super) struct Match { + left_position: Position, + left_y: Y, + right_position: Position, } -#[derive(Debug, Clone)] -struct Bucket -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ +#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)] +struct Bucket { /// Bucket index - bucket_index: usize, - /// `y` values in this bucket - ys: Vec>, + bucket_index: u32, /// Start position of this bucket in the table - start_position: usize, -} - -impl Default for Bucket -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - fn default() -> Self { - Self { - bucket_index: 0, - // TODO: Currently twice the average size (*2), re-consider size in the future if it is - // typically exceeded - ys: Vec::with_capacity(usize::from(PARAM_BC) / (1 << PARAM_EXT) * 2), - start_position: 0, - } - } + start_position: Position, + /// Size of this bucket + size: Position, } #[derive(Debug, Default, Copy, Clone)] pub(super) struct RmapItem { - count: usize, - start_index: usize, -} + count: Position, + start_position: Position, +} + +/// `partial_y_offset` is in bits +pub(super) fn compute_f1(x: X, partial_y: &[u8], partial_y_offset: usize) -> Y { + let partial_y_length = + (partial_y_offset % u8::BITS as usize + usize::from(K)).div_ceil(u8::BITS as usize); + let mut pre_y_bytes = 0u64.to_be_bytes(); + pre_y_bytes[..partial_y_length] + .copy_from_slice(&partial_y[partial_y_offset / u8::BITS as usize..][..partial_y_length]); + // Contains `K` desired bits of `partial_y` in the final offset of eventual `y` with the rest + // of bits being in undefined state + let pre_y = u64::from_be_bytes(pre_y_bytes) + >> (u64::BITS as usize - usize::from(K + PARAM_EXT) - partial_y_offset % u8::BITS as usize); + let pre_y = pre_y as u32; + // Mask for clearing the rest of bits of `pre_y`. + let pre_y_mask = (u32::MAX << usize::from(PARAM_EXT)) + & (u32::MAX >> (u32::BITS as usize - usize::from(K + PARAM_EXT))); + + // Extract `PARAM_EXT` most significant bits from `x` and store in the final offset of + // eventual `y` with the rest of bits being in undefined state. + let pre_ext = u32::from(x) >> (usize::from(K - PARAM_EXT)); + // Mask for clearing the rest of bits of `pre_ext`. + let pre_ext_mask = u32::MAX >> (u32::BITS as usize - usize::from(PARAM_EXT)); + + // Combine all of the bits together: + // [padding zero bits][`K` bits rom `partial_y`][`PARAM_EXT` bits from `x`] + Y::from((pre_y & pre_y_mask) | (pre_ext & pre_ext_mask)) +} + +pub(super) fn compute_f1_simd( + xs: [X; COMPUTE_F1_SIMD_FACTOR], + partial_ys: &[u8; K as usize * COMPUTE_F1_SIMD_FACTOR / u8::BITS as usize], +) -> [Y; COMPUTE_F1_SIMD_FACTOR] { + // Each element contains `K` desired bits of `partial_ys` in the final offset of eventual `ys` + // with the rest of bits being in undefined state + let pre_ys_bytes = Simd::from(seq!(N in 0..8 { + [ + #( + { + #[allow(clippy::erasing_op, clippy::identity_op)] + let partial_y_offset = N * usize::from(K); + let partial_y_length = + (partial_y_offset % u8::BITS as usize + usize::from(K)).div_ceil(u8::BITS as usize); + let mut pre_y_bytes = 0u64.to_be_bytes(); + pre_y_bytes[..partial_y_length].copy_from_slice( + &partial_ys[partial_y_offset / u8::BITS as usize..][..partial_y_length], + ); -/// Y value will be in the first bits of returned byte array, `partial_y_offset` is in bits -pub(super) fn compute_f1(x: X, partial_y: &[u8], partial_y_offset: usize) -> Y -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - let mut y = Y::default(); + u64::from_be_bytes(pre_y_bytes) + }, + )* + ] + })); + let pre_ys_right_offset = Simd::from(seq!(N in 0..8 { + [ + #( + { + #[allow(clippy::erasing_op, clippy::identity_op)] + let partial_y_offset = N * u32::from(K); + u64::from(u64::BITS - u32::from(K + PARAM_EXT) - partial_y_offset % u8::BITS) + }, + )* + ] + })); + // TODO: both this and above operations are most likely possible on x86-64 with a special + // intrinsic in a more efficient way + let pre_ys = pre_ys_bytes >> pre_ys_right_offset; + + // Mask for clearing the rest of bits of `pre_ys`. + let pre_ys_mask = Simd::splat( + (u32::MAX << usize::from(PARAM_EXT)) + & (u32::MAX >> (u32::BITS as usize - usize::from(K + PARAM_EXT))), + ); + + // SAFETY: `X` is `#[repr(transparent)]` and guaranteed to have the same memory layout as `u32` + let xs = unsafe { mem::transmute::<_, [u32; COMPUTE_F1_SIMD_FACTOR]>(xs) }; + // Extract `PARAM_EXT` most significant bits from `xs` and store in the final offset of + // eventual `ys` with the rest of bits being in undefined state. + let pre_exts = Simd::from(xs) >> Simd::splat(u32::from(K - PARAM_EXT)); - // Copy partial y value derived from ChaCha8 stream - y.copy_bits_from(partial_y, partial_y_offset, K, 0_usize); - // And `PARAM_EXT` most significant bits from `x` - y.copy_bits_from(&x, 0_usize, PARAM_EXT, K); + // Mask for clearing the rest of bits of `pre_exts`. + let pre_exts_mask = Simd::splat(u32::MAX >> (u32::BITS as usize - usize::from(PARAM_EXT))); - y + // Combine all of the bits together: + // [padding zero bits][`K` bits rom `partial_y`][`PARAM_EXT` bits from `x`] + // NOTE: `pre_exts_mask` is unnecessary here and makes no difference, but it allows compiler to + // generate faster code 🤷‍ + let ys = (pre_ys.cast() & pre_ys_mask) | (pre_exts & pre_exts_mask); + + // SAFETY: `Y` is `#[repr(transparent)]` and guaranteed to have the same memory layout as `u32` + unsafe { mem::transmute(ys.to_array()) } } /// `rmap_scratch` is just an optimization to reuse allocations between calls. @@ -255,75 +258,71 @@ where /// For verification purposes use [`num_matches`] instead. /// /// Returns `None` if either of buckets is empty. -fn find_matches<'a, const K: u8>( - left_bucket_ys: &'a [Y], - right_bucket_ys: &'a [Y], +fn find_matches<'a>( + left_bucket_ys: &'a [Y], + left_bucket_start_position: Position, + right_bucket_ys: &'a [Y], + right_bucket_start_position: Position, rmap_scratch: &'a mut Vec, - left_targets: &'a [Vec>], -) -> Option> + 'a> -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ + left_targets: &'a [Vec>], +) -> Option + 'a> { // Clear and set to correct size with zero values rmap_scratch.clear(); rmap_scratch.resize_with(usize::from(PARAM_BC), RmapItem::default); let rmap = rmap_scratch; // Both left and right buckets can be empty - let first_left_bucket_y = usize::from(left_bucket_ys.first()?); - let first_right_bucket_y = usize::from(right_bucket_ys.first()?); + let first_left_bucket_y = *left_bucket_ys.first()?; + let first_right_bucket_y = *right_bucket_ys.first()?; // Since all entries in a bucket are obtained after division by `PARAM_BC`, we can compute // quotient more efficiently by subtracting base value rather than computing remainder of // division - let base = (first_right_bucket_y / usize::from(PARAM_BC)) * usize::from(PARAM_BC); - for (right_index, y) in right_bucket_ys.iter().enumerate() { + let base = (usize::from(first_right_bucket_y) / usize::from(PARAM_BC)) * usize::from(PARAM_BC); + for (&y, right_position) in right_bucket_ys.iter().zip(right_bucket_start_position..) { let r = usize::from(y) - base; // Same `y` and as the result `r` can appear in the table multiple times, in which case // they'll all occupy consecutive slots in `right_bucket` and all we need to store is just // the first position and number of elements. - if rmap[r].count == 0 { - rmap[r].start_index = right_index; + if rmap[r].count == Position::ZERO { + rmap[r].start_position = right_position; } - rmap[r].count += 1; + rmap[r].count += Position::ONE; } let rmap = rmap.as_slice(); // Same idea as above, but avoids division by leveraging the fact that each bucket is exactly // `PARAM_BC` away from the previous one in terms of divisor by `PARAM_BC` let base = base - usize::from(PARAM_BC); - let parity = (first_left_bucket_y / usize::from(PARAM_BC)) % 2; + let parity = (usize::from(first_left_bucket_y) / usize::from(PARAM_BC)) % 2; let left_targets = &left_targets[parity]; Some( left_bucket_ys .iter() - .enumerate() - .flat_map(move |(left_index, y)| { + .zip(left_bucket_start_position..) + .flat_map(move |(&y, left_position)| { let r = usize::from(y) - base; let left_targets = &left_targets[r]; (0..usize::from(PARAM_M)).flat_map(move |m| { let r_target = left_targets[m]; - let rmap_item = rmap[r_target]; - - (rmap_item.start_index..) - .take(rmap_item.count) - .map(move |right_index| Match { - left_index, - left_y: *y, - right_index, - }) + let rmap_item = rmap[usize::from(r_target)]; + + (rmap_item.start_position..rmap_item.start_position + rmap_item.count).map( + move |right_position| Match { + left_position, + left_y: y, + right_position, + }, + ) }) }), ) } /// Simplified version of [`find_matches`] for verification purposes. -pub(super) fn num_matches(left_y: &Y, right_y: &Y) -> usize -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ +pub(super) fn num_matches(left_y: Y, right_y: Y) -> usize { let right_r = usize::from(right_y) % usize::from(PARAM_BC); let parity = (usize::from(left_y) / usize::from(PARAM_BC)) % 2; let left_r = usize::from(left_y) % usize::from(PARAM_BC); @@ -340,137 +339,161 @@ where } pub(super) fn compute_fn( - y: Y, + y: Y, left_metadata: Metadata, right_metadata: Metadata, -) -> (Y, Metadata) +) -> (Y, Metadata) where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, PARENT_TABLE_NUMBER) }>: Sized, - EvaluatableUsize<{ fn_hashing_input_bytes(K) }>: Sized, + EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, { - let hash = { - let mut input = [0; fn_hashing_input_bytes(K)]; - - input.copy_bits_from(&y, 0_usize, y_size_bits(K), 0_usize); - input.copy_bits_from( - &left_metadata, - 0_usize, - metadata_size_bits(K, PARENT_TABLE_NUMBER), - y_size_bits(K), - ); - input.copy_bits_from( - &right_metadata, - 0_usize, - metadata_size_bits(K, PARENT_TABLE_NUMBER), - y_size_bits(K) + metadata_size_bits(K, PARENT_TABLE_NUMBER), - ); + let left_metadata = u128::from(left_metadata); + let right_metadata = u128::from(right_metadata); + + let parent_metadata_bits = metadata_size_bits(K, PARENT_TABLE_NUMBER); + // Only supports `K` from 15 to 25 (otherwise math will not be correct when concatenating y, + // left metadata and right metadata) + let hash = { // Take only bytes where bits were set let num_bytes_with_data = (y_size_bits(K) + metadata_size_bits(K, PARENT_TABLE_NUMBER) * 2) .div_ceil(u8::BITS as usize); - blake3::hash(&input[..num_bytes_with_data]) + + // Collect `K` most significant bits of `y` at the final offset of eventual `input_a` + let y_bits = u128::from(y) << (u128::BITS as usize - y_size_bits(K)); + + // Move bits of `left_metadata` at the final offset of eventual `input_a` + let left_metadata_bits = + left_metadata << (u128::BITS as usize - parent_metadata_bits - y_size_bits(K)); + + // Part of the `right_bits` at the final offset of eventual `input_a` + let y_and_left_bits = y_size_bits(K) + parent_metadata_bits; + let right_bits_start_offset = u128::BITS as usize - parent_metadata_bits; + + // If `right_metadata` bits start to the left of the desired position in `input_a` move + // bits right, else move left + if right_bits_start_offset < y_and_left_bits { + let right_bits_pushed_into_input_b = y_and_left_bits - right_bits_start_offset; + // Collect bits of `right_metadata` that will fit into `input_a` at the final offset in + // eventual `input_a` + let right_bits_a = right_metadata >> right_bits_pushed_into_input_b; + let input_a = y_bits | left_metadata_bits | right_bits_a; + // Collect bits of `right_metadata` that will spill over into `input_b` + let input_b = right_metadata << (u128::BITS as usize - right_bits_pushed_into_input_b); + + blake3_hash_list(&[ + &input_a.to_be_bytes(), + &input_b.to_be_bytes() + [..right_bits_pushed_into_input_b.div_ceil(u8::BITS as usize)], + ]) + } else { + let right_bits_a = right_metadata << (right_bits_start_offset - y_and_left_bits); + let input_a = y_bits | left_metadata_bits | right_bits_a; + + blake3_hash(&input_a.to_be_bytes()[..num_bytes_with_data]) + } }; - let mut y_output = Y::default(); - y_output.copy_bits_from(hash.as_bytes(), 0_usize, y_size_bits(K), 0_usize); - let mut metadata = Metadata::default(); + let y_output = Y::from( + u32::from_be_bytes( + hash[..mem::size_of::()] + .try_into() + .expect("Hash if statically guaranteed to have enough bytes; qed"), + ) >> (u32::BITS as usize - y_size_bits(K)), + ); - if TABLE_NUMBER < 4 { - metadata.copy_bits_from( - &left_metadata, - 0_usize, - metadata_size_bits(K, PARENT_TABLE_NUMBER), - 0_usize, - ); - metadata.copy_bits_from( - &right_metadata, - 0_usize, - metadata_size_bits(K, PARENT_TABLE_NUMBER), - metadata_size_bits(K, PARENT_TABLE_NUMBER), - ); - } else if metadata_size_bits(K, TABLE_NUMBER) > 0 { - metadata.copy_bits_from( - hash.as_bytes(), - y_size_bits(K), - metadata_size_bits(K, TABLE_NUMBER), - 0_usize, + let metadata_size_bits = metadata_size_bits(K, TABLE_NUMBER); + + let metadata = if TABLE_NUMBER < 4 { + (left_metadata << parent_metadata_bits) | right_metadata + } else if metadata_size_bits > 0 { + // For K under 25 it is guaranteed that metadata + bit offset will always fit into u128. + // We collect bytes necessary, potentially with extra bits at the start and end of the bytes + // that will be taken care of later. + let metadata = u128::from_be_bytes( + hash[y_size_bits(K) / u8::BITS as usize..][..mem::size_of::()] + .try_into() + .expect("Always enough bits for any K; qed"), ); - } + // Remove extra bits at the beginning + let metadata = metadata << (y_size_bits(K) % u8::BITS as usize); + // Move bits into correct location + metadata >> (u128::BITS as usize - metadata_size_bits) + } else { + 0 + }; - (y_output, metadata) + (y_output, Metadata::from(metadata)) +} + +fn match_to_result( + last_table: &Table, + m: Match, +) -> (Y, [Position; 2], Metadata) +where + EvaluatableUsize<{ metadata_size_bytes(K, PARENT_TABLE_NUMBER) }>: Sized, + EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, +{ + let left_metadata = last_table + .metadata(m.left_position) + .expect("Position resulted from matching is correct; qed"); + let right_metadata = last_table + .metadata(m.right_position) + .expect("Position resulted from matching is correct; qed"); + + let (y, metadata) = + compute_fn::(m.left_y, left_metadata, right_metadata); + + (y, [m.left_position, m.right_position], metadata) } fn match_and_compute_fn<'a, const K: u8, const TABLE_NUMBER: u8, const PARENT_TABLE_NUMBER: u8>( last_table: &'a Table, - left_bucket: &'a Bucket, - right_bucket: &'a Bucket, + left_bucket: Bucket, + right_bucket: Bucket, rmap_scratch: &'a mut Vec, - left_targets: &'a [Vec>], -) -> impl Iterator, Metadata, [Position; 2])> + 'a -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, + left_targets: &'a [Vec>], + results_table: &mut Vec<(Y, [Position; 2], Metadata)>, +) where EvaluatableUsize<{ metadata_size_bytes(K, PARENT_TABLE_NUMBER) }>: Sized, - EvaluatableUsize<{ fn_hashing_input_bytes(K) }>: Sized, + EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, { - let maybe_matches = find_matches::( - &left_bucket.ys, - &right_bucket.ys, + let Some(matches) = find_matches( + &last_table.ys()[usize::from(left_bucket.start_position)..] + [..usize::from(left_bucket.size)], + left_bucket.start_position, + &last_table.ys()[usize::from(right_bucket.start_position)..] + [..usize::from(right_bucket.size)], + right_bucket.start_position, rmap_scratch, left_targets, - ); + ) else { + return; + }; - maybe_matches.into_iter().flat_map(|matches| { - matches.map(|m| { - let left_position = left_bucket.start_position + m.left_index; - let right_position = right_bucket.start_position + m.right_index; - let left_metadata = last_table - .metadata(left_position) - .expect("Position resulted from matching is correct; qed"); - let right_metadata = last_table - .metadata(right_position) - .expect("Position resulted from matching is correct; qed"); - - let (y, metadata) = compute_fn::( - m.left_y, - left_metadata, - right_metadata, - ); - ( - y, - metadata, - [ - Position::from(left_position), - Position::from(right_position), - ], - ) - }) - }) + matches.for_each(|m| { + results_table.push(match_to_result(last_table, m)); + }); } #[derive(Debug)] pub(super) enum Table where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, { /// First table with contents of entries split into separate vectors for more efficient access First { /// Derived values computed from `x` - ys: Vec>, + ys: Vec, /// X values - xs: Vec>, + xs: Vec, }, /// Other tables Other { /// Derived values computed from previous table - ys: Vec>, + ys: Vec, /// Left and right entry positions in a previous table encoded into bits - positions: Vec<[Position; 2]>, + positions: Vec<[Position; 2]>, /// Metadata corresponding to each entry metadatas: Vec>, }, @@ -478,23 +501,35 @@ where impl Table where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 1) }>: Sized, { /// Create the table - pub(super) fn create(seed: Seed) -> Self { + pub(super) fn create(seed: Seed) -> Self + where + EvaluatableUsize<{ K as usize * COMPUTE_F1_SIMD_FACTOR / u8::BITS as usize }>: Sized, + { let partial_ys = partial_ys::(seed); - let mut t_1 = (0..1 << K) - .map(|x| { - let partial_y_offset = x * usize::from(K); - let x = X::from(x); - let y = compute_f1::(x, &partial_ys, partial_y_offset); - - (y, x) - }) - .collect::>(); + let mut t_1 = Vec::with_capacity(1_usize << K); + for (x_start, partial_ys) in X::all::().step_by(COMPUTE_F1_SIMD_FACTOR).zip( + partial_ys + .array_chunks::<{ K as usize * COMPUTE_F1_SIMD_FACTOR / u8::BITS as usize }>() + .copied(), + ) { + let xs = seq!(N in 0..8 { + [ + #( + #[allow(clippy::erasing_op, clippy::identity_op)] + { + x_start + X::from(N) + }, + )* + ] + }); + + let ys = compute_f1_simd::(xs, &partial_ys); + t_1.extend(ys.into_iter().zip(xs)); + } t_1.sort_unstable(); @@ -505,18 +540,32 @@ where /// Create the table, leverages available parallelism #[cfg(any(feature = "parallel", test))] - pub(super) fn create_parallel(seed: Seed) -> Self { + pub(super) fn create_parallel(seed: Seed) -> Self + where + EvaluatableUsize<{ K as usize * COMPUTE_F1_SIMD_FACTOR / u8::BITS as usize }>: Sized, + { let partial_ys = partial_ys::(seed); - let mut t_1 = (0..1 << K) - .map(|x| { - let partial_y_offset = x * usize::from(K); - let x = X::from(x); - let y = compute_f1::(x, &partial_ys, partial_y_offset); - - (y, x) - }) - .collect::>(); + let mut t_1 = Vec::with_capacity(1_usize << K); + for (x_start, partial_ys) in X::all::().step_by(COMPUTE_F1_SIMD_FACTOR).zip( + partial_ys + .array_chunks::<{ K as usize * COMPUTE_F1_SIMD_FACTOR / u8::BITS as usize }>() + .copied(), + ) { + let xs = seq!(N in 0..8 { + [ + #( + #[allow(clippy::erasing_op, clippy::identity_op)] + { + x_start + X::from(N) + }, + )* + ] + }); + + let ys = compute_f1_simd::(xs, &partial_ys); + t_1.extend(ys.into_iter().zip(xs)); + } t_1.par_sort_unstable(); @@ -526,7 +575,7 @@ where } /// All `x`s as [`BitSlice`], for individual `x`s needs to be slices into [`K`] bits slices - pub(super) fn xs(&self) -> &[X] { + pub(super) fn xs(&self) -> &[X] { match self { Table::First { xs, .. } => xs, _ => { @@ -540,61 +589,40 @@ mod private { pub(in super::super) trait SupportedOtherTables {} } -impl private::SupportedOtherTables for Table -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, 2) }>: Sized, +impl private::SupportedOtherTables for Table where + EvaluatableUsize<{ metadata_size_bytes(K, 2) }>: Sized { } -impl private::SupportedOtherTables for Table -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, 3) }>: Sized, +impl private::SupportedOtherTables for Table where + EvaluatableUsize<{ metadata_size_bytes(K, 3) }>: Sized { } -impl private::SupportedOtherTables for Table -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, 4) }>: Sized, +impl private::SupportedOtherTables for Table where + EvaluatableUsize<{ metadata_size_bytes(K, 4) }>: Sized { } -impl private::SupportedOtherTables for Table -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, 5) }>: Sized, +impl private::SupportedOtherTables for Table where + EvaluatableUsize<{ metadata_size_bytes(K, 5) }>: Sized { } -impl private::SupportedOtherTables for Table -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, 6) }>: Sized, +impl private::SupportedOtherTables for Table where + EvaluatableUsize<{ metadata_size_bytes(K, 6) }>: Sized { } -impl private::SupportedOtherTables for Table -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, 7) }>: Sized, +impl private::SupportedOtherTables for Table where + EvaluatableUsize<{ metadata_size_bytes(K, 7) }>: Sized { } impl Table where Self: private::SupportedOtherTables, - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, - EvaluatableUsize<{ fn_hashing_input_bytes(K) }>: Sized, { /// Creates new [`TABLE_NUMBER`] table. There also exists [`Self::create_parallel()`] that /// trades CPU efficiency and memory usage for lower latency. @@ -605,79 +633,67 @@ where where EvaluatableUsize<{ metadata_size_bytes(K, PARENT_TABLE_NUMBER) }>: Sized, { - let left_bucket = &mut cache.left_bucket; - let right_bucket = &mut cache.right_bucket; + let buckets = &mut cache.buckets; let rmap_scratch = &mut cache.rmap_scratch; let left_targets = &cache.left_targets; - // Clear input variables just in case - left_bucket.bucket_index = 0; - left_bucket.ys.clear(); - left_bucket.start_position = 0; - right_bucket.bucket_index = 1; - right_bucket.ys.clear(); - right_bucket.start_position = 0; + let mut bucket = Bucket { + bucket_index: 0, + start_position: Position::ZERO, + size: Position::ZERO, + }; + + let last_y = *last_table + .ys() + .last() + .expect("List of y values is never empty; qed"); + buckets.clear(); + buckets.reserve(1 + usize::from(last_y) / usize::from(PARAM_BC)); + last_table + .ys() + .iter() + .zip(Position::ZERO..) + .for_each(|(&y, position)| { + let bucket_index = u32::from(y) / u32::from(PARAM_BC); - let num_values = 1 << K; - let mut t_n = Vec::with_capacity(num_values); - for (position, &y) in last_table.ys().iter().enumerate() { - let bucket_index = usize::from(&y) / usize::from(PARAM_BC); - - if bucket_index == left_bucket.bucket_index { - left_bucket.ys.push(y); - continue; - } else if bucket_index == right_bucket.bucket_index { - if right_bucket.ys.is_empty() { - right_bucket.start_position = position; + if bucket_index == bucket.bucket_index { + bucket.size += Position::ONE; + return; } - right_bucket.ys.push(y); - continue; - } - t_n.extend(match_and_compute_fn( - last_table, - left_bucket, - right_bucket, - rmap_scratch, - left_targets, - )); - - if bucket_index == right_bucket.bucket_index + 1 { - // Move right bucket into left bucket while reusing existing allocations - mem::swap(left_bucket, right_bucket); - right_bucket.bucket_index = bucket_index; - right_bucket.ys.clear(); - right_bucket.start_position = position; - - right_bucket.ys.push(y); - } else { - // We have skipped some buckets, clean up both left and right buckets - left_bucket.bucket_index = bucket_index; - left_bucket.ys.clear(); - left_bucket.start_position = position; - - left_bucket.ys.push(y); - - right_bucket.bucket_index = bucket_index + 1; - right_bucket.ys.clear(); - } - } - // Iteration stopped, but we did not process contents of the last pair of buckets yet - t_n.extend(match_and_compute_fn( - last_table, - left_bucket, - right_bucket, - rmap_scratch, - left_targets, - )); + buckets.push(bucket); + + bucket = Bucket { + bucket_index, + start_position: position, + size: Position::ONE, + }; + }); + // Iteration stopped, but we did not store the last bucket yet + buckets.push(bucket); + + let num_values = 1 << K; + let mut t_n = Vec::with_capacity(num_values); + buckets + .array_windows::<2>() + .for_each(|&[left_bucket, right_bucket]| { + match_and_compute_fn::( + last_table, + left_bucket, + right_bucket, + rmap_scratch, + left_targets, + &mut t_n, + ); + }); t_n.sort_unstable(); - let mut ys = Vec::with_capacity(num_values); - let mut positions = Vec::with_capacity(num_values); - let mut metadatas = Vec::with_capacity(num_values); + let mut ys = Vec::with_capacity(t_n.len()); + let mut positions = Vec::with_capacity(t_n.len()); + let mut metadatas = Vec::with_capacity(t_n.len()); - for (y, metadata, [left_position, right_position]) in t_n { + for (y, [left_position, right_position], metadata) in t_n { ys.push(y); positions.push([left_position, right_position]); // Last table doesn't have metadata @@ -696,6 +712,7 @@ where /// Almost the same as [`Self::create()`], but uses parallelism internally for better /// performance (though not efficiency of CPU and memory usage), if you create multiple tables /// in parallel, prefer [`Self::create()`] for better overall performance. + // TODO: Cache more allocations in this function to improve performance further #[cfg(any(feature = "parallel", test))] pub(super) fn create_parallel( last_table: &Table, @@ -704,92 +721,94 @@ where where EvaluatableUsize<{ metadata_size_bytes(K, PARENT_TABLE_NUMBER) }>: Sized, { - let left_bucket = &mut cache.left_bucket; - let right_bucket = &mut cache.right_bucket; + let buckets = &mut cache.buckets; let left_targets = &cache.left_targets; - // Clear input variables just in case - left_bucket.bucket_index = 0; - left_bucket.ys.clear(); - left_bucket.start_position = 0; - right_bucket.bucket_index = 1; - right_bucket.ys.clear(); - right_bucket.start_position = 0; - - // Experimentally found that this value seems reasonable - let mut buckets = Vec::with_capacity(usize::from(PARAM_BC) / (1 << PARAM_EXT) * 3); - for (position, &y) in last_table.ys().iter().enumerate() { - let bucket_index = usize::from(&y) / usize::from(PARAM_BC); - - if bucket_index == left_bucket.bucket_index { - left_bucket.ys.push(y); - continue; - } else if bucket_index == right_bucket.bucket_index { - if right_bucket.ys.is_empty() { - right_bucket.start_position = position; + let mut bucket = Bucket { + bucket_index: 0, + start_position: Position::ZERO, + size: Position::ZERO, + }; + + let last_y = *last_table + .ys() + .last() + .expect("List of y values is never empty; qed"); + buckets.clear(); + buckets.reserve(1 + usize::from(last_y) / usize::from(PARAM_BC)); + last_table + .ys() + .iter() + .zip(Position::ZERO..) + .for_each(|(&y, position)| { + let bucket_index = u32::from(y) / u32::from(PARAM_BC); + + if bucket_index == bucket.bucket_index { + bucket.size += Position::ONE; + return; } - right_bucket.ys.push(y); - continue; - } - buckets.push(left_bucket.clone()); + buckets.push(bucket); - if bucket_index == right_bucket.bucket_index + 1 { - // Move right bucket into left bucket while reusing existing allocations - mem::swap(left_bucket, right_bucket); - right_bucket.bucket_index = bucket_index; - right_bucket.ys.clear(); - right_bucket.start_position = position; + bucket = Bucket { + bucket_index, + start_position: position, + size: Position::ONE, + }; + }); + // Iteration stopped, but we did not store the last bucket yet + buckets.push(bucket); - right_bucket.ys.push(y); - } else { - // We have skipped some buckets, clean up both left and right buckets - left_bucket.bucket_index = bucket_index; - left_bucket.ys.clear(); - left_bucket.start_position = position; + let (entries_sender, entries_receiver) = mpsc::sync_channel(1); - left_bucket.ys.push(y); + let t_n_handle = std::thread::spawn(move || { + let num_values = 1 << K; + let mut t_n = Vec::with_capacity(num_values); - right_bucket.bucket_index = bucket_index + 1; - right_bucket.ys.clear(); + while let Ok(entries) = entries_receiver.recv() { + t_n.extend(entries); } - } - // Iteration stopped, but we did not store the last two buckets yet - buckets.push(left_bucket.clone()); - buckets.push(right_bucket.clone()); - - let num_values = 1 << K; - let mut t_n = Vec::with_capacity(num_values); - t_n.par_extend(buckets.par_windows(2).flat_map_iter(|buckets| { - match_and_compute_fn( - last_table, - &buckets[0], - &buckets[1], - &mut Vec::new(), - left_targets, - ) - .collect::>() - })); - // Drop in thread pool to return faster from here - rayon::spawn(move || { - drop(buckets); + t_n }); + buckets + .par_windows(2) + .fold( + || (Vec::new(), Vec::new()), + |(mut entries, mut rmap_scratch), buckets| { + match_and_compute_fn::( + last_table, + buckets[0], + buckets[1], + &mut rmap_scratch, + left_targets, + &mut entries, + ); + (entries, rmap_scratch) + }, + ) + .for_each(move |(entries, _rmap_scratch)| { + entries_sender + .send(entries) + .expect("Receiver is waiting until sender is exhausted; qed"); + }); + + let mut t_n = t_n_handle.join().expect("Not joining itself; qed"); t_n.par_sort_unstable(); - let mut ys = Vec::with_capacity(num_values); - let mut positions = Vec::with_capacity(num_values); - let mut metadatas = Vec::with_capacity(num_values); + let mut ys = vec![Default::default(); t_n.len()]; + let mut positions = vec![Default::default(); t_n.len()]; + let mut metadatas = vec![Default::default(); t_n.len()]; - for (y, metadata, [left_position, right_position]) in t_n { - ys.push(y); - positions.push([left_position, right_position]); - // Last table doesn't have metadata - if metadata_size_bits(K, TABLE_NUMBER) > 0 { - metadatas.push(metadata); - } - } + // Going in parallel saves a bit of time + t_n.into_par_iter() + .zip(ys.par_iter_mut().zip(&mut positions).zip(&mut metadatas)) + .for_each(|(input, output)| { + *output.0 .0 = input.0; + *output.0 .1 = input.1; + *output.1 = input.2; + }); Self::Other { ys, @@ -801,19 +820,17 @@ where impl Table where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, { /// All `y`s as [`BitSlice`], for individual `x`s needs to be slices into [`K`] bits slices - pub(super) fn ys(&self) -> &[Y] { + pub(super) fn ys(&self) -> &[Y] { let (Table::First { ys, .. } | Table::Other { ys, .. }) = self; ys } /// Returns `None` on invalid position or first table, `Some(left_position, right_position)` in /// previous table on success - pub(super) fn position(&self, position: Position) -> Option<[Position; 2]> { + pub(super) fn position(&self, position: Position) -> Option<[Position; 2]> { match self { Table::First { .. } => None, Table::Other { positions, .. } => positions.get(usize::from(position)).copied(), @@ -821,23 +838,10 @@ where } /// Returns `None` on invalid position or for table number 7 - pub(super) fn metadata(&self, position: usize) -> Option> { + pub(super) fn metadata(&self, position: Position) -> Option> { match self { - Table::First { xs, .. } => { - // This is a bit awkward since we store `K` bits in each `x`, but we also - // technically have `metadata_size_bits` function that is supposed to point to the - // number of bytes metadata has for table 1. They are the same and trying to slice - // it will cause overhead. Use assertion here instead that will be removed by - // compiler and not incurring any overhead. - assert_eq!(metadata_size_bits(K, TABLE_NUMBER), usize::from(K)); - - xs.get(position).map(|x| { - let mut metadata = Metadata::default(); - metadata.copy_bits_from(x, 0_usize, K, 0_usize); - metadata - }) - } - Table::Other { metadatas, .. } => metadatas.get(position).copied(), + Table::First { xs, .. } => xs.get(usize::from(position)).map(|&x| Metadata::from(x)), + Table::Other { metadatas, .. } => metadatas.get(usize::from(position)).copied(), } } } diff --git a/crates/subspace-proof-of-space/src/chiapos/table/tests.rs b/crates/subspace-proof-of-space/src/chiapos/table/tests.rs index b6eacb85d11..65e3b704998 100644 --- a/crates/subspace-proof-of-space/src/chiapos/table/tests.rs +++ b/crates/subspace-proof-of-space/src/chiapos/table/tests.rs @@ -2,13 +2,14 @@ //! https://github.com/Chia-Network/chiapos/blob/a2049c5367fe60930533a995f7ffded538f04dc4/tests/test.cpp use crate::chiapos::constants::{PARAM_B, PARAM_BC, PARAM_C, PARAM_EXT}; -use crate::chiapos::table::types::{Metadata, X, Y}; +use crate::chiapos::table::types::{Metadata, Position, X, Y}; use crate::chiapos::table::{ - calculate_left_targets, compute_f1, compute_fn, find_matches, fn_hashing_input_bytes, - metadata_size_bytes, partial_y, y_size_bytes, + calculate_left_targets, compute_f1, compute_f1_simd, compute_fn, find_matches, + metadata_size_bytes, partial_y, COMPUTE_F1_SIMD_FACTOR, }; use crate::chiapos::utils::EvaluatableUsize; use crate::chiapos::Seed; +use bitvec::prelude::*; use std::collections::BTreeMap; /// Chia does this for some reason 🤷‍ @@ -18,53 +19,55 @@ fn to_chia_seed(seed: &Seed) -> Seed { chia_seed } -#[cfg(target_pointer_width = "64")] #[test] -fn test_compute_f1_k35() { - const K: u8 = 35; +fn test_compute_f1_k25() { + const K: u8 = 25; let seed = to_chia_seed(&[ 0, 2, 3, 4, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 41, 5, 6, 7, 8, 9, 10, 11, 12, 13, 11, 15, 16, ]); - let xs = [525, 526, 625_usize]; - let expected_ys = [948_868_477_184, 2_100_559_512_384, 1_455_233_158_208_usize]; + let xs = [525, 526, 625_u32]; + let expected_ys = [2_016_650_816, 2_063_162_112, 1_930_299_520_u32]; for (x, expected_y) in xs.into_iter().zip(expected_ys) { + let x = X::from(x); let (partial_y, partial_y_offset) = partial_y::(seed, x); - let y = compute_f1::(X::from(x), &partial_y, partial_y_offset); - let y = usize::from(&y); - assert_eq!(y, expected_y); + let y = compute_f1::(x, &partial_y, partial_y_offset); + assert_eq!(y, Y::from(expected_y)); + + // Make sure SIMD matches non-SIMD version + let mut partial_ys = [0; K as usize * COMPUTE_F1_SIMD_FACTOR / u8::BITS as usize]; + partial_ys.view_bits_mut::()[..usize::from(K)] + .copy_from_bitslice(&partial_y.view_bits()[partial_y_offset..][..usize::from(K)]); + let y = compute_f1_simd::([x; COMPUTE_F1_SIMD_FACTOR], &partial_ys); + assert_eq!(y[0], Y::from(expected_y)); } } -#[cfg(target_pointer_width = "64")] #[test] -fn test_compute_f1_k32() { - const K: u8 = 32; +fn test_compute_f1_k22() { + const K: u8 = 22; let seed = to_chia_seed(&[ 0, 2, 3, 4, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 41, 5, 6, 7, 8, 9, 10, 11, 12, 13, 11, 15, 16, ]); - let xs = [ - 192_837_491, - 192_837_491 + 1, - 192_837_491 + 2, - 192_837_491 + 255_usize, - ]; - let expected_ys = [ - 206_843_700_930, - 32_315_542_210, - 156_034_446_146, - 128_694_732_738_usize, - ]; + let xs = [1_837_491, 1_837_491 + 1, 1_837_491 + 2, 1_837_491 + 255_u32]; + let expected_ys = [105_738_140, 192_213_404, 64_977_628, 91_711_644_u32]; for (x, expected_y) in xs.into_iter().zip(expected_ys) { + let x = X::from(x); let (partial_y, partial_y_offset) = partial_y::(seed, x); - let y = compute_f1::(X::from(x), &partial_y, partial_y_offset); - let y = usize::from(&y); - assert_eq!(y, expected_y); + let y = compute_f1::(x, &partial_y, partial_y_offset); + assert_eq!(y, Y::from(expected_y)); + + // Make sure SIMD matches non-SIMD version + let mut partial_ys = [0; K as usize * COMPUTE_F1_SIMD_FACTOR / u8::BITS as usize]; + partial_ys.view_bits_mut::()[..usize::from(K)] + .copy_from_bitslice(&partial_y.view_bits()[partial_y_offset..][..usize::from(K)]); + let y = compute_f1_simd::([x; COMPUTE_F1_SIMD_FACTOR], &partial_ys); + assert_eq!(y[0], Y::from(expected_y)); } } @@ -104,47 +107,49 @@ fn test_matches() { 204, 10, 9, 10, 11, 129, 139, 171, 15, 18, ]); - let mut buckets = BTreeMap::>::new(); - let mut x = 0; + let mut bucket_ys = BTreeMap::>::new(); + let mut x = X::from(0); for _ in 0..=1 << (K - 4) { for _ in 0..16 { let (partial_y, partial_y_offset) = partial_y::(seed, x); - let y = compute_f1::(X::from(x), &partial_y, partial_y_offset); - let bucket_index = usize::from(&y) / usize::from(PARAM_BC); + let y = compute_f1::(x, &partial_y, partial_y_offset); + let bucket_index = usize::from(y) / usize::from(PARAM_BC); - buckets.entry(bucket_index).or_default().push(y); + bucket_ys.entry(bucket_index).or_default().push(y); - if x + 1 > (1 << K) - 1 { + if x + X::from(1) > X::from((1 << K) - 1) { break; } - x += 1; + x += X::from(1); } - if x + 1 > (1 << K) - 1 { + if x + X::from(1) > X::from((1 << K) - 1) { break; } } let left_targets = calculate_left_targets(); let mut rmap_scratch = Vec::new(); - let buckets = buckets.into_values().collect::>(); + let bucket_ys = bucket_ys.into_values().collect::>(); let mut total_matches = 0_usize; - for [mut left_bucket, mut right_bucket] in buckets.array_windows::<2>().cloned() { - left_bucket.sort_unstable(); - left_bucket.reverse(); - right_bucket.sort_unstable(); - right_bucket.reverse(); - - let matches = find_matches::( - &left_bucket, - &right_bucket, + for [mut left_bucket_ys, mut right_bucket_ys] in bucket_ys.array_windows::<2>().cloned() { + left_bucket_ys.sort_unstable(); + left_bucket_ys.reverse(); + right_bucket_ys.sort_unstable(); + right_bucket_ys.reverse(); + + let matches = find_matches( + &left_bucket_ys, + Position::ZERO, + &right_bucket_ys, + Position::ZERO, &mut rmap_scratch, &left_targets, ); for m in matches.unwrap() { - let yl = usize::from(left_bucket.get(m.left_index).unwrap()); - let yr = usize::from(right_bucket.get(m.right_index).unwrap()); + let yl = usize::from(*left_bucket_ys.get(usize::from(m.left_position)).unwrap()); + let yr = usize::from(*right_bucket_ys.get(usize::from(m.right_position)).unwrap()); assert!(check_match(yl, yr)); total_matches += 1; @@ -162,29 +167,23 @@ fn test_matches() { } fn verify_fn( - left_metadata: usize, - right_metadata: usize, - y: usize, - y_output_expected: usize, - metadata_expected: usize, + left_metadata: u128, + right_metadata: u128, + y: u32, + y_output_expected: u32, + metadata_expected: u128, ) where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, - EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, PARENT_TABLE_NUMBER) }>: Sized, - EvaluatableUsize<{ fn_hashing_input_bytes(K) }>: Sized, + EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, { let (y_output, metadata) = compute_fn::( - Y::::from(y), - Metadata::::from(left_metadata), - Metadata::::from(right_metadata), + Y::from(y), + Metadata::from(left_metadata), + Metadata::from(right_metadata), ); - let y_output = usize::from(&y_output); - assert_eq!(y_output, y_output_expected); + assert_eq!(y_output, Y::from(y_output_expected)); if metadata_expected != 0 { - assert_eq!( - metadata, - Metadata::::from(metadata_expected) - ); + assert_eq!(metadata, Metadata::from(metadata_expected)); } } diff --git a/crates/subspace-proof-of-space/src/chiapos/table/types.rs b/crates/subspace-proof-of-space/src/chiapos/table/types.rs index 4526bf21c06..d6495cc41ad 100644 --- a/crates/subspace-proof-of-space/src/chiapos/table/types.rs +++ b/crates/subspace-proof-of-space/src/chiapos/table/types.rs @@ -1,620 +1,111 @@ -use crate::chiapos::table::{ - metadata_size_bits, metadata_size_bytes, x_size_bytes, y_size_bits, y_size_bytes, -}; +use crate::chiapos::constants::PARAM_EXT; +use crate::chiapos::table::metadata_size_bytes; use crate::chiapos::utils::EvaluatableUsize; -use bitvec::prelude::*; -use core::ops::Deref; -use core::{fmt, mem}; -use std::cmp::Ordering; +use core::iter::Step; +use core::mem; +use core::ops::Range; +use derive_more::{Add, AddAssign, From, Into}; -/// Copy `size` bits from `source` starting at `source_offset` into `destination` at -/// `destination_offset` -/// -/// ## Panics -/// Panics if `source_offset > 7` or `destination_offset > 7`. -/// Panics if `source_offset + size > source * u8::BITS` or -/// `destination_offset + size > destination * u8::BITS`. -// TODO: Should benefit from SIMD instructions -// Inlining helps compiler remove most of the logic in this function -#[inline(always)] -#[track_caller] -fn copy_bits( - source: &[u8], - source_offset: usize, - destination: &mut [u8], - destination_offset: usize, - size: usize, -) { - const BYTE_SIZE: usize = u8::BITS as usize; - - // TODO: Make it skip bytes automatically - assert!(source_offset <= 7, "source_offset {source_offset} > 7"); - assert!(destination_offset <= 7, "source_offset {source_offset} > 7"); - // Source length in bytes - let source_len = source.len(); - // Destination length in bytes - let destination_len = destination.len(); - assert!( - source_offset + size <= source_len * BYTE_SIZE, - "source_offset {source_offset} + size {size} > source.len() {source_len} * BYTE_SIZE {BYTE_SIZE}", - ); - assert!( - destination_offset + size <= destination_len * BYTE_SIZE, - "destination_offset {destination_offset} + size {size} > destination.len() {destination_len} * BYTE_SIZE {BYTE_SIZE}", - ); - - // This number of bits in the last destination byte will be composed from source bits - let last_byte_bits_from_source = { - let last_byte_bits_from_source = (destination_offset + size) % BYTE_SIZE; - if last_byte_bits_from_source == 0 { - BYTE_SIZE - } else { - last_byte_bits_from_source - } - }; - - // Copy and shift bits left or right to match desired `OUT_OFFSET` - match destination_offset.cmp(&source_offset) { - // Strategy in case we shift bits left - // - // We start with the first byte that we compose into the final form form its original bits - // that do not need to be updated and bits from the source that need to be moved into it. - // - // Observation here is that source is potentially one byte longer than destination, so by - // processing the first byte separately we can continue iterating over source bytes with - // offset by 1 byte to the right with previous byte in destination allows us to move forward - // without touching previous bytes in the process. - // - // If length of source and destination bytes is not the same we skip very last iteration in - // general way. This is because last destination byte might have bits that need to be - // preserved and we don't want to read destination unnecessarily here, so we do another pass - // afterwards with destination bit preserved. - // - // If length of source and destination are the same, we iterate all the way to the end (but - // we still skip one destination byte due to iterating over source and destination bytes - // with offset to each other). After iteration the only thing left is just to take - // accumulator and apply to the last destination byte (again, the only byte we actually need - // to read). - Ordering::Less => { - // Offset between source and destination - let offset = source_offset - destination_offset; - // Preserve first bits from destination that must not be changed in accumulator - let mut left_acc = if destination_offset == 0 { - // Byte will be fully overridden by the source - 0 - } else { - destination[0] & (u8::MAX << (BYTE_SIZE - destination_offset)) - }; - // Add bits from the first source byte to the accumulator - left_acc |= (source[0] << offset) & (u8::MAX >> destination_offset); - - // Compose destination bytes, skip the first source byte since we have already processed - // it above. - // - // Note that on every step source byte is to the right of the destination, skip last - // pair such that we can preserve trailing bits of the destination unchanged - // (this is an optimization, it allows us to not read `destination` in this loop at all) - for (source, destination) in source[1..] - .iter() - .zip(destination.iter_mut()) - .rev() - .skip(if source_len != destination_len { 1 } else { 0 }) - .rev() - { - // Take bits that were be moved out of the byte boundary and add the left side from - // accumulator - *destination = left_acc | (*source >> (BYTE_SIZE - offset)); - // Store left side of the source bits in the accumulator that will be applied to the - // next byte - left_acc = *source << offset; - } - - // Clear bits in accumulator that must not be copied into destination - let left_acc = left_acc & (u8::MAX << (BYTE_SIZE - last_byte_bits_from_source)); - - if source_len != destination_len { - if let Some((source, destination)) = - source[1..].iter().zip(destination.iter_mut()).last() - { - let preserved_bits = if last_byte_bits_from_source == BYTE_SIZE { - // Byte will be fully overridden by the source - 0 - } else { - *destination & (u8::MAX >> last_byte_bits_from_source) - }; - // Take bits that were be moved out of the byte boundary - let source_bits = (*source >> (BYTE_SIZE - offset)) - & (u8::MAX << (BYTE_SIZE - last_byte_bits_from_source)); - // Combine last accumulator bits (left most bits) with source bits and preserved - // bits in destination - *destination = left_acc | source_bits | preserved_bits; - } - } else { - // Shift source bits to the right and remove trailing bits that we'll get from - // destination, this is the middle part of the last destination byte - let source_bits = (source[source_len - 1] >> (BYTE_SIZE - offset)) - & (u8::MAX << (BYTE_SIZE - last_byte_bits_from_source)); - // Bits preserved in destination - let preserved_bits = if last_byte_bits_from_source == BYTE_SIZE { - // Byte will be fully overridden by the source - 0 - } else { - destination[destination_len - 1] & (u8::MAX >> last_byte_bits_from_source) - }; - // Combine last accumulator bits (left most bits) with source bits and preserved - // bits in destination - destination[destination_len - 1] = left_acc | source_bits | preserved_bits; - } - } - // Strategy here is much simpler: copy first and last bytes while accounting for bits that - // should be preserved in destination, otherwise do bulk copy - Ordering::Equal => { - if destination_offset > 0 { - // Clear bits of the first byte that will be overridden by bits from source - destination[0] &= u8::MAX << ((BYTE_SIZE - destination_offset) % BYTE_SIZE); - // Add bits to the first byte from source - destination[0] |= source[0] & (u8::MAX >> destination_offset); - } else { - destination[0] = source[0]; - } - - // Copy some bytes in bulk - if destination_len > 2 { - // Copy everything except first and last bytes - destination[1..destination_len - 1] - .copy_from_slice(&source[1..destination_len - 1]); - } - - if last_byte_bits_from_source == BYTE_SIZE { - destination[destination_len - 1] = source[destination_len - 1]; - } else { - // Clear bits of the last byte that will be overridden by bits from source - destination[destination_len - 1] &= u8::MAX >> last_byte_bits_from_source; - // Add bits to the last byte from source - destination[destination_len - 1] |= source[destination_len - 1] - & (u8::MAX << (BYTE_SIZE - last_byte_bits_from_source)); - } - } - // Strategy in case we shift bits right - // - // We start with the first byte that we compose into the final form form its original bits - // that do not need to be updated and bits from the source that need to be moved into it. - // - // Here destination is potentially one byte longer than source and we still need to preserve - // last destination bits that should not have been modified. - // - // If length of source and destination bytes is the same, we skip very last iteration. That - // is because it might have bits that need to be preserved and we don't want to read - // destination unnecessarily here, so we do another pass afterwards with destination bit - // preserved. - // - // If length of source and destination are not the same, we iterate all the way to the end. - // After iteration the only thing left is just to take accumulator and apply to the last - // destination byte (again, the only byte we actually need to read). - Ordering::Greater => { - // Offset between source and destination - let offset = destination_offset - source_offset; - { - // Bits preserved in destination - let preserved_bits = destination[0] & (u8::MAX << (BYTE_SIZE - destination_offset)); - // Source bits that will be stored in the first byte - let source_bits = (source[0] >> offset) & (u8::MAX >> destination_offset); - // Combine preserved bits and source bits into the first destination byte - destination[0] = preserved_bits | source_bits; - } - // Store bits from first source byte that didn't fit into first destination byte into - // the accumulator - let mut left_acc = (source[0] & (u8::MAX >> source_offset)) << (BYTE_SIZE - offset); - - // Compose destination bytes, skip the first pair since we have already processed - // them above. - // - // Note that we skip last pair in case source and destination are the same, such that we - // can preserve trailing bits of the destination unchanged (this is an optimization, it - // allows us to not read `destination` in this loop at all) - for (source, destination) in source - .iter() - .zip(destination.iter_mut()) - .skip(1) - .rev() - .skip(if source_len == destination_len { 1 } else { 0 }) - .rev() - { - // Shift source bits to the right and add the left side from accumulator - *destination = left_acc | (*source >> offset); - // Take bits that were moved out of the boundary into accumulator that will be - // applied to the next byte - left_acc = *source << (BYTE_SIZE - offset); - } - - // Clear bits in accumulator that must not be copied into destination - let left_acc = left_acc & (u8::MAX << (BYTE_SIZE - last_byte_bits_from_source)); - - if source_len == destination_len { - // In case we skipped last pair above, process it here - if let Some((source, destination)) = - source.iter().zip(destination.iter_mut()).skip(1).last() - { - let preserved_bits = if last_byte_bits_from_source == BYTE_SIZE { - // Byte will be fully overridden by the source - 0 - } else { - *destination & (u8::MAX >> last_byte_bits_from_source) - }; - // Shift source bits to the right and clear bits that correspond to preserved - // bits - let source_bits = - (*source >> offset) & (u8::MAX << (BYTE_SIZE - last_byte_bits_from_source)); - // Combine last accumulator bits (left most bits) with source bits and preserved - // bits in destination - *destination = left_acc | source_bits | preserved_bits; - } - } else { - // Bits preserved in destination - let preserved_bits = - destination[destination_len - 1] & (u8::MAX >> last_byte_bits_from_source); - // Combine last accumulator bits (left most bits) with preserved bits in destination - destination[destination_len - 1] = left_acc | preserved_bits; - } - } - } -} - -/// Container with data source and information about contents -pub(in super::super) struct CopyBitsSourceData<'a> { - pub(in super::super) bytes: &'a [u8], - /// Where do bits of useful data start - pub(in super::super) bit_offset: usize, - /// Size in bits - pub(in super::super) bit_size: usize, -} - -pub(in super::super) trait CopyBitsSource { - fn data(&self) -> CopyBitsSourceData<'_>; -} - -pub(in super::super) trait CopyBitsDestination { - /// Where do bits of useful data start - const DATA_OFFSET: usize; - - /// Underlying data container - fn data_mut(&mut self) -> &mut [u8]; - - /// Size in bits - fn bits(&self) -> usize; - - /// Copy `size` bits from [`Source`] bits starting at `source_offset` and write at - /// `destination_offset` into this data structure. Contents of bits after `DESTINATION_OFFSET` - /// is not defined. - /// - /// ## Panics - /// Panics if `SOURCE_OFFSET + SIZE` is more bits than [`Source`] has or - /// `DESTINATION_OFFSET + SIZE` is more bits than [`Self::bits()`], higher level code must ensure - /// this never happens, method is not exposed outside of this crate and crate boundaries are - /// supposed to protect this invariant. Exposing error handling from here will be too noisy and - /// seemed not worth it. - // Inlining helps compiler remove most of the logic in this function - #[inline(always)] - fn copy_bits_from( - &mut self, - source: &Source, - source_offset: SourceOffset, - size: Size, - destination_offset: DestinationOffset, - ) where - Source: CopyBitsSource + ?Sized, - usize: From, - usize: From, - usize: From, - { - let source_offset = usize::from(source_offset); - let size = usize::from(size); - let destination_offset = usize::from(destination_offset); - let source_data = source.data(); - - assert!(source_offset + size <= source_data.bit_size); - assert!(destination_offset + size <= self.bits()); - - // Which byte to start reading bytes at, taking into account where actual data bits start - // and desired offset - let read_byte_offset = (source_data.bit_offset + source_offset) / u8::BITS as usize; - // Which bit in read bytes is the first one we care about - let read_bit_offset = (source_data.bit_offset + source_offset) % u8::BITS as usize; - // How many bytes to read from source, while taking into account the fact desired source - // offset - let bytes_to_read = (read_bit_offset + size).div_ceil(u8::BITS as usize); - // Source bytes at which we have `SIZE` bits of data starting at `read_bit_offset` bit - let source_bytes = &source_data.bytes[read_byte_offset..][..bytes_to_read]; - - // Which byte to start writing bytes at, taking into account where actual data bits start - // and desired offset - let write_byte_offset = (Self::DATA_OFFSET + destination_offset) / u8::BITS as usize; - // Which bit in destination is the first bit at which source should actually be written, - // bits before that must be preserved - let write_bit_offset = (Self::DATA_OFFSET + destination_offset) % u8::BITS as usize; - // How many bytes to write into destination, while taking into account the fact desired - // destination offset - let bytes_to_write = (write_bit_offset + size).div_ceil(u8::BITS as usize); - // Destination bytes at which we have `SIZE` bits to write starting at `write_bit_offset` - let destination_bytes = &mut self.data_mut()[write_byte_offset..][..bytes_to_write]; - - // Defensive checks in debug builds before we have robust test for bit copying - #[cfg(debug_assertions)] - let first_destination_bits = - destination_bytes.view_bits::()[..write_bit_offset].to_bitvec(); - #[cfg(debug_assertions)] - let last_destination_bits = - destination_bytes.view_bits::()[write_bit_offset + size..].to_bitvec(); - copy_bits( - source_bytes, - read_bit_offset, - destination_bytes, - write_bit_offset, - size, - ); - #[cfg(debug_assertions)] - assert_eq!( - first_destination_bits, - destination_bytes.view_bits::()[..write_bit_offset].to_bitvec(), - "Implementation bug in subspace-proof-of-space bit copy, please report to Nazar \ - immediately with reproduction steps" - ); - #[cfg(debug_assertions)] - assert_eq!( - destination_bytes.view_bits::()[write_bit_offset..][..size].to_bitvec(), - source_bytes.view_bits::()[read_bit_offset..][..size].to_bitvec(), - "Implementation bug in subspace-proof-of-space bit copy, please report to Nazar \ - immediately with reproduction steps" - ); - #[cfg(debug_assertions)] - assert_eq!( - last_destination_bits, - destination_bytes.view_bits::()[write_bit_offset + size..].to_bitvec(), - "Implementation bug in subspace-proof-of-space bit copy, please report to Nazar \ - immediately with reproduction steps" - ); - } -} - -impl CopyBitsSource for T -where - T: AsRef<[u8]> + ?Sized, -{ - fn data(&self) -> CopyBitsSourceData<'_> { - CopyBitsSourceData { - bytes: self.as_ref(), - bit_offset: 0, - bit_size: self.as_ref().len() * u8::BITS as usize, - } - } -} - -impl CopyBitsDestination for T -where - T: AsRef<[u8]> + AsMut<[u8]> + ?Sized, -{ - const DATA_OFFSET: usize = 0; - - fn data_mut(&mut self) -> &mut [u8] { - self.as_mut() - } - - fn bits(&self) -> usize { - self.as_ref().len() * u8::BITS as usize - } -} - -/// Wrapper data structure around bits of `x` values, stores data in the last bits of internal array -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] +/// Stores data in lower bits +#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, From, Into, Add, AddAssign)] #[repr(transparent)] -pub(in super::super) struct X([u8; x_size_bytes(K)]) -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized; +pub(in super::super) struct X(u32); -impl Default for X -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - fn default() -> Self { - Self([0; x_size_bytes(K)]) +impl Step for X { + fn steps_between(start: &Self, end: &Self) -> Option { + u32::steps_between(&start.0, &end.0) } -} -impl fmt::Debug for X -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("X") - .field(&&self.0.view_bits::()[Self::BYTES * u8::BITS as usize - Self::BITS..]) - .finish() + fn forward_checked(start: Self, count: usize) -> Option { + u32::forward_checked(start.0, count).map(Self) } -} -impl From for X -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - /// Will silently drop data if [`K`] is too small to store useful data in [`usize`], higher - /// level code must ensure this never happens, method is not exposed outside of this crate and - /// crate boundaries are supposed to protect this invariant. Exposing error handling from here - /// will be too noisy and seemed not worth it. - fn from(value: usize) -> Self { - let mut output = [0; x_size_bytes(K)]; - // Copy last bytes - output.copy_from_slice(&value.to_be_bytes()[mem::size_of::() - Self::BYTES..]); - Self(output) + fn backward_checked(start: Self, count: usize) -> Option { + u32::backward_checked(start.0, count).map(Self) } } -impl From<&X> for usize -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - /// Panics if conversion to [`usize`] fails, higher level code must ensure this never happens, - /// method is not exposed outside of this crate and crate boundaries are supposed to protect - /// this invariant. Exposing error handling from here will be too noisy and seemed not worth it. - fn from(value: &X) -> Self { - let mut output = 0_usize.to_be_bytes(); - output[mem::size_of::() - x_size_bytes(K)..].copy_from_slice(&value.0); - usize::from_be_bytes(output) +impl From for u64 { + fn from(value: X) -> Self { + Self::from(value.0) } } -impl CopyBitsSource for X -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - fn data(&self) -> CopyBitsSourceData<'_> { - CopyBitsSourceData { - bytes: &self.0, - bit_offset: Self::DATA_OFFSET, - bit_size: Self::BITS, - } +impl From for u128 { + fn from(value: X) -> Self { + Self::from(value.0) } } -impl CopyBitsDestination for X -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - const DATA_OFFSET: usize = Self::DATA_OFFSET; - - fn data_mut(&mut self) -> &mut [u8] { - &mut self.0 - } - - fn bits(&self) -> usize { - Self::BITS +impl From for usize { + fn from(value: X) -> Self { + value.0 as Self } } -impl X -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - /// Size in bytes - const BYTES: usize = x_size_bytes(K); - /// Size in bits - const BITS: usize = K as usize; - /// Where do bits of useful data start - const DATA_OFFSET: usize = Self::BYTES * u8::BITS as usize - Self::BITS; +impl X { + /// All possible values of `x` for given `K` + pub(in super::super) const fn all() -> Range { + Self(0)..Self(1 << K) + } } -/// Wrapper data structure around bits of `y` values, stores data in the last bits of internal -/// array -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] +/// Stores data in lower bits +#[derive(Debug, Default, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, From, Into)] #[repr(transparent)] -pub(in super::super) struct Y([u8; y_size_bytes(K)]) -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized; - -impl Default for Y -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - fn default() -> Self { - Self([0; y_size_bytes(K)]) - } -} +pub(in super::super) struct Y(u32); -impl fmt::Debug for Y -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Y").field(&self.deref()).finish() +impl From for u128 { + fn from(value: Y) -> Self { + Self::from(value.0) } } -// TODO: Implement bit matching and remove this -impl Deref for Y -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - type Target = BitSlice; - - fn deref(&self) -> &Self::Target { - &self.0.view_bits::()[Self::DATA_OFFSET..] +impl From for usize { + fn from(value: Y) -> Self { + value.0 as Self } } -impl CopyBitsSource for Y -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - fn data(&self) -> CopyBitsSourceData<'_> { - CopyBitsSourceData { - bytes: &self.0, - bit_offset: Self::DATA_OFFSET, - bit_size: Self::BITS, - } +impl Y { + pub(in super::super) const fn first_k_bits(self) -> u32 { + self.0 >> PARAM_EXT as usize } } -impl CopyBitsDestination for Y -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - const DATA_OFFSET: usize = Self::DATA_OFFSET; +#[derive( + Debug, Default, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, From, Into, Add, AddAssign, +)] +#[repr(transparent)] +pub(in super::super) struct Position(u32); - fn data_mut(&mut self) -> &mut [u8] { - &mut self.0 +impl Step for Position { + fn steps_between(start: &Self, end: &Self) -> Option { + u32::steps_between(&start.0, &end.0) } - fn bits(&self) -> usize { - Self::BITS + fn forward_checked(start: Self, count: usize) -> Option { + u32::forward_checked(start.0, count).map(Self) } -} -#[cfg(test)] -impl From for Y -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - /// Will silently drop data if [`K`] is too small to store useful data in [`usize`], higher - /// level code must ensure this never happens, method is not exposed outside of this crate and - /// crate boundaries are supposed to protect this invariant. Exposing error handling from here - /// will be too noisy and seemed not worth it. - fn from(value: usize) -> Self { - let mut output = Self::default(); - // Copy last bytes from big-endian `value` into `Y` - output - .0 - .copy_from_slice(&value.to_be_bytes()[mem::size_of::() - Self::BYTES..]); - output + fn backward_checked(start: Self, count: usize) -> Option { + u32::backward_checked(start.0, count).map(Self) } } -impl From<&Y> for usize -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - /// Panics if conversion to [`usize`] fails, higher level code must ensure this never happens, - /// method is not exposed outside of this crate and crate boundaries are supposed to protect - /// this invariant. Exposing error handling from here will be too noisy and seemed not worth it. - fn from(value: &Y) -> Self { - let mut output = 0_usize.to_be_bytes(); - output[mem::size_of::() - y_size_bytes(K)..].copy_from_slice(&value.0); - usize::from_be_bytes(output) +impl From for usize { + fn from(value: Position) -> Self { + value.0 as Self } } -impl Y -where - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, -{ - /// Size in bytes - const BYTES: usize = y_size_bytes(K); - /// Size in bits - const BITS: usize = y_size_bits(K); - /// Where do bits of useful data start - const DATA_OFFSET: usize = Self::BYTES * u8::BITS as usize - Self::BITS; +impl Position { + pub(in super::super) const ZERO: Self = Self(0); + pub(in super::super) const ONE: Self = Self(1); } -/// Wrapper data structure around bits of `metadata` values, stores data in the last bits of -/// internal array -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] +/// Stores data in lower bits +#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] #[repr(transparent)] pub(in super::super) struct Metadata( [u8; metadata_size_bytes(K, TABLE_NUMBER)], @@ -631,129 +122,39 @@ where } } -impl fmt::Debug for Metadata +impl From> for u128 where EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Metadata") - .field(&&self.0.view_bits::()[Self::DATA_OFFSET..]) - .finish() - } -} + fn from(value: Metadata) -> Self { + // `*_be_bytes()` is used such that `Ord`/`PartialOrd` impl works as expected + let mut output = 0u128.to_be_bytes(); + output[mem::size_of::() - value.0.len()..].copy_from_slice(&value.0); -impl CopyBitsSource for Metadata -where - EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, -{ - fn data(&self) -> CopyBitsSourceData<'_> { - CopyBitsSourceData { - bytes: &self.0, - bit_offset: Self::DATA_OFFSET, - bit_size: Self::BITS, - } + Self::from_be_bytes(output) } } -impl CopyBitsDestination for Metadata +impl From for Metadata where EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, { - const DATA_OFFSET: usize = Self::DATA_OFFSET; - - fn data_mut(&mut self) -> &mut [u8] { - &mut self.0 - } - - fn bits(&self) -> usize { - Self::BITS + /// If used incorrectly, will truncate information, it is up to implementation to ensure `u128` + /// only contains data in lower bits and fits into internal byte array of `Metadata` + fn from(value: u128) -> Self { + Self( + value.to_be_bytes()[mem::size_of::() - metadata_size_bytes(K, TABLE_NUMBER)..] + .try_into() + .expect("Size of internal byte array is always smaller or equal to u128; qed"), + ) } } -#[cfg(test)] -impl From for Metadata +impl From for Metadata where EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, { - /// Will silently drop data if [`K`] is too small to store useful data in [`usize`], higher - /// level code must ensure this never happens, method is not exposed outside of this crate and - /// crate boundaries are supposed to protect this invariant. Exposing error handling from here - /// will be too noisy and seemed not worth it. - fn from(value: usize) -> Self { - let mut output = Self::default(); - // Copy last bytes from big-endian `value` into `Metadata` - output - .0 - .copy_from_slice(&value.to_be_bytes()[mem::size_of::() - Self::BYTES..]); - output - } -} - -impl Metadata -where - EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, -{ - /// Size in bytes - const BYTES: usize = metadata_size_bytes(K, TABLE_NUMBER); - /// Size in bits - const BITS: usize = metadata_size_bits(K, TABLE_NUMBER); - /// Where do bits of useful data start - const DATA_OFFSET: usize = Self::BYTES * u8::BITS as usize - Self::BITS; -} - -/// Wrapper data structure around bits of `position` values, stores data in the last bits of internal -/// array. Has the same size as [`X`], but different internal layout. -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] -#[repr(transparent)] -pub(in super::super) struct Position([u8; x_size_bytes(K)]) -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized; - -impl fmt::Debug for Position -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Position") - .field(&usize::from(*self)) - .finish() - } -} - -impl From for Position -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - /// Will silently drop data if [`K`] is too small to store useful data in [`usize`], higher - /// level code must ensure this never happens, method is not exposed outside of this crate and - /// crate boundaries are supposed to protect this invariant. Exposing error handling from here - /// will be too noisy and seemed not worth it. - fn from(value: usize) -> Self { - let mut output = [0; x_size_bytes(K)]; - // Copy last bytes - output.copy_from_slice(&value.to_be_bytes()[mem::size_of::() - Self::BYTES..]); - Self(output) + fn from(value: X) -> Self { + Self::from(u128::from(value)) } } - -impl From> for usize -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - /// Panics if conversion to [`usize`] fails, higher level code must ensure this never happens, - /// method is not exposed outside of this crate and crate boundaries are supposed to protect - /// this invariant. Exposing error handling from here will be too noisy and seemed not worth it. - fn from(value: Position) -> Self { - let mut output = 0_usize.to_be_bytes(); - output[mem::size_of::() - Position::::BYTES..].copy_from_slice(&value.0); - usize::from_be_bytes(output) - } -} - -impl Position -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ - /// Size in bytes - const BYTES: usize = x_size_bytes(K); -} diff --git a/crates/subspace-proof-of-space/src/chiapos/tables.rs b/crates/subspace-proof-of-space/src/chiapos/tables.rs index c34fab06601..0dcc39dbac7 100644 --- a/crates/subspace-proof-of-space/src/chiapos/tables.rs +++ b/crates/subspace-proof-of-space/src/chiapos/tables.rs @@ -1,27 +1,23 @@ #[cfg(test)] mod tests; -use crate::chiapos::table::types::{CopyBitsDestination, Metadata, Position, X, Y}; +use crate::chiapos::table::types::{Metadata, Position, X, Y}; pub use crate::chiapos::table::TablesCache; use crate::chiapos::table::{ - compute_f1, compute_fn, fn_hashing_input_bytes, max_metadata_size_bits, metadata_size_bytes, - num_matches, partial_y, x_size_bytes, y_size_bits, y_size_bytes, Table, + compute_f1, compute_fn, metadata_size_bytes, num_matches, partial_y, Table, + COMPUTE_F1_SIMD_FACTOR, }; use crate::chiapos::utils::EvaluatableUsize; use crate::chiapos::{Challenge, Quality, Seed}; -use bitvec::prelude::*; use core::mem; use sha2::{Digest, Sha256}; /// Pick position in `table_number` based on challenge bits -const fn pick_position( - [left_position, right_position]: [Position; 2], +const fn pick_position( + [left_position, right_position]: [Position; 2], last_5_challenge_bits: u8, table_number: u8, -) -> Position -where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, -{ +) -> Position { if ((last_5_challenge_bits >> (table_number - 2)) & 1) == 0 { left_position } else { @@ -29,16 +25,10 @@ where } } -pub const fn quality_hashing_buffer_bytes(k: u8) -> usize { - mem::size_of::() + (k as usize * 2).div_ceil(u8::BITS as usize) -} - /// Collection of Chia tables #[derive(Debug)] pub(super) struct TablesGeneric where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 1) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 2) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 3) }>: Sized, @@ -58,8 +48,6 @@ where impl TablesGeneric where - EvaluatableUsize<{ x_size_bytes(K) }>: Sized, - EvaluatableUsize<{ y_size_bytes(K) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 1) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 2) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 3) }>: Sized, @@ -67,27 +55,12 @@ where EvaluatableUsize<{ metadata_size_bytes(K, 5) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 6) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, 7) }>: Sized, - EvaluatableUsize<{ fn_hashing_input_bytes(K) }>: Sized, - EvaluatableUsize<{ quality_hashing_buffer_bytes(K) }>: Sized, + EvaluatableUsize<{ K as usize * COMPUTE_F1_SIMD_FACTOR / u8::BITS as usize }>: Sized, EvaluatableUsize<{ 64 * K as usize / 8 }>: Sized, { /// Create Chia proof of space tables. There also exists [`Self::create_parallel()`] that trades /// CPU efficiency and memory usage for lower latency. - /// - /// ## Panics - /// Panics when [`K`] is too large on current platform. pub(super) fn create(seed: Seed, cache: &mut TablesCache) -> Self { - let heap_size_bits = usize::MAX as u128 * u128::from(u8::BITS); - let num_values = 1 << K; - // Check that space for `y` values can be allocated on the heap - assert!(num_values * y_size_bits(K) as u128 <= heap_size_bits); - // Check that positions can be allocated on the heap - assert!(num_values * u128::from(K) * 2 <= heap_size_bits); - // Check that metadata can be allocated on the heap - assert!(num_values * max_metadata_size_bits(K) as u128 * 2 <= heap_size_bits); - // `y` must fit into `usize` - assert!(y_size_bits(K) <= usize::BITS as usize); - let table_1 = Table::::create(seed); let table_2 = Table::::create(&table_1, cache); let table_3 = Table::::create(&table_2, cache); @@ -110,22 +83,8 @@ where /// Almost the same as [`Self::create()`], but uses parallelism internally for better /// performance (though not efficiency of CPU and memory usage), if you create multiple tables /// in parallel, prefer [`Self::create()`] for better overall performance. - /// - /// ## Panics - /// Panics when [`K`] is too large on current platform. #[cfg(any(feature = "parallel", test))] pub(super) fn create_parallel(seed: Seed, cache: &mut TablesCache) -> Self { - let heap_size_bits = usize::MAX as u128 * u128::from(u8::BITS); - let num_values = 1 << K; - // Check that space for `y` values can be allocated on the heap - assert!(num_values * y_size_bits(K) as u128 <= heap_size_bits); - // Check that positions can be allocated on the heap - assert!(num_values * u128::from(K) * 2 <= heap_size_bits); - // Check that metadata can be allocated on the heap - assert!(num_values * max_metadata_size_bits(K) as u128 * 2 <= heap_size_bits); - // `y` must fit into `usize` - assert!(y_size_bits(K) <= usize::BITS as usize); - let table_1 = Table::::create_parallel(seed); let table_2 = Table::::create_parallel(&table_1, cache); let table_3 = Table::::create_parallel(&table_2, cache); @@ -149,35 +108,33 @@ where pub(super) fn find_quality<'a>( &'a self, challenge: &'a Challenge, - ) -> impl Iterator + 'a - where - EvaluatableUsize<{ mem::size_of::() + K as usize * 2 }>: Sized, - { + ) -> impl Iterator + 'a { let last_5_challenge_bits = challenge[challenge.len() - 1] & 0b00011111; let ys = self.table_7.ys(); // We take advantage of the fact that entries are sorted by `y` (as big-endian numbers) to // quickly seek to desired offset - let mut first_k_challenge_bits = Y::::default(); - first_k_challenge_bits.copy_bits_from(challenge, 0_usize, usize::from(K), 0_usize); + let first_k_challenge_bits = u32::from_be_bytes( + challenge[..mem::size_of::()] + .try_into() + .expect("Challenge is known to statically have enough bytes; qed"), + ) >> (u32::BITS as usize - usize::from(K)); let first_matching_element = ys - .binary_search(&first_k_challenge_bits) + .binary_search_by(|&y| y.first_k_bits::().cmp(&first_k_challenge_bits)) .unwrap_or_else(|insert| insert); // Iterate just over elements that are matching `first_k_challenge_bits` prefix ys[first_matching_element..] .iter() - .take_while(move |&y| { - let mut y_k_bits = Y::::default(); - y_k_bits.copy_bits_from(y, 0_usize, usize::from(K), 0_usize); - // Check if first K bits match - y_k_bits == first_k_challenge_bits + .take_while(move |&&y| { + // Check if first K bits of `y` match + y.first_k_bits::() == first_k_challenge_bits }) - .zip(first_matching_element..) + .zip(Position::from(first_matching_element as u32)..) .map(move |(_y, position)| { let positions = self .table_7 - .position(Position::::from(position)) + .position(position) .expect("Internally generated pointers must be correct; qed"); let positions = self .table_6 @@ -200,35 +157,24 @@ where .position(pick_position(positions, last_5_challenge_bits, 2)) .expect("Internally generated pointers must be correct; qed"); - let left_x = self + let left_x = *self .table_1 .xs() .get(usize::from(left_position)) .expect("Internally generated pointers must be correct; qed"); - let right_x = self + let right_x = *self .table_1 .xs() .get(usize::from(right_position)) .expect("Internally generated pointers must be correct; qed"); - let mut buffer = [0; mem::size_of::() + K as usize * 2]; - - buffer[..mem::size_of::()].copy_from_slice(challenge); - buffer.copy_bits_from( - left_x, - 0_usize, - usize::from(K), - mem::size_of::() * u8::BITS as usize, - ); - buffer.copy_bits_from( - right_x, - 0_usize, - usize::from(K), - mem::size_of::() * u8::BITS as usize + usize::from(K), - ); - let mut hasher = Sha256::new(); - hasher.update(buffer); + hasher.update(challenge); + let left_right_xs = (u64::from(left_x) << (u64::BITS as usize - usize::from(K))) + | (u64::from(right_x) << (u64::BITS as usize - usize::from(K * 2))); + hasher.update( + &left_right_xs.to_be_bytes()[..(K as usize * 2).div_ceil(u8::BITS as usize)], + ); hasher.finalize().into() }) } @@ -241,27 +187,28 @@ where let ys = self.table_7.ys(); // We take advantage of the fact that entries are sorted by `y` (as big-endian numbers) to // quickly seek to desired offset - let mut first_k_challenge_bits = Y::::default(); - first_k_challenge_bits.copy_bits_from(challenge, 0_usize, usize::from(K), 0_usize); + let first_k_challenge_bits = u32::from_be_bytes( + challenge[..mem::size_of::()] + .try_into() + .expect("Challenge is known to statically have enough bytes; qed"), + ) >> (u32::BITS as usize - usize::from(K)); let first_matching_element = ys - .binary_search(&first_k_challenge_bits) + .binary_search_by(|&y| y.first_k_bits::().cmp(&first_k_challenge_bits)) .unwrap_or_else(|insert| insert); // Iterate just over elements that are matching `first_k_challenge_bits` prefix ys[first_matching_element..] .iter() - .take_while(move |&y| { - let mut y_k_bits = Y::::default(); - y_k_bits.copy_bits_from(y, 0_usize, usize::from(K), 0_usize); - // Check if first K bits match - y_k_bits == first_k_challenge_bits + .take_while(move |&&y| { + // Check if first K bits of `y` match + y.first_k_bits::() == first_k_challenge_bits }) - .zip(first_matching_element..) + .zip(Position::from(first_matching_element as u32)..) .map(move |(_y, position)| { let mut proof = [0u8; 64 * K as usize / 8]; self.table_7 - .position(Position::::from(position)) + .position(position) .expect("Internally generated pointers must be correct; qed") .into_iter() .flat_map(|position| { @@ -296,8 +243,27 @@ where .expect("Internally generated pointers must be correct; qed") }) .enumerate() - .for_each(|(offset, x)| { - proof.copy_bits_from(x, 0_usize, usize::from(K), usize::from(K) * offset) + .for_each(|(offset, &x)| { + let x_offset_in_bits = usize::from(K) * offset; + // Collect bytes where bits of `x` will be written + let proof_bytes = &mut proof[x_offset_in_bits / u8::BITS as usize..] + [..(x_offset_in_bits % u8::BITS as usize + usize::from(K)) + .div_ceil(u8::BITS as usize)]; + + // Bits of `x` already shifted to correct location as they will appear in + // `proof` + let x_shifted = u32::from(x) + << (u32::BITS as usize + - (usize::from(K) + x_offset_in_bits % u8::BITS as usize)); + + // Copy `x` bits into proof + x_shifted + .to_be_bytes() + .iter() + .zip(proof_bytes) + .for_each(|(from, to)| { + *to |= from; + }); }); proof @@ -314,26 +280,34 @@ where ) -> Option where EvaluatableUsize<{ (K as usize * 2).div_ceil(u8::BITS as usize) }>: Sized, - EvaluatableUsize<{ mem::size_of::() + K as usize * 2 }>: Sized, { let last_5_challenge_bits = challenge[challenge.len() - 1] & 0b00011111; + let first_k_challenge_bits = u32::from_be_bytes( + challenge[..mem::size_of::()] + .try_into() + .expect("Challenge is known to statically have enough bytes; qed"), + ) >> (u32::BITS as usize - usize::from(K)); let ys_and_metadata = (0..64_usize) .map(|offset| { - let mut x = X::default(); - x.copy_bits_from( - proof_of_space, - usize::from(K) * offset, - usize::from(K), - 0_usize, + let mut pre_x_bytes = 0u64.to_be_bytes(); + let offset_in_bits = usize::from(K) * offset; + let bytes_to_copy = (offset_in_bits % u8::BITS as usize + usize::from(K)) + .div_ceil(u8::BITS as usize); + // Copy full bytes that contain bits of `x` + pre_x_bytes[..bytes_to_copy].copy_from_slice( + &proof_of_space[offset_in_bits / u8::BITS as usize..][..bytes_to_copy], ); + // Extract `pre_x` whose last `K` bits start with `x` + let pre_x = u64::from_be_bytes(pre_x_bytes) + >> (u64::BITS as usize - (usize::from(K) + offset_in_bits % u8::BITS as usize)); + // Convert to desired type and clear extra bits + let x = X::from(pre_x as u32 & (u32::MAX >> (u32::BITS as usize - usize::from(K)))); - let (partial_y, partial_y_offset) = partial_y::(seed, usize::from(&x)); + let (partial_y, partial_y_offset) = partial_y::(seed, x); let y = compute_f1::(x, &partial_y, partial_y_offset); - let mut metadata = Metadata::::default(); - metadata.copy_bits_from(&x, 0_usize, K, 0_usize); - (y, metadata) + (y, Metadata::from(x)) }) .collect::>(); @@ -348,32 +322,45 @@ where .first() .expect("On success returns exactly one entry; qed"); - y.starts_with(&challenge.view_bits::()[..usize::from(K)]) + // Check if first K bits of `y` match + y.first_k_bits::() == first_k_challenge_bits }) .map(|_| { - let mut buffer = [0; mem::size_of::() + K as usize * 2]; - - buffer[..mem::size_of::()].copy_from_slice(challenge); let mut quality_index = 0_usize.to_be_bytes(); quality_index[0] = last_5_challenge_bits; let quality_index = usize::from_be_bytes(quality_index); - buffer.copy_bits_from( - proof_of_space, - quality_index * usize::from(K) * 2, - usize::from(K) * 2, - mem::size_of::() * u8::BITS as usize, + let mut hasher = Sha256::new(); + hasher.update(challenge); + + let left_right_xs_bit_offset = quality_index * usize::from(K * 2); + // Collect `left_x` and `right_x` bits, potentially with extra bits at the beginning + // and the end + let left_right_xs_bytes = + &proof_of_space[left_right_xs_bit_offset / u8::BITS as usize..] + [..(left_right_xs_bit_offset % u8::BITS as usize + usize::from(K * 2)) + .div_ceil(u8::BITS as usize)]; + + let mut left_right_xs = 0u64.to_be_bytes(); + left_right_xs[..left_right_xs_bytes.len()].copy_from_slice(left_right_xs_bytes); + // Move `left_x` and `right_x` bits to most significant bits + let left_right_xs = u64::from_be_bytes(left_right_xs) + << (left_right_xs_bit_offset % u8::BITS as usize); + // Clear extra bits + let left_right_xs_mask = u64::MAX << (u64::BITS as usize - usize::from(K * 2)); + let left_right_xs = left_right_xs & left_right_xs_mask; + + hasher.update( + &left_right_xs.to_be_bytes()[..usize::from(K * 2).div_ceil(u8::BITS as usize)], ); - let mut hasher = Sha256::new(); - hasher.update(buffer); hasher.finalize().into() }) } fn collect_ys_and_metadata( - ys_and_metadata: &[(Y, Metadata)], - ) -> Option, Metadata)>> + ys_and_metadata: &[(Y, Metadata)], + ) -> Option)>> where EvaluatableUsize<{ metadata_size_bytes(K, TABLE_NUMBER) }>: Sized, EvaluatableUsize<{ metadata_size_bytes(K, PARENT_TABLE_NUMBER) }>: Sized, @@ -381,7 +368,11 @@ where ys_and_metadata .array_chunks::<2>() .map(|&[(left_y, left_metadata), (right_y, right_metadata)]| { - (num_matches(&left_y, &right_y) == 1).then_some(compute_fn( + (num_matches(left_y, right_y) == 1).then_some(compute_fn::< + K, + TABLE_NUMBER, + PARENT_TABLE_NUMBER, + >( left_y, left_metadata, right_metadata, diff --git a/crates/subspace-proof-of-space/src/lib.rs b/crates/subspace-proof-of-space/src/lib.rs index ae2f57d26a9..3dddba32cd2 100644 --- a/crates/subspace-proof-of-space/src/lib.rs +++ b/crates/subspace-proof-of-space/src/lib.rs @@ -9,18 +9,18 @@ const_trait_impl, generic_const_exprs, int_roundings, - iter_collect_into + portable_simd, + step_trait )] #[cfg(feature = "chia")] pub mod chia; -#[cfg(feature = "chia-legacy")] -pub mod chia_legacy; #[cfg(feature = "chia")] pub mod chiapos; #[cfg(feature = "shim")] pub mod shim; +use core::fmt; use subspace_core_primitives::{PosProof, PosQualityBytes, PosSeed}; /// Abstraction that represents quality of the solution in the table @@ -35,9 +35,6 @@ pub trait Quality { /// Proof of space table type #[derive(Debug, Clone, Copy)] pub enum PosTableType { - /// Chia table - #[cfg(feature = "chia-legacy")] - ChiaLegacy, /// Chia table #[cfg(feature = "chia")] Chia, @@ -46,10 +43,29 @@ pub enum PosTableType { Shim, } +/// Stateful table generator with better performance +pub trait TableGenerator: fmt::Debug + Default + Clone + Send + Sized + 'static { + /// Generate new table with 32 bytes seed. + /// + /// There is also [`Self::generate_parallel()`] that can achieve lower latency. + fn generate(&mut self, seed: &PosSeed) -> T; + + /// Generate new table with 32 bytes seed using parallelism. + /// + /// This implementation will trade efficiency of CPU and memory usage for lower latency, prefer + /// [`Self::generate()`] unless lower latency is critical. + #[cfg(any(feature = "parallel", test))] + fn generate_parallel(&mut self, seed: &PosSeed) -> T { + self.generate(seed) + } +} + /// Proof of space kind pub trait Table: Sized + Send + Sync + 'static { /// Proof of space table type const TABLE_TYPE: PosTableType; + /// Instance that can be used to generate tables with better performance + type Generator: TableGenerator; /// Abstraction that represents quality of the solution in the table type Quality<'a>: Quality @@ -79,4 +95,9 @@ pub trait Table: Sized + Send + Sync + 'static { challenge_index: u32, proof: &PosProof, ) -> Option; + + /// Returns a stateful table generator with better performance + fn generator() -> Self::Generator { + Self::Generator::default() + } } diff --git a/crates/subspace-proof-of-space/src/shim.rs b/crates/subspace-proof-of-space/src/shim.rs index 9f68047cab3..ebbedb4177a 100644 --- a/crates/subspace-proof-of-space/src/shim.rs +++ b/crates/subspace-proof-of-space/src/shim.rs @@ -1,6 +1,6 @@ //! Shim proof of space implementation -use crate::{PosTableType, Quality, Table}; +use crate::{PosTableType, Quality, Table, TableGenerator}; use core::iter; use subspace_core_primitives::crypto::blake2b_256_hash; use subspace_core_primitives::{Blake2b256Hash, PosProof, PosQualityBytes, PosSeed, U256}; @@ -36,6 +36,18 @@ impl<'a> Quality for ShimQuality<'a> { } } +/// Subspace proof of space table generator. +/// +/// Shim implementation. +#[derive(Debug, Default, Clone)] +pub struct ShimTableGenerator; + +impl TableGenerator for ShimTableGenerator { + fn generate(&mut self, seed: &PosSeed) -> ShimTable { + ShimTable::generate(seed) + } +} + /// Subspace proof of space table. /// /// Shim implementation. @@ -46,6 +58,7 @@ pub struct ShimTable { impl Table for ShimTable { const TABLE_TYPE: PosTableType = PosTableType::Shim; + type Generator = ShimTableGenerator; type Quality<'a> = ShimQuality<'a>; diff --git a/crates/subspace-proof-of-time/Cargo.toml b/crates/subspace-proof-of-time/Cargo.toml new file mode 100644 index 00000000000..228fad0e19a --- /dev/null +++ b/crates/subspace-proof-of-time/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "subspace-proof-of-time" +description = "Subspace proof of time implementation" +license = "Apache-2.0" +version = "0.1.0" +authors = ["Rahul Subramaniyam "] +edition = "2021" +include = [ + "/src", + "/Cargo.toml", +] + +[lib] +# Necessary for CLI options to work on benches +bench = false + +[dependencies] +aes = "0.8.3" +subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } +thiserror = { version = "1.0.38", optional = true } + +[dev-dependencies] +criterion = "0.5.1" +rand = "0.8.5" + +[[bench]] +name = "pot" +harness = false + +[features] +default = ["std"] +std = [ + "subspace-core-primitives/std", + "thiserror", +] diff --git a/crates/subspace-proof-of-time/benches/pot.rs b/crates/subspace-proof-of-time/benches/pot.rs new file mode 100644 index 00000000000..eaa32c8ba67 --- /dev/null +++ b/crates/subspace-proof-of-time/benches/pot.rs @@ -0,0 +1,54 @@ +use core::num::{NonZeroU32, NonZeroU8}; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use rand::{thread_rng, Rng}; +use subspace_core_primitives::{BlockHash, PotKey, PotSeed}; +use subspace_proof_of_time::ProofOfTime; + +fn criterion_benchmark(c: &mut Criterion) { + let mut seed = PotSeed::default(); + thread_rng().fill(seed.as_mut()); + let mut key = PotKey::default(); + thread_rng().fill(key.as_mut()); + let slot_number = 1; + let mut injected_block_hash = BlockHash::default(); + thread_rng().fill(injected_block_hash.as_mut()); + let checkpoints_1 = NonZeroU8::new(1).expect("Not zero; qed"); + let checkpoints_8 = NonZeroU8::new(8).expect("Not zero; qed"); + // About 1s on 5.5 GHz Raptor Lake CPU + let pot_iterations = NonZeroU32::new(166_000_000).expect("Not zero; qed"); + let proof_of_time_sequential = ProofOfTime::new(pot_iterations, checkpoints_1).unwrap(); + let proof_of_time = ProofOfTime::new(pot_iterations, checkpoints_8).unwrap(); + + c.bench_function("prove/sequential", |b| { + b.iter(|| { + proof_of_time_sequential.create( + black_box(seed), + black_box(key), + black_box(slot_number), + black_box(injected_block_hash), + ); + }) + }); + + c.bench_function("prove/checkpoints", |b| { + b.iter(|| { + proof_of_time.create( + black_box(seed), + black_box(key), + black_box(slot_number), + black_box(injected_block_hash), + ); + }) + }); + + let proof = proof_of_time.create(seed, key, slot_number, injected_block_hash); + + c.bench_function("verify", |b| { + b.iter(|| { + proof_of_time.verify(black_box(&proof)).unwrap(); + }) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/crates/subspace-proof-of-time/src/lib.rs b/crates/subspace-proof-of-time/src/lib.rs new file mode 100644 index 00000000000..e07d277d491 --- /dev/null +++ b/crates/subspace-proof-of-time/src/lib.rs @@ -0,0 +1,107 @@ +//! Proof of time implementation. + +#![cfg_attr(not(feature = "std"), no_std)] +mod pot_aes; + +use core::num::{NonZeroU32, NonZeroU8}; +use subspace_core_primitives::{BlockHash, NonEmptyVec, PotKey, PotProof, PotSeed, SlotNumber}; + +#[derive(Debug)] +#[cfg_attr(feature = "thiserror", derive(thiserror::Error))] +pub enum PotInitError { + #[cfg_attr( + feature = "thiserror", + error( + "pot_iterations not multiple of num_checkpoints: {pot_iterations}, {num_checkpoints}" + ) + )] + NotMultiple { + pot_iterations: u32, + num_checkpoints: u8, + }, +} + +#[derive(Debug)] +#[cfg_attr(feature = "thiserror", derive(thiserror::Error))] +pub enum PotVerificationError { + #[cfg_attr( + feature = "thiserror", + error("Unexpected number of checkpoints: {expected}, {actual}") + )] + CheckpointCountMismatch { expected: u8, actual: u64 }, + + #[cfg_attr(feature = "thiserror", error("Checkpoint verification failed"))] + VerificationFailed, +} + +/// Wrapper for the low level AES primitives +#[derive(Clone)] +pub struct ProofOfTime { + /// Number of checkpoints per PoT. + num_checkpoints: u8, + + /// Number of chained AES operations per checkpoint. + checkpoint_iterations: u32, +} + +impl ProofOfTime { + /// Creates the AES wrapper. + pub fn new( + pot_iterations: NonZeroU32, + num_checkpoints: NonZeroU8, + ) -> Result { + let pot_iterations = pot_iterations.get(); + let num_checkpoints = num_checkpoints.get(); + if pot_iterations % (num_checkpoints as u32) != 0 { + return Err(PotInitError::NotMultiple { + pot_iterations, + num_checkpoints, + }); + } + + Ok(Self { + num_checkpoints, + checkpoint_iterations: pot_iterations / (num_checkpoints as u32), + }) + } + + /// Builds the proof. + pub fn create( + &self, + seed: PotSeed, + key: PotKey, + slot_number: SlotNumber, + injected_block_hash: BlockHash, + ) -> PotProof { + let checkpoints = NonEmptyVec::new(pot_aes::create( + &seed, + &key, + self.num_checkpoints, + self.checkpoint_iterations, + )) + .expect("List of checkpoints is never empty; qed"); + PotProof::new(slot_number, seed, key, checkpoints, injected_block_hash) + } + + /// Verifies the proof. + pub fn verify(&self, proof: &PotProof) -> Result<(), PotVerificationError> { + // TODO: this check may break upgrades, revisit. + if proof.checkpoints.len() != self.num_checkpoints as usize { + return Err(PotVerificationError::CheckpointCountMismatch { + expected: self.num_checkpoints, + actual: proof.checkpoints.len() as u64, + }); + } + + if pot_aes::verify_sequential( + &proof.seed, + &proof.key, + proof.checkpoints.as_slice(), + self.checkpoint_iterations, + ) { + Ok(()) + } else { + Err(PotVerificationError::VerificationFailed) + } + } +} diff --git a/crates/subspace-proof-of-time/src/pot_aes.rs b/crates/subspace-proof-of-time/src/pot_aes.rs new file mode 100644 index 00000000000..79bb6a8fd8e --- /dev/null +++ b/crates/subspace-proof-of-time/src/pot_aes.rs @@ -0,0 +1,145 @@ +//! AES related functionality. + +extern crate alloc; + +use aes::cipher::generic_array::GenericArray; +use aes::cipher::{BlockDecrypt, BlockEncrypt, KeyInit}; +use aes::Aes128; +use alloc::vec::Vec; +use subspace_core_primitives::{PotBytes, PotCheckpoint, PotKey, PotSeed}; + +/// Creates the AES based proof. +pub(crate) fn create( + seed: &PotSeed, + key: &PotKey, + num_checkpoints: u8, + checkpoint_iterations: u32, +) -> Vec { + let key = GenericArray::from(PotBytes::from(*key)); + let cipher = Aes128::new(&key); + let mut cur_block = GenericArray::from(PotBytes::from(*seed)); + + let mut checkpoints = Vec::with_capacity(num_checkpoints as usize); + for _ in 0..num_checkpoints { + for _ in 0..checkpoint_iterations { + // Encrypt in place to produce the next block. + cipher.encrypt_block(&mut cur_block); + } + checkpoints.push(PotCheckpoint::from(PotBytes::from(cur_block))); + } + checkpoints +} + +/// Verifies the AES based proof sequentially. +/// +/// Panics if `checkpoint_iterations` is not a multiple of `2`. +pub(crate) fn verify_sequential( + seed: &PotSeed, + key: &PotKey, + checkpoints: &[PotCheckpoint], + checkpoint_iterations: u32, +) -> bool { + assert_eq!(checkpoint_iterations % 2, 0); + + let key = GenericArray::from(PotBytes::from(*key)); + let cipher = Aes128::new(&key); + + let mut inputs = Vec::with_capacity(checkpoints.len()); + inputs.push(GenericArray::from(PotBytes::from(*seed))); + for checkpoint in checkpoints.iter().rev().skip(1).rev() { + inputs.push(GenericArray::from(PotBytes::from(*checkpoint))); + } + let mut outputs = checkpoints + .iter() + .map(|checkpoint| GenericArray::from(PotBytes::from(*checkpoint))) + .collect::>(); + + for _ in 0..checkpoint_iterations / 2 { + cipher.encrypt_blocks(&mut inputs); + cipher.decrypt_blocks(&mut outputs); + } + + inputs == outputs +} + +#[cfg(test)] +mod tests { + use super::*; + use subspace_core_primitives::{PotCheckpoint, PotKey, PotSeed}; + + const SEED: [u8; 16] = [ + 0xd6, 0x66, 0xcc, 0xd8, 0xd5, 0x93, 0xc2, 0x3d, 0xa8, 0xdb, 0x6b, 0x5b, 0x14, 0x13, 0xb1, + 0x3a, + ]; + const SEED_1: [u8; 16] = [ + 0xd7, 0xd6, 0xdc, 0xd8, 0xd5, 0x93, 0xc2, 0x3d, 0xa8, 0xdb, 0x6b, 0x5b, 0x14, 0x13, 0xb1, + 0x3a, + ]; + const KEY: [u8; 16] = [ + 0x9a, 0x84, 0x94, 0x0f, 0xfe, 0xf5, 0xb0, 0xd7, 0x01, 0x99, 0xfc, 0x67, 0xf4, 0x6e, 0xa2, + 0x7a, + ]; + const KEY_1: [u8; 16] = [ + 0x9b, 0x8b, 0x9b, 0x0f, 0xfe, 0xf5, 0xb0, 0xd7, 0x01, 0x99, 0xfc, 0x67, 0xf4, 0x6e, 0xa2, + 0x7a, + ]; + const BAD_CIPHER: [u8; 16] = [22; 16]; + + #[test] + fn test_encrypt_decrypt_sequential() { + let seed = PotSeed::from(SEED); + let key = PotKey::from(KEY); + let num_checkpoints = 10; + let checkpoint_iterations = 100; + + // Can encrypt/decrypt. + let checkpoints = create(&seed, &key, num_checkpoints, checkpoint_iterations); + assert_eq!(checkpoints.len(), num_checkpoints as usize); + assert!(verify_sequential( + &seed, + &key, + &checkpoints, + checkpoint_iterations + )); + + // Decryption of invalid cipher text fails. + let mut checkpoints_1 = checkpoints.clone(); + checkpoints_1[0] = PotCheckpoint::from(BAD_CIPHER); + assert!(!verify_sequential( + &seed, + &key, + &checkpoints_1, + checkpoint_iterations + )); + + // Decryption with wrong number of iterations fails. + assert!(!verify_sequential( + &seed, + &key, + &checkpoints, + checkpoint_iterations + 2 + )); + assert!(!verify_sequential( + &seed, + &key, + &checkpoints, + checkpoint_iterations - 2 + )); + + // Decryption with wrong seed fails. + assert!(!verify_sequential( + &PotSeed::from(SEED_1), + &key, + &checkpoints, + checkpoint_iterations + )); + + // Decryption with wrong key fails. + assert!(!verify_sequential( + &seed, + &PotKey::from(KEY_1), + &checkpoints, + checkpoint_iterations + )); + } +} diff --git a/crates/subspace-rpc-primitives/src/lib.rs b/crates/subspace-rpc-primitives/src/lib.rs index 575ab2718a9..910a09b74df 100644 --- a/crates/subspace-rpc-primitives/src/lib.rs +++ b/crates/subspace-rpc-primitives/src/lib.rs @@ -22,8 +22,8 @@ use subspace_core_primitives::{ use subspace_farmer_components::FarmerProtocolInfo; use subspace_networking::libp2p::Multiaddr; -/// Defines a limit for segment indexes array. It affects storage access on the runtime side. -pub const MAX_SEGMENT_INDEXES_PER_REQUEST: usize = 300; +/// Defines a limit for number of segments that can be requested over RPC +pub const MAX_SEGMENT_HEADERS_PER_REQUEST: usize = 1000; /// Information necessary for farmer application #[derive(Debug, Clone, Serialize, Deserialize)] @@ -87,3 +87,20 @@ pub struct RewardSignatureResponse { /// Pre-header or vote hash signature. pub signature: Option, } + +/// Information about new slot that just arrived +#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum NodeSyncStatus { + /// Node is fully synced + Synced, + /// Node is major syncing + MajorSyncing, +} + +impl NodeSyncStatus { + /// Whether node is synced + pub fn is_synced(&self) -> bool { + matches!(self, Self::Synced) + } +} diff --git a/crates/subspace-runtime-primitives/Cargo.toml b/crates/subspace-runtime-primitives/Cargo.toml index fa87ccb7474..6056470f0cf 100644 --- a/crates/subspace-runtime-primitives/Cargo.toml +++ b/crates/subspace-runtime-primitives/Cargo.toml @@ -16,14 +16,14 @@ include = [ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } +parity-scale-codec = { version = "3.6.3", default-features = false, features = ["derive"] } # TODO: Should, idealy, be optional, but `sp-runtime`'s `serde` feature is enabled unconditiionally by something in # Substrate and as the result our custom `Block` implementation has to derive `serde` traits essentially # unconditionally or else it doesn't compile serde = { version = "1.0.159", default-features = false, features = ["alloc", "derive"] } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } [features] diff --git a/crates/subspace-runtime-primitives/src/lib.rs b/crates/subspace-runtime-primitives/src/lib.rs index e8cc64dbf21..187de5e438e 100644 --- a/crates/subspace-runtime-primitives/src/lib.rs +++ b/crates/subspace-runtime-primitives/src/lib.rs @@ -67,60 +67,14 @@ pub type Moment = u64; /// to even the core data structures. pub mod opaque { use super::BlockNumber; - use parity_scale_codec::{Decode, Encode}; - use serde::{Deserialize, Serialize}; - use sp_runtime::traits::{BlakeTwo256, Block as BlockT, Header as HeaderT}; - use sp_runtime::{generic, DigestItem, OpaqueExtrinsic}; - use sp_std::prelude::*; - use subspace_core_primitives::RecordedHistorySegment; + use sp_runtime::generic; + use sp_runtime::traits::BlakeTwo256; + pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; /// Opaque block header type. pub type Header = generic::Header; /// Opaque block type. - - /// Abstraction over a substrate block. - #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode, Serialize, Deserialize)] - #[serde(rename_all = "camelCase")] - #[serde(deny_unknown_fields)] - pub struct Block { - /// The block header. - pub header: Header, - /// The accompanying extrinsics. - pub extrinsics: Vec, - } - - impl BlockT for Block { - type Extrinsic = OpaqueExtrinsic; - type Header = Header; - type Hash =
::Hash; - - fn header(&self) -> &Self::Header { - &self.header - } - fn extrinsics(&self) -> &[Self::Extrinsic] { - &self.extrinsics[..] - } - fn deconstruct(self) -> (Self::Header, Vec) { - (self.header, self.extrinsics) - } - fn new(mut header: Self::Header, extrinsics: Vec) -> Self { - if header.number == 0 { - // This check is necessary in case block was deconstructed and constructed again. - if header.digest.logs.is_empty() { - // We fill genesis block with extra data such that the very first archived - // segment can be produced right away, bootstrapping the farming process. - let ballast = vec![0; RecordedHistorySegment::SIZE]; - header.digest.logs.push(DigestItem::Other(ballast)); - } - Block { header, extrinsics } - } else { - Block { header, extrinsics } - } - } - fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec { - (header, extrinsics).encode() - } - } + pub type Block = generic::Block; } /// A trait for finding the address for a block reward based on the `PreRuntime` digests contained within it. diff --git a/crates/subspace-runtime/Cargo.toml b/crates/subspace-runtime/Cargo.toml index 7e160e27fa2..0f41d1a10f6 100644 --- a/crates/subspace-runtime/Cargo.toml +++ b/crates/subspace-runtime/Cargo.toml @@ -16,55 +16,52 @@ include = [ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } domain-runtime-primitives = { version = "0.1.0", default-features = false, path = "../../domains/primitives/runtime" } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -frame-executive = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } +frame-executive = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } +frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } orml-vesting = { version = "0.4.1-dev", default-features = false, path = "../../orml/vesting" } -pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } pallet-domains = { version = "0.1.0", default-features = false, path = "../pallet-domains" } pallet-feeds = { version = "0.1.0", default-features = false, path = "../pallet-feeds" } pallet-grandpa-finality-verifier = { version = "0.1.0", default-features = false, path = "../pallet-grandpa-finality-verifier" } pallet-object-store = { version = "0.1.0", default-features = false, path = "../pallet-object-store" } pallet-offences-subspace = { version = "0.1.0", default-features = false, path = "../pallet-offences-subspace" } -pallet-settlement = { version = "0.1.0", default-features = false, path = "../pallet-settlement" } pallet-rewards = { version = "0.1.0", default-features = false, path = "../pallet-rewards" } pallet-runtime-configs = { version = "0.1.0", default-features = false, path = "../pallet-runtime-configs" } pallet-subspace = { version = "0.1.0", default-features = false, features = ["serde"], path = "../pallet-subspace" } -pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } pallet-transaction-fees = { version = "0.1.0", default-features = false, path = "../pallet-transaction-fees" } -pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-utility = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-utility = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false, version = "4.0.0-dev"} +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false, version = "4.0.0-dev"} sp-consensus-subspace = { version = "0.1.0", default-features = false, path = "../sp-consensus-subspace" } -sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", default-features = false, path = "../sp-domains" } -sp-inherents = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false, version = "4.0.0-dev"} +sp-inherents = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false, version = "4.0.0-dev"} sp-objects = { version = "0.1.0", default-features = false, path = "../sp-objects" } -sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", default-features = false, path = "../sp-settlement" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +static_assertions = "1.1.0" subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../subspace-runtime-primitives" } subspace-verification = { version = "0.1.0", default-features = false, path = "../subspace-verification" } -system-domain-runtime = { version = "0.1.0", default-features = false, path = "../../domains/runtime/system" } [build-dependencies] -subspace-wasm-tools = { version = "0.1.0", path = "../subspace-wasm-tools" } -substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } +substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } [dev-dependencies] hex-literal = "0.4.0" @@ -87,7 +84,6 @@ std = [ "pallet-grandpa-finality-verifier/std", "pallet-object-store/std", "pallet-offences-subspace/std", - "pallet-settlement/std", "pallet-rewards/std", "pallet-runtime-configs/std", "pallet-subspace/std", @@ -109,14 +105,12 @@ std = [ "sp-offchain/std", "sp-runtime/std", "sp-session/std", - "sp-settlement/std", "sp-std/std", "sp-transaction-pool/std", "sp-version/std", "subspace-core-primitives/std", "subspace-runtime-primitives/std", "subspace-verification/std", - "system-domain-runtime/std", "substrate-wasm-builder", ] runtime-benchmarks = [ @@ -133,6 +127,5 @@ runtime-benchmarks = [ "pallet-timestamp/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "system-domain-runtime/runtime-benchmarks", ] do-not-enforce-cost-of-storage = [] diff --git a/crates/subspace-runtime/build.rs b/crates/subspace-runtime/build.rs index d3c215d321e..e2217a8dda5 100644 --- a/crates/subspace-runtime/build.rs +++ b/crates/subspace-runtime/build.rs @@ -15,13 +15,6 @@ // along with this program. If not, see . fn main() { - subspace_wasm_tools::create_runtime_bundle_inclusion_file( - "system-domain-runtime", - "SYSTEM_DOMAIN_WASM_BUNDLE", - None, - "system_domain_wasm_bundle.rs", - ); - #[cfg(feature = "std")] { substrate_wasm_builder::WasmBuilder::new() diff --git a/crates/subspace-runtime/src/domains.rs b/crates/subspace-runtime/src/domains.rs index 88ffab56b89..824e6f6dd53 100644 --- a/crates/subspace-runtime/src/domains.rs +++ b/crates/subspace-runtime/src/domains.rs @@ -1,4 +1,5 @@ -use crate::{Block, BlockNumber, Domains, Hash, RuntimeCall, Settlement, UncheckedExtrinsic}; +use crate::{Balance, Block, BlockNumber, Domains, Hash, RuntimeCall, UncheckedExtrinsic}; +use domain_runtime_primitives::{BlockNumber as DomainNumber, Hash as DomainHash}; use sp_consensus_subspace::digests::CompatibleDigestItem; use sp_consensus_subspace::FarmerPublicKey; use sp_domains::fraud_proof::FraudProof; @@ -9,39 +10,11 @@ use sp_std::vec::Vec; use subspace_core_primitives::Randomness; use subspace_verification::derive_randomness; -pub(crate) fn extract_system_bundles( - extrinsics: Vec, -) -> ( - sp_domains::OpaqueBundles, - sp_domains::OpaqueBundles, -) { - let successful_bundles = Domains::successful_bundles(); - let (system_bundles, core_bundles): (Vec<_>, Vec<_>) = extrinsics - .into_iter() - .filter_map(|uxt| match uxt.function { - RuntimeCall::Domains(pallet_domains::Call::submit_bundle { opaque_bundle }) - if successful_bundles.contains(&opaque_bundle.hash()) => - { - if opaque_bundle.domain_id().is_system() { - Some((Some(opaque_bundle), None)) - } else { - Some((None, Some(opaque_bundle))) - } - } - _ => None, - }) - .unzip(); - ( - system_bundles.into_iter().flatten().collect(), - core_bundles.into_iter().flatten().collect(), - ) -} - -pub(crate) fn extract_core_bundles( - extrinsics: Vec, +pub(crate) fn extract_successful_bundles( domain_id: DomainId, -) -> sp_domains::OpaqueBundles { - let successful_bundles = Domains::successful_bundles(); + extrinsics: Vec, +) -> sp_domains::OpaqueBundles { + let successful_bundles = Domains::successful_bundles(domain_id); extrinsics .into_iter() .filter_map(|uxt| match uxt.function { @@ -56,11 +29,13 @@ pub(crate) fn extract_core_bundles( .collect() } +// TODO: Remove when proceeding to fraud proof v2. +#[allow(unused)] pub(crate) fn extract_receipts( extrinsics: Vec, domain_id: DomainId, -) -> Vec> { - let successful_bundles = Domains::successful_bundles(); +) -> Vec> { + let successful_bundles = Domains::successful_bundles(domain_id); extrinsics .into_iter() .filter_map(|uxt| match uxt.function { @@ -68,26 +43,27 @@ pub(crate) fn extract_receipts( if opaque_bundle.domain_id() == domain_id && successful_bundles.contains(&opaque_bundle.hash()) => { - Some(opaque_bundle.receipt) + Some(opaque_bundle.into_receipt()) } _ => None, }) .collect() } +// TODO: Remove when proceeding to fraud proof v2. +#[allow(unused)] pub(crate) fn extract_fraud_proofs( extrinsics: Vec, domain_id: DomainId, ) -> Vec> { - let successful_fraud_proofs = Settlement::successful_fraud_proofs(); + // TODO: Ensure fraud proof extrinsic is infallible. extrinsics .into_iter() .filter_map(|uxt| match uxt.function { RuntimeCall::Domains(pallet_domains::Call::submit_fraud_proof { fraud_proof }) - if fraud_proof.domain_id() == domain_id - && successful_fraud_proofs.contains(&fraud_proof.hash()) => + if fraud_proof.domain_id() == domain_id => { - Some(fraud_proof) + Some(*fraud_proof) } _ => None, }) @@ -96,10 +72,10 @@ pub(crate) fn extract_fraud_proofs( pub(crate) fn extract_pre_validation_object( extrinsic: UncheckedExtrinsic, -) -> PreValidationObject { +) -> PreValidationObject { match extrinsic.function { RuntimeCall::Domains(pallet_domains::Call::submit_fraud_proof { fraud_proof }) => { - PreValidationObject::FraudProof(fraud_proof) + PreValidationObject::FraudProof(*fraud_proof) } RuntimeCall::Domains(pallet_domains::Call::submit_bundle { opaque_bundle }) => { PreValidationObject::Bundle(opaque_bundle) diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index 3bddc900ebe..30552ed6aa6 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -25,9 +25,6 @@ mod fees; mod object_mapping; mod signed_extensions; -// Make system domain WASM runtime available. -include!(concat!(env!("OUT_DIR"), "/system_domain_wasm_bundle.rs")); - // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); @@ -41,15 +38,19 @@ pub use crate::feed_processor::FeedProcessorKind; use crate::fees::{OnChargeTransaction, TransactionByteFee}; use crate::object_mapping::extract_block_object_mapping; use crate::signed_extensions::{CheckStorageAccess, DisablePallets}; +use codec::{Decode, Encode, MaxEncodedLen}; use core::mem; +use core::num::NonZeroU64; +use domain_runtime_primitives::{BlockNumber as DomainNumber, Hash as DomainHash}; use frame_support::traits::{ConstU16, ConstU32, ConstU64, ConstU8, Everything, Get}; use frame_support::weights::constants::{RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND}; use frame_support::weights::{ConstantMultiplier, IdentityFee, Weight}; -use frame_support::{construct_runtime, parameter_types}; +use frame_support::{construct_runtime, parameter_types, PalletId}; use frame_system::limits::{BlockLength, BlockWeights}; use frame_system::EnsureNever; use pallet_feeds::feed_processor::FeedProcessor; pub use pallet_subspace::AllowAuthoringBy; +use scale_info::TypeInfo; use sp_api::{impl_runtime_apis, BlockT}; use sp_consensus_slots::SlotDuration; use sp_consensus_subspace::{ @@ -58,21 +59,26 @@ use sp_consensus_subspace::{ }; use sp_core::crypto::{ByteArray, KeyTypeId}; use sp_core::{OpaqueMetadata, H256}; -use sp_domains::fraud_proof::FraudProof; -use sp_domains::{DomainId, ExecutionReceipt, OpaqueBundle}; -use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, NumberFor}; +use sp_domains::bundle_producer_election::BundleProducerElectionParams; +use sp_domains::{ + DomainId, DomainInstanceData, DomainsHoldIdentifier, OperatorId, OperatorPublicKey, + StakingHoldIdentifier, +}; +use sp_runtime::traits::{AccountIdConversion, AccountIdLookup, BlakeTwo256, NumberFor}; use sp_runtime::transaction_validity::{TransactionSource, TransactionValidity}; -use sp_runtime::{create_runtime_str, generic, AccountId32, ApplyExtrinsicResult, Perbill}; -use sp_std::borrow::Cow; +use sp_runtime::{ + create_runtime_str, generic, AccountId32, ApplyExtrinsicResult, Perbill, SaturatedConversion, +}; use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; +use static_assertions::const_assert; use subspace_core_primitives::crypto::Scalar; use subspace_core_primitives::objects::BlockObjectMapping; use subspace_core_primitives::{ HistorySize, Piece, Randomness, Record, SegmentCommitment, SegmentHeader, SegmentIndex, - SolutionRange, + SolutionRange, U256, }; use subspace_runtime_primitives::{ opaque, AccountId, Balance, BlockNumber, Hash, Index, Moment, Signature, @@ -131,7 +137,7 @@ pub const MILLISECS_PER_BLOCK: u64 = 6000; // NOTE: Currently it is not possible to change the slot duration after the chain has started. // Attempting to do so will brick block production. -const SLOT_DURATION: u64 = 1000; +const SLOT_DURATION: u64 = 2000; /// 1 in 6 slots (on average, not counting collisions) will have a block. /// Must match ratio between block and slot duration in constants above. @@ -145,6 +151,12 @@ const ERA_DURATION_IN_BLOCKS: BlockNumber = 2016; const EQUIVOCATION_REPORT_LONGEVITY: BlockNumber = 256; +/// Initial tx range = U256::MAX / INITIAL_DOMAIN_TX_RANGE. +const INITIAL_DOMAIN_TX_RANGE: u64 = 10; + +/// Tx range is adjusted every DOMAIN_TX_RANGE_ADJUSTMENT_INTERVAL blocks. +const TX_RANGE_ADJUSTMENT_INTERVAL_BLOCKS: u64 = 100; + // We assume initial plot size starts with the a single sector, where we effectively audit each // chunk of every piece. const INITIAL_SOLUTION_RANGE: SolutionRange = (SolutionRange::MAX @@ -163,6 +175,21 @@ const INITIAL_SOLUTION_RANGE: SolutionRange = (SolutionRange::MAX /// This impacts solution range for votes in consensus. const EXPECTED_VOTES_PER_BLOCK: u32 = 9; +/// Number of latest archived segments that are considered "recent history". +const RECENT_SEGMENTS: HistorySize = HistorySize::new(NonZeroU64::new(5).expect("Not zero; qed")); +/// Fraction of pieces from the "recent history" (`recent_segments`) in each sector. +const RECENT_HISTORY_FRACTION: (HistorySize, HistorySize) = ( + HistorySize::new(NonZeroU64::new(1).expect("Not zero; qed")), + HistorySize::new(NonZeroU64::new(10).expect("Not zero; qed")), +); +/// Minimum lifetime of a plotted sector, measured in archived segment. +const MIN_SECTOR_LIFETIME: HistorySize = + HistorySize::new(NonZeroU64::new(4).expect("Not zero; qed")); + +/// The block weight for 2 seconds of compute +const BLOCK_WEIGHT_FOR_2_SEC: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX); + /// A ratio of `Normal` dispatch class within block, for `BlockWeight` and `BlockLength`. const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); @@ -173,7 +200,7 @@ parameter_types! { pub const Version: RuntimeVersion = VERSION; pub const BlockHashCount: BlockNumber = 2400; /// We allow for 2 seconds of compute with a 6 second average block time. - pub SubspaceBlockWeights: BlockWeights = BlockWeights::with_sensible_defaults(Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX), NORMAL_DISPATCH_RATIO); + pub SubspaceBlockWeights: BlockWeights = BlockWeights::with_sensible_defaults(BLOCK_WEIGHT_FOR_2_SEC, NORMAL_DISPATCH_RATIO); /// We allow for 3.75 MiB for `Normal` extrinsic with 5 MiB maximum block length. pub SubspaceBlockLength: BlockLength = BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); } @@ -241,6 +268,9 @@ parameter_types! { pub const SlotProbability: (u64, u64) = SLOT_PROBABILITY; pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; pub const ExpectedVotesPerBlock: u32 = EXPECTED_VOTES_PER_BLOCK; + pub const RecentSegments: HistorySize = RECENT_SEGMENTS; + pub const RecentHistoryFraction: (HistorySize, HistorySize) = RECENT_HISTORY_FRACTION; + pub const MinSectorLifetime: HistorySize = MIN_SECTOR_LIFETIME; // Disable solution range adjustment at the start of chain. // Root origin must enable later pub const ShouldAdjustSolutionRange: bool = false; @@ -262,6 +292,9 @@ impl pallet_subspace::Config for Runtime { type SlotProbability = SlotProbability; type ExpectedBlockTime = ExpectedBlockTime; type ConfirmationDepthK = ConfirmationDepthK; + type RecentSegments = RecentSegments; + type RecentHistoryFraction = RecentHistoryFraction; + type MinSectorLifetime = MinSectorLifetime; type ExpectedVotesPerBlock = ExpectedVotesPerBlock; type MaxPiecesInSector = ConstU16<{ MAX_PIECES_IN_SECTOR }>; type ShouldAdjustSolutionRange = ShouldAdjustSolutionRange; @@ -289,6 +322,42 @@ parameter_types! { pub const ExistentialDeposit: Balance = 500 * SHANNON; } +#[derive( + PartialEq, Eq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, Ord, PartialOrd, Copy, Debug, +)] +pub enum HoldIdentifier { + Domains(DomainsHoldIdentifier), +} + +impl pallet_domains::HoldIdentifier for HoldIdentifier { + fn staking_pending_deposit(operator_id: OperatorId) -> Self { + Self::Domains(DomainsHoldIdentifier::Staking( + StakingHoldIdentifier::PendingDeposit(operator_id), + )) + } + + fn staking_staked(operator_id: OperatorId) -> Self { + Self::Domains(DomainsHoldIdentifier::Staking( + StakingHoldIdentifier::Staked(operator_id), + )) + } + + fn staking_pending_unlock(operator_id: OperatorId) -> Self { + Self::Domains(DomainsHoldIdentifier::Staking( + StakingHoldIdentifier::PendingUnlock(operator_id), + )) + } + + fn domain_instantiation_id(domain_id: DomainId) -> Self { + Self::Domains(DomainsHoldIdentifier::DomainInstantiation(domain_id)) + } +} + +parameter_types! { + // TODO: revisit this + pub const MaxHolds: u32 = 100; +} + impl pallet_balances::Config for Runtime { type MaxLocks = ConstU32<50>; type MaxReserves = (); @@ -303,8 +372,8 @@ impl pallet_balances::Config for Runtime { type WeightInfo = pallet_balances::weights::SubstrateWeight; type FreezeIdentifier = (); type MaxFreezes = (); - type RuntimeHoldReason = (); - type MaxHolds = (); + type RuntimeHoldReason = HoldIdentifier; + type MaxHolds = MaxHolds; } parameter_types! { @@ -398,21 +467,63 @@ impl pallet_offences_subspace::Config for Runtime { } parameter_types! { - pub const ReceiptsPruningDepth: BlockNumber = 256; pub const MaximumReceiptDrift: BlockNumber = 128; -} + pub const InitialDomainTxRange: u64 = INITIAL_DOMAIN_TX_RANGE; + pub const DomainTxRangeAdjustmentInterval: u64 = TX_RANGE_ADJUSTMENT_INTERVAL_BLOCKS; + /// Runtime upgrade is delayed for 1 day at 6 sec block time. + pub const DomainRuntimeUpgradeDelay: BlockNumber = 14_400; + // Minimum Operator stake is 2 * MaximumBlockWeight * WeightToFee + pub MinOperatorStake: Balance = Balance::saturated_from(2 * BLOCK_WEIGHT_FOR_2_SEC.ref_time()); + /// Use the consensus chain's `Normal` extrinsics block size limit as the domain block size limit + pub MaxDomainBlockSize: u32 = NORMAL_DISPATCH_RATIO * MAX_BLOCK_LENGTH; + /// Use the consensus chain's `Normal` extrinsics block weight limit as the domain block weight limit + pub MaxDomainBlockWeight: Weight = NORMAL_DISPATCH_RATIO * BLOCK_WEIGHT_FOR_2_SEC; + pub const MaxBundlesPerBlock: u32 = 10; + pub const DomainInstantiationDeposit: Balance = 100 * SSC; + pub const MaxDomainNameLength: u32 = 32; + pub const BlockTreePruningDepth: u32 = 256; + // TODO: revisit these + pub const StakeWithdrawalLockingPeriod: DomainNumber = 256; + // TODO: revisit these. For now epoch every 10 mins for a 6 second block + pub const StakeEpochDuration: DomainNumber = 100; + pub TreasuryAccount: AccountId = PalletId(*b"treasury").into_account_truncating(); +} + +// `BlockTreePruningDepth` should <= `BlockHashCount` because we need the consensus block hash to verify +// execution receipt, which is used to construct the node of the block tree. +const_assert!(BlockTreePruningDepth::get() <= BlockHashCount::get()); impl pallet_domains::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type DomainNumber = DomainNumber; + type DomainHash = DomainHash; type ConfirmationDepthK = ConfirmationDepthK; + type DomainRuntimeUpgradeDelay = DomainRuntimeUpgradeDelay; + type Currency = Balances; + type HoldIdentifier = HoldIdentifier; type WeightInfo = pallet_domains::weights::SubstrateWeight; -} - -impl pallet_settlement::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type DomainHash = domain_runtime_primitives::Hash; - type MaximumReceiptDrift = MaximumReceiptDrift; - type ReceiptsPruningDepth = ReceiptsPruningDepth; + type InitialDomainTxRange = InitialDomainTxRange; + type DomainTxRangeAdjustmentInterval = DomainTxRangeAdjustmentInterval; + type MinOperatorStake = MinOperatorStake; + type MaxDomainBlockSize = MaxDomainBlockSize; + type MaxDomainBlockWeight = MaxDomainBlockWeight; + type MaxBundlesPerBlock = MaxBundlesPerBlock; + type DomainInstantiationDeposit = DomainInstantiationDeposit; + type MaxDomainNameLength = MaxDomainNameLength; + type Share = Balance; + type BlockTreePruningDepth = BlockTreePruningDepth; + type StakeWithdrawalLockingPeriod = StakeWithdrawalLockingPeriod; + type StakeEpochDuration = StakeEpochDuration; + type TreasuryAccount = TreasuryAccount; + type DomainBlockReward = BlockReward; +} + +pub struct StakingOnReward; + +impl pallet_rewards::OnReward for StakingOnReward { + fn on_reward(account: AccountId, reward: Balance) { + Domains::on_block_reward(account, reward); + } } parameter_types! { @@ -428,6 +539,7 @@ impl pallet_rewards::Config for Runtime { type FindBlockRewardAddress = Subspace; type FindVotingRewardAddresses = Subspace; type WeightInfo = (); + type OnReward = StakingOnReward; } pub type FeedId = u64; @@ -496,7 +608,6 @@ construct_runtime!( Feeds: pallet_feeds = 9, GrandpaFinalityVerifier: pallet_grandpa_finality_verifier = 10, ObjectStore: pallet_object_store = 11, - Settlement: pallet_settlement = 15, Domains: pallet_domains = 12, RuntimeConfigs: pallet_runtime_configs = 14, @@ -733,103 +844,80 @@ impl_runtime_apis! { } } - impl sp_settlement::SettlementApi for Runtime { - fn execution_trace(domain_id: DomainId, receipt_hash: H256) -> Vec { - Settlement::receipts(domain_id, receipt_hash).map(|receipt| receipt.trace).unwrap_or_default() - } - - fn state_root( - domain_id: DomainId, - domain_block_number: NumberFor, - domain_block_hash: Hash, - ) -> Option { - Settlement::state_root((domain_id, domain_block_number, domain_block_hash)) - } - - fn primary_hash(domain_id: DomainId, domain_block_number: BlockNumber) -> Option { - Settlement::primary_hash(domain_id, domain_block_number) + impl sp_domains::transaction::PreValidationObjectApi for Runtime { + fn extract_pre_validation_object( + extrinsic: ::Extrinsic, + ) -> sp_domains::transaction::PreValidationObject { + crate::domains::extract_pre_validation_object(extrinsic) } + } - fn receipts_pruning_depth() -> BlockNumber { - ReceiptsPruningDepth::get() + impl sp_domains::DomainsApi for Runtime { + fn submit_bundle_unsigned( + opaque_bundle: sp_domains::OpaqueBundle, ::Hash, DomainNumber, DomainHash, Balance>, + ) { + Domains::submit_bundle_unsigned(opaque_bundle) } - fn head_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::head_receipt_number(domain_id) + fn extract_successful_bundles( + domain_id: DomainId, + extrinsics: Vec<::Extrinsic>, + ) -> sp_domains::OpaqueBundles { + crate::domains::extract_successful_bundles(domain_id, extrinsics) } - fn oldest_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::oldest_receipt_number(domain_id) + fn extrinsics_shuffling_seed(header: ::Header) -> Randomness { + crate::domains::extrinsics_shuffling_seed::(header) } - fn maximum_receipt_drift() -> NumberFor { - MaximumReceiptDrift::get() + fn domain_runtime_code(domain_id: DomainId) -> Option> { + Domains::domain_runtime_code(domain_id) } - fn extract_receipts( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, ::Hash, domain_runtime_primitives::Hash>> { - crate::domains::extract_receipts(extrinsics, domain_id) + fn runtime_id(domain_id: DomainId) -> Option { + Domains::runtime_id(domain_id) } - fn extract_fraud_proofs( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, ::Hash>> { - crate::domains::extract_fraud_proofs(extrinsics, domain_id) + fn domain_instance_data(domain_id: DomainId) -> Option<(DomainInstanceData, NumberFor)> { + Domains::domain_instance_data(domain_id) } - fn submit_fraud_proof_unsigned(fraud_proof: FraudProof, ::Hash>) { - Domains::submit_fraud_proof_unsigned(fraud_proof) + fn timestamp() -> Moment{ + Timestamp::now() } - } - impl sp_domains::transaction::PreValidationObjectApi for Runtime { - fn extract_pre_validation_object( - extrinsic: ::Extrinsic, - ) -> sp_domains::transaction::PreValidationObject { - crate::domains::extract_pre_validation_object(extrinsic) + fn domain_tx_range(domain_id: DomainId) -> U256 { + Domains::domain_tx_range(domain_id) } - } - impl sp_domains::ExecutorApi for Runtime { - fn submit_bundle_unsigned( - opaque_bundle: OpaqueBundle, ::Hash, domain_runtime_primitives::Hash>, - ) { - Domains::submit_bundle_unsigned(opaque_bundle) + fn genesis_state_root(domain_id: DomainId) -> Option { + Domains::genesis_state_root(domain_id) } - fn extract_system_bundles( - extrinsics: Vec<::Extrinsic>, - ) -> ( - sp_domains::OpaqueBundles, - sp_domains::OpaqueBundles, - ) { - crate::domains::extract_system_bundles(extrinsics) + fn head_receipt_number(domain_id: DomainId) -> NumberFor { + Domains::head_receipt_number(domain_id) } - fn extract_core_bundles( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> sp_domains::OpaqueBundles { - crate::domains::extract_core_bundles(extrinsics, domain_id) + fn oldest_receipt_number(domain_id: DomainId) -> NumberFor { + Domains::oldest_receipt_number(domain_id) } - fn successful_bundle_hashes() -> Vec { - Domains::successful_bundles() + fn block_tree_pruning_depth() -> NumberFor { + Domains::block_tree_pruning_depth() } - fn extrinsics_shuffling_seed(header: ::Header) -> Randomness { - crate::domains::extrinsics_shuffling_seed::(header) + fn domain_block_limit(domain_id: DomainId) -> Option { + Domains::domain_block_limit(domain_id) } + } - fn system_domain_wasm_bundle() -> Cow<'static, [u8]> { - SYSTEM_DOMAIN_WASM_BUNDLE.into() + impl sp_domains::BundleProducerElectionApi for Runtime { + fn bundle_producer_election_params(domain_id: DomainId) -> Option> { + Domains::bundle_producer_election_params(domain_id) } - fn timestamp() -> Moment{ - Timestamp::now() + fn operator(operator_id: OperatorId) -> Option<(OperatorPublicKey, Balance)> { + Domains::operator(operator_id) } } diff --git a/crates/subspace-runtime/src/signed_extensions.rs b/crates/subspace-runtime/src/signed_extensions.rs index c6facedd177..ace49ab3b77 100644 --- a/crates/subspace-runtime/src/signed_extensions.rs +++ b/crates/subspace-runtime/src/signed_extensions.rs @@ -100,7 +100,7 @@ impl SignedExtension for DisablePallets { _info: &DispatchInfoOf, _len: usize, ) -> TransactionValidity { - if matches!(call, RuntimeCall::Domains(_)) && !RuntimeConfigs::enable_executor() { + if matches!(call, RuntimeCall::Domains(_)) && !RuntimeConfigs::enable_domains() { InvalidTransaction::Call.into() } else { Ok(ValidTransaction::default()) diff --git a/crates/subspace-service/Cargo.toml b/crates/subspace-service/Cargo.toml index 3310053a986..19b3ed49a21 100644 --- a/crates/subspace-service/Cargo.toml +++ b/crates/subspace-service/Cargo.toml @@ -17,54 +17,56 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] async-trait = "0.1.68" +atomic = "0.5.3" cross-domain-message-gossip = { version = "0.1.0", path = "../../domains/client/cross-domain-message-gossip" } derive_more = "0.99.17" domain-block-preprocessor = { version = "0.1.0", path = "../../domains/client/block-preprocessor" } domain-runtime-primitives = { version = "0.1.0", path = "../../domains/primitives/runtime" } either = "1.8.1" -frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } futures = "0.3.28" hex = "0.4.3" jsonrpsee = { version = "0.16.2", features = ["server"] } -pallet-transaction-payment-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -parity-scale-codec = "3.4.0" +pallet-transaction-payment-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +parity-scale-codec = "3.6.3" parking_lot = "0.12.1" -sc-basic-authorship = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-chain-spec = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-basic-authorship = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-chain-spec = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sc-consensus-fraud-proof = { version = "0.1.0", path = "../sc-consensus-fraud-proof" } sc-consensus-subspace = { version = "0.1.0", path = "../sc-consensus-subspace" } sc-consensus-subspace-rpc = { version = "0.1.0", path = "../sc-consensus-subspace-rpc" } -sc-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-rpc-api = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-rpc-spec-v2 = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } +sc-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-proof-of-time = { version = "0.1.0", path = "../sc-proof-of-time" } +sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-rpc-api = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-rpc-spec-v2 = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } sc-subspace-block-relay = { version = "0.1.0", path = "../sc-subspace-block-relay" } -sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-tracing = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-tracing = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../sp-domains" } -sp-externalities = { version = "0.19.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-externalities = { version = "0.19.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-objects = { version = "0.1.0", path = "../sp-objects" } -sp-offchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", path = "../sp-settlement" } -sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-offchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +static_assertions = "1.1.0" subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } subspace-fraud-proof = { version = "0.1.0", path = "../subspace-fraud-proof" } @@ -72,15 +74,15 @@ subspace-networking = { version = "0.1.0", path = "../subspace-networking" } subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-space" } subspace-runtime-primitives = { version = "0.1.0", path = "../subspace-runtime-primitives" } subspace-transaction-pool = { version = "0.1.0", path = "../subspace-transaction-pool" } -substrate-frame-rpc-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +substrate-frame-rpc-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } thiserror = "1.0.38" tokio = { version = "1.28.2", features = ["sync"] } tracing = "0.1.37" -sp-session = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system-rpc-runtime-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-session = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system-rpc-runtime-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = [] diff --git a/crates/subspace-service/src/dsn.rs b/crates/subspace-service/src/dsn.rs index 9afd631ee06..404a81bc772 100644 --- a/crates/subspace-service/src/dsn.rs +++ b/crates/subspace-service/src/dsn.rs @@ -1,33 +1,25 @@ pub mod import_blocks; -pub mod node_provider_storage; -use crate::dsn::node_provider_storage::NodeProviderStorage; use crate::piece_cache::PieceCache; -use crate::SegmentHeaderCache; -use either::Either; use sc_client_api::AuxStore; -use sc_consensus_subspace_rpc::SegmentHeaderProvider; -use std::num::NonZeroUsize; +use sc_consensus_subspace::SegmentHeadersStore; +use std::collections::HashSet; +use std::fs; use std::path::PathBuf; -use std::time::Instant; +use std::sync::Arc; use subspace_core_primitives::{SegmentHeader, SegmentIndex}; -use subspace_networking::libp2p::kad::ProviderRecord; use subspace_networking::libp2p::{identity, Multiaddr}; +use subspace_networking::utils::strip_peer_id; use subspace_networking::{ - peer_id, BootstrappedNetworkingParameters, CreationError, MemoryProviderStorage, - NetworkParametersPersistenceError, NetworkingParametersManager, Node, NodeRunner, - ParityDbError, ParityDbProviderStorage, PieceAnnouncementRequestHandler, - PieceAnnouncementResponse, PieceByHashRequestHandler, PieceByHashResponse, ProviderStorage, + CreationError, NetworkParametersPersistenceError, NetworkingParametersManager, Node, + NodeRunner, PeerInfoProvider, PieceByHashRequestHandler, PieceByHashResponse, SegmentHeaderBySegmentIndexesRequestHandler, SegmentHeaderRequest, SegmentHeaderResponse, KADEMLIA_PROVIDER_TTL_IN_SECS, }; use thiserror::Error; use tracing::{debug, error, trace}; -/// Provider records cache size -const MAX_PROVIDER_RECORDS_LIMIT: usize = 100000; // ~ 10 MB - -const ROOT_BLOCK_NUMBER_LIMIT: u64 = 100; +const SEGMENT_HEADERS_NUMBER_LIMIT: u64 = 1000; /// Errors that might happen during DSN configuration. #[derive(Debug, Error)] @@ -35,9 +27,6 @@ pub enum DsnConfigurationError { /// Can't instantiate the DSN. #[error("Can't instantiate the DSN: {0}")] CreationError(#[from] CreationError), - /// ParityDb storage error - #[error("ParityDb storage error: {0}")] - ParityDbStorageError(#[from] ParityDbError), /// Network parameter manager error. #[error("Network parameter manager error: {0}")] NetworkParameterManagerError(#[from] NetworkParametersPersistenceError), @@ -78,55 +67,49 @@ pub struct DsnConfig { /// Defines target total (in and out) connection number for DSN that should be maintained. pub target_connections: u32, -} -type DsnProviderStorage = - NodeProviderStorage, Either>; + /// Known external addresses + pub external_addresses: Vec, +} pub(crate) fn create_dsn_instance( dsn_protocol_version: String, dsn_config: DsnConfig, piece_cache: PieceCache, - segment_header_cache: SegmentHeaderCache, -) -> Result<(Node, NodeRunner>), DsnConfigurationError> + segment_headers_store: SegmentHeadersStore, +) -> Result<(Node, NodeRunner>), DsnConfigurationError> where AS: AuxStore + Sync + Send + 'static, { trace!("Subspace networking starting."); - let peer_id = peer_id(&dsn_config.keypair); - - let external_provider_storage = if let Some(path) = &dsn_config.base_path { - let db_path = path.join("storage_providers_db"); - - let cache_size: NonZeroUsize = NonZeroUsize::new(MAX_PROVIDER_RECORDS_LIMIT) - .expect("Manual value should be greater than zero."); - - Either::Left(ParityDbProviderStorage::new(&db_path, cache_size, peer_id)?) - } else { - Either::Right(MemoryProviderStorage::new(peer_id)) - }; - - let networking_parameters_registry = { - dsn_config - .base_path - .map(|path| { - let db_path = path.join("known_addresses_db"); - - NetworkingParametersManager::new(&db_path, dsn_config.bootstrap_nodes.clone()) - .map(|manager| manager.boxed()) - }) - .unwrap_or(Ok(BootstrappedNetworkingParameters::new( - dsn_config.bootstrap_nodes, + let networking_parameters_registry = dsn_config + .base_path + .map(|path| { + // TODO: Remove this in the future after enough upgrade time that this no longer exist + if path.join("known_addresses_db").is_dir() { + let _ = fs::remove_file(path.join("known_addresses_db")); + } + let file_path = path.join("known_addresses.bin"); + + NetworkingParametersManager::new( + &file_path, + strip_peer_id(dsn_config.bootstrap_nodes.clone()) + .into_iter() + .map(|(peer_id, _)| peer_id) + .collect::>(), ) - .boxed()))? - }; + .map(NetworkingParametersManager::boxed) + }) + .transpose()?; - let provider_storage = - NodeProviderStorage::new(peer_id, piece_cache.clone(), external_provider_storage); let keypair = dsn_config.keypair.clone(); - let mut default_networking_config = - subspace_networking::Config::new(dsn_protocol_version, keypair, provider_storage.clone()); + let mut default_networking_config = subspace_networking::Config::new( + dsn_protocol_version, + keypair, + piece_cache.clone(), + Some(PeerInfoProvider::new_node()), + ); default_networking_config .kademlia @@ -138,34 +121,6 @@ where allow_non_global_addresses_in_dht: dsn_config.allow_non_global_addresses_in_dht, networking_parameters_registry, request_response_protocols: vec![ - PieceAnnouncementRequestHandler::create({ - move |peer_id, req| { - trace!(?req, %peer_id, "Piece announcement request received."); - - let provider_record = ProviderRecord { - provider: peer_id, - key: req.piece_index_hash.into(), - addresses: req.addresses.clone(), - expires: KADEMLIA_PROVIDER_TTL_IN_SECS.map(|ttl| Instant::now() + ttl), - }; - - let result = match provider_storage.add_provider(provider_record) { - Ok(()) => Some(PieceAnnouncementResponse::Success), - Err(error) => { - error!( - %error, - %peer_id, - ?req, - "Failed to add provider for received key." - ); - - None - } - }; - - async move { result } - } - }), PieceByHashRequestHandler::create(move |_, req| { let result = match piece_cache.get_piece(req.piece_index_hash) { Ok(maybe_piece) => maybe_piece, @@ -185,41 +140,42 @@ where SegmentHeaderRequest::LastSegmentHeaders { segment_header_number, } => { - let mut block_limit = *segment_header_number; - if *segment_header_number > ROOT_BLOCK_NUMBER_LIMIT { + let mut segment_headers_limit = *segment_header_number; + if *segment_header_number > SEGMENT_HEADERS_NUMBER_LIMIT { debug!( %segment_header_number, "Segment header number exceeded the limit." ); - block_limit = ROOT_BLOCK_NUMBER_LIMIT; + segment_headers_limit = SEGMENT_HEADERS_NUMBER_LIMIT; } - let max_segment_index = segment_header_cache.max_segment_index(); - - // several last segment indexes - (SegmentIndex::ZERO..=max_segment_index) - .rev() - .take(block_limit as usize) - .collect::>() + match segment_headers_store.max_segment_index() { + Some(max_segment_index) => { + // Several last segment indexes + (SegmentIndex::ZERO..=max_segment_index) + .rev() + .take(segment_headers_limit as usize) + .collect::>() + } + None => { + // Nothing yet + Vec::new() + } + } } }; - let internal_result = segment_indexes + let maybe_segment_headers = segment_indexes .iter() - .map(|segment_index| segment_header_cache.get_segment_header(*segment_index)) - .collect::>, _>>(); + .map(|segment_index| segment_headers_store.get_segment_header(*segment_index)) + .collect::>>(); - let result = match internal_result { - Ok(Some(segment_headers)) => Some(SegmentHeaderResponse { segment_headers }), - Ok(None) => { + let result = match maybe_segment_headers { + Some(segment_headers) => Some(SegmentHeaderResponse { segment_headers }), + None => { error!("Segment header collection contained empty segment headers."); - None - } - Err(error) => { - error!(%error, "Failed to get segment headers from cache"); - None } }; @@ -231,8 +187,13 @@ where max_established_outgoing_connections: dsn_config.max_out_connections, max_pending_incoming_connections: dsn_config.max_pending_in_connections, max_pending_outgoing_connections: dsn_config.max_pending_out_connections, - target_connections: dsn_config.target_connections, + general_target_connections: dsn_config.target_connections, + special_target_connections: 0, reserved_peers: dsn_config.reserved_peers, + // maintain permanent connections with any peer + general_connected_peers_handler: Some(Arc::new(|_| true)), + bootstrap_addresses: dsn_config.bootstrap_nodes, + external_addresses: dsn_config.external_addresses, ..default_networking_config }; diff --git a/crates/subspace-service/src/dsn/import_blocks.rs b/crates/subspace-service/src/dsn/import_blocks.rs index 8bf116a9bb9..f4eaff3bc98 100644 --- a/crates/subspace-service/src/dsn/import_blocks.rs +++ b/crates/subspace-service/src/dsn/import_blocks.rs @@ -19,23 +19,35 @@ mod segment_headers; use crate::dsn::import_blocks::piece_validator::SegmentCommitmentPieceValidator; use crate::dsn::import_blocks::segment_headers::SegmentHeaderHandler; +use futures::FutureExt; use parity_scale_codec::Encode; use sc_client_api::{BlockBackend, HeaderBackend}; +use sc_consensus::import_queue::ImportQueueService; use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock, Link}; use sc_service::ImportQueue; use sc_tracing::tracing::{debug, info, trace}; use sp_consensus::BlockOrigin; use sp_runtime::traits::{Block as BlockT, Header, NumberFor}; +use static_assertions::const_assert; use std::sync::Arc; use std::task::Poll; +use std::time::Duration; use subspace_archiving::reconstructor::Reconstructor; use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; use subspace_core_primitives::{ - ArchivedHistorySegment, Piece, RecordedHistorySegment, SegmentHeader, SegmentIndex, + ArchivedHistorySegment, BlockNumber, Piece, RecordedHistorySegment, SegmentHeader, SegmentIndex, }; use subspace_networking::utils::piece_provider::{PieceProvider, RetryPolicy}; use subspace_networking::Node; +// Refuse to compile on non-64-bit platforms, otherwise segment indices will not fit in memory +const_assert!(std::mem::size_of::() >= std::mem::size_of::()); + +/// How many blocks to queue before pausing and waiting for blocks to be imported +const QUEUED_BLOCKS_LIMIT: BlockNumber = 2048; +/// Time to wait for blocks to import if import is too slow +const WAIT_FOR_BLOCKS_TO_IMPORT: Duration = Duration::from_secs(1); + struct WaitLinkError { error: BlockImportError, hash: B::Hash, @@ -77,29 +89,123 @@ impl Link for WaitLink { } } -/// Starts the process of importing blocks. +/// Starts the process of importing blocks, used for for initial sync on node startup because it +/// requires [`ImportQueue`] as a dependency. /// /// Returns number of imported blocks. -pub async fn import_blocks( +pub async fn initial_block_import_from_dsn( node: &Node, - client: Arc, + client: Arc, import_queue: &mut IQ, force: bool, ) -> Result where - C: HeaderBackend + BlockBackend + Send + Sync + 'static, - B: BlockT, - IQ: ImportQueue + 'static, + Block: BlockT, + Client: HeaderBackend + BlockBackend + Send + Sync + 'static, + IQ: ImportQueue + 'static, { - // TODO: Consider introducing and using global in-memory segment header cache (this comment is - // in multiple files) - let segment_commitments = SegmentHeaderHandler::new(node.clone()) + let mut link = WaitLink::new(); + let mut import_queue_service = import_queue.service(); + + let import_blocks_fut = import_blocks_from_dsn( + node, + client.as_ref(), + import_queue_service.as_mut(), + BlockOrigin::NetworkInitialSync, + force, + ); + let drive_import_queue_fut = async { + let mut last_imported_blocks = link.imported_blocks; + loop { + futures::future::poll_fn(|ctx| { + import_queue.poll_actions(ctx, &mut link); + + if last_imported_blocks == link.imported_blocks && link.error.is_none() { + // Nothing changed yet, wait for waker to be called + Poll::Pending + } else { + last_imported_blocks = link.imported_blocks; + Poll::Ready(()) + } + }) + .await; + + if let Some(WaitLinkError { error, hash }) = &link.error { + return Err::<(), sc_service::Error>(sc_service::Error::Other(format!( + "Stopping block import after #{} blocks on {} because of an error: {}", + link.imported_blocks, hash, error + ))); + } + } + }; + + let downloaded_blocks = futures::select! { + maybe_downloaded_blocks = import_blocks_fut.fuse() => { + maybe_downloaded_blocks? + } + result = drive_import_queue_fut.fuse() => { + if let Err(error) = result { + return Err(error); + } else { + unreachable!(); + } + } + }; + + while link.imported_blocks < downloaded_blocks { + futures::future::poll_fn(|ctx| { + import_queue.poll_actions(ctx, &mut link); + + Poll::Ready(()) + }) + .await; + + if let Some(WaitLinkError { error, hash }) = &link.error { + return Err(sc_service::Error::Other(format!( + "Stopping block import after #{} blocks on {} because of an error: {}", + link.imported_blocks, hash, error + ))); + } + } + + Ok(downloaded_blocks) +} + +// TODO: Only download segment headers starting with the first segment that node doesn't have rather +// than from genesis +/// Starts the process of importing blocks. +/// +/// Returns number of downloaded blocks. +pub async fn import_blocks_from_dsn( + node: &Node, + client: &Client, + import_queue_service: &mut IQS, + block_origin: BlockOrigin, + force: bool, +) -> Result +where + Block: BlockT, + Client: HeaderBackend + BlockBackend + Send + Sync + 'static, + IQS: ImportQueueService + ?Sized, +{ + let segment_headers = SegmentHeaderHandler::new(node.clone()) .get_segment_headers() .await - .map_err(|error| sc_service::Error::Other(error.to_string()))? + .map_err(|error| error.to_string())?; + + debug!("Found {} segment headers", segment_headers.len()); + + if segment_headers.is_empty() { + return Ok(0); + } + + // TODO: Consider introducing and using global in-memory segment header cache (this comment is + // in multiple files) + let segment_commitments = segment_headers .iter() .map(SegmentHeader::segment_commitment) .collect::>(); + let segments_found = segment_commitments.len(); let piece_provider = PieceProvider::::new( node.clone(), @@ -110,28 +216,30 @@ where )), ); - debug!("Waiting for connected peers..."); - let _ = node.wait_for_connected_peers().await; - debug!("Connected to peers."); - - let best_block_number = client.info().best_number; - let mut link = WaitLink::new(); - let mut imported_blocks = 0; - let mut reconstructor = - Reconstructor::new().map_err(|error| sc_service::Error::Other(error.to_string()))?; + let mut downloaded_blocks = 0; + let mut reconstructor = Reconstructor::new().map_err(|error| error.to_string())?; // Skip the first segment, everyone has it locally for segment_index in (SegmentIndex::ZERO..).take(segments_found).skip(1) { let pieces_indices = segment_index.segment_piece_indexes_source_first(); + if let Some(segment_header) = segment_headers.get(u64::from(segment_index) as usize) { + let last_archived_block = + NumberFor::::from(segment_header.last_archived_block().number); + if last_archived_block <= client.info().best_number { + // Reset reconstructor instance + reconstructor = Reconstructor::new().map_err(|error| error.to_string())?; + continue; + } + } + let mut segment_pieces = vec![None::; ArchivedHistorySegment::NUM_PIECES]; let mut pieces_received = 0; for piece_index in pieces_indices { let maybe_piece = piece_provider .get_piece(piece_index, RetryPolicy::Limited(0)) - .await - .map_err(|error| sc_service::Error::Other(error.to_string()))?; + .await?; trace!( ?piece_index, @@ -156,8 +264,12 @@ where let reconstructed_contents = reconstructor .add_segment(segment_pieces.as_ref()) - .map_err(|error| sc_service::Error::Other(error.to_string()))?; + .map_err(|error| error.to_string())?; + drop(segment_pieces); + let mut blocks_to_import = Vec::with_capacity(reconstructed_contents.blocks.len()); + + let best_block_number = client.info().best_number; for (block_number, block_bytes) in reconstructed_contents.blocks { { let block_number = block_number.into(); @@ -178,68 +290,46 @@ where continue; } + + // Limit number of queued blocks for import + while block_number - best_block_number >= QUEUED_BLOCKS_LIMIT.into() { + tokio::time::sleep(WAIT_FOR_BLOCKS_TO_IMPORT).await; + } } - let block = B::decode(&mut block_bytes.as_slice()) - .map_err(|error| sc_service::Error::Other(error.to_string()))?; + let block = + Block::decode(&mut block_bytes.as_slice()).map_err(|error| error.to_string())?; let (header, extrinsics) = block.deconstruct(); let hash = header.hash(); - // import queue handles verification and importing it into the client. - import_queue.service_ref().import_blocks( - BlockOrigin::NetworkInitialSync, - vec![IncomingBlock:: { - hash, - header: Some(header), - body: Some(extrinsics), - indexed_body: None, - justifications: None, - origin: None, - allow_missing_state: false, - import_existing: force, - state: None, - skip_execution: false, - }], - ); - - imported_blocks += 1; - - if imported_blocks % 1000 == 0 { - info!("Imported block {}", block_number); + blocks_to_import.push(IncomingBlock { + hash, + header: Some(header), + body: Some(extrinsics), + indexed_body: None, + justifications: None, + origin: None, + allow_missing_state: false, + import_existing: force, + state: None, + skip_execution: false, + }); + + downloaded_blocks += 1; + + if downloaded_blocks % 1000 == 0 { + info!("Imported block {} from DSN", block_number); } } - futures::future::poll_fn(|ctx| { - import_queue.poll_actions(ctx, &mut link); - - Poll::Ready(()) - }) - .await; - - if let Some(WaitLinkError { error, hash }) = &link.error { - return Err(sc_service::Error::Other(format!( - "Stopping block import after #{} blocks on {} because of an error: {}", - link.imported_blocks, hash, error - ))); + if blocks_to_import.is_empty() { + break; } - } - - while link.imported_blocks < imported_blocks { - futures::future::poll_fn(|ctx| { - import_queue.poll_actions(ctx, &mut link); - Poll::Ready(()) - }) - .await; - - if let Some(WaitLinkError { error, hash }) = &link.error { - return Err(sc_service::Error::Other(format!( - "Stopping block import after #{} blocks on {} because of an error: {}", - link.imported_blocks, hash, error - ))); - } + // import queue handles verification and importing it into the client. + import_queue_service.import_blocks(block_origin, blocks_to_import); } - Ok(imported_blocks) + Ok(downloaded_blocks) } diff --git a/crates/subspace-service/src/dsn/import_blocks/segment_headers.rs b/crates/subspace-service/src/dsn/import_blocks/segment_headers.rs index f96fe367fc4..9aa16fa04eb 100644 --- a/crates/subspace-service/src/dsn/import_blocks/segment_headers.rs +++ b/crates/subspace-service/src/dsn/import_blocks/segment_headers.rs @@ -24,7 +24,9 @@ impl SegmentHeaderHandler { pub async fn get_segment_headers(&self) -> Result, Box> { trace!("Getting segment headers..."); - let (mut last_segment_header, peers) = self.get_last_segment_header().await?; + let Some((mut last_segment_header, peers)) = self.get_last_segment_header().await? else { + return Ok(Vec::new()); + }; debug!( "Getting segment headers starting from segment_index={}", last_segment_header.segment_index() @@ -72,13 +74,13 @@ impl SegmentHeaderHandler { Ok(all_segment_headers) } - /// Return last segment header known to DSN and peers voted for it. We ask several peers for the - /// highest segment header known to them. Target segment header should be known to the majority - /// of the peer set with minimum initial size of [`SEGMENT_HEADER_CONSENSUS_INITIAL_NODES`] - /// peers. + /// Return last segment header known to DSN and agreed on by majority of the peer set with + /// minimum initial size of [`SEGMENT_HEADER_CONSENSUS_INITIAL_NODES`] peers. + /// + /// `Ok(None)` is returned when no peers were found. async fn get_last_segment_header( &self, - ) -> Result<(SegmentHeader, Vec), Box> { + ) -> Result)>, Box> { for (root_block_consensus_nodes, retry_attempt) in (1 ..=SEGMENT_HEADER_CONSENSUS_INITIAL_NODES) .rev() @@ -111,7 +113,9 @@ impl SegmentHeaderHandler { .send_generic_request( peer_id, SegmentHeaderRequest::LastSegmentHeaders { - segment_header_number: SEGMENT_HEADER_NUMBER_PER_REQUEST, + // Request 2 top segment headers, accounting for situations when new + // segment header was just produced and not all nodes have it + segment_header_number: 2, }, ) .await; @@ -186,10 +190,10 @@ impl SegmentHeaderHandler { } } - return Ok((best_segment_header, most_peers)); + return Ok(Some((best_segment_header, most_peers))); } - Err("No peers found to sync from".into()) + Ok(None) } /// Validates segment headers and related segment indexes. diff --git a/crates/subspace-service/src/dsn/node_provider_storage.rs b/crates/subspace-service/src/dsn/node_provider_storage.rs deleted file mode 100644 index 9432bdc708b..00000000000 --- a/crates/subspace-service/src/dsn/node_provider_storage.rs +++ /dev/null @@ -1,82 +0,0 @@ -use subspace_networking::libp2p::kad::record::Key; -use subspace_networking::libp2p::kad::ProviderRecord; -use subspace_networking::libp2p::PeerId; -use subspace_networking::ProviderStorage; - -pub struct NodeProviderStorage { - local_peer_id: PeerId, - /// Provider records from local cache - implicit_provider_storage: ImplicitProviderStorage, - /// External provider records - persistent_provider_storage: PersistentProviderStorage, -} - -impl Clone - for NodeProviderStorage -{ - fn clone(&self) -> Self { - Self { - local_peer_id: self.local_peer_id, - implicit_provider_storage: self.implicit_provider_storage.clone(), - persistent_provider_storage: self.persistent_provider_storage.clone(), - } - } -} - -impl - NodeProviderStorage -where - PersistentProviderStorage: ProviderStorage, -{ - pub fn new( - local_peer_id: PeerId, - implicit_provider_storage: ImplicitProviderStorage, - persistent_provider_storage: PersistentProviderStorage, - ) -> Self { - Self { - local_peer_id, - implicit_provider_storage, - persistent_provider_storage, - } - } -} - -impl ProviderStorage - for NodeProviderStorage -where - ImplicitProviderStorage: ProviderStorage, - PersistentProviderStorage: ProviderStorage, -{ - type ProvidedIter<'a> = ImplicitProviderStorage::ProvidedIter<'a> where Self:'a; - - fn add_provider( - &self, - record: ProviderRecord, - ) -> subspace_networking::libp2p::kad::store::Result<()> { - // Local providers are implicit and should not be put into persistent storage - if record.provider != self.local_peer_id { - self.persistent_provider_storage.add_provider(record) - } else { - Ok(()) - } - } - - fn providers(&self, key: &Key) -> Vec { - let mut local_provider_records = self.implicit_provider_storage.providers(key); - let mut external_provider_records = self.persistent_provider_storage.providers(key); - - local_provider_records.append(&mut external_provider_records); - - local_provider_records - } - - fn provided(&self) -> Self::ProvidedIter<'_> { - // Only provider records cached locally - self.implicit_provider_storage.provided() - } - - fn remove_provider(&self, key: &Key, peer_id: &PeerId) { - self.persistent_provider_storage - .remove_provider(key, peer_id); - } -} diff --git a/crates/subspace-service/src/lib.rs b/crates/subspace-service/src/lib.rs index 55be0d5327b..6971b16250c 100644 --- a/crates/subspace-service/src/lib.rs +++ b/crates/subspace-service/src/lib.rs @@ -15,24 +15,28 @@ // along with this program. If not, see . //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. -#![feature(type_alias_impl_trait, type_changing_struct_update)] +#![feature( + impl_trait_in_assoc_type, + int_roundings, + type_alias_impl_trait, + type_changing_struct_update +)] pub mod dsn; mod metrics; pub mod piece_cache; pub mod rpc; -pub mod segment_headers; +mod sync_from_dsn; pub mod tx_pre_validator; -use crate::dsn::import_blocks::import_blocks as import_blocks_from_dsn; +use crate::dsn::import_blocks::initial_block_import_from_dsn; use crate::dsn::{create_dsn_instance, DsnConfigurationError}; use crate::metrics::NodeMetrics; use crate::piece_cache::PieceCache; -use crate::segment_headers::{start_segment_header_archiver, SegmentHeaderCache}; -use crate::tx_pre_validator::PrimaryChainTxPreValidator; +use crate::tx_pre_validator::ConsensusChainTxPreValidator; use cross_domain_message_gossip::cdm_gossip_peers_set_config; use derive_more::{Deref, DerefMut, Into}; -use domain_runtime_primitives::Hash as DomainHash; +use domain_runtime_primitives::{BlockNumber as DomainNumber, Hash as DomainHash}; pub use dsn::DsnConfig; use frame_system_rpc_runtime_api::AccountNonceApi; use futures::channel::oneshot; @@ -44,39 +48,40 @@ use sc_client_api::execution_extensions::ExtensionsFactory; use sc_client_api::{ BlockBackend, BlockchainEvents, ExecutorProvider, HeaderBackend, StateBackendFor, }; -use sc_consensus::{BlockImport, DefaultImportQueue}; +use sc_consensus::{BlockImport, DefaultImportQueue, ImportQueue}; use sc_consensus_slots::SlotProportion; use sc_consensus_subspace::notification::SubspaceNotificationStream; use sc_consensus_subspace::{ ArchivedSegmentNotification, BlockImportingNotification, NewSlotNotification, - RewardSigningNotification, SubspaceLink, SubspaceParams, + RewardSigningNotification, SegmentHeadersStore, SubspaceLink, SubspaceParams, + SubspaceSyncOracle, }; use sc_executor::{NativeElseWasmExecutor, NativeExecutionDispatch}; +use sc_network::NetworkService; +use sc_proof_of_time::{pot_gossip_peers_set_config, PotClient, PotComponents, TimeKeeper}; use sc_service::error::Error as ServiceError; use sc_service::{Configuration, NetworkStarter, PartialComponents, SpawnTasksParams, TaskManager}; use sc_subspace_block_relay::{build_consensus_relay, NetworkWrapper}; use sc_telemetry::{Telemetry, TelemetryWorker}; use sp_api::{ApiExt, ConstructRuntimeApi, Metadata, ProvideRuntimeApi, TransactionFor}; use sp_block_builder::BlockBuilder; -use sp_blockchain::HeaderMetadata; -use sp_consensus::{Error as ConsensusError, SyncOracle}; +use sp_blockchain::{HeaderMetadata, Info}; +use sp_consensus::Error as ConsensusError; use sp_consensus_slots::Slot; use sp_consensus_subspace::{FarmerPublicKey, KzgExtension, PosExtension, SubspaceApi}; use sp_core::offchain; use sp_core::traits::SpawnEssentialNamed; use sp_domains::transaction::PreValidationObjectApi; -use sp_domains::ExecutorApi; +use sp_domains::{DomainsApi, GenerateGenesisStateRoot, GenesisReceiptExtension}; use sp_externalities::Extensions; use sp_objects::ObjectsApi; use sp_offchain::OffchainWorkerApi; use sp_runtime::traits::{Block as BlockT, BlockIdTo, NumberFor}; use sp_session::SessionKeys; -use sp_settlement::SettlementApi; use sp_transaction_pool::runtime_api::TaggedTransactionQueue; use std::marker::PhantomData; use std::sync::{Arc, Mutex}; use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; -use subspace_fraud_proof::domain_extrinsics_builder::SystemDomainExtrinsicsBuilder; use subspace_fraud_proof::verifier_api::VerifierClient; use subspace_networking::libp2p::multiaddr::Protocol; use subspace_networking::libp2p::Multiaddr; @@ -84,7 +89,6 @@ use subspace_networking::{peer_id, Node}; use subspace_proof_of_space::Table; use subspace_runtime_primitives::opaque::Block; use subspace_runtime_primitives::{AccountId, Balance, Hash, Index as Nonce}; -use subspace_transaction_pool::bundle_validator::BundleValidator; use subspace_transaction_pool::{FullPool, PreValidateTransaction}; use tracing::{debug, error, info, Instrument}; @@ -138,11 +142,6 @@ pub type InvalidTransactionProofVerifier = Hash, NativeElseWasmExecutor, VerifierClient, Block>, - SystemDomainExtrinsicsBuilder< - Block, - FullClient, - NativeElseWasmExecutor, - >, >; pub type InvalidStateTransitionProofVerifier = @@ -152,11 +151,6 @@ pub type InvalidStateTransitionProofVerifier = NativeElseWasmExecutor, Hash, VerifierClient, Block>, - SystemDomainExtrinsicsBuilder< - Block, - FullClient, - NativeElseWasmExecutor, - >, >; pub type FraudProofVerifier = subspace_fraud_proof::ProofVerifier< @@ -207,6 +201,7 @@ pub struct SubspaceConfiguration { struct SubspaceExtensionsFactory { kzg: Kzg, + domain_genesis_receipt_ext: Option>, _pos_table: PhantomData, } @@ -224,6 +219,9 @@ where let mut exts = Extensions::new(); exts.register(KzgExtension::new(self.kzg.clone())); exts.register(PosExtension::new::()); + if let Some(ext) = self.domain_genesis_receipt_ext.clone() { + exts.register(GenesisReceiptExtension::new(ext)); + } exts } } @@ -232,6 +230,13 @@ where #[allow(clippy::type_complexity)] pub fn new_partial( config: &Configuration, + construct_domain_genesis_block_builder: Option< + &dyn Fn( + Arc, + NativeElseWasmExecutor, + ) -> Arc, + >, + pot_components: Option, ) -> Result< PartialComponents< FullClient, @@ -241,11 +246,10 @@ pub fn new_partial( FullPool< Block, FullClient, - PrimaryChainTxPreValidator< + ConsensusChainTxPreValidator< Block, FullClient, FraudProofVerifier, - BundleValidator>, >, >, ( @@ -255,8 +259,9 @@ pub fn new_partial( Transaction = TransactionFor, Block>, >, SubspaceLink, + SegmentHeadersStore>, Option, - BundleValidator>, + Option, ), >, ServiceError, @@ -273,11 +278,10 @@ where + OffchainWorkerApi + SessionKeys + TaggedTransactionQueue - + ExecutorApi + + SubspaceApi + + DomainsApi + ObjectsApi - + SettlementApi - + PreValidationObjectApi - + SubspaceApi, + + PreValidationObjectApi, ExecutorDispatch: NativeExecutionDispatch + 'static, { let telemetry = config @@ -302,10 +306,14 @@ where let kzg = Kzg::new(embedded_kzg_settings()); + let domain_genesis_receipt_ext = + construct_domain_genesis_block_builder.map(|f| f(backend.clone(), executor.clone())); + client .execution_extensions() .set_extensions_factory(SubspaceExtensionsFactory:: { kzg: kzg.clone(), + domain_genesis_receipt_ext, _pos_table: PhantomData, }); @@ -320,23 +328,16 @@ where let select_chain = sc_consensus::LongestChain::new(backend.clone()); - let bundle_validator = BundleValidator::new(client.clone()); - - let domain_extrinsics_builder = - SystemDomainExtrinsicsBuilder::new(client.clone(), Arc::new(executor.clone())); - let invalid_transaction_proof_verifier = InvalidTransactionProofVerifier::new( client.clone(), Arc::new(executor.clone()), VerifierClient::new(client.clone()), - domain_extrinsics_builder.clone(), ); let invalid_state_transition_proof_verifier = InvalidStateTransitionProofVerifier::new( client.clone(), executor, VerifierClient::new(client.clone()), - domain_extrinsics_builder, ); let proof_verifier = subspace_fraud_proof::ProofVerifier::new( @@ -344,11 +345,10 @@ where Arc::new(invalid_state_transition_proof_verifier), ); - let tx_pre_validator = PrimaryChainTxPreValidator::new( + let tx_pre_validator = ConsensusChainTxPreValidator::new( client.clone(), Box::new(task_manager.spawn_handle()), proof_verifier.clone(), - bundle_validator.clone(), ); let transaction_pool = subspace_transaction_pool::new_full( config, @@ -357,10 +357,19 @@ where tx_pre_validator, ); + let segment_headers_store = SegmentHeadersStore::new(client.clone()) + .map_err(|error| ServiceError::Application(error.into()))?; let fraud_proof_block_import = sc_consensus_fraud_proof::block_import(client.clone(), client.clone(), proof_verifier); - let (block_import, subspace_link) = sc_consensus_subspace::block_import::( + let (block_import, subspace_link) = sc_consensus_subspace::block_import::< + PosTable, + _, + _, + _, + _, + _, + >( sc_consensus_subspace::slot_duration(&*client)?, fraud_proof_block_import, client.clone(), @@ -392,6 +401,10 @@ where } } }, + segment_headers_store.clone(), + pot_components + .as_ref() + .map(|component| component.consensus_state()), )?; let slot_duration = subspace_link.slot_duration(); @@ -420,7 +433,13 @@ where keystore_container, select_chain, transaction_pool, - other: (block_import, subspace_link, telemetry, bundle_validator), + other: ( + block_import, + subspace_link, + segment_headers_store, + telemetry, + pot_components, + ), }) } @@ -434,8 +453,8 @@ where + HeaderMetadata + 'static, Client::Api: TaggedTransactionQueue - + ExecutorApi - + PreValidationObjectApi, + + DomainsApi + + PreValidationObjectApi, TxPreValidator: PreValidateTransaction + Send + Sync + Clone + 'static, { /// Task manager. @@ -445,7 +464,7 @@ where /// Chain selection rule. pub select_chain: FullSelectChain, /// Network service. - pub network_service: Arc::Hash>>, + pub network_service: Arc::Hash>>, /// Sync service. pub sync_service: Arc>, /// RPC handlers. @@ -470,11 +489,10 @@ where type FullNode = NewFull< FullClient, - PrimaryChainTxPreValidator< + ConsensusChainTxPreValidator< Block, FullClient, FraudProofVerifier, - BundleValidator>, >, >; @@ -490,18 +508,18 @@ pub async fn new_full( FullPool< Block, FullClient, - PrimaryChainTxPreValidator< + ConsensusChainTxPreValidator< Block, FullClient, FraudProofVerifier, - BundleValidator>, >, >, ( I, SubspaceLink, + SegmentHeadersStore>, Option, - BundleValidator>, + Option, ), >, enable_rpc_extensions: bool, @@ -521,11 +539,10 @@ where + SessionKeys + TaggedTransactionQueue + TransactionPaymentApi - + ExecutorApi + + SubspaceApi + + DomainsApi + ObjectsApi - + SettlementApi - + PreValidationObjectApi - + SubspaceApi, + + PreValidationObjectApi, ExecutorDispatch: NativeExecutionDispatch + 'static, I: BlockImport< Block, @@ -543,17 +560,15 @@ where keystore_container, select_chain, transaction_pool, - other: (block_import, subspace_link, mut telemetry, mut bundle_validator), + other: (block_import, subspace_link, segment_headers_store, mut telemetry, pot_components), } = partial_components; - let segment_header_cache = SegmentHeaderCache::new(client.clone()); - - let (node, bootstrap_nodes, piece_cache) = match config.subspace_networking.clone() { + let (node, bootstrap_nodes) = match config.subspace_networking.clone() { SubspaceNetworking::Reuse { node, bootstrap_nodes, // TODO: Revisit piece cache creation when we get SDK requirements. - } => (node, bootstrap_nodes, None), + } => (node, bootstrap_nodes), SubspaceNetworking::Create { config: dsn_config, piece_cache_size, @@ -606,8 +621,8 @@ where let (node, mut node_runner) = create_dsn_instance( dsn_protocol_version, dsn_config.clone(), - piece_cache.clone(), - segment_header_cache.clone(), + piece_cache, + segment_headers_store.clone(), )?; info!("Subspace networking initialized: Node ID is {}", node.id()); @@ -618,40 +633,29 @@ where move |address| { info!( "DSN listening on {}", - address.clone().with(Protocol::P2p(node.id().into())) + address.clone().with(Protocol::P2p(node.id())) ); } })) .detach(); - task_manager.spawn_essential_handle().spawn_essential( - "node-runner", - Some("subspace-networking"), - Box::pin( - async move { - node_runner.run().await; - } - .in_current_span(), - ), - ); + task_manager + .spawn_essential_handle() + .spawn_essential_blocking( + "node-runner", + Some("subspace-networking"), + Box::pin( + async move { + node_runner.run().await; + } + .in_current_span(), + ), + ); - (node, dsn_config.bootstrap_nodes, Some(piece_cache)) + (node, dsn_config.bootstrap_nodes) } }; - let segment_header_archiving_fut = start_segment_header_archiver( - segment_header_cache.clone(), - subspace_link - .archived_segment_notification_stream() - .subscribe(), - ); - - task_manager.spawn_essential_handle().spawn_essential( - "segment-header-archiver", - Some("subspace-networking"), - Box::pin(segment_header_archiving_fut.in_current_span()), - ); - let dsn_bootstrap_nodes = { // Fall back to node itself as bootstrap node for DSN so farmer always has someone to // connect to @@ -690,7 +694,7 @@ where } node_listeners.iter_mut().for_each(|multiaddr| { - multiaddr.push(Protocol::P2p(node.id().into())); + multiaddr.push(Protocol::P2p(node.id())); }); node_listeners @@ -699,23 +703,16 @@ where } }; - let subspace_archiver = sc_consensus_subspace::create_subspace_archiver( - &subspace_link, - client.clone(), - telemetry.as_ref().map(|telemetry| telemetry.handle()), - ); - - task_manager - .spawn_essential_handle() - .spawn_essential_blocking("subspace-archiver", None, Box::pin(subspace_archiver)); - + // TODO: This prevents SIGINT from working properly if config.sync_from_dsn { + info!("⚙️ Starting initial sync from DSN, this might take some time"); + let mut imported_blocks = 0; // Repeat until no new blocks are imported loop { let new_imported_blocks = - import_blocks_from_dsn(&node, client.clone(), &mut import_queue, false) + initial_block_import_from_dsn(&node, client.clone(), &mut import_queue, false) .await .map_err(|error| { sc_service::Error::Other(format!( @@ -730,22 +727,25 @@ where imported_blocks += new_imported_blocks; info!( - "🎉 Imported {} blocks, best #{}/#{}", + "🎉 Imported {} blocks from DSN, current best #{}/#{}", imported_blocks, client.info().best_number, client.info().best_hash ); } - info!( - "🎉 Imported {} blocks, best #{}/#{}, check against reliable sources to make sure it is a \ - block on canonical chain", - imported_blocks, - client.info().best_number, - client.info().best_hash - ); + if imported_blocks > 0 { + info!( + "🎉 Imported {} blocks from DSN, best #{}/#{}, check against reliable sources to \ + make sure it is a block on canonical chain", + imported_blocks, + client.info().best_number, + client.info().best_hash + ); + } } + let import_queue_service = import_queue.service(); let network_wrapper = Arc::new(NetworkWrapper::default()); let block_relay = if config.enable_subspace_block_relay { Some(build_consensus_relay( @@ -759,6 +759,8 @@ where }; let mut net_config = sc_network::config::FullNetworkConfiguration::new(&config.network); net_config.add_notification_protocol(cdm_gossip_peers_set_config()); + net_config.add_notification_protocol(pot_gossip_peers_set_config()); + let sync_mode = Arc::clone(&net_config.network_config.sync_mode); let (network_service, system_rpc_tx, tx_handler_controller, network_starter, sync_service) = sc_service::build_network(sc_service::BuildNetworkParams { config: &config, @@ -771,27 +773,48 @@ where warp_sync_params: None, block_relay, })?; + + let subspace_sync_oracle = + SubspaceSyncOracle::new(config.force_authoring, sync_service.clone()); + + let subspace_archiver = sc_consensus_subspace::create_subspace_archiver( + segment_headers_store.clone(), + &subspace_link, + client.clone(), + subspace_sync_oracle.clone(), + telemetry.as_ref().map(|telemetry| telemetry.handle()), + ); + + task_manager + .spawn_essential_handle() + .spawn_essential_blocking("subspace-archiver", None, Box::pin(subspace_archiver)); + if config.enable_subspace_block_relay { network_wrapper.set(network_service.clone()); } - - let sync_oracle = sync_service.clone(); - let best_hash = client.info().best_hash; - let mut imported_blocks_stream = client.import_notification_stream(); - task_manager.spawn_handle().spawn( - "maintain-bundles-stored-in-last-k", - None, - Box::pin(async move { - if !sync_oracle.is_major_syncing() { - bundle_validator.update_recent_stored_bundles(best_hash); - } - while let Some(incoming_block) = imported_blocks_stream.next().await { - if !sync_oracle.is_major_syncing() && incoming_block.is_new_best { - bundle_validator.update_recent_stored_bundles(incoming_block.hash); - } - } - }), - ); + if config.sync_from_dsn { + let (observer, worker) = sync_from_dsn::create_observer_and_worker( + Arc::clone(&network_service), + node.clone(), + Arc::clone(&client), + import_queue_service, + sync_mode, + ); + task_manager + .spawn_handle() + .spawn("observer", Some("sync-from-dsn"), observer); + task_manager + .spawn_essential_handle() + .spawn_essential_blocking( + "worker", + Some("sync-from-dsn"), + Box::pin(async move { + if let Err(error) = worker.await { + error!(%error, "Sync from DSN exited with an error"); + } + }), + ); + } if let Some(registry) = config.prometheus_registry().as_ref() { match NodeMetrics::new( @@ -832,6 +855,49 @@ where let archived_segment_notification_stream = subspace_link.archived_segment_notification_stream(); if config.role.is_authority() || config.force_new_slot_notifications { + let client_cl = client.clone(); + let chain_info_fn: Arc Info + Send + Sync> = + Arc::new(move || client_cl.chain_info()); + let pot_consensus = pot_components + .as_ref() + .map(|component| component.consensus_state()); + if let Some(components) = pot_components { + if components.is_time_keeper() { + let time_keeper = TimeKeeper::::new( + components, + client.clone(), + sync_service.clone(), + network_service.clone(), + sync_service.clone(), + chain_info_fn, + ); + + task_manager.spawn_essential_handle().spawn_blocking( + "subspace-proof-of-time-time-keeper", + Some("pot"), + async move { + time_keeper.run().await; + }, + ); + } else { + let pot_client = PotClient::::new( + components, + client.clone(), + sync_service.clone(), + network_service.clone(), + sync_service.clone(), + chain_info_fn, + ); + task_manager.spawn_essential_handle().spawn_blocking( + "subspace-proof-of-time-client", + Some("pot"), + async move { + pot_client.run().await; + }, + ); + } + } + let proposer_factory = ProposerFactory::new( task_manager.spawn_handle(), client.clone(), @@ -845,7 +911,7 @@ where select_chain: select_chain.clone(), env: proposer_factory, block_import, - sync_oracle: sync_service.clone(), + sync_oracle: subspace_sync_oracle.clone(), justification_sync_link: sync_service.clone(), create_inherent_data_providers: { let client = client.clone(); @@ -878,13 +944,15 @@ where force_authoring: config.force_authoring, backoff_authoring_blocks, subspace_link: subspace_link.clone(), + segment_headers_store: segment_headers_store.clone(), block_proposal_slot_portion, max_block_proposal_slot_portion: None, telemetry: None, + proof_of_time: pot_consensus, }; let subspace = - sc_consensus_subspace::start_subspace::( + sc_consensus_subspace::start_subspace::( subspace_config, )?; @@ -923,9 +991,8 @@ where archived_segment_notification_stream: archived_segment_notification_stream .clone(), dsn_bootstrap_nodes: dsn_bootstrap_nodes.clone(), - subspace_link: subspace_link.clone(), - segment_headers_provider: segment_header_cache.clone(), - piece_provider: piece_cache.clone(), + segment_headers_store: segment_headers_store.clone(), + sync_oracle: subspace_sync_oracle.clone(), }; rpc::create_full(deps).map_err(Into::into) diff --git a/crates/subspace-service/src/piece_cache.rs b/crates/subspace-service/src/piece_cache.rs index 05c2f0516e5..f5f405179f0 100644 --- a/crates/subspace-service/src/piece_cache.rs +++ b/crates/subspace-service/src/piece_cache.rs @@ -4,19 +4,16 @@ mod tests; use parity_scale_codec::{Decode, Encode}; use parking_lot::Mutex; use sc_client_api::backend::AuxStore; -use sc_consensus_subspace_rpc::PieceProvider; -use std::borrow::Cow; use std::collections::BTreeSet; use std::error::Error; -use std::marker::PhantomData; use std::sync::Arc; use subspace_core_primitives::{FlatPieces, Piece, PieceIndex, PieceIndexHash}; use subspace_networking::libp2p::kad::record::Key; use subspace_networking::libp2p::kad::ProviderRecord; use subspace_networking::libp2p::PeerId; use subspace_networking::utils::multihash::ToMultihash; -use subspace_networking::ProviderStorage; -use tracing::{info, trace, warn}; +use subspace_networking::LocalRecordProvider; +use tracing::info; const LOCAL_PROVIDED_KEYS: &[u8] = b"LOCAL_PROVIDED_KEYS"; @@ -28,7 +25,7 @@ pub struct PieceCache { /// Peer ID of the current node. local_peer_id: PeerId, /// Local provided keys - local_provided_keys: Arc>>, + local_provided_keys: Arc>, } impl Clone for PieceCache { @@ -74,30 +71,23 @@ where fn get_local_provided_keys( aux_store: Arc, - ) -> Result>, Box> { + ) -> Result, Box> { Ok(aux_store.get_aux(LOCAL_PROVIDED_KEYS)?.map(|data| { - let collection: ParityDbKeyCollection = + let collection: PieceIndexKeyCollection = data.try_into().expect("DB loading should succeed."); - collection.set + collection })) } fn write_local_provided_keys( &self, - local_provided_keys: BTreeSet, + local_provided_keys: PieceIndexKeyCollection, ) -> Result<(), Box> { // TODO: Could be a slow process. We need to optimize it ASAP! self.aux_store .insert_aux( - &vec![( - LOCAL_PROVIDED_KEYS, - ParityDbKeyCollection { - set: local_provided_keys, - } - .encode() - .as_slice(), - )], + &vec![(LOCAL_PROVIDED_KEYS, local_provided_keys.encode().as_slice())], &Vec::new(), ) .map_err(Into::into) @@ -158,13 +148,8 @@ where let local_provided_keys = { let mut local_provided_keys = self.local_provided_keys.lock(); - for piece_index in delete_indexes { - local_provided_keys.remove(&piece_index); - } - - for piece_index in insert_indexes { - local_provided_keys.insert(piece_index); - } + local_provided_keys.remove_piece_indexes(&delete_indexes); + local_provided_keys.insert_piece_indexes(&insert_indexes); local_provided_keys.clone() }; @@ -196,144 +181,69 @@ where } #[derive(Clone, Debug, Decode, Encode, Default)] -struct ParityDbKeyCollection { - pub set: BTreeSet, +struct PieceIndexKeyCollection { + piece_index_keys: BTreeSet>, } -impl From for Vec { - #[inline] - fn from(value: ParityDbKeyCollection) -> Self { - value.encode() - } -} - -impl TryFrom> for ParityDbKeyCollection { - type Error = parity_scale_codec::Error; - - #[inline] - fn try_from(data: Vec) -> Result { - ParityDbKeyCollection::decode(&mut data.as_slice()).map(Into::into) +impl PieceIndexKeyCollection { + fn insert_piece_indexes(&mut self, indexes: &[PieceIndex]) { + for piece_index in indexes { + let key: Key = piece_index.hash().to_multihash().into(); + self.piece_index_keys.insert(key.to_vec()); + } } -} -impl ProviderStorage for PieceCache -where - AS: AuxStore, -{ - type ProvidedIter<'a> = AuxStoreProviderRecordIterator<'a, AS> where Self:'a; - - fn add_provider( - &self, - rec: ProviderRecord, - ) -> subspace_networking::libp2p::kad::store::Result<()> { - trace!(key=?rec.key, "Attempted to put a provider record to the aux piece record store."); - - Ok(()) + fn remove_piece_indexes(&mut self, indexes: &[PieceIndex]) { + for piece_index in indexes { + let key: Key = piece_index.hash().to_multihash().into(); + self.piece_index_keys.remove::>(&key.to_vec()); + } } - fn providers(&self, key: &Key) -> Vec { - let get_result = self.get_piece_by_index_multihash(key.as_ref()); - - let providers = match get_result { - Ok(result) => result.map(|_| { - vec![ProviderRecord { - key: key.clone(), - provider: self.local_peer_id, - expires: None, - addresses: vec![], // Kademlia adds addresses for local providers - }] - }), - Err(err) => { - warn!( - ?err, - ?key, - "Couldn't get a piece by key from aux piece store." - ); - - None - } - }; - - providers.unwrap_or_default() + fn is_empty(&self) -> bool { + self.piece_index_keys.is_empty() } - fn provided(&self) -> Self::ProvidedIter<'_> { - let pieces_indexes = { - self.local_provided_keys - .lock() - .iter() - .cloned() - .collect::>() - }; - - AuxStoreProviderRecordIterator::new(pieces_indexes, self.clone()) + fn len(&self) -> usize { + self.piece_index_keys.len() } +} - fn remove_provider(&self, key: &Key, peer_id: &PeerId) { - trace!( - ?key, - %peer_id, - "Attempted to remove a provider record from the aux piece record store." - ); +impl From for Vec { + #[inline] + fn from(value: PieceIndexKeyCollection) -> Self { + value.encode() } } -pub struct AuxStoreProviderRecordIterator<'a, AS> { - piece_indexes: Vec, - piece_indexes_cursor: usize, - piece_cache: PieceCache, - marker: PhantomData<&'a ()>, -} +impl TryFrom> for PieceIndexKeyCollection { + type Error = parity_scale_codec::Error; -impl<'a, AS: AuxStore> AuxStoreProviderRecordIterator<'a, AS> { - pub fn new(piece_indexes: Vec, piece_cache: PieceCache) -> Self { - Self { - piece_indexes, - piece_indexes_cursor: 0, - piece_cache, - marker: PhantomData, - } + #[inline] + fn try_from(data: Vec) -> Result { + PieceIndexKeyCollection::decode(&mut data.as_slice()).map(Into::into) } } -impl<'a, AS: AuxStore> Iterator for AuxStoreProviderRecordIterator<'a, AS> { - type Item = Cow<'a, ProviderRecord>; - - fn next(&mut self) -> Option { - if self.piece_indexes.len() == self.piece_indexes_cursor { - return None; // iterator finished - } - - let peer_id = self.piece_cache.local_peer_id; - let piece_index = self.piece_indexes[self.piece_indexes_cursor]; - let piece_index_hash = piece_index.hash(); - let key = Key::from(piece_index_hash.to_multihash()); - - let result = self - .piece_cache - .get_piece(piece_index_hash) - .ok() - .flatten() - .map(move |_| ProviderRecord { +impl LocalRecordProvider for PieceCache +where + AS: AuxStore, +{ + fn record(&self, key: &Key) -> Option { + if self + .local_provided_keys + .lock() + .piece_index_keys + .contains(&key.to_vec()) + { + Some(ProviderRecord { key: key.clone(), - provider: peer_id, + provider: self.local_peer_id, expires: None, addresses: vec![], // Kademlia adds addresses for local providers }) - .map(Cow::Owned); - - // Move iterator cursor forward - self.piece_indexes_cursor += 1; - - result - } -} - -impl PieceProvider for PieceCache { - fn get_piece_by_index( - &self, - piece_index: PieceIndex, - ) -> Result, Box> { - self.get_piece(piece_index.hash()) + } else { + None + } } } diff --git a/crates/subspace-service/src/piece_cache/tests.rs b/crates/subspace-service/src/piece_cache/tests.rs index 5c56b04f488..e9ca3f90b42 100644 --- a/crates/subspace-service/src/piece_cache/tests.rs +++ b/crates/subspace-service/src/piece_cache/tests.rs @@ -1,6 +1,6 @@ use crate::piece_cache::PieceCache; +use parking_lot::RwLock; use sc_client_api::AuxStore; -use std::cell::RefCell; use std::collections::HashMap; use std::sync::Arc; use subspace_core_primitives::{ArchivedHistorySegment, FlatPieces, Piece, PieceIndex}; @@ -9,7 +9,7 @@ use subspace_networking::utils::multihash::ToMultihash; #[derive(Default)] pub struct TestAuxStore { - store: RefCell, Vec>>, + store: RwLock, Vec>>, } impl AuxStore for TestAuxStore { @@ -24,21 +24,20 @@ impl AuxStore for TestAuxStore { I: IntoIterator, D: IntoIterator, { + let mut store = self.store.write(); for pair in insert { - self.store - .borrow_mut() - .insert(pair.0.to_vec(), pair.1.to_vec()); + store.insert(pair.0.to_vec(), pair.1.to_vec()); } for key in delete { - self.store.borrow_mut().remove(&key.to_vec()); + store.remove(&key.to_vec()); } Ok(()) } fn get_aux(&self, key: &[u8]) -> sc_client_api::blockchain::Result>> { - Ok(self.store.borrow().get(&key.to_vec()).cloned()) + Ok(self.store.read().get(&key.to_vec()).cloned()) } } diff --git a/crates/subspace-service/src/rpc.rs b/crates/subspace-service/src/rpc.rs index 12321bfdf96..a4056ea06d0 100644 --- a/crates/subspace-service/src/rpc.rs +++ b/crates/subspace-service/src/rpc.rs @@ -23,14 +23,13 @@ use jsonrpsee::RpcModule; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; -use sc_client_api::BlockBackend; +use sc_client_api::{AuxStore, BlockBackend}; use sc_consensus_subspace::notification::SubspaceNotificationStream; use sc_consensus_subspace::{ - ArchivedSegmentNotification, NewSlotNotification, RewardSigningNotification, SubspaceLink, -}; -use sc_consensus_subspace_rpc::{ - PieceProvider, SegmentHeaderProvider, SubspaceRpc, SubspaceRpcApiServer, + ArchivedSegmentNotification, NewSlotNotification, RewardSigningNotification, + SegmentHeadersStore, SubspaceSyncOracle, }; +use sc_consensus_subspace_rpc::{SubspaceRpc, SubspaceRpcApiServer}; use sc_rpc::SubscriptionTaskExecutor; use sc_rpc_api::DenyUnsafe; use sc_rpc_spec_v2::chain_spec::{ChainSpec, ChainSpecApiServer}; @@ -38,6 +37,7 @@ use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; +use sp_consensus::SyncOracle; use sp_consensus_subspace::FarmerPublicKey; use std::sync::Arc; use subspace_networking::libp2p::Multiaddr; @@ -46,7 +46,10 @@ use subspace_runtime_primitives::{AccountId, Balance, Index}; use substrate_frame_rpc_system::{System, SystemApiServer}; /// Full client dependencies. -pub struct FullDeps { +pub struct FullDeps +where + SO: SyncOracle + Send + Sync + Clone, +{ /// The client instance to use. pub client: Arc, /// Transaction pool instance. @@ -67,17 +70,15 @@ pub struct FullDeps { SubspaceNotificationStream, /// Bootstrap nodes for DSN. pub dsn_bootstrap_nodes: Vec, - /// SubspaceLink shared state. - pub subspace_link: SubspaceLink, /// Segment header provider. - pub segment_headers_provider: RBP, - /// Provides pieces from piece cache. - pub piece_provider: Option, + pub segment_headers_store: SegmentHeadersStore, + /// Subspace sync oracle + pub sync_oracle: SubspaceSyncOracle, } /// Instantiate all full RPC extensions. -pub fn create_full( - deps: FullDeps, +pub fn create_full( + deps: FullDeps, ) -> Result, Box> where C: ProvideRuntimeApi @@ -92,8 +93,8 @@ where + BlockBuilder + sp_consensus_subspace::SubspaceApi, P: TransactionPool + 'static, - RPB: SegmentHeaderProvider + Send + Sync + 'static, - PP: PieceProvider + Send + Sync + 'static, + SO: SyncOracle + Send + Sync + Clone + 'static, + AS: AuxStore + Send + Sync + 'static, { let mut module = RpcModule::new(()); let FullDeps { @@ -106,9 +107,8 @@ where reward_signing_notification_stream, archived_segment_notification_stream, dsn_bootstrap_nodes, - subspace_link, - segment_headers_provider, - piece_provider, + segment_headers_store, + sync_oracle, } = deps; let chain_name = chain_spec.name().to_string(); @@ -127,9 +127,8 @@ where reward_signing_notification_stream, archived_segment_notification_stream, dsn_bootstrap_nodes, - subspace_link, - segment_headers_provider, - piece_provider, + segment_headers_store, + sync_oracle, ) .into_rpc(), )?; diff --git a/crates/subspace-service/src/segment_headers.rs b/crates/subspace-service/src/segment_headers.rs deleted file mode 100644 index 538aa95059e..00000000000 --- a/crates/subspace-service/src/segment_headers.rs +++ /dev/null @@ -1,109 +0,0 @@ -use futures::{Stream, StreamExt}; -use parity_scale_codec::{Decode, Encode}; -use sc_client_api::backend::AuxStore; -use sc_consensus_subspace::ArchivedSegmentNotification; -use sc_consensus_subspace_rpc::SegmentHeaderProvider; -use std::error::Error; -use std::sync::atomic::{AtomicU64, Ordering}; -use std::sync::Arc; -use subspace_core_primitives::{SegmentHeader, SegmentIndex}; -use tracing::{debug, error, trace}; - -/// Start an archiver that will listen for archived segments and send segment header to the storage -pub(crate) async fn start_segment_header_archiver( - mut segment_header_cache: SegmentHeaderCache, - mut archived_segment_notification_stream: impl Stream + Unpin, -) { - trace!("Subspace segment header archiver started."); - - while let Some(ArchivedSegmentNotification { - archived_segment, .. - }) = archived_segment_notification_stream.next().await - { - let segment_index = archived_segment.segment_header.segment_index(); - let result = segment_header_cache.add_segment_header(archived_segment.segment_header); - - if let Err(err) = result { - error!(%segment_index, ?err, "Segment header archiving failed."); - } else { - debug!(%segment_index, "Segment header archived."); - } - } -} - -/// Cache of recently produced segment headers in aux storage -pub struct SegmentHeaderCache { - aux_store: Arc, - // TODO: Consider introducing and using global in-memory segment header cache (this comment is - // in multiple files) - max_segment_index: Arc, -} - -impl Clone for SegmentHeaderCache { - fn clone(&self) -> Self { - Self { - aux_store: self.aux_store.clone(), - max_segment_index: self.max_segment_index.clone(), - } - } -} - -impl SegmentHeaderCache -where - AS: AuxStore, -{ - const KEY_PREFIX: &[u8] = b"segment-headers-cache"; - - /// Create new instance. - pub fn new(aux_store: Arc) -> Self { - Self { - aux_store, - max_segment_index: Default::default(), - } - } - - /// Returns last observed segment index. - pub fn max_segment_index(&self) -> SegmentIndex { - SegmentIndex::from(self.max_segment_index.load(Ordering::Relaxed)) - } - - /// Add segment header to cache (likely as the result of archiving) - pub fn add_segment_header( - &mut self, - segment_header: SegmentHeader, - ) -> Result<(), Box> { - let key = Self::key(segment_header.segment_index()); - let value = segment_header.encode(); - let insert_data = vec![(key.as_slice(), value.as_slice())]; - - self.aux_store.insert_aux(&insert_data, &Vec::new())?; - self.max_segment_index - .store(u64::from(segment_header.segment_index()), Ordering::Relaxed); - - Ok(()) - } - - fn key(segment_index: SegmentIndex) -> Vec { - Self::key_from_bytes(&u64::from(segment_index).to_le_bytes()) - } - - fn key_from_bytes(bytes: &[u8]) -> Vec { - (Self::KEY_PREFIX, bytes).encode() - } -} - -impl SegmentHeaderProvider for SegmentHeaderCache { - /// Get segment header from storage - fn get_segment_header( - &self, - segment_index: SegmentIndex, - ) -> Result, Box> { - Ok(self - .aux_store - .get_aux(&Self::key(segment_index))? - .map(|segment_header| { - SegmentHeader::decode(&mut segment_header.as_slice()) - .expect("Always correct segment header unless DB is corrupted; qed") - })) - } -} diff --git a/crates/subspace-service/src/sync_from_dsn.rs b/crates/subspace-service/src/sync_from_dsn.rs new file mode 100644 index 00000000000..96593c87139 --- /dev/null +++ b/crates/subspace-service/src/sync_from_dsn.rs @@ -0,0 +1,218 @@ +use crate::dsn::import_blocks::import_blocks_from_dsn; +use atomic::Atomic; +use futures::channel::mpsc; +use futures::{FutureExt, StreamExt}; +use sc_client_api::{BlockBackend, BlockchainEvents}; +use sc_consensus::import_queue::ImportQueueService; +use sc_network::config::SyncMode; +use sc_network::{NetworkPeers, NetworkService}; +use sp_api::BlockT; +use sp_blockchain::HeaderBackend; +use sp_consensus::BlockOrigin; +use std::future::Future; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use std::time::Duration; +use subspace_networking::Node; +use tracing::{info, trace, warn}; + +/// How much time to wait for new block to be imported before timing out and starting sync from DSN. +const NO_IMPORTED_BLOCKS_TIMEOUT: Duration = Duration::from_secs(10 * 60); +/// Frequency with which to check whether node is online or not +const CHECK_ONLINE_STATUS_INTERVAL: Duration = Duration::from_secs(10); + +#[derive(Debug)] +enum NotificationReason { + NoImportedBlocks, + WentOnlineSubspace, + WentOnlineSubstrate, +} + +/// Create node observer that will track node state and send notifications to worker to start sync +/// from DSN. +pub(super) fn create_observer_and_worker( + network_service: Arc::Hash>>, + node: Node, + client: Arc, + mut import_queue_service: Box>, + sync_mode: Arc>, +) -> ( + impl Future + Send + 'static, + impl Future> + Send + 'static, +) +where + Block: BlockT, + Client: HeaderBackend + + BlockBackend + + BlockchainEvents + + Send + + Sync + + 'static, +{ + let (tx, rx) = mpsc::channel(0); + let observer_fut = { + let node = node.clone(); + let client = Arc::clone(&client); + + async move { create_observer(network_service.as_ref(), &node, client.as_ref(), tx).await } + }; + let worker_fut = async move { + create_worker( + &node, + client.as_ref(), + import_queue_service.as_mut(), + sync_mode, + rx, + ) + .await + }; + (observer_fut, worker_fut) +} + +async fn create_observer( + network_service: &NetworkService::Hash>, + node: &Node, + client: &Client, + notifications_sender: mpsc::Sender, +) where + Block: BlockT, + Client: BlockchainEvents + Send + Sync + 'static, +{ + // Separate reactive observer for Subspace networking that is not a future + let _handler_id = node.on_num_established_peer_connections_change({ + // Assuming node is online by default + let was_online = AtomicBool::new(false); + let notifications_sender = notifications_sender.clone(); + + Arc::new(move |&new_connections| { + let is_online = new_connections > 0; + let was_online = was_online.swap(is_online, Ordering::AcqRel); + + if is_online && !was_online { + // Doesn't matter if sending failed here + let _ = notifications_sender + .clone() + .try_send(NotificationReason::WentOnlineSubspace); + } + }) + }); + futures::select! { + _ = create_imported_blocks_observer(client, notifications_sender.clone()).fuse() => { + // Runs indefinitely + } + _ = create_substrate_network_observer(network_service, notifications_sender).fuse() => { + // Runs indefinitely + } + // TODO: More sources + } +} + +async fn create_imported_blocks_observer( + client: &Client, + mut notifications_sender: mpsc::Sender, +) where + Block: BlockT, + Client: BlockchainEvents + Send + Sync + 'static, +{ + let mut import_notification_stream = client.every_import_notification_stream(); + loop { + match tokio::time::timeout( + NO_IMPORTED_BLOCKS_TIMEOUT, + import_notification_stream.next(), + ) + .await + { + Ok(Some(_notification)) => { + // Do nothing + } + Ok(None) => { + // No more notifications + return; + } + Err(_timeout) => { + if let Err(error) = + notifications_sender.try_send(NotificationReason::NoImportedBlocks) + { + if error.is_disconnected() { + // Receiving side was closed + return; + } + } + } + } + } +} + +async fn create_substrate_network_observer( + network_service: &NetworkService::Hash>, + mut notifications_sender: mpsc::Sender, +) where + Block: BlockT, +{ + // Assuming node is online by default + let mut was_online = false; + + loop { + tokio::time::sleep(CHECK_ONLINE_STATUS_INTERVAL).await; + + let is_online = network_service.sync_num_connected() > 0; + + if is_online && !was_online { + if let Err(error) = + notifications_sender.try_send(NotificationReason::WentOnlineSubstrate) + { + if error.is_disconnected() { + // Receiving side was closed + return; + } + } + } + + was_online = is_online; + } +} + +async fn create_worker( + node: &Node, + client: &Client, + import_queue_service: &mut IQS, + sync_mode: Arc>, + mut notifications: mpsc::Receiver, +) -> Result<(), sc_service::Error> +where + Block: BlockT, + Client: HeaderBackend + BlockBackend + Send + Sync + 'static, + IQS: ImportQueueService + ?Sized, +{ + while let Some(reason) = notifications.next().await { + // TODO: Remove this condition once we switch to Subspace networking for everything + if matches!(reason, NotificationReason::WentOnlineSubspace) { + trace!("Ignoring Subspace networking for DSN sync for now"); + continue; + } + + let prev_sync_mode = sync_mode.swap(SyncMode::Paused, Ordering::SeqCst); + + while notifications.try_next().is_ok() { + // Just drain extra messages if there are any + } + + info!(?reason, "Received notification to sync from DSN"); + // TODO: Maybe handle failed block imports, additional helpful logging + if let Err(error) = import_blocks_from_dsn( + node, + client, + import_queue_service, + BlockOrigin::NetworkBroadcast, + false, + ) + .await + { + warn!(%error, "Error when syncing blocks from DSN"); + } + + sync_mode.store(prev_sync_mode, Ordering::Release); + } + + Ok(()) +} diff --git a/crates/subspace-service/src/tx_pre_validator.rs b/crates/subspace-service/src/tx_pre_validator.rs index 0f1281ff25f..4b1077aea0b 100644 --- a/crates/subspace-service/src/tx_pre_validator.rs +++ b/crates/subspace-service/src/tx_pre_validator.rs @@ -1,3 +1,4 @@ +use domain_runtime_primitives::{BlockNumber as DomainNumber, Hash as DomainHash}; use sc_transaction_pool::error::Result as TxPoolResult; use sc_transaction_pool_api::error::Error as TxPoolError; use sc_transaction_pool_api::TransactionSource; @@ -6,68 +7,56 @@ use sp_core::traits::SpawnNamed; use sp_domains::transaction::{ InvalidTransactionCode, PreValidationObject, PreValidationObjectApi, }; -use sp_runtime::generic::BlockId; use sp_runtime::traits::Block as BlockT; use std::marker::PhantomData; use std::sync::Arc; use subspace_fraud_proof::VerifyFraudProof; -use subspace_transaction_pool::bundle_validator::ValidateBundle; use subspace_transaction_pool::PreValidateTransaction; -pub struct PrimaryChainTxPreValidator { +pub struct ConsensusChainTxPreValidator { client: Arc, spawner: Box, fraud_proof_verifier: Verifier, - bundle_validator: BundleValidator, _phantom_data: PhantomData, } -impl Clone - for PrimaryChainTxPreValidator +impl Clone for ConsensusChainTxPreValidator where Verifier: Clone, - BundleValidator: Clone, { fn clone(&self) -> Self { Self { client: self.client.clone(), spawner: self.spawner.clone(), fraud_proof_verifier: self.fraud_proof_verifier.clone(), - bundle_validator: self.bundle_validator.clone(), _phantom_data: self._phantom_data, } } } -impl - PrimaryChainTxPreValidator -{ +impl ConsensusChainTxPreValidator { pub fn new( client: Arc, spawner: Box, fraud_proof_verifier: Verifier, - bundle_validator: BundleValidator, ) -> Self { Self { client, spawner, fraud_proof_verifier, - bundle_validator, _phantom_data: Default::default(), } } } #[async_trait::async_trait] -impl PreValidateTransaction - for PrimaryChainTxPreValidator +impl PreValidateTransaction + for ConsensusChainTxPreValidator where Block: BlockT, Client: ProvideRuntimeApi + Send + Sync, - Client::Api: PreValidationObjectApi, + Client::Api: PreValidationObjectApi, Verifier: VerifyFraudProof + Clone + Send + Sync + 'static, - BundleValidator: - ValidateBundle + Clone + Send + Sync + 'static, { type Block = Block; async fn pre_validate_transaction( @@ -86,23 +75,10 @@ where PreValidationObject::Null => { // No pre-validation is required. } - PreValidationObject::Bundle(bundle) => { - if let Err(err) = self - .bundle_validator - .validate_bundle(&BlockId::Hash(at), &bundle) - { - tracing::trace!(target: "txpool", error = ?err, "Dropped `submit_bundle` extrinsic"); - return Err(TxPoolError::ImmediatelyDropped.into()); - } + PreValidationObject::Bundle(_bundle) => { + // TODO: perhaps move the bundle format check here } PreValidationObject::FraudProof(fraud_proof) => { - if !fraud_proof.domain_id().is_system() { - tracing::debug!(target: "txpool", "Wrong fraud proof, expected system domain fraud proof but got: {fraud_proof:?}"); - return Err(TxPoolError::InvalidTransaction( - InvalidTransactionCode::FraudProof.into(), - ) - .into()); - } subspace_fraud_proof::validate_fraud_proof_in_tx_pool( &self.spawner, self.fraud_proof_verifier.clone(), diff --git a/crates/subspace-transaction-pool/Cargo.toml b/crates/subspace-transaction-pool/Cargo.toml index 9863d88213c..d2d2667d3cc 100644 --- a/crates/subspace-transaction-pool/Cargo.toml +++ b/crates/subspace-transaction-pool/Cargo.toml @@ -10,22 +10,23 @@ description = "Subspace transaction pool" [dependencies] async-trait = "0.1.68" -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } domain-runtime-primitives = { version = "0.1.0", path = "../../domains/primitives/runtime" } futures = "0.3.28" jsonrpsee = { version = "0.16.2", features = ["server"] } parking_lot = "0.12.1" -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sc-consensus-subspace = { version = "0.1.0", path = "../sc-consensus-subspace" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace" } sp-domains = { version = "0.1.0", path = "../sp-domains" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +subspace-runtime-primitives = { version = "0.1.0", path = "../../crates/subspace-runtime-primitives" } tracing = "0.1.37" diff --git a/crates/subspace-transaction-pool/src/bundle_validator.rs b/crates/subspace-transaction-pool/src/bundle_validator.rs deleted file mode 100644 index d96e0fd4b5a..00000000000 --- a/crates/subspace-transaction-pool/src/bundle_validator.rs +++ /dev/null @@ -1,356 +0,0 @@ -use codec::Encode; -use domain_runtime_primitives::Hash; -use parking_lot::{Mutex, RwLock}; -use sc_client_api::{AuxStore, BlockBackend, HeaderBackend}; -use sc_consensus_subspace::get_chain_constants; -use sp_api::{HeaderT, ProvideRuntimeApi}; -use sp_blockchain::HeaderMetadata; -use sp_consensus_subspace::{FarmerPublicKey, SubspaceApi}; -use sp_domains::{ExecutorApi, OpaqueBundle}; -use sp_runtime::generic::BlockId; -use sp_runtime::traits::{Block as BlockT, NumberFor, Zero}; -use std::collections::{HashSet, VecDeque}; -use std::marker::PhantomData; -use std::sync::Arc; - -/// `BundleCollector` collect all the bundle from the last K (confirm depth) blocks -/// of the best chain -struct BundleCollector { - client: Arc, - confirm_depth_k: usize, - _phantom_data: PhantomData, -} - -impl Clone for BundleCollector { - fn clone(&self) -> Self { - BundleCollector { - client: self.client.clone(), - confirm_depth_k: self.confirm_depth_k, - _phantom_data: self._phantom_data, - } - } -} - -impl BundleCollector -where - Block: BlockT, - Client: HeaderBackend - + BlockBackend - + HeaderMetadata - + ProvideRuntimeApi - + AuxStore, - Client::Api: ExecutorApi + SubspaceApi, -{ - fn new(client: Arc) -> Self { - let confirm_depth_k = get_chain_constants(client.as_ref()) - .expect("Must always be able to get chain constants") - .confirmation_depth_k() as usize; - BundleCollector { - client, - confirm_depth_k, - _phantom_data: PhantomData, - } - } - - fn successfully_submitted_bundles_at( - &self, - block_hash: Block::Hash, - ) -> sp_blockchain::Result> { - let bundle_hashes: HashSet<_> = self - .client - .runtime_api() - .successful_bundle_hashes(block_hash)? - .into_iter() - .collect(); - Ok(bundle_hashes) - } - - /// Initialize recent stored bundle from the last K block - /// - /// This function should only call when the recent stored bundle is not initialized. - fn initialize_recent_stored_bundles( - &self, - mut hash: Block::Hash, - bundle_stored_in_last_k: &mut VecDeque>, - ) -> sp_blockchain::Result<()> { - assert!( - bundle_stored_in_last_k.is_empty(), - "recent stored bundle already initialized" - ); - // `blocks` sorted from older block to newer block - let mut blocks = VecDeque::new(); - for _ in 0..self.confirm_depth_k { - match self.client.header(hash)? { - Some(header) => { - blocks.push_front((hash, *header.number())); - if header.number().is_zero() { - break; - } - hash = *header.parent_hash() - } - _ => { - return Err(sp_blockchain::Error::Backend(format!( - "BlockHeader of {hash:?} unavailable" - ))) - } - } - } - for (hash, number) in blocks { - let bundles = self.successfully_submitted_bundles_at(hash)?; - bundle_stored_in_last_k.push_front(BlockBundle::new(hash, number, bundles)); - } - Ok(()) - } - - /// Collect bundles from the new blocks of the best chain, blocks are handled from - /// older blcok to newer blcok, an `Err` may return in the middle and left some blocks - /// unhandled, these blocks will be handled when processing the next new best block. - fn on_new_best_block( - &self, - new_best_hash: Block::Hash, - bundle_stored_in_last_k: &mut VecDeque>, - ) -> sp_blockchain::Result<()> { - let current_best_hash = - match BundleStoredInLastK::::best_hash(bundle_stored_in_last_k) { - Some(h) => h, - None => { - self.initialize_recent_stored_bundles(new_best_hash, bundle_stored_in_last_k)?; - return Ok(()); - } - }; - - let route = sp_blockchain::tree_route(&*self.client, current_best_hash, new_best_hash)?; - let (retracted, enacted) = (route.retracted(), route.enacted()); - - // Remove bundles from the stale fork - for retracted_block in retracted { - match bundle_stored_in_last_k.front() { - Some(bb) if bb.block_hash == retracted_block.hash => { - bundle_stored_in_last_k.pop_front(); - } - bb => { - return Err(sp_blockchain::Error::Application(Box::from( - format!( - "Got wrong block from the bundle-collector, expect {:?}, got {:?}, this should not happen", - retracted_block, - bb.map(|bb| bb.block_hash), - ), - ))); - } - } - } - - // Add bundles from the new block of the best fork - for enacted_block in enacted { - let bundles = self.successfully_submitted_bundles_at(enacted_block.hash)?; - bundle_stored_in_last_k.push_front(BlockBundle::new( - enacted_block.hash, - enacted_block.number, - bundles, - )); - } - - // Remove blocks from the back end to keep at most the bundle of the last K blocks - bundle_stored_in_last_k.truncate(self.confirm_depth_k); - - Ok(()) - } -} - -#[derive(Clone)] -struct BlockBundle { - block_hash: Block::Hash, - block_number: NumberFor, - bundle_hashes: HashSet, -} - -impl BlockBundle { - fn new( - block_hash: Block::Hash, - block_number: NumberFor, - bundle_hashes: HashSet, - ) -> Self { - BlockBundle { - block_hash, - block_number, - bundle_hashes, - } - } -} - -/// `BundleStoredInLastK` maintains the last consecutive K blocks of the canonical chain and the bundles -/// stored within these blocks, it also used to share them between thread. -struct BundleStoredInLastK { - // Bundles stored in last K blocks, sorted from newer block to older block. - bundles: Mutex>>, - // `bundle_syncer` used to sync `bundles` to other thread - bundle_syncer: RwLock>>, -} - -impl BundleStoredInLastK { - fn new() -> Self { - BundleStoredInLastK { - bundles: Mutex::new(VecDeque::new()), - bundle_syncer: RwLock::new(VecDeque::new()), - } - } - - fn best_hash(bundles: &VecDeque>) -> Option { - bundles.front().map(|bb| bb.block_hash) - } - - // Update the recent stored bundles with the given closure, the `Mutex` of `bundles` will be held - // while updating but there should only be one thread trying to update it. If the `Mutex` is already - // be held an error will be returned instead of blocking. - fn update_with(&self, update_fn: UpdateFn) -> sp_blockchain::Result<()> - where - UpdateFn: FnOnce(&mut VecDeque>) -> sp_blockchain::Result<()>, - { - let mut bundles = match self.bundles.try_lock() { - Some(b) => b, - None => { - return Err(sp_blockchain::Error::Application(Box::from( - "Failed to acquire bundles Mutex, this should not happen".to_owned(), - ))) - } - }; - let pre_best_hash = Self::best_hash(&bundles); - let res = update_fn(&mut bundles); - if pre_best_hash != Self::best_hash(&bundles) { - *self.bundle_syncer.write() = bundles.clone(); - } - res - } - - fn contains_bundle(&self, hash: Hash) -> bool { - let block_bundles = self.bundle_syncer.read(); - block_bundles - .iter() - .any(|bb| bb.bundle_hashes.contains(&hash)) - } - - // Get the canonical block hash by the given block number - fn get_canonical_block_hash(&self, number: NumberFor) -> Option { - let block_bundles = self.bundle_syncer.read(); - block_bundles - .iter() - .find(|b| b.block_number == number) - .map(|b| b.block_hash) - } -} - -pub struct BundleValidator { - bundle_collector: BundleCollector, - bundle_stored_in_last_k: Arc>, -} - -impl Clone for BundleValidator { - fn clone(&self) -> Self { - BundleValidator { - bundle_collector: self.bundle_collector.clone(), - bundle_stored_in_last_k: self.bundle_stored_in_last_k.clone(), - } - } -} - -impl BundleValidator -where - Block: BlockT, - Client: HeaderBackend - + BlockBackend - + HeaderMetadata - + ProvideRuntimeApi - + AuxStore, - Client::Api: ExecutorApi + SubspaceApi, -{ - pub fn new(client: Arc) -> Self { - BundleValidator { - bundle_collector: BundleCollector::new(client), - bundle_stored_in_last_k: Arc::new(BundleStoredInLastK::new()), - } - } - - pub fn update_recent_stored_bundles(&mut self, new_best_hash: Block::Hash) { - if let Err(err) = self.bundle_stored_in_last_k.update_with(|bundles| { - self.bundle_collector - .on_new_best_block(new_best_hash, bundles) - }) { - tracing::error!( - %err, - "Failed to update recent stored bundles for bundle-validator" - ); - } - } -} - -#[derive(Debug)] -pub enum BundleError { - DuplicatedBundle, - ReceiptInFuture, - ReceiptPointToUnknownBlock, - BlockChain(sp_blockchain::Error), -} - -impl From for BundleError { - #[inline] - fn from(err: sp_blockchain::Error) -> Self { - BundleError::BlockChain(err) - } -} - -pub trait ValidateBundle { - // For consensus chain, check the duplicated bundle and receipts. - // For system domain, checks nothing. - fn validate_bundle( - &self, - at: &BlockId, - opaque_bundle: &OpaqueBundle, Block::Hash, DomainHash>, - ) -> Result<(), BundleError>; -} - -impl ValidateBundle for BundleValidator -where - Block: BlockT, - DomainHash: Encode, - Client: HeaderBackend, -{ - fn validate_bundle( - &self, - at: &BlockId, - opaque_bundle: &OpaqueBundle, Block::Hash, DomainHash>, - ) -> Result<(), BundleError> { - // The hash used here must be the same as what is maintaining in `bundle_stored_in_last_k`, - // namely the hash of `OpaqueBundle` - let incoming_bundle = opaque_bundle.hash(); - // This implement will never return false negative result (i.e return `Err` for a new bundle) - // but it may return false positive result (i.e return `Ok` for a duplicated bundle) if - // `BundleCollector::on_new_best_block` return error and left some blocks unhandled, and it - // will be recovered after successfully handling the next best block. - if self - .bundle_stored_in_last_k - .contains_bundle(incoming_bundle) - { - return Err(BundleError::DuplicatedBundle); - } - - let best_primary_number = self - .bundle_collector - .client - .block_number_from_id(at)? - .ok_or(sp_blockchain::Error::Backend(format!( - "Can not convert BlockId {at:?} to block number" - )))?; - if opaque_bundle.receipt.primary_number > best_primary_number { - return Err(BundleError::ReceiptInFuture); - } - if let Some(expected_hash) = self - .bundle_stored_in_last_k - .get_canonical_block_hash(opaque_bundle.receipt.primary_number) - { - if opaque_bundle.receipt.primary_hash != expected_hash { - return Err(BundleError::ReceiptPointToUnknownBlock); - } - } - Ok(()) - } -} diff --git a/crates/subspace-transaction-pool/src/lib.rs b/crates/subspace-transaction-pool/src/lib.rs index 8da8f3dc0d9..a8fa1b93c33 100644 --- a/crates/subspace-transaction-pool/src/lib.rs +++ b/crates/subspace-transaction-pool/src/lib.rs @@ -25,8 +25,6 @@ use std::pin::Pin; use std::sync::Arc; use substrate_prometheus_endpoint::Registry as PrometheusRegistry; -pub mod bundle_validator; - /// Block hash type for a pool. type BlockHash = <::Block as BlockT>::Hash; diff --git a/crates/subspace-verification/Cargo.toml b/crates/subspace-verification/Cargo.toml index ec7debb91df..dd8e748480c 100644 --- a/crates/subspace-verification/Cargo.toml +++ b/crates/subspace-verification/Cargo.toml @@ -16,11 +16,11 @@ include = [ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } schnorrkel = { version = "0.9.1", default-features = false, features = ["u64_backend"] } -sp-arithmetic = { version = "16.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-arithmetic = { version = "16.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-archiving = { version = "0.1.0", path = "../subspace-archiving", default-features = false } subspace-solving = { version = "0.1.0", path = "../subspace-solving", default-features = false } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives", default-features = false } diff --git a/crates/subspace-verification/src/lib.rs b/crates/subspace-verification/src/lib.rs index 22b1665052a..cabc2de5f82 100644 --- a/crates/subspace-verification/src/lib.rs +++ b/crates/subspace-verification/src/lib.rs @@ -28,10 +28,13 @@ use schnorrkel::SignatureError; use sp_arithmetic::traits::SaturatedConversion; use subspace_archiving::archiver; use subspace_core_primitives::crypto::kzg::Kzg; -use subspace_core_primitives::crypto::{blake2b_256_254_hash_to_scalar, blake2b_256_hash_list}; +use subspace_core_primitives::crypto::{ + blake2b_256_254_hash_to_scalar, blake2b_256_hash_list, blake2b_256_hash_with_key, +}; use subspace_core_primitives::{ - Blake2b256Hash, BlockNumber, BlockWeight, PublicKey, Randomness, Record, RewardSignature, - SectorId, SectorSlotChallenge, SegmentCommitment, SlotNumber, Solution, SolutionRange, + Blake2b256Hash, BlockNumber, BlockWeight, HistorySize, PublicKey, Randomness, Record, + RewardSignature, SectorId, SectorSlotChallenge, SegmentCommitment, SlotNumber, Solution, + SolutionRange, }; use subspace_proof_of_space::Table; @@ -39,7 +42,7 @@ use subspace_proof_of_space::Table; #[derive(Debug, Eq, PartialEq)] #[cfg_attr(feature = "thiserror", derive(thiserror::Error))] pub enum Error { - /// Piece verification failed + /// Invalid piece offset #[cfg_attr(feature = "thiserror", error("Piece verification failed"))] InvalidPieceOffset { /// Index of the piece that failed verification @@ -47,6 +50,14 @@ pub enum Error { /// How many pieces one sector is supposed to contain (max) max_pieces_in_sector: u16, }, + /// Sector expired + #[cfg_attr(feature = "thiserror", error("Sector expired"))] + SectorExpired { + /// Expiration history size + expiration_history_size: HistorySize, + /// Current history size + current_history_size: HistorySize, + }, /// Piece verification failed #[cfg_attr(feature = "thiserror", error("Piece verification failed"))] InvalidPiece, @@ -73,6 +84,9 @@ pub enum Error { /// Invalid chunk witness #[cfg_attr(feature = "thiserror", error("Invalid chunk witness"))] InvalidChunkWitness, + /// Invalid history size + #[cfg_attr(feature = "thiserror", error("Invalid history size"))] + InvalidHistorySize, } /// Check the reward signature validity. @@ -100,15 +114,18 @@ fn calculate_solution_distance( .next() .expect("Solution range is smaller in size than global challenge; qed"), ); - let sector_slot_challenge_as_solution_range: SolutionRange = SolutionRange::from_le_bytes( - *sector_slot_challenge - .array_chunks::<{ mem::size_of::() }>() - .next() - .expect("Solution range is smaller in size than sector slot challenge; qed"), - ); + let sector_slot_challenge_with_audit_chunk = + blake2b_256_hash_with_key(sector_slot_challenge.as_ref(), &audit_chunk.to_le_bytes()); + let sector_slot_challenge_with_audit_chunk_as_solution_range: SolutionRange = + SolutionRange::from_le_bytes( + *sector_slot_challenge_with_audit_chunk + .array_chunks::<{ mem::size_of::() }>() + .next() + .expect("Solution range is smaller in size than blake2b-256 hash; qed"), + ); subspace_core_primitives::bidirectional_distance( &global_challenge_as_solution_range, - &(audit_chunk ^ sector_slot_challenge_as_solution_range), + §or_slot_challenge_with_audit_chunk_as_solution_range, ) } @@ -130,6 +147,16 @@ pub struct PieceCheckParams { pub max_pieces_in_sector: u16, /// Segment commitment of segment to which piece belongs pub segment_commitment: SegmentCommitment, + /// Number of latest archived segments that are considered "recent history" + pub recent_segments: HistorySize, + /// Fraction of pieces from the "recent history" (`recent_segments`) in each sector + pub recent_history_fraction: (HistorySize, HistorySize), + /// Minimum lifetime of a plotted sector, measured in archived segment + pub min_sector_lifetime: HistorySize, + /// Current size of the history + pub current_history_size: HistorySize, + /// Segment commitment at `min_sector_lifetime` from sector creation (if exists) + pub sector_expiration_check_segment_commitment: Option, } /// Parameters for solution verification @@ -178,18 +205,19 @@ where let s_bucket_audit_index = sector_slot_challenge.s_bucket_audit_index(); // Check that proof of space is valid - let quality = match PosTable::is_proof_valid( - §or_id.evaluation_seed(solution.piece_offset, solution.history_size), + if PosTable::is_proof_valid( + §or_id.derive_evaluation_seed(solution.piece_offset, solution.history_size), s_bucket_audit_index.into(), &solution.proof_of_space, - ) { - Some(quality) => quality, - None => { - return Err(Error::InvalidProofOfSpace); - } + ) + .is_none() + { + return Err(Error::InvalidProofOfSpace); }; - let masked_chunk = (Simd::from(solution.chunk.to_bytes()) ^ Simd::from(*quality)).to_array(); + let masked_chunk = (Simd::from(solution.chunk.to_bytes()) + ^ Simd::from(solution.proof_of_space.hash())) + .to_array(); // Extract audit chunk from masked chunk let audit_chunk = match masked_chunk .array_chunks::<{ mem::size_of::() }>() @@ -228,6 +256,11 @@ where if let Some(PieceCheckParams { max_pieces_in_sector, segment_commitment, + recent_segments, + recent_history_fraction, + min_sector_lifetime, + current_history_size, + sector_expiration_check_segment_commitment, }) = piece_check_params { if u16::from(solution.piece_offset) >= *max_pieces_in_sector { @@ -236,9 +269,36 @@ where max_pieces_in_sector: *max_pieces_in_sector, }); } + if let Some(sector_expiration_check_segment_commitment) = + sector_expiration_check_segment_commitment + { + let expiration_history_size = match sector_id.derive_expiration_history_size( + solution.history_size, + sector_expiration_check_segment_commitment, + *min_sector_lifetime, + ) { + Some(expiration_history_size) => expiration_history_size, + None => { + return Err(Error::InvalidHistorySize); + } + }; + + if expiration_history_size <= *current_history_size { + return Err(Error::SectorExpired { + expiration_history_size, + current_history_size: *current_history_size, + }); + } + } let position = sector_id - .derive_piece_index(solution.piece_offset, solution.history_size) + .derive_piece_index( + solution.piece_offset, + solution.history_size, + *max_pieces_in_sector, + *recent_segments, + *recent_history_fraction, + ) .position(); // Check that piece is part of the blockchain history diff --git a/crates/subspace-wasm-tools/Cargo.toml b/crates/subspace-wasm-tools/Cargo.toml deleted file mode 100644 index 20f6aff4634..00000000000 --- a/crates/subspace-wasm-tools/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "subspace-wasm-tools" -description = "Utilities for building WASM bundles" -license = "Apache-2.0" -version = "0.1.0" -authors = ["Nazar Mokrynskyi "] -edition = "2021" -include = [ - "/src", - "/Cargo.toml", -] diff --git a/crates/subspace-wasm-tools/src/lib.rs b/crates/subspace-wasm-tools/src/lib.rs deleted file mode 100644 index 24f0250f385..00000000000 --- a/crates/subspace-wasm-tools/src/lib.rs +++ /dev/null @@ -1,89 +0,0 @@ -use std::path::PathBuf; -use std::{env, fs}; - -/// Emits `cargo:WASM_FILE=/path` so that dependent crates can use it in build script using -/// `DEP_PACKAGE_WASM_FILE` environment variable -/// -/// This also requires `links` attribute in the `package` section of `Cargo.toml` set to the package -/// name. -pub fn export_wasm_bundle_path() { - let mut out_dir = PathBuf::from(env::var("OUT_DIR").expect("Always set by cargo")); - // Removing `build/package-abcd/out` component from - // `target/debug/build/package-abcd/out` - out_dir.pop(); - out_dir.pop(); - out_dir.pop(); - - let package_name = env::var("CARGO_PKG_NAME").expect("Always set by cargo"); - let wasm_base_file_name = package_name.replace('-', "_"); - let wasm_file_path = out_dir - .join("wbuild") - .join(package_name) - .join(format!("{wasm_base_file_name}.compact.wasm")); - - println!("cargo:WASM_FILE={}", wasm_file_path.display()); -} - -/// Creates a `target_file_name` in `OUT_DIR` that will contain constant `bundle_const_name` with -/// runtime of `runtime_crate_name` stored in it. -/// -/// Must be called before Substrate's WASM builder. -pub fn create_runtime_bundle_inclusion_file( - runtime_crate_name: &str, - bundle_const_name: &str, - maybe_link_section_name: Option<&str>, - target_file_name: &str, -) { - // Create a file that will include execution runtime into consensus runtime - let execution_wasm_bundle_path = env::var("SUBSPACE_WASM_BUNDLE_PATH").unwrap_or_else(|_| { - env::var(format!( - "DEP_{}_WASM_FILE", - runtime_crate_name.replace('-', "_").to_ascii_uppercase() - )) - .unwrap_or_else(|_| panic!("{runtime_crate_name:?} Must be set by dependency")) - }); - - env::set_var("SUBSPACE_WASM_BUNDLE_PATH", &execution_wasm_bundle_path); - - let execution_wasm_bundle_rs_path = - env::var("OUT_DIR").expect("Set by cargo; qed") + "/" + target_file_name; - let mut execution_wasm_bundle_rs_contents = format!( - r#" - pub const {bundle_const_name}: &[u8] = include_bytes!("{}"); - "#, - execution_wasm_bundle_path.escape_default() - ); - - if let Some(link_section_name) = maybe_link_section_name { - let wasm_bundle_content = fs::read(&execution_wasm_bundle_path).unwrap_or_else(|e| { - panic!("Failed to read wasm bundle from {execution_wasm_bundle_path:?}: {e}",) - }); - let wasm_bundle_size = wasm_bundle_content.len(); - drop(wasm_bundle_content); - - let link_section_decl = format!( - r#" - const _: () = {{ - #[cfg(not(feature = "std"))] - #[link_section = "{link_section_name}"] - static SECTION_CONTENTS: [u8; {wasm_bundle_size}] = *include_bytes!("{}"); - }}; - "#, - execution_wasm_bundle_path.escape_default() - ); - - execution_wasm_bundle_rs_contents.push_str(&link_section_decl); - } - - fs::write( - execution_wasm_bundle_rs_path, - execution_wasm_bundle_rs_contents, - ) - .unwrap_or_else(|error| { - panic!("Must be able to write to {target_file_name}: {error}"); - }); - - // Ensure this build script is re-run when runtime wasm contents changes. - // This will ensure the inclusion file will be updated with updated WASM contents. - println!("cargo:rerun-if-changed={execution_wasm_bundle_path}"); -} diff --git a/docs/farming.md b/docs/farming.md index 08e93991f59..d27b2f01039 100644 --- a/docs/farming.md +++ b/docs/farming.md @@ -44,21 +44,20 @@ If you're connected directly without any router, then again nothing needs to be # Replace `INSERT_YOUR_ID` with a nickname you choose # Copy all of the lines below, they are all part of the same command .\NODE_FILE_NAME.exe ` ---chain gemini-3d ` +--chain gemini-3e ` --execution wasm ` --blocks-pruning archive ` --state-pruning archive ` ---dsn-disable-private-ips ` --no-private-ipv4 ` --validator ` ---name INSERT_YOUR_ID +--name "INSERT_YOUR_ID" ``` 5. You should see something similar in the terminal: ``` 2022-02-03 10:52:23 Subspace 2022-02-03 10:52:23 ✌️ version 0.1.0-35cf6f5-x86_64-windows 2022-02-03 10:52:23 ❤️ by Subspace Labs , 2021-2022 -2022-02-03 10:52:23 📋 Chain specification: Subspace Gemini 3b +2022-02-03 10:52:23 📋 Chain specification: Subspace Gemini 3e 2022-02-03 10:52:23 🏷 Node name: YOUR_FANCY_NAME 2022-02-03 10:52:23 👤 Role: AUTHORITY 2022-02-03 10:52:23 💾 Database: RocksDb at C:\Users\X\AppData\Local\subspace-node-windows-x86_64-snapshot-2022-jan-05.exe\data\chains\subspace_test\db\full @@ -78,10 +77,11 @@ If you're connected directly without any router, then again nothing needs to be 6. After running this command, Windows may ask you for permissions related to firewall, select `allow` in this case. 7. We will then open another terminal, change to the downloads directory, then start the farmer node with the following command: ```PowerShell +# Replace `PATH_TO_PLOT` with location where you want you store plot files # Replace `FARMER_FILE_NAME.exe` with the name of the farmer file you downloaded from releases # Replace `WALLET_ADDRESS` below with your account address from Polkadot.js wallet # Replace `PLOT_SIZE` with plot size in gigabytes or terabytes, for example 100G or 2T (but leave at least 60G of disk space for node and some for OS) -.\FARMER_FILE_NAME.exe farm --disable-private-ips --reward-address WALLET_ADDRESS --plot-size PLOT_SIZE +.\FARMER_FILE_NAME.exe --farm path=PATH_TO_PLOT,size=PLOT_SIZE farm --reward-address WALLET_ADDRESS ``` ## 🐧 Ubuntu Instructions @@ -96,21 +96,20 @@ If you're connected directly without any router, then again nothing needs to be # Replace `INSERT_YOUR_ID` with a nickname you choose # Copy all of the lines below, they are all part of the same command ./NODE_FILE_NAME \ - --chain gemini-3d \ + --chain gemini-3e \ --execution wasm \ --blocks-pruning archive \ --state-pruning archive \ - --dsn-disable-private-ips \ --no-private-ipv4 \ --validator \ - --name INSERT_YOUR_ID + --name "INSERT_YOUR_ID" ``` 5. You should see something similar in the terminal: ``` 2022-02-03 10:52:23 Subspace 2022-02-03 10:52:23 ✌️ version 0.1.0-35cf6f5-x86_64-ubuntu 2022-02-03 10:52:23 ❤️ by Subspace Labs , 2021-2022 -2022-02-03 10:52:23 📋 Chain specification: Subspace Gemini 3b +2022-02-03 10:52:23 📋 Chain specification: Subspace Gemini 3e 2022-02-03 10:52:23 🏷 Node name: YOUR_FANCY_NAME 2022-02-03 10:52:23 👤 Role: AUTHORITY 2022-02-03 10:52:23 💾 Database: RocksDb at /home/X/.local/share/subspace-node-x86_64-ubuntu-20.04-snapshot-2022-jan-05/chains/subspace_test/db/full @@ -129,10 +128,11 @@ If you're connected directly without any router, then again nothing needs to be ``` 7. We will then open another terminal, change to the downloads directory, then start the farmer node with the following command: ```bash +# Replace `PATH_TO_PLOT` with location where you want you store plot files # Replace `FARMER_FILE_NAME` with the name of the farmer file you downloaded from releases # Replace `WALLET_ADDRESS` below with your account address from Polkadot.js wallet # Replace `PLOT_SIZE` with plot size in gigabytes or terabytes, for example 100G or 2T (but leave at least 60G of disk space for node and some for OS) -./FARMER_FILE_NAME farm --disable-private-ips --reward-address WALLET_ADDRESS --plot-size PLOT_SIZE +./FARMER_FILE_NAME --farm path=PATH_TO_PLOT,size=PLOT_SIZE farm --reward-address WALLET_ADDRESS ``` ## 🍎 macOS Instructions @@ -151,21 +151,20 @@ After this, simply repeat the step you prompted for (step 4 or 6). This time, cl # Replace `INSERT_YOUR_ID` with a nickname you choose # Copy all of the lines below, they are all part of the same command ./NODE_FILE_NAME \ - --chain gemini-3d \ + --chain gemini-3e \ --execution wasm \ --blocks-pruning archive \ --state-pruning archive \ - --dsn-disable-private-ips \ --no-private-ipv4 \ --validator \ - --name INSERT_YOUR_ID + --name "INSERT_YOUR_ID" ``` 5. You should see something similar in the terminal: ``` 2022-02-03 10:52:23 Subspace 2022-02-03 10:52:23 ✌️ version 0.1.0-35cf6f5-x86_64-macos 2022-02-03 10:52:23 ❤️ by Subspace Labs , 2021-2022 -2022-02-03 10:52:23 📋 Chain specification: Subspace Gemini 3b +2022-02-03 10:52:23 📋 Chain specification: Subspace Gemini 3e 2022-02-03 10:52:23 🏷 Node name: YOUR_FANCY_NAME 2022-02-03 10:52:23 👤 Role: AUTHORITY 2022-02-03 10:52:23 💾 Database: RocksDb at /Users/X/Library/Application Support/subspace-node-x86_64-macos-11-snapshot-2022-jan-05/chains/subspace_test/db/full @@ -184,10 +183,11 @@ After this, simply repeat the step you prompted for (step 4 or 6). This time, cl ``` 7. We will then open another terminal, change to the downloads directory, then start the farmer node with the following command: ```bash +# Replace `PATH_TO_PLOT` with location where you want you store plot files # Replace `FARMER_FILE_NAME` with the name of the farmer file you downloaded from releases # Replace `WALLET_ADDRESS` below with your account address from Polkadot.js wallet # Replace `PLOT_SIZE` with plot size in gigabytes or terabytes, for example 100G or 2T (but leave at least 60G of disk space for node and some for OS) -./FARMER_FILE_NAME farm --disable-private-ips --reward-address WALLET_ADDRESS --plot-size PLOT_SIZE +./FARMER_FILE_NAME --farm path=PATH_TO_PLOT,size=PLOT_SIZE farm --reward-address WALLET_ADDRESS ``` 7. It may prompt again in here. Refer to the note on step 4. @@ -214,7 +214,7 @@ services: - "0.0.0.0:30433:30433" restart: unless-stopped command: [ - "--chain", "gemini-3d", + "--chain", "gemini-3e", "--base-path", "/var/subspace", "--execution", "wasm", "--blocks-pruning", "archive", @@ -223,8 +223,7 @@ services: "--dsn-listen-on", "/ip4/0.0.0.0/tcp/30433", "--rpc-cors", "all", "--rpc-methods", "safe", - "--unsafe-ws-external", - "--dsn-disable-private-ips", + "--unsafe-rpc-external", "--no-private-ipv4", "--validator", # Replace `INSERT_YOUR_ID` with your node ID (will be shown in telemetry) @@ -234,7 +233,7 @@ services: timeout: 5s # If node setup takes longer than expected, you want to increase `interval` and `retries` number. interval: 30s - retries: 5 + retries: 60 farmer: depends_on: @@ -255,15 +254,13 @@ services: - "0.0.0.0:30533:30533" restart: unless-stopped command: [ - "--base-path", "/var/subspace", + # Replace `PLOT_SIZE` with plot size in gigabytes or terabytes, for example 100G or 2T (but leave at least 60G of disk space for node and some for OS) + "--farm", "path=/var/subspace,size=PLOT_SIZE", "farm", - "--disable-private-ips", "--node-rpc-url", "ws://node:9944", "--listen-on", "/ip4/0.0.0.0/tcp/30533", # Replace `WALLET_ADDRESS` with your Polkadot.js wallet address "--reward-address", "WALLET_ADDRESS", -# Replace `PLOT_SIZE` with plot size in gigabytes or terabytes, for example 100G or 2T (but leave at least 60G of disk space for node and some for OS) - "--plot-size", "PLOT_SIZE" ] volumes: node-data: @@ -286,7 +283,7 @@ You can read logs with `docker-compose logs --tail=1000 -f`, for the rest read [ ## Checking results and interacting with the network -Visit [Polkadot.js explorer](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Feu-0.gemini-3d.subspace.network%2Fws#/explorer), from there you can interact with Subspace Network as any Substrate-based blockchain. +Visit [Polkadot.js explorer](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Feu-0.gemini-3e.subspace.network%2Fws#/explorer), from there you can interact with Subspace Network as any Substrate-based blockchain. ## Switching from older/different versions of Subspace @@ -295,9 +292,9 @@ Visit [Polkadot.js explorer](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Feu-0. If you were running a node previously, and want to switch to a new snapshot, please perform these steps and then follow the guideline again: ``` # Replace `FARMER_FILE_NAME` with the name of the node file you downloaded from releases -./FARMER_FILE_NAME wipe +./FARMER_FILE_NAME --farm path=PATH_TO_PLOT,size=PLOT_SIZE wipe # Replace `NODE_FILE_NAME` with the name of the node file you downloaded from releases -./NODE_FILE_NAME purge-chain --chain gemini-3d +./NODE_FILE_NAME purge-chain --chain gemini-3e ``` Does not matter if the node/farmer executable is the previous one or from the new snapshot, both will work :) The reason we require this is, with every snapshot change, the network might get partitioned, and you may be on a different genesis than the current one. @@ -317,10 +314,10 @@ There are extra commands and parameters you can use on farmer or node, use the ` Below are some helpful samples: -- `./FARMER_FILE_NAME --base-path /path/to/data farm ...` : will store data in `/path/to/data` instead of default location -- `./FARMER_FILE_NAME --base-path /path/to/data wipe` : erases everything related to farmer if data were stored in `/path/to/data` -- `./NODE_FILE_NAME --base-path /path/to/data --chain gemini-3d ...` : start node and store data in `/path/to/data` instead of default location -- `./NODE_FILE_NAME purge-chain --base-path /path/to/data --chain gemini-3d` : erases data related to the node if data were stored in `/path/to/data` +- `./FARMER_FILE_NAME --farm path=PATH_TO_PLOT,size=PLOT_SIZE farm ...` : will store data in `PATH_TO_PLOT` instead of default location +- `./FARMER_FILE_NAME --farm path=PATH_TO_PLOT,size=PLOT_SIZE wipe` : erases everything related to farmer if data were stored in `PATH_TO_PLOT` +- `./NODE_FILE_NAME --base-path PATH_TO_PLOT --chain gemini-3e ...` : start node and store data in `PATH_TO_PLOT` instead of default location +- `./NODE_FILE_NAME purge-chain --base-path PATH_TO_PLOT --chain gemini-3e` : erases data related to the node if data were stored in `PATH_TO_PLOT` Examples: ```bash @@ -331,23 +328,10 @@ Examples: ## [Advanced] Support for multiple disks -Farmer has an advanced set of parameters that allow using multiple disks. - -To use these advanced parameters you need to replace this command: -``` -./FARMER_FILE_NAME farm --reward-address WALLET_ADDRESS --plot-size PLOT_SIZE -``` - -With this: -``` -./FARMER_FILE_NAME --farm path=/path/to/directory,size=PLOT_SIZE farm --reward-address WALLET_ADDRESS -``` - -`/path/to/directory` is path that will store the data, up to `PLOT_SIZE`. - -NOTE: `PLOT_SIZE` has a different notion here, it doesn't include metadata size! +`--farm` argument you have seen above can be specified more than once to engage multiple disks. +It is recommended to specify multiple disks explicitly rather than using RAID for better hardware utilization and efficiency. -Multiple farms are supported too, for example: +Example: ``` ./FARMER_FILE_NAME \ --farm path=/media/ssd1,size=100GiB \ diff --git a/domains/client/block-builder/Cargo.toml b/domains/client/block-builder/Cargo.toml index daf89cace11..54008525ade 100644 --- a/domains/client/block-builder/Cargo.toml +++ b/domains/client/block-builder/Cargo.toml @@ -13,16 +13,16 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", features = ["derive"] } -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", features = ["derive"] } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } tracing = "0.1.37" [dev-dependencies] -substrate-test-runtime-client = { version = "2.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +substrate-test-runtime-client = { version = "2.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } diff --git a/domains/client/block-preprocessor/Cargo.toml b/domains/client/block-preprocessor/Cargo.toml index d324aafce81..4bb3202c4f2 100644 --- a/domains/client/block-preprocessor/Cargo.toml +++ b/domains/client/block-preprocessor/Cargo.toml @@ -12,27 +12,24 @@ include = [ ] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", features = [ "derive" ] } +codec = { package = "parity-scale-codec", version = "3.6.3", features = [ "derive" ] } domain-runtime-primitives = { version = "0.1.0", path = "../../primitives/runtime" } rand = "0.8.5" rand_chacha = "0.3.1" -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-executor-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-executor-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } sp-messenger = { version = "0.1.0", path = "../../primitives/messenger" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", path = "../../../crates/sp-settlement" } -sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", path = "../../../crates/subspace-core-primitives" } subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives" } -subspace-wasm-tools = { version = "0.1.0", path = "../../../crates/subspace-wasm-tools" } -system-runtime-primitives = { version = "0.1.0", path = "../../primitives/system-runtime" } tracing = "0.1.37" [dev-dependencies] -sp-keyring = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-keyring = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } diff --git a/domains/client/block-preprocessor/src/inherents.rs b/domains/client/block-preprocessor/src/inherents.rs index 9d3fb8547de..0b79b3419f2 100644 --- a/domains/client/block-preprocessor/src/inherents.rs +++ b/domains/client/block-preprocessor/src/inherents.rs @@ -10,33 +10,32 @@ //! and then create an unsigned extrinsic that is put on top the bundle extrinsics. //! //! Deriving these extrinsics during fraud proof verification should be possible since -//! verification environment will have access to primary chain. +//! verification environment will have access to consensus chain. use crate::runtime_api::InherentExtrinsicConstructor; use sp_api::ProvideRuntimeApi; -use sp_domains::ExecutorApi; -use sp_runtime::traits::Block as BlockT; +use sp_domains::DomainsApi; +use sp_runtime::traits::{Block as BlockT, NumberFor}; use std::sync::Arc; /// Returns required inherent extrinsics for the domain block based on the primary block. -/// Note: primary block hash must be used to construct domain block. -// TODO: Remove once evm domain is supported. -#[allow(dead_code)] -pub fn construct_inherent_extrinsics( - primary_client: &Arc, +/// Note: consensus block hash must be used to construct domain block. +pub fn construct_inherent_extrinsics( + consensus_client: &Arc, domain_runtime_api: &DomainRuntimeApi, - primary_block_hash: PBlock::Hash, + consensus_block_hash: CBlock::Hash, domain_parent_hash: Block::Hash, ) -> Result, sp_blockchain::Error> where Block: BlockT, - PBlock: BlockT, - PClient: ProvideRuntimeApi, - PClient::Api: ExecutorApi, + CBlock: BlockT, + CClient: ProvideRuntimeApi, + CClient::Api: DomainsApi, Block::Hash>, DomainRuntimeApi: InherentExtrinsicConstructor, { - let primary_api = primary_client.runtime_api(); - let moment = primary_api.timestamp(primary_block_hash)?; + let moment = consensus_client + .runtime_api() + .timestamp(consensus_block_hash)?; let mut inherent_exts = vec![]; if let Some(inherent_timestamp) = diff --git a/domains/client/block-preprocessor/src/lib.rs b/domains/client/block-preprocessor/src/lib.rs index 05b2eed1c89..80ef802a5bd 100644 --- a/domains/client/block-preprocessor/src/lib.rs +++ b/domains/client/block-preprocessor/src/lib.rs @@ -1,14 +1,10 @@ //! This crate provides a preprocessor for the domain block, which is used to construct -//! domain extrinsics from the primary block. +//! domain extrinsics from the consensus block. //! //! The workflow is as follows: -//! 1. Extract domain-specific bundles from the primary block. +//! 1. Extract domain-specific bundles from the consensus block. //! 2. Compile the domain bundles into a list of extrinsics. -//! - System domain: Each core domain bundle in the primary block will be wrapped -//! in an extrinsic and then joined with the extrinsics extracted from the system -//! domain bundle. -//! - Core domain: Extrinsics extracted from the core domain bundle. -//! 3. Shuffle the extrisnics using the seed from the primary chain. +//! 3. Shuffle the extrisnics using the seed from the consensus chain. //! 4. Filter out the invalid xdm extrinsics. //! 5. Push back the potential new domain runtime extrisnic. @@ -20,119 +16,97 @@ pub mod runtime_api_full; pub mod runtime_api_light; pub mod xdm_verifier; -use crate::runtime_api::{ - CoreBundleConstructor, SetCodeConstructor, SignerExtractor, StateRootExtractor, -}; -use crate::xdm_verifier::verify_xdm_with_primary_chain_client; +use crate::inherents::construct_inherent_extrinsics; +use crate::runtime_api::{SetCodeConstructor, SignerExtractor, StateRootExtractor}; +use crate::xdm_verifier::verify_xdm_with_consensus_client; use codec::{Decode, Encode}; use domain_runtime_primitives::opaque::AccountId; +use domain_runtime_primitives::DomainCoreApi; use rand::seq::SliceRandom; use rand::SeedableRng; use rand_chacha::ChaCha8Rng; +use runtime_api::InherentExtrinsicConstructor; use sc_client_api::BlockBackend; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; -use sp_domains::{DomainId, ExecutorApi, OpaqueBundles}; -use sp_runtime::generic::DigestItem; +use sp_domains::{ + BundleValidity, DomainId, DomainsApi, DomainsDigestItem, ExecutionReceipt, ExtrinsicsRoot, + InvalidBundle, InvalidBundleType, OpaqueBundle, OpaqueBundles, ReceiptValidity, +}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; -use sp_settlement::SettlementApi; use std::borrow::Cow; use std::collections::{BTreeMap, VecDeque}; use std::fmt::Debug; use std::marker::PhantomData; use std::sync::Arc; -use subspace_core_primitives::Randomness; +use subspace_core_primitives::{Randomness, U256}; +use subspace_runtime_primitives::Balance; type MaybeNewRuntime = Option>; -type DomainBlockElements = ( - Vec<::Extrinsic>, +type DomainBlockElements = ( + Vec<::Extrinsic>, Randomness, MaybeNewRuntime, ); /// Extracts the raw materials for building a new domain block from the primary block. -fn prepare_domain_block_elements( +fn prepare_domain_block_elements( domain_id: DomainId, - primary_chain_client: &PClient, - block_hash: PBlock::Hash, -) -> sp_blockchain::Result> + consensus_client: &CClient, + block_hash: CBlock::Hash, +) -> sp_blockchain::Result> where Block: BlockT, - PBlock: BlockT, - PClient: HeaderBackend + BlockBackend + ProvideRuntimeApi + Send + Sync, - PClient::Api: ExecutorApi, + CBlock: BlockT, + CClient: HeaderBackend + BlockBackend + ProvideRuntimeApi + Send + Sync, + CClient::Api: DomainsApi, Block::Hash>, { - let extrinsics = primary_chain_client - .block_body(block_hash)? - .ok_or_else(|| { - sp_blockchain::Error::Backend(format!("BlockBody of {block_hash:?} unavailable")) - })?; + let extrinsics = consensus_client.block_body(block_hash)?.ok_or_else(|| { + sp_blockchain::Error::Backend(format!("BlockBody of {block_hash:?} unavailable")) + })?; - let header = primary_chain_client.header(block_hash)?.ok_or_else(|| { + let header = consensus_client.header(block_hash)?.ok_or_else(|| { sp_blockchain::Error::Backend(format!("BlockHeader of {block_hash:?} unavailable")) })?; + let runtime_id = consensus_client + .runtime_api() + .runtime_id(block_hash, domain_id)? + .ok_or_else(|| { + sp_blockchain::Error::Application(Box::from(format!( + "Runtime id not found for {domain_id:?}" + ))) + })?; + let maybe_new_runtime = if header .digest() .logs .iter() - .any(|item| *item == DigestItem::RuntimeEnvironmentUpdated) + .filter_map(|log| log.as_domain_runtime_upgrade()) + .any(|upgraded_runtime_id| upgraded_runtime_id == runtime_id) { - let system_domain_runtime = primary_chain_client + let new_domain_runtime = consensus_client .runtime_api() - .system_domain_wasm_bundle(block_hash)?; - - let new_runtime = { - if domain_id.is_system() { - system_domain_runtime - } else { - return Err(sp_blockchain::Error::Application(Box::from(format!( + .domain_runtime_code(block_hash, domain_id)? + .ok_or_else(|| { + sp_blockchain::Error::Application(Box::from(format!( "No new runtime code for {domain_id:?}" - )))); - } - }; + ))) + })?; - Some(new_runtime) + Some(new_domain_runtime.into()) } else { None }; - let shuffling_seed = primary_chain_client + let shuffling_seed = consensus_client .runtime_api() .extrinsics_shuffling_seed(block_hash, header)?; Ok((extrinsics, shuffling_seed, maybe_new_runtime)) } -fn compile_own_domain_bundles( - bundles: OpaqueBundles, -) -> Vec -where - Block: BlockT, - PBlock: BlockT, -{ - bundles - .into_iter() - .flat_map(|bundle| { - bundle.extrinsics.into_iter().filter_map(|opaque_extrinsic| { - match <::Extrinsic>::decode( - &mut opaque_extrinsic.encode().as_slice(), - ) { - Ok(uxt) => Some(uxt), - Err(e) => { - tracing::error!( - error = ?e, - "Failed to decode the opaque extrisic in bundle, this should not happen" - ); - None - } - } - }) - }) - .collect::>() -} - fn deduplicate_and_shuffle_extrinsics( parent_hash: Block::Hash, signer_extractor: &SE, @@ -219,95 +193,127 @@ fn shuffle_extrinsics( shuffled_extrinsics } -pub struct SystemDomainBlockPreprocessor { - primary_chain_client: Arc, +pub struct PreprocessResult { + pub extrinsics: Vec, + pub extrinsics_roots: Vec, + pub invalid_bundles: Vec, +} + +pub struct DomainBlockPreprocessor { + domain_id: DomainId, + client: Arc, + consensus_client: Arc, runtime_api: RuntimeApi, - _phantom_data: PhantomData<(Block, PBlock)>, + receipt_validator: ReceiptValidator, + _phantom_data: PhantomData<(Block, CBlock)>, } -impl Clone - for SystemDomainBlockPreprocessor +impl Clone + for DomainBlockPreprocessor { fn clone(&self) -> Self { Self { - primary_chain_client: self.primary_chain_client.clone(), + domain_id: self.domain_id, + client: self.client.clone(), + consensus_client: self.consensus_client.clone(), runtime_api: self.runtime_api.clone(), + receipt_validator: self.receipt_validator.clone(), _phantom_data: self._phantom_data, } } } -impl - SystemDomainBlockPreprocessor +pub trait ValidateReceipt where Block: BlockT, - PBlock: BlockT, - PBlock::Hash: From, - NumberFor: From>, - RuntimeApi: CoreBundleConstructor - + SignerExtractor + CBlock: BlockT, +{ + fn validate_receipt( + &self, + receipt: &ExecutionReceipt< + NumberFor, + CBlock::Hash, + NumberFor, + Block::Hash, + Balance, + >, + ) -> sp_blockchain::Result; +} + +impl + DomainBlockPreprocessor +where + Block: BlockT, + CBlock: BlockT, + CBlock::Hash: From, + NumberFor: From>, + RuntimeApi: SignerExtractor + StateRootExtractor - + SetCodeConstructor, - PClient: HeaderBackend - + BlockBackend - + ProvideRuntimeApi + + SetCodeConstructor + + InherentExtrinsicConstructor, + Client: ProvideRuntimeApi + 'static, + Client::Api: DomainCoreApi, + CClient: HeaderBackend + + BlockBackend + + ProvideRuntimeApi + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, + CClient::Api: DomainsApi, Block::Hash>, + ReceiptValidator: ValidateReceipt, { - pub fn new(primary_chain_client: Arc, runtime_api: RuntimeApi) -> Self { + pub fn new( + domain_id: DomainId, + client: Arc, + consensus_client: Arc, + runtime_api: RuntimeApi, + receipt_validator: ReceiptValidator, + ) -> Self { Self { - primary_chain_client, + domain_id, + client, + consensus_client, runtime_api, + receipt_validator, _phantom_data: Default::default(), } } - pub fn preprocess_primary_block_for_verifier( - &self, - primary_hash: PBlock::Hash, - ) -> sp_blockchain::Result>> { - // `domain_hash` is unused in `preprocess_primary_block` when using stateless runtime api. - let domain_hash = Default::default(); - Ok(self - .preprocess_primary_block(primary_hash, domain_hash)? - .into_iter() - .map(|ext| ext.encode()) - .collect()) - } - - pub fn preprocess_primary_block( + pub fn preprocess_consensus_block( &self, - primary_hash: PBlock::Hash, + consensus_block_hash: CBlock::Hash, domain_hash: Block::Hash, - ) -> sp_blockchain::Result> { + ) -> sp_blockchain::Result>> { let (primary_extrinsics, shuffling_seed, maybe_new_runtime) = - prepare_domain_block_elements::( - DomainId::SYSTEM, - &*self.primary_chain_client, - primary_hash, + prepare_domain_block_elements::( + self.domain_id, + &*self.consensus_client, + consensus_block_hash, )?; - let (system_bundles, core_bundles) = self - .primary_chain_client + let bundles = self + .consensus_client .runtime_api() - .extract_system_bundles(primary_hash, primary_extrinsics)?; + .extract_successful_bundles(consensus_block_hash, self.domain_id, primary_extrinsics)?; - let origin_system_extrinsics = compile_own_domain_bundles::(system_bundles); + if bundles.is_empty() && maybe_new_runtime.is_none() { + return Ok(None); + } - let extrinsics = self - .runtime_api - .construct_submit_core_bundle_extrinsics(domain_hash, core_bundles)? - .into_iter() - .map(|uxt| { - <::Extrinsic>::decode(&mut uxt.as_slice()) - .expect("Internally constructed extrinsic must be valid; qed") - }) - .chain(origin_system_extrinsics) - .collect::>(); + let extrinsics_roots = bundles + .iter() + .map(|bundle| bundle.extrinsics_root()) + .collect(); + + let tx_range = self + .consensus_client + .runtime_api() + .domain_tx_range(consensus_block_hash, self.domain_id)?; - let mut extrinsics = deduplicate_and_shuffle_extrinsics( + let (invalid_bundles, extrinsics) = + self.compile_bundles_to_extrinsics(bundles, tx_range, domain_hash)?; + + let extrinsics_in_bundle = deduplicate_and_shuffle_extrinsics( domain_hash, &self.runtime_api, extrinsics, @@ -315,6 +321,16 @@ where ) .map(|exts| self.filter_invalid_xdm_extrinsics(domain_hash, exts))?; + // Fetch inherent extrinsics + let mut extrinsics = construct_inherent_extrinsics( + &self.consensus_client, + &self.runtime_api, + consensus_block_hash, + domain_hash, + )?; + + extrinsics.extend(extrinsics_in_bundle); + if let Some(new_runtime) = maybe_new_runtime { let encoded_set_code = self .runtime_api @@ -327,8 +343,105 @@ where })?; extrinsics.push(set_code_extrinsic); } + Ok(Some(PreprocessResult { + extrinsics, + extrinsics_roots, + invalid_bundles, + })) + } + + /// Filter out the invalid bundles first and then convert the remaining valid ones to + /// a list of extrinsics. + fn compile_bundles_to_extrinsics( + &self, + bundles: OpaqueBundles, Block::Hash, Balance>, + tx_range: U256, + at: Block::Hash, + ) -> sp_blockchain::Result<(Vec, Vec)> { + let mut invalid_bundles = Vec::with_capacity(bundles.len()); + let mut valid_extrinsics = Vec::new(); + + for (index, bundle) in bundles.into_iter().enumerate() { + match self.check_bundle_validity(&bundle, &tx_range, at)? { + BundleValidity::Valid(extrinsics) => valid_extrinsics.extend(extrinsics), + BundleValidity::Invalid(invalid_bundle_type) => { + invalid_bundles.push(InvalidBundle { + bundle_index: index as u32, + invalid_bundle_type, + }); + } + } + } + + Ok((invalid_bundles, valid_extrinsics)) + } + + fn check_bundle_validity( + &self, + bundle: &OpaqueBundle< + NumberFor, + CBlock::Hash, + NumberFor, + Block::Hash, + Balance, + >, + tx_range: &U256, + at: Block::Hash, + ) -> sp_blockchain::Result> { + // Bundles with incorrect ER are considered invalid. + if let ReceiptValidity::Invalid(invalid_receipt) = + self.receipt_validator.validate_receipt(bundle.receipt())? + { + return Ok(BundleValidity::Invalid(InvalidBundleType::InvalidReceipt( + invalid_receipt, + ))); + } + + let bundle_vrf_hash = + U256::from_be_bytes(bundle.sealed_header.header.proof_of_election.vrf_hash()); + + let mut extrinsics = Vec::with_capacity(bundle.extrinsics.len()); + + for opaque_extrinsic in &bundle.extrinsics { + let Ok(extrinsic) = + <::Extrinsic>::decode(&mut opaque_extrinsic.encode().as_slice()) + else { + tracing::error!( + ?opaque_extrinsic, + "Undecodable extrinsic in bundle({})", + bundle.hash() + ); + return Ok(BundleValidity::Invalid(InvalidBundleType::UndecodableTx)); + }; + + let is_within_tx_range = self.client.runtime_api().is_within_tx_range( + at, + &extrinsic, + &bundle_vrf_hash, + tx_range, + )?; + + if !is_within_tx_range { + // TODO: Generate a fraud proof for this invalid bundle + return Ok(BundleValidity::Invalid(InvalidBundleType::OutOfRangeTx)); + } + + // TODO: the `check_transaction_validity` is unimplemented + let is_legal_tx = self + .client + .runtime_api() + .check_transaction_validity(at, &extrinsic, at)? + .is_ok(); + + if !is_legal_tx { + // TODO: Generate a fraud proof for this invalid bundle + return Ok(BundleValidity::Invalid(InvalidBundleType::IllegalTx)); + } + + extrinsics.push(extrinsic); + } - Ok(extrinsics) + Ok(BundleValidity::Valid(extrinsics)) } fn filter_invalid_xdm_extrinsics( @@ -338,19 +451,16 @@ where ) -> Vec { exts.into_iter() .filter(|ext| { - match verify_xdm_with_primary_chain_client::( - &self.primary_chain_client, + match verify_xdm_with_consensus_client::( + self.domain_id, + &self.consensus_client, at, &self.runtime_api, ext, ) { Ok(valid) => valid, Err(err) => { - tracing::error!( - target = "system_domain_xdm_filter", - "failed to verify extrinsic: {}", - err - ); + tracing::error!("failed to verify extrinsic: {err}",); false } } diff --git a/domains/client/block-preprocessor/src/runtime_api.rs b/domains/client/block-preprocessor/src/runtime_api.rs index 7a64c84ee31..4f54e86e081 100644 --- a/domains/client/block-preprocessor/src/runtime_api.rs +++ b/domains/client/block-preprocessor/src/runtime_api.rs @@ -1,6 +1,5 @@ use domain_runtime_primitives::opaque::AccountId; use sp_api::{ApiError, BlockT}; -use sp_domains::OpaqueBundle; use sp_messenger::messages::ExtractedStateRootsFromProof; use sp_runtime::traits::NumberFor; @@ -20,15 +19,6 @@ pub trait StateRootExtractor { ) -> Result, ApiError>; } -/// Trait to extract core domain bundles from the given set of core domain extrinsics. -pub trait CoreBundleConstructor { - fn construct_submit_core_bundle_extrinsics( - &self, - at: Block::Hash, - opaque_bundles: Vec, PBlock::Hash, Block::Hash>>, - ) -> Result>, ApiError>; -} - /// Trait to construct inherent extrinsics pub trait InherentExtrinsicConstructor { /// Returns Inherent timestamp extrinsic if the Runtime implements the API. diff --git a/domains/client/block-preprocessor/src/runtime_api_full.rs b/domains/client/block-preprocessor/src/runtime_api_full.rs index 9b2e0e7daa2..3afd53c177a 100644 --- a/domains/client/block-preprocessor/src/runtime_api_full.rs +++ b/domains/client/block-preprocessor/src/runtime_api_full.rs @@ -1,16 +1,14 @@ use crate::runtime_api::{ - CoreBundleConstructor, ExtractSignerResult, ExtractedStateRoots, InherentExtrinsicConstructor, - SetCodeConstructor, SignerExtractor, StateRootExtractor, + ExtractSignerResult, ExtractedStateRoots, InherentExtrinsicConstructor, SetCodeConstructor, + SignerExtractor, StateRootExtractor, }; use codec::Encode; use domain_runtime_primitives::{DomainCoreApi, InherentExtrinsicApi}; use sp_api::{ApiError, BlockT, ProvideRuntimeApi}; -use sp_domains::OpaqueBundle; use sp_messenger::MessengerApi; use sp_runtime::traits::NumberFor; use std::sync::Arc; use subspace_runtime_primitives::Moment; -use system_runtime_primitives::SystemDomainApi; /// A runtime api with full backend. pub struct RuntimeApiFull { @@ -50,23 +48,6 @@ where } } -impl CoreBundleConstructor for RuntimeApiFull -where - PBlock: BlockT, - Block: BlockT, - Client: ProvideRuntimeApi, - Client::Api: SystemDomainApi, PBlock::Hash, Block::Hash>, -{ - fn construct_submit_core_bundle_extrinsics( - &self, - at: Block::Hash, - opaque_bundles: Vec, PBlock::Hash, Block::Hash>>, - ) -> Result>, ApiError> { - let api = self.client.runtime_api(); - api.construct_submit_core_bundle_extrinsics(at, opaque_bundles) - } -} - impl InherentExtrinsicConstructor for RuntimeApiFull where Block: BlockT, diff --git a/domains/client/block-preprocessor/src/runtime_api_light.rs b/domains/client/block-preprocessor/src/runtime_api_light.rs index c6bb55d8531..b9f8c1d4fe8 100644 --- a/domains/client/block-preprocessor/src/runtime_api_light.rs +++ b/domains/client/block-preprocessor/src/runtime_api_light.rs @@ -1,6 +1,6 @@ use crate::runtime_api::{ - CoreBundleConstructor, ExtractSignerResult, ExtractedStateRoots, InherentExtrinsicConstructor, - SetCodeConstructor, SignerExtractor, StateRootExtractor, + ExtractSignerResult, ExtractedStateRoots, InherentExtrinsicConstructor, SetCodeConstructor, + SignerExtractor, StateRootExtractor, }; use codec::{Codec, Encode}; use domain_runtime_primitives::{DomainCoreApi, InherentExtrinsicApi}; @@ -8,7 +8,6 @@ use sc_executor_common::runtime_blob::RuntimeBlob; use sp_api::{ApiError, BlockT, Core, Hasher, RuntimeVersion}; use sp_core::traits::{CallContext, CodeExecutor, FetchRuntimeCode, RuntimeCode}; use sp_core::ExecutionContext; -use sp_domains::OpaqueBundle; use sp_messenger::MessengerApi; use sp_runtime::traits::NumberFor; use sp_runtime::Storage; @@ -16,7 +15,6 @@ use sp_state_machine::BasicExternalities; use std::borrow::Cow; use std::sync::Arc; use subspace_runtime_primitives::Moment; -use system_runtime_primitives::SystemDomainApi; /// Lightweight runtime api based on the runtime code and partial state. /// @@ -170,25 +168,6 @@ where } } -impl SystemDomainApi - for RuntimeApiLight -where - Block: BlockT, - PNumber: Codec, - PHash: Codec, - Executor: CodeExecutor, -{ - fn __runtime_api_internal_call_api_at( - &self, - _at: ::Hash, - _context: ExecutionContext, - params: Vec, - fn_name: &dyn Fn(RuntimeVersion) -> &'static str, - ) -> Result, ApiError> { - self.dispatch_call(fn_name, params) - } -} - impl InherentExtrinsicApi for RuntimeApiLight where Block: BlockT, @@ -205,23 +184,6 @@ where } } -impl CoreBundleConstructor for RuntimeApiLight -where - PBlock: BlockT, - Block: BlockT, - Executor: CodeExecutor, -{ - fn construct_submit_core_bundle_extrinsics( - &self, - at: Block::Hash, - opaque_bundles: Vec, PBlock::Hash, Block::Hash>>, - ) -> Result>, ApiError> { - , PBlock::Hash, Block::Hash>>::construct_submit_core_bundle_extrinsics( - self, at, opaque_bundles, - ) - } -} - impl SignerExtractor for RuntimeApiLight where Block: BlockT, diff --git a/domains/client/block-preprocessor/src/xdm_verifier.rs b/domains/client/block-preprocessor/src/xdm_verifier.rs index f26cf64e960..eded9b4d845 100644 --- a/domains/client/block-preprocessor/src/xdm_verifier.rs +++ b/domains/client/block-preprocessor/src/xdm_verifier.rs @@ -1,114 +1,49 @@ +// TODO: Remove one the subsequent TODO is resolved. +#![allow(unused)] + use crate::runtime_api::StateRootExtractor; use sp_api::ProvideRuntimeApi; use sp_blockchain::{Error, HeaderBackend}; -use sp_domains::DomainId; +use sp_domains::{DomainId, DomainsApi}; use sp_messenger::MessengerApi; use sp_runtime::traits::{Block as BlockT, CheckedSub, Header, NumberFor}; -use sp_settlement::SettlementApi; use std::sync::Arc; /// Verifies if the xdm has the correct proof generated from known parent block. -/// This is used by Core domain nodes. -/// Core domains nodes use this to verify an XDM coming from other domains. +/// This is used by the System domain to validate Extrinsics. /// Returns either true if the XDM is valid else false. /// Returns Error when required calls to fetch header info fails. -pub fn verify_xdm_with_system_domain_client( - system_domain_client: &Arc, +pub fn verify_xdm_with_consensus_client( + _domain_id: DomainId, + consensus_client: &Arc, at: Block::Hash, - extrinsic: &Block::Extrinsic, state_root_extractor: &SRE, + extrinsic: &Block::Extrinsic, ) -> Result where - SClient: HeaderBackend + ProvideRuntimeApi + 'static, - SClient::Api: MessengerApi> + SettlementApi, + CClient: HeaderBackend + ProvideRuntimeApi + 'static, + CClient::Api: DomainsApi, Block::Hash>, Block: BlockT, - SBlock: BlockT, - SBlock::Hash: From, - NumberFor: From>, - PBlock: BlockT, + CBlock: BlockT, + NumberFor: From>, + CBlock::Hash: From, SRE: StateRootExtractor, { - if let Ok(state_roots) = state_root_extractor.extract_state_roots(at, extrinsic) { - // verify system domain state root - let header = system_domain_client - .header(state_roots.system_domain_block_info.block_hash.into())? - .ok_or(Error::MissingHeader(format!( - "hash: {}", - state_roots.system_domain_block_info.block_hash - )))?; - - if *header.number() != state_roots.system_domain_block_info.block_number.into() { - return Ok(false); - } - - if *header.state_root() != state_roots.system_domain_state_root.into() { - return Ok(false); - } - - // verify core domain state root and the if the number is K-deep. - let best_hash = system_domain_client.info().best_hash; - let api = system_domain_client.runtime_api(); - if let Some((domain_id, core_domain_info, core_domain_state_root)) = - state_roots.core_domain_info - { - let best_number = api.head_receipt_number(best_hash, domain_id)?; - if let Some(confirmed_number) = - best_number.checked_sub(&api.confirmation_depth(best_hash)?) - { - if confirmed_number < core_domain_info.block_number.into() { - return Ok(false); - } - } - - if let Some(expected_core_domain_state_root) = api.state_root( - best_hash, - domain_id, - core_domain_info.block_number.into(), - core_domain_info.block_hash.into(), - )? { - if expected_core_domain_state_root != core_domain_state_root { - return Ok(false); - } - } - } - } - - Ok(true) -} - -/// Verifies if the xdm has the correct proof generated from known parent block. -/// This is used by the System domain to validate Extrinsics. -/// Returns either true if the XDM is valid else false. -/// Returns Error when required calls to fetch header info fails. -pub fn verify_xdm_with_primary_chain_client( - primary_chain_client: &Arc, - at: SBlock::Hash, - state_root_extractor: &SRE, - extrinsic: &SBlock::Extrinsic, -) -> Result -where - PClient: HeaderBackend + ProvideRuntimeApi + 'static, - PClient::Api: SettlementApi, - SBlock: BlockT, - PBlock: BlockT, - NumberFor: From>, - PBlock::Hash: From, - SRE: StateRootExtractor, -{ - if let Ok(state_roots) = state_root_extractor.extract_state_roots(at, extrinsic) { + if let Ok(_state_roots) = state_root_extractor.extract_state_roots(at, extrinsic) { // verify system domain state root - let best_hash = primary_chain_client.info().best_hash; - let primary_runtime = primary_chain_client.runtime_api(); - if let Some(system_domain_state_root) = primary_runtime.state_root( - best_hash, - DomainId::SYSTEM, - state_roots.system_domain_block_info.block_number.into(), - state_roots.system_domain_block_info.block_hash.into(), - )? { - if system_domain_state_root != state_roots.system_domain_state_root { - return Ok(false); - } - } + let _best_hash = consensus_client.info().best_hash; + let _primary_runtime = consensus_client.runtime_api(); + // TODO: Add `state_root` in DomainsApi + // if let Some(system_domain_state_root) = primary_runtime.state_root( + // best_hash, + // domain_id, + // state_roots.system_domain_block_info.block_number.into(), + // state_roots.system_domain_block_info.block_hash.into(), + // )? { + // if system_domain_state_root != state_roots.system_domain_state_root { + // return Ok(false); + // } + // } } Ok(true) diff --git a/domains/client/consensus-relay-chain/Cargo.toml b/domains/client/consensus-relay-chain/Cargo.toml index f49b64552cd..5fb8bf2b6c5 100644 --- a/domains/client/consensus-relay-chain/Cargo.toml +++ b/domains/client/consensus-relay-chain/Cargo.toml @@ -9,10 +9,10 @@ edition = "2021" async-trait = "0.1.68" futures = "0.3.28" parking_lot = "0.12.1" -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } diff --git a/domains/client/cross-domain-message-gossip/Cargo.toml b/domains/client/cross-domain-message-gossip/Cargo.toml index f3769c4fb0e..ff590c486a7 100644 --- a/domains/client/cross-domain-message-gossip/Cargo.toml +++ b/domains/client/cross-domain-message-gossip/Cargo.toml @@ -13,14 +13,14 @@ include = [ [dependencies] futures = "0.3.28" -parity-scale-codec = { version = "3.4.0", features = ["derive"] } +parity-scale-codec = { version = "3.6.3", features = ["derive"] } parking_lot = "0.12.1" -sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } tracing = "0.1.37" diff --git a/domains/client/domain-executor/README.md b/domains/client/domain-executor/README.md deleted file mode 100644 index 037dafcd1ff..00000000000 --- a/domains/client/domain-executor/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# Domain Executor - -## Overview - -```text - +-------------------------+ - Primary Chain Events | Executor | - | | -+----------------------+ | +----------------+ | -| New Slot |------------->| BundleProducer | | -+----------------------+ | +----------------+ | - | | - | | -+----------------------+ | +-----------------+ | -| Primary Block Import |------------->| BundleProcessor | | -+----------------------+ | +-----------------+ | - | | - | | - +-------------------------+ -``` - -Each executor instance, whether for system domain or core domain, consists of these components: - -- `BundleProducer`: Produce a bundle on new slot. - - `BundleElectionSolver`: Attempt to solve the bundle election challenge on each each slot in order to be allowed to author a bundle. - - `DomainBundleProposer`: Collect the transactions from transaction pool and a range of receipts upon solving the bundle election challenge successfully. -- `BundleProcessor`: On each imported primary block, the bundle processor extracts the domain-specific bundles from the primary block, compiles the bundles to a list of extrinsics, construct a custom `BlockBuilder` with compiled extrinsics, execute and import the domain block. The receipt of processing the domain block is stored locally and then submitted to the primary chain in some bundle later. -- domain worker: Run the components `BundleProducer` and `BundleProcessor` on the arrived events(new_slot, primary_block_import). -- `GossipMessageValidator`: Validate the bundle gossiped from the domain node peers. Currently, this part is inactive and will be re-enabled in the future. - -## Modules structure - -- `domain_{block_processor,bundle_producer,bundle_proposer,worker}.rs`/`gossip_message_validator` - - General executor components, sharing the common logics between system domain and core domain. -- `system_{block_processor,bundle_producer,bundle_proposer,worker}.rs`/`system_gossip_message_validator` - - Executor components specfic to the system domain. -- `core_{block_processor,bundle_producer,bundle_proposer,worker}.rs`/`core_gossip_message_validator` - - Executor components specfic to the core domain. - -## Run a local testnet - -Clone the repo and start a local testnet: - -```bash -$ git clone https://github.com/subspace/subspace - -$ cd subspace - -# Run a primary chain, a system domain and a core domain node in one command: -$ cargo run --bin subspace-node -- --dev -- --alice --dev --rpc-port 5678 -- --domain-id 1 --alice --dev --rpc-port 6789 - -# Prepare the reward address beforehand and start a farmer in another terminal: -$ cargo run --bin subspace-farmer -- --base-path tmp-farmer farm --plot-size 100M --reward-address [ADDRESS] -``` - -``` -2023-01-05 00:25:33 [PrimaryChain] 🙌 Starting consensus session on top of parent 0xb5c9e775e81475e5153c60849028bb2be5d1afa7070ec2f2e725a21e23a060d7 -2023-01-05 00:25:33 [PrimaryChain] 🎁 Prepared block for proposing at 2 (55 ms) [hash: 0xecaac32f763f9308272b6de285650d76195d132ee0d5e681f3a17da65665b008; parent_hash: 0xb5c9…60d7; extrinsics (12): [0x2f28…df6d, 0x9166…cd9b, 0x5e9f…fc1b, 0x4e47…53a7, 0xccca…82ab, 0x48ff…f888, 0x84af…4239, 0xa3ed…896f, 0xb52f…fd39, 0xd86b…f894, 0xf0ab…ee3f, 0x3f18…8b0c]] -2023-01-05 00:25:33 [PrimaryChain] 🔖 Pre-sealed block for proposal at 2. Hash now 0xf679fa11c20b461bd62d89f5bd42b1c73b2b193f6d2df5e5c7364656cb7d9e44, previously 0xecaac32f763f9308272b6de285650d76195d132ee0d5e681f3a17da65665b008. -2023-01-05 00:25:33 [PrimaryChain] ✨ Imported #2 (0xf679…9e44) -2023-01-05 00:25:33 [SecondaryChain] [apply_extrinsic] after: 0x30f0d98f4bde3789cf8fdc5a5f29acb26d50cbd43a5cbead0d2f213f3eded659 -2023-01-05 00:25:33 [CoreDomain] Not enough confirmed blocks for domain: DomainId(1). Skipping... -2023-01-05 00:25:33 [CoreDomain] ✨ Imported #2 (0xd265…af31) -2023-01-05 00:25:33 [SecondaryChain] Not enough confirmed blocks for domain: DomainId(0). Skipping... -2023-01-05 00:25:33 [SecondaryChain] ✨ Imported #2 (0x2fca…317d) -2023-01-05 00:25:33 [CoreDomain] 📦 Claimed bundle at slot 1672849533 -2023-01-05 00:25:33 [SecondaryChain] 📦 Claimed bundle at slot 1672849533 -2023-01-05 00:25:33 [CoreDomain] Submitted bundle -2023-01-05 00:25:33 [SecondaryChain] Submitted bundle -2023-01-05 00:25:34 [SecondaryChain] 📦 Claimed bundle at slot 1672849534 -2023-01-05 00:25:34 [CoreDomain] 📦 Claimed bundle at slot 1672849534 -2023-01-05 00:25:34 [SecondaryChain] Submitted bundle -2023-01-05 00:25:34 [CoreDomain] Submitted bundle -2023-01-05 00:25:34 [PrimaryChain] 💤 Idle (0 peers), best: #2 (0xf679…9e44), finalized #0 (0xb171…ae48), ⬇ 0 ⬆ 0 -2023-01-05 00:25:34 [PrimaryChain] 🚜 Claimed block at slot 1672849534 -2023-01-05 00:25:34 [PrimaryChain] 🗳️ Claimed vote at slot 1672849534 -2023-01-05 00:25:34 [PrimaryChain] 🙌 Starting consensus session on top of parent 0xf679fa11c20b461bd62d89f5bd42b1c73b2b193f6d2df5e5c7364656cb7d9e44 -2023-01-05 00:25:34 [PrimaryChain] 🎁 Prepared block for proposing at 3 (15 ms) [hash: 0x830be738a562bc8f264bf593a4e66fe5caa4d9acf05c299195adaf93c97f3d5d; parent_hash: 0xf679…9e44; extrinsics (6): [0xd705…47ed, 0xb00e…85b3, 0xd084…986b, 0xbbd5…cf82, 0x7d60…1e57, 0x0e19…ba00]] -2023-01-05 00:25:34 [PrimaryChain] 🔖 Pre-sealed block for proposal at 3. Hash now 0x18b93ababe7ad2e2043afcf9f94440bfa851193858c3c425d3e553de5c7df742, previously 0x830be738a562bc8f264bf593a4e66fe5caa4d9acf05c299195adaf93c97f3d5d. -2023-01-05 00:25:34 [PrimaryChain] ✨ Imported #3 (0x18b9…f742) -2023-01-05 00:25:34 [CoreDomain] Not enough confirmed blocks for domain: DomainId(1). Skipping... -2023-01-05 00:25:34 [CoreDomain] ✨ Imported #3 (0x3f5a…9a68) -2023-01-05 00:25:34 [SecondaryChain] [apply_extrinsic] after: 0x904b59ac373a7466b205469d2939a42e212d360635d696348c66511c98d324c3 -2023-01-05 00:25:34 [SecondaryChain] [apply_extrinsic] after: 0x2abfbba7763441d8db853fc05b03d88967a00a0a726d068609aca8fb3631bcf9 -``` diff --git a/domains/client/domain-executor/src/bundle_election_solver.rs b/domains/client/domain-executor/src/bundle_election_solver.rs deleted file mode 100644 index 8569deab84e..00000000000 --- a/domains/client/domain-executor/src/bundle_election_solver.rs +++ /dev/null @@ -1,165 +0,0 @@ -use crate::utils::{to_number_primitive, translate_block_hash_type}; -use sc_client_api::ProofProvider; -use sp_api::{NumberFor, ProvideRuntimeApi}; -use sp_blockchain::HeaderBackend; -use sp_domains::bundle_election::{ - calculate_bundle_election_threshold, derive_bundle_election_solution, - is_election_solution_within_threshold, make_local_randomness_input, well_known_keys, - BundleElectionSolverParams, -}; -use sp_domains::merkle_tree::{authorities_merkle_tree, Witness}; -use sp_domains::{BundleSolution, DomainId, ExecutorPublicKey, ProofOfElection, StakeWeight}; -use sp_keystore::KeystorePtr; -use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; -use sp_runtime::RuntimeAppPublic; -use std::marker::PhantomData; -use std::sync::Arc; -use subspace_core_primitives::Blake2b256Hash; -use system_runtime_primitives::SystemDomainApi; - -pub(super) struct BundleElectionSolver { - system_domain_client: Arc, - keystore: KeystorePtr, - _phantom_data: PhantomData<(Block, SBlock, PBlock)>, -} - -impl Clone - for BundleElectionSolver -{ - fn clone(&self) -> Self { - Self { - system_domain_client: self.system_domain_client.clone(), - keystore: self.keystore.clone(), - _phantom_data: self._phantom_data, - } - } -} - -impl BundleElectionSolver -where - Block: BlockT, - SBlock: BlockT, - PBlock: BlockT, - SClient: HeaderBackend + ProvideRuntimeApi + ProofProvider, - SClient::Api: SystemDomainApi, PBlock::Hash, Block::Hash>, -{ - pub(super) fn new(system_domain_client: Arc, keystore: KeystorePtr) -> Self { - Self { - system_domain_client, - keystore, - _phantom_data: PhantomData, - } - } - - pub(super) fn solve_bundle_election_challenge( - &self, - best_hash: SBlock::Hash, - best_number: NumberFor, - domain_id: DomainId, - global_challenge: Blake2b256Hash, - ) -> sp_blockchain::Result>> { - let BundleElectionSolverParams { - authorities, - total_stake_weight, - slot_probability, - } = self - .system_domain_client - .runtime_api() - .bundle_election_solver_params(best_hash, domain_id)?; - - assert!( - total_stake_weight - == authorities - .iter() - .map(|(_, weight)| weight) - .sum::(), - "Total stake weight mismatches, which must be a bug in the runtime" - ); - - let input = make_local_randomness_input(&global_challenge).into(); - - for (index, (authority_id, stake_weight)) in authorities.iter().enumerate() { - if let Ok(Some(vrf_signature)) = - self.keystore - .sr25519_vrf_sign(ExecutorPublicKey::ID, authority_id.as_ref(), &input) - { - let election_solution = derive_bundle_election_solution( - domain_id, - &vrf_signature.output, - authority_id, - &global_challenge, - ) - .map_err(|err| { - sp_blockchain::Error::Application(Box::from(format!( - "Failed to derive bundle election solution: {err}", - ))) - })?; - - let threshold = calculate_bundle_election_threshold( - *stake_weight, - total_stake_weight, - slot_probability, - ); - - if is_election_solution_within_threshold(election_solution, threshold) { - // TODO: bench how large the storage proof we can afford and try proving a single - // electioned executor storage instead of the whole authority set. - let storage_proof = if domain_id.is_system() { - let storage_keys = well_known_keys::system_bundle_election_storage_keys(); - self.system_domain_client - .read_proof(best_hash, &mut storage_keys.iter().map(|s| s.as_slice()))? - } else { - return Err(sp_blockchain::Error::Application(Box::from( - "Only system and core domain are supported".to_string(), - ))); - }; - - let state_root = *self - .system_domain_client - .header(best_hash)? - .expect("Best block header must exist; qed") - .state_root(); - - let block_hash = translate_block_hash_type::(best_hash); - let state_root = translate_block_hash_type::(state_root); - - let proof_of_election = ProofOfElection { - domain_id, - vrf_output: vrf_signature.output, - vrf_proof: vrf_signature.proof, - executor_public_key: authority_id.clone(), - global_challenge, - storage_proof, - system_state_root: state_root, - system_block_number: to_number_primitive(best_number), - system_block_hash: block_hash, - }; - - let preliminary_bundle_solution = if domain_id.is_system() { - let merkle_tree = authorities_merkle_tree(&authorities); - let authority_witness = Witness { - leaf_index: index.try_into().expect("Leaf index must fit into u32"), - number_of_leaves: authorities - .len() - .try_into() - .expect("Authorities size must fit into u32"), - proof: merkle_tree.proof(&[index]).to_bytes(), - }; - - BundleSolution::System { - authority_stake_weight: *stake_weight, - authority_witness, - proof_of_election, - } - } else { - unreachable!("Open domain has been handled above") - }; - - return Ok(Some(preliminary_bundle_solution)); - } - } - } - - Ok(None) - } -} diff --git a/domains/client/domain-executor/src/domain_block_processor.rs b/domains/client/domain-executor/src/domain_block_processor.rs deleted file mode 100644 index 935ae1b6356..00000000000 --- a/domains/client/domain-executor/src/domain_block_processor.rs +++ /dev/null @@ -1,625 +0,0 @@ -use crate::fraud_proof::{find_trace_mismatch, FraudProofGenerator}; -use crate::parent_chain::ParentChainInterface; -use crate::utils::{ - to_number_primitive, translate_number_type, DomainBlockImportNotification, - DomainImportNotificationSinks, -}; -use crate::ExecutionReceiptFor; -use codec::{Decode, Encode}; -use domain_block_builder::{BlockBuilder, BuiltBlock, RecordProof}; -use domain_runtime_primitives::DomainCoreApi; -use sc_client_api::{AuxStore, BlockBackend, Finalizer, StateBackendFor, TransactionFor}; -use sc_consensus::{ - BlockImport, BlockImportParams, ForkChoiceStrategy, ImportResult, StateAction, StorageChanges, -}; -use sp_api::{NumberFor, ProvideRuntimeApi}; -use sp_blockchain::{HashAndNumber, HeaderBackend, HeaderMetadata}; -use sp_consensus::{BlockOrigin, SyncOracle}; -use sp_core::traits::CodeExecutor; -use sp_domains::fraud_proof::FraudProof; -use sp_domains::merkle_tree::MerkleTree; -use sp_domains::{DomainId, ExecutionReceipt, ExecutorApi}; -use sp_runtime::traits::{Block as BlockT, CheckedSub, HashFor, Header as HeaderT, One, Zero}; -use sp_runtime::Digest; -use std::sync::Arc; - -pub(crate) struct DomainBlockResult -where - Block: BlockT, - PBlock: BlockT, -{ - pub header_hash: Block::Hash, - pub header_number: NumberFor, - pub execution_receipt: ExecutionReceiptFor, -} - -/// A common component shared between the system and core domain bundle processor. -pub(crate) struct DomainBlockProcessor -where - Block: BlockT, - PBlock: BlockT, -{ - pub(crate) domain_id: DomainId, - pub(crate) client: Arc, - pub(crate) primary_chain_client: Arc, - pub(crate) backend: Arc, - pub(crate) domain_confirmation_depth: NumberFor, - pub(crate) block_import: Arc, - pub(crate) import_notification_sinks: DomainImportNotificationSinks, -} - -impl Clone - for DomainBlockProcessor -where - Block: BlockT, - PBlock: BlockT, -{ - fn clone(&self) -> Self { - Self { - domain_id: self.domain_id, - client: self.client.clone(), - primary_chain_client: self.primary_chain_client.clone(), - backend: self.backend.clone(), - domain_confirmation_depth: self.domain_confirmation_depth, - block_import: self.block_import.clone(), - import_notification_sinks: self.import_notification_sinks.clone(), - } - } -} - -/// A list of primary blocks waiting to be processed by executor on each imported primary block -/// notification. -/// -/// Usually, each new domain block is built on top of the current best domain block, with the block -/// content extracted from the incoming primary block. However, an incoming imported primary block -/// notification can also imply multiple pending primary blocks in case of the primary chain re-org. -#[derive(Debug)] -pub(crate) struct PendingPrimaryBlocks { - /// Base block used to build new domain blocks derived from the primary blocks below. - pub initial_parent: (Block::Hash, NumberFor), - /// Pending primary blocks that need to be processed sequentially. - pub primary_imports: Vec>, -} - -impl - DomainBlockProcessor -where - Block: BlockT, - PBlock: BlockT, - Client: HeaderBackend - + BlockBackend - + AuxStore - + ProvideRuntimeApi - + Finalizer - + 'static, - Client::Api: DomainCoreApi - + sp_block_builder::BlockBuilder - + sp_api::ApiExt>, - for<'b> &'b BI: BlockImport< - Block, - Transaction = sp_api::TransactionFor, - Error = sp_consensus::Error, - >, - PClient: HeaderBackend - + HeaderMetadata - + BlockBackend - + ProvideRuntimeApi - + 'static, - PClient::Api: ExecutorApi + 'static, - Backend: sc_client_api::Backend + 'static, - TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, -{ - /// Returns a list of primary blocks waiting to be processed if any. - /// - /// It's possible to have multiple pending primary blocks that need to be processed in case - /// the primary chain re-org occurs. - pub(crate) fn pending_imported_primary_blocks( - &self, - primary_hash: PBlock::Hash, - primary_number: NumberFor, - ) -> sp_blockchain::Result>> { - if primary_number == One::one() { - return Ok(Some(PendingPrimaryBlocks { - initial_parent: (self.client.info().genesis_hash, Zero::zero()), - primary_imports: vec![HashAndNumber { - hash: primary_hash, - number: primary_number, - }], - })); - } - - let best_hash = self.client.info().best_hash; - let best_number = self.client.info().best_number; - - let primary_hash_for_best_domain_hash = - crate::aux_schema::primary_hash_for(&*self.backend, best_hash)?.ok_or_else(|| { - sp_blockchain::Error::Backend(format!( - "Primary hash for domain hash #{best_number},{best_hash} not found" - )) - })?; - - let primary_from = primary_hash_for_best_domain_hash; - let primary_to = primary_hash; - - if primary_from == primary_to { - return Err(sp_blockchain::Error::Application(Box::from( - "Primary block {primary_hash:?} has already been processed.", - ))); - } - - let route = - sp_blockchain::tree_route(&*self.primary_chain_client, primary_from, primary_to)?; - - let retracted = route.retracted(); - let enacted = route.enacted(); - - tracing::trace!( - ?retracted, - ?enacted, - common_block = ?route.common_block(), - "Calculating PendingPrimaryBlocks on #{best_number},{best_hash:?}" - ); - - match (retracted.is_empty(), enacted.is_empty()) { - (true, false) => { - // New tip, A -> B - Ok(Some(PendingPrimaryBlocks { - initial_parent: (best_hash, best_number), - primary_imports: enacted.to_vec(), - })) - } - (false, true) => { - tracing::debug!("Primary blocks {retracted:?} have been already processed"); - Ok(None) - } - (true, true) => { - unreachable!( - "Tree route is not empty as `primary_from` and `primary_to` in tree_route() \ - are checked above to be not the same; qed", - ); - } - (false, false) => { - let common_block_number = translate_number_type(route.common_block().number); - let parent_header = self - .client - .header(self.client.hash(common_block_number)?.ok_or_else(|| { - sp_blockchain::Error::Backend(format!( - "Header for #{common_block_number} not found" - )) - })?)? - .ok_or_else(|| { - sp_blockchain::Error::Backend(format!( - "Header for #{common_block_number} not found" - )) - })?; - - Ok(Some(PendingPrimaryBlocks { - initial_parent: (parent_header.hash(), *parent_header.number()), - primary_imports: enacted.to_vec(), - })) - } - } - } - - pub(crate) async fn process_domain_block( - &self, - (primary_hash, primary_number): (PBlock::Hash, NumberFor), - (parent_hash, parent_number): (Block::Hash, NumberFor), - extrinsics: Vec, - digests: Digest, - ) -> Result, sp_blockchain::Error> { - let primary_number = to_number_primitive(primary_number); - - if to_number_primitive(parent_number) + 1 != primary_number { - return Err(sp_blockchain::Error::Application(Box::from(format!( - "Wrong domain parent block #{parent_number},{parent_hash} for \ - primary block #{primary_number},{primary_hash}, the number of new \ - domain block must match the number of corresponding primary block." - )))); - } - - // Although the domain block intuitively ought to use the same fork choice - // from the corresponding primary block, it's fine to forcibly always use - // the longest chain for simplicity as we manually build all the domain - // branches by literally following the primary chain branches anyway. - let fork_choice = ForkChoiceStrategy::LongestChain; - - let (header_hash, header_number, state_root) = self - .build_and_import_block(parent_hash, parent_number, extrinsics, fork_choice, digests) - .await?; - - tracing::debug!( - "Built new domain block #{header_number},{header_hash} from primary block #{primary_number},{primary_hash} \ - on top of parent block #{parent_number},{parent_hash}" - ); - - if let Some(to_finalize_block_number) = - header_number.checked_sub(&self.domain_confirmation_depth) - { - if to_finalize_block_number > self.client.info().finalized_number { - let to_finalize_block_hash = - self.client.hash(to_finalize_block_number)?.ok_or_else(|| { - sp_blockchain::Error::Backend(format!( - "Header for #{to_finalize_block_number} not found" - )) - })?; - self.client - .finalize_block(to_finalize_block_hash, None, true)?; - tracing::debug!("Successfully finalized block: #{to_finalize_block_number},{to_finalize_block_hash}"); - } - } - - let mut roots = self.client.runtime_api().intermediate_roots(header_hash)?; - - let state_root = state_root - .encode() - .try_into() - .expect("State root uses the same Block hash type which must fit into [u8; 32]; qed"); - - roots.push(state_root); - - let trace_root = MerkleTree::from_leaves(&roots).root().ok_or_else(|| { - sp_blockchain::Error::Application(Box::from("Failed to get merkle root of trace")) - })?; - let trace = roots - .into_iter() - .map(|r| { - Block::Hash::decode(&mut r.as_slice()) - .expect("Storage root uses the same Block hash type; qed") - }) - .collect(); - - tracing::trace!( - ?trace, - ?trace_root, - "Trace root calculated for #{header_number},{header_hash}" - ); - - let execution_receipt = ExecutionReceipt { - primary_number: primary_number.into(), - primary_hash, - domain_hash: header_hash, - trace, - trace_root, - }; - - Ok(DomainBlockResult { - header_hash, - header_number, - execution_receipt, - }) - } - - async fn build_and_import_block( - &self, - parent_hash: Block::Hash, - parent_number: NumberFor, - extrinsics: Vec, - fork_choice: ForkChoiceStrategy, - digests: Digest, - ) -> Result<(Block::Hash, NumberFor, Block::Hash), sp_blockchain::Error> { - let block_builder = BlockBuilder::new( - &*self.client, - parent_hash, - parent_number, - RecordProof::No, - digests, - &*self.backend, - extrinsics, - )?; - - let BuiltBlock { - block, - storage_changes, - proof: _, - } = block_builder.build()?; - - let (header, body) = block.deconstruct(); - let state_root = *header.state_root(); - let header_hash = header.hash(); - let header_number = *header.number(); - - let block_import_params = { - let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); - import_block.body = Some(body); - import_block.state_action = - StateAction::ApplyChanges(StorageChanges::Changes(storage_changes)); - // Follow the primary block's fork choice. - import_block.fork_choice = Some(fork_choice); - import_block - }; - - let import_result = (&*self.block_import) - .import_block(block_import_params) - .await?; - - match import_result { - ImportResult::Imported(..) => {} - ImportResult::AlreadyInChain => { - tracing::debug!("Block #{header_number},{header_hash:?} is already in chain"); - } - ImportResult::KnownBad => { - return Err(sp_consensus::Error::ClientImport(format!( - "Bad block #{header_number}({header_hash:?})" - )) - .into()); - } - ImportResult::UnknownParent => { - return Err(sp_consensus::Error::ClientImport(format!( - "Block #{header_number}({header_hash:?}) has an unknown parent: {parent_hash:?}" - )) - .into()); - } - ImportResult::MissingState => { - return Err(sp_consensus::Error::ClientImport(format!( - "Parent state of block #{header_number}({header_hash:?}) is missing, parent: {parent_hash:?}" - )) - .into()); - } - } - - Ok((header_hash, header_number, state_root)) - } - - pub(crate) fn on_domain_block_processed( - &self, - primary_hash: PBlock::Hash, - domain_block_result: DomainBlockResult, - head_receipt_number: NumberFor, - ) -> sp_blockchain::Result<()> { - let DomainBlockResult { - header_hash, - header_number: _, - execution_receipt, - } = domain_block_result; - - crate::aux_schema::write_execution_receipt::<_, Block, PBlock>( - &*self.client, - head_receipt_number, - &execution_receipt, - )?; - - crate::aux_schema::track_domain_hash_to_primary_hash( - &*self.client, - header_hash, - primary_hash, - )?; - - // Notify the imported domain block when the receipt processing is done. - let domain_import_notification = DomainBlockImportNotification { - domain_block_hash: header_hash, - primary_block_hash: primary_hash, - }; - self.import_notification_sinks.lock().retain(|sink| { - sink.unbounded_send(domain_import_notification.clone()) - .is_ok() - }); - - Ok(()) - } -} - -pub(crate) struct ReceiptsChecker< - Block, - Client, - PBlock, - PClient, - Backend, - E, - ParentChain, - ParentChainBlock, -> { - pub(crate) domain_id: DomainId, - pub(crate) client: Arc, - pub(crate) primary_chain_client: Arc, - pub(crate) primary_network_sync_oracle: Arc, - pub(crate) fraud_proof_generator: - FraudProofGenerator, - pub(crate) parent_chain: ParentChain, - pub(crate) _phantom: std::marker::PhantomData, -} - -impl Clone - for ReceiptsChecker -where - Block: BlockT, - ParentChain: Clone, -{ - fn clone(&self) -> Self { - Self { - domain_id: self.domain_id, - client: self.client.clone(), - primary_chain_client: self.primary_chain_client.clone(), - primary_network_sync_oracle: self.primary_network_sync_oracle.clone(), - fraud_proof_generator: self.fraud_proof_generator.clone(), - parent_chain: self.parent_chain.clone(), - _phantom: self._phantom, - } - } -} - -impl - ReceiptsChecker -where - Block: BlockT, - PBlock: BlockT, - ParentChainBlock: BlockT, - NumberFor: Into>, - Client: - HeaderBackend + BlockBackend + AuxStore + ProvideRuntimeApi + 'static, - Client::Api: DomainCoreApi - + sp_block_builder::BlockBuilder - + sp_api::ApiExt>, - PClient: HeaderBackend + BlockBackend + ProvideRuntimeApi + 'static, - PClient::Api: ExecutorApi, - Backend: sc_client_api::Backend + 'static, - TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, - E: CodeExecutor, - ParentChain: ParentChainInterface, -{ - pub(crate) fn check_state_transition( - &self, - parent_chain_block_hash: ParentChainBlock::Hash, - ) -> sp_blockchain::Result<()> { - let extrinsics = self.parent_chain.block_body(parent_chain_block_hash)?; - - let receipts = self - .parent_chain - .extract_receipts(parent_chain_block_hash, extrinsics.clone())?; - - let fraud_proofs = self - .parent_chain - .extract_fraud_proofs(parent_chain_block_hash, extrinsics)?; - - self.check_receipts(receipts, fraud_proofs)?; - - if self.primary_network_sync_oracle.is_major_syncing() { - tracing::debug!( - "Skip reporting unconfirmed bad receipt as the primary node is still major syncing..." - ); - return Ok(()); - } - - // Submit fraud proof for the first unconfirmed incorrent ER. - let oldest_receipt_number = self - .parent_chain - .oldest_receipt_number(parent_chain_block_hash)?; - crate::aux_schema::prune_expired_bad_receipts(&*self.client, oldest_receipt_number)?; - - if let Some(fraud_proof) = self.create_fraud_proof_for_first_unconfirmed_bad_receipt()? { - self.parent_chain.submit_fraud_proof_unsigned(fraud_proof)?; - } - - Ok(()) - } - - fn check_receipts( - &self, - receipts: Vec>, - fraud_proofs: Vec, ParentChainBlock::Hash>>, - ) -> Result<(), sp_blockchain::Error> { - let mut bad_receipts_to_write = vec![]; - - for execution_receipt in receipts.iter() { - let primary_block_hash = execution_receipt.primary_hash; - - let local_receipt = crate::aux_schema::load_execution_receipt::< - _, - Block::Hash, - NumberFor, - ParentChainBlock::Hash, - >(&*self.client, primary_block_hash)? - .ok_or(sp_blockchain::Error::Backend(format!( - "receipt for primary block #{},{primary_block_hash} not found", - execution_receipt.primary_number - )))?; - - if let Some(trace_mismatch_index) = - find_trace_mismatch(&local_receipt.trace, &execution_receipt.trace) - { - bad_receipts_to_write.push(( - execution_receipt.primary_number, - execution_receipt.hash(), - (trace_mismatch_index, primary_block_hash), - )); - } - } - - let bad_receipts_to_delete = fraud_proofs - .into_iter() - .filter_map(|fraud_proof| { - match fraud_proof { - FraudProof::InvalidStateTransition(fraud_proof) => { - let bad_receipt_number = fraud_proof.parent_number + 1; - let bad_receipt_hash = fraud_proof.bad_receipt_hash; - - // In order to not delete a receipt which was just inserted, accumulate the write&delete operations - // in case the bad receipt and corresponding farud proof are included in the same block. - if let Some(index) = bad_receipts_to_write - .iter() - .map(|(_, receipt_hash, _)| receipt_hash) - .position(|v| *v == bad_receipt_hash) - { - bad_receipts_to_write.swap_remove(index); - None - } else { - Some((bad_receipt_number, bad_receipt_hash)) - } - } - _ => None, - } - }) - .collect::>(); - - for (bad_receipt_number, bad_receipt_hash, mismatch_info) in bad_receipts_to_write { - crate::aux_schema::write_bad_receipt::<_, ParentChainBlock>( - &*self.client, - bad_receipt_number, - bad_receipt_hash, - mismatch_info, - )?; - } - - for (bad_receipt_number, bad_receipt_hash) in bad_receipts_to_delete { - if let Err(e) = crate::aux_schema::delete_bad_receipt( - &*self.client, - bad_receipt_number, - bad_receipt_hash, - ) { - tracing::error!( - error = ?e, - ?bad_receipt_number, - ?bad_receipt_hash, - "Failed to delete bad receipt" - ); - } - } - - Ok(()) - } - - fn create_fraud_proof_for_first_unconfirmed_bad_receipt( - &self, - ) -> sp_blockchain::Result< - Option, ParentChainBlock::Hash>>, - > { - if let Some((bad_receipt_hash, trace_mismatch_index, primary_block_hash)) = - crate::aux_schema::find_first_unconfirmed_bad_receipt_info::<_, Block, PBlock, _>( - &*self.client, - |height| { - self.primary_chain_client.hash(height)?.ok_or_else(|| { - sp_blockchain::Error::Backend(format!( - "Primary block hash for {height} not found", - )) - }) - }, - )? - { - let local_receipt = - crate::aux_schema::load_execution_receipt(&*self.client, primary_block_hash)? - .ok_or_else(|| { - sp_blockchain::Error::Backend(format!( - "Receipt for primary block {primary_block_hash} not found" - )) - })?; - - let fraud_proof = self - .fraud_proof_generator - .generate_invalid_state_transition_proof::( - self.domain_id, - trace_mismatch_index, - &local_receipt, - bad_receipt_hash, - ) - .map_err(|err| { - sp_blockchain::Error::Application(Box::from(format!( - "Failed to generate fraud proof: {err}" - ))) - })?; - - return Ok(Some(fraud_proof)); - } - - Ok(None) - } -} diff --git a/domains/client/domain-executor/src/domain_bundle_proposer.rs b/domains/client/domain-executor/src/domain_bundle_proposer.rs deleted file mode 100644 index 0d106ccc90f..00000000000 --- a/domains/client/domain-executor/src/domain_bundle_proposer.rs +++ /dev/null @@ -1,213 +0,0 @@ -use crate::parent_chain::ParentChainInterface; -use crate::sortition::{TransactionSelectError, TransactionSelector}; -use crate::ExecutionReceiptFor; -use codec::Encode; -use domain_runtime_primitives::DomainCoreApi; -use futures::{select, FutureExt}; -use sc_client_api::{AuxStore, BlockBackend}; -use sc_transaction_pool_api::InPoolTransaction; -use sp_api::{NumberFor, ProvideRuntimeApi}; -use sp_block_builder::BlockBuilder; -use sp_blockchain::HeaderBackend; -use sp_consensus_slots::Slot; -use sp_domains::{BundleHeader, BundleSolution}; -use sp_runtime::traits::{BlakeTwo256, Block as BlockT, Hash as HashT, One, Saturating}; -use std::marker::PhantomData; -use std::sync::Arc; -use std::time; - -pub(super) struct DomainBundleProposer { - client: Arc, - primary_chain_client: Arc, - transaction_pool: Arc, - _phantom_data: PhantomData<(Block, PBlock)>, -} - -impl Clone - for DomainBundleProposer -{ - fn clone(&self) -> Self { - Self { - client: self.client.clone(), - primary_chain_client: self.primary_chain_client.clone(), - transaction_pool: self.transaction_pool.clone(), - _phantom_data: self._phantom_data, - } - } -} - -pub(super) type ProposeBundleOutput = ( - BundleHeader, ::Hash, ::Hash>, - ExecutionReceiptFor::Hash>, - Vec<::Extrinsic>, -); - -impl - DomainBundleProposer -where - Block: BlockT, - PBlock: BlockT, - NumberFor: Into>, - Client: HeaderBackend + BlockBackend + AuxStore + ProvideRuntimeApi, - Client::Api: BlockBuilder + DomainCoreApi, - PClient: HeaderBackend, - TransactionPool: sc_transaction_pool_api::TransactionPool, -{ - pub(crate) fn new( - client: Arc, - primary_chain_client: Arc, - transaction_pool: Arc, - ) -> Self { - Self { - client, - primary_chain_client, - transaction_pool, - _phantom_data: PhantomData, - } - } - - pub(crate) async fn propose_bundle_at( - &self, - bundle_solution: BundleSolution, - slot: Slot, - primary_info: (PBlock::Hash, NumberFor), - parent_chain: ParentChain, - tx_selector: TransactionSelector, - ) -> sp_blockchain::Result> - where - ParentChainBlock: BlockT, - ParentChain: ParentChainInterface, - { - let parent_number = self.client.info().best_number; - let parent_hash = self.client.info().best_hash; - - let mut t1 = self.transaction_pool.ready_at(parent_number).fuse(); - // TODO: proper timeout - let mut t2 = futures_timer::Delay::new(time::Duration::from_micros(100)).fuse(); - - let pending_iterator = select! { - res = t1 => res, - _ = t2 => { - tracing::warn!( - "Timeout fired waiting for transaction pool at #{parent_number}, proceeding with production." - ); - self.transaction_pool.ready() - } - }; - - // TODO: proper deadline - let pushing_duration = time::Duration::from_micros(500); - - let start = time::Instant::now(); - - // TODO: Select transactions properly from the transaction pool - // - // Selection policy: - // - minimize the transaction equivocation. - // - maximize the executor computation power. - let mut extrinsics = Vec::new(); - - for pending_tx in pending_iterator { - if start.elapsed() >= pushing_duration { - break; - } - let pending_tx_data = pending_tx.data().clone(); - let should_select_this_tx = tx_selector - .should_select_tx(parent_hash, pending_tx_data.clone()) - .unwrap_or_else(|err| { - // Accept unsigned transactions like cross domain. - tracing::trace!("propose bundle: sortition select failed: {err:?}"); - matches!(err, TransactionSelectError::TxSignerNotFound) - }); - if should_select_this_tx { - extrinsics.push(pending_tx_data); - } - } - - let extrinsics_root = BlakeTwo256::ordered_trie_root( - extrinsics.iter().map(|xt| xt.encode()).collect(), - sp_core::storage::StateVersion::V1, - ); - - let (primary_hash, primary_number) = primary_info; - - let receipt = self.load_bundle_receipt(parent_number, parent_hash, parent_chain)?; - - let header = BundleHeader { - primary_number, - primary_hash, - slot_number: slot.into(), - extrinsics_root, - bundle_solution, - }; - - Ok((header, receipt, extrinsics)) - } - - /// Returns the receipt in the next domain bundle. - fn load_bundle_receipt( - &self, - header_number: NumberFor, - header_hash: Block::Hash, - parent_chain: ParentChain, - ) -> sp_blockchain::Result> - where - ParentChainBlock: BlockT, - ParentChain: ParentChainInterface, - { - let parent_chain_block_hash = parent_chain.best_hash(); - let head_receipt_number = parent_chain.head_receipt_number(parent_chain_block_hash)?; - let max_drift = parent_chain.maximum_receipt_drift(parent_chain_block_hash)?; - - tracing::trace!( - ?header_number, - ?head_receipt_number, - ?max_drift, - "Collecting receipts at {parent_chain_block_hash:?}" - ); - - let load_receipt = |primary_block_hash, block_number| { - crate::aux_schema::load_execution_receipt::< - _, - Block::Hash, - NumberFor, - PBlock::Hash, - >(&*self.client, primary_block_hash)? - .ok_or_else(|| { - sp_blockchain::Error::Backend(format!( - "Receipt of primary block #{block_number},{primary_block_hash} not found" - )) - }) - }; - - let header_block_receipt_is_written = - crate::aux_schema::primary_hash_for::<_, _, PBlock::Hash>(&*self.client, header_hash)? - .is_some(); - - // TODO: remove once the receipt generation can be done before the domain block is - // committed to the database, in other words, only when the receipt of block N+1 has - // been generated can the `client.info().best_number` be updated from N to N+1. - // - // This requires: - // 1. Reimplement `runtime_api.intermediate_roots()` on the client side. - // 2. Add a hook before the upstream `client.commit_operation(op)`. - let available_best_receipt_number = if header_block_receipt_is_written { - header_number - } else { - header_number.saturating_sub(One::one()) - }; - - let receipt_number = (head_receipt_number + One::one()).min(available_best_receipt_number); - - let primary_block_hash = self - .primary_chain_client - .hash(receipt_number.into())? - .ok_or_else(|| { - sp_blockchain::Error::Backend(format!( - "Primary block hash for #{receipt_number:?} not found" - )) - })?; - - load_receipt(primary_block_hash, receipt_number) - } -} diff --git a/domains/client/domain-executor/src/gossip_message_validator.rs b/domains/client/domain-executor/src/gossip_message_validator.rs deleted file mode 100644 index b9a732220b2..00000000000 --- a/domains/client/domain-executor/src/gossip_message_validator.rs +++ /dev/null @@ -1,390 +0,0 @@ -use crate::fraud_proof::{find_trace_mismatch, FraudProofError, FraudProofGenerator}; -use crate::parent_chain::ParentChainInterface; -use crate::utils::to_number_primitive; -use crate::{ExecutionReceiptFor, TransactionFor}; -use codec::Encode; -use domain_runtime_primitives::{CheckTxValidityError, DomainCoreApi}; -use futures::FutureExt; -use sc_client_api::{AuxStore, BlockBackend, ProofProvider, StateBackendFor}; -use sp_api::ProvideRuntimeApi; -use sp_blockchain::HeaderBackend; -use sp_core::traits::{CodeExecutor, SpawnNamed}; -use sp_core::H256; -use sp_domains::fraud_proof::{BundleEquivocationProof, InvalidTransactionProof}; -use sp_domains::{Bundle, DomainId, ExecutorPublicKey}; -use sp_runtime::traits::{Block as BlockT, HashFor, Header as HeaderT, NumberFor}; -use sp_trie::StorageProof; -use std::marker::PhantomData; -use std::sync::Arc; -use subspace_core_primitives::BlockNumber; - -type FraudProof = sp_domains::fraud_proof::FraudProof< - NumberFor, - ::Hash, ->; - -/// Error type for domain gossip handling. -#[derive(Debug, thiserror::Error)] -pub enum GossipMessageError { - #[error("Bundle equivocation error")] - BundleEquivocation, - #[error(transparent)] - FraudProof(#[from] FraudProofError), - #[error(transparent)] - Client(Box), - #[error(transparent)] - RuntimeApi(#[from] sp_api::ApiError), - #[error(transparent)] - RecvError(#[from] crossbeam::channel::RecvError), - #[error("Failed to send local receipt result because the channel is disconnected")] - SendError, - #[error("The signature of bundle is invalid")] - BadBundleSignature, - #[error("Invalid bundle author, got: {got}, expected: {expected}")] - InvalidBundleAuthor { - got: ExecutorPublicKey, - expected: ExecutorPublicKey, - }, -} - -impl From for GossipMessageError { - #[inline] - fn from(error: sp_blockchain::Error) -> Self { - Self::Client(Box::new(error)) - } -} - -/// Base domain gossip message validator. -pub struct GossipMessageValidator< - Block, - PBlock, - ParentChainBlock, - Client, - PClient, - Backend, - E, - TransactionPool, - ParentChain, -> { - client: Arc, - spawner: Box, - parent_chain: ParentChain, - transaction_pool: Arc, - fraud_proof_generator: FraudProofGenerator, - _phantom_data: PhantomData, -} - -impl< - Block, - PBlock, - ParentChainBlock, - Client, - PClient, - Backend, - E, - TransactionPool, - ParentChain, - > Clone - for GossipMessageValidator< - Block, - PBlock, - ParentChainBlock, - Client, - PClient, - Backend, - E, - TransactionPool, - ParentChain, - > -where - ParentChain: Clone, -{ - fn clone(&self) -> Self { - Self { - client: self.client.clone(), - spawner: self.spawner.clone(), - parent_chain: self.parent_chain.clone(), - transaction_pool: self.transaction_pool.clone(), - fraud_proof_generator: self.fraud_proof_generator.clone(), - _phantom_data: self._phantom_data, - } - } -} - -impl< - Block, - PBlock, - ParentChainBlock, - Client, - PClient, - Backend, - E, - TransactionPool, - ParentChain, - > - GossipMessageValidator< - Block, - PBlock, - ParentChainBlock, - Client, - PClient, - Backend, - E, - TransactionPool, - ParentChain, - > -where - Block: BlockT, - PBlock: BlockT, - ParentChainBlock: BlockT, - Block::Hash: Into, - Client: HeaderBackend - + BlockBackend - + AuxStore - + ProvideRuntimeApi - + ProofProvider - + 'static, - Client::Api: DomainCoreApi - + sp_block_builder::BlockBuilder - + sp_api::ApiExt>, - PClient: HeaderBackend + 'static, - Backend: sc_client_api::Backend + 'static, - TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, - E: CodeExecutor, - TransactionPool: sc_transaction_pool_api::TransactionPool + 'static, - ParentChain: ParentChainInterface + Send + Sync + Clone + 'static, -{ - pub(crate) fn new( - client: Arc, - spawner: Box, - parent_chain: ParentChain, - transaction_pool: Arc, - fraud_proof_generator: FraudProofGenerator, - ) -> Self { - Self { - client, - spawner, - parent_chain, - transaction_pool, - fraud_proof_generator, - _phantom_data: Default::default(), - } - } - - pub(crate) fn check_bundle_equivocation( - &self, - bundle: &Bundle, PBlock::Hash, Block::Hash>, - ) -> Result<(), GossipMessageError> { - // TODO: check bundle equivocation - let bundle_is_an_equivocation = false; - - if bundle_is_an_equivocation { - let equivocation_proof = - BundleEquivocationProof::dummy_at(bundle.sealed_header.header.slot_number); - let fraud_proof = - FraudProof::::BundleEquivocation(equivocation_proof); - self.parent_chain.submit_fraud_proof_unsigned(fraud_proof)?; - Err(GossipMessageError::BundleEquivocation) - } else { - Ok(()) - } - } - - pub(crate) fn validate_bundle_receipt( - &self, - receipt: &ExecutionReceiptFor, - domain_id: DomainId, - ) -> Result<(), GossipMessageError> { - let head_receipt_number = self - .parent_chain - .head_receipt_number(self.parent_chain.best_hash())?; - let head_receipt_number = to_number_primitive(head_receipt_number); - - if let Some(fraud_proof) = - self.validate_execution_receipt(receipt, head_receipt_number, domain_id)? - { - self.parent_chain.submit_fraud_proof_unsigned(fraud_proof)?; - } - - Ok(()) - } - - pub(crate) fn validate_bundle_transactions( - &self, - extrinsics: &[Block::Extrinsic], - domain_id: DomainId, - at: Block::Hash, - ) -> Result<(), GossipMessageError> { - let block_number = self - .client - .number(at)? - .ok_or_else(|| sp_blockchain::Error::Backend(format!("Number for #{at} not found")))?; - - for (_index, extrinsic) in extrinsics.iter().enumerate() { - let tx_hash = self.transaction_pool.hash_of(extrinsic); - - if self.transaction_pool.ready_transaction(&tx_hash).is_some() { - // TODO: Set the status of each tx in the bundle to seen - } else if let Err(transaction_fee_err) = self - .client - .runtime_api() - .check_transaction_validity(at, extrinsic.clone(), at)? - { - let storage_proof = match transaction_fee_err { - CheckTxValidityError::Lookup => StorageProof::empty(), - CheckTxValidityError::InvalidTransaction { - error, - storage_keys, - } => { - tracing::debug!( - ?extrinsic, - ?error, - "Invalid transaction at #{block_number},{at}" - ); - self.client - .read_proof(at, &mut storage_keys.iter().map(|s| s.as_slice()))? - } - }; - - // TODO: Include verifiable bundle solution - let invalid_transaction_proof = InvalidTransactionProof { - domain_id, - block_number: to_number_primitive(block_number), - domain_block_hash: at.into(), - invalid_extrinsic: extrinsic.encode(), // TODO: Verifiable invalid extrinsic - storage_proof, - }; - - let fraud_proof = - FraudProof::::InvalidTransaction(invalid_transaction_proof); - - self.parent_chain.submit_fraud_proof_unsigned(fraud_proof)?; - } - - // TODO: also check invalid XDM? - } - - Ok(()) - } - - /// The background is that a receipt received from the network points to a future block - /// from the local view, so we need to wait for the receipt for the block at the same - /// height to be produced locally in order to check the validity of the external receipt. - #[allow(clippy::never_loop)] - async fn wait_for_local_future_receipt( - &self, - primary_block_hash: PBlock::Hash, - _block_number: ::Number, - tx: crossbeam::channel::Sender< - sp_blockchain::Result>, - >, - ) -> Result<(), GossipMessageError> { - loop { - match crate::aux_schema::load_execution_receipt(&*self.client, primary_block_hash) { - Ok(Some(local_receipt)) => { - return tx - .send(Ok(local_receipt)) - .map_err(|_| GossipMessageError::SendError) - } - Ok(None) => { - unimplemented!( - "TODO: rework the following logic once the compact bundle is a thing" - ) - - /* - // TODO: test how this works under the primary forks. - // ref https://github.com/subspace/subspace/pull/250#discussion_r804247551 - // - // Whether or not the best execution chain number on primary chain has been - // updated, the local client has proceeded to a higher block, that means the receipt - // of `block_hash` received from the network does not match the local one, - // we should just send back the local receipt at the same height. - if self.client.info().best_number >= block_number { - let local_block_hash = self - .client - .expect_block_hash_from_id(&BlockId::Number(block_number))?; - let local_receipt_result = crate::aux_schema::load_execution_receipt( - &*self.client, - local_block_hash, - )? - .ok_or_else(|| { - sp_blockchain::Error::Backend(format!( - "Execution receipt not found for {local_block_hash:?}" - )) - }); - return tx - .send(local_receipt_result) - .map_err(|_| GossipMessageError::SendError); - } else { - tokio::time::sleep(std::time::Duration::from_millis(100)).await; - } - */ - } - Err(e) => return tx.send(Err(e)).map_err(|_| GossipMessageError::SendError), - } - } - } - - fn validate_execution_receipt( - &self, - execution_receipt: &ExecutionReceiptFor, - head_receipt_number: BlockNumber, - domain_id: DomainId, - ) -> Result>, GossipMessageError> { - let primary_number = to_number_primitive(execution_receipt.primary_number); - - // Just ignore it if the receipt is too old and has been pruned. - if crate::aux_schema::target_receipt_is_pruned(head_receipt_number, primary_number) { - return Ok(None); - } - - let primary_block_hash = execution_receipt.primary_hash; - let block_number = primary_number.into(); - - // TODO: more efficient execution receipt checking strategy? - let local_receipt = if let Some(local_receipt) = - crate::aux_schema::load_execution_receipt(&*self.client, primary_block_hash)? - { - local_receipt - } else { - // Wait for the local execution receipt until it's ready. - let (tx, rx) = crossbeam::channel::bounded::< - sp_blockchain::Result>, - >(1); - let executor = self.clone(); - self.spawner.spawn( - "wait-for-local-execution-receipt", - None, - async move { - if let Err(err) = executor - .wait_for_local_future_receipt(primary_block_hash, block_number, tx) - .await - { - tracing::error!(?err, "Error occurred while waiting for the local receipt"); - } - } - .boxed(), - ); - rx.recv()?? - }; - - // TODO: What happens for this obvious error? - if local_receipt.trace.len() != execution_receipt.trace.len() {} - - if let Some(trace_mismatch_index) = - find_trace_mismatch(&local_receipt.trace, &execution_receipt.trace) - { - let fraud_proof = self - .fraud_proof_generator - .generate_invalid_state_transition_proof::( - domain_id, - trace_mismatch_index, - &local_receipt, - execution_receipt.hash(), - )?; - Ok(Some(fraud_proof)) - } else { - Ok(None) - } - } -} diff --git a/domains/client/domain-executor/src/parent_chain.rs b/domains/client/domain-executor/src/parent_chain.rs deleted file mode 100644 index 1e45a32dbe2..00000000000 --- a/domains/client/domain-executor/src/parent_chain.rs +++ /dev/null @@ -1,276 +0,0 @@ -use crate::ExecutionReceiptFor; -use sc_client_api::BlockBackend; -use sp_api::{NumberFor, ProvideRuntimeApi}; -use sp_blockchain::HeaderBackend; -use sp_domains::fraud_proof::FraudProof; -use sp_domains::DomainId; -use sp_runtime::traits::Block as BlockT; -use sp_settlement::SettlementApi; -use std::marker::PhantomData; -use std::sync::Arc; - -type FraudProofFor = - FraudProof, ::Hash>; - -/// Trait for interacting between the domain and its corresponding parent chain, i.e. retrieving -/// the necessary info from the parent chain or submit extrinsics to the parent chain. -/// -/// - The parent chain of System Domain => Primary Chain -/// - The parent chain of Core Domain => System Domain -pub trait ParentChainInterface { - fn best_hash(&self) -> ParentChainBlock::Hash; - - fn block_body( - &self, - at: ParentChainBlock::Hash, - ) -> sp_blockchain::Result>; - - fn oldest_receipt_number( - &self, - at: ParentChainBlock::Hash, - ) -> Result, sp_api::ApiError>; - - fn head_receipt_number( - &self, - at: ParentChainBlock::Hash, - ) -> Result, sp_api::ApiError>; - - fn maximum_receipt_drift( - &self, - at: ParentChainBlock::Hash, - ) -> Result, sp_api::ApiError>; - - fn extract_receipts( - &self, - at: ParentChainBlock::Hash, - extrinsics: Vec, - ) -> Result>, sp_api::ApiError>; - - fn extract_fraud_proofs( - &self, - at: ParentChainBlock::Hash, - extrinsics: Vec, - ) -> Result>, sp_api::ApiError>; - - fn submit_fraud_proof_unsigned( - &self, - fraud_proof: FraudProof, ParentChainBlock::Hash>, - ) -> Result<(), sp_api::ApiError>; -} - -/// The parent chain of the core domain -pub struct CoreDomainParentChain { - /// Core domain id - domain_id: DomainId, - system_domain_client: Arc, - _phantom: PhantomData<(Block, SBlock, PBlock)>, -} - -impl Clone - for CoreDomainParentChain -{ - fn clone(&self) -> Self { - Self { - domain_id: self.domain_id, - system_domain_client: self.system_domain_client.clone(), - _phantom: self._phantom, - } - } -} - -impl CoreDomainParentChain { - pub fn new(domain_id: DomainId, system_domain_client: Arc) -> Self { - Self { - domain_id, - system_domain_client, - _phantom: PhantomData, - } - } -} - -impl ParentChainInterface - for CoreDomainParentChain -where - Block: BlockT, - SBlock: BlockT, - PBlock: BlockT, - NumberFor: Into>, - SClient: HeaderBackend + BlockBackend + ProvideRuntimeApi, - SClient::Api: SettlementApi, -{ - fn best_hash(&self) -> SBlock::Hash { - self.system_domain_client.info().best_hash - } - - fn block_body(&self, at: SBlock::Hash) -> sp_blockchain::Result> { - self.system_domain_client.block_body(at)?.ok_or_else(|| { - sp_blockchain::Error::Backend(format!("System domain block body for {at} not found")) - }) - } - - fn oldest_receipt_number( - &self, - at: SBlock::Hash, - ) -> Result, sp_api::ApiError> { - let oldest_receipt_number = self - .system_domain_client - .runtime_api() - .oldest_receipt_number(at, self.domain_id)?; - Ok(oldest_receipt_number.into()) - } - - fn head_receipt_number(&self, at: SBlock::Hash) -> Result, sp_api::ApiError> { - let head_receipt_number = self - .system_domain_client - .runtime_api() - .head_receipt_number(at, self.domain_id)?; - Ok(head_receipt_number.into()) - } - - fn maximum_receipt_drift( - &self, - at: SBlock::Hash, - ) -> Result, sp_api::ApiError> { - let max_drift = self - .system_domain_client - .runtime_api() - .maximum_receipt_drift(at)?; - Ok(max_drift.into()) - } - - fn extract_receipts( - &self, - at: SBlock::Hash, - extrinsics: Vec, - ) -> Result>, sp_api::ApiError> { - self.system_domain_client - .runtime_api() - .extract_receipts(at, extrinsics, self.domain_id) - } - - fn extract_fraud_proofs( - &self, - at: SBlock::Hash, - extrinsics: Vec, - ) -> Result>, sp_api::ApiError> { - self.system_domain_client - .runtime_api() - .extract_fraud_proofs(at, extrinsics, self.domain_id) - } - - fn submit_fraud_proof_unsigned( - &self, - fraud_proof: FraudProof, SBlock::Hash>, - ) -> Result<(), sp_api::ApiError> { - let at = self.system_domain_client.info().best_hash; - self.system_domain_client - .runtime_api() - .submit_fraud_proof_unsigned(at, fraud_proof)?; - Ok(()) - } -} - -/// The parent chain of the system domain -pub struct SystemDomainParentChain { - primary_chain_client: Arc, - _phantom: PhantomData<(Block, PBlock)>, -} - -impl Clone for SystemDomainParentChain { - fn clone(&self) -> Self { - Self { - primary_chain_client: self.primary_chain_client.clone(), - _phantom: self._phantom, - } - } -} - -impl SystemDomainParentChain { - pub fn new(primary_chain_client: Arc) -> Self { - Self { - primary_chain_client, - _phantom: PhantomData, - } - } -} - -impl ParentChainInterface - for SystemDomainParentChain -where - Block: BlockT, - PBlock: BlockT, - NumberFor: Into>, - PClient: HeaderBackend + BlockBackend + ProvideRuntimeApi, - PClient::Api: SettlementApi, -{ - fn best_hash(&self) -> PBlock::Hash { - self.primary_chain_client.info().best_hash - } - - fn block_body(&self, at: PBlock::Hash) -> sp_blockchain::Result> { - self.primary_chain_client.block_body(at)?.ok_or_else(|| { - sp_blockchain::Error::Backend(format!("Primary block body for {at} not found")) - }) - } - - fn oldest_receipt_number( - &self, - at: PBlock::Hash, - ) -> Result, sp_api::ApiError> { - let oldest_receipt_number = self - .primary_chain_client - .runtime_api() - .oldest_receipt_number(at, DomainId::SYSTEM)?; - Ok(oldest_receipt_number.into()) - } - - fn head_receipt_number(&self, at: PBlock::Hash) -> Result, sp_api::ApiError> { - let head_receipt_number = self - .primary_chain_client - .runtime_api() - .head_receipt_number(at, DomainId::SYSTEM)?; - Ok(head_receipt_number.into()) - } - - fn maximum_receipt_drift( - &self, - at: PBlock::Hash, - ) -> Result, sp_api::ApiError> { - let max_drift = self - .primary_chain_client - .runtime_api() - .maximum_receipt_drift(at)?; - Ok(max_drift.into()) - } - - fn extract_receipts( - &self, - at: PBlock::Hash, - extrinsics: Vec, - ) -> Result>, sp_api::ApiError> { - self.primary_chain_client - .runtime_api() - .extract_receipts(at, extrinsics, DomainId::SYSTEM) - } - - fn extract_fraud_proofs( - &self, - at: PBlock::Hash, - extrinsics: Vec, - ) -> Result>, sp_api::ApiError> { - self.primary_chain_client - .runtime_api() - .extract_fraud_proofs(at, extrinsics, DomainId::SYSTEM) - } - - fn submit_fraud_proof_unsigned( - &self, - fraud_proof: FraudProof, PBlock::Hash>, - ) -> Result<(), sp_api::ApiError> { - let at = self.primary_chain_client.info().best_hash; - self.primary_chain_client - .runtime_api() - .submit_fraud_proof_unsigned(at, fraud_proof)?; - Ok(()) - } -} diff --git a/domains/client/domain-executor/src/sortition.rs b/domains/client/domain-executor/src/sortition.rs deleted file mode 100644 index 591f4c3f776..00000000000 --- a/domains/client/domain-executor/src/sortition.rs +++ /dev/null @@ -1,300 +0,0 @@ -//! Domain transaction sortition related logic. - -use codec::Encode; -use domain_runtime_primitives::DomainCoreApi; -use sp_api::ProvideRuntimeApi; -use sp_runtime::traits::Block as BlockT; -use std::sync::Arc; -use subspace_core_primitives::crypto::blake2b_256_hash; -use subspace_core_primitives::{bidirectional_distance, U256}; - -/// Transaction sortition for inclusion in a proposed bundle. -pub(crate) struct TransactionSelector { - /// VRF signature hash from the proof of election. - pub bundle_vrf_hash: U256, - - /// Current tx range. - pub tx_range: U256, - - /// Runtime API. - pub client: Arc, - - _p: std::marker::PhantomData, -} - -impl TransactionSelector -where - Block: BlockT, - Client: ProvideRuntimeApi, - Client::Api: DomainCoreApi, -{ - pub(crate) fn new(bundle_vrf_hash: U256, client: Arc) -> Self { - // TODO: this will be refactored as part of the change to make the - // tx range dynamic. Setting this to 100% for now. - let tx_range = U256::MAX; - Self { - bundle_vrf_hash, - tx_range, - client, - _p: Default::default(), - } - } - - /// Checks if the transaction should be selected based on the - /// sortition scheme - pub(crate) fn should_select_tx( - &self, - at: Block::Hash, - tx: Block::Extrinsic, - ) -> Result { - // Extract the signer Id hash - let api = self.client.runtime_api(); - let ret = api.extract_signer(at, vec![tx])?; - let signer_id_hash = ret - .into_iter() - .next() - .and_then(|(maybe_signer, _)| { - maybe_signer.map(|signer| { - let bytes = signer.encode(); - U256::from_be_bytes(blake2b_256_hash(&bytes)) - }) - }) - .ok_or(TransactionSelectError::TxSignerNotFound)?; - - // Check if the signer Id hash is within the tx range - Ok(signer_in_tx_range( - &self.bundle_vrf_hash, - &signer_id_hash, - &self.tx_range, - )) - } -} - -/// Error type for transaction selection. -#[derive(Debug, thiserror::Error)] -pub enum TransactionSelectError { - #[error(transparent)] - RuntimeApi(#[from] sp_api::ApiError), - - #[error("Transaction signer not found")] - TxSignerNotFound, -} - -/// Checks if the signer Id hash is within the tx range -fn signer_in_tx_range(bundle_vrf_hash: &U256, signer_id_hash: &U256, tx_range: &U256) -> bool { - let distance_from_vrf_hash = bidirectional_distance(bundle_vrf_hash, signer_id_hash); - distance_from_vrf_hash <= (*tx_range / 2) -} - -#[cfg(test)] -mod tests { - use super::signer_in_tx_range; - use num_traits::ops::wrapping::{WrappingAdd, WrappingSub}; - use subspace_core_primitives::U256; - - #[test] - fn test_tx_range() { - let tx_range = U256::MAX / 4; - let bundle_vrf_hash = U256::MAX / 2; - - let signer_id_hash = bundle_vrf_hash + U256::from(10_u64); - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash - U256::from(10_u64); - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash + U256::MAX / 8; - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash - U256::MAX / 8; - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash + U256::MAX / 8 + U256::from(1_u64); - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash - U256::MAX / 8 - U256::from(1_u64); - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash + U256::MAX / 4; - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash - U256::MAX / 4; - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - } - - #[test] - fn test_tx_range_wrap_under_flow() { - let tx_range = U256::MAX / 4; - let bundle_vrf_hash = U256::from(100_u64); - - let signer_id_hash = bundle_vrf_hash + U256::from(1000_u64); - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash.wrapping_sub(&U256::from(1000_u64)); - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash + U256::MAX / 8; - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let v = U256::MAX / 8; - let signer_id_hash = bundle_vrf_hash.wrapping_sub(&v); - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash + U256::MAX / 8 + U256::from(1_u64); - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let v = U256::MAX / 8 + U256::from(1_u64); - let signer_id_hash = bundle_vrf_hash.wrapping_sub(&v); - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash + U256::MAX / 4; - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let v = U256::MAX / 4; - let signer_id_hash = bundle_vrf_hash.wrapping_sub(&v); - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - } - - #[test] - fn test_tx_range_wrap_over_flow() { - let tx_range = U256::MAX / 4; - let v = U256::MAX; - let bundle_vrf_hash = v.wrapping_sub(&U256::from(100_u64)); - - let signer_id_hash = bundle_vrf_hash.wrapping_add(&U256::from(1000_u64)); - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash - U256::from(1000_u64); - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let v = U256::MAX / 8; - let signer_id_hash = bundle_vrf_hash.wrapping_add(&v); - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash - U256::MAX / 8; - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let v = U256::MAX / 8 + U256::from(1_u64); - let signer_id_hash = bundle_vrf_hash.wrapping_add(&v); - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash - U256::MAX / 8 - U256::from(1_u64); - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let v = U256::MAX / 4; - let signer_id_hash = bundle_vrf_hash.wrapping_add(&v); - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - - let signer_id_hash = bundle_vrf_hash - U256::MAX / 4; - assert!(!signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - } - - #[test] - fn test_tx_range_max() { - let tx_range = U256::MAX; - let bundle_vrf_hash = U256::MAX / 2; - - let signer_id_hash = bundle_vrf_hash + U256::from(10_u64); - assert!(signer_in_tx_range( - &bundle_vrf_hash, - &signer_id_hash, - &tx_range - )); - } -} diff --git a/domains/client/domain-executor/src/system_bundle_processor.rs b/domains/client/domain-executor/src/system_bundle_processor.rs deleted file mode 100644 index 7d3bdde578f..00000000000 --- a/domains/client/domain-executor/src/system_bundle_processor.rs +++ /dev/null @@ -1,245 +0,0 @@ -use crate::domain_block_processor::{DomainBlockProcessor, PendingPrimaryBlocks, ReceiptsChecker}; -use crate::{SystemDomainParentChain, TransactionFor}; -use domain_block_preprocessor::runtime_api_full::RuntimeApiFull; -use domain_block_preprocessor::SystemDomainBlockPreprocessor; -use domain_runtime_primitives::DomainCoreApi; -use sc_client_api::{AuxStore, BlockBackend, Finalizer, StateBackendFor}; -use sc_consensus::BlockImport; -use sp_api::{NumberFor, ProvideRuntimeApi}; -use sp_blockchain::{HeaderBackend, HeaderMetadata}; -use sp_core::traits::CodeExecutor; -use sp_domain_digests::AsPredigest; -use sp_domains::{DomainId, ExecutorApi}; -use sp_keystore::KeystorePtr; -use sp_messenger::MessengerApi; -use sp_runtime::traits::{Block as BlockT, HashFor, One, Zero}; -use sp_runtime::{Digest, DigestItem}; -use sp_settlement::SettlementApi; -use std::sync::Arc; -use system_runtime_primitives::SystemDomainApi; - -type SystemDomainReceiptsChecker = ReceiptsChecker< - Block, - Client, - PBlock, - PClient, - Backend, - E, - SystemDomainParentChain, - PBlock, ->; - -pub(crate) struct SystemBundleProcessor -where - Block: BlockT, - PBlock: BlockT, -{ - primary_chain_client: Arc, - client: Arc, - backend: Arc, - keystore: KeystorePtr, - system_domain_receipts_checker: - SystemDomainReceiptsChecker, - system_domain_block_preprocessor: - SystemDomainBlockPreprocessor>, - domain_block_processor: DomainBlockProcessor, -} - -impl Clone - for SystemBundleProcessor -where - Block: BlockT, - PBlock: BlockT, -{ - fn clone(&self) -> Self { - Self { - primary_chain_client: self.primary_chain_client.clone(), - client: self.client.clone(), - backend: self.backend.clone(), - keystore: self.keystore.clone(), - system_domain_receipts_checker: self.system_domain_receipts_checker.clone(), - system_domain_block_preprocessor: self.system_domain_block_preprocessor.clone(), - domain_block_processor: self.domain_block_processor.clone(), - } - } -} - -impl - SystemBundleProcessor -where - Block: BlockT, - PBlock: BlockT, - NumberFor: From> + Into>, - PBlock::Hash: From, - Client: HeaderBackend - + BlockBackend - + AuxStore - + ProvideRuntimeApi - + Finalizer - + 'static, - Client::Api: DomainCoreApi - + sp_block_builder::BlockBuilder - + sp_api::ApiExt> - + SystemDomainApi, PBlock::Hash, Block::Hash> - + MessengerApi>, - for<'b> &'b Client: BlockImport< - Block, - Transaction = sp_api::TransactionFor, - Error = sp_consensus::Error, - >, - PClient: HeaderBackend - + HeaderMetadata - + BlockBackend - + ProvideRuntimeApi - + 'static, - PClient::Api: ExecutorApi + SettlementApi + 'static, - Backend: sc_client_api::Backend + 'static, - TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, - E: CodeExecutor, -{ - pub(crate) fn new( - primary_chain_client: Arc, - client: Arc, - backend: Arc, - keystore: KeystorePtr, - system_domain_receipts_checker: SystemDomainReceiptsChecker< - Block, - PBlock, - Client, - PClient, - Backend, - E, - >, - domain_block_processor: DomainBlockProcessor< - Block, - PBlock, - Client, - PClient, - Backend, - Client, - >, - ) -> Self { - let system_domain_block_preprocessor = SystemDomainBlockPreprocessor::new( - primary_chain_client.clone(), - RuntimeApiFull::new(client.clone()), - ); - Self { - primary_chain_client, - client, - backend, - keystore, - system_domain_receipts_checker, - system_domain_block_preprocessor, - domain_block_processor, - } - } - - // TODO: Handle the returned error properly, ref to https://github.com/subspace/subspace/pull/695#discussion_r926721185 - pub(crate) async fn process_bundles( - self, - primary_info: (PBlock::Hash, NumberFor), - ) -> sp_blockchain::Result<()> { - let (primary_hash, primary_number) = primary_info; - - tracing::debug!("Processing imported primary block #{primary_number},{primary_hash}"); - - let maybe_pending_primary_blocks = self - .domain_block_processor - .pending_imported_primary_blocks(primary_hash, primary_number)?; - - if let Some(PendingPrimaryBlocks { - initial_parent, - primary_imports, - }) = maybe_pending_primary_blocks - { - tracing::trace!( - ?initial_parent, - ?primary_imports, - "Pending primary blocks to process" - ); - - let mut domain_parent = initial_parent; - - for primary_info in primary_imports { - domain_parent = self - .process_bundles_at((primary_info.hash, primary_info.number), domain_parent) - .await?; - } - } - - Ok(()) - } - - async fn process_bundles_at( - &self, - primary_info: (PBlock::Hash, NumberFor), - parent_info: (Block::Hash, NumberFor), - ) -> sp_blockchain::Result<(Block::Hash, NumberFor)> { - let (primary_hash, primary_number) = primary_info; - let (parent_hash, parent_number) = parent_info; - - tracing::debug!( - "Building a new domain block from primary block #{primary_number},{primary_hash} \ - on top of parent block #{parent_number},{parent_hash}" - ); - - let extrinsics = self - .system_domain_block_preprocessor - .preprocess_primary_block(primary_hash, parent_hash)?; - - let logs = if primary_number == One::one() { - // Manually inject the genesis block info. - vec![ - DigestItem::primary_block_info::, _>(( - Zero::zero(), - self.primary_chain_client.info().genesis_hash, - )), - DigestItem::primary_block_info((primary_number, primary_hash)), - ] - } else { - vec![DigestItem::primary_block_info(( - primary_number, - primary_hash, - ))] - }; - - let digests = Digest { logs }; - - let domain_block_result = self - .domain_block_processor - .process_domain_block( - (primary_hash, primary_number), - (parent_hash, parent_number), - extrinsics, - digests, - ) - .await?; - - let head_receipt_number = self - .primary_chain_client - .runtime_api() - .head_receipt_number(primary_hash, DomainId::SYSTEM)? - .into(); - - assert!( - domain_block_result.header_number > head_receipt_number, - "Consensus chain number must larger than execution chain number by at least 1" - ); - - let built_block_info = ( - domain_block_result.header_hash, - domain_block_result.header_number, - ); - - self.domain_block_processor.on_domain_block_processed( - primary_hash, - domain_block_result, - head_receipt_number, - )?; - - self.system_domain_receipts_checker - .check_state_transition(primary_hash)?; - - Ok(built_block_info) - } -} diff --git a/domains/client/domain-executor/src/system_gossip_message_validator.rs b/domains/client/domain-executor/src/system_gossip_message_validator.rs deleted file mode 100644 index 42324ce1805..00000000000 --- a/domains/client/domain-executor/src/system_gossip_message_validator.rs +++ /dev/null @@ -1,199 +0,0 @@ -use crate::fraud_proof::FraudProofGenerator; -use crate::gossip_message_validator::{GossipMessageError, GossipMessageValidator}; -use crate::parent_chain::ParentChainInterface; -use crate::TransactionFor; -use domain_client_executor_gossip::{Action, GossipMessageHandler}; -use domain_runtime_primitives::DomainCoreApi; -use sc_client_api::{AuxStore, BlockBackend, ProofProvider, StateBackendFor}; -use sp_api::ProvideRuntimeApi; -use sp_blockchain::HeaderBackend; -use sp_core::traits::{CodeExecutor, SpawnNamed}; -use sp_core::H256; -use sp_domains::Bundle; -use sp_runtime::traits::{Block as BlockT, HashFor, NumberFor}; -use std::sync::Arc; -use system_runtime_primitives::SystemDomainApi; - -/// Gossip message validator for system domain. -pub struct SystemGossipMessageValidator< - Block, - PBlock, - Client, - PClient, - TransactionPool, - Backend, - E, - ParentChain, -> { - client: Arc, - gossip_message_validator: GossipMessageValidator< - Block, - PBlock, - PBlock, - Client, - PClient, - Backend, - E, - TransactionPool, - ParentChain, - >, -} - -impl Clone - for SystemGossipMessageValidator< - Block, - PBlock, - Client, - PClient, - TransactionPool, - Backend, - E, - ParentChain, - > -where - ParentChain: Clone, -{ - fn clone(&self) -> Self { - Self { - client: self.client.clone(), - gossip_message_validator: self.gossip_message_validator.clone(), - } - } -} - -impl - SystemGossipMessageValidator< - Block, - PBlock, - Client, - PClient, - TransactionPool, - Backend, - E, - ParentChain, - > -where - Block: BlockT, - PBlock: BlockT, - Block::Hash: Into, - Client: HeaderBackend - + BlockBackend - + AuxStore - + ProvideRuntimeApi - + ProofProvider - + 'static, - Client::Api: DomainCoreApi - + SystemDomainApi, PBlock::Hash, Block::Hash> - + sp_block_builder::BlockBuilder - + sp_api::ApiExt>, - PClient: HeaderBackend + 'static, - Backend: sc_client_api::Backend + 'static, - TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, - TransactionPool: sc_transaction_pool_api::TransactionPool + 'static, - E: CodeExecutor, - ParentChain: ParentChainInterface + Send + Sync + Clone + 'static, -{ - pub fn new( - parent_chain: ParentChain, - client: Arc, - spawner: Box, - transaction_pool: Arc, - fraud_proof_generator: FraudProofGenerator, - ) -> Self { - let gossip_message_validator = GossipMessageValidator::new( - client.clone(), - spawner, - parent_chain, - transaction_pool, - fraud_proof_generator, - ); - Self { - client, - gossip_message_validator, - } - } - - pub fn validate_gossiped_bundle( - &self, - bundle: &Bundle, PBlock::Hash, Block::Hash>, - ) -> Result { - self.gossip_message_validator - .check_bundle_equivocation(bundle)?; - - let bundle_exists = false; - - if bundle_exists { - Ok(Action::Empty) - } else { - if !bundle.sealed_header.verify_signature() { - return Err(GossipMessageError::BadBundleSignature); - } - - // TODO: validate the bundle election. - - let domain_id = bundle.domain_id(); - - self.gossip_message_validator - .validate_bundle_receipt(&bundle.receipt, domain_id)?; - - let at = bundle - .sealed_header - .header - .bundle_solution - .creation_block_hash(); - - self.gossip_message_validator.validate_bundle_transactions( - &bundle.extrinsics, - domain_id, - *at, - )?; - - // TODO: all checks pass, add to the bundle pool - - Ok(Action::RebroadcastBundle) - } - } -} - -impl - GossipMessageHandler - for SystemGossipMessageValidator< - Block, - PBlock, - Client, - PClient, - TransactionPool, - Backend, - E, - ParentChain, - > -where - Block: BlockT, - PBlock: BlockT, - Block::Hash: Into, - Client: HeaderBackend - + BlockBackend - + ProvideRuntimeApi - + AuxStore - + ProofProvider - + 'static, - Client::Api: DomainCoreApi - + SystemDomainApi, PBlock::Hash, Block::Hash> - + sp_block_builder::BlockBuilder - + sp_api::ApiExt>, - Backend: sc_client_api::Backend + 'static, - PClient: HeaderBackend + 'static, - TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, - TransactionPool: sc_transaction_pool_api::TransactionPool + 'static, - E: CodeExecutor, - ParentChain: ParentChainInterface + Send + Sync + Clone + 'static, -{ - type Error = GossipMessageError; - - fn on_bundle( - &self, - bundle: &Bundle, PBlock::Hash, Block::Hash>, - ) -> Result { - self.validate_gossiped_bundle(bundle) - } -} diff --git a/domains/client/domain-executor/Cargo.toml b/domains/client/domain-operator/Cargo.toml similarity index 57% rename from domains/client/domain-executor/Cargo.toml rename to domains/client/domain-operator/Cargo.toml index 7fd60d2ba7b..8b336149fc4 100644 --- a/domains/client/domain-executor/Cargo.toml +++ b/domains/client/domain-operator/Cargo.toml @@ -1,67 +1,65 @@ [package] -name = "domain-client-executor" +name = "domain-client-operator" version = "0.1.0" -authors = ["Parity Technologies "] +authors = ["Subspace Labs "] edition = "2021" [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", features = [ "derive" ] } +codec = { package = "parity-scale-codec", version = "3.6.3", features = [ "derive" ] } crossbeam = "0.8.2" domain-block-builder = { version = "0.1.0", path = "../block-builder" } domain-block-preprocessor = { version = "0.1.0", path = "../block-preprocessor" } domain-client-consensus-relay-chain = { version = "0.1.0", path = "../consensus-relay-chain" } -domain-client-executor-gossip = { version = "0.1.0", path = "../executor-gossip" } domain-runtime-primitives = { version = "0.1.0", path = "../../primitives/runtime" } futures = "0.3.28" futures-timer = "3.0.1" parking_lot = "0.12.1" -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } sp-domain-digests = { version = "0.1.0", path = "../../primitives/digests" } -sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-messenger = { version = "0.1.0", path = "../../primitives/messenger" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", path = "../../../crates/sp-settlement" } -sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-weights = { version = "20.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", path = "../../../crates/subspace-core-primitives" } subspace-fraud-proof = { version = "0.1.0", path = "../../../crates/subspace-fraud-proof" } subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives" } -subspace-wasm-tools = { version = "0.1.0", path = "../../../crates/subspace-wasm-tools" } -system-runtime-primitives = { version = "0.1.0", path = "../../primitives/system-runtime" } tracing = "0.1.37" thiserror = "1.0.38" tokio = { version = "1.28.2", features = ["macros"] } [dev-dependencies] domain-client-message-relayer = { version = "0.1.0", path = "../relayer" } -domain-test-primitives = { version = "0.1.0", path = "../../test/primitives" } domain-test-service = { version = "0.1.0", path = "../../test/service" } +domain-test-primitives = { version = "0.1.0", path = "../../test/primitives" } +evm-domain-test-runtime = { version = "0.1.0", path = "../../test/runtime/evm" } num-traits = "0.2.15" -pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } pallet-domains = { version = "0.1.0", path = "../../../crates/pallet-domains" } pallet-messenger = { version = "0.1.0", path = "../../pallets/messenger" } pallet-transporter = { version = "0.1.0", path = "../../pallets/transporter" } -pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-cli = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-executor-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -system-domain-test-runtime = { version = "0.1.0", path = "../../test/runtime/system" } +pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-cli = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-executor-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +subspace-node = { version = "0.1.0", path = "../../../crates/subspace-node" } subspace-test-runtime = { version = "0.1.0", path = "../../../test/subspace-test-runtime" } subspace-test-service = { version = "0.1.0", path = "../../../test/subspace-test-service" } -substrate-test-runtime-client = { version = "2.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -substrate-test-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +substrate-test-runtime-client = { version = "2.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +substrate-test-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } tempfile = "3.4.0" diff --git a/domains/client/domain-executor/src/aux_schema.rs b/domains/client/domain-operator/src/aux_schema.rs similarity index 71% rename from domains/client/domain-executor/src/aux_schema.rs rename to domains/client/domain-operator/src/aux_schema.rs index db4e8c6b1f1..dd57d8f1f0b 100644 --- a/domains/client/domain-executor/src/aux_schema.rs +++ b/domains/client/domain-operator/src/aux_schema.rs @@ -1,11 +1,11 @@ //! Schema for executor in the aux-db. +use crate::ExecutionReceiptFor; use codec::{Decode, Encode}; use sc_client_api::backend::AuxStore; use sc_client_api::HeaderBackend; use sp_blockchain::{Error as ClientError, Result as ClientResult}; use sp_core::H256; -use sp_domains::ExecutionReceipt; use sp_runtime::traits::{Block as BlockT, NumberFor, One, SaturatedConversion}; use subspace_core_primitives::BlockNumber; @@ -24,8 +24,32 @@ const BAD_RECEIPT_MISMATCH_INFO: &[u8] = b"bad_receipt_mismatch_info"; /// NOTE: Unbounded but the size is not expected to be large. const BAD_RECEIPT_NUMBERS: &[u8] = b"bad_receipt_numbers"; -/// domain_block_hash => primary_block_hash -const PRIMARY_HASH: &[u8] = b"primary_hash"; +/// domain_block_hash => consensus_block_hash +/// +/// Updated only when there is a new domain block produced +const CONSENSUS_HASH: &[u8] = b"consensus_block_hash"; + +/// domain_block_hash => latest_consensus_block_hash +/// +/// It's important to note that a consensus block could possibly contain no bundles for a specific domain, +/// leading to the situation where multiple consensus blocks could correspond to the same domain block. +/// +/// ConsensusBlock10 --> DomainBlock5 +/// ConsensusBlock11 --> DomainBlock5 +/// ConsensusBlock12 --> DomainBlock5 +/// +/// This mapping is designed to track the most recent consensus block that derives the domain block +/// identified by `domain_block_hash`, e.g., Hash(DomainBlock5) => Hash(ConsensusBlock12). +const LATEST_CONSENSUS_HASH: &[u8] = b"latest_consensus_hash"; + +/// consensus_block_hash => best_domain_block_hash +/// +/// This mapping tracks the mapping of a consensus block and the corresponding domain block derived +/// until this consensus block: +/// - Hash(ConsensusBlock10) => Hash(DomainBlock5) +/// - Hash(ConsensusBlock11) => Hash(DomainBlock5) +/// - Hash(ConsensusBlock12) => Hash(DomainBlock5) +const BEST_DOMAIN_HASH: &[u8] = b"best_domain_hash"; /// Prune the execution receipts when they reach this number. const PRUNING_DEPTH: BlockNumber = 1000; @@ -46,7 +70,7 @@ fn load_decode( None => Ok(None), Some(t) => T::decode(&mut &t[..]) .map_err(|e| { - ClientError::Backend(format!("Executor DB is corrupted. Decode error: {e}")) + ClientError::Backend(format!("Operator DB is corrupted. Decode error: {e}")) }) .map(Some), } @@ -54,27 +78,28 @@ fn load_decode( /// Write an execution receipt to aux storage, optionally prune the receipts that are /// too old. -pub(super) fn write_execution_receipt( +pub(super) fn write_execution_receipt( backend: &Backend, head_receipt_number: NumberFor, - execution_receipt: &ExecutionReceipt, PBlock::Hash, Block::Hash>, + execution_receipt: &ExecutionReceiptFor, ) -> Result<(), sp_blockchain::Error> where Backend: AuxStore, Block: BlockT, - PBlock: BlockT, + CBlock: BlockT, { - let block_number = execution_receipt.primary_number; - let primary_hash = execution_receipt.primary_hash; + let block_number = execution_receipt.consensus_block_number; + let consensus_hash = execution_receipt.consensus_block_hash; + let domain_hash = execution_receipt.domain_block_hash; let block_number_key = (EXECUTION_RECEIPT_BLOCK_NUMBER, block_number).encode(); let mut hashes_at_block_number = - load_decode::<_, Vec>(backend, block_number_key.as_slice())? + load_decode::<_, Vec>(backend, block_number_key.as_slice())? .unwrap_or_default(); - hashes_at_block_number.push(primary_hash); + hashes_at_block_number.push(consensus_hash); let first_saved_receipt = - load_decode::<_, NumberFor>(backend, EXECUTION_RECEIPT_START)? + load_decode::<_, NumberFor>(backend, EXECUTION_RECEIPT_START)? .unwrap_or(block_number); let mut new_first_saved_receipt = first_saved_receipt; @@ -85,13 +110,13 @@ where .saturated_into::() .checked_sub(PRUNING_DEPTH) { - new_first_saved_receipt = Into::>::into(delete_receipts_to) + One::one(); + new_first_saved_receipt = Into::>::into(delete_receipts_to) + One::one(); for receipt_to_delete in first_saved_receipt.saturated_into()..=delete_receipts_to { let delete_block_number_key = (EXECUTION_RECEIPT_BLOCK_NUMBER, receipt_to_delete).encode(); if let Some(hashes_to_delete) = - load_decode::<_, Vec>(backend, delete_block_number_key.as_slice())? + load_decode::<_, Vec>(backend, delete_block_number_key.as_slice())? { keys_to_delete.extend( hashes_to_delete @@ -106,9 +131,14 @@ where backend.insert_aux( &[ ( - execution_receipt_key(primary_hash).as_slice(), + execution_receipt_key(consensus_hash).as_slice(), execution_receipt.encode().as_slice(), ), + // TODO: prune the stale mappings. + ( + (CONSENSUS_HASH, domain_hash).encode().as_slice(), + consensus_hash.encode().as_slice(), + ), ( block_number_key.as_slice(), hashes_at_block_number.encode().as_slice(), @@ -125,45 +155,103 @@ where ) } -/// Load the execution receipt for given primary block hash. -pub(super) fn load_execution_receipt( +/// Load the execution receipt for given domain block hash. +pub(super) fn load_execution_receipt_by_domain_hash( backend: &Backend, - primary_block_hash: PHash, -) -> ClientResult>> + domain_hash: Block::Hash, +) -> ClientResult>> where Backend: AuxStore, - Hash: Decode, - Number: Decode, - PHash: Encode + Decode, + Block: BlockT, + CBlock: BlockT, +{ + match consensus_block_hash_for::(backend, domain_hash)? { + Some(consensus_block_hash) => load_decode( + backend, + execution_receipt_key(consensus_block_hash).as_slice(), + ), + None => Ok(None), + } +} + +/// Load the execution receipt for given consensus block hash. +pub(super) fn load_execution_receipt( + backend: &Backend, + consensus_block_hash: CBlock::Hash, +) -> ClientResult>> +where + Backend: AuxStore, + Block: BlockT, + CBlock: BlockT, { load_decode( backend, - execution_receipt_key(primary_block_hash).as_slice(), + execution_receipt_key(consensus_block_hash).as_slice(), ) } -pub(super) fn track_domain_hash_to_primary_hash( +pub(super) fn track_domain_hash_and_consensus_hash( backend: &Backend, - domain_hash: Hash, - primary_hash: PHash, + best_domain_hash: Hash, + latest_consensus_hash: PHash, ) -> ClientResult<()> where Backend: AuxStore, - Hash: Encode, + Hash: Clone + Encode, PHash: Encode, { // TODO: prune the stale mappings. backend.insert_aux( - &[( - (PRIMARY_HASH, domain_hash).encode().as_slice(), - primary_hash.encode().as_slice(), - )], + &[ + ( + (LATEST_CONSENSUS_HASH, best_domain_hash.clone()) + .encode() + .as_slice(), + latest_consensus_hash.encode().as_slice(), + ), + ( + (BEST_DOMAIN_HASH, latest_consensus_hash) + .encode() + .as_slice(), + best_domain_hash.encode().as_slice(), + ), + ], vec![], ) } -pub(super) fn primary_hash_for( +pub(super) fn best_domain_hash_for( + backend: &Backend, + consensus_hash: &CHash, +) -> ClientResult> +where + Backend: AuxStore, + Hash: Decode, + CHash: Encode, +{ + load_decode( + backend, + (BEST_DOMAIN_HASH, consensus_hash).encode().as_slice(), + ) +} + +pub(super) fn latest_consensus_block_hash_for( + backend: &Backend, + domain_hash: &Hash, +) -> ClientResult> +where + Backend: AuxStore, + Hash: Encode, + CHash: Decode, +{ + load_decode( + backend, + (LATEST_CONSENSUS_HASH, domain_hash).encode().as_slice(), + ) +} + +pub(super) fn consensus_block_hash_for( backend: &Backend, domain_hash: Hash, ) -> ClientResult> @@ -172,9 +260,11 @@ where Hash: Encode, PHash: Decode, { - load_decode(backend, (PRIMARY_HASH, domain_hash).encode().as_slice()) + load_decode(backend, (CONSENSUS_HASH, domain_hash).encode().as_slice()) } +// TODO: Unlock once domain test infra is workable again. +#[allow(dead_code)] pub(super) fn target_receipt_is_pruned( head_receipt_number: BlockNumber, target_block: BlockNumber, @@ -183,15 +273,15 @@ pub(super) fn target_receipt_is_pruned( } /// Writes a bad execution receipt to aux storage. -pub(super) fn write_bad_receipt( +pub(super) fn write_bad_receipt( backend: &Backend, - bad_receipt_number: NumberFor, + bad_receipt_number: NumberFor, bad_receipt_hash: H256, - trace_mismatch_info: (u32, PBlock::Hash), + trace_mismatch_info: (u32, CBlock::Hash), ) -> Result<(), ClientError> where Backend: AuxStore, - PBlock: BlockT, + CBlock: BlockT, { let bad_receipt_hashes_key = (BAD_RECEIPT_HASHES, bad_receipt_number).encode(); let mut bad_receipt_hashes: Vec = @@ -206,7 +296,7 @@ where ), ]; - let mut bad_receipt_numbers: Vec> = + let mut bad_receipt_numbers: Vec> = load_decode(backend, BAD_RECEIPT_NUMBERS.encode().as_slice())?.unwrap_or_default(); // The first bad receipt detected at this block number. @@ -310,15 +400,15 @@ where load_decode(backend, BAD_RECEIPT_NUMBERS.encode().as_slice())?.unwrap_or_default(); let expired_receipt_numbers = bad_receipt_numbers - .drain_filter(|number| *number < oldest_receipt_number) + .extract_if(|number| *number < oldest_receipt_number) .collect::>(); if !expired_receipt_numbers.is_empty() { - // The bad receipt had been pruned on primary chain, i.e., _finalized_. + // The bad receipt had been pruned on consensus chain, i.e., _finalized_. tracing::error!( ?oldest_receipt_number, ?expired_receipt_numbers, - "Bad receipt(s) had been pruned on primary chain" + "Bad receipt(s) had been pruned on consensus chain" ); for expired_receipt_number in expired_receipt_numbers { @@ -344,17 +434,17 @@ where } /// Returns the first unconfirmed bad receipt info necessary for building a fraud proof if any. -pub(super) fn find_first_unconfirmed_bad_receipt_info( +pub(super) fn find_first_unconfirmed_bad_receipt_info( backend: &Backend, - canonical_primary_hash_at: F, -) -> Result, ClientError> + canonical_consensus_hash_at: F, +) -> Result, ClientError> where Backend: AuxStore + HeaderBackend, Block: BlockT, - PBlock: BlockT, - F: Fn(NumberFor) -> sp_blockchain::Result, + CBlock: BlockT, + F: Fn(NumberFor) -> sp_blockchain::Result, { - let bad_receipt_numbers: Vec> = + let bad_receipt_numbers: Vec> = load_decode(backend, BAD_RECEIPT_NUMBERS.encode().as_slice())?.unwrap_or_default(); for bad_receipt_number in bad_receipt_numbers { @@ -362,10 +452,10 @@ where let bad_receipt_hashes: Vec = load_decode(backend, bad_receipt_hashes_key.as_slice())?.unwrap_or_default(); - let canonical_primary_hash = canonical_primary_hash_at(bad_receipt_number)?; + let canonical_consensus_hash = canonical_consensus_hash_at(bad_receipt_number)?; for bad_receipt_hash in bad_receipt_hashes.iter() { - let (trace_mismatch_index, primary_block_hash): (u32, PBlock::Hash) = load_decode( + let (trace_mismatch_index, consensus_block_hash): (u32, CBlock::Hash) = load_decode( backend, bad_receipt_mismatch_info_key(bad_receipt_hash).as_slice(), )? @@ -375,11 +465,11 @@ where )) })?; - if primary_block_hash == canonical_primary_hash { + if consensus_block_hash == canonical_consensus_hash { return Ok(Some(( *bad_receipt_hash, trace_mismatch_index, - primary_block_hash, + consensus_block_hash, ))); } } @@ -391,27 +481,34 @@ where #[cfg(test)] mod tests { use super::*; - use domain_test_service::system_domain_test_runtime::Block; + use domain_test_service::evm_domain_test_runtime::Block; use sc_client_api::backend::NewBlockState; use sc_client_api::{Backend, BlockImportOperation}; use sp_core::hash::H256; use sp_runtime::traits::Header as HeaderT; use std::collections::HashSet; use std::sync::Mutex; - use subspace_runtime_primitives::{BlockNumber, Hash}; - use subspace_test_runtime::Block as PBlock; + use subspace_runtime_primitives::{Balance, BlockNumber, Hash}; + use subspace_test_runtime::Block as CBlock; // TODO: Remove `substrate_test_runtime_client` dependency for faster build time use substrate_test_runtime_client::{DefaultTestClientBuilderExt, TestClientBuilderExt}; - type ExecutionReceipt = sp_domains::ExecutionReceipt; + type ExecutionReceipt = + sp_domains::ExecutionReceipt; - fn create_execution_receipt(primary_number: BlockNumber) -> ExecutionReceipt { + fn create_execution_receipt(consensus_block_number: BlockNumber) -> ExecutionReceipt { ExecutionReceipt { - primary_number, - primary_hash: H256::random(), - domain_hash: H256::random(), - trace: Default::default(), - trace_root: Default::default(), + domain_block_number: consensus_block_number, + domain_block_hash: H256::random(), + parent_domain_block_receipt_hash: H256::random(), + consensus_block_number, + consensus_block_hash: H256::random(), + invalid_bundles: Vec::new(), + block_extrinsics_roots: Default::default(), + final_state_root: Default::default(), + execution_trace: Default::default(), + execution_trace_root: Default::default(), + total_rewards: Default::default(), } } @@ -455,11 +552,12 @@ mod tests { .unwrap() }; - let receipt_at = - |primary_block_hash: Hash| load_execution_receipt(&client, primary_block_hash).unwrap(); + let receipt_at = |consensus_block_hash: Hash| { + load_execution_receipt::<_, Block, CBlock>(&client, consensus_block_hash).unwrap() + }; let write_receipt_at = |number: BlockNumber, receipt: &ExecutionReceipt| { - write_execution_receipt::<_, Block, PBlock>( + write_execution_receipt::<_, Block, CBlock>( &client, number - 1, // Ideally, the receipt of previous block has been included when writing the receipt of current block. receipt, @@ -473,12 +571,12 @@ mod tests { let block_hash_list = (1..=PRUNING_DEPTH) .map(|block_number| { let receipt = create_execution_receipt(block_number); - let primary_hash = receipt.primary_hash; + let consensus_block_hash = receipt.consensus_block_hash; write_receipt_at(block_number, &receipt); - assert_eq!(receipt_at(primary_hash), Some(receipt)); - assert_eq!(hashes_at(block_number), Some(vec![primary_hash])); + assert_eq!(receipt_at(consensus_block_hash), Some(receipt)); + assert_eq!(hashes_at(block_number), Some(vec![consensus_block_hash])); assert_eq!(receipt_start(), Some(1)); - primary_hash + consensus_block_hash }) .collect::>(); @@ -486,14 +584,14 @@ mod tests { // Create PRUNING_DEPTH + 1 receipt, head_receipt_number is PRUNING_DEPTH. let receipt = create_execution_receipt(PRUNING_DEPTH + 1); - assert!(receipt_at(receipt.primary_hash).is_none()); + assert!(receipt_at(receipt.consensus_block_hash).is_none()); write_receipt_at(PRUNING_DEPTH + 1, &receipt); - assert!(receipt_at(receipt.primary_hash).is_some()); + assert!(receipt_at(receipt.consensus_block_hash).is_some()); // Create PRUNING_DEPTH + 2 receipt, head_receipt_number is PRUNING_DEPTH + 1. let receipt = create_execution_receipt(PRUNING_DEPTH + 2); write_receipt_at(PRUNING_DEPTH + 2, &receipt); - assert!(receipt_at(receipt.primary_hash).is_some()); + assert!(receipt_at(receipt.consensus_block_hash).is_some()); // ER of block #1 should be pruned. assert!(receipt_at(block_hash_list[0]).is_none()); @@ -504,9 +602,9 @@ mod tests { // Create PRUNING_DEPTH + 3 receipt, head_receipt_number is PRUNING_DEPTH + 2. let receipt = create_execution_receipt(PRUNING_DEPTH + 3); - let primary_hash1 = receipt.primary_hash; + let consensus_block_hash1 = receipt.consensus_block_hash; write_receipt_at(PRUNING_DEPTH + 3, &receipt); - assert!(receipt_at(primary_hash1).is_some()); + assert!(receipt_at(consensus_block_hash1).is_some()); // ER of block #2 should be pruned. assert!(receipt_at(block_hash_list[1]).is_none()); assert!(target_receipt_is_pruned(PRUNING_DEPTH + 2, 2)); @@ -515,12 +613,12 @@ mod tests { // Multiple hashes attached to the block #(PRUNING_DEPTH + 3) let receipt = create_execution_receipt(PRUNING_DEPTH + 3); - let primary_hash2 = receipt.primary_hash; + let consensus_block_hash2 = receipt.consensus_block_hash; write_receipt_at(PRUNING_DEPTH + 3, &receipt); - assert!(receipt_at(primary_hash2).is_some()); + assert!(receipt_at(consensus_block_hash2).is_some()); assert_eq!( hashes_at(PRUNING_DEPTH + 3), - Some(vec![primary_hash1, primary_hash2]) + Some(vec![consensus_block_hash1, consensus_block_hash2]) ); } @@ -543,27 +641,28 @@ mod tests { .unwrap() }; - let receipt_at = - |primary_block_hash: Hash| load_execution_receipt(&client, primary_block_hash).unwrap(); + let receipt_at = |consensus_block_hash: Hash| { + load_execution_receipt::<_, Block, CBlock>(&client, consensus_block_hash).unwrap() + }; let write_receipt_at = |head_receipt_number: BlockNumber, receipt: &ExecutionReceipt| { - write_execution_receipt::<_, Block, PBlock>(&client, head_receipt_number, receipt) + write_execution_receipt::<_, Block, CBlock>(&client, head_receipt_number, receipt) .unwrap() }; assert_eq!(receipt_start(), None); // Create PRUNING_DEPTH receipts, head_receipt_number is 0, i.e., no receipt - // has ever been included on primary chain. + // has ever been included on consensus chain. let block_hash_list = (1..=PRUNING_DEPTH) .map(|block_number| { let receipt = create_execution_receipt(block_number); - let primary_hash = receipt.primary_hash; + let consensus_block_hash = receipt.consensus_block_hash; write_receipt_at(0, &receipt); - assert_eq!(receipt_at(primary_hash), Some(receipt)); - assert_eq!(hashes_at(block_number), Some(vec![primary_hash])); + assert_eq!(receipt_at(consensus_block_hash), Some(receipt)); + assert_eq!(hashes_at(block_number), Some(vec![consensus_block_hash])); assert_eq!(receipt_start(), Some(1)); - primary_hash + consensus_block_hash }) .collect::>(); @@ -571,7 +670,7 @@ mod tests { // Create PRUNING_DEPTH + 1 receipt, head_receipt_number is 0. let receipt = create_execution_receipt(PRUNING_DEPTH + 1); - assert!(receipt_at(receipt.primary_hash).is_none()); + assert!(receipt_at(receipt.consensus_block_hash).is_none()); write_receipt_at(0, &receipt); // Create PRUNING_DEPTH + 2 receipt, head_receipt_number is 0. @@ -608,9 +707,9 @@ mod tests { #[test] #[ignore] fn write_delete_prune_bad_receipt_works() { - struct PrimaryNumberHashMappings(Mutex>); + struct ConsensusNumberHashMappings(Mutex>); - impl PrimaryNumberHashMappings { + impl ConsensusNumberHashMappings { fn insert_number_to_hash_mapping(&self, block_number: u32, block_hash: Hash) { let mut mappings = self.0.lock().unwrap(); if !mappings.contains(&(block_number, block_hash)) { @@ -632,7 +731,7 @@ mod tests { let (client, backend) = substrate_test_runtime_client::TestClientBuilder::new().build_with_backend(); - let primary_chain_client = PrimaryNumberHashMappings(Mutex::new(Vec::new())); + let consensus_client = ConsensusNumberHashMappings(Mutex::new(Vec::new())); let bad_receipts_at = |number: BlockNumber| -> Option> { let bad_receipt_hashes_key = (BAD_RECEIPT_HASHES, number).encode(); @@ -657,8 +756,8 @@ mod tests { |oldest_receipt_number: BlockNumber| -> Option<(H256, u32, Hash)> { // Always check and prune the expired bad receipts before loading the first unconfirmed one. prune_expired_bad_receipts(&client, oldest_receipt_number).unwrap(); - find_first_unconfirmed_bad_receipt_info::<_, _, PBlock, _>(&client, |height| { - Ok(primary_chain_client.canonical_hash(height).unwrap()) + find_first_unconfirmed_bad_receipt_info::<_, _, CBlock, _>(&client, |height| { + Ok(consensus_client.canonical_hash(height).unwrap()) }) .unwrap() }; @@ -676,22 +775,22 @@ mod tests { insert_header(backend.as_ref(), 3u64, block_hash2), ); - primary_chain_client.insert_number_to_hash_mapping(10, block_hash1); - write_bad_receipt::<_, PBlock>(&client, 10, bad_receipt_hash1, (1, block_hash1)).unwrap(); + consensus_client.insert_number_to_hash_mapping(10, block_hash1); + write_bad_receipt::<_, CBlock>(&client, 10, bad_receipt_hash1, (1, block_hash1)).unwrap(); assert_eq!(bad_receipt_numbers(), Some(vec![10])); - primary_chain_client.insert_number_to_hash_mapping(10, block_hash2); - write_bad_receipt::<_, PBlock>(&client, 10, bad_receipt_hash2, (2, block_hash2)).unwrap(); + consensus_client.insert_number_to_hash_mapping(10, block_hash2); + write_bad_receipt::<_, CBlock>(&client, 10, bad_receipt_hash2, (2, block_hash2)).unwrap(); assert_eq!(bad_receipt_numbers(), Some(vec![10])); - primary_chain_client.insert_number_to_hash_mapping(10, block_hash3); - write_bad_receipt::<_, PBlock>(&client, 10, bad_receipt_hash3, (3, block_hash3)).unwrap(); + consensus_client.insert_number_to_hash_mapping(10, block_hash3); + write_bad_receipt::<_, CBlock>(&client, 10, bad_receipt_hash3, (3, block_hash3)).unwrap(); assert_eq!(bad_receipt_numbers(), Some(vec![10])); let (bad_receipt_hash4, block_hash4) = ( Hash::random(), insert_header(backend.as_ref(), 4u64, block_hash3), ); - primary_chain_client.insert_number_to_hash_mapping(20, block_hash4); - write_bad_receipt::<_, PBlock>(&client, 20, bad_receipt_hash4, (1, block_hash4)).unwrap(); + consensus_client.insert_number_to_hash_mapping(20, block_hash4); + write_bad_receipt::<_, CBlock>(&client, 20, bad_receipt_hash4, (1, block_hash4)).unwrap(); assert_eq!(bad_receipt_numbers(), Some(vec![10, 20])); assert_eq!( @@ -746,8 +845,8 @@ mod tests { Hash::random(), insert_header(backend.as_ref(), 5u64, block_hash4), ); - primary_chain_client.insert_number_to_hash_mapping(30, block_hash5); - write_bad_receipt::<_, PBlock>(&client, 30, bad_receipt_hash5, (1, block_hash5)).unwrap(); + consensus_client.insert_number_to_hash_mapping(30, block_hash5); + write_bad_receipt::<_, CBlock>(&client, 30, bad_receipt_hash5, (1, block_hash5)).unwrap(); assert_eq!(bad_receipt_numbers(), Some(vec![30])); assert_eq!(bad_receipts_at(30).unwrap(), [bad_receipt_hash5].into()); // Expired bad receipts will be removed. diff --git a/domains/client/domain-operator/src/bootstrapper.rs b/domains/client/domain-operator/src/bootstrapper.rs new file mode 100644 index 00000000000..bb948007fef --- /dev/null +++ b/domains/client/domain-operator/src/bootstrapper.rs @@ -0,0 +1,107 @@ +use futures::StreamExt; +use sc_client_api::{BlockchainEvents, ImportNotifications}; +use sp_api::{HeaderT, NumberFor, ProvideRuntimeApi}; +use sp_blockchain::HeaderBackend; +use sp_domains::{DomainId, DomainInstanceData, DomainsApi, DomainsDigestItem}; +use sp_runtime::traits::Block as BlockT; +use std::marker::PhantomData; +use std::sync::Arc; + +pub struct BootstrapResult { + // The `DomainInstanceData` used by the domain instance starter to + // construct `RuntimeGenesisConfig` of the domain instance + pub domain_instance_data: DomainInstanceData, + /// The consensus chain block number when the domain first instantiated. + pub domain_created_at: NumberFor, + // The `imported_block_notification_stream` used by the bootstrapper + // + // NOTE: the domain instance starter must reuse this stream instead of + // create a new one from the consensus client to avoid missing imported + // block notification. + pub imported_block_notification_stream: ImportNotifications, +} + +/// Domain instance bootstrapper +pub struct Bootstrapper { + consensus_client: Arc, + _phantom_data: PhantomData<(Block, CBlock)>, +} + +impl Bootstrapper +where + Block: BlockT, + CBlock: BlockT, + CClient: HeaderBackend + + ProvideRuntimeApi + + BlockchainEvents + + Send + + Sync + + 'static, + CClient::Api: DomainsApi, Block::Hash>, +{ + pub fn new(consensus_client: Arc) -> Self { + Bootstrapper { + consensus_client, + _phantom_data: Default::default(), + } + } + + pub async fn fetch_domain_bootstrap_info( + self, + self_domain_id: DomainId, + ) -> std::result::Result, Box> { + let mut imported_block_notification_stream = + self.consensus_client.every_import_notification_stream(); + + // Check if the domain instance data already exist in the consensus chain's genesis state + let best_hash = self.consensus_client.info().best_hash; + if let Some((domain_instance_data, domain_created_at)) = self + .consensus_client + .runtime_api() + .domain_instance_data(best_hash, self_domain_id)? + { + return Ok(BootstrapResult { + domain_instance_data, + domain_created_at, + imported_block_notification_stream, + }); + } + + // Check each imported consensus block to get the domain instance data + let (domain_instance_data, domain_created_at) = 'outer: loop { + if let Some(block_imported) = imported_block_notification_stream.next().await { + let header = block_imported.header; + for item in header.digest().logs.iter() { + if let Some(domain_id) = item.as_domain_instantiation() { + if domain_id == self_domain_id { + let res = self + .consensus_client + .runtime_api() + .domain_instance_data(header.hash(), domain_id)?; + + match res { + Some(data) => break 'outer data, + None => { + return Err(format!( + "Failed to get domain instance data for domain {domain_id:?}" + ) + .into()) + } + } + } + } + } + } else { + return Err("Imported block notification stream end unexpectedly" + .to_string() + .into()); + } + }; + + Ok(BootstrapResult { + domain_instance_data, + domain_created_at, + imported_block_notification_stream, + }) + } +} diff --git a/domains/client/domain-operator/src/bundle_processor.rs b/domains/client/domain-operator/src/bundle_processor.rs new file mode 100644 index 00000000000..fd2501841d7 --- /dev/null +++ b/domains/client/domain-operator/src/bundle_processor.rs @@ -0,0 +1,329 @@ +use crate::domain_block_processor::{ + DomainBlockProcessor, PendingConsensusBlocks, ReceiptsChecker, +}; +use crate::{DomainParentChain, ExecutionReceiptFor, TransactionFor}; +use domain_block_preprocessor::runtime_api_full::RuntimeApiFull; +use domain_block_preprocessor::{DomainBlockPreprocessor, PreprocessResult}; +use domain_runtime_primitives::{DomainCoreApi, InherentExtrinsicApi}; +use sc_client_api::{AuxStore, BlockBackend, Finalizer, StateBackendFor}; +use sc_consensus::{BlockImport, BlockImportParams, ForkChoiceStrategy, StateAction}; +use sp_api::{NumberFor, ProvideRuntimeApi}; +use sp_blockchain::{HeaderBackend, HeaderMetadata}; +use sp_consensus::BlockOrigin; +use sp_core::traits::CodeExecutor; +use sp_domains::{DomainId, DomainsApi, InvalidReceipt, ReceiptValidity}; +use sp_keystore::KeystorePtr; +use sp_messenger::MessengerApi; +use sp_runtime::traits::{Block as BlockT, HashFor, Zero}; +use sp_runtime::Digest; +use std::sync::Arc; + +type DomainReceiptsChecker = ReceiptsChecker< + Block, + Client, + CBlock, + CClient, + Backend, + E, + DomainParentChain, + CBlock, +>; + +pub(crate) struct BundleProcessor +where + Block: BlockT, + CBlock: BlockT, +{ + domain_id: DomainId, + consensus_client: Arc, + client: Arc, + backend: Arc, + keystore: KeystorePtr, + domain_receipts_checker: DomainReceiptsChecker, + domain_block_preprocessor: DomainBlockPreprocessor< + Block, + CBlock, + Client, + CClient, + RuntimeApiFull, + ReceiptValidator, + >, + domain_block_processor: DomainBlockProcessor, +} + +impl Clone + for BundleProcessor +where + Block: BlockT, + CBlock: BlockT, +{ + fn clone(&self) -> Self { + Self { + domain_id: self.domain_id, + consensus_client: self.consensus_client.clone(), + client: self.client.clone(), + backend: self.backend.clone(), + keystore: self.keystore.clone(), + domain_receipts_checker: self.domain_receipts_checker.clone(), + domain_block_preprocessor: self.domain_block_preprocessor.clone(), + domain_block_processor: self.domain_block_processor.clone(), + } + } +} + +struct ReceiptValidator { + client: Arc, +} + +impl Clone for ReceiptValidator { + fn clone(&self) -> Self { + Self { + client: self.client.clone(), + } + } +} + +impl ReceiptValidator { + pub fn new(client: Arc) -> Self { + Self { client } + } +} + +impl domain_block_preprocessor::ValidateReceipt + for ReceiptValidator +where + Block: BlockT, + CBlock: BlockT, + Client: AuxStore, +{ + fn validate_receipt( + &self, + receipt: &ExecutionReceiptFor, + ) -> sp_blockchain::Result { + // Skip genesis receipt as it has been already verified by the consensus chain. + if receipt.domain_block_number.is_zero() { + return Ok(ReceiptValidity::Valid); + } + + let consensus_block_hash = receipt.consensus_block_hash; + let local_receipt = crate::aux_schema::load_execution_receipt::<_, Block, CBlock>( + &*self.client, + consensus_block_hash, + )? + .ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Receipt for consensus block {consensus_block_hash} not found" + )) + })?; + + if local_receipt.invalid_bundles != receipt.invalid_bundles { + // TODO: Generate fraud proof + return Ok(ReceiptValidity::Invalid(InvalidReceipt::InvalidBundles)); + } + + Ok(ReceiptValidity::Valid) + } +} + +impl + BundleProcessor +where + Block: BlockT, + CBlock: BlockT, + NumberFor: From> + Into>, + CBlock::Hash: From, + Client: HeaderBackend + + BlockBackend + + AuxStore + + ProvideRuntimeApi + + Finalizer + + 'static, + Client::Api: DomainCoreApi + + MessengerApi> + + InherentExtrinsicApi + + sp_block_builder::BlockBuilder + + sp_api::ApiExt>, + for<'b> &'b BI: BlockImport< + Block, + Transaction = sp_api::TransactionFor, + Error = sp_consensus::Error, + >, + CClient: HeaderBackend + + HeaderMetadata + + BlockBackend + + ProvideRuntimeApi + + 'static, + CClient::Api: DomainsApi, Block::Hash> + 'static, + Backend: sc_client_api::Backend + 'static, + TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, + E: CodeExecutor, +{ + pub(crate) fn new( + domain_id: DomainId, + consensus_client: Arc, + client: Arc, + backend: Arc, + keystore: KeystorePtr, + domain_receipts_checker: DomainReceiptsChecker, + domain_block_processor: DomainBlockProcessor, + ) -> Self { + let domain_block_preprocessor = DomainBlockPreprocessor::new( + domain_id, + client.clone(), + consensus_client.clone(), + RuntimeApiFull::new(client.clone()), + ReceiptValidator::new(client.clone()), + ); + Self { + domain_id, + consensus_client, + client, + backend, + keystore, + domain_receipts_checker, + domain_block_preprocessor, + domain_block_processor, + } + } + + // TODO: Handle the returned error properly, ref to https://github.com/subspace/subspace/pull/695#discussion_r926721185 + pub(crate) async fn process_bundles( + self, + consensus_block_info: (CBlock::Hash, NumberFor, bool), + ) -> sp_blockchain::Result<()> { + let (consensus_block_hash, consensus_block_number, is_new_best) = consensus_block_info; + + tracing::debug!( + "Processing consensus block #{consensus_block_number},{consensus_block_hash}" + ); + + let maybe_pending_consensus_blocks = self + .domain_block_processor + .pending_imported_consensus_blocks(consensus_block_hash, consensus_block_number)?; + + if let Some(PendingConsensusBlocks { + initial_parent, + consensus_imports, + }) = maybe_pending_consensus_blocks + { + tracing::trace!( + ?initial_parent, + ?consensus_imports, + "Pending consensus blocks to process" + ); + + let mut domain_parent = initial_parent; + + for consensus_info in consensus_imports { + if let Some(next_domain_parent) = self + .process_bundles_at((consensus_info.hash, consensus_info.number), domain_parent) + .await? + { + domain_parent = next_domain_parent; + } + } + + // The domain branch driving from the best consensus branch should also be the best domain branch even + // if it is no the longest domain branch. Thus re-import the tip of the best domain branch to make it + // the new best block if it isn't. + // + // Note: this may cause the best domain fork switch to a shorter fork or in some case the best domain + // block become the ancestor block of the current best block. + let domain_tip = domain_parent.0; + if is_new_best && self.client.info().best_hash != domain_tip { + let header = self.client.header(domain_tip)?.ok_or_else(|| { + sp_blockchain::Error::Backend(format!("Header for #{:?} not found", domain_tip)) + })?; + let block_import_params = { + let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); + import_block.import_existing = true; + import_block.fork_choice = Some(ForkChoiceStrategy::Custom(true)); + import_block.state_action = StateAction::Skip; + import_block + }; + self.domain_block_processor + .import_domain_block(block_import_params) + .await?; + assert_eq!(domain_tip, self.client.info().best_hash); + } + } + + Ok(()) + } + + async fn process_bundles_at( + &self, + consensus_block_info: (CBlock::Hash, NumberFor), + parent_info: (Block::Hash, NumberFor), + ) -> sp_blockchain::Result)>> { + let (consensus_block_hash, consensus_block_number) = consensus_block_info; + let (parent_hash, parent_number) = parent_info; + + tracing::debug!( + "Building a new domain block from consensus block #{consensus_block_number},{consensus_block_hash} \ + on top of parent block #{parent_number},{parent_hash}" + ); + + let head_receipt_number = self + .consensus_client + .runtime_api() + .head_receipt_number(consensus_block_hash, self.domain_id)? + .into(); + + let Some(PreprocessResult { + extrinsics, + extrinsics_roots, + invalid_bundles, + }) = self + .domain_block_preprocessor + .preprocess_consensus_block(consensus_block_hash, parent_hash)? + else { + tracing::debug!( + "Skip building new domain block, no bundles and runtime upgrade for this domain \ + in consensus block #{consensus_block_number:?},{consensus_block_hash}" + ); + self.domain_block_processor.on_consensus_block_processed( + consensus_block_hash, + None, + head_receipt_number, + )?; + + return Ok(None); + }; + + let domain_block_result = self + .domain_block_processor + .process_domain_block( + (consensus_block_hash, consensus_block_number), + (parent_hash, parent_number), + extrinsics, + invalid_bundles, + extrinsics_roots, + Digest::default(), + ) + .await?; + + assert!( + domain_block_result.header_number > head_receipt_number, + "Domain chain number must larger than the head number of the receipt chain \ + (which is maintained on the consensus chain) by at least 1" + ); + + let built_block_info = ( + domain_block_result.header_hash, + domain_block_result.header_number, + ); + + self.domain_block_processor.on_consensus_block_processed( + consensus_block_hash, + Some(domain_block_result), + head_receipt_number, + )?; + + // TODO: Remove as ReceiptsChecker has been superseded by ReceiptValidator in block-preprocessor. + self.domain_receipts_checker + .check_state_transition(consensus_block_hash)?; + + Ok(Some(built_block_info)) + } +} diff --git a/domains/client/domain-operator/src/bundle_producer_election_solver.rs b/domains/client/domain-operator/src/bundle_producer_election_solver.rs new file mode 100644 index 00000000000..9973fee4239 --- /dev/null +++ b/domains/client/domain-operator/src/bundle_producer_election_solver.rs @@ -0,0 +1,106 @@ +use sp_api::ProvideRuntimeApi; +use sp_consensus_slots::Slot; +use sp_domains::bundle_producer_election::{ + calculate_threshold, is_below_threshold, make_transcript, BundleProducerElectionParams, +}; +use sp_domains::{BundleProducerElectionApi, DomainId, OperatorPublicKey, ProofOfElection}; +use sp_keystore::{Keystore, KeystorePtr}; +use sp_runtime::traits::Block as BlockT; +use sp_runtime::RuntimeAppPublic; +use std::marker::PhantomData; +use std::sync::Arc; +use subspace_core_primitives::Randomness; +use subspace_runtime_primitives::Balance; + +pub(super) struct BundleProducerElectionSolver { + keystore: KeystorePtr, + consensus_client: Arc, + _phantom_data: PhantomData<(Block, CBlock)>, +} + +impl Clone for BundleProducerElectionSolver { + fn clone(&self) -> Self { + Self { + keystore: self.keystore.clone(), + consensus_client: self.consensus_client.clone(), + _phantom_data: self._phantom_data, + } + } +} + +impl BundleProducerElectionSolver +where + Block: BlockT, + CBlock: BlockT, + CClient: ProvideRuntimeApi, + CClient::Api: BundleProducerElectionApi, +{ + pub(super) fn new(keystore: KeystorePtr, consensus_client: Arc) -> Self { + Self { + keystore, + consensus_client, + _phantom_data: PhantomData, + } + } + + pub(super) fn solve_challenge( + &self, + slot: Slot, + consensus_block_hash: CBlock::Hash, + domain_id: DomainId, + global_randomness: Randomness, + ) -> sp_blockchain::Result> { + let BundleProducerElectionParams { + current_operators, + total_domain_stake, + bundle_slot_probability, + } = match self + .consensus_client + .runtime_api() + .bundle_producer_election_params(consensus_block_hash, domain_id)? + { + Some(params) => params, + None => return Ok(None), + }; + + let global_challenge = global_randomness.derive_global_challenge(slot.into()); + let vrf_sign_data = make_transcript(domain_id, &global_challenge).into_sign_data(); + + // TODO: The runtime API may take 10~20 microseonds each time, looping the operator set + // could take too long for the bundle production, track a mapping of signing_key to + // operator_id in the runtime and then we can update it to loop the keys in the keystore. + for operator_id in current_operators { + if let Some((operator_signing_key, operator_stake)) = self + .consensus_client + .runtime_api() + .operator(consensus_block_hash, operator_id)? + { + if let Ok(Some(vrf_signature)) = Keystore::sr25519_vrf_sign( + &*self.keystore, + OperatorPublicKey::ID, + &operator_signing_key.clone().into(), + &vrf_sign_data, + ) { + let threshold = calculate_threshold( + operator_stake, + total_domain_stake, + bundle_slot_probability, + ); + + if is_below_threshold(&vrf_signature.output, threshold) { + let proof_of_election = ProofOfElection { + domain_id, + slot_number: slot.into(), + global_randomness, + vrf_signature, + operator_id, + }; + return Ok(Some((proof_of_election, operator_signing_key))); + } + } + } + } + + Ok(None) + } +} diff --git a/domains/client/domain-operator/src/domain_block_processor.rs b/domains/client/domain-operator/src/domain_block_processor.rs new file mode 100644 index 00000000000..59814e92a21 --- /dev/null +++ b/domains/client/domain-operator/src/domain_block_processor.rs @@ -0,0 +1,761 @@ +use crate::fraud_proof::{find_trace_mismatch, FraudProofGenerator}; +use crate::parent_chain::ParentChainInterface; +use crate::utils::{DomainBlockImportNotification, DomainImportNotificationSinks}; +use crate::ExecutionReceiptFor; +use codec::{Decode, Encode}; +use domain_block_builder::{BlockBuilder, BuiltBlock, RecordProof}; +use domain_runtime_primitives::DomainCoreApi; +use sc_client_api::{AuxStore, BlockBackend, Finalizer, StateBackendFor, TransactionFor}; +use sc_consensus::{ + BlockImport, BlockImportParams, ForkChoiceStrategy, ImportResult, StateAction, StorageChanges, +}; +use sp_api::{NumberFor, ProvideRuntimeApi}; +use sp_blockchain::{HashAndNumber, HeaderBackend, HeaderMetadata}; +use sp_consensus::{BlockOrigin, SyncOracle}; +use sp_core::traits::CodeExecutor; +use sp_domains::fraud_proof::FraudProof; +use sp_domains::merkle_tree::MerkleTree; +use sp_domains::{DomainId, DomainsApi, ExecutionReceipt, ExtrinsicsRoot, InvalidBundle}; +use sp_runtime::traits::{Block as BlockT, CheckedSub, HashFor, Header as HeaderT, One, Zero}; +use sp_runtime::Digest; +use std::cmp::Ordering; +use std::sync::Arc; + +pub(crate) struct DomainBlockResult +where + Block: BlockT, + CBlock: BlockT, +{ + pub header_hash: Block::Hash, + pub header_number: NumberFor, + pub execution_receipt: ExecutionReceiptFor, +} + +/// An abstracted domain block processor. +pub(crate) struct DomainBlockProcessor +where + Block: BlockT, + CBlock: BlockT, +{ + pub(crate) domain_id: DomainId, + pub(crate) domain_created_at: NumberFor, + pub(crate) client: Arc, + pub(crate) consensus_client: Arc, + pub(crate) backend: Arc, + pub(crate) domain_confirmation_depth: NumberFor, + pub(crate) block_import: Arc, + pub(crate) import_notification_sinks: DomainImportNotificationSinks, +} + +impl Clone + for DomainBlockProcessor +where + Block: BlockT, + CBlock: BlockT, +{ + fn clone(&self) -> Self { + Self { + domain_id: self.domain_id, + domain_created_at: self.domain_created_at, + client: self.client.clone(), + consensus_client: self.consensus_client.clone(), + backend: self.backend.clone(), + domain_confirmation_depth: self.domain_confirmation_depth, + block_import: self.block_import.clone(), + import_notification_sinks: self.import_notification_sinks.clone(), + } + } +} + +/// A list of consensus blocks waiting to be processed by operator on each imported consensus block +/// notification. +/// +/// Usually, each new domain block is built on top of the current best domain block, with the block +/// content extracted from the incoming consensus block. However, an incoming imported consensus block +/// notification can also imply multiple pending consensus blocks in case of the consensus chain re-org. +#[derive(Debug)] +pub(crate) struct PendingConsensusBlocks { + /// Base block used to build new domain blocks derived from the consensus blocks below. + pub initial_parent: (Block::Hash, NumberFor), + /// Pending consensus blocks that need to be processed sequentially. + pub consensus_imports: Vec>, +} + +impl + DomainBlockProcessor +where + Block: BlockT, + CBlock: BlockT, + NumberFor: Into>, + Client: HeaderBackend + + BlockBackend + + AuxStore + + ProvideRuntimeApi + + Finalizer + + 'static, + Client::Api: DomainCoreApi + + sp_block_builder::BlockBuilder + + sp_api::ApiExt>, + for<'b> &'b BI: BlockImport< + Block, + Transaction = sp_api::TransactionFor, + Error = sp_consensus::Error, + >, + CClient: HeaderBackend + + HeaderMetadata + + BlockBackend + + ProvideRuntimeApi + + 'static, + CClient::Api: DomainsApi, Block::Hash> + 'static, + Backend: sc_client_api::Backend + 'static, + TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, +{ + /// Returns a list of consensus blocks waiting to be processed if any. + /// + /// It's possible to have multiple pending consensus blocks that need to be processed in case + /// the consensus chain re-org occurs. + pub(crate) fn pending_imported_consensus_blocks( + &self, + consensus_block_hash: CBlock::Hash, + consensus_block_number: NumberFor, + ) -> sp_blockchain::Result>> { + match consensus_block_number.cmp(&(self.domain_created_at + One::one())) { + // Consensus block at `domain_created_at + 1` is the first block that possibly contains + // bundle, thus we can safely skip any consensus block that is smaller than this block. + Ordering::Less => return Ok(None), + // For consensus block at `domain_created_at + 1` use the genesis domain block as the + // initial parent block directly to avoid further processing. + Ordering::Equal => { + return Ok(Some(PendingConsensusBlocks { + initial_parent: (self.client.info().genesis_hash, Zero::zero()), + consensus_imports: vec![HashAndNumber { + hash: consensus_block_hash, + number: consensus_block_number, + }], + })); + } + // For consensus block > `domain_created_at + 1`, there is potential existing fork + // thus we need to handle it carefully as following. + Ordering::Greater => {} + } + + let best_hash = self.client.info().best_hash; + let best_number = self.client.info().best_number; + + // When there are empty consensus blocks multiple consensus block could map to the same + // domain block, thus use `latest_consensus_block_hash_for` to find the latest consensus + // block that map to the best domain block. + let consensus_block_hash_for_best_domain_hash = + match crate::aux_schema::latest_consensus_block_hash_for(&*self.backend, &best_hash)? { + // If the auxiliary storage is empty and the best domain block is the genesis block + // this consensus block could be the first block being processed thus just use the + // consensus block at `domain_created_at` directly, otherwise the auxiliary storage + // is expected to be non-empty thus return an error. + // + // NOTE: it is important to check the auxiliary storage first before checking if it + // is the genesis block otherwise we may repeatedly processing the empty consensus + // block, see https://github.com/subspace/subspace/issues/1763 for more detail. + None if best_number.is_zero() => self + .consensus_client + .hash(self.domain_created_at)? + .ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Consensus hash for block #{} not found", + self.domain_created_at + )) + })?, + None => { + return Err(sp_blockchain::Error::Backend(format!( + "Consensus hash for domain hash #{best_number},{best_hash} not found" + ))) + } + Some(b) => b, + }; + + let consensus_from = consensus_block_hash_for_best_domain_hash; + let consensus_to = consensus_block_hash; + + if consensus_from == consensus_to { + return Err(sp_blockchain::Error::Application( + format!("Consensus block {consensus_block_hash:?} has already been processed.",) + .into(), + )); + } + + let route = + sp_blockchain::tree_route(&*self.consensus_client, consensus_from, consensus_to)?; + + let retracted = route.retracted(); + let enacted = route.enacted(); + + tracing::trace!( + ?retracted, + ?enacted, + common_block = ?route.common_block(), + "Calculating PendingConsensusBlocks on #{best_number},{best_hash:?}" + ); + + match (retracted.is_empty(), enacted.is_empty()) { + (true, false) => { + // New tip, A -> B + Ok(Some(PendingConsensusBlocks { + initial_parent: (best_hash, best_number), + consensus_imports: enacted.to_vec(), + })) + } + (false, true) => { + tracing::debug!("Consensus blocks {retracted:?} have been already processed"); + Ok(None) + } + (true, true) => { + unreachable!( + "Tree route is not empty as `consensus_from` and `consensus_to` in tree_route() \ + are checked above to be not the same; qed", + ); + } + (false, false) => { + let (common_block_number, common_block_hash) = + (route.common_block().number, route.common_block().hash); + + // The `common_block` is smaller than the consensus block that the domain was created at, thus + // we can safely skip any consensus block that is smaller than `domain_created_at` and start at + // the consensus block `domain_created_at + 1`, which the first block that possibly contains bundle, + // and use the genesis domain block as the initial parent block. + if common_block_number <= self.domain_created_at { + let consensus_imports = enacted + .iter() + .skip_while(|block| block.number <= self.domain_created_at) + .cloned() + .collect(); + return Ok(Some(PendingConsensusBlocks { + initial_parent: (self.client.info().genesis_hash, Zero::zero()), + consensus_imports, + })); + } + + // Get the domain block that is derived from the common consensus block and use it as + // the initial domain parent block + let domain_block_hash: Block::Hash = crate::aux_schema::best_domain_hash_for( + &*self.client, + &common_block_hash, + )? + .ok_or_else( + || { + sp_blockchain::Error::Backend(format!( + "Hash of domain block derived from consensus block #{common_block_number},{common_block_hash} not found" + )) + }, + )?; + let parent_header = self.client.header(domain_block_hash)?.ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Domain block header for #{domain_block_hash:?} not found", + )) + })?; + + Ok(Some(PendingConsensusBlocks { + initial_parent: (parent_header.hash(), *parent_header.number()), + consensus_imports: enacted.to_vec(), + })) + } + } + } + + pub(crate) async fn process_domain_block( + &self, + (consensus_block_hash, consensus_block_number): (CBlock::Hash, NumberFor), + (parent_hash, parent_number): (Block::Hash, NumberFor), + extrinsics: Vec, + invalid_bundles: Vec, + bundle_extrinsics_roots: Vec, + digests: Digest, + ) -> Result, sp_blockchain::Error> { + // Although the domain block intuitively ought to use the same fork choice + // from the corresponding consensus block, it's fine to forcibly always use + // the longest chain for simplicity as we manually build the domain branches + // by following the consensus chain branches. Due to the possibility of domain + // branch transitioning to a lower fork caused by the change that a consensus block + // can possibility produce no domain block, it's important to note that now we + // need to ensure the consensus block built from the latest consensus block is the + // new best domain block after processing each imported consensus block. + let fork_choice = ForkChoiceStrategy::LongestChain; + + let (header_hash, header_number, state_root) = self + .build_and_import_block(parent_hash, parent_number, extrinsics, fork_choice, digests) + .await?; + + tracing::debug!( + "Built new domain block #{header_number},{header_hash} from \ + consensus block #{consensus_block_number},{consensus_block_hash} \ + on top of parent domain block #{parent_number},{parent_hash}" + ); + + if let Some(to_finalize_block_number) = consensus_block_number + .into() + .checked_sub(&self.domain_confirmation_depth) + { + if to_finalize_block_number > self.client.info().finalized_number { + let to_finalize_block_hash = + self.client.hash(to_finalize_block_number)?.ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Header for #{to_finalize_block_number} not found" + )) + })?; + self.client + .finalize_block(to_finalize_block_hash, None, true)?; + tracing::debug!("Successfully finalized block: #{to_finalize_block_number},{to_finalize_block_hash}"); + } + } + + let mut roots = self.client.runtime_api().intermediate_roots(header_hash)?; + + let encoded_state_root = state_root + .encode() + .try_into() + .expect("State root uses the same Block hash type which must fit into [u8; 32]; qed"); + + roots.push(encoded_state_root); + + let trace_root = MerkleTree::from_leaves(&roots).root().ok_or_else(|| { + sp_blockchain::Error::Application(Box::from("Failed to get merkle root of trace")) + })?; + let trace: Vec<::Hash> = roots + .into_iter() + .map(|r| { + Block::Hash::decode(&mut r.as_slice()) + .expect("Storage root uses the same Block hash type; qed") + }) + .collect(); + + tracing::trace!( + ?trace, + ?trace_root, + "Trace root calculated for #{header_number},{header_hash}" + ); + + let parent_receipt = if parent_number.is_zero() { + let genesis_hash = self.client.info().genesis_hash; + let genesis_header = self.client.header(genesis_hash)?.ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Domain block header for #{genesis_hash:?} not found", + )) + })?; + ExecutionReceipt::genesis( + self.consensus_client.info().genesis_hash, + *genesis_header.state_root(), + ) + } else { + crate::aux_schema::load_execution_receipt_by_domain_hash::<_, Block, CBlock>( + &*self.client, + parent_hash, + )? + .ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Receipt of domain block #{parent_number},{parent_hash} not found" + )) + })? + }; + + let execution_receipt = ExecutionReceipt { + domain_block_number: header_number, + domain_block_hash: header_hash, + parent_domain_block_receipt_hash: parent_receipt.hash(), + consensus_block_number, + consensus_block_hash, + invalid_bundles, + block_extrinsics_roots: bundle_extrinsics_roots, + final_state_root: state_root, + execution_trace: trace, + execution_trace_root: sp_core::H256(trace_root), + // TODO: set proper value + total_rewards: Default::default(), + }; + + Ok(DomainBlockResult { + header_hash, + header_number, + execution_receipt, + }) + } + + async fn build_and_import_block( + &self, + parent_hash: Block::Hash, + parent_number: NumberFor, + extrinsics: Vec, + fork_choice: ForkChoiceStrategy, + digests: Digest, + ) -> Result<(Block::Hash, NumberFor, Block::Hash), sp_blockchain::Error> { + let block_builder = BlockBuilder::new( + &*self.client, + parent_hash, + parent_number, + RecordProof::No, + digests, + &*self.backend, + extrinsics, + )?; + + let BuiltBlock { + block, + storage_changes, + proof: _, + } = block_builder.build()?; + + let (header, body) = block.deconstruct(); + let state_root = *header.state_root(); + let header_hash = header.hash(); + let header_number = *header.number(); + + let block_import_params = { + let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); + import_block.body = Some(body); + import_block.state_action = + StateAction::ApplyChanges(StorageChanges::Changes(storage_changes)); + import_block.fork_choice = Some(fork_choice); + import_block + }; + self.import_domain_block(block_import_params).await?; + + Ok((header_hash, header_number, state_root)) + } + + pub(crate) async fn import_domain_block( + &self, + block_import_params: BlockImportParams>, + ) -> Result<(), sp_blockchain::Error> { + let (header_number, header_hash, parent_hash) = ( + *block_import_params.header.number(), + block_import_params.header.hash(), + *block_import_params.header.parent_hash(), + ); + + let import_result = (&*self.block_import) + .import_block(block_import_params) + .await?; + + match import_result { + ImportResult::Imported(..) => {} + ImportResult::AlreadyInChain => { + tracing::debug!("Block #{header_number},{header_hash:?} is already in chain"); + } + ImportResult::KnownBad => { + return Err(sp_consensus::Error::ClientImport(format!( + "Bad block #{header_number}({header_hash:?})" + )) + .into()); + } + ImportResult::UnknownParent => { + return Err(sp_consensus::Error::ClientImport(format!( + "Block #{header_number}({header_hash:?}) has an unknown parent: {parent_hash:?}" + )) + .into()); + } + ImportResult::MissingState => { + return Err(sp_consensus::Error::ClientImport(format!( + "Parent state of block #{header_number}({header_hash:?}) is missing, parent: {parent_hash:?}" + )) + .into()); + } + } + + Ok(()) + } + + pub(crate) fn on_consensus_block_processed( + &self, + consensus_block_hash: CBlock::Hash, + domain_block_result: Option>, + head_receipt_number: NumberFor, + ) -> sp_blockchain::Result<()> { + let domain_hash = match domain_block_result { + Some(DomainBlockResult { + header_hash, + header_number: _, + execution_receipt, + }) => { + crate::aux_schema::write_execution_receipt::<_, Block, CBlock>( + &*self.client, + head_receipt_number, + &execution_receipt, + )?; + + // Notify the imported domain block when the receipt processing is done. + let domain_import_notification = DomainBlockImportNotification { + domain_block_hash: header_hash, + consensus_block_hash, + }; + + self.import_notification_sinks.lock().retain(|sink| { + sink.unbounded_send(domain_import_notification.clone()) + .is_ok() + }); + + header_hash + } + None => { + // No new domain block produced, thus this consensus block should map to the same + // domain block as its parent block + let consensus_header = self + .consensus_client + .header(consensus_block_hash)? + .ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Header for consensus block {consensus_block_hash:?} not found" + )) + })?; + if *consensus_header.number() > self.domain_created_at + One::one() { + let consensus_parent_hash = consensus_header.parent_hash(); + crate::aux_schema::best_domain_hash_for(&*self.client, consensus_parent_hash)? + .ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Domain hash for consensus block {consensus_parent_hash:?} not found", + )) + })? + } else { + self.client.info().genesis_hash + } + } + }; + + crate::aux_schema::track_domain_hash_and_consensus_hash( + &*self.client, + domain_hash, + consensus_block_hash, + )?; + + Ok(()) + } +} + +pub(crate) struct ReceiptsChecker< + Block, + Client, + CBlock, + CClient, + Backend, + E, + ParentChain, + ParentChainBlock, +> { + pub(crate) domain_id: DomainId, + pub(crate) client: Arc, + pub(crate) consensus_client: Arc, + pub(crate) consensus_network_sync_oracle: Arc, + pub(crate) fraud_proof_generator: + FraudProofGenerator, + pub(crate) parent_chain: ParentChain, + pub(crate) _phantom: std::marker::PhantomData, +} + +impl Clone + for ReceiptsChecker +where + Block: BlockT, + ParentChain: Clone, +{ + fn clone(&self) -> Self { + Self { + domain_id: self.domain_id, + client: self.client.clone(), + consensus_client: self.consensus_client.clone(), + consensus_network_sync_oracle: self.consensus_network_sync_oracle.clone(), + fraud_proof_generator: self.fraud_proof_generator.clone(), + parent_chain: self.parent_chain.clone(), + _phantom: self._phantom, + } + } +} + +impl + ReceiptsChecker +where + Block: BlockT, + CBlock: BlockT, + ParentChainBlock: BlockT, + NumberFor: Into>, + Client: + HeaderBackend + BlockBackend + AuxStore + ProvideRuntimeApi + 'static, + Client::Api: DomainCoreApi + + sp_block_builder::BlockBuilder + + sp_api::ApiExt>, + CClient: HeaderBackend + BlockBackend + ProvideRuntimeApi + 'static, + CClient::Api: DomainsApi, Block::Hash>, + Backend: sc_client_api::Backend + 'static, + TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, + E: CodeExecutor, + ParentChain: ParentChainInterface, +{ + pub(crate) fn check_state_transition( + &self, + parent_chain_block_hash: ParentChainBlock::Hash, + ) -> sp_blockchain::Result<()> { + let extrinsics = self.parent_chain.block_body(parent_chain_block_hash)?; + + let receipts = self + .parent_chain + .extract_receipts(parent_chain_block_hash, extrinsics.clone())?; + + let fraud_proofs = self + .parent_chain + .extract_fraud_proofs(parent_chain_block_hash, extrinsics)?; + + self.check_receipts(receipts, fraud_proofs)?; + + if self.consensus_network_sync_oracle.is_major_syncing() { + tracing::debug!( + "Skip reporting unconfirmed bad receipt as the consensus node is still major syncing..." + ); + return Ok(()); + } + + // Submit fraud proof for the first unconfirmed incorrent ER. + let oldest_receipt_number = self + .parent_chain + .oldest_receipt_number(parent_chain_block_hash)?; + crate::aux_schema::prune_expired_bad_receipts(&*self.client, oldest_receipt_number)?; + + if let Some(fraud_proof) = self.create_fraud_proof_for_first_unconfirmed_bad_receipt()? { + self.parent_chain.submit_fraud_proof_unsigned(fraud_proof)?; + } + + Ok(()) + } + + fn check_receipts( + &self, + receipts: Vec>, + fraud_proofs: Vec, ParentChainBlock::Hash>>, + ) -> Result<(), sp_blockchain::Error> { + let mut bad_receipts_to_write = vec![]; + + for execution_receipt in receipts.iter() { + // Skip check for genesis receipt as it is generated on the domain instantiation by + // the consensus chain. + if execution_receipt.domain_block_number.is_zero() { + continue; + } + + let consensus_block_hash = execution_receipt.consensus_block_hash; + + let local_receipt = crate::aux_schema::load_execution_receipt::< + _, + Block, + ParentChainBlock, + >(&*self.client, consensus_block_hash)? + .ok_or(sp_blockchain::Error::Backend(format!( + "Receipt for consensus block #{},{consensus_block_hash} not found", + execution_receipt.consensus_block_number + )))?; + + if let Some(trace_mismatch_index) = find_trace_mismatch( + &local_receipt.execution_trace, + &execution_receipt.execution_trace, + ) { + bad_receipts_to_write.push(( + execution_receipt.consensus_block_number, + execution_receipt.hash(), + (trace_mismatch_index, consensus_block_hash), + )); + } + } + + let bad_receipts_to_delete = fraud_proofs + .into_iter() + .filter_map(|fraud_proof| { + match fraud_proof { + FraudProof::InvalidStateTransition(fraud_proof) => { + let bad_receipt_number = fraud_proof.parent_number + 1; + let bad_receipt_hash = fraud_proof.bad_receipt_hash; + + // In order to not delete a receipt which was just inserted, accumulate the write&delete operations + // in case the bad receipt and corresponding farud proof are included in the same block. + if let Some(index) = bad_receipts_to_write + .iter() + .map(|(_, receipt_hash, _)| receipt_hash) + .position(|v| *v == bad_receipt_hash) + { + bad_receipts_to_write.swap_remove(index); + None + } else { + Some((bad_receipt_number, bad_receipt_hash)) + } + } + _ => None, + } + }) + .collect::>(); + + for (bad_receipt_number, bad_receipt_hash, mismatch_info) in bad_receipts_to_write { + crate::aux_schema::write_bad_receipt::<_, ParentChainBlock>( + &*self.client, + bad_receipt_number, + bad_receipt_hash, + mismatch_info, + )?; + } + + for (bad_receipt_number, bad_receipt_hash) in bad_receipts_to_delete { + if let Err(e) = crate::aux_schema::delete_bad_receipt( + &*self.client, + bad_receipt_number, + bad_receipt_hash, + ) { + tracing::error!( + error = ?e, + ?bad_receipt_number, + ?bad_receipt_hash, + "Failed to delete bad receipt" + ); + } + } + + Ok(()) + } + + fn create_fraud_proof_for_first_unconfirmed_bad_receipt( + &self, + ) -> sp_blockchain::Result< + Option, ParentChainBlock::Hash>>, + > { + if let Some((bad_receipt_hash, trace_mismatch_index, consensus_block_hash)) = + crate::aux_schema::find_first_unconfirmed_bad_receipt_info::<_, Block, CBlock, _>( + &*self.client, + |height| { + self.consensus_client.hash(height)?.ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Consensus block hash for #{height} not found", + )) + }) + }, + )? + { + let local_receipt = crate::aux_schema::load_execution_receipt::<_, Block, CBlock>( + &*self.client, + consensus_block_hash, + )? + .ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Receipt for consensus block {consensus_block_hash} not found" + )) + })?; + + let fraud_proof = self + .fraud_proof_generator + .generate_invalid_state_transition_proof::( + self.domain_id, + trace_mismatch_index, + &local_receipt, + bad_receipt_hash, + ) + .map_err(|err| { + sp_blockchain::Error::Application(Box::from(format!( + "Failed to generate fraud proof: {err}" + ))) + })?; + + return Ok(Some(fraud_proof)); + } + + Ok(None) + } +} diff --git a/domains/client/domain-executor/src/domain_bundle_producer.rs b/domains/client/domain-operator/src/domain_bundle_producer.rs similarity index 53% rename from domains/client/domain-executor/src/domain_bundle_producer.rs rename to domains/client/domain-operator/src/domain_bundle_producer.rs index 1f6b7027b48..51d4a5270dd 100644 --- a/domains/client/domain-executor/src/domain_bundle_producer.rs +++ b/domains/client/domain-operator/src/domain_bundle_producer.rs @@ -1,165 +1,137 @@ -use crate::bundle_election_solver::BundleElectionSolver; +use crate::bundle_producer_election_solver::BundleProducerElectionSolver; use crate::domain_bundle_proposer::DomainBundleProposer; use crate::parent_chain::ParentChainInterface; -use crate::sortition::TransactionSelector; -use crate::utils::ExecutorSlotInfo; +use crate::utils::OperatorSlotInfo; use crate::BundleSender; use codec::Decode; use domain_runtime_primitives::DomainCoreApi; -use sc_client_api::{AuxStore, BlockBackend, ProofProvider}; +use sc_client_api::{AuxStore, BlockBackend}; use sp_api::{NumberFor, ProvideRuntimeApi}; use sp_block_builder::BlockBuilder; -use sp_blockchain::HeaderBackend; -use sp_domains::{Bundle, DomainId, ExecutorPublicKey, ExecutorSignature, SealedBundleHeader}; +use sp_blockchain::{HashAndNumber, HeaderBackend}; +use sp_domains::{ + Bundle, BundleProducerElectionApi, DomainId, DomainsApi, OperatorPublicKey, OperatorSignature, + SealedBundleHeader, +}; use sp_keystore::KeystorePtr; use sp_runtime::traits::{Block as BlockT, One, Saturating, Zero}; use sp_runtime::RuntimeAppPublic; use std::marker::PhantomData; use std::sync::Arc; -use subspace_core_primitives::U256; -use system_runtime_primitives::SystemDomainApi; +use subspace_runtime_primitives::Balance; -type OpaqueBundle = - sp_domains::OpaqueBundle, ::Hash, ::Hash>; +type OpaqueBundle = sp_domains::OpaqueBundle< + NumberFor, + ::Hash, + NumberFor, + ::Hash, + Balance, +>; pub(super) struct DomainBundleProducer< Block, - SBlock, - PBlock, + CBlock, ParentChainBlock, Client, - SClient, - PClient, + CClient, ParentChain, TransactionPool, > where Block: BlockT, - SBlock: BlockT, - PBlock: BlockT, + CBlock: BlockT, { domain_id: DomainId, - system_domain_client: Arc, + consensus_client: Arc, client: Arc, parent_chain: ParentChain, - bundle_sender: Arc>, + bundle_sender: Arc>, keystore: KeystorePtr, - bundle_election_solver: BundleElectionSolver, - domain_bundle_proposer: DomainBundleProposer, + bundle_producer_election_solver: BundleProducerElectionSolver, + domain_bundle_proposer: DomainBundleProposer, _phantom_data: PhantomData, } -impl< - Block, - SBlock, - PBlock, - ParentChainBlock, - Client, - SClient, - PClient, - ParentChain, - TransactionPool, - > Clone +impl Clone for DomainBundleProducer< Block, - SBlock, - PBlock, + CBlock, ParentChainBlock, Client, - SClient, - PClient, + CClient, ParentChain, TransactionPool, > where Block: BlockT, - SBlock: BlockT, - PBlock: BlockT, + CBlock: BlockT, ParentChain: Clone, { fn clone(&self) -> Self { Self { domain_id: self.domain_id, - system_domain_client: self.system_domain_client.clone(), + consensus_client: self.consensus_client.clone(), client: self.client.clone(), parent_chain: self.parent_chain.clone(), bundle_sender: self.bundle_sender.clone(), keystore: self.keystore.clone(), - bundle_election_solver: self.bundle_election_solver.clone(), + bundle_producer_election_solver: self.bundle_producer_election_solver.clone(), domain_bundle_proposer: self.domain_bundle_proposer.clone(), _phantom_data: self._phantom_data, } } } -impl< - Block, - SBlock, - PBlock, - ParentChainBlock, - Client, - SClient, - PClient, - ParentChain, - TransactionPool, - > +impl DomainBundleProducer< Block, - SBlock, - PBlock, + CBlock, ParentChainBlock, Client, - SClient, - PClient, + CClient, ParentChain, TransactionPool, > where Block: BlockT, - SBlock: BlockT, - PBlock: BlockT, + CBlock: BlockT, ParentChainBlock: BlockT, - NumberFor: Into>, + NumberFor: Into>, NumberFor: Into>, Client: HeaderBackend + BlockBackend + AuxStore + ProvideRuntimeApi, Client::Api: BlockBuilder + DomainCoreApi, - SClient: HeaderBackend - + BlockBackend - + ProvideRuntimeApi - + ProofProvider, - SClient::Api: DomainCoreApi - + SystemDomainApi, PBlock::Hash, Block::Hash>, - PClient: HeaderBackend, + CClient: HeaderBackend + ProvideRuntimeApi, + CClient::Api: DomainsApi, Block::Hash> + + BundleProducerElectionApi, ParentChain: ParentChainInterface + Clone, TransactionPool: sc_transaction_pool_api::TransactionPool, { - #[allow(clippy::too_many_arguments)] pub(super) fn new( domain_id: DomainId, - system_domain_client: Arc, + consensus_client: Arc, client: Arc, parent_chain: ParentChain, domain_bundle_proposer: DomainBundleProposer< Block, Client, - PBlock, - PClient, + CBlock, + CClient, TransactionPool, >, - bundle_sender: Arc>, + bundle_sender: Arc>, keystore: KeystorePtr, ) -> Self { - let bundle_election_solver = BundleElectionSolver::::new( - system_domain_client.clone(), + let bundle_producer_election_solver = BundleProducerElectionSolver::::new( keystore.clone(), + consensus_client.clone(), ); Self { domain_id, - system_domain_client, + consensus_client, client, parent_chain, bundle_sender, keystore, - bundle_election_solver, + bundle_producer_election_solver, domain_bundle_proposer, _phantom_data: PhantomData, } @@ -167,21 +139,19 @@ where pub(super) async fn produce_bundle( self, - primary_info: (PBlock::Hash, NumberFor), - slot_info: ExecutorSlotInfo, - ) -> sp_blockchain::Result>> { - let ExecutorSlotInfo { + consensus_block_info: HashAndNumber, + slot_info: OperatorSlotInfo, + ) -> sp_blockchain::Result>> { + let OperatorSlotInfo { slot, - global_challenge, + global_randomness, } = slot_info; - let best_hash = self.system_domain_client.info().best_hash; - let best_number = self.system_domain_client.info().best_number; - - let best_receipt_is_written = crate::aux_schema::primary_hash_for::<_, _, PBlock::Hash>( - &*self.client, - self.client.info().best_hash, - )? + let best_receipt_is_written = crate::aux_schema::consensus_block_hash_for::< + _, + _, + CBlock::Hash, + >(&*self.client, self.client.info().best_hash)? .is_some(); // TODO: remove once the receipt generation can be done before the domain block is @@ -198,21 +168,15 @@ where }; let should_skip_slot = { - let primary_block_number = primary_info.1; let head_receipt_number = self .parent_chain .head_receipt_number(self.parent_chain.best_hash())?; - // Receipt for block #0 does not exist, simply skip slot here to bypasss this case and - // make the code cleaner - primary_block_number.is_zero() - // Executor hasn't able to finish the processing of domain block #1. - || domain_best_number.is_zero() - // Executor is lagging behind the receipt chain on its parent chain as another executor - // already processed a block higher than the local best and submitted the receipt to - // the parent chain, we ought to catch up with the primary block processing before - // producing new bundle. - || domain_best_number <= head_receipt_number + // Operator is lagging behind the receipt chain on its parent chain as another operator + // already processed a block higher than the local best and submitted the receipt to + // the parent chain, we ought to catch up with the consensus block processing before + // producing new bundle. + !domain_best_number.is_zero() && domain_best_number <= head_receipt_number }; if should_skip_slot { @@ -223,32 +187,28 @@ where return Ok(None); } - if let Some(bundle_solution) = self - .bundle_election_solver - .solve_bundle_election_challenge( - best_hash, - best_number, + if let Some((proof_of_election, operator_signing_key)) = + self.bundle_producer_election_solver.solve_challenge( + slot, + consensus_block_info.hash, self.domain_id, - global_challenge, + global_randomness, )? { tracing::info!("📦 Claimed bundle at slot {slot}"); - let proof_of_election = bundle_solution.proof_of_election(); - let bundle_author = proof_of_election.executor_public_key.clone(); - let tx_selector = TransactionSelector::new( - U256::from_be_bytes(proof_of_election.vrf_hash()), - self.client.clone(), - ); - let (bundle_header, receipt, extrinsics) = self + let tx_range = self + .consensus_client + .runtime_api() + .domain_tx_range(consensus_block_info.hash, self.domain_id) + .map_err(|error| { + sp_blockchain::Error::Application(Box::from(format!( + "Error getting tx range: {error}" + ))) + })?; + let (bundle_header, extrinsics) = self .domain_bundle_proposer - .propose_bundle_at( - bundle_solution, - slot, - primary_info, - self.parent_chain.clone(), - tx_selector, - ) + .propose_bundle_at(proof_of_election, self.parent_chain.clone(), tx_range) .await?; let to_sign = bundle_header.hash(); @@ -256,8 +216,8 @@ where let signature = self .keystore .sr25519_sign( - ExecutorPublicKey::ID, - bundle_author.as_ref(), + OperatorPublicKey::ID, + operator_signing_key.as_ref(), to_sign.as_ref(), ) .map_err(|error| { @@ -271,7 +231,7 @@ where )) })?; - let signature = ExecutorSignature::decode(&mut signature.as_ref()).map_err(|err| { + let signature = OperatorSignature::decode(&mut signature.as_ref()).map_err(|err| { sp_blockchain::Error::Application(Box::from(format!( "Failed to decode the signature of bundle: {err}" ))) @@ -279,7 +239,6 @@ where let bundle = Bundle { sealed_header: SealedBundleHeader::new(bundle_header, signature), - receipt, extrinsics, }; diff --git a/domains/client/domain-operator/src/domain_bundle_proposer.rs b/domains/client/domain-operator/src/domain_bundle_proposer.rs new file mode 100644 index 00000000000..fe3ab649ac3 --- /dev/null +++ b/domains/client/domain-operator/src/domain_bundle_proposer.rs @@ -0,0 +1,242 @@ +use crate::parent_chain::ParentChainInterface; +use crate::ExecutionReceiptFor; +use codec::Encode; +use domain_runtime_primitives::DomainCoreApi; +use futures::{select, FutureExt}; +use sc_client_api::{AuxStore, BlockBackend}; +use sc_transaction_pool_api::InPoolTransaction; +use sp_api::{HeaderT, NumberFor, ProvideRuntimeApi}; +use sp_block_builder::BlockBuilder; +use sp_blockchain::HeaderBackend; +use sp_domains::{BundleHeader, ExecutionReceipt, ProofOfElection}; +use sp_runtime::traits::{BlakeTwo256, Block as BlockT, Hash as HashT, One, Saturating, Zero}; +use sp_weights::Weight; +use std::marker::PhantomData; +use std::sync::Arc; +use std::time; +use subspace_core_primitives::U256; +use subspace_runtime_primitives::Balance; + +pub(super) struct DomainBundleProposer { + client: Arc, + consensus_client: Arc, + transaction_pool: Arc, + _phantom_data: PhantomData<(Block, CBlock)>, +} + +impl Clone + for DomainBundleProposer +{ + fn clone(&self) -> Self { + Self { + client: self.client.clone(), + consensus_client: self.consensus_client.clone(), + transaction_pool: self.transaction_pool.clone(), + _phantom_data: self._phantom_data, + } + } +} + +pub(super) type ProposeBundleOutput = ( + BundleHeader< + NumberFor, + ::Hash, + NumberFor, + ::Hash, + Balance, + >, + Vec<::Extrinsic>, +); + +impl + DomainBundleProposer +where + Block: BlockT, + CBlock: BlockT, + NumberFor: Into>, + Client: HeaderBackend + BlockBackend + AuxStore + ProvideRuntimeApi, + Client::Api: BlockBuilder + DomainCoreApi, + CClient: HeaderBackend, + TransactionPool: sc_transaction_pool_api::TransactionPool, +{ + pub(crate) fn new( + client: Arc, + consensus_client: Arc, + transaction_pool: Arc, + ) -> Self { + Self { + client, + consensus_client, + transaction_pool, + _phantom_data: PhantomData, + } + } + + pub(crate) async fn propose_bundle_at( + &self, + proof_of_election: ProofOfElection, + parent_chain: ParentChain, + tx_range: U256, + ) -> sp_blockchain::Result> + where + ParentChainBlock: BlockT, + ParentChain: ParentChainInterface, + { + let parent_number = self.client.info().best_number; + let parent_hash = self.client.info().best_hash; + + let mut t1 = self.transaction_pool.ready_at(parent_number).fuse(); + // TODO: proper timeout + let mut t2 = futures_timer::Delay::new(time::Duration::from_micros(100)).fuse(); + + let pending_iterator = select! { + res = t1 => res, + _ = t2 => { + tracing::warn!( + "Timeout fired waiting for transaction pool at #{parent_number},{parent_hash}, \ + proceeding with bundle production." + ); + self.transaction_pool.ready() + } + }; + + let bundle_vrf_hash = U256::from_be_bytes(proof_of_election.vrf_hash()); + let domain_block_limit = parent_chain.domain_block_limit(parent_chain.best_hash())?; + let mut extrinsics = Vec::new(); + let mut estimated_bundle_weight = Weight::default(); + let mut bundle_size = 0u32; + for pending_tx in pending_iterator { + let pending_tx_data = pending_tx.data(); + + let is_within_tx_range = self + .client + .runtime_api() + .is_within_tx_range(parent_hash, pending_tx_data, &bundle_vrf_hash, &tx_range) + .map_err(|err| { + tracing::error!( + ?err, + ?pending_tx_data, + "Error occurred in locating the tx range" + ); + }) + .unwrap_or(false); + + if is_within_tx_range { + let tx_weight = self + .client + .runtime_api() + .extrinsic_weight(parent_hash, pending_tx_data) + .map_err(|error| { + sp_blockchain::Error::Application(Box::from(format!( + "Error getting extrinsic weight: {error}" + ))) + })?; + let next_estimated_bundle_weight = + estimated_bundle_weight.saturating_add(tx_weight); + if next_estimated_bundle_weight.any_gt(domain_block_limit.max_block_weight) { + break; + } + + let next_bundle_size = bundle_size + pending_tx_data.encoded_size() as u32; + if next_bundle_size > domain_block_limit.max_block_size { + break; + } + + estimated_bundle_weight = next_estimated_bundle_weight; + bundle_size = next_bundle_size; + extrinsics.push(pending_tx_data.clone()); + } + } + + let extrinsics_root = BlakeTwo256::ordered_trie_root( + extrinsics.iter().map(|xt| xt.encode()).collect(), + sp_core::storage::StateVersion::V1, + ); + + let receipt = self.load_bundle_receipt(parent_number, parent_hash, parent_chain)?; + + let header = BundleHeader { + proof_of_election, + receipt, + bundle_size, + estimated_bundle_weight, + bundle_extrinsics_root: extrinsics_root, + }; + + Ok((header, extrinsics)) + } + + /// Returns the receipt in the next domain bundle. + fn load_bundle_receipt( + &self, + header_number: NumberFor, + header_hash: Block::Hash, + parent_chain: ParentChain, + ) -> sp_blockchain::Result> + where + ParentChainBlock: BlockT, + ParentChain: ParentChainInterface, + { + let parent_chain_block_hash = parent_chain.best_hash(); + let head_receipt_number = parent_chain.head_receipt_number(parent_chain_block_hash)?; + let max_drift = parent_chain.block_tree_pruning_depth(parent_chain_block_hash)?; + + tracing::trace!( + ?header_number, + ?head_receipt_number, + ?max_drift, + "Collecting receipts at {parent_chain_block_hash:?}" + ); + + let header_block_receipt_is_written = crate::aux_schema::consensus_block_hash_for::< + _, + _, + CBlock::Hash, + >(&*self.client, header_hash)? + .is_some(); + + // TODO: remove once the receipt generation can be done before the domain block is + // committed to the database, in other words, only when the receipt of block N+1 has + // been generated can the `client.info().best_number` be updated from N to N+1. + // + // This requires: + // 1. Reimplement `runtime_api.intermediate_roots()` on the client side. + // 2. Add a hook before the upstream `client.commit_operation(op)`. + let available_best_receipt_number = if header_block_receipt_is_written { + header_number + } else { + header_number.saturating_sub(One::one()) + }; + + let receipt_number = (head_receipt_number + One::one()).min(available_best_receipt_number); + + if receipt_number.is_zero() { + let genesis_hash = self.client.info().genesis_hash; + let genesis_header = self.client.header(genesis_hash)?.ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Domain block header for #{genesis_hash:?} not found", + )) + })?; + return Ok(ExecutionReceipt::genesis( + self.consensus_client.info().genesis_hash, + *genesis_header.state_root(), + )); + } + + let domain_hash = self.client.hash(receipt_number)?.ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Domain block hash for #{receipt_number:?} not found" + )) + })?; + + crate::aux_schema::load_execution_receipt_by_domain_hash::<_, Block, CBlock>( + &*self.client, + domain_hash, + )? + .ok_or_else(|| { + sp_blockchain::Error::Backend(format!( + "Receipt of domain block #{receipt_number},{domain_hash} not found" + )) + }) + } +} diff --git a/domains/client/domain-executor/src/domain_worker.rs b/domains/client/domain-operator/src/domain_worker.rs similarity index 62% rename from domains/client/domain-executor/src/domain_worker.rs rename to domains/client/domain-operator/src/domain_worker.rs index b5ad8c36adb..bc215e31fd5 100644 --- a/domains/client/domain-executor/src/domain_worker.rs +++ b/domains/client/domain-operator/src/domain_worker.rs @@ -1,43 +1,48 @@ -use crate::utils::{to_number_primitive, BlockInfo, ExecutorSlotInfo}; +//! Shared domain worker functions. + +use crate::utils::{to_number_primitive, BlockInfo, OperatorSlotInfo}; use futures::channel::mpsc; use futures::{SinkExt, Stream, StreamExt}; use sc_client_api::{BlockBackend, BlockImportNotification, BlockchainEvents}; use sp_api::{ApiError, BlockT, ProvideRuntimeApi}; -use sp_blockchain::HeaderBackend; +use sp_blockchain::{HashAndNumber, HeaderBackend}; use sp_core::traits::SpawnEssentialNamed; -use sp_domains::{ExecutorApi, OpaqueBundle}; +use sp_domains::{DomainsApi, OpaqueBundle}; use sp_runtime::traits::{Header as HeaderT, NumberFor, One, Saturating}; use std::collections::hash_map::Entry; use std::collections::HashMap; use std::future::Future; use std::pin::Pin; +use subspace_runtime_primitives::Balance; + +type OpaqueBundleFor = OpaqueBundle< + NumberFor, + ::Hash, + NumberFor, + ::Hash, + Balance, +>; -pub(crate) async fn handle_slot_notifications( - primary_chain_client: &PClient, +pub(crate) async fn handle_slot_notifications( + consensus_client: &CClient, bundler: BundlerFn, - mut slots: impl Stream>)> + Unpin, + mut slots: impl Stream>)> + Unpin, ) where Block: BlockT, - PBlock: BlockT, - PClient: HeaderBackend + ProvideRuntimeApi, - PClient::Api: ExecutorApi, + CBlock: BlockT, + CClient: HeaderBackend + ProvideRuntimeApi, + CClient::Api: DomainsApi, Block::Hash>, BundlerFn: Fn( - (PBlock::Hash, NumberFor), - ExecutorSlotInfo, - ) -> Pin< - Box< - dyn Future< - Output = Option, PBlock::Hash, Block::Hash>>, - > + Send, - >, - > + Send + HashAndNumber, + OperatorSlotInfo, + ) -> Pin>> + Send>> + + Send + Sync, { - while let Some((executor_slot_info, slot_acknowledgement_sender)) = slots.next().await { - let slot = executor_slot_info.slot; + while let Some((operator_slot_info, slot_acknowledgement_sender)) = slots.next().await { + let slot = operator_slot_info.slot; if let Err(error) = - on_new_slot::(primary_chain_client, &bundler, executor_slot_info) - .await + on_new_slot::(consensus_client, &bundler, operator_slot_info).await { tracing::error!( ?error, @@ -54,48 +59,48 @@ pub(crate) async fn handle_slot_notifications #[allow(clippy::too_many_arguments)] pub(crate) async fn handle_block_import_notifications< Block, - PBlock, - PClient, + CBlock, + CClient, ProcessorFn, BlocksImporting, BlocksImported, >( spawn_essential: Box, - primary_chain_client: &PClient, + consensus_client: &CClient, best_domain_number: NumberFor, processor: ProcessorFn, - mut leaves: Vec<(PBlock::Hash, NumberFor)>, + mut leaves: Vec<(CBlock::Hash, NumberFor, bool)>, mut blocks_importing: BlocksImporting, mut blocks_imported: BlocksImported, - primary_block_import_throttling_buffer_size: u32, + consensus_block_import_throttling_buffer_size: u32, ) where Block: BlockT, - PBlock: BlockT, - PClient: HeaderBackend - + BlockBackend - + ProvideRuntimeApi - + BlockchainEvents, - PClient::Api: ExecutorApi, + CBlock: BlockT, + CClient: HeaderBackend + + BlockBackend + + ProvideRuntimeApi + + BlockchainEvents, + CClient::Api: DomainsApi, Block::Hash>, ProcessorFn: Fn( - (PBlock::Hash, NumberFor), + (CBlock::Hash, NumberFor, bool), ) -> Pin> + Send>> + Send + Sync + 'static, - BlocksImporting: Stream, mpsc::Sender<()>)> + Unpin, - BlocksImported: Stream> + Unpin, + BlocksImporting: Stream, mpsc::Sender<()>)> + Unpin, + BlocksImported: Stream> + Unpin, { let mut active_leaves = HashMap::with_capacity(leaves.len()); let best_domain_number = to_number_primitive(best_domain_number); // Notify about active leaves on startup before starting the loop - for (hash, number) in std::mem::take(&mut leaves) { + for (hash, number, is_new_best) in std::mem::take(&mut leaves) { let _ = active_leaves.insert(hash, number); // Skip the blocks that have been processed by the execution chain. if number > best_domain_number.into() { - if let Err(error) = processor((hash, number)).await { - tracing::error!(?error, "Failed to process primary block on startup"); + if let Err(error) = processor((hash, number, is_new_best)).await { + tracing::error!(?error, "Failed to process consensus block on startup"); // Bring down the service as bundles processor is an essential task. // TODO: more graceful shutdown. return; @@ -103,26 +108,26 @@ pub(crate) async fn handle_block_import_notifications< } } - // The primary chain can be ahead of the domain by up to `block_import_throttling_buffer_size/2` + // The consensus chain can be ahead of the domain by up to `block_import_throttling_buffer_size/2` // blocks, for there are two notifications per block sent to this buffer (one will be actually // consumed by the domain processor, the other from `sc-consensus-subspace` is used to discontinue - // the primary block import in case the primary chain runs much faster than the domain.). + // the consensus block import in case the consensus chain runs much faster than the domain.). let (mut block_info_sender, mut block_info_receiver) = - mpsc::channel(primary_block_import_throttling_buffer_size as usize); + mpsc::channel(consensus_block_import_throttling_buffer_size as usize); // Run the actual processor in a dedicated task, otherwise `tokio::select!` might hang forever // when the throttling buffer is full. spawn_essential.spawn_essential_blocking( - "primary-block-processor", + "consensus-block-processor", None, Box::pin(async move { while let Some(maybe_block_info) = block_info_receiver.next().await { if let Some(block_info) = maybe_block_info { if let Err(error) = - block_imported::(&processor, &mut active_leaves, block_info) + block_imported::(&processor, &mut active_leaves, block_info) .await { - tracing::error!(?error, "Failed to process primary block"); + tracing::error!(?error, "Failed to process consensus block"); // Bring down the service as bundles processor is an essential task. // TODO: more graceful shutdown. break; @@ -150,13 +155,13 @@ pub(crate) async fn handle_block_import_notifications< break; } }; - let header = match primary_chain_client.header(block_imported.hash) { + let header = match consensus_client.header(block_imported.hash) { Ok(Some(header)) => header, res => { tracing::error!( result = ?res, header = ?block_imported.header, - "Imported primary block header not found", + "Imported consensus block header not found", ); return; } @@ -165,6 +170,7 @@ pub(crate) async fn handle_block_import_notifications< hash: header.hash(), parent_hash: *header.parent_hash(), number: *header.number(), + is_new_best: block_imported.is_new_best, }; let _ = block_info_sender.feed(Some(block_info)).await; } @@ -177,7 +183,7 @@ pub(crate) async fn handle_block_import_notifications< break; } }; - // Pause the primary block import when the sink is full. + // Pause the consensus block import when the sink is full. let _ = block_info_sender.feed(None).await; let _ = acknowledgement_sender.send(()).await; } @@ -185,55 +191,56 @@ pub(crate) async fn handle_block_import_notifications< } } -async fn on_new_slot( - primary_chain_client: &PClient, +async fn on_new_slot( + consensus_client: &CClient, bundler: &BundlerFn, - executor_slot_info: ExecutorSlotInfo, + operator_slot_info: OperatorSlotInfo, ) -> Result<(), ApiError> where Block: BlockT, - PBlock: BlockT, - PClient: HeaderBackend + ProvideRuntimeApi, - PClient::Api: ExecutorApi, + CBlock: BlockT, + CClient: HeaderBackend + ProvideRuntimeApi, + CClient::Api: DomainsApi, Block::Hash>, BundlerFn: Fn( - (PBlock::Hash, NumberFor), - ExecutorSlotInfo, - ) -> Pin< - Box< - dyn Future< - Output = Option, PBlock::Hash, Block::Hash>>, - > + Send, - >, - > + Send + HashAndNumber, + OperatorSlotInfo, + ) -> Pin>> + Send>> + + Send + Sync, { - let best_hash = primary_chain_client.info().best_hash; - let best_number = primary_chain_client.info().best_number; + let best_hash = consensus_client.info().best_hash; + let best_number = consensus_client.info().best_number; + + let consensus_block_info = HashAndNumber { + number: best_number, + hash: best_hash, + }; - let opaque_bundle = match bundler((best_hash, best_number), executor_slot_info).await { + let slot = operator_slot_info.slot; + let opaque_bundle = match bundler(consensus_block_info, operator_slot_info).await { Some(opaque_bundle) => opaque_bundle, None => { - tracing::debug!("executor returned no bundle on bundling"); + tracing::debug!("No bundle produced on slot {slot}"); return Ok(()); } }; - primary_chain_client + consensus_client .runtime_api() .submit_bundle_unsigned(best_hash, opaque_bundle)?; Ok(()) } -async fn block_imported( +async fn block_imported( processor: &ProcessorFn, - active_leaves: &mut HashMap>, - block_info: BlockInfo, + active_leaves: &mut HashMap>, + block_info: BlockInfo, ) -> Result<(), ApiError> where - PBlock: BlockT, + CBlock: BlockT, ProcessorFn: Fn( - (PBlock::Hash, NumberFor), + (CBlock::Hash, NumberFor, bool), ) -> Pin> + Send>> + Send + Sync, @@ -250,7 +257,7 @@ where debug_assert_eq!(block_info.number.saturating_sub(One::one()), number); } - processor((block_info.hash, block_info.number)).await?; + processor((block_info.hash, block_info.number, block_info.is_new_best)).await?; Ok(()) } diff --git a/domains/client/domain-executor/src/system_domain_worker.rs b/domains/client/domain-operator/src/domain_worker_starter.rs similarity index 66% rename from domains/client/domain-executor/src/system_domain_worker.rs rename to domains/client/domain-operator/src/domain_worker_starter.rs index 15a91aafb5f..38f37e5a7ca 100644 --- a/domains/client/domain-executor/src/system_domain_worker.rs +++ b/domains/client/domain-operator/src/domain_worker_starter.rs @@ -14,13 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +use crate::bundle_processor::BundleProcessor; use crate::domain_bundle_producer::DomainBundleProducer; use crate::domain_worker::{handle_block_import_notifications, handle_slot_notifications}; -use crate::parent_chain::SystemDomainParentChain; -use crate::system_bundle_processor::SystemBundleProcessor; -use crate::utils::{BlockInfo, ExecutorSlotInfo}; -use crate::{ExecutorStreams, TransactionFor}; -use domain_runtime_primitives::DomainCoreApi; +use crate::parent_chain::DomainParentChain; +use crate::utils::{BlockInfo, OperatorSlotInfo}; +use crate::{NewSlotNotification, OperatorStreams, TransactionFor}; +use domain_runtime_primitives::{DomainCoreApi, InherentExtrinsicApi}; use futures::channel::mpsc; use futures::{future, FutureExt, Stream, StreamExt, TryFutureExt}; use sc_client_api::{ @@ -31,53 +31,49 @@ use sc_consensus::BlockImport; use sp_api::{BlockT, ProvideRuntimeApi}; use sp_block_builder::BlockBuilder; use sp_blockchain::{HeaderBackend, HeaderMetadata}; -use sp_consensus_slots::Slot; use sp_core::traits::{CodeExecutor, SpawnEssentialNamed}; -use sp_domains::ExecutorApi; +use sp_domains::{BundleProducerElectionApi, DomainsApi}; use sp_messenger::MessengerApi; use sp_runtime::traits::{HashFor, NumberFor}; -use sp_settlement::SettlementApi; use std::sync::Arc; -use subspace_core_primitives::Blake2b256Hash; -use system_runtime_primitives::SystemDomainApi; +use subspace_runtime_primitives::Balance; use tracing::Instrument; #[allow(clippy::type_complexity, clippy::too_many_arguments)] pub(super) async fn start_worker< Block, - PBlock, + CBlock, Client, - PClient, + CClient, TransactionPool, Backend, IBNS, CIBNS, NSNS, E, + BI, >( spawn_essential: Box, - primary_chain_client: Arc, + consensus_client: Arc, client: Arc, is_authority: bool, bundle_producer: DomainBundleProducer< Block, - Block, - PBlock, - PBlock, - Client, + CBlock, + CBlock, Client, - PClient, - SystemDomainParentChain, + CClient, + DomainParentChain, TransactionPool, >, - bundle_processor: SystemBundleProcessor, - executor_streams: ExecutorStreams, - active_leaves: Vec>, + bundle_processor: BundleProcessor, + operator_streams: OperatorStreams, + active_leaves: Vec>, ) where Block: BlockT, - PBlock: BlockT, - NumberFor: From> + Into>, - PBlock::Hash: From, + CBlock: BlockT, + NumberFor: From> + Into>, + CBlock::Hash: From, Client: HeaderBackend + BlockBackend + AuxStore @@ -87,51 +83,53 @@ pub(super) async fn start_worker< + 'static, Client::Api: DomainCoreApi + MessengerApi> - + SystemDomainApi, PBlock::Hash, Block::Hash> + + InherentExtrinsicApi + BlockBuilder + sp_api::ApiExt>, - for<'b> &'b Client: BlockImport< - Block, - Transaction = sp_api::TransactionFor, - Error = sp_consensus::Error, - >, - PClient: HeaderBackend - + HeaderMetadata - + BlockBackend - + ProvideRuntimeApi - + BlockchainEvents + CClient: HeaderBackend + + HeaderMetadata + + BlockBackend + + ProvideRuntimeApi + + BlockchainEvents + 'static, - PClient::Api: ExecutorApi + SettlementApi, + CClient::Api: DomainsApi, Block::Hash> + + BundleProducerElectionApi, TransactionPool: sc_transaction_pool_api::TransactionPool + 'static, Backend: sc_client_api::Backend + 'static, - IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, - CIBNS: Stream> + Send + 'static, - NSNS: Stream>)> + Send + 'static, - TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, + IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, + CIBNS: Stream> + Send + 'static, + NSNS: Stream + Send + 'static, E: CodeExecutor, + TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, + for<'b> &'b BI: BlockImport< + Block, + Transaction = sp_api::TransactionFor, + Error = sp_consensus::Error, + >, + BI: Send + Sync + 'static, { let span = tracing::Span::current(); - let ExecutorStreams { - primary_block_import_throttling_buffer_size, + let OperatorStreams { + consensus_block_import_throttling_buffer_size, block_importing_notification_stream, imported_block_notification_stream, new_slot_notification_stream, _phantom, - } = executor_streams; + } = operator_streams; let handle_block_import_notifications_fut = handle_block_import_notifications::( spawn_essential, - primary_chain_client.as_ref(), + consensus_client.as_ref(), client.info().best_number, { let span = span.clone(); - move |primary_info| { + move |consensus_block_info| { bundle_processor .clone() - .process_bundles(primary_info) + .process_bundles(consensus_block_info) .instrument(span.clone()) .boxed() } @@ -143,32 +141,33 @@ pub(super) async fn start_worker< hash, parent_hash: _, number, - }| (hash, number), + is_new_best, + }| (hash, number, is_new_best), ) .collect(), Box::pin(block_importing_notification_stream), Box::pin(imported_block_notification_stream), - primary_block_import_throttling_buffer_size, + consensus_block_import_throttling_buffer_size, ); - let handle_slot_notifications_fut = handle_slot_notifications::( - primary_chain_client.as_ref(), - move |primary_info, slot_info| { + let handle_slot_notifications_fut = handle_slot_notifications::( + consensus_client.as_ref(), + move |consensus_block_info, slot_info| { bundle_producer .clone() - .produce_bundle(primary_info, slot_info) + .produce_bundle(consensus_block_info.clone(), slot_info) .instrument(span.clone()) .unwrap_or_else(move |error| { - tracing::error!(?primary_info, ?error, "Error at producing bundle."); + tracing::error!(?consensus_block_info, ?error, "Error at producing bundle."); None }) .boxed() }, Box::pin(new_slot_notification_stream.map( - |(slot, global_challenge, acknowledgement_sender)| { + |(slot, global_randomness, acknowledgement_sender)| { ( - ExecutorSlotInfo { + OperatorSlotInfo { slot, - global_challenge, + global_randomness, }, acknowledgement_sender, ) diff --git a/domains/client/domain-executor/src/fraud_proof.rs b/domains/client/domain-operator/src/fraud_proof.rs similarity index 79% rename from domains/client/domain-executor/src/fraud_proof.rs rename to domains/client/domain-operator/src/fraud_proof.rs index 42aaf84fadd..8bcbb93e99a 100644 --- a/domains/client/domain-executor/src/fraud_proof.rs +++ b/domains/client/domain-operator/src/fraud_proof.rs @@ -1,5 +1,5 @@ use crate::utils::to_number_primitive; -use crate::TransactionFor; +use crate::{ExecutionReceiptFor, TransactionFor}; use codec::{Decode, Encode}; use domain_block_builder::{BlockBuilder, RecordProof}; use sc_client_api::{AuxStore, BlockBackend, StateBackendFor}; @@ -7,11 +7,10 @@ use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_core::traits::CodeExecutor; use sp_core::H256; -use sp_domain_digests::AsPredigest; use sp_domains::fraud_proof::{ExecutionPhase, FraudProof, InvalidStateTransitionProof}; -use sp_domains::{DomainId, ExecutionReceipt}; +use sp_domains::DomainId; use sp_runtime::traits::{Block as BlockT, HashFor, Header as HeaderT, NumberFor}; -use sp_runtime::{Digest, DigestItem}; +use sp_runtime::Digest; use sp_trie::StorageProof; use std::marker::PhantomData; use std::sync::Arc; @@ -32,21 +31,21 @@ pub enum FraudProofError { RuntimeApi(#[from] sp_api::ApiError), } -pub struct FraudProofGenerator { +pub struct FraudProofGenerator { client: Arc, - primary_chain_client: Arc, + consensus_client: Arc, backend: Arc, code_executor: Arc, - _phantom: PhantomData<(Block, PBlock)>, + _phantom: PhantomData<(Block, CBlock)>, } -impl Clone - for FraudProofGenerator +impl Clone + for FraudProofGenerator { fn clone(&self) -> Self { Self { client: self.client.clone(), - primary_chain_client: self.primary_chain_client.clone(), + consensus_client: self.consensus_client.clone(), backend: self.backend.clone(), code_executor: self.code_executor.clone(), _phantom: self._phantom, @@ -54,29 +53,29 @@ impl Clone } } -impl - FraudProofGenerator +impl + FraudProofGenerator where Block: BlockT, - PBlock: BlockT, + CBlock: BlockT, Client: HeaderBackend + BlockBackend + AuxStore + ProvideRuntimeApi + 'static, Client::Api: sp_block_builder::BlockBuilder + sp_api::ApiExt>, - PClient: HeaderBackend + 'static, + CClient: HeaderBackend + 'static, Backend: sc_client_api::Backend + Send + Sync + 'static, TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, E: CodeExecutor, { pub fn new( client: Arc, - primary_chain_client: Arc, + consensus_client: Arc, backend: Arc, code_executor: Arc, ) -> Self { Self { client, - primary_chain_client, + consensus_client, backend, code_executor, _phantom: Default::default(), @@ -87,14 +86,14 @@ where &self, domain_id: DomainId, local_trace_index: u32, - local_receipt: &ExecutionReceipt, PBlock::Hash, Block::Hash>, + local_receipt: &ExecutionReceiptFor, bad_receipt_hash: H256, ) -> Result, PCB::Hash>, FraudProofError> where PCB: BlockT, { - let block_hash = local_receipt.domain_hash; - let block_number = to_number_primitive(local_receipt.primary_number); + let block_hash = local_receipt.domain_block_hash; + let block_number = to_number_primitive(local_receipt.consensus_block_number); let header = self.header(block_hash)?; let parent_header = self.header(*header.parent_hash())?; @@ -109,21 +108,22 @@ where let parent_number = to_number_primitive(*parent_header.number()); - let local_root = local_receipt.trace.get(local_trace_index as usize).ok_or( - FraudProofError::InvalidTraceIndex { + let local_root = local_receipt + .execution_trace + .get(local_trace_index as usize) + .ok_or(FraudProofError::InvalidTraceIndex { index: local_trace_index as usize, - max: local_receipt.trace.len() - 1, - }, - )?; + max: local_receipt.execution_trace.len() - 1, + })?; - let primary_parent_hash = H256::decode( + let consensus_parent_hash = H256::decode( &mut self - .primary_chain_client - .header(local_receipt.primary_hash)? + .consensus_client + .header(local_receipt.consensus_block_hash)? .ok_or_else(|| { sp_blockchain::Error::Backend(format!( - "Header not found for primary {:?}", - local_receipt.primary_hash + "Header not found for consensus block {:?}", + local_receipt.consensus_block_hash )) })? .parent_hash() @@ -132,26 +132,13 @@ where ) .map_err(|_| FraudProofError::InvalidStateRootType)?; - let digest = if domain_id.is_system() { - Digest { - logs: vec![DigestItem::primary_block_info::, _>(( - block_number.into(), - local_receipt.primary_hash, - ))], - } - } else { - Default::default() - }; + let digest = Digest::default(); - // TODO: abstract the execution proof impl to be reusable in the test. let invalid_state_transition_proof = if local_trace_index == 0 { // `initialize_block` execution proof. let pre_state_root = as_h256(parent_header.state_root())?; let post_state_root = as_h256(local_root)?; - // TODO: add a test to cover the entire flow of creation and verification in the production - // environment, i.e., the generate_proof function on the executor side and the verify function - // on the verifier side. let new_header = Block::Header::new( block_number.into(), Default::default(), @@ -175,15 +162,16 @@ where domain_id, bad_receipt_hash, parent_number, - primary_parent_hash, + consensus_parent_hash, pre_state_root, post_state_root, proof, execution_phase, } - } else if local_trace_index as usize == local_receipt.trace.len() - 1 { + } else if local_trace_index as usize == local_receipt.execution_trace.len() - 1 { // `finalize_block` execution proof. - let pre_state_root = as_h256(&local_receipt.trace[local_trace_index as usize - 1])?; + let pre_state_root = + as_h256(&local_receipt.execution_trace[local_trace_index as usize - 1])?; let post_state_root = as_h256(local_root)?; let extrinsics = self.block_body(block_hash)?; let execution_phase = ExecutionPhase::FinalizeBlock { @@ -216,7 +204,7 @@ where domain_id, bad_receipt_hash, parent_number, - primary_parent_hash, + consensus_parent_hash, pre_state_root, post_state_root, proof, @@ -224,7 +212,8 @@ where } } else { // Regular extrinsic execution proof. - let pre_state_root = as_h256(&local_receipt.trace[local_trace_index as usize - 1])?; + let pre_state_root = + as_h256(&local_receipt.execution_trace[local_trace_index as usize - 1])?; let post_state_root = as_h256(local_root)?; let (proof, execution_phase) = self.create_extrinsic_execution_proof( @@ -240,7 +229,7 @@ where domain_id, bad_receipt_hash, parent_number, - primary_parent_hash, + consensus_parent_hash, pre_state_root, post_state_root, proof, diff --git a/domains/client/domain-executor/src/lib.rs b/domains/client/domain-operator/src/lib.rs similarity index 61% rename from domains/client/domain-executor/src/lib.rs rename to domains/client/domain-operator/src/lib.rs index 11f4bd8638b..6c4730b4396 100644 --- a/domains/client/domain-executor/src/lib.rs +++ b/domains/client/domain-operator/src/lib.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -//! # Domain Executor +//! # Domain Operator //! //! ## Domains //! @@ -22,37 +22,18 @@ //! framework allowing for the simple, secure and low-cost deployment of application //! specific blockchain called domain. //! -//! There are three types of domains: system domain, core domain and open domain. -//! -//! - System domain: responsible for securing and managing all the non-system domains -//! by maintaining the receipts of other domains and handling the potential execution -//! disputes using the fraud-proof mechanism. The system domain itself is secured by the -//! consensus chain. -//! - Core domain: developed and audited by Subspace team, providing some important -//! system-wide features, e.g., the payments, contracts and messages. -//! - Open domain: similar to the smart contract in Ethereum which reflects application -//! specific business logic and can be created by anyone with enough security deposits. -//! -//! All kinds of domains form the Subspace execution layer. The domains do not rely on -//! any typical blockchain consensus like PoW for producing blocks, the block production -//! of each domain is totally driven by the consensus chain which are collectively -//! maintained by Subspace farmers. Please refer to the white paper [Computation section] -//! for more in-depth description and analysis. -//! -//! ## Executors +//! ## Operators //! //! In Subspace, the farmers offering the storage resources are responsible for maintaining -//! the consensus layer, executors are a separate class of contributors in the system focusing +//! the consensus layer, operators are a separate class of contributors in the system focusing //! on the execution layer, they provide the necessary computational resources to maintain the -//! blockchain state by running domains. Some deposits as the stake are required to be an executor. -//! Every executor must run the system domain, but they can opt-in to run one or multiple -//! non-system domains by partially allocating their executor stake on the domain. +//! blockchain state by running domains. Some deposits as the stake are required to be an operator. //! -//! Specifically, executors have the responsibity of producing a [`Bundle`] which contains a -//! number of [`ExecutionReceipt`]s on each slot notified from the consensus chain. The executors +//! Specifically, operators have the responsibity of producing a [`Bundle`] which contains a +//! number of [`ExecutionReceipt`]s on each slot notified from the consensus chain. The operators //! are primarily driven by two events from the consensus chain. //! -//! - On each new slot, executors will attempt to solve a domain-specific bundle election +//! - On each new slot, operators will attempt to solve a domain-specific bundle election //! challenge derived from a global randomness provided by the consensus chain. Upon finding //! a solution to the challenge, they will start producing a bundle: they will collect a set //! of extrinsics from the transaction pool which are verified to be able to cover the transaction @@ -60,7 +41,7 @@ //! [`Bundle`] can be constructed and then be submitted to the consensus chain. The transactions //! included in each bundle are uninterpretable blob from the consensus chain's persepective. //! -//! - On each imported primary block, executors will extract all the needed bundles from it +//! - On each imported consensus block, operators will extract all the needed bundles from it //! and convert the bundles to a list of extrinsics, construct a custom [`BlockBuilder`] to //! build a domain block. The execution trace of all the extrinsics and hooks like //! `initialize_block`/`finalize_block` will be recorded during the domain block execution. @@ -68,40 +49,37 @@ //! will be generated and stored locally. //! //! The receipt of each domain block contains all the intermediate state roots during the block -//! execution, which will be gossiped in the executor network. All executors whether running as an +//! execution, which will be gossiped in the domain subnet (in future). All operators whether running as an //! authority or a full node will compute each block and generate an execution receipt independently, //! once the execution receipt received from the network does not match the one produced locally, //! a [`FraudProof`] will be generated and reported to the consensus chain accordingly. //! -//! [Computation section]: https://subspace.network/news/subspace-network-whitepaper //! [`BlockBuilder`]: ../domain_block_builder/struct.BlockBuilder.html //! [`FraudProof`]: ../sp_domains/struct.FraudProof.html #![feature(array_windows)] #![feature(const_option)] -#![feature(drain_filter)] +#![feature(extract_if)] mod aux_schema; -mod bundle_election_solver; +mod bootstrapper; +mod bundle_processor; +mod bundle_producer_election_solver; mod domain_block_processor; mod domain_bundle_producer; mod domain_bundle_proposer; mod domain_worker; +mod domain_worker_starter; mod fraud_proof; -mod gossip_message_validator; +mod operator; mod parent_chain; -mod sortition; -mod system_bundle_processor; -mod system_domain_worker; -mod system_executor; -mod system_gossip_message_validator; #[cfg(test)] mod tests; mod utils; -pub use self::parent_chain::{CoreDomainParentChain, SystemDomainParentChain}; -pub use self::system_executor::Executor as SystemExecutor; -pub use self::system_gossip_message_validator::SystemGossipMessageValidator; +pub use self::bootstrapper::{BootstrapResult, Bootstrapper}; +pub use self::operator::Operator; +pub use self::parent_chain::DomainParentChain; pub use self::utils::{DomainBlockImportNotification, DomainImportNotifications}; use crate::utils::BlockInfo; use futures::channel::mpsc; @@ -112,55 +90,65 @@ use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_consensus::{SelectChain, SyncOracle}; use sp_consensus_slots::Slot; -use sp_domains::{Bundle, ExecutionReceipt}; +use sp_domains::{Bundle, DomainId, ExecutionReceipt}; use sp_keystore::KeystorePtr; use sp_runtime::traits::{ Block as BlockT, HashFor, Header as HeaderT, NumberFor, One, Saturating, Zero, }; use std::marker::PhantomData; use std::sync::Arc; -use subspace_core_primitives::Blake2b256Hash; - -type ExecutionReceiptFor = - ExecutionReceipt, ::Hash, Hash>; +use subspace_core_primitives::Randomness; +use subspace_runtime_primitives::Balance; + +type ExecutionReceiptFor = ExecutionReceipt< + NumberFor, + ::Hash, + NumberFor, + ::Hash, + Balance, +>; type TransactionFor = <>::State as sc_client_api::backend::StateBackend< HashFor, >>::Transaction; -type BundleSender = TracingUnboundedSender< +type BundleSender = TracingUnboundedSender< Bundle< ::Extrinsic, - NumberFor, - ::Hash, + NumberFor, + ::Hash, + NumberFor, ::Hash, + Balance, >, >; -/// Notification streams from the primary chain driving the executor. -pub struct ExecutorStreams { - /// Pause the primary block import when the primary chain client +/// Notification streams from the consensus chain driving the executor. +pub struct OperatorStreams { + /// Pause the consensus block import when the consensus chain client /// runs much faster than the domain client. - pub primary_block_import_throttling_buffer_size: u32, + pub consensus_block_import_throttling_buffer_size: u32, /// Notification about to be imported. /// /// Fired before the completion of entire block import pipeline. pub block_importing_notification_stream: IBNS, - /// Primary block import notification from the client. + /// Consensus block import notification from the client. /// /// Fired after the completion of entire block import pipeline. pub imported_block_notification_stream: CIBNS, /// New slot arrives. pub new_slot_notification_stream: NSNS, - pub _phantom: PhantomData, + pub _phantom: PhantomData, } -pub struct EssentialExecutorParams< +type NewSlotNotification = (Slot, Randomness, Option>); + +pub struct OperatorParams< Block, - PBlock, + CBlock, Client, - PClient, + CClient, TransactionPool, Backend, E, @@ -170,37 +158,39 @@ pub struct EssentialExecutorParams< BI, > where Block: BlockT, - PBlock: BlockT, - IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, - CIBNS: Stream> + Send + 'static, - NSNS: Stream>)> + Send + 'static, + CBlock: BlockT, + IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, + CIBNS: Stream> + Send + 'static, + NSNS: Stream + Send + 'static, { - pub primary_chain_client: Arc, - pub primary_network_sync_oracle: Arc, + pub domain_id: DomainId, + pub domain_created_at: NumberFor, + pub consensus_client: Arc, + pub consensus_network_sync_oracle: Arc, pub client: Arc, pub transaction_pool: Arc, pub backend: Arc, pub code_executor: Arc, pub is_authority: bool, pub keystore: KeystorePtr, - pub bundle_sender: Arc>, - pub executor_streams: ExecutorStreams, + pub bundle_sender: Arc>, + pub operator_streams: OperatorStreams, pub domain_confirmation_depth: NumberFor, pub block_import: Arc, } -/// Returns the active leaves the overseer should start with. +/// Returns the active leaves the operator should start with. /// -/// The longest chain is used as the fork choice for the leaves as the primary block's fork choice -/// is only available in the imported primary block notifications. -async fn active_leaves( - client: &PClient, +/// The longest chain is used as the fork choice for the leaves as the consensus block's fork choice +/// is only available in the imported consensus block notifications. +async fn active_leaves( + client: &CClient, select_chain: &SC, -) -> Result>, sp_consensus::Error> +) -> Result>, sp_consensus::Error> where - PBlock: BlockT, - PClient: HeaderBackend + ProvideRuntimeApi + 'static, - SC: SelectChain, + CBlock: BlockT, + CClient: HeaderBackend + ProvideRuntimeApi + 'static, + SC: SelectChain, { let best_block = select_chain.best_chain().await?; @@ -229,6 +219,7 @@ where hash, parent_hash, number, + is_new_best: false, }) }) .collect::>(); @@ -240,9 +231,10 @@ where hash: best_block.hash(), parent_hash: *best_block.parent_hash(), number: *best_block.number(), + is_new_best: true, }); - /// The maximum number of active leaves we forward to the [`Overseer`] on startup. + /// The maximum number of active leaves we forward to the [`Operator`] on startup. const MAX_ACTIVE_LEAVES: usize = 4; Ok(leaves.into_iter().rev().take(MAX_ACTIVE_LEAVES).collect()) diff --git a/domains/client/domain-executor/src/system_executor.rs b/domains/client/domain-operator/src/operator.rs similarity index 59% rename from domains/client/domain-executor/src/system_executor.rs rename to domains/client/domain-operator/src/operator.rs index 6335d023454..6e0e4f81554 100644 --- a/domains/client/domain-executor/src/system_executor.rs +++ b/domains/client/domain-operator/src/operator.rs @@ -1,11 +1,13 @@ +use crate::bundle_processor::BundleProcessor; use crate::domain_block_processor::{DomainBlockProcessor, ReceiptsChecker}; use crate::domain_bundle_producer::DomainBundleProducer; use crate::domain_bundle_proposer::DomainBundleProposer; use crate::fraud_proof::FraudProofGenerator; -use crate::parent_chain::SystemDomainParentChain; -use crate::system_bundle_processor::SystemBundleProcessor; -use crate::{active_leaves, DomainImportNotifications, EssentialExecutorParams, TransactionFor}; -use domain_runtime_primitives::DomainCoreApi; +use crate::parent_chain::DomainParentChain; +use crate::{ + active_leaves, DomainImportNotifications, NewSlotNotification, OperatorParams, TransactionFor, +}; +use domain_runtime_primitives::{DomainCoreApi, InherentExtrinsicApi}; use futures::channel::mpsc; use futures::{FutureExt, Stream}; use sc_client_api::{ @@ -16,40 +18,37 @@ use sc_utils::mpsc::tracing_unbounded; use sp_api::ProvideRuntimeApi; use sp_blockchain::{HeaderBackend, HeaderMetadata}; use sp_consensus::SelectChain; -use sp_consensus_slots::Slot; use sp_core::traits::{CodeExecutor, SpawnEssentialNamed}; -use sp_domains::{DomainId, ExecutorApi}; +use sp_domains::{BundleProducerElectionApi, DomainsApi}; use sp_messenger::MessengerApi; use sp_runtime::traits::{Block as BlockT, HashFor, NumberFor}; -use sp_settlement::SettlementApi; use std::sync::Arc; -use subspace_core_primitives::Blake2b256Hash; -use system_runtime_primitives::SystemDomainApi; +use subspace_runtime_primitives::Balance; -/// System domain executor. -pub struct Executor +/// Domain operator. +pub struct Operator where Block: BlockT, - PBlock: BlockT, + CBlock: BlockT, { - primary_chain_client: Arc, + consensus_client: Arc, client: Arc, transaction_pool: Arc, backend: Arc, - fraud_proof_generator: FraudProofGenerator, - bundle_processor: SystemBundleProcessor, - domain_block_processor: DomainBlockProcessor, + fraud_proof_generator: FraudProofGenerator, + bundle_processor: BundleProcessor, + domain_block_processor: DomainBlockProcessor, } -impl Clone - for Executor +impl Clone + for Operator where Block: BlockT, - PBlock: BlockT, + CBlock: BlockT, { fn clone(&self) -> Self { Self { - primary_chain_client: self.primary_chain_client.clone(), + consensus_client: self.consensus_client.clone(), client: self.client.clone(), transaction_pool: self.transaction_pool.clone(), backend: self.backend.clone(), @@ -60,13 +59,13 @@ where } } -impl - Executor +impl + Operator where Block: BlockT, - PBlock: BlockT, - NumberFor: From> + Into>, - PBlock::Hash: From, + CBlock: BlockT, + NumberFor: From> + Into>, + CBlock::Hash: From, Client: HeaderBackend + BlockBackend + AuxStore @@ -75,67 +74,69 @@ where + Finalizer + 'static, Client::Api: DomainCoreApi + + InherentExtrinsicApi + MessengerApi> - + SystemDomainApi, PBlock::Hash, Block::Hash> + sp_block_builder::BlockBuilder + sp_api::ApiExt>, - for<'b> &'b Client: sc_consensus::BlockImport< - Block, - Transaction = sp_api::TransactionFor, - Error = sp_consensus::Error, - >, - PClient: HeaderBackend - + HeaderMetadata - + BlockBackend - + ProvideRuntimeApi - + BlockchainEvents + CClient: HeaderBackend + + HeaderMetadata + + BlockBackend + + ProvideRuntimeApi + + BlockchainEvents + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, + CClient::Api: DomainsApi, Block::Hash> + + BundleProducerElectionApi, Backend: sc_client_api::Backend + Send + Sync + 'static, - TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, TransactionPool: sc_transaction_pool_api::TransactionPool + 'static, E: CodeExecutor, + TransactionFor: sp_trie::HashDBT, sp_trie::DBValue>, + for<'b> &'b BI: sc_consensus::BlockImport< + Block, + Transaction = sp_api::TransactionFor, + Error = sp_consensus::Error, + >, + BI: Send + Sync + 'static, { /// Create a new instance. pub async fn new( spawn_essential: Box, select_chain: &SC, - params: EssentialExecutorParams< + params: OperatorParams< Block, - PBlock, + CBlock, Client, - PClient, + CClient, TransactionPool, Backend, E, IBNS, CIBNS, NSNS, - Client, + BI, >, ) -> Result where - SC: SelectChain, - IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, - CIBNS: Stream> + Send + 'static, - NSNS: Stream>)> + Send + 'static, + SC: SelectChain, + IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, + CIBNS: Stream> + Send + 'static, + NSNS: Stream + Send + 'static, { - let active_leaves = - active_leaves(params.primary_chain_client.as_ref(), select_chain).await?; + let active_leaves = active_leaves(params.consensus_client.as_ref(), select_chain).await?; - let parent_chain = SystemDomainParentChain::new(params.primary_chain_client.clone()); + let parent_chain = + DomainParentChain::new(params.domain_id, params.consensus_client.clone()); let domain_bundle_proposer = DomainBundleProposer::new( params.client.clone(), - params.primary_chain_client.clone(), + params.consensus_client.clone(), params.transaction_pool.clone(), ); let bundle_producer = DomainBundleProducer::new( - DomainId::SYSTEM, - params.client.clone(), + params.domain_id, + params.consensus_client.clone(), params.client.clone(), parent_chain.clone(), domain_bundle_proposer, @@ -145,15 +146,16 @@ where let fraud_proof_generator = FraudProofGenerator::new( params.client.clone(), - params.primary_chain_client.clone(), + params.consensus_client.clone(), params.backend.clone(), params.code_executor, ); let domain_block_processor = DomainBlockProcessor { - domain_id: DomainId::SYSTEM, + domain_id: params.domain_id, + domain_created_at: params.domain_created_at, client: params.client.clone(), - primary_chain_client: params.primary_chain_client.clone(), + consensus_client: params.consensus_client.clone(), backend: params.backend.clone(), domain_confirmation_depth: params.domain_confirmation_depth, block_import: params.block_import, @@ -161,17 +163,18 @@ where }; let receipts_checker = ReceiptsChecker { - domain_id: DomainId::SYSTEM, + domain_id: params.domain_id, client: params.client.clone(), - primary_chain_client: params.primary_chain_client.clone(), + consensus_client: params.consensus_client.clone(), fraud_proof_generator: fraud_proof_generator.clone(), parent_chain, - primary_network_sync_oracle: params.primary_network_sync_oracle, + consensus_network_sync_oracle: params.consensus_network_sync_oracle, _phantom: std::marker::PhantomData, }; - let bundle_processor = SystemBundleProcessor::new( - params.primary_chain_client.clone(), + let bundle_processor = BundleProcessor::new( + params.domain_id, + params.consensus_client.clone(), params.client.clone(), params.backend.clone(), params.keystore, @@ -180,23 +183,23 @@ where ); spawn_essential.spawn_essential_blocking( - "system-executor-worker", + "domain-operator-worker", None, - crate::system_domain_worker::start_worker( + crate::domain_worker_starter::start_worker( spawn_essential.clone(), - params.primary_chain_client.clone(), + params.consensus_client.clone(), params.client.clone(), params.is_authority, bundle_producer, bundle_processor.clone(), - params.executor_streams, + params.operator_streams, active_leaves, ) .boxed(), ); Ok(Self { - primary_chain_client: params.primary_chain_client, + consensus_client: params.consensus_client, client: params.client, transaction_pool: params.transaction_pool, backend: params.backend, @@ -208,7 +211,7 @@ where pub fn fraud_proof_generator( &self, - ) -> FraudProofGenerator { + ) -> FraudProofGenerator { self.fraud_proof_generator.clone() } @@ -216,7 +219,7 @@ where /// /// NOTE: Unlike `BlockchainEvents::import_notification_stream()`, this notification won't be /// fired until the system domain block's receipt processing is done. - pub fn import_notification_stream(&self) -> DomainImportNotifications { + pub fn import_notification_stream(&self) -> DomainImportNotifications { let (sink, stream) = tracing_unbounded("mpsc_domain_import_notification_stream", 100); self.domain_block_processor .import_notification_sinks @@ -225,13 +228,20 @@ where stream } - /// Processes the bundles extracted from the primary block. + /// Processes the bundles extracted from the consensus block. // TODO: Remove this whole method, `self.bundle_processor` as a property and fix // `set_new_code_should_work` test to do an actual runtime upgrade #[doc(hidden)] - pub async fn process_bundles(self, primary_info: (PBlock::Hash, NumberFor)) { - if let Err(err) = self.bundle_processor.process_bundles(primary_info).await { - tracing::error!(?primary_info, ?err, "Error at processing bundles."); + pub async fn process_bundles( + self, + consensus_block_info: (CBlock::Hash, NumberFor, bool), + ) { + if let Err(err) = self + .bundle_processor + .process_bundles(consensus_block_info) + .await + { + tracing::error!(?consensus_block_info, ?err, "Error at processing bundles."); } } } diff --git a/domains/client/domain-operator/src/parent_chain.rs b/domains/client/domain-operator/src/parent_chain.rs new file mode 100644 index 00000000000..8cc42231d53 --- /dev/null +++ b/domains/client/domain-operator/src/parent_chain.rs @@ -0,0 +1,188 @@ +use crate::ExecutionReceiptFor; +use sc_client_api::BlockBackend; +use sp_api::{NumberFor, ProvideRuntimeApi}; +use sp_blockchain::HeaderBackend; +use sp_domains::fraud_proof::FraudProof; +use sp_domains::{DomainBlockLimit, DomainId, DomainsApi}; +use sp_runtime::traits::Block as BlockT; +use std::marker::PhantomData; +use std::sync::Arc; + +type FraudProofFor = + FraudProof, ::Hash>; + +/// Trait for interacting between the domain and its corresponding parent chain, i.e. retrieving +/// the necessary info from the parent chain or submit extrinsics to the parent chain. +pub trait ParentChainInterface { + fn best_hash(&self) -> ParentChainBlock::Hash; + + fn block_body( + &self, + at: ParentChainBlock::Hash, + ) -> sp_blockchain::Result>; + + fn oldest_receipt_number( + &self, + at: ParentChainBlock::Hash, + ) -> Result, sp_api::ApiError>; + + fn head_receipt_number( + &self, + at: ParentChainBlock::Hash, + ) -> Result, sp_api::ApiError>; + + fn block_tree_pruning_depth( + &self, + at: ParentChainBlock::Hash, + ) -> Result, sp_api::ApiError>; + + fn domain_block_limit( + &self, + at: ParentChainBlock::Hash, + ) -> Result; + + fn extract_receipts( + &self, + at: ParentChainBlock::Hash, + extrinsics: Vec, + ) -> Result>, sp_api::ApiError>; + + fn extract_fraud_proofs( + &self, + at: ParentChainBlock::Hash, + extrinsics: Vec, + ) -> Result>, sp_api::ApiError>; + + fn submit_fraud_proof_unsigned( + &self, + fraud_proof: FraudProof, ParentChainBlock::Hash>, + ) -> Result<(), sp_api::ApiError>; +} + +/// The parent chain of the domain. +pub struct DomainParentChain { + domain_id: DomainId, + consensus_client: Arc, + _phantom: PhantomData<(Block, CBlock)>, +} + +impl Clone for DomainParentChain { + fn clone(&self) -> Self { + Self { + domain_id: self.domain_id, + consensus_client: self.consensus_client.clone(), + _phantom: self._phantom, + } + } +} + +impl DomainParentChain { + pub fn new(domain_id: DomainId, consensus_client: Arc) -> Self { + Self { + domain_id, + consensus_client, + _phantom: PhantomData, + } + } +} + +impl ParentChainInterface + for DomainParentChain +where + Block: BlockT, + CBlock: BlockT, + NumberFor: Into>, + CClient: HeaderBackend + BlockBackend + ProvideRuntimeApi, + CClient::Api: DomainsApi, Block::Hash>, +{ + fn best_hash(&self) -> CBlock::Hash { + self.consensus_client.info().best_hash + } + + fn block_body(&self, at: CBlock::Hash) -> sp_blockchain::Result> { + self.consensus_client.block_body(at)?.ok_or_else(|| { + sp_blockchain::Error::Backend(format!("Consensus block body for {at} not found")) + }) + } + + fn oldest_receipt_number( + &self, + at: CBlock::Hash, + ) -> Result, sp_api::ApiError> { + let oldest_receipt_number = self + .consensus_client + .runtime_api() + .oldest_receipt_number(at, self.domain_id)?; + Ok(oldest_receipt_number.into()) + } + + fn head_receipt_number(&self, at: CBlock::Hash) -> Result, sp_api::ApiError> { + let head_receipt_number = self + .consensus_client + .runtime_api() + .head_receipt_number(at, self.domain_id)?; + Ok(head_receipt_number.into()) + } + + fn block_tree_pruning_depth( + &self, + at: CBlock::Hash, + ) -> Result, sp_api::ApiError> { + let max_drift = self + .consensus_client + .runtime_api() + .block_tree_pruning_depth(at)?; + Ok(max_drift.into()) + } + + fn domain_block_limit(&self, at: CBlock::Hash) -> Result { + let limit = self + .consensus_client + .runtime_api() + .domain_block_limit(at, self.domain_id)? + .ok_or(sp_blockchain::Error::Application( + format!( + "Domain block limit for domain {:?} not found", + self.domain_id + ) + .into(), + ))?; + Ok(limit) + } + + fn extract_receipts( + &self, + _at: CBlock::Hash, + _extrinsics: Vec, + ) -> Result>, sp_api::ApiError> { + // TODO: Implement when proceeding to fraud proof v2. + Ok(Vec::new()) + // self.consensus_client + // .runtime_api() + // .extract_receipts(at, extrinsics, self.domain_id) + } + + fn extract_fraud_proofs( + &self, + _at: CBlock::Hash, + _extrinsics: Vec, + ) -> Result>, sp_api::ApiError> { + // TODO: Implement when proceeding to fraud proof v2. + Ok(Vec::new()) + // self.consensus_client + // .runtime_api() + // .extract_fraud_proofs(at, extrinsics, self.domain_id) + } + + fn submit_fraud_proof_unsigned( + &self, + _fraud_proof: FraudProof, CBlock::Hash>, + ) -> Result<(), sp_api::ApiError> { + // TODO: Implement when proceeding to fraud proof v2. + // let at = self.consensus_client.info().best_hash; + // self.consensus_client + // .runtime_api() + // .submit_fraud_proof_unsigned(at, fraud_proof)?; + Ok(()) + } +} diff --git a/domains/client/domain-executor/src/tests.rs b/domains/client/domain-operator/src/tests.rs similarity index 54% rename from domains/client/domain-executor/src/tests.rs rename to domains/client/domain-operator/src/tests.rs index b8c99f3525e..0914661b505 100644 --- a/domains/client/domain-executor/src/tests.rs +++ b/domains/client/domain-operator/src/tests.rs @@ -1,7 +1,11 @@ +use crate::domain_block_processor::{DomainBlockProcessor, PendingConsensusBlocks}; use codec::{Decode, Encode}; use domain_runtime_primitives::{DomainCoreApi, Hash}; -use domain_test_service::system_domain_test_runtime::{Address, Header, UncheckedExtrinsic}; -use domain_test_service::Keyring::{Alice, Bob, Ferdie}; +use domain_test_primitives::TimestampApi; +use domain_test_service::evm_domain_test_runtime::{Header, UncheckedExtrinsic}; +use domain_test_service::EcdsaKeyring::{Alice, Bob}; +use domain_test_service::Sr25519Keyring::{self, Ferdie}; +use domain_test_service::GENESIS_DOMAIN_ID; use futures::StreamExt; use sc_client_api::{Backend, BlockBackend, HeaderBackend}; use sc_service::{BasePath, Role}; @@ -14,168 +18,539 @@ use sp_core::Pair; use sp_domain_digests::AsPredigest; use sp_domains::fraud_proof::{ExecutionPhase, FraudProof, InvalidStateTransitionProof}; use sp_domains::transaction::InvalidTransactionCode; -use sp_domains::{Bundle, DomainId}; +use sp_domains::{Bundle, DomainId, DomainsApi}; use sp_runtime::generic::{BlockId, Digest, DigestItem}; use sp_runtime::traits::{BlakeTwo256, Header as HeaderT}; use sp_runtime::OpaqueExtrinsic; -use sp_settlement::SettlementApi; -use subspace_core_primitives::BlockNumber; use subspace_fraud_proof::invalid_state_transition_proof::ExecutionProver; +use subspace_runtime_primitives::Balance; use subspace_test_service::{ - produce_block_with, produce_blocks, produce_blocks_until, MockPrimaryNode, + produce_block_with, produce_blocks, produce_blocks_until, MockConsensusNode, }; use tempfile::TempDir; -fn number_of(primary_node: &MockPrimaryNode, block_hash: Hash) -> u32 { - primary_node +fn number_of(consensus_node: &MockConsensusNode, block_hash: Hash) -> u32 { + consensus_node .client .number(block_hash) .unwrap_or_else(|err| panic!("Failed to fetch number for {block_hash}: {err}")) .unwrap_or_else(|| panic!("header {block_hash} not in the chain")) } +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn test_domain_instance_bootstrapper() { + let directory = TempDir::new().expect("Must be able to create temporary directory"); + + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + let _ = builder.init(); + + let tokio_handle = tokio::runtime::Handle::current(); + + // Start Ferdie + let mut ferdie = MockConsensusNode::run( + tokio_handle.clone(), + Ferdie, + BasePath::new(directory.path().join("ferdie")), + ); + + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); + + let expected_genesis_state_root = ferdie + .client + .runtime_api() + .genesis_state_root(ferdie.client.info().best_hash, GENESIS_DOMAIN_ID) + .unwrap() + .unwrap(); + + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( + tokio_handle.clone(), + Alice, + BasePath::new(directory.path().join("alice")), + ) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) + .await; + + let genesis_state_root = *alice + .client + .header(alice.client.info().genesis_hash) + .unwrap() + .unwrap() + .state_root(); + + assert_eq!(expected_genesis_state_root, genesis_state_root); + + produce_blocks!(ferdie, alice, 3) + .await + .expect("3 consensus blocks produced successfully"); +} + +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn test_domain_block_production() { + let directory = TempDir::new().expect("Must be able to create temporary directory"); + + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + let _ = builder.init(); + + let tokio_handle = tokio::runtime::Handle::current(); + + // Start Ferdie + let mut ferdie = MockConsensusNode::run( + tokio_handle.clone(), + Ferdie, + BasePath::new(directory.path().join("ferdie")), + ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); + + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( + tokio_handle.clone(), + Alice, + BasePath::new(directory.path().join("alice")), + ) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) + .await; + + for i in 0..50 { + let (tx, slot) = if i % 2 == 0 { + // Produce bundle and include it in the primary block hence produce a domain block + let (slot, _) = ferdie.produce_slot_and_wait_for_bundle_submission().await; + // `None` means collect tx from the tx pool + (None, slot) + } else { + // No bundle hence not produce domain block + (Some(vec![]), ferdie.produce_slot()) + }; + ferdie + .produce_block_with_slot_at(slot, ferdie.client.info().best_hash, tx) + .await + .unwrap(); + } + // Domain block only produced when there is bundle contains in the primary block + assert_eq!(ferdie.client.info().best_number, 51); + assert_eq!(alice.client.info().best_number, 25); + + let consensus_block_hash = ferdie.client.info().best_hash; + let domain_block_number = alice.client.info().best_number; + let domain_block_hash = alice.client.info().best_hash; + + // Fork A + // Produce 5 more primary blocks and producing domain block for every primary block + produce_blocks!(ferdie, alice, 3).await.unwrap(); + + // Record the block hashes for later use + let mut fork_b_parent_hash = ferdie.client.info().best_hash; + let fork_a_block_hash_3 = alice.client.info().best_hash; + + produce_blocks!(ferdie, alice, 2).await.unwrap(); + assert_eq!(alice.client.info().best_number, domain_block_number + 5); + + // Fork B + // Produce 6 more primary blocks but only producing 3 domain blocks because there are + // more primary block on fork B, it will become the best fork of the domain chain + for _ in 0..3 { + let slot = ferdie.produce_slot(); + fork_b_parent_hash = ferdie + .produce_block_with_slot_at(slot, fork_b_parent_hash, Some(vec![])) + .await + .unwrap(); + } + assert_eq!(alice.client.info().best_number, domain_block_number + 3); + assert_eq!(alice.client.info().best_hash, fork_a_block_hash_3); + + // Fork C + // Produce 10 more primary blocks and do not produce any domain block but because there are + // more primary block on fork C, it will become the best fork of the domain chain + let mut fork_c_parent_hash = consensus_block_hash; + for _ in 0..10 { + let slot = ferdie.produce_slot(); + fork_c_parent_hash = ferdie + .produce_block_with_slot_at(slot, fork_c_parent_hash, Some(vec![])) + .await + .unwrap(); + } + // The best block fall back to an ancestor block + assert_eq!(alice.client.info().best_number, domain_block_number); + assert_eq!(alice.client.info().best_hash, domain_block_hash); + + // Simply producing more block on fork C + for _ in 0..10 { + let (slot, bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; + let tx = subspace_test_runtime::UncheckedExtrinsic::new_unsigned( + pallet_domains::Call::submit_bundle { + opaque_bundle: bundle.unwrap(), + } + .into(), + ) + .into(); + // Produce consensus block that only contains the `submit_bundle` extrinsic instead of + // any extrinsic in the tx pool, because the background worker `txpool-notifications` may + // submit extrinsic from the retracted blocks of other fork to the tx pool and these tx + // is invalid in the fork C + ferdie + .produce_block_with_slot_at(slot, ferdie.client.info().best_hash, Some(vec![tx])) + .await + .unwrap(); + } + assert_eq!(alice.client.info().best_number, domain_block_number + 10); +} + +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn test_processing_empty_consensus_block() { + let directory = TempDir::new().expect("Must be able to create temporary directory"); + + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + let _ = builder.init(); + + let tokio_handle = tokio::runtime::Handle::current(); + + // Start Ferdie + let mut ferdie = MockConsensusNode::run( + tokio_handle.clone(), + Ferdie, + BasePath::new(directory.path().join("ferdie")), + ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); + + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( + tokio_handle.clone(), + Alice, + BasePath::new(directory.path().join("alice")), + ) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) + .await; + + let domain_block_processor = DomainBlockProcessor { + domain_id: alice.domain_id, + domain_created_at: 1, + client: alice.client.clone(), + consensus_client: ferdie.client.clone(), + backend: alice.backend.clone(), + domain_confirmation_depth: 256u32, + block_import: alice.client.clone(), + import_notification_sinks: Default::default(), + }; + + let domain_genesis_hash = alice.client.info().best_hash; + for _ in 0..10 { + // Produce consensus block with no tx thus no bundle + ferdie.produce_block_with_extrinsics(vec![]).await.unwrap(); + + let consensus_best_hash = ferdie.client.info().best_hash; + let consensus_best_number = ferdie.client.info().best_number; + let res = domain_block_processor + .pending_imported_consensus_blocks(consensus_best_hash, consensus_best_number); + match res { + // The consensus block is processed in the above `produce_block_with_extrinsics` call, + // thus calling `pending_imported_consensus_blocks` again will result in an error + Err(err) => { + // `sp_blockchain::Error` is not impl `PartialEq` thus comparing the string + assert_eq!( + err.to_string(), + sp_blockchain::Error::Application( + format!( + "Consensus block {consensus_best_hash:?} has already been processed.", + ) + .into() + ) + .to_string() + ); + // The `latest_consensus_block` that mapped to the genesis domain block must be updated + let latest_consensus_block: Hash = + crate::aux_schema::latest_consensus_block_hash_for( + &*alice.backend, + &domain_genesis_hash, + ) + .unwrap() + .unwrap(); + assert_eq!(latest_consensus_block, consensus_best_hash); + } + // For consensus block at `domain_created_at + 1` (namely block #2), `pending_imported_consensus_blocks` + // will return `PendingConsensusBlocks` directly + Ok(Some(PendingConsensusBlocks { + initial_parent, + consensus_imports, + })) if consensus_best_number == 2 => { + assert_eq!(initial_parent.0, domain_genesis_hash); + assert_eq!(consensus_imports.len(), 1); + assert_eq!(consensus_imports[0].hash, consensus_best_hash,); + } + _ => panic!("unexpected result: {res:?}"), + } + } + // The domain chain is not progressed as all the consensus blocks are empty + assert_eq!(ferdie.client.info().best_number, 11); + assert_eq!(alice.client.info().best_number, 0); + + // To process non-empty consensus blocks and produce domain blocks + produce_blocks!(ferdie, alice, 3).await.unwrap(); + assert_eq!(alice.client.info().best_number, 3); +} + +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn test_domain_block_deriving_from_multiple_bundles() { + let directory = TempDir::new().expect("Must be able to create temporary directory"); + + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + let _ = builder.init(); + + let tokio_handle = tokio::runtime::Handle::current(); + + // Start Ferdie + let mut ferdie = MockConsensusNode::run( + tokio_handle.clone(), + Ferdie, + BasePath::new(directory.path().join("ferdie")), + ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); + + // Run Alice (a evm domain authority node) + let mut alice = domain_test_service::DomainNodeBuilder::new( + tokio_handle.clone(), + Alice, + BasePath::new(directory.path().join("alice")), + ) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) + .await; + + produce_blocks!(ferdie, alice, 3).await.unwrap(); + + let pre_bob_free_balance = alice.free_balance(Bob.to_account_id()); + let alice_account_nonce = alice.account_nonce(); + for i in 0..3 { + let tx = alice.construct_extrinsic( + alice_account_nonce + i, + pallet_balances::Call::transfer { + dest: Bob.to_account_id(), + value: 1, + }, + ); + alice + .send_extrinsic(tx) + .await + .expect("Failed to send extrinsic"); + + // Produce a bundle and submit to the tx pool of the consensus node + let (slot, bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; + assert!(bundle.is_some()); + + // In the last iteration, produce a consensus block which will included all the bundles + // and drive the corresponding domain block + if i == 2 { + produce_block_with!(ferdie.produce_block_with_slot(slot), alice) + .await + .unwrap(); + } + } + assert_eq!( + alice.free_balance(Bob.to_account_id()), + pre_bob_free_balance + 3 + ); + let domain_block_number = alice.client.info().best_number; + + // Produce one more bundle to submit the receipt of the above 3 bundles + produce_blocks!(ferdie, alice, 1).await.unwrap(); + + // The receipt should be submitted successfully thus head receipt number + // is updated + let head_receipt_number = ferdie + .client + .runtime_api() + .head_receipt_number(ferdie.client.info().best_hash, 0u32.into()) + .unwrap(); + assert_eq!(domain_block_number, head_receipt_number); +} + #[substrate_test_utils::test(flavor = "multi_thread")] async fn collected_receipts_should_be_on_the_same_branch_with_current_best_block() { let directory = TempDir::new().expect("Must be able to create temporary directory"); - let _ = sc_cli::LoggerBuilder::new("runtime=debug").init(); + + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + let _ = builder.init(); + let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut primary_node = MockPrimaryNode::run_mock_primary_node( + let mut consensus_node = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); + // Produce 1 consensus block to initialize genesis domain + consensus_node + .produce_block_with_slot(1.into()) + .await + .unwrap(); - // Run Alice (a system domain authority node) - let alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut primary_node) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut consensus_node) .await; - produce_blocks!(primary_node, alice, 3) + produce_blocks!(consensus_node, alice, 3) .await - .expect("3 primary blocks produced successfully"); + .expect("3 consensus blocks produced successfully"); - let best_primary_hash = primary_node.client.info().best_hash; - let best_primary_number = primary_node.client.info().best_number; - assert_eq!(best_primary_number, 3); + let best_consensus_hash = consensus_node.client.info().best_hash; + let best_consensus_number = consensus_node.client.info().best_number; + assert_eq!(best_consensus_number, 4); + + assert_eq!(alice.client.info().best_number, 3); + let domain_block_2_hash = *alice + .client + .header(alice.client.info().best_hash) + .unwrap() + .unwrap() + .parent_hash(); - let best_header = primary_node + let best_header = consensus_node .client - .header(best_primary_hash) + .header(best_consensus_hash) .unwrap() .unwrap(); let parent_hash = *best_header.parent_hash(); - // Primary chain forks: + // Domain chain forks: // 3 // / // 2 -- 3a // \ // 3b -- 4 - let slot = primary_node.produce_slot(); - let fork_block_hash_3a = primary_node + + // Consensus chain forks (it has 1 more block compare to the domain chain): + // 4 + // / + // 3 -- 4a + // \ + // 4b -- 5 + let slot = consensus_node.produce_slot(); + let fork_block_hash_4a = consensus_node .produce_block_with_slot_at(slot, parent_hash, Some(vec![])) .await - .expect("Produced first primary fork block 3a at height #3"); - // A fork block 3a at #3 produced. - assert_eq!(number_of(&primary_node, fork_block_hash_3a), 3); - assert_ne!(fork_block_hash_3a, best_primary_hash); + .expect("Produced first consensus fork block 4a at height #4"); + // A fork block 4a at #4 produced. + assert_eq!(number_of(&consensus_node, fork_block_hash_4a), 4); + assert_ne!(fork_block_hash_4a, best_consensus_hash); // Best hash unchanged due to the longest chain fork choice. - assert_eq!(primary_node.client.info().best_hash, best_primary_hash); - // Hash of block number #3 unchanged. + assert_eq!(consensus_node.client.info().best_hash, best_consensus_hash); + // Hash of block number #4 unchanged. assert_eq!( - primary_node.client.hash(3).unwrap().unwrap(), - best_primary_hash + consensus_node.client.hash(4).unwrap().unwrap(), + best_consensus_hash ); - let primary_block_info = + let consensus_block_info = |best_header: Header| -> (u32, Hash) { (*best_header.number(), best_header.hash()) }; - let receipts_primary_info = - |bundle: Bundle| { - (bundle.receipt.primary_number, bundle.receipt.primary_hash) + let receipts_consensus_info = + |bundle: Bundle| { + ( + bundle.receipt().consensus_block_number, + bundle.receipt().consensus_block_hash, + ) }; - // Produce a bundle after the fork block #3a has been produced. - let signed_bundle = primary_node.notify_new_slot_and_wait_for_bundle(slot).await; + // Produce a bundle after the fork block #4a has been produced. + let signed_bundle = consensus_node + .notify_new_slot_and_wait_for_bundle(slot) + .await; - let expected_receipts_primary_info = primary_block_info(best_header.clone()); + let expected_receipts_consensus_info = consensus_block_info(best_header.clone()); // TODO: make MaximumReceiptDrift configurable in order to submit all the pending receipts at // once, now the max drift is 2, the receipts is limitted to [2, 3]. Once configurable, we // can make the assertation straightforward: - // assert_eq!(receipts_primary_info, expected_receipts_primary_info). + // assert_eq!(receipts_consensus_info, expected_receipts_consensus_info). // // Receipts are always collected against the current best block. assert_eq!( - receipts_primary_info(signed_bundle.unwrap()), - expected_receipts_primary_info + receipts_consensus_info(signed_bundle.unwrap()), + expected_receipts_consensus_info ); - let slot = primary_node.produce_slot(); - let fork_block_hash_3b = primary_node + let slot = consensus_node.produce_slot(); + let fork_block_hash_4b = consensus_node .produce_block_with_slot_at(slot, parent_hash, Some(vec![])) .await - .expect("Produced second primary fork block 3b at height #3"); - // Another fork block 3b at #3 produced, - assert_eq!(number_of(&primary_node, fork_block_hash_3b), 3); - assert_ne!(fork_block_hash_3b, best_primary_hash); + .expect("Produced second consensus fork block 3b at height #3"); + // Another fork block 3b at #4 produced, + assert_eq!(number_of(&consensus_node, fork_block_hash_4b), 4); + assert_ne!(fork_block_hash_4b, best_consensus_hash); // Best hash unchanged due to the longest chain fork choice. - assert_eq!(primary_node.client.info().best_hash, best_primary_hash); - // Hash of block number #3 unchanged. + assert_eq!(consensus_node.client.info().best_hash, best_consensus_hash); + // Hash of block number #4 unchanged. assert_eq!( - primary_node.client.hash(3).unwrap().unwrap(), - best_primary_hash + consensus_node.client.hash(4).unwrap().unwrap(), + best_consensus_hash ); // Produce a bundle after the fork block #3b has been produced. - let signed_bundle = primary_node.notify_new_slot_and_wait_for_bundle(slot).await; + let signed_bundle = consensus_node + .notify_new_slot_and_wait_for_bundle(slot) + .await; // Receipts are always collected against the current best block. assert_eq!( - receipts_primary_info(signed_bundle.unwrap()), - expected_receipts_primary_info + receipts_consensus_info(signed_bundle.unwrap()), + expected_receipts_consensus_info ); - // Produce a new tip at #4. - let slot = primary_node.produce_slot(); + // Produce a new tip at #5. + let slot = consensus_node.produce_slot(); produce_block_with!( - primary_node.produce_block_with_slot_at(slot, fork_block_hash_3b, Some(vec![])), + consensus_node.produce_block_with_slot_at(slot, fork_block_hash_4b, Some(vec![])), alice ) .await - .expect("Produce a new block on top of the second fork block at height #3"); - let new_best_hash = primary_node.client.info().best_hash; - let new_best_number = primary_node.client.info().best_number; - assert_eq!(new_best_number, 4); - assert_eq!(alice.client.info().best_number, 4); + .expect("Produce a new block on top of the second fork block at height #4"); + let new_best_hash = consensus_node.client.info().best_hash; + let new_best_number = consensus_node.client.info().best_number; + assert_eq!(new_best_number, 5); + + // The domain best block should be reverted to #2 because the primary block #4b and #5 do + // not contains any bundles + assert_eq!(alice.client.info().best_number, 2); + assert_eq!(alice.client.info().best_hash, domain_block_2_hash); - // Hash of block number #3 is updated to the second fork block 3b. + // Hash of block number #4 is updated to the second fork block 4b. assert_eq!( - primary_node.client.hash(3).unwrap().unwrap(), - fork_block_hash_3b + consensus_node.client.hash(4).unwrap().unwrap(), + fork_block_hash_4b ); - let new_best_header = primary_node.client.header(new_best_hash).unwrap().unwrap(); + let new_best_header = consensus_node + .client + .header(new_best_hash) + .unwrap() + .unwrap(); - assert_eq!(*new_best_header.parent_hash(), fork_block_hash_3b); + assert_eq!(*new_best_header.parent_hash(), fork_block_hash_4b); - // Produce a bundle after the new block #4 has been produced. - let (_slot, signed_bundle) = primary_node + // Produce a bundle after the new block #5 has been produced. + let (_slot, signed_bundle) = consensus_node .produce_slot_and_wait_for_bundle_submission() .await; - // In the new best fork, the receipt header number is 1 thus it produce the receipt - // of next block namely block 2 - let hash_2 = primary_node.client.hash(2).unwrap().unwrap(); - let header_2 = primary_node.client.header(hash_2).unwrap().unwrap(); + // In the new best fork, the receipt header number is 2 thus it produce the receipt + // of next block namely block 3 + let hash_3 = consensus_node.client.hash(3).unwrap().unwrap(); + let header_3 = consensus_node.client.header(hash_3).unwrap().unwrap(); assert_eq!( - receipts_primary_info(signed_bundle.unwrap()), - primary_block_info(header_2) + receipts_consensus_info(signed_bundle.unwrap()), + consensus_block_info(header_3) ); } @@ -190,29 +565,31 @@ async fn test_domain_tx_propagate() { let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); - // Run Alice (a system domain authority node) - let alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; - // Run Bob (a system domain full node) - let mut bob = domain_test_service::SystemDomainNodeBuilder::new( + // Run Bob (a evm domain full node) + let mut bob = domain_test_service::DomainNodeBuilder::new( tokio_handle, Bob, BasePath::new(directory.path().join("bob")), ) - .connect_to_system_domain_node(&alice) - .build_with_mock_primary_node(Role::Full, &mut ferdie) + .connect_to_domain_node(alice.addr.clone()) + .build_evm_node(Role::Full, GENESIS_DOMAIN_ID, &mut ferdie) .await; produce_blocks!(ferdie, alice, bob, 5).await.unwrap(); @@ -224,7 +601,7 @@ async fn test_domain_tx_propagate() { // Construct and send an extrinsic to bob, as bob is not a authoity node, the extrinsic has // to propagate to alice to get executed bob.construct_and_send_extrinsic(pallet_balances::Call::transfer { - dest: Address::Id(Alice.public().into()), + dest: Alice.to_account_id(), value: 123, }) .await @@ -248,28 +625,34 @@ async fn test_executor_full_node_catching_up() { let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); + // Produce 5 consensus block to initialize genesis domain + // + // This also make the first consensus block being processed by the alice's domain + // block processor be block #5, to ensure it can correctly handle the consensus + // block even it is out of order. + ferdie.produce_blocks(5).await.unwrap(); - // Run Alice (a system domain authority node) - let alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; - // Run Bob (a system domain full node) - let bob = domain_test_service::SystemDomainNodeBuilder::new( + // Run Bob (a evm domain full node) + let bob = domain_test_service::DomainNodeBuilder::new( tokio_handle, Bob, BasePath::new(directory.path().join("bob")), ) - .build_with_mock_primary_node(Role::Full, &mut ferdie) + .build_evm_node(Role::Full, GENESIS_DOMAIN_ID, &mut ferdie) .await; // Bob is able to sync blocks. @@ -285,73 +668,84 @@ async fn test_executor_full_node_catching_up() { .unwrap(); assert_eq!( alice_block_hash, bob_block_hash, - "Executor authority node and full node must have the same state" + "Domain authority node and full node must have the same state" ); } -// TODO: Unlock test when evm domain is supported in DecEx v2. -// #[substrate_test_utils::test(flavor = "multi_thread")] -// async fn test_executor_inherent_timestamp_is_set() { -// let directory = TempDir::new().expect("Must be able to create temporary directory"); +#[substrate_test_utils::test(flavor = "multi_thread")] +async fn test_executor_inherent_timestamp_is_set() { + let directory = TempDir::new().expect("Must be able to create temporary directory"); -// let mut builder = sc_cli::LoggerBuilder::new(""); -// builder.with_colors(false); -// let _ = builder.init(); + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + let _ = builder.init(); -// let tokio_handle = tokio::runtime::Handle::current(); + let tokio_handle = tokio::runtime::Handle::current(); -// // Start Ferdie -// let mut ferdie = MockPrimaryNode::run_mock_primary_node( -// tokio_handle.clone(), -// Ferdie, -// BasePath::new(directory.path().join("ferdie")), -// ); + // Start Ferdie + let mut ferdie = MockConsensusNode::run( + tokio_handle.clone(), + Ferdie, + BasePath::new(directory.path().join("ferdie")), + ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); -// // Run Alice (a system domain authority node) -// let alice = domain_test_service::SystemDomainNodeBuilder::new( -// tokio_handle.clone(), -// Alice, -// BasePath::new(directory.path().join("alice")), -// ) -// .build_with_mock_primary_node(Role::Authority, &mut ferdie) -// .await; + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( + tokio_handle.clone(), + Alice, + BasePath::new(directory.path().join("alice")), + ) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) + .await; -// // Run Bob who runs the authority node for core domain -// let bob = domain_test_service::CoreDomainNodeBuilder::new( -// tokio_handle.clone(), -// Bob, -// BasePath::new(directory.path().join("bob")), -// ) -// .build_core_payments_node(Role::Authority, &mut ferdie, &alice) -// .await; + // Run Bob who runs the authority node for core domain + let bob = domain_test_service::DomainNodeBuilder::new( + tokio_handle.clone(), + Bob, + BasePath::new(directory.path().join("bob")), + ) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) + .await; -// produce_blocks!(ferdie, alice, bob, 1).await.unwrap(); + produce_blocks!(ferdie, alice, bob, 1).await.unwrap(); -// let primary_api = ferdie.client.runtime_api(); -// let primary_timestamp = primary_api -// .timestamp(ferdie.client.info().best_hash) -// .unwrap(); + let consensus_timestamp = ferdie + .client + .runtime_api() + .timestamp(ferdie.client.info().best_hash) + .unwrap(); -// let core_api = bob.client.runtime_api(); -// let core_timestamp = core_api.timestamp(bob.client.info().best_hash).unwrap(); + let domain_timestamp = bob + .client + .runtime_api() + .timestamp(bob.client.info().best_hash) + .unwrap(); -// assert_eq!( -// primary_timestamp, core_timestamp, -// "Timestamp should be preset on Core domain and should match Primary runtime timestamp" -// ); -// } + assert_eq!( + consensus_timestamp, domain_timestamp, + "Timestamp should be preset on domain and must match Consensus runtime timestamp" + ); +} #[substrate_test_utils::test(flavor = "multi_thread")] +#[ignore] async fn test_initialize_block_proof_creation_and_verification_should_work() { test_invalid_state_transition_proof_creation_and_verification(0).await } #[substrate_test_utils::test(flavor = "multi_thread")] +#[ignore] async fn test_apply_extrinsic_proof_creation_and_verification_should_work() { test_invalid_state_transition_proof_creation_and_verification(1).await } +// TODO: the test is ignored due to the invalid receipt can not pass the state root check +// in the runtime now, thus can't construct `finalize_block` fraud proof, find a way to +// bypass the check #[substrate_test_utils::test(flavor = "multi_thread")] +#[ignore] async fn test_finalize_block_proof_creation_and_verification_should_work() { test_invalid_state_transition_proof_creation_and_verification(2).await } @@ -371,19 +765,21 @@ async fn test_invalid_state_transition_proof_creation_and_verification( let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); - // Run Alice (a system domain authority node) - let mut alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let mut alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; let bundle_to_tx = |opaque_bundle| { @@ -397,7 +793,7 @@ async fn test_invalid_state_transition_proof_creation_and_verification( alice .construct_and_send_extrinsic(pallet_balances::Call::transfer { - dest: Address::Id(Bob.public().into()), + dest: Bob.to_account_id(), value: 1, }) .await @@ -407,17 +803,6 @@ async fn test_invalid_state_transition_proof_creation_and_verification( let (slot, bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; let target_bundle = bundle.unwrap(); assert_eq!(target_bundle.extrinsics.len(), 1); - produce_block_with!(ferdie.produce_block_with_slot(slot), alice) - .await - .unwrap(); - // Manually remove the target bundle from tx pool in case resubmit it by accident - ferdie - .prune_tx_from_pool(&bundle_to_tx(target_bundle.clone())) - .unwrap(); - - // Produce one more block but using the same slot to avoid producing new bundle, this step is intend - // to increase the `ProofOfElection::block_number` of the next bundle such that we can skip the runtime - // `state_root` check for the modified `trace` when testing the `finalize_block` proof. produce_block_with!(ferdie.produce_block_with_slot(slot), alice) .await .unwrap(); @@ -427,16 +812,11 @@ async fn test_invalid_state_transition_proof_creation_and_verification( let original_submit_bundle_tx = bundle_to_tx(bundle.clone().unwrap()); let bad_submit_bundle_tx = { let mut opaque_bundle = bundle.unwrap(); - let receipt = &mut opaque_bundle.receipt; - assert_eq!( - receipt.primary_number, - target_bundle.sealed_header.header.primary_number + 1 - ); - assert_eq!(receipt.trace.len(), 3); + let receipt = &mut opaque_bundle.sealed_header.header.receipt; + assert_eq!(receipt.execution_trace.len(), 3); - receipt.trace[mismatch_trace_index] = Default::default(); - opaque_bundle.sealed_header.signature = alice - .key + receipt.execution_trace[mismatch_trace_index] = Default::default(); + opaque_bundle.sealed_header.signature = Sr25519Keyring::Alice .pair() .sign(opaque_bundle.sealed_header.pre_hash().as_ref()) .into(); @@ -446,6 +826,7 @@ async fn test_invalid_state_transition_proof_creation_and_verification( // Replace `original_submit_bundle_tx` with `bad_submit_bundle_tx` in the tx pool ferdie .prune_tx_from_pool(&original_submit_bundle_tx) + .await .unwrap(); assert!(ferdie.get_bundle_from_tx_pool(slot.into()).is_none()); @@ -454,7 +835,7 @@ async fn test_invalid_state_transition_proof_creation_and_verification( .await .unwrap(); - // Produce a primary block that contains the `bad_submit_bundle_tx` + // Produce a consensus block that contains the `bad_submit_bundle_tx` let mut import_tx_stream = ferdie.transaction_pool.import_notification_stream(); produce_block_with!(ferdie.produce_block_with_slot(slot), alice) .await @@ -472,36 +853,37 @@ async fn test_invalid_state_transition_proof_creation_and_verification( ) .unwrap(); if let subspace_test_runtime::RuntimeCall::Domains( - pallet_domains::Call::submit_fraud_proof { - fraud_proof: FraudProof::InvalidStateTransition(proof), - }, + pallet_domains::Call::submit_fraud_proof { fraud_proof }, ) = ext.function { - match mismatch_trace_index { - 0 => assert!(matches!( - proof.execution_phase, - ExecutionPhase::InitializeBlock { .. } - )), - 1 => assert!(matches!( - proof.execution_phase, - ExecutionPhase::ApplyExtrinsic(_) - )), - 2 => assert!(matches!( - proof.execution_phase, - ExecutionPhase::FinalizeBlock { .. } - )), - _ => unreachable!(), + if let FraudProof::InvalidStateTransition(proof) = *fraud_proof { + match mismatch_trace_index { + 0 => assert!(matches!( + proof.execution_phase, + ExecutionPhase::InitializeBlock { .. } + )), + 1 => assert!(matches!( + proof.execution_phase, + ExecutionPhase::ApplyExtrinsic(_) + )), + 2 => assert!(matches!( + proof.execution_phase, + ExecutionPhase::FinalizeBlock { .. } + )), + _ => unreachable!(), + } + break; } - break; } } - // Produce a primary block that contains the fraud proof, the fraud proof wil be verified + // Produce a consensus block that contains the fraud proof, the fraud proof wil be verified // in the block import pipeline ferdie.produce_blocks(1).await.unwrap(); } #[substrate_test_utils::test(flavor = "multi_thread")] +#[ignore] async fn fraud_proof_verification_in_tx_pool_should_work() { let directory = TempDir::new().expect("Must be able to create temporary directory"); @@ -512,19 +894,21 @@ async fn fraud_proof_verification_in_tx_pool_should_work() { let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); - // Run Alice (a system domain authority node) - let alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; // TODO: test the `initialize_block` fraud proof of block 1 with `wait_for_blocks(1)` @@ -535,14 +919,14 @@ async fn fraud_proof_verification_in_tx_pool_should_work() { let (_, bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; let bad_bundle = { let mut opaque_bundle = bundle.unwrap(); - opaque_bundle.receipt.trace[0] = Default::default(); + opaque_bundle.sealed_header.header.receipt.execution_trace[0] = Default::default(); opaque_bundle }; - let bad_receipt = bad_bundle.receipt.clone(); - let bad_receipt_number = bad_receipt.primary_number; + let bad_receipt = bad_bundle.receipt().clone(); + let bad_receipt_number = bad_receipt.consensus_block_number; assert_ne!(bad_receipt_number, 1); - // Submit the bad receipt to the primary chain + // Submit the bad receipt to the consensus chain let submit_bundle_tx = subspace_test_runtime::UncheckedExtrinsic::new_unsigned( pallet_domains::Call::submit_bundle { opaque_bundle: bad_bundle, @@ -615,10 +999,10 @@ async fn fraud_proof_verification_in_tx_pool_should_work() { let parent_number_ferdie = *parent_header_ferdie.number(); let good_invalid_state_transition_proof = InvalidStateTransitionProof { - domain_id: DomainId::SYSTEM, + domain_id: DomainId::new(3u32), bad_receipt_hash: bad_receipt.hash(), parent_number: parent_number_ferdie, - primary_parent_hash: parent_hash_ferdie, + consensus_parent_hash: parent_hash_ferdie, pre_state_root: *parent_header.state_root(), post_state_root: intermediate_roots[0].into(), proof: storage_proof, @@ -629,7 +1013,7 @@ async fn fraud_proof_verification_in_tx_pool_should_work() { let tx = subspace_test_runtime::UncheckedExtrinsic::new_unsigned( pallet_domains::Call::submit_fraud_proof { - fraud_proof: valid_fraud_proof.clone(), + fraud_proof: Box::new(valid_fraud_proof.clone()), } .into(), ) @@ -654,7 +1038,7 @@ async fn fraud_proof_verification_in_tx_pool_should_work() { let tx = subspace_test_runtime::UncheckedExtrinsic::new_unsigned( pallet_domains::Call::submit_fraud_proof { - fraud_proof: invalid_fraud_proof, + fraud_proof: Box::new(invalid_fraud_proof), } .into(), ); @@ -670,8 +1054,8 @@ async fn fraud_proof_verification_in_tx_pool_should_work() { // TODO: Add a new test which simulates a situation that an executor produces a fraud proof // when an invalid receipt is received. -// TODO: construct a minimal primary runtime code and use the `set_code` extrinsic to actually -// cover the case that the new domain runtime are updated accordingly upon the new primary runtime. +// TODO: construct a minimal consensus runtime code and use the `set_code` extrinsic to actually +// cover the case that the new domain runtime are updated accordingly upon the new consensus runtime. #[substrate_test_utils::test(flavor = "multi_thread")] #[ignore] async fn set_new_code_should_work() { @@ -684,19 +1068,21 @@ async fn set_new_code_should_work() { let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); - // Run Alice (a system domain authority node) - let alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; produce_blocks!(ferdie, alice, 1).await.unwrap(); @@ -704,22 +1090,22 @@ async fn set_new_code_should_work() { let new_runtime_wasm_blob = b"new_runtime_wasm_blob".to_vec(); let best_number = alice.client.info().best_number; - let primary_number = best_number + 1; + let consensus_block_number = best_number + 1; // Although we're processing the bundle manually, the original bundle processor still works in - // the meanwhile, it's possible the executor alice already processed this primary block, expecting next - // primary block, in which case we use a dummy primary hash instead. + // the meanwhile, it's possible the executor alice already processed this consensus block, expecting next + // consensus block, in which case we use a dummy consensus hash instead. // // Nice to disable the built-in bundle processor and have a full control of the executor block // production manually. - let primary_hash = ferdie + let consensus_block_hash = ferdie .client - .hash(primary_number) + .hash(consensus_block_number) .unwrap() .unwrap_or_else(Hash::random); alice - .executor + .operator .clone() - .process_bundles((primary_hash, primary_number)) + .process_bundles((consensus_block_hash, consensus_block_number, true)) .await; let best_hash = alice.client.info().best_hash; @@ -755,125 +1141,93 @@ async fn pallet_domains_unsigned_extrinsics_should_work() { let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); - // Run Alice (a system domain authority node) - let alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; - // Run Bob (a system domain full node) - let bob = domain_test_service::SystemDomainNodeBuilder::new( + // Run Bob (a evm domain full node) + let bob = domain_test_service::DomainNodeBuilder::new( tokio_handle, Bob, BasePath::new(directory.path().join("bob")), ) - .build_with_mock_primary_node(Role::Full, &mut ferdie) + .build_evm_node(Role::Full, GENESIS_DOMAIN_ID, &mut ferdie) .await; produce_blocks!(ferdie, alice, 1).await.unwrap(); // Get a bundle from alice's tx pool and used as bundle template. - let (_, bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; - let bundle_template = bundle.unwrap(); - let alice_key = alice.key; + let (slot, bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; + let _bundle_template = bundle.unwrap(); + let _alice_key = alice.key; // Drop alice in order to control the execution chain by submitting the receipts manually later. drop(alice); - // Wait for 5 blocks to make sure the execution receipts of block 2,3,4,5 are - // able to be written to the database. - produce_blocks!(ferdie, bob, 5).await.unwrap(); - - let ferdie_client = ferdie.client.clone(); - let create_submit_bundle = |primary_number: BlockNumber| { - let primary_hash = ferdie_client.hash(primary_number).unwrap().unwrap(); - let execution_receipt = - crate::aux_schema::load_execution_receipt(&*bob.backend, primary_hash) - .expect("Failed to load execution receipt from the local aux_db") - .unwrap_or_else(|| { - panic!( - "The requested execution receipt for block {primary_number} does not exist" - ) - }); - - let mut opaque_bundle = bundle_template.clone(); - opaque_bundle.sealed_header.header.primary_number = primary_number; - opaque_bundle.sealed_header.header.primary_hash = primary_hash; - opaque_bundle.sealed_header.signature = alice_key - .pair() - .sign(opaque_bundle.sealed_header.pre_hash().as_ref()) - .into(); - opaque_bundle.receipt = execution_receipt; - - subspace_test_runtime::UncheckedExtrinsic::new_unsigned( - pallet_domains::Call::submit_bundle { opaque_bundle }.into(), - ) - .into() - }; - - let ferdie_client = ferdie.client.clone(); - let head_receipt_number = || { - let best_hash = ferdie_client.info().best_hash; - ferdie_client - .runtime_api() - .head_receipt_number(best_hash, DomainId::SYSTEM) - .expect("Failed to get head receipt number") - }; - - ferdie - .submit_transaction(create_submit_bundle(1)) + produce_block_with!(ferdie.produce_block_with_slot(slot), bob) .await .unwrap(); - ferdie - .submit_transaction(create_submit_bundle(2)) - .await - .unwrap(); - produce_blocks!(ferdie, bob, 1).await.unwrap(); - assert_eq!(head_receipt_number(), 2); - // max drift is 2, hence the max allowed receipt number is 2 + 2, 5 will be rejected as being - // too far. - match ferdie - .submit_transaction(create_submit_bundle(5)) - .await - .unwrap_err() - { - sc_transaction_pool::error::Error::Pool( - sc_transaction_pool_api::error::Error::InvalidTransaction(invalid_tx), - ) => assert_eq!(invalid_tx, InvalidTransactionCode::ExecutionReceipt.into()), - e => panic!("Unexpected error while submitting execution receipt: {e}"), - } - - // The 4 is able to be submitted to tx pool but the execution will fail as the receipt of 3 is missing. - let submit_bundle_4 = create_submit_bundle(4); - ferdie - .submit_transaction(submit_bundle_4.clone()) - .await - .unwrap(); - assert!(ferdie.produce_blocks(1).await.is_err()); - assert_eq!(head_receipt_number(), 2); - - // Re-submit 4 after 3, this time the execution will succeed and the head receipt number will - // be updated. - ferdie.prune_tx_from_pool(&submit_bundle_4).unwrap(); - ferdie - .submit_transaction(create_submit_bundle(3)) - .await - .unwrap(); - ferdie - .submit_transaction(create_submit_bundle(4)) - .await - .unwrap(); - produce_blocks!(ferdie, bob, 1).await.unwrap(); - assert_eq!(head_receipt_number(), 4); + // let ferdie_client = ferdie.client.clone(); + // let create_submit_bundle = |consensus_block_number: BlockNumber| { + // let consensus_block_hash = ferdie_client.hash(consensus_block_number).unwrap().unwrap(); + // let execution_receipt = + // crate::aux_schema::load_execution_receipt(&*bob.backend, consensus_block_hash) + // .expect("Failed to load execution receipt from the local aux_db") + // .unwrap_or_else(|| { + // panic!( + // "The requested execution receipt for block {consensus_block_number} does not exist" + // ) + // }); + + // let mut opaque_bundle = bundle_template.clone(); + // opaque_bundle.sealed_header.header.consensus_block_number = consensus_block_number; + // opaque_bundle.sealed_header.header.consensus_block_hash = consensus_block_hash; + // opaque_bundle.sealed_header.signature = alice_key + // .pair() + // .sign(opaque_bundle.sealed_header.pre_hash().as_ref()) + // .into(); + // opaque_bundle.receipt = execution_receipt; + + // subspace_test_runtime::UncheckedExtrinsic::new_unsigned( + // pallet_domains::Call::submit_bundle { opaque_bundle }.into(), + // ) + // .into() + // }; + + // TODO: Unlock once `head_receipt_number` API is usable. + // let ferdie_client = ferdie.client.clone(); + // let head_receipt_number = || { + // let best_hash = ferdie_client.info().best_hash; + // ferdie_client + // .runtime_api() + // .head_receipt_number(best_hash, DomainId::SYSTEM) + // .expect("Failed to get head receipt number") + // }; + + // ferdie + // .submit_transaction(create_submit_bundle(1)) + // .await + // .unwrap(); + // produce_blocks!(ferdie, bob, 1).await.unwrap(); + // ferdie + // .submit_transaction(create_submit_bundle(2)) + // .await + // .unwrap(); + // produce_blocks!(ferdie, bob, 1).await.unwrap(); + // assert_eq!(head_receipt_number(), 2); } #[substrate_test_utils::test(flavor = "multi_thread")] @@ -887,37 +1241,39 @@ async fn duplicated_and_stale_bundle_should_be_rejected() { let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); - // Run Alice (a system domain authority node) - let alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; produce_blocks!(ferdie, alice, 1).await.unwrap(); let (slot, bundle) = ferdie.produce_slot_and_wait_for_bundle_submission().await; - let submit_bundle_tx = subspace_test_runtime::UncheckedExtrinsic::new_unsigned( - pallet_domains::Call::submit_bundle { - opaque_bundle: bundle.unwrap(), - } - .into(), - ) - .into(); + let submit_bundle_tx: OpaqueExtrinsic = + subspace_test_runtime::UncheckedExtrinsic::new_unsigned( + pallet_domains::Call::submit_bundle { + opaque_bundle: bundle.unwrap(), + } + .into(), + ) + .into(); - // Wait for one block to ensure the bundle is stored onchain and then manually remove it from tx pool. + // Wait for one block to ensure the bundle is stored onchain. produce_block_with!(ferdie.produce_block_with_slot(slot), alice) .await .unwrap(); - ferdie.prune_tx_from_pool(&submit_bundle_tx).unwrap(); // Bundle is rejected because it is duplicated. match ferdie @@ -925,28 +1281,23 @@ async fn duplicated_and_stale_bundle_should_be_rejected() { .await .unwrap_err() { - sc_transaction_pool::error::Error::Pool(err) => { - // Compare the error message of `TxPoolError::ImmediatelyDropped` here because - // `TxPoolError` didn't drive `PartialEq` - assert_eq!( - &err.to_string(), - "Transaction couldn't enter the pool because of the limit" - ); + sc_transaction_pool::error::Error::Pool(TxPoolError::InvalidTransaction(invalid_tx)) => { + assert_eq!(invalid_tx, InvalidTransactionCode::Bundle.into()) } e => panic!("Unexpected error: {e}"), } - // Wait for confirmation depth K blocks which is 100 in test - produce_blocks!(ferdie, alice, 100).await.unwrap(); + // Wait for `BlockTreePruningDepth + 1` blocks which is 16 + 1 in test + produce_blocks!(ferdie, alice, 17).await.unwrap(); - // Bundle is now rejected because it is stale. + // Bundle is now rejected because its receipt is pruned. match ferdie .submit_transaction(submit_bundle_tx) .await .unwrap_err() { sc_transaction_pool::error::Error::Pool(TxPoolError::InvalidTransaction(invalid_tx)) => { - assert_eq!(invalid_tx, InvalidTransactionCode::Bundle.into()) + assert_eq!(invalid_tx, InvalidTransactionCode::ExecutionReceipt.into()) } e => panic!("Unexpected error: {e}"), } @@ -963,19 +1314,21 @@ async fn existing_bundle_can_be_resubmitted_to_new_fork() { let tokio_handle = tokio::runtime::Handle::current(); // Start Ferdie - let mut ferdie = MockPrimaryNode::run_mock_primary_node( + let mut ferdie = MockConsensusNode::run( tokio_handle.clone(), Ferdie, BasePath::new(directory.path().join("ferdie")), ); + // Produce 1 consensus block to initialize genesis domain + ferdie.produce_block_with_slot(1.into()).await.unwrap(); - // Run Alice (a system domain authority node) - let alice = domain_test_service::SystemDomainNodeBuilder::new( + // Run Alice (a evm domain authority node) + let alice = domain_test_service::DomainNodeBuilder::new( tokio_handle.clone(), Alice, BasePath::new(directory.path().join("alice")), ) - .build_with_mock_primary_node(Role::Authority, &mut ferdie) + .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) .await; produce_blocks!(ferdie, alice, 3).await.unwrap(); @@ -1001,27 +1354,21 @@ async fn existing_bundle_can_be_resubmitted_to_new_fork() { .produce_block_with_slot_at(slot, parent_hash, Some(vec![])) .await .unwrap(); - produce_block_with!( - ferdie.produce_block_with_slot_at(slot + 1, parent_hash, Some(vec![])), - alice - ) - .await - .unwrap(); - - // Manually remove the retracted block's `submit_bundle_tx` from tx pool - ferdie.prune_tx_from_pool(&submit_bundle_tx).unwrap(); + ferdie + .produce_block_with_slot_at(slot + 1, parent_hash, Some(vec![])) + .await + .unwrap(); // Bundle can be successfully submitted to the new fork, or it is also possible // that the `submit_bundle_tx` in the retracted block has been resubmitted to the - // tx pool in the background by the `txpool-notifications` worker just after the above - // `prune_tx_from_pool` call. + // tx pool in the background by the `txpool-notifications` worker. match ferdie.submit_transaction(submit_bundle_tx).await { Ok(_) | Err(sc_transaction_pool::error::Error::Pool(TxPoolError::AlreadyImported(_))) => {} Err(err) => panic!("Unexpected error: {err}"), } } -// TODO: Unlock test when fixed (core-eth-relay was removed) +// TODO: Unlock test when multiple domains are supported in DecEx v2. // #[substrate_test_utils::test(flavor = "multi_thread")] // async fn test_cross_domains_message_should_work() { // let directory = TempDir::new().expect("Must be able to create temporary directory"); @@ -1033,24 +1380,24 @@ async fn existing_bundle_can_be_resubmitted_to_new_fork() { // let tokio_handle = tokio::runtime::Handle::current(); // // // Start Ferdie -// let mut ferdie = MockPrimaryNode::run_mock_primary_node( +// let mut ferdie = MockConsensusNode::run( // tokio_handle.clone(), // Ferdie, // BasePath::new(directory.path().join("ferdie")), // ); // // // Run Alice (a system domain authority node) -// let mut alice = domain_test_service::SystemDomainNodeBuilder::new( +// let mut alice = domain_test_service::DomainNodeBuilder::new( // tokio_handle.clone(), // Alice, // BasePath::new(directory.path().join("alice")), // ) // .run_relayer() -// .build_with_mock_primary_node(Role::Authority, &mut ferdie) +// .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) // .await; // // // Run Bob (a core payments domain authority node) -// let mut bob = domain_test_service::CoreDomainNodeBuilder::new( +// let mut bob = domain_test_service::DomainNodeBuilder::new( // tokio_handle.clone(), // Bob, // BasePath::new(directory.path().join("bob")), @@ -1060,7 +1407,7 @@ async fn existing_bundle_can_be_resubmitted_to_new_fork() { // .await; // // // Run Charlie (a core eth relay domain authority node) -// let mut charlie = domain_test_service::CoreDomainNodeBuilder::new( +// let mut charlie = domain_test_service::DomainNodeBuilder::new( // tokio_handle.clone(), // Charlie, // BasePath::new(directory.path().join("charlie")), @@ -1216,24 +1563,24 @@ async fn existing_bundle_can_be_resubmitted_to_new_fork() { // let tokio_handle = tokio::runtime::Handle::current(); // // Start Ferdie -// let mut ferdie = MockPrimaryNode::run_mock_primary_node( +// let mut ferdie = MockConsensusNode::run( // tokio_handle.clone(), // Ferdie, // BasePath::new(directory.path().join("ferdie")), // ); // // Run Alice (a system domain authority node) -// let mut alice = domain_test_service::SystemDomainNodeBuilder::new( +// let mut alice = domain_test_service::DomainNodeBuilder::new( // tokio_handle.clone(), // Alice, // BasePath::new(directory.path().join("alice")), // ) // .run_relayer() -// .build_with_mock_primary_node(Role::Authority, &mut ferdie) +// .build_evm_node(Role::Authority, GENESIS_DOMAIN_ID, &mut ferdie) // .await; // // Run Bob (a core payments domain authority node) -// let mut bob = domain_test_service::CoreDomainNodeBuilder::new( +// let mut bob = domain_test_service::DomainNodeBuilder::new( // tokio_handle.clone(), // Bob, // BasePath::new(directory.path().join("bob")), @@ -1243,7 +1590,7 @@ async fn existing_bundle_can_be_resubmitted_to_new_fork() { // .await; // // Run Charlie (a core eth relay domain full node) and don't its relayer worker -// let charlie = domain_test_service::CoreDomainNodeBuilder::new( +// let charlie = domain_test_service::DomainNodeBuilder::new( // tokio_handle.clone(), // Charlie, // BasePath::new(directory.path().join("charlie")), diff --git a/domains/client/domain-executor/src/utils.rs b/domains/client/domain-operator/src/utils.rs similarity index 51% rename from domains/client/domain-executor/src/utils.rs rename to domains/client/domain-operator/src/utils.rs index 42dcb186f2e..262cbb7bfe0 100644 --- a/domains/client/domain-executor/src/utils.rs +++ b/domains/client/domain-operator/src/utils.rs @@ -1,19 +1,18 @@ -use codec::{Decode, Encode}; use parking_lot::Mutex; use sc_utils::mpsc::{TracingUnboundedReceiver, TracingUnboundedSender}; use sp_consensus_slots::Slot; use sp_runtime::traits::{Block as BlockT, NumberFor}; use std::convert::TryInto; use std::sync::Arc; -use subspace_core_primitives::{Blake2b256Hash, BlockNumber}; +use subspace_core_primitives::{BlockNumber, Randomness}; /// Data required to produce bundles on executor node. #[derive(PartialEq, Clone, Debug)] -pub(super) struct ExecutorSlotInfo { +pub(super) struct OperatorSlotInfo { /// Slot pub(super) slot: Slot, - /// Global challenge - pub(super) global_challenge: Blake2b256Hash, + /// Global randomness + pub(super) global_randomness: Randomness, } #[derive(Debug, Clone)] @@ -27,17 +26,8 @@ where pub parent_hash: Block::Hash, /// block's number. pub number: NumberFor, -} - -// TODO: unify this with trait bounds set directly on block traits. -// Maybe we dont need these translations.? -/// Converts the block number from the generic type `N1` to `N2`. -pub(crate) fn translate_number_type(block_number: N1) -> N2 -where - N1: TryInto, - N2: From, -{ - N2::from(to_number_primitive(block_number)) + /// Is this the new best block. + pub is_new_best: bool, } /// Converts a generic block number to a concrete primitive block number. @@ -50,23 +40,14 @@ where .unwrap_or_else(|_| panic!("Block number must fit into u32; qed")) } -/// Converts the block hash from the generic type `B1::Hash` to `B2::Hash`. -pub(crate) fn translate_block_hash_type(block_hash: B1::Hash) -> B2::Hash -where - B1: BlockT, - B2: BlockT, -{ - B2::Hash::decode(&mut block_hash.encode().as_slice()).unwrap() -} - -pub type DomainImportNotificationSinks = - Arc>>>>; +pub type DomainImportNotificationSinks = + Arc>>>>; -pub type DomainImportNotifications = - TracingUnboundedReceiver>; +pub type DomainImportNotifications = + TracingUnboundedReceiver>; #[derive(Clone, Debug)] -pub struct DomainBlockImportNotification { +pub struct DomainBlockImportNotification { pub domain_block_hash: Block::Hash, - pub primary_block_hash: PBlock::Hash, + pub consensus_block_hash: CBlock::Hash, } diff --git a/domains/client/eth-service/Cargo.toml b/domains/client/eth-service/Cargo.toml index 66281d08107..841d179fc3b 100644 --- a/domains/client/eth-service/Cargo.toml +++ b/domains/client/eth-service/Cargo.toml @@ -15,27 +15,27 @@ include = [ clap = { version = "4.2.1", features = ["derive"] } domain-runtime-primitives = { version = "0.1.0", path = "../../primitives/runtime" } domain-service = { version = "0.1.0", path = "../../service" } -fc-consensus = { version = "2.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } -fc-db = { version = "2.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } -fc-mapping-sync = { version = "2.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } -fc-rpc = { version = "2.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4", features = ['rpc-binary-search-estimate'] } -fc-rpc-core = { version = "1.1.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } -fc-storage = { version = "1.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } -fp-rpc = { version = "3.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4", features = ['default'] } +fc-consensus = { version = "2.0.0-dev", git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +fc-db = { version = "2.0.0-dev", git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +fc-mapping-sync = { version = "2.0.0-dev", git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +fc-rpc = { version = "2.0.0-dev", git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3", features = ['rpc-binary-search-estimate'] } +fc-rpc-core = { version = "1.1.0-dev", git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +fc-storage = { version = "1.0.0-dev", git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +fp-rpc = { version = "3.0.0-dev", git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3", features = ['default'] } futures = "0.3.28" jsonrpsee = { version = "0.16.2", features = ["server"] } -pallet-transaction-payment-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-transaction-payment-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } serde = { version = "1.0.159", features = ["derive"] } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -substrate-frame-rpc-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +substrate-frame-rpc-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } diff --git a/domains/client/executor-gossip/Cargo.toml b/domains/client/executor-gossip/Cargo.toml deleted file mode 100644 index 11bfd38e6a1..00000000000 --- a/domains/client/executor-gossip/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "domain-client-executor-gossip" -version = "0.1.0" -authors = ["Liu-Cheng Xu "] -edition = "2021" - -[dependencies] -futures = "0.3.28" -parity-scale-codec = { version = "3.4.0", features = ["derive"] } -parking_lot = "0.12.1" -sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -tracing = "0.1.37" diff --git a/domains/client/relayer/Cargo.toml b/domains/client/relayer/Cargo.toml index b48f577034d..9a23537e72c 100644 --- a/domains/client/relayer/Cargo.toml +++ b/domains/client/relayer/Cargo.toml @@ -16,20 +16,18 @@ async-channel = "1.8.0" cross-domain-message-gossip = { path = "../../client/cross-domain-message-gossip" } domain-runtime-primitives = { path = "../../primitives/runtime" } futures = "0.3.28" -parity-scale-codec = { version = "3.4.0", features = ["derive"] } +parity-scale-codec = { version = "3.6.3", features = ["derive"] } parking_lot = "0.12.1" -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } sp-messenger = { version = "0.1.0", path = "../../primitives/messenger" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", path = "../../../crates/sp-settlement" } -system-runtime-primitives = { version = "0.1.0", path = "../../primitives/system-runtime" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } tracing = "0.1.37" diff --git a/domains/client/relayer/src/lib.rs b/domains/client/relayer/src/lib.rs index 01580ed68ad..2d15e762b1d 100644 --- a/domains/client/relayer/src/lib.rs +++ b/domains/client/relayer/src/lib.rs @@ -4,17 +4,16 @@ pub mod worker; use async_channel::TrySendError; use cross_domain_message_gossip::Message as GossipMessage; -use parity_scale_codec::{Decode, Encode, FullCodec}; -use sc_client_api::{AuxStore, HeaderBackend, ProofProvider, StorageProof}; +use parity_scale_codec::{Decode, Encode}; +use sc_client_api::{AuxStore, HeaderBackend, ProofProvider}; use sc_utils::mpsc::TracingUnboundedSender; use sp_api::ProvideRuntimeApi; use sp_domains::DomainId; use sp_messenger::messages::{ - CoreDomainStateRootStorage, CrossDomainMessage, DomainBlockInfo, Proof, - RelayerMessageWithStorageKey, RelayerMessagesWithStorageKey, + CrossDomainMessage, DomainBlockInfo, Proof, RelayerMessageWithStorageKey, + RelayerMessagesWithStorageKey, }; use sp_messenger::RelayerApi; -use sp_runtime::scale_info::TypeInfo; use sp_runtime::traits::{Block as BlockT, CheckedSub, Header as HeaderT, NumberFor, One, Zero}; use sp_runtime::ArithmeticError; use std::marker::PhantomData; @@ -96,15 +95,6 @@ where .map_err(|_| Error::UnableToFetchDomainId) } - pub(crate) fn relay_confirmation_depth( - client: &Arc, - ) -> Result, Error> { - let best_block_id = client.info().best_hash; - let api = client.runtime_api(); - api.relay_confirmation_depth(best_block_id) - .map_err(|_| Error::UnableToFetchRelayConfirmationDepth) - } - /// Constructs the proof for the given key using the system domain backend. fn construct_system_domain_storage_proof_for_key_at( system_domain_client: &Arc, @@ -131,45 +121,6 @@ where .ok_or(Error::ConstructStorageProof) } - /// Constructs the proof for the given key using the core domain backend. - fn construct_core_domain_storage_proof_for_key_at( - system_domain_info: DomainBlockInfo, - core_domain_client: &Arc, - block_hash: Block::Hash, - key: &[u8], - system_domain_state_root: SHash, - core_domain_proof: StorageProof, - ) -> Result, Error> - where - SNumber: Into>, - SHash: Into, - { - core_domain_client - .header(block_hash)? - .map(|header| (*header.number(), header.hash())) - .and_then(|(number, hash)| { - let proof = core_domain_client - .read_proof(block_hash, &mut [key].into_iter()) - .ok()?; - Some(Proof { - system_domain_block_info: DomainBlockInfo { - block_number: system_domain_info.block_number.into(), - block_hash: system_domain_info.block_hash.into(), - }, - system_domain_state_root: system_domain_state_root.into(), - core_domain_proof: Some(( - DomainBlockInfo { - block_number: number, - block_hash: hash, - }, - core_domain_proof, - )), - message_proof: proof, - }) - }) - .ok_or(Error::ConstructStorageProof) - } - fn construct_cross_domain_message_and_submit< Submitter: Fn(CrossDomainMessage, Block::Hash, Block::Hash>) -> Result<(), Error>, ProofConstructor: Fn(Block::Hash, &[u8]) -> Result, Block::Hash, Block::Hash>, Error>, @@ -297,138 +248,6 @@ where Ok(()) } - pub(crate) fn submit_messages_from_core_domain( - relayer_id: RelayerId, - core_domain_client: &Arc, - system_domain_client: &Arc, - confirmed_block_hash: Block::Hash, - gossip_message_sink: &GossipMessageSink, - relay_confirmation_depth: NumberFor, - ) -> Result<(), Error> - where - SBlock: BlockT, - Block::Hash: FullCodec, - NumberFor: FullCodec + TypeInfo, - NumberFor: From> + Into>, - SBlock::Hash: Into + From, - SDC: HeaderBackend + ProvideRuntimeApi + ProofProvider, - SDC::Api: RelayerApi>, - { - let core_domain_id = Self::domain_id(core_domain_client)?; - let core_domain_block_header = core_domain_client.expect_header(confirmed_block_hash)?; - let system_domain_api = system_domain_client.runtime_api(); - let best_system_domain_block_hash = system_domain_client.info().best_hash; - let best_system_domain_block_header = - system_domain_client.expect_header(best_system_domain_block_hash)?; - - // verify if the core domain number is K-deep on System domain client - if !system_domain_api - .domain_best_number(best_system_domain_block_hash, core_domain_id)? - .map( - |best_number| match best_number.checked_sub(&relay_confirmation_depth) { - None => false, - Some(best_confirmed) => { - best_confirmed >= (*core_domain_block_header.number()).into() - } - }, - ) - .unwrap_or(false) - { - return Err(Error::CoreDomainNonConfirmedOnSystemDomain); - } - - // verify if the state root is matching. - let core_domain_number = *core_domain_block_header.number(); - if !system_domain_api - .domain_state_root( - best_system_domain_block_hash, - core_domain_id, - core_domain_number.into(), - confirmed_block_hash.into(), - )? - .map(|state_root| state_root == (*core_domain_block_header.state_root()).into()) - .unwrap_or_else(|| { - // if this is genesis block, ignore as state root of genesis for core domain is not tracked on runtime - core_domain_number.is_zero() - }) - { - tracing::error!( - target: LOG_TARGET, - "Core domain state root mismatch at: Number: {:?}, Hash: {:?}", - core_domain_number, - confirmed_block_hash - ); - return Err(Error::CoreDomainStateRootInvalid); - } - - // fetch messages to be relayed - let core_domain_api = core_domain_client.runtime_api(); - let assigned_messages: RelayerMessagesWithStorageKey = core_domain_api - .relayer_assigned_messages(confirmed_block_hash, relayer_id) - .map_err(|_| Error::FetchAssignedMessages)?; - - let filtered_messages = - Self::filter_assigned_messages(core_domain_client, assigned_messages)?; - - // short circuit if the there are no messages to relay - if filtered_messages.outbox.is_empty() && filtered_messages.inbox_responses.is_empty() { - return Ok(()); - } - - // generate core domain proof that points to the state root of the core domain block on System domain. - let storage_key = - CoreDomainStateRootStorage::, Block::Hash, Block::Hash>::storage_key( - core_domain_id, - *core_domain_block_header.number(), - core_domain_block_header.hash(), - ); - - // construct storage proof for the core domain state root using system domain backend. - let core_domain_state_root_proof = system_domain_client.read_proof( - best_system_domain_block_hash, - &mut [storage_key.as_ref()].into_iter(), - )?; - - let system_domain_block_info = DomainBlockInfo { - block_number: *best_system_domain_block_header.number(), - block_hash: best_system_domain_block_hash, - }; - - Self::construct_cross_domain_message_and_submit( - confirmed_block_hash, - filtered_messages.outbox, - |block_hash, key| { - Self::construct_core_domain_storage_proof_for_key_at( - system_domain_block_info.clone(), - core_domain_client, - block_hash, - key, - *best_system_domain_block_header.state_root(), - core_domain_state_root_proof.clone(), - ) - }, - |msg| Self::gossip_outbox_message(core_domain_client, msg, gossip_message_sink), - )?; - - Self::construct_cross_domain_message_and_submit( - confirmed_block_hash, - filtered_messages.inbox_responses, - |block_id, key| { - Self::construct_core_domain_storage_proof_for_key_at( - system_domain_block_info.clone(), - core_domain_client, - block_id, - key, - *best_system_domain_block_header.state_root(), - core_domain_state_root_proof.clone(), - ) - }, - |msg| Self::gossip_inbox_message_response(core_domain_client, msg, gossip_message_sink), - )?; - - Ok(()) - } - /// Sends an Outbox message from src_domain to dst_domain. fn gossip_outbox_message( client: &Arc, diff --git a/domains/client/relayer/src/worker.rs b/domains/client/relayer/src/worker.rs index d7f4ced29cd..f3403af2624 100644 --- a/domains/client/relayer/src/worker.rs +++ b/domains/client/relayer/src/worker.rs @@ -1,14 +1,12 @@ use crate::{BlockT, Error, GossipMessageSink, HeaderBackend, HeaderT, Relayer, LOG_TARGET}; use futures::StreamExt; -use parity_scale_codec::{Decode, Encode, FullCodec}; +use parity_scale_codec::{Decode, Encode}; use sc_client_api::{AuxStore, BlockchainEvents, ProofProvider}; use sp_api::{ApiError, ProvideRuntimeApi}; use sp_consensus::SyncOracle; use sp_domains::DomainId; use sp_messenger::RelayerApi; -use sp_runtime::scale_info::TypeInfo; use sp_runtime::traits::{CheckedSub, NumberFor, Zero}; -use sp_settlement::SettlementApi; use std::sync::Arc; /// Starts relaying system domain messages to other domains. @@ -62,81 +60,6 @@ pub async fn relay_system_domain_messages( } } -/// Starts relaying core domain messages to other domains. -/// If the either system domain or core domain node is in major sync, -/// worker waits waits until the sync is finished. -pub async fn relay_core_domain_messages( - relayer_id: RelayerId, - core_domain_client: Arc, - system_domain_client: Arc, - system_domain_sync_oracle: SDSO, - core_domain_sync_oracle: CDSO, - gossip_message_sink: GossipMessageSink, -) where - Block: BlockT, - PBlock: BlockT, - SBlock: BlockT, - Block::Hash: FullCodec, - NumberFor: FullCodec + TypeInfo, - NumberFor: From> + Into>, - SBlock::Hash: Into + From, - CDC: BlockchainEvents - + HeaderBackend - + AuxStore - + ProofProvider - + ProvideRuntimeApi, - CDC::Api: RelayerApi>, - SDC: HeaderBackend + ProvideRuntimeApi + ProofProvider, - SDC::Api: RelayerApi> - + SettlementApi, - SDSO: SyncOracle + Send, - CDSO: SyncOracle + Send, - RelayerId: Encode + Decode + Clone, -{ - let combined_sync_oracle = - CombinedSyncOracle::new(system_domain_sync_oracle, core_domain_sync_oracle); - - let relay_confirmation_depth = match Relayer::relay_confirmation_depth(&core_domain_client) { - Ok(depth) => depth, - Err(err) => { - tracing::error!(target: LOG_TARGET, ?err, "Failed to get confirmation depth"); - return; - } - }; - - let result = relay_domain_messages( - relayer_id, - relay_confirmation_depth, - core_domain_client, - |relayer_id, client, block_hash| { - Relayer::submit_messages_from_core_domain( - relayer_id, - client, - &system_domain_client, - block_hash, - &gossip_message_sink, - relay_confirmation_depth.into(), - ) - }, - combined_sync_oracle, - |domain_id, block_number| -> Result { - let api = system_domain_client.runtime_api(); - let at = system_domain_client.info().best_hash; - let oldest_tracked_number = api.oldest_receipt_number(at, domain_id)?; - // ensure block number is at least the oldest tracked number - Ok(block_number >= oldest_tracked_number.into()) - }, - ) - .await; - if let Err(err) = result { - tracing::error!( - target: LOG_TARGET, - ?err, - "Failed to start relayer for core domain" - ) - } -} - async fn relay_domain_messages( relayer_id: RelayerId, relay_confirmation_depth: NumberFor, @@ -273,6 +196,8 @@ where impl CombinedSyncOracle { /// Returns a new sync oracle that wraps system domain and core domain sync oracle. + // TODO: Remove or make use of it. + #[allow(unused)] fn new(system_domain_sync_oracle: SDSO, core_domain_sync_oracle: CDSO) -> Self { CombinedSyncOracle { system_domain_sync_oracle, diff --git a/domains/client/subnet-gossip/Cargo.toml b/domains/client/subnet-gossip/Cargo.toml new file mode 100644 index 00000000000..ac4386d7208 --- /dev/null +++ b/domains/client/subnet-gossip/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "domain-client-subnet-gossip" +version = "0.1.0" +authors = ["Liu-Cheng Xu "] +edition = "2021" + +[dependencies] +futures = "0.3.28" +parity-scale-codec = { version = "3.6.3", features = ["derive"] } +parking_lot = "0.12.1" +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-gossip = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives" } +tracing = "0.1.37" diff --git a/domains/client/executor-gossip/src/lib.rs b/domains/client/subnet-gossip/src/lib.rs similarity index 70% rename from domains/client/executor-gossip/src/lib.rs rename to domains/client/subnet-gossip/src/lib.rs index 5fc944f40b3..389a98f67ce 100644 --- a/domains/client/executor-gossip/src/lib.rs +++ b/domains/client/subnet-gossip/src/lib.rs @@ -1,3 +1,10 @@ +//! This crate is intended to provide the feature of gossiping bundles over the domain subnet. +//! However, it's unused at present as it's not yet fully implemented. +//! +//! We may enable this feature in the future: +//! 1. Implement the [`GossipMessageHandler`] somewhere. +//! 2. Run the gossip worker using `start_gossip_worker` when building the service. + mod worker; use self::worker::GossipWorker; @@ -19,10 +26,20 @@ use std::fmt::Debug; use std::marker::PhantomData; use std::sync::Arc; use std::time::{Duration, Instant}; +use subspace_runtime_primitives::Balance; + +const LOG_TARGET: &str = "gossip::operator"; -const LOG_TARGET: &str = "gossip::executor"; +const DOMAIN_SUBNET_PROTOCOL_NAME: &str = "/subspace/operator/1"; -const EXECUTOR_PROTOCOL_NAME: &str = "/subspace/executor/1"; +type BundleFor = Bundle< + ::Extrinsic, + NumberFor, + ::Hash, + NumberFor, + ::Hash, + Balance, +>; // TODO: proper timeout /// Timeout for rebroadcasting messages. @@ -33,33 +50,30 @@ type MessageHash = [u8; 8]; /// Returns the configuration value to use in /// [`sc_network::config::FullNetworkConfiguration::add_notification_protocol`]. -pub fn executor_gossip_peers_set_config() -> NonDefaultSetConfig { - let mut cfg = NonDefaultSetConfig::new(EXECUTOR_PROTOCOL_NAME.into(), 1024 * 1024); +pub fn domain_subnet_gossip_peers_set_config() -> NonDefaultSetConfig { + let mut cfg = NonDefaultSetConfig::new(DOMAIN_SUBNET_PROTOCOL_NAME.into(), 1024 * 1024); cfg.allow_non_reserved(25, 25); cfg } /// Gossip engine messages topic. fn topic() -> Block::Hash { - <::Hashing as HashT>::hash(b"executor") + <::Hashing as HashT>::hash(b"operator") } -/// Executor gossip message type. +/// Operator gossip message type. /// /// This is the root type that gets encoded and sent on the network. #[derive(Debug, Encode, Decode)] -pub enum GossipMessage { - Bundle(Bundle, PBlock::Hash, Block::Hash>), +pub enum GossipMessage { + Bundle(BundleFor), } -impl - From, PBlock::Hash, Block::Hash>> - for GossipMessage +impl From> + for GossipMessage { #[inline] - fn from( - bundle: Bundle, PBlock::Hash, Block::Hash>, - ) -> Self { + fn from(bundle: BundleFor) -> Self { Self::Bundle(bundle) } } @@ -81,43 +95,40 @@ impl Action { } } -/// Handler for the messages received from the executor gossip network. -pub trait GossipMessageHandler +/// Handler for the messages received from the domain subnet. +pub trait GossipMessageHandler where - PBlock: BlockT, + CBlock: BlockT, Block: BlockT, { /// Error type. type Error: Debug; /// Validates and applies when a transaction bundle was received. - fn on_bundle( - &self, - bundle: &Bundle, PBlock::Hash, Block::Hash>, - ) -> Result; + fn on_bundle(&self, bundle: &BundleFor) -> Result; } /// Validator for the gossip messages. -pub struct GossipValidator +pub struct GossipValidator where - PBlock: BlockT, + CBlock: BlockT, Block: BlockT, - Executor: GossipMessageHandler, + Operator: GossipMessageHandler, { topic: Block::Hash, - executor: Executor, + executor: Operator, next_rebroadcast: Mutex, known_rebroadcasted: RwLock>, - _phantom_data: PhantomData, + _phantom_data: PhantomData, } -impl GossipValidator +impl GossipValidator where - PBlock: BlockT, + CBlock: BlockT, Block: BlockT, - Executor: GossipMessageHandler, + Operator: GossipMessageHandler, { - pub fn new(executor: Executor) -> Self { + pub fn new(executor: Operator) -> Self { Self { topic: topic::(), executor, @@ -132,7 +143,7 @@ where known_rebroadcasted.insert(twox_64(encoded_message)); } - fn validate_message(&self, msg: GossipMessage) -> ValidationResult { + fn validate_message(&self, msg: GossipMessage) -> ValidationResult { match msg { GossipMessage::Bundle(bundle) => { let outcome = self.executor.on_bundle(&bundle); @@ -155,11 +166,11 @@ where } } -impl Validator for GossipValidator +impl Validator for GossipValidator where - PBlock: BlockT, + CBlock: BlockT, Block: BlockT, - Executor: GossipMessageHandler + Send + Sync, + Operator: GossipMessageHandler + Send + Sync, { fn new_peer( &self, @@ -177,7 +188,7 @@ where _sender: &PeerId, mut data: &[u8], ) -> ValidationResult { - match GossipMessage::::decode(&mut data) { + match GossipMessage::::decode(&mut data) { Ok(msg) => { tracing::debug!(target: LOG_TARGET, ?msg, "Validating incoming message"); self.validate_message(msg) @@ -202,7 +213,7 @@ where Box::new(move |_topic, mut data| { let msg_hash = twox_64(data); // TODO: can be expired due to the message itself might be too old? - let _msg = match GossipMessage::::decode(&mut data) { + let _msg = match GossipMessage::::decode(&mut data) { Ok(msg) => msg, Err(_) => return true, }; @@ -240,54 +251,47 @@ where return do_rebroadcast; } - GossipMessage::::decode(&mut data).is_ok() + GossipMessage::::decode(&mut data).is_ok() }) } } -type BundleReceiver = TracingUnboundedReceiver< - Bundle< - ::Extrinsic, - NumberFor, - ::Hash, - ::Hash, - >, ->; +type BundleReceiver = TracingUnboundedReceiver>; /// Parameters to run the executor gossip service. -pub struct ExecutorGossipParams { +pub struct ExecutorGossipParams { /// Substrate network service. pub network: Network, /// Syncing service an event stream for peers. pub sync: Arc, - /// Executor instance. - pub executor: Executor, + /// Operator instance. + pub operator: Operator, /// Stream of transaction bundle produced locally. - pub bundle_receiver: BundleReceiver, + pub bundle_receiver: BundleReceiver, } /// Starts the executor gossip worker. -pub async fn start_gossip_worker( - gossip_params: ExecutorGossipParams, +pub async fn start_gossip_worker( + gossip_params: ExecutorGossipParams, ) where - PBlock: BlockT, + CBlock: BlockT, Block: BlockT, Network: GossipNetwork + Send + Sync + Clone + 'static, - Executor: GossipMessageHandler + Send + Sync + 'static, + Operator: GossipMessageHandler + Send + Sync + 'static, GossipSync: GossipSyncing + 'static, { let ExecutorGossipParams { network, sync, - executor, + operator, bundle_receiver, } = gossip_params; - let gossip_validator = Arc::new(GossipValidator::new(executor)); + let gossip_validator = Arc::new(GossipValidator::new(operator)); let gossip_engine = GossipEngine::new( network, sync, - EXECUTOR_PROTOCOL_NAME, + DOMAIN_SUBNET_PROTOCOL_NAME, gossip_validator.clone(), None, ); diff --git a/domains/client/executor-gossip/src/worker.rs b/domains/client/subnet-gossip/src/worker.rs similarity index 70% rename from domains/client/executor-gossip/src/worker.rs rename to domains/client/subnet-gossip/src/worker.rs index 4b92a843dfa..fe444858c14 100644 --- a/domains/client/executor-gossip/src/worker.rs +++ b/domains/client/subnet-gossip/src/worker.rs @@ -1,36 +1,36 @@ use crate::{ - topic, BundleReceiver, GossipMessage, GossipMessageHandler, GossipValidator, LOG_TARGET, + topic, BundleFor, BundleReceiver, GossipMessage, GossipMessageHandler, GossipValidator, + LOG_TARGET, }; use futures::{future, FutureExt, StreamExt}; use parity_scale_codec::{Decode, Encode}; use parking_lot::Mutex; use sc_network_gossip::GossipEngine; -use sp_domains::Bundle; -use sp_runtime::traits::{Block as BlockT, NumberFor}; +use sp_runtime::traits::Block as BlockT; use std::sync::Arc; /// A worker plays the executor gossip protocol. -pub struct GossipWorker +pub struct GossipWorker where - PBlock: BlockT, + CBlock: BlockT, Block: BlockT, - Executor: GossipMessageHandler, + Executor: GossipMessageHandler, { - gossip_validator: Arc>, + gossip_validator: Arc>, gossip_engine: Arc>>, - bundle_receiver: BundleReceiver, + bundle_receiver: BundleReceiver, } -impl GossipWorker +impl GossipWorker where - PBlock: BlockT, + CBlock: BlockT, Block: BlockT, - Executor: GossipMessageHandler, + Executor: GossipMessageHandler, { pub(super) fn new( - gossip_validator: Arc>, + gossip_validator: Arc>, gossip_engine: Arc>>, - bundle_receiver: BundleReceiver, + bundle_receiver: BundleReceiver, ) -> Self { Self { gossip_validator, @@ -39,11 +39,8 @@ where } } - fn gossip_bundle( - &self, - bundle: Bundle, PBlock::Hash, Block::Hash>, - ) { - let outgoing_message: GossipMessage = bundle.into(); + fn gossip_bundle(&self, bundle: BundleFor) { + let outgoing_message: GossipMessage = bundle.into(); let encoded_message = outgoing_message.encode(); self.gossip_validator.note_rebroadcasted(&encoded_message); self.gossip_engine @@ -57,7 +54,7 @@ where .lock() .messages_for(topic::()) .filter_map(|notification| async move { - GossipMessage::::decode(&mut ¬ification.message[..]).ok() + GossipMessage::::decode(&mut ¬ification.message[..]).ok() }), ); diff --git a/domains/pallets/domain-id/Cargo.toml b/domains/pallets/domain-id/Cargo.toml new file mode 100644 index 00000000000..3b5fc54a26a --- /dev/null +++ b/domains/pallets/domain-id/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "pallet-domain-id" +version = "0.1.0" +authors = ["Subspace Labs "] +edition = "2021" +license = "Apache-2.0" +homepage = "https://subspace.network" +repository = "https://github.com/subspace/subspace" +description = "Subspace node pallet to store domain id." +include = [ + "/src", + "/Cargo.toml", +] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } +sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-support/std", + "frame-system/std", + "scale-info/std", + "sp-domains/std", +] diff --git a/domains/pallets/domain-id/src/lib.rs b/domains/pallets/domain-id/src/lib.rs new file mode 100644 index 00000000000..655739a6a97 --- /dev/null +++ b/domains/pallets/domain-id/src/lib.rs @@ -0,0 +1,53 @@ +// Copyright (C) 2023 Subspace Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Pallet Domain Id + +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::*; + use sp_domains::DomainId; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::storage] + pub(super) type SelfDomainId = StorageValue<_, DomainId, ValueQuery>; + + /// Pallet domain-id to store self domain id. + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[derive(Default)] + #[pallet::genesis_config] + pub struct GenesisConfig { + pub domain_id: Option, + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + SelfDomainId::::set( + self.domain_id + .expect("Genesis config of pallet-domain-id must be set"), + ); + } + } +} diff --git a/domains/pallets/domain-registry/Cargo.toml b/domains/pallets/domain-registry/Cargo.toml deleted file mode 100644 index 7b9449fe211..00000000000 --- a/domains/pallets/domain-registry/Cargo.toml +++ /dev/null @@ -1,64 +0,0 @@ -[package] -name = "pallet-domain-registry" -version = "0.1.0" -authors = ["Liu-Cheng Xu "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://subspace.network" -repository = "https://github.com/subspace/subspace/" -description = "System domain pallet for the domains management" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -frame-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -log = { version = "0.4.19", default-features = false } -pallet-settlement = { version = "0.1.0", default-features = false, path = "../../../crates/pallet-settlement" } -scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.159", optional = true } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains", default-features = false } -sp-domain-digests = { version = "0.1.0", path = "../../primitives/digests", default-features = false } -sp-executor-registry = { version = "0.1.0", path = "../../primitives/executor-registry", default-features = false } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-std = { version = "8.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-trie = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } - -[dev-dependencies] -pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-executor-registry = { version = "0.1.0", path = "../executor-registry" } -sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } - -[features] -default = ["std"] -std = [ - "codec/std", - "frame-benchmarking?/std", - "frame-support/std", - "frame-system/std", - "log/std", - "pallet-settlement/std", - "scale-info/std", - "serde/std", - "sp-core/std", - "sp-domains/std", - "sp-domain-digests/std", - "sp-executor-registry/std", - "sp-runtime/std", - "sp-std/std", - "sp-trie/std", -] -try-runtime = ["frame-support/try-runtime"] -runtime-benchmarks = [ - "frame-benchmarking", - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-executor-registry/runtime-benchmarks", - "sp-domains/runtime-benchmarks", - "sp-executor-registry/runtime-benchmarks", -] diff --git a/domains/pallets/domain-registry/src/benchmarking.rs b/domains/pallets/domain-registry/src/benchmarking.rs deleted file mode 100644 index 2bb86955d60..00000000000 --- a/domains/pallets/domain-registry/src/benchmarking.rs +++ /dev/null @@ -1,272 +0,0 @@ -//! Benchmarking for `pallet-domain-registry`. - -use super::*; -use crate::Pallet as DomainRegistry; -use frame_benchmarking::v2::*; -use frame_support::assert_ok; -use frame_support::traits::Hooks; -use frame_system::{Pallet as System, RawOrigin}; -use sp_core::crypto::ByteArray; -use sp_domain_digests::AsPredigest; -use sp_domains::fraud_proof::{dummy_invalid_state_transition_proof, FraudProof}; -use sp_domains::{create_dummy_bundle_with_receipts_generic, ExecutionReceipt, ExecutorPublicKey}; -use sp_runtime::traits::SaturatedConversion; -use sp_runtime::{Digest, DigestItem, Percent}; - -const SEED: u32 = 0; -const TEST_CORE_DOMAIN_ID: DomainId = DomainId::CORE_PAYMENTS; - -#[benchmarks] -mod benchmarks { - use super::*; - - #[benchmark] - fn create_domain() { - let domain_deposit = T::MinDomainDeposit::get(); - let creator = funded_account::("creator", 1, domain_deposit); - - let domain_id = NextDomainId::::get(); - let domain_config = sp_domains::DomainConfig { - wasm_runtime_hash: Default::default(), - max_bundle_size: 1024 * 1024, - bundle_slot_probability: (1, 1), - max_bundle_weight: Weight::MAX, - min_operator_stake: T::MinDomainOperatorStake::get(), - }; - - #[extrinsic_call] - _( - RawOrigin::Signed(creator.clone()), - domain_deposit, - domain_config.clone(), - ); - - assert_eq!(NextDomainId::::get(), domain_id + 1); - assert_eq!(Domains::::get(domain_id), Some(domain_config)); - assert_eq!( - DomainCreators::::get(domain_id, creator), - Some(domain_deposit) - ); - } - - #[benchmark] - fn register_domain_operator() { - let operator_stake = T::MinDomainOperatorStake::get(); - let domain_deposit = T::MinDomainDeposit::get(); - let operator = funded_account::("operator", 1, operator_stake + domain_deposit); - - let domain_id = create_helper_domain::(operator.clone(), domain_deposit); - registry_executor::(operator.clone(), T::MinDomainOperatorStake::get()); - - #[extrinsic_call] - _( - RawOrigin::Signed(operator.clone()), - domain_id, - Percent::one(), - ); - - assert_eq!( - DomainOperators::::get(operator, domain_id), - Some(Percent::one()) - ); - } - - #[benchmark] - fn deregister_domain_operator() { - let operator_stake = T::MinDomainOperatorStake::get(); - let domain_deposit = T::MinDomainDeposit::get(); - let operator = funded_account::("operator", 1, operator_stake + domain_deposit); - - let domain_id = create_helper_domain::(operator.clone(), domain_deposit); - registry_executor::(operator.clone(), T::MinDomainOperatorStake::get()); - - // register the domain operator first - assert_ok!(DomainRegistry::::do_domain_stake_update( - operator.clone(), - domain_id, - Percent::one() - )); - assert_eq!( - DomainOperators::::get(&operator, domain_id), - Some(Percent::one()) - ); - - #[extrinsic_call] - _(RawOrigin::Signed(operator.clone()), domain_id); - - assert!(DomainOperators::::get(operator, domain_id).is_none()); - } - - /// Benchmark `submit_core_bundle` extrinsic with the worst possible conditions: - /// - The receipts will prune a expired receipt - #[benchmark] - fn submit_core_bundle() { - let receipts_pruning_depth = T::ReceiptsPruningDepth::get().saturated_into::(); - - // Import `ReceiptsPruningDepth` number of receipts which will be pruned later - run_to_block::(1, receipts_pruning_depth); - for i in 0..receipts_pruning_depth { - let receipt = ExecutionReceipt::dummy(i.into(), block_hash_n::(i)); - let bundle = create_dummy_bundle_with_receipts_generic( - TEST_CORE_DOMAIN_ID, - (i + 1).into(), - Default::default(), - receipt, - ); - assert_ok!(DomainRegistry::::submit_core_bundle( - RawOrigin::None.into(), - bundle - )); - } - assert_eq!( - DomainRegistry::::head_receipt_number(TEST_CORE_DOMAIN_ID), - (receipts_pruning_depth - 1).into() - ); - - // Construct a bundle that contains a new receipts - run_to_block::(receipts_pruning_depth + 1, receipts_pruning_depth + 2); - let receipt = ExecutionReceipt::dummy( - receipts_pruning_depth.into(), - block_hash_n::(receipts_pruning_depth), - ); - let bundle = create_dummy_bundle_with_receipts_generic( - TEST_CORE_DOMAIN_ID, - (receipts_pruning_depth + 1).into(), - Default::default(), - receipt, - ); - - #[extrinsic_call] - _(RawOrigin::None, bundle); - - assert_eq!( - DomainRegistry::::head_receipt_number(TEST_CORE_DOMAIN_ID), - receipts_pruning_depth.into() - ); - assert_eq!( - DomainRegistry::::oldest_receipt_number(TEST_CORE_DOMAIN_ID), - 1u32.into() - ); - } - - /// Benchmark `submit_fraud_proof` extrinsic with the worst possible conditions: - /// - Submit a core domain invalid state transition proof - /// - The fraud proof will revert the maximal possible number of receipts - #[benchmark] - fn submit_fraud_proof() { - let receipts_pruning_depth = T::ReceiptsPruningDepth::get().saturated_into::(); - - // Import `ReceiptsPruningDepth` number of receipts which will be revert later - run_to_block::(1, receipts_pruning_depth); - for i in 0..receipts_pruning_depth { - let receipt = ExecutionReceipt::dummy(i.into(), block_hash_n::(i)); - let bundle = create_dummy_bundle_with_receipts_generic( - TEST_CORE_DOMAIN_ID, - (i + 1).into(), - Default::default(), - receipt, - ); - assert_ok!(DomainRegistry::::submit_core_bundle( - RawOrigin::None.into(), - bundle - )); - } - assert_eq!( - DomainRegistry::::head_receipt_number(TEST_CORE_DOMAIN_ID), - (receipts_pruning_depth - 1).into() - ); - - // Construct a fraud proof that will revert `ReceiptsPruningDepth` number of receipts - let proof: FraudProof = FraudProof::InvalidStateTransition( - dummy_invalid_state_transition_proof(TEST_CORE_DOMAIN_ID, 0), - ); - - #[extrinsic_call] - _(RawOrigin::None, proof); - - assert_eq!( - DomainRegistry::::head_receipt_number(TEST_CORE_DOMAIN_ID), - 0u32.into() - ); - } - - // Create an account with the given fund plus the `ExistentialDeposit` - fn funded_account( - name: &'static str, - index: u32, - fund: BalanceOf, - ) -> T::AccountId { - let account = account(name, index, SEED); - T::Currency::make_free_balance_be(&account, fund + T::Currency::minimum_balance()); - account - } - - // Create a helper domain for later operations - fn create_helper_domain(creator: T::AccountId, deposit: BalanceOf) -> DomainId { - let domain_id = NextDomainId::::get(); - let domain_config = sp_domains::DomainConfig { - wasm_runtime_hash: Default::default(), - max_bundle_size: 1024 * 1024, - bundle_slot_probability: (1, 1), - max_bundle_weight: Weight::MAX, - min_operator_stake: T::MinDomainOperatorStake::get(), - }; - - DomainRegistry::::apply_create_domain(&creator, deposit, &domain_config); - assert_eq!(NextDomainId::::get(), domain_id + 1); - assert_eq!(Domains::::get(domain_id), Some(domain_config)); - assert_eq!(DomainCreators::::get(domain_id, creator), Some(deposit)); - - domain_id - } - - // Registry an executor for later operations - fn registry_executor(executor: T::AccountId, stake: BalanceOf) { - let public_key = ExecutorPublicKey::from_slice(&[1; 32]).unwrap(); - T::ExecutorRegistry::unchecked_register(executor.clone(), public_key.clone(), stake); - - assert_eq!(T::ExecutorRegistry::executor_stake(&executor), Some(stake)); - assert_eq!( - T::ExecutorRegistry::executor_public_key(&executor), - Some(public_key) - ); - } - - fn block_hash_n(n: u32) -> T::Hash { - let mut h = T::Hash::default(); - h.as_mut() - .iter_mut() - .zip(u32::to_be_bytes(n).as_slice().iter()) - .for_each(|(h, n)| *h = *n); - h - } - - fn run_to_block(from: u32, to: u32) { - assert!(from > 0); - for b in from..=to { - let block_number = b.into(); - let hash = block_hash_n::(b - 1); - let digest = { - let mut d = Digest::default(); - if b == 1 { - d.push(DigestItem::primary_block_info::(( - 0u32.into(), - block_hash_n::(b), - ))); - } - d.push(DigestItem::primary_block_info((block_number, hash))); - d - }; - System::::set_block_number(block_number); - System::::initialize(&block_number, &hash, &digest); - as Hooks>::on_initialize(block_number); - System::::finalize(); - } - } - - impl_benchmark_test_suite!( - DomainRegistry, - crate::tests::new_test_ext(), - crate::tests::Test - ); -} diff --git a/domains/pallets/domain-registry/src/lib.rs b/domains/pallets/domain-registry/src/lib.rs deleted file mode 100644 index f3700faf42d..00000000000 --- a/domains/pallets/domain-registry/src/lib.rs +++ /dev/null @@ -1,1020 +0,0 @@ -// Copyright (C) 2021 Subspace Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! # Domain Registry Module - -#![cfg_attr(not(feature = "std"), no_std)] - -#[cfg(test)] -mod tests; - -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; - -pub mod weights; - -use codec::Decode; -use frame_support::traits::{Currency, Get, LockIdentifier, LockableCurrency, WithdrawReasons}; -use frame_support::weights::Weight; -use frame_system::offchain::SubmitTransaction; -pub use pallet::*; -use sp_core::H256; -use sp_domains::bundle_election::{ - verify_bundle_solution_threshold, ReadBundleElectionParamsError, -}; -use sp_domains::fraud_proof::FraudProof; -use sp_domains::{ - BundleSolution, DomainId, ExecutorPublicKey, OpaqueBundle, ProofOfElection, StakeWeight, -}; -use sp_executor_registry::{ExecutorRegistry, OnNewEpoch}; -use sp_runtime::traits::{BlakeTwo256, One, Zero}; -use sp_runtime::Percent; -use sp_std::cmp::Ordering; -use sp_std::collections::btree_map::BTreeMap; -use sp_std::vec; -use sp_std::vec::Vec; - -type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; - -type DomainConfig = - sp_domains::DomainConfig<::Hash, BalanceOf, Weight>; - -const DOMAIN_LOCK_ID: LockIdentifier = *b"_domains"; - -#[frame_support::pallet] -mod pallet { - use super::{BalanceOf, DomainConfig}; - use crate::weights::WeightInfo; - use codec::Codec; - use frame_support::pallet_prelude::{StorageMap, *}; - use frame_support::traits::LockableCurrency; - use frame_support::PalletError; - use frame_system::pallet_prelude::*; - use pallet_settlement::{Error as PalletSettlementError, FraudProofError}; - use sp_core::H256; - use sp_domain_digests::AsPredigest; - use sp_domains::bundle_election::ReadBundleElectionParamsError; - use sp_domains::fraud_proof::FraudProof; - use sp_domains::transaction::InvalidTransactionCode; - use sp_domains::{DomainId, OpaqueBundle}; - use sp_executor_registry::ExecutorRegistry; - use sp_runtime::traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize}; - use sp_runtime::{FixedPointOperand, Percent}; - use sp_std::fmt::Debug; - use sp_std::vec::Vec; - - #[pallet::config] - pub trait Config: frame_system::Config + pallet_settlement::Config { - type RuntimeEvent: From> + IsType<::RuntimeEvent>; - - type Currency: LockableCurrency; - - /// The stake weight of an executor. - type StakeWeight: Parameter - + Member - + AtLeast32BitUnsigned - + Codec - + Default - + Copy - + MaybeSerializeDeserialize - + Debug - + MaxEncodedLen - + TypeInfo - + FixedPointOperand - + From>; - - /// Interface to access the executor info. - type ExecutorRegistry: ExecutorRegistry, Self::StakeWeight>; - - /// Minimum amount of deposit to create a domain. - #[pallet::constant] - type MinDomainDeposit: Get>; - - /// Maximum amount of deposit to create a domain. - #[pallet::constant] - type MaxDomainDeposit: Get>; - - /// Minimal stake to be a domain operator. - /// - /// This is global, each domain can have its own minimum stake requirement - /// but must be no less than this value. - // TODO: When an executor decreases its stake in pallet-executor-registry, we should ensure - // the new stake amount still meets the operator stake threshold on all domains he stakes. - #[pallet::constant] - type MinDomainOperatorStake: Get>; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; - } - - #[pallet::pallet] - #[pallet::without_storage_info] - pub struct Pallet(_); - - /// Core domain bundles submitted successfully in current block. - #[pallet::storage] - pub(super) type SuccessfulBundles = StorageValue<_, Vec, ValueQuery>; - - /// Domain id for the next core domain. - #[pallet::storage] - pub(super) type NextDomainId = StorageValue<_, DomainId, ValueQuery>; - - /// (domain_id, domain_creator, deposit) - #[pallet::storage] - pub(super) type DomainCreators = StorageDoubleMap< - _, - Twox64Concat, - DomainId, - Twox64Concat, - T::AccountId, - BalanceOf, - OptionQuery, - >; - - /// A map tracking all the non-system domains. - #[pallet::storage] - pub(super) type Domains = - StorageMap<_, Twox64Concat, DomainId, DomainConfig, OptionQuery>; - - /// At which block the domain was created. - #[pallet::storage] - pub(super) type CreatedAt = - StorageMap<_, Twox64Concat, DomainId, T::BlockNumber, OptionQuery>; - - /// (executor, domain_id, allocated_stake_proportion) - #[pallet::storage] - pub(super) type DomainOperators = StorageDoubleMap< - _, - Twox64Concat, - T::AccountId, - Twox64Concat, - DomainId, - Percent, - OptionQuery, - >; - - /// (domain_id, domain_authority, domain_stake_weight) - #[pallet::storage] - pub(super) type DomainAuthorities = StorageDoubleMap< - _, - Twox64Concat, - DomainId, - Twox64Concat, - T::AccountId, - T::StakeWeight, - OptionQuery, - >; - - /// A map tracking the total stake weight of each domain. - #[pallet::storage] - pub(super) type DomainTotalStakeWeight = - StorageMap<_, Twox64Concat, DomainId, T::StakeWeight, OptionQuery>; - - #[pallet::call] - impl Pallet { - /// Creates a new domain with some deposit locked. - #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::create_domain())] - pub fn create_domain( - origin: OriginFor, - deposit: BalanceOf, - domain_config: DomainConfig, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - Self::can_create_domain(&who, deposit, &domain_config)?; - - let domain_id = Self::apply_create_domain(&who, deposit, &domain_config); - - Self::deposit_event(Event::::NewDomain { - creator: who, - domain_id, - deposit, - domain_config, - }); - - Ok(()) - } - - // TODO: support destroy_domain in the future. - - // TODO: proper weight - #[pallet::call_index(1)] - #[pallet::weight({10_000})] - pub fn update_domain_config( - origin: OriginFor, - domain_id: DomainId, - _domain_config: DomainConfig, - ) -> DispatchResult { - let _who = ensure_signed(origin)?; - - ensure!( - Domains::::contains_key(domain_id), - Error::::InvalidDomainId - ); - - // TODO: Check if the origin account is allowed to update the config. - - // TODO: validate domain_config and deposit an event DomainConfigUpdated - - Ok(()) - } - - /// Register a new domain operator. - #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::register_domain_operator())] - pub fn register_domain_operator( - origin: OriginFor, - domain_id: DomainId, - to_stake: Percent, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - if !to_stake.is_zero() { - Self::can_stake_on_domain(&who, domain_id, to_stake)?; - - Self::do_domain_stake_update(who, domain_id, to_stake)?; - } - - Ok(()) - } - - /// Update the domain stake. - /// - /// NOTE: This has an _identical_ implementation to [`Call::register_domain_operator`], - /// which is intentional, otherwise, it can be confusing when an operator wants to update - /// the domain stake but has to call a API named `register_domain_operator` that usually - /// implies the caller is not yet an operator. - #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::register_domain_operator())] - pub fn update_domain_stake( - origin: OriginFor, - domain_id: DomainId, - new_stake: Percent, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - if !new_stake.is_zero() { - Self::can_stake_on_domain(&who, domain_id, new_stake)?; - - Self::do_domain_stake_update(who, domain_id, new_stake)?; - } - - Ok(()) - } - - /// Deregister a domain operator. - #[pallet::call_index(4)] - #[pallet::weight(T::WeightInfo::deregister_domain_operator())] - pub fn deregister_domain_operator( - origin: OriginFor, - domain_id: DomainId, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - ensure!( - Domains::::contains_key(domain_id), - Error::::InvalidDomainId - ); - - // TODO: may also have a min_domain_operators constraint? - - DomainOperators::::mutate_exists(who.clone(), domain_id, |maybe_stake| { - let old_stake = maybe_stake.take(); - - if old_stake.is_some() { - Self::deposit_event(Event::::DomainOperatorDeregistered { who, domain_id }); - Ok(()) - } else { - Err(Error::::NotOperator) - } - })?; - - Ok(()) - } - - // TODO: Rename this extrinsic since the core bundle is not submit to the transaction pool but crafted and injected - // on fly when building the system domain block. - #[pallet::call_index(5)] - #[pallet::weight(T::WeightInfo::submit_core_bundle())] - pub fn submit_core_bundle( - origin: OriginFor, - opaque_bundle: OpaqueBundle, - ) -> DispatchResult { - ensure_none(origin)?; - - pallet_settlement::Pallet::::track_receipt( - opaque_bundle.domain_id(), - &opaque_bundle.receipt, - ) - .map_err(Error::::from)?; - - let bundle_hash = opaque_bundle.hash(); - - SuccessfulBundles::::append(bundle_hash); - - Ok(()) - } - - #[pallet::call_index(6)] - #[pallet::weight(T::WeightInfo::submit_fraud_proof())] - pub fn submit_fraud_proof( - origin: OriginFor, - fraud_proof: FraudProof, - ) -> DispatchResult { - ensure_none(origin)?; - - log::trace!(target: "runtime::domain-registry", "Processing fraud proof: {fraud_proof:?}"); - - if fraud_proof.domain_id().is_core() { - pallet_settlement::Pallet::::process_fraud_proof(fraud_proof) - .map_err(Error::::from)?; - } - - // TODO: slash the executor accordingly. - - Ok(()) - } - } - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(_n: BlockNumberFor) -> Weight { - let primary_block_info = >::digest() - .logs - .iter() - .filter_map(|s| s.as_primary_block_info::()) - .collect::>(); - - let mut consumed_weight = Weight::zero(); - for domain_id in Domains::::iter_keys() { - for (primary_number, primary_hash) in &primary_block_info { - pallet_settlement::PrimaryBlockHash::::insert( - domain_id, - primary_number, - primary_hash, - ); - consumed_weight += T::DbWeight::get().reads_writes(1, 1); - } - } - - SuccessfulBundles::::kill(); - consumed_weight += T::DbWeight::get().writes(1); - - consumed_weight - } - } - - type GenesisDomainInfo = ( - ::AccountId, - BalanceOf, - DomainConfig, - ::AccountId, - Percent, - ); - - #[pallet::genesis_config] - #[derive(frame_support::DefaultNoBound)] - pub struct GenesisConfig { - pub domains: Vec>, - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - NextDomainId::::put(DomainId::CORE_DOMAIN_ID_START); - - for (creator, deposit, domain_config, domain_operator, operator_stake) in &self.domains - { - Pallet::::can_create_domain(creator, *deposit, domain_config) - .expect("Cannot create genesis domain"); - let domain_id = Pallet::::apply_create_domain(creator, *deposit, domain_config); - - Pallet::::can_stake_on_domain(domain_operator, domain_id, *operator_stake) - .expect("Cannot register genesis domain operator"); - Pallet::::do_domain_stake_update( - domain_operator.clone(), - domain_id, - *operator_stake, - ) - .expect("Failed to apply the genesis domain operator registration"); - - let stake_weight = T::ExecutorRegistry::authority_stake_weight(domain_operator) - .expect("Genesis domain operator must be a genesis executor authority; qed"); - let domain_stake_weight: T::StakeWeight = operator_stake.mul_floor(stake_weight); - - DomainAuthorities::::insert(domain_id, domain_operator, domain_stake_weight); - DomainTotalStakeWeight::::mutate(domain_id, |maybe_total| { - let old = maybe_total.unwrap_or_default(); - maybe_total.replace(old + domain_stake_weight); - }); - } - } - } - - impl From for Error { - #[inline] - fn from(_error: ReadBundleElectionParamsError) -> Self { - Self::FailedToReadBundleElectionParams - } - } - - #[derive(TypeInfo, Encode, Decode, PalletError, Debug)] - pub enum ReceiptError { - /// A missing core domain parent receipt. - MissingParent, - /// Core domain receipt is too far in the future. - TooFarInFuture, - /// Core domain receipt points to an unknown primary block. - UnknownBlock, - /// Valid receipts start after the domain creation. - BeforeDomainCreation, - } - - impl From for Error { - #[inline] - fn from(error: PalletSettlementError) -> Self { - match error { - PalletSettlementError::MissingParent => Self::Receipt(ReceiptError::MissingParent), - PalletSettlementError::FraudProof(err) => Self::FraudProof(err), - PalletSettlementError::UnavailablePrimaryBlockHash => { - Self::UnavailablePrimaryBlockHash - } - } - } - } - - #[pallet::error] - pub enum Error { - /// The amount of deposit is smaller than the `T::MinDomainDeposit` bound. - DepositTooSmall, - - /// The amount of deposit is larger than the `T::MaxDomainDeposit` bound. - DepositTooLarge, - - /// Account does not have enough balance. - InsufficientBalance, - - /// The minimum executor stake value in the domain config is lower than the global - /// requirement `T::MinDomainOperatorStake`. - OperatorStakeThresholdTooLow, - - /// Account is not an executor. - NotExecutor, - - /// Account is not an operator of a domain. - NotOperator, - - /// Domain does not exist for the given domain id. - InvalidDomainId, - - /// The amount of allocated stake is smaller than the minimum value. - OperatorStakeTooSmall, - - /// Domain stake allocation exceeds the maximum available value. - StakeAllocationTooLarge, - - /// An error occurred while reading the state needed for verifying the bundle solution. - FailedToReadBundleElectionParams, - - /// Invalid core domain bundle solution. - BadBundleElectionSolution, - - /// State root of a core domain block is missing. - StateRootNotFound, - - /// Invalid core domain state root. - BadStateRoot, - - /// Not a core domain bundle. - NotCoreDomainBundle, - - /// Can not find the number of block the domain was created at. - DomainNotCreated, - - /// Can not find the block hash of given primary block number. - UnavailablePrimaryBlockHash, - - /// Bundle was created on an unknown primary block (probably a fork block). - BundleCreatedOnUnknownBlock, - - /// Receipt error. - Receipt(ReceiptError), - - /// Fraud proof error. - FraudProof(FraudProofError), - } - - #[pallet::event] - #[pallet::generate_deposit(pub (super) fn deposit_event)] - pub enum Event { - /// A new domain was created. - NewDomain { - creator: T::AccountId, - domain_id: DomainId, - deposit: BalanceOf, - domain_config: DomainConfig, - }, - - /// A new domain operator. - NewDomainOperator { - who: T::AccountId, - domain_id: DomainId, - stake: Percent, - }, - - /// Domain operator updated its stake allocation on this domain. - DomainStakeUpdated { - who: T::AccountId, - domain_id: DomainId, - new_stake: Percent, - }, - - /// A domain operator was deregistered. - DomainOperatorDeregistered { - who: T::AccountId, - domain_id: DomainId, - }, - - FraudProofProcessed, - } - - /// Constructs a `TransactionValidity` with pallet-domain-registry specific defaults. - fn unsigned_validity(prefix: &'static str, tag: impl Encode) -> TransactionValidity { - ValidTransaction::with_tag_prefix(prefix) - .priority(TransactionPriority::MAX) - .and_provides(tag) - .longevity(TransactionLongevity::MAX) - // TODO: may not be necessary if using farmnet as the global executor network. - .propagate(true) - .build() - } - - // TODO: the fraud-proof unsigned extrinsics are same with the ones in pallet-doamins, probably - // find an abstraction to unify them. - #[pallet::validate_unsigned] - impl ValidateUnsigned for Pallet { - type Call = Call; - fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { - match call { - Call::submit_core_bundle { - opaque_bundle, - } => Self::pre_dispatch_submit_core_bundle(opaque_bundle).map_err(|e| { - log::error!(target: "runtime::domain-registry", "Bad core bundle, error: {e:?}"); - TransactionValidityError::Invalid(InvalidTransactionCode::Bundle.into()) - }), - Call::submit_fraud_proof { fraud_proof } => { - if fraud_proof.domain_id().is_system() { - log::debug!( - target: "runtime::domain-registry", - "Unexpected system domain fraud proof: {fraud_proof:?}", - ); - Err(TransactionValidityError::Invalid( - InvalidTransactionCode::FraudProof.into(), - )) - } else { - Ok(()) - } - } - _ => Err(InvalidTransaction::Call.into()), - } - } - - fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { - match call { - Call::submit_fraud_proof { fraud_proof } => { - if fraud_proof.domain_id().is_system() { - log::debug!( - target: "runtime::domain-registry", - "Unexpected system domain fraud proof: {fraud_proof:?}", - ); - return InvalidTransactionCode::FraudProof.into(); - } - if let Err(e) = - pallet_settlement::Pallet::::validate_fraud_proof(fraud_proof) - { - log::debug!( - target: "runtime::domain-registry", - "Bad fraud proof: {fraud_proof:?}, error: {e:?}", - ); - return InvalidTransactionCode::FraudProof.into(); - } - - // TODO: proper tag value. - unsigned_validity("SubspaceSubmitFraudProof", fraud_proof) - } - _ => InvalidTransaction::Call.into(), - } - } - } -} - -impl OnNewEpoch for Pallet { - // TODO: similar to the executors, bench how many domain operators can be supported. - /// Rotate the domain authorities on each new epoch. - fn on_new_epoch(executor_weights: BTreeMap) { - let _ = DomainAuthorities::::clear(u32::MAX, None); - let _ = DomainTotalStakeWeight::::clear(u32::MAX, None); - - let mut total_stake_weights = BTreeMap::new(); - - for (operator, domain_id, stake_allocation) in DomainOperators::::iter() { - // TODO: Need to confirm whether an inactive executor can still be the domain authority. - if let Some(stake_weight) = executor_weights.get(&operator) { - let domain_stake_weight: T::StakeWeight = stake_allocation.mul_floor(*stake_weight); - - total_stake_weights - .entry(domain_id) - .and_modify(|total| *total += domain_stake_weight) - .or_insert(domain_stake_weight); - - DomainAuthorities::::insert(domain_id, operator, domain_stake_weight); - } - } - - for (domain_id, total_stake_weight) in total_stake_weights { - DomainTotalStakeWeight::::insert(domain_id, total_stake_weight); - } - } -} - -impl Pallet -where - T: Config + frame_system::offchain::SendTransactionTypes>, -{ - /// Submits an unsigned extrinsic [`Call::submit_fraud_proof`]. - pub fn submit_fraud_proof_unsigned(fraud_proof: FraudProof) { - let call = Call::submit_fraud_proof { fraud_proof }; - - match SubmitTransaction::>::submit_unsigned_transaction(call.into()) { - Ok(()) => { - log::info!(target: "runtime::domain-registry", "Submitted fraud proof"); - } - Err(()) => { - log::error!(target: "runtime::domain-registry", "Error submitting fraud proof"); - } - } - } -} - -impl Pallet { - pub fn successful_bundles() -> Vec { - SuccessfulBundles::::get() - } - - pub fn head_receipt_number(domain_id: DomainId) -> T::BlockNumber { - pallet_settlement::Pallet::::head_receipt_number(domain_id) - } - - /// Returns the block number of the oldest receipt still being tracked in the state. - pub fn oldest_receipt_number(domain_id: DomainId) -> T::BlockNumber { - pallet_settlement::Pallet::::oldest_receipt_number(domain_id) - } - - pub fn domain_authorities(domain_id: DomainId) -> Vec<(ExecutorPublicKey, T::StakeWeight)> { - DomainAuthorities::::iter_prefix(domain_id) - .filter_map(|(who, stake_weight)| { - T::ExecutorRegistry::executor_public_key(&who) - .map(|executor_public_key| (executor_public_key, stake_weight)) - }) - .collect() - } - - pub fn domain_total_stake_weight(domain_id: DomainId) -> Option { - DomainTotalStakeWeight::::get(domain_id) - } - - pub fn domain_slot_probability(domain_id: DomainId) -> Option<(u64, u64)> { - Domains::::get(domain_id).map(|domain_config| domain_config.bundle_slot_probability) - } - - pub fn core_bundle_election_storage_keys( - domain_id: DomainId, - executor: T::AccountId, - ) -> Vec> { - vec![ - DomainAuthorities::::hashed_key_for(domain_id, executor), - DomainTotalStakeWeight::::hashed_key_for(domain_id), - Domains::::hashed_key_for(domain_id), - ] - } - - fn pre_dispatch_submit_core_bundle( - opaque_bundle: &OpaqueBundle, - ) -> Result<(), Error> { - let header = &opaque_bundle.sealed_header.header; - - let BundleSolution::Core { - proof_of_election, - core_block_number, - core_block_hash, - core_state_root - } = &header.bundle_solution else { - return Err(Error::::NotCoreDomainBundle); - }; - - let domain_id = opaque_bundle.domain_id(); - - if !domain_id.is_core() { - return Err(Error::::NotCoreDomainBundle); - } - - let bundle_created_on_valid_primary_block = - pallet_settlement::PrimaryBlockHash::::get(domain_id, header.primary_number) - .map(|block_hash| block_hash == header.primary_hash) - .unwrap_or(false); - - if !bundle_created_on_valid_primary_block { - log::debug!( - target: "runtime::domain-registry", - "Bundle of {domain_id:?} is probably created on a primary fork #{:?}, expected: {:?}, got: {:?}", - header.primary_number, - pallet_settlement::PrimaryBlockHash::::get(domain_id, header.primary_number), - header.primary_hash, - ); - return Err(Error::BundleCreatedOnUnknownBlock); - } - - let created_at = CreatedAt::::get(domain_id).ok_or(Error::::DomainNotCreated)?; - let head_receipt_number = Self::head_receipt_number(domain_id); - let next_head_receipt_number = head_receipt_number + One::one(); - let max_allowed = head_receipt_number + T::MaximumReceiptDrift::get(); - let receipt = &opaque_bundle.receipt; - - // TODO: Check if the receipt extend the receipt chain or add confirmations to the head receipt - match receipt.primary_number.cmp(&next_head_receipt_number) { - // Missing receipt. - Ordering::Greater => { - log::debug!( - target: "runtime::domain-registry", - "Receipt for {domain_id:?} #{next_head_receipt_number:?} is missing, \ - head_receipt_number: {head_receipt_number:?}, max_allowed: {max_allowed:?}, received: {:?}", - receipt.primary_number - ); - return Err(Error::::Receipt(ReceiptError::MissingParent)); - } - // Non-best receipt - Ordering::Less => {} - // New nest receipt. - Ordering::Equal => { - let primary_number = receipt.primary_number; - - if primary_number <= created_at { - log::debug!( - target: "runtime::domain-registry", - "Domain was created at #{created_at:?}, but this receipt points to an earlier block #{:?}", receipt.primary_number, - ); - return Err(Error::::Receipt(ReceiptError::BeforeDomainCreation)); - } - - if !pallet_settlement::Pallet::::point_to_valid_primary_block(domain_id, receipt) - { - log::debug!( - target: "runtime::domain-registry", - "Receipt of {domain_id:?} #{primary_number:?},{:?} points to an unknown primary block, \ - expected: #{primary_number:?},{:?}", - receipt.primary_hash, - pallet_settlement::PrimaryBlockHash::::get(domain_id, primary_number), - ); - return Err(Error::::Receipt(ReceiptError::UnknownBlock)); - } - - if primary_number > max_allowed { - log::debug!( - target: "runtime::domain-registry", - "Receipt for #{primary_number:?} is too far in future, max_allowed: {max_allowed:?}", - ); - return Err(Error::::Receipt(ReceiptError::TooFarInFuture)); - } - } - } - - // The validity of vrf proof itself has been verified on the primary chain, thus only the - // proof_of_election is necessary to be checked here. - let ProofOfElection { - vrf_output, - storage_proof, - system_state_root, - executor_public_key, - global_challenge, - .. - } = &proof_of_election; - - let core_block_number = T::BlockNumber::from(*core_block_number); - - // Considering this scenario, a core domain stalls at block 1 for a long time and then - // resumes at block 1000, assuming `MaximumReceiptDrift` is 128 and the receipt of - // block 1 had been submitted, the range of receipts in the new bundle created at - // block 1000 would be (1, 1+128] , thus the state root corresponding to block 1000,i.e., - // `core_state_root`, can not be verified, in which case the `core_state_root` - // verification will be skipped. - // - // We can not simply remove the `MaximumReceiptDrift` constraint as it's unwise to - // fill in an unlimited number of missing receipts in one single bundle when the - // domain resumes because the computation resource per block is limited anyway. - // - // This edge case does not impact the security due to the fraud-proof mechanism. - let state_root_verifiable = core_block_number <= head_receipt_number; - - if !core_block_number.is_zero() && state_root_verifiable { - let maybe_state_root = if (receipt.primary_number, receipt.domain_hash) - == (core_block_number, *core_block_hash) - { - receipt.trace.last().cloned() - } else { - None - }; - - let expected_state_root = match maybe_state_root { - Some(v) => v, - None => pallet_settlement::Pallet::::state_root(( - domain_id, - core_block_number, - core_block_hash, - )) - .ok_or(Error::::StateRootNotFound) - .map_err(|err| { - log::debug!( - target: "runtime::domain-registry", - "State root for {domain_id:?} #{core_block_number:?},{core_block_hash:?} not found, \ - current head receipt: {:?}", - pallet_settlement::Pallet::::receipt_head(domain_id), - ); - err - })?, - }; - - if expected_state_root != *core_state_root { - log::debug!( - target: "runtime::domains", - "Bad state root for {domain_id:?} #{core_block_number:?},{core_block_hash:?}, \ - expected: {expected_state_root:?}, got: {core_state_root:?}", - ); - return Err(Error::::BadStateRoot); - } - } - - let db = storage_proof.clone().into_memory_db::(); - - let system_state_root: sp_core::H256 = (*system_state_root).into(); - - let read_value = |storage_key: Vec| { - sp_trie::read_trie_value::, _>( - &db, - &system_state_root, - &storage_key, - None, - None, - ) - .map_err(|_| ReadBundleElectionParamsError::TrieError)? - .ok_or(ReadBundleElectionParamsError::MissingValue) - }; - - fn decode(storage_key: Vec) -> Result { - T::decode(&mut storage_key.as_slice()) - .map_err(|_| ReadBundleElectionParamsError::DecodeError) - } - - let executor_key = T::ExecutorRegistry::key_owner_storage_key(executor_public_key); - let executor: T::AccountId = decode(read_value(executor_key)?)?; - - let stake_weight_key = DomainAuthorities::::hashed_key_for(domain_id, executor); - let stake_weight: StakeWeight = decode(read_value(stake_weight_key)?)?; - - let total_stake_weight_key = DomainTotalStakeWeight::::hashed_key_for(domain_id); - let total_stake_weight: StakeWeight = decode(read_value(total_stake_weight_key)?)?; - - let domain_config_key = Domains::::hashed_key_for(domain_id); - let domain_config: DomainConfig = decode(read_value(domain_config_key)?)?; - - let slot_probability = domain_config.bundle_slot_probability; - - verify_bundle_solution_threshold( - domain_id, - vrf_output, - stake_weight, - total_stake_weight, - slot_probability, - executor_public_key, - global_challenge, - ) - .map_err(|_| Error::::BadBundleElectionSolution)?; - - Ok(()) - } - - fn can_create_domain( - who: &T::AccountId, - deposit: BalanceOf, - domain_config: &DomainConfig, - ) -> Result<(), Error> { - if deposit < T::MinDomainDeposit::get() { - return Err(Error::::DepositTooSmall); - } - - if deposit > T::MaxDomainDeposit::get() { - return Err(Error::::DepositTooLarge); - } - - if T::Currency::free_balance(who) < deposit { - return Err(Error::::InsufficientBalance); - } - - if domain_config.min_operator_stake < T::MinDomainOperatorStake::get() { - return Err(Error::::OperatorStakeThresholdTooLow); - } - - Ok(()) - } - - fn apply_create_domain( - who: &T::AccountId, - deposit: BalanceOf, - domain_config: &DomainConfig, - ) -> DomainId { - T::Currency::set_lock(DOMAIN_LOCK_ID, who, deposit, WithdrawReasons::all()); - - let domain_id = NextDomainId::::get(); - - Domains::::insert(domain_id, domain_config); - DomainCreators::::insert(domain_id, who, deposit); - NextDomainId::::put(domain_id + 1); - - let current_block_number = frame_system::Pallet::::block_number(); - CreatedAt::::insert(domain_id, current_block_number); - pallet_settlement::Pallet::::initialize_head_receipt_number( - domain_id, - current_block_number, - ); - - domain_id - } - - fn can_stake_on_domain( - who: &T::AccountId, - domain_id: DomainId, - to_stake: Percent, - ) -> Result<(), Error> { - let stake_amount = - T::ExecutorRegistry::executor_stake(who).ok_or(Error::::NotExecutor)?; - - let min_stake = Domains::::get(domain_id) - .map(|domain_config| domain_config.min_operator_stake) - .ok_or(Error::::InvalidDomainId)?; - - if to_stake.mul_floor(stake_amount) < min_stake { - return Err(Error::::OperatorStakeTooSmall); - } - - // Exclude the potential existing stake allocation on this domain. - let already_allocated: Percent = DomainOperators::::iter_prefix(who) - .filter_map(|(id, value)| if domain_id == id { None } else { Some(value) }) - .fold(Zero::zero(), |acc, x| acc + x); - - let available_stake = Percent::one() - already_allocated; - if to_stake > available_stake { - return Err(Error::::StakeAllocationTooLarge); - } - - Ok(()) - } - - fn do_domain_stake_update( - who: T::AccountId, - domain_id: DomainId, - new_stake: Percent, - ) -> Result<(), Error> { - DomainOperators::::mutate_exists(who.clone(), domain_id, |maybe_stake| { - let old_stake = maybe_stake.replace(new_stake); - - if old_stake.is_some() { - Self::deposit_event(Event::::DomainStakeUpdated { - who, - domain_id, - new_stake, - }); - } else { - Self::deposit_event(Event::::NewDomainOperator { - who, - domain_id, - stake: new_stake, - }); - } - - Ok(()) - }) - } -} diff --git a/domains/pallets/domain-registry/src/tests.rs b/domains/pallets/domain-registry/src/tests.rs deleted file mode 100644 index e92b109b8c8..00000000000 --- a/domains/pallets/domain-registry/src/tests.rs +++ /dev/null @@ -1,428 +0,0 @@ -use crate::{ - self as pallet_domain_registry, DomainAuthorities, DomainCreators, DomainOperators, - DomainTotalStakeWeight, Domains, Error, NextDomainId, -}; -use frame_support::dispatch::Weight; -use frame_support::traits::{ConstU16, ConstU32, ConstU64, GenesisBuild, Hooks}; -use frame_support::{assert_noop, assert_ok, parameter_types}; -use pallet_balances::AccountData; -use sp_core::crypto::Pair; -use sp_core::{H256, U256}; -use sp_domains::{DomainId, ExecutorPair, StakeWeight}; -use sp_runtime::testing::Header; -use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; -use sp_runtime::Percent; - -type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -type Block = frame_system::mocking::MockBlock; - -type DomainConfig = crate::DomainConfig; - -frame_support::construct_runtime!( - pub struct Test - where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system, - Balances: pallet_balances, - ExecutorRegistry: pallet_executor_registry, - Settlement: pallet_settlement, - DomainRegistry: pallet_domain_registry, - } -); - -type AccountId = u64; -type BlockNumber = u64; -type Balance = u128; -type Hash = H256; - -impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - type Index = u64; - type BlockNumber = BlockNumber; - type Hash = Hash; - type Hashing = BlakeTwo256; - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Header = Header; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = ConstU64<2>; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = ConstU16<42>; - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; -} - -parameter_types! { - pub static ExistentialDeposit: Balance = 1; -} - -impl pallet_balances::Config for Test { - type MaxLocks = (); - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - type Balance = Balance; - type DustRemoval = (); - type RuntimeEvent = RuntimeEvent; - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); - type FreezeIdentifier = (); - type MaxFreezes = (); - type RuntimeHoldReason = (); - type MaxHolds = (); -} - -parameter_types! { - pub const MinExecutorStake: Balance = 10; - pub const MaxExecutorStake: Balance = 1000; - pub const MinExecutors: u32 = 1; - pub const MaxExecutors: u32 = 10; - pub const EpochDuration: BlockNumber = 3; - pub const MaxWithdrawals: u32 = 1; - pub const WithdrawalDuration: BlockNumber = 10; -} - -parameter_types! { - pub const StateRootsBound: u32 = 50; - pub const RelayConfirmationDepth: BlockNumber = 7; -} - -impl pallet_executor_registry::Config for Test { - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type StakeWeight = StakeWeight; - type MinExecutorStake = MinExecutorStake; - type MaxExecutorStake = MaxExecutorStake; - type MinExecutors = MinExecutors; - type MaxExecutors = MaxExecutors; - type EpochDuration = EpochDuration; - type MaxWithdrawals = MaxWithdrawals; - type WithdrawalDuration = WithdrawalDuration; - type OnNewEpoch = DomainRegistry; - type WeightInfo = (); -} - -parameter_types! { - pub const MinDomainDeposit: Balance = 10; - pub const MaxDomainDeposit: Balance = 1000; - pub const MinDomainOperatorStake: u32 = 10; - pub const MaximumReceiptDrift: BlockNumber = 128; - pub const ReceiptsPruningDepth: BlockNumber = 256; -} - -impl pallet_domain_registry::Config for Test { - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type StakeWeight = StakeWeight; - type ExecutorRegistry = ExecutorRegistry; - type MinDomainDeposit = MinDomainDeposit; - type MaxDomainDeposit = MaxDomainDeposit; - type MinDomainOperatorStake = MinDomainOperatorStake; - type WeightInfo = (); -} - -impl pallet_settlement::Config for Test { - type RuntimeEvent = RuntimeEvent; - type DomainHash = Hash; - type MaximumReceiptDrift = MaximumReceiptDrift; - type ReceiptsPruningDepth = ReceiptsPruningDepth; -} - -pub(crate) fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); - - pallet_balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 2000), (3, 3000), (4, 4000)], - } - .assimilate_storage(&mut t) - .unwrap(); - - pallet_executor_registry::GenesisConfig:: { - executors: vec![ - ( - 1, - 100, - 1 + 10000, - ExecutorPair::from_seed(&U256::from(1u32).into()).public(), - ), - ( - 2, - 200, - 2 + 10000, - ExecutorPair::from_seed(&U256::from(2u32).into()).public(), - ), - ( - 3, - 300, - 3 + 10000, - ExecutorPair::from_seed(&U256::from(3u32).into()).public(), - ), - ], - slot_probability: (1u64, 1u64), - } - .assimilate_storage(&mut t) - .unwrap(); - - pallet_domain_registry::GenesisConfig:: { - domains: vec![( - 1, - 100, - DomainConfig { - wasm_runtime_hash: Hash::repeat_byte(1), - bundle_slot_probability: (1, 1), - max_bundle_size: 1024 * 1024, - max_bundle_weight: Weight::from_parts(100_000_000_000, 0), - min_operator_stake: 20, - }, - 1, - Percent::from_percent(80), - )], - } - .assimilate_storage(&mut t) - .unwrap(); - - t.into() -} - -#[test] -fn create_domain_should_work() { - new_test_ext().execute_with(|| { - let genesis_core_domain_id = DomainId::from(1); - let genesis_domain_config = DomainConfig { - wasm_runtime_hash: Hash::repeat_byte(1), - bundle_slot_probability: (1, 1), - max_bundle_size: 1024 * 1024, - max_bundle_weight: Weight::from_parts(100_000_000_000, 0), - min_operator_stake: 20, - }; - assert_eq!( - Domains::::get(genesis_core_domain_id).unwrap(), - genesis_domain_config - ); - assert_eq!(NextDomainId::::get(), 2.into()); - assert_eq!( - DomainCreators::::get(genesis_core_domain_id, 1), - Some(100) - ); - - let domain_config = DomainConfig { - wasm_runtime_hash: Hash::random(), - bundle_slot_probability: (1, 1), - max_bundle_size: 1024 * 1024, - max_bundle_weight: Weight::from_parts(100_000_000_000, 0), - min_operator_stake: 20, - }; - - assert_noop!( - DomainRegistry::create_domain(RuntimeOrigin::signed(1), 1, domain_config.clone()), - Error::::DepositTooSmall - ); - assert_noop!( - DomainRegistry::create_domain(RuntimeOrigin::signed(1), 10_000, domain_config.clone()), - Error::::DepositTooLarge - ); - assert_noop!( - DomainRegistry::create_domain(RuntimeOrigin::signed(8), 100, domain_config.clone()), - Error::::InsufficientBalance - ); - assert_noop!( - DomainRegistry::create_domain( - RuntimeOrigin::signed(1), - 100, - DomainConfig { - min_operator_stake: 1, - ..domain_config - } - ), - Error::::OperatorStakeThresholdTooLow - ); - - let (creator, deposit) = (2, 200); - let next_domain_id = NextDomainId::::get(); - assert_ok!(DomainRegistry::create_domain( - RuntimeOrigin::signed(creator), - deposit, - domain_config.clone(), - )); - assert_eq!( - frame_system::Account::::get(creator).data, - AccountData { - free: 2000, - reserved: 0, - frozen: deposit, - ..AccountData::default() - } - ); - - assert_eq!(Domains::::get(next_domain_id).unwrap(), domain_config); - assert_eq!(NextDomainId::::get(), next_domain_id + 1); - assert_eq!( - DomainCreators::::get(next_domain_id, creator), - Some(deposit) - ); - }); -} - -#[test] -fn register_domain_operator_and_update_domain_stake_should_work() { - new_test_ext().execute_with(|| { - let genesis_core_domain_id = DomainId::from(1); - assert_eq!( - DomainOperators::::get(1, genesis_core_domain_id).unwrap(), - Percent::from_percent(80) - ); - - assert_noop!( - DomainRegistry::update_domain_stake( - RuntimeOrigin::signed(1), - genesis_core_domain_id, - Percent::from_percent(10), - ), - Error::::OperatorStakeTooSmall - ); - - assert_ok!(DomainRegistry::update_domain_stake( - RuntimeOrigin::signed(1), - genesis_core_domain_id, - Percent::from_percent(20), - )); - - assert_eq!( - DomainOperators::::get(1, genesis_core_domain_id).unwrap(), - Percent::from_percent(20) - ); - - assert_ok!(DomainRegistry::create_domain( - RuntimeOrigin::signed(2), - 200, - DomainConfig { - wasm_runtime_hash: Hash::random(), - bundle_slot_probability: (1, 1), - max_bundle_size: 1024 * 1024, - max_bundle_weight: Weight::from_parts(100_000_000_000, 0), - min_operator_stake: 20, - } - )); - - // only 80% is available. - assert_noop!( - DomainRegistry::register_domain_operator( - RuntimeOrigin::signed(1), - DomainId::from(2), - Percent::from_percent(90), - ), - Error::::StakeAllocationTooLarge - ); - - assert_ok!(DomainRegistry::register_domain_operator( - RuntimeOrigin::signed(1), - DomainId::from(2), - Percent::from_percent(80), - )); - - assert_ok!(DomainRegistry::register_domain_operator( - RuntimeOrigin::signed(2), - genesis_core_domain_id, - Percent::from_percent(50), - )); - - assert_eq!( - DomainOperators::::get(2, genesis_core_domain_id).unwrap(), - Percent::from_percent(50) - ); - - assert_noop!( - DomainRegistry::register_domain_operator( - RuntimeOrigin::signed(8), - DomainId::from(1), - Percent::from_percent(30), - ), - Error::::NotExecutor - ); - }); -} - -#[test] -fn deregister_domain_operator_should_work() { - new_test_ext().execute_with(|| { - assert_noop!( - DomainRegistry::deregister_domain_operator(RuntimeOrigin::signed(3), DomainId::from(1)), - Error::::NotOperator - ); - - assert_ok!(DomainRegistry::register_domain_operator( - RuntimeOrigin::signed(2), - DomainId::from(1), - Percent::from_percent(50), - )); - - assert_ok!(DomainRegistry::deregister_domain_operator( - RuntimeOrigin::signed(1), - DomainId::from(1) - )); - - assert!(DomainOperators::::get(1, DomainId::from(1)).is_none()); - }); -} - -#[test] -fn rotate_domain_authorities_should_work() { - new_test_ext().execute_with(|| { - let genesis_core_domain_id = DomainId::from(1); - assert_eq!( - DomainAuthorities::::iter().collect::>(), - vec![(genesis_core_domain_id, 1, 80)] - ); - assert_eq!( - DomainTotalStakeWeight::::iter().collect::>(), - vec![(genesis_core_domain_id, 80)] - ); - - assert_ok!(DomainRegistry::register_domain_operator( - RuntimeOrigin::signed(2), - genesis_core_domain_id, - Percent::from_percent(20), - )); - - assert_ok!(DomainRegistry::register_domain_operator( - RuntimeOrigin::signed(3), - genesis_core_domain_id, - Percent::from_percent(30), - )); - - let epoch_end = EpochDuration::get(); - - for b in (System::block_number() + 1)..=epoch_end { - System::set_block_number(b); - >::on_initialize(b); - } - - assert_eq!( - DomainAuthorities::::iter().collect::>(), - vec![ - (genesis_core_domain_id, 3, 90), - (genesis_core_domain_id, 1, 80), - (genesis_core_domain_id, 2, 40), - ] - ); - assert_eq!( - DomainTotalStakeWeight::::iter().collect::>(), - vec![(genesis_core_domain_id, 90 + 80 + 40)] - ); - }); -} diff --git a/domains/pallets/domain-registry/src/weights.rs b/domains/pallets/domain-registry/src/weights.rs deleted file mode 100644 index e8ec179db29..00000000000 --- a/domains/pallets/domain-registry/src/weights.rs +++ /dev/null @@ -1,244 +0,0 @@ - -//! Autogenerated weights for pallet_domain_registry -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-06-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `local`, CPU: `` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 - -// Executed Command: -// ./target/release/subspace-node -// executor -// benchmark -// pallet -// --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=pallet_domain_registry -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./domains/pallets/domain-registry/src/weights.rs -// --template -// ./frame-weight-template.hbs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - -/// Weight functions needed for pallet_domain_registry. -pub trait WeightInfo { - fn create_domain() -> Weight; - fn register_domain_operator() -> Weight; - fn deregister_domain_operator() -> Weight; - fn submit_core_bundle() -> Weight; - fn submit_fraud_proof() -> Weight; -} - -/// Weights for pallet_domain_registry using the Substrate node and recommended hardware. -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: DomainRegistry NextDomainId (r:1 w:1) - /// Proof Skipped: DomainRegistry NextDomainId (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: DomainRegistry Domains (r:0 w:1) - /// Proof Skipped: DomainRegistry Domains (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry DomainCreators (r:0 w:1) - /// Proof Skipped: DomainRegistry DomainCreators (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry CreatedAt (r:0 w:1) - /// Proof Skipped: DomainRegistry CreatedAt (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement HeadReceiptNumber (r:0 w:1) - /// Proof Skipped: Settlement HeadReceiptNumber (max_values: None, max_size: None, mode: Measured) - fn create_domain() -> Weight { - // Proof Size summary in bytes: - // Measured: `316` - // Estimated: `14936` - // Minimum execution time: 46_000_000 picoseconds. - Weight::from_parts(49_000_000, 14936) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:0) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry Domains (r:1 w:0) - /// Proof Skipped: DomainRegistry Domains (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry DomainOperators (r:2 w:1) - /// Proof Skipped: DomainRegistry DomainOperators (max_values: None, max_size: None, mode: Measured) - fn register_domain_operator() -> Weight { - // Proof Size summary in bytes: - // Measured: `810` - // Estimated: `15300` - // Minimum execution time: 28_000_000 picoseconds. - Weight::from_parts(30_000_000, 15300) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: DomainRegistry Domains (r:1 w:0) - /// Proof Skipped: DomainRegistry Domains (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry DomainOperators (r:1 w:1) - /// Proof Skipped: DomainRegistry DomainOperators (max_values: None, max_size: None, mode: Measured) - fn deregister_domain_operator() -> Weight { - // Proof Size summary in bytes: - // Measured: `369` - // Estimated: `7668` - // Minimum execution time: 16_000_000 picoseconds. - Weight::from_parts(17_000_000, 7668) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: Settlement OldestReceiptNumber (r:1 w:1) - /// Proof Skipped: Settlement OldestReceiptNumber (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement HeadReceiptNumber (r:1 w:1) - /// Proof Skipped: Settlement HeadReceiptNumber (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement Receipts (r:1 w:2) - /// Proof Skipped: Settlement Receipts (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement ReceiptVotes (r:3 w:2) - /// Proof Skipped: Settlement ReceiptVotes (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement PrimaryBlockHash (r:1 w:1) - /// Proof Skipped: Settlement PrimaryBlockHash (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry SuccessfulBundles (r:1 w:1) - /// Proof Skipped: DomainRegistry SuccessfulBundles (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Settlement StateRoots (r:0 w:1) - /// Proof Skipped: Settlement StateRoots (max_values: None, max_size: None, mode: Measured) - fn submit_core_bundle() -> Weight { - // Proof Size summary in bytes: - // Measured: `4145` - // Estimated: `52775` - // Minimum execution time: 100_000_000 picoseconds. - Weight::from_parts(118_000_000, 52775) - .saturating_add(T::DbWeight::get().reads(8_u64)) - .saturating_add(T::DbWeight::get().writes(9_u64)) - } - /// Storage: Settlement HeadReceiptNumber (r:1 w:1) - /// Proof Skipped: Settlement HeadReceiptNumber (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement PrimaryBlockHash (r:256 w:0) - /// Proof Skipped: Settlement PrimaryBlockHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement ReceiptVotes (r:510 w:255) - /// Proof Skipped: Settlement ReceiptVotes (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement Receipts (r:255 w:255) - /// Proof Skipped: Settlement Receipts (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement StateRoots (r:255 w:255) - /// Proof Skipped: Settlement StateRoots (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement SuccessfulFraudProofs (r:1 w:1) - /// Proof Skipped: Settlement SuccessfulFraudProofs (max_values: Some(1), max_size: None, mode: Measured) - fn submit_fraud_proof() -> Weight { - // Proof Size summary in bytes: - // Measured: `113582` - // Estimated: `3848502` - // Minimum execution time: 7_131_000_000 picoseconds. - Weight::from_parts(7_645_000_000, 3848502) - .saturating_add(T::DbWeight::get().reads(1278_u64)) - .saturating_add(T::DbWeight::get().writes(767_u64)) - } -} - -// For backwards compatibility and tests -impl WeightInfo for () { - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: DomainRegistry NextDomainId (r:1 w:1) - /// Proof Skipped: DomainRegistry NextDomainId (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: DomainRegistry Domains (r:0 w:1) - /// Proof Skipped: DomainRegistry Domains (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry DomainCreators (r:0 w:1) - /// Proof Skipped: DomainRegistry DomainCreators (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry CreatedAt (r:0 w:1) - /// Proof Skipped: DomainRegistry CreatedAt (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement HeadReceiptNumber (r:0 w:1) - /// Proof Skipped: Settlement HeadReceiptNumber (max_values: None, max_size: None, mode: Measured) - fn create_domain() -> Weight { - // Proof Size summary in bytes: - // Measured: `316` - // Estimated: `14936` - // Minimum execution time: 46_000_000 picoseconds. - Weight::from_parts(49_000_000, 14936) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:0) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry Domains (r:1 w:0) - /// Proof Skipped: DomainRegistry Domains (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry DomainOperators (r:2 w:1) - /// Proof Skipped: DomainRegistry DomainOperators (max_values: None, max_size: None, mode: Measured) - fn register_domain_operator() -> Weight { - // Proof Size summary in bytes: - // Measured: `810` - // Estimated: `15300` - // Minimum execution time: 28_000_000 picoseconds. - Weight::from_parts(30_000_000, 15300) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: DomainRegistry Domains (r:1 w:0) - /// Proof Skipped: DomainRegistry Domains (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry DomainOperators (r:1 w:1) - /// Proof Skipped: DomainRegistry DomainOperators (max_values: None, max_size: None, mode: Measured) - fn deregister_domain_operator() -> Weight { - // Proof Size summary in bytes: - // Measured: `369` - // Estimated: `7668` - // Minimum execution time: 16_000_000 picoseconds. - Weight::from_parts(17_000_000, 7668) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: Settlement OldestReceiptNumber (r:1 w:1) - /// Proof Skipped: Settlement OldestReceiptNumber (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement HeadReceiptNumber (r:1 w:1) - /// Proof Skipped: Settlement HeadReceiptNumber (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement Receipts (r:1 w:2) - /// Proof Skipped: Settlement Receipts (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement ReceiptVotes (r:3 w:2) - /// Proof Skipped: Settlement ReceiptVotes (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement PrimaryBlockHash (r:1 w:1) - /// Proof Skipped: Settlement PrimaryBlockHash (max_values: None, max_size: None, mode: Measured) - /// Storage: DomainRegistry SuccessfulBundles (r:1 w:1) - /// Proof Skipped: DomainRegistry SuccessfulBundles (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: Settlement StateRoots (r:0 w:1) - /// Proof Skipped: Settlement StateRoots (max_values: None, max_size: None, mode: Measured) - fn submit_core_bundle() -> Weight { - // Proof Size summary in bytes: - // Measured: `4145` - // Estimated: `52775` - // Minimum execution time: 100_000_000 picoseconds. - Weight::from_parts(118_000_000, 52775) - .saturating_add(RocksDbWeight::get().reads(8_u64)) - .saturating_add(RocksDbWeight::get().writes(9_u64)) - } - /// Storage: Settlement HeadReceiptNumber (r:1 w:1) - /// Proof Skipped: Settlement HeadReceiptNumber (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement PrimaryBlockHash (r:256 w:0) - /// Proof Skipped: Settlement PrimaryBlockHash (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement ReceiptVotes (r:510 w:255) - /// Proof Skipped: Settlement ReceiptVotes (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement Receipts (r:255 w:255) - /// Proof Skipped: Settlement Receipts (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement StateRoots (r:255 w:255) - /// Proof Skipped: Settlement StateRoots (max_values: None, max_size: None, mode: Measured) - /// Storage: Settlement SuccessfulFraudProofs (r:1 w:1) - /// Proof Skipped: Settlement SuccessfulFraudProofs (max_values: Some(1), max_size: None, mode: Measured) - fn submit_fraud_proof() -> Weight { - // Proof Size summary in bytes: - // Measured: `113582` - // Estimated: `3848502` - // Minimum execution time: 7_131_000_000 picoseconds. - Weight::from_parts(7_645_000_000, 3848502) - .saturating_add(RocksDbWeight::get().reads(1278_u64)) - .saturating_add(RocksDbWeight::get().writes(767_u64)) - } -} diff --git a/domains/pallets/executive/Cargo.toml b/domains/pallets/executive/Cargo.toml index 452b115978c..7cd05461ccb 100644 --- a/domains/pallets/executive/Cargo.toml +++ b/domains/pallets/executive/Cargo.toml @@ -12,23 +12,23 @@ description = "Cirrus executives engine" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-executive = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -frame-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-executive = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +frame-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-std = { version = "8.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-tracing = { version = "10.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-std = { version = "8.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-tracing = { version = "10.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } [dev-dependencies] hex-literal = "0.4.0" -pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-version = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transaction-payment = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-version = { version = "22.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/domains/pallets/executive/src/lib.rs b/domains/pallets/executive/src/lib.rs index 1d36dfbfa35..42e17d2d706 100644 --- a/domains/pallets/executive/src/lib.rs +++ b/domains/pallets/executive/src/lib.rs @@ -329,7 +329,7 @@ where // Note the storage root before finalizing the block so that the block imported during the // syncing processs produces the same storage root with the one processed based on - // the primary block. + // the consensus block. Pallet::::push_root(Self::storage_root()); // post-extrinsics book-keeping diff --git a/domains/pallets/executor-registry/Cargo.toml b/domains/pallets/executor-registry/Cargo.toml deleted file mode 100644 index 885f2987f79..00000000000 --- a/domains/pallets/executor-registry/Cargo.toml +++ /dev/null @@ -1,58 +0,0 @@ -[package] -name = "pallet-executor-registry" -version = "0.1.0" -authors = ["Liu-Cheng Xu "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://subspace.network" -repository = "https://github.com/subspace/subspace/" -description = "System domain pallet managing the executors and their funds at stake" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -frame-support = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -frame-system = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-arithmetic = { version = "16.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false, optional = true } -sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains", default-features = false } -sp-executor-registry = { version = "0.1.0", path = "../../primitives/executor-registry", default-features = false } -sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-std = { version = "8.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -subspace-core-primitives = { version = "0.1.0", path = "../../../crates/subspace-core-primitives", default-features = false } - -[dev-dependencies] -pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } - -[features] -default = ["std"] -std = [ - "codec/std", - "frame-benchmarking?/std", - "frame-support/std", - "frame-system/std", - "scale-info/std", - "sp-arithmetic/std", - "sp-core?/std", - "sp-domains/std", - "sp-executor-registry/std", - "sp-io/std", - "sp-runtime/std", - "sp-std/std", - "subspace-core-primitives/std", -] -try-runtime = ["frame-support/try-runtime"] -runtime-benchmarks = [ - "frame-benchmarking", - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "sp-core", - "sp-executor-registry/runtime-benchmarks", -] diff --git a/domains/pallets/executor-registry/src/benchmarking.rs b/domains/pallets/executor-registry/src/benchmarking.rs deleted file mode 100644 index 2bfb5c717ec..00000000000 --- a/domains/pallets/executor-registry/src/benchmarking.rs +++ /dev/null @@ -1,217 +0,0 @@ -//! Benchmarking for `pallet-executor-registry`. - -use super::*; -use crate::Pallet as ExecutorRegistry; -use frame_benchmarking::v2::*; -use frame_support::assert_ok; -use frame_support::traits::Get; -use frame_system::{Pallet as System, RawOrigin}; -use sp_core::crypto::ByteArray; -use sp_domains::ExecutorPublicKey; -use sp_executor_registry::ExecutorRegistry as ExecutorRegistryT; -use sp_runtime::Saturating; - -const SEED: u32 = 0; - -#[benchmarks] -mod benchmarks { - use super::*; - - #[benchmark] - fn register() { - let stake = T::MinExecutorStake::get(); - let executor = funded_account::("executor", 1, stake); - let public_key = ExecutorPublicKey::from_slice(&[1; 32]).unwrap(); - - #[extrinsic_call] - _( - RawOrigin::Signed(executor.clone()), - public_key.clone(), - executor.clone(), - true, - stake, - ); - - assert_eq!( - ExecutorRegistry::::executor_stake(&executor), - Some(stake) - ); - assert_eq!( - ExecutorRegistry::::executor_public_key(&executor), - Some(public_key) - ); - } - - #[benchmark] - fn increase_stake() { - let init_stake = T::MinExecutorStake::get(); - let increasing_stake = T::MinExecutorStake::get(); - let executor = funded_account::("executor", 1, init_stake + increasing_stake); - - registry_executor::(executor.clone(), init_stake, true); - - #[extrinsic_call] - _(RawOrigin::Signed(executor.clone()), increasing_stake); - - assert_eq!( - ExecutorRegistry::::executor_stake(&executor), - Some(init_stake + increasing_stake) - ); - } - - #[benchmark] - fn decrease_stake() { - let init_stake = T::MinExecutorStake::get().saturating_mul(2u32.into()); - let decreasing_stake = T::MinExecutorStake::get(); - let executor = funded_account::("executor", 1, init_stake); - - registry_executor::(executor.clone(), init_stake, true); - - #[extrinsic_call] - _(RawOrigin::Signed(executor.clone()), decreasing_stake); - - let executor_config = - Executors::::get(&executor).expect("Should be able to get the executor config"); - assert_eq!(executor_config.stake, init_stake - decreasing_stake); - assert_eq!(executor_config.withdrawals.len(), 1); - } - - #[benchmark] - fn withdraw_stake() { - let init_stake = T::MinExecutorStake::get().saturating_mul(2u32.into()); - let decreasing_stake = T::MinExecutorStake::get(); - let executor = funded_account::("executor", 1, init_stake); - - // Register an executor and create a withdrawal - registry_executor::(executor.clone(), init_stake, true); - assert_ok!(ExecutorRegistry::::decrease_stake( - RawOrigin::Signed(executor.clone()).into(), - decreasing_stake, - )); - let executor_config = - Executors::::get(&executor).expect("Should be able to get the executor config"); - assert_eq!(executor_config.stake, init_stake - decreasing_stake); - assert_eq!(executor_config.withdrawals.len(), 1); - - // Going through the withdraw duration period - let current_block = System::::block_number(); - System::::set_block_number(current_block + T::WithdrawalDuration::get() + 1u32.into()); - - #[extrinsic_call] - _(RawOrigin::Signed(executor.clone()), 0); - - let executor_config = - Executors::::get(&executor).expect("Should be able to get the executor config"); - assert!(executor_config.withdrawals.is_empty()); - } - - #[benchmark] - fn pause_execution() { - let stake = T::MinExecutorStake::get(); - let executor = funded_account::("executor", 1, stake); - - registry_executor::(executor.clone(), stake, true); - let total_active_executor = TotalActiveExecutors::::get(); - - #[extrinsic_call] - _(RawOrigin::Signed(executor.clone())); - - let executor_config = - Executors::::get(&executor).expect("Should be able to get the executor config"); - assert!(!executor_config.is_active); - assert_eq!(TotalActiveExecutors::::get(), total_active_executor - 1); - } - - #[benchmark] - fn resume_execution() { - let stake = T::MinExecutorStake::get(); - let executor = funded_account::("executor", 1, stake); - - // Register an inactive executor - registry_executor::(executor.clone(), stake, false); - let total_active_executor = TotalActiveExecutors::::get(); - - #[extrinsic_call] - _(RawOrigin::Signed(executor.clone())); - - let executor_config = - Executors::::get(&executor).expect("Should be able to get the executor config"); - assert!(executor_config.is_active); - assert_eq!(TotalActiveExecutors::::get(), total_active_executor + 1); - } - - #[benchmark] - fn update_public_key() { - let stake = T::MinExecutorStake::get(); - let executor = funded_account::("executor", 1, stake); - - registry_executor::(executor.clone(), stake, true); - - let new_public_key = ExecutorPublicKey::from_slice(&[2; 32]).unwrap(); - - #[extrinsic_call] - _(RawOrigin::Signed(executor.clone()), new_public_key.clone()); - - assert_eq!(NextKey::::get(&executor), Some(new_public_key.clone())); - assert_eq!(KeyOwner::::get(&new_public_key), Some(executor)); - } - - #[benchmark] - fn update_reward_address() { - let stake = T::MinExecutorStake::get(); - let executor = funded_account::("executor", 1, stake); - - registry_executor::(executor.clone(), stake, true); - - let new_reward_address: T::AccountId = account("new_reward_address", 2, SEED); - - #[extrinsic_call] - _( - RawOrigin::Signed(executor.clone()), - new_reward_address.clone(), - ); - - let executor_config = - Executors::::get(&executor).expect("Should be able to get the executor config"); - assert_eq!(executor_config.reward_address, new_reward_address); - } - - // Create an account with the given fund plus the `ExistentialDeposit` - fn funded_account( - name: &'static str, - index: u32, - fund: BalanceOf, - ) -> T::AccountId { - let account = account(name, index, SEED); - T::Currency::make_free_balance_be(&account, fund + T::Currency::minimum_balance()); - account - } - - // Registry an executor for later operations - fn registry_executor(executor: T::AccountId, stake: BalanceOf, is_active: bool) { - let public_key = ExecutorPublicKey::from_slice(&[1; 32]).unwrap(); - - assert_ok!(ExecutorRegistry::::register( - RawOrigin::Signed(executor.clone()).into(), - public_key.clone(), - executor.clone(), - is_active, - stake, - )); - - assert_eq!( - ExecutorRegistry::::executor_stake(&executor), - Some(stake) - ); - assert_eq!( - ExecutorRegistry::::executor_public_key(&executor), - Some(public_key) - ); - } - - impl_benchmark_test_suite!( - ExecutorRegistry, - crate::tests::new_test_ext(), - crate::tests::Test - ); -} diff --git a/domains/pallets/executor-registry/src/lib.rs b/domains/pallets/executor-registry/src/lib.rs deleted file mode 100644 index 7843bab84c1..00000000000 --- a/domains/pallets/executor-registry/src/lib.rs +++ /dev/null @@ -1,892 +0,0 @@ -// Copyright (C) 2021 Subspace Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! # Executor Registry Module - -#![cfg_attr(not(feature = "std"), no_std)] - -#[cfg(test)] -mod tests; - -#[cfg(feature = "runtime-benchmarks")] -mod benchmarking; - -pub mod weights; - -use frame_support::traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons}; -pub use pallet::*; -use sp_arithmetic::Percent; -use sp_domains::ExecutorPublicKey; -use sp_executor_registry::ExecutorRegistry; -use sp_runtime::traits::{CheckedAdd, CheckedSub}; -use sp_runtime::BoundedVec; -use sp_std::vec::Vec; - -type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; - -const EXECUTOR_LOCK_ID: LockIdentifier = *b"executor"; - -const MIN_ACTIVE_EXECUTORS_FACTOR: Percent = Percent::from_percent(75); - -#[frame_support::pallet] -mod pallet { - use super::{BalanceOf, MIN_ACTIVE_EXECUTORS_FACTOR}; - use crate::weights::WeightInfo; - use codec::Codec; - use frame_support::pallet_prelude::*; - use frame_support::traits::{Currency, LockableCurrency}; - use frame_system::pallet_prelude::*; - use sp_arithmetic::traits::{BaseArithmetic, Unsigned}; - use sp_domains::merkle_tree::authorities_merkle_tree; - use sp_domains::ExecutorPublicKey; - use sp_executor_registry::OnNewEpoch; - use sp_runtime::traits::{ - BlockNumberProvider, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Zero, - }; - use sp_runtime::FixedPointOperand; - use sp_std::collections::btree_map::BTreeMap; - use sp_std::fmt::Debug; - use sp_std::vec::Vec; - use subspace_core_primitives::Blake2b256Hash; - - /// Same sematic as `AtLeast32Bit` but requires at least `u128`. - pub trait AtLeast128Bit: - BaseArithmetic + From + From + From + From - { - } - - impl + From + From + From> AtLeast128Bit for T {} - - /// Same as `AtLeast128Bit` but bounded to be unsigned. - pub trait AtLeast128BitUnsigned: AtLeast128Bit + Unsigned {} - - impl AtLeast128BitUnsigned for T {} - - #[pallet::config] - pub trait Config: frame_system::Config { - type RuntimeEvent: From> + IsType<::RuntimeEvent>; - - type Currency: LockableCurrency; - - /// The stake weight of an executor. - type StakeWeight: Parameter - + Member - + AtLeast128BitUnsigned - + Codec - + Default - + Copy - + MaybeSerializeDeserialize - + Debug - + MaxEncodedLen - + TypeInfo - + FixedPointOperand - + From>; - - /// Minimum SSC required to be an executor. - #[pallet::constant] - type MinExecutorStake: Get>; - - /// Maximum SSC that can be staked by a single executor. - #[pallet::constant] - type MaxExecutorStake: Get>; - - /// Minimum number of executors. - /// - /// The minimum number of active executors is also constrained by this parameter with - /// `MIN_ACTIVE_EXECUTORS_FACTOR`. - #[pallet::constant] - type MinExecutors: Get; - - /// Maximum number of executors. - /// - /// Increase this number gradually as the network grows. - #[pallet::constant] - type MaxExecutors: Get; - - /// Maximum number of ongoing unlocking items per executor. - #[pallet::constant] - type MaxWithdrawals: Get; - - /// Number of blocks the withdrawn stake has to remain locked before it can become free. - /// - /// Typically should be the same with fraud proof challenge period, like one week for arbitrum. - /// - /// TODO: Use Slot instead of BlockNumber, which is closer to the actual elapsed time. - #[pallet::constant] - type WithdrawalDuration: Get; - - /// The amount of time each epoch should last in blocks. - /// - /// The executor set for the bundle election is scheduled to rotate on each new epoch. - #[pallet::constant] - type EpochDuration: Get; - - /// What to do on epoch changes. - type OnNewEpoch: OnNewEpoch; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; - } - - #[pallet::pallet] - #[pallet::without_storage_info] - pub struct Pallet(_); - - /// Represents the inactive stake of an executor after calling `decrease_stake`. - /// - /// An executor called `decrease_stake` to withdraw some stakes, which - /// have to wait for another lock-up period before making it transferrable again. - #[derive(Debug, Encode, Decode, TypeInfo, Clone, PartialEq, Eq)] - pub struct Withdrawal { - /// Amount of the unlocking balance. - pub amount: Balance, - /// Block number after which the balance can be really unlocked. - pub locked_until: BlockNumber, - } - - /// Executor configuration. - #[derive(DebugNoBound, Encode, Decode, TypeInfo, CloneNoBound, PartialEqNoBound, EqNoBound)] - #[scale_info(skip_type_params(T))] - pub struct ExecutorConfig { - /// Executor's signing key. - pub public_key: ExecutorPublicKey, - - /// Address for receiving the execution reward. - pub reward_address: T::AccountId, - - /// Whether the executor is actively participating in the bundle election. - pub is_active: bool, - - /// Amount of balance at stake. - /// - /// Only the `stake` is used for in the forthcoming bundle election. - pub stake: BalanceOf, - - /// Inactive stake still being frozen, which can be freed up once mature. - pub withdrawals: BoundedVec, T::BlockNumber>, T::MaxWithdrawals>, - } - - #[pallet::call] - impl Pallet { - /// Register the origin account as an executor. - #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::register())] - pub fn register( - origin: OriginFor, - public_key: ExecutorPublicKey, - reward_address: T::AccountId, - is_active: bool, - stake: BalanceOf, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - ensure!( - stake >= T::MinExecutorStake::get(), - Error::::StakeTooSmall - ); - ensure!( - stake <= T::MaxExecutorStake::get(), - Error::::StakeTooLarge - ); - ensure!( - !Executors::::contains_key(&who), - Error::::AlreadyExecutor - ); - ensure!( - Executors::::count() <= T::MaxExecutors::get(), - Error::::TooManyExecutors - ); - ensure!( - T::Currency::free_balance(&who) >= stake, - Error::::InsufficientBalance - ); - ensure!( - KeyOwner::::get(&public_key).is_none(), - Error::::DuplicatedKey - ); - - let executor_config = - Self::apply_register(&who, public_key, reward_address, is_active, stake)?; - - Self::deposit_event(Event::::NewExecutor { - who, - executor_config, - }); - - Ok(()) - } - - /// Declare no desire to be an executor and remove the registration. - // TODO: proper weight - #[pallet::call_index(1)] - #[pallet::weight({10_000})] - pub fn deregister(origin: OriginFor) -> DispatchResult { - let _who = ensure_signed(origin)?; - - // TODO: - // Ensure the number of remaining executors can't be lower than T::MinExecutors. - // Ensure the executor has no funds locked in this pallet(deposits and pending_withdrawals). - // Remove the corresponding entry from the Executors. - // Remove the corresponding entry from the KeyOwner. - // Deposit an event Deregistered. - - Ok(()) - } - - /// Increase the executor's stake by locking some more balance. - #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::increase_stake())] - pub fn increase_stake(origin: OriginFor, amount: BalanceOf) -> DispatchResult { - let who = ensure_signed(origin)?; - - if !amount.is_zero() { - ensure!( - T::Currency::free_balance(&who) >= amount, - Error::::InsufficientBalance - ); - - Executors::::try_mutate(&who, |maybe_executor_config| { - let executor_config = maybe_executor_config - .as_mut() - .ok_or(Error::::NotExecutor)?; - - let new_stake = executor_config - .stake - .checked_add(&amount) - .ok_or(Error::::StakeTooLarge)?; - - if new_stake > T::MaxExecutorStake::get() { - return Err(Error::::StakeTooLarge); - } - - executor_config.stake = new_stake; - - Self::lock_fund(&who, executor_config.stake); - - if executor_config.is_active { - Self::increase_total_active_stake(amount)?; - } - - Ok(()) - })?; - - Self::deposit_event(Event::::StakeIncreased { who, amount }); - } - - Ok(()) - } - - /// Decrease the executor stake by unlocking some balance. - /// - /// The reduced stake will be held locked for a while until it - /// can be withdrawn to be transferrable. - #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::decrease_stake())] - pub fn decrease_stake(origin: OriginFor, amount: BalanceOf) -> DispatchResult { - let who = ensure_signed(origin)?; - - if !amount.is_zero() { - Executors::::try_mutate(&who, |maybe_executor_config| { - let executor_config = maybe_executor_config - .as_mut() - .ok_or(Error::::NotExecutor)?; - - let new_stake = executor_config - .stake - .checked_sub(&amount) - .ok_or(Error::::InsufficientStake)?; - - if new_stake < T::MinExecutorStake::get() { - return Err(Error::::InsufficientStake); - } - - executor_config.stake = new_stake; - - let new_withdrawal = Withdrawal { - amount, - locked_until: frame_system::Pallet::::current_block_number() - + T::WithdrawalDuration::get(), - }; - - executor_config - .withdrawals - .try_push(new_withdrawal) - .map_err(|_| Error::::TooManyWithdrawals)?; - - if executor_config.is_active { - Self::decrease_total_active_stake(amount)?; - } - - Ok(()) - })?; - - Self::deposit_event(Event::::StakeDecreasedAndWithdrawalInitiated { - who, - amount, - }); - } - - Ok(()) - } - - /// Remove the item at given index which is due in the unlocking queue. - /// - /// The balance being locked will become free on success. - #[pallet::call_index(4)] - #[pallet::weight(T::WeightInfo::withdraw_stake())] - pub fn withdraw_stake(origin: OriginFor, withdrawal_index: u32) -> DispatchResult { - let who = ensure_signed(origin)?; - - Executors::::try_mutate(&who, |maybe_executor_config| -> DispatchResult { - let executor_config = maybe_executor_config - .as_mut() - .ok_or(Error::::NotExecutor)?; - - if withdrawal_index as usize >= executor_config.withdrawals.len() { - return Err(Error::::InvalidWithdrawalIndex.into()); - } - - let Withdrawal { - amount, - locked_until, - } = executor_config - .withdrawals - .swap_remove(withdrawal_index as usize); - - let current_block_number = frame_system::Pallet::::current_block_number(); - - if current_block_number <= locked_until { - return Err(Error::::PrematureWithdrawal.into()); - } - - let inactive_stake = executor_config - .withdrawals - .iter() - .fold(Zero::zero(), |acc, x| acc + x.amount); - - let new_total = executor_config.stake + inactive_stake; - - Self::lock_fund(&who, new_total); - - Self::deposit_event(Event::::WithdrawalCompleted { - who: who.clone(), - withdrawn: amount, - }); - - Ok(()) - }) - } - - /// Stop participating in the bundle election temporarily. - #[pallet::call_index(5)] - #[pallet::weight(T::WeightInfo::pause_execution())] - pub fn pause_execution(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - - Executors::::try_mutate(&who, |maybe_executor_config| -> DispatchResult { - let executor_config = maybe_executor_config - .as_mut() - .ok_or(Error::::NotExecutor)?; - - if executor_config.is_active { - let min_active_executors = - MIN_ACTIVE_EXECUTORS_FACTOR.mul_ceil(T::MinExecutors::get()); - - if TotalActiveExecutors::::get() == min_active_executors { - return Err(Error::::TooFewActiveExecutors.into()); - } - - executor_config.is_active = false; - - Self::decrease_total_active_stake(executor_config.stake)?; - TotalActiveExecutors::::mutate(|total| { - *total -= 1; - }); - - Self::deposit_event(Event::::Paused { who: who.clone() }); - } - - Ok(()) - }) - } - - /// Participate in the bundle election again. - #[pallet::call_index(6)] - #[pallet::weight(T::WeightInfo::resume_execution())] - pub fn resume_execution(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - - Executors::::try_mutate(&who, |maybe_executor_config| -> DispatchResult { - let executor_config = maybe_executor_config - .as_mut() - .ok_or(Error::::NotExecutor)?; - - if !executor_config.is_active { - executor_config.is_active = true; - - Self::increase_total_active_stake(executor_config.stake)?; - TotalActiveExecutors::::mutate(|total| { - *total += 1; - }); - - Self::deposit_event(Event::::Resumed { who: who.clone() }); - } - - Ok(()) - }) - } - - /// Set a new executor public key. - /// - /// It won't take effect until next epoch. - #[pallet::call_index(7)] - #[pallet::weight(T::WeightInfo::update_public_key())] - pub fn update_public_key( - origin: OriginFor, - next_key: ExecutorPublicKey, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - ensure!( - KeyOwner::::get(&next_key).is_none(), - Error::::DuplicatedKey - ); - - ensure!(Executors::::contains_key(&who), Error::::NotExecutor); - - NextKey::::insert(&who, &next_key); - KeyOwner::::insert(&next_key, &who); - - Self::deposit_event(Event::::PublicKeyUpdated { who, next_key }); - - Ok(()) - } - - /// Set a new reward address. - #[pallet::call_index(8)] - #[pallet::weight(T::WeightInfo::update_reward_address())] - pub fn update_reward_address(origin: OriginFor, new: T::AccountId) -> DispatchResult { - let who = ensure_signed(origin)?; - - Executors::::try_mutate(&who, |maybe_executor_config| -> DispatchResult { - let executor_config = maybe_executor_config - .as_mut() - .ok_or(Error::::NotExecutor)?; - - if executor_config.reward_address != new { - executor_config.reward_address = new.clone(); - - Self::deposit_event(Event::::RewardAddressUpdated { - who: who.clone(), - new, - }); - } - - Ok(()) - }) - } - } - - type GenesisExecutorInfo = ( - ::AccountId, - BalanceOf, - ::AccountId, - ExecutorPublicKey, - ); - - #[pallet::genesis_config] - pub struct GenesisConfig { - pub executors: Vec>, - pub slot_probability: (u64, u64), - } - - impl Default for GenesisConfig { - #[inline] - fn default() -> Self { - Self { - executors: Vec::new(), - slot_probability: (1u64, 1u64), - } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - assert!( - self.executors.len() >= T::MinExecutors::get() as usize, - "Too few genesis executors" - ); - assert!( - self.executors.len() <= T::MaxExecutors::get() as usize, - "Too many genesis executors" - ); - - let mut authorities = Vec::new(); - for (executor, initial_stake, reward_address, public_key) in self.executors.clone() { - assert!( - initial_stake >= T::MinExecutorStake::get() - && initial_stake <= T::MaxExecutorStake::get(), - "Initial stake can not be too small or too large" - ); - assert!( - T::Currency::free_balance(&executor) >= initial_stake, - "Genesis executor does not have enough balance to stake." - ); - - Pallet::::apply_register( - &executor, - public_key.clone(), - reward_address, - true, - initial_stake, - ) - .expect("Genesis executor registration can not fail"); - - let stake_weight: T::StakeWeight = initial_stake.into(); - authorities.push((public_key, stake_weight)); - } - - let merkle_tree = authorities_merkle_tree(authorities.as_slice()); - let merkle_root = merkle_tree - .root() - .expect("Merkle root must exist as authorities are always non-empty; qed"); - AuthoritiesRoot::::put(merkle_root); - - let bounded_authorities = BoundedVec::<_, T::MaxExecutors>::try_from(authorities) - .expect("T::MaxExecutors bound is checked above; qed"); - Authorities::::put(bounded_authorities); - - let total_stake_weight: T::StakeWeight = TotalActiveStake::::get().into(); - TotalStakeWeight::::put(total_stake_weight); - - SlotProbability::::put(self.slot_probability); - } - } - - #[pallet::error] - pub enum Error { - /// The amount of deposit is smaller than the `T::MinExecutorStake` bound. - StakeTooSmall, - - /// The amount of deposit is larger than the `T::MaxExecutorStake` bound. - StakeTooLarge, - - /// An account is already an executor. - AlreadyExecutor, - - /// The number of executors exceeds the `T::MaxExecutors` bound. - TooManyExecutors, - - /// An account does not have enough balance. - InsufficientBalance, - - /// The user is not an executor. - NotExecutor, - - /// Can not continue as the stake would be lower than the `T::MinExecutorStake` bound. - /// - /// If you want to withdraw all the stake, use `deregister` instead. - InsufficientStake, - - /// The withdrawal queue size reached the upper bound. - TooManyWithdrawals, - - /// The withdrawal entry does not exist for the given index. - InvalidWithdrawalIndex, - - /// The withdrawal entry is still undue. - PrematureWithdrawal, - - /// Too few active executors. - TooFewActiveExecutors, - - /// Executor public key is already occupied. - DuplicatedKey, - - /// An arithmetic overflow error. - ArithmeticOverflow, - - /// An arithmetic underflow error. - ArithmeticUnderflow, - } - - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { - /// A new executor. - NewExecutor { - who: T::AccountId, - executor_config: ExecutorConfig, - }, - - /// An executor deposited this account. - StakeIncreased { - who: T::AccountId, - amount: BalanceOf, - }, - - /// An executor requested to unstake this account. - StakeDecreasedAndWithdrawalInitiated { - who: T::AccountId, - amount: BalanceOf, - }, - - /// The funds locked as inactive stake became free. - WithdrawalCompleted { - who: T::AccountId, - withdrawn: BalanceOf, - }, - - /// An executor paused the execution. - Paused { who: T::AccountId }, - - /// An executor resumed the execution. - Resumed { who: T::AccountId }, - - /// An executor updated its public key. - PublicKeyUpdated { - who: T::AccountId, - next_key: ExecutorPublicKey, - }, - - /// An executor updated its reward address. - RewardAddressUpdated { - who: T::AccountId, - new: T::AccountId, - }, - } - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(block_number: T::BlockNumber) -> Weight { - // Enact the epoch change: - // 1. Snapshot the latest state of active executors. - // 2. Activate the new executor public key if any. - if (block_number % T::EpochDuration::get()).is_zero() { - let mut executor_weights = BTreeMap::new(); - - // TODO: currently, we are iterating the Executors map, figure out how many executors - // we can support with this approach and optimize it when it does not satisfy our requirement. - let authorities = Executors::::iter() - .filter(|(_who, executor_config)| executor_config.is_active) - .map(|(who, executor_config)| { - let public_key = match NextKey::::take(&who) { - Some(new_key) => { - // It's okay to update a field while iterating the storage map. - // - // TODO: add a test that the public_key can be updated and the key_owner - // will be deleted as expected. - Executors::::mutate(&who, |maybe_executor_config| { - let executor_config = maybe_executor_config - .as_mut() - .expect("Executor config must exist; qed"); - - // Clear the old key owner. - KeyOwner::::remove(&executor_config.public_key); - - executor_config.public_key = new_key.clone(); - }); - - new_key - } - None => executor_config.public_key, - }; - - let stake_weight: T::StakeWeight = executor_config.stake.into(); - - executor_weights.insert(who, stake_weight); - - (public_key, stake_weight) - }) - .collect::>(); - - let merkle_tree = authorities_merkle_tree(authorities.as_slice()); - let merkle_root = merkle_tree - .root() - .expect("Merkle root must exist as authorities are always non-empty; qed"); - AuthoritiesRoot::::put(merkle_root); - - let bounded_authorities = BoundedVec::<_, T::MaxExecutors>::try_from(authorities) - .expect( - "T::MaxExecutors bound is ensured while registering a new executor; qed", - ); - Authorities::::put(bounded_authorities); - - let total_stake_weight: T::StakeWeight = TotalActiveStake::::get().into(); - TotalStakeWeight::::put(total_stake_weight); - - T::OnNewEpoch::on_new_epoch(executor_weights); - } - - // TODO: proper weight - Weight::zero() - } - - fn on_idle(_n: T::BlockNumber, _remaining_weight: Weight) -> Weight { - // TODO: Release the mature withdrawal automatically so that users do not have to call - // `withdraw_unlocked_deposit` manually. - Weight::zero() - } - } - - /// A map tracking all the executors. - #[pallet::storage] - pub(super) type Executors = - CountedStorageMap<_, Twox64Concat, T::AccountId, ExecutorConfig, OptionQuery>; - - /// Total amount of active stake in the system. - /// - /// Sum of the `stake` of each active executor. - #[pallet::storage] - pub(super) type TotalActiveStake = StorageValue<_, BalanceOf, ValueQuery>; - - /// Total number of active executors. - #[pallet::storage] - pub(super) type TotalActiveExecutors = StorageValue<_, u32, ValueQuery>; - - /// Pending executor public key for the next epoch. - #[pallet::storage] - pub(super) type NextKey = - StorageMap<_, Twox64Concat, T::AccountId, ExecutorPublicKey, OptionQuery>; - - /// A map tracking the owner of current and next key of each executor. - #[pallet::storage] - #[pallet::getter(fn key_owner)] - pub(super) type KeyOwner = - StorageMap<_, Twox64Concat, ExecutorPublicKey, T::AccountId, OptionQuery>; - - /// Current epoch executor authorities. - #[pallet::storage] - #[pallet::getter(fn authorities)] - pub(super) type Authorities = StorageValue< - _, - BoundedVec<(ExecutorPublicKey, T::StakeWeight), T::MaxExecutors>, - ValueQuery, - >; - - /// Merkle root of authorities. - #[pallet::storage] - pub(super) type AuthoritiesRoot = StorageValue<_, Blake2b256Hash, ValueQuery>; - - /// Total stake weight of authorities. - #[pallet::storage] - #[pallet::getter(fn total_stake_weight)] - pub(super) type TotalStakeWeight = StorageValue<_, T::StakeWeight, ValueQuery>; - - /// How many bundles on average in a number of slots. - /// - /// TODO: Add a root call to update the slot probability. - #[pallet::storage] - #[pallet::getter(fn slot_probability)] - pub(super) type SlotProbability = StorageValue<_, (u64, u64), ValueQuery>; -} - -impl ExecutorRegistry, T::StakeWeight> for Pallet { - fn executor_stake(who: &T::AccountId) -> Option> { - Executors::::get(who).map(|executor| executor.stake) - } - - fn executor_public_key(who: &T::AccountId) -> Option { - Executors::::get(who).map(|executor_config| executor_config.public_key) - } - - fn key_owner_storage_key(executor_public_key: &ExecutorPublicKey) -> Vec { - Self::key_owner_hashed_key_for(executor_public_key) - } - - fn authority_stake_weight(who: &T::AccountId) -> Option { - Executors::::get(who).and_then(|executor_config| { - Authorities::::get() - .iter() - .find_map(|(authority, stake_weight)| { - if *authority == executor_config.public_key { - Some(*stake_weight) - } else { - None - } - }) - }) - } - - #[cfg(feature = "runtime-benchmarks")] - fn unchecked_register( - executor: T::AccountId, - public_key: ExecutorPublicKey, - stake: BalanceOf, - ) { - Self::apply_register(&executor.clone(), public_key, executor, true, stake) - .expect("executor register should succeed"); - } -} - -impl Pallet { - pub fn key_owner_hashed_key_for(executor_public_key: &ExecutorPublicKey) -> Vec { - KeyOwner::::hashed_key_for(executor_public_key) - } - - fn lock_fund(who: &T::AccountId, value: BalanceOf) { - T::Currency::set_lock(EXECUTOR_LOCK_ID, who, value, WithdrawReasons::all()); - } - - fn apply_register( - who: &T::AccountId, - public_key: ExecutorPublicKey, - reward_address: T::AccountId, - is_active: bool, - stake: BalanceOf, - ) -> Result, Error> { - Self::lock_fund(who, stake); - - KeyOwner::::insert(&public_key, who); - - let executor_config = ExecutorConfig { - public_key, - reward_address, - is_active, - stake, - withdrawals: BoundedVec::default(), - }; - Executors::::insert(who, &executor_config); - - if is_active { - Self::increase_total_active_stake(stake)?; - TotalActiveExecutors::::mutate(|total| { - *total += 1; - }); - } - - Ok(executor_config) - } - - fn increase_total_active_stake(value: BalanceOf) -> Result<(), Error> { - let old = TotalActiveStake::::get(); - let new = old - .checked_add(&value) - .ok_or(Error::::ArithmeticOverflow)?; - TotalActiveStake::::put(new); - Ok(()) - } - - fn decrease_total_active_stake(value: BalanceOf) -> Result<(), Error> { - let old = TotalActiveStake::::get(); - let new = old - .checked_sub(&value) - .ok_or(Error::::ArithmeticUnderflow)?; - TotalActiveStake::::put(new); - Ok(()) - } -} diff --git a/domains/pallets/executor-registry/src/tests.rs b/domains/pallets/executor-registry/src/tests.rs deleted file mode 100644 index 64fbe68664b..00000000000 --- a/domains/pallets/executor-registry/src/tests.rs +++ /dev/null @@ -1,490 +0,0 @@ -use crate::{ - self as pallet_executor_registry, Error, ExecutorConfig, Executors, KeyOwner, - TotalActiveExecutors, TotalActiveStake, TotalStakeWeight, Withdrawal, -}; -use frame_support::traits::{ConstU16, ConstU32, ConstU64, GenesisBuild, Hooks}; -use frame_support::{assert_noop, assert_ok, bounded_vec, parameter_types}; -use frame_system::RawOrigin; -use pallet_balances::AccountData; -use sp_core::crypto::Pair; -use sp_core::{H256, U256}; -use sp_domains::{ExecutorPair, StakeWeight}; -use sp_runtime::testing::Header; -use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; - -type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -type Block = frame_system::mocking::MockBlock; - -frame_support::construct_runtime!( - pub struct Test - where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system, - Balances: pallet_balances, - ExecutorRegistry: pallet_executor_registry, - } -); - -type AccountId = u64; -type BlockNumber = u64; -type Balance = u128; -type Hash = H256; - -impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - type Index = u64; - type BlockNumber = BlockNumber; - type Hash = Hash; - type Hashing = BlakeTwo256; - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Header = Header; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = ConstU64<2>; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = ConstU16<42>; - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; -} - -parameter_types! { - pub static ExistentialDeposit: Balance = 1; -} - -impl pallet_balances::Config for Test { - type MaxLocks = (); - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - type Balance = Balance; - type DustRemoval = (); - type RuntimeEvent = RuntimeEvent; - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); - type FreezeIdentifier = (); - type MaxFreezes = (); - type RuntimeHoldReason = (); - type MaxHolds = (); -} - -parameter_types! { - pub const MinExecutorStake: Balance = 10; - pub const MaxExecutorStake: Balance = StakeWeight::MAX - 1; - pub const MinExecutors: u32 = 1; - pub const MaxExecutors: u32 = 10; - pub const EpochDuration: BlockNumber = 3; - pub const MaxWithdrawals: u32 = 1; - pub const WithdrawalDuration: BlockNumber = 10; -} - -impl pallet_executor_registry::Config for Test { - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type StakeWeight = StakeWeight; - type MinExecutorStake = MinExecutorStake; - type MaxExecutorStake = MaxExecutorStake; - type MinExecutors = MinExecutors; - type MaxExecutors = MaxExecutors; - type MaxWithdrawals = MaxWithdrawals; - type WithdrawalDuration = WithdrawalDuration; - type EpochDuration = EpochDuration; - type OnNewEpoch = (); - type WeightInfo = (); -} - -pub(crate) fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); - - pallet_balances::GenesisConfig:: { - balances: vec![(1, 1000), (2, 2000), (3, 3000), (4, 4000)], - } - .assimilate_storage(&mut t) - .unwrap(); - - pallet_executor_registry::GenesisConfig:: { - executors: vec![( - 1, - 100, - 1 + 10000, - ExecutorPair::from_seed(&U256::from(1u32).into()).public(), - )], - slot_probability: (1u64, 1u64), - } - .assimilate_storage(&mut t) - .unwrap(); - - t.into() -} - -#[test] -fn register_should_work() { - new_test_ext().execute_with(|| { - // Check the registration of genesis executors. - let genesis_executor_public_key = - ExecutorPair::from_seed(&U256::from(1u32).into()).public(); - assert_eq!(TotalActiveStake::::get(), 100); - assert_eq!(TotalActiveExecutors::::get(), 1); - assert_eq!( - KeyOwner::::get(genesis_executor_public_key).unwrap(), - 1 - ); - - let public_key = ExecutorPair::from_seed(&U256::from(2u32).into()).public(); - let reward_address = 2 + 10_000; - let is_active = true; - let stake = 200; - - assert_noop!( - ExecutorRegistry::register( - RuntimeOrigin::signed(1), - public_key.clone(), - reward_address, - is_active, - StakeWeight::MAX, - ), - Error::::StakeTooLarge - ); - assert_noop!( - ExecutorRegistry::register( - RuntimeOrigin::signed(1), - public_key.clone(), - reward_address, - true, - 1 - ), - Error::::StakeTooSmall - ); - assert_noop!( - ExecutorRegistry::register( - RuntimeOrigin::signed(8), - public_key.clone(), - reward_address, - true, - 100 - ), - Error::::InsufficientBalance - ); - assert_noop!( - ExecutorRegistry::register( - RuntimeOrigin::signed(1), - public_key.clone(), - reward_address, - true, - stake - ), - Error::::AlreadyExecutor - ); - - assert_ok!(ExecutorRegistry::register( - RuntimeOrigin::signed(2), - public_key.clone(), - reward_address, - is_active, - stake, - )); - assert_eq!( - frame_system::Account::::get(2).data, - AccountData { - free: 2000, - reserved: 0, - frozen: stake, - ..AccountData::default() - } - ); - assert_eq!(KeyOwner::::get(&public_key).unwrap(), 2); - assert_eq!( - Executors::::get(2), - Some(ExecutorConfig { - public_key, - reward_address, - is_active, - stake, - withdrawals: Default::default() - }) - ); - assert_eq!(TotalActiveStake::::get(), 100 + stake); - assert_eq!(TotalActiveExecutors::::get(), 2); - }); -} - -#[test] -fn stake_extra_should_work() { - new_test_ext().execute_with(|| { - let executor_config = Executors::::get(1).unwrap(); - assert_eq!( - frame_system::Account::::get(1).data, - AccountData { - free: 1000, - reserved: 0, - frozen: 100, - ..AccountData::default() - } - ); - let extra = 200; - assert_ok!(ExecutorRegistry::increase_stake( - RuntimeOrigin::signed(1), - extra - )); - assert_eq!( - Executors::::get(1).unwrap(), - ExecutorConfig { - stake: executor_config.stake + extra, - ..executor_config - } - ); - assert_eq!( - frame_system::Account::::get(1).data, - AccountData { - free: 1000, - reserved: 0, - frozen: 100 + extra, - ..AccountData::default() - } - ); - }); -} - -#[test] -fn decrease_and_withdraw_stake_should_work() { - new_test_ext().execute_with(|| { - System::set_block_number(1); - - assert_eq!( - frame_system::Account::::get(1).data, - AccountData { - free: 1000, - reserved: 0, - frozen: 100, - ..AccountData::default() - } - ); - assert_noop!( - ExecutorRegistry::decrease_stake(RuntimeOrigin::signed(1), 1000), - Error::::InsufficientStake - ); - assert_noop!( - ExecutorRegistry::decrease_stake(RuntimeOrigin::signed(1), Balance::MAX), - Error::::InsufficientStake - ); - let executor_config = Executors::::get(1).unwrap(); - let to_decrease = 10; - - assert_ok!(ExecutorRegistry::decrease_stake( - RuntimeOrigin::signed(1), - to_decrease - )); - - assert_eq!( - frame_system::Account::::get(1).data, - AccountData { - free: 1000, - reserved: 0, - frozen: 100, - ..AccountData::default() - } - ); - - assert_eq!( - Executors::::get(1).unwrap(), - ExecutorConfig { - withdrawals: bounded_vec![Withdrawal { - amount: 10, - locked_until: 11 - }], - stake: executor_config.stake - to_decrease, - ..executor_config - } - ); - - System::set_block_number(11); - assert_noop!( - ExecutorRegistry::withdraw_stake(RuntimeOrigin::signed(1), 0), - Error::::PrematureWithdrawal - ); - - System::set_block_number(12); - let executor_config = Executors::::get(1).unwrap(); - assert_ok!(ExecutorRegistry::withdraw_stake( - RuntimeOrigin::signed(1), - 0 - )); - assert_eq!( - Executors::::get(1).unwrap(), - ExecutorConfig { - withdrawals: Default::default(), - ..executor_config - } - ); - assert_eq!( - frame_system::Account::::get(1).data, - AccountData { - free: 1000, - reserved: 0, - frozen: 90, - ..AccountData::default() - } - ); - }); -} - -#[test] -fn pause_and_resume_execution_should_work() { - new_test_ext().execute_with(|| { - assert_noop!( - ExecutorRegistry::pause_execution(RuntimeOrigin::signed(1)), - Error::::TooFewActiveExecutors - ); - - let public_key = ExecutorPair::from_seed(&U256::from(2u32).into()).public(); - let reward_address = 2 + 10_000; - let is_active = false; - let stake = 200; - - assert_ok!(ExecutorRegistry::register( - RuntimeOrigin::signed(2), - public_key, - reward_address, - is_active, - stake - )); - - assert_eq!(TotalActiveStake::::get(), 100); - assert_eq!(TotalActiveExecutors::::get(), 1); - - assert_ok!(ExecutorRegistry::resume_execution(RuntimeOrigin::signed(2))); - - assert_eq!(TotalActiveStake::::get(), 100 + 200); - assert_eq!(TotalActiveExecutors::::get(), 2); - - assert_ok!(ExecutorRegistry::pause_execution(RuntimeOrigin::signed(2))); - - assert_eq!(TotalActiveStake::::get(), 100); - assert_eq!(TotalActiveExecutors::::get(), 1); - }); -} - -#[test] -fn update_public_key_should_work() { - new_test_ext().execute_with(|| { - let new_public_key = ExecutorPair::from_seed(&U256::from(10u32).into()).public(); - assert_noop!( - ExecutorRegistry::update_public_key(RuntimeOrigin::signed(10), new_public_key), - Error::::NotExecutor - ); - - let executor_config_1 = Executors::::get(1).unwrap(); - assert_noop!( - ExecutorRegistry::update_public_key( - RuntimeOrigin::signed(1), - executor_config_1.public_key.clone() - ), - Error::::DuplicatedKey - ); - - let public_key = ExecutorPair::from_seed(&U256::from(2u32).into()).public(); - let reward_address = 2 + 10_000; - let is_active = true; - let stake = 200; - - assert_ok!(ExecutorRegistry::register( - RuntimeOrigin::signed(2), - public_key, - reward_address, - is_active, - stake, - )); - - assert_noop!( - ExecutorRegistry::update_public_key( - RuntimeOrigin::signed(2), - executor_config_1.public_key - ), - Error::::DuplicatedKey - ); - }); -} - -#[test] -fn update_reward_address_should_work() { - new_test_ext().execute_with(|| { - let executor_config = Executors::::get(1).unwrap(); - assert_ok!(ExecutorRegistry::update_reward_address( - RuntimeOrigin::signed(1), - 888 - )); - assert_eq!( - Executors::::get(1).unwrap(), - ExecutorConfig { - reward_address: 888, - ..executor_config - } - ); - }); -} - -#[test] -fn test_total_stake_overflow() { - new_test_ext().execute_with(|| { - Balances::force_set_balance(RawOrigin::Root.into(), 2, StakeWeight::MAX / 2).unwrap(); - Balances::force_set_balance(RawOrigin::Root.into(), 3, StakeWeight::MAX / 2).unwrap(); - - assert_eq!(TotalActiveStake::::get(), 100); - assert_eq!(TotalStakeWeight::::get(), 100); - - // `register` trigger overflow error - assert_ok!(ExecutorRegistry::register( - RuntimeOrigin::signed(2), - ExecutorPair::from_seed(&U256::from(2u32).into()).public(), - 2 + 10000, - true, - StakeWeight::MAX / 2, - )); - assert_noop!( - ExecutorRegistry::register( - RuntimeOrigin::signed(3), - ExecutorPair::from_seed(&U256::from(3u32).into()).public(), - 3 + 10000, - true, - StakeWeight::MAX / 2, - ), - Error::::ArithmeticOverflow - ); - - // `increase_stake` trigger overflow error - Balances::force_set_balance(RawOrigin::Root.into(), 1, StakeWeight::MAX / 2).unwrap(); - assert_noop!( - ExecutorRegistry::increase_stake(RuntimeOrigin::signed(1), StakeWeight::MAX / 2), - Error::::ArithmeticOverflow - ); - - // `resume_execution` trigger overflow error - assert_ok!(ExecutorRegistry::pause_execution(RuntimeOrigin::signed(2))); - assert_ok!(ExecutorRegistry::increase_stake( - RuntimeOrigin::signed(1), - StakeWeight::MAX / 2 - )); - assert_noop!( - ExecutorRegistry::resume_execution(RuntimeOrigin::signed(2),), - Error::::ArithmeticOverflow - ); - - // `TotalStakeWeight` should be updated correctly - ExecutorRegistry::on_initialize(0); - assert_eq!(TotalStakeWeight::::get(), StakeWeight::MAX / 2 + 100); - }); -} diff --git a/domains/pallets/executor-registry/src/weights.rs b/domains/pallets/executor-registry/src/weights.rs deleted file mode 100644 index f2bbfa03437..00000000000 --- a/domains/pallets/executor-registry/src/weights.rs +++ /dev/null @@ -1,313 +0,0 @@ - -//! Autogenerated weights for pallet_executor_registry -//! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-05-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `local`, CPU: `` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 - -// Executed Command: -// ./target/release/subspace-node -// executor -// benchmark -// pallet -// --chain=dev -// --steps=50 -// --repeat=20 -// --pallet=pallet_executor_registry -// --extrinsic=* -// --execution=wasm -// --wasm-execution=compiled -// --heap-pages=4096 -// --output=./domains/pallets/executor-registry/src/weights.rs -// --template -// ./frame-weight-template.hbs - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use core::marker::PhantomData; - -/// Weight functions needed for pallet_executor_registry. -pub trait WeightInfo { - fn register() -> Weight; - fn increase_stake() -> Weight; - fn decrease_stake() -> Weight; - fn withdraw_stake() -> Weight; - fn pause_execution() -> Weight; - fn resume_execution() -> Weight; - fn update_public_key() -> Weight; - fn update_reward_address() -> Weight; -} - -/// Weights for pallet_executor_registry using the Substrate node and recommended hardware. -pub struct SubstrateWeight(PhantomData); -impl WeightInfo for SubstrateWeight { - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry CounterForExecutors (r:1 w:1) - /// Proof: ExecutorRegistry CounterForExecutors (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ExecutorRegistry KeyOwner (r:1 w:1) - /// Proof Skipped: ExecutorRegistry KeyOwner (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveExecutors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveExecutors (max_values: Some(1), max_size: None, mode: Measured) - fn register() -> Weight { - // Proof Size summary in bytes: - // Measured: `590` - // Estimated: `25620` - // Minimum execution time: 54_000_000 picoseconds. - Weight::from_parts(55_000_000, 25620) - .saturating_add(T::DbWeight::get().reads(8_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) - } - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - fn increase_stake() -> Weight { - // Proof Size summary in bytes: - // Measured: `627` - // Estimated: `18075` - // Minimum execution time: 41_000_000 picoseconds. - Weight::from_parts(42_000_000, 18075) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(4_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - fn decrease_stake() -> Weight { - // Proof Size summary in bytes: - // Measured: `424` - // Estimated: `5798` - // Minimum execution time: 18_000_000 picoseconds. - Weight::from_parts(18_000_000, 5798) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - fn withdraw_stake() -> Weight { - // Proof Size summary in bytes: - // Measured: `607` - // Estimated: `15943` - // Minimum execution time: 36_000_000 picoseconds. - Weight::from_parts(37_000_000, 15943) - .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveExecutors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveExecutors (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - fn pause_execution() -> Weight { - // Proof Size summary in bytes: - // Measured: `424` - // Estimated: `7707` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(20_000_000, 7707) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveExecutors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveExecutors (max_values: Some(1), max_size: None, mode: Measured) - fn resume_execution() -> Weight { - // Proof Size summary in bytes: - // Measured: `424` - // Estimated: `7707` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 7707) - .saturating_add(T::DbWeight::get().reads(3_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) - } - /// Storage: ExecutorRegistry KeyOwner (r:1 w:1) - /// Proof Skipped: ExecutorRegistry KeyOwner (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry Executors (r:1 w:0) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry NextKey (r:0 w:1) - /// Proof Skipped: ExecutorRegistry NextKey (max_values: None, max_size: None, mode: Measured) - fn update_public_key() -> Weight { - // Proof Size summary in bytes: - // Measured: `412` - // Estimated: `8166` - // Minimum execution time: 18_000_000 picoseconds. - Weight::from_parts(19_000_000, 8166) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - fn update_reward_address() -> Weight { - // Proof Size summary in bytes: - // Measured: `384` - // Estimated: `3849` - // Minimum execution time: 14_000_000 picoseconds. - Weight::from_parts(14_000_000, 3849) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } -} - -// For backwards compatibility and tests -impl WeightInfo for () { - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry CounterForExecutors (r:1 w:1) - /// Proof: ExecutorRegistry CounterForExecutors (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ExecutorRegistry KeyOwner (r:1 w:1) - /// Proof Skipped: ExecutorRegistry KeyOwner (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveExecutors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveExecutors (max_values: Some(1), max_size: None, mode: Measured) - fn register() -> Weight { - // Proof Size summary in bytes: - // Measured: `590` - // Estimated: `25620` - // Minimum execution time: 54_000_000 picoseconds. - Weight::from_parts(55_000_000, 25620) - .saturating_add(RocksDbWeight::get().reads(8_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) - } - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - fn increase_stake() -> Weight { - // Proof Size summary in bytes: - // Measured: `627` - // Estimated: `18075` - // Minimum execution time: 41_000_000 picoseconds. - Weight::from_parts(42_000_000, 18075) - .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(4_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - fn decrease_stake() -> Weight { - // Proof Size summary in bytes: - // Measured: `424` - // Estimated: `5798` - // Minimum execution time: 18_000_000 picoseconds. - Weight::from_parts(18_000_000, 5798) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: Balances Locks (r:1 w:1) - /// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen) - /// Storage: Balances Freezes (r:1 w:0) - /// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) - /// Storage: System Account (r:1 w:1) - /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) - fn withdraw_stake() -> Weight { - // Proof Size summary in bytes: - // Measured: `607` - // Estimated: `15943` - // Minimum execution time: 36_000_000 picoseconds. - Weight::from_parts(37_000_000, 15943) - .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveExecutors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveExecutors (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - fn pause_execution() -> Weight { - // Proof Size summary in bytes: - // Measured: `424` - // Estimated: `7707` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(20_000_000, 7707) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveStake (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveStake (max_values: Some(1), max_size: None, mode: Measured) - /// Storage: ExecutorRegistry TotalActiveExecutors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry TotalActiveExecutors (max_values: Some(1), max_size: None, mode: Measured) - fn resume_execution() -> Weight { - // Proof Size summary in bytes: - // Measured: `424` - // Estimated: `7707` - // Minimum execution time: 19_000_000 picoseconds. - Weight::from_parts(19_000_000, 7707) - .saturating_add(RocksDbWeight::get().reads(3_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) - } - /// Storage: ExecutorRegistry KeyOwner (r:1 w:1) - /// Proof Skipped: ExecutorRegistry KeyOwner (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry Executors (r:1 w:0) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - /// Storage: ExecutorRegistry NextKey (r:0 w:1) - /// Proof Skipped: ExecutorRegistry NextKey (max_values: None, max_size: None, mode: Measured) - fn update_public_key() -> Weight { - // Proof Size summary in bytes: - // Measured: `412` - // Estimated: `8166` - // Minimum execution time: 18_000_000 picoseconds. - Weight::from_parts(19_000_000, 8166) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: ExecutorRegistry Executors (r:1 w:1) - /// Proof Skipped: ExecutorRegistry Executors (max_values: None, max_size: None, mode: Measured) - fn update_reward_address() -> Weight { - // Proof Size summary in bytes: - // Measured: `384` - // Estimated: `3849` - // Minimum execution time: 14_000_000 picoseconds. - Weight::from_parts(14_000_000, 3849) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } -} diff --git a/domains/pallets/messenger/Cargo.toml b/domains/pallets/messenger/Cargo.toml index 63508d4511e..ded6a296f8b 100644 --- a/domains/pallets/messenger/Cargo.toml +++ b/domains/pallets/messenger/Cargo.toml @@ -14,24 +14,24 @@ include = [ ] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } log = { version = "0.4.19", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } sp-messenger = { version = "0.1.0", default-features = false, path = "../../primitives/messenger" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [dev-dependencies] domain-runtime-primitives = { path = "../../primitives/runtime" } -pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } pallet-transporter = { version = "0.1.0", path = "../transporter" } -sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/domains/pallets/messenger/src/lib.rs b/domains/pallets/messenger/src/lib.rs index 1a5a74162f1..ff3ceed47a7 100644 --- a/domains/pallets/messenger/src/lib.rs +++ b/domains/pallets/messenger/src/lib.rs @@ -111,7 +111,6 @@ mod pallet { ProtocolMessageRequest, RequestResponse, VersionedPayload, }; use sp_messenger::verification::{StorageProofVerifier, VerificationError}; - use sp_runtime::traits::CheckedSub; use sp_runtime::ArithmeticError; use sp_std::boxed::Box; use sp_std::vec::Vec; @@ -732,11 +731,9 @@ mod pallet { dst_domain_id: DomainId, init_params: InitiateChannelParams>, ) -> Result { + // TODO: system domain and core domain have been removed. // ensure domain is either system domain or core domain - ensure!( - dst_domain_id.is_core() || dst_domain_id.is_system(), - Error::::InvalidDomain, - ); + // ensure!(dst_domain_id.is_core(), Error::::InvalidDomain,); let channel_id = NextChannelId::::get(dst_domain_id); let next_channel_id = channel_id @@ -928,32 +925,33 @@ mod pallet { TransactionValidityError::Invalid(InvalidTransaction::BadProof), )?; + // TODO: system domain has been removed // on system domain, ensure the core domain info is at K-depth and state root matches - if T::SelfDomainId::get().is_system() { - if let Some((domain_id, block_info, state_root)) = - extracted_state_roots.core_domain_info.clone() - { - // ensure the block is at-least k-deep - let confirmed = T::DomainInfo::domain_best_number(domain_id) - .and_then(|best_number| { - best_number - .checked_sub(&T::ConfirmationDepth::get()) - .map(|confirmed_number| confirmed_number >= block_info.block_number) - }) - .unwrap_or(false); - ensure!(confirmed, InvalidTransaction::BadMandatory); - - // verify state root of the block - let valid_state_root = T::DomainInfo::domain_state_root( - domain_id, - block_info.block_number, - block_info.block_hash, - ) - .map(|got_state_root| got_state_root == state_root) - .unwrap_or(false); - ensure!(valid_state_root, InvalidTransaction::BadMandatory) - } - } + // if T::SelfDomainId::get().is_system() { + // if let Some((domain_id, block_info, state_root)) = + // extracted_state_roots.core_domain_info.clone() + // { + // // ensure the block is at-least k-deep + // let confirmed = T::DomainInfo::domain_best_number(domain_id) + // .and_then(|best_number| { + // best_number + // .checked_sub(&T::ConfirmationDepth::get()) + // .map(|confirmed_number| confirmed_number >= block_info.block_number) + // }) + // .unwrap_or(false); + // ensure!(confirmed, InvalidTransaction::BadMandatory); + + // // verify state root of the block + // let valid_state_root = T::DomainInfo::domain_state_root( + // domain_id, + // block_info.block_number, + // block_info.block_hash, + // ) + // .map(|got_state_root| got_state_root == state_root) + // .unwrap_or(false); + // ensure!(valid_state_root, InvalidTransaction::BadMandatory) + // } + // } let state_root = extracted_state_roots .core_domain_info diff --git a/domains/pallets/messenger/src/mock.rs b/domains/pallets/messenger/src/mock.rs index 18f2be954dd..5ca21181cea 100644 --- a/domains/pallets/messenger/src/mock.rs +++ b/domains/pallets/messenger/src/mock.rs @@ -242,6 +242,7 @@ impl EndpointHandler for MockEndpoint { } } +// TODO: Remove as pallet_settlement has been removed. #[frame_support::pallet] #[allow(dead_code)] pub(crate) mod mock_pallet_settlement { diff --git a/domains/pallets/transporter/Cargo.toml b/domains/pallets/transporter/Cargo.toml index a098a71a770..6c09c7223d1 100644 --- a/domains/pallets/transporter/Cargo.toml +++ b/domains/pallets/transporter/Cargo.toml @@ -14,21 +14,21 @@ include = [ ] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } domain-runtime-primitives = { path = "../../primitives/runtime" , default-features = false } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } sp-messenger = { version = "0.1.0", default-features = false, path = "../../primitives/messenger" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [dev-dependencies] -pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-io = { version = "23.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/domains/primitives/digests/Cargo.toml b/domains/primitives/digests/Cargo.toml index 8a1ec38b318..17f6a64a0ad 100644 --- a/domains/primitives/digests/Cargo.toml +++ b/domains/primitives/digests/Cargo.toml @@ -15,10 +15,10 @@ include = [ [dependencies] codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/domains/primitives/executor-registry/Cargo.toml b/domains/primitives/executor-registry/Cargo.toml deleted file mode 100644 index f2691b5dadf..00000000000 --- a/domains/primitives/executor-registry/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "sp-executor-registry" -version = "0.1.0" -authors = ["Liu-Cheng Xu "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://subspace.network" -repository = "https://github.com/subspace/subspace" -description = "Primitives of executor registry" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } -sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } - -[features] -default = ["std"] -std = [ - "parity-scale-codec/std", - "sp-domains/std", - "sp-std/std", -] -runtime-benchmarks = [] diff --git a/domains/primitives/executor-registry/src/lib.rs b/domains/primitives/executor-registry/src/lib.rs deleted file mode 100644 index e613760b1f1..00000000000 --- a/domains/primitives/executor-registry/src/lib.rs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2021 Subspace Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Primitives for Executor Registry. - -#![cfg_attr(not(feature = "std"), no_std)] - -use sp_domains::ExecutorPublicKey; -use sp_std::collections::btree_map::BTreeMap; -use sp_std::vec::Vec; - -/// Executor registry interface. -pub trait ExecutorRegistry { - /// Returns `Some(stake_amount)` if the given account is an executor, `None` if not. - fn executor_stake(who: &AccountId) -> Option; - - /// Returns `Some(executor_public_key)` if the given account is an executor, `None` if not. - fn executor_public_key(who: &AccountId) -> Option; - - /// Return the storage key of `KeyOwner` entry in pallet-executor-registry. - fn key_owner_storage_key(executor_public_key: &ExecutorPublicKey) -> Vec; - - /// Returns `Some(stake_weight)` if the given account is an authority. - fn authority_stake_weight(who: &AccountId) -> Option; - - /// Register an executor without check, only use in benchmark. - #[cfg(feature = "runtime-benchmarks")] - fn unchecked_register(executor: AccountId, public_key: ExecutorPublicKey, stake: Balance); -} - -impl ExecutorRegistry for () { - fn executor_stake(_who: &AccountId) -> Option { - None - } - - fn executor_public_key(_who: &AccountId) -> Option { - None - } - - fn key_owner_storage_key(_executor_public_key: &ExecutorPublicKey) -> Vec { - Vec::new() - } - - fn authority_stake_weight(_who: &AccountId) -> Option { - None - } - - #[cfg(feature = "runtime-benchmarks")] - fn unchecked_register(_executor: AccountId, _public_key: ExecutorPublicKey, _stake: Balance) {} -} - -/// Hook invoked after the executor set is updated on each epoch. -pub trait OnNewEpoch { - /// Something that should happen after the executors rotation. - fn on_new_epoch(executor_weights: BTreeMap); -} - -impl OnNewEpoch for () { - fn on_new_epoch(_executor_weights: BTreeMap) {} -} diff --git a/domains/primitives/messenger/Cargo.toml b/domains/primitives/messenger/Cargo.toml index 01c6fe9e8d0..91dc0f70ae1 100644 --- a/domains/primitives/messenger/Cargo.toml +++ b/domains/primitives/messenger/Cargo.toml @@ -14,16 +14,16 @@ include = [ ] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } hash-db = { version = "0.16.0", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-trie = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/domains/primitives/messenger/src/messages.rs b/domains/primitives/messenger/src/messages.rs index b78c67a0bb2..ceb62fc8518 100644 --- a/domains/primitives/messenger/src/messages.rs +++ b/domains/primitives/messenger/src/messages.rs @@ -1,9 +1,8 @@ use crate::endpoint::{Endpoint, EndpointRequest, EndpointResponse}; -use crate::verification::StorageProofVerifier; use codec::{Decode, Encode, FullCodec}; use frame_support::pallet_prelude::NMapKey; use frame_support::storage::generator::StorageNMap; -use frame_support::{log, Twox64Concat}; +use frame_support::Twox64Concat; use scale_info::TypeInfo; use sp_core::storage::StorageKey; use sp_domains::DomainId; @@ -256,53 +255,56 @@ impl CrossDomainMessage::storage_key( - self.src_domain_id, - domain_info.block_number.clone(), - domain_info.block_hash.clone(), - ); - let core_domain_state_root = - match StorageProofVerifier::::verify_and_get_value::( - &system_domain_state_root.into(), - core_domain_state_root_proof, - core_domain_state_root_key, - ) { - Ok(result) => result, - Err(err) => { - log::error!( - target: "runtime::messenger", - "Failed to verify Core domain proof: {:?}", - err - ); - return None; - } - }; - - extracted_state_roots.core_domain_info = - Some((self.src_domain_id, domain_info, core_domain_state_root)); - - Some(extracted_state_roots) - } else { - None - } + // else if self.src_domain_id.is_core() && core_domain_state_root_proof.is_some() { + // let (domain_info, core_domain_state_root_proof) = + // core_domain_state_root_proof.expect("checked for existence value above"); + // let core_domain_state_root_key = + // CoreDomainStateRootStorage::<_, _, StateRoot>::storage_key( + // self.src_domain_id, + // domain_info.block_number.clone(), + // domain_info.block_hash.clone(), + // ); + // let core_domain_state_root = + // match StorageProofVerifier::::verify_and_get_value::( + // &system_domain_state_root.into(), + // core_domain_state_root_proof, + // core_domain_state_root_key, + // ) { + // Ok(result) => result, + // Err(err) => { + // log::error!( + // target: "runtime::messenger", + // "Failed to verify Core domain proof: {:?}", + // err + // ); + // return None; + // } + // }; + + // extracted_state_roots.core_domain_info = + // Some((self.src_domain_id, domain_info, core_domain_state_root)); + + // Some(extracted_state_roots) + // } else { + // None + // } } } diff --git a/domains/primitives/runtime/Cargo.toml b/domains/primitives/runtime/Cargo.toml index d60ebad3d70..b9512a651b0 100644 --- a/domains/primitives/runtime/Cargo.toml +++ b/domains/primitives/runtime/Cargo.toml @@ -12,13 +12,15 @@ description = "Common primitives of subspace domain runtime" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } +parity-scale-codec = { version = "3.6.3", default-features = false, features = ["derive"] } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +subspace-core-primitives = { version = "0.1.0", path = "../../../crates/subspace-core-primitives", default-features = false } subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives", default-features = false } +sp-weights = { version = "20.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] @@ -29,5 +31,6 @@ std = [ "sp-core/std", "sp-runtime/std", "sp-std/std", + "subspace-core-primitives/std", "subspace-runtime-primitives/std", ] diff --git a/domains/primitives/runtime/src/lib.rs b/domains/primitives/runtime/src/lib.rs index 65aa2ea347a..7e9b205a5bc 100644 --- a/domains/primitives/runtime/src/lib.rs +++ b/domains/primitives/runtime/src/lib.rs @@ -24,6 +24,8 @@ use sp_runtime::traits::{Block as BlockT, Convert, IdentifyAccount, LookupError, use sp_runtime::transaction_validity::TransactionValidityError; use sp_runtime::{MultiAddress, MultiSignature}; use sp_std::vec::Vec; +use sp_weights::Weight; +use subspace_core_primitives::U256; use subspace_runtime_primitives::Moment; /// Alias to 512-bit hash when used in the context of a transaction signature on the chain. @@ -48,7 +50,7 @@ pub type BlockNumber = u32; /// The address format for describing accounts. pub type Address = MultiAddress; -/// Slot duration that is same as primary runtime. +/// Slot duration that is same as consensus chain runtime. pub const SLOT_DURATION: u64 = 1000; /// Extracts the signer from an unchecked extrinsic. @@ -162,6 +164,12 @@ sp_api::decl_runtime_apis! { extrinsics: Vec<::Extrinsic>, ) -> Vec<(Option, ::Extrinsic)>; + fn is_within_tx_range( + extrinsic: &::Extrinsic, + bundle_vrf_hash: &U256, + tx_range: &U256, + ) -> bool; + /// Returns the intermediate storage roots in an encoded form. fn intermediate_roots() -> Vec<[u8; 32]>; @@ -176,7 +184,7 @@ sp_api::decl_runtime_apis! { /// Checks the validity of extrinsic in a bundle. fn check_transaction_validity( - uxt: ::Extrinsic, + uxt: &::Extrinsic, block_hash: ::Hash, ) -> Result<(), CheckTxValidityError>; @@ -184,6 +192,9 @@ sp_api::decl_runtime_apis! { fn storage_keys_for_verifying_transaction_validity( account_id: opaque::AccountId, ) -> Result>, VerifyTxValidityError>; + + /// Return the extrinsic weight + fn extrinsic_weight(ext: &Block::Extrinsic) -> Weight; } /// Api that construct inherent extrinsics. diff --git a/domains/primitives/system-runtime/Cargo.toml b/domains/primitives/system-runtime/Cargo.toml deleted file mode 100644 index 46d0e9643c5..00000000000 --- a/domains/primitives/system-runtime/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "system-runtime-primitives" -version = "0.1.0" -authors = ["Subspace Labs "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://subspace.network" -repository = "https://github.com/subspace/subspace" -description = "Primitives of system domain runtime" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } - -[features] -default = ["std"] -std = [ - "parity-scale-codec/std", - "sp-api/std", - "sp-core/std", - "sp-domains/std", - "sp-runtime/std", - "sp-std/std", -] diff --git a/domains/primitives/system-runtime/src/lib.rs b/domains/primitives/system-runtime/src/lib.rs deleted file mode 100644 index 71379c6e6ef..00000000000 --- a/domains/primitives/system-runtime/src/lib.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2021 Subspace Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Primitives for system domain runtime. - -#![cfg_attr(not(feature = "std"), no_std)] - -use parity_scale_codec::{Decode, Encode}; -use sp_domains::bundle_election::BundleElectionSolverParams; -use sp_domains::{DomainId, ExecutorPublicKey, OpaqueBundle}; -use sp_runtime::traits::Block as BlockT; -use sp_std::vec::Vec; - -sp_api::decl_runtime_apis! { - /// API necessary for system domain. - pub trait SystemDomainApi { - /// Wrap the core domain bundles into extrinsics. - fn construct_submit_core_bundle_extrinsics( - opaque_bundles: Vec::Hash>>, - ) -> Vec>; - - /// Returns the parameters for solving the bundle election. - fn bundle_election_solver_params(domain_id: DomainId) -> BundleElectionSolverParams; - - fn core_bundle_election_storage_keys( - domain_id: DomainId, - executor_public_key: ExecutorPublicKey, - ) -> Option>>; - } -} diff --git a/domains/runtime/core-evm/src/lib.rs b/domains/runtime/core-evm/src/lib.rs deleted file mode 100644 index 584958b9280..00000000000 --- a/domains/runtime/core-evm/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit = "256"] - -// Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported -// functions -#[cfg(any(feature = "wasm-builder", feature = "std"))] -mod precompiles; -#[cfg(any(feature = "wasm-builder", feature = "std"))] -mod runtime; - -// Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported -// functions -#[cfg(any(feature = "wasm-builder", feature = "std"))] -pub use runtime::*; - -// Make the WASM binary available. -#[cfg(feature = "std")] -include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); diff --git a/domains/runtime/evm/Cargo.toml b/domains/runtime/evm/Cargo.toml new file mode 100644 index 00000000000..c2f69ccf29f --- /dev/null +++ b/domains/runtime/evm/Cargo.toml @@ -0,0 +1,129 @@ +[package] +name = "evm-domain-runtime" +version = "0.1.0" +authors = ["Vedhavyas Singareddi, Liu-Cheng Xu "] +license = "Apache-2.0" +homepage = "https://subspace.network" +repository = "https://github.com/subspace/subspace/" +edition = "2021" +description = "Subspace EVM domain runtime" +include = [ + "/src", + "/build.rs", + "/Cargo.toml", +] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.2.1", default-features = false, features = ["derive"] } +domain-pallet-executive = { version = "0.1.0", path = "../../pallets/executive", default-features = false } +domain-runtime-primitives = { version = "0.1.0", path = "../../primitives/runtime", default-features = false } +fp-account = { version = "1.0.0-dev", default-features = false, features = ["serde"], git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +fp-evm = { version = "3.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +fp-rpc = { version = "3.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +fp-self-contained = { version = "1.0.0-dev", default-features = false, features = ["serde"], git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +hex-literal = { version = '0.4.0', optional = true } +log = { version = "0.4.19", default-features = false } +pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-base-fee = { version = "1.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +pallet-domain-id = { version = "0.1.0", path = "../../pallets/domain-id", default-features = false } +pallet-ethereum = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +pallet-evm = { version = "6.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +pallet-evm-chain-id = { version = "1.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +pallet-evm-precompile-modexp = { version = "2.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +pallet-evm-precompile-sha3fips = { version = "2.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +pallet-evm-precompile-simple = { version = "2.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "74483666645e121c0c5e6616f43fdfd8664ea0d3" } +pallet-messenger = { version = "0.1.0", path = "../../pallets/messenger", default-features = false } +pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transporter = { version = "0.1.0", path = "../../pallets/transporter", default-features = false } +scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains", default-features = false } +sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-messenger = { version = "0.1.0", default-features = false, path = "../../primitives/messenger" } +sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +subspace-core-primitives = { version = "0.1.0", path = "../../../crates/subspace-core-primitives", default-features = false } +subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives", default-features = false } + +[build-dependencies] +substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } + +[features] +default = [ + "std", +] +std = [ + "codec/std", + "domain-pallet-executive/std", + "domain-runtime-primitives/std", + "fp-account/std", + "fp-evm/std", + "fp-rpc/std", + "fp-self-contained/std", + "frame-support/std", + "frame-system/std", + "frame-system-rpc-runtime-api/std", + "log/std", + "pallet-balances/std", + "pallet-base-fee/std", + "pallet-domain-id/std", + "pallet-ethereum/std", + "pallet-evm/std", + "pallet-evm-chain-id/std", + "pallet-evm-precompile-modexp/std", + "pallet-evm-precompile-sha3fips/std", + "pallet-evm-precompile-simple/std", + "pallet-messenger/std", + "pallet-sudo/std", + "pallet-timestamp/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + "pallet-transporter/std", + "scale-info/std", + "sp-api/std", + "sp-block-builder/std", + "sp-core/std", + "sp-domains/std", + "sp-session/std", + "sp-inherents/std", + "sp-io/std", + "sp-messenger/std", + "sp-offchain/std", + "sp-runtime/std", + "sp-std/std", + "sp-transaction-pool/std", + "sp-version/std", + "subspace-core-primitives/std", + "subspace-runtime-primitives/std", + "substrate-wasm-builder", +] +runtime-benchmarks = [ + 'hex-literal', + "sp-runtime/runtime-benchmarks", + "frame-benchmarking", + "frame-system-benchmarking", + "frame-system-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-ethereum/runtime-benchmarks", + "pallet-evm/runtime-benchmarks", +] diff --git a/domains/runtime/core-evm/build.rs b/domains/runtime/evm/build.rs similarity index 69% rename from domains/runtime/core-evm/build.rs rename to domains/runtime/evm/build.rs index a9033702fe0..8f021e8381d 100644 --- a/domains/runtime/core-evm/build.rs +++ b/domains/runtime/evm/build.rs @@ -3,11 +3,8 @@ fn main() { { substrate_wasm_builder::WasmBuilder::new() .with_current_project() - .enable_feature("wasm-builder") .export_heap_base() .import_memory() .build(); } - - subspace_wasm_tools::export_wasm_bundle_path(); } diff --git a/domains/runtime/core-evm/src/runtime.rs b/domains/runtime/evm/src/lib.rs similarity index 93% rename from domains/runtime/core-evm/src/runtime.rs rename to domains/runtime/evm/src/lib.rs index f1084903b0a..66979c6d35d 100644 --- a/domains/runtime/core-evm/src/runtime.rs +++ b/domains/runtime/evm/src/lib.rs @@ -1,10 +1,20 @@ +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit = "256"] + +mod precompiles; + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + use codec::{Decode, Encode}; use domain_runtime_primitives::opaque::Header; pub use domain_runtime_primitives::{opaque, Balance, BlockNumber, Hash, Index}; use domain_runtime_primitives::{MultiAccountId, TryConvertBack, SLOT_DURATION}; use fp_account::EthereumSignature; -use fp_self_contained::CheckedSignature; -use frame_support::dispatch::DispatchClass; +use fp_self_contained::SelfContainedCall; +use frame_support::dispatch::{DispatchClass, GetDispatchInfo}; use frame_support::traits::{ConstU16, ConstU32, ConstU64, Everything, FindAuthor}; use frame_support::weights::constants::{ BlockExecutionWeight, ExtrinsicBaseWeight, ParityDbWeight, WEIGHT_REF_TIME_PER_MILLIS, @@ -159,7 +169,7 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { impl_opaque_keys! { pub struct SessionKeys { /// Primarily used for adding the executor authority key into the keystore in the dev mode. - pub executor: sp_domains::ExecutorKey, + pub executor: sp_domains::OperatorKey, } } @@ -346,7 +356,8 @@ parameter_types! { parameter_types! { pub const MaximumRelayers: u32 = 100; pub const RelayerDeposit: Balance = 100 * SSC; - pub const CoreDomainId: DomainId = DomainId::CORE_EVM; + // TODO: Proper value + pub const CoreDomainId: DomainId = DomainId::new(3u32); } impl pallet_messenger::Config for Runtime { @@ -507,6 +518,8 @@ impl pallet_base_fee::Config for Runtime { type DefaultElasticity = DefaultElasticity; } +impl pallet_domain_id::Config for Runtime {} + // Create the runtime by composing the FRAME pallets that were previously configured. // // NOTE: Currently domain runtime does not naturally support the pallets with inherent extrinsics. @@ -536,6 +549,9 @@ construct_runtime!( EVMChainId: pallet_evm_chain_id = 82, BaseFee: pallet_base_fee = 83, + // domain instance stuff + SelfDomainId: pallet_domain_id = 90, + // Sudo account Sudo: pallet_sudo = 100, } @@ -566,6 +582,59 @@ impl fp_rpc::ConvertTransaction for TransactionConve } } +fn extract_xdm_proof_state_roots( + encoded_ext: Vec, +) -> Option> { + if let Ok(ext) = UncheckedExtrinsic::decode(&mut encoded_ext.as_slice()) { + match &ext.0.function { + RuntimeCall::Messenger(pallet_messenger::Call::relay_message { msg }) => { + msg.extract_state_roots_from_proof::() + } + RuntimeCall::Messenger(pallet_messenger::Call::relay_message_response { msg }) => { + msg.extract_state_roots_from_proof::() + } + _ => None, + } + } else { + None + } +} + +fn extract_signer_inner( + ext: &UncheckedExtrinsic, + lookup: &Lookup, +) -> Option +where + Lookup: sp_runtime::traits::Lookup, +{ + if ext.0.function.is_self_contained() { + ext.0 + .function + .check_self_contained() + .and_then(|signed_info| signed_info.ok()) + .map(|account| account.encode()) + } else { + ext.0 + .signature + .as_ref() + .and_then(|(signed, _, _)| lookup.lookup(*signed).ok().map(|account| account.encode())) + } +} + +pub fn extract_signer( + extrinsics: Vec, +) -> Vec<(Option, UncheckedExtrinsic)> { + let lookup = frame_system::ChainContext::::default(); + + extrinsics + .into_iter() + .map(|extrinsic| { + let maybe_signer = extract_signer_inner(&extrinsic, &lookup); + (maybe_signer, extrinsic) + }) + .collect() +} + impl_runtime_apis! { impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { @@ -675,8 +744,26 @@ impl_runtime_apis! { fn extract_signer( extrinsics: Vec<::Extrinsic>, ) -> Vec<(Option, ::Extrinsic)> { + extract_signer(extrinsics) + } + + fn is_within_tx_range( + extrinsic: &::Extrinsic, + bundle_vrf_hash: &subspace_core_primitives::U256, + tx_range: &subspace_core_primitives::U256 + ) -> bool { + use subspace_core_primitives::U256; + use subspace_core_primitives::crypto::blake2b_256_hash; + let lookup = frame_system::ChainContext::::default(); - extract_signers(extrinsics, &lookup) + if let Some(signer) = extract_signer_inner(extrinsic, &lookup) { + // Check if the signer Id hash is within the tx range + let signer_id_hash = U256::from_be_bytes(blake2b_256_hash(&signer.encode())); + sp_domains::signer_in_tx_range(bundle_vrf_hash, &signer_id_hash, tx_range) + } else { + // Unsigned transactions are always in the range. + true + } } fn intermediate_roots() -> Vec<[u8; 32]> { @@ -705,10 +792,11 @@ impl_runtime_apis! { } fn check_transaction_validity( - _uxt: ::Extrinsic, + _uxt: &::Extrinsic, _block_hash: ::Hash, ) -> Result<(), domain_runtime_primitives::CheckTxValidityError> { - unimplemented!("TODO: check transaction fee to core-evm") + // TODO: check transaction fee to core-evm + Ok(()) } fn storage_keys_for_verifying_transaction_validity( @@ -721,6 +809,10 @@ impl_runtime_apis! { pallet_transaction_payment::NextFeeMultiplier::::hashed_key().to_vec(), ]) } + + fn extrinsic_weight(ext: &::Extrinsic) -> Weight { + ext.get_dispatch_info().weight + } } impl domain_runtime_primitives::InherentExtrinsicApi for Runtime { @@ -986,48 +1078,3 @@ impl_runtime_apis! { } } } - -fn extract_xdm_proof_state_roots( - encoded_ext: Vec, -) -> Option> { - if let Ok(ext) = UncheckedExtrinsic::decode(&mut encoded_ext.as_slice()) { - match &ext.0.function { - RuntimeCall::Messenger(pallet_messenger::Call::relay_message { msg }) => { - msg.extract_state_roots_from_proof::() - } - RuntimeCall::Messenger(pallet_messenger::Call::relay_message_response { msg }) => { - msg.extract_state_roots_from_proof::() - } - _ => None, - } - } else { - None - } -} - -// TODO: this is inconsistent with other domains. -// Ref https://github.com/subspace/subspace/pull/1434#discussion_r1186633233 -pub fn extract_signers( - extrinsics: Vec, - lookup: &Lookup, -) -> Vec<(Option, UncheckedExtrinsic)> -where - Lookup: sp_runtime::traits::Lookup, -{ - use sp_runtime::traits::Checkable; - - let mut signer_extrinsics = sp_std::vec![]; - for extrinsic in extrinsics { - if let Ok(checked) = extrinsic.clone().check(lookup) { - let maybe_signer = match checked.signed { - CheckedSignature::SelfContained(account_id) => Some(account_id.encode()), - CheckedSignature::Signed(account_id, _) => Some(account_id.encode()), - CheckedSignature::Unsigned => None, - }; - - signer_extrinsics.push((maybe_signer, extrinsic)) - } - } - - signer_extrinsics -} diff --git a/domains/runtime/core-evm/src/precompiles.rs b/domains/runtime/evm/src/precompiles.rs similarity index 100% rename from domains/runtime/core-evm/src/precompiles.rs rename to domains/runtime/evm/src/precompiles.rs diff --git a/domains/runtime/system/Cargo.toml b/domains/runtime/system/Cargo.toml deleted file mode 100644 index 9534fd8ec8e..00000000000 --- a/domains/runtime/system/Cargo.toml +++ /dev/null @@ -1,113 +0,0 @@ -[package] -name = "system-domain-runtime" -version = "0.1.0" -authors = ["Anonymous"] -description = "A new Cumulus FRAME-based Substrate Runtime, ready for hacking together a parachain." -license = "Unlicense" -homepage = "https://substrate.io" -repository = "https://github.com/paritytech/cumulus/" -edition = "2021" -links = "system-domain-runtime" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"]} -domain-pallet-executive = { version = "0.1.0", path = "../../pallets/executive", default-features = false } -domain-runtime-primitives = { version = "0.1.0", path = "../../primitives/runtime", default-features = false } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-domain-registry = { version = "0.1.0", path = "../../pallets/domain-registry", default-features = false } -pallet-executor-registry = { version = "0.1.0", path = "../../pallets/executor-registry", default-features = false } -pallet-settlement = { version = "0.1.0", path = "../../../crates/pallet-settlement", default-features = false } -pallet-messenger = { version = "0.1.0", path = "../../pallets/messenger", default-features = false } -pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transporter = { version = "0.1.0", path = "../../pallets/transporter", default-features = false } -scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains", default-features = false } -sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-messenger = { version = "0.1.0", path = "../../primitives/messenger", default-features = false } -sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", path = "../../../crates/sp-settlement", default-features = false } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives", default-features = false } -system-runtime-primitives = { version = "0.1.0", path = "../../primitives/system-runtime", default-features = false } - -[build-dependencies] -sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } -subspace-wasm-tools = { version = "0.1.0", path = "../../../crates/subspace-wasm-tools" } -substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } - -[features] -default = [ - "std", -] -std = [ - "codec/std", - "domain-pallet-executive/std", - "domain-runtime-primitives/std", - "frame-benchmarking?/std", - "frame-support/std", - "frame-system/std", - "frame-system-benchmarking?/std", - "frame-system-rpc-runtime-api/std", - "pallet-balances/std", - "pallet-domain-registry/std", - "pallet-executor-registry/std", - "pallet-settlement/std", - "pallet-messenger/std", - "pallet-sudo/std", - "pallet-transaction-payment/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transporter/std", - "scale-info/std", - "sp-api/std", - "sp-block-builder/std", - "sp-core/std", - "sp-domains/std", - "sp-inherents/std", - "sp-io/std", - "sp-messenger/std", - "sp-offchain/std", - "sp-runtime/std", - "sp-session/std", - "sp-settlement/std", - "sp-std/std", - "sp-transaction-pool/std", - "sp-version/std", - "subspace-runtime-primitives/std", - "system-runtime-primitives/std", - "substrate-wasm-builder", -] -# Internal implementation detail, enabled during building of wasm blob. -wasm-builder = [] -runtime-benchmarks = [ - "frame-benchmarking", - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "frame-system-benchmarking", - "frame-system-benchmarking/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-domain-registry/runtime-benchmarks", - "pallet-executor-registry/runtime-benchmarks", - "pallet-messenger/runtime-benchmarks", - "pallet-transporter/runtime-benchmarks", - "sp-domains/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] diff --git a/domains/runtime/system/src/lib.rs b/domains/runtime/system/src/lib.rs deleted file mode 100644 index ce27ff5ae1d..00000000000 --- a/domains/runtime/system/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit = "256"] - -// Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported -// functions -#[cfg(any(feature = "wasm-builder", feature = "std"))] -mod runtime; - -// Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported -// functions -#[cfg(any(feature = "wasm-builder", feature = "std"))] -pub use runtime::*; - -// Make the WASM binary available. -#[cfg(feature = "std")] -include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); - -#[cfg(feature = "runtime-benchmarks")] -#[macro_use] -extern crate frame_benchmarking; diff --git a/domains/runtime/system/src/runtime.rs b/domains/runtime/system/src/runtime.rs deleted file mode 100644 index 81df2e4c47a..00000000000 --- a/domains/runtime/system/src/runtime.rs +++ /dev/null @@ -1,856 +0,0 @@ -use codec::{Decode, Encode}; -use domain_runtime_primitives::{opaque, AccountIdConverter}; -pub use domain_runtime_primitives::{ - AccountId, Address, Balance, BlockNumber, Hash, Index, Signature, -}; -use frame_support::dispatch::DispatchClass; -use frame_support::traits::{ConstU16, ConstU32, Everything}; -use frame_support::weights::constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; -use frame_support::weights::{ConstantMultiplier, IdentityFee, Weight}; -use frame_support::{construct_runtime, parameter_types}; -use frame_system::limits::{BlockLength, BlockWeights}; -use pallet_transporter::EndpointHandler; -use sp_api::impl_runtime_apis; -use sp_core::crypto::KeyTypeId; -use sp_core::{OpaqueMetadata, H256}; -use sp_domains::bundle_election::BundleElectionSolverParams; -use sp_domains::fraud_proof::FraudProof; -use sp_domains::transaction::PreValidationObject; -use sp_domains::{DomainId, ExecutionReceipt, ExecutorPublicKey, OpaqueBundle}; -use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId}; -use sp_messenger::messages::{ - CrossDomainMessage, ExtractedStateRootsFromProof, MessageId, RelayerMessagesWithStorageKey, -}; -use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, NumberFor, StaticLookup}; -use sp_runtime::transaction_validity::{TransactionSource, TransactionValidity}; -#[cfg(any(feature = "std", test))] -pub use sp_runtime::BuildStorage; -use sp_runtime::{create_runtime_str, generic, impl_opaque_keys, ApplyExtrinsicResult}; -pub use sp_runtime::{MultiAddress, Perbill, Permill}; -use sp_std::marker::PhantomData; -use sp_std::prelude::*; -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use sp_version::RuntimeVersion; -use subspace_runtime_primitives::{SHANNON, SSC}; - -/// Block header type as expected by this runtime. -pub type Header = generic::Header; - -/// Block type as expected by this runtime. -pub type Block = generic::Block; - -/// A Block signed with a Justification -pub type SignedBlock = generic::SignedBlock; - -/// BlockId type as expected by this runtime. -pub type BlockId = generic::BlockId; - -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckMortality, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, -); - -/// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; - -/// Extrinsic type that has already been checked. -pub type CheckedExtrinsic = generic::CheckedExtrinsic; - -/// Executive: handles dispatch to the various modules. -pub type Executive = domain_pallet_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystem, - Runtime, ->; - -impl_opaque_keys! { - pub struct SessionKeys { - /// Primarily used for adding the executor authority key into the keystore in the dev mode. - pub executor: sp_domains::ExecutorKey, - } -} - -#[sp_version::runtime_version] -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("subspace-system-domain"), - impl_name: create_runtime_str!("subspace-system-domain"), - authoring_version: 0, - spec_version: 2, - impl_version: 0, - apis: RUNTIME_API_VERSIONS, - transaction_version: 0, - state_version: 0, -}; - -/// The existential deposit. Same with the one on primary chain. -pub const EXISTENTIAL_DEPOSIT: Balance = 500 * SHANNON; - -/// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is -/// used to limit the maximal weight of a single extrinsic. -const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); - -/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by -/// `Operational` extrinsics. -const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); - -/// TODO: Proper max block weight -const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::MAX; - -/// The version information used to identify this runtime when compiled natively. -#[cfg(feature = "std")] -pub fn native_version() -> NativeVersion { - NativeVersion { - runtime_version: VERSION, - can_author_with: Default::default(), - } -} - -parameter_types! { - pub const Version: RuntimeVersion = VERSION; - pub const BlockHashCount: BlockNumber = 2400; - - // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`. - // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the - // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize - // the lazy contract deletion. - pub RuntimeBlockLength: BlockLength = - BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); - pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() - .base_block(BlockExecutionWeight::get()) - .for_class(DispatchClass::all(), |weights| { - weights.base_extrinsic = ExtrinsicBaseWeight::get(); - }) - .for_class(DispatchClass::Normal, |weights| { - weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); - }) - .for_class(DispatchClass::Operational, |weights| { - weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); - // Operational transactions have some extra reserved space, so that they - // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. - weights.reserved = Some( - MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT - ); - }) - .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) - .build_or_panic(); -} - -// Configure FRAME pallets to include in runtime. - -impl frame_system::Config for Runtime { - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The aggregated dispatch type that is available for extrinsics. - type RuntimeCall = RuntimeCall; - /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = AccountIdLookup; - /// The index type for storing how many extrinsics an account has signed. - type Index = Index; - /// The index type for blocks. - type BlockNumber = BlockNumber; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The hashing algorithm used. - type Hashing = BlakeTwo256; - /// The header type. - type Header = generic::Header; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - /// The ubiquitous origin type. - type RuntimeOrigin = RuntimeOrigin; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// Runtime version. - type Version = Version; - /// Converts a module to an index of this module in the runtime. - type PalletInfo = PalletInfo; - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// What to do if a new account is created. - type OnNewAccount = (); - /// What to do if an account is fully reaped from the system. - type OnKilledAccount = (); - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// The basic call filter to use in dispatchable. - type BaseCallFilter = Everything; - /// Weight information for the extrinsics of this pallet. - type SystemWeightInfo = (); - /// Block & extrinsics weights: base values and limits. - type BlockWeights = RuntimeBlockWeights; - /// The maximum length of a block (in bytes). - type BlockLength = RuntimeBlockLength; - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. - type SS58Prefix = ConstU16<42>; - /// The action to take on a Runtime Upgrade - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; -} - -parameter_types! { - pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; - pub const MaxLocks: u32 = 50; - pub const MaxReserves: u32 = 50; -} - -impl pallet_balances::Config for Runtime { - type MaxLocks = MaxLocks; - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; - type MaxReserves = MaxReserves; - type ReserveIdentifier = [u8; 8]; - type FreezeIdentifier = (); - type MaxFreezes = (); - type RuntimeHoldReason = (); - type MaxHolds = (); -} - -parameter_types! { - pub const TransactionByteFee: Balance = 1; - pub const OperationalFeeMultiplier: u8 = 5; -} - -impl pallet_transaction_payment::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; - type WeightToFee = IdentityFee; - type LengthToFee = ConstantMultiplier; - type FeeMultiplierUpdate = (); - type OperationalFeeMultiplier = OperationalFeeMultiplier; -} - -impl domain_pallet_executive::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; -} - -parameter_types! { - // TODO: proper parameters - pub const MinExecutorStake: Balance = SSC; - pub const MaxExecutorStake: Balance = 1000 * SSC; - pub const MinExecutors: u32 = 1; - pub const MaxExecutors: u32 = 10; - // One hour in blocks. - pub const EpochDuration: BlockNumber = 3600 / 6; - pub const MaxWithdrawals: u32 = 1; - // One day in blocks. - pub const WithdrawalDuration: BlockNumber = 3600 * 24 / 6; -} - -impl pallet_executor_registry::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type StakeWeight = sp_domains::StakeWeight; - type MinExecutorStake = MinExecutorStake; - type MaxExecutorStake = MaxExecutorStake; - type MinExecutors = MinExecutors; - type MaxExecutors = MaxExecutors; - type MaxWithdrawals = MaxWithdrawals; - type WithdrawalDuration = WithdrawalDuration; - type EpochDuration = EpochDuration; - type OnNewEpoch = DomainRegistry; - type WeightInfo = pallet_executor_registry::weights::SubstrateWeight; -} - -parameter_types! { - pub const MinDomainDeposit: Balance = 10 * SSC; - pub const MaxDomainDeposit: Balance = 1000 * SSC; - pub const MinDomainOperatorStake: Balance = 10 * SSC; - pub const ReceiptsPruningDepth: BlockNumber = 256; - pub const MaximumReceiptDrift: BlockNumber = 128; -} - -impl pallet_domain_registry::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type StakeWeight = sp_domains::StakeWeight; - type ExecutorRegistry = ExecutorRegistry; - type MinDomainDeposit = MinDomainDeposit; - type MaxDomainDeposit = MaxDomainDeposit; - type MinDomainOperatorStake = MinDomainOperatorStake; - type WeightInfo = pallet_domain_registry::weights::SubstrateWeight; -} - -impl pallet_settlement::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type DomainHash = domain_runtime_primitives::Hash; - type MaximumReceiptDrift = MaximumReceiptDrift; - type ReceiptsPruningDepth = ReceiptsPruningDepth; -} - -parameter_types! { - pub const StateRootsBound: u32 = 50; - pub const RelayConfirmationDepth: BlockNumber = 7; -} - -pub struct DomainInfo; - -impl sp_messenger::endpoint::DomainInfo for DomainInfo { - fn domain_best_number(domain_id: DomainId) -> Option { - Some(Settlement::head_receipt_number(domain_id)) - } - - fn domain_state_root(domain_id: DomainId, number: BlockNumber, hash: Hash) -> Option { - Settlement::domain_state_root_at(domain_id, number, hash) - } -} - -parameter_types! { - pub const MaximumRelayers: u32 = 100; - pub const RelayerDeposit: Balance = 100 * SSC; - pub const SystemDomainId: DomainId = DomainId::SYSTEM; -} - -impl pallet_messenger::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type SelfDomainId = SystemDomainId; - - fn get_endpoint_response_handler( - endpoint: &Endpoint, - ) -> Option>> { - // Return a dummy handler for benchmark to observe the outer weight when processing cross domain - // message (i.e. updating the `next_nonce` of the channel, assigning msg to the relayer, etc.) - #[cfg(feature = "runtime-benchmarks")] - { - return Some(Box::new(sp_messenger::endpoint::BenchmarkEndpointHandler)); - } - if endpoint == &Endpoint::Id(TransporterEndpointId::get()) { - Some(Box::new(EndpointHandler(PhantomData::))) - } else { - None - } - } - - type Currency = Balances; - type MaximumRelayers = MaximumRelayers; - type RelayerDeposit = RelayerDeposit; - type DomainInfo = DomainInfo; - type ConfirmationDepth = RelayConfirmationDepth; - type WeightInfo = pallet_messenger::weights::SubstrateWeight; -} - -impl frame_system::offchain::SendTransactionTypes for Runtime -where - RuntimeCall: From, -{ - type Extrinsic = UncheckedExtrinsic; - type OverarchingCall = RuntimeCall; -} - -parameter_types! { - pub const TransporterEndpointId: EndpointId = 1; -} - -impl pallet_transporter::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type SelfDomainId = SystemDomainId; - type SelfEndpointId = TransporterEndpointId; - type Currency = Balances; - type Sender = Messenger; - type AccountIdConverter = AccountIdConverter; - type WeightInfo = pallet_transporter::weights::SubstrateWeight; -} - -impl pallet_sudo::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - type WeightInfo = pallet_sudo::weights::SubstrateWeight; -} - -// Create the runtime by composing the FRAME pallets that were previously configured. -// -// NOTE: Currently domain runtime does not naturally support the pallets with inherent extrinsics. -construct_runtime!( - pub struct Runtime where - Block = Block, - NodeBlock = opaque::Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - // System support stuff. - System: frame_system = 0, - ExecutivePallet: domain_pallet_executive = 1, - - // Monetary stuff. - Balances: pallet_balances = 20, - TransactionPayment: pallet_transaction_payment = 21, - - // System domain. - // - // Must be after Balances pallet so that its genesis is built after the Balances genesis is - // built. - ExecutorRegistry: pallet_executor_registry = 40, - Settlement: pallet_settlement = 41, - DomainRegistry: pallet_domain_registry = 42, - - // Note: Indexes should be used by all other core domain for proper xdm decode. - Messenger: pallet_messenger = 60, - Transporter: pallet_transporter = 61, - - // Sudo account - Sudo: pallet_sudo = 100, - } -); - -#[cfg(feature = "runtime-benchmarks")] -frame_benchmarking::define_benchmarks!( - [frame_benchmarking, BaselineBench::] - [frame_system, SystemBench::] - [pallet_balances, Balances] - [pallet_executor_registry, ExecutorRegistry] - [pallet_domain_registry, DomainRegistry] - [pallet_messenger, Messenger] - [pallet_transporter, Transporter] -); - -impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block) - } - - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - - fn metadata_at_version(version: u32) -> Option { - Runtime::metadata_at_version(version) - } - - fn metadata_versions() -> sp_std::vec::Vec { - Runtime::metadata_versions() - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Index { - System::account_nonce(account) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl domain_runtime_primitives::DomainCoreApi for Runtime { - fn extract_signer( - extrinsics: Vec<::Extrinsic>, - ) -> Vec<(Option, ::Extrinsic)> { - use domain_runtime_primitives::Signer; - let lookup = frame_system::ChainContext::::default(); - extrinsics.into_iter().map(|xt| (xt.signer(&lookup).map(|signer| signer.encode()), xt)).collect() - } - - fn intermediate_roots() -> Vec<[u8; 32]> { - ExecutivePallet::intermediate_roots() - } - - fn initialize_block_with_post_state_root(header: &::Header) -> Vec { - Executive::initialize_block(header); - Executive::storage_root() - } - - fn apply_extrinsic_with_post_state_root(extrinsic: ::Extrinsic) -> Vec { - let _ = Executive::apply_extrinsic(extrinsic); - Executive::storage_root() - } - - fn construct_set_code_extrinsic(code: Vec) -> Vec { - use codec::Encode; - let set_code_call = frame_system::Call::set_code { code }; - UncheckedExtrinsic::new_unsigned( - domain_pallet_executive::Call::sudo_unchecked_weight_unsigned { - call: Box::new(set_code_call.into()), - weight: Weight::zero(), - }.into() - ).encode() - } - - fn check_transaction_validity( - uxt: ::Extrinsic, - block_hash: ::Hash, - ) -> Result<(), domain_runtime_primitives::CheckTxValidityError> { - let maybe_address = uxt - .signature - .as_ref() - .map(|(address, _signature, _extra)| address.clone()); - - if let Some(address) = maybe_address { - let sender = ::Lookup::lookup(address)?; - - let tx_validity = - Executive::validate_transaction(TransactionSource::External, uxt, block_hash); - - tx_validity.map(|_| ()).map_err(|tx_validity_error| { - let storage_keys = sp_std::vec![ - frame_system::Account::::hashed_key_for(&sender), - pallet_transaction_payment::NextFeeMultiplier::::hashed_key().to_vec(), - ]; - domain_runtime_primitives::CheckTxValidityError::InvalidTransaction { - error: tx_validity_error, - storage_keys, - } - }) - } else { - Ok(()) - } - } - - fn storage_keys_for_verifying_transaction_validity( - who: opaque::AccountId, - ) -> Result>, domain_runtime_primitives::VerifyTxValidityError> { - let sender = AccountId::decode(&mut who.as_slice()) - .map_err(|_| domain_runtime_primitives::VerifyTxValidityError::FailedToDecodeAccountId)?; - Ok(sp_std::vec![ - frame_system::Account::::hashed_key_for(sender), - pallet_transaction_payment::NextFeeMultiplier::::hashed_key().to_vec(), - ]) - } - } - - impl sp_settlement::SettlementApi for Runtime { - fn execution_trace(domain_id: DomainId, receipt_hash: H256) -> Vec { - Settlement::receipts(domain_id, receipt_hash).map(|receipt| receipt.trace).unwrap_or_default() - } - - fn state_root( - domain_id: DomainId, - domain_block_number: BlockNumber, - domain_block_hash: Hash, - ) -> Option { - Settlement::state_root((domain_id, domain_block_number, domain_block_hash)) - } - - fn primary_hash(domain_id: DomainId, domain_block_number: BlockNumber) -> Option { - Settlement::primary_hash(domain_id, domain_block_number) - } - - fn receipts_pruning_depth() -> BlockNumber { - ReceiptsPruningDepth::get() - } - - fn head_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::head_receipt_number(domain_id) - } - - fn oldest_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::oldest_receipt_number(domain_id) - } - - fn maximum_receipt_drift() -> NumberFor { - MaximumReceiptDrift::get() - } - - fn extract_receipts( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec> { - let successful_bundles = DomainRegistry::successful_bundles(); - extrinsics - .into_iter() - .filter_map(|uxt| match uxt.function { - RuntimeCall::DomainRegistry(pallet_domain_registry::Call::submit_core_bundle { - opaque_bundle, - }) if opaque_bundle.domain_id() == domain_id - && successful_bundles.contains(&opaque_bundle.hash()) => - { - Some(opaque_bundle.receipt) - } - _ => None, - }) - .collect() - } - - fn extract_fraud_proofs( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, Hash>> { - let successful_fraud_proofs = Settlement::successful_fraud_proofs(); - extrinsics - .into_iter() - .filter_map(|uxt| match uxt.function { - RuntimeCall::DomainRegistry(pallet_domain_registry::Call::submit_fraud_proof { fraud_proof }) - if fraud_proof.domain_id() == domain_id - && successful_fraud_proofs.contains(&fraud_proof.hash()) => - { - Some(fraud_proof) - } - _ => None, - }) - .collect() - } - - fn submit_fraud_proof_unsigned(fraud_proof: FraudProof, Hash>) { - DomainRegistry::submit_fraud_proof_unsigned(fraud_proof) - } - } - - impl system_runtime_primitives::SystemDomainApi for Runtime { - fn construct_submit_core_bundle_extrinsics( - opaque_bundles: Vec::Hash>>, - ) -> Vec> { - use codec::Encode; - opaque_bundles - .into_iter() - .map(|opaque_bundle| { - UncheckedExtrinsic::new_unsigned( - pallet_domain_registry::Call::submit_core_bundle { - opaque_bundle - }.into() - ).encode() - }) - .collect() - } - - fn bundle_election_solver_params(domain_id: DomainId) -> BundleElectionSolverParams { - if domain_id.is_system() { - BundleElectionSolverParams { - authorities: ExecutorRegistry::authorities().into(), - total_stake_weight: ExecutorRegistry::total_stake_weight(), - slot_probability: ExecutorRegistry::slot_probability(), - } - } else { - match ( - DomainRegistry::domain_authorities(domain_id), - DomainRegistry::domain_total_stake_weight(domain_id), - DomainRegistry::domain_slot_probability(domain_id), - ) { - (authorities, Some(total_stake_weight), Some(slot_probability)) => { - BundleElectionSolverParams { - authorities, - total_stake_weight, - slot_probability, - } - } - _ => BundleElectionSolverParams::empty(), - } - } - } - - fn core_bundle_election_storage_keys( - domain_id: DomainId, - executor_public_key: ExecutorPublicKey, - ) -> Option>> { - let executor = ExecutorRegistry::key_owner(&executor_public_key)?; - let mut storage_keys = DomainRegistry::core_bundle_election_storage_keys(domain_id, executor); - storage_keys.push(ExecutorRegistry::key_owner_hashed_key_for(&executor_public_key)); - Some(storage_keys) - } - } - - impl sp_messenger::RelayerApi for Runtime { - fn domain_id() -> DomainId { - SystemDomainId::get() - } - - fn relay_confirmation_depth() -> BlockNumber { - RelayConfirmationDepth::get() - } - - fn domain_best_number(domain_id: DomainId) -> Option { - Some(Settlement::head_receipt_number(domain_id)) - } - - fn domain_state_root(domain_id: DomainId, number: BlockNumber, hash: Hash) -> Option{ - Settlement::domain_state_root_at(domain_id, number, hash) - } - - fn relayer_assigned_messages(relayer_id: AccountId) -> RelayerMessagesWithStorageKey { - Messenger::relayer_assigned_messages(relayer_id) - } - - fn outbox_message_unsigned(msg: CrossDomainMessage::Hash, ::Hash>) -> Option<::Extrinsic> { - Messenger::outbox_message_unsigned(msg) - } - - fn inbox_response_message_unsigned(msg: CrossDomainMessage::Hash, ::Hash>) -> Option<::Extrinsic> { - Messenger::inbox_response_message_unsigned(msg) - } - - fn should_relay_outbox_message(dst_domain_id: DomainId, msg_id: MessageId) -> bool { - Messenger::should_relay_outbox_message(dst_domain_id, msg_id) - } - - fn should_relay_inbox_message_response(dst_domain_id: DomainId, msg_id: MessageId) -> bool { - Messenger::should_relay_inbox_message_response(dst_domain_id, msg_id) - } - } - - impl sp_messenger::MessengerApi for Runtime { - fn extract_xdm_proof_state_roots( - extrinsic: Vec, - ) -> Option::Hash, ::Hash>> { - extract_xdm_proof_state_roots(extrinsic) - } - - fn confirmation_depth() -> BlockNumber { - RelayConfirmationDepth::get() - } - } - - impl sp_domains::transaction::PreValidationObjectApi for Runtime { - fn extract_pre_validation_object( - extrinsic: ::Extrinsic, - ) -> PreValidationObject { - match extrinsic.function { - RuntimeCall::DomainRegistry(pallet_domain_registry::Call::submit_fraud_proof { fraud_proof }) => { - PreValidationObject::FraudProof(fraud_proof) - } - _ => PreValidationObject::Null, - } - } - } - - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - use frame_system_benchmarking::Pallet as SystemBench; - use baseline::Pallet as BaselineBench; - - let mut list = Vec::::new(); - list_benchmarks!(list, extra); - - let storage_info = AllPalletsWithSystem::storage_info(); - - (list, storage_info) - } - - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch, TrackedStorageKey}; - - use frame_system_benchmarking::Pallet as SystemBench; - use baseline::Pallet as BaselineBench; - - impl frame_system_benchmarking::Config for Runtime {} - impl baseline::Config for Runtime {} - - use frame_support::traits::WhitelistedStorageKeys; - let whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); - - let mut batches = Vec::::new(); - let params = (&config, &whitelist); - add_benchmarks!(params, batches); - - Ok(batches) - } - } -} - -fn extract_xdm_proof_state_roots( - encoded_ext: Vec, -) -> Option> { - if let Ok(ext) = UncheckedExtrinsic::decode(&mut encoded_ext.as_slice()) { - match &ext.function { - RuntimeCall::Messenger(pallet_messenger::Call::relay_message { msg }) => { - msg.extract_state_roots_from_proof::() - } - RuntimeCall::Messenger(pallet_messenger::Call::relay_message_response { msg }) => { - msg.extract_state_roots_from_proof::() - } - _ => None, - } - } else { - None - } -} diff --git a/domains/service/Cargo.toml b/domains/service/Cargo.toml index 17816a2eeca..cafd9d5d96f 100644 --- a/domains/service/Cargo.toml +++ b/domains/service/Cargo.toml @@ -18,57 +18,55 @@ clap = { version = "4.2.1", features = ["derive"] } cross-domain-message-gossip = { version = "0.1.0", path = "../client/cross-domain-message-gossip" } domain-client-block-preprocessor = { package = "domain-block-preprocessor", version = "0.1.0", path = "../client/block-preprocessor" } domain-client-consensus-relay-chain = { version = "0.1.0", path = "../client/consensus-relay-chain" } -domain-client-executor = { version = "0.1.0", path = "../client/domain-executor" } -domain-client-executor-gossip = { version = "0.1.0", path = "../client/executor-gossip" } domain-client-message-relayer = { version = "0.1.0", path = "../client/relayer" } +domain-client-operator = { version = "0.1.0", path = "../client/domain-operator" } +domain-client-subnet-gossip = { version = "0.1.0", path = "../client/subnet-gossip" } domain-runtime-primitives = { version = "0.1.0", path = "../primitives/runtime" } -frame-benchmarking = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-benchmarking-cli = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false, features = ["runtime-benchmarks"] } +frame-benchmarking = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-benchmarking-cli = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false, features = ["runtime-benchmarks"] } futures = "0.3.28" hex-literal = "0.4.0" jsonrpsee = { version = "0.16.2", features = ["server"] } log = "0.4.19" -pallet-transaction-payment-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-chain-spec = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-transactions = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-rpc-api = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-rpc-spec-v2 = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-transaction-payment-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-chain-spec = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-common = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-transactions = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-rpc-api = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-rpc-spec-v2 = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } serde = { version = "1.0.159", features = ["derive"] } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../../crates/sp-domains" } -sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-messenger = { version = "0.1.0", path = "../../domains/primitives/messenger" } -sp-offchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-session = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", path = "../../crates/sp-settlement" } -sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -system-runtime-primitives = { version = "0.1.0", path = "../primitives/system-runtime" } +sp-offchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-session = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", path = "../../crates/subspace-core-primitives" } subspace-fraud-proof = { version = "0.1.0", path = "../../crates/subspace-fraud-proof" } subspace-runtime-primitives = { version = "0.1.0", path = "../../crates/subspace-runtime-primitives" } subspace-transaction-pool = { version = "0.1.0", path = "../../crates/subspace-transaction-pool" } -substrate-frame-rpc-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +substrate-frame-rpc-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +substrate-prometheus-endpoint = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } tracing = "0.1.37" [build-dependencies] -substrate-build-script-utils = { version = "3.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +substrate-build-script-utils = { version = "3.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } diff --git a/domains/service/src/system_domain.rs b/domains/service/src/domain.rs similarity index 52% rename from domains/service/src/system_domain.rs rename to domains/service/src/domain.rs index 79ec03d9d62..4c02612aad0 100644 --- a/domains/service/src/system_domain.rs +++ b/domains/service/src/domain.rs @@ -1,14 +1,12 @@ -use crate::system_domain_tx_pre_validator::SystemDomainTxPreValidator; +use crate::providers::{BlockImportProvider, RpcProvider}; use crate::{DomainConfiguration, FullBackend, FullClient}; use cross_domain_message_gossip::DomainTxPoolSink; use domain_client_block_preprocessor::runtime_api_full::RuntimeApiFull; -use domain_client_executor::{ - EssentialExecutorParams, ExecutorStreams, SystemDomainParentChain, SystemExecutor, -}; -use domain_client_executor_gossip::ExecutorGossipParams; +use domain_client_consensus_relay_chain::DomainBlockImport; use domain_client_message_relayer::GossipMessageSink; +use domain_client_operator::{Operator, OperatorParams, OperatorStreams}; use domain_runtime_primitives::opaque::Block; -use domain_runtime_primitives::{AccountId, Balance, DomainCoreApi, Hash}; +use domain_runtime_primitives::{Balance, BlockNumber, DomainCoreApi, Hash, InherentExtrinsicApi}; use futures::channel::mpsc; use futures::Stream; use jsonrpsee::tracing; @@ -22,80 +20,72 @@ use sc_service::{ }; use sc_telemetry::{Telemetry, TelemetryWorker, TelemetryWorkerHandle}; use sc_utils::mpsc::tracing_unbounded; +use serde::de::DeserializeOwned; use sp_api::{ApiExt, BlockT, ConstructRuntimeApi, Metadata, NumberFor, ProvideRuntimeApi}; use sp_block_builder::BlockBuilder; use sp_blockchain::{HeaderBackend, HeaderMetadata}; use sp_consensus::{SelectChain, SyncOracle}; use sp_consensus_slots::Slot; use sp_core::traits::SpawnEssentialNamed; -use sp_domains::transaction::PreValidationObjectApi; -use sp_domains::{DomainId, ExecutorApi}; +use sp_core::{Decode, Encode}; +use sp_domains::{BundleProducerElectionApi, DomainId, DomainsApi}; use sp_messenger::{MessengerApi, RelayerApi}; use sp_offchain::OffchainWorkerApi; use sp_session::SessionKeys; -use sp_settlement::SettlementApi; use sp_transaction_pool::runtime_api::TaggedTransactionQueue; +use std::fmt::{Debug, Display}; +use std::marker::PhantomData; +use std::str::FromStr; use std::sync::Arc; -use subspace_core_primitives::Blake2b256Hash; +use subspace_core_primitives::Randomness; use subspace_runtime_primitives::Index as Nonce; +use subspace_transaction_pool::FullChainApiWrapper; use substrate_frame_rpc_system::AccountNonceApi; -use system_runtime_primitives::SystemDomainApi; -type SystemDomainExecutor = SystemExecutor< +type BlockImportOf = >::BI; + +pub type DomainOperator = Operator< Block, - PBlock, + CBlock, FullClient, - PClient, - FullPool, + CClient, + FullPool, FullBackend, NativeElseWasmExecutor, + DomainBlockImport, >; -type SystemGossipMessageValidator = - domain_client_executor::SystemGossipMessageValidator< - Block, - PBlock, - FullClient, - PClient, - FullPool, - FullBackend, - NativeElseWasmExecutor, - SystemDomainParentChain, - >; - -/// System domain full node along with some other components. -pub struct NewFullSystem +/// Domain full node along with some other components. +pub struct NewFull where Block: BlockT, - PBlock: BlockT, - NumberFor: From>, - PBlock::Hash: From, - ExecutorDispatch: NativeExecutionDispatch + 'static, - PClient: HeaderBackend - + BlockBackend - + ProvideRuntimeApi + CBlock: BlockT, + NumberFor: From>, + CBlock::Hash: From, + CClient: HeaderBackend + + BlockBackend + + ProvideRuntimeApi + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, + CClient::Api: DomainsApi, RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, RuntimeApi::RuntimeApi: ApiExt, Block>> + Metadata + + AccountNonceApi + BlockBuilder + OffchainWorkerApi + SessionKeys - + DomainCoreApi - + MessengerApi> - + SystemDomainApi, PBlock::Hash, ::Hash> + TaggedTransactionQueue - + AccountNonceApi + TransactionPaymentRuntimeApi - + RelayerApi> - + SettlementApi - + PreValidationObjectApi, + + DomainCoreApi + + MessengerApi> + + RelayerApi>, + ExecutorDispatch: NativeExecutionDispatch + 'static, + AccountId: Encode + Decode, { /// Task manager. pub task_manager: TaskManager, @@ -113,69 +103,72 @@ where pub rpc_handlers: sc_service::RpcHandlers, /// Network starter. pub network_starter: NetworkStarter, - /// Executor. - pub executor: SystemDomainExecutor, - pub gossip_message_validator: - SystemGossipMessageValidator, + /// Operator. + pub operator: DomainOperator, /// Transaction pool sink pub tx_pool_sink: DomainTxPoolSink, + _phantom_data: PhantomData, } -pub type FullPool = subspace_transaction_pool::FullPool< - Block, - FullClient, - SystemDomainTxPreValidator< +type DomainTxPreValidator = + crate::domain_tx_pre_validator::DomainTxPreValidator< Block, - PBlock, - FullClient, - PClient, - RuntimeApiFull>, - >, ->; + CBlock, + FullClient, + CClient, + RuntimeApiFull>, + >; -/// Constructs a partial system domain node. +pub type FullPool = + subspace_transaction_pool::FullPool< + Block, + FullClient, + DomainTxPreValidator, + >; + +/// Constructs a partial domain node. #[allow(clippy::type_complexity)] -fn new_partial( +fn new_partial( config: &ServiceConfiguration, - primary_chain_client: Arc, + domain_id: DomainId, + consensus_client: Arc, + block_import_provider: &BIMP, ) -> Result< PartialComponents< - FullClient, + FullClient, FullBackend, (), - sc_consensus::DefaultImportQueue>, - FullPool, + sc_consensus::DefaultImportQueue>, + FullPool, ( Option, Option, - NativeElseWasmExecutor, - Arc>, + NativeElseWasmExecutor, + Arc>, ), >, sc_service::Error, > where - PBlock: BlockT, - NumberFor: From>, - PBlock::Hash: From, - PClient: HeaderBackend - + BlockBackend - + ProvideRuntimeApi + CBlock: BlockT, + NumberFor: From>, + CBlock::Hash: From, + CClient: HeaderBackend + + BlockBackend + + ProvideRuntimeApi + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, - RuntimeApi: ConstructRuntimeApi> + CClient::Api: DomainsApi, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, RuntimeApi::RuntimeApi: TaggedTransactionQueue - + SystemDomainApi, PBlock::Hash, ::Hash> + MessengerApi> - + ApiExt, Block>> - + SettlementApi - + PreValidationObjectApi, - ExecutionDispatch: NativeExecutionDispatch + 'static, + + ApiExt, Block>>, + ExecutorDispatch: NativeExecutionDispatch + 'static, + BIMP: BlockImportProvider>, { let telemetry = config .telemetry_endpoints @@ -206,10 +199,11 @@ where telemetry }); - let system_domain_tx_pre_validator = SystemDomainTxPreValidator::new( + let domain_tx_pre_validator = DomainTxPreValidator::new( + domain_id, client.clone(), Box::new(task_manager.spawn_handle()), - primary_chain_client, + consensus_client, RuntimeApiFull::new(client.clone()), ); @@ -217,10 +211,13 @@ where config, &task_manager, client.clone(), - system_domain_tx_pre_validator, + domain_tx_pre_validator, ); - let block_import = client.clone(); + let block_import = Arc::new(DomainBlockImport::new(BlockImportProvider::block_import( + block_import_provider, + client.clone(), + ))); let import_queue = domain_client_consensus_relay_chain::import_queue( block_import.clone(), &task_manager.spawn_essential_handle(), @@ -241,44 +238,66 @@ where Ok(params) } -/// Start a node with the given system domain `Configuration` and consensus chain `Configuration`. -/// -/// This is the actual implementation that is abstract over the executor and the runtime api. -pub async fn new_full_system( - system_domain_config: DomainConfiguration, - primary_chain_client: Arc, - primary_network_sync_oracle: Arc, - select_chain: &SC, - executor_streams: ExecutorStreams, - gossip_message_sink: GossipMessageSink, +pub struct DomainParams +where + CBlock: BlockT, +{ + pub domain_id: DomainId, + pub domain_config: DomainConfiguration, + pub domain_created_at: NumberFor, + pub consensus_client: Arc, + pub consensus_network_sync_oracle: Arc, + pub select_chain: SC, + pub operator_streams: OperatorStreams, + pub gossip_message_sink: GossipMessageSink, + pub provider: Provider, +} + +/// Builds service for a domain full node. +pub async fn new_full< + CBlock, + CClient, + SC, + IBNS, + CIBNS, + NSNS, + RuntimeApi, + ExecutorDispatch, + AccountId, + Provider, +>( + domain_params: DomainParams, ) -> sc_service::error::Result< - NewFullSystem< + NewFull< Arc>, NativeElseWasmExecutor, - PBlock, - PClient, + CBlock, + CClient, RuntimeApi, ExecutorDispatch, + AccountId, + BlockImportOf, Provider>, >, > where - PBlock: BlockT, - NumberFor: From> + Into, + CBlock: BlockT, + NumberFor: From> + Into, ::Hash: From, - PBlock::Hash: From, - PClient: HeaderBackend - + HeaderMetadata - + BlockBackend - + ProvideRuntimeApi - + BlockchainEvents + CBlock::Hash: From, + CClient: HeaderBackend + + HeaderMetadata + + BlockBackend + + ProvideRuntimeApi + + BlockchainEvents + Send + Sync + 'static, - PClient::Api: ExecutorApi + SettlementApi, - SC: SelectChain, - IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, - CIBNS: Stream> + Send + 'static, - NSNS: Stream>)> + Send + 'static, + CClient::Api: DomainsApi + + BundleProducerElectionApi, + SC: SelectChain, + IBNS: Stream, mpsc::Sender<()>)> + Send + 'static, + CIBNS: Stream> + Send + 'static, + NSNS: Stream>)> + Send + 'static, RuntimeApi: ConstructRuntimeApi> + Send + Sync @@ -289,22 +308,57 @@ where + OffchainWorkerApi + SessionKeys + DomainCoreApi - + SystemDomainApi, PBlock::Hash, ::Hash> + MessengerApi> + + InherentExtrinsicApi + TaggedTransactionQueue + AccountNonceApi + TransactionPaymentRuntimeApi - + RelayerApi> - + SettlementApi - + PreValidationObjectApi, + + RelayerApi>, ExecutorDispatch: NativeExecutionDispatch + 'static, + AccountId: DeserializeOwned + + Encode + + Decode + + Clone + + Debug + + Display + + FromStr + + Sync + + Send + + 'static, + Provider: RpcProvider< + Block, + FullClient, + FullPool, + FullChainApiWrapper< + Block, + FullClient, + DomainTxPreValidator, + >, + TFullBackend, + AccountId, + > + BlockImportProvider> + + 'static, { - // TODO: Do we even need block announcement on system domain node? - // system_domain_config.announce_block = false; + let DomainParams { + domain_id, + mut domain_config, + domain_created_at, + consensus_client, + consensus_network_sync_oracle, + select_chain, + operator_streams, + gossip_message_sink, + provider, + } = domain_params; + + // TODO: Do we even need block announcement on domain node? + // domain_config.announce_block = false; let params = new_partial( - &system_domain_config.service_config, - primary_chain_client.clone(), + &domain_config.service_config, + domain_id, + consensus_client.clone(), + &provider, )?; let (mut telemetry, _telemetry_worker_handle, code_executor, block_import) = params.other; @@ -314,17 +368,16 @@ where let transaction_pool = params.transaction_pool.clone(); let mut task_manager = params.task_manager; - let mut net_config = sc_network::config::FullNetworkConfiguration::new( - &system_domain_config.service_config.network, - ); + let mut net_config = + sc_network::config::FullNetworkConfiguration::new(&domain_config.service_config.network); net_config.add_notification_protocol( - domain_client_executor_gossip::executor_gossip_peers_set_config(), + domain_client_subnet_gossip::domain_subnet_gossip_peers_set_config(), ); let (network_service, system_rpc_tx, tx_handler_controller, network_starter, sync_service) = crate::build_network(BuildNetworkParams { - config: &system_domain_config.service_config, + config: &domain_config.service_config, net_config, client: client.clone(), transaction_pool: transaction_pool.clone(), @@ -336,27 +389,36 @@ where block_relay: None, })?; - let is_authority = system_domain_config.service_config.role.is_authority(); + let is_authority = domain_config.service_config.role.is_authority(); + domain_config.service_config.rpc_id_provider = provider.rpc_id(); let rpc_builder = { let deps = crate::rpc::FullDeps { client: client.clone(), pool: transaction_pool.clone(), graph: transaction_pool.pool().clone(), - chain_spec: system_domain_config.service_config.chain_spec.cloned_box(), + chain_spec: domain_config.service_config.chain_spec.cloned_box(), deny_unsafe: DenyUnsafe::Yes, network: network_service.clone(), sync: sync_service.clone(), is_authority, - prometheus_registry: system_domain_config - .service_config - .prometheus_registry() - .cloned(), - database_source: system_domain_config.service_config.database.clone(), + prometheus_registry: domain_config.service_config.prometheus_registry().cloned(), + database_source: domain_config.service_config.database.clone(), task_spawner: task_manager.spawn_handle(), backend: backend.clone(), }; - Box::new(move |_, _| crate::rpc::create_full(deps.clone()).map_err(Into::into)) + let spawn_essential = task_manager.spawn_essential_handle(); + let rpc_deps = provider.deps(deps)?; + Box::new(move |_, subscription_task_executor| { + let spawn_essential = spawn_essential.clone(); + provider + .rpc_builder( + rpc_deps.clone(), + subscription_task_executor, + spawn_essential, + ) + .map_err(Into::into) + }) }; let rpc_handlers = sc_service::spawn_tasks(SpawnTasksParams { @@ -364,7 +426,7 @@ where client: client.clone(), transaction_pool: transaction_pool.clone(), task_manager: &mut task_manager, - config: system_domain_config.service_config, + config: domain_config.service_config, keystore: params.keystore_container.keystore(), backend: backend.clone(), network: network_service.clone(), @@ -377,20 +439,24 @@ where let code_executor = Arc::new(code_executor); let spawn_essential = task_manager.spawn_essential_handle(); - let (bundle_sender, bundle_receiver) = tracing_unbounded("system_domain_bundle_stream", 100); - - let domain_confirmation_depth = primary_chain_client - .runtime_api() - .receipts_pruning_depth(primary_chain_client.info().best_hash) - .map_err(|err| sc_service::error::Error::Application(Box::new(err)))? - .into(); - - let executor = SystemExecutor::new( - Box::new(task_manager.spawn_essential_handle()), - select_chain, - EssentialExecutorParams { - primary_chain_client: primary_chain_client.clone(), - primary_network_sync_oracle, + let (bundle_sender, _bundle_receiver) = tracing_unbounded("domain_bundle_stream", 100); + + // let domain_confirmation_depth = consensus_client + // .runtime_api() + // .receipts_pruning_depth(consensus_client.info().best_hash) + // .map_err(|err| sc_service::error::Error::Application(Box::new(err)))? + // .into(); + // TODO: Implement when block tree is ready. + let domain_confirmation_depth = 256u32; + + let operator = Operator::new( + Box::new(spawn_essential.clone()), + &select_chain, + OperatorParams { + domain_id, + domain_created_at, + consensus_client: consensus_client.clone(), + consensus_network_sync_oracle, client: client.clone(), transaction_pool: transaction_pool.clone(), backend: backend.clone(), @@ -398,69 +464,42 @@ where is_authority, keystore: params.keystore_container.keystore(), bundle_sender: Arc::new(bundle_sender), - executor_streams, + operator_streams, domain_confirmation_depth, block_import, }, ) .await?; - let gossip_message_validator = SystemGossipMessageValidator::new( - SystemDomainParentChain::::new(primary_chain_client), - client.clone(), - Box::new(task_manager.spawn_handle()), - transaction_pool.clone(), - executor.fraud_proof_generator(), - ); - let executor_gossip = - domain_client_executor_gossip::start_gossip_worker(ExecutorGossipParams { - network: network_service.clone(), - sync: sync_service.clone(), - executor: gossip_message_validator.clone(), - bundle_receiver, - }); - spawn_essential.spawn_essential_blocking( - "system-domain-gossip", - None, - Box::pin(executor_gossip), - ); - - if let Some(relayer_id) = system_domain_config.maybe_relayer_id { - tracing::info!( - "Starting system domain relayer with relayer_id[{:?}]", - relayer_id - ); + if let Some(relayer_id) = domain_config.maybe_relayer_id { + tracing::info!(?domain_id, ?relayer_id, "Starting domain relayer"); let relayer_worker = domain_client_message_relayer::worker::relay_system_domain_messages( relayer_id, client.clone(), sync_service.clone(), - gossip_message_sink.clone(), + gossip_message_sink, ); - spawn_essential.spawn_essential_blocking( - "system-domain-relayer", - None, - Box::pin(relayer_worker), - ); + spawn_essential.spawn_essential_blocking("domain-relayer", None, Box::pin(relayer_worker)); } - let (msg_sender, msg_receiver) = tracing_unbounded("system_domain_message_channel", 100); + let (msg_sender, msg_receiver) = tracing_unbounded("domain_message_channel", 100); - // start cross domain message listener for system domain - let system_domain_listener = cross_domain_message_gossip::start_domain_message_listener( - DomainId::SYSTEM, + // Start cross domain message listener for domain + let domain_listener = cross_domain_message_gossip::start_domain_message_listener( + domain_id, client.clone(), params.transaction_pool.clone(), msg_receiver, ); spawn_essential.spawn_essential_blocking( - "system-domain-message-listener", + "domain-message-listener", None, - Box::pin(system_domain_listener), + Box::pin(domain_listener), ); - let new_full = NewFullSystem { + let new_full = NewFull { task_manager, client, backend, @@ -469,9 +508,9 @@ where sync_service, rpc_handlers, network_starter, - executor, - gossip_message_validator, + operator, tx_pool_sink: msg_sender, + _phantom_data: Default::default(), }; Ok(new_full) diff --git a/domains/service/src/system_domain_tx_pre_validator.rs b/domains/service/src/domain_tx_pre_validator.rs similarity index 59% rename from domains/service/src/system_domain_tx_pre_validator.rs rename to domains/service/src/domain_tx_pre_validator.rs index bf3273fbf55..ccc4e1ae949 100644 --- a/domains/service/src/system_domain_tx_pre_validator.rs +++ b/domains/service/src/domain_tx_pre_validator.rs @@ -1,55 +1,58 @@ use domain_client_block_preprocessor::runtime_api::StateRootExtractor; -use domain_client_block_preprocessor::xdm_verifier::verify_xdm_with_primary_chain_client; +use domain_client_block_preprocessor::xdm_verifier::verify_xdm_with_consensus_client; use sc_transaction_pool::error::Result as TxPoolResult; use sc_transaction_pool_api::error::Error as TxPoolError; use sc_transaction_pool_api::TransactionSource; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_core::traits::SpawnNamed; -use sp_domains::transaction::PreValidationObjectApi; +use sp_domains::{DomainId, DomainsApi}; use sp_runtime::traits::{Block as BlockT, NumberFor}; -use sp_settlement::SettlementApi; use std::marker::PhantomData; use std::sync::Arc; use subspace_transaction_pool::PreValidateTransaction; -pub struct SystemDomainTxPreValidator { +pub struct DomainTxPreValidator { + domain_id: DomainId, client: Arc, spawner: Box, - primary_chain_client: Arc, + consensus_client: Arc, state_root_extractor: SRE, - _phantom_data: PhantomData<(Block, PBlock)>, + _phantom_data: PhantomData<(Block, CBlock)>, } -impl Clone - for SystemDomainTxPreValidator +impl Clone + for DomainTxPreValidator where SRE: Clone, { fn clone(&self) -> Self { Self { + domain_id: self.domain_id, client: self.client.clone(), spawner: self.spawner.clone(), - primary_chain_client: self.primary_chain_client.clone(), + consensus_client: self.consensus_client.clone(), state_root_extractor: self.state_root_extractor.clone(), _phantom_data: self._phantom_data, } } } -impl - SystemDomainTxPreValidator +impl + DomainTxPreValidator { pub fn new( + domain_id: DomainId, client: Arc, spawner: Box, - primary_chain_client: Arc, + consensus_client: Arc, state_root_extractor: SRE, ) -> Self { Self { + domain_id, client, spawner, - primary_chain_client, + consensus_client, state_root_extractor, _phantom_data: Default::default(), } @@ -57,17 +60,16 @@ impl } #[async_trait::async_trait] -impl PreValidateTransaction - for SystemDomainTxPreValidator +impl PreValidateTransaction + for DomainTxPreValidator where Block: BlockT, - PBlock: BlockT, - PBlock::Hash: From, - NumberFor: From>, + CBlock: BlockT, + CBlock::Hash: From, + NumberFor: From>, Client: ProvideRuntimeApi + Send + Sync, - Client::Api: PreValidationObjectApi, - PClient: HeaderBackend + ProvideRuntimeApi + 'static, - PClient::Api: SettlementApi, + CClient: HeaderBackend + ProvideRuntimeApi + 'static, + CClient::Api: DomainsApi, Block::Hash>, SRE: StateRootExtractor + Send + Sync, { type Block = Block; @@ -77,8 +79,9 @@ where _source: TransactionSource, uxt: Block::Extrinsic, ) -> TxPoolResult<()> { - if !verify_xdm_with_primary_chain_client::( - &self.primary_chain_client, + if !verify_xdm_with_consensus_client::( + self.domain_id, + &self.consensus_client, at, &self.state_root_extractor, &uxt, diff --git a/domains/service/src/lib.rs b/domains/service/src/lib.rs index 05c6a9472ca..70506fa3697 100644 --- a/domains/service/src/lib.rs +++ b/domains/service/src/lib.rs @@ -1,11 +1,11 @@ //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. +mod domain; +mod domain_tx_pre_validator; pub mod providers; pub mod rpc; -mod system_domain; -mod system_domain_tx_pre_validator; -pub use self::system_domain::{new_full_system, FullPool, NewFullSystem}; +pub use self::domain::{new_full, DomainOperator, DomainParams, FullPool, NewFull}; use futures::channel::oneshot; use futures::{FutureExt, StreamExt}; use sc_client_api::{BlockBackend, BlockchainEvents, HeaderBackend, ProofProvider}; @@ -29,6 +29,7 @@ use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderMetadata; use sp_consensus::block_validation::{Chain, DefaultBlockAnnounceValidator}; use sp_runtime::traits::{Block as BlockT, BlockIdTo, Zero}; +use std::sync::atomic::Ordering; use std::sync::Arc; /// Domain full client. @@ -87,10 +88,12 @@ where } = params; if client.requires_full_sync() { - match config.network.sync_mode { - SyncMode::Fast { .. } => return Err("Fast sync doesn't work for archive nodes".into()), + match config.network.sync_mode.load(Ordering::Acquire) { + SyncMode::LightState { .. } => { + return Err("Fast sync doesn't work for archive nodes".into()) + } SyncMode::Warp => return Err("Warp sync doesn't work for archive nodes".into()), - SyncMode::Full => {} + SyncMode::Full | SyncMode::Paused => {} } } diff --git a/domains/test/primitives/Cargo.toml b/domains/test/primitives/Cargo.toml index aaebae70192..a05aa2635e4 100644 --- a/domains/test/primitives/Cargo.toml +++ b/domains/test/primitives/Cargo.toml @@ -13,7 +13,7 @@ include = [ [dependencies] codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"]} -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } sp-domains = { version = "0.1.0", default-features = false, path = "../../../crates/sp-domains" } sp-messenger = { version = "0.1.0", default-features = false, path = "../../primitives/messenger" } subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives", default-features = false } @@ -22,5 +22,7 @@ subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subsp default = ["std"] std = [ "sp-api/std", + "sp-domains/std", + "sp-messenger/std", "subspace-runtime-primitives/std", ] diff --git a/domains/runtime/core-evm/Cargo.toml b/domains/test/runtime/evm/Cargo.toml similarity index 65% rename from domains/runtime/core-evm/Cargo.toml rename to domains/test/runtime/evm/Cargo.toml index d2214550fab..7fa7eaf825c 100644 --- a/domains/runtime/core-evm/Cargo.toml +++ b/domains/test/runtime/evm/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "core-evm-runtime" +name = "evm-domain-test-runtime" version = "0.1.0" authors = ["Vedhavyas Singareddi, Liu-Cheng Xu "] license = "Apache-2.0" @@ -18,52 +18,54 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.2.1", default-features = false, features = ["derive"] } -domain-pallet-executive = { version = "0.1.0", path = "../../pallets/executive", default-features = false } -domain-runtime-primitives = { version = "0.1.0", path = "../../primitives/runtime", default-features = false } +domain-pallet-executive = { version = "0.1.0", path = "../../../pallets/executive", default-features = false } +domain-test-primitives = { version = "0.1.0", path = "../../primitives", default-features = false } +domain-runtime-primitives = { version = "0.1.0", path = "../../../primitives/runtime", default-features = false } fp-account = { version = "1.0.0-dev", default-features = false, features = ["serde"], git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } fp-evm = { version = "3.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } fp-rpc = { version = "3.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } fp-self-contained = { version = "1.0.0-dev", default-features = false, features = ["serde"], git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } hex-literal = { version = '0.4.0', optional = true } log = { version = "0.4.19", default-features = false } -pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } pallet-base-fee = { version = "1.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } +pallet-domain-id = { version = "0.1.0", path = "../../../pallets/domain-id", default-features = false } pallet-ethereum = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } pallet-evm = { version = "6.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } pallet-evm-chain-id = { version = "1.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } pallet-evm-precompile-modexp = { version = "2.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } pallet-evm-precompile-sha3fips = { version = "2.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } pallet-evm-precompile-simple = { version = "2.0.0-dev", default-features = false, git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } -pallet-messenger = { version = "0.1.0", path = "../../pallets/messenger", default-features = false } -pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transporter = { version = "0.1.0", path = "../../pallets/transporter", default-features = false } +pallet-messenger = { version = "0.1.0", path = "../../../pallets/messenger", default-features = false } +pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transaction-payment-rpc-runtime-api = { default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transporter = { version = "0.1.0", path = "../../../pallets/transporter", default-features = false } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains", default-features = false } -sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-messenger = { version = "0.1.0", default-features = false, path = "../../primitives/messenger" } -sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives", default-features = false } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-domains = { version = "0.1.0", path = "../../../../crates/sp-domains", default-features = false } +sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-messenger = { version = "0.1.0", default-features = false, path = "../../../primitives/messenger" } +sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +subspace-core-primitives = { version = "0.1.0", path = "../../../../crates/subspace-core-primitives", default-features = false } +subspace-runtime-primitives = { version = "0.1.0", path = "../../../../crates/subspace-runtime-primitives", default-features = false } [build-dependencies] -subspace-wasm-tools = { version = "0.1.0", path = "../../../crates/subspace-wasm-tools" } -substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } +substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } [features] default = [ @@ -73,6 +75,7 @@ std = [ "codec/std", "domain-pallet-executive/std", "domain-runtime-primitives/std", + "domain-test-primitives/std", "fp-account/std", "fp-evm/std", "fp-rpc/std", @@ -83,6 +86,7 @@ std = [ "log/std", "pallet-balances/std", "pallet-base-fee/std", + "pallet-domain-id/std", "pallet-ethereum/std", "pallet-evm/std", "pallet-evm-chain-id/std", @@ -109,6 +113,7 @@ std = [ "sp-std/std", "sp-transaction-pool/std", "sp-version/std", + "subspace-core-primitives/std", "subspace-runtime-primitives/std", "substrate-wasm-builder", ] diff --git a/domains/runtime/system/build.rs b/domains/test/runtime/evm/build.rs similarity index 69% rename from domains/runtime/system/build.rs rename to domains/test/runtime/evm/build.rs index a9033702fe0..8f021e8381d 100644 --- a/domains/runtime/system/build.rs +++ b/domains/test/runtime/evm/build.rs @@ -3,11 +3,8 @@ fn main() { { substrate_wasm_builder::WasmBuilder::new() .with_current_project() - .enable_feature("wasm-builder") .export_heap_base() .import_memory() .build(); } - - subspace_wasm_tools::export_wasm_bundle_path(); } diff --git a/domains/test/runtime/evm/src/lib.rs b/domains/test/runtime/evm/src/lib.rs new file mode 100644 index 00000000000..5d73af5136c --- /dev/null +++ b/domains/test/runtime/evm/src/lib.rs @@ -0,0 +1,1096 @@ +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit = "256"] + +mod precompiles; + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +use codec::{Decode, Encode}; +pub use domain_runtime_primitives::opaque::Header; +pub use domain_runtime_primitives::{opaque, Balance, BlockNumber, Hash, Index}; +use domain_runtime_primitives::{MultiAccountId, TryConvertBack, SLOT_DURATION}; +use fp_account::EthereumSignature; +use fp_self_contained::SelfContainedCall; +use frame_support::dispatch::{DispatchClass, GetDispatchInfo}; +use frame_support::traits::{ConstU16, ConstU32, ConstU64, Everything, FindAuthor}; +use frame_support::weights::constants::{ + BlockExecutionWeight, ExtrinsicBaseWeight, ParityDbWeight, WEIGHT_REF_TIME_PER_MILLIS, + WEIGHT_REF_TIME_PER_SECOND, +}; +use frame_support::weights::{ConstantMultiplier, IdentityFee, Weight}; +use frame_support::{construct_runtime, parameter_types}; +use frame_system::limits::{BlockLength, BlockWeights}; +use pallet_ethereum::Call::transact; +use pallet_ethereum::{PostLogContent, Transaction as EthereumTransaction, TransactionStatus}; +use pallet_evm::{ + Account as EVMAccount, EnsureAddressNever, EnsureAddressRoot, FeeCalculator, + IdentityAddressMapping, Runner, +}; +use pallet_transporter::EndpointHandler; +use sp_api::impl_runtime_apis; +use sp_core::crypto::KeyTypeId; +use sp_core::{Get, OpaqueMetadata, H160, H256, U256}; +use sp_domains::DomainId; +use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId}; +use sp_messenger::messages::{ + ChannelId, CrossDomainMessage, ExtractedStateRootsFromProof, MessageId, + RelayerMessagesWithStorageKey, +}; +use sp_runtime::traits::{ + BlakeTwo256, Block as BlockT, Convert, DispatchInfoOf, Dispatchable, IdentifyAccount, + IdentityLookup, PostDispatchInfoOf, UniqueSaturatedInto, Verify, +}; +use sp_runtime::transaction_validity::{ + TransactionSource, TransactionValidity, TransactionValidityError, +}; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, ApplyExtrinsicResult, ConsensusEngineId, +}; +pub use sp_runtime::{MultiAddress, Perbill, Permill}; +use sp_std::marker::PhantomData; +use sp_std::prelude::*; +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +use subspace_runtime_primitives::{Moment, SHANNON, SSC}; + +/// Alias to 512-bit hash when used in the context of a transaction signature on the chain. +pub type Signature = EthereumSignature; + +/// Some way of identifying an account on the chain. We intentionally make it equivalent +/// to the public key of our transaction signing scheme. +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; + +/// The address format for describing accounts. +pub type Address = AccountId; + +/// Block type as expected by this runtime. +pub type Block = generic::Block; + +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; + +/// BlockId type as expected by this runtime. +pub type BlockId = generic::BlockId; + +/// Precompiles we use for EVM +pub type Precompiles = crate::precompiles::Precompiles; + +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckMortality, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, +); + +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + fp_self_contained::UncheckedExtrinsic; + +/// Extrinsic type that has already been checked. +pub type CheckedExtrinsic = + fp_self_contained::CheckedExtrinsic; + +/// Executive: handles dispatch to the various modules. +pub type Executive = domain_pallet_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, + Runtime, +>; + +impl fp_self_contained::SelfContainedCall for RuntimeCall { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + RuntimeCall::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + RuntimeCall::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option { + match self { + RuntimeCall::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option> { + match self { + RuntimeCall::Ethereum(call) => { + call.pre_dispatch_self_contained(info, dispatch_info, len) + } + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { + Some(call.dispatch(RuntimeOrigin::from( + pallet_ethereum::RawOrigin::EthereumTransaction(info), + ))) + } + _ => None, + } + } +} + +impl_opaque_keys! { + pub struct SessionKeys { + /// Primarily used for adding the executor authority key into the keystore in the dev mode. + pub executor: sp_domains::OperatorKey, + } +} + +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("subspace-evm-domain"), + impl_name: create_runtime_str!("subspace-evm-domain"), + authoring_version: 0, + spec_version: 0, + impl_version: 0, + apis: RUNTIME_API_VERSIONS, + transaction_version: 0, + state_version: 0, +}; + +/// The existential deposit. Same with the one on primary chain. +pub const EXISTENTIAL_DEPOSIT: Balance = 500 * SHANNON; + +/// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is +/// used to limit the maximal weight of a single extrinsic. +const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); + +/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by +/// `Operational` extrinsics. +const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +/// We allow for 2000ms of compute with a 6 second average block time. +pub const WEIGHT_MILLISECS_PER_BLOCK: u64 = 2000; +pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( + WEIGHT_MILLISECS_PER_BLOCK * WEIGHT_REF_TIME_PER_MILLIS, + u64::MAX, +); +pub const MAXIMUM_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; + +/// The version information used to identify this runtime when compiled natively. +#[cfg(feature = "std")] +pub fn native_version() -> NativeVersion { + NativeVersion { + runtime_version: VERSION, + can_author_with: Default::default(), + } +} + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + pub const BlockHashCount: BlockNumber = 2400; + + // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`. + // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the + // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize + // the lazy contract deletion. + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() + .base_block(BlockExecutionWeight::get()) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = ExtrinsicBaseWeight::get(); + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); + // Operational transactions have some extra reserved space, so that they + // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. + weights.reserved = Some( + MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT + ); + }) + .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) + .build_or_panic(); +} + +impl frame_system::Config for Runtime { + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The aggregated dispatch type that is available for extrinsics. + type RuntimeCall = RuntimeCall; + /// The lookup mechanism to get account ID from whatever is passed in dispatchers. + type Lookup = IdentityLookup; + /// The index type for storing how many extrinsics an account has signed. + type Index = Index; + /// The index type for blocks. + type BlockNumber = BlockNumber; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The hashing algorithm used. + type Hashing = BlakeTwo256; + /// The header type. + type Header = Header; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + /// The ubiquitous origin type. + type RuntimeOrigin = RuntimeOrigin; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// Runtime version. + type Version = Version; + /// Converts a module to an index of this module in the runtime. + type PalletInfo = PalletInfo; + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; + /// What to do if a new account is created. + type OnNewAccount = (); + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// The weight of database operations that the runtime can invoke. + type DbWeight = ParityDbWeight; + /// The basic call filter to use in dispatchable. + type BaseCallFilter = Everything; + /// Weight information for the extrinsics of this pallet. + type SystemWeightInfo = (); + /// Block & extrinsics weights: base values and limits. + type BlockWeights = RuntimeBlockWeights; + /// The maximum length of a block (in bytes). + type BlockLength = RuntimeBlockLength; + type SS58Prefix = ConstU16<2254>; + /// The action to take on a Runtime Upgrade + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +impl pallet_timestamp::Config for Runtime { + /// A timestamp: milliseconds since the unix epoch. + type Moment = Moment; + type OnTimestampSet = (); + type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; + type WeightInfo = (); +} + +parameter_types! { + pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = pallet_balances::weights::SubstrateWeight; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type FreezeIdentifier = (); + type MaxFreezes = (); + type RuntimeHoldReason = (); + type MaxHolds = (); +} + +parameter_types! { + pub const TransactionByteFee: Balance = 1; + pub const OperationalFeeMultiplier: u8 = 5; +} + +impl pallet_transaction_payment::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; + type WeightToFee = IdentityFee; + type LengthToFee = ConstantMultiplier; + type FeeMultiplierUpdate = (); + type OperationalFeeMultiplier = OperationalFeeMultiplier; +} + +impl domain_pallet_executive::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; +} + +impl pallet_sudo::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type WeightInfo = pallet_sudo::weights::SubstrateWeight; +} + +parameter_types! { + pub const StateRootsBound: u32 = 50; + pub const RelayConfirmationDepth: BlockNumber = 1; +} + +parameter_types! { + pub const MaximumRelayers: u32 = 100; + pub const RelayerDeposit: Balance = 100 * SSC; + // TODO: Proper value + pub const CoreDomainId: DomainId = DomainId::new(3u32); +} + +impl pallet_messenger::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SelfDomainId = CoreDomainId; + + fn get_endpoint_response_handler( + endpoint: &Endpoint, + ) -> Option>> { + if endpoint == &Endpoint::Id(TransporterEndpointId::get()) { + Some(Box::new(EndpointHandler(PhantomData::))) + } else { + None + } + } + + type Currency = Balances; + type MaximumRelayers = MaximumRelayers; + type RelayerDeposit = RelayerDeposit; + type DomainInfo = (); + type ConfirmationDepth = RelayConfirmationDepth; + type WeightInfo = pallet_messenger::weights::SubstrateWeight; +} + +impl frame_system::offchain::SendTransactionTypes for Runtime +where + RuntimeCall: From, +{ + type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = RuntimeCall; +} + +parameter_types! { + pub const TransporterEndpointId: EndpointId = 1; +} + +pub struct AccountId20Converter; + +impl Convert for AccountId20Converter { + fn convert(account_id: AccountId) -> MultiAccountId { + MultiAccountId::AccountId20(account_id.into()) + } +} + +impl TryConvertBack for AccountId20Converter { + fn try_convert_back(multi_account_id: MultiAccountId) -> Option { + match multi_account_id { + MultiAccountId::AccountId20(acc) => Some(AccountId::from(acc)), + _ => None, + } + } +} + +impl pallet_transporter::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SelfDomainId = CoreDomainId; + type SelfEndpointId = TransporterEndpointId; + type Currency = Balances; + type Sender = Messenger; + type AccountIdConverter = AccountId20Converter; + type WeightInfo = pallet_transporter::weights::SubstrateWeight; +} + +impl pallet_evm_chain_id::Config for Runtime {} + +pub struct FindAuthorTruncated; + +impl FindAuthor for FindAuthorTruncated { + fn find_author<'a, I>(_digests: I) -> Option + where + I: 'a + IntoIterator, + { + // TODO: returns the executor reward address once we start collecting them + None + } +} + +/// Current approximation of the gas/s consumption considering +/// EVM execution over compiled WASM (on 4.4Ghz CPU). +/// Given the 500ms Weight, from which 75% only are used for transactions, +/// the total EVM execution gas limit is: GAS_PER_SECOND * 0.500 * 0.75 ~= 15_000_000. +pub const GAS_PER_SECOND: u64 = 40_000_000; + +/// Approximate ratio of the amount of Weight per Gas. +/// u64 works for approximations because Weight is a very small unit compared to gas. +pub const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND.saturating_div(GAS_PER_SECOND); + +parameter_types! { + /// EVM gas limit + pub BlockGasLimit: U256 = U256::from( + NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS + ); + pub PrecompilesValue: Precompiles = Precompiles::default(); + pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0); +} + +impl pallet_evm::Config for Runtime { + type FeeCalculator = BaseFee; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = IdentityAddressMapping; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type PrecompilesType = Precompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = EVMChainId; + type BlockGasLimit = BlockGasLimit; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = (); + type OnCreate = (); + type FindAuthor = FindAuthorTruncated; + type Timestamp = Timestamp; + type WeightInfo = pallet_evm::weights::SubstrateWeight; +} + +parameter_types! { + pub const PostOnlyBlockHash: PostLogContent = PostLogContent::OnlyBlockHash; +} + +impl pallet_ethereum::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type StateRoot = pallet_ethereum::IntermediateStateRoot; + type PostLogContent = PostOnlyBlockHash; + type ExtraDataLength = ConstU32<30>; +} + +parameter_types! { + pub BoundDivision: U256 = U256::from(1024); +} + +parameter_types! { + pub DefaultBaseFeePerGas: U256 = U256::from(1_000_000_000); + // mark it to 5% increments on beyond target weight. + pub DefaultElasticity: Permill = Permill::from_parts(50_000); +} + +pub struct BaseFeeThreshold; + +impl pallet_base_fee::BaseFeeThreshold for BaseFeeThreshold { + fn lower() -> Permill { + Permill::zero() + } + fn ideal() -> Permill { + Permill::from_parts(500_000) + } + fn upper() -> Permill { + Permill::from_parts(1_000_000) + } +} + +impl pallet_base_fee::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Threshold = BaseFeeThreshold; + type DefaultBaseFeePerGas = DefaultBaseFeePerGas; + type DefaultElasticity = DefaultElasticity; +} + +impl pallet_domain_id::Config for Runtime {} + +// Create the runtime by composing the FRAME pallets that were previously configured. +// +// NOTE: Currently domain runtime does not naturally support the pallets with inherent extrinsics. +construct_runtime!( + pub struct Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + // System support stuff. + System: frame_system = 0, + Timestamp: pallet_timestamp = 1, + ExecutivePallet: domain_pallet_executive = 2, + + // monetary stuff + Balances: pallet_balances = 20, + TransactionPayment: pallet_transaction_payment = 21, + + // messenger stuff + // Note: Indexes should match the indexes of the System domain runtime + Messenger: pallet_messenger = 60, + Transporter: pallet_transporter = 61, + + // evm stuff + Ethereum: pallet_ethereum = 80, + EVM: pallet_evm = 81, + EVMChainId: pallet_evm_chain_id = 82, + BaseFee: pallet_base_fee = 83, + + // domain instance stuff + SelfDomainId: pallet_domain_id = 90, + + // Sudo account + Sudo: pallet_sudo = 100, + } +); + +#[derive(Clone, Default)] +pub struct TransactionConverter; + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } +} + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction( + &self, + transaction: pallet_ethereum::Transaction, + ) -> opaque::UncheckedExtrinsic { + let extrinsic = UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ); + let encoded = extrinsic.encode(); + opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) + .expect("Encoded extrinsic is always valid") + } +} + +fn extract_xdm_proof_state_roots( + encoded_ext: Vec, +) -> Option> { + if let Ok(ext) = UncheckedExtrinsic::decode(&mut encoded_ext.as_slice()) { + match &ext.0.function { + RuntimeCall::Messenger(pallet_messenger::Call::relay_message { msg }) => { + msg.extract_state_roots_from_proof::() + } + RuntimeCall::Messenger(pallet_messenger::Call::relay_message_response { msg }) => { + msg.extract_state_roots_from_proof::() + } + _ => None, + } + } else { + None + } +} + +fn extract_signer_inner( + ext: &UncheckedExtrinsic, + lookup: &Lookup, +) -> Option +where + Lookup: sp_runtime::traits::Lookup, +{ + if ext.0.function.is_self_contained() { + ext.0 + .function + .check_self_contained() + .and_then(|signed_info| signed_info.ok()) + .map(|account| account.encode()) + } else { + ext.0 + .signature + .as_ref() + .and_then(|(signed, _, _)| lookup.lookup(*signed).ok().map(|account| account.encode())) + } +} + +pub fn extract_signer( + extrinsics: Vec, +) -> Vec<(Option, UncheckedExtrinsic)> { + let lookup = frame_system::ChainContext::::default(); + + extrinsics + .into_iter() + .map(|extrinsic| { + let maybe_signer = extract_signer_inner(&extrinsic, &lookup); + (maybe_signer, extrinsic) + }) + .collect() +} + +impl_runtime_apis! { + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Index { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { + fn query_info( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl domain_runtime_primitives::DomainCoreApi for Runtime { + fn extract_signer( + extrinsics: Vec<::Extrinsic>, + ) -> Vec<(Option, ::Extrinsic)> { + extract_signer(extrinsics) + } + + fn is_within_tx_range( + extrinsic: &::Extrinsic, + bundle_vrf_hash: &subspace_core_primitives::U256, + tx_range: &subspace_core_primitives::U256 + ) -> bool { + use subspace_core_primitives::U256; + use subspace_core_primitives::crypto::blake2b_256_hash; + + let lookup = frame_system::ChainContext::::default(); + if let Some(signer) = extract_signer_inner(extrinsic, &lookup) { + let signer_id_hash = U256::from_be_bytes(blake2b_256_hash(&signer.encode())); + sp_domains::signer_in_tx_range(bundle_vrf_hash, &signer_id_hash, tx_range) + } else { + true + } + } + + fn intermediate_roots() -> Vec<[u8; 32]> { + ExecutivePallet::intermediate_roots() + } + + fn initialize_block_with_post_state_root(header: &::Header) -> Vec { + Executive::initialize_block(header); + Executive::storage_root() + } + + fn apply_extrinsic_with_post_state_root(extrinsic: ::Extrinsic) -> Vec { + let _ = Executive::apply_extrinsic(extrinsic); + Executive::storage_root() + } + + fn construct_set_code_extrinsic(code: Vec) -> Vec { + use codec::Encode; + // Use `set_code_without_checks` instead of `set_code` in the test environment. + let set_code_call = frame_system::Call::set_code_without_checks { code }; + UncheckedExtrinsic::new_unsigned( + domain_pallet_executive::Call::sudo_unchecked_weight_unsigned { + call: Box::new(set_code_call.into()), + weight: Weight::from_parts(0, 0), + }.into() + ).encode() + } + + fn check_transaction_validity( + _uxt: &::Extrinsic, + _block_hash: ::Hash, + ) -> Result<(), domain_runtime_primitives::CheckTxValidityError> { + // TODO: check transaction fee to core-evm + Ok(()) + } + + fn storage_keys_for_verifying_transaction_validity( + who: opaque::AccountId, + ) -> Result>, domain_runtime_primitives::VerifyTxValidityError> { + let sender = AccountId::decode(&mut who.as_slice()) + .map_err(|_| domain_runtime_primitives::VerifyTxValidityError::FailedToDecodeAccountId)?; + Ok(sp_std::vec![ + frame_system::Account::::hashed_key_for(sender), + pallet_transaction_payment::NextFeeMultiplier::::hashed_key().to_vec(), + ]) + } + + fn extrinsic_weight(ext: &::Extrinsic) -> Weight { + ext.get_dispatch_info().weight + } + } + + impl domain_runtime_primitives::InherentExtrinsicApi for Runtime { + fn construct_inherent_timestamp_extrinsic(moment: Moment) -> Option<::Extrinsic> { + Some( + UncheckedExtrinsic::new_unsigned( + pallet_timestamp::Call::set{ now: moment }.into() + ) + ) + } + } + + impl sp_messenger::MessengerApi for Runtime { + fn extract_xdm_proof_state_roots( + extrinsic: Vec, + ) -> Option::Hash, ::Hash>> { + extract_xdm_proof_state_roots(extrinsic) + } + + fn confirmation_depth() -> BlockNumber { + RelayConfirmationDepth::get() + } + } + + impl sp_messenger::RelayerApi for Runtime { + fn domain_id() -> DomainId { + CoreDomainId::get() + } + + fn relay_confirmation_depth() -> BlockNumber { + RelayConfirmationDepth::get() + } + + fn domain_best_number(_domain_id: DomainId) -> Option { + None + } + + fn domain_state_root(_domain_id: DomainId, _number: BlockNumber, _hash: Hash) -> Option{ + None + } + + fn relayer_assigned_messages(relayer_id: AccountId) -> RelayerMessagesWithStorageKey { + Messenger::relayer_assigned_messages(relayer_id) + } + + fn outbox_message_unsigned(msg: CrossDomainMessage::Hash, ::Hash>) -> Option<::Extrinsic> { + Messenger::outbox_message_unsigned(msg) + } + + fn inbox_response_message_unsigned(msg: CrossDomainMessage::Hash, ::Hash>) -> Option<::Extrinsic> { + Messenger::inbox_response_message_unsigned(msg) + } + + fn should_relay_outbox_message(dst_domain_id: DomainId, msg_id: MessageId) -> bool { + Messenger::should_relay_outbox_message(dst_domain_id, msg_id) + } + + fn should_relay_inbox_message_response(dst_domain_id: DomainId, msg_id: MessageId) -> bool { + Messenger::should_relay_inbox_message_response(dst_domain_id, msg_id) + } + } + + impl fp_rpc::EthereumRuntimeRPCApi for Runtime { + fn chain_id() -> u64 { + ::ChainId::get() + } + + fn account_basic(address: H160) -> EVMAccount { + let (account, _) = EVM::account_basic(&address); + account + } + + fn gas_price() -> U256 { + let (gas_price, _) = ::FeeCalculator::min_gas_price(); + gas_price + } + + fn account_code_at(address: H160) -> Vec { + pallet_evm::AccountCodes::::get(address) + } + + fn author() -> H160 { + >::find_author() + } + + fn storage_at(address: H160, index: U256) -> H256 { + let mut tmp = [0u8; 32]; + index.to_big_endian(&mut tmp); + pallet_evm::AccountStorages::::get(address, H256::from_slice(&tmp[..])) + } + + fn call( + from: H160, + to: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + let is_transactional = false; + let validate = true; + let evm_config = config.as_ref().unwrap_or(::config()); + ::Runner::call( + from, + to, + data, + value, + gas_limit.unique_saturated_into(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + is_transactional, + validate, + evm_config, + ).map_err(|err| err.error.into()) + } + + fn create( + from: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + let is_transactional = false; + let validate = true; + let evm_config = config.as_ref().unwrap_or(::config()); + ::Runner::create( + from, + data, + value, + gas_limit.unique_saturated_into(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + is_transactional, + validate, + evm_config, + ).map_err(|err| err.error.into()) + } + + fn current_transaction_statuses() -> Option> { + pallet_ethereum::CurrentTransactionStatuses::::get() + } + + fn current_block() -> Option { + pallet_ethereum::CurrentBlock::::get() + } + + fn current_receipts() -> Option> { + pallet_ethereum::CurrentReceipts::::get() + } + + fn current_all() -> ( + Option, + Option>, + Option> + ) { + ( + pallet_ethereum::CurrentBlock::::get(), + pallet_ethereum::CurrentReceipts::::get(), + pallet_ethereum::CurrentTransactionStatuses::::get() + ) + } + + fn extrinsic_filter( + xts: Vec<::Extrinsic>, + ) -> Vec { + xts.into_iter().filter_map(|xt| match xt.0.function { + RuntimeCall::Ethereum(transact { transaction }) => Some(transaction), + _ => None + }).collect::>() + } + + fn elasticity() -> Option { + Some(pallet_base_fee::Elasticity::::get()) + } + + fn gas_limit_multiplier_support() {} + } + + impl fp_rpc::ConvertTransactionRuntimeApi for Runtime { + fn convert_transaction(transaction: EthereumTransaction) -> ::Extrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{Benchmarking, BenchmarkList, list_benchmark}; + use frame_support::traits::StorageInfoTrait; + use frame_system_benchmarking::Pallet as SystemBench; + + let mut list = Vec::::new(); + + list_benchmark!(list, extra, frame_system, SystemBench::); + + let storage_info = AllPalletsWithSystem::storage_info(); + + (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{Benchmarking, BenchmarkBatch, TrackedStorageKey, add_benchmark}; + + use frame_system_benchmarking::Pallet as SystemBench; + impl frame_system_benchmarking::Config for Runtime {} + + let whitelist: Vec = vec![ + // Block Number + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), + // Total Issuance + hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(), + // Execution Phase + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(), + // RuntimeEvent Count + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), + // System Events + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), + ]; + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + + add_benchmark!(params, batches, frame_system, SystemBench::); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) + } + } + + impl domain_test_primitives::TimestampApi for Runtime { + fn timestamp() -> Moment { + Timestamp::now() + } + } + + impl domain_test_primitives::OnchainStateApi for Runtime { + fn free_balance(account_id: AccountId) -> Balance { + Balances::free_balance(account_id) + } + + fn get_open_channel_for_domain(dst_domain_id: DomainId) -> Option { + Messenger::get_open_channel_for_domain(dst_domain_id).map(|(c, _)| c) + } + } +} diff --git a/domains/test/runtime/evm/src/precompiles.rs b/domains/test/runtime/evm/src/precompiles.rs new file mode 100644 index 00000000000..a1e11d859f7 --- /dev/null +++ b/domains/test/runtime/evm/src/precompiles.rs @@ -0,0 +1,66 @@ +use pallet_evm::{ + IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet, +}; +use sp_core::H160; +use sp_std::marker::PhantomData; + +use pallet_evm_precompile_modexp::Modexp; +use pallet_evm_precompile_sha3fips::Sha3FIPS256; +use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; + +pub struct Precompiles(PhantomData); + +impl Precompiles +where + R: pallet_evm::Config, +{ + pub fn used_addresses() -> [H160; 7] { + [ + hash(1), + hash(2), + hash(3), + hash(4), + hash(5), + hash(1024), + hash(1025), + ] + } +} + +impl Default for Precompiles { + #[inline] + fn default() -> Self { + Self(PhantomData) + } +} + +impl PrecompileSet for Precompiles +where + R: pallet_evm::Config, +{ + fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { + match handle.code_address() { + // Ethereum precompiles : + a if a == hash(1) => Some(ECRecover::execute(handle)), + a if a == hash(2) => Some(Sha256::execute(handle)), + a if a == hash(3) => Some(Ripemd160::execute(handle)), + a if a == hash(4) => Some(Identity::execute(handle)), + a if a == hash(5) => Some(Modexp::execute(handle)), + // Non-Frontier specific nor Ethereum precompiles : + a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), + a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), + _ => None, + } + } + + fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { + IsPrecompileResult::Answer { + is_precompile: Self::used_addresses().contains(&address), + extra_cost: 0, + } + } +} + +fn hash(a: u64) -> H160 { + H160::from_low_u64_be(a) +} diff --git a/domains/test/runtime/system/Cargo.toml b/domains/test/runtime/system/Cargo.toml deleted file mode 100644 index f9fa0b46609..00000000000 --- a/domains/test/runtime/system/Cargo.toml +++ /dev/null @@ -1,99 +0,0 @@ -[package] -name = "system-domain-test-runtime" -version = "0.1.0" -authors = ["Anonymous"] -description = "A new Cumulus FRAME-based Substrate Runtime, ready for hacking together a parachain." -license = "Unlicense" -homepage = "https://substrate.io" -repository = "https://github.com/paritytech/cumulus/" -edition = "2021" -links = "system-domain-test-runtime" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[build-dependencies] -sp-domains = { version = "0.1.0", path = "../../../../crates/sp-domains" } -subspace-wasm-tools = { version = "0.1.0", path = "../../../../crates/subspace-wasm-tools" } -substrate-wasm-builder = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"]} -domain-pallet-executive = { version = "0.1.0", path = "../../../pallets/executive", default-features = false } -domain-runtime-primitives = { version = "0.1.0", path = "../../../primitives/runtime", default-features = false } -domain-test-primitives = { version = "0.1.0", path = "../../primitives", default-features = false } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -hex-literal = { version = '0.4.0', optional = true } -log = { version = "0.4.19", default-features = false } -pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-domain-registry = { version = "0.1.0", path = "../../../pallets/domain-registry", default-features = false } -pallet-executor-registry = { version = "0.1.0", path = "../../../pallets/executor-registry", default-features = false } -pallet-messenger = { version = "0.1.0", path = "../../../pallets/messenger", default-features = false } -pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-settlement = { version = "0.1.0", path = "../../../../crates/pallet-settlement", default-features = false } -pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transporter = { version = "0.1.0", path = "../../../pallets/transporter", default-features = false } -scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-domains = { version = "0.1.0", path = "../../../../crates/sp-domains", default-features = false } -sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-io = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-messenger = { version = "0.1.0", path = "../../../primitives/messenger", default-features = false } -sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", path = "../../../../crates/sp-settlement", default-features = false } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -system-runtime-primitives = { version = "0.1.0", path = "../../../primitives/system-runtime", default-features = false } -subspace-runtime-primitives = { version = "0.1.0", path = "../../../../crates/subspace-runtime-primitives", default-features = false } - -[features] -default = [ - "std", -] -std = [ - "codec/std", - "domain-pallet-executive/std", - "domain-runtime-primitives/std", - "domain-test-primitives/std", - "frame-support/std", - "frame-system/std", - "frame-system-rpc-runtime-api/std", - "log/std", - "pallet-balances/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transaction-payment/std", - "pallet-domain-registry/std", - "pallet-settlement/std", - "pallet-messenger/std", - "pallet-executor-registry/std", - "scale-info/std", - "sp-api/std", - "sp-block-builder/std", - "sp-core/std", - "sp-domains/std", - "sp-inherents/std", - "sp-io/std", - "sp-messenger/std", - "sp-offchain/std", - "sp-runtime/std", - "sp-session/std", - "sp-settlement/std", - "sp-std/std", - "sp-transaction-pool/std", - "sp-version/std", - "system-runtime-primitives/std", - "subspace-runtime-primitives/std", - "substrate-wasm-builder", -] -# Internal implementation detail, enabled during building of wasm blob. -wasm-builder = [] diff --git a/domains/test/runtime/system/build.rs b/domains/test/runtime/system/build.rs deleted file mode 100644 index a9033702fe0..00000000000 --- a/domains/test/runtime/system/build.rs +++ /dev/null @@ -1,13 +0,0 @@ -fn main() { - #[cfg(feature = "std")] - { - substrate_wasm_builder::WasmBuilder::new() - .with_current_project() - .enable_feature("wasm-builder") - .export_heap_base() - .import_memory() - .build(); - } - - subspace_wasm_tools::export_wasm_bundle_path(); -} diff --git a/domains/test/runtime/system/src/lib.rs b/domains/test/runtime/system/src/lib.rs deleted file mode 100644 index 3578523b6ae..00000000000 --- a/domains/test/runtime/system/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit = "256"] - -// Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported -// functions -#[cfg(any(feature = "wasm-builder", feature = "std"))] -mod runtime; - -// Skip in regular `no-std` environment, such that we don't cause conflicts of globally exported -// functions -#[cfg(any(feature = "wasm-builder", feature = "std"))] -pub use runtime::*; - -// Make the WASM binary available. -#[cfg(feature = "std")] -include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); diff --git a/domains/test/runtime/system/src/runtime.rs b/domains/test/runtime/system/src/runtime.rs deleted file mode 100644 index bc03685e81a..00000000000 --- a/domains/test/runtime/system/src/runtime.rs +++ /dev/null @@ -1,839 +0,0 @@ -use codec::{Decode, Encode}; -pub use domain_runtime_primitives::{ - AccountId, AccountIdConverter, Address, Balance, BlockNumber, Hash, Index, Signature, -}; -use frame_support::dispatch::DispatchClass; -use frame_support::traits::{ConstU16, ConstU32, Everything}; -use frame_support::weights::constants::{ - BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND, -}; -use frame_support::weights::{ConstantMultiplier, IdentityFee, Weight}; -use frame_support::{construct_runtime, parameter_types}; -use frame_system::limits::{BlockLength, BlockWeights}; -use pallet_transporter::EndpointHandler; -use sp_api::impl_runtime_apis; -use sp_core::crypto::KeyTypeId; -use sp_core::{OpaqueMetadata, H256}; -use sp_domains::bundle_election::BundleElectionSolverParams; -use sp_domains::fraud_proof::FraudProof; -use sp_domains::transaction::PreValidationObject; -use sp_domains::{DomainId, ExecutionReceipt, ExecutorPublicKey, OpaqueBundle}; -use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId}; -use sp_messenger::messages::{ - ChannelId, CrossDomainMessage, ExtractedStateRootsFromProof, MessageId, - RelayerMessagesWithStorageKey, -}; -use sp_runtime::traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, NumberFor, StaticLookup}; -use sp_runtime::transaction_validity::{TransactionSource, TransactionValidity}; -use sp_runtime::{create_runtime_str, generic, impl_opaque_keys, ApplyExtrinsicResult}; -pub use sp_runtime::{MultiAddress, Perbill, Permill}; -use sp_std::marker::PhantomData; -use sp_std::prelude::*; -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use sp_version::RuntimeVersion; -use subspace_runtime_primitives::{SHANNON, SSC}; - -#[cfg(any(feature = "std", test))] -pub use sp_runtime::BuildStorage; - -/// Block header type as expected by this runtime. -pub type Header = generic::Header; - -/// Block type as expected by this runtime. -pub type Block = generic::Block; - -/// A Block signed with a Justification -pub type SignedBlock = generic::SignedBlock; - -/// BlockId type as expected by this runtime. -pub type BlockId = generic::BlockId; - -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( - frame_system::CheckNonZeroSender, - frame_system::CheckSpecVersion, - frame_system::CheckTxVersion, - frame_system::CheckGenesis, - frame_system::CheckMortality, - frame_system::CheckNonce, - frame_system::CheckWeight, - pallet_transaction_payment::ChargeTransactionPayment, -); - -/// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; - -/// Extrinsic type that has already been checked. -pub type CheckedExtrinsic = generic::CheckedExtrinsic; - -/// Executive: handles dispatch to the various modules. -pub type Executive = domain_pallet_executive::Executive< - Runtime, - Block, - frame_system::ChainContext, - Runtime, - AllPalletsWithSystem, - Runtime, ->; - -/// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; - -/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know -/// the specifics of the runtime. They can then be made to be agnostic over specific formats -/// of data like extrinsics, allowing for them to continue syncing the network through upgrades -/// to even the core data structures. -pub mod opaque { - use super::*; - use sp_runtime::generic; - use sp_runtime::traits::BlakeTwo256; - - pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; - - /// Opaque block header type. - pub type Header = generic::Header; - /// Opaque block type. - pub type Block = generic::Block; - /// Opaque block identifier type. - pub type BlockId = generic::BlockId; - /// Opaque Account ID identifier type. - pub type AccountId = Vec; -} - -impl_opaque_keys! { - pub struct SessionKeys { - /// Primarily used for adding the executor authority key into the keystore in the dev mode. - pub executor: sp_domains::ExecutorKey, - } -} - -#[sp_version::runtime_version] -pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("subspace-executor"), - impl_name: create_runtime_str!("subspace-executor"), - authoring_version: 0, - spec_version: 0, - impl_version: 0, - apis: RUNTIME_API_VERSIONS, - transaction_version: 0, - state_version: 0, -}; - -/// The existential deposit. Same with the one on primary chain. -pub const EXISTENTIAL_DEPOSIT: Balance = 500 * SHANNON; - -/// We assume that ~5% of the block weight is consumed by `on_initialize` handlers. This is -/// used to limit the maximal weight of a single extrinsic. -const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5); - -/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used by -/// `Operational` extrinsics. -const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); - -/// We allow for 0.5 of a second of compute with a 12 second average block time. -const MAXIMUM_BLOCK_WEIGHT: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(2), u64::MAX); - -/// The version information used to identify this runtime when compiled natively. -#[cfg(feature = "std")] -pub fn native_version() -> NativeVersion { - NativeVersion { - runtime_version: VERSION, - can_author_with: Default::default(), - } -} - -parameter_types! { - pub const Version: RuntimeVersion = VERSION; - pub const BlockHashCount: BlockNumber = 2400; - - // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`. - // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the - // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize - // the lazy contract deletion. - pub RuntimeBlockLength: BlockLength = - BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); - pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() - .base_block(BlockExecutionWeight::get()) - .for_class(DispatchClass::all(), |weights| { - weights.base_extrinsic = ExtrinsicBaseWeight::get(); - }) - .for_class(DispatchClass::Normal, |weights| { - weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); - }) - .for_class(DispatchClass::Operational, |weights| { - weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); - // Operational transactions have some extra reserved space, so that they - // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. - weights.reserved = Some( - MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT - ); - }) - .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) - .build_or_panic(); -} - -// Configure FRAME pallets to include in runtime. - -impl frame_system::Config for Runtime { - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The aggregated dispatch type that is available for extrinsics. - type RuntimeCall = RuntimeCall; - /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = AccountIdLookup; - /// The index type for storing how many extrinsics an account has signed. - type Index = Index; - /// The index type for blocks. - type BlockNumber = BlockNumber; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The hashing algorithm used. - type Hashing = BlakeTwo256; - /// The header type. - type Header = generic::Header; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - /// The ubiquitous origin type. - type RuntimeOrigin = RuntimeOrigin; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// Runtime version. - type Version = Version; - /// Converts a module to an index of this module in the runtime. - type PalletInfo = PalletInfo; - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// What to do if a new account is created. - type OnNewAccount = (); - /// What to do if an account is fully reaped from the system. - type OnKilledAccount = (); - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// The basic call filter to use in dispatchable. - type BaseCallFilter = Everything; - /// Weight information for the extrinsics of this pallet. - type SystemWeightInfo = (); - /// Block & extrinsics weights: base values and limits. - type BlockWeights = RuntimeBlockWeights; - /// The maximum length of a block (in bytes). - type BlockLength = RuntimeBlockLength; - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. - type SS58Prefix = ConstU16<42>; - /// The action to take on a Runtime Upgrade - type OnSetCode = (); - type MaxConsumers = ConstU32<16>; -} - -parameter_types! { - pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; - pub const MaxLocks: u32 = 50; - pub const MaxReserves: u32 = 50; -} - -impl pallet_balances::Config for Runtime { - type MaxLocks = MaxLocks; - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; - type MaxReserves = MaxReserves; - type ReserveIdentifier = [u8; 8]; - type FreezeIdentifier = (); - type MaxFreezes = (); - type RuntimeHoldReason = (); - type MaxHolds = (); -} - -parameter_types! { - pub const TransactionByteFee: Balance = 1; - pub const OperationalFeeMultiplier: u8 = 5; -} - -impl pallet_transaction_payment::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; - type WeightToFee = IdentityFee; - type LengthToFee = ConstantMultiplier; - type FeeMultiplierUpdate = (); - type OperationalFeeMultiplier = OperationalFeeMultiplier; -} - -impl domain_pallet_executive::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; -} - -parameter_types! { - pub const MinExecutorStake: Balance = SSC; - pub const MaxExecutorStake: Balance = 1_000_000 * SSC; - pub const MinExecutors: u32 = 1; - pub const MaxExecutors: u32 = 10; - pub const EpochDuration: BlockNumber = 3; - pub const MaxWithdrawals: u32 = 1; - pub const WithdrawalDuration: BlockNumber = 10; -} - -impl pallet_executor_registry::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type StakeWeight = sp_domains::StakeWeight; - type MinExecutorStake = MinExecutorStake; - type MaxExecutorStake = MaxExecutorStake; - type MinExecutors = MinExecutors; - type MaxExecutors = MaxExecutors; - type MaxWithdrawals = MaxWithdrawals; - type WithdrawalDuration = WithdrawalDuration; - type EpochDuration = EpochDuration; - type OnNewEpoch = DomainRegistry; - type WeightInfo = pallet_executor_registry::weights::SubstrateWeight; -} - -parameter_types! { - pub const MinDomainDeposit: Balance = 10 * SSC; - pub const MaxDomainDeposit: Balance = 1000 * SSC; - pub const MinDomainOperatorStake: Balance = SSC; - pub const MaximumReceiptDrift: BlockNumber = 128; - pub const ReceiptsPruningDepth: BlockNumber = 256; -} - -impl pallet_domain_registry::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type StakeWeight = sp_domains::StakeWeight; - type ExecutorRegistry = ExecutorRegistry; - type MinDomainDeposit = MinDomainDeposit; - type MaxDomainDeposit = MaxDomainDeposit; - type MinDomainOperatorStake = MinDomainOperatorStake; - type WeightInfo = pallet_domain_registry::weights::SubstrateWeight; -} - -impl pallet_settlement::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type DomainHash = domain_runtime_primitives::Hash; - type MaximumReceiptDrift = MaximumReceiptDrift; - type ReceiptsPruningDepth = ReceiptsPruningDepth; -} - -parameter_types! { - pub const StateRootsBound: u32 = 50; - pub const RelayConfirmationDepth: BlockNumber = 1; -} - -parameter_types! { - pub const MaximumRelayers: u32 = 100; - pub const RelayerDeposit: Balance = 100 * SSC; - pub const SystemDomainId: DomainId = DomainId::SYSTEM; -} - -parameter_types! { - pub const TransporterEndpointId: EndpointId = 1; -} - -impl pallet_transporter::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type SelfDomainId = SystemDomainId; - type SelfEndpointId = TransporterEndpointId; - type Currency = Balances; - type Sender = Messenger; - type AccountIdConverter = AccountIdConverter; - type WeightInfo = pallet_transporter::weights::SubstrateWeight; -} - -pub struct DomainInfo; - -impl sp_messenger::endpoint::DomainInfo for DomainInfo { - fn domain_best_number(domain_id: DomainId) -> Option { - Some(Settlement::head_receipt_number(domain_id)) - } - - fn domain_state_root(domain_id: DomainId, number: BlockNumber, hash: Hash) -> Option { - Settlement::domain_state_root_at(domain_id, number, hash) - } -} - -impl pallet_messenger::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type SelfDomainId = SystemDomainId; - - fn get_endpoint_response_handler( - endpoint: &Endpoint, - ) -> Option>> { - // Return a dummy handler for benchmark to observe the outer weight when processing cross domain - // message (i.e. updating the `next_nonce` of the channel, assigning msg to the relayer, etc.) - #[cfg(feature = "runtime-benchmarks")] - { - return Some(Box::new(sp_messenger::endpoint::BenchmarkEndpointHandler)); - } - if endpoint == &Endpoint::Id(TransporterEndpointId::get()) { - Some(Box::new(EndpointHandler(PhantomData::))) - } else { - None - } - } - - type Currency = Balances; - type MaximumRelayers = MaximumRelayers; - type RelayerDeposit = RelayerDeposit; - type DomainInfo = DomainInfo; - type ConfirmationDepth = RelayConfirmationDepth; - type WeightInfo = pallet_messenger::weights::SubstrateWeight; -} - -impl frame_system::offchain::SendTransactionTypes for Runtime -where - RuntimeCall: From, -{ - type Extrinsic = UncheckedExtrinsic; - type OverarchingCall = RuntimeCall; -} - -impl pallet_sudo::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - type WeightInfo = pallet_sudo::weights::SubstrateWeight; -} - -// Create the runtime by composing the FRAME pallets that were previously configured. -construct_runtime!( - pub struct Runtime - where - Block = Block, - NodeBlock = opaque::Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - // System support stuff. - System: frame_system, - ExecutivePallet: domain_pallet_executive, - - // Monetary stuff. - Balances: pallet_balances, - TransactionPayment: pallet_transaction_payment, - - // System domain. - // - // Must be after Balances pallet so that its genesis is built after the Balances genesis is - // built. - ExecutorRegistry: pallet_executor_registry, - Settlement: pallet_settlement, - DomainRegistry: pallet_domain_registry, - - // messenger stuff - Messenger: pallet_messenger = 60, - Transporter: pallet_transporter = 61, - - // Sudo account - Sudo: pallet_sudo = 100, - } -); - -impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block) - } - - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - - fn metadata_at_version(version: u32) -> Option { - Runtime::metadata_at_version(version) - } - - fn metadata_versions() -> sp_std::vec::Vec { - Runtime::metadata_versions() - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Index { - System::account_nonce(account) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl domain_runtime_primitives::DomainCoreApi for Runtime { - fn extract_signer( - extrinsics: Vec<::Extrinsic>, - ) -> Vec<(Option, ::Extrinsic)> { - use domain_runtime_primitives::Signer; - let lookup = frame_system::ChainContext::::default(); - extrinsics.into_iter().map(|xt| (xt.signer(&lookup).map(|signer| signer.encode()), xt)).collect() - } - - fn intermediate_roots() -> Vec<[u8; 32]> { - ExecutivePallet::intermediate_roots() - } - - fn initialize_block_with_post_state_root(header: &::Header) -> Vec { - Executive::initialize_block(header); - Executive::storage_root() - } - - fn apply_extrinsic_with_post_state_root(extrinsic: ::Extrinsic) -> Vec { - let _ = Executive::apply_extrinsic(extrinsic); - Executive::storage_root() - } - - fn construct_set_code_extrinsic(code: Vec) -> Vec { - use codec::Encode; - // Use `set_code_without_checks` instead of `set_code` in the test environment. - let set_code_call = frame_system::Call::set_code_without_checks { code }; - UncheckedExtrinsic::new_unsigned( - domain_pallet_executive::Call::sudo_unchecked_weight_unsigned { - call: Box::new(set_code_call.into()), - weight: Weight::zero() - }.into() - ).encode() - } - - fn check_transaction_validity( - uxt: ::Extrinsic, - block_hash: ::Hash, - ) -> Result<(), domain_runtime_primitives::CheckTxValidityError> { - let maybe_address = uxt - .signature - .as_ref() - .map(|(address, _signature, _extra)| address.clone()); - - if let Some(address) = maybe_address { - let sender = ::Lookup::lookup(address)?; - - let tx_validity = - Executive::validate_transaction(TransactionSource::External, uxt, block_hash); - - tx_validity.map(|_| ()).map_err(|tx_validity_error| { - let storage_keys = sp_std::vec![ - frame_system::Account::::hashed_key_for(&sender), - pallet_transaction_payment::NextFeeMultiplier::::hashed_key().to_vec(), - ]; - domain_runtime_primitives::CheckTxValidityError::InvalidTransaction { - error: tx_validity_error, - storage_keys, - } - }) - } else { - Ok(()) - } - } - - fn storage_keys_for_verifying_transaction_validity( - who: opaque::AccountId, - ) -> Result>, domain_runtime_primitives::VerifyTxValidityError> { - let sender = AccountId::decode(&mut who.as_slice()) - .map_err(|_| domain_runtime_primitives::VerifyTxValidityError::FailedToDecodeAccountId)?; - Ok(sp_std::vec![ - frame_system::Account::::hashed_key_for(sender), - pallet_transaction_payment::NextFeeMultiplier::::hashed_key().to_vec(), - ]) - } - } - - impl sp_settlement::SettlementApi for Runtime { - fn execution_trace(domain_id: DomainId, receipt_hash: H256) -> Vec { - Settlement::receipts(domain_id, receipt_hash).map(|receipt| receipt.trace).unwrap_or_default() - } - - fn state_root( - domain_id: DomainId, - domain_block_number: BlockNumber, - domain_block_hash: Hash, - ) -> Option { - Settlement::state_root((domain_id, domain_block_number, domain_block_hash)) - } - - fn primary_hash(domain_id: DomainId, domain_block_number: BlockNumber) -> Option { - Settlement::primary_hash(domain_id, domain_block_number) - } - - fn receipts_pruning_depth() -> BlockNumber { - ReceiptsPruningDepth::get() - } - - fn head_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::head_receipt_number(domain_id) - } - - fn oldest_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::oldest_receipt_number(domain_id) - } - - fn maximum_receipt_drift() -> NumberFor { - MaximumReceiptDrift::get() - } - - fn extract_receipts( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec> { - let successful_bundles = DomainRegistry::successful_bundles(); - extrinsics - .into_iter() - .filter_map(|uxt| match uxt.function { - RuntimeCall::DomainRegistry(pallet_domain_registry::Call::submit_core_bundle { - opaque_bundle, - }) if opaque_bundle.domain_id() == domain_id - && successful_bundles.contains(&opaque_bundle.hash()) => - { - Some(opaque_bundle.receipt) - } - _ => None, - }) - .collect() - } - - fn extract_fraud_proofs( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, Hash>> { - let successful_fraud_proofs = Settlement::successful_fraud_proofs(); - extrinsics - .into_iter() - .filter_map(|uxt| match uxt.function { - RuntimeCall::DomainRegistry(pallet_domain_registry::Call::submit_fraud_proof { fraud_proof }) - if fraud_proof.domain_id() == domain_id - && successful_fraud_proofs.contains(&fraud_proof.hash()) => - { - Some(fraud_proof) - } - _ => None, - }) - .collect() - } - - fn submit_fraud_proof_unsigned(fraud_proof: FraudProof, Hash>) { - DomainRegistry::submit_fraud_proof_unsigned(fraud_proof) - } - } - - impl system_runtime_primitives::SystemDomainApi for Runtime { - fn construct_submit_core_bundle_extrinsics( - opaque_bundles: Vec::Hash>>, - ) -> Vec> { - use codec::Encode; - opaque_bundles - .into_iter() - .map(|opaque_bundle| { - UncheckedExtrinsic::new_unsigned( - pallet_domain_registry::Call::submit_core_bundle { - opaque_bundle - }.into() - ).encode() - }) - .collect() - } - - fn bundle_election_solver_params(domain_id: DomainId) -> BundleElectionSolverParams { - if domain_id.is_system() { - BundleElectionSolverParams { - authorities: ExecutorRegistry::authorities().into(), - total_stake_weight: ExecutorRegistry::total_stake_weight(), - slot_probability: ExecutorRegistry::slot_probability(), - } - } else { - match ( - DomainRegistry::domain_authorities(domain_id), - DomainRegistry::domain_total_stake_weight(domain_id), - DomainRegistry::domain_slot_probability(domain_id), - ) { - (authorities, Some(total_stake_weight), Some(slot_probability)) => { - BundleElectionSolverParams { - authorities, - total_stake_weight, - slot_probability, - } - } - _ => BundleElectionSolverParams::empty(), - } - } - } - - fn core_bundle_election_storage_keys( - domain_id: DomainId, - executor_public_key: ExecutorPublicKey, - ) -> Option>> { - let executor = ExecutorRegistry::key_owner(&executor_public_key)?; - let mut storage_keys = DomainRegistry::core_bundle_election_storage_keys(domain_id, executor); - storage_keys.push(ExecutorRegistry::key_owner_hashed_key_for(&executor_public_key)); - Some(storage_keys) - } - - } - - impl sp_messenger::RelayerApi for Runtime { - fn domain_id() -> DomainId { - SystemDomainId::get() - } - - fn relay_confirmation_depth() -> BlockNumber { - RelayConfirmationDepth::get() - } - - fn domain_best_number(domain_id: DomainId) -> Option { - Some(Settlement::head_receipt_number(domain_id)) - } - - fn domain_state_root(domain_id: DomainId, number: BlockNumber, hash: Hash) -> Option{ - Settlement::domain_state_root_at(domain_id, number, hash) - } - - fn relayer_assigned_messages(relayer_id: AccountId) -> RelayerMessagesWithStorageKey { - Messenger::relayer_assigned_messages(relayer_id) - } - - fn outbox_message_unsigned(msg: CrossDomainMessage::Hash, ::Hash>) -> Option<::Extrinsic> { - Messenger::outbox_message_unsigned(msg) - } - - fn inbox_response_message_unsigned(msg: CrossDomainMessage::Hash, ::Hash>) -> Option<::Extrinsic> { - Messenger::inbox_response_message_unsigned(msg) - } - - fn should_relay_outbox_message(dst_domain_id: DomainId, msg_id: MessageId) -> bool { - Messenger::should_relay_outbox_message(dst_domain_id, msg_id) - } - - fn should_relay_inbox_message_response(dst_domain_id: DomainId, msg_id: MessageId) -> bool { - Messenger::should_relay_inbox_message_response(dst_domain_id, msg_id) - } - } - - impl sp_messenger::MessengerApi for Runtime { - fn extract_xdm_proof_state_roots( - extrinsic: Vec, - ) -> Option::Hash, ::Hash>> { - extract_xdm_proof_state_roots(extrinsic) - } - - fn confirmation_depth() -> BlockNumber { - RelayConfirmationDepth::get() - } - } - - impl sp_domains::transaction::PreValidationObjectApi for Runtime { - fn extract_pre_validation_object( - extrinsic: ::Extrinsic, - ) -> PreValidationObject { - match extrinsic.function { - RuntimeCall::DomainRegistry(pallet_domain_registry::Call::submit_fraud_proof { fraud_proof }) => { - PreValidationObject::FraudProof(fraud_proof) - } - _ => PreValidationObject::Null, - } - } - } - - impl domain_test_primitives::OnchainStateApi for Runtime { - fn free_balance(account_id: AccountId) -> Balance { - Balances::free_balance(account_id) - } - - fn get_open_channel_for_domain(dst_domain_id: DomainId) -> Option { - Messenger::get_open_channel_for_domain(dst_domain_id).map(|(c, _)| c) - } - } -} - -fn extract_xdm_proof_state_roots( - encoded_ext: Vec, -) -> Option> { - if let Ok(ext) = UncheckedExtrinsic::decode(&mut encoded_ext.as_slice()) { - match &ext.function { - RuntimeCall::Messenger(pallet_messenger::Call::relay_message { msg }) => { - msg.extract_state_roots_from_proof::() - } - RuntimeCall::Messenger(pallet_messenger::Call::relay_message_response { msg }) => { - msg.extract_state_roots_from_proof::() - } - _ => None, - } - } else { - None - } -} diff --git a/domains/test/service/Cargo.toml b/domains/test/service/Cargo.toml index 23145c07f29..2e671d88176 100644 --- a/domains/test/service/Cargo.toml +++ b/domains/test/service/Cargo.toml @@ -14,43 +14,51 @@ include = [ [dependencies] async-trait = "0.1.68" domain-client-consensus-relay-chain = { version = "0.1.0", path = "../../client/consensus-relay-chain" } -domain-client-executor = { version = "0.1.0", path = "../../client/domain-executor" } +domain-client-operator = { version = "0.1.0", path = "../../client/domain-operator" } +domain-eth-service = { version = "0.1.0", path = "../../client/eth-service" } domain-service = { version = "0.1.0", path = "../../service" } +domain-test-primitives = { version = "0.1.0", path = "../primitives" } domain-runtime-primitives = { version = "0.1.0", path = "../../primitives/runtime", default-features = false } -domain-test-primitives = { version = "0.1.0", path = "../../test/primitives", default-features = false } +evm-domain-test-runtime = { version = "0.1.0", path = "../runtime/evm" } +fp-account = { version = "1.0.0-dev", default-features = false, features = ["serde"], git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } +fp-evm = { version = "3.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } +fp-rpc = { version = "3.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4", features = ['default'] } futures = "0.3.28" -frame-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system-rpc-runtime-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system-rpc-runtime-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-support = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } rand = "0.8.5" -pallet-transaction-payment = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-tracing = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-application-crypto = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-arithmetic = { version = "16.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +once_cell = "1.18.0" +pallet-transaction-payment = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transaction-payment-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus-slots = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-executor = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-rpc = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-service = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-tracing = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +serde = { version = "1.0.159", features = ["derive"] } +serde_json = "1.0.95" +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-application-crypto = { version = "23.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-arithmetic = { version = "16.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../../../crates/sp-domains" } -sp-keyring = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-keyring = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-messenger = { version = "0.1.0", path = "../../../domains/primitives/messenger" } -sp-offchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-session = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-offchain = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sp-session = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-networking = { path = "../../../crates/subspace-networking" } subspace-proof-of-space = { path = "../../../crates/subspace-proof-of-space" } subspace-runtime-primitives = { version = "0.1.0", path = "../../../crates/subspace-runtime-primitives" } @@ -58,8 +66,7 @@ subspace-service = { version = "0.1.0", path = "../../../crates/subspace-service subspace-test-client = { version = "0.1.0", path = "../../../test/subspace-test-client" } subspace-test-runtime = { version = "0.1.0", path = "../../../test/subspace-test-runtime" } subspace-test-service = { version = "0.1.0", path = "../../../test/subspace-test-service" } -substrate-frame-rpc-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -substrate-test-client = { version = "2.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -system-domain-test-runtime = { version = "0.1.0", path = "../runtime/system" } +substrate-frame-rpc-system = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +substrate-test-client = { version = "2.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } tokio = { version = "1.28.2", features = ["macros"] } tracing = "0.1.37" diff --git a/domains/test/service/src/chain_spec.rs b/domains/test/service/src/chain_spec.rs index 86762cd5e28..daeb7f602c7 100644 --- a/domains/test/service/src/chain_spec.rs +++ b/domains/test/service/src/chain_spec.rs @@ -1,121 +1,71 @@ //! Chain specification for the domain test runtime. -use crate::Keyring::{Alice, Bob, Charlie, Dave, Eve, Ferdie}; -use domain_runtime_primitives::{AccountId, Signature}; -use sc_service::{ChainSpec, ChainType, GenericChainSpec}; -use sp_application_crypto::UncheckedFrom; -use sp_core::{sr25519, Pair, Public}; -use sp_domains::{DomainId, ExecutorPublicKey}; -use sp_runtime::traits::{IdentifyAccount, Verify}; -use subspace_runtime_primitives::SSC; -type AccountPublic = ::Signer; +use evm_domain_test_runtime::GenesisConfig; +use once_cell::sync::OnceCell; +use sc_service::{ChainSpec, ChainType, GenericChainSpec}; +use sp_domains::{DomainId, DomainInstanceData, RuntimeType}; -/// Helper function to generate an account ID from seed. -pub fn get_account_id_from_seed(seed: &str) -> AccountId -where - AccountPublic: From<::Public>, -{ - AccountPublic::from( - TPublic::Pair::from_string(&format!("//{seed}"), None) - .expect("static values are valid; qed") - .public(), - ) - .into_account() +macro_rules! chain_spec_from_genesis { + ( $constructor:expr ) => {{ + GenericChainSpec::from_genesis( + "Local Testnet", + "local_testnet", + ChainType::Local, + $constructor, + vec![], + None, + None, + None, + None, + None, + ) + }}; } -/// Get the chain spec for the given domain. -/// -/// Note: for convenience, the returned chain spec give some specific accounts the ability to -/// win the bundle election for a specific domain with (nearly) 100% probability in each slot: -/// [System domain => Alice] -/// [Core payments domain => Bob] -/// [Core eth relay domain => Charlie] -pub fn get_chain_spec(domain_id: DomainId) -> Box { - macro_rules! chain_spec_from_genesis { - ( $constructor:expr ) => {{ - GenericChainSpec::from_genesis( - "Local Testnet", - "local_testnet", - ChainType::Local, - $constructor, - vec![], - None, - None, - None, - None, - None, - ) - }}; - } - match domain_id { - DomainId::SYSTEM => Box::new(chain_spec_from_genesis!(testnet_system_genesis)), - _ => panic!("{domain_id:?} unimplemented"), - } -} +/// HACK: `ChainSpec::from_genesis` is only allow to create hardcoded spec and `GenesisConfig` +/// dosen't derive `Clone`, using global variable and serialization/deserialization to workaround +/// these limits +// TODO: find a better solution, tests will run parallelly thus `load_chain_spec_with` multiple +// time, when we support more domain in the future the genesis domain of different domain will +// mixup in the current workaround. +static GENESIS_CONFIG: OnceCell> = OnceCell::new(); + +/// Load chain spec that contains the given `GenesisConfig` +fn load_chain_spec_with(genesis_config: GenesisConfig) -> Box { + let _ = GENESIS_CONFIG.set( + serde_json::to_vec(&genesis_config).expect("Genesis config serialization never fails; qed"), + ); + let constructor = || { + let raw_genesis_config = GENESIS_CONFIG.get().expect("Value just set; qed"); + serde_json::from_slice::(raw_genesis_config) + .expect("Genesis config deserialization never fails; qed") + }; -fn endowed_accounts() -> Vec { - vec![ - Alice.to_account_id(), - Bob.to_account_id(), - Charlie.to_account_id(), - Dave.to_account_id(), - Eve.to_account_id(), - Ferdie.to_account_id(), - get_account_id_from_seed::("Alice//stash"), - get_account_id_from_seed::("Bob//stash"), - get_account_id_from_seed::("Charlie//stash"), - get_account_id_from_seed::("Dave//stash"), - get_account_id_from_seed::("Eve//stash"), - get_account_id_from_seed::("Ferdie//stash"), - ] + Box::new(chain_spec_from_genesis!(constructor)) } -fn testnet_system_genesis() -> system_domain_test_runtime::GenesisConfig { - system_domain_test_runtime::GenesisConfig { - system: system_domain_test_runtime::SystemConfig { - code: system_domain_test_runtime::WASM_BINARY - .expect("WASM binary was not build, please build it!") - .to_vec(), - }, - transaction_payment: Default::default(), - balances: system_domain_test_runtime::BalancesConfig { - balances: endowed_accounts() - .iter() - .cloned() - .map(|k| (k, 2_000_000 * SSC)) - .collect(), - }, - executor_registry: system_domain_test_runtime::ExecutorRegistryConfig { - // Make Alice has a dominant executor stake such that it can produce bundle for the system domain - // in each slot with high probability (nearly 100%). - executors: vec![ - ( - Alice.to_account_id(), - 1_000_000 * SSC, - Alice.to_account_id(), - ExecutorPublicKey::unchecked_from(Alice.public().0), - ), - ( - Bob.to_account_id(), - SSC, - Bob.to_account_id(), - ExecutorPublicKey::unchecked_from(Bob.public().0), - ), - ( - Charlie.to_account_id(), - SSC, - Charlie.to_account_id(), - ExecutorPublicKey::unchecked_from(Charlie.public().0), - ), - ], - slot_probability: (1, 1), - }, - domain_registry: system_domain_test_runtime::DomainRegistryConfig::default(), - messenger: system_domain_test_runtime::MessengerConfig { - relayers: vec![(Alice.to_account_id(), Alice.to_account_id())], - }, - sudo: system_domain_test_runtime::SudoConfig { - key: Some(Alice.to_account_id()), - }, +/// Create chain spec +pub fn create_domain_spec( + domain_id: DomainId, + domain_instance_data: DomainInstanceData, +) -> Box { + let DomainInstanceData { + runtime_type, + runtime_code, + raw_genesis_config, + } = domain_instance_data; + + match runtime_type { + RuntimeType::Evm => { + let mut genesis_config = match raw_genesis_config { + Some(raw_genesis_config) => serde_json::from_slice(&raw_genesis_config) + .expect("Raw genesis config should be well-formatted"), + None => GenesisConfig::default(), + }; + genesis_config.system.code = runtime_code; + genesis_config.self_domain_id.domain_id = Some(domain_id); + + load_chain_spec_with(genesis_config) + } } } diff --git a/domains/test/service/src/domain.rs b/domains/test/service/src/domain.rs new file mode 100644 index 00000000000..862b35dbf58 --- /dev/null +++ b/domains/test/service/src/domain.rs @@ -0,0 +1,460 @@ +//! Utilities used for testing with the domain. +#![warn(missing_docs)] + +use crate::chain_spec::create_domain_spec; +use crate::{construct_extrinsic_generic, node_config, EcdsaKeyring, UncheckedExtrinsicFor}; +use domain_client_operator::{BootstrapResult, Bootstrapper, OperatorStreams}; +use domain_runtime_primitives::opaque::Block; +use domain_runtime_primitives::{Balance, DomainCoreApi, InherentExtrinsicApi}; +use domain_service::providers::DefaultProvider; +use domain_service::FullClient; +use domain_test_primitives::OnchainStateApi; +use evm_domain_test_runtime; +use evm_domain_test_runtime::AccountId as AccountId20; +use fp_rpc::EthereumRuntimeRPCApi; +use frame_support::dispatch::{DispatchInfo, PostDispatchInfo}; +use pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi; +use sc_client_api::{HeaderBackend, StateBackendFor}; +use sc_executor::NativeExecutionDispatch; +use sc_network::{NetworkService, NetworkStateInfo}; +use sc_network_sync::SyncingService; +use sc_service::config::MultiaddrWithPeerId; +use sc_service::{BasePath, Role, RpcHandlers, TFullBackend, TaskManager}; +use sc_utils::mpsc::TracingUnboundedSender; +use serde::de::DeserializeOwned; +use sp_api::{ApiExt, ConstructRuntimeApi, Metadata, NumberFor, ProvideRuntimeApi}; +use sp_block_builder::BlockBuilder; +use sp_core::{Decode, Encode, H256}; +use sp_domains::DomainId; +use sp_messenger::{MessengerApi, RelayerApi}; +use sp_offchain::OffchainWorkerApi; +use sp_runtime::traits::Dispatchable; +use sp_runtime::OpaqueExtrinsic; +use sp_session::SessionKeys; +use sp_transaction_pool::runtime_api::TaggedTransactionQueue; +use std::fmt::{Debug, Display}; +use std::future::Future; +use std::marker::PhantomData; +use std::str::FromStr; +use std::sync::Arc; +use subspace_runtime_primitives::opaque::Block as CBlock; +use subspace_runtime_primitives::Index as Nonce; +use subspace_test_service::MockConsensusNode; +use substrate_frame_rpc_system::AccountNonceApi; +use substrate_test_client::{ + BlockchainEventsExt, RpcHandlersExt, RpcTransactionError, RpcTransactionOutput, +}; + +/// Trait for convert keyring to account id +pub trait FromKeyring { + /// Convert keyring to account id + fn from_keyring(key: EcdsaKeyring) -> Self; +} + +impl FromKeyring for AccountId20 { + fn from_keyring(key: EcdsaKeyring) -> Self { + key.to_account_id() + } +} + +/// The backend type used by the test service. +pub type Backend = TFullBackend; + +type Client = FullClient; + +/// Domain executor for the test service. +pub type DomainOperator = domain_service::DomainOperator< + Block, + CBlock, + subspace_test_client::Client, + RuntimeApi, + ExecutorDispatch, + Arc>, +>; + +/// A generic domain node instance used for testing. +pub struct DomainNode +where + RuntimeApi: + ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: ApiExt> + + Metadata + + BlockBuilder + + OffchainWorkerApi + + SessionKeys + + DomainCoreApi + + MessengerApi> + + TaggedTransactionQueue + + AccountNonceApi + + TransactionPaymentRuntimeApi + + RelayerApi>, + ExecutorDispatch: NativeExecutionDispatch + Send + Sync + 'static, + AccountId: Encode + Decode + FromKeyring, +{ + /// The domain id + pub domain_id: DomainId, + // TODO: Make the signing scheme generic over domains, because Ecdsa only used in the EVM domain, + // other (incoming) domains may use Sr25519 + /// The node's account key + pub key: EcdsaKeyring, + /// TaskManager's instance. + pub task_manager: TaskManager, + /// Client's instance. + pub client: Arc>, + /// Client backend. + pub backend: Arc, + /// Code executor. + pub code_executor: Arc>, + /// Network service. + pub network_service: Arc>, + /// Sync service. + pub sync_service: Arc>, + /// The `MultiaddrWithPeerId` to this node. This is useful if you want to pass it as "boot node" + /// to other nodes. + pub addr: MultiaddrWithPeerId, + /// RPCHandlers to make RPC queries. + pub rpc_handlers: RpcHandlers, + /// Domain oeprator. + pub operator: DomainOperator, + /// Sink to the node's tx pool + pub tx_pool_sink: TracingUnboundedSender>, + _phantom_data: PhantomData<(Runtime, AccountId)>, +} + +impl + DomainNode +where + Runtime: frame_system::Config + + pallet_transaction_payment::Config + + Send + + Sync, + Runtime::RuntimeCall: + Dispatchable + Send + Sync, + crate::BalanceOf: Send + Sync + From + sp_runtime::FixedPointOperand, + RuntimeApi: + ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: ApiExt> + + Metadata + + BlockBuilder + + OffchainWorkerApi + + SessionKeys + + DomainCoreApi + + TaggedTransactionQueue + + AccountNonceApi + + TransactionPaymentRuntimeApi + + InherentExtrinsicApi + + MessengerApi> + + RelayerApi> + + OnchainStateApi + + EthereumRuntimeRPCApi, + ExecutorDispatch: NativeExecutionDispatch + Send + Sync + 'static, + AccountId: DeserializeOwned + + Encode + + Decode + + Clone + + Debug + + Display + + FromStr + + Sync + + Send + + FromKeyring + + 'static, +{ + #[allow(clippy::too_many_arguments)] + async fn build( + domain_id: DomainId, + tokio_handle: tokio::runtime::Handle, + key: EcdsaKeyring, + base_path: BasePath, + domain_nodes: Vec, + domain_nodes_exclusive: bool, + run_relayer: bool, + role: Role, + mock_consensus_node: &mut MockConsensusNode, + ) -> Self { + let BootstrapResult { + domain_instance_data, + domain_created_at, + imported_block_notification_stream, + } = { + let bootstrapper = Bootstrapper::::new(mock_consensus_node.client.clone()); + bootstrapper + .fetch_domain_bootstrap_info(domain_id) + .await + .expect("Failed to get domain instance data") + }; + let chain_spec = create_domain_spec(domain_id, domain_instance_data); + let service_config = node_config( + domain_id, + tokio_handle.clone(), + key, + domain_nodes, + domain_nodes_exclusive, + role.clone(), + BasePath::new(base_path.path().join(format!("domain-{domain_id:?}"))), + chain_spec, + ) + .expect("could not generate domain node Configuration"); + + let span = sc_tracing::tracing::info_span!( + sc_tracing::logging::PREFIX_LOG_SPAN, + name = service_config.network.node_name.as_str() + ); + let _enter = span.enter(); + + let multiaddr = service_config.network.listen_addresses[0].clone(); + + let maybe_relayer_id = if run_relayer { + Some(::from_keyring(key)) + } else { + None + }; + let domain_config = domain_service::DomainConfiguration { + service_config, + maybe_relayer_id, + }; + let operator_streams = OperatorStreams { + // Set `consensus_block_import_throttling_buffer_size` to 0 to ensure the primary chain will not be + // ahead of the execution chain by more than one block, thus slot will not be skipped in test. + consensus_block_import_throttling_buffer_size: 0, + block_importing_notification_stream: mock_consensus_node + .block_importing_notification_stream(), + imported_block_notification_stream, + new_slot_notification_stream: mock_consensus_node.new_slot_notification_stream(), + _phantom: Default::default(), + }; + + let gossip_msg_sink = mock_consensus_node + .xdm_gossip_worker_builder() + .gossip_msg_sink(); + let domain_params = domain_service::DomainParams { + domain_id, + domain_config, + domain_created_at, + consensus_client: mock_consensus_node.client.clone(), + consensus_network_sync_oracle: mock_consensus_node.sync_service.clone(), + select_chain: mock_consensus_node.select_chain.clone(), + operator_streams, + gossip_message_sink: gossip_msg_sink, + provider: DefaultProvider, + }; + + let domain_node = domain_service::new_full::< + _, + _, + _, + _, + _, + _, + RuntimeApi, + ExecutorDispatch, + AccountId, + _, + >(domain_params) + .await + .expect("failed to build domain node"); + + let domain_service::NewFull { + task_manager, + client, + backend, + code_executor, + network_service, + sync_service, + network_starter, + rpc_handlers, + operator, + tx_pool_sink, + .. + } = domain_node; + + if role.is_authority() { + mock_consensus_node + .xdm_gossip_worker_builder() + .push_domain_tx_pool_sink(domain_id, tx_pool_sink.clone()); + } + + let addr = MultiaddrWithPeerId { + multiaddr, + peer_id: network_service.local_peer_id(), + }; + + network_starter.start_network(); + + DomainNode { + domain_id, + key, + task_manager, + client, + backend, + code_executor, + network_service, + sync_service, + addr, + rpc_handlers, + operator, + tx_pool_sink, + _phantom_data: Default::default(), + } + } + + /// Wait for `count` blocks to be imported in the node and then exit. This function will not + /// return if no blocks are ever created, thus you should restrict the maximum amount of time of + /// the test execution. + pub fn wait_for_blocks(&self, count: usize) -> impl Future { + self.client.wait_for_blocks(count) + } + + /// Get the nonce of the node account + pub fn account_nonce(&self) -> u32 { + self.client + .runtime_api() + .account_nonce( + self.client.info().best_hash, + ::from_keyring(self.key), + ) + .expect("Fail to get account nonce") + } + + /// Construct an extrinsic with the current nonce of the node account and send it to this node. + pub async fn construct_and_send_extrinsic( + &mut self, + function: impl Into<::RuntimeCall>, + ) -> Result { + let extrinsic = construct_extrinsic_generic::( + &self.client, + function, + self.key, + false, + self.account_nonce(), + ); + self.rpc_handlers.send_transaction(extrinsic.into()).await + } + + /// Construct an extrinsic. + pub fn construct_extrinsic( + &mut self, + nonce: u32, + function: impl Into<::RuntimeCall>, + ) -> UncheckedExtrinsicFor { + construct_extrinsic_generic::(&self.client, function, self.key, false, nonce) + } + + /// Send an extrinsic to this node. + pub async fn send_extrinsic( + &self, + extrinsic: impl Into, + ) -> Result { + self.rpc_handlers.send_transaction(extrinsic.into()).await + } + + /// Get the free balance of the given account + pub fn free_balance(&self, account_id: AccountId) -> Balance { + self.client + .runtime_api() + .free_balance(self.client.info().best_hash, account_id) + .expect("Fail to get account free balance") + } +} + +/// A builder to create a [`DomainNode`]. +pub struct DomainNodeBuilder { + tokio_handle: tokio::runtime::Handle, + key: EcdsaKeyring, + domain_nodes: Vec, + domain_nodes_exclusive: bool, + base_path: BasePath, + run_relayer: bool, +} + +impl DomainNodeBuilder { + /// Create a new instance of `Self`. + /// + /// `tokio_handle` - The tokio handler to use. + /// `key` - The key that will be used to generate the name. + /// `base_path` - Where databases will be stored. + pub fn new( + tokio_handle: tokio::runtime::Handle, + key: EcdsaKeyring, + base_path: BasePath, + ) -> Self { + DomainNodeBuilder { + key, + tokio_handle, + domain_nodes: Vec::new(), + domain_nodes_exclusive: false, + base_path, + run_relayer: false, + } + } + + /// Run relayer with the node account id as the relayer id + pub fn run_relayer(mut self) -> Self { + self.run_relayer = true; + self + } + + /// Instruct the node to exclusively connect to registered parachain nodes. + /// + /// Domain nodes can be registered using [`Self::connect_to_domain_node`]. + pub fn exclusively_connect_to_registered_parachain_nodes(mut self) -> Self { + self.domain_nodes_exclusive = true; + self + } + + /// Make the node connect to the given domain node. + /// + /// By default the node will not be connected to any node or will be able to discover any other + /// node. + pub fn connect_to_domain_node(mut self, addr: MultiaddrWithPeerId) -> Self { + self.domain_nodes.push(addr); + self + } + + /// Build a evm domain node + pub async fn build_evm_node( + self, + role: Role, + domain_id: DomainId, + mock_consensus_node: &mut MockConsensusNode, + ) -> EvmDomainNode { + DomainNode::build( + domain_id, + self.tokio_handle, + self.key, + self.base_path, + self.domain_nodes, + self.domain_nodes_exclusive, + self.run_relayer, + role, + mock_consensus_node, + ) + .await + } +} + +/// Evm domain executor instance. +pub struct EVMDomainExecutorDispatch; + +impl NativeExecutionDispatch for EVMDomainExecutorDispatch { + type ExtendHostFunctions = (); + + fn dispatch(method: &str, data: &[u8]) -> Option> { + evm_domain_test_runtime::api::dispatch(method, data) + } + + fn native_version() -> sc_executor::NativeVersion { + evm_domain_test_runtime::native_version() + } +} + +/// The evm domain node +pub type EvmDomainNode = DomainNode< + evm_domain_test_runtime::Runtime, + evm_domain_test_runtime::RuntimeApi, + EVMDomainExecutorDispatch, + AccountId20, +>; + +/// The evm domain client +pub type EvmDomainClient = Client; diff --git a/domains/test/service/src/keyring.rs b/domains/test/service/src/keyring.rs new file mode 100644 index 00000000000..9694c9a6078 --- /dev/null +++ b/domains/test/service/src/keyring.rs @@ -0,0 +1,45 @@ +//! Set of test accounts. +use fp_account::AccountId20; +use sp_core::ecdsa::{Pair, Public, Signature}; +use sp_core::{ecdsa, keccak_256, Pair as PairT}; + +#[allow(missing_docs)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Keyring { + Alice, + Bob, + Charlie, + Dave, + Eve, + Ferdie, + One, + Two, +} + +impl Keyring { + /// Sign `msg`. + pub fn sign(self, msg: &[u8]) -> Signature { + let msg = keccak_256(msg); + self.pair().sign_prehashed(&msg) + } + + /// Return key pair. + pub fn pair(self) -> Pair { + ecdsa::Pair::from_string(self.to_seed().as_str(), None).unwrap() + } + + /// Return public key. + pub fn public(self) -> Public { + self.pair().public() + } + + /// Return seed string. + pub fn to_seed(self) -> String { + format!("//{:?}", self) + } + + /// Return account id + pub fn to_account_id(self) -> AccountId20 { + self.public().into() + } +} diff --git a/domains/test/service/src/lib.rs b/domains/test/service/src/lib.rs index 5d2cd012b16..083a9258867 100644 --- a/domains/test/service/src/lib.rs +++ b/domains/test/service/src/lib.rs @@ -19,10 +19,14 @@ #![warn(missing_docs)] pub mod chain_spec; -pub mod system_domain; +pub mod domain; +pub mod keyring; + +pub use keyring::Keyring as EcdsaKeyring; +pub use sp_keyring::Sr25519Keyring; use domain_runtime_primitives::opaque::Block; -use domain_runtime_primitives::{Address, Signature}; +use evm_domain_test_runtime::{Address, Signature}; use frame_support::dispatch::{DispatchInfo, PostDispatchInfo}; use sc_client_api::execution_extensions::ExecutionStrategies; use sc_network::config::{NonReservedPeerMode, TransportConfig}; @@ -32,42 +36,43 @@ use sc_service::config::{ OffchainWorkerConfig, PruningMode, WasmExecutionMethod, WasmtimeInstantiationStrategy, }; use sc_service::{ - BasePath, BlocksPruning, Configuration as ServiceConfiguration, Error as ServiceError, Role, + BasePath, BlocksPruning, ChainSpec, Configuration as ServiceConfiguration, + Error as ServiceError, Role, }; use sp_arithmetic::traits::SaturatedConversion; use sp_blockchain::HeaderBackend; use sp_core::{Get, H256}; use sp_domains::DomainId; -use sp_keyring::Sr25519Keyring; use sp_runtime::codec::Encode; use sp_runtime::generic; use sp_runtime::traits::Dispatchable; -pub use sp_keyring::Sr25519Keyring as Keyring; -pub use system_domain::*; -pub use system_domain_test_runtime; +pub use domain::*; +pub use evm_domain_test_runtime; + +/// The domain id of the genesis domain +pub const GENESIS_DOMAIN_ID: DomainId = DomainId::new(0u32); /// Create a domain node `Configuration`. /// /// By default an in-memory socket will be used, therefore you need to provide nodes if you want the /// node to be connected to other nodes. If `nodes_exclusive` is `true`, the node will only connect /// to the given `nodes` and not to any other node. +#[allow(clippy::too_many_arguments)] pub fn node_config( domain_id: DomainId, tokio_handle: tokio::runtime::Handle, - key: Sr25519Keyring, + key: EcdsaKeyring, nodes: Vec, nodes_exclusive: bool, role: Role, base_path: BasePath, + chain_spec: Box, ) -> Result { let root = base_path.path().to_path_buf(); let key_seed = key.to_seed(); - let domain_name = match domain_id { - DomainId::SYSTEM => "SystemDomain", - _ => panic!("{domain_id:?} unimplemented"), - }; + let domain_name = format!("{domain_id:?}"); let mut network_config = NetworkConfiguration::new( format!("{key_seed} ({domain_name})"), @@ -110,7 +115,7 @@ pub fn node_config( trie_cache_maximum_size: Some(16 * 1024 * 1024), state_pruning: Some(PruningMode::ArchiveAll), blocks_pruning: BlocksPruning::KeepAll, - chain_spec: chain_spec::get_chain_spec(domain_id), + chain_spec, wasm_method: WasmExecutionMethod::Compiled { instantiation_strategy: WasmtimeInstantiationStrategy::PoolingCopyOnWrite, }, @@ -177,7 +182,7 @@ type BalanceOf = <::OnChargeTransact pub fn construct_extrinsic_generic( client: impl AsRef, function: impl Into<::RuntimeCall>, - caller: Sr25519Keyring, + caller: EcdsaKeyring, immortal: bool, nonce: u32, ) -> UncheckedExtrinsicFor @@ -225,8 +230,8 @@ where let signature = raw_payload.using_encoded(|e| caller.sign(e)); UncheckedExtrinsicFor::::new_signed( function, - subspace_test_runtime::Address::Id(caller.public().into()), - Signature::Sr25519(signature), + caller.to_account_id(), + Signature::new(signature), extra, ) } diff --git a/domains/test/service/src/system_domain.rs b/domains/test/service/src/system_domain.rs deleted file mode 100644 index 1d65e071a14..00000000000 --- a/domains/test/service/src/system_domain.rs +++ /dev/null @@ -1,437 +0,0 @@ -//! Utilities used for testing with the system domain. -#![warn(missing_docs)] -use crate::{construct_extrinsic_generic, node_config}; -use domain_client_executor::ExecutorStreams; -use domain_runtime_primitives::{AccountId, Balance}; -use domain_service::{DomainConfiguration, FullPool}; -use domain_test_primitives::OnchainStateApi; -use frame_system_rpc_runtime_api::AccountNonceApi; -use sc_client_api::{BlockchainEvents, HeaderBackend}; -use sc_network::{NetworkService, NetworkStateInfo}; -use sc_network_sync::SyncingService; -use sc_service::config::MultiaddrWithPeerId; -use sc_service::{ - BasePath, Configuration as ServiceConfiguration, Role, RpcHandlers, TFullBackend, TFullClient, - TaskManager, -}; -use sc_utils::mpsc::TracingUnboundedSender; -use sp_api::ProvideRuntimeApi; -use sp_core::H256; -use sp_domains::DomainId; -use sp_keyring::Sr25519Keyring; -use sp_messenger::messages::ChannelId; -use sp_runtime::OpaqueExtrinsic; -use std::future::Future; -use std::sync::Arc; -use subspace_runtime_primitives::opaque::Block as PBlock; -use subspace_test_service::MockPrimaryNode; -use substrate_test_client::{ - BlockchainEventsExt, RpcHandlersExt, RpcTransactionError, RpcTransactionOutput, -}; -use system_domain_test_runtime; -use system_domain_test_runtime::opaque::Block; - -/// The backend type used by the test service. -pub type Backend = TFullBackend; - -/// The system domain client type being used by the test service. -pub type SClient = TFullClient< - Block, - system_domain_test_runtime::RuntimeApi, - sc_executor::NativeElseWasmExecutor, ->; - -/// System domain code executor for the test service. -pub type SystemCodeExecutor = sc_executor::NativeElseWasmExecutor; - -/// System domain executor for the test service. -pub type SystemExecutor = domain_client_executor::SystemExecutor< - Block, - PBlock, - SClient, - subspace_test_client::Client, - FullPool< - PBlock, - subspace_test_client::Client, - system_domain_test_runtime::RuntimeApi, - SystemDomainExecutorDispatch, - >, - Backend, - SystemCodeExecutor, ->; - -type SystemGossipMessageValidator = domain_client_executor::SystemGossipMessageValidator< - Block, - PBlock, - SClient, - subspace_test_client::Client, - FullPool< - PBlock, - subspace_test_client::Client, - system_domain_test_runtime::RuntimeApi, - SystemDomainExecutorDispatch, - >, - Backend, - SystemCodeExecutor, - domain_client_executor::SystemDomainParentChain, ->; - -/// The System domain native executor instance. -pub struct SystemDomainExecutorDispatch; - -impl sc_executor::NativeExecutionDispatch for SystemDomainExecutorDispatch { - type ExtendHostFunctions = (); - - fn dispatch(method: &str, data: &[u8]) -> Option> { - system_domain_test_runtime::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - system_domain_test_runtime::native_version() - } -} - -/// Start an executor with the given system domain `Configuration` and the mock primary node. -#[sc_tracing::logging::prefix_logs_with(system_domain_config.network.node_name.as_str())] -async fn run_executor_with_mock_primary_node( - role: Role, - system_domain_config: ServiceConfiguration, - mock_primary_node: &mut MockPrimaryNode, - maybe_relayer_id: Option, -) -> sc_service::error::Result<( - TaskManager, - Arc, - Arc, - Arc, - Arc>, - Arc>, - RpcHandlers, - SystemExecutor, - SystemGossipMessageValidator, - TracingUnboundedSender>, -)> { - let system_domain_config = DomainConfiguration { - service_config: system_domain_config, - maybe_relayer_id, - }; - let executor_streams = ExecutorStreams { - // Set `primary_block_import_throttling_buffer_size` to 0 to ensure the primary chain will not be - // ahead of the execution chain by more than one block, thus slot will not be skipped in test. - primary_block_import_throttling_buffer_size: 0, - block_importing_notification_stream: mock_primary_node - .block_importing_notification_stream(), - imported_block_notification_stream: mock_primary_node - .client - .every_import_notification_stream(), - new_slot_notification_stream: mock_primary_node.new_slot_notification_stream(), - _phantom: Default::default(), - }; - let gossip_msg_sink = mock_primary_node - .xdm_gossip_worker_builder() - .gossip_msg_sink(); - let system_domain_node = domain_service::new_full_system::< - _, - _, - _, - _, - _, - _, - system_domain_test_runtime::RuntimeApi, - SystemDomainExecutorDispatch, - >( - system_domain_config, - mock_primary_node.client.clone(), - mock_primary_node.sync_service.clone(), - &mock_primary_node.select_chain, - executor_streams, - gossip_msg_sink, - ) - .await?; - - let domain_service::NewFullSystem { - task_manager, - client, - backend, - code_executor, - network_service, - sync_service, - network_starter, - rpc_handlers, - executor, - gossip_message_validator, - tx_pool_sink, - } = system_domain_node; - - if role.is_authority() { - mock_primary_node - .xdm_gossip_worker_builder() - .push_domain_tx_pool_sink(DomainId::SYSTEM, tx_pool_sink.clone()); - } - - network_starter.start_network(); - - Ok(( - task_manager, - client, - backend, - code_executor, - network_service, - sync_service, - rpc_handlers, - executor, - gossip_message_validator, - tx_pool_sink, - )) -} - -/// A Cumulus test node instance used for testing. -pub struct SystemDomainNode { - /// The node's key - pub key: Sr25519Keyring, - /// TaskManager's instance. - pub task_manager: TaskManager, - /// Client's instance. - pub client: Arc, - /// Client backend. - pub backend: Arc, - /// Code executor. - pub code_executor: Arc, - /// Network service. - pub network_service: Arc>, - /// Sync service. - pub sync_service: Arc>, - /// The `MultiaddrWithPeerId` to this node. This is useful if you want to pass it as "boot node" - /// to other nodes. - pub addr: MultiaddrWithPeerId, - /// RPCHandlers to make RPC queries. - pub rpc_handlers: RpcHandlers, - /// System domain executor. - pub executor: SystemExecutor, - /// System domain gossip message validator. - pub gossip_message_validator: SystemGossipMessageValidator, - /// Sink to the node's tx pool - pub tx_pool_sink: TracingUnboundedSender>, -} - -/// A builder to create a [`SystemDomainNode`]. -pub struct SystemDomainNodeBuilder { - tokio_handle: tokio::runtime::Handle, - key: Sr25519Keyring, - system_domain_nodes: Vec, - system_domain_nodes_exclusive: bool, - base_path: BasePath, - run_relayer: bool, -} - -impl SystemDomainNodeBuilder { - /// Create a new instance of `Self`. - /// - /// `tokio_handle` - The tokio handler to use. - /// `key` - The key that will be used to generate the name. - /// `base_path` - Where databases will be stored. - pub fn new( - tokio_handle: tokio::runtime::Handle, - key: Sr25519Keyring, - base_path: BasePath, - ) -> Self { - SystemDomainNodeBuilder { - key, - tokio_handle, - system_domain_nodes: Vec::new(), - system_domain_nodes_exclusive: false, - base_path, - run_relayer: false, - } - } - - /// Run relayer with the node account id as the relayer id - pub fn run_relayer(mut self) -> Self { - self.run_relayer = true; - self - } - - /// Instruct the node to exclusively connect to registered parachain nodes. - /// - /// System domain nodes can be registered using [`Self::connect_to_system_domain_node`] and - /// [`Self::connect_to_system_domain_nodes`]. - pub fn exclusively_connect_to_registered_parachain_nodes(mut self) -> Self { - self.system_domain_nodes_exclusive = true; - self - } - - /// Make the node connect to the given system domain node. - /// - /// By default the node will not be connected to any node or will be able to discover any other - /// node. - pub fn connect_to_system_domain_node(mut self, node: &SystemDomainNode) -> Self { - self.system_domain_nodes.push(node.addr.clone()); - self - } - - /// Make the node connect to the given system domain nodes. - /// - /// By default the node will not be connected to any node or will be able to discover any other - /// node. - pub fn connect_to_system_domain_nodes<'a>( - mut self, - nodes: impl Iterator, - ) -> Self { - self.system_domain_nodes - .extend(nodes.map(|n| n.addr.clone())); - self - } - - /// Build the [`SystemDomainNode`] with `MockPrimaryNode` as the embedded primary node. - pub async fn build_with_mock_primary_node( - self, - role: Role, - mock_primary_node: &mut MockPrimaryNode, - ) -> SystemDomainNode { - let system_domain_config = node_config( - DomainId::SYSTEM, - self.tokio_handle.clone(), - self.key, - self.system_domain_nodes, - self.system_domain_nodes_exclusive, - role.clone(), - BasePath::new(self.base_path.path().join("system")), - ) - .expect("could not generate system domain node Configuration"); - - let multiaddr = system_domain_config.network.listen_addresses[0].clone(); - - let maybe_relayer_id = if self.run_relayer { - Some(self.key.into()) - } else { - None - }; - let ( - task_manager, - client, - backend, - code_executor, - network_service, - sync_service, - rpc_handlers, - executor, - gossip_message_validator, - tx_pool_sink, - ) = run_executor_with_mock_primary_node( - role, - system_domain_config, - mock_primary_node, - maybe_relayer_id, - ) - .await - .expect("could not start system domain node"); - - let peer_id = network_service.local_peer_id(); - let addr = MultiaddrWithPeerId { multiaddr, peer_id }; - - SystemDomainNode { - key: self.key, - task_manager, - client, - backend, - code_executor, - network_service, - sync_service, - addr, - rpc_handlers, - executor, - gossip_message_validator, - tx_pool_sink, - } - } -} - -impl SystemDomainNode { - /// Wait for `count` blocks to be imported in the node and then exit. This function will not - /// return if no blocks are ever created, thus you should restrict the maximum amount of time of - /// the test execution. - pub fn wait_for_blocks(&self, count: usize) -> impl Future { - self.client.wait_for_blocks(count) - } - - /// Get the nonce of the node account - pub fn account_nonce(&self) -> u32 { - self.client - .runtime_api() - .account_nonce(self.client.info().best_hash, self.key.into()) - .expect("Fail to get account nonce") - } - - /// Get the free balance of the given account - pub fn free_balance(&self, account_id: AccountId) -> Balance { - self.client - .runtime_api() - .free_balance(self.client.info().best_hash, account_id) - .expect("Fail to get account free balance") - } - - /// Get the last open channel of the given domain - pub fn get_open_channel_for_domain(&self, dst_domain_id: DomainId) -> Option { - self.client - .runtime_api() - .get_open_channel_for_domain(self.client.info().best_hash, dst_domain_id) - .expect("Fail to get open channel") - } - - /// Construct an extrinsic with the current nonce of the node account and send it to this node. - pub async fn construct_and_send_extrinsic( - &mut self, - function: impl Into, - ) -> Result { - let extrinsic = construct_extrinsic_generic::( - &self.client, - function, - self.key, - false, - self.account_nonce(), - ); - self.rpc_handlers.send_transaction(extrinsic.into()).await - } - - /// Construct an extrinsic. - pub fn construct_extrinsic( - &mut self, - nonce: u32, - function: impl Into, - ) -> system_domain_test_runtime::UncheckedExtrinsic { - crate::construct_extrinsic_generic::( - &self.client, - function, - self.key, - false, - nonce, - ) - } - - /// Construct an extrinsic. - pub fn construct_extrinsic_with_caller( - &mut self, - caller: Sr25519Keyring, - function: impl Into, - ) -> system_domain_test_runtime::UncheckedExtrinsic { - let nonce = self - .client - .runtime_api() - .account_nonce(self.client.info().best_hash, caller.into()) - .expect("Fail to get account nonce"); - crate::construct_extrinsic_generic::( - &self.client, - function, - caller, - false, - nonce, - ) - } - - /// Send an extrinsic to this node. - pub async fn send_extrinsic( - &self, - extrinsic: impl Into, - ) -> Result { - self.rpc_handlers.send_transaction(extrinsic.into()).await - } -} diff --git a/orml/vesting/Cargo.toml b/orml/vesting/Cargo.toml index cbc7672609e..9620361fa87 100644 --- a/orml/vesting/Cargo.toml +++ b/orml/vesting/Cargo.toml @@ -12,15 +12,15 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = scale-info = { version = "2.1.2", default-features = false, features = ["derive"] } serde = { version = "1.0.136", optional = true } -frame-support = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-io = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-std = { default-features = false , git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-support = { default-features = false , git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { default-features = false , git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-io = { default-features = false , git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { default-features = false , git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { default-features = false , git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [dev-dependencies] -pallet-balances = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [features] default = ["std"] diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 34d57e19465..1504b5fa85e 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "nightly-2023-05-16" +channel = "nightly-2023-07-21" components = ["rust-src"] targets = ["wasm32-unknown-unknown"] profile = "default" diff --git a/test/subspace-test-client/Cargo.toml b/test/subspace-test-client/Cargo.toml index a0461945dd0..71f4decf063 100644 --- a/test/subspace-test-client/Cargo.toml +++ b/test/subspace-test-client/Cargo.toml @@ -15,17 +15,21 @@ include = [ targets = ["x86_64-unknown-linux-gnu"] [dependencies] +evm-domain-test-runtime = { version = "0.1.0", path = "../../domains/test/runtime/evm" } +fp-evm = { version = "3.0.0-dev", git = "https://github.com/subspace/frontier", rev = "c13d670b25b5506c1c5243f352941dc46c82ffe4" } futures = "0.3.28" schnorrkel = "0.9.1" -sc-chain-spec = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-client-api = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-chain-spec = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-client-api = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sc-consensus-subspace = { version = "0.1.0", path = "../../crates/sc-consensus-subspace" } -sc-executor = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sp-api = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-executor = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-service = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +serde_json = "1.0.95" +sp-api = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-consensus-subspace = { version = "0.1.0", path = "../../crates/sp-consensus-subspace" } -sp-core = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-domains = { version = "0.1.0", path = "../../crates/sp-domains" } +sp-runtime = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-archiving = { path = "../../crates/subspace-archiving" } subspace-core-primitives = { path = "../../crates/subspace-core-primitives" } subspace-erasure-coding = { path = "../../crates/subspace-erasure-coding" } @@ -35,5 +39,4 @@ subspace-proof-of-space = { path = "../../crates/subspace-proof-of-space" } subspace-service = { path = "../../crates/subspace-service" } subspace-solving = { path = "../../crates/subspace-solving" } subspace-test-runtime = { version = "0.1.0", features = ["do-not-enforce-cost-of-storage"], path = "../subspace-test-runtime" } -subspace-transaction-pool = { version = "0.1.0", path = "../../crates/subspace-transaction-pool" } zeroize = "1.6.0" diff --git a/test/subspace-test-client/src/chain_spec.rs b/test/subspace-test-client/src/chain_spec.rs index 455e78400c8..0bed5402dd2 100644 --- a/test/subspace-test-client/src/chain_spec.rs +++ b/test/subspace-test-client/src/chain_spec.rs @@ -1,12 +1,16 @@ //! Chain specification for the test runtime. +use crate::domain_chain_spec::testnet_evm_genesis; use sc_chain_spec::ChainType; use sp_core::{sr25519, Pair, Public}; +use sp_domains::{GenesisDomain, OperatorPublicKey, RuntimeType}; use sp_runtime::traits::{IdentifyAccount, Verify}; +use sp_runtime::Percent; use subspace_runtime_primitives::{AccountId, Balance, BlockNumber, Signature}; use subspace_test_runtime::{ - AllowAuthoringBy, BalancesConfig, GenesisConfig, SubspaceConfig, SudoConfig, SystemConfig, - VestingConfig, SSC, WASM_BINARY, + AllowAuthoringBy, BalancesConfig, DomainsConfig, GenesisConfig, MaxDomainBlockSize, + MaxDomainBlockWeight, SubspaceConfig, SudoConfig, SystemConfig, VestingConfig, SSC, + WASM_BINARY, }; /// The `ChainSpec` parameterized for subspace test runtime. @@ -73,6 +77,13 @@ fn create_genesis_config( // who, start, period, period_count, per_period vesting: Vec<(AccountId, BlockNumber, BlockNumber, u32, Balance)>, ) -> GenesisConfig { + let raw_domain_genesis_config = { + let mut domain_genesis_config = testnet_evm_genesis(); + // Clear the WASM code of the genesis config since it is duplicated with `GenesisDomain::code` + domain_genesis_config.system.code = Default::default(); + serde_json::to_vec(&domain_genesis_config) + .expect("Genesis config serialization never fails; qed") + }; GenesisConfig { system: SystemConfig { // Add Wasm runtime to storage. @@ -82,7 +93,7 @@ fn create_genesis_config( transaction_payment: Default::default(), sudo: SudoConfig { // Assign network admin rights. - key: Some(sudo_account), + key: Some(sudo_account.clone()), }, subspace: SubspaceConfig { enable_rewards: false, @@ -90,5 +101,28 @@ fn create_genesis_config( allow_authoring_by: AllowAuthoringBy::Anyone, }, vesting: VestingConfig { vesting }, + domains: DomainsConfig { + genesis_domain: Some(GenesisDomain { + runtime_name: b"evm".to_vec(), + runtime_type: RuntimeType::Evm, + runtime_version: evm_domain_test_runtime::VERSION, + code: evm_domain_test_runtime::WASM_BINARY + .unwrap_or_else(|| panic!("EVM domain runtime not available")) + .to_owned(), + + // Domain config, mainly for placeholder the concrete value TBD + owner_account_id: sudo_account, + domain_name: b"evm-domain".to_vec(), + max_block_size: MaxDomainBlockSize::get(), + max_block_weight: MaxDomainBlockWeight::get(), + bundle_slot_probability: (1, 1), + target_bundles_per_block: 10, + raw_genesis_config: raw_domain_genesis_config, + + signing_key: get_from_seed::("Alice"), + minimum_nominator_stake: 100 * SSC, + nomination_tax: Percent::from_percent(5), + }), + }, } } diff --git a/test/subspace-test-client/src/domain_chain_spec.rs b/test/subspace-test-client/src/domain_chain_spec.rs new file mode 100644 index 00000000000..b973f733db9 --- /dev/null +++ b/test/subspace-test-client/src/domain_chain_spec.rs @@ -0,0 +1,95 @@ +//! Chain specification for the evm domain. + +use evm_domain_test_runtime::{AccountId as AccountId20, GenesisConfig, Precompiles, Signature}; +use sp_core::{ecdsa, Pair, Public}; +use sp_domains::DomainId; +use sp_runtime::traits::{IdentifyAccount, Verify}; +use subspace_runtime_primitives::SSC; + +type AccountPublic = ::Signer; + +/// Helper function to generate an account ID from seed. +pub fn get_account_id_from_seed(seed: &str) -> AccountId20 +where + AccountPublic: From<::Public>, +{ + AccountPublic::from( + TPublic::Pair::from_string(&format!("//{seed}"), None) + .expect("static values are valid; qed") + .public(), + ) + .into_account() +} + +fn endowed_accounts() -> Vec { + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ] +} + +/// Get the genesis config of the evm domain +pub fn testnet_evm_genesis() -> GenesisConfig { + // This is the simplest bytecode to revert without returning any data. + // We will pre-deploy it under all of our precompiles to ensure they can be called from + // within contracts. + // (PUSH1 0x00 PUSH1 0x00 REVERT) + let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD]; + + let alice = get_account_id_from_seed::("Alice"); + + evm_domain_test_runtime::GenesisConfig { + system: evm_domain_test_runtime::SystemConfig { + code: evm_domain_test_runtime::WASM_BINARY + .expect("WASM binary was not build, please build it!") + .to_vec(), + }, + transaction_payment: Default::default(), + balances: evm_domain_test_runtime::BalancesConfig { + balances: endowed_accounts() + .iter() + .cloned() + .map(|k| (k, 2_000_000 * SSC)) + .collect(), + }, + messenger: evm_domain_test_runtime::MessengerConfig { + relayers: vec![(alice, alice)], + }, + sudo: evm_domain_test_runtime::SudoConfig { key: Some(alice) }, + evm_chain_id: evm_domain_test_runtime::EVMChainIdConfig { chain_id: 100 }, + evm: evm_domain_test_runtime::EVMConfig { + // We need _some_ code inserted at the precompile address so that + // the evm will actually call the address. + accounts: Precompiles::used_addresses() + .into_iter() + .map(|addr| { + ( + addr, + fp_evm::GenesisAccount { + nonce: Default::default(), + balance: Default::default(), + storage: Default::default(), + code: revert_bytecode.clone(), + }, + ) + }) + .collect(), + }, + ethereum: Default::default(), + base_fee: Default::default(), + self_domain_id: evm_domain_test_runtime::SelfDomainIdConfig { + // Id of the genesis domain + domain_id: Some(DomainId::new(0)), + }, + } +} diff --git a/test/subspace-test-client/src/lib.rs b/test/subspace-test-client/src/lib.rs index 9a47b4e6264..dda0d75b706 100644 --- a/test/subspace-test-client/src/lib.rs +++ b/test/subspace-test-client/src/lib.rs @@ -19,6 +19,7 @@ #![warn(missing_docs, unused_crate_dependencies)] pub mod chain_spec; +pub mod domain_chain_spec; use futures::executor::block_on; use futures::StreamExt; @@ -28,7 +29,7 @@ use sc_consensus_subspace::{NewSlotNotification, RewardSigningNotification}; use sp_api::ProvideRuntimeApi; use sp_consensus_subspace::{FarmerPublicKey, FarmerSignature, SubspaceApi}; use sp_core::{Decode, Encode}; -use std::num::NonZeroUsize; +use std::num::{NonZeroU64, NonZeroUsize}; use std::sync::Arc; use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; use subspace_core_primitives::objects::BlockObjectMapping; @@ -40,10 +41,9 @@ use subspace_farmer_components::sector::{sector_size, SectorMetadata}; use subspace_farmer_components::FarmerProtocolInfo; use subspace_proof_of_space::Table; use subspace_runtime_primitives::opaque::Block; -use subspace_service::tx_pre_validator::PrimaryChainTxPreValidator; +use subspace_service::tx_pre_validator::ConsensusChainTxPreValidator; use subspace_service::{FullClient, NewFull}; use subspace_solving::REWARD_SIGNING_CONTEXT; -use subspace_transaction_pool::bundle_validator::BundleValidator; use zeroize::Zeroizing; // Smaller value for testing purposes @@ -53,8 +53,10 @@ const MAX_PIECES_IN_SECTOR: u16 = 32; pub struct TestExecutorDispatch; impl sc_executor::NativeExecutionDispatch for TestExecutorDispatch { - /// Otherwise we only use the default Substrate host functions. - type ExtendHostFunctions = sp_consensus_subspace::consensus::HostFunctions; + type ExtendHostFunctions = ( + sp_consensus_subspace::consensus::HostFunctions, + sp_domains::domain::HostFunctions, + ); fn dispatch(method: &str, data: &[u8]) -> Option> { subspace_test_runtime::api::dispatch(method, data) @@ -75,8 +77,7 @@ pub type Backend = sc_service::TFullBackend; pub type FraudProofVerifier = subspace_service::FraudProofVerifier; -type TxPreValidator = - PrimaryChainTxPreValidator>; +type TxPreValidator = ConsensusChainTxPreValidator; /// Run a farmer. pub fn start_farmer(new_full: &NewFull) @@ -148,24 +149,28 @@ async fn start_farming( ) .unwrap(); + let table_generator = PosTable::generator(); + std::thread::spawn({ let keypair = keypair.clone(); let erasure_coding = erasure_coding.clone(); move || { - let (sector, sector_metadata) = block_on(plot_one_segment::( - client.as_ref(), - &keypair, - MAX_PIECES_IN_SECTOR, - &erasure_coding, - )); + let (sector, sector_metadata, table_generator) = + block_on(plot_one_segment::( + client.as_ref(), + &keypair, + MAX_PIECES_IN_SECTOR, + &erasure_coding, + table_generator, + )); plotting_result_sender - .send((sector, sector_metadata)) + .send((sector, sector_metadata, table_generator)) .unwrap(); } }); - let (sector, plotted_sector) = plotting_result_receiver.await.unwrap(); + let (sector, plotted_sector, mut table_generator) = plotting_result_receiver.await.unwrap(); let sector_index = 0; let public_key = PublicKey::from(keypair.public.to_bytes()); @@ -177,10 +182,13 @@ async fn start_farming( }) = new_slot_notification_stream.next().await { if u64::from(new_slot_info.slot) % 2 == 0 { + let global_challenge = new_slot_info + .global_randomness + .derive_global_challenge(new_slot_info.slot.into()); let solution_candidates = audit_sector( &public_key, sector_index, - &new_slot_info.global_challenge, + &global_challenge, new_slot_info.solution_range, §or, &plotted_sector.sector_metadata, @@ -188,7 +196,7 @@ async fn start_farming( .expect("With max solution range there must be a sector eligible; qed"); let solution = solution_candidates - .into_iter::<_, PosTable>(&public_key, &kzg, &erasure_coding) + .into_iter::<_, PosTable>(&public_key, &kzg, &erasure_coding, &mut table_generator) .unwrap() .next() .expect("With max solution range there must be a solution; qed") @@ -208,7 +216,8 @@ async fn plot_one_segment( keypair: &schnorrkel::Keypair, pieces_in_sector: u16, erasure_coding: &ErasureCoding, -) -> (Vec, PlottedSector) + mut table_generator: PosTable::Generator, +) -> (Vec, PlottedSector, PosTable::Generator) where PosTable: Table, Client: BlockBackend + HeaderBackend, @@ -219,25 +228,28 @@ where let genesis_block = client.block(client.info().genesis_hash).unwrap().unwrap(); let archived_segment = archiver - .add_block(genesis_block.encode(), BlockObjectMapping::default()) + .add_block(genesis_block.encode(), BlockObjectMapping::default(), true) .into_iter() .next() .expect("First block is always producing one segment; qed"); let history_size = HistorySize::from(SegmentIndex::ZERO); let mut sector = vec![0u8; sector_size(pieces_in_sector)]; let mut sector_metadata = vec![0u8; SectorMetadata::encoded_size()]; - let sector_offset = 0; let sector_index = 0; let public_key = PublicKey::from(keypair.public.to_bytes()); let farmer_protocol_info = FarmerProtocolInfo { history_size, max_pieces_in_sector: pieces_in_sector, - sector_expiration: SegmentIndex::from(100), + recent_segments: HistorySize::from(NonZeroU64::new(5).unwrap()), + recent_history_fraction: ( + HistorySize::from(NonZeroU64::new(1).unwrap()), + HistorySize::from(NonZeroU64::new(10).unwrap()), + ), + min_sector_lifetime: HistorySize::from(NonZeroU64::new(4).unwrap()), }; let plotted_sector = plot_sector::<_, PosTable>( &public_key, - sector_offset, sector_index, &archived_segment.pieces, PieceGetterRetryPolicy::default(), @@ -247,10 +259,10 @@ where pieces_in_sector, &mut sector, &mut sector_metadata, - Default::default(), + &mut table_generator, ) .await .expect("Plotting one sector in memory must not fail"); - (sector, plotted_sector) + (sector, plotted_sector, table_generator) } diff --git a/test/subspace-test-runtime/Cargo.toml b/test/subspace-test-runtime/Cargo.toml index 02760d3493a..564ece531c7 100644 --- a/test/subspace-test-runtime/Cargo.toml +++ b/test/subspace-test-runtime/Cargo.toml @@ -16,62 +16,57 @@ include = [ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.6.3", default-features = false, features = ["derive"] } domain-runtime-primitives = { version = "0.1.0", default-features = false, path = "../../domains/primitives/runtime" } -frame-executive = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-executive = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } hex-literal = { version = "0.4.0", optional = true } orml-vesting = { version = "0.4.1-dev", default-features = false, path = "../../orml/vesting" } -pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } pallet-domains = { version = "0.1.0", default-features = false, path = "../../crates/pallet-domains" } pallet-feeds = { version = "0.1.0", default-features = false, path = "../../crates/pallet-feeds" } pallet-grandpa-finality-verifier = { version = "0.1.0", default-features = false, path = "../../crates/pallet-grandpa-finality-verifier" } pallet-object-store = { version = "0.1.0", default-features = false, path = "../../crates/pallet-object-store" } pallet-offences-subspace = { version = "0.1.0", default-features = false, path = "../../crates/pallet-offences-subspace" } -pallet-settlement = { version = "0.1.0", default-features = false, path = "../../crates/pallet-settlement" } pallet-rewards = { version = "0.1.0", default-features = false, path = "../../crates/pallet-rewards" } pallet-subspace = { version = "0.1.0", default-features = false, features = ["serde"], path = "../../crates/pallet-subspace" } -pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-sudo = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } pallet-transaction-fees = { version = "0.1.0", default-features = false, path = "../../crates/pallet-transaction-fees" } -pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-utility = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-utility = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } scale-info = { version = "2.7.0", default-features = false, features = ["derive"] } -sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-block-builder = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false, version = "4.0.0-dev"} -sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-block-builder = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false, version = "4.0.0-dev"} +sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-consensus-subspace = { version = "0.1.0", default-features = false, path = "../../crates/sp-consensus-subspace" } -sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", default-features = false, path = "../../crates/sp-domains" } -sp-inherents = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false, version = "4.0.0-dev"} +sp-inherents = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false, version = "4.0.0-dev"} sp-objects = { version = "0.1.0", default-features = false, path = "../../crates/sp-objects" } -sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-settlement = { version = "0.1.0", default-features = false, path = "../../crates/sp-settlement" } -sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-offchain = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { version = "24.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-session = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-std = { version = "8.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-transaction-pool = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-version = { version = "22.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../../crates/subspace-core-primitives" } subspace-runtime-primitives = { version = "0.1.0", default-features = false, path = "../../crates/subspace-runtime-primitives" } subspace-verification = { version = "0.1.0", default-features = false, path = "../../crates/subspace-verification" } -system-domain-test-runtime = { version = "0.1.0", default-features = false, path = "../../domains/test/runtime/system" } # Used for the node template's RPCs -frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } [build-dependencies] -subspace-wasm-tools = { version = "0.1.0", path = "../../crates/subspace-wasm-tools" } -substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", optional = true } +substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", optional = true } [features] default = ["std"] std = [ "codec/std", "domain-runtime-primitives/std", - "system-domain-test-runtime/std", "frame-executive/std", "frame-support/std", "frame-system/std", @@ -83,7 +78,6 @@ std = [ "pallet-grandpa-finality-verifier/std", "pallet-object-store/std", "pallet-offences-subspace/std", - "pallet-settlement/std", "pallet-rewards/std", "pallet-subspace/std", "pallet-sudo/std", @@ -104,7 +98,6 @@ std = [ "sp-offchain/std", "sp-runtime/std", "sp-session/std", - "sp-settlement/std", "sp-std/std", "sp-transaction-pool/std", "sp-version/std", diff --git a/test/subspace-test-runtime/build.rs b/test/subspace-test-runtime/build.rs index 1fc5b77977e..e2217a8dda5 100644 --- a/test/subspace-test-runtime/build.rs +++ b/test/subspace-test-runtime/build.rs @@ -15,13 +15,6 @@ // along with this program. If not, see . fn main() { - subspace_wasm_tools::create_runtime_bundle_inclusion_file( - "system-domain-test-runtime", - "TEST_DOMAIN_WASM_BUNDLE", - None, - "test_system_domain_wasm_bundle.rs", - ); - #[cfg(feature = "std")] { substrate_wasm_builder::WasmBuilder::new() diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index 05b18c54034..9bc7bdc6946 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -19,30 +19,27 @@ // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] -// Make `system-domain-test-runtime` WASM runtime available. -include!(concat!( - env!("OUT_DIR"), - "/test_system_domain_wasm_bundle.rs" -)); - // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use codec::{Compact, CompactLen, Encode}; +use codec::{Compact, CompactLen, Decode, Encode, MaxEncodedLen}; +use core::num::NonZeroU64; +use domain_runtime_primitives::{BlockNumber as DomainNumber, Hash as DomainHash}; use frame_support::traits::{ ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons, }; use frame_support::weights::constants::{RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND}; use frame_support::weights::{ConstantMultiplier, IdentityFee, Weight}; -use frame_support::{construct_runtime, parameter_types}; +use frame_support::{construct_runtime, parameter_types, PalletId}; use frame_system::limits::{BlockLength, BlockWeights}; use frame_system::EnsureNever; use pallet_balances::NegativeImbalance; use pallet_feeds::feed_processor::{FeedMetadata, FeedObjectMapping, FeedProcessor}; use pallet_grandpa_finality_verifier::chain::Chain; pub use pallet_subspace::AllowAuthoringBy; +use scale_info::TypeInfo; use sp_api::{impl_runtime_apis, BlockT, HashT, HeaderT}; use sp_consensus_slots::SlotDuration; use sp_consensus_subspace::digests::CompatibleDigestItem; @@ -52,11 +49,16 @@ use sp_consensus_subspace::{ }; use sp_core::crypto::{ByteArray, KeyTypeId}; use sp_core::{Hasher, OpaqueMetadata, H256}; +use sp_domains::bundle_producer_election::BundleProducerElectionParams; use sp_domains::fraud_proof::FraudProof; use sp_domains::transaction::PreValidationObject; -use sp_domains::{DomainId, ExecutionReceipt, OpaqueBundle}; +use sp_domains::{ + DomainId, DomainInstanceData, DomainsHoldIdentifier, ExecutionReceipt, OpaqueBundle, + OpaqueBundles, OperatorId, OperatorPublicKey, StakingHoldIdentifier, +}; use sp_runtime::traits::{ - AccountIdLookup, BlakeTwo256, DispatchInfoOf, NumberFor, PostDispatchInfoOf, Zero, + AccountIdConversion, AccountIdLookup, BlakeTwo256, DispatchInfoOf, NumberFor, + PostDispatchInfoOf, Zero, }; use sp_runtime::transaction_validity::{ InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, @@ -64,7 +66,6 @@ use sp_runtime::transaction_validity::{ use sp_runtime::{ create_runtime_str, generic, AccountId32, ApplyExtrinsicResult, DispatchError, Perbill, }; -use sp_std::borrow::Cow; use sp_std::iter::Peekable; use sp_std::marker::PhantomData; use sp_std::prelude::*; @@ -74,6 +75,7 @@ use sp_version::RuntimeVersion; use subspace_core_primitives::objects::{BlockObject, BlockObjectMapping}; use subspace_core_primitives::{ HistorySize, Piece, Randomness, SegmentCommitment, SegmentHeader, SegmentIndex, SolutionRange, + U256, }; use subspace_runtime_primitives::{ opaque, AccountId, Balance, BlockNumber, Hash, Index, Moment, Signature, @@ -164,6 +166,10 @@ const INITIAL_SOLUTION_RANGE: SolutionRange = SolutionRange::MAX; /// A ratio of `Normal` dispatch class within block, for `BlockWeight` and `BlockLength`. const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +/// The block weight for 2 seconds of compute +const BLOCK_WEIGHT_FOR_2_SEC: Weight = + Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX); + /// Maximum block length for non-`Normal` extrinsic is 5 MiB. const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; @@ -173,7 +179,7 @@ parameter_types! { pub const Version: RuntimeVersion = VERSION; pub const BlockHashCount: BlockNumber = 2400; /// We allow for 2 seconds of compute with a 6 second average block time. - pub SubspaceBlockWeights: BlockWeights = BlockWeights::with_sensible_defaults(Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX), NORMAL_DISPATCH_RATIO); + pub SubspaceBlockWeights: BlockWeights = BlockWeights::with_sensible_defaults(BLOCK_WEIGHT_FOR_2_SEC, NORMAL_DISPATCH_RATIO); /// We allow for 3.75 MiB for `Normal` extrinsic with 5 MiB maximum block length. pub SubspaceBlockLength: BlockLength = BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO); } @@ -240,6 +246,12 @@ parameter_types! { pub const ShouldAdjustSolutionRange: bool = false; pub const ExpectedVotesPerBlock: u32 = 9; pub const ConfirmationDepthK: u32 = 100; + pub const RecentSegments: HistorySize = HistorySize::new(NonZeroU64::new(5).unwrap()); + pub const RecentHistoryFraction: (HistorySize, HistorySize) = ( + HistorySize::new(NonZeroU64::new(1).unwrap()), + HistorySize::new(NonZeroU64::new(10).unwrap()), + ); + pub const MinSectorLifetime: HistorySize = HistorySize::new(NonZeroU64::new(4).unwrap()); } impl pallet_subspace::Config for Runtime { @@ -250,6 +262,9 @@ impl pallet_subspace::Config for Runtime { type SlotProbability = SlotProbability; type ExpectedBlockTime = ExpectedBlockTime; type ConfirmationDepthK = ConfirmationDepthK; + type RecentSegments = RecentSegments; + type RecentHistoryFraction = RecentHistoryFraction; + type MinSectorLifetime = MinSectorLifetime; type ExpectedVotesPerBlock = ExpectedVotesPerBlock; type MaxPiecesInSector = ConstU16<{ MAX_PIECES_IN_SECTOR }>; type ShouldAdjustSolutionRange = ShouldAdjustSolutionRange; @@ -272,6 +287,41 @@ impl pallet_timestamp::Config for Runtime { type WeightInfo = (); } +#[derive( + PartialEq, Eq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, Ord, PartialOrd, Copy, Debug, +)] +pub enum HoldIdentifier { + Domains(DomainsHoldIdentifier), +} + +impl pallet_domains::HoldIdentifier for HoldIdentifier { + fn staking_pending_deposit(operator_id: OperatorId) -> Self { + Self::Domains(DomainsHoldIdentifier::Staking( + StakingHoldIdentifier::PendingDeposit(operator_id), + )) + } + + fn staking_staked(operator_id: OperatorId) -> Self { + Self::Domains(DomainsHoldIdentifier::Staking( + StakingHoldIdentifier::Staked(operator_id), + )) + } + + fn staking_pending_unlock(operator_id: OperatorId) -> Self { + Self::Domains(DomainsHoldIdentifier::Staking( + StakingHoldIdentifier::PendingUnlock(operator_id), + )) + } + + fn domain_instantiation_id(domain_id: DomainId) -> Self { + Self::Domains(DomainsHoldIdentifier::DomainInstantiation(domain_id)) + } +} + +parameter_types! { + pub const MaxHolds: u32 = 10; +} + impl pallet_balances::Config for Runtime { type MaxLocks = ConstU32<50>; type MaxReserves = (); @@ -287,8 +337,8 @@ impl pallet_balances::Config for Runtime { type WeightInfo = pallet_balances::weights::SubstrateWeight; type FreezeIdentifier = (); type MaxFreezes = (); - type RuntimeHoldReason = (); - type MaxHolds = (); + type RuntimeHoldReason = HoldIdentifier; + type MaxHolds = MaxHolds; } parameter_types! { @@ -476,21 +526,47 @@ impl pallet_offences_subspace::Config for Runtime { } parameter_types! { - pub const ReceiptsPruningDepth: BlockNumber = 256; pub const MaximumReceiptDrift: BlockNumber = 2; + pub const InitialDomainTxRange: u64 = 10; + pub const DomainTxRangeAdjustmentInterval: u64 = 100; + pub const DomainRuntimeUpgradeDelay: BlockNumber = 10; + pub const MinOperatorStake: Balance = 100 * SSC; + /// Use the consensus chain's `Normal` extrinsics block size limit as the domain block size limit + pub MaxDomainBlockSize: u32 = NORMAL_DISPATCH_RATIO * MAX_BLOCK_LENGTH; + /// Use the consensus chain's `Normal` extrinsics block weight limit as the domain block weight limit + pub MaxDomainBlockWeight: Weight = NORMAL_DISPATCH_RATIO * BLOCK_WEIGHT_FOR_2_SEC; + pub const MaxBundlesPerBlock: u32 = 10; + pub const DomainInstantiationDeposit: Balance = 100 * SSC; + pub const MaxDomainNameLength: u32 = 32; + pub const BlockTreePruningDepth: u32 = 16; + pub const StakeWithdrawalLockingPeriod: BlockNumber = 20; + pub const StakeEpochDuration: DomainNumber = 5; + pub TreasuryAccount: AccountId = PalletId(*b"treasury").into_account_truncating(); } impl pallet_domains::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type DomainNumber = DomainNumber; + type DomainHash = DomainHash; type ConfirmationDepthK = ConfirmationDepthK; + type DomainRuntimeUpgradeDelay = DomainRuntimeUpgradeDelay; + type Currency = Balances; + type HoldIdentifier = HoldIdentifier; type WeightInfo = pallet_domains::weights::SubstrateWeight; -} - -impl pallet_settlement::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type DomainHash = domain_runtime_primitives::Hash; - type MaximumReceiptDrift = MaximumReceiptDrift; - type ReceiptsPruningDepth = ReceiptsPruningDepth; + type InitialDomainTxRange = InitialDomainTxRange; + type DomainTxRangeAdjustmentInterval = DomainTxRangeAdjustmentInterval; + type MinOperatorStake = MinOperatorStake; + type MaxDomainBlockSize = MaxDomainBlockSize; + type MaxDomainBlockWeight = MaxDomainBlockWeight; + type MaxBundlesPerBlock = MaxBundlesPerBlock; + type DomainInstantiationDeposit = DomainInstantiationDeposit; + type MaxDomainNameLength = MaxDomainNameLength; + type Share = Balance; + type BlockTreePruningDepth = BlockTreePruningDepth; + type StakeWithdrawalLockingPeriod = StakeWithdrawalLockingPeriod; + type StakeEpochDuration = StakeEpochDuration; + type TreasuryAccount = TreasuryAccount; + type DomainBlockReward = BlockReward; } parameter_types! { @@ -506,6 +582,7 @@ impl pallet_rewards::Config for Runtime { type FindBlockRewardAddress = Subspace; type FindVotingRewardAddresses = Subspace; type WeightInfo = (); + type OnReward = (); } /// Polkadot-like chain. @@ -614,7 +691,6 @@ construct_runtime!( Feeds: pallet_feeds = 6, GrandpaFinalityVerifier: pallet_grandpa_finality_verifier = 13, ObjectStore: pallet_object_store = 10, - Settlement: pallet_settlement = 14, Domains: pallet_domains = 11, Vesting: orml_vesting = 7, @@ -840,39 +916,11 @@ fn extract_block_object_mapping(block: Block, successful_calls: Vec) -> Bl block_object_mapping } -fn extract_system_bundles( - extrinsics: Vec, -) -> ( - sp_domains::OpaqueBundles, - sp_domains::OpaqueBundles, -) { - let successful_bundles = Domains::successful_bundles(); - let (system_bundles, core_bundles): (Vec<_>, Vec<_>) = extrinsics - .into_iter() - .filter_map(|uxt| match uxt.function { - RuntimeCall::Domains(pallet_domains::Call::submit_bundle { opaque_bundle }) - if successful_bundles.contains(&opaque_bundle.hash()) => - { - if opaque_bundle.domain_id().is_system() { - Some((Some(opaque_bundle), None)) - } else { - Some((None, Some(opaque_bundle))) - } - } - _ => None, - }) - .unzip(); - ( - system_bundles.into_iter().flatten().collect(), - core_bundles.into_iter().flatten().collect(), - ) -} - -fn extract_core_bundles( - extrinsics: Vec, +fn extract_successful_bundles( domain_id: DomainId, -) -> sp_domains::OpaqueBundles { - let successful_bundles = Domains::successful_bundles(); + extrinsics: Vec, +) -> OpaqueBundles { + let successful_bundles = Domains::successful_bundles(domain_id); extrinsics .into_iter() .filter_map(|uxt| match uxt.function { @@ -887,11 +935,13 @@ fn extract_core_bundles( .collect() } +// TODO: Remove when proceeding to fraud proof v2. +#[allow(unused)] fn extract_receipts( extrinsics: Vec, domain_id: DomainId, -) -> Vec> { - let successful_bundles = Domains::successful_bundles(); +) -> Vec> { + let successful_bundles = Domains::successful_bundles(domain_id); extrinsics .into_iter() .filter_map(|uxt| match uxt.function { @@ -899,26 +949,27 @@ fn extract_receipts( if opaque_bundle.domain_id() == domain_id && successful_bundles.contains(&opaque_bundle.hash()) => { - Some(opaque_bundle.receipt) + Some(opaque_bundle.into_receipt()) } _ => None, }) .collect() } +// TODO: Remove when proceeding to fraud proof v2. +#[allow(unused)] fn extract_fraud_proofs( extrinsics: Vec, domain_id: DomainId, ) -> Vec, Hash>> { - let successful_fraud_proofs = Settlement::successful_fraud_proofs(); + // TODO: Ensure fraud proof extrinsic is infallible. extrinsics .into_iter() .filter_map(|uxt| match uxt.function { RuntimeCall::Domains(pallet_domains::Call::submit_fraud_proof { fraud_proof }) - if fraud_proof.domain_id() == domain_id - && successful_fraud_proofs.contains(&fraud_proof.hash()) => + if fraud_proof.domain_id() == domain_id => { - Some(fraud_proof) + Some(*fraud_proof) } _ => None, }) @@ -927,10 +978,10 @@ fn extract_fraud_proofs( fn extract_pre_validation_object( extrinsic: UncheckedExtrinsic, -) -> PreValidationObject { +) -> PreValidationObject { match extrinsic.function { RuntimeCall::Domains(pallet_domains::Call::submit_fraud_proof { fraud_proof }) => { - PreValidationObject::FraudProof(fraud_proof) + PreValidationObject::FraudProof(*fraud_proof) } RuntimeCall::Domains(pallet_domains::Call::submit_bundle { opaque_bundle }) => { PreValidationObject::Bundle(opaque_bundle) @@ -1140,103 +1191,80 @@ impl_runtime_apis! { } } - impl sp_settlement::SettlementApi for Runtime { - fn execution_trace(domain_id: DomainId, receipt_hash: H256) -> Vec { - Settlement::receipts(domain_id, receipt_hash).map(|receipt| receipt.trace).unwrap_or_default() - } - - fn state_root( - domain_id: DomainId, - domain_block_number: NumberFor, - domain_block_hash: Hash, - ) -> Option { - Settlement::state_root((domain_id, domain_block_number, domain_block_hash)) - } - - fn primary_hash(domain_id: DomainId, domain_block_number: BlockNumber) -> Option { - Settlement::primary_hash(domain_id, domain_block_number) + impl sp_domains::transaction::PreValidationObjectApi for Runtime { + fn extract_pre_validation_object( + extrinsic: ::Extrinsic, + ) -> sp_domains::transaction::PreValidationObject { + extract_pre_validation_object(extrinsic) } + } - fn receipts_pruning_depth() -> BlockNumber { - ReceiptsPruningDepth::get() + impl sp_domains::DomainsApi for Runtime { + fn submit_bundle_unsigned( + opaque_bundle: OpaqueBundle, ::Hash, DomainNumber, DomainHash, Balance>, + ) { + Domains::submit_bundle_unsigned(opaque_bundle) } - fn head_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::head_receipt_number(domain_id) + fn extract_successful_bundles( + domain_id: DomainId, + extrinsics: Vec<::Extrinsic>, + ) -> OpaqueBundles { + extract_successful_bundles(domain_id, extrinsics) } - fn oldest_receipt_number(domain_id: DomainId) -> NumberFor { - Settlement::oldest_receipt_number(domain_id) + fn extrinsics_shuffling_seed(header: ::Header) -> Randomness { + extrinsics_shuffling_seed::(header) } - fn maximum_receipt_drift() -> NumberFor { - MaximumReceiptDrift::get() + fn domain_runtime_code(domain_id: DomainId) -> Option> { + Domains::domain_runtime_code(domain_id) } - fn extract_receipts( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, ::Hash, domain_runtime_primitives::Hash>> { - extract_receipts(extrinsics, domain_id) + fn runtime_id(domain_id: DomainId) -> Option { + Domains::runtime_id(domain_id) } - fn extract_fraud_proofs( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> Vec, ::Hash>> { - extract_fraud_proofs(extrinsics, domain_id) + fn domain_instance_data(domain_id: DomainId) -> Option<(DomainInstanceData, NumberFor)> { + Domains::domain_instance_data(domain_id) } - fn submit_fraud_proof_unsigned(fraud_proof: FraudProof, ::Hash>) { - Domains::submit_fraud_proof_unsigned(fraud_proof) + fn timestamp() -> Moment{ + Timestamp::now() } - } - impl sp_domains::transaction::PreValidationObjectApi for Runtime { - fn extract_pre_validation_object( - extrinsic: ::Extrinsic, - )-> sp_domains::transaction::PreValidationObject { - extract_pre_validation_object(extrinsic) + fn domain_tx_range(_: DomainId) -> U256 { + U256::MAX } - } - impl sp_domains::ExecutorApi for Runtime { - fn submit_bundle_unsigned( - opaque_bundle: OpaqueBundle, ::Hash, domain_runtime_primitives::Hash>, - ) { - Domains::submit_bundle_unsigned(opaque_bundle) + fn genesis_state_root(domain_id: DomainId) -> Option { + Domains::genesis_state_root(domain_id) } - fn extract_system_bundles( - extrinsics: Vec<::Extrinsic>, - ) -> ( - sp_domains::OpaqueBundles, - sp_domains::OpaqueBundles, - ) { - extract_system_bundles(extrinsics) + fn head_receipt_number(domain_id: DomainId) -> NumberFor { + Domains::head_receipt_number(domain_id) } - fn extract_core_bundles( - extrinsics: Vec<::Extrinsic>, - domain_id: DomainId, - ) -> sp_domains::OpaqueBundles { - extract_core_bundles(extrinsics, domain_id) + fn oldest_receipt_number(domain_id: DomainId) -> NumberFor { + Domains::oldest_receipt_number(domain_id) } - fn successful_bundle_hashes() -> Vec { - Domains::successful_bundles() + fn block_tree_pruning_depth() -> NumberFor { + Domains::block_tree_pruning_depth() } - fn extrinsics_shuffling_seed(header: ::Header) -> Randomness { - extrinsics_shuffling_seed::(header) + fn domain_block_limit(domain_id: DomainId) -> Option { + Domains::domain_block_limit(domain_id) } + } - fn system_domain_wasm_bundle() -> Cow<'static, [u8]> { - TEST_DOMAIN_WASM_BUNDLE.into() + impl sp_domains::BundleProducerElectionApi for Runtime { + fn bundle_producer_election_params(domain_id: DomainId) -> Option> { + Domains::bundle_producer_election_params(domain_id) } - fn timestamp() -> Moment{ - Timestamp::now() + fn operator(operator_id: OperatorId) -> Option<(OperatorPublicKey, Balance)> { + Domains::operator(operator_id) } } diff --git a/test/subspace-test-service/Cargo.toml b/test/subspace-test-service/Cargo.toml index a8a8a147458..9bf243f89c5 100644 --- a/test/subspace-test-service/Cargo.toml +++ b/test/subspace-test-service/Cargo.toml @@ -18,38 +18,41 @@ targets = ["x86_64-unknown-linux-gnu"] async-trait = "0.1.68" cross-domain-message-gossip = { version = "0.1.0", path = "../../domains/client/cross-domain-message-gossip" } codec = { package = "parity-scale-codec", version = "3.2.1", features = ["derive"] } +domain-runtime-primitives = { version = "0.1.0", path = "../../domains/primitives/runtime" } futures = "0.3.28" futures-timer = "3.0.1" jsonrpsee = { version = "0.16.2", features = ["server"] } rand = "0.8.5" pallet-domains = { version = "0.1.0", path = "../../crates/pallet-domains" } parking_lot = "0.12.1" -sc-block-builder = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-client-api = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-executor = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-block-builder = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-client-api = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-consensus = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-executor = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sc-consensus-fraud-proof = { version = "0.1.0", path = "../../crates/sc-consensus-fraud-proof" } -sc-network = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-service = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f", default-features = false } -sc-tracing = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-application-crypto = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-blockchain = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-consensus = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sc-network = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-network-sync = { version = "0.10.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-service = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71", default-features = false } +sc-tracing = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sc-utils = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-application-crypto = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-blockchain = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-core = { version = "21.0.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-consensus = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-consensus-subspace = { version = "0.1.0", path = "../../crates/sp-consensus-subspace" } -sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } sp-domains = { version = "0.1.0", path = "../../crates/sp-domains" } -sp-keyring = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } -sp-runtime = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-externalities = { version = "0.19.0", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-keyring = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-inherents = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } +sp-runtime = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../../crates/subspace-core-primitives" } subspace-fraud-proof = { path = "../../crates/subspace-fraud-proof" } +subspace-node = { path = "../../crates/subspace-node" } subspace-runtime-primitives = { path = "../../crates/subspace-runtime-primitives" } subspace-service = { path = "../../crates/subspace-service" } subspace-test-client = { path = "../subspace-test-client" } @@ -59,4 +62,4 @@ tokio = "1.28.2" tracing = "0.1.37" [dev-dependencies] -sp-keyring = { git = "https://github.com/subspace/substrate", rev = "28e33f78a3aa8ac4c6753108bc0471273ff6bf6f" } +sp-keyring = { git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" } diff --git a/test/subspace-test-service/src/lib.rs b/test/subspace-test-service/src/lib.rs index 53b379e84e9..6fc5f54e7bb 100644 --- a/test/subspace-test-service/src/lib.rs +++ b/test/subspace-test-service/src/lib.rs @@ -20,13 +20,14 @@ use codec::{Decode, Encode}; use cross_domain_message_gossip::GossipWorkerBuilder; +use domain_runtime_primitives::BlockNumber as DomainNumber; use futures::channel::mpsc; -use futures::{select, FutureExt, SinkExt, StreamExt}; +use futures::{select, FutureExt, StreamExt}; use jsonrpsee::RpcModule; use parking_lot::Mutex; use sc_block_builder::BlockBuilderProvider; -use sc_client_api::execution_extensions::ExecutionStrategies; -use sc_client_api::{backend, BlockchainEvents}; +use sc_client_api::execution_extensions::{ExecutionStrategies, ExtensionsFactory}; +use sc_client_api::{backend, ExecutorProvider}; use sc_consensus::block_import::{ BlockCheckParams, BlockImportParams, ForkChoiceStrategy, ImportResult, }; @@ -55,7 +56,8 @@ use sp_consensus_subspace::digests::{CompatibleDigestItem, PreDigest}; use sp_consensus_subspace::FarmerPublicKey; use sp_core::traits::SpawnEssentialNamed; use sp_core::H256; -use sp_domains::OpaqueBundle; +use sp_domains::{GenerateGenesisStateRoot, GenesisReceiptExtension, OpaqueBundle}; +use sp_externalities::Extensions; use sp_inherents::{InherentData, InherentDataProvider}; use sp_keyring::Sr25519Keyring; use sp_runtime::generic::{BlockId, Digest}; @@ -66,18 +68,17 @@ use std::error::Error; use std::marker::PhantomData; use std::sync::Arc; use std::time; -use subspace_core_primitives::{Blake2b256Hash, Solution}; -use subspace_fraud_proof::domain_extrinsics_builder::SystemDomainExtrinsicsBuilder; +use subspace_core_primitives::{Randomness, Solution}; use subspace_fraud_proof::invalid_state_transition_proof::InvalidStateTransitionProofVerifier; use subspace_fraud_proof::invalid_transaction_proof::InvalidTransactionProofVerifier; use subspace_fraud_proof::verifier_api::VerifierClient; +use subspace_node::domain::DomainGenesisBlockBuilder; use subspace_runtime_primitives::opaque::Block; -use subspace_runtime_primitives::{AccountId, Hash}; -use subspace_service::tx_pre_validator::PrimaryChainTxPreValidator; +use subspace_runtime_primitives::{AccountId, Balance, Hash}; +use subspace_service::tx_pre_validator::ConsensusChainTxPreValidator; use subspace_service::FullSelectChain; use subspace_test_client::{chain_spec, Backend, Client, FraudProofVerifier, TestExecutorDispatch}; use subspace_test_runtime::{RuntimeApi, RuntimeCall, UncheckedExtrinsic, SLOT_DURATION}; -use subspace_transaction_pool::bundle_validator::BundleValidator; use subspace_transaction_pool::FullPool; /// Create a Subspace `Configuration`. @@ -178,11 +179,28 @@ pub fn node_config( type StorageChanges = sp_api::StorageChanges, Block>; -type TxPreValidator = - PrimaryChainTxPreValidator>; +type TxPreValidator = ConsensusChainTxPreValidator; -/// A mock Subspace primary node instance used for testing. -pub struct MockPrimaryNode { +struct MockExtensionsFactory(Arc); + +impl ExtensionsFactory for MockExtensionsFactory +where + Block: BlockT, +{ + fn extensions_for( + &self, + _block_hash: Block::Hash, + _block_number: NumberFor, + _capabilities: sp_core::offchain::Capabilities, + ) -> Extensions { + let mut exts = Extensions::new(); + exts.register(GenesisReceiptExtension::new(self.0.clone())); + exts + } +} + +/// A mock Subspace consensus node instance used for testing. +pub struct MockConsensusNode { /// `TaskManager`'s instance. pub task_manager: TaskManager, /// Client's instance. @@ -208,11 +226,11 @@ pub struct MockPrimaryNode { /// The slot notification subscribers #[allow(clippy::type_complexity)] new_slot_notification_subscribers: - Vec>)>>, + Vec>)>>, /// Block import pipeline #[allow(clippy::type_complexity)] block_import: MockBlockImport< - FraudProofBlockImport, FraudProofVerifier, H256>, + FraudProofBlockImport, FraudProofVerifier, DomainNumber, H256>, Client, Block, >, @@ -222,13 +240,13 @@ pub struct MockPrimaryNode { log_prefix: &'static str, } -impl MockPrimaryNode { - /// Run a mock primary node - pub fn run_mock_primary_node( +impl MockConsensusNode { + /// Run a mock consensus node + pub fn run( tokio_handle: tokio::runtime::Handle, key: Sr25519Keyring, base_path: BasePath, - ) -> MockPrimaryNode { + ) -> MockConsensusNode { let log_prefix = key.into(); let mut config = node_config(tokio_handle, key, vec![], false, false, false, base_path); @@ -237,7 +255,7 @@ impl MockPrimaryNode { // by `TemporarilyBanned` config.transaction_pool.ban_time = time::Duration::from_millis(0); - config.network.node_name = format!("{} (MockPrimaryChain)", config.network.node_name); + config.network.node_name = format!("{} (Consensus)", config.network.node_name); let span = sc_tracing::tracing::info_span!( sc_tracing::logging::PREFIX_LOG_SPAN, name = config.network.node_name.as_str() @@ -250,27 +268,26 @@ impl MockPrimaryNode { sc_service::new_full_parts::(&config, None, executor.clone()) .expect("Fail to new full parts"); + client + .execution_extensions() + .set_extensions_factory(MockExtensionsFactory(Arc::new( + DomainGenesisBlockBuilder::new(backend.clone(), executor.clone()), + ))); + let client = Arc::new(client); let select_chain = sc_consensus::LongestChain::new(backend.clone()); - let mut bundle_validator = BundleValidator::new(client.clone()); - - let domain_extrinsics_builder = - SystemDomainExtrinsicsBuilder::new(client.clone(), Arc::new(executor.clone())); - let invalid_transaction_proof_verifier = InvalidTransactionProofVerifier::new( client.clone(), Arc::new(executor.clone()), VerifierClient::new(client.clone()), - domain_extrinsics_builder.clone(), ); let invalid_state_transition_proof_verifier = InvalidStateTransitionProofVerifier::new( client.clone(), executor.clone(), VerifierClient::new(client.clone()), - domain_extrinsics_builder, ); let proof_verifier = subspace_fraud_proof::ProofVerifier::new( @@ -278,11 +295,10 @@ impl MockPrimaryNode { Arc::new(invalid_state_transition_proof_verifier), ); - let tx_pre_validator = PrimaryChainTxPreValidator::new( + let tx_pre_validator = ConsensusChainTxPreValidator::new( client.clone(), Box::new(task_manager.spawn_handle()), proof_verifier.clone(), - bundle_validator.clone(), ); let transaction_pool = subspace_transaction_pool::new_full( @@ -295,7 +311,7 @@ impl MockPrimaryNode { let fraud_proof_block_import = sc_consensus_fraud_proof::block_import(client.clone(), client.clone(), proof_verifier); - let mut block_import = MockBlockImport::<_, _, _>::new(fraud_proof_block_import); + let block_import = MockBlockImport::<_, _, _>::new(fraud_proof_block_import); let net_config = sc_network::config::FullNetworkConfiguration::new(&config.network); @@ -332,46 +348,12 @@ impl MockPrimaryNode { }) .expect("Should be able to spawn tasks"); - // The `maintain-bundles-stored-in-last-k` worker here is different from the one in the production code - // that it subscribes the `block_importing_notification_stream`, which is intended to ensure the bundle - // validator's `recent_stored_bundles` info must be updated when a new primary block is produced, this - // will help the test to be more deterministic. - let mut imported_blocks_stream = client.import_notification_stream(); - let mut block_importing_stream = block_import.block_importing_notification_stream(); - task_manager.spawn_handle().spawn( - "maintain-bundles-stored-in-last-k", - None, - Box::pin(async move { - loop { - tokio::select! { - biased; - maybe_block_imported = imported_blocks_stream.next() => { - match maybe_block_imported { - Some(block) => if block.is_new_best { - bundle_validator.update_recent_stored_bundles(block.hash); - } - None => break, - } - }, - maybe_block_importing = block_importing_stream.next() => { - match maybe_block_importing { - Some((_, mut acknowledgement_sender)) => { - let _ = acknowledgement_sender.send(()).await; - } - None => break, - } - } - } - } - }), - ); - let mock_solution = Solution::genesis_solution( FarmerPublicKey::unchecked_from(key.public().0), key.to_account_id(), ); - MockPrimaryNode { + MockConsensusNode { task_manager, client, backend, @@ -391,11 +373,11 @@ impl MockPrimaryNode { } } - /// Start the mock primary node network + /// Start the mock consensus node network pub fn start_network(&mut self) { self.network_starter .take() - .expect("mock primary node network have not started yet") + .expect("mock consensus node network have not started yet") .start_network(); } @@ -439,7 +421,7 @@ impl MockPrimaryNode { pub async fn notify_new_slot_and_wait_for_bundle( &mut self, slot: Slot, - ) -> Option, Hash, H256>> { + ) -> Option, Hash, DomainNumber, H256, Balance>> { let (slot_acknowledgement_sender, mut slot_acknowledgement_receiver) = mpsc::channel(0); // Must drop `slot_acknowledgement_sender` after the notification otherwise the receiver @@ -447,7 +429,7 @@ impl MockPrimaryNode { { let value = ( slot, - Hash::random().into(), + Randomness::from(Hash::random().to_fixed_bytes()), Some(slot_acknowledgement_sender), ); self.new_slot_notification_subscribers @@ -473,7 +455,10 @@ impl MockPrimaryNode { /// Produce a new slot and wait for a bundle produced at this slot. pub async fn produce_slot_and_wait_for_bundle_submission( &mut self, - ) -> (Slot, Option, Hash, H256>>) { + ) -> ( + Slot, + Option, Hash, DomainNumber, H256, Balance>>, + ) { let slot = self.produce_slot(); let bundle = self.notify_new_slot_and_wait_for_bundle(slot).await; @@ -484,7 +469,7 @@ impl MockPrimaryNode { /// Subscribe the new slot notification pub fn new_slot_notification_stream( &mut self, - ) -> TracingUnboundedReceiver<(Slot, Blake2b256Hash, Option>)> { + ) -> TracingUnboundedReceiver<(Slot, Randomness, Option>)> { let (tx, rx) = tracing_unbounded("subspace_new_slot_notification_stream", 100); self.new_slot_notification_subscribers.push(tx); rx @@ -501,14 +486,14 @@ impl MockPrimaryNode { pub fn get_bundle_from_tx_pool( &self, slot: u64, - ) -> Option, Hash, H256>> { + ) -> Option, Hash, DomainNumber, H256, Balance>> { for ready_tx in self.transaction_pool.ready() { let ext = UncheckedExtrinsic::decode(&mut ready_tx.data.encode().as_slice()) .expect("should be able to decode"); if let RuntimeCall::Domains(pallet_domains::Call::submit_bundle { opaque_bundle }) = ext.function { - if opaque_bundle.sealed_header.header.slot_number == slot { + if opaque_bundle.sealed_header.slot_number() == slot { return Some(opaque_bundle); } } @@ -527,12 +512,32 @@ impl MockPrimaryNode { .await } + /// Remove all tx from the tx pool + pub async fn clear_tx_pool(&self) -> Result<(), Box> { + let txs: Vec<_> = self + .transaction_pool + .ready() + .map(|t| self.transaction_pool.hash_of(&t.data)) + .collect(); + self.prune_txs_from_pool(txs.as_slice()).await + } + /// Remove a ready transaction from transaction pool. - pub fn prune_tx_from_pool(&self, tx: &OpaqueExtrinsic) -> Result<(), Box> { - self.transaction_pool.pool().prune_known( - &BlockId::Hash(self.client.info().best_hash), - &[self.transaction_pool.hash_of(tx)], - )?; + pub async fn prune_tx_from_pool(&self, tx: &OpaqueExtrinsic) -> Result<(), Box> { + self.prune_txs_from_pool(&[self.transaction_pool.hash_of(tx)]) + .await + } + + async fn prune_txs_from_pool( + &self, + tx_hashes: &[::Hash], + ) -> Result<(), Box> { + self.transaction_pool + .pool() + .prune_known(&BlockId::Hash(self.client.info().best_hash), tx_hashes)?; + // `ban_time` have set to 0, explicitly wait 1ms here to ensure `clear_stale` will remove + // all the bans as the ban time must be passed. + tokio::time::sleep(time::Duration::from_millis(1)).await; self.transaction_pool .pool() .validated_pool() @@ -541,7 +546,7 @@ impl MockPrimaryNode { } } -impl MockPrimaryNode { +impl MockConsensusNode { async fn collect_txn_from_pool( &self, parent_number: NumberFor, @@ -589,6 +594,7 @@ impl MockPrimaryNode { let pre_digest: PreDigest = PreDigest { slot, solution: self.mock_solution.clone(), + proof_of_time: Default::default(), }; let mut digest = Digest::default(); digest.push(DigestItem::subspace_pre_digest(&pre_digest)); @@ -669,12 +675,24 @@ impl MockPrimaryNode { Some(extrinsics) => extrinsics, None => self.collect_txn_from_pool(parent_number).await, }; + let tx_hashes: Vec<_> = extrinsics + .iter() + .map(|t| self.transaction_pool.hash_of(t)) + .collect(); let (block, storage_changes) = self.build_block(slot, parent_hash, extrinsics).await?; log_new_block(&block, block_timer.elapsed().as_millis()); - self.import_block(block, Some(storage_changes)).await + match self.import_block(block, Some(storage_changes)).await { + Ok(hash) => { + // Remove the tx of the imported block from the tx pool incase re-include them + // in the future block by accident. + self.prune_txs_from_pool(tx_hashes.as_slice()).await?; + Ok(hash) + } + err => err, + } } /// Produce a new block on top of the current best block, with the extrinsics collected from @@ -844,7 +862,7 @@ where // It is necessary to notify the subscriber twice for each importing block in the test to ensure // the imported block must be fully processed by the executor when all acknowledgements responded. // This is because the `futures::channel::mpsc::channel` used in the executor have 1 slot even the - // `primary_block_import_throttling_buffer_size` is set to 0 in the test, notify one more time can + // `consensus_block_import_throttling_buffer_size` is set to 0 in the test, notify one more time can // ensure the previously sent `block_imported` notification must be fully processed by the executor // when the second acknowledgements responded. // Please see https://github.com/subspace/subspace/pull/1363#discussion_r1162571291 for more details.